1 /* testdnd.c
2 * Copyright (C) 1998 Red Hat, Inc.
3 * Author: Owen Taylor
4 *
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.
9 *
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.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
20
21 #include "config.h"
22 #include "gtk/gtk.h"
23
24 /* Target side drag signals */
25
26 /* XPM */
27 static const char * drag_icon_xpm[] = {
28 "36 48 9 1",
29 " c None",
30 ". c #020204",
31 "+ c #8F8F90",
32 "@ c #D3D3D2",
33 "# c #AEAEAC",
34 "$ c #ECECEC",
35 "% c #A2A2A4",
36 "& c #FEFEFC",
37 "* c #BEBEBC",
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 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
84 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
85 "...................................."};
86
87 /* XPM */
88 static const char * trashcan_closed_xpm[] = {
89 "64 80 17 1",
90 " c None",
91 ". c #030304",
92 "+ c #5A5A5C",
93 "@ c #323231",
94 "# c #888888",
95 "$ c #1E1E1F",
96 "% c #767677",
97 "& c #494949",
98 "* c #9E9E9C",
99 "= c #111111",
100 "- c #3C3C3D",
101 "; c #6B6B6B",
102 "> c #949494",
103 ", c #282828",
104 "' c #808080",
105 ") c #545454",
106 "! c #AEAEAC",
107 " ",
108 " ",
109 " ",
110 " ",
111 " ",
112 " ",
113 " ",
114 " ",
115 " ",
116 " ",
117 " ",
118 " ",
119 " ",
120 " ",
121 " ",
122 " ",
123 " ",
124 " ",
125 " ",
126 " ",
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 " =.++++++++++++++!++++!++++!+++!++.= ",
176 " $..+++++++++++++++!++++++...$ ",
177 " $$=.............=$$ ",
178 " ",
179 " ",
180 " ",
181 " ",
182 " ",
183 " ",
184 " ",
185 " ",
186 " "};
187
188 /* XPM */
189 static const char * trashcan_open_xpm[] = {
190 "64 80 17 1",
191 " c None",
192 ". c #030304",
193 "+ c #5A5A5C",
194 "@ c #323231",
195 "# c #888888",
196 "$ c #1E1E1F",
197 "% c #767677",
198 "& c #494949",
199 "* c #9E9E9C",
200 "= c #111111",
201 "- c #3C3C3D",
202 "; c #6B6B6B",
203 "> c #949494",
204 ", c #282828",
205 "' c #808080",
206 ") c #545454",
207 "! c #AEAEAC",
208 " ",
209 " ",
210 " ",
211 " ",
212 " ",
213 " ",
214 " .=.==.,@ ",
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 " =.++++++++++++++!++++!++++!+++!++.= ",
277 " $..+++++++++++++++!++++++...$ ",
278 " $$==...........==$$ ",
279 " ",
280 " ",
281 " ",
282 " ",
283 " ",
284 " ",
285 " ",
286 " ",
287 " "};
288
289 GdkPixbuf *trashcan_open;
290 GdkPixbuf *trashcan_closed;
291
292 gboolean have_drag;
293
294 enum {
295 TARGET_STRING,
296 TARGET_ROOTWIN
297 };
298
299 static GtkTargetEntry target_table[] = {
300 { "STRING", 0, TARGET_STRING },
301 { "text/plain", 0, TARGET_STRING },
302 { "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
303 };
304
305 static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
306
307 void
target_drag_leave(GtkWidget * widget,GdkDragContext * context,guint time)308 target_drag_leave (GtkWidget *widget,
309 GdkDragContext *context,
310 guint time)
311 {
312 g_print("leave\n");
313 have_drag = FALSE;
314 gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed);
315 }
316
317 gboolean
target_drag_motion(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time)318 target_drag_motion (GtkWidget *widget,
319 GdkDragContext *context,
320 gint x,
321 gint y,
322 guint time)
323 {
324 GtkWidget *source_widget;
325 GList *tmp_list;
326
327 if (!have_drag)
328 {
329 have_drag = TRUE;
330 gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_open);
331 }
332
333 source_widget = gtk_drag_get_source_widget (context);
334 g_print ("motion, source %s\n", source_widget ?
335 G_OBJECT_TYPE_NAME (source_widget) :
336 "NULL");
337
338 tmp_list = context->targets;
339 while (tmp_list)
340 {
341 char *name = gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data));
342 g_print ("%s\n", name);
343 g_free (name);
344
345 tmp_list = tmp_list->next;
346 }
347
348 gdk_drag_status (context, context->suggested_action, time);
349 return TRUE;
350 }
351
352 gboolean
target_drag_drop(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time)353 target_drag_drop (GtkWidget *widget,
354 GdkDragContext *context,
355 gint x,
356 gint y,
357 guint time)
358 {
359 g_print("drop\n");
360 have_drag = FALSE;
361
362 gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed);
363
364 if (context->targets)
365 {
366 gtk_drag_get_data (widget, context,
367 GDK_POINTER_TO_ATOM (context->targets->data),
368 time);
369 return TRUE;
370 }
371
372 return FALSE;
373 }
374
375 void
target_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * data,guint info,guint time)376 target_drag_data_received (GtkWidget *widget,
377 GdkDragContext *context,
378 gint x,
379 gint y,
380 GtkSelectionData *data,
381 guint info,
382 guint time)
383 {
384 if ((data->length >= 0) && (data->format == 8))
385 {
386 g_print ("Received \"%s\" in trashcan\n", (gchar *)data->data);
387 gtk_drag_finish (context, TRUE, FALSE, time);
388 return;
389 }
390
391 gtk_drag_finish (context, FALSE, FALSE, time);
392 }
393
394 void
label_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * data,guint info,guint time)395 label_drag_data_received (GtkWidget *widget,
396 GdkDragContext *context,
397 gint x,
398 gint y,
399 GtkSelectionData *data,
400 guint info,
401 guint time)
402 {
403 if ((data->length >= 0) && (data->format == 8))
404 {
405 g_print ("Received \"%s\" in label\n", (gchar *)data->data);
406 gtk_drag_finish (context, TRUE, FALSE, time);
407 return;
408 }
409
410 gtk_drag_finish (context, FALSE, FALSE, time);
411 }
412
413 void
source_drag_data_get(GtkWidget * widget,GdkDragContext * context,GtkSelectionData * selection_data,guint info,guint time,gpointer data)414 source_drag_data_get (GtkWidget *widget,
415 GdkDragContext *context,
416 GtkSelectionData *selection_data,
417 guint info,
418 guint time,
419 gpointer data)
420 {
421 if (info == TARGET_ROOTWIN)
422 g_print ("I was dropped on the rootwin\n");
423 else
424 gtk_selection_data_set (selection_data,
425 selection_data->target,
426 8, (guchar *) "I'm Data!", 9);
427 }
428
429 /* The following is a rather elaborate example demonstrating/testing
430 * changing of the window hierarchy during a drag - in this case,
431 * via a "spring-loaded" popup window.
432 */
433 static GtkWidget *popup_window = NULL;
434
435 static gboolean popped_up = FALSE;
436 static gboolean in_popup = FALSE;
437 static guint popdown_timer = 0;
438 static guint popup_timer = 0;
439
440 gint
popdown_cb(gpointer data)441 popdown_cb (gpointer data)
442 {
443 popdown_timer = 0;
444
445 gtk_widget_hide (popup_window);
446 popped_up = FALSE;
447
448 return FALSE;
449 }
450
451 gboolean
popup_motion(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time)452 popup_motion (GtkWidget *widget,
453 GdkDragContext *context,
454 gint x,
455 gint y,
456 guint time)
457 {
458 if (!in_popup)
459 {
460 in_popup = TRUE;
461 if (popdown_timer)
462 {
463 g_print ("removed popdown\n");
464 g_source_remove (popdown_timer);
465 popdown_timer = 0;
466 }
467 }
468
469 return TRUE;
470 }
471
472 void
popup_leave(GtkWidget * widget,GdkDragContext * context,guint time)473 popup_leave (GtkWidget *widget,
474 GdkDragContext *context,
475 guint time)
476 {
477 if (in_popup)
478 {
479 in_popup = FALSE;
480 if (!popdown_timer)
481 {
482 g_print ("added popdown\n");
483 popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
484 }
485 }
486 }
487
488 gboolean
popup_cb(gpointer data)489 popup_cb (gpointer data)
490 {
491 if (!popped_up)
492 {
493 if (!popup_window)
494 {
495 GtkWidget *button;
496 GtkWidget *table;
497 int i, j;
498
499 popup_window = gtk_window_new (GTK_WINDOW_POPUP);
500 gtk_window_set_position (GTK_WINDOW (popup_window), GTK_WIN_POS_MOUSE);
501
502 table = gtk_table_new (3,3, FALSE);
503
504 for (i=0; i<3; i++)
505 for (j=0; j<3; j++)
506 {
507 char buffer[128];
508 g_snprintf(buffer, sizeof(buffer), "%d,%d", i, j);
509 button = gtk_button_new_with_label (buffer);
510 gtk_table_attach (GTK_TABLE (table), button, i, i+1, j, j+1,
511 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
512 0, 0);
513
514 gtk_drag_dest_set (button,
515 GTK_DEST_DEFAULT_ALL,
516 target_table, n_targets - 1, /* no rootwin */
517 GDK_ACTION_COPY | GDK_ACTION_MOVE);
518 g_signal_connect (button, "drag_motion",
519 G_CALLBACK (popup_motion), NULL);
520 g_signal_connect (button, "drag_leave",
521 G_CALLBACK (popup_leave), NULL);
522 }
523
524 gtk_widget_show_all (table);
525 gtk_container_add (GTK_CONTAINER (popup_window), table);
526
527 }
528 gtk_widget_show (popup_window);
529 popped_up = TRUE;
530 }
531
532 popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
533 g_print ("added popdown\n");
534
535 popup_timer = FALSE;
536
537 return FALSE;
538 }
539
540 gboolean
popsite_motion(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time)541 popsite_motion (GtkWidget *widget,
542 GdkDragContext *context,
543 gint x,
544 gint y,
545 guint time)
546 {
547 if (!popup_timer)
548 popup_timer = gdk_threads_add_timeout (500, popup_cb, NULL);
549
550 return TRUE;
551 }
552
553 void
popsite_leave(GtkWidget * widget,GdkDragContext * context,guint time)554 popsite_leave (GtkWidget *widget,
555 GdkDragContext *context,
556 guint time)
557 {
558 if (popup_timer)
559 {
560 g_source_remove (popup_timer);
561 popup_timer = 0;
562 }
563 }
564
565 void
source_drag_data_delete(GtkWidget * widget,GdkDragContext * context,gpointer data)566 source_drag_data_delete (GtkWidget *widget,
567 GdkDragContext *context,
568 gpointer data)
569 {
570 g_print ("Delete the data!\n");
571 }
572
573 void
test_init(void)574 test_init (void)
575 {
576 if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
577 G_FILE_TEST_EXISTS))
578 {
579 g_setenv ("GDK_PIXBUF_MODULE_FILE", "../gdk-pixbuf/gdk-pixbuf.loaders", TRUE);
580 g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
581 }
582 }
583
584 int
main(int argc,char ** argv)585 main (int argc, char **argv)
586 {
587 GtkWidget *window;
588 GtkWidget *table;
589 GtkWidget *label;
590 GtkWidget *pixmap;
591 GtkWidget *button;
592 GdkPixbuf *drag_icon;
593
594 test_init ();
595
596 gtk_init (&argc, &argv);
597
598 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
599 g_signal_connect (window, "destroy",
600 G_CALLBACK (gtk_main_quit), NULL);
601
602
603 table = gtk_table_new (2, 2, FALSE);
604 gtk_container_add (GTK_CONTAINER (window), table);
605
606 drag_icon = gdk_pixbuf_new_from_xpm_data (drag_icon_xpm);
607 trashcan_open = gdk_pixbuf_new_from_xpm_data (trashcan_open_xpm);
608 trashcan_closed = gdk_pixbuf_new_from_xpm_data (trashcan_closed_xpm);
609
610 label = gtk_label_new ("Drop Here\n");
611
612 gtk_drag_dest_set (label,
613 GTK_DEST_DEFAULT_ALL,
614 target_table, n_targets - 1, /* no rootwin */
615 GDK_ACTION_COPY | GDK_ACTION_MOVE);
616
617 g_signal_connect (label, "drag_data_received",
618 G_CALLBACK( label_drag_data_received), NULL);
619
620 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
621 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
622 0, 0);
623
624 label = gtk_label_new ("Popup\n");
625
626 gtk_drag_dest_set (label,
627 GTK_DEST_DEFAULT_ALL,
628 target_table, n_targets - 1, /* no rootwin */
629 GDK_ACTION_COPY | GDK_ACTION_MOVE);
630
631 gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2,
632 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
633 0, 0);
634
635 g_signal_connect (label, "drag_motion",
636 G_CALLBACK (popsite_motion), NULL);
637 g_signal_connect (label, "drag_leave",
638 G_CALLBACK (popsite_leave), NULL);
639
640 pixmap = gtk_image_new_from_pixbuf (trashcan_closed);
641 gtk_drag_dest_set (pixmap, 0, NULL, 0, 0);
642 gtk_table_attach (GTK_TABLE (table), pixmap, 1, 2, 0, 1,
643 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
644 0, 0);
645
646 g_signal_connect (pixmap, "drag_leave",
647 G_CALLBACK (target_drag_leave), NULL);
648
649 g_signal_connect (pixmap, "drag_motion",
650 G_CALLBACK (target_drag_motion), NULL);
651
652 g_signal_connect (pixmap, "drag_drop",
653 G_CALLBACK (target_drag_drop), NULL);
654
655 g_signal_connect (pixmap, "drag_data_received",
656 G_CALLBACK (target_drag_data_received), NULL);
657
658 /* Drag site */
659
660 button = gtk_button_new_with_label ("Drag Here\n");
661
662 gtk_drag_source_set (button, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
663 target_table, n_targets,
664 GDK_ACTION_COPY | GDK_ACTION_MOVE);
665 gtk_drag_source_set_icon_pixbuf (button, drag_icon);
666
667 g_object_unref (drag_icon);
668
669 gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,
670 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
671 0, 0);
672
673 g_signal_connect (button, "drag_data_get",
674 G_CALLBACK (source_drag_data_get), NULL);
675 g_signal_connect (button, "drag_data_delete",
676 G_CALLBACK (source_drag_data_delete), NULL);
677
678 gtk_widget_show_all (window);
679
680 gtk_main ();
681
682 return 0;
683 }
684