123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: DndDrag.c /main/5 1996/09/27 19:00:40 drk $ */
- /*********************************************************************
- *
- * File: DndDrag.c
- *
- * Description: Implemenation of DND Drag Initator
- *
- *********************************************************************
- *
- *+SNOTICE
- *
- * RESTRICTED CONFIDENTIAL INFORMATION:
- *
- * The information in this document is subject to special
- * restrictions in a confidential disclosure agreement between
- * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
- * document outside HP, IBM, Sun, USL, SCO, or Univel without
- * Sun's specific written approval. This documment and all copies
- * and derivative works thereof must be returned or destroyed at
- * Sun's request.
- *
- * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
- *
- * (c) Copyright 1993, 1994 Hewlett-Packard Company
- * (c) Copyright 1993, 1994 International Business Machines Corp.
- * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
- * (c) Copyright 1993, 1994 Novell, Inc.
- *
- *+ENOTICE
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <X11/Intrinsic.h>
- #include <Xm/AtomMgr.h>
- #include <Xm/DragDrop.h>
- #include <Xm/DragC.h>
- #include <Xm/DragCP.h>
- #include <Xm/DragOverSP.h>
- #include <Dt/Wsm.h>
- #include "Dnd.h"
- #include "DndP.h"
- #include "DtSvcLock.h"
- /*
- * Drag Initiator Callbacks
- */
- static Boolean dndConvertProc(Widget, Atom*, Atom*, Atom*, XtPointer *,
- unsigned long*, int*);
- static void dndAppConvert(Widget, int, XEvent*, DtDragInfo*);
- static void dndDropStartCallback(Widget, XtPointer, XtPointer);
- static void dndDropFinishCallback(Widget, XtPointer, XtPointer);
- static void dndDragDropFinishCallback(Widget, XtPointer, XtPointer);
- static void dndTopLevelEnterCallback(Widget, XtPointer, XtPointer);
- static void dndTopLevelLeaveCallback(Widget, XtPointer, XtPointer);
- extern int _DtDndCountVarArgs(va_list vaList);
- extern void _DtDndArgListFromVarArgs(va_list vaList,
- Cardinal maxArgs,
- ArgList *argListReturn,
- Cardinal *argCountReturn);
- extern void _XmDragOverChange(Widget w,
- unsigned char dropSiteStatus);
- /*
- * Drag Initiator Resources
- */
- typedef struct {
- XtCallbackList dropOnRootCallback;
- Widget sourceIcon;
- Boolean bufferIsText;
- } DragSettings;
- #define Offset(field) XtOffsetOf(DragSettings, field)
- static XtResource dragResources[] = {
- { DtNdropOnRootCallback, DtCDropOnRootCallback,
- XtRCallback, sizeof(XtCallbackList), Offset(dropOnRootCallback),
- XtRImmediate, (XtPointer)NULL},
- { DtNsourceIcon, DtCSourceIcon,
- XtRWidget, sizeof(Widget), Offset(sourceIcon),
- XtRImmediate, (XtPointer)NULL },
- { DtNbufferIsText, DtCBufferIsText,
- XtRBoolean, sizeof(Boolean), Offset(bufferIsText),
- XtRImmediate, (XtPointer)False },
- };
- #undef Offset
- /*
- * DtDndVaDragStart
- *
- * Drag Start - varargs version
- */
- Widget
- DtDndVaDragStart(
- Widget dragInitiator,
- XEvent* event,
- DtDndProtocol protocol,
- Cardinal numItems,
- unsigned char operations,
- XtCallbackList dragConvertCallback,
- XtCallbackList dragFinishCallback,
- ...)
- {
- Widget dragContext;
- va_list vaList;
- ArgList argList;
- Cardinal argCount;
- _DtSvcWidgetToAppContext(dragInitiator);
- _DtSvcAppLock(app);
- va_start(vaList, dragFinishCallback);
- argCount = _DtDndCountVarArgs(vaList);
- va_end(vaList);
- va_start(vaList, dragFinishCallback);
- _DtDndArgListFromVarArgs(vaList, argCount, &argList, &argCount);
- va_end(vaList);
- dragContext = DtDndDragStart(dragInitiator, event, protocol,
- numItems, operations,
- dragConvertCallback, dragFinishCallback,
- argList, argCount);
- XtFree((char *)argList);
- _DtSvcAppUnlock(app);
- return dragContext;
- }
- /*
- * DtDndVaDragStart
- *
- * Drag Start - arglist version
- */
- Widget
- DtDndDragStart(
- Widget dragInitiator,
- XEvent* event,
- DtDndProtocol protocol,
- Cardinal numItems,
- unsigned char operations,
- XtCallbackList dragConvertCallback,
- XtCallbackList dragFinishCallback,
- ArgList argList,
- Cardinal argCount)
- {
- XtCallbackRec dragDropFinishCbRec[] = { {dndDragDropFinishCallback,
- NULL}, {NULL, NULL} };
- XtCallbackRec topLevelEnterCbRec[] = { {dndTopLevelEnterCallback,
- NULL}, {NULL, NULL} };
- XtCallbackRec topLevelLeaveCbRec[] = { {dndTopLevelLeaveCallback,
- NULL}, {NULL, NULL} };
- XtCallbackRec dropStartCbRec[] = { {dndDropStartCallback,
- NULL}, {NULL, NULL} };
- XtCallbackRec dropFinishCbRec[] = { {dndDropFinishCallback,
- NULL}, {NULL, NULL} };
- Display * display = XtDisplayOfObject(dragInitiator);
- Screen * screen = XtScreenOfObject(dragInitiator);
- Window rootWindow = RootWindowOfScreen(screen);
- DtDragInfo * dtDragInfo;
- DragSettings settings;
- DtDndDragSource sourceType;
- DtDndTransfer * transfer;
- Arg * args;
- int ii, nn, savedEventType;
- Atom * exportTargets;
- Cardinal numExportTargets;
- _DtSvcWidgetToAppContext(dragInitiator);
- _DtSvcAppLock(app);
- /*
- * Reject the drag if noop or multiple protocols specified
- */
- switch (protocol) {
- case DtDND_BUFFER_TRANSFER:
- case DtDND_FILENAME_TRANSFER:
- case DtDND_TEXT_TRANSFER:
- break;
- case DtDND_NOOP_TRANSFER:
- default:
- _DtSvcAppUnlock(app);
- return (Widget)NULL;
- }
- /*
- * Parse resources into dragResources
- */
- XtGetSubresources(dragInitiator, &settings,
- (String)NULL, (String)NULL,
- dragResources, XtNumber(dragResources),
- argList, argCount);
- /*
- * Initialize DragInfo
- */
- dtDragInfo = (DtDragInfo *) XtMalloc(sizeof(DtDragInfo));
- dtDragInfo->dragInitiator = dragInitiator;
- dtDragInfo->dragContext = NULL;
- dtDragInfo->protocol = protocol;
- dtDragInfo->numItems = numItems;
- dtDragInfo->operations = operations;
- dtDragInfo->sourceIcon = settings.sourceIcon;
- dtDragInfo->bufferIsText = settings.bufferIsText;
- dtDragInfo->dragData = NULL;
- dtDragInfo->inRoot = False;
- dtDragInfo->status = DtDND_SUCCESS;
- dtDragInfo->clientData = NULL;
- dtDragInfo->backdropWindow
- = DtWsmGetCurrentBackdropWindow(display, rootWindow);
- dtDragInfo->dragConvertCallback
- = _DtDndCopyCallbackList(dragConvertCallback);
- dtDragInfo->dragFinishCallback
- = _DtDndCopyCallbackList(dragFinishCallback);
- dtDragInfo->dropOnRootCallback
- = _DtDndCopyCallbackList(settings.dropOnRootCallback);
- dtDragInfo->dragData = (DtDndContext *)XtCalloc(1,sizeof(DtDndContext));
- dtDragInfo->dragData->protocol = dtDragInfo->protocol;
- dtDragInfo->dragData->numItems = 0;
- /*
- * Get data transfer method
- * Use the transfer targets as export targets
- */
- dtDragInfo->transfer = _DtDndCreateExportTransfer(dtDragInfo);
- exportTargets = dtDragInfo->transfer->targets;
- numExportTargets = dtDragInfo->transfer->numTargets;
- #ifdef DEBUG
- printf("DtDndDragStart: drag from widget 0x%p\n", dragInitiator);
- _DtDndPrintTransfers(display,dtDragInfo->transfer,1);
- #endif
- /*
- * Set up drag icon
- */
- if (numItems > 1) {
- sourceType = DtDND_DRAG_SOURCE_MULTIPLE;
- } else {
- sourceType = dtDragInfo->transfer->methods->sourceType;
- }
-
- _DtDndSelectDragSource(dragInitiator, sourceType,
- dtDragInfo->sourceIcon);
- /*
- * Construct argument list
- */
- #define NUM_DRAG_ARGS 30
- args = (Arg *) XtMalloc(sizeof(Arg) * (NUM_DRAG_ARGS + argCount));
- #undef NUM_DRAG_ARGS
- /*
- * Copy in passed arguments
- */
- nn = 0;
- for (ii = 0; ii < argCount; ii++) {
- XtSetArg(args[nn], argList[ii].name, argList[ii].value); nn++;
- }
- /*
- * Set basic drag start arguments
- */
- XtSetArg(args[nn], XmNexportTargets, exportTargets);
- nn++;
- XtSetArg(args[nn], XmNnumExportTargets, numExportTargets);
- nn++;
- XtSetArg(args[nn], XmNdragOperations, operations);
- nn++;
- XtSetArg(args[nn], XmNblendModel, XmBLEND_ALL);
- nn++;
- XtSetArg(args[nn], XmNcursorBackground, WhitePixelOfScreen(screen));
- nn++;
- XtSetArg(args[nn], XmNcursorForeground, BlackPixelOfScreen(screen));
- nn++;
- XtSetArg(args[nn], XmNclientData, dtDragInfo);
- nn++;
- if (dtDragInfo->sourceIcon != NULL) {
- XtSetArg(args[nn],XmNsourcePixmapIcon, dtDragInfo->sourceIcon);
- nn++;
- XtSetArg(args[nn],XmNsourceCursorIcon, dtDragInfo->sourceIcon);
- nn++;
- }
- /*
- * Set up DnD callbacks for Motif
- */
- XtSetArg(args[nn], XmNconvertProc, dndConvertProc);
- nn++;
-
- dragDropFinishCbRec[0].closure = (XtPointer) dtDragInfo;
- dropFinishCbRec[0].closure = (XtPointer) dtDragInfo;
- dtDragInfo->dragDropFinishCallback
- = _DtDndCopyCallbackList(dragDropFinishCbRec);
- dtDragInfo->dropFinishCallback
- = _DtDndCopyCallbackList(dropFinishCbRec);
- XtSetArg(args[nn], XmNdragDropFinishCallback, dtDragInfo->dragDropFinishCallback);
- nn++;
- XtSetArg(args[nn], XmNdropFinishCallback, dtDragInfo->dropFinishCallback);
- nn++;
- /*
- * Only use top-level-enter/leave callbacks if also doing drop-on-root
- */
- if (dtDragInfo->dropOnRootCallback != NULL) {
- topLevelEnterCbRec[0].closure = (XtPointer) dtDragInfo;
- topLevelLeaveCbRec[0].closure = (XtPointer) dtDragInfo;
- dropStartCbRec[0].closure = (XtPointer) dtDragInfo;
- dtDragInfo->topLevelEnterCallback
- = _DtDndCopyCallbackList(topLevelEnterCbRec);
- dtDragInfo->topLevelLeaveCallback
- = _DtDndCopyCallbackList(topLevelLeaveCbRec);
- dtDragInfo->dropStartCallback
- = _DtDndCopyCallbackList(dropStartCbRec);
- XtSetArg(args[nn], XmNtopLevelEnterCallback, dtDragInfo->topLevelEnterCallback);
- nn++;
- XtSetArg(args[nn], XmNtopLevelLeaveCallback, dtDragInfo->topLevelLeaveCallback);
- nn++;
- XtSetArg(args[nn], XmNdropStartCallback, dtDragInfo->dropStartCallback);
- nn++;
- }
- /*
- * Fake a button press. This is necessary because Motif requires
- * a drag to start on a button press. We need to be able to start
- * a drag on a mouse motion event when Bselect is held down. Since
- * the motion event has the fields necessary for Motif this works.
- */
- savedEventType = event->type;
- if (event->type == MotionNotify) {
- event->type = ButtonPress;
- }
- /*
- * Start the drag
- */
- dtDragInfo->dragContext = XmDragStart(dragInitiator, event, args, nn);
- XtFree((char *)args);
- event->type = savedEventType;
- _DtSvcAppUnlock(app);
- return (dtDragInfo->dragContext);
- }
- /*********************************************************************
- *
- * Drag Initiator Callbacks
- *
- *********************************************************************/
- /*
- * dndDropStartCallback
- *
- *
- */
- static void
- dndDropStartCallback(
- Widget dragContext,
- XtPointer clientData,
- XtPointer callData)
- {
- DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
- DtDndContext *dragData;
- XmDragContext xmDragContext = (XmDragContext)dtDragInfo->dragContext;
- XmDropStartCallbackStruct *xmDropInfo = (XmDropStartCallback) callData;
- DtDndTransferCallbackStruct dropCallData;
- int posOffsetX, posOffsetY;
- /*
- * If the user has cancelled the drop, or the drop isn't on the
- * root, or there are no dropOnRoot or convert callbacks
- * then reject the drop.
- */
- if (xmDragContext->drag.dragCompletionStatus == XmDROP_CANCEL ||
- dtDragInfo->inRoot == False ||
- dtDragInfo->dropOnRootCallback == NULL ||
- dtDragInfo->dragConvertCallback == NULL ) {
-
- xmDropInfo->dropSiteStatus = XmINVALID_DROP_SITE;
- xmDropInfo->dropAction = XmDROP_CANCEL;
- return;
- }
- /*
- * The following is to handle the dropOnRoot situation.
- * We handle both the convert and transfer sides of the
- * transaction here. First we get the application drag data
- * and then we call the application dropOnRoot callback.
- */
-
- /*
- * Initialize protocol specific dragData
- */
- dtDragInfo->dragData->numItems = dtDragInfo->numItems;
- (*dtDragInfo->transfer->methods->convertInit)(dtDragInfo);
- /*
- * Invoke the application convert callback
- */
- dndAppConvert(dragContext, DtCR_DND_CONVERT_DATA,
- xmDropInfo->event, dtDragInfo);
- if (dtDragInfo->status == DtDND_FAILURE) {
- return;
- }
- /*
- * Setup dropOnRootcall data and invoke the dropOnroot callback
- */
- _DtDndGetIconOffset(dtDragInfo->dragContext,
- dtDragInfo->transfer->methods->sourceType,
- &posOffsetX, &posOffsetY);
- dropCallData.reason = DtCR_DND_ROOT_TRANSFER;
- dropCallData.event = xmDropInfo->event;
- dropCallData.x = xmDropInfo->x + posOffsetX;
- dropCallData.y = xmDropInfo->y + posOffsetY;
- dropCallData.operation = xmDropInfo->operation;
- dropCallData.dropData = dtDragInfo->dragData;
- dropCallData.completeMove = False;
- dropCallData.status = DtDND_SUCCESS;
- _DtDndCallCallbackList(dragContext, dtDragInfo->dropOnRootCallback,
- (XtPointer)&dropCallData);
- /*
- * Tell Motif that the root is a valid drop site
- */
- xmDropInfo->dropSiteStatus = XmVALID_DROP_SITE;
- xmDropInfo->dropAction = XmDROP;
- }
- /*
- * dndConvertProc
- *
- *
- */
- static Boolean
- dndConvertProc(
- Widget dragContext,
- Atom *selection,
- Atom *target,
- Atom *returnType,
- XtPointer *returnValue,
- unsigned long *returnLength,
- int *returnFormat)
- {
- Atom realSelectionAtom; /* Motif hides the selection atom */
- DtDragInfo *dtDragInfo = NULL;
- XSelectionRequestEvent *selectionRequestEvent;
- Boolean status;
- #ifdef DEBUG
- {
- Display *display = XtDisplayOfObject(dragContext);
- char *atomname = XGetAtomName(display,*target);
- printf("dndConvertProc: target = %s\n",(atomname ? atomname : "Null"));
- if (atomname) XFree(atomname);
- }
- #endif
- /*
- * Get the DtDragInfo
- */
- XtVaGetValues(dragContext, XmNclientData, &dtDragInfo, NULL);
- if (dtDragInfo == NULL || dtDragInfo->status == DtDND_FAILURE) {
- return False;
- }
- /*
- * Get selection request event
- */
- XtVaGetValues(dragContext, XmNiccHandle, &realSelectionAtom, NULL);
- selectionRequestEvent = XtGetSelectionRequest(dragContext,
- realSelectionAtom, NULL); /* REMIND: NULL for atomic transfer */
- /*
- * Get the application drag data if necessary
- */
- if (dtDragInfo->dragData->numItems == 0) {
- dtDragInfo->dragData->numItems = dtDragInfo->numItems;
-
- (*dtDragInfo->transfer->methods->convertInit)(dtDragInfo);
- dndAppConvert(dragContext, DtCR_DND_CONVERT_DATA,
- (XEvent *)selectionRequestEvent, dtDragInfo);
- if (dtDragInfo->status == DtDND_FAILURE) {
- return False;
- }
- }
- /*
- * Handle transfer protocol independent target conversions
- */
- if (*target == XA_TARGETS) {
- /*
- * TARGETS Construct a list of targets consisting of those
- * the dnd library supports plus those supported by
- * the drag initiator.
- */
- int ii, LIBRARY_TARGETS = 6;
- Atom * availTargets;
- Atom * allTargets;
- Cardinal numAvailTargets;
- Cardinal numAllTargets;
- (*dtDragInfo->transfer->methods->getAvailTargets)(dtDragInfo,
- &availTargets, &numAvailTargets);
- numAllTargets = numAvailTargets + LIBRARY_TARGETS;
- allTargets = (Atom *)XtMalloc(sizeof(Atom) * numAllTargets);
- for (ii = 0; ii < numAvailTargets; ii++) {
- allTargets[ii] = availTargets[ii];
- }
- XtFree((char *)availTargets);
- ii = numAvailTargets;
- allTargets[ii++] = XA_TARGETS;
- allTargets[ii++] = XA_TIMESTAMP;
- allTargets[ii++] = XA_MULTIPLE;
- allTargets[ii++] = XA_HOST_NAME;
- allTargets[ii++] = XA_SUN_FILE_HOST_NAME;
- allTargets[ii++] = XA_DELETE;
- *returnType = XA_ATOM;
- *returnFormat = 32;
- *returnValue = (XtPointer)allTargets;
- *returnLength = numAllTargets * sizeof(Atom)/4;
- status = True;
- } else if (*target == XA_TIMESTAMP || *target == XA_MULTIPLE) {
- /*
- * TIMESTAMP and MULTIPLE are handled by the Intrinsics
- */
- status = True;
- } else if (*target == XA_HOST_NAME ||
- *target == XA_SUN_FILE_HOST_NAME) {
- /*
- * HOST_NAME, _SUN_FILE_HOST_NAME The name of this host
- */
- *returnType = XA_STRING;
- *returnValue = (XtPointer)XtNewString(_DtDndGetHostName());
- *returnLength = strlen((char *)*returnValue) + 1;
- *returnFormat = 8;
- status = True;
- } else if (*target == XA_DELETE) {
- /*
- * DELETE Set up convert callback data to specify
- * deletion and invoke the application-defined
- * convertCallback() to perform the delete.
- */
- *returnType = XA_NULL;
- *returnFormat = 32;
- *returnValue = (XtPointer) NULL;
- *returnLength = 0;
- dndAppConvert(dragContext, DtCR_DND_CONVERT_DELETE,
- (XEvent *)selectionRequestEvent, dtDragInfo);
- status = True;
- } else if (*target == XA_SUN_ENUM_COUNT) {
- /*
- * _SUN_ENUMERATION_COUNT The number of items available
- */
- int *count = XtNew(int);
- if (dtDragInfo->dragData->numItems == 1) {
- count[0] = 1;
- } else {
- count[0] = 0;
- dtDragInfo->status = DtDND_FAILURE;
- }
- *returnType = XA_INTEGER;
- *returnValue = (XtPointer)count;
- *returnLength = 1;
- *returnFormat = 32;
- status = True;
- } else {
- /*
- * Invoke protocol specific convert method
- */
- status = (*dtDragInfo->transfer->methods->convert)(
- dragContext, dtDragInfo,
- selection, target,
- returnType, returnValue,
- returnLength, returnFormat,
- selectionRequestEvent);
- }
- return status;
- }
- /*
- * dndAppConvert
- *
- * Call the application convert callback
- */
- static void
- dndAppConvert(
- Widget dragContext,
- int reason,
- XEvent * event,
- DtDragInfo * dtDragInfo)
- {
- DtDndConvertCallbackStruct convertCallData;
- convertCallData.reason = reason;
- convertCallData.event = event;
- convertCallData.dragData = dtDragInfo->dragData;
- convertCallData.status = DtDND_SUCCESS;
- _DtDndCallCallbackList(dragContext, dtDragInfo->dragConvertCallback,
- (XtPointer)&convertCallData);
- dtDragInfo->status = convertCallData.status;
- if (reason == DtCR_DND_CONVERT_DATA &&
- dtDragInfo->dragData->numItems <= 0) {
- dtDragInfo->status = DtDND_FAILURE;
- }
- }
- /*
- * dndDropFinishCallback
- *
- * Handle drop-on-root case
- */
- static void
- dndDropFinishCallback(
- Widget dragContext,
- XtPointer clientData,
- XtPointer callData)
- {
- DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
- XmDropFinishCallbackStruct *xmDropFinishCallData =
- (XmDropFinishCallbackStruct *) callData;
- if (dtDragInfo->dropOnRootCallback != NULL &&
- dtDragInfo->inRoot &&
- xmDropFinishCallData->dropSiteStatus == XmVALID_DROP_SITE) {
- xmDropFinishCallData->completionStatus = XmDROP_SUCCESS;
- XtVaSetValues(dtDragInfo->dragContext,
- XmNblendModel, XmBLEND_NONE, NULL);
- }
- }
- /*
- * dndDragDropFinishCallback
- *
- * Call the application dragFinishCallback
- */
- static void
- dndDragDropFinishCallback(
- Widget dragContext,
- XtPointer clientData,
- XtPointer callData)
- {
- XmDragDropFinishCallbackStruct *xmDndFinishInfo =
- (XmDragDropFinishCallbackStruct *)callData;
- DtDragInfo *dtDragInfo = (DtDragInfo *)clientData;
- DtDndDragFinishCallbackStruct dragFinishCallData;
- /*
- * Invoke application dragFinishCallback
- */
- dragFinishCallData.reason = DtCR_DND_DRAG_FINISH;
- dragFinishCallData.event = xmDndFinishInfo->event;
- dragFinishCallData.sourceIcon = dtDragInfo->sourceIcon;
- dragFinishCallData.dragData = dtDragInfo->dragData;
- _DtDndCallCallbackList(dragContext, dtDragInfo->dragFinishCallback,
- (XtPointer)&dragFinishCallData);
- /*
- * Restore motif default drag cursors
- */
- _DtDndSelectDragSource(dragContext, DtDND_DRAG_SOURCE_DEFAULT, NULL);
- /*
- * Invoke protocol specific convertFinish
- */
- (*dtDragInfo->transfer->methods->convertFinish)(dtDragInfo);
- /*
- * Free data structures allocated during the drag
- */
- XtFree((char *)dtDragInfo->transfer->targets);
- XtFree((char *)dtDragInfo->transfer);
- XtFree((char *)dtDragInfo->dragConvertCallback);
- XtFree((char *)dtDragInfo->dragFinishCallback);
- XtFree((char *)dtDragInfo->dragDropFinishCallback);
- XtFree((char *)dtDragInfo->dropFinishCallback);
- if (dtDragInfo->dropOnRootCallback != NULL) {
- XtFree((char *)dtDragInfo->topLevelEnterCallback);
- XtFree((char *)dtDragInfo->topLevelLeaveCallback);
- XtFree((char *)dtDragInfo->dropStartCallback);
- }
- XtFree((char *)dtDragInfo->dropOnRootCallback);
- XtFree((char *)dtDragInfo->dragData);
- XtFree((char *)dtDragInfo);
- }
- /*
- * dndTopLevelEnterCallback -- Support for drop-on-root callback.
- * When a drop-on-root callback has been set, determines if
- * the drag has entered the root window (or equivalents)
- * and sneakily changes Motif's idea that the root is an
- * invalid drop site to think that it's really a valid one.
- * Also updates dtDragInfo.inRoot as needed.
- */
- static void
- dndTopLevelEnterCallback(
- Widget dragContext,
- XtPointer clientData,
- XtPointer callData)
- {
- XmTopLevelEnterCallbackStruct *xmEnterInfo =
- (XmTopLevelEnterCallbackStruct *) callData;
- DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
- XmDragContext xmDragContext = (XmDragContext) dragContext;
- XmDragOverShellWidget dragOverShell = xmDragContext->drag.curDragOver;
-
- if (xmEnterInfo->window == RootWindowOfScreen(xmEnterInfo->screen) ||
- dtDragInfo->backdropWindow == xmEnterInfo->window ) {
- dragOverShell->drag.cursorState = XmVALID_DROP_SITE;
- _XmDragOverChange((Widget)dragOverShell,
- dragOverShell->drag.cursorState);
- dtDragInfo->inRoot = True;
- } else {
- dtDragInfo->inRoot = False;
- }
- }
- /*
- * dndTopLevelLeaveCallback -- Support for drop-on-root callback.
- * When a drop-on-root callback has been set, determines if
- * the drag is exiting the root window and restores Motif's
- * internal state back to thinking that the root window is
- * an invalid drop site. We don't update dtDragInfo->inRoot
- * here since the top-level-leave callback is called before
- * the drop callback which needs to know if we're in the root
- * or not.
- */
- static void
- dndTopLevelLeaveCallback(
- Widget dragContext,
- XtPointer clientData,
- XtPointer callData)
- {
- XmTopLevelLeaveCallbackStruct *xmLeaveInfo =
- (XmTopLevelLeaveCallbackStruct *) callData;
- DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
- XmDragContext xmDragContext = (XmDragContext) dragContext;
- XmDragOverShellWidget dragOverShell = xmDragContext->drag.curDragOver;
-
- if (xmLeaveInfo->window == RootWindowOfScreen(xmLeaveInfo->screen) ||
- dtDragInfo->backdropWindow == xmLeaveInfo->window ) {
- dragOverShell->drag.cursorState = XmINVALID_DROP_SITE;
- _XmDragOverChange((Widget)dragOverShell,
- dragOverShell->drag.cursorState);
- }
- }
|