1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$TOG: DropSMgr.c /main/21 1999/08/11 14:44:57 vipin $"
26 #endif
27 #endif
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 
34 /*****************************************************************************
35  * THE DROPSITE DATABASE
36  *
37  * Drag and Drop maintains a two way mapping between information records
38  * and the dropsites widgets they represent.  There are two kinds of records
39  * kept in the database.
40  *
41  * The first kind of records are associated with a real dropsite.  These
42  * contain the information the user passes in via XmDropSiteRegister and
43  * modifies via XmDropSiteUpdate.
44  *
45  * The second kind are clipping records which represent widgets which
46  * in some way obscure one or more dropsites.  These are created and destroyed
47  * by Drag and Drop as dynamic things (like a ScrolledWindow scrolling)
48  * occur.
49  *
50  * When a new record is created,  it is associated via a hashtable kept
51  * in dsm -> dstable to the widget it represents.  This mapping is maintained
52  * by the RegisterInfo and UnregisterInfo functions.  Additionally,  the
53  * records themselves are kept internally in a compacted form.  This
54  * translation occurs in CopyVariantIntoFull and CopyFullIntoVariant.
55  *
56  * While confusing,  the compression saves significant room.  The fields
57  * are accessed by macros (defined in DropSMgrI.h) to avoid the problems
58  * of constantly compressing and decompressing the records.
59  *
60  * WHEN A CHANGE OCCURS
61  *
62  * When a new DS is added, one is removed,  or a geometry change occurs,
63  * the database must be brought up to sync with the real widgets.
64  * This is done in a number of stages.
65  *
66  * RemoveAllClippers(dsm, root) - This removes all the clippers created
67  * in the database hierarchy.  The dropsites become a flat list held in
68  * the child list of the topmost node.
69  *
70  * SyncDropSiteGeometry(dsm, root) - Now we go down the flat list and
71  * see what updates are needed to the internal geometry information.  This
72  * is really needed for PREREGISTER,  as we'll finalize the update by
73  * refreshing the information kept on the window properties.
74  *
75  * DetectAndInsertAllClippers(dsm, root) - We now rebuild the clipper
76  * hierarchy.
77  *****************************************************************************/
78 
79 #include <Xm/GadgetP.h>
80 #include <Xm/PrimitiveP.h>
81 #include <Xm/ManagerP.h>
82 #include <Xm/DragC.h>
83 #include <Xm/DropTrans.h>
84 #include <Xm/XmosP.h>		/* for bzero */
85 #include "XmI.h"
86 #include "DisplayI.h"
87 #include "DragBSI.h"
88 #include "DragCI.h"
89 #include "DragICCI.h"
90 #include "DragUnderI.h"
91 #include "DropSMgrI.h"
92 #include "HashI.h"
93 #include "MessagesI.h"
94 #include "PixConvI.h"
95 #include "RegionI.h"
96 #include "TraversalI.h"		/* for _XmIntersectionOf() */
97 
98 #define FIX_1212
99 
100 #define MESSAGE1 _XmMMsgDropSMgr_0001
101 #define MESSAGE2 _XmMMsgDropSMgr_0002
102 #define MESSAGE3 _XmMMsgDropSMgr_0003
103 #define MESSAGE4 _XmMMsgDropSMgr_0004
104 #define MESSAGE5 _XmMMsgDropSMgr_0005
105 #define MESSAGE6 _XmMMsgDropSMgr_0006
106 #define MESSAGE7 _XmMMsgDropSMgr_0007
107 #define MESSAGE8 _XmMMsgDropSMgr_0008
108 #define MESSAGE9 _XmMMsgDropSMgr_0009
109 #define MESSAGE10 _XmMMsgDropSMgr_0010
110 
111 /* #define DEBUG */
112 #ifdef DEBUG
113 #define DPRINT(x) printf x
114 void _XmPrintDSTree(XmDropSiteManagerObject dsm, XmDSInfo root);
115 #else
116 #define DPRINT(x)
117 #endif
118 
119 /********    Static Function Declarations    ********/
120 
121 static void ClassInit( void ) ;
122 static void ClassPartInit(
123                         WidgetClass wc) ;
124 static void DropSiteManagerInitialize(
125                         Widget rw,
126                         Widget nw,
127                         ArgList args,
128                         Cardinal *num_args) ;
129 static void Destroy(
130                         Widget w) ;
131 static Boolean SetValues(
132                         Widget cw,
133                         Widget rw,
134                         Widget nw,
135                         ArgList args,
136                         Cardinal *num_args) ;
137 static void CreateTable(
138                         XmDropSiteManagerObject dsm) ;
139 static void DestroyTable(
140                         XmDropSiteManagerObject dsm) ;
141 static void RegisterInfo(
142                         register XmDropSiteManagerObject dsm,
143                         register Widget widget,
144                         register XtPointer info) ;
145 static void UnregisterInfo(
146                         register XmDropSiteManagerObject dsm,
147                         register XtPointer info) ;
148 static XtPointer WidgetToInfo(
149                         register XmDropSiteManagerObject dsm,
150                         register Widget widget) ;
151 static Boolean Coincident(
152                         XmDropSiteManagerObject dsm,
153                         Widget w,
154                         XmDSClipRect *r) ;
155 static Boolean IsDescendent(
156                         Widget parentW,
157                         Widget childW) ;
158 static void DetectAncestorClippers(
159                         XmDropSiteManagerObject dsm,
160                         Widget w,
161                         XmDSClipRect *r,
162                         XmDSInfo info) ;
163 static void DetectImpliedClipper(
164                         XmDropSiteManagerObject dsm,
165                         XmDSInfo info) ;
166 static void DetectAllClippers(
167                         XmDropSiteManagerObject dsm,
168                         XmDSInfo parentInfo) ;
169 static Boolean InsertClipper(
170                         XmDropSiteManagerObject dsm,
171                         XmDSInfo parentInfo,
172                         XmDSInfo clipper) ;
173 static void DetectAndInsertAllClippers(
174                         XmDropSiteManagerObject dsm,
175                         XmDSInfo root) ;
176 static void RemoveClipper(
177                         XmDropSiteManagerObject dsm,
178                         XmDSInfo clipper) ;
179 static void RemoveAllClippers(
180                         XmDropSiteManagerObject dsm,
181                         XmDSInfo parentInfo) ;
182 static void DestroyDSInfo(
183                         XmDSInfo info,
184 #if NeedWidePrototypes
185                         int substructures) ;
186 #else
187                         Boolean substructures) ;
188 #endif /* NeedWidePrototypes */
189 static XmDSInfo CreateShellDSInfo(
190                         XmDropSiteManagerObject dsm,
191                         Widget widget) ;
192 static XmDSInfo CreateClipperDSInfo(
193                         XmDropSiteManagerObject dsm,
194                         Widget clipW) ;
195 static void InsertInfo(
196                         XmDropSiteManagerObject dsm,
197                         XtPointer info,
198                         XtPointer call_data) ;
199 static void RemoveInfo(
200                         XmDropSiteManagerObject dsm,
201                         XtPointer info) ;
202 static Boolean IntersectWithWidgetAncestors(
203                         Widget w,
204                         XmRegion r) ;
205 static Boolean IntersectWithDSInfoAncestors(
206                         XmDSInfo parent,
207                         XmRegion r) ;
208 static Boolean CalculateAncestorClip(
209                         XmDropSiteManagerObject dsm,
210                         XmDSInfo info,
211                         XmRegion r) ;
212 static Boolean PointInDS(
213                         XmDropSiteManagerObject dsm,
214                         XmDSInfo info,
215 #if NeedWidePrototypes
216                         int x,
217                         int y) ;
218 #else
219                         Position x,
220                         Position y) ;
221 #endif /* NeedWidePrototypes */
222 static XmDSInfo PointToDSInfo(
223                         XmDropSiteManagerObject dsm,
224                         XmDSInfo info,
225 #if NeedWidePrototypes
226                         int x,
227                         int y) ;
228 #else
229                         Position x,
230                         Position y) ;
231 #endif /* NeedWidePrototypes */
232 static void DoAnimation(
233                         XmDropSiteManagerObject dsm,
234                         XmDragMotionClientData motionData,
235                         XtPointer callback) ;
236 static void ProxyDragProc(
237                         XmDropSiteManagerObject dsm,
238                         XtPointer client_data,
239                         XmDragProcCallbackStruct *callback) ;
240 static void HandleEnter(
241                         XmDropSiteManagerObject dsm,
242                         XmDragMotionClientData motionData,
243                         XmDragMotionCallbackStruct *callback,
244                         XmDSInfo info,
245 #if NeedWidePrototypes
246                         unsigned int style) ;
247 #else
248                         unsigned char style) ;
249 #endif /* NeedWidePrototypes */
250 static void HandleMotion(
251                         XmDropSiteManagerObject dsm,
252                         XmDragMotionClientData motionData,
253                         XmDragMotionCallbackStruct *callback,
254                         XmDSInfo info,
255 #if NeedWidePrototypes
256                         unsigned int style) ;
257 #else
258                         unsigned char style) ;
259 #endif /* NeedWidePrototypes */
260 static void HandleLeave(
261                         XmDropSiteManagerObject dsm,
262                         XmDragMotionClientData motionData,
263                         XmDragMotionCallbackStruct *callback,
264                         XmDSInfo info,
265 #if NeedWidePrototypes
266                         unsigned int style,
267                         int enterPending) ;
268 #else
269                         unsigned char style,
270                         Boolean enterPending) ;
271 #endif /* NeedWidePrototypes */
272 static void ProcessMotion(
273                         XmDropSiteManagerObject dsm,
274                         XtPointer clientData,
275                         XtPointer calldata) ;
276 static void ProcessDrop(
277                         XmDropSiteManagerObject dsm,
278                         XtPointer clientData,
279                         XtPointer cb) ;
280 static void ChangeOperation(
281                         XmDropSiteManagerObject dsm,
282                         XtPointer clientData,
283                         XtPointer calldata) ;
284 static void PutDSToStream(
285                         XmDropSiteManagerObject dsm,
286                         XmDSInfo dsInfo,
287 #if NeedWidePrototypes
288                         int last,
289 #else
290                         Boolean last,
291 #endif /* NeedWidePrototypes */
292                         XtPointer dataPtr) ;
293 static void GetDSFromDSM(
294                         XmDropSiteManagerObject dsm,
295                         XmDSInfo parentInfo,
296 #if NeedWidePrototypes
297                         int last,
298 #else
299                         Boolean last,
300 #endif /* NeedWidePrototypes */
301                         XtPointer dataPtr) ;
302 static int GetTreeFromDSM(
303                         XmDropSiteManagerObject dsm,
304                         Widget shell,
305                         XtPointer dataPtr) ;
306 static XmDSInfo GetDSFromStream(
307                         XmDropSiteManagerObject dsm,
308                         XtPointer dataPtr,
309                         Boolean *close,
310                         unsigned char *type) ;
311 static void GetNextDS(
312                         XmDropSiteManagerObject dsm,
313                         XmDSInfo parentInfo,
314                         XtPointer dataPtr) ;
315 static XmDSInfo ReadTree(
316                         XmDropSiteManagerObject dsm,
317                         XtPointer dataPtr) ;
318 static void FreeDSTree(
319                         XmDSInfo tree) ;
320 static void ChangeRoot(
321                         XmDropSiteManagerObject dsm,
322                         XtPointer clientData,
323                         XtPointer callData) ;
324 static int CountDropSites(
325                         XmDSInfo info) ;
326 static void CreateInfo(
327                         XmDropSiteManagerObject dsm,
328                         Widget widget,
329                         ArgList args,
330                         Cardinal argCount) ;
331 static void CopyVariantIntoFull(
332                         XmDropSiteManagerObject dsm,
333                         XmDSInfo variant,
334                         XmDSFullInfo full_info) ;
335 static void RetrieveInfo(
336                         XmDropSiteManagerObject dsm,
337                         Widget widget,
338                         ArgList args,
339                         Cardinal argCount) ;
340 static void CopyFullIntoVariant(
341                         XmDSFullInfo full_info,
342                         XmDSInfo variant) ;
343 static void UpdateInfo(
344                         XmDropSiteManagerObject dsm,
345                         Widget widget,
346                         ArgList args,
347                         Cardinal argCount) ;
348 static void StartUpdate(
349                         XmDropSiteManagerObject dsm,
350                         Widget refWidget) ;
351 static void EndUpdate(
352                         XmDropSiteManagerObject dsm,
353                         Widget refWidget) ;
354 static void DestroyInfo(
355                         XmDropSiteManagerObject dsm,
356                         Widget widget) ;
357 static void SyncDropSiteGeometry(
358                         XmDropSiteManagerObject dsm,
359                         XmDSInfo info) ;
360 static void SyncTree(
361                         XmDropSiteManagerObject dsm,
362                         Widget shell) ;
363 static void Update(
364                         XmDropSiteManagerObject dsm,
365                         XtPointer clientData,
366                         XtPointer callData) ;
367 static Boolean HasDropSiteDescendant(
368                         XmDropSiteManagerObject dsm,
369                         Widget widget) ;
370 static void DestroyCallback(
371                         Widget widget,
372                         XtPointer client_data,
373                         XtPointer call_data) ;
374 
375 /********    End Static Function Declarations    ********/
376 
377 static XtResource resources[] = {
378 { XmNnotifyProc, XmCNotifyProc, XmRCallbackProc,
379   sizeof(XtCallbackProc),
380   XtOffsetOf( struct _XmDropSiteManagerRec, dropManager.notifyProc),
381   XmRImmediate, NULL },
382 { XmNtreeUpdateProc, XmCTreeUpdateProc, XmRCallbackProc,
383   sizeof(XtCallbackProc),
384   XtOffsetOf( struct _XmDropSiteManagerRec, dropManager.treeUpdateProc),
385   XmRImmediate, NULL },
386 { XmNclientData, XmCClientData, XmRPointer,
387   sizeof(XtPointer),
388   XtOffsetOf( struct _XmDropSiteManagerRec, dropManager.client_data),
389   XmRImmediate, NULL },
390 };
391 
392 /*  class record definition  */
393 
394 externaldef(xmdropsitemanagerclassrec)
395     XmDropSiteManagerClassRec xmDropSiteManagerClassRec =
396 {
397 	{
398 		(WidgetClass) &objectClassRec,    /* superclass	         */
399 		"XmDropSiteManager",              /* class_name	         */
400 		sizeof(XmDropSiteManagerRec),     /* widget_size	         */
401 		ClassInit, 			  /* class_initialize      */
402 		ClassPartInit,                    /* class part initialize */
403 		False,                            /* class_inited          */
404 		DropSiteManagerInitialize,        /* initialize	         */
405 		NULL,                             /* initialize_hook       */
406 		NULL,                             /* obj1                  */
407 		NULL,							  /* obj2                  */
408 		0,								  /* obj3	                 */
409 		resources,                        /* resources	         */
410 		XtNumber(resources),              /* num_resources         */
411 		NULLQUARK,                        /* xrm_class	         */
412 		True,                             /* obj4                  */
413 		XtExposeCompressSeries,           /* obj5                  */
414 		True,                             /* obj6                  */
415 		False,                            /* obj7                  */
416 		Destroy,                          /* destroy               */
417 		NULL,                             /* obj8                  */
418 		NULL,				              /* obj9                  */
419 		SetValues,                        /* set_values	         */
420 		NULL,                             /* set_values_hook       */
421 		NULL,                             /* obj10                 */
422 		NULL,                             /* get_values_hook       */
423 		NULL,                             /* obj11    	         */
424 		XtVersion,                        /* version               */
425 		NULL,                             /* callback private      */
426 		NULL,                             /* obj12                 */
427 		NULL,                             /* obj13                 */
428 		NULL,				              /* obj14                 */
429 		NULL,                             /* extension             */
430 	},
431 	{
432 		CreateInfo,          /* createInfo           */
433 		DestroyInfo,         /* destroyInfo          */
434 		StartUpdate,         /* startUpdate          */
435 		RetrieveInfo,        /* retrieveInfo         */
436 		UpdateInfo,          /* updateInfo           */
437 		EndUpdate,           /* endUpdate            */
438 
439 		Update,              /* updateDSM            */
440 
441 		ProcessMotion,       /* processMotion        */
442 		ProcessDrop,         /* processDrop          */
443 		ChangeOperation,     /* operationChanged     */
444 		ChangeRoot,          /* changeDSRoot         */
445 
446 		InsertInfo,          /* insertInfo           */
447 		RemoveInfo,          /* removeInfo           */
448 
449 		SyncTree,            /* syncTree             */
450 		GetTreeFromDSM,      /* getTreeFromDSM       */
451 
452 		CreateTable,         /* createTable          */
453 		DestroyTable,        /* destroyTable         */
454 		RegisterInfo,        /* registerInfo         */
455 		WidgetToInfo,        /* widgetToInfo         */
456 		UnregisterInfo,      /* unregisterInfo       */
457 
458 		NULL,                /* extension            */
459 	},
460 };
461 
462 externaldef(xmdropsitemanagerobjectclass) WidgetClass
463 	xmDropSiteManagerObjectClass = (WidgetClass)
464 		&xmDropSiteManagerClassRec;
465 
466 static void
ClassInit(void)467 ClassInit( void )
468 {
469     _XmRegisterPixmapConverters();
470 }
471 
472 /*ARGSUSED*/
473 static void
ClassPartInit(WidgetClass wc)474 ClassPartInit(
475 		WidgetClass wc )
476 {
477 	/*EMPTY*/
478 }
479 
480 
481 /*ARGSUSED*/
482 static void
DropSiteManagerInitialize(Widget rw,Widget nw,ArgList args,Cardinal * num_args)483 DropSiteManagerInitialize(
484 		Widget rw,
485 		Widget nw,
486 		ArgList args,
487 		Cardinal *num_args )
488 {
489 	XmDropSiteManagerObject 	dsm = (XmDropSiteManagerObject)nw;
490 	XmDSFullInfoRec info_rec;
491 	XmDSFullInfo info = &(info_rec);
492 
493 	dsm->dropManager.dragUnderData = NULL;
494 	dsm->dropManager.curInfo = NULL;
495 	dsm->dropManager.curTime = 0;
496 	dsm->dropManager.oldX = dsm->dropManager.curX = 0;
497 	dsm->dropManager.oldY = dsm->dropManager.curY = 0;
498 	dsm->dropManager.curDropSiteStatus = XmINVALID_DROP_SITE;
499 	dsm->dropManager.curDragContext = NULL;
500 	dsm->dropManager.curAnimate = True;
501 	dsm->dropManager.curOperations = XmDROP_NOOP;
502 	dsm->dropManager.curOperation = XmDROP_NOOP;
503 	dsm->dropManager.curAncestorClipRegion = _XmRegionCreate();
504 	dsm->dropManager.newAncestorClipRegion = _XmRegionCreate();
505 	DSMCreateTable(dsm);
506 	dsm->dropManager.dsRoot = NULL;
507 	dsm->dropManager.rootX = dsm->dropManager.rootY = 0;
508 	dsm->dropManager.rootW = dsm->dropManager.rootH = ~0;
509 	dsm->dropManager.clipperList = NULL;
510 	dsm->dropManager.updateInfo = NULL;
511 	dsm->dropManager.updateTimeOutId = 0;
512 
513 	/* Patch around broken Xt interfaces */
514 	XtGetSubresources(nw, info, NULL, NULL, _XmDSResources,
515 		_XmNumDSResources, NULL, 0);
516 }
517 
518 static void
Destroy(Widget w)519 Destroy(
520 		Widget w )
521 {
522 	XmDropSiteManagerObject	dsm = (XmDropSiteManagerObject)w;
523 
524 	if (dsm->dropManager.updateTimeOutId)
525 	    XtRemoveTimeOut(dsm->dropManager.updateTimeOutId);
526 
527 	DSMDestroyTable(dsm);
528 	_XmRegionDestroy(dsm->dropManager.curAncestorClipRegion);
529 	_XmRegionDestroy(dsm->dropManager.newAncestorClipRegion);
530 }
531 
532 /*ARGSUSED*/
533 static Boolean
SetValues(Widget cw,Widget rw,Widget nw,ArgList args,Cardinal * num_args)534 SetValues(
535 		Widget cw,
536 		Widget rw,
537 		Widget nw,
538 		ArgList args,
539 		Cardinal *num_args )
540 {
541 	/*EMPTY*/
542 	return False;
543 }
544 
545 /* Function for Hash table */
546 static Boolean
CompareWidgets(XtPointer w1,XtPointer w2)547 CompareWidgets(XtPointer w1, XtPointer w2)
548 {
549   return(w1 == w2);
550 }
551 
552 static XmHashValue
HashWidget(XtPointer w1)553 HashWidget(XtPointer w1)
554 {
555   return((XmHashValue)(long)w1);
556 }
557 
558 static void
CreateTable(XmDropSiteManagerObject dsm)559 CreateTable(
560 		XmDropSiteManagerObject dsm )
561 {
562   XtPointer *tab = &(dsm->dropManager.dsTable);
563 
564   _XmProcessLock();
565   *tab = (XtPointer) _XmAllocHashTable(100, CompareWidgets, HashWidget);
566   _XmProcessUnlock();
567 }
568 
569 static void
DestroyTable(XmDropSiteManagerObject dsm)570 DestroyTable(
571         XmDropSiteManagerObject dsm )
572 {
573     XtPointer * tab = &(dsm->dropManager.dsTable);
574 
575     _XmProcessLock();
576     _XmFreeHashTable((XmHashTable) *tab);
577     _XmProcessUnlock();
578     *tab = NULL;
579 }
580 
581 #define DSTABLE(dsm) ((XmHashTable)(dsm->dropManager.dsTable))
582 
583 static void
RegisterInfo(register XmDropSiteManagerObject dsm,register Widget widget,register XtPointer info)584 RegisterInfo(
585         register XmDropSiteManagerObject dsm,
586         register Widget widget,
587         register XtPointer info )
588 {
589     register XmHashTable tab;
590 
591     if (GetDSRegistered(info)) return;
592 
593     DPRINT(("(RegI) Widget %p (%s) info %p (internal %d widget %p)\n",
594 	    widget, XtName(widget), info, GetDSInternal(info),
595 	    GetDSWidget(info)));
596 
597     tab = DSTABLE(dsm);
598 
599     _XmProcessLock();
600     /* Resize if the table has many more entries than slots */
601     if (_XmHashTableCount(tab) > (2 * _XmHashTableSize(tab)))
602       _XmResizeHashTable(tab, 2 * _XmHashTableSize(tab));
603 
604     _XmAddHashEntry(tab, widget, info);
605     _XmProcessUnlock();
606 
607     SetDSRegistered(info, True);
608 }
609 
610 static void
UnregisterInfo(register XmDropSiteManagerObject dsm,register XtPointer info)611 UnregisterInfo(
612         register XmDropSiteManagerObject dsm,
613         register XtPointer info )
614 {
615     XmHashTable tab;
616     XtPointer iterator;
617     Widget widget = GetDSWidget(info);
618     XtPointer data;
619 
620     if ((info == NULL) || !GetDSRegistered(info))
621       return;
622 
623     DPRINT(("(UnregI) Widget %p (%s) info %p (internal %d widget %p)\n",
624 	    widget, XtName(widget), info, GetDSInternal(info),
625 	    GetDSWidget(info)));
626 
627     tab = DSTABLE(dsm);
628 
629     iterator = NULL;
630 
631     _XmProcessLock();
632     while((data = _XmGetHashEntryIterate(tab, widget, &iterator)) != NULL)
633       {
634 	if (data == info) {
635 	  _XmRemoveHashIterator(tab, &iterator);
636 	  break;
637 	}
638       }
639       _XmProcessUnlock();
640 
641     SetDSRegistered(info, False);
642 }
643 
644 static XtPointer
WidgetToInfo(register XmDropSiteManagerObject dsm,register Widget widget)645 WidgetToInfo(
646         register XmDropSiteManagerObject dsm,
647         register Widget widget )
648 {
649   XmHashTable tab;
650   XmDSInfo info;
651 
652   tab = DSTABLE(dsm);
653 
654   info = (XmDSInfo) _XmGetHashEntry(tab, widget);
655 
656   return((XtPointer) info);
657 }
658 
659 static Boolean
Coincident(XmDropSiteManagerObject dsm,Widget w,XmDSClipRect * r)660 Coincident(
661         XmDropSiteManagerObject dsm,
662         Widget w,
663         XmDSClipRect *r )
664 {
665 	XRectangle wR;
666 	Boolean hit = False;
667 
668 	if (!XtIsShell(w))
669 	{
670 		/* r is shell relative, so wR needs to be translated */
671 		XtTranslateCoords(XtParent(w), XtX(w), XtY(w),
672 			&(wR.x), &(wR.y));
673 		wR.x -= dsm->dropManager.rootX;
674 		wR.y -= dsm->dropManager.rootY;
675 	}
676 	else
677 	{
678 		wR.x = wR.y = 0;
679 	}
680 
681 
682 	wR.width = XtWidth(w);
683 	wR.height = XtHeight(w);
684 
685 	if ( !(r->detected & XmDROP_SITE_LEFT_EDGE) && (r->x == wR.x))
686 	{
687 		r->detected |= XmDROP_SITE_LEFT_EDGE;
688 		hit = True;
689 	}
690 
691 	if ( !(r->detected & XmDROP_SITE_RIGHT_EDGE) &&
692 		((r->x + r->width) == (wR.x + wR.width)))
693 	{
694 		r->detected |= XmDROP_SITE_RIGHT_EDGE;
695 		hit = True;
696 	}
697 
698 	if ( !(r->detected & XmDROP_SITE_TOP_EDGE) && (r->y == wR.y))
699 	{
700 		r->detected |= XmDROP_SITE_TOP_EDGE;
701 		hit = True;
702 	}
703 
704 	if ( !(r->detected & XmDROP_SITE_BOTTOM_EDGE) &&
705 		((r->y + r->height) == (wR.y + wR.height)))
706 	{
707 		r->detected |= XmDROP_SITE_BOTTOM_EDGE;
708 		hit = True;
709 	}
710 
711 	return(hit);
712 }
713 
714 static Boolean
IsDescendent(Widget parentW,Widget childW)715 IsDescendent(
716         Widget parentW,
717         Widget childW )
718 {
719 	Widget tmp;
720 
721 	if ((parentW == NULL) || (childW == NULL))
722 		return(False);
723 
724 	tmp = XtParent(childW);
725 
726 	while (tmp != parentW)
727 	{
728 		if (XtIsShell(tmp))
729 			return(False);
730 
731 		tmp = XtParent(tmp);
732 	}
733 
734 	return(True);
735 }
736 
737 static void
DetectAncestorClippers(XmDropSiteManagerObject dsm,Widget w,XmDSClipRect * r,XmDSInfo info)738 DetectAncestorClippers(
739         XmDropSiteManagerObject dsm,
740         Widget w,
741         XmDSClipRect *r,
742         XmDSInfo info )
743 {
744 	/*
745 	 * We know that r represents the visible region of the dropSite
746 	 * as clipped by its ancestors in shell relative coordinates.  We
747 	 * now search for the most ancient ancestor who provides that clip.
748 	 * We do this by looking from the shell downward for the parent
749 	 * whose edge is coincident with a clipped edge.
750 	 *
751 	 * We can add as many as four clippers to the tree as a result
752 	 * of this routine.
753 	 */
754 
755 
756 	/*
757 	 * Hygiene.
758 	 */
759 	if (w == NULL)
760 		return;
761 
762 	if (!XtIsShell(w))
763 		DetectAncestorClippers(dsm, XtParent(w), r, info);
764 
765 	/*
766 	 * We never need to add the shell to the tree as a clipper.
767 	 * We call Coincident first so that any clipping provided by
768 	 * the shell is marked in the cliprect structure.
769 	 */
770 	if ((Coincident(dsm, w, r)) && (!XtIsShell(w)))
771 	{
772 		XmDSInfo clipper;
773 
774 		/* Have we already put this clipper in the tree? */
775 		if ((clipper = (XmDSInfo) DSMWidgetToInfo(dsm, w)) != NULL)
776 			return;
777 
778 		clipper = CreateClipperDSInfo(dsm, w);
779 		DSMRegisterInfo(dsm, w, (XtPointer) clipper);
780 		SetDSParent(clipper, dsm->dropManager.clipperList);
781 		dsm->dropManager.clipperList = (XtPointer) clipper;
782 	}
783 }
784 
785 static void
DetectImpliedClipper(XmDropSiteManagerObject dsm,XmDSInfo info)786 DetectImpliedClipper(
787         XmDropSiteManagerObject dsm,
788         XmDSInfo info )
789 {
790 	static XmRegion tmpRegion = NULL;
791 
792 	if (tmpRegion == NULL)
793 	{
794 		tmpRegion = _XmRegionCreate();
795 	}
796 
797 	if ((GetDSType(info) == XmDROP_SITE_SIMPLE) && GetDSHasRegion(info))
798 	{
799 		Widget w = GetDSWidget(info);
800 		XRectangle wr, tr, rr;
801 
802 		/*
803 		 * This step only has meaning if there is a separately
804 		 * specified region for this drop site (which can only be done
805 		 * for simple drop sites).
806 		 */
807 
808 		/* The region will be relative to the origin of the widget */
809 		wr.x = wr.y = 0;
810 		wr.width = XtWidth(w);
811 		wr.height = XtHeight(w);
812 
813 		_XmRegionGetExtents(GetDSRegion(info), &rr);
814 
815 		_XmIntersectionOf(&wr, &rr, &tr);
816 
817 		if ((rr.x != tr.x) ||
818 			(rr.y != tr.y) ||
819 			(rr.width != tr.width) ||
820 			(rr.height != tr.height))
821 		{
822 			XmDSInfo clipper;
823 			/*
824 			 * The implied clipper is magic.  It's in the tree but not
825 			 * of it.  (It refers to the same widget, but it's not
826 			 * registered.)
827 			 */
828 
829 			clipper = CreateClipperDSInfo(dsm, w);
830 			SetDSParent(clipper, dsm->dropManager.clipperList);
831 			dsm->dropManager.clipperList = (XtPointer) clipper;
832 		}
833 	}
834 }
835 
836 static void
DetectAllClippers(XmDropSiteManagerObject dsm,XmDSInfo parentInfo)837 DetectAllClippers(
838         XmDropSiteManagerObject dsm,
839         XmDSInfo parentInfo )
840 {
841 	XmDSInfo childInfo;
842 	XmDSClipRect extents, clippedExtents;
843 	int i;
844 	Widget w;
845 	static XmRegion tmpR = NULL;
846 
847 	if (GetDSLeaf(parentInfo))
848 		return;
849 
850 	_XmProcessLock();
851 	if (tmpR == NULL)
852 	{
853 		tmpR = _XmRegionCreate();
854 	}
855 	_XmProcessUnlock();
856 
857 	for (i = 0; i < (int)GetDSNumChildren(parentInfo); i++)
858 	{
859 		childInfo = (XmDSInfo) GetDSChild(parentInfo, i);
860 		/*
861 		 * Because we don't allow composite drop sites to have
862 		 * arbitrary regions, and Motif doesn't support shaped
863 		 * widgets, we do a simple rectangle clip detection.
864 		 *
865 		 * IntersectWithAncestors expects the region to be in
866 		 * widget relative coordinates, and returns in shell relative
867 		 * coordinates (the ultimate ancestor is the shell).
868 		 */
869 		_XmRegionGetExtents(GetDSRegion(childInfo),
870 			(XRectangle *)(&extents));
871 
872 		_XmProcessLock();
873 		_XmRegionUnion(GetDSRegion(childInfo), GetDSRegion(childInfo),
874 			tmpR);
875 
876 		w = GetDSWidget(childInfo);
877 
878 		IntersectWithWidgetAncestors(w, tmpR);
879 
880 		_XmRegionGetExtents(tmpR, (XRectangle *)(&clippedExtents));
881 		_XmProcessUnlock();
882 
883 		/* tmpR is now in shell relative position */
884 
885 		clippedExtents.detected = 0;
886 
887 		if ((clippedExtents.width < extents.width) ||
888 			(clippedExtents.height < extents.height))
889 		{
890 			/*
891 			 * We've been clipped.  Find out who did it and add
892 			 * them to the tree.
893 			 */
894 			DetectAncestorClippers(dsm,
895 				XtParent(GetDSWidget(childInfo)),
896 				&clippedExtents, childInfo);
897 		}
898 
899 		/*
900 		 * We now have inserted clippers for any ancestors which may
901 		 * have clipped the widget.  Now we need to check for the
902 		 * case that the widget itself clips the region.
903 		 */
904 		DetectImpliedClipper(dsm, childInfo);
905 
906 		/* Re-Curse */
907 		DetectAllClippers(dsm, childInfo);
908 	}
909 }
910 
911 static Boolean
InsertClipper(XmDropSiteManagerObject dsm,XmDSInfo parentInfo,XmDSInfo clipper)912 InsertClipper(
913         XmDropSiteManagerObject dsm,
914         XmDSInfo parentInfo,
915 		XmDSInfo clipper )
916 {
917 	int i;
918 	XmDSInfo childInfo;
919 
920 	/*
921 	 * Do a tail-end recursion which will insert the clipper into
922 	 * the info tree as a child of its closest ancestor in the tree.
923 	 */
924 
925 	if (GetDSLeaf(parentInfo))
926 		return(False);
927 
928 	for (i=0; i < (int)GetDSNumChildren(parentInfo); i++)
929 	{
930 		childInfo = (XmDSInfo) GetDSChild(parentInfo, i);
931 		if (InsertClipper(dsm, childInfo, clipper))
932 			return(True);
933 	}
934 
935 	if (IsDescendent(GetDSWidget(parentInfo), GetDSWidget(clipper)))
936 	{
937 		i = 0;
938 		while (i < (int)GetDSNumChildren(parentInfo))
939 		{
940 			childInfo = (XmDSInfo) GetDSChild(parentInfo, i);
941 			if (IsDescendent(GetDSWidget(clipper),
942 				GetDSWidget(childInfo)))
943 			{
944 				RemoveDSChild(parentInfo, childInfo);
945 				AddDSChild(clipper, childInfo,
946 					GetDSNumChildren(clipper));
947 			}
948 			else
949 				/*
950 				 * Because RemoveDSChild monkeys with the num children,
951 				 * we only increment i if we haven't called
952 				 * RemoveDSChild.
953 				 */
954 				i++;
955 		}
956 
957 		AddDSChild(parentInfo, clipper, GetDSNumChildren(parentInfo));
958 
959 		/* We have inserted the clipper into the tree */
960 		return(True);
961 	}
962 	else
963 		return(False);
964 }
965 
966 static void
DetectAndInsertAllClippers(XmDropSiteManagerObject dsm,XmDSInfo root)967 DetectAndInsertAllClippers(
968         XmDropSiteManagerObject dsm,
969         XmDSInfo root )
970 {
971 	XmDSInfo clipper;
972 
973 	if ((!GetDSShell(root)) || (GetDSRemote(root)))
974 		return;
975 
976 	DetectAllClippers(dsm, root);
977 
978 	while ((clipper = (XmDSInfo) dsm->dropManager.clipperList) != NULL)
979 	{
980 		dsm->dropManager.clipperList = GetDSParent(clipper);
981 		(void) InsertClipper(dsm, root, clipper);
982 	}
983 }
984 
985 static void
RemoveClipper(XmDropSiteManagerObject dsm,XmDSInfo clipper)986 RemoveClipper(
987         XmDropSiteManagerObject dsm,
988         XmDSInfo clipper )
989 {
990   XmDSInfo parentInfo = (XmDSInfo) GetDSParent(clipper);
991   int i;
992 
993   /* Remove the clipper from its parent */
994   RemoveDSChild(parentInfo, clipper);
995 
996   /*
997    * Pull all of the children up into the parent's child
998    * list between the clipper and the clipper's sibling.
999    */
1000   for (i = 0; i < (int)GetDSNumChildren(clipper); i++) {
1001     XmDSInfo childInfo = (XmDSInfo) GetDSChild(clipper, i);
1002     AddDSChild(parentInfo, childInfo, GetDSNumChildren(parentInfo));
1003   }
1004 
1005   /*
1006    * Destroy the clipper
1007    */
1008   DSMUnregisterInfo(dsm, clipper);
1009   DestroyDSInfo(clipper, True);
1010 }
1011 
1012 static void
RemoveAllClippers(XmDropSiteManagerObject dsm,XmDSInfo parentInfo)1013 RemoveAllClippers(
1014         XmDropSiteManagerObject dsm,
1015         XmDSInfo parentInfo )
1016 {
1017   XmDSInfo child;
1018   int i;
1019 
1020   if (!GetDSLeaf(parentInfo))
1021     {
1022       i = 0;
1023       while(i < (int)GetDSNumChildren(parentInfo)) {
1024 	child = (XmDSInfo) GetDSChild(parentInfo, i);
1025 	RemoveAllClippers(dsm, child);
1026 	if (GetDSInternal(child))
1027 	  RemoveClipper(dsm, child);
1028 	/* Only increment i if the current child wasn't
1029 	   removed.  Otherwise we'll skip items in the list
1030 	   unintentionally */
1031 	if (child == (XmDSInfo) GetDSChild(parentInfo, i)) i++;
1032       }
1033     }
1034 }
1035 
1036 static void
DestroyDSInfo(XmDSInfo info,int substructures)1037 DestroyDSInfo(
1038         XmDSInfo info,
1039 #if NeedWidePrototypes
1040                         int substructures )
1041 #else
1042                         Boolean substructures )
1043 #endif /* NeedWidePrototypes */
1044 {
1045 	DestroyDS(info, substructures);
1046 }
1047 
1048 static XmDSInfo
CreateShellDSInfo(XmDropSiteManagerObject dsm,Widget widget)1049 CreateShellDSInfo(
1050         XmDropSiteManagerObject dsm,
1051         Widget widget )
1052 {
1053 	XmDSInfo		info;
1054 	XmRegion region = _XmRegionCreate();
1055 	XRectangle rect;
1056 
1057 	info = (XmDSInfo) XtCalloc(1, sizeof(XmDSLocalNoneNodeRec));
1058 
1059 	SetDSLeaf(info, True);
1060 	SetDSShell(info, True);
1061 	SetDSAnimationStyle(info, XmDRAG_UNDER_NONE);
1062 	SetDSType(info, XmDROP_SITE_COMPOSITE);
1063 	SetDSInternal(info, True);
1064 	SetDSActivity(info, XmDROP_SITE_INACTIVE);
1065 	SetDSWidget(info, widget);
1066 
1067 	rect.x = rect.y = 0;
1068 	rect.width = XtWidth(widget);
1069 	rect.height = XtHeight(widget);
1070 	_XmRegionUnionRectWithRegion(&rect, region, region);
1071 	SetDSRegion(info, region);
1072 
1073 	XtAddCallback(widget, XmNdestroyCallback,
1074 		DestroyCallback, dsm);
1075 
1076 	return(info);
1077 }
1078 
1079 /*ARGSUSED*/
1080 static XmDSInfo
CreateClipperDSInfo(XmDropSiteManagerObject dsm,Widget clipW)1081 CreateClipperDSInfo(
1082         XmDropSiteManagerObject dsm,
1083         Widget clipW )
1084 {
1085 	XmDSInfo info = NULL;
1086 	XmRegion region = _XmRegionCreate();
1087 	XRectangle rect;
1088 
1089 	info = (XmDSInfo) XtCalloc(1, sizeof(XmDSLocalNoneNodeRec));
1090 
1091 	SetDSLeaf(info, True);
1092 	SetDSInternal(info, True);
1093 	SetDSType(info, XmDROP_SITE_COMPOSITE);
1094 	SetDSAnimationStyle(info, XmDRAG_UNDER_NONE);
1095 	SetDSWidget(info, clipW);
1096 	SetDSActivity(info, XmDROP_SITE_ACTIVE);
1097 
1098 	rect.x = rect.y = 0;
1099 	rect.width = XtWidth(clipW);
1100 	rect.height = XtHeight(clipW);
1101 	_XmRegionUnionRectWithRegion(&rect, region, region);
1102 	SetDSRegion(info, region);
1103 
1104 	/*
1105 	 * Don't need a destroy callback.  When this widget is destroyed
1106 	 * the drop site children will be destroyed and as a side-effect
1107 	 * of the last drop site being destroyed, the clipper will be
1108 	 * destroyed.
1109 	 */
1110 
1111 	return(info);
1112 }
1113 
1114 
1115 /*ARGSUSED*/
1116 static void
InsertInfo(XmDropSiteManagerObject dsm,XtPointer info,XtPointer call_data)1117 InsertInfo(
1118         XmDropSiteManagerObject dsm,
1119         XtPointer info,
1120         XtPointer call_data )
1121 {
1122 	XmDSInfo	childInfo = (XmDSInfo) info;
1123 	XmDSInfo	parentInfo = NULL;
1124 	Widget		parent = XtParent(GetDSWidget(childInfo));
1125 
1126 	while (!(parentInfo = (XmDSInfo) DSMWidgetToInfo(dsm, parent)) &&
1127 		!XtIsShell(parent))
1128 	{
1129 		parent = XtParent(parent);
1130 	}
1131 
1132 	if (parentInfo == NULL)
1133 	{
1134 		/*
1135 		 * We've traversed clear back to the shell and not found a
1136 		 * parent for this info.  Therefore this must be the first drop
1137 		 * site to be registered under this shell, and we must create a
1138 		 * parent place holder at for shell
1139 		 */
1140 		parentInfo = CreateShellDSInfo(dsm, parent);
1141 		DSMRegisterInfo(dsm, parent, (XtPointer) parentInfo);
1142 		AddDSChild(parentInfo, childInfo, GetDSNumChildren(parentInfo));
1143 		if ((dsm->dropManager.treeUpdateProc) &&
1144 			(!XtIsRealized(parent) ||
1145 				(_XmGetDragProtocolStyle(parent) == XmDRAG_DYNAMIC)))
1146 		{
1147 			/*
1148 			 * If this is a preregister client and the shell isn't
1149 			 * realized yet, we need to register this shell with the
1150 			 * DragDisplay so the DragDisplay can register a realize
1151 			 * callback on this shell.
1152 			 *
1153 			 * OR
1154 			 *
1155 			 * If this is a dynamic client, we need to notify the Drag-
1156 			 * Display exactly once so that event handlers and such
1157 			 * can be installed on this client.
1158 			 */
1159 
1160 			XmDropSiteTreeAddCallbackStruct	outCB;
1161 
1162 			outCB.reason = XmCR_DROP_SITE_TREE_ADD;
1163 			outCB.event = NULL;
1164 			outCB.rootShell = parent;
1165 			outCB.numDropSites = 0; /* Unused */
1166 			outCB.numArgsPerDSHint = 0;
1167 
1168 			(dsm->dropManager.treeUpdateProc)
1169 			  ((Widget) dsm, NULL, (XtPointer) &outCB);
1170 		}
1171 	}
1172 	else if (GetDSType(parentInfo) == XmDROP_SITE_COMPOSITE)
1173 	{
1174 		AddDSChild(parentInfo, childInfo, GetDSNumChildren(parentInfo));
1175 	}
1176 	else
1177 	{
1178 		XmeWarning(GetDSWidget(childInfo), MESSAGE1);
1179 	}
1180 }
1181 
1182 static void
RemoveInfo(XmDropSiteManagerObject dsm,XtPointer info)1183 RemoveInfo(
1184         XmDropSiteManagerObject dsm,
1185         XtPointer info )
1186 {
1187 	Widget widget = GetDSWidget(info);
1188 	XmDSInfo parentInfo = (XmDSInfo) GetDSParent(info);
1189 
1190 	RemoveDSChild(parentInfo, (XmDSInfo) info);
1191 
1192 	DSMUnregisterInfo(dsm, info);
1193 
1194 	XtRemoveCallback(widget, XmNdestroyCallback, DestroyCallback, dsm);
1195 
1196 	if ((parentInfo != NULL) &&
1197 		(GetDSNumChildren(parentInfo) == 0) &&
1198 		(GetDSInternal(parentInfo)))
1199 	{
1200 		if (XtIsShell(GetDSWidget(parentInfo)))
1201 		{
1202 			/*
1203 			 * Need to notify the DragDisplay that this shell no
1204 			 * longer has any drop sites in it.
1205 			 */
1206 			if (dsm->dropManager.treeUpdateProc)
1207 			{
1208 				XmDropSiteTreeAddCallbackStruct	outCB;
1209 
1210 				outCB.reason = XmCR_DROP_SITE_TREE_REMOVE;
1211 				outCB.event = NULL;
1212 				outCB.rootShell = GetDSWidget(parentInfo);
1213 				(dsm->dropManager.treeUpdateProc)
1214 				  ((Widget)dsm, NULL, (XtPointer) &outCB);
1215 			}
1216 		}
1217 
1218 		DSMDestroyInfo(dsm, GetDSWidget(parentInfo));
1219 	}
1220 }
1221 
1222 
1223 static Boolean
IntersectWithWidgetAncestors(Widget w,XmRegion r)1224 IntersectWithWidgetAncestors(
1225         Widget w,
1226         XmRegion r )
1227 {
1228 	/*
1229 	 * r is the bounding box of the region.  It is in widget relative
1230 	 * coordinates.
1231 	 */
1232 	XRectangle parentR;
1233 	static XmRegion tmpR = NULL;
1234 	Dimension bw = XtBorderWidth(w);
1235 
1236 	if (XtIsShell(w))
1237 	{
1238 		return(True);
1239 	}
1240 
1241 	_XmProcessLock();
1242 	if (tmpR == NULL)
1243 	{
1244 		tmpR = _XmRegionCreate();
1245 	}
1246 	_XmProcessUnlock();
1247 
1248 	/* Translate the coordinates into parent relative coords */
1249 	_XmRegionOffset(r, (XtX(w) + bw), (XtY(w) + bw));
1250 
1251 	parentR.x = parentR.y = 0;
1252 	parentR.width = XtWidth(XtParent(w));
1253 	parentR.height = XtHeight(XtParent(w));
1254 
1255 	_XmProcessLock();
1256 	_XmRegionClear(tmpR);
1257 	_XmRegionUnionRectWithRegion(&parentR, tmpR, tmpR);
1258 
1259 	_XmRegionIntersect(tmpR, r, r);
1260 	_XmProcessUnlock();
1261 
1262 	if (!_XmRegionIsEmpty(r))
1263 		return(IntersectWithWidgetAncestors(XtParent(w), r));
1264 	else
1265 		return(False);
1266 }
1267 
1268 
1269 static Boolean
IntersectWithDSInfoAncestors(XmDSInfo parent,XmRegion r)1270 IntersectWithDSInfoAncestors(
1271         XmDSInfo parent,
1272         XmRegion r )
1273 {
1274 	static XmRegion testR = (XmRegion) NULL;
1275 	static XmRegion pR = (XmRegion) NULL;
1276 	Dimension bw;
1277 
1278 	_XmProcessLock();
1279 	if (testR == NULL)
1280 	{
1281 		testR = _XmRegionCreate();
1282 		pR = _XmRegionCreate();
1283 	}
1284 	_XmProcessUnlock();
1285 
1286 	/*
1287 	 * A simplifying assumption in this code is that the regions
1288 	 * are all relative to the shell widget.  We don't have to
1289 	 * do any fancy translations.
1290 	 *
1291 	 * All that we have to do is successively intersect the drop site
1292 	 * region with its ancestors until we reach the top of the drop
1293 	 * site tree.
1294 	 */
1295 
1296 	/*
1297 	 * If got to the top, then there is some part of the
1298 	 * region which is visible.
1299 	 */
1300 	if (parent == NULL)
1301 		return(True);
1302 
1303 	_XmProcessLock();
1304 	_XmRegionUnion(GetDSRegion(parent), GetDSRegion(parent), pR);
1305 	_XmProcessUnlock();
1306 
1307 	if ((bw = GetDSBorderWidth(parent)) != 0)
1308 	{
1309 		/*
1310 		 * Adjust for the border width ala X clipping
1311 		 * Recall that all Composite's drop rectangles represent the
1312 		 * refW's sensitive area (including border width), but clipping
1313 		 * should be done to the window not the border.  The clip
1314 		 * region is smaller than the sensitive region.
1315 		 */
1316 		_XmProcessLock();
1317 		_XmRegionShrink(pR, bw, bw);
1318 		_XmProcessUnlock();
1319 	}
1320 
1321 	_XmProcessLock();
1322 	_XmRegionIntersect(r, pR, r);
1323 	_XmProcessUnlock();
1324 
1325 	/* C will ensure that we only recurse if testR is non-empty */
1326 	return((!_XmRegionIsEmpty(r)) &&
1327 		(IntersectWithDSInfoAncestors(
1328 			(XmDSInfo) GetDSParent(parent), r)));
1329 }
1330 
1331 
1332 static Boolean
CalculateAncestorClip(XmDropSiteManagerObject dsm,XmDSInfo info,XmRegion r)1333 CalculateAncestorClip(
1334         XmDropSiteManagerObject dsm,
1335         XmDSInfo info,
1336         XmRegion r )
1337 {
1338 	/*
1339 	 * When this procedure finishes, r will contain the composite
1340 	 * clip region for all ancestors of info.  The clip region will
1341 	 * be in shell relative coordinates.
1342 	 */
1343 	_XmRegionClear(r);
1344 
1345     if (GetDSRemote(info))
1346 	{
1347 		XRectangle universe;
1348 
1349 		/* Set it to the "universe" -- which is shell relative */
1350 		universe.x = universe.y = 0;
1351 		universe.width = dsm->dropManager.rootW;
1352 		universe.height = dsm->dropManager.rootH;
1353 
1354 		_XmRegionUnionRectWithRegion(&universe, r, r);
1355 
1356 		/*
1357 		 * IntersectWithDSInfoAncestors will shoot the universe
1358 		 * through all of the DSInfo ancestors and return us what
1359 		 * is left in r.
1360 		 */
1361 		return(IntersectWithDSInfoAncestors(
1362 			(XmDSInfo) GetDSParent(info), r));
1363 	}
1364 	else
1365 	{
1366 		XRectangle parentR;
1367 		Widget parentW = XtParent(GetDSWidget(info));
1368 
1369 		if (parentW == NULL)
1370 			return(True);
1371 		else
1372 		{
1373 			parentR.x = parentR.y = -(XtBorderWidth(parentW));
1374 			parentR.width = XtWidth(parentW);
1375 			parentR.height = XtHeight(parentW);
1376 
1377 			_XmRegionUnionRectWithRegion(&parentR, r, r);
1378 
1379 			/*
1380 			 * IntersectWithWidgetAncestors will intersect the parent
1381 			 * of info with all successive parents and return us what
1382 			 * is left in r.
1383 			 */
1384 			return(IntersectWithWidgetAncestors(parentW, r));
1385 		}
1386 	}
1387 }
1388 
1389 
1390 static Boolean
PointInDS(XmDropSiteManagerObject dsm,XmDSInfo info,int x,int y)1391 PointInDS(
1392         XmDropSiteManagerObject dsm,
1393         XmDSInfo info,
1394 #if NeedWidePrototypes
1395         int x,
1396         int y )
1397 #else
1398         Position x,
1399         Position y )
1400 #endif /* NeedWidePrototypes */
1401 {
1402 	static XmRegion testR = (XmRegion) NULL;
1403 	static XmRegion tmpR = (XmRegion) NULL;
1404 	XmRegion *visR = &(dsm->dropManager.newAncestorClipRegion);
1405 	Widget w = GetDSWidget(info);
1406 
1407 	_XmProcessLock();
1408 	if (testR == NULL)
1409 	{
1410 		testR = _XmRegionCreate();
1411 		tmpR = _XmRegionCreate();
1412 	}
1413 	_XmProcessUnlock();
1414 
1415 	/*
1416 	 * CalculateAncestorClip will intersect the universe with all of
1417 	 * the ancestors.  If anything is left, it will return true the
1418 	 * intersection will be in tmpR.
1419 	 */
1420 
1421 	_XmProcessLock();
1422 	if (!CalculateAncestorClip(dsm, info, tmpR))
1423 	{
1424 		_XmProcessUnlock();
1425 		return(False);
1426 	}
1427 	_XmProcessUnlock();
1428 
1429 	if (GetDSRemote(info))
1430 	{
1431 		/*
1432 		 * We know that the region in the info struct is shell relative
1433 		 */
1434 		_XmProcessLock();
1435 		_XmRegionIntersect(tmpR, GetDSRegion(info), testR);
1436 		_XmProcessUnlock();
1437 	}
1438 	else
1439 	{
1440 		Position tmpX, tmpY;
1441 
1442 		_XmRegionUnion(GetDSRegion(info), GetDSRegion(info), testR);
1443 
1444 		/*
1445 		 * We know that the information is widget
1446 		 * relative so we will have to translate it.
1447 		 */
1448 
1449 		XtTranslateCoords(w, 0, 0, &tmpX, &tmpY);
1450 
1451 		_XmProcessLock();
1452 		_XmRegionOffset(testR, (tmpX - dsm->dropManager.rootX),
1453 			(tmpY - dsm->dropManager.rootY));
1454 		_XmRegionIntersect(tmpR, testR, testR);
1455 		_XmProcessUnlock();
1456 	}
1457 
1458 	_XmProcessLock();
1459 	if ((!_XmRegionIsEmpty(testR)) &&
1460 		(_XmRegionPointInRegion(testR, x, y)))
1461 	{
1462 		_XmRegionUnion(tmpR, tmpR, *visR);
1463 		_XmProcessUnlock();
1464 		return(True);
1465 	}
1466 	else
1467 	{
1468 		_XmProcessUnlock();
1469 		return(False);
1470 	}
1471 
1472 	/* _XmProcessUnlock();	*/	/* not reached */
1473 }
1474 
1475 
1476 static XmDSInfo
PointToDSInfo(XmDropSiteManagerObject dsm,XmDSInfo info,int x,int y)1477 PointToDSInfo(
1478         XmDropSiteManagerObject dsm,
1479         XmDSInfo info,
1480 #if NeedWidePrototypes
1481         int x,
1482         int y )
1483 #else
1484         Position x,
1485         Position y )
1486 #endif /* NeedWidePrototypes */
1487 {
1488   unsigned int	i;
1489   XmDSInfo		child = NULL;
1490 
1491   if (!GetDSLeaf(info))
1492     {
1493       /*
1494        * This should be optimized at some point.
1495        * CalculateAncestorClip is having to do potentially
1496        * unneccessary work, because it starts from scratch each time.
1497        */
1498       for (i = 0; i < GetDSNumChildren(info); i++)
1499 	{
1500 	  Boolean managed;
1501 
1502 	  child = (XmDSInfo) GetDSChild(info,i);
1503 
1504 	  if (GetDSRemote(child))
1505 	    managed = True;
1506 	  else {
1507 	    Widget child_widget;
1508 	    Widget parent;
1509 
1510 	    child_widget = GetDSWidget(child);
1511 	    parent = XtParent(child_widget);
1512 	    managed = XtIsManaged(child_widget);
1513 
1514 	    /* CR 7848,  first check if DS widget is managed and
1515 	       all the parents are managed.  To accomplish this
1516 	       we wander up to the shell and make sure all the widget
1517 	       parents are managed */
1518 	    while(managed && ! XtIsShell(parent)) {
1519 	      managed = XtIsManaged(parent);
1520 	      parent = XtParent(parent);
1521 	    }
1522 	  }
1523 
1524 	  if (managed &&
1525 	      PointInDS(dsm, child, x, y) &&
1526 	      GetDSActivity(child) != XmDROP_SITE_INACTIVE)
1527 	    {
1528 	      if (!GetDSLeaf(child))
1529 		{
1530 		  XmDSInfo descendant = PointToDSInfo(dsm, child,
1531 						      x, y);
1532 
1533 		  if (descendant != NULL)
1534 		    return(descendant);
1535 		}
1536 
1537 	      if (!GetDSInternal(child))
1538 		return(child);
1539 	    }
1540 	}
1541     }
1542 
1543   return(NULL);
1544 }
1545 
1546 static void
DoAnimation(XmDropSiteManagerObject dsm,XmDragMotionClientData motionData,XtPointer callback)1547 DoAnimation(
1548         XmDropSiteManagerObject dsm,
1549         XmDragMotionClientData motionData,
1550         XtPointer callback )
1551 {
1552 
1553   XmDSInfo info = (XmDSInfo) (dsm->dropManager.curInfo);
1554   XmDSInfo parentInfo = (XmDSInfo) GetDSParent(info);
1555   Widget w;
1556   int i, n;
1557   XmDSInfo child;
1558   XmAnimationDataRec animationData;
1559   static XmRegion dsRegion = (XmRegion) NULL;
1560   static XmRegion clipRegion = (XmRegion) NULL;
1561   static XmRegion tmpRegion = (XmRegion) NULL;
1562   Widget dc = dsm->dropManager.curDragContext;
1563   Boolean sourceIsExternal;
1564   Dimension bw = 0;
1565   Arg args[1];
1566 
1567   if (GetDSAnimationStyle(info) == XmDRAG_UNDER_NONE)
1568     return;
1569 
1570   /*
1571    * Should we have saved this from the last top level enter?
1572    */
1573   n = 0;
1574   XtSetArg(args[n], XmNsourceIsExternal, &sourceIsExternal); n++;
1575   XtGetValues(dc, args, n);
1576 
1577   _XmProcessLock();
1578   if (dsRegion == NULL)
1579     {
1580       dsRegion   = _XmRegionCreate();
1581       clipRegion = _XmRegionCreate();
1582       tmpRegion  = _XmRegionCreate();
1583     }
1584   _XmProcessUnlock();
1585 
1586   if (sourceIsExternal)
1587     {
1588       animationData.dragOver = NULL;
1589 
1590       /*
1591        * The window is expected to the the shell window which will be
1592        * drawn in with include inferiors.
1593        */
1594       animationData.window = XtWindow(GetDSWidget(
1595 						  dsm->dropManager.dsRoot));
1596       animationData.screen = XtScreen(GetDSWidget(
1597 						  dsm->dropManager.dsRoot));
1598     }
1599   else
1600     {
1601       animationData.dragOver = motionData->dragOver;
1602       animationData.window = motionData->window;
1603       animationData.screen = XtScreen(motionData->dragOver);
1604     }
1605 
1606   animationData.windowX = dsm->dropManager.rootX;
1607   animationData.windowY = dsm->dropManager.rootY;
1608   animationData.saveAddr =
1609     (XtPointer) &(dsm->dropManager.dragUnderData);
1610 
1611   /* We're going to need a copy. */
1612   _XmProcessLock();
1613   _XmRegionUnion(GetDSRegion(info), GetDSRegion(info), dsRegion);
1614   _XmProcessUnlock();
1615 
1616   bw = GetDSBorderWidth(info);
1617 
1618   if (!GetDSRemote(info))
1619     {
1620       Position wX, wY;
1621 
1622       w = GetDSWidget(info);
1623 
1624       XtTranslateCoords(w, 0, 0, &wX, &wY);
1625       _XmProcessLock();
1626       _XmRegionOffset(dsRegion, (wX - dsm->dropManager.rootX),
1627 		      (wY - dsm->dropManager.rootY));
1628       _XmProcessUnlock();
1629     }
1630 
1631   /* All drawing occurs within the drop site */
1632   _XmProcessLock();
1633   _XmRegionUnion(dsRegion, dsRegion, clipRegion);
1634   _XmProcessUnlock();
1635 
1636   if (bw && !GetDSHasRegion(info))
1637     {
1638       /*
1639        * The region is stored widget relative, and it represents
1640        * the entire drop-sensitive area of the drop site.  In the
1641        * case that we provided the region this includes the
1642        * border area (the x,y position of the bounding box is
1643        * negative), however, we don't animate the entire
1644        * sensitive region; we only animate the sensitive region
1645        * within the border.  Sooo, if we provided the region, and
1646        * the widget has a border, shrink down the region
1647        * (which will offset it) before passing it on to the
1648        * animation code.
1649        */
1650       _XmProcessLock();
1651       _XmRegionShrink(clipRegion, bw, bw);
1652       _XmProcessUnlock();
1653     }
1654 
1655   /*
1656    * trim off anything clipped by ancestors
1657    * ancestorClip region is in shell relative coordinates.
1658    */
1659   _XmProcessLock();
1660   _XmRegionIntersect(clipRegion,
1661 		     dsm->dropManager.curAncestorClipRegion, clipRegion);
1662   _XmProcessUnlock();
1663 
1664   /* trim off anything obsucred by a sibling stacked above us */
1665   if (parentInfo != NULL)
1666     {
1667       for (i = 0; i < (int)GetDSNumChildren(parentInfo); i++)
1668 	{
1669 	  child = (XmDSInfo) GetDSChild(parentInfo, i);
1670 	  if (child == info)
1671 	    break;
1672 	  else
1673 	    {
1674 	      if (GetDSRemote(child))
1675 		{
1676 		  /*
1677 		   * Non-local case.  The info region is in shell
1678 		   * relative coordinates.
1679 		   */
1680 		  _XmProcessLock();
1681 		  _XmRegionSubtract(clipRegion, GetDSRegion(child),
1682 				    clipRegion);
1683 		  _XmProcessUnlock();
1684 		}
1685 	      else
1686 		{
1687 		  /*
1688 		   * Local case.  We have to translate the region.
1689 		   */
1690 		  Position wX, wY;
1691 		  Widget sibling = GetDSWidget(child);
1692 
1693 		  XtTranslateCoords(sibling, 0, 0, &wX, &wY);
1694 		  _XmProcessLock();
1695 		  _XmRegionUnion(GetDSRegion(child),
1696 				 GetDSRegion(child), tmpRegion);
1697 
1698 		  _XmRegionOffset(tmpRegion,
1699 				  (wX - dsm->dropManager.rootX),
1700 				  (wY - dsm->dropManager.rootY));
1701 
1702 		  _XmRegionSubtract(clipRegion, tmpRegion,
1703 				    clipRegion);
1704 		  _XmProcessUnlock();
1705 		}
1706 	    }
1707 	}
1708     }
1709   _XmProcessLock();
1710   animationData.clipRegion = clipRegion;
1711   animationData.dropSiteRegion = dsRegion;
1712   _XmProcessUnlock();
1713 
1714   _XmDragUnderAnimation((Widget)dsm,
1715 			(XtPointer) &animationData,
1716 			(XtPointer) callback);
1717 }
1718 
1719 /*ARGSUSED*/
1720 static void
ProxyDragProc(XmDropSiteManagerObject dsm,XtPointer client_data,XmDragProcCallbackStruct * callback)1721 ProxyDragProc(
1722         XmDropSiteManagerObject dsm,
1723 		XtPointer client_data,
1724         XmDragProcCallbackStruct *callback )
1725 {
1726 	XmDSInfo info = (XmDSInfo) dsm->dropManager.curInfo;
1727 	XmDragContext dc = (XmDragContext) callback->dragContext;
1728 	Atom *import_targets = NULL, *export_targets = NULL;
1729 	Cardinal num_import = 0, num_export = 0;
1730 	int n;
1731 	Arg args[10];
1732 	Widget shell;
1733 	unsigned char operations;
1734 
1735 	operations = callback->operations & GetDSOperations(info);
1736 	if (XmDROP_MOVE & operations)
1737 	  callback->operation = XmDROP_MOVE;
1738 	else if (XmDROP_COPY & operations)
1739 	  callback->operation = XmDROP_COPY;
1740 	else if (XmDROP_LINK & operations)
1741 	  callback->operation = XmDROP_LINK;
1742 	else
1743 	  callback->operation = XmDROP_NOOP;
1744 
1745 	n = 0;
1746 	XtSetArg(args[n], XmNexportTargets, &export_targets); n++;
1747 	XtSetArg(args[n], XmNnumExportTargets, &num_export); n++;
1748 	XtGetValues ((Widget)dc, args, n);
1749 
1750 	if (GetDSRemote(info))
1751 		shell = XtParent(dsm);
1752 	else
1753 		shell = GetDSWidget(info);
1754 
1755 	while (!XtIsShell(shell))
1756 		shell = XtParent(shell);
1757 
1758 	num_import = _XmIndexToTargets(shell,
1759 		GetDSImportTargetsID(info), &import_targets);
1760 
1761 	if ((callback->operation != XmDROP_NOOP) &&
1762 		(XmTargetsAreCompatible (XtDisplay (dsm),
1763 			export_targets, num_export, import_targets, num_import)))
1764 		callback->dropSiteStatus = XmVALID_DROP_SITE;
1765 	else
1766 		callback->dropSiteStatus = XmINVALID_DROP_SITE;
1767 
1768 	callback->animate = True;
1769 }
1770 
1771 /*ARGSUSED*/
1772 static void
HandleEnter(XmDropSiteManagerObject dsm,XmDragMotionClientData motionData,XmDragMotionCallbackStruct * callback,XmDSInfo info,unsigned int style)1773 HandleEnter(
1774         XmDropSiteManagerObject dsm,
1775         XmDragMotionClientData motionData,
1776         XmDragMotionCallbackStruct *callback,
1777         XmDSInfo info,
1778 #if NeedWidePrototypes
1779         unsigned int style )	/* unused */
1780 #else
1781         unsigned char style )
1782 #endif /* NeedWidePrototypes */
1783 {
1784 	XmDragProcCallbackStruct cbRec;
1785 	Position tmpX, tmpY;
1786 	XRectangle extents;
1787 
1788 	cbRec.reason = XmCR_DROP_SITE_ENTER_MESSAGE;
1789 	cbRec.event = (XEvent *) NULL;
1790 	cbRec.timeStamp = callback->timeStamp;
1791 	cbRec.dragContext = dsm->dropManager.curDragContext;
1792 	cbRec.x = dsm->dropManager.curX;
1793 	cbRec.y = dsm->dropManager.curY;
1794 	cbRec.dropSiteStatus = XmVALID_DROP_SITE;
1795 	cbRec.operations = callback->operations;
1796 	cbRec.operation = callback->operation;
1797 	cbRec.animate = True;
1798 
1799 	ProxyDragProc(dsm, NULL, &cbRec);
1800 
1801 	if ((!GetDSRemote(info)) &&
1802 	    (GetDSDragProc(info) != NULL))
1803 	{
1804   	        Widget widget = GetDSWidget(info);
1805 
1806 		/* Return if this is not a managed widget, CR5215 */
1807 		if (! XtIsManaged(widget)) return;
1808 
1809 		/* Make the coordinates widget relative */
1810 		XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY);
1811 
1812 		cbRec.x -= tmpX;
1813 		cbRec.y -= tmpY;
1814 
1815 		(*(GetDSDragProc(info)))
1816 			(widget, NULL, (XtPointer) &cbRec);
1817 	}
1818 
1819 	if ((cbRec.animate) &&
1820 		(cbRec.dropSiteStatus == XmVALID_DROP_SITE))
1821 		DoAnimation(dsm, motionData, (XtPointer) &cbRec);
1822 
1823 	dsm->dropManager.curDropSiteStatus = cbRec.dropSiteStatus;
1824 	dsm->dropManager.curAnimate = cbRec.animate;
1825 	dsm->dropManager.curOperations = cbRec.operations;
1826 	dsm->dropManager.curOperation = cbRec.operation;
1827 
1828 	if (dsm->dropManager.notifyProc)
1829 	{
1830 		XmDropSiteEnterCallbackStruct	outCB;
1831 
1832 		_XmRegionGetExtents(GetDSRegion(info), &extents);
1833 
1834 		outCB.reason = XmCR_DROP_SITE_ENTER;
1835 		outCB.event = NULL;
1836 		outCB.timeStamp = cbRec.timeStamp;
1837 		outCB.dropSiteStatus = cbRec.dropSiteStatus;
1838 		outCB.operations = cbRec.operations;
1839 		outCB.operation = cbRec.operation;
1840 
1841 		/*
1842 		 * Pass outCB.x and outCB.y as the root relative position
1843 		 * of the entered drop site.  Remote info's are already
1844 		 * in shell coordinates; Local info's are in widget
1845 		 * relative coordinates.
1846 		 */
1847 		if (GetDSRemote(info))
1848 		{
1849 			outCB.x = extents.x + dsm->dropManager.rootX;
1850 			outCB.y = extents.y + dsm->dropManager.rootY;
1851 		}
1852 		else
1853 		{
1854 			Widget	widget = GetDSWidget(info);
1855 
1856 			XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY);
1857 
1858 			outCB.x = extents.x + tmpX;
1859 			outCB.y = extents.y + tmpY;
1860 		}
1861 
1862 		(*(dsm->dropManager.notifyProc))
1863 			((Widget)dsm, dsm->dropManager.client_data,
1864 			 (XtPointer) &outCB);
1865 	}
1866 }
1867 
1868 
1869 /*ARGSUSED*/
1870 static void
HandleMotion(XmDropSiteManagerObject dsm,XmDragMotionClientData motionData,XmDragMotionCallbackStruct * callback,XmDSInfo info,unsigned int style)1871 HandleMotion(
1872         XmDropSiteManagerObject dsm,
1873         XmDragMotionClientData motionData,
1874         XmDragMotionCallbackStruct *callback,
1875         XmDSInfo info,
1876 #if NeedWidePrototypes
1877         unsigned int style )
1878 #else
1879         unsigned char style )
1880 #endif /* NeedWidePrototypes */
1881 {
1882 	XmDragProcCallbackStruct cbRec;
1883 
1884 	cbRec.reason = XmCR_DROP_SITE_MOTION_MESSAGE;
1885 	cbRec.event = (XEvent *) NULL;
1886 	cbRec.timeStamp = callback->timeStamp;
1887 	cbRec.dragContext = dsm->dropManager.curDragContext;
1888 	cbRec.x = dsm->dropManager.curX;
1889 	cbRec.y = dsm->dropManager.curY;
1890 	cbRec.animate = dsm->dropManager.curAnimate;
1891 	cbRec.dropSiteStatus = dsm->dropManager.curDropSiteStatus;
1892 
1893 	if (info != NULL)
1894 	{
1895 		cbRec.operations = dsm->dropManager.curOperations;
1896 		cbRec.operation = dsm->dropManager.curOperation;
1897 
1898 		if (	(!GetDSRemote(info)) &&
1899 			(GetDSDragProc(info) != NULL))
1900 		{
1901 			Widget	widget = GetDSWidget(info);
1902 			Position tmpX, tmpY;
1903 
1904 			/* Return if this is not a managed widget */
1905 			if (! XtIsManaged(widget)) return;
1906 
1907 			/* Make the coordinates widget relative */
1908 
1909 			XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY);
1910 
1911 			cbRec.x -= tmpX;
1912 			cbRec.y -= tmpY;
1913 
1914 			(*(GetDSDragProc(info)))
1915 				(widget, NULL, (XtPointer) &cbRec);
1916 		}
1917 
1918 		if ((cbRec.animate) &&
1919 			(cbRec.dropSiteStatus !=
1920 				dsm->dropManager.curDropSiteStatus))
1921 		{
1922 			if (cbRec.dropSiteStatus == XmVALID_DROP_SITE)
1923 				cbRec.reason = XmCR_DROP_SITE_ENTER;
1924 			else
1925 				cbRec.reason = XmCR_DROP_SITE_LEAVE;
1926 
1927 			DoAnimation(dsm, motionData, (XtPointer) &cbRec);
1928 			cbRec.reason = XmCR_DROP_SITE_MOTION_MESSAGE;
1929 		}
1930 
1931 		dsm->dropManager.curDropSiteStatus = cbRec.dropSiteStatus;
1932 		dsm->dropManager.curAnimate = cbRec.animate;
1933 		dsm->dropManager.curOperations = cbRec.operations;
1934 		dsm->dropManager.curOperation = cbRec.operation;
1935 	}
1936 	else
1937 	{
1938 		cbRec.operations = callback->operations;
1939 		cbRec.operation = callback->operation;
1940 		cbRec.dropSiteStatus = XmNO_DROP_SITE;
1941 	}
1942 
1943 	if (dsm->dropManager.notifyProc)
1944 	{
1945 		XmDragMotionCallbackStruct	outCB;
1946 
1947 		outCB.reason = XmCR_DRAG_MOTION;
1948 		outCB.event = NULL;
1949 		outCB.timeStamp = cbRec.timeStamp;
1950 		outCB.dropSiteStatus = cbRec.dropSiteStatus;
1951 		outCB.x = dsm->dropManager.curX;
1952 		outCB.y = dsm->dropManager.curY;
1953 		outCB.operations = cbRec.operations;
1954 		outCB.operation = cbRec.operation;
1955 
1956 		(*(dsm->dropManager.notifyProc))
1957 			((Widget)dsm, dsm->dropManager.client_data,
1958 			 (XtPointer)&outCB);
1959 	}
1960 }
1961 
1962 /*ARGSUSED*/
1963 static void
HandleLeave(XmDropSiteManagerObject dsm,XmDragMotionClientData motionData,XmDragMotionCallbackStruct * callback,XmDSInfo info,unsigned int style,int enterPending)1964 HandleLeave(
1965         XmDropSiteManagerObject dsm,
1966         XmDragMotionClientData motionData,
1967         XmDragMotionCallbackStruct *callback,
1968         XmDSInfo info,
1969 #if NeedWidePrototypes
1970         unsigned int style,	/* unused */
1971         int enterPending )
1972 #else
1973         unsigned char style,
1974         Boolean enterPending )
1975 #endif /* NeedWidePrototypes */
1976 {
1977 	XmDragProcCallbackStruct cbRec;
1978 
1979 	cbRec.reason = XmCR_DROP_SITE_LEAVE_MESSAGE;
1980 	cbRec.event = (XEvent *) NULL;
1981 	cbRec.timeStamp = callback->timeStamp;
1982 	cbRec.dragContext = dsm->dropManager.curDragContext;
1983 	cbRec.x = dsm->dropManager.oldX;
1984 	cbRec.y = dsm->dropManager.oldY;
1985 	cbRec.operations = callback->operations;
1986 	cbRec.operation = callback->operation;
1987 	cbRec.animate = dsm->dropManager.curAnimate;
1988 	cbRec.dropSiteStatus = dsm->dropManager.curDropSiteStatus;
1989 
1990 	if (	(!GetDSRemote(info) && (GetDSDragProc(info) != NULL)))
1991 	{
1992 		Widget widget = GetDSWidget(info);
1993 		Position tmpX, tmpY;
1994 
1995 		/* Make the coordinates widget relative */
1996 
1997 		XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY);
1998 
1999 		cbRec.x -= tmpX;
2000 		cbRec.y -= tmpY;
2001 
2002 		(*(GetDSDragProc(info)))
2003 			(widget, NULL, (XtPointer) &cbRec);
2004 	}
2005 
2006 	if ((cbRec.animate) &&
2007 		(cbRec.dropSiteStatus == XmVALID_DROP_SITE))
2008 		DoAnimation(dsm, motionData, (XtPointer) &cbRec);
2009 
2010 	if (dsm->dropManager.notifyProc)
2011 	{
2012 		XmDropSiteEnterPendingCallbackStruct	outCB;
2013 
2014 		outCB.reason = XmCR_DROP_SITE_LEAVE;
2015 		outCB.event = callback->event;
2016 		outCB.timeStamp = cbRec.timeStamp;
2017                 outCB.enter_pending = enterPending;
2018 
2019 		(*(dsm->dropManager.notifyProc))
2020 			((Widget)dsm, dsm->dropManager.client_data,
2021 			 (XtPointer)&outCB);
2022 	}
2023 }
2024 
2025 
2026 /*ARGSUSED*/
2027 static void
ProcessMotion(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer calldata)2028 ProcessMotion(
2029         XmDropSiteManagerObject dsm,
2030         XtPointer clientData,
2031         XtPointer calldata )
2032 {
2033   XmDragMotionCallbackStruct *callback =
2034     (XmDragMotionCallbackStruct *) calldata;
2035   XmDragMotionClientData	motionData =
2036     (XmDragMotionClientData) clientData;
2037   Position	x = callback->x, y = callback->y;
2038   XmDSInfo	dsRoot = (XmDSInfo) (dsm->dropManager.dsRoot);
2039   XmDSInfo	curDSInfo = (XmDSInfo)(dsm->dropManager.curInfo);
2040   XmDSInfo	newDSInfo;
2041   unsigned char style;
2042 
2043   if (dsm->dropManager.curDragContext == NULL)
2044     {
2045       XmeWarning((Widget)dsm, MESSAGE2);
2046       return;
2047     }
2048 
2049   style = _XmGetActiveProtocolStyle(dsm->dropManager.curDragContext);
2050   dsm->dropManager.curTime = callback->timeStamp;
2051   dsm->dropManager.oldX = dsm->dropManager.curX;
2052   dsm->dropManager.oldY = dsm->dropManager.curY;
2053   dsm->dropManager.curX = x;
2054   dsm->dropManager.curY = y;
2055 
2056   if (dsRoot)
2057     {
2058       /*
2059        * Make x and y shell relative, preregister info's are shell
2060        * relative, and CalculateAncestorClip (called for dynammic)
2061        * returns a shell relative rectangle.
2062        */
2063       x -= dsm->dropManager.rootX;
2064       y -= dsm->dropManager.rootY;
2065 
2066       newDSInfo =  PointToDSInfo(dsm, dsRoot, x, y);
2067 
2068       if (curDSInfo != newDSInfo)
2069 	{
2070 	  if (curDSInfo) {
2071 	    /* if we are entering a drop site as we leave
2072 	     * the old drop site, we don't want to set
2073 	     * the drop site status to NO_DROP_SITE. We
2074 	     * are using the event field of the callback
2075 	     * (since is is guarenteed to be NULL) for
2076 	     * use as a flag, since we can't modify the
2077 	     * public callback struct.
2078 	     */
2079 	    if (newDSInfo)
2080 	      HandleLeave(dsm, motionData, callback,
2081 			  curDSInfo, style, True);
2082 	    else
2083 	      HandleLeave(dsm, motionData, callback,
2084 			  curDSInfo, style, False);
2085 	  }
2086 
2087 	  dsm->dropManager.curInfo = (XtPointer) newDSInfo;
2088 	  _XmRegionUnion(dsm->dropManager.newAncestorClipRegion,
2089 			 dsm->dropManager.newAncestorClipRegion,
2090 			 dsm->dropManager.curAncestorClipRegion);
2091 
2092 	  if (newDSInfo)
2093 	    HandleEnter(dsm, motionData, callback,
2094 			newDSInfo, style);
2095 
2096 	  return;
2097 	}
2098     }
2099 
2100   HandleMotion(dsm, motionData, callback, curDSInfo, style);
2101 }
2102 
2103 /*ARGSUSED*/
2104 static void
ProcessDrop(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer cb)2105 ProcessDrop(
2106         XmDropSiteManagerObject dsm,
2107         XtPointer clientData,
2108         XtPointer cb )
2109 {
2110 	XmDragTopLevelClientData cd =
2111 		(XmDragTopLevelClientData) clientData;
2112 	XmDropStartCallbackStruct *callback =
2113 		(XmDropStartCallbackStruct *) cb;
2114 	XmDropProcCallbackStruct cbRec;
2115 	Widget	dragContext =
2116 		XmGetDragContext((Widget)dsm, callback->timeStamp);
2117 	XmDSInfo	info = NULL;
2118 	Widget	widget = NULL;
2119 	Position x, y, tmpX, tmpY;
2120 	XmDSInfo savRoot, savInfo;
2121 	XmDSInfo newRoot = (XmDSInfo) DSMWidgetToInfo(dsm, cd->destShell);
2122 	Position savX, savY;
2123 	Dimension savW, savH;
2124 	Time savTime;
2125 
2126 	if (dragContext == NULL)
2127 	{
2128 		/*
2129 		 * Can't do a failure transfer.  Just give up.
2130 		 *
2131 		 * Should we send a warning message?
2132 		 */
2133 		return;
2134 	}
2135 
2136 	/*
2137 	 * Look out for race conditions.
2138 	 *
2139 	 * This should be enough state saving to allow the drop to occur
2140 	 * in the middle of some other drag.
2141 	 */
2142 	savRoot = (XmDSInfo) dsm->dropManager.dsRoot;
2143 	savInfo = (XmDSInfo) dsm->dropManager.curInfo;
2144 	savX = dsm->dropManager.rootX;
2145 	savY = dsm->dropManager.rootY;
2146 	savW = dsm->dropManager.rootW;
2147 	savH = dsm->dropManager.rootH;
2148 	savTime = dsm->dropManager.curTime;
2149 
2150 	dsm->dropManager.curTime = callback->timeStamp;
2151 	dsm->dropManager.dsRoot = (XtPointer) newRoot;
2152 	dsm->dropManager.rootX = cd->xOrigin;
2153 	dsm->dropManager.rootY = cd->yOrigin;
2154 	dsm->dropManager.rootW = cd->width;
2155 	dsm->dropManager.rootH = cd->height;
2156 
2157 	x = callback->x - dsm->dropManager.rootX;
2158 	y = callback->y - dsm->dropManager.rootY;
2159 
2160 	if (newRoot != NULL)
2161 		info = PointToDSInfo(dsm, (XmDSInfo) dsm->dropManager.dsRoot, x, y);
2162 
2163 	if (info != NULL)
2164         {
2165             widget = GetDSWidget(info);
2166         }
2167 	/* Handle error conditions nicely */
2168 	if ((info == NULL) ||
2169 	    ! XtIsManaged(widget) || /* CR 5215 */
2170 	    /* These are wierd conditions */
2171 	    (newRoot == NULL)   ||
2172 	    (GetDSRemote(info)) ||
2173 	    (GetDSDropProc(info) == NULL))
2174 	{
2175 		/* we will do a failure drop transfer */
2176 		Arg		args[4];
2177 		Cardinal	i = 0;
2178 
2179 		XtSetArg(args[i], XmNtransferStatus, XmTRANSFER_FAILURE); i++;
2180 		XtSetArg(args[i], XmNnumDropTransfers, 0); i++;
2181 		(void) XmDropTransferStart(dragContext, args, i);
2182 
2183 		/* ???
2184 		 * Should we do something interesting with the callback
2185 		 * struct before calling notify in these cases?
2186 		 * ???
2187 		 */
2188 	}
2189 	else
2190 	{
2191 
2192 		/* This will be needed by the ProxyDragProc */
2193 		dsm->dropManager.curInfo = (XtPointer) info;
2194 
2195 		/* Make the coordinates widget relative */
2196 		XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY);
2197 
2198 		/* Load the dropProcStruct */
2199 		cbRec.reason = XmCR_DROP_MESSAGE;
2200 		cbRec.event = callback->event;
2201 		cbRec.timeStamp = callback->timeStamp;
2202 		cbRec.dragContext = dragContext;
2203 
2204 		/* Make the coordinates widget relative */
2205 		XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY);
2206 
2207 		cbRec.x = callback->x - tmpX;
2208 		cbRec.y = callback->y - tmpY;
2209 
2210 
2211 		{ /* Nonsense to pre-load the cbRec correctly */
2212 			XmDragProcCallbackStruct junkRec;
2213 
2214 			junkRec.reason = XmCR_DROP_SITE_MOTION_MESSAGE;
2215 			junkRec.event = callback->event;
2216 			junkRec.timeStamp = cbRec.timeStamp;
2217 			junkRec.dragContext = dragContext;
2218 			junkRec.x = cbRec.x;
2219 			junkRec.y = cbRec.y;
2220 			junkRec.dropSiteStatus = dsm->dropManager.curDropSiteStatus;
2221 			junkRec.operation = callback->operation;
2222 			junkRec.operations = callback->operations;
2223 			junkRec.animate = dsm->dropManager.curAnimate;
2224 
2225 			ProxyDragProc(dsm, NULL, &junkRec);
2226 
2227 			cbRec.dropSiteStatus = junkRec.dropSiteStatus;
2228 			cbRec.operation = junkRec.operation;
2229 			cbRec.operations = junkRec.operations;
2230 		}
2231 
2232 		cbRec.dropAction = callback->dropAction;
2233 
2234 		/* Call the drop site's drop proc */
2235 		(*(GetDSDropProc(info))) (widget, NULL, (XtPointer) &cbRec);
2236 
2237 		callback->operation = cbRec.operation;
2238 		callback->operations = cbRec.operations;
2239 		callback->dropSiteStatus = cbRec.dropSiteStatus;
2240 		callback->dropAction = cbRec.dropAction;
2241 	}
2242 
2243 	if (dsm->dropManager.notifyProc)
2244 	{
2245 		(*(dsm->dropManager.notifyProc))
2246 			((Widget)dsm, dsm->dropManager.client_data,
2247 			(XtPointer)callback);
2248 	}
2249 
2250 	dsm->dropManager.dsRoot = (XtPointer) savRoot;
2251 	dsm->dropManager.curInfo = (XtPointer) savInfo;
2252 	dsm->dropManager.rootX = savX;
2253 	dsm->dropManager.rootY = savY;
2254 	dsm->dropManager.rootW = savW;
2255 	dsm->dropManager.rootH = savH;
2256 	dsm->dropManager.curTime = savTime;
2257 }
2258 
2259 /*ARGSUSED*/
2260 static void
ChangeOperation(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer calldata)2261 ChangeOperation(
2262         XmDropSiteManagerObject dsm,
2263         XtPointer clientData,
2264         XtPointer calldata )
2265 {
2266 	XmOperationChangedCallbackStruct *callback =
2267 		(XmOperationChangedCallbackStruct *) calldata;
2268 	XmDragMotionClientData	motionData =
2269 		(XmDragMotionClientData) clientData;
2270 	XmDragProcCallbackStruct cbRec;
2271 	XmDSInfo info = (XmDSInfo) dsm->dropManager.curInfo;
2272 	unsigned char style;
2273 
2274 	if ((cbRec.dragContext = dsm->dropManager.curDragContext) == NULL)
2275 	{
2276 		XmeWarning((Widget)dsm, MESSAGE3);
2277 		return;
2278 	}
2279 	else
2280 	{
2281 		style = _XmGetActiveProtocolStyle(
2282 			dsm->dropManager.curDragContext);
2283 	}
2284 
2285 	cbRec.reason = callback->reason;
2286 	cbRec.event = callback->event;
2287 	cbRec.timeStamp = callback->timeStamp;
2288 
2289 	cbRec.x = dsm->dropManager.curX;
2290 	cbRec.y = dsm->dropManager.curY;
2291 	cbRec.dropSiteStatus = dsm->dropManager.curDropSiteStatus;
2292 	cbRec.animate = dsm->dropManager.curAnimate;
2293 
2294 	cbRec.operation = callback->operation;
2295 	cbRec.operations = callback->operations;
2296 
2297 	if (info != NULL)
2298 	{
2299 		ProxyDragProc(dsm, NULL, &cbRec);
2300 
2301 		if ((style == XmDRAG_DYNAMIC) &&
2302 			(!GetDSRemote(info)) &&
2303 			(GetDSDragProc(info) != NULL))
2304 		{
2305 			Widget widget = GetDSWidget(info);
2306 			Position tmpX, tmpY;
2307 
2308 			/* Make the coordinates widget relative */
2309 			XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY);
2310 
2311 			cbRec.x -= tmpX;
2312 			cbRec.y -= tmpY;
2313 
2314 			(*(GetDSDragProc(info)))
2315 				(widget, NULL, (XtPointer) &cbRec);
2316 		}
2317 
2318 		if ((cbRec.animate) &&
2319 			(cbRec.dropSiteStatus !=
2320 				dsm->dropManager.curDropSiteStatus))
2321 		{
2322 			if (cbRec.dropSiteStatus == XmVALID_DROP_SITE)
2323 				cbRec.reason = XmCR_DROP_SITE_ENTER_MESSAGE;
2324 			else
2325 				cbRec.reason = XmCR_DROP_SITE_LEAVE_MESSAGE;
2326 
2327 			DoAnimation(dsm, motionData, (XtPointer) &cbRec);
2328 			cbRec.reason = callback->reason;
2329 		}
2330 
2331 		/* Update the callback rec */
2332 		callback->operations = cbRec.operations;
2333 		callback->operation = cbRec.operation;
2334 		callback->dropSiteStatus = cbRec.dropSiteStatus;
2335 
2336 		/* Update the drop site manager */
2337 		dsm->dropManager.curDropSiteStatus = cbRec.dropSiteStatus;
2338 		dsm->dropManager.curAnimate = cbRec.animate;
2339 		dsm->dropManager.curOperations = cbRec.operations;
2340 		dsm->dropManager.curOperation = cbRec.operation;
2341 	}
2342 	else
2343 	{
2344 		callback->dropSiteStatus = XmNO_DROP_SITE;
2345 	}
2346 
2347 	if (dsm->dropManager.notifyProc)
2348 	{
2349 		(*(dsm->dropManager.notifyProc))
2350 			((Widget)dsm, dsm->dropManager.client_data,
2351 			(XtPointer)callback);
2352 	}
2353 }
2354 
2355 /*ARGSUSED*/
2356 static void
PutDSToStream(XmDropSiteManagerObject dsm,XmDSInfo dsInfo,int last,XtPointer dataPtr)2357 PutDSToStream(
2358         XmDropSiteManagerObject dsm,
2359         XmDSInfo dsInfo,
2360 #if NeedWidePrototypes
2361         int last,
2362 #else
2363         Boolean last,
2364 #endif /* NeedWidePrototypes */
2365         XtPointer dataPtr )
2366 {
2367 	static XmRegion tmpRegion = NULL;
2368 	unsigned char dsType = 0, tType = 0;
2369 	unsigned char unitType = XmPIXELS;
2370 	Position wX, wY;
2371 	Widget w = GetDSWidget(dsInfo);
2372 	Dimension bw = XtBorderWidth(w);
2373 	XmICCDropSiteInfoStruct iccInfo;
2374 	Arg args[30];
2375 	int n;
2376 
2377 	_XmProcessLock();
2378 	if (tmpRegion == NULL)
2379 	{
2380 		tmpRegion = _XmRegionCreate();
2381 	}
2382 	_XmProcessUnlock();
2383 
2384 	/*
2385 	 * Clear out the info.  This is especially important in the cases
2386 	 * that the widget does not define resources all of the required
2387 	 * animation resources.
2388 	 */
2389 	bzero(((void *) &iccInfo), sizeof(iccInfo));
2390 
2391 	if (last)
2392 		tType |= XmDSM_T_CLOSE;
2393 	else
2394 		tType &= ~ XmDSM_T_CLOSE;
2395 
2396 
2397 	if (GetDSLeaf(dsInfo) || (!GetDSNumChildren(dsInfo)))
2398 		dsType |= XmDSM_DS_LEAF;
2399 	else
2400 		dsType &= ~ XmDSM_DS_LEAF;
2401 
2402 	if (GetDSInternal(dsInfo))
2403 		dsType |= XmDSM_DS_INTERNAL;
2404 	else
2405 		dsType &= ~ XmDSM_DS_INTERNAL;
2406 
2407 	if (GetDSHasRegion(dsInfo))
2408 		dsType |= XmDSM_DS_HAS_REGION;
2409 	else
2410 		dsType &= ~ XmDSM_DS_HAS_REGION;
2411 
2412 	/*
2413 	 * The local drop site tree is always kept in widget relative
2414 	 * coordinates.  We have to put shell relative coordinates on
2415 	 * the wire however, so we to a copy and translate into a tmp
2416 	 * region.
2417 	 */
2418 	XtTranslateCoords(w, 0, 0, &wX, &wY);
2419 
2420 	if (GetDSHasRegion(dsInfo))
2421 	{
2422 		_XmProcessLock();
2423 		_XmRegionUnion(GetDSRegion(dsInfo), GetDSRegion(dsInfo),
2424 			tmpRegion);
2425 		_XmProcessUnlock();
2426 	}
2427 	else
2428 	{
2429 		XRectangle rect;
2430 
2431 		rect.x = rect.y = -bw;
2432 		rect.width = XtWidth(w) + (2 * bw);
2433 		rect.height = XtHeight(w) + (2 * bw);
2434 
2435 		_XmProcessLock();
2436 		_XmRegionClear(tmpRegion);
2437 		_XmRegionUnionRectWithRegion(&rect, tmpRegion, tmpRegion);
2438 		_XmProcessUnlock();
2439 	}
2440 
2441 	_XmProcessLock();
2442 	_XmRegionOffset(tmpRegion, (wX - dsm->dropManager.rootX),
2443 		(wY - dsm->dropManager.rootY));
2444 	_XmProcessUnlock();
2445 
2446 	/*
2447 	 * We need to pull up the relevant visual information from
2448 	 * the widget so it will be available for correct animation
2449 	 * by a non-local peregister initiator.
2450 	 */
2451 	iccInfo.header.dropType = dsType;
2452 	iccInfo.header.dropActivity = GetDSActivity(dsInfo);
2453 	iccInfo.header.traversalType = tType;
2454 	iccInfo.header.animationStyle = GetDSAnimationStyle(dsInfo);
2455 	iccInfo.header.operations = GetDSOperations(dsInfo);
2456 	iccInfo.header.importTargetsID = GetDSImportTargetsID(dsInfo);
2457 	_XmProcessLock();
2458 	iccInfo.header.region = tmpRegion;
2459 	_XmProcessUnlock();
2460 
2461 	/*
2462 	 * We need to retrieve information from the widget. XtGetValues is
2463 	 * too slow, so retrieve the information directly from the widget
2464 	 * instance.
2465 	 *
2466 	 * XtGetValues is used for non-Motif widgets, just in case they provide
2467 	 * Motif-style resources.
2468 	 *
2469 	 * (See also XmDropSiteGetActiveVisuals() )
2470 	 */
2471 
2472 	if (XmIsPrimitive(w))
2473 	{
2474 	     XmPrimitiveWidget pw= (XmPrimitiveWidget)w;
2475 
2476 	    switch(iccInfo.header.animationStyle)
2477 	    {
2478 		case XmDRAG_UNDER_HIGHLIGHT:
2479 		{
2480 			XmICCDropSiteHighlight info =
2481 				(XmICCDropSiteHighlight)  (&iccInfo);
2482 
2483 			info->animation_data.highlightPixmap = XmUNSPECIFIED_PIXMAP;
2484 			if (!GetDSHasRegion(dsInfo))
2485 				info->animation_data.borderWidth =
2486 					pw->core.border_width;
2487 			info->animation_data.highlightThickness =
2488 				pw->primitive.highlight_thickness;
2489 			info->animation_data.highlightColor =
2490 				pw->primitive.highlight_color;
2491 			info->animation_data.highlightPixmap =
2492 				pw->primitive.highlight_pixmap;
2493 			info->animation_data.background =
2494 				pw->core.background_pixel;
2495 		}
2496 		break;
2497 		case XmDRAG_UNDER_SHADOW_IN:
2498 		case XmDRAG_UNDER_SHADOW_OUT:
2499 		{
2500 			XmICCDropSiteShadow info =
2501 				(XmICCDropSiteShadow)  (&iccInfo);
2502 
2503 			info->animation_data.topShadowPixmap =
2504 				info->animation_data.bottomShadowPixmap =
2505 				XmUNSPECIFIED_PIXMAP;
2506 
2507 			if (!GetDSHasRegion(dsInfo))
2508 				info->animation_data.borderWidth =
2509 					pw->core.border_width;
2510 			info->animation_data.highlightThickness =
2511 				pw->primitive.highlight_thickness;
2512 			info->animation_data.shadowThickness =
2513 				pw->primitive.shadow_thickness;
2514 			info->animation_data.foreground =
2515 				pw->primitive.foreground;
2516 			info->animation_data.topShadowColor =
2517 				pw->primitive.top_shadow_color;
2518 			info->animation_data.topShadowPixmap =
2519 				pw->primitive.top_shadow_pixmap;
2520 			info->animation_data.bottomShadowColor =
2521 				pw->primitive.bottom_shadow_color;
2522 			info->animation_data.bottomShadowPixmap =
2523 				pw->primitive.bottom_shadow_pixmap;
2524 		}
2525 		break;
2526 		case XmDRAG_UNDER_PIXMAP:
2527 		{
2528 			XmICCDropSitePixmap info =
2529 				(XmICCDropSitePixmap)  (&iccInfo);
2530 			XmDSLocalPixmapStyle ps =
2531 				(XmDSLocalPixmapStyle) GetDSLocalAnimationPart(dsInfo);
2532 
2533 			info->animation_data.animationPixmapDepth =
2534 				ps->animation_pixmap_depth;
2535 			info->animation_data.animationPixmap =
2536 				ps->animation_pixmap;
2537 			info->animation_data.animationMask = ps->animation_mask;
2538 
2539 			if (!GetDSHasRegion(dsInfo))
2540 				info->animation_data.borderWidth =
2541 					pw->core.border_width;
2542 			info->animation_data.highlightThickness =
2543 				pw->primitive.highlight_thickness;
2544 			info->animation_data.shadowThickness =
2545 				pw->primitive.shadow_thickness;
2546 			info->animation_data.foreground =
2547 				pw->primitive.foreground;
2548 			info->animation_data.background =
2549 				pw->core.background_pixel;
2550 		}
2551 		break;
2552 		case XmDRAG_UNDER_NONE:
2553 		{
2554 			XmICCDropSiteNone info =
2555 				(XmICCDropSiteNone)  (&iccInfo);
2556 
2557 			if (!GetDSHasRegion(dsInfo))
2558 				info->animation_data.borderWidth = pw->core.border_width;
2559 			else
2560 				info->animation_data.borderWidth = 0;
2561 		}
2562 		default:
2563 		{
2564 			/*EMPTY*/
2565 		}
2566 		break;
2567 	    }
2568 	}
2569 	else if (XmIsManager(w) || XmIsGadget(w))
2570 	{
2571 	    XmManagerWidget mw;
2572             XmGadget g;
2573             Boolean is_gadget;
2574 
2575             if (XmIsGadget(w)) {
2576 	       mw = (XmManagerWidget) XtParent(w);
2577 	       g = (XmGadget) w;
2578                is_gadget = True;
2579             } else {
2580 	       mw = (XmManagerWidget) w;
2581 	       g = NULL;
2582                is_gadget = False;
2583             }
2584 
2585 	    switch(iccInfo.header.animationStyle)
2586 	    {
2587 		case XmDRAG_UNDER_HIGHLIGHT:
2588 		{
2589 			XmICCDropSiteHighlight info =
2590 				(XmICCDropSiteHighlight)  (&iccInfo);
2591 
2592 			info->animation_data.highlightPixmap = XmUNSPECIFIED_PIXMAP;
2593 			if (!GetDSHasRegion(dsInfo))
2594 			{
2595                            if (is_gadget)
2596 			      info->animation_data.borderWidth =
2597 					w->core.border_width;
2598                            else
2599 			      info->animation_data.borderWidth =
2600 					mw->core.border_width;
2601                         }
2602 
2603 		       /* Temporary hack until we support full defaulting */
2604 		        info->animation_data.highlightThickness = 1;
2605 			info->animation_data.highlightColor =
2606 				mw->manager.highlight_color;
2607 			info->animation_data.highlightPixmap =
2608 				mw->manager.highlight_pixmap;
2609 			info->animation_data.background =
2610 				mw->core.background_pixel;
2611 		}
2612 		break;
2613 		case XmDRAG_UNDER_SHADOW_IN:
2614 		case XmDRAG_UNDER_SHADOW_OUT:
2615 		{
2616 			XmICCDropSiteShadow info =
2617 				(XmICCDropSiteShadow)  (&iccInfo);
2618 
2619 			info->animation_data.topShadowPixmap =
2620 				info->animation_data.bottomShadowPixmap =
2621 				XmUNSPECIFIED_PIXMAP;
2622 
2623                         if (is_gadget)
2624 			{
2625 			   if (!GetDSHasRegion(dsInfo))
2626 				info->animation_data.borderWidth =
2627 					w->core.border_width;
2628 
2629 			   info->animation_data.shadowThickness =
2630 				   g->gadget.shadow_thickness;
2631                         }
2632 			else
2633 			{
2634 			   if (!GetDSHasRegion(dsInfo))
2635 				info->animation_data.borderWidth =
2636 					mw->core.border_width;
2637 
2638 			   info->animation_data.shadowThickness =
2639 				   mw->manager.shadow_thickness;
2640                         }
2641 			info->animation_data.highlightThickness = 0;
2642 			info->animation_data.foreground =
2643 				mw->manager.foreground;
2644 			info->animation_data.topShadowColor =
2645 				mw->manager.top_shadow_color;
2646 			info->animation_data.topShadowPixmap =
2647 				mw->manager.top_shadow_pixmap;
2648 			info->animation_data.bottomShadowColor =
2649 				mw->manager.bottom_shadow_color;
2650 			info->animation_data.bottomShadowPixmap =
2651 				mw->manager.bottom_shadow_pixmap;
2652 		}
2653 		break;
2654 		case XmDRAG_UNDER_PIXMAP:
2655 		{
2656 			XmICCDropSitePixmap info =
2657 				(XmICCDropSitePixmap)  (&iccInfo);
2658 			XmDSLocalPixmapStyle ps =
2659 				(XmDSLocalPixmapStyle) GetDSLocalAnimationPart(dsInfo);
2660 
2661 			info->animation_data.animationPixmapDepth =
2662 				ps->animation_pixmap_depth;
2663 			info->animation_data.animationPixmap =
2664 				ps->animation_pixmap;
2665 			info->animation_data.animationMask = ps->animation_mask;
2666 
2667                         if (is_gadget)
2668 			{
2669 			   if (!GetDSHasRegion(dsInfo))
2670 				info->animation_data.borderWidth =
2671 					w->core.border_width;
2672 
2673 			   info->animation_data.shadowThickness =
2674 				   g->gadget.shadow_thickness;
2675                         }
2676 			else
2677 			{
2678 			   if (!GetDSHasRegion(dsInfo))
2679 				info->animation_data.borderWidth =
2680 					mw->core.border_width;
2681 
2682 			   info->animation_data.shadowThickness =
2683 				   mw->manager.shadow_thickness;
2684                         }
2685 			info->animation_data.highlightThickness = 0;
2686 			info->animation_data.foreground =
2687 				mw->manager.foreground;
2688 			info->animation_data.background =
2689 				mw->core.background_pixel;
2690 		}
2691 		break;
2692 		case XmDRAG_UNDER_NONE:
2693 		{
2694 			XmICCDropSiteNone info =
2695 				(XmICCDropSiteNone)  (&iccInfo);
2696 
2697 			if (!GetDSHasRegion(dsInfo))
2698 			{
2699                            if (is_gadget)
2700 			      info->animation_data.borderWidth =
2701 					w->core.border_width;
2702                            else
2703 			      info->animation_data.borderWidth =
2704 					mw->core.border_width;
2705                         } else
2706 			   info->animation_data.borderWidth = 0;
2707 		}
2708 		default:
2709 		{
2710 			/*EMPTY*/
2711 		}
2712 		break;
2713 	    }
2714 	}
2715 	else /* non-Motif subclass */
2716 	{
2717 		n = 0;
2718 		XtSetArg(args[n], XmNunitType, &unitType); n++;
2719 		XtGetValues(w, args, n);
2720 
2721 		if (unitType != XmPIXELS) { /* we need values in pixels */
2722 		    n = 0;
2723 		    XtSetArg(args[n], XmNunitType, XmPIXELS); n++;
2724 		    XtSetValues(w, args, n);
2725 		}
2726 
2727 	 	switch(iccInfo.header.animationStyle)
2728 	 	{
2729 		    case XmDRAG_UNDER_HIGHLIGHT:
2730 		    {
2731 			XmICCDropSiteHighlight info =
2732 				(XmICCDropSiteHighlight)  (&iccInfo);
2733 
2734 			/*
2735 			 * Pre-load a sane pixmap default in case the
2736 			 * widget doesn't have a pixmap resource.
2737 			 */
2738 			info->animation_data.highlightPixmap = XmUNSPECIFIED_PIXMAP;
2739 
2740 			n = 0;
2741 			if (!GetDSHasRegion(dsInfo))
2742 			{
2743 				XtSetArg(args[n], XmNborderWidth,
2744 					&(info->animation_data.borderWidth)); n++;
2745 			}
2746 			XtSetArg(args[n], XmNhighlightThickness,
2747 				&(info->animation_data.highlightThickness)); n++;
2748 			XtSetArg(args[n], XmNbackground,
2749 				&(info->animation_data.background)); n++;
2750 			XtSetArg(args[n], XmNhighlightColor,
2751 				&(info->animation_data.highlightColor)); n++;
2752 			XtSetArg(args[n], XmNhighlightPixmap,
2753 				&(info->animation_data.highlightPixmap)); n++;
2754 			XtGetValues(w, args, n);
2755 		    }
2756 		    break;
2757 		    case XmDRAG_UNDER_SHADOW_IN:
2758 		    case XmDRAG_UNDER_SHADOW_OUT:
2759 		    {
2760 			XmICCDropSiteShadow info =
2761 				(XmICCDropSiteShadow)  (&iccInfo);
2762 
2763 			/* Pre-load some sane pixmap defaults */
2764 			info->animation_data.topShadowPixmap =
2765 				info->animation_data.bottomShadowPixmap =
2766 				XmUNSPECIFIED_PIXMAP;
2767 
2768 			n = 0;
2769 			if (!GetDSHasRegion(dsInfo))
2770 			{
2771 				XtSetArg(args[n], XmNborderWidth,
2772 					&(info->animation_data.borderWidth)); n++;
2773 			}
2774 			XtSetArg(args[n], XmNhighlightThickness,
2775 				&(info->animation_data.highlightThickness)); n++;
2776 			XtSetArg(args[n], XmNshadowThickness,
2777 				&(info->animation_data.shadowThickness)); n++;
2778 			XtSetArg(args[n], XmNforeground,
2779 				&(info->animation_data.foreground)); n++;
2780 			XtSetArg(args[n], XmNtopShadowColor,
2781 				&(info->animation_data.topShadowColor)); n++;
2782 			XtSetArg(args[n], XmNbottomShadowColor,
2783 				&(info->animation_data.bottomShadowColor)); n++;
2784 			XtSetArg(args[n], XmNtopShadowPixmap,
2785 				&(info->animation_data.topShadowPixmap)); n++;
2786 			XtSetArg(args[n], XmNbottomShadowPixmap,
2787 				&(info->animation_data.bottomShadowPixmap)); n++;
2788 			XtGetValues(w, args, n);
2789 		    }
2790 		    break;
2791 		    case XmDRAG_UNDER_PIXMAP:
2792 		    {
2793 			XmICCDropSitePixmap info =
2794 				(XmICCDropSitePixmap)  (&iccInfo);
2795 			XmDSLocalPixmapStyle ps =
2796 				(XmDSLocalPixmapStyle) GetDSLocalAnimationPart(dsInfo);
2797 
2798 			info->animation_data.animationPixmapDepth =
2799 				ps->animation_pixmap_depth;
2800 			info->animation_data.animationPixmap =
2801 				ps->animation_pixmap;
2802 			info->animation_data.animationMask = ps->animation_mask;
2803 
2804 			n = 0;
2805 			if (!GetDSHasRegion(dsInfo))
2806 			{
2807 				XtSetArg(args[n], XmNborderWidth,
2808 					&(info->animation_data.borderWidth)); n++;
2809 			}
2810 			XtSetArg(args[n], XmNhighlightThickness,
2811 				&(info->animation_data.highlightThickness)); n++;
2812 			XtSetArg(args[n], XmNshadowThickness,
2813 				&(info->animation_data.shadowThickness)); n++;
2814 			XtSetArg(args[n], XmNforeground,
2815 				&(info->animation_data.foreground)); n++;
2816 			XtSetArg(args[n], XmNbackground,
2817 				&(info->animation_data.background)); n++;
2818 			XtGetValues(w, args, n);
2819 		}
2820 		    break;
2821 		    case XmDRAG_UNDER_NONE:
2822 		    {
2823 			XmICCDropSiteNone info =
2824 				(XmICCDropSiteNone)  (&iccInfo);
2825 
2826 			if (!GetDSHasRegion(dsInfo))
2827 			{
2828 				n = 0;
2829 				XtSetArg(args[n], XmNborderWidth,
2830 					&(info->animation_data.borderWidth)); n++;
2831 				XtGetValues(w, args, n);
2832 			}
2833 			else
2834 				info->animation_data.borderWidth = 0;
2835 		    }
2836 		    default:
2837 		    {
2838 			/*EMPTY*/
2839 		    }
2840 		    break;
2841 
2842 		}
2843 
2844 		if (unitType != XmPIXELS) {
2845 		    n = 0;
2846 		    XtSetArg(args[n], XmNunitType, unitType); n++;
2847 		    XtSetValues(w, args, n);
2848 		}
2849 	}
2850 	_XmWriteDSToStream(dsm, dataPtr, &iccInfo);
2851 }
2852 
2853 /*ARGSUSED*/
2854 static void
GetDSFromDSM(XmDropSiteManagerObject dsm,XmDSInfo parentInfo,int last,XtPointer dataPtr)2855 GetDSFromDSM(
2856         XmDropSiteManagerObject dsm,
2857         XmDSInfo parentInfo,
2858 #if NeedWidePrototypes
2859         int last,
2860 #else
2861         Boolean last,
2862 #endif /* NeedWidePrototypes */
2863         XtPointer dataPtr )
2864 {
2865 	XmDSInfo child;
2866 	int i;
2867 
2868 	PutDSToStream(dsm, parentInfo, last, dataPtr);
2869 
2870 	last = False;
2871 	for (i = 0; i < (int)GetDSNumChildren(parentInfo); i++)
2872 	{
2873 		if ((i + 1) == GetDSNumChildren(parentInfo))
2874 			last = True;
2875 
2876 		child = (XmDSInfo) GetDSChild(parentInfo, i);
2877 		if (!GetDSLeaf(child))
2878 			GetDSFromDSM(dsm, child, last, dataPtr);
2879 		else
2880 			PutDSToStream(dsm, child, last, dataPtr);
2881 	}
2882 }
2883 
2884 /*ARGSUSED*/
2885 static int
GetTreeFromDSM(XmDropSiteManagerObject dsm,Widget shell,XtPointer dataPtr)2886 GetTreeFromDSM(
2887         XmDropSiteManagerObject dsm,
2888         Widget shell,
2889         XtPointer dataPtr )
2890 {
2891 	XmDSInfo root = (XmDSInfo) DSMWidgetToInfo(dsm, shell);
2892 	Position shellX, shellY, savX, savY;
2893 
2894 	if (root == NULL)
2895 		return(0);
2896 	XtTranslateCoords(shell, 0, 0, &shellX, &shellY);
2897 
2898 	/* Save current */
2899 	savX = dsm->dropManager.rootX;
2900 	savY = dsm->dropManager.rootY;
2901 
2902 	dsm->dropManager.rootX = shellX;
2903 	dsm->dropManager.rootY = shellY;
2904 
2905 	DSMSyncTree(dsm, shell);
2906 	GetDSFromDSM(dsm, root, True, dataPtr);
2907 
2908 	dsm->dropManager.rootX = savX;
2909 	dsm->dropManager.rootY = savY;
2910 
2911 	return(CountDropSites(root));
2912 }
2913 
2914 /*ARGSUSED*/
2915 static XmDSInfo
GetDSFromStream(XmDropSiteManagerObject dsm,XtPointer dataPtr,Boolean * close,unsigned char * type)2916 GetDSFromStream(
2917         XmDropSiteManagerObject dsm,
2918         XtPointer dataPtr,
2919         Boolean *close,
2920         unsigned char *type )
2921 {
2922 	XmDSInfo info;
2923 	XmICCDropSiteInfoStruct iccInfo;
2924 	size_t size;
2925 
2926 	_XmReadDSFromStream(dsm, dataPtr, &iccInfo);
2927 
2928 	switch(iccInfo.header.animationStyle)
2929 	  {
2930 	  case XmDRAG_UNDER_HIGHLIGHT:
2931 	    if (iccInfo.header.dropType & XmDSM_DS_LEAF)
2932 	      size = sizeof(XmDSRemoteHighlightLeafRec);
2933 	    else
2934 	      size = sizeof(XmDSRemoteHighlightNodeRec);
2935 	    break;
2936 	  case XmDRAG_UNDER_SHADOW_IN:
2937 	  case XmDRAG_UNDER_SHADOW_OUT:
2938 	    if (iccInfo.header.dropType & XmDSM_DS_LEAF)
2939 	      size = sizeof(XmDSRemoteShadowLeafRec);
2940 	    else
2941 	      size = sizeof(XmDSRemoteShadowNodeRec);
2942 	    break;
2943 	  case XmDRAG_UNDER_PIXMAP:
2944 	    if (iccInfo.header.dropType & XmDSM_DS_LEAF)
2945 	      size = sizeof(XmDSRemotePixmapLeafRec);
2946 	    else
2947 	      size = sizeof(XmDSRemotePixmapNodeRec);
2948 	    break;
2949 	  case XmDRAG_UNDER_NONE:
2950 	    if (iccInfo.header.dropType & XmDSM_DS_LEAF)
2951 	      size = sizeof(XmDSRemoteNoneLeafRec);
2952 	    else
2953 	      size = sizeof(XmDSRemoteNoneNodeRec);
2954 	    break;
2955 	  default:
2956 	    if (iccInfo.header.dropType & XmDSM_DS_LEAF)
2957 	      size = sizeof(XmDSRemoteNoneLeafRec);
2958 	    else
2959 	      size = sizeof(XmDSRemoteNoneNodeRec);
2960 	    break;
2961 	  }
2962 
2963 	info = (XmDSInfo) XtCalloc(1, size);
2964 
2965 	/* Load the Status fields */
2966 
2967 	SetDSRemote(info, True);
2968 
2969 	if (iccInfo.header.dropType & XmDSM_DS_LEAF)
2970 	{
2971 		SetDSLeaf(info, True);
2972 		SetDSType(info, XmDROP_SITE_SIMPLE);
2973 	}
2974 	else
2975 	{
2976 		SetDSLeaf(info, False);
2977 		SetDSType(info, XmDROP_SITE_COMPOSITE);
2978 	}
2979 
2980 	SetDSAnimationStyle(info, iccInfo.header.animationStyle);
2981 
2982 	if (iccInfo.header.dropType & XmDSM_DS_INTERNAL)
2983 		SetDSInternal(info, True);
2984 	else
2985 		SetDSInternal(info, False);
2986 
2987 	if (iccInfo.header.dropType & XmDSM_DS_HAS_REGION)
2988 		SetDSHasRegion(info, True);
2989 	else
2990 		SetDSHasRegion(info, False);
2991 
2992 	SetDSActivity(info, iccInfo.header.dropActivity);
2993 	SetDSImportTargetsID(info, iccInfo.header.importTargetsID);
2994 	SetDSOperations(info, iccInfo.header.operations);
2995 	SetDSRegion(info, iccInfo.header.region);
2996 
2997 	/* Load the animation data */
2998 	switch(GetDSAnimationStyle(info))
2999 	{
3000 		case XmDRAG_UNDER_HIGHLIGHT:
3001 		{
3002 			XmDSRemoteHighlightStyle hs =
3003 				(XmDSRemoteHighlightStyle)
3004 					GetDSRemoteAnimationPart(info);
3005 			XmICCDropSiteHighlight hi =
3006 				(XmICCDropSiteHighlight) (&iccInfo);
3007 
3008 			hs->highlight_color = hi->animation_data.highlightColor;
3009 			hs->highlight_pixmap =
3010 				hi->animation_data.highlightPixmap;
3011 			hs->background = hi->animation_data.background;
3012 			hs->highlight_thickness =
3013 				hi->animation_data.highlightThickness;
3014 			hs->border_width =
3015 				hi->animation_data.borderWidth;
3016 		}
3017 		break;
3018 		case XmDRAG_UNDER_SHADOW_IN:
3019 		case XmDRAG_UNDER_SHADOW_OUT:
3020 		{
3021 			XmDSRemoteShadowStyle ss =
3022 				(XmDSRemoteShadowStyle) GetDSRemoteAnimationPart(info);
3023 			XmICCDropSiteShadow si =
3024 				(XmICCDropSiteShadow) (&iccInfo);
3025 
3026 			ss->top_shadow_color =
3027 				si->animation_data.topShadowColor;
3028 			ss->top_shadow_pixmap =
3029 				si->animation_data.topShadowPixmap;
3030 			ss->bottom_shadow_color =
3031 				si->animation_data.bottomShadowColor;
3032 			ss->bottom_shadow_pixmap =
3033 				si->animation_data.bottomShadowPixmap;
3034 			ss->foreground = si->animation_data.foreground;
3035 			ss->shadow_thickness =
3036 				si->animation_data.shadowThickness;
3037 			ss->highlight_thickness =
3038 				si->animation_data.highlightThickness;
3039 			ss->border_width = si->animation_data.borderWidth;
3040 		}
3041 		break;
3042 		case XmDRAG_UNDER_PIXMAP:
3043 		{
3044 			XmDSRemotePixmapStyle ps =
3045 				(XmDSRemotePixmapStyle) GetDSRemoteAnimationPart(info);
3046 			XmICCDropSitePixmap pi =
3047 				(XmICCDropSitePixmap) (&iccInfo);
3048 
3049 			ps->animation_pixmap =
3050 				pi->animation_data.animationPixmap;
3051 			ps->animation_pixmap_depth =
3052 				pi->animation_data.animationPixmapDepth;
3053 			ps->animation_mask = pi->animation_data.animationMask;
3054 			ps->background = pi->animation_data.background;
3055 			ps->foreground = pi->animation_data.foreground;
3056 			ps->shadow_thickness =
3057 				pi->animation_data.shadowThickness;
3058 			ps->highlight_thickness =
3059 				pi->animation_data.highlightThickness;
3060 			ps->border_width = pi->animation_data.borderWidth;
3061 		}
3062 		break;
3063 		case XmDRAG_UNDER_NONE:
3064 		{
3065 			XmDSRemoteNoneStyle ns =
3066 				(XmDSRemoteNoneStyle) GetDSRemoteAnimationPart(info);
3067 			XmICCDropSiteNone ni =
3068 				(XmICCDropSiteNone) (&iccInfo);
3069 
3070 			ns->border_width = ni->animation_data.borderWidth;
3071 		}
3072 		break;
3073 		default:
3074 		break;
3075 	}
3076 
3077 	*close = (iccInfo.header.traversalType & XmDSM_T_CLOSE);
3078 	*type = iccInfo.header.dropType;
3079 	return(info);
3080 }
3081 
3082 /*ARGSUSED*/
3083 static void
GetNextDS(XmDropSiteManagerObject dsm,XmDSInfo parentInfo,XtPointer dataPtr)3084 GetNextDS(
3085         XmDropSiteManagerObject dsm,
3086         XmDSInfo parentInfo,
3087         XtPointer dataPtr )
3088 {
3089 	Boolean close = TRUE;
3090 	unsigned char type;
3091 	XmDSInfo new_w = GetDSFromStream(dsm, dataPtr, &close, &type);
3092 
3093 	while (!close)
3094 	{
3095 		AddDSChild(parentInfo, new_w, GetDSNumChildren(parentInfo));
3096 		if (! (type & XmDSM_DS_LEAF))
3097 			GetNextDS(dsm, new_w, dataPtr);
3098 		new_w = GetDSFromStream(dsm, dataPtr, &close, &type);
3099 	}
3100 
3101 	AddDSChild(parentInfo, new_w, GetDSNumChildren(parentInfo));
3102 	if (! (type & XmDSM_DS_LEAF))
3103 		GetNextDS(dsm, new_w, dataPtr);
3104 }
3105 
3106 
3107 
3108 /*ARGSUSED*/
3109 static XmDSInfo
ReadTree(XmDropSiteManagerObject dsm,XtPointer dataPtr)3110 ReadTree(
3111         XmDropSiteManagerObject dsm,
3112         XtPointer dataPtr )
3113 {
3114 	Boolean junkb;
3115 	unsigned char junkc;
3116 
3117 	XmDSInfo root = GetDSFromStream(dsm, dataPtr, &junkb, &junkc);
3118 	SetDSShell(root, True);
3119 	GetNextDS(dsm, root, dataPtr);
3120 	return root;
3121 }
3122 
3123 
3124 /*ARGSUSED*/
3125 static void
FreeDSTree(XmDSInfo tree)3126 FreeDSTree(
3127         XmDSInfo tree )
3128 {
3129 	int i;
3130 	XmDSInfo child;
3131 
3132 	if (!GetDSLeaf(tree))
3133 		for (i = 0; i < (int)GetDSNumChildren(tree); i++)
3134 		{
3135 			child = (XmDSInfo) GetDSChild(tree, i);
3136 			FreeDSTree(child);
3137 		}
3138 	DestroyDSInfo(tree, True);
3139 }
3140 
3141 static void
ChangeRoot(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)3142 ChangeRoot(
3143         XmDropSiteManagerObject dsm,
3144         XtPointer clientData,
3145         XtPointer callData )
3146 {
3147 	XmDragTopLevelClientData cd =
3148 		(XmDragTopLevelClientData) clientData;
3149 	XmTopLevelEnterCallback callback =
3150 		(XmTopLevelEnterCallback) callData;
3151 	Widget		newRoot = cd->destShell;
3152 	XtPointer	dataPtr = cd->iccInfo;
3153 
3154 	dsm->dropManager.curTime = callback->timeStamp;
3155 
3156 	if (callback->reason == XmCR_TOP_LEVEL_ENTER)
3157 	{
3158 		/*
3159 		 * We assume that the drag context will not change without
3160 		 * a call to change the root.
3161 		 */
3162 		dsm->dropManager.curDragContext = (Widget) XmGetDragContext(
3163 			(Widget)dsm, callback->timeStamp);
3164 
3165 		if (newRoot)
3166 		{
3167 			dsm->dropManager.dsRoot = DSMWidgetToInfo(dsm, newRoot);
3168 			/*
3169 			 * Do we need to do anything for prereg emulation of dyn?
3170 			 */
3171 		}
3172 		else
3173 		{
3174 			dsm->dropManager.dsRoot =
3175 				(XtPointer) ReadTree(dsm, dataPtr);
3176 		}
3177 
3178 		dsm->dropManager.rootX = cd->xOrigin;
3179 		dsm->dropManager.rootY = cd->yOrigin;
3180 		dsm->dropManager.rootW = cd->width;
3181 		dsm->dropManager.rootH = cd->height;
3182 	}
3183 	else if (dsm->dropManager.dsRoot)/* XmCR_TOP_LEVEL_LEAVE */
3184 	{
3185 		if (dsm->dropManager.curInfo != NULL)
3186 		{
3187 			XmDragMotionCallbackStruct cbRec ;
3188 			XmDragMotionClientDataStruct cdRec ;
3189 			unsigned char style = _XmGetActiveProtocolStyle(
3190 				dsm->dropManager.curDragContext);
3191 
3192 			/* Fake out a motion message from the DragC */
3193 			cbRec.reason = XmCR_DROP_SITE_LEAVE;
3194 			cbRec.event = callback->event;
3195 			cbRec.timeStamp = callback->timeStamp;
3196 			cbRec.x = dsm->dropManager.curX;
3197 			cbRec.y = dsm->dropManager.curY;
3198 
3199 			/* These fields are irrelevant on a leave */
3200 			cbRec.operations = cbRec.operation = 0;
3201 			cbRec.dropSiteStatus = 0;
3202 
3203 			/* Need these too */
3204 			cdRec.window = cd->window;
3205 			cdRec.dragOver = cd->dragOver;
3206 
3207 			HandleLeave(dsm, &cdRec, &cbRec,
3208 				    (XmDSInfo) dsm->dropManager.curInfo,
3209 				    style, False);
3210 
3211 			dsm->dropManager.curInfo = NULL;
3212 		}
3213 
3214 		if (GetDSRemote((XmDSInfo)(dsm->dropManager.dsRoot)))
3215 			FreeDSTree((XmDSInfo)dsm->dropManager.dsRoot);
3216 
3217 		/* Invalidate the root--force errors to show themselves */
3218 		dsm->dropManager.curDragContext = NULL;
3219 		dsm->dropManager.dsRoot = (XtPointer) NULL;
3220 		dsm->dropManager.rootX = (Position) -1;
3221 		dsm->dropManager.rootY = (Position) -1;
3222 		dsm->dropManager.rootW = 0;
3223 		dsm->dropManager.rootH = 0;
3224 	}
3225 }
3226 
3227 static int
CountDropSites(XmDSInfo info)3228 CountDropSites(
3229         XmDSInfo info )
3230 {
3231 	int i;
3232 	XmDSInfo child;
3233 	int acc = 1;
3234 
3235 	if (!GetDSLeaf(info))
3236 	{
3237 		for (i = 0; i < (int)GetDSNumChildren(info); i++)
3238 		{
3239 			child = (XmDSInfo) GetDSChild(info, i);
3240 			acc += CountDropSites(child);
3241 		}
3242 	}
3243 
3244 	return(acc);
3245 }
3246 
3247 /* This short resource list is used to initialize just the
3248    activity member. */
3249 static XtResource mini_resources[] = {
3250 	{   XmNdropSiteActivity, XmCDropSiteActivity, XmRDropSiteActivity,
3251 		sizeof(unsigned char),
3252 		XtOffsetOf( struct _XmDSFullInfoRec, activity),
3253 		XmRImmediate, (XtPointer) XmDROP_SITE_ACTIVE
3254 	},
3255 };
3256 
3257 static void
CreateInfo(XmDropSiteManagerObject dsm,Widget widget,ArgList args,Cardinal argCount)3258 CreateInfo(
3259         XmDropSiteManagerObject dsm,
3260         Widget widget,
3261         ArgList args,
3262         Cardinal argCount )
3263 {
3264 	XmDSFullInfoRec fullInfoRec;
3265 	XmDSInfo new_info, prev_info;
3266 	XmRegion region = _XmRegionCreate();
3267 	Widget shell = widget;
3268 	size_t size;
3269 
3270 	/* zero out the working info struct */
3271 	bzero((void *)(&fullInfoRec), sizeof(fullInfoRec));
3272 
3273 	/* Load that puppy */
3274 	SetDSLeaf(&fullInfoRec, True);
3275 	fullInfoRec.widget = widget;
3276 	XtGetSubresources(widget, &fullInfoRec, NULL, NULL, _XmDSResources,
3277 			  _XmNumDSResources, args, argCount);
3278 
3279 	/* Handle ignore first. */
3280 	if (fullInfoRec.activity == XmDROP_SITE_IGNORE) {
3281 	  return;
3282 	}
3283 
3284 	DSMStartUpdate(dsm, widget);
3285 
3286 	/* Do some input validation */
3287 
3288 	if ((fullInfoRec.activity == XmDROP_SITE_ACTIVE) &&
3289 		(fullInfoRec.drop_proc == NULL))
3290 	{
3291 		XmeWarning(widget, MESSAGE4);
3292 	}
3293 
3294 	if ((fullInfoRec.animation_style == XmDRAG_UNDER_PIXMAP) &&
3295 		(fullInfoRec.animation_pixmap != XmUNSPECIFIED_PIXMAP) &&
3296 		(fullInfoRec.animation_pixmap_depth == 0))
3297 	{
3298 	    /*
3299 	     * They didn't tell us the depth of the pixmaps.  ask for it. */
3300 	    XmeGetPixmapData(XtScreen(widget), fullInfoRec.animation_pixmap,
3301 			     NULL,
3302 			     (int*)&(fullInfoRec.animation_pixmap_depth),
3303 			     NULL, NULL, NULL, NULL, NULL, NULL);
3304 	}
3305 
3306 	if ((fullInfoRec.type == XmDROP_SITE_COMPOSITE) &&
3307 		((fullInfoRec.rectangles != NULL) ||
3308 		(fullInfoRec.num_rectangles != 1)))
3309 	{
3310 		XmeWarning(widget, MESSAGE5);
3311 		fullInfoRec.rectangles = NULL;
3312 		fullInfoRec.num_rectangles = 1;
3313 	}
3314 
3315 	/* Handle the region*/
3316 	if (fullInfoRec.rectangles == NULL)
3317 	{
3318 		XRectangle rect;
3319 		Dimension bw = XtBorderWidth(widget);
3320 
3321 		rect.x = rect.y = -bw;
3322 		rect.width = XtWidth(widget) + (2 * bw);
3323 		rect.height = XtHeight(widget) + (2 * bw);
3324 
3325 		_XmRegionUnionRectWithRegion(&rect, region, region);
3326 
3327 		fullInfoRec.region = region;
3328 
3329 		/*
3330 		 * Leave HasRegion == 0 indicating that we created this
3331 		 * region for the drop site.
3332 		 */
3333 	}
3334 	else
3335 	{
3336 		int i;
3337 		XRectangle *rects = fullInfoRec.rectangles;
3338 
3339 		for (i=0; i < fullInfoRec.num_rectangles; i++)
3340 			_XmRegionUnionRectWithRegion(&(rects[i]), region, region);
3341 
3342 		fullInfoRec.region = region;
3343 		fullInfoRec.status.has_region = True;
3344 	}
3345 
3346 	XtAddCallback(widget, XmNdestroyCallback, DestroyCallback, dsm);
3347 
3348 	while(!XtIsShell(shell))
3349 		shell = XtParent(shell);
3350 
3351 	fullInfoRec.import_targets_ID = _XmTargetsToIndex(shell,
3352 		fullInfoRec.import_targets, fullInfoRec.num_import_targets);
3353 
3354 	switch(fullInfoRec.animation_style)
3355 	{
3356 		case XmDRAG_UNDER_PIXMAP:
3357 			if (fullInfoRec.type == XmDROP_SITE_COMPOSITE)
3358 			  size = sizeof(XmDSLocalPixmapNodeRec);
3359 			else
3360 			  size = sizeof(XmDSLocalPixmapLeafRec);
3361 		break;
3362 		case XmDRAG_UNDER_HIGHLIGHT:
3363 		case XmDRAG_UNDER_SHADOW_IN:
3364 		case XmDRAG_UNDER_SHADOW_OUT:
3365 		case XmDRAG_UNDER_NONE:
3366 		default:
3367 			if (fullInfoRec.type == XmDROP_SITE_COMPOSITE)
3368 			  size = sizeof(XmDSLocalNoneNodeRec);
3369 			else
3370 			  size = sizeof(XmDSLocalNoneLeafRec);
3371 		break;
3372 	}
3373 
3374 	new_info = (XmDSInfo) XtCalloc(1, size);
3375 
3376 	CopyFullIntoVariant(&fullInfoRec, new_info);
3377 
3378 	if ((prev_info = (XmDSInfo) DSMWidgetToInfo(dsm, widget)) == NULL)
3379 	{
3380 		DSMRegisterInfo(dsm, widget, (XtPointer) new_info);
3381 	}
3382 	else
3383 	{
3384 		if (GetDSInternal(prev_info))
3385 		{
3386 		  /*
3387 		   * They are registering a widget for which we already had
3388 		   * to register internally.  The only types of widgets which
3389 		   * we register internally are of type
3390 		   * XmDROP_SITE_COMPOSITE with children!  This means that
3391 		   * they are trying to create their drop sites out of order
3392 		   * (parents must be registered before their children).
3393 		   */
3394 		  XmeWarning(widget, MESSAGE6);
3395 		}
3396 		else
3397 		{
3398 		  XmeWarning(widget, MESSAGE7);
3399 		}
3400 
3401 		DestroyDSInfo(new_info, True);
3402 		return;
3403 	}
3404 
3405 	DSMInsertInfo(dsm, (XtPointer) new_info, NULL);
3406 
3407 	DSMEndUpdate(dsm, widget);
3408 }
3409 
3410 
3411 /*ARGSUSED*/
3412 static void
CopyVariantIntoFull(XmDropSiteManagerObject dsm,XmDSInfo variant,XmDSFullInfo full_info)3413 CopyVariantIntoFull(
3414         XmDropSiteManagerObject dsm,
3415         XmDSInfo variant,
3416         XmDSFullInfo full_info )
3417 {
3418 	Widget shell;
3419 	Atom *targets;
3420 	Cardinal num_targets;
3421 	long num_rects;
3422 	XRectangle *rects;
3423 int index;
3424 
3425 	if (GetDSRemote(variant))
3426 		shell = XtParent(dsm);
3427 	else
3428 		shell = GetDSWidget(variant);
3429 
3430 	while (!XtIsShell(shell))
3431 		shell = XtParent(shell);
3432 
3433 	/*
3434 	 * Clear the full info back to the default (kind of) state.
3435 	 */
3436 	bzero((void *)(full_info), sizeof(XmDSFullInfoRec));
3437 	full_info->animation_pixmap = XmUNSPECIFIED_PIXMAP;
3438 	full_info->animation_mask = XmUNSPECIFIED_PIXMAP;
3439 
3440 	/* Structure copy the status stuff across */
3441 	full_info->status = variant->status;
3442 
3443 	full_info->parent = GetDSParent(variant);
3444 	full_info->import_targets_ID = GetDSImportTargetsID(variant);
3445 	full_info->operations = GetDSOperations(variant);
3446 	full_info->region = GetDSRegion(variant);
3447 	full_info->drag_proc = GetDSDragProc(variant);
3448 	full_info->drop_proc = GetDSDropProc(variant);
3449  	full_info->client_data = GetDSClientData(variant);
3450 
3451 	full_info->widget = GetDSWidget(variant);
3452 
3453 	full_info->type = GetDSType(variant);
3454 	full_info->animation_style = GetDSAnimationStyle(variant);
3455 	full_info->activity = GetDSActivity(variant);
3456 	index = GetDSImportTargetsID(variant);
3457 	if (index)
3458 	{
3459 		num_targets = _XmIndexToTargets(shell,
3460 			index, &targets);
3461 		full_info->num_import_targets = num_targets;
3462 		full_info->import_targets = targets;
3463 	}
3464 	else
3465 	{
3466 		full_info->num_import_targets = 0;
3467 		full_info->import_targets = NULL;
3468 	}
3469 
3470 
3471 	_XmRegionGetRectangles(GetDSRegion(variant), &rects, &num_rects);
3472 	full_info->rectangles = rects;
3473 	full_info->num_rectangles = (Cardinal) num_rects;
3474 
3475 	if (GetDSRemote(variant))
3476 	{
3477 		switch(GetDSAnimationStyle(variant))
3478 		{
3479 			case XmDRAG_UNDER_HIGHLIGHT:
3480 			{
3481 				XmDSRemoteHighlightStyle hs =
3482 					(XmDSRemoteHighlightStyle)
3483 						GetDSRemoteAnimationPart(variant);
3484 
3485 				full_info->highlight_color = hs->highlight_color;
3486 				full_info->highlight_pixmap = hs->highlight_pixmap;
3487 				full_info->background = hs->background;
3488 				full_info->highlight_thickness =
3489 					hs->highlight_thickness;
3490 				full_info->border_width = hs->border_width;
3491 			}
3492 			break;
3493 			case XmDRAG_UNDER_SHADOW_IN:
3494 			case XmDRAG_UNDER_SHADOW_OUT:
3495 			{
3496 				XmDSRemoteShadowStyle ss =
3497 					(XmDSRemoteShadowStyle)
3498 						GetDSRemoteAnimationPart(variant);
3499 
3500 				full_info->top_shadow_color = ss->top_shadow_color;
3501 				full_info->top_shadow_pixmap = ss->top_shadow_pixmap;
3502 				full_info->bottom_shadow_color =
3503 					ss->bottom_shadow_color;
3504 				full_info->bottom_shadow_pixmap =
3505 					ss->bottom_shadow_pixmap;
3506 				full_info->foreground = ss->foreground;
3507 				full_info->shadow_thickness = ss->shadow_thickness;
3508 				full_info->highlight_thickness = ss->highlight_thickness;
3509 				full_info->border_width = ss->border_width;
3510 			}
3511 			break;
3512 			case XmDRAG_UNDER_PIXMAP:
3513 			{
3514 				XmDSRemotePixmapStyle ps =
3515 					(XmDSRemotePixmapStyle)
3516 						GetDSRemoteAnimationPart(variant);
3517 
3518 				full_info->animation_pixmap = ps->animation_pixmap;
3519 				full_info->animation_pixmap_depth =
3520 					ps->animation_pixmap_depth;
3521 				full_info->animation_mask = ps->animation_mask;
3522 				full_info->background = ps->background;
3523 				full_info->foreground = ps->foreground;
3524 				full_info->shadow_thickness = ps->shadow_thickness;
3525 				full_info->highlight_thickness =
3526 					ps->highlight_thickness;
3527 				full_info->border_width = ps->border_width;
3528 			}
3529 			break;
3530 			case XmDRAG_UNDER_NONE:
3531 			default:
3532 			break;
3533 		}
3534 	}
3535 	else
3536 	{
3537 		switch(GetDSAnimationStyle(variant))
3538 		{
3539 			case XmDRAG_UNDER_HIGHLIGHT:
3540 			break;
3541 			case XmDRAG_UNDER_SHADOW_IN:
3542 			case XmDRAG_UNDER_SHADOW_OUT:
3543 			break;
3544 			case XmDRAG_UNDER_PIXMAP:
3545 			{
3546 				XmDSLocalPixmapStyle ps =
3547 					(XmDSLocalPixmapStyle)
3548 						GetDSLocalAnimationPart(variant);
3549 
3550 				full_info->animation_pixmap = ps->animation_pixmap;
3551 				full_info->animation_pixmap_depth =
3552 					ps->animation_pixmap_depth;
3553 				full_info->animation_mask = ps->animation_mask;
3554 			}
3555 			break;
3556 			case XmDRAG_UNDER_NONE:
3557 			default:
3558 			break;
3559 		}
3560 	}
3561 }
3562 
3563 
3564 /*ARGSUSED*/
3565 static void
RetrieveInfo(XmDropSiteManagerObject dsm,Widget widget,ArgList args,Cardinal argCount)3566 RetrieveInfo(
3567         XmDropSiteManagerObject dsm,
3568         Widget widget,
3569         ArgList args,
3570         Cardinal argCount )
3571 {
3572 	XmDSFullInfoRec full_info_rec;
3573 	XmDSInfo	info;
3574 #ifdef FIX_1212
3575 	int i;
3576 	Boolean freeRects;
3577 #else
3578 	XRectangle	*rects;
3579 #endif
3580 
3581 	if (XmIsDragContext(widget))
3582 	{
3583 		if (widget != dsm->dropManager.curDragContext)
3584 			return;
3585 		else
3586 			info = (XmDSInfo) (dsm->dropManager.curInfo);
3587 	}
3588 	else
3589 		info = (XmDSInfo) DSMWidgetToInfo(dsm, widget);
3590 
3591 	if (info == NULL)
3592 		return;
3593 
3594 	CopyVariantIntoFull(dsm, info, &full_info_rec);
3595 
3596 	XtGetSubvalues((XtPointer)(&full_info_rec),
3597 	      (XtResourceList)(_XmDSResources), (Cardinal)(_XmNumDSResources),
3598 	      (ArgList)(args), (Cardinal)(argCount));
3599 #ifdef FIX_1212
3600 	freeRects = True;
3601 	for (i = 0 ; i < argCount; i++) {
3602 	    if (strcmp(args[i].name, "dropRectangles") == 0)
3603 		freeRects = False;
3604 	}
3605 	if (freeRects && full_info_rec.rectangles)
3606 	    XtFree((char *) full_info_rec.rectangles);
3607 #else
3608 	rects = full_info_rec.rectangles;
3609 
3610 	if (rects)
3611 		XtFree((char *) rects);
3612 #endif
3613 }
3614 
3615 /*ARGSUSED*/
3616 static void
CopyFullIntoVariant(XmDSFullInfo full_info,XmDSInfo variant)3617 CopyFullIntoVariant(
3618         XmDSFullInfo full_info,
3619         XmDSInfo variant )
3620 {
3621 	/*
3622 	 * This procedure assumes that variant is a variant of Local,
3623 	 * there should be no calls to this procedure with variant of
3624 	 * remote.
3625 	 */
3626 	if (GetDSRemote(full_info))
3627 		return;
3628 
3629 	/* Magic internal fields */
3630 	SetDSRemote(variant, GetDSRemote(full_info));
3631 	SetDSLeaf(variant, GetDSLeaf(full_info));
3632 	SetDSShell(variant, GetDSShell(full_info));
3633 	SetDSHasRegion(variant, full_info->status.has_region);
3634 
3635 	/* Externally visible fields */
3636 	SetDSAnimationStyle(variant, full_info->animation_style);
3637 	SetDSType(variant, full_info->type);
3638 	SetDSActivity(variant, full_info->activity);
3639 
3640 	SetDSImportTargetsID(variant, full_info->import_targets_ID);
3641 	SetDSOperations(variant, full_info->operations);
3642 	SetDSRegion(variant, full_info->region);
3643 	SetDSDragProc(variant, full_info->drag_proc);
3644 	SetDSDropProc(variant, full_info->drop_proc);
3645  	SetDSClientData(variant, full_info->client_data);
3646 	SetDSWidget(variant, full_info->widget);
3647 
3648 	switch(full_info->animation_style)
3649 	{
3650 		case XmDRAG_UNDER_HIGHLIGHT:
3651 		break;
3652 		case XmDRAG_UNDER_SHADOW_IN:
3653 		case XmDRAG_UNDER_SHADOW_OUT:
3654 		break;
3655 		case XmDRAG_UNDER_PIXMAP:
3656 		{
3657 			XmDSLocalPixmapStyle ps =
3658 				(XmDSLocalPixmapStyle) GetDSLocalAnimationPart(variant);
3659 
3660 			ps->animation_pixmap = full_info->animation_pixmap;
3661 			ps->animation_pixmap_depth =
3662 				full_info->animation_pixmap_depth;
3663 			ps->animation_mask = full_info->animation_mask;
3664 		}
3665 		break;
3666 		case XmDRAG_UNDER_NONE:
3667 		default:
3668 		break;
3669 	}
3670 }
3671 
3672 
3673 /*ARGSUSED*/
3674 static void
UpdateInfo(XmDropSiteManagerObject dsm,Widget widget,ArgList args,Cardinal argCount)3675 UpdateInfo(
3676         XmDropSiteManagerObject dsm,
3677         Widget widget,
3678         ArgList args,
3679         Cardinal argCount )
3680 {
3681 	XmDSFullInfoRec	full_info_rec;
3682 	XmDSFullInfo	full_info = &full_info_rec;
3683 	XmDSInfo	info = (XmDSInfo) DSMWidgetToInfo(dsm, widget);
3684 	unsigned char	type;
3685 	XmRegion	old_region;
3686 	XRectangle	*rects;
3687 	long		num_rects;
3688 
3689 	if ((info == NULL) || GetDSInternal(info))
3690 		return;
3691 
3692         rects = NULL;
3693 
3694 	DSMStartUpdate(dsm, widget);
3695 
3696 	CopyVariantIntoFull(dsm, info, full_info);
3697 
3698 	/* Save the type and region in case they try to cheat */
3699 	type = GetDSType(info);
3700 	old_region = GetDSRegion(info);
3701 
3702 /* BEGIN OSF Fix CR 5335 */
3703 	/*
3704 	 * Set up the rectangle list stuff.
3705 	 */
3706 	rects = full_info->rectangles;
3707 	num_rects = (long) full_info->num_rectangles;
3708 /* END OSF Fix CR 5335 */
3709 
3710 	/* Update the info */
3711         {
3712 	Atom			*old_import_targets;
3713 	Cardinal		old_num_import_targets;
3714 
3715         old_num_import_targets = full_info->num_import_targets;
3716         old_import_targets = full_info->import_targets;
3717 	XtSetSubvalues(full_info, _XmDSResources, _XmNumDSResources,
3718 		args, argCount);
3719         if ( (full_info->num_import_targets != old_num_import_targets) ||
3720 	     (full_info->import_targets != old_import_targets) )
3721 		{
3722 		Widget shell = widget;
3723 		while(!(XtIsShell(shell))) shell = XtParent(shell);
3724 		full_info->import_targets_ID = _XmTargetsToIndex(shell,
3725 			full_info->import_targets, full_info->num_import_targets);
3726 		}
3727         }
3728 
3729 	if (full_info->type != type)
3730 	{
3731 		XmeWarning(widget, MESSAGE8);
3732 		full_info->type = type;
3733 	}
3734 
3735 	if ((full_info->rectangles != rects) ||
3736 		(full_info->num_rectangles != num_rects))
3737 	{
3738 		if (type == XmDROP_SITE_SIMPLE)
3739 		{
3740 			int i;
3741 			XmRegion new_region = _XmRegionCreate();
3742 
3743 			for (i=0; i < full_info->num_rectangles; i++)
3744 				_XmRegionUnionRectWithRegion(
3745 					&(full_info->rectangles[i]), new_region,
3746 					new_region);
3747 
3748 			full_info->region = new_region;
3749 			full_info->status.has_region = True;
3750 			_XmRegionDestroy(old_region);
3751 		}
3752 		else
3753 		{
3754 			XmeWarning(widget, MESSAGE9);
3755 		}
3756 
3757 /* BEGIN OSF Fix CR 5335 */
3758 /* END OSF Fix CR 5335 */
3759 	}
3760 
3761 	if ((full_info->animation_style == XmDRAG_UNDER_PIXMAP) &&
3762 		(full_info->animation_pixmap_depth == 0))
3763 	{
3764 	    Widget widget = GetDSWidget(info);
3765 
3766 	    XmeGetPixmapData(XtScreen(widget), full_info->animation_pixmap,
3767 			     NULL,
3768 			     (int*)&(full_info->animation_pixmap_depth),
3769 			     NULL, NULL, NULL, NULL, NULL, NULL);
3770 	}
3771 
3772 	/*
3773 	 * If the animation style has changed, we need to change info
3774 	 * into a different variant.
3775 	 */
3776 
3777 	if (full_info->animation_style != GetDSAnimationStyle(info))
3778 	{
3779 		XmDSInfo new_info;
3780 		size_t size;
3781 
3782 		switch (full_info->animation_style)
3783 		{
3784 			case XmDRAG_UNDER_PIXMAP:
3785 				if (GetDSType(info) == XmDROP_SITE_COMPOSITE)
3786 				  size = sizeof(XmDSLocalPixmapNodeRec);
3787 				else
3788 				  size = sizeof(XmDSLocalPixmapLeafRec);
3789 			break;
3790 			case XmDRAG_UNDER_HIGHLIGHT:
3791 			case XmDRAG_UNDER_SHADOW_IN:
3792 			case XmDRAG_UNDER_SHADOW_OUT:
3793 			case XmDRAG_UNDER_NONE:
3794 			default:
3795 				if (GetDSType(info) == XmDROP_SITE_COMPOSITE)
3796 				  size = sizeof(XmDSLocalNoneNodeRec);
3797 				else
3798 				  size = sizeof(XmDSLocalNoneLeafRec);
3799 			break;
3800 		}
3801 
3802 		/* Allocate the new info rec */
3803 		new_info = (XmDSInfo) XtCalloc(1, size);
3804 
3805 		CopyFullIntoVariant(full_info, new_info);
3806 
3807 		/*
3808 		 * Fix the parent pointers of the children
3809 		 */
3810 		SetDSNumChildren(new_info, GetDSNumChildren(info));
3811 		SetDSChildren(new_info, GetDSChildren(info));
3812 
3813 		if ((GetDSType(new_info) == XmDROP_SITE_COMPOSITE) &&
3814 			(GetDSNumChildren(new_info)))
3815 		{
3816 			XmDSInfo child;
3817 			int i;
3818 
3819 			for (i=0; i < (int)GetDSNumChildren(new_info); i++)
3820 			{
3821 				child = (XmDSInfo) GetDSChild(new_info, i);
3822 				SetDSParent(child, new_info);
3823 			}
3824 		}
3825 
3826 		/* Clear the registered bit on the new one */
3827 		SetDSRegistered(new_info, False);
3828 
3829 		/* Remove the old one from the hash table */
3830 		DSMUnregisterInfo(dsm, info);
3831 
3832 		/* Replace the old one in the drop site tree */
3833 		ReplaceDSChild(info, new_info);
3834 
3835 		/* Destroy the old one, but not anything it points to */
3836 		DestroyDSInfo(info, False);
3837 
3838 		/* Register the new one */
3839 		DSMRegisterInfo(dsm, widget, (XtPointer) new_info);
3840 	}
3841 	else
3842 	{
3843 		CopyFullIntoVariant(full_info, info);
3844 	}
3845 
3846 	DSMEndUpdate(dsm, widget);
3847 
3848 	if (rects!=NULL) XtFree ((char *)rects);
3849 }
3850 
3851 /*ARGSUSED*/
3852 static void
StartUpdate(XmDropSiteManagerObject dsm,Widget refWidget)3853 StartUpdate(
3854         XmDropSiteManagerObject dsm,
3855         Widget refWidget )
3856 {
3857 	Widget shell = refWidget;
3858 	XmDSInfo shellInfo;
3859 
3860 	while(!(XtIsShell(shell)))
3861 		shell = XtParent(shell);
3862 
3863 	shellInfo = (XmDSInfo) DSMWidgetToInfo(dsm, shell);
3864 
3865 	if (shellInfo)
3866 		SetDSUpdateLevel(shellInfo, (GetDSUpdateLevel(shellInfo) + 1));
3867 }
3868 
3869 /*ARGSUSED*/
3870 static void
EndUpdate(XmDropSiteManagerObject dsm,Widget refWidget)3871 EndUpdate(
3872         XmDropSiteManagerObject dsm,
3873         Widget refWidget )
3874 {
3875   _XmDropSiteUpdateInfo dsupdate, oldupdate;
3876   Boolean found = False;
3877   Boolean clean;
3878   Widget shell;
3879   XmDSInfo shellInfo;
3880 
3881   dsupdate = dsm -> dropManager.updateInfo;
3882   clean = (dsupdate == NULL);
3883 
3884   shell = refWidget;
3885 
3886   while(!(XtIsShell(shell)))
3887     shell = XtParent(shell);
3888 
3889   shellInfo = (XmDSInfo) DSMWidgetToInfo(dsm, shell);
3890 
3891   if (shellInfo == NULL) return;
3892 
3893   if (GetDSUpdateLevel(shellInfo) > 0)
3894     SetDSUpdateLevel(shellInfo, (GetDSUpdateLevel(shellInfo) - 1));
3895 
3896   if (GetDSUpdateLevel(shellInfo) > 0) return;
3897 
3898   /* Fix CR 7976,  losing track of some updates because of bad
3899      list manipulation */
3900   oldupdate = dsupdate;
3901 
3902   /* Really,  keep track of toplevel widgets to be updated */
3903   while(dsupdate) {
3904     if (dsupdate -> refWidget == shell) {
3905       found = True;
3906       break;
3907     }
3908     dsupdate = dsupdate -> next;
3909   }
3910 
3911   if (! found) {
3912     /* Queue real end update to a timeout */
3913     dsupdate = (_XmDropSiteUpdateInfo)
3914       XtMalloc(sizeof(_XmDropSiteUpdateInfoRec));
3915     dsupdate -> dsm = dsm;
3916     dsupdate -> refWidget = shell;
3917     dsupdate -> next = oldupdate;
3918     dsm -> dropManager.updateInfo = dsupdate;
3919   }
3920 
3921   /* We don't add a timeout if the record is already marked for update */
3922   if (clean) {
3923     dsm -> dropManager.updateTimeOutId =
3924       XtAppAddTimeOut(XtWidgetToApplicationContext(shell), 0,
3925 		      _XmIEndUpdate, dsm);
3926   }
3927 }
3928 
3929 /*ARGSUSED*/
3930 void
_XmIEndUpdate(XtPointer client_data,XtIntervalId * interval_id)3931 _XmIEndUpdate(XtPointer client_data, XtIntervalId *interval_id)
3932 {
3933   XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) client_data;
3934   _XmDropSiteUpdateInfo dsupdate;
3935   Widget shell;
3936   XmDSInfo shellInfo;
3937 
3938   /* Remove timeout if this is a forced update */
3939   if (dsm -> dropManager.updateTimeOutId) {
3940     if (interval_id == NULL)
3941       XtRemoveTimeOut(dsm -> dropManager.updateTimeOutId);
3942     dsm -> dropManager.updateTimeOutId = 0;
3943   }
3944 
3945   /* Return if all updates have already happened */
3946   while(dsm -> dropManager.updateInfo != NULL) {
3947     dsupdate = (_XmDropSiteUpdateInfo) dsm -> dropManager.updateInfo;
3948     shell = dsupdate -> refWidget;
3949     dsm -> dropManager.updateInfo = dsupdate -> next;
3950     XtFree((char*) dsupdate);
3951 
3952     while(!(XtIsShell(shell)))
3953       shell = XtParent(shell);
3954 
3955     shellInfo = (XmDSInfo) DSMWidgetToInfo(dsm, shell);
3956 
3957     if (shellInfo && XtIsRealized(shell))
3958       {
3959 	/* This one's for real */
3960 
3961 	if (_XmGetDragProtocolStyle(shell) != XmDRAG_DYNAMIC)
3962 	  {
3963 	    XmDropSiteTreeAddCallbackStruct	outCB;
3964 
3965 	    /* Gotta' update that window property. */
3966 	    outCB.reason = XmCR_DROP_SITE_TREE_ADD;
3967 	    outCB.event = NULL;
3968 	    outCB.rootShell = shell;
3969 	    outCB.numDropSites = CountDropSites(shellInfo);
3970 	    outCB.numArgsPerDSHint = 0;
3971 
3972 	    if (dsm->dropManager.treeUpdateProc)
3973 	      (dsm->dropManager.treeUpdateProc)
3974 		((Widget) dsm, NULL, (XtPointer) &outCB);
3975 	  }
3976 	else
3977 	  {
3978 	    /* We have to Sync the regions with the widgets */
3979 	    SyncTree(dsm, shell);
3980 	  }
3981       }
3982   }
3983 }
3984 
3985 static void
DestroyInfo(XmDropSiteManagerObject dsm,Widget widget)3986 DestroyInfo(
3987         XmDropSiteManagerObject dsm,
3988         Widget widget )
3989 {
3990 	XmDSInfo info = (XmDSInfo) DSMWidgetToInfo(dsm, widget);
3991 
3992 	if (info == NULL)
3993 		return;
3994 
3995 	DSMStartUpdate(dsm, widget);
3996 
3997 	if (info == (XmDSInfo) (dsm->dropManager.curInfo))
3998 	{
3999 		Widget shell;
4000 		XmDragMotionCallbackStruct cbRec ;
4001 		XmDragMotionClientDataStruct cdRec ;
4002 		unsigned char style = _XmGetActiveProtocolStyle(
4003 			dsm->dropManager.curDragContext);
4004 
4005 		/* Fake out a motion message from the DragC */
4006 		cbRec.reason = XmCR_DROP_SITE_LEAVE;
4007 		cbRec.event = NULL;
4008 		cbRec.timeStamp = dsm->dropManager.curTime;
4009 		cbRec.x = dsm->dropManager.curX;
4010 		cbRec.y = dsm->dropManager.curY;
4011 
4012 		/* These fields are irrelevant on a leave */
4013 		cbRec.operations = cbRec.operation = 0;
4014 		cbRec.dropSiteStatus = 0;
4015 
4016 		/* Need these too */
4017 		shell = GetDSWidget(info);
4018 
4019 		while (!XtIsShell(shell))
4020 			shell = XtParent(shell);
4021 
4022 		cdRec.window = XtWindow(shell);
4023 		cdRec.dragOver = (Widget)
4024 			(((XmDragContext)(dsm->dropManager.curDragContext))
4025 				->drag.curDragOver);
4026 
4027 		HandleLeave(dsm, &cdRec, &cbRec,
4028 			    (XmDSInfo) dsm->dropManager.curInfo, style, False);
4029 
4030 		dsm->dropManager.curInfo = NULL;
4031 	}
4032 
4033 	while(info != NULL) {
4034 	  DSMRemoveInfo(dsm, (XtPointer) info);
4035 	  DestroyDSInfo(info, True);
4036 
4037 	  /* This should be NULL now,  otherwise,  keep removing
4038 	     until done */
4039 	  info = (XmDSInfo) DSMWidgetToInfo(dsm, widget);
4040 	}
4041 
4042 	DSMEndUpdate(dsm, widget);
4043 }
4044 
4045 static void
SyncDropSiteGeometry(XmDropSiteManagerObject dsm,XmDSInfo info)4046 SyncDropSiteGeometry(
4047         XmDropSiteManagerObject dsm,
4048         XmDSInfo info )
4049 {
4050 	XmDSInfo child;
4051 
4052 	if (!GetDSLeaf(info))
4053 	{
4054 		int i;
4055 
4056 		for (i = 0; i < (int)GetDSNumChildren(info); i++)
4057 		{
4058 			child = (XmDSInfo) GetDSChild(info, i);
4059 			SyncDropSiteGeometry(dsm, child);
4060 		}
4061 	}
4062 
4063 	if (!GetDSHasRegion(info))
4064 	{
4065 		Widget w = GetDSWidget(info);
4066 		XRectangle rect;
4067 		Dimension bw = XtBorderWidth(w);
4068 
4069 		/* The region is the object rectangle */
4070 
4071 		/* assert(GetDSRegion(info) != NULL)  */
4072 
4073 		/* The region comes from the widget */
4074 
4075 		rect.x = rect.y = -bw;
4076 		rect.width = XtWidth(w) + (2 * bw);
4077 		rect.height = XtHeight(w) + (2 * bw);
4078 
4079 		_XmRegionClear(GetDSRegion(info));
4080 		_XmRegionUnionRectWithRegion(&rect, GetDSRegion(info),
4081 			GetDSRegion(info));
4082 	}
4083 }
4084 
4085 static void
SyncTree(XmDropSiteManagerObject dsm,Widget shell)4086 SyncTree(
4087         XmDropSiteManagerObject dsm,
4088         Widget shell )
4089 {
4090 	XmDSInfo saveRoot;
4091 	XmDSInfo root = (XmDSInfo) DSMWidgetToInfo(dsm, shell);
4092 	Position shellX, shellY, savX, savY;
4093 
4094 	if ((root == NULL) || (GetDSRemote(root)))
4095 		return;
4096 
4097 	/*
4098 	 * Set things up so that the shell coordinates are trivially
4099 	 * available.
4100 	 */
4101 	saveRoot = (XmDSInfo) dsm->dropManager.dsRoot;
4102 	savX = dsm->dropManager.rootX;
4103 	savY = dsm->dropManager.rootY;
4104 
4105 	dsm->dropManager.dsRoot = (XtPointer) root;
4106 	XtTranslateCoords(GetDSWidget(root), 0, 0, &shellX, &shellY);
4107 	dsm->dropManager.rootX = shellX;
4108 	dsm->dropManager.rootY = shellY;
4109 
4110 	/* Do the work */
4111 	RemoveAllClippers(dsm, root);
4112 	SyncDropSiteGeometry(dsm, root);
4113 	DetectAndInsertAllClippers(dsm, root);
4114 
4115 	/* Restore the DSM */
4116 	dsm->dropManager.dsRoot = (XtPointer) saveRoot;
4117 	dsm->dropManager.rootX = savX;
4118 	dsm->dropManager.rootY = savY;
4119 }
4120 
4121 void
_XmSyncDropSiteTree(Widget shell)4122 _XmSyncDropSiteTree(
4123         Widget shell )
4124 {
4125 	XmDropSiteManagerObject dsm = (XmDropSiteManagerObject)
4126 		_XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4127 			XtDisplayOfObject(shell)));
4128 
4129 	DSMSyncTree(dsm, shell);
4130 }
4131 
4132 static void
Update(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)4133 Update(
4134         XmDropSiteManagerObject dsm,
4135         XtPointer clientData,
4136         XtPointer callData )
4137 {
4138 	XmAnyCallbackStruct	*callback = (XmAnyCallbackStruct *)callData;
4139 
4140 	switch(callback->reason)
4141 	{
4142 		case XmCR_TOP_LEVEL_ENTER:
4143 		case XmCR_TOP_LEVEL_LEAVE:
4144 			DSMChangeRoot(dsm, clientData, callData);
4145 		break;
4146 		case XmCR_DRAG_MOTION:
4147 			DSMProcessMotion(dsm, clientData, callData);
4148 		break;
4149 		case XmCR_DROP_START:
4150 			DSMProcessDrop(dsm, clientData, callData);
4151 		break;
4152 		case XmCR_OPERATION_CHANGED:
4153 			DSMOperationChanged(dsm, clientData, callData);
4154 		default:
4155 		break;
4156 	}
4157 }
4158 
4159 void
_XmDSMUpdate(XmDropSiteManagerObject dsm,XtPointer clientData,XtPointer callData)4160 _XmDSMUpdate(
4161         XmDropSiteManagerObject dsm,
4162         XtPointer clientData,
4163         XtPointer callData )
4164 {
4165 	DSMUpdate(dsm, clientData, callData);
4166 }
4167 
4168 
4169 int
_XmDSMGetTreeFromDSM(XmDropSiteManagerObject dsm,Widget shell,XtPointer dataPtr)4170 _XmDSMGetTreeFromDSM(
4171         XmDropSiteManagerObject dsm,
4172         Widget shell,
4173         XtPointer dataPtr )
4174 {
4175 	return(DSMGetTreeFromDSM(dsm, shell, dataPtr));
4176 }
4177 
4178 Boolean
_XmDropSiteShell(Widget widget)4179 _XmDropSiteShell(
4180         Widget widget )
4181 {
4182 	XmDropSiteManagerObject dsm = (XmDropSiteManagerObject)
4183 		_XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4184 			XtDisplayOfObject(widget)));
4185 
4186 	if ((XtIsShell(widget)) && (DSMWidgetToInfo(dsm, widget) != NULL))
4187 		return(True);
4188 	else
4189 		return(False);
4190 }
4191 
4192 static Boolean
HasDropSiteDescendant(XmDropSiteManagerObject dsm,Widget widget)4193 HasDropSiteDescendant(
4194 	XmDropSiteManagerObject dsm,
4195 	Widget widget )
4196 {
4197 	CompositeWidget cw;
4198 	int i;
4199 	Widget child;
4200 
4201 	if (!XtIsComposite(widget))
4202 		return(False);
4203 
4204 	cw = (CompositeWidget) widget;
4205 	for (i = 0; i < cw->composite.num_children; i++)
4206 	{
4207 		child = cw->composite.children[i];
4208 		if ((DSMWidgetToInfo(dsm, child) != NULL) ||
4209 			(HasDropSiteDescendant(dsm, child)))
4210 		{
4211 			return(True);
4212 		}
4213 	}
4214 
4215 	return(False);
4216 }
4217 
4218 Boolean
_XmDropSiteWrapperCandidate(Widget widget)4219 _XmDropSiteWrapperCandidate(
4220         Widget widget )
4221 {
4222 	XmDropSiteManagerObject dsm = (XmDropSiteManagerObject)
4223 		_XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4224 			XtDisplayOfObject(widget)));
4225 	Widget shell;
4226 
4227 	if (widget == NULL)
4228 		return(False);
4229 
4230 	if (DSMWidgetToInfo(dsm, widget) != NULL)
4231 		return(True);
4232 	else if (!XtIsComposite(widget))
4233 		return(False);
4234 
4235 	/*
4236 	 * Make sure that there might be a drop site somewhere in
4237 	 * this shell before traversing the descendants.
4238 	 */
4239 	shell = widget;
4240 	while (!XtIsShell(shell))
4241 		shell = XtParent(shell);
4242 
4243 	if (!_XmDropSiteShell(shell))
4244 		return(False);
4245 
4246 	return(HasDropSiteDescendant(dsm, widget));
4247 }
4248 
4249 /*ARGSUSED*/
4250 static void
DestroyCallback(Widget widget,XtPointer client_data,XtPointer call_data)4251 DestroyCallback(
4252         Widget widget,
4253         XtPointer client_data,
4254         XtPointer call_data )
4255 {
4256 	XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) client_data;
4257 
4258 	DSMDestroyInfo(dsm, widget);
4259 
4260 	/* Force Update */
4261 	_XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL);
4262 }
4263 
4264 Boolean
XmDropSiteRegistered(Widget widget)4265 XmDropSiteRegistered(
4266         Widget widget )
4267 {
4268     XmDropSiteManagerObject dsm;
4269     XtPointer info;
4270     _XmWidgetToAppContext(widget);
4271 
4272     _XmAppLock(app);
4273     dsm = (XmDropSiteManagerObject)
4274 	   _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4275 	                         XtDisplayOfObject(widget)));
4276     info = DSMWidgetToInfo(dsm, widget);
4277 
4278     if ((info == NULL)) {
4279 	_XmAppUnlock(app);
4280 	return False;
4281     }
4282 
4283     _XmAppUnlock(app);
4284     return True;
4285 }
4286 
4287 
4288 void
XmDropSiteRegister(Widget widget,ArgList args,Cardinal argCount)4289 XmDropSiteRegister(
4290         Widget widget,
4291         ArgList args,
4292         Cardinal argCount )
4293 {
4294   XmDropSiteManagerObject dsm;
4295   _XmWidgetToAppContext(widget);
4296 
4297   _XmAppLock(app);
4298   dsm = (XmDropSiteManagerObject)
4299     _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4300 	     XtDisplayOfObject(widget)));
4301   if (XtIsShell(widget)) {
4302     XmeWarning(widget, MESSAGE10);
4303   } else
4304     DSMCreateInfo(dsm, widget, args, argCount);
4305   _XmAppUnlock(app);
4306 }
4307 
4308 void
XmDropSiteUnregister(Widget widget)4309 XmDropSiteUnregister(
4310         Widget widget )
4311 {
4312 	XmDropSiteManagerObject dsm;
4313 	_XmWidgetToAppContext(widget);
4314 
4315 	_XmAppLock(app);
4316 	dsm = (XmDropSiteManagerObject)
4317 	    _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4318 			XtDisplayOfObject(widget)));
4319 	DSMDestroyInfo(dsm, widget);
4320 
4321 	/* Force Update */
4322 	_XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL);
4323 	_XmAppUnlock(app);
4324 }
4325 
4326 void
XmDropSiteStartUpdate(Widget refWidget)4327 XmDropSiteStartUpdate(
4328         Widget refWidget )
4329 {
4330 	XmDropSiteManagerObject dsm;
4331 	_XmWidgetToAppContext(refWidget);
4332 
4333 	_XmAppLock(app);
4334 	dsm = (XmDropSiteManagerObject)
4335 	    _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4336 			XtDisplayOfObject(refWidget)));
4337 	DSMStartUpdate(dsm, refWidget);
4338 	_XmAppUnlock(app);
4339 }
4340 
4341 void
XmDropSiteUpdate(Widget enclosingWidget,ArgList args,Cardinal argCount)4342 XmDropSiteUpdate(
4343         Widget enclosingWidget,
4344         ArgList args,
4345         Cardinal argCount )
4346 {
4347 	XmDropSiteManagerObject dsm;
4348 	_XmWidgetToAppContext(enclosingWidget);
4349 
4350 	_XmAppLock(app);
4351 	dsm = (XmDropSiteManagerObject)
4352 	    _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4353 			XtDisplayOfObject(enclosingWidget)));
4354 	DSMUpdateInfo(dsm, enclosingWidget, args, argCount);
4355 	_XmAppUnlock(app);
4356 }
4357 
4358 void
XmDropSiteEndUpdate(Widget refWidget)4359 XmDropSiteEndUpdate(
4360         Widget refWidget )
4361 {
4362 	XmDropSiteManagerObject dsm;
4363 	_XmWidgetToAppContext(refWidget);
4364 
4365 	_XmAppLock(app);
4366 	dsm = (XmDropSiteManagerObject)
4367 	    _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4368 			XtDisplayOfObject(refWidget)));
4369 
4370 	DSMEndUpdate(dsm, refWidget);
4371 	_XmAppUnlock(app);
4372 }
4373 
4374 void
XmDropSiteRetrieve(Widget enclosingWidget,ArgList args,Cardinal argCount)4375 XmDropSiteRetrieve(
4376         Widget enclosingWidget,
4377         ArgList args,
4378         Cardinal argCount )
4379 {
4380 	XmDropSiteManagerObject dsm;
4381 	_XmWidgetToAppContext(enclosingWidget);
4382 
4383 	_XmAppLock(app);
4384 	dsm = (XmDropSiteManagerObject)
4385 	    _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4386 			XtDisplayOfObject(enclosingWidget)));
4387 
4388 	/* Update if dsm is dirty */
4389 	_XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL);
4390 
4391 	DSMRetrieveInfo(dsm, enclosingWidget, args, argCount);
4392 	_XmAppUnlock(app);
4393 }
4394 
4395 Status
XmDropSiteQueryStackingOrder(Widget widget,Widget * parent_rtn,Widget ** children_rtn,Cardinal * num_children_rtn)4396 XmDropSiteQueryStackingOrder(
4397         Widget widget,
4398         Widget *parent_rtn,
4399         Widget **children_rtn,
4400         Cardinal *num_children_rtn )
4401 {
4402 	XmDropSiteManagerObject dsm;
4403 	XmDSInfo info;
4404 	XmDSInfo parentInfo;
4405 	Cardinal num_visible_children = 0; /* visible to application code */
4406 	int i,j;
4407 	_XmWidgetToAppContext(widget);
4408 
4409 	_XmAppLock(app);
4410 	dsm = (XmDropSiteManagerObject)
4411 	    _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4412 			XtDisplayOfObject(widget)));
4413 	info = (XmDSInfo) DSMWidgetToInfo(dsm, widget);
4414 
4415 	/* Update if dsm is dirty */
4416 	_XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL);
4417 
4418 	if (info == NULL) {
4419 		_XmAppUnlock(app);
4420 		return(0);
4421 	}
4422 
4423 	if (!GetDSLeaf(info))
4424 	{
4425 		for (i=0; i < (int)GetDSNumChildren(info); i++)
4426 		{
4427 			XmDSInfo child = (XmDSInfo) GetDSChild(info, i);
4428 			if (!GetDSInternal(child))
4429 				num_visible_children++;
4430 		}
4431 
4432 		if (num_visible_children)
4433 		{
4434 			*children_rtn = (Widget *) XtMalloc(sizeof(Widget) *
4435 				num_visible_children);
4436 
4437 			/* Remember to reverse the order */
4438 			for (j=0, i=(GetDSNumChildren(info) - 1); i >= 0; i--)
4439 			{
4440 				XmDSInfo child = (XmDSInfo) GetDSChild(info, i);
4441 				if (!GetDSInternal(child))
4442 					(*children_rtn)[j++] = GetDSWidget(child);
4443 			}
4444 			/* assert(j == num_visible_children) */
4445 		}
4446 		else
4447 			*children_rtn = NULL;
4448 
4449 		*num_children_rtn = num_visible_children;
4450 	}
4451 	else
4452 	{
4453 		*children_rtn = NULL;
4454 		*num_children_rtn = 0;
4455 	}
4456 
4457 	parentInfo = (XmDSInfo) GetDSParent(info);
4458 
4459 	if (GetDSInternal(parentInfo))
4460 	{
4461 	  *parent_rtn = NULL;
4462 	  while ((parentInfo = (XmDSInfo) GetDSParent(parentInfo)) != NULL)
4463 	    if (!GetDSInternal(parentInfo))
4464 	      *parent_rtn = GetDSWidget(parentInfo);
4465 	}
4466 	else
4467 		*parent_rtn = GetDSWidget(parentInfo);
4468 
4469 	_XmAppUnlock(app);
4470 	return(1);
4471 }
4472 
4473 void
XmDropSiteConfigureStackingOrder(Widget widget,Widget sibling,Cardinal stack_mode)4474 XmDropSiteConfigureStackingOrder(
4475         Widget widget,
4476         Widget sibling,
4477         Cardinal stack_mode )
4478 {
4479 	XmDropSiteManagerObject dsm;
4480 	XmDSInfo info;
4481 	XmDSInfo parent;
4482 	_XmWidgetToAppContext(widget);
4483 
4484 	if (widget == NULL)
4485 		return;
4486 
4487 	_XmAppLock(app);
4488 	dsm = (XmDropSiteManagerObject)
4489 		_XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4490 			XtDisplayOfObject(widget)));
4491 
4492 	info = (XmDSInfo) DSMWidgetToInfo(dsm, widget);
4493 
4494 	if ((widget == sibling) || (info == NULL)) {
4495 		_XmAppUnlock(app);
4496 		return;
4497 	}
4498 
4499 	parent = (XmDSInfo) GetDSParent(info);
4500 
4501 	if (sibling != NULL)
4502 	{
4503 		XmDSInfo sib = (XmDSInfo) DSMWidgetToInfo(dsm, sibling);
4504 		Cardinal index, sib_index;
4505 		int i;
4506 
4507 		if ((sib == NULL) ||
4508 			(((XmDSInfo) GetDSParent(sib)) != parent) ||
4509 			(XtParent(widget) != XtParent(sibling))) {
4510 			_XmAppUnlock(app);
4511 			return;
4512 		}
4513 
4514 		index = GetDSChildPosition(parent, info);
4515 		sib_index = GetDSChildPosition(parent, sib);
4516 
4517 		switch(stack_mode)
4518 		{
4519 			case XmABOVE:
4520 				if (index > sib_index)
4521 					for(i=index; i > sib_index; i--)
4522 						SwapDSChildren(parent, i, i - 1);
4523 				else
4524 					for (i=index; i < (sib_index - 1); i++)
4525 						SwapDSChildren(parent, i, i + 1);
4526 			break;
4527 			case XmBELOW:
4528 				if (index > sib_index)
4529 					for(i=index; i > (sib_index + 1); i--)
4530 						SwapDSChildren(parent, i, i - 1);
4531 				else
4532 					for (i=index; i < sib_index; i++)
4533 						SwapDSChildren(parent, i, i + 1);
4534 			break;
4535 			default:
4536 				/* do nothing */
4537 			break;
4538 		}
4539 	}
4540 	else
4541 	{
4542 		Cardinal index = GetDSChildPosition(parent, info);
4543 		int i;
4544 
4545 		switch(stack_mode)
4546 		{
4547 			case XmABOVE:
4548 				for (i=index; i > 0; i--)
4549 					SwapDSChildren(parent, i, i - 1);
4550 			break;
4551 			case XmBELOW:
4552 				for (i=index; i < (int)(GetDSNumChildren(parent) - 1); i++)
4553 					SwapDSChildren(parent, i, i + 1);
4554 			break;
4555 			default:
4556 				/* do nothing */
4557 			break;
4558 		}
4559 	}
4560 	_XmAppUnlock(app);
4561 }
4562 
4563 XmDropSiteVisuals
XmDropSiteGetActiveVisuals(Widget widget)4564 XmDropSiteGetActiveVisuals(
4565         Widget widget )
4566 {
4567 	XmDropSiteManagerObject dsm;
4568 	XmDSInfo info;
4569 	XmDropSiteVisuals dsv;
4570 	_XmWidgetToAppContext(widget);
4571 
4572 	_XmAppLock(app);
4573 	dsm = (XmDropSiteManagerObject)
4574 	    _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4575 			XtDisplayOfObject(widget)));
4576 	info = (XmDSInfo) dsm->dropManager.curInfo;
4577 	dsv = (XmDropSiteVisuals) XtCalloc(1,
4578 		sizeof(XmDropSiteVisualsRec));
4579 
4580 	/* Update if dsm is dirty */
4581 	_XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL);
4582 
4583 	if (info == NULL)
4584 	{
4585 		XtFree((char *)dsv);
4586 		_XmAppUnlock(app);
4587 		return(NULL);
4588 	}
4589 
4590 	if (!GetDSRemote(info))
4591 	{
4592 		Arg args[30];
4593 		int n;
4594 		Widget w;
4595                 unsigned char unitType;
4596 		w = GetDSWidget(info);
4597 
4598 		/*
4599 		 * We need to retrieve information from the widget. XtGetValues is
4600 		 * too slow, so retrieve the information directly from the widget
4601 		 * instance.
4602 		 *
4603 		 * XtGetValues is used for gadgets, since part of the instance
4604 		 * structure will be in the cache and not directly accessable.
4605 		 *
4606 		 * XtGetValues is used for non-Motif widgets, just in case they provide
4607 		 * Motif-style resources.
4608 		 *
4609 		 * (See also PutDSToStream() )
4610 		 */
4611 
4612 		if (XmIsPrimitive(w))
4613 		{
4614 			XmPrimitiveWidget pw = (XmPrimitiveWidget)w;
4615 
4616 			dsv->background = pw->core.background_pixel;
4617 			dsv->foreground = pw->primitive.foreground;
4618 			dsv->topShadowColor = pw->primitive.top_shadow_color;
4619 			dsv->topShadowPixmap = pw->primitive.top_shadow_pixmap;
4620 			dsv->bottomShadowColor = pw->primitive.bottom_shadow_color;
4621 			dsv->bottomShadowPixmap = pw->primitive.bottom_shadow_pixmap;
4622 			dsv->shadowThickness = pw->primitive.shadow_thickness;
4623 			dsv->highlightColor = pw->primitive.highlight_color;
4624 			dsv->highlightPixmap = pw->primitive.highlight_pixmap;
4625 			dsv->highlightThickness = pw->primitive.highlight_thickness;
4626 			if (!GetDSHasRegion(info))
4627 			    dsv->borderWidth = pw->core.border_width;
4628 			else
4629 			    dsv->borderWidth = 0;
4630 		}
4631 		else if (XmIsManager(w))
4632 		{
4633 			XmManagerWidget mw = (XmManagerWidget)w;
4634 
4635 			dsv->background = mw->core.background_pixel;
4636 			dsv->foreground = mw->manager.foreground;
4637 			dsv->topShadowColor = mw->manager.top_shadow_color;
4638 			dsv->topShadowPixmap = mw->manager.top_shadow_pixmap;
4639 			dsv->bottomShadowColor = mw->manager.bottom_shadow_color;
4640 			dsv->bottomShadowPixmap = mw->manager.bottom_shadow_pixmap;
4641 			dsv->shadowThickness = mw->manager.shadow_thickness;
4642 			dsv->highlightColor = mw->manager.highlight_color;
4643 			dsv->highlightPixmap = mw->manager.highlight_pixmap;
4644 			/* Temporary hack, until we support full defaulting */
4645 			if (GetDSAnimationStyle(info) == XmDRAG_UNDER_HIGHLIGHT)
4646 			    dsv->highlightThickness = 1;
4647 			else
4648 			    dsv->highlightThickness = 0;
4649 			if (!GetDSHasRegion(info))
4650 			    dsv->borderWidth = mw->core.border_width;
4651 			else
4652 			    dsv->borderWidth = 0;
4653 		}
4654 		else /* XmGadget or non-Motif subclass */
4655 		{
4656 			n = 0;
4657 			XtSetArg(args[n], XmNunitType, &unitType); n++;
4658 			XtGetValues(w, args, n);
4659 
4660                 	if (unitType != XmPIXELS) { /* we need values in pixels */
4661 			   n = 0;
4662 			   XtSetArg(args[n], XmNunitType, XmPIXELS); n++;
4663 			   XtSetValues(w, args, n);
4664                 	}
4665 
4666 			n = 0;
4667 			XtSetArg(args[n], XmNbackground, &(dsv->background)); n++;
4668 			XtSetArg(args[n], XmNforeground, &(dsv->foreground)); n++;
4669 			XtSetArg(args[n], XmNtopShadowColor,
4670 				&(dsv->topShadowColor)); n++;
4671 			XtSetArg(args[n], XmNtopShadowPixmap,
4672 				&(dsv->topShadowPixmap)); n++;
4673 			XtSetArg(args[n], XmNbottomShadowColor,
4674 				&(dsv->bottomShadowColor)); n++;
4675 			XtSetArg(args[n], XmNbottomShadowPixmap,
4676 				&(dsv->bottomShadowPixmap)); n++;
4677 			XtSetArg(args[n], XmNshadowThickness,
4678 				&(dsv->shadowThickness)); n++;
4679 			XtSetArg(args[n], XmNhighlightColor,
4680 				&(dsv->highlightColor)); n++;
4681 			XtSetArg(args[n], XmNhighlightPixmap,
4682 				&(dsv->highlightPixmap)); n++;
4683 			XtSetArg(args[n], XmNhighlightThickness,
4684 				&(dsv->highlightThickness)); n++;
4685 			if (!GetDSHasRegion(info))
4686 			{
4687 			    XtSetArg(args[n], XmNborderWidth,
4688 				&(dsv->borderWidth)); n++;
4689 			}
4690 			else
4691 			    dsv->borderWidth = 0;
4692 
4693 			XtGetValues(w, args, n);
4694 
4695 			if (unitType != XmPIXELS) {
4696 			    n = 0;
4697 			    XtSetArg(args[n], XmNunitType, unitType); n++;
4698 			    XtSetValues(w, args, n);
4699 			}
4700 		}
4701 	}
4702 	else
4703 	{
4704 		switch (GetDSAnimationStyle(info))
4705 		{
4706 			case XmDRAG_UNDER_HIGHLIGHT:
4707 			{
4708 				XmDSRemoteHighlightStyle hs =
4709 					(XmDSRemoteHighlightStyle)
4710 						GetDSRemoteAnimationPart(info);
4711 
4712 				dsv->highlightColor = hs->highlight_color;
4713 				dsv->highlightPixmap = hs->highlight_pixmap;
4714 				dsv->background = hs->background;
4715 				dsv->highlightThickness = hs->highlight_thickness;
4716 				dsv->borderWidth = hs->border_width;
4717 			}
4718 			break;
4719 			case XmDRAG_UNDER_SHADOW_IN:
4720 			case XmDRAG_UNDER_SHADOW_OUT:
4721 			{
4722 				XmDSRemoteShadowStyle ss =
4723 					(XmDSRemoteShadowStyle)
4724 						GetDSRemoteAnimationPart(info);
4725 
4726 				dsv->topShadowColor = ss->top_shadow_color;
4727 				dsv->topShadowPixmap = ss->top_shadow_pixmap;
4728 				dsv->bottomShadowColor = ss->bottom_shadow_color;
4729 				dsv->bottomShadowPixmap = ss->bottom_shadow_pixmap;
4730 				dsv->foreground = ss->foreground;
4731 				dsv->shadowThickness = ss->shadow_thickness;
4732 				dsv->highlightThickness = ss->highlight_thickness;
4733 				dsv->borderWidth = ss->border_width;
4734 			}
4735 			break;
4736 			case XmDRAG_UNDER_PIXMAP:
4737 			{
4738 				XmDSRemotePixmapStyle ps =
4739 					(XmDSRemotePixmapStyle)
4740 						GetDSRemoteAnimationPart(info);
4741 
4742 				dsv->background = ps->background;
4743 				dsv->foreground = ps->foreground;
4744 				dsv->shadowThickness = ps->shadow_thickness;
4745 				dsv->highlightThickness = ps->highlight_thickness;
4746 				dsv->borderWidth = ps->border_width;
4747 			}
4748 			break;
4749 			case XmDRAG_UNDER_NONE:
4750 			default:
4751 			break;
4752 		}
4753 	}
4754 	_XmAppUnlock(app);
4755 	return(dsv);
4756 }
4757 
4758 Widget
_XmGetActiveDropSite(Widget widget)4759 _XmGetActiveDropSite(
4760         Widget widget )
4761 {
4762 	XmDropSiteManagerObject dsm = (XmDropSiteManagerObject)
4763 		_XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay(
4764 			XtDisplayOfObject(widget)));
4765 	XmDSInfo info = (XmDSInfo) dsm->dropManager.curInfo;
4766 
4767 	/* Update if dsm is dirty */
4768 	_XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL);
4769 
4770 	if ((!XmIsDragContext(widget)) || (GetDSRemote(info)))
4771 		return(NULL);
4772 	else
4773 		return(GetDSWidget(info));
4774 
4775 }
4776 
4777 #ifdef DEBUG
4778 /**********************************************************************
4779  * Debugging code for DropSMgr.  This code will print out the current
4780  * state of the tree
4781  **********************************************************************/
4782 
4783 
4784 static Boolean
PrintHashEntry(XmHashKey key,XtPointer value,XtPointer data)4785 PrintHashEntry(XmHashKey key, XtPointer value, XtPointer data)
4786 {
4787   Widget wid = (Widget) key;
4788 
4789   printf("Widget %p (%s) Info %p\n", wid, XtName(wid), value);
4790 
4791   return(False);
4792 }
4793 
4794 static void
PrintTree(XmDSInfo rec,int level)4795 PrintTree(XmDSInfo rec, int level)
4796 {
4797   int i;
4798   Widget wid = GetDSWidget(rec);
4799   char *name = "";
4800 
4801   /* Indent for level */
4802   for(i = 0; i < level; i++) printf("  ");
4803 
4804   if (wid != (Widget) NULL) name = XtName(wid);
4805 
4806   printf("%p (internal %d) - widget %p (%s)\n",
4807 	 rec, GetDSInternal(rec), wid, name);
4808 
4809   if (!GetDSLeaf(rec)) {
4810     int j;
4811 
4812     for(j = 0; j < GetDSNumChildren(rec); j++)
4813       PrintTree(GetDSChild(rec, j), level + 1);
4814   }
4815 }
4816 
4817 void
_XmPrintDSTree(XmDropSiteManagerObject dsm,XmDSInfo root)4818 _XmPrintDSTree(XmDropSiteManagerObject dsm, XmDSInfo root)
4819 {
4820   /* First print all the information records in tree format */
4821   PrintTree(root, 0);
4822 
4823   /* Now print widget to info hash table */
4824   _XmMapHashTable(DSTABLE(dsm), PrintHashEntry, NULL);
4825 }
4826 #endif /* DEBUG */
4827