1 /*
2  *
3  * $Id: DropSMgr.c,v 1.1 2004/08/28 19:22:44 dannybackx Exp $
4  *
5  * Copyright (C) 1995 Free Software Foundation, Inc.
6  * Copyright (C) 1995-2001 LessTif Development Team
7  *
8  * This file is part of the GNU LessTif Library.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the Free
22  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  **/
25 
26 static const char rcsid[] = "$Id: DropSMgr.c,v 1.1 2004/08/28 19:22:44 dannybackx Exp $";
27 
28 #include <LTconfig.h>
29 
30 #include <XmI/XmI.h>
31 
32 #include <Xm/DropSMgrP.h>
33 #include <Xm/DisplayP.h>
34 #include <XmI/DragDropI.h>
35 #include <Xm/DragCP.h>
36 #include <Xm/DropTrans.h>
37 #include <Xm/XmP.h>
38 #include <Xm/AtomMgr.h>
39 
40 #include <XmI/DebugUtil.h>
41 
42 
43 #define HASH_BUCKETS	127
44 
45 
46 /* Forward Declarations */
47 
48 static void __XmDSMCreateInfo(XmDropSiteManagerObject dsm,
49 			      Widget widget,
50 			      ArgList args,
51 			      Cardinal num_args);
52 static void __XmDSMDestroyInfo(XmDropSiteManagerObject dsm,
53 			       Widget widget);
54 static void __XmDSMStartUpdate(XmDropSiteManagerObject dsm,
55 			       Widget widget);
56 static void __XmDSMRetrieveInfo(XmDropSiteManagerObject dsm,
57 				Widget widget,
58 				ArgList args,
59 				Cardinal num_args);
60 static void __XmDSMUpdateInfo(XmDropSiteManagerObject dsm,
61 			      Widget widget,
62 			      ArgList args,
63 			      Cardinal num_args);
64 static void __XmDSMEndUpdate(XmDropSiteManagerObject dsm,
65 			     Widget widget);
66 static void __XmDSMUpdateDSM(XmDropSiteManagerObject dsm,
67 			     XtPointer clientData,
68 			     XtPointer callData);
69 static void __XmDSMProcessMotion(XmDropSiteManagerObject dsm,
70 				 XtPointer clientData,
71 				 XtPointer callData);
72 static void __XmDSMProcessDrop(XmDropSiteManagerObject dsm,
73 			       XtPointer clientData,
74 			       XtPointer callData);
75 static void __XmDSMOperationChanged(XmDropSiteManagerObject dsm,
76 				    XtPointer clientData,
77  			    XtPointer callData);
78 static void __XmDSMChangeRoot(XmDropSiteManagerObject dsm,
79 			      XtPointer clientData,
80 			      XtPointer callData);
81 static void __XmDSMInsertInfo(XmDropSiteManagerObject dsm,
82 			      XtPointer clientData,
83 			      XtPointer callData);
84 static void __XmDSMRemoveInfo(XmDropSiteManagerObject dsm,
85 			      XtPointer info);
86 static void __XmDSMSyncTree(XmDropSiteManagerObject dsm,
87 			    Widget shell);
88 static int __XmDSMGetTree(XmDropSiteManagerObject dsm,
89 			  Widget shell,
90 			  XtPointer dataPtr);
91 static void __XmDSMCreateDSInfoTable(XmDropSiteManagerObject dsm);
92 static void __XmDSMDestroyDSInfoTable(XmDropSiteManagerObject dsm);
93 static void __XmDSMRegisterInfo(XmDropSiteManagerObject dsm,
94 				Widget widget,
95 				XtPointer info);
96 static XtPointer __XmDSMWidgetToInfo(XmDropSiteManagerObject dsm,
97 				     Widget widget);
98 static void __XmDSMUnregisterInfo(XmDropSiteManagerObject dsm,
99 				  XtPointer info);
100 static void class_initialize(void);
101 static void class_part_initialize(WidgetClass widget_class);
102 static void initialize(Widget request, Widget new_w,
103 		       ArgList args, Cardinal *num_args);
104 static void destroy(Widget w);
105 static Boolean set_values(Widget current, Widget request, Widget new_w,
106 			  ArgList args, Cardinal *num_args);
107 static void updateTree(Widget w, XtPointer cd, XtPointer cbs);
108 
109 #define Offset(f)	XtOffsetOf(XmDropSiteManagerRec, dropManager.f)
110 static XtResource resources[] =
111 {
112     {
113 	XmNnotifyProc, XmCNotifyProc, XmRCallbackProc,
114 	sizeof(XtCallbackList), Offset(notifyProc),
115 	XmRImmediate, (XtPointer)NULL
116     },
117     {
118 	XmNtreeUpdateProc, XmCTreeUpdateProc, XmRCallbackProc,
119 	sizeof(XtCallbackList), Offset(treeUpdateProc),
120 	XmRImmediate, (XtPointer)NULL
121     },
122     {
123 	XmNclientData, XmCClientData, XmRPointer,
124 	sizeof(XtPointer), Offset(client_data),
125 	XmRImmediate, (XtPointer)NULL
126     }
127 };
128 #undef Offset
129 
130 
131 #if 0
132 static XmBaseClassExtRec _XmDropSMgrObjectClassExtRec = {
133     /* next_extension            */ NULL,
134     /* record_type               */ NULLQUARK,
135     /* version                   */ XmBaseClassExtVersion,
136     /* size                      */ sizeof(XmBaseClassExtRec),
137     /* initialize_prehook        */ NULL,
138     /* set_values_prehook        */ NULL,
139     /* initialize_posthook       */ NULL,
140     /* set_values_posthook       */ NULL,
141     /* secondary_object_class    */ NULL,
142     /* secondary_object_create   */ NULL,
143     /* get_secondary_resources   */ NULL,
144     /* fast_subclass             */ { 0 },
145     /* get_values_prehook        */ NULL,
146     /* get_values_posthook       */ NULL,
147     /* class_part_init_prehook   */ NULL,
148     /* class_part_init_posthook  */ NULL,
149     /* ext_resources             */ NULL,
150     /* compiled_ext_resources    */ NULL,
151     /* num_ext_resources         */ 0,
152     /* use_sub_resources         */ False,
153     /* widget_navigable          */ NULL,
154     /* focus_change              */ NULL,
155     /* wrapper_data              */ NULL
156 };
157 #endif
158 
159 XmDropSiteManagerClassRec xmDropSiteManagerClassRec = {
160     /* Object class part */
161     {
162 	/* superclass            */ (WidgetClass) &objectClassRec,
163         /* class_name            */ "XmDropSiteManager",
164 	/* widget_size           */ sizeof(XmDropSiteManagerRec),
165 	/* class_initialize      */ class_initialize,
166 	/* class_part_initialize */ class_part_initialize,
167 	/* class_inited          */ False,
168 	/* initialize            */ initialize,
169 	/* initialize_hook       */ NULL,
170 	/* obj1                  */ NULL, /* Motif has one of these */
171 	/* obj2                  */ NULL,
172 	/* obj3                  */ 0,
173 	/* resources             */ resources,
174 	/* num_resources         */ XtNumber(resources),
175 	/* xrm_class             */ NULLQUARK,
176 	/* obj4                  */ True,
177 	/* obj5                  */ XtExposeCompressSeries,
178 	/* obj6                  */ True,
179 	/* obj7                  */ 0,
180 	/* destroy               */ destroy,
181 	/* obj8                  */ NULL,
182 	/* obj9                  */ NULL,
183 	/* set_values            */ set_values,
184 	/* set_values_hook       */ NULL,
185 	/* obj10                 */ NULL,
186 	/* get_values_hook       */ NULL,
187 	/* obj11                 */ NULL,
188 	/* version               */ XtVersion,
189 	/* callback offsets      */ NULL,
190 	/* obj12                 */ NULL,
191 	/* obj13                 */ NULL,
192 	/* obj14                 */ NULL,
193 	/* extension             */ (XtPointer)NULL /*&_XmDropSMgrObjectClassExtRec*/
194     },
195     /* Drop site manager class part */
196     {
197 	/* createInfo       */  __XmDSMCreateInfo,
198 	/* destroyInfo      */  __XmDSMDestroyInfo,
199 	/* startUpdate      */  __XmDSMStartUpdate,
200 	/* retrieveInfo     */  __XmDSMRetrieveInfo,
201 	/* updateInfo       */  __XmDSMUpdateInfo,
202 	/* endUpdate        */  __XmDSMEndUpdate,
203 	/* updateDSM        */  __XmDSMUpdateDSM,
204 	/* processMotion    */  __XmDSMProcessMotion,
205 	/* processDrop      */  __XmDSMProcessDrop,
206 	/* operationChanged */  __XmDSMOperationChanged,
207 	/* changeRoot       */  __XmDSMChangeRoot,
208 	/* insertInfo       */  __XmDSMInsertInfo,
209 	/* removeInfo       */  __XmDSMRemoveInfo,
210 	/* syncTree         */  __XmDSMSyncTree,
211 	/* getTreeFromDSM   */  __XmDSMGetTree,
212 	/* createTable      */  __XmDSMCreateDSInfoTable,
213 	/* destroyTable     */  __XmDSMDestroyDSInfoTable,
214 	/* registerInfo     */  __XmDSMRegisterInfo,
215 	/* widgetToInfo     */  __XmDSMWidgetToInfo,
216 	/* unregisterInfo   */  __XmDSMUnregisterInfo,
217 	/* extension        */  NULL
218     }
219 };
220 
221 
222 WidgetClass xmDropSiteManagerObjectClass = (WidgetClass)(&xmDropSiteManagerClassRec);
223 
224 /*
225  * Creates a drop site for the associated widget (perhaps)
226  */
227 
228 static void
class_initialize(void)229 class_initialize(void)
230 {
231     DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:class_initialize(%d)\n",
232     	__FILE__, __LINE__));
233 #if 0
234     _XmDropSMgrObjectClassExtRec.record_type = XmQmotif;
235 #endif
236 }
237 
238 
239 static void
class_part_initialize(WidgetClass widget_class)240 class_part_initialize(WidgetClass widget_class)
241 {
242     WidgetClass sc;
243 
244     DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:class_part_initialize(%d)\n",
245     	__FILE__, __LINE__));
246     _XmFastSubclassInit(widget_class, XmDROP_SITE_MANAGER_BIT);
247 
248     sc = widget_class->core_class.superclass;
249 
250     if (DSC_CreateInfoProc(widget_class) == XmInheritCreateInfoProc)
251     {
252 	DSC_CreateInfoProc(widget_class) = DSC_CreateInfoProc(sc);
253     }
254 
255     if (DSC_DestroyInfoProc(widget_class) == XmInheritDestroyInfoProc)
256     {
257 	DSC_DestroyInfoProc(widget_class) = DSC_DestroyInfoProc(sc);
258     }
259 
260     if (DSC_StartUpdateProc(widget_class) == XmInheritStartUpdateProc)
261     {
262 	DSC_StartUpdateProc(widget_class) = DSC_StartUpdateProc(sc);
263     }
264 
265     if (DSC_RetrieveInfoProc(widget_class) == XmInheritRetrieveInfoProc)
266     {
267 	DSC_RetrieveInfoProc(widget_class) = DSC_RetrieveInfoProc(sc);
268     }
269 
270     if (DSC_UpdateInfoProc(widget_class) == XmInheritUpdateInfoProc)
271     {
272 	DSC_UpdateInfoProc(widget_class) = DSC_UpdateInfoProc(sc);
273     }
274 
275     if (DSC_EndUpdateProc(widget_class) == XmInheritEndUpdateProc)
276     {
277 	DSC_EndUpdateProc(widget_class) = DSC_EndUpdateProc(sc);
278     }
279 
280     if (DSC_UpdateProc(widget_class) == XmInheritUpdateProc)
281     {
282 	DSC_UpdateProc(widget_class) = DSC_UpdateProc(sc);
283     }
284 
285     if (DSC_ProcessMotionProc(widget_class) == XmInheritProcessMotionProc)
286     {
287 	DSC_ProcessMotionProc(widget_class) = DSC_ProcessMotionProc(sc);
288     }
289 
290     if (DSC_ProcessDropProc(widget_class) == XmInheritProcessDropProc)
291     {
292 	DSC_ProcessDropProc(widget_class) = DSC_ProcessDropProc(sc);
293     }
294 
295     if (DSC_OperationChangedProc(widget_class) == XmInheritOperationChangedProc)
296     {
297 	DSC_OperationChangedProc(widget_class) = DSC_OperationChangedProc(sc);
298     }
299 
300     if (DSC_ChangeRootProc(widget_class) == XmInheritChangeRootProc)
301     {
302 	DSC_ChangeRootProc(widget_class) = DSC_ChangeRootProc(sc);
303     }
304 
305     if (DSC_InsertInfoProc(widget_class) == XmInheritInsertInfoProc)
306     {
307 	DSC_InsertInfoProc(widget_class) = DSC_InsertInfoProc(sc);
308     }
309 
310     if (DSC_RemoveInfoProc(widget_class) == XmInheritRemoveInfoProc)
311     {
312 	DSC_RemoveInfoProc(widget_class) = DSC_RemoveInfoProc(sc);
313     }
314 
315     if (DSC_SyncTreeProc(widget_class) == XmInheritSyncTreeProc)
316     {
317 	DSC_SyncTreeProc(widget_class) = DSC_SyncTreeProc(sc);
318     }
319 
320     if (DSC_GetTreeFromDSMProc(widget_class) == XmInheritGetTreeFromDSMProc)
321     {
322 	DSC_GetTreeFromDSMProc(widget_class) = DSC_GetTreeFromDSMProc(sc);
323     }
324 
325     if (DSC_CreateDSInfoTable(widget_class) == XmInheritCreateDSInfoTable)
326     {
327 	DSC_CreateDSInfoTable(widget_class) = DSC_CreateDSInfoTable(sc);
328     }
329 
330     if (DSC_DestroyDSInfoTable(widget_class) == XmInheritDestroyDSInfoTable)
331     {
332 	DSC_DestroyDSInfoTable(widget_class) = DSC_DestroyDSInfoTable(sc);
333     }
334 
335     if (DSC_RegisterInfoProc(widget_class) == XmInheritRegisterInfoProc)
336     {
337 	DSC_RegisterInfoProc(widget_class) = DSC_RegisterInfoProc(sc);
338     }
339 
340     if (DSC_WidgetToInfoProc(widget_class) == XmInheritWidgetToInfoProc)
341     {
342 	DSC_WidgetToInfoProc(widget_class) = DSC_WidgetToInfoProc(sc);
343     }
344 
345     if (DSC_UnregisterInfoProc(widget_class) == XmInheritUnregisterInfoProc)
346     {
347 	DSC_UnregisterInfoProc(widget_class) = DSC_UnregisterInfoProc(sc);
348     }
349 }
350 
351 
352 static void
initialize(Widget request,Widget new_w,ArgList args,Cardinal * num_args)353 initialize(Widget request, Widget new_w,
354 	   ArgList args, Cardinal *num_args)
355 {
356     XmDropSiteInfoRec hr;
357 
358     DEBUGOUT(_LtDebug(__FILE__, new_w,
359 		      "%s:initialize(%d) - %i args\n"
360 		      "\trequest X %5i Y %5i W %5i H %5i\n"
361 		      "\t  new_w X %5i Y %5i W %5i H %5i\n",
362 		      __FILE__, __LINE__,
363 		      *num_args,
364 		      XtX(request), XtY(request),
365 		      XtWidth(request), XtHeight(request),
366 		      XtX(new_w), XtY(new_w),
367 		      XtWidth(new_w), XtHeight(new_w)));
368     DEBUGOUT(_LtDebugPrintArgList(__FILE__, new_w, args, *num_args, False));
369 
370     DS_CurAnimate(new_w) = True;
371 
372     DS_CurDropSiteStatus(new_w) = XmINVALID_DROP_SITE;
373     DS_CurOperations(new_w) = 0;
374     DS_CurOperation(new_w) = 0;
375 
376     DS_CurX(new_w) = 0;
377     DS_CurY(new_w) = 0;
378     DS_OldX(new_w) = 0;
379     DS_OldY(new_w) = 0;
380 
381     DS_CurDragContext(new_w) = NULL;
382     DS_CurTime(new_w) = CurrentTime;
383     DS_CurInfo(new_w) = NULL;
384     DS_DragUnderData(new_w) = NULL;
385 
386     DS_CurAncestorClipRegion(new_w) = _XmRegionCreate();
387     DS_NewAncestorClipRegion(new_w) = _XmRegionCreate();
388 
389     DSMCreateTable((XmDropSiteManagerObject)new_w);
390 
391     DS_RootX(new_w) = 0;
392     DS_RootY(new_w) = 0;
393 
394     DS_RootWidth(new_w) = XmUNSPECIFIED;
395     DS_RootHeight(new_w) = XmUNSPECIFIED;
396 
397     DS_DSRoot(new_w) = NULL;
398     DS_ClipperList(new_w) = NULL;
399     DS_UpdateInfo(new_w) = NULL;
400 
401     /* compile the resources */
402     XtGetSubresources(new_w, &hr, NULL, NULL,
403 		      _XmDSResources, _XmNumDSResources,
404 		      NULL, 0);
405 
406     if (DS_TreeUpdateProc(new_w) == NULL)
407 	DS_TreeUpdateProc(new_w) = updateTree;
408 
409 }
410 
411 
412 static void
destroy(Widget w)413 destroy(Widget w)
414 {
415     DEBUGOUT(_LtDebug(__FILE__, w, "%s:destroy(%d)\n",
416     	__FILE__, __LINE__));
417     DSMDestroyTable((XmDropSiteManagerObject)w);
418 
419     _XmRegionDestroy(DS_CurAncestorClipRegion(w));
420     _XmRegionDestroy(DS_NewAncestorClipRegion(w));
421 }
422 
423 
424 static Boolean
set_values(Widget old,Widget request,Widget new_w,ArgList args,Cardinal * num_args)425 set_values(Widget old, Widget request, Widget new_w,
426 	   ArgList args, Cardinal *num_args)
427 {
428     DEBUGOUT(_LtDebug(__FILE__, new_w,
429 		      "%s:set_values(%d) - %i args\n"
430 		      "\t    old X %5i Y %5i W %5i H %5i\n"
431 		      "\trequest X %5i Y %5i W %5i H %5i\n"
432 		      "\t  new_w X %5i Y %5i W %5i H %5i\n",
433 		      __FILE__, __LINE__,
434 		      *num_args,
435 		      XtX(old), XtY(old),
436 		      XtWidth(old), XtHeight(old),
437 		      XtX(request), XtY(request),
438 		      XtWidth(request), XtHeight(request),
439 		      XtX(new_w), XtY(new_w),
440 		      XtWidth(new_w), XtHeight(new_w)));
441     DEBUGOUT(_LtDebugPrintArgList(__FILE__, new_w, args, *num_args, False));
442 
443     return True;
444 }
445 
446 
447 static void
updateReceiverInfo(Widget w,XtPointer cd,XEvent * ev,Boolean * ctd)448 updateReceiverInfo(Widget w, XtPointer cd, XEvent *ev, Boolean *ctd)
449 {
450     DEBUGOUT(_LtDebug(__FILE__, w, "%s:updateReceiverInfo(%d)\n",
451     	__FILE__, __LINE__));
452     DEBUGOUT(_LtDebug("DRAGSINK", w, "%s:updateReceiverInfo(%d) - %s\n",
453     	__FILE__, __LINE__,
454     	_LtDebugEventType2String(ev->xany.type)));
455 #if 1
456     /* rws 8 Feb 2000
457        I have no idea if this belongs here or not, but it has to be
458        created at some point.....
459      */
460     /* rws 12 Feb 2000
461        This should probably be DragBS.c:_XmSetDragReceiverInfo()
462      */
463     {
464     XmDndReceiverProp ri;
465     Atom pa;
466     Widget shell = w;
467 
468 	DEBUGOUT(_LtDebug("DND", shell, "%s:createShellInfoRec(%d)\n",
469 	    __FILE__, __LINE__));
470     	ri.byte_order = _XmByteOrder();
471     	ri.protocol_version = DND_PROTOCOL_VERSION;
472     	ri.protocol_style = XmDRAG_DYNAMIC;
473     	ri.proxy_window = (CARD32)None;
474     	ri.num_drop_sites = (CARD32)0;
475     	ri.total_size = (CARD32)sizeof(XmDndReceiverProp);
476 	pa = XmInternAtom(XtDisplay(shell), _XA_MOTIF_DRAG_RECEIVER_INFO, False);
477 	XChangeProperty(XtDisplay(shell), XtWindow(shell),
478 		pa, pa, 8, PropModeReplace,
479 		(unsigned char *)&ri, sizeof(ri));
480     }
481 #endif
482 }
483 
484 
485 static void
SwapMessageData(XmDndMessage * msg)486 SwapMessageData(XmDndMessage *msg)
487 {
488     if (msg->byte_order != _XmByteOrder())
489     {
490 	SWAP2BYTES(msg->flags);
491 	SWAP4BYTES(msg->time);
492 	switch (msg->reason & DND_CLEAR_EVENT_TYPE)
493 	{
494 	case XmTOP_LEVEL_ENTER:
495 	case XmTOP_LEVEL_LEAVE:
496 	    SWAP4BYTES(msg->data.top.property);
497 	    SWAP4BYTES(msg->data.top.src_window);
498 	    break;
499 	case XmDROP_SITE_ENTER:
500 	case XmDRAG_MOTION:
501 	case XmDROP_START:
502 	    SWAP2BYTES(msg->data.pot.x);
503 	    SWAP2BYTES(msg->data.pot.y);
504 	    SWAP4BYTES(msg->data.pot.property);
505 	    SWAP4BYTES(msg->data.pot.src_window);
506 	    break;
507 	case XmDROP_SITE_LEAVE:
508 	case XmDROP_FINISH:
509 	case XmDRAG_DROP_FINISH:
510 	case XmOPERATION_CHANGED:
511 	    break;
512 	default:
513 	    _XmWarning(NULL, "Unexpected DnD message type >%i<\n    %s:SwapMessageData(%d)",
514 		msg->reason, __FILE__, __LINE__);
515 	    break;
516 	}
517     }
518 }
519 
520 
521 /* for Motif BC ?! */
522 extern int
_XmMessageTypeToReason(BYTE reason)523 _XmMessageTypeToReason(BYTE reason)
524 {
525     switch (reason & DND_CLEAR_EVENT_TYPE)
526     {
527     case XmTOP_LEVEL_ENTER:
528 	return(XmCR_TOP_LEVEL_ENTER);
529 	break;
530     case XmTOP_LEVEL_LEAVE:
531 	return(XmCR_TOP_LEVEL_LEAVE);
532 	break;
533     case XmDROP_SITE_ENTER:
534 	return(XmCR_DROP_SITE_ENTER);
535 	break;
536     case XmDRAG_MOTION:
537 	return(XmCR_DRAG_MOTION);
538 	break;
539     case XmDROP_START:
540 	return(XmCR_DROP_START);
541 	break;
542     case XmDROP_SITE_LEAVE:
543 	return(XmCR_DROP_SITE_LEAVE);
544 	break;
545     case XmDROP_FINISH:
546 	return(XmCR_DROP_FINISH);
547 	break;
548     case XmDRAG_DROP_FINISH:
549 	return(XmCR_DRAG_DROP_FINISH);
550 	break;
551     case XmOPERATION_CHANGED:
552 	return(XmCR_OPERATION_CHANGED);
553 	break;
554     default:
555 	_XmWarning(NULL, "Unexpected DnD message type >%i<\n    %s:_XmMessageTypeToReason(%d)",
556 	    reason, __FILE__, __LINE__);
557 	return(reason);
558 	break;
559     }
560 }
561 
562 
563 /* for Motif BC ? */
564 extern void
_XmICCEventToICCCallback(XmDndMessage * msg,XmDragDropCallbackStruct * cbs)565 _XmICCEventToICCCallback(XmDndMessage *msg, XmDragDropCallbackStruct *cbs)
566 {
567     switch (msg->reason & DND_CLEAR_EVENT_TYPE)
568     {
569     case XmTOP_LEVEL_ENTER:
570 	/*
571 	cbs->tle.screen =
572 	cbs->tle.x =
573 	cbs->tle.y =
574 	cbs->tle.dragProtocolStyle =
575 	*/
576 	cbs->tle.window = msg->data.top.src_window;
577 	cbs->tle.iccHandle = msg->data.top.property;
578 	break;
579     case XmTOP_LEVEL_LEAVE:
580 	/*
581 	cbs->tll.screen =
582 	*/
583 	cbs->tle.window = msg->data.top.src_window;
584 	break;
585     case XmDROP_SITE_ENTER:
586 	cbs->dse.operation = DND_GET_OPERATION(msg->flags);
587 	cbs->dse.operations = DND_GET_OPERATIONS(msg->flags);
588 	cbs->dse.dropSiteStatus = DND_GET_STATUS(msg->flags);
589 	cbs->dse.x = msg->data.pot.x;
590 	cbs->dse.y = msg->data.pot.y;
591 	break;
592     case XmDRAG_MOTION:
593 	cbs->dm.operation = DND_GET_OPERATION(msg->flags);
594 	cbs->dm.operations = DND_GET_OPERATIONS(msg->flags);
595 	cbs->dm.dropSiteStatus = DND_GET_STATUS(msg->flags);
596 	cbs->dm.x = msg->data.pot.x;
597 	cbs->dm.y = msg->data.pot.y;
598 	break;
599     case XmDROP_START:
600 	cbs->ds.operation = DND_GET_OPERATION(msg->flags);
601 	cbs->ds.operations = DND_GET_OPERATIONS(msg->flags);
602 	cbs->ds.dropSiteStatus = DND_GET_STATUS(msg->flags);
603 	cbs->ds.dropAction = DND_GET_COMPLETION(msg->flags);
604 	cbs->ds.x = msg->data.pot.x;
605 	cbs->ds.y = msg->data.pot.y;
606 	cbs->ds.iccHandle = msg->data.pot.property;
607 	cbs->ds.window = msg->data.pot.src_window;
608 	break;
609     case XmDROP_SITE_LEAVE:
610 	/* nothing to do */
611 	break;
612     case XmOPERATION_CHANGED:
613 	cbs->oc.operation = DND_GET_OPERATION(msg->flags);
614 	cbs->oc.operations = DND_GET_OPERATIONS(msg->flags);
615 	cbs->oc.dropSiteStatus = DND_GET_STATUS(msg->flags);
616 	break;
617     default:
618 	_XmWarning(NULL, "Unexpected DnD message type >%i<\n    %s:_XmICCEventToICCCallback(%d)",
619 	    msg->reason, __FILE__, __LINE__);
620 	break;
621     }
622 }
623 
624 
625 static void
externalSourceHandler(Widget w,XtPointer cd,XEvent * ev,Boolean * ctd)626 externalSourceHandler(Widget w, XtPointer cd, XEvent *ev, Boolean *ctd)
627 {
628     DEBUGOUT(_LtDebug2(__FILE__, w, (Widget)cd, "%s:externalSourceHandler(%d)\n",
629     	__FILE__, __LINE__));
630     DEBUGOUT(_LtDebug2("DRAGSINK", w, (Widget)cd, "%s:externalSourceHandler(%d)\n",
631     	__FILE__, __LINE__));
632     DEBUGOUT(_LtDebug0("DRAGSINK", w, "\t%s\n",
633     	_LtDebugEventType2String(ev->xany.type)));
634 
635     switch (ev->xany.type)
636     {
637     case ClientMessage:
638 	{
639 	Atom DndMessage;
640 
641 	    DndMessage = XmInternAtom(ev->xclient.display, _XA_MOTIF_DRAG_AND_DROP_MESSAGE, False);
642 	    if (DndMessage == ev->xclient.message_type)
643 	    {
644 	    XmDndMessage *msg = (XmDndMessage *)&(ev->xclient.data.b[0]);
645 	    XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) cd;
646 	    XmDisplay disp = (XmDisplay)XmGetXmDisplay(ev->xclient.display);
647 	    XmDragDropCallbackStruct DnDcbs;
648 	    XmDragTopLevelClientDataStruct TLCcbs;
649 
650 	    	SwapMessageData(msg);
651 		DEBUGOUT(_LtDebug0("DRAGSINK", w, "\t%s from %s\n",
652 		    _LtDebugDragAndDropMessageType2String(msg->reason & DND_CLEAR_EVENT_TYPE),
653 		    msg->reason & ~DND_CLEAR_EVENT_TYPE ? "Receiver" : "Initiator"));
654 		DEBUGOUT(_LtDebug0("DRAGSINK", w, "\tDS_CurDragContext %s %p\n",
655 		    DS_CurDragContext(dsm) ? XtName(DS_CurDragContext(dsm)) : "NULL", DS_CurDragContext(dsm)));
656 		DEBUGOUT(_LtDebug0("DRAGSINK", w, "\tDisplay_ActiveDC %s %p\n",
657 		    Display_ActiveDC(disp) ? XtName(Display_ActiveDC(disp)) : "NULL", Display_ActiveDC(disp)));
658 		DEBUGOUT(_LtDebug0("DRAGSINK", w, "\tXmGetDragContext %s %p\n",
659 		    XmGetDragContext((Widget)dsm, msg->time) ? XtName(XmGetDragContext((Widget)dsm, msg->time)) : "NULL", XmGetDragContext((Widget)dsm, msg->time)));
660 
661 		DnDcbs.any.reason = _XmMessageTypeToReason(msg->reason);
662 		DnDcbs.any.event = ev;
663 		DnDcbs.any.timeStamp = msg->time;
664 		_XmICCEventToICCCallback(msg, &DnDcbs);
665 		TLCcbs.shell = w;
666 		TLCcbs.sourceIsExternal = True;
667 		TLCcbs.window = ev->xclient.window;
668 		TLCcbs.xOrigin = XtX(w);
669 		TLCcbs.yOrigin = XtY(w);
670 		TLCcbs.width = XtWidth(w);
671 		TLCcbs.height = XtHeight(w);
672 		DS_CurDragContext(dsm) = XmGetDragContext((Widget)dsm,
673 						  DnDcbs.any.timeStamp);
674 		DSMUpdate(dsm, (XtPointer)&TLCcbs, (XtPointer)&DnDcbs);
675 	    }
676 	    else
677 	    {
678 	    /* rws 28 Mar 2001
679 	       Normal situation
680 	    char *AtomName;
681 
682 		AtomName = XGetAtomName(ev->xclient.display, ev->xclient.message_type);
683 		_XmWarning(w, "Unexpected ClientMessaget, type >%s<\n    %s:externalSourceHandler(%d)",
684 		    AtomName, __FILE__, __LINE__);
685 		XtFree(AtomName);
686 	    */
687 	    }
688 	}
689 	break;
690     /* rws 28 Mar 2001
691        Normal situation
692     case SelectionClear:
693 	{
694 	char *AtomName;
695 
696 	    AtomName = XGetAtomName(ev->xselectionclear.display, ev->xselectionclear.selection);
697 	    _XmWarning(w, "Unexpected SelectionClear event, losing %s selection\n    %s:externalSourceHandler(%d)",
698 	    	AtomName, __FILE__, __LINE__);
699 	    XtFree(AtomName);
700 	}
701 	break;
702     */
703     default:
704     	/*
705     	_XmWarning(w, "Unexpected event >%s<\n    %s:externalSourceHandler(%d)", _LtDebugEventType2String(ev->xany.type), __FILE__, __LINE__);
706     	*/
707     	break;
708     }
709 #if 0
710     Widget dc, disp;
711     XmDropSiteManagerObject dsm;
712 
713     DEBUGOUT(_LtDebug(__FILE__, w, "External drag event seen\n"));
714 
715     disp = XmGetXmDisplay(XtDisplay(w));
716 
717     dsm = _XmGetDropSiteManagerObject((XmDisplay)disp);
718 
719     if (Display_ActiveDC(disp) != NULL)
720     {
721 	return;
722     }
723 
724     w = XtVaCreateWidget("ExternalDragC", xmDragContextClass, disp,
725 			 XmNsourceIsExternal, True, NULL);
726 #endif
727 }
728 
729 
730 /*
731  * this should be called with a shell widget.
732  */
733 static void
updateTree(Widget w,XtPointer cd,XtPointer cbs)734 updateTree(Widget w, XtPointer cd, XtPointer cbs)
735 {
736     Widget disp = XmGetXmDisplay(XtDisplay(w));
737     XmTreeUpdateCallbackStruct *tucbs = (XmTreeUpdateCallbackStruct *) cbs;
738 
739     DEBUGOUT(_LtDebug(__FILE__, w, "%s:updateTree(%d)\n",
740     	__FILE__, __LINE__));
741     DEBUGOUT(_LtDebug("DRAGSINK", w, "%s:updateTree(%d)\n",
742     	__FILE__, __LINE__));
743 
744     if (Display_DragReceiverProtocolStyle(disp) == XmDRAG_NONE)
745     {
746 	return;
747     }
748 
749     if (tucbs->reason == XmCR_ADD_DROP_SITE)
750     {
751 	if (XtIsRealized(tucbs->widget))
752 	{
753 	    _XmSetDragReceiverInfo(w, tucbs->widget);
754 	}
755 	else
756 	{
757 	    XtAddEventHandler(tucbs->widget,
758 			      StructureNotifyMask,
759 			      False,
760 			      updateReceiverInfo,
761 			      (XtPointer)tucbs->widget);
762 	}
763 
764 	XtAddEventHandler(tucbs->widget,
765 			  NoEventMask,
766 			  True,
767 			  externalSourceHandler,
768 			  (XtPointer)w);
769 
770     }
771     else if (tucbs->reason == XmCR_REMOVE_DROP_SITE)
772     {
773 	XtRemoveEventHandler(tucbs->widget,
774 			     NoEventMask,
775 			     True,
776 			     externalSourceHandler,
777 			     (XtPointer)w);
778 
779 	if (XtIsRealized(tucbs->widget))
780 	{
781 	    _XmClearDragReceiverInfo(tucbs->widget);
782 	}
783     }
784 }
785 
786 
787 static void
destroyInfo(Widget w,XtPointer cd,XtPointer cbs)788 destroyInfo(Widget w, XtPointer cd, XtPointer cbs)
789 {
790     Widget dsm = (Widget)cd;
791 
792     DEBUGOUT(_LtDebug(__FILE__, w, "%s:destroyInfo(%d)\n",
793     	__FILE__, __LINE__));
794     DSMDestroyInfo((XmDropSiteManagerObject)dsm, w);
795 }
796 
797 
798 static XmDropSiteInfo
createShellInfoRec(XmDropSiteManagerObject dsm,Widget shell)799 createShellInfoRec(XmDropSiteManagerObject dsm, Widget shell)
800 {
801     XmRegion r = _XmRegionCreate();
802     XmDropSiteInfo dsi;
803     XRectangle rect;
804 
805     DEBUGOUT(_LtDebug(__FILE__, shell, "%s:createShellInfoRec(%d)\n",
806     	__FILE__, __LINE__));
807     dsi = (XmDropSiteInfo) XtCalloc(1, sizeof(XmDropSiteInfoRec));
808 
809     dsi->leaf = True;
810     dsi->isShell = 1;
811 
812     dsi->animationStyle = XmDRAG_UNDER_NONE;
813     dsi->dropSiteType = XmDROP_SITE_COMPOSITE;
814     dsi->implicit = True;
815     dsi->dropSiteActivity = XmDROP_SITE_INACTIVE;
816 
817     dsi->dropSite = shell;
818 
819     rect.x = 0;
820     rect.y = 0;
821     rect.width = XtWidth(shell);
822     rect.height = XtHeight(shell);
823 
824     _XmRegionUnionRectWithRegion(&rect, r, r);
825 
826     dsi->region = r;
827 
828     XtAddCallback(shell, XmNdestroyCallback, destroyInfo, (XtPointer)dsm);
829 
830     return dsi;
831 }
832 
833 
834 static void
addChildToComposite(XmDropSiteInfo pi,XmDropSiteInfo ci,short pos)835 addChildToComposite(XmDropSiteInfo pi, XmDropSiteInfo ci, short pos)
836 {
837     DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:addChildToComposite(%d)\n",
838     	__FILE__, __LINE__));
839 
840     if (pi == NULL || ci == NULL)
841 	return;
842 
843     if (pi->dropSiteType != XmDROP_SITE_COMPOSITE)
844     {
845 	_XmWarning(pi->dropSite,
846 		   "Can't add child to simple dropSite.");
847 	return;
848     }
849 
850     if (pos > pi->numChildren)
851     {
852 	_XmWarning(pi->dropSite,
853 		   "Position error adding child to composite dropSite.\n");
854 
855 	pos = pi->numChildren;
856     }
857 
858     if (pi->numChildren == pi->maxChildren)
859     {
860 
861 	if (pi->maxChildren == 0)
862 	{
863 
864 	    pi->maxChildren = 8;
865 
866 	    pi->children =
867 		(XmDropSiteInfo *) XtCalloc(pi->maxChildren,
868 					    sizeof(XmDropSiteInfo));
869 	}
870 	else
871 	{
872 
873 	    pi->maxChildren <<= 1;
874 
875 	    pi->children =
876 		(XmDropSiteInfo *) XtRealloc((char *)pi->children,
877 				     pi->maxChildren * sizeof(XmDropSiteInfo));
878 	}
879     }
880 
881     if (pi->numChildren)
882     {
883 
884 	/* T. Straumann: use mmove() !! (overlap)
885 	 * NOTE: src/dest swapped
886 	 */
887 	memmove(&pi->children[pos + 1],&pi->children[pos],
888 	        (pi->numChildren - pos) * sizeof(XmDropSiteInfo));
889     }
890 
891     pi->children[pos] = ci;
892     pi->numChildren++;
893 
894     ci->parent = pi;
895 
896     pi->leaf = False;
897 }
898 
899 
900 static void
removeChildFromComposite(XmDropSiteInfo pi,XmDropSiteInfo dsi)901 removeChildFromComposite(XmDropSiteInfo pi, XmDropSiteInfo dsi)
902 {
903     int i;
904 
905     DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:removeChildFromComposite(%d)\n",
906     	__FILE__, __LINE__));
907 
908     if (pi->dropSiteType != XmDROP_SITE_COMPOSITE)
909     {
910 	return;
911     }
912 
913     for (i = 0; i < pi->numChildren; i++)
914     {
915 	if (pi->children[i] == dsi)
916 	    break;
917     }
918 
919     if (i == pi->numChildren)
920     {
921 	return;
922     }
923 
924     if (i != pi->numChildren - 1)
925     {
926 	/* T. Straumann: use mmove() !! (overlap)
927 	 * NOTE: src/dest swapped
928 	 */
929 	memmove(&pi->children[i], &pi->children[i + 1],
930 	      (pi->numChildren - i - 1)*sizeof(XmDropSiteInfo));
931     }
932 
933     pi->numChildren--;
934 }
935 
936 
937 static void
destroyInfoRec(XmDropSiteInfo dsi,Boolean thorough)938 destroyInfoRec(XmDropSiteInfo dsi, Boolean thorough)
939 {
940     DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:destroyInfoRec(%d)\n",
941     	__FILE__, __LINE__));
942 
943     if (dsi->dropSiteType == XmDROP_SITE_COMPOSITE && thorough &&
944 	dsi->children != 0)
945     {
946 	XtFree((char *)dsi->children);
947     }
948 
949     if (!dsi->userRegion)
950     {
951 	_XmRegionDestroy(dsi->region);
952     }
953 
954     if (thorough)
955     {
956 	XtFree((char *)dsi);
957     }
958 }
959 
960 
961 /*
962  * create the per-widget information
963  */
964 static void
__XmDSMCreateInfo(XmDropSiteManagerObject object,Widget widget,ArgList args,Cardinal num_args)965 __XmDSMCreateInfo(XmDropSiteManagerObject object,
966 		  Widget widget,
967 		  ArgList args,
968 		  Cardinal num_args)
969 {
970     XmRegion r = _XmRegionCreate();
971     XmDropSiteInfo hr;
972     int x, y;
973     Cardinal i;
974     Window root;
975     unsigned int width, height, border;
976     XRectangle rect;
977     Widget shell;
978     XmDropSiteInfo info;
979 
980     DEBUGOUT(_LtDebug2(__FILE__, (Widget)object, widget,
981 		      "%s:__XmDSMCreateInfo(%d) - %i args\n",
982 		      __FILE__, __LINE__,
983 		      num_args
984 		      ));
985     DEBUGOUT(_LtDebugPrintArgList(__FILE__, (Widget)object, args, num_args, False));
986     DEBUGOUT(_LtDebug2("DRAGSINK", (Widget)object, widget,
987 		      "%s:__XmDSMCreateInfo(%d) - %i args\n",
988 		      __FILE__, __LINE__,
989 		      num_args
990 		      ));
991     DEBUGOUT(_LtDebugPrintArgList("DRAGSINK", (Widget)object, args, num_args, False));
992 
993     DSMStartUpdate(object, widget);
994 
995     hr = (XmDropSiteInfo) XtCalloc(1, sizeof(XmDropSiteInfoRec));
996 
997     hr->dropSite = widget;
998     hr->leaf = True;
999     XtGetSubresources(widget, (XtPointer)hr, NULL, NULL,
1000 		      _XmDSResources, _XmNumDSResources,
1001 		      args, num_args);
1002 
1003     if (hr->dropSiteActivity == XmDROP_SITE_ACTIVE &&
1004 	hr->dropProc == NULL)
1005     {
1006 	_XmWarning(widget, "Active dropSite missing dropProc\n");
1007     }
1008 
1009     if (hr->animationStyle == XmDRAG_UNDER_PIXMAP &&
1010 	hr->animationPixmap != None &&
1011         hr->animationPixmap != XmUNSPECIFIED_PIXMAP &&
1012 	hr->animationPixmapDepth == 0)
1013     {
1014 	XGetGeometry(XtDisplay(widget), hr->animationPixmap, &root,
1015 		     &x, &y, &width, &height, &border,
1016 		     &hr->animationPixmapDepth);
1017     }
1018 
1019     if (hr->dropSiteType == XmDROP_SITE_COMPOSITE &&
1020 	(hr->dropRectangles != NULL || hr->numDropRectangles != 1))
1021     {
1022 	_XmWarning(widget, "Can't set rectangles/numRectangles on composite.");
1023 	hr->dropRectangles = NULL;
1024 	hr->numDropRectangles = 1;
1025     }
1026 
1027     if (hr->dropRectangles == NULL)
1028     {
1029 	rect.x = -XtBorderWidth(widget);
1030 	rect.y = -XtBorderWidth(widget);
1031 	rect.width = XtBorderWidth(widget) * 2 + XtWidth(widget);
1032 	rect.height = XtBorderWidth(widget) * 2 + XtHeight(widget);
1033 
1034 	_XmRegionUnionRectWithRegion(&rect, r, r);
1035     }
1036     else
1037     {
1038 	for (i = 0; i < hr->numDropRectangles; i++)
1039 	{
1040 	    _XmRegionUnionRectWithRegion(&hr->dropRectangles[i], r, r);
1041 	}
1042 
1043 	hr->userRegion = True;
1044     }
1045     hr->region = r;
1046 
1047     XtAddCallback(widget, XmNdestroyCallback, destroyInfo, (XtPointer)object);
1048 
1049     shell = widget;
1050     while (shell && !XtIsShell(shell))
1051     {
1052 	shell = XtParent(shell);
1053     }
1054 
1055     hr->target_index = _XmTargetsToIndex(shell,
1056 					 hr->importTargets,
1057 					 hr->numImportTargets);
1058 
1059     info = (XmDropSiteInfo) DSMWidgetToInfo(object, widget);
1060 
1061     if (info == NULL)
1062     {
1063 	DSMRegisterInfo(object, widget, (XtPointer)hr);
1064 
1065 	DSMInsertInfo(object, (XtPointer)hr, NULL);
1066 
1067 	DSMEndUpdate(object, widget);
1068     }
1069     else
1070     {
1071 	if (info->implicit)
1072 	{
1073 	    _XmWarning(widget,
1074 		       "Registering a widget as a dropSite out of sequence.\n");
1075 	}
1076 	else
1077 	{
1078 	    _XmWarning(widget,
1079 		       "Can't register widget as a dropSite more than once.");
1080 	}
1081 
1082 	destroyInfoRec(hr, True);
1083     }
1084 }
1085 
1086 
1087 static void
__XmDSMDestroyInfo(XmDropSiteManagerObject dsm,Widget widget)1088 __XmDSMDestroyInfo(XmDropSiteManagerObject dsm,
1089 		   Widget widget)
1090 {
1091     XmDropSiteInfo dsi;
1092 
1093     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM DestroyInfo\n"));
1094 
1095     dsi = (XmDropSiteInfo) DSMWidgetToInfo(dsm, widget);
1096 
1097     if (!dsi)
1098     {
1099 	_XmWarning(widget,
1100 		   "Attempt to destroy dropSite info for widget that\n"
1101 		   "hasn't been added as a dropSite.\n");
1102 	return;
1103     }
1104 
1105     DSMStartUpdate(dsm, widget);
1106 
1107     if (dsi == (XmDropSiteInfo) DS_CurInfo(dsm))
1108     {
1109 	DS_CurInfo(dsm) = NULL;
1110     }
1111 
1112     DSMRemoveInfo(dsm, (XtPointer)dsi);
1113 
1114     destroyInfoRec(dsi, True);
1115 
1116     DSMEndUpdate(dsm, widget);
1117 }
1118 
1119 
1120 static void
__XmDSMStartUpdate(XmDropSiteManagerObject dsm,Widget widget)1121 __XmDSMStartUpdate(XmDropSiteManagerObject dsm,
1122 		   Widget widget)
1123 {
1124     Widget shell = widget;
1125     XmDropSiteInfo info;
1126 
1127     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM StartUpdate\n"));
1128 
1129     while (!XtIsShell(shell))
1130     {
1131 	shell = XtParent(shell);
1132     }
1133 
1134     info = (XmDropSiteInfo) DSMWidgetToInfo(dsm, shell);
1135 
1136     if (info == NULL)
1137     {
1138 	return;
1139     }
1140 
1141     if (!info->isShell)
1142     {
1143 	return;
1144     }
1145 
1146     info->inUpdate++;
1147 }
1148 
1149 
1150 static void
__XmDSMRetrieveInfo(XmDropSiteManagerObject dsm,Widget widget,ArgList args,Cardinal num_args)1151 __XmDSMRetrieveInfo(XmDropSiteManagerObject dsm,
1152 		    Widget widget,
1153 		    ArgList args,
1154 		    Cardinal num_args)
1155 {
1156     XmDropSiteInfo info;
1157 
1158     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM RetrieveInfo\n"));
1159 
1160     if (XmIsDragContext(widget))
1161     {
1162 
1163 	if (widget == DS_CurDragContext(dsm))
1164 	{
1165 	    info = (XmDropSiteInfo) DS_CurInfo(dsm);
1166 	}
1167 	else
1168 	{
1169 	    return;
1170 	}
1171     }
1172     else
1173     {
1174 	info = (XmDropSiteInfo) DSMWidgetToInfo(dsm, widget);
1175     }
1176 
1177     if (!info)
1178     {
1179 	return;
1180     }
1181 
1182     XtGetSubvalues((XtPointer)info,
1183 		   _XmDSResources, _XmNumDSResources,
1184 		   args, num_args);
1185 }
1186 
1187 
1188 static void
__XmDSMUpdateInfo(XmDropSiteManagerObject dsm,Widget widget,ArgList args,Cardinal num_args)1189 __XmDSMUpdateInfo(XmDropSiteManagerObject dsm,
1190 		  Widget widget,
1191 		  ArgList args,
1192 		  Cardinal num_args)
1193 {
1194     XmDropSiteInfo dsi, ndsi;
1195     XmRegion r;
1196     int x, y;
1197     Cardinal i;
1198     Window root;
1199     unsigned int width, height, border;
1200 
1201     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM UpdateInfo\n"));
1202 
1203     dsi = (XmDropSiteInfo) DSMWidgetToInfo(dsm, widget);
1204 
1205     if (!dsi || dsi->implicit)
1206     {
1207 	return;
1208     }
1209 
1210     DSMStartUpdate(dsm, widget);
1211 
1212     ndsi = (XmDropSiteInfo) XtMalloc(sizeof(XmDropSiteInfoRec));
1213 
1214     memcpy(ndsi, dsi, sizeof(XmDropSiteInfoRec));
1215 
1216     XtSetSubvalues((XtPointer)ndsi,
1217 		   _XmDSResources, _XmNumDSResources,
1218 		   args, num_args);
1219 
1220     /* from here, treat it like a normal set_values() call. */
1221     if (ndsi->dropSiteType != dsi->dropSiteType)
1222     {
1223 	_XmWarning(widget, "Can't change DropSiteType after creation\n");
1224 	ndsi->dropSiteType = dsi->dropSiteType;
1225     }
1226 
1227     if (ndsi->dropRectangles != dsi->dropRectangles ||
1228 	ndsi->numDropRectangles != dsi->numDropRectangles)
1229     {
1230 
1231 	if (ndsi->dropSiteType == XmDROP_SITE_SIMPLE)
1232 	{
1233 	    r = _XmRegionCreate();
1234 
1235 	    for (i = 0; i < ndsi->numDropRectangles; i++)
1236 	    {
1237 		_XmRegionUnionRectWithRegion(&ndsi->dropRectangles[i], r, r);
1238 	    }
1239 
1240 	    ndsi->region = r;
1241 
1242 	    _XmRegionDestroy(dsi->region);
1243 	}
1244 	else
1245 	{
1246 	    _XmWarning(widget, "Can't change rectangles for composite.\n");
1247 	}
1248     }
1249 
1250     if (ndsi->animationStyle == XmDRAG_UNDER_PIXMAP &&
1251 	ndsi->animationPixmap != None &&
1252         ndsi->animationPixmap != XmUNSPECIFIED_PIXMAP &&
1253         ndsi->animationPixmapDepth == 0)
1254     {
1255 	XGetGeometry(XtDisplay(widget), ndsi->animationPixmap, &root,
1256 		     &x, &y, &width, &height, &border,
1257 		     &ndsi->animationPixmapDepth);
1258     }
1259 
1260     memcpy(dsi, ndsi, sizeof(XmDropSiteInfoRec));
1261 
1262     XtFree((char *)ndsi);
1263 
1264     DSMEndUpdate(dsm, widget);
1265 }
1266 
1267 
1268 static void
__XmDSMEndUpdate(XmDropSiteManagerObject dsm,Widget widget)1269 __XmDSMEndUpdate(XmDropSiteManagerObject dsm,
1270 		 Widget widget)
1271 {
1272     XmDropSiteInfo dsi;
1273     Widget shell;
1274     XmTreeUpdateCallbackStruct tucbs;
1275 
1276     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM EndUpdate\n"));
1277 
1278     shell = widget;
1279 
1280     while (!XtIsShell(shell))
1281     {
1282 	shell = XtParent(shell);
1283     }
1284 
1285     dsi = (XmDropSiteInfo) DSMWidgetToInfo(dsm, shell);
1286 
1287     if (dsi == NULL)
1288     {
1289 	return;
1290     }
1291 
1292     if (dsi->inUpdate > 0)
1293     {
1294 	dsi->inUpdate--;
1295     }
1296 
1297     if (dsi->inUpdate == 0 && XtIsRealized(shell))
1298     {
1299 
1300 	if (_XmGetDragProtocolStyle(shell) != XmDRAG_DYNAMIC)
1301 	{
1302 
1303 	    tucbs.reason = XmCR_ADD_DROP_SITE;
1304 	    tucbs.event = NULL;
1305 	    tucbs.widget = shell;
1306 
1307 	    DS_TreeUpdateProc(dsm) ((Widget)dsm, NULL, &tucbs);
1308 	}
1309 	else
1310 	{
1311 	    DSMSyncTree(dsm, shell);
1312 	}
1313 
1314     }
1315 }
1316 
1317 
1318 static void
__XmDSMUpdateDSM(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)1319 __XmDSMUpdateDSM(XmDropSiteManagerObject dsm,
1320 		 XtPointer clientData,
1321 		 XtPointer callData)
1322 {
1323     XmDragDropCallbackStruct *cbs = (XmDragDropCallbackStruct *) callData;
1324 
1325     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM UpdateDSM\n"));
1326     DEBUGOUT(_LtDebug("DRAGSINK", (Widget)dsm, "__XmDSMUpdateDSM\n"));
1327 
1328     switch (cbs->any.reason)
1329     {
1330     case XmCR_TOP_LEVEL_ENTER:
1331     case XmCR_TOP_LEVEL_LEAVE:
1332 	DSMChangeRoot(dsm, clientData, callData);
1333 	break;
1334 
1335     case XmCR_DRAG_MOTION:
1336 	DSMProcessMotion(dsm, clientData, callData);
1337 	break;
1338 
1339     case XmCR_DROP_START:
1340 	DSMProcessDrop(dsm, clientData, callData);
1341 	break;
1342 
1343     case XmCR_OPERATION_CHANGED:
1344 	DSMOperationChanged(dsm, clientData, callData);
1345 	break;
1346 
1347     default:
1348 	DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm,
1349 			  "DSMUpdate default: %d\n", cbs->any.reason));
1350 	break;
1351     }
1352 }
1353 
1354 
1355 static Boolean
loc_in_info(XmDropSiteManagerObject dsm,XmDropSiteInfo dsi,Position x,Position y)1356 loc_in_info(XmDropSiteManagerObject dsm, XmDropSiteInfo dsi,
1357 	    Position x, Position y)
1358 {
1359     Position tx, ty;
1360 
1361     DEBUGOUT(_LtDebug2(__FILE__, (Widget)dsm, dsi->dropSite, "%s:loc_in_info(%d) - %+i%+i %+i%+i\n",
1362     	__FILE__, __LINE__,
1363     	x, y,
1364     	DS_RootX(dsm), DS_RootY(dsm)));
1365 
1366     XtTranslateCoords(dsi->dropSite, 0, 0, &tx, &ty);
1367 
1368     tx -= DS_RootX(dsm);
1369     ty -= DS_RootY(dsm);
1370 
1371     x -= tx;
1372     y -= ty;
1373     DEBUGOUT(_LtDebug0(__FILE__, (Widget)dsm, "\t%+i%+i\n",
1374     	x, y));
1375 
1376     if (_XmRegionPointInRegion(dsi->region, x, y))
1377     {
1378 	return True;
1379     }
1380     else
1381     {
1382 	return False;
1383     }
1384 }
1385 
1386 
1387 static XmDropSiteInfo
loc_to_info(XmDropSiteManagerObject dsm,XmDropSiteInfo dsi,Position x,Position y)1388 loc_to_info(XmDropSiteManagerObject dsm, XmDropSiteInfo dsi,
1389 	    Position x, Position y)
1390 {
1391     int i;
1392     XmDropSiteInfo child;
1393 
1394     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "%s:loc_to_info(%d) - %+i%+i %s\n",
1395     	__FILE__, __LINE__,
1396     	x, y,
1397     	dsi->leaf ? "Leaf" : "Not leaf"));
1398 
1399     if (!dsi->leaf)
1400     {
1401 	DEBUGOUT(_LtDebug0(__FILE__, (Widget)dsm, "\t%i children\n", dsi->numChildren));
1402 	for (i = 0; i < dsi->numChildren; i++)
1403 	{
1404 	    child = dsi->children[i];
1405 
1406 	    if (loc_in_info(dsm, child, x, y))
1407 	    {
1408 		if (child->dropSiteActivity == XmDROP_SITE_INACTIVE)
1409 		{
1410 		    return NULL;
1411 		}
1412 
1413 		if (!child->leaf)
1414 		{
1415 		    XmDropSiteInfo grandchild;
1416 
1417 		    grandchild = loc_to_info(dsm, child, x, y);
1418 
1419 		    if (grandchild)
1420 		    {
1421 			return grandchild;
1422 		    }
1423 		}
1424 
1425 		if (!child->implicit)
1426 		{
1427 		    return child;
1428 		}
1429 	    }
1430 	}
1431     }
1432 
1433     return NULL;
1434 }
1435 
1436 
1437 /**
1438  * Waider 14/06/98 I've just noticed that this function /has/ no
1439  * function other than, at the moment, to generate core dumps.
1440  */
1441 static void
animate(XmDropSiteManagerObject dsm,XmDragMotionClientDataStruct * cd,XmDragProcCallbackStruct * dpc)1442 animate(XmDropSiteManagerObject dsm,
1443 	XmDragMotionClientDataStruct * cd,
1444 	XmDragProcCallbackStruct *dpc)
1445 {
1446     XmDropSiteInfo dsi = (XmDropSiteInfo) DS_CurInfo(dsm);
1447     Widget dc;
1448 
1449     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "%s:animate(%d)\n",
1450     	__FILE__, __LINE__));
1451 
1452     if (dsi && dsi->animationStyle == XmDRAG_UNDER_NONE)
1453     {
1454 	return;
1455     }
1456 
1457     dc = DS_CurDragContext(dsm);
1458 }
1459 
1460 
1461 static void
drop_site_enter(XmDropSiteManagerObject dsm,XmDragMotionClientDataStruct * cd,XmDragMotionCallbackStruct * cbs,XmDropSiteInfo dsi,unsigned char ps)1462 drop_site_enter(XmDropSiteManagerObject dsm, XmDragMotionClientDataStruct * cd,
1463 		XmDragMotionCallbackStruct *cbs, XmDropSiteInfo dsi,
1464 		unsigned char ps)
1465 {
1466     XmDragProcCallbackStruct dpc;
1467     XmDropSiteEnterCallbackStruct dse;
1468     XRectangle extents;
1469     Position x, y;
1470     Atom *itargs;
1471     int nimps;
1472     Widget par;
1473 
1474     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "%s:drop_site_enter(%d)\n",
1475     	__FILE__, __LINE__));
1476 
1477     dpc.reason = XmCR_DROP_SITE_ENTER_MESSAGE;
1478     dpc.event = NULL;
1479     dpc.timeStamp = cbs->timeStamp;
1480     dpc.dragContext = DS_CurDragContext(dsm);
1481     dpc.x = DS_CurX(dsm);
1482     dpc.y = DS_CurY(dsm);
1483     dpc.animate = True;
1484 
1485     dpc.operations = cbs->operations & dsi->dropSiteOperations;
1486     if (dpc.operations & XmDROP_MOVE)
1487     {
1488 	dpc.operation = XmDROP_MOVE;
1489     }
1490     else if (dpc.operations & XmDROP_COPY)
1491     {
1492 	dpc.operation = XmDROP_COPY;
1493     }
1494     else if (dpc.operations & XmDROP_LINK)
1495     {
1496 	dpc.operation = XmDROP_LINK;
1497     }
1498     else
1499     {
1500 	dpc.operation = XmDROP_NOOP;
1501 	dpc.operations = XmDROP_NOOP;
1502     }
1503 
1504     if (dsi->external)
1505     {
1506 	par = XtParent(dsm);
1507     }
1508     else
1509     {
1510 	par = dsi->dropSite;
1511     }
1512 
1513     while (!XtIsShell(par))
1514     {
1515 	par = XtParent(par);
1516     }
1517 
1518     /* a little self preservation here.  The user defined import targets table
1519      * might not be around. */
1520     nimps = _XmIndexToTargets(par, dsi->target_index, &itargs);
1521 
1522     if (dpc.operation != XmDROP_NOOP &&
1523 	XmTargetsAreCompatible(XtDisplay(dsm),
1524 			       DC_ExportTargets(dpc.dragContext),
1525 			       DC_NumExportTargets(dpc.dragContext),
1526 			       itargs, nimps))
1527     {
1528 	dpc.dropSiteStatus = XmVALID_DROP_SITE;
1529     }
1530     else
1531     {
1532 	dpc.dropSiteStatus = XmINVALID_DROP_SITE;
1533     }
1534 
1535     dpc.animate = True;
1536 
1537     if (ps == XmDRAG_DYNAMIC && !dsi->external && dsi->dragProc)
1538     {
1539 	XtTranslateCoords(dsi->dropSite, 0, 0, &x, &y);
1540 
1541 	dpc.x -= x;
1542 	dpc.y -= y;
1543 
1544 	(*dsi->dragProc) (dsi->dropSite, NULL, &dpc);
1545     }
1546 
1547     if (dpc.animate && dpc.dropSiteStatus == XmVALID_DROP_SITE)
1548     {
1549 	animate(dsm, cd, &dpc);
1550     }
1551 
1552     DS_CurDropSiteStatus(dsm) = dpc.dropSiteStatus;
1553     DS_CurAnimate(dsm) = dpc.animate;
1554     DS_CurOperation(dsm) = dpc.operation;
1555     DS_CurOperations(dsm) = dpc.operations;
1556 
1557     if (DS_NotifyProc(dsm) != NULL)
1558     {
1559 
1560 	_XmRegionGetExtents(dsi->region, &extents);
1561 
1562 	dse.reason = XmCR_DROP_SITE_ENTER;
1563 	dse.event = NULL;
1564 	dse.timeStamp = dpc.timeStamp;
1565 	dse.operation = dpc.operation;
1566 	dse.operations = dpc.operations;
1567 	dse.dropSiteStatus = dpc.dropSiteStatus;
1568 
1569 	if (dsi->external)
1570 	{
1571 	    dse.x = DS_RootX(dsm) + extents.x;
1572 	    dse.y = DS_RootY(dsm) + extents.y;
1573 	}
1574 	else
1575 	{
1576 	    XtTranslateCoords(dsi->dropSite, 0, 0, &x, &y);
1577 
1578 	    dse.x = x + extents.x;
1579 	    dse.y = y + extents.y;
1580 	}
1581 
1582 	(*DS_NotifyProc(dsm)) ((Widget)dsm, DS_ClientData(dsm), (XtPointer)&dse);
1583     }
1584 }
1585 
1586 
1587 static void
drop_site_leave(XmDropSiteManagerObject dsm,XmDragMotionClientDataStruct * cd,XmDragMotionCallbackStruct * cbs,XmDropSiteInfo dsi,unsigned char ps)1588 drop_site_leave(XmDropSiteManagerObject dsm, XmDragMotionClientDataStruct * cd,
1589 		XmDragMotionCallbackStruct *cbs, XmDropSiteInfo dsi,
1590 		unsigned char ps)
1591 {
1592     XmDragProcCallbackStruct dpc;
1593     XmDropSiteLeaveCallbackStruct dsl;
1594     Position x, y;
1595 
1596     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "%s:drop_site_leave(%d)\n",
1597     	__FILE__, __LINE__));
1598 
1599     dpc.reason = XmCR_DROP_SITE_LEAVE_MESSAGE;
1600     dpc.event = NULL;
1601     dpc.timeStamp = cbs->timeStamp;
1602     dpc.dragContext = DS_CurDragContext(dsm);
1603     dpc.x = DS_OldX(dsm);
1604     dpc.y = DS_OldY(dsm);
1605     dpc.operation = cbs->operation;
1606     dpc.operations = cbs->operations;
1607     dpc.animate = DS_CurAnimate(dsm);
1608     dpc.dropSiteStatus = DS_CurDropSiteStatus(dsm);
1609 
1610     if (ps == XmDRAG_DYNAMIC && !dsi->external && dsi->dragProc)
1611     {
1612 
1613 	XtTranslateCoords(dsi->dropSite, 0, 0, &x, &y);
1614 
1615 	dpc.x -= x;
1616 	dpc.y -= y;
1617 
1618 	(*dsi->dragProc) (dsi->dropSite, NULL, &dpc);
1619     }
1620 
1621     if (dpc.animate && dpc.dropSiteStatus == XmVALID_DROP_SITE)
1622     {
1623 	animate(dsm, cd, &dpc);
1624     }
1625 
1626     if (DS_NotifyProc(dsm) != NULL)
1627     {
1628 
1629 	dsl.reason = XmCR_DROP_SITE_LEAVE;
1630 	dsl.event = NULL;
1631 	dsl.timeStamp = dpc.timeStamp;
1632 
1633 	(*DS_NotifyProc(dsm)) ((Widget)dsm, DS_ClientData(dsm), (XtPointer)&dsl);
1634     }
1635 }
1636 
1637 
1638 static void
drag_motion(XmDropSiteManagerObject dsm,XmDragMotionClientDataStruct * cd,XmDragMotionCallbackStruct * cbs,XmDropSiteInfo dsi,unsigned char ps)1639 drag_motion(XmDropSiteManagerObject dsm, XmDragMotionClientDataStruct * cd,
1640 	    XmDragMotionCallbackStruct *cbs, XmDropSiteInfo dsi,
1641 	    unsigned char ps)
1642 {
1643     XmDragProcCallbackStruct dpc;
1644     XmDragMotionCallbackStruct dm;
1645     Position x, y;
1646 
1647     DEBUGOUT(_LtDebug("DRAGSINK", (Widget)dsm, "%s:drag_motion(%d)\n",
1648     	__FILE__, __LINE__));
1649 
1650     dpc.reason = XmCR_DROP_SITE_MOTION_MESSAGE;
1651     dpc.event = NULL;
1652     dpc.timeStamp = cbs->timeStamp;
1653     dpc.dragContext = DS_CurDragContext(dsm);
1654     dpc.x = DS_CurX(dsm);
1655     dpc.y = DS_CurY(dsm);
1656     dpc.operation = cbs->operation;
1657     dpc.operations = cbs->operations;
1658     dpc.animate = DS_CurAnimate(dsm);
1659     dpc.dropSiteStatus = DS_CurDropSiteStatus(dsm);
1660 
1661     if (dsi != NULL)
1662     {
1663 
1664 	dpc.operation = DS_CurOperation(dsm);
1665 	dpc.operations = DS_CurOperations(dsm);
1666 
1667 	if (ps == XmDRAG_DYNAMIC && !dsi->external && dsi->dragProc)
1668 	{
1669 	    XtTranslateCoords(dsi->dropSite, 0, 0, &x, &y);
1670 
1671 	    dpc.x -= x;
1672 	    dpc.y -= y;
1673 
1674 	    (*dsi->dragProc) (dsi->dropSite, NULL, &dpc);
1675 	}
1676 
1677 	if (dpc.animate && dpc.dropSiteStatus != DS_CurDropSiteStatus(dsm))
1678 	{
1679 	    if (dpc.dropSiteStatus == XmVALID_DROP_SITE)
1680 	    {
1681 		dpc.reason = XmCR_DROP_SITE_ENTER;
1682 	    }
1683 	    else
1684 	    {
1685 		dpc.reason = XmCR_DROP_SITE_LEAVE;
1686 	    }
1687 
1688 	    animate(dsm, cd, &dpc);
1689 
1690 	    dpc.reason = XmCR_DROP_SITE_MOTION_MESSAGE;
1691 	}
1692 
1693 	DS_CurDropSiteStatus(dsm) = dpc.dropSiteStatus;
1694 	DS_CurAnimate(dsm) = dpc.animate;
1695 	DS_CurOperation(dsm) = dpc.operation;
1696 	DS_CurOperations(dsm) = dpc.operations;
1697 
1698     }
1699     else
1700     {
1701 	dpc.operation = cbs->operation;
1702 	dpc.operations = cbs->operations;
1703 	dpc.dropSiteStatus = XmNO_DROP_SITE;
1704     }
1705 
1706     if (DS_NotifyProc(dsm) != NULL)
1707     {
1708 	dm.reason = XmCR_DRAG_MOTION;
1709 	dm.event = NULL;
1710 	dm.timeStamp = dpc.timeStamp;
1711 	dm.x = DS_CurX(dsm);
1712 	dm.y = DS_CurY(dsm);
1713 	dm.operation = dpc.operation;
1714 	dm.operations = dpc.operations;
1715 	dm.dropSiteStatus = dpc.dropSiteStatus;
1716 
1717 	(*DS_NotifyProc(dsm)) ((Widget)dsm, DS_ClientData(dsm), (XtPointer)&dm);
1718     }
1719 }
1720 
1721 
1722 /*
1723  * When a drag motion event is sent to this client, we handle
1724  * the notification of the drop site (if it has drag under effects)
1725  */
1726 static void
__XmDSMProcessMotion(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)1727 __XmDSMProcessMotion(XmDropSiteManagerObject dsm,
1728 		     XtPointer clientData,
1729 		     XtPointer callData)
1730 {
1731     XmDragMotionCallbackStruct *cbs = (XmDragMotionCallbackStruct *)callData;
1732     XmDragMotionClientDataStruct *cd = (XmDragMotionClientDataStruct *) clientData;
1733     XmDropSiteInfo dsi = (XmDropSiteInfo) DS_CurInfo(dsm);
1734     XmDropSiteInfo ndsi;
1735     unsigned char ps;
1736 
1737     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "__XmDSMProcessMotion - %s %+i%+i %+i%+i\n",
1738     	_LtDebugDragAndDropMessageType2String(cbs->reason),
1739     	cbs->x, cbs->y, DS_RootX(dsm), DS_RootY(dsm)));
1740     DEBUGOUT(_LtDebug("DRAGSINK", (Widget)dsm, "__XmDSMProcessMotion - %s %+i%+i %+i%+i\n",
1741     	_LtDebugDragAndDropMessageType2String(cbs->reason),
1742     	cbs->x, cbs->y, DS_RootX(dsm), DS_RootY(dsm)));
1743 
1744     if (DS_CurDragContext(dsm) == NULL)
1745     {
1746 	_XmWarning((Widget)dsm, "Eeek!  Where'd that come from? %s(%d)\n",
1747 		__FILE__, __LINE__);
1748 	return;
1749     }
1750 
1751     DS_CurTime(dsm) = cbs->timeStamp;
1752     DS_OldX(dsm) = DS_CurX(dsm);
1753     DS_OldY(dsm) = DS_CurY(dsm);
1754     DS_CurX(dsm) = cbs->x;
1755     DS_CurY(dsm) = cbs->y;
1756 
1757     ps = _XmGetActiveProtocolStyle(DS_CurDragContext(dsm));
1758 
1759     if (DS_DSRoot(dsm) != NULL)
1760     {
1761 	ndsi = loc_to_info(dsm, (XmDropSiteInfo) DS_DSRoot(dsm),
1762 			   cbs->x - DS_RootX(dsm),
1763 			   cbs->y - DS_RootY(dsm));
1764 
1765 	if (ndsi != dsi)
1766 	{
1767 	    if (dsi)
1768 	    {
1769 		drop_site_leave(dsm, cd, cbs, dsi, ps);
1770 	    }
1771 
1772             DEBUGOUT(_LtDebug(__FILE__,
1773                               (Widget)dsm, "Setting dsi to %p\n", ndsi ));
1774             DEBUGOUT(_LtDebug("DRAGSINK",
1775                               (Widget)dsm, "Setting dsi to %s\n",
1776                               ndsi ? XtName(ndsi->dropSite) : "NULL"));
1777 	    DS_CurInfo(dsm) = (XtPointer)ndsi;
1778 
1779 	    if (ndsi)
1780 	    {
1781 		drop_site_enter(dsm, cd, cbs, ndsi, ps);
1782 	    }
1783 	}
1784     }
1785 
1786     DEBUGOUT(_LtDebug("DRAGSINK",
1787                       (Widget)dsm, "Dragging on %s\n",
1788                       dsi ? XtName(dsi->dropSite) : "NULL"));
1789     drag_motion(dsm, cd, cbs, dsi, ps);
1790 }
1791 
1792 
1793 /*
1794  * When the drop is started (BDrag is released), we let the drop site know that
1795  * it's being dropped in
1796  */
1797 static void
__XmDSMProcessDrop(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)1798 __XmDSMProcessDrop(XmDropSiteManagerObject dsm,
1799 		   XtPointer clientData,
1800 		   XtPointer callData)
1801 {
1802     XmDragTopLevelClientDataStruct *cd = (XmDragTopLevelClientDataStruct *) clientData;
1803     XmDropStartCallbackStruct *cbs = (XmDropStartCallbackStruct *)callData;
1804     XmDropProcCallbackStruct dpc;
1805     Widget dc;
1806     XmDropSiteInfo dsi = NULL, rsi = NULL;
1807     Arg al[2];
1808     int ac;
1809     Position x, y;
1810     Widget par;
1811     Cardinal nimps;
1812     Atom *itargs;
1813 
1814     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "__XmDSMProcessDrop\n"));
1815     DEBUGOUT(_LtDebug("DRAGSINK", (Widget)dsm, "__XmDSMProcessDrop %s %s\n",
1816     	cbs->dropAction == XmDROP ? "XmDROP" : "not XmDROP",
1817     	cbs->dropSiteStatus == XmDROP_SITE_VALID ? "XmDROP_SITE_VALID" : "not XmDROP_SITE_VALID"));
1818 
1819     dc = XmGetDragContext((Widget)dsm, cbs->timeStamp);
1820 
1821     if (dc == NULL)
1822     {
1823 	_XmWarning((Widget)dsm, "Eeek!  Where'd that come from? %s(%d)\n",
1824 		__FILE__, __LINE__);
1825 	return;
1826     }
1827 
1828     DS_CurTime(dsm) = cbs->timeStamp;
1829     DS_DSRoot(dsm) = DSMWidgetToInfo(dsm, cd->shell);
1830     DS_RootX(dsm) = cd->xOrigin;
1831     DS_RootY(dsm) = cd->yOrigin;
1832     DS_RootWidth(dsm) = cd->width;
1833     DS_RootHeight(dsm) = cd->height;
1834 
1835     rsi = (XmDropSiteInfo) DSMWidgetToInfo(dsm, cd->shell);
1836 
1837     if (rsi != NULL)
1838     {
1839 	dsi = loc_to_info(dsm, (XmDropSiteInfo) DS_DSRoot(dsm),
1840 			  cbs->x - cd->xOrigin, cbs->y - cd->yOrigin);
1841     }
1842 
1843     if (dsi == NULL)
1844     {
1845 	ac = 0;
1846 	XtSetArg(al[ac], XmNnumDropTransfers, 0);
1847 	ac++;
1848 	XtSetArg(al[ac], XmNtransferStatus, XmTRANSFER_FAILURE);
1849 	ac++;
1850 
1851 	XmDropTransferStart(dc, al, ac);
1852     }
1853     else
1854     {
1855 
1856 	DS_CurInfo(dsm) = (XtPointer)dsi;
1857 
1858 	dpc.reason = XmCR_DROP_MESSAGE;
1859 	dpc.event = cbs->event;
1860 	dpc.timeStamp = cbs->timeStamp;
1861 	dpc.dragContext = dc;
1862 
1863 	XtTranslateCoords(dsi->dropSite, 0, 0, &x, &y);
1864 
1865 	dpc.x = cbs->x - x;
1866 	dpc.y = cbs->y - y;
1867 
1868 	dpc.operations = cbs->operations & dsi->dropSiteOperations;
1869 	if (dpc.operations & XmDROP_MOVE)
1870 	{
1871 	    dpc.operation = XmDROP_MOVE;
1872 	}
1873 	else if (dpc.operations & XmDROP_COPY)
1874 	{
1875 	    dpc.operation = XmDROP_COPY;
1876 	}
1877 	else if (dpc.operations & XmDROP_LINK)
1878 	{
1879 	    dpc.operation = XmDROP_LINK;
1880 	}
1881 	else
1882 	{
1883 	    dpc.operation = XmDROP_NOOP;
1884 	    dpc.operations = XmDROP_NOOP;
1885 	}
1886 
1887 	if (dsi->external)
1888 	{
1889 	    par = XtParent(dsm);
1890 	}
1891 	else
1892 	{
1893 	    par = dsi->dropSite;
1894 	}
1895 
1896 	while (!XtIsShell(par))
1897 	{
1898 	    par = XtParent(par);
1899 	}
1900 
1901 	/* a little self preservation here.  The user defined import targets
1902 	 * table might not be around. */
1903 	nimps = _XmIndexToTargets(par, dsi->target_index, &itargs);
1904 
1905 	if (dpc.operation != XmDROP_NOOP &&
1906 	    XmTargetsAreCompatible(XtDisplay(dsm),
1907 				   DC_ExportTargets(dpc.dragContext),
1908 				   DC_NumExportTargets(dpc.dragContext),
1909 				   itargs, nimps))
1910 	{
1911 	    dpc.dropSiteStatus = XmVALID_DROP_SITE;
1912 	}
1913 	else
1914 	{
1915 	    dpc.dropSiteStatus = XmINVALID_DROP_SITE;
1916 	}
1917 
1918 	dpc.dropAction = cbs->dropAction;
1919 
1920 	/* T. Straumann: safe guard against NULL added */
1921 	if (dsi->dropProc)
1922 	{
1923 		(*dsi->dropProc) (dsi->dropSite, NULL, (XtPointer)&dpc);
1924 	}
1925 	else
1926 	{
1927 		_XmWarning((Widget)dsm, "__XmDSMProcessDrop():  no dsi->dropProc!\n");
1928 	}
1929 
1930 	cbs->operation = dpc.operation;
1931 	cbs->operations = dpc.operations;
1932 	cbs->dropSiteStatus = dpc.dropSiteStatus;
1933 	cbs->dropAction = dpc.dropAction;
1934     }
1935 
1936     if (DS_NotifyProc(dsm) != NULL)
1937     {
1938 	(*DS_NotifyProc(dsm)) ((Widget)dsm, DS_ClientData(dsm), (XtPointer)cbs);
1939     }
1940 }
1941 
1942 
1943 /*
1944  * We notify the current drop site (if any) that the operation of the drag
1945  * has changed
1946  */
1947 static void
__XmDSMOperationChanged(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)1948 __XmDSMOperationChanged(XmDropSiteManagerObject dsm,
1949 			XtPointer clientData,
1950 			XtPointer callData)
1951 {
1952     XmOperationChangedCallbackStruct *cbs = (XmOperationChangedCallbackStruct *)callData;
1953     XmDragMotionClientDataStruct *cd = (XmDragMotionClientDataStruct *) clientData;
1954     XmDragProcCallbackStruct dpc;
1955     unsigned char ps;
1956     XmDropSiteInfo dsi;
1957     Position x, y;
1958     Atom *itargs;
1959     int nimps;
1960     Widget par;
1961 
1962     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM OperationChanged\n"));
1963 
1964     if (DS_CurDragContext(dsm) == NULL)
1965     {
1966 	_XmWarning((Widget)dsm, "Eeek!  Where'd that come from? %s(%d)\n",
1967 		__FILE__, __LINE__);
1968 	return;
1969     }
1970 
1971     ps = _XmGetActiveProtocolStyle(DS_CurDragContext(dsm));
1972 
1973     dpc.dragContext = DS_CurDragContext(dsm);
1974     dpc.reason = cbs->reason;
1975     dpc.timeStamp = cbs->timeStamp;
1976     dpc.operation = cbs->operation;
1977     dpc.operations = cbs->operations;
1978     dpc.x = DS_CurX(dsm);
1979     dpc.y = DS_CurY(dsm);
1980     dpc.dropSiteStatus = DS_CurDropSiteStatus(dsm);
1981     dpc.animate = DS_CurAnimate(dsm);
1982 
1983     if (DS_CurInfo(dsm) != NULL)
1984     {
1985 
1986 	dsi = (XmDropSiteInfo) DS_CurInfo(dsm);
1987 
1988 	dpc.operations = cbs->operations & dsi->dropSiteOperations;
1989 	if (dpc.operations & XmDROP_MOVE)
1990 	{
1991 	    dpc.operation = XmDROP_MOVE;
1992 	}
1993 	else if (dpc.operations & XmDROP_COPY)
1994 	{
1995 	    dpc.operation = XmDROP_COPY;
1996 	}
1997 	else if (dpc.operations & XmDROP_LINK)
1998 	{
1999 	    dpc.operation = XmDROP_LINK;
2000 	}
2001 	else
2002 	{
2003 	    dpc.operation = XmDROP_NOOP;
2004 	    dpc.operations = XmDROP_NOOP;
2005 	}
2006 
2007 	if (dsi->external)
2008 	{
2009 	    par = XtParent(dsm);
2010 	}
2011 	else
2012 	{
2013 	    par = dsi->dropSite;
2014 	}
2015 
2016 	while (!XtIsShell(par))
2017 	    par = XtParent(par);
2018 
2019 	/* a little self preservation here.  The user defined import targets
2020 	 * table might not be around. */
2021 	nimps = _XmIndexToTargets(par, dsi->target_index, &itargs);
2022 
2023 	if (dpc.operation != XmDROP_NOOP &&
2024 	    XmTargetsAreCompatible(XtDisplay(dsm),
2025 				   DC_ExportTargets(dpc.dragContext),
2026 				   DC_NumExportTargets(dpc.dragContext),
2027 				   itargs, nimps))
2028 	{
2029 	    dpc.dropSiteStatus = XmVALID_DROP_SITE;
2030 	}
2031 	else
2032 	{
2033 	    dpc.dropSiteStatus = XmINVALID_DROP_SITE;
2034 	}
2035 
2036 	dpc.animate = True;
2037 
2038 	if (ps == XmDRAG_DYNAMIC && !dsi->external && dsi->dragProc)
2039 	{
2040 
2041 	    XtTranslateCoords(dsi->dropSite, 0, 0, &x, &y);
2042 
2043 	    dpc.x -= x;
2044 	    dpc.y -= y;
2045 
2046 	    (*dsi->dragProc) (dsi->dropSite, NULL, &dpc);
2047 	}
2048 
2049 	if (dpc.animate && dpc.dropSiteStatus != DS_CurDropSiteStatus(dsm))
2050 	{
2051 
2052 	    if (dpc.dropSiteStatus == XmVALID_DROP_SITE)
2053 	    {
2054 		dpc.reason = XmCR_DROP_SITE_ENTER;
2055 	    }
2056 	    else
2057 	    {
2058 		dpc.reason = XmCR_DROP_SITE_LEAVE;
2059 	    }
2060 
2061 	    animate(dsm, cd, &dpc);
2062 
2063 	    dpc.reason = XmCR_DROP_SITE_MOTION_MESSAGE;
2064 	}
2065 
2066 	cbs->operation = dpc.operation;
2067 	cbs->operations = dpc.operations;
2068 	cbs->dropSiteStatus = dpc.dropSiteStatus;
2069 
2070 	DS_CurDropSiteStatus(dsm) = dpc.dropSiteStatus;
2071 	DS_CurAnimate(dsm) = dpc.animate;
2072 	DS_CurOperation(dsm) = dpc.operation;
2073 	DS_CurOperations(dsm) = dpc.operations;
2074     }
2075     else
2076     {
2077 	cbs->dropSiteStatus = XmNO_DROP_SITE;
2078     }
2079 
2080     if (DS_NotifyProc(dsm) != NULL)
2081     {
2082 	(*DS_NotifyProc(dsm)) ((Widget)dsm, DS_ClientData(dsm), (XtPointer)cbs);
2083     }
2084 }
2085 
2086 
2087 static void
__XmDSMChangeRoot(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)2088 __XmDSMChangeRoot(XmDropSiteManagerObject dsm,
2089 		  XtPointer clientData,
2090 		  XtPointer callData)
2091 {
2092     XmDragTopLevelClientDataStruct *cd =
2093     (XmDragTopLevelClientDataStruct *) clientData;
2094     XmDragDropCallbackStruct *cbs = (XmDragDropCallbackStruct *) callData;
2095 
2096     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "__XmDSMChangeRoot: %s\n",
2097 		      _LtDebugDragAndDropMessageType2String(cbs->any.reason)));
2098     DEBUGOUT(_LtDebug("DRAGSINK", (Widget)dsm, "__XmDSMChangeRoot: %s\n",
2099 		      _LtDebugDragAndDropMessageType2String(cbs->any.reason)));
2100 
2101     DS_CurTime(dsm) = cbs->any.timeStamp;
2102 
2103     if (cbs->any.reason == XmCR_TOP_LEVEL_ENTER)
2104     {
2105 	if (cd->sourceIsExternal)
2106 	{
2107 	    DS_CurDragContext(dsm) = XtVaCreateWidget("ExternalDragC",
2108 	    	xmDragContextClass, XmGetXmDisplay(XtDisplay(dsm)),
2109 		XmNsourceIsExternal, True,
2110 		XmNsourceWindow, cbs->tle.window,
2111 		XmNiccHandle, cbs->tle.iccHandle,
2112 		NULL);
2113 	    DC_CurrReceiverInfo(DS_CurDragContext(dsm)) = _XmAllocReceiverInfo((XmDragContext)DS_CurDragContext(dsm));
2114 	    (DC_CurrReceiverInfo(DS_CurDragContext(dsm)))->shell = cd->shell;
2115 	}
2116 	else
2117 	{
2118 	    DS_CurDragContext(dsm) = XmGetDragContext((Widget)dsm,
2119 						  cbs->any.timeStamp);
2120 	}
2121 
2122 	if (cd->shell)
2123 	{
2124 	    DS_DSRoot(dsm) = DSMWidgetToInfo(dsm, cd->shell);
2125 	}
2126 	else
2127 	{
2128 	    DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "EEEEEK!!!\n")); /* EEK! */
2129 	    DS_DSRoot(dsm) = NULL;
2130 	}
2131 
2132 	DS_RootX(dsm) = cd->xOrigin;
2133 	DS_RootY(dsm) = cd->yOrigin;
2134 	DS_RootWidth(dsm) = cd->width;
2135 	DS_RootHeight(dsm) = cd->height;
2136     }
2137     else
2138     {	/* LEAVE */
2139 	if (DS_CurInfo(dsm) != NULL)
2140 	{
2141 	    XmDragMotionCallbackStruct dm;
2142 	    XmDragMotionClientDataStruct dmc;
2143 
2144 	    dm.reason = XmCR_DROP_SITE_LEAVE;
2145 	    dm.event = cbs->any.event;
2146 	    dm.timeStamp = cbs->any.timeStamp;
2147 	    dm.x = DS_CurX(dsm);
2148 	    dm.y = DS_CurY(dsm);
2149 	    dm.operation = dm.operations = dm.dropSiteStatus = 0;
2150 
2151 	    dmc.window = cd->window;
2152 	    dmc.dos = cd->dos;
2153 
2154 	    drop_site_leave(dsm, &dmc, &dm, (XmDropSiteInfo) DS_CurInfo(dsm),
2155 			    _XmGetActiveProtocolStyle(DS_CurDragContext(dsm)));
2156 
2157 	    DS_CurInfo(dsm) = NULL;
2158 	}
2159 
2160 	DS_CurDragContext(dsm) = NULL;
2161 	DS_DSRoot(dsm) = NULL;
2162 	DS_RootX(dsm) = -1;
2163 	DS_RootY(dsm) = -1;
2164 	DS_RootWidth(dsm) = 0;
2165 	DS_RootHeight(dsm) = 0;
2166     }
2167 }
2168 
2169 
2170 static void
__XmDSMInsertInfo(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)2171 __XmDSMInsertInfo(XmDropSiteManagerObject dsm,
2172 		  XtPointer clientData,
2173 		  XtPointer callData)
2174 {
2175     XmDropSiteInfo dsi = (XmDropSiteInfo) clientData, pi;
2176     Widget w, parent;
2177     XmTreeUpdateCallbackStruct tucbs;
2178 
2179     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "%s:__XmDSMInsertInfo(%d)\n",
2180     	__FILE__, __LINE__));
2181     DEBUGOUT(_LtDebug("DRAGSINK", (Widget)dsm, "%s:__XmDSMInsertInfo(%d)\n",
2182     	__FILE__, __LINE__));
2183 
2184     w = dsi->dropSite;
2185 
2186     parent = w;
2187 
2188     do
2189     {
2190 	parent = XtParent(parent);
2191 
2192 	if ((pi = (XmDropSiteInfo) DSMWidgetToInfo(dsm, parent)) != NULL)
2193 	{
2194 	    break;
2195 	}
2196 
2197     }
2198     while (!XtIsShell(parent));
2199 
2200     if (pi == NULL)
2201     {
2202 
2203 	pi = createShellInfoRec(dsm, parent);
2204 
2205 	DSMRegisterInfo(dsm, parent, (XtPointer)pi);
2206 
2207 	addChildToComposite(pi, dsi, pi->numChildren);
2208 
2209 	if (DS_TreeUpdateProc(dsm) == NULL)
2210 	{
2211 	    return;
2212 	}
2213 
2214 	if (XtIsRealized(parent) &&
2215 	    _XmGetDragProtocolStyle(parent) != XmDYNAMIC)
2216 	{
2217 	    return;
2218 	}
2219 
2220 	tucbs.reason = XmCR_ADD_DROP_SITE;
2221 	tucbs.event = NULL;
2222 	tucbs.widget = parent;
2223 
2224 	DS_TreeUpdateProc(dsm) ((Widget)dsm, NULL, &tucbs);
2225     }
2226     else
2227     {
2228 
2229 	if (pi->dropSiteType == XmDROP_SITE_COMPOSITE)
2230 	{
2231 	    addChildToComposite(pi, dsi, pi->numChildren);
2232 	}
2233 	else
2234 	{
2235 	    _XmWarning(parent,
2236 		   "Attempt to add dropSite to parent that isn't composite\n");
2237 	}
2238     }
2239 }
2240 
2241 
2242 static void
__XmDSMRemoveInfo(XmDropSiteManagerObject dsm,XtPointer info)2243 __XmDSMRemoveInfo(XmDropSiteManagerObject dsm,
2244 		  XtPointer info)
2245 {
2246     XmDropSiteInfo dsi = (XmDropSiteInfo) info, pi;
2247     Widget w;
2248     XmTreeUpdateCallbackStruct tucbs;
2249 
2250     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM RemoveInfo\n"));
2251 
2252     w = dsi->dropSite;
2253 
2254     pi = dsi->parent;
2255 
2256     if (pi)
2257     {
2258 	removeChildFromComposite(pi, dsi);
2259     }
2260 
2261     DSMUnregisterInfo(dsm, (XtPointer)dsi);
2262 
2263     XtRemoveCallback(w, XmNdestroyCallback, destroyInfo, (XtPointer)dsm);
2264 
2265     if (dsi->parent == NULL)
2266     {
2267 	return;
2268     }
2269 
2270     if (pi->numChildren != 0)
2271     {
2272 	return;
2273     }
2274 
2275     if (!pi->implicit)
2276     {
2277 	return;
2278     }
2279 
2280     tucbs.reason = XmCR_REMOVE_DROP_SITE;
2281     tucbs.event = NULL;
2282     tucbs.widget = pi->dropSite;
2283 
2284     if (XtIsShell(pi->dropSite))
2285     {
2286 	if (DS_TreeUpdateProc(dsm) != NULL)
2287 	{
2288 	    DS_TreeUpdateProc(dsm) ((Widget)dsm, NULL, &tucbs);
2289 	}
2290     }
2291 
2292     DSMDestroyInfo(dsm, pi->dropSite);
2293 }
2294 
2295 
2296 static void
__XmDSMSyncTree(XmDropSiteManagerObject dsm,Widget shell)2297 __XmDSMSyncTree(XmDropSiteManagerObject dsm,
2298 		Widget shell)
2299 {
2300     DEBUGOUT(_LtDebug2(__FILE__, (Widget)dsm, shell, "%s:__XmDSMSyncTree(%d)\n",
2301     	__FILE__, __LINE__));
2302 }
2303 
2304 
2305 /*
2306  * This function creates (or replaces) the property on the shell widget
2307  * to contain the entire drop site database.
2308  */
2309 static int
__XmDSMGetTree(XmDropSiteManagerObject dsm,Widget shell,XtPointer dataPtr)2310 __XmDSMGetTree(XmDropSiteManagerObject dsm,
2311 	       Widget shell,
2312 	       XtPointer dataPtr)
2313 {
2314     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM GetTree\n"));
2315 
2316     return 0;
2317 }
2318 
2319 
2320 /*
2321  * Creates a hash table that goes from widgets to drop site information
2322  */
2323 static void
__XmDSMCreateDSInfoTable(XmDropSiteManagerObject dsm)2324 __XmDSMCreateDSInfoTable(XmDropSiteManagerObject dsm)
2325 {
2326     DSInfoTable *it;
2327 
2328     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM CreateDSInfoTable\n"));
2329 
2330     it = (DSInfoTable *) XtCalloc(1, sizeof(DSInfoTable));
2331 
2332     DS_DSTable(dsm) = (XtPointer)it;
2333     it->num_buckets = HASH_BUCKETS;
2334 
2335     it->buckets = (XmDropSiteInfo *) XtCalloc(it->num_buckets,
2336 					      sizeof(XmDropSiteInfo));
2337 }
2338 
2339 
2340 /*
2341  * destroys the hash table
2342  */
2343 static void
__XmDSMDestroyDSInfoTable(XmDropSiteManagerObject dsm)2344 __XmDSMDestroyDSInfoTable(XmDropSiteManagerObject dsm)
2345 {
2346     DSInfoTable *it;
2347 
2348     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM DestroyDSInfoTable\n"));
2349 
2350     it = (DSInfoTable *) DS_DSTable(dsm);
2351 
2352     XtFree((char *)it->buckets);
2353 
2354     XtFree((char *)it);
2355 }
2356 
2357 
2358 /*
2359  * adds a widget and its associated info to the hash table
2360  */
2361 static void
__XmDSMRegisterInfo(XmDropSiteManagerObject dsm,Widget widget,XtPointer info)2362 __XmDSMRegisterInfo(XmDropSiteManagerObject dsm,
2363 		    Widget widget,
2364 		    XtPointer info)
2365 {
2366     XmDropSiteInfo dsi = (XmDropSiteInfo) info;
2367     DSInfoTable *dst;
2368     long hash;
2369 
2370     DEBUGOUT(_LtDebug2(__FILE__, (Widget)dsm, widget, "%s:__XmDSMRegisterInfo(%d)\n",
2371     	__FILE__, __LINE__));
2372     DEBUGOUT(_LtDebug2("DRAGSINK", (Widget)dsm, widget, "%s:__XmDSMRegisterInfo(%d)\n",
2373     	__FILE__, __LINE__));
2374 
2375     if (dsi->registered)
2376     {
2377 	return;
2378     }
2379 
2380     dst = (DSInfoTable *) DS_DSTable(dsm);
2381 
2382     hash = (long)widget & dst->num_buckets;
2383 
2384     dsi->next = dst->buckets[hash];
2385     dst->buckets[hash] = dsi;
2386 
2387     dsi->registered = 1;
2388 }
2389 
2390 
2391 /*
2392  * retrieves the info for a given widget from the hash table
2393  */
2394 static XtPointer
__XmDSMWidgetToInfo(XmDropSiteManagerObject dsm,Widget widget)2395 __XmDSMWidgetToInfo(XmDropSiteManagerObject dsm,
2396 		    Widget widget)
2397 {
2398     DSInfoTable *info;
2399     long hash;
2400     XmDropSiteInfo dsi;
2401 
2402     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM WidgetToInfo\n"));
2403 
2404     info = (DSInfoTable *) DS_DSTable(dsm);
2405 
2406     hash = (long)widget & info->num_buckets;
2407 
2408     if (info->buckets[hash] == NULL)
2409     {
2410 	return NULL;
2411     }
2412 
2413     dsi = info->buckets[hash];
2414 
2415     while (dsi != NULL)
2416     {
2417 
2418 	if (dsi->dropSite == widget)
2419 	{
2420 	    return (XtPointer)dsi;
2421 	}
2422 
2423 	dsi = dsi->next;
2424     }
2425 
2426     return NULL;
2427 }
2428 
2429 
2430 /*
2431  * removes the info from the hash table, along with the widget that
2432  * hashes to it.
2433  */
2434 static void
__XmDSMUnregisterInfo(XmDropSiteManagerObject dsm,XtPointer info)2435 __XmDSMUnregisterInfo(XmDropSiteManagerObject dsm,
2436 		      XtPointer info)
2437 {
2438     XmDropSiteInfo dsi = (XmDropSiteInfo) info, *ptr;
2439     DSInfoTable *dst;
2440     long hash;
2441 
2442     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "DSM UnregisterInfo\n"));
2443 
2444     if (!dsi->registered)
2445     {
2446 	return;
2447     }
2448 
2449     dst = (DSInfoTable *) DS_DSTable(dsm);
2450 
2451     hash = (long)dsi->dropSite & dst->num_buckets;
2452 
2453     for (ptr = &dst->buckets[hash]; *ptr; ptr = &((*ptr)->next))
2454     {
2455 	if (*ptr == dsi)
2456 	{
2457 	    *ptr = dsi->next;
2458 	    break;
2459 	}
2460     }
2461 
2462     dsi->registered = 0;
2463 }
2464 
2465 
2466 extern void
_XmDSMUpdate(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)2467 _XmDSMUpdate(XmDropSiteManagerObject dsm,
2468 	     XtPointer clientData,
2469 	     XtPointer callData)
2470 {
2471     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "_XmDSMUpdate\n"));
2472 
2473     DSMUpdate(dsm, clientData, callData);
2474 }
2475 
2476 
2477 extern int
_XmDSMGetTreeFromDSM(XmDropSiteManagerObject dsm,Widget shell,XtPointer dataPtr)2478 _XmDSMGetTreeFromDSM(XmDropSiteManagerObject dsm,
2479 		     Widget shell,
2480 		     XtPointer dataPtr)
2481 {
2482     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "_XmDSMGetTreeFromDSM\n"));
2483 
2484     return DSMGetTreeFromDSM(dsm, shell, dataPtr);
2485 }
2486 
2487 
2488 extern Boolean
_XmDropSiteShell(Widget widget)2489 _XmDropSiteShell(Widget widget)
2490 {
2491     Widget disp = XmGetXmDisplay(XtDisplay(widget));
2492     XmDropSiteManagerObject dsm;
2493 
2494     DEBUGOUT(_LtDebug(__FILE__, widget, "_XmDropSiteShell\n"));
2495 
2496     dsm = _XmGetDropSiteManagerObject((XmDisplay)disp);
2497 
2498     if (!XtIsShell(widget))
2499     {
2500 	return False;
2501     }
2502 
2503     if (DSMWidgetToInfo(dsm, widget))
2504     {
2505 	return True;
2506     }
2507 
2508     return False;
2509 }
2510 
2511 
2512 static Boolean
has_ds_offspring(XmDropSiteManagerObject dsm,Widget w)2513 has_ds_offspring(XmDropSiteManagerObject dsm, Widget w)
2514 {
2515     Cardinal i;
2516 
2517     DEBUGOUT(_LtDebug(__FILE__, (Widget)dsm, "%s:has_ds_offspring(%d)\n",
2518     	__FILE__, __LINE__));
2519 
2520     if (!XtIsComposite(w))
2521     {
2522 	return False;
2523     }
2524 
2525     for (i = 0; i < MGR_NumChildren(w); i++)
2526     {
2527 
2528 	if (DSMWidgetToInfo(dsm, w))
2529 	{
2530 	    return True;
2531 	}
2532 
2533 	if (has_ds_offspring(dsm, MGR_Children(w)[i]))
2534 	{
2535 	    return True;
2536 	}
2537     }
2538 
2539     return False;
2540 }
2541 
2542 
2543 extern Boolean
_XmDropSiteWrapperCandidate(Widget widget)2544 _XmDropSiteWrapperCandidate(Widget widget)
2545 {
2546     Widget disp = XmGetXmDisplay(XtDisplay(widget)), par;
2547     XmDropSiteManagerObject dsm;
2548 
2549     DEBUGOUT(_LtDebug(__FILE__, widget, "_XmDropSiteWrapperCandidate\n"));
2550 
2551     dsm = _XmGetDropSiteManagerObject((XmDisplay)disp);
2552 
2553     if (!dsm)
2554     {
2555 	return False;
2556     }
2557 
2558     if (DSMWidgetToInfo(dsm, widget))
2559     {
2560 	return True;
2561     }
2562 
2563     if (!XtIsComposite(widget))
2564     {
2565 	return False;
2566     }
2567 
2568     par = widget;
2569     while (!XtIsShell(par))
2570     {
2571 	par = XtParent(par);
2572     }
2573 
2574     if (!_XmDropSiteShell(par))
2575     {
2576 	return False;
2577     }
2578 
2579     return has_ds_offspring(dsm, widget);
2580 }
2581 
2582 
2583 extern Widget
_XmGetActiveDropSite(Widget widget)2584 _XmGetActiveDropSite(Widget widget)
2585 {
2586     Widget disp = XmGetXmDisplay(XtDisplay(widget));
2587     XmDropSiteManagerObject dsm;
2588 
2589     DEBUGOUT(_LtDebug(__FILE__, widget, "_XmGetActiveDropSite\n"));
2590 
2591     dsm = _XmGetDropSiteManagerObject((XmDisplay)disp);
2592 
2593     if (DS_CurInfo(dsm) != NULL)
2594     {
2595 	return ((XmDropSiteInfo) DS_CurInfo(dsm))->dropSite;
2596     }
2597     else
2598     {
2599 	return NULL;
2600     }
2601 }
2602 
2603 
2604 extern void
_XmSyncDropSiteTree(Widget shell)2605 _XmSyncDropSiteTree(Widget shell)
2606 {
2607     Widget disp = XmGetXmDisplay(XtDisplay(shell));
2608     XmDropSiteManagerObject dsm;
2609 
2610     DEBUGOUT(_LtDebug(__FILE__, shell, "_XmSyncDropSiteTree\n"));
2611 
2612     dsm = _XmGetDropSiteManagerObject((XmDisplay)disp);
2613 
2614     DSMSyncTree(dsm, shell);
2615 }
2616 
2617 /*
2618  * dead function
2619  */
2620 
2621 extern void
_XmIEndUpdate(XtPointer client_data,XtIntervalId * interval_id)2622 _XmIEndUpdate(XtPointer client_data, XtIntervalId *interval_id)
2623 {
2624     DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:_XmIEndUpdate(%d)\n",
2625     	__FILE__, __LINE__));
2626 
2627 }
2628 
2629 
2630 extern void
XmDropSiteConfigureStackingOrder(Widget widget,Widget Sibling,Cardinal stack_mode)2631 XmDropSiteConfigureStackingOrder(Widget widget,
2632 				 Widget Sibling,
2633 				 Cardinal stack_mode)
2634 {
2635     DEBUGOUT(_LtDebug(__FILE__, widget, "XmDropSiteConfigureStackingOrder()\n"));
2636 
2637     /* FIX ME */
2638 }
2639 
2640 
2641 extern void
XmDropSiteEndUpdate(Widget widget)2642 XmDropSiteEndUpdate(Widget widget)
2643 {
2644     Widget disp = XmGetXmDisplay(XtDisplay(widget));
2645 
2646     DEBUGOUT(_LtDebug(__FILE__, widget, "XmDropSiteEndUpdate()\n"));
2647 
2648     DSMEndUpdate(_XmGetDropSiteManagerObject((XmDisplay)disp), widget);
2649 }
2650 
2651 
2652 extern Status
XmDropSiteQueryStackingOrder(Widget widget,Widget * parent_return,Widget ** child_returns,Cardinal * num_child_returns)2653 XmDropSiteQueryStackingOrder(Widget widget,
2654 			     Widget *parent_return,
2655 			     Widget **child_returns,
2656 			     Cardinal *num_child_returns)
2657 {
2658     DEBUGOUT(_LtDebug(__FILE__, widget, "XmDropSiteQueryStackingOrder()\n"));
2659 
2660     /* FIX ME */
2661 
2662     return 0;
2663 }
2664 
2665 
2666 extern void
XmDropSiteRegister(Widget widget,ArgList arglist,Cardinal argcount)2667 XmDropSiteRegister(Widget widget,
2668 		   ArgList arglist,
2669 		   Cardinal argcount)
2670 {
2671     Widget disp = XmGetXmDisplay(XtDisplay(widget));
2672 
2673     DEBUGOUT(_LtDebug(__FILE__, widget,
2674 		      "%s:XmDropSiteRegister(%d) - %i args\n",
2675 		      __FILE__, __LINE__,
2676 		      argcount));
2677     DEBUGOUT(_LtDebugPrintArgList(__FILE__, widget, arglist, argcount, False));
2678     DEBUGOUT(_LtDebug("DRAGSINK", widget,
2679 		      "%s:XmDropSiteRegister(%d) - %i args\n",
2680 		      __FILE__, __LINE__,
2681 		      argcount));
2682     DEBUGOUT(_LtDebugPrintArgList("DRAGSINK", widget, arglist, argcount, False));
2683 
2684     DSMCreateInfo(_XmGetDropSiteManagerObject((XmDisplay)disp),
2685 		  widget, arglist, argcount);
2686 }
2687 
2688 
2689 extern void
XmDropSiteRetrieve(Widget widget,ArgList arglist,Cardinal argcount)2690 XmDropSiteRetrieve(Widget widget,
2691 		   ArgList arglist,
2692 		   Cardinal argcount)
2693 {
2694     Widget disp = XmGetXmDisplay(XtDisplay(widget));
2695 
2696     DEBUGOUT(_LtDebug(__FILE__, widget, "XmDropSiteRetrieve()\n"));
2697 
2698     DSMRetrieveInfo(_XmGetDropSiteManagerObject((XmDisplay)disp),
2699 		    widget, arglist, argcount);
2700 }
2701 
2702 
2703 extern void
XmDropSiteStartUpdate(Widget widget)2704 XmDropSiteStartUpdate(Widget widget)
2705 {
2706     Widget disp = XmGetXmDisplay(XtDisplay(widget));
2707 
2708     DEBUGOUT(_LtDebug(__FILE__, widget, "XmDropSiteStartUpdate()\n"));
2709 
2710     DSMStartUpdate(_XmGetDropSiteManagerObject((XmDisplay)disp), widget);
2711 }
2712 
2713 
2714 extern void
XmDropSiteUnregister(Widget widget)2715 XmDropSiteUnregister(Widget widget)
2716 {
2717     Widget disp = XmGetXmDisplay(XtDisplay(widget));
2718 
2719     DEBUGOUT(_LtDebug(__FILE__, widget, "XmDropSiteUnregister()\n"));
2720 
2721     DSMDestroyInfo(_XmGetDropSiteManagerObject((XmDisplay)disp), widget);
2722 }
2723 
2724 
2725 extern void
XmDropSiteUpdate(Widget widget,ArgList arglist,Cardinal argcount)2726 XmDropSiteUpdate(Widget widget,
2727 		 ArgList arglist,
2728 		 Cardinal argcount)
2729 {
2730     Widget disp = XmGetXmDisplay(XtDisplay(widget));
2731 
2732     DEBUGOUT(_LtDebug(__FILE__, widget, "XmDropSiteUpdate()\n"));
2733 
2734     DSMUpdateInfo(_XmGetDropSiteManagerObject((XmDisplay)disp),
2735 		  widget, arglist, argcount);
2736 }
2737 
2738 /* amai: this call is not within the 2.1 docs for OM ... */
2739 extern XmDropSiteVisuals
XmDropSiteGetActiveVisuals(Widget widget)2740 XmDropSiteGetActiveVisuals(Widget widget)
2741 {
2742     /* FIX ME */
2743 
2744     DEBUGOUT(_LtDebug(__FILE__, widget, "XmDropSiteGetActiveVisuals()\n"));
2745 
2746     return NULL;
2747 }
2748 
2749 
2750 #if XmVERSION >= 2
2751 extern Boolean
XmDropSiteRegistered(Widget w)2752 XmDropSiteRegistered(Widget w)
2753 {
2754 	/* FIX ME */
2755 
2756 	DEBUGOUT(_LtDebug(__FILE__, w, "XmDropSiteRegistered()\n"));
2757 	return False;
2758 }
2759 #endif /* #if XmVERSION >= 2 */
2760