1 /* $XConsortium: DndDrop.c /main/6 1996/09/27 19:00:45 drk $ */
2 /*********************************************************************
6 * Description: Implementation of DND Drop Registration
8 *********************************************************************
12 * RESTRICTED CONFIDENTIAL INFORMATION:
14 * The information in this document is subject to special
15 * restrictions in a confidential disclosure agreement between
16 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
17 * document outside HP, IBM, Sun, USL, SCO, or Univel without
18 * Sun's specific written approval. This documment and all copies
19 * and derivative works thereof must be returned or destroyed at
22 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
24 * (c) Copyright 1993, 1994 Hewlett-Packard Company
25 * (c) Copyright 1993, 1994 International Business Machines Corp.
26 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
27 * (c) Copyright 1993, 1994 Novell, Inc.
34 #include <X11/Intrinsic.h>
35 #include <Xm/AtomMgr.h>
36 #include <Xm/DragDrop.h>
37 #include <Xm/DropSMgr.h>
38 #include <Xm/DropTrans.h>
41 #include "DtSvcLock.h"
44 * Drop Receiver Callbacks
47 static void dndDropProc(Widget, XtPointer, XtPointer);
48 static void dndTransferStart(Widget, XmDropProcCallbackStruct*,
49 DtDropInfo*, DtDndTransfer*, Atom*, Cardinal);
50 static void dndTransferProc(Widget, XtPointer, Atom*, Atom*,
51 XtPointer, unsigned long*, int*);
52 static void dndAppTransfer(Widget, DtDropInfo*);
53 static void dndDropAnimateCallback(Widget, XtPointer, XtPointer);
56 * Drop Support Functions
59 static void dndDropSiteDestroy(Widget, XtPointer, XtPointer);
60 static XID dndGetContextXID(Display*);
61 static Boolean dndSaveDropInfo(Display*, Widget, DtDropInfo*);
62 static DtDropInfo * dndFindDropInfo(Display*, Widget);
63 static void dndTransferStartFailed(Widget);
64 static void dndTransferFail(DtDropInfo*, Widget);
67 * Drop Register Resources
71 XtCallbackList dropAnimateCallback;
72 Boolean preserveRegistration;
73 Boolean registerChildren;
77 #define Offset(field) XtOffsetOf(DropSettings, field)
79 static XtResource dropResources[] = {
80 { DtNdropAnimateCallback, DtCDropAnimateCallback,
81 XtRCallback, sizeof(XtCallbackList), Offset(dropAnimateCallback),
82 XtRImmediate, (XtPointer)NULL },
83 { DtNpreserveRegistration, DtCPreserveRegistration,
84 XtRBoolean, sizeof(Boolean), Offset(preserveRegistration),
85 XtRImmediate, (XtPointer)True },
86 { DtNregisterChildren, DtCRegisterChildren,
87 XtRBoolean, sizeof(Boolean), Offset(registerChildren),
88 XtRImmediate, (XtPointer)False },
89 { DtNtextIsBuffer, DtCTextIsBuffer,
90 XtRBoolean, sizeof(Boolean), Offset(textIsBuffer),
91 XtRImmediate, (XtPointer)False },
99 * Drop Site Registration - varargs version
105 DtDndProtocol protocols,
106 unsigned char operations,
107 XtCallbackList transferCallback,
113 _DtSvcWidgetToAppContext(dropReceiver);
116 va_start(vaList, transferCallback);
117 argCount = _DtDndCountVarArgs(vaList);
120 va_start(vaList, transferCallback);
121 _DtDndArgListFromVarArgs(vaList, argCount, &argList, &argCount);
124 DtDndDropRegister(dropReceiver, protocols, operations,
125 transferCallback, argList, argCount);
127 XtFree((char *)argList);
128 _DtSvcAppUnlock(app);
134 * Drop Site Registration - arglist version
140 DtDndProtocol protocols,
141 unsigned char operations,
142 XtCallbackList dropTransferCallback,
146 Display * display = XtDisplayOfObject(dropReceiver);
147 DropSettings settings;
148 DtDropInfo * dtDropInfo;
149 DtDropSiteInfo* dsInfo = NULL;
150 DtDndTransfer * transfers;
151 Cardinal numTransfers;
153 Cardinal numImportTargets;
154 unsigned char mergedOperations;
157 _DtSvcWidgetToAppContext(dropReceiver);
162 * Reject a noop registration
164 if (protocols == DtDND_NOOP_TRANSFER) {
165 _DtSvcAppUnlock(app);
170 * Parse resources into dropResources
172 XtGetSubresources(dropReceiver, &settings,
173 (String)NULL, (String)NULL,
174 dropResources, XtNumber(dropResources),
177 * Initialize DropInfo
180 dtDropInfo = (DtDropInfo *) XtMalloc(sizeof(DtDropInfo));
182 dtDropInfo->dropReceiver = dropReceiver;
183 dtDropInfo->protocols = protocols;
184 dtDropInfo->operations = operations;
185 dtDropInfo->textIsBuffer = settings.textIsBuffer;
186 dtDropInfo->dropSiteInfo = NULL;
187 dtDropInfo->transferInfo = NULL;
188 dtDropInfo->status = DtDND_SUCCESS;
190 dtDropInfo->dropTransferCallback
191 = _DtDndCopyCallbackList(dropTransferCallback);
192 dtDropInfo->dropAnimateCallback
193 = _DtDndCopyCallbackList(settings.dropAnimateCallback);
196 * Initialize Transfer Methods
199 transfers = _DtDndCreateImportTransfers(dtDropInfo, &numTransfers);
201 dtDropInfo->transfers = transfers;
202 dtDropInfo->numTransfers = numTransfers;
205 printf("DtDndDropRegister: registering widget 0x%p\n", dropReceiver);
206 _DtDndPrintTransfers(display,transfers,numTransfers);
210 * Preserve existing drop registration info if requested
213 if (settings.preserveRegistration) {
216 dsInfo = (DtDropSiteInfo *)XtMalloc(sizeof(DtDropSiteInfo));
218 dsInfo->dropProc = (XtCallbackProc)NULL;
219 dsInfo->operations = XmDROP_NOOP;
220 dsInfo->importTargets = NULL;
221 dsInfo->numImportTargets = 0;
225 XtSetArg(pArgs[nn], XmNimportTargets,
226 &(dsInfo->importTargets)); nn++;
227 XtSetArg(pArgs[nn], XmNdropSiteOperations,
228 &(dsInfo->operations)); nn++;
229 XtSetArg(pArgs[nn], XmNnumImportTargets,
230 &(dsInfo->numImportTargets)); nn++;
231 XtSetArg(pArgs[nn], XmNdropProc,
232 &(dsInfo->dropProc)); nn++;
234 XmDropSiteRetrieve(dropReceiver, pArgs, nn);
236 if ( (dsInfo->dropProc != NULL) &&
237 (dsInfo->numImportTargets > 0) &&
238 (dsInfo->operations != XmDROP_NOOP) ){
240 dtDropInfo->dropSiteInfo = dsInfo;
242 XtFree((char *)dsInfo);
248 * Create list of import targets based on the requested transfer
249 * protocols and any preserved drop site registration.
252 numImportTargets = 0;
254 for (ii = 0; ii < numTransfers; ii++) {
255 numImportTargets += transfers[ii].numTargets;
258 if (dsInfo != NULL) {
259 numImportTargets += dsInfo->numImportTargets;
262 importTargets = (Atom *) XtMalloc(numImportTargets * sizeof(Atom));
265 for (ii = 0; ii < numTransfers; ii++) {
266 for (jj = 0; jj < transfers[ii].numTargets; jj++) {
267 importTargets[kk++] = transfers[ii].targets[jj];
271 if (dsInfo != NULL) {
272 for (jj = 0; jj < dsInfo->numImportTargets; jj++) {
273 importTargets[kk++] = dsInfo->importTargets[jj];
281 if (dsInfo != NULL) {
282 mergedOperations = dsInfo->operations | operations;
284 mergedOperations = operations;
288 * Create an argument list
291 #define NUM_DROP_ARGS 5
292 args = (Arg *) XtMalloc(sizeof(Arg) * (NUM_DROP_ARGS + argCount));
296 * Copy in passed arguments
301 for (ii = 0; ii < argCount; ii++) {
302 XtSetArg(args[nn], argList[ii].name, argList[ii].value); nn++;
306 * Set argument list for drop site registration
309 XtSetArg(args[nn], XmNimportTargets, importTargets); nn++;
310 XtSetArg(args[nn], XmNnumImportTargets, numImportTargets); nn++;
311 XtSetArg(args[nn], XmNdropSiteOperations, mergedOperations); nn++;
312 XtSetArg(args[nn], XmNdropProc, dndDropProc); nn++;
314 if (settings.registerChildren) {
315 XtSetArg(args[nn], XmNdropSiteType, XmDROP_SITE_COMPOSITE); nn++;
319 * Register the drop site
322 if (dsInfo != NULL) {
323 XmDropSiteUnregister(dropReceiver);
324 XmDropSiteRegister(dropReceiver, args, nn);
326 XmDropSiteRegister(dropReceiver, args, nn);
330 * Add a destroy callback to unregister the drop site
331 * Store the dropInfo using the dropReceiver as the context
332 * Free locally allocated memory
335 XtAddCallback(dropReceiver, XtNdestroyCallback,
336 dndDropSiteDestroy, NULL);
338 (void)dndSaveDropInfo(display, dropReceiver, dtDropInfo);
340 XtFree((char *)importTargets);
341 XtFree((char *)args);
342 _DtSvcAppUnlock(app);
346 * DtDndDropUnregister
348 * Unregister the drop site
354 Display *display = XtDisplayOfObject(dropReceiver);
355 DtDropInfo *dtDropInfo;
356 DtDropSiteInfo *dsInfo;
357 _DtSvcWidgetToAppContext(dropReceiver);
362 * Retrieve dropInfo. If there isn't one then the drop site
363 * was not registered by DtDndDropRegister() so return.
366 if ((dtDropInfo = dndFindDropInfo(display, dropReceiver)) == NULL) {
367 _DtSvcAppUnlock(app);
370 dsInfo = dtDropInfo->dropSiteInfo;
373 * Unregister the drop site
376 XmDropSiteUnregister(dropReceiver);
379 * If we have preserved drop site registration
380 * then restore the drop site to it's original state.
383 if (dsInfo != NULL) {
387 XtSetArg(args[nn], XmNimportTargets,
388 dsInfo->importTargets); nn++;
389 XtSetArg(args[nn], XmNnumImportTargets,
390 dsInfo->numImportTargets); nn++;
391 XtSetArg(args[nn], XmNdropProc,
392 dsInfo->dropProc); nn++;
393 XtSetArg(args[nn], XmNdropSiteOperations,
394 dsInfo->operations); nn++;
396 XmDropSiteRegister(dropReceiver, args, nn);
398 XtFree((char *)dsInfo);
402 * Free callback, context and memory associated with DtDndDropRegister
405 XtRemoveCallback(dropReceiver, XtNdestroyCallback,
406 dndDropSiteDestroy, NULL);
408 XDeleteContext(display, dndGetContextXID(display),
409 (XContext)dropReceiver);
411 _DtDndDestroyTransfers(dtDropInfo->transfers, dtDropInfo->numTransfers);
413 XtFree((char *)dtDropInfo->dropTransferCallback);
414 XtFree((char *)dtDropInfo->dropAnimateCallback);
415 XtFree((char *)dtDropInfo);
416 _DtSvcAppUnlock(app);
420 /*********************************************************************
422 * Drop Receiver Callbacks
424 *********************************************************************/
430 * Determine transfer target and operation and initiate transfer.
435 XtPointer clientData,
438 XmDropProcCallbackStruct *xmDropInfo =
439 (XmDropProcCallbackStruct *) callData;
440 Display * display = XtDisplayOfObject(dropReceiver);
442 Atom * exportTargets = NULL;
443 Cardinal numExportTargets = 0;
444 DtDropInfo * dtDropInfo;
445 DtDropSiteInfo* dsInfo;
446 DtDndTransfer * transfer;
449 * Reject invalid drops
452 if ( (xmDropInfo->dropSiteStatus != XmDROP_SITE_VALID) ||
453 (xmDropInfo->operation == XmDROP_NOOP) ||
454 (xmDropInfo->dropAction != XmDROP) ) {
457 printf("dndDropProc: failed drop status or operation\n");
459 dndTransferStartFailed(xmDropInfo->dragContext);
464 * Get the cached DropInfo
467 if ((dtDropInfo = dndFindDropInfo(display, dropReceiver)) == NULL) {
468 dndTransferStartFailed(xmDropInfo->dragContext);
473 * Get the export targets from the dragContext
476 XtVaGetValues(xmDropInfo->dragContext,
477 XmNexportTargets, &exportTargets,
478 XmNnumExportTargets, &numExportTargets,
481 if (exportTargets == NULL) {
482 dndTransferStartFailed(xmDropInfo->dragContext);
483 dtDropInfo->status = DtDND_FAILURE;
488 printf("dndDropProc: Export Targets: ");
489 _DtDndPrintTargets(display,exportTargets,numExportTargets);
493 * Search the DnD protocol import targets list to see
494 * if it's a target we handle. If it is then start our transfer.
497 transfer = _DtDndTransferFromTargets(
498 dtDropInfo->transfers, dtDropInfo->numTransfers,
499 exportTargets, numExportTargets);
501 if (transfer != NULL) {
503 dndTransferStart(dropReceiver, xmDropInfo, dtDropInfo,
504 transfer, exportTargets, numExportTargets);
509 * If there isn't any alternate drop registration
510 * then fail the transfer
513 dsInfo = dtDropInfo->dropSiteInfo;
515 if (dsInfo == NULL) {
516 dndTransferStartFailed(xmDropInfo->dragContext);
517 dtDropInfo->status = DtDND_FAILURE;
522 * Determine if the exportTargets are compatible with
523 * the alternate drop registration targets
524 * If they are not compatible then fail the transfer
525 * Otherwise call the original dropProc.
528 compatible = XmTargetsAreCompatible(display,
529 dsInfo->importTargets, dsInfo->numImportTargets,
530 exportTargets, numExportTargets);
533 dndTransferStartFailed(xmDropInfo->dragContext);
534 dtDropInfo->status = DtDND_FAILURE;
538 if (dsInfo->dropProc != NULL) {
539 (*(dsInfo->dropProc))(dropReceiver, clientData, callData);
546 * Start the transfer using protocol specific transfer entries
552 XmDropProcCallbackStruct *xmDropInfo,
553 DtDropInfo * dtDropInfo,
554 DtDndTransfer * transfer,
555 Atom * exportTargets,
556 Cardinal numExportTargets)
558 XtCallbackRec dropAnimateCbRec[] = { {dndDropAnimateCallback,
559 NULL}, {NULL, NULL} };
560 Display * display = XtDisplayOfObject(dropReceiver);
561 DtDndContext * dropData;
562 DtTransferInfo *transferInfo;
563 Atom * transferTargets;
564 Cardinal numTransferTargets;
566 XmDropTransferEntryRec * transferEntries;
567 Cardinal numTransferEntries;
568 int posOffsetX, posOffsetY;
574 printf("dndTransferStart: transfer method = %s\n",
575 transfer->methods->name);
578 * If the operation is a move but not registered for a move
579 * then force it to a copy drop.
582 if ((xmDropInfo->operation == XmDROP_MOVE) &&
583 !(dtDropInfo->operations & XmDROP_MOVE)) {
584 xmDropInfo->operation = XmDROP_COPY;
588 * Determine icon adjustment to drop position
591 _DtDndGetIconOffset(xmDropInfo->dragContext,
592 transfer->methods->sourceType,
593 &posOffsetX, &posOffsetY);
596 * Initialize drop transfer info
599 transferInfo = (DtTransferInfo *)XtMalloc(sizeof(DtTransferInfo));
601 transferInfo->dragContext = xmDropInfo->dragContext;
602 transferInfo->protocol = transfer->methods->protocol;
603 transferInfo->operation = xmDropInfo->operation;
604 transferInfo->methods = transfer->methods;
605 transferInfo->transferTargets = NULL;
606 transferInfo->numTransferTargets = 0;
607 transferInfo->currentTransfer = 0;
608 transferInfo->appTransferCalled = False;
609 transferInfo->event = xmDropInfo->event;
610 transferInfo->x = xmDropInfo->x + posOffsetX;
611 transferInfo->y = xmDropInfo->y + posOffsetY;
612 transferInfo->clientData = NULL;
615 * Initialize drop data
618 dropData = (DtDndContext *)XtCalloc(1,sizeof(DtDndContext));
620 dropData->protocol = transferInfo->protocol;
623 * Initialize drop transfer fields of DtDropInfo
626 dtDropInfo->transferInfo = transferInfo;
627 dtDropInfo->dropData = dropData;
628 dtDropInfo->status = DtDND_SUCCESS;
631 * Get protocol specific transfer targets
634 (*transferInfo->methods->transferTargets)(dtDropInfo,
635 exportTargets, numExportTargets,
636 &transferTargets, &numTransferTargets);
638 if (transferTargets == NULL) {
640 XtFree((char *)dtDropInfo->transferInfo);
641 XtFree((char *)dtDropInfo->dropData);
643 dtDropInfo->transferInfo = NULL;
644 dtDropInfo->dropData = NULL;
645 dtDropInfo->status = DtDND_FAILURE;
647 dndTransferStartFailed(xmDropInfo->dragContext);
652 * Convert _SUN_ENUMERATION_COUNT if available
653 * Insert into transfer targets list
655 owCompat = XmTargetsAreCompatible(display,
656 exportTargets, numExportTargets,
657 &XA_SUN_ENUM_COUNT, 1);
660 Cardinal jj, numTargets;
663 numTargets = numTransferTargets + 1;
664 targets = (Atom *)XtMalloc(numTargets * sizeof(Atom));
667 targets[jj++] = XA_SUN_ENUM_COUNT;
669 for (ii = 0; ii < numTransferTargets; ii++, jj++) {
670 targets[jj] = transferTargets[ii];
673 XtFree((char *)transferTargets);
675 transferTargets = targets;
676 numTransferTargets = numTargets;
680 * Create a transfer entries list from the transfer targets
683 numTransferEntries = numTransferTargets;
684 transferEntries = (XmDropTransferEntryRec *)
685 XtMalloc(numTransferEntries * sizeof(XmDropTransferEntryRec));
687 for (ii = 0; ii < numTransferEntries; ii++) {
688 transferEntries[ii].target = transferTargets[ii];
689 transferEntries[ii].client_data = (XtPointer)dtDropInfo;
692 transferInfo->transferTargets = transferTargets;
693 transferInfo->numTransferTargets = numTransferTargets;
696 printf("Requesting transfers: ");
697 _DtDndPrintTargets(display,transferTargets,numTransferTargets);
701 * Start the drop transfer
704 dropAnimateCbRec[0].closure = (XtPointer) dtDropInfo;
705 transferInfo->dropAnimateCallback
706 = _DtDndCopyCallbackList(dropAnimateCbRec);
708 XtSetArg(args[nn], XmNdropTransfers, transferEntries); nn++;
709 XtSetArg(args[nn], XmNnumDropTransfers, numTransferEntries);nn++;
710 XtSetArg(args[nn], XmNtransferProc, dndTransferProc); nn++;
711 XtSetArg(args[nn], XmNdestroyCallback, transferInfo->dropAnimateCallback); nn++;
713 (void)XmDropTransferStart(xmDropInfo->dragContext, args, nn);
715 XtFree((char *)transferEntries);
721 * Process the transfers
726 XtPointer clientData,
730 unsigned long * length,
733 DtDropInfo * dtDropInfo = (DtDropInfo *)clientData;
734 DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
739 * Ignore if no dtDropInfo or failed transfer
740 * Ignore null transfer (which are responses to DELETE)
743 if (value == NULL || dtDropInfo == NULL ||
744 dtDropInfo->status == DtDND_FAILURE) {
745 dndTransferFail(dtDropInfo, dropTransfer);
748 } else if (*type == XA_NULL) {
754 * Determine current transfer target
757 index = transferInfo->currentTransfer;
759 if (index < transferInfo->numTransferTargets) {
760 target = transferInfo->transferTargets[index];
764 transferInfo->currentTransfer++;
768 Display *display = XtDisplayOfObject(dropTransfer);
769 char *targetname = XGetAtomName(display,target);
770 char *typename = XGetAtomName(display,*type);
771 printf("dndTransferProc: target = %s type = %s fmt = %d len = %ld\n",
772 (targetname ? targetname : "Null"),
773 (typename ? typename : "Null"),
775 if (targetname) XFree(targetname);
776 if (typename) XFree(typename);
781 * Handle _SUN_ENUMERATION_COUNT request; reject multiple items
783 if (target == XA_SUN_ENUM_COUNT) {
784 int * enumCount = (int *)value;
785 if (enumCount[0] > 1) {
786 dndTransferFail(dtDropInfo, dropTransfer);
793 * Invoke protocol specific transfer proc
796 (*transferInfo->methods->transfer)( dropTransfer, dtDropInfo,
797 selection, &target, type, value, length, format);
800 * If the transfer failed, set up to terminate unsuccessfully
803 if (dtDropInfo->status == DtDND_FAILURE) {
804 dndTransferFail(dtDropInfo, dropTransfer);
809 * If the transfers are complete;
810 * If the dropData isn't ready then fail the transfer
811 * Otherwise call the application transfer callback
814 if (transferInfo->currentTransfer == transferInfo->numTransferTargets) {
816 if (dtDropInfo->dropData->numItems == 0) {
817 dndTransferFail(dtDropInfo, dropTransfer);
819 } else if (!transferInfo->appTransferCalled) {
820 dndAppTransfer(dropTransfer, dtDropInfo);
821 transferInfo->appTransferCalled = True;
829 * Call the application transfer callback
834 DtDropInfo * dtDropInfo)
836 DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
837 DtDndTransferCallbackStruct transferCallData;
840 * If the transfer failed or there isn't a callback simply return
843 if (dtDropInfo->status == DtDND_FAILURE ||
844 dtDropInfo->dropTransferCallback == NULL) {
849 * Fill in the callback structure and call the
850 * application-defined dropTransferCallback.
853 transferCallData.reason = DtCR_DND_TRANSFER_DATA;
854 transferCallData.event = transferInfo->event;
855 transferCallData.x = transferInfo->x;
856 transferCallData.y = transferInfo->y;
857 transferCallData.operation = transferInfo->operation;
858 transferCallData.dropData = dtDropInfo->dropData;
859 transferCallData.dragContext = transferInfo->dragContext;
860 transferCallData.status = DtDND_SUCCESS;
862 if (transferInfo->operation == XmDROP_MOVE) {
863 transferCallData.completeMove = True;
865 transferCallData.completeMove = False;
868 _DtDndCallCallbackList(dtDropInfo->dropReceiver,
869 dtDropInfo->dropTransferCallback,
870 (XtPointer)&transferCallData);
872 dtDropInfo->status = transferCallData.status;
875 * If the app requests it then fail the transfer
877 if (transferCallData.status == DtDND_FAILURE) {
878 dndTransferFail(dtDropInfo, dropTransfer);
883 * If the transfer succeeded and this is a move operation
884 * then transfer DELETE to delete the original.
887 if (transferCallData.status == DtDND_SUCCESS &&
888 transferCallData.completeMove &&
889 transferInfo->operation == XmDROP_MOVE) {
891 XmDropTransferEntryRec transferEntries[1];
893 transferEntries[0].target = XA_DELETE;
894 transferEntries[0].client_data = (XtPointer)dtDropInfo;
896 XmDropTransferAdd(dropTransfer, transferEntries, 1);
901 * dndDropAnimateCallback
903 * Call the application dropAnimateCallback
906 dndDropAnimateCallback(
908 XtPointer clientData,
911 DtDropInfo * dtDropInfo = (DtDropInfo *)clientData;
912 DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
913 DtDndDropAnimateCallbackStruct dropAnimateCallData;
916 * Fill in the callback structure and call the
917 * application-defined dropAnimateCallback.
920 if (dtDropInfo->status == DtDND_SUCCESS &&
921 dtDropInfo->dropAnimateCallback != NULL) {
923 dropAnimateCallData.reason = DtCR_DND_DROP_ANIMATE;
924 dropAnimateCallData.event = transferInfo->event;
925 dropAnimateCallData.x = transferInfo->x;
926 dropAnimateCallData.y = transferInfo->y;
927 dropAnimateCallData.operation = transferInfo->operation;
928 dropAnimateCallData.dropData = dtDropInfo->dropData;
930 _DtDndCallCallbackList(dtDropInfo->dropReceiver,
931 dtDropInfo->dropAnimateCallback,
932 (XtPointer)&dropAnimateCallData);
936 * Invoke the protocol specific transfer finish proc
939 (*transferInfo->methods->transferFinish)(dtDropInfo);
942 * Free transfer created memory
944 XtFree((char *)dtDropInfo->transferInfo->transferTargets);
945 XtFree((char *)dtDropInfo->transferInfo->dropAnimateCallback);
946 XtFree((char *)dtDropInfo->transferInfo);
947 XtFree((char *)dtDropInfo->dropData);
949 dtDropInfo->transferInfo = NULL;
950 dtDropInfo->dropData = NULL;
956 * Destroy callback unregisters the widget being destroyed as a drop site
961 XtPointer clientData,
964 DtDndDropUnregister(widget);
970 * Returns a pixmap to use as the XID for Save/Find Context
976 static XID contextXID;
979 if (contextXID == NULL) {
980 contextXID = XCreatePixmap(display,
981 DefaultRootWindow(display), 1, 1, 1);
983 _DtSvcProcessUnlock();
990 * Saves the DtDropInfo relative to the dropReceiver
996 DtDropInfo * dtDropInfo)
1000 status = XSaveContext(display, dndGetContextXID(display),
1001 (XContext)dropReceiver, (XPointer)dtDropInfo);
1003 return (status == 0);
1009 * Finds the DtDropInfo saved relative to the dropReceiver
1014 Widget dropReceiver)
1017 DtDropInfo * dtDropInfo;
1019 status = XFindContext(display, dndGetContextXID(display),
1020 (XContext)dropReceiver, (XPointer *)&dtDropInfo);
1023 dtDropInfo = (DtDropInfo *)NULL;
1029 * dndTransferStartFailed
1031 * Fail the transfer by starting a 'failure' transfer
1032 * Calls XmDropTransferStart()
1035 dndTransferStartFailed(
1041 XtSetArg(args[nn], XmNtransferStatus, XmTRANSFER_FAILURE); nn++;
1042 XtSetArg(args[nn], XmNnumDropTransfers, 0); nn++;
1044 XmDropTransferStart(dragContext, args, nn);
1050 * Fail the transfer by setting the dropTransfer widget to failure
1051 * Assumes XmDropTransferStart() already called.
1055 DtDropInfo * dtDropInfo,
1056 Widget dropTransfer)
1059 dtDropInfo->status = DtDND_FAILURE;
1061 XtVaSetValues(dropTransfer,
1062 XmNtransferStatus, XmTRANSFER_FAILURE,
1063 XmNnumDropTransfers, 0,