KWWidgets
XDND.h
Go to the documentation of this file.
00001 /*
00002  * XDND.h -- Definitions of the Tk XDND Drag'n'Drop Protocol Implementation
00003  * 
00004  *    This file implements the unix portion of the drag&drop mechanish
00005  *    for the tk toolkit. The protocol in use under unix is the
00006  *    XDND protocol.
00007  *
00008  * This software is copyrighted by:
00009  * George Petasis, National Centre for Scientific Research "Demokritos",
00010  * Aghia Paraskevi, Athens, Greece.
00011  * e-mail: petasis@iit.demokritos.gr
00012  * Laurent Riesterer, Rennes, France.
00013  * e-mail: laurent.riesterer@free.fr
00014  *
00015  * The following terms apply to all files associated
00016  * with the software unless explicitly disclaimed in individual files.
00017  *
00018  * The authors hereby grant permission to use, copy, modify, distribute,
00019  * and license this software and its documentation for any purpose, provided
00020  * that existing copyright notices are retained in all copies and that this
00021  * notice is included verbatim in any distributions. No written agreement,
00022  * license, or royalty fee is required for any of the authorized uses.
00023  * Modifications to this software may be copyrighted by their authors
00024  * and need not follow the licensing terms described here, provided that
00025  * the new terms are clearly indicated on the first page of each file where
00026  * they apply.
00027  * 
00028  * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
00029  * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
00030  * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
00031  * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  * 
00034  * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
00035  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
00036  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
00037  * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
00038  * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
00039  * MODIFICATIONS.
00040  */
00041 
00042 #ifndef _X_DND_H
00043 #define _X_DND_H
00044 #include "vtkTcl.h"
00045 #include "vtkTk.h"
00046 #include <tcl.h>
00047 #include <tk.h>
00048 #include "tkDND.h"
00049 
00050 #ifdef  TKDND_ENABLE_MOTIF_DRAGS
00051 #ifndef TKDND_ENABLE_MOTIF_DROPS
00052 #define TKDND_ENABLE_MOTIF_DROPS
00053 #endif /* TKDND_ENABLE_MOTIF_DROPS */
00054 #endif /* TKDND_ENABLE_MOTIF_DRAGS */
00055 
00056 /*
00057  * We also support Motif drops :-)
00058  */
00059 #ifdef TKDND_ENABLE_MOTIF_DROPS
00060 #include "Dnd.h"
00061 #endif /* TKDND_ENABLE_MOTIF_DROPS */
00062 
00063 #define XDND_VERSION 3
00064 #define XDND_MINVERSION 3
00065 #define XDND_ENTERTYPECOUNT 3
00066 #define XDND_BOOL short
00067 
00068 #define XDND_NODROP_CURSOR     0
00069 #define XDND_COPY_CURSOR       1
00070 #define XDND_MOVE_CURSOR       2
00071 #define XDND_LINK_CURSOR       3
00072 #define XDND_ASK_CURSOR        4
00073 #define XDND_PRIVATE_CURSOR    5
00074 
00075 /*
00076  * Debug Facilities...
00077  */
00078 #ifndef XDND_DEBUG
00079 #ifdef  DND_DEBUG
00080 #include <stdio.h>
00081 #define XDND_DEBUG(a)          \
00082   printf("%s, %d: " a,__FILE__,__LINE__);         fflush(stdout)
00083 #define XDND_DEBUG2(a,b)       \
00084   printf("%s, %d: " a,__FILE__,__LINE__,b);       fflush(stdout)
00085 #define XDND_DEBUG3(a,b,c)     \
00086   printf("%s, %d: " a,__FILE__,__LINE__,b,c);     fflush(stdout)
00087 #define XDND_DEBUG4(a,b,c,d)   \
00088   printf("%s, %d: " a,__FILE__,__LINE__,b,c,d);   fflush(stdout)
00089 #define XDND_DEBUG5(a,b,c,d,e) \
00090   printf("%s, %d: " a,__FILE__,__LINE__,b,c,d,e); fflush(stdout)
00091 #else  /* DND_DEBUG */
00092 #define XDND_DEBUG(a)
00093 #define XDND_DEBUG2(a,b)
00094 #define XDND_DEBUG3(a,b,c)
00095 #define XDND_DEBUG4(a,b,c,d)
00096 #define XDND_DEBUG5(a,b,c,d,e)
00097 #endif /* DND_DEBUG */
00098 #endif /* XDND_DEBUG */
00099 
00100 #ifdef  __cplusplus
00101 extern "C" {
00102 #endif
00103 
00104 #ifndef LONG_MAX
00105 #define LONG_MAX 0x8000000L
00106 #endif
00107 
00108 #define Min(x,y) (x<y?x:y)
00109 #define XDND_Sqrt(x) ((x)*(x))
00110 #ifndef False
00111 #define False 0
00112 #endif /* False */
00113 #ifndef True
00114 #define True 1
00115 #endif /* True */
00116 
00117 typedef struct _XDND_Cursor {
00118   int width, height;
00119   int x, y;
00120   unsigned char *image_data, *mask_data;
00121   char *_action;
00122   Pixmap image_pixmap, mask_pixmap;
00123   Cursor cursor;
00124   Atom action;
00125 } XDNDCursor;
00126 
00127 typedef struct _XDND_Struct {
00128   Tk_Window    MainWindow;          /* The main window of our application */
00129   Tcl_Interp  *interp;              /* A Tcl Interpreter */
00130   Display     *display;             /* Display Pointer */
00131   Window       RootWindow;          /* Display's root window */
00132   Atom         XDNDVersion;         /* Protocol version being used */
00133   int          x;                   /* Current position of the mouse */
00134   int          y;                   /* Current position of the mouse */
00135   int          button;              /* Current button used for drag operation*/
00136   unsigned int state;               /* Current state to convert to modifiers */
00137   int          CallbackStatus;      /* The return value of last tcl callback */
00138   XDND_BOOL    ResetValues;         /* This is used by TkDND_HandleDNDLeave */
00139 
00140     /* Slots used during drag... */
00141   XDND_BOOL   InternalDrag;         /* True if the drag is in the same app */
00142   XDND_BOOL   ReceivedStatusFlag;   /* True if received any XdndStatus 
00143                                         from current target */
00144   char       *data;                 /* Pointer to hold the dnd data */
00145   int         index;                /* Length of dnd data */
00146   
00147     /* Drag source window info */
00148   Window      DraggerWindow;        /* Window of the drag source */
00149   Atom       *DraggerTypeList;      /* Type list supported by the drag source */
00150   Atom       *DraggerAskActionList; /* Actions supported by the drag source */
00151   char       *DraggerAskDescriptions; /* Descriptions of supported actions */
00152   Tk_Window   CursorWindow;         /* A window to replace cursor */
00153   char       *CursorCallback;       /* A Callback to update cursor window */
00154   XDND_BOOL   WaitForStatusFlag;    /* True if waiting for XdndStatus message */
00155 
00156     /* Current drop target info */ 
00157   Window      Toplevel;             /* The toplevel that the mouse is in */
00158   Window      MouseWindow;          /* Window that mouse is in; not owned */
00159   XDND_BOOL   MouseWindowIsAware;   /* True if itsMouseWindow has XdndAware */
00160   Window      MsgWindow;            /* Window that receives messages 
00161                                        (not MouseWindow if proxy) */
00162   Atom        DesiredType;          /* The drop desired type */
00163 #ifdef XDND_USE_TK_GET_SELECTION
00164   char       *DesiredName;          /* The string of the desired type */
00165 #endif /* XDND_USE_TK_GET_SELECTION */
00166   Atom        SupportedAction;      /* The supported by the target action */
00167   
00168   XDND_BOOL   WillAcceptDropFlag;   /* True if target will accept drop */
00169   Time        LastEventTime;        /* Time of the last processed event */
00170   
00171   XDND_BOOL   IsDraggingFlag;       /* True until XDND_Finish is called */
00172   XDND_BOOL   UseMouseRectFlag;     /* True if use MouseRectR */
00173   XRectangle  MouseRectR;           /* Don't send another XdndPosition while 
00174                                        inside here */
00175   XDNDCursor *cursors;              /* The available cursors... */
00176 
00177   /*
00178    * Motif slots...
00179    */
00180 #ifdef TKDND_ENABLE_MOTIF_DROPS
00181   DndData     Motif_DND_Data;       /* Internal Motif data... */
00182   int         Motif_DND;            /* True if protocol in use is Motif */
00183   Atom        Motif_DND_SuccessAtom;
00184   Atom        Motif_DND_FailureAtom;
00185 #endif /* TKDND_ENABLE_MOTIF_DROPS */
00186 #ifdef TKDND_ENABLE_MOTIF_DRAGS
00187   Window      Motif_LastToplevel;   /* The last toplevel we send enter */
00188   int         Motif_ToplevelAware;  /* True if dnd->Toplevel supports Motif */
00189   Atom        Motif_DND_Selection;  /* The selection that will be used */
00190   Atom        Motif_DND_WM_STATE;   /* WM_STATE property */
00191 #endif /* TKDND_ENABLE_MOTIF_DRAGS */
00192 
00193   /*
00194    * Keep info about the last window that we send a <DragEnter> event.
00195    * If the LastEnterDeliveredWindow is not None, then we have to simulate
00196    * a DragLeave to that window. We have to do that, as qt for example
00197    * sometimes forgets (!) to send Leave events to windows that overlap...
00198    */
00199   Window      LastEnterDeliveredWindow;
00200   unsigned int
00201               Alt_ModifierMask;    /* The modifier the Alt keys are bind to */
00202   unsigned int
00203               Meta_ModifierMask;   /* The modifier the Meta keys are bind to */
00204   
00205   /* Here we keep some frequently used Atoms... */
00206   Atom        DNDSelectionName;
00207 
00208   Atom        DNDProxyXAtom;
00209   Atom        DNDAwareXAtom;
00210   Atom        DNDTypeListXAtom;
00211   
00212   Atom        DNDEnterXAtom;
00213   Atom        DNDHereXAtom;
00214   Atom        DNDStatusXAtom;
00215   Atom        DNDLeaveXAtom;
00216   Atom        DNDDropXAtom;
00217   Atom        DNDFinishedXAtom;
00218 
00219   Atom        DNDActionCopyXAtom;
00220   Atom        DNDActionMoveXAtom;
00221   Atom        DNDActionLinkXAtom;
00222   Atom        DNDActionAskXAtom;
00223   Atom        DNDActionPrivateXAtom;
00224 
00225   Atom        DNDActionListXAtom;
00226   Atom        DNDActionDescriptionXAtom;
00227 
00228   Atom        DNDDirectSave0XAtom;
00229 
00230   Atom        DNDMimePlainTextXAtom;
00231   Atom        DNDStringAtom;
00232   Atom        DNDNonProtocolAtom;
00233 
00234   /*
00235    * Allow user to register event callbacks...
00236    */
00237 
00238   /* This function will be called for various windows (application or
00239    * foreign). It must return True if given window is a valid one and belongs
00240    * to this application. Else, False must be returned.
00241    * If this method is not set then the code assumes that no widgets have
00242    * support for recieving drops. In this case none of the widget methods
00243    * need be set.
00244    */
00245   int (*WidgetExistsCallback) (struct _XDND_Struct *dnd, Window window);
00246   /* This function will be called when the mouse has entered a widget to
00247    * announce "XdndEnter". This function must return True if the widget will
00248    * accept the drop and False otherwise. If True is returned, the apply
00249    * position callback (the next pointer :-)) will be immediately called...
00250    */
00251   int (*WidgetApplyEnterCallback) (struct _XDND_Struct *dnd,
00252         Window target, Window source, Atom action, int x, int y,
00253         Time t, Atom *typelist);
00254   /* This function will be called when the mouse is moving inside a drag
00255    * target. It is responsible for changing the drop target widget appearence.
00256    * It must also sets the correct data to pointers. As per the protocol, if
00257    * the widget cannot perform the action specified by `action' then it should
00258    * return either XdndActionPrivate or XdndActionCopy into supported_action
00259    * (leaving  supported_action unchanged is equivalent to XdndActionCopy).
00260    * Returns True if widget is ready to accept the drop...
00261    */
00262   int (*WidgetApplyPositionCallback) (struct _XDND_Struct *dnd,
00263         Window target, Window source, Atom action, Atom *actionList,
00264         int x, int y, Time t, Atom *typelist, int *wantPosition,
00265         Atom *supported_action, Atom *desired_type, XRectangle *rectangle);
00266   /* This function will be called when the mouse leaves a drop target widget,
00267    * or when the drop is canceled. It must update the widget border to its
00268    * default appearance...
00269    */
00270   int (*WidgetApplyLeaveCallback) (struct _XDND_Struct *dnd, Window target);
00271   /* This function must insert the data into the drop target */
00272   int (*WidgetInsertDropDataCallback) (struct _XDND_Struct *dnd,
00273        unsigned char *data, int length, int remaining,
00274        Window into, Window from, Atom type);
00275   /* This function will be used in order to get the user-prefered action, if
00276    * the action is XdndAsk... */
00277   int (*Ask) (struct _XDND_Struct *dnd, Window source, Window target,
00278               Atom *action);
00279   /* This is our callback to get the data that is to be dropped from the drag
00280    * source... */
00281   int (*GetData) (struct _XDND_Struct *dnd, Window source, 
00282                   unsigned char **data, int *length, Atom type);
00283   /* This function will be called, in order to handle events that are not
00284    * related to the XDND protocol... */
00285   void (*HandleEvents) (struct _XDND_Struct *dnd, XEvent *xevent);
00286   /*
00287    * This function must return the current types that a window supports as a
00288    * drag source...
00289    */
00290   Atom *(*GetDragAtoms) (struct _XDND_Struct *dnd, Window window);
00291   /*
00292    * Set the cursor callback...
00293    * The requested cursors will be one of the extern Cursor variables:
00294    *   noDropCursor, moveCursor, copyCursor, linkCursor, askCursor
00295    */
00296   int (*SetCursor) (struct _XDND_Struct *dnd, int cursor);
00297 } XDND;
00298 #define DndClass XDND
00299 extern Cursor noDropCursor, moveCursor, copyCursor, linkCursor, askCursor;
00300 
00301 /*
00302  * Function Prototypes...
00303  */
00304 
00305 void      XDND_Reset(XDND *dndp);
00306 XDND     *XDND_Init(Display *display);
00307 void      XDND_Enable(XDND *dnd, Window window);
00308 XDND_BOOL XDND_IsDndAware(XDND *dnd, Window window, Window* proxy, Atom *vers);
00309 int       XDND_AtomListLength(Atom *list);
00310 int       XDND_DescriptionListLength(char *list);
00311 Atom     *XDND_GetTypeList(XDND *dnd, Window window);
00312 void      XDND_AnnounceTypeList(XDND *dnd, Window window, Atom *list);
00313 void      XDND_AppendType(XDND *dnd, Window window, Atom type);
00314 void      XDND_AnnounceAskActions(XDND *dnd, Window window, Atom *Actions,
00315                                   char *Descriptions);
00316 Atom     *XDND_GetAskActions(XDND *dnd, Window window);
00317 char     *XDND_GetAskActionDescriptions(XDND *dnd, Window window);
00318 XDND_BOOL XDND_DraggerCanProvideText(XDND *dnd);
00319 XDND_BOOL XDND_FindTarget(XDND *dnd, int x, int y,
00320                           Window *toplevel, Window *msgWindow,
00321                           Window *target, XDND_BOOL *aware, Atom *version);
00322 Window    XDND_FindToplevel(XDND *dnd, Window window);
00323 
00324 XDND_BOOL XDND_BeginDrag(XDND *dnd, Window source, Atom *actions, Atom *types,
00325                          char *Descriptions, Tk_Window cursor_window,
00326                          char *cursor_callback);
00327 
00328 void      XDND_SendDNDEnter(XDND *dnd, Window window, Window msgWindow,
00329                             XDND_BOOL isAware, Atom vers);
00330 XDND_BOOL XDND_SendDNDPosition(XDND *dnd, Atom action);
00331 XDND_BOOL XDND_SendDNDStatus(XDND *dnd, Atom action);
00332 XDND_BOOL XDND_SendDNDLeave(XDND *dnd);
00333 XDND_BOOL XDND_SendDNDDrop(XDND *dnd);
00334 XDND_BOOL XDND_SendDNDSelection(XDND *dnd, XSelectionRequestEvent *request);
00335 
00336 int XDND_HandleClientMessage(XDND *dnd, XEvent *xevent);
00337 int XDND_HandleDNDEnter(XDND *dnd, XClientMessageEvent clientMessage);
00338 int XDND_HandleDNDHere(XDND *dnd, XClientMessageEvent clientMessage);
00339 int XDND_HandleDNDLeave(XDND *dnd, XClientMessageEvent clientMessage);
00340 int XDND_HandleDNDDrop(XDND *dnd, XClientMessageEvent clientMessage);
00341 int XDND_GetSelProc(ClientData clientData, Tcl_Interp *interp, char *portion);
00342 
00343 int XDND_HandleDNDStatus(XDND *dnd, XClientMessageEvent clientMessage);
00344 
00345 #ifdef TKDND_ENABLE_MOTIF_DROPS
00346 int MotifDND_HandleClientMessage(XDND *dnd, XEvent xevent);
00347 #endif /* TKDND_ENABLE_MOTIF_DROPS */
00348 #ifdef  __cplusplus
00349 }
00350 #endif
00351 
00352 #endif /* _X_DND_H */