diff options
author | pontscho <pontscho@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-08-11 13:12:38 +0000 |
---|---|---|
committer | pontscho <pontscho@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-08-11 13:12:38 +0000 |
commit | 418dbef6efa7efd9ccd76bb1925f5eeaf5008b3e (patch) | |
tree | a0dd4ff3367cf1da204f5fb41029b790fdeec357 /Gui/wm/wsxdnd.c | |
parent | 0f7ec7d88544be01df6c6710f1ddb4a8df77c9d6 (diff) | |
download | mpv-418dbef6efa7efd9ccd76bb1925f5eeaf5008b3e.tar.bz2 mpv-418dbef6efa7efd9ccd76bb1925f5eeaf5008b3e.tar.xz |
add xdnd support (from Gregory Kovriga <gkovriga@techunix.technion.ac.il>) and fix -subdelay bug
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6968 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'Gui/wm/wsxdnd.c')
-rw-r--r-- | Gui/wm/wsxdnd.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/Gui/wm/wsxdnd.c b/Gui/wm/wsxdnd.c new file mode 100644 index 0000000000..90c2e95e97 --- /dev/null +++ b/Gui/wm/wsxdnd.c @@ -0,0 +1,205 @@ +/* Took WindowMaker implementation and adopted for MPlayer */ + + +#include <X11/Xlib.h> +#include "ws.h" +#include "wsxdnd.h" + +#include <stdlib.h> +#include <string.h> + +#include <X11/Xatom.h> + + +#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); +} + +#define MAX_DND_FILES 64 +Bool +wsXDNDProcessSelection(wsTWindow* wnd, XEvent *event) +{ + Atom ret_type; + int ret_format; + unsigned long ret_items; + 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_items, &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; + } + + { + /* Handle dropped files */ + char * retain = delme; + char * files[MAX_DND_FILES]; + int num = 0; + /* + printf("Got: %s\n",delme); + */ + while(retain < delme + ret_items) { + if (!strncmp(retain,"file:",5)) { + /* add more 2 chars while removing 5 is harmless */ + retain+=5; + } + + /* add the "retain" to the list */ + files[num++]=retain; + + + /* now check for special characters */ + { + int newone = 0; + while(retain < (delme + ret_items)){ + if(*retain == '\r' || *retain == '\n'){ + *retain=0; + newone = 1; + } else { + if (newone) + break; + } + retain++; + } + } + + if (num >= MAX_DND_FILES) + break; + } + + /* Handle the files */ + if(wnd->DandDHandler){ + wnd->DandDHandler(num,files); + } + } + + free(delme); +} + +Bool +wsXDNDProcessClientMessage(wsTWindow* wnd, XClientMessageEvent *event) +{ + /* test */ + /*{ + char * name = XGetAtomName(wsDisplay, event->message_type); + printf("Got %s\n",name); + XFree(name); + }*/ + + if (event->message_type == _XA_XdndEnter) { + Atom ok = XInternAtom(wsDisplay, "text/uri-list", False); + atom_support = None; + if ((event->data.l[1] & 1) == 0){ + int index; + for(index = 0; index <= 2 ; index++){ + if (event->data.l[2+index] == ok) { + atom_support = ok; + } + } + if (atom_support == None) { + printf("This doesn't seem as a file...\n"); + } + } else { + /* FIXME: need something else here */ + } + 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 == None){ + 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; +} |