1 /* Many part of code are ripped of an example from JX's site */
8 #include "WindowMaker.h"
14 #include "workspace.h"
18 #include <X11/Xatom.h>
21 #define XDND_VERSION 3L
27 Atom _XA_XdndPosition
;
29 Atom _XA_XdndActionCopy
;
30 Atom _XA_XdndSelection
;
31 Atom _XA_XdndFinished
;
32 Atom _XA_WINDOWMAKER_XDNDEXCHANGE
;
35 Atom _XA_MOTIF_DRAG_RECEIVER_INFO;
36 Atom _XA_MOTIF_DRAG_AND_DROP_MESSAGE;
41 void wXDNDInitializeAtoms()
44 _XA_XdndAware
= XInternAtom(dpy
, "XdndAware", False
);
45 _XA_XdndEnter
= XInternAtom(dpy
, "XdndEnter", False
);
46 _XA_XdndLeave
= XInternAtom(dpy
, "XdndLeave", False
);
47 _XA_XdndDrop
= XInternAtom(dpy
, "XdndDrop", False
);
48 _XA_XdndPosition
= XInternAtom(dpy
, "XdndPosition", False
);
49 _XA_XdndStatus
= XInternAtom(dpy
, "XdndStatus", False
);
50 _XA_XdndActionCopy
= XInternAtom(dpy
, "XdndActionCopy", False
);
51 _XA_XdndSelection
= XInternAtom(dpy
, "XdndSelection", False
);
52 _XA_XdndFinished
= XInternAtom(dpy
, "XdndFinished", False
);
54 _XA_WINDOWMAKER_XDNDEXCHANGE
= XInternAtom(dpy
, "_WINDOWMAKER_XDNDEXCHANGE", False
);
57 _XA_MOTIF_DRAG_RECEIVER_INFO = XInternAtom(dpy, "_MOTIF_DRAG_RECEIVER_INFO",False);
58 _XA_MOTIF_DRAG_AND_DROP_MESSAGE = XInternAtom(dpy, "_MOTIF_DRAG_AND_DROP_MESSAGE", False);
62 void wXDNDMakeAwareness(Window window
) {
63 long int xdnd_version
= 3;
65 MotifDragReceiverInfo info;
67 XChangeProperty (dpy
, window
, _XA_XdndAware
, XA_ATOM
,
68 32, PropModeAppend
, (char *)&xdnd_version
, 1);
71 info.byte_order = '\0';
72 info.protocol_version = 0;
73 info.protocol_style = XmDRAG_DYNAMIC;
74 info.proxy_window = 0;
75 info.num_drop_sites = 0;
76 info.total_size = sizeof(info);
78 XChangeProperty (dpy, window,
79 _XA_MOTIF_DRAG_RECEIVER_INFO,
80 _XA_MOTIF_DRAG_RECEIVER_INFO,
82 (unsigned char *)&info,
87 void wXDNDClearAwareness(Window window
) {
88 long int xdnd_version
= 3;
89 XDeleteProperty (dpy
, window
, _XA_XdndAware
);
93 wXDNDProcessSelection(XEvent
*event
)
95 WScreen
*scr
= wScreenForWindow(event
->xselection
.requestor
);
97 char *retain
= scr
->xdestring
;
100 unsigned long ret_item
;
101 unsigned long remain_byte
;
104 Window selowner
= XGetSelectionOwner(dpy
,_XA_XdndSelection
);
105 XGetWindowProperty(dpy
, event
->xselection
.requestor
,
106 _XA_WINDOWMAKER_XDNDEXCHANGE
,
107 0, 65536, True
, atom_support
, &ret_type
, &ret_format
,
108 &ret_item
, &remain_byte
, (unsigned char **)&delme
);
111 printf("get -%s-\n",delme);
113 scr
->xdestring
=delme
;
117 memset (&xevent
, 0, sizeof(xevent
));
118 xevent
.xany
.type
= ClientMessage
;
119 xevent
.xany
.display
= dpy
;
120 xevent
.xclient
.window
= selowner
;
121 xevent
.xclient
.message_type
= _XA_XdndFinished
;
122 xevent
.xclient
.format
= 32;
123 XDND_FINISHED_TARGET_WIN(&xevent
) = event
->xselection
.requestor
;
124 XSendEvent(dpy
, selowner
, 0, 0, &xevent
);
127 for (;retain
[0];retain
++) {
128 if (retain
[0] < 32) retain
[0] = 32;
129 if (!strncmp(retain
, "file:", 5)) {
131 for (i
=0;i
<5;retain
[i
++]=' ');
134 retain
= scr
->xdestring
;
136 if (!strncmp(scr
->xdestring
, "file:", 5))
139 wDockReceiveDNDDrop(scr
,event
);
142 scr
->xdestring
= NULL
;
147 isAwareXDND(Window window
)
151 unsigned long count
, remaining
;
152 unsigned char *data
=0;
155 if (!window
) return False
;
156 XGetWindowProperty (dpy
, window
, _XA_XdndAware
,
157 0, 0x8000000L
, False
, XA_ATOM
,
159 &count
, &remaining
, &data
);
160 if (actual
!= XA_ATOM
|| format
!= 32 || count
== 0 || !data
) {
171 acceptXDND(Window window
)
173 WScreen
*scr
= wScreenForWindow(window
);
174 WWindow
*wwin
= wWindowFor(window
);
179 if ((dock
= scr
->dock
)!=NULL
) {
180 for (i
=0; i
<dock
->max_icons
; i
++) {
181 if (dock
->icon_array
[i
]
182 && dock
->icon_array
[i
]->icon
->core
->window
==window
) {
188 if (icon_pos
<0 && (dock
= scr
->workspaces
[scr
->current_workspace
]->clip
)!=NULL
) {
189 for (i
=0; i
<dock
->max_icons
; i
++) {
190 if (dock
->icon_array
[i
]
191 && dock
->icon_array
[i
]->icon
->core
->window
==window
) {
197 if (icon_pos
<0) return False
;
198 if (!dock
) return False
;
199 if (isAwareXDND(dock
->icon_array
[icon_pos
]->icon
->icon_win
)) return False
;
201 if (dock
->icon_array
[icon_pos
]->dnd_command
!=NULL
) return True
;
207 wXDNDProcessClientMessage(XClientMessageEvent
*event
)
211 char * name
= XGetAtomName(dpy
, event
->message_type
);
213 printf("Get %s\n",name);
219 if (event->message_type == _XA_MOTIF_DRAG_AND_DROP_MESSAGE) {
220 printf("motif dnd msg %d\n",event->data.b[0]);
221 if (event->data.b[0] == XmDROP_START){
222 unsigned x_root, y_root, flags;
223 unsigned char reason;
224 unsigned long timestamp;
226 Window source_window;
227 MotifDragInitiatorInfo *initiator_info;
230 unsigned long ret_item;
231 unsigned long remain_byte;
233 reason = event->data.b[0];
234 flags = event->data.s[1];
235 timestamp = event->data.l[1];
236 x_root = event->data.s[4];
237 y_root = event->data.s[5];
238 atom = event->data.l[3];
239 source_window = event->data.l[4];
241 XGetWindowProperty(dpy, source_window, atom,
242 0, sizeof(*initiator_info), True, atom_support,
243 &ret_type, &ret_format,
244 &ret_item, &remain_byte, (unsigned char **)&initiator_info);
248 if (event
->message_type
== _XA_XdndEnter
) {
249 if ((event
->data
.l
[1] & 1) == 0){
250 atom_support
= event
->data
.l
[2];
253 else puts("enter more than 3 types");
256 } else if (event
->message_type
== _XA_XdndLeave
) {
258 } else if (event
->message_type
== _XA_XdndDrop
) {
259 if (event
->data
.l
[0] == XGetSelectionOwner(dpy
, _XA_XdndSelection
)){
260 XConvertSelection(dpy
, _XA_XdndSelection
, atom_support
,
261 _XA_WINDOWMAKER_XDNDEXCHANGE
, event
->window
, CurrentTime
);
264 else puts("wierd selection owner");
267 } else if (event
->message_type
== _XA_XdndPosition
) {
269 Window srcwin
= event
->data
.l
[0];
270 if (atom_support
!= XInternAtom(dpy
, "text/uri-list", False
)) {
274 memset (&xevent
, 0, sizeof(xevent
));
275 xevent
.xany
.type
= ClientMessage
;
276 xevent
.xany
.display
= dpy
;
277 xevent
.xclient
.window
= srcwin
;
278 xevent
.xclient
.message_type
= _XA_XdndStatus
;
279 xevent
.xclient
.format
= 32;
281 XDND_STATUS_TARGET_WIN (&xevent
) = event
->window
;
282 XDND_STATUS_WILL_ACCEPT_SET (&xevent
, acceptXDND(event
->window
));
283 XDND_STATUS_WANT_POSITION_SET(&xevent
, True
);
284 XDND_STATUS_RECT_SET(&xevent
, 0, 0, 1024,768);
285 XDND_STATUS_ACTION(&xevent
) = _XA_XdndActionCopy
;
287 XSendEvent(dpy
, srcwin
, 0, 0, &xevent
);