diff Gui/wm/wsxdnd.c @ 6967:0fa27966ac47

add xdnd support (from Gregory Kovriga <gkovriga@techunix.technion.ac.il>) and fix -subdelay bug
author pontscho
date Sun, 11 Aug 2002 13:12:38 +0000
parents
children 7242f1840f8d
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Gui/wm/wsxdnd.c	Sun Aug 11 13:12:38 2002 +0000
@@ -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;
+}