Drag-n-drop support on Linux
[blender-staging.git] / extern / xdnd / xdnd.h
1 /* xdnd.c, xdnd.h - C program library for handling the Xdnd protocol
2    Copyright (C) 1996-2000 Paul Sheer
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    This program 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
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307, USA.
18  */
19
20 #ifndef _X_DND_H
21 #define _X_DND_H
22
23 #ifdef  __cplusplus
24 extern "C" {
25 #endif
26
27 /* you can set this to either 2 (which support 0 and 1 as well) or 3 */
28 /* #define XDND_VERSION 2 */
29 #define XDND_VERSION 3
30
31
32 /* XdndEnter */
33 #define XDND_THREE 3
34 #define XDND_ENTER_SOURCE_WIN(e)        ((e)->xclient.data.l[0])
35 #define XDND_ENTER_THREE_TYPES(e)       (((e)->xclient.data.l[1] & 0x1UL) == 0)
36 #define XDND_ENTER_THREE_TYPES_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x1UL) | (((b) == 0) ? 0 : 0x1UL)
37 #define XDND_ENTER_VERSION(e)           ((e)->xclient.data.l[1] >> 24)
38 #define XDND_ENTER_VERSION_SET(e,v)     (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~(0xFF << 24)) | ((v) << 24)
39 #define XDND_ENTER_TYPE(e,i)            ((e)->xclient.data.l[2 + i])    /* i => (0, 1, 2) */
40
41 /* XdndPosition */
42 #define XDND_POSITION_SOURCE_WIN(e)     ((e)->xclient.data.l[0])
43 #define XDND_POSITION_ROOT_X(e)         ((e)->xclient.data.l[2] >> 16)
44 #define XDND_POSITION_ROOT_Y(e)         ((e)->xclient.data.l[2] & 0xFFFFUL)
45 #define XDND_POSITION_ROOT_SET(e,x,y)   (e)->xclient.data.l[2]  = ((x) << 16) | ((y) & 0xFFFFUL)
46 #define XDND_POSITION_TIME(e)           ((e)->xclient.data.l[3])
47 #define XDND_POSITION_ACTION(e)         ((e)->xclient.data.l[4])
48
49 /* XdndStatus */
50 #define XDND_STATUS_TARGET_WIN(e)       ((e)->xclient.data.l[0])
51 #define XDND_STATUS_WILL_ACCEPT(e)      ((e)->xclient.data.l[1] & 0x1L)
52 #define XDND_STATUS_WILL_ACCEPT_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x1UL) | (((b) == 0) ? 0 : 0x1UL)
53 #define XDND_STATUS_WANT_POSITION(e)    ((e)->xclient.data.l[1] & 0x2UL)
54 #define XDND_STATUS_WANT_POSITION_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x2UL) | (((b) == 0) ? 0 : 0x2UL)
55 #define XDND_STATUS_RECT_X(e)           ((e)->xclient.data.l[2] >> 16)
56 #define XDND_STATUS_RECT_Y(e)           ((e)->xclient.data.l[2] & 0xFFFFL)
57 #define XDND_STATUS_RECT_WIDTH(e)       ((e)->xclient.data.l[3] >> 16)
58 #define XDND_STATUS_RECT_HEIGHT(e)      ((e)->xclient.data.l[3] & 0xFFFFL)
59 #define XDND_STATUS_RECT_SET(e,x,y,w,h) {(e)->xclient.data.l[2] = ((x) << 16) | ((y) & 0xFFFFUL); (e)->xclient.data.l[3] = ((w) << 16) | ((h) & 0xFFFFUL); }
60 #define XDND_STATUS_ACTION(e)           ((e)->xclient.data.l[4])
61
62 /* XdndLeave */
63 #define XDND_LEAVE_SOURCE_WIN(e)        ((e)->xclient.data.l[0])
64
65 /* XdndDrop */
66 #define XDND_DROP_SOURCE_WIN(e)         ((e)->xclient.data.l[0])
67 #define XDND_DROP_TIME(e)               ((e)->xclient.data.l[2])
68
69 /* XdndFinished */
70 #define XDND_FINISHED_TARGET_WIN(e)     ((e)->xclient.data.l[0])
71
72 struct _DndCursor {
73     int width, height;
74     int x, y;
75     unsigned char *image_data, *mask_data;
76     char *_action;
77     Pixmap image_pixmap, mask_pixmap;
78     Cursor cursor;
79     Atom action;
80 };
81
82 typedef struct _DndCursor DndCursor;
83 typedef struct _DndClass DndClass;
84
85 struct _DndClass {
86 /* insert chars sequentionally into the target widget, type will be the same as `desired_type'
87    returned from widget_apply_position. This may be called several times in succession 
88    with sequention blocks of data. Must return non-zero on failure */
89     int (*widget_insert_drop) (DndClass * dnd, unsigned char *data, int length, int remaining, Window into, Window from, Atom type);
90
91 /* In response to DELETE requests : FIXME - not yet used */
92     int (*widget_delete_selection) (DndClass * dnd, Window window, Window from);
93
94 /* returns 1 if widget exists, zero otherwise. If this method is not 
95    set then the code assumes that no widgets have support for recieving drops.
96    In this case none of the widget methods need be set. */
97     int (*widget_exists) (DndClass * dnd, Window window);
98
99 /* must update the widgets border to its default appearance */
100     void (*widget_apply_leave) (DndClass * dnd, Window widgets_window);
101
102 /* must update the widgets border to give the appearance of being able to recieve a drop,
103    plus return all data to pointers. As per the protocol, if the widget cannot
104    perform the action specified by `action' then it should return either XdndActionPrivate
105    or XdndActionCopy into supported_action (leaving 0 supported_action unchanged is equivalent
106    to XdndActionCopy). Returns 1 if ready to ok drop */
107     int (*widget_apply_position) (DndClass * dnd, Window widgets_window, Window from,
108                                   Atom action, int x, int y, Time t, Atom * typelist,
109                                   int *want_position, Atom * supported_action, Atom * desired_type,
110                                   XRectangle * rectangle);
111
112 /* returns drag data of the specified type. This will be one of `typelist' given to xdnd_drag */
113     void (*widget_get_data) (DndClass * dnd, Window window, unsigned char **data, int *length, Atom type);
114
115 /* this is called from with the main event loop if an expose event is recieved and is optional */
116     void (*handle_expose_events) (DndClass * dnd, XEvent * xevent);
117
118 /* creates a chooser dialog if the action is XdndActionAsk. Returns non-zero on cancel */
119     int (*action_choose_dialog) (DndClass * dnd, char **descriptions, Atom * actions, Atom * result);
120
121 #if 0 /* implemented internally */
122 /* returns a widget that is dnd aware within a parent widget that lies under the point x, y */
123     Window (*widget_get_child_widget) (DndClass * dnd, Window parent, int x, int y);
124 #endif
125
126     void *pad1[8];
127
128     DndCursor *cursors;
129
130     Display *display;
131
132     Atom XdndAware;
133     Atom XdndSelection;
134     Atom XdndEnter;
135     Atom XdndLeave;
136     Atom XdndPosition;
137     Atom XdndDrop;
138     Atom XdndFinished;
139     Atom XdndStatus;
140     Atom XdndActionCopy;
141     Atom XdndActionMove;
142     Atom XdndActionLink;
143     Atom XdndActionAsk;
144     Atom XdndActionPrivate;
145     Atom XdndTypeList;
146     Atom XdndActionList;
147     Atom XdndActionDescription;
148
149     Atom Xdnd_NON_PROTOCOL_ATOM;
150     Atom version;
151
152     Atom pad2[16];
153
154     Window root_window;
155
156 #define XDND_DROP_STAGE_IDLE            0
157 #define XDND_DRAG_STAGE_DRAGGING        1
158 #define XDND_DRAG_STAGE_ENTERED         2
159 #define XDND_DROP_STAGE_CONVERTING      3
160 #define XDND_DROP_STAGE_ENTERED         4
161     int stage;
162     int dragging_version;
163     int internal_drag;
164     int want_position;
165     int ready_to_drop;
166     int will_accept;
167     XRectangle rectangle;
168     Window dropper_window, dragger_window;
169     Atom *dragger_typelist;
170     Atom desired_type;
171     Atom supported_action;
172     Time time;
173 /* drop position from last XdndPosition */
174     int x, y;
175     int pad3[16];
176
177 /* move euclidian pixels before considering this to be an actual drag */
178     float drag_threshold;
179
180 /* block for only this many seconds on not receiving a XdndFinished from target, default : 10 */
181     int time_out;
182
183 #define XDND_OPTION_NO_HYSTERESIS (1<<0)
184     int options;
185
186 /* user hooks */
187     void *user_hook1;
188     void *user_hook2;
189     void *user_hook3;
190     Window dropper_toplevel;
191     void *pad4[15];
192 };
193
194
195 void xdnd_init (DndClass * dnd, Display * display);
196 void xdnd_shut (DndClass * dnd);
197 /* for nested widgets where parent and child receive drops of different
198 types; then always pass typelist as null */
199 void xdnd_set_dnd_aware (DndClass * dnd, Window window, Atom * typelist);
200 int xdnd_is_dnd_aware (DndClass * dnd, Window window, int *version, Atom * typelist);
201 void xdnd_set_type_list (DndClass * dnd, Window window, Atom * typelist);
202 void xdnd_set_actions (DndClass * dnd, Window window, Atom * actions, char **descriptions);
203 int xdnd_get_actions (DndClass * dnd, Window window, Atom ** actions, char ***descriptions);
204 int xdnd_choose_action_dialog (DndClass * dnd, Atom * actions, char **descriptions, Atom * result);
205 Atom xdnd_drag (DndClass * dnd, Window from, Atom action, Atom * typelist);
206
207 /* Returns 1 if event is handled, This must be placed in the widget
208 libraries main event loop and be called if the event type is
209 ClientMessage or SelectionNotify */
210 int xdnd_handle_drop_events (DndClass * dnd, XEvent * xevent);
211 Atom xdnd_get_drop (Display * display, XEvent * xevent, Atom * typelist, Atom * actionlist,
212                     unsigned char **data, int *length, Atom * type, int *x, int *y);
213
214
215 #ifdef  __cplusplus
216 }
217 #endif
218
219 #endif  /* !_X_DND_H */
220
221