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