comparison lwlib/xlwscrollbar.c @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents 441bb1e64a06
children c0c698873ce1
comparison
equal deleted inserted replaced
69:804d1389bcd6 70:131b0175ea99
1 /* Implements a lightweight scrollbar widget. 1 /* Implements a lightweight scrollbar widget.
2 Copyright (C) 1992, 1993, 1994 Lucid, Inc. 2 Copyright (C) 1992, 1993, 1994 Lucid, Inc.
3 Copyright (C) 1997 Sun Microsystems, Inc.
4 3
5 This file is part of the Lucid Widget Library. 4 This file is part of the Lucid Widget Library.
6 5
7 The Lucid Widget Library is free software; you can redistribute it and/or 6 The Lucid Widget Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as published by 7 modify it under the terms of the GNU General Public License as published by
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 14 GNU General Public License for more details.
16 15
17 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to 17 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 Boston, MA 02111-1307, USA. */
21 19
22 /* Created by Douglas Keller <dkeller@vnet.ibm.com> */ 20 /* Created by Douglas Keller <dkeller@vnet.ibm.com> */
23 /* Lots of hacking by Martin Buchholz */ 21 /* Last changed 03/24/95 */
24 22
25 /* 23 /*
26 * Athena-style scrollbar button bindings added on Sun Dec 24 22:03:57 1995 24 * Athena-style scrollbar button bindings added on Sun Dec 24 22:03:57 1995
27 * by Jonathan Stigelman <Stig@hackvan.com>... Ho ho ho! 25 * by Jonathan Stigelman <Stig@hackvan.com>... Ho ho ho!
28 * 26 *
61 * XmNpageDecrementCallback 59 * XmNpageDecrementCallback
62 * XmNtoTopCallback 60 * XmNtoTopCallback
63 * XmNtoBottomCallback 61 * XmNtoBottomCallback
64 * XmNdragCallback 62 * XmNdragCallback
65 * 63 *
66 * XmNsliderStyle - values can be: "plain" or "dimple" 64 * XmNknobStyle - values can be: "plain" or "dimple"
67 * XmNarrowPosition - values can be: "opposite" or "same" 65 * XmNarrowPosition - values can be: "opposite" or "same"
68 * 66 *
69 */ 67 */
70 68
71 #include <stdio.h> 69 #include <stdio.h>
80 #include "xlwscrollbar.h" 78 #include "xlwscrollbar.h"
81 79
82 #define DBUG(x) 80 #define DBUG(x)
83 81
84 #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \ 82 #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \
85 ? ((unsigned long) (x)) : ((unsigned long) (y))) 83 ? ((unsigned long) (x)) : ((unsigned long) (y)))
86 84
87 #define VERT(w) ((w)->sb.orientation == XmVERTICAL) 85 #define VERT(w) (w->sb.orientation == XmVERTICAL)
88 86
89 #define SS_MIN 8 87 #define SS_MIN 8
90 88
91 typedef enum 89 #define ARROW_UP 0
92 { 90 #define ARROW_DOWN 1
93 BUTTON_NONE, 91 #define ARROW_LEFT 2
94 BUTTON_SLIDER, 92 #define ARROW_RIGHT 3
95 BUTTON_UP_ARROW, 93
96 BUTTON_DOWN_ARROW, 94 #define ARM_NONE 0
97 BUTTON_TROUGH_ABOVE, 95 #define ARM_KNOB 1
98 BUTTON_TROUGH_BELOW 96 #define ARM_UP 2
99 } button_where; 97 #define ARM_DOWN 3
100 98 #define ARM_PAGEUP 4
101 typedef enum 99 #define ARM_PAGEDOWN 5
102 { 100
103 SLIDER_PLAIN, 101 #define BUTTON_NONE 0
104 SLIDER_DIMPLE 102 #define BUTTON_KNOB 1
105 } SliderStyle; 103 #define BUTTON_UP_ARROW 2
106 104 #define BUTTON_DOWN_ARROW 3
107 /*-------------------------- Resources ----------------------------------*/ 105 #define BUTTON_TROUGH_ABOVE 4
106 #define BUTTON_TROUGH_BELOW 5
107
108 #define KNOB_PLAIN 0
109 #define KNOB_DIMPLE 1
110
111 /************************************************************************
112 **
113 ** Resources
114 **
115 */
108 #define offset(field) XtOffset(XlwScrollBarWidget, field) 116 #define offset(field) XtOffset(XlwScrollBarWidget, field)
109 117
110 static XtResource resources[] = { 118 static XtResource resources[] = {
111 { XmNforeground, XmCForeground, XtRPixel, sizeof(Pixel), 119 { (String) XmNforeground, (String) XmCForeground, XtRPixel, sizeof(Pixel),
112 offset(sb.foreground), XtRImmediate, (XtPointer) XtDefaultForeground }, 120 offset(sb.foreground), XtRImmediate, (XtPointer) XtDefaultForeground },
113 121
114 { XmNtopShadowColor, XmCTopShadowColor, XtRPixel, 122 { (String) XmNtopShadowColor, (String) XmCTopShadowColor, XtRPixel,
115 sizeof(Pixel), offset(sb.topShadowColor), XtRImmediate, (XtPointer) ~0 }, 123 sizeof(Pixel), offset(sb.topShadowColor), XtRImmediate, (XtPointer) ~0 },
116 { XmNbottomShadowColor, XmCBottomShadowColor, XtRPixel, 124 { (String) XmNbottomShadowColor, (String) XmCBottomShadowColor, XtRPixel,
117 sizeof(Pixel), offset(sb.bottomShadowColor), XtRImmediate, 125 sizeof(Pixel), offset(sb.bottomShadowColor), XtRImmediate,
118 (XtPointer)~0 }, 126 (XtPointer)~0 },
119 127
120 { XmNtopShadowPixmap, XmCTopShadowPixmap, XtRPixmap, 128 { (String) XmNtopShadowPixmap, (String) XmCTopShadowPixmap, XtRPixmap,
121 sizeof (Pixmap), offset(sb.topShadowPixmap), XtRImmediate, 129 sizeof (Pixmap), offset(sb.topShadowPixmap), XtRImmediate,
122 (XtPointer)None}, 130 (XtPointer)None},
123 { XmNbottomShadowPixmap, XmCBottomShadowPixmap, 131 { (String) XmNbottomShadowPixmap, (String) XmCBottomShadowPixmap,
124 XtRPixmap, sizeof (Pixmap), offset(sb.bottomShadowPixmap), 132 XtRPixmap, sizeof (Pixmap), offset(sb.bottomShadowPixmap),
125 XtRImmediate, (XtPointer)None}, 133 XtRImmediate, (XtPointer)None},
126 134
127 { XmNtroughColor, XmCTroughColor, XtRPixel, sizeof(Pixel), 135 { (String)XmNtroughColor, (String)XmCTroughColor, XtRPixel, sizeof(Pixel),
128 offset(sb.troughColor), XtRImmediate, (XtPointer)~0 }, 136 offset(sb.troughColor), XtRImmediate, (XtPointer)~0 },
129 137
130 { XmNshadowThickness, XmCShadowThickness, XtRInt, 138 { (String)XmNshadowThickness, (String)XmCShadowThickness, XtRInt,
131 sizeof(int), offset(sb.shadowThickness), XtRImmediate, (XtPointer)2 }, 139 sizeof(int), offset(sb.shadowThickness), XtRImmediate, (XtPointer)2 },
132 140
133 { XmNborderWidth, XmCBorderWidth, XtRDimension, 141 { (String) XmNborderWidth, (String) XmCBorderWidth, XtRDimension,
134 sizeof(Dimension), offset(core.border_width), XtRImmediate, 142 sizeof(Dimension), offset(core.border_width), XtRImmediate,
135 (XtPointer)0 }, 143 (XtPointer)0 },
136 144
137 { XmNshowArrows, XmCShowArrows, XtRBoolean, 145 { (String) XmNshowArrows, (String) XmCShowArrows, XtRBoolean,
138 sizeof(Boolean), offset(sb.showArrows), XtRImmediate, (XtPointer)True }, 146 sizeof(Boolean), offset(sb.showArrows), XtRImmediate, (XtPointer)True },
139 147
140 { XmNinitialDelay, XmCInitialDelay, XtRInt, sizeof(int), 148 { (String) XmNinitialDelay, (String) XmCInitialDelay, XtRInt, sizeof(int),
141 offset(sb.initialDelay), XtRImmediate, (XtPointer) 250 }, 149 offset(sb.initialDelay), XtRImmediate, (XtPointer) 250 },
142 { XmNrepeatDelay, XmCRepeatDelay, XtRInt, sizeof(int), 150 { (String) XmNrepeatDelay, (String) XmCRepeatDelay, XtRInt, sizeof(int),
143 offset(sb.repeatDelay), XtRImmediate, (XtPointer) 50 }, 151 offset(sb.repeatDelay), XtRImmediate, (XtPointer) 50 },
144 152
145 { XmNorientation, XmCOrientation, XtROrientation, 153 { (String) XmNorientation, (String) XmCOrientation, XtROrientation,
146 sizeof(unsigned char), offset(sb.orientation), XtRImmediate, 154 sizeof(unsigned char), offset(sb.orientation), XtRImmediate,
147 (XtPointer) XmVERTICAL }, 155 (XtPointer) XmVERTICAL },
148 156
149 { XmNminimum, XmCMinimum, XtRInt, sizeof(int), 157 { (String) XmNminimum, (String) XmCMinimum, XtRInt, sizeof(int),
150 offset(sb.minimum), XtRImmediate, (XtPointer) 0}, 158 offset(sb.minimum), XtRImmediate, (XtPointer) 0},
151 { XmNmaximum, XmCMaximum, XtRInt, sizeof(int), 159 { (String) XmNmaximum, (String) XmCMaximum, XtRInt, sizeof(int),
152 offset(sb.maximum), XtRImmediate, (XtPointer) 100}, 160 offset(sb.maximum), XtRImmediate, (XtPointer) 100},
153 { XmNvalue, XmCValue, XtRInt, sizeof(int), 161 { (String) XmNvalue, (String) XmCValue, XtRInt, sizeof(int),
154 offset(sb.value), XtRImmediate, (XtPointer) 0}, 162 offset(sb.value), XtRImmediate, (XtPointer) 0},
155 { XmNsliderSize, XmCSliderSize, XtRInt, sizeof(int), 163 { (String) XmNsliderSize, (String) XmCSliderSize, XtRInt, sizeof(int),
156 offset(sb.sliderSize), XtRImmediate, (XtPointer) 10}, 164 offset(sb.sliderSize), XtRImmediate, (XtPointer) 10},
157 { XmNincrement, XmCIncrement, XtRInt, sizeof(int), 165 { (String) XmNincrement, (String) XmCIncrement, XtRInt, sizeof(int),
158 offset(sb.increment), XtRImmediate, (XtPointer) 1}, 166 offset(sb.increment), XtRImmediate, (XtPointer) 1},
159 { XmNpageIncrement, XmCPageIncrement, XtRInt, sizeof(int), 167 { (String)XmNpageIncrement, (String)XmCPageIncrement, XtRInt, sizeof(int),
160 offset(sb.pageIncrement), XtRImmediate, (XtPointer) 10}, 168 offset(sb.pageIncrement), XtRImmediate, (XtPointer) 10},
161 169
162 { XmNvalueChangedCallback, XmCValueChangedCallback, 170 { (String) XmNvalueChangedCallback, (String) XmCValueChangedCallback,
163 XtRCallback, sizeof(XtPointer), offset(sb.valueChangedCBL), 171 XtRCallback, sizeof(XtPointer), offset(sb.valueChangedCBL),
164 XtRCallback, NULL}, 172 XtRCallback, NULL},
165 { XmNincrementCallback, XmCIncrementCallback, 173 { (String) XmNincrementCallback, (String) XmCIncrementCallback,
166 XtRCallback, sizeof(XtPointer), offset(sb.incrementCBL), 174 XtRCallback, sizeof(XtPointer), offset(sb.incrementCBL),
167 XtRCallback, NULL}, 175 XtRCallback, NULL},
168 { XmNdecrementCallback, XmCDecrementCallback, 176 { (String) XmNdecrementCallback, (String) XmCDecrementCallback,
169 XtRCallback, sizeof(XtPointer), offset(sb.decrementCBL), 177 XtRCallback, sizeof(XtPointer), offset(sb.decrementCBL),
170 XtRCallback, NULL}, 178 XtRCallback, NULL},
171 { XmNpageIncrementCallback, XmCPageIncrementCallback, 179 { (String) XmNpageIncrementCallback, (String) XmCPageIncrementCallback,
172 XtRCallback, sizeof(XtPointer), offset(sb.pageIncrementCBL), 180 XtRCallback, sizeof(XtPointer), offset(sb.pageIncrementCBL),
173 XtRCallback, NULL}, 181 XtRCallback, NULL},
174 { XmNpageDecrementCallback, XmCPageDecrementCallback, 182 { (String) XmNpageDecrementCallback, (String) XmCPageDecrementCallback,
175 XtRCallback, sizeof(XtPointer), offset(sb.pageDecrementCBL), 183 XtRCallback, sizeof(XtPointer), offset(sb.pageDecrementCBL),
176 XtRCallback, NULL}, 184 XtRCallback, NULL},
177 { XmNtoTopCallback, XmCToTopCallback, XtRCallback, 185 { (String) XmNtoTopCallback, (String) XmCToTopCallback, XtRCallback,
178 sizeof(XtPointer), offset(sb.toTopCBL), XtRCallback, NULL}, 186 sizeof(XtPointer), offset(sb.toTopCBL), XtRCallback, NULL},
179 { XmNtoBottomCallback, XmCToBottomCallback, XtRCallback, 187 { (String) XmNtoBottomCallback, (String) XmCToBottomCallback, XtRCallback,
180 sizeof(XtPointer), offset(sb.toBottomCBL), XtRCallback, NULL}, 188 sizeof(XtPointer), offset(sb.toBottomCBL), XtRCallback, NULL},
181 { XmNdragCallback, XmCDragCallback, XtRCallback, 189 { (String) XmNdragCallback, (String) XmCDragCallback, XtRCallback,
182 sizeof(XtPointer), offset(sb.dragCBL), XtRCallback, NULL}, 190 sizeof(XtPointer), offset(sb.dragCBL), XtRCallback, NULL},
183 191
184 /* "knob" is obsolete; use "slider" instead. */ 192 { (String) XmNknobStyle, (String) XmCKnobStyle, XtRString, sizeof(char *),
185 { XmNsliderStyle, XmCSliderStyle, XtRString, sizeof(char *), 193 offset(sb.knobStyle), XtRImmediate, NULL},
186 offset(sb.sliderStyle), XtRImmediate, NULL}, 194
187 { XmNknobStyle, XmCKnobStyle, XtRString, sizeof(char *), 195 { (String) XmNarrowPosition, (String) XmCArrowPosition, XtRString,
188 offset(sb.sliderStyle), XtRImmediate, NULL},
189
190 { XmNarrowPosition, XmCArrowPosition, XtRString,
191 sizeof(char *), offset(sb.arrowPosition), XtRImmediate, NULL}, 196 sizeof(char *), offset(sb.arrowPosition), XtRImmediate, NULL},
192 }; 197 };
193 198
194 /*-------------------------- Prototypes ---------------------------------*/ 199 /************************************************************************
195 200 **
196 /* Actions */ 201 ** Prototypes
197 typedef void Action(Widget w, XEvent *event, String *parms, Cardinal *num_parms); 202 **
198 static Action Select, PageUpOrLeft, PageDownOrRight, Drag, Release, Jump, Abort; 203 */
199 204
200 /* Methods */ 205 /*
206 ** Actions
207 */
208 static void Select(Widget w, XEvent *event, String *parms, Cardinal *num_parms);
209 static void PageUpOrLeft(Widget w, XEvent *event, String *parms, Cardinal *num_parms);
210 static void PageDownOrRight(Widget w, XEvent *event, String *parms, Cardinal *num_parms);
211 static void Drag(Widget w, XEvent *event, String *parms, Cardinal *num_parms);
212 static void Release(Widget w, XEvent *event, String *parms, Cardinal *num_parms);
213 static void Jump(Widget w, XEvent *event, String *parms, Cardinal *num_parms);
214 static void Abort(Widget w, XEvent *event, String *parms, Cardinal *num_parms);
215
216 /*
217 ** Methods
218 */
201 static void Initialize(Widget treq, Widget tnew, ArgList args, Cardinal *num_args); 219 static void Initialize(Widget treq, Widget tnew, ArgList args, Cardinal *num_args);
202 static Boolean SetValues(Widget current, Widget request, Widget nw, ArgList args, Cardinal *num_args); 220 static Boolean SetValues(Widget current, Widget request, Widget nw, ArgList args, Cardinal *num_args);
203 static void Destroy(Widget widget); 221 static void Destroy(Widget widget);
204 static void Redisplay(Widget widget, XEvent *event, Region region); 222 static void Redisplay(Widget widget, XEvent *event, Region region);
205 static void Resize(Widget widget); 223 static void Resize(Widget widget);
206 static void Realize(Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr); 224 static void Realize(Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr);
207 225
208 /* Private */ 226 /*
209 227 ** Private
210 /*-------------------------- Actions Table ------------------------------*/ 228 */
211 static XtActionsRec actions[] = 229
212 { 230
213 {"Select", Select}, 231 /************************************************************************
214 {"PageDownOrRight", PageDownOrRight}, 232 **
215 {"PageUpOrLeft", PageUpOrLeft}, 233 ** Actions Table
216 {"Drag", Drag}, 234 **
217 {"Release", Release}, 235 */
218 {"Jump", Jump}, 236 static XtActionsRec actions[] = {
219 {"Abort", Abort}, 237 {(String) "Select", Select},
238 {(String) "PageDownOrRight", PageDownOrRight},
239 {(String) "PageUpOrLeft", PageUpOrLeft},
240 {(String) "Drag", Drag},
241 {(String) "Release", Release},
242 {(String) "Jump", Jump},
243 {(String) "Abort", Abort},
220 }; 244 };
221 245
222 /*--------------------- Default Translation Table -----------------------*/ 246 /************************************************************************
247 **
248 ** Default Translation Table
249 **
250 */
223 static char default_translations[] = 251 static char default_translations[] =
224 "<Btn1Down>: Select()\n" 252 "<Btn1Down>: Select()\n"
225 "<Btn1Motion>: Drag()\n" 253 "<Btn1Motion>: Drag()\n"
226 "<Btn1Up>: Release()\n" 254 "<Btn1Up>: Release()\n"
227 "<Btn2Down>: Jump()\n" 255 "<Btn2Down>: Jump()\n"
228 "<Btn2Motion>: Drag()\n" 256 "<Btn2Motion>: Drag()\n"
229 "<Btn2Up>: Release()\n" 257 "<Btn2Up>: Release()\n"
230 "<Key>Delete: Abort()" 258 "<Key>Delete: Abort()"
231 ; 259 ;
232 260
233 /*------------------- Class record initialization -----------------------*/ 261 /************************************************************************
262 **
263 ** Class record initalization
264 **
265 */
234 XlwScrollBarClassRec xlwScrollBarClassRec = { 266 XlwScrollBarClassRec xlwScrollBarClassRec = {
235 /* core_class fields */ 267 /* core_class fields */
236 { 268 {
237 /* superclass */ (WidgetClass) &coreClassRec, 269 /* superclass */ (WidgetClass) &coreClassRec,
238 /* class_name */ "XlwScrollBar", 270 /* class_name */ (String) "XlwScrollBar",
239 /* widget_size */ sizeof(XlwScrollBarRec), 271 /* widget_size */ sizeof(XlwScrollBarRec),
240 /* class_initialize */ NULL, 272 /* class_initialize */ NULL,
241 /* class_part_init */ NULL, 273 /* class_part_init */ NULL,
242 /* class_inited */ False, 274 /* class_inited */ False,
243 /* initialize */ Initialize, 275 /* initialize */ Initialize,
271 }, 303 },
272 }; 304 };
273 305
274 WidgetClass xlwScrollBarWidgetClass = (WidgetClass) &xlwScrollBarClassRec; 306 WidgetClass xlwScrollBarWidgetClass = (WidgetClass) &xlwScrollBarClassRec;
275 307
276 /*-------------------------- Debug Functions ----------------------------*/ 308 /************************************************************************
309 **
310 ** Debug funcitons
311 **
312 */
277 313
278 #ifdef SHOW_CLEAR 314 #ifdef SHOW_CLEAR
279 static void 315 static void myXClearArea(Display *dpy, Drawable d, int x, int y, int w, int h, Boolean exp, XlwScrollBarWidget widget)
280 myXClearArea(Display *dpy, Drawable d, int x, int y, int w, int h, 316 {
281 Boolean exp, XlwScrollBarWidget widget) 317 XFillRectangle(dpy, d, widget->sb.topShadowGC, x, y, w, h);
282 { 318 XSync(dpy, False);
283 XFillRectangle (dpy, d, widget->sb.topShadowGC, x, y, w, h); 319 sleep(2);
284 XSync (dpy, False); 320 XClearArea(dpy, d, x, y, w, h, exp);
285 sleep (2);
286 XClearArea (dpy, d, x, y, w, h, exp);
287 } 321 }
288 322
289 #define XClearArea(dpy,win,x,y,width,height,exp) myXClearArea(dpy,win,x,y,width,height,exp,w) 323 #define XClearArea(dpy,win,x,y,width,height,exp) myXClearArea(dpy,win,x,y,width,height,exp,w)
290 #endif 324 #endif
291 325
292 #ifdef CHECK_VALUES 326 #ifdef CHECK_VALUES
293 static void 327 static void check(XlwScrollBarWidget w)
294 check(XlwScrollBarWidget w) 328 {
295 { 329 int height;
296 int height = widget_h (w); 330
297 if (w->sb.showArrows) 331 height= widget_h(w);
298 height -= (2 * arrow_h (w)); 332 if( w->sb.showArrows ) height -= (2*arrow_h(w));
299 333
300 if ((w->sb.above + w->sb.ss + w->sb.below > height) || 334 if( (w->sb.above + w->sb.ss + w->sb.below > height) ||
301 (w->sb.value < w->sb.minimum) || 335 (w->sb.value < w->sb.minimum) ||
302 (w->sb.value > w->sb.maximum - w->sb.sliderSize)) 336 (w->sb.value > w->sb.maximum - w->sb.sliderSize )
303 { 337 )
338 {
304 printf("above=%d ss=%d below=%d height=%d\n", 339 printf("above=%d ss=%d below=%d height=%d\n",
305 w->sb.above, w->sb.ss, w->sb.below, height); 340 w->sb.above, w->sb.ss, w->sb.below, height);
306 printf("value=%d min=%d max=%d ss=%d max-ss=%d\n", 341 printf("value=%d min=%d max=%d ss=%d max-ss=%d\n",
307 w->sb.value, w->sb.minimum, w->sb.maximum, 342 w->sb.value, w->sb.minimum, w->sb.maximum, w->sb.sliderSize, w->sb.maximum - w->sb.sliderSize);
308 w->sb.sliderSize, w->sb.maximum - w->sb.sliderSize);
309 abort(); 343 abort();
310 } 344 }
311 } 345 }
312 346
313 # define CHECK(w) check(w) 347 # define CHECK(w) check(w)
314 #else 348 #else
315 # define CHECK(w) 349 # define CHECK(w)
316 #endif 350 #endif
317 351
318 /*-------------------------- Static functions ---------------------------*/ 352 /************************************************************************
319 353 **
320 static void 354 ** Static funcitons
321 call_callbacks (XlwScrollBarWidget w, int reason, 355 **
322 int value, int pixel, XEvent *event) 356 */
357
358 static void call_callbacks(XlwScrollBarWidget w, int reason, int value, int pixel,
359 XEvent *event)
323 { 360 {
324 XlwScrollBarCallbackStruct cbs; 361 XlwScrollBarCallbackStruct cbs;
325 Boolean called_anything; 362 Boolean called_anything;
326 363
327 cbs.reason = reason; 364 cbs.reason = reason;
328 cbs.event = event; 365 cbs.event = event;
329 cbs.value = value; 366 cbs.value = value;
330 cbs.pixel = pixel; 367 cbs.pixel = pixel;
331 368
332 called_anything = False; 369 called_anything = False;
333 370
334 switch (reason) 371 switch( reason )
335 { 372 {
336 case XmCR_VALUE_CHANGED: 373 case XmCR_VALUE_CHANGED:
337 XtCallCallbackList ((Widget) w, w->sb.valueChangedCBL, &cbs); 374 XtCallCallbackList( (Widget)w, w->sb.valueChangedCBL, &cbs );
338 called_anything = True;
339 break;
340 case XmCR_INCREMENT:
341 if (w->sb.incrementCBL)
342 {
343 XtCallCallbackList ((Widget) w, w->sb.incrementCBL, &cbs);
344 called_anything = True; 375 called_anything = True;
345 } 376 break;
346 break; 377 case XmCR_INCREMENT:
347 case XmCR_DECREMENT: 378 if( w->sb.incrementCBL )
348 if (w->sb.decrementCBL) 379 {
349 { 380 XtCallCallbackList( (Widget)w, w->sb.incrementCBL, &cbs );
350 XtCallCallbackList ((Widget) w, w->sb.decrementCBL, &cbs); 381 called_anything = True;
351 called_anything = True; 382 }
352 } 383 break;
353 break; 384 case XmCR_DECREMENT:
354 case XmCR_PAGE_INCREMENT: 385 if( w->sb.decrementCBL )
355 if (w->sb.incrementCBL) 386 {
356 { 387 XtCallCallbackList( (Widget)w, w->sb.decrementCBL, &cbs );
357 XtCallCallbackList ((Widget) w, w->sb.pageIncrementCBL, &cbs); 388 called_anything = True;
358 called_anything = True; 389 }
359 } 390 break;
360 break; 391 case XmCR_PAGE_INCREMENT:
361 case XmCR_PAGE_DECREMENT: 392 if( w->sb.incrementCBL )
362 if (w->sb.decrementCBL) 393 {
363 { 394 XtCallCallbackList( (Widget)w, w->sb.pageIncrementCBL, &cbs );
364 XtCallCallbackList ((Widget) w, w->sb.pageDecrementCBL, &cbs); 395 called_anything = True;
365 called_anything = True; 396 }
366 } 397 break;
367 break; 398 case XmCR_PAGE_DECREMENT:
368 case XmCR_TO_TOP: 399 if( w->sb.decrementCBL )
369 if (w->sb.toTopCBL) 400 {
370 { 401 XtCallCallbackList( (Widget)w, w->sb.pageDecrementCBL, &cbs );
371 XtCallCallbackList ((Widget) w, w->sb.toTopCBL, &cbs); 402 called_anything = True;
372 called_anything = True; 403 }
373 } 404 break;
374 break; 405 case XmCR_TO_TOP:
375 case XmCR_TO_BOTTOM: 406 if( w->sb.toTopCBL )
376 if (w->sb.toBottomCBL) 407 {
377 { 408 XtCallCallbackList( (Widget)w, w->sb.toTopCBL, &cbs );
378 XtCallCallbackList ((Widget) w, w->sb.toBottomCBL, &cbs); 409 called_anything = True;
379 called_anything = True; 410 }
380 } 411 break;
381 break; 412 case XmCR_TO_BOTTOM:
382 case XmCR_DRAG: 413 if( w->sb.toBottomCBL )
383 if (w->sb.dragCBL) 414 {
384 { 415 XtCallCallbackList( (Widget)w, w->sb.toBottomCBL, &cbs );
385 XtCallCallbackList ((Widget) w, w->sb.dragCBL, &cbs); 416 called_anything = True;
386 } 417 }
387 called_anything = True; /* Special Case */ 418 break;
388 break; 419 case XmCR_DRAG:
389 } 420 if( w->sb.dragCBL )
390 421 {
391 if (!called_anything) 422 XtCallCallbackList( (Widget)w, w->sb.dragCBL, &cbs );
392 { 423 }
424 called_anything = True; /* Special Case */
425 break;
426 }
427
428 if( !called_anything )
429 {
393 cbs.reason = XmCR_VALUE_CHANGED; 430 cbs.reason = XmCR_VALUE_CHANGED;
394 XtCallCallbackList ((Widget) w, w->sb.valueChangedCBL, &cbs); 431 XtCallCallbackList( (Widget)w, w->sb.valueChangedCBL, &cbs );
395 } 432 }
396 } 433 }
397 434
398 /* Widget sizes minus the shadow and highlight area */ 435 /*
399 436 ** Widget sizes minus the shadow and highlight area
400 static int 437 **
401 widget_x (XlwScrollBarWidget w) 438 */
402 { 439 static int widget_x(XlwScrollBarWidget w)
403 return w->sb.shadowThickness; 440 {
404 } 441 return( w->sb.shadowThickness );
405 442 }
406 static int 443
407 widget_y (XlwScrollBarWidget w) 444 static int widget_y(XlwScrollBarWidget w)
408 { 445 {
409 return w->sb.shadowThickness; 446 return( w->sb.shadowThickness );
410 } 447 }
411 448
412 static int 449 static int widget_w(XlwScrollBarWidget w)
413 widget_w (XlwScrollBarWidget w) 450 {
414 { 451 int width, x = w->sb.shadowThickness;
415 int x = w->sb.shadowThickness; 452
416 int width = (VERT (w) ? w->core.width : w->core.height) - (2 * x); 453 width = VERT(w) ? w->core.width : w->core.height;
417 return width > 1 ? width : 1; 454
418 } 455 if( width <= (2 * x) )
419 456 return( 1 );
420 static int 457 else
421 widget_h (XlwScrollBarWidget w) 458 return( width - (2 * x) );
422 { 459 }
423 int y = w->sb.shadowThickness; 460
424 int height = (VERT (w) ? w->core.height : w->core.width) - (2 * y); 461 static int widget_h(XlwScrollBarWidget w)
425 462 {
426 return height > 1 ? height : 1; 463 int height, y = w->sb.shadowThickness;
427 } 464
428 465 height = VERT(w) ? w->core.height : w->core.width;
429 static int 466
430 arrow_h (XlwScrollBarWidget w) 467 if( height <= (2 * y) )
431 { 468 return( 1 );
432 int width = widget_w (w); 469 else
433 int minimum_size = ((widget_h (w) - SS_MIN) / 2) - 1; 470 return( height - (2 * y) );
434 return minimum_size < width ? minimum_size : width; 471 }
435 } 472
436 473 static int arrow_h(XlwScrollBarWidget w)
437 static int 474 {
438 event_x (XlwScrollBarWidget w, XEvent *event) 475 int width, height;
439 { 476
440 return VERT (w) ? event->xbutton.x : event->xbutton.y; 477 width = widget_w(w);
441 } 478 height= widget_h(w);
442 479
443 static int 480 if( width > ((height / 2) - (SS_MIN / 2) - 1) )
444 event_y (XlwScrollBarWidget w, XEvent *event) 481 {
445 { 482 return( ((height / 2) - (SS_MIN / 2) - 1) );
446 return VERT (w) ? event->xbutton.y : event->xbutton.x; 483 }
447 } 484 else
448 485 {
449 /* Safe addition and subtraction */ 486 return( width );
450 static void 487 }
451 increment_value (XlwScrollBarWidget w, int diff) 488 }
452 { 489
453 w->sb.value = w->sb.maximum - diff < w->sb.value ? 490 static int event_x(XlwScrollBarWidget w, XEvent *event)
454 w->sb.maximum : 491 {
455 w->sb.value + diff; 492 return( VERT(w) ? event->xbutton.x : event->xbutton.y );
456 } 493 }
457 494
458 static void 495 static int event_y(XlwScrollBarWidget w, XEvent *event)
459 decrement_value (XlwScrollBarWidget w, int diff) 496 {
460 { 497 return( VERT(w) ? event->xbutton.y : event->xbutton.x );
461 w->sb.value = w->sb.minimum + diff > w->sb.value ? 498 }
462 w->sb.minimum : 499
463 w->sb.value - diff; 500 /*
464 } 501 ** Safe addition and subtraction
465 502 */
466 static SliderStyle 503 static int safe_add(int a, int b)
467 slider_style (XlwScrollBarWidget w) 504 {
468 { 505 if( a > 0 && INT_MAX - a < b ) return( INT_MAX );
469 return w->sb.sliderStyle && w->sb.sliderStyle[0] == 'd' ? 506 else return( a + b );
470 SLIDER_DIMPLE : 507 }
471 SLIDER_PLAIN; 508
472 } 509 static int safe_subtract(int a, int b)
473 510 {
474 static Boolean 511 if( a < 0 && -(INT_MIN - a) < b ) return( INT_MIN );
475 arrow_same_end (XlwScrollBarWidget w) 512 else return( a - b );
476 { 513 }
477 return w->sb.arrowPosition && w->sb.arrowPosition[0] == 's' ? True : False; 514
478 } 515 static int knob_style(XlwScrollBarWidget w)
479 516 {
480 /*-------------------------- GC and Pixel allocation --------------------*/ 517 if( w->sb.knobStyle )
481 static GC 518 {
482 get_gc (XlwScrollBarWidget w, Pixel fg, Pixel bg, Pixmap pm) 519 if( w->sb.knobStyle[0] == 'd' )
520 {
521 return( KNOB_DIMPLE );
522 }
523 }
524 return( KNOB_PLAIN );
525 }
526
527 static Boolean arrow_same_end(XlwScrollBarWidget w)
528 {
529 if( w->sb.arrowPosition && w->sb.arrowPosition[0] == 's' )
530 {
531 return( True );
532 }
533 return( False );
534 }
535
536 /*
537 ** GC and Pixel allocation
538 */
539 static GC get_gc(XlwScrollBarWidget w, Pixel fg, Pixel bg, Pixmap pm)
483 { 540 {
484 XGCValues values; 541 XGCValues values;
485 XtGCMask mask; 542 XtGCMask mask;
486 543
487 if (pm == w->sb.grayPixmap) 544 if (pm == w->sb.grayPixmap) {
488 {
489 /* If we're using the gray pixmap, guarantee white on black ... 545 /* If we're using the gray pixmap, guarantee white on black ...
490 * otherwise, we could end up with something odd like grey on white 546 * otherwise, we could end up with something odd like grey on white
491 * when we're on a color display that ran out of color cells 547 * when we're on a color display that ran out of color cells
492 */ 548 */
493 549
494 fg = WhitePixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); 550 fg = WhitePixelOfScreen(DefaultScreenOfDisplay(XtDisplay(w)));
495 bg = BlackPixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); 551 bg = BlackPixelOfScreen(DefaultScreenOfDisplay(XtDisplay(w)));
496 } 552 }
497 553
498 values.foreground = fg; 554 values.foreground = fg;
499 values.background = bg; 555 values.background = bg;
500 values.fill_style = FillOpaqueStippled; 556 values.fill_style = FillOpaqueStippled;
501 values.stipple = pm; 557 values.stipple = pm;
502 mask = GCForeground | GCBackground | 558 mask = GCForeground | GCBackground |
503 (pm == None ? 0 : GCStipple | GCFillStyle); 559 ( pm == None ? 0 : GCStipple | GCFillStyle );
504 return XtGetGC((Widget) w, mask, &values); 560 return( XtGetGC((Widget)w, mask, &values) );
505 } 561 }
506 562
507 /* Replacement for XAllocColor() that tries to return the nearest 563 /* Replacement for XAllocColor() that tries to return the nearest
508 available color if the colormap is full. From FSF Emacs. */ 564 available color if the colormap is full. From FSF Emacs. */
509 565
510 static int 566 static int
511 allocate_nearest_color (Display *display, Colormap screen_colormap, 567 allocate_nearest_color (Display *display, Colormap screen_colormap,
512 XColor *color_def) 568 XColor *color_def)
513 { 569 {
514 int status = XAllocColor (display, screen_colormap, color_def); 570 int status;
515 if (status) 571
516 return status; 572 status = XAllocColor (display, screen_colormap, color_def);
517 573 if (!status)
518 { 574 {
519 /* If we got to this point, the colormap is full, so we're 575 /* If we got to this point, the colormap is full, so we're
520 going to try to get the next closest color. 576 going to try and get the next closest color.
521 The algorithm used is a least-squares matching, which is 577 The algorithm used is a least-squares matching, which is
522 what X uses for closest color matching with StaticColor visuals. */ 578 what X uses for closest color matching with StaticColor visuals. */
523 579
524 int nearest, x; 580 XColor *cells;
525 unsigned long nearest_delta = ULONG_MAX; 581 int no_cells;
526 582 int nearest;
527 int no_cells = XDisplayCells (display, XDefaultScreen (display)); 583 long nearest_delta, trial_delta;
584 int x;
585
586 no_cells = XDisplayCells (display, XDefaultScreen (display));
528 /* Don't use alloca here because lwlib doesn't have the 587 /* Don't use alloca here because lwlib doesn't have the
529 necessary configuration information that src does. */ 588 necessary configuration information that src does. */
530 XColor *cells = (XColor *) malloc (sizeof (XColor) * no_cells); 589 cells = (XColor *) malloc (sizeof (XColor) * no_cells);
531 590
532 for (x = 0; x < no_cells; x++) 591 for (x = 0; x < no_cells; x++)
533 cells[x].pixel = x; 592 cells[x].pixel = x;
534 593
535 XQueryColors (display, screen_colormap, cells, no_cells); 594 XQueryColors (display, screen_colormap, cells, no_cells);
536 595 nearest = 0;
537 for (nearest = 0, x = 0; x < no_cells; x++) 596 /* I'm assuming CSE so I'm not going to condense this. */
597 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
598 * ((color_def->red >> 8) - (cells[0].red >> 8)))
599 +
600 (((color_def->green >> 8) - (cells[0].green >> 8))
601 * ((color_def->green >> 8) - (cells[0].green >> 8)))
602 +
603 (((color_def->blue >> 8) - (cells[0].blue >> 8))
604 * ((color_def->blue >> 8) - (cells[0].blue >> 8))));
605 for (x = 1; x < no_cells; x++)
538 { 606 {
539 long dred = (color_def->red >> 8) - (cells[x].red >> 8); 607 trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8))
540 long dgreen = (color_def->green >> 8) - (cells[x].green >> 8); 608 * ((color_def->red >> 8) - (cells[x].red >> 8)))
541 long dblue = (color_def->blue >> 8) - (cells[x].blue >> 8); 609 +
542 unsigned long delta = dred * dred + dgreen * dgreen + dblue * dblue; 610 (((color_def->green >> 8) - (cells[x].green >> 8))
543 611 * ((color_def->green >> 8) - (cells[x].green >> 8)))
544 if (delta < nearest_delta) 612 +
613 (((color_def->blue >> 8) - (cells[x].blue >> 8))
614 * ((color_def->blue >> 8) - (cells[x].blue >> 8))));
615 if (trial_delta < nearest_delta)
545 { 616 {
546 nearest = x; 617 nearest = x;
547 nearest_delta = delta; 618 nearest_delta = trial_delta;
548 } 619 }
549 } 620 }
550 color_def->red = cells[nearest].red; 621 color_def->red = cells[nearest].red;
551 color_def->green = cells[nearest].green; 622 color_def->green = cells[nearest].green;
552 color_def->blue = cells[nearest].blue; 623 color_def->blue = cells[nearest].blue;
624 status = XAllocColor (display, screen_colormap, color_def);
625
553 free (cells); 626 free (cells);
554 return XAllocColor (display, screen_colormap, color_def);
555 } 627 }
556 } 628
557 629 return status;
558 static void 630 }
559 make_shadow_pixels (XlwScrollBarWidget w) 631
632 static void make_shadow_pixels(XlwScrollBarWidget w)
560 { 633 {
561 Display *dpy = XtDisplay((Widget) w); 634 Display *dpy = XtDisplay((Widget) w);
562 Colormap cmap = w->core.colormap; 635 Colormap cmap = w->core.colormap;
563 XColor topc, botc; 636 XColor topc, botc;
564 int top_frobbed, bottom_frobbed; 637 int top_frobbed, bottom_frobbed;
567 top_frobbed = bottom_frobbed = 0; 640 top_frobbed = bottom_frobbed = 0;
568 641
569 bg = w->core.background_pixel; 642 bg = w->core.background_pixel;
570 fg = w->sb.foreground; 643 fg = w->sb.foreground;
571 644
572 if (w->sb.topShadowColor == (Pixel)~0) w->sb.topShadowColor = bg; 645 if( w->sb.topShadowColor == (Pixel)~0) w->sb.topShadowColor = bg;
573 if (w->sb.bottomShadowColor == (Pixel)~0) w->sb.bottomShadowColor = fg; 646 if( w->sb.bottomShadowColor == (Pixel)~0) w->sb.bottomShadowColor = fg;
574 647
575 if (w->sb.topShadowColor == bg || w->sb.topShadowColor == fg) 648 if( w->sb.topShadowColor == bg || w->sb.topShadowColor == fg )
576 { 649 {
577 topc.pixel = bg; 650 topc.pixel = bg;
578 XQueryColor (dpy, cmap, &topc); 651 XQueryColor( dpy, cmap, &topc );
579 /* don't overflow/wrap! */ 652 /* don't overflow/wrap! */
580 topc.red = MINL(65535, topc.red * 1.2); 653 topc.red = MINL(65535, topc.red * 1.2);
581 topc.green = MINL(65535, topc.green * 1.2); 654 topc.green = MINL(65535, topc.green * 1.2);
582 topc.blue = MINL(65535, topc.blue * 1.2); 655 topc.blue = MINL(65535, topc.blue * 1.2);
583 if (allocate_nearest_color (dpy, cmap, &topc)) 656 if( allocate_nearest_color(dpy, cmap, &topc) )
584 { 657 {
585 if (topc.pixel == bg) 658 if( topc.pixel == bg )
586 { 659 {
587 XFreeColors (dpy, cmap, &topc.pixel, 1, 0); 660 XFreeColors( dpy, cmap, &topc.pixel, 1, 0);
588 topc.red = MINL(65535, topc.red + 0x8000); 661 topc.red = MINL(65535, topc.red + 0x8000);
589 topc.green = MINL(65535, topc.green + 0x8000); 662 topc.green = MINL(65535, topc.green + 0x8000);
590 topc.blue = MINL(65535, topc.blue + 0x8000); 663 topc.blue = MINL(65535, topc.blue + 0x8000);
591 if (allocate_nearest_color (dpy, cmap, &topc)) 664 if( allocate_nearest_color(dpy, cmap, &topc) )
592 { 665 {
593 w->sb.topShadowColor = topc.pixel; 666 w->sb.topShadowColor = topc.pixel;
594 } 667 }
595 } 668 }
596 else 669 else
597 { 670 {
598 w->sb.topShadowColor = topc.pixel; 671 w->sb.topShadowColor = topc.pixel;
599 } 672 }
600 673
601 top_frobbed = 1; 674 top_frobbed = 1;
602 } 675 }
603 } 676 }
604 677
605 if (w->sb.bottomShadowColor == fg || w->sb.bottomShadowColor == bg) 678 if( w->sb.bottomShadowColor == fg || w->sb.bottomShadowColor == bg )
606 { 679 {
607 botc.pixel = bg; 680 botc.pixel = bg;
608 XQueryColor (dpy, cmap, &botc); 681 XQueryColor( dpy, cmap, &botc );
609 botc.red *= 0.6; 682 botc.red *= 0.6;
610 botc.green *= 0.6; 683 botc.green *= 0.6;
611 botc.blue *= 0.6; 684 botc.blue *= 0.6;
612 if (allocate_nearest_color (dpy, cmap, &botc)) 685 if( allocate_nearest_color(dpy, cmap, &botc) )
613 { 686 {
614 if (botc.pixel == bg) 687 if( botc.pixel == bg )
615 { 688 {
616 XFreeColors (dpy, cmap, &botc.pixel, 1, 0); 689 XFreeColors( dpy, cmap, &botc.pixel, 1, 0);
617 botc.red = MINL(65535, botc.red + 0x4000); 690 botc.red = MINL(65535, botc.red + 0x4000);
618 botc.green = MINL(65535, botc.green + 0x4000); 691 botc.green = MINL(65535, botc.green + 0x4000);
619 botc.blue = MINL(65535, botc.blue + 0x4000); 692 botc.blue = MINL(65535, botc.blue + 0x4000);
620 if (allocate_nearest_color (dpy, cmap, &botc)) 693 if( allocate_nearest_color(dpy, cmap, &botc) )
621 { 694 {
622 w->sb.bottomShadowColor = botc.pixel; 695 w->sb.bottomShadowColor = botc.pixel;
623 } 696 }
624 } 697 }
625 else 698 else
626 { 699 {
627 w->sb.bottomShadowColor = botc.pixel; 700 w->sb.bottomShadowColor = botc.pixel;
628 } 701 }
629 bottom_frobbed = 1; 702 bottom_frobbed = 1;
630 } 703 }
631 } 704 }
632 705
633 if (top_frobbed && bottom_frobbed) 706 if( top_frobbed && bottom_frobbed )
634 { 707 {
635 int top_avg = ((topc.red / 3) + (topc.green / 3) + (topc.blue / 3)); 708 int top_avg = ((topc.red / 3) + (topc.green / 3) + (topc.blue / 3));
636 int bot_avg = ((botc.red / 3) + (botc.green / 3) + (botc.blue / 3)); 709 int bot_avg = ((botc.red / 3) + (botc.green / 3) + (botc.blue / 3));
637 if (bot_avg > top_avg) 710 if( bot_avg > top_avg )
638 { 711 {
639 Pixel tmp = w->sb.topShadowColor; 712 Pixel tmp = w->sb.topShadowColor;
640 w->sb.topShadowColor = w->sb.bottomShadowColor; 713 w->sb.topShadowColor = w->sb.bottomShadowColor;
641 w->sb.bottomShadowColor = tmp; 714 w->sb.bottomShadowColor = tmp;
642 } 715 }
643 else if (topc.pixel == botc.pixel) 716 else if( topc.pixel == botc.pixel )
644 { 717 {
645 if (botc.pixel == bg) 718 if( botc.pixel == bg )
646 w->sb.topShadowColor = bg; 719 w->sb.topShadowColor = bg;
647 else 720 else
648 w->sb.bottomShadowColor = fg; 721 w->sb.bottomShadowColor = fg;
649 } 722 }
650 } 723 }
651 724
652 if (w->sb.topShadowColor == w->core.background_pixel || 725 if (w->sb.topShadowColor == w->core.background_pixel ||
653 w->sb.bottomShadowColor == w->core.background_pixel) 726 w->sb.bottomShadowColor == w->core.background_pixel) {
654 { 727
655 /* Assume we're in mono. This code should be okay even if we're 728 /* Assume we're in mono. This code should be okay even if we're
656 * really in color but just short on color cells -- We want the 729 * really in color but just short on color cells -- We want the
657 * following behavior, which has been empirically determined to 730 * following behavior, which has been empirically determined to
658 * work well for all fg/bg combinations in mono: If the trough 731 * work well for all fg/bg combinations in mono: If the trough
659 * and slider are BOTH black, then use a white top shadow and a 732 * and thumb are BOTH black, then use a white top shadow and a
660 * grey bottom shadow, otherwise use a grey top shadow and a 733 * grey bottom shadow, otherwise use a grey top shadow and a
661 * black bottom shadow. 734 * black bottom shadow.
662 */ 735 */
663 736
664 Pixel white = WhitePixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); 737 Pixel white = WhitePixelOfScreen(DefaultScreenOfDisplay(XtDisplay(w)));
665 Pixel black = BlackPixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); 738 Pixel black = BlackPixelOfScreen(DefaultScreenOfDisplay(XtDisplay(w)));
666 739
667 /* Note: core.background_pixel is the color of the slider ... */ 740 /* Note: core.background_pixel is the color of the thumb ... */
668 741
669 if (w->core.background_pixel == black && 742 if (w->core.background_pixel == black &&
670 w->sb.troughColor == black) 743 w->sb.troughColor == black) {
671 { 744
672 w->sb.topShadowColor = white; 745 w->sb.topShadowColor = white;
673 w->sb.bottomShadowPixmap = w->sb.grayPixmap; 746 w->sb.bottomShadowPixmap = w->sb.grayPixmap;
674 } else { 747
675 w->sb.topShadowPixmap = w->sb.grayPixmap; 748 } else {
676 w->sb.bottomShadowColor = black; 749
677 } 750 w->sb.topShadowPixmap = w->sb.grayPixmap;
678 } 751 w->sb.bottomShadowColor = black;
679 } 752 }
680 753
681 static void 754 }
682 make_trough_pixel (XlwScrollBarWidget w) 755
756
757 }
758
759 static void make_trough_pixel(XlwScrollBarWidget w)
683 { 760 {
684 Display *dpy = XtDisplay((Widget) w); 761 Display *dpy = XtDisplay((Widget) w);
685 Colormap cmap = DefaultColormapOfScreen (XtScreen ((Widget) w)); 762 Colormap cmap = DefaultColormapOfScreen( XtScreen((Widget)w) );
686 XColor troughC; 763 XColor troughC;
687 764
688 if (w->sb.troughColor == (Pixel)~0) w->sb.troughColor = w->core.background_pixel; 765 if( w->sb.troughColor == (Pixel)~0) w->sb.troughColor = w->core.background_pixel;
689 766
690 if (w->sb.troughColor == w->core.background_pixel) 767 if( w->sb.troughColor == w->core.background_pixel )
691 { 768 {
692 troughC.pixel = w->core.background_pixel; 769 troughC.pixel = w->core.background_pixel;
693 XQueryColor (dpy, cmap, &troughC); 770 XQueryColor( dpy, cmap, &troughC );
694 troughC.red *= 0.8; 771 troughC.red *= 0.8;
695 troughC.green *= 0.8; 772 troughC.green *= 0.8;
696 troughC.blue *= 0.8; 773 troughC.blue *= 0.8;
697 if (allocate_nearest_color (dpy, cmap, &troughC)) 774 if( allocate_nearest_color(dpy, cmap, &troughC) )
698 w->sb.troughColor = troughC.pixel; 775 {
699 } 776 w->sb.troughColor = troughC.pixel;
700 } 777 }
701 778 }
702 /*-------------------------- Draw 3D Border -----------------------------*/ 779 }
703 static void 780
704 draw_shadows (Display *dpy, Drawable d, GC shine_gc, GC shadow_gc, 781 /*
705 int x, int y, int width, int height, int shadowT) 782 ** Draw 3d border
706 { 783 */
707 XSegment shine[10], shadow[10]; 784 static void draw_shadows(Display *dpy, Drawable d,
785 GC shine_gc, GC shadow_gc,
786 int x, int y, int width, int height,
787 int shadowT)
788 {
789 XSegment shine[10], shadow[10];
790 int i;
791
792 if(shadowT > (width / 2)) shadowT = (width / 2);
793 if(shadowT > (height / 2)) shadowT = (height / 2);
794 if(shadowT <= 0) return;
795
796 for(i = 0; i < shadowT; i++)
797 {
798 /* Top segments */
799 shine[i].x1 = x;
800 shine[i].y2 = shine[i].y1 = y + i;
801 shine[i].x2 = x + width - i - 1;
802 /* Left segments */
803 shine[i + shadowT].x2 = shine[i + shadowT].x1 = x + i;
804 shine[i + shadowT].y1 = y + shadowT;
805 shine[i + shadowT].y2 = y + height - i - 1;
806
807 /* Bottom segments */
808 shadow[i].x1 = x + i;
809 shadow[i].y2 = shadow[i].y1 = y + height - i - 1;
810 shadow[i].x2 = x + width - 1 ;
811 /* Right segments */
812 shadow[i + shadowT].x2 = shadow[i + shadowT].x1 = x + width - i - 1;
813 shadow[i + shadowT].y1 = y + i + 1;
814 shadow[i + shadowT].y2 = y + height - 1 ;
815 }
816
817 XDrawSegments( dpy, d, shine_gc, shine, shadowT * 2 );
818 XDrawSegments( dpy, d, shadow_gc, shadow, shadowT * 2 );
819 }
820
821 /*
822 ** Draw 3d arrows, left, up, down, and right
823 */
824 static int make_vert_seg(XSegment *seg, int x1, int y1, int x2, int y2, int shadowT)
825 {
708 int i; 826 int i;
709 827
710 if (shadowT > (width / 2)) shadowT = (width / 2); 828 for(i=0; i<shadowT; i++)
711 if (shadowT > (height / 2)) shadowT = (height / 2); 829 {
712 if (shadowT <= 0) return; 830 seg[i].x1 = x1;
713 831 seg[i].y1 = y1 + i;
714 for (i = 0; i < shadowT; i++) 832 seg[i].x2 = x2;
715 { 833 seg[i].y2 = y2 + i;
716 /* Top segments */ 834 }
717 shine[i].x1 = x; 835 return( shadowT );
718 shine[i].y2 = shine[i].y1 = y + i; 836 }
719 shine[i].x2 = x + width - i - 1; 837
720 /* Left segments */ 838 static int make_hor_seg(XSegment *seg, int x1, int y1, int x2, int y2, int shadowT)
721 shine[i + shadowT].x2 = shine[i + shadowT].x1 = x + i;
722 shine[i + shadowT].y1 = y + shadowT;
723 shine[i + shadowT].y2 = y + height - i - 1;
724
725 /* Bottom segments */
726 shadow[i].x1 = x + i;
727 shadow[i].y2 = shadow[i].y1 = y + height - i - 1;
728 shadow[i].x2 = x + width - 1 ;
729 /* Right segments */
730 shadow[i + shadowT].x2 = shadow[i + shadowT].x1 = x + width - i - 1;
731 shadow[i + shadowT].y1 = y + i + 1;
732 shadow[i + shadowT].y2 = y + height - 1 ;
733 }
734
735 XDrawSegments (dpy, d, shine_gc, shine, shadowT * 2);
736 XDrawSegments (dpy, d, shadow_gc, shadow, shadowT * 2);
737 }
738
739 /*------------------ Draw 3D Arrows: left, up, down, right --------------*/
740 static int
741 make_vert_seg (XSegment *seg, int x1, int y1, int x2, int y2, int shadowT)
742 { 839 {
743 int i; 840 int i;
744 841
745 for (i=0; i<shadowT; i++, seg++) 842 for(i=0; i<shadowT; i++)
746 { 843 {
747 seg->x1 = x1; 844 seg[i].x1 = x1 + i;
748 seg->y1 = y1++; 845 seg[i].y1 = y1;
749 seg->x2 = x2; 846 seg[i].x2 = x2 + i;
750 seg->y2 = y2++; 847 seg[i].y2 = y2;
751 } 848 }
752 return shadowT; 849 return( shadowT );
753 } 850 }
754 851
755 static int 852 static void draw_arrow_up(Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC,
756 make_hor_seg (XSegment *seg, int x1, int y1, int x2, int y2, int shadowT) 853 int x, int y, int width, int height, int shadowT)
757 {
758 int i;
759
760 for (i=0; i<shadowT; i++, seg++)
761 {
762 seg->x1 = x1++;
763 seg->y1 = y1;
764 seg->x2 = x2++;
765 seg->y2 = y2;
766 }
767 return shadowT;
768 }
769
770 static void
771 draw_arrow_up (Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC,
772 int x, int y, int width, int height, int shadowT)
773 { 854 {
774 XSegment shine[10], shadow[10]; 855 XSegment shine[10], shadow[10];
775 XPoint triangle[3]; 856 XPoint triangle[3];
776 int mid; 857 int mid;
777 858
778 mid = width / 2; 859 mid = width / 2;
779 860
780 if (shadowT > (width / 2)) shadowT = (width / 2); 861 if(shadowT > (width / 2)) shadowT = (width / 2);
781 if (shadowT > (height / 2)) shadowT = (height / 2); 862 if(shadowT > (height / 2)) shadowT = (height / 2);
782 if (shadowT < 0) shadowT = 0; 863 if(shadowT <= 0) shadowT = 0;
783 864
784 /* / */ 865 /* / */
785 make_vert_seg (shine, 866 make_vert_seg( shine,
786 x, y + height - shadowT - 1, 867 x, y + height - shadowT - 1,
787 x + mid, y, shadowT); 868 x + mid, y, shadowT );
788 /* _\ */ 869 /* _\ */
789 make_vert_seg (shadow, 870 make_vert_seg( shadow,
790 x, y + height - shadowT - 1, 871 x, y + height - shadowT - 1,
791 x + width - 1, y + height - shadowT - 1, shadowT); 872 x + width - 1, y + height - shadowT - 1, shadowT );
792 make_vert_seg (shadow + shadowT, 873 make_vert_seg( shadow + shadowT,
793 x + mid, y, 874 x + mid, y,
794 x + width - 1, y + height - shadowT - 1, shadowT); 875 x + width - 1, y + height - shadowT - 1, shadowT );
795 876
796 triangle[0].x = x; 877 triangle[0].x = x;
797 triangle[0].y = y + height - 1; 878 triangle[0].y = y + height - 1;
798 triangle[1].x = x + mid; 879 triangle[1].x = x + mid;
799 triangle[1].y = y; 880 triangle[1].y = y;
800 triangle[2].x = x + width - 1; 881 triangle[2].x = x + width - 1;
801 triangle[2].y = y + height - 1; 882 triangle[2].y = y + height - 1;
802 883
803 XFillPolygon (dpy, win, bgGC, triangle, 3, Convex, ArcChord); 884 XFillPolygon( dpy, win, bgGC, triangle, 3, Convex, ArcChord );
804 885
805 XDrawSegments (dpy, win, shadowGC, shadow, shadowT * 2); 886 XDrawSegments( dpy, win, shadowGC, shadow, shadowT * 2 );
806 XDrawSegments (dpy, win, shineGC, shine, shadowT); 887 XDrawSegments( dpy, win, shineGC, shine, shadowT );
807 } 888 }
808 889
809 static void 890 static void draw_arrow_left(Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC,
810 draw_arrow_left (Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC, 891 int x, int y, int width, int height, int shadowT)
811 int x, int y, int width, int height, int shadowT)
812 { 892 {
813 XSegment shine[10], shadow[10]; 893 XSegment shine[10], shadow[10];
814 XPoint triangle[3]; 894 XPoint triangle[3];
815 895 int mid;
816 int mid = width / 2; 896
817 897 mid = width / 2;
818 if (shadowT > (width / 2)) shadowT = (width / 2); 898
819 if (shadowT > (height / 2)) shadowT = (height / 2); 899 if(shadowT > (width / 2)) shadowT = (width / 2);
820 if (shadowT < 0) shadowT = 0; 900 if(shadowT > (height / 2)) shadowT = (height / 2);
901 if(shadowT <= 0) shadowT = 0;
821 902
822 /* / */ 903 /* / */
823 make_hor_seg (shine, 904 make_hor_seg( shine,
824 x, y + mid, 905 x, y + mid,
825 x + width - shadowT - 1, y, shadowT); 906 x + width - shadowT - 1, y, shadowT );
826 /* \| */ 907 /* \| */
827 make_hor_seg (shadow, 908 make_hor_seg( shadow,
828 x, y + mid, 909 x, y + mid,
829 x + width - shadowT - 1, y + height - 1, shadowT); 910 x + width - shadowT - 1, y + height - 1, shadowT );
830 make_hor_seg (shadow + shadowT, 911 make_hor_seg( shadow + shadowT,
831 x + width - shadowT - 1, y, 912 x + width - shadowT - 1, y,
832 x + width - shadowT - 1, y + height - 1, shadowT); 913 x + width - shadowT - 1, y + height - 1, shadowT );
833 914
834 triangle[0].x = x + width - 1; 915 triangle[0].x = x + width - 1;
835 triangle[0].y = y + height - 1; 916 triangle[0].y = y + height - 1;
836 triangle[1].x = x; 917 triangle[1].x = x;
837 triangle[1].y = y + mid; 918 triangle[1].y = y + mid;
838 triangle[2].x = x + width - 1; 919 triangle[2].x = x + width - 1;
839 triangle[2].y = y; 920 triangle[2].y = y;
840 921
841 XFillPolygon (dpy, win, bgGC, triangle, 3, Convex, ArcChord); 922 XFillPolygon( dpy, win, bgGC, triangle, 3, Convex, ArcChord );
842 923
843 XDrawSegments (dpy, win, shadowGC, shadow, shadowT * 2); 924 XDrawSegments( dpy, win, shadowGC, shadow, shadowT * 2 );
844 XDrawSegments (dpy, win, shineGC, shine, shadowT); 925 XDrawSegments( dpy, win, shineGC, shine, shadowT );
845 } 926 }
846 927
847 static void 928 static void draw_arrow_down(Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC,
848 draw_arrow_down (Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC, 929 int x, int y, int width, int height, int shadowT)
849 int x, int y, int width, int height, int shadowT)
850 { 930 {
851 XSegment shine[10], shadow[10]; 931 XSegment shine[10], shadow[10];
852 XPoint triangle[3]; 932 XPoint triangle[3];
853 int mid; 933 int mid;
854 934
855 mid = width / 2; 935 mid = width / 2;
856 936
857 if (shadowT > (width / 2)) shadowT = (width / 2); 937 if(shadowT > (width / 2)) shadowT = (width / 2);
858 if (shadowT > (height / 2)) shadowT = (height / 2); 938 if(shadowT > (height / 2)) shadowT = (height / 2);
859 if (shadowT < 0) shadowT = 0; 939 if(shadowT <= 0) shadowT = 0;
860 940
861 /* \- */ 941 /* \- */
862 make_vert_seg (shine, 942 make_vert_seg( shine,
863 x, y, 943 x, y,
864 x + mid, y + height - shadowT - 1, shadowT); 944 x + mid, y + height - shadowT - 1, shadowT );
865 make_vert_seg (shine + shadowT, 945 make_vert_seg( shine + shadowT,
866 x, y, 946 x, y,
867 x + width - 1, y, shadowT); 947 x + width - 1, y, shadowT );
868 /* / */ 948 /* / */
869 make_vert_seg (shadow, 949 make_vert_seg( shadow,
870 x + width - 1, y, 950 x + width - 1, y,
871 x + mid, y + height - shadowT - 1, shadowT); 951 x + mid, y + height - shadowT - 1, shadowT );
872 952
873 triangle[0].x = x; 953 triangle[0].x = x;
874 triangle[0].y = y; 954 triangle[0].y = y;
875 triangle[1].x = x + mid; 955 triangle[1].x = x + mid;
876 triangle[1].y = y + height - 1; 956 triangle[1].y = y + height - 1;
877 triangle[2].x = x + width - 1; 957 triangle[2].x = x + width - 1;
878 triangle[2].y = y; 958 triangle[2].y = y;
879 959
880 XFillPolygon (dpy, win, bgGC, triangle, 3, Convex, ArcChord); 960 XFillPolygon( dpy, win, bgGC, triangle, 3, Convex, ArcChord );
881 961
882 XDrawSegments (dpy, win, shadowGC, shadow, shadowT); 962 XDrawSegments( dpy, win, shadowGC, shadow, shadowT );
883 XDrawSegments (dpy, win, shineGC, shine, shadowT * 2); 963 XDrawSegments( dpy, win, shineGC, shine, shadowT * 2 );
884 } 964 }
885 965
886 static void 966 static void draw_arrow_right(Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC,
887 draw_arrow_right (Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC, 967 int x, int y, int width, int height, int shadowT)
888 int x, int y, int width, int height, int shadowT)
889 { 968 {
890 XSegment shine[10], shadow[10]; 969 XSegment shine[10], shadow[10];
891 XPoint triangle[3]; 970 XPoint triangle[3];
892 int mid; 971 int mid;
893 972
894 mid = width / 2; 973 mid = width / 2;
895 974
896 if (shadowT > (width / 2)) shadowT = (width / 2); 975 if(shadowT > (width / 2)) shadowT = (width / 2);
897 if (shadowT > (height / 2)) shadowT = (height / 2); 976 if(shadowT > (height / 2)) shadowT = (height / 2);
898 if (shadowT < 0) shadowT = 0; 977 if(shadowT <= 0) shadowT = 0;
899 978
900 /* |\ */ 979 /* |\ */
901 make_hor_seg (shine, 980 make_hor_seg( shine,
981 x, y,
982 x + width - shadowT - 1, y + mid, shadowT );
983 make_hor_seg( shine + shadowT,
902 x, y, 984 x, y,
903 x + width - shadowT - 1, y + mid, shadowT); 985 x, y + height -1, shadowT );
904 make_hor_seg (shine + shadowT,
905 x, y,
906 x, y + height - 1, shadowT);
907 /* / */ 986 /* / */
908 make_hor_seg (shadow, 987 make_hor_seg( shadow,
909 x, y + height - 1, 988 x, y + height -1,
910 x + width - shadowT - 1, y + mid, shadowT); 989 x + width - shadowT - 1, y + mid, shadowT );
911 990
912 triangle[0].x = x + 1; 991 triangle[0].x = x + 1;
913 triangle[0].y = y + height - 1; 992 triangle[0].y = y + height - 1;
914 triangle[1].x = x + width - 1; 993 triangle[1].x = x + width - 1;
915 triangle[1].y = y + mid; 994 triangle[1].y = y + mid;
916 triangle[2].x = x + 1; 995 triangle[2].x = x + 1;
917 triangle[2].y = y; 996 triangle[2].y = y;
918 997
919 XFillPolygon (dpy, win, bgGC, triangle, 3, Convex, ArcChord); 998 XFillPolygon( dpy, win, bgGC, triangle, 3, Convex, ArcChord );
920 999
921 XDrawSegments (dpy, win, shadowGC, shadow, shadowT); 1000 XDrawSegments( dpy, win, shadowGC, shadow, shadowT );
922 XDrawSegments (dpy, win, shineGC, shine, shadowT * 2); 1001 XDrawSegments( dpy, win, shineGC, shine, shadowT * 2 );
923 } 1002 }
924 1003
925 static void 1004 static void draw_dimple(Display *dpy, Drawable win, GC shine, GC shadow,
926 draw_dimple (Display *dpy, Drawable win, GC shine, GC shadow, 1005 int x, int y, int width, int height)
927 int x, int y, int width, int height) 1006 {
928 { 1007 XDrawArc(dpy, win, shine, x, y, width, height, 46*64, 180*64);
929 XDrawArc (dpy, win, shine, x, y, width, height, 46*64, 180*64); 1008 XDrawArc(dpy, win, shadow, x, y, width, height, 45*64, -179*64);
930 XDrawArc (dpy, win, shadow, x, y, width, height, 45*64, -179*64); 1009 }
931 } 1010
932 1011 /*
933 /*------- Scrollbar values -> pixels, pixels -> scrollbar values --------*/ 1012 ** Scrollbar values -> pixels, pixels -> scrollbar values
934 1013 */
935 static void 1014
936 seg_pixel_sizes (XlwScrollBarWidget w, int *above_return, 1015 static void seg_pixel_sizes(XlwScrollBarWidget w, int *above_return, int *ss_return,
937 int *ss_return, int *below_return) 1016 int *below_return)
938 { 1017 {
939 float total, height, fuz; 1018 float total, height, fuz;
940 int value; 1019 int value;
941 int above, ss, below; 1020 int above, ss, below;
942 1021
943 height= widget_h (w); 1022 height= widget_h(w);
944 if (w->sb.showArrows) height -= (2 * arrow_h (w)); 1023 if( w->sb.showArrows ) height -= (2*arrow_h(w));
945 1024
946 value = w->sb.value - w->sb.minimum; 1025 value = w->sb.value - w->sb.minimum;
947 1026
948 total = w->sb.maximum - w->sb.minimum; 1027 total = w->sb.maximum - w->sb.minimum;
949 fuz = total / 2; 1028 fuz = total / 2;
950 1029
951 ss = ((height * w->sb.sliderSize + fuz) / total); 1030 ss = ((height * w->sb.sliderSize + fuz) / total);
952 above = ((height * value + fuz) / total); 1031 above = ((height * value + fuz) / total);
953 below = ((height) - (ss + above)); 1032 below = ((height) - (ss + above));
954 1033
955 /* Don't let slider get smaller than SS_MIN */ 1034 /* Dont' let knob get smaller than SS_MIN */
956 if (ss < SS_MIN) 1035 if( ss < SS_MIN )
957 { 1036 {
958 /* add a percent amount for integer rounding */ 1037 /* add a percent amount for interger rounding */
959 float tmp = ((((float) (SS_MIN - ss) * (float) value)) / total) + 0.5; 1038 float tmp = ((((float)(SS_MIN - ss) * (float)value)) / total) + 0.5;
960 1039
961 above -= (int) tmp; 1040 above -= (int)tmp;
962 ss = SS_MIN; 1041 ss = SS_MIN;
963 below = ((height) - (ss + above)); 1042 below = ((height) - (ss + above));
964 1043
965 if (above < 0) 1044 if( above < 0 )
966 { 1045 {
967 above = 0; 1046 above = 0;
968 below = height - ss; 1047 below = height - ss;
969 } 1048 }
970 if (below < 0) 1049 if( below < 0 )
971 { 1050 {
972 above = height - ss; 1051 above = height - ss;
973 below = 0; 1052 below = 0;
974 } 1053 }
975 if (ss > height) 1054 if( ss > height )
976 { 1055 {
977 above = 0; 1056 above = 0;
978 ss = height; 1057 ss = height;
979 below = 0; 1058 below = 0;
980 } 1059 }
981 } 1060 }
982 1061
983 *above_return = above; 1062 *above_return = above;
984 *ss_return = ss; 1063 *ss_return = ss;
985 *below_return = below; 1064 *below_return = below;
986 1065
987 CHECK (w); 1066 CHECK(w);
988 } 1067 }
989 1068
990 static void 1069 static void verify_values(XlwScrollBarWidget w)
991 verify_values (XlwScrollBarWidget w)
992 { 1070 {
993 int total = w->sb.maximum - w->sb.minimum; 1071 int total = w->sb.maximum - w->sb.minimum;
994 1072
995 if (w->sb.sliderSize > total) 1073 if( w->sb.sliderSize > total )
1074 {
996 w->sb.sliderSize = total; 1075 w->sb.sliderSize = total;
997 1076 }
998 if (w->sb.pageIncrement > total) 1077 if( w->sb.pageIncrement > total )
1078 {
999 w->sb.pageIncrement = total; 1079 w->sb.pageIncrement = total;
1000 1080 }
1001 if (w->sb.increment > total) 1081 if( w->sb.increment > total )
1082 {
1002 w->sb.increment = total; 1083 w->sb.increment = total;
1003 1084 }
1004 if (w->sb.value < w->sb.minimum) 1085 if( w->sb.value < w->sb.minimum )
1086 {
1005 w->sb.value = w->sb.minimum; 1087 w->sb.value = w->sb.minimum;
1006 1088 }
1007 if (w->sb.value > w->sb.maximum) 1089 if( w->sb.value > w->sb.maximum - w->sb.sliderSize)
1008 w->sb.value = w->sb.maximum; 1090 {
1009 1091 w->sb.value = w->sb.maximum - w->sb.sliderSize;
1010 if (w->sb.sliderSize > w->sb.maximum - w->sb.value) 1092 }
1011 w->sb.sliderSize = w->sb.maximum - w->sb.value; 1093 }
1012 } 1094
1013 1095 static int value_from_pixel(XlwScrollBarWidget w, int above)
1014 static int
1015 value_from_pixel (XlwScrollBarWidget w, int above)
1016 { 1096 {
1017 float total, height, fuz; 1097 float total, height, fuz;
1018 int value, ss; 1098 int value, ss;
1019 1099
1020 height = widget_h (w); 1100 height= widget_h(w);
1021 if (w->sb.showArrows) 1101 if( w->sb.showArrows ) height -= (2*arrow_h(w));
1022 height -= (2 * arrow_h (w));
1023 1102
1024 total = w->sb.maximum - w->sb.minimum; 1103 total = w->sb.maximum - w->sb.minimum;
1025 fuz = height / 2; 1104 fuz = height / 2;
1026 1105
1027 ss = ((height * w->sb.sliderSize + (total / 2)) / total); 1106 ss = ((height * w->sb.sliderSize + (total / 2)) / total);
1028 1107
1029 if (ss < SS_MIN) 1108 if( ss < SS_MIN )
1030 { 1109 {
1031 /* add a percent amount for integer rounding */ 1110 /* add a percent amount for interger rounding */
1032 above += ((((SS_MIN - ss) * above) + fuz) / height); 1111 above += ((((SS_MIN - ss) * above) + fuz) / height);
1033 } 1112 }
1034 1113
1035 { 1114 {
1036 /* Prevent SIGFPE's that would occur if we don't truncate the value. */ 1115 /* Prevent SIGFPE's that would occur if we don't truncate the
1037 float floatval = w->sb.minimum + ((float)(above * total + fuz) / height); 1116 value. */
1117 float floatval = w->sb.minimum + ((float)(above * total + fuz ) / height);
1038 if (floatval >= (float) INT_MAX) 1118 if (floatval >= (float) INT_MAX)
1039 value = INT_MAX; 1119 value = INT_MAX;
1040 else if (floatval <= (float) INT_MIN) 1120 else if (floatval <= (float) INT_MIN)
1041 value = INT_MIN; 1121 value = INT_MIN;
1042 else 1122 else
1043 value = floatval; 1123 value = floatval;
1044 } 1124 }
1045 1125
1046 return value; 1126 return( value );
1047 } 1127 }
1048 1128
1049 1129
1050 static void 1130 static void redraw_dimple(XlwScrollBarWidget w, Display *dpy, Window win,
1051 redraw_dimple (XlwScrollBarWidget w, Display *dpy, Window win, 1131 int x, int y, int width, int height)
1052 int x, int y, int width, int height) 1132 {
1053 { 1133 GC shine, shadow;
1054 if (SLIDER_DIMPLE == slider_style (w)) 1134 int shadowT, size;
1055 { 1135
1056 int size; 1136 if( KNOB_DIMPLE == knob_style(w) )
1057 int slider_p = (w->sb.armed == ARM_SLIDER); 1137 {
1058 GC shine = slider_p ? w->sb.bottomShadowGC : w->sb.topShadowGC; 1138 if( w->sb.armed == ARM_KNOB )
1059 GC shadow = slider_p ? w->sb.topShadowGC : w->sb.bottomShadowGC; 1139 {
1060 int shadowT = w->sb.shadowThickness; 1140 shine = w->sb.bottomShadowGC;
1141 shadow = w->sb.topShadowGC;
1142 }
1143 else
1144 {
1145 shine = w->sb.topShadowGC;
1146 shadow = w->sb.bottomShadowGC;
1147 }
1148
1149 shadowT = w->sb.shadowThickness;
1061 1150
1062 x += shadowT; 1151 x += shadowT;
1063 y += shadowT; 1152 y += shadowT;
1064 width -= 2*shadowT; 1153 width -= 2*shadowT;
1065 height -= 2*shadowT; 1154 height -= 2*shadowT;
1066 1155
1067 size = (width < height ? width : height) * 3 / 4; 1156 size = (width < height ? width : height) * 3 / 4;
1068 1157
1069 if (size%2 != (width < height ? width : height)%2) size--; 1158 if( size%2 != (width < height ? width : height)%2 ) size--;
1070 1159
1071 DBUG (fprintf (stderr, "%d %d\n", 1160 DBUG (fprintf(stderr, "%d %d\n",
1072 x + (width / 2) - (size / 2) - 2*shadowT, 1161 x + (width / 2) - (size / 2) - 2*shadowT,
1073 width - size - shadowT)); 1162 width - size - shadowT));
1074 1163
1075 draw_dimple (dpy, win, shine, shadow, 1164 draw_dimple( dpy, win, shine, shadow,
1076 x + (width / 2) - (size / 2), 1165 x + (width / 2) - (size / 2),
1077 y + (height / 2) - (size / 2), 1166 y + (height / 2) - (size / 2),
1078 size, size); 1167 size, size );
1079 } 1168 }
1080 } 1169 }
1081 1170
1082 static void 1171 static void draw_knob(XlwScrollBarWidget w, int above, int ss, int below)
1083 draw_slider (XlwScrollBarWidget w, int above, int ss, int below) 1172 {
1084 { 1173 Display *dpy = XtDisplay((Widget)w);
1085 Display *dpy = XtDisplay ((Widget) w); 1174 Window win = XtWindow((Widget)w);
1086 Window win = XtWindow ((Widget) w); 1175 int x, y, width, height;
1087 1176 int shadowT;
1088 int x = widget_x (w); 1177
1089 int y = widget_y (w); 1178 x = widget_x(w);
1090 int width = widget_w (w); 1179 y = widget_y(w);
1091 int height = widget_h (w); 1180 width = widget_w(w);
1092 int shadowT = w->sb.shadowThickness; 1181 height = widget_h(w);
1093 int vert_p = VERT (w); 1182
1094 1183 shadowT = w->sb.shadowThickness;
1095 if (shadowT > (width / 2)) shadowT = (width / 2); 1184
1096 if (shadowT > (height / 2)) shadowT = (height / 2); 1185 if(shadowT > (width / 2)) shadowT = (width / 2);
1097 if (shadowT < 0) shadowT = 0; 1186 if(shadowT > (height / 2)) shadowT = (height / 2);
1098 1187 if(shadowT <= 0) return;
1099 if (w->sb.showArrows && !arrow_same_end (w)) 1188
1100 y += arrow_h (w); 1189 if( w->sb.showArrows && !arrow_same_end(w) ) y += (arrow_h(w));
1101 1190
1102 /* trough above slider */ 1191 /* trough above knob */
1103 if (above > 0) 1192 if( above > 0 )
1104 { 1193 {
1105 if (vert_p) 1194 if( VERT(w) )
1106 XClearArea (dpy, win, x, y, width, above, False); 1195 XClearArea( dpy, win, x, y, width, above, False );
1107 else 1196 else
1108 XClearArea (dpy, win, y, x, above, width, False); 1197 XClearArea( dpy, win, y, x, above, width, False );
1109 } 1198 }
1110 1199
1111 /* slider */ 1200 /* knob */
1112 if (vert_p) 1201 if( VERT(w) )
1113 { 1202 {
1114 draw_shadows (dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC, 1203 draw_shadows( dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC,
1115 x, y + above, width, ss, shadowT); 1204 x, y + above, width, ss, shadowT);
1116 XFillRectangle (dpy, win, w->sb.backgroundGC, 1205 XFillRectangle( dpy, win,
1117 x+shadowT, y + above + shadowT, 1206 w->sb.backgroundGC,
1118 width-2*shadowT, ss-2*shadowT); 1207 x+shadowT, y + above + shadowT, width-2*shadowT, ss-2*shadowT );
1119 redraw_dimple (w, dpy, win, x, y + above, width, ss); 1208 redraw_dimple(w, dpy, win, x, y + above, width, ss);
1120 } 1209 }
1121 else 1210 else
1122 { 1211 {
1123 draw_shadows (dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC, 1212 draw_shadows( dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC,
1124 y + above, x, ss, width, shadowT); 1213 y + above, x, ss, width, shadowT);
1125 XFillRectangle (dpy, win, w->sb.backgroundGC, 1214 XFillRectangle( dpy, win,
1126 y + above + shadowT, x+shadowT, 1215 w->sb.backgroundGC,
1127 ss-2*shadowT, width-2*shadowT); 1216 y + above + shadowT, x+shadowT, ss-2*shadowT, width-2*shadowT );
1128 redraw_dimple (w, dpy, win, y + above, x, ss, width); 1217 redraw_dimple(w, dpy, win, y + above, x, ss, width);
1129 } 1218 }
1130 1219
1131 /* trough below slider */ 1220 /* trough below knob */
1132 if (below > 0) 1221 if( below > 0 )
1133 { 1222 {
1134 if (vert_p) 1223 if( VERT(w) )
1135 XClearArea (dpy, win, x, y + above + ss, width, below, False); 1224 XClearArea( dpy, win, x, y + above + ss, width, below, False );
1136 else 1225 else
1137 XClearArea (dpy, win, y + above + ss, x, below, width, False); 1226 XClearArea( dpy, win, y + above + ss, x, below, width, False );
1138 } 1227 }
1139 1228
1140 CHECK (w); 1229 CHECK(w);
1141 } 1230 }
1142 1231
1143 static void 1232 static void redraw_up_arrow(XlwScrollBarWidget w, Boolean armed, Boolean clear_behind)
1144 redraw_up_arrow (XlwScrollBarWidget w, Boolean armed, Boolean clear_behind) 1233 {
1145 { 1234 Display *dpy = XtDisplay((Widget)w);
1146 Display *dpy = XtDisplay ((Widget) w); 1235 Window win = XtWindow((Widget)w);
1147 Window win = XtWindow ((Widget) w); 1236 GC bg, shine, shadow;
1148 1237 int x, y, width, height, arrow_height, shadowT;
1149 int x = widget_x (w); 1238
1150 int y = widget_y (w); 1239 x = widget_x(w);
1151 int width = widget_w (w); 1240 y = widget_y(w);
1152 int height = widget_h (w); 1241 width = widget_w(w);
1153 int shadowT = w->sb.shadowThickness; 1242 height = widget_h(w);
1154 int arrow_height = arrow_h (w); 1243 arrow_height = arrow_h(w);
1155 1244
1156 GC bg = w->sb.backgroundGC; 1245 shadowT = w->sb.shadowThickness;
1157 GC shine = armed ? w->sb.bottomShadowGC : w->sb.topShadowGC; 1246 bg = w->sb.backgroundGC;
1158 GC shadow = armed ? w->sb.topShadowGC : w->sb.bottomShadowGC; 1247
1159 1248 if( armed )
1160 if (VERT (w)) 1249 {
1161 { 1250 shine = w->sb.bottomShadowGC;
1162 if (arrow_same_end (w)) 1251 shadow = w->sb.topShadowGC;
1163 y += height - 2 * arrow_height; 1252 }
1164 if (clear_behind) 1253 else
1165 XClearArea (dpy, win, x, y, width, arrow_height + 1, False); 1254 {
1166 draw_arrow_up (dpy, win, bg, shine, shadow, 1255 shine = w->sb.topShadowGC;
1256 shadow = w->sb.bottomShadowGC;
1257 }
1258
1259 if( VERT(w) )
1260 {
1261 if( arrow_same_end(w) )
1262 {
1263 y += height - 2*arrow_h(w) + 2;
1264 }
1265 if( clear_behind )
1266 XClearArea( dpy, win, x, y, width, arrow_height + 1, False );
1267 draw_arrow_up( dpy, win, bg, shine, shadow,
1167 x + (width - arrow_height)/2, y, 1268 x + (width - arrow_height)/2, y,
1168 arrow_height, arrow_height, shadowT); 1269 arrow_height, arrow_height, shadowT );
1169 } 1270 }
1170 else 1271 else
1171 { 1272 {
1172 if (arrow_same_end (w)) 1273 if( arrow_same_end(w) )
1173 y += height - 2 * arrow_height; 1274 {
1174 if (clear_behind) 1275 y += height - 2*arrow_h(w);
1175 XClearArea (dpy, win, y, x, arrow_height + 1, height, False); 1276 }
1176 draw_arrow_left (dpy, win, bg, shine, shadow, 1277 if( clear_behind )
1278 XClearArea( dpy, win, y, x, arrow_height + 1, height, False );
1279 draw_arrow_left( dpy, win, bg, shine, shadow,
1177 y, x + (width - arrow_height)/2, 1280 y, x + (width - arrow_height)/2,
1178 arrow_height, arrow_height, shadowT); 1281 arrow_height, arrow_height, shadowT );
1179 } 1282 }
1180 } 1283 }
1181 1284
1182 static void 1285 static void redraw_down_arrow(XlwScrollBarWidget w, Boolean armed, Boolean clear_behind)
1183 redraw_down_arrow (XlwScrollBarWidget w, Boolean armed, Boolean clear_behind) 1286 {
1184 { 1287 Display *dpy = XtDisplay((Widget)w);
1185 Display *dpy = XtDisplay ((Widget) w); 1288 Window win = XtWindow((Widget)w);
1186 Window win = XtWindow ((Widget) w); 1289 GC bg, shine, shadow;
1187 1290 int x, y, width, height, arrow_height, shadowT;
1188 int x = widget_x (w); 1291
1189 int y = widget_y (w); 1292 x = widget_x(w);
1190 int width = widget_w (w); 1293 y = widget_y(w);
1191 int height = widget_h (w); 1294 width = widget_w(w);
1192 int shadowT = w->sb.shadowThickness; 1295 height = widget_h(w);
1193 int arrow_height = arrow_h (w); 1296 arrow_height = arrow_h(w);
1194 1297
1195 GC bg = w->sb.backgroundGC; 1298 shadowT = w->sb.shadowThickness;
1196 GC shine = armed ? w->sb.bottomShadowGC : w->sb.topShadowGC; 1299 bg = w->sb.backgroundGC;
1197 GC shadow = armed ? w->sb.topShadowGC : w->sb.bottomShadowGC; 1300
1198 1301 if( armed )
1199 if (VERT (w)) 1302 {
1200 { 1303 shine = w->sb.bottomShadowGC;
1201 if (clear_behind) 1304 shadow = w->sb.topShadowGC;
1202 XClearArea (dpy, win, x, y + height - arrow_height, width, 1305 }
1203 arrow_height + 1, False);
1204 draw_arrow_down (dpy, win, bg, shine, shadow,
1205 x + (width - arrow_height)/2,
1206 y + height - arrow_height + 1,
1207 arrow_height, arrow_height, shadowT);
1208 }
1209 else 1306 else
1210 { 1307 {
1211 if (clear_behind) 1308 shine = w->sb.topShadowGC;
1212 XClearArea (dpy, win, y + height - arrow_height, x, 1309 shadow = w->sb.bottomShadowGC;
1213 arrow_height + 1, height, False); 1310 }
1214 draw_arrow_right (dpy, win, bg, shine, shadow, 1311
1215 y + height - arrow_height + 1, 1312 if( VERT(w) )
1216 x + (width - arrow_height)/2, 1313 {
1217 arrow_height, arrow_height, shadowT); 1314 if( clear_behind )
1218 } 1315 XClearArea( dpy, win, x, y + height - arrow_height, width, arrow_height + 1, False );
1219 } 1316 draw_arrow_down( dpy, win, bg, shine, shadow,
1220 1317 x + (width - arrow_height)/2, y + height - arrow_height + 1,
1221 static void 1318 arrow_height, arrow_height, shadowT );
1222 redraw_everything (XlwScrollBarWidget w, Region region, Boolean behind_arrows) 1319 }
1223 { 1320 else
1224 Display *dpy = XtDisplay ((Widget) w); 1321 {
1225 Window win = XtWindow ((Widget) w); 1322 if( clear_behind )
1226 1323 XClearArea( dpy, win, y + height - arrow_height, x, arrow_height + 1, height, False );
1227 if (w->sb.showArrows) 1324 draw_arrow_right( dpy, win, bg, shine, shadow,
1228 { 1325 y + height - arrow_height + 1, x + (width - arrow_height)/2,
1229 if (region == NULL) 1326 arrow_height, arrow_height, shadowT );
1230 { 1327 }
1231 redraw_up_arrow (w, False, behind_arrows); 1328 }
1232 redraw_down_arrow (w, False, behind_arrows); 1329
1233 } 1330 static void redraw_everything(XlwScrollBarWidget w, Region region, Boolean behind_arrows)
1331 {
1332 Display *dpy = XtDisplay((Widget)w);
1333 Window win = XtWindow((Widget)w);
1334 int x, y, width, height, shadowT, tmp;
1335
1336 x = widget_x(w);
1337 y = widget_y(w);
1338 width = widget_w(w);
1339 height = widget_h(w);
1340 shadowT = w->sb.shadowThickness;
1341
1342 if( w->sb.showArrows )
1343 {
1344 if( region == NULL || XRectInRegion( region, x, y, width, width ) )
1345 {
1346 redraw_up_arrow( w, False, behind_arrows );
1347 }
1348 if( VERT(w) )
1349 {
1350 y = y + height - width + 1;
1351 }
1234 else 1352 else
1235 { 1353 {
1236 int x = widget_x (w); 1354 tmp = y;
1237 int y = widget_y (w); 1355 y = x;
1238 int width = widget_w (w); 1356 x = tmp + height - width + 1;
1239 int height = widget_h (w); 1357 }
1240 int arrow_height = arrow_h (w); 1358 if( region == NULL || XRectInRegion( region, x, y, width, width ) )
1241 int ax = x, ay = y; 1359 {
1242 1360 redraw_down_arrow( w, False, behind_arrows );
1243 if (arrow_same_end (w)) 1361 }
1244 { 1362 }
1245 if (VERT (w)) 1363
1246 ay = y + height - arrow_height - arrow_height; 1364 draw_shadows( dpy, win, w->sb.bottomShadowGC, w->sb.topShadowGC,
1247 else 1365 0, 0, w->core.width, w->core.height, shadowT);
1248 ax = x + height - arrow_height - arrow_height; 1366
1249 } 1367 draw_knob( w, w->sb.above, w->sb.ss, w->sb.below );
1250 if (XRectInRegion (region, ax, ay, width, width)) 1368
1251 redraw_up_arrow (w, False, behind_arrows); 1369 }
1252 1370
1253 if (VERT (w)) 1371 /************************************************************************
1254 ay = y + height - arrow_height; 1372 **
1255 else 1373 ** Method funcitons
1256 ax = x + height - arrow_height; 1374 **
1257 if (XRectInRegion (region, ax, ay, width, width)) 1375 */
1258 redraw_down_arrow (w, False, behind_arrows); 1376
1259 } 1377 /*
1260 } 1378 ** Initialize
1261 1379 */
1262 draw_shadows (dpy, win, w->sb.bottomShadowGC, w->sb.topShadowGC, 0, 0, 1380 static void Initialize(Widget treq, Widget tnew, ArgList args, Cardinal *num_args)
1263 w->core.width, w->core.height, w->sb.shadowThickness);
1264
1265 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below);
1266 }
1267
1268 /*-------------------------- Method Functions ---------------------------*/
1269
1270 static void
1271 Initialize (Widget treq, Widget tnew, ArgList args, Cardinal *num_args)
1272 { 1381 {
1273 XlwScrollBarWidget request = (XlwScrollBarWidget) treq; 1382 XlwScrollBarWidget request = (XlwScrollBarWidget) treq;
1274 XlwScrollBarWidget w = (XlwScrollBarWidget) tnew; 1383 XlwScrollBarWidget w = (XlwScrollBarWidget) tnew;
1275 Display *dpy = XtDisplay ((Widget) w); 1384 Display *dpy = XtDisplay((Widget)w);
1276 Window win = RootWindowOfScreen (DefaultScreenOfDisplay (dpy)); 1385 Window win = RootWindowOfScreen( DefaultScreenOfDisplay(dpy) );
1277 1386
1278 if (request->core.width == 0) w->core.width += (VERT (w) ? 12 : 25); 1387 DBUG(fprintf(stderr, "Initialize\n"));
1279 if (request->core.height == 0) w->core.height += (VERT (w) ? 25 : 12); 1388
1280 1389 if( request->core.width == 0 ) w->core.width += (VERT(w) ? 12 : 25);
1281 verify_values (w); 1390 if( request->core.height == 0 ) w->core.height += (VERT(w) ? 25 : 12);
1391
1392 verify_values(w);
1282 1393
1283 w->sb.lastY = 0; 1394 w->sb.lastY = 0;
1284 w->sb.above = 0; 1395 w->sb.above = 0;
1285 w->sb.ss = 0; 1396 w->sb.ss = 0;
1286 w->sb.below = 0; 1397 w->sb.below = 0;
1287 w->sb.armed = ARM_NONE; 1398 w->sb.armed = ARM_NONE;
1288 w->sb.forced_scroll = FORCED_SCROLL_NONE; 1399
1289 1400 if( w->sb.shadowThickness > 5 ) w->sb.shadowThickness = 5;
1290 if (w->sb.shadowThickness > 5) w->sb.shadowThickness = 5;
1291 1401
1292 w->sb.grayPixmap = 1402 w->sb.grayPixmap =
1293 XCreatePixmapFromBitmapData (dpy, win, (char *) gray_bits, gray_width, 1403 XCreatePixmapFromBitmapData( dpy, win, (char *) gray_bits, gray_width,
1294 gray_height, 1, 0, 1); 1404 gray_height, 1, 0, 1);
1295 1405
1296 make_trough_pixel (w); 1406 make_trough_pixel( w );
1297 1407
1298 make_shadow_pixels (w); 1408 make_shadow_pixels( w );
1299 1409
1300 w->sb.backgroundGC = 1410 w->sb.backgroundGC = get_gc(w, w->core.background_pixel, w->core.background_pixel, None);
1301 get_gc (w, w->core.background_pixel, w->core.background_pixel, None); 1411 w->sb.topShadowGC = get_gc(w, w->sb.topShadowColor, w->core.background_pixel, w->sb.topShadowPixmap);
1302 w->sb.topShadowGC = 1412 w->sb.bottomShadowGC = get_gc(w, w->sb.bottomShadowColor, w->core.background_pixel, w->sb.bottomShadowPixmap);
1303 get_gc (w, w->sb.topShadowColor, w->core.background_pixel,
1304 w->sb.topShadowPixmap);
1305 w->sb.bottomShadowGC =
1306 get_gc (w, w->sb.bottomShadowColor, w->core.background_pixel,
1307 w->sb.bottomShadowPixmap);
1308 1413
1309 w->sb.fullRedrawNext = True; 1414 w->sb.fullRedrawNext = True;
1310 1415 }
1311 w->sb.timerActive = False; 1416
1312 } 1417 /*
1313 1418 ** Destroy
1314 static void 1419 */
1315 Destroy (Widget widget) 1420 static void Destroy(Widget widget)
1316 { 1421 {
1317 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; 1422 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1318 Display *dpy = XtDisplay ((Widget) w); 1423 Display *dpy = XtDisplay((Widget)w);
1319 1424
1320 XtReleaseGC (widget, w->sb.bottomShadowGC); 1425 DBUG(fprintf(stderr, "Destroy\n"));
1321 XtReleaseGC (widget, w->sb.topShadowGC); 1426
1322 XtReleaseGC (widget, w->sb.backgroundGC); 1427 XtReleaseGC(widget, w->sb.bottomShadowGC);
1323 1428 XtReleaseGC(widget, w->sb.topShadowGC);
1324 XFreePixmap (dpy, w->sb.grayPixmap); 1429 XtReleaseGC(widget, w->sb.backgroundGC);
1325 1430
1326 if (w->sb.timerActive) 1431 XFreePixmap( dpy, w->sb.grayPixmap );
1327 { 1432 }
1328 XtRemoveTimeOut (w->sb.timerId); 1433
1329 w->sb.timerActive = False; /* Should be a no-op, but you never know */ 1434 /*
1330 } 1435 ** Realize
1331 } 1436 */
1332 1437 static void Realize(Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr)
1333 static void
1334 Realize (Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr)
1335 { 1438 {
1336 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; 1439 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1337 Display *dpy = XtDisplay ((Widget) w); 1440 Display *dpy = XtDisplay((Widget)w);
1338 Window win; 1441 Window win;
1339 XSetWindowAttributes win_attr; 1442 XSetWindowAttributes win_attr;
1340 1443
1444 DBUG(fprintf(stderr, "Realize\n"));
1445
1341 (*coreClassRec.core_class.realize)(widget, valuemask, attr); 1446 (*coreClassRec.core_class.realize)(widget, valuemask, attr);
1342 1447
1343 win = XtWindow ((Widget) w); 1448 win = XtWindow((Widget)w);
1344 1449
1345 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); 1450 seg_pixel_sizes(w, &w->sb.above, &w->sb.ss, &w->sb.below);
1346 1451
1347 XSetWindowBackground (dpy, win, w->sb.troughColor); 1452 XSetWindowBackground( dpy, win, w->sb.troughColor);
1348 1453
1349 /* Change bit gravity so widget is not cleared on resize */ 1454 /* Change bit gravity so widget is not cleared on resize */
1350 win_attr.bit_gravity = NorthWestGravity; 1455 win_attr.bit_gravity = NorthWestGravity;
1351 XChangeWindowAttributes (dpy, win, CWBitGravity , &win_attr); 1456 XChangeWindowAttributes( dpy, win, CWBitGravity , &win_attr);
1352 1457
1353 } 1458 }
1354 1459
1355 static void 1460 /*
1356 Resize (Widget widget) 1461 ** Resize
1462 */
1463 static void Resize(Widget widget)
1357 { 1464 {
1358 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; 1465 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1359 Display *dpy = XtDisplay ((Widget) w); 1466 Display *dpy = XtDisplay((Widget)w);
1360 Window win = XtWindow ((Widget) w); 1467 Window win = XtWindow((Widget)w);
1361 1468
1362 if (XtIsRealized (widget)) 1469 if( XtIsRealized(widget) )
1363 { 1470 {
1364 DBUG (fprintf (stderr, "Resize = %08lx\n", w)); 1471 DBUG(fprintf(stderr, "Resize = %08lx\n", w));
1365 1472
1366 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); 1473 seg_pixel_sizes(w, &w->sb.above, &w->sb.ss, &w->sb.below);
1367 1474
1368 /* redraw_everything (w, NULL, True); */ 1475 /*redraw_everything(w, NULL, True);*/
1369 1476
1370 w->sb.fullRedrawNext = True; 1477 w->sb.fullRedrawNext = True;
1371 /* Force expose event */ 1478 /* Force expose event */
1372 XClearArea (dpy, win, widget_x (w), widget_y (w), 1, 1, True); 1479 XClearArea(dpy, win, widget_x(w), widget_y(w), 1, 1, True);
1373 } 1480 }
1374 1481 }
1375 if (w->sb.timerActive) 1482
1376 { 1483 /*
1377 XtRemoveTimeOut (w->sb.timerId); 1484 ** Redisplay
1378 w->sb.timerActive = False; 1485 */
1379 } 1486 static void Redisplay(Widget widget, XEvent *event, Region region)
1380 }
1381
1382 static void
1383 Redisplay (Widget widget, XEvent *event, Region region)
1384 { 1487 {
1385 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; 1488 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1386 1489
1387 DBUG (fprintf (stderr, "Redisplay = %08lx\n", w)); 1490 DBUG(fprintf(stderr, "Redisplay = %08lx\n", w));
1388 1491
1389 if (XtIsRealized (widget)) 1492 if( XtIsRealized(widget) )
1390 { 1493 {
1391 if (w->sb.fullRedrawNext) 1494 if( w->sb.fullRedrawNext )
1392 redraw_everything (w, NULL, True); 1495 {
1496 redraw_everything(w, NULL, True);
1497 }
1393 else 1498 else
1394 redraw_everything (w, region, False); 1499 {
1500 redraw_everything(w, region, False);
1501 }
1395 w->sb.fullRedrawNext = False; 1502 w->sb.fullRedrawNext = False;
1396 } 1503 }
1397 } 1504 }
1398 1505
1399 static Boolean 1506 /*
1400 SetValues (Widget current, Widget request, Widget neww, 1507 ** SetValues
1401 ArgList args, Cardinal *num_args) 1508 */
1509 static Boolean SetValues(Widget current, Widget request, Widget neww, ArgList args, Cardinal *num_args)
1402 { 1510 {
1403 XlwScrollBarWidget cur = (XlwScrollBarWidget) current; 1511 XlwScrollBarWidget cur = (XlwScrollBarWidget) current;
1404 XlwScrollBarWidget w = (XlwScrollBarWidget) neww; 1512 XlwScrollBarWidget w = (XlwScrollBarWidget) neww;
1405 Boolean do_redisplay = False; 1513 Boolean do_redisplay = False;
1406 1514
1407 if (cur->sb.troughColor != w->sb.troughColor) 1515 if( cur->sb.troughColor != w->sb.troughColor )
1408 { 1516 {
1409 if (XtIsRealized ((Widget) w)) 1517 if( XtIsRealized((Widget)w) )
1410 { 1518 {
1411 XSetWindowBackground (XtDisplay((Widget) w), XtWindow ((Widget) w), 1519 XSetWindowBackground( XtDisplay((Widget)w), XtWindow((Widget)w),
1412 w->sb.troughColor); 1520 w->sb.troughColor);
1413 do_redisplay = True; 1521 do_redisplay = True;
1414 } 1522 }
1415 } 1523 }
1416 1524
1417 if (cur->core.background_pixel != w->core.background_pixel) 1525 if( cur->core.background_pixel != w->core.background_pixel )
1418 { 1526 {
1419 XtReleaseGC ((Widget)cur, cur->sb.backgroundGC); 1527 XtReleaseGC((Widget)cur, cur->sb.backgroundGC);
1420 w->sb.backgroundGC = 1528 w->sb.backgroundGC = get_gc(w, w->core.background_pixel, w->core.background_pixel, None);
1421 get_gc (w, w->core.background_pixel, w->core.background_pixel, None);
1422 do_redisplay = True; 1529 do_redisplay = True;
1423 } 1530 }
1424 1531
1425 if (cur->sb.topShadowColor != w->sb.topShadowColor || 1532 if( cur->sb.topShadowColor != w->sb.topShadowColor ||
1426 cur->sb.topShadowPixmap != w->sb.topShadowPixmap) 1533 cur->sb.topShadowPixmap != w->sb.topShadowPixmap )
1427 { 1534 {
1428 XtReleaseGC ((Widget)cur, cur->sb.topShadowGC); 1535 XtReleaseGC((Widget)cur, cur->sb.topShadowGC);
1429 w->sb.topShadowGC = 1536 w->sb.topShadowGC = get_gc(w, w->sb.topShadowColor, w->core.background_pixel, w->sb.topShadowPixmap);
1430 get_gc (w, w->sb.topShadowColor, w->core.background_pixel,
1431 w->sb.topShadowPixmap);
1432 do_redisplay = True; 1537 do_redisplay = True;
1433 } 1538 }
1434 1539
1435 if (cur->sb.bottomShadowColor != w->sb.bottomShadowColor || 1540 if( cur->sb.bottomShadowColor != w->sb.bottomShadowColor ||
1436 cur->sb.bottomShadowPixmap != w->sb.bottomShadowPixmap) 1541 cur->sb.bottomShadowPixmap != w->sb.bottomShadowPixmap )
1437 { 1542 {
1438 XtReleaseGC ((Widget)cur, cur->sb.bottomShadowGC); 1543 XtReleaseGC((Widget)cur, cur->sb.bottomShadowGC);
1439 w->sb.bottomShadowGC = 1544 w->sb.bottomShadowGC = get_gc(w, w->sb.bottomShadowColor, w->core.background_pixel, w->sb.bottomShadowPixmap);
1440 get_gc (w, w->sb.bottomShadowColor, w->core.background_pixel,
1441 w->sb.bottomShadowPixmap);
1442 do_redisplay = True; 1545 do_redisplay = True;
1443 } 1546 }
1444 1547
1445 if (cur->sb.orientation != w->sb.orientation) 1548 if( cur->sb.orientation != w->sb.orientation )
1446 do_redisplay = True; 1549 {
1447 1550 do_redisplay = True;
1448 1551 }
1449 if (cur->sb.minimum != w->sb.minimum || 1552
1553
1554 if( cur->sb.minimum != w->sb.minimum ||
1450 cur->sb.maximum != w->sb.maximum || 1555 cur->sb.maximum != w->sb.maximum ||
1451 cur->sb.sliderSize != w->sb.sliderSize || 1556 cur->sb.sliderSize != w->sb.sliderSize ||
1452 cur->sb.value != w->sb.value || 1557 cur->sb.value != w->sb.value ||
1453 cur->sb.pageIncrement != w->sb.pageIncrement || 1558 cur->sb.pageIncrement != w->sb.pageIncrement ||
1454 cur->sb.increment != w->sb.increment) 1559 cur->sb.increment != w->sb.increment )
1455 { 1560 {
1456 verify_values (w); 1561 verify_values(w);
1457 if (XtIsRealized ((Widget) w)) 1562 if( XtIsRealized((Widget)w) )
1458 { 1563 {
1459 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); 1564 seg_pixel_sizes(w, &w->sb.above, &w->sb.ss, &w->sb.below);
1460 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); 1565 draw_knob( w, w->sb.above, w->sb.ss, w->sb.below );
1461 } 1566 }
1462 } 1567 }
1463 1568
1464 if (w->sb.shadowThickness > 5) w->sb.shadowThickness = 5; 1569 if( w->sb.shadowThickness > 5 ) w->sb.shadowThickness = 5;
1465 1570
1466 return do_redisplay; 1571 return( do_redisplay );
1467 } 1572 }
1468 1573
1469 void 1574 void XlwScrollBarGetValues(Widget widget, int *value, int *sliderSize,
1470 XlwScrollBarGetValues (Widget widget, int *value, int *sliderSize, 1575 int *increment, int *pageIncrement)
1471 int *increment, int *pageIncrement) 1576 {
1472 { 1577 XlwScrollBarWidget w = (XlwScrollBarWidget)widget;
1473 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; 1578
1474 1579 if( w && XtClass((Widget)w) == xlwScrollBarWidgetClass )
1475 if (w && XtClass ((Widget) w) == xlwScrollBarWidgetClass) 1580 {
1476 { 1581 if( value ) *value = w->sb.value;
1477 if (value) *value = w->sb.value; 1582 if( sliderSize ) *sliderSize = w->sb.sliderSize;
1478 if (sliderSize) *sliderSize = w->sb.sliderSize; 1583 if( increment ) *increment = w->sb.increment;
1479 if (increment) *increment = w->sb.increment; 1584 if( pageIncrement ) *pageIncrement = w->sb.pageIncrement;
1480 if (pageIncrement) *pageIncrement = w->sb.pageIncrement; 1585 }
1481 } 1586 }
1482 } 1587
1483 1588 void XlwScrollBarSetValues(Widget widget, int value, int sliderSize,
1484 void 1589 int increment, int pageIncrement, Boolean notify)
1485 XlwScrollBarSetValues (Widget widget, int value, int sliderSize, 1590 {
1486 int increment, int pageIncrement, Boolean notify) 1591 XlwScrollBarWidget w = (XlwScrollBarWidget)widget;
1487 { 1592 int last_value;
1488 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; 1593
1489 1594 if( w && XtClass((Widget)w) == xlwScrollBarWidgetClass &&
1490 if (w && XtClass ((Widget) w) == xlwScrollBarWidgetClass &&
1491 (w->sb.value != value || 1595 (w->sb.value != value ||
1492 w->sb.sliderSize != sliderSize || 1596 w->sb.sliderSize != sliderSize ||
1493 w->sb.increment != increment || 1597 w->sb.increment != increment ||
1494 w->sb.pageIncrement != pageIncrement)) 1598 w->sb.pageIncrement != pageIncrement ))
1495 { 1599 {
1496 int last_value = w->sb.value;
1497
1498 w->sb.value = value; 1600 w->sb.value = value;
1499 w->sb.sliderSize = sliderSize; 1601 w->sb.sliderSize = sliderSize;
1500 w->sb.increment = increment; 1602 w->sb.increment = increment;
1501 w->sb.pageIncrement = pageIncrement; 1603 w->sb.pageIncrement = pageIncrement;
1502 1604
1503 verify_values (w); 1605 verify_values(w);
1504 1606
1505 if (XtIsRealized (widget)) 1607 if( XtIsRealized(widget) )
1506 { 1608 {
1507 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); 1609 seg_pixel_sizes(w, &w->sb.above, &w->sb.ss, &w->sb.below);
1508 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); 1610 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
1509 1611
1510 if (w->sb.value != last_value && notify) 1612 last_value = w->sb.value;
1511 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, 0, NULL); 1613 w->sb.value = value_from_pixel(w, w->sb.above);
1512 } 1614 verify_values(w);
1513 } 1615
1514 } 1616 if( w->sb.value != last_value && notify )
1515 1617 {
1516 /*-------------------------- Action Functions ---------------------------*/ 1618 call_callbacks( w, XmCR_VALUE_CHANGED, w->sb.value, 0, NULL );
1517 1619 }
1518 static void 1620 }
1519 timer (XtPointer data, XtIntervalId *id) 1621 }
1520 { 1622 }
1521 XlwScrollBarWidget w = (XlwScrollBarWidget) data; 1623
1522 w->sb.timerActive = False; 1624 /************************************************************************
1523 1625 **
1524 if (w->sb.armed != ARM_NONE) 1626 ** Action funcitons
1627 **
1628 */
1629
1630 static void timer(XtPointer data, XtIntervalId *id)
1631 {
1632 XlwScrollBarWidget w = (XlwScrollBarWidget)data;
1633 int reason, last_value;
1634
1635 if( w->sb.armed != ARM_NONE )
1636 {
1637 last_value = w->sb.value;
1638 reason = XmCR_NONE;
1639
1640 switch( w->sb.armed )
1641 {
1642 case ARM_PAGEUP:
1643 w->sb.value = safe_subtract( w->sb.value, w->sb.pageIncrement );
1644 reason = XmCR_PAGE_DECREMENT;
1645 break;
1646 case ARM_PAGEDOWN:
1647 w->sb.value = safe_add( w->sb.value, w->sb.pageIncrement );
1648 reason = XmCR_PAGE_INCREMENT;
1649 break;
1650 case ARM_UP:
1651 w->sb.value = safe_subtract( w->sb.value, w->sb.increment );
1652 reason = XmCR_DECREMENT;
1653 break;
1654 case ARM_DOWN:
1655 w->sb.value = safe_add( w->sb.value, w->sb.increment );
1656 reason = XmCR_INCREMENT;
1657 break;
1658 }
1659
1660 verify_values(w);
1661
1662 if( last_value != w->sb.value )
1663 {
1664 seg_pixel_sizes(w, &w->sb.above, &w->sb.ss, &w->sb.below);
1665 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
1666
1667 call_callbacks( w, reason, w->sb.value, 0, NULL );
1668
1669 XtAppAddTimeOut( XtWidgetToApplicationContext((Widget)w),
1670 (unsigned long) w->sb.repeatDelay,
1671 timer, (XtPointer) w );
1672 }
1673 }
1674 }
1675
1676 static int what_button(XlwScrollBarWidget w, int mouse_x, int mouse_y)
1677 {
1678 int x, y, width, height, arrow_height_top, arrow_height_bottom;
1679 int where;
1680
1681 x = widget_x(w);
1682 y = widget_y(w);
1683 width = widget_w(w);
1684 height = widget_h(w);
1685
1686 #if 0
1687 arrow_height = w->sb.showArrows ? arrow_h(w) : 0;
1688 #endif
1689 if( w->sb.showArrows )
1690 {
1691 if( arrow_same_end(w) )
1692 {
1693 arrow_height_top = 0;
1694 arrow_height_bottom = 2*arrow_h(w);
1695 }
1696 else
1697 {
1698 arrow_height_top = arrow_height_bottom = arrow_h(w);
1699 }
1700 }
1701 else
1702 {
1703 arrow_height_top = arrow_height_bottom = 0;
1704 }
1705
1706 where = BUTTON_NONE;
1707
1708 if( mouse_x > x && mouse_x < (x + width) )
1709 {
1710 if( mouse_y > (y + arrow_height_top) && mouse_y < (y + height - arrow_height_bottom) )
1711 {
1712 if( mouse_y < (y + w->sb.above + arrow_height_top) )
1713 {
1714 where = BUTTON_TROUGH_ABOVE;
1715 }
1716 else if( mouse_y > (y + w->sb.above + w->sb.ss + arrow_height_top) )
1717 {
1718 where = BUTTON_TROUGH_BELOW;
1719 }
1720 else
1721 {
1722 where = BUTTON_KNOB;
1723 }
1724 }
1725 else if( arrow_same_end(w) )
1726 {
1727 if( mouse_y > (y + height - arrow_height_bottom + 1) && mouse_y < (y + height) )
1728 {
1729 if( mouse_y < (y + height - arrow_height_bottom/2) )
1730 {
1731 where = BUTTON_UP_ARROW;
1732 }
1733 else
1734 {
1735 where = BUTTON_DOWN_ARROW;
1736 }
1737 }
1738 }
1739 else
1740 {
1741 if( mouse_y > y && mouse_y < (y + arrow_height_top) )
1742 {
1743 where = BUTTON_UP_ARROW;
1744 }
1745 else if( mouse_y > (y + height - arrow_height_bottom + 1) && mouse_y < (y + height) )
1746 {
1747 where = BUTTON_DOWN_ARROW;
1748 }
1749 }
1750 }
1751 #if 0
1752 if( mouse_x > x && mouse_x < (x + width) )
1753 {
1754 if( mouse_y > (y + arrow_height) && mouse_y < (y + height - arrow_height) )
1755 {
1756 if( mouse_y < (y+w->sb.above+arrow_height) )
1757 {
1758 where = BUTTON_TROUGH_ABOVE;
1759 }
1760 else if( mouse_y > (y + w->sb.above + w->sb.ss + arrow_height) )
1761 {
1762 where = BUTTON_TROUGH_BELOW;
1763 }
1764 else
1765 {
1766 where = BUTTON_KNOB;
1767 }
1768 }
1769 else if( mouse_y > y && mouse_y < (y + arrow_height) )
1770 {
1771 where = BUTTON_UP_ARROW;
1772 }
1773 else if( mouse_y > (y + height - arrow_height + 1) && mouse_y < (y + height) )
1774 {
1775 where = BUTTON_DOWN_ARROW;
1776 }
1777 }
1778 #endif
1779 return( where );
1780 }
1781
1782 #define FORCED_SCROLL_NONE 0
1783 #define FORCED_SCROLL_DOWNRIGHT 1
1784 #define FORCED_SCROLL_UPLEFT 2
1785
1786 int forced_scroll_flag = FORCED_SCROLL_NONE;
1787
1788 /*
1789 ** PageDownOrRight
1790 */
1791 static void PageDownOrRight(Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1792 {
1793 forced_scroll_flag = FORCED_SCROLL_DOWNRIGHT;
1794 Select(widget, event, parms, num_parms);
1795 forced_scroll_flag = FORCED_SCROLL_NONE;
1796 }
1797
1798 /*
1799 ** PageUpOrLeft
1800 */
1801 static void PageUpOrLeft(Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1802 {
1803 forced_scroll_flag = FORCED_SCROLL_UPLEFT;
1804 Select(widget, event, parms, num_parms);
1805 forced_scroll_flag = FORCED_SCROLL_NONE;
1806 }
1807
1808 /*
1809 ** Select
1810 */
1811 static void Select(Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1812 {
1813 XlwScrollBarWidget w = (XlwScrollBarWidget)widget;
1814 int mouse_x, mouse_y;
1815 int reason, last_value;
1816 int sb_button;
1817
1818 DBUG(fprintf(stderr, "Select:\n"));
1819
1820 mouse_x = event_x( w, event );
1821 mouse_y = event_y( w, event );
1822
1823 w->sb.savedValue = w->sb.value;
1824
1825 last_value = w->sb.value;
1826 reason = XmCR_NONE;
1827
1828 XtGrabKeyboard( (Widget)w, False, GrabModeAsync, GrabModeAsync, event->xbutton.time );
1829
1830 sb_button = what_button(w, mouse_x, mouse_y);
1831
1832 if ( forced_scroll_flag != FORCED_SCROLL_NONE )
1525 { 1833 {
1526 int last_value = w->sb.value; 1834 switch ( sb_button )
1527 int reason = XmCR_NONE;
1528
1529 switch (w->sb.armed)
1530 {
1531 case ARM_PAGEUP:
1532 decrement_value (w, w->sb.pageIncrement);
1533 reason = XmCR_PAGE_DECREMENT;
1534 break;
1535 case ARM_PAGEDOWN:
1536 increment_value (w, w->sb.pageIncrement);
1537 reason = XmCR_PAGE_INCREMENT;
1538 break;
1539 case ARM_UP:
1540 decrement_value (w, w->sb.increment);
1541 reason = XmCR_DECREMENT;
1542 break;
1543 case ARM_DOWN:
1544 increment_value (w, w->sb.increment);
1545 reason = XmCR_INCREMENT;
1546 break;
1547 }
1548
1549 verify_values (w);
1550
1551 if (last_value != w->sb.value)
1552 {
1553 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below);
1554 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below);
1555
1556 call_callbacks (w, reason, w->sb.value, 0, NULL);
1557
1558 w->sb.timerId =
1559 XtAppAddTimeOut (XtWidgetToApplicationContext ((Widget) w),
1560 (unsigned long) w->sb.repeatDelay,
1561 timer, (XtPointer) w);
1562 w->sb.timerActive = True;
1563 }
1564 }
1565 }
1566
1567 static button_where
1568 what_button (XlwScrollBarWidget w, int mouse_x, int mouse_y)
1569 {
1570 int width = widget_w (w);
1571 int height = widget_h (w);
1572 int arrow_height = arrow_h (w);
1573
1574 mouse_x -= widget_x (w);
1575 mouse_y -= widget_y (w);
1576
1577 if (mouse_x < 0 || mouse_x >= width ||
1578 mouse_y < 0 || mouse_y >= height)
1579 return BUTTON_NONE;
1580
1581 if (w->sb.showArrows)
1582 {
1583 if (mouse_y >= (height -= arrow_height))
1584 return BUTTON_DOWN_ARROW;
1585
1586 if (arrow_same_end (w))
1587 {
1588 if (mouse_y >= (height -= arrow_height))
1589 return BUTTON_UP_ARROW;
1590 }
1591 else
1592 if ( (mouse_y -= arrow_height) < 0)
1593 return BUTTON_UP_ARROW;
1594 }
1595
1596 if ( (mouse_y -= w->sb.above) < 0)
1597 return BUTTON_TROUGH_ABOVE;
1598
1599 if ( (mouse_y -= w->sb.ss) < 0)
1600 return BUTTON_SLIDER;
1601
1602 return BUTTON_TROUGH_BELOW;
1603 }
1604
1605 static void
1606 PageDownOrRight (Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1607 {
1608 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1609 w->sb.forced_scroll = FORCED_SCROLL_DOWNRIGHT;
1610 Select (widget, event, parms, num_parms);
1611 w->sb.forced_scroll = FORCED_SCROLL_NONE;
1612 }
1613
1614 static void
1615 PageUpOrLeft (Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1616 {
1617 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1618 w->sb.forced_scroll = FORCED_SCROLL_UPLEFT;
1619 Select (widget, event, parms, num_parms);
1620 w->sb.forced_scroll = FORCED_SCROLL_NONE;
1621 }
1622
1623 static void
1624 Select (Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1625 {
1626 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1627 button_where sb_button;
1628
1629 int mouse_x = event_x (w, event);
1630 int mouse_y = event_y (w, event);
1631
1632 int last_value = w->sb.savedValue = w->sb.value;
1633 int reason = XmCR_NONE;
1634
1635 XtGrabKeyboard ((Widget) w, False, GrabModeAsync, GrabModeAsync,
1636 event->xbutton.time);
1637
1638 sb_button = what_button (w, mouse_x, mouse_y);
1639
1640 if (w->sb.forced_scroll != FORCED_SCROLL_NONE)
1641 {
1642 switch (sb_button)
1643 { 1835 {
1644 case BUTTON_TROUGH_ABOVE: 1836 case BUTTON_TROUGH_ABOVE:
1645 case BUTTON_TROUGH_BELOW: 1837 case BUTTON_TROUGH_BELOW:
1646 case BUTTON_SLIDER: 1838 case BUTTON_KNOB:
1647 sb_button= BUTTON_NONE; /* cause next switch to fall through */ 1839 sb_button= BUTTON_NONE; /* cause next switch to fall through */
1648 if (w->sb.forced_scroll == FORCED_SCROLL_UPLEFT) 1840 if ( forced_scroll_flag == FORCED_SCROLL_UPLEFT )
1649 { 1841 {
1650 decrement_value (w, w->sb.pageIncrement); 1842 w->sb.value = safe_subtract( w->sb.value, w->sb.pageIncrement );
1651 w->sb.armed = ARM_PAGEUP; 1843 w->sb.armed = ARM_PAGEUP;
1652 reason = XmCR_PAGE_DECREMENT; 1844 reason = XmCR_PAGE_DECREMENT;
1653 break; 1845 break;
1654 } 1846 }
1655 else if (w->sb.forced_scroll == FORCED_SCROLL_DOWNRIGHT) 1847 else if ( forced_scroll_flag == FORCED_SCROLL_DOWNRIGHT )
1656 { 1848 {
1657 increment_value (w, w->sb.pageIncrement); 1849 w->sb.value = safe_add( w->sb.value, w->sb.pageIncrement );
1658 w->sb.armed = ARM_PAGEDOWN; 1850 w->sb.armed = ARM_PAGEDOWN;
1659 reason = XmCR_PAGE_INCREMENT; 1851 reason = XmCR_PAGE_INCREMENT;
1660 break; 1852 break;
1661 } 1853 }
1662 abort(); 1854 abort();
1663 } 1855 }
1664 } 1856 }
1665 1857
1666 switch (sb_button) 1858 switch( sb_button )
1667 { 1859 {
1668 case BUTTON_TROUGH_ABOVE: 1860 case BUTTON_TROUGH_ABOVE:
1669 decrement_value (w, w->sb.pageIncrement); 1861 w->sb.value = safe_subtract( w->sb.value, w->sb.pageIncrement );
1670 w->sb.armed = ARM_PAGEUP; 1862 w->sb.armed = ARM_PAGEUP;
1671 reason = XmCR_PAGE_DECREMENT; 1863 reason = XmCR_PAGE_DECREMENT;
1672 break; 1864 break;
1673 case BUTTON_TROUGH_BELOW: 1865 case BUTTON_TROUGH_BELOW:
1674 increment_value (w, w->sb.pageIncrement); 1866 w->sb.value = safe_add( w->sb.value, w->sb.pageIncrement );
1675 w->sb.armed = ARM_PAGEDOWN; 1867 w->sb.armed = ARM_PAGEDOWN;
1676 reason = XmCR_PAGE_INCREMENT; 1868 reason = XmCR_PAGE_INCREMENT;
1677 break; 1869 break;
1678 case BUTTON_SLIDER: 1870 case BUTTON_KNOB:
1679 w->sb.lastY = mouse_y; 1871 w->sb.lastY = mouse_y;
1680 w->sb.armed = ARM_SLIDER; 1872 w->sb.armed = ARM_KNOB;
1681 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); 1873 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
1682 break; 1874 break;
1683 case BUTTON_UP_ARROW: 1875 case BUTTON_UP_ARROW:
1684 if (event->xbutton.state & ControlMask) 1876 if( event->xbutton.state & ControlMask )
1685 { 1877 {
1686 w->sb.value = w->sb.minimum; 1878 w->sb.value = INT_MIN;
1687 reason = XmCR_TO_TOP; 1879 w->sb.armed = ARM_UP;
1688 } 1880 reason = XmCR_TO_TOP;
1689 else 1881 }
1690 { 1882 else
1691 decrement_value (w, w->sb.increment); 1883 {
1692 reason = XmCR_DECREMENT; 1884 w->sb.value = safe_subtract( w->sb.value, w->sb.increment );
1693 } 1885 w->sb.armed = ARM_UP;
1694 w->sb.armed = ARM_UP; 1886 reason = XmCR_DECREMENT;
1695 redraw_up_arrow (w, True, False); 1887 }
1696 break; 1888 redraw_up_arrow(w, True, False);
1697 case BUTTON_DOWN_ARROW: 1889 break;
1698 if (event->xbutton.state & ControlMask) 1890 case BUTTON_DOWN_ARROW:
1699 { 1891 if( event->xbutton.state & ControlMask )
1700 w->sb.value = w->sb.maximum; 1892 {
1701 reason = XmCR_TO_BOTTOM; 1893 w->sb.value = INT_MAX;
1702 } 1894 w->sb.armed = ARM_DOWN;
1703 else 1895 reason = XmCR_TO_BOTTOM;
1704 { 1896 }
1705 increment_value (w, w->sb.increment); 1897 else
1706 reason = XmCR_INCREMENT; 1898 {
1707 } 1899 w->sb.value = safe_add( w->sb.value, w->sb.increment );
1708 w->sb.armed = ARM_DOWN; 1900 w->sb.armed = ARM_DOWN;
1709 redraw_down_arrow (w, True, False); 1901 reason = XmCR_INCREMENT;
1710 break; 1902 }
1711 } 1903 redraw_down_arrow(w, True, False);
1712 1904 break;
1713 verify_values (w); 1905 }
1714 1906
1715 if (last_value != w->sb.value) 1907 verify_values(w);
1716 { 1908
1717 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); 1909 if( last_value != w->sb.value )
1718 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); 1910 {
1911 seg_pixel_sizes(w, &w->sb.above, &w->sb.ss, &w->sb.below);
1912 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
1719 1913
1720 call_callbacks (w, reason, w->sb.value, mouse_y, event); 1914 call_callbacks( w, reason, w->sb.value, mouse_y, event );
1721 1915
1722 if (w->sb.timerActive) 1916 XtAppAddTimeOut( XtWidgetToApplicationContext((Widget)w),
1723 XtRemoveTimeOut (w->sb.timerId); 1917 (unsigned long) w->sb.initialDelay,
1724 1918 timer, (XtPointer) w );
1725 w->sb.timerId = 1919 }
1726 XtAppAddTimeOut (XtWidgetToApplicationContext ((Widget) w), 1920
1727 (unsigned long) w->sb.initialDelay, 1921 CHECK(w);
1728 timer, (XtPointer) w); 1922 }
1729 w->sb.timerActive = True; 1923
1730 } 1924 /*
1731 1925 ** Drag
1732 CHECK (w); 1926 */
1733 } 1927 static void Drag(Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1734 1928 {
1735 static void 1929 XlwScrollBarWidget w = (XlwScrollBarWidget)widget;
1736 Drag (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) 1930 int diff;
1737 { 1931 int height, mouse_y;
1738 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; 1932 int last_value, last_above;
1739 1933
1740 if (w->sb.armed == ARM_SLIDER) 1934 DBUG(fprintf(stderr, "Drag:\n"));
1741 { 1935
1742 int mouse_y = event_y (w, event); 1936 if( w->sb.armed == ARM_KNOB )
1743 int diff = mouse_y - w->sb.lastY; 1937 {
1744 1938 height = widget_h(w);
1745 if (diff < -(w->sb.above)) /* up */ 1939 if( w->sb.showArrows ) height -= (2*arrow_h(w));
1746 { 1940
1747 mouse_y -= (diff + w->sb.above); 1941 mouse_y = event_y( w, event );
1748 diff = -(w->sb.above); 1942
1749 } 1943 diff = mouse_y - w->sb.lastY;
1750 else if (diff > w->sb.below) /* down */ 1944
1751 { 1945 last_above = w->sb.above;
1752 mouse_y -= (diff - w->sb.below); 1946 last_value = w->sb.value;
1753 diff = w->sb.below; 1947
1754 } 1948 if( diff < 0 )
1755 1949 {
1756 if (diff) 1950 /* up */
1757 { 1951 w->sb.above -= (-diff);
1952 if( w->sb.above < 0 )
1953 {
1954 mouse_y = (mouse_y - w->sb.above);
1955 w->sb.above = 0;
1956 diff = 0;
1957 w->sb.below = height - w->sb.ss;
1958 }
1959 w->sb.below -= diff;
1960 CHECK(w);
1961 }
1962 else if( diff > 0 )
1963 {
1964 /* down */
1758 w->sb.above += diff; 1965 w->sb.above += diff;
1966 if( w->sb.above + w->sb.ss > height )
1967 {
1968 mouse_y = height + (mouse_y - (w->sb.above + w->sb.ss));
1969 w->sb.above = height - w->sb.ss;
1970 diff = 0;
1971 w->sb.below = 0;
1972 }
1759 w->sb.below -= diff; 1973 w->sb.below -= diff;
1760 1974 CHECK(w);
1761 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); 1975 }
1976
1977 if( last_above != w->sb.above )
1978 {
1979 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
1762 1980
1763 w->sb.lastY = mouse_y; 1981 w->sb.lastY = mouse_y;
1764 1982
1765 w->sb.value = value_from_pixel (w, w->sb.above); 1983 w->sb.value = value_from_pixel(w, w->sb.above);
1766 verify_values (w); 1984 verify_values(w);
1767 CHECK (w); 1985 CHECK(w);
1768 1986
1769 call_callbacks (w, XmCR_DRAG, w->sb.value, event_y (w, event), event); 1987 if( w->sb.value != last_value )
1770 } 1988 {
1771 } 1989 call_callbacks( w, XmCR_DRAG, w->sb.value, event_y(w, event), event );
1772 CHECK (w); 1990 }
1773 } 1991 }
1774 1992 }
1775 static void 1993 CHECK(w);
1776 Release (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) 1994 }
1777 { 1995
1778 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; 1996 /*
1779 1997 ** Release
1780 switch (w->sb.armed) 1998 */
1781 { 1999 static void Release(Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1782 case ARM_SLIDER: 2000 {
1783 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, event_y (w, event), event); 2001 XlwScrollBarWidget w = (XlwScrollBarWidget)widget;
2002
2003 DBUG(fprintf(stderr, "EndDrag:\n"));
2004
2005 switch( w->sb.armed )
2006 {
2007 case ARM_KNOB:
2008 call_callbacks( w, XmCR_VALUE_CHANGED, w->sb.value, event_y(w, event), event );
2009 w->sb.armed = ARM_NONE;
2010 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
2011 break;
2012 case ARM_UP:
2013 redraw_up_arrow(w, False, False);
2014 break;
2015 case ARM_DOWN:
2016 redraw_down_arrow(w, False, False);
2017 break;
2018 }
2019
2020 XtUngrabKeyboard( (Widget)w, event->xbutton.time );
2021
2022 w->sb.armed = ARM_NONE;
2023 }
2024
2025 /*
2026 ** Jump
2027 */
2028 static void Jump(Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
2029 {
2030 XlwScrollBarWidget w = (XlwScrollBarWidget)widget;
2031 int x, y, width, height, mouse_x, mouse_y;
2032 int arrow_height;
2033 int last_above, last_value;
2034
2035 DBUG(fprintf(stderr, "Jump:\n"));
2036
2037 x = widget_x(w);
2038 y = widget_y(w);
2039 width = widget_w(w);
2040 height = widget_h(w);
2041 mouse_x = event_x( w, event );
2042 mouse_y = event_y( w, event );
2043
2044 arrow_height = w->sb.showArrows ? arrow_h(w) : 0;
2045
2046 XtGrabKeyboard( (Widget)w, False, GrabModeAsync, GrabModeAsync, event->xbutton.time );
2047
2048 switch( what_button(w, mouse_x, mouse_y) )
2049 {
2050 case BUTTON_TROUGH_ABOVE:
2051 case BUTTON_TROUGH_BELOW:
2052 case BUTTON_KNOB:
2053 w->sb.savedValue = w->sb.value;
2054
2055 height -= (2*arrow_height);
2056 y += arrow_height;
2057
2058 last_above = w->sb.above;
2059 last_value = w->sb.value;
2060
2061 w->sb.armed = ARM_KNOB;
2062 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
2063
2064 w->sb.above = mouse_y - (w->sb.ss / 2) - arrow_height;
2065 if( w->sb.above < 0 )
2066 {
2067 w->sb.above = 0;
2068 }
2069 else if( w->sb.above + w->sb.ss > height )
2070 {
2071 w->sb.above = height - w->sb.ss;
2072 }
2073 w->sb.below = (height - (w->sb.ss + w->sb.above));
2074
2075 if( last_above != w->sb.above )
2076 {
2077 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
2078
2079 w->sb.value = value_from_pixel(w, w->sb.above);
2080 verify_values(w);
2081 CHECK(w);
2082
2083 w->sb.lastY = mouse_y;
2084 w->sb.lastY = w->sb.above + arrow_height + (w->sb.ss / 2);
2085
2086 if( w->sb.value != last_value )
2087 {
2088 call_callbacks( w, XmCR_DRAG, w->sb.value, event_y(w, event), event );
2089 }
2090 }
2091 break;
2092 }
2093 CHECK(w);
2094 }
2095
2096 /*
2097 ** Abort
2098 */
2099 static void Abort(Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
2100 {
2101 XlwScrollBarWidget w = (XlwScrollBarWidget)widget;
2102
2103 DBUG(fprintf(stderr, "Abort:\n"));
2104
2105 if( w->sb.armed != ARM_NONE )
2106 {
2107 if( w->sb.value != w->sb.savedValue )
2108 {
2109 w->sb.value = w->sb.savedValue;
2110
2111 seg_pixel_sizes(w, &w->sb.above, &w->sb.ss, &w->sb.below);
2112 draw_knob(w, w->sb.above, w->sb.ss, w->sb.below);
2113
2114 call_callbacks( w, XmCR_VALUE_CHANGED, w->sb.value, event_y(w, event), event );
2115 }
2116
2117 switch( w->sb.armed )
2118 {
2119 case ARM_UP:
2120 redraw_up_arrow(w, False, False);
2121 break;
2122 case ARM_DOWN:
2123 redraw_down_arrow(w, False, False);
2124 break;
2125 }
2126
1784 w->sb.armed = ARM_NONE; 2127 w->sb.armed = ARM_NONE;
1785 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); 2128
1786 break; 2129 XtUngrabKeyboard( (Widget)w, event->xbutton.time );
1787 case ARM_UP: 2130 }
1788 redraw_up_arrow (w, False, False); 2131 }
1789 break;
1790 case ARM_DOWN:
1791 redraw_down_arrow (w, False, False);
1792 break;
1793 }
1794
1795 XtUngrabKeyboard ((Widget) w, event->xbutton.time);
1796
1797 w->sb.armed = ARM_NONE;
1798 }
1799
1800 static void
1801 Jump (Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1802 {
1803 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1804 int last_value;
1805
1806 int mouse_x = event_x (w, event);
1807 int mouse_y = event_y (w, event);
1808
1809 int scroll_region_y = widget_y (w);
1810 int scroll_region_h = widget_h (w);
1811
1812 if (w->sb.showArrows)
1813 {
1814 int arrow_height = arrow_h (w);
1815 scroll_region_h -= 2 * arrow_height;
1816 if (!arrow_same_end (w))
1817 scroll_region_y += arrow_height;
1818 }
1819
1820 XtGrabKeyboard ((Widget) w, False, GrabModeAsync, GrabModeAsync,
1821 event->xbutton.time);
1822
1823 switch (what_button (w, mouse_x, mouse_y))
1824 {
1825 case BUTTON_TROUGH_ABOVE:
1826 case BUTTON_TROUGH_BELOW:
1827 case BUTTON_SLIDER:
1828 w->sb.savedValue = w->sb.value;
1829
1830 last_value = w->sb.value;
1831
1832 w->sb.above = mouse_y - (w->sb.ss / 2) - scroll_region_y;
1833 if (w->sb.above < 0)
1834 w->sb.above = 0;
1835 else if (w->sb.above + w->sb.ss > scroll_region_h)
1836 w->sb.above = scroll_region_h - w->sb.ss;
1837
1838 w->sb.below = scroll_region_h - w->sb.ss - w->sb.above;
1839
1840 w->sb.armed = ARM_SLIDER;
1841 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below);
1842
1843 w->sb.value = value_from_pixel (w, w->sb.above);
1844 verify_values (w);
1845 CHECK (w);
1846
1847 w->sb.lastY = mouse_y;
1848
1849 if (w->sb.value != last_value)
1850 call_callbacks (w, XmCR_DRAG, w->sb.value, mouse_y, event);
1851
1852 break;
1853 }
1854 CHECK (w);
1855 }
1856
1857 static void
1858 Abort (Widget widget, XEvent *event, String *parms, Cardinal *num_parms)
1859 {
1860 XlwScrollBarWidget w = (XlwScrollBarWidget) widget;
1861
1862 if (w->sb.armed != ARM_NONE)
1863 {
1864 if (w->sb.value != w->sb.savedValue)
1865 {
1866 w->sb.value = w->sb.savedValue;
1867
1868 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below);
1869 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below);
1870
1871 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value,
1872 event_y (w, event), event);
1873 }
1874
1875 switch (w->sb.armed)
1876 {
1877 case ARM_UP: redraw_up_arrow (w, False, False); break;
1878 case ARM_DOWN: redraw_down_arrow (w, False, False); break;
1879 }
1880
1881 w->sb.armed = ARM_NONE;
1882
1883 XtUngrabKeyboard ((Widget) w, event->xbutton.time);
1884 }
1885 }