5 #define VERSION_INFO(dragInfo) dragInfo->protocolVersion
6 #define XDND_DEST_INFO(dragInfo) dragInfo->destInfo
7 #define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView
8 #define XDND_DEST_VIEW_STORED(dragInfo) ((dragInfo->destInfo) != NULL)\
9 && ((dragInfo->destInfo->destView) != NULL)
12 static Bool _WindowExists
;
16 W_OperationToAction(WMScreen
*scr
, WMDragOperationType operation
)
23 return scr
->xdndActionCopy
;
26 return scr
->xdndActionMove
;
29 return scr
->xdndActionLink
;
32 return scr
->xdndActionAsk
;
34 case WDOperationPrivate
:
35 return scr
->xdndActionPrivate
;
44 W_ActionToOperation(WMScreen
*scr
, Atom action
)
46 if (action
== scr
->xdndActionCopy
) {
47 return WDOperationCopy
;
49 } else if (action
== scr
->xdndActionMove
) {
50 return WDOperationMove
;
52 } else if (action
== scr
->xdndActionLink
) {
53 return WDOperationLink
;
55 } else if (action
== scr
->xdndActionAsk
) {
56 return WDOperationAsk
;
58 } else if (action
== scr
->xdndActionPrivate
) {
59 return WDOperationPrivate
;
61 } else if (action
== None
) {
63 return WDOperationNone
;
65 char *tmp
= XGetAtomName(scr
->display
, action
);
67 wwarning("unknown XDND action %s ", tmp
);
70 return WDOperationCopy
;
76 freeDragOperationItem(void* item
)
82 WMCreateDragOperationArray(int initialSize
)
84 return WMCreateArrayWithDestructor(initialSize
, freeDragOperationItem
);
89 WMCreateDragOperationItem(WMDragOperationType type
, char* text
)
91 W_DragOperationItem
*result
= wmalloc(sizeof(W_DragOperationItem
));
96 return (WMDragOperationItem
*) result
;
100 WMGetDragOperationItemType(WMDragOperationItem
* item
)
102 return ((W_DragOperationItem
*)item
)->type
;
107 WMGetDragOperationItemText(WMDragOperationItem
* item
)
109 return ((W_DragOperationItem
*)item
)->text
;
113 handleNoWindowXError(Display
*dpy
, XErrorEvent
*errEvt
)
115 if (errEvt
->error_code
== BadWindow
116 || errEvt
->error_code
== BadDrawable
) {
117 _WindowExists
= False
;
121 return errEvt
->error_code
;
126 windowExists(Display
*dpy
, Window win
)
128 void* previousErrorHandler
;
129 XWindowAttributes attr
;
131 XSynchronize(dpy
, True
);
132 previousErrorHandler
= XSetErrorHandler(handleNoWindowXError
);
133 _WindowExists
= True
;
135 /* can generate BadDrawable or BadWindow */
136 XGetWindowAttributes(dpy
, win
, &attr
);
138 XSetErrorHandler(previousErrorHandler
);
139 XSynchronize(dpy
, False
);
140 return _WindowExists
;
145 W_SendDnDClientMessage(Display
*dpy
, Window win
, Atom message
,
154 if (! windowExists(dpy
, win
)) {
155 wwarning("xdnd message target %d does no longer exist.", win
);
156 return False
; /* message not sent */
159 ev
.type
= ClientMessage
;
160 ev
.xclient
.message_type
= message
;
161 ev
.xclient
.format
= 32;
162 ev
.xclient
.window
= win
;
163 ev
.xclient
.data
.l
[0] = data0
;
164 ev
.xclient
.data
.l
[1] = data1
;
165 ev
.xclient
.data
.l
[2] = data2
;
166 ev
.xclient
.data
.l
[3] = data3
;
167 ev
.xclient
.data
.l
[4] = data4
;
170 XSendEvent(dpy
, win
, False
, 0, &ev
);
173 return True
; /* message sent */
178 handleLeaveMessage(WMDraggingInfo
*info
)
180 if (XDND_DEST_INFO(info
) != NULL
) {
181 if (XDND_DEST_VIEW(info
) != NULL
) {
182 XDND_DEST_VIEW(info
)->dragDestinationProcs
->concludeDragOperation(
183 XDND_DEST_VIEW(info
));
185 W_DragDestinationInfoClear(info
);
191 W_HandleDNDClientMessage(WMView
*toplevel
, XClientMessageEvent
*event
)
193 WMScreen
*scr
= W_VIEW_SCREEN(toplevel
);
194 WMDraggingInfo
*info
= &scr
->dragInfo
;
195 Atom messageType
= event
->message_type
;
199 char* msgTypeName
= XGetAtomName(scr
->display
, messageType
);
201 if (msgTypeName
!= NULL
)
202 printf("event type = %s\n", msgTypeName
);
204 printf("pb with event type !\n");
209 /* Messages from destination to source */
210 if (messageType
== scr
->xdndStatusAtom
211 || messageType
== scr
->xdndFinishedAtom
) {
212 W_DragSourceStopTimer();
213 W_DragSourceStateHandler(info
, event
);
217 /* Messages from source to destination */
218 if (messageType
== scr
->xdndEnterAtom
) {
219 W_DragDestinationStopTimer();
220 W_DragDestinationStoreEnterMsgInfo(info
, toplevel
, event
);
222 if (VERSION_INFO(info
) <= XDND_VERSION
) {
223 if (XDND_DEST_VIEW_STORED(info
)) {
224 /* xdndPosition previously received on xdnd aware view */
225 W_DragDestinationStateHandler(info
, event
);
228 W_DragDestinationStartTimer(info
);
232 wwarning("received dnd enter msg with unsupported version %i",
234 W_DragDestinationCancelDropOnEnter(toplevel
, info
);
239 if (messageType
== scr
->xdndPositionAtom
) {
240 W_DragDestinationStopTimer();
241 W_DragDestinationStorePositionMsgInfo(info
, toplevel
, event
);
242 W_DragDestinationStateHandler(info
, event
);
246 if (messageType
== scr
->xdndSelectionAtom
247 || messageType
== scr
->xdndDropAtom
) {
248 W_DragDestinationStopTimer();
249 W_DragDestinationStateHandler(info
, event
);
253 if (messageType
== scr
->xdndLeaveAtom
) {
254 /* conclude drop operation, and clear dragging info */
255 W_DragDestinationStopTimer();
256 handleLeaveMessage(info
);
261 /* called in destroyView (wview.c) */
263 W_FreeViewXdndPart(WMView
*view
)
265 WMUnregisterViewDraggedTypes(view
);
267 if (view
->dragSourceProcs
)
268 wfree(view
->dragSourceProcs
);
270 if (view
->dragDestinationProcs
)
271 wfree(view
->dragDestinationProcs
);
274 WMReleasePixmap(view
->dragImage
);