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