/*
 *	$Source: /u1/X/DECToolkit/src/RCS/ScrollBar.c,v $
 *	$Header: ScrollBar.c,v 1.1 86/12/17 09:02:26 swick Exp $
 */

#ifndef lint
static char *rcsid_ScrollBar_c = "$Header: ScrollBar.c,v 1.1 86/12/17 09:02:26 swick Exp $";
#endif	lint

#ifndef lint
static char *sccsid = "@(#)ScrollBar.c	1.11          12/11/86";
#endif lint
/*
 *			  COPYRIGHT 1986
 *		   DIGITAL EQUIPMENT CORPORATION
 *		       MAYNARD, MASSACHUSETTS
 *			ALL RIGHTS RESERVED.
 *
 * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
 * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
 * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
 * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
 *
 * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
 * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
 * SET FORTH ABOVE.
 *
 *
 * 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.
 */


/*
 * 
 * Author: K. Langone
 *
 */

#include <stdio.h>
#include <X/Xlib.h>
#include "Toolkit.h"

/* Private Definitions */

#define scrollbarEvents (LeaveWindow | EnterWindow | ButtonPressed | \
			 ButtonReleased | LeftDownMotion | ExposeWindow) 
#define scrollbuttonEvents (ExposeRegion | ExposeWindow | \
 			 ButtonPressed | ButtonReleased) 
#define IgnoreEvent -1

typedef struct _ScrollBarData {
    Window tw;			/* scroll bar tool window */
    Window pw;			/* parent window, needed for resizing */
    Window leftorupw;		/* window for the left or upper button */
    Window rightordownw;	/* window for the righ or lower button */
    enum WhichWay orientation;	/* left-right-up-down */
    float   thumbpos;		/* thumb pos. on scroll bar(0.0-1.0) */
    int     thumbx, thumby;	/* integer pixel position */
    int     thumbsize;		/* height of thumb */
    Pixmap brcolor;	        /* border color index */
    Pixmap background;	        /* pixmap of background */
    int     brwidth;		/* border width */
    Pixmap thumbcolor;   	/* thumb color iondex */
    int     width;		/* max width of scroll bar */
    int     otherdim;		/* other window dimension */
    int     sthick;		/* thickness of scroll bar */
    int     (*ThumbProc) ();	/* procedure called when thumb is moved */
    int     (*PageProc) ();	/* procedure called when either of the two
				   page buttons are clicked */
    caddr_t tag;		/* additional tool data */
}                               ScrollBarData;

static int  scrollbarContext;
static int  initDone = 0;
extern char *malloc ();
float  *ptr;

/* =================================================================== */
/* Private Procedures */


static  Initialize () 
{
    scrollbarContext = UniqueEntryType ();
    initDone = 1;
}

static Dummy()
{
	printf("dummy callback for ScrollBar\n");
}

/* -----> Utilities */

/*  This procedure will move the thumb using
 *  two XTileSet calls
 *  If the thumbx or thumby = IgnoreEvent the
 *  current thumb position is not updated ,
 *  this condition will occur on expose window events
 */


/* =================================================================== */

/* -----> Utilities */

/*  This procedure will move the thumb using
 *  two XTileSet calls
 *  If the thumbx or thumby = IgnoreEvent the
 *  current thumb position is not updated ,
 *  this condition will occur on expose window events or
 *  changing the thumb size
 */

static  void MoveTheThumb (data, event)
ScrollBarData * data;
XButtonPressedEvent * event;

{


    int     newpos, update, delta, deltax, deltay;

 /* -----> check to see if thumb should be moved */

    update = 1;

    if (data -> orientation == Down | data -> orientation == Up) {
    /* -----> move thumb pixmap horizontally */

	if (data -> thumbx == IgnoreEvent) {
	/* ignore input event */
	    update = 0;
	    data -> thumbx =
		(int) (data -> thumbpos * (data -> width - data -> thumbsize));

	/* don't need to clear */
	    XTileSet (data -> tw, data -> thumbx, data -> thumby,
		    data -> thumbsize, data -> sthick, data -> thumbcolor);

	}

	else
	    if (event -> x >= data -> width - data -> thumbsize)
				/* got input at end of scroll bar */
		newpos = data -> width - data -> thumbsize;

	    else
		if (event -> x < 0)/* possible error */
		    newpos = 0;
		else		/* valid input for scroll bar */
		    newpos = event -> x;


    /* ----->Calculate the clear and draw areas */


	if (update) {
	    delta = abs (newpos - data -> thumbx);
	    deltax = data -> thumbsize - delta;
	    if (abs (newpos - data -> thumbx) >= data -> thumbsize) {
	    /* clear all of the thumb */
		XTileSet (data -> tw, newpos, data -> thumby,
			data -> thumbsize, data -> sthick,
			data -> thumbcolor);
		XTileSet (data -> tw, data -> thumbx, data -> thumby,
			data -> thumbsize, data -> sthick,
			data -> background);
	    }
	    else
		if (newpos < data -> thumbx) {
		    XTileSet (data -> tw, newpos, data -> thumby,
			    delta, data -> sthick,
			    data -> thumbcolor);
		    XTileSet (data -> tw, data -> thumbx + deltax,
			    data -> thumby, delta, data -> sthick, 
			    data -> background);
		}
		else {		/* newpos > data->thumbx */
		    XTileSet (data -> tw, newpos + deltax, data -> thumby,
			    delta, data -> sthick, data -> thumbcolor);
		    XTileSet (data -> tw, data -> thumbx, data -> thumby,
			    delta, data -> sthick, data -> background);
		}
	/* update thumb position */
	    data -> thumbx = newpos;
	}

    }				/* end up/down scroll bar */

    else {
    /* -----> move thumb pixmap vertically */

	if (data -> thumby == IgnoreEvent) {
	/* ignore input event */
	    update = 0;
	    data -> thumby =
		(int) (data -> thumbpos * (data -> width - data -> thumbsize));

	/* don't need to clear */
	    XTileSet (data -> tw, data -> thumbx, data -> thumby,
		    data -> sthick, data -> thumbsize, data -> thumbcolor);

	}

	else
	    if (event -> y >= data -> width - data -> thumbsize)
				/* got input at end of scroll bar */
		newpos = data -> width - data -> thumbsize;

	    else
		if (event -> y < 0)/* possible error */
		    newpos = 0;
		else		/* valid input for scroll bar */
		    newpos = event -> y;


    /* ----->Calculate the clear and draw areas */


	if (update) {
	    delta = abs (newpos - data -> thumby);
	    deltay = data -> thumbsize - delta;
	    if (abs (newpos - data -> thumby) >= data -> thumbsize) {
	    /* clear all of the thumb */
		XTileSet (data -> tw, data -> thumbx, newpos,
			data -> sthick, data -> thumbsize,
			data -> thumbcolor);
		XTileSet (data -> tw, data -> thumbx, data -> thumby,
			data -> sthick, data -> thumbsize,
			data -> background);
	    }
	    else
		if (newpos < data -> thumby) {
		    XTileSet (data -> tw, data -> thumbx, newpos,
			    data -> sthick, delta,
			    data -> thumbcolor);
		    XTileSet (data -> tw, data -> thumbx,
			    data -> thumby + deltay,
			    data -> sthick, delta, data -> background);
		}
		else {		/* newpos > data->thumby */
		    XTileSet (data -> tw, data -> thumbx, newpos + deltay,
			    data -> sthick, delta, data -> thumbcolor);
		    XTileSet (data -> tw, data -> thumbx, data -> thumby,
			    data -> sthick, delta, data -> background);
		}
	/* update thumb position */
	    data -> thumby = newpos;
	}

    }
 /* -----> Change the floating point relative thumb position */
    if (update) {
	data -> thumbpos = 
	(float) newpos / (float) (data -> width - 2 * data -> brwidth);
    }

}

/* =================================================================== */

/* This procedure reports the thumb position
 * in floating point to the ThumbProc
 */

static  void ReportThumbPosition (data, event)
ScrollBarData * data;
XButtonPressedEvent * event;


{
    float   finalvalue;
    caddr_t tooldata;

    if (data -> orientation == Down | data -> orientation == Up) {
	if (event -> x >= data -> width - (int) data -> thumbsize)
	    finalvalue = 1.0;
	else
	    if (event -> x < 0)
		finalvalue = 0.0;
	    else
		finalvalue = (float) event -> x /
		    ((float) (data -> width - data -> thumbsize));
    }
    else {
	if (event -> y >= data -> width - (int) data -> thumbsize)
	    finalvalue = 1.0;
	else
	    if (event -> y < 0)
		finalvalue = 0.0;
	    else
		finalvalue = (float) event -> y /
		    ((float) (data -> width - data -> thumbsize));
    }

 /* -----> call the client procedure */
    data -> ThumbProc (finalvalue, data -> tag);

}
/* =================================================================== */

/* This procedure will configure the scroll bar with
 * the new dimensions and update the parent window
 * dimensions in the scroll bar data structure
 */

static  void ConfigureScrollBar (data, x, y, width, height)
        ScrollBarData * data;
int     x, y;
int     width;
int     height;

{

 /* -----> Set the Scroll Bar data to the new values */

    if (data -> orientation == Up | data -> orientation == Down) {

	data -> width = width;
	data -> otherdim = height;

    }
    else {
	data -> width = height;
	data -> otherdim = width;
    }

    if (data -> orientation == Up)
	XConfigureWindow (data -> tw, 0, 0,
		data -> width - 2 * data -> brwidth, data -> sthick);

    else
	if (data -> orientation == Down)
	    XConfigureWindow (data -> tw, 0,
		    height - data -> sthick - data -> brwidth,
		    data -> width - 2 * data -> brwidth, data -> sthick);

	else
	    if (data -> orientation == Left)
		XConfigureWindow (data -> tw, 0, 0,
			data -> sthick, data -> width - 2 * data -> brwidth);

	    else
		XConfigureWindow (data -> tw,
			width - data -> sthick - data -> brwidth, 0,
			data -> sthick, data -> width - 2 * data -> brwidth);

    XFlush ();



}

/* =================================================================== */

/* The procedure checks to see if the window size was 
 * and will invoke ConfigureScrollBar if necessary
 */

static  void CheckForResize (data, event)
        ScrollBarData * data;
XEvent * event;

{
    WindowInfo info;

 /* -----> get parent window information */
    XQueryWindow (data -> pw, &info);

    XFlush ();


    if (data -> orientation == Up | data -> orientation == Down) {
	if (info.width != data -> width | info.height != data -> otherdim) {
	/* resize the window */
	    ConfigureScrollBar (data, info.x, info.y,
		    info.width, info.height);
	}
    }
    else {
	if (info.height != data -> width | info.width != data -> otherdim) {
	/* resize the window */
	    ConfigureScrollBar (data, info.x, info.y,
		    info.width, info.height);
	}
    }

}
/* =================================================================== */

/* This procedure will process the Scroll Bar events
 * and given the event will invoke routines to
 * move the thumb and check for resize 
 */

static int  TProcessScrollBarEvent (event)
            XEvent * event;
{
    int     x, y, subW, error;
    int     returnCode;
    short   state;
    ScrollBarData * data;
    Status status;


    error = FindEntry (event -> window, scrollbarContext, &data);

    if (error != ERRNONE)
	return (NOTHANDLED);
    returnCode = PROCESSED;
    switch (event -> type) {
	case MouseMoved: 
	    MoveTheThumb (data, event);
	case ButtonPressed: 
	    MoveTheThumb (data, event);
	    ReportThumbPosition (data, event);
	    break;
	case ButtonReleased: 
	    MoveTheThumb (data, event);
	    ReportThumbPosition (data, event);
	    break;
	case ExposeWindow: 

	    CheckForResize (data, event);

	/* -----> Don't Update Relative Thumb position */
	    if (data -> orientation == Up | data -> orientation == Down)
		data -> thumbx = IgnoreEvent;
	    else
		data -> thumby = IgnoreEvent;

	    MoveTheThumb (data, event);
	case EnterWindow: 
	    break;
	case LeaveWindow: 
	    break;
	default: 
	    returnCode = NOTHANDLED;
    }
    return (returnCode);
}
/* =================================================================== */

/* ----->NOTE: This routine has not been debugged 
*/

/* This procedure will handle input for the scroll bar buttons */

static int  TProcessSButtonEvent (event)
            XEvent * event;
{
    int     x, y, subW, error;
    int     returnCode;
    short   state;
    ScrollBarData * data;
    Status status;

    /* Code to be supplied */

    return (returnCode);
}


/* Public Procedures */
/* =================================================================== */
/*
 * This procedure will reposition the thumb
 * and can be called from the application
 */


Status TSetThumbPosition (tw, thumbpos)
Window tw;			/* scroll bar tool window */
float   thumbpos;		/* thumb position on scroll bar(0.0-1.0) 
				*/
{

    ScrollBarData * data;
    int     error;
    Status status;
    float   movelength;
    WindowInfo info;

    error = FindEntry (tw, scrollbarContext, &data);
 /* put in error check on thumbpos later (0.0-1.0) */

    movelength = (float) (data -> width) - data -> thumbsize;

 /* if (data->orientation == Up | data->orientation == Down) else */

 /* -----> change the value in the data structure */
    data -> thumbpos = thumbpos;
    status = 1;

}

/* =================================================================== */
/*
 *
 * This procedure will resize the scroll bar thumb
 */
Status TSetThumbSize (tw, thumbsize)
Window tw;			/* scroll bar tool window */
float   thumbsize;		/* thumb size as portion of scroll bar */
{

    ScrollBarData * data;
    XEvent * event;		/* this is only used as a pointer */
    int     error;
    Status status;


 /* -----> Error check for appropriate thumbsize */
 /* if (thumbsize > 1.0) or (thumbsize < 0.0) then report error */

 /* -----> Get scroll bar data */
    error = FindEntry (tw, scrollbarContext, &data);

 /* -----> Calulate the thumb size in pixels */
    data -> thumbsize = (int) (thumbsize * (float) data -> width);


}

/* =================================================================== */
/*
 *
 * This procedure will refresh the Scroll Bar
 */
Status TRefreshScrollBar (tw)
Window tw;			/* scroll bar tool window */
{

    ScrollBarData * data;
    XEvent * event;		/* this is only used as a pointer */
    int     error;
    Status status;

 /* -----> Get the data */
    error = FindEntry (tw, scrollbarContext, &data);
 /* -----> Set Ignore Event flag */
    if (data -> orientation == Down | data -> orientation == Up)
	data -> thumbx = IgnoreEvent;
    else
	data -> thumby = IgnoreEvent;

 /* -----> Invoke procedure to display new thumb size */
    MoveTheThumb (data, event);
}

/* =================================================================== */
/*
 * This procedure will reconfigure the scroll bar
 * and obtain the tool's data
 * Note: if Up/Down Scroll bar - width = long dimension
 *       else for Left/Right Scroll bar - height = long dimension
 */


Status TConfigureScrollBar (tw, x, y, width, height)
Window tw;			/* scroll bar tool window */
int     x, y;			/* new window position */
int     width;			/* new scroll bar width */
int     height;			/* new scroll bar height */
{

    ScrollBarData * data;
    int     error;
    float   thumbsize;
    Status status;

 /* -----> Get the scroll bar data */
    error = FindEntry (tw, scrollbarContext, data);

 /* -----> Proportionally Change the Thumbsize */
    if (data -> orientation == Down | data -> orientation == Up)
	thumbsize = (float) width / (float) data -> width;
    else
	thumbsize = (float) height / (float) data -> width;

    TSetThumbSize (tw, thumbsize);

    ConfigureScrollBar (data, x, y, width, height);
}

/* =================================================================== */
/*
 * This procedure will destroy a scroll bar 
 *
 */

Status TDestroyScrollBar (tw)
Window tw;
{

 /* -----> Delete the data in the table */
    DeleteEntry (tw, scrollbarContext);

 /* Other code, tbd... */
}

/* =================================================================== */

/*
 * This procedure will create a command button and will set predefined
 * values colors,font,and state selection. If any errors are detected
 * during the parsing of the input arguments, an exit will occur.
 *
 */

Status TGetScrollBarAttr (tw, arglist)
Window tw;			/* tool window */
Targ * arglist;
{
    ScrollBarData * data;
    int     return_code;	/* return code from window creation */
    int     i, error;

    error = FindEntry (tw, scrollbarContext, &data);

 /* -----> Parsing input parameters */


    while (arglist -> name) {
	switch (arglist -> name) {
	    case T_SCROLLBAR_ORIENT: 
		arglist -> data = (caddr_t) data -> orientation;
		break;
	    case T_SCROLLBAR_STHICK: 
		arglist -> data = (caddr_t) data -> sthick;
		break;
	    case T_SCROLLBAR_THUMBPOS: 
		arglist -> data = (caddr_t) & data -> thumbpos;
		break;
	    case T_SCROLLBAR_THUMBSIZE: 
		arglist -> data = (caddr_t) data -> thumbsize;
		break;
	    case T_SCROLLBAR_THUMBCOLOR: 
		arglist -> data = (caddr_t) data -> thumbcolor;
		break;
	    case T_SCROLLBAR_BRCOLOR: 
		arglist -> data = (caddr_t) data -> brcolor;
		break;
	    case T_SCROLLBAR_BACKGROUND: 
		arglist -> data = (caddr_t) data -> background;
		break;
	    case T_SCROLLBAR_BRWIDTH: 
		arglist -> data = (caddr_t) data -> brwidth;
		break;
	    case T_SCROLLBAR_TPROC: 
		arglist -> data = (caddr_t) data -> ThumbProc;
		break;
	    case T_SCROLLBAR_PPROC: 
		arglist -> data = (caddr_t) data -> PageProc;
		break;
	    case T_SCROLLBAR_TAG: 
		arglist -> data = (caddr_t) data -> tag;
	    default: 
		break;
	}
	arglist++;
    }


}
/* =================================================================== */

/*
 * This procedure will create a command button and will set predefined
 * values colors,font,and state selection. If any errors are detected
 * during the parsing of the input arguments, an exit will occur.
 *
 */

Status TSetScrollBarAttr (tw, arglist)
Window tw;			/* tool window */
Targ * arglist;
{
    ScrollBarData * data;
    int     return_code;	/* return code from window creation */
    int     twidth, theight;
    int     error;

    error = FindEntry (tw, scrollbarContext, &data);

 /* -----> Parsing input parameters */


    while (arglist -> name) {
	switch (arglist -> name) {
	    case T_SCROLLBAR_ORIENT: 
		data -> orientation = (enum WhichWay) arglist -> data;
		break;
	    case T_SCROLLBAR_STHICK: 
		data -> sthick = (int) arglist -> data;
		break;
	    case T_SCROLLBAR_THUMBPOS: 
		ptr = (float *) (arglist -> data);
		data -> thumbpos = *ptr;
		break;
	    case T_SCROLLBAR_THUMBSIZE: 
		data -> thumbsize = (int) arglist -> data;
		break;
	    case T_SCROLLBAR_THUMBCOLOR: 
		data -> thumbcolor = (int) arglist -> data;
		break;
	    case T_SCROLLBAR_BRCOLOR: 
		data -> brcolor = (Pixmap) arglist -> data;
		break;
	    case T_SCROLLBAR_BACKGROUND: 
		data -> background = (Pixmap) arglist -> data;
		break;
	    case T_SCROLLBAR_BRWIDTH: 
		data -> brwidth = (int) arglist -> data;
		break;
	    case T_SCROLLBAR_TPROC: 
		data -> ThumbProc = (int (*) ()) arglist -> data;
		break;
	    case T_SCROLLBAR_PPROC: 
		data -> PageProc = (int (*) ()) arglist -> data;
		break;
	    case T_SCROLLBAR_TAG: 
		data -> tag = arglist -> data;
	    default: 
		break;
	}
	arglist++;
    }

    TRefreshScrollBar (tw);

}

/* =================================================================== */

/*
 *
 * This procedure will create a scroll bar
 *
 */

Window TCreateScrollBar (pw, arglist)
Window pw;
Targ * arglist;

{
    ScrollBarData * data;
    WindowInfo info;
    Window tw;
    Status status;
    int     thumbx, thumby;
    int     brdelta;

 /* -----> Perform initialization */
    if (!initDone)
	Initialize ();

 /* -----> Allocate space for data structure */
    data = (ScrollBarData *) Tmalloc (sizeof (ScrollBarData));

 /* -----> Set Default Values */
    data -> orientation = Right;
    data -> sthick = 20;
    data -> thumbpos = 0.0;
    data -> thumbsize = 10;
    data -> brcolor = BlackPixmap;
    data -> background = WhitePixmap;
    data -> brwidth = 2;
    data -> thumbcolor = BlackPixmap;
    data -> ThumbProc = Dummy;
    data -> PageProc = NULL;

 /* -----> Parsing input parameters */

    while (arglist -> name) {
	switch (arglist -> name) {
	    case T_SCROLLBAR_ORIENT: 
		data -> orientation = (enum WhichWay) arglist -> data;
		break;
	    case T_SCROLLBAR_STHICK: 
		data -> sthick = (int) arglist -> data;
		break;
	    case T_SCROLLBAR_THUMBPOS: 
		ptr = (float *) (arglist -> data);
		data -> thumbpos = *ptr;
		break;
	    case T_SCROLLBAR_THUMBSIZE: 
		data -> thumbsize = (int) arglist -> data;
		break;
	    case T_SCROLLBAR_THUMBCOLOR: 
		data -> thumbcolor = (int) arglist -> data;
		break;
	    case T_SCROLLBAR_BRCOLOR: 
		data -> brcolor = (Pixmap) arglist -> data;
		break;
	    case T_SCROLLBAR_BACKGROUND: 
		data -> background = (Pixmap) arglist -> data;
		break;
	    case T_SCROLLBAR_BRWIDTH: 
		data -> brwidth = (int) arglist -> data;
		break;
	    case T_SCROLLBAR_TPROC: 
		data -> ThumbProc = (int (*) ()) arglist -> data;
		break;
	    case T_SCROLLBAR_PPROC: 
		data -> PageProc = (int (*) ()) arglist -> data;
		break;
	    case T_SCROLLBAR_TAG: 
		data -> tag = arglist -> data;
	    default: 
		break;
	}
	arglist++;
    }

 /* -----> Get parent window dimensions */
    status = XQueryWindow (pw, &info);

 /* -----> Given the dimensions, create the scroll bar window and thumb
    window */

    brdelta = 2 * data -> brwidth;

    if (data -> orientation == Up) {
	tw = XCreateWindow (pw, 0, 0,
		info.width - brdelta, data -> sthick,
		data -> brwidth,
		data -> brcolor, data -> background);
	data -> width = info.width;
	data -> otherdim = info.height;
    }
    else
	if (data -> orientation == Down) {
	    tw = XCreateWindow (pw, 0,
		    info.height - data -> sthick - data -> brwidth,
		    info.width - brdelta, data -> sthick,
		    data -> brwidth,
		    data -> brcolor, data -> background);
	    data -> width = info.width;
	    data -> otherdim = info.height;
	}
	else
	    if (data -> orientation == Left) {
		tw = XCreateWindow (pw, 0, 0,
			data -> sthick, info.height - brdelta,
			data -> brwidth,
			data -> brcolor, data -> background);
		data -> width = info.height;
		data -> otherdim = info.width;
	    }
	    else {		/* orientation==Right */
		tw = XCreateWindow (pw,
			info.width - data -> sthick - data -> brwidth,
			0,
			data -> sthick, info.height - brdelta,
			data -> brwidth,
			data -> brcolor, data -> background);
		data -> width = info.height;
		data -> otherdim = info.width;
	    }


    if (tw == 0)
	printf ("Error in creating scrollbar\n");


 /* -----> Get tool window dimensions */
    status = XQueryWindow (tw, &info);

    if (data -> orientation == Up | data -> orientation == Down) {
	data -> thumbx = -1;
	data -> thumby = 0;
	data -> sthick = info.height;
    }
    else {
	data -> thumby = -1;
	data -> thumbx = 0;
	data -> sthick = info.width;
    }

    data -> tw = tw;
    data -> pw = pw;

    SaveEntry (tw, scrollbarContext, data);
    TSetXEventDispatch (tw, TProcessScrollBarEvent, scrollbarEvents, 0);

 /* Put in page buttons later if (data->PageProc != 0) { /* -----> Save
    the scroll button entries, select in input, and save the event handler 
 */

 /* SaveEntry(leftorupw, scrollbarContext, data);
    TSetXEventDispatch(leftorupw, TProcessSButtonEvent,
    scrollbuttonEvents, 0); SaveEntry(rightordownw, scrollbarContext,
    data); TSetXEventDispatch(rightordownw, TProcessSButtonEvent,
    scrollbuttonEvents, 0); } */

    return (tw);
}
