749N/A#ifndef lint
749N/Astatic char Xrcsid[] = "$XConsortium: Viewport.c,v 1.48 89/12/15 11:37:22 kit Exp $";
749N/A#endif /* lint */
749N/A
749N/A
749N/A/***********************************************************
749N/ACopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
749N/Aand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
749N/A
749N/A All Rights Reserved
749N/A
749N/APermission to use, copy, modify, and distribute this software and its
749N/Adocumentation for any purpose and without fee is hereby granted,
749N/Aprovided that the above copyright notice appear in all copies and that
749N/Aboth that copyright notice and this permission notice appear in
749N/Asupporting documentation, and that the names of Digital or MIT not be
749N/Aused in advertising or publicity pertaining to distribution of the
749N/Asoftware without specific, written prior permission.
749N/A
749N/ADIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
749N/AALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
749N/ADIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
749N/AANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
749N/AWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
749N/AARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
749N/ASOFTWARE.
749N/A
749N/A******************************************************************/
749N/A
749N/A#include <X11/IntrinsicP.h>
749N/A#include <X11/StringDefs.h>
749N/A
749N/A#include <./Xaw3_1XawInit.h>
749N/A#include <X11/Xmu/Misc.h>
749N/A#include <./Xaw3_1Scrollbar.h>
749N/A#include <./Xaw3_1ViewportP.h>
749N/A
749N/Astatic void ScrollUpDownProc(), ThumbProc();
749N/Astatic Boolean GetGeometry();
749N/A
749N/A#define offset(field) XtOffset(ViewportWidget,viewport.field)
749N/Astatic XtResource resources[] = {
749N/A {XtNforceBars, XtCBoolean, XtRBoolean, sizeof(Boolean),
749N/A offset(forcebars), XtRImmediate, (caddr_t)False},
749N/A {XtNallowHoriz, XtCBoolean, XtRBoolean, sizeof(Boolean),
749N/A offset(allowhoriz), XtRImmediate, (caddr_t)False},
749N/A {XtNallowVert, XtCBoolean, XtRBoolean, sizeof(Boolean),
749N/A offset(allowvert), XtRImmediate, (caddr_t)False},
749N/A {XtNuseBottom, XtCBoolean, XtRBoolean, sizeof(Boolean),
749N/A offset(usebottom), XtRImmediate, (caddr_t)False},
749N/A {XtNuseRight, XtCBoolean, XtRBoolean, sizeof(Boolean),
749N/A offset(useright), XtRImmediate, (caddr_t)False},
749N/A};
749N/A#undef offset
749N/A
749N/Astatic void Initialize(), ConstraintInitialize(),
749N/A Realize(), Resize(), ChangeManaged();
749N/Astatic Boolean SetValues(), Layout();
749N/Astatic XtGeometryResult GeometryManager(), PreferredGeometry();
749N/A
749N/A#define superclass (&formClassRec)
749N/AViewportClassRec viewportClassRec = {
749N/A { /* core_class fields */
749N/A /* superclass */ (WidgetClass) superclass,
749N/A /* class_name */ "Viewport",
749N/A /* widget_size */ sizeof(ViewportRec),
749N/A /* class_initialize */ XawInitializeWidgetSet,
749N/A /* class_part_init */ NULL,
749N/A /* class_inited */ FALSE,
749N/A /* initialize */ Initialize,
749N/A /* initialize_hook */ NULL,
749N/A /* realize */ Realize,
749N/A /* actions */ NULL,
749N/A /* num_actions */ 0,
749N/A /* resources */ resources,
749N/A /* num_resources */ XtNumber(resources),
749N/A /* xrm_class */ NULLQUARK,
749N/A /* compress_motion */ TRUE,
749N/A /* compress_exposure */ TRUE,
749N/A /* compress_enterleave*/ TRUE,
749N/A /* visible_interest */ FALSE,
749N/A /* destroy */ NULL,
749N/A /* resize */ Resize,
749N/A /* expose */ XtInheritExpose,
749N/A /* set_values */ SetValues,
749N/A /* set_values_hook */ NULL,
749N/A /* set_values_almost */ XtInheritSetValuesAlmost,
749N/A /* get_values_hook */ NULL,
749N/A /* accept_focus */ NULL,
749N/A /* version */ XtVersion,
749N/A /* callback_private */ NULL,
749N/A /* tm_table */ NULL,
749N/A /* query_geometry */ PreferredGeometry,
749N/A /* display_accelerator*/ XtInheritDisplayAccelerator,
749N/A /* extension */ NULL
749N/A },
749N/A { /* composite_class fields */
749N/A /* geometry_manager */ GeometryManager,
749N/A /* change_managed */ ChangeManaged,
749N/A /* insert_child */ XtInheritInsertChild,
749N/A /* delete_child */ XtInheritDeleteChild,
749N/A /* extension */ NULL
749N/A },
749N/A { /* constraint_class fields */
749N/A /* subresourses */ NULL,
749N/A /* subresource_count */ 0,
749N/A /* constraint_size */ sizeof(ViewportConstraintsRec),
749N/A /* initialize */ ConstraintInitialize,
749N/A /* destroy */ NULL,
749N/A /* set_values */ NULL,
749N/A /* extension */ NULL
749N/A },
749N/A { /* form_class fields */
749N/A /* layout */ Layout
749N/A },
749N/A { /* viewport_class fields */
749N/A /* empty */ 0
749N/A }
749N/A};
749N/A
749N/A
749N/AWidgetClass viewportWidgetClass = (WidgetClass)&viewportClassRec;
749N/A
749N/Astatic Widget CreateScrollbar(w, horizontal)
749N/A ViewportWidget w;
749N/A Boolean horizontal;
749N/A{
749N/A Widget clip = w->viewport.clip;
749N/A ViewportConstraints constraints =
749N/A (ViewportConstraints)clip->core.constraints;
749N/A static Arg barArgs[] = {
749N/A {XtNorientation, NULL},
749N/A {XtNlength, NULL},
749N/A {XtNleft, NULL},
749N/A {XtNright, NULL},
749N/A {XtNtop, NULL},
749N/A {XtNbottom, NULL},
749N/A {XtNmappedWhenManaged, False},
749N/A };
749N/A Widget bar;
749N/A
749N/A XtSetArg(barArgs[0], XtNorientation,
749N/A horizontal ? XtorientHorizontal : XtorientVertical );
749N/A XtSetArg(barArgs[1], XtNlength,
749N/A horizontal ? clip->core.width : clip->core.height);
749N/A XtSetArg(barArgs[2], XtNleft,
749N/A (!horizontal && w->viewport.useright) ? XtChainRight : XtChainLeft);
749N/A XtSetArg(barArgs[3], XtNright,
749N/A (!horizontal && !w->viewport.useright) ? XtChainLeft : XtChainRight);
749N/A XtSetArg(barArgs[4], XtNtop,
749N/A (horizontal && w->viewport.usebottom) ? XtChainBottom: XtChainTop);
749N/A XtSetArg(barArgs[5], XtNbottom,
749N/A (horizontal && !w->viewport.usebottom) ? XtChainTop: XtChainBottom);
749N/A
749N/A bar = XtCreateWidget( (horizontal ? "horizontal" : "vertical"),
749N/A scrollbarWidgetClass, (Widget)w,
749N/A barArgs, XtNumber(barArgs) );
749N/A XtAddCallback( bar, XtNscrollProc, ScrollUpDownProc, (caddr_t)w );
749N/A XtAddCallback( bar, XtNjumpProc, ThumbProc, (caddr_t)w );
749N/A
749N/A if (horizontal) {
749N/A w->viewport.horiz_bar = bar;
749N/A constraints->form.vert_base = bar;
749N/A }
749N/A else {
749N/A w->viewport.vert_bar = bar;
749N/A constraints->form.horiz_base = bar;
749N/A }
749N/A
749N/A XtManageChild( bar );
749N/A
749N/A return bar;
749N/A}
749N/A
749N/A/* ARGSUSED */
749N/Astatic void Initialize(request, new)
749N/A Widget request, new;
749N/A{
749N/A ViewportWidget w = (ViewportWidget)new;
749N/A static Arg clip_args[5];
749N/A Cardinal num_args;
749N/A Widget h_bar, v_bar;
749N/A Dimension clip_height, clip_width;
749N/A
749N/A w->form.default_spacing = 0; /* Reset the default spacing to 0 pixels. */
749N/A
749N/A
749N/A/*
749N/A * Initialize all widget pointers to NULL.
749N/A */
749N/A
749N/A w->viewport.child = (Widget) NULL;
749N/A w->viewport.horiz_bar = w->viewport.vert_bar = (Widget)NULL;
749N/A
749N/A/*
749N/A * Create Clip Widget.
749N/A */
749N/A
749N/A num_args = 0;
749N/A XtSetArg(clip_args[num_args], XtNborderWidth, 0); num_args++;
749N/A XtSetArg(clip_args[num_args], XtNleft, XtChainLeft); num_args++;
749N/A XtSetArg(clip_args[num_args], XtNright, XtChainRight); num_args++;
749N/A XtSetArg(clip_args[num_args], XtNtop, XtChainTop); num_args++;
749N/A XtSetArg(clip_args[num_args], XtNbottom, XtChainBottom); num_args++;
749N/A
749N/A w->viewport.clip = XtCreateManagedWidget("clip", widgetClass, new,
749N/A clip_args, num_args);
749N/A
749N/A
749N/A if (!w->viewport.forcebars)
749N/A return; /* If we are not forcing the bars then we are done. */
749N/A
749N/A if (w->viewport.allowhoriz)
749N/A (void) CreateScrollbar(w, True);
749N/A if (w->viewport.allowvert)
749N/A (void) CreateScrollbar(w, False);
749N/A
749N/A h_bar = w->viewport.horiz_bar;
749N/A v_bar = w->viewport.vert_bar;
749N/A
749N/A/*
749N/A * Set the clip widget to the correct height.
749N/A */
749N/A
749N/A clip_width = w->core.width;
749N/A clip_height = w->core.height;
749N/A
749N/A if ( (h_bar != NULL) &&
749N/A (w->core.width > h_bar->core.width + h_bar->core.border_width) )
749N/A clip_width -= h_bar->core.width + h_bar->core.border_width;
749N/A
749N/A if ( (v_bar != NULL) &&
749N/A (w->core.height > v_bar->core.height + v_bar->core.border_width) )
749N/A clip_height -= v_bar->core.height + v_bar->core.border_width;
749N/A
749N/A num_args = 0;
749N/A XtSetArg(clip_args[num_args], XtNwidth, clip_width); num_args++;
749N/A XtSetArg(clip_args[num_args], XtNheight, clip_height); num_args++;
749N/A XtSetValues(w->viewport.clip, clip_args, num_args);
749N/A}
749N/A
749N/A/* ARGSUSED */
749N/Astatic void ConstraintInitialize(request, new)
749N/A Widget request, new;
749N/A{
749N/A ((ViewportConstraints)new->core.constraints)->viewport.reparented = False;
749N/A}
749N/A
749N/Astatic void Realize(widget, value_mask, attributes)
749N/A Widget widget;
749N/A XtValueMask *value_mask;
749N/A XSetWindowAttributes *attributes;
749N/A{
749N/A ViewportWidget w = (ViewportWidget)widget;
749N/A register Widget child = w->viewport.child;
749N/A register Widget clip = w->viewport.clip;
749N/A
749N/A *value_mask |= CWBitGravity;
749N/A attributes->bit_gravity = NorthWestGravity;
749N/A (*superclass->core_class.realize)(widget, value_mask, attributes);
749N/A
749N/A (*w->core.widget_class->core_class.resize)(widget); /* turn on bars */
749N/A
749N/A if (child != (Widget)NULL) {
749N/A XtMoveWidget( child, (Position)0, (Position)0 );
749N/A XtRealizeWidget( clip );
749N/A XtRealizeWidget( child );
749N/A XReparentWindow( XtDisplay(w), XtWindow(child), XtWindow(clip),
749N/A (Position)0, (Position)0 );
749N/A XtMapWidget( child );
749N/A }
749N/A}
749N/A
749N/A/* ARGSUSED */
749N/Astatic Boolean SetValues(current, request, new)
749N/A Widget current, request, new;
749N/A{
749N/A ViewportWidget w = (ViewportWidget)new;
749N/A ViewportWidget cw = (ViewportWidget)current;
749N/A
749N/A if (w->viewport.forcebars != cw->viewport.forcebars) {
749N/A if (w->viewport.forcebars) {
749N/A if (w->viewport.allowhoriz && w->viewport.horiz_bar == (Widget)NULL)
749N/A (void) CreateScrollbar( w, True );
749N/A if (w->viewport.allowvert && w->viewport.vert_bar == (Widget)NULL)
749N/A (void) CreateScrollbar( w, False );
749N/A }
749N/A }
749N/A
749N/A /* take care of bars, &tc. */
749N/A (*w->core.widget_class->core_class.resize)( new );
749N/A return False;
749N/A}
749N/A
749N/A
749N/Astatic void ChangeManaged(widget)
749N/A Widget widget;
749N/A{
749N/A ViewportWidget w = (ViewportWidget)widget;
749N/A register int num_children = w->composite.num_children;
749N/A register Widget child, *childP;
749N/A register int i;
749N/A
749N/A child = (Widget)NULL;
749N/A for (childP=w->composite.children, i=0; i < num_children; childP++, i++) {
749N/A if (XtIsManaged(*childP)
749N/A && *childP != w->viewport.clip
749N/A && *childP != w->viewport.horiz_bar
749N/A && *childP != w->viewport.vert_bar)
749N/A {
749N/A child = *childP;
749N/A break;
749N/A }
749N/A }
749N/A
749N/A if (child != w->viewport.child) {
749N/A w->viewport.child = child;
749N/A if (child != (Widget)NULL) {
749N/A XtResizeWidget( child, child->core.width,
749N/A child->core.height, (Dimension)0 );
749N/A if (XtIsRealized(widget)) {
749N/A ViewportConstraints constraints =
749N/A (ViewportConstraints)child->core.constraints;
749N/A if (!XtIsRealized(child)) {
749N/A Window window = XtWindow(w);
749N/A XtMoveWidget( child, (Position)0, (Position)0 );
749N/A#ifdef notdef
749N/A /* this is dirty, but it saves the following code: */
749N/A XtRealizeWidget( child );
749N/A XReparentWindow( XtDisplay(w), XtWindow(child),
749N/A XtWindow(w->viewport.clip),
749N/A (Position)0, (Position)0 );
749N/A if (child->core.mapped_when_managed)
749N/A XtMapWidget( child );
749N/A#else
749N/A w->core.window = XtWindow(w->viewport.clip);
749N/A XtRealizeWidget( child );
749N/A w->core.window = window;
749N/A#endif /* notdef */
749N/A constraints->viewport.reparented = True;
749N/A }
749N/A else if (!constraints->viewport.reparented) {
749N/A XReparentWindow( XtDisplay(w), XtWindow(child),
749N/A XtWindow(w->viewport.clip),
749N/A (Position)0, (Position)0 );
749N/A constraints->viewport.reparented = True;
749N/A if (child->core.mapped_when_managed)
749N/A XtMapWidget( child );
749N/A }
749N/A }
749N/A GetGeometry( widget, child->core.width, child->core.height );
749N/A (*((ViewportWidgetClass)w->core.widget_class)->form_class.layout)
749N/A ( (FormWidget)w, w->core.width, w->core.height );
749N/A /* %%% do we need to hide this child from Form? */
749N/A }
749N/A }
749N/A
749N/A#ifdef notdef
749N/A (*superclass->composite_class.change_managed)( widget );
749N/A#endif
749N/A}
749N/A
749N/A
749N/Astatic void SetBar(w, top, length, total)
749N/A Widget w;
749N/A Position top;
749N/A Dimension length, total;
749N/A{
749N/A XawScrollbarSetThumb(w, (float) top / total, (float) length / total );
749N/A}
749N/A
749N/Astatic void RedrawThumbs(w)
749N/A ViewportWidget w;
749N/A{
749N/A register Widget child = w->viewport.child;
749N/A register Widget clip = w->viewport.clip;
749N/A
749N/A if (w->viewport.horiz_bar != (Widget)NULL)
749N/A SetBar( w->viewport.horiz_bar, -(child->core.x),
749N/A clip->core.width, child->core.width );
749N/A
749N/A if (w->viewport.vert_bar != (Widget)NULL)
749N/A SetBar( w->viewport.vert_bar, -(child->core.y),
749N/A clip->core.height, child->core.height );
749N/A}
749N/A
749N/A
749N/A
749N/Astatic void MoveChild(w, x, y)
749N/A ViewportWidget w;
749N/A Position x, y;
749N/A{
749N/A register Widget child = w->viewport.child;
749N/A register Widget clip = w->viewport.clip;
749N/A
749N/A /* make sure we never move past right/bottom borders */
749N/A if (-x + clip->core.width > child->core.width)
749N/A x = -(child->core.width - clip->core.width);
749N/A
749N/A if (-y + clip->core.height > child->core.height)
749N/A y = -(child->core.height - clip->core.height);
749N/A
749N/A /* make sure we never move past left/top borders */
749N/A if (x >= 0) x = 0;
749N/A if (y >= 0) y = 0;
749N/A
749N/A XtMoveWidget(child, x, y);
749N/A
749N/A RedrawThumbs(w);
749N/A}
749N/A
749N/A
749N/Astatic void ComputeLayout(widget, query, destroy_scrollbars)
749N/A Widget widget; /* Viewport */
749N/A Boolean query; /* query child's preferred geom? */
749N/A Boolean destroy_scrollbars; /* destroy un-needed scrollbars? */
749N/A{
749N/A ViewportWidget w = (ViewportWidget)widget;
749N/A register Widget child = w->viewport.child;
749N/A register Widget clip = w->viewport.clip;
749N/A ViewportConstraints constraints
749N/A = (ViewportConstraints)clip->core.constraints;
749N/A Boolean needshoriz, needsvert;
749N/A int clip_width, clip_height;
749N/A XtWidgetGeometry intended;
749N/A static void ComputeWithForceBars();
749N/A
749N/A if (child == (Widget) NULL) return;
749N/A
749N/A clip_width = w->core.width;
749N/A clip_height = w->core.height;
749N/A intended.request_mode = CWBorderWidth;
749N/A intended.border_width = 0;
749N/A
749N/A if (w->viewport.forcebars) {
749N/A needsvert = w->viewport.allowvert;
749N/A needshoriz = w->viewport.allowhoriz;
749N/A ComputeWithForceBars(widget, query, &intended,
749N/A &clip_width, &clip_height);
749N/A }
749N/A else {
749N/A Dimension prev_width, prev_height;
749N/A XtGeometryMask prev_mode;
749N/A XtWidgetGeometry preferred;
749N/A
749N/A needshoriz = needsvert = False;
749N/A
749N/A /*
749N/A * intended.{width,height} caches the eventual child dimensions,
749N/A * but we don't set the mode bits until after we decide that the
749N/A * child's preferences are not acceptable.
749N/A */
749N/A
749N/A if (!w->viewport.allowhoriz)
749N/A intended.request_mode |= CWWidth;
749N/A
749N/A if (child->core.width < clip_width)
749N/A intended.width = clip_width;
749N/A else
749N/A intended.width = child->core.width;
749N/A
749N/A if (child->core.height < clip_height)
749N/A intended.height = clip_height;
749N/A else
749N/A intended.height = child->core.height;
749N/A
749N/A if (!w->viewport.allowvert)
749N/A intended.request_mode |= CWHeight;
749N/A
749N/A if (!query) {
749N/A preferred.width = child->core.width;
749N/A preferred.height = child->core.height;
749N/A }
749N/A do { /* while intended != prev */
749N/A
749N/A if (query) {
749N/A (void) XtQueryGeometry( child, &intended, &preferred );
749N/A if ( !(preferred.request_mode & CWWidth) )
749N/A preferred.width = intended.width;
749N/A if ( !(preferred.request_mode & CWHeight) )
749N/A preferred.height = intended.height;
749N/A }
749N/A prev_width = intended.width;
749N/A prev_height = intended.height;
749N/A prev_mode = intended.request_mode;
749N/A /*
749N/A * note that having once decided to turn on either bar
749N/A * we'll not change our mind until we're next resized,
749N/A * thus avoiding potential oscillations.
749N/A */
749N/A#define CheckHoriz() \
749N/A if (w->viewport.allowhoriz && preferred.width > clip_width) { \
749N/A if (!needshoriz) { \
749N/A Widget bar; \
749N/A needshoriz = True; \
749N/A if ((bar = w->viewport.horiz_bar) == (Widget)NULL) \
749N/A bar = CreateScrollbar(w, True); \
749N/A clip_height -= bar->core.height + \
749N/A bar->core.border_width; \
749N/A if (clip_height < 1) clip_height = 1; \
749N/A } \
749N/A intended.width = preferred.width; \
749N/A }
749N/A/*enddef*/
749N/A CheckHoriz();
749N/A if (w->viewport.allowvert && preferred.height > clip_height) {
749N/A if (!needsvert) {
749N/A Widget bar;
749N/A needsvert = True;
749N/A if ((bar = w->viewport.vert_bar) == (Widget)NULL)
749N/A bar = CreateScrollbar(w, False);
749N/A clip_width -= bar->core.width + bar->core.border_width;
749N/A if (clip_width < 1) clip_width = 1;
749N/A CheckHoriz();
749N/A }
749N/A intended.height = preferred.height;
749N/A }
749N/A if (!w->viewport.allowhoriz || preferred.width < clip_width) {
749N/A intended.width = clip_width;
749N/A intended.request_mode |= CWWidth;
749N/A }
749N/A if (!w->viewport.allowvert || preferred.height < clip_height) {
749N/A intended.height = clip_height;
749N/A intended.request_mode |= CWHeight;
749N/A }
749N/A } while (intended.request_mode != prev_mode
749N/A || (intended.request_mode & CWWidth
749N/A && intended.width != prev_width)
749N/A || (intended.request_mode & CWHeight
749N/A && intended.height != prev_height));
749N/A }
749N/A
749N/A if (XtIsRealized(clip))
749N/A XRaiseWindow( XtDisplay(clip), XtWindow(clip) );
749N/A
749N/A XtMoveWidget( clip,
749N/A needsvert ? (w->viewport.useright ? 0 :
749N/A w->viewport.vert_bar->core.width +
749N/A w->viewport.vert_bar->core.border_width) : 0,
749N/A needshoriz ? (w->viewport.usebottom ? 0 :
749N/A w->viewport.horiz_bar->core.height +
749N/A w->viewport.horiz_bar->core.border_width) : 0);
749N/A XtResizeWidget( clip, (Dimension)clip_width,
749N/A (Dimension)clip_height, (Dimension)0 );
749N/A
749N/A if (w->viewport.horiz_bar != (Widget)NULL) {
749N/A register Widget bar = w->viewport.horiz_bar;
749N/A if (!needshoriz) {
749N/A constraints->form.vert_base = (Widget)NULL;
749N/A if (destroy_scrollbars) {
749N/A XtDestroyWidget( bar );
749N/A w->viewport.horiz_bar = (Widget)NULL;
749N/A }
749N/A }
749N/A else {
749N/A register int bw = bar->core.border_width;
749N/A XtResizeWidget( bar, clip_width, bar->core.height, bw );
749N/A XtMoveWidget( bar,
749N/A ((needsvert && !w->viewport.useright)
749N/A ? w->viewport.vert_bar->core.width
749N/A : -bw),
749N/A (w->viewport.usebottom
749N/A ? w->core.height - bar->core.height - bw
749N/A : -bw) );
749N/A XtSetMappedWhenManaged( bar, True );
749N/A }
749N/A }
749N/A
749N/A if (w->viewport.vert_bar != (Widget)NULL) {
749N/A register Widget bar = w->viewport.vert_bar;
749N/A if (!needsvert) {
749N/A constraints->form.horiz_base = (Widget)NULL;
749N/A if (destroy_scrollbars) {
749N/A XtDestroyWidget( bar );
749N/A w->viewport.vert_bar = (Widget)NULL;
749N/A }
749N/A }
749N/A else {
749N/A register int bw = bar->core.border_width;
749N/A XtResizeWidget( bar, bar->core.width, clip_height, bw );
749N/A XtMoveWidget( bar,
749N/A (w->viewport.useright
749N/A ? w->core.width - bar->core.width - bw
749N/A : -bw),
749N/A ((needshoriz && !w->viewport.usebottom)
749N/A ? w->viewport.horiz_bar->core.height
749N/A : -bw) );
749N/A XtSetMappedWhenManaged( bar, True );
749N/A }
749N/A }
749N/A
749N/A if (child != (Widget)NULL) {
749N/A XtResizeWidget( child, (Dimension)intended.width,
749N/A (Dimension)intended.height, (Dimension)0 );
749N/A MoveChild(w,
749N/A needshoriz ? child->core.x : 0,
749N/A needsvert ? child->core.y : 0);
749N/A }
749N/A}
749N/A
749N/A/* Function Name: ComputeWithForceBars
749N/A * Description: Computes the layout give forcebars is set.
749N/A * Arguments: widget - the viewport widget.
749N/A * query - whether or not to query the child.
749N/A * intended - the cache of the childs height is
749N/A * stored here ( USED AND RETURNED ).
749N/A * clip_width, clip_height - size of clip window.
749N/A * (USED AND RETURNED ).
749N/A * Returns: none.
749N/A */
749N/A
749N/Astatic void
749N/AComputeWithForceBars(widget, query, intended, clip_width, clip_height)
749N/AWidget widget;
749N/ABoolean query;
749N/AXtWidgetGeometry * intended;
749N/Aint *clip_width, *clip_height;
749N/A{
749N/A ViewportWidget w = (ViewportWidget)widget;
749N/A register Widget child = w->viewport.child;
749N/A XtWidgetGeometry preferred;
749N/A
749N/A/*
749N/A * If forcebars then needs = allows = has.
749N/A * Thus if needsvert is set it MUST have a scrollbar.
749N/A */
749N/A
749N/A if (w->viewport.allowvert)
749N/A *clip_width -= w->viewport.vert_bar->core.width +
749N/A w->viewport.vert_bar->core.border_width;
749N/A
749N/A if (w->viewport.allowhoriz)
749N/A *clip_height -= w->viewport.horiz_bar->core.height +
749N/A w->viewport.horiz_bar->core.border_width;
749N/A
749N/A AssignMax( *clip_width, 1 );
749N/A AssignMax( *clip_height, 1 );
749N/A
749N/A if (!w->viewport.allowvert) {
749N/A intended->height = *clip_height;
749N/A intended->request_mode = CWHeight;
749N/A }
749N/A if (!w->viewport.allowhoriz) {
749N/A intended->width = *clip_width;
749N/A intended->request_mode = CWWidth;
749N/A }
749N/A
749N/A if ( query ) {
749N/A if ( (w->viewport.allowvert || w->viewport.allowhoriz) ) {
749N/A XtQueryGeometry( child, intended, &preferred );
749N/A
749N/A if ( !(intended->request_mode & CWWidth) )
749N/A if ( preferred.request_mode & CWWidth )
749N/A intended->width = preferred.width;
749N/A else
749N/A intended->width = child->core.width;
749N/A
749N/A if ( !(intended->request_mode & CWHeight) )
749N/A if ( preferred.request_mode & CWHeight )
749N/A intended->height = preferred.height;
749N/A else
749N/A intended->height = child->core.height;
749N/A }
749N/A }
749N/A else {
749N/A if (w->viewport.allowvert)
749N/A intended->height = child->core.height;
749N/A if (w->viewport.allowhoriz)
749N/A intended->width = child->core.width;
749N/A }
749N/A
749N/A AssignMax(intended->width, *clip_width);
749N/A AssignMax(intended->height, *clip_height);
749N/A}
749N/A
749N/Astatic void Resize(widget)
749N/A Widget widget;
749N/A{
749N/A ComputeLayout( widget, /*query=*/True, /*destroy=*/True );
749N/A}
749N/A
749N/A
749N/A/* ARGSUSED */
749N/Astatic Boolean Layout(w, width, height)
749N/A FormWidget w;
749N/A Dimension width, height;
749N/A{
749N/A ComputeLayout( (Widget)w, /*query=*/True, /*destroy=*/True );
749N/A w->form.preferred_width = w->core.width;
749N/A w->form.preferred_height = w->core.height;
749N/A return False;
749N/A}
749N/A
749N/A
749N/Astatic void ScrollUpDownProc(widget, closure, call_data)
749N/A Widget widget;
749N/A caddr_t closure;
749N/A caddr_t call_data;
749N/A{
749N/A ViewportWidget w = (ViewportWidget)closure;
749N/A register Widget child = w->viewport.child;
749N/A int pix = (int)call_data;
749N/A Position x, y;
749N/A
749N/A if (child == NULL) return; /* no child to scroll. */
749N/A
749N/A x = child->core.x - ((widget == w->viewport.horiz_bar) ? pix : 0);
749N/A y = child->core.y - ((widget == w->viewport.vert_bar) ? pix : 0);
749N/A MoveChild(w, x, y);
749N/A}
749N/A
749N/A
749N/A/* ARGSUSED */
749N/Astatic void ThumbProc(widget, closure, percent)
749N/A Widget widget;
749N/A caddr_t closure;
749N/A float *percent;
749N/A{
749N/A ViewportWidget w = (ViewportWidget)closure;
749N/A register Widget child = w->viewport.child;
749N/A Position x, y;
749N/A
749N/A if (child == NULL) return; /* no child to scroll. */
749N/A
749N/A if (widget == w->viewport.horiz_bar)
749N/A#ifdef macII /* bug in the macII A/UX 1.0 cc */
749N/A x = (int)(-*percent * child->core.width);
749N/A#else /* else not macII */
749N/A x = -(int)(*percent * child->core.width);
749N/A#endif /* macII */
749N/A else
749N/A x = child->core.x;
749N/A
749N/A if (widget == w->viewport.vert_bar)
749N/A#ifdef macII /* bug in the macII A/UX 1.0 cc */
749N/A y = (int)(-*percent * child->core.height);
749N/A#else /* else not macII */
749N/A y = -(int)(*percent * child->core.height);
749N/A#endif /* macII */
749N/A else
749N/A y = child->core.y;
749N/A
749N/A MoveChild(w, x, y);
749N/A}
749N/A
749N/A
749N/Astatic XtGeometryResult GeometryManager(child, request, reply)
749N/A Widget child;
749N/A XtWidgetGeometry *request, *reply;
749N/A{
749N/A ViewportWidget w = (ViewportWidget)child->core.parent;
749N/A Boolean rWidth = (Boolean)(request->request_mode & CWWidth);
749N/A Boolean rHeight = (Boolean)(request->request_mode & CWHeight);
749N/A XtWidgetGeometry allowed;
749N/A XtGeometryResult result;
749N/A Boolean reconfigured;
749N/A Dimension height_remaining;
749N/A
749N/A if (child != w->viewport.child
749N/A || request->request_mode & ~(CWWidth | CWHeight | CWBorderWidth)
749N/A || ((request->request_mode & CWBorderWidth)
749N/A && request->border_width > 0))
749N/A return XtGeometryNo;
749N/A
749N/A allowed = *request;
749N/A
749N/A
749N/A reconfigured = GetGeometry( (Widget)w,
749N/A (rWidth ? request->width : w->core.width),
749N/A (rHeight ? request->height : w->core.height)
749N/A );
749N/A
749N/A height_remaining = w->core.height;
749N/A if (rWidth && w->core.width != request->width) {
749N/A if (w->viewport.allowhoriz && request->width > w->core.width) {
749N/A /* horizontal scrollbar will be needed so possibly reduce height */
749N/A Widget bar;
749N/A if ((bar = w->viewport.horiz_bar) == (Widget)NULL)
749N/A bar = CreateScrollbar( w, True );
749N/A height_remaining -= bar->core.height + bar->core.border_width;
749N/A reconfigured = True;
749N/A }
749N/A else {
749N/A allowed.width = w->core.width;
749N/A }
749N/A }
749N/A if (rHeight && height_remaining != request->height) {
749N/A if (w->viewport.allowvert && request->height > height_remaining) {
749N/A /* vertical scrollbar will be needed, so possibly reduce width */
749N/A if (!w->viewport.allowhoriz || request->width < w->core.width) {
749N/A Widget bar;
749N/A if ((bar = w->viewport.vert_bar) == (Widget)NULL)
749N/A bar = CreateScrollbar( w, False );
749N/A if (!rWidth) {
749N/A allowed.width = w->core.width;
749N/A allowed.request_mode |= CWWidth;
749N/A }
749N/A if (allowed.width > (bar->core.width + bar->core.border_width))
749N/A allowed.width -= bar->core.width + bar->core.border_width;
749N/A else
749N/A allowed.width = 1;
749N/A reconfigured = True;
749N/A }
749N/A }
749N/A else {
749N/A allowed.height = height_remaining;
749N/A }
749N/A }
749N/A
749N/A if (allowed.width != request->width || allowed.height != request->height) {
749N/A *reply = allowed;
749N/A result = XtGeometryAlmost;
749N/A }
749N/A else {
749N/A if (rWidth) child->core.width = request->width;
749N/A if (rHeight) child->core.height = request->height;
749N/A result = XtGeometryYes;
749N/A }
749N/A
749N/A if (reconfigured)
749N/A ComputeLayout( (Widget)w,
749N/A /*query=*/ False,
749N/A /*destroy=*/ (result == XtGeometryYes) ? True : False );
749N/A
749N/A return result;
749N/A }
749N/A
749N/A
749N/Astatic Boolean GetGeometry(w, width, height)
749N/A Widget w;
749N/A Dimension width, height;
749N/A{
749N/A XtWidgetGeometry geometry;
749N/A XtGeometryResult result;
749N/A
749N/A if (width == w->core.width && height == w->core.height)
749N/A return False;
749N/A
749N/A geometry.request_mode = CWWidth | CWHeight;
749N/A geometry.width = width;
749N/A geometry.height = height;
749N/A
749N/A if (XtIsRealized(w)) {
749N/A if (((ViewportWidget)w)->viewport.allowhoriz && width > w->core.width)
749N/A geometry.width = w->core.width;
749N/A if (((ViewportWidget)w)->viewport.allowvert && height > w->core.height)
749N/A geometry.height = w->core.height;
749N/A } else {
749N/A /* This is the Realize call; we'll inherit a w&h iff none currently */
749N/A if (w->core.width != 0) {
749N/A if (w->core.height != 0) return False;
749N/A geometry.width = w->core.width;
749N/A }
749N/A if (w->core.height != 0) geometry.height = w->core.height;
749N/A }
749N/A if ((result = XtMakeGeometryRequest(w, &geometry, &geometry))
749N/A == XtGeometryAlmost)
749N/A result = XtMakeGeometryRequest(w, &geometry, NULL);
749N/A
749N/A return (result == XtGeometryYes);
749N/A}
749N/A
749N/Astatic XtGeometryResult PreferredGeometry(w, constraints, reply)
749N/A Widget w;
749N/A XtWidgetGeometry *constraints, *reply;
749N/A{
749N/A if (((ViewportWidget)w)->viewport.child != NULL)
749N/A return XtQueryGeometry( ((ViewportWidget)w)->viewport.child,
749N/A constraints, reply );
749N/A else
749N/A return XtGeometryYes;
749N/A}