aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/xgterm/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/x11iraf/xgterm/screen.c')
-rw-r--r--vendor/x11iraf/xgterm/screen.c771
1 files changed, 771 insertions, 0 deletions
diff --git a/vendor/x11iraf/xgterm/screen.c b/vendor/x11iraf/xgterm/screen.c
new file mode 100644
index 00000000..0928daa9
--- /dev/null
+++ b/vendor/x11iraf/xgterm/screen.c
@@ -0,0 +1,771 @@
+/*
+ * $XConsortium: screen.c,v 1.33 94/04/02 17:34:36 gildea 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>
+#ifdef SVR4
+#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>
+#endif
+
+#ifdef MINIX
+#include <termios.h>
+#endif
+
+
+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 = (Char *)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.)
+ */
+static
+Reallocate(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 memmove here! */
+ memmove( *sbuf, *sbuf+move_up,
+ (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 = (Char *)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) {
+ memmove( tmp, base[i], 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, *attrs0, *fgs, *bgs;
+ register int avail = screen->max_col - screen->cur_col + 1;
+ register Char *col;
+ register int wrappedbit;
+
+ if (length > avail)
+ length = avail;
+ if (length <= 0)
+ return;
+
+ col = screen->buf[avail = 4 * screen->cur_row] + screen->cur_col;
+ attrs = attrs0 = screen->buf[avail + 1] + screen->cur_col;
+ fgs = screen->buf[avail + 2] + screen->cur_col;
+ bgs = screen->buf[avail + 3] + screen->cur_col;
+
+ wrappedbit = *attrs0&LINEWRAPPED;
+ flags &= ATTRIBUTES;
+ flags |= CHARDRAWN;
+ memmove( col, str, length);
+ while(length-- > 0)
+ {
+ *attrs++ = flags;
+ *fgs++ = cur_fg;
+ *bgs++ = cur_bg;
+ }
+ if (wrappedbit)
+ *attrs0 |= LINEWRAPPED;
+}
+
+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 */
+ memmove( (char *) save, (char *) &sb [4 * (last -= n - 1)],
+ 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:
+ *
+ * +--------|---------|----+
+ */
+ memmove( (char *) &sb [4 * (where + n)], (char *) &sb [4 * where],
+ 4 * sizeof (char *) * (last - where));
+
+ /* reuse storage for new lines at where */
+ memmove( (char *) &sb[4 * where], (char *)save, 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 */
+ memmove( (char *)save, (char *) &sb[4 * where], 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 */
+ memmove( (char *) &sb[4 * where], (char *) &sb[4 * (where + n)],
+ 4 * sizeof (char *) * ((last -= n - 1) - where));
+
+ /* reuse storage for new bottom lines */
+ memmove( (char *) &sb[4 * last], (char *)save,
+ 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];
+ 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];
+ }
+
+ for (i=col; i<col+n; i++)
+ ptr[i] = ' ';
+ for (i=col; i<col+n; i++)
+ attrs[i] = CHARDRAWN;
+
+ 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;
+
+ memmove( ptr + col, ptr + col + n, nbytes);
+ memmove( attrs + col, attrs + col + n, nbytes);
+ bzero (ptr + size - n, n);
+ bzero (attrs + 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;
+
+ 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];
+
+ if (row < screen->startHRow || row > screen->endHRow ||
+ (row == screen->startHRow && maxcol < screen->startHCol) ||
+ (row == screen->endHRow && col >= screen->endHCol))
+ {
+ /* row does not intersect selection; don't hilite */
+ if (!force) {
+ while (col <= maxcol && (attrs[col] & ~BOLD) == 0 &&
+ (chars[col] & ~040) == 0)
+ col++;
+
+ while (col <= maxcol && (attrs[maxcol] & ~BOLD) == 0 &&
+ (chars[maxcol] & ~040) == 0)
+ maxcol--;
+ }
+ hilite = False;
+ }
+ else {
+ /* row intersects selection; split into pieces of single type */
+ if (row == screen->startHRow && col < screen->startHCol) {
+ ScrnRefresh(screen, row, col, 1, screen->startHCol - col,
+ force);
+ col = screen->startHCol;
+ }
+ if (row == screen->endHRow && maxcol >= screen->endHCol) {
+ ScrnRefresh(screen, row, screen->endHCol, 1,
+ maxcol - screen->endHCol + 1, force);
+ maxcol = screen->endHCol - 1;
+ }
+ /* remaining piece should be hilited */
+ hilite = True;
+ }
+
+ if (col > maxcol) continue;
+
+ flags = attrs[col];
+ fg = fgs[col];
+ bg = bgs[col];
+
+ fg_pix = (flags & FG_COLOR) ? screen->colors[fg] :
+ screen->foreground;
+ bg_pix = (flags & BG_COLOR) ? screen->colors[bg] :
+ term->core.background_pixel;
+
+ if ( (!hilite && (flags & INVERSE) != 0) ||
+ (hilite && (flags & INVERSE) == 0) ) {
+ if (flags & BOLD) gc = screen->reverseboldGC;
+ else gc = screen->reverseGC;
+
+ if (term->misc.dynamicColors) {
+ XSetForeground(screen->display, gc, bg_pix);
+ XSetBackground(screen->display, gc, fg_pix);
+ }
+
+ } else {
+ if (flags & BOLD) gc = screen->normalboldGC;
+ else gc = screen->normalGC;
+
+ if (term->misc.dynamicColors) {
+ XSetForeground(screen->display, gc, fg_pix);
+ XSetBackground(screen->display, gc, bg_pix);
+ }
+ }
+
+ x = CursorX(screen, col);
+ lastind = col;
+
+ for (; col <= maxcol; col++) {
+ if (attrs[col] != flags ||
+ (term->misc.dynamicColors &&
+ ((flags & FG_COLOR && fgs[col] != fg) ||
+ (flags & BG_COLOR && bgs[col] != bg)))) {
+
+ XDrawImageString(screen->display, TextWindow(screen),
+ gc, x, y, (char *) &chars[lastind], n = col - lastind);
+ if((flags & BOLD) && screen->enbolden)
+ XDrawString(screen->display, TextWindow(screen),
+ gc, x + 1, y, (char *) &chars[lastind], n);
+ if((flags & UNDERLINE) && screen->underline)
+ XDrawLine(screen->display, TextWindow(screen),
+ gc, x, y+1, x+n*FontWidth(screen), y+1);
+
+ x += (col - lastind) * FontWidth(screen);
+
+ lastind = col;
+
+ flags = attrs[col];
+ fg = fgs[col];
+ bg = bgs[col];
+
+ fg_pix = (flags & FG_COLOR) ? screen->colors[fg]
+ : screen->foreground;
+ bg_pix = (flags & BG_COLOR) ? screen->colors[bg]
+ : term->core.background_pixel;
+
+ if ( (!hilite && (flags & INVERSE) != 0) ||
+ (hilite && (flags & INVERSE) == 0) ) {
+ if (flags & BOLD) gc = screen->reverseboldGC;
+ else gc = screen->reverseGC;
+
+ if (term->misc.dynamicColors) {
+ XSetForeground(screen->display, gc, bg_pix);
+ XSetBackground(screen->display, gc, fg_pix);
+ }
+ } else {
+ if (flags & BOLD) gc = screen->normalboldGC;
+ else gc = screen->normalGC;
+
+ if (term->misc.dynamicColors) {
+ XSetForeground(screen->display, gc, fg_pix);
+ XSetBackground(screen->display, gc, bg_pix);
+ }
+ }
+ }
+
+ if(chars[col] == 0)
+ chars[col] = ' ';
+ }
+
+
+ if ( (!hilite && (flags & INVERSE) != 0) ||
+ (hilite && (flags & INVERSE) == 0) ) {
+ if (flags & BOLD) gc = screen->reverseboldGC;
+ else gc = screen->reverseGC;
+
+ if (term->misc.dynamicColors) {
+ XSetForeground(screen->display, gc, bg_pix);
+ XSetBackground(screen->display, gc, fg_pix);
+ }
+
+ } else {
+ if (flags & BOLD) gc = screen->normalboldGC;
+ else gc = screen->normalGC;
+
+ if (term->misc.dynamicColors) {
+ XSetForeground(screen->display, gc, fg_pix);
+ XSetBackground(screen->display, gc, bg_pix);
+ }
+ }
+
+ XDrawImageString(screen->display, TextWindow(screen), gc,
+ x, y, (char *) &chars[lastind], n = col - lastind);
+ if((flags & BOLD) && screen->enbolden)
+ XDrawString(screen->display, TextWindow(screen), gc,
+ x + 1, y, (char *) &chars[lastind], n);
+ if((flags & UNDERLINE) && screen->underline)
+ XDrawLine(screen->display, TextWindow(screen), gc,
+ x, y+1, x + n * FontWidth(screen), y+1);
+ }
+}
+
+ClearBufRows (screen, first, last)
+/*
+ Sets the rows first though last of the buffer of screen to spaces.
+ Requires first <= last; first, last are rows of screen->buf.
+ */
+register TScreen *screen;
+register int first, last;
+{
+ first *= 4;
+ last = 4 * last + 3;
+ while (first <= last)
+ bzero (screen->buf [first++], (screen->max_col + 1));
+}
+
+/*
+ Resizes screen:
+ 1. If new window would have fractional characters, sets window size so as to
+ discard fractional characters and returns -1.
+ Minimum screen size is 1 X 1.
+ Note that this causes another ExposeWindow event.
+ 2. Enlarges screen->buf if necessary. New space is appended to the bottom
+ and to the right
+ 3. Reduces screen->buf if necessary. Old space is removed from the bottom
+ and from the right
+ 4. Cursor is positioned as closely to its former position as possible
+ 5. Sets screen->max_row and screen->max_col to reflect new size
+ 6. Maintains the inner border (and clears the border on the screen).
+ 7. Clears origin mode and sets scrolling region to be entire screen.
+ 8. Returns 0
+ */
+ScreenResize (screen, width, height, flags)
+ register TScreen *screen;
+ int width, height;
+ unsigned *flags;
+{
+ int rows, cols;
+ int border = 2 * screen->border;
+ int move_down_by;
+#if defined(sun) && !defined(SVR4)
+#ifdef TIOCSSIZE
+ struct ttysize ts;
+#endif /* TIOCSSIZE */
+#else /* sun */
+#ifdef TIOCSWINSZ
+ struct winsize ws;
+#endif /* TIOCSWINSZ */
+#endif /* sun */
+ Window tw = TextWindow (screen);
+
+ /* clear the right and bottom internal border because of NorthWest
+ gravity might have left junk on the right and bottom edges */
+ XClearArea (screen->display, tw,
+ width - screen->border, 0, /* right edge */
+ screen->border, height, /* from top to bottom */
+ False);
+ XClearArea (screen->display, tw,
+ 0, height - screen->border, /* bottom */
+ width, screen->border, /* all across the bottom */
+ False);
+
+ /* round so that it is unlikely the screen will change size on */
+ /* small mouse movements. */
+ rows = (height + FontHeight(screen) / 2 - border) /
+ FontHeight(screen);
+ cols = (width + FontWidth(screen) / 2 - border - screen->scrollbar) /
+ FontWidth(screen);
+ if (rows < 1) rows = 1;
+ if (cols < 1) cols = 1;
+
+ /* update buffers if the screen has changed size */
+ if (screen->max_row != rows - 1 || screen->max_col != cols - 1) {
+ register int savelines = screen->scrollWidget ?
+ screen->savelines : 0;
+ int delta_rows = rows - (screen->max_row + 1);
+
+ if(screen->cursor_state)
+ HideCursor();
+ if ( screen->alternate
+ && term->misc.resizeGravity == SouthWestGravity )
+ /* swap buffer pointers back to make all this hair work */
+ SwitchBufPtrs(screen);
+ if (screen->altbuf)
+ (void) Reallocate(&screen->altbuf, (Char **)&screen->abuf_address,
+ rows, cols, screen->max_row + 1, screen->max_col + 1);
+ move_down_by = Reallocate(&screen->allbuf,
+ (Char **)&screen->sbuf_address,
+ rows + savelines, cols,
+ screen->max_row + 1 + savelines,
+ screen->max_col + 1);
+ screen->buf = &screen->allbuf[4 * savelines];
+
+ screen->max_row += delta_rows;
+ screen->max_col = cols - 1;
+
+ if (term->misc.resizeGravity == SouthWestGravity) {
+ screen->savedlines -= move_down_by;
+ if (screen->savedlines < 0)
+ screen->savedlines = 0;
+ if (screen->savedlines > screen->savelines)
+ screen->savedlines = screen->savelines;
+ if (screen->topline < -screen->savedlines)
+ screen->topline = -screen->savedlines;
+ screen->cur_row += move_down_by;
+ screen->cursor_row += move_down_by;
+ ScrollSelection(screen, move_down_by);
+
+ if (screen->alternate)
+ SwitchBufPtrs(screen); /* put the pointers back */
+ }
+
+ /* adjust scrolling region */
+ screen->top_marg = 0;
+ screen->bot_marg = screen->max_row;
+ *flags &= ~ORIGIN;
+
+ if (screen->cur_row > screen->max_row)
+ screen->cur_row = screen->max_row;
+ if (screen->cur_col > screen->max_col)
+ screen->cur_col = screen->max_col;
+
+ screen->fullVwin.height = height - border;
+ screen->fullVwin.width = width - border - screen->scrollbar;
+
+ } else if(FullHeight(screen) == height && FullWidth(screen) == width)
+ return(0); /* nothing has changed at all */
+
+ if (screen->scrollWidget) {
+ if (term->misc.sb_right) {
+ ResizeScrollBar(screen->scrollWidget, width -
+ screen->scrollWidget->core.width -
+ screen->scrollWidget->core.border_width, 0, height -1);
+ } else {
+ ResizeScrollBar(screen->scrollWidget, -1, -1, height);
+ }
+ }
+
+ screen->fullVwin.fullheight = height;
+ screen->fullVwin.fullwidth = width;
+ ResizeSelection (screen, rows, cols);
+#if defined(sun) && !defined(SVR4)
+#ifdef TIOCSSIZE
+ /* Set tty's idea of window size */
+ ts.ts_lines = rows;
+ ts.ts_cols = cols;
+ ioctl (screen->respond, TIOCSSIZE, &ts);
+#ifdef SIGWINCH
+ if(screen->pid > 1) {
+ int pgrp;
+
+ if (ioctl (screen->respond, TIOCGPGRP, &pgrp) != -1)
+ kill_process_group(pgrp, SIGWINCH);
+ }
+#endif /* SIGWINCH */
+#endif /* TIOCSSIZE */
+#else /* sun */
+#ifdef TIOCSWINSZ
+ /* Set tty's idea of window size */
+ ws.ws_row = rows;
+ ws.ws_col = cols;
+ ws.ws_xpixel = width;
+ ws.ws_ypixel = height;
+ ioctl (screen->respond, TIOCSWINSZ, (char *)&ws);
+#ifdef notdef /* change to SIGWINCH if this doesn't work for you */
+ if(screen->pid > 1) {
+ int pgrp;
+
+ if (ioctl (screen->respond, TIOCGPGRP, &pgrp) != -1)
+ kill_process_group(pgrp, SIGWINCH);
+ }
+#endif /* SIGWINCH */
+#endif /* TIOCSWINSZ */
+#endif /* sun */
+ return (0);
+}
+
+/*
+ * Sets the attributes from the row, col, to row, col + length according to
+ * mask and value. The bits in the attribute byte specified by the mask are
+ * set to the corresponding bits in the value byte. If length would carry us
+ * over the end of the line, it stops at the end of the line.
+ */
+void
+ScrnSetAttributes(screen, row, col, mask, value, length)
+TScreen *screen;
+int row, col;
+unsigned mask, value;
+register int length; /* length of string */
+{
+ register Char *attrs;
+ register int avail = screen->max_col - col + 1;
+
+ if (length > avail)
+ length = avail;
+ if (length <= 0)
+ return;
+ attrs = screen->buf[4 * row + 1] + col;
+ value &= mask; /* make sure we only change the bits allowed by mask*/
+ while(length-- > 0) {
+ *attrs &= ~mask; /* clear the bits */
+ *attrs |= value; /* copy in the new values */
+ attrs++;
+ }
+}
+
+/*
+ * Gets the attributes from the row, col, to row, col + length into the
+ * supplied array, which is assumed to be big enough. If length would carry us
+ * over the end of the line, it stops at the end of the line. Returns
+ * the number of bytes of attributes (<= length)
+ */
+int
+ScrnGetAttributes(screen, row, col, str, length)
+TScreen *screen;
+int row, col;
+Char *str;
+register int length; /* length of string */
+{
+ register Char *attrs;
+ register int avail = screen->max_col - col + 1;
+ int ret;
+
+ if (length > avail)
+ length = avail;
+ if (length <= 0)
+ return 0;
+ ret = length;
+ attrs = screen->buf[4 * row + 1] + col;
+ while(length-- > 0) {
+ *str++ = *attrs++;
+ }
+ return ret;
+}
+Bool
+non_blank_line(sb, row, col, len)
+ScrnBuf sb;
+register int row, col, len;
+{
+ register int i;
+ register Char *ptr = sb [4 * row];
+
+ for (i = col; i < len; i++) {
+ if (ptr[i])
+ return True;
+ }
+ return False;
+}