ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gtkbfc/gtkbfc.c
Revision: 1.5
Committed: Wed Aug 15 15:41:09 2007 UTC (16 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.4: +7 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #define _GNU_SOURCE
2    
3     #include <dlfcn.h>
4     #include <glib.h>
5     #include <gtk/gtk.h>
6     #include <stdlib.h>
7 root 1.4 #include <string.h>
8     #include <unistd.h>
9     #include <sys/types.h>
10     #include <sys/stat.h>
11     #include <fcntl.h>
12 root 1.1
13     static char *helper = "/etc/gtkbfc-helper";
14    
15     static GObject *(*old_constructor) (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties);
16    
17 root 1.4 static gchar *last_path;
18    
19     /////////////////////////////////////////////////////////////////////////////
20    
21     gchar *gtk_file_chooser_get_filename (GtkFileChooser *chooser)
22     {
23     return g_strdup (last_path ? last_path : "/nonex1st4nt");
24     }
25    
26     gboolean gtk_file_chooser_select_filename (GtkFileChooser *chooser, const char *filename)
27     {
28     return 1;
29     }
30    
31     void gtk_file_chooser_unselect_all (GtkFileChooser *chooser)
32     {
33     }
34    
35     gboolean gtk_file_chooser_set_filename (GtkFileChooser *chooser, const char *filename)
36     {
37     return 1;
38     }
39    
40     void gtk_file_chooser_set_current_name (GtkFileChooser *chooser, const char *filename)
41     {
42     }
43    
44     GSList *gtk_file_chooser_get_filenames (GtkFileChooser *chooser)
45     {
46     GSList *rv = 0;
47     rv = g_slist_prepend (rv, gtk_file_chooser_get_filename (chooser));
48     return rv;
49     }
50    
51     gboolean gtk_file_chooser_set_current_folder (GtkFileChooser *chooser, const gchar *folder)
52     {
53     return 1;
54     }
55    
56     gchar * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser)
57     {
58     return g_strdup ("/nonex1st4nt/");
59     }
60    
61     /////////////////////////////////////////////////////////////////////////////
62    
63     static const gchar *
64     from_uri (const gchar *uri)
65     {
66     const gchar *rv = uri;
67    
68     if (uri && uri == strstr (uri, "file:///"))
69     rv = uri + 7;
70    
71     return rv;
72     }
73    
74     static gchar *
75     to_uri (gchar * file)
76     {
77     gchar *rv = NULL;
78    
79     if (file)
80     {
81     GString *str = g_string_new ("file://");
82    
83     str = g_string_append (str, file);
84     rv = g_strdup (str->str);
85     g_string_free (str, TRUE);
86     g_free (file);
87     }
88    
89     return rv;
90     }
91    
92     static GSList *
93     to_uris (GSList *files)
94     {
95     GSList *item = files;
96    
97     for (; item; item = g_slist_next (item))
98     {
99     GString *str = g_string_new ("file://");
100     gchar *cur = item->data;
101    
102     str = g_string_append (str, cur);
103     item->data = g_string_free (str, FALSE);
104     g_free (cur);
105     }
106    
107     return files;
108     }
109    
110     gchar * gtk_file_chooser_get_uri (GtkFileChooser *chooser)
111     {
112     return to_uri(gtk_file_chooser_get_filename (chooser));
113     }
114    
115     gboolean gtk_file_chooser_set_uri (GtkFileChooser *chooser, const char *uri)
116     {
117     return gtk_file_chooser_set_filename (chooser, from_uri (uri));
118     }
119    
120     GSList *gtk_file_chooser_get_uris (GtkFileChooser *chooser)
121     {
122     return to_uris (gtk_file_chooser_get_filenames (chooser));
123     }
124    
125     gboolean gtk_file_chooser_set_current_folder_uri(GtkFileChooser *chooser, const gchar *uri)
126     {
127     return gtk_file_chooser_set_current_folder (chooser, from_uri (uri));
128     }
129    
130     gchar *gtk_file_chooser_get_current_folder_uri (GtkFileChooser *chooser)
131     {
132     return to_uri (gtk_file_chooser_get_current_folder (chooser));
133     }
134    
135     /////////////////////////////////////////////////////////////////////////////
136    
137 root 1.1 static gboolean activate_cb (gpointer data)
138     {
139     gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (data), FALSE);
140 root 1.4 //fprintf (stderr, "ad %d\n", gtk_window_activate_default (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (data)))));
141 root 1.1 g_signal_emit_by_name (GTK_FILE_CHOOSER (data), "file-activated");
142     return FALSE;
143     }
144    
145 root 1.4 static gboolean unmap_cb (gpointer data)
146     {
147     gtk_widget_unmap (GTK_WIDGET (gtk_widget_get_toplevel (data)));
148     return FALSE;
149     }
150    
151     static gboolean read_result (GIOChannel *source, GIOCondition condition, gpointer data)
152     {
153     g_io_channel_read_to_end (source, &last_path, 0, 0);
154     g_io_channel_unref (source);
155     activate_cb (data);
156     return FALSE;
157     }
158    
159 root 1.1 static gboolean show_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
160     {
161 root 1.5 gchar *argv[10];
162 root 1.4 gboolean save = 0;
163 root 1.5 char xid [40];
164 root 1.1
165     argv [0] = helper;
166 root 1.3
167     switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (widget)))
168     {
169 root 1.4 case GTK_FILE_CHOOSER_ACTION_SAVE: argv [1] = "save "; save = 1;break;
170     case GTK_FILE_CHOOSER_ACTION_OPEN: argv [1] = "load "; break;
171     case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: argv [1] = "mkdir "; save = 1; break;
172 root 1.3 case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: argv [1] = "cd "; break;
173     default: argv [1] = "<filechooser> "; break;
174     }
175    
176 root 1.5 GdkWindow *w = gtk_widget_get_parent_window (GTK_WIDGET (widget));
177    
178     snprintf (xid, 80, "%lu", (unsigned long)(w ? gdk_x11_drawable_get_xid (w) : 0));
179     argv [2] = xid;
180     argv [3] = 0;
181 root 1.1
182 root 1.4 mkdir ("/tmp/gtkbfc", 0777);
183     close (open ("/tmp/gtkbfc/empty", O_WRONLY|O_CREAT|O_TRUNC, 0666));
184    
185     if (save)
186     ((void (*)(void *, const char *)) dlsym (RTLD_NEXT, "gtk_file_chooser_set_current_name"))(GTK_FILE_CHOOSER (widget), "/tmp/gtkbfc/empty");
187     else
188     ((void (*)(void *, const char *)) dlsym (RTLD_NEXT, "gtk_file_chooser_set_filename"))(GTK_FILE_CHOOSER (widget), "/tmp/gtkbfc/empty");
189    
190     if (last_path)
191     {
192     g_free (last_path);
193     last_path = 0;
194     }
195    
196     gint stdout_fd = -1;
197    
198     if (g_spawn_async_with_pipes (0, argv, 0, 0, 0, 0, 0, 0, &stdout_fd, 0, 0))
199 root 1.1 {
200 root 1.4 GIOChannel *channel = g_io_channel_unix_new (stdout_fd);
201     gtk_widget_hide (GTK_WIDGET (gtk_widget_get_toplevel (widget)));
202     g_io_add_watch (channel, G_IO_IN, read_result, widget);
203     g_idle_add (unmap_cb, widget);
204     //g_timeout_add (1, unmap_cb, widget);
205 root 1.1 }
206     else
207     ;//gtk_widget_show (widget);
208     }
209    
210     static GObject *new_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)
211     {
212     GObject *ob = old_constructor (type, n_construct_properties, construct_properties);
213     g_signal_connect_after (ob, "map", G_CALLBACK (show_cb), 0);
214     return ob;
215     }
216    
217     __attribute__ ((constructor))
218     static void init ()
219     {
220 root 1.3 g_type_init ();
221 root 1.1
222 root 1.3 GType type = GTK_TYPE_FILE_CHOOSER_WIDGET;
223     GObjectClass *klass = g_type_class_ref (type);
224 root 1.1
225 root 1.3 old_constructor = klass->constructor;
226     klass->constructor = new_constructor;
227 root 1.1 }
228