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