[Mplayer-cvslog] CVS: main/Gui/wm wsxdnd.c,NONE,1.1 wsxdnd.h,NONE,1.1 ws.c,1.48,1.49 ws.h,1.19,1.20

Zoltan Ponekker pontscho at mplayerhq.hu
Sun Aug 11 15:12:41 CEST 2002


Update of /cvsroot/mplayer/main/Gui/wm
In directory mail:/var/tmp.root/cvs-serv32452/wm

Modified Files:
	ws.c ws.h 
Added Files:
	wsxdnd.c wsxdnd.h 
Log Message:
add xdnd support (from Gregory Kovriga <gkovriga at techunix.technion.ac.il>) and fix -subdelay bug

--- NEW FILE ---
/* 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;
}

--- NEW FILE ---

#ifndef _XDND_H_
#define _XDND_H_


void wsXDNDInitialize();
Bool wsXDNDProcessSelection(wsTWindow* wnd,XEvent *event);
Bool wsXDNDProcessClientMessage(wsTWindow* wnd, XClientMessageEvent *event);
void wsXDNDMakeAwareness(wsTWindow* window);
void wsXDNDClearAwareness(wsTWindow* window);

/* header was ripped from xdnd's example on its page */

#define XDND_THREE 3
#define XDND_ENTER_SOURCE_WIN(e)	((e)->xclient.data.l[0])
#define XDND_ENTER_THREE_TYPES(e)	(((e)->xclient.data.l[1] & 0x1UL) == 0)
#define XDND_ENTER_THREE_TYPES_SET(e,b)	(e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x1UL) | (((b) == 0) ? 0 : 0x1UL)
#define XDND_ENTER_VERSION(e)		((e)->xclient.data.l[1] >> 24)
#define XDND_ENTER_VERSION_SET(e,v)	(e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~(0xFF << 24)) | ((v) << 24)
#define XDND_ENTER_TYPE(e,i)		((e)->xclient.data.l[2 + i])	/* i => (0, 1, 2) */

/* XdndPosition */
#define XDND_POSITION_SOURCE_WIN(e)	((e)->xclient.data.l[0])
#define XDND_POSITION_ROOT_X(e)		((e)->xclient.data.l[2] >> 16)
#define XDND_POSITION_ROOT_Y(e)		((e)->xclient.data.l[2] & 0xFFFFUL)
#define XDND_POSITION_ROOT_SET(e,x,y)	(e)->xclient.data.l[2]  = ((x) << 16) | ((y) & 0xFFFFUL)
#define XDND_POSITION_TIME(e)		((e)->xclient.data.l[3])
#define XDND_POSITION_ACTION(e)		((e)->xclient.data.l[4])

/* XdndStatus */
#define XDND_STATUS_TARGET_WIN(e)	((e)->xclient.data.l[0])
#define XDND_STATUS_WILL_ACCEPT(e)	((e)->xclient.data.l[1] & 0x1L)
#define XDND_STATUS_WILL_ACCEPT_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x1UL) | (((b) == 0) ? 0 : 0x1UL)
#define XDND_STATUS_WANT_POSITION(e)	((e)->xclient.data.l[1] & 0x2UL)
#define XDND_STATUS_WANT_POSITION_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x2UL) | (((b) == 0) ? 0 : 0x2UL)
#define XDND_STATUS_RECT_X(e)		((e)->xclient.data.l[2] >> 16)
#define XDND_STATUS_RECT_Y(e)		((e)->xclient.data.l[2] & 0xFFFFL)
#define XDND_STATUS_RECT_WIDTH(e)	((e)->xclient.data.l[3] >> 16)
#define XDND_STATUS_RECT_HEIGHT(e)	((e)->xclient.data.l[3] & 0xFFFFL)
#define XDND_STATUS_RECT_SET(e,x,y,w,h)	{(e)->xclient.data.l[2] = ((x) << 16) | ((y) & 0xFFFFUL); (e)->xclient.data.l[3] = ((w) << 16) | ((h) & 0xFFFFUL); }
#define XDND_STATUS_ACTION(e)		((e)->xclient.data.l[4])

/* XdndLeave */
#define XDND_LEAVE_SOURCE_WIN(e)	((e)->xclient.data.l[0])

/* XdndDrop */
#define XDND_DROP_SOURCE_WIN(e)		((e)->xclient.data.l[0])
#define XDND_DROP_TIME(e)		((e)->xclient.data.l[2])

/* XdndFinished */
#define XDND_FINISHED_TARGET_WIN(e)	((e)->xclient.data.l[0])

#endif

Index: ws.c
===================================================================
RCS file: /cvsroot/mplayer/main/Gui/wm/ws.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- ws.c	25 Jul 2002 20:26:38 -0000	1.48
+++ ws.c	11 Aug 2002 13:12:38 -0000	1.49
@@ -21,6 +21,7 @@
 #include "../../config.h"
 #include "ws.h"
 #include "wsconv.h"
+#include "wsxdnd.h"
 #include "../../postproc/rgb2rgb.h"
 #include "../../mp_msg.h"
 #include "../../mplayer.h"
@@ -227,6 +228,9 @@
   }
 }
 
+/* enable DND atoms */
+wsXDNDInitialize();
+ 
 { /* on remote display XShm will be disabled - LGB */
  char *dispname=DisplayString(wsDisplay);
  int localdisp=1;
@@ -557,7 +561,10 @@
            { i=wsWindowFocusIn;  wsWindowList[l]->Focused=wsFocused; goto expose; }
           if ( Event->xclient.data.l[0] == wsWindowList[l]->AtomRolle )
            { mp_msg( MSGT_GPLAYER,MSGL_STATUS,"[ws] rolled.\n" ); }
-         }
+         } else {
+	   /* try to process DND events */
+	   wsXDNDProcessClientMessage(wsWindowList[l],&Event->xclient);
+	 }
         break;
 
    case MapNotify:   i=wsWindowMapped;   wsWindowList[l]->Mapped=wsMapped;   goto expose;
@@ -681,6 +688,10 @@
 	}
         break;
 
+   case SelectionNotify:
+     /* Handle DandD */
+     wsXDNDProcessSelection(wsWindowList[l],Event);
+     break;
   }
  XFlush( wsDisplay );
  XSync( wsDisplay,False );

Index: ws.h
===================================================================
RCS file: /cvsroot/mplayer/main/Gui/wm/ws.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- ws.h	25 Jul 2002 20:26:38 -0000	1.19
+++ ws.h	11 Aug 2002 13:12:38 -0000	1.20
@@ -100,7 +100,7 @@
 typedef   void (*wsTIdle)( void );
 typedef   void (*wsTKeyHandler)( int KeyCode,int Type,int Key );
 typedef   void (*wsTMouseHandler)( int Button,int X,int Y,int RX,int RY  );
-typedef   void (*wsRemoteHandler)( char * str );
+typedef   void (*wsTDNDHandler)( int num,char ** str );
 
 typedef struct
 {
@@ -128,7 +128,7 @@
  wsTIdle              Idle;
  wsTKeyHandler        KeyHandler;
  wsTMouseHandler      MouseHandler;
- wsRemoteHandler      RemoteHandler;
+ wsTDNDHandler        DandDHandler;
 
  int                  Alt;
  int                  Shift;




More information about the MPlayer-cvslog mailing list