]> Pileus Git - ~andy/gtk/blob - gdk/gdkdnd.c
0d5e5bec44f77feab30a83a80e750384762978b4
[~andy/gtk] / gdk / gdkdnd.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28
29 #include "gdkdnd.h"
30 #include "gdkinternals.h"
31 #include "gdkdisplay.h"
32 #include "gdkwindow.h"
33
34
35 /**
36  * SECTION:dnd
37  * @title: Drag And Drop
38  * @short_description: Functions for controlling drag and drop handling
39  *
40  * These functions provide a low level interface for drag and drop.
41  * The X backend of GDK supports both the Xdnd and Motif drag and drop
42  * protocols transparently, the Win32 backend supports the WM_DROPFILES
43  * protocol.
44  *
45  * GTK+ provides a higher level abstraction based on top of these functions,
46  * and so they are not normally needed in GTK+ applications.
47  * See the <link linkend="gtk-Drag-and-Drop">Drag and Drop</link> section of
48  * the GTK+ documentation for more information.
49  */
50
51 /**
52  * gdk_drag_context_list_targets:
53  * @context: a #GdkDragContext
54  *
55  * Retrieves the list of targets of the context.
56  *
57  * Return value: (transfer none) (element-type GdkAtom): a #GList of targets
58  *
59  * Since: 2.22
60  **/
61 GList *
62 gdk_drag_context_list_targets (GdkDragContext *context)
63 {
64   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
65
66   return context->targets;
67 }
68
69 /**
70  * gdk_drag_context_get_actions:
71  * @context: a #GdkDragContext
72  *
73  * Determines the bitmask of actions proposed by the source if
74  * gdk_drag_context_suggested_action() returns GDK_ACTION_ASK.
75  *
76  * Return value: the #GdkDragAction flags
77  *
78  * Since: 2.22
79  **/
80 GdkDragAction
81 gdk_drag_context_get_actions (GdkDragContext *context)
82 {
83   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_ACTION_DEFAULT);
84
85   return context->actions;
86 }
87
88 /**
89  * gdk_drag_context_get_suggested_action:
90  * @context: a #GdkDragContext
91  *
92  * Determines the suggested drag action of the context.
93  *
94  * Return value: a #GdkDragAction value
95  *
96  * Since: 2.22
97  **/
98 GdkDragAction
99 gdk_drag_context_get_suggested_action (GdkDragContext *context)
100 {
101   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0);
102
103   return context->suggested_action;
104 }
105
106 /**
107  * gdk_drag_context_get_selected_action:
108  * @context: a #GdkDragContext
109  *
110  * Determines the action chosen by the drag destination.
111  *
112  * Return value: a #GdkDragAction value
113  *
114  * Since: 2.22
115  **/
116 GdkDragAction
117 gdk_drag_context_get_selected_action (GdkDragContext *context)
118 {
119   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0);
120
121   return context->action;
122 }
123
124 /**
125  * gdk_drag_context_get_source_window:
126  * @context: a #GdkDragContext
127  *
128  * Returns the #GdkWindow where the DND operation started.
129  *
130  * Return value: (transfer none): a #GdkWindow
131  *
132  * Since: 2.22
133  **/
134 GdkWindow *
135 gdk_drag_context_get_source_window (GdkDragContext *context)
136 {
137   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
138
139   return context->source_window;
140 }
141
142 /**
143  * gdk_drag_context_get_dest_window:
144  * @context: a #GdkDragContext
145  *
146  * Returns the destination windw for the DND operation.
147  *
148  * Return value: (transfer none): a #GdkWindow
149  *
150  * Since: 3.0
151  **/
152 GdkWindow *
153 gdk_drag_context_get_dest_window (GdkDragContext *context)
154 {
155   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
156
157   return context->dest_window;
158 }
159
160 /**
161  * gdk_drag_context_get_protocol:
162  * @context: a #GdkDragContext
163  *
164  * Returns the drag protocol thats used by this context.
165  *
166  * Returns: the drag protocol
167  *
168  * Since: 3.0
169  */
170 GdkDragProtocol
171 gdk_drag_context_get_protocol (GdkDragContext *context)
172 {
173   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_DRAG_PROTO_NONE);
174
175   return context->protocol;
176 }
177
178 /**
179  * gdk_drag_context_set_device:
180  * @context: a #GdkDragContext
181  * @device: a #GdkDevice
182  *
183  * Associates a #GdkDevice to @context, so all Drag and Drop events
184  * for @context are emitted as if they came from this device.
185  */
186 void
187 gdk_drag_context_set_device (GdkDragContext *context,
188                              GdkDevice      *device)
189 {
190   g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
191   g_return_if_fail (GDK_IS_DEVICE (device));
192
193   if (context->device)
194     g_object_unref (context->device);
195
196   context->device = device;
197
198   if (context->device)
199     g_object_ref (context->device);
200 }
201
202 /**
203  * gdk_drag_context_get_device:
204  * @context: a #GdkDragContext
205  *
206  * Returns the #GdkDevice associated to the drag context.
207  *
208  * Returns: (transfer none): The #GdkDevice associated to @context.
209  **/
210 GdkDevice *
211 gdk_drag_context_get_device (GdkDragContext *context)
212 {
213   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
214
215   return context->device;
216 }
217
218 G_DEFINE_TYPE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT)
219
220 static void
221 gdk_drag_context_init (GdkDragContext *context)
222 {
223 }
224
225 static void
226 gdk_drag_context_finalize (GObject *object)
227 {
228   GdkDragContext *context = GDK_DRAG_CONTEXT (object);
229
230   g_list_free (context->targets);
231
232   if (context->source_window)
233     g_object_unref (context->source_window);
234
235   if (context->dest_window)
236     g_object_unref (context->dest_window);
237
238   G_OBJECT_CLASS (gdk_drag_context_parent_class)->finalize (object);
239 }
240
241 static void
242 gdk_drag_context_class_init (GdkDragContextClass *klass)
243 {
244   GObjectClass *object_class = G_OBJECT_CLASS (klass);
245
246   object_class->finalize = gdk_drag_context_finalize;
247 }
248
249 /**
250  * gdk_drag_find_window_for_screen:
251  * @context: a #GdkDragContext
252  * @drag_window: a window which may be at the pointer position, but
253  *     should be ignored, since it is put up by the drag source as an icon
254  * @screen: the screen where the destination window is sought
255  * @x_root: the x position of the pointer in root coordinates
256  * @y_root: the y position of the pointer in root coordinates
257  * @dest_window: (out): location to store the destination window in
258  * @protocol: (out): location to store the DND protocol in
259  *
260  * Finds the destination window and DND protocol to use at the
261  * given pointer position.
262  *
263  * This function is called by the drag source to obtain the
264  * @dest_window and @protocol parameters for gdk_drag_motion().
265  *
266  * Since: 2.2
267  */
268 void
269 gdk_drag_find_window_for_screen (GdkDragContext  *context,
270                                  GdkWindow       *drag_window,
271                                  GdkScreen       *screen,
272                                  gint             x_root,
273                                  gint             y_root,
274                                  GdkWindow      **dest_window,
275                                  GdkDragProtocol *protocol)
276 {
277   g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
278
279   *dest_window = GDK_DRAG_CONTEXT_GET_CLASS (context)
280       ->find_window (context, drag_window, screen, x_root, y_root, protocol);
281 }
282
283 /**
284  * gdk_drag_status:
285  * @context: a #GdkDragContext
286  * @action: the selected action which will be taken when a drop happens,
287  *    or 0 to indicate that a drop will not be accepted
288  * @time_: the timestamp for this operation
289  *
290  * Selects one of the actions offered by the drag source.
291  *
292  * This function is called by the drag destination in response to
293  * gdk_drag_motion() called by the drag source.
294  */
295 void
296 gdk_drag_status (GdkDragContext *context,
297                  GdkDragAction   action,
298                  guint32         time_)
299 {
300   g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
301
302   GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_status (context, action, time_);
303 }
304
305 /**
306  * gdk_drag_motion:
307  * @context: a #GdkDragContext
308  * @dest_window: the new destination window, obtained by
309  *     gdk_drag_find_window()
310  * @protocol: the DND protocol in use, obtained by gdk_drag_find_window()
311  * @x_root: the x position of the pointer in root coordinates
312  * @y_root: the y position of the pointer in root coordinates
313  * @suggested_action: the suggested action
314  * @possible_actions: the possible actions
315  * @time_: the timestamp for this operation
316  *
317  * Updates the drag context when the pointer moves or the
318  * set of actions changes.
319  *
320  * This function is called by the drag source.
321  */
322 gboolean
323 gdk_drag_motion (GdkDragContext *context,
324                  GdkWindow      *dest_window,
325                  GdkDragProtocol protocol,
326                  gint            x_root,
327                  gint            y_root,
328                  GdkDragAction   suggested_action,
329                  GdkDragAction   possible_actions,
330                  guint32         time_)
331 {
332   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE);
333
334   return GDK_DRAG_CONTEXT_GET_CLASS (context)
335        ->drag_motion (context,
336                       dest_window,
337                       protocol,
338                       x_root,
339                       y_root,
340                       suggested_action,
341                       possible_actions,
342                       time_);
343 }
344
345 /**
346  * gdk_drag_abort:
347  * @context: a #GdkDragContext
348  * @time_: the timestamp for this operation
349  *
350  * Aborts a drag without dropping.
351  *
352  * This function is called by the drag source.
353  */
354 void
355 gdk_drag_abort (GdkDragContext *context,
356                 guint32         time_)
357 {
358   g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
359
360   GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_abort (context, time_);
361 }
362
363 /**
364  * gdk_drag_drop:
365  * @context: a #GdkDragContext
366  * @time_: the timestamp for this operation
367  *
368  * Drops on the current destination.
369  *
370  * This function is called by the drag source.
371  */
372 void
373 gdk_drag_drop (GdkDragContext *context,
374                guint32         time_)
375 {
376   g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
377
378   GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_drop (context, time_);
379 }
380
381 /**
382  * gdk_drop_reply:
383  * @context: a #GdkDragContext
384  * @accepted: %TRUE if the drop is accepted
385  * @time_: the timestamp for this operation
386  *
387  * Accepts or rejects a drop.
388  *
389  * This function is called by the drag destination in response
390  * to a drop initiated by the drag source.
391  */
392 void
393 gdk_drop_reply (GdkDragContext *context,
394                 gboolean        accepted,
395                 guint32         time_)
396 {
397   g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
398
399   GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_reply (context, accepted, time_);
400 }
401
402 /**
403  * gdk_drop_finish:
404  * @context: a #GtkDragContext
405  * @success: %TRUE if the data was successfully received
406  * @time_: the timestamp for this operation
407  *
408  * Ends the drag operation after a drop.
409  *
410  * This function is called by the drag destination.
411  */
412 void
413 gdk_drop_finish (GdkDragContext *context,
414                  gboolean        success,
415                  guint32         time_)
416 {
417   g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
418
419   GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_finish (context, success, time_);
420 }
421
422 /**
423  * gdk_drag_drop_succeeded:
424  * @context: a #GdkDragContext
425  *
426  * Returns whether the dropped data has been successfully
427  * transferred. This function is intended to be used while
428  * handling a %GDK_DROP_FINISHED event, its return value is
429  * meaningless at other times.
430  *
431  * Return value: %TRUE if the drop was successful.
432  *
433  * Since: 2.6
434  **/
435 gboolean
436 gdk_drag_drop_succeeded (GdkDragContext *context)
437 {
438   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE);
439
440   return GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_status (context);
441 }
442
443 /**
444  * gdk_drag_get_selection:
445  * @context: a #GdkDragContext.
446  *
447  * Returns the selection atom for the current source window.
448  *
449  * Return value: the selection atom, or %GDK_NONE
450  */
451 GdkAtom
452 gdk_drag_get_selection (GdkDragContext *context)
453 {
454   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_NONE);
455
456   return GDK_DRAG_CONTEXT_GET_CLASS (context)->get_selection (context);
457 }