2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: DndDrag.c /main/5 1996/09/27 19:00:40 drk $ */
24 /*********************************************************************
28 * Description: Implemenation of DND Drag Initator
30 *********************************************************************
34 * RESTRICTED CONFIDENTIAL INFORMATION:
36 * The information in this document is subject to special
37 * restrictions in a confidential disclosure agreement between
38 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
39 * document outside HP, IBM, Sun, USL, SCO, or Univel without
40 * Sun's specific written approval. This documment and all copies
41 * and derivative works thereof must be returned or destroyed at
44 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
46 * (c) Copyright 1993, 1994 Hewlett-Packard Company
47 * (c) Copyright 1993, 1994 International Business Machines Corp.
48 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
49 * (c) Copyright 1993, 1994 Novell, Inc.
57 #include <X11/Intrinsic.h>
58 #include <Xm/AtomMgr.h>
59 #include <Xm/DragDrop.h>
61 #include <Xm/DragCP.h>
62 #include <Xm/DragOverSP.h>
65 #include "DtSvcLock.h"
68 * Drag Initiator Callbacks
70 static Boolean dndConvertProc(Widget, Atom*, Atom*, Atom*, XtPointer *,
71 unsigned long*, int*);
72 static void dndAppConvert(Widget, int, XEvent*, DtDragInfo*);
73 static void dndDropStartCallback(Widget, XtPointer, XtPointer);
74 static void dndDropFinishCallback(Widget, XtPointer, XtPointer);
75 static void dndDragDropFinishCallback(Widget, XtPointer, XtPointer);
76 static void dndTopLevelEnterCallback(Widget, XtPointer, XtPointer);
77 static void dndTopLevelLeaveCallback(Widget, XtPointer, XtPointer);
80 * Drag Initiator Resources
83 XtCallbackList dropOnRootCallback;
88 #define Offset(field) XtOffsetOf(DragSettings, field)
90 static XtResource dragResources[] = {
91 { DtNdropOnRootCallback, DtCDropOnRootCallback,
92 XtRCallback, sizeof(XtCallbackList), Offset(dropOnRootCallback),
93 XtRImmediate, (XtPointer)NULL},
94 { DtNsourceIcon, DtCSourceIcon,
95 XtRWidget, sizeof(Widget), Offset(sourceIcon),
96 XtRImmediate, (XtPointer)NULL },
97 { DtNbufferIsText, DtCBufferIsText,
98 XtRBoolean, sizeof(Boolean), Offset(bufferIsText),
99 XtRImmediate, (XtPointer)False },
107 * Drag Start - varargs version
112 Widget dragInitiator,
114 DtDndProtocol protocol,
116 unsigned char operations,
117 XtCallbackList dragConvertCallback,
118 XtCallbackList dragFinishCallback,
125 _DtSvcWidgetToAppContext(dragInitiator);
129 va_start(vaList, dragFinishCallback);
130 argCount = _DtDndCountVarArgs(vaList);
133 va_start(vaList, dragFinishCallback);
134 _DtDndArgListFromVarArgs(vaList, argCount, &argList, &argCount);
137 dragContext = DtDndDragStart(dragInitiator, event, protocol,
138 numItems, operations,
139 dragConvertCallback, dragFinishCallback,
142 XtFree((char *)argList);
144 _DtSvcAppUnlock(app);
151 * Drag Start - arglist version
156 Widget dragInitiator,
158 DtDndProtocol protocol,
160 unsigned char operations,
161 XtCallbackList dragConvertCallback,
162 XtCallbackList dragFinishCallback,
166 XtCallbackRec dragDropFinishCbRec[] = { {dndDragDropFinishCallback,
167 NULL}, {NULL, NULL} };
168 XtCallbackRec topLevelEnterCbRec[] = { {dndTopLevelEnterCallback,
169 NULL}, {NULL, NULL} };
170 XtCallbackRec topLevelLeaveCbRec[] = { {dndTopLevelLeaveCallback,
171 NULL}, {NULL, NULL} };
172 XtCallbackRec dropStartCbRec[] = { {dndDropStartCallback,
173 NULL}, {NULL, NULL} };
174 XtCallbackRec dropFinishCbRec[] = { {dndDropFinishCallback,
175 NULL}, {NULL, NULL} };
176 Display * display = XtDisplayOfObject(dragInitiator);
177 Screen * screen = XtScreenOfObject(dragInitiator);
178 Window rootWindow = RootWindowOfScreen(screen);
179 DtDragInfo * dtDragInfo;
180 DragSettings settings;
181 DtDndDragSource sourceType;
182 DtDndTransfer * transfer;
184 int ii, nn, savedEventType;
185 Atom * exportTargets;
186 Cardinal numExportTargets;
187 _DtSvcWidgetToAppContext(dragInitiator);
191 * Reject the drag if noop or multiple protocols specified
195 case DtDND_BUFFER_TRANSFER:
196 case DtDND_FILENAME_TRANSFER:
197 case DtDND_TEXT_TRANSFER:
199 case DtDND_NOOP_TRANSFER:
201 _DtSvcAppUnlock(app);
206 * Parse resources into dragResources
209 XtGetSubresources(dragInitiator, &settings,
210 (String)NULL, (String)NULL,
211 dragResources, XtNumber(dragResources),
215 * Initialize DragInfo
218 dtDragInfo = (DtDragInfo *) XtMalloc(sizeof(DtDragInfo));
220 dtDragInfo->dragInitiator = dragInitiator;
221 dtDragInfo->dragContext = NULL;
222 dtDragInfo->protocol = protocol;
223 dtDragInfo->numItems = numItems;
224 dtDragInfo->operations = operations;
225 dtDragInfo->sourceIcon = settings.sourceIcon;
226 dtDragInfo->bufferIsText = settings.bufferIsText;
227 dtDragInfo->dragData = NULL;
228 dtDragInfo->inRoot = False;
229 dtDragInfo->status = DtDND_SUCCESS;
230 dtDragInfo->clientData = NULL;
231 dtDragInfo->backdropWindow
232 = DtWsmGetCurrentBackdropWindow(display, rootWindow);
234 dtDragInfo->dragConvertCallback
235 = _DtDndCopyCallbackList(dragConvertCallback);
236 dtDragInfo->dragFinishCallback
237 = _DtDndCopyCallbackList(dragFinishCallback);
238 dtDragInfo->dropOnRootCallback
239 = _DtDndCopyCallbackList(settings.dropOnRootCallback);
241 dtDragInfo->dragData = (DtDndContext *)XtCalloc(1,sizeof(DtDndContext));
242 dtDragInfo->dragData->protocol = dtDragInfo->protocol;
243 dtDragInfo->dragData->numItems = 0;
246 * Get data transfer method
247 * Use the transfer targets as export targets
250 dtDragInfo->transfer = _DtDndCreateExportTransfer(dtDragInfo);
252 exportTargets = dtDragInfo->transfer->targets;
253 numExportTargets = dtDragInfo->transfer->numTargets;
256 printf("DtDndDragStart: drag from widget 0x%p\n", dragInitiator);
257 _DtDndPrintTransfers(display,dtDragInfo->transfer,1);
265 sourceType = DtDND_DRAG_SOURCE_MULTIPLE;
267 sourceType = dtDragInfo->transfer->methods->sourceType;
270 _DtDndSelectDragSource(dragInitiator, sourceType,
271 dtDragInfo->sourceIcon);
274 * Construct argument list
277 #define NUM_DRAG_ARGS 30
278 args = (Arg *) XtMalloc(sizeof(Arg) * (NUM_DRAG_ARGS + argCount));
282 * Copy in passed arguments
286 for (ii = 0; ii < argCount; ii++) {
287 XtSetArg(args[nn], argList[ii].name, argList[ii].value); nn++;
291 * Set basic drag start arguments
294 XtSetArg(args[nn], XmNexportTargets, exportTargets);
296 XtSetArg(args[nn], XmNnumExportTargets, numExportTargets);
298 XtSetArg(args[nn], XmNdragOperations, operations);
300 XtSetArg(args[nn], XmNblendModel, XmBLEND_ALL);
302 XtSetArg(args[nn], XmNcursorBackground, WhitePixelOfScreen(screen));
304 XtSetArg(args[nn], XmNcursorForeground, BlackPixelOfScreen(screen));
306 XtSetArg(args[nn], XmNclientData, dtDragInfo);
309 if (dtDragInfo->sourceIcon != NULL) {
310 XtSetArg(args[nn],XmNsourcePixmapIcon, dtDragInfo->sourceIcon);
312 XtSetArg(args[nn],XmNsourceCursorIcon, dtDragInfo->sourceIcon);
317 * Set up DnD callbacks for Motif
320 XtSetArg(args[nn], XmNconvertProc, dndConvertProc);
323 dragDropFinishCbRec[0].closure = (XtPointer) dtDragInfo;
324 dropFinishCbRec[0].closure = (XtPointer) dtDragInfo;
325 dtDragInfo->dragDropFinishCallback
326 = _DtDndCopyCallbackList(dragDropFinishCbRec);
327 dtDragInfo->dropFinishCallback
328 = _DtDndCopyCallbackList(dropFinishCbRec);
330 XtSetArg(args[nn], XmNdragDropFinishCallback, dtDragInfo->dragDropFinishCallback);
332 XtSetArg(args[nn], XmNdropFinishCallback, dtDragInfo->dropFinishCallback);
336 * Only use top-level-enter/leave callbacks if also doing drop-on-root
339 if (dtDragInfo->dropOnRootCallback != NULL) {
341 topLevelEnterCbRec[0].closure = (XtPointer) dtDragInfo;
342 topLevelLeaveCbRec[0].closure = (XtPointer) dtDragInfo;
343 dropStartCbRec[0].closure = (XtPointer) dtDragInfo;
344 dtDragInfo->topLevelEnterCallback
345 = _DtDndCopyCallbackList(topLevelEnterCbRec);
346 dtDragInfo->topLevelLeaveCallback
347 = _DtDndCopyCallbackList(topLevelLeaveCbRec);
348 dtDragInfo->dropStartCallback
349 = _DtDndCopyCallbackList(dropStartCbRec);
351 XtSetArg(args[nn], XmNtopLevelEnterCallback, dtDragInfo->topLevelEnterCallback);
353 XtSetArg(args[nn], XmNtopLevelLeaveCallback, dtDragInfo->topLevelLeaveCallback);
355 XtSetArg(args[nn], XmNdropStartCallback, dtDragInfo->dropStartCallback);
360 * Fake a button press. This is necessary because Motif requires
361 * a drag to start on a button press. We need to be able to start
362 * a drag on a mouse motion event when Bselect is held down. Since
363 * the motion event has the fields necessary for Motif this works.
366 savedEventType = event->type;
368 if (event->type == MotionNotify) {
369 event->type = ButtonPress;
376 dtDragInfo->dragContext = XmDragStart(dragInitiator, event, args, nn);
378 XtFree((char *)args);
380 event->type = savedEventType;
382 _DtSvcAppUnlock(app);
383 return (dtDragInfo->dragContext);
386 /*********************************************************************
388 * Drag Initiator Callbacks
390 *********************************************************************/
393 * dndDropStartCallback
398 dndDropStartCallback(
400 XtPointer clientData,
403 DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
404 DtDndContext *dragData;
405 XmDragContext xmDragContext = (XmDragContext)dtDragInfo->dragContext;
406 XmDropStartCallbackStruct *xmDropInfo = (XmDropStartCallback) callData;
407 DtDndTransferCallbackStruct dropCallData;
408 int posOffsetX, posOffsetY;
411 * If the user has cancelled the drop, or the drop isn't on the
412 * root, or there are no dropOnRoot or convert callbacks
413 * then reject the drop.
416 if (xmDragContext->drag.dragCompletionStatus == XmDROP_CANCEL ||
417 dtDragInfo->inRoot == False ||
418 dtDragInfo->dropOnRootCallback == NULL ||
419 dtDragInfo->dragConvertCallback == NULL ) {
421 xmDropInfo->dropSiteStatus = XmINVALID_DROP_SITE;
422 xmDropInfo->dropAction = XmDROP_CANCEL;
428 * The following is to handle the dropOnRoot situation.
429 * We handle both the convert and transfer sides of the
430 * transaction here. First we get the application drag data
431 * and then we call the application dropOnRoot callback.
435 * Initialize protocol specific dragData
438 dtDragInfo->dragData->numItems = dtDragInfo->numItems;
440 (*dtDragInfo->transfer->methods->convertInit)(dtDragInfo);
443 * Invoke the application convert callback
446 dndAppConvert(dragContext, DtCR_DND_CONVERT_DATA,
447 xmDropInfo->event, dtDragInfo);
449 if (dtDragInfo->status == DtDND_FAILURE) {
454 * Setup dropOnRootcall data and invoke the dropOnroot callback
457 _DtDndGetIconOffset(dtDragInfo->dragContext,
458 dtDragInfo->transfer->methods->sourceType,
459 &posOffsetX, &posOffsetY);
461 dropCallData.reason = DtCR_DND_ROOT_TRANSFER;
462 dropCallData.event = xmDropInfo->event;
463 dropCallData.x = xmDropInfo->x + posOffsetX;
464 dropCallData.y = xmDropInfo->y + posOffsetY;
465 dropCallData.operation = xmDropInfo->operation;
466 dropCallData.dropData = dtDragInfo->dragData;
467 dropCallData.completeMove = False;
468 dropCallData.status = DtDND_SUCCESS;
470 _DtDndCallCallbackList(dragContext, dtDragInfo->dropOnRootCallback,
471 (XtPointer)&dropCallData);
474 * Tell Motif that the root is a valid drop site
477 xmDropInfo->dropSiteStatus = XmVALID_DROP_SITE;
478 xmDropInfo->dropAction = XmDROP;
492 XtPointer *returnValue,
493 unsigned long *returnLength,
496 Atom realSelectionAtom; /* Motif hides the selection atom */
497 DtDragInfo *dtDragInfo = NULL;
498 XSelectionRequestEvent *selectionRequestEvent;
503 Display *display = XtDisplayOfObject(dragContext);
504 char *atomname = XGetAtomName(display,*target);
505 printf("dndConvertProc: target = %s\n",(atomname ? atomname : "Null"));
506 if (atomname) XFree(atomname);
513 XtVaGetValues(dragContext, XmNclientData, &dtDragInfo, NULL);
515 if (dtDragInfo == NULL || dtDragInfo->status == DtDND_FAILURE) {
520 * Get selection request event
523 XtVaGetValues(dragContext, XmNiccHandle, &realSelectionAtom, NULL);
524 selectionRequestEvent = XtGetSelectionRequest(dragContext,
525 realSelectionAtom, NULL); /* REMIND: NULL for atomic transfer */
528 * Get the application drag data if necessary
531 if (dtDragInfo->dragData->numItems == 0) {
533 dtDragInfo->dragData->numItems = dtDragInfo->numItems;
535 (*dtDragInfo->transfer->methods->convertInit)(dtDragInfo);
537 dndAppConvert(dragContext, DtCR_DND_CONVERT_DATA,
538 (XEvent *)selectionRequestEvent, dtDragInfo);
540 if (dtDragInfo->status == DtDND_FAILURE) {
546 * Handle transfer protocol independent target conversions
549 if (*target == XA_TARGETS) {
551 * TARGETS Construct a list of targets consisting of those
552 * the dnd library supports plus those supported by
553 * the drag initiator.
555 int ii, LIBRARY_TARGETS = 6;
558 Cardinal numAvailTargets;
559 Cardinal numAllTargets;
561 (*dtDragInfo->transfer->methods->getAvailTargets)(dtDragInfo,
562 &availTargets, &numAvailTargets);
564 numAllTargets = numAvailTargets + LIBRARY_TARGETS;
565 allTargets = (Atom *)XtMalloc(sizeof(Atom) * numAllTargets);
567 for (ii = 0; ii < numAvailTargets; ii++) {
568 allTargets[ii] = availTargets[ii];
571 XtFree((char *)availTargets);
573 ii = numAvailTargets;
575 allTargets[ii++] = XA_TARGETS;
576 allTargets[ii++] = XA_TIMESTAMP;
577 allTargets[ii++] = XA_MULTIPLE;
578 allTargets[ii++] = XA_HOST_NAME;
579 allTargets[ii++] = XA_SUN_FILE_HOST_NAME;
580 allTargets[ii++] = XA_DELETE;
582 *returnType = XA_ATOM;
584 *returnValue = (XtPointer)allTargets;
585 *returnLength = numAllTargets * sizeof(Atom)/4;
589 } else if (*target == XA_TIMESTAMP || *target == XA_MULTIPLE) {
591 * TIMESTAMP and MULTIPLE are handled by the Intrinsics
595 } else if (*target == XA_HOST_NAME ||
596 *target == XA_SUN_FILE_HOST_NAME) {
598 * HOST_NAME, _SUN_FILE_HOST_NAME The name of this host
600 *returnType = XA_STRING;
601 *returnValue = (XtPointer)XtNewString(_DtDndGetHostName());
602 *returnLength = strlen((char *)*returnValue) + 1;
607 } else if (*target == XA_DELETE) {
609 * DELETE Set up convert callback data to specify
610 * deletion and invoke the application-defined
611 * convertCallback() to perform the delete.
614 *returnType = XA_NULL;
616 *returnValue = (XtPointer) NULL;
619 dndAppConvert(dragContext, DtCR_DND_CONVERT_DELETE,
620 (XEvent *)selectionRequestEvent, dtDragInfo);
624 } else if (*target == XA_SUN_ENUM_COUNT) {
626 * _SUN_ENUMERATION_COUNT The number of items available
628 int *count = XtNew(int);
630 if (dtDragInfo->dragData->numItems == 1) {
634 dtDragInfo->status = DtDND_FAILURE;
637 *returnType = XA_INTEGER;
638 *returnValue = (XtPointer)count;
645 * Invoke protocol specific convert method
647 status = (*dtDragInfo->transfer->methods->convert)(
648 dragContext, dtDragInfo,
650 returnType, returnValue,
651 returnLength, returnFormat,
652 selectionRequestEvent);
661 * Call the application convert callback
668 DtDragInfo * dtDragInfo)
670 DtDndConvertCallbackStruct convertCallData;
672 convertCallData.reason = reason;
673 convertCallData.event = event;
674 convertCallData.dragData = dtDragInfo->dragData;
675 convertCallData.status = DtDND_SUCCESS;
677 _DtDndCallCallbackList(dragContext, dtDragInfo->dragConvertCallback,
678 (XtPointer)&convertCallData);
680 dtDragInfo->status = convertCallData.status;
682 if (reason == DtCR_DND_CONVERT_DATA &&
683 dtDragInfo->dragData->numItems <= 0) {
684 dtDragInfo->status = DtDND_FAILURE;
690 * dndDropFinishCallback
692 * Handle drop-on-root case
695 dndDropFinishCallback(
697 XtPointer clientData,
700 DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
701 XmDropFinishCallbackStruct *xmDropFinishCallData =
702 (XmDropFinishCallbackStruct *) callData;
704 if (dtDragInfo->dropOnRootCallback != NULL &&
705 dtDragInfo->inRoot &&
706 xmDropFinishCallData->dropSiteStatus == XmVALID_DROP_SITE) {
708 xmDropFinishCallData->completionStatus = XmDROP_SUCCESS;
710 XtVaSetValues(dtDragInfo->dragContext,
711 XmNblendModel, XmBLEND_NONE, NULL);
716 * dndDragDropFinishCallback
718 * Call the application dragFinishCallback
721 dndDragDropFinishCallback(
723 XtPointer clientData,
726 XmDragDropFinishCallbackStruct *xmDndFinishInfo =
727 (XmDragDropFinishCallbackStruct *)callData;
728 DtDragInfo *dtDragInfo = (DtDragInfo *)clientData;
729 DtDndDragFinishCallbackStruct dragFinishCallData;
732 * Invoke application dragFinishCallback
735 dragFinishCallData.reason = DtCR_DND_DRAG_FINISH;
736 dragFinishCallData.event = xmDndFinishInfo->event;
737 dragFinishCallData.sourceIcon = dtDragInfo->sourceIcon;
738 dragFinishCallData.dragData = dtDragInfo->dragData;
740 _DtDndCallCallbackList(dragContext, dtDragInfo->dragFinishCallback,
741 (XtPointer)&dragFinishCallData);
744 * Restore motif default drag cursors
747 _DtDndSelectDragSource(dragContext, DtDND_DRAG_SOURCE_DEFAULT, NULL);
750 * Invoke protocol specific convertFinish
753 (*dtDragInfo->transfer->methods->convertFinish)(dtDragInfo);
756 * Free data structures allocated during the drag
759 XtFree((char *)dtDragInfo->transfer->targets);
760 XtFree((char *)dtDragInfo->transfer);
761 XtFree((char *)dtDragInfo->dragConvertCallback);
762 XtFree((char *)dtDragInfo->dragFinishCallback);
763 XtFree((char *)dtDragInfo->dragDropFinishCallback);
764 XtFree((char *)dtDragInfo->dropFinishCallback);
765 if (dtDragInfo->dropOnRootCallback != NULL) {
766 XtFree((char *)dtDragInfo->topLevelEnterCallback);
767 XtFree((char *)dtDragInfo->topLevelLeaveCallback);
768 XtFree((char *)dtDragInfo->dropStartCallback);
770 XtFree((char *)dtDragInfo->dropOnRootCallback);
771 XtFree((char *)dtDragInfo->dragData);
772 XtFree((char *)dtDragInfo);
776 * dndTopLevelEnterCallback -- Support for drop-on-root callback.
777 * When a drop-on-root callback has been set, determines if
778 * the drag has entered the root window (or equivalents)
779 * and sneakily changes Motif's idea that the root is an
780 * invalid drop site to think that it's really a valid one.
781 * Also updates dtDragInfo.inRoot as needed.
784 dndTopLevelEnterCallback(
786 XtPointer clientData,
789 XmTopLevelEnterCallbackStruct *xmEnterInfo =
790 (XmTopLevelEnterCallbackStruct *) callData;
791 DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
792 XmDragContext xmDragContext = (XmDragContext) dragContext;
793 XmDragOverShellWidget dragOverShell = xmDragContext->drag.curDragOver;
796 if (xmEnterInfo->window == RootWindowOfScreen(xmEnterInfo->screen) ||
797 dtDragInfo->backdropWindow == xmEnterInfo->window ) {
799 dragOverShell->drag.cursorState = XmVALID_DROP_SITE;
800 _XmDragOverChange((Widget)dragOverShell,
801 dragOverShell->drag.cursorState);
803 dtDragInfo->inRoot = True;
806 dtDragInfo->inRoot = False;
811 * dndTopLevelLeaveCallback -- Support for drop-on-root callback.
812 * When a drop-on-root callback has been set, determines if
813 * the drag is exiting the root window and restores Motif's
814 * internal state back to thinking that the root window is
815 * an invalid drop site. We don't update dtDragInfo->inRoot
816 * here since the top-level-leave callback is called before
817 * the drop callback which needs to know if we're in the root
821 dndTopLevelLeaveCallback(
823 XtPointer clientData,
826 XmTopLevelLeaveCallbackStruct *xmLeaveInfo =
827 (XmTopLevelLeaveCallbackStruct *) callData;
828 DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
829 XmDragContext xmDragContext = (XmDragContext) dragContext;
830 XmDragOverShellWidget dragOverShell = xmDragContext->drag.curDragOver;
833 if (xmLeaveInfo->window == RootWindowOfScreen(xmLeaveInfo->screen) ||
834 dtDragInfo->backdropWindow == xmLeaveInfo->window ) {
836 dragOverShell->drag.cursorState = XmINVALID_DROP_SITE;
838 _XmDragOverChange((Widget)dragOverShell,
839 dragOverShell->drag.cursorState);