Mercurial > hg > xemacs-beta
annotate lwlib/xlwscrollbar.c @ 5574:d4f334808463
Support inlining labels, bytecomp.el.
lisp/ChangeLog addition:
2011-10-02 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el (byte-compile-initial-macro-environment):
Add #'declare to this, so it doesn't need to rely on
#'cl-compiling file to determine when we're byte-compiling.
Update #'labels to support declaring labels inline, as Common Lisp
requires.
* bytecomp.el (byte-compile-function-form):
Don't error if FUNCTION is quoting a non-lambda, non-symbol, just
return it.
* cl-extra.el (cl-macroexpand-all):
If a label name has been quoted, expand to the label placeholder
quoted with 'function. This allows the byte compiler to
distinguish between uses of the placeholder as data and uses in
contexts where it should be inlined.
* cl-macs.el:
* cl-macs.el (cl-do-proclaim):
When proclaming something as inline, if it is bound as a label,
don't modify the symbol's plist; instead, treat the first element
of its placeholder constant vector as a place to store compile
information.
* cl-macs.el (declare):
Leave processing declarations while compiling to the
implementation of #'declare in
byte-compile-initial-macro-environment.
tests/ChangeLog addition:
2011-10-02 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-tests.el:
* automated/lisp-tests.el (+):
Test #'labels and inlining.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 02 Oct 2011 15:32:16 +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 } |