ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gtkbfc/gtkbfc.c
Revision: 1.12
Committed: Sat Aug 18 13:33:20 2007 UTC (16 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.11: +19 -18 lines
Log Message:
*** empty log message ***

File Contents

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