|
|
1 | /* this file is publiched under the gnu gpl license, version 3 or any later */ |
|
|
2 | |
1 | #define _GNU_SOURCE |
3 | #define _GNU_SOURCE |
2 | |
4 | |
3 | #include <dlfcn.h> |
5 | #include <dlfcn.h> |
4 | #include <glib.h> |
6 | #include <glib.h> |
5 | #include <gtk/gtk.h> |
7 | #include <gtk/gtk.h> |
… | |
… | |
14 | |
16 | |
15 | static GObject *(*old_constructor) (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties); |
17 | static GObject *(*old_constructor) (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties); |
16 | |
18 | |
17 | static gchar *last_path; |
19 | static gchar *last_path; |
18 | |
20 | |
|
|
21 | #if 0 |
|
|
22 | # define DEBUG(stmt) stmt; |
|
|
23 | #else |
|
|
24 | # define DEBUG(stmt) |
|
|
25 | #endif |
|
|
26 | |
19 | ///////////////////////////////////////////////////////////////////////////// |
27 | ///////////////////////////////////////////////////////////////////////////// |
20 | |
28 | |
21 | gchar *gtk_file_chooser_get_filename (GtkFileChooser *chooser) |
29 | gchar *gtk_file_chooser_get_filename (GtkFileChooser *chooser) |
22 | { |
30 | { |
|
|
31 | DEBUG ((printf ("gtk_file_chooser_get_filename<%s>\n", last_path))) |
23 | return g_strdup (last_path ? last_path : "/nonex1st4nt"); |
32 | return g_strdup (last_path ? last_path : "/nonex1st4nt"); |
24 | } |
33 | } |
25 | |
34 | |
26 | gboolean gtk_file_chooser_select_filename (GtkFileChooser *chooser, const char *filename) |
35 | gboolean gtk_file_chooser_select_filename (GtkFileChooser *chooser, const char *filename) |
27 | { |
36 | { |
… | |
… | |
53 | return 1; |
62 | return 1; |
54 | } |
63 | } |
55 | |
64 | |
56 | gchar * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser) |
65 | gchar * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser) |
57 | { |
66 | { |
58 | return g_strdup ("/nonex1st4nt/"); |
67 | DEBUG ((printf ("gtk_file_chooser_get_current_folder\n"))) |
|
|
68 | return g_strdup ("/tmp/gtkbfc"); |
59 | } |
69 | } |
60 | |
70 | |
61 | ///////////////////////////////////////////////////////////////////////////// |
71 | ///////////////////////////////////////////////////////////////////////////// |
62 | |
72 | |
63 | static const gchar * |
73 | static const gchar * |
… | |
… | |
70 | |
80 | |
71 | return rv; |
81 | return rv; |
72 | } |
82 | } |
73 | |
83 | |
74 | static gchar * |
84 | static gchar * |
75 | to_uri (gchar * file) |
85 | to_uri (gchar *file) |
76 | { |
86 | { |
77 | gchar *rv = NULL; |
87 | gchar *rv = NULL; |
78 | |
88 | |
79 | if (file) |
89 | if (file) |
80 | { |
90 | { |
… | |
… | |
105 | } |
115 | } |
106 | |
116 | |
107 | return files; |
117 | return files; |
108 | } |
118 | } |
109 | |
119 | |
110 | gchar * gtk_file_chooser_get_uri (GtkFileChooser *chooser) |
120 | gchar *gtk_file_chooser_get_uri (GtkFileChooser *chooser) |
111 | { |
121 | { |
112 | return to_uri(gtk_file_chooser_get_filename (chooser)); |
122 | gchar *uri = to_uri(gtk_file_chooser_get_filename (chooser)); |
|
|
123 | DEBUG ((printf ("gtk_file_chooser_get_uri<%s>\n", uri))); |
|
|
124 | return uri; |
113 | } |
125 | } |
114 | |
126 | |
115 | gboolean gtk_file_chooser_set_uri (GtkFileChooser *chooser, const char *uri) |
127 | gboolean gtk_file_chooser_set_uri (GtkFileChooser *chooser, const char *uri) |
116 | { |
128 | { |
117 | return gtk_file_chooser_set_filename (chooser, from_uri (uri)); |
129 | return gtk_file_chooser_set_filename (chooser, from_uri (uri)); |
… | |
… | |
132 | return to_uri (gtk_file_chooser_get_current_folder (chooser)); |
144 | return to_uri (gtk_file_chooser_get_current_folder (chooser)); |
133 | } |
145 | } |
134 | |
146 | |
135 | ///////////////////////////////////////////////////////////////////////////// |
147 | ///////////////////////////////////////////////////////////////////////////// |
136 | |
148 | |
137 | static gboolean activate_cb (gpointer data) |
149 | static gboolean disable_cb (gpointer data) |
138 | { |
150 | { |
139 | gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (data), FALSE); |
151 | // set the path again to avoid a race condition |
140 | //fprintf (stderr, "ad %d\n", gtk_window_activate_default (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (data))))); |
152 | ((void (*)(void *, const char *)) dlsym (RTLD_NEXT, "gtk_file_chooser_set_filename"))(GTK_FILE_CHOOSER (data), "/tmp/gtkbfc/empty"); |
141 | g_signal_emit_by_name (GTK_FILE_CHOOSER (data), "file-activated"); |
153 | gtk_widget_set_sensitive (GTK_WIDGET (gtk_widget_get_toplevel (data)), 0); |
|
|
154 | //gtk_widget_unmap (GTK_WIDGET (gtk_widget_get_toplevel (data))); |
142 | return FALSE; |
155 | return FALSE; |
143 | } |
156 | } |
144 | |
157 | |
145 | 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) |
158 | static gboolean read_result (GIOChannel *source, GIOCondition condition, gpointer data) |
152 | { |
159 | { |
|
|
160 | if (last_path) |
|
|
161 | { |
|
|
162 | g_free (last_path); |
|
|
163 | last_path = 0; |
|
|
164 | } |
|
|
165 | |
153 | g_io_channel_read_to_end (source, &last_path, 0, 0); |
166 | g_io_channel_read_to_end (source, &last_path, 0, 0); |
154 | g_io_channel_unref (source); |
167 | g_io_channel_unref (source); |
155 | activate_cb (data); |
168 | |
|
|
169 | 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 | |
156 | return FALSE; |
184 | return FALSE; |
157 | } |
185 | } |
158 | |
186 | |
159 | static gboolean show_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) |
187 | static gboolean show_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) |
160 | { |
188 | { |
161 | gchar *argv[3]; |
189 | gchar *argv[10]; |
162 | gboolean save = 0; |
190 | gboolean save = 0; |
|
|
191 | char xid [40]; |
163 | |
192 | |
164 | argv [0] = helper; |
193 | argv [0] = helper; |
165 | |
194 | |
166 | switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (widget))) |
195 | switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (widget))) |
167 | { |
196 | { |
… | |
… | |
170 | case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: argv [1] = "mkdir "; save = 1; break; |
199 | case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: argv [1] = "mkdir "; save = 1; break; |
171 | case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: argv [1] = "cd "; break; |
200 | case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: argv [1] = "cd "; break; |
172 | default: argv [1] = "<filechooser> "; break; |
201 | default: argv [1] = "<filechooser> "; break; |
173 | } |
202 | } |
174 | |
203 | |
|
|
204 | 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; |
175 | argv [2] = 0; |
208 | argv [3] = 0; |
176 | |
209 | |
177 | mkdir ("/tmp/gtkbfc", 0777); |
210 | mkdir ("/tmp/gtkbfc", 0777); |
178 | close (open ("/tmp/gtkbfc/empty", O_WRONLY|O_CREAT|O_TRUNC, 0666)); |
211 | close (open ("/tmp/gtkbfc/empty", O_WRONLY|O_CREAT|O_TRUNC, 0666)); |
179 | |
212 | |
180 | if (save) |
|
|
181 | ((void (*)(void *, const char *)) dlsym (RTLD_NEXT, "gtk_file_chooser_set_current_name"))(GTK_FILE_CHOOSER (widget), "/tmp/gtkbfc/empty"); |
|
|
182 | else |
|
|
183 | ((void (*)(void *, const char *)) dlsym (RTLD_NEXT, "gtk_file_chooser_set_filename"))(GTK_FILE_CHOOSER (widget), "/tmp/gtkbfc/empty"); |
213 | ((void (*)(void *, const char *)) dlsym (RTLD_NEXT, "gtk_file_chooser_set_filename"))(GTK_FILE_CHOOSER (widget), "/tmp/gtkbfc/empty"); |
184 | |
|
|
185 | if (last_path) |
|
|
186 | { |
|
|
187 | g_free (last_path); |
|
|
188 | last_path = 0; |
|
|
189 | } |
|
|
190 | |
214 | |
191 | gint stdout_fd = -1; |
215 | gint stdout_fd = -1; |
192 | |
216 | |
193 | if (g_spawn_async_with_pipes (0, argv, 0, 0, 0, 0, 0, 0, &stdout_fd, 0, 0)) |
217 | if (g_spawn_async_with_pipes (0, argv, 0, 0, 0, 0, 0, 0, &stdout_fd, 0, 0)) |
194 | { |
218 | { |
195 | GIOChannel *channel = g_io_channel_unix_new (stdout_fd); |
219 | GIOChannel *channel = g_io_channel_unix_new (stdout_fd); |
196 | gtk_widget_hide (GTK_WIDGET (gtk_widget_get_toplevel (widget))); |
|
|
197 | g_io_add_watch (channel, G_IO_IN, read_result, widget); |
220 | g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP, read_result, widget); |
198 | g_idle_add (unmap_cb, widget); |
221 | g_idle_add (disable_cb, widget); |
199 | //g_timeout_add (1, unmap_cb, widget); |
|
|
200 | } |
222 | } |
201 | else |
223 | else |
202 | ;//gtk_widget_show (widget); |
224 | ;//gtk_widget_show (widget); |
203 | } |
225 | } |
204 | |
226 | |