Annotation of researchv9/X11/src/X.V11R1/clients/xterm/screen.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     $Source: /orpheus/u1/X11/clients/xterm/RCS/screen.c,v $
                      3:  *     $Header: screen.c,v 1.9 87/08/13 16:02:42 guarino 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: /* screen.c */
                     32: 
                     33: #ifndef lint
                     34: static char rcs_id[] = "$Header: screen.c,v 1.9 87/08/13 16:02:42 guarino Exp $";
                     35: #endif lint
                     36: 
                     37: #include <X11/Xlib.h>
                     38: #include <stdio.h>
                     39: #include <sys/ioctl.h>
                     40: #include <signal.h>
                     41: #include "ptyx.h"
                     42: #include "error.h"
                     43: 
                     44: extern char *calloc();
                     45: extern char *malloc();
                     46: extern char *realloc();
                     47: extern void bcopy();
                     48: extern void free();
                     49: 
                     50: ScrnBuf Allocate (nrow, ncol)
                     51: /*
                     52:    allocates memory for a 2-dimensional array of chars and returns a pointer
                     53:    thereto
                     54:    each line is formed from a pair of char arrays.  The first (even) one is
                     55:    the actual character array and the second (odd) one is the attributes.
                     56:  */
                     57: register int nrow, ncol;
                     58: {
                     59:        register ScrnBuf base;
                     60: 
                     61:        if ((base = (ScrnBuf) calloc ((unsigned)(nrow *= 2), sizeof (char *))) == 0)
                     62:                SysError (ERROR_SCALLOC);
                     63: 
                     64:        for (nrow--; nrow >= 0; nrow--)
                     65:                if ((base [nrow] = calloc ((unsigned)ncol, sizeof(char))) == 0)
                     66:                        SysError (ERROR_SCALLOC2);
                     67: 
                     68:        return (base);
                     69: }
                     70: 
                     71: ScreenWrite (screen, str, flags, length)
                     72: /*
                     73:    Writes str into buf at row row and column col.  Characters are set to match
                     74:    flags.
                     75:  */
                     76: TScreen *screen;
                     77: char *str;
                     78: register unsigned flags;
                     79: register int length;           /* length of string */
                     80: {
                     81:        register char *att;
                     82:        register int avail  = screen->max_col - screen->cur_col + 1;
                     83:        register char *col;
                     84: 
                     85:        if (length > avail)
                     86:            length = avail;
                     87:        if (length <= 0)
                     88:                return;
                     89: 
                     90:        col = screen->buf[avail = 2 * screen->cur_row] + screen->cur_col;
                     91:        att = screen->buf[avail + 1] + screen->cur_col;
                     92:        flags &= ATTRIBUTES;
                     93:        bcopy(str, col, length);
                     94:        while(length-- > 0)
                     95:                *att++ = flags;
                     96: }
                     97: 
                     98: ScrnInsertLine (sb, last, where, n, size)
                     99: /*
                    100:    Inserts n blank lines at sb + where, treating last as a bottom margin.
                    101:    Size is the size of each entry in sb.
                    102:    Requires: 0 <= where < where + n <= last
                    103:             n <= MAX_ROWS
                    104:  */
                    105: register ScrnBuf sb;
                    106: int last;
                    107: register int where, n, size;
                    108: {
                    109:        register int i;
                    110:        char *save [2 * MAX_ROWS];
                    111: 
                    112:        /* save n lines at bottom */
                    113:        bcopy ((char *) &sb [2 * (last -= n - 1)], (char *) save,
                    114:                2 * sizeof (char *) * n);
                    115:        
                    116:        /* clear contents of old rows */
                    117:        for (i = 2 * n - 1; i >= 0; i--)
                    118:                bzero ((char *) save [i], size);
                    119: 
                    120:        /* move down lines */
                    121:        bcopy ((char *) &sb [2 * where], (char *) &sb [2 * (where + n)],
                    122:                2 * sizeof (char *) * (last - where));
                    123: 
                    124:        /* reuse storage for new lines at where */
                    125:        bcopy ((char *)save, (char *) &sb[2 * where], 2 * sizeof(char *) * n);
                    126: }
                    127: 
                    128: 
                    129: ScrnDeleteLine (sb, last, where, n, size)
                    130: /*
                    131:    Deletes n lines at sb + where, treating last as a bottom margin.
                    132:    Size is the size of each entry in sb.
                    133:    Requires 0 <= where < where + n < = last
                    134:            n <= MAX_ROWS
                    135:  */
                    136: register ScrnBuf sb;
                    137: register int n, last, size;
                    138: int where;
                    139: {
                    140:        register int i;
                    141:        char *save [2 * MAX_ROWS];
                    142: 
                    143:        /* save n lines at where */
                    144:        bcopy ((char *) &sb[2 * where], (char *)save, 2 * sizeof(char *) * n);
                    145: 
                    146:        /* clear contents of old rows */
                    147:        for (i = 2 * n - 1 ; i >= 0 ; i--)
                    148:                bzero ((char *) save [i], size);
                    149: 
                    150:        /* move up lines */
                    151:        bcopy ((char *) &sb[2 * (where + n)], (char *) &sb[2 * where],
                    152:                2 * sizeof (char *) * ((last -= n - 1) - where));
                    153: 
                    154:        /* reuse storage for new bottom lines */
                    155:        bcopy ((char *)save, (char *) &sb[2 * last],
                    156:                2 * sizeof(char *) * n);
                    157: }
                    158: 
                    159: 
                    160: ScrnInsertChar (sb, row, col, n, size)
                    161: /*
                    162:    Inserts n blanks in sb at row, col.  Size is the size of each row.
                    163:  */
                    164: ScrnBuf sb;
                    165: int row, size;
                    166: register int col, n;
                    167: {
                    168:        register int i, j;
                    169:        register char *ptr = sb [2 * row];
                    170:        register char *att = sb [2 * row + 1];
                    171: 
                    172:        for (i = size - 1; i >= col + n; i--) {
                    173:                ptr[i] = ptr[j = i - n];
                    174:                att[i] = att[j];
                    175:        }
                    176: 
                    177:        bzero (ptr + col, n);
                    178:        bzero (att + col, n);
                    179: }
                    180: 
                    181: 
                    182: ScrnDeleteChar (sb, row, col, n, size)
                    183: /*
                    184:    Deletes n characters in sb at row, col. Size is the size of each row.
                    185:  */
                    186: ScrnBuf sb;
                    187: register int row, size;
                    188: register int n, col;
                    189: {
                    190:        register char *ptr = sb[2 * row];
                    191:        register char *att = sb[2 * row + 1];
                    192:        register nbytes = (size - n - col);
                    193: 
                    194:        bcopy (ptr + col + n, ptr + col, nbytes);
                    195:        bcopy (att + col + n, att + col, nbytes);
                    196:        bzero (ptr + size - n, n);
                    197:        bzero (att + size - n, n);
                    198: }
                    199: 
                    200: 
                    201: ScrnRefresh (screen, toprow, leftcol, nrows, ncols)
                    202: /*
                    203:    Repaints the area enclosed by the parameters.
                    204:    Requires: (toprow, leftcol), (toprow + nrows, leftcol + ncols) are
                    205:             coordinates of characters in screen;
                    206:             nrows and ncols positive.
                    207:  */
                    208: register TScreen *screen;
                    209: int toprow, leftcol, nrows, ncols;
                    210: {
                    211:        int y = toprow * FontHeight(screen) + screen->border +
                    212:                screen->fnt_norm->max_bounds.ascent;
                    213:        register int row;
                    214:        register int topline = screen->topline;
                    215:        int maxrow = toprow + nrows - 1;
                    216:        int scrollamt = screen->scroll_amt;
                    217:        int max = screen->max_row;
                    218:        
                    219: 
                    220:        if(screen->cursor_col >= leftcol && screen->cursor_col <=
                    221:         (leftcol + ncols - 1) && screen->cursor_row >= toprow + topline &&
                    222:         screen->cursor_row <= maxrow + topline)
                    223:                screen->cursor_state = OFF;
                    224:        for (row = toprow; row <= maxrow; y += FontHeight(screen), row++) {
                    225:           register char *chars;
                    226:           register char *att;
                    227:           register int col = leftcol;
                    228:           int maxcol = leftcol + ncols - 1;
                    229:           int lastind;
                    230:           int flags;
                    231:           int x, n;
                    232:           GC gc;
                    233: 
                    234:           lastind = row - scrollamt;
                    235:           if (lastind < 0 || lastind > max)
                    236:                continue;
                    237:           chars = screen->buf [2 * (lastind + topline)];
                    238:           att = screen->buf [2 * (lastind + topline) + 1];
                    239: 
                    240:           while (col <= maxcol && (att[col] & ~BOLD) == 0 &&
                    241:            (chars[col] & ~040) == 0)
                    242:                col++;
                    243: 
                    244:           while (col <= maxcol && (att[maxcol] & ~BOLD) == 0 &&
                    245:            (chars[maxcol] & ~040) == 0)
                    246:                maxcol--;
                    247: 
                    248:           if (col > maxcol) continue;
                    249: 
                    250:           flags = att[col];
                    251: 
                    252:           if ((flags & INVERSE) != 0)
                    253:               if (flags & BOLD) gc = screen->reverseboldGC;
                    254:               else gc = screen->reverseGC;
                    255:           else 
                    256:               if (flags & BOLD) gc = screen->normalboldGC;
                    257:               else gc = screen->normalGC;
                    258: 
                    259:           x = CursorX(screen, col);
                    260:           lastind = col;
                    261: 
                    262:           for (; col <= maxcol; col++) {
                    263:                if (att[col] != flags) {
                    264:                   XDrawImageString(screen->display, TextWindow(screen), 
                    265:                                gc, x, y, &chars[lastind], n = col - lastind);
                    266:                   if((flags & BOLD) && screen->enbolden)
                    267:                        XDrawString(screen->display, TextWindow(screen), 
                    268:                         gc, x + 1, y, &chars[lastind], n);
                    269:                   if(flags & UNDERLINE) 
                    270:                        XDrawLine(screen->display, TextWindow(screen), 
                    271:                         gc, x, y+1, x+n*FontWidth(screen), y+1);
                    272: 
                    273:                   x += (col - lastind) * FontWidth(screen);
                    274: 
                    275:                   lastind = col;
                    276: 
                    277:                   flags = att[col];
                    278: 
                    279:                   if ((flags & INVERSE) != 0)
                    280:                        if (flags & BOLD) gc = screen->reverseboldGC;
                    281:                        else gc = screen->reverseGC;
                    282:                    else 
                    283:                         if (flags & BOLD) gc = screen->normalboldGC;
                    284:                         else gc = screen->normalGC;
                    285:                }
                    286: 
                    287:                if(chars[col] == 0)
                    288:                        chars[col] = ' ';
                    289:           }
                    290: 
                    291: 
                    292:           if ((flags & INVERSE) != 0)
                    293:               if (flags & BOLD) gc = screen->reverseboldGC;
                    294:               else gc = screen->reverseGC;
                    295:           else 
                    296:               if (flags & BOLD) gc = screen->normalboldGC;
                    297:               else gc = screen->normalGC;
                    298:           XDrawImageString(screen->display, TextWindow(screen), gc, 
                    299:                 x, y, &chars[lastind], n = col - lastind);
                    300:           if((flags & BOLD) && screen->enbolden)
                    301:                XDrawString(screen->display, TextWindow(screen), gc,
                    302:                x + 1, y, &chars[lastind], n);
                    303:           if(flags & UNDERLINE) 
                    304:                XDrawLine(screen->display, TextWindow(screen), gc, 
                    305:                 x, y+1, x + n * FontWidth(screen), y+1);
                    306:        }
                    307: }
                    308: 
                    309: ClearBufRows (screen, first, last)
                    310: /*
                    311:    Sets the rows first though last of the buffer of screen to spaces.
                    312:    Requires first <= last; first, last are rows of screen->buf.
                    313:  */
                    314: register TScreen *screen;
                    315: register int first, last;
                    316: {
                    317:        first *= 2;
                    318:        last = 2 * last + 1;
                    319:        while (first <= last)
                    320:                bzero (screen->buf [first++], (screen->max_col + 1));
                    321: }
                    322: 
                    323: ScreenResize (screen, width, height, flags)
                    324: /*
                    325:    Resizes screen:
                    326:    1. If new window would have fractional characters, sets window size so as to
                    327:       discard fractional characters and returns -1.
                    328:       Minimum screen size is 1 X 1.
                    329:       Note that this causes another ExposeWindow event.
                    330:    2. Enlarges screen->buf if necessary.  New space is appended to the bottom
                    331:       and to the right
                    332:    3. Reduces  screen->buf if necessary.  Old space is removed from the bottom
                    333:       and from the right
                    334:    4. Cursor is positioned as closely to its former position as possible
                    335:    5. Sets screen->max_row and screen->max_col to reflect new size
                    336:    6. Maintains the inner border.
                    337:    7. Clears origin mode and sets scrolling region to be entire screen.
                    338:    8. Returns 0
                    339:  */
                    340: register TScreen *screen;
                    341: int width, height;
                    342: unsigned *flags;
                    343: {
                    344:        register int rows, cols;
                    345:        register int index;
                    346:        register int savelines;
                    347:        register ScrnBuf sb = screen->allbuf;
                    348:        register ScrnBuf ab = screen->altbuf;
                    349:        register int x;
                    350:        register int border = 2 * screen->border;
                    351:        register int i, j, k;
                    352: #ifdef sun
                    353: #ifdef TIOCSSIZE
                    354:        struct ttysize ts;
                    355: #endif TIOCSSIZE
                    356: #else sun
                    357: #ifdef TIOCSWINSZ
                    358:        struct winsize ws;
                    359: #endif TIOCSWINSZ
                    360: #endif sun
                    361: 
                    362:        /* round so that it is unlikely the screen will change size on  */
                    363:        /* small mouse movements.                                       */
                    364:        rows = (height + FontHeight(screen) / 2 - border) /
                    365:         FontHeight(screen);
                    366:        cols = (width + FontWidth(screen) / 2 - border - screen->scrollbar) /
                    367:         FontWidth(screen);
                    368:        if (rows < 1) rows = 1;
                    369:        if (cols < 1) cols = 1;
                    370: 
                    371:        if ((width - border - screen->scrollbar) % FontWidth(screen)
                    372:         != 0 || (height - border) % FontHeight(screen) != 0) {
                    373:                XResizeWindow(
                    374:                    screen->display,
                    375:                    TextWindow(screen),
                    376:                    (unsigned) cols * FontWidth(screen) + border
                    377:                        + screen->scrollbar,
                    378:                    (unsigned) rows * FontHeight(screen) + border);
                    379:                return (-1);
                    380:        }
                    381: 
                    382:        /* change buffers if the screen has changed size */
                    383:        if (screen->max_row != rows - 1 || screen->max_col != cols - 1) {
                    384:                if(screen->cursor_state)
                    385:                        HideCursor();
                    386:                savelines = screen->scrollWindow ? screen->savelines : 0;
                    387:                j = screen->max_col + 1;
                    388:                i = cols - j;
                    389:                k = screen->max_row;
                    390:                if(rows < k)
                    391:                        k = rows;
                    392:                if(ab) {
                    393:                        /* resize current lines in alternate buf */
                    394:                        for (index = x = 0; index <= k; x += 2, index++) {
                    395:                                if ((ab[x] = realloc(ab[x], (unsigned) cols)) == NULL)
                    396:                                        SysError(ERROR_SREALLOC);
                    397:                                if((ab[x + 1] = realloc(ab[x + 1], (unsigned) cols)) ==
                    398:                                 NULL)
                    399:                                        SysError (ERROR_SREALLOC2);
                    400:                                if (cols > j) {
                    401:                                        bzero (ab [x] + j, i);
                    402:                                        bzero (ab [x + 1] + j, i);
                    403:                                }
                    404:                        }
                    405:                        /* discard excess bottom rows in alt buf */
                    406:                        for (index = rows, x = 2 * k ; index <=
                    407:                         screen->max_row; x += 2, index++) {
                    408:                           free (ab [x]);
                    409:                           free (ab [x + 1]);
                    410:                        }
                    411:                }
                    412:                /* resize current lines */
                    413:                 k += savelines;
                    414:                for (index = x = 0; index <= k; x += 2, index++) {
                    415:                        if ((sb[x] = realloc(sb[x], (unsigned) cols)) == NULL)
                    416:                                SysError(ERROR_SREALLOC3);
                    417:                        if((sb[x + 1] = realloc(sb[x + 1], (unsigned) cols)) == NULL)
                    418:                                SysError (ERROR_SREALLOC4);
                    419:                        if (cols > j) {
                    420:                                bzero (sb [x] + j, i);
                    421:                                bzero (sb [x + 1] + j, i);
                    422:                        }
                    423:                }
                    424:                /* discard excess bottom rows */
                    425:                for (index = rows, x = 2 * k; index <= screen->max_row;
                    426:                 x += 2, index++) {
                    427:                   free (sb [x]);
                    428:                   free (sb [x + 1]);
                    429:                }
                    430:                if(ab) {
                    431:                    if((ab = (ScrnBuf)realloc((char *)ab,
                    432:                     (unsigned) 2 * sizeof(char *) * rows)) == NULL)
                    433:                        SysError (ERROR_RESIZE);
                    434:                    screen->altbuf = ab;
                    435:                }
                    436:                k = 2 * (rows + savelines);
                    437:                /* resize sb */
                    438:                if((sb = (ScrnBuf)realloc((char *) sb, (unsigned) k * sizeof(char *)))
                    439:                  == NULL)
                    440:                        SysError (ERROR_RESIZE2);
                    441:                screen->allbuf = sb;
                    442:                screen->buf = &sb[2 * savelines];
                    443:        
                    444:                if(ab) {
                    445:                        /* create additional bottom rows as required in alt */
                    446:                        for (index = screen->max_row + 1, x = 2 * index ;
                    447:                         index < rows; x += 2, index++) {
                    448:                           if((ab[x] = calloc ((unsigned) cols, sizeof(char))) == NULL)
                    449:                                SysError(ERROR_RESIZROW);
                    450:                           if((ab[x + 1] = calloc ((unsigned) cols, sizeof(char))) == NULL)
                    451:                                SysError(ERROR_RESIZROW2);
                    452:                        }
                    453:                }
                    454:                /* create additional bottom rows as required */
                    455:                for (index = screen->max_row + 1, x = 2 * (index + savelines) ;
                    456:                 index < rows; x += 2, index++) {
                    457:                   if((sb[x] = calloc ((unsigned) cols, sizeof(char))) == NULL)
                    458:                        SysError(ERROR_RESIZROW3);
                    459:                   if((sb[x + 1] = calloc ((unsigned) cols, sizeof(char))) == NULL)
                    460:                        SysError(ERROR_RESIZROW4);
                    461:                }
                    462: 
                    463:                screen->max_row = rows - 1;
                    464:                screen->max_col = cols - 1;
                    465:        
                    466:                /* adjust scrolling region */
                    467:                screen->top_marg = 0;
                    468:                screen->bot_marg = screen->max_row;
                    469:                *flags &= ~ORIGIN;
                    470:        
                    471:                if (screen->cur_row > screen->max_row)
                    472:                        screen->cur_row = screen->max_row;
                    473:                if (screen->cur_col > screen->max_col)
                    474:                        screen->cur_col = screen->max_col;
                    475:        
                    476:                screen->fullVwin.height = height - border;
                    477:                screen->fullVwin.width = width - border - screen->scrollbar;
                    478: 
                    479:        } else if(FullHeight(screen) == height && FullWidth(screen) == width)
                    480:                return(0);      /* nothing has changed at all */
                    481: 
                    482:        if(screen->scrollWindow)
                    483:                ResizeScrollBar(screen->scrollWindow, -1, -1, height);
                    484:        
                    485:        screen->fullVwin.fullheight = height;
                    486:        screen->fullVwin.fullwidth = width;
                    487: #ifdef sun
                    488: #ifdef TIOCSSIZE
                    489:        /* Set tty's idea of window size */
                    490:        ts.ts_lines = rows;
                    491:        ts.ts_cols = cols;
                    492:        ioctl (screen->respond, TIOCSSIZE, &ts);
                    493: #ifdef SIGWINCH
                    494:        if(screen->pid > 1)
                    495:                killpg(getpgrp(screen->pid), SIGWINCH);
                    496: #endif SIGWINCH
                    497: #endif TIOCSSIZE
                    498: #else sun
                    499: #ifdef TIOCSWINSZ
                    500:        /* Set tty's idea of window size */
                    501:        ws.ws_row = rows;
                    502:        ws.ws_col = cols;
                    503:        ws.ws_xpixel = width;
                    504:        ws.ws_ypixel = height;
                    505:        ioctl (screen->respond, TIOCSWINSZ, (char *)&ws);
                    506: #ifdef SIGWINCH
                    507:        if(screen->pid > 1)
                    508:                killpg(getpgrp((int)screen->pid), SIGWINCH);
                    509: #endif SIGWINCH
                    510: #endif TIOCSWINSZ
                    511: #endif sun
                    512:        return (0);
                    513: }
                    514: 
                    515: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.