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 /* $TOG: Dnd.c /main/7 1998/10/23 13:47:10 mgreess $ */
24 /*********************************************************************
28 * Description: Implemenation of DND Convenience API.
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.
56 #include <sys/utsname.h>
57 #include <X11/Intrinsic.h>
59 #include <Xm/DragDrop.h>
60 #include <Xm/DropTrans.h>
61 #include <Xm/AtomMgr.h>
62 #include <Dt/UserMsg.h>
65 #include "DtSvcLock.h"
67 /*********************************************************************
69 * Data Transfer Selection Targets
71 *********************************************************************/
80 Atom XA_SUN_FILE_HOST_NAME;
81 Atom XA_SUN_ENUM_COUNT;
82 Atom XA_SUN_DATA_LABEL;
83 Atom XA_SUN_SELN_READONLY;
84 Atom XA_SUN_ATM_FILE_NAME;
85 Atom XA_SUN_ATM_METHODS;
92 if (XA_TARGETS != 0) {
93 _DtSvcProcessUnlock();
97 XA_TARGETS = DtGetAtom(dpy,"TARGETS");
98 XA_TIMESTAMP = DtGetAtom(dpy,"TIMESTAMP");
99 XA_MULTIPLE = DtGetAtom(dpy,"MULTIPLE");
100 XA_DELETE = DtGetAtom(dpy,"DELETE");
101 XA_NULL = DtGetAtom(dpy,"NULL");
102 XA_TEXT = DtGetAtom(dpy,"TEXT");
103 XA_HOST_NAME = DtGetAtom(dpy,"HOST_NAME");
104 XA_SUN_FILE_HOST_NAME = DtGetAtom(dpy,"_SUN_FILE_HOST_NAME");
105 XA_SUN_ENUM_COUNT = DtGetAtom(dpy,"_SUN_ENUMERATION_COUNT");
106 XA_SUN_DATA_LABEL = DtGetAtom(dpy,"_SUN_DATA_LABEL");
107 XA_SUN_SELN_READONLY = DtGetAtom(dpy,"_SUN_SELN_IS_READONLY");
108 XA_SUN_ATM_FILE_NAME = DtGetAtom(dpy,"_SUN_ATM_FILE_NAME");
109 XA_SUN_ATM_METHODS = DtGetAtom(dpy,
110 "_SUN_ALTERNATE_TRANSPORT_METHODS");
111 _DtSvcProcessUnlock();
114 /*********************************************************************
116 * Data Transfer Protocol Method Functions
118 *********************************************************************/
120 static DtDndProtocol dndProtocolList[] = {
121 DtDND_FILENAME_TRANSFER,
122 DtDND_BUFFER_TRANSFER,
127 extern DtDndMethods *_DtDndBuffTransferProtocolInitialize(Display*);
128 extern DtDndMethods *_DtDndFileTransferProtocolInitialize(Display*);
129 extern DtDndMethods *_DtDndTextTransferProtocolInitialize(Display*);
132 * dndGetTransferMethods
134 * Return the transfer methods for a particular protocol
136 static DtDndMethods *
137 dndGetTransferMethods(
139 DtDndProtocol protocol)
141 DtDndMethods * methods = NULL;
144 case DtDND_BUFFER_TRANSFER:
145 methods = _DtDndBuffTransferProtocolInitialize(display);
147 case DtDND_FILENAME_TRANSFER:
148 methods = _DtDndFileTransferProtocolInitialize(display);
150 case DtDND_TEXT_TRANSFER:
151 methods = _DtDndTextTransferProtocolInitialize(display);
159 * _DtDndCreateExportTransfer
161 * Returns a transfer suitable for use by a drag initiator
164 _DtDndCreateExportTransfer(
165 DtDragInfo * dtDragInfo)
167 Display * dpy = XtDisplayOfObject(dtDragInfo->dragInitiator);
168 DtDndTransfer * transfer;
172 transfer = (DtDndTransfer *)XtMalloc(sizeof(DtDndTransfer));
174 transfer->methods = dndGetTransferMethods(dpy,dtDragInfo->protocol);
176 (*transfer->methods->getExportTargets)(dtDragInfo,
177 &(transfer->targets), &(transfer->numTargets));
183 * _DtDndCreateImportTransfers
185 * Create the list of transfers specified by the protocols.
188 _DtDndCreateImportTransfers(
189 DtDropInfo * dtDropInfo,
190 Cardinal * numTransfers)
192 Display * dpy = XtDisplayOfObject(dtDropInfo->dropReceiver);
193 DtDndTransfer * transfers;
194 DtDndTransfer * transfer;
201 for (ii = 0; dndProtocolList[ii] != DtDND_NOOP_TRANSFER; ii++) {
202 if (dtDropInfo->protocols & dndProtocolList[ii]) {
207 if (*numTransfers == 0)
208 return (DtDndTransfer *)NULL;
210 transfers = (DtDndTransfer *)XtMalloc(
211 *numTransfers * sizeof(DtDndTransfer));
213 for (ii = 0, jj = 0; dndProtocolList[ii] != DtDND_NOOP_TRANSFER; ii++) {
214 if (dtDropInfo->protocols & dndProtocolList[ii]) {
215 transfer = &transfers[jj++];
217 dndGetTransferMethods(dpy,dndProtocolList[ii]);
218 (*transfer->methods->getImportTargets)(dtDropInfo,
219 &(transfer->targets), &(transfer->numTargets));
227 * _DtDndDestroyTransfers
229 * Destroy the transfer list created by
230 * _DtDndCreateExportTransfer() or _DtDndCreateImportTransfers()
233 _DtDndDestroyTransfers(
234 DtDndTransfer * transfers,
235 Cardinal numTransfers)
240 for (ii = 0; ii < numTransfers; ii++) {
241 XtFree((char *)transfers[ii].targets);
243 XtFree((char *)transfers);
247 * _DtDndTransferFromTargets
249 * Returns the transfer method that matches the target list
252 _DtDndTransferFromTargets(
253 DtDndTransfer * transfers,
254 Cardinal numTransfers,
260 for (ii = 0; ii < numTransfers; ii++) {
261 for (jj = 0; jj < transfers[ii].numTargets; jj++) {
262 for (kk = 0; kk < numTargets; kk++) {
263 if (transfers[ii].targets[jj] == targets[kk]) {
264 return &transfers[ii];
269 return (DtDndTransfer *)NULL;
275 * Add the targets to the requested transfer targets list
276 * and call XmDropTransferAdd() to request them
281 DtDropInfo * dtDropInfo,
282 Atom * transferTargets,
283 Cardinal numTransferTargets)
285 DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
286 XmDropTransferEntryRec * transferEntries;
287 Cardinal numTransfers;
290 transferEntries = (XmDropTransferEntryRec *)
291 XtMalloc(numTransferTargets * sizeof(XmDropTransferEntryRec));
293 numTransfers = transferInfo->numTransferTargets + numTransferTargets;
295 transferInfo->transferTargets = (Atom *)XtRealloc(
296 (char *)transferInfo->transferTargets,
297 numTransfers * sizeof(Atom));
299 jj = transferInfo->numTransferTargets;
301 for (ii = 0; ii < numTransferTargets; ii++) {
302 transferEntries[ii].target = transferTargets[ii];
303 transferEntries[ii].client_data = (XtPointer)dtDropInfo;
305 transferInfo->transferTargets[ii+jj] = transferTargets[ii];
308 transferInfo->numTransferTargets = numTransfers;
310 XmDropTransferAdd(dropTransfer, transferEntries, numTransferTargets);
312 XtFree((char *)transferEntries);
315 /*********************************************************************
317 * Misc Debugging Functions
319 *********************************************************************/
331 for (ii = 0; ii < numTargets; ii++) {
332 name = XGetAtomName(display, targets[ii]);
344 _DtDndPrintTransfers(
346 DtDndTransfer *transfers,
347 Cardinal numTransfers)
351 for (ii = 0; ii < numTransfers; ii++) {
352 printf("%s\tTargets: ",transfers[ii].methods->name);
353 _DtDndPrintTargets(display,
354 transfers[ii].targets,transfers[ii].numTargets);
359 /*********************************************************************
361 * Misc Utility Functions
363 *********************************************************************/
369 _DtDndCopyCallbackList(
370 XtCallbackList callbacks)
375 if (callbacks == NULL)
379 for (cl = callbacks; cl->callback != NULL; cl++) {
383 cl = (XtCallbackList)XtMalloc(count * sizeof(XtCallbackRec));
385 for (ii = 0; ii < count; ii++) {
386 cl[ii].callback = callbacks[ii].callback;
387 cl[ii].closure = callbacks[ii].closure;
397 _DtDndCallCallbackList(
399 XtCallbackList callbacks,
404 if (callbacks == NULL)
407 for (cl = callbacks; cl->callback != NULL; cl++) {
408 (*cl->callback)(widget, cl->closure, calldata);
413 * Misc Varargs Utility Functions
424 for (argPtr = va_arg(vaList,String);
426 argPtr = va_arg(vaList,String)) {
428 va_arg(vaList, XtArgVal);
436 _DtDndArgListFromVarArgs(
439 ArgList *argListReturn,
440 Cardinal *argCountReturn)
448 *argListReturn = NULL;
453 argList = (ArgList)XtMalloc((unsigned)(maxArgs * sizeof(Arg)));
456 for (argPtr = va_arg(vaList,String);
458 argPtr = va_arg(vaList,String)) {
460 XtSetArg(argList[argCount], argPtr, va_arg(vaList,XtArgVal));
464 *argListReturn = argList;
465 *argCountReturn = argCount;
469 * Returns the network node/host name.
472 _DtDndGetHostName(void)
474 static char *nodename;
477 if (nodename == NULL) {
480 if (uname(&un) == -1) {
481 _DtSimpleError(DtProgName,DtError, NULL, "uname", NULL);
482 nodename = XtNewString("nodename");
484 nodename = XtNewString(un.nodename);
487 _DtSvcProcessUnlock();