WINGs: Added 'const' attribute to function 'WMCreateHashTable'
[wmaker-crm.git] / WINGs / dragcommon.c
blobdb5e5f11da2ca5029af38f44b1ca0769b8fe9a30
2 #include "WINGsP.h"
4 #define XDND_SOURCE_VERSION(dragInfo) dragInfo->protocolVersion
5 #define XDND_DEST_INFO(dragInfo) dragInfo->destInfo
6 #define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView
8 static Bool _WindowExists;
10 Atom W_OperationToAction(WMScreen * scr, WMDragOperationType operation)
12 switch (operation) {
13 case WDOperationNone:
14 return None;
16 case WDOperationCopy:
17 return scr->xdndActionCopy;
19 case WDOperationMove:
20 return scr->xdndActionMove;
22 case WDOperationLink:
23 return scr->xdndActionLink;
25 case WDOperationAsk:
26 return scr->xdndActionAsk;
28 case WDOperationPrivate:
29 return scr->xdndActionPrivate;
31 default:
32 return None;
36 WMDragOperationType W_ActionToOperation(WMScreen * scr, Atom action)
38 if (action == scr->xdndActionCopy) {
39 return WDOperationCopy;
41 } else if (action == scr->xdndActionMove) {
42 return WDOperationMove;
44 } else if (action == scr->xdndActionLink) {
45 return WDOperationLink;
47 } else if (action == scr->xdndActionAsk) {
48 return WDOperationAsk;
50 } else if (action == scr->xdndActionPrivate) {
51 return WDOperationPrivate;
53 } else if (action == None) {
55 return WDOperationNone;
56 } else {
57 char *tmp = XGetAtomName(scr->display, action);
59 wwarning("unknown XDND action %s ", tmp);
60 XFree(tmp);
62 return WDOperationCopy;
66 static void freeDragOperationItem(void *item)
68 wfree(item);
71 WMArray *WMCreateDragOperationArray(int initialSize)
73 return WMCreateArrayWithDestructor(initialSize, freeDragOperationItem);
76 WMDragOperationItem *WMCreateDragOperationItem(WMDragOperationType type, char *text)
78 W_DragOperationItem *result = wmalloc(sizeof(W_DragOperationItem));
80 result->type = type;
81 result->text = text;
83 return (WMDragOperationItem *) result;
86 WMDragOperationType WMGetDragOperationItemType(WMDragOperationItem * item)
88 return ((W_DragOperationItem *) item)->type;
91 char *WMGetDragOperationItemText(WMDragOperationItem * item)
93 return ((W_DragOperationItem *) item)->text;
96 static int handleNoWindowXError(Display * dpy, XErrorEvent * errEvt)
98 /* Parameter not used, but tell the compiler that it is ok */
99 (void) dpy;
101 if (errEvt->error_code == BadWindow || errEvt->error_code == BadDrawable) {
102 _WindowExists = False;
103 return Success;
106 return errEvt->error_code;
109 static Bool windowExists(Display * dpy, Window win)
111 void *previousErrorHandler;
112 XWindowAttributes attr;
114 XSynchronize(dpy, True);
115 previousErrorHandler = XSetErrorHandler(handleNoWindowXError);
116 _WindowExists = True;
118 /* can generate BadDrawable or BadWindow */
119 XGetWindowAttributes(dpy, win, &attr);
121 XSetErrorHandler(previousErrorHandler);
122 XSynchronize(dpy, False);
123 return _WindowExists;
126 Bool
127 W_SendDnDClientMessage(Display * dpy, Window win, Atom message,
128 unsigned long data0,
129 unsigned long data1, unsigned long data2, unsigned long data3, unsigned long data4)
131 XEvent ev;
133 #ifdef XDND_DEBUG
134 char *msgName = XGetAtomName(dpy, message);
136 printf("sending message %s ... ", msgName);
137 XFree(msgName);
138 #endif
140 if (!windowExists(dpy, win)) {
141 wwarning("xdnd message target %lu does no longer exist.", win);
142 return False; /* message not sent */
145 ev.type = ClientMessage;
146 ev.xclient.message_type = message;
147 ev.xclient.format = 32;
148 ev.xclient.window = win;
149 ev.xclient.data.l[0] = data0;
150 ev.xclient.data.l[1] = data1;
151 ev.xclient.data.l[2] = data2;
152 ev.xclient.data.l[3] = data3;
153 ev.xclient.data.l[4] = data4;
155 XSendEvent(dpy, win, False, 0, &ev);
156 XFlush(dpy);
158 #ifdef XDND_DEBUG
159 printf("sent\n");
160 #endif
161 return True; /* message sent */
164 static void handleLeaveMessage(WMDraggingInfo * info)
166 if (XDND_DEST_INFO(info) != NULL) {
167 /* XDND_DEST_VIEW is never NULL (it's the xdnd aware view) */
168 wassertr(XDND_DEST_VIEW(info) != NULL);
169 if (XDND_DEST_VIEW(info)->dragDestinationProcs != NULL) {
170 XDND_DEST_VIEW(info)->dragDestinationProcs->concludeDragOperation(XDND_DEST_VIEW(info));
172 W_DragDestinationInfoClear(info);
176 void W_HandleDNDClientMessage(WMView * toplevel, XClientMessageEvent * event)
178 WMScreen *scr = W_VIEW_SCREEN(toplevel);
179 WMDraggingInfo *info = &scr->dragInfo;
180 Atom messageType = event->message_type;
182 #ifdef XDND_DEBUG
184 char *msgTypeName = XGetAtomName(scr->display, messageType);
186 if (msgTypeName != NULL)
187 printf("event type = %s\n", msgTypeName);
188 else
189 printf("pb with event type !\n");
191 #endif
193 /* Messages from destination to source */
194 if (messageType == scr->xdndStatusAtom || messageType == scr->xdndFinishedAtom) {
195 W_DragSourceStopTimer();
196 W_DragSourceStateHandler(info, event);
197 return;
200 /* Messages from source to destination */
201 if (messageType == scr->xdndEnterAtom) {
202 Bool positionSent = (XDND_DEST_INFO(info) != NULL);
204 W_DragDestinationStopTimer();
205 W_DragDestinationStoreEnterMsgInfo(info, toplevel, event);
207 /* Xdnd version 3 and up are not compatible with version 1 or 2 */
208 if (XDND_SOURCE_VERSION(info) > 2) {
210 if (positionSent) {
211 /* xdndPosition previously received on xdnd aware view */
212 W_DragDestinationStateHandler(info, event);
213 return;
214 } else {
215 W_DragDestinationStartTimer(info);
216 return;
218 } else {
219 wwarning("received dnd enter msg with unsupported version %i", XDND_SOURCE_VERSION(info));
220 W_DragDestinationCancelDropOnEnter(toplevel, info);
221 return;
225 if (messageType == scr->xdndPositionAtom) {
226 W_DragDestinationStopTimer();
227 W_DragDestinationStorePositionMsgInfo(info, toplevel, event);
228 W_DragDestinationStateHandler(info, event);
229 return;
232 if (messageType == scr->xdndSelectionAtom || messageType == scr->xdndDropAtom) {
233 W_DragDestinationStopTimer();
234 W_DragDestinationStateHandler(info, event);
235 return;
238 if (messageType == scr->xdndLeaveAtom) {
239 /* conclude drop operation, and clear dragging info */
240 W_DragDestinationStopTimer();
241 handleLeaveMessage(info);
245 /* called in destroyView (wview.c) */
246 void W_FreeViewXdndPart(WMView * view)
248 WMUnregisterViewDraggedTypes(view);
250 if (view->dragSourceProcs)
251 wfree(view->dragSourceProcs);
253 if (view->dragDestinationProcs)
254 wfree(view->dragDestinationProcs);
256 if (view->dragImage)
257 WMReleasePixmap(view->dragImage);