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