diff --git a/src/Makefile.am b/src/Makefile.am index d420f70f..c2b9638e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -77,8 +77,8 @@ wmaker_SOURCES = \ texture.h \ usermenu.c \ usermenu.h \ - xde.h \ - xde.c \ + xdnd.h \ + xdnd.c \ xmodifier.h \ xmodifier.c \ xutil.c \ diff --git a/src/Makefile.in b/src/Makefile.in index abd8e474..a7be89f4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -99,7 +99,7 @@ bin_PROGRAMS = wmaker EXTRA_DIST = wmnotify.c wmnotdef.h wmnotify.h -wmaker_SOURCES = GNUstep.h WindowMaker.h actions.c actions.h appicon.c appicon.h application.c application.h appmenu.c appmenu.h balloon.c balloon.h client.c client.h colormap.c def_pixmaps.h defaults.c defaults.h dialog.c dialog.h dock.c dockedapp.c dock.h event.c framewin.c framewin.h gnome.c gnome.h funcs.h icon.c icon.h keybind.h kwm.h kwm.c list.c list.h main.c menu.c menu.h misc.c motif.c motif.h moveres.c openlook.c openlook.h pixmap.c pixmap.h placement.c properties.c properties.h proplist.c resources.c resources.h rootmenu.c screen.c screen.h session.h session.c shutdown.c stacking.c stacking.h startup.c superfluous.c superfluous.h switchmenu.c texture.c texture.h usermenu.c usermenu.h xde.h xde.c xmodifier.h xmodifier.c xutil.c xutil.h wconfig.h wcore.c wcore.h wdefaults.c wdefaults.h window.c window.h winmenu.c winspector.h winspector.c workspace.c workspace.h wmsound.c wmsound.h text.c text.h +wmaker_SOURCES = GNUstep.h WindowMaker.h actions.c actions.h appicon.c appicon.h application.c application.h appmenu.c appmenu.h balloon.c balloon.h client.c client.h colormap.c def_pixmaps.h defaults.c defaults.h dialog.c dialog.h dock.c dockedapp.c dock.h event.c framewin.c framewin.h gnome.c gnome.h funcs.h icon.c icon.h keybind.h kwm.h kwm.c list.c list.h main.c menu.c menu.h misc.c motif.c motif.h moveres.c openlook.c openlook.h pixmap.c pixmap.h placement.c properties.c properties.h proplist.c resources.c resources.h rootmenu.c screen.c screen.h session.h session.c shutdown.c stacking.c stacking.h startup.c superfluous.c superfluous.h switchmenu.c texture.c texture.h usermenu.c usermenu.h xdnd.h xdnd.c xmodifier.h xmodifier.c xutil.c xutil.h wconfig.h wcore.c wcore.h wdefaults.c wdefaults.h window.c window.h winmenu.c winspector.h winspector.c workspace.c workspace.h wmsound.c wmsound.h text.c text.h CPPFLAGS = @CPPFLAGS@ @DFLAGS@ -DLOCALEDIR=\"$(NLSDIR)\" @@ -126,7 +126,7 @@ client.o colormap.o defaults.o dialog.o dock.o dockedapp.o event.o \ framewin.o gnome.o icon.o kwm.o list.o main.o menu.o misc.o motif.o \ moveres.o openlook.o pixmap.o placement.o properties.o proplist.o \ resources.o rootmenu.o screen.o session.o shutdown.o stacking.o \ -startup.o superfluous.o switchmenu.o texture.o usermenu.o xde.o \ +startup.o superfluous.o switchmenu.o texture.o usermenu.o xdnd.o \ xmodifier.o xutil.o wcore.o wdefaults.o window.o winmenu.o winspector.o \ workspace.o wmsound.o text.o wmaker_DEPENDENCIES = $(top_builddir)/WINGs/libWINGs.a \ diff --git a/src/appicon.c b/src/appicon.c index 1fc2e8b8..e55e8574 100644 --- a/src/appicon.c +++ b/src/appicon.c @@ -44,6 +44,9 @@ #include "framewin.h" #include "dialog.h" #include "client.h" +#ifdef XDND +#include "xdnd.h" +#endif /* * icon_file for the dock is got from the preferences file by @@ -103,6 +106,9 @@ wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance, dicon->icon = wIconCreateWithIconFile(scr, path, tile); if (path) free(path); +#ifdef XDND + wXDNDMakeAwareness(dicon->icon->core->window); +#endif #ifdef REDUCE_APPICONS dicon->num_apps = 0; #endif @@ -219,6 +225,9 @@ wAppIconCreate(WWindow *leader_win) CWSaveUnder, &attribs); } #endif +#ifdef XDND + wXDNDMakeAwareness(aicon->icon->core->window); +#endif /* will be overriden if docked */ aicon->icon->core->descriptor.handle_mousedown = appIconMouseDown; diff --git a/src/event.c b/src/event.c index 6d26a4fb..52b2ef83 100644 --- a/src/event.c +++ b/src/event.c @@ -34,8 +34,8 @@ #ifdef SHAPE #include #endif -#ifdef XDE_DND -#include "xde.h" +#ifdef XDND +#include "xdnd.h" #endif #ifdef KEEP_XKB_LOCK_STATUS @@ -405,6 +405,7 @@ handleDeadProcess(void *foo) static void saveTimestamp(XEvent *event) { + WScreen *scr = wScreenForWindow(event->xany.window); LastTimestamp = CurrentTime; switch (event->type) { @@ -434,6 +435,29 @@ saveTimestamp(XEvent *event) break; case SelectionNotify: LastTimestamp = event->xselection.time; +#ifdef XDND + wXDNDProcessSelection(&event->xselection); + { + char *retain = scr->xdestring; + for (;retain[0];retain++) { + if (retain[0] < 32) retain[0] = 32; + if (!strncmp(retain, "file:", 5)) { + int i; + for (i=0;i<5;retain[i++]=' '); + } + } + retain = scr->xdestring; + if (scr->xdestring){ + if (!strncmp(scr->xdestring, "file:", 5)) + scr->xdestring+=5; + } + wDockReceiveDNDDrop(scr,event); + if (retain){ + XFree(retain); + scr->xdestring = NULL; + } + } +#endif break; } } @@ -911,10 +935,10 @@ handleClientMessage(XEvent *event) } else if (wKWMProcessClientMessage(&event->xclient)) { /* do nothing */ #endif /* KWM_HINTS */ -#ifdef XDE_DND - } else if (wXDEProcessClientMessage(&event->xclient)) { +#ifdef XDND + } else if (wXDNDProcessClientMessage(&event->xclient)) { /* do nothing */ -#endif /* XDE_DND */ +#endif /* XDND */ #ifdef OFFIX_DND } else if (event->xclient.message_type==_XA_DND_PROTOCOL) { WScreen *scr = wScreenForWindow(event->xclient.window); diff --git a/src/main.c b/src/main.c index 6d269ccf..5d260337 100644 --- a/src/main.c +++ b/src/main.c @@ -113,15 +113,6 @@ Atom _XA_WINDOWMAKER_COMMAND; Atom _XA_DND_PROTOCOL; Atom _XA_DND_SELECTION; #endif -#ifdef XDE_DND -Atom _XA_XDE_REQUEST; -Atom _XA_XDE_ENTER; -Atom _XA_XDE_LEAVE; -Atom _XA_XDE_DATA_AVAILABLE; -Atom _XDE_FILETYPE; -Atom _XDE_URLTYPE; -#endif - /* cursors */ Cursor wCursor[WCUR_LAST]; diff --git a/src/misc.c b/src/misc.c index 0c2fea81..2feecd1a 100644 --- a/src/misc.c +++ b/src/misc.c @@ -875,8 +875,11 @@ get_dnd_selection(WScreen *scr) char *flat_string; int count; -#ifdef XDE_DND +#ifdef XDND if(scr->xdestring) { + /* + printf(" return %s\n",scr->xdestring); + */ return (wstrdup(scr->xdestring)); } #endif diff --git a/src/screen.h b/src/screen.h index b1a3c119..5b42391a 100644 --- a/src/screen.h +++ b/src/screen.h @@ -26,10 +26,6 @@ #include "WindowMaker.h" #include -#ifdef XDE_DND -#include -#endif - #include @@ -298,7 +294,7 @@ typedef struct _WScreen { struct WWindow *shortcutWindow[MAX_WINDOW_SHORTCUTS]; struct LinkedList *shortcutSelectedWindows[MAX_WINDOW_SHORTCUTS]; -#ifdef XDE_DND +#ifdef XDND char *xdestring; #endif diff --git a/src/startup.c b/src/startup.c index 695c0d32..3dc3d419 100644 --- a/src/startup.c +++ b/src/startup.c @@ -57,6 +57,9 @@ #include "defaults.h" #include "properties.h" #include "dialog.h" +#ifdef XDND +#include "xdnd.h" +#endif #include "xutil.h" @@ -125,14 +128,6 @@ extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW; extern Atom _XA_DND_PROTOCOL; extern Atom _XA_DND_SELECTION; #endif -#ifdef XDE_DND -extern Atom _XA_XDE_REQUEST; -extern Atom _XA_XDE_ENTER; -extern Atom _XA_XDE_LEAVE; -extern Atom _XA_XDE_DATA_AVAILABLE; -extern Atom _XDE_FILETYPE; -extern Atom _XDE_URLTYPE; -#endif /* cursors */ @@ -697,13 +692,8 @@ StartUp(Bool defaultScreenOnly) _XA_DND_SELECTION = XInternAtom(dpy, "DndSelection", False); _XA_DND_PROTOCOL = XInternAtom(dpy, "DndProtocol", False); #endif -#ifdef XDE_DND - _XA_XDE_ENTER = XInternAtom(dpy, "_XDE_ENTER", False); - _XA_XDE_REQUEST = XInternAtom(dpy, "_XDE_REQUEST", False); - _XA_XDE_LEAVE = XInternAtom(dpy, "_XDE_LEAVE", False); - _XA_XDE_DATA_AVAILABLE = XInternAtom(dpy, "_XDE_DATA_AVAILABLE", False); - _XDE_FILETYPE = XInternAtom(dpy, "file:ALL", False); - _XDE_URLTYPE = XInternAtom(dpy, "url:ALL", False); +#ifdef XDND + wXDNDInitializeAtoms(); #endif diff --git a/src/wconfig.h.in b/src/wconfig.h.in index 246d35bd..c0694ff2 100644 --- a/src/wconfig.h.in +++ b/src/wconfig.h.in @@ -72,9 +72,9 @@ #define OFFIX_DND /* - * support for XDE drang and drop in the Dock. Experimental + * support for XDND drop in the Dock. Experimental */ -#undef XDE_DND +#undef XDND /* * support for Motif window manager (mwm) window hints diff --git a/src/wcore.c b/src/wcore.c index ee73075e..7ef8381e 100644 --- a/src/wcore.c +++ b/src/wcore.c @@ -69,9 +69,6 @@ wCoreCreateTopLevel(WScreen *screen, int x, int y, int width, int height, attribs.border_pixel = screen->frame_border_pixel; attribs.event_mask = SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask | EnterWindowMask -#ifdef XDE_DND - | StructureNotifyMask -#endif | LeaveWindowMask; vmask |= CWColormap; diff --git a/src/xde.c b/src/xde.c deleted file mode 100644 index a8ef769d..00000000 --- a/src/xde.c +++ /dev/null @@ -1,113 +0,0 @@ - -#include "wconfig.h" - -#ifdef XDE_DND - -#include -#include "WindowMaker.h" -#include "window.h" - -#include "stdlib.h" - -#include -#include - - -extern Atom _XA_XDE_REQUEST; -extern Atom _XA_XDE_ENTER; -extern Atom _XA_XDE_LEAVE; -extern Atom _XA_XDE_DATA_AVAILABLE; -extern Atom _XDE_FILETYPE; -extern Atom _XDE_URLTYPE; - - - -Bool -wXDEProcessClientMessage(XClientMessageEvent *event) -{ - Bool done = False; - - if (event->message_type==_XA_XDE_DATA_AVAILABLE) { - GdkEvent gdkev; - WScreen *scr = wScreenForWindow(event->window); - Atom tmpatom; - int datalenght; - long tmplong; - char * tmpstr, * runstr, * freestr, * tofreestr; - printf("x\n"); - gdkev.dropdataavailable.u.allflags = event->data.l[1]; - gdkev.dropdataavailable.timestamp = event->data.l[4]; - - if(gdkev.dropdataavailable.u.flags.isdrop){ - gdkev.dropdataavailable.type = GDK_DROP_DATA_AVAIL; - gdkev.dropdataavailable.requestor = event->data.l[0]; - XGetWindowProperty(dpy,gdkev.dropdataavailable.requestor, - event->data.l[2], - 0, LONG_MAX -1, - 0, XA_PRIMARY, &tmpatom, - &datalenght, - &gdkev.dropdataavailable.data_numbytes, - &tmplong, - &tmpstr); - datalenght=gdkev.dropdataavailable.data_numbytes-1; - tofreestr=tmpstr; - runstr=NULL; - for(;datalenght>0;datalenght-=(strlen(tmpstr)+1),tmpstr=&tmpstr[strlen(tmpstr)+1]){ - freestr=runstr;runstr=wstrappend(runstr,tmpstr);free(freestr); - freestr=runstr;runstr=wstrappend(runstr," ");free(freestr); - } - free(tofreestr); - scr->xdestring=runstr; - /* no need to redirect ? */ - wDockReceiveDNDDrop(scr,event); - free(runstr); - scr->xdestring=NULL; - } - done = True; - } else if (event->message_type==_XA_XDE_LEAVE) { - printf("leave\n"); - done = True; - } else if (event->message_type==_XA_XDE_ENTER) { - GdkEvent gdkev; - XEvent replyev; - - gdkev.dropenter.u.allflags=event->data.l[1]; - printf("from win %x\n",event->data.l[0]); - printf("to win %x\n",event->window); - printf("enter %x\n",event->data.l[1]); - printf("v %x ",event->data.l[2]); - printf("%x ",event->data.l[3]); - printf("%x\n",event->data.l[4]); - - if(event->data.l[2]==_XDE_FILETYPE || - event->data.l[3]==_XDE_FILETYPE || - event->data.l[4]==_XDE_FILETYPE || - event->data.l[2]==_XDE_URLTYPE || - event->data.l[3]==_XDE_URLTYPE || - event->data.l[4]==_XDE_URLTYPE) - if(gdkev.dropenter.u.flags.sendreply){ - /*reply*/ - replyev.xclient.type = ClientMessage; - replyev.xclient.window = event->data.l[0]; - replyev.xclient.format = 32; - replyev.xclient.message_type = _XA_XDE_REQUEST; - replyev.xclient.data.l[0] = event->window; - - gdkev.dragrequest.u.allflags = 0; - gdkev.dragrequest.u.flags.protocol_version = 0; - gdkev.dragrequest.u.flags.willaccept = 1; - gdkev.dragrequest.u.flags.delete_data = 0; - - replyev.xclient.data.l[1] = gdkev.dragrequest.u.allflags; - replyev.xclient.data.l[2] = replyev.xclient.data.l[3] = 0; - replyev.xclient.data.l[4] = event->data.l[2]; - XSendEvent(dpy, replyev.xclient.window, 0, NoEventMask, &replyev); - XSync(dpy, 0); - } - done = True; - } - - return done; -} - -#endif diff --git a/src/xde.h b/src/xde.h deleted file mode 100644 index 971895c6..00000000 --- a/src/xde.h +++ /dev/null @@ -1,8 +0,0 @@ - -#ifndef _XDE_H_ -#define _XDE_H_ - -Bool wXDEProcessClientMessage(XClientMessageEvent *event); - - -#endif diff --git a/src/xdnd.c b/src/xdnd.c new file mode 100644 index 00000000..8c863e6e --- /dev/null +++ b/src/xdnd.c @@ -0,0 +1,276 @@ +/* Many part of code are ripped of an example from JX's site */ + +#include "wconfig.h" + +#ifdef XDND + +#include +#include "WindowMaker.h" +#include "window.h" +#include "dock.h" +#include "xdnd.h" +#include "motif.h" + +#include "workspace.h" + +#include "stdlib.h" + +#include + + +#define XDND_VERSION 3L + +Atom _XA_XdndAware; +Atom _XA_XdndEnter; +Atom _XA_XdndLeave; +Atom _XA_XdndDrop; +Atom _XA_XdndPosition; +Atom _XA_XdndStatus; +Atom _XA_XdndActionCopy; +Atom _XA_XdndSelection; +Atom _XA_XdndFinished; +Atom _XA_WINDOWMAKER_XDNDEXCHANGE; + +/* +Atom _XA_MOTIF_DRAG_RECEIVER_INFO; +Atom _XA_MOTIF_DRAG_AND_DROP_MESSAGE; +*/ + +Atom atom_support; + +void wXDNDInitializeAtoms() +{ + + _XA_XdndAware = XInternAtom(dpy, "XdndAware", False); + _XA_XdndEnter = XInternAtom(dpy, "XdndEnter", False); + _XA_XdndLeave = XInternAtom(dpy, "XdndLeave", False); + _XA_XdndDrop = XInternAtom(dpy, "XdndDrop", False); + _XA_XdndPosition = XInternAtom(dpy, "XdndPosition", False); + _XA_XdndStatus = XInternAtom(dpy, "XdndStatus", False); + _XA_XdndActionCopy = XInternAtom(dpy, "XdndActionCopy", False); + _XA_XdndSelection = XInternAtom(dpy, "XdndSelection", False); + _XA_XdndFinished = XInternAtom(dpy, "XdndFinished", False); + + _XA_WINDOWMAKER_XDNDEXCHANGE = XInternAtom(dpy, "_WINDOWMAKER_XDNDEXCHANGE", False); + + /* + _XA_MOTIF_DRAG_RECEIVER_INFO = XInternAtom(dpy, "_MOTIF_DRAG_RECEIVER_INFO",False); + _XA_MOTIF_DRAG_AND_DROP_MESSAGE = XInternAtom(dpy, "_MOTIF_DRAG_AND_DROP_MESSAGE", False); + */ +} + +void wXDNDMakeAwareness(Window window) { + long int xdnd_version = 3; + /* + MotifDragReceiverInfo info; + */ + XChangeProperty (dpy, window, _XA_XdndAware, XA_ATOM, + 32, PropModeAppend, (char *)&xdnd_version, 1); + + /*** MOTIF *** + info.byte_order = '\0'; + info.protocol_version = 0; + info.protocol_style = XmDRAG_DYNAMIC; + info.proxy_window = 0; + info.num_drop_sites = 0; + info.total_size = sizeof(info); + + XChangeProperty (dpy, window, + _XA_MOTIF_DRAG_RECEIVER_INFO, + _XA_MOTIF_DRAG_RECEIVER_INFO, + 8, PropModeReplace, + (unsigned char *)&info, + sizeof (info)); + */ +} + +void wXDNDClearAwareness(Window window) { + long int xdnd_version = 3; + XDeleteProperty (dpy, window, _XA_XdndAware); +} + +Bool +wXDNDProcessSelection(XSelectionEvent *event) +{ + WScreen *scr = wScreenForWindow(event->requestor); + char *dropdata; + Atom ret_type; + int ret_format; + unsigned long ret_item; + unsigned long remain_byte; + char * delme; + Window selowner = XGetSelectionOwner(dpy,_XA_XdndSelection); + XGetWindowProperty(dpy, event->requestor, _XA_WINDOWMAKER_XDNDEXCHANGE, + 0, 65536, True, atom_support, &ret_type, &ret_format, + &ret_item, &remain_byte, (unsigned char **)&delme); + if (delme){ + /* + printf("get -%s-\n",delme); + */ + scr->xdestring=delme; + } + + { + /*finished*/ + XEvent xevent; + memset (&xevent, 0, sizeof(xevent)); + xevent.xany.type = ClientMessage; + xevent.xany.display = dpy; + xevent.xclient.window = selowner; + xevent.xclient.message_type = _XA_XdndFinished; + xevent.xclient.format = 32; + + XDND_FINISHED_TARGET_WIN(&xevent) = event->requestor; + XSendEvent(dpy, selowner, 0, 0, &xevent); + } +} + +Bool +isAwareXDND(Window window) +{ + Atom actual; + int format; + unsigned long count, remaining; + unsigned char *data=0; + Atom *types, *t; + + if (!window) return False; + XGetWindowProperty (dpy, window, _XA_XdndAware, + 0, 0x8000000L, False, XA_ATOM, + &actual, &format, + &count, &remaining, &data); + if (actual != XA_ATOM || format != 32 || count == 0 || !data) { + if (data) + XFree (data); + return False; + } + if (data) + XFree (data); + return True; +} + +Bool +acceptXDND(Window window) +{ + WScreen *scr = wScreenForWindow(window); + WWindow *wwin = wWindowFor(window); + WDock *dock; + int icon_pos,i; + + icon_pos = -1; + if ((dock = scr->dock)!=NULL) { + for (i=0; imax_icons; i++) { + if (dock->icon_array[i] + && dock->icon_array[i]->icon->core->window==window) { + icon_pos = i; + break; + } + } + } + if (icon_pos<0 && (dock = scr->workspaces[scr->current_workspace]->clip)!=NULL) { + for (i=0; imax_icons; i++) { + if (dock->icon_array[i] + && dock->icon_array[i]->icon->core->window==window) { + icon_pos = i; + break; + } + } + } + if (icon_pos<0) return False; + if (!dock) return False; + if (isAwareXDND(dock->icon_array[icon_pos]->icon->icon_win)) return False; + + if (dock->icon_array[icon_pos]->dnd_command!=NULL) return True; + + return False; +} + +Bool +wXDNDProcessClientMessage(XClientMessageEvent *event) +{ + /* test */ + { + char * name = XGetAtomName(dpy, event->message_type); + /* + printf("Get %s\n",name); + */ + XFree(name); + } + + /* + if (event->message_type == _XA_MOTIF_DRAG_AND_DROP_MESSAGE) { + printf("motif dnd msg %d\n",event->data.b[0]); + if (event->data.b[0] == XmDROP_START){ + unsigned x_root, y_root, flags; + unsigned char reason; + unsigned long timestamp; + Atom atom; + Window source_window; + MotifDragInitiatorInfo *initiator_info; + Atom ret_type; + int ret_format; + unsigned long ret_item; + unsigned long remain_byte; + + reason = event->data.b[0]; + flags = event->data.s[1]; + timestamp = event->data.l[1]; + x_root = event->data.s[4]; + y_root = event->data.s[5]; + atom = event->data.l[3]; + source_window = event->data.l[4]; + + XGetWindowProperty(dpy, source_window, atom, + 0, sizeof(*initiator_info), True, atom_support, + &ret_type, &ret_format, + &ret_item, &remain_byte, (unsigned char **)&initiator_info); + } + } + else */ + if (event->message_type == _XA_XdndEnter) { + if ((event->data.l[1] & 1) == 0){ + atom_support = event->data.l[2]; + } + /* + else puts("enter more than 3 types"); + */ + return True; + } else if (event->message_type == _XA_XdndLeave) { + return True; + } else if (event->message_type == _XA_XdndDrop) { + if (event->data.l[0] == XGetSelectionOwner(dpy, _XA_XdndSelection)){ + XConvertSelection(dpy, _XA_XdndSelection, atom_support, + _XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime); + } + /* + else puts("wierd selection owner"); + */ + return True; + } else if (event->message_type == _XA_XdndPosition) { + XEvent xevent; + Window srcwin = event->data.l[0]; + if (atom_support != XInternAtom(dpy, "text/uri-list", False)) { + return True; + } + { + memset (&xevent, 0, sizeof(xevent)); + xevent.xany.type = ClientMessage; + xevent.xany.display = dpy; + xevent.xclient.window = srcwin; + xevent.xclient.message_type = _XA_XdndStatus; + xevent.xclient.format = 32; + + XDND_STATUS_TARGET_WIN (&xevent) = event->window; + XDND_STATUS_WILL_ACCEPT_SET (&xevent, acceptXDND(event->window)); + XDND_STATUS_WANT_POSITION_SET(&xevent, True); + XDND_STATUS_RECT_SET(&xevent, 0, 0, 1024,768); + XDND_STATUS_ACTION(&xevent) = _XA_XdndActionCopy; + + XSendEvent(dpy, srcwin, 0, 0, &xevent); + } + return True; + } + return False; +} + +#endif diff --git a/src/xdnd.h b/src/xdnd.h new file mode 100644 index 00000000..9d674619 --- /dev/null +++ b/src/xdnd.h @@ -0,0 +1,53 @@ + +#ifndef _XDND_H_ +#define _XDND_H_ + + +void wXDNDInitializeAtoms(); +Bool wXDNDProcessSelection(XSelectionEvent *event); +Bool wXDNDProcessClientMessage(XClientMessageEvent *event); +void wXDNDMakeAwareness(Window window); +void wXDNDClearAwareness(Window window); + +/* header was ripped from xdnd's example on its page */ + +#define XDND_THREE 3 +#define XDND_ENTER_SOURCE_WIN(e) ((e)->xclient.data.l[0]) +#define XDND_ENTER_THREE_TYPES(e) (((e)->xclient.data.l[1] & 0x1UL) == 0) +#define XDND_ENTER_THREE_TYPES_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x1UL) | (((b) == 0) ? 0 : 0x1UL) +#define XDND_ENTER_VERSION(e) ((e)->xclient.data.l[1] >> 24) +#define XDND_ENTER_VERSION_SET(e,v) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~(0xFF << 24)) | ((v) << 24) +#define XDND_ENTER_TYPE(e,i) ((e)->xclient.data.l[2 + i]) /* i => (0, 1, 2) */ + +/* XdndPosition */ +#define XDND_POSITION_SOURCE_WIN(e) ((e)->xclient.data.l[0]) +#define XDND_POSITION_ROOT_X(e) ((e)->xclient.data.l[2] >> 16) +#define XDND_POSITION_ROOT_Y(e) ((e)->xclient.data.l[2] & 0xFFFFUL) +#define XDND_POSITION_ROOT_SET(e,x,y) (e)->xclient.data.l[2] = ((x) << 16) | ((y) & 0xFFFFUL) +#define XDND_POSITION_TIME(e) ((e)->xclient.data.l[3]) +#define XDND_POSITION_ACTION(e) ((e)->xclient.data.l[4]) + +/* XdndStatus */ +#define XDND_STATUS_TARGET_WIN(e) ((e)->xclient.data.l[0]) +#define XDND_STATUS_WILL_ACCEPT(e) ((e)->xclient.data.l[1] & 0x1L) +#define XDND_STATUS_WILL_ACCEPT_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x1UL) | (((b) == 0) ? 0 : 0x1UL) +#define XDND_STATUS_WANT_POSITION(e) ((e)->xclient.data.l[1] & 0x2UL) +#define XDND_STATUS_WANT_POSITION_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x2UL) | (((b) == 0) ? 0 : 0x2UL) +#define XDND_STATUS_RECT_X(e) ((e)->xclient.data.l[2] >> 16) +#define XDND_STATUS_RECT_Y(e) ((e)->xclient.data.l[2] & 0xFFFFL) +#define XDND_STATUS_RECT_WIDTH(e) ((e)->xclient.data.l[3] >> 16) +#define XDND_STATUS_RECT_HEIGHT(e) ((e)->xclient.data.l[3] & 0xFFFFL) +#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); } +#define XDND_STATUS_ACTION(e) ((e)->xclient.data.l[4]) + +/* XdndLeave */ +#define XDND_LEAVE_SOURCE_WIN(e) ((e)->xclient.data.l[0]) + +/* XdndDrop */ +#define XDND_DROP_SOURCE_WIN(e) ((e)->xclient.data.l[0]) +#define XDND_DROP_TIME(e) ((e)->xclient.data.l[2]) + +/* XdndFinished */ +#define XDND_FINISHED_TARGET_WIN(e) ((e)->xclient.data.l[0]) + +#endif