ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gtkbfc/gtkbfc.c
Revision: 1.9
Committed: Sat Aug 18 10:48:29 2007 UTC (16 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.8: +5 -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.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.8 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.4 return g_strdup ("/nonex1st4nt/");
69     }
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     DEBUG ((printf ("gtk_file_chooser_get_uri %s\n", uri)));
124     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.1 static gboolean activate_cb (gpointer data)
150     {
151     gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (data), FALSE);
152 root 1.4 //fprintf (stderr, "ad %d\n", gtk_window_activate_default (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (data)))));
153 root 1.1 g_signal_emit_by_name (GTK_FILE_CHOOSER (data), "file-activated");
154     return FALSE;
155     }
156    
157 root 1.4 static gboolean unmap_cb (gpointer data)
158     {
159     gtk_widget_unmap (GTK_WIDGET (gtk_widget_get_toplevel (data)));
160     return FALSE;
161     }
162    
163     static gboolean read_result (GIOChannel *source, GIOCondition condition, gpointer data)
164     {
165 root 1.7 if (last_path)
166     {
167     g_free (last_path);
168     last_path = 0;
169     }
170    
171 root 1.4 g_io_channel_read_to_end (source, &last_path, 0, 0);
172     g_io_channel_unref (source);
173     activate_cb (data);
174 root 1.8
175     DEBUG ((printf ("read_result<%s>\n", last_path)));
176    
177 root 1.4 return FALSE;
178     }
179    
180 root 1.1 static gboolean show_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
181     {
182 root 1.5 gchar *argv[10];
183 root 1.4 gboolean save = 0;
184 root 1.5 char xid [40];
185 root 1.1
186     argv [0] = helper;
187 root 1.3
188     switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (widget)))
189     {
190 root 1.4 case GTK_FILE_CHOOSER_ACTION_SAVE: argv [1] = "save "; save = 1;break;
191     case GTK_FILE_CHOOSER_ACTION_OPEN: argv [1] = "load "; break;
192     case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: argv [1] = "mkdir "; save = 1; break;
193 root 1.3 case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: argv [1] = "cd "; break;
194     default: argv [1] = "<filechooser> "; break;
195     }
196    
197 root 1.5 GdkWindow *w = gtk_widget_get_parent_window (GTK_WIDGET (widget));
198    
199     snprintf (xid, 80, "%lu", (unsigned long)(w ? gdk_x11_drawable_get_xid (w) : 0));
200     argv [2] = xid;
201     argv [3] = 0;
202 root 1.1
203 root 1.4 mkdir ("/tmp/gtkbfc", 0777);
204     close (open ("/tmp/gtkbfc/empty", O_WRONLY|O_CREAT|O_TRUNC, 0666));
205    
206     if (save)
207     ((void (*)(void *, const char *)) dlsym (RTLD_NEXT, "gtk_file_chooser_set_current_name"))(GTK_FILE_CHOOSER (widget), "/tmp/gtkbfc/empty");
208     else
209     ((void (*)(void *, const char *)) dlsym (RTLD_NEXT, "gtk_file_chooser_set_filename"))(GTK_FILE_CHOOSER (widget), "/tmp/gtkbfc/empty");
210    
211     gint stdout_fd = -1;
212    
213     if (g_spawn_async_with_pipes (0, argv, 0, 0, 0, 0, 0, 0, &stdout_fd, 0, 0))
214 root 1.1 {
215 root 1.4 GIOChannel *channel = g_io_channel_unix_new (stdout_fd);
216     gtk_widget_hide (GTK_WIDGET (gtk_widget_get_toplevel (widget)));
217     g_io_add_watch (channel, G_IO_IN, read_result, widget);
218     g_idle_add (unmap_cb, widget);
219     //g_timeout_add (1, unmap_cb, widget);
220 root 1.1 }
221     else
222     ;//gtk_widget_show (widget);
223     }
224    
225     static GObject *new_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)
226     {
227     GObject *ob = old_constructor (type, n_construct_properties, construct_properties);
228     g_signal_connect_after (ob, "map", G_CALLBACK (show_cb), 0);
229     return ob;
230     }
231    
232     __attribute__ ((constructor))
233     static void init ()
234     {
235 root 1.3 g_type_init ();
236 root 1.1
237 root 1.3 GType type = GTK_TYPE_FILE_CHOOSER_WIDGET;
238     GObjectClass *klass = g_type_class_ref (type);
239 root 1.1
240 root 1.3 old_constructor = klass->constructor;
241     klass->constructor = new_constructor;
242 root 1.1 }
243