Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / dragcommon.c
blobfeb2e87a506bb85ac945794dcc0788be6aca81cb
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)
11 {
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;
33 }
34 }
36 WMDragOperationType W_ActionToOperation(WMScreen * scr, Atom action)
37 {
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;
63 }
64 }
66 static void freeDragOperationItem(void *item)
67 {
68 wfree(item);
69 }
71 WMArray *WMCreateDragOperationArray(int initialSize)
72 {
73 return WMCreateArrayWithDestructor(initialSize, freeDragOperationItem);
74 }
76 WMDragOperationItem *WMCreateDragOperationItem(WMDragOperationType type, char *text)
77 {
78 W_DragOperationItem *result = wmalloc(sizeof(W_DragOperationItem));
80 result->type = type;
81 result->text = text;
83 return (WMDragOperationItem *) result;
84 }
86 WMDragOperationType WMGetDragOperationItemType(WMDragOperationItem * item)
87 {
88 return ((W_DragOperationItem *) item)->type;
89 }
91 char *WMGetDragOperationItemText(WMDragOperationItem * item)
92 {
93 return ((W_DragOperationItem *) item)->text;
94 }
96 static int handleNoWindowXError(Display * dpy, XErrorEvent * errEvt)
97 {
98 if (errEvt->error_code == BadWindow || errEvt->error_code == BadDrawable) {
99 _WindowExists = False;
100 return Success;
103 return errEvt->error_code;
106 static Bool windowExists(Display * dpy, Window win)
108 void *previousErrorHandler;
109 XWindowAttributes attr;
111 XSynchronize(dpy, True);
112 previousErrorHandler = XSetErrorHandler(handleNoWindowXError);
113 _WindowExists = True;
115 /* can generate BadDrawable or BadWindow */
116 XGetWindowAttributes(dpy, win, &attr);
118 XSetErrorHandler(previousErrorHandler);
119 XSynchronize(dpy, False);
120 return _WindowExists;
123 Bool
124 W_SendDnDClientMessage(Display * dpy, Window win, Atom message,
125 unsigned long data0,
126 unsigned long data1, unsigned long data2, unsigned long data3, unsigned long data4)
128 XEvent ev;
130 #ifdef XDND_DEBUG
131 char *msgName = XGetAtomName(dpy, message);
133 printf("sending message %s ... ", msgName);
134 XFree(msgName);
135 #endif
137 if (!windowExists(dpy, win)) {
138 wwarning("xdnd message target %d does no longer exist.", win);
139 return False; /* message not sent */
142 ev.type = ClientMessage;
143 ev.xclient.message_type = message;
144 ev.xclient.format = 32;
145 ev.xclient.window = win;
146 ev.xclient.data.l[0] = data0;
147 ev.xclient.data.l[1] = data1;
148 ev.xclient.data.l[2] = data2;
149 ev.xclient.data.l[3] = data3;
150 ev.xclient.data.l[4] = data4;
152 XSendEvent(dpy, win, False, 0, &ev);
153 XFlush(dpy);
155 #ifdef XDND_DEBUG
156 printf("sent\n");
157 #endif
158 return True; /* message sent */
161 static void handleLeaveMessage(WMDraggingInfo * info)
163 if (XDND_DEST_INFO(info) != NULL) {
164 /* XDND_DEST_VIEW is never NULL (it's the xdnd aware view) */
165 wassertr(XDND_DEST_VIEW(info) != NULL);
166 if (XDND_DEST_VIEW(info)->dragDestinationProcs != NULL) {
167 XDND_DEST_VIEW(info)->dragDestinationProcs->concludeDragOperation(XDND_DEST_VIEW(info));
169 W_DragDestinationInfoClear(info);
173 void W_HandleDNDClientMessage(WMView * toplevel, XClientMessageEvent * event)
175 WMScreen *scr = W_VIEW_SCREEN(toplevel);
176 WMDraggingInfo *info = &scr->dragInfo;
177 Atom messageType = event->message_type;
179 #ifdef XDND_DEBUG
181 char *msgTypeName = XGetAtomName(scr->display, messageType);
183 if (msgTypeName != NULL)
184 printf("event type = %s\n", msgTypeName);
185 else
186 printf("pb with event type !\n");
188 #endif
190 /* Messages from destination to source */
191 if (messageType == scr->xdndStatusAtom || messageType == scr->xdndFinishedAtom) {
192 W_DragSourceStopTimer();
193 W_DragSourceStateHandler(info, event);
194 return;
197 /* Messages from source to destination */
198 if (messageType == scr->xdndEnterAtom) {
199 Bool positionSent = (XDND_DEST_INFO(info) != NULL);
201 W_DragDestinationStopTimer();
202 W_DragDestinationStoreEnterMsgInfo(info, toplevel, event);
204 /* Xdnd version 3 and up are not compatible with version 1 or 2 */
205 if (XDND_SOURCE_VERSION(info) > 2) {
207 if (positionSent) {
208 /* xdndPosition previously received on xdnd aware view */
209 W_DragDestinationStateHandler(info, event);
210 return;
211 } else {
212 W_DragDestinationStartTimer(info);
213 return;
215 } else {
216 wwarning("received dnd enter msg with unsupported version %i", XDND_SOURCE_VERSION(info));
217 W_DragDestinationCancelDropOnEnter(toplevel, info);
218 return;
222 if (messageType == scr->xdndPositionAtom) {
223 W_DragDestinationStopTimer();
224 W_DragDestinationStorePositionMsgInfo(info, toplevel, event);
225 W_DragDestinationStateHandler(info, event);
226 return;
229 if (messageType == scr->xdndSelectionAtom || messageType == scr->xdndDropAtom) {
230 W_DragDestinationStopTimer();
231 W_DragDestinationStateHandler(info, event);
232 return;
235 if (messageType == scr->xdndLeaveAtom) {
236 /* conclude drop operation, and clear dragging info */
237 W_DragDestinationStopTimer();
238 handleLeaveMessage(info);
242 /* called in destroyView (wview.c) */
243 void W_FreeViewXdndPart(WMView * view)
245 WMUnregisterViewDraggedTypes(view);
247 if (view->dragSourceProcs)
248 wfree(view->dragSourceProcs);
250 if (view->dragDestinationProcs)
251 wfree(view->dragDestinationProcs);
253 if (view->dragImage)
254 WMReleasePixmap(view->dragImage);