[BACK]Return to gui_at_sb.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/gui_at_sb.c, Revision 1.1.1.1

1.1       downsj      1: /* $OpenBSD$   */
                      2: /* vi:set ts=4 sw=4: */
                      3: /* MODIFIED ATHENA SCROLLBAR (USING ARROWHEADS AT ENDS OF TRAVEL) */
                      4: /* Modifications Copyright 1992 by Mitch Trachtenberg             */
                      5: /* Rights, permissions, and disclaimer of warranty are as in the  */
                      6: /* DEC and MIT notice below.                                      */
                      7: /* $XConsortium: Scrollbar.c,v 1.72 94/04/17 20:12:40 kaleb Exp $ */
                      8:
                      9: /*
                     10:  * Modified for Vim by Bill Foster and Bram Moolenaar
                     11:  */
                     12:
                     13: /***********************************************************
                     14:
                     15: Copyright (c) 1987, 1988, 1994  X Consortium
                     16:
                     17: Permission is hereby granted, free of charge, to any person obtaining a copy
                     18: of this software and associated documentation files (the "Software"), to deal
                     19: in the Software without restriction, including without limitation the rights
                     20: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     21: copies of the Software, and to permit persons to whom the Software is
                     22: furnished to do so, subject to the following conditions:
                     23:
                     24: The above copyright notice and this permission notice shall be included in
                     25: all copies or substantial portions of the Software.
                     26:
                     27: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     28: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     29: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
                     30: X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
                     31: AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
                     32: CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                     33:
                     34: Except as contained in this notice, the name of the X Consortium shall not be
                     35: used in advertising or otherwise to promote the sale, use or other dealings
                     36: in this Software without prior written authorization from the X Consortium.
                     37:
                     38:
                     39: Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
                     40:
                     41:                         All Rights Reserved
                     42:
                     43: Permission to use, copy, modify, and distribute this software and its
                     44: documentation for any purpose and without fee is hereby granted,
                     45: provided that the above copyright notice appear in all copies and that
                     46: both that copyright notice and this permission notice appear in
                     47: supporting documentation, and that the name of Digital not be
                     48: used in advertising or publicity pertaining to distribution of the
                     49: software without specific, written prior permission.
                     50:
                     51: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     52: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     53: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     54: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     55: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     56: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     57: SOFTWARE.
                     58:
                     59: ******************************************************************/
                     60:
                     61: /* ScrollBar.c */
                     62: /* created by weissman, Mon Jul  7 13:20:03 1986 */
                     63: /* converted by swick, Thu Aug 27 1987 */
                     64:
                     65: #include <X11/IntrinsicP.h>
                     66: #include <X11/StringDefs.h>
                     67:
                     68: #include <X11/Xaw/XawInit.h>
                     69: #include "vim.h"
                     70: #include "gui_at_sb.h"
                     71:
                     72: #include <X11/Xmu/Drawing.h>
                     73:
                     74: /* Private definitions. */
                     75:
                     76: static char defaultTranslations[] =
                     77:     "<Btn1Down>:   NotifyScroll()\n\
                     78:      <Btn2Down>:   MoveThumb() NotifyThumb() \n\
                     79:      <Btn3Down>:   NotifyScroll()\n\
                     80:      <Btn1Motion>: HandleThumb() \n\
                     81:      <Btn3Motion>: HandleThumb() \n\
                     82:      <Btn2Motion>: MoveThumb() NotifyThumb() \n\
                     83:      <BtnUp>:      EndScroll()";
                     84:
                     85: static float floatZero = 0.0;
                     86:
                     87: #define Offset(field) XtOffsetOf(ScrollbarRec, field)
                     88:
                     89: static XtResource resources[] =
                     90: {
                     91: /*  {XtNscrollCursor, XtCCursor, XtRCursor, sizeof(Cursor),
                     92:        Offset(scrollbar.cursor), XtRString, "crosshair"},*/
                     93:   {XtNlength, XtCLength, XtRDimension, sizeof(Dimension),
                     94:        Offset(scrollbar.length), XtRImmediate, (XtPointer) 1},
                     95:   {XtNthickness, XtCThickness, XtRDimension, sizeof(Dimension),
                     96:        Offset(scrollbar.thickness), XtRImmediate, (XtPointer) 14},
                     97:   {XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation),
                     98:       Offset(scrollbar.orientation), XtRImmediate, (XtPointer) XtorientVertical},
                     99:   {XtNscrollProc, XtCCallback, XtRCallback, sizeof(XtPointer),
                    100:        Offset(scrollbar.scrollProc), XtRCallback, NULL},
                    101:   {XtNthumbProc, XtCCallback, XtRCallback, sizeof(XtPointer),
                    102:        Offset(scrollbar.thumbProc), XtRCallback, NULL},
                    103:   {XtNjumpProc, XtCCallback, XtRCallback, sizeof(XtPointer),
                    104:        Offset(scrollbar.jumpProc), XtRCallback, NULL},
                    105:   {XtNthumb, XtCThumb, XtRBitmap, sizeof(Pixmap),
                    106:        Offset(scrollbar.thumb), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
                    107:   {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
                    108:        Offset(scrollbar.foreground), XtRString, XtDefaultForeground},
                    109:   {XtNshown, XtCShown, XtRFloat, sizeof(float),
                    110:        Offset(scrollbar.shown), XtRFloat, (XtPointer)&floatZero},
                    111:   {XtNtopOfThumb, XtCTopOfThumb, XtRFloat, sizeof(float),
                    112:        Offset(scrollbar.top), XtRFloat, (XtPointer)&floatZero},
                    113:   {XtNmaxOfThumb, XtCMaxOfThumb, XtRFloat, sizeof(float),
                    114:        Offset(scrollbar.max), XtRFloat, (XtPointer)&floatZero},
                    115:   {XtNminimumThumb, XtCMinimumThumb, XtRDimension, sizeof(Dimension),
                    116:        Offset(scrollbar.min_thumb), XtRImmediate, (XtPointer) 7},
                    117:   {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
                    118:       Offset(scrollbar.shadow_width), XtRImmediate, (XtPointer) 1},
                    119:   {XtNtopShadowPixel, XtCTopShadowPixel, XtRPixel, sizeof(Pixel),
                    120:       Offset(scrollbar.top_shadow_pixel), XtRString, XtDefaultBackground},
                    121:   {XtNbottomShadowPixel, XtCBottomShadowPixel, XtRPixel, sizeof(Pixel),
                    122:       Offset(scrollbar.bot_shadow_pixel), XtRString, XtDefaultForeground}
                    123: };
                    124: #undef Offset
                    125:
                    126: static void ClassInitialize __ARGS((void));
                    127: static void Initialize __ARGS((Widget, Widget, ArgList, Cardinal *));
                    128: static void Destroy __ARGS((Widget));
                    129: static void Realize __ARGS((Widget, Mask *, XSetWindowAttributes *));
                    130: static void Resize __ARGS((Widget));
                    131: static void Redisplay __ARGS((Widget, XEvent *, Region));
                    132: static Boolean SetValues __ARGS((Widget, Widget, Widget, ArgList, Cardinal *));
                    133:
                    134: static void HandleThumb __ARGS((Widget, XEvent *, String *, Cardinal *));
                    135: static void MoveThumb __ARGS((Widget, XEvent *, String *, Cardinal *));
                    136: static void NotifyThumb __ARGS((Widget, XEvent *, String *, Cardinal *));
                    137: static void NotifyScroll __ARGS((Widget, XEvent *, String *, Cardinal *));
                    138: static void EndScroll __ARGS((Widget, XEvent *, String *, Cardinal *));
                    139: static void _Xaw3dDrawShadows __ARGS((Widget, XEvent *, Region, Boolean));
                    140: static void AllocTopShadowGC __ARGS((Widget));
                    141: static void AllocBotShadowGC __ARGS((Widget));
                    142:
                    143: static XtActionsRec actions[] =
                    144: {
                    145:     {"HandleThumb",        HandleThumb},
                    146:     {"MoveThumb",      MoveThumb},
                    147:     {"NotifyThumb",        NotifyThumb},
                    148:     {"NotifyScroll",   NotifyScroll},
                    149:     {"EndScroll",      EndScroll}
                    150: };
                    151:
                    152:
                    153: ScrollbarClassRec vim_scrollbarClassRec =
                    154: {
                    155:   { /* core fields */
                    156:     /* superclass       */ (WidgetClass) &simpleClassRec,
                    157:     /* class_name       */ "Scrollbar",
                    158:     /* size             */ sizeof(ScrollbarRec),
                    159:     /* class_initialize    */  ClassInitialize,
                    160:     /* class_part_init  */ NULL,
                    161:     /* class_inited        */  FALSE,
                    162:     /* initialize       */ Initialize,
                    163:     /* initialize_hook  */ NULL,
                    164:     /* realize          */ Realize,
                    165:     /* actions          */ actions,
                    166:     /* num_actions     */  XtNumber(actions),
                    167:     /* resources        */ resources,
                    168:     /* num_resources    */ XtNumber(resources),
                    169:     /* xrm_class        */ NULLQUARK,
                    170:     /* compress_motion */  TRUE,
                    171:     /* compress_exposure*/ TRUE,
                    172:     /* compress_enterleave*/   TRUE,
                    173:     /* visible_interest */ FALSE,
                    174:     /* destroy          */ Destroy,
                    175:     /* resize           */ Resize,
                    176:     /* expose           */ Redisplay,
                    177:     /* set_values       */ SetValues,
                    178:     /* set_values_hook  */ NULL,
                    179:     /* set_values_almost */    XtInheritSetValuesAlmost,
                    180:     /* get_values_hook  */ NULL,
                    181:     /* accept_focus     */ NULL,
                    182:     /* version          */ XtVersion,
                    183:     /* callback_private */ NULL,
                    184:     /* tm_table         */ defaultTranslations,
                    185:     /* query_geometry  */  XtInheritQueryGeometry,
                    186:     /* display_accelerator*/   XtInheritDisplayAccelerator,
                    187:     /* extension        */ NULL
                    188:   },
                    189:   { /* simple fields */
                    190:     /* change_sensitive    */  XtInheritChangeSensitive
                    191:   },
                    192:   { /* scrollbar fields */
                    193:     /* ignore      */  0
                    194:   }
                    195:
                    196: };
                    197:
                    198: WidgetClass vim_scrollbarWidgetClass = (WidgetClass)&vim_scrollbarClassRec;
                    199:
                    200: #define NoButton -1
                    201: #define PICKLENGTH(widget, x, y) \
                    202:     ((widget->scrollbar.orientation == XtorientHorizontal) ? (x) : (y))
                    203: #define MIN(x,y)   ((x) < (y) ? (x) : (y))
                    204: #define MAX(x,y)   ((x) > (y) ? (x) : (y))
                    205:
                    206: #define LINE_DELAY     300
                    207: #define PAGE_DELAY     300
                    208: #define LINE_REPEAT         50
                    209: #define PAGE_REPEAT        250
                    210:
                    211: static void ClassInitialize()
                    212: {
                    213:     XawInitializeWidgetSet();
                    214:     XtAddConverter( XtRString, XtROrientation, XmuCvtStringToOrientation,
                    215:            (XtConvertArgList)NULL, (Cardinal)0 );
                    216: }
                    217:
                    218: #define MARGIN(sbw) (sbw)->scrollbar.thickness + (sbw)->scrollbar.shadow_width
                    219:
                    220: static void FillArea(sbw, top, bottom, fill, draw_shadow)
                    221:     ScrollbarWidget        sbw;
                    222:     Position           top, bottom;
                    223:     int                    fill;
                    224:     int                    draw_shadow;
                    225: {
                    226:     int tlen = bottom - top;   /* length of thumb in pixels */
                    227:     int sw, margin, floor;
                    228:     int lx, ly, lw, lh;
                    229:
                    230:     if (bottom <= 0 || bottom <= top)
                    231:        return;
                    232:     if ((sw = sbw->scrollbar.shadow_width) < 0)
                    233:        sw = 0;
                    234:     margin = MARGIN (sbw);
                    235:     floor = sbw->scrollbar.length - margin + 2;
                    236:
                    237:     if (sbw->scrollbar.orientation == XtorientHorizontal)
                    238:    {
                    239:        lx = ((top < margin) ? margin : top);
                    240:        ly = sw;
                    241:        lw = (((top + tlen) > floor) ? floor - top : tlen);
                    242:        lh = sbw->core.height - 2 * sw;
                    243:    }
                    244:    else
                    245:    {
                    246:        lx = sw;
                    247:        ly = ((top < margin) ? margin : top);
                    248:        lw = sbw->core.width - 2 * sw;
                    249:        lh = (((top + tlen) > floor) ? floor - top : tlen);
                    250:    }
                    251:     if (lh <= 0 || lw <= 0)
                    252:        return;
                    253:
                    254:     if (draw_shadow)
                    255:    {
                    256:        if (!sbw->scrollbar.orientation == XtorientHorizontal)
                    257:        {
                    258:            /* Top border */
                    259:            XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    260:                    sbw->scrollbar.top_shadow_GC,
                    261:                    lx, ly, lx + lw - 1, ly);
                    262:
                    263:            /* Bottom border */
                    264:            XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    265:                    sbw->scrollbar.bot_shadow_GC,
                    266:                    lx, ly + lh - 1, lx + lw - 1, ly + lh - 1);
                    267:        }
                    268:        else
                    269:        {
                    270:            /* Left border */
                    271:            XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    272:                    sbw->scrollbar.top_shadow_GC,
                    273:                    lx, ly, lx, ly + lh - 1);
                    274:
                    275:            /* Right border */
                    276:            XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    277:                    sbw->scrollbar.bot_shadow_GC,
                    278:                    lx + lw - 1, ly, lx + lw - 1, ly + lh - 1);
                    279:        }
                    280:        return;
                    281:    }
                    282:
                    283:     if (fill)
                    284:     {
                    285:        XFillRectangle(XtDisplay((Widget) sbw), XtWindow((Widget) sbw),
                    286:                sbw->scrollbar.gc,
                    287:                lx, ly, (unsigned int) lw, (unsigned int) lh);
                    288:
                    289:        if (!sbw->scrollbar.orientation == XtorientHorizontal)
                    290:        {
                    291:            /* Left border */
                    292:            XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    293:                    sbw->scrollbar.top_shadow_GC,
                    294:                    lx, ly, lx, ly + lh - 1);
                    295:
                    296:            /* Right border */
                    297:            XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    298:                    sbw->scrollbar.bot_shadow_GC,
                    299:                    lx + lw - 1, ly, lx + lw - 1, ly + lh - 1);
                    300:        }
                    301:        else
                    302:        {
                    303:            /* Top border */
                    304:            XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    305:                    sbw->scrollbar.top_shadow_GC,
                    306:                    lx, ly, lx + lw - 1, ly);
                    307:
                    308:            /* Bottom border */
                    309:            XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    310:                    sbw->scrollbar.bot_shadow_GC,
                    311:                    lx, ly + lh - 1, lx + lw - 1, ly + lh - 1);
                    312:        }
                    313:    }
                    314:     else
                    315:    {
                    316:        XClearArea (XtDisplay((Widget) sbw), XtWindow((Widget) sbw),
                    317:                lx, ly, (unsigned int) lw, (unsigned int) lh,
                    318:                FALSE);
                    319:    }
                    320: }
                    321:
                    322: /* Paint the thumb in the area specified by sbw->top and
                    323:    sbw->shown.  The old area is erased.  The painting and
                    324:    erasing is done cleverly so that no flickering will occur.
                    325:  */
                    326:
                    327: static void PaintThumb(sbw)
                    328:     ScrollbarWidget sbw;
                    329: {
                    330:     Position       oldtop, oldbot, newtop, newbot;
                    331:     Dimension      margin, tzl;
                    332:
                    333:     margin = MARGIN (sbw);
                    334:     tzl = sbw->scrollbar.length - 2 * margin;
                    335:     newtop = margin + (int)(tzl * sbw->scrollbar.top);
                    336:     newbot = newtop + (int)(tzl * sbw->scrollbar.shown) + 1;
                    337:     if (newbot < newtop + (int)sbw->scrollbar.min_thumb)
                    338:        newbot = newtop + sbw->scrollbar.min_thumb;
                    339:
                    340:     oldtop = sbw->scrollbar.topLoc;
                    341:     oldbot = oldtop + sbw->scrollbar.shownLength;
                    342:     sbw->scrollbar.topLoc = newtop;
                    343:     sbw->scrollbar.shownLength = newbot - newtop;
                    344:    if (XtIsRealized ((Widget) sbw))
                    345:    {
                    346:        if (newtop < oldtop)
                    347:            FillArea(sbw, newtop, MIN(newbot,   oldtop+1),1,0);
                    348:        if (newtop > oldtop)
                    349:            FillArea(sbw, oldtop, MIN(newtop,   oldbot  ),0,0);
                    350:        if (newbot < oldbot)
                    351:            FillArea(sbw, MAX(newbot, oldtop),  oldbot,   0,0);
                    352:        if (newbot > oldbot)
                    353:            FillArea(sbw, MAX(newtop, oldbot-1), newbot,  1,0);
                    354:
                    355:        /* Only draw the missing shadows */
                    356:        FillArea(sbw, newtop, newbot, 0, 1);
                    357:    }
                    358: }
                    359:
                    360: static void PaintArrows(sbw)
                    361:     ScrollbarWidget sbw;
                    362: {
                    363:     XPoint     point[6];
                    364:     Dimension  thickness = sbw->scrollbar.thickness - 1;
                    365:    Dimension   size;
                    366:    Dimension   off;
                    367:
                    368:     if (XtIsRealized((Widget) sbw))
                    369:    {
                    370:        if (thickness * 2 > sbw->scrollbar.length)
                    371:        {
                    372:            size = sbw->scrollbar.length / 2;
                    373:            off = (thickness - size) / 2;
                    374:        }
                    375:        else
                    376:        {
                    377:            size = thickness;
                    378:            off = 0;
                    379:        }
                    380:        point[0].x = off + sbw->scrollbar.shadow_width;
                    381:        point[0].y = size;
                    382:        point[1].x = thickness - off - sbw->scrollbar.shadow_width;
                    383:        point[1].y = size;
                    384:        point[2].x = thickness / 2;
                    385:        point[2].y = sbw->scrollbar.shadow_width;
                    386:
                    387:        point[3].x = off + sbw->scrollbar.shadow_width;
                    388:        point[3].y = sbw->scrollbar.length - size;
                    389:        point[4].x = thickness - off - sbw->scrollbar.shadow_width;
                    390:        point[4].y = sbw->scrollbar.length - size;
                    391:        point[5].x = thickness / 2;
                    392:        point[5].y = sbw->scrollbar.length - sbw->scrollbar.shadow_width - 1;
                    393:
                    394:        /* horizontal arrows require that x and y coordinates be swapped */
                    395:        if (sbw->scrollbar.orientation == XtorientHorizontal)
                    396:        {
                    397:            int n;
                    398:            int swap;
                    399:            for (n = 0; n < 6; n++)
                    400:            {
                    401:                swap = point[n].x;
                    402:                point[n].x = point[n].y;
                    403:                point[n].y = swap;
                    404:            }
                    405:        }
                    406:        /* draw the up/left arrow */
                    407:        XFillPolygon (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    408:                sbw->scrollbar.gc,
                    409:                point, 3,
                    410:                Convex, CoordModeOrigin);
                    411:        XDrawLines (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    412:                sbw->scrollbar.bot_shadow_GC,
                    413:                point, 3,
                    414:                CoordModeOrigin);
                    415:        XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    416:                sbw->scrollbar.top_shadow_GC,
                    417:                point[0].x, point[0].y,
                    418:                point[2].x, point[2].y);
                    419:        /* draw the down/right arrow */
                    420:        XFillPolygon (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    421:                sbw->scrollbar.gc,
                    422:                point+3, 3,
                    423:                Convex, CoordModeOrigin);
                    424:        XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    425:                sbw->scrollbar.top_shadow_GC,
                    426:                point[3].x, point[3].y,
                    427:                point[4].x, point[4].y);
                    428:        XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    429:                sbw->scrollbar.top_shadow_GC,
                    430:                point[3].x, point[3].y,
                    431:                point[5].x, point[5].y);
                    432:        XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
                    433:                sbw->scrollbar.bot_shadow_GC,
                    434:                point[4].x, point[4].y,
                    435:                point[5].x, point[5].y);
                    436:    }
                    437: }
                    438:
                    439: /* Function Name: Destroy
                    440:  * Description: Called as the scrollbar is going away...
                    441:  * Arguments: w - the scrollbar.
                    442:  * Returns: nonw
                    443:  */
                    444: static void Destroy(w)
                    445:     Widget w;
                    446: {
                    447:    ScrollbarWidget sbw = (ScrollbarWidget) w;
                    448:    if (sbw->scrollbar.timer_id != (XtIntervalId) 0)
                    449:        XtRemoveTimeOut (sbw->scrollbar.timer_id);
                    450:    XtReleaseGC(w, sbw->scrollbar.gc);
                    451:    XtReleaseGC(w, sbw->scrollbar.top_shadow_GC);
                    452:    XtReleaseGC(w, sbw->scrollbar.bot_shadow_GC);
                    453: }
                    454:
                    455: /* Function Name: CreateGC
                    456:  * Description: Creates the GC.
                    457:  * Arguments: w - the scrollbar widget.
                    458:  * Returns: none.
                    459:  */
                    460:
                    461: static void CreateGC (w)
                    462:     Widget w;
                    463: {
                    464:     ScrollbarWidget        sbw = (ScrollbarWidget) w;
                    465:     XGCValues          gcValues;
                    466:     XtGCMask           mask;
                    467:     unsigned int       depth = 1;
                    468:
                    469:     if (sbw->scrollbar.thumb == XtUnspecifiedPixmap)
                    470:    {
                    471:         sbw->scrollbar.thumb = XmuCreateStippledPixmap (XtScreen(w),
                    472:                    (Pixel) 1, (Pixel) 0, depth);
                    473:     }
                    474:    else if (sbw->scrollbar.thumb != None)
                    475:    {
                    476:        Window root;
                    477:        int x, y;
                    478:        unsigned int width, height, bw;
                    479:
                    480:        if (XGetGeometry (XtDisplay(w), sbw->scrollbar.thumb, &root, &x, &y,
                    481:                &width, &height, &bw, &depth) == 0)
                    482:        {
                    483:            XtAppError (XtWidgetToApplicationContext (w),
                    484:                 "Scrollbar Widget: Could not get geometry of thumb pixmap.");
                    485:        }
                    486:     }
                    487:
                    488:     gcValues.foreground = sbw->scrollbar.foreground;
                    489:     gcValues.background = sbw->core.background_pixel;
                    490:     mask = GCForeground | GCBackground;
                    491:
                    492:     if (sbw->scrollbar.thumb != None)
                    493:    {
                    494:        gcValues.fill_style = FillSolid;
                    495:        mask |= GCFillStyle;
                    496: #if 0
                    497:    if (depth == 1)
                    498:    {
                    499:        gcValues.fill_style = FillOpaqueStippled;
                    500:        gcValues.stipple = sbw->scrollbar.thumb;
                    501:        mask |= GCFillStyle | GCStipple;
                    502:    }
                    503:    else
                    504:    {
                    505:        gcValues.fill_style = FillTiled;
                    506:        gcValues.tile = sbw->scrollbar.thumb;
                    507:        mask |= GCFillStyle | GCTile;
                    508:    }
                    509: #endif
                    510:     }
                    511:     /* the creation should be non-caching, because */
                    512:     /* we now set and clear clip masks on the gc returned */
                    513:     sbw->scrollbar.gc = XtGetGC (w, mask, &gcValues);
                    514: }
                    515:
                    516: static void SetDimensions(sbw)
                    517:     ScrollbarWidget sbw;
                    518: {
                    519:     if (sbw->scrollbar.orientation == XtorientVertical)
                    520:    {
                    521:        sbw->scrollbar.length = sbw->core.height;
                    522:        sbw->scrollbar.thickness = sbw->core.width;
                    523:     }
                    524:    else
                    525:    {
                    526:        sbw->scrollbar.length = sbw->core.width;
                    527:        sbw->scrollbar.thickness = sbw->core.height;
                    528:     }
                    529: }
                    530:
                    531: /* ARGSUSED */
                    532: static void Initialize(request, new, args, num_args)
                    533:     Widget     request;        /* what the client asked for */
                    534:     Widget     new;            /* what we're going to give him */
                    535:     ArgList        args;
                    536:     Cardinal   *num_args;
                    537: {
                    538:     ScrollbarWidget sbw = (ScrollbarWidget) new;
                    539:
                    540:     CreateGC(new);
                    541:    AllocTopShadowGC(new);
                    542:    AllocBotShadowGC(new);
                    543:
                    544:    if (sbw->core.width == 0)
                    545:        sbw->core.width = (sbw->scrollbar.orientation == XtorientVertical)
                    546:            ? sbw->scrollbar.thickness : sbw->scrollbar.length;
                    547:
                    548:    if (sbw->core.height == 0)
                    549:        sbw->core.height = (sbw->scrollbar.orientation == XtorientHorizontal)
                    550:            ? sbw->scrollbar.thickness : sbw->scrollbar.length;
                    551:
                    552:     SetDimensions(sbw);
                    553:     sbw->scrollbar.scroll_mode = SMODE_NONE;
                    554:     sbw->scrollbar.timer_id = (XtIntervalId)0;
                    555:     sbw->scrollbar.topLoc = 0;
                    556:     sbw->scrollbar.shownLength = sbw->scrollbar.min_thumb;
                    557: }
                    558:
                    559: static void Realize(w, valueMask, attributes)
                    560:     Widget w;
                    561:     Mask *valueMask;
                    562:     XSetWindowAttributes *attributes;
                    563: {
                    564: #if 0
                    565:    ScrollbarWidget sbw = (ScrollbarWidget) w;
                    566:
                    567:    if (sbw->simple.cursor_name == NULL)
                    568:        XtVaSetValues(w, XtNcursorName, "crosshair", NULL);
                    569:
                    570:    /* dont set the cursor of the window to anything */
                    571:    *valueMask &= ~CWCursor;
                    572: #endif
                    573:
                    574:    /*
                    575:     * The Simple widget actually stuffs the value in the valuemask.
                    576:     */
                    577:    (*vim_scrollbarWidgetClass->core_class.superclass->core_class.realize)
                    578:        (w, valueMask, attributes);
                    579: }
                    580:
                    581: /* ARGSUSED */
                    582: static Boolean SetValues(current, request, desired, args, num_args)
                    583:     Widget  current,       /* what I am */
                    584:            request,        /* what he wants me to be */
                    585:            desired;        /* what I will become */
                    586:     ArgList args;
                    587:     Cardinal *num_args;
                    588: {
                    589:     ScrollbarWidget        sbw = (ScrollbarWidget) current;
                    590:     ScrollbarWidget        dsbw = (ScrollbarWidget) desired;
                    591:     Boolean                redraw = FALSE;
                    592:
                    593: /*
                    594:  * If these values are outside the acceptable range ignore them...
                    595:  */
                    596:
                    597:     if (dsbw->scrollbar.top < 0.0 || dsbw->scrollbar.top > 1.0)
                    598:         dsbw->scrollbar.top = sbw->scrollbar.top;
                    599:
                    600:     if (dsbw->scrollbar.shown < 0.0 || dsbw->scrollbar.shown > 1.0)
                    601:         dsbw->scrollbar.shown = sbw->scrollbar.shown;
                    602:
                    603: /*
                    604:  * Change colors and stuff...
                    605:  */
                    606:    if (XtIsRealized(desired))
                    607:    {
                    608:        if (sbw->scrollbar.foreground != dsbw->scrollbar.foreground ||
                    609:                sbw->core.background_pixel != dsbw->core.background_pixel ||
                    610:                sbw->scrollbar.thumb != dsbw->scrollbar.thumb)
                    611:        {
                    612:            XtReleaseGC(desired, sbw->scrollbar.gc);
                    613:            CreateGC (desired);
                    614:            redraw = TRUE;
                    615:        }
                    616:        if (sbw->scrollbar.top != dsbw->scrollbar.top ||
                    617:                sbw->scrollbar.shown != dsbw->scrollbar.shown)
                    618:            redraw = TRUE;
                    619:    }
                    620:    return redraw;
                    621: }
                    622:
                    623: static void Resize (w)
                    624:     Widget w;
                    625: {
                    626:     /* ForgetGravity has taken care of background, but thumb may
                    627:      * have to move as a result of the new size. */
                    628:    SetDimensions ((ScrollbarWidget) w);
                    629:    Redisplay (w, (XEvent*) NULL, (Region)NULL);
                    630: }
                    631:
                    632:
                    633: /* ARGSUSED */
                    634: static void Redisplay(w, event, region)
                    635:     Widget w;
                    636:     XEvent *event;
                    637:     Region region;
                    638: {
                    639:     ScrollbarWidget sbw = (ScrollbarWidget) w;
                    640:     int x, y;
                    641:     unsigned int width, height;
                    642:
                    643:    _Xaw3dDrawShadows(w, event, region, FALSE);
                    644:
                    645:     if (sbw->scrollbar.orientation == XtorientHorizontal)
                    646:    {
                    647:        x = sbw->scrollbar.topLoc;
                    648:        y = 1;
                    649:        width = sbw->scrollbar.shownLength;
                    650:        height = sbw->core.height - 2;
                    651:    }
                    652:    else
                    653:    {
                    654:        x = 1;
                    655:        y = sbw->scrollbar.topLoc;
                    656:        width = sbw->core.width - 2;
                    657:        height = sbw->scrollbar.shownLength;
                    658:    }
                    659:    if (region == NULL ||
                    660:            XRectInRegion (region, x, y, width, height) != RectangleOut)
                    661:    {
                    662:        /* Forces entire thumb to be painted. */
                    663:        sbw->scrollbar.topLoc = -(sbw->scrollbar.length + 1);
                    664:        PaintThumb (sbw);
                    665:     }
                    666:     /* we'd like to be region aware here!!!! */
                    667:     PaintArrows(sbw);
                    668: }
                    669:
                    670:
                    671: static Boolean CompareEvents (oldEvent, newEvent)
                    672:     XEvent *oldEvent, *newEvent;
                    673: {
                    674: #define Check(field) if (newEvent->field != oldEvent->field) return False;
                    675:
                    676:     Check(xany.display);
                    677:     Check(xany.type);
                    678:     Check(xany.window);
                    679:
                    680:     switch (newEvent->type)
                    681:    {
                    682:        case MotionNotify:
                    683:            Check(xmotion.state);
                    684:            break;
                    685:        case ButtonPress:
                    686:        case ButtonRelease:
                    687:            Check(xbutton.state);
                    688:            Check(xbutton.button);
                    689:            break;
                    690:        case KeyPress:
                    691:        case KeyRelease:
                    692:            Check(xkey.state);
                    693:            Check(xkey.keycode);
                    694:            break;
                    695:        case EnterNotify:
                    696:        case LeaveNotify:
                    697:            Check(xcrossing.mode);
                    698:            Check(xcrossing.detail);
                    699:            Check(xcrossing.state);
                    700:            break;
                    701:    }
                    702: #undef Check
                    703:
                    704:     return True;
                    705: }
                    706:
                    707: struct EventData
                    708: {
                    709:     XEvent *oldEvent;
                    710:     int count;
                    711: };
                    712:
                    713: static Bool PeekNotifyEvent (dpy, event, args)
                    714:     Display *dpy;
                    715:     XEvent *event;
                    716:     char *args;
                    717: {
                    718:     struct EventData *eventData = (struct EventData*)args;
                    719:
                    720:     return ((++eventData->count == QLength(dpy)) /* since PeekIf blocks */
                    721:        || CompareEvents(event, eventData->oldEvent));
                    722: }
                    723:
                    724:
                    725: static Boolean LookAhead (w, event)
                    726:     Widget w;
                    727:     XEvent *event;
                    728: {
                    729:     XEvent newEvent;
                    730:     struct EventData eventData;
                    731:
                    732:     if (QLength (XtDisplay (w)) == 0)
                    733:        return False;
                    734:
                    735:     eventData.count = 0;
                    736:     eventData.oldEvent = event;
                    737:
                    738:     XPeekIfEvent (XtDisplay (w), &newEvent, PeekNotifyEvent, (char*)&eventData);
                    739:
                    740:     return CompareEvents (event, &newEvent);
                    741: }
                    742:
                    743:
                    744: static void ExtractPosition(event, x, y, state)
                    745:     XEvent         *event;
                    746:     Position       *x, *y;     /* RETURN */
                    747:    unsigned int    *state;     /* RETURN */
                    748: {
                    749:     switch( event->type )
                    750:    {
                    751:        case MotionNotify:
                    752:            *x = event->xmotion.x;
                    753:            *y = event->xmotion.y;
                    754:            if (state != NULL)
                    755:                *state = event->xmotion.state;
                    756:            break;
                    757:        case ButtonPress:
                    758:        case ButtonRelease:
                    759:            *x = event->xbutton.x;
                    760:            *y = event->xbutton.y;
                    761:            if (state != NULL)
                    762:                *state = event->xbutton.state;
                    763:            break;
                    764:        case KeyPress:
                    765:        case KeyRelease:
                    766:            *x = event->xkey.x;
                    767:            *y = event->xkey.y;
                    768:            if (state != NULL)
                    769:                *state = event->xkey.state;
                    770:            break;
                    771:        case EnterNotify:
                    772:        case LeaveNotify:
                    773:            *x = event->xcrossing.x;
                    774:            *y = event->xcrossing.y;
                    775:            if (state != NULL)
                    776:                *state = event->xcrossing.state;
                    777:            break;
                    778:        default:
                    779:            *x = 0; *y = 0;
                    780:            if (state != NULL)
                    781:                *state = 0;
                    782:    }
                    783: }
                    784:
                    785: /* ARGSUSED */
                    786: static void HandleThumb(w, event, params, num_params)
                    787:     Widget w;
                    788:     XEvent *event;
                    789:     String *params;        /* unused */
                    790:     Cardinal *num_params;  /* unused */
                    791: {
                    792:     Position x, y, loc;
                    793:     ScrollbarWidget sbw = (ScrollbarWidget) w;
                    794:
                    795:     ExtractPosition(event, &x, &y, NULL);
                    796:    loc = PICKLENGTH(sbw, x, y);
                    797:     /* if the motion event puts the pointer in thumb, call Move and Notify */
                    798:     /* also call Move and Notify if we're already in continuous scroll mode */
                    799:     if (sbw->scrollbar.scroll_mode == SMODE_CONT ||
                    800:            (loc >= sbw->scrollbar.topLoc &&
                    801:             loc <= sbw->scrollbar.topLoc + sbw->scrollbar.shownLength))
                    802:    {
                    803:        XtCallActionProc(w, "MoveThumb", event, params, *num_params);
                    804:        XtCallActionProc(w, "NotifyThumb", event, params, *num_params);
                    805:     }
                    806: }
                    807:
                    808: static void RepeatNotify(client_data, idp)
                    809:     XtPointer client_data;
                    810:     XtIntervalId *idp;
                    811: {
                    812:     ScrollbarWidget    sbw = (ScrollbarWidget) client_data;
                    813:     int                call_data;
                    814:    char            mode = sbw->scrollbar.scroll_mode;
                    815:    unsigned long   rep;
                    816:
                    817:     if (mode == SMODE_NONE || mode == SMODE_CONT)
                    818:    {
                    819:        sbw->scrollbar.timer_id = (XtIntervalId)0;
                    820:        return;
                    821:     }
                    822:
                    823:    if (mode == SMODE_LINE_DOWN || mode == SMODE_LINE_UP)
                    824:    {
                    825:        call_data = ONE_LINE_DATA;
                    826:        rep = LINE_REPEAT;
                    827:    }
                    828:    else
                    829:    {
                    830:        call_data = ONE_PAGE_DATA;
                    831:        rep = PAGE_REPEAT;
                    832:    }
                    833:
                    834:     if (mode == SMODE_PAGE_UP || mode == SMODE_LINE_UP)
                    835:        call_data = -call_data;
                    836:
                    837:     XtCallCallbacks((Widget)sbw, XtNscrollProc, (XtPointer)call_data);
                    838:
                    839:    sbw->scrollbar.timer_id =
                    840:        XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)sbw),
                    841:                rep,
                    842:                RepeatNotify,
                    843:                client_data);
                    844: }
                    845:
                    846: /*
                    847:  * Same as above, but for floating numbers.
                    848:  */
                    849: static float FloatInRange(num, small, big)
                    850:     float num, small, big;
                    851: {
                    852:     return (num < small) ? small : ((num > big) ? big : num);
                    853: }
                    854:
                    855: /* ARGSUSED */
                    856: static void NotifyScroll(w, event, params, num_params)
                    857:     Widget     w;
                    858:     XEvent     *event;
                    859:     String     *params;
                    860:     Cardinal   *num_params;
                    861: {
                    862:     ScrollbarWidget sbw = (ScrollbarWidget) w;
                    863:     Position       x, y, loc;
                    864:    Dimension       arrow_size;
                    865:    unsigned long   delay = 0;
                    866:     int                call_data = 0;
                    867:    unsigned int    state;
                    868:
                    869:     if (sbw->scrollbar.scroll_mode == SMODE_CONT)  /* if scroll continuous */
                    870:        return;
                    871:
                    872:     if (LookAhead (w, event))
                    873:        return;
                    874:
                    875:     ExtractPosition(event, &x, &y, &state);
                    876:     loc = PICKLENGTH(sbw, x, y);
                    877:
                    878:    if (sbw->scrollbar.thickness * 2 > sbw->scrollbar.length)
                    879:        arrow_size = sbw->scrollbar.length / 2;
                    880:    else
                    881:        arrow_size = sbw->scrollbar.thickness;
                    882:
                    883:    /*
                    884:     * handle CTRL modifier
                    885:     */
                    886:    if (state & ControlMask)
                    887:    {
                    888:        if (loc > sbw->scrollbar.topLoc + (Position)sbw->scrollbar.shownLength)
                    889:            call_data = END_PAGE_DATA;
                    890:        else
                    891:            call_data = -END_PAGE_DATA;
                    892:        sbw->scrollbar.scroll_mode = SMODE_NONE;
                    893:    }
                    894:    /*
                    895:     * handle first arrow zone
                    896:     */
                    897:    else if (loc < (Position)arrow_size)
                    898:    {
                    899:        call_data = -ONE_LINE_DATA;
                    900:        sbw->scrollbar.scroll_mode = SMODE_LINE_UP;
                    901:        delay = LINE_DELAY;
                    902:    }
                    903:
                    904:    /*
                    905:     * handle last arrow zone
                    906:     */
                    907:    else if (loc > (Position)(sbw->scrollbar.length - arrow_size))
                    908:    {
                    909:        call_data = ONE_LINE_DATA;
                    910:        sbw->scrollbar.scroll_mode = SMODE_LINE_DOWN;
                    911:        delay = LINE_DELAY;
                    912:     }
                    913:
                    914:    /*
                    915:     * handle zone "above" the thumb
                    916:     */
                    917:    else if (loc < sbw->scrollbar.topLoc)
                    918:    {
                    919:        call_data = -ONE_PAGE_DATA;
                    920:        sbw->scrollbar.scroll_mode = SMODE_PAGE_UP;
                    921:        delay = PAGE_DELAY;
                    922:     }
                    923:
                    924:    /*
                    925:     * handle zone "below" the thumb
                    926:     */
                    927:    else if (loc > sbw->scrollbar.topLoc + (Position)sbw->scrollbar.shownLength)
                    928:    {
                    929:        call_data = ONE_PAGE_DATA;
                    930:        sbw->scrollbar.scroll_mode = SMODE_PAGE_DOWN;
                    931:        delay = PAGE_DELAY;
                    932:     }
                    933:
                    934:    if (call_data)
                    935:        XtCallCallbacks(w, XtNscrollProc, (XtPointer)call_data);
                    936:
                    937:    /* establish autoscroll */
                    938:    if (delay)
                    939:        sbw->scrollbar.timer_id =
                    940:            XtAppAddTimeOut(XtWidgetToApplicationContext(w),
                    941:                                           delay, RepeatNotify, (XtPointer)w);
                    942: }
                    943:
                    944: /* ARGSUSED */
                    945: static void EndScroll(w, event, params, num_params)
                    946:     Widget w;
                    947:     XEvent *event;     /* unused */
                    948:     String *params;        /* unused */
                    949:     Cardinal *num_params;  /* unused */
                    950: {
                    951:     ScrollbarWidget sbw = (ScrollbarWidget) w;
                    952:
                    953:     sbw->scrollbar.scroll_mode = SMODE_NONE;
                    954:     /* no need to remove any autoscroll timeout; it will no-op */
                    955:     /* because the scroll_mode is SMODE_NONE */
                    956:     /* but be sure to remove timeout in destroy proc */
                    957: }
                    958:
                    959: static float FractionLoc(sbw, x, y)
                    960:     ScrollbarWidget sbw;
                    961:     int x, y;
                    962: {
                    963:     int        margin;
                    964:     float   height, width;
                    965:
                    966:     margin = MARGIN(sbw);
                    967:     x -= margin;
                    968:     y -= margin;
                    969:     height = sbw->core.height - 2 * margin;
                    970:     width = sbw->core.width - 2 * margin;
                    971:     return PICKLENGTH(sbw, x / width, y / height);
                    972: }
                    973:
                    974:
                    975: static void MoveThumb(w, event, params, num_params)
                    976:     Widget     w;
                    977:     XEvent     *event;
                    978:     String     *params;        /* unused */
                    979:     Cardinal   *num_params;    /* unused */
                    980: {
                    981:     ScrollbarWidget        sbw = (ScrollbarWidget)w;
                    982:     Position           x, y;
                    983:     float              top;
                    984:    char                old_mode = sbw->scrollbar.scroll_mode;
                    985:
                    986:     sbw->scrollbar.scroll_mode = SMODE_CONT; /* indicate continuous scroll */
                    987:
                    988:     if (LookAhead(w, event))
                    989:        return;
                    990:
                    991:     if (!event->xmotion.same_screen)
                    992:        return;
                    993:
                    994:     ExtractPosition(event, &x, &y, NULL);
                    995:
                    996:     top = FractionLoc(sbw, x, y);
                    997:
                    998:    if (old_mode != SMODE_CONT)             /* start dragging: set offset */
                    999:        if (event->xbutton.button == Button2)
                   1000:            sbw->scrollbar.scroll_off = sbw->scrollbar.shown / 2.;
                   1001:        else
                   1002:            sbw->scrollbar.scroll_off = top - sbw->scrollbar.top;
                   1003:
                   1004:    top -= sbw->scrollbar.scroll_off;
                   1005:     top = FloatInRange(top, 0.0, sbw->scrollbar.max);
                   1006:
                   1007:     sbw->scrollbar.top = top;
                   1008:     PaintThumb(sbw);
                   1009:     XFlush(XtDisplay(w));  /* re-draw it before Notifying */
                   1010: }
                   1011:
                   1012:
                   1013: /* ARGSUSED */
                   1014: static void NotifyThumb(w, event, params, num_params)
                   1015:     Widget     w;
                   1016:     XEvent     *event;
                   1017:     String     *params;        /* unused */
                   1018:     Cardinal   *num_params;    /* unused */
                   1019: {
                   1020:     ScrollbarWidget sbw = (ScrollbarWidget)w;
                   1021:
                   1022:     if (LookAhead(w, event))
                   1023:        return;
                   1024:
                   1025:     /* thumbProc is not pretty, but is necessary for backwards
                   1026:        compatibility on those architectures for which it work{s,ed};
                   1027:        the intent is to pass a (truncated) float by value. */
                   1028:     XtCallCallbacks(w, XtNthumbProc, *(XtPointer*)&sbw->scrollbar.top);
                   1029:     XtCallCallbacks(w, XtNjumpProc, (XtPointer)&sbw->scrollbar.top);
                   1030: }
                   1031:
                   1032: /* ARGSUSED */
                   1033: static void
                   1034: AllocTopShadowGC (w)
                   1035:     Widget w;
                   1036: {
                   1037:    ScrollbarWidget sbw = (ScrollbarWidget) w;
                   1038:    XtGCMask        valuemask;
                   1039:    XGCValues       myXGCV;
                   1040:
                   1041:    valuemask = GCForeground;
                   1042:    myXGCV.foreground = sbw->scrollbar.top_shadow_pixel;
                   1043:    sbw->scrollbar.top_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
                   1044: }
                   1045:
                   1046: /* ARGSUSED */
                   1047: static void
                   1048: AllocBotShadowGC (w)
                   1049:     Widget w;
                   1050: {
                   1051:    ScrollbarWidget sbw = (ScrollbarWidget) w;
                   1052:    XtGCMask        valuemask;
                   1053:    XGCValues       myXGCV;
                   1054:
                   1055:    valuemask = GCForeground;
                   1056:    myXGCV.foreground = sbw->scrollbar.bot_shadow_pixel;
                   1057:    sbw->scrollbar.bot_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
                   1058: }
                   1059:
                   1060: /* ARGSUSED */
                   1061: static void
                   1062: _Xaw3dDrawShadows(gw, event, region, out)
                   1063:    Widget  gw;
                   1064:    XEvent  *event;
                   1065:    Region  region;
                   1066:    Boolean out;
                   1067: {
                   1068:    XPoint  pt[6];
                   1069:    ScrollbarWidget sbw = (ScrollbarWidget) gw;
                   1070:    Dimension   s = sbw->scrollbar.shadow_width;
                   1071:    /*
                   1072:     * draw the shadows using the core part width and height,
                   1073:     * and the scrollbar part shadow_width.
                   1074:     *
                   1075:     *  no point to do anything if the shadow_width is 0 or the
                   1076:     *  widget has not been realized.
                   1077:     */
                   1078:    if ((s > 0) && XtIsRealized (gw))
                   1079:    {
                   1080:        Dimension   h = sbw->core.height;
                   1081:        Dimension   w = sbw->core.width;
                   1082:        Dimension   wms = w - s;
                   1083:        Dimension   hms = h - s;
                   1084:        Display     *dpy = XtDisplay (gw);
                   1085:        Window      win = XtWindow (gw);
                   1086:        GC      top, bot;
                   1087:
                   1088:        if (out)
                   1089:        {
                   1090:            top = sbw->scrollbar.top_shadow_GC;
                   1091:            bot = sbw->scrollbar.bot_shadow_GC;
                   1092:        }
                   1093:        else
                   1094:        {
                   1095:            top = sbw->scrollbar.bot_shadow_GC;
                   1096:            bot = sbw->scrollbar.top_shadow_GC;
                   1097:        }
                   1098:
                   1099:        /* top-left shadow */
                   1100:        if ((region == NULL) ||
                   1101:                (XRectInRegion (region, 0, 0, w, s) != RectangleOut) ||
                   1102:                (XRectInRegion (region, 0, 0, s, h) != RectangleOut))
                   1103:        {
                   1104:            pt[0].x = 0;    pt[0].y = h;
                   1105:            pt[1].x =       pt[1].y = 0;
                   1106:            pt[2].x = w;    pt[2].y = 0;
                   1107:            pt[3].x = wms;  pt[3].y = s;
                   1108:            pt[4].x =       pt[4].y = s;
                   1109:            pt[5].x = s;    pt[5].y = hms;
                   1110:            XFillPolygon (dpy, win, top, pt, 6,Complex,CoordModeOrigin);
                   1111:        }
                   1112:
                   1113:        /* bottom-right shadow */
                   1114:        if ((region == NULL) ||
                   1115:                (XRectInRegion (region, 0, hms, w, s) != RectangleOut) ||
                   1116:                (XRectInRegion (region, wms, 0, s, h) != RectangleOut))
                   1117:        {
                   1118:            pt[0].x = 0;    pt[0].y = h;
                   1119:            pt[1].x = w;    pt[1].y = h;
                   1120:            pt[2].x = w;    pt[2].y = 0;
                   1121:            pt[3].x = wms;  pt[3].y = s;
                   1122:            pt[4].x = wms;  pt[4].y = hms;
                   1123:            pt[5].x = s;    pt[5].y = hms;
                   1124:            XFillPolygon (dpy, win, bot, pt,6, Complex,CoordModeOrigin);
                   1125:        }
                   1126:    }
                   1127: }
                   1128:
                   1129: /************************************************************
                   1130:  *
                   1131:  *  Public routines.
                   1132:  *
                   1133:  ************************************************************/
                   1134:
                   1135: /* Set the scroll bar to the given location. */
                   1136:
                   1137: void vim_XawScrollbarSetThumb (w, top, shown, max)
                   1138:     Widget w;
                   1139: #if NeedWidePrototypes
                   1140:     double top, shown, max;
                   1141: #else
                   1142:     float top, shown, max;
                   1143: #endif
                   1144: {
                   1145:     ScrollbarWidget sbw = (ScrollbarWidget) w;
                   1146:
                   1147:     if (sbw->scrollbar.scroll_mode == SMODE_CONT) /* if still thumbing */
                   1148:        return;
                   1149:
                   1150:     sbw->scrollbar.max = (max > 1.0) ? 1.0 :
                   1151:                (max >= 0.0) ? max : sbw->scrollbar.max;
                   1152:
                   1153:     sbw->scrollbar.top = (top > sbw->scrollbar.max) ? sbw->scrollbar.max :
                   1154:                (top >= 0.0) ? top : sbw->scrollbar.top;
                   1155:
                   1156:     sbw->scrollbar.shown = (shown > 1.0) ? 1.0 :
                   1157:                (shown >= 0.0) ? shown : sbw->scrollbar.shown;
                   1158:
                   1159:     PaintThumb (sbw);
                   1160: }