summaryrefslogtreecommitdiffstats
path: root/Gui/wm/wsxdnd.c
diff options
context:
space:
mode:
Diffstat (limited to 'Gui/wm/wsxdnd.c')
-rw-r--r--Gui/wm/wsxdnd.c205
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;
+}