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