Added code to automatically convert Icon paths in WMWindowAttributes from
[wmaker-crm.git] / WINGs / dragcommon.c
blob61482bc93ebac896dbabab44a6d5f2d2f92b0460
3 #include "WINGsP.h"
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;
15 Atom
16 W_OperationToAction(WMScreen *scr, WMDragOperationType operation)
18 switch (operation) {
19 case WDOperationNone:
20 return None;
22 case WDOperationCopy:
23 return scr->xdndActionCopy;
25 case WDOperationMove:
26 return scr->xdndActionMove;
28 case WDOperationLink:
29 return scr->xdndActionLink;
31 case WDOperationAsk:
32 return scr->xdndActionAsk;
34 case WDOperationPrivate:
35 return scr->xdndActionPrivate;
37 default:
38 return None;
43 WMDragOperationType
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;
64 } else {
65 char *tmp = XGetAtomName(scr->display, action);
67 wwarning("unknown XDND action %s ", tmp);
68 XFree(tmp);
70 return WDOperationCopy;
75 static void
76 freeDragOperationItem(void* item)
78 wfree(item);
81 WMArray*
82 WMCreateDragOperationArray(int initialSize)
84 return WMCreateArrayWithDestructor(initialSize, freeDragOperationItem);
88 WMDragOperationItem*
89 WMCreateDragOperationItem(WMDragOperationType type, char* text)
91 W_DragOperationItem *result = wmalloc(sizeof(W_DragOperationItem));
93 result->type = type;
94 result->text = text;
96 return (WMDragOperationItem*) result;
99 WMDragOperationType
100 WMGetDragOperationItemType(WMDragOperationItem* item)
102 return ((W_DragOperationItem*)item)->type;
106 char*
107 WMGetDragOperationItemText(WMDragOperationItem* item)
109 return ((W_DragOperationItem*)item)->text;
112 static int
113 handleNoWindowXError(Display *dpy, XErrorEvent *errEvt)
115 if (errEvt->error_code == BadWindow
116 || errEvt->error_code == BadDrawable) {
117 _WindowExists = False;
118 return Success;
121 return errEvt->error_code;
125 static Bool
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;
144 Bool
145 W_SendDnDClientMessage(Display *dpy, Window win, Atom message,
146 unsigned long data0,
147 unsigned long data1,
148 unsigned long data2,
149 unsigned long data3,
150 unsigned long data4)
152 XEvent ev;
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);
171 XFlush(dpy);
173 return True; /* message sent */
177 static void
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);
190 void
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;
197 #ifdef XDND_DEBUG
199 char* msgTypeName = XGetAtomName(scr->display, messageType);
201 if (msgTypeName != NULL)
202 printf("event type = %s\n", msgTypeName);
203 else
204 printf("pb with event type !\n");
206 #endif
209 /* Messages from destination to source */
210 if (messageType == scr->xdndStatusAtom
211 || messageType == scr->xdndFinishedAtom) {
212 W_DragSourceStopTimer();
213 W_DragSourceStateHandler(info, event);
214 return;
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);
226 return;
227 } else {
228 W_DragDestinationStartTimer(info);
229 return;
231 } else {
232 wwarning("received dnd enter msg with unsupported version %i",
233 VERSION_INFO(info));
234 W_DragDestinationCancelDropOnEnter(toplevel, info);
235 return;
239 if (messageType == scr->xdndPositionAtom) {
240 W_DragDestinationStopTimer();
241 W_DragDestinationStorePositionMsgInfo(info, toplevel, event);
242 W_DragDestinationStateHandler(info, event);
243 return;
246 if (messageType == scr->xdndSelectionAtom
247 || messageType == scr->xdndDropAtom) {
248 W_DragDestinationStopTimer();
249 W_DragDestinationStateHandler(info, event);
250 return;
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) */
262 void
263 W_FreeViewXdndPart(WMView *view)
265 WMUnregisterViewDraggedTypes(view);
267 if (view->dragSourceProcs)
268 wfree(view->dragSourceProcs);
270 if (view->dragDestinationProcs)
271 wfree(view->dragDestinationProcs);
273 if (view->dragImage)
274 WMReleasePixmap(view->dragImage);