2 * Copyright (C) 1998 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
22 /* Target side drag signals */
25 static const char * drag_icon_xpm[] = {
36 " .....................",
37 " ..&&&&&&&&&&&&&&&&&&&.",
38 " ...&&&&&&&&&&&&&&&&&&&.",
39 " ..&.&&&&&&&&&&&&&&&&&&&.",
40 " ..&&.&&&&&&&&&&&&&&&&&&&.",
41 " ..&&&.&&&&&&&&&&&&&&&&&&&.",
42 " ..&&&&.&&&&&&&&&&&&&&&&&&&.",
43 " ..&&&&&.&&&@&&&&&&&&&&&&&&&.",
44 " ..&&&&&&.*$%$+$&&&&&&&&&&&&&.",
45 " ..&&&&&&&.%$%$+&&&&&&&&&&&&&&.",
46 " ..&&&&&&&&.#&#@$&&&&&&&&&&&&&&.",
47 " ..&&&&&&&&&.#$**#$&&&&&&&&&&&&&.",
48 " ..&&&&&&&&&&.&@%&%$&&&&&&&&&&&&&.",
49 " ..&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&.",
50 " ..&&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&.",
51 "................&$@&&&@&&&&&&&&&&&&.",
52 ".&&&&&&&+&&#@%#+@#@*$%$+$&&&&&&&&&&.",
53 ".&&&&&&&+&&#@#@&&@*%$%$+&&&&&&&&&&&.",
54 ".&&&&&&&+&$%&#@&#@@#&#@$&&&&&&&&&&&.",
55 ".&&&&&&@#@@$&*@&@#@#$**#$&&&&&&&&&&.",
56 ".&&&&&&&&&&&&&&&&&&&@%&%$&&&&&&&&&&.",
57 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
58 ".&&&&&&&&$#@@$&&&&&&&&&&&&&&&&&&&&&.",
59 ".&&&&&&&&&+&$+&$&@&$@&&$@&&&&&&&&&&.",
60 ".&&&&&&&&&+&&#@%#+@#@*$%&+$&&&&&&&&.",
61 ".&&&&&&&&&+&&#@#@&&@*%$%$+&&&&&&&&&.",
62 ".&&&&&&&&&+&$%&#@&#@@#&#@$&&&&&&&&&.",
63 ".&&&&&&&&@#@@$&*@&@#@#$#*#$&&&&&&&&.",
64 ".&&&&&&&&&&&&&&&&&&&&&$%&%$&&&&&&&&.",
65 ".&&&&&&&&&&$#@@$&&&&&&&&&&&&&&&&&&&.",
66 ".&&&&&&&&&&&+&$%&$$@&$@&&$@&&&&&&&&.",
67 ".&&&&&&&&&&&+&&#@%#+@#@*$%$+$&&&&&&.",
68 ".&&&&&&&&&&&+&&#@#@&&@*#$%$+&&&&&&&.",
69 ".&&&&&&&&&&&+&$+&*@&#@@#&#@$&&&&&&&.",
70 ".&&&&&&&&&&$%@@&&*@&@#@#$#*#&&&&&&&.",
71 ".&&&&&&&&&&&&&&&&&&&&&&&$%&%$&&&&&&.",
72 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
73 ".&&&&&&&&&&&&&&$#@@$&&&&&&&&&&&&&&&.",
74 ".&&&&&&&&&&&&&&&+&$%&$$@&$@&&$@&&&&.",
75 ".&&&&&&&&&&&&&&&+&&#@%#+@#@*$%$+$&&.",
76 ".&&&&&&&&&&&&&&&+&&#@#@&&@*#$%$+&&&.",
77 ".&&&&&&&&&&&&&&&+&$+&*@&#@@#&#@$&&&.",
78 ".&&&&&&&&&&&&&&$%@@&&*@&@#@#$#*#&&&.",
79 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&$%&%$&&.",
80 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
81 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
82 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
83 "...................................."};
86 static const char * trashcan_closed_xpm[] = {
127 " ==......=$$...=== ",
128 " ..$------)+++++++++++++@$$... ",
129 " ..=@@-------&+++++++++++++++++++-.... ",
130 " =.$$@@@-&&)++++)-,$$$$=@@&+++++++++++++,..$ ",
131 " .$$$$@@&+++++++&$$$@@@@-&,$,-++++++++++;;;&.. ",
132 " $$$$,@--&++++++&$$)++++++++-,$&++++++;%%'%%;;$@ ",
133 " .-@@-@-&++++++++-@++++++++++++,-++++++;''%;;;%*-$ ",
134 " +------++++++++++++++++++++++++++++++;;%%%;;##*!. ",
135 " =+----+++++++++++++++++++++++;;;;;;;;;;;;%'>>). ",
136 " .=)&+++++++++++++++++;;;;;;;;;;;;;;%''>>#>#@. ",
137 " =..=&++++++++++++;;;;;;;;;;;;;%###>>###+%== ",
138 " .&....=-+++++%;;####''''''''''##'%%%)..#. ",
139 " .+-++@....=,+%#####'%%%%%%%%%;@$-@-@*++!. ",
140 " .+-++-+++-&-@$$=$=......$,,,@;&)+!++!++!. ",
141 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
142 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
143 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
144 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
145 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
146 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
147 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
148 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
149 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
150 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
151 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
152 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
153 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
154 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
155 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
156 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
157 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
158 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
159 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
160 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
161 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
162 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
163 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
164 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
165 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
166 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
167 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
168 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
169 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
170 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
171 " =+-++-+++-+++++++++!++++!++++!+++!++!+++= ",
172 " $.++-+++-+++++++++!++++!++++!+++!++!+.$ ",
173 " =.++++++++++++++!++++!++++!+++!++.= ",
174 " $..+++++++++++++++!++++++...$ ",
175 " $$=.............=$$ ",
187 static const char * trashcan_open_xpm[] = {
215 " $,-+)+++%%;;'#+. ",
216 " =---+++++;%%%;%##@. ",
217 " @)++++++++;%%%%'#%$ ",
218 " $&++++++++++;%%;%##@= ",
219 " ,-++++)+++++++;;;'#%) ",
220 " @+++&&--&)++++;;%'#'-. ",
221 " ,&++-@@,,,,-)++;;;'>'+, ",
222 " =-++&@$@&&&&-&+;;;%##%+@ ",
223 " =,)+)-,@@&+++++;;;;%##%&@ ",
224 " @--&&,,@&)++++++;;;;'#)@ ",
225 " ---&)-,@)+++++++;;;%''+, ",
226 " $--&)+&$-+++++++;;;%%'';- ",
227 " .,-&+++-$&++++++;;;%''%&= ",
228 " $,-&)++)-@++++++;;%''%), ",
229 " =,@&)++++&&+++++;%'''+$@&++++++ ",
230 " .$@-++++++++++++;'#';,........=$@&++++ ",
231 " =$@@&)+++++++++++'##-.................=&++ ",
232 " .$$@-&)+++++++++;%#+$.....................=)+ ",
233 " $$,@-)+++++++++;%;@=........................,+ ",
234 " .$$@@-++++++++)-)@=............................ ",
235 " $,@---)++++&)@===............................,. ",
236 " $-@---&)))-$$=..............................=)!. ",
237 " --&-&&,,$=,==...........................=&+++!. ",
238 " =,=$..=$+)+++++&@$=.............=$@&+++++!++!. ",
239 " .)-++-+++++++++++++++++++++++++++!++!++!. ",
240 " .+-++-+++++++++++++++++++++++!+++!++!++!. ",
241 " .+-++-+++-+++++++++!+++!!++++!+++!++!++!. ",
242 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
243 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
244 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
245 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
246 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
247 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
248 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
249 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
250 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
251 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
252 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
253 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
254 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
255 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
256 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
257 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
258 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
259 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
260 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
261 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
262 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
263 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
264 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
265 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
266 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
267 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
268 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
269 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
270 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
271 " .+-++-+++-+++++++++!++++!++++!+++!++!++!. ",
272 " =+-++-+++-+++++++++!++++!++++!+++!++!+++= ",
273 " $.++-+++-+++++++++!++++!++++!+++!++!+.$ ",
274 " =.++++++++++++++!++++!++++!+++!++.= ",
275 " $..+++++++++++++++!++++++...$ ",
276 " $$==...........==$$ ",
287 GdkPixbuf *trashcan_open;
288 GdkPixbuf *trashcan_closed;
297 static GtkTargetEntry target_table[] = {
298 { "STRING", 0, TARGET_STRING },
299 { "text/plain", 0, TARGET_STRING },
300 { "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
303 static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
306 target_drag_leave (GtkWidget *widget,
307 GdkDragContext *context,
312 gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed);
316 target_drag_motion (GtkWidget *widget,
317 GdkDragContext *context,
322 GtkWidget *source_widget;
328 gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_open);
331 source_widget = gtk_drag_get_source_widget (context);
332 g_print ("motion, source %s\n", source_widget ?
333 G_OBJECT_TYPE_NAME (source_widget) :
336 tmp_list = gdk_drag_context_list_targets (context);
339 char *name = gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data));
340 g_print ("%s\n", name);
343 tmp_list = tmp_list->next;
346 gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time);
352 target_drag_drop (GtkWidget *widget,
353 GdkDragContext *context,
361 gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed);
363 if (gdk_drag_context_list_targets (context))
365 gtk_drag_get_data (widget, context,
366 GDK_POINTER_TO_ATOM (gdk_drag_context_list_targets (context)->data),
375 target_drag_data_received (GtkWidget *widget,
376 GdkDragContext *context,
379 GtkSelectionData *selection_data,
383 if (gtk_selection_data_get_length (selection_data) >= 0 &&
384 gtk_selection_data_get_format (selection_data) == 8)
386 g_print ("Received \"%s\" in trashcan\n", (gchar *) gtk_selection_data_get_data (selection_data));
387 gtk_drag_finish (context, TRUE, FALSE, time);
391 gtk_drag_finish (context, FALSE, FALSE, time);
395 label_drag_data_received (GtkWidget *widget,
396 GdkDragContext *context,
399 GtkSelectionData *selection_data,
403 if (gtk_selection_data_get_length (selection_data) >= 0 &&
404 gtk_selection_data_get_format (selection_data) == 8)
406 g_print ("Received \"%s\" in label\n", (gchar *) gtk_selection_data_get_data (selection_data));
407 gtk_drag_finish (context, TRUE, FALSE, time);
411 gtk_drag_finish (context, FALSE, FALSE, time);
415 source_drag_data_get (GtkWidget *widget,
416 GdkDragContext *context,
417 GtkSelectionData *selection_data,
422 if (info == TARGET_ROOTWIN)
423 g_print ("I was dropped on the rootwin\n");
425 gtk_selection_data_set (selection_data,
426 gtk_selection_data_get_target (selection_data),
427 8, (guchar *) "I'm Data!", 9);
430 /* The following is a rather elaborate example demonstrating/testing
431 * changing of the window hierarchy during a drag - in this case,
432 * via a "spring-loaded" popup window.
434 static GtkWidget *popup_window = NULL;
436 static gboolean popped_up = FALSE;
437 static gboolean in_popup = FALSE;
438 static guint popdown_timer = 0;
439 static guint popup_timer = 0;
442 popdown_cb (gpointer data)
446 gtk_widget_hide (popup_window);
453 popup_motion (GtkWidget *widget,
454 GdkDragContext *context,
464 g_print ("removed popdown\n");
465 g_source_remove (popdown_timer);
474 popup_leave (GtkWidget *widget,
475 GdkDragContext *context,
483 g_print ("added popdown\n");
484 popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
490 popup_cb (gpointer data)
500 popup_window = gtk_window_new (GTK_WINDOW_POPUP);
501 gtk_window_set_position (GTK_WINDOW (popup_window), GTK_WIN_POS_MOUSE);
503 grid = gtk_grid_new ();
509 g_snprintf(buffer, sizeof(buffer), "%d,%d", i, j);
510 button = gtk_button_new_with_label (buffer);
511 gtk_widget_set_hexpand (button, TRUE);
512 gtk_widget_set_vexpand (button, TRUE);
513 gtk_grid_attach (GTK_GRID (grid), button, i, j, 1, 1);
515 gtk_drag_dest_set (button,
516 GTK_DEST_DEFAULT_ALL,
517 target_table, n_targets - 1, /* no rootwin */
518 GDK_ACTION_COPY | GDK_ACTION_MOVE);
519 g_signal_connect (button, "drag_motion",
520 G_CALLBACK (popup_motion), NULL);
521 g_signal_connect (button, "drag_leave",
522 G_CALLBACK (popup_leave), NULL);
525 gtk_widget_show_all (grid);
526 gtk_container_add (GTK_CONTAINER (popup_window), grid);
529 gtk_widget_show (popup_window);
533 popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
534 g_print ("added popdown\n");
542 popsite_motion (GtkWidget *widget,
543 GdkDragContext *context,
549 popup_timer = gdk_threads_add_timeout (500, popup_cb, NULL);
555 popsite_leave (GtkWidget *widget,
556 GdkDragContext *context,
561 g_source_remove (popup_timer);
567 source_drag_data_delete (GtkWidget *widget,
568 GdkDragContext *context,
571 g_print ("Delete the data!\n");
577 if (g_file_test ("../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
578 g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
582 main (int argc, char **argv)
589 GdkPixbuf *drag_icon;
593 gtk_init (&argc, &argv);
595 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
596 g_signal_connect (window, "destroy",
597 G_CALLBACK (gtk_main_quit), NULL);
600 grid = gtk_grid_new ();
601 gtk_container_add (GTK_CONTAINER (window), grid);
603 drag_icon = gdk_pixbuf_new_from_xpm_data (drag_icon_xpm);
604 trashcan_open = gdk_pixbuf_new_from_xpm_data (trashcan_open_xpm);
605 trashcan_closed = gdk_pixbuf_new_from_xpm_data (trashcan_closed_xpm);
607 label = gtk_label_new ("Drop Here\n");
609 gtk_drag_dest_set (label,
610 GTK_DEST_DEFAULT_ALL,
611 target_table, n_targets - 1, /* no rootwin */
612 GDK_ACTION_COPY | GDK_ACTION_MOVE);
614 g_signal_connect (label, "drag_data_received",
615 G_CALLBACK( label_drag_data_received), NULL);
617 gtk_widget_set_hexpand (label, TRUE);
618 gtk_widget_set_vexpand (label, TRUE);
619 gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
621 label = gtk_label_new ("Popup\n");
623 gtk_drag_dest_set (label,
624 GTK_DEST_DEFAULT_ALL,
625 target_table, n_targets - 1, /* no rootwin */
626 GDK_ACTION_COPY | GDK_ACTION_MOVE);
628 gtk_widget_set_hexpand (label, TRUE);
629 gtk_widget_set_vexpand (label, TRUE);
630 gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
632 g_signal_connect (label, "drag_motion",
633 G_CALLBACK (popsite_motion), NULL);
634 g_signal_connect (label, "drag_leave",
635 G_CALLBACK (popsite_leave), NULL);
637 pixmap = gtk_image_new_from_pixbuf (trashcan_closed);
638 gtk_drag_dest_set (pixmap, 0, NULL, 0, 0);
639 gtk_widget_set_hexpand (pixmap, TRUE);
640 gtk_widget_set_vexpand (pixmap, TRUE);
641 gtk_grid_attach (GTK_GRID (grid), pixmap, 1, 0, 1, 1);
643 g_signal_connect (pixmap, "drag_leave",
644 G_CALLBACK (target_drag_leave), NULL);
646 g_signal_connect (pixmap, "drag_motion",
647 G_CALLBACK (target_drag_motion), NULL);
649 g_signal_connect (pixmap, "drag_drop",
650 G_CALLBACK (target_drag_drop), NULL);
652 g_signal_connect (pixmap, "drag_data_received",
653 G_CALLBACK (target_drag_data_received), NULL);
657 button = gtk_button_new_with_label ("Drag Here\n");
659 gtk_drag_source_set (button, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
660 target_table, n_targets,
661 GDK_ACTION_COPY | GDK_ACTION_MOVE);
662 gtk_drag_source_set_icon_pixbuf (button, drag_icon);
664 g_object_unref (drag_icon);
666 gtk_widget_set_hexpand (button, TRUE);
667 gtk_widget_set_vexpand (button, TRUE);
668 gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 1, 1);
670 g_signal_connect (button, "drag_data_get",
671 G_CALLBACK (source_drag_data_get), NULL);
672 g_signal_connect (button, "drag_data_delete",
673 G_CALLBACK (source_drag_data_delete), NULL);
675 gtk_widget_show_all (window);