KWWidgets
XDND.h
Go to the documentation of this file.
1 /*
2  * XDND.h -- Definitions of the Tk XDND Drag'n'Drop Protocol Implementation
3  *
4  * This file implements the unix portion of the drag&drop mechanish
5  * for the tk toolkit. The protocol in use under unix is the
6  * XDND protocol.
7  *
8  * This software is copyrighted by:
9  * George Petasis, National Centre for Scientific Research "Demokritos",
10  * Aghia Paraskevi, Athens, Greece.
11  * e-mail: petasis@iit.demokritos.gr
12  * Laurent Riesterer, Rennes, France.
13  * e-mail: laurent.riesterer@free.fr
14  *
15  * The following terms apply to all files associated
16  * with the software unless explicitly disclaimed in individual files.
17  *
18  * The authors hereby grant permission to use, copy, modify, distribute,
19  * and license this software and its documentation for any purpose, provided
20  * that existing copyright notices are retained in all copies and that this
21  * notice is included verbatim in any distributions. No written agreement,
22  * license, or royalty fee is required for any of the authorized uses.
23  * Modifications to this software may be copyrighted by their authors
24  * and need not follow the licensing terms described here, provided that
25  * the new terms are clearly indicated on the first page of each file where
26  * they apply.
27  *
28  * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
29  * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
30  * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
31  * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
36  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
37  * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
38  * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
39  * MODIFICATIONS.
40  */
41 
42 #ifndef _X_DND_H
43 #define _X_DND_H
44 #include "vtkTcl.h"
45 #include "vtkTk.h"
46 #include <tcl.h>
47 #include <tk.h>
48 #include "tkDND.h"
49 
50 #ifdef TKDND_ENABLE_MOTIF_DRAGS
51 #ifndef TKDND_ENABLE_MOTIF_DROPS
52 #define TKDND_ENABLE_MOTIF_DROPS
53 #endif /* TKDND_ENABLE_MOTIF_DROPS */
54 #endif /* TKDND_ENABLE_MOTIF_DRAGS */
55 
56 /*
57  * We also support Motif drops :-)
58  */
59 #ifdef TKDND_ENABLE_MOTIF_DROPS
60 #include "Dnd.h"
61 #endif /* TKDND_ENABLE_MOTIF_DROPS */
62 
63 #define XDND_VERSION 3
64 #define XDND_MINVERSION 3
65 #define XDND_ENTERTYPECOUNT 3
66 #define XDND_BOOL short
67 
68 #define XDND_NODROP_CURSOR 0
69 #define XDND_COPY_CURSOR 1
70 #define XDND_MOVE_CURSOR 2
71 #define XDND_LINK_CURSOR 3
72 #define XDND_ASK_CURSOR 4
73 #define XDND_PRIVATE_CURSOR 5
74 
75 /*
76  * Debug Facilities...
77  */
78 #ifndef XDND_DEBUG
79 #ifdef DND_DEBUG
80 #include <stdio.h>
81 #define XDND_DEBUG(a) \
82  printf("%s, %d: " a,__FILE__,__LINE__); fflush(stdout)
83 #define XDND_DEBUG2(a,b) \
84  printf("%s, %d: " a,__FILE__,__LINE__,b); fflush(stdout)
85 #define XDND_DEBUG3(a,b,c) \
86  printf("%s, %d: " a,__FILE__,__LINE__,b,c); fflush(stdout)
87 #define XDND_DEBUG4(a,b,c,d) \
88  printf("%s, %d: " a,__FILE__,__LINE__,b,c,d); fflush(stdout)
89 #define XDND_DEBUG5(a,b,c,d,e) \
90  printf("%s, %d: " a,__FILE__,__LINE__,b,c,d,e); fflush(stdout)
91 #else /* DND_DEBUG */
92 #define XDND_DEBUG(a)
93 #define XDND_DEBUG2(a,b)
94 #define XDND_DEBUG3(a,b,c)
95 #define XDND_DEBUG4(a,b,c,d)
96 #define XDND_DEBUG5(a,b,c,d,e)
97 #endif /* DND_DEBUG */
98 #endif /* XDND_DEBUG */
99 
100 #ifdef __cplusplus
101 extern "C" {
102 #endif
103 
104 #ifndef LONG_MAX
105 #define LONG_MAX 0x8000000L
106 #endif
107 
108 #define Min(x,y) (x<y?x:y)
109 #define XDND_Sqrt(x) ((x)*(x))
110 #ifndef False
111 #define False 0
112 #endif /* False */
113 #ifndef True
114 #define True 1
115 #endif /* True */
116 
117 typedef struct _XDND_Cursor {
118  int width, height;
119  int x, y;
120  unsigned char *image_data, *mask_data;
121  char *_action;
123  Cursor cursor;
124  Atom action;
125 } XDNDCursor;
126 
127 typedef struct _XDND_Struct {
128  Tk_Window MainWindow; /* The main window of our application */
129  Tcl_Interp *interp; /* A Tcl Interpreter */
130  Display *display; /* Display Pointer */
131  Window RootWindow; /* Display's root window */
132  Atom XDNDVersion; /* Protocol version being used */
133  int x; /* Current position of the mouse */
134  int y; /* Current position of the mouse */
135  int button; /* Current button used for drag operation*/
136  unsigned int state; /* Current state to convert to modifiers */
137  int CallbackStatus; /* The return value of last tcl callback */
138  XDND_BOOL ResetValues; /* This is used by TkDND_HandleDNDLeave */
139 
140  /* Slots used during drag... */
141  XDND_BOOL InternalDrag; /* True if the drag is in the same app */
142  XDND_BOOL ReceivedStatusFlag; /* True if received any XdndStatus
143  from current target */
144  char *data; /* Pointer to hold the dnd data */
145  int index; /* Length of dnd data */
146 
147  /* Drag source window info */
148  Window DraggerWindow; /* Window of the drag source */
149  Atom *DraggerTypeList; /* Type list supported by the drag source */
150  Atom *DraggerAskActionList; /* Actions supported by the drag source */
151  char *DraggerAskDescriptions; /* Descriptions of supported actions */
152  Tk_Window CursorWindow; /* A window to replace cursor */
153  char *CursorCallback; /* A Callback to update cursor window */
154  XDND_BOOL WaitForStatusFlag; /* True if waiting for XdndStatus message */
155 
156  /* Current drop target info */
157  Window Toplevel; /* The toplevel that the mouse is in */
158  Window MouseWindow; /* Window that mouse is in; not owned */
159  XDND_BOOL MouseWindowIsAware; /* True if itsMouseWindow has XdndAware */
160  Window MsgWindow; /* Window that receives messages
161  (not MouseWindow if proxy) */
162  Atom DesiredType; /* The drop desired type */
163 #ifdef XDND_USE_TK_GET_SELECTION
164  char *DesiredName; /* The string of the desired type */
165 #endif /* XDND_USE_TK_GET_SELECTION */
166  Atom SupportedAction; /* The supported by the target action */
167 
168  XDND_BOOL WillAcceptDropFlag; /* True if target will accept drop */
169  Time LastEventTime; /* Time of the last processed event */
170 
171  XDND_BOOL IsDraggingFlag; /* True until XDND_Finish is called */
172  XDND_BOOL UseMouseRectFlag; /* True if use MouseRectR */
173  XRectangle MouseRectR; /* Don't send another XdndPosition while
174  inside here */
175  XDNDCursor *cursors; /* The available cursors... */
176 
177  /*
178  * Motif slots...
179  */
180 #ifdef TKDND_ENABLE_MOTIF_DROPS
181  DndData Motif_DND_Data; /* Internal Motif data... */
182  int Motif_DND; /* True if protocol in use is Motif */
183  Atom Motif_DND_SuccessAtom;
184  Atom Motif_DND_FailureAtom;
185 #endif /* TKDND_ENABLE_MOTIF_DROPS */
186 #ifdef TKDND_ENABLE_MOTIF_DRAGS
187  Window Motif_LastToplevel; /* The last toplevel we send enter */
188  int Motif_ToplevelAware; /* True if dnd->Toplevel supports Motif */
189  Atom Motif_DND_Selection; /* The selection that will be used */
190  Atom Motif_DND_WM_STATE; /* WM_STATE property */
191 #endif /* TKDND_ENABLE_MOTIF_DRAGS */
192 
193  /*
194  * Keep info about the last window that we send a <DragEnter> event.
195  * If the LastEnterDeliveredWindow is not None, then we have to simulate
196  * a DragLeave to that window. We have to do that, as qt for example
197  * sometimes forgets (!) to send Leave events to windows that overlap...
198  */
200  unsigned int
201  Alt_ModifierMask; /* The modifier the Alt keys are bind to */
202  unsigned int
203  Meta_ModifierMask; /* The modifier the Meta keys are bind to */
204 
205  /* Here we keep some frequently used Atoms... */
207 
211 
218 
224 
227 
229 
233 
234  /*
235  * Allow user to register event callbacks...
236  */
237 
238  /* This function will be called for various windows (application or
239  * foreign). It must return True if given window is a valid one and belongs
240  * to this application. Else, False must be returned.
241  * If this method is not set then the code assumes that no widgets have
242  * support for recieving drops. In this case none of the widget methods
243  * need be set.
244  */
245  int (*WidgetExistsCallback) (struct _XDND_Struct *dnd, Window window);
246  /* This function will be called when the mouse has entered a widget to
247  * announce "XdndEnter". This function must return True if the widget will
248  * accept the drop and False otherwise. If True is returned, the apply
249  * position callback (the next pointer :-)) will be immediately called...
250  */
252  Window target, Window source, Atom action, int x, int y,
253  Time t, Atom *typelist);
254  /* This function will be called when the mouse is moving inside a drag
255  * target. It is responsible for changing the drop target widget appearence.
256  * It must also sets the correct data to pointers. As per the protocol, if
257  * the widget cannot perform the action specified by `action' then it should
258  * return either XdndActionPrivate or XdndActionCopy into supported_action
259  * (leaving supported_action unchanged is equivalent to XdndActionCopy).
260  * Returns True if widget is ready to accept the drop...
261  */
263  Window target, Window source, Atom action, Atom *actionList,
264  int x, int y, Time t, Atom *typelist, int *wantPosition,
265  Atom *supported_action, Atom *desired_type, XRectangle *rectangle);
266  /* This function will be called when the mouse leaves a drop target widget,
267  * or when the drop is canceled. It must update the widget border to its
268  * default appearance...
269  */
270  int (*WidgetApplyLeaveCallback) (struct _XDND_Struct *dnd, Window target);
271  /* This function must insert the data into the drop target */
273  unsigned char *data, int length, int remaining,
274  Window into, Window from, Atom type);
275  /* This function will be used in order to get the user-prefered action, if
276  * the action is XdndAsk... */
277  int (*Ask) (struct _XDND_Struct *dnd, Window source, Window target,
278  Atom *action);
279  /* This is our callback to get the data that is to be dropped from the drag
280  * source... */
281  int (*GetData) (struct _XDND_Struct *dnd, Window source,
282  unsigned char **data, int *length, Atom type);
283  /* This function will be called, in order to handle events that are not
284  * related to the XDND protocol... */
285  void (*HandleEvents) (struct _XDND_Struct *dnd, XEvent *xevent);
286  /*
287  * This function must return the current types that a window supports as a
288  * drag source...
289  */
290  Atom *(*GetDragAtoms) (struct _XDND_Struct *dnd, Window window);
291  /*
292  * Set the cursor callback...
293  * The requested cursors will be one of the extern Cursor variables:
294  * noDropCursor, moveCursor, copyCursor, linkCursor, askCursor
295  */
296  int (*SetCursor) (struct _XDND_Struct *dnd, int cursor);
297 } XDND;
298 #define DndClass XDND
300 
301 /*
302  * Function Prototypes...
303  */
304 
305 void XDND_Reset(XDND *dndp);
306 XDND *XDND_Init(Display *display);
307 void XDND_Enable(XDND *dnd, Window window);
308 XDND_BOOL XDND_IsDndAware(XDND *dnd, Window window, Window* proxy, Atom *vers);
309 int XDND_AtomListLength(Atom *list);
310 int XDND_DescriptionListLength(char *list);
311 Atom *XDND_GetTypeList(XDND *dnd, Window window);
312 void XDND_AnnounceTypeList(XDND *dnd, Window window, Atom *list);
313 void XDND_AppendType(XDND *dnd, Window window, Atom type);
314 void XDND_AnnounceAskActions(XDND *dnd, Window window, Atom *Actions,
315  char *Descriptions);
316 Atom *XDND_GetAskActions(XDND *dnd, Window window);
317 char *XDND_GetAskActionDescriptions(XDND *dnd, Window window);
319 XDND_BOOL XDND_FindTarget(XDND *dnd, int x, int y,
320  Window *toplevel, Window *msgWindow,
321  Window *target, XDND_BOOL *aware, Atom *version);
322 Window XDND_FindToplevel(XDND *dnd, Window window);
323 
324 XDND_BOOL XDND_BeginDrag(XDND *dnd, Window source, Atom *actions, Atom *types,
325  char *Descriptions, Tk_Window cursor_window,
326  char *cursor_callback);
327 
328 void XDND_SendDNDEnter(XDND *dnd, Window window, Window msgWindow,
329  XDND_BOOL isAware, Atom vers);
330 XDND_BOOL XDND_SendDNDPosition(XDND *dnd, Atom action);
331 XDND_BOOL XDND_SendDNDStatus(XDND *dnd, Atom action);
334 XDND_BOOL XDND_SendDNDSelection(XDND *dnd, XSelectionRequestEvent *request);
335 
336 int XDND_HandleClientMessage(XDND *dnd, XEvent *xevent);
337 int XDND_HandleDNDEnter(XDND *dnd, XClientMessageEvent clientMessage);
338 int XDND_HandleDNDHere(XDND *dnd, XClientMessageEvent clientMessage);
339 int XDND_HandleDNDLeave(XDND *dnd, XClientMessageEvent clientMessage);
340 int XDND_HandleDNDDrop(XDND *dnd, XClientMessageEvent clientMessage);
341 int XDND_GetSelProc(ClientData clientData, Tcl_Interp *interp, char *portion);
342 
343 int XDND_HandleDNDStatus(XDND *dnd, XClientMessageEvent clientMessage);
344 
345 #ifdef TKDND_ENABLE_MOTIF_DROPS
346 int MotifDND_HandleClientMessage(XDND *dnd, XEvent xevent);
347 #endif /* TKDND_ENABLE_MOTIF_DROPS */
348 #ifdef __cplusplus
349 }
350 #endif
351 
352 #endif /* _X_DND_H */