📄 screen.c
字号:
/* * $Header: screen.c,v 1.30.1.1 92/09/24 12:38:18 dbrooks Exp $ *//* * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. *//* screen.c */#include "ptyx.h"#include "error.h"#include "data.h"#include <stdio.h>#include <signal.h>#if defined(SVR4) || defined(hpux)#include <termios.h>#else#include <sys/ioctl.h>#endif#ifdef att#include <sys/termio.h>#include <sys/stream.h> /* get typedef used in ptem.h */#include <sys/ptem.h>#endifextern Char *calloc(), *malloc(), *realloc();extern void free();ScrnBuf Allocate (nrow, ncol, addr)/* allocates memory for a 2-dimensional array of chars and returns a pointer thereto each line is formed from a pair of char arrays. The first (even) one is the actual character array and the second (odd) one is the attributes.> each line is formed from four char arrays. The first one is the actual> character array, the second one is the attributes, the third is the> foreground color, and the fourth is the background color. */register int nrow, ncol;Char **addr;{ register ScrnBuf base; register Char *tmp; register int i; if ((base = (ScrnBuf) calloc ((unsigned)(nrow *= 4), sizeof (char *))) == 0) SysError (ERROR_SCALLOC); if ((tmp = calloc ((unsigned) (nrow * ncol), sizeof(char))) == 0) SysError (ERROR_SCALLOC2); *addr = tmp; for (i = 0; i < nrow; i++, tmp += ncol) base[i] = tmp; return (base);}/* * This is called when the screen is resized. * Returns the number of lines the text was moved down (neg for up). * (Return value only necessary with SouthWestGravity.) */staticReallocate(sbuf, sbufaddr, nrow, ncol, oldrow, oldcol) ScrnBuf *sbuf; Char **sbufaddr; int nrow, ncol, oldrow, oldcol;{ register ScrnBuf base; register Char *tmp; register int i, minrows, mincols; Char *oldbuf; int move_down = 0, move_up = 0; if (sbuf == NULL || *sbuf == NULL) return 0; oldrow *= 4; oldbuf = *sbufaddr; /* * Special case if oldcol == ncol - straight forward realloc and * update of the additional lines in sbuf */ /* this is a good idea, but doesn't seem to be implemented. -gildea */ /* * realloc sbuf, the pointers to all the lines. * If the screen shrinks, remove lines off the top of the buffer * if resizeGravity resource says to do so. */ nrow *= 4; if (nrow < oldrow && term->misc.resizeGravity == SouthWestGravity) { /* Remove lines off the top of the buffer if necessary. */ move_up = oldrow-nrow - 4*(term->screen.max_row - term->screen.cur_row); if (move_up < 0) move_up = 0; /* Overlapping bcopy here! */ bcopy(*sbuf+move_up, *sbuf, (oldrow-move_up)*sizeof((*sbuf)[0]) ); } *sbuf = (ScrnBuf) realloc((char *) (*sbuf), (unsigned) (nrow * sizeof(char *))); if (*sbuf == 0) SysError(ERROR_RESIZE); base = *sbuf; /* * create the new buffer space and copy old buffer contents there * line by line. */ if ((tmp = calloc((unsigned) (nrow * ncol), sizeof(char))) == 0) SysError(ERROR_SREALLOC); *sbufaddr = tmp; minrows = (oldrow < nrow) ? oldrow : nrow; mincols = (oldcol < ncol) ? oldcol : ncol; if (nrow > oldrow && term->misc.resizeGravity == SouthWestGravity) { /* move data down to bottom of expanded screen */ move_down = Min(nrow-oldrow, 4*term->screen.savedlines); tmp += ncol*move_down; } for (i = 0; i < minrows; i++, tmp += ncol) { bcopy(base[i], tmp, mincols); } /* * update the pointers in sbuf */ for (i = 0, tmp = *sbufaddr; i < nrow; i++, tmp += ncol) base[i] = tmp; /* Now free the old buffer */ free(oldbuf); return move_down ? move_down/4 : -move_up/4; /* convert to rows */}ScreenWrite (screen, str, flags, cur_fg, cur_bg, length)/* Writes str into buf at row row and column col. Characters are set to match flags. */TScreen *screen;char *str;register unsigned flags;register unsigned cur_fg, cur_bg;register int length; /* length of string */{ register Char *attrs, *fgs, *bgs; register int avail = screen->max_col - screen->cur_col + 1; register Char *col; if (length > avail) length = avail; if (length <= 0) return; col = screen->buf[avail = 4 * screen->cur_row] + screen->cur_col; attrs = screen->buf[avail + 1] + screen->cur_col; fgs = screen->buf[avail + 2] + screen->cur_col; bgs = screen->buf[avail + 3] + screen->cur_col; flags &= ATTRIBUTES; flags |= CHARDRAWN; bcopy(str, col, length); while(length-- > 0) { *attrs++ = flags; *fgs++ = cur_fg; *bgs++ = cur_bg; }}ScrnInsertLine (sb, last, where, n, size)/* Inserts n blank lines at sb + where, treating last as a bottom margin. Size is the size of each entry in sb. Requires: 0 <= where < where + n <= last n <= MAX_ROWS */register ScrnBuf sb;int last;register int where, n, size;{ register int i; char *save [4 * MAX_ROWS]; /* save n lines at bottom */ bcopy ((char *) &sb [4 * (last -= n - 1)], (char *) save, 4 * sizeof (char *) * n); /* clear contents of old rows */ for (i = 4 * n - 1; i >= 0; i--) bzero ((char *) save [i], size); /* * WARNING, overlapping copy operation. Move down lines (pointers). * * +----|---------|--------+ * * is copied in the array to: * * +--------|---------|----+ */ bcopy ((char *) &sb [4 * where], (char *) &sb [4 * (where + n)], 4 * sizeof (char *) * (last - where)); /* reuse storage for new lines at where */ bcopy ((char *)save, (char *) &sb[4 * where], 4 * sizeof(char *) * n);}ScrnDeleteLine (sb, last, where, n, size)/* Deletes n lines at sb + where, treating last as a bottom margin. Size is the size of each entry in sb. Requires 0 <= where < where + n < = last n <= MAX_ROWS */register ScrnBuf sb;register int n, last, size;int where;{ register int i; char *save [4 * MAX_ROWS]; /* save n lines at where */ bcopy ((char *) &sb[4 * where], (char *)save, 4 * sizeof(char *) * n); /* clear contents of old rows */ for (i = 4 * n - 1 ; i >= 0 ; i--) bzero ((char *) save [i], size); /* move up lines */ bcopy ((char *) &sb[4 * (where + n)], (char *) &sb[4 * where], 4 * sizeof (char *) * ((last -= n - 1) - where)); /* reuse storage for new bottom lines */ bcopy ((char *)save, (char *) &sb[4 * last], 4 * sizeof(char *) * n);}ScrnInsertChar (sb, row, col, n, size) /* Inserts n blanks in sb at row, col. Size is the size of each row. */ ScrnBuf sb; int row, size; register int col, n;{ register int i, j; register Char *ptr = sb [4 * row]; register Char *attrs = sb [4 * row + 1]; register Char *fgs = sb [4 * row + 2]; register Char *bgs = sb [4 * row + 3]; int wrappedbit = attrs[0]&LINEWRAPPED; attrs[0] &= ~LINEWRAPPED; /* make sure the bit isn't moved */ for (i = size - 1; i >= col + n; i--) { ptr[i] = ptr[j = i - n]; attrs[i] = attrs[j]; fgs[i] = fgs[j]; bgs[i] = bgs[j]; } for (i=col; i<col+n; i++) { ptr[i] = ' '; attrs[i] = CHARDRAWN | term->flags; fgs[i] = term->cur_foreground; bgs[i] = term->cur_background; } if (wrappedbit) attrs[0] |= LINEWRAPPED;}ScrnDeleteChar (sb, row, col, n, size) /* Deletes n characters in sb at row, col. Size is the size of each row. */ ScrnBuf sb; register int row, size; register int n, col;{ register Char *ptr = sb[4 * row]; register Char *attrs = sb[4 * row + 1]; register nbytes = (size - n - col); int wrappedbit = attrs[0]&LINEWRAPPED; bcopy (ptr + col + n, ptr + col, nbytes); bcopy (attrs + col + n, attrs + col, nbytes); bcopy (sb[4 * row + 2] + col + n, sb[4 * row + 2] + col, nbytes); bcopy (sb[4 * row + 3] + col + n, sb[4 * row + 3] + col, nbytes); bzero (ptr + size - n, n); bzero (attrs + size - n, n); bzero (sb[4 * row + 2] + size - n, n); bzero (sb[4 * row + 3] + size - n, n); if (wrappedbit) attrs[0] |= LINEWRAPPED;}ScrnRefresh (screen, toprow, leftcol, nrows, ncols, force)/* Repaints the area enclosed by the parameters. Requires: (toprow, leftcol), (toprow + nrows, leftcol + ncols) are coordinates of characters in screen; nrows and ncols positive. */register TScreen *screen;int toprow, leftcol, nrows, ncols;Boolean force; /* ... leading/trailing spaces */{ int y = toprow * FontHeight(screen) + screen->border + screen->fnt_norm->ascent; register int row; register int topline = screen->topline; int maxrow = toprow + nrows - 1; int scrollamt = screen->scroll_amt; int max = screen->max_row;#ifdef DEBUGGINGfprintf(stderr, "Entering ScrnRefresh.\ntoprow = %d leftcol = %d nrows = %d " "ncols = %d force = %c\n", toprow, leftcol, nrows, ncols, force ? 'T' : 'F' );#endif if(screen->cursor_col >= leftcol && screen->cursor_col <= (leftcol + ncols - 1) && screen->cursor_row >= toprow + topline && screen->cursor_row <= maxrow + topline) screen->cursor_state = OFF; for (row = toprow; row <= maxrow; y += FontHeight(screen), row++) { register Char *chars; register Char *attrs; register Char *fgs, *bgs; register int col = leftcol; int maxcol = leftcol + ncols - 1; int lastind; int flags; int fg, bg; int x, n; GC gc; Pixel fg_pix, bg_pix; Boolean hilite; if (row < screen->top_marg || row > screen->bot_marg) lastind = row; else lastind = row - scrollamt; if (lastind < 0 || lastind > max) continue; chars = screen->buf [4 * (lastind + topline)]; attrs = screen->buf [4 * (lastind + topline) + 1]; fgs = screen->buf [4 * (lastind + topline) + 2]; bgs = screen->buf [4 * (lastind + topline) + 3];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -