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