aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/obm/ObmW/Frame.man
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/x11iraf/obm/ObmW/Frame.man')
-rw-r--r--vendor/x11iraf/obm/ObmW/Frame.man1062
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