DtSvc/DtUtil1: fix implicit function declarations
[oweals/cde.git] / cde / lib / DtSvc / DtUtil1 / Dnd.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /* $TOG: Dnd.c /main/7 1998/10/23 13:47:10 mgreess $ */
24  /*********************************************************************
25  *
26  *      File:           Dnd.c
27  *
28  *      Description:    Implemenation of DND Convenience API.
29  *
30  *********************************************************************
31  *
32  *+SNOTICE
33  *
34  *      RESTRICTED CONFIDENTIAL INFORMATION:
35  *      
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
42  *      Sun's request.
43  *
44  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
45  *
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.
50  *
51  *+ENOTICE
52  */
53
54 #include <stdlib.h>
55 #include <stdarg.h>
56 #include <sys/utsname.h>
57 #include <X11/Intrinsic.h> 
58 #include <Xm/Xm.h>
59 #include <Xm/DragDrop.h>
60 #include <Xm/DropTrans.h>
61 #include <Xm/AtomMgr.h>
62 #include <Dt/UserMsg.h>
63 #include "Dnd.h"
64 #include "DndP.h"
65 #include "DtSvcLock.h"
66
67 /*********************************************************************
68  *
69  * Data Transfer Selection Targets
70  *
71  *********************************************************************/
72
73 Atom    XA_TARGETS;
74 Atom    XA_TIMESTAMP;
75 Atom    XA_MULTIPLE;
76 Atom    XA_DELETE;
77 Atom    XA_NULL;
78 Atom    XA_TEXT;
79 Atom    XA_HOST_NAME;
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;
86
87 static void
88 dndInitTargets(
89         Display *dpy)
90 {
91         _DtSvcProcessLock();
92         if (XA_TARGETS != 0) {
93                 _DtSvcProcessUnlock();
94                 return;
95               }
96
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();
112 }
113
114 /*********************************************************************
115  *
116  * Data Transfer Protocol Method Functions
117  *
118  *********************************************************************/
119
120 static  DtDndProtocol   dndProtocolList[] = {
121         DtDND_FILENAME_TRANSFER,
122         DtDND_BUFFER_TRANSFER,
123         DtDND_TEXT_TRANSFER,
124         DtDND_NOOP_TRANSFER
125 };
126
127 extern DtDndMethods *_DtDndBuffTransferProtocolInitialize(Display*);
128 extern DtDndMethods *_DtDndFileTransferProtocolInitialize(Display*);
129 extern DtDndMethods *_DtDndTextTransferProtocolInitialize(Display*);
130
131 /*
132  * dndGetTransferMethods
133  *
134  *      Return the transfer methods for a particular protocol
135  */
136 static DtDndMethods *
137 dndGetTransferMethods(
138         Display *       display,
139         DtDndProtocol   protocol)
140 {
141         DtDndMethods *  methods = NULL;
142
143         switch (protocol) {
144         case DtDND_BUFFER_TRANSFER:
145                 methods = _DtDndBuffTransferProtocolInitialize(display);
146                 break;
147         case DtDND_FILENAME_TRANSFER:
148                 methods = _DtDndFileTransferProtocolInitialize(display);
149                 break;
150         case DtDND_TEXT_TRANSFER:
151                 methods = _DtDndTextTransferProtocolInitialize(display);
152                 break;
153         }
154
155         return methods;
156 }
157
158 /*
159  * _DtDndCreateExportTransfer
160  *
161  *      Returns a transfer suitable for use by a drag initiator
162  */
163 DtDndTransfer *
164 _DtDndCreateExportTransfer(
165         DtDragInfo *    dtDragInfo)
166 {
167         Display *       dpy = XtDisplayOfObject(dtDragInfo->dragInitiator);
168         DtDndTransfer * transfer;
169
170         dndInitTargets(dpy);
171
172         transfer = (DtDndTransfer *)XtMalloc(sizeof(DtDndTransfer));
173
174         transfer->methods = dndGetTransferMethods(dpy,dtDragInfo->protocol);
175
176         (*transfer->methods->getExportTargets)(dtDragInfo,
177                         &(transfer->targets), &(transfer->numTargets));
178
179         return transfer;
180 }
181
182 /*
183  * _DtDndCreateImportTransfers
184  *
185  *      Create the list of transfers specified by the protocols.
186  */
187 DtDndTransfer *
188 _DtDndCreateImportTransfers(
189         DtDropInfo *    dtDropInfo,
190         Cardinal *      numTransfers)
191 {
192         Display *       dpy = XtDisplayOfObject(dtDropInfo->dropReceiver);
193         DtDndTransfer * transfers;
194         DtDndTransfer * transfer;
195         Cardinal        ii, jj;
196
197         dndInitTargets(dpy);
198
199         *numTransfers = 0;
200
201         for (ii = 0; dndProtocolList[ii] != DtDND_NOOP_TRANSFER; ii++) {
202                 if (dtDropInfo->protocols & dndProtocolList[ii]) {
203                         (*numTransfers)++;
204                 }
205         }
206
207         if (*numTransfers == 0)
208                 return (DtDndTransfer *)NULL;
209         
210         transfers = (DtDndTransfer *)XtMalloc(
211                                 *numTransfers * sizeof(DtDndTransfer));
212
213         for (ii = 0, jj = 0; dndProtocolList[ii] != DtDND_NOOP_TRANSFER; ii++) {
214                 if (dtDropInfo->protocols & dndProtocolList[ii]) {
215                         transfer = &transfers[jj++];
216                         transfer->methods = 
217                                 dndGetTransferMethods(dpy,dndProtocolList[ii]);
218                         (*transfer->methods->getImportTargets)(dtDropInfo,
219                                 &(transfer->targets), &(transfer->numTargets));
220                 }
221         }
222
223         return transfers;
224 }
225
226 /*
227  * _DtDndDestroyTransfers
228  *
229  *      Destroy the transfer list created by
230  *      _DtDndCreateExportTransfer() or _DtDndCreateImportTransfers()
231  */
232 void
233 _DtDndDestroyTransfers(
234         DtDndTransfer * transfers,
235         Cardinal        numTransfers)
236 {
237         Cardinal        ii;
238
239         
240         for (ii = 0; ii < numTransfers; ii++) {
241                 XtFree((char *)transfers[ii].targets);
242         }
243         XtFree((char *)transfers);
244 }
245
246 /*
247  * _DtDndTransferFromTargets
248  *
249  *      Returns the transfer method that matches the target list
250  */
251 DtDndTransfer * 
252 _DtDndTransferFromTargets(
253         DtDndTransfer * transfers,
254         Cardinal        numTransfers,
255         Atom *          targets,
256         Cardinal        numTargets)
257 {
258         Cardinal        ii, jj, kk;
259
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];
265                                 }
266                         }
267                 }
268         }
269         return (DtDndTransfer *)NULL;
270 }
271
272 /*
273  * _DtDndTransferAdd
274  *
275  *      Add the targets to the requested transfer targets list
276  *      and call XmDropTransferAdd() to request them
277  */
278 void
279 _DtDndTransferAdd(
280         Widget          dropTransfer,
281         DtDropInfo *    dtDropInfo,
282         Atom *          transferTargets,
283         Cardinal        numTransferTargets)
284 {
285         DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
286         XmDropTransferEntryRec * transferEntries;
287         Cardinal        numTransfers;
288         int             ii, jj;
289
290         transferEntries = (XmDropTransferEntryRec *)
291                 XtMalloc(numTransferTargets * sizeof(XmDropTransferEntryRec));
292
293         numTransfers = transferInfo->numTransferTargets + numTransferTargets;
294
295         transferInfo->transferTargets = (Atom *)XtRealloc(
296                         (char *)transferInfo->transferTargets,
297                         numTransfers * sizeof(Atom));
298
299         jj = transferInfo->numTransferTargets;
300
301         for (ii = 0; ii < numTransferTargets; ii++) {
302                 transferEntries[ii].target      = transferTargets[ii];
303                 transferEntries[ii].client_data = (XtPointer)dtDropInfo;
304
305                 transferInfo->transferTargets[ii+jj] = transferTargets[ii];
306         }
307
308         transferInfo->numTransferTargets = numTransfers;
309
310         XmDropTransferAdd(dropTransfer, transferEntries, numTransferTargets);
311
312         XtFree((char *)transferEntries);
313 }
314
315 /*********************************************************************
316  *
317  * Misc Debugging Functions
318  *
319  *********************************************************************/
320
321 #ifdef DEBUG
322 void
323 _DtDndPrintTargets(
324         Display         *display,
325         Atom            *targets,
326         Cardinal        numTargets)
327 {
328         Cardinal        ii;
329         char            *name;
330
331         for (ii = 0; ii < numTargets; ii++) {
332                 name = XGetAtomName(display, targets[ii]);
333                 if (name) {
334                         printf("%s ", name);
335                         XFree(name);
336                 } else {
337                         printf("(null) ");
338                 }
339         }
340         printf("\n");
341 }
342
343 void
344 _DtDndPrintTransfers(
345         Display         *display,
346         DtDndTransfer   *transfers,
347         Cardinal        numTransfers)
348 {
349         Cardinal        ii;
350
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);
355         }
356 }
357 #endif
358
359 /*********************************************************************
360  *
361  * Misc Utility Functions
362  *
363  *********************************************************************/
364
365 /*
366  * Copy CallbackList
367  */
368 XtCallbackList
369 _DtDndCopyCallbackList(
370         XtCallbackList  callbacks)
371 {
372         XtCallbackList  cl;
373         int             ii, count;
374
375         if (callbacks == NULL)
376                 return NULL;
377
378         count = 1;
379         for (cl = callbacks; cl->callback != NULL; cl++) {
380                 count++;
381         }
382
383         cl = (XtCallbackList)XtMalloc(count * sizeof(XtCallbackRec));
384
385         for (ii = 0; ii < count; ii++) {
386                 cl[ii].callback = callbacks[ii].callback;
387                 cl[ii].closure  = callbacks[ii].closure;
388         }
389         
390         return cl;
391 }
392
393 /*
394  * Call CallbackList
395  */
396 void
397 _DtDndCallCallbackList(
398         Widget          widget,
399         XtCallbackList  callbacks,
400         XtPointer       calldata)
401 {
402         XtCallbackList  cl;
403
404         if (callbacks == NULL)
405                 return;
406
407         for (cl = callbacks; cl->callback != NULL; cl++) {
408                 (*cl->callback)(widget, cl->closure, calldata);
409         }
410 }
411
412 /*
413  * Misc Varargs Utility Functions
414  */
415
416 int
417 _DtDndCountVarArgs(
418         va_list         vaList)
419 {
420         XtPointer       argPtr;
421         Cardinal        argCount;
422
423         argCount = 0; 
424         for (argPtr = va_arg(vaList,String);
425              argPtr != NULL; 
426              argPtr = va_arg(vaList,String)) {
427
428                 va_arg(vaList, XtArgVal);
429                 argCount++;
430         }
431
432         return argCount;
433 }
434
435 void
436 _DtDndArgListFromVarArgs(
437         va_list         vaList,
438         Cardinal        maxArgs,
439         ArgList         *argListReturn,
440         Cardinal        *argCountReturn)
441 {
442         ArgList         argList;
443         Cardinal        argCount;
444         XtPointer       argPtr;
445
446         if (0 == maxArgs)
447         {
448             *argListReturn = NULL;
449             *argCountReturn = 0;
450             return;
451         }
452
453         argList = (ArgList)XtMalloc((unsigned)(maxArgs * sizeof(Arg)));
454
455         argCount = 0;
456         for (argPtr = va_arg(vaList,String);
457              argPtr != NULL;
458              argPtr = va_arg(vaList,String)) {
459
460                 XtSetArg(argList[argCount], argPtr, va_arg(vaList,XtArgVal));
461                 argCount++;
462         }
463
464         *argListReturn          = argList;
465         *argCountReturn         = argCount;
466 }
467
468 /*
469  * Returns the network node/host name.
470  */
471 String
472 _DtDndGetHostName(void)
473 {
474         static char *nodename;
475
476         _DtSvcProcessLock();
477         if (nodename == NULL) {
478                 struct utsname  un;
479
480                 if (uname(&un) == -1) {
481                         _DtSimpleError(DtProgName,DtError, NULL, "uname", NULL);
482                         nodename = XtNewString("nodename");
483                 } else {
484                         nodename = XtNewString(un.nodename);
485                 }
486         }
487         _DtSvcProcessUnlock();
488         return nodename;
489 }
490