grotwin (Part 4 of 7)
nwh at hrc63.UUCP
nwh at hrc63.UUCP
Sat Jul 12 00:06:36 AEST 1986
#! /bin/sh
# This is a shell archive. To extract the files type 'sh file'
# This archive created on Thu Jul 10 13:33:09 WET 1986
echo 'shar: extracting 'window.c' ( 15624 characters)'
if test -f 'window.c'
then
echo "shar: will not overwrite existing file 'window.c'"
else
cat << \SHAR_EOF > 'window.c'
#ifndef lint
static char sccsid[] = "@(#)window.c 2.2 [ (C) Nigel Holder 1986 ]";
#endif
/***************************************
*
* Author : Nigel Holder
*
* Date : 10 July 1986
*
*
* Copyright (C) 1986 by Nigel Holder
*
* Permission to use this program is granted, provided it is not
* sold, or distributed for direct commercial advantage, and includes
* the copyright notice and this clause.
*
* Grotwin - provides a somewhat primitive windowing capability
* for people unfortunate enough to use the standard 24 x 80 type
* of terminal when the console is in use. Definitely written for
* 4.[2,3] at the present time, as Sys V.2 does not cater for pseudo
* terminals or have the select() facility (amongst other things !)
* (version 8 should fix this).
*
* Files used :-
*
* grotwin.c - window system initialisation
* deals with startup files
*
* manager.c - window manager
* deals with input and output
*
* window.c - window manipulator
* deals with aspects concerning windows
* during normal usage
*
* update.c - simulates dumb terminal for use
* with window manager.
*
* grotwin.h - header file for above
*
* utmp.c - utmp manipulator
* updates utmp entries for each window
*
* grotwin.make - makefile for above
*
* Bugs :-
*
* Can't have the situation where no windows are present !
* Needs a vt100 like terminal type
*
***************************************/
#include <sys/ioctl.h>
#include "grotwin.h"
/* externals defined in grotwin.c */
/* list of priorities - end referenced by tail variable */
extern struct windowdetails win[MAX_WINDOWS_PLUS];
extern int window_priorities[]; /* window details */
extern int **screen_priority; /* which window visible at each point */
extern int active_windows; /* number of user windows active */
extern int screenlines; /* lines on users screen */
extern int screencolumns; /* columns on users screen */
extern int time_start; /* where time string is placed */
extern int time_end; /* where time string ends */
extern int win_border; /* window border characteristic */
extern int timeon; /* display clock on top edge */
extern char **masterscreen; /* hook to stdscr from curses */
extern char *progname; /* program name stripped of any /'s */
extern char *home_shell; /* shell from users $SHELL variable */
extern char nottimestring[]; /* used when time is not displayed */
int tail = 0; /* tail of window priority list */
/* create instance of window */
createwin(winno, lines, columns, ystart, xstart)
int winno, lines, columns, ystart, xstart;
{
register struct windowdetails *ptr;
char **virtwin(), *rindex(), *tty;
ptr = &(win[winno]);
/* remember that a border surrounds window */
ptr->lines = lines - 2;
ptr->columns = columns - 2;
ptr->y_start = ystart + 1;
ptr->x_start = xstart + 1;
ptr->y_end = ptr->y_start + ptr->lines;
ptr->x_end = ptr->x_start + ptr->columns;
ptr->y_current = 0;
ptr->x_current = 0;
ptr->screenptr = virtwin('\0');
win_initialise(winno, ' ');
/* skip pass "/dev/" */
tty = 1 + rindex(ptr->pseudo_ttyname, '/');
utmp_insert(tty, progname);
ptr->page_buf_length = 0;
strcpy(ptr->page_buf, "");
ptr->output_blocked = FALSE;
ptr->output_paged = FALSE;
ptr->paged_page_full = FALSE;
ptr->line_count = 0;
ptr->overwrite = FALSE;
ptr->cursor_addressing = FALSE;
ptr->cursor_addr_passes = 0;
ptr->cursor_addr_row = 0;
ptr->standout_mode = WIN_STANDEND;
ptr->readgrain = (ptr->lines / READGRAIN) * ptr->columns;
if (ptr->readgrain > BUFSIZ) {
ptr->readgrain = BUFSIZ;
}
ptr->active = TRUE;
++active_windows;
top_dog(winno);
/* place cursor in new window */
wmove(stdscr, ptr->y_current + ptr->y_start,
ptr->x_current + ptr->x_start);
touchwin(stdscr);
wrefresh(stdscr);
}
/* provide user with half screen height window at near full screen width */
new_window()
{
static int i = OVERLAY - 1;
int columns, rows, xstart, ystart, new_winno;
i = (i + 1) % OVERLAY;
columns = screencolumns - (OVERLAY * 2);
rows = screenlines / 2;
/* offset slightly to enable multpile instances to be seen */
xstart = (i + 1) * 2;
ystart = (rows / 2) + i;
check_size(&columns, &rows, &xstart, &ystart);
new_winno = win_instance(rows, columns, ystart, xstart, home_shell);
if (new_winno != -1) {
next_input_window(new_winno);
}
else {
write(1, "\007", 1);
}
}
/* allocate a window screen to hold characters and initialise it */
char **
virtwin(filler)
char filler;
{
char *calloc();
register int line, x;
register char **virt_ptr, *lineptr;
virt_ptr = (char **) calloc(screenlines, sizeof (char *));
for (line = 0 ; line < screenlines ; ++line) {
virt_ptr[line] = calloc(screencolumns, sizeof(char));
lineptr = virt_ptr[line];
for (x = 0 ; x < screencolumns ; ++x) {
lineptr[x] = filler;
}
}
return(virt_ptr);
}
free_virt_win(virt_ptr) /* return structure to free list */
char **virt_ptr;
{
int line;
for (line = 0 ; line < screenlines ; ++line) {
free(virt_ptr[line]);
}
free(virt_ptr);
}
/*******************
* Screen priority positions to decide display areas.
* Originally declared via virtwin(), but has been changed to use
* ints (instead of chars) to hopefully speed it up (by requiring less
* conversions to ints for comparisons etc.).
*******************/
int **
priority_win()
{
char *calloc();
register int x, *lineptr, **priority_ptr, line;
priority_ptr = (int **) calloc(screenlines, sizeof (int *));
for (line = 0 ; line < screenlines ; ++line) {
priority_ptr[line] = (int *) calloc(screencolumns, sizeof(int));
lineptr = priority_ptr[line];
for (x = 0 ; x < screencolumns ; ++x) {
lineptr[x] = -1;
}
}
return(priority_ptr);
}
free_priority_win(priority_ptr) /* return structure to free store */
int **priority_ptr;
{
register int line;
for (line = 0 ; line < screenlines ; ++line) {
free(priority_ptr[line]);
}
free(priority_ptr);
}
/* fill window with specified fill pattern (usually a ' ') */
win_initialise(winno, filler)
int winno;
char filler;
{
register char *lineptr;
register int x, y;
register int y_end, x_end;
register struct windowdetails *ptr;
int y_start, x_start;
ptr = &(win[winno]);
y_start = ptr->y_start;
x_start = ptr->x_start;
y_end = ptr->y_end;
x_end = ptr->x_end;
/* fill window with filler */
for (y = y_start ; y < y_end ; ++y) {
lineptr = ptr->screenptr[y];
for (x = x_start ; x < x_end ; ++x) {
lineptr[x] = filler;
}
}
border(winno, BOX);
}
border(winno, command) /* place box around window */
int winno, command;
{
register struct windowdetails *ptr;
register int x, y, y_end, x_end;
int top, side, y_start, x_start;
char winid;
if (command == BOX) {
top = '-' | win_border;
side = '|' | win_border;
}
else { /* NOT_BOX */
top = ' ';
side = ' ';
}
ptr = &(win[winno]);
y_start = ptr->y_start - 1;
x_start = ptr->x_start - 1;
y_end = ptr->y_end;
x_end = ptr->x_end;
/* side of box */
for (y = y_start + 1; y < y_end ; ++y) {
ptr->screenptr[y][x_start] = side;
ptr->screenptr[y][x_end] = side;
}
/* top and bottom */
for (x = x_start + 1 ; x < x_end ; ++x) {
ptr->screenptr[y_start][x] = top;
ptr->screenptr[y_end][x] = top;
}
ptr->screenptr[y_start][x_start] = ' ';
ptr->screenptr[y_start][x_end] = ' ';
ptr->screenptr[y_end][x_start] = ' ';
ptr->screenptr[y_end][x_end] = ' ';
/* place window number in top corners (ish) */
if (winno < MAX_WINDOWS && top != ' ') {
winid = '0' + winno;
ptr->screenptr[y_start][x_start + 3] = winid;
ptr->screenptr[y_start][x_end - 3] = winid;
}
}
/* make window topmost one and adjust visibility priority list accordingly */
top_dog(winno)
int winno;
{
register struct windowdetails *ptr;
register int x, *line_priority;
register char *lineptr, *masterline;
int y, y_start, x_start, y_end, x_end, start, i;
ptr = &(win[winno]);
y_start = ptr->y_start - 1;
x_start = ptr->x_start - 1;
y_end = ptr->y_end;
x_end = ptr->x_end;
/* ensure that time is not overwritten on top border */
if (y_start == 0) {
lineptr = ptr->screenptr[0];
line_priority = screen_priority[0];
masterline = masterscreen[0];
for (x = x_start ; x <= x_end ; ++x) {
if (x < time_start || x > time_end) {
line_priority[x] = winno;
masterline[x] = lineptr[x];
}
else {
nottimestring[x - time_start] = lineptr[x];
line_priority[x] = winno;
if (timeon == FALSE) {
masterline[x] = lineptr[x];
}
}
}
++y_start;
}
for (y = y_start ; y <= y_end ; ++y) {
lineptr = ptr->screenptr[y];
line_priority = screen_priority[y];
masterline = masterscreen[y];
for (x = x_start; x <= x_end ; ++x) {
line_priority[x] = winno;
masterline[x] = lineptr[x];
}
}
/* find window in list */
for (i = 0 ; i < tail ; ++i) {
if (window_priorities[i] == winno) {
break;
}
}
if (i == tail) { /* new window */
++tail;
}
/* push down priorities and place latest on top */
while (i > 0) {
window_priorities[i] = window_priorities[i - 1];
--i;
}
window_priorities[0] = winno;
}
/*******************
* Either make window backmost one or remove completely by
* making window lie behind fixed screen background window.
* Adjust visibility priority list accordingly.
*******************/
bottom_dog(winno, status)
int winno, status;
{
register struct windowdetails *ptr;
register int x, *line_priority;
register char *lineptr, *masterline;
int y, i, j, start, end;
/* find position in list */
for (start = 0 ; start < tail ; ++start) {
if (window_priorities[start] == winno) {
break;
}
}
if (status == HIDE) {
end = tail - 2;
}
else { /* REMOVE */
end = tail - 1;
--tail; /* since window no longer exists */
}
/* move up and place winno in list */
for (i = start ; i < end ; ++i) {
window_priorities[i] = window_priorities[i + 1];
}
window_priorities[end] = winno;
/* dumb removal of window whilst maintaining window priorities */
ptr = &(win[winno]);
for (i = tail - 1 ; i >= 0 ; --i) {
j = window_priorities[i];
for (y = ptr->y_start - 1 ; y <= ptr->y_end ; ++y) {
lineptr = win[j].screenptr[y];
line_priority = screen_priority[y];
masterline = masterscreen[y];
for (x = ptr->x_start - 1 ; x <= ptr->x_end ; ++x) {
/* ensure that time is not overwritten */
if (y == 0 && x >= time_start && x <= time_end){
if (lineptr[x] != '\0') {
nottimestring[x - time_start] =
lineptr[x];
}
if (timeon == TRUE) {
continue;
}
}
if (lineptr[x] != '\0') {
line_priority[x] = j;
masterline[x] = lineptr[x];
}
}
}
}
}
top_corners(winno) /* expose top corners of a window */
int winno;
{
register struct windowdetails *ptr;
register int y, x;
int diff;
ptr = &(win[winno]);
y = ptr->y_start - 1;
x = ptr->x_start - 1;
diff = ptr->x_end - x;
/* for both top corners */
for ( ; x <= ptr->x_end ; x += diff) {
if (screen_priority[y][x] == winno) {
if (y == 0) { /* check for overwriting time */
if (x >= time_start && x <= time_end) {
nottimestring[x - time_start] =
ptr->screenptr[y][x];
if (timeon == TRUE) {
continue;
}
}
}
masterscreen[y][x] = ptr->screenptr[y][x];
}
}
}
/*******************
* Doesn't check if widen action will have any effect. This allows
* user to send SIGWINCH to process if he really wants to.
*******************/
widen_window(winno, direction)
int winno, direction;
{
struct windowdetails *ptr;
int old_x_start, old_x_end, x_diff, x;
int old_y_start, old_y_end, y_diff, y;
char **virtwin(), **old_screenptr;
ptr = &(win[winno]);
border(winno, NOT_BOX); /* remove window border */
bottom_dog(winno, REMOVE); /* remove window */
if (direction == HORIZONTAL_EXPAND) {
y_diff = 0;
old_x_start = ptr->x_start; /* set up new x size */
old_x_end = ptr->x_end;
ptr->x_start = 1;
x_diff = old_x_start - ptr->x_start;
ptr->columns = screencolumns - 2;
ptr->x_end = ptr->x_start + ptr->columns;
}
else { /* VERTICAL_EXPAND */
x_diff = 0;
old_y_start = ptr->y_start; /* set up y new size */
old_y_end = ptr->y_end;
ptr->y_start = 1;
y_diff = old_y_start - ptr->y_start;
ptr->lines = screenlines - 2;
ptr->y_end = ptr->y_start + ptr->lines;
}
check_size(&ptr->columns, &ptr->lines, &ptr->x_start, &ptr->y_start);
/* copy old window contents to new window */
old_screenptr = ptr->screenptr;
ptr->screenptr = virtwin('\0');
win_initialise(winno, ' ');
if (direction == HORIZONTAL_EXPAND) {
for (y = ptr->y_start ; y < ptr->y_end ; ++y) {
for (x = old_x_start ; x < old_x_end ; ++ x) {
ptr->screenptr[y][x - x_diff] =
old_screenptr[y][x];
}
}
}
else { /* VERTICAL_EXPAND */
for (y = old_y_start ; y < old_y_end ; ++y) {
for (x = ptr->x_start ; x < ptr->x_end ; ++ x) {
ptr->screenptr[y - y_diff][x] =
old_screenptr[y][x];
}
}
}
top_dog(winno);
next_input_window(winno);
/*******************
* place cusor in window - can't rely on manager() to do this
* with input_changed flag since it may be servicing output before
* input_changed check is performed again !
*******************/
wmove(stdscr, ptr->y_current + ptr->y_start,
ptr->x_current + ptr->x_start);
free_virt_win(old_screenptr);
/* set new (?) tty size */
set_tty_size(ptr->slavefd, ptr->lines, ptr->columns, TRUE);
}
window_info(winno) /* display information about windows */
int winno;
{
static char command_string[] =
"[ w or 0-9 for next window, return to exit ] ";
int found;
char c;
while (1) {
selected_window_info(winno);
fputs(command_string, stdout);
fflush(stdout);
do {
read(1, &c, 1);
if (c == '\r' || c == '\n') {
return(FALSE);
}
found = FALSE;
if (c == 'w') {
do {
winno = (winno + 1) % MAX_WINDOWS;
} while (win[winno].active == FALSE);
found = TRUE;
}
else {
winno = c - '0';
if (winno >= 0 && winno <= MAX_WINDOWS) {
if (win[winno].active == TRUE) {
found = TRUE;
}
}
else {
winno += '0'; /* restore */
}
}
if (found == TRUE) { /* remove command */
clear_line(sizeof(command_string));
}
else { /* indicate error */
write(1, "\007", 1);
}
} while (found != TRUE);
}
}
static
selected_window_info(winno) /* display dumbly status of a window */
int winno;
{
struct windowdetails *ptr;
char *status(), *truth_status();
ptr = &(win[winno]);
printf("\r\nstatus information for window %d\r\n\n", winno);
printf(" tty name - %s\r\n", ptr->pseudo_ttyname);
printf(" lines - %-6d\r\n", ptr->lines);
printf(" columns - %-6d\r\n", ptr->columns);
printf(" running - %s [ pid = %d ]\r\n",
ptr->progy, ptr->slavepid);
printf(" XOFF - %s\r\n", status(ptr->output_blocked));
printf(" page mode - %s\r\n", status(ptr->output_paged));
if (ptr->output_paged) {
printf("page mode full - %s\r\n",
truth_status(ptr->paged_page_full));
}
printf("page overwrite - %s\r\n", status(ptr->overwrite));
putchar('\n');
}
char *
status(expr)
int expr;
{
if (expr) {
return("ON");
}
else {
return("OFF");
}
}
char *
truth_status(expr)
int expr;
{
if (expr) {
return("TRUE");
}
else {
return("FALSE");
}
}
SHAR_EOF
if test 15624 -ne `wc -c < 'window.c'`
then
echo 'shar: error transmitting 'window.c' (should have been 15624 charcaters)'
fi
fi
exit
Nigel Holder UK JANET: yf21 at uk.co.gec-mrc.u
Marconi Research, ARPA: yf21%u.gec-mrc.co.uk at ucl-cs
Chelmsford,
Essex. CM2 8HN.
+44 245 73331 ext. 3219 / 3214
More information about the Comp.sources.unix
mailing list