/* @(#)center_vis.c 17.1.1.1 (ESO-IPG) 01/25/02 17:26:41 */ /*--------------------------------------------------------------------- * $Date: 93/07/12 19:05:09 $ $Revision: 2.3.6.1 $ *--------------------------------------------------------------------- * * * Copyright (c) 1992, Visual Edge Software Ltd. * * ALL RIGHTS RESERVED. Permission to use, copy, modify, and * distribute this software and its documentation for any purpose * and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Visual Edge Software not be * used in advertising or publicity pertaining to distribution of * the software without specific, written prior permission. The year * included in the notice is the year of the creation of the work. *-------------------------------------------------------------------*/ /*--------------------------------------------------------------------- * FILE: center_vis.c * * CONTENTS: * widget placement utilities * UxCenterVisibly * UxCenterWidgetVisibly * * Shared between design and runtime systems. *--------------------------------------------------------------------*/ #include #include #include #include "valloc.h" #ifdef MOTIF_WIDGETS #include #include #endif /* MOTIF_WIDGETS */ #include "UxLib.h" #include "global.h" #include "unit.h" #include "uimx_cat.h" #include "misc1_ds.h" /* X/OPEN message catalog macros. */ #define CGETS(ms,ds_ms) UxCatGets(MC_MISC1,ms,ds_ms) /* Allowances made for decoration when ensuring that * widgets stay onscreen. */ #define DECORATION_X 10 #define DECORATION_Y 10 /*----------------------------------------------------------------------------- * GLOBAL *----------------------------------------------------------------------------- * NAME: void UxCenterWidgetVisibly (rs, parent) * INPUT: swidget rs - swidget to center on * swidget parent - swidget to move * * DESCRIPTION: Center 'rs' under the cursor by moving 'parent'. If 'parent' * would have to be partly off the screen then 'parent' is moved * as far as possible on the screen, and if MOTIF widgets are * NOT being used the cursor is warped to the center of 'rs'. * * REVISON: Last revision: bugfix 2605 *-----------------------------------------------------------------------------*/ void UxCenterWidgetVisibly (child, parent) Widget child; Widget parent; { Window rp, wp; int xoff, yoff; int rx, ry, wx= 0, wy= 0; int px, py; Position x, y; Dimension w, h, bw; unsigned char unittype=0; Widget widget; unsigned int mask; /* Initialize offsets with center of child. */ XtVaGetValues (child, XmNwidth, &w, XmNheight, &h, NULL); unittype = UxFindUnitType (child); UxConvertDimension (child, unittype, w, h, XmPIXELS, &w, &h); xoff = w / 2; yoff = h / 2; /* Add each containing widget offset until we reach parent. */ widget = child; while (widget != parent) { if (( widget == NULL) || XtIsSubclass (widget, wmShellWidgetClass)) { char *msg_ptr; msg_ptr = UxCopyString (CGETS(MS_MISC1_PARM_ERR, DS_MS_MISC1_PARM_ERR)); UxStandardError (msg_ptr); UxFree (msg_ptr); return; } XtVaGetValues (widget, XmNx, &x, XmNy, &y, XmNborderWidth, &bw, NULL); unittype = UxFindUnitType (widget); if(!XtIsSubclass(widget, xmBulletinBoardWidgetClass)) { UxConvertPosition (widget, unittype, x, y, XmPIXELS, &x, &y); bw = XmConvertUnits (widget,XmHORIZONTAL,unittype,(int)bw,XmPIXELS); } xoff+= x + bw; yoff+= y + bw; widget = XtParent (widget); } #ifdef MOTIF_WIDGETS /* If the parent is a XmDialogShell then its child will have * an X and Y position that are the same as that of the dialogShell. * In other words, we have to correct for the distance we already * subtracted (all other shell children have an X and Y of 0). */ if (XtClass (parent) == xmDialogShellWidgetClass) { xoff -= (x+bw); yoff -= (y+bw); } #endif /* MOTIF_WIDGETS */ XQueryPointer (UxDisplay, UxRootWindow, &rp, &wp, &rx, &ry, &px, &py, &mask); #if defined (UX_FORCE_CENTER_VISIBLY) { /* If the resources used to force the center of the parent * widget are set, use them instead. This makes it possible * to perform Automated testing with HP's Synergy Tool */ XrmValue resX, resY; char *type; extern char * UxProgramName; if (UxGetAnyResource(UxProgramName, "centerVisX", &type, &resX) == True) { rx = atoi(resX.addr); } if (UxGetAnyResource(UxProgramName, "centerVisY", &type, &resY) == True) { ry = atoi(resY.addr); } } #endif rx -= xoff; ry -= yoff; /* rx and ry are our tentative coordinates for parent. * Make sure we don't put parent offscreen (even partially), * leaving margin all round for window decoration. * If we adjust rx or ry, we set wx or wy to the amount * we must warp the cursor so it shows up centered in rs. */ XtVaGetValues (parent, XmNwidth, &w, XmNheight, &h, NULL); unittype = UxFindUnitType (parent); UxConvertDimension (parent, unittype, w, h, XmPIXELS, &w, &h); if (rx-DECORATION_X < 0) { wx = DECORATION_X - rx; rx = DECORATION_X; } else if (rx+w+DECORATION_X > DisplayWidth (UxDisplay, UxScreen)) { wx = DisplayWidth (UxDisplay, UxScreen) - (rx + w); rx = DisplayWidth (UxDisplay, UxScreen) - (w + DECORATION_X); } if (ry-DECORATION_Y < 0) { wy = DECORATION_Y - ry; ry = DECORATION_Y; } else if (ry+h+DECORATION_Y > DisplayHeight (UxDisplay,UxScreen)) { wy = DisplayHeight (UxDisplay, UxScreen) - (ry + h); ry = DisplayHeight (UxDisplay, UxScreen) - (h + DECORATION_Y); } #ifndef MOTIF_WIDGETS if ((wy != 0) || (wx != 0)) { XWarpPointer (UxDisplay,UxRootWindow,UxRootWindow, px,py, DisplayWidth (UxDisplay,UxScreen), DisplayHeight (UxDisplay, UxScreen), wx+px, wy+py); } #endif /* MOTIF_WIDGETS */ UxConvertPosition (parent, XmPIXELS, rx, ry, unittype, &x, &y); XtVaSetValues (parent, XmNx, x, XmNy, y, NULL); #ifdef OL_WIDGETS /* Set the window manager size hints to position shells properly. * These are obsolete in X11R4, but are needed for pre-R4 managers. * This code used to modify the parent WMShell size_hints member, * but that struct is under the complete control of the WMShell * implementation in Motif. * The code also used to set USSize hints, for no apparent reason. */ if (XtIsSubclass (parent, wmShellWidgetClass) && XtIsRealized (parent)) { XSizeHints size_hints; size_hints.x = rx; size_hints.y = ry; size_hints.flags = USPosition; XSetNormalHints (UxDisplay, XtWindow (parent), &size_hints); } #endif /* OL_WIDGETS */ } /*----------------------------------------------------------------------------- * GLOBAL *----------------------------------------------------------------------------- * NAME: void UxCenterVisibly (rs, parent) * INPUT: swidget *rs - swidget to center on * swidget *parent - ancestor to move * * DESCRIPTION: * Center 'rs' under the cursor by moving 'parent'. If 'parent' * would have to be partly off the screen then 'parent' is moved * as far as possible to the edge of the screen, and if MOTIF * widgets are NOT being used, the pointer is warped * to the center of 'rs'. * * Last revision: bugfix 2605 *---------------------------------------------------------------------------*/ void UxCenterVisibly (rs, parent) swidget rs; swidget parent; { #ifndef RUNTIME if (UxIsInvalidObject (rs, "UxCenterVisibly")) return; if (UxIsInvalidObject (parent, "UxCenterVisibly")) return; #endif /* RUNTIME */ UxCenterWidgetVisibly (UxGetWidget (rs), UxRealWidget (parent)); } #ifndef RUNTIME /* Alternate name used in UIMX interface code. */ UxCenter_visibly (rs, par) swidget rs, par; { UxCenterVisibly (rs, par); } #endif