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
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@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;
participants (1)
-
Zoltan Ponekker