1 /* #include <X11/Xatom.h> */
4 #define VERSION_INFO(dragInfo) dragInfo->protocolVersion
5 #define XDND_DEST_INFO(dragInfo) dragInfo->destInfo
6 #define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView
7 #define XDND_DEST_VIEW_STORED(dragInfo) ((dragInfo->destInfo) != NULL)\
8 && ((dragInfo->destInfo->destView) != NULL)
11 static Bool _WindowExists
;
15 W_OperationToAction(WMScreen
*scr
, WMDragOperationType operation
)
22 return scr
->xdndActionCopy
;
25 return scr
->xdndActionMove
;
28 return scr
->xdndActionLink
;
31 return scr
->xdndActionAsk
;
33 case WDOperationPrivate
:
34 return scr
->xdndActionPrivate
;
43 W_ActionToOperation(WMScreen
*scr
, Atom action
)
45 if (action
== scr
->xdndActionCopy
) {
46 return WDOperationCopy
;
48 } else if (action
== scr
->xdndActionMove
) {
49 return WDOperationMove
;
51 } else if (action
== scr
->xdndActionLink
) {
52 return WDOperationLink
;
54 } else if (action
== scr
->xdndActionAsk
) {
55 return WDOperationAsk
;
57 } else if (action
== scr
->xdndActionPrivate
) {
58 return WDOperationPrivate
;
60 } else if (action
== None
) {
62 return WDOperationNone
;
64 char *tmp
= XGetAtomName(scr
->display
, action
);
66 wwarning("unknown XDND action %s ", tmp
);
69 return WDOperationCopy
;
75 freeDragOperationItem(void* item
)
81 WMCreateDragOperationArray(int initialSize
)
83 return WMCreateArrayWithDestructor(initialSize
, freeDragOperationItem
);
88 WMCreateDragOperationItem(WMDragOperationType type
, char* text
)
90 W_DragOperationItem
*result
= wmalloc(sizeof(W_DragOperationItem
));
95 return (WMDragOperationItem
*) result
;
99 WMGetDragOperationItemType(WMDragOperationItem
* item
)
101 return ((W_DragOperationItem
*)item
)->type
;
106 WMGetDragOperationItemText(WMDragOperationItem
* item
)
108 return ((W_DragOperationItem
*)item
)->text
;
112 handleNoWindowXError(Display
*dpy
, XErrorEvent
*errEvt
)
114 if (errEvt
->error_code
== BadWindow
115 || errEvt
->error_code
== BadDrawable
) {
116 _WindowExists
= False
;
120 return errEvt
->error_code
;
125 windowExists(Display
*dpy
, Window win
)
127 void* previousErrorHandler
;
128 XWindowAttributes attr
;
130 XSynchronize(dpy
, True
);
131 previousErrorHandler
= XSetErrorHandler(handleNoWindowXError
);
132 _WindowExists
= True
;
134 /* can generate BadDrawable or BadWindow */
135 XGetWindowAttributes(dpy
, win
, &attr
);
137 XSetErrorHandler(previousErrorHandler
);
138 XSynchronize(dpy
, False
);
139 return _WindowExists
;
144 W_SendDnDClientMessage(Display
*dpy
, Window win
, Atom message
,
153 if (! windowExists(dpy
, win
)) {
154 wwarning("xdnd message target %d does no longer exist.", win
);
155 return False
; /* message not sent */
158 ev
.type
= ClientMessage
;
159 ev
.xclient
.message_type
= message
;
160 ev
.xclient
.format
= 32;
161 ev
.xclient
.window
= win
;
162 ev
.xclient
.data
.l
[0] = data0
;
163 ev
.xclient
.data
.l
[1] = data1
;
164 ev
.xclient
.data
.l
[2] = data2
;
165 ev
.xclient
.data
.l
[3] = data3
;
166 ev
.xclient
.data
.l
[4] = data4
;
169 XSendEvent(dpy
, win
, False
, 0, &ev
);
172 return True
; /* message sent */
177 handleLeaveMessage(WMDraggingInfo
*info
)
179 if (XDND_DEST_INFO(info
) != NULL
) {
180 if (XDND_DEST_VIEW(info
) != NULL
) {
181 XDND_DEST_VIEW(info
)->dragDestinationProcs
->concludeDragOperation(
182 XDND_DEST_VIEW(info
));
184 W_DragDestinationInfoClear(info
);
190 W_HandleDNDClientMessage(WMView
*toplevel
, XClientMessageEvent
*event
)
192 WMScreen
*scr
= W_VIEW_SCREEN(toplevel
);
193 WMDraggingInfo
*info
= &scr
->dragInfo
;
194 Atom messageType
= event
->message_type
;
198 char* msgTypeName
= XGetAtomName(scr
->display
, messageType
);
200 if (msgTypeName
!= NULL
)
201 printf("event type = %s\n", msgTypeName
);
203 printf("pb with event type !\n");
208 /* Messages from destination to source */
209 if (messageType
== scr
->xdndStatusAtom
210 || messageType
== scr
->xdndFinishedAtom
) {
211 W_DragSourceStopTimer();
212 W_DragSourceStateHandler(info
, event
);
216 /* Messages from source to destination */
217 if (messageType
== scr
->xdndEnterAtom
) {
218 W_DragDestinationStopTimer();
219 W_DragDestinationStoreEnterMsgInfo(info
, toplevel
, event
);
221 if (VERSION_INFO(info
) <= XDND_VERSION
) {
222 if (XDND_DEST_VIEW_STORED(info
)) {
223 /* xdndPosition previously received on xdnd aware view */
224 W_DragDestinationStateHandler(info
, event
);
227 W_DragDestinationStartTimer(info
);
231 wwarning("received dnd enter msg with unsupported version %i",
233 W_DragDestinationCancelDropOnEnter(toplevel
, info
);
238 if (messageType
== scr
->xdndPositionAtom
) {
239 W_DragDestinationStopTimer();
240 W_DragDestinationStorePositionMsgInfo(info
, toplevel
, event
);
241 W_DragDestinationStateHandler(info
, event
);
245 if (messageType
== scr
->xdndSelectionAtom
246 || messageType
== scr
->xdndDropAtom
) {
247 W_DragDestinationStopTimer();
248 W_DragDestinationStateHandler(info
, event
);
252 if (messageType
== scr
->xdndLeaveAtom
) {
253 /* conclude drop operation, and clear dragging info */
254 W_DragDestinationStopTimer();
255 handleLeaveMessage(info
);
260 /* called in destroyView (wview.c) */
262 W_FreeViewXdndPart(WMView
*view
)
264 WMUnregisterViewDraggedTypes(view
);
266 if (view
->dragSourceProcs
)
267 wfree(view
->dragSourceProcs
);
269 if (view
->dragDestinationProcs
)
270 wfree(view
->dragDestinationProcs
);
273 WMReleasePixmap(view
->dragImage
);