static XtGeometryResult QueryGeometry(ViewportWidget w, XtWidgetGeometry *request, XtWidgetGeometry *reply_return) { if (w->viewport.allowhoriz && w->viewport.allowvert) return (TestSmaller(w, request, reply_return)); else if (w->viewport.allowhoriz && !w->viewport.allowvert) { if (WidthChange() && !HeightChange()) return (TestSmaller(w, request, reply_return)); else if (!WidthChange() && HeightChange()) return (XtMakeGeometryRequest((Widget)w, request, reply_return)); else if (WidthChange() && HeightChange()) return (GeometryRequestPlusScrollbar(w, True, request, reply_return)); else /* !WidthChange() && !HeightChange() */ return (XtGeometryYes); } else if (!w->viewport.allowhoriz && w->viewport.allowvert) { if (!WidthChange() && HeightChange()) return (TestSmaller(w, request, reply_return)); else if (WidthChange() && !HeightChange()) return (XtMakeGeometryRequest((Widget)w, request, reply_return)); else if (WidthChange() && HeightChange()) return (GeometryRequestPlusScrollbar(w, False, request, reply_return)); else /* !WidthChange() && !HeightChange() */ return (XtGeometryYes); } else /* (!w->viewport.allowhoriz && !w->viewport.allowvert) */ return (XtMakeGeometryRequest((Widget)w, request, reply_return)); }
/* * Function: * ChangeSize * * Parameters: * w - widget to try change the size of * * Description: * Laysout the widget. */ static void ChangeSize(Widget w, unsigned int width, unsigned int height) { XtWidgetGeometry request, reply; request.request_mode = CWWidth | CWHeight; request.width = width; request.height = height; switch (XtMakeGeometryRequest(w, &request, &reply)) { case XtGeometryYes: case XtGeometryNo: break; case XtGeometryAlmost: Layout(w, request.height != reply.height, request.width != reply.width, &reply.width, &reply.height); request = reply; switch (XtMakeGeometryRequest(w, &request, &reply)) { case XtGeometryYes: case XtGeometryNo: break; case XtGeometryAlmost: request = reply; Layout(w, False, False, &request.width, &request.height); request.request_mode = CWWidth | CWHeight; XtMakeGeometryRequest(w, &request, &reply); /*FALLTROUGH*/ default: break; } /*FALLTROUGH*/ default: break; } }
static void XawPortholeChangeManaged(Widget gw) { PortholeWidget pw = (PortholeWidget)gw; Widget child = find_child (pw); /* ignore extra children */ if (child) { if (!XtIsRealized (gw)) { XtWidgetGeometry geom, retgeom; geom.request_mode = 0; if (XtWidth(pw) == 0) { geom.width = XtWidth(child); geom.request_mode |= CWWidth; } if (XtHeight(pw) == 0) { geom.height = XtHeight(child); geom.request_mode |= CWHeight; } if (geom.request_mode && XtMakeGeometryRequest (gw, &geom, &retgeom) == XtGeometryAlmost) (void)XtMakeGeometryRequest(gw, &retgeom, NULL); } XtResizeWidget(child, Max(XtWidth(child), XtWidth(pw)), Max(XtHeight(child), XtHeight(pw)), 0); SendReport(pw, XawPRAll); } }
static void ChangeManaged(Widget wid) { XmGrabShellWidget gs = (XmGrabShellWidget)wid; ShellWidget shell = (ShellWidget)wid; Dimension bw = 0; XtWidgetGeometry pref, mygeom, replygeom; XtGeometryResult result; Widget child; mygeom.request_mode = 0; if (gs->composite.num_children) { child = gs->composite.children[0]; if (XtIsManaged(child)) { /* Get child's preferred size */ result = XtQueryGeometry(child, NULL, &pref); /* Take whatever they want */ if (pref.request_mode & CWWidth) { mygeom.width = pref.width; mygeom.request_mode |= CWWidth; } if (pref.request_mode & CWHeight) { mygeom.height = pref.height; mygeom.request_mode |= CWHeight; } if (pref.request_mode & CWBorderWidth) bw = pref.border_width; else bw = child->core.border_width; } } mygeom.width += 2*bw + 2*gs->grab_shell.shadow_thickness; mygeom.height += 2*bw + 2*gs->grab_shell.shadow_thickness; result = XtMakeGeometryRequest((Widget)shell, &mygeom, &replygeom); switch (result) { case XtGeometryAlmost: XtMakeGeometryRequest((Widget)shell, &replygeom, NULL); /* fall through. */ case XtGeometryYes: DoLayout(wid); break; case XtGeometryNo: case XtGeometryDone: break; } }
/* * Function: * ChangeFormGeometry * * Parameters: * w - Form widget * query_only - is only a query? * width - new width and height * height - "" * ret_width - actual size the form is allowed to resize to (return) * ret_height - "" * * Description: * Ask the parent to change the form widget's geometry. * * Returns: * True of children may always be resized */ static Bool ChangeFormGeometry(Widget w, Bool query_only, unsigned int width, unsigned int height, Dimension *ret_width, Dimension *ret_height) { FormWidget fw = (FormWidget)w; Boolean always_resize_children; XtGeometryResult result; XtWidgetGeometry request, return_request; /* * If we are already at the desired size then there is no need * to ask our parent of we can change size */ if (width == XtWidth(fw) && height == XtHeight(fw)) return (True); request.width = width; request.height = height; request.request_mode = CWWidth | CWHeight; if (query_only) request.request_mode |= XtCWQueryOnly; /* * Do no invoke the resize rules if our size changes here */ fw->form.resize_is_no_op = True; result = XtMakeGeometryRequest(w, &request, &return_request); if (result == XtGeometryAlmost) { request = return_request; (void)XtMakeGeometryRequest(w, &request, &return_request); always_resize_children = False; } else always_resize_children = result == XtGeometryYes; fw->form.resize_is_no_op = False; if (ret_width != NULL) *ret_width = request.width; if (ret_height != NULL) *ret_height = request.height; return (always_resize_children); }
static void compute_height (RestraintWidget w, Widget child) { XtGeometryResult result; XtWidgetGeometry reply, intended; XtWidgetGeometry my_request, my_reply; /* -------- See how big the kid wants to be. -------- */ /* Let it know we plan to change his width. */ intended.request_mode = CWWidth; intended.width = w->core.width; XtQueryGeometry (child, &intended, &reply); ON_DEBUG(printf ("In Restraint::compute_height, child wants to be:\n")); ON_DEBUG(printf (" Width: %d, Height: %d\n", reply.width, reply.height)); /* -------- Check with my parent for the change. -------- */ if (reply.height != 0) { my_request.request_mode = CWHeight; my_request.height = reply.height; ON_DEBUG(printf ("Restraint: Asking parent for height %d\n", reply.height)); result = XtMakeGeometryRequest ((Widget) w, &my_request, &my_reply); if (result == XtGeometryAlmost) { ON_DEBUG(printf (" Parent said Almost\n")); /* Go with suggestion if we can get taller. */ if (my_reply.height > w->core.height) { ON_DEBUG(printf (" Asking again for %d\n", my_reply.height)); my_request.height = my_reply.height; /* Parent must say Yes. */ XtMakeGeometryRequest ((Widget) w, &my_request, NULL); } } else if (result == XtGeometryYes) ON_DEBUG(printf (" Parent said Yes.\n")); else if (result == XtGeometryNo) ON_DEBUG(printf (" Parent said No.\n")); else ON_DEBUG(printf (" *** Impossible Reply = %d ***\n", result)); } ON_DEBUG(printf ("Restraint: compute_height = %d\n", w->core.height)); }
static XtGeometryResult TestSmaller(ViewportWidget w, XtWidgetGeometry *request, XtWidgetGeometry *reply_return) { if (request->width < XtWidth(w) || request->height < XtHeight(w)) return (XtMakeGeometryRequest((Widget)w, request, reply_return)); return (XtGeometryYes); }
static void compute_width (RestraintWidget w, Widget child) { XtGeometryResult result; XtWidgetGeometry reply; XtWidgetGeometry my_request, my_reply; /* Let's see how big the kid wants to be. */ XtQueryGeometry (child, NULL, &reply); ON_DEBUG(printf ("In Restraint::compute_width, child wants to be:\n")); ON_DEBUG(printf (" Width: %d, Height: %d\n", reply.width, reply.height)); /* Try to grow if the child wants to be wider. */ if (reply.width > w->core.width) { my_request.request_mode = CWWidth; my_request.width = reply.width; ON_DEBUG(printf ("Restraint: Asking parent width = %d\n", reply.width)); result = XtMakeGeometryRequest ((Widget) w, &my_request, &my_reply); /* Go with parent suggestion on almost. */ if (result == XtGeometryAlmost) { ON_DEBUG(printf (" Parent said Almost.\n")); ON_DEBUG(printf (" Using suggested width of %d\n", my_reply.width)); my_request.width = my_reply.width; /* Parent must say Yes. */ XtMakeGeometryRequest ((Widget) w, &my_request, NULL); } else if (result == XtGeometryYes) ON_DEBUG(printf (" Parent said Yes\n")); else if (result == XtGeometryNo) ON_DEBUG(printf (" Parent said No\n")); else ON_DEBUG(printf (" *** Impossible Reply = %d ***\n", result)); } ON_DEBUG(printf ("Restraint: compute_width = %d\n", w->core.width)); }
static Bool GetGeometry(Widget w, unsigned int width, unsigned int height) { XtWidgetGeometry geometry, return_geom; XtGeometryResult result; if (width == XtWidth(w) && height == XtHeight(w)) return (False); geometry.request_mode = CWWidth | CWHeight; geometry.width = width; geometry.height = height; if (XtIsRealized(w)) { if (((ViewportWidget)w)->viewport.allowhoriz && width > XtWidth(w)) geometry.width = XtWidth(w); if (((ViewportWidget)w)->viewport.allowvert && height > XtHeight(w)) geometry.height = XtHeight(w); } else { /* This is the Realize call; we'll inherit a w&h iff none currently */ if (XtWidth(w) != 0) { if (XtHeight(w) != 0) return (False); geometry.width = XtWidth(w); } if (XtHeight(w) != 0) geometry.height = XtHeight(w); } result = XtMakeGeometryRequest(w, &geometry, &return_geom); if (result == XtGeometryAlmost) result = XtMakeGeometryRequest(w, &return_geom, NULL); return (result == XtGeometryYes); }
void SetDevice (DviWidget dw, const char *name) { XtWidgetGeometry request, reply; XtGeometryResult ret; ForgetFonts (dw); dw->dvi.device = device_load (name); if (!dw->dvi.device) return; dw->dvi.sizescale = dw->dvi.device->sizescale; dw->dvi.device_resolution = dw->dvi.device->res; dw->dvi.native = dw->dvi.device->X11; dw->dvi.paperlength = dw->dvi.device->paperlength; dw->dvi.paperwidth = dw->dvi.device->paperwidth; if (dw->dvi.native) { dw->dvi.display_resolution = dw->dvi.device_resolution; dw->dvi.scale_factor = 1.0; } else { dw->dvi.display_resolution = dw->dvi.default_resolution; dw->dvi.scale_factor = ((double)dw->dvi.display_resolution / dw->dvi.device_resolution); } request.request_mode = CWWidth|CWHeight; request.width = MY_WIDTH(dw); request.height = MY_HEIGHT(dw); ret = XtMakeGeometryRequest ((Widget)dw, &request, &reply); if (ret == XtGeometryAlmost && reply.height >= request.height && reply.width >= request.width) { request.width = reply.width; request.height = reply.height; XtMakeGeometryRequest ((Widget)dw, &request, &reply); } }
/*ARGSUSED*/ static XtGeometryResult XawVendorShellGeometryManager(Widget wid, XtWidgetGeometry *request, XtWidgetGeometry *reply) { ShellWidget shell = (ShellWidget)(wid->core.parent); XtWidgetGeometry my_request; if(shell->shell.allow_shell_resize == FALSE && XtIsRealized(wid)) return(XtGeometryNo); if (request->request_mode & (CWX | CWY)) return(XtGeometryNo); /* %%% worry about XtCWQueryOnly */ my_request.request_mode = 0; if (request->request_mode & CWWidth) { my_request.width = request->width; my_request.request_mode |= CWWidth; } if (request->request_mode & CWHeight) { my_request.height = request->height + _XawImGetImAreaHeight( wid ); my_request.request_mode |= CWHeight; } if (request->request_mode & CWBorderWidth) { my_request.border_width = request->border_width; my_request.request_mode |= CWBorderWidth; } if (XtMakeGeometryRequest((Widget)shell, &my_request, NULL) == XtGeometryYes) { /* assert: if (request->request_mode & CWWidth) then * shell->core.width == request->width * assert: if (request->request_mode & CWHeight) then * shell->core.height == request->height * * so, whatever the WM sized us to (if the Shell requested * only one of the two) is now the correct child size */ wid->core.width = shell->core.width; wid->core.height = shell->core.height; if (request->request_mode & CWBorderWidth) { wid->core.x = wid->core.y = -request->border_width; } _XawImCallVendorShellExtResize(wid); return XtGeometryYes; } else return XtGeometryNo; }
static XtGeometryResult GeometryRequestPlusScrollbar(ViewportWidget w, Bool horizontal, XtWidgetGeometry *request, XtWidgetGeometry *reply_return) { Widget sb; XtWidgetGeometry plusScrollbars; plusScrollbars = *request; if ((sb = w->viewport.horiz_bar) == NULL) sb = CreateScrollbar(w, horizontal); request->width += XtWidth(sb); request->height += XtHeight(sb); XtDestroyWidget(sb); return (XtMakeGeometryRequest((Widget)w, &plusScrollbars, reply_return)); }
/* * border width and size and location are ty... * * 1. We allow the border width of a XmDialogShell child to change * size arbitrarily. * * 2. The border width of the shell widget tracks the child's * at all times, exactly. * * 3. The width of the shell is kept exactly the same as the * width of the child at all times. * * 4. The child is always positioned at the location * (- child_border, - child_border). * * the net result is the child has a border width which is always * what the user asked for; but none of it is ever seen, it's all * clipped by the shell (parent). The user sees the border * of the shell which is the size he set the child's border to. * * In the DEC window manager world the window manager does * exactly the same thing with the window it puts around the shell. * Hence the shell and child have a border width just as the user * set but the window manager overrides that and only a single * pixel border is displayed. In a non-wm environment the child * appears to have a border width, in reality this is the shell * widget border. You wanted to know... */ static void ChangeManaged( Widget wid ) { XmDialogShellWidget shell = (XmDialogShellWidget) wid ; /* * If the child went to unmanaged, call XtPopdown. * If the child went to managed, call XtPopup. */ Widget child; XmWidgetExtData extData = _XmGetWidgetExtData((Widget) shell, XmSHELL_EXTENSION); XmVendorShellExtObject ve = (XmVendorShellExtObject)extData->widget; XmDialogSavvyTrait trait ; if (((child = GetRectObjKid((CompositeWidget) shell)) == NULL) || (child->core.being_destroyed)) return; trait = (XmDialogSavvyTrait) XmeTraitGet((XtPointer) XtClass(child), XmQTdialogShellSavvy) ; /* MANAGED Case first ********/ if (child->core.managed) { XtWidgetGeometry request; Position kidX, kidY; Dimension kidBW; Boolean defaultPosition = True; /* * temporary workaround for setkeyboard focus ||| */ if (child != ve->vendor.old_managed) { XtSetKeyboardFocus((Widget)shell, (Widget)child); ve->vendor.old_managed = (Widget)child; } /* * if the child isn't realized, then we need to realize it * so we have a valid size. It will get created as a result * so we zero out it's position info so it'll * be okay and then restore it. */ if (!XtIsRealized(child)) { kidX = XtX(child); kidY = XtY(child); kidBW = XtBorderWidth(child); XtX(child) = 0; XtY(child) = 0; XtBorderWidth(child) = 0; /* Bug 4102306, This is an additional difference brought forward from motif 1.2 */ if (XtHeight(shell) != XtHeight(child)) { _XmImChangeManaged((Widget)shell); } /* End fix for Bug 4012306 */ XtRealizeWidget(child); XtX(child) = kidX; XtY(child) = kidY; XtBorderWidth(child) = kidBW; } else if (trait) { /* * Move the window to 0,0 * but don't tell the widget. It thinks it's where * the shell is... */ if ((XtX(child) != 0) || (XtY(child) != 0)) XMoveWindow (XtDisplay(child), XtWindow(child), 0, 0); } /* * map callback should occur BEFORE child default positioning * otherwise, widgets such as fileselection using map callback for * correct sizing have default positioning done before the widget * grows to its correct dimensions */ if(shell->core.mapped_when_managed && trait ) { trait->callMapUnmapCB(child, True); /* call Map callback */ } /* * Make sure that the shell has the same common parameters as * its child. Then move the child so that the shell will * correctly surround it. */ request.request_mode = 0; if (trait) { XtVaGetValues(child, XmNdefaultPosition, &defaultPosition, NULL); if (defaultPosition && (ve->vendor.externalReposition)) { defaultPosition = False; XtVaSetValues(child, XmNdefaultPosition, False, NULL); } } if (XtX(child) && trait) { kidX = XtX(child); XtX(child) = 0; } else kidX = XtX(shell); if (XtY(child) && trait) { kidY = XtY(child); XtY(child) = 0; } else kidY = XtY(shell); if (XtBorderWidth(child) && trait) { kidBW = XtBorderWidth(child); XtBorderWidth(child) = 0; } else kidBW = XtBorderWidth(shell); if (XtWidth (child) != XtWidth (shell)) { request.request_mode |= CWWidth; request.width = XtWidth(child); } if (XtHeight (child) + ve->vendor.im_height != XtHeight (shell)) { request.request_mode |= CWHeight; request.height = XtHeight(child) + ve->vendor.im_height; } if (trait) { if (defaultPosition) { GetDefaultPosition(child, XtParent(shell), &request.x, &request.y); if (request.x != kidX) request.request_mode |= CWX; if (request.y != kidY) request.request_mode |= CWY; } else { if (kidX != XtX(shell)) { request.request_mode |= CWX; if (kidX == XmDIALOG_SAVVY_FORCE_ORIGIN) request.x = 0; else request.x = kidX; } if (kidY != XtY(shell)) { request.request_mode |= CWY; if (kidY == XmDIALOG_SAVVY_FORCE_ORIGIN) request.y = 0; else request.y = kidY; } } } else { if (kidX != XtX(shell)) { request.request_mode |= CWX; request.x = kidX; } if (kidY != XtY(shell)) { request.request_mode |= CWY; request.y = kidY; } if (kidBW != XtBorderWidth(shell)) { request.request_mode |= CWBorderWidth; request.border_width = kidBW; } } if (request.request_mode) { unsigned int old_height = ve->vendor.im_height; XtMakeGeometryRequest((Widget) shell, &request, &request); _XmImResize((Widget)shell); if (ve->vendor.im_height != old_height) { request.request_mode = CWHeight; request.height = XtHeight(child) + ve->vendor.im_height; XtMakeGeometryRequest((Widget) shell, &request, &request); _XmImResize((Widget)shell); } } /* * the grab_kind is handled in the popup_callback */ if(shell->core.mapped_when_managed ) { XtPopup ((Widget) shell, XtGrabNone); } } /* * CHILD BEING UNMANAGED */ else { int i, j; /* * Fix for CR5043, CR5758 and CR8825 - * For nested Dialog Shells, it is necessary to unmanage * dialog shell popups of the child of this dialog shell. */ for (i = 0; i < child->core.num_popups; i++) { if (XmIsDialogShell(child->core.popup_list[i])) { XmDialogShellWidget next_shell = (XmDialogShellWidget)(child->core.popup_list[i]); for (j = 0; j < next_shell->composite.num_children; j++) { XtUnmanageChild(next_shell->composite.children[j]); } } } /* End Fix CR5043, CR5758 and CR8825 */ /* * take it down and then tell user */ XtPopdown((Widget) shell); if(trait ) { trait->callMapUnmapCB(child, False); /* call UnMap callback */ } } XmeNavigChangeManaged((Widget) shell); }
/************************************************************************ * * * GeometryManager * * * ************************************************************************/ static XtGeometryResult GeometryManager( Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply ) { CompositeWidgetClass superclass = (CompositeWidgetClass) xmMainWindowClassRec.core_class.superclass ; XmMainWindowWidget mw = (XmMainWindowWidget ) w->core.parent; XtGeometryResult res; Dimension newWidth,newHeight, OldHeight; Dimension bw; XtWidgetGeometry parent_request ; XtWidgetGeometry desired, preferred; XtWidgetProc resize; CheckKids(mw); /**************** * * If it's not a mainwindow kid, let the scrolled window deal with it. * If it's from the workwindow, and the width changed, resize the menubar * and ask for a new height so my layout routine doesn't clip the workwindow. * ****************/ if (w != mw->mwindow.MenuBar && w != mw->mwindow.Message && w != mw->mwindow.CommandWindow && w != (Widget )mw->mwindow.Sep1 && w != (Widget) mw->mwindow.Sep2 && w != (Widget) mw->mwindow.Sep3) { /* this is the only case of geometry manager enveloping that I know of in Motif */ XtGeometryHandler geo_mgr; _XmProcessLock(); geo_mgr = superclass->composite_class.geometry_manager; _XmProcessUnlock(); res = (*geo_mgr)(w, request, reply); if (res == XtGeometryYes) { Widget mb = mw->mwindow.MenuBar; if ((w == mw->swindow.WorkWindow) && (request->request_mode & CWWidth) && mb && XtIsManaged(mb)) { desired.x = mb->core.x; desired.y = mb->core.y; desired.border_width = mb->core.border_width; desired.width = mw->core.width - (2 * mw->mwindow.margin_width); desired.height = mb->core.height; desired.request_mode = (CWWidth); XtQueryGeometry(mw->mwindow.MenuBar, &desired, &preferred); if (preferred.height != mb->core.height) { parent_request.request_mode = CWWidth | CWHeight; if (request->request_mode & XtCWQueryOnly) parent_request.request_mode |= XtCWQueryOnly; parent_request.width = mw->core.width ; parent_request.height = newHeight = mw->core.height - (mb->core.height - (2 * mb->core.border_width)) + preferred.height + (2 *preferred.border_width); if (XtMakeGeometryRequest((Widget) mw, &parent_request, NULL) == XtGeometryYes) { if (!(request->request_mode & XtCWQueryOnly)) XmeConfigureObject(mw->mwindow.MenuBar, mb->core.x, mb->core.y, preferred.width, preferred.height, preferred.border_width); else return XtGeometryYes ; } } } _XmProcessLock(); resize = XtCoreProc(mw, resize); _XmProcessUnlock(); (*resize)((Widget)mw) ; } return(res); } /** Disallow any X or Y changes for MainW children **/ if ((request -> request_mode & CWX || request -> request_mode & CWY)) return(XtGeometryNo); if(request->request_mode & CWBorderWidth) bw = request->border_width; else bw = w->core.border_width; if (request->request_mode & CWWidth) newWidth = request->width + 2 * (bw + mw->mwindow.margin_width); else newWidth = mw->core.width ; /* grow only in width */ if (newWidth <= mw->core.width) newWidth = mw->core.width; /**************** * * Margins are already included in the old width & height * ****************/ if(request->request_mode & CWHeight) newHeight = mw->core.height - (w->core.height - (2 * w->core.border_width)) + request->height + 2 * bw; else newHeight = mw->core.height; OldHeight = mw->core.height; parent_request.request_mode = CWWidth | CWHeight; if (request->request_mode & XtCWQueryOnly) parent_request.request_mode |= XtCWQueryOnly; parent_request.width = newWidth ; parent_request.height = newHeight; res = XtMakeGeometryRequest((Widget) mw, &parent_request, NULL) ; if (res == XtGeometryYes) { if (!(request->request_mode & XtCWQueryOnly)) { if(request->request_mode & CWWidth) w->core.width = request->width; if(request->request_mode & CWHeight) w->core.height = request->height; mw->swindow.YOffset = mw->swindow.YOffset + (newHeight - OldHeight); _XmProcessLock(); resize = XtCoreProc(mw, resize); _XmProcessUnlock(); (*resize) ((Widget)mw) ; } } return(res); }
/**************************************************************** * Calculate the size needed for the Manager * Request a change in size from parent if needed. ****************/ Boolean _XmGMDoLayout(XmManagerWidget manager, #if NeedWidePrototypes int margin_width, int margin_height, #else Dimension margin_width, Dimension margin_height, #endif /* NeedWidePrototypes */ int resize_policy, #if NeedWidePrototypes int queryonly #else Boolean queryonly #endif /* NeedWidePrototypes */ ) { /* return: True means that the layout is accepted, either with no request to the parent, or with a successfull serie of requests. No means that the layout is denied, without request (NONE policy for instance) or with request (parent does not accept the change in size or proposes something unacceptable). Note that when the parent returns almost, since this function returns either true or false (see below), we don't handle almost reply to the instigator. The queryonly flag just controls the "reality" of the parent request and the call to resize. */ XtWidgetGeometry request ; XtWidgetGeometry reply ; XtWidgetProc resize; request.request_mode = CWWidth|CWHeight ; if (queryonly) request.request_mode |= XtCWQueryOnly ; _XmGMCalcSize(manager, margin_width, margin_height, &request.width, &request.height); /* no change, just accept it */ if ((XtWidth(manager) == request.width) && (XtHeight(manager) == request.height)) return (True); /* the current manager sizes are bigger than the new ones and we don't want to strink, just accept the layout as is, since it already fits */ if ((resize_policy == XmRESIZE_GROW || resize_policy == XmRESIZE_NONE) && ((XtWidth(manager) >= request.width) && (XtHeight(manager) >= request.height)) ) return (True); /* the previous test passes over, so one of the needed sizes must be bigger than one of the current, and we can't do that with NONE */ if (resize_policy == XmRESIZE_NONE ) return (False); /* we can't shrink on one side while growing on the other, just overwrite the shrinking side */ if(resize_policy == XmRESIZE_GROW ) { if(request.width < XtWidth(manager)) request.width = XtWidth(manager) ; if(request.height < XtHeight(manager)) request.height = XtHeight(manager) ; } _XmProcessLock(); resize = XtCoreProc(manager,resize); _XmProcessUnlock(); /* now the request */ switch(XtMakeGeometryRequest((Widget)manager, &request, &reply)) { case XtGeometryYes: if (!queryonly) /* call the resize proc, since the widget set has now a Yes policy */ (*resize)((Widget)manager) ; return(True) ; case XtGeometryAlmost: /* The following behavior is based on the shrink wrapper behavior of this manager. What we have asked is the minimum. If the almost returned size is smaller than the requested one, refuse, since it will always clip something */ if ((reply.width < request.width) || (reply.height < request.height)) { return( False) ; } else { /* if almost returned a bigger size than requested, accept it since it cannot hurt the shrink wrap behavior, neither the Grow policy (requested always > current). Apply it if not queryonly. If queryonly, we don't have to re-request something, since no change is needed and we already know it's OK */ if (!queryonly) { (void) XtMakeResizeRequest((Widget)manager, reply.width, reply.height, NULL, NULL) ; (*resize)((Widget)manager) ; } return(True) ; } case XtGeometryNo: default: break ; } return( False) ; }
/************************************************************************ * * Geometry Manager * Take the requested geometry, calculate the needed size for * the frame and make a request to the frames parent. * Requests to change x, y position are always denied. * ************************************************************************/ static XtGeometryResult GeometryManager( Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply ) { XmFrameWidget fw = (XmFrameWidget) XtParent(w); Widget title_area = fw->frame.title_area; Widget work_area = fw->frame.work_area; Dimension req_width, req_height, req_bw; Boolean query_only = False; Boolean almost = False; Dimension title_width = (title_area)?title_area->core.width:0; Dimension title_height = (title_area)?title_area->core.height:0; Dimension title_bw = (title_area)?title_area->core.border_width:0; Dimension work_width = (work_area)?work_area->core.width:0; Dimension work_height = (work_area)?work_area->core.height:0; Dimension work_bw = (work_area)?work_area->core.border_width:0; Dimension frame_width, frame_height; XtWidgetGeometry parent_request; XtWidgetGeometry parent_reply; Dimension almost_width; Dimension almost_height; if (fw->frame.processing_constraints) { fw->frame.processing_constraints = False; request -> border_width -= 1; } /* Set up the calculation variables according to the */ /* contents of the requested geometry. */ if (request -> request_mode & XtCWQueryOnly) query_only = True; if ((request -> request_mode & CWX) || (request -> request_mode & CWY)) almost = True; if (request -> request_mode & CWWidth) req_width = request -> width; else req_width = w -> core.width; if (request -> request_mode & CWHeight) req_height = request -> height; else req_height = w -> core.height; if (request -> request_mode & CWBorderWidth) req_bw = request -> border_width; else req_bw = w -> core.border_width; if (w == title_area) { title_width = req_width; title_height = req_height; title_bw = req_bw; } if (w == work_area) { work_width = req_width; work_height = req_height; work_bw = req_bw; } /* find the frame size based on the children preferred geometry */ CalcFrameSize (fw, title_width, title_height, title_bw, work_width, work_height, work_bw, &frame_width, &frame_height); parent_request.request_mode = CWWidth | CWHeight; if (almost || query_only) parent_request.request_mode |= XtCWQueryOnly; parent_request.width = frame_width; parent_request.height = frame_height; switch (XtMakeGeometryRequest ((Widget)fw, &parent_request, &parent_reply)) { case XtGeometryYes: if (!almost) { if (!query_only) { ClearShadow(fw); ConfigureChildren(fw, w, request); DrawShadow(fw); } return (XtGeometryYes); } else { almost_width = request->width; almost_height = request->height; } break; case XtGeometryNo: if (w == title_area) { /* we got a No, try to honor the title request anyway, by resizing the work_area child */ if (!almost) { if (!query_only) { ClearShadow(fw); ConfigureChildren(fw, w, request); DrawShadow(fw); } return (XtGeometryYes); } else { almost_width = request->width; almost_height = request->height; } } else return (XtGeometryNo); break; case XtGeometryAlmost: if (w == title_area) { /* we got an Almost, try to honor the title request anyway, by accepting the deal and resizing the work_area child */ if (!almost) { if (!query_only) { ClearShadow(fw); XtMakeResizeRequest((Widget)fw, parent_reply.width, parent_reply.height, NULL, NULL); ConfigureChildren(fw, w, request); } return (XtGeometryYes); } else { almost_width = request->width; almost_height = request->height; } } else { /* we got an Almost, accept the deal and compute the work_area size */ CalcWorkAreaSize (fw, &almost_width, &almost_height, req_bw, parent_reply.width, parent_reply.height); } break; default: return (XtGeometryNo); break; } /* Fallen through to an almost condition. Clear the x and y */ /* and set the width, height, and border. */ if (reply != NULL) { reply -> request_mode = request -> request_mode & ~(CWX | CWY); reply -> width = almost_width; reply -> height = almost_height; reply -> border_width = req_bw; if (request -> request_mode & CWSibling) reply -> sibling = request -> sibling; if (request -> request_mode & CWStackMode) reply -> stack_mode = request -> stack_mode; return (XtGeometryAlmost); } return (XtGeometryNo); }
/*ARGSUSED*/ static XtGeometryResult GeometryManager( Widget wid, XtWidgetGeometry *request, XtWidgetGeometry *reply ) /* unused */ { ShellWidget shell = (ShellWidget)(wid->core.parent); XtWidgetGeometry my_request; XmVendorShellExtObject ve; XmWidgetExtData extData; extData = _XmGetWidgetExtData((Widget)shell, XmSHELL_EXTENSION); ve = (XmVendorShellExtObject) extData->widget; if(!(shell->shell.allow_shell_resize) && XtIsRealized(wid) && (request->request_mode & (CWWidth | CWHeight | CWBorderWidth))) return(XtGeometryNo); /* * Because of our klutzy API we mimic position requests on the * dialog to ourselves. * We cannot check for the trait here since it isn't done only for * BB. DialogShell GM behavior is to always follow position requests * even if the child is not dialogShellSavvy. */ my_request.request_mode = 0; /* %%% worry about XtCWQueryOnly */ if (request->request_mode & XtCWQueryOnly) my_request.request_mode |= XtCWQueryOnly; /* Here we have a tricky bit of code. If the SetValues on the bb child position was 0, which is always the current position of the bb, Xt will not see a change and therefore not trigerred a geometry request. So BB (or any dialogShellSavvy child) has to catch this case and change the position request to use a special value, XmDIALOG_SAVVY_FORCE_ORIGIN, to notify the Dialog that it wants to move in 0 */ if (request->request_mode & CWX) { if (request->x == XmDIALOG_SAVVY_FORCE_ORIGIN) my_request.x = 0; else my_request.x = request->x; my_request.request_mode |= CWX; } if (request->request_mode & CWY) { if (request->y == XmDIALOG_SAVVY_FORCE_ORIGIN) my_request.y = 0; else my_request.y = request->y; my_request.request_mode |= CWY; } if (request->request_mode & CWWidth) { my_request.width = request->width; my_request.request_mode |= CWWidth; } if (request->request_mode & CWHeight) { if (!ve->vendor.im_height) _XmImResize((Widget)shell); /* updates im_height */ my_request.height = request->height + ve->vendor.im_height; my_request.request_mode |= CWHeight; } if (request->request_mode & CWBorderWidth) { my_request.border_width = request->border_width; my_request.request_mode |= CWBorderWidth; } if (XtMakeGeometryRequest((Widget)shell, &my_request, NULL) == XtGeometryYes) { if (!(request->request_mode & XtCWQueryOnly)) { /* just report the size changes to the kid, not the dialog position itself, but reply yes anyway */ if (my_request.request_mode & CWWidth) wid->core.width = my_request.width ; _XmImResize((Widget)shell); if (my_request.request_mode & CWHeight) wid->core.height = my_request.height - ve->vendor.im_height; } return XtGeometryYes; } else return XtGeometryNo; }
static XtGeometryResult GeometryManager (Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply) { Widget restraint = w->core.parent; Boolean almost = False, yes = False; /* Always give some kind of reply to each request. */ reply->request_mode = request->request_mode; ON_DEBUG(printf ("Restraint: Child '%s' requesting:\n", XtName (w))); if (request->request_mode & CWX) { ON_DEBUG(printf (" X: %d\n", request->x)); reply->x = w->core.x; } if (request->request_mode & CWY) { ON_DEBUG(printf (" Y: %d\n", request->y)); reply->y = w->core.y; } #ifdef DEBUG if (request->request_mode & CWWidth) { printf (" Width: %d\n", request->width); /* Detect conditions under which a Form bug occurs. If the Form request a width increase and a height change, this widget refuses the width change, and the bogus Form bails on the height change. The result is a totally messed up Form layout. Therefore, the query editor must coerce the Form into never requesting a width increase. */ if (request->width > w->core.width) { fprintf (stderr, "Severe warning: query term requesting width increase\n"); fprintf (stderr, " File a DTS bug immediately!!!\n"); if (request->request_mode & CWHeight) abort(); } } if (request->request_mode & CWHeight) printf (" Height: %d\n", request->height); #endif if (request->request_mode & CWBorderWidth) { ON_DEBUG(printf (" Border: %d\n", request->border_width)); reply->border_width = w->core.border_width; } if (request->request_mode & (CWBorderWidth | CWX | CWY)) almost = True; /* Only allow width changes to the width of the restraint. */ if (request->request_mode & CWWidth) if (request->width == restraint->core.width) yes = True; else almost = True; /* Allow any height changes */ if (request->request_mode & CWHeight) yes = True; if (yes && !almost) { /* Change is acceptable. See if parent will accommodate. */ XtWidgetGeometry my_request, my_reply; XtGeometryResult result; /* Only need to check width and height below, because they are the only requests that can generate a yes. */ my_request.request_mode = 0; if (request->request_mode & CWHeight) { my_request.request_mode |= CWHeight; my_request.height = request->height; ON_DEBUG(printf ("Restraint: requesting height of %d\n", my_request.height)); } if (request->request_mode & CWWidth) { my_request.request_mode |= CWWidth; my_request.width = request->width; ON_DEBUG(printf ("Restraint: requesting width of %d\n", my_request.width)); } result = XtMakeGeometryRequest (restraint, &my_request, &my_reply); /* Stick with current values if it said No. */ if (result == XtGeometryNo) { ON_DEBUG(puts ("Restraint: Parent said no")); } /* Need to go with parent's width and height if it said Almost. */ else if (result == XtGeometryAlmost) { ON_DEBUG(puts ("Restraint: Parent said almost -->")); ON_DEBUG(puts ("Restraint: responding XtGeometryAlmost:")); /* reply->request_mode = 0; */ if (request->request_mode & CWHeight) { ON_DEBUG(printf (" Height: %d\n", reply->height)); /* reply->request_mode |= CWHeight; */ /* Allow height change if parent didn't mind. */ if (my_reply.request_mode & CWHeight) reply->height = request->height; else reply->height = w->core.height; } if (request->request_mode & CWWidth) { ON_DEBUG(printf (" Width: %d\n", reply->width)); /* reply->request_mode |= CWWidth; */ /* Allowable width is always the restraint width. */ reply->width = restraint->core.width; } } /* Everything's cool if it said Yes. */ else if (result == XtGeometryYes) { ON_DEBUG(puts ("Restraint: Parent said yes")); ON_DEBUG(puts ("Restraint: responding XtGeometryYes.")); if (request->request_mode & CWHeight) { w->core.height = request->height; } if (request->request_mode & CWWidth) { /* Sanity Check: Yes on width is only allowed if this is true. */ /* This means that width changes are essentially not allowed. */ if (w->core.width != restraint->core.width) abort(); } } /* If parent said No, stick around and return Almost later on. */ if (result != XtGeometryNo) return (result); } /* Not a simple Yes, so it'll be an Almost reply. */ /* Either 1) widget tried to change some things I don't like, or 2) my parent didn't allow the changes requested. */ if (yes || almost) { ON_DEBUG(puts ("Restraint: responding XtGeometryAlmost:")); if (request->request_mode & CWX) ON_DEBUG(printf (" X: %d\n", reply->x)); if (request->request_mode & CWY) ON_DEBUG(printf (" Y: %d\n", reply->y)); if (request->request_mode & CWBorderWidth) ON_DEBUG(printf (" BorderWidth: %d\n", reply->border_width)); if (request->request_mode & CWWidth) { ON_DEBUG(printf (" Width: %d\n", w->core.width)); reply->request_mode |= CWWidth; /* Always reply with restraint's width for child width. */ reply->width = restraint->core.width; } if (request->request_mode & CWHeight) { /* Check with parent before allowing a height change. */ XtWidgetGeometry my_request, my_reply; XtGeometryResult result; ON_DEBUG(printf (" Checking with parent for Almost height value:\n")); my_request.request_mode = CWHeight & XtCWQueryOnly; my_request.height = request->height; ON_DEBUG(printf (" Asking for height = %d\n", my_request.height)); result = XtMakeGeometryRequest (restraint, &my_request, &my_reply); if (result == XtGeometryNo) /* unable to comply */ { ON_DEBUG(printf (" Parent said No.\n")); reply->height = w->core.height; } else if (result == XtGeometryAlmost) /* partial compliance */ { ON_DEBUG(printf (" Parent said Almost.\n")); reply->height = my_reply.height; } else if (result == XtGeometryYes) /* total compliance */ { ON_DEBUG(printf (" Parent said Yes.\n")); reply->height = request->height; } ON_DEBUG(printf (" Height: %d\n", reply->height)); reply->request_mode |= CWHeight; } return (XtGeometryAlmost); } /* If we got here something is wrong, so bomb out. */ abort(); }