X-Git-Url: https://repo.or.cz/w/wmaker-crm.git/blobdiff_plain/59fc927dc9f183802621138534fa6eaafe5593ba..688a56e8ab67b56550e2874d9d7423f0d435bfd9:/src/xdnd.c diff --git a/src/xdnd.c b/src/xdnd.c dissimilarity index 88% index 391bccdd..c8119fad 100644 --- a/src/xdnd.c +++ b/src/xdnd.c @@ -1,340 +1,331 @@ -/* 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 -#include - -#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) -{ - XDeleteProperty (dpy, window, _XA_XdndAware); -} - -Bool -wXDNDProcessSelection(XEvent *event) -{ - WScreen *scr = wScreenForWindow(event->xselection.requestor); - char *retain; - Atom ret_type; - int ret_format; - unsigned long ret_item; - unsigned long remain_byte; - char * delme; - XEvent xevent; - Window selowner = XGetSelectionOwner(dpy,_XA_XdndSelection); - WMArray *items; - - - XGetWindowProperty(dpy, event->xselection.requestor, - _XA_WINDOWMAKER_XDNDEXCHANGE, - 0, 65536, True, atom_support, &ret_type, &ret_format, - &ret_item, &remain_byte, (unsigned char **)&delme); - if (delme){ - scr->xdestring=delme; - } - - /*send finished*/ - 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->xselection.requestor; - XSendEvent(dpy, selowner, 0, 0, &xevent); - - /*process dropping*/ - if (scr->xdestring) { - WMArrayIterator iter; - int length, str_size; - int total_size = 0; - char *tmp; - - items = WMCreateArray(4); - retain = wstrdup(scr->xdestring); - XFree(scr->xdestring); /* since xdestring was created by Xlib */ - - length = strlen(retain); - - /* search in string */ - while (length--) { - if (retain[length] == '\r') { /* useless char, nuke it */ - retain[length] = 0; - } - if (retain[length] == '\n') { - str_size = strlen(&retain[length + 1]); - if(str_size) { - WMAddToArray(items, wstrdup(&retain[length + 1])); - total_size += str_size + 3; /* reserve for " \"\"" */ - /* this is nonsense -- if (length) - WMAppendArray(items, WMCreateArray(1));*/ - } - retain[length] = 0; - } - } - /* final one */ - WMAddToArray(items, wstrdup(retain)); - total_size += strlen(retain) + 3; - wfree(retain); - - /* now pack new string */ - scr->xdestring = wmalloc(total_size); - scr->xdestring[0]=0; /* empty string */ - WM_ETARETI_ARRAY(items, tmp, iter) { - if (!strncmp(tmp,"file:",5)) { - /* add more 2 chars while removing 5 is harmless */ - strcat(scr->xdestring, " \""); - strcat(scr->xdestring, &tmp[5]); - strcat(scr->xdestring, "\""); - } else { - /* unsupport object, still need more " ? tell ]d */ - strcat(scr->xdestring, &tmp[5]); - } - wfree(tmp); - } - WMFreeArray(items); - wDockReceiveDNDDrop(scr,event); - /* - printf("free "); - puts(scr->xdestring); - */ - wfree(scr->xdestring); /* this xdestring is not from Xlib (no XFree) */ - } - - /* why doesn't this function return anything ? -Dan */ -} - -Bool -isAwareXDND(Window window) -{ - Atom actual; - int format; - unsigned long count, remaining; - unsigned char *data=0; - - 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); - 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? QT?"); - XConvertSelection(dpy, _XA_XdndSelection, atom_support, - _XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime); - } - 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 - +/* 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 +#include + +#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) +{ + XDeleteProperty(dpy, window, _XA_XdndAware); +} + +Bool wXDNDProcessSelection(XEvent * event) +{ + WScreen *scr = wScreenForWindow(event->xselection.requestor); + char *retain; + Atom ret_type; + int ret_format; + unsigned long ret_item; + unsigned long remain_byte; + char *delme; + XEvent xevent; + Window selowner = XGetSelectionOwner(dpy, _XA_XdndSelection); + WMArray *items; + + XGetWindowProperty(dpy, event->xselection.requestor, + _XA_WINDOWMAKER_XDNDEXCHANGE, + 0, 65536, True, atom_support, &ret_type, &ret_format, + &ret_item, &remain_byte, (unsigned char **)&delme); + if (delme) { + scr->xdestring = delme; + } + + /*send finished */ + 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->xselection.requestor; + XSendEvent(dpy, selowner, 0, 0, &xevent); + + /*process dropping */ + if (scr->xdestring) { + WMArrayIterator iter; + int length, str_size; + int total_size = 0; + char *tmp; + + items = WMCreateArray(4); + retain = wstrdup(scr->xdestring); + XFree(scr->xdestring); /* since xdestring was created by Xlib */ + + length = strlen(retain); + + /* search in string */ + while (length--) { + if (retain[length] == '\r') { /* useless char, nuke it */ + retain[length] = 0; + } + if (retain[length] == '\n') { + str_size = strlen(&retain[length + 1]); + if (str_size) { + WMAddToArray(items, wstrdup(&retain[length + 1])); + total_size += str_size + 3; /* reserve for " \"\"" */ + /* this is nonsense -- if (length) + WMAppendArray(items, WMCreateArray(1)); */ + } + retain[length] = 0; + } + } + /* final one */ + WMAddToArray(items, wstrdup(retain)); + total_size += strlen(retain) + 3; + wfree(retain); + + /* now pack new string */ + scr->xdestring = wmalloc(total_size); + scr->xdestring[0] = 0; /* empty string */ + WM_ETARETI_ARRAY(items, tmp, iter) { + if (!strncmp(tmp, "file:", 5)) { + /* add more 2 chars while removing 5 is harmless */ + strcat(scr->xdestring, " \""); + strcat(scr->xdestring, &tmp[5]); + strcat(scr->xdestring, "\""); + } else { + /* unsupport object, still need more " ? tell ]d */ + strcat(scr->xdestring, &tmp[5]); + } + wfree(tmp); + } + WMFreeArray(items); + wDockReceiveDNDDrop(scr, event); + /* + printf("free "); + puts(scr->xdestring); + */ + wfree(scr->xdestring); /* this xdestring is not from Xlib (no XFree) */ + } + + /* why doesn't this function return anything ? -Dan */ +} + +Bool isAwareXDND(Window window) +{ + Atom actual; + int format; + unsigned long count, remaining; + unsigned char *data = 0; + + 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); + WDock *dock; + int icon_pos, i; + + icon_pos = -1; + if ((dock = scr->dock) != NULL) { + for (i = 0; i < dock->max_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; i < dock->max_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? QT?"); + XConvertSelection(dpy, _XA_XdndSelection, atom_support, + _XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime); + } + 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