/* Took WindowMaker implementation and adopted for MPlayer */ #include #include "ws.h" #include "wsxdnd.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 atom_support; void wsXDNDInitialize() { _XA_XdndAware = XInternAtom(wsDisplay, "XdndAware", False); _XA_XdndEnter = XInternAtom(wsDisplay, "XdndEnter", False); _XA_XdndLeave = XInternAtom(wsDisplay, "XdndLeave", False); _XA_XdndDrop = XInternAtom(wsDisplay, "XdndDrop", False); _XA_XdndPosition = XInternAtom(wsDisplay, "XdndPosition", False); _XA_XdndStatus = XInternAtom(wsDisplay, "XdndStatus", False); _XA_XdndActionCopy = XInternAtom(wsDisplay, "XdndActionCopy", False); _XA_XdndSelection = XInternAtom(wsDisplay, "XdndSelection", False); _XA_XdndFinished = XInternAtom(wsDisplay, "XdndFinished", False); } void wsXDNDMakeAwareness(wsTWindow* window) { long int xdnd_version = XDND_VERSION; XChangeProperty (wsDisplay, window->WindowID, _XA_XdndAware, XA_ATOM, 32, PropModeAppend, (char *)&xdnd_version, 1); } void wsXDNDClearAwareness(wsTWindow* window) { XDeleteProperty (wsDisplay, window->WindowID, _XA_XdndAware); } Bool wsXDNDProcessSelection(wsTWindow* wnd, XEvent *event) { char *retain; Atom ret_type; int ret_format; unsigned long ret_item; unsigned long remain_byte; char * delme; XEvent xevent; Window selowner = XGetSelectionOwner(wsDisplay,_XA_XdndSelection); XGetWindowProperty(wsDisplay, event->xselection.requestor, event->xselection.property, 0, 65536, True, atom_support, &ret_type, &ret_format, &ret_item, &remain_byte, (unsigned char **)&delme); /*send finished*/ memset (&xevent, 0, sizeof(xevent)); xevent.xany.type = ClientMessage; xevent.xany.display = wsDisplay; xevent.xclient.window = selowner; xevent.xclient.message_type = _XA_XdndFinished; xevent.xclient.format = 32; XDND_FINISHED_TARGET_WIN(&xevent) = wnd->WindowID; XSendEvent(wsDisplay, selowner, 0, 0, &xevent); if (!delme){ printf("D&D: Nothing returned!\n"); return False; } if (!strncmp(delme,"file:",5)) { /* add more 2 chars while removing 5 is harmless */ retain = &delme[5]; } else { retain = delme; } /* now check for special characters */ /* so we will take only the first item */ { int i = 0; while(retain[i]){ if(retain[i] == '\r' || retain[i] == '\n'){ retain[i]=0; } ++i; } } /* Handle the "retain" as if it is a file */ if(wnd->DandDHandler){ wnd->DandDHandler(retain); } free(delme); } Bool wsXDNDProcessClientMessage(wsTWindow* wnd, XClientMessageEvent *event) { /* test */ /*{ char * name = XGetAtomName(wsDisplay, event->message_type); printf("Get %s\n",name); XFree(name); }*/ if (event->message_type == _XA_XdndEnter) { if ((event->data.l[1] & 1) == 0){ atom_support = event->data.l[2]; } else { /* FIXME: need something else here */ /*atom_support = XInternAtom(wsDisplay,"text/uri-list",False);*/ atom_support = None; } return True; } if (event->message_type == _XA_XdndLeave) { return True; } if (event->message_type == _XA_XdndDrop) { if (event->data.l[0] != XGetSelectionOwner(wsDisplay, _XA_XdndSelection)){ puts("wierd selection owner? QT?"); } if (atom_support != None) { XConvertSelection(wsDisplay, _XA_XdndSelection, atom_support, _XA_XdndSelection, event->window, CurrentTime); } return True; } if (event->message_type == _XA_XdndPosition) { Window srcwin = event->data.l[0]; if (atom_support != XInternAtom(wsDisplay, "text/uri-list", False)) { return True; } /* send response */ { XEvent xevent; memset (&xevent, 0, sizeof(xevent)); xevent.xany.type = ClientMessage; xevent.xany.display = wsDisplay; 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, True); XDND_STATUS_WANT_POSITION_SET(&xevent, True); /* actually need smth real here */ XDND_STATUS_RECT_SET(&xevent, 0, 0, 1024,768); XDND_STATUS_ACTION(&xevent) = _XA_XdndActionCopy; XSendEvent(wsDisplay, srcwin, 0, 0, &xevent); } return True; } return False; }