diff options
Diffstat (limited to 'vendor/x11iraf/obm/ObmW/Frame.man')
-rw-r--r-- | vendor/x11iraf/obm/ObmW/Frame.man | 1062 |
1 files changed, 1062 insertions, 0 deletions
diff --git a/vendor/x11iraf/obm/ObmW/Frame.man b/vendor/x11iraf/obm/ObmW/Frame.man new file mode 100644 index 00000000..66fdb4c3 --- /dev/null +++ b/vendor/x11iraf/obm/ObmW/Frame.man @@ -0,0 +1,1062 @@ +.\"remove .ig hn for full docs +.de hi +.ig eh +.. +.de eh +.. +.TH "" 3 "" "Version 3.0" "Free Widget Foundation" +.SH NAME +XfwfFrame +.SH DESCRIPTION +The Frame widget is a composite widget that accepts just one child. +Its only purpose is to draw a frame around widgets that do not have a +frame of their own. It always uses the size of its child, with a +little extra for the frame. There are several types of frames +available, selectable with a resource. + +Widget writers can also use the Frame class as a superclass for new +widgets. The frame is drawn by the \fIexpose\fP method (which must +therefore be called by subclasses). Its width is given by +\fIXtNframeWidth\fP, the appearance by \fIXtNframeType\fP. The possible types +are: + +\item{\fIXfwfRaised\fP} Gives a beveled look. The top and left borders will +be lighter, the bottom and right sides darker. + +\item{\fIXfwfSunken\fP} Just the opposite. + +\item{\fIXfwfChiseled\fP} The border will look as if it was made with a +chisel. + +\item{\fIXfwfLedged\fP} The border will be a ledge that juts out of the +background. + +.SS "Public variables" + +.ps-2 +.TS +center box; +cBsss +lB|lB|lB|lB +l|l|l|l. +XfwfFrame +Name Class Type Default +XtNcursor XtCCursor Cursor None +XtNframeType XtCFrameType FrameType XfwfRaised +XtNframeWidth XtCFrameWidth Dimension 0 +XtNouterOffset XtCOuterOffset Dimension 0 +XtNinnerOffset XtCInnerOffset Dimension 0 +XtNshadowScheme XtCShadowScheme ShadowScheme XfwfAuto +XtNtopShadowColor XtCTopShadowColor Pixel compute_topcolor +XtNbottomShadowColor XtCBottomShadowColor Pixel compute_bottomcolor +XtNtopShadowStipple XtCTopShadowStipple Bitmap NULL +XtNbottomShadowStipple XtCBottomShadowStipple Bitmap NULL + +.TE +.ps + +.TP +.I "XtNcursor" +The cursor (when not \fINone\fP) is the mouse cursor that is displayed +when the mouse is over the Board widget. The default value \fINone\fP +causes the parent's cursor to be used. + + + +.hi + +.nf +Cursor cursor = None +.fi + +.eh + +.TP +.I "XtNframeType" +The \fIXtNframeType\fP determines how the border looks. + + + +.hi + +.nf +FrameType frameType = XfwfRaised +.fi + +.eh + +.TP +.I "XtNframeWidth" +\fIXtNframeWidth\fP gives the width of the border. The default value +of 0 shows no border at all. The border is drawn {\it inside\/} the +widget. (See also \fIXtNouterOffset\fP.) + + + +.hi + +.nf +Dimension frameWidth = 0 +.fi + +.eh + +.TP +.I "XtNouterOffset" +Normally, the border is draw along the outer edge of the widget, but +it can be moved inward. \fIXtNouterOffset\fP is the number of pixels +between the edge and the frame. + + + +.hi + +.nf +Dimension outerOffset = 0 +.fi + +.eh + +.TP +.I "XtNinnerOffset" +Between the frame and whatever is inside the widget, there is also +margin. By default, however, it is 0. + + + +.hi + +.nf +Dimension innerOffset = 0 +.fi + +.eh + +.TP +.I "XtNshadowScheme" +The colors of the top and bottom shadows can be set with the +resources \fItopShadowColor\fP and \fIbottomShadowColor\fP, but it is also +possible to use a stiple of foreground and background colors. This may +be preferable on workstations with limited or no color capabilities. +However, the easiest way (which is also the default) is to let the +widget determine its own shadow colors or stipples, based on the +widget's background color and the color capabilities of the screen. + +The resource \fIshadowScheme\fP can be set to \fIXfwfColor\fP, \fIXfwfStipple\fP +or \fIXfwfAuto\fP. The converter for the shadow pixmap accepts the strings +\fI"stipple0"\fP through \fI"stipple8"\fP, which create pixmaps of the current +background and foreground colors, with \fI"stipple0"\fP entirely +background and \fI"stipple8"\fP entirely foreground. Setting pixmaps or +colors is only useful when \fIshadowScheme\fP is set to \fIXfwfStipple\fP or +\fIXfwfColor\fP respectively. + +The values of \fItopShadowColor\fP and \fIbottomShadowColor\fP are ignored by +the Frame widget as long as \fIshadowScheme\fP is not \fIXfwfColor\fP, but the +default values are computed nevertheless, since they are useful, e.g., +when an icon uses `topShadowColor' and `bottomShadowColor' as dynamic +colors. + + + +.hi + +.nf +ShadowScheme shadowScheme = XfwfAuto +.fi + +.eh + +.TP +.I "XtNtopShadowColor" + +.hi + +.nf +Pixel topShadowColor = <CallProc>compute_topcolor +.fi + +.eh + +.TP +.I "XtNbottomShadowColor" + +.hi + +.nf +Pixel bottomShadowColor = <CallProc>compute_bottomcolor +.fi + +.eh + +.TP +.I "XtNtopShadowStipple" + +.hi + +.nf +Bitmap topShadowStipple = NULL +.fi + +.eh + +.TP +.I "XtNbottomShadowStipple" + +.hi + +.nf +Bitmap bottomShadowStipple = NULL +.fi + +.eh + +.TP +.I "XtNborder_width" +The inherited resource \fIborderWidth\fP is given a default value of 0, +instead of 1. + + + +.hi + +.nf + border_width = 0 +.fi + +.eh + +.ps-2 +.TS +center box; +cBsss +lB|lB|lB|lB +l|l|l|l. +XfwfCommon +Name Class Type Default +XtNtraversalOn XtCTraversalOn Boolean True +XtNhighlightThickness XtCHighlightThickness Dimension 2 +XtNhighlightColor XtCHighlightColor Pixel XtDefaultForeground +XtNhighlightPixmap XtCHighlightPixmap Pixmap None +XtNnextTop XtCNextTop Callback NULL +XtNuserData XtCUserData Pointer NULL + +.TE +.ps + +.ps-2 +.TS +center box; +cBsss +lB|lB|lB|lB +l|l|l|l. +Composite +Name Class Type Default +XtNchildren XtCChildren WidgetList NULL +insertPosition XtCInsertPosition XTOrderProc NULL +numChildren XtCNumChildren Cardinal 0 + +.TE +.ps + +.ps-2 +.TS +center box; +cBsss +lB|lB|lB|lB +l|l|l|l. +Core +Name Class Type Default +XtNx XtCX Position 0 +XtNy XtCY Position 0 +XtNwidth XtCWidth Dimension 0 +XtNheight XtCHeight Dimension 0 +borderWidth XtCBorderWidth Dimension 0 +XtNcolormap XtCColormap Colormap NULL +XtNdepth XtCDepth Int 0 +destroyCallback XtCDestroyCallback XTCallbackList NULL +XtNsensitive XtCSensitive Boolean True +XtNtm XtCTm XTTMRec NULL +ancestorSensitive XtCAncestorSensitive Boolean False +accelerators XtCAccelerators XTTranslations NULL +borderColor XtCBorderColor Pixel 0 +borderPixmap XtCBorderPixmap Pixmap NULL +background XtCBackground Pixel 0 +backgroundPixmap XtCBackgroundPixmap Pixmap NULL +mappedWhenManaged XtCMappedWhenManaged Boolean True +XtNscreen XtCScreen Screen * NULL + +.TE +.ps + +.SS "Exports" + +A number of new types is introduced by the Common class. The +possible types of borders are enumerated in \fIFrame3dType\fP (see the +introduction). + + + +.nf + +.B type + FrameType = enum { + XfwfRaised, XfwfSunken, XfwfChiseled, XfwfLedged } +.fi + +The shadow scheme can be used to choose colors, pixmaps or automatic +shadows. + + + +.nf + +.B type + ShadowScheme = enum {XfwfAuto, XfwfColor, XfwfStipple} +.fi + +The type \fIBitmap\fP is an alias for \fIPixmap\fP, but it is meant to +contain only bitmaps, i.e., pixmaps of depth one. + + + +.nf + +.B type + Bitmap = Pixmap +.fi + +The routine that draws the border is generally useful, so it is +exported. \fIt\fP is the thickness of the frame. The frame is drawn inside +the rectangle \fI(x, y, x+w-1, y+h-1)\fP. + +.nf +XfwfDrawFrame( $, int x, int y, int w, int h, FrameType tp, int t, GC lightgc, GC darkgc) +.fi + +.hi +{ + XPoint tlPoints[7], brPoints[7]; + + if (t == 0) return; + switch (tp) { + case XfwfRaised: + case XfwfSunken: + tlPoints[0].x = x; tlPoints[0].y = y; + tlPoints[1].x = x + w; tlPoints[1].y = y; + tlPoints[2].x = x + w - t; tlPoints[2].y = y + t; + tlPoints[3].x = x + t; tlPoints[3].y = y + t; + tlPoints[4].x = x + t; tlPoints[4].y = y + h - t; + tlPoints[5].x = x; tlPoints[5].y = y + h; + tlPoints[6].x = x; tlPoints[6].y = y; + brPoints[0].x = x + w; brPoints[0].y = y + h; + brPoints[1].x = x; brPoints[1].y = y + h; + brPoints[2].x = x + t; brPoints[2].y = y + h - t; + brPoints[3].x = x + w - t; brPoints[3].y = y + h - t; + brPoints[4].x = x + w - t; brPoints[4].y = y + t; + brPoints[5].x = x + w; brPoints[5].y = y; + brPoints[6].x = x + w; brPoints[6].y = y + h; + if (tp == XfwfSunken) { + XFillPolygon(XtDisplay($), XtWindow($), + darkgc, tlPoints, 7, Nonconvex, CoordModeOrigin); + XFillPolygon(XtDisplay($), XtWindow($), + lightgc, brPoints, 7, Nonconvex, CoordModeOrigin); + } else { + XFillPolygon(XtDisplay($), XtWindow($), + lightgc, tlPoints, 7, Nonconvex, CoordModeOrigin); + XFillPolygon(XtDisplay($), XtWindow($), + darkgc, brPoints, 7, Nonconvex, CoordModeOrigin); + } + break; + case XfwfLedged: + XfwfDrawFrame($, x, y, w, h, XfwfRaised, t/2, lightgc, darkgc); + XfwfDrawFrame($, x+t/2, y+t/2, w-2*(int)(t/2), h-2*(int)(t/2), + XfwfSunken, t/2, lightgc, darkgc); + break; + case XfwfChiseled: + XfwfDrawFrame($, x, y, w, h, XfwfSunken, t/2, lightgc, darkgc); + XfwfDrawFrame($, x+t/2, y+t/2, w-2*(int)(t/2), h-2*(int)(t/2), + XfwfRaised, t/2, lightgc, darkgc); + break; + } + +} +.eh + +\fIcvtStringToFrameType\fP converts the strings `raised', `sunken', +`chiseled' and `ledged'. Case doesn't matter. + +.nf +Boolean cvtStringToFrameType(Display * display, XrmValuePtr args, Cardinal * num_args, XrmValuePtr from, XrmValuePtr to, XtPointer * converter_data) +.fi + +.hi +{ + String s = (String) from->addr; + + if (*num_args != 0) + XtAppErrorMsg(XtDisplayToApplicationContext(display), + "cvtStringToFrameType", "wrongParameters", + "XtToolkitError", + "String to frame type conversion needs no arguments", + (String*) NULL, (Cardinal*) NULL); + + if (XmuCompareISOLatin1(s, "raised") == 0) done(FrameType, XfwfRaised); + if (XmuCompareISOLatin1(s, "sunken") == 0) done(FrameType, XfwfSunken); + if (XmuCompareISOLatin1(s, "chiseled") == 0) done(FrameType, XfwfChiseled); + if (XmuCompareISOLatin1(s, "ledged") == 0) done(FrameType, XfwfLedged); + XtDisplayStringConversionWarning(display, s, XtRFrameType); + done(FrameType, XfwfRaised); +} +.eh + +.nf +Boolean cvtFrameTypeToString(Display * display, XrmValuePtr args, Cardinal * num_args, XrmValuePtr from, XrmValuePtr to, XtPointer * converter_data) +.fi + +.hi +{ + if (*num_args != 0) + XtAppErrorMsg(XtDisplayToApplicationContext(display), + "cvtFrameTypeToString", "wrongParameters", + "XtToolkitError", + "Fframe type to String conversion needs no arguments", + (String*) NULL, (Cardinal*) NULL); + switch (*(FrameType*)from->addr) { + case XfwfRaised: done(String, "raised"); + case XfwfSunken: done(String, "sunken"); + case XfwfChiseled: done(String, "chiseled"); + case XfwfLedged: done(String, "ledged"); + default: XtError("Illegal FrameType"); + } +} +.eh + +The converter \fIcvtStringToShadowScheme\fP converts strings `color', +`auto' and `stipple' to \fIXfwfColor\fP, \fIXfwfAuto\fP and \fIXfwfStipple\fP. + +.nf +Boolean cvtStringToShadowScheme(Display * display, XrmValuePtr args, Cardinal * num_args, XrmValuePtr from, XrmValuePtr to, XtPointer * converter_data) +.fi + +.hi +{ + String s = (String) from->addr; + + if (*num_args != 0) + XtAppErrorMsg(XtDisplayToApplicationContext(display), + "cvtStringToShadowScheme", "wrongParameters", + "XtToolkitError", + "String to shadow scheme conversion needs no arguments", + (String*) NULL, (Cardinal*) NULL); + + if (XmuCompareISOLatin1(s, "auto")==0) done(ShadowScheme, XfwfAuto); + if (XmuCompareISOLatin1(s, "color")==0) done(ShadowScheme, XfwfColor); + if (XmuCompareISOLatin1(s, "stipple")==0) done(ShadowScheme, XfwfStipple); + XtDisplayStringConversionWarning(display, s, XtRShadowScheme); + done(ShadowScheme, XfwfAuto); +} +.eh + +.nf +Boolean cvtShadowSchemeToString(Display * display, XrmValuePtr args, Cardinal * num_args, XrmValuePtr from, XrmValuePtr to, XtPointer * converter_data) +.fi + +.hi +{ + if (*num_args != 0) + XtAppErrorMsg(XtDisplayToApplicationContext(display), + "cvtShadowSchemeToString", "wrongParameters", + "XtToolkitError", + "Shadow scheme to String conversion needs no arguments", + (String*) NULL, (Cardinal*) NULL); + + switch (*(ShadowScheme*)from->addr) { + case XfwfAuto: done(String, "auto"); + case XfwfColor: done(String, "color"); + case XfwfStipple: done(String, "stipple"); + default: XtError("Illegal ShadowScheme"); + } +} +.eh + +.hi +.SS "Actions" + +.TP +.I "set_shadow + +Although the Frame widget has no translations, one action is +defined, that may be of use to subclasses. The action function +\fIset_shadow\fP can be used to change the shadow frame. It has zero or +one argument. Without an argument, it resets the shadow to its +original type; with an argument, it sets the shadow to the type given +in the argument. + +Warning: the function uses the \fIXfwfDrawFrame\fP routine to draw the +frames directly, instead of calling the \fIexpose\fP or even \fIset_values\fP +methods. Any subclass that defines behaviour that depends on knowing +the frame type, will have to redefine the \fIset_shadow\fP action. + +.hi + +.nf +void set_shadow($, XEvent* event, String* params, Cardinal* num_params) +{ + Position x, y; + Dimension w, h; + FrameType f = XfwfSunken; + + if (*num_params == 0) f = $old_frame_type; /* Reset to old style */ + else if (strcmp("raised", params[0]) == 0) f = XfwfRaised; + else if (strcmp("sunken", params[0]) == 0) f = XfwfSunken; + else if (strcmp("chiseled", params[0]) == 0) f = XfwfChiseled; + else if (strcmp("ledged", params[0]) == 0) f = XfwfLedged; + else XtWarning("Unknown frame type in set_shadow action"); + + if ($frameType != f) { + $frameType = f; + #compute_inside($, x, y, w, h); + XfwfDrawFrame($, x + $outerOffset, y + $outerOffset, + w - 2*$outerOffset, h - 2*$outerOffset, + $frameType, $frameWidth, $lightgc, $darkgc); + } +} +.fi + +.eh + +.hi + +.hi +.SH "Importss" + +.nf + +.B incl + <string.h> +.fi + +.nf + +.B incl + <stdio.h> +.fi + +.nf + +.B incl + <X11/Xmu/Converters.h> +.fi + +.nf + +.B incl + <X11/Xmu/CharSet.h> +.fi + +The stipple for the shadows is loaded from a bitmap file. + +.nf + +.B incl + "stip4.bm" +.fi + +.hi + +.hi +.SS "Private variables" + +The GC for drawing the light parts of the frame: + + + +.nf +GC lightgc +.fi + +The GC for drawing the dark parts of the frame: + + + +.nf +GC darkgc +.fi + +The \fIstip4\fP bitmap is used on screens with insufficient colors to +simulate light and dark shadows. It will be created by the +\fIinitialize\fP method, whether or not it is needed. Since it is but a +small bitmap, this can't hurt much. + + + +.nf +Pixmap stip4 +.fi + +The \fIold_frame_type\fP variable is used by the \fIset_shadow\fP action +function to store the original frame type, when it is temporarily +changed. + + + +.nf +FrameType old_frame_type +.fi + +.hi + +.hi +.SS "Methods" + +\fIclass_initialize\fP installs the type converters. The type converters +back to String are installed as a convenience, so resources can be +retrieved in readable form with \fIXtVaGetValues\fP. + +.nf +class_initialize() +{ + static XtConvertArgRec screenArg[] = { + {XtBaseOffset, (XtPointer)XtOffset(Widget, core.screen), sizeof(Screen*)}}; + + XtSetTypeConverter(XtRString, XtRFrameType, cvtStringToFrameType, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRFrameType, XtRString, cvtFrameTypeToString, + NULL, 0, XtCacheNone, NULL); + + XtAddConverter(XtRString, XtRBitmap, XmuCvtStringToBitmap, + screenArg, XtNumber(screenArg)); + + XtSetTypeConverter(XtRString, XtRShadowScheme, cvtStringToShadowScheme, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRShadowScheme, XtRString, cvtShadowSchemeToString, + NULL, 0, XtCacheNone, NULL); +} +.fi + +Much of the initialization that one would expect in the \fIinitialize\fP +method is actually delegated to the \fIrealize\fP method, since a window +ID is needed for most of the initializations. + +.nf +initialize(Widget request, $, ArgList args, Cardinal * num_args) +{ + $lightgc = NULL; + $darkgc = NULL; + $old_frame_type = $frameType; +} +.fi + +The \fIrealize\fP method uses the inherited method, but adds the cursor +attribute. + +This is also the place to create the \fIstip4\fP bitmap, that is used for +stippled shadows. It could not be created in \fIinitialize\fP, since +creating a bitmap requires a window ID. + +The GC's must be created after the \fIstip4\fP bitmaps, since they might +have to use it as a stipple. + +.nf +realize($, XtValueMask * mask, XSetWindowAttributes * attributes) +{ + *mask |= CWCursor; + attributes->cursor = $cursor; + #realize($, mask, attributes); + + $stip4 = XCreateBitmapFromData(XtDisplay($), XtWindow($), + stip4_bits, stip4_width, stip4_height); + + if (! $topShadowStipple) $topShadowStipple = $stip4; + if (! $bottomShadowStipple) $bottomShadowStipple = $stip4; + + create_lightgc($); + create_darkgc($); +} +.fi + +The \fIset_values\fP method has to create new GC's if the resources +change. It also makes sure that \fIframeWidth\fP is even if the frame type +is chiseled or ledged. + +If the frame width was and is zero, nothing needs to be drawn, +regardless of the changes in other resources. Therefore, at the end +\fIneed_redisplay\fP is set to False. + +When the cursor changes, the \fIset_values\fP method uses the +\fIXDefineCursor\fP routine to set the attribute on the widget's window, +provided the widget is realized. + +.nf +Boolean set_values(Widget old, Widget request, $, ArgList args, Cardinal * num_args) +{ + Boolean need_redisplay = False; + + if ($cursor != $old$cursor XtIsRealized($)) + XDefineCursor(XtDisplay($), XtWindow($), $cursor); + + if ($frameType == XfwfChiseled || $frameType == XfwfLedged) + $frameWidth = 2 * ((int) ($frameWidth / 2)); + + if ($shadowScheme != $old$shadowScheme) { + create_darkgc($); + create_lightgc($); + need_redisplay = True; + } else if ($shadowScheme == XfwfColor) { + if ($topShadowColor != $old$topShadowColor) { + create_lightgc($); + need_redisplay = True; + } + if ($bottomShadowColor != $old$bottomShadowColor) { + create_darkgc($); + need_redisplay = True; + } + } else if ($shadowScheme == XfwfStipple) { + if ($topShadowStipple != $old$topShadowStipple) { + create_lightgc($); + need_redisplay = True; + } + if ($bottomShadowStipple != $old$bottomShadowStipple) { + create_darkgc($); + need_redisplay = True; + } + } + + if ($outerOffset != $old$outerOffset) + need_redisplay = True; + + if ($innerOffset != $old$innerOffset) + need_redisplay = True; + + if ($frameType != $old$frameType) { + $old_frame_type = $frameType; + need_redisplay = True; + } + + if ($frameWidth != $old$frameWidth) + need_redisplay = True; + else if ($frameWidth == 0) + need_redisplay = False; + + return need_redisplay; +} +.fi + +The \fIexpose\fP method draws the frame, for which it uses the +\fIXfwfDrawFrame\fP routine. Before it calls the routine, it sets the clip +region. Afterwards, the clip region is reset, because we don't know +which other widgets share the same GC's. As explained in {\em X +Toolkit Intrinsics Programming Manual} (Nye \& O'Reilly, Motif +Edition, 1990, p~223), the test for \fIXtIsRealized\fP is there for the +unlikely case when an expose event arrives after the widget has been +destroyed or unrealized. + +.nf +expose($, XEvent * event, Region region) +{ + Position x, y; + Dimension w, h; + + if (! XtIsRealized($)) return; + if (region != NULL) { + XSetRegion(XtDisplay($), $lightgc, region); + XSetRegion(XtDisplay($), $darkgc, region); + } + #compute_inside($, x, y, w, h); + XfwfDrawFrame($, x + $outerOffset, y + $outerOffset, w - 2*$outerOffset, + h - 2*$outerOffset, $frameType, $frameWidth, $lightgc, $darkgc); + if (region != NULL) { + XSetClipMask(XtDisplay($), $lightgc, None); + XSetClipMask(XtDisplay($), $darkgc, None); + } + #expose($, event, region); +} +.fi + +The method \fIcompute_inside\fP is re-defined. The method now returns +the area inside the frame. It calls the superclass's method and then +decreases the area by the width of the frame. + +.nf +compute_inside($, Position * x, Position * y, Dimension * w, Dimension * h) +{ + #compute_inside($, x, y, w, h); + *x += $outerOffset + $frameWidth + $innerOffset; + *y += $outerOffset + $frameWidth + $innerOffset; + *w -= 2 * ($outerOffset + $frameWidth + $innerOffset); + *h -= 2 * ($outerOffset + $frameWidth + $innerOffset); +} +.fi + +A Frame widget passes its parent's inquiry on to its (presumably) +single child. If there is no child, the proposal is accepted. +The border and position proposals are always accepted, the stacking +order and size are left to the child to decide. + +.nf +XtGeometryResult query_geometry($, XtWidgetGeometry * request, XtWidgetGeometry * reply) +{ + XtWidgetGeometry request2, reply2; + XtGeometryResult result; + Dimension h; + + if ($num_children == 0) return XtGeometryYes; + + /* We're only interested in size and stacking order */ + reply->request_mode = + (CWWidth | CWHeight | CWStackMode) request->request_mode; + + /* If nothing of interest is left, we can return immediately */ + if (reply->request_mode == 0) + return XtGeometryYes; + + /* Prepare a request to the child */ + h = 2 * ($outerOffset + $frameWidth + $innerOffset); + request2.request_mode = reply->request_mode; + request2.width = request->width - h; + request2.height = request->height - h; + request2.sibling = request->sibling; + request2.stack_mode = request->stack_mode; + + result = XtQueryGeometry($children[0], request2, reply2); + + /* If the child accepted its proposal, we accept ours */ + if (result == XtGeometryYes) return XtGeometryYes; + + /* If the child doesn't want any change, we don't want any, either */ + if (result == XtGeometryNo) return XtGeometryNo; + + /* Otherwise, ignore everything but size and stacking order */ + reply->request_mode = reply2.request_mode; + if (reply->request_mode == 0) return XtGeometryYes; + + reply->width = reply2.width + h; + reply->height = reply2.height + h; + reply->sibling = reply2.sibling; + reply->stack_mode = reply2.stack_mode; + return XtGeometryAlmost; +} +.fi + +Requests by the child to be resized are passed on to the parent. If +the parent replies with \fIXtGeometryYes\fP, the change is accepted and +(if not \fIXtCWQueryOnly\fP) already done. In that case the Frame widget +accepts its child's request. If the parent replies with +\fIXtGeometryNo\fP, the change is denied and the denial is passed on. If +the parent replies with a different geometry, the geometry is passed +on, after compensating for the frame width. + +Requests for anything other than width or height are always granted. + +.nf +XtGeometryResult geometry_manager(Widget child, XtWidgetGeometry * request, XtWidgetGeometry * reply) +{ + XtWidgetGeometry request2, reply2; + XtGeometryResult result; + Position x, y; + Dimension w, h, extraw, extrah; + + $compute_inside($, x, y, w, h); + if (! (request->request_mode (CWWidth|CWHeight))) return XtGeometryYes; + extraw = $width - w; + extrah = $height - h; + request2.request_mode = request->request_mode (CWWidth|CWHeight); + request2.width = request->width + extraw; + request2.height = request->height + extrah; + result = XtMakeGeometryRequest($, request2, reply2); + if (result == XtGeometryNo) return XtGeometryNo; + if (result == XtGeometryYes) return XtGeometryYes; + reply->request_mode = reply2.request_mode (CWWidth|CWHeight); + reply->width = reply2.width - extraw; + reply->height = reply2.height - extrah; + return XtGeometryAlmost; +} +.fi + +The \fIresize\fP method doesn't have to recompute any private variables, +but it passes on the resize message to its child, after decreasing the +area by the amount needed for the frame. + +.nf +resize($) +{ + Position x, y; + Dimension w, h; + Widget child; + + if ($num_children == 0) return; + $compute_inside($, x, y, w, h); + child = $children[0]; + w -= 2 * $child$border_width; + h -= 2 * $child$border_width; + XtConfigureWidget(child, x, y, w, h, $child$border_width); +} +.fi + +The \fIchange_managed\fP method is called when a child becomes managed +or unmanaged. The task of the routine is enforcing the layout policy, +which in this case consists of trying to take on the size of the child +or otherwise resize the child to fit inside the frame. +If the parent of the Frame widget doesn't allow the Frame widget to be +resized, the child of the Frame widget will be resized instead. + +.nf +change_managed($) +{ + XtWidgetGeometry request2, reply2; + XtGeometryResult result; + Widget child; + Position x, y; + Dimension w, h; + + if ($num_children == 0) return; + $compute_inside($, x, y, w, h); + child = $children[0]; + request2.request_mode = CWWidth | CWHeight; + request2.width = $child$width + $width - w; + request2.height = $child$height + $height - h; + result = XtMakeGeometryRequest($, request2, reply2); + $compute_inside($, x, y, w, h); + w -= 2 * $child$border_width; + h -= 2 * $child$border_width; + XtConfigureWidget(child, x, y, w, h, $child$border_width); +} +.fi + +.hi + +.hi +.SH "Utilities" + +The converters use the following macro. + +\fBdef\fP done(type, value) = +do { + if (to->addr != NULL) { + if (to->size < sizeof(type)) { + to->size = sizeof(type); + return False; + } + *(type*)(to->addr) = (value); + } else { + static type static_val; + static_val = (value); + to->addr = (XtPointer)static_val; + } + to->size = sizeof(type); + return True; + }while (0 ) + +The variable \fIrcsid\fP isn't used for anything, except tracking of +versions. The version number is that of the specification file (this +file) from which the widget's source is build. + +.nf +char rcsid[] = "$Header: Frame.w,v 1.5 92/11/02 14:07:52 bert Exp $" +.fi + +The \fIcreate_darkgc\fP function creates the GC for the dark parts of +the frame. The contents of the GC depend on the resources +\fIshadowScheme\fP and possibly \fIbackground_pixel\fP, \fIbottomShadowColor\fP, +\fItopShadowColor\fP, \fIbottomShadowStipple\fP and \fItopShadowStipple\fP. + +.nf +create_darkgc($) +{ + XtGCMask mask; + XGCValues values; + + if ($darkgc != NULL) XtReleaseGC($, $darkgc); + switch ($shadowScheme) { + case XfwfColor: + mask = GCForeground; + values.foreground = $bottomShadowColor; + break; + case XfwfStipple: + mask = GCFillStyle | GCStipple | GCForeground | GCBackground; + values.fill_style = FillOpaqueStippled; + values.stipple = $bottomShadowStipple; + values.foreground = BlackPixelOfScreen(XtScreen($)); + values.background = $background_pixel; + break; + case XfwfAuto: + if (DefaultDepthOfScreen(XtScreen($)) > 4 + $darker_color($, $background_pixel, values.foreground)) { + mask = GCForeground; + } else { + mask = GCFillStyle | GCBackground | GCForeground | GCStipple; + values.fill_style = FillOpaqueStippled; + values.background = $background_pixel; + values.foreground = WhitePixelOfScreen(XtScreen($)); + values.stipple = $stip4; + } + break; + } + $darkgc = XtGetGC($, mask, values); +} +.fi + +\fIcreate_lightgc\fP does the same for the light parts of the frame. +When the \fIshadowScheme\fP resource is \fIXfwfAuto\fP, the depth of the screen +and the availability of colors determines whether colors or stipples +will be used for the frame. + +.nf +create_lightgc($) +{ + XtGCMask mask; + XGCValues values; + + if ($lightgc != NULL) XtReleaseGC($, $lightgc); + switch ($shadowScheme) { + case XfwfColor: + mask = GCForeground; + values.foreground = $topShadowColor; + break; + case XfwfStipple: + mask = GCFillStyle | GCStipple | GCForeground | GCBackground; + values.fill_style = FillOpaqueStippled; + values.background = $background_pixel; + values.stipple = $topShadowStipple; + values.foreground = WhitePixelOfScreen(XtScreen($)); + break; + case XfwfAuto: + if (DefaultDepthOfScreen(XtScreen($)) > 4 + $lighter_color($, $background_pixel, values.foreground)) { + mask = GCForeground; + } else { + mask = GCFillStyle | GCBackground | GCForeground | GCStipple; + values.fill_style = FillOpaqueStippled; + values.background = $background_pixel; + values.foreground = WhitePixelOfScreen(XtScreen($)); + values.stipple = $stip4; + } + break; + } + $lightgc = XtGetGC($, mask, values); +} +.fi + +The function \fIcompute_topcolor\fP is a resource default proc. It is +used to compute the value of the \fItopShadowColor\fP relative to the +\fIbackground\fP color. + +.nf +compute_topcolor($, int offset, XrmValue * value) +{ + static Pixel color; + $lighter_color($, $background_pixel, color); + value->addr = (XtPointer) color; +} +.fi + +.nf +compute_bottomcolor($, int offset, XrmValue * value) +{ + static Pixel color; + $darker_color($, $background_pixel, color); + value->addr = (XtPointer) color; +} +.fi + +.hi |