]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkdnd-x11.c
DnD bugfixes (hopefully :). Rasters code is still buggy, methinks - try the dnd in...
[~andy/gtk] / gdk / x11 / gdkdnd-x11.c
1 #include <X11/Xlib.h>
2 #include <X11/Xatom.h>
3 #include <string.h>
4 #include "gdkx.h"
5 #include "gdk.h"
6
7 /* Nothing much here now, but we have to make a start some time ;-) */
8
9 void
10 gdk_dnd_set_drag_cursors(GdkCursor *default_cursor, GdkCursor *goahead_cursor)
11 {
12   gdk_dnd.c->gdk_cursor_dragdefault =
13     ((GdkCursorPrivate *)default_cursor)->xcursor;
14   gdk_dnd.c->gdk_cursor_dragok = ((GdkCursorPrivate *)goahead_cursor)->xcursor;
15
16   if(gdk_dnd.dnd_grabbed)
17     {
18       if(gdk_dnd.c->drag_pm_default)
19         /* We were displaying pixmaps for the drag */
20         {
21           gdk_window_hide(gdk_dnd.c->drag_pm_default);
22           gdk_window_unref(gdk_dnd.c->drag_pm_default);
23           if(gdk_dnd.c->drag_pm_ok)
24             {
25               gdk_window_hide(gdk_dnd.c->drag_pm_ok);
26               gdk_window_unref(gdk_dnd.c->drag_pm_ok);
27             }
28           gdk_dnd.c->drag_pm_default = gdk_dnd.c->drag_pm_ok = NULL;
29           g_list_free(gdk_dnd.c->xids);
30           gdk_dnd.c->xids = NULL;
31         }
32       gdk_dnd_display_drag_cursor(-1, -1,
33                                   gdk_dnd.dnd_drag_target?TRUE:FALSE,
34                                   TRUE);
35     }
36 }
37
38 void
39 gdk_dnd_set_drag_shape(GdkWindow *default_pixmapwin,
40                        GdkPoint *default_hotspot,
41                        GdkWindow *goahead_pixmapwin,
42                        GdkPoint *goahead_hotspot)
43 {
44   g_return_if_fail(default_pixmapwin != NULL);
45
46   g_list_free(gdk_dnd.c->xids); gdk_dnd.c->xids = NULL;
47   if(gdk_dnd.c->drag_pm_default)
48     gdk_window_unref(gdk_dnd.c->drag_pm_default);
49   if(gdk_dnd.c->drag_pm_ok)
50     gdk_window_unref(gdk_dnd.c->drag_pm_ok);
51
52   gdk_dnd.c->drag_pm_ok = NULL;
53
54   gdk_window_ref(default_pixmapwin);
55   gdk_dnd.c->drag_pm_default = default_pixmapwin;
56   gdk_dnd.c->default_hotspot = *default_hotspot;
57   gdk_dnd.c->xids = g_list_append(gdk_dnd.c->xids, ((GdkWindowPrivate *)default_pixmapwin)->xwindow);
58   if(goahead_pixmapwin)
59     {
60       gdk_window_ref(goahead_pixmapwin);
61       gdk_dnd.c->xids = g_list_append(gdk_dnd.c->xids, ((GdkWindowPrivate *)goahead_pixmapwin)->xwindow);
62       gdk_dnd.c->drag_pm_ok = goahead_pixmapwin;
63       gdk_dnd.c->ok_hotspot = *goahead_hotspot;
64     }
65
66   if(gdk_dnd.dnd_grabbed)
67     {
68       gdk_dnd_display_drag_cursor(-1, -1,
69                                   gdk_dnd.dnd_drag_target?TRUE:FALSE,
70                                   TRUE);
71       XChangeActivePointerGrab (gdk_display,
72                                 ButtonMotionMask |
73                                 ButtonPressMask |
74                                 ButtonReleaseMask |
75                                 EnterWindowMask | LeaveWindowMask,
76                                 None,
77                                 CurrentTime);      
78     }
79 }
80
81 void
82 gdk_dnd_display_drag_cursor(gint x, gint y, gboolean drag_ok,
83                             gboolean change_made)
84 {
85   if(!gdk_dnd.dnd_grabbed)
86     return;
87
88   if(gdk_dnd.c->drag_pm_default)
89     {
90       /* We're doing pixmaps here... */
91       GdkWindow *mypix, *opix;
92       GdkPoint *myhotspot;
93       gint itmp;
94       guint masktmp;
95       Window wtmp;
96
97       if(x == -2 && y == -2) /* Hide the cursors */
98         {
99           gdk_window_hide(gdk_dnd.c->drag_pm_ok);
100           gdk_window_hide(gdk_dnd.c->drag_pm_default);
101           return;
102         }
103
104       if(x == -1 && y == -1) /* We're supposed to find it out for ourselves */
105         XQueryPointer(gdk_display, gdk_root_window,
106                       &wtmp, &wtmp, &x, &y, &itmp, &itmp, &masktmp);
107
108       if(drag_ok)
109         {
110           mypix = gdk_dnd.c->drag_pm_ok;
111           opix = gdk_dnd.c->drag_pm_default;
112           myhotspot = &gdk_dnd.c->ok_hotspot;
113         }
114       else
115         {
116           mypix = gdk_dnd.c->drag_pm_default;
117           opix = gdk_dnd.c->drag_pm_ok;
118           myhotspot = &gdk_dnd.c->default_hotspot;
119         }
120       if(change_made)
121         {
122           gdk_window_hide(opix);
123           gdk_window_show(mypix); /* There ought to be a way to know if
124                                      a window is already mapped etc. */
125         }
126       gdk_window_move(mypix, x - myhotspot->x, y - myhotspot->y);
127     }
128   else if(change_made)
129     {
130       Cursor c;
131       /* Move cursors around */
132       if(drag_ok)
133         c = gdk_dnd.c->gdk_cursor_dragok;
134       else
135         c = gdk_dnd.c->gdk_cursor_dragdefault;
136       XChangeActivePointerGrab (gdk_display,
137                                 ButtonMotionMask |
138                                 ButtonPressMask |
139                                 ButtonReleaseMask |
140                                 EnterWindowMask | LeaveWindowMask,
141                                 c,
142                                 CurrentTime);
143     }
144 }