]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkdnd-x11.c
restricted the --g*fatal-* arguments to --g-fatal-warnings again. this
[~andy/gtk] / gdk / x11 / gdkdnd-x11.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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 #include <X11/Xlib.h>
20 #include <X11/Xatom.h>
21 #include <string.h>
22 #include "gdkx.h"
23 #include "gdk.h"
24
25 /* Nothing much here now, but we have to make a start some time ;-) */
26
27 void
28 gdk_dnd_set_drag_cursors(GdkCursor *default_cursor, GdkCursor *goahead_cursor)
29 {
30   gdk_dnd.c->gdk_cursor_dragdefault =
31     ((GdkCursorPrivate *)default_cursor)->xcursor;
32   gdk_dnd.c->gdk_cursor_dragok = ((GdkCursorPrivate *)goahead_cursor)->xcursor;
33   
34   if(gdk_dnd.dnd_grabbed)
35     {
36       if(gdk_dnd.c->drag_pm_default)
37         /* We were displaying pixmaps for the drag */
38         {
39           gdk_window_hide(gdk_dnd.c->drag_pm_default);
40           gdk_window_unref(gdk_dnd.c->drag_pm_default);
41           if(gdk_dnd.c->drag_pm_ok)
42             {
43               gdk_window_hide(gdk_dnd.c->drag_pm_ok);
44               gdk_window_unref(gdk_dnd.c->drag_pm_ok);
45             }
46           gdk_dnd.c->drag_pm_default = gdk_dnd.c->drag_pm_ok = NULL;
47           g_list_free(gdk_dnd.c->xids);
48           gdk_dnd.c->xids = NULL;
49         }
50       gdk_dnd_display_drag_cursor(-1, -1,
51                                   gdk_dnd.dnd_drag_target?TRUE:FALSE,
52                                   TRUE);
53     }
54 }
55
56 void
57 gdk_dnd_set_drag_shape(GdkWindow *default_pixmapwin,
58                        GdkPoint *default_hotspot,
59                        GdkWindow *goahead_pixmapwin,
60                        GdkPoint *goahead_hotspot)
61 {
62   g_return_if_fail(default_pixmapwin != NULL);
63   
64   g_list_free(gdk_dnd.c->xids); gdk_dnd.c->xids = NULL;
65   if(gdk_dnd.c->drag_pm_default)
66     {
67       gdk_window_hide(gdk_dnd.c->drag_pm_default);
68       gdk_window_unref(gdk_dnd.c->drag_pm_default);
69     }
70   if(gdk_dnd.c->drag_pm_ok)
71     {
72       gdk_window_hide(gdk_dnd.c->drag_pm_ok);
73       gdk_window_unref(gdk_dnd.c->drag_pm_ok);
74     }
75   
76   gdk_dnd.c->drag_pm_ok = NULL;
77   
78   gdk_window_ref(default_pixmapwin);
79   gdk_dnd.c->drag_pm_default = default_pixmapwin;
80   gdk_dnd.c->default_hotspot = *default_hotspot;
81   gdk_dnd.c->xids = g_list_append(gdk_dnd.c->xids, GUINT_TO_POINTER (((GdkWindowPrivate *)default_pixmapwin)->xwindow));
82   if(goahead_pixmapwin)
83     {
84       gdk_window_ref(goahead_pixmapwin);
85       gdk_dnd.c->xids = g_list_append(gdk_dnd.c->xids, GUINT_TO_POINTER (((GdkWindowPrivate *)goahead_pixmapwin)->xwindow));
86       gdk_dnd.c->drag_pm_ok = goahead_pixmapwin;
87       gdk_dnd.c->ok_hotspot = *goahead_hotspot;
88     }
89   
90   if(gdk_dnd.dnd_grabbed)
91     {
92       gdk_dnd_display_drag_cursor(-1, -1,
93                                   gdk_dnd.dnd_drag_target?TRUE:FALSE,
94                                   TRUE);
95       XChangeActivePointerGrab (gdk_display,
96                                 ButtonMotionMask |
97                                 ButtonPressMask |
98                                 ButtonReleaseMask |
99                                 EnterWindowMask | LeaveWindowMask,
100                                 None,
101                                 CurrentTime);      
102     }
103 }
104
105 void
106 gdk_dnd_display_drag_cursor(gint x, gint y, gboolean drag_ok,
107                             gboolean change_made)
108 {
109   if(!gdk_dnd.dnd_grabbed)
110     return;
111   
112   if(gdk_dnd.c->drag_pm_default)
113     {
114       /* We're doing pixmaps here... */
115       GdkWindow *mypix, *opix;
116       GdkPoint *myhotspot;
117       gint itmp;
118       guint masktmp;
119       Window wtmp;
120       
121       if(x == -2 && y == -2) /* Hide the cursors */
122         {
123           gdk_window_hide(gdk_dnd.c->drag_pm_ok);
124           gdk_window_hide(gdk_dnd.c->drag_pm_default);
125           GDK_NOTE(DND, g_message("Hiding both drag cursors\n"));
126           return;
127         }
128       
129       if(x == -1 && y == -1) /* We're supposed to find it out for ourselves */
130         XQueryPointer(gdk_display, gdk_root_window,
131                       &wtmp, &wtmp, &x, &y, &itmp, &itmp, &masktmp);
132       
133       if(drag_ok)
134         {
135           GDK_NOTE(DND, g_message("Switching to drag_ok cursor\n"));
136           mypix = gdk_dnd.c->drag_pm_ok;
137           opix = gdk_dnd.c->drag_pm_default;
138           myhotspot = &gdk_dnd.c->ok_hotspot;
139         }
140       else
141         {
142           GDK_NOTE(DND, g_message("Switching to drag_default cursor\n"));
143           mypix = gdk_dnd.c->drag_pm_default;
144           opix = gdk_dnd.c->drag_pm_ok;
145           myhotspot = &gdk_dnd.c->default_hotspot;
146         }
147       gdk_window_move(mypix, x - myhotspot->x, y - myhotspot->y);
148       if(change_made)
149         {
150           GDK_NOTE(DND, g_message("Cursors switched, hide & show\n"));
151           gdk_window_hide(opix);
152         }
153       gdk_window_move(mypix, x - myhotspot->x, y - myhotspot->y);
154       if (change_made)
155         {
156           gdk_window_show(mypix); /* There ought to be a way to know if
157                                      a window is already mapped etc. */
158         }      
159     }
160   else if(change_made)
161     {
162       Cursor c;
163       /* Move cursors around */
164       if(drag_ok)
165         c = gdk_dnd.c->gdk_cursor_dragok;
166       else
167         c = gdk_dnd.c->gdk_cursor_dragdefault;
168       XChangeActivePointerGrab (gdk_display,
169                                 ButtonMotionMask |
170                                 ButtonPressMask |
171                                 ButtonReleaseMask |
172                                 EnterWindowMask | LeaveWindowMask,
173                                 c,
174                                 CurrentTime);
175     }
176 }