DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T V

⟦42ac4fb86⟧ TextFile

    Length: 21592 (0x5458)
    Types: TextFile
    Names: »VPane.c«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/others/max/VPane.c« 
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/others/max/VPane.c« 

TextFile

#ifndef lint
static char *sccsid = "@(#)VPane.c	1.36	6/1/87";
#endif lint
/*
 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 * 
 *                         All Rights Reserved
 * 
 * Permission to use, copy, modify, and distribute this software and its 
 * documentation for any purpose and without fee is hereby granted, 
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in 
 * supporting documentation, and that the name of Digital Equipment
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.  
 * 
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */
/* VPane.c */

#include <X/Xlib.h>
#include "Intrinsic.h"
#include "VPane.h"
#include "Atoms.h"

/* Private definitions. */


#define BORDERWIDTH		1 /* Size of borders between panes. */
#define DEFAULTKNOBWIDTH	9
#define DEFAULTKNOBHEIGHT	9
#define DEFAULTKNOBINDENT	16

typedef struct {
    Window w;			/* Subwindow */
    int y;			/* Location in master window */
    int dy;			/* Desired location. */
    int olddy;			/* The last value of dy.  */
    int min, max;		/* Minimum and maximum height. */
    short autochange;		/* Whether we're allowed to change this */
				/* subwindow's height without an */
				/* explicite command from user. */
    int height;			/* Current height. */
    int dheight;		/* Desired height. */
    Window knob;		/* The knob for this subwindow. */
    Boolean allowresize;	/* Whether we should honor geometry requests */
				/* from this window to change its height. */
} SubWindowInfo, *SubWindowPtr;

typedef struct {
    Window ourparent;		/* Parent of the paned window. */
    Window window;		/* Window containing everything. */
    int foregroundpixel;	/* Foreground pixel. */
    int backgroundpixel;	/* Background pixel. */
    int x, y;			/* Location of master window. */
    int width, height;		/* Dimension of master window. */
    int borderWidth;		/* Borderwidth of master window. */
    Pixmap borderpixmap;	/* Color of border of master window. */
    int knobwidth, knobheight;	/* Dimension of knobs. */
    int knobindent;		/* Location of knobs (offset from */
				/* right margin.) */
    int knobpixel;		/* Color of knobs. */
    int heightused;		/* Total height used by subwindows. */
    int numsubwindows;		/* How many windows within it. */
    SubWindowInfo *sub;		/* Array of info about the sub windows. */
    int whichtracking;		/* Which knob we are tracking, if any */
    int starty;			/* Starting y value. */
    int whichdirection;		/* Which direction to refigure things in. */
    SubWindowPtr whichadd;	/* Which subwindow to add changes to. */
    SubWindowPtr whichsub;	/* Which subwindow to sub changes from. */
    Boolean refiguremode;	/* Whether to refigure things right now. */
    int autoraise;		/* Whether we raise the window like xterm */
} PanedWindowInfo, *PanedWindowPtr;

static PanedWindowInfo glob, globinit;

static Resource resources[] = {
    {XtNwindow, XtCWindow, XtRWindow, sizeof(Window),
	 (caddr_t)&glob.window, NULL},
    {XtNforeground, XtCColor, XtRPixel, sizeof(int),
	 (caddr_t)&glob.foregroundpixel, (caddr_t)&XtDefaultFGPixel},
    {XtNbackground, XtCColor, XtRPixel, sizeof(int),
	 (caddr_t)&glob.backgroundpixel, (caddr_t)&XtDefaultBGPixel},
    {XtNx, XtCX, XtRInt, sizeof(int),
	 (caddr_t)&glob.x, NULL},
    {XtNy, XtCY, XtRInt, sizeof(int),
	 (caddr_t)&glob.y, NULL},
    {XtNwidth, XtCWidth, XtRInt, sizeof(int),
	 (caddr_t)&glob.width, NULL},
    {XtNheight, XtCHeight, XtRInt, sizeof(int),
	 (caddr_t)&glob.height, NULL},
    {XtNborderWidth, XtCBorderWidth, XtRInt, sizeof(int),
	 (caddr_t)&glob.borderWidth, NULL},
    {XtNborder, XtCColor, XtRPixmap, sizeof(Pixmap),
	 (caddr_t)&glob.borderpixmap, (caddr_t)&XtDefaultFGPixmap},
    {XtNknobWidth, XtCWidth, XtRInt, sizeof(int),
	 (caddr_t)&glob.knobwidth, NULL},
    {XtNknobHeight, XtCHeight, XtRInt, sizeof(int),
	 (caddr_t)&glob.knobheight, NULL},
    {XtNknobIndent, XtCKnobIndent, XtRInt, sizeof(int),
	 (caddr_t)&glob.knobindent, NULL},
    {XtNknobPixel, XtCKnobPixel, XtRPixel, sizeof(int),
	 (caddr_t)&glob.knobpixel, NULL},
    {XtNautoRaise, XtCAutoRaise, XtRBoolean, sizeof(int),
	 (caddr_t)&glob.autoraise, NULL},
};

static XtContext vPaneContext;
static char *CursorNums[3] ={
			    "sb_down_arrow",
			    "sb_v_double_arrow",
			    "sb_up_arrow"
			    };

static PanedWindowPtr PanedWindowPtrFromWindow(w)
  Window w;
{
    PanedWindowPtr ctx;
    if (XtFindContext(w, vPaneContext, (caddr_t *) &ctx)) return 0;
    return ctx;
}

static void TryResize(ctx, newwidth, newheight)
  PanedWindowPtr ctx;
  int newwidth, newheight;
{
    WindowBox requestBox, replyBox;
    XtGeometryReturnCode result;
    requestBox.x = 0;
    requestBox.y = 0;
    if (newwidth < 1) newwidth = 1;
    if (newheight < 1) newheight = 1;
    requestBox.width = newwidth;
    requestBox.height = newheight;
    result = XtMakeGeometryRequest(ctx->window, geometryRESIZE,
				   &requestBox, &replyBox);
    if (result == XtgeometryAlmost) {
	requestBox = replyBox;
	result = XtMakeGeometryRequest(ctx->window, geometryRESIZE,
				       &requestBox, &replyBox);
    }
    if (result == XtgeometryYes) {
	ctx->width = replyBox.width;
	ctx->height = replyBox.height;
    }
}


static RefigureLocations(ctx, position, dir)
  PanedWindowPtr ctx;
  int position;
  int dir;		/* -1 = up, 1 = down, 0 = this border only */
{
    SubWindowPtr sub, firstsub;
    int     i, old, y, cdir;
    if (ctx->numsubwindows == 0 || !ctx->refiguremode)
	return;
    do {
	ctx->heightused = 0;
	for (i = 0, sub = ctx->sub; i < ctx->numsubwindows; i++, sub++) {
	    if (sub->dheight < sub->min)
		sub->dheight = sub->min;
	    if (sub->dheight > sub->max)
		sub->dheight = sub->max;
	    ctx->heightused += sub->dheight;
	}
	ctx->heightused += BORDERWIDTH * (ctx->numsubwindows - 1);
	if (dir == 0 && ctx->heightused != ctx->height) {
	    for (i = 0, sub = ctx->sub; i < ctx->numsubwindows; i++, sub++)
		if (sub->dheight != sub->height)
		    sub->dheight += ctx->height - ctx->heightused;
	}
    } while (dir == 0 && ctx->heightused != ctx->height);

    firstsub = ctx->sub + position;
    sub = firstsub;
    cdir = dir;
    while (ctx->heightused != ctx->height) {
	if (sub->autochange || cdir != dir) {
	    old = sub->dheight;
	    sub->dheight = ctx->height - ctx->heightused + old;
	    if (sub->dheight < sub->min)
		sub->dheight = sub->min;
	    if (sub->dheight > sub->max)
		sub->dheight = sub->max;
	    ctx->heightused += (sub->dheight - old);
	}
	sub += cdir;
	while (sub < ctx->sub || sub - ctx->sub == ctx->numsubwindows) {
	    cdir = -cdir;
	    if (cdir == dir) goto doublebreak;
	    sub = firstsub + cdir;
	}
    }
doublebreak:
    y = -BORDERWIDTH;
    for (i = 0, sub = ctx->sub; i < ctx->numsubwindows; i++, sub++) {
	sub->dy = y;
	y += sub->dheight + BORDERWIDTH;
    }
}


static CommitNewLocations(ctx)
  PanedWindowPtr ctx;
{
    int i, kx, ky;
    SubWindowPtr sub;
    if (ctx->heightused != ctx->height)
	TryResize(ctx, ctx->width, ctx->height);
    for (i = 0, sub = ctx->sub; i < ctx->numsubwindows; i++, sub++) {
	if (sub->dy != sub->y || sub->dheight != sub->height) {
	    WindowBox box;
	    XConfigureWindow(sub->w,
			     box.x = -BORDERWIDTH,
			     box.y = sub->dy,
			     box.width = ctx->width,
			     box.height = sub->dheight);
	    sub->y = sub->dy;
	    sub->height = sub->dheight;
	}
    }
    kx = ctx->width - ctx->knobindent;
    for (i = 0, sub = ctx->sub; i < ctx->numsubwindows; i++, sub++) {
	ky = sub->y + sub->height - (ctx->knobheight / 2) + 1;
	if (i == ctx->numsubwindows - 1)
	    ky = -99;
	XMoveWindow(sub->knob, kx, ky);
    }
}


static RefigureLocationsAndCommit(ctx, position, dir)
  PanedWindowPtr ctx;
  int position, dir;
{
    RefigureLocations(ctx, position, dir);
    CommitNewLocations(ctx);
}


EraseInternalBorders(ctx)
  PanedWindowPtr ctx;
{
    int     i;
    
    for (i = 1; i < ctx->numsubwindows; i++)
	XLine(ctx->window, 0, ctx->sub[i].y, ctx->width, ctx->sub[i].y,
	      1, 1, ctx->backgroundpixel, GXcopy, AllPlanes);
}


DrawInternalBorders(ctx)
  PanedWindowPtr ctx;
{
    int     i;
    
    for (i = 1; i < ctx->numsubwindows; i++)
	XLine(ctx->window, 0, ctx->sub[i].y, ctx->width, ctx->sub[i].y,
	      1, 1, ctx->foregroundpixel, GXcopy, AllPlanes);
}


static DrawTrackLines(ctx)
  PanedWindowPtr ctx;
{
    int     i;
    SubWindowPtr sub;
    for (i = 1, sub = ctx->sub + 1; i < ctx->numsubwindows; i++, sub++) {
	if (sub->olddy != sub->dy) {
	    XLine(ctx->window, 0, sub->olddy, ctx->width, sub->olddy, 
                    1, 1, 1, GXinvert, 1);
	    XLine(ctx->window, 0, sub->dy, ctx->width, sub->dy,
                    1, 1, 1, GXinvert, 1);
	    sub->olddy = sub->dy;
	}
    }
}

static EraseTrackLines(ctx)
  PanedWindowPtr ctx;
{
    int     i;
    for (i = 1; i < ctx->numsubwindows; i++)
	XLine(ctx->window, 0, ctx->sub[i].olddy, ctx->width, ctx->sub[i].olddy,
                1, 1, 1, GXinvert, 1); 
}


/* Semi-public routines. */

static XtGeometryReturnCode PanedWindowGeometryRequest(
				      w, request, reqBox, replBox)
Window w;
int request;
WindowBox *reqBox, *replBox;
{
    PanedWindowPtr ctx;
    int i;
    SubWindowPtr sub;
    ctx = PanedWindowPtrFromWindow(w);
    if (!ctx) return XtgeometryNo;
    for (i=0 ; i<ctx->numsubwindows ; i++)
	if (ctx->sub[i].w == w) break;
    if (i >= ctx->numsubwindows) return XtgeometryNo;
    sub = ctx->sub + i;
    if (request == geometryRESIZE) {
	if (!sub->allowresize) return XtgeometryNo;
	if (ctx->width != reqBox->width) {
	    if (sub->height == reqBox->height)
		return XtgeometryNo;
	    *replBox = *reqBox;
	    replBox->width = ctx->width;
	    return XtgeometryAlmost;
	}
	if (sub->min == sub->height || sub->min > reqBox->height)
	    sub->min = reqBox->height;
	if (sub->max == sub->height || sub->max < reqBox->height)
	    sub->max = reqBox->height;
	sub->dheight = reqBox->height;
	RefigureLocationsAndCommit(ctx, i, 1);
	return XtgeometryYes;
    }
    if (request == geometryGETWINDOWBOX) {
	replBox->x = -BORDERWIDTH;
	replBox->y = sub->y;
	replBox->width = ctx->width;
	replBox->height = sub->height;
	replBox->borderWidth = BORDERWIDTH;
	return XtgeometryYes;
    }
    return XtgeometryNo;
}


static XtEventReturnCode HandleEvents(event)
  XExposeWindowEvent *event;
{
    PanedWindowPtr ctx;
    int i;

    ctx = PanedWindowPtrFromWindow(event->window);
    if (!ctx) return XteventNotHandled;
    switch (event->type) {
      case ResizeWindow:
	if (ctx->width != event->width || ctx->height != event->height) {
	    if (ctx->width != event->width) {
		for (i = 0; i < ctx->numsubwindows; i++) {
		    XChangeWindow(ctx->sub[i].w,
				  event->width, ctx->sub[i].height);
		}
	    }
	    ctx->width = event->width;
	    ctx->height = event->height;
	    RefigureLocationsAndCommit(ctx, ctx->numsubwindows - 1, -1);
	}
	return XteventHandled;

      case EnterWindow:
	if (ctx -> autoraise)
	    XRaiseWindow (ctx -> window);
	return XteventHandled;

      case DestroyWindow:
	ctx->refiguremode = FALSE;
	for (i = ctx->numsubwindows-1 ; i >= 0 ; i--)
	    (void) XtSendDestroyNotify(ctx->sub[i].w);
	(void) XtDeleteContext(ctx->window, vPaneContext);
	XtClearEventHandlers(ctx->window);
	XtFree((char *)ctx->sub);
	XtFree((char *)ctx);
	return XteventHandled;
    }
    return XteventNotHandled;
}

static XtEventReturnCode HandleSubwindow(event)
  XEvent *event;
{
    PanedWindowPtr ctx;
    if (event->type == DestroyWindow) {
	ctx = PanedWindowPtrFromWindow(event->window);
	if (ctx) {
	    XtVPanedWindowDeletePane(ctx->window,
				     event->window);
	    return XteventHandled;
	}
    }
    return XteventNotHandled;
}

static XtEventReturnCode HandleKnob(event)
  XButtonEvent *event;
{
    PanedWindowPtr ctx;
    int     position, diff, y, i;

    ctx = PanedWindowPtrFromWindow(event->window);
    if (!ctx) return XteventNotHandled;
    switch (event->type) {
	case ButtonPressed: 
	    y = event->y;
	    if (ctx->whichtracking != -1)
		return XteventNotHandled;
	    for (position = 0; position < ctx->numsubwindows; position++)
		if (ctx->sub[position].knob == event->window)
		    break;
	    if (position >= ctx->numsubwindows)
		return XteventNotHandled;
	    
	    XtGrabMouse(event->window, 
			XtGetCursor(CursorNums[event->detail & 0xff]),
			MouseMoved | ButtonReleased);
	    ctx->whichadd = ctx->whichsub = NULL;
	    ctx->whichdirection = (event->detail & 0xff) - 1;
	    ctx->starty = y;
	    if (ctx->whichdirection >= 0) {
		ctx->whichadd = ctx->sub + position;
		while (ctx->whichadd->max == ctx->whichadd->min &&
			ctx->whichadd > ctx->sub)
		    (ctx->whichadd)--;
	    }
	    if (ctx->whichdirection <= 0) {
		ctx->whichsub = ctx->sub + position + 1;
		while (ctx->whichsub->max == ctx->whichsub->min &&
			ctx->whichsub < ctx->sub + ctx->numsubwindows - 1)
		    (ctx->whichsub)++;
	    }
	    ctx->whichtracking = position;
	    if (ctx->whichdirection == 1)
		(ctx->whichtracking)++;
	    XClipDrawThrough(ctx->window);
	    EraseInternalBorders(ctx);
	    for (i = 0; i < ctx->numsubwindows; i++)
		ctx->sub[i].olddy = -99;
	/* Fall through */

	case MouseMoved: 
	case ButtonReleased:
            y = event->y;
	    if (ctx->whichtracking == -1)
		return XteventNotHandled;
	    for (i = 0; i < ctx->numsubwindows; i++)
		ctx->sub[i].dheight = ctx->sub[i].height;
	    diff = y - ctx->starty;
	    if (ctx->whichadd)
		ctx->whichadd->dheight = ctx->whichadd->height + diff;
	    if (ctx->whichsub)
		ctx->whichsub->dheight = ctx->whichsub->height - diff;
	    RefigureLocations(ctx, ctx->whichtracking, ctx->whichdirection);

	    if (event->type != ButtonReleased) {
		DrawTrackLines(ctx);/* Draw new borders */
		return XteventHandled;
	    }
	    XtUngrabMouse();
	    EraseTrackLines(ctx);
	    CommitNewLocations(ctx);
	    DrawInternalBorders(ctx);
	    XClipClipped(ctx->window);
	    ctx->whichtracking = -1;
	    return XteventHandled;
    }
    return XteventNotHandled;
}
  

/* Public routines. */

static Boolean initialized = FALSE;

extern void VPanedInitialize()
{
    if (initialized)
    	return;
    initialized = TRUE;

    vPaneContext = XtUniqueContext();
    globinit.window = NULL;
    globinit.x = globinit.y = 0;
    globinit.width = globinit.height = globinit.borderWidth = 1;
    globinit.knobwidth = DEFAULTKNOBWIDTH;
    globinit.knobheight = DEFAULTKNOBHEIGHT;
    globinit.knobindent = DEFAULTKNOBINDENT;
    globinit.knobpixel = -1;
}


Window XtVPanedWindowCreate(parent, args, argCount)
    Window   parent;
    ArgList  args;
    int      argCount;
{
    PanedWindowPtr ctx;
    XtNameList	names;
    XtClassList	classes;
    WindowInfo info;    

    if (!initialized) VPanedInitialize();

    ctx = (PanedWindowPtr) XtMalloc(sizeof(PanedWindowInfo));
    glob = globinit;
    XtGetResources(resources, XtNumber(resources), args, argCount, parent,
	"vpane", "VPane", &names, &classes);
    *ctx = glob;


    if (ctx->window != NULL) {
        XQueryWindow(ctx->window, &info);
        ctx->x = info.x;
        ctx->y = info.y;
        ctx->width = info.width;
        ctx->height = info.height;
        ctx->borderWidth = info.bdrwidth;
    } else {
        ctx->window = XCreateWindow(parent, ctx->x, ctx->y, ctx->width,
                              ctx->height, ctx->borderWidth,
                              ctx->borderpixmap, 
                              XMakeTile(ctx->backgroundpixel) );
    }

    XtSetNameAndClass(ctx->window, names, classes);
    XtFreeNameList(names);
    XtFreeClassList(classes);
    if (ctx->knobpixel < 0)
	ctx->knobpixel = ctx->foregroundpixel;
    ctx->heightused = 0;
    ctx->numsubwindows = 0;
    ctx->sub = (SubWindowInfo *) XtMalloc(1);
    ctx->whichtracking = -1;
    ctx->refiguremode = TRUE;
    (void) XtSaveContext(ctx->window, vPaneContext, (caddr_t) ctx);
    (void) XtSetEventHandler(ctx->window, HandleEvents, ExposeWindow
		| EnterWindow, (caddr_t) NULL);
    return ctx->window;
}


void XtVPanedWindowDelete(w)
    Window w;
{
    PanedWindowPtr ctx;
    int i;
    ctx = PanedWindowPtrFromWindow(w);
    if (!ctx) return;
    XUnmapWindow(w);
    for (i=ctx->numsubwindows-1 ; i>=0 ; i--) 
	XtVPanedWindowDeletePane(w, ctx->sub[i].w);
    (void) XtDeleteContext(w, vPaneContext);
    XtFree((char *) ctx->sub);
    XtFree((char *) ctx);
}



void XtVPanedWindowAddPane(parent, paneWindow, position, min, max, autochange)
    Window parent, paneWindow;
    int position, min, max, autochange;
{
    PanedWindowPtr ctx;
    int i, needed;
    SubWindowPtr sub;
    WindowInfo info;

    ctx = PanedWindowPtrFromWindow(parent);
    if (!ctx) return;
    ctx->numsubwindows++;
    ctx->sub = (SubWindowPtr)
	XtRealloc((char *) ctx->sub,
	       	  (unsigned) ctx->numsubwindows * sizeof(SubWindowInfo));
    for (i = ctx->numsubwindows - 1; i > position; i--)
	ctx->sub[i] = ctx->sub[i - 1];
    XQueryWindow(paneWindow, &info);
    sub = &(ctx->sub[position]);
    sub->w = paneWindow;
    sub->y = info.y;
    sub->height = sub->dheight = info.height;
    if (info.width != ctx->width || info.x != -BORDERWIDTH) {
        XConfigureWindow(paneWindow, -BORDERWIDTH, info.y,
                ctx->width, info.height);
    }
    sub->min = min;
    sub->max = max;
    sub->autochange = autochange;
    needed = sub->height + BORDERWIDTH + ctx->heightused;
    if (needed > ctx->height)
	TryResize(ctx, ctx->width, needed);
    (void) XtSetGeometryHandler(paneWindow, PanedWindowGeometryRequest);
    sub->knob = XCreateWindow(ctx->window, -99, -99,
			      ctx->knobwidth, ctx->knobheight,
			      0, XMakeTile(0), XMakeTile(ctx->knobpixel) );
    (void) XtSaveContext(sub->w, vPaneContext, (caddr_t) ctx);
    (void) XtSaveContext(sub->knob, vPaneContext, (caddr_t) ctx);
    XDefineCursor(sub->knob, XtGetCursor("sb_v_double_arrow"));
    XMapWindow(sub->w);
    XMapWindow(sub->knob);
    (void) XtSetEventHandler(sub->w, HandleSubwindow, ExposeWindow,
     (caddr_t) NULL);
    (void) XtSetEventHandler(sub->knob, HandleKnob, 
			ButtonPressed | ButtonReleased | RightDownMotion |
			MiddleDownMotion | LeftDownMotion,
                        (caddr_t) NULL);
    RefigureLocationsAndCommit(ctx, position, 1);
    for (i=0 ; i<ctx->numsubwindows; i++)
	XRaiseWindow(ctx->sub[i].knob);
}


/* Change the min and max size of the given sub window. */

void XtVPanedSetMinMax(w, paneWindow, min, max)
Window w, paneWindow;
int    min, max;
{
    PanedWindowPtr ctx;
    int i;
    ctx = PanedWindowPtrFromWindow(w);
    if (!ctx)
	return;
    for (i = 0; i < ctx->numsubwindows; i++) {
	if (ctx->sub[i].w == paneWindow) {
	    ctx->sub[i].min = min;
	    ctx->sub[i].max = max;
	    RefigureLocationsAndCommit(ctx, i, 1);
	    return;
	}
    }
}



/* Delete the given paneWindow from the given paned window.  Doesn't actually
   destroy the paneWindow. */

void XtVPanedWindowDeletePane(w, paneWindow)
    Window w, paneWindow;
{
    PanedWindowPtr ctx;
    int     i;
    Boolean j;

    ctx = PanedWindowPtrFromWindow(w);
    if (!ctx)
	return;
    j = FALSE;
    for (i = 0; i < ctx->numsubwindows; i++) {
	if (ctx->sub[i].w == paneWindow) {
	    j = TRUE;
	    (void) XtDeleteContext(ctx->sub[i].w, vPaneContext);
	    (void) XtDeleteContext(ctx->sub[i].knob, vPaneContext);
	    (void) XtSetEventHandler(ctx->sub[i].w, HandleSubwindow,
	     (unsigned long) NULL, (caddr_t) NULL);
	    XtClearEventHandlers(ctx->sub[i].knob);
	    XDestroyWindow(ctx->sub[i].knob);
	    (void) XtSendDestroyNotify(ctx->sub[i].knob);
	    TryResize(ctx, ctx->width,
		    ctx->height - ctx->sub[i].height - BORDERWIDTH);
	}
	if (j && i < ctx->numsubwindows - 1)
	    ctx->sub[i] = ctx->sub[i + 1];
    }
    if (!j)
	return;
    ctx->numsubwindows--;
    if (ctx->numsubwindows > 0) {
	ctx->sub = (SubWindowPtr)
	    XtRealloc((char *) ctx->sub,
	     (unsigned) ctx->numsubwindows * sizeof(SubWindowInfo));
    }
    RefigureLocationsAndCommit(ctx, ctx->numsubwindows - 1, -1);
}


void XtVPanedAllowResize(window, paneWindow, allowresize)
    Window window, paneWindow;
    Boolean  allowresize;
{
    PanedWindowPtr ctx;
    int i;
    ctx = PanedWindowPtrFromWindow(window);
    if (ctx)
	for (i=0 ; i<ctx->numsubwindows ; i++)
	    if (ctx->sub[i].w == paneWindow)
		ctx->sub[i].allowresize = allowresize;
}




void XtVPanedRefigureMode(window, mode)
  Window window;
  Boolean  mode;
{
    PanedWindowPtr ctx;
    ctx = PanedWindowPtrFromWindow(window);
    if (ctx) {
	ctx->refiguremode = mode;
	if (mode)
	    RefigureLocationsAndCommit(ctx, ctx->numsubwindows - 1, -1);
    }
}

void XtVPanedGetValues(w, args, argCount)
Window w;
ArgList args;
int argCount;
{
    PanedWindowPtr ctx;
    ctx = PanedWindowPtrFromWindow(w);
    glob = *ctx;
    XtGetValues(resources, XtNumber(resources), args, argCount);
}

void XtVPanedSetValues(w, args, argCount)
Window w;
ArgList args;
int argCount;
{
    PanedWindowPtr ctx;
    ctx = PanedWindowPtrFromWindow(w);
    glob = *ctx;
    XtSetValues(resources, XtNumber(resources), args, argCount);
    *ctx = glob;
}