Update Serbian translation from master branch
[wmaker-crm.git] / WINGs / dragcommon.c
blob35985503c90b45c8f056eec719bf009b57357acd
1 #include "wconfig.h"
3 #include "WINGsP.h"
5 #define XDND_SOURCE_VERSION(dragInfo) dragInfo->protocolVersion
6 #define XDND_DEST_INFO(dragInfo) dragInfo->destInfo
7 #define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView
9 static Bool _WindowExists;
11 Atom W_OperationToAction(WMScreen * scr, WMDragOperationType operation)
13 switch (operation) {
14 case WDOperationNone:
15 return None;
17 case WDOperationCopy:
18 return scr->xdndActionCopy;
20 case WDOperationMove:
21 return scr->xdndActionMove;
23 case WDOperationLink:
24 return scr->xdndActionLink;
26 case WDOperationAsk:
27 return scr->xdndActionAsk;
29 case WDOperationPrivate:
30 return scr->xdndActionPrivate;
32 default:
33 return None;
37 WMDragOperationType W_ActionToOperation(WMScreen * scr, Atom action)
39 if (action == scr->xdndActionCopy) {
40 return WDOperationCopy;
42 } else if (action == scr->xdndActionMove) {
43 return WDOperationMove;
45 } else if (action == scr->xdndActionLink) {
46 return WDOperationLink;
48 } else if (action == scr->xdndActionAsk) {
49 return WDOperationAsk;
51 } else if (action == scr->xdndActionPrivate) {
52 return WDOperationPrivate;
54 } else if (action == None) {
56 return WDOperationNone;
57 } else {
58 char *tmp = XGetAtomName(scr->display, action);
60 wwarning(_("unknown XDND action %s"), tmp);
61 XFree(tmp);
63 return WDOperationCopy;
67 static void freeDragOperationItem(void *item)
69 wfree(item);
72 WMArray *WMCreateDragOperationArray(int initialSize)
74 return WMCreateArrayWithDestructor(initialSize, freeDragOperationItem);
77 WMDragOperationItem *WMCreateDragOperationItem(WMDragOperationType type, char *text)
79 W_DragOperationItem *result = wmalloc(sizeof(W_DragOperationItem));
81 result->type = type;
82 result->text = text;
84 return (WMDragOperationItem *) result;
87 WMDragOperationType WMGetDragOperationItemType(WMDragOperationItem * item)
89 return ((W_DragOperationItem *) item)->type;
92 char *WMGetDragOperationItemText(WMDragOperationItem * item)
94 return ((W_DragOperationItem *) item)->text;
97 static int handleNoWindowXError(Display * dpy, XErrorEvent * errEvt)
99 /* Parameter not used, but tell the compiler that it is ok */
100 (void) dpy;
102 if (errEvt->error_code == BadWindow || errEvt->error_code == BadDrawable) {
103 _WindowExists = False;
104 return Success;
107 return errEvt->error_code;
110 static Bool windowExists(Display * dpy, Window win)
112 void *previousErrorHandler;
113 XWindowAttributes attr;
115 XSynchronize(dpy, True);
116 previousErrorHandler = XSetErrorHandler(handleNoWindowXError);
117 _WindowExists = True;
119 /* can generate BadDrawable or BadWindow */
120 XGetWindowAttributes(dpy, win, &attr);
122 XSetErrorHandler(previousErrorHandler);
123 XSynchronize(dpy, False);
124 return _WindowExists;
127 Bool
128 W_SendDnDClientMessage(Display * dpy, Window win, Atom message,
129 unsigned long data0,
130 unsigned long data1, unsigned long data2, unsigned long data3, unsigned long data4)
132 XEvent ev;
134 #ifdef XDND_DEBUG
135 char *msgName = XGetAtomName(dpy, message);
137 printf("sending message %s ... ", msgName);
138 XFree(msgName);
139 #endif
141 if (!windowExists(dpy, win)) {
142 wwarning(_("target %lu for XDND message no longer exists"), win);
143 return False; /* message not sent */
146 ev.type = ClientMessage;
147 ev.xclient.message_type = message;
148 ev.xclient.format = 32;
149 ev.xclient.window = win;
150 ev.xclient.data.l[0] = data0;
151 ev.xclient.data.l[1] = data1;
152 ev.xclient.data.l[2] = data2;
153 ev.xclient.data.l[3] = data3;
154 ev.xclient.data.l[4] = data4;
156 XSendEvent(dpy, win, False, 0, &ev);
157 XFlush(dpy);
159 #ifdef XDND_DEBUG
160 printf("sent\n");
161 #endif
162 return True; /* message sent */
165 static void handleLeaveMessage(WMDraggingInfo * info)
167 if (XDND_DEST_INFO(info) != NULL) {
168 /* XDND_DEST_VIEW is never NULL (it's the xdnd aware view) */
169 wassertr(XDND_DEST_VIEW(info) != NULL);
170 if (XDND_DEST_VIEW(info)->dragDestinationProcs != NULL) {
171 XDND_DEST_VIEW(info)->dragDestinationProcs->concludeDragOperation(XDND_DEST_VIEW(info));
173 W_DragDestinationInfoClear(info);
177 void W_HandleDNDClientMessage(WMView * toplevel, XClientMessageEvent * event)
179 WMScreen *scr = W_VIEW_SCREEN(toplevel);
180 WMDraggingInfo *info = &scr->dragInfo;
181 Atom messageType = event->message_type;
183 #ifdef XDND_DEBUG
185 char *msgTypeName = XGetAtomName(scr->display, messageType);
187 if (msgTypeName != NULL)
188 printf("event type = %s\n", msgTypeName);
189 else
190 printf("pb with event type !\n");
192 #endif
194 /* Messages from destination to source */
195 if (messageType == scr->xdndStatusAtom || messageType == scr->xdndFinishedAtom) {
196 W_DragSourceStopTimer();
197 W_DragSourceStateHandler(info, event);
198 return;
201 /* Messages from source to destination */
202 if (messageType == scr->xdndEnterAtom) {
203 Bool positionSent = (XDND_DEST_INFO(info) != NULL);
205 W_DragDestinationStopTimer();
206 W_DragDestinationStoreEnterMsgInfo(info, toplevel, event);
208 /* Xdnd version 3 and up are not compatible with version 1 or 2 */
209 if (XDND_SOURCE_VERSION(info) > 2) {
211 if (positionSent) {
212 /* xdndPosition previously received on xdnd aware view */
213 W_DragDestinationStateHandler(info, event);
214 return;
215 } else {
216 W_DragDestinationStartTimer(info);
217 return;
219 } else {
220 wwarning(_("unsupported version %i for XDND enter message"), XDND_SOURCE_VERSION(info));
221 W_DragDestinationCancelDropOnEnter(toplevel, info);
222 return;
226 if (messageType == scr->xdndPositionAtom) {
227 W_DragDestinationStopTimer();
228 W_DragDestinationStorePositionMsgInfo(info, toplevel, event);
229 W_DragDestinationStateHandler(info, event);
230 return;
233 if (messageType == scr->xdndSelectionAtom || messageType == scr->xdndDropAtom) {
234 W_DragDestinationStopTimer();
235 W_DragDestinationStateHandler(info, event);
236 return;
239 if (messageType == scr->xdndLeaveAtom) {
240 /* conclude drop operation, and clear dragging info */
241 W_DragDestinationStopTimer();
242 handleLeaveMessage(info);
246 /* called in destroyView (wview.c) */
247 void W_FreeViewXdndPart(WMView * view)
249 WMUnregisterViewDraggedTypes(view);
251 if (view->dragSourceProcs)
252 wfree(view->dragSourceProcs);
254 if (view->dragDestinationProcs)
255 wfree(view->dragDestinationProcs);
257 if (view->dragImage)
258 WMReleasePixmap(view->dragImage);