]> Pileus Git - ~andy/gtk/blob - tests/testdnd.c
Merge branch 'master' into treeview-refactor
[~andy/gtk] / tests / testdnd.c
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  
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
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
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  
376 target_drag_data_received  (GtkWidget          *widget,
377                             GdkDragContext     *context,
378                             gint                x,
379                             gint                y,
380                             GtkSelectionData   *selection_data,
381                             guint               info,
382                             guint               time)
383 {
384   if (gtk_selection_data_get_length (selection_data) >= 0 &&
385       gtk_selection_data_get_format (selection_data) == 8)
386     {
387       g_print ("Received \"%s\" in trashcan\n", (gchar *) gtk_selection_data_get_data (selection_data));
388       gtk_drag_finish (context, TRUE, FALSE, time);
389       return;
390     }
391   
392   gtk_drag_finish (context, FALSE, FALSE, time);
393 }
394   
395 void  
396 label_drag_data_received  (GtkWidget          *widget,
397                             GdkDragContext     *context,
398                             gint                x,
399                             gint                y,
400                             GtkSelectionData   *selection_data,
401                             guint               info,
402                             guint               time)
403 {
404   if (gtk_selection_data_get_length (selection_data) >= 0 &&
405       gtk_selection_data_get_format (selection_data) == 8)
406     {
407       g_print ("Received \"%s\" in label\n", (gchar *) gtk_selection_data_get_data (selection_data));
408       gtk_drag_finish (context, TRUE, FALSE, time);
409       return;
410     }
411   
412   gtk_drag_finish (context, FALSE, FALSE, time);
413 }
414
415 void  
416 source_drag_data_get  (GtkWidget          *widget,
417                        GdkDragContext     *context,
418                        GtkSelectionData   *selection_data,
419                        guint               info,
420                        guint               time,
421                        gpointer            data)
422 {
423   if (info == TARGET_ROOTWIN)
424     g_print ("I was dropped on the rootwin\n");
425   else
426     gtk_selection_data_set (selection_data,
427                             gtk_selection_data_get_target (selection_data),
428                             8, (guchar *) "I'm Data!", 9);
429 }
430   
431 /* The following is a rather elaborate example demonstrating/testing
432  * changing of the window hierarchy during a drag - in this case,
433  * via a "spring-loaded" popup window.
434  */
435 static GtkWidget *popup_window = NULL;
436
437 static gboolean popped_up = FALSE;
438 static gboolean in_popup = FALSE;
439 static guint popdown_timer = 0;
440 static guint popup_timer = 0;
441
442 gint
443 popdown_cb (gpointer data)
444 {
445   popdown_timer = 0;
446
447   gtk_widget_hide (popup_window);
448   popped_up = FALSE;
449
450   return FALSE;
451 }
452
453 gboolean
454 popup_motion       (GtkWidget          *widget,
455                     GdkDragContext     *context,
456                     gint                x,
457                     gint                y,
458                     guint               time)
459 {
460   if (!in_popup)
461     {
462       in_popup = TRUE;
463       if (popdown_timer)
464         {
465           g_print ("removed popdown\n");
466           g_source_remove (popdown_timer);
467           popdown_timer = 0;
468         }
469     }
470
471   return TRUE;
472 }
473
474 void  
475 popup_leave        (GtkWidget          *widget,
476                     GdkDragContext     *context,
477                     guint               time)
478 {
479   if (in_popup)
480     {
481       in_popup = FALSE;
482       if (!popdown_timer)
483         {
484           g_print ("added popdown\n");
485           popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
486         }
487     }
488 }
489
490 gboolean
491 popup_cb (gpointer data)
492 {
493   if (!popped_up)
494     {
495       if (!popup_window)
496         {
497           GtkWidget *button;
498           GtkWidget *table;
499           int i, j;
500           
501           popup_window = gtk_window_new (GTK_WINDOW_POPUP);
502           gtk_window_set_position (GTK_WINDOW (popup_window), GTK_WIN_POS_MOUSE);
503
504           table = gtk_table_new (3,3, FALSE);
505
506           for (i=0; i<3; i++)
507             for (j=0; j<3; j++)
508               {
509                 char buffer[128];
510                 g_snprintf(buffer, sizeof(buffer), "%d,%d", i, j);
511                 button = gtk_button_new_with_label (buffer);
512                 gtk_table_attach (GTK_TABLE (table), button, i, i+1, j, j+1,
513                                   GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
514                                   0, 0);
515
516                 gtk_drag_dest_set (button,
517                                    GTK_DEST_DEFAULT_ALL,
518                                    target_table, n_targets - 1, /* no rootwin */
519                                    GDK_ACTION_COPY | GDK_ACTION_MOVE);
520                 g_signal_connect (button, "drag_motion",
521                                   G_CALLBACK (popup_motion), NULL);
522                 g_signal_connect (button, "drag_leave",
523                                   G_CALLBACK (popup_leave), NULL);
524               }
525
526           gtk_widget_show_all (table);
527           gtk_container_add (GTK_CONTAINER (popup_window), table);
528
529         }
530       gtk_widget_show (popup_window);
531       popped_up = TRUE;
532     }
533
534   popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
535   g_print ("added popdown\n");
536
537   popup_timer = FALSE;
538
539   return FALSE;
540 }
541
542 gboolean
543 popsite_motion     (GtkWidget          *widget,
544                     GdkDragContext     *context,
545                     gint                x,
546                     gint                y,
547                     guint               time)
548 {
549   if (!popup_timer)
550     popup_timer = gdk_threads_add_timeout (500, popup_cb, NULL);
551
552   return TRUE;
553 }
554
555 void  
556 popsite_leave      (GtkWidget          *widget,
557                     GdkDragContext     *context,
558                     guint               time)
559 {
560   if (popup_timer)
561     {
562       g_source_remove (popup_timer);
563       popup_timer = 0;
564     }
565 }
566
567 void  
568 source_drag_data_delete  (GtkWidget          *widget,
569                           GdkDragContext     *context,
570                           gpointer            data)
571 {
572   g_print ("Delete the data!\n");
573 }
574   
575 void
576 test_init (void)
577 {
578   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
579                    G_FILE_TEST_EXISTS))
580     {
581       g_setenv ("GDK_PIXBUF_MODULE_FILE", "../gdk-pixbuf/loaders.cache", TRUE);
582       g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
583     }
584 }
585
586 int 
587 main (int argc, char **argv)
588 {
589   GtkWidget *window;
590   GtkWidget *table;
591   GtkWidget *label;
592   GtkWidget *pixmap;
593   GtkWidget *button;
594   GdkPixbuf *drag_icon;
595
596   test_init ();
597   
598   gtk_init (&argc, &argv); 
599
600   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
601   g_signal_connect (window, "destroy",
602                     G_CALLBACK (gtk_main_quit), NULL);
603
604   
605   table = gtk_table_new (2, 2, FALSE);
606   gtk_container_add (GTK_CONTAINER (window), table);
607
608   drag_icon = gdk_pixbuf_new_from_xpm_data (drag_icon_xpm);
609   trashcan_open = gdk_pixbuf_new_from_xpm_data (trashcan_open_xpm);
610   trashcan_closed = gdk_pixbuf_new_from_xpm_data (trashcan_closed_xpm);
611   
612   label = gtk_label_new ("Drop Here\n");
613
614   gtk_drag_dest_set (label,
615                      GTK_DEST_DEFAULT_ALL,
616                      target_table, n_targets - 1, /* no rootwin */
617                      GDK_ACTION_COPY | GDK_ACTION_MOVE);
618
619   g_signal_connect (label, "drag_data_received",
620                     G_CALLBACK( label_drag_data_received), NULL);
621
622   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
623                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
624                     0, 0);
625
626   label = gtk_label_new ("Popup\n");
627
628   gtk_drag_dest_set (label,
629                      GTK_DEST_DEFAULT_ALL,
630                      target_table, n_targets - 1, /* no rootwin */
631                      GDK_ACTION_COPY | GDK_ACTION_MOVE);
632
633   gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2,
634                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
635                     0, 0);
636
637   g_signal_connect (label, "drag_motion",
638                     G_CALLBACK (popsite_motion), NULL);
639   g_signal_connect (label, "drag_leave",
640                     G_CALLBACK (popsite_leave), NULL);
641   
642   pixmap = gtk_image_new_from_pixbuf (trashcan_closed);
643   gtk_drag_dest_set (pixmap, 0, NULL, 0, 0);
644   gtk_table_attach (GTK_TABLE (table), pixmap, 1, 2, 0, 1,
645                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
646                     0, 0);
647
648   g_signal_connect (pixmap, "drag_leave",
649                     G_CALLBACK (target_drag_leave), NULL);
650
651   g_signal_connect (pixmap, "drag_motion",
652                     G_CALLBACK (target_drag_motion), NULL);
653
654   g_signal_connect (pixmap, "drag_drop",
655                     G_CALLBACK (target_drag_drop), NULL);
656
657   g_signal_connect (pixmap, "drag_data_received",
658                     G_CALLBACK (target_drag_data_received), NULL);
659
660   /* Drag site */
661
662   button = gtk_button_new_with_label ("Drag Here\n");
663
664   gtk_drag_source_set (button, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
665                        target_table, n_targets, 
666                        GDK_ACTION_COPY | GDK_ACTION_MOVE);
667   gtk_drag_source_set_icon_pixbuf (button, drag_icon);
668
669   g_object_unref (drag_icon);
670
671   gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,
672                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
673                     0, 0);
674
675   g_signal_connect (button, "drag_data_get",
676                     G_CALLBACK (source_drag_data_get), NULL);
677   g_signal_connect (button, "drag_data_delete",
678                     G_CALLBACK (source_drag_data_delete), NULL);
679
680   gtk_widget_show_all (window);
681
682   gtk_main ();
683
684   return 0;
685 }