|
|
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.