/* vi:set ts=8 sts=4 sw=4: */
/*
 * MODIFIED ATHENA SCROLLBAR (USING ARROWHEADS AT ENDS OF TRAVEL)
 * Modifications Copyright 1992 by Mitch Trachtenberg
 * Rights, permissions, and disclaimer of warranty are as in the DEC and MIT
 * notice below.
 * $XConsortium: Scrollbar.c,v 1.72 94/04/17 20:12:40 kaleb Exp $
 */

/*
 * Modified for Vim by Bill Foster and Bram Moolenaar
 */

/*

Copyright (c) 1987, 1988, 1994	X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE X
CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be
used in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from the X Consortium.

Copyright 1987, 1988 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 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.

*/

/* ScrollBar.c */
/* created by weissman, Mon Jul  7 13:20:03 1986 */
/* converted by swick, Thu Aug 27 1987 */

#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>

#include <X11/Xaw/XawInit.h>
#include "vim.h"
#include "gui_at_sb.h"

#include <X11/Xmu/Drawing.h>

/* Private definitions. */

static char defaultTranslations[] =
    "<Btn1Down>: NotifyScroll()\n\
     <Btn2Down>: MoveThumb() NotifyThumb()\n\
     <Btn3Down>: NotifyScroll()\n\
     <Btn4Down>: ScrollOneLineUp()\n\
     Shift<Btn4Down>: ScrollPageUp()\n\
     <Btn5Down>: ScrollOneLineDown()\n\
     Shift<Btn5Down>: ScrollPageDown()\n\
     <Btn1Motion>: HandleThumb()\n\
     <Btn3Motion>: HandleThumb()\n\
     <Btn2Motion>: MoveThumb() NotifyThumb()\n\
     <BtnUp>: EndScroll()";

static float floatZero = 0.0;

#define Offset(field) XtOffsetOf(ScrollbarRec, field)

static XtResource resources[] =
{
  {XtNlength, XtCLength, XtRDimension, sizeof(Dimension),
       Offset(scrollbar.length), XtRImmediate, (XtPointer) 1},
  {XtNthickness, XtCThickness, XtRDimension, sizeof(Dimension),
       Offset(scrollbar.thickness), XtRImmediate, (XtPointer) 14},
  {XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation),
      Offset(scrollbar.orientation), XtRImmediate, (XtPointer) XtorientVertical},
  {XtNscrollProc, XtCCallback, XtRCallback, sizeof(XtPointer),
       Offset(scrollbar.scrollProc), XtRCallback, NULL},
  {XtNthumbProc, XtCCallback, XtRCallback, sizeof(XtPointer),
       Offset(scrollbar.thumbProc), XtRCallback, NULL},
  {XtNjumpProc, XtCCallback, XtRCallback, sizeof(XtPointer),
       Offset(scrollbar.jumpProc), XtRCallback, NULL},
  {XtNthumb, XtCThumb, XtRBitmap, sizeof(Pixmap),
       Offset(scrollbar.thumb), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
  {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
       Offset(scrollbar.foreground), XtRString, XtDefaultForeground},
  {XtNshown, XtCShown, XtRFloat, sizeof(float),
       Offset(scrollbar.shown), XtRFloat, (XtPointer)&floatZero},
  {XtNtopOfThumb, XtCTopOfThumb, XtRFloat, sizeof(float),
       Offset(scrollbar.top), XtRFloat, (XtPointer)&floatZero},
  {XtNmaxOfThumb, XtCMaxOfThumb, XtRFloat, sizeof(float),
       Offset(scrollbar.max), XtRFloat, (XtPointer)&floatZero},
  {XtNminimumThumb, XtCMinimumThumb, XtRDimension, sizeof(Dimension),
       Offset(scrollbar.min_thumb), XtRImmediate, (XtPointer) 7},
  {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
       Offset(scrollbar.shadow_width), XtRImmediate, (XtPointer) 1},
  {XtNtopShadowPixel, XtCTopShadowPixel, XtRPixel, sizeof(Pixel),
       Offset(scrollbar.top_shadow_pixel), XtRString, XtDefaultBackground},
  {XtNbottomShadowPixel, XtCBottomShadowPixel, XtRPixel, sizeof(Pixel),
       Offset(scrollbar.bot_shadow_pixel), XtRString, XtDefaultForeground},
  {XtNlimitThumb, XtCLimitThumb, XtRBool, sizeof(Bool),
       Offset(scrollbar.limit_thumb), XtRImmediate, (XtPointer)0}
};
#undef Offset

static void ClassInitialize __ARGS((void));
static void Initialize __ARGS((Widget, Widget, ArgList, Cardinal *));
static void Destroy __ARGS((Widget));
static void Realize __ARGS((Widget, Mask *, XSetWindowAttributes *));
static void Resize __ARGS((Widget));
static void Redisplay __ARGS((Widget, XEvent *, Region));
static Boolean SetValues __ARGS((Widget, Widget, Widget, ArgList, Cardinal *));

static void HandleThumb __ARGS((Widget, XEvent *, String *, Cardinal *));
static void MoveThumb __ARGS((Widget, XEvent *, String *, Cardinal *));
static void NotifyThumb __ARGS((Widget, XEvent *, String *, Cardinal *));
static void NotifyScroll __ARGS((Widget, XEvent *, String *, Cardinal *));
static void EndScroll __ARGS((Widget, XEvent *, String *, Cardinal *));
static void ScrollOneLineUp __ARGS((Widget, XEvent *, String *, Cardinal *));
static void ScrollOneLineDown __ARGS((Widget, XEvent *, String *, Cardinal *));
static void ScrollPageUp __ARGS((Widget, XEvent *, String *, Cardinal *));
static void ScrollPageDown __ARGS((Widget, XEvent *, String *, Cardinal *));
static void ScrollSome __ARGS((Widget w, XEvent *event, int call_data));
static void _Xaw3dDrawShadows __ARGS((Widget, XEvent *, Region, int));
static void AllocTopShadowGC __ARGS((Widget));
static void AllocBotShadowGC __ARGS((Widget));

static XtActionsRec actions[] =
{
    {"HandleThumb",	HandleThumb},
    {"MoveThumb",	MoveThumb},
    {"NotifyThumb",	NotifyThumb},
    {"NotifyScroll",	NotifyScroll},
    {"EndScroll",	EndScroll},
    {"ScrollOneLineUp", ScrollOneLineUp},
    {"ScrollOneLineDown", ScrollOneLineDown},
    {"ScrollPageUp",	ScrollPageUp},
    {"ScrollPageDown",	ScrollPageDown}
};


ScrollbarClassRec vim_scrollbarClassRec =
{
  { /* core fields */
    /* superclass	*/  (WidgetClass) &simpleClassRec,
    /* class_name	*/  "Scrollbar",
    /* size		*/  sizeof(ScrollbarRec),
    /* class_initialize	*/  ClassInitialize,
    /* class_part_init	*/  NULL,
    /* class_inited	*/  FALSE,
    /* initialize	*/  Initialize,
    /* initialize_hook	*/  NULL,
    /* realize		*/  Realize,
    /* actions		*/  actions,
    /* num_actions	*/  XtNumber(actions),
    /* resources	*/  resources,
    /* num_resources	*/  XtNumber(resources),
    /* xrm_class	*/  NULLQUARK,
    /* compress_motion	*/  TRUE,
    /* compress_exposure*/  TRUE,
    /* compress_enterleave*/	TRUE,
    /* visible_interest */  FALSE,
    /* destroy		*/  Destroy,
    /* resize		*/  Resize,
    /* expose		*/  Redisplay,
    /* set_values	*/  SetValues,
    /* set_values_hook	*/  NULL,
    /* set_values_almost */ XtInheritSetValuesAlmost,
    /* get_values_hook	*/  NULL,
    /* accept_focus	*/  NULL,
    /* version		*/  XtVersion,
    /* callback_private */  NULL,
    /* tm_table		*/  defaultTranslations,
    /* query_geometry	*/  XtInheritQueryGeometry,
    /* display_accelerator*/	XtInheritDisplayAccelerator,
    /* extension	*/  NULL
  },
  { /* simple fields */
    /* change_sensitive	*/  XtInheritChangeSensitive,
#ifndef OLDXAW
    /* extension */	    NULL
#endif
  },
  { /* scrollbar fields */
    /* empty	    */	    0
  }
};

WidgetClass vim_scrollbarWidgetClass = (WidgetClass)&vim_scrollbarClassRec;

#define NoButton -1
#define PICKLENGTH(widget, x, y) \
    ((widget->scrollbar.orientation == XtorientHorizontal) ? (x) : (y))
#define AT_MIN(x,y)    ((x) < (y) ? (x) : (y))
#define AT_MAX(x,y)    ((x) > (y) ? (x) : (y))

#define LINE_DELAY	300
#define PAGE_DELAY	300
#define LINE_REPEAT	 50
#define PAGE_REPEAT	250

    static void
ClassInitialize()
{
    XawInitializeWidgetSet();
    XtAddConverter( XtRString, XtROrientation, XmuCvtStringToOrientation,
	    (XtConvertArgList)NULL, (Cardinal)0 );
}

#define MARGIN(sbw) (sbw)->scrollbar.thickness + (sbw)->scrollbar.shadow_width

    static void
FillArea(sbw, top, bottom, fill, draw_shadow)
    ScrollbarWidget	sbw;
    Position		top, bottom;
    int			fill;
    int			draw_shadow;
{
    int tlen = bottom - top;	/* length of thumb in pixels */
    int sw, margin, floor;
    int lx, ly, lw, lh;

    if (bottom <= 0 || bottom <= top)
	return;
    sw = sbw->scrollbar.shadow_width;
    if (sw < 0)
	sw = 0;
    margin = MARGIN (sbw);
    floor = sbw->scrollbar.length - margin + 2;

    if (sbw->scrollbar.orientation == XtorientHorizontal)
    {
	lx = ((top < margin) ? margin : top);
	ly = sw;
	lw = (((top + tlen) > floor) ? floor - top : tlen);
	lh = sbw->core.height - 2 * sw;
    }
    else
    {
	lx = sw;
	ly = ((top < margin) ? margin : top);
	lw = sbw->core.width - 2 * sw;
	lh = (((top + tlen) > floor) ? floor - top : tlen);
    }
    if (lh <= 0 || lw <= 0)
	return;

    if (draw_shadow)
    {
	if (!(sbw->scrollbar.orientation == XtorientHorizontal))
	{
	    /* Top border */
	    XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		    sbw->scrollbar.top_shadow_GC,
		    lx, ly, lx + lw - 1, ly);

	    /* Bottom border */
	    XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		    sbw->scrollbar.bot_shadow_GC,
		    lx, ly + lh - 1, lx + lw - 1, ly + lh - 1);
	}
	else
	{
	    /* Left border */
	    XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		    sbw->scrollbar.top_shadow_GC,
		    lx, ly, lx, ly + lh - 1);

	    /* Right border */
	    XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		    sbw->scrollbar.bot_shadow_GC,
		    lx + lw - 1, ly, lx + lw - 1, ly + lh - 1);
	}
	return;
    }

    if (fill)
    {
	XFillRectangle(XtDisplay((Widget) sbw), XtWindow((Widget) sbw),
		sbw->scrollbar.gc,
		lx, ly, (unsigned int) lw, (unsigned int) lh);

	if (!(sbw->scrollbar.orientation == XtorientHorizontal))
	{
	    /* Left border */
	    XDrawLine(XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		    sbw->scrollbar.top_shadow_GC,
		    lx, ly, lx, ly + lh - 1);

	    /* Right border */
	    XDrawLine(XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		    sbw->scrollbar.bot_shadow_GC,
		    lx + lw - 1, ly, lx + lw - 1, ly + lh - 1);
	}
	else
	{
	    /* Top border */
	    XDrawLine(XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		    sbw->scrollbar.top_shadow_GC,
		    lx, ly, lx + lw - 1, ly);

	    /* Bottom border */
	    XDrawLine(XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		    sbw->scrollbar.bot_shadow_GC,
		    lx, ly + lh - 1, lx + lw - 1, ly + lh - 1);
	}
    }
    else
    {
	XClearArea(XtDisplay((Widget) sbw), XtWindow((Widget) sbw),
		lx, ly, (unsigned int) lw, (unsigned int) lh, FALSE);
    }
}

/* Paint the thumb in the area specified by sbw->top and
   sbw->shown.	The old area is erased.  The painting and
   erasing is done cleverly so that no flickering will occur.
 */

    static void
PaintThumb(sbw)
    ScrollbarWidget sbw;
{
    Position	    oldtop, oldbot, newtop, newbot;
    Dimension	    margin, tzl;

    margin = MARGIN (sbw);
    tzl = sbw->scrollbar.length - 2 * margin;
    newtop = margin + (int)(tzl * sbw->scrollbar.top);
    newbot = newtop + (int)(tzl * sbw->scrollbar.shown) + 1;
    if (newbot < newtop + (int)sbw->scrollbar.min_thumb)
	newbot = newtop + sbw->scrollbar.min_thumb;

    oldtop = sbw->scrollbar.topLoc;
    oldbot = oldtop + sbw->scrollbar.shownLength;
    sbw->scrollbar.topLoc = newtop;
    sbw->scrollbar.shownLength = newbot - newtop;
    if (XtIsRealized ((Widget) sbw))
    {
	if (newtop < oldtop)
	    FillArea(sbw, newtop, AT_MIN(newbot,	oldtop+1),1,0);
	if (newtop > oldtop)
	    FillArea(sbw, oldtop, AT_MIN(newtop,	oldbot	),0,0);
	if (newbot < oldbot)
	    FillArea(sbw, AT_MAX(newbot, oldtop),	oldbot,   0,0);
	if (newbot > oldbot)
	    FillArea(sbw, AT_MAX(newtop, oldbot-1), newbot,  1,0);

	/* Only draw the missing shadows */
	FillArea(sbw, newtop, newbot, 0, 1);
    }
}

    static void
PaintArrows(sbw)
    ScrollbarWidget sbw;
{
    XPoint	point[6];
    Dimension	thickness = sbw->scrollbar.thickness - 1;
    Dimension	size;
    Dimension	off;

    if (XtIsRealized((Widget) sbw))
    {
	if ((int)thickness * 2 > (int)sbw->scrollbar.length)
	{
	    size = sbw->scrollbar.length / 2;
	    off = (int)(thickness - size) / 2;
	}
	else
	{
	    size = thickness;
	    off = 0;
	}
	point[0].x = off + sbw->scrollbar.shadow_width;
	point[0].y = size;
	point[1].x = thickness - off - sbw->scrollbar.shadow_width;
	point[1].y = size;
	point[2].x = thickness / 2;
	point[2].y = sbw->scrollbar.shadow_width;

	point[3].x = off + sbw->scrollbar.shadow_width;
	point[3].y = sbw->scrollbar.length - size;
	point[4].x = thickness - off - sbw->scrollbar.shadow_width;
	point[4].y = sbw->scrollbar.length - size;
	point[5].x = thickness / 2;
	point[5].y = sbw->scrollbar.length - sbw->scrollbar.shadow_width - 1;

	/* horizontal arrows require that x and y coordinates be swapped */
	if (sbw->scrollbar.orientation == XtorientHorizontal)
	{
	    int n;
	    int swap;
	    for (n = 0; n < 6; n++)
	    {
		swap = point[n].x;
		point[n].x = point[n].y;
		point[n].y = swap;
	    }
	}
	/* draw the up/left arrow */
	XFillPolygon (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		sbw->scrollbar.gc,
		point, 3,
		Convex, CoordModeOrigin);
	XDrawLines (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		sbw->scrollbar.bot_shadow_GC,
		point, 3,
		CoordModeOrigin);
	XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		sbw->scrollbar.top_shadow_GC,
		point[0].x, point[0].y,
		point[2].x, point[2].y);
	/* draw the down/right arrow */
	XFillPolygon (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		sbw->scrollbar.gc,
		point+3, 3,
		Convex, CoordModeOrigin);
	XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		sbw->scrollbar.top_shadow_GC,
		point[3].x, point[3].y,
		point[4].x, point[4].y);
	XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		sbw->scrollbar.top_shadow_GC,
		point[3].x, point[3].y,
		point[5].x, point[5].y);
	XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
		sbw->scrollbar.bot_shadow_GC,
		point[4].x, point[4].y,
		point[5].x, point[5].y);
    }
}

    static void
Destroy(w)
    Widget w;
{
    ScrollbarWidget sbw = (ScrollbarWidget) w;
    if (sbw->scrollbar.timer_id != (XtIntervalId) 0)
	XtRemoveTimeOut (sbw->scrollbar.timer_id);
    XtReleaseGC(w, sbw->scrollbar.gc);
    XtReleaseGC(w, sbw->scrollbar.top_shadow_GC);
    XtReleaseGC(w, sbw->scrollbar.bot_shadow_GC);
}

    static void
CreateGC(w)
    Widget w;
{
    ScrollbarWidget	sbw = (ScrollbarWidget) w;
    XGCValues		gcValues;
    XtGCMask		mask;
    unsigned int	depth = 1;

    if (sbw->scrollbar.thumb == XtUnspecifiedPixmap)
    {
	sbw->scrollbar.thumb = XmuCreateStippledPixmap (XtScreen(w),
		    (Pixel) 1, (Pixel) 0, depth);
    }
    else if (sbw->scrollbar.thumb != None)
    {
	Window		root;
	int		x, y;
	unsigned int	width, height, bw;

	if (XGetGeometry (XtDisplay(w), sbw->scrollbar.thumb, &root, &x, &y,
		&width, &height, &bw, &depth) == 0)
	    EMSG(_("Scrollbar Widget: Could not get geometry of thumb pixmap."));
    }

    gcValues.foreground = sbw->scrollbar.foreground;
    gcValues.background = sbw->core.background_pixel;
    mask = GCForeground | GCBackground;

    if (sbw->scrollbar.thumb != None)
    {
	gcValues.fill_style = FillSolid;
	mask |= GCFillStyle;
    }
    /* the creation should be non-caching, because */
    /* we now set and clear clip masks on the gc returned */
    sbw->scrollbar.gc = XtGetGC (w, mask, &gcValues);
}

    static void
SetDimensions(sbw)
    ScrollbarWidget sbw;
{
    if (sbw->scrollbar.orientation == XtorientVertical)
    {
	sbw->scrollbar.length = sbw->core.height;
	sbw->scrollbar.thickness = sbw->core.width;
    }
    else
    {
	sbw->scrollbar.length = sbw->core.width;
	sbw->scrollbar.thickness = sbw->core.height;
    }
}

    static void
Initialize(request, new, args, num_args)
    Widget	request UNUSED;	/* what the client asked for */
    Widget	new;		/* what we're going to give him */
    ArgList	args UNUSED;
    Cardinal	*num_args UNUSED;
{
    ScrollbarWidget sbw = (ScrollbarWidget) new;

    CreateGC(new);
    AllocTopShadowGC(new);
    AllocBotShadowGC(new);

    if (sbw->core.width == 0)
	sbw->core.width = (sbw->scrollbar.orientation == XtorientVertical)
	    ? sbw->scrollbar.thickness : sbw->scrollbar.length;

    if (sbw->core.height == 0)
	sbw->core.height = (sbw->scrollbar.orientation == XtorientHorizontal)
	    ? sbw->scrollbar.thickness : sbw->scrollbar.length;

    SetDimensions(sbw);
    sbw->scrollbar.scroll_mode = SMODE_NONE;
    sbw->scrollbar.timer_id = (XtIntervalId)0;
    sbw->scrollbar.topLoc = 0;
    sbw->scrollbar.shownLength = sbw->scrollbar.min_thumb;
}

    static void
Realize(w, valueMask, attributes)
    Widget w;
    Mask *valueMask;
    XSetWindowAttributes *attributes;
{
    /* The Simple widget actually stuffs the value in the valuemask. */
    (*vim_scrollbarWidgetClass->core_class.superclass->core_class.realize)
	(w, valueMask, attributes);
}

    static Boolean
SetValues(current, request, desired, args, num_args)
    Widget  current;	    /* what I am */
    Widget  request UNUSED; /* what he wants me to be */
    Widget  desired;	    /* what I will become */
    ArgList args UNUSED;
    Cardinal *num_args UNUSED;
{
    ScrollbarWidget	sbw = (ScrollbarWidget) current;
    ScrollbarWidget	dsbw = (ScrollbarWidget) desired;
    Boolean		redraw = FALSE;

/*
 * If these values are outside the acceptable range ignore them...
 */
    if (dsbw->scrollbar.top < 0.0 || dsbw->scrollbar.top > 1.0)
	dsbw->scrollbar.top = sbw->scrollbar.top;

    if (dsbw->scrollbar.shown < 0.0 || dsbw->scrollbar.shown > 1.0)
	dsbw->scrollbar.shown = sbw->scrollbar.shown;

/*
 * Change colors and stuff...
 */
    if (XtIsRealized(desired))
    {
	if (sbw->scrollbar.foreground != dsbw->scrollbar.foreground ||
		sbw->core.background_pixel != dsbw->core.background_pixel ||
		sbw->scrollbar.thumb != dsbw->scrollbar.thumb)
	{
	    XtReleaseGC(desired, sbw->scrollbar.gc);
	    CreateGC (desired);
	    redraw = TRUE;
	}
	if (sbw->scrollbar.top != dsbw->scrollbar.top ||
		sbw->scrollbar.shown != dsbw->scrollbar.shown)
	    redraw = TRUE;
    }
    return redraw;
}

    static void
Resize(w)
    Widget w;
{
    /* ForgetGravity has taken care of background, but thumb may
     * have to move as a result of the new size. */
    SetDimensions ((ScrollbarWidget) w);
    Redisplay(w, (XEvent*) NULL, (Region)NULL);
}


    static void
Redisplay(w, event, region)
    Widget w;
    XEvent *event;
    Region region;
{
    ScrollbarWidget sbw = (ScrollbarWidget) w;
    int x, y;
    unsigned int width, height;

    _Xaw3dDrawShadows(w, event, region, FALSE);

    if (sbw->scrollbar.orientation == XtorientHorizontal)
    {
	x = sbw->scrollbar.topLoc;
	y = 1;
	width = sbw->scrollbar.shownLength;
	height = sbw->core.height - 2;
    }
    else
    {
	x = 1;
	y = sbw->scrollbar.topLoc;
	width = sbw->core.width - 2;
	height = sbw->scrollbar.shownLength;
    }
    if (region == NULL ||
	    XRectInRegion (region, x, y, width, height) != RectangleOut)
    {
	/* Forces entire thumb to be painted. */
	sbw->scrollbar.topLoc = -(sbw->scrollbar.length + 1);
	PaintThumb (sbw);
    }
    /* we'd like to be region aware here!!!! */
    PaintArrows(sbw);
}


    static Boolean
CompareEvents(oldEvent, newEvent)
    XEvent *oldEvent, *newEvent;
{
#define Check(field) if (newEvent->field != oldEvent->field) return False;

    Check(xany.display);
    Check(xany.type);
    Check(xany.window);

    switch (newEvent->type)
    {
	case MotionNotify:
	    Check(xmotion.state);
	    break;
	case ButtonPress:
	case ButtonRelease:
	    Check(xbutton.state);
	    Check(xbutton.button);
	    break;
	case KeyPress:
	case KeyRelease:
	    Check(xkey.state);
	    Check(xkey.keycode);
	    break;
	case EnterNotify:
	case LeaveNotify:
	    Check(xcrossing.mode);
	    Check(xcrossing.detail);
	    Check(xcrossing.state);
	    break;
    }
#undef Check

    return True;
}

struct EventData
{
    XEvent *oldEvent;
    int count;
};

    static Bool
PeekNotifyEvent(dpy, event, args)
    Display *dpy;
    XEvent *event;
    char *args;
{
    struct EventData *eventData = (struct EventData*)args;

    return ((++eventData->count == QLength(dpy)) /* since PeekIf blocks */
	|| CompareEvents(event, eventData->oldEvent));
}


    static Boolean
LookAhead(w, event)
    Widget w;
    XEvent *event;
{
    XEvent newEvent;
    struct EventData eventData;

    if (QLength (XtDisplay (w)) == 0)
	return False;

    eventData.count = 0;
    eventData.oldEvent = event;

    XPeekIfEvent (XtDisplay (w), &newEvent, PeekNotifyEvent, (char*)&eventData);

    return CompareEvents (event, &newEvent);
}


    static void
ExtractPosition(event, x, y, state)
    XEvent	    *event;
    Position	    *x, *y;	/* RETURN */
    unsigned int    *state;	/* RETURN */
{
    switch (event->type)
    {
	case MotionNotify:
	    *x = event->xmotion.x;
	    *y = event->xmotion.y;
	    if (state != NULL)
		*state = event->xmotion.state;
	    break;
	case ButtonPress:
	case ButtonRelease:
	    *x = event->xbutton.x;
	    *y = event->xbutton.y;
	    if (state != NULL)
		*state = event->xbutton.state;
	    break;
	case KeyPress:
	case KeyRelease:
	    *x = event->xkey.x;
	    *y = event->xkey.y;
	    if (state != NULL)
		*state = event->xkey.state;
	    break;
	case EnterNotify:
	case LeaveNotify:
	    *x = event->xcrossing.x;
	    *y = event->xcrossing.y;
	    if (state != NULL)
		*state = event->xcrossing.state;
	    break;
	default:
	    *x = 0; *y = 0;
	    if (state != NULL)
		*state = 0;
    }
}

    static void
HandleThumb(w, event, params, num_params)
    Widget w;
    XEvent *event;
    String *params;
    Cardinal *num_params;
{
    Position x, y, loc;
    ScrollbarWidget sbw = (ScrollbarWidget) w;

    ExtractPosition(event, &x, &y, (unsigned int *)NULL);
    loc = PICKLENGTH(sbw, x, y);
    /* if the motion event puts the pointer in thumb, call Move and Notify */
    /* also call Move and Notify if we're already in continuous scroll mode */
    if (sbw->scrollbar.scroll_mode == SMODE_CONT ||
	    (loc >= sbw->scrollbar.topLoc &&
	     loc <= sbw->scrollbar.topLoc + (int)sbw->scrollbar.shownLength))
    {
	XtCallActionProc(w, "MoveThumb", event, params, *num_params);
	XtCallActionProc(w, "NotifyThumb", event, params, *num_params);
    }
}

    static void
RepeatNotify(client_data, idp)
    XtPointer client_data;
    XtIntervalId *idp UNUSED;
{
    ScrollbarWidget sbw = (ScrollbarWidget) client_data;
    int		    call_data;
    char	    mode = sbw->scrollbar.scroll_mode;
    unsigned long   rep;

    if (mode == SMODE_NONE || mode == SMODE_CONT)
    {
	sbw->scrollbar.timer_id = (XtIntervalId)0;
	return;
    }

    if (mode == SMODE_LINE_DOWN || mode == SMODE_LINE_UP)
    {
	call_data = ONE_LINE_DATA;
	rep = LINE_REPEAT;
    }
    else
    {
	call_data = ONE_PAGE_DATA;
	rep = PAGE_REPEAT;
    }

    if (mode == SMODE_PAGE_UP || mode == SMODE_LINE_UP)
	call_data = -call_data;

    XtCallCallbacks((Widget)sbw, XtNscrollProc, (XtPointer)(long_u)call_data);

    sbw->scrollbar.timer_id =
	XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)sbw),
		rep,
		RepeatNotify,
		client_data);
}

/*
 * Same as above, but for floating numbers.
 */
    static float
FloatInRange(num, small, big)
    float num, small, big;
{
    return (num < small) ? small : ((num > big) ? big : num);
}

    static void
ScrollOneLineUp(w, event, params, num_params)
    Widget	w;
    XEvent	*event;
    String	*params UNUSED;
    Cardinal	*num_params UNUSED;
{
    ScrollSome(w, event, -ONE_LINE_DATA);
}

    static void
ScrollOneLineDown(w, event, params, num_params)
    Widget	w;
    XEvent	*event;
    String	*params UNUSED;
    Cardinal	*num_params UNUSED;
{
    ScrollSome(w, event, ONE_LINE_DATA);
}

    static void
ScrollPageDown(w, event, params, num_params)
    Widget	w;
    XEvent	*event;
    String	*params UNUSED;
    Cardinal	*num_params UNUSED;
{
    ScrollSome(w, event, ONE_PAGE_DATA);
}

    static void
ScrollPageUp(w, event, params, num_params)
    Widget	w;
    XEvent	*event;
    String	*params UNUSED;
    Cardinal	*num_params UNUSED;
{
    ScrollSome(w, event, -ONE_PAGE_DATA);
}

    static void
ScrollSome(w, event, call_data)
    Widget	w;
    XEvent	*event;
    int		call_data;
{
    ScrollbarWidget	sbw = (ScrollbarWidget) w;

    if (sbw->scrollbar.scroll_mode == SMODE_CONT)   /* if scroll continuous */
	return;

    if (LookAhead(w, event))
	return;

    sbw->scrollbar.scroll_mode = SMODE_LINE_UP;
    XtCallCallbacks(w, XtNscrollProc, (XtPointer)(long_u)call_data);
}

    static void
NotifyScroll(w, event, params, num_params)
    Widget	w;
    XEvent	*event;
    String	*params UNUSED;
    Cardinal	*num_params UNUSED;
{
    ScrollbarWidget sbw = (ScrollbarWidget) w;
    Position	    x, y, loc;
    Dimension	    arrow_size;
    unsigned long   delay = 0;
    int		    call_data = 0;
    unsigned int    state;

    if (sbw->scrollbar.scroll_mode == SMODE_CONT)   /* if scroll continuous */
	return;

    if (LookAhead (w, event))
	return;

    ExtractPosition(event, &x, &y, &state);
    loc = PICKLENGTH(sbw, x, y);

    if ((int)sbw->scrollbar.thickness * 2 > (int)sbw->scrollbar.length)
	arrow_size = sbw->scrollbar.length / 2;
    else
	arrow_size = sbw->scrollbar.thickness;

    /*
     * handle CTRL modifier
     */
    if (state & ControlMask)
    {
	if (loc > sbw->scrollbar.topLoc + (Position)sbw->scrollbar.shownLength)
	    call_data = END_PAGE_DATA;
	else
	    call_data = -END_PAGE_DATA;
	sbw->scrollbar.scroll_mode = SMODE_NONE;
    }
    /*
     * handle first arrow zone
     */
    else if (loc < (Position)arrow_size)
    {
	call_data = -ONE_LINE_DATA;
	sbw->scrollbar.scroll_mode = SMODE_LINE_UP;
	delay = LINE_DELAY;
    }

    /*
     * handle last arrow zone
     */
    else if (loc > (Position)(sbw->scrollbar.length - arrow_size))
    {
	call_data = ONE_LINE_DATA;
	sbw->scrollbar.scroll_mode = SMODE_LINE_DOWN;
	delay = LINE_DELAY;
    }

    /*
     * handle zone "above" the thumb
     */
    else if (loc < sbw->scrollbar.topLoc)
    {
	call_data = -ONE_PAGE_DATA;
	sbw->scrollbar.scroll_mode = SMODE_PAGE_UP;
	delay = PAGE_DELAY;
    }

    /*
     * handle zone "below" the thumb
     */
    else if (loc > sbw->scrollbar.topLoc + (Position)sbw->scrollbar.shownLength)
    {
	call_data = ONE_PAGE_DATA;
	sbw->scrollbar.scroll_mode = SMODE_PAGE_DOWN;
	delay = PAGE_DELAY;
    }

    if (call_data)
	XtCallCallbacks(w, XtNscrollProc, (XtPointer)(long_u)call_data);

    /* establish autoscroll */
    if (delay)
	sbw->scrollbar.timer_id =
	    XtAppAddTimeOut(XtWidgetToApplicationContext(w),
					   delay, RepeatNotify, (XtPointer)w);
}

    static void
EndScroll(w, event, params, num_params)
    Widget w;
    XEvent *event UNUSED;
    String *params UNUSED;
    Cardinal *num_params UNUSED;
{
    ScrollbarWidget sbw = (ScrollbarWidget) w;

    sbw->scrollbar.scroll_mode = SMODE_NONE;
    /* no need to remove any autoscroll timeout; it will no-op */
    /* because the scroll_mode is SMODE_NONE */
    /* but be sure to remove timeout in destroy proc */
}

    static float
FractionLoc(sbw, x, y)
    ScrollbarWidget sbw;
    int x, y;
{
    int	    margin;
    float   height, width;

    margin = MARGIN(sbw);
    x -= margin;
    y -= margin;
    height = (float)sbw->core.height - 2 * margin;
    width = (float)sbw->core.width - 2 * margin;
    return PICKLENGTH(sbw, x / width, y / height);
}

    static void
MoveThumb(w, event, params, num_params)
    Widget	w;
    XEvent	*event;
    String	*params UNUSED;
    Cardinal	*num_params UNUSED;
{
    ScrollbarWidget	sbw = (ScrollbarWidget)w;
    Position		x, y;
    float		top;
    char		old_mode = sbw->scrollbar.scroll_mode;

    sbw->scrollbar.scroll_mode = SMODE_CONT; /* indicate continuous scroll */

    if (LookAhead(w, event))
	return;

    if (!event->xmotion.same_screen)
	return;

    ExtractPosition(event, &x, &y, (unsigned int *)NULL);

    top = FractionLoc(sbw, x, y);

    if (old_mode != SMODE_CONT)		    /* start dragging: set offset */
    {
	if (event->xbutton.button == Button2)
	    sbw->scrollbar.scroll_off = sbw->scrollbar.shown / 2.;
	else
	    sbw->scrollbar.scroll_off = top - sbw->scrollbar.top;
    }

    top -= sbw->scrollbar.scroll_off;
    if (sbw->scrollbar.limit_thumb)
	top = FloatInRange(top, 0.0,
			sbw->scrollbar.max - sbw->scrollbar.shown + 0.000001);
    else
	top = FloatInRange(top, 0.0, sbw->scrollbar.max);

    sbw->scrollbar.top = top;
    PaintThumb(sbw);
    XFlush(XtDisplay(w));   /* re-draw it before Notifying */
}


    static void
NotifyThumb(w, event, params, num_params)
    Widget	w;
    XEvent	*event;
    String	*params UNUSED;
    Cardinal	*num_params UNUSED;
{
    ScrollbarWidget sbw = (ScrollbarWidget)w;
    /* Use a union to avoid a warning for the weird conversion from float to
     * XtPointer.  Comes from Xaw/Scrollbar.c. */
    union {
	XtPointer xtp;
	float xtf;
    } xtpf;

    if (LookAhead(w, event))
	return;

    /* thumbProc is not pretty, but is necessary for backwards
       compatibility on those architectures for which it work{s,ed};
       the intent is to pass a (truncated) float by value. */
    xtpf.xtf = sbw->scrollbar.top;
    XtCallCallbacks(w, XtNthumbProc, xtpf.xtp);
    XtCallCallbacks(w, XtNjumpProc, (XtPointer)&sbw->scrollbar.top);
}

    static void
AllocTopShadowGC(w)
    Widget w;
{
    ScrollbarWidget sbw = (ScrollbarWidget) w;
    XtGCMask	    valuemask;
    XGCValues	    myXGCV;

    valuemask = GCForeground;
    myXGCV.foreground = sbw->scrollbar.top_shadow_pixel;
    sbw->scrollbar.top_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
}

    static void
AllocBotShadowGC(w)
    Widget w;
{
    ScrollbarWidget sbw = (ScrollbarWidget) w;
    XtGCMask	    valuemask;
    XGCValues	    myXGCV;

    valuemask = GCForeground;
    myXGCV.foreground = sbw->scrollbar.bot_shadow_pixel;
    sbw->scrollbar.bot_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
}

    static void
_Xaw3dDrawShadows(gw, event, region, out)
    Widget  gw;
    XEvent  *event UNUSED;
    Region  region;
    int	    out;
{
    XPoint  pt[6];
    ScrollbarWidget sbw = (ScrollbarWidget) gw;
    Dimension	s = sbw->scrollbar.shadow_width;
    /*
     * draw the shadows using the core part width and height,
     * and the scrollbar part shadow_width.
     *
     *	no point to do anything if the shadow_width is 0 or the
     *	widget has not been realized.
     */
    if (s > 0 && XtIsRealized(gw))
    {
	Dimension   h = sbw->core.height;
	Dimension   w = sbw->core.width;
	Dimension   wms = w - s;
	Dimension   hms = h - s;
	Display	    *dpy = XtDisplay (gw);
	Window	    win = XtWindow (gw);
	GC	top, bot;

	if (out)
	{
	    top = sbw->scrollbar.top_shadow_GC;
	    bot = sbw->scrollbar.bot_shadow_GC;
	}
	else
	{
	    top = sbw->scrollbar.bot_shadow_GC;
	    bot = sbw->scrollbar.top_shadow_GC;
	}

	/* top-left shadow */
	if ((region == NULL) ||
		(XRectInRegion (region, 0, 0, w, s) != RectangleOut) ||
		(XRectInRegion (region, 0, 0, s, h) != RectangleOut))
	{
	    pt[0].x = 0;    pt[0].y = h;
	    pt[1].x =	    pt[1].y = 0;
	    pt[2].x = w;    pt[2].y = 0;
	    pt[3].x = wms;  pt[3].y = s;
	    pt[4].x =	    pt[4].y = s;
	    pt[5].x = s;    pt[5].y = hms;
	    XFillPolygon (dpy, win, top, pt, 6, Complex, CoordModeOrigin);
	}

	/* bottom-right shadow */
	if ((region == NULL) ||
		(XRectInRegion (region, 0, hms, w, s) != RectangleOut) ||
		(XRectInRegion (region, wms, 0, s, h) != RectangleOut))
	{
	    pt[0].x = 0;    pt[0].y = h;
	    pt[1].x = w;    pt[1].y = h;
	    pt[2].x = w;    pt[2].y = 0;
	    pt[3].x = wms;  pt[3].y = s;
	    pt[4].x = wms;  pt[4].y = hms;
	    pt[5].x = s;    pt[5].y = hms;
	    XFillPolygon (dpy, win, bot, pt, 6, Complex, CoordModeOrigin);
	}
    }
}


/*
 * Set the scroll bar to the given location.
 */
    void
vim_XawScrollbarSetThumb(w, top, shown, max)
    Widget w;
    double top, shown, max;
{
    ScrollbarWidget sbw = (ScrollbarWidget) w;

    if (sbw->scrollbar.scroll_mode == SMODE_CONT) /* if still thumbing */
	return;

    sbw->scrollbar.max = (max > 1.0) ? 1.0 :
		(max >= 0.0) ? max : sbw->scrollbar.max;

    sbw->scrollbar.top = (top > sbw->scrollbar.max) ? sbw->scrollbar.max :
		(top >= 0.0) ? top : sbw->scrollbar.top;

    sbw->scrollbar.shown = (shown > 1.0) ? 1.0 :
		(shown >= 0.0) ? shown : sbw->scrollbar.shown;

    PaintThumb(sbw);
}
