|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)ScrollBar.c 1.8 2/25/87";
3: #endif lint
4: /*
5: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
6: *
7: * All Rights Reserved
8: *
9: * Permission to use, copy, modify, and distribute this software and its
10: * documentation for any purpose and without fee is hereby granted,
11: * provided that the above copyright notice appear in all copies and that
12: * both that copyright notice and this permission notice appear in
13: * supporting documentation, and that the name of Digital Equipment
14: * Corporation not be used in advertising or publicity pertaining to
15: * distribution of the software without specific, written prior permission.
16: *
17: *
18: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
19: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
21: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24: * SOFTWARE.
25: */
26:
27:
28: /* ScrollBar.c */
29: /* created by weissman, Mon Jul 7 13:20:03 1986 */
30:
31: #include "X.h"
32: #include "Xlib.h"
33: #include "Intrinsic.h"
34: #include "Scroll.h"
35: #include "Atoms.h"
36: #include "cursorfont.h"
37:
38: /* Private definitions. */
39:
40: typedef void (*NotifyProc)();
41:
42: typedef struct _WidgetDataRec
43: {
44: Display *dpy; /* Display connection */
45: Window scrollbarWindow;/* Window containing the scrollbar */
46: XtOrientation orientation; /* Horizontal or vertical? */
47: int *value; /* client data to pass in call-back procs */
48: Position x, y; /* Location of the scroll bar */
49: Dimension width, height, borderwidth;
50: /* Dimensions of the scroll bar */
51: NotifyProc ScrollProc; /* Call to scroll content */
52: NotifyProc ThumbProc; /* Call if user thumbs scrollbar */
53: float top; /* What percent is above the win's top */
54: float shown; /* What percent is shown in the win */
55: int topLoc; /* Pixel that corresponds to top */
56: int shownLength; /* Num pixels corresponding to shown */
57: int foreground; /* thumb color */
58: Pixmap customthumb; /* thumb pixmap */
59: Pixel background; /* window background color. */
60: Pixel border; /* What to use for painting the border. */
61: XtEventsPtr eventTable; /* Table for Translation Manager */
62: caddr_t state; /* state for Translation Manager */
63: int eventlevels; /* recursion levels of event handling */
64: Cursor NormalCursor; /* The normal cursor for scrollbar window */
65: Cursor ButtonCursors[4];/* The cursors to use with each button */
66: short curbutton; /* Which button is currently held down. */
67: GC gc; /*this will go away if thumb becomes a window*/
68: } WidgetDataRec, *WidgetData;
69:
70: static int dummyvalue;
71: extern void Dummy ();
72: static WidgetDataRec globaldata;
73: static WidgetDataRec globalinit = {
74: NULL, /* Display dpy; */
75: NULL, /* scrollBar window */
76: XtorientVertical,/*orientation */
77: &dummyvalue, /* client data */
78: 0,0, /* x,y */
79: 10,20, /* width,height */
80: 1, /* borderwidth */
81: Dummy, /* void (*proc)(); */
82: Dummy, /* void (*proc)(); */
83: 0.0, /* fraction above top */
84: 0.0, /* shown fraction */
85: NULL, /* top percent pixel */
86: NULL, /* shown length */
87: NULL, /* foreground */
88: NULL, /* customthumb */
89: 0, /* background pixel*/
90: 0, /* border pixel */
91: NULL, /* table for TM */
92: NULL, /* state for TM */
93: NULL, /* eventlevels */
94: NULL, /* normal cursor */
95: {NULL,NULL,NULL,NULL}, /*ButtonCursors */
96: NULL, /*curbotton */
97: NULL /*gc*/
98: };
99:
100:
101: static Resource resources[] = {
102: {XtNwindow, XtCWindow, XrmRWindow, sizeof(Window),
103: (caddr_t)&globaldata.scrollbarWindow, NULL},
104: {XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation),
105: (caddr_t)&globaldata.orientation, NULL},
106: {XtNvalue, XtCValue, XrmRPointer, sizeof(caddr_t),
107: (caddr_t)&globaldata.value,(caddr_t)NULL},
108: {XtNx, XtCX, XrmRInt,
109: sizeof(int),(caddr_t)&globaldata.x, (caddr_t)NULL },
110: {XtNy, XtCY, XrmRInt,
111: sizeof(int),(caddr_t)&globaldata.y, (caddr_t)NULL },
112: {XtNwidth, XtCWidth, XrmRInt, sizeof(int),
113: (caddr_t)&globaldata.width, NULL},
114: {XtNheight, XtCHeight, XrmRInt, sizeof(int),
115: (caddr_t)&globaldata.height, NULL},
116: {XtNborderWidth, XtCBorderWidth, XrmRInt, sizeof(int),
117: (caddr_t)&globaldata.borderwidth, NULL},
118: {XtNborder, XtCColor, XrmRPixel, sizeof(int),
119: (caddr_t)&globaldata.border, (caddr_t)&XtDefaultFGPixel},
120: {XtNscrollUpDownProc, XtCFunction, XtRFunction,
121: sizeof(globaldata.ScrollProc),
122: (caddr_t)&globaldata.ScrollProc, NULL},
123: {XtNthumbProc, XtCFunction, XtRFunction, sizeof(globaldata.ThumbProc),
124: (caddr_t)&globaldata.ThumbProc, NULL},
125: {XtNforeground, XtCColor, XrmRPixel, sizeof(int),
126: (caddr_t)&globaldata.foreground, (caddr_t)&XtDefaultFGPixel},
127: {XtNcustomthumb, XtCPixmap, XrmRPixmap, sizeof(Pixmap),
128: (caddr_t)&globaldata.customthumb,NULL},
129: {XtNbackground, XtCColor, XrmRPixel, sizeof(int),
130: (caddr_t)&globaldata.background, (caddr_t)&XtDefaultBGPixel},
131: {XtNtop, XtCFraction, XrmRFloat, sizeof(float),
132: (caddr_t)&globaldata.top, NULL},
133: {XtNshown, XtCFraction, XrmRFloat, sizeof(float),
134: (caddr_t)&globaldata.shown, NULL},
135: {XtNeventBindings,XtCEventBindings,XtREventBindings,
136: sizeof(caddr_t), (caddr_t)&globaldata.eventTable, NULL}
137: };
138:
139: static XContext widgetContext;
140:
141:
142:
143: #define MINBARHEIGHT 7 /* How many pixels of scrollbar to always show */
144: #define NoButton -1
145: #define PICKLENGTH(data,x,y) \
146: ((data->orientation == XtorientHorizontal) ? x : y)
147: #define PICKTHICKNESS(data,x,y) \
148: ((data->orientation == XtorientHorizontal) ? y : x)
149: #define MIN(x,y) ((x) < (y) ? (x) : (y))
150: #define MAX(x,y) ((x) > (y) ? (x) : (y))
151:
152:
153: /* Orientation enumeration constants */
154:
155: static XrmQuark XtQEhorizontal;
156: static XrmQuark XtQEvertical;
157:
158: /*ARGSUSED*/
159: #define done(address, type) \
160: { (*toVal).size = sizeof(type); (*toVal).addr = (caddr_t) address; }
161:
162: extern void _XLowerCase();
163:
164: static void CvtStringToOrientation(fromVal, toVal)
165: XrmValue fromVal;
166: XrmValue *toVal;
167: {
168: static XtOrientation orient;
169: XrmQuark q;
170: char lowerName[1000];
171:
172: /* ||| where to put LowerCase */
173: _XLowerCase((char *) fromVal.addr, lowerName);
174: q = XrmAtomToQuark(lowerName);
175: if (q == XtQEhorizontal) {
176: orient = XtorientHorizontal;
177: done(&orient, XtOrientation);
178: return;
179: }
180: if (q == XtQEvertical) {
181: orient = XtorientVertical;
182: done(&orient, XtOrientation);
183: return;
184: }
185: };
186:
187:
188: static char *defaultEventBindings[] = {
189: "<ButtonPress>left: startup\n",
190: "<ButtonPress>middle: startscroll\n",
191: "<ButtonPress>right: startdown\n",
192: "<ButtonRelease>left: doup\n",
193: "<ButtonRelease>middle: doscroll\n",
194: "<ButtonRelease>right: dodown\n",
195: "<MotionNotify>middle: movebar\n", /*bug in TM forces button spec here */
196: NULL
197: };
198:
199: static void Ignore()
200: {
201: (void)printf("you are being ignored\n");
202: }
203:
204: static Boolean initialized = FALSE;
205: static void ScrollBarInitialize ()
206: {
207: widgetContext = XUniqueContext();
208: globalinit.eventTable = XtParseEventBindings(defaultEventBindings);
209: XtQEhorizontal = XrmAtomToQuark(XtEhorizontal);
210: XtQEvertical = XrmAtomToQuark(XtEvertical);
211: XrmRegisterTypeConverter(XrmRString, XtROrientation, CvtStringToOrientation);
212: initialized = TRUE;
213: }
214:
215: /*
216: * Given a display and window, get the widget data.
217: */
218:
219: static WidgetData DataFromWindow(dpy, window)
220: Display *dpy;
221: Window window;
222: {
223: WidgetData result;
224: if (XFindContext(dpy, window, widgetContext, (caddr_t *)&result))
225: return NULL;
226: return result;
227: }
228:
229: /* ARGSUSED */
230: static void Dummy(p) /* default call back proc */
231: caddr_t p;
232: {
233: (void) printf("dummy call back for ScrollBar\n");
234: }
235:
236: /*
237: * Make sure the first number is within the range specified by the other
238: * two numbers.
239: */
240:
241: static int InRange(num, small, big)
242: int num, small, big;
243: {
244: return (num < small) ? small : ((num > big) ? big : num);
245: }
246:
247: /*
248: * Same as above, but for floating numbers.
249: */
250:
251: static float FloatInRange(num, small, big)
252: float num, small, big;
253: {
254: return (num < small) ? small : ((num > big) ? big : num);
255: }
256:
257: /* Given the scrollbar window, return the SbarInfo record for it. */
258: static WidgetData SbarInfoFromSbarWindow(dpy, window)
259: Display *dpy;
260: Window window; /* Scrollbar window */
261: {
262: WidgetData result;
263: if (XFindContext(dpy, window, widgetContext, (caddr_t *)&result))
264: return NULL;
265: return result;
266: }
267:
268:
269:
270:
271: /* Given a WidgetData record and a point in the scrollbarWindow, determine */
272: /* what percentage that point indicates. */
273:
274:
275:
276:
277:
278: /* Fill the area specified by top and bottom with the given pattern. */
279: float FractionLoc(data,x,y)
280: WidgetData data;
281: int x,y;
282: {
283: float result;
284: result = PICKLENGTH(data, (float) x/data->width, (float) y/data->height);
285: return FloatInRange(result, 0.0, 1.0);
286: }
287:
288:
289: static FillArea(data, top, bottom, thumb)
290: WidgetData data;
291: Position top, bottom;
292: int thumb;
293: {
294: Dimension length = bottom-top;
295: switch(thumb) {
296: /* Fill the new Thumb location */
297: case 1:
298: if (data->orientation == XtorientHorizontal)
299: XFillRectangle(data->dpy, data->scrollbarWindow, data->gc,
300: top, 1, length, data->height-2);
301:
302: else XFillRectangle(data->dpy, data->scrollbarWindow, data->gc,
303: 1, top, data->width-2, length);
304:
305: break;
306: /* Clear the old Thumb location */
307: case 0:
308: if (data->orientation == XtorientHorizontal)
309: XClearArea(data->dpy, data->scrollbarWindow, top, 1,
310: length, data->height-2, FALSE);
311:
312: else XClearArea(data->dpy, data->scrollbarWindow, 1, top,
313: data->width-2, length, FALSE);
314:
315: }
316: }
317:
318:
319: /* Paint the thumb in the area specified by data->top and
320: data->shown. The old area is erased. The painting and
321: erasing is done cleverly so that no flickering will occur. */
322:
323: static PaintThumb(data)
324: WidgetData data;
325: {
326: int length, oldtop, oldbot, newtop, newbot;
327: length = PICKLENGTH(data, data->width, data->height);
328: oldtop = data->topLoc;
329: oldbot = oldtop + data->shownLength;
330: newtop = length * data->top;
331: newbot = newtop + length * (data->shown);
332: if (newbot < newtop + MINBARHEIGHT) newbot = newtop + MINBARHEIGHT;
333: if (newtop < oldtop)
334: FillArea(data, newtop, MIN(newbot, oldtop),1);
335: if (newtop > oldtop)
336: FillArea(data, oldtop, MIN(newtop, oldbot), 0);
337: if (newbot < oldbot)
338: FillArea(data, MAX(newbot, oldtop), oldbot,0);
339: if (newbot > oldbot)
340: FillArea(data, MAX(newtop, oldbot), newbot, 1);
341: data->topLoc = newtop;
342: data->shownLength = newbot - newtop;
343: }
344:
345:
346: /* Move the thumb to the value corresponding to the given point. */
347:
348: static MoveThumb(data,x,y)
349: WidgetData data;
350: int x,y;
351: {
352: data->top = FractionLoc(data, x, y);
353: PaintThumb(data);
354: }
355:
356:
357:
358:
359:
360: StartScroll(data,button)
361: WidgetData data;
362: unsigned int button;
363: {
364: if (data->curbutton != 0) return;
365: data->curbutton = button;
366:
367: XDefineCursor(data->dpy, data->scrollbarWindow,
368: data->ButtonCursors[data->curbutton]);
369: XFlush(data->dpy);
370:
371: }
372:
373:
374:
375: ScrollElevator(data,button,x,y)
376: WidgetData data;
377: Position x,y;
378: unsigned int button;
379: {
380: if (data->curbutton != 0) return;
381: data->curbutton = button;
382: XDefineCursor(data->dpy, data->scrollbarWindow,
383: data->ButtonCursors[data->curbutton]);
384: XFlush(data->dpy);
385:
386: MoveThumb(data,x,y);
387: }
388:
389:
390:
391: /* The user has thumbed to the location he wants; tell the other module where
392: the thumb now is. */
393:
394: static FinalThumbLoc(data,x,y)
395: WidgetData data;
396: Position x,y;
397: {
398: MoveThumb(data, x, y);
399: (*(data->ThumbProc)) (data->dpy, data->scrollbarWindow,
400: data->value,
401: data->top);
402: }
403:
404:
405: static NotifyScroll(data,x,y)
406: WidgetData data;
407: Position x,y;
408: {
409: if (data->curbutton == 0) return;
410: XDefineCursor(data->dpy,data->scrollbarWindow, data->NormalCursor);
411: XFlush(data->dpy);
412: (*(data->ScrollProc)) (data->dpy, data->scrollbarWindow,
413: data->value,
414: InRange(PICKLENGTH(data, x,y),
415: 0,
416: (int)PICKLENGTH(data, data->width, data->height)));
417: data->curbutton = AnyButton; /*means NoButton */
418:
419:
420: }
421:
422: static NotifyScroll1(data,x,y)
423: WidgetData data;
424: Position x,y;
425: {
426: if (data->curbutton == 0) return;
427: XDefineCursor(data->dpy,data->scrollbarWindow, data->NormalCursor);
428: XFlush(data->dpy);
429: (*(data->ScrollProc)) (data->dpy, data->scrollbarWindow,
430: data->value,
431: -InRange(PICKLENGTH(data, x,y),
432: 0,
433: (int)PICKLENGTH(data, data->width, data->height)));
434: data->curbutton = AnyButton; /*means NoButton */
435:
436:
437: }
438: static NotifyThumb(data,x,y)
439: WidgetData data;
440: Position x,y;
441: {
442: if (data->curbutton == 0) return;
443: XDefineCursor(data->dpy,data->scrollbarWindow, data->NormalCursor);
444: XFlush(data->dpy);
445:
446: FinalThumbLoc(data, x, y);
447: data->curbutton = AnyButton; /*means NoButton */
448:
449: }
450:
451:
452:
453:
454: static MoveElevator(data, x,y)
455: WidgetData data;
456: Position x,y;
457: {
458: if (data->curbutton == 0) return;
459: MoveThumb(data, x, y);
460: }
461:
462:
463:
464: /* Handle an event in a scrollBar window. */
465:
466: static XtEventReturnCode HandleScrollBarEvent(event, eventdata)
467: XEvent *event; /* The event itself. */
468: caddr_t eventdata;
469: {
470: WidgetData data = (WidgetData) eventdata;
471: XtActionTokenPtr actionList;
472: NotifyProc proc;
473:
474: data->eventlevels++;
475: switch (event->type) {
476: case Expose:
477: if (event->xexpose.count == 0){
478: data->topLoc = -1000; /* Forces entire thumb to be painted. */
479: PaintThumb(data);
480: }
481: return XteventHandled;
482: case DestroyNotify:
483: XtScrollBarDestroy(event->xany.display, event->xany.window);
484: return XteventHandled;
485: case ConfigureNotify:
486: data->width = event->xconfigure.width;
487: data->height = event->xconfigure.height;
488: FillArea(data, data->topLoc,
489: data->topLoc + data->shownLength, 0);
490:
491: data->topLoc = -1000; /* Forces entire thumb to be painted. */
492: PaintThumb(data);
493: return (XteventHandled);
494:
495: default:
496: actionList = (XtActionTokenPtr) XtTranslateEvent(
497: event, (TranslationPtr) data->state);
498: for (; actionList != NULL; actionList = actionList ->next) {
499: if (actionList ->type ==XttokenAction) {
500: proc = (NotifyProc)XtInterpretAction(data->dpy, (TranslationPtr) data->state, actionList->value.action);
501:
502: /* HACK until TM passes data */
503: if (proc == (NotifyProc)StartScroll) StartScroll(data,event->xbutton.button);
504: else if (proc == (NotifyProc)ScrollElevator) ScrollElevator(data,event->xbutton.button,event->xbutton.x,event->xbutton.y);
505: else if (proc == (NotifyProc)NotifyScroll) NotifyScroll(data, event->xbutton.x, event->xbutton.y);
506: else if (proc == (NotifyProc)NotifyThumb) NotifyThumb(data, event->xbutton.x,event->xbutton.y);
507: else if (proc == (NotifyProc)NotifyScroll1) NotifyScroll1(data,event->xbutton.x,event->xbutton.y);
508: else if (proc == (NotifyProc)MoveElevator) MoveElevator(data, event->xmotion.x, event->xmotion.y);
509:
510: /* (*proc) (data); */
511: }
512: }
513: break;
514:
515: }
516: data->eventlevels--;
517: return (XteventHandled);
518: }
519:
520:
521: /* Public routines. */
522:
523: /* Set the scroll bar to the given location. */
524:
525: void XtScrollBarSetThumb(dpy, scrollbarWindow,top,shown)
526: Display *dpy;
527: Window scrollbarWindow;
528: float top, shown;
529: {
530: WidgetData data;
531: data = SbarInfoFromSbarWindow(dpy, scrollbarWindow);
532: data->top = top;
533: data->shown = shown;
534: PaintThumb(data);
535: }
536:
537:
538: /* scroll bar already destroyed, remove its associated data. */
539: void XtScrollBarDestroy(dpy, scrollbarWindow)
540: Display *dpy;
541: Window scrollbarWindow;
542: {
543: XtFree((char *)SbarInfoFromSbarWindow(dpy, scrollbarWindow));
544: XtClearEventHandlers(dpy, scrollbarWindow);
545: (void) XDeleteContext(dpy, scrollbarWindow,widgetContext);
546: }
547:
548:
549:
550: /* Given a window definition, make it a scroll bar. */
551: Window XtScrollBarCreate(dpy, parent, args, argCount)
552: Display *dpy;
553: Window parent;
554: ArgList args;
555: int argCount;
556: {
557: WidgetData data; /* Record for info about this scrollBar */
558: XrmNameList names;
559: XrmClassList classes;
560: XGCValues values; /* goes away if thumb becomes a window */
561: unsigned long valuemask;
562: XImage image;
563:
564: static short pixmap_bits[] = {
565: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
566: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
567: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
568: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
569: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
570: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
571: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
572: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
573: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
574: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
575: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
576: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
577: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
578: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
579: 0xaaaa, 0xaaaa, 0x5555, 0x5555,
580: 0xaaaa, 0xaaaa, 0x5555, 0x5555
581: };
582:
583: #define default_width 32
584: #define default_height 32
585:
586: static XtActionsRec actionsTable[] = {
587: {"startup", (caddr_t)StartScroll},
588: {"startscroll", (caddr_t)ScrollElevator},
589: {"startdown", (caddr_t)StartScroll},
590: {"doup", (caddr_t)NotifyScroll},
591: {"doscroll", (caddr_t)NotifyThumb},
592: {"dodown", (caddr_t)NotifyScroll1},
593: {"movebar", (caddr_t)MoveElevator},
594: {NULL,NULL}
595: };
596:
597: if (!initialized) ScrollBarInitialize();
598:
599:
600: globaldata = globalinit;
601: globaldata.dpy = dpy;
602: XtGetResources(dpy,
603: resources, XtNumber(resources), args, argCount, parent,
604: "scrollBar","ScrollBar",&names, &classes);
605:
606: data = (WidgetData) XtMalloc(sizeof(WidgetDataRec));
607: *data = globaldata;
608:
609: data->state = XtSetActionBindings(data->dpy, data->eventTable, actionsTable, (caddr_t) Ignore);
610:
611: if (data->scrollbarWindow == NULL) {
612: if (data->width == 0) data->width = 1;
613: if (data->height == 0) data->height = 1;
614: data->scrollbarWindow = XCreateSimpleWindow(
615: data->dpy, parent, data->x, data->y,
616: data->width, data->height, 1,
617: data->border, data->background);
618: } else {
619: XWindowChanges wc;
620: unsigned int valuemask;
621: valuemask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
622: wc.x = data->x; wc.y = data->y; wc.width = data->width;
623: wc.height=data->height; wc.border_width = data->borderwidth;
624: XConfigureWindow(data->dpy,data->scrollbarWindow,valuemask,&wc);
625: XReparentWindow(data->dpy,data->scrollbarWindow,parent,data->x,data->y);
626: }
627:
628: if (data->orientation == XtorientHorizontal) {
629: if (data->NormalCursor == NULL)
630: data->NormalCursor = XtGetCursor(dpy, XC_sb_h_double_arrow);
631: if (data -> ButtonCursors[Button1] == NULL )
632: data->ButtonCursors[Button1] = XtGetCursor(dpy, XC_sb_left_arrow);
633: if (data -> ButtonCursors[Button2] == NULL)
634: data->ButtonCursors[Button2] = XtGetCursor(dpy, XC_sb_up_arrow);
635: if (data -> ButtonCursors[Button3] == NULL)
636: data->ButtonCursors[Button3] = XtGetCursor(dpy, XC_sb_right_arrow);
637: } else { if (data->orientation == XtorientVertical) {
638: if (data->NormalCursor == NULL)
639: data->NormalCursor = XtGetCursor(dpy, XC_sb_v_double_arrow);
640: if (data -> ButtonCursors[Button1] == NULL )
641: data->ButtonCursors[Button1] = XtGetCursor(dpy, XC_sb_up_arrow);
642: if (data -> ButtonCursors[Button2] == NULL)
643: data->ButtonCursors[Button2] = XtGetCursor(dpy, XC_sb_left_arrow);
644: if (data -> ButtonCursors[Button3] == NULL)
645: data->ButtonCursors[Button3] = XtGetCursor(dpy, XC_sb_down_arrow);
646: }
647: }
648: if (data->foreground == NULL)
649: data->foreground = BlackPixel(data->dpy,DefaultScreen(dpy));
650:
651:
652:
653: if (data->customthumb == NULL) {
654: image.height = default_height;
655: image.width = default_width;
656: image.xoffset = 0;
657: image.format = XYBitmap;
658: image.data = (char*) pixmap_bits;
659: image.byte_order = ImageByteOrder(data->dpy);
660: image.bitmap_pad = BitmapPad(data->dpy);
661: image.bitmap_bit_order = BitmapBitOrder(data->dpy);
662: image.bitmap_unit = BitmapUnit(data->dpy);
663: image.depth = 1;
664: image.bytes_per_line = default_width/8;
665: image.obdata = NULL;
666:
667: data->customthumb = XCreatePixmap(data->dpy, data->scrollbarWindow,
668: (Dimension)image.width,
669: (Dimension)image.height,
670: DefaultDepth(
671: data->dpy, DefaultScreen(data->dpy)));
672:
673: values.foreground = data->foreground;
674: values.background = data->background;
675: values.function = GXcopy; /* need to be explicit about defaults */
676: values.plane_mask = AllPlanes; /* until XtGetGC is re-done */
677: valuemask = GCFunction | GCForeground | GCBackground | GCPlaneMask;
678: data->gc = XtGetGC( data->dpy, widgetContext, data->scrollbarWindow,
679: valuemask, &values);
680: XPutImage(data->dpy, data->customthumb, data->gc, &image, 0, 0, 0, 0,
681: (Dimension) image.width, (Dimension) image.height);
682:
683: values.fill_style = FillTiled;
684: values.tile = data->customthumb;
685: valuemask = GCFillStyle | GCTile;
686: data->gc = XtGetGC(data->dpy,widgetContext,data->scrollbarWindow,valuemask,&values);
687: }
688:
689: else {
690:
691: values.foreground = data->foreground;
692: values.fill_style = FillTiled;
693: values.tile = data->customthumb;
694: valuemask = GCForeground | GCFillStyle | GCTile;
695: data->gc = XtGetGC(data->dpy,widgetContext,data->scrollbarWindow,valuemask,&values);
696: }
697: XDefineCursor(data->dpy,data->scrollbarWindow, data->NormalCursor);
698:
699: XtSetNameAndClass(data->dpy, data->scrollbarWindow, names, classes);
700:
701: (void) XSaveContext(data->dpy, data->scrollbarWindow, widgetContext, (caddr_t)data);
702: XtSetEventHandler(data->dpy, data->scrollbarWindow,
703: (XtEventHandler)HandleScrollBarEvent,
704: ButtonPressMask | ExposureMask | ButtonReleaseMask |
705: Button2MotionMask | StructureNotifyMask,
706: (caddr_t) data);
707: return data->scrollbarWindow;
708: }
709:
710: void XtScrollBarGetValues(dpy, window, args, argCount)
711: Display *dpy;
712: Window window;
713: ArgList args;
714: int argCount;
715: {
716: WidgetData data;
717: data = DataFromWindow(dpy, window);
718: if (data == NULL) return;
719: globaldata = *data;
720: XtGetValues(resources, XtNumber(resources), args, argCount);
721: }
722:
723:
724: void XtScrollBarSetValues(dpy, window, args, argCount)
725: Display *dpy;
726: Window window;
727: ArgList args;
728: int argCount;
729: {
730: WidgetData data;
731: short thumbmoved, redraw;
732:
733: thumbmoved = redraw = FALSE;
734: data = DataFromWindow(dpy, window);
735: if (data == NULL) return;
736: globaldata = *data;
737: XtSetValues(resources, XtNumber(resources), args, argCount);
738: if (globaldata.border != data->border) {
739: data->border = globaldata.border;
740: if (data->borderwidth != 0)
741: XSetWindowBorder(data->dpy,data->scrollbarWindow, data->border);
742: }
743: data->ScrollProc = globaldata.ScrollProc;
744: data->ThumbProc = globaldata.ThumbProc;
745: if (globaldata.foreground != data->foreground
746: || globaldata.background != data->background) {
747:
748: }
749: if (globaldata.foreground != data->foreground) {
750: data->foreground = globaldata.foreground;
751: }
752: if (globaldata.background != data->background) {
753: data->background = globaldata.background;
754:
755: }
756:
757: if (globaldata.customthumb != data->customthumb)
758: data->customthumb = globaldata.customthumb;
759:
760: if (globaldata.top != data->top) {
761: data->top = globaldata.top;
762: thumbmoved = TRUE;
763: }
764: if (globaldata.shown != data->shown) {
765: data->shown = globaldata.shown;
766: thumbmoved = TRUE;
767: }
768: if (redraw) {
769: XClearWindow(data->dpy, data->scrollbarWindow);
770: data->topLoc = -1000;
771: PaintThumb(data);
772: } else if (thumbmoved)
773: PaintThumb(data);
774: }
775:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.