summaryrefslogtreecommitdiffstats
path: root/Gui/wm
diff options
context:
space:
mode:
authorpontscho <pontscho@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-08-11 13:12:38 +0000
committerpontscho <pontscho@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-08-11 13:12:38 +0000
commit418dbef6efa7efd9ccd76bb1925f5eeaf5008b3e (patch)
treea0dd4ff3367cf1da204f5fb41029b790fdeec357 /Gui/wm
parent0f7ec7d88544be01df6c6710f1ddb4a8df77c9d6 (diff)
downloadmpv-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')
-rw-r--r--Gui/wm/ws.c13
-rw-r--r--Gui/wm/ws.h4
-rw-r--r--Gui/wm/wsxdnd.c205
-rw-r--r--Gui/wm/wsxdnd.h53
4 files changed, 272 insertions, 3 deletions
diff --git a/Gui/wm/ws.c b/Gui/wm/ws.c
index f67a1fa108..e8128ffe7a 100644
--- a/Gui/wm/ws.c
+++ b/Gui/wm/ws.c
@@ -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 @@ if(mDisplay){
}
}
+/* enable DND atoms */
+wsXDNDInitialize();
+
{ /* on remote display XShm will be disabled - LGB */
char *dispname=DisplayString(wsDisplay);
int localdisp=1;
@@ -557,7 +561,10 @@ Bool wsEvents( Display * display,XEvent * Event,XPointer arg )
{ 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 @@ buttonreleased:
}
break;
+ case SelectionNotify:
+ /* Handle DandD */
+ wsXDNDProcessSelection(wsWindowList[l],Event);
+ break;
}
XFlush( wsDisplay );
XSync( wsDisplay,False );
diff --git a/Gui/wm/ws.h b/Gui/wm/ws.h
index 3b22de8978..332abdcbf1 100644
--- a/Gui/wm/ws.h
+++ b/Gui/wm/ws.h
@@ -100,7 +100,7 @@ typedef void (*wsTReSize)( unsigned int X,unsigned int Y,unsigned int width,un
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 @@ typedef struct
wsTIdle Idle;
wsTKeyHandler KeyHandler;
wsTMouseHandler MouseHandler;
- wsRemoteHandler RemoteHandler;
+ wsTDNDHandler DandDHandler;
int Alt;
int Shift;
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;
+}
diff --git a/Gui/wm/wsxdnd.h b/Gui/wm/wsxdnd.h
new file mode 100644
index 0000000000..8d88aeacdc
--- /dev/null
+++ b/Gui/wm/wsxdnd.h
@@ -0,0 +1,53 @@
+
+#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