|
|
1.1 ! root 1: /* ! 2: * $Source: /orpheus/u1/X11/clients/xterm/RCS/scrollbar.c,v $ ! 3: * $Header: scrollbar.c,v 1.20 87/08/17 19:38:44 swick Exp $ ! 4: */ ! 5: ! 6: #include <X11/copyright.h> ! 7: ! 8: /* ! 9: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 10: * ! 11: * All Rights Reserved ! 12: * ! 13: * Permission to use, copy, modify, and distribute this software and its ! 14: * documentation for any purpose and without fee is hereby granted, ! 15: * provided that the above copyright notice appear in all copies and that ! 16: * both that copyright notice and this permission notice appear in ! 17: * supporting documentation, and that the name of Digital Equipment ! 18: * Corporation not be used in advertising or publicity pertaining to ! 19: * distribution of the software without specific, written prior permission. ! 20: * ! 21: * ! 22: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 23: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 24: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 25: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 26: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 27: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 28: * SOFTWARE. ! 29: */ ! 30: ! 31: #include <stdio.h> ! 32: #include <setjmp.h> ! 33: #include <X11/Xlib.h> ! 34: #include <X11/Xtlib.h> ! 35: #include <X11/Xatom.h> ! 36: #include <X11/Xutil.h> ! 37: #include "ptyx.h" ! 38: #include "data.h" ! 39: #include "error.h" ! 40: ! 41: extern void bcopy(); ! 42: ! 43: #ifndef lint ! 44: static char rcs_id[] = "$Header: scrollbar.c,v 1.20 87/08/17 19:38:44 swick Exp $"; ! 45: #endif lint ! 46: ! 47: /* Event handlers */ ! 48: extern EventDoNothing(); ! 49: ! 50: extern ScrollTextTo(); ! 51: extern ScrollTextUpDownBy(); ! 52: ! 53: static Bool IsEventType( display, event, type ) ! 54: Display *display; ! 55: XEvent *event; ! 56: int type; ! 57: { ! 58: if (event->type == type) ! 59: return( True ); ! 60: else ! 61: return( False ); ! 62: } ! 63: ! 64: ! 65: /* resize the text window for a terminal screen, modifying the ! 66: * appropriate WM_SIZE_HINTS and taking advantage of bit gravity. ! 67: */ ! 68: ! 69: static void ResizeScreen( screen, min_width, min_height ) ! 70: register TScreen *screen; ! 71: int min_width, min_height; ! 72: { ! 73: XSizeHints sizehints; ! 74: XSetWindowAttributes newAttributes; ! 75: XWindowAttributes oldAttributes; ! 76: XEvent event; ! 77: ! 78: XGrabServer(screen->display); ! 79: if (!XGetSizeHints(screen->display, VWindow(screen), ! 80: &sizehints, XA_WM_NORMAL_HINTS)) ! 81: sizehints.flags = 0; ! 82: sizehints.min_width = min_width; ! 83: sizehints.min_height = min_height; ! 84: sizehints.width_inc = FontWidth(screen); ! 85: sizehints.height_inc = FontHeight(screen); ! 86: sizehints.width = (screen->max_col + 1) * FontWidth(screen) ! 87: + min_width; ! 88: sizehints.height = FontHeight(screen) * (screen->max_row + 1) ! 89: + min_height; ! 90: sizehints.flags |= PMinSize|PResizeInc|PSize; ! 91: XSetSizeHints(screen->display, ! 92: TextWindow(screen), &sizehints, XA_WM_NORMAL_HINTS); ! 93: XUngrabServer(screen->display); ! 94: ! 95: XGetWindowAttributes( screen->display, TextWindow(screen), ! 96: &oldAttributes ); ! 97: ! 98: newAttributes.event_mask = ! 99: oldAttributes.your_event_mask | StructureNotifyMask; ! 100: /* assume that the scrollbar always goes on the left! */ ! 101: newAttributes.bit_gravity = EastGravity; ! 102: ! 103: XChangeWindowAttributes( screen->display, TextWindow(screen), ! 104: CWEventMask|CWBitGravity, ! 105: &newAttributes ); ! 106: XResizeWindow( ! 107: screen->display, ! 108: TextWindow(screen), ! 109: (unsigned) (screen->max_col + 1) * FontWidth(screen) + min_width, ! 110: (unsigned) FontHeight(screen) * (screen->max_row + 1) ! 111: + min_height ); ! 112: ! 113: /* wait for a window manager to actually do it */ ! 114: XIfEvent( screen->display, &event, IsEventType, ConfigureNotify ); ! 115: ! 116: newAttributes.event_mask = oldAttributes.your_event_mask; ! 117: newAttributes.bit_gravity = NorthWestGravity; ! 118: XChangeWindowAttributes( screen->display, TextWindow(screen), ! 119: CWEventMask|CWBitGravity, ! 120: &newAttributes ); ! 121: } ! 122: ! 123: ! 124: Window CreateScrollBar(w, x, y, height) ! 125: Window w; ! 126: int x, y, height; ! 127: { ! 128: Window scrollWindow; ! 129: TScreen *screen = &term.screen; ! 130: XSetWindowAttributes attr; ! 131: extern char *calloc(); ! 132: ! 133: static Arg argList[] = { ! 134: {XtNbackground, (caddr_t) 0}, ! 135: {XtNborder, (caddr_t) 0}, ! 136: {XtNx, (caddr_t) 0}, ! 137: {XtNy, (caddr_t) 0}, ! 138: {XtNheight, (caddr_t) 0}, ! 139: {XtNorientation, (caddr_t) XtorientVertical}, ! 140: {XtNscrollUpDownProc,(caddr_t) ScrollTextUpDownBy}, ! 141: {XtNthumbProc, (caddr_t) ScrollTextTo}, ! 142: {XtNborderWidth, (caddr_t) 1}, ! 143: {XtNwidth, (caddr_t) SCROLLBARWIDTH-1}, ! 144: }; ! 145: ! 146: argList[0].value = (caddr_t) screen->background; ! 147: argList[1].value = (caddr_t) screen->bordercolor; ! 148: argList[2].value = (caddr_t) x; ! 149: argList[3].value = (caddr_t) y; ! 150: argList[4].value = (caddr_t) height; ! 151: ! 152: scrollWindow = XtScrollBarCreate(screen->display, w, ! 153: argList, XtNumber(argList)); ! 154: ! 155: attr.do_not_propagate_mask = ! 156: LeaveWindowMask | EnterWindowMask | StructureNotifyMask; ! 157: XChangeWindowAttributes(screen->display, scrollWindow, ! 158: CWDontPropagate, &attr); ! 159: ! 160: return(scrollWindow); ! 161: } ! 162: ! 163: ! 164: RedrawScrollBar(scrollWindow) ! 165: Window scrollWindow; ! 166: { ! 167: ! 168: TScreen *screen = &term.screen; ! 169: XtSendExpose(screen->display, scrollWindow); ! 170: } ! 171: ! 172: ScrollBarReverseVideo(scrollWindow) ! 173: register Window scrollWindow; ! 174: { ! 175: register TScreen *screen = &term.screen; ! 176: register caddr_t temp; ! 177: ! 178: static Arg argList[] = { ! 179: /* Don't muck with the order */ ! 180: {XtNforeground, (caddr_t) NULL}, ! 181: {XtNbackground, (caddr_t) NULL}, ! 182: {XtNborder, (caddr_t) NULL}, ! 183: }; ! 184: ! 185: XtScrollBarGetValues( ! 186: screen->display, scrollWindow, argList, XtNumber(argList)); ! 187: ! 188: /* Swap background and foreground */ ! 189: temp = argList[0].value; ! 190: argList[0].value = argList[1].value; ! 191: argList[1].value = temp; ! 192: ! 193: /* Should really only do this if the old bordertile is the same as ! 194: the scrollbar's current bordertile ||| LGR: ???*/ ! 195: argList[2].value = (caddr_t) screen->bordercolor; ! 196: ! 197: XtScrollBarGetValues( ! 198: screen->display, scrollWindow, argList, XtNumber(argList)); ! 199: ! 200: } ! 201: ! 202: ! 203: ScrollBarDrawThumb(scrollWindow) ! 204: register Window scrollWindow; ! 205: { ! 206: register TScreen *screen = &term.screen; ! 207: register int thumbTop, thumbHeight, totalHeight; ! 208: ! 209: thumbTop = screen->topline + screen->savedlines; ! 210: thumbHeight = screen->max_row + 1; ! 211: totalHeight = thumbHeight + screen->savedlines; ! 212: ! 213: XtScrollBarSetThumb(screen->display, scrollWindow, ! 214: ((float)thumbTop) / totalHeight, ! 215: ((float)thumbHeight) / totalHeight); ! 216: ! 217: } ! 218: ! 219: ResizeScrollBar(scrollWindow, x, y, height) ! 220: register Window scrollWindow; ! 221: int x, y; ! 222: unsigned height; ! 223: { ! 224: register TScreen *screen = &term.screen; ! 225: ! 226: XMoveResizeWindow( ! 227: screen->display, scrollWindow, ! 228: x, y, ! 229: (SCROLLBARWIDTH - 1), height); ! 230: ScrollBarDrawThumb(scrollWindow); ! 231: } ! 232: ! 233: WindowScroll(screen, top) ! 234: register TScreen *screen; ! 235: int top; ! 236: { ! 237: register int i, lines; ! 238: register int scrolltop, scrollheight, refreshtop; ! 239: ! 240: if (top < -screen->savedlines) ! 241: top = -screen->savedlines; ! 242: else if (top > 0) ! 243: top = 0; ! 244: if((i = screen->topline - top) == 0) { ! 245: ScrollBarDrawThumb(screen->scrollWindow); ! 246: return; ! 247: } ! 248: ! 249: ScrollSelection(i); ! 250: ! 251: if(screen->cursor_state) ! 252: HideCursor(); ! 253: lines = i > 0 ? i : -i; ! 254: if(lines > screen->max_row + 1) ! 255: lines = screen->max_row + 1; ! 256: scrollheight = screen->max_row - lines + 1; ! 257: if(i > 0) ! 258: refreshtop = scrolltop = 0; ! 259: else { ! 260: scrolltop = lines; ! 261: refreshtop = scrollheight; ! 262: } ! 263: if(scrollheight > 0) { ! 264: if (screen->multiscroll && scrollheight == 1 && ! 265: screen->topline == 0 && screen->top_marg == 0 && ! 266: screen->bot_marg == screen->max_row) { ! 267: if (screen->incopy < 0 && screen->scrolls == 0) ! 268: CopyWait (screen); ! 269: screen->scrolls++; ! 270: } else { ! 271: if (screen->incopy) ! 272: CopyWait (screen); ! 273: screen->incopy = -1; ! 274: } ! 275: XCopyArea( ! 276: screen->display, ! 277: TextWindow(screen), TextWindow(screen), ! 278: screen->normalGC, ! 279: (int) screen->border + screen->scrollbar, ! 280: (int) scrolltop * FontHeight(screen) + screen->border, ! 281: (unsigned) Width(screen), ! 282: (unsigned) scrollheight * FontHeight(screen), ! 283: (int) screen->border + screen->scrollbar, ! 284: (int) (scrolltop + i) * FontHeight(screen) ! 285: + screen->border); ! 286: } ! 287: screen->topline = top; ! 288: XClearArea( ! 289: screen->display, ! 290: TextWindow(screen), ! 291: (int) screen->border + screen->scrollbar, ! 292: (int) refreshtop * FontHeight(screen) + screen->border, ! 293: (unsigned) Width(screen), ! 294: (unsigned) lines * FontHeight(screen), ! 295: FALSE); ! 296: ScrnRefresh(screen, refreshtop, 0, lines, screen->max_col + 1); ! 297: ! 298: ScrollBarDrawThumb(screen->scrollWindow); ! 299: } ! 300: ! 301: ScrollBarOn(screen, init) ! 302: register TScreen *screen; ! 303: int init; ! 304: { ! 305: register int border = 2 * screen->border; ! 306: register int i; ! 307: char *realloc(), *calloc(); ! 308: ! 309: if(screen->scrollbar) ! 310: return; ! 311: if(!screen->scrollWindow) { ! 312: if((screen->scrollWindow = CreateScrollBar(TextWindow(screen), ! 313: -1, - 1, Height(screen) + border)) == NULL) { ! 314: Bell(); ! 315: return; ! 316: } ! 317: if((screen->allbuf = (ScrnBuf) realloc((char *) screen->buf, ! 318: (unsigned) 2*(screen->max_row + 2 + screen->savelines) * sizeof(char *))) ! 319: == NULL) ! 320: Error (ERROR_SBRALLOC); ! 321: screen->buf = &screen->allbuf[2 * screen->savelines]; ! 322: bcopy ((char *)screen->allbuf, (char *)screen->buf, ! 323: 2 * (screen->max_row + 2) * sizeof (char *)); ! 324: for(i = 2 * screen->savelines - 1 ; i >= 0 ; i--) ! 325: if((screen->allbuf[i] = ! 326: calloc((unsigned) screen->max_col + 1, sizeof(char))) == NULL) ! 327: Error (ERROR_SBRALLOC2); ! 328: } ! 329: screen->scrollbar = SCROLLBARWIDTH; ! 330: ScrollBarDrawThumb(screen->scrollWindow); ! 331: if (!init) ResizeScreen( screen, border + SCROLLBARWIDTH, border ); ! 332: /* map afterwards so BitGravity can be used profitably */ ! 333: XMapWindow(screen->display, screen->scrollWindow); ! 334: } ! 335: ! 336: ScrollBarOff(screen) ! 337: register TScreen *screen; ! 338: { ! 339: register int border = 2 * screen->border; ! 340: ! 341: if(!screen->scrollbar) ! 342: return; ! 343: screen->scrollbar = 0; ! 344: XUnmapWindow(screen->display, screen->scrollWindow); ! 345: ResizeScreen( screen, border, border ); ! 346: } ! 347: ! 348: /*ARGSUSED*/ ! 349: ScrollTextTo(dpy, scrollbarWindow, clientWindow, topPercent) ! 350: Display *dpy; ! 351: Window scrollbarWindow, clientWindow; ! 352: float topPercent; ! 353: { ! 354: register TScreen *screen = &term.screen; ! 355: int thumbTop; /* relative to first saved line */ ! 356: int newTopLine; ! 357: ! 358: /* ! 359: screen->savedlines : Number of offscreen text lines, ! 360: screen->maxrow + 1 : Number of onscreen text lines, ! 361: screen->topline : -Number of lines above the last screen->max_row+1 lines ! 362: */ ! 363: ! 364: thumbTop = topPercent * (screen->savedlines + screen->max_row+1); ! 365: newTopLine = thumbTop - screen->savedlines; ! 366: WindowScroll(screen, newTopLine); ! 367: } ! 368: ! 369: /*ARGSUSED*/ ! 370: ScrollTextUpDownBy(dpy, scrollbarWindow, clientWindow, pixels) ! 371: Display *dpy; ! 372: Window scrollbarWindow, clientWindow; ! 373: int pixels; ! 374: { ! 375: register TScreen *screen = &term.screen; ! 376: register int rowOnScreen, newTopLine; ! 377: ! 378: rowOnScreen = pixels / FontHeight(screen); ! 379: if (rowOnScreen == 0) { ! 380: if (pixels < 0) ! 381: rowOnScreen = -1; ! 382: else if (pixels > 0) ! 383: rowOnScreen = 1; ! 384: } ! 385: newTopLine = screen->topline + rowOnScreen; ! 386: WindowScroll(screen, newTopLine); ! 387: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.