1
/* Took WindowMaker implementation and adopted for MPlayer */
12
#include <X11/Xatom.h>
14
#include "../mp_msg.h"
15
#include "../help_mp.h"
17
#define XDND_VERSION 3L
23
Atom _XA_XdndPosition;
25
Atom _XA_XdndActionCopy;
26
Atom _XA_XdndSelection;
27
Atom _XA_XdndFinished;
28
Atom _XA_XdndTypeList;
32
void wsXDNDInitialize()
35
_XA_XdndAware = XInternAtom(wsDisplay, "XdndAware", False);
36
_XA_XdndEnter = XInternAtom(wsDisplay, "XdndEnter", False);
37
_XA_XdndLeave = XInternAtom(wsDisplay, "XdndLeave", False);
38
_XA_XdndDrop = XInternAtom(wsDisplay, "XdndDrop", False);
39
_XA_XdndPosition = XInternAtom(wsDisplay, "XdndPosition", False);
40
_XA_XdndStatus = XInternAtom(wsDisplay, "XdndStatus", False);
41
_XA_XdndActionCopy = XInternAtom(wsDisplay, "XdndActionCopy", False);
42
_XA_XdndSelection = XInternAtom(wsDisplay, "XdndSelection", False);
43
_XA_XdndFinished = XInternAtom(wsDisplay, "XdndFinished", False);
44
_XA_XdndTypeList = XInternAtom(wsDisplay, "XdndTypeList", False);
47
void wsXDNDMakeAwareness(wsTWindow* window) {
48
long int xdnd_version = XDND_VERSION;
49
XChangeProperty (wsDisplay, window->WindowID, _XA_XdndAware, XA_ATOM,
50
32, PropModeAppend, (char *)&xdnd_version, 1);
53
void wsXDNDClearAwareness(wsTWindow* window) {
54
XDeleteProperty (wsDisplay, window->WindowID, _XA_XdndAware);
57
#define MAX_DND_FILES 64
59
wsXDNDProcessSelection(wsTWindow* wnd, XEvent *event)
63
unsigned long ret_items;
64
unsigned long remain_byte;
68
Window selowner = XGetSelectionOwner(wsDisplay,_XA_XdndSelection);
70
XGetWindowProperty(wsDisplay, event->xselection.requestor,
71
event->xselection.property,
72
0, 65536, True, atom_support, &ret_type, &ret_format,
73
&ret_items, &remain_byte, (unsigned char **)&delme);
76
memset (&xevent, 0, sizeof(xevent));
77
xevent.xany.type = ClientMessage;
78
xevent.xany.display = wsDisplay;
79
xevent.xclient.window = selowner;
80
xevent.xclient.message_type = _XA_XdndFinished;
81
xevent.xclient.format = 32;
82
XDND_FINISHED_TARGET_WIN(&xevent) = wnd->WindowID;
83
XSendEvent(wsDisplay, selowner, 0, 0, &xevent);
86
mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_WS_DDNothing );
91
/* Handle dropped files */
92
char * retain = delme;
93
char * files[MAX_DND_FILES];
96
while(retain < delme + ret_items) {
97
if (!strncmp(retain,"file:",5)) {
98
/* add more 2 chars while removing 5 is harmless */
102
/* add the "retain" to the list */
106
/* now check for special characters */
109
while(retain < (delme + ret_items)){
110
if(*retain == '\r' || *retain == '\n'){
121
if (num >= MAX_DND_FILES)
125
/* Handle the files */
126
if(wnd->DandDHandler){
127
wnd->DandDHandler(num-1,files);
136
wsXDNDProcessClientMessage(wsTWindow* wnd, XClientMessageEvent *event)
140
char * name = XGetAtomName(wsDisplay, event->message_type);
141
printf("Got %s\n",name);
145
if (event->message_type == _XA_XdndEnter) {
146
Atom ok = XInternAtom(wsDisplay, "text/uri-list", False);
148
if ((event->data.l[1] & 1) == 0){
150
for(index = 0; index <= 2 ; index++){
151
if (event->data.l[2+index] == ok) {
155
if (atom_support == None) {
156
mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_WS_NotAFile );
159
/* need to check the whole list here */
160
unsigned long ret_left = 1;
165
unsigned long ret_items;
167
/* while there is data left...*/
168
while(ret_left && atom_support == None){
169
XGetWindowProperty(wsDisplay,event->data.l[0],_XA_XdndTypeList,
170
offset,256,False,XA_ATOM,&ret_type,
171
&ret_format,&ret_items,&ret_left,
172
(unsigned char**)&ret_buff);
174
/* sanity checks...*/
175
if(ret_buff == NULL || ret_type != XA_ATOM || ret_format != 8*sizeof(Atom)){
179
/* now chek what we've got */
182
for(i=0; i<ret_items; i++){
183
if(ret_buff[i] == ok){
189
/* maybe next time ... */
197
if (event->message_type == _XA_XdndLeave) {
201
if (event->message_type == _XA_XdndDrop) {
202
if (event->data.l[0] != XGetSelectionOwner(wsDisplay, _XA_XdndSelection)){
203
puts("Wierd selection owner... QT?");
205
if (atom_support != None) {
206
XConvertSelection(wsDisplay, _XA_XdndSelection, atom_support,
207
_XA_XdndSelection, event->window,
213
if (event->message_type == _XA_XdndPosition) {
214
Window srcwin = event->data.l[0];
215
if (atom_support == None){
222
memset (&xevent, 0, sizeof(xevent));
223
xevent.xany.type = ClientMessage;
224
xevent.xany.display = wsDisplay;
225
xevent.xclient.window = srcwin;
226
xevent.xclient.message_type = _XA_XdndStatus;
227
xevent.xclient.format = 32;
229
XDND_STATUS_TARGET_WIN (&xevent) = event->window;
230
XDND_STATUS_WILL_ACCEPT_SET (&xevent, True);
231
XDND_STATUS_WANT_POSITION_SET(&xevent, True);
232
/* actually need smth real here */
233
XDND_STATUS_RECT_SET(&xevent, 0, 0, 1024,768);
234
XDND_STATUS_ACTION(&xevent) = _XA_XdndActionCopy;
236
XSendEvent(wsDisplay, srcwin, 0, 0, &xevent);