1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$TOG: ScrollBar.c /main/20 1997/03/10 14:52:28 dbl $"
26 #endif
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33
34 #ifndef X_NOT_STDC_ENV
35 #include <stdlib.h>
36 #endif
37
38 #include <Xm/DisplayP.h> /* for enableThinThickness */
39 #include <Xm/DrawP.h>
40 #include <Xm/DropSMgr.h> /* for XmDropSiteStartUpdate/EndUPdate */
41 #include <Xm/ManagerP.h>
42 #include <Xm/NavigatorT.h>
43 #include <Xm/ScrollBarP.h>
44 #include <Xm/TraitP.h>
45 #include <Xm/TransltnsP.h>
46 #include <Xm/VaSimpleP.h>
47 #include "ColorI.h"
48 #include "MessagesI.h"
49 #include "RepTypeI.h"
50 #include "ScreenI.h"
51 #include "XmI.h"
52
53 /* see comments in ScrollBarP.h */
54 #define slider_visual etched_slider
55 #define flat_slider_GC unhighlight_GC
56
57 #define MESSAGE1 _XmMMsgScrollBar_0000
58 #define MESSAGE2 _XmMMsgScrollBar_0001
59 #define MESSAGE3 _XmMMsgScrollBar_0002
60 #define MESSAGE4 _XmMMsgScrollBar_0003
61 #define MESSAGE6 _XmMMsgScaleScrBar_0004
62 #define MESSAGE7 _XmMMsgScrollBar_0004
63 #define MESSAGE8 _XmMMsgScrollBar_0005
64 #define MESSAGE9 _XmMMsgScrollBar_0006
65 #define MESSAGE10 _XmMMsgScrollBar_0007
66 #define MESSAGE13 _XmMMsgScrollBar_0008
67 #define MESSAGE14 _XmMMsgMotif_0001
68
69 #define MAXDIMENSION 65535
70
71 #define DRAWARROW(sbw, t_gc, b_gc, x, y, dir)\
72 XmeDrawArrow(XtDisplay ((Widget) sbw),\
73 XtWindow ((Widget) sbw),\
74 t_gc, b_gc,\
75 sbw->scrollBar.foreground_GC,\
76 x-1, y-1,\
77 sbw->scrollBar.arrow_width+2,\
78 sbw->scrollBar.arrow_height+2,\
79 sbw->primitive.shadow_thickness,\
80 dir);
81
82 #define PROCESS_DIR_INVERSED(sbw) \
83 ((sbw->scrollBar.processing_direction == XmMAX_ON_LEFT) || \
84 (sbw->scrollBar.processing_direction == XmMAX_ON_TOP))
85
86 #define INVERSED_VALUE(sbw) \
87 (sbw->scrollBar.maximum + sbw->scrollBar.minimum - \
88 sbw->scrollBar.value - sbw->scrollBar.slider_size)
89
90 /******** Static Function Declarations ********/
91
92 static void ClassPartInitialize(
93 WidgetClass wc) ;
94 static void ProcessingDirectionDefault(
95 XmScrollBarWidget widget,
96 int offset,
97 XrmValue *value) ;
98 static void BackgroundPixelDefault(
99 XmScrollBarWidget widget,
100 int offset,
101 XrmValue *value) ;
102 static void TraversalDefault(
103 XmScrollBarWidget widget,
104 int offset,
105 XrmValue *value) ;
106 static void HighlightDefault(
107 XmScrollBarWidget widget,
108 int offset,
109 XrmValue *value) ;
110 static void SliderVisualDefault(
111 XmScrollBarWidget widget,
112 int offset,
113 XrmValue *value) ;
114 static void SliderMarkDefault(
115 XmScrollBarWidget widget,
116 int offset,
117 XrmValue *value) ;
118 static void EditableDefault(
119 XmScrollBarWidget widget,
120 int offset,
121 XrmValue *value) ;
122 static void Initialize(
123 Widget rw,
124 Widget nw,
125 ArgList args,
126 Cardinal *num_args) ;
127 static void GetForegroundGC(
128 XmScrollBarWidget sbw) ;
129 static void GetUnavailableGC(
130 XmScrollBarWidget sbw) ;
131 static void GetFlatSliderGC(
132 XmScrollBarWidget sbw) ;
133 static void GetSliderPixmap(
134 XmScrollBarWidget sbw) ;
135 static void CalcSliderRect(
136 XmScrollBarWidget sbw,
137 short *slider_x,
138 short *slider_y,
139 short *slider_width,
140 short *slider_height) ;
141 static void DrawSliderPixmap(
142 XmScrollBarWidget sbw) ;
143 static void Redisplay(
144 Widget wid,
145 XEvent *event,
146 Region region) ;
147 static void Resize(
148 Widget wid) ;
149 static void Realize(
150 Widget sbw,
151 XtValueMask *window_mask,
152 XSetWindowAttributes *window_attributes) ;
153 static void Destroy(
154 Widget wid) ;
155 static Boolean ValidateInputs(
156 XmScrollBarWidget current,
157 XmScrollBarWidget request,
158 XmScrollBarWidget new_w) ;
159 static Boolean SetValues(
160 Widget cw,
161 Widget rw,
162 Widget nw,
163 ArgList args,
164 Cardinal *num_args) ;
165 static int CalcSliderVal(
166 XmScrollBarWidget sbw,
167 int x,
168 int y) ;
169 static void Select(
170 Widget wid,
171 XEvent *event,
172 String *params,
173 Cardinal *num_params) ;
174 static void Release(
175 Widget wid,
176 XEvent *event,
177 String *params,
178 Cardinal *num_params) ;
179 static void Moved(
180 Widget wid,
181 XEvent *event,
182 String *params,
183 Cardinal *num_params) ;
184 static void TopOrBottom(
185 Widget wid,
186 XEvent *event,
187 String *params,
188 Cardinal *num_params) ;
189 static void IncrementUpOrLeft(
190 Widget wid,
191 XEvent *event,
192 String *params,
193 Cardinal *num_params) ;
194 static void IncrementDownOrRight(
195 Widget wid,
196 XEvent *event,
197 String *params,
198 Cardinal *num_params) ;
199 static void PageUpOrLeft(
200 Widget wid,
201 XEvent *event,
202 String *params,
203 Cardinal *num_params) ;
204 static void PageDownOrRight(
205 Widget wid,
206 XEvent *event,
207 String *params,
208 Cardinal *num_params) ;
209 static void CancelDrag(
210 Widget wid,
211 XEvent *event,
212 String *params,
213 Cardinal *num_params) ;
214 static void MoveSlider(
215 XmScrollBarWidget sbw,
216 int currentX,
217 int currentY) ;
218 static void RedrawSliderWindow(
219 XmScrollBarWidget sbw) ;
220 static Boolean ChangeScrollBarValue(
221 XmScrollBarWidget sbw) ;
222 static void TimerEvent(
223 XtPointer closure,
224 XtIntervalId *id) ;
225 static void ScrollCallback(
226 XmScrollBarWidget sbw,
227 int reason,
228 int value,
229 int xpixel,
230 int ypixel,
231 XEvent *event) ;
232 static void ExportScrollBarValue(
233 Widget wid,
234 int offset,
235 XtArgVal *value) ;
236 static XmImportOperator ImportScrollBarValue(
237 Widget wid,
238 int offset,
239 XtArgVal *value) ;
240
241
242 static void NavigChangeMoveCB(Widget nav,
243 XtCallbackProc moveProc,
244 XtPointer closure,
245 Boolean setunset) ;
246 static void NavigSetValue(Widget nav,
247 XmNavigatorData nav_data,
248 Boolean notify) ;
249 static void NavigGetValue(Widget nav,
250 XmNavigatorData nav_data) ;
251
252 /******** End Static Function Declarations ********/
253
254 /* Default translation table and action list */
255
256 #define defaultTranslations _XmScrollBar_defaultTranslations
257
258 static XtActionsRec actions[] =
259 {
260 { "Select", Select },
261 { "Release", Release },
262 { "Moved", Moved },
263 { "TopOrBottom", TopOrBottom },
264 { "IncrementUpOrLeft", IncrementUpOrLeft },
265 { "IncrementDownOrRight", IncrementDownOrRight },
266 { "PageUpOrLeft", PageUpOrLeft },
267 { "PageDownOrRight", PageDownOrRight },
268 { "CancelDrag", CancelDrag },
269 };
270
271
272 /* Resource list for ScrollBar */
273
274 static XtResource resources[] =
275 {
276 { XmNnavigationType, XmCNavigationType, XmRNavigationType,
277 sizeof(unsigned char),
278 XtOffsetOf(XmScrollBarRec, primitive.navigation_type),
279 XmRImmediate, (XtPointer) XmSTICKY_TAB_GROUP
280 },
281 { XmNbackground, XmCBackground, XmRPixel, sizeof(Pixel),
282 XtOffsetOf(XmScrollBarRec, core.background_pixel),
283 XmRCallProc, (XtPointer) BackgroundPixelDefault
284 },
285 { XmNtroughColor, XmCTroughColor, XmRPixel, sizeof(Pixel),
286 XtOffsetOf(XmScrollBarRec, scrollBar.trough_color),
287 XmRCallProc, (XtPointer) _XmSelectColorDefault
288 },
289 { XmNvalue, XmCValue, XmRInt, sizeof (int),
290 XtOffsetOf(XmScrollBarRec, scrollBar.value),
291 XmRImmediate, (XtPointer) XmINVALID_DIMENSION
292 },
293 { XmNminimum, XmCMinimum, XmRInt, sizeof (int),
294 XtOffsetOf(XmScrollBarRec, scrollBar.minimum),
295 XmRImmediate, (XtPointer) 0
296 },
297 { XmNmaximum, XmCMaximum, XmRInt, sizeof (int),
298 XtOffsetOf(XmScrollBarRec, scrollBar.maximum),
299 XmRImmediate, (XtPointer) 100
300 },
301 { XmNsliderSize, XmCSliderSize, XmRInt, sizeof (int),
302 XtOffsetOf(XmScrollBarRec, scrollBar.slider_size),
303 XmRImmediate, (XtPointer) XmINVALID_DIMENSION
304 },
305 { XmNshowArrows, XmCShowArrows, XmRShowArrows, sizeof (XtEnum),
306 XtOffsetOf(XmScrollBarRec, scrollBar.show_arrows),
307 XmRImmediate, (XtPointer) XmEACH_SIDE
308 },
309 { XmNorientation, XmCOrientation,
310 XmROrientation, sizeof (unsigned char),
311 XtOffsetOf(XmScrollBarRec, scrollBar.orientation),
312 XmRImmediate, (XtPointer) XmVERTICAL
313 },
314 { XmNprocessingDirection, XmCProcessingDirection,
315 XmRProcessingDirection, sizeof (unsigned char),
316 XtOffsetOf(XmScrollBarRec, scrollBar.processing_direction),
317 XmRCallProc, (XtPointer) ProcessingDirectionDefault
318 },
319 { XmNincrement, XmCIncrement, XmRInt, sizeof (int),
320 XtOffsetOf(XmScrollBarRec, scrollBar.increment),
321 XmRImmediate, (XtPointer) 1
322 },
323 { XmNpageIncrement, XmCPageIncrement, XmRInt, sizeof (int),
324 XtOffsetOf(XmScrollBarRec, scrollBar.page_increment),
325 XmRImmediate, (XtPointer) 10
326 },
327 { XmNinitialDelay, XmCInitialDelay, XmRInt, sizeof (int),
328 XtOffsetOf(XmScrollBarRec, scrollBar.initial_delay),
329 XmRImmediate, (XtPointer) 250
330 },
331 { XmNrepeatDelay, XmCRepeatDelay, XmRInt, sizeof (int),
332 XtOffsetOf(XmScrollBarRec, scrollBar.repeat_delay),
333 XmRImmediate, (XtPointer) 50
334 },
335 { XmNvalueChangedCallback, XmCCallback,
336 XmRCallback, sizeof(XtCallbackList),
337 XtOffsetOf(XmScrollBarRec, scrollBar.value_changed_callback),
338 XmRPointer, (XtPointer) NULL
339 },
340 { XmNincrementCallback, XmCCallback,
341 XmRCallback, sizeof(XtCallbackList),
342 XtOffsetOf(XmScrollBarRec, scrollBar.increment_callback),
343 XmRPointer, (XtPointer) NULL
344 },
345 { XmNdecrementCallback, XmCCallback,
346 XmRCallback, sizeof(XtCallbackList),
347 XtOffsetOf(XmScrollBarRec, scrollBar.decrement_callback),
348 XmRPointer, (XtPointer) NULL
349 },
350 { XmNpageIncrementCallback, XmCCallback,
351 XmRCallback, sizeof(XtCallbackList),
352 XtOffsetOf(XmScrollBarRec, scrollBar.page_increment_callback),
353 XmRPointer, (XtPointer) NULL
354 },
355 { XmNpageDecrementCallback, XmCCallback,
356 XmRCallback, sizeof (XtCallbackList),
357 XtOffsetOf(XmScrollBarRec, scrollBar.page_decrement_callback),
358 XmRPointer, (XtPointer) NULL
359 },
360 { XmNtoTopCallback, XmCCallback,
361 XmRCallback, sizeof(XtCallbackList),
362 XtOffsetOf(XmScrollBarRec, scrollBar.to_top_callback),
363 XmRPointer, (XtPointer) NULL
364 },
365 { XmNtoBottomCallback, XmCCallback,
366 XmRCallback, sizeof(XtCallbackList),
367 XtOffsetOf(XmScrollBarRec, scrollBar.to_bottom_callback),
368 XmRPointer, (XtPointer) NULL
369 },
370 { XmNdragCallback, XmCCallback,
371 XmRCallback, sizeof(XtCallbackList),
372 XtOffsetOf(XmScrollBarRec, scrollBar.drag_callback),
373 XmRPointer, (XtPointer) NULL
374 },
375 {
376 XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
377 XtOffsetOf(XmPrimitiveRec, primitive.traversal_on),
378 XmRCallProc, (XtPointer) TraversalDefault
379 },
380 {
381 XmNhighlightThickness, XmCHighlightThickness,
382 XmRHorizontalDimension, sizeof (Dimension),
383 XtOffsetOf(XmPrimitiveRec, primitive.highlight_thickness),
384 XmRCallProc, (XtPointer) HighlightDefault
385 },
386 {
387 XmNsnapBackMultiple, XmCSnapBackMultiple, XmRShort,
388 sizeof (unsigned short),
389 XtOffsetOf(XmScrollBarRec, scrollBar.snap_back_multiple),
390 XmRImmediate, (XtPointer) MAXDIMENSION
391 },
392 {
393 XmNslidingMode, XmCSlidingMode, XmRSlidingMode,
394 sizeof(XtEnum), XtOffsetOf(XmScrollBarRec, scrollBar.sliding_mode),
395 XmRImmediate, (XtPointer) XmSLIDER
396 },
397 {
398 XmNeditable, XmCEditable, XmRBoolean,
399 sizeof(XtEnum), XtOffsetOf(XmScrollBarRec,scrollBar.editable),
400 XmRCallProc, (XtPointer) EditableDefault
401 },
402 {
403 XmNsliderVisual, XmCSliderVisual, XmRSliderVisual,
404 sizeof (XtEnum),
405 XtOffsetOf(XmScrollBarRec, scrollBar.slider_visual),
406 XmRCallProc, (XtPointer) SliderVisualDefault
407 },
408 {
409 XmNsliderMark, XmCSliderMark, XmRSliderMark,
410 sizeof (XtEnum),
411 XtOffsetOf(XmScrollBarRec, scrollBar.slider_mark),
412 XmRCallProc, (XtPointer) SliderMarkDefault
413 },
414 };
415
416
417 /* Definition for resources that need special processing in get values */
418
419 static XmSyntheticResource syn_resources[] =
420 {
421 { XmNvalue,
422 sizeof (int),
423 XtOffsetOf(XmScrollBarRec, scrollBar.value),
424 ExportScrollBarValue,
425 ImportScrollBarValue
426 },
427 };
428
429
430 externaldef(xmscrollbarclassrec) XmScrollBarClassRec xmScrollBarClassRec =
431 {
432 {
433 (WidgetClass) &xmPrimitiveClassRec, /* superclass */
434 "XmScrollBar", /* class_name */
435 sizeof(XmScrollBarRec), /* widget_size */
436 NULL, /* class_initialize */
437 ClassPartInitialize, /* class_part_initialize */
438 FALSE, /* class_inited */
439 Initialize, /* initialize */
440 (XtArgsProc)NULL, /* initialize_hook */
441 Realize, /* realize */
442 actions, /* actions */
443 XtNumber(actions), /* num_actions */
444 resources, /* resources */
445 XtNumber(resources), /* num_resources */
446 NULLQUARK, /* xrm_class */
447 TRUE, /* compress_motion */
448 XtExposeCompressMaximal, /* compress_exposure */
449 TRUE, /* compress_enterleave */
450 FALSE, /* visible_interest */
451 Destroy, /* destroy */
452 Resize, /* resize */
453 Redisplay, /* expose */
454 SetValues, /* set_values */
455 (XtArgsFunc)NULL, /* set_values_hook */
456 XtInheritSetValuesAlmost, /* set_values_almost */
457 (XtArgsProc)NULL, /* get_values_hook */
458 (XtAcceptFocusProc)NULL, /* accept_focus */
459 XtVersion, /* version */
460 NULL, /* callback private */
461 defaultTranslations, /* tm_table */
462 (XtGeometryHandler)NULL, /* query_geometry */
463 (XtStringProc)NULL, /* display_accelerator */
464 (XtPointer) NULL, /* extension */
465 },
466
467 {
468 XmInheritWidgetProc, /* border_highlight */
469 XmInheritWidgetProc, /* border_unhighlight */
470 NULL, /* translations */
471 (XtActionProc)NULL, /* arm_and_activate */
472 syn_resources, /* syn_resources */
473 XtNumber(syn_resources), /* num syn_resources */
474 NULL, /* extension */
475 },
476
477 {
478 (XtPointer) NULL, /* extension */
479 },
480 };
481
482 externaldef(xmscrollbarwidgetclass) WidgetClass xmScrollBarWidgetClass =
483 (WidgetClass) &xmScrollBarClassRec;
484
485
486 /* Trait record for ScrollBar */
487
488 static XmConst XmNavigatorTraitRec scrollBarNT = {
489 0, /* version */
490 NavigChangeMoveCB,
491 NavigSetValue,
492 NavigGetValue,
493 };
494
495 /*********************************************************************
496 *
497 * ExportScrollBarValue
498 * Convert the scrollbar value from the normal processing direction
499 * to reverse processing if needed.
500 *
501 *********************************************************************/
502 /*ARGSUSED*/
503 static void
ExportScrollBarValue(Widget wid,int offset,XtArgVal * value)504 ExportScrollBarValue(
505 Widget wid,
506 int offset, /* unused */
507 XtArgVal *value )
508 {
509 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
510 if (PROCESS_DIR_INVERSED(sbw))
511 *value = (XtArgVal) INVERSED_VALUE(sbw);
512 else
513 *value = (XtArgVal) sbw->scrollBar.value;
514 }
515
516 /*********************************************************************
517 *
518 * ImportScrollBarValue
519 * Indicate that the value did indeed change.
520 *
521 *********************************************************************/
522 /*ARGSUSED*/
523 static XmImportOperator
ImportScrollBarValue(Widget wid,int offset,XtArgVal * value)524 ImportScrollBarValue(
525 Widget wid,
526 int offset, /* unused */
527 XtArgVal *value )
528 {
529 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
530
531 sbw->scrollBar.flags |= VALUE_SET_FLAG;
532 *value = (XtArgVal)sbw->scrollBar.value;
533 return(XmSYNTHETIC_LOAD);
534 }
535
536
537 /*********************************************************************
538 *
539 * ProcessingDirectionDefault
540 * This procedure provides the dynamic default behavior for
541 * the processing direction resource dependent on the orientation.
542 *
543 *********************************************************************/
544 /*ARGSUSED*/
545 static void
ProcessingDirectionDefault(XmScrollBarWidget widget,int offset,XrmValue * value)546 ProcessingDirectionDefault(
547 XmScrollBarWidget widget,
548 int offset, /* unused */
549 XrmValue *value )
550 {
551 static unsigned char direction;
552
553 value->addr = (XPointer) &direction;
554
555 if (widget->scrollBar.orientation == XmHORIZONTAL)
556 {
557 if (LayoutIsRtoLP(widget))
558 direction = XmMAX_ON_LEFT;
559 else
560 direction = XmMAX_ON_RIGHT;
561 }
562 else /* XmVERTICAL -- range checking done during widget
563 initialization */
564 direction = XmMAX_ON_BOTTOM;
565 }
566
567
568 /*********************************************************************
569 *
570 * BackgroundPixelDefault
571 * This procedure provides the dynamic default behavior for
572 * the background color. It looks to see if the parent is a
573 * ScrolledWindow, and if so, it uses the parent background.
574 * This is mostly for compatibility with 1.1 where the scrolledwindow
575 * was forcing its scrollbar color to its own background.
576 * Note that it works for both automatic and non automatic SW,
577 * which is a new feature for non automatic.
578 *
579 *********************************************************************/
580 static void
BackgroundPixelDefault(XmScrollBarWidget widget,int offset,XrmValue * value)581 BackgroundPixelDefault(
582 XmScrollBarWidget widget,
583 int offset,
584 XrmValue *value )
585 {
586 static Pixel background;
587 Widget parent = XtParent(widget) ;
588
589 if (XmIsScrolledWindow(parent)) {
590 value->addr = (XPointer) &background;
591 background = parent->core.background_pixel;
592 return ;
593 }
594
595 /* else use the primitive defaulting mechanism */
596
597 _XmBackgroundColorDefault((Widget )widget, offset, value);
598 }
599
600 /*********************************************************************
601 *
602 * TraversalDefault
603 * This procedure provides the dynamic default behavior for
604 * the traversal. It looks to see if the parent is a
605 * ScrolledWindow, and if so, it sets it to On.
606 * This is mostly for compatibility with 1.1 where the scrolledwindow
607 * was forcing its scrollbar traversal to On
608 * Note that it works only for automatic.
609 *
610 *********************************************************************/
611 /*ARGSUSED*/
612 static void
TraversalDefault(XmScrollBarWidget widget,int offset,XrmValue * value)613 TraversalDefault(
614 XmScrollBarWidget widget,
615 int offset, /* unused */
616 XrmValue *value )
617 {
618 static Boolean traversal ;
619 Widget parent = XtParent(widget) ;
620 Arg al[1] ;
621 unsigned char sp ;
622
623 traversal = False ;
624 value->addr = (XPointer) &traversal;
625
626 if (XmIsScrolledWindow(parent)) {
627 XtSetArg(al[0], XmNscrollingPolicy, &sp);
628 XtGetValues(parent, al, 1);
629 if (sp == XmAUTOMATIC) {
630 traversal = True ;
631 return ;
632 }
633 }
634 }
635
636
637
638 /*********************************************************************
639 *
640 * SliderVisualDefault
641 *
642 *
643 *********************************************************************/
644 /*ARGSUSED*/
645 static void
SliderVisualDefault(XmScrollBarWidget widget,int offset,XrmValue * value)646 SliderVisualDefault(
647 XmScrollBarWidget widget,
648 int offset, /* unused */
649 XrmValue *value )
650 {
651 static XtEnum slider_visual ;
652
653 value->addr = (XPointer) &slider_visual;
654
655 if (widget->scrollBar.sliding_mode == XmTHERMOMETER) {
656 slider_visual = XmTROUGH_COLOR ;
657 } else {
658 slider_visual = XmSHADOWED_BACKGROUND ;
659 }
660
661 }
662
663
664
665 /*********************************************************************
666 *
667 * SliderMarkDefault
668 *
669 *
670 *********************************************************************/
671 /*ARGSUSED*/
672 static void
SliderMarkDefault(XmScrollBarWidget widget,int offset,XrmValue * value)673 SliderMarkDefault(
674 XmScrollBarWidget widget,
675 int offset, /* unused */
676 XrmValue *value )
677 {
678 static XtEnum slider_mark ;
679
680 value->addr = (XPointer) &slider_mark;
681
682 if ((widget->scrollBar.sliding_mode == XmTHERMOMETER) &&
683 (widget->scrollBar.editable))
684 slider_mark = XmROUND_MARK ;
685 else
686 slider_mark = XmNONE ;
687 }
688
689
690
691 /*********************************************************************
692 *
693 * EditableDefault
694 *
695 *
696 *********************************************************************/
697 /*ARGSUSED*/
698 static void
EditableDefault(XmScrollBarWidget widget,int offset,XrmValue * value)699 EditableDefault(
700 XmScrollBarWidget widget,
701 int offset, /* unused */
702 XrmValue *value )
703 {
704 static XtEnum editable ;
705
706 value->addr = (XPointer) &editable;
707
708 if (widget->scrollBar.sliding_mode == XmTHERMOMETER) {
709 editable = False ;
710 } else {
711 editable = True ;
712 }
713
714 }
715
716 /*********************************************************************
717 *
718 * HighlightDefault
719 * This procedure provides the dynamic default behavior for
720 * the highlight. It looks to see if the parent is a
721 * ScrolledWindow, and if so, it sets it to 2 or 1 depending on
722 * the enableThinThickness resource, otherwise, 0.
723 * Note that it works only for automatic.
724 *
725 *********************************************************************/
726 /*ARGSUSED*/
727 static void
HighlightDefault(XmScrollBarWidget widget,int offset,XrmValue * value)728 HighlightDefault(
729 XmScrollBarWidget widget,
730 int offset, /* unused */
731 XrmValue *value )
732 {
733 static Dimension highlight ;
734 Widget parent = XtParent(widget) ;
735 Arg al[1] ;
736 unsigned char sp ;
737 Boolean thinthickness = False;
738
739 highlight = 0 ;
740 value->addr = (XPointer) &highlight;
741
742 if (XmIsScrolledWindow(parent)) {
743 XtSetArg(al[0], XmNscrollingPolicy, &sp);
744 XtGetValues(parent, al, 1);
745 if (sp == XmAUTOMATIC) {
746 XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(widget));
747 thinthickness = dpy->display.enable_thin_thickness;
748
749 if (thinthickness) {
750 highlight = 1;
751 }
752 else {
753 highlight = 2 ;
754 }
755 return ;
756 }
757 }
758 }
759
760
761
762
763 /*********************************************************************
764 *
765 * ClassPartInitialize
766 * Initialize the fast subclassing.
767 *
768 *********************************************************************/
769 static void
ClassPartInitialize(WidgetClass wc)770 ClassPartInitialize(
771 WidgetClass wc )
772 {
773 _XmFastSubclassInit (wc, XmSCROLL_BAR_BIT);
774
775 /* Install the navigator trait for all subclasses */
776 XmeTraitSet((XtPointer)wc, XmQTnavigator, (XtPointer) &scrollBarNT);
777 }
778
779
780
781
782
783
784 /*********************************************************************
785 *
786 * Initialize
787 * The main widget instance initialization routine.
788 *
789 *********************************************************************/
790 /*ARGSUSED*/
791 static void
Initialize(Widget rw,Widget nw,ArgList args,Cardinal * num_args)792 Initialize(
793 Widget rw,
794 Widget nw,
795 ArgList args, /* unused */
796 Cardinal *num_args ) /* unused */
797 {
798 XmScrollBarWidget request = (XmScrollBarWidget) rw ;
799 XmScrollBarWidget new_w = (XmScrollBarWidget) nw ;
800
801 Boolean default_value = FALSE;
802
803 if(!XmRepTypeValidValue( XmRID_SHOW_ARROWS,
804 new_w->scrollBar.show_arrows, (Widget) new_w) )
805 {
806 new_w->scrollBar.show_arrows = XmEACH_SIDE;
807 }
808
809 if(!XmRepTypeValidValue( XmRID_SLIDER_VISUAL,
810 new_w->scrollBar.slider_visual, (Widget) new_w) )
811 {
812 new_w->scrollBar.slider_visual = XmSHADOWED_BACKGROUND;
813 }
814
815 if(!XmRepTypeValidValue( XmRID_SLIDER_MARK,
816 new_w->scrollBar.slider_mark, (Widget) new_w) )
817 {
818 new_w->scrollBar.slider_mark = XmNONE;
819 }
820
821 if(!XmRepTypeValidValue( XmRID_SLIDING_MODE,
822 new_w->scrollBar.sliding_mode, (Widget) new_w) )
823 {
824 new_w->scrollBar.sliding_mode = XmSLIDER;
825 }
826
827 if (new_w->scrollBar.value == XmINVALID_DIMENSION)
828 {
829 new_w->scrollBar.value = 0;
830 default_value = True;
831 }
832
833 /* Validate the incoming data */
834
835 if (new_w->scrollBar.minimum >= new_w->scrollBar.maximum)
836 {
837 new_w->scrollBar.minimum = 0;
838 new_w->scrollBar.maximum = 100;
839 XmeWarning( (Widget) new_w, MESSAGE1);
840 }
841
842 if (new_w->scrollBar.slider_size == XmINVALID_DIMENSION)
843 {
844 new_w->scrollBar.slider_size = (new_w->scrollBar.maximum
845 - new_w->scrollBar.minimum) / 10;
846 if (new_w->scrollBar.slider_size < 1)
847 new_w->scrollBar.slider_size = 1;
848 }
849
850 if (new_w->scrollBar.slider_size < 1)
851 {
852 new_w->scrollBar.slider_size = 1;
853 XmeWarning( (Widget) new_w, MESSAGE2);
854 }
855
856 if (new_w->scrollBar.slider_size >
857 (new_w->scrollBar.maximum - new_w->scrollBar.minimum))
858 {
859 new_w->scrollBar.slider_size = new_w->scrollBar.maximum
860 - new_w->scrollBar.minimum;
861 XmeWarning( (Widget) new_w, MESSAGE13);
862 }
863
864 /* in thermo, slider_size is forced to be 0 */
865 if (new_w->scrollBar.sliding_mode == XmTHERMOMETER)
866 new_w->scrollBar.slider_size = 0 ;
867
868 if (new_w->scrollBar.value < new_w->scrollBar.minimum)
869 {
870 new_w->scrollBar.value = new_w->scrollBar.minimum;
871 if (!default_value) XmeWarning( (Widget) new_w, MESSAGE3);
872 }
873
874 if (new_w->scrollBar.value >
875 new_w->scrollBar.maximum - new_w->scrollBar.slider_size)
876 {
877 new_w->scrollBar.value = new_w->scrollBar.minimum;
878 if (!default_value) XmeWarning( (Widget) new_w, MESSAGE4);
879 }
880
881 if( !XmRepTypeValidValue(XmRID_ORIENTATION,
882 new_w->scrollBar.orientation, (Widget) new_w))
883 {
884 new_w->scrollBar.orientation = XmVERTICAL;
885 }
886
887 if (new_w->scrollBar.orientation == XmHORIZONTAL)
888 {
889 if ((new_w->scrollBar.processing_direction != XmMAX_ON_RIGHT) &&
890 (new_w->scrollBar.processing_direction != XmMAX_ON_LEFT))
891
892 {
893 new_w->scrollBar.processing_direction = XmMAX_ON_RIGHT;
894 XmeWarning( (Widget) new_w, MESSAGE6);
895 }
896 }
897 else
898 {
899 if ((new_w->scrollBar.processing_direction != XmMAX_ON_TOP) &&
900 (new_w->scrollBar.processing_direction != XmMAX_ON_BOTTOM))
901 {
902 new_w->scrollBar.processing_direction = XmMAX_ON_BOTTOM;
903 XmeWarning( (Widget) new_w, MESSAGE6);
904 }
905 }
906
907 if (new_w->scrollBar.increment <= 0)
908 {
909 new_w->scrollBar.increment = 1;
910 XmeWarning( (Widget) new_w, MESSAGE7);
911 }
912
913 if (new_w->scrollBar.page_increment <= 0)
914 {
915 new_w->scrollBar.page_increment = 10;
916 XmeWarning( (Widget) new_w, MESSAGE8);
917 }
918
919 if (new_w->scrollBar.initial_delay <= 0)
920 {
921 new_w->scrollBar.initial_delay = 250;
922 XmeWarning( (Widget) new_w, MESSAGE9);
923 }
924
925 if (new_w->scrollBar.repeat_delay <= 0)
926 {
927 new_w->scrollBar.repeat_delay = 75;
928 XmeWarning( (Widget) new_w, MESSAGE10);
929 }
930
931 /* Set up a geometry for the widget if it is currently 0. */
932
933 if (request->core.width == 0)
934 {
935 if (new_w->scrollBar.orientation == XmHORIZONTAL)
936 new_w->core.width += 100;
937 else
938 new_w->core.width += 11;
939 }
940 if (request->core.height == 0)
941 {
942 if (new_w->scrollBar.orientation == XmHORIZONTAL)
943 new_w->core.height += 11;
944 else
945 new_w->core.height += 100;
946 }
947
948 /* Reverse the value for reverse processing. */
949
950 if (PROCESS_DIR_INVERSED(new_w))
951 new_w->scrollBar.value = INVERSED_VALUE(new_w);
952
953 /* Set the internally used variables. */
954
955 new_w->scrollBar.flags = 0;
956 if (new_w->scrollBar.slider_size < (new_w->scrollBar.maximum
957 - new_w->scrollBar.minimum))
958 {
959 new_w->scrollBar.flags |= SLIDER_AVAILABLE;
960
961 if (new_w->scrollBar.value > new_w->scrollBar.minimum)
962 new_w->scrollBar.flags |= ARROW1_AVAILABLE;
963 if (new_w->scrollBar.value < (new_w->scrollBar.maximum
964 - new_w->scrollBar.slider_size))
965 new_w->scrollBar.flags |= ARROW2_AVAILABLE;
966 }
967 else
968 {
969 /*
970 * For correct setvalues processing, when the slider is
971 * unavailable, the arrows should be available.
972 */
973 new_w->scrollBar.flags |= ARROW1_AVAILABLE;
974 new_w->scrollBar.flags |= ARROW2_AVAILABLE;
975 }
976
977 new_w->scrollBar.pixmap = 0;
978 new_w->scrollBar.sliding_on = FALSE;
979 new_w->scrollBar.timer = 0;
980 new_w->scrollBar.add_flags = 0 ;
981
982 new_w->scrollBar.arrow_width = 0;
983 new_w->scrollBar.arrow_height = 0;
984
985 new_w->scrollBar.arrow1_x = 0;
986 new_w->scrollBar.arrow1_y = 0;
987 new_w->scrollBar.arrow1_selected = FALSE;
988
989 new_w->scrollBar.arrow2_x = 0;
990 new_w->scrollBar.arrow2_y = 0;
991 new_w->scrollBar.arrow2_selected = FALSE;
992
993 new_w->scrollBar.saved_value = new_w->scrollBar.value;
994
995 if (LayoutIsRtoLP(new_w))
996 new_w->scrollBar.flags &= ~VALUE_SET_FLAG;
997
998 /* Get the drawing graphics contexts. */
999
1000 GetForegroundGC(new_w);
1001 GetUnavailableGC(new_w);
1002 GetFlatSliderGC(new_w);
1003
1004 /* call the resize method to get an initial size */
1005
1006 {
1007 XtWidgetProc resize;
1008 _XmProcessLock();
1009 resize = new_w->core.widget_class->core_class.resize;
1010 _XmProcessUnlock();
1011
1012 (* (resize)) ((Widget) new_w);
1013 }
1014
1015 }
1016
1017
1018
1019
1020 /************************************************************************
1021 *
1022 * GetForegroundGC
1023 * Get the graphics context used for drawing the slider and arrows.
1024 *
1025 ************************************************************************/
1026 static void
GetForegroundGC(XmScrollBarWidget sbw)1027 GetForegroundGC(
1028 XmScrollBarWidget sbw )
1029 {
1030 XGCValues values;
1031 XtGCMask valueMask;
1032
1033 valueMask = GCForeground | GCBackground | GCGraphicsExposures;
1034 values.foreground = sbw->core.background_pixel;
1035 values.background = sbw->primitive.foreground;
1036 values.graphics_exposures = False;
1037
1038 sbw->scrollBar.foreground_GC = XtAllocateGC ((Widget) sbw, 0, valueMask,
1039 &values, 0, GCFont);
1040 }
1041
1042 /************************************************************************
1043 *
1044 * GetFlatSliderGC
1045 * Get the graphics context used for drawing the flat slider
1046 *
1047 ************************************************************************/
1048 static void
GetFlatSliderGC(XmScrollBarWidget sbw)1049 GetFlatSliderGC(
1050 XmScrollBarWidget sbw )
1051 {
1052 XGCValues values;
1053 XtGCMask valueMask, unusedMask;
1054
1055 valueMask = GCForeground | GCBackground | GCGraphicsExposures;
1056 unusedMask = GCFont | GCClipXOrigin | GCClipYOrigin;
1057 if (sbw->scrollBar.slider_visual == XmTROUGH_COLOR)
1058 values.foreground = sbw->scrollBar.trough_color;
1059 else
1060 values.foreground = sbw->primitive.foreground;
1061 values.background = sbw->core.background_pixel;
1062 values.graphics_exposures = False;
1063
1064 sbw->scrollBar.flat_slider_GC = XtAllocateGC ((Widget) sbw, 0, valueMask,
1065 &values, GCClipMask,
1066 unusedMask);
1067 }
1068
1069
1070
1071 /************************************************************************
1072 *
1073 * GetUnavailableGC
1074 * Get the graphics context used for drawing the slider and arrows
1075 * as being unavailable.
1076 *
1077 ************************************************************************/
1078 static void
GetUnavailableGC(XmScrollBarWidget sbw)1079 GetUnavailableGC(
1080 XmScrollBarWidget sbw )
1081 {
1082 XGCValues values;
1083 XtGCMask valueMask, unusedMask;
1084
1085 valueMask = GCForeground | GCBackground | GCGraphicsExposures |
1086 GCFillStyle | GCStipple;
1087 unusedMask = GCClipXOrigin | GCClipYOrigin | GCFont;
1088 values.graphics_exposures = False;
1089 values.fill_style = FillStippled;
1090 values.background = sbw->core.background_pixel;
1091 values.foreground = sbw->primitive.foreground;
1092
1093 values.stipple = _XmGetInsensitiveStippleBitmap((Widget) sbw);
1094
1095 sbw->scrollBar.unavailable_GC = XtAllocateGC((Widget) sbw, 0, valueMask,
1096 &values, GCClipMask,
1097 unusedMask);
1098 }
1099
1100
1101
1102
1103 /************************************************************************
1104 *
1105 * Logic of the scrollbar pixmap management:
1106 * ----------------------------------------
1107 * A pixmap the size of the trough area is created each time the
1108 * scrollbar changes size.
1109 * This pixmap receives the drawing of the slider which is then
1110 * copied on the scrollbar window whenever exposure is needed.
1111 * GetSliderPixmap:
1112 * creates the pixmap and possibly free the current one if present.
1113 * the pixmap is free upon destruction of the widget.
1114 * the field pixmap == 0 means there is no pixmap to freed.
1115 * Is called from Resize method.
1116 * DrawSliderPixmap:
1117 * draws the slider graphics (sized shadowed rectangle) in the pixmap.
1118 * the fields slider_width and height must have been calculated.
1119 * Is called from Resize, after the pixmap has been created,
1120 * and from SetValues, if something has changed in the visual
1121 * of the slider.
1122 * RedrawSliderWindow:
1123 * clears the current scrollbar slider area, computes the
1124 * new position and call CopySliderInWindow.
1125 * Is called from SetValues method, from increment actions, and
1126 * from ChangeScrollBarValue (from Select, Timer).
1127 * CopySliderInWindow:
1128 * color slider case and then dump the slider pixmap using
1129 * XCopyArea. Called from Redisplay and from Move, where
1130 * the more expensive RedrawSliderWindow is not needed.
1131 *
1132 ************************************************************************/
1133
1134
1135 /************************************************************************
1136 *
1137 * GetSliderPixmap
1138 * Create the new pixmap for the slider.
1139 * This pixmap is the size of the widget minus the arrows.
1140 *
1141 ************************************************************************/
1142 static void
GetSliderPixmap(XmScrollBarWidget sbw)1143 GetSliderPixmap(
1144 XmScrollBarWidget sbw )
1145 {
1146
1147 if (sbw->scrollBar.pixmap)
1148 XFreePixmap (XtDisplay (sbw), sbw->scrollBar.pixmap);
1149
1150 sbw->scrollBar.pixmap =
1151 XCreatePixmap (XtDisplay(sbw), RootWindowOfScreen(XtScreen(sbw)),
1152 sbw->scrollBar.slider_area_width,
1153 sbw->scrollBar.slider_area_height,
1154 sbw->core.depth);
1155 }
1156
1157
1158
1159
1160
1161 /************************************************************************
1162 *
1163 * DrawSliderPixmap
1164 * Draw the slider graphic into the pixmap.
1165 * Draw the rectangle with a shadow or not and a mark in
1166 * the middle or the side.
1167 *
1168 ************************************************************************/
1169 static void
DrawSliderPixmap(XmScrollBarWidget sbw)1170 DrawSliderPixmap(
1171 XmScrollBarWidget sbw )
1172 {
1173 register int slider_width = sbw->scrollBar.slider_width;
1174 register int slider_height = sbw->scrollBar.slider_height;
1175 register Drawable slider = sbw->scrollBar.pixmap;
1176
1177 if ((sbw->scrollBar.slider_visual == XmFOREGROUND_COLOR) ||
1178 (sbw->scrollBar.slider_visual == XmTROUGH_COLOR)) {
1179 /* we use the same GC, previously filled with either the
1180 foreground or the trough_color pixel */
1181 /* The trough area itself has been set, as the window background,
1182 to either the trough color (not in that case) or the background
1183 pixel */
1184 XSetClipMask(XtDisplay((Widget) sbw),
1185 sbw->scrollBar.flat_slider_GC,
1186 None);
1187 XFillRectangle (XtDisplay ((Widget) sbw), slider,
1188 sbw->scrollBar.flat_slider_GC,
1189 0, 0, slider_width, slider_height);
1190 } else
1191 if ((sbw->scrollBar.slider_visual == XmBACKGROUND_COLOR) ||
1192 (sbw->scrollBar.slider_visual == XmSHADOWED_BACKGROUND)) {
1193
1194 /* in all other case, draw the shadow */
1195 XFillRectangle (XtDisplay ((Widget) sbw), slider,
1196 sbw->scrollBar.foreground_GC,
1197 0, 0, slider_width, slider_height);
1198
1199 if (sbw->scrollBar.slider_visual == XmSHADOWED_BACKGROUND)
1200 XmeDrawShadows (XtDisplay (sbw), slider,
1201 sbw->primitive.top_shadow_GC,
1202 sbw->primitive.bottom_shadow_GC,
1203 0, 0, slider_width, slider_height,
1204 sbw->primitive.shadow_thickness,
1205 XmSHADOW_OUT);
1206 }
1207
1208
1209 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER) {
1210 /* in thermo mode, the mark must go on the side
1211 of the slider, not in the middle.
1212 We do that by modifying slider_width or _height
1213 up front and share the same code thereafter */
1214 if (sbw->scrollBar.orientation == XmHORIZONTAL) {
1215 if (PROCESS_DIR_INVERSED(sbw)) {
1216 slider_width = THERMO_MARK_OFFSET ;
1217 } else {
1218 slider_width = 2 * slider_width - THERMO_MARK_OFFSET ;
1219 }
1220 } else {
1221 if (PROCESS_DIR_INVERSED(sbw)) {
1222 slider_height = THERMO_MARK_OFFSET;
1223 } else {
1224 slider_height = 2 * slider_height - THERMO_MARK_OFFSET;
1225 }
1226 }
1227 }
1228
1229 if (sbw->scrollBar.slider_mark == XmETCHED_LINE) {
1230
1231 if (sbw->scrollBar.orientation == XmHORIZONTAL) {
1232 XDrawLine (XtDisplay (sbw), slider,
1233 sbw->primitive.bottom_shadow_GC,
1234 slider_width / 2 - 1, 1,
1235 slider_width / 2 - 1, slider_height - 2);
1236 XDrawLine (XtDisplay (sbw), slider,
1237 sbw->primitive.top_shadow_GC,
1238 slider_width / 2, 1,
1239 slider_width / 2, slider_height - 2);
1240 } else {
1241 XDrawLine (XtDisplay (sbw), slider,
1242 sbw->primitive.bottom_shadow_GC,
1243 1, slider_height / 2 - 1,
1244 slider_width - 2, slider_height / 2 - 1);
1245 XDrawLine (XtDisplay (sbw), slider,
1246 sbw->primitive.top_shadow_GC,
1247 1, slider_height / 2,
1248 slider_width - 2, slider_height / 2);
1249 }
1250 } else
1251
1252 if (sbw->scrollBar.slider_mark == XmTHUMB_MARK) {
1253 Dimension thumb_spacing = 4, margin = 2 ;
1254
1255 if (sbw->scrollBar.orientation == XmHORIZONTAL) {
1256 XmeDrawSeparator (XtDisplay (sbw), slider,
1257 sbw->primitive.top_shadow_GC,
1258 sbw->primitive.bottom_shadow_GC, NULL,
1259 slider_width / 2, 0,
1260 2, slider_height, 2, margin,
1261 XmVERTICAL, XmSHADOW_ETCHED_OUT);
1262 XmeDrawSeparator (XtDisplay (sbw), slider,
1263 sbw->primitive.top_shadow_GC,
1264 sbw->primitive.bottom_shadow_GC, NULL,
1265 slider_width / 2 - thumb_spacing, 0,
1266 2, slider_height, 2, margin,
1267 XmVERTICAL, XmSHADOW_ETCHED_OUT);
1268 XmeDrawSeparator (XtDisplay (sbw), slider,
1269 sbw->primitive.top_shadow_GC,
1270 sbw->primitive.bottom_shadow_GC, NULL,
1271 slider_width / 2 + thumb_spacing, 0,
1272 2, slider_height, 2, margin,
1273 XmVERTICAL, XmSHADOW_ETCHED_OUT);
1274 }
1275 else
1276 {
1277 XmeDrawSeparator (XtDisplay (sbw), slider,
1278 sbw->primitive.top_shadow_GC,
1279 sbw->primitive.bottom_shadow_GC, NULL,
1280 0, slider_height / 2,
1281 slider_width, 2, 2, margin,
1282 XmHORIZONTAL, XmSHADOW_ETCHED_OUT);
1283 XmeDrawSeparator (XtDisplay (sbw), slider,
1284 sbw->primitive.top_shadow_GC,
1285 sbw->primitive.bottom_shadow_GC, NULL,
1286 0, slider_height / 2 - thumb_spacing,
1287 slider_width, 2, 2, margin,
1288 XmHORIZONTAL, XmSHADOW_ETCHED_OUT);
1289 XmeDrawSeparator (XtDisplay (sbw), slider,
1290 sbw->primitive.top_shadow_GC,
1291 sbw->primitive.bottom_shadow_GC, NULL,
1292 0, slider_height / 2 + thumb_spacing,
1293 slider_width, 2, 2, margin,
1294 XmHORIZONTAL, XmSHADOW_ETCHED_OUT);
1295
1296 }
1297 }
1298
1299 if (sbw->scrollBar.slider_mark == XmROUND_MARK) {
1300 Dimension radius = DEFAULT_ROUND_MARK_RADIUS ;
1301
1302 XmeDrawCircle(XtDisplay (sbw), slider,
1303 sbw->primitive.top_shadow_GC,
1304 sbw->primitive.bottom_shadow_GC,
1305 NULL,
1306 slider_width / 2 - radius,
1307 slider_height / 2 - radius,
1308 2*radius, 2*radius,
1309 sbw->primitive.shadow_thickness, 0);
1310 }
1311
1312 }
1313
1314 /************************************************************************
1315 *
1316 * CopySliderInWindow
1317 * Dump the slider pixmap into the window using CopyArea.
1318 *
1319 ************************************************************************/
1320 static void
CopySliderInWindow(XmScrollBarWidget sbw)1321 CopySliderInWindow(
1322 XmScrollBarWidget sbw )
1323 {
1324 /* use the pixmap that contains the slider graphics */
1325 if (XtIsRealized((Widget)sbw) && sbw->scrollBar.pixmap) {
1326 XCopyArea (XtDisplay ((Widget) sbw),
1327 sbw->scrollBar.pixmap, XtWindow ((Widget) sbw),
1328 sbw->scrollBar.foreground_GC,
1329 0, 0,
1330 sbw->scrollBar.slider_width, sbw->scrollBar.slider_height,
1331 sbw->scrollBar.slider_x, sbw->scrollBar.slider_y);
1332 }
1333 }
1334
1335 /************************************************************************
1336 *
1337 * RedrawSliderWindow
1338 * Clear the trough area at the current slider position,
1339 * recompute the slider coordinates and redraw the slider the window by
1340 * copying from the pixmap graphics.
1341 *
1342 ************************************************************************/
1343 static void
RedrawSliderWindow(XmScrollBarWidget sbw)1344 RedrawSliderWindow(
1345 XmScrollBarWidget sbw )
1346 {
1347 short old_slider_width = sbw->scrollBar.slider_width ;
1348 short old_slider_height = sbw->scrollBar.slider_height ;
1349
1350 if (XtIsRealized((Widget)sbw))
1351 XClearArea(XtDisplay ((Widget) sbw), XtWindow ((Widget) sbw),
1352 (int) sbw->scrollBar.slider_area_x,
1353 (int) sbw->scrollBar.slider_area_y,
1354 (unsigned int) sbw->scrollBar.slider_area_width,
1355 (unsigned int) sbw->scrollBar.slider_area_height,
1356 (Bool) FALSE);
1357
1358 CalcSliderRect(sbw,
1359 &(sbw->scrollBar.slider_x),
1360 &(sbw->scrollBar.slider_y),
1361 &(sbw->scrollBar.slider_width),
1362 &(sbw->scrollBar.slider_height));
1363
1364 if ((old_slider_width != sbw->scrollBar.slider_width) ||
1365 (old_slider_height != sbw->scrollBar.slider_height))
1366 DrawSliderPixmap(sbw);
1367
1368 CopySliderInWindow(sbw);
1369 }
1370
1371
1372
1373
1374 /************************************************************************
1375 *
1376 * CalcSliderRect
1377 * Calculate the slider location and size in pixels so that
1378 * it can be drawn. Note that number and location of pixels
1379 * is always positive, so no special case rounding is needed.
1380 * DD: better be a CalcSliderPosition and CalcSliderSize, since
1381 * this routine is often use for one _or_ the other case.
1382 *
1383 ************************************************************************/
1384 static void
CalcSliderRect(XmScrollBarWidget sbw,short * slider_x,short * slider_y,short * slider_width,short * slider_height)1385 CalcSliderRect(
1386 XmScrollBarWidget sbw,
1387 short *slider_x,
1388 short *slider_y,
1389 short *slider_width,
1390 short *slider_height )
1391 {
1392 float range;
1393 float trueSize;
1394 float factor;
1395 float slideSize;
1396 int minSliderWidth;
1397 int minSliderHeight;
1398 int hitTheWall = 0;
1399 int value ;
1400
1401 /* Set up */
1402 if (sbw->scrollBar.orientation == XmHORIZONTAL)
1403 {
1404 trueSize = sbw->scrollBar.slider_area_width;
1405 minSliderWidth = MIN_SLIDER_LENGTH;
1406 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER)
1407 minSliderWidth = 1;
1408 minSliderHeight = MIN_SLIDER_THICKNESS;
1409
1410 }
1411 else /* orientation == XmVERTICAL */
1412 {
1413 trueSize = sbw->scrollBar.slider_area_height;
1414 minSliderWidth = MIN_SLIDER_THICKNESS;
1415 minSliderHeight = MIN_SLIDER_LENGTH;
1416 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER)
1417 minSliderHeight = 1;
1418 }
1419
1420 /* Total number of user units displayed */
1421 range = sbw->scrollBar.maximum - sbw->scrollBar.minimum;
1422
1423 /* A naive notion of pixels per user unit */
1424 factor = trueSize / range;
1425
1426 if (PROCESS_DIR_INVERSED(sbw))
1427 value = INVERSED_VALUE(sbw);
1428 else
1429 value = sbw->scrollBar.value ;
1430
1431 /* A naive notion of the size of the slider in pixels */
1432 /* in thermo, slider_size is 0 ans is ignored */
1433 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER)
1434 slideSize = (float) value * factor;
1435 else
1436 slideSize = (float) (sbw->scrollBar.slider_size) * factor;
1437
1438
1439
1440 /* NOTE SIDE EFFECT */
1441 #define MAX_SCROLLBAR_DIMENSION(val, min)\
1442 ((val) > (min)) ? (val) : (hitTheWall = min)
1443
1444
1445 /* Don't let the slider get too small */
1446 if (sbw->scrollBar.orientation == XmHORIZONTAL)
1447 {
1448 *slider_width = MAX_SCROLLBAR_DIMENSION(
1449 (int) (slideSize + 0.5), minSliderWidth);
1450 *slider_height = MAX(sbw->scrollBar.slider_area_height,
1451 minSliderHeight);
1452 }
1453 else /* orientation == XmVERTICAL */
1454 {
1455 *slider_width = MAX(sbw->scrollBar.slider_area_width,
1456 minSliderWidth);
1457 *slider_height = MAX_SCROLLBAR_DIMENSION((int)
1458 (slideSize + 0.5), minSliderHeight);
1459 }
1460
1461 if (hitTheWall)
1462 {
1463 /*
1464 * The slider has not been allowed to take on its true
1465 * proportionate size (it would have been too small). This
1466 * breaks proportionality of the slider and the conversion
1467 * between pixels and user units.
1468 *
1469 * The factor needs to be tweaked in this case.
1470 */
1471
1472 trueSize -= hitTheWall; /* actual pixels available */
1473 range -= sbw->scrollBar.slider_size; /* actual range */
1474 if (range == 0) range = 1;
1475 factor = trueSize / range;
1476
1477 }
1478
1479 if (sbw->scrollBar.orientation == XmHORIZONTAL)
1480 {
1481 /* Many parentheses to explicitly control type conversion. */
1482 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER) {
1483 if (PROCESS_DIR_INVERSED(sbw)) {
1484 *slider_x = sbw->scrollBar.slider_area_x +
1485 sbw->scrollBar.slider_area_width - *slider_width;
1486 } else {
1487 *slider_x = sbw->scrollBar.slider_area_x;
1488 }
1489 } else
1490 *slider_x = ((int) (((((float) sbw->scrollBar.value)
1491 - ((float) sbw->scrollBar.minimum)) * factor) + 0.5))
1492 + sbw->scrollBar.slider_area_x;
1493 *slider_y = sbw->scrollBar.slider_area_y ;
1494 }
1495 else
1496 {
1497 *slider_x = sbw->scrollBar.slider_area_x;
1498 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER) {
1499 if (PROCESS_DIR_INVERSED(sbw)) {
1500 *slider_y = sbw->scrollBar.slider_area_y +
1501 sbw->scrollBar.slider_area_height - *slider_height;
1502 } else {
1503 *slider_y = sbw->scrollBar.slider_area_y ;
1504 }
1505 } else
1506 *slider_y = ((int) (((((float) sbw->scrollBar.value)
1507 - ((float) sbw->scrollBar.minimum)) * factor) + 0.5))
1508 + sbw->scrollBar.slider_area_y;
1509 }
1510
1511 /* One final adjustment (of questionable value--preserved
1512 for visual backward compatibility) */
1513
1514 if ((sbw->scrollBar.orientation == XmHORIZONTAL)
1515 &&
1516 ((*slider_x + *slider_width) > (sbw->scrollBar.slider_area_x
1517 + sbw->scrollBar.slider_area_width)))
1518 {
1519 *slider_x = sbw->scrollBar.slider_area_x
1520 + sbw->scrollBar.slider_area_width - *slider_width;
1521 }
1522
1523 if ((sbw->scrollBar.orientation == XmVERTICAL)
1524 &&
1525 ((*slider_y + *slider_height) > (sbw->scrollBar.slider_area_y
1526 + sbw->scrollBar.slider_area_height)))
1527 {
1528 *slider_y = sbw->scrollBar.slider_area_y
1529 + sbw->scrollBar.slider_area_height - *slider_height;
1530 }
1531 }
1532
1533
1534
1535
1536 /************************************************************************
1537 *
1538 * Redisplay
1539 * General redisplay function called on exposure events.
1540 *
1541 ************************************************************************/
1542 static void
Redisplay(Widget wid,XEvent * event,Region region)1543 Redisplay(
1544 Widget wid,
1545 XEvent *event,
1546 Region region )
1547 {
1548 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
1549
1550
1551 if (sbw->primitive.shadow_thickness > 0)
1552 XmeDrawShadows (XtDisplay (sbw), XtWindow (sbw),
1553 sbw->primitive.bottom_shadow_GC,
1554 sbw->primitive.top_shadow_GC,
1555 sbw->primitive.highlight_thickness,
1556 sbw->primitive.highlight_thickness,
1557 sbw->core.width-2 *
1558 sbw->primitive.highlight_thickness,
1559 sbw->core.height-2 *
1560 sbw->primitive.highlight_thickness,
1561 sbw->primitive.shadow_thickness,
1562 XmSHADOW_OUT);
1563
1564 /* dump the pixmap that contains the slider graphics */
1565 CopySliderInWindow(sbw);
1566
1567 if (sbw -> scrollBar.show_arrows) {
1568
1569 DRAWARROW(sbw, ((sbw->scrollBar.arrow1_selected)?
1570 sbw -> primitive.bottom_shadow_GC:
1571 sbw -> primitive.top_shadow_GC),
1572 ((sbw->scrollBar.arrow1_selected)?
1573 sbw -> primitive.top_shadow_GC :
1574 sbw -> primitive.bottom_shadow_GC),
1575 sbw->scrollBar.arrow1_x,
1576 sbw->scrollBar.arrow1_y,
1577 sbw->scrollBar.arrow1_orientation);
1578 DRAWARROW(sbw, ((sbw->scrollBar.arrow2_selected)?
1579 sbw -> primitive.bottom_shadow_GC:
1580 sbw -> primitive.top_shadow_GC),
1581 ((sbw->scrollBar.arrow2_selected)?
1582 sbw -> primitive.top_shadow_GC :
1583 sbw -> primitive.bottom_shadow_GC),
1584 sbw->scrollBar.arrow2_x,
1585 sbw->scrollBar.arrow2_y,
1586 sbw->scrollBar.arrow2_orientation);
1587 }
1588
1589 if (!(XtIsSensitive(wid))) {
1590 XSetClipMask(XtDisplay(sbw), sbw->scrollBar.unavailable_GC, None);
1591 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
1592 sbw->scrollBar.unavailable_GC,
1593 sbw->primitive.highlight_thickness
1594 + sbw->primitive.shadow_thickness,
1595 sbw->primitive.highlight_thickness
1596 + sbw->primitive.shadow_thickness,
1597 XtWidth(sbw) - (2 * (sbw->primitive.highlight_thickness
1598 + sbw->primitive.shadow_thickness)),
1599 XtHeight(sbw) - (2 * (sbw->primitive.highlight_thickness
1600 + sbw->primitive.shadow_thickness)));
1601 }
1602 #ifdef FUNKY_INSENSITIVE_VISUAL
1603 else if (sbw->scrollBar.show_arrows)
1604 {
1605 XSetClipMask(XtDisplay(sbw), sbw->scrollBar.unavailable_GC, None);
1606 if (!(sbw->scrollBar.flags & ARROW1_AVAILABLE))
1607 {
1608 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
1609 sbw->scrollBar.unavailable_GC,
1610 sbw->scrollBar.arrow1_x,
1611 sbw->scrollBar.arrow1_y,
1612 sbw->scrollBar.arrow_width,
1613 sbw->scrollBar.arrow_height);
1614 }
1615 if (!(sbw->scrollBar.flags & ARROW2_AVAILABLE))
1616 {
1617 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
1618 sbw->scrollBar.unavailable_GC,
1619 sbw->scrollBar.arrow2_x,
1620 sbw->scrollBar.arrow2_y,
1621 sbw->scrollBar.arrow_width,
1622 sbw->scrollBar.arrow_height);
1623 }
1624 }
1625 #endif
1626
1627
1628 /* envelop primitive expose method for highlight */
1629 {
1630 XtExposeProc expose;
1631
1632 _XmProcessLock();
1633 expose = xmPrimitiveClassRec.core_class.expose;
1634 _XmProcessUnlock();
1635
1636 (*(expose))(wid, event, region) ;
1637 }
1638
1639 }
1640
1641
1642
1643
1644
1645 /************************************************************************
1646 *
1647 * Resize
1648 * Process resizes on the widget by destroying and recreating the
1649 * slider pixmap.
1650 * Also draw the correct sized slider onto this pixmap.
1651 *
1652 ************************************************************************/
1653 static void
Resize(Widget wid)1654 Resize(
1655 Widget wid )
1656 {
1657 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
1658 register int ht = sbw->primitive.highlight_thickness;
1659 register int st = sbw->primitive.shadow_thickness;
1660
1661 #define CHECK(x) if (x <= 0) x = 1
1662
1663 #define BOTH_ARROWS_NEAR_SIDE(sbw) \
1664 (((sbw->scrollBar.show_arrows == XmMIN_SIDE) &&\
1665 !PROCESS_DIR_INVERSED(sbw)) ||\
1666 ((sbw->scrollBar.show_arrows == XmMAX_SIDE) &&\
1667 PROCESS_DIR_INVERSED(sbw)))
1668
1669 #define BOTH_ARROWS_FAR_SIDE(sbw) \
1670 (((sbw->scrollBar.show_arrows == XmMIN_SIDE) &&\
1671 PROCESS_DIR_INVERSED(sbw)) ||\
1672 ((sbw->scrollBar.show_arrows == XmMAX_SIDE) &&\
1673 !PROCESS_DIR_INVERSED(sbw)))
1674
1675 #define ARROW1_NEAR_SIDE(sbw) \
1676 ( (sbw->scrollBar.show_arrows == XmEACH_SIDE) ||\
1677 BOTH_ARROWS_NEAR_SIDE (sbw) )
1678
1679 #define ARROW2_FAR_SIDE(sbw) \
1680 ((sbw->scrollBar.show_arrows == XmEACH_SIDE) ||\
1681 BOTH_ARROWS_FAR_SIDE (sbw) )
1682
1683 /* Calculate all of the internal data for slider */
1684
1685 if (sbw->scrollBar.show_arrows) {
1686
1687 if (sbw->scrollBar.orientation == XmHORIZONTAL) {
1688
1689 sbw->scrollBar.arrow1_orientation = XmARROW_LEFT;
1690 sbw->scrollBar.arrow2_orientation = XmARROW_RIGHT;
1691
1692 /* left arrow position and size */
1693
1694 sbw->scrollBar.arrow1_y = ht + st;
1695
1696 sbw->scrollBar.arrow_width =
1697 sbw->scrollBar.arrow_height = sbw->core.height
1698 - 2 * (ht + st);
1699
1700 if (ARROW1_NEAR_SIDE (sbw)) {
1701 sbw->scrollBar.arrow1_x = ht + st;
1702 } else {
1703 sbw->scrollBar.arrow1_x = sbw->core.width -ht -st
1704 - 2 * sbw->scrollBar.arrow_width;
1705 }
1706
1707 if (sbw->core.width <
1708 2 * (sbw->scrollBar.arrow_width + ht + st)
1709 + MIN_SLIDER_LENGTH + 2)
1710 sbw->scrollBar.arrow_width = (sbw->core.width
1711 - (MIN_SLIDER_LENGTH + 2 + 2 * (ht + st))) / 2;
1712
1713 /* slide area position and size */
1714
1715 if (sbw->scrollBar.show_arrows == XmEACH_SIDE) {
1716 sbw->scrollBar.slider_area_x =
1717 ht + st + sbw->scrollBar.arrow_width + 1;
1718 } else
1719 if (BOTH_ARROWS_NEAR_SIDE (sbw)) {
1720 sbw->scrollBar.slider_area_x =
1721 ht + st + 2 * sbw->scrollBar.arrow_width + 2;
1722 } else {
1723 sbw->scrollBar.slider_area_x = ht + st ;
1724 }
1725
1726 sbw->scrollBar.slider_area_width =
1727 sbw->core.width
1728 - 2 * (ht + st + sbw->scrollBar.arrow_width + 1);
1729
1730 if ((2*(ht+st)) > XtHeight(sbw))
1731 sbw->scrollBar.slider_area_y = XtHeight(sbw) / 2;
1732 else
1733 sbw->scrollBar.slider_area_y = ht + st;
1734
1735 sbw->scrollBar.slider_area_height =
1736 sbw->core.height - 2 * (ht + st);
1737
1738
1739 /* right arrow position */
1740
1741 if (ARROW2_FAR_SIDE(sbw)) {
1742 sbw->scrollBar.arrow2_x = ht + st
1743 + sbw->scrollBar.arrow_width + 1 +
1744 sbw->scrollBar.slider_area_width + 1;
1745 } else {
1746 sbw->scrollBar.arrow2_x = ht + st
1747 + sbw->scrollBar.arrow_width ;
1748 }
1749
1750 sbw->scrollBar.arrow2_y = ht + st;
1751
1752 } else { /* VERTICAL */
1753
1754 sbw->scrollBar.arrow1_orientation = XmARROW_UP;
1755 sbw->scrollBar.arrow2_orientation = XmARROW_DOWN;
1756
1757 /* top arrow position and size */
1758
1759 sbw->scrollBar.arrow1_x = ht + st;
1760
1761 sbw->scrollBar.arrow_width = sbw->scrollBar.arrow_height =
1762 sbw->core.width - 2 * (ht + st);
1763
1764 if (ARROW1_NEAR_SIDE(sbw)) {
1765 sbw->scrollBar.arrow1_y = ht + st;
1766 } else {
1767 sbw->scrollBar.arrow1_y = sbw->core.height -ht -st
1768 - 2 * sbw->scrollBar.arrow_height;
1769 }
1770
1771 if (sbw->core.height <
1772 2 * (sbw->scrollBar.arrow_height + ht + st)
1773 + MIN_SLIDER_LENGTH +2)
1774 sbw->scrollBar.arrow_height = (sbw->core.height
1775 - (MIN_SLIDER_LENGTH + 2 + 2 * (ht + st))) / 2;
1776
1777 /* slide area position and size */
1778
1779 if (sbw->scrollBar.show_arrows == XmEACH_SIDE) {
1780 sbw->scrollBar.slider_area_y =
1781 ht + st + sbw->scrollBar.arrow_height + 1;
1782 } else
1783 if (BOTH_ARROWS_NEAR_SIDE (sbw)) {
1784 sbw->scrollBar.slider_area_y =
1785 ht + st + 2 * sbw->scrollBar.arrow_height + 2 ;
1786 } else {
1787 sbw->scrollBar.slider_area_y = ht + st ;
1788 }
1789
1790 sbw->scrollBar.slider_area_height = sbw->core.height
1791 - 2 * (ht + st + sbw->scrollBar.arrow_height +1);
1792
1793 if ((2*(st+ht)) > XtWidth(sbw))
1794 sbw->scrollBar.slider_area_x = XtWidth(sbw) / 2;
1795 else
1796 sbw->scrollBar.slider_area_x = ht + st;
1797
1798 sbw->scrollBar.slider_area_width = sbw->core.width
1799 - 2 * (ht + st);
1800
1801
1802 /* down arrow position */
1803 if (ARROW2_FAR_SIDE(sbw)) {
1804 sbw->scrollBar.arrow2_y = ht + st
1805 + sbw->scrollBar.arrow_height + 1 +
1806 sbw->scrollBar.slider_area_height + 1;
1807 } else {
1808 sbw->scrollBar.arrow2_y = ht + st
1809 + sbw->scrollBar.arrow_height ;
1810 }
1811
1812 sbw->scrollBar.arrow2_x = ht + st;
1813 }
1814
1815 CHECK(sbw->scrollBar.arrow_height);
1816 CHECK(sbw->scrollBar.arrow_width);
1817 } else {
1818 sbw->scrollBar.arrow_width = 0;
1819 sbw->scrollBar.arrow_height = 0;
1820
1821 if (sbw->scrollBar.orientation == XmHORIZONTAL) {
1822 /* slide area position and size */
1823
1824 sbw->scrollBar.slider_area_x = ht + st;
1825 sbw->scrollBar.slider_area_width = sbw->core.width
1826 - 2 * (ht + st);
1827
1828 if ((2*(ht+st)) > XtHeight(sbw))
1829 sbw->scrollBar.slider_area_y = XtHeight(sbw) / 2;
1830 else
1831 sbw->scrollBar.slider_area_y = ht + st;
1832 sbw->scrollBar.slider_area_height = sbw->core.height
1833 - 2 * (ht + st);
1834 } else {
1835 /* slide area position and size */
1836
1837 sbw->scrollBar.slider_area_y = ht + st;
1838 sbw->scrollBar.slider_area_height = sbw->core.height
1839 - 2 * (ht + st);
1840
1841 if ((2*(st+ht)) > XtWidth(sbw))
1842 sbw->scrollBar.slider_area_x = XtWidth(sbw) / 2;
1843 else
1844 sbw->scrollBar.slider_area_x = ht + st;
1845 sbw->scrollBar.slider_area_width = sbw->core.width
1846 - 2 * (ht + st);
1847 }
1848 }
1849
1850 CHECK(sbw->scrollBar.slider_area_height);
1851 CHECK(sbw->scrollBar.slider_area_width);
1852
1853 GetSliderPixmap (sbw); /* the size of the scrollbar window - arrows */
1854
1855 CalcSliderRect(sbw,
1856 &(sbw->scrollBar.slider_x),
1857 &(sbw->scrollBar.slider_y),
1858 &(sbw->scrollBar.slider_width),
1859 &(sbw->scrollBar.slider_height));
1860
1861 DrawSliderPixmap (sbw);
1862 }
1863
1864
1865
1866
1867 /*********************************************************************
1868 *
1869 * Realize
1870 *
1871 ********************************************************************/
1872 static void
Realize(Widget wid,XtValueMask * window_mask,XSetWindowAttributes * window_attributes)1873 Realize(
1874 Widget wid,
1875 XtValueMask *window_mask,
1876 XSetWindowAttributes *window_attributes )
1877 {
1878 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
1879
1880 *window_mask |= CWBitGravity;
1881 window_attributes->bit_gravity = ForgetGravity;
1882
1883 /* if we are in the slider color = trough color case, we need to
1884 get the regular background as the trough (= window) color,
1885 otherwise, we need to get the trough color */
1886 if (sbw->scrollBar.slider_visual != XmTROUGH_COLOR) {
1887 *window_mask |= CWBackPixel ;
1888 window_attributes->background_pixel = sbw->scrollBar.trough_color;
1889 }
1890
1891 XtCreateWindow (wid, InputOutput, CopyFromParent, *window_mask,
1892 window_attributes);
1893 }
1894
1895
1896
1897
1898 /************************************************************************
1899 *
1900 * Destroy
1901 * Clean up allocated resources when the widget is destroyed.
1902 *
1903 ************************************************************************/
1904 static void
Destroy(Widget wid)1905 Destroy(
1906 Widget wid )
1907 {
1908 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
1909
1910 XtReleaseGC ((Widget) sbw, sbw->scrollBar.foreground_GC);
1911 XtReleaseGC ((Widget) sbw, sbw->scrollBar.unavailable_GC);
1912 XtReleaseGC ((Widget) sbw, sbw->scrollBar.flat_slider_GC);
1913
1914 if (sbw->scrollBar.pixmap != 0)
1915 XFreePixmap (XtDisplay (sbw), sbw->scrollBar.pixmap);
1916
1917 if (sbw->scrollBar.timer != 0)
1918 {
1919 XtRemoveTimeOut (sbw->scrollBar.timer);
1920 sbw->scrollBar.timer = 0;
1921 }
1922 }
1923
1924
1925
1926
1927 /************************************************************************
1928 *
1929 * ValidateInputs
1930 *
1931 ************************************************************************/
1932 /*ARGSUSED*/
1933 static Boolean
ValidateInputs(XmScrollBarWidget current,XmScrollBarWidget request,XmScrollBarWidget new_w)1934 ValidateInputs(
1935 XmScrollBarWidget current,
1936 XmScrollBarWidget request, /* unused */
1937 XmScrollBarWidget new_w )
1938 {
1939 Boolean returnFlag = TRUE;
1940 int value ;
1941
1942 /* Validate the incoming data */
1943
1944 if (new_w->scrollBar.minimum >= new_w->scrollBar.maximum)
1945 {
1946 new_w->scrollBar.minimum = current->scrollBar.minimum;
1947 new_w->scrollBar.maximum = current->scrollBar.maximum;
1948 XmeWarning( (Widget) new_w, MESSAGE1);
1949 returnFlag = FALSE;
1950 }
1951
1952 if (new_w->scrollBar.sliding_mode != current->scrollBar.sliding_mode) {
1953 if (new_w->scrollBar.sliding_mode != XmTHERMOMETER) {
1954 new_w->scrollBar.slider_size = (new_w->scrollBar.maximum
1955 - new_w->scrollBar.minimum) / 10;
1956 if (new_w->scrollBar.slider_size < 1)
1957 new_w->scrollBar.slider_size = 1;
1958 } else
1959 new_w->scrollBar.slider_size = 0 ;
1960 }
1961
1962 if (new_w->scrollBar.sliding_mode != XmTHERMOMETER) {
1963
1964 if (new_w->scrollBar.slider_size < 1) {
1965 if ((new_w->scrollBar.maximum - new_w->scrollBar.minimum) <
1966 current->scrollBar.slider_size)
1967 new_w->scrollBar.slider_size = new_w->scrollBar.maximum
1968 - new_w->scrollBar.minimum;
1969 else
1970 new_w->scrollBar.slider_size = current->scrollBar.slider_size;
1971 XmeWarning( (Widget) new_w, MESSAGE2);
1972 returnFlag = FALSE;
1973 }
1974
1975 if ((new_w->scrollBar.slider_size >
1976 new_w->scrollBar.maximum - new_w->scrollBar.minimum)) {
1977 if ((new_w->scrollBar.maximum - new_w->scrollBar.minimum) <
1978 current->scrollBar.slider_size)
1979 new_w->scrollBar.slider_size = new_w->scrollBar.maximum
1980 - new_w->scrollBar.minimum;
1981 else
1982 new_w->scrollBar.slider_size = current->scrollBar.slider_size;
1983 XmeWarning( (Widget) new_w, MESSAGE13);
1984 returnFlag = FALSE;
1985 }
1986 } else
1987 new_w->scrollBar.slider_size = 0 ;
1988
1989 if (new_w->scrollBar.value < new_w->scrollBar.minimum)
1990 {
1991 new_w->scrollBar.value = new_w->scrollBar.minimum;
1992 XmeWarning( (Widget) new_w, MESSAGE3);
1993 returnFlag = FALSE;
1994 }
1995
1996 /* do the checking on the real user value */
1997 if (new_w->scrollBar.value == current->scrollBar.value) {
1998 if (PROCESS_DIR_INVERSED(new_w))
1999 /* use new for value since that's the one getting changed below */
2000 #ifdef FIX_1396
2001 value = INVERSED_VALUE(new_w);
2002 #else
2003 value = INVERSED_VALUE(current);
2004 #endif
2005 else
2006 value = new_w->scrollBar.value ;
2007 } else
2008 value = new_w->scrollBar.value ;
2009
2010 if (value > new_w->scrollBar.maximum - new_w->scrollBar.slider_size)
2011 {
2012 new_w->scrollBar.value =
2013 new_w->scrollBar.maximum - new_w->scrollBar.slider_size;
2014 new_w->scrollBar.flags |= VALUE_SET_FLAG;
2015 XmeWarning( (Widget) new_w, MESSAGE4);
2016 }
2017
2018 if( !XmRepTypeValidValue( XmRID_ORIENTATION,
2019 new_w->scrollBar.orientation, (Widget) new_w))
2020 {
2021 new_w->scrollBar.orientation = current->scrollBar.orientation;
2022 returnFlag = FALSE;
2023 }
2024
2025 if (new_w->scrollBar.orientation == XmHORIZONTAL)
2026 {
2027 if ((new_w->scrollBar.processing_direction != XmMAX_ON_LEFT) &&
2028 (new_w->scrollBar.processing_direction != XmMAX_ON_RIGHT))
2029 {
2030 new_w->scrollBar.processing_direction =
2031 current->scrollBar.processing_direction;
2032 XmeWarning( (Widget) new_w, MESSAGE6);
2033 returnFlag = FALSE;
2034 }
2035 }
2036 else /* new_w->scrollBar.orientation == XmVERTICAL */
2037 {
2038 if ((new_w->scrollBar.processing_direction != XmMAX_ON_TOP) &&
2039 (new_w->scrollBar.processing_direction != XmMAX_ON_BOTTOM))
2040 {
2041 new_w->scrollBar.processing_direction =
2042 current->scrollBar.processing_direction;
2043 XmeWarning( (Widget) new_w, MESSAGE6);
2044 returnFlag = FALSE;
2045 }
2046 }
2047
2048 if (new_w->scrollBar.increment <= 0)
2049 {
2050 new_w->scrollBar.increment = current->scrollBar.increment;
2051 XmeWarning( (Widget) new_w, MESSAGE7);
2052 returnFlag = FALSE;
2053 }
2054
2055 if (new_w->scrollBar.page_increment <= 0)
2056 {
2057 new_w->scrollBar.page_increment =
2058 current->scrollBar.page_increment;
2059 XmeWarning( (Widget) new_w, MESSAGE8);
2060 returnFlag = FALSE;
2061 }
2062
2063 if (new_w->scrollBar.initial_delay <= 0)
2064 {
2065 new_w->scrollBar.initial_delay = current->scrollBar.initial_delay;
2066 XmeWarning( (Widget) new_w, MESSAGE9);
2067 returnFlag = FALSE;
2068 }
2069
2070 if (new_w->scrollBar.repeat_delay <= 0)
2071 {
2072 new_w->scrollBar.repeat_delay = current->scrollBar.repeat_delay;
2073 XmeWarning( (Widget) new_w, MESSAGE10);
2074 returnFlag = FALSE;
2075 }
2076
2077 if (new_w->core.width == 0)
2078 {
2079 if (new_w->scrollBar.orientation == XmHORIZONTAL)
2080 new_w->core.width += 100;
2081 else
2082 new_w->core.width += 11;
2083 }
2084
2085 if (new_w->core.height == 0)
2086 {
2087 if (new_w->scrollBar.orientation == XmHORIZONTAL)
2088 new_w->core.height += 11;
2089 else
2090 new_w->core.height += 100;
2091 }
2092
2093 return(returnFlag);
2094 }
2095
2096 /************************************************************************
2097 *
2098 * SetValues
2099 *
2100 ************************************************************************/
2101 /*ARGSUSED*/
2102 static Boolean
SetValues(Widget cw,Widget rw,Widget nw,ArgList args,Cardinal * num_args)2103 SetValues(
2104 Widget cw,
2105 Widget rw,
2106 Widget nw,
2107 ArgList args, /* unused */
2108 Cardinal *num_args ) /* unused */
2109 {
2110 XmScrollBarWidget current = (XmScrollBarWidget) cw ;
2111 XmScrollBarWidget request = (XmScrollBarWidget) rw ;
2112 XmScrollBarWidget new_w = (XmScrollBarWidget) nw ;
2113 Boolean returnFlag = FALSE;
2114 Boolean current_backwards = PROCESS_DIR_INVERSED(current);
2115 Boolean new_backwards = PROCESS_DIR_INVERSED(new_w);
2116
2117
2118
2119 if(!XmRepTypeValidValue( XmRID_SHOW_ARROWS,
2120 new_w->scrollBar.show_arrows, (Widget) new_w) )
2121 {
2122 new_w->scrollBar.show_arrows = current->scrollBar.sliding_mode;
2123 }
2124
2125 if(!XmRepTypeValidValue( XmRID_SLIDING_MODE,
2126 new_w->scrollBar.sliding_mode, (Widget) new_w) )
2127 {
2128 new_w->scrollBar.sliding_mode = current->scrollBar.sliding_mode;
2129 }
2130
2131 if(!XmRepTypeValidValue( XmRID_SLIDER_VISUAL,
2132 new_w->scrollBar.slider_visual, (Widget) new_w) )
2133 {
2134 new_w->scrollBar.slider_visual = current->scrollBar.slider_visual;
2135 }
2136
2137 if(!XmRepTypeValidValue( XmRID_SLIDER_MARK,
2138 new_w->scrollBar.slider_mark, (Widget) new_w) )
2139 {
2140 new_w->scrollBar.slider_mark = current->scrollBar.slider_mark;
2141 }
2142
2143 if (new_w->scrollBar.orientation == XmHORIZONTAL)
2144 {
2145 if (new_w->scrollBar.processing_direction == XmMAX_ON_LEFT &&
2146 !(new_w->scrollBar.flags & VALUE_SET_FLAG) &&
2147 ((new_w->scrollBar.slider_size != current->scrollBar.slider_size) ||
2148 (new_w->scrollBar.maximum != current->scrollBar.maximum) ||
2149 (new_w->scrollBar.minimum != current->scrollBar.minimum) ))
2150
2151 {
2152 new_w->scrollBar.value = (new_w->scrollBar.maximum
2153 + new_w->scrollBar.minimum
2154 - new_w->scrollBar.slider_size) -
2155 INVERSED_VALUE(current);
2156 new_backwards = FALSE;
2157 current_backwards = FALSE;
2158 }
2159 }
2160
2161
2162 /* Make sure that processing direction tracks orientation */
2163
2164 if ((new_w->scrollBar.orientation != current->scrollBar.orientation)
2165 &&
2166 (new_w->scrollBar.processing_direction ==
2167 current->scrollBar.processing_direction))
2168 {
2169 if ((new_w->scrollBar.orientation == XmHORIZONTAL) &&
2170 (current->scrollBar.processing_direction == XmMAX_ON_TOP))
2171 new_w->scrollBar.processing_direction = XmMAX_ON_LEFT;
2172 else if ((new_w->scrollBar.orientation == XmHORIZONTAL) &&
2173 (current->scrollBar.processing_direction ==
2174 XmMAX_ON_BOTTOM))
2175 new_w->scrollBar.processing_direction = XmMAX_ON_RIGHT;
2176 else if ((new_w->scrollBar.orientation == XmVERTICAL) &&
2177 (current->scrollBar.processing_direction == XmMAX_ON_LEFT))
2178 new_w->scrollBar.processing_direction = XmMAX_ON_TOP;
2179 else if ((new_w->scrollBar.orientation == XmVERTICAL) &&
2180 (current->scrollBar.processing_direction == XmMAX_ON_RIGHT))
2181 new_w->scrollBar.processing_direction = XmMAX_ON_BOTTOM;
2182 }
2183
2184 while (!ValidateInputs(current, request, new_w)) /*EMPTY*/;
2185
2186 /*
2187 * Because someone somewhere originally thought that it was clever
2188 * for the scrollbar widget to do all of its internal processing in
2189 * just one direction, all of the interface procedures have to go
2190 * through extreme gymnastics to support reversal.
2191 */
2192 if ((new_backwards && !current_backwards) ||
2193 (!new_backwards && current_backwards))
2194 {
2195 if (new_w->scrollBar.flags & VALUE_SET_FLAG)
2196 {
2197 if (new_backwards)
2198 new_w->scrollBar.value = INVERSED_VALUE(new_w);
2199 }
2200 else
2201 {
2202 new_w->scrollBar.value = INVERSED_VALUE(new_w);
2203 }
2204 }
2205 else
2206 {
2207 if ((new_w->scrollBar.flags & VALUE_SET_FLAG) &&
2208 (new_backwards))
2209 new_w->scrollBar.value = INVERSED_VALUE(new_w);
2210 }
2211
2212 if (new_w->scrollBar.flags & VALUE_SET_FLAG)
2213 new_w->scrollBar.flags &= ~VALUE_SET_FLAG;
2214
2215 /* See if the GC needs to be regenerated */
2216
2217 if (new_w->core.background_pixel != current->core.background_pixel)
2218 {
2219 XtReleaseGC((Widget) new_w, new_w->scrollBar.foreground_GC);
2220 GetForegroundGC(new_w);
2221 }
2222
2223 if (((new_w->scrollBar.slider_visual == XmTROUGH_COLOR) &&
2224 (new_w->scrollBar.trough_color != current->scrollBar.trough_color)) ||
2225 ((new_w->scrollBar.slider_visual == XmFOREGROUND_COLOR) &&
2226 (new_w->primitive.foreground != current->primitive.foreground)))
2227 {
2228 XtReleaseGC((Widget) new_w, new_w->scrollBar.flat_slider_GC);
2229 GetFlatSliderGC(new_w);
2230 }
2231
2232 /*
2233 * See if the trough (a.k.a the window background) needs to be
2234 * changed to use a different pixel.
2235 */
2236 if (XtIsRealized(nw)) {
2237 Pixel change_to = XmUNSPECIFIED_PIXEL ;
2238 /* slider_visual == XmTROUGH_COLOR is the case where the
2239 window background is the real core.background_pixel, all the
2240 other use the trough_color as the window background */
2241
2242 if ((new_w->scrollBar.slider_visual == XmTROUGH_COLOR) &&
2243 (current->scrollBar.slider_visual != XmTROUGH_COLOR)) {
2244 /* no need to care for background change since Core did it */
2245 change_to = new_w->core.background_pixel;
2246 }
2247 if ((new_w->scrollBar.slider_visual != XmTROUGH_COLOR) &&
2248 ((current->scrollBar.slider_visual == XmTROUGH_COLOR) ||
2249 (new_w->scrollBar.trough_color != current->scrollBar.trough_color) ||
2250 /* if the background had changed, Core has certainly reset the
2251 window background already, so we need to undo that */
2252 (new_w->core.background_pixel != current->core.background_pixel))) {
2253 change_to = new_w->scrollBar.trough_color ;
2254 }
2255 if (change_to != XmUNSPECIFIED_PIXEL) {
2256 returnFlag = TRUE;
2257 XtReleaseGC((Widget) new_w, new_w->scrollBar.flat_slider_GC);
2258 GetFlatSliderGC(new_w);
2259 XSetWindowBackground(XtDisplay((Widget)new_w),
2260 XtWindow((Widget)new_w), change_to);
2261 }
2262 }
2263
2264 /*
2265 * See if the widget needs to be redrawn. Minimize the amount
2266 * of redraw by having specific checks.
2267 */
2268
2269 if ((new_w->scrollBar.orientation !=
2270 current->scrollBar.orientation) ||
2271 (new_w->primitive.shadow_thickness !=
2272 current->primitive.shadow_thickness) ||
2273 (new_w->primitive.highlight_thickness !=
2274 current->primitive.highlight_thickness) ||
2275 (new_w->scrollBar.show_arrows !=
2276 current->scrollBar.show_arrows))
2277 {
2278 /* call Resize method, that will have the effect of
2279 recomputing all the internal variables (arrow size,
2280 trough are) and recreating the slider pixmap. */
2281 XtWidgetProc resize;
2282 _XmProcessLock();
2283 resize = new_w->core.widget_class->core_class.resize;
2284 _XmProcessUnlock();
2285
2286 (* (resize)) ((Widget) new_w);
2287 returnFlag = TRUE;
2288 }
2289
2290 if ((new_w->primitive.foreground !=
2291 current->primitive.foreground)
2292 ||
2293 (new_w->core.background_pixel != current->core.background_pixel)
2294 ||
2295 (new_w->primitive.top_shadow_color !=
2296 current->primitive.top_shadow_color)
2297 ||
2298 (new_w->scrollBar.slider_visual !=
2299 current->scrollBar.slider_visual)
2300 ||
2301 (new_w->scrollBar.slider_mark !=
2302 current->scrollBar.slider_mark)
2303 ||
2304 (new_w->scrollBar.trough_color !=
2305 current->scrollBar.trough_color)
2306 ||
2307 (new_w->primitive.bottom_shadow_color !=
2308 current->primitive.bottom_shadow_color))
2309 {
2310 returnFlag = TRUE;
2311 /* only draw the slider graphics, no need to change the
2312 pixmap (call to GetSliderPixmap) nor the slider size
2313 (call to CalcSliderRect). */
2314 DrawSliderPixmap(new_w);
2315
2316 }
2317
2318 if ((new_w->scrollBar.slider_size !=
2319 current->scrollBar.slider_size) ||
2320 (new_w->scrollBar.minimum != current->scrollBar.minimum) ||
2321 (new_w->scrollBar.maximum != current->scrollBar.maximum) ||
2322 (new_w->scrollBar.processing_direction !=
2323 current->scrollBar.processing_direction)) {
2324
2325 /* have to clear the current slider before setting the
2326 new slider position and size */
2327 if (XtIsRealized(nw))
2328 XClearArea(XtDisplay((Widget)new_w),
2329 XtWindow((Widget)new_w),
2330 new_w->scrollBar.slider_x,
2331 new_w->scrollBar.slider_y,
2332 new_w->scrollBar.slider_width,
2333 new_w->scrollBar.slider_height, False);
2334
2335 /* recompute the slider size and draw in the pixmap */
2336 CalcSliderRect(new_w,
2337 &(new_w->scrollBar.slider_x),
2338 &(new_w->scrollBar.slider_y),
2339 &(new_w->scrollBar.slider_width),
2340 &(new_w->scrollBar.slider_height));
2341
2342 /* redraw the slider in the pixmap */
2343 DrawSliderPixmap (new_w);
2344
2345 if (new_w->scrollBar.slider_size >= (new_w->scrollBar.maximum
2346 - new_w->scrollBar.minimum))
2347 {
2348 new_w->scrollBar.flags &= ~SLIDER_AVAILABLE;
2349 /*
2350 * Disabling the slider enables the arrows. This
2351 * leaves the scrollbar in a state amenable to reenabling
2352 * the slider.
2353 */
2354 new_w->scrollBar.flags |= ARROW1_AVAILABLE;
2355 new_w->scrollBar.flags |= ARROW2_AVAILABLE;
2356 returnFlag = TRUE;
2357 }
2358 else
2359 {
2360 if (! (new_w->scrollBar.flags & SLIDER_AVAILABLE)) {
2361 returnFlag = TRUE;
2362 new_w->scrollBar.flags |= SLIDER_AVAILABLE;
2363 } else {
2364 /* directly use the pixmap that contains the slider
2365 graphics, no need to call RedrawSliderWindow since the
2366 cleararea and the calcrect have already been made */
2367 CopySliderInWindow(new_w);
2368 }
2369 }
2370 }
2371
2372
2373 if (new_w->scrollBar.value != current->scrollBar.value) {
2374 /* the value has changed, the slider needs to move. */
2375 RedrawSliderWindow (new_w);
2376
2377 if (XtIsRealized(nw))
2378 {
2379 /* Following lines taken from Redisplay code; the XmNvalue can change
2380 ** even when the widget is insensitive. Other paths through the code
2381 ** involve user interaction and so sensitivity doesn't need to be
2382 ** considered.
2383 ** NOTE! doesn't deal with FUNKY_INSENSITIVE_VISUAL
2384 */
2385 if (!(XtIsSensitive((Widget)new_w))) {
2386 XmScrollBarWidget sbw = (XmScrollBarWidget) new_w;
2387 XSetClipMask(XtDisplay(sbw), sbw->scrollBar.unavailable_GC, None);
2388 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
2389 sbw->scrollBar.unavailable_GC,
2390 sbw->primitive.highlight_thickness
2391 + sbw->primitive.shadow_thickness,
2392 sbw->primitive.highlight_thickness
2393 + sbw->primitive.shadow_thickness,
2394 XtWidth(sbw) - (2 * (sbw->primitive.highlight_thickness
2395 + sbw->primitive.shadow_thickness)),
2396 XtHeight(sbw) - (2 * (sbw->primitive.highlight_thickness
2397 + sbw->primitive.shadow_thickness)));
2398 }
2399 }
2400 }
2401
2402 if (XtIsSensitive(nw) != XtIsSensitive(cw))
2403 returnFlag = TRUE;
2404
2405 return(returnFlag);
2406 }
2407
2408
2409
2410
2411 /************************************************************************
2412 *
2413 * CalcSliderVal
2414 * Calculate the slider val in application coordinates given
2415 * the input x and y.
2416 *
2417 ************************************************************************/
2418 static int
CalcSliderVal(XmScrollBarWidget sbw,int x,int y)2419 CalcSliderVal(
2420 XmScrollBarWidget sbw,
2421 int x,
2422 int y )
2423 {
2424 float range;
2425 float trueSize; /* size of slider area in pixels */
2426 float referencePoint; /* origin of slider */
2427 float proportion;
2428 int int_proportion;
2429 int slider_area_origin;
2430
2431
2432 if (sbw->scrollBar.orientation == XmHORIZONTAL)
2433 {
2434 referencePoint = (float) x - sbw->scrollBar.separation_x;
2435 trueSize = sbw->scrollBar.slider_area_width;
2436 if (sbw->scrollBar.sliding_mode != XmTHERMOMETER)
2437 trueSize -= sbw->scrollBar.slider_width;
2438 slider_area_origin = sbw->scrollBar.slider_area_x;
2439 }
2440 else
2441 {
2442 referencePoint = (float) y - sbw->scrollBar.separation_y;
2443 trueSize = sbw->scrollBar.slider_area_height;
2444 if (sbw->scrollBar.sliding_mode != XmTHERMOMETER)
2445 trueSize -= sbw->scrollBar.slider_height;
2446 slider_area_origin = sbw->scrollBar.slider_area_y;
2447 }
2448
2449 if (trueSize > 0)
2450
2451 /* figure the proportion of slider area between the origin
2452 of the slider area and the origin of the slider. */
2453 proportion = (referencePoint - slider_area_origin
2454 + (((sbw->scrollBar.show_arrows == XmEACH_SIDE) &&
2455 (sbw->scrollBar.sliding_mode != XmTHERMOMETER))?1:0)) /
2456 trueSize;
2457 else
2458 /*
2459 * We've got an interesting problem here. There isn't any
2460 * slider area available to slide in. What should the value
2461 * of the scrollbar be when the user tries to drag the slider?
2462 *
2463 * Setting proportion to 1 snaps to maximum. Setting
2464 * proportion to the reciprocal of "range" will cause the
2465 * slider to snap to the minimum.
2466 *
2467 */
2468 proportion = 1;
2469
2470 /* Actual range displayed */
2471 range = sbw->scrollBar.maximum - sbw->scrollBar.minimum
2472 - sbw->scrollBar.slider_size;
2473
2474 /* Now scale the proportion in pixels to user units */
2475 proportion = (proportion * range)
2476 + ((float) sbw->scrollBar.minimum);
2477
2478 /* Round off appropriately */
2479 if (proportion > 0)
2480 proportion += 0.5;
2481 else if (proportion < 0)
2482 proportion -= 0.5;
2483
2484 int_proportion = (int) proportion;
2485
2486 if (int_proportion < sbw->scrollBar.minimum)
2487 int_proportion = sbw->scrollBar.minimum;
2488 else if (int_proportion > (sbw->scrollBar.maximum
2489 - sbw->scrollBar.slider_size))
2490 int_proportion = sbw->scrollBar.maximum
2491 - sbw->scrollBar.slider_size;
2492
2493 return (int_proportion);
2494 }
2495
2496
2497
2498
2499 /************************************************************************
2500 *
2501 * Select
2502 * This function processes selections occuring on the scrollBar.
2503 *
2504 ************************************************************************/
2505 static void
Select(Widget wid,XEvent * event,String * params,Cardinal * num_params)2506 Select(
2507 Widget wid,
2508 XEvent *event,
2509 String *params,
2510 Cardinal *num_params )
2511 {
2512 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
2513 XButtonPressedEvent *buttonEvent = (XButtonPressedEvent *) event ;
2514 int slider_x = sbw->scrollBar.slider_x;
2515 int slider_y = sbw->scrollBar.slider_y;
2516 int slider_width = sbw->scrollBar.slider_width;
2517 int slider_height = sbw->scrollBar.slider_height;
2518 Boolean slider_moved;
2519
2520 if (!sbw->scrollBar.editable) return ;
2521
2522
2523 /* add a start update when the button is pressed
2524 so that scrollbar moves generating widget
2525 configurations be bracketed for dropsite update.
2526 The endupdate is done in Release */
2527
2528 XmDropSiteStartUpdate(wid);
2529
2530 sbw->scrollBar.flags &= ~OPERATION_CANCELLED ;
2531
2532 #ifndef DEBUG_NO_SB_GRAB
2533 if (XtGrabKeyboard(wid, False, GrabModeAsync,
2534 GrabModeAsync, buttonEvent->time) == GrabSuccess)
2535 sbw->scrollBar.flags |= KEYBOARD_GRABBED;
2536 #endif
2537
2538 XAllowEvents(XtDisplay(wid), AsyncPointer, CurrentTime);
2539 XAllowEvents(XtDisplay(wid), AsyncKeyboard, CurrentTime);
2540
2541 if (!(sbw->scrollBar.flags & SLIDER_AVAILABLE))
2542 return;
2543 if ((buttonEvent->button == Button1) &&
2544 (!XmIsScrolledWindow(XtParent(wid))))
2545 (void) XmProcessTraversal( (Widget) sbw, XmTRAVERSE_CURRENT);
2546
2547 sbw->scrollBar.separation_x = 0;
2548 sbw->scrollBar.separation_y = 0;
2549
2550
2551 if ((sbw->scrollBar.orientation == XmHORIZONTAL) &&
2552 (buttonEvent->y >= slider_y) &&
2553 (buttonEvent->y <= slider_y + slider_height) &&
2554 (buttonEvent->button == Button1) &&
2555 (sbw->scrollBar.sliding_mode == XmTHERMOMETER) &&
2556 (((PROCESS_DIR_INVERSED(sbw)) &&
2557 (buttonEvent->x >= slider_x) &&
2558 (buttonEvent->x <= slider_x + THERMO_MARK_OFFSET)) ||
2559 (!PROCESS_DIR_INVERSED(sbw) &&
2560 (buttonEvent->x <= slider_x + slider_width) &&
2561 (buttonEvent->x >= slider_x + slider_width - THERMO_MARK_OFFSET))))
2562 /* hack */
2563 buttonEvent->button = Button2 ;
2564
2565 if ((sbw->scrollBar.orientation == XmVERTICAL) &&
2566 (buttonEvent->x >= slider_x) &&
2567 (buttonEvent->x <= slider_x + slider_width) &&
2568 (buttonEvent->button == Button1) &&
2569 (sbw->scrollBar.sliding_mode == XmTHERMOMETER) &&
2570 (((PROCESS_DIR_INVERSED(sbw)) &&
2571 (buttonEvent->y >= slider_y) &&
2572 (buttonEvent->y <= slider_y + THERMO_MARK_OFFSET)) ||
2573 (!PROCESS_DIR_INVERSED(sbw) &&
2574 (buttonEvent->y >= slider_y + slider_height - THERMO_MARK_OFFSET) &&
2575 (buttonEvent->y <= slider_y + slider_height))))
2576 /* hack */
2577 buttonEvent->button = Button2 ;
2578
2579 /* Calculate whether the selection point is in the slider */
2580 if ((buttonEvent->x >= slider_x) &&
2581 (buttonEvent->x <= slider_x + slider_width) &&
2582 (buttonEvent->y >= slider_y) &&
2583 (buttonEvent->y <= slider_y + slider_height) &&
2584 ((buttonEvent->button != Button1) ||
2585 (sbw->scrollBar.sliding_mode != XmTHERMOMETER)))
2586 {
2587 sbw->scrollBar.initial_x = slider_x;
2588 sbw->scrollBar.initial_y = slider_y;
2589 sbw->scrollBar.sliding_on = True;
2590 sbw->scrollBar.saved_value = sbw->scrollBar.value;
2591 sbw->scrollBar.arrow1_selected = FALSE;
2592 sbw->scrollBar.arrow2_selected = FALSE;
2593
2594 if ((buttonEvent->button == Button1) &&
2595 (sbw->scrollBar.sliding_mode != XmTHERMOMETER))
2596 {
2597 sbw->scrollBar.separation_x = buttonEvent->x - slider_x;
2598 sbw->scrollBar.separation_y = buttonEvent->y - slider_y;
2599 }
2600 else if (buttonEvent->button == Button2)
2601 {
2602 /* Warp the slider to the cursor, and then drag */
2603 if (sbw->scrollBar.sliding_mode != XmTHERMOMETER) {
2604 if (sbw->scrollBar.orientation == XmHORIZONTAL)
2605 sbw->scrollBar.separation_x =
2606 sbw->scrollBar.slider_width / 2;
2607 else
2608 sbw->scrollBar.separation_y =
2609 sbw->scrollBar.slider_height / 2;
2610 } else {
2611 sbw->scrollBar.separation_x = 0 ;
2612 sbw->scrollBar.separation_y = 0 ;
2613 }
2614 Moved ((Widget) sbw, (XEvent *) buttonEvent,
2615 params, num_params);
2616 }
2617
2618 return;
2619 }
2620
2621 /* ... in the trough (i.e. slider area)... */
2622 else if ((buttonEvent->x >= sbw->scrollBar.slider_area_x) &&
2623 (buttonEvent->y >= sbw->scrollBar.slider_area_y) &&
2624 (buttonEvent->x <= sbw->scrollBar.slider_area_x
2625 + sbw->scrollBar.slider_area_width) &&
2626 (buttonEvent->y <= sbw->scrollBar.slider_area_y
2627 + sbw->scrollBar.slider_area_height)) {
2628
2629 sbw->scrollBar.arrow1_selected = FALSE;
2630 sbw->scrollBar.arrow2_selected = FALSE;
2631 sbw->scrollBar.saved_value = sbw->scrollBar.value;
2632
2633 if (buttonEvent->button == Button1) {
2634 Position limit_x, limit_y ;
2635
2636 /* Page the slider up or down */
2637 /* what is up or down depends on the processing direction... */
2638
2639 limit_x = sbw->scrollBar.slider_x ;
2640 limit_y = sbw->scrollBar.slider_y ;
2641 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER) {
2642 if (PROCESS_DIR_INVERSED(sbw)) {
2643 limit_x = sbw->scrollBar.slider_area_width -
2644 sbw->scrollBar.slider_width ;
2645 limit_y = sbw->scrollBar.slider_area_height -
2646 sbw->scrollBar.slider_height ;
2647 } else {
2648 limit_x = sbw->scrollBar.slider_width ;
2649 limit_y = sbw->scrollBar.slider_height ;
2650 }
2651 }
2652
2653 if (sbw->scrollBar.orientation == XmHORIZONTAL) {
2654 if (buttonEvent->x < limit_x)
2655 sbw->scrollBar.change_type = XmCR_PAGE_DECREMENT;
2656 else
2657 sbw->scrollBar.change_type = XmCR_PAGE_INCREMENT;
2658 }
2659 else
2660 {
2661 if (buttonEvent->y < limit_y)
2662 sbw->scrollBar.change_type = XmCR_PAGE_DECREMENT;
2663 else
2664 sbw->scrollBar.change_type = XmCR_PAGE_INCREMENT;
2665 }
2666 slider_moved = ChangeScrollBarValue(sbw);
2667 }
2668 else /* Button2 */ {
2669 /* Warp the slider to the cursor, and then drag */
2670
2671 if (sbw->scrollBar.sliding_mode != XmTHERMOMETER) {
2672 if (sbw->scrollBar.orientation == XmHORIZONTAL)
2673 sbw->scrollBar.separation_x =
2674 sbw->scrollBar.slider_width / 2;
2675 else
2676 sbw->scrollBar.separation_y =
2677 sbw->scrollBar.slider_height / 2;
2678 } else {
2679 sbw->scrollBar.separation_x = 0 ;
2680 sbw->scrollBar.separation_y = 0 ;
2681 }
2682
2683 sbw->scrollBar.initial_x = slider_x;
2684 sbw->scrollBar.initial_y = slider_y;
2685 sbw->scrollBar.sliding_on = True;
2686
2687 Moved ((Widget) sbw, (XEvent *) buttonEvent,
2688 params, num_params);
2689 return;
2690 }
2691 }
2692
2693 /* ... in arrow 1 */
2694 else if ((buttonEvent->x >= sbw->scrollBar.arrow1_x) &&
2695 (buttonEvent->y >= sbw->scrollBar.arrow1_y) &&
2696 (buttonEvent->x <= sbw->scrollBar.arrow1_x
2697 + sbw->scrollBar.arrow_width) &&
2698 (buttonEvent->y <= sbw->scrollBar.arrow1_y
2699 + sbw->scrollBar.arrow_height))
2700 {
2701 sbw->scrollBar.change_type = XmCR_DECREMENT;
2702 sbw->scrollBar.saved_value = sbw->scrollBar.value;
2703 sbw->scrollBar.arrow1_selected = True;
2704
2705 slider_moved = ChangeScrollBarValue(sbw) ;
2706 DRAWARROW(sbw, sbw->primitive.bottom_shadow_GC,
2707 sbw -> primitive.top_shadow_GC,
2708 sbw->scrollBar.arrow1_x,
2709 sbw->scrollBar.arrow1_y,
2710 sbw->scrollBar.arrow1_orientation);
2711 }
2712
2713 /* ... in arrow 2 */
2714 else if ((buttonEvent->x >= sbw->scrollBar.arrow2_x) &&
2715 (buttonEvent->y >= sbw->scrollBar.arrow2_y) &&
2716 (buttonEvent->x <= sbw->scrollBar.arrow2_x
2717 + sbw->scrollBar.arrow_width) &&
2718 (buttonEvent->y <= sbw->scrollBar.arrow2_y
2719 + sbw->scrollBar.arrow_height))
2720 {
2721 sbw->scrollBar.change_type = XmCR_INCREMENT;
2722 sbw->scrollBar.saved_value = sbw->scrollBar.value;
2723 sbw->scrollBar.arrow2_selected = True;
2724
2725 slider_moved = ChangeScrollBarValue(sbw) ;
2726 DRAWARROW(sbw, sbw->primitive.bottom_shadow_GC,
2727 sbw -> primitive.top_shadow_GC,
2728 sbw->scrollBar.arrow2_x,
2729 sbw->scrollBar.arrow2_y,
2730 sbw->scrollBar.arrow2_orientation);
2731 }
2732 else
2733 /* ... in the highlight area. */
2734 return;
2735
2736 if (slider_moved) {
2737
2738 ScrollCallback (sbw, sbw->scrollBar.change_type,
2739 sbw->scrollBar.value, 0, 0, (XEvent *) buttonEvent);
2740
2741 XSync (XtDisplay((Widget)sbw), False);
2742
2743 sbw->scrollBar.flags |= FIRST_SCROLL_FLAG ;
2744 sbw->scrollBar.flags &= ~END_TIMER;
2745
2746
2747 if (!sbw->scrollBar.timer)
2748 sbw->scrollBar.timer = XtAppAddTimeOut
2749 (XtWidgetToApplicationContext((Widget) sbw),
2750 (unsigned long) sbw->scrollBar.initial_delay,
2751 TimerEvent, (XtPointer) sbw);
2752 }
2753 }
2754
2755
2756
2757
2758 /************************************************************************
2759 *
2760 * Release
2761 * This function processes releases occuring on the scrollBar.
2762 *
2763 ************************************************************************/
2764 /*ARGSUSED*/
2765 static void
Release(Widget wid,XEvent * event,String * params,Cardinal * num_params)2766 Release(
2767 Widget wid,
2768 XEvent *event,
2769 String *params, /* unused */
2770 Cardinal *num_params ) /* unused */
2771 {
2772 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
2773
2774 if (!sbw->scrollBar.editable) return ;
2775
2776
2777 /* add an end update when the button is released.
2778 see comment in Select for the start update */
2779
2780 XmDropSiteEndUpdate(wid);
2781
2782 sbw->scrollBar.flags &= ~OPERATION_CANCELLED ;
2783
2784 if (sbw->scrollBar.flags & KEYBOARD_GRABBED)
2785 {
2786 XtUngrabKeyboard(wid, ((XButtonPressedEvent *)event)->time);
2787 sbw->scrollBar.flags &= ~KEYBOARD_GRABBED;
2788 }
2789
2790 #ifdef FUNKY_INSENSITIVE_VISUAL
2791 if ( (!(sbw->scrollBar.flags & ARROW1_AVAILABLE)) &&
2792 (sbw->scrollBar.value > sbw->scrollBar.minimum))
2793 {
2794 XClearArea(XtDisplay(sbw), XtWindow(sbw),
2795 sbw->scrollBar.arrow1_x,
2796 sbw->scrollBar.arrow1_y,
2797 sbw->scrollBar.arrow_width,
2798 sbw->scrollBar.arrow_height,
2799 FALSE);
2800
2801 DRAWARROW (sbw, sbw -> primitive.top_shadow_GC,
2802 sbw->primitive.bottom_shadow_GC,
2803 sbw->scrollBar.arrow1_x,
2804 sbw->scrollBar.arrow1_y,
2805 sbw->scrollBar.arrow1_orientation);
2806
2807 sbw->scrollBar.flags |= ARROW1_AVAILABLE;
2808 }
2809 else if (sbw->scrollBar.value == sbw->scrollBar.minimum)
2810 sbw->scrollBar.flags &= ~ARROW1_AVAILABLE;
2811
2812 if ( (!(sbw->scrollBar.flags & ARROW2_AVAILABLE)) &&
2813 (sbw->scrollBar.value < (sbw->scrollBar.maximum
2814 - sbw->scrollBar.slider_size)))
2815 {
2816 XClearArea(XtDisplay(sbw), XtWindow(sbw),
2817 sbw->scrollBar.arrow2_x,
2818 sbw->scrollBar.arrow2_y,
2819 sbw->scrollBar.arrow_width,
2820 sbw->scrollBar.arrow_height,
2821 FALSE);
2822
2823 DRAWARROW (sbw, sbw->primitive.top_shadow_GC,
2824 sbw -> primitive.bottom_shadow_GC,
2825 sbw->scrollBar.arrow2_x,
2826 sbw->scrollBar.arrow2_y,
2827 sbw->scrollBar.arrow2_orientation);
2828
2829 sbw->scrollBar.flags |= ARROW2_AVAILABLE;
2830 }
2831 else if (sbw->scrollBar.value == (sbw->scrollBar.maximum
2832 - sbw->scrollBar.slider_size))
2833 sbw->scrollBar.flags &= ~ARROW2_AVAILABLE;
2834 #endif
2835 if (sbw->scrollBar.arrow1_selected)
2836 {
2837 sbw->scrollBar.arrow1_selected = False;
2838
2839 DRAWARROW (sbw, sbw -> primitive.top_shadow_GC,
2840 sbw->primitive.bottom_shadow_GC,
2841 sbw->scrollBar.arrow1_x,
2842 sbw->scrollBar.arrow1_y,
2843 sbw->scrollBar.arrow1_orientation);
2844 }
2845
2846 if (sbw->scrollBar.arrow2_selected)
2847 {
2848 sbw->scrollBar.arrow2_selected = False;
2849
2850 DRAWARROW (sbw, sbw->primitive.top_shadow_GC,
2851 sbw -> primitive.bottom_shadow_GC,
2852 sbw->scrollBar.arrow2_x,
2853 sbw->scrollBar.arrow2_y,
2854 sbw->scrollBar.arrow2_orientation);
2855 }
2856
2857 if (! (sbw->scrollBar.flags & SLIDER_AVAILABLE))
2858 return;
2859
2860 if (sbw->scrollBar.timer != 0)
2861 {
2862 sbw->scrollBar.flags |= END_TIMER;
2863 }
2864
2865 if (sbw->scrollBar.sliding_on == True)
2866 {
2867 sbw->scrollBar.sliding_on = False;
2868 ScrollCallback (sbw, XmCR_VALUE_CHANGED, sbw->scrollBar.value,
2869 event->xbutton.x, event->xbutton.y, event);
2870 }
2871
2872 #ifdef FUNKY_INSENSITIVE_VISUAL
2873 XSetClipMask(XtDisplay(sbw), sbw->scrollBar.unavailable_GC, None);
2874 if (! (sbw->scrollBar.flags & ARROW1_AVAILABLE))
2875 {
2876 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
2877 sbw->scrollBar.unavailable_GC,
2878 sbw->scrollBar.arrow1_x,
2879 sbw->scrollBar.arrow1_y,
2880 sbw->scrollBar.arrow_width,
2881 sbw->scrollBar.arrow_height);
2882 }
2883 else if (! (sbw->scrollBar.flags & ARROW2_AVAILABLE))
2884 {
2885 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
2886 sbw->scrollBar.unavailable_GC,
2887 sbw->scrollBar.arrow2_x,
2888 sbw->scrollBar.arrow2_y,
2889 sbw->scrollBar.arrow_width,
2890 sbw->scrollBar.arrow_height);
2891 }
2892 #endif
2893 }
2894
2895
2896
2897
2898 /************************************************************************
2899 *
2900 * Moved
2901 * This function processes mouse moved events during interactive
2902 * slider moves.
2903 *
2904 ************************************************************************/
2905 /*ARGSUSED*/
2906 static void
Moved(Widget wid,XEvent * event,String * params,Cardinal * num_params)2907 Moved(
2908 Widget wid,
2909 XEvent *event,
2910 String *params, /* unused */
2911 Cardinal *num_params ) /* unused */
2912 {
2913 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
2914 XButtonPressedEvent * buttonEvent = (XButtonPressedEvent *) event;
2915 int newX, newY;
2916 int realX, realY;
2917 int slideVal;
2918 int button_x;
2919 int button_y;
2920 int real_width_limit =
2921 (sbw->scrollBar.snap_back_multiple +
2922 (buttonEvent->x > 0)) * XtWidth(wid);
2923 int real_height_limit =
2924 (sbw->scrollBar.snap_back_multiple +
2925 (buttonEvent->y > 0)) * XtHeight(wid) ;
2926
2927 if (!sbw->scrollBar.editable) return ;
2928
2929 if (! (sbw->scrollBar.flags & SLIDER_AVAILABLE)) return;
2930
2931 /* operation was cancelled, so don't restart the move
2932 as it could happen with the snapBack stuff */
2933 if (sbw->scrollBar.flags & OPERATION_CANCELLED) return;
2934
2935 if (!sbw->scrollBar.sliding_on) return;
2936
2937 /* Only deal with snap_back if operation was started by a
2938 click in the slider. */
2939 if (((sbw->scrollBar.orientation == XmVERTICAL) &&
2940 ((buttonEvent->x > real_width_limit) ||
2941 (-buttonEvent->x > real_width_limit))) ||
2942 ((sbw->scrollBar.orientation == XmHORIZONTAL) &&
2943 ((buttonEvent->y > real_height_limit) ||
2944 (-buttonEvent->y > real_height_limit)))) {
2945 /* going out of the snap back area */
2946
2947 if (!(sbw->scrollBar.add_flags & SNAPPED_OUT)) {
2948 short savedX, savedY, j1, j2;
2949
2950 /* get the saved value, also used by the Cancel action */
2951 sbw->scrollBar.value = sbw->scrollBar.saved_value;
2952 CalcSliderRect(sbw, &savedX, &savedY, &j1, &j2);
2953 MoveSlider(sbw, savedX, savedY);
2954 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER)
2955 RedrawSliderWindow (sbw);
2956 ScrollCallback (sbw, XmCR_VALUE_CHANGED,
2957 sbw->scrollBar.value, savedX, savedY,
2958 (XEvent *) buttonEvent);
2959
2960 sbw->scrollBar.add_flags |= SNAPPED_OUT ;
2961 }
2962 return ;
2963 } else {
2964 /* moving in the snap back area */
2965 sbw->scrollBar.add_flags &= ~SNAPPED_OUT ; ;
2966 }
2967
2968 button_x = buttonEvent->x;
2969 button_y = buttonEvent->y;
2970
2971 /*
2972 * Force button_x and button_y to be within the slider_area.
2973 */
2974 if (button_x < sbw->scrollBar.slider_area_x)
2975 button_x = sbw->scrollBar.slider_area_x;
2976
2977 if (button_x >
2978 sbw->scrollBar.slider_area_x + sbw->scrollBar.slider_area_width)
2979 button_x = sbw->scrollBar.slider_area_x
2980 + sbw->scrollBar.slider_area_width;
2981
2982 if (button_y < sbw->scrollBar.slider_area_y)
2983 button_y = sbw->scrollBar.slider_area_y;
2984
2985 if (button_y >
2986 sbw->scrollBar.slider_area_y
2987 + sbw->scrollBar.slider_area_height)
2988 button_y = sbw->scrollBar.slider_area_y
2989 + sbw->scrollBar.slider_area_height;
2990
2991
2992 /*
2993 * Calculate the new origin of the slider.
2994 * Bound the values with the slider area.
2995 */
2996 if (sbw->scrollBar.orientation == XmHORIZONTAL)
2997 {
2998 newX = realX = button_x - sbw->scrollBar.separation_x;
2999 newY = realY = sbw->scrollBar.slider_y;
3000
3001 if (newX < sbw->scrollBar.slider_area_x)
3002 newX = sbw->scrollBar.slider_area_x;
3003
3004 if ((newX + sbw->scrollBar.slider_width >
3005 sbw->scrollBar.slider_area_x
3006 + sbw->scrollBar.slider_area_width) &&
3007 (sbw->scrollBar.sliding_mode != XmTHERMOMETER))
3008 newX = sbw->scrollBar.slider_area_x
3009 + sbw->scrollBar.slider_area_width
3010 - sbw->scrollBar.slider_width;
3011 }
3012 else
3013 {
3014 newX = realX = sbw->scrollBar.slider_x;
3015 newY = realY = button_y - sbw->scrollBar.separation_y;
3016
3017
3018 if (newY < sbw->scrollBar.slider_area_y)
3019 newY = sbw->scrollBar.slider_area_y;
3020
3021 if ((newY + sbw->scrollBar.slider_height >
3022 sbw->scrollBar.slider_area_y
3023 + sbw->scrollBar.slider_area_height) &&
3024 (sbw->scrollBar.sliding_mode != XmTHERMOMETER))
3025 newY = sbw->scrollBar.slider_area_y
3026 + sbw->scrollBar.slider_area_height
3027 - sbw->scrollBar.slider_height;
3028 }
3029
3030
3031 if (((sbw->scrollBar.orientation == XmHORIZONTAL) &&
3032 (realX != sbw->scrollBar.initial_x))
3033 ||
3034 ((sbw->scrollBar.orientation == XmVERTICAL) &&
3035 (realY != sbw->scrollBar.initial_y)))
3036 {
3037 slideVal = CalcSliderVal (sbw, button_x, button_y);
3038
3039 if ((newX != sbw->scrollBar.initial_x) ||
3040 (newY != sbw->scrollBar.initial_y))
3041 {
3042 MoveSlider (sbw, newX, newY);
3043 sbw->scrollBar.initial_x = newX;
3044 sbw->scrollBar.initial_y = newY;
3045 }
3046
3047 if (slideVal != sbw->scrollBar.value)
3048 {
3049 sbw->scrollBar.value = slideVal;
3050
3051 if (slideVal >= (sbw->scrollBar.maximum
3052 - sbw->scrollBar.slider_size))
3053 slideVal = sbw->scrollBar.maximum
3054 - sbw->scrollBar.slider_size;
3055
3056 if (slideVal <= sbw->scrollBar.minimum)
3057 slideVal = sbw->scrollBar.minimum;
3058 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER)
3059 RedrawSliderWindow (sbw);
3060 ScrollCallback(sbw, XmCR_DRAG,
3061 sbw->scrollBar.value = slideVal,
3062 buttonEvent->x, buttonEvent->y,
3063 (XEvent *) buttonEvent);
3064 }
3065 }
3066 }
3067
3068
3069
3070
3071 /*********************************************************************
3072 *
3073 * TopOrBottom
3074 * Issue the to top or bottom callbacks.
3075 *
3076 *********************************************************************/
3077 /*ARGSUSED*/
3078 static void
TopOrBottom(Widget wid,XEvent * event,String * params,Cardinal * num_params)3079 TopOrBottom(
3080 Widget wid,
3081 XEvent *event,
3082 String *params, /* unused */
3083 Cardinal *num_params ) /* unused */
3084 {
3085 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
3086 XmScrollBarPart *sbp = (XmScrollBarPart *) &(sbw->scrollBar);
3087
3088 if (!sbw->scrollBar.editable) return ;
3089
3090 sbw->scrollBar.flags &= ~OPERATION_CANCELLED ;
3091
3092 if (! (sbw->scrollBar.flags & SLIDER_AVAILABLE))
3093 return;
3094
3095 if (event->type == KeyPress) {
3096 Modifiers junk;
3097 KeySym key_sym;
3098 XKeyPressedEvent *keyEvent = (XKeyPressedEvent *) event;
3099
3100 key_sym = XtGetActionKeysym(event, &junk);
3101
3102 if (key_sym == osfXK_BeginLine) {
3103 if (sbp->orientation == XmVERTICAL) {
3104 if (sbp->processing_direction == XmMAX_ON_BOTTOM)
3105 MoveSlider(sbw, sbp->slider_x, sbp->slider_area_y);
3106 else
3107 MoveSlider(sbw,
3108 sbp->slider_x,
3109 sbp->slider_area_y + sbp->slider_area_height
3110 - sbp->slider_height);
3111 } else {
3112 if (sbp->processing_direction == XmMAX_ON_RIGHT)
3113 MoveSlider(sbw, sbp->slider_area_x, sbp->slider_y);
3114 else
3115 MoveSlider(sbw,
3116 sbp->slider_area_x + sbp->slider_area_width
3117 - sbp->slider_width,
3118 sbp->slider_y);
3119 }
3120 /*
3121 * The following grevious bogosity is due to the fact
3122 * that the key behavior was implemented long after
3123 * the rest of this code, and so we have to work around
3124 * currently operating nonsense.
3125 *
3126 * Specifically, since the dawn of time, ScrollBar
3127 * processes in just one direction, and does any necessary
3128 * reversal just before calling the callback.
3129 *
3130 * We now proceed to trick that code into doing the right
3131 * thing anyway
3132 */
3133 if (!PROCESS_DIR_INVERSED(sbw)) {
3134 sbp->value = sbp->minimum;
3135 if (sbp->sliding_mode == XmTHERMOMETER)
3136 RedrawSliderWindow (sbw);
3137 ScrollCallback(sbw, XmCR_TO_TOP, sbp->value,
3138 keyEvent->x, keyEvent->y,
3139 (XEvent *) keyEvent);
3140 } else {
3141 sbp->value = sbp->maximum - sbp->slider_size;
3142 if (sbp->sliding_mode == XmTHERMOMETER)
3143 RedrawSliderWindow (sbw);
3144 ScrollCallback(sbw, XmCR_TO_BOTTOM, sbp->value,
3145 keyEvent->x, keyEvent->y,
3146 (XEvent *) keyEvent);
3147 }
3148 }
3149 else /* key_sym == osfXK_EndLine */ {
3150 if (sbp->orientation == XmVERTICAL) {
3151 if (sbp->processing_direction == XmMAX_ON_BOTTOM)
3152 MoveSlider(sbw,
3153 sbp->slider_x,
3154 sbp->slider_area_y + sbp->slider_area_height
3155 - sbp->slider_height);
3156 else
3157 MoveSlider(sbw, sbp->slider_x, sbp->slider_area_y);
3158 } else {
3159 if (sbp->processing_direction == XmMAX_ON_RIGHT)
3160 MoveSlider(sbw,
3161 sbp->slider_area_x + sbp->slider_area_width
3162 - sbp->slider_width,
3163 sbp->slider_y);
3164 else
3165 MoveSlider(sbw, sbp->slider_area_x, sbp->slider_y);
3166 }
3167
3168 /* See above for explanation of this nonsense */
3169 if (!PROCESS_DIR_INVERSED(sbw)) {
3170 sbp->value = sbp->maximum - sbp->slider_size;
3171 if (sbp->sliding_mode == XmTHERMOMETER)
3172 RedrawSliderWindow (sbw);
3173 ScrollCallback(sbw, XmCR_TO_BOTTOM, sbp->value,
3174 keyEvent->x, keyEvent->y,
3175 (XEvent *) keyEvent);
3176 } else {
3177 sbp->value = sbp->minimum;
3178 if (sbp->sliding_mode == XmTHERMOMETER)
3179 RedrawSliderWindow (sbw);
3180 ScrollCallback (sbw, XmCR_TO_TOP, sbp->value,
3181 keyEvent->x, keyEvent->y,
3182 (XEvent *) keyEvent);
3183 }
3184 }
3185 } else /* event->type == ButtonPress */ {
3186 XButtonPressedEvent *buttonEvent =
3187 (XButtonPressedEvent *) event;
3188
3189 XmDropSiteStartUpdate(wid);
3190
3191 if /* In arrow1... */
3192 ((buttonEvent->x >= sbp->arrow1_x) &&
3193 (buttonEvent->y >= sbp->arrow1_y) &&
3194 (buttonEvent->x <= sbp->arrow1_x + sbp->arrow_width) &&
3195 (buttonEvent->y <= sbp->arrow1_y + sbp->arrow_height)) {
3196 sbp->change_type = XmCR_DECREMENT;
3197 sbp->arrow1_selected = True;
3198
3199 DRAWARROW(sbw, sbw->primitive.bottom_shadow_GC,
3200 sbw -> primitive.top_shadow_GC,
3201 sbw->scrollBar.arrow1_x,
3202 sbw->scrollBar.arrow1_y,
3203 sbw->scrollBar.arrow1_orientation);
3204
3205 if (sbp->orientation == XmVERTICAL)
3206 MoveSlider(sbw, sbp->slider_x, sbp->slider_area_y);
3207 else
3208 MoveSlider(sbw, sbp->slider_area_x, sbp->slider_y);
3209
3210 sbp->value = sbp->minimum;
3211 if (sbp->sliding_mode == XmTHERMOMETER)
3212 RedrawSliderWindow (sbw);
3213 ScrollCallback (sbw, XmCR_TO_TOP, sbp->value,
3214 buttonEvent->x, buttonEvent->y,
3215 (XEvent *) buttonEvent);
3216 }
3217
3218 else if /* In arrow2... */
3219 ((buttonEvent->x >= sbp->arrow2_x) &&
3220 (buttonEvent->y >= sbp->arrow2_y) &&
3221 (buttonEvent->x <= sbp->arrow2_x
3222 + sbp->arrow_width) &&
3223 (buttonEvent->y <= sbp->arrow2_y
3224 + sbp->arrow_height))
3225 {
3226 sbp->change_type = XmCR_INCREMENT;
3227 sbp->arrow2_selected = True;
3228
3229 DRAWARROW (sbw, sbw->primitive.bottom_shadow_GC,
3230 sbw -> primitive.top_shadow_GC,
3231 sbw->scrollBar.arrow2_x,
3232 sbw->scrollBar.arrow2_y,
3233 sbw->scrollBar.arrow2_orientation);
3234 if (sbp->orientation == XmVERTICAL)
3235 MoveSlider(sbw,
3236 sbp->slider_x,
3237 sbp->slider_area_y + sbp->slider_area_height
3238 - sbp->slider_height);
3239 else
3240 MoveSlider(sbw,
3241 sbp->slider_area_x + sbp->slider_area_width
3242 - sbp->slider_width,
3243 sbp->slider_y);
3244 sbp->value = sbp->maximum - sbp->slider_size;
3245 if (sbp->sliding_mode == XmTHERMOMETER)
3246 RedrawSliderWindow (sbw);
3247 ScrollCallback (sbw, XmCR_TO_BOTTOM,
3248 sbp->value, buttonEvent->x, buttonEvent->y,
3249 (XEvent *) buttonEvent);
3250 }
3251 else if /* in the trough between arrow2 and the slider... */
3252 (((sbp->sliding_mode != XmTHERMOMETER) &&
3253 (((sbp->orientation == XmHORIZONTAL) &&
3254 (buttonEvent->x >= sbp->slider_area_x) &&
3255 (buttonEvent->x < sbp->slider_x) &&
3256 (buttonEvent->y >= sbp->slider_area_y) &&
3257 (buttonEvent->y <= sbp->slider_area_y
3258 + sbp->slider_area_height))
3259 ||
3260 ((sbp->orientation == XmVERTICAL) &&
3261 (buttonEvent->y >= sbp->slider_area_y) &&
3262 (buttonEvent->y < sbp->slider_y) &&
3263 (buttonEvent->x >= sbp->slider_area_x) &&
3264 (buttonEvent->x < sbp->slider_area_x
3265 + sbp->slider_area_width)))) ||
3266 /* only partial treatment, processing direction
3267 has to be handled here */
3268 ((sbp->sliding_mode == XmTHERMOMETER) &&
3269 (((sbp->orientation == XmHORIZONTAL) &&
3270 (buttonEvent->x >= sbp->slider_area_x) &&
3271 (buttonEvent->x < sbp->slider_width) &&
3272 (buttonEvent->y >= sbp->slider_area_y) &&
3273 (buttonEvent->y <= sbp->slider_area_y
3274 + sbp->slider_area_height))
3275 ||
3276 ((sbp->orientation == XmVERTICAL) &&
3277 (buttonEvent->y < sbp->slider_area_height
3278 - sbp->slider_height) &&
3279 (buttonEvent->x >= sbp->slider_area_x) &&
3280 (buttonEvent->x < sbp->slider_area_x
3281 + sbp->slider_area_width)))))
3282 {
3283 if (sbp->orientation == XmVERTICAL)
3284 MoveSlider(sbw, sbp->slider_x, sbp->slider_area_y);
3285 else
3286 MoveSlider(sbw, sbp->slider_area_x, sbp->slider_y);
3287 sbp->value = sbp->minimum;
3288 if (sbp->sliding_mode == XmTHERMOMETER)
3289 RedrawSliderWindow (sbw);
3290 ScrollCallback (sbw, XmCR_TO_TOP, sbp->value,
3291 buttonEvent->x, buttonEvent->y,
3292 (XEvent *) buttonEvent);
3293 }
3294 else if
3295 /* in the trough between arrow1 and the slider... */
3296 (((sbp->orientation == XmHORIZONTAL) &&
3297 (buttonEvent->x > sbp->slider_x + sbp->slider_width) &&
3298 (buttonEvent->x <= sbp->slider_area_x
3299 + sbp->slider_area_width) &&
3300 (buttonEvent->y >= sbp->slider_area_y) &&
3301 (buttonEvent->y <= sbp->slider_area_y
3302 + sbp->slider_area_height))
3303 ||
3304 ((sbp->orientation == XmVERTICAL) &&
3305 (buttonEvent->y > sbp->slider_y
3306 + sbp->slider_height) &&
3307 (buttonEvent->y <= sbp->slider_area_y
3308 + sbp->slider_area_height) &&
3309 (buttonEvent->x >= sbp->slider_area_x) &&
3310 (buttonEvent->x <= sbp->slider_area_x
3311 + sbp->slider_area_width))
3312 || (sbp->sliding_mode == XmTHERMOMETER)) {
3313 if (sbp->orientation == XmVERTICAL)
3314 MoveSlider(sbw,
3315 sbp->slider_x,
3316 sbp->slider_area_y + sbp->slider_area_height
3317 - sbp->slider_height);
3318 else
3319 MoveSlider(sbw,
3320 sbp->slider_area_x + sbp->slider_area_width
3321 - sbp->slider_width,
3322 sbp->slider_y);
3323 sbp->value = sbp->maximum - sbp->slider_size;
3324 if (sbp->sliding_mode == XmTHERMOMETER)
3325 RedrawSliderWindow (sbw);
3326 ScrollCallback (sbw, XmCR_TO_BOTTOM,
3327 sbp->value, buttonEvent->x, buttonEvent->y,
3328 (XEvent *) buttonEvent);
3329 }
3330
3331 }
3332 #ifdef FUNKY_INSENSITIVE_VISUAL
3333 XSetClipMask(XtDisplay(sbw), sbw->scrollBar.unavailable_GC, None);
3334 if (sbp->value == sbp->minimum) {
3335 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
3336 sbw->scrollBar.unavailable_GC,
3337 sbw->scrollBar.arrow1_x,
3338 sbw->scrollBar.arrow1_y,
3339 sbw->scrollBar.arrow_width,
3340 sbw->scrollBar.arrow_height);
3341
3342 sbw->scrollBar.flags &= ~ARROW1_AVAILABLE;
3343
3344 if (! (sbw->scrollBar.flags & ARROW2_AVAILABLE)) {
3345 XClearArea(XtDisplay(sbw), XtWindow(sbw),
3346 sbw->scrollBar.arrow2_x,
3347 sbw->scrollBar.arrow2_y,
3348 sbw->scrollBar.arrow_width,
3349 sbw->scrollBar.arrow_height,
3350 FALSE);
3351
3352 DRAWARROW (sbw, sbw -> primitive.top_shadow_GC,
3353 sbw->primitive.bottom_shadow_GC,
3354 sbw->scrollBar.arrow2_x,
3355 sbw->scrollBar.arrow2_y,
3356 sbw->scrollBar.arrow2_orientation);
3357
3358 sbw->scrollBar.flags |= ARROW2_AVAILABLE;
3359 }
3360 }
3361 else /* sbp->value == (sbp->maximum - sbp->slider_size) */
3362 {
3363 /* XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
3364 sbw->scrollBar.unavailable_GC,
3365 sbw->scrollBar.arrow2_x,
3366 sbw->scrollBar.arrow2_y,
3367 sbw->scrollBar.arrow_width,
3368 sbw->scrollBar.arrow_height);
3369 */
3370 sbw->scrollBar.flags &= ~ARROW2_AVAILABLE;
3371
3372 if (! (sbw->scrollBar.flags & ARROW1_AVAILABLE)) {
3373 XClearArea(XtDisplay(sbw), XtWindow(sbw),
3374 sbw->scrollBar.arrow1_x,
3375 sbw->scrollBar.arrow1_y,
3376 sbw->scrollBar.arrow_width,
3377 sbw->scrollBar.arrow_height,
3378 FALSE);
3379
3380 DRAWARROW (sbw, sbw -> primitive.top_shadow_GC,
3381 sbw->primitive.bottom_shadow_GC,
3382 sbw->scrollBar.arrow1_x,
3383 sbw->scrollBar.arrow1_y,
3384 sbw->scrollBar.arrow1_orientation);
3385
3386 sbw->scrollBar.flags |= ARROW1_AVAILABLE;
3387 }
3388 }
3389 #endif
3390 }
3391
3392
3393
3394
3395 /*********************************************************************
3396 *
3397 * IncrementUpOrLeft
3398 * The up or left key was pressed, decrease the value by
3399 * one increment.
3400 *
3401 *********************************************************************/
3402 /*ARGSUSED*/
3403 static void
IncrementUpOrLeft(Widget wid,XEvent * event,String * params,Cardinal * num_params)3404 IncrementUpOrLeft(
3405 Widget wid,
3406 XEvent *event,
3407 String *params,
3408 Cardinal *num_params )
3409 {
3410 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
3411
3412 int new_value;
3413 int key_pressed;
3414
3415 if (!num_params || (*num_params != 1) || !params)
3416 {
3417 XmeWarning(wid, MESSAGE14);
3418 return;
3419 }
3420
3421 if (!sbw->scrollBar.editable) return ;
3422
3423
3424 sbw->scrollBar.flags &= ~OPERATION_CANCELLED ;
3425
3426 if (! (sbw->scrollBar.flags & SLIDER_AVAILABLE))
3427 return;
3428
3429 /*
3430 * arg value passed in will either be "up" for the up key or
3431 * "left" for the left arrow key (or for compatibility 0 -> up
3432 * key or 1 -> left key. The key needs to be compared with the
3433 * scrollbar orientation to ensure only the proper directional key
3434 * presses work.
3435 */
3436
3437 if (_XmConvertActionParamToRepTypeId((Widget) sbw,
3438 XmRID_SCROLL_BAR_INCREMENT_UP_OR_LEFT_ACTION_PARAMS,
3439 params[0], True, &key_pressed) == False)
3440 {
3441 /* We couldn't convert the value. Just assume a value of 0. */
3442 key_pressed = 0;
3443 }
3444
3445 if (((key_pressed == 0) &&
3446 (sbw->scrollBar.orientation == XmHORIZONTAL))
3447 ||
3448 ((key_pressed == 1) &&
3449 (sbw->scrollBar.orientation == XmVERTICAL)))
3450 return;
3451
3452 new_value = sbw->scrollBar.value - sbw->scrollBar.increment;
3453
3454 if (new_value < sbw->scrollBar.minimum)
3455 new_value = sbw->scrollBar.minimum;
3456
3457 if (new_value != sbw->scrollBar.value)
3458 {
3459 sbw->scrollBar.value = new_value;
3460 #ifdef FUNKY_INSENSITIVE_VISUAL
3461 if ((sbw->scrollBar.value = new_value)
3462 == sbw->scrollBar.minimum)
3463 {
3464 XSetClipMask(XtDisplay(sbw),
3465 sbw->scrollBar.unavailable_GC, None);
3466 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
3467 sbw->scrollBar.unavailable_GC,
3468 sbw->scrollBar.arrow1_x,
3469 sbw->scrollBar.arrow1_y,
3470 sbw->scrollBar.arrow_width,
3471 sbw->scrollBar.arrow_height);
3472
3473 sbw->scrollBar.flags &= ~ARROW1_AVAILABLE;
3474 }
3475 #endif
3476 if ((sbw->scrollBar.show_arrows) &&
3477 (! (sbw->scrollBar.flags & ARROW2_AVAILABLE)))
3478 {
3479 XClearArea(XtDisplay(sbw), XtWindow(sbw),
3480 sbw->scrollBar.arrow2_x,
3481 sbw->scrollBar.arrow2_y,
3482 sbw->scrollBar.arrow_width,
3483 sbw->scrollBar.arrow_height,
3484 FALSE);
3485
3486 DRAWARROW (sbw, sbw -> primitive.top_shadow_GC,
3487 sbw->primitive.bottom_shadow_GC,
3488 sbw->scrollBar.arrow2_x,
3489 sbw->scrollBar.arrow2_y,
3490 sbw->scrollBar.arrow2_orientation);
3491
3492 sbw->scrollBar.flags |= ARROW2_AVAILABLE;
3493 }
3494
3495 RedrawSliderWindow (sbw);
3496
3497 ScrollCallback (sbw, XmCR_DECREMENT, sbw->scrollBar.value,
3498 event->xbutton.x, event->xbutton.y, event);
3499 }
3500 }
3501
3502
3503
3504
3505 /*********************************************************************
3506 *
3507 * IncrementDownOrRight
3508 * The down or right key was pressed, increase the value by
3509 * one increment.
3510 *
3511 *********************************************************************/
3512 /*ARGSUSED*/
3513 static void
IncrementDownOrRight(Widget wid,XEvent * event,String * params,Cardinal * num_params)3514 IncrementDownOrRight(
3515 Widget wid,
3516 XEvent *event,
3517 String *params,
3518 Cardinal *num_params )
3519 {
3520 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
3521 int new_value;
3522 int key_pressed;
3523
3524 if (!num_params || (*num_params != 1) || !params)
3525 {
3526 XmeWarning(wid, MESSAGE14);
3527 return;
3528 }
3529
3530 if (!sbw->scrollBar.editable) return ;
3531
3532 sbw->scrollBar.flags &= ~OPERATION_CANCELLED ;
3533
3534 if (! (sbw->scrollBar.flags & SLIDER_AVAILABLE))
3535 return;
3536
3537 /*
3538 * arg value passed in will either be "down" for the down key or
3539 * "right" for the right arrow key (or for compatibility 0 -> down
3540 * key or 1 -> right key. The key needs to be compared with the
3541 * scrollbar orientation to ensure only the proper directional key
3542 * presses work.
3543 */
3544
3545 if (_XmConvertActionParamToRepTypeId((Widget) sbw,
3546 XmRID_SCROLL_BAR_INCREMENT_DOWN_OR_RIGHT_ACTION_PARAMS,
3547 params[0], True, &key_pressed) == False)
3548 {
3549 /* We couldn't convert the value. Just assume a value of 0. */
3550 key_pressed = 0;
3551 }
3552
3553 if (((key_pressed == 0) &&
3554 (sbw->scrollBar.orientation == XmHORIZONTAL))
3555 ||
3556 ((key_pressed == 1) &&
3557 (sbw->scrollBar.orientation == XmVERTICAL)))
3558 return;
3559
3560 new_value = sbw->scrollBar.value + sbw->scrollBar.increment;
3561
3562 if (new_value > sbw->scrollBar.maximum - sbw->scrollBar.slider_size)
3563 new_value = sbw->scrollBar.maximum - sbw->scrollBar.slider_size;
3564
3565 if (new_value != sbw->scrollBar.value)
3566 {
3567 sbw->scrollBar.value = new_value;
3568 #ifdef FUNKY_INSENSITIVE_VISUAL
3569 if ((sbw->scrollBar.value = new_value)
3570 == (sbw->scrollBar.maximum - sbw->scrollBar.slider_size))
3571 {
3572 XSetClipMask(XtDisplay(sbw),
3573 sbw->scrollBar.unavailable_GC, None);
3574 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
3575 sbw->scrollBar.unavailable_GC,
3576 sbw->scrollBar.arrow2_x,
3577 sbw->scrollBar.arrow2_y,
3578 sbw->scrollBar.arrow_width,
3579 sbw->scrollBar.arrow_height);
3580
3581 sbw->scrollBar.flags &= ~ARROW2_AVAILABLE;
3582 }
3583 #endif
3584 if ((sbw->scrollBar.show_arrows) &&
3585 (! (sbw->scrollBar.flags & ARROW1_AVAILABLE)))
3586
3587 {
3588 XClearArea(XtDisplay(sbw), XtWindow(sbw),
3589 sbw->scrollBar.arrow1_x,
3590 sbw->scrollBar.arrow1_y,
3591 sbw->scrollBar.arrow_width,
3592 sbw->scrollBar.arrow_height,
3593 FALSE);
3594
3595 DRAWARROW (sbw, sbw -> primitive.top_shadow_GC,
3596 sbw->primitive.bottom_shadow_GC,
3597 sbw->scrollBar.arrow1_x,
3598 sbw->scrollBar.arrow1_y,
3599 sbw->scrollBar.arrow1_orientation);
3600
3601 sbw->scrollBar.flags |= ARROW1_AVAILABLE;
3602 }
3603
3604 RedrawSliderWindow (sbw);
3605
3606 ScrollCallback (sbw, XmCR_INCREMENT, sbw->scrollBar.value,
3607 event->xbutton.x, event->xbutton.y, event);
3608 }
3609 }
3610
3611
3612
3613
3614 /*********************************************************************
3615 *
3616 * PageUpOrLeft
3617 * The up or left key was pressed, decrease the value by
3618 * one increment.
3619 *
3620 *********************************************************************/
3621 /*ARGSUSED*/
3622 static void
PageUpOrLeft(Widget wid,XEvent * event,String * params,Cardinal * num_params)3623 PageUpOrLeft(
3624 Widget wid,
3625 XEvent *event,
3626 String *params,
3627 Cardinal *num_params )
3628 {
3629 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
3630 int new_value;
3631 int key_pressed;
3632
3633 if (!num_params || (*num_params != 1) || !params)
3634 {
3635 XmeWarning(wid, MESSAGE14);
3636 return;
3637 }
3638
3639 if (!sbw->scrollBar.editable) return ;
3640
3641 sbw->scrollBar.flags &= ~OPERATION_CANCELLED ;
3642
3643 if (! (sbw->scrollBar.flags & SLIDER_AVAILABLE))
3644 return;
3645 /*
3646 * arg value passed in will either be "up" for the up key or
3647 * "left" for the left arrow key (or for compatibility 0 -> up
3648 * key or 1 -> left key. The key needs to be compared with the
3649 * scrollbar orientation to ensure only the proper directional key
3650 * presses work.
3651 */
3652
3653 if (_XmConvertActionParamToRepTypeId((Widget) sbw,
3654 XmRID_SCROLL_BAR_PAGE_UP_OR_LEFT_ACTION_PARAMS,
3655 params[0], True, &key_pressed) == False)
3656 {
3657 /* We couldn't convert the value. Just assume a value of 0. */
3658 key_pressed = 0;
3659 }
3660
3661 if (((key_pressed == 0) &&
3662 (sbw->scrollBar.orientation == XmHORIZONTAL))
3663 ||
3664 ((key_pressed == 1) &&
3665 (sbw->scrollBar.orientation == XmVERTICAL)))
3666 return;
3667
3668 new_value = sbw->scrollBar.value - sbw->scrollBar.page_increment;
3669
3670 if (new_value < sbw->scrollBar.minimum)
3671 new_value = sbw->scrollBar.minimum;
3672
3673 if (new_value != sbw->scrollBar.value)
3674 {
3675 sbw->scrollBar.value = new_value;
3676 #ifdef FUNKY_INSENSITIVE_VISUAL
3677 if ((sbw->scrollBar.value = new_value)
3678 == sbw->scrollBar.minimum)
3679 {
3680 XSetClipMask(XtDisplay(sbw),
3681 sbw->scrollBar.unavailable_GC, None);
3682 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
3683 sbw->scrollBar.unavailable_GC,
3684 sbw->scrollBar.arrow1_x,
3685 sbw->scrollBar.arrow1_y,
3686 sbw->scrollBar.arrow_width,
3687 sbw->scrollBar.arrow_height);
3688
3689 sbw->scrollBar.flags &= ~ARROW1_AVAILABLE;
3690 }
3691 #endif
3692 if ((sbw->scrollBar.show_arrows) &&
3693 (! (sbw->scrollBar.flags & ARROW2_AVAILABLE)))
3694 {
3695 XClearArea(XtDisplay(sbw), XtWindow(sbw),
3696 sbw->scrollBar.arrow2_x,
3697 sbw->scrollBar.arrow2_y,
3698 sbw->scrollBar.arrow_width,
3699 sbw->scrollBar.arrow_height,
3700 FALSE);
3701
3702 DRAWARROW (sbw, sbw -> primitive.top_shadow_GC,
3703 sbw->primitive.bottom_shadow_GC,
3704 sbw->scrollBar.arrow2_x,
3705 sbw->scrollBar.arrow2_y,
3706 sbw->scrollBar.arrow2_orientation);
3707
3708 sbw->scrollBar.flags |= ARROW2_AVAILABLE;
3709 }
3710
3711 RedrawSliderWindow (sbw);
3712
3713 ScrollCallback (sbw, XmCR_PAGE_DECREMENT,
3714 sbw->scrollBar.value,
3715 event->xbutton.x, event->xbutton.y, event);
3716 }
3717 }
3718
3719
3720
3721
3722 /*********************************************************************
3723 *
3724 * PageDownOrRight
3725 * The down or right key was pressed, increase the value by
3726 * one increment.
3727 *
3728 *********************************************************************/
3729 /*ARGSUSED*/
3730 static void
PageDownOrRight(Widget wid,XEvent * event,String * params,Cardinal * num_params)3731 PageDownOrRight(
3732 Widget wid,
3733 XEvent *event,
3734 String *params,
3735 Cardinal *num_params )
3736 {
3737 XmScrollBarWidget sbw = (XmScrollBarWidget) wid ;
3738 int new_value;
3739 int key_pressed;
3740
3741 if (!num_params || (*num_params != 1) || !params)
3742 {
3743 XmeWarning(wid, MESSAGE14);
3744 return;
3745 }
3746
3747 if (!sbw->scrollBar.editable) return ;
3748
3749 sbw->scrollBar.flags &= ~OPERATION_CANCELLED ;
3750
3751 if (! (sbw->scrollBar.flags & SLIDER_AVAILABLE))
3752 return;
3753
3754 /*
3755 * arg value passed in will either be "down" for the down key or
3756 * "right" for the right arrow key (or for compatibility 0 -> down
3757 * key or 1 -> right key. The key needs to be compared with the
3758 * scrollbar orientation to ensure only the proper directional key
3759 * presses work.
3760 */
3761
3762 if (_XmConvertActionParamToRepTypeId((Widget) sbw,
3763 XmRID_SCROLL_BAR_PAGE_DOWN_OR_RIGHT_ACTION_PARAMS,
3764 params[0], True, &key_pressed) == False)
3765 {
3766 /* We couldn't convert the value. Just assume a value of 0. */
3767 key_pressed = 0;
3768 }
3769
3770 if (((key_pressed == 0) &&
3771 (sbw->scrollBar.orientation == XmHORIZONTAL))
3772 ||
3773 ((key_pressed == 1) &&
3774 (sbw->scrollBar.orientation == XmVERTICAL)))
3775 return;
3776
3777 new_value = sbw->scrollBar.value + sbw->scrollBar.page_increment;
3778
3779 if (new_value > sbw->scrollBar.maximum - sbw->scrollBar.slider_size)
3780 new_value = sbw->scrollBar.maximum - sbw->scrollBar.slider_size;
3781
3782 if (new_value != sbw->scrollBar.value)
3783 {
3784 sbw->scrollBar.value = new_value;
3785 #ifdef FUNKY_INSENSITIVE_VISUAL
3786 if ((sbw->scrollBar.value = new_value)
3787 == (sbw->scrollBar.maximum - sbw->scrollBar.slider_size))
3788 {
3789 XSetClipMask(XtDisplay(sbw),
3790 sbw->scrollBar.unavailable_GC, None);
3791 XFillRectangle(XtDisplay(sbw), XtWindow(sbw),
3792 sbw->scrollBar.unavailable_GC,
3793 sbw->scrollBar.arrow2_x,
3794 sbw->scrollBar.arrow2_y,
3795 sbw->scrollBar.arrow_width,
3796 sbw->scrollBar.arrow_height);
3797
3798 sbw->scrollBar.flags &= ~ARROW2_AVAILABLE;
3799 }
3800 #endif
3801 if ((sbw->scrollBar.show_arrows) &&
3802 (! (sbw->scrollBar.flags & ARROW1_AVAILABLE)))
3803 {
3804 XClearArea(XtDisplay(sbw), XtWindow(sbw),
3805 sbw->scrollBar.arrow1_x,
3806 sbw->scrollBar.arrow1_y,
3807 sbw->scrollBar.arrow_width,
3808 sbw->scrollBar.arrow_height,
3809 FALSE);
3810
3811 DRAWARROW (sbw, sbw -> primitive.top_shadow_GC,
3812 sbw->primitive.bottom_shadow_GC,
3813 sbw->scrollBar.arrow1_x,
3814 sbw->scrollBar.arrow1_y,
3815 sbw->scrollBar.arrow1_orientation);
3816
3817 sbw->scrollBar.flags |= ARROW1_AVAILABLE;
3818 }
3819
3820 RedrawSliderWindow (sbw);
3821
3822 ScrollCallback (sbw, XmCR_PAGE_INCREMENT, sbw->scrollBar.value,
3823 event->xbutton.x, event->xbutton.y, event);
3824 }
3825 }
3826
3827 /*ARGSUSED*/
3828 static void
CancelDrag(Widget wid,XEvent * event,String * params,Cardinal * num_params)3829 CancelDrag(
3830 Widget wid,
3831 XEvent *event,
3832 String *params,
3833 Cardinal *num_params)
3834 {
3835 XmScrollBarWidget sbw = (XmScrollBarWidget) wid;
3836
3837 if (!sbw->scrollBar.editable) return ;
3838
3839 if (sbw->scrollBar.flags & KEYBOARD_GRABBED)
3840 {
3841 short savedX, savedY, j1, j2;
3842
3843 XtUngrabKeyboard(wid, ((XButtonPressedEvent *)event)->time);
3844 sbw->scrollBar.flags &= ~KEYBOARD_GRABBED;
3845
3846 sbw->scrollBar.flags |= OPERATION_CANCELLED;
3847
3848 sbw->scrollBar.sliding_on = False;
3849 sbw->scrollBar.value = sbw->scrollBar.saved_value;
3850 CalcSliderRect(sbw, &savedX, &savedY, &j1, &j2);
3851 MoveSlider(sbw, savedX, savedY);
3852 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER)
3853 RedrawSliderWindow (sbw);
3854 ScrollCallback (sbw, XmCR_VALUE_CHANGED,
3855 sbw->scrollBar.value, savedX, savedY,
3856 (XEvent *) event);
3857
3858 if (sbw->scrollBar.timer != 0)
3859 {
3860 sbw->scrollBar.flags |= END_TIMER;
3861 }
3862
3863 }
3864 else
3865 {
3866 XmParentInputActionRec pp_data ;
3867
3868 pp_data.process_type = XmINPUT_ACTION ;
3869 pp_data.action = XmPARENT_CANCEL ;
3870 pp_data.event = event ;
3871 pp_data.params = params ;
3872 pp_data.num_params = num_params ;
3873
3874 _XmParentProcess( XtParent( wid), (XmParentProcessData) &pp_data) ;
3875 }
3876 }
3877
3878
3879 /*********************************************************************
3880 *
3881 * MoveSlider
3882 * Given x and y positions, move the slider and clear the area
3883 * moved out of.
3884 *
3885 *********************************************************************/
3886 static void
MoveSlider(XmScrollBarWidget sbw,int currentX,int currentY)3887 MoveSlider(
3888 XmScrollBarWidget sbw,
3889 int currentX,
3890 int currentY )
3891 {
3892 int oldX = sbw->scrollBar.slider_x;
3893 int oldY = sbw->scrollBar.slider_y;
3894 int width = sbw->scrollBar.slider_width;
3895 int height = sbw->scrollBar.slider_height;
3896
3897 XSegment seg[2];
3898
3899 if ((currentX == oldX) && (currentY == oldY))
3900 return;
3901
3902 if (sbw->scrollBar.sliding_mode == XmTHERMOMETER) {
3903 if (sbw->scrollBar.orientation == XmHORIZONTAL)
3904 sbw->scrollBar.slider_x = currentX;
3905 else
3906 sbw->scrollBar.slider_y = currentY;
3907 return ;
3908 }
3909
3910 if (sbw->scrollBar.orientation == XmHORIZONTAL)
3911 {
3912 sbw->scrollBar.slider_x = currentX;
3913
3914 seg[0].y1 = seg[0].y2 = oldY + 2;
3915 seg[1].y1 = seg[1].y2 = oldY + height - 3;
3916
3917 if (oldX < currentX)
3918 {
3919 seg[0].x1 = seg[1].x1 = oldX;
3920 seg[0].x2 = seg[1].x2 = oldX + currentX - oldX - 1;
3921 }
3922 else
3923 {
3924 seg[0].x1 = seg[1].x1 = currentX + width;
3925 seg[0].x2 = seg[1].x2 = seg[0].x1 + oldX - currentX - 1;
3926 }
3927
3928
3929 if (sbw->scrollBar.pixmap != 0)
3930 {
3931 CopySliderInWindow(sbw);
3932 XClearArea (XtDisplay((Widget)sbw),
3933 XtWindow((Widget)sbw),
3934 seg[0].x1, oldY,
3935 seg[0].x2 - seg[0].x1 + 1,
3936 height, False);
3937 }
3938 }
3939 else /* sbw->scrollBar.orientation == XmVERTICAL */
3940 {
3941 sbw->scrollBar.slider_y = currentY;
3942
3943 seg[0].x1 = seg[0].x2 = oldX + 2;
3944 seg[1].x1 = seg[1].x2 = oldX + width - 3;
3945
3946 if (oldY < currentY)
3947 {
3948 seg[0].y1 = seg[1].y1 = oldY;
3949 seg[0].y2 = seg[1].y2 = oldY + currentY - oldY - 1;
3950 }
3951 else
3952 {
3953 seg[0].y1 = seg[1].y1 = currentY + height;
3954 seg[0].y2 = seg[1].y2 = seg[0].y1 + oldY - currentY - 1;
3955 }
3956
3957 if (sbw->scrollBar.pixmap != 0)
3958 {
3959 CopySliderInWindow(sbw);
3960 XClearArea (XtDisplay((Widget)sbw),
3961 XtWindow((Widget)sbw),
3962 oldX, seg[0].y1, width,
3963 seg[0].y2 - seg[0].y1 + 1, False);
3964 }
3965 }
3966 }
3967
3968
3969
3970
3971 /************************************************************************
3972 *
3973 * ChangeScrollBarValue
3974 * Change the scrollbar value by the indicated change type. Return
3975 * True if the value changes, False otherwise.
3976 *
3977 ************************************************************************/
3978 static Boolean
ChangeScrollBarValue(XmScrollBarWidget sbw)3979 ChangeScrollBarValue(
3980 XmScrollBarWidget sbw )
3981 {
3982 register unsigned char change_type = sbw->scrollBar.change_type;
3983 register int change_amount = 0;
3984 register Boolean returnFlag = TRUE;
3985 register int old_value = sbw->scrollBar.value;
3986
3987 if (! (sbw->scrollBar.flags & SLIDER_AVAILABLE))
3988 return(FALSE);
3989 /* Get the amount to change the scroll bar value based on */
3990 /* the type of change occuring. */
3991
3992 if (change_type == XmCR_INCREMENT)
3993 change_amount = sbw->scrollBar.increment;
3994 else if (change_type == XmCR_PAGE_INCREMENT)
3995 change_amount = sbw->scrollBar.page_increment;
3996 else if (change_type == XmCR_DECREMENT)
3997 change_amount = -sbw->scrollBar.increment;
3998 else if (change_type == XmCR_PAGE_DECREMENT)
3999 change_amount = -sbw->scrollBar.page_increment;
4000
4001 /* Change the value */
4002 sbw->scrollBar.value += change_amount;
4003
4004 /* Truncate and set flags as appropriate */
4005 if (sbw->scrollBar.value >= (sbw->scrollBar.maximum
4006 - sbw->scrollBar.slider_size))
4007 sbw->scrollBar.value = sbw->scrollBar.maximum
4008 - sbw->scrollBar.slider_size;
4009
4010 if (sbw->scrollBar.value <= sbw->scrollBar.minimum)
4011 sbw->scrollBar.value = sbw->scrollBar.minimum;
4012
4013 if ((returnFlag = (sbw->scrollBar.value != old_value)) != False) {
4014 RedrawSliderWindow (sbw);
4015 }
4016
4017
4018 return (returnFlag);
4019 }
4020
4021
4022
4023
4024 /*********************************************************************
4025 *
4026 * TimerEvent
4027 * This is an event processing function which handles timer
4028 * event evoked because of arrow selection.
4029 *
4030 *********************************************************************/
4031 /*ARGSUSED*/
4032 static void
TimerEvent(XtPointer closure,XtIntervalId * id)4033 TimerEvent(
4034 XtPointer closure,
4035 XtIntervalId *id ) /* unused */
4036 {
4037 XmScrollBarWidget sbw = (XmScrollBarWidget) closure ;
4038 Boolean flag;
4039
4040 sbw->scrollBar.timer = 0;
4041
4042 if (sbw->scrollBar.flags & END_TIMER)
4043 {
4044 sbw->scrollBar.flags &= ~END_TIMER;
4045 return;
4046 }
4047
4048 if (sbw->scrollBar.flags & FIRST_SCROLL_FLAG)
4049 {
4050 XSync (XtDisplay (sbw), False);
4051
4052 sbw->scrollBar.flags &= ~FIRST_SCROLL_FLAG;
4053
4054 sbw->scrollBar.timer =
4055 XtAppAddTimeOut (XtWidgetToApplicationContext((Widget) sbw),
4056 (unsigned long) sbw->scrollBar.repeat_delay,
4057 TimerEvent, (XtPointer) sbw);
4058 return;
4059 }
4060
4061
4062 /* Change the scrollbar slider value */
4063
4064 flag = ChangeScrollBarValue (sbw);
4065
4066 /* If the orgin was changed invoke the application supplied */
4067 /* slider moved callbacks */
4068
4069 if (flag)
4070 ScrollCallback (sbw, sbw->scrollBar.change_type,
4071 sbw->scrollBar.value, 0, 0, NULL);
4072
4073 /*
4074 * If the callback does alot of processing, and XSync is needed
4075 * to flush the output and input buffers. If this is not done,
4076 * the entry back to MainLoop will cause the flush. The server
4077 * will then perform it work which may take longer than the timer
4078 * interval which will cause the scrollbar to be stuck in a loop.
4079 */
4080
4081 XSync (XtDisplay (sbw), False);
4082
4083 /* Add the repeat timer and check that the scrollbar hasn't been set
4084 insensitive by some callbacks */
4085
4086 if (flag)
4087 {
4088 sbw->scrollBar.timer =
4089 XtAppAddTimeOut (XtWidgetToApplicationContext((Widget) sbw),
4090 (unsigned long) sbw->scrollBar.repeat_delay,
4091 TimerEvent, (XtPointer) sbw);
4092 }
4093 }
4094
4095
4096
4097
4098 /************************************************************************
4099 *
4100 * ScrollCallback
4101 * This routine services the widget's callbacks. It calls the
4102 * specific callback if it is not empty. If it is empty then the
4103 * main callback is called.
4104 *
4105 ************************************************************************/
4106 static void
ScrollCallback(XmScrollBarWidget sbw,int reason,int value,int xpixel,int ypixel,XEvent * event)4107 ScrollCallback(
4108 XmScrollBarWidget sbw,
4109 int reason,
4110 int value,
4111 int xpixel,
4112 int ypixel,
4113 XEvent *event )
4114 {
4115 XmScrollBarCallbackStruct call_value;
4116
4117 call_value.reason = reason;
4118 call_value.event = event;
4119
4120 if (PROCESS_DIR_INVERSED(sbw)) {
4121 switch (reason) {
4122 case XmCR_INCREMENT:
4123 call_value.reason = reason = XmCR_DECREMENT;
4124 break;
4125 case XmCR_DECREMENT:
4126 call_value.reason = reason = XmCR_INCREMENT;
4127 break;
4128 case XmCR_PAGE_INCREMENT:
4129 call_value.reason = reason = XmCR_PAGE_DECREMENT;
4130 break;
4131 case XmCR_PAGE_DECREMENT:
4132 call_value.reason = reason = XmCR_PAGE_INCREMENT;
4133 break;
4134 case XmCR_TO_TOP:
4135 call_value.reason = reason = XmCR_TO_BOTTOM;
4136 break;
4137 case XmCR_TO_BOTTOM:
4138 call_value.reason = reason = XmCR_TO_TOP;
4139 break;
4140 }
4141 call_value.value = sbw->scrollBar.maximum
4142 + sbw->scrollBar.minimum - value - sbw->scrollBar.slider_size;
4143 }
4144 else
4145 call_value.value = value;
4146
4147
4148 if (sbw->scrollBar.orientation == XmHORIZONTAL)
4149 call_value.pixel = xpixel;
4150 else
4151 call_value.pixel = ypixel;
4152
4153 switch (reason) {
4154
4155 case XmCR_VALUE_CHANGED:
4156 XtCallCallbackList ((Widget) sbw, sbw->scrollBar.value_changed_callback,
4157 &call_value);
4158 break;
4159
4160 case XmCR_INCREMENT:
4161 if (sbw->scrollBar.increment_callback)
4162 XtCallCallbackList ((Widget) sbw,
4163 sbw->scrollBar.increment_callback, &call_value);
4164 else
4165 {
4166 call_value.reason = XmCR_VALUE_CHANGED;
4167 XtCallCallbackList ((Widget) sbw,
4168 sbw->scrollBar.value_changed_callback, &call_value);
4169 }
4170 break;
4171
4172 case XmCR_DECREMENT:
4173 if (sbw->scrollBar.decrement_callback)
4174 XtCallCallbackList ((Widget) sbw,
4175 sbw->scrollBar.decrement_callback, &call_value);
4176 else
4177 {
4178 call_value.reason = XmCR_VALUE_CHANGED;
4179 XtCallCallbackList ((Widget) sbw,
4180 sbw->scrollBar.value_changed_callback, &call_value);
4181 }
4182 break;
4183
4184 case XmCR_PAGE_INCREMENT:
4185 if (sbw->scrollBar.page_increment_callback)
4186 XtCallCallbackList ((Widget) sbw,
4187 sbw->scrollBar.page_increment_callback, &call_value);
4188 else
4189 {
4190 call_value.reason = XmCR_VALUE_CHANGED;
4191 XtCallCallbackList ((Widget) sbw,
4192 sbw->scrollBar.value_changed_callback, &call_value);
4193 }
4194 break;
4195
4196 case XmCR_PAGE_DECREMENT:
4197 if (sbw->scrollBar.page_decrement_callback)
4198 XtCallCallbackList ((Widget) sbw,
4199 sbw->scrollBar.page_decrement_callback, &call_value);
4200 else
4201 {
4202 call_value.reason = XmCR_VALUE_CHANGED;
4203 XtCallCallbackList ((Widget) sbw,
4204 sbw->scrollBar.value_changed_callback, &call_value);
4205 }
4206 break;
4207
4208 case XmCR_TO_TOP:
4209 if (sbw->scrollBar.to_top_callback)
4210 XtCallCallbackList ((Widget) sbw,
4211 sbw->scrollBar.to_top_callback, &call_value);
4212 else
4213 {
4214 call_value.reason = XmCR_VALUE_CHANGED;
4215 XtCallCallbackList ((Widget) sbw,
4216 sbw->scrollBar.value_changed_callback, &call_value);
4217 }
4218 break;
4219
4220 case XmCR_TO_BOTTOM:
4221 if (sbw->scrollBar.to_bottom_callback)
4222 XtCallCallbackList ((Widget) sbw,
4223 sbw->scrollBar.to_bottom_callback, &call_value);
4224 else
4225 {
4226 call_value.reason = XmCR_VALUE_CHANGED;
4227 XtCallCallbackList ((Widget) sbw,
4228 sbw->scrollBar.value_changed_callback, &call_value);
4229 }
4230 break;
4231
4232 case XmCR_DRAG:
4233 if (sbw->scrollBar.drag_callback)
4234 XtCallCallbackList ((Widget) sbw,
4235 sbw->scrollBar.drag_callback, &call_value);
4236 break;
4237 }
4238 }
4239
4240
4241
4242
4243 /************************************************************************
4244 *
4245 * NavigChangeMoveCB
4246 * add or remove the callback list to be called on any move.
4247 * Since valueChangedCallback is not called on increment (& co)
4248 * if an increment callback is present, we have to set them all.
4249 *
4250 ************************************************************************/
4251 static void
NavigChangeMoveCB(Widget nav,XtCallbackProc moveCB,XtPointer closure,Boolean setunset)4252 NavigChangeMoveCB(
4253 Widget nav,
4254 XtCallbackProc moveCB,
4255 XtPointer closure,
4256 Boolean setunset)
4257 {
4258 if (setunset) {
4259 XtAddCallback (nav, XmNvalueChangedCallback, moveCB, closure);
4260 XtAddCallback (nav, XmNincrementCallback, moveCB, closure);
4261 XtAddCallback (nav, XmNdecrementCallback, moveCB, closure);
4262 XtAddCallback (nav, XmNpageIncrementCallback, moveCB, closure);
4263 XtAddCallback (nav, XmNpageDecrementCallback, moveCB, closure);
4264 XtAddCallback (nav, XmNtoTopCallback, moveCB, closure);
4265 XtAddCallback (nav, XmNtoBottomCallback, moveCB, closure);
4266 XtAddCallback (nav, XmNdragCallback, moveCB, closure);
4267 } else {
4268 XtRemoveCallback (nav, XmNvalueChangedCallback, moveCB, closure);
4269 XtRemoveCallback (nav, XmNincrementCallback, moveCB, closure);
4270 XtRemoveCallback (nav, XmNdecrementCallback, moveCB, closure);
4271 XtRemoveCallback (nav, XmNpageIncrementCallback, moveCB, closure);
4272 XtRemoveCallback (nav, XmNpageDecrementCallback, moveCB, closure);
4273 XtRemoveCallback (nav, XmNtoTopCallback, moveCB, closure);
4274 XtRemoveCallback (nav, XmNtoBottomCallback, moveCB, closure);
4275 XtRemoveCallback (nav, XmNdragCallback, moveCB, closure);
4276 }
4277 }
4278
4279
4280
4281
4282
4283 /************************************************************************
4284 *
4285 * NavigSetValue
4286 * change the value and possibly call the callbacks
4287 *
4288 ************************************************************************/
4289 static void
NavigSetValue(Widget nav,XmNavigatorData nav_data,Boolean notify)4290 NavigSetValue(
4291 Widget nav,
4292 XmNavigatorData nav_data,
4293 Boolean notify)
4294 {
4295 XmScrollBarWidget sbw = (XmScrollBarWidget) nav;
4296 int save_value;
4297 Arg arglist[6];
4298 Cardinal n;
4299
4300 /* register which dimension this scrollbar is to operate */
4301 if (nav_data->valueMask & NavDimMask) {
4302 sbw->scrollBar.dimMask = nav_data->dimMask ;
4303 }
4304
4305 /* scrollbar is a one dimensional navigator, it expects
4306 only one dimension to be set, the one that has been registered
4307 for using the NavDimMask (as treated above) */
4308
4309 if (!(sbw->scrollBar.dimMask & nav_data->dimMask)) return ;
4310
4311 /* we need to fetch either the x or y values out of the
4312 passed nav_data record, depending on the dimmask.
4313 scrollbar is only interested in one value */
4314
4315
4316 save_value = sbw->scrollBar.value;
4317
4318 n = 0;
4319 if (nav_data->valueMask & NavValue) {
4320 if ((PROCESS_DIR_INVERSED(sbw) ?
4321 INVERSED_VALUE(sbw) : sbw->scrollBar.value) !=
4322 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->value)) {
4323 XtSetArg (arglist[n], XmNvalue,
4324 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->value));n++;
4325 }
4326 }
4327
4328
4329 if ((nav_data->valueMask & NavMinimum) &&
4330 (sbw->scrollBar.minimum !=
4331 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->minimum))) {
4332 XtSetArg (arglist[n], XmNminimum,
4333 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->minimum));n++;
4334 }
4335
4336 if ((nav_data->valueMask & NavMaximum) &&
4337 (sbw->scrollBar.maximum !=
4338 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->maximum))) {
4339 XtSetArg (arglist[n], XmNmaximum,
4340 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->maximum));n++;
4341 }
4342
4343 if (sbw->scrollBar.sliding_mode != XmTHERMOMETER) {
4344 if ((nav_data->valueMask & NavSliderSize) &&
4345 (sbw->scrollBar.slider_size !=
4346 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->slider_size)) &&
4347 (ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->slider_size) != 0)) {
4348 XtSetArg (arglist[n], XmNsliderSize,
4349 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->slider_size));
4350 n++;
4351 }
4352 }
4353
4354 if ((nav_data->valueMask & NavIncrement) &&
4355 (sbw->scrollBar.increment !=
4356 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->increment)) &&
4357 (ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->increment) != 0)) {
4358 XtSetArg (arglist[n], XmNincrement,
4359 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->increment)); n++;
4360 }
4361
4362 if ((nav_data->valueMask & NavPageIncrement) &&
4363 (sbw->scrollBar.page_increment !=
4364 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->page_increment)) &&
4365 (ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->page_increment) != 0)) {
4366 XtSetArg (arglist[n], XmNpageIncrement,
4367 ACCESS_DIM(sbw->scrollBar.dimMask, nav_data->page_increment));
4368 n++;
4369 }
4370
4371 if (n) XtSetValues (nav, arglist, n);
4372
4373 if (notify && sbw->scrollBar.value != save_value)
4374 ScrollCallback (sbw, XmCR_VALUE_CHANGED,
4375 sbw->scrollBar.value, 0, 0, NULL);
4376
4377 }
4378
4379
4380 /************************************************************************
4381 *
4382 * NavigGetValue
4383 * reports the all the data for this navigator scrollbar
4384 * nav_data allocated by the caller
4385 ************************************************************************/
4386 static void
NavigGetValue(Widget nav,XmNavigatorData nav_data)4387 NavigGetValue(
4388 Widget nav,
4389 XmNavigatorData nav_data)
4390 {
4391 XmScrollBarWidget sbw = (XmScrollBarWidget) nav;
4392
4393 nav_data->dimMask = sbw->scrollBar.dimMask;
4394
4395 if (nav_data->valueMask & NavValue) {
4396 int value ;
4397
4398 if (PROCESS_DIR_INVERSED(sbw)) {
4399 value = INVERSED_VALUE(sbw);
4400 } else
4401 value = sbw->scrollBar.value;
4402
4403 ASSIGN_DIM(nav_data->dimMask, nav_data->value, value) ;
4404 }
4405
4406 if (nav_data->valueMask & NavMinimum)
4407 ASSIGN_DIM(nav_data->dimMask, nav_data->minimum,
4408 sbw->scrollBar.minimum) ;
4409
4410
4411 if (nav_data->valueMask & NavMaximum)
4412 ASSIGN_DIM(nav_data->dimMask, nav_data->maximum,
4413 sbw->scrollBar.maximum) ;
4414
4415
4416 if (nav_data->valueMask & NavSliderSize)
4417 ASSIGN_DIM(nav_data->dimMask, nav_data->slider_size,
4418 sbw->scrollBar.slider_size) ;
4419
4420 if (nav_data->valueMask & NavIncrement)
4421 ASSIGN_DIM(nav_data->dimMask, nav_data->increment,
4422 sbw->scrollBar.increment) ;
4423
4424 if (nav_data->valueMask & NavPageIncrement)
4425 ASSIGN_DIM(nav_data->dimMask, nav_data->page_increment,
4426 sbw->scrollBar.page_increment) ;
4427
4428 }
4429
4430
4431
4432
4433 /************************************************************************
4434 *
4435 * Application Accessible External Functions
4436 *
4437 ************************************************************************/
4438
4439
4440 /************************************************************************
4441 *
4442 * XmCreateScrollBar
4443 * Create an instance of a scrollbar and return the widget id.
4444 *
4445 ************************************************************************/
4446 Widget
XmCreateScrollBar(Widget parent,char * name,ArgList arglist,Cardinal argcount)4447 XmCreateScrollBar(
4448 Widget parent,
4449 char *name,
4450 ArgList arglist,
4451 Cardinal argcount )
4452 {
4453 return (XtCreateWidget (name, xmScrollBarWidgetClass,
4454 parent, arglist, argcount));
4455 }
4456
4457 Widget
XmVaCreateScrollBar(Widget parent,char * name,...)4458 XmVaCreateScrollBar(
4459 Widget parent,
4460 char *name,
4461 ...)
4462 {
4463 register Widget w;
4464 va_list var;
4465 int count;
4466
4467 Va_start(var,name);
4468 count = XmeCountVaListSimple(var);
4469 va_end(var);
4470
4471
4472 Va_start(var, name);
4473 w = XmeVLCreateWidget(name,
4474 xmScrollBarWidgetClass,
4475 parent, False,
4476 var, count);
4477 va_end(var);
4478 return w;
4479 }
4480
4481 Widget
XmVaCreateManagedScrollBar(Widget parent,char * name,...)4482 XmVaCreateManagedScrollBar(
4483 Widget parent,
4484 char *name,
4485 ...)
4486 {
4487 Widget w = NULL;
4488 va_list var;
4489 int count;
4490
4491 Va_start(var, name);
4492 count = XmeCountVaListSimple(var);
4493 va_end(var);
4494
4495 Va_start(var, name);
4496 w = XmeVLCreateWidget(name,
4497 xmScrollBarWidgetClass,
4498 parent, True,
4499 var, count);
4500 va_end(var);
4501 return w;
4502 }
4503
4504 /************************************************************************
4505 *
4506 * XmScrollBarGetValues
4507 * Return some scrollbar values.
4508 *
4509 ************************************************************************/
4510 void
XmScrollBarGetValues(Widget w,int * value,int * slider_size,int * increment,int * page_increment)4511 XmScrollBarGetValues(
4512 Widget w,
4513 int *value,
4514 int *slider_size,
4515 int *increment,
4516 int *page_increment )
4517 {
4518 XmScrollBarWidget sbw = (XmScrollBarWidget) w;
4519 XtAppContext app = XtWidgetToApplicationContext(w);
4520
4521 _XmAppLock(app);
4522
4523 if (PROCESS_DIR_INVERSED(sbw)) {
4524 if (value) *value = INVERSED_VALUE(sbw);
4525 } else
4526 if (value) *value = sbw->scrollBar.value;
4527
4528 if (slider_size) *slider_size = sbw->scrollBar.slider_size;
4529 if (increment) *increment = sbw->scrollBar.increment;
4530 if (page_increment) *page_increment = sbw->scrollBar.page_increment;
4531 _XmAppUnlock(app);
4532 }
4533
4534
4535
4536
4537 /************************************************************************
4538 *
4539 * XmScrollBarSetValues
4540 * Set some scrollbar values.
4541 *
4542 ************************************************************************/
4543 void
XmScrollBarSetValues(Widget w,int value,int slider_size,int increment,int page_increment,int notify)4544 XmScrollBarSetValues(
4545 Widget w,
4546 int value,
4547 int slider_size,
4548 int increment,
4549 int page_increment,
4550 #if NeedWidePrototypes
4551 int notify )
4552 #else
4553 Boolean notify )
4554 #endif /* NeedWidePrototypes */
4555 {
4556 XmScrollBarWidget sbw = (XmScrollBarWidget) w;
4557 int save_value;
4558 Arg arglist[4];
4559 Cardinal n;
4560 XtAppContext app = XtWidgetToApplicationContext(w);
4561
4562 _XmAppLock(app);
4563
4564
4565 save_value = sbw->scrollBar.value;
4566
4567 n = 0;
4568 XtSetArg (arglist[n], XmNvalue, value); n++;
4569
4570 if (sbw->scrollBar.sliding_mode != XmTHERMOMETER) {
4571 if (slider_size != 0) {
4572 XtSetArg (arglist[n], XmNsliderSize, slider_size); n++;
4573 }
4574 }
4575
4576 if (increment != 0) {
4577 XtSetArg (arglist[n], XmNincrement, increment); n++;
4578 }
4579
4580 if (page_increment != 0) {
4581 XtSetArg (arglist[n], XmNpageIncrement, page_increment); n++;
4582 }
4583
4584 XtSetValues ((Widget) sbw, arglist, n);
4585
4586 if (notify && sbw->scrollBar.value != save_value)
4587 ScrollCallback (sbw, XmCR_VALUE_CHANGED,
4588 sbw->scrollBar.value, 0, 0, NULL);
4589 _XmAppUnlock(app);
4590 }
4591
4592