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