/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * HISTORY */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$TOG: DropSMgr.c /main/21 1999/08/11 14:44:57 vipin $" #endif #endif /* (c) Copyright 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */ /***************************************************************************** * THE DROPSITE DATABASE * * Drag and Drop maintains a two way mapping between information records * and the dropsites widgets they represent. There are two kinds of records * kept in the database. * * The first kind of records are associated with a real dropsite. These * contain the information the user passes in via XmDropSiteRegister and * modifies via XmDropSiteUpdate. * * The second kind are clipping records which represent widgets which * in some way obscure one or more dropsites. These are created and destroyed * by Drag and Drop as dynamic things (like a ScrolledWindow scrolling) * occur. * * When a new record is created, it is associated via a hashtable kept * in dsm -> dstable to the widget it represents. This mapping is maintained * by the RegisterInfo and UnregisterInfo functions. Additionally, the * records themselves are kept internally in a compacted form. This * translation occurs in CopyVariantIntoFull and CopyFullIntoVariant. * * While confusing, the compression saves significant room. The fields * are accessed by macros (defined in DropSMgrI.h) to avoid the problems * of constantly compressing and decompressing the records. * * WHEN A CHANGE OCCURS * * When a new DS is added, one is removed, or a geometry change occurs, * the database must be brought up to sync with the real widgets. * This is done in a number of stages. * * RemoveAllClippers(dsm, root) - This removes all the clippers created * in the database hierarchy. The dropsites become a flat list held in * the child list of the topmost node. * * SyncDropSiteGeometry(dsm, root) - Now we go down the flat list and * see what updates are needed to the internal geometry information. This * is really needed for PREREGISTER, as we'll finalize the update by * refreshing the information kept on the window properties. * * DetectAndInsertAllClippers(dsm, root) - We now rebuild the clipper * hierarchy. *****************************************************************************/ #include #include #include #include #include #include /* for bzero */ #include "XmI.h" #include "DisplayI.h" #include "DragBSI.h" #include "DragCI.h" #include "DragICCI.h" #include "DragUnderI.h" #include "DropSMgrI.h" #include "HashI.h" #include "MessagesI.h" #include "PixConvI.h" #include "RegionI.h" #include "TraversalI.h" /* for _XmIntersectionOf() */ #define MESSAGE1 _XmMMsgDropSMgr_0001 #define MESSAGE2 _XmMMsgDropSMgr_0002 #define MESSAGE3 _XmMMsgDropSMgr_0003 #define MESSAGE4 _XmMMsgDropSMgr_0004 #define MESSAGE5 _XmMMsgDropSMgr_0005 #define MESSAGE6 _XmMMsgDropSMgr_0006 #define MESSAGE7 _XmMMsgDropSMgr_0007 #define MESSAGE8 _XmMMsgDropSMgr_0008 #define MESSAGE9 _XmMMsgDropSMgr_0009 #define MESSAGE10 _XmMMsgDropSMgr_0010 /* #define DEBUG */ #ifdef DEBUG #define DPRINT(x) printf x void _XmPrintDSTree(XmDropSiteManagerObject dsm, XmDSInfo root); #else #define DPRINT(x) #endif /******** Static Function Declarations ********/ static void ClassInit( void ) ; static void ClassPartInit( WidgetClass wc) ; static void DropSiteManagerInitialize( Widget rw, Widget nw, ArgList args, Cardinal *num_args) ; static void Destroy( Widget w) ; static Boolean SetValues( Widget cw, Widget rw, Widget nw, ArgList args, Cardinal *num_args) ; static void CreateTable( XmDropSiteManagerObject dsm) ; static void DestroyTable( XmDropSiteManagerObject dsm) ; static void RegisterInfo( register XmDropSiteManagerObject dsm, register Widget widget, register XtPointer info) ; static void UnregisterInfo( register XmDropSiteManagerObject dsm, register XtPointer info) ; static XtPointer WidgetToInfo( register XmDropSiteManagerObject dsm, register Widget widget) ; static Boolean Coincident( XmDropSiteManagerObject dsm, Widget w, XmDSClipRect *r) ; static Boolean IsDescendent( Widget parentW, Widget childW) ; static void DetectAncestorClippers( XmDropSiteManagerObject dsm, Widget w, XmDSClipRect *r, XmDSInfo info) ; static void DetectImpliedClipper( XmDropSiteManagerObject dsm, XmDSInfo info) ; static void DetectAllClippers( XmDropSiteManagerObject dsm, XmDSInfo parentInfo) ; static Boolean InsertClipper( XmDropSiteManagerObject dsm, XmDSInfo parentInfo, XmDSInfo clipper) ; static void DetectAndInsertAllClippers( XmDropSiteManagerObject dsm, XmDSInfo root) ; static void RemoveClipper( XmDropSiteManagerObject dsm, XmDSInfo clipper) ; static void RemoveAllClippers( XmDropSiteManagerObject dsm, XmDSInfo parentInfo) ; static void DestroyDSInfo( XmDSInfo info, #if NeedWidePrototypes int substructures) ; #else Boolean substructures) ; #endif /* NeedWidePrototypes */ static XmDSInfo CreateShellDSInfo( XmDropSiteManagerObject dsm, Widget widget) ; static XmDSInfo CreateClipperDSInfo( XmDropSiteManagerObject dsm, Widget clipW) ; static void InsertInfo( XmDropSiteManagerObject dsm, XtPointer info, XtPointer call_data) ; static void RemoveInfo( XmDropSiteManagerObject dsm, XtPointer info) ; static Boolean IntersectWithWidgetAncestors( Widget w, XmRegion r) ; static Boolean IntersectWithDSInfoAncestors( XmDSInfo parent, XmRegion r) ; static Boolean CalculateAncestorClip( XmDropSiteManagerObject dsm, XmDSInfo info, XmRegion r) ; static Boolean PointInDS( XmDropSiteManagerObject dsm, XmDSInfo info, #if NeedWidePrototypes int x, int y) ; #else Position x, Position y) ; #endif /* NeedWidePrototypes */ static XmDSInfo PointToDSInfo( XmDropSiteManagerObject dsm, XmDSInfo info, #if NeedWidePrototypes int x, int y) ; #else Position x, Position y) ; #endif /* NeedWidePrototypes */ static void DoAnimation( XmDropSiteManagerObject dsm, XmDragMotionClientData motionData, XtPointer callback) ; static void ProxyDragProc( XmDropSiteManagerObject dsm, XtPointer client_data, XmDragProcCallbackStruct *callback) ; static void HandleEnter( XmDropSiteManagerObject dsm, XmDragMotionClientData motionData, XmDragMotionCallbackStruct *callback, XmDSInfo info, #if NeedWidePrototypes unsigned int style) ; #else unsigned char style) ; #endif /* NeedWidePrototypes */ static void HandleMotion( XmDropSiteManagerObject dsm, XmDragMotionClientData motionData, XmDragMotionCallbackStruct *callback, XmDSInfo info, #if NeedWidePrototypes unsigned int style) ; #else unsigned char style) ; #endif /* NeedWidePrototypes */ static void HandleLeave( XmDropSiteManagerObject dsm, XmDragMotionClientData motionData, XmDragMotionCallbackStruct *callback, XmDSInfo info, #if NeedWidePrototypes unsigned int style, int enterPending) ; #else unsigned char style, Boolean enterPending) ; #endif /* NeedWidePrototypes */ static void ProcessMotion( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer calldata) ; static void ProcessDrop( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer cb) ; static void ChangeOperation( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer calldata) ; static void PutDSToStream( XmDropSiteManagerObject dsm, XmDSInfo dsInfo, #if NeedWidePrototypes int last, #else Boolean last, #endif /* NeedWidePrototypes */ XtPointer dataPtr) ; static void GetDSFromDSM( XmDropSiteManagerObject dsm, XmDSInfo parentInfo, #if NeedWidePrototypes int last, #else Boolean last, #endif /* NeedWidePrototypes */ XtPointer dataPtr) ; static int GetTreeFromDSM( XmDropSiteManagerObject dsm, Widget shell, XtPointer dataPtr) ; static XmDSInfo GetDSFromStream( XmDropSiteManagerObject dsm, XtPointer dataPtr, Boolean *close, unsigned char *type) ; static void GetNextDS( XmDropSiteManagerObject dsm, XmDSInfo parentInfo, XtPointer dataPtr) ; static XmDSInfo ReadTree( XmDropSiteManagerObject dsm, XtPointer dataPtr) ; static void FreeDSTree( XmDSInfo tree) ; static void ChangeRoot( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer callData) ; static int CountDropSites( XmDSInfo info) ; static void CreateInfo( XmDropSiteManagerObject dsm, Widget widget, ArgList args, Cardinal argCount) ; static void CopyVariantIntoFull( XmDropSiteManagerObject dsm, XmDSInfo variant, XmDSFullInfo full_info) ; static void RetrieveInfo( XmDropSiteManagerObject dsm, Widget widget, ArgList args, Cardinal argCount) ; static void CopyFullIntoVariant( XmDSFullInfo full_info, XmDSInfo variant) ; static void UpdateInfo( XmDropSiteManagerObject dsm, Widget widget, ArgList args, Cardinal argCount) ; static void StartUpdate( XmDropSiteManagerObject dsm, Widget refWidget) ; static void EndUpdate( XmDropSiteManagerObject dsm, Widget refWidget) ; static void DestroyInfo( XmDropSiteManagerObject dsm, Widget widget) ; static void SyncDropSiteGeometry( XmDropSiteManagerObject dsm, XmDSInfo info) ; static void SyncTree( XmDropSiteManagerObject dsm, Widget shell) ; static void Update( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer callData) ; static Boolean HasDropSiteDescendant( XmDropSiteManagerObject dsm, Widget widget) ; static void DestroyCallback( Widget widget, XtPointer client_data, XtPointer call_data) ; /******** End Static Function Declarations ********/ static XtResource resources[] = { { XmNnotifyProc, XmCNotifyProc, XmRCallbackProc, sizeof(XtCallbackProc), XtOffsetOf( struct _XmDropSiteManagerRec, dropManager.notifyProc), XmRImmediate, NULL }, { XmNtreeUpdateProc, XmCTreeUpdateProc, XmRCallbackProc, sizeof(XtCallbackProc), XtOffsetOf( struct _XmDropSiteManagerRec, dropManager.treeUpdateProc), XmRImmediate, NULL }, { XmNclientData, XmCClientData, XmRPointer, sizeof(XtPointer), XtOffsetOf( struct _XmDropSiteManagerRec, dropManager.client_data), XmRImmediate, NULL }, }; /* class record definition */ externaldef(xmdropsitemanagerclassrec) XmDropSiteManagerClassRec xmDropSiteManagerClassRec = { { (WidgetClass) &objectClassRec, /* superclass */ "XmDropSiteManager", /* class_name */ sizeof(XmDropSiteManagerRec), /* widget_size */ ClassInit, /* class_initialize */ ClassPartInit, /* class part initialize */ False, /* class_inited */ DropSiteManagerInitialize, /* initialize */ NULL, /* initialize_hook */ NULL, /* obj1 */ NULL, /* obj2 */ 0, /* obj3 */ resources, /* resources */ XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ True, /* obj4 */ XtExposeCompressSeries, /* obj5 */ True, /* obj6 */ False, /* obj7 */ Destroy, /* destroy */ NULL, /* obj8 */ NULL, /* obj9 */ SetValues, /* set_values */ NULL, /* set_values_hook */ NULL, /* obj10 */ NULL, /* get_values_hook */ NULL, /* obj11 */ XtVersion, /* version */ NULL, /* callback private */ NULL, /* obj12 */ NULL, /* obj13 */ NULL, /* obj14 */ NULL, /* extension */ }, { CreateInfo, /* createInfo */ DestroyInfo, /* destroyInfo */ StartUpdate, /* startUpdate */ RetrieveInfo, /* retrieveInfo */ UpdateInfo, /* updateInfo */ EndUpdate, /* endUpdate */ Update, /* updateDSM */ ProcessMotion, /* processMotion */ ProcessDrop, /* processDrop */ ChangeOperation, /* operationChanged */ ChangeRoot, /* changeDSRoot */ InsertInfo, /* insertInfo */ RemoveInfo, /* removeInfo */ SyncTree, /* syncTree */ GetTreeFromDSM, /* getTreeFromDSM */ CreateTable, /* createTable */ DestroyTable, /* destroyTable */ RegisterInfo, /* registerInfo */ WidgetToInfo, /* widgetToInfo */ UnregisterInfo, /* unregisterInfo */ NULL, /* extension */ }, }; externaldef(xmdropsitemanagerobjectclass) WidgetClass xmDropSiteManagerObjectClass = (WidgetClass) &xmDropSiteManagerClassRec; static void ClassInit( void ) { _XmRegisterPixmapConverters(); } /*ARGSUSED*/ static void ClassPartInit( WidgetClass wc ) { /*EMPTY*/ } /*ARGSUSED*/ static void DropSiteManagerInitialize( Widget rw, Widget nw, ArgList args, Cardinal *num_args ) { XmDropSiteManagerObject dsm = (XmDropSiteManagerObject)nw; XmDSFullInfoRec info_rec; XmDSFullInfo info = &(info_rec); dsm->dropManager.dragUnderData = NULL; dsm->dropManager.curInfo = NULL; dsm->dropManager.curTime = 0; dsm->dropManager.oldX = dsm->dropManager.curX = 0; dsm->dropManager.oldY = dsm->dropManager.curY = 0; dsm->dropManager.curDropSiteStatus = XmINVALID_DROP_SITE; dsm->dropManager.curDragContext = NULL; dsm->dropManager.curAnimate = True; dsm->dropManager.curOperations = XmDROP_NOOP; dsm->dropManager.curOperation = XmDROP_NOOP; dsm->dropManager.curAncestorClipRegion = _XmRegionCreate(); dsm->dropManager.newAncestorClipRegion = _XmRegionCreate(); DSMCreateTable(dsm); dsm->dropManager.dsRoot = NULL; dsm->dropManager.rootX = dsm->dropManager.rootY = 0; dsm->dropManager.rootW = dsm->dropManager.rootH = ~0; dsm->dropManager.clipperList = NULL; dsm->dropManager.updateInfo = NULL; /* Patch around broken Xt interfaces */ XtGetSubresources(nw, info, NULL, NULL, _XmDSResources, _XmNumDSResources, NULL, 0); } static void Destroy( Widget w ) { XmDropSiteManagerObject dsm = (XmDropSiteManagerObject)w; DSMDestroyTable(dsm); _XmRegionDestroy(dsm->dropManager.curAncestorClipRegion); _XmRegionDestroy(dsm->dropManager.newAncestorClipRegion); } /*ARGSUSED*/ static Boolean SetValues( Widget cw, Widget rw, Widget nw, ArgList args, Cardinal *num_args ) { /*EMPTY*/ return False; } /* Function for Hash table */ static Boolean CompareWidgets(XtPointer w1, XtPointer w2) { return(w1 == w2); } static XmHashValue HashWidget(XtPointer w1) { return((XmHashValue)(long)w1); } static void CreateTable( XmDropSiteManagerObject dsm ) { XtPointer *tab = &(dsm->dropManager.dsTable); _XmProcessLock(); *tab = (XtPointer) _XmAllocHashTable(100, CompareWidgets, HashWidget); _XmProcessUnlock(); } static void DestroyTable( XmDropSiteManagerObject dsm ) { XtPointer * tab = &(dsm->dropManager.dsTable); _XmProcessLock(); _XmFreeHashTable((XmHashTable) *tab); _XmProcessUnlock(); *tab = NULL; } #define DSTABLE(dsm) ((XmHashTable)(dsm->dropManager.dsTable)) static void RegisterInfo( register XmDropSiteManagerObject dsm, register Widget widget, register XtPointer info ) { register XmHashTable tab; if (GetDSRegistered(info)) return; DPRINT(("(RegI) Widget %p (%s) info %p (internal %d widget %p)\n", widget, XtName(widget), info, GetDSInternal(info), GetDSWidget(info))); tab = DSTABLE(dsm); _XmProcessLock(); /* Resize if the table has many more entries than slots */ if (_XmHashTableCount(tab) > (2 * _XmHashTableSize(tab))) _XmResizeHashTable(tab, 2 * _XmHashTableSize(tab)); _XmAddHashEntry(tab, widget, info); _XmProcessUnlock(); SetDSRegistered(info, True); } static void UnregisterInfo( register XmDropSiteManagerObject dsm, register XtPointer info ) { XmHashTable tab; XtPointer iterator; Widget widget = GetDSWidget(info); XtPointer data; if ((info == NULL) || !GetDSRegistered(info)) return; DPRINT(("(UnregI) Widget %p (%s) info %p (internal %d widget %p)\n", widget, XtName(widget), info, GetDSInternal(info), GetDSWidget(info))); tab = DSTABLE(dsm); iterator = NULL; _XmProcessLock(); while((data = _XmGetHashEntryIterate(tab, widget, &iterator)) != NULL) { if (data == info) { _XmRemoveHashIterator(tab, &iterator); break; } } _XmProcessUnlock(); SetDSRegistered(info, False); } static XtPointer WidgetToInfo( register XmDropSiteManagerObject dsm, register Widget widget ) { XmHashTable tab; XmDSInfo info; tab = DSTABLE(dsm); info = (XmDSInfo) _XmGetHashEntry(tab, widget); return((XtPointer) info); } static Boolean Coincident( XmDropSiteManagerObject dsm, Widget w, XmDSClipRect *r ) { XRectangle wR; Boolean hit = False; if (!XtIsShell(w)) { /* r is shell relative, so wR needs to be translated */ XtTranslateCoords(XtParent(w), XtX(w), XtY(w), &(wR.x), &(wR.y)); wR.x -= dsm->dropManager.rootX; wR.y -= dsm->dropManager.rootY; } else { wR.x = wR.y = 0; } wR.width = XtWidth(w); wR.height = XtHeight(w); if ( !(r->detected & XmDROP_SITE_LEFT_EDGE) && (r->x == wR.x)) { r->detected |= XmDROP_SITE_LEFT_EDGE; hit = True; } if ( !(r->detected & XmDROP_SITE_RIGHT_EDGE) && ((r->x + r->width) == (wR.x + wR.width))) { r->detected |= XmDROP_SITE_RIGHT_EDGE; hit = True; } if ( !(r->detected & XmDROP_SITE_TOP_EDGE) && (r->y == wR.y)) { r->detected |= XmDROP_SITE_TOP_EDGE; hit = True; } if ( !(r->detected & XmDROP_SITE_BOTTOM_EDGE) && ((r->y + r->height) == (wR.y + wR.height))) { r->detected |= XmDROP_SITE_BOTTOM_EDGE; hit = True; } return(hit); } static Boolean IsDescendent( Widget parentW, Widget childW ) { Widget tmp = XtParent(childW); if ((parentW == NULL) || (childW == NULL)) return(False); while (tmp != parentW) { if (XtIsShell(tmp)) return(False); tmp = XtParent(tmp); } return(True); } static void DetectAncestorClippers( XmDropSiteManagerObject dsm, Widget w, XmDSClipRect *r, XmDSInfo info ) { /* * We know that r represents the visible region of the dropSite * as clipped by its ancestors in shell relative coordinates. We * now search for the most ancient ancestor who provides that clip. * We do this by looking from the shell downward for the parent * whose edge is coincident with a clipped edge. * * We can add as many as four clippers to the tree as a result * of this routine. */ /* * Hygiene. */ if (w == NULL) return; if (!XtIsShell(w)) DetectAncestorClippers(dsm, XtParent(w), r, info); /* * We never need to add the shell to the tree as a clipper. * We call Coincident first so that any clipping provided by * the shell is marked in the cliprect structure. */ if ((Coincident(dsm, w, r)) && (!XtIsShell(w))) { XmDSInfo clipper; /* Have we already put this clipper in the tree? */ if ((clipper = (XmDSInfo) DSMWidgetToInfo(dsm, w)) != NULL) return; clipper = CreateClipperDSInfo(dsm, w); DSMRegisterInfo(dsm, w, (XtPointer) clipper); SetDSParent(clipper, dsm->dropManager.clipperList); dsm->dropManager.clipperList = (XtPointer) clipper; } } static void DetectImpliedClipper( XmDropSiteManagerObject dsm, XmDSInfo info ) { static XmRegion tmpRegion = NULL; if (tmpRegion == NULL) { tmpRegion = _XmRegionCreate(); } if ((GetDSType(info) == XmDROP_SITE_SIMPLE) && GetDSHasRegion(info)) { Widget w = GetDSWidget(info); XRectangle wr, tr, rr; /* * This step only has meaning if there is a separately * specified region for this drop site (which can only be done * for simple drop sites). */ /* The region will be relative to the origin of the widget */ wr.x = wr.y = 0; wr.width = XtWidth(w); wr.height = XtHeight(w); _XmRegionGetExtents(GetDSRegion(info), &rr); _XmIntersectionOf(&wr, &rr, &tr); if ((rr.x != tr.x) || (rr.y != tr.y) || (rr.width != tr.width) || (rr.height != tr.height)) { XmDSInfo clipper; /* * The implied clipper is magic. It's in the tree but not * of it. (It refers to the same widget, but it's not * registered.) */ clipper = CreateClipperDSInfo(dsm, w); SetDSParent(clipper, dsm->dropManager.clipperList); dsm->dropManager.clipperList = (XtPointer) clipper; } } } static void DetectAllClippers( XmDropSiteManagerObject dsm, XmDSInfo parentInfo ) { XmDSInfo childInfo; XmDSClipRect extents, clippedExtents; int i; Widget w; static XmRegion tmpR = NULL; if (GetDSLeaf(parentInfo)) return; _XmProcessLock(); if (tmpR == NULL) { tmpR = _XmRegionCreate(); } _XmProcessUnlock(); for (i = 0; i < (int)GetDSNumChildren(parentInfo); i++) { childInfo = (XmDSInfo) GetDSChild(parentInfo, i); /* * Because we don't allow composite drop sites to have * arbitrary regions, and Motif doesn't support shaped * widgets, we do a simple rectangle clip detection. * * IntersectWithAncestors expects the region to be in * widget relative coordinates, and returns in shell relative * coordinates (the ultimate ancestor is the shell). */ _XmRegionGetExtents(GetDSRegion(childInfo), (XRectangle *)(&extents)); _XmProcessLock(); _XmRegionUnion(GetDSRegion(childInfo), GetDSRegion(childInfo), tmpR); w = GetDSWidget(childInfo); IntersectWithWidgetAncestors(w, tmpR); _XmRegionGetExtents(tmpR, (XRectangle *)(&clippedExtents)); _XmProcessUnlock(); /* tmpR is now in shell relative position */ clippedExtents.detected = 0; if ((clippedExtents.width < extents.width) || (clippedExtents.height < extents.height)) { /* * We've been clipped. Find out who did it and add * them to the tree. */ DetectAncestorClippers(dsm, XtParent(GetDSWidget(childInfo)), &clippedExtents, childInfo); } /* * We now have inserted clippers for any ancestors which may * have clipped the widget. Now we need to check for the * case that the widget itself clips the region. */ DetectImpliedClipper(dsm, childInfo); /* Re-Curse */ DetectAllClippers(dsm, childInfo); } } static Boolean InsertClipper( XmDropSiteManagerObject dsm, XmDSInfo parentInfo, XmDSInfo clipper ) { int i; XmDSInfo childInfo; /* * Do a tail-end recursion which will insert the clipper into * the info tree as a child of its closest ancestor in the tree. */ if (GetDSLeaf(parentInfo)) return(False); for (i=0; i < (int)GetDSNumChildren(parentInfo); i++) { childInfo = (XmDSInfo) GetDSChild(parentInfo, i); if (InsertClipper(dsm, childInfo, clipper)) return(True); } if (IsDescendent(GetDSWidget(parentInfo), GetDSWidget(clipper))) { i = 0; while (i < (int)GetDSNumChildren(parentInfo)) { childInfo = (XmDSInfo) GetDSChild(parentInfo, i); if (IsDescendent(GetDSWidget(clipper), GetDSWidget(childInfo))) { RemoveDSChild(parentInfo, childInfo); AddDSChild(clipper, childInfo, GetDSNumChildren(clipper)); } else /* * Because RemoveDSChild monkeys with the num children, * we only increment i if we haven't called * RemoveDSChild. */ i++; } AddDSChild(parentInfo, clipper, GetDSNumChildren(parentInfo)); /* We have inserted the clipper into the tree */ return(True); } else return(False); } static void DetectAndInsertAllClippers( XmDropSiteManagerObject dsm, XmDSInfo root ) { XmDSInfo clipper; if ((!GetDSShell(root)) || (GetDSRemote(root))) return; DetectAllClippers(dsm, root); while ((clipper = (XmDSInfo) dsm->dropManager.clipperList) != NULL) { dsm->dropManager.clipperList = GetDSParent(clipper); (void) InsertClipper(dsm, root, clipper); } } static void RemoveClipper( XmDropSiteManagerObject dsm, XmDSInfo clipper ) { XmDSInfo parentInfo = (XmDSInfo) GetDSParent(clipper); int i; /* Remove the clipper from its parent */ RemoveDSChild(parentInfo, clipper); /* * Pull all of the children up into the parent's child * list between the clipper and the clipper's sibling. */ for (i = 0; i < (int)GetDSNumChildren(clipper); i++) { XmDSInfo childInfo = (XmDSInfo) GetDSChild(clipper, i); AddDSChild(parentInfo, childInfo, GetDSNumChildren(parentInfo)); } /* * Destroy the clipper */ DSMUnregisterInfo(dsm, clipper); DestroyDSInfo(clipper, True); } static void RemoveAllClippers( XmDropSiteManagerObject dsm, XmDSInfo parentInfo ) { XmDSInfo child; int i; if (!GetDSLeaf(parentInfo)) { i = 0; while(i < (int)GetDSNumChildren(parentInfo)) { child = (XmDSInfo) GetDSChild(parentInfo, i); RemoveAllClippers(dsm, child); if (GetDSInternal(child)) RemoveClipper(dsm, child); /* Only increment i if the current child wasn't removed. Otherwise we'll skip items in the list unintentionally */ if (child == (XmDSInfo) GetDSChild(parentInfo, i)) i++; } } } static void DestroyDSInfo( XmDSInfo info, #if NeedWidePrototypes int substructures ) #else Boolean substructures ) #endif /* NeedWidePrototypes */ { DestroyDS(info, substructures); } static XmDSInfo CreateShellDSInfo( XmDropSiteManagerObject dsm, Widget widget ) { XmDSInfo info; XmRegion region = _XmRegionCreate(); XRectangle rect; info = (XmDSInfo) XtCalloc(1, sizeof(XmDSLocalNoneNodeRec)); SetDSLeaf(info, True); SetDSShell(info, True); SetDSAnimationStyle(info, XmDRAG_UNDER_NONE); SetDSType(info, XmDROP_SITE_COMPOSITE); SetDSInternal(info, True); SetDSActivity(info, XmDROP_SITE_INACTIVE); SetDSWidget(info, widget); rect.x = rect.y = 0; rect.width = XtWidth(widget); rect.height = XtHeight(widget); _XmRegionUnionRectWithRegion(&rect, region, region); SetDSRegion(info, region); XtAddCallback(widget, XmNdestroyCallback, DestroyCallback, dsm); return(info); } /*ARGSUSED*/ static XmDSInfo CreateClipperDSInfo( XmDropSiteManagerObject dsm, Widget clipW ) { XmDSInfo info = NULL; XmRegion region = _XmRegionCreate(); XRectangle rect; info = (XmDSInfo) XtCalloc(1, sizeof(XmDSLocalNoneNodeRec)); SetDSLeaf(info, True); SetDSInternal(info, True); SetDSType(info, XmDROP_SITE_COMPOSITE); SetDSAnimationStyle(info, XmDRAG_UNDER_NONE); SetDSWidget(info, clipW); SetDSActivity(info, XmDROP_SITE_ACTIVE); rect.x = rect.y = 0; rect.width = XtWidth(clipW); rect.height = XtHeight(clipW); _XmRegionUnionRectWithRegion(&rect, region, region); SetDSRegion(info, region); /* * Don't need a destroy callback. When this widget is destroyed * the drop site children will be destroyed and as a side-effect * of the last drop site being destroyed, the clipper will be * destroyed. */ return(info); } /*ARGSUSED*/ static void InsertInfo( XmDropSiteManagerObject dsm, XtPointer info, XtPointer call_data ) { XmDSInfo childInfo = (XmDSInfo) info; XmDSInfo parentInfo = NULL; Widget parent = XtParent(GetDSWidget(childInfo)); while (!(parentInfo = (XmDSInfo) DSMWidgetToInfo(dsm, parent)) && !XtIsShell(parent)) { parent = XtParent(parent); } if (parentInfo == NULL) { /* * We've traversed clear back to the shell and not found a * parent for this info. Therefore this must be the first drop * site to be registered under this shell, and we must create a * parent place holder at for shell */ parentInfo = CreateShellDSInfo(dsm, parent); DSMRegisterInfo(dsm, parent, (XtPointer) parentInfo); AddDSChild(parentInfo, childInfo, GetDSNumChildren(parentInfo)); if ((dsm->dropManager.treeUpdateProc) && (!XtIsRealized(parent) || (_XmGetDragProtocolStyle(parent) == XmDRAG_DYNAMIC))) { /* * If this is a preregister client and the shell isn't * realized yet, we need to register this shell with the * DragDisplay so the DragDisplay can register a realize * callback on this shell. * * OR * * If this is a dynamic client, we need to notify the Drag- * Display exactly once so that event handlers and such * can be installed on this client. */ XmDropSiteTreeAddCallbackStruct outCB; outCB.reason = XmCR_DROP_SITE_TREE_ADD; outCB.event = NULL; outCB.rootShell = parent; outCB.numDropSites = 0; /* Unused */ outCB.numArgsPerDSHint = 0; (dsm->dropManager.treeUpdateProc) ((Widget) dsm, NULL, (XtPointer) &outCB); } } else if (GetDSType(parentInfo) == XmDROP_SITE_COMPOSITE) { AddDSChild(parentInfo, childInfo, GetDSNumChildren(parentInfo)); } else { XmeWarning(GetDSWidget(childInfo), MESSAGE1); } } static void RemoveInfo( XmDropSiteManagerObject dsm, XtPointer info ) { Widget widget = GetDSWidget(info); XmDSInfo parentInfo = (XmDSInfo) GetDSParent(info); RemoveDSChild(parentInfo, (XmDSInfo) info); DSMUnregisterInfo(dsm, info); XtRemoveCallback(widget, XmNdestroyCallback, DestroyCallback, dsm); if ((parentInfo != NULL) && (GetDSNumChildren(parentInfo) == 0) && (GetDSInternal(parentInfo))) { if (XtIsShell(GetDSWidget(parentInfo))) { /* * Need to notify the DragDisplay that this shell no * longer has any drop sites in it. */ if (dsm->dropManager.treeUpdateProc) { XmDropSiteTreeAddCallbackStruct outCB; outCB.reason = XmCR_DROP_SITE_TREE_REMOVE; outCB.event = NULL; outCB.rootShell = GetDSWidget(parentInfo); (dsm->dropManager.treeUpdateProc) ((Widget)dsm, NULL, (XtPointer) &outCB); } } DSMDestroyInfo(dsm, GetDSWidget(parentInfo)); } } static Boolean IntersectWithWidgetAncestors( Widget w, XmRegion r ) { /* * r is the bounding box of the region. It is in widget relative * coordinates. */ XRectangle parentR; static XmRegion tmpR = NULL; Dimension bw = XtBorderWidth(w); if (XtIsShell(w)) { return(True); } _XmProcessLock(); if (tmpR == NULL) { tmpR = _XmRegionCreate(); } _XmProcessUnlock(); /* Translate the coordinates into parent relative coords */ _XmRegionOffset(r, (XtX(w) + bw), (XtY(w) + bw)); parentR.x = parentR.y = 0; parentR.width = XtWidth(XtParent(w)); parentR.height = XtHeight(XtParent(w)); _XmProcessLock(); _XmRegionClear(tmpR); _XmRegionUnionRectWithRegion(&parentR, tmpR, tmpR); _XmRegionIntersect(tmpR, r, r); _XmProcessUnlock(); if (!_XmRegionIsEmpty(r)) return(IntersectWithWidgetAncestors(XtParent(w), r)); else return(False); } static Boolean IntersectWithDSInfoAncestors( XmDSInfo parent, XmRegion r ) { static XmRegion testR = (XmRegion) NULL; static XmRegion pR = (XmRegion) NULL; Dimension bw; _XmProcessLock(); if (testR == NULL) { testR = _XmRegionCreate(); pR = _XmRegionCreate(); } _XmProcessUnlock(); /* * A simplifying assumption in this code is that the regions * are all relative to the shell widget. We don't have to * do any fancy translations. * * All that we have to do is successively intersect the drop site * region with its ancestors until we reach the top of the drop * site tree. */ /* * If got to the top, then there is some part of the * region which is visible. */ if (parent == NULL) return(True); _XmProcessLock(); _XmRegionUnion(GetDSRegion(parent), GetDSRegion(parent), pR); _XmProcessUnlock(); if ((bw = GetDSBorderWidth(parent)) != 0) { /* * Adjust for the border width ala X clipping * Recall that all Composite's drop rectangles represent the * refW's sensitive area (including border width), but clipping * should be done to the window not the border. The clip * region is smaller than the sensitive region. */ _XmProcessLock(); _XmRegionShrink(pR, bw, bw); _XmProcessUnlock(); } _XmProcessLock(); _XmRegionIntersect(r, pR, r); _XmProcessUnlock(); /* C will ensure that we only recurse if testR is non-empty */ return((!_XmRegionIsEmpty(r)) && (IntersectWithDSInfoAncestors( (XmDSInfo) GetDSParent(parent), r))); } static Boolean CalculateAncestorClip( XmDropSiteManagerObject dsm, XmDSInfo info, XmRegion r ) { /* * When this procedure finishes, r will contain the composite * clip region for all ancestors of info. The clip region will * be in shell relative coordinates. */ _XmRegionClear(r); if (GetDSRemote(info)) { XRectangle universe; /* Set it to the "universe" -- which is shell relative */ universe.x = universe.y = 0; universe.width = dsm->dropManager.rootW; universe.height = dsm->dropManager.rootH; _XmRegionUnionRectWithRegion(&universe, r, r); /* * IntersectWithDSInfoAncestors will shoot the universe * through all of the DSInfo ancestors and return us what * is left in r. */ return(IntersectWithDSInfoAncestors( (XmDSInfo) GetDSParent(info), r)); } else { XRectangle parentR; Widget parentW = XtParent(GetDSWidget(info)); if (parentW == NULL) return(True); else { parentR.x = parentR.y = -(XtBorderWidth(parentW)); parentR.width = XtWidth(parentW); parentR.height = XtHeight(parentW); _XmRegionUnionRectWithRegion(&parentR, r, r); /* * IntersectWithWidgetAncestors will intersect the parent * of info with all successive parents and return us what * is left in r. */ return(IntersectWithWidgetAncestors(parentW, r)); } } } static Boolean PointInDS( XmDropSiteManagerObject dsm, XmDSInfo info, #if NeedWidePrototypes int x, int y ) #else Position x, Position y ) #endif /* NeedWidePrototypes */ { static XmRegion testR = (XmRegion) NULL; static XmRegion tmpR = (XmRegion) NULL; XmRegion *visR = &(dsm->dropManager.newAncestorClipRegion); Widget w = GetDSWidget(info); _XmProcessLock(); if (testR == NULL) { testR = _XmRegionCreate(); tmpR = _XmRegionCreate(); } _XmProcessUnlock(); /* * CalculateAncestorClip will intersect the universe with all of * the ancestors. If anything is left, it will return true the * intersection will be in tmpR. */ _XmProcessLock(); if (!CalculateAncestorClip(dsm, info, tmpR)) { _XmProcessUnlock(); return(False); } _XmProcessUnlock(); if (GetDSRemote(info)) { /* * We know that the region in the info struct is shell relative */ _XmProcessLock(); _XmRegionIntersect(tmpR, GetDSRegion(info), testR); _XmProcessUnlock(); } else { Position tmpX, tmpY; _XmRegionUnion(GetDSRegion(info), GetDSRegion(info), testR); /* * We know that the information is widget * relative so we will have to translate it. */ XtTranslateCoords(w, 0, 0, &tmpX, &tmpY); _XmProcessLock(); _XmRegionOffset(testR, (tmpX - dsm->dropManager.rootX), (tmpY - dsm->dropManager.rootY)); _XmRegionIntersect(tmpR, testR, testR); _XmProcessUnlock(); } _XmProcessLock(); if ((!_XmRegionIsEmpty(testR)) && (_XmRegionPointInRegion(testR, x, y))) { _XmRegionUnion(tmpR, tmpR, *visR); _XmProcessUnlock(); return(True); } else { _XmProcessUnlock(); return(False); } /* _XmProcessUnlock(); */ /* not reached */ } static XmDSInfo PointToDSInfo( XmDropSiteManagerObject dsm, XmDSInfo info, #if NeedWidePrototypes int x, int y ) #else Position x, Position y ) #endif /* NeedWidePrototypes */ { unsigned int i; XmDSInfo child = NULL; if (!GetDSLeaf(info)) { /* * This should be optimized at some point. * CalculateAncestorClip is having to do potentially * unneccessary work, because it starts from scratch each time. */ for (i = 0; i < GetDSNumChildren(info); i++) { Boolean managed; child = (XmDSInfo) GetDSChild(info,i); if (GetDSRemote(child)) managed = True; else { Widget child_widget; Widget parent; child_widget = GetDSWidget(child); parent = XtParent(child_widget); managed = XtIsManaged(child_widget); /* CR 7848, first check if DS widget is managed and all the parents are managed. To accomplish this we wander up to the shell and make sure all the widget parents are managed */ while(managed && ! XtIsShell(parent)) { managed = XtIsManaged(parent); parent = XtParent(parent); } } if (managed && PointInDS(dsm, child, x, y) && GetDSActivity(child) != XmDROP_SITE_INACTIVE) { if (!GetDSLeaf(child)) { XmDSInfo descendant = PointToDSInfo(dsm, child, x, y); if (descendant != NULL) return(descendant); } if (!GetDSInternal(child)) return(child); } } } return(NULL); } static void DoAnimation( XmDropSiteManagerObject dsm, XmDragMotionClientData motionData, XtPointer callback ) { XmDSInfo info = (XmDSInfo) (dsm->dropManager.curInfo); XmDSInfo parentInfo = (XmDSInfo) GetDSParent(info); Widget w; int i, n; XmDSInfo child; XmAnimationDataRec animationData; static XmRegion dsRegion = (XmRegion) NULL; static XmRegion clipRegion = (XmRegion) NULL; static XmRegion tmpRegion = (XmRegion) NULL; Widget dc = dsm->dropManager.curDragContext; Boolean sourceIsExternal; Dimension bw = 0; Arg args[1]; if (GetDSAnimationStyle(info) == XmDRAG_UNDER_NONE) return; /* * Should we have saved this from the last top level enter? */ n = 0; XtSetArg(args[n], XmNsourceIsExternal, &sourceIsExternal); n++; XtGetValues(dc, args, n); _XmProcessLock(); if (dsRegion == NULL) { dsRegion = _XmRegionCreate(); clipRegion = _XmRegionCreate(); tmpRegion = _XmRegionCreate(); } _XmProcessUnlock(); if (sourceIsExternal) { animationData.dragOver = NULL; /* * The window is expected to the the shell window which will be * drawn in with include inferiors. */ animationData.window = XtWindow(GetDSWidget( dsm->dropManager.dsRoot)); animationData.screen = XtScreen(GetDSWidget( dsm->dropManager.dsRoot)); } else { animationData.dragOver = motionData->dragOver; animationData.window = motionData->window; animationData.screen = XtScreen(motionData->dragOver); } animationData.windowX = dsm->dropManager.rootX; animationData.windowY = dsm->dropManager.rootY; animationData.saveAddr = (XtPointer) &(dsm->dropManager.dragUnderData); /* We're going to need a copy. */ _XmProcessLock(); _XmRegionUnion(GetDSRegion(info), GetDSRegion(info), dsRegion); _XmProcessUnlock(); bw = GetDSBorderWidth(info); if (!GetDSRemote(info)) { Position wX, wY; w = GetDSWidget(info); XtTranslateCoords(w, 0, 0, &wX, &wY); _XmProcessLock(); _XmRegionOffset(dsRegion, (wX - dsm->dropManager.rootX), (wY - dsm->dropManager.rootY)); _XmProcessUnlock(); } /* All drawing occurs within the drop site */ _XmProcessLock(); _XmRegionUnion(dsRegion, dsRegion, clipRegion); _XmProcessUnlock(); if (bw && !GetDSHasRegion(info)) { /* * The region is stored widget relative, and it represents * the entire drop-sensitive area of the drop site. In the * case that we provided the region this includes the * border area (the x,y position of the bounding box is * negative), however, we don't animate the entire * sensitive region; we only animate the sensitive region * within the border. Sooo, if we provided the region, and * the widget has a border, shrink down the region * (which will offset it) before passing it on to the * animation code. */ _XmProcessLock(); _XmRegionShrink(clipRegion, bw, bw); _XmProcessUnlock(); } /* * trim off anything clipped by ancestors * ancestorClip region is in shell relative coordinates. */ _XmProcessLock(); _XmRegionIntersect(clipRegion, dsm->dropManager.curAncestorClipRegion, clipRegion); _XmProcessUnlock(); /* trim off anything obsucred by a sibling stacked above us */ if (parentInfo != NULL) { for (i = 0; i < (int)GetDSNumChildren(parentInfo); i++) { child = (XmDSInfo) GetDSChild(parentInfo, i); if (child == info) break; else { if (GetDSRemote(child)) { /* * Non-local case. The info region is in shell * relative coordinates. */ _XmProcessLock(); _XmRegionSubtract(clipRegion, GetDSRegion(child), clipRegion); _XmProcessUnlock(); } else { /* * Local case. We have to translate the region. */ Position wX, wY; Widget sibling = GetDSWidget(child); XtTranslateCoords(sibling, 0, 0, &wX, &wY); _XmProcessLock(); _XmRegionUnion(GetDSRegion(child), GetDSRegion(child), tmpRegion); _XmRegionOffset(tmpRegion, (wX - dsm->dropManager.rootX), (wY - dsm->dropManager.rootY)); _XmRegionSubtract(clipRegion, tmpRegion, clipRegion); _XmProcessUnlock(); } } } } _XmProcessLock(); animationData.clipRegion = clipRegion; animationData.dropSiteRegion = dsRegion; _XmProcessUnlock(); _XmDragUnderAnimation((Widget)dsm, (XtPointer) &animationData, (XtPointer) callback); } /*ARGSUSED*/ static void ProxyDragProc( XmDropSiteManagerObject dsm, XtPointer client_data, XmDragProcCallbackStruct *callback ) { XmDSInfo info = (XmDSInfo) dsm->dropManager.curInfo; XmDragContext dc = (XmDragContext) callback->dragContext; Atom *import_targets = NULL, *export_targets = NULL; Cardinal num_import = 0, num_export = 0; int n; Arg args[10]; Widget shell; unsigned char operations; operations = callback->operations & GetDSOperations(info); if (XmDROP_MOVE & operations) callback->operation = XmDROP_MOVE; else if (XmDROP_COPY & operations) callback->operation = XmDROP_COPY; else if (XmDROP_LINK & operations) callback->operation = XmDROP_LINK; else callback->operation = XmDROP_NOOP; n = 0; XtSetArg(args[n], XmNexportTargets, &export_targets); n++; XtSetArg(args[n], XmNnumExportTargets, &num_export); n++; XtGetValues ((Widget)dc, args, n); if (GetDSRemote(info)) shell = XtParent(dsm); else shell = GetDSWidget(info); while (!XtIsShell(shell)) shell = XtParent(shell); num_import = _XmIndexToTargets(shell, GetDSImportTargetsID(info), &import_targets); if ((callback->operation != XmDROP_NOOP) && (XmTargetsAreCompatible (XtDisplay (dsm), export_targets, num_export, import_targets, num_import))) callback->dropSiteStatus = XmVALID_DROP_SITE; else callback->dropSiteStatus = XmINVALID_DROP_SITE; callback->animate = True; } /*ARGSUSED*/ static void HandleEnter( XmDropSiteManagerObject dsm, XmDragMotionClientData motionData, XmDragMotionCallbackStruct *callback, XmDSInfo info, #if NeedWidePrototypes unsigned int style ) /* unused */ #else unsigned char style ) #endif /* NeedWidePrototypes */ { XmDragProcCallbackStruct cbRec; Position tmpX, tmpY; XRectangle extents; cbRec.reason = XmCR_DROP_SITE_ENTER_MESSAGE; cbRec.event = (XEvent *) NULL; cbRec.timeStamp = callback->timeStamp; cbRec.dragContext = dsm->dropManager.curDragContext; cbRec.x = dsm->dropManager.curX; cbRec.y = dsm->dropManager.curY; cbRec.dropSiteStatus = XmVALID_DROP_SITE; cbRec.operations = callback->operations; cbRec.operation = callback->operation; cbRec.animate = True; ProxyDragProc(dsm, NULL, &cbRec); if ((!GetDSRemote(info)) && (GetDSDragProc(info) != NULL)) { Widget widget = GetDSWidget(info); /* Return if this is not a managed widget, CR5215 */ if (! XtIsManaged(widget)) return; /* Make the coordinates widget relative */ XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY); cbRec.x -= tmpX; cbRec.y -= tmpY; (*(GetDSDragProc(info))) (widget, NULL, (XtPointer) &cbRec); } if ((cbRec.animate) && (cbRec.dropSiteStatus == XmVALID_DROP_SITE)) DoAnimation(dsm, motionData, (XtPointer) &cbRec); dsm->dropManager.curDropSiteStatus = cbRec.dropSiteStatus; dsm->dropManager.curAnimate = cbRec.animate; dsm->dropManager.curOperations = cbRec.operations; dsm->dropManager.curOperation = cbRec.operation; if (dsm->dropManager.notifyProc) { XmDropSiteEnterCallbackStruct outCB; _XmRegionGetExtents(GetDSRegion(info), &extents); outCB.reason = XmCR_DROP_SITE_ENTER; outCB.event = NULL; outCB.timeStamp = cbRec.timeStamp; outCB.dropSiteStatus = cbRec.dropSiteStatus; outCB.operations = cbRec.operations; outCB.operation = cbRec.operation; /* * Pass outCB.x and outCB.y as the root relative position * of the entered drop site. Remote info's are already * in shell coordinates; Local info's are in widget * relative coordinates. */ if (GetDSRemote(info)) { outCB.x = extents.x + dsm->dropManager.rootX; outCB.y = extents.y + dsm->dropManager.rootY; } else { Widget widget = GetDSWidget(info); XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY); outCB.x = extents.x + tmpX; outCB.y = extents.y + tmpY; } (*(dsm->dropManager.notifyProc)) ((Widget)dsm, dsm->dropManager.client_data, (XtPointer) &outCB); } } /*ARGSUSED*/ static void HandleMotion( XmDropSiteManagerObject dsm, XmDragMotionClientData motionData, XmDragMotionCallbackStruct *callback, XmDSInfo info, #if NeedWidePrototypes unsigned int style ) #else unsigned char style ) #endif /* NeedWidePrototypes */ { XmDragProcCallbackStruct cbRec; cbRec.reason = XmCR_DROP_SITE_MOTION_MESSAGE; cbRec.event = (XEvent *) NULL; cbRec.timeStamp = callback->timeStamp; cbRec.dragContext = dsm->dropManager.curDragContext; cbRec.x = dsm->dropManager.curX; cbRec.y = dsm->dropManager.curY; cbRec.animate = dsm->dropManager.curAnimate; cbRec.dropSiteStatus = dsm->dropManager.curDropSiteStatus; if (info != NULL) { cbRec.operations = dsm->dropManager.curOperations; cbRec.operation = dsm->dropManager.curOperation; if ( (!GetDSRemote(info)) && (GetDSDragProc(info) != NULL)) { Widget widget = GetDSWidget(info); Position tmpX, tmpY; /* Return if this is not a managed widget */ if (! XtIsManaged(widget)) return; /* Make the coordinates widget relative */ XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY); cbRec.x -= tmpX; cbRec.y -= tmpY; (*(GetDSDragProc(info))) (widget, NULL, (XtPointer) &cbRec); } if ((cbRec.animate) && (cbRec.dropSiteStatus != dsm->dropManager.curDropSiteStatus)) { if (cbRec.dropSiteStatus == XmVALID_DROP_SITE) cbRec.reason = XmCR_DROP_SITE_ENTER; else cbRec.reason = XmCR_DROP_SITE_LEAVE; DoAnimation(dsm, motionData, (XtPointer) &cbRec); cbRec.reason = XmCR_DROP_SITE_MOTION_MESSAGE; } dsm->dropManager.curDropSiteStatus = cbRec.dropSiteStatus; dsm->dropManager.curAnimate = cbRec.animate; dsm->dropManager.curOperations = cbRec.operations; dsm->dropManager.curOperation = cbRec.operation; } else { cbRec.operations = callback->operations; cbRec.operation = callback->operation; cbRec.dropSiteStatus = XmNO_DROP_SITE; } if (dsm->dropManager.notifyProc) { XmDragMotionCallbackStruct outCB; outCB.reason = XmCR_DRAG_MOTION; outCB.event = NULL; outCB.timeStamp = cbRec.timeStamp; outCB.dropSiteStatus = cbRec.dropSiteStatus; outCB.x = dsm->dropManager.curX; outCB.y = dsm->dropManager.curY; outCB.operations = cbRec.operations; outCB.operation = cbRec.operation; (*(dsm->dropManager.notifyProc)) ((Widget)dsm, dsm->dropManager.client_data, (XtPointer)&outCB); } } /*ARGSUSED*/ static void HandleLeave( XmDropSiteManagerObject dsm, XmDragMotionClientData motionData, XmDragMotionCallbackStruct *callback, XmDSInfo info, #if NeedWidePrototypes unsigned int style, /* unused */ int enterPending ) #else unsigned char style, Boolean enterPending ) #endif /* NeedWidePrototypes */ { XmDragProcCallbackStruct cbRec; cbRec.reason = XmCR_DROP_SITE_LEAVE_MESSAGE; cbRec.event = (XEvent *) NULL; cbRec.timeStamp = callback->timeStamp; cbRec.dragContext = dsm->dropManager.curDragContext; cbRec.x = dsm->dropManager.oldX; cbRec.y = dsm->dropManager.oldY; cbRec.operations = callback->operations; cbRec.operation = callback->operation; cbRec.animate = dsm->dropManager.curAnimate; cbRec.dropSiteStatus = dsm->dropManager.curDropSiteStatus; if ( (!GetDSRemote(info) && (GetDSDragProc(info) != NULL))) { Widget widget = GetDSWidget(info); Position tmpX, tmpY; /* Make the coordinates widget relative */ XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY); cbRec.x -= tmpX; cbRec.y -= tmpY; (*(GetDSDragProc(info))) (widget, NULL, (XtPointer) &cbRec); } if ((cbRec.animate) && (cbRec.dropSiteStatus == XmVALID_DROP_SITE)) DoAnimation(dsm, motionData, (XtPointer) &cbRec); if (dsm->dropManager.notifyProc) { XmDropSiteEnterPendingCallbackStruct outCB; outCB.reason = XmCR_DROP_SITE_LEAVE; outCB.event = callback->event; outCB.timeStamp = cbRec.timeStamp; outCB.enter_pending = enterPending; (*(dsm->dropManager.notifyProc)) ((Widget)dsm, dsm->dropManager.client_data, (XtPointer)&outCB); } } /*ARGSUSED*/ static void ProcessMotion( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer calldata ) { XmDragMotionCallbackStruct *callback = (XmDragMotionCallbackStruct *) calldata; XmDragMotionClientData motionData = (XmDragMotionClientData) clientData; Position x = callback->x, y = callback->y; XmDSInfo dsRoot = (XmDSInfo) (dsm->dropManager.dsRoot); XmDSInfo curDSInfo = (XmDSInfo)(dsm->dropManager.curInfo); XmDSInfo newDSInfo; unsigned char style; if (dsm->dropManager.curDragContext == NULL) { XmeWarning((Widget)dsm, MESSAGE2); return; } style = _XmGetActiveProtocolStyle(dsm->dropManager.curDragContext); dsm->dropManager.curTime = callback->timeStamp; dsm->dropManager.oldX = dsm->dropManager.curX; dsm->dropManager.oldY = dsm->dropManager.curY; dsm->dropManager.curX = x; dsm->dropManager.curY = y; if (dsRoot) { /* * Make x and y shell relative, preregister info's are shell * relative, and CalculateAncestorClip (called for dynammic) * returns a shell relative rectangle. */ x -= dsm->dropManager.rootX; y -= dsm->dropManager.rootY; newDSInfo = PointToDSInfo(dsm, dsRoot, x, y); if (curDSInfo != newDSInfo) { if (curDSInfo) { /* if we are entering a drop site as we leave * the old drop site, we don't want to set * the drop site status to NO_DROP_SITE. We * are using the event field of the callback * (since is is guarenteed to be NULL) for * use as a flag, since we can't modify the * public callback struct. */ if (newDSInfo) HandleLeave(dsm, motionData, callback, curDSInfo, style, True); else HandleLeave(dsm, motionData, callback, curDSInfo, style, False); } dsm->dropManager.curInfo = (XtPointer) newDSInfo; _XmRegionUnion(dsm->dropManager.newAncestorClipRegion, dsm->dropManager.newAncestorClipRegion, dsm->dropManager.curAncestorClipRegion); if (newDSInfo) HandleEnter(dsm, motionData, callback, newDSInfo, style); return; } } HandleMotion(dsm, motionData, callback, curDSInfo, style); } /*ARGSUSED*/ static void ProcessDrop( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer cb ) { XmDragTopLevelClientData cd = (XmDragTopLevelClientData) clientData; XmDropStartCallbackStruct *callback = (XmDropStartCallbackStruct *) cb; XmDropProcCallbackStruct cbRec; Widget dragContext = XmGetDragContext((Widget)dsm, callback->timeStamp); XmDSInfo info = NULL; Widget widget; Position x, y, tmpX, tmpY; XmDSInfo savRoot, savInfo; XmDSInfo newRoot = (XmDSInfo) DSMWidgetToInfo(dsm, cd->destShell); Position savX, savY; Dimension savW, savH; Time savTime; if (dragContext == NULL) { /* * Can't do a failure transfer. Just give up. * * Should we send a warning message? */ return; } /* * Look out for race conditions. * * This should be enough state saving to allow the drop to occur * in the middle of some other drag. */ savRoot = (XmDSInfo) dsm->dropManager.dsRoot; savInfo = (XmDSInfo) dsm->dropManager.curInfo; savX = dsm->dropManager.rootX; savY = dsm->dropManager.rootY; savW = dsm->dropManager.rootW; savH = dsm->dropManager.rootH; savTime = dsm->dropManager.curTime; dsm->dropManager.curTime = callback->timeStamp; dsm->dropManager.dsRoot = (XtPointer) newRoot; dsm->dropManager.rootX = cd->xOrigin; dsm->dropManager.rootY = cd->yOrigin; dsm->dropManager.rootW = cd->width; dsm->dropManager.rootH = cd->height; x = callback->x - dsm->dropManager.rootX; y = callback->y - dsm->dropManager.rootY; if (newRoot != NULL) info = PointToDSInfo(dsm, (XmDSInfo) dsm->dropManager.dsRoot, x, y); if (info != NULL) widget = GetDSWidget(info); /* Handle error conditions nicely */ if ((info == NULL) || ! XtIsManaged(widget) || /* CR 5215 */ /* These are wierd conditions */ (newRoot == NULL) || (GetDSRemote(info)) || (GetDSDropProc(info) == NULL)) { /* we will do a failure drop transfer */ Arg args[4]; Cardinal i = 0; XtSetArg(args[i], XmNtransferStatus, XmTRANSFER_FAILURE); i++; XtSetArg(args[i], XmNnumDropTransfers, 0); i++; (void) XmDropTransferStart(dragContext, args, i); /* ??? * Should we do something interesting with the callback * struct before calling notify in these cases? * ??? */ } else { /* This will be needed by the ProxyDragProc */ dsm->dropManager.curInfo = (XtPointer) info; /* Make the coordinates widget relative */ XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY); /* Load the dropProcStruct */ cbRec.reason = XmCR_DROP_MESSAGE; cbRec.event = callback->event; cbRec.timeStamp = callback->timeStamp; cbRec.dragContext = dragContext; /* Make the coordinates widget relative */ XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY); cbRec.x = callback->x - tmpX; cbRec.y = callback->y - tmpY; { /* Nonsense to pre-load the cbRec correctly */ XmDragProcCallbackStruct junkRec; junkRec.reason = XmCR_DROP_SITE_MOTION_MESSAGE; junkRec.event = callback->event; junkRec.timeStamp = cbRec.timeStamp; junkRec.dragContext = dragContext; junkRec.x = cbRec.x; junkRec.y = cbRec.y; junkRec.dropSiteStatus = dsm->dropManager.curDropSiteStatus; junkRec.operation = callback->operation; junkRec.operations = callback->operations; junkRec.animate = dsm->dropManager.curAnimate; ProxyDragProc(dsm, NULL, &junkRec); cbRec.dropSiteStatus = junkRec.dropSiteStatus; cbRec.operation = junkRec.operation; cbRec.operations = junkRec.operations; } cbRec.dropAction = callback->dropAction; /* Call the drop site's drop proc */ (*(GetDSDropProc(info))) (widget, NULL, (XtPointer) &cbRec); callback->operation = cbRec.operation; callback->operations = cbRec.operations; callback->dropSiteStatus = cbRec.dropSiteStatus; callback->dropAction = cbRec.dropAction; } if (dsm->dropManager.notifyProc) { (*(dsm->dropManager.notifyProc)) ((Widget)dsm, dsm->dropManager.client_data, (XtPointer)callback); } dsm->dropManager.dsRoot = (XtPointer) savRoot; dsm->dropManager.curInfo = (XtPointer) savInfo; dsm->dropManager.rootX = savX; dsm->dropManager.rootY = savY; dsm->dropManager.rootW = savW; dsm->dropManager.rootH = savH; dsm->dropManager.curTime = savTime; } /*ARGSUSED*/ static void ChangeOperation( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer calldata ) { XmOperationChangedCallbackStruct *callback = (XmOperationChangedCallbackStruct *) calldata; XmDragMotionClientData motionData = (XmDragMotionClientData) clientData; XmDragProcCallbackStruct cbRec; XmDSInfo info = (XmDSInfo) dsm->dropManager.curInfo; unsigned char style; if ((cbRec.dragContext = dsm->dropManager.curDragContext) == NULL) { XmeWarning((Widget)dsm, MESSAGE3); return; } else { style = _XmGetActiveProtocolStyle( dsm->dropManager.curDragContext); } cbRec.reason = callback->reason; cbRec.event = callback->event; cbRec.timeStamp = callback->timeStamp; cbRec.x = dsm->dropManager.curX; cbRec.y = dsm->dropManager.curY; cbRec.dropSiteStatus = dsm->dropManager.curDropSiteStatus; cbRec.animate = dsm->dropManager.curAnimate; cbRec.operation = callback->operation; cbRec.operations = callback->operations; if (info != NULL) { ProxyDragProc(dsm, NULL, &cbRec); if ((style == XmDRAG_DYNAMIC) && (!GetDSRemote(info)) && (GetDSDragProc(info) != NULL)) { Widget widget = GetDSWidget(info); Position tmpX, tmpY; /* Make the coordinates widget relative */ XtTranslateCoords(widget, 0, 0, &tmpX, &tmpY); cbRec.x -= tmpX; cbRec.y -= tmpY; (*(GetDSDragProc(info))) (widget, NULL, (XtPointer) &cbRec); } if ((cbRec.animate) && (cbRec.dropSiteStatus != dsm->dropManager.curDropSiteStatus)) { if (cbRec.dropSiteStatus == XmVALID_DROP_SITE) cbRec.reason = XmCR_DROP_SITE_ENTER_MESSAGE; else cbRec.reason = XmCR_DROP_SITE_LEAVE_MESSAGE; DoAnimation(dsm, motionData, (XtPointer) &cbRec); cbRec.reason = callback->reason; } /* Update the callback rec */ callback->operations = cbRec.operations; callback->operation = cbRec.operation; callback->dropSiteStatus = cbRec.dropSiteStatus; /* Update the drop site manager */ dsm->dropManager.curDropSiteStatus = cbRec.dropSiteStatus; dsm->dropManager.curAnimate = cbRec.animate; dsm->dropManager.curOperations = cbRec.operations; dsm->dropManager.curOperation = cbRec.operation; } else { callback->dropSiteStatus = XmNO_DROP_SITE; } if (dsm->dropManager.notifyProc) { (*(dsm->dropManager.notifyProc)) ((Widget)dsm, dsm->dropManager.client_data, (XtPointer)callback); } } /*ARGSUSED*/ static void PutDSToStream( XmDropSiteManagerObject dsm, XmDSInfo dsInfo, #if NeedWidePrototypes int last, #else Boolean last, #endif /* NeedWidePrototypes */ XtPointer dataPtr ) { static XmRegion tmpRegion = NULL; unsigned char dsType = 0, tType = 0; unsigned char unitType = XmPIXELS; Position wX, wY; Widget w = GetDSWidget(dsInfo); Dimension bw = XtBorderWidth(w); XmICCDropSiteInfoStruct iccInfo; Arg args[30]; int n; _XmProcessLock(); if (tmpRegion == NULL) { tmpRegion = _XmRegionCreate(); } _XmProcessUnlock(); /* * Clear out the info. This is especially important in the cases * that the widget does not define resources all of the required * animation resources. */ bzero(((void *) &iccInfo), sizeof(iccInfo)); if (last) tType |= XmDSM_T_CLOSE; else tType &= ~ XmDSM_T_CLOSE; if (GetDSLeaf(dsInfo) || (!GetDSNumChildren(dsInfo))) dsType |= XmDSM_DS_LEAF; else dsType &= ~ XmDSM_DS_LEAF; if (GetDSInternal(dsInfo)) dsType |= XmDSM_DS_INTERNAL; else dsType &= ~ XmDSM_DS_INTERNAL; if (GetDSHasRegion(dsInfo)) dsType |= XmDSM_DS_HAS_REGION; else dsType &= ~ XmDSM_DS_HAS_REGION; /* * The local drop site tree is always kept in widget relative * coordinates. We have to put shell relative coordinates on * the wire however, so we to a copy and translate into a tmp * region. */ XtTranslateCoords(w, 0, 0, &wX, &wY); if (GetDSHasRegion(dsInfo)) { _XmProcessLock(); _XmRegionUnion(GetDSRegion(dsInfo), GetDSRegion(dsInfo), tmpRegion); _XmProcessUnlock(); } else { XRectangle rect; rect.x = rect.y = -bw; rect.width = XtWidth(w) + (2 * bw); rect.height = XtHeight(w) + (2 * bw); _XmProcessLock(); _XmRegionClear(tmpRegion); _XmRegionUnionRectWithRegion(&rect, tmpRegion, tmpRegion); _XmProcessUnlock(); } _XmProcessLock(); _XmRegionOffset(tmpRegion, (wX - dsm->dropManager.rootX), (wY - dsm->dropManager.rootY)); _XmProcessUnlock(); /* * We need to pull up the relevant visual information from * the widget so it will be available for correct animation * by a non-local peregister initiator. */ iccInfo.header.dropType = dsType; iccInfo.header.dropActivity = GetDSActivity(dsInfo); iccInfo.header.traversalType = tType; iccInfo.header.animationStyle = GetDSAnimationStyle(dsInfo); iccInfo.header.operations = GetDSOperations(dsInfo); iccInfo.header.importTargetsID = GetDSImportTargetsID(dsInfo); _XmProcessLock(); iccInfo.header.region = tmpRegion; _XmProcessUnlock(); /* * We need to retrieve information from the widget. XtGetValues is * too slow, so retrieve the information directly from the widget * instance. * * XtGetValues is used for non-Motif widgets, just in case they provide * Motif-style resources. * * (See also XmDropSiteGetActiveVisuals() ) */ if (XmIsPrimitive(w)) { XmPrimitiveWidget pw= (XmPrimitiveWidget)w; switch(iccInfo.header.animationStyle) { case XmDRAG_UNDER_HIGHLIGHT: { XmICCDropSiteHighlight info = (XmICCDropSiteHighlight) (&iccInfo); info->animation_data.highlightPixmap = XmUNSPECIFIED_PIXMAP; if (!GetDSHasRegion(dsInfo)) info->animation_data.borderWidth = pw->core.border_width; info->animation_data.highlightThickness = pw->primitive.highlight_thickness; info->animation_data.highlightColor = pw->primitive.highlight_color; info->animation_data.highlightPixmap = pw->primitive.highlight_pixmap; info->animation_data.background = pw->core.background_pixel; } break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: { XmICCDropSiteShadow info = (XmICCDropSiteShadow) (&iccInfo); info->animation_data.topShadowPixmap = info->animation_data.bottomShadowPixmap = XmUNSPECIFIED_PIXMAP; if (!GetDSHasRegion(dsInfo)) info->animation_data.borderWidth = pw->core.border_width; info->animation_data.highlightThickness = pw->primitive.highlight_thickness; info->animation_data.shadowThickness = pw->primitive.shadow_thickness; info->animation_data.foreground = pw->primitive.foreground; info->animation_data.topShadowColor = pw->primitive.top_shadow_color; info->animation_data.topShadowPixmap = pw->primitive.top_shadow_pixmap; info->animation_data.bottomShadowColor = pw->primitive.bottom_shadow_color; info->animation_data.bottomShadowPixmap = pw->primitive.bottom_shadow_pixmap; } break; case XmDRAG_UNDER_PIXMAP: { XmICCDropSitePixmap info = (XmICCDropSitePixmap) (&iccInfo); XmDSLocalPixmapStyle ps = (XmDSLocalPixmapStyle) GetDSLocalAnimationPart(dsInfo); info->animation_data.animationPixmapDepth = ps->animation_pixmap_depth; info->animation_data.animationPixmap = ps->animation_pixmap; info->animation_data.animationMask = ps->animation_mask; if (!GetDSHasRegion(dsInfo)) info->animation_data.borderWidth = pw->core.border_width; info->animation_data.highlightThickness = pw->primitive.highlight_thickness; info->animation_data.shadowThickness = pw->primitive.shadow_thickness; info->animation_data.foreground = pw->primitive.foreground; info->animation_data.background = pw->core.background_pixel; } break; case XmDRAG_UNDER_NONE: { XmICCDropSiteNone info = (XmICCDropSiteNone) (&iccInfo); if (!GetDSHasRegion(dsInfo)) info->animation_data.borderWidth = pw->core.border_width; else info->animation_data.borderWidth = 0; } default: { /*EMPTY*/ } break; } } else if (XmIsManager(w) || XmIsGadget(w)) { XmManagerWidget mw; XmGadget g; Boolean is_gadget; if (XmIsGadget(w)) { mw = (XmManagerWidget) XtParent(w); g = (XmGadget) w; is_gadget = True; } else { mw = (XmManagerWidget) w; g = NULL; is_gadget = False; } switch(iccInfo.header.animationStyle) { case XmDRAG_UNDER_HIGHLIGHT: { XmICCDropSiteHighlight info = (XmICCDropSiteHighlight) (&iccInfo); info->animation_data.highlightPixmap = XmUNSPECIFIED_PIXMAP; if (!GetDSHasRegion(dsInfo)) { if (is_gadget) info->animation_data.borderWidth = w->core.border_width; else info->animation_data.borderWidth = mw->core.border_width; } /* Temporary hack until we support full defaulting */ info->animation_data.highlightThickness = 1; info->animation_data.highlightColor = mw->manager.highlight_color; info->animation_data.highlightPixmap = mw->manager.highlight_pixmap; info->animation_data.background = mw->core.background_pixel; } break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: { XmICCDropSiteShadow info = (XmICCDropSiteShadow) (&iccInfo); info->animation_data.topShadowPixmap = info->animation_data.bottomShadowPixmap = XmUNSPECIFIED_PIXMAP; if (is_gadget) { if (!GetDSHasRegion(dsInfo)) info->animation_data.borderWidth = w->core.border_width; info->animation_data.shadowThickness = g->gadget.shadow_thickness; } else { if (!GetDSHasRegion(dsInfo)) info->animation_data.borderWidth = mw->core.border_width; info->animation_data.shadowThickness = mw->manager.shadow_thickness; } info->animation_data.highlightThickness = 0; info->animation_data.foreground = mw->manager.foreground; info->animation_data.topShadowColor = mw->manager.top_shadow_color; info->animation_data.topShadowPixmap = mw->manager.top_shadow_pixmap; info->animation_data.bottomShadowColor = mw->manager.bottom_shadow_color; info->animation_data.bottomShadowPixmap = mw->manager.bottom_shadow_pixmap; } break; case XmDRAG_UNDER_PIXMAP: { XmICCDropSitePixmap info = (XmICCDropSitePixmap) (&iccInfo); XmDSLocalPixmapStyle ps = (XmDSLocalPixmapStyle) GetDSLocalAnimationPart(dsInfo); info->animation_data.animationPixmapDepth = ps->animation_pixmap_depth; info->animation_data.animationPixmap = ps->animation_pixmap; info->animation_data.animationMask = ps->animation_mask; if (is_gadget) { if (!GetDSHasRegion(dsInfo)) info->animation_data.borderWidth = w->core.border_width; info->animation_data.shadowThickness = g->gadget.shadow_thickness; } else { if (!GetDSHasRegion(dsInfo)) info->animation_data.borderWidth = mw->core.border_width; info->animation_data.shadowThickness = mw->manager.shadow_thickness; } info->animation_data.highlightThickness = 0; info->animation_data.foreground = mw->manager.foreground; info->animation_data.background = mw->core.background_pixel; } break; case XmDRAG_UNDER_NONE: { XmICCDropSiteNone info = (XmICCDropSiteNone) (&iccInfo); if (!GetDSHasRegion(dsInfo)) { if (is_gadget) info->animation_data.borderWidth = w->core.border_width; else info->animation_data.borderWidth = mw->core.border_width; } else info->animation_data.borderWidth = 0; } default: { /*EMPTY*/ } break; } } else /* non-Motif subclass */ { n = 0; XtSetArg(args[n], XmNunitType, &unitType); n++; XtGetValues(w, args, n); if (unitType != XmPIXELS) { /* we need values in pixels */ n = 0; XtSetArg(args[n], XmNunitType, XmPIXELS); n++; XtSetValues(w, args, n); } switch(iccInfo.header.animationStyle) { case XmDRAG_UNDER_HIGHLIGHT: { XmICCDropSiteHighlight info = (XmICCDropSiteHighlight) (&iccInfo); /* * Pre-load a sane pixmap default in case the * widget doesn't have a pixmap resource. */ info->animation_data.highlightPixmap = XmUNSPECIFIED_PIXMAP; n = 0; if (!GetDSHasRegion(dsInfo)) { XtSetArg(args[n], XmNborderWidth, &(info->animation_data.borderWidth)); n++; } XtSetArg(args[n], XmNhighlightThickness, &(info->animation_data.highlightThickness)); n++; XtSetArg(args[n], XmNbackground, &(info->animation_data.background)); n++; XtSetArg(args[n], XmNhighlightColor, &(info->animation_data.highlightColor)); n++; XtSetArg(args[n], XmNhighlightPixmap, &(info->animation_data.highlightPixmap)); n++; XtGetValues(w, args, n); } break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: { XmICCDropSiteShadow info = (XmICCDropSiteShadow) (&iccInfo); /* Pre-load some sane pixmap defaults */ info->animation_data.topShadowPixmap = info->animation_data.bottomShadowPixmap = XmUNSPECIFIED_PIXMAP; n = 0; if (!GetDSHasRegion(dsInfo)) { XtSetArg(args[n], XmNborderWidth, &(info->animation_data.borderWidth)); n++; } XtSetArg(args[n], XmNhighlightThickness, &(info->animation_data.highlightThickness)); n++; XtSetArg(args[n], XmNshadowThickness, &(info->animation_data.shadowThickness)); n++; XtSetArg(args[n], XmNforeground, &(info->animation_data.foreground)); n++; XtSetArg(args[n], XmNtopShadowColor, &(info->animation_data.topShadowColor)); n++; XtSetArg(args[n], XmNbottomShadowColor, &(info->animation_data.bottomShadowColor)); n++; XtSetArg(args[n], XmNtopShadowPixmap, &(info->animation_data.topShadowPixmap)); n++; XtSetArg(args[n], XmNbottomShadowPixmap, &(info->animation_data.bottomShadowPixmap)); n++; XtGetValues(w, args, n); } break; case XmDRAG_UNDER_PIXMAP: { XmICCDropSitePixmap info = (XmICCDropSitePixmap) (&iccInfo); XmDSLocalPixmapStyle ps = (XmDSLocalPixmapStyle) GetDSLocalAnimationPart(dsInfo); info->animation_data.animationPixmapDepth = ps->animation_pixmap_depth; info->animation_data.animationPixmap = ps->animation_pixmap; info->animation_data.animationMask = ps->animation_mask; n = 0; if (!GetDSHasRegion(dsInfo)) { XtSetArg(args[n], XmNborderWidth, &(info->animation_data.borderWidth)); n++; } XtSetArg(args[n], XmNhighlightThickness, &(info->animation_data.highlightThickness)); n++; XtSetArg(args[n], XmNshadowThickness, &(info->animation_data.shadowThickness)); n++; XtSetArg(args[n], XmNforeground, &(info->animation_data.foreground)); n++; XtSetArg(args[n], XmNbackground, &(info->animation_data.background)); n++; XtGetValues(w, args, n); } break; case XmDRAG_UNDER_NONE: { XmICCDropSiteNone info = (XmICCDropSiteNone) (&iccInfo); if (!GetDSHasRegion(dsInfo)) { n = 0; XtSetArg(args[n], XmNborderWidth, &(info->animation_data.borderWidth)); n++; XtGetValues(w, args, n); } else info->animation_data.borderWidth = 0; } default: { /*EMPTY*/ } break; } if (unitType != XmPIXELS) { n = 0; XtSetArg(args[n], XmNunitType, unitType); n++; XtSetValues(w, args, n); } } _XmWriteDSToStream(dsm, dataPtr, &iccInfo); } /*ARGSUSED*/ static void GetDSFromDSM( XmDropSiteManagerObject dsm, XmDSInfo parentInfo, #if NeedWidePrototypes int last, #else Boolean last, #endif /* NeedWidePrototypes */ XtPointer dataPtr ) { XmDSInfo child; int i; PutDSToStream(dsm, parentInfo, last, dataPtr); last = False; for (i = 0; i < (int)GetDSNumChildren(parentInfo); i++) { if ((i + 1) == GetDSNumChildren(parentInfo)) last = True; child = (XmDSInfo) GetDSChild(parentInfo, i); if (!GetDSLeaf(child)) GetDSFromDSM(dsm, child, last, dataPtr); else PutDSToStream(dsm, child, last, dataPtr); } } /*ARGSUSED*/ static int GetTreeFromDSM( XmDropSiteManagerObject dsm, Widget shell, XtPointer dataPtr ) { XmDSInfo root = (XmDSInfo) DSMWidgetToInfo(dsm, shell); Position shellX, shellY, savX, savY; if (root == NULL) return(0); XtTranslateCoords(shell, 0, 0, &shellX, &shellY); /* Save current */ savX = dsm->dropManager.rootX; savY = dsm->dropManager.rootY; dsm->dropManager.rootX = shellX; dsm->dropManager.rootY = shellY; DSMSyncTree(dsm, shell); GetDSFromDSM(dsm, root, True, dataPtr); dsm->dropManager.rootX = savX; dsm->dropManager.rootY = savY; return(CountDropSites(root)); } /*ARGSUSED*/ static XmDSInfo GetDSFromStream( XmDropSiteManagerObject dsm, XtPointer dataPtr, Boolean *close, unsigned char *type ) { XmDSInfo info; XmICCDropSiteInfoStruct iccInfo; size_t size; _XmReadDSFromStream(dsm, dataPtr, &iccInfo); switch(iccInfo.header.animationStyle) { case XmDRAG_UNDER_HIGHLIGHT: if (iccInfo.header.dropType & XmDSM_DS_LEAF) size = sizeof(XmDSRemoteHighlightLeafRec); else size = sizeof(XmDSRemoteHighlightNodeRec); break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: if (iccInfo.header.dropType & XmDSM_DS_LEAF) size = sizeof(XmDSRemoteShadowLeafRec); else size = sizeof(XmDSRemoteShadowNodeRec); break; case XmDRAG_UNDER_PIXMAP: if (iccInfo.header.dropType & XmDSM_DS_LEAF) size = sizeof(XmDSRemotePixmapLeafRec); else size = sizeof(XmDSRemotePixmapNodeRec); break; case XmDRAG_UNDER_NONE: if (iccInfo.header.dropType & XmDSM_DS_LEAF) size = sizeof(XmDSRemoteNoneLeafRec); else size = sizeof(XmDSRemoteNoneNodeRec); break; default: if (iccInfo.header.dropType & XmDSM_DS_LEAF) size = sizeof(XmDSRemoteNoneLeafRec); else size = sizeof(XmDSRemoteNoneNodeRec); break; } info = (XmDSInfo) XtCalloc(1, size); /* Load the Status fields */ SetDSRemote(info, True); if (iccInfo.header.dropType & XmDSM_DS_LEAF) { SetDSLeaf(info, True); SetDSType(info, XmDROP_SITE_SIMPLE); } else { SetDSLeaf(info, False); SetDSType(info, XmDROP_SITE_COMPOSITE); } SetDSAnimationStyle(info, iccInfo.header.animationStyle); if (iccInfo.header.dropType & XmDSM_DS_INTERNAL) SetDSInternal(info, True); else SetDSInternal(info, False); if (iccInfo.header.dropType & XmDSM_DS_HAS_REGION) SetDSHasRegion(info, True); else SetDSHasRegion(info, False); SetDSActivity(info, iccInfo.header.dropActivity); SetDSImportTargetsID(info, iccInfo.header.importTargetsID); SetDSOperations(info, iccInfo.header.operations); SetDSRegion(info, iccInfo.header.region); /* Load the animation data */ switch(GetDSAnimationStyle(info)) { case XmDRAG_UNDER_HIGHLIGHT: { XmDSRemoteHighlightStyle hs = (XmDSRemoteHighlightStyle) GetDSRemoteAnimationPart(info); XmICCDropSiteHighlight hi = (XmICCDropSiteHighlight) (&iccInfo); hs->highlight_color = hi->animation_data.highlightColor; hs->highlight_pixmap = hi->animation_data.highlightPixmap; hs->background = hi->animation_data.background; hs->highlight_thickness = hi->animation_data.highlightThickness; hs->border_width = hi->animation_data.borderWidth; } break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: { XmDSRemoteShadowStyle ss = (XmDSRemoteShadowStyle) GetDSRemoteAnimationPart(info); XmICCDropSiteShadow si = (XmICCDropSiteShadow) (&iccInfo); ss->top_shadow_color = si->animation_data.topShadowColor; ss->top_shadow_pixmap = si->animation_data.topShadowPixmap; ss->bottom_shadow_color = si->animation_data.bottomShadowColor; ss->bottom_shadow_pixmap = si->animation_data.bottomShadowPixmap; ss->foreground = si->animation_data.foreground; ss->shadow_thickness = si->animation_data.shadowThickness; ss->highlight_thickness = si->animation_data.highlightThickness; ss->border_width = si->animation_data.borderWidth; } break; case XmDRAG_UNDER_PIXMAP: { XmDSRemotePixmapStyle ps = (XmDSRemotePixmapStyle) GetDSRemoteAnimationPart(info); XmICCDropSitePixmap pi = (XmICCDropSitePixmap) (&iccInfo); ps->animation_pixmap = pi->animation_data.animationPixmap; ps->animation_pixmap_depth = pi->animation_data.animationPixmapDepth; ps->animation_mask = pi->animation_data.animationMask; ps->background = pi->animation_data.background; ps->foreground = pi->animation_data.foreground; ps->shadow_thickness = pi->animation_data.shadowThickness; ps->highlight_thickness = pi->animation_data.highlightThickness; ps->border_width = pi->animation_data.borderWidth; } break; case XmDRAG_UNDER_NONE: { XmDSRemoteNoneStyle ns = (XmDSRemoteNoneStyle) GetDSRemoteAnimationPart(info); XmICCDropSiteNone ni = (XmICCDropSiteNone) (&iccInfo); ns->border_width = ni->animation_data.borderWidth; } break; default: break; } *close = (iccInfo.header.traversalType & XmDSM_T_CLOSE); *type = iccInfo.header.dropType; return(info); } /*ARGSUSED*/ static void GetNextDS( XmDropSiteManagerObject dsm, XmDSInfo parentInfo, XtPointer dataPtr ) { Boolean close = TRUE; unsigned char type; XmDSInfo new_w = GetDSFromStream(dsm, dataPtr, &close, &type); while (!close) { AddDSChild(parentInfo, new_w, GetDSNumChildren(parentInfo)); if (! (type & XmDSM_DS_LEAF)) GetNextDS(dsm, new_w, dataPtr); new_w = GetDSFromStream(dsm, dataPtr, &close, &type); } AddDSChild(parentInfo, new_w, GetDSNumChildren(parentInfo)); if (! (type & XmDSM_DS_LEAF)) GetNextDS(dsm, new_w, dataPtr); } /*ARGSUSED*/ static XmDSInfo ReadTree( XmDropSiteManagerObject dsm, XtPointer dataPtr ) { Boolean junkb; unsigned char junkc; XmDSInfo root = GetDSFromStream(dsm, dataPtr, &junkb, &junkc); SetDSShell(root, True); GetNextDS(dsm, root, dataPtr); return root; } /*ARGSUSED*/ static void FreeDSTree( XmDSInfo tree ) { int i; XmDSInfo child; if (!GetDSLeaf(tree)) for (i = 0; i < (int)GetDSNumChildren(tree); i++) { child = (XmDSInfo) GetDSChild(tree, i); FreeDSTree(child); } DestroyDSInfo(tree, True); } static void ChangeRoot( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer callData ) { XmDragTopLevelClientData cd = (XmDragTopLevelClientData) clientData; XmTopLevelEnterCallback callback = (XmTopLevelEnterCallback) callData; Widget newRoot = cd->destShell; XtPointer dataPtr = cd->iccInfo; dsm->dropManager.curTime = callback->timeStamp; if (callback->reason == XmCR_TOP_LEVEL_ENTER) { /* * We assume that the drag context will not change without * a call to change the root. */ dsm->dropManager.curDragContext = (Widget) XmGetDragContext( (Widget)dsm, callback->timeStamp); if (newRoot) { dsm->dropManager.dsRoot = DSMWidgetToInfo(dsm, newRoot); /* * Do we need to do anything for prereg emulation of dyn? */ } else { dsm->dropManager.dsRoot = (XtPointer) ReadTree(dsm, dataPtr); } dsm->dropManager.rootX = cd->xOrigin; dsm->dropManager.rootY = cd->yOrigin; dsm->dropManager.rootW = cd->width; dsm->dropManager.rootH = cd->height; } else if (dsm->dropManager.dsRoot)/* XmCR_TOP_LEVEL_LEAVE */ { if (dsm->dropManager.curInfo != NULL) { XmDragMotionCallbackStruct cbRec ; XmDragMotionClientDataStruct cdRec ; unsigned char style = _XmGetActiveProtocolStyle( dsm->dropManager.curDragContext); /* Fake out a motion message from the DragC */ cbRec.reason = XmCR_DROP_SITE_LEAVE; cbRec.event = callback->event; cbRec.timeStamp = callback->timeStamp; cbRec.x = dsm->dropManager.curX; cbRec.y = dsm->dropManager.curY; /* These fields are irrelevant on a leave */ cbRec.operations = cbRec.operation = 0; cbRec.dropSiteStatus = 0; /* Need these too */ cdRec.window = cd->window; cdRec.dragOver = cd->dragOver; HandleLeave(dsm, &cdRec, &cbRec, (XmDSInfo) dsm->dropManager.curInfo, style, False); dsm->dropManager.curInfo = NULL; } if (GetDSRemote((XmDSInfo)(dsm->dropManager.dsRoot))) FreeDSTree((XmDSInfo)dsm->dropManager.dsRoot); /* Invalidate the root--force errors to show themselves */ dsm->dropManager.curDragContext = NULL; dsm->dropManager.dsRoot = (XtPointer) NULL; dsm->dropManager.rootX = (Position) -1; dsm->dropManager.rootY = (Position) -1; dsm->dropManager.rootW = 0; dsm->dropManager.rootH = 0; } } static int CountDropSites( XmDSInfo info ) { int i; XmDSInfo child; int acc = 1; if (!GetDSLeaf(info)) { for (i = 0; i < (int)GetDSNumChildren(info); i++) { child = (XmDSInfo) GetDSChild(info, i); acc += CountDropSites(child); } } return(acc); } /* This short resource list is used to initialize just the activity member. */ static XtResource mini_resources[] = { { XmNdropSiteActivity, XmCDropSiteActivity, XmRDropSiteActivity, sizeof(unsigned char), XtOffsetOf( struct _XmDSFullInfoRec, activity), XmRImmediate, (XtPointer) XmDROP_SITE_ACTIVE }, }; static void CreateInfo( XmDropSiteManagerObject dsm, Widget widget, ArgList args, Cardinal argCount ) { XmDSFullInfoRec fullInfoRec; XmDSInfo new_info, prev_info; XmRegion region = _XmRegionCreate(); Widget shell = widget; size_t size; /* zero out the working info struct */ bzero((void *)(&fullInfoRec), sizeof(fullInfoRec)); /* Load that puppy */ SetDSLeaf(&fullInfoRec, True); fullInfoRec.widget = widget; XtGetSubresources(widget, &fullInfoRec, NULL, NULL, _XmDSResources, _XmNumDSResources, args, argCount); /* Handle ignore first. */ if (fullInfoRec.activity == XmDROP_SITE_IGNORE) { return; } DSMStartUpdate(dsm, widget); /* Do some input validation */ if ((fullInfoRec.activity == XmDROP_SITE_ACTIVE) && (fullInfoRec.drop_proc == NULL)) { XmeWarning(widget, MESSAGE4); } if ((fullInfoRec.animation_style == XmDRAG_UNDER_PIXMAP) && (fullInfoRec.animation_pixmap != XmUNSPECIFIED_PIXMAP) && (fullInfoRec.animation_pixmap_depth == 0)) { /* * They didn't tell us the depth of the pixmaps. ask for it. */ XmeGetPixmapData(XtScreen(widget), fullInfoRec.animation_pixmap, NULL, (int*)&(fullInfoRec.animation_pixmap_depth), NULL, NULL, NULL, NULL, NULL, NULL); } if ((fullInfoRec.type == XmDROP_SITE_COMPOSITE) && ((fullInfoRec.rectangles != NULL) || (fullInfoRec.num_rectangles != 1))) { XmeWarning(widget, MESSAGE5); fullInfoRec.rectangles = NULL; fullInfoRec.num_rectangles = 1; } /* Handle the region*/ if (fullInfoRec.rectangles == NULL) { XRectangle rect; Dimension bw = XtBorderWidth(widget); rect.x = rect.y = -bw; rect.width = XtWidth(widget) + (2 * bw); rect.height = XtHeight(widget) + (2 * bw); _XmRegionUnionRectWithRegion(&rect, region, region); fullInfoRec.region = region; /* * Leave HasRegion == 0 indicating that we created this * region for the drop site. */ } else { int i; XRectangle *rects = fullInfoRec.rectangles; for (i=0; i < fullInfoRec.num_rectangles; i++) _XmRegionUnionRectWithRegion(&(rects[i]), region, region); fullInfoRec.region = region; fullInfoRec.status.has_region = True; } XtAddCallback(widget, XmNdestroyCallback, DestroyCallback, dsm); while(!XtIsShell(shell)) shell = XtParent(shell); fullInfoRec.import_targets_ID = _XmTargetsToIndex(shell, fullInfoRec.import_targets, fullInfoRec.num_import_targets); switch(fullInfoRec.animation_style) { case XmDRAG_UNDER_PIXMAP: if (fullInfoRec.type == XmDROP_SITE_COMPOSITE) size = sizeof(XmDSLocalPixmapNodeRec); else size = sizeof(XmDSLocalPixmapLeafRec); break; case XmDRAG_UNDER_HIGHLIGHT: case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: case XmDRAG_UNDER_NONE: default: if (fullInfoRec.type == XmDROP_SITE_COMPOSITE) size = sizeof(XmDSLocalNoneNodeRec); else size = sizeof(XmDSLocalNoneLeafRec); break; } new_info = (XmDSInfo) XtCalloc(1, size); CopyFullIntoVariant(&fullInfoRec, new_info); if ((prev_info = (XmDSInfo) DSMWidgetToInfo(dsm, widget)) == NULL) { DSMRegisterInfo(dsm, widget, (XtPointer) new_info); } else { if (GetDSInternal(prev_info)) { /* * They are registering a widget for which we already had * to register internally. The only types of widgets which * we register internally are of type * XmDROP_SITE_COMPOSITE with children! This means that * they are trying to create their drop sites out of order * (parents must be registered before their children). */ XmeWarning(widget, MESSAGE6); } else { XmeWarning(widget, MESSAGE7); } DestroyDSInfo(new_info, True); return; } DSMInsertInfo(dsm, (XtPointer) new_info, NULL); DSMEndUpdate(dsm, widget); } /*ARGSUSED*/ static void CopyVariantIntoFull( XmDropSiteManagerObject dsm, XmDSInfo variant, XmDSFullInfo full_info ) { Widget shell; Atom *targets; Cardinal num_targets; long num_rects; XRectangle *rects; int index; if (GetDSRemote(variant)) shell = XtParent(dsm); else shell = GetDSWidget(variant); while (!XtIsShell(shell)) shell = XtParent(shell); /* * Clear the full info back to the default (kind of) state. */ bzero((void *)(full_info), sizeof(XmDSFullInfoRec)); full_info->animation_pixmap = XmUNSPECIFIED_PIXMAP; full_info->animation_mask = XmUNSPECIFIED_PIXMAP; /* Structure copy the status stuff across */ full_info->status = variant->status; full_info->parent = GetDSParent(variant); full_info->import_targets_ID = GetDSImportTargetsID(variant); full_info->operations = GetDSOperations(variant); full_info->region = GetDSRegion(variant); full_info->drag_proc = GetDSDragProc(variant); full_info->drop_proc = GetDSDropProc(variant); full_info->client_data = GetDSClientData(variant); full_info->widget = GetDSWidget(variant); full_info->type = GetDSType(variant); full_info->animation_style = GetDSAnimationStyle(variant); full_info->activity = GetDSActivity(variant); index = GetDSImportTargetsID(variant); if (index) { num_targets = _XmIndexToTargets(shell, index, &targets); full_info->num_import_targets = num_targets; full_info->import_targets = targets; } else { full_info->num_import_targets = 0; full_info->import_targets = NULL; } _XmRegionGetRectangles(GetDSRegion(variant), &rects, &num_rects); full_info->rectangles = rects; full_info->num_rectangles = (Cardinal) num_rects; if (GetDSRemote(variant)) { switch(GetDSAnimationStyle(variant)) { case XmDRAG_UNDER_HIGHLIGHT: { XmDSRemoteHighlightStyle hs = (XmDSRemoteHighlightStyle) GetDSRemoteAnimationPart(variant); full_info->highlight_color = hs->highlight_color; full_info->highlight_pixmap = hs->highlight_pixmap; full_info->background = hs->background; full_info->highlight_thickness = hs->highlight_thickness; full_info->border_width = hs->border_width; } break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: { XmDSRemoteShadowStyle ss = (XmDSRemoteShadowStyle) GetDSRemoteAnimationPart(variant); full_info->top_shadow_color = ss->top_shadow_color; full_info->top_shadow_pixmap = ss->top_shadow_pixmap; full_info->bottom_shadow_color = ss->bottom_shadow_color; full_info->bottom_shadow_pixmap = ss->bottom_shadow_pixmap; full_info->foreground = ss->foreground; full_info->shadow_thickness = ss->shadow_thickness; full_info->highlight_thickness = ss->highlight_thickness; full_info->border_width = ss->border_width; } break; case XmDRAG_UNDER_PIXMAP: { XmDSRemotePixmapStyle ps = (XmDSRemotePixmapStyle) GetDSRemoteAnimationPart(variant); full_info->animation_pixmap = ps->animation_pixmap; full_info->animation_pixmap_depth = ps->animation_pixmap_depth; full_info->animation_mask = ps->animation_mask; full_info->background = ps->background; full_info->foreground = ps->foreground; full_info->shadow_thickness = ps->shadow_thickness; full_info->highlight_thickness = ps->highlight_thickness; full_info->border_width = ps->border_width; } break; case XmDRAG_UNDER_NONE: default: break; } } else { switch(GetDSAnimationStyle(variant)) { case XmDRAG_UNDER_HIGHLIGHT: break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: break; case XmDRAG_UNDER_PIXMAP: { XmDSLocalPixmapStyle ps = (XmDSLocalPixmapStyle) GetDSLocalAnimationPart(variant); full_info->animation_pixmap = ps->animation_pixmap; full_info->animation_pixmap_depth = ps->animation_pixmap_depth; full_info->animation_mask = ps->animation_mask; } break; case XmDRAG_UNDER_NONE: default: break; } } } /*ARGSUSED*/ static void RetrieveInfo( XmDropSiteManagerObject dsm, Widget widget, ArgList args, Cardinal argCount ) { XmDSFullInfoRec full_info_rec; XmDSInfo info; XRectangle *rects; if (XmIsDragContext(widget)) { if (widget != dsm->dropManager.curDragContext) return; else info = (XmDSInfo) (dsm->dropManager.curInfo); } else info = (XmDSInfo) DSMWidgetToInfo(dsm, widget); if (info == NULL) return; CopyVariantIntoFull(dsm, info, &full_info_rec); XtGetSubvalues((XtPointer)(&full_info_rec), (XtResourceList)(_XmDSResources), (Cardinal)(_XmNumDSResources), (ArgList)(args), (Cardinal)(argCount)); rects = full_info_rec.rectangles; if (rects) XtFree((char *) rects); } /*ARGSUSED*/ static void CopyFullIntoVariant( XmDSFullInfo full_info, XmDSInfo variant ) { /* * This procedure assumes that variant is a variant of Local, * there should be no calls to this procedure with variant of * remote. */ if (GetDSRemote(full_info)) return; /* Magic internal fields */ SetDSRemote(variant, GetDSRemote(full_info)); SetDSLeaf(variant, GetDSLeaf(full_info)); SetDSShell(variant, GetDSShell(full_info)); SetDSHasRegion(variant, full_info->status.has_region); /* Externally visible fields */ SetDSAnimationStyle(variant, full_info->animation_style); SetDSType(variant, full_info->type); SetDSActivity(variant, full_info->activity); SetDSImportTargetsID(variant, full_info->import_targets_ID); SetDSOperations(variant, full_info->operations); SetDSRegion(variant, full_info->region); SetDSDragProc(variant, full_info->drag_proc); SetDSDropProc(variant, full_info->drop_proc); SetDSClientData(variant, full_info->client_data); SetDSWidget(variant, full_info->widget); switch(full_info->animation_style) { case XmDRAG_UNDER_HIGHLIGHT: break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: break; case XmDRAG_UNDER_PIXMAP: { XmDSLocalPixmapStyle ps = (XmDSLocalPixmapStyle) GetDSLocalAnimationPart(variant); ps->animation_pixmap = full_info->animation_pixmap; ps->animation_pixmap_depth = full_info->animation_pixmap_depth; ps->animation_mask = full_info->animation_mask; } break; case XmDRAG_UNDER_NONE: default: break; } } /*ARGSUSED*/ static void UpdateInfo( XmDropSiteManagerObject dsm, Widget widget, ArgList args, Cardinal argCount ) { XmDSFullInfoRec full_info_rec; XmDSFullInfo full_info = &full_info_rec; XmDSInfo info = (XmDSInfo) DSMWidgetToInfo(dsm, widget); unsigned char type; XmRegion old_region; XRectangle *rects; long num_rects; if ((info == NULL) || GetDSInternal(info)) return; rects = NULL; DSMStartUpdate(dsm, widget); CopyVariantIntoFull(dsm, info, full_info); /* Save the type and region in case they try to cheat */ type = GetDSType(info); old_region = GetDSRegion(info); /* BEGIN OSF Fix CR 5335 */ /* * Set up the rectangle list stuff. */ rects = full_info->rectangles; num_rects = (long) full_info->num_rectangles; /* END OSF Fix CR 5335 */ /* Update the info */ { Atom *old_import_targets; Cardinal old_num_import_targets; old_num_import_targets = full_info->num_import_targets; old_import_targets = full_info->import_targets; XtSetSubvalues(full_info, _XmDSResources, _XmNumDSResources, args, argCount); if ( (full_info->num_import_targets != old_num_import_targets) || (full_info->import_targets != old_import_targets) ) { Widget shell = widget; while(!(XtIsShell(shell))) shell = XtParent(shell); full_info->import_targets_ID = _XmTargetsToIndex(shell, full_info->import_targets, full_info->num_import_targets); } } if (full_info->type != type) { XmeWarning(widget, MESSAGE8); full_info->type = type; } if ((full_info->rectangles != rects) || (full_info->num_rectangles != num_rects)) { if (type == XmDROP_SITE_SIMPLE) { int i; XmRegion new_region = _XmRegionCreate(); for (i=0; i < full_info->num_rectangles; i++) _XmRegionUnionRectWithRegion( &(full_info->rectangles[i]), new_region, new_region); full_info->region = new_region; full_info->status.has_region = True; _XmRegionDestroy(old_region); } else { XmeWarning(widget, MESSAGE9); } /* BEGIN OSF Fix CR 5335 */ /* END OSF Fix CR 5335 */ } if ((full_info->animation_style == XmDRAG_UNDER_PIXMAP) && (full_info->animation_pixmap_depth == 0)) { Widget widget = GetDSWidget(info); XmeGetPixmapData(XtScreen(widget), full_info->animation_pixmap, NULL, (int*)&(full_info->animation_pixmap_depth), NULL, NULL, NULL, NULL, NULL, NULL); } /* * If the animation style has changed, we need to change info * into a different variant. */ if (full_info->animation_style != GetDSAnimationStyle(info)) { XmDSInfo new_info; size_t size; switch (full_info->animation_style) { case XmDRAG_UNDER_PIXMAP: if (GetDSType(info) == XmDROP_SITE_COMPOSITE) size = sizeof(XmDSLocalPixmapNodeRec); else size = sizeof(XmDSLocalPixmapLeafRec); break; case XmDRAG_UNDER_HIGHLIGHT: case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: case XmDRAG_UNDER_NONE: default: if (GetDSType(info) == XmDROP_SITE_COMPOSITE) size = sizeof(XmDSLocalNoneNodeRec); else size = sizeof(XmDSLocalNoneLeafRec); break; } /* Allocate the new info rec */ new_info = (XmDSInfo) XtCalloc(1, size); CopyFullIntoVariant(full_info, new_info); /* * Fix the parent pointers of the children */ SetDSNumChildren(new_info, GetDSNumChildren(info)); SetDSChildren(new_info, GetDSChildren(info)); if ((GetDSType(new_info) == XmDROP_SITE_COMPOSITE) && (GetDSNumChildren(new_info))) { XmDSInfo child; int i; for (i=0; i < (int)GetDSNumChildren(new_info); i++) { child = (XmDSInfo) GetDSChild(new_info, i); SetDSParent(child, new_info); } } /* Clear the registered bit on the new one */ SetDSRegistered(new_info, False); /* Remove the old one from the hash table */ DSMUnregisterInfo(dsm, info); /* Replace the old one in the drop site tree */ ReplaceDSChild(info, new_info); /* Destroy the old one, but not anything it points to */ DestroyDSInfo(info, False); /* Register the new one */ DSMRegisterInfo(dsm, widget, (XtPointer) new_info); } else { CopyFullIntoVariant(full_info, info); } DSMEndUpdate(dsm, widget); if (rects!=NULL) XtFree ((char *)rects); } /*ARGSUSED*/ static void StartUpdate( XmDropSiteManagerObject dsm, Widget refWidget ) { Widget shell = refWidget; XmDSInfo shellInfo; while(!(XtIsShell(shell))) shell = XtParent(shell); shellInfo = (XmDSInfo) DSMWidgetToInfo(dsm, shell); if (shellInfo) SetDSUpdateLevel(shellInfo, (GetDSUpdateLevel(shellInfo) + 1)); } /*ARGSUSED*/ static void EndUpdate( XmDropSiteManagerObject dsm, Widget refWidget ) { _XmDropSiteUpdateInfo dsupdate, oldupdate; Boolean found = False; Boolean clean; Widget shell; XmDSInfo shellInfo; dsupdate = dsm -> dropManager.updateInfo; clean = (dsupdate == NULL); shell = refWidget; while(!(XtIsShell(shell))) shell = XtParent(shell); shellInfo = (XmDSInfo) DSMWidgetToInfo(dsm, shell); if (shellInfo == NULL) return; if (GetDSUpdateLevel(shellInfo) > 0) SetDSUpdateLevel(shellInfo, (GetDSUpdateLevel(shellInfo) - 1)); if (GetDSUpdateLevel(shellInfo) > 0) return; /* Fix CR 7976, losing track of some updates because of bad list manipulation */ oldupdate = dsupdate; /* Really, keep track of toplevel widgets to be updated */ while(dsupdate) { if (dsupdate -> refWidget == shell) { found = True; break; } dsupdate = dsupdate -> next; } if (! found) { /* Queue real end update to a timeout */ dsupdate = (_XmDropSiteUpdateInfo) XtMalloc(sizeof(_XmDropSiteUpdateInfoRec)); dsupdate -> dsm = dsm; dsupdate -> refWidget = shell; dsupdate -> next = oldupdate; dsm -> dropManager.updateInfo = dsupdate; } /* We don't add a timeout if the record is already marked for update */ if (clean) { XtAppAddTimeOut(XtWidgetToApplicationContext(shell), 0, _XmIEndUpdate, dsm); } } /*ARGSUSED*/ void _XmIEndUpdate(XtPointer client_data, XtIntervalId *interval_id) { XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) client_data; _XmDropSiteUpdateInfo dsupdate; Widget shell; XmDSInfo shellInfo; /* Return if all updates have already happened */ while(dsm -> dropManager.updateInfo != NULL) { dsupdate = (_XmDropSiteUpdateInfo) dsm -> dropManager.updateInfo; shell = dsupdate -> refWidget; dsm -> dropManager.updateInfo = dsupdate -> next; XtFree((char*) dsupdate); while(!(XtIsShell(shell))) shell = XtParent(shell); shellInfo = (XmDSInfo) DSMWidgetToInfo(dsm, shell); if (shellInfo && XtIsRealized(shell)) { /* This one's for real */ if (_XmGetDragProtocolStyle(shell) != XmDRAG_DYNAMIC) { XmDropSiteTreeAddCallbackStruct outCB; /* Gotta' update that window property. */ outCB.reason = XmCR_DROP_SITE_TREE_ADD; outCB.event = NULL; outCB.rootShell = shell; outCB.numDropSites = CountDropSites(shellInfo); outCB.numArgsPerDSHint = 0; if (dsm->dropManager.treeUpdateProc) (dsm->dropManager.treeUpdateProc) ((Widget) dsm, NULL, (XtPointer) &outCB); } else { /* We have to Sync the regions with the widgets */ SyncTree(dsm, shell); } } } } static void DestroyInfo( XmDropSiteManagerObject dsm, Widget widget ) { XmDSInfo info = (XmDSInfo) DSMWidgetToInfo(dsm, widget); if (info == NULL) return; DSMStartUpdate(dsm, widget); if (info == (XmDSInfo) (dsm->dropManager.curInfo)) { Widget shell; XmDragMotionCallbackStruct cbRec ; XmDragMotionClientDataStruct cdRec ; unsigned char style = _XmGetActiveProtocolStyle( dsm->dropManager.curDragContext); /* Fake out a motion message from the DragC */ cbRec.reason = XmCR_DROP_SITE_LEAVE; cbRec.event = NULL; cbRec.timeStamp = dsm->dropManager.curTime; cbRec.x = dsm->dropManager.curX; cbRec.y = dsm->dropManager.curY; /* These fields are irrelevant on a leave */ cbRec.operations = cbRec.operation = 0; cbRec.dropSiteStatus = 0; /* Need these too */ shell = GetDSWidget(info); while (!XtIsShell(shell)) shell = XtParent(shell); cdRec.window = XtWindow(shell); cdRec.dragOver = (Widget) (((XmDragContext)(dsm->dropManager.curDragContext)) ->drag.curDragOver); HandleLeave(dsm, &cdRec, &cbRec, (XmDSInfo) dsm->dropManager.curInfo, style, False); dsm->dropManager.curInfo = NULL; } while(info != NULL) { DSMRemoveInfo(dsm, (XtPointer) info); DestroyDSInfo(info, True); /* This should be NULL now, otherwise, keep removing until done */ info = (XmDSInfo) DSMWidgetToInfo(dsm, widget); } DSMEndUpdate(dsm, widget); } static void SyncDropSiteGeometry( XmDropSiteManagerObject dsm, XmDSInfo info ) { XmDSInfo child; if (!GetDSLeaf(info)) { int i; for (i = 0; i < (int)GetDSNumChildren(info); i++) { child = (XmDSInfo) GetDSChild(info, i); SyncDropSiteGeometry(dsm, child); } } if (!GetDSHasRegion(info)) { Widget w = GetDSWidget(info); XRectangle rect; Dimension bw = XtBorderWidth(w); /* The region is the object rectangle */ /* assert(GetDSRegion(info) != NULL) */ /* The region comes from the widget */ rect.x = rect.y = -bw; rect.width = XtWidth(w) + (2 * bw); rect.height = XtHeight(w) + (2 * bw); _XmRegionClear(GetDSRegion(info)); _XmRegionUnionRectWithRegion(&rect, GetDSRegion(info), GetDSRegion(info)); } } static void SyncTree( XmDropSiteManagerObject dsm, Widget shell ) { XmDSInfo saveRoot; XmDSInfo root = (XmDSInfo) DSMWidgetToInfo(dsm, shell); Position shellX, shellY, savX, savY; if ((root == NULL) || (GetDSRemote(root))) return; /* * Set things up so that the shell coordinates are trivially * available. */ saveRoot = (XmDSInfo) dsm->dropManager.dsRoot; savX = dsm->dropManager.rootX; savY = dsm->dropManager.rootY; dsm->dropManager.dsRoot = (XtPointer) root; XtTranslateCoords(GetDSWidget(root), 0, 0, &shellX, &shellY); dsm->dropManager.rootX = shellX; dsm->dropManager.rootY = shellY; /* Do the work */ RemoveAllClippers(dsm, root); SyncDropSiteGeometry(dsm, root); DetectAndInsertAllClippers(dsm, root); /* Restore the DSM */ dsm->dropManager.dsRoot = (XtPointer) saveRoot; dsm->dropManager.rootX = savX; dsm->dropManager.rootY = savY; } void _XmSyncDropSiteTree( Widget shell ) { XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(shell))); DSMSyncTree(dsm, shell); } static void Update( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer callData ) { XmAnyCallbackStruct *callback = (XmAnyCallbackStruct *)callData; switch(callback->reason) { case XmCR_TOP_LEVEL_ENTER: case XmCR_TOP_LEVEL_LEAVE: DSMChangeRoot(dsm, clientData, callData); break; case XmCR_DRAG_MOTION: DSMProcessMotion(dsm, clientData, callData); break; case XmCR_DROP_START: DSMProcessDrop(dsm, clientData, callData); break; case XmCR_OPERATION_CHANGED: DSMOperationChanged(dsm, clientData, callData); default: break; } } void _XmDSMUpdate( XmDropSiteManagerObject dsm, XtPointer clientData, XtPointer callData ) { DSMUpdate(dsm, clientData, callData); } int _XmDSMGetTreeFromDSM( XmDropSiteManagerObject dsm, Widget shell, XtPointer dataPtr ) { return(DSMGetTreeFromDSM(dsm, shell, dataPtr)); } Boolean _XmDropSiteShell( Widget widget ) { XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); if ((XtIsShell(widget)) && (DSMWidgetToInfo(dsm, widget) != NULL)) return(True); else return(False); } static Boolean HasDropSiteDescendant( XmDropSiteManagerObject dsm, Widget widget ) { CompositeWidget cw; int i; Widget child; if (!XtIsComposite(widget)) return(False); cw = (CompositeWidget) widget; for (i = 0; i < cw->composite.num_children; i++) { child = cw->composite.children[i]; if ((DSMWidgetToInfo(dsm, child) != NULL) || (HasDropSiteDescendant(dsm, child))) { return(True); } } return(False); } Boolean _XmDropSiteWrapperCandidate( Widget widget ) { XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); Widget shell; if (widget == NULL) return(False); if (DSMWidgetToInfo(dsm, widget) != NULL) return(True); else if (!XtIsComposite(widget)) return(False); /* * Make sure that there might be a drop site somewhere in * this shell before traversing the descendants. */ shell = widget; while (!XtIsShell(shell)) shell = XtParent(shell); if (!_XmDropSiteShell(shell)) return(False); return(HasDropSiteDescendant(dsm, widget)); } /*ARGSUSED*/ static void DestroyCallback( Widget widget, XtPointer client_data, XtPointer call_data ) { XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) client_data; DSMDestroyInfo(dsm, widget); /* Force Update */ _XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL); } Boolean XmDropSiteRegistered( Widget widget ) { XmDropSiteManagerObject dsm; XtPointer info; _XmWidgetToAppContext(widget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); info = DSMWidgetToInfo(dsm, widget); if ((info == NULL)) { _XmAppUnlock(app); return False; } _XmAppUnlock(app); return True; } void XmDropSiteRegister( Widget widget, ArgList args, Cardinal argCount ) { XmDropSiteManagerObject dsm; _XmWidgetToAppContext(widget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); if (XtIsShell(widget)) { XmeWarning(widget, MESSAGE10); } else DSMCreateInfo(dsm, widget, args, argCount); _XmAppUnlock(app); } void XmDropSiteUnregister( Widget widget ) { XmDropSiteManagerObject dsm; _XmWidgetToAppContext(widget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); DSMDestroyInfo(dsm, widget); /* Force Update */ _XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL); _XmAppUnlock(app); } void XmDropSiteStartUpdate( Widget refWidget ) { XmDropSiteManagerObject dsm; _XmWidgetToAppContext(refWidget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(refWidget))); DSMStartUpdate(dsm, refWidget); _XmAppUnlock(app); } void XmDropSiteUpdate( Widget enclosingWidget, ArgList args, Cardinal argCount ) { XmDropSiteManagerObject dsm; _XmWidgetToAppContext(enclosingWidget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(enclosingWidget))); DSMUpdateInfo(dsm, enclosingWidget, args, argCount); _XmAppUnlock(app); } void XmDropSiteEndUpdate( Widget refWidget ) { XmDropSiteManagerObject dsm; _XmWidgetToAppContext(refWidget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(refWidget))); DSMEndUpdate(dsm, refWidget); _XmAppUnlock(app); } void XmDropSiteRetrieve( Widget enclosingWidget, ArgList args, Cardinal argCount ) { XmDropSiteManagerObject dsm; _XmWidgetToAppContext(enclosingWidget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(enclosingWidget))); /* Update if dsm is dirty */ _XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL); DSMRetrieveInfo(dsm, enclosingWidget, args, argCount); _XmAppUnlock(app); } Status XmDropSiteQueryStackingOrder( Widget widget, Widget *parent_rtn, Widget **children_rtn, Cardinal *num_children_rtn ) { XmDropSiteManagerObject dsm; XmDSInfo info; XmDSInfo parentInfo; Cardinal num_visible_children = 0; /* visible to application code */ int i,j; _XmWidgetToAppContext(widget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); info = (XmDSInfo) DSMWidgetToInfo(dsm, widget); /* Update if dsm is dirty */ _XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL); if (info == NULL) { _XmAppUnlock(app); return(0); } if (!GetDSLeaf(info)) { for (i=0; i < (int)GetDSNumChildren(info); i++) { XmDSInfo child = (XmDSInfo) GetDSChild(info, i); if (!GetDSInternal(child)) num_visible_children++; } if (num_visible_children) { *children_rtn = (Widget *) XtMalloc(sizeof(Widget) * num_visible_children); /* Remember to reverse the order */ for (j=0, i=(GetDSNumChildren(info) - 1); i >= 0; i--) { XmDSInfo child = (XmDSInfo) GetDSChild(info, i); if (!GetDSInternal(child)) (*children_rtn)[j++] = GetDSWidget(child); } /* assert(j == num_visible_children) */ } else *children_rtn = NULL; *num_children_rtn = num_visible_children; } else { *children_rtn = NULL; *num_children_rtn = 0; } parentInfo = (XmDSInfo) GetDSParent(info); if (GetDSInternal(parentInfo)) { *parent_rtn = NULL; while ((parentInfo = (XmDSInfo) GetDSParent(parentInfo)) != NULL) if (!GetDSInternal(parentInfo)) *parent_rtn = GetDSWidget(parentInfo); } else *parent_rtn = GetDSWidget(parentInfo); _XmAppUnlock(app); return(1); } void XmDropSiteConfigureStackingOrder( Widget widget, Widget sibling, Cardinal stack_mode ) { XmDropSiteManagerObject dsm; XmDSInfo info; XmDSInfo parent; _XmWidgetToAppContext(widget); if (widget == NULL) return; _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); info = (XmDSInfo) DSMWidgetToInfo(dsm, widget); if ((widget == sibling) || (info == NULL)) { _XmAppUnlock(app); return; } parent = (XmDSInfo) GetDSParent(info); if (sibling != NULL) { XmDSInfo sib = (XmDSInfo) DSMWidgetToInfo(dsm, sibling); Cardinal index, sib_index; int i; if ((sib == NULL) || (((XmDSInfo) GetDSParent(sib)) != parent) || (XtParent(widget) != XtParent(sibling))) { _XmAppUnlock(app); return; } index = GetDSChildPosition(parent, info); sib_index = GetDSChildPosition(parent, sib); switch(stack_mode) { case XmABOVE: if (index > sib_index) for(i=index; i > sib_index; i--) SwapDSChildren(parent, i, i - 1); else for (i=index; i < (sib_index - 1); i++) SwapDSChildren(parent, i, i + 1); break; case XmBELOW: if (index > sib_index) for(i=index; i > (sib_index + 1); i--) SwapDSChildren(parent, i, i - 1); else for (i=index; i < sib_index; i++) SwapDSChildren(parent, i, i + 1); break; default: /* do nothing */ break; } } else { Cardinal index = GetDSChildPosition(parent, info); int i; switch(stack_mode) { case XmABOVE: for (i=index; i > 0; i--) SwapDSChildren(parent, i, i - 1); break; case XmBELOW: for (i=index; i < (int)(GetDSNumChildren(parent) - 1); i++) SwapDSChildren(parent, i, i + 1); break; default: /* do nothing */ break; } } _XmAppUnlock(app); } XmDropSiteVisuals XmDropSiteGetActiveVisuals( Widget widget ) { XmDropSiteManagerObject dsm; XmDSInfo info; XmDropSiteVisuals dsv; _XmWidgetToAppContext(widget); _XmAppLock(app); dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); info = (XmDSInfo) dsm->dropManager.curInfo; dsv = (XmDropSiteVisuals) XtCalloc(1, sizeof(XmDropSiteVisualsRec)); /* Update if dsm is dirty */ _XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL); if (info == NULL) { XtFree((char *)dsv); _XmAppUnlock(app); return(NULL); } if (!GetDSRemote(info)) { Arg args[30]; int n; Widget w; unsigned char unitType; w = GetDSWidget(info); /* * We need to retrieve information from the widget. XtGetValues is * too slow, so retrieve the information directly from the widget * instance. * * XtGetValues is used for gadgets, since part of the instance * structure will be in the cache and not directly accessable. * * XtGetValues is used for non-Motif widgets, just in case they provide * Motif-style resources. * * (See also PutDSToStream() ) */ if (XmIsPrimitive(w)) { XmPrimitiveWidget pw = (XmPrimitiveWidget)w; dsv->background = pw->core.background_pixel; dsv->foreground = pw->primitive.foreground; dsv->topShadowColor = pw->primitive.top_shadow_color; dsv->topShadowPixmap = pw->primitive.top_shadow_pixmap; dsv->bottomShadowColor = pw->primitive.bottom_shadow_color; dsv->bottomShadowPixmap = pw->primitive.bottom_shadow_pixmap; dsv->shadowThickness = pw->primitive.shadow_thickness; dsv->highlightColor = pw->primitive.highlight_color; dsv->highlightPixmap = pw->primitive.highlight_pixmap; dsv->highlightThickness = pw->primitive.highlight_thickness; if (!GetDSHasRegion(info)) dsv->borderWidth = pw->core.border_width; else dsv->borderWidth = 0; } else if (XmIsManager(w)) { XmManagerWidget mw = (XmManagerWidget)w; dsv->background = mw->core.background_pixel; dsv->foreground = mw->manager.foreground; dsv->topShadowColor = mw->manager.top_shadow_color; dsv->topShadowPixmap = mw->manager.top_shadow_pixmap; dsv->bottomShadowColor = mw->manager.bottom_shadow_color; dsv->bottomShadowPixmap = mw->manager.bottom_shadow_pixmap; dsv->shadowThickness = mw->manager.shadow_thickness; dsv->highlightColor = mw->manager.highlight_color; dsv->highlightPixmap = mw->manager.highlight_pixmap; /* Temporary hack, until we support full defaulting */ if (GetDSAnimationStyle(info) == XmDRAG_UNDER_HIGHLIGHT) dsv->highlightThickness = 1; else dsv->highlightThickness = 0; if (!GetDSHasRegion(info)) dsv->borderWidth = mw->core.border_width; else dsv->borderWidth = 0; } else /* XmGadget or non-Motif subclass */ { n = 0; XtSetArg(args[n], XmNunitType, &unitType); n++; XtGetValues(w, args, n); if (unitType != XmPIXELS) { /* we need values in pixels */ n = 0; XtSetArg(args[n], XmNunitType, XmPIXELS); n++; XtSetValues(w, args, n); } n = 0; XtSetArg(args[n], XmNbackground, &(dsv->background)); n++; XtSetArg(args[n], XmNforeground, &(dsv->foreground)); n++; XtSetArg(args[n], XmNtopShadowColor, &(dsv->topShadowColor)); n++; XtSetArg(args[n], XmNtopShadowPixmap, &(dsv->topShadowPixmap)); n++; XtSetArg(args[n], XmNbottomShadowColor, &(dsv->bottomShadowColor)); n++; XtSetArg(args[n], XmNbottomShadowPixmap, &(dsv->bottomShadowPixmap)); n++; XtSetArg(args[n], XmNshadowThickness, &(dsv->shadowThickness)); n++; XtSetArg(args[n], XmNhighlightColor, &(dsv->highlightColor)); n++; XtSetArg(args[n], XmNhighlightPixmap, &(dsv->highlightPixmap)); n++; XtSetArg(args[n], XmNhighlightThickness, &(dsv->highlightThickness)); n++; if (!GetDSHasRegion(info)) { XtSetArg(args[n], XmNborderWidth, &(dsv->borderWidth)); n++; } else dsv->borderWidth = 0; XtGetValues(w, args, n); if (unitType != XmPIXELS) { n = 0; XtSetArg(args[n], XmNunitType, unitType); n++; XtSetValues(w, args, n); } } } else { switch (GetDSAnimationStyle(info)) { case XmDRAG_UNDER_HIGHLIGHT: { XmDSRemoteHighlightStyle hs = (XmDSRemoteHighlightStyle) GetDSRemoteAnimationPart(info); dsv->highlightColor = hs->highlight_color; dsv->highlightPixmap = hs->highlight_pixmap; dsv->background = hs->background; dsv->highlightThickness = hs->highlight_thickness; dsv->borderWidth = hs->border_width; } break; case XmDRAG_UNDER_SHADOW_IN: case XmDRAG_UNDER_SHADOW_OUT: { XmDSRemoteShadowStyle ss = (XmDSRemoteShadowStyle) GetDSRemoteAnimationPart(info); dsv->topShadowColor = ss->top_shadow_color; dsv->topShadowPixmap = ss->top_shadow_pixmap; dsv->bottomShadowColor = ss->bottom_shadow_color; dsv->bottomShadowPixmap = ss->bottom_shadow_pixmap; dsv->foreground = ss->foreground; dsv->shadowThickness = ss->shadow_thickness; dsv->highlightThickness = ss->highlight_thickness; dsv->borderWidth = ss->border_width; } break; case XmDRAG_UNDER_PIXMAP: { XmDSRemotePixmapStyle ps = (XmDSRemotePixmapStyle) GetDSRemoteAnimationPart(info); dsv->background = ps->background; dsv->foreground = ps->foreground; dsv->shadowThickness = ps->shadow_thickness; dsv->highlightThickness = ps->highlight_thickness; dsv->borderWidth = ps->border_width; } break; case XmDRAG_UNDER_NONE: default: break; } } _XmAppUnlock(app); return(dsv); } Widget _XmGetActiveDropSite( Widget widget ) { XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) _XmGetDropSiteManagerObject((XmDisplay) XmGetXmDisplay( XtDisplayOfObject(widget))); XmDSInfo info = (XmDSInfo) dsm->dropManager.curInfo; /* Update if dsm is dirty */ _XmIEndUpdate((XtPointer) dsm, (XtIntervalId *) NULL); if ((!XmIsDragContext(widget)) || (GetDSRemote(info))) return(NULL); else return(GetDSWidget(info)); } #ifdef DEBUG /********************************************************************** * Debugging code for DropSMgr. This code will print out the current * state of the tree **********************************************************************/ static Boolean PrintHashEntry(XmHashKey key, XtPointer value, XtPointer data) { Widget wid = (Widget) key; printf("Widget %p (%s) Info %p\n", wid, XtName(wid), value); return(False); } static void PrintTree(XmDSInfo rec, int level) { int i; Widget wid = GetDSWidget(rec); char *name = ""; /* Indent for level */ for(i = 0; i < level; i++) printf(" "); if (wid != (Widget) NULL) name = XtName(wid); printf("%p (internal %d) - widget %p (%s)\n", rec, GetDSInternal(rec), wid, name); if (!GetDSLeaf(rec)) { int j; for(j = 0; j < GetDSNumChildren(rec); j++) PrintTree(GetDSChild(rec, j), level + 1); } } void _XmPrintDSTree(XmDropSiteManagerObject dsm, XmDSInfo root) { /* First print all the information records in tree format */ PrintTree(root, 0); /* Now print widget to info hash table */ _XmMapHashTable(DSTABLE(dsm), PrintHashEntry, NULL); } #endif /* DEBUG */