|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* Copyright Massachusetts Institute of Technology 1984, 1985 */
4:
5: /* screen.c */
6:
7: #ifndef lint
8: static char *rcsid_screen_c = "$Header: screen.c,v 10.13 86/02/01 16:07:00 tony Rel $";
9: #endif lint
10:
11: #include <X/Xlib.h>
12: #include <stdio.h>
13: #include <sys/ioctl.h>
14: #include "ptyx.h"
15:
16: ScrnBuf Allocate (nrow, ncol)
17: /*
18: allocates memory for a 2-dimensional array of shorts and returns a pointer thereto
19: */
20: register int nrow, ncol;
21: {
22: register ScrnBuf base;
23:
24: if ((base = (ScrnBuf) calloc (nrow, sizeof (short *))) == 0) Error ();
25:
26: for (nrow--; nrow >= 0; nrow--)
27: if ((base [nrow] = (short *) calloc (ncol, sizeof (short))) == 0) Error ();
28:
29: return (base);
30: }
31:
32: ScreenWrite (screen, str, flags, length)
33: /*
34: Writes str into buf at row row and column col. Characters are set to match flags.
35: */
36: Screen *screen;
37: register char *str;
38: unsigned flags;
39: register int length; /* length of string */
40: {
41: register short mask = 0;
42: register short *row = screen->buf [screen->cur_row];
43: register short *col = row + screen->cur_col;
44: register int avail = screen->max_col - screen->cur_col + 1;
45: if (length > avail)
46: length = avail;
47: if (length <= 0) return;
48:
49: if (flags & INVERSE) mask |= INVERSEbit;
50: if (flags & BOLD) mask |= BOLDbit;
51:
52: if (mask)
53: do { *col++ = *str++ | mask; } while (--length > 0);
54: else
55: do { *col++ = *str++; } while (--length > 0);
56: }
57:
58: char *ScrnGetChars (sb, row, col, max, ptr, flags)
59: /*
60: Stores characters from sb at row, col into *ptr. At most max
61: characters are stored; will stop if the characters in sb do not match
62: the characteristics of flags. Returns the number of characters actually
63: stored + ptr.
64:
65: Requires max + col - 1 <= the maximum size of a row in sb.
66: max >= 0
67: */
68: ScrnBuf sb;
69: int row, col;
70: register int max;
71: register char *ptr;
72: unsigned int flags;
73: {
74: register short mask = 0;
75: register short *fetch = sb [row] + col;
76:
77: if (flags & INVERSE) mask |= INVERSEbit;
78: if (flags & BOLD) mask |= BOLDbit;
79:
80: while (((*fetch & (short) 0xff00) == mask) && (max-- > 0))
81: {
82: if (*fetch == 0) *fetch = (short) ' ';
83: *(ptr++) = (char) (*(fetch++) & (short) 0xff);
84: }
85:
86: return (ptr);
87: }
88:
89: ScrnInsertLine (sb, last, where, n, size)
90: /*
91: Inserts n blank lines at sb + where, treating last as a bottom margin.
92: Size is the size of each entry in sb.
93: Requires: 0 <= where < where + n <= last
94: n <= MAX_ROWS
95: */
96: register ScrnBuf sb;
97: int last;
98: register int where, n, size;
99: {
100: register int i;
101: register short *save [MAX_ROWS];
102: int length = size * sizeof (short);
103:
104: /* save n lines at bottom */
105: bcopy ((char *) &sb [last - n + 1], (char *) save,
106: n * sizeof (short *));
107:
108: /* clear contents of old rows */
109: for (i = 0; i < n; i++)
110: bzero ((char *) save [i], length);
111:
112: /* move down lines */
113: bcopy ((char *) &sb [where], (char *) &sb [where + n],
114: (last - where - n + 1) * sizeof (short *));
115:
116: /* reuse storage for new lines at where */
117: bcopy ((char *) save, (char *) &sb [where], n * sizeof (short *));
118: }
119:
120:
121: ScrnDeleteLine (sb, last, where, n, size)
122: /*
123: Deletes n lines at sb + where, treating last as a bottom margin.
124: Size is the size of each entry in sb.
125: Requires 0 <= where < where + n < = last
126: n <= MAX_ROWS
127: */
128: register ScrnBuf sb;
129: register int n, last, size;
130: int where;
131: {
132: register int i;
133: register short *save [MAX_ROWS];
134: int length = size * sizeof (short);
135:
136: /* save n lines at where */
137: bcopy ((char *) &sb [where], (char *) save, n * sizeof (short *));
138:
139: /* clear contents of old rows */
140: for (i = 0; i < n; i++)
141: bzero ((char *) save [i], length);
142:
143: /* move up lines */
144: bcopy ((char *) &sb [where + n], (char *) &sb [where],
145: (last - where - n + 1) * sizeof (short *));
146:
147: /* reuse storage for new bottom lines */
148: bcopy ((char *) save, (char *) &sb [last - n + 1],
149: n * sizeof (short *));
150: }
151:
152:
153: ScrnInsertChar (sb, row, col, n, size)
154: /*
155: Inserts n blanks in sb at row, col. Size is the size of each row.
156: */
157: ScrnBuf sb;
158: int row, size;
159: register int col, n;
160: {
161: register short *ptr = sb [row];
162: register int i;
163:
164: for (i = size - 1; i >= col + n; i--)
165: ptr [i] = ptr [i - n];
166:
167: bzero (ptr + col, n * sizeof (short));
168: }
169:
170:
171: ScrnDeleteChar (sb, row, col, n, size)
172: /*
173: Deletes n characters in sb at row, col. Size is the size of each row.
174: */
175: ScrnBuf sb;
176: register int row, size;
177: register int n, col;
178: {
179: register short *ptr = sb [row];
180: register nbytes;
181: nbytes = (size - n - col) * sizeof (short);
182:
183: bcopy (ptr + col + n, ptr + col, nbytes);
184: bzero (ptr + size - n, n * sizeof (short));
185: }
186:
187:
188: ScrnRefresh (screen, toprow, leftcol, nrows, ncols)
189: /*
190: Repaints the area enclosed by the parameters.
191: Requires: (toprow, leftcol), (toprow + nrows, leftcol + ncols) are
192: coordinates of characters in screen;
193: nrows and ncols positive.
194: */
195: register Screen *screen;
196: int toprow, leftcol, nrows, ncols;
197: {
198: char str [MAX_COLS];
199: int y = toprow * screen->f_height + screen->border;
200: register int row;
201: int maxrow = toprow + nrows - 1;
202:
203: for (row = toprow; row <= maxrow; y += screen->f_height, row++)
204: {
205: register short *chars = screen->buf [row];
206: register int col = leftcol;
207: int maxcol = leftcol + ncols - 1;
208: int lastind, curind;
209: unsigned short flags;
210: int gxfunction;
211: Font fnt;
212: int x;
213: short s;
214: #ifdef JUMPSCROLL
215: curind = row - screen->scroll_amt;
216: if (curind < 0 || curind > screen->max_row)
217: continue;
218: chars = screen->buf [curind];
219: #else
220: chars = screen->buf [row];
221: #endif JUMPSCROLL
222:
223: while (col <= maxcol && ((s = (chars[col] & ~BOLDbit)) == 0 ||
224: s == ' '))
225: col++;
226:
227: while (col <= maxcol && ((s = (chars[maxcol] & ~BOLDbit)) == 0 ||
228: s == ' '))
229: maxcol--;
230:
231: if (col > maxcol) continue;
232:
233: flags = (chars [col] & ~CHAR);
234:
235: if (flags & BOLDbit) fnt = screen->fnt_bold;
236: else fnt = screen->fnt_norm;
237:
238: x = col * screen->f_width + screen->border;
239: lastind = curind = 0;
240:
241: for (; col <= maxcol; col++, curind++)
242: {
243: s = chars [col];
244:
245: if ((s & ~CHAR) != flags)
246: {
247: if (flags & INVERSEbit)
248: XText (screen->window, x, y, &str[lastind],
249: curind-lastind, fnt,
250: screen->background, screen->foreground);
251: else
252: XText (screen->window, x, y, &str[lastind],
253: curind-lastind, fnt,
254: screen->foreground, screen->background);
255:
256: x += (curind - lastind) * screen->f_width;
257:
258: lastind = curind;
259:
260: flags = (s & ~CHAR);
261:
262: if (flags & BOLDbit) fnt = screen->fnt_bold;
263: else fnt = screen->fnt_norm;
264: }
265:
266: if ((str[curind] = (char) (s & CHAR)) == 0) str[curind] = ' ';
267: }
268:
269: if (flags & INVERSEbit)
270: XText (screen->window, x, y, &str[lastind], curind - lastind,
271: fnt, screen->background, screen->foreground);
272: else
273: XText (screen->window, x, y, &str[lastind], curind - lastind,
274: fnt, screen->foreground, screen->background);
275: }
276: }
277:
278: ClearBufRows (screen, first, last)
279: /*
280: Sets the rows first though last of the buffer of screen to spaces.
281: Requires first <= last; first, last are rows of screen->buf.
282: */
283: register Screen *screen;
284: register int first, last;
285: {
286: while (first <= last)
287: bzero (screen->buf [first++], sizeof (short) *
288: (screen->max_col + 1));
289: }
290:
291: ScreenResize (screen, width, height, flags)
292: /*
293: Resizes screen:
294: 1. If new window would have fractional characters, sets window size so as to discard fractional characters and returns -1.
295: Minimum screen size is 1 X 1.
296: Note that this causes another ExposeWindow event.
297: 2. Enlarges screen->buf if necessary. New space is appended to the bottom and to the right
298: 3. Reduces screen->buf if necessary. Old space is removed from the bottom and from the right
299: 4. Cursor is positioned as closely to its former position as possible
300: 5. Sets screen->max_row and screen->max_col to reflect new size
301: 6. Maintains the inner border.
302: 7. Clears origin mode and sets scrolling region to be entire screen.
303: 8. Returns 0
304: */
305: register Screen *screen;
306: int width, height;
307: unsigned *flags;
308: {
309: register int rows, cols;
310: register int index;
311: register ScrnBuf sb = screen->buf;
312: double scale_x, scale_y;
313: #ifdef TIOCSWINSZ
314: struct winsize ws;
315: #endif
316:
317: /* round so that it is unlikely the screen will change size on */
318: /* small mouse movements. */
319: rows = (height + screen->f_height / 2 - 2 * screen->border) /
320: screen->f_height;
321: cols = (width + screen->f_width / 2 - 2 * screen->border) /
322: screen->f_width;
323: if (rows < 1) rows = 1;
324: if (cols < 1) cols = 1;
325:
326: if ((width - screen->border * 2) % screen->f_width != 0 ||
327: (height - screen->border * 2) % screen->f_height != 0) {
328: int nwidth = cols * screen->f_width + screen->border * 2;
329: int nheight = rows * screen->f_height + screen->border * 2;
330:
331: XChangeWindow (screen->window, nwidth, nheight);
332: return (-1);
333: }
334:
335: /* don't change anything if the screen has not changed size */
336: if (screen->max_row == rows - 1 && screen->max_col == cols - 1)
337: return (0);
338:
339: /* resize current lines */
340: if (sb) for (index = 0; index <= screen->max_row; index++) {
341: if ((sb [index] = (short *) realloc ((char *) sb [index],
342: cols * sizeof (short))) == NULL) Error ();
343: if (cols > (screen->max_col + 1))
344: bzero (sb [index] + screen->max_col + 1,
345: sizeof(short) *(cols - (screen->max_col + 1)));
346: }
347:
348: /* discard excess bottom rows */
349: for (index = rows; index <= screen->max_row; index++)
350: free (sb [index]);
351:
352: /* resize sb */
353: if (sb == NULL)
354: sb = (ScrnBuf) malloc (rows * sizeof (short *));
355: else
356: sb = (ScrnBuf) realloc (sb, rows * sizeof (short *));
357: if (sb == NULL)
358: Error ();
359: screen->buf = sb;
360:
361: /* create additional bottom rows as required */
362: for (index = screen->max_row + 1; index < rows; index++)
363: if ((sb [index] = (short *) calloc (cols, sizeof (short))) == NULL)
364: Error ();
365:
366: screen->max_row = rows - 1;
367: screen->max_col = cols - 1;
368:
369: /* adjust scrolling region */
370: screen->top_marg = 0;
371: screen->bot_marg = screen->max_row;
372: *flags &= ~ORIGIN;
373:
374: if (screen->cur_row > screen->max_row)
375: screen->cur_row = screen->max_row;
376: if (screen->cur_col > screen->max_col)
377: screen->cur_col = screen->max_col;
378:
379: screen->height = height - 2 * screen->border;
380: screen->width = width - 2 * screen->border;
381:
382: /* Set Tektronix scale factor */
383: scale_x = screen->width / 4096.0;
384: scale_y = screen->height / 3128.0;
385: screen->TekScale = (scale_x < scale_y) ? scale_x : scale_y;
386:
387: #ifdef TIOCSWINSZ
388: /* Set tty's idea of window size */
389: ws.ws_row = rows;
390: ws.ws_col = cols;
391: ws.ws_xpixel = width;
392: ws.ws_ypixel = height;
393: ioctl (screen->respond, TIOCSWINSZ, &ws);
394: #endif
395: return (0);
396: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.