]> Pileus Git - ~andy/gtk/blob - tests/testdnd.c
Deprecate flag macros for toplevel, state, no window and composite child
[~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 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 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 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 GdkPixmap *trashcan_open;
290 GdkPixmap *trashcan_open_mask;
291 GdkPixmap *trashcan_closed;
292 GdkPixmap *trashcan_closed_mask;
293
294 gboolean have_drag;
295
296 enum {
297   TARGET_STRING,
298   TARGET_ROOTWIN
299 };
300
301 static GtkTargetEntry target_table[] = {
302   { "STRING",     0, TARGET_STRING },
303   { "text/plain", 0, TARGET_STRING },
304   { "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
305 };
306
307 static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
308
309 void  
310 target_drag_leave          (GtkWidget          *widget,
311                             GdkDragContext     *context,
312                             guint               time)
313 {
314   g_print("leave\n");
315   have_drag = FALSE;
316   gtk_image_set_from_pixmap (GTK_IMAGE (widget),
317                              trashcan_closed, trashcan_closed_mask);
318 }
319
320 gboolean
321 target_drag_motion         (GtkWidget          *widget,
322                             GdkDragContext     *context,
323                             gint                x,
324                             gint                y,
325                             guint               time)
326 {
327   GtkWidget *source_widget;
328   GList *tmp_list;
329
330   if (!have_drag)
331     {
332       have_drag = TRUE;
333       gtk_image_set_from_pixmap (GTK_IMAGE (widget),
334                                  trashcan_open, trashcan_open_mask);
335     }
336
337   source_widget = gtk_drag_get_source_widget (context);
338   g_print ("motion, source %s\n", source_widget ?
339            G_OBJECT_TYPE_NAME (source_widget) :
340            "NULL");
341
342   tmp_list = context->targets;
343   while (tmp_list)
344     {
345       char *name = gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data));
346       g_print ("%s\n", name);
347       g_free (name);
348       
349       tmp_list = tmp_list->next;
350     }
351
352   gdk_drag_status (context, context->suggested_action, time);
353   return TRUE;
354 }
355
356 gboolean
357 target_drag_drop           (GtkWidget          *widget,
358                             GdkDragContext     *context,
359                             gint                x,
360                             gint                y,
361                             guint               time)
362 {
363   g_print("drop\n");
364   have_drag = FALSE;
365
366   gtk_image_set_from_pixmap (GTK_IMAGE (widget),
367                              trashcan_closed, trashcan_closed_mask);
368
369   if (context->targets)
370     {
371       gtk_drag_get_data (widget, context, 
372                          GDK_POINTER_TO_ATOM (context->targets->data), 
373                          time);
374       return TRUE;
375     }
376   
377   return FALSE;
378 }
379
380 void  
381 target_drag_data_received  (GtkWidget          *widget,
382                             GdkDragContext     *context,
383                             gint                x,
384                             gint                y,
385                             GtkSelectionData   *data,
386                             guint               info,
387                             guint               time)
388 {
389   if ((data->length >= 0) && (data->format == 8))
390     {
391       g_print ("Received \"%s\" in trashcan\n", (gchar *)data->data);
392       gtk_drag_finish (context, TRUE, FALSE, time);
393       return;
394     }
395   
396   gtk_drag_finish (context, FALSE, FALSE, time);
397 }
398   
399 void  
400 label_drag_data_received  (GtkWidget          *widget,
401                             GdkDragContext     *context,
402                             gint                x,
403                             gint                y,
404                             GtkSelectionData   *data,
405                             guint               info,
406                             guint               time)
407 {
408   if ((data->length >= 0) && (data->format == 8))
409     {
410       g_print ("Received \"%s\" in label\n", (gchar *)data->data);
411       gtk_drag_finish (context, TRUE, FALSE, time);
412       return;
413     }
414   
415   gtk_drag_finish (context, FALSE, FALSE, time);
416 }
417
418 void  
419 source_drag_data_get  (GtkWidget          *widget,
420                        GdkDragContext     *context,
421                        GtkSelectionData   *selection_data,
422                        guint               info,
423                        guint               time,
424                        gpointer            data)
425 {
426   if (info == TARGET_ROOTWIN)
427     g_print ("I was dropped on the rootwin\n");
428   else
429     gtk_selection_data_set (selection_data,
430                             selection_data->target,
431                             8, (guchar *) "I'm Data!", 9);
432 }
433   
434 /* The following is a rather elaborate example demonstrating/testing
435  * changing of the window hierarchy during a drag - in this case,
436  * via a "spring-loaded" popup window.
437  */
438 static GtkWidget *popup_window = NULL;
439
440 static gboolean popped_up = FALSE;
441 static gboolean in_popup = FALSE;
442 static guint popdown_timer = 0;
443 static guint popup_timer = 0;
444
445 gint
446 popdown_cb (gpointer data)
447 {
448   popdown_timer = 0;
449
450   gtk_widget_hide (popup_window);
451   popped_up = FALSE;
452
453   return FALSE;
454 }
455
456 gboolean
457 popup_motion       (GtkWidget          *widget,
458                     GdkDragContext     *context,
459                     gint                x,
460                     gint                y,
461                     guint               time)
462 {
463   if (!in_popup)
464     {
465       in_popup = TRUE;
466       if (popdown_timer)
467         {
468           g_print ("removed popdown\n");
469           g_source_remove (popdown_timer);
470           popdown_timer = 0;
471         }
472     }
473
474   return TRUE;
475 }
476
477 void  
478 popup_leave        (GtkWidget          *widget,
479                     GdkDragContext     *context,
480                     guint               time)
481 {
482   if (in_popup)
483     {
484       in_popup = FALSE;
485       if (!popdown_timer)
486         {
487           g_print ("added popdown\n");
488           popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
489         }
490     }
491 }
492
493 gboolean
494 popup_cb (gpointer data)
495 {
496   if (!popped_up)
497     {
498       if (!popup_window)
499         {
500           GtkWidget *button;
501           GtkWidget *table;
502           int i, j;
503           
504           popup_window = gtk_window_new (GTK_WINDOW_POPUP);
505           gtk_window_set_position (GTK_WINDOW (popup_window), GTK_WIN_POS_MOUSE);
506
507           table = gtk_table_new (3,3, FALSE);
508
509           for (i=0; i<3; i++)
510             for (j=0; j<3; j++)
511               {
512                 char buffer[128];
513                 g_snprintf(buffer, sizeof(buffer), "%d,%d", i, j);
514                 button = gtk_button_new_with_label (buffer);
515                 gtk_table_attach (GTK_TABLE (table), button, i, i+1, j, j+1,
516                                   GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
517                                   0, 0);
518
519                 gtk_drag_dest_set (button,
520                                    GTK_DEST_DEFAULT_ALL,
521                                    target_table, n_targets - 1, /* no rootwin */
522                                    GDK_ACTION_COPY | GDK_ACTION_MOVE);
523                 g_signal_connect (button, "drag_motion",
524                                   G_CALLBACK (popup_motion), NULL);
525                 g_signal_connect (button, "drag_leave",
526                                   G_CALLBACK (popup_leave), NULL);
527               }
528
529           gtk_widget_show_all (table);
530           gtk_container_add (GTK_CONTAINER (popup_window), table);
531
532         }
533       gtk_widget_show (popup_window);
534       popped_up = TRUE;
535     }
536
537   popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
538   g_print ("added popdown\n");
539
540   popup_timer = FALSE;
541
542   return FALSE;
543 }
544
545 gboolean
546 popsite_motion     (GtkWidget          *widget,
547                     GdkDragContext     *context,
548                     gint                x,
549                     gint                y,
550                     guint               time)
551 {
552   if (!popup_timer)
553     popup_timer = gdk_threads_add_timeout (500, popup_cb, NULL);
554
555   return TRUE;
556 }
557
558 void  
559 popsite_leave      (GtkWidget          *widget,
560                     GdkDragContext     *context,
561                     guint               time)
562 {
563   if (popup_timer)
564     {
565       g_source_remove (popup_timer);
566       popup_timer = 0;
567     }
568 }
569
570 void  
571 source_drag_data_delete  (GtkWidget          *widget,
572                           GdkDragContext     *context,
573                           gpointer            data)
574 {
575   g_print ("Delete the data!\n");
576 }
577   
578 void
579 test_init (void)
580 {
581   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
582                    G_FILE_TEST_EXISTS))
583     {
584       g_setenv ("GDK_PIXBUF_MODULE_FILE", "../gdk-pixbuf/gdk-pixbuf.loaders", TRUE);
585       g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/gtk.immodules", TRUE);
586     }
587 }
588
589 int 
590 main (int argc, char **argv)
591 {
592   GtkWidget *window;
593   GtkWidget *table;
594   GtkWidget *label;
595   GtkWidget *pixmap;
596   GtkWidget *button;
597   GdkPixmap *drag_icon;
598   GdkPixmap *drag_mask;
599
600   test_init ();
601   
602   gtk_init (&argc, &argv); 
603
604   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
605   g_signal_connect (window, "destroy",
606                     G_CALLBACK (gtk_main_quit), NULL);
607
608   
609   table = gtk_table_new (2, 2, FALSE);
610   gtk_container_add (GTK_CONTAINER (window), table);
611
612   drag_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL,
613                                                      gtk_widget_get_colormap (window),
614                                                      &drag_mask,
615                                                      NULL, drag_icon_xpm);
616
617   trashcan_open = gdk_pixmap_colormap_create_from_xpm_d (NULL,
618                                                          gtk_widget_get_colormap (window),
619                                                          &trashcan_open_mask,
620                                                          NULL, trashcan_open_xpm);
621   trashcan_closed = gdk_pixmap_colormap_create_from_xpm_d (NULL,
622                                                            gtk_widget_get_colormap (window),
623                                                            &trashcan_closed_mask,
624                                                            NULL, trashcan_closed_xpm);
625   
626   label = gtk_label_new ("Drop Here\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   g_signal_connect (label, "drag_data_received",
634                     G_CALLBACK( label_drag_data_received), NULL);
635
636   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
637                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
638                     0, 0);
639
640   label = gtk_label_new ("Popup\n");
641
642   gtk_drag_dest_set (label,
643                      GTK_DEST_DEFAULT_ALL,
644                      target_table, n_targets - 1, /* no rootwin */
645                      GDK_ACTION_COPY | GDK_ACTION_MOVE);
646
647   gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2,
648                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
649                     0, 0);
650
651   g_signal_connect (label, "drag_motion",
652                     G_CALLBACK (popsite_motion), NULL);
653   g_signal_connect (label, "drag_leave",
654                     G_CALLBACK (popsite_leave), NULL);
655   
656   pixmap = gtk_image_new_from_pixmap (trashcan_closed, trashcan_closed_mask);
657   gtk_drag_dest_set (pixmap, 0, NULL, 0, 0);
658   gtk_table_attach (GTK_TABLE (table), pixmap, 1, 2, 0, 1,
659                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
660                     0, 0);
661
662   g_signal_connect (pixmap, "drag_leave",
663                     G_CALLBACK (target_drag_leave), NULL);
664
665   g_signal_connect (pixmap, "drag_motion",
666                     G_CALLBACK (target_drag_motion), NULL);
667
668   g_signal_connect (pixmap, "drag_drop",
669                     G_CALLBACK (target_drag_drop), NULL);
670
671   g_signal_connect (pixmap, "drag_data_received",
672                     G_CALLBACK (target_drag_data_received), NULL);
673
674   /* Drag site */
675
676   button = gtk_button_new_with_label ("Drag Here\n");
677
678   gtk_drag_source_set (button, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
679                        target_table, n_targets, 
680                        GDK_ACTION_COPY | GDK_ACTION_MOVE);
681   gtk_drag_source_set_icon (button, 
682                             gtk_widget_get_colormap (window),
683                             drag_icon, drag_mask);
684
685   g_object_unref (drag_icon);
686   g_object_unref (drag_mask);
687
688   gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,
689                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
690                     0, 0);
691
692   g_signal_connect (button, "drag_data_get",
693                     G_CALLBACK (source_drag_data_get), NULL);
694   g_signal_connect (button, "drag_data_delete",
695                     G_CALLBACK (source_drag_data_delete), NULL);
696
697   gtk_widget_show_all (window);
698
699   gtk_main ();
700
701   return 0;
702 }