/**************************************************************** * * XmeReplyToQueryGeometry. * * This is the generic handling of Almost, No and Yes replies * based on the intended values and the given desirs. * * This can be used by any widget that really only care about is * width and height dimension. It just has to compute its desired size * using its own private layout routine and resources before calling * this one that will deal with the Xt reply value cuisine. * ****************/ XtGeometryResult XmeReplyToQueryGeometry(Widget widget, XtWidgetGeometry * intended, XtWidgetGeometry * desired) { _XmWidgetToAppContext(widget); /* the caller should have set desired width and height*/ desired->request_mode = (CWWidth | CWHeight) ; /* Accept any x, y, border and stacking. If the proposed geometry matches the desired one, and the parent intends to use these values (flags are set in intended), return Yes. Otherwise, the parent intends to use values for width and height that differ from the desired size, return No if the desired is the current and Almost if the desired size is different from the current size */ if ((IsWidth(intended)) && (intended->width == desired->width) && (IsHeight(intended)) && (intended->height == desired->height)) { return XtGeometryYes ; } _XmAppLock(app); if ((desired->width == XtWidth(widget)) && (desired->height == XtHeight(widget))) { _XmAppUnlock(app); return XtGeometryNo ; } _XmAppUnlock(app); return XtGeometryAlmost ; }
/************************************************************************ * * QueryGeometry * return width X height based on the children preferred sizes * ************************************************************************/ static XtGeometryResult QueryGeometry( Widget widget, XtWidgetGeometry *intended, XtWidgetGeometry *desired ) { Dimension work_width = 0, work_height = 0, work_bw = 0 ; Dimension title_width = 0, title_height = 0, title_bw = 0 ; XtWidgetGeometry child_pref ; XmFrameWidget fw = (XmFrameWidget) widget ; /* first determine what is the desired size, using the preferred sizes of the title and the work_area, or the current setting if no preference are given */ if (fw->frame.work_area) { XtQueryGeometry (fw->frame.work_area, NULL, &child_pref); if (IsWidth(&child_pref)) work_width = child_pref.width ; else work_width = XtWidth(fw->frame.work_area); if (IsHeight(&child_pref)) work_height = child_pref.height ; else work_height = XtHeight(fw->frame.work_area); if (IsBorder(&child_pref)) work_bw = child_pref.border_width ; else work_bw = XtBorderWidth(fw->frame.work_area); } if (fw->frame.title_area) { XtQueryGeometry (fw->frame.title_area, NULL, &child_pref); if (IsWidth(&child_pref)) title_width = child_pref.width ; else title_width = XtWidth(fw->frame.title_area); if (IsHeight(&child_pref)) title_height = child_pref.height ; else title_height = XtHeight(fw->frame.title_area); if (IsBorder(&child_pref)) title_bw = child_pref.border_width ; else title_bw = XtBorderWidth(fw->frame.title_area); } CalcFrameSize (fw, title_width, title_height, title_bw, work_width, work_height, work_bw, &desired->width, &desired->height); /* deal with user initial size setting */ if (!XtIsRealized(widget)) { if (XtWidth(widget) != 0) desired->width = XtWidth(widget) ; if (XtHeight(widget) != 0) desired->height = XtHeight(widget) ; } return XmeReplyToQueryGeometry(widget, intended, desired) ; }
/**************** * Handle geometry requests from children. ****************/ XtGeometryResult _XmGMHandleGeometryManager(Widget parent, Widget w, XtWidgetGeometry * request, XtWidgetGeometry * reply, #if NeedWidePrototypes int margin_width, int margin_height, #else Dimension margin_width, Dimension margin_height, #endif /* NeedWidePrototypes */ int resize_policy, int allow_overlap) { /* Policy: Yes if margin is non null requests inside the margin or negative are a priori almosted (or denied if the resizepolicy does not authorize it). That's the only case where almost is returned, no management of a limit position or size is done */ XtWidgetGeometry localReply ; Dimension width, height, borderWidth ; Position x, y ; XtGeometryResult returnCode = XtGeometryNo ; Boolean geoFlag = False, queryonly = False ; XmManagerWidget manager = (XmManagerWidget) parent ; localReply = *request ; localReply.request_mode = CWX|CWY|CWWidth|CWHeight|CWBorderWidth ; if(!IsX(request)) localReply.x = XtX(w) ; if(!IsY(request)) localReply.y = XtY(w) ; if(!IsWidth(request)) localReply.width = XtWidth(w) ; if(!IsHeight(request)) localReply.height = XtHeight(w) ; if(!IsBorder(request)) localReply.border_width = XtBorderWidth(w) ; /* check for x less than margin width */ if(IsX(request) && (margin_width != 0) && (request->x < (int)margin_width)) { localReply.x = (Position) margin_width ; returnCode = XtGeometryAlmost ; } /* check for y less than margin height */ if(IsY(request) && (margin_height != 0) && (request->y < (int)margin_height)) { localReply.y = (Position) margin_height ; returnCode = XtGeometryAlmost ; } /* Save current size and set to new size */ x = XtX(w) ; y = XtY(w) ; width = XtWidth(w) ; height = XtHeight(w) ; borderWidth = XtBorderWidth(w) ; XtX(w) = localReply.x ; XtY(w) = localReply.y ; XtWidth(w) = localReply.width ; XtHeight(w) = localReply.height ; XtBorderWidth(w) = localReply.border_width ; if(!allow_overlap && _XmGMOverlap (manager, w)) { returnCode = XtGeometryNo ; } else { /* if we already know that we are not gonna change anything */ if ((returnCode == XtGeometryAlmost) || IsQueryOnly(request)) queryonly = True ; /* see if the new layout is OK */ geoFlag = _XmGMDoLayout(manager, margin_width, margin_height, resize_policy, queryonly) ; /* if we cannot adapt the new size but the child is still inside go for it */ if(!geoFlag && ((localReply.x + localReply.width + (localReply.border_width << 1)) <= (XtWidth(manager) - margin_width)) && ((localReply.y + localReply.height + (localReply.border_width << 1)) <= (XtHeight(manager) - margin_height))) geoFlag = True ; if (geoFlag) { if (returnCode != XtGeometryAlmost) returnCode = XtGeometryYes ; } else returnCode = XtGeometryNo ; if (returnCode == XtGeometryAlmost){ if (reply) *reply = localReply ; else returnCode = XtGeometryNo ; } } if ((returnCode != XtGeometryYes) || queryonly) { /* Can't oblige, so restore previous values. */ XtX(w) = x ; XtY(w) = y ; XtWidth(w) = width ; XtHeight(w) = height ; XtBorderWidth(w) = borderWidth ; } return returnCode ; }