]> Pileus Git - ~andy/gtk/blob - tests/testdnd.c
stylecontext: Do invalidation on first resize container
[~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, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "config.h"
20 #include "gtk/gtk.h"
21
22 /* Target side drag signals */
23
24 /* XPM */
25 static const char * drag_icon_xpm[] = {
26 "36 48 9 1",
27 "       c None",
28 ".      c #020204",
29 "+      c #8F8F90",
30 "@      c #D3D3D2",
31 "#      c #AEAEAC",
32 "$      c #ECECEC",
33 "%      c #A2A2A4",
34 "&      c #FEFEFC",
35 "*      c #BEBEBC",
36 "               .....................",
37 "              ..&&&&&&&&&&&&&&&&&&&.",
38 "             ...&&&&&&&&&&&&&&&&&&&.",
39 "            ..&.&&&&&&&&&&&&&&&&&&&.",
40 "           ..&&.&&&&&&&&&&&&&&&&&&&.",
41 "          ..&&&.&&&&&&&&&&&&&&&&&&&.",
42 "         ..&&&&.&&&&&&&&&&&&&&&&&&&.",
43 "        ..&&&&&.&&&@&&&&&&&&&&&&&&&.",
44 "       ..&&&&&&.*$%$+$&&&&&&&&&&&&&.",
45 "      ..&&&&&&&.%$%$+&&&&&&&&&&&&&&.",
46 "     ..&&&&&&&&.#&#@$&&&&&&&&&&&&&&.",
47 "    ..&&&&&&&&&.#$**#$&&&&&&&&&&&&&.",
48 "   ..&&&&&&&&&&.&@%&%$&&&&&&&&&&&&&.",
49 "  ..&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&.",
50 " ..&&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&.",
51 "................&$@&&&@&&&&&&&&&&&&.",
52 ".&&&&&&&+&&#@%#+@#@*$%$+$&&&&&&&&&&.",
53 ".&&&&&&&+&&#@#@&&@*%$%$+&&&&&&&&&&&.",
54 ".&&&&&&&+&$%&#@&#@@#&#@$&&&&&&&&&&&.",
55 ".&&&&&&@#@@$&*@&@#@#$**#$&&&&&&&&&&.",
56 ".&&&&&&&&&&&&&&&&&&&@%&%$&&&&&&&&&&.",
57 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
58 ".&&&&&&&&$#@@$&&&&&&&&&&&&&&&&&&&&&.",
59 ".&&&&&&&&&+&$+&$&@&$@&&$@&&&&&&&&&&.",
60 ".&&&&&&&&&+&&#@%#+@#@*$%&+$&&&&&&&&.",
61 ".&&&&&&&&&+&&#@#@&&@*%$%$+&&&&&&&&&.",
62 ".&&&&&&&&&+&$%&#@&#@@#&#@$&&&&&&&&&.",
63 ".&&&&&&&&@#@@$&*@&@#@#$#*#$&&&&&&&&.",
64 ".&&&&&&&&&&&&&&&&&&&&&$%&%$&&&&&&&&.",
65 ".&&&&&&&&&&$#@@$&&&&&&&&&&&&&&&&&&&.",
66 ".&&&&&&&&&&&+&$%&$$@&$@&&$@&&&&&&&&.",
67 ".&&&&&&&&&&&+&&#@%#+@#@*$%$+$&&&&&&.",
68 ".&&&&&&&&&&&+&&#@#@&&@*#$%$+&&&&&&&.",
69 ".&&&&&&&&&&&+&$+&*@&#@@#&#@$&&&&&&&.",
70 ".&&&&&&&&&&$%@@&&*@&@#@#$#*#&&&&&&&.",
71 ".&&&&&&&&&&&&&&&&&&&&&&&$%&%$&&&&&&.",
72 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
73 ".&&&&&&&&&&&&&&$#@@$&&&&&&&&&&&&&&&.",
74 ".&&&&&&&&&&&&&&&+&$%&$$@&$@&&$@&&&&.",
75 ".&&&&&&&&&&&&&&&+&&#@%#+@#@*$%$+$&&.",
76 ".&&&&&&&&&&&&&&&+&&#@#@&&@*#$%$+&&&.",
77 ".&&&&&&&&&&&&&&&+&$+&*@&#@@#&#@$&&&.",
78 ".&&&&&&&&&&&&&&$%@@&&*@&@#@#$#*#&&&.",
79 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&$%&%$&&.",
80 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
81 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
82 ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.",
83 "...................................."};
84
85 /* XPM */
86 static const char * trashcan_closed_xpm[] = {
87 "64 80 17 1",
88 "       c None",
89 ".      c #030304",
90 "+      c #5A5A5C",
91 "@      c #323231",
92 "#      c #888888",
93 "$      c #1E1E1F",
94 "%      c #767677",
95 "&      c #494949",
96 "*      c #9E9E9C",
97 "=      c #111111",
98 "-      c #3C3C3D",
99 ";      c #6B6B6B",
100 ">      c #949494",
101 ",      c #282828",
102 "'      c #808080",
103 ")      c #545454",
104 "!      c #AEAEAC",
105 "                                                                ",
106 "                                                                ",
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 /* XPM */
187 static const char * trashcan_open_xpm[] = {
188 "64 80 17 1",
189 "       c None",
190 ".      c #030304",
191 "+      c #5A5A5C",
192 "@      c #323231",
193 "#      c #888888",
194 "$      c #1E1E1F",
195 "%      c #767677",
196 "&      c #494949",
197 "*      c #9E9E9C",
198 "=      c #111111",
199 "-      c #3C3C3D",
200 ";      c #6B6B6B",
201 ">      c #949494",
202 ",      c #282828",
203 "'      c #808080",
204 ")      c #545454",
205 "!      c #AEAEAC",
206 "                                                                ",
207 "                                                                ",
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 GdkPixbuf *trashcan_open;
288 GdkPixbuf *trashcan_closed;
289
290 gboolean have_drag;
291
292 enum {
293   TARGET_STRING,
294   TARGET_ROOTWIN
295 };
296
297 static GtkTargetEntry target_table[] = {
298   { "STRING",     0, TARGET_STRING },
299   { "text/plain", 0, TARGET_STRING },
300   { "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
301 };
302
303 static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
304
305 void  
306 target_drag_leave          (GtkWidget          *widget,
307                             GdkDragContext     *context,
308                             guint               time)
309 {
310   g_print("leave\n");
311   have_drag = FALSE;
312   gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed);
313 }
314
315 gboolean
316 target_drag_motion         (GtkWidget          *widget,
317                             GdkDragContext     *context,
318                             gint                x,
319                             gint                y,
320                             guint               time)
321 {
322   GtkWidget *source_widget;
323   GList *tmp_list;
324
325   if (!have_drag)
326     {
327       have_drag = TRUE;
328       gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_open);
329     }
330
331   source_widget = gtk_drag_get_source_widget (context);
332   g_print ("motion, source %s\n", source_widget ?
333            G_OBJECT_TYPE_NAME (source_widget) :
334            "NULL");
335
336   tmp_list = gdk_drag_context_list_targets (context);
337   while (tmp_list)
338     {
339       char *name = gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data));
340       g_print ("%s\n", name);
341       g_free (name);
342       
343       tmp_list = tmp_list->next;
344     }
345
346   gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time);
347
348   return TRUE;
349 }
350
351 gboolean
352 target_drag_drop           (GtkWidget          *widget,
353                             GdkDragContext     *context,
354                             gint                x,
355                             gint                y,
356                             guint               time)
357 {
358   g_print("drop\n");
359   have_drag = FALSE;
360
361   gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed);
362
363   if (gdk_drag_context_list_targets (context))
364     {
365       gtk_drag_get_data (widget, context,
366                          GDK_POINTER_TO_ATOM (gdk_drag_context_list_targets (context)->data),
367                          time);
368       return TRUE;
369     }
370   
371   return FALSE;
372 }
373
374 void  
375 target_drag_data_received  (GtkWidget          *widget,
376                             GdkDragContext     *context,
377                             gint                x,
378                             gint                y,
379                             GtkSelectionData   *selection_data,
380                             guint               info,
381                             guint               time)
382 {
383   if (gtk_selection_data_get_length (selection_data) >= 0 &&
384       gtk_selection_data_get_format (selection_data) == 8)
385     {
386       g_print ("Received \"%s\" in trashcan\n", (gchar *) gtk_selection_data_get_data (selection_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  
395 label_drag_data_received  (GtkWidget          *widget,
396                             GdkDragContext     *context,
397                             gint                x,
398                             gint                y,
399                             GtkSelectionData   *selection_data,
400                             guint               info,
401                             guint               time)
402 {
403   if (gtk_selection_data_get_length (selection_data) >= 0 &&
404       gtk_selection_data_get_format (selection_data) == 8)
405     {
406       g_print ("Received \"%s\" in label\n", (gchar *) gtk_selection_data_get_data (selection_data));
407       gtk_drag_finish (context, TRUE, FALSE, time);
408       return;
409     }
410   
411   gtk_drag_finish (context, FALSE, FALSE, time);
412 }
413
414 void  
415 source_drag_data_get  (GtkWidget          *widget,
416                        GdkDragContext     *context,
417                        GtkSelectionData   *selection_data,
418                        guint               info,
419                        guint               time,
420                        gpointer            data)
421 {
422   if (info == TARGET_ROOTWIN)
423     g_print ("I was dropped on the rootwin\n");
424   else
425     gtk_selection_data_set (selection_data,
426                             gtk_selection_data_get_target (selection_data),
427                             8, (guchar *) "I'm Data!", 9);
428 }
429   
430 /* The following is a rather elaborate example demonstrating/testing
431  * changing of the window hierarchy during a drag - in this case,
432  * via a "spring-loaded" popup window.
433  */
434 static GtkWidget *popup_window = NULL;
435
436 static gboolean popped_up = FALSE;
437 static gboolean in_popup = FALSE;
438 static guint popdown_timer = 0;
439 static guint popup_timer = 0;
440
441 gint
442 popdown_cb (gpointer data)
443 {
444   popdown_timer = 0;
445
446   gtk_widget_hide (popup_window);
447   popped_up = FALSE;
448
449   return FALSE;
450 }
451
452 gboolean
453 popup_motion       (GtkWidget          *widget,
454                     GdkDragContext     *context,
455                     gint                x,
456                     gint                y,
457                     guint               time)
458 {
459   if (!in_popup)
460     {
461       in_popup = TRUE;
462       if (popdown_timer)
463         {
464           g_print ("removed popdown\n");
465           g_source_remove (popdown_timer);
466           popdown_timer = 0;
467         }
468     }
469
470   return TRUE;
471 }
472
473 void  
474 popup_leave        (GtkWidget          *widget,
475                     GdkDragContext     *context,
476                     guint               time)
477 {
478   if (in_popup)
479     {
480       in_popup = FALSE;
481       if (!popdown_timer)
482         {
483           g_print ("added popdown\n");
484           popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
485         }
486     }
487 }
488
489 gboolean
490 popup_cb (gpointer data)
491 {
492   if (!popped_up)
493     {
494       if (!popup_window)
495         {
496           GtkWidget *button;
497           GtkWidget *grid;
498           int i, j;
499           
500           popup_window = gtk_window_new (GTK_WINDOW_POPUP);
501           gtk_window_set_position (GTK_WINDOW (popup_window), GTK_WIN_POS_MOUSE);
502
503           grid = gtk_grid_new ();
504
505           for (i=0; i<3; i++)
506             for (j=0; j<3; j++)
507               {
508                 char buffer[128];
509                 g_snprintf(buffer, sizeof(buffer), "%d,%d", i, j);
510                 button = gtk_button_new_with_label (buffer);
511                 gtk_widget_set_hexpand (button, TRUE);
512                 gtk_widget_set_vexpand (button, TRUE);
513                 gtk_grid_attach (GTK_GRID (grid), button, i, j, 1, 1);
514
515                 gtk_drag_dest_set (button,
516                                    GTK_DEST_DEFAULT_ALL,
517                                    target_table, n_targets - 1, /* no rootwin */
518                                    GDK_ACTION_COPY | GDK_ACTION_MOVE);
519                 g_signal_connect (button, "drag_motion",
520                                   G_CALLBACK (popup_motion), NULL);
521                 g_signal_connect (button, "drag_leave",
522                                   G_CALLBACK (popup_leave), NULL);
523               }
524
525           gtk_widget_show_all (grid);
526           gtk_container_add (GTK_CONTAINER (popup_window), grid);
527
528         }
529       gtk_widget_show (popup_window);
530       popped_up = TRUE;
531     }
532
533   popdown_timer = gdk_threads_add_timeout (500, popdown_cb, NULL);
534   g_print ("added popdown\n");
535
536   popup_timer = FALSE;
537
538   return FALSE;
539 }
540
541 gboolean
542 popsite_motion     (GtkWidget          *widget,
543                     GdkDragContext     *context,
544                     gint                x,
545                     gint                y,
546                     guint               time)
547 {
548   if (!popup_timer)
549     popup_timer = gdk_threads_add_timeout (500, popup_cb, NULL);
550
551   return TRUE;
552 }
553
554 void  
555 popsite_leave      (GtkWidget          *widget,
556                     GdkDragContext     *context,
557                     guint               time)
558 {
559   if (popup_timer)
560     {
561       g_source_remove (popup_timer);
562       popup_timer = 0;
563     }
564 }
565
566 void  
567 source_drag_data_delete  (GtkWidget          *widget,
568                           GdkDragContext     *context,
569                           gpointer            data)
570 {
571   g_print ("Delete the data!\n");
572 }
573   
574 void
575 test_init (void)
576 {
577   if (g_file_test ("../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
578     g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
579 }
580
581 int 
582 main (int argc, char **argv)
583 {
584   GtkWidget *window;
585   GtkWidget *grid;
586   GtkWidget *label;
587   GtkWidget *pixmap;
588   GtkWidget *button;
589   GdkPixbuf *drag_icon;
590
591   test_init ();
592   
593   gtk_init (&argc, &argv); 
594
595   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
596   g_signal_connect (window, "destroy",
597                     G_CALLBACK (gtk_main_quit), NULL);
598
599   
600   grid = gtk_grid_new ();
601   gtk_container_add (GTK_CONTAINER (window), grid);
602
603   drag_icon = gdk_pixbuf_new_from_xpm_data (drag_icon_xpm);
604   trashcan_open = gdk_pixbuf_new_from_xpm_data (trashcan_open_xpm);
605   trashcan_closed = gdk_pixbuf_new_from_xpm_data (trashcan_closed_xpm);
606   
607   label = gtk_label_new ("Drop Here\n");
608
609   gtk_drag_dest_set (label,
610                      GTK_DEST_DEFAULT_ALL,
611                      target_table, n_targets - 1, /* no rootwin */
612                      GDK_ACTION_COPY | GDK_ACTION_MOVE);
613
614   g_signal_connect (label, "drag_data_received",
615                     G_CALLBACK( label_drag_data_received), NULL);
616
617   gtk_widget_set_hexpand (label, TRUE);
618   gtk_widget_set_vexpand (label, TRUE);
619   gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
620
621   label = gtk_label_new ("Popup\n");
622
623   gtk_drag_dest_set (label,
624                      GTK_DEST_DEFAULT_ALL,
625                      target_table, n_targets - 1, /* no rootwin */
626                      GDK_ACTION_COPY | GDK_ACTION_MOVE);
627
628   gtk_widget_set_hexpand (label, TRUE);
629   gtk_widget_set_vexpand (label, TRUE);
630   gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
631
632   g_signal_connect (label, "drag_motion",
633                     G_CALLBACK (popsite_motion), NULL);
634   g_signal_connect (label, "drag_leave",
635                     G_CALLBACK (popsite_leave), NULL);
636   
637   pixmap = gtk_image_new_from_pixbuf (trashcan_closed);
638   gtk_drag_dest_set (pixmap, 0, NULL, 0, 0);
639   gtk_widget_set_hexpand (pixmap, TRUE);
640   gtk_widget_set_vexpand (pixmap, TRUE);
641   gtk_grid_attach (GTK_GRID (grid), pixmap, 1, 0, 1, 1);
642
643   g_signal_connect (pixmap, "drag_leave",
644                     G_CALLBACK (target_drag_leave), NULL);
645
646   g_signal_connect (pixmap, "drag_motion",
647                     G_CALLBACK (target_drag_motion), NULL);
648
649   g_signal_connect (pixmap, "drag_drop",
650                     G_CALLBACK (target_drag_drop), NULL);
651
652   g_signal_connect (pixmap, "drag_data_received",
653                     G_CALLBACK (target_drag_data_received), NULL);
654
655   /* Drag site */
656
657   button = gtk_button_new_with_label ("Drag Here\n");
658
659   gtk_drag_source_set (button, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
660                        target_table, n_targets, 
661                        GDK_ACTION_COPY | GDK_ACTION_MOVE);
662   gtk_drag_source_set_icon_pixbuf (button, drag_icon);
663
664   g_object_unref (drag_icon);
665
666   gtk_widget_set_hexpand (button, TRUE);
667   gtk_widget_set_vexpand (button, TRUE);
668   gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 1, 1);
669
670   g_signal_connect (button, "drag_data_get",
671                     G_CALLBACK (source_drag_data_get), NULL);
672   g_signal_connect (button, "drag_data_delete",
673                     G_CALLBACK (source_drag_data_delete), NULL);
674
675   gtk_widget_show_all (window);
676
677   gtk_main ();
678
679   return 0;
680 }