Reindent
[mplayer/glamo.git] / gui / wm / wsxdnd.c
blobba2236f868780684398e92e983359afb293a9f53
1 /*
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.
21 #include <X11/Xlib.h>
22 #include "ws.h"
23 #include "wsxdnd.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
29 #include <X11/Xatom.h>
31 #include "mp_msg.h"
32 #include "help_mp.h"
34 #define XDND_VERSION 3L
36 Atom XA_XdndAware;
37 Atom XA_XdndEnter;
38 Atom XA_XdndLeave;
39 Atom XA_XdndDrop;
40 Atom XA_XdndPosition;
41 Atom XA_XdndStatus;
42 Atom XA_XdndActionCopy;
43 Atom XA_XdndSelection;
44 Atom XA_XdndFinished;
45 Atom XA_XdndTypeList;
47 Atom atom_support;
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
75 Bool
76 wsXDNDProcessSelection(wsTWindow* wnd, XEvent *event)
78 Atom ret_type;
79 int ret_format;
80 unsigned long ret_items;
81 unsigned long remain_byte;
82 char * delme;
83 XEvent xevent;
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);
92 /*send finished*/
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);
102 if (!delme){
103 mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_WS_DDNothing );
104 return False;
108 /* Handle dropped files */
109 char * retain = delme;
110 char * files[MAX_DND_FILES];
111 int num = 0;
113 while(retain < delme + ret_items) {
114 if (!strncmp(retain,"file:",5)) {
115 /* add more 2 chars while removing 5 is harmless */
116 retain+=5;
119 /* add the "retain" to the list */
120 files[num++]=retain;
123 /* now check for special characters */
125 int newone = 0;
126 while(retain < (delme + ret_items)){
127 if(*retain == '\r' || *retain == '\n'){
128 *retain=0;
129 newone = 1;
130 } else {
131 if (newone)
132 break;
134 retain++;
138 if (num >= MAX_DND_FILES)
139 break;
142 /* Handle the files */
143 if(wnd->DandDHandler){
144 wnd->DandDHandler(num,files);
148 free(delme);
149 return True;
152 Bool
153 wsXDNDProcessClientMessage(wsTWindow* wnd, XClientMessageEvent *event)
155 /* test */
157 char * name = XGetAtomName(wsDisplay, event->message_type);
158 printf("Got %s\n",name);
159 XFree(name);
162 if (event->message_type == XA_XdndEnter) {
163 Atom ok = XInternAtom(wsDisplay, "text/uri-list", False);
164 atom_support = None;
165 if ((event->data.l[1] & 1) == 0){
166 int index;
167 for(index = 0; index <= 2 ; index++){
168 if (event->data.l[2+index] == ok) {
169 atom_support = ok;
172 if (atom_support == None) {
173 mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_WS_NotAFile );
175 } else {
176 /* need to check the whole list here */
177 unsigned long ret_left = 1;
178 int offset = 0;
179 Atom* ret_buff;
180 Atom ret_type;
181 int ret_format;
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)){
193 XFree(ret_buff);
194 break;
196 /* now chek what we've got */
198 int i;
199 for(i=0; i<ret_items; i++){
200 if(ret_buff[i] == ok){
201 atom_support = ok;
202 break;
206 /* maybe next time ... */
207 XFree(ret_buff);
208 offset += 256;
211 return True;
214 if (event->message_type == XA_XdndLeave) {
215 return True;
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,
225 CurrentTime);
227 return True;
230 if (event->message_type == XA_XdndPosition) {
231 Window srcwin = event->data.l[0];
232 if (atom_support == None){
233 return True;
236 /* send response */
238 XEvent xevent;
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);
255 return True;
258 return False;