2 * WindowMaker implementation adopted for MPlayer
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <X11/Xatom.h>
34 #define XDND_VERSION 3L
42 Atom XA_XdndActionCopy
;
43 Atom XA_XdndSelection
;
49 void wsXDNDInitialize(void)
52 XA_XdndAware
= XInternAtom(wsDisplay
, "XdndAware", False
);
53 XA_XdndEnter
= XInternAtom(wsDisplay
, "XdndEnter", False
);
54 XA_XdndLeave
= XInternAtom(wsDisplay
, "XdndLeave", False
);
55 XA_XdndDrop
= XInternAtom(wsDisplay
, "XdndDrop", False
);
56 XA_XdndPosition
= XInternAtom(wsDisplay
, "XdndPosition", False
);
57 XA_XdndStatus
= XInternAtom(wsDisplay
, "XdndStatus", False
);
58 XA_XdndActionCopy
= XInternAtom(wsDisplay
, "XdndActionCopy", False
);
59 XA_XdndSelection
= XInternAtom(wsDisplay
, "XdndSelection", False
);
60 XA_XdndFinished
= XInternAtom(wsDisplay
, "XdndFinished", False
);
61 XA_XdndTypeList
= XInternAtom(wsDisplay
, "XdndTypeList", False
);
64 void wsXDNDMakeAwareness(wsTWindow
* window
) {
65 long int xdnd_version
= XDND_VERSION
;
66 XChangeProperty (wsDisplay
, window
->WindowID
, XA_XdndAware
, XA_ATOM
,
67 32, PropModeAppend
, (char *)&xdnd_version
, 1);
70 void wsXDNDClearAwareness(wsTWindow
* window
) {
71 XDeleteProperty (wsDisplay
, window
->WindowID
, XA_XdndAware
);
74 #define MAX_DND_FILES 64
76 wsXDNDProcessSelection(wsTWindow
* wnd
, XEvent
*event
)
80 unsigned long ret_items
;
81 unsigned long remain_byte
;
85 Window selowner
= XGetSelectionOwner(wsDisplay
,XA_XdndSelection
);
87 XGetWindowProperty(wsDisplay
, event
->xselection
.requestor
,
88 event
->xselection
.property
,
89 0, 65536, True
, atom_support
, &ret_type
, &ret_format
,
90 &ret_items
, &remain_byte
, (unsigned char **)&delme
);
93 memset (&xevent
, 0, sizeof(xevent
));
94 xevent
.xany
.type
= ClientMessage
;
95 xevent
.xany
.display
= wsDisplay
;
96 xevent
.xclient
.window
= selowner
;
97 xevent
.xclient
.message_type
= XA_XdndFinished
;
98 xevent
.xclient
.format
= 32;
99 XDND_FINISHED_TARGET_WIN(&xevent
) = wnd
->WindowID
;
100 XSendEvent(wsDisplay
, selowner
, 0, 0, &xevent
);
103 mp_msg( MSGT_GPLAYER
,MSGL_WARN
,MSGTR_WS_DDNothing
);
108 /* Handle dropped files */
109 char * retain
= delme
;
110 char * files
[MAX_DND_FILES
];
113 while(retain
< delme
+ ret_items
) {
114 if (!strncmp(retain
,"file:",5)) {
115 /* add more 2 chars while removing 5 is harmless */
119 /* add the "retain" to the list */
123 /* now check for special characters */
126 while(retain
< (delme
+ ret_items
)){
127 if(*retain
== '\r' || *retain
== '\n'){
138 if (num
>= MAX_DND_FILES
)
142 /* Handle the files */
143 if(wnd
->DandDHandler
){
144 wnd
->DandDHandler(num
,files
);
153 wsXDNDProcessClientMessage(wsTWindow
* wnd
, XClientMessageEvent
*event
)
157 char * name = XGetAtomName(wsDisplay, event->message_type);
158 printf("Got %s\n",name);
162 if (event
->message_type
== XA_XdndEnter
) {
163 Atom ok
= XInternAtom(wsDisplay
, "text/uri-list", False
);
165 if ((event
->data
.l
[1] & 1) == 0){
167 for(index
= 0; index
<= 2 ; index
++){
168 if (event
->data
.l
[2+index
] == ok
) {
172 if (atom_support
== None
) {
173 mp_msg( MSGT_GPLAYER
,MSGL_WARN
,MSGTR_WS_NotAFile
);
176 /* need to check the whole list here */
177 unsigned long ret_left
= 1;
182 unsigned long ret_items
;
184 /* while there is data left...*/
185 while(ret_left
&& atom_support
== None
){
186 XGetWindowProperty(wsDisplay
,event
->data
.l
[0],XA_XdndTypeList
,
187 offset
,256,False
,XA_ATOM
,&ret_type
,
188 &ret_format
,&ret_items
,&ret_left
,
189 (unsigned char**)&ret_buff
);
191 /* sanity checks...*/
192 if(ret_buff
== NULL
|| ret_type
!= XA_ATOM
|| ret_format
!= 8*sizeof(Atom
)){
196 /* now chek what we've got */
199 for(i
=0; i
<ret_items
; i
++){
200 if(ret_buff
[i
] == ok
){
206 /* maybe next time ... */
214 if (event
->message_type
== XA_XdndLeave
) {
218 if (event
->message_type
== XA_XdndDrop
) {
219 if (event
->data
.l
[0] != XGetSelectionOwner(wsDisplay
, XA_XdndSelection
)){
220 puts("Wierd selection owner... QT?");
222 if (atom_support
!= None
) {
223 XConvertSelection(wsDisplay
, XA_XdndSelection
, atom_support
,
224 XA_XdndSelection
, event
->window
,
230 if (event
->message_type
== XA_XdndPosition
) {
231 Window srcwin
= event
->data
.l
[0];
232 if (atom_support
== None
){
239 memset (&xevent
, 0, sizeof(xevent
));
240 xevent
.xany
.type
= ClientMessage
;
241 xevent
.xany
.display
= wsDisplay
;
242 xevent
.xclient
.window
= srcwin
;
243 xevent
.xclient
.message_type
= XA_XdndStatus
;
244 xevent
.xclient
.format
= 32;
246 XDND_STATUS_TARGET_WIN (&xevent
) = event
->window
;
247 XDND_STATUS_WILL_ACCEPT_SET (&xevent
, True
);
248 XDND_STATUS_WANT_POSITION_SET(&xevent
, True
);
249 /* actually need smth real here */
250 XDND_STATUS_RECT_SET(&xevent
, 0, 0, 1024,768);
251 XDND_STATUS_ACTION(&xevent
) = XA_XdndActionCopy
;
253 XSendEvent(wsDisplay
, srcwin
, 0, 0, &xevent
);