void WMScreenAbortDrag(W_Screen *screen) { if (!screen || !screen->dragInfo.sourceInfo) return; W_DragSourceInfo *source = screen->dragInfo.sourceInfo; W_DragSourceStopTimer(); // inform the other client if (source->destinationWindow) W_SendDnDClientMessage(screen->display, source->destinationWindow, screen->xdndLeaveAtom, WMViewXID(source->sourceView), 0, 0, 0, 0); WMDeleteSelectionHandler(source->sourceView, screen->xdndSelectionAtom, CurrentTime); wfree(source->selectionProcs); if (source->sourceView->dragSourceProcs->endedDrag) source->sourceView->dragSourceProcs->endedDrag(source->sourceView, &source->imageLocation, False); if (source->icon) XDestroyWindow(screen->display, source->icon); if (source->dragCursor != None) { XDefineCursor(screen->display, screen->rootWin, screen->defaultCursor); XFreeCursor(screen->display, source->dragCursor); } wfree(source); screen->dragInfo.sourceInfo = NULL; }
static void registerDescriptionList(WMScreen * scr, WMView * view, WMArray * operationArray) { char *text, *textListItem, *textList; int count = WMGetArrayItemCount(operationArray); int i; int size = 0; /* size of XA_STRING info */ for (i = 0; i < count; i++) { size += strlen(WMGetDragOperationItemText(WMGetFromArray(operationArray, i))) + 1 /* NULL */; } /* create text list */ textList = wmalloc(size); textListItem = textList; for (i = 0; i < count; i++) { text = WMGetDragOperationItemText(WMGetFromArray(operationArray, i)); wstrlcpy(textListItem, text, size); /* to next text offset */ textListItem = &(textListItem[strlen(textListItem) + 1]); } XChangeProperty(scr->display, WMViewXID(view), scr->xdndActionDescriptionAtom, XA_STRING, XDND_ACTION_DESCRIPTION_FORMAT, PropModeReplace, (unsigned char *)textList, size); }
/* send a DnD message to the destination window */ static Bool sendDnDClientMessage(WMDraggingInfo * info, Atom message, unsigned long data1, unsigned long data2, unsigned long data3, unsigned long data4) { Display *dpy = sourceScreen(info)->display; Window srcWin = WMViewXID(XDND_SOURCE_VIEW(info)); Window destWin = XDND_DEST_WIN(info); if (!W_SendDnDClientMessage(dpy, destWin, message, srcWin, data1, data2, data3, data4)) { /* drop failed */ recolorCursor(info, False); endDragImage(info, True); endDragProcess(info, False); return False; } return True; }
static void registerOperationList(WMScreen * scr, WMView * view, WMArray * operationArray) { Atom *actionList; WMDragOperationType operation; int count = WMGetArrayItemCount(operationArray); int i; actionList = wmalloc(sizeof(Atom) * count); for (i = 0; i < count; i++) { operation = WMGetDragOperationItemType(WMGetFromArray(operationArray, i)); actionList[i] = W_OperationToAction(scr, operation); } XChangeProperty(scr->display, WMViewXID(view), scr->xdndActionListAtom, XA_ATOM, XDND_PROPERTY_FORMAT, PropModeReplace, (unsigned char *)actionList, count); }
static void endDragImage(WMDraggingInfo * info, Bool slideBack) { WMView *view = XDND_SOURCE_VIEW(info); Display *dpy = W_VIEW_SCREEN(view)->display; if (slideBack) { WMPoint toLocation; Window foo; XTranslateCoordinates(W_VIEW_SCREEN(view)->display, WMViewXID(view), W_VIEW_SCREEN(view)->rootWin, 0, 0, &(toLocation.x), &(toLocation.y), &foo); slideWindow(dpy, XDND_DRAG_ICON(info), XDND_DRAG_ICON_POS(info).x, XDND_DRAG_ICON_POS(info).y, toLocation.x, toLocation.y); } XDestroyWindow(dpy, XDND_DRAG_ICON(info)); }
static void registerDropTypes(WMScreen * scr, WMView * view, WMDraggingInfo * info) { Atom *typeList; int i, count; typeList = getTypeAtomList(scr, view, &count); /* store the first 3 types */ for (i = 0; i < 3 && i < count; i++) XDND_3_TYPES(info)[i] = typeList[i]; for (; i < 3; i++) XDND_3_TYPES(info)[i] = None; /* store the entire type list */ XChangeProperty(scr->display, WMViewXID(view), scr->xdndTypeListAtom, XA_ATOM, XDND_PROPERTY_FORMAT, PropModeReplace, (unsigned char *)typeList, count); }
static void initDragImagePos(WMView * view, WMDraggingInfo * info, XEvent * event) { WMSize iconSize = WMGetPixmapSize(view->dragImage); WMSize viewSize = WMGetViewSize(view); WMPoint viewPos; Window foo; XTranslateCoordinates(W_VIEW_SCREEN(view)->display, WMViewXID(view), W_VIEW_SCREEN(view)->rootWin, 0, 0, &(viewPos.x), &(viewPos.y), &foo); /* set icon pos */ XDND_DRAG_ICON_POS(info).x = getInitialDragImageCoord(viewPos.x, event->xmotion.x_root, viewSize.width, iconSize.width); XDND_DRAG_ICON_POS(info).y = getInitialDragImageCoord(viewPos.y, event->xmotion.y_root, viewSize.height, iconSize.height); /* set mouse offset relative to icon */ XDND_MOUSE_OFFSET(info).x = event->xmotion.x_root - XDND_DRAG_ICON_POS(info).x; XDND_MOUSE_OFFSET(info).y = event->xmotion.y_root - XDND_DRAG_ICON_POS(info).y; }