blob: 98caad58e2ac480f2ec0b155f7ede76dfd170236 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* 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
16Copyright (c) 1987, 1988, 1994 X Consortium
17
18Permission is hereby granted, free of charge, to any person obtaining a copy
19of this software and associated documentation files (the "Software"), to deal
20in the Software without restriction, including without limitation the rights
21to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22copies of the Software, and to permit persons to whom the Software is
23furnished to do so, subject to the following conditions:
24
25The above copyright notice and this permission notice shall be included in all
26copies or substantial portions of the Software.
27
28THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X
31CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34
35Except as contained in this notice, the name of the X Consortium shall not be
36used in advertising or otherwise to promote the sale, use or other dealings in
37this Software without prior written authorization from the X Consortium.
38
39Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
40
41 All Rights Reserved
42
43Permission to use, copy, modify, and distribute this software and its
44documentation for any purpose and without fee is hereby granted, provided that
45the above copyright notice appear in all copies and that both that copyright
46notice and this permission notice appear in supporting documentation, and that
47the name of Digital not be used in advertising or publicity pertaining to
48distribution of the software without specific, written prior permission.
49
50DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
51IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL
52BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
53WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
54OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
55CONNECTION 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
74static 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
87static float floatZero = 0.0;
88
89#define Offset(field) XtOffsetOf(ScrollbarRec, field)
90
91static 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
Bram Moolenaar56985072016-01-29 23:23:06 +0100128static void ClassInitialize(void);
129static void Initialize(Widget, Widget, ArgList, Cardinal *);
130static void Destroy(Widget);
131static void Realize(Widget, Mask *, XSetWindowAttributes *);
132static void Resize(Widget);
133static void Redisplay(Widget, XEvent *, Region);
134static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000135
Bram Moolenaar56985072016-01-29 23:23:06 +0100136static void HandleThumb(Widget, XEvent *, String *, Cardinal *);
137static void MoveThumb(Widget, XEvent *, String *, Cardinal *);
138static void NotifyThumb(Widget, XEvent *, String *, Cardinal *);
139static void NotifyScroll(Widget, XEvent *, String *, Cardinal *);
140static void EndScroll(Widget, XEvent *, String *, Cardinal *);
141static void ScrollOneLineUp(Widget, XEvent *, String *, Cardinal *);
142static void ScrollOneLineDown(Widget, XEvent *, String *, Cardinal *);
143static void ScrollPageUp(Widget, XEvent *, String *, Cardinal *);
144static void ScrollPageDown(Widget, XEvent *, String *, Cardinal *);
145static void ScrollSome(Widget w, XEvent *event, int call_data);
146static void _Xaw3dDrawShadows(Widget, XEvent *, Region, int);
147static void AllocTopShadowGC(Widget);
148static void AllocBotShadowGC(Widget);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000149
150static 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
164ScrollbarClassRec 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 */
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +0000201 /* change_sensitive */ XtInheritChangeSensitive,
202#ifndef OLDXAW
203 /* extension */ NULL
204#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000205 },
206 { /* scrollbar fields */
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +0000207 /* empty */ 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000208 }
209};
210
211WidgetClass 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
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100225ClassInitialize(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000226{
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
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100235FillArea(
236 ScrollbarWidget sbw,
237 Position top, bottom,
238 int fill,
239 int draw_shadow)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000240{
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;
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +0000247 sw = sbw->scrollbar.shadow_width;
248 if (sw < 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000249 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
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100343PaintThumb(ScrollbarWidget sbw)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000344{
345 Position oldtop, oldbot, newtop, newbot;
346 Dimension margin, tzl;
347
348 margin = MARGIN (sbw);
349 tzl = sbw->scrollbar.length - 2 * margin;
350 newtop = margin + (int)(tzl * sbw->scrollbar.top);
351 newbot = newtop + (int)(tzl * sbw->scrollbar.shown) + 1;
352 if (newbot < newtop + (int)sbw->scrollbar.min_thumb)
353 newbot = newtop + sbw->scrollbar.min_thumb;
354
355 oldtop = sbw->scrollbar.topLoc;
356 oldbot = oldtop + sbw->scrollbar.shownLength;
357 sbw->scrollbar.topLoc = newtop;
358 sbw->scrollbar.shownLength = newbot - newtop;
359 if (XtIsRealized ((Widget) sbw))
360 {
361 if (newtop < oldtop)
362 FillArea(sbw, newtop, AT_MIN(newbot, oldtop+1),1,0);
363 if (newtop > oldtop)
364 FillArea(sbw, oldtop, AT_MIN(newtop, oldbot ),0,0);
365 if (newbot < oldbot)
366 FillArea(sbw, AT_MAX(newbot, oldtop), oldbot, 0,0);
367 if (newbot > oldbot)
368 FillArea(sbw, AT_MAX(newtop, oldbot-1), newbot, 1,0);
369
370 /* Only draw the missing shadows */
371 FillArea(sbw, newtop, newbot, 0, 1);
372 }
373}
374
375 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100376PaintArrows(ScrollbarWidget sbw)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000377{
378 XPoint point[6];
379 Dimension thickness = sbw->scrollbar.thickness - 1;
380 Dimension size;
381 Dimension off;
382
383 if (XtIsRealized((Widget) sbw))
384 {
385 if ((int)thickness * 2 > (int)sbw->scrollbar.length)
386 {
387 size = sbw->scrollbar.length / 2;
388 off = (int)(thickness - size) / 2;
389 }
390 else
391 {
392 size = thickness;
393 off = 0;
394 }
395 point[0].x = off + sbw->scrollbar.shadow_width;
396 point[0].y = size;
397 point[1].x = thickness - off - sbw->scrollbar.shadow_width;
398 point[1].y = size;
399 point[2].x = thickness / 2;
400 point[2].y = sbw->scrollbar.shadow_width;
401
402 point[3].x = off + sbw->scrollbar.shadow_width;
403 point[3].y = sbw->scrollbar.length - size;
404 point[4].x = thickness - off - sbw->scrollbar.shadow_width;
405 point[4].y = sbw->scrollbar.length - size;
406 point[5].x = thickness / 2;
407 point[5].y = sbw->scrollbar.length - sbw->scrollbar.shadow_width - 1;
408
409 /* horizontal arrows require that x and y coordinates be swapped */
410 if (sbw->scrollbar.orientation == XtorientHorizontal)
411 {
412 int n;
413 int swap;
414 for (n = 0; n < 6; n++)
415 {
416 swap = point[n].x;
417 point[n].x = point[n].y;
418 point[n].y = swap;
419 }
420 }
421 /* draw the up/left arrow */
422 XFillPolygon (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
423 sbw->scrollbar.gc,
424 point, 3,
425 Convex, CoordModeOrigin);
426 XDrawLines (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
427 sbw->scrollbar.bot_shadow_GC,
428 point, 3,
429 CoordModeOrigin);
430 XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
431 sbw->scrollbar.top_shadow_GC,
432 point[0].x, point[0].y,
433 point[2].x, point[2].y);
434 /* draw the down/right arrow */
435 XFillPolygon (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
436 sbw->scrollbar.gc,
437 point+3, 3,
438 Convex, CoordModeOrigin);
439 XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
440 sbw->scrollbar.top_shadow_GC,
441 point[3].x, point[3].y,
442 point[4].x, point[4].y);
443 XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
444 sbw->scrollbar.top_shadow_GC,
445 point[3].x, point[3].y,
446 point[5].x, point[5].y);
447 XDrawLine (XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
448 sbw->scrollbar.bot_shadow_GC,
449 point[4].x, point[4].y,
450 point[5].x, point[5].y);
451 }
452}
453
454 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100455Destroy(Widget w)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000456{
457 ScrollbarWidget sbw = (ScrollbarWidget) w;
458 if (sbw->scrollbar.timer_id != (XtIntervalId) 0)
459 XtRemoveTimeOut (sbw->scrollbar.timer_id);
460 XtReleaseGC(w, sbw->scrollbar.gc);
461 XtReleaseGC(w, sbw->scrollbar.top_shadow_GC);
462 XtReleaseGC(w, sbw->scrollbar.bot_shadow_GC);
463}
464
465 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100466CreateGC(Widget w)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000467{
468 ScrollbarWidget sbw = (ScrollbarWidget) w;
469 XGCValues gcValues;
470 XtGCMask mask;
471 unsigned int depth = 1;
472
473 if (sbw->scrollbar.thumb == XtUnspecifiedPixmap)
474 {
475 sbw->scrollbar.thumb = XmuCreateStippledPixmap (XtScreen(w),
476 (Pixel) 1, (Pixel) 0, depth);
477 }
478 else if (sbw->scrollbar.thumb != None)
479 {
480 Window root;
481 int x, y;
482 unsigned int width, height, bw;
483
484 if (XGetGeometry (XtDisplay(w), sbw->scrollbar.thumb, &root, &x, &y,
485 &width, &height, &bw, &depth) == 0)
486 EMSG(_("Scrollbar Widget: Could not get geometry of thumb pixmap."));
487 }
488
489 gcValues.foreground = sbw->scrollbar.foreground;
490 gcValues.background = sbw->core.background_pixel;
491 mask = GCForeground | GCBackground;
492
493 if (sbw->scrollbar.thumb != None)
494 {
495 gcValues.fill_style = FillSolid;
496 mask |= GCFillStyle;
497 }
498 /* the creation should be non-caching, because */
499 /* we now set and clear clip masks on the gc returned */
500 sbw->scrollbar.gc = XtGetGC (w, mask, &gcValues);
501}
502
503 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100504SetDimensions(ScrollbarWidget sbw)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000505{
506 if (sbw->scrollbar.orientation == XtorientVertical)
507 {
508 sbw->scrollbar.length = sbw->core.height;
509 sbw->scrollbar.thickness = sbw->core.width;
510 }
511 else
512 {
513 sbw->scrollbar.length = sbw->core.width;
514 sbw->scrollbar.thickness = sbw->core.height;
515 }
516}
517
Bram Moolenaar071d4272004-06-13 20:20:40 +0000518 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100519Initialize(
520 Widget request UNUSED, /* what the client asked for */
521 Widget new, /* what we're going to give him */
522 ArgList args UNUSED,
523 Cardinal *num_args UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000524{
525 ScrollbarWidget sbw = (ScrollbarWidget) new;
526
527 CreateGC(new);
528 AllocTopShadowGC(new);
529 AllocBotShadowGC(new);
530
531 if (sbw->core.width == 0)
532 sbw->core.width = (sbw->scrollbar.orientation == XtorientVertical)
533 ? sbw->scrollbar.thickness : sbw->scrollbar.length;
534
535 if (sbw->core.height == 0)
536 sbw->core.height = (sbw->scrollbar.orientation == XtorientHorizontal)
537 ? sbw->scrollbar.thickness : sbw->scrollbar.length;
538
539 SetDimensions(sbw);
540 sbw->scrollbar.scroll_mode = SMODE_NONE;
541 sbw->scrollbar.timer_id = (XtIntervalId)0;
542 sbw->scrollbar.topLoc = 0;
543 sbw->scrollbar.shownLength = sbw->scrollbar.min_thumb;
544}
545
546 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100547Realize(
548 Widget w,
549 Mask *valueMask,
550 XSetWindowAttributes *attributes)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000551{
552 /* The Simple widget actually stuffs the value in the valuemask. */
553 (*vim_scrollbarWidgetClass->core_class.superclass->core_class.realize)
554 (w, valueMask, attributes);
555}
556
Bram Moolenaar071d4272004-06-13 20:20:40 +0000557 static Boolean
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100558SetValues(
559 Widget current, /* what I am */
560 Widget request UNUSED, /* what he wants me to be */
561 Widget desired, /* what I will become */
562 ArgList args UNUSED,
563 Cardinal *num_args UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000564{
565 ScrollbarWidget sbw = (ScrollbarWidget) current;
566 ScrollbarWidget dsbw = (ScrollbarWidget) desired;
567 Boolean redraw = FALSE;
568
569/*
570 * If these values are outside the acceptable range ignore them...
571 */
572 if (dsbw->scrollbar.top < 0.0 || dsbw->scrollbar.top > 1.0)
573 dsbw->scrollbar.top = sbw->scrollbar.top;
574
575 if (dsbw->scrollbar.shown < 0.0 || dsbw->scrollbar.shown > 1.0)
576 dsbw->scrollbar.shown = sbw->scrollbar.shown;
577
578/*
579 * Change colors and stuff...
580 */
581 if (XtIsRealized(desired))
582 {
583 if (sbw->scrollbar.foreground != dsbw->scrollbar.foreground ||
584 sbw->core.background_pixel != dsbw->core.background_pixel ||
585 sbw->scrollbar.thumb != dsbw->scrollbar.thumb)
586 {
587 XtReleaseGC(desired, sbw->scrollbar.gc);
588 CreateGC (desired);
589 redraw = TRUE;
590 }
591 if (sbw->scrollbar.top != dsbw->scrollbar.top ||
592 sbw->scrollbar.shown != dsbw->scrollbar.shown)
593 redraw = TRUE;
594 }
595 return redraw;
596}
597
598 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100599Resize(Widget w)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000600{
601 /* ForgetGravity has taken care of background, but thumb may
602 * have to move as a result of the new size. */
603 SetDimensions ((ScrollbarWidget) w);
604 Redisplay(w, (XEvent*) NULL, (Region)NULL);
605}
606
607
Bram Moolenaar071d4272004-06-13 20:20:40 +0000608 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100609Redisplay(Widget w, XEvent *event, Region region)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000610{
611 ScrollbarWidget sbw = (ScrollbarWidget) w;
612 int x, y;
613 unsigned int width, height;
614
615 _Xaw3dDrawShadows(w, event, region, FALSE);
616
617 if (sbw->scrollbar.orientation == XtorientHorizontal)
618 {
619 x = sbw->scrollbar.topLoc;
620 y = 1;
621 width = sbw->scrollbar.shownLength;
622 height = sbw->core.height - 2;
623 }
624 else
625 {
626 x = 1;
627 y = sbw->scrollbar.topLoc;
628 width = sbw->core.width - 2;
629 height = sbw->scrollbar.shownLength;
630 }
631 if (region == NULL ||
632 XRectInRegion (region, x, y, width, height) != RectangleOut)
633 {
634 /* Forces entire thumb to be painted. */
635 sbw->scrollbar.topLoc = -(sbw->scrollbar.length + 1);
636 PaintThumb (sbw);
637 }
638 /* we'd like to be region aware here!!!! */
639 PaintArrows(sbw);
640}
641
642
643 static Boolean
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100644CompareEvents(XEvent *oldEvent, *newEvent)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000645{
646#define Check(field) if (newEvent->field != oldEvent->field) return False;
647
648 Check(xany.display);
649 Check(xany.type);
650 Check(xany.window);
651
652 switch (newEvent->type)
653 {
654 case MotionNotify:
655 Check(xmotion.state);
656 break;
657 case ButtonPress:
658 case ButtonRelease:
659 Check(xbutton.state);
660 Check(xbutton.button);
661 break;
662 case KeyPress:
663 case KeyRelease:
664 Check(xkey.state);
665 Check(xkey.keycode);
666 break;
667 case EnterNotify:
668 case LeaveNotify:
669 Check(xcrossing.mode);
670 Check(xcrossing.detail);
671 Check(xcrossing.state);
672 break;
673 }
674#undef Check
675
676 return True;
677}
678
679struct EventData
680{
681 XEvent *oldEvent;
682 int count;
683};
684
685 static Bool
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100686PeekNotifyEvent(Display *dpy, XEvent *event, char *args)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000687{
688 struct EventData *eventData = (struct EventData*)args;
689
690 return ((++eventData->count == QLength(dpy)) /* since PeekIf blocks */
691 || CompareEvents(event, eventData->oldEvent));
692}
693
694
695 static Boolean
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100696LookAhead(Widget w, XEvent *event)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000697{
698 XEvent newEvent;
699 struct EventData eventData;
700
701 if (QLength (XtDisplay (w)) == 0)
702 return False;
703
704 eventData.count = 0;
705 eventData.oldEvent = event;
706
707 XPeekIfEvent (XtDisplay (w), &newEvent, PeekNotifyEvent, (char*)&eventData);
708
709 return CompareEvents (event, &newEvent);
710}
711
712
713 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100714ExtractPosition(
715 XEvent *event,
716 Position *x, *y, /* RETURN */
717 unsigned int *state) /* RETURN */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000718{
719 switch (event->type)
720 {
721 case MotionNotify:
722 *x = event->xmotion.x;
723 *y = event->xmotion.y;
724 if (state != NULL)
725 *state = event->xmotion.state;
726 break;
727 case ButtonPress:
728 case ButtonRelease:
729 *x = event->xbutton.x;
730 *y = event->xbutton.y;
731 if (state != NULL)
732 *state = event->xbutton.state;
733 break;
734 case KeyPress:
735 case KeyRelease:
736 *x = event->xkey.x;
737 *y = event->xkey.y;
738 if (state != NULL)
739 *state = event->xkey.state;
740 break;
741 case EnterNotify:
742 case LeaveNotify:
743 *x = event->xcrossing.x;
744 *y = event->xcrossing.y;
745 if (state != NULL)
746 *state = event->xcrossing.state;
747 break;
748 default:
749 *x = 0; *y = 0;
750 if (state != NULL)
751 *state = 0;
752 }
753}
754
755 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100756HandleThumb(
757 Widget w,
758 XEvent *event,
759 String *params,
760 Cardinal *num_params)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000761{
762 Position x, y, loc;
763 ScrollbarWidget sbw = (ScrollbarWidget) w;
764
765 ExtractPosition(event, &x, &y, (unsigned int *)NULL);
766 loc = PICKLENGTH(sbw, x, y);
767 /* if the motion event puts the pointer in thumb, call Move and Notify */
768 /* also call Move and Notify if we're already in continuous scroll mode */
769 if (sbw->scrollbar.scroll_mode == SMODE_CONT ||
770 (loc >= sbw->scrollbar.topLoc &&
771 loc <= sbw->scrollbar.topLoc + (int)sbw->scrollbar.shownLength))
772 {
773 XtCallActionProc(w, "MoveThumb", event, params, *num_params);
774 XtCallActionProc(w, "NotifyThumb", event, params, *num_params);
775 }
776}
777
Bram Moolenaar071d4272004-06-13 20:20:40 +0000778 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100779RepeatNotify(XtPointer client_data, XtIntervalId *idp UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000780{
781 ScrollbarWidget sbw = (ScrollbarWidget) client_data;
782 int call_data;
783 char mode = sbw->scrollbar.scroll_mode;
784 unsigned long rep;
785
786 if (mode == SMODE_NONE || mode == SMODE_CONT)
787 {
788 sbw->scrollbar.timer_id = (XtIntervalId)0;
789 return;
790 }
791
792 if (mode == SMODE_LINE_DOWN || mode == SMODE_LINE_UP)
793 {
794 call_data = ONE_LINE_DATA;
795 rep = LINE_REPEAT;
796 }
797 else
798 {
799 call_data = ONE_PAGE_DATA;
800 rep = PAGE_REPEAT;
801 }
802
803 if (mode == SMODE_PAGE_UP || mode == SMODE_LINE_UP)
804 call_data = -call_data;
805
Bram Moolenaar9d6650f2010-06-06 23:04:47 +0200806 XtCallCallbacks((Widget)sbw, XtNscrollProc, (XtPointer)(long_u)call_data);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000807
808 sbw->scrollbar.timer_id =
809 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)sbw),
810 rep,
811 RepeatNotify,
812 client_data);
813}
814
815/*
816 * Same as above, but for floating numbers.
817 */
818 static float
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100819FloatInRange(float num, small, big)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000820{
821 return (num < small) ? small : ((num > big) ? big : num);
822}
823
Bram Moolenaar071d4272004-06-13 20:20:40 +0000824 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100825ScrollOneLineUp(
826 Widget w,
827 XEvent *event,
828 String *params UNUSED,
829 Cardinal *num_params UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000830{
831 ScrollSome(w, event, -ONE_LINE_DATA);
832}
833
Bram Moolenaar071d4272004-06-13 20:20:40 +0000834 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100835ScrollOneLineDown(
836 Widget w,
837 XEvent *event,
838 String *params UNUSED,
839 Cardinal *num_params UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000840{
841 ScrollSome(w, event, ONE_LINE_DATA);
842}
843
Bram Moolenaar071d4272004-06-13 20:20:40 +0000844 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100845ScrollPageDown(
846 Widget w,
847 XEvent *event,
848 String *params UNUSED,
849 Cardinal *num_params UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000850{
851 ScrollSome(w, event, ONE_PAGE_DATA);
852}
853
Bram Moolenaar071d4272004-06-13 20:20:40 +0000854 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100855ScrollPageUp(
856 Widget w,
857 XEvent *event,
858 String *params UNUSED,
859 Cardinal *num_params UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000860{
861 ScrollSome(w, event, -ONE_PAGE_DATA);
862}
863
864 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100865ScrollSome(
866 Widget w,
867 XEvent *event,
868 int call_data)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000869{
870 ScrollbarWidget sbw = (ScrollbarWidget) w;
871
872 if (sbw->scrollbar.scroll_mode == SMODE_CONT) /* if scroll continuous */
873 return;
874
875 if (LookAhead(w, event))
876 return;
877
878 sbw->scrollbar.scroll_mode = SMODE_LINE_UP;
Bram Moolenaar9d6650f2010-06-06 23:04:47 +0200879 XtCallCallbacks(w, XtNscrollProc, (XtPointer)(long_u)call_data);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000880}
881
Bram Moolenaar071d4272004-06-13 20:20:40 +0000882 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100883NotifyScroll(
884 Widget w,
885 XEvent *event,
886 String *params UNUSED,
887 Cardinal *num_params UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000888{
889 ScrollbarWidget sbw = (ScrollbarWidget) w;
890 Position x, y, loc;
891 Dimension arrow_size;
892 unsigned long delay = 0;
893 int call_data = 0;
894 unsigned int state;
895
896 if (sbw->scrollbar.scroll_mode == SMODE_CONT) /* if scroll continuous */
897 return;
898
899 if (LookAhead (w, event))
900 return;
901
902 ExtractPosition(event, &x, &y, &state);
903 loc = PICKLENGTH(sbw, x, y);
904
905 if ((int)sbw->scrollbar.thickness * 2 > (int)sbw->scrollbar.length)
906 arrow_size = sbw->scrollbar.length / 2;
907 else
908 arrow_size = sbw->scrollbar.thickness;
909
910 /*
911 * handle CTRL modifier
912 */
913 if (state & ControlMask)
914 {
915 if (loc > sbw->scrollbar.topLoc + (Position)sbw->scrollbar.shownLength)
916 call_data = END_PAGE_DATA;
917 else
918 call_data = -END_PAGE_DATA;
919 sbw->scrollbar.scroll_mode = SMODE_NONE;
920 }
921 /*
922 * handle first arrow zone
923 */
924 else if (loc < (Position)arrow_size)
925 {
926 call_data = -ONE_LINE_DATA;
927 sbw->scrollbar.scroll_mode = SMODE_LINE_UP;
928 delay = LINE_DELAY;
929 }
930
931 /*
932 * handle last arrow zone
933 */
934 else if (loc > (Position)(sbw->scrollbar.length - arrow_size))
935 {
936 call_data = ONE_LINE_DATA;
937 sbw->scrollbar.scroll_mode = SMODE_LINE_DOWN;
938 delay = LINE_DELAY;
939 }
940
941 /*
942 * handle zone "above" the thumb
943 */
944 else if (loc < sbw->scrollbar.topLoc)
945 {
946 call_data = -ONE_PAGE_DATA;
947 sbw->scrollbar.scroll_mode = SMODE_PAGE_UP;
948 delay = PAGE_DELAY;
949 }
950
951 /*
952 * handle zone "below" the thumb
953 */
954 else if (loc > sbw->scrollbar.topLoc + (Position)sbw->scrollbar.shownLength)
955 {
956 call_data = ONE_PAGE_DATA;
957 sbw->scrollbar.scroll_mode = SMODE_PAGE_DOWN;
958 delay = PAGE_DELAY;
959 }
960
961 if (call_data)
Bram Moolenaar9d6650f2010-06-06 23:04:47 +0200962 XtCallCallbacks(w, XtNscrollProc, (XtPointer)(long_u)call_data);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000963
964 /* establish autoscroll */
965 if (delay)
966 sbw->scrollbar.timer_id =
967 XtAppAddTimeOut(XtWidgetToApplicationContext(w),
968 delay, RepeatNotify, (XtPointer)w);
969}
970
Bram Moolenaar071d4272004-06-13 20:20:40 +0000971 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100972EndScroll(
973 Widget w,
974 XEvent *event UNUSED,
975 String *params UNUSED,
976 Cardinal *num_params UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000977{
978 ScrollbarWidget sbw = (ScrollbarWidget) w;
979
980 sbw->scrollbar.scroll_mode = SMODE_NONE;
981 /* no need to remove any autoscroll timeout; it will no-op */
982 /* because the scroll_mode is SMODE_NONE */
983 /* but be sure to remove timeout in destroy proc */
984}
985
986 static float
Bram Moolenaar66f948e2016-01-30 16:39:25 +0100987FractionLoc(ScrollbarWidget sbw, int x, y)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000988{
989 int margin;
990 float height, width;
991
992 margin = MARGIN(sbw);
993 x -= margin;
994 y -= margin;
995 height = (float)sbw->core.height - 2 * margin;
996 width = (float)sbw->core.width - 2 * margin;
997 return PICKLENGTH(sbw, x / width, y / height);
998}
999
Bram Moolenaar071d4272004-06-13 20:20:40 +00001000 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +01001001MoveThumb(
1002 Widget w,
1003 XEvent *event,
1004 String *params UNUSED,
1005 Cardinal *num_params UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001006{
1007 ScrollbarWidget sbw = (ScrollbarWidget)w;
1008 Position x, y;
1009 float top;
1010 char old_mode = sbw->scrollbar.scroll_mode;
1011
1012 sbw->scrollbar.scroll_mode = SMODE_CONT; /* indicate continuous scroll */
1013
1014 if (LookAhead(w, event))
1015 return;
1016
1017 if (!event->xmotion.same_screen)
1018 return;
1019
1020 ExtractPosition(event, &x, &y, (unsigned int *)NULL);
1021
1022 top = FractionLoc(sbw, x, y);
1023
1024 if (old_mode != SMODE_CONT) /* start dragging: set offset */
1025 {
1026 if (event->xbutton.button == Button2)
1027 sbw->scrollbar.scroll_off = sbw->scrollbar.shown / 2.;
1028 else
1029 sbw->scrollbar.scroll_off = top - sbw->scrollbar.top;
1030 }
1031
1032 top -= sbw->scrollbar.scroll_off;
1033 if (sbw->scrollbar.limit_thumb)
1034 top = FloatInRange(top, 0.0,
1035 sbw->scrollbar.max - sbw->scrollbar.shown + 0.000001);
1036 else
1037 top = FloatInRange(top, 0.0, sbw->scrollbar.max);
1038
1039 sbw->scrollbar.top = top;
1040 PaintThumb(sbw);
1041 XFlush(XtDisplay(w)); /* re-draw it before Notifying */
1042}
1043
1044
Bram Moolenaar071d4272004-06-13 20:20:40 +00001045 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +01001046NotifyThumb(
1047 Widget w,
1048 XEvent *event,
1049 String *params UNUSED,
1050 Cardinal *num_params UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001051{
1052 ScrollbarWidget sbw = (ScrollbarWidget)w;
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00001053 /* Use a union to avoid a warning for the weird conversion from float to
1054 * XtPointer. Comes from Xaw/Scrollbar.c. */
1055 union {
1056 XtPointer xtp;
1057 float xtf;
1058 } xtpf;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001059
1060 if (LookAhead(w, event))
1061 return;
1062
1063 /* thumbProc is not pretty, but is necessary for backwards
1064 compatibility on those architectures for which it work{s,ed};
1065 the intent is to pass a (truncated) float by value. */
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00001066 xtpf.xtf = sbw->scrollbar.top;
1067 XtCallCallbacks(w, XtNthumbProc, xtpf.xtp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001068 XtCallCallbacks(w, XtNjumpProc, (XtPointer)&sbw->scrollbar.top);
1069}
1070
Bram Moolenaar071d4272004-06-13 20:20:40 +00001071 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +01001072AllocTopShadowGC(Widget w)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001073{
1074 ScrollbarWidget sbw = (ScrollbarWidget) w;
1075 XtGCMask valuemask;
1076 XGCValues myXGCV;
1077
1078 valuemask = GCForeground;
1079 myXGCV.foreground = sbw->scrollbar.top_shadow_pixel;
1080 sbw->scrollbar.top_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
1081}
1082
Bram Moolenaar071d4272004-06-13 20:20:40 +00001083 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +01001084AllocBotShadowGC(Widget w)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001085{
1086 ScrollbarWidget sbw = (ScrollbarWidget) w;
1087 XtGCMask valuemask;
1088 XGCValues myXGCV;
1089
1090 valuemask = GCForeground;
1091 myXGCV.foreground = sbw->scrollbar.bot_shadow_pixel;
1092 sbw->scrollbar.bot_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
1093}
1094
Bram Moolenaar071d4272004-06-13 20:20:40 +00001095 static void
Bram Moolenaar66f948e2016-01-30 16:39:25 +01001096_Xaw3dDrawShadows(
1097 Widget gw,
1098 XEvent *event UNUSED,
1099 Region region,
1100 int out)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001101{
1102 XPoint pt[6];
1103 ScrollbarWidget sbw = (ScrollbarWidget) gw;
1104 Dimension s = sbw->scrollbar.shadow_width;
1105 /*
1106 * draw the shadows using the core part width and height,
1107 * and the scrollbar part shadow_width.
1108 *
1109 * no point to do anything if the shadow_width is 0 or the
1110 * widget has not been realized.
1111 */
1112 if (s > 0 && XtIsRealized(gw))
1113 {
1114 Dimension h = sbw->core.height;
1115 Dimension w = sbw->core.width;
1116 Dimension wms = w - s;
1117 Dimension hms = h - s;
1118 Display *dpy = XtDisplay (gw);
1119 Window win = XtWindow (gw);
1120 GC top, bot;
1121
1122 if (out)
1123 {
1124 top = sbw->scrollbar.top_shadow_GC;
1125 bot = sbw->scrollbar.bot_shadow_GC;
1126 }
1127 else
1128 {
1129 top = sbw->scrollbar.bot_shadow_GC;
1130 bot = sbw->scrollbar.top_shadow_GC;
1131 }
1132
1133 /* top-left shadow */
1134 if ((region == NULL) ||
1135 (XRectInRegion (region, 0, 0, w, s) != RectangleOut) ||
1136 (XRectInRegion (region, 0, 0, s, h) != RectangleOut))
1137 {
1138 pt[0].x = 0; pt[0].y = h;
1139 pt[1].x = pt[1].y = 0;
1140 pt[2].x = w; pt[2].y = 0;
1141 pt[3].x = wms; pt[3].y = s;
1142 pt[4].x = pt[4].y = s;
1143 pt[5].x = s; pt[5].y = hms;
1144 XFillPolygon (dpy, win, top, pt, 6, Complex, CoordModeOrigin);
1145 }
1146
1147 /* bottom-right shadow */
1148 if ((region == NULL) ||
1149 (XRectInRegion (region, 0, hms, w, s) != RectangleOut) ||
1150 (XRectInRegion (region, wms, 0, s, h) != RectangleOut))
1151 {
1152 pt[0].x = 0; pt[0].y = h;
1153 pt[1].x = w; pt[1].y = h;
1154 pt[2].x = w; pt[2].y = 0;
1155 pt[3].x = wms; pt[3].y = s;
1156 pt[4].x = wms; pt[4].y = hms;
1157 pt[5].x = s; pt[5].y = hms;
1158 XFillPolygon (dpy, win, bot, pt, 6, Complex, CoordModeOrigin);
1159 }
1160 }
1161}
1162
1163
1164/*
1165 * Set the scroll bar to the given location.
1166 */
1167 void
Bram Moolenaar66f948e2016-01-30 16:39:25 +01001168vim_XawScrollbarSetThumb(Widget w, double top, shown, max)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001169{
1170 ScrollbarWidget sbw = (ScrollbarWidget) w;
1171
1172 if (sbw->scrollbar.scroll_mode == SMODE_CONT) /* if still thumbing */
1173 return;
1174
1175 sbw->scrollbar.max = (max > 1.0) ? 1.0 :
1176 (max >= 0.0) ? max : sbw->scrollbar.max;
1177
1178 sbw->scrollbar.top = (top > sbw->scrollbar.max) ? sbw->scrollbar.max :
1179 (top >= 0.0) ? top : sbw->scrollbar.top;
1180
1181 sbw->scrollbar.shown = (shown > 1.0) ? 1.0 :
1182 (shown >= 0.0) ? shown : sbw->scrollbar.shown;
1183
1184 PaintThumb(sbw);
1185}