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