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: DndDrop.c /main/6 1996/09/27 19:00:45 drk $ */
24 /*********************************************************************
28 * Description: Implementation of DND Drop Registration
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>
60 #include <Xm/DropSMgr.h>
61 #include <Xm/DropTrans.h>
64 #include "DtSvcLock.h"
67 * Drop Receiver Callbacks
70 static void dndDropProc(Widget, XtPointer, XtPointer);
71 static void dndTransferStart(Widget, XmDropProcCallbackStruct*,
72 DtDropInfo*, DtDndTransfer*, Atom*, Cardinal);
73 static void dndTransferProc(Widget, XtPointer, Atom*, Atom*,
74 XtPointer, unsigned long*, int*);
75 static void dndAppTransfer(Widget, DtDropInfo*);
76 static void dndDropAnimateCallback(Widget, XtPointer, XtPointer);
79 * Drop Support Functions
82 static void dndDropSiteDestroy(Widget, XtPointer, XtPointer);
83 static XID dndGetContextXID(Display*);
84 static Boolean dndSaveDropInfo(Display*, Widget, DtDropInfo*);
85 static DtDropInfo * dndFindDropInfo(Display*, Widget);
86 static void dndTransferStartFailed(Widget);
87 static void dndTransferFail(DtDropInfo*, Widget);
90 * Drop Register Resources
94 XtCallbackList dropAnimateCallback;
95 Boolean preserveRegistration;
96 Boolean registerChildren;
100 #define Offset(field) XtOffsetOf(DropSettings, field)
102 static XtResource dropResources[] = {
103 { DtNdropAnimateCallback, DtCDropAnimateCallback,
104 XtRCallback, sizeof(XtCallbackList), Offset(dropAnimateCallback),
105 XtRImmediate, (XtPointer)NULL },
106 { DtNpreserveRegistration, DtCPreserveRegistration,
107 XtRBoolean, sizeof(Boolean), Offset(preserveRegistration),
108 XtRImmediate, (XtPointer)True },
109 { DtNregisterChildren, DtCRegisterChildren,
110 XtRBoolean, sizeof(Boolean), Offset(registerChildren),
111 XtRImmediate, (XtPointer)False },
112 { DtNtextIsBuffer, DtCTextIsBuffer,
113 XtRBoolean, sizeof(Boolean), Offset(textIsBuffer),
114 XtRImmediate, (XtPointer)False },
117 extern int _DtDndCountVarArgs(va_list vaList);
118 extern void _DtDndArgListFromVarArgs(va_list vaList,
120 ArgList *argListReturn,
121 Cardinal *argCountReturn);
128 * DtDndVaDropRegister
130 * Drop Site Registration - varargs version
136 DtDndProtocol protocols,
137 unsigned char operations,
138 XtCallbackList transferCallback,
144 _DtSvcWidgetToAppContext(dropReceiver);
147 va_start(vaList, transferCallback);
148 argCount = _DtDndCountVarArgs(vaList);
151 va_start(vaList, transferCallback);
152 _DtDndArgListFromVarArgs(vaList, argCount, &argList, &argCount);
155 DtDndDropRegister(dropReceiver, protocols, operations,
156 transferCallback, argList, argCount);
158 XtFree((char *)argList);
159 _DtSvcAppUnlock(app);
165 * Drop Site Registration - arglist version
171 DtDndProtocol protocols,
172 unsigned char operations,
173 XtCallbackList dropTransferCallback,
177 Display * display = XtDisplayOfObject(dropReceiver);
178 DropSettings settings;
179 DtDropInfo * dtDropInfo;
180 DtDropSiteInfo* dsInfo = NULL;
181 DtDndTransfer * transfers;
182 Cardinal numTransfers;
184 Cardinal numImportTargets;
185 unsigned char mergedOperations;
188 _DtSvcWidgetToAppContext(dropReceiver);
193 * Reject a noop registration
195 if (protocols == DtDND_NOOP_TRANSFER) {
196 _DtSvcAppUnlock(app);
201 * Parse resources into dropResources
203 XtGetSubresources(dropReceiver, &settings,
204 (String)NULL, (String)NULL,
205 dropResources, XtNumber(dropResources),
208 * Initialize DropInfo
211 dtDropInfo = (DtDropInfo *) XtMalloc(sizeof(DtDropInfo));
213 dtDropInfo->dropReceiver = dropReceiver;
214 dtDropInfo->protocols = protocols;
215 dtDropInfo->operations = operations;
216 dtDropInfo->textIsBuffer = settings.textIsBuffer;
217 dtDropInfo->dropSiteInfo = NULL;
218 dtDropInfo->transferInfo = NULL;
219 dtDropInfo->status = DtDND_SUCCESS;
221 dtDropInfo->dropTransferCallback
222 = _DtDndCopyCallbackList(dropTransferCallback);
223 dtDropInfo->dropAnimateCallback
224 = _DtDndCopyCallbackList(settings.dropAnimateCallback);
227 * Initialize Transfer Methods
230 transfers = _DtDndCreateImportTransfers(dtDropInfo, &numTransfers);
232 dtDropInfo->transfers = transfers;
233 dtDropInfo->numTransfers = numTransfers;
236 printf("DtDndDropRegister: registering widget 0x%p\n", dropReceiver);
237 _DtDndPrintTransfers(display,transfers,numTransfers);
241 * Preserve existing drop registration info if requested
244 if (settings.preserveRegistration) {
247 dsInfo = (DtDropSiteInfo *)XtMalloc(sizeof(DtDropSiteInfo));
249 dsInfo->dropProc = (XtCallbackProc)NULL;
250 dsInfo->operations = XmDROP_NOOP;
251 dsInfo->importTargets = NULL;
252 dsInfo->numImportTargets = 0;
256 XtSetArg(pArgs[nn], XmNimportTargets,
257 &(dsInfo->importTargets)); nn++;
258 XtSetArg(pArgs[nn], XmNdropSiteOperations,
259 &(dsInfo->operations)); nn++;
260 XtSetArg(pArgs[nn], XmNnumImportTargets,
261 &(dsInfo->numImportTargets)); nn++;
262 XtSetArg(pArgs[nn], XmNdropProc,
263 &(dsInfo->dropProc)); nn++;
265 XmDropSiteRetrieve(dropReceiver, pArgs, nn);
267 if ( (dsInfo->dropProc != NULL) &&
268 (dsInfo->numImportTargets > 0) &&
269 (dsInfo->operations != XmDROP_NOOP) ){
271 dtDropInfo->dropSiteInfo = dsInfo;
273 XtFree((char *)dsInfo);
279 * Create list of import targets based on the requested transfer
280 * protocols and any preserved drop site registration.
283 numImportTargets = 0;
285 for (ii = 0; ii < numTransfers; ii++) {
286 numImportTargets += transfers[ii].numTargets;
289 if (dsInfo != NULL) {
290 numImportTargets += dsInfo->numImportTargets;
293 importTargets = (Atom *) XtMalloc(numImportTargets * sizeof(Atom));
296 for (ii = 0; ii < numTransfers; ii++) {
297 for (jj = 0; jj < transfers[ii].numTargets; jj++) {
298 importTargets[kk++] = transfers[ii].targets[jj];
302 if (dsInfo != NULL) {
303 for (jj = 0; jj < dsInfo->numImportTargets; jj++) {
304 importTargets[kk++] = dsInfo->importTargets[jj];
312 if (dsInfo != NULL) {
313 mergedOperations = dsInfo->operations | operations;
315 mergedOperations = operations;
319 * Create an argument list
322 #define NUM_DROP_ARGS 5
323 args = (Arg *) XtMalloc(sizeof(Arg) * (NUM_DROP_ARGS + argCount));
327 * Copy in passed arguments
332 for (ii = 0; ii < argCount; ii++) {
333 XtSetArg(args[nn], argList[ii].name, argList[ii].value); nn++;
337 * Set argument list for drop site registration
340 XtSetArg(args[nn], XmNimportTargets, importTargets); nn++;
341 XtSetArg(args[nn], XmNnumImportTargets, numImportTargets); nn++;
342 XtSetArg(args[nn], XmNdropSiteOperations, mergedOperations); nn++;
343 XtSetArg(args[nn], XmNdropProc, dndDropProc); nn++;
345 if (settings.registerChildren) {
346 XtSetArg(args[nn], XmNdropSiteType, XmDROP_SITE_COMPOSITE); nn++;
350 * Register the drop site
353 if (dsInfo != NULL) {
354 XmDropSiteUnregister(dropReceiver);
355 XmDropSiteRegister(dropReceiver, args, nn);
357 XmDropSiteRegister(dropReceiver, args, nn);
361 * Add a destroy callback to unregister the drop site
362 * Store the dropInfo using the dropReceiver as the context
363 * Free locally allocated memory
366 XtAddCallback(dropReceiver, XtNdestroyCallback,
367 dndDropSiteDestroy, NULL);
369 (void)dndSaveDropInfo(display, dropReceiver, dtDropInfo);
371 XtFree((char *)importTargets);
372 XtFree((char *)args);
373 _DtSvcAppUnlock(app);
377 * DtDndDropUnregister
379 * Unregister the drop site
385 Display *display = XtDisplayOfObject(dropReceiver);
386 DtDropInfo *dtDropInfo;
387 DtDropSiteInfo *dsInfo;
388 _DtSvcWidgetToAppContext(dropReceiver);
393 * Retrieve dropInfo. If there isn't one then the drop site
394 * was not registered by DtDndDropRegister() so return.
397 if ((dtDropInfo = dndFindDropInfo(display, dropReceiver)) == NULL) {
398 _DtSvcAppUnlock(app);
401 dsInfo = dtDropInfo->dropSiteInfo;
404 * Unregister the drop site
407 XmDropSiteUnregister(dropReceiver);
410 * If we have preserved drop site registration
411 * then restore the drop site to it's original state.
414 if (dsInfo != NULL) {
418 XtSetArg(args[nn], XmNimportTargets,
419 dsInfo->importTargets); nn++;
420 XtSetArg(args[nn], XmNnumImportTargets,
421 dsInfo->numImportTargets); nn++;
422 XtSetArg(args[nn], XmNdropProc,
423 dsInfo->dropProc); nn++;
424 XtSetArg(args[nn], XmNdropSiteOperations,
425 dsInfo->operations); nn++;
427 XmDropSiteRegister(dropReceiver, args, nn);
429 XtFree((char *)dsInfo);
433 * Free callback, context and memory associated with DtDndDropRegister
436 XtRemoveCallback(dropReceiver, XtNdestroyCallback,
437 dndDropSiteDestroy, NULL);
439 XDeleteContext(display, dndGetContextXID(display),
440 (XContext)(intptr_t)dropReceiver);
442 _DtDndDestroyTransfers(dtDropInfo->transfers, dtDropInfo->numTransfers);
444 XtFree((char *)dtDropInfo->dropTransferCallback);
445 XtFree((char *)dtDropInfo->dropAnimateCallback);
446 XtFree((char *)dtDropInfo);
447 _DtSvcAppUnlock(app);
451 /*********************************************************************
453 * Drop Receiver Callbacks
455 *********************************************************************/
461 * Determine transfer target and operation and initiate transfer.
466 XtPointer clientData,
469 XmDropProcCallbackStruct *xmDropInfo =
470 (XmDropProcCallbackStruct *) callData;
471 Display * display = XtDisplayOfObject(dropReceiver);
473 Atom * exportTargets = NULL;
474 Cardinal numExportTargets = 0;
475 DtDropInfo * dtDropInfo;
476 DtDropSiteInfo* dsInfo;
477 DtDndTransfer * transfer;
480 * Reject invalid drops
483 if ( (xmDropInfo->dropSiteStatus != XmDROP_SITE_VALID) ||
484 (xmDropInfo->operation == XmDROP_NOOP) ||
485 (xmDropInfo->dropAction != XmDROP) ) {
488 printf("dndDropProc: failed drop status or operation\n");
490 dndTransferStartFailed(xmDropInfo->dragContext);
495 * Get the cached DropInfo
498 if ((dtDropInfo = dndFindDropInfo(display, dropReceiver)) == NULL) {
499 dndTransferStartFailed(xmDropInfo->dragContext);
504 * Get the export targets from the dragContext
507 XtVaGetValues(xmDropInfo->dragContext,
508 XmNexportTargets, &exportTargets,
509 XmNnumExportTargets, &numExportTargets,
512 if (exportTargets == NULL) {
513 dndTransferStartFailed(xmDropInfo->dragContext);
514 dtDropInfo->status = DtDND_FAILURE;
519 printf("dndDropProc: Export Targets: ");
520 _DtDndPrintTargets(display,exportTargets,numExportTargets);
524 * Search the DnD protocol import targets list to see
525 * if it's a target we handle. If it is then start our transfer.
528 transfer = _DtDndTransferFromTargets(
529 dtDropInfo->transfers, dtDropInfo->numTransfers,
530 exportTargets, numExportTargets);
532 if (transfer != NULL) {
534 dndTransferStart(dropReceiver, xmDropInfo, dtDropInfo,
535 transfer, exportTargets, numExportTargets);
540 * If there isn't any alternate drop registration
541 * then fail the transfer
544 dsInfo = dtDropInfo->dropSiteInfo;
546 if (dsInfo == NULL) {
547 dndTransferStartFailed(xmDropInfo->dragContext);
548 dtDropInfo->status = DtDND_FAILURE;
553 * Determine if the exportTargets are compatible with
554 * the alternate drop registration targets
555 * If they are not compatible then fail the transfer
556 * Otherwise call the original dropProc.
559 compatible = XmTargetsAreCompatible(display,
560 dsInfo->importTargets, dsInfo->numImportTargets,
561 exportTargets, numExportTargets);
564 dndTransferStartFailed(xmDropInfo->dragContext);
565 dtDropInfo->status = DtDND_FAILURE;
569 if (dsInfo->dropProc != NULL) {
570 (*(dsInfo->dropProc))(dropReceiver, clientData, callData);
577 * Start the transfer using protocol specific transfer entries
583 XmDropProcCallbackStruct *xmDropInfo,
584 DtDropInfo * dtDropInfo,
585 DtDndTransfer * transfer,
586 Atom * exportTargets,
587 Cardinal numExportTargets)
589 XtCallbackRec dropAnimateCbRec[] = { {dndDropAnimateCallback,
590 NULL}, {NULL, NULL} };
591 Display * display = XtDisplayOfObject(dropReceiver);
592 DtDndContext * dropData;
593 DtTransferInfo *transferInfo;
594 Atom * transferTargets;
595 Cardinal numTransferTargets;
597 XmDropTransferEntryRec * transferEntries;
598 Cardinal numTransferEntries;
599 int posOffsetX, posOffsetY;
605 printf("dndTransferStart: transfer method = %s\n",
606 transfer->methods->name);
609 * If the operation is a move but not registered for a move
610 * then force it to a copy drop.
613 if ((xmDropInfo->operation == XmDROP_MOVE) &&
614 !(dtDropInfo->operations & XmDROP_MOVE)) {
615 xmDropInfo->operation = XmDROP_COPY;
619 * Determine icon adjustment to drop position
622 _DtDndGetIconOffset(xmDropInfo->dragContext,
623 transfer->methods->sourceType,
624 &posOffsetX, &posOffsetY);
627 * Initialize drop transfer info
630 transferInfo = (DtTransferInfo *)XtMalloc(sizeof(DtTransferInfo));
632 transferInfo->dragContext = xmDropInfo->dragContext;
633 transferInfo->protocol = transfer->methods->protocol;
634 transferInfo->operation = xmDropInfo->operation;
635 transferInfo->methods = transfer->methods;
636 transferInfo->transferTargets = NULL;
637 transferInfo->numTransferTargets = 0;
638 transferInfo->currentTransfer = 0;
639 transferInfo->appTransferCalled = False;
640 transferInfo->event = xmDropInfo->event;
641 transferInfo->x = xmDropInfo->x + posOffsetX;
642 transferInfo->y = xmDropInfo->y + posOffsetY;
643 transferInfo->clientData = NULL;
646 * Initialize drop data
649 dropData = (DtDndContext *)XtCalloc(1,sizeof(DtDndContext));
651 dropData->protocol = transferInfo->protocol;
654 * Initialize drop transfer fields of DtDropInfo
657 dtDropInfo->transferInfo = transferInfo;
658 dtDropInfo->dropData = dropData;
659 dtDropInfo->status = DtDND_SUCCESS;
662 * Get protocol specific transfer targets
665 (*transferInfo->methods->transferTargets)(dtDropInfo,
666 exportTargets, numExportTargets,
667 &transferTargets, &numTransferTargets);
669 if (transferTargets == NULL) {
671 XtFree((char *)dtDropInfo->transferInfo);
672 XtFree((char *)dtDropInfo->dropData);
674 dtDropInfo->transferInfo = NULL;
675 dtDropInfo->dropData = NULL;
676 dtDropInfo->status = DtDND_FAILURE;
678 dndTransferStartFailed(xmDropInfo->dragContext);
683 * Convert _SUN_ENUMERATION_COUNT if available
684 * Insert into transfer targets list
686 owCompat = XmTargetsAreCompatible(display,
687 exportTargets, numExportTargets,
688 &XA_SUN_ENUM_COUNT, 1);
691 Cardinal jj, numTargets;
694 numTargets = numTransferTargets + 1;
695 targets = (Atom *)XtMalloc(numTargets * sizeof(Atom));
698 targets[jj++] = XA_SUN_ENUM_COUNT;
700 for (ii = 0; ii < numTransferTargets; ii++, jj++) {
701 targets[jj] = transferTargets[ii];
704 XtFree((char *)transferTargets);
706 transferTargets = targets;
707 numTransferTargets = numTargets;
711 * Create a transfer entries list from the transfer targets
714 numTransferEntries = numTransferTargets;
715 transferEntries = (XmDropTransferEntryRec *)
716 XtMalloc(numTransferEntries * sizeof(XmDropTransferEntryRec));
718 for (ii = 0; ii < numTransferEntries; ii++) {
719 transferEntries[ii].target = transferTargets[ii];
720 transferEntries[ii].client_data = (XtPointer)dtDropInfo;
723 transferInfo->transferTargets = transferTargets;
724 transferInfo->numTransferTargets = numTransferTargets;
727 printf("Requesting transfers: ");
728 _DtDndPrintTargets(display,transferTargets,numTransferTargets);
732 * Start the drop transfer
735 dropAnimateCbRec[0].closure = (XtPointer) dtDropInfo;
736 transferInfo->dropAnimateCallback
737 = _DtDndCopyCallbackList(dropAnimateCbRec);
739 XtSetArg(args[nn], XmNdropTransfers, transferEntries); nn++;
740 XtSetArg(args[nn], XmNnumDropTransfers, numTransferEntries);nn++;
741 XtSetArg(args[nn], XmNtransferProc, dndTransferProc); nn++;
742 XtSetArg(args[nn], XmNdestroyCallback, transferInfo->dropAnimateCallback); nn++;
744 (void)XmDropTransferStart(xmDropInfo->dragContext, args, nn);
746 XtFree((char *)transferEntries);
752 * Process the transfers
757 XtPointer clientData,
761 unsigned long * length,
764 DtDropInfo * dtDropInfo = (DtDropInfo *)clientData;
765 DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
770 * Ignore if no dtDropInfo or failed transfer
771 * Ignore null transfer (which are responses to DELETE)
774 if (value == NULL || dtDropInfo == NULL ||
775 dtDropInfo->status == DtDND_FAILURE) {
776 dndTransferFail(dtDropInfo, dropTransfer);
779 } else if (*type == XA_NULL) {
785 * Determine current transfer target
788 index = transferInfo->currentTransfer;
790 if (index < transferInfo->numTransferTargets) {
791 target = transferInfo->transferTargets[index];
795 transferInfo->currentTransfer++;
799 Display *display = XtDisplayOfObject(dropTransfer);
800 char *targetname = XGetAtomName(display,target);
801 char *typename = XGetAtomName(display,*type);
802 printf("dndTransferProc: target = %s type = %s fmt = %d len = %ld\n",
803 (targetname ? targetname : "Null"),
804 (typename ? typename : "Null"),
806 if (targetname) XFree(targetname);
807 if (typename) XFree(typename);
812 * Handle _SUN_ENUMERATION_COUNT request; reject multiple items
814 if (target == XA_SUN_ENUM_COUNT) {
815 int * enumCount = (int *)value;
816 if (enumCount[0] > 1) {
817 dndTransferFail(dtDropInfo, dropTransfer);
824 * Invoke protocol specific transfer proc
827 (*transferInfo->methods->transfer)( dropTransfer, dtDropInfo,
828 selection, &target, type, value, length, format);
831 * If the transfer failed, set up to terminate unsuccessfully
834 if (dtDropInfo->status == DtDND_FAILURE) {
835 dndTransferFail(dtDropInfo, dropTransfer);
840 * If the transfers are complete;
841 * If the dropData isn't ready then fail the transfer
842 * Otherwise call the application transfer callback
845 if (transferInfo->currentTransfer == transferInfo->numTransferTargets) {
847 if (dtDropInfo->dropData->numItems == 0) {
848 dndTransferFail(dtDropInfo, dropTransfer);
850 } else if (!transferInfo->appTransferCalled) {
851 dndAppTransfer(dropTransfer, dtDropInfo);
852 transferInfo->appTransferCalled = True;
860 * Call the application transfer callback
865 DtDropInfo * dtDropInfo)
867 DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
868 DtDndTransferCallbackStruct transferCallData;
871 * If the transfer failed or there isn't a callback simply return
874 if (dtDropInfo->status == DtDND_FAILURE ||
875 dtDropInfo->dropTransferCallback == NULL) {
880 * Fill in the callback structure and call the
881 * application-defined dropTransferCallback.
884 transferCallData.reason = DtCR_DND_TRANSFER_DATA;
885 transferCallData.event = transferInfo->event;
886 transferCallData.x = transferInfo->x;
887 transferCallData.y = transferInfo->y;
888 transferCallData.operation = transferInfo->operation;
889 transferCallData.dropData = dtDropInfo->dropData;
890 transferCallData.dragContext = transferInfo->dragContext;
891 transferCallData.status = DtDND_SUCCESS;
893 if (transferInfo->operation == XmDROP_MOVE) {
894 transferCallData.completeMove = True;
896 transferCallData.completeMove = False;
899 _DtDndCallCallbackList(dtDropInfo->dropReceiver,
900 dtDropInfo->dropTransferCallback,
901 (XtPointer)&transferCallData);
903 dtDropInfo->status = transferCallData.status;
906 * If the app requests it then fail the transfer
908 if (transferCallData.status == DtDND_FAILURE) {
909 dndTransferFail(dtDropInfo, dropTransfer);
914 * If the transfer succeeded and this is a move operation
915 * then transfer DELETE to delete the original.
918 if (transferCallData.status == DtDND_SUCCESS &&
919 transferCallData.completeMove &&
920 transferInfo->operation == XmDROP_MOVE) {
922 XmDropTransferEntryRec transferEntries[1];
924 transferEntries[0].target = XA_DELETE;
925 transferEntries[0].client_data = (XtPointer)dtDropInfo;
927 XmDropTransferAdd(dropTransfer, transferEntries, 1);
932 * dndDropAnimateCallback
934 * Call the application dropAnimateCallback
937 dndDropAnimateCallback(
939 XtPointer clientData,
942 DtDropInfo * dtDropInfo = (DtDropInfo *)clientData;
943 DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
944 DtDndDropAnimateCallbackStruct dropAnimateCallData;
947 * Fill in the callback structure and call the
948 * application-defined dropAnimateCallback.
951 if (dtDropInfo->status == DtDND_SUCCESS &&
952 dtDropInfo->dropAnimateCallback != NULL) {
954 dropAnimateCallData.reason = DtCR_DND_DROP_ANIMATE;
955 dropAnimateCallData.event = transferInfo->event;
956 dropAnimateCallData.x = transferInfo->x;
957 dropAnimateCallData.y = transferInfo->y;
958 dropAnimateCallData.operation = transferInfo->operation;
959 dropAnimateCallData.dropData = dtDropInfo->dropData;
961 _DtDndCallCallbackList(dtDropInfo->dropReceiver,
962 dtDropInfo->dropAnimateCallback,
963 (XtPointer)&dropAnimateCallData);
967 * Invoke the protocol specific transfer finish proc
970 (*transferInfo->methods->transferFinish)(dtDropInfo);
973 * Free transfer created memory
975 XtFree((char *)dtDropInfo->transferInfo->transferTargets);
976 XtFree((char *)dtDropInfo->transferInfo->dropAnimateCallback);
977 XtFree((char *)dtDropInfo->transferInfo);
978 XtFree((char *)dtDropInfo->dropData);
980 dtDropInfo->transferInfo = NULL;
981 dtDropInfo->dropData = NULL;
987 * Destroy callback unregisters the widget being destroyed as a drop site
992 XtPointer clientData,
995 DtDndDropUnregister(widget);
1001 * Returns a pixmap to use as the XID for Save/Find Context
1007 static XID contextXID;
1009 _DtSvcProcessLock();
1010 if (contextXID == 0) {
1011 contextXID = XCreatePixmap(display,
1012 DefaultRootWindow(display), 1, 1, 1);
1014 _DtSvcProcessUnlock();
1021 * Saves the DtDropInfo relative to the dropReceiver
1026 Widget dropReceiver,
1027 DtDropInfo * dtDropInfo)
1031 status = XSaveContext(display, dndGetContextXID(display),
1032 (XContext)(intptr_t)dropReceiver, (XPointer)dtDropInfo);
1034 return (status == 0);
1040 * Finds the DtDropInfo saved relative to the dropReceiver
1045 Widget dropReceiver)
1048 DtDropInfo * dtDropInfo;
1050 status = XFindContext(display, dndGetContextXID(display),
1051 (XContext)(intptr_t)dropReceiver, (XPointer *)&dtDropInfo);
1054 dtDropInfo = (DtDropInfo *)NULL;
1060 * dndTransferStartFailed
1062 * Fail the transfer by starting a 'failure' transfer
1063 * Calls XmDropTransferStart()
1066 dndTransferStartFailed(
1072 XtSetArg(args[nn], XmNtransferStatus, XmTRANSFER_FAILURE); nn++;
1073 XtSetArg(args[nn], XmNnumDropTransfers, 0); nn++;
1075 XmDropTransferStart(dragContext, args, nn);
1081 * Fail the transfer by setting the dropTransfer widget to failure
1082 * Assumes XmDropTransferStart() already called.
1086 DtDropInfo * dtDropInfo,
1087 Widget dropTransfer)
1090 dtDropInfo->status = DtDND_FAILURE;
1092 XtVaSetValues(dropTransfer,
1093 XmNtransferStatus, XmTRANSFER_FAILURE,
1094 XmNnumDropTransfers, 0,