home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / tcl / tkstep0.3b3 / tkstep0 / tkstep / tkScrollbar.c.diff < prev    next >
Encoding:
Text File  |  1996-07-08  |  26.1 KB  |  791 lines

  1. --- ../tk4.1/generic/tkScrollbar.c    Fri Feb 16 22:32:13 1996
  2. +++ tkScrollbar.c    Mon Jul  8 19:24:13 1996
  3. @@ -14,6 +14,10 @@
  4.   *
  5.   * SCCS: @(#) tkScrollbar.c 1.79 96/02/15 18:52:40
  6.   */
  7. +/*
  8. + * TkSTEP modifications Copyright
  9. + * by Alfredo K. Kojima 
  10. + */ 
  11.  
  12.  #include "tkPort.h"
  13.  #include "default.h"
  14. @@ -59,7 +63,9 @@
  15.      Tk_3DBorder activeBorder;    /* For drawing backgrounds when active (i.e.
  16.                   * when mouse is positioned over element). */
  17.      XColor *troughColorPtr;    /* Color for drawing trough. */
  18. -    GC troughGC;        /* For drawing trough. */
  19. +    XColor *darkPtr;        /* Color for background stipple */    
  20. +    GC troughGC;        /* For drawing trough's stippled part. */
  21. +    GC troughBackGC;        /* For drawing trough */
  22.      GC copyGC;            /* Used for copying from pixmap onto screen. */
  23.      int relief;            /* Indicates whether window as a whole is
  24.                   * raised, sunken, or flat. */
  25. @@ -70,6 +76,8 @@
  26.                  /* Color for drawing traversal highlight
  27.                   * area when highlight is off. */
  28.      XColor *highlightColorPtr;    /* Color for drawing traversal highlight. */
  29. +    Pixmap stipple;        /* trough base pattern */
  30. +    Pixmap bump;        /* bump in the slider */
  31.      int inset;            /* Total width of all borders, including
  32.                   * traversal highlight and 3-D border.
  33.                   * Indicates how much interior stuff must
  34. @@ -166,6 +174,7 @@
  35.  #define NEW_STYLE_COMMANDS    2
  36.  #define GOT_FOCUS        4
  37.  
  38. +#define RECONFIGURE        256
  39.  /*
  40.   * Minimum slider length, in pixels (designed to make sure that the slider
  41.   * is always easy to grab with the mouse).
  42. @@ -174,30 +183,43 @@
  43.  #define MIN_SLIDER_LENGTH    5
  44.  
  45.  /*
  46. + * If you want to make Tk ignore attribute settings that may be violating
  47. + * NEXTSTEP(tm) styles leave DISABLE_FORCE_STEP undef'ed, otherwise define it
  48. + * somewhere
  49. + */
  50. +#ifndef DISABLE_FORCE_STEP
  51. +#  define DISABLE_CHANGE    TK_CONFIG_DONT_CHANGE_DEFAULT
  52. +#else
  53. +#  define DISABLE_CHANGE    0
  54. +#endif
  55. +
  56. +/*
  57.   * Information used for argv parsing.
  58.   */
  59.  
  60.  static Tk_ConfigSpec configSpecs[] = {
  61.      {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
  62.      DEF_SCROLLBAR_ACTIVE_BG_COLOR, Tk_Offset(Scrollbar, activeBorder),
  63. -    TK_CONFIG_COLOR_ONLY},
  64. +    TK_CONFIG_COLOR_ONLY|DISABLE_CHANGE},
  65.      {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
  66.      DEF_SCROLLBAR_ACTIVE_BG_MONO, Tk_Offset(Scrollbar, activeBorder),
  67. -    TK_CONFIG_MONO_ONLY},
  68. +    TK_CONFIG_MONO_ONLY|DISABLE_CHANGE},
  69.      {TK_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief",
  70. -    DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(Scrollbar, activeRelief), 0},
  71. +    DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(Scrollbar, activeRelief), 
  72. +        0},
  73.      {TK_CONFIG_BORDER, "-background", "background", "Background",
  74.      DEF_SCROLLBAR_BG_COLOR, Tk_Offset(Scrollbar, bgBorder),
  75. -    TK_CONFIG_COLOR_ONLY},
  76. +    TK_CONFIG_COLOR_ONLY|DISABLE_CHANGE},
  77.      {TK_CONFIG_BORDER, "-background", "background", "Background",
  78.      DEF_SCROLLBAR_BG_MONO, Tk_Offset(Scrollbar, bgBorder),
  79. -    TK_CONFIG_MONO_ONLY},
  80. +    TK_CONFIG_MONO_ONLY|DISABLE_CHANGE},
  81.      {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
  82.      (char *) NULL, 0, 0},
  83.      {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
  84.      (char *) NULL, 0, 0},
  85.      {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
  86. -    DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(Scrollbar, borderWidth), 0},
  87. +    DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(Scrollbar, borderWidth), 
  88. +        DISABLE_CHANGE},
  89.      {TK_CONFIG_STRING, "-command", "command", "Command",
  90.      DEF_SCROLLBAR_COMMAND, Tk_Offset(Scrollbar, command),
  91.      TK_CONFIG_NULL_OK},
  92. @@ -208,19 +230,23 @@
  93.      Tk_Offset(Scrollbar, elementBorderWidth), 0},
  94.      {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
  95.      "HighlightBackground", DEF_SCROLLBAR_HIGHLIGHT_BG,
  96. -    Tk_Offset(Scrollbar, highlightBgColorPtr), 0},
  97. +    Tk_Offset(Scrollbar, highlightBgColorPtr), 
  98. +        DISABLE_CHANGE},
  99.      {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
  100.      DEF_SCROLLBAR_HIGHLIGHT,
  101. -    Tk_Offset(Scrollbar, highlightColorPtr), 0},
  102. +    Tk_Offset(Scrollbar, highlightColorPtr), 
  103. +        DISABLE_CHANGE},
  104.      {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
  105.      "HighlightThickness",
  106. -    DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(Scrollbar, highlightWidth), 0},
  107. +    DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(Scrollbar, highlightWidth), 
  108. +        DISABLE_CHANGE},
  109.      {TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump",
  110.      DEF_SCROLLBAR_JUMP, Tk_Offset(Scrollbar, jump), 0},
  111.      {TK_CONFIG_UID, "-orient", "orient", "Orient",
  112.      DEF_SCROLLBAR_ORIENT, Tk_Offset(Scrollbar, orientUid), 0},
  113.      {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
  114. -    DEF_SCROLLBAR_RELIEF, Tk_Offset(Scrollbar, relief), 0},
  115. +    DEF_SCROLLBAR_RELIEF, Tk_Offset(Scrollbar, relief), 
  116. +        DISABLE_CHANGE},
  117.      {TK_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
  118.      DEF_SCROLLBAR_REPEAT_DELAY, Tk_Offset(Scrollbar, repeatDelay), 0},
  119.      {TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
  120. @@ -230,16 +256,35 @@
  121.      TK_CONFIG_NULL_OK},
  122.      {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
  123.      DEF_SCROLLBAR_TROUGH_COLOR, Tk_Offset(Scrollbar, troughColorPtr),
  124. -    TK_CONFIG_COLOR_ONLY},
  125. +    TK_CONFIG_COLOR_ONLY|DISABLE_CHANGE},
  126.      {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
  127.      DEF_SCROLLBAR_TROUGH_MONO, Tk_Offset(Scrollbar, troughColorPtr),
  128. -    TK_CONFIG_MONO_ONLY},
  129. +    TK_CONFIG_MONO_ONLY|DISABLE_CHANGE},
  130.      {TK_CONFIG_PIXELS, "-width", "width", "Width",
  131. -    DEF_SCROLLBAR_WIDTH, Tk_Offset(Scrollbar, width), 0},
  132. +    DEF_SCROLLBAR_WIDTH, Tk_Offset(Scrollbar, width), 
  133. +        DISABLE_CHANGE},
  134.      {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
  135.      (char *) NULL, 0, 0}
  136.  };
  137.  
  138. +
  139. +#define SB_BUMP_WIDTH  6
  140. +#define SB_BUMP_HEIGHT 6
  141. +static char scrollbar_bump[] = {
  142. +" dbbb "\
  143. +"dbdddd"\
  144. +"bdd   "\
  145. +"bd  ww"\
  146. +"bd www"\
  147. +" d ww "
  148. +};
  149. +
  150. +
  151. +static unsigned char scrollbar_bump_bmp[] = {
  152. +   0x1e, 0x21, 0x39, 0x35, 0x3d, 0x1e};
  153. +
  154. +
  155.  /*
  156.   * Forward declarations for procedures defined later in this file:
  157.   */
  158. @@ -261,6 +306,83 @@
  159.  static int        ScrollbarWidgetCmd _ANSI_ARGS_((ClientData clientData,
  160.                  Tcl_Interp *, int argc, char **argv));
  161.  
  162. +
  163. +/*
  164. + *--------------------------------------------------------
  165. + * PaintPixmap -
  166. + *    Dirty routine to draw pixmaps from char data
  167. + *    
  168. + * gotta find a better way to do this...
  169. + *--------------------------------------------------------
  170. + */
  171. +static void PaintPixmap(clientData, d, data, width, height)
  172. +    ClientData clientData;
  173. +    Drawable d;
  174. +    char *data;
  175. +    int width, height;
  176. +{
  177. +    int x, y, ofs=0;
  178. +    Scrollbar *scrollPtr = (Scrollbar *)clientData;
  179. +    Display *display = scrollPtr->display;
  180. +    GC lightGC, backGC, darkGC, dark2GC;
  181. +
  182. +
  183. +    backGC = Tk_3DBorderGC( scrollPtr->tkwin, scrollPtr->bgBorder, 
  184. +               TK_3D_FLAT_GC);
  185. +    lightGC = Tk_3DBorderGC( scrollPtr->tkwin, scrollPtr->bgBorder, 
  186. +              TK_3D_LIGHT_GC);
  187. +    darkGC = Tk_3DBorderGC( scrollPtr->tkwin, scrollPtr->bgBorder, 
  188. +               TK_3D_DARK_GC);
  189. +    dark2GC = Tk_3DBorderGC( scrollPtr->tkwin, scrollPtr->bgBorder, 
  190. +               TK_3D_DARK2_GC);
  191. +    for(y = 0; y < height; y++) {
  192. +    for(x = 0; x < width; x++) {
  193. +        switch (data[ofs++]) {
  194. +         case 'b': /* black */
  195. +        XDrawPoint( scrollPtr->display, d, dark2GC, x, y);
  196. +        break;
  197. +         case 'd': /* dark */
  198. +        XDrawPoint( scrollPtr->display, d, darkGC, x, y);
  199. +        break;
  200. +         case 'w': /* white */
  201. +        XDrawPoint( scrollPtr->display, d, lightGC, x, y);
  202. +        break;
  203. +         default:
  204. +        XDrawPoint( scrollPtr->display, d, backGC, x, y);
  205. +        }
  206. +    }
  207. +    }
  208. +}
  209. +
  210. +
  211. +/*
  212. + *---------------------------------------------
  213. + *  
  214. + * MakePixmaps
  215. + *   Make pixmaps needed by scrollbar with 
  216. + * PaintPixmap
  217. + *
  218. + *---------------------------------------------
  219. + */
  220. +static void MakePixmaps(clientData)
  221. +    ClientData clientData;
  222. +{
  223. +    register Scrollbar *scrollPtr = (Scrollbar *) clientData;
  224. +
  225. +    if (Tk_Depth(scrollPtr->tkwin) > 1) {
  226. +    scrollPtr->bump = Tk_GetPixmap( scrollPtr->display, 
  227. +        Tk_WindowId(scrollPtr->tkwin),
  228. +        SB_BUMP_WIDTH, SB_BUMP_HEIGHT, Tk_Depth(scrollPtr->tkwin) );
  229. +    PaintPixmap(clientData, scrollPtr->bump, scrollbar_bump,
  230. +            SB_BUMP_WIDTH, SB_BUMP_HEIGHT);
  231. +    
  232. +    } else { /* monochrome display */
  233. +    scrollPtr->bump = XCreateBitmapFromData( scrollPtr->display,
  234. +        Tk_WindowId(scrollPtr->tkwin), scrollbar_bump_bmp,
  235. +        SB_BUMP_WIDTH, SB_BUMP_HEIGHT);
  236. +    }
  237. +}
  238. +
  239.  /*
  240.   *--------------------------------------------------------------
  241.   *
  242. @@ -326,6 +448,10 @@
  243.      scrollPtr->bgBorder = NULL;
  244.      scrollPtr->activeBorder = NULL;
  245.      scrollPtr->troughColorPtr = NULL;
  246. +    scrollPtr->darkPtr = NULL;
  247. +    scrollPtr->troughBackGC = None;
  248. +    scrollPtr->bump = None;
  249. +    scrollPtr->stipple = None;    
  250.      scrollPtr->troughGC = None;
  251.      scrollPtr->copyGC = None;
  252.      scrollPtr->relief = TK_RELIEF_FLAT;
  253. @@ -442,6 +568,8 @@
  254.          (char *) scrollPtr, argv[2], 0);
  255.      } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
  256.          && (length >= 2)) {
  257. +    /* make sure that fg colors will be changed */    
  258. +    scrollPtr->flags|=RECONFIGURE;
  259.      if (argc == 2) {
  260.          result = Tk_ConfigureInfo(interp, scrollPtr->tkwin, configSpecs,
  261.              (char *) scrollPtr, (char *) NULL, 0);
  262. @@ -676,6 +804,18 @@
  263.      if (scrollPtr->copyGC != None) {
  264.      Tk_FreeGC(scrollPtr->display, scrollPtr->copyGC);
  265.      }
  266. +    if (scrollPtr->troughBackGC != None) {
  267. +    Tk_FreeGC(scrollPtr->display, scrollPtr->troughBackGC);
  268. +    }
  269. +    if (scrollPtr->bump != None) {
  270. +    Tk_FreePixmap(scrollPtr->display, scrollPtr->bump);
  271. +    }
  272. +    if (scrollPtr->stipple != None) {
  273. +    Tk_FreeBitmap(scrollPtr->display, scrollPtr->stipple);
  274. +    }    
  275. +    if (scrollPtr->darkPtr != NULL) {
  276. +    Tk_FreeColor(scrollPtr->darkPtr);
  277. +    }    
  278.      Tk_FreeOptions(configSpecs, (char *) scrollPtr, scrollPtr->display, 0);
  279.      ckfree((char *) scrollPtr);
  280.  }
  281. @@ -700,7 +840,6 @@
  282.   *
  283.   *----------------------------------------------------------------------
  284.   */
  285. -
  286.  static int
  287.  ConfigureScrollbar(interp, scrollPtr, argc, argv, flags)
  288.      Tcl_Interp *interp;            /* Used for error reporting. */
  289. @@ -714,13 +853,16 @@
  290.  {
  291.      size_t length;
  292.      XGCValues gcValues;
  293. +    XColor newcolor;
  294.      GC new;
  295.  
  296. +    if (Tk_StrictMotif(scrollPtr->tkwin)) {
  297. +    flags|=TK_CONFIG_CHECK_MY_FLAG;
  298. +    } 
  299.      if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs,
  300.          argc, argv, (char *) scrollPtr, flags) != TCL_OK) {
  301.      return TCL_ERROR;
  302.      }
  303. -
  304.      /*
  305.       * A few options need special processing, such as parsing the
  306.       * orientation or setting the background from a 3-D border.
  307. @@ -743,20 +885,57 @@
  308.      scrollPtr->commandSize = 0;
  309.      }
  310.  
  311. -    Tk_SetBackgroundFromBorder(scrollPtr->tkwin, scrollPtr->bgBorder);
  312. +    if (scrollPtr->stipple==None) {
  313. +    scrollPtr->stipple = Tk_GetBitmap((Tcl_Interp *)NULL, scrollPtr->tkwin,
  314. +        Tk_GetUid("gray50"));
  315. +    if (scrollPtr->stipple == None) {
  316. +        panic("ScrollBar couldn't allocate bitmap for trough");
  317. +    }
  318. +    }
  319. +    
  320. +    Tk_SetBackgroundFromBorder(scrollPtr->tkwin, scrollPtr->bgBorder);    
  321. +    /* alloc color for trough base stipple */
  322. +    newcolor.red = (60 * (int) scrollPtr->troughColorPtr->red)/100;
  323. +    newcolor.green =(60 * (int) scrollPtr->troughColorPtr->green)/100;
  324. +    newcolor.blue = (60 * (int) scrollPtr->troughColorPtr->blue)/100;
  325. +    
  326. +    if (scrollPtr->darkPtr != NULL) {
  327. +    Tk_FreeColor(scrollPtr->darkPtr);
  328. +    }    
  329. +    scrollPtr->darkPtr = Tk_GetColorByValue(scrollPtr->tkwin,
  330. +    &newcolor);
  331. +
  332. +    gcValues.background = scrollPtr->troughColorPtr->pixel;
  333. +    gcValues.foreground = scrollPtr->darkPtr->pixel;   
  334. +    gcValues.stipple = scrollPtr->stipple;
  335. +    gcValues.fill_style = FillOpaqueStippled;
  336.  
  337. -    gcValues.foreground = scrollPtr->troughColorPtr->pixel;
  338. -    new = Tk_GetGC(scrollPtr->tkwin, GCForeground, &gcValues);
  339. +    new = Tk_GetGC(scrollPtr->tkwin, GCForeground|GCBackground|GCStipple|
  340. +    GCFillStyle, &gcValues);
  341.      if (scrollPtr->troughGC != None) {
  342.      Tk_FreeGC(scrollPtr->display, scrollPtr->troughGC);
  343.      }
  344.      scrollPtr->troughGC = new;
  345. +    gcValues.foreground = scrollPtr->troughColorPtr->pixel;
  346. +    new = Tk_GetGC(scrollPtr->tkwin, GCForeground, &gcValues);
  347. +    if (scrollPtr->troughBackGC != None) {
  348. +    Tk_FreeGC(scrollPtr->display, scrollPtr->troughBackGC);
  349. +    }
  350. +    scrollPtr->troughBackGC = new;
  351. +    
  352.      if (scrollPtr->copyGC == None) {
  353.      gcValues.graphics_exposures = False;
  354.      scrollPtr->copyGC = Tk_GetGC(scrollPtr->tkwin, GCGraphicsExposures,
  355.          &gcValues);
  356.      }
  357.  
  358. +    if (Tk_IsMapped(scrollPtr->tkwin)&&(scrollPtr->flags & RECONFIGURE)) {
  359. +    scrollPtr->flags &= ~RECONFIGURE;
  360. +    if (scrollPtr->bump != None) {
  361. +        Tk_FreePixmap(scrollPtr->display, scrollPtr->bump);
  362. +    }
  363. +    MakePixmaps(scrollPtr);
  364. +    }
  365.      /*
  366.       * Register the desired geometry for the window (leave enough space
  367.       * for the two arrows plus a minimum-size slider, plus border around
  368. @@ -766,8 +945,85 @@
  369.  
  370.      ComputeScrollbarGeometry(scrollPtr);
  371.      EventuallyRedraw(scrollPtr);
  372. +
  373.      return TCL_OK;
  374.  }
  375. +
  376. +#define ARROW_UP    0
  377. +#define ARROW_DOWN    1
  378. +#define ARROW_LEFT    2
  379. +#define ARROW_RIGHT    3
  380. +/*
  381. + * DrawArrow --
  382. + *       Draws an antialiased arrow with direction dir and size w x h. 
  383. + *      It's coordinates are relative to the center of the arrow. 
  384. + */
  385. +static void DrawArrow(scrollPtr, drawable, x, y, w, h, dir)
  386. +    Scrollbar   *scrollPtr;
  387. +    Drawable    drawable;
  388. +    int     x, y;    /* position relative to middle of arrow */
  389. +    int     w, h;
  390. +    char    dir;
  391. +{
  392. +    int i, hw;
  393. +    float d, s;
  394. +    GC     core, border;
  395. +
  396. +    core = Tk_3DBorderGC(scrollPtr->tkwin,scrollPtr->bgBorder,TK_3D_DARK2_GC);
  397. +    border = Tk_3DBorderGC(scrollPtr->tkwin,scrollPtr->bgBorder,TK_3D_DARK_GC);
  398. +
  399. +    if (h<3) h=3;
  400. +    if (w<3) w=3;
  401. +    if (dir<2) { /* vertical */
  402. +    hw = w/2;
  403. +    d = ((float)w/2)/(float)h;
  404. +    y -= h/2;    
  405. +    } else {
  406. +    hw = h/2;
  407. +    d = ((float)h/2)/(float)w;
  408. +    x -= w/2;
  409. +    }    
  410. +    s=0;
  411. +    switch (dir) {
  412. +     case ARROW_DOWN:
  413. +    s=h*d+0.5;
  414. +    d=-d;
  415. +     case ARROW_UP:
  416. +    for(i = 0; i < h; i++) {
  417. +        s += d;    
  418. +        XDrawLine(scrollPtr->display, drawable, core,
  419. +              (unsigned)(x-(int)(s-0.5)), y+i,
  420. +              (unsigned)(x+(int)(s-0.5)), y+i);
  421. +        /* anti-aliasing */    
  422. +        if ((int)(s+0.5)!=(int)s) {
  423. +        XDrawPoint(scrollPtr->display, drawable, 
  424. +               border, (unsigned)(x+(int)s), y+i);
  425. +        XDrawPoint(scrollPtr->display, drawable,
  426. +               border, (unsigned)(x-(int)s), y+i);
  427. +        }
  428. +    }
  429. +    break;
  430. +     case ARROW_RIGHT:
  431. +    s=h*d+0.5;
  432. +    d=-d;
  433. +     case ARROW_LEFT:
  434. +    for(i = 0; i < h; i++) {
  435. +        s += d;    
  436. +        XDrawLine(scrollPtr->display, drawable,
  437. +              core, x+i,(unsigned)(y-(int)(s-0.5)),
  438. +              x+i,(unsigned)(y+(int)(s-0.5)));
  439. +        /* anti-aliasing */    
  440. +        if ((int)(s+0.5)!=(int)s) {
  441. +        XDrawPoint(scrollPtr->display, drawable,
  442. +               border, x+i,(unsigned)(y+(int)s));
  443. +        XDrawPoint(scrollPtr->display, drawable,
  444. +               border, x+i,(unsigned)(y-(int)s));
  445. +        }
  446. +    }
  447. +    break;
  448. +    }
  449. +}
  450. +
  451.  
  452.  /*
  453.   *--------------------------------------------------------------
  454. @@ -793,15 +1049,21 @@
  455.  {
  456.      register Scrollbar *scrollPtr = (Scrollbar *) clientData;
  457.      register Tk_Window tkwin = scrollPtr->tkwin;
  458. -    XPoint points[7];
  459.      Tk_3DBorder border;
  460. -    int relief, width, elementBorderWidth;
  461. +    int relief, width, elementBorderWidth, sliderSize, delta;
  462. +    int arrowl = scrollPtr->arrowLength;
  463.      Pixmap pixmap;
  464. +    int empty=0;    
  465. +
  466.  
  467.      if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
  468.      goto done;
  469.      }
  470.  
  471. +    if ((scrollPtr->firstFraction<=0.0) && (scrollPtr->lastFraction>=1.0)) {
  472. +    empty=1;
  473. +    }
  474. +    
  475.      if (scrollPtr->vertical) {
  476.      width = Tk_Width(tkwin) - 2*scrollPtr->inset;
  477.      } else {
  478. @@ -812,6 +1074,10 @@
  479.      elementBorderWidth = scrollPtr->borderWidth;
  480.      }
  481.  
  482. +    if (scrollPtr->bump == None) {
  483. +    MakePixmaps((ClientData)scrollPtr);
  484. +    }
  485. +
  486.      /*
  487.       * In order to avoid screen flashes, this procedure redraws
  488.       * the scrollbar in a pixmap, then copies the pixmap to the
  489. @@ -822,6 +1088,7 @@
  490.      pixmap = Tk_GetPixmap(scrollPtr->display, Tk_WindowId(tkwin),
  491.          Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
  492.  
  493. +    sliderSize = scrollPtr->sliderLast - scrollPtr->sliderFirst + 1;
  494.      if (scrollPtr->highlightWidth != 0) {
  495.      GC gc;
  496.  
  497. @@ -832,16 +1099,60 @@
  498.      }
  499.      Tk_DrawFocusHighlight(tkwin, gc, scrollPtr->highlightWidth, pixmap);
  500.      }
  501. -    Tk_Draw3DRectangle(tkwin, pixmap, scrollPtr->bgBorder,
  502. +    /*
  503. +     * Tk_Draw3DRectangle(tkwin, pixmap, scrollPtr->bgBorder,
  504.          scrollPtr->highlightWidth, scrollPtr->highlightWidth,
  505.          Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
  506.          Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
  507.          scrollPtr->borderWidth, scrollPtr->relief);
  508. -    XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
  509. -        scrollPtr->inset, scrollPtr->inset,
  510. -        (unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
  511. -        (unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
  512. +     */
  513. +    XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughBackGC,
  514. +    scrollPtr->highlightWidth, scrollPtr->highlightWidth,
  515. +     Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
  516. +      Tk_Height(tkwin) - 2*scrollPtr->highlightWidth);
  517. +    
  518. +    XDrawRectangle(scrollPtr->display, pixmap, 
  519. +    Tk_3DBorderGC(scrollPtr->tkwin,scrollPtr->bgBorder,TK_3D_DARK2_GC),
  520. +     scrollPtr->highlightWidth, scrollPtr->highlightWidth,
  521. +     Tk_Width(tkwin) - 2*scrollPtr->highlightWidth-1,
  522. +     Tk_Height(tkwin) - 2*scrollPtr->highlightWidth-1);
  523.  
  524. +    if (scrollPtr->vertical) {
  525. +    if (!empty) {
  526. +        XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
  527. +           scrollPtr->inset, scrollPtr->inset,
  528. +           (unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
  529. +           (unsigned) (Tk_Height(tkwin) + 1 -
  530. +           (scrollPtr->arrowLength + scrollPtr->inset)*2));
  531. +    } else {
  532. +        XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
  533. +           scrollPtr->inset, scrollPtr->inset,
  534. +           (unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
  535. +           (unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
  536. +    }
  537. +    } else {
  538. +    if (!empty) {
  539. +        XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
  540. +           scrollPtr->arrowLength * 2+2,
  541. +           scrollPtr->inset,
  542. +           (unsigned) (Tk_Width(tkwin) -
  543. +           (scrollPtr->arrowLength*2 + scrollPtr->inset*2)),
  544. +           (unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
  545. +    } else {
  546. +        XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
  547. +           scrollPtr->inset, scrollPtr->inset,
  548. +           (unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
  549. +           (unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
  550. +    }
  551. +    }
  552. +    
  553. +    /* 
  554. +     * don't draw slider/arrows if everything is visible
  555. +     */
  556. +    if (empty) {
  557. +    goto docopy;
  558. +    }    
  559. +    
  560.      /*
  561.       * Draw the top or left arrow.  The coordinates of the polygon
  562.       * points probably seem odd, but they were carefully chosen with
  563. @@ -849,33 +1160,42 @@
  564.       * cause the arrows to just fill the narrow dimension of the
  565.       * scrollbar and be properly centered.
  566.       */
  567. -
  568.      if (scrollPtr->activeField == TOP_ARROW) {
  569.      border = scrollPtr->activeBorder;
  570.      relief = scrollPtr->activeField == TOP_ARROW ? scrollPtr->activeRelief
  571.          : TK_RELIEF_RAISED;
  572. +    delta = (relief == TK_RELIEF_SUNKEN) ? scrollPtr->borderWidth/2+1 : 0;
  573.      } else {
  574.      border = scrollPtr->bgBorder;
  575.      relief = TK_RELIEF_RAISED;
  576. +    delta = 0;
  577.      }
  578. +    
  579.      if (scrollPtr->vertical) {
  580. -    points[0].x = scrollPtr->inset - 1;
  581. -    points[0].y = scrollPtr->arrowLength + scrollPtr->inset - 1;
  582. -    points[1].x = width + scrollPtr->inset;
  583. -    points[1].y = points[0].y;
  584. -    points[2].x = width/2 + scrollPtr->inset;
  585. -    points[2].y = scrollPtr->inset - 1;
  586. -    Tk_Fill3DPolygon(tkwin, pixmap, border, points, 3,
  587. +    Tk_Fill3DRectangle(tkwin, pixmap, border, scrollPtr->inset,
  588. +         Tk_Height(tkwin) - scrollPtr->arrowLength*2,
  589. +        scrollPtr->width, scrollPtr->width,
  590.          elementBorderWidth, relief);
  591. +    if (width >= 5) {
  592. +        DrawArrow(scrollPtr, pixmap, scrollPtr->inset+arrowl/2+delta
  593. +              -(2-(arrowl&1)),
  594. +              Tk_Height(tkwin) - (2-(arrowl&1)) + scrollPtr->inset/2 -
  595. +              arrowl*2 + (arrowl-scrollPtr->inset)/2+delta,
  596. +              arrowl-2*scrollPtr->inset-3, arrowl-2*scrollPtr->inset-3,
  597. +              ARROW_UP);
  598. +    }    
  599.      } else {
  600. -    points[0].x = scrollPtr->arrowLength + scrollPtr->inset - 1;
  601. -    points[0].y = scrollPtr->inset - 1;
  602. -    points[1].x = scrollPtr->inset;
  603. -    points[1].y = width/2 + scrollPtr->inset;
  604. -    points[2].x = points[0].x;
  605. -    points[2].y = width + scrollPtr->inset;
  606. -    Tk_Fill3DPolygon(tkwin, pixmap, border, points, 3,
  607. +    Tk_Fill3DRectangle(tkwin, pixmap, border,
  608. +         scrollPtr->inset, scrollPtr->inset,
  609. +        scrollPtr->width, scrollPtr->width,
  610.          elementBorderWidth, relief);
  611. +    if (width >= 5) {
  612. +        DrawArrow(scrollPtr, pixmap, 3*scrollPtr->inset/2 - (arrowl&1) +
  613. +              (arrowl-scrollPtr->inset)/2+delta,
  614. +              scrollPtr->inset+ arrowl/2-(arrowl&1)+delta,
  615. +              arrowl-2*scrollPtr->inset-3, arrowl-2*scrollPtr->inset-3,
  616. +              ARROW_LEFT);
  617. +    }
  618.      }
  619.  
  620.      /*
  621. @@ -886,40 +1206,48 @@
  622.      border = scrollPtr->activeBorder;
  623.      relief = scrollPtr->activeField == BOTTOM_ARROW
  624.          ? scrollPtr->activeRelief : TK_RELIEF_RAISED;
  625. +    delta = (relief == TK_RELIEF_SUNKEN) ? scrollPtr->borderWidth/2+1 : 0;
  626.      } else {
  627.      border = scrollPtr->bgBorder;
  628.      relief = TK_RELIEF_RAISED;
  629. +    delta = 0;
  630.      }
  631.      if (scrollPtr->vertical) {
  632. -    points[0].x = scrollPtr->inset;
  633. -    points[0].y = Tk_Height(tkwin) - scrollPtr->arrowLength
  634. -        - scrollPtr->inset + 1;
  635. -    points[1].x = width/2 + scrollPtr->inset;
  636. -    points[1].y = Tk_Height(tkwin) - scrollPtr->inset;
  637. -    points[2].x = width + scrollPtr->inset;
  638. -    points[2].y = points[0].y;
  639. -    Tk_Fill3DPolygon(tkwin, pixmap, border,
  640. -        points, 3, elementBorderWidth, relief);
  641. +    Tk_Fill3DRectangle(tkwin, pixmap, border, scrollPtr->inset,
  642. +         Tk_Height(tkwin) - scrollPtr->arrowLength,
  643. +        scrollPtr->width, scrollPtr->width,
  644. +        elementBorderWidth, relief);
  645. +    if (width >= 5 ) {
  646. +        DrawArrow(scrollPtr, pixmap, scrollPtr->inset+arrowl/2-
  647. +              (2-(arrowl&1))+delta,
  648. +              scrollPtr->inset/2+Tk_Height(tkwin) - (1-(arrowl&1)) -
  649. +              arrowl + (arrowl-scrollPtr->inset)/2+delta,
  650. +              arrowl-2*scrollPtr->inset-3, arrowl-2*scrollPtr->inset-3,
  651. +              ARROW_DOWN);        
  652. +    }    
  653.      } else {
  654. -    points[0].x = Tk_Width(tkwin) - scrollPtr->arrowLength
  655. -        - scrollPtr->inset + 1;
  656. -    points[0].y = scrollPtr->inset - 1;
  657. -    points[1].x = points[0].x;
  658. -    points[1].y = width + scrollPtr->inset;
  659. -    points[2].x = Tk_Width(tkwin) - scrollPtr->inset;
  660. -    points[2].y = width/2 + scrollPtr->inset;
  661. -    Tk_Fill3DPolygon(tkwin, pixmap, border,
  662. -        points, 3, elementBorderWidth, relief);
  663. +    Tk_Fill3DRectangle(tkwin, pixmap, border, 
  664. +         scrollPtr->inset + scrollPtr->arrowLength,
  665. +        scrollPtr->inset, scrollPtr->width, scrollPtr->width,
  666. +        elementBorderWidth, relief);
  667. +    if (width >= 5) {
  668. +        DrawArrow(scrollPtr, pixmap, 3*scrollPtr->inset/2+delta-
  669. +              (arrowl&1) + arrowl + (arrowl-scrollPtr->inset)/2,
  670. +              scrollPtr->inset+arrowl/2-(arrowl&1)+delta,
  671. +              arrowl-2*scrollPtr->inset-3, arrowl-2*scrollPtr->inset-3,
  672. +              ARROW_RIGHT);
  673. +    }
  674.      }
  675.  
  676. +
  677.      /*
  678.       * Display the slider.
  679.       */
  680.  
  681.      if (scrollPtr->activeField == SLIDER) {
  682.      border = scrollPtr->activeBorder;
  683. -    relief = scrollPtr->activeField == SLIDER ? scrollPtr->activeRelief
  684. -        : TK_RELIEF_RAISED;
  685. +    relief = /*scrollPtr->activeField == SLIDER ? scrollPtr->activeRelief
  686. +        :*/ TK_RELIEF_RAISED;
  687.      } else {
  688.      border = scrollPtr->bgBorder;
  689.      relief = TK_RELIEF_RAISED;
  690. @@ -927,20 +1255,32 @@
  691.      if (scrollPtr->vertical) {
  692.      Tk_Fill3DRectangle(tkwin, pixmap, border,
  693.          scrollPtr->inset, scrollPtr->sliderFirst,
  694. -        width, scrollPtr->sliderLast - scrollPtr->sliderFirst,
  695. +        width, sliderSize,
  696.          elementBorderWidth, relief);
  697. +    if ((sliderSize > SB_BUMP_HEIGHT*2) && (width > SB_BUMP_WIDTH)) {
  698. +        XCopyArea(scrollPtr->display, scrollPtr->bump, pixmap,
  699. +        scrollPtr->copyGC, 0, 0, SB_BUMP_WIDTH, SB_BUMP_HEIGHT,
  700. +        scrollPtr->inset + (width - SB_BUMP_WIDTH)/2-1, 
  701. +        scrollPtr->sliderFirst - 1  + (sliderSize - SB_BUMP_HEIGHT)/2);
  702. +    }
  703.      } else {
  704.      Tk_Fill3DRectangle(tkwin, pixmap, border,
  705.          scrollPtr->sliderFirst, scrollPtr->inset,
  706. -        scrollPtr->sliderLast - scrollPtr->sliderFirst, width,
  707. +        sliderSize-1, width,
  708.          elementBorderWidth, relief);
  709. +    if ((sliderSize > SB_BUMP_HEIGHT*2) && (width > SB_BUMP_HEIGHT)) {
  710. +        XCopyArea(scrollPtr->display, scrollPtr->bump, pixmap,
  711. +        scrollPtr->copyGC, 0, 0, SB_BUMP_WIDTH, SB_BUMP_HEIGHT,
  712. +        scrollPtr->sliderFirst + (sliderSize - SB_BUMP_HEIGHT)/2-1, 
  713. +        scrollPtr->inset - 1 + (width - SB_BUMP_WIDTH)/2);
  714. +    }
  715.      }
  716.  
  717.      /*
  718.       * Copy the information from the off-screen pixmap onto the screen,
  719.       * then delete the pixmap.
  720.       */
  721. -
  722. +    docopy:
  723.      XCopyArea(scrollPtr->display, pixmap, Tk_WindowId(tkwin),
  724.          scrollPtr->copyGC, 0, 0, (unsigned) Tk_Width(tkwin),
  725.          (unsigned) Tk_Height(tkwin), 0, 0);
  726. @@ -1106,8 +1446,13 @@
  727.      if (scrollPtr->sliderLast > fieldLength) {
  728.      scrollPtr->sliderLast = fieldLength;
  729.      }
  730. -    scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
  731. -    scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;
  732. +    if (scrollPtr->vertical) {    
  733. +    scrollPtr->sliderFirst += scrollPtr->inset;
  734. +    scrollPtr->sliderLast += scrollPtr->inset;
  735. +    } else {
  736. +    scrollPtr->sliderFirst += scrollPtr->arrowLength*2 + scrollPtr->inset;
  737. +    scrollPtr->sliderLast += scrollPtr->arrowLength*2 +scrollPtr->inset;
  738. +    }        
  739.  
  740.      /*
  741.       * Register the desired geometry for the window (leave enough space
  742. @@ -1177,20 +1522,35 @@
  743.       * All of the calculations in this procedure mirror those in
  744.       * DisplayScrollbar.  Be sure to keep the two consistent.
  745.       */
  746. -
  747. -    if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
  748. -    return TOP_ARROW;
  749. -    }
  750. -    if (y < scrollPtr->sliderFirst) {
  751. -    return TOP_GAP;
  752. -    }
  753. -    if (y < scrollPtr->sliderLast) {
  754. -    return SLIDER;
  755. -    }
  756. -    if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
  757. +    if (scrollPtr->vertical) {    
  758. +    if (y < scrollPtr->sliderFirst) {
  759. +        return TOP_GAP;
  760. +    }
  761. +    if (y < scrollPtr->sliderLast) {        
  762. +        return SLIDER;
  763. +    }
  764. +    if (y < (length - (scrollPtr->arrowLength*2 + scrollPtr->inset + 1))) {
  765. +        return BOTTOM_GAP;
  766. +    }
  767. +    if (y < (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
  768. +        return TOP_ARROW;
  769. +    }
  770.      return BOTTOM_ARROW;
  771. +    } else {
  772. +    if (y < (scrollPtr->arrowLength + scrollPtr->inset)) {
  773. +        return TOP_ARROW;
  774. +    }
  775. +    if (y < (scrollPtr->arrowLength*2 + scrollPtr->inset + 1)) {
  776. +        return BOTTOM_ARROW;
  777. +    }
  778. +    if (y < (scrollPtr->sliderFirst)) {
  779. +        return TOP_GAP;
  780. +    }
  781. +    if (y < (scrollPtr->sliderLast)) {
  782. +        return SLIDER;
  783. +    }
  784. +    return BOTTOM_GAP;
  785.      }
  786. -    return BOTTOM_GAP;
  787.  }
  788.  
  789.  /*
  790.