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