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