File: DND.c

package info (click to toggle)
gridengine 8.1.9%2Bdfsg-9
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 56,756 kB
  • sloc: ansic: 432,689; java: 87,068; cpp: 31,958; sh: 29,429; jsp: 7,757; perl: 6,336; xml: 5,828; makefile: 4,701; csh: 3,934; ruby: 2,221; tcl: 1,676; lisp: 669; yacc: 519; python: 503; lex: 361
file content (452 lines) | stat: -rw-r--r-- 15,118 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
#ifndef DND 
   static int DNDdummy;
#else   
/*-------------------------------------------------------------------------*/
/*----------------- Drag & Drop -------------------------------------------*/
/*-------------------------------------------------------------------------*/

#include <stdio.h>

#include <Xm/MessageB.h>
#include <Xm/AtomMgr.h>
#include <Xm/DragDrop.h>

#include "ListTreeP.h"
#include "DND.h"

#if NeedFunctionPrototypes
static void DragDropFinish(Widget w, XtPointer cld,  XtPointer cad);
static Boolean ConvertProc(Widget w, Atom *selection, Atom *target, 
                     Atom *type_return, XtPointer *value_return, 
                     unsigned long *length_return, int *format_return);
static void TransferProc(Widget w, XtPointer cld, Atom *seltype, Atom *type,
                  XtPointer value, unsigned long *length, int format);
static void HandleDropOK(Widget w, XtPointer cld, XtPointer cad);
static void HandleDropCancel(Widget w, XtPointer cld, XtPointer cad);
static void HandleDropLabel(Widget w, XtPointer cld, XtPointer cad);
#else
static void DragDropFinish();
static Boolean ConvertProc();
static void TransferProc();
static void HandleDropOK();
static void HandleDropCancel();
static void HandleDropLabel();
#endif


/*-------------------------------------------------------------------------*/
/* InitializeDropSite() registers the list tree widget as a drop site for  */
/* list sub trees                                                          */
/*-------------------------------------------------------------------------*/
#if NeedFunctionPrototypes
void InitializeDropSite(Widget aw)
#else
void InitializeDropSite(aw)
Widget aw;
#endif
{
   int ac;
   Arg args[10];
   Atom LIST_SUB_TREE;
   Atom import_list[1];
   Display *dpy;

   dpy = XtDisplay(aw);
   LIST_SUB_TREE = XmInternAtom(dpy, "LIST_SUB_TREE", False);

   import_list[0] = LIST_SUB_TREE;

   ac = 0;
   XtSetArg(args[ac], XmNimportTargets, import_list); ac++;
   XtSetArg(args[ac], XmNnumImportTargets, XtNumber(import_list)); ac++;
   XtSetArg(args[ac], XmNdropSiteOperations, XmDROP_COPY); ac++;
   XtSetArg(args[ac], XmNdropProc, HandleDropLabel); ac++;
   XmDropSiteRegister(aw, args, ac);

}

/*-------------------------------------------------------------------------*/
/* HandleDropLabel() -- start the data transfer when data is dropped in    */
/* the filename status area.                                               */
/*-------------------------------------------------------------------------*/
#if NeedFunctionPrototypes
static void HandleDropLabel(Widget w, XtPointer cld, XtPointer cad)
#else
static void HandleDropLabel(w, cld, cad)
Widget          w;
XtPointer       cld;
XtPointer       cad;
#endif
{
#if 0
   static Widget help_dialog = 0;
   Display *dpy;
   Atom LIST_SUB_TREE;
   static struct {
      XmDropProcCallbackStruct client;
      DNDInfo dndinfo;
   } data;
   XmDropProcCallback DropData;
   XmDropTransferEntryRec transferEntries[1];
   XmDropTransferEntry transferList;
   Arg args[10];
   int ac, i;
   Widget dc;
   Cardinal numExportTargets;
   Atom *exportTargets;
   Boolean list_sub_tree = False;
   static DNDInfo dndinfo;
   XmString message;

   /* intern the Atoms for data targets */
   dpy = XtDisplay (w);
   LIST_SUB_TREE = XmInternAtom(dpy, "LIST_SUB_TREE", False);

   DropData = (XmDropProcCallback) cad;
   dc = DropData->dragContext;

   /* get the item */
   dndinfo.item = GetItem((ListTreeWidget)w, DropData->y);
   dndinfo.list_tree = (ListTreeWidget)w;

   /* retrieve the data targets and search for LIST_SUB_TREE */
   ac = 0;
   XtSetArg(args[ac], XmNexportTargets, &exportTargets); ac++;
   XtSetArg(args[ac], XmNnumExportTargets, &numExportTargets); ac++;
   XtGetValues(dc, args, ac);

   for (i = 0; i < numExportTargets; i++) {
      if (exportTargets[i] == LIST_SUB_TREE) {
         list_sub_tree = True;
         break;
      }
   }

   if (DropData->dropAction == XmDROP_HELP) {
      /* create a dialog if it doesn't already exist */
      if (!help_dialog) {
         ac = 0;
         message = XmStringCreateLtoR("Blabla", XmFONTLIST_DEFAULT_TAG);
         XtSetArg(args[ac], XmNdialogStyle, 
                     XmDIALOG_FULL_APPLICATION_MODAL); ac++;
         XtSetArg(args[ac], XmNtitle, "Drop Help"); ac++;
         XtSetArg(args[ac], XmNmessageString, message); ac++;
         help_dialog = XmCreateInformationDialog((Widget)dndinfo.list_tree,
                           "ListTreeDropHelp", args, ac);
         XmStringFree(message);
         XtAddCallback(help_dialog, XmNokCallback,
                        HandleDropOK, (XtPointer) &data);
         XtAddCallback(help_dialog, XmNcancelCallback,
                        HandleDropCancel, (XtPointer) &data.client);
      }
      /* set up the callback structure for when the user proceeds
       * with the drop and pass it as client data to the callbacks
       * for the buttons.
       */	
      data.client.dragContext = dc;
      data.client.x = DropData->x;
      data.client.y = DropData->y;
      data.client.dropSiteStatus = DropData->dropSiteStatus;
      data.client.operation = DropData->operation;
      data.client.operations = DropData->operations;
      data.dndinfo.list_tree = dndinfo.list_tree;
      data.dndinfo.item = dndinfo.item;

      XtManageChild(help_dialog);
      return;
    }
         

   /* make sure we have a drop that is a copy operation and one of
    * the targets is LIST_SUB_TREE.  if not, set the status to failure.
    */
   ac = 0;
   if ((!list_sub_tree) || (DropData->dropAction != XmDROP) || 
      (DropData->operation != XmDROP_COPY)) {
      XtSetArg(args[ac], XmNtransferStatus, XmTRANSFER_FAILURE); ac++;
      XtSetArg(args[ac], XmNnumDropTransfers, 0); ac++;
   }
   else {
      /* set up transfer requests for drop site */
      transferEntries[0].target = LIST_SUB_TREE;
      transferEntries[0].client_data = &dndinfo;
      transferList = transferEntries;
      XtSetArg(args[ac], XmNdropTransfers, transferEntries); ac++;
      XtSetArg(args[ac], XmNnumDropTransfers, XtNumber(transferEntries));ac++;
      XtSetArg(args[ac], XmNtransferProc, TransferProc); ac++;
   }
   XmDropTransferStart(dc, args, ac);
#endif
}

/*-------------------------------------------------------------------------*/
/* HandleDropOK() -- callback routine for OK button in drop site help      */
/* dialog that processes the drop as normal.                               */
/*-------------------------------------------------------------------------*/
#if NeedFunctionPrototypes
static void HandleDropOK(Widget w, XtPointer cld, XtPointer cad)
#else
static void HandleDropOK(w, cld, cad)
Widget          w;
XtPointer       cld;
XtPointer       cad;
#endif
{
   Display *dpy;
   Atom LIST_SUB_TREE;
   struct _data {
      XmDropProcCallbackStruct client;
      DNDInfo dndinfo;
   } *data;
   XmDropTransferEntryRec transferEntries[1];
   XmDropTransferEntry transferList;
   Arg args[10];
   int n;
   Widget dc;

   /* intern the Atoms for data targets */
   dpy = XtDisplay(w);
   LIST_SUB_TREE = XmInternAtom(dpy, "LIST_SUB_TREE", False);

   /* get the callback structure passed via client data */
   data = (struct _data*) cld;
   dc = data->client.dragContext;

   n = 0;
   /* if operation is not a copy, the transfer fails */
   if (data->client.operation != XmDROP_COPY) {
      XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
      XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
   }
   else {
      /* set up transfer requests to process data transfer */
      transferEntries[0].target = LIST_SUB_TREE;
      transferEntries[0].client_data = (XtPointer) &data->dndinfo;
      transferList = transferEntries;
      XtSetArg(args[n], XmNdropTransfers, transferEntries); n++;
      XtSetArg(args[n], XmNnumDropTransfers, 
                  XtNumber(transferEntries)); n++;
      XtSetArg(args[n], XmNtransferProc, TransferProc); n++;
   }
   XmDropTransferStart(dc, args, n);
}

/*-------------------------------------------------------------------------*/
/* HandleDropCancel() -- callback routine for Cancel button in drop site   */
/* help dialog that cancels the transfer.                                  */
/*-------------------------------------------------------------------------*/
#if NeedFunctionPrototypes
static void HandleDropCancel(Widget w, XtPointer cld, XtPointer cad)
#else
static void HandleDropCancel(w, cld, cad)
Widget w;
XtPointer cld;
XtPointer cad;
#endif
{
   XmDropProcCallbackStruct        *DropData;
   Arg                             args[10];
   int                             n;
   Widget                          dc;

   /* get the callback structures passed via client data */
   DropData = (XmDropProcCallbackStruct *) cld;
   dc = DropData->dragContext;

   /* user has canceled the transfer, so it fails */
   n = 0;
   XtSetArg (args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
   XtSetArg (args[n], XmNnumDropTransfers, 0); n++;
   XmDropTransferStart (dc, args, n);
}


/*-------------------------------------------------------------------------*/
/* TransferProc() -- handle data transfer of converted data from drag      */
/* source to drop site.                                                    */
/*-------------------------------------------------------------------------*/
#if NeedFunctionPrototypes
static void TransferProc(Widget w, XtPointer cld, Atom *seltype, Atom *type,
                  XtPointer value, unsigned long *length, int format)
#else
static void TransferProc(w, cld, seltype, type, value, length, format)
Widget w;
XtPointer cld;
Atom *seltype;
Atom *type;
XtPointer value;
unsigned long *length;
int format;
#endif
{
   Display *dpy;
   Atom LIST_SUB_TREE;
   DNDInfo *dndinfo = (DNDInfo*)cld;

   /* intern the Atoms for data targets */
   dpy = XtDisplay(w);
   LIST_SUB_TREE = XmInternAtom(dpy, "LIST_SUB_TREE", False);

   if (*type == LIST_SUB_TREE) {
      if (dndinfo->item)
         printf("TransferProc is working '%s' '%s'\n", dndinfo->item->text, 
                     ((ListTreeItem*)value)->text);
      ListTreeReparent((Widget)dndinfo->list_tree, (ListTreeItem*)value, 
                           dndinfo->item); 
   }

}

/*-------------------------------------------------------------------------*/
/* start_drag action routine - starts a drag & drop action                 */
/*-------------------------------------------------------------------------*/
#if NeedFunctionPrototypes
void start_drag(Widget aw, XEvent *event, String *params, 
                    Cardinal *num_params)
#else
void start_drag(aw, event, params, num_params)
Widget aw;
XEvent *event;
String *params;
Cardinal *num_params;
#endif
{
#if 0
   ListTreeWidget w = (ListTreeWidget)aw;
   ListTreeItem *item;    
   Arg args[20];
   int n;
   Display *dpy;
   Atom LIST_SUB_TREE;
   Atom exportList[1];
   Widget dc;
   Pixel fg, bg;
#if 0
   Pixmap icon, iconmask;
   Widget drag_icon;
#endif
   /* intern the Atoms for data targets */
   dpy = XtDisplay(aw);
   LIST_SUB_TREE = XmInternAtom(dpy, "LIST_SUB_TREE", False);

   /* get the current ListTree Item */
   item = GetItem(w, event->xbutton.y);

   XtVaGetValues( aw,
                  XmNforeground, &fg,
                  XmNbackground, &bg,
                  NULL);

#if 0
   /* create pixmaps for drag icon -- either file or directory */
   icon = XmGetPixmapByDepth(XtScreen(aw), "file.xbm", 1, 0, 1);
   iconmask = XmGetPixmapByDepth(XtScreen(aw), "filemask.xbm", 1, 0, 1);
   if (icon == XmUNSPECIFIED_PIXMAP || iconmask == XmUNSPECIFIED_PIXMAP) {
       puts("Couldn't load pixmaps");
       return;
   }

   n = 0;
   XtSetArg(args[n], XmNpixmap, icon); n++;
   XtSetArg(args[n], XmNmask, iconmask); n++;
   drag_icon = XmCreateDragIcon(aw, "drag_icon", args, n);
#endif

   /* specify resources for DragContext for the transfer */
   n = 0;
   XtSetArg(args[n], XmNblendModel, XmBLEND_ALL); n++;
   XtSetArg(args[n], XmNcursorBackground, bg); n++;
   XtSetArg(args[n], XmNcursorForeground, fg); n++;
/*    XtSetArg(args[n], XmNsourceCursorIcon, drag_icon); n++;  */
   /* establish the list of valid target types */
   exportList[0] = LIST_SUB_TREE;
   XtSetArg(args[n], XmNexportTargets, exportList); n++;
   XtSetArg(args[n], XmNnumExportTargets, 1); n++;
   XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
   XtSetArg(args[n], XmNconvertProc, ConvertProc); n++;
   XtSetArg(args[n], XmNclientData, (XtPointer)item); n++;

   /* start the drag and register a callback to clean up when done */
   dc = XmDragStart(aw, event, args, n);
   if (dc) {
      XtAddCallback(dc, XmNdragDropFinishCallback, DragDropFinish, NULL);
   }
   else
      fprintf(stderr, "XmDragStart() failed\n");
#endif
}

/*-------------------------------------------------------------------------*/
/* ConvertProc() -- convert the file data to the format requested          */
/* by the drop site.                                                       */
/*-------------------------------------------------------------------------*/
#if NeedFunctionPrototypes
static Boolean ConvertProc(Widget w, Atom *selection, Atom *target, 
                     Atom *type_return, XtPointer *value_return, 
                     unsigned long *length_return, int *format_return)
#else
static Boolean ConvertProc(w, selection, target, type_return, value_return, 
       length_return, format_return)
Widget              w;
Atom                *selection;
Atom                *target;
Atom                *type_return;
XtPointer           *value_return;
unsigned long       *length_return;
int                 *format_return;
#endif
{
   Display     *dpy;
   Atom        LIST_SUB_TREE, MOTIF_DROP;
   XtPointer   ptr;
   ListTreeItem *item;

   /* intern the Atoms for data targets */
   dpy = XtDisplay(w);
   LIST_SUB_TREE = XmInternAtom(dpy, "LIST_SUB_TREE", False);
   MOTIF_DROP = XmInternAtom(dpy, "_MOTIF_DROP", False);

   /* check if we are dealing with a drop */
   if (*selection != MOTIF_DROP)
       return False;

   /* get the drag source widget */
   XtVaGetValues(w, XmNclientData, &ptr, NULL);
   item = (ListTreeItem*) ptr;
   
   if (item == NULL)
       return False;

   /* this routine processes only file contents and file name */
   if (*target == LIST_SUB_TREE) {
      /* format the value for transfer */
      *type_return = LIST_SUB_TREE;
      *value_return = (XtPointer) item;
      *length_return = 0;
      *format_return = 0;
      return True;
   }
   else
      return False;
}

/*-------------------------------------------------------------------------*/
/* DragDropFinish() -- clean up after a drag and drop transfer.            */
/*-------------------------------------------------------------------------*/
#if NeedFunctionPrototypes
static void DragDropFinish(Widget w, XtPointer cld,  XtPointer cad)
#else
static void DragDropFinish(w, cld, cad)
Widget w;
XtPointer cld;
XtPointer cad;
#endif
{
   Widget source_icon = NULL;

   XtVaGetValues(w, XmNsourceCursorIcon, &source_icon, NULL);

   if (source_icon)
      XtDestroyWidget(source_icon);
}
#endif