wm - a window manager (part 2 of 4)
sources-request at genrad.UUCP
sources-request at genrad.UUCP
Sun Aug 4 00:06:22 AEST 1985
Mod.sources: Volume 2, Issue 32
Submitted by: Tom Truscott <decvax!mcnc!rti-sel!trt>
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# Makefile
# wm.h
# cmd.c
# curses.c
# getch.c
# hacks.c
# help.c
# This archive created: Fri Aug 2 13:13:15 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(2215 characters)'
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
#
# Makefile for wm
#
# Flags for the C compiler.
CFLAGS = -O
# Flags for loader. You probably do not need any.
LDFLAGS =
# Final resting place of wm executable.
BIN = /usr/local
# Name of owner and group that you want installed wm to have.
OWNER = bin
GROUP = bin
# Version of libcurses wm is linked with. This *must* be
# the version that is distributed with wm, since it contains
# several bug fixes necessary to the correct operation of wm.
LIBS = -lcurses -ltermcap
OBJS = cmd.o curses.o getch.o hacks.o help.o misc.o \
save.o shell.o vterm.o wlist.o wm.o
XSRCS = cmd.c curses.c getch.c hacks.c help.c misc.c \
save.c shell.c vterm.c wlist.c wm.c
wm: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o wm
$(OBJS): wm.h
lint:
lint -hbux $(SRCS)
clean:
/bin/rm -f *.o wm core *.out
install: wm
install -o $(OWNER) -g $(GROUP) -s wm $(DESTDIR)/$(BIN)
depend:
cat </dev/null >x.c
for i in ${SRCS}; do \
(echo `basename $$i .c`.o: $$i >>makedep; \
/bin/grep '^#[ ]*include' x.c $$i | sed \
-e 's,<\(.*\)>,"/usr/include/\1",' \
-e 's/:[^"]*"\([^"]*\)".*/: \1/' \
-e 's/\.c/.o/' >>makedep); done
echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
echo '$$r makedep' >>eddep
echo 'w' >>eddep
cp Makefile Makefile.bak
ed - Makefile < eddep
rm eddep makedep x.c
echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
echo '# see make depend above' >> Makefile
# DO NOT DELETE THIS LINE -- make depend uses it
cmd.o: cmd.c
cmd.o: wm.h
curses.o: curses.c
curses.o: wm.h
getch.o: getch.c
getch.o: wm.h
getch.o: /usr/include/signal.h
getch.o: /usr/include/setjmp.h
getch.o: /usr/include/sys/time.h
hacks.o: hacks.c
hacks.o: wm.h
help.o: help.c
help.o: wm.h
misc.o: misc.c
misc.o: wm.h
save.o: save.c
save.o: wm.h
shell.o: shell.c
shell.o: wm.h
shell.o: /usr/include/signal.h
shell.o: /usr/include/errno.h
vterm.o: vterm.c
vterm.o: wm.h
wlist.o: wlist.c
wlist.o: wm.h
wm.o: wm.c
wm.o: wm.h
wm.o: /usr/include/signal.h
wm.o: /usr/include/sys/wait.h
wm.o: /usr/include/sys/time.h
wm.o: /usr/include/sys/resource.h
# DEPENDENCIES MUST END AT END OF FILE
# IF YOU PUT STUFF HERE IT WILL GO AWAY
# see make depend above
SHAR_EOF
if test 2215 -ne "`wc -c < 'Makefile'`"
then
echo shar: error transmitting "'Makefile'" '(should have been 2215 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'wm.h'" '(6227 characters)'
if test -f 'wm.h'
then
echo shar: will not over-write existing file "'wm.h'"
else
sed 's/^X//' << \SHAR_EOF > 'wm.h'
/*
*************
* DISTRIBUTION NOTICE July 30 1985
* A Revised Edition of WM, by Matt Lennon and Tom Truscott,
* Research Triangle Institute, (919) 541-7005.
* Based on the original by Robert Jacob (decvax!nrl-css!jacob),
* Naval Research Laboratory, (202) 767-3365.
* No claims or warranties of any sort are made for this distribution.
* General permission is granted to copy, but not for profit,
* any of this distribution, provided that this notice
* is always included in the copies.
*************
*/
/*
* definitions for wm
*/
#include "curses.h"
#include <sys/types.h>
#include <ctype.h>
#define CURSEASSIST /* give curses a hand, sigh. */
#define SET_WINDOW /* assist all-wonderful scrolling rectangles */
#define GAGMEKEYPAD /* gross hack for arrow keys */
/*#define SNEAKYTERMCAP /* /tmp termcap kludge */
/* define TERMINFO if we are using a terminfo version of curses */
#ifdef A_STANDOUT
#define TERMINFO
#endif
#ifdef TERMINFO
/* define FASTTERMINFO if your terminfo has a clever doupdate */
/*#define FASTTERMINFO /**/
/* define BUGGYTERMINFO if your terminfo has 'certain bugs' */
#define BUGGYTERMINFO /**/
#endif
/*
* Definitions for curses
*/
#define wcury(w) ((w)->_cury) /* current (y,x) in window w */
#define wcurx(w) ((w)->_curx)
#define wbegy(w) ((w)->_begy) /* window offset from origin */
#define wbegx(w) ((w)->_begx)
#define wlines(w) ((w)->_maxy) /* # lines/cols in window w */
#define wcols(w) ((w)->_maxx)
#define cursrow() wcury(curscr) /* current (y,x) on screen */
#define curscol() wcurx(curscr)
/* stuff dependent on the version of curses */
#ifdef TERMINFO
#undef GAGMEKEYPAD
#ifdef FASTTERMINFO
#undef CURSEASSIST
#endif
#undef wlines
#undef wcols
#define wlines(w) ((w)->_maxy+1) /* # lines/cols in window w */
#define wcols(w) ((w)->_maxx+1)
#include <term.h>
/* undefine one of the more annoying definitions in term.h */
#ifdef lines
#undef lines
#endif
extern WINDOW *newscr;
#define Untouchwin(wp) untouchwin(wp),untouchwin(newscr)
#ifdef CURSEASSIST
/* curseassist cheats big */
#define Cmove(y,x) wmove(curscr,y,x),wmove(newscr,y,x)
#define Cinsertln() winsertln(curscr),winsertln(newscr)
#define Cdeleteln() wdeleteln(curscr),wdeleteln(newscr)
#endif
#else
extern int *_putchar();
#define putp _puts
#define enter_ca_mode TI
#define cursor_address CM
#define flash_screen VB
#define enter_standout_mode SO
#define exit_standout_mode SE
#define move_standout_mode MS
#define insert_line AL
#define delete_line DL
#define change_scroll_region CS
#define scroll_reverse SR
#define save_cursor SC
#define restore_cursor RC
#define insert_character IC
#define insert_null_glitch IN
#define enter_insert_mode IM
#define exit_insert_mode EI
#define delete_character DC
#define scroll_forward NL
#define cursor_down DO
#define cursor_up UP
#define Untouchwin(wp) untouchwin(wp)
#ifdef CURSEASSIST
/* curseassist cheats big */
#define Cmove(y,x) wmove(curscr,y,x)
#define Cinsertln() winsertln(curscr)
#define Cdeleteln() wdeleteln(curscr)
#endif
#endif
/* key pad atrocities follow */
extern char tty_text[], keycap[];
extern int tty_textlen, tty_backcnt;
#ifndef KEY_BACKSPACE
#define KEY_BACKSPACE 0401
#define KEY_UP 0402
#define KEY_DOWN 0403
#define KEY_LEFT 0404
#define KEY_RIGHT 0405
#define KEY_HOME 0406
#endif
#ifndef GAGMEKEYPAD
#define tty_getch tty_realgetch
#endif
/*
* The number of active windows is limited by the number of
* open files a process (i.e., main) may have,
* the number of processes a user or the whole system can have,
* and (on an 11 but not a VAX) the memory for the per-window curses buffers.
* Also, window names are limited to 0..9, i.e. at most 10 windows.
*/
#define MAXWINDOWS 10 /* windows #0..#9 */
#define ESC '\033' /* char for virtual terminal functions */
#define CANCEL1 '\033' /* char to cancel wm command */
#define CANCEL2 '\177' /* char to cancel wm command */
#define MINWINDOW 1 /* change this to 0 to permit window #0 */
#define iswindow(w) ((w)>=MINWINDOW && (w)<MAXWINDOWS && (win[w].flags&INUSE))
#define ctoi(c) ((c)-'0') /* convert ascii digit to int */
#define itoc(i) ((i)+'0') /* convert int to ascii digit */
/*
* Global data with miscellaneous information about each window
*/
struct win_struct
{
int flags; /* window status bits */
#define INUSE 001 /* window is in use */
#define XFLEX 002 /* # of columns is COLS (depends on terminal type) */
#define YFLEX 004 /* # of rows is ROWS ( "" "" "" "" ) */
#define FAST 010 /* window can scroll 'quickly' (not redrawn) */
#define BROWSE 020 /* window is in 'browse' mode */
#define BLOCKED 040 /* window updates are being delayed */
int next; /* next window in list */
char covers[MAXWINDOWS]; /* TRUE for windows we're on top of */
WINDOW *wptr; /* ptr to small curses win to be displayed */
WINDOW *boxbot, *boxtop; /* ptrs to curses wins for box, or NULL */
WINDOW *boxright, *boxleft; /* ptrs to curses wins for box, or NULL */
char pend[4]; /* characters in partial escape sequence */
int pid; /* pid of this window's shell */
int pty; /* fildes of pty to/from this win's shell */
};
/*
* Handy macros
*/
#define MAX(a,b) ((a)>=(b)? (a): (b))
#define MIN(a,b) ((a)<=(b)? (a): (b))
/*
* External variables.
*/
extern struct win_struct win[]; /* array of windows */
extern int botw, topw, lastw; /* bottom, top, last window */
extern int prefix; /* WM command prefix character */
extern char savefile[]; /* name of save/restore file */
extern char shellname[]; /* name of shell */
extern char shellpgm[]; /* pathname of shell */
extern int configflag; /* true if window config. has changed */
extern time_t msgbirth; /* time last message was displayed */
#ifndef TERMINFO
extern char *change_scroll_region, *save_cursor, *restore_cursor;
extern char *set_window;
#endif
extern int has_scroll_window, has_scroll_region, has_insdel_line;
/*
* Functions returning a non-int value
*/
XFILE *fopen();
char *sprintf(), *strcpy(), *strcat(), *rindex(), *getenv();
char *mkprint(), *termcap(), *WPrompt(), *plural();
double *Malloc(); /* if only malloc were declared this way */
#define alloc(n,type) ((type*)Malloc((unsigned)((n)*sizeof(type))))
SHAR_EOF
if test 6227 -ne "`wc -c < 'wm.h'`"
then
echo shar: error transmitting "'wm.h'" '(should have been 6227 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'cmd.c'" '(7983 characters)'
if test -f 'cmd.c'
then
echo shar: will not over-write existing file "'cmd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'cmd.c'
/*
*************
* DISTRIBUTION NOTICE July 30 1985
* A Revised Edition of WM, by Matt Lennon and Tom Truscott,
* Research Triangle Institute, (919) 541-7005.
* Based on the original by Robert Jacob (decvax!nrl-css!jacob),
* Naval Research Laboratory, (202) 767-3365.
* No claims or warranties of any sort are made for this distribution.
* General permission is granted to copy, but not for profit,
* any of this distribution, provided that this notice
* is always included in the copies.
*************
*/
/*
* Command interpreter for WM.
*/
#include "wm.h"
/*
* Command definitions
*/
# define DUMPWINDOW 'd' /* dump contents of current window to file */
# define FITWINDOW 'f' /* Find best unobscured place for a window */
# define HELP2 'h' /* Command summary */
# define HELP1 '?' /* Command summary */
# define IDENTWINDOW 'i' /* print name of current window */
# define KILLWINDOW 'k' /* get rid of this window forever */
# define LASTWINDOW 'l' /* change to Last-used window */
# define MOVEWINDOW 'm' /* Move locn and/or change size of window */
# define NEWWINDOW 'n' /* make New window */
# define PREFIX 'p' /* change prefix character */
# define QUIT 'q' /* close up everything and Quit */
# define REDRAW 'r' /* Redraw all windows */
# define SAVEWINDOWS 's' /* save current window configuration */
# define TERMCAP 't' /* Reset $TERM and $TERMCAP of current window */
# define SUSPEND 'z' /* suspend wm */
# define NOOP1 ' ' /* no-op */
# define NOOP2 '\n' /* no-op */
# define NOOP3 '\r' /* no-op */
/*
* Execute a WM command.
*/
docmd(cmd)
int cmd; /* IN: command code */
{
register int w, tmpw;
int begline, begcol, lines, cols; /* window parameters */
char *s;
register WINDOW *wp;
switch (cmd)
{
case CANCEL1:
case CANCEL2:
showmsg("Canceled.");
break;
case NEWWINDOW:
tmpw = topw;
if ((w = GetSlot()) < 0) {
showmsg("Sorry, can't create any more windows.");
break;
}
if (NewWindow(w,LINES-1,COLS,0,0))
break;
WListAdd(w);
if (getbounds(w, TRUE) != 0)
break; /* getbounds will have freed the window */
lastw = tmpw;
showmsg("Created new window #%d.", w);
winchanged(w);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
w = ctoi(cmd);
if ( ! iswindow(w))
showmsg("No such window #%d.", w);
else if (w == topw)
showmsg("You're already in window #%d.", w);
else
{
lastw = topw;
WListDelete(w);
WListAdd(w);
RedrawScreen();
showmsg("Changed to window #%d.", w);
}
break;
case LASTWINDOW:
if (iswindow(lastw) && lastw!=topw)
{
w=lastw;
lastw=topw;
WListDelete(w);
WListAdd(w);
RedrawScreen();
showmsg("Changed back to window #%d.", w);
}
else
showmsg("No last window.");
break;
case MOVEWINDOW:
w = topw;
wp = win[w].wptr;
lines = wlines(wp); cols = wcols(wp);
begline = wbegy(wp); begcol = wbegx(wp);
if (getbounds(w, FALSE) != 0)
break;
wp = win[w].wptr;
if (lines == wlines(wp) && cols == wcols(wp)) {
if (begline == wbegy(wp) && begcol == wbegx(wp)) {
showmsg("Window unchanged.");
break;
}
}
else
SetTerm(w, 2);
showmsg("Moved window #%d.", w);
winchanged(w);
break;
case FITWINDOW:
showmsg("Fit which window?");
if ((w = askwindow()) < 0)
break;
if (fitwindow(w, &lines, &cols, &begline, &begcol) < 0) {
showmsg("Sorry, cannot find unobscured placement.");
break;
}
wp = win[w].wptr;
tmpw = 1; /* shameless misuse of variable */
if (lines == wlines(wp) && cols == wcols(wp)) {
tmpw = 0;
if (begline == wbegy(wp) && begcol == wbegx(wp)) {
showmsg("Window already has best fit.");
break;
}
}
if (NewWindow(w,lines,cols,begline,begcol)) {
WListDelete(w);
break;
}
if (tmpw)
SetTerm(w, 2);
RedrawScreen();
showmsg("Moved window #%d.", w);
winchanged(w);
break;
case KILLWINDOW:
showmsg("Kill which window?"); /* enter window name */
if ((w = askwindow()) < 0)
break;
if (w==topw)
{
showmsg("Can't kill the current window.");
break;
}
WListDelete(w); KillShell(w); FreeWindow(w);
RedrawScreen();
showmsg("Killed window #%d.", w);
if (w==lastw) lastw = -1;
configflag = TRUE;
break;
case IDENTWINDOW:
IdentWindows();
break;
case DUMPWINDOW:
if ((s = WPrompt("dump file", "wmdump")) == NULL)
break;
else if (DumpWindow(topw, s) == 0)
showmsg("Dumped contents of top window to file '%s'.", s);
else
showmsg("Sorry, can't open dump file '%s'.", s);
break;
case REDRAW:
ClearScreen();
RedrawScreen();
break;
case TERMCAP:
SetTerm(topw, 3);
break;
case HELP1:
case HELP2:
ClearScreen();
helpmsg();
(void) tty_getch();
ClearScreen();
RedrawScreen();
break;
case PREFIX:
showmsg("Enter new WM prefix character.");
prefix = tty_getch();
showmsg("New WM prefix character is '%s'.", mkprint(prefix));
configflag = TRUE;
break;
case SUSPEND:
suspend();
break;
case SAVEWINDOWS:
if ((s = WPrompt("save file", savefile)) == NULL)
break;
(void) strcpy(savefile, s);
if (Save(savefile) != 0)
{
showmsg("Saved current window configuration in '%s'.", savefile);
configflag = FALSE;
}
else showmsg("Sorry, can't save current window configuration.");
break;
case QUIT:
return(TRUE);
case NOOP1:
case NOOP2:
case NOOP3:
break;
default:
showmsg("Invalid command '%s': use 'h' command for help.",mkprint(cmd));
break;
}
return(FALSE);
}
/*
* suspend w/ job control if using csh, otherwise spawn subshell.
* This could be integrated into curses tstp(),
* but I wasn't sure that could be done correctly,
* since it is impossible(?) to determine if the parent shell
* knows job control.
*/
suspend()
{
register int rc;
#ifndef TERMINFO
register int ttyflags;
#endif
/* If wm's parent is init, then we better not suspend with TSTP!
* Unfortunately, this heuristic fails if the user used rlogin,
* since wm's parent would then be rlogind. We can only hope
* the user knows what he is doing.
*/
if (getppid() != 1
&& (rc = strlen(shellname)) >= 3
&& strcmp(shellname+rc-3, "csh") == 0) {
showmsg("Suspending.");
tstp();
showmsg("WM resumed.");
return;
}
showmsg("Spawning a sub-shell ...");
(void) movecursor(LINES-1, 0);
#ifndef TERMINFO
ttyflags = _tty.sg_flags;
#endif
endwin();
putchar('\n'); /* scroll up, for neatness */
(void) fflush(stdout);
rc = system(shellpgm);
#ifdef TERMINFO
#ifdef BUGGYTERMINFO
/* Alas, buggyterminfo apparently does not re-remember the virgin state
* or correct for a baud-rate change */
#endif
fixterm();
#else
savetty(); /* re-remember the virgin state */
_tty.sg_flags = ttyflags;
(void) ioctl(_tty_ch, TIOCSETN, (char *)&_tty);
#endif
if (enter_ca_mode)
putp(enter_ca_mode);
wrefresh(curscr);
/* we could diagnose things better here */
if (rc == 127)
showmsg("Cannot spawn a shell!");
else
showmsg("Returning to WM.");
}
/*
* Set 'configflag' to indicate change affecting wmrc file.
* If this window is full-width or full-length,
* set the corresponding 'flex' flag.
* Warn user if this is a 'slow' window.
*/
winchanged(w)
register int w;
{
register WINDOW *wp;
static int full_width_warning = FALSE;
configflag = TRUE;
win[w].flags &= ~(XFLEX|YFLEX);
wp = win[w].wptr;
if (wcols(wp) == COLS)
win[w].flags |= XFLEX;
if (wlines(wp) == LINES-1)
win[w].flags |= YFLEX;
WObscure(); /* recompute obscured window info */
if (!(win[w].flags&FAST)) {
if (wcols(wp) != COLS) {
showmsg("\007Non full-width window #%d will scroll slowly!", w);
return;
}
if (full_width_warning)
return;
full_width_warning = TRUE;
showmsg("\007This terminal scrolls split-screen windows slowly.");
}
}
SHAR_EOF
if test 7983 -ne "`wc -c < 'cmd.c'`"
then
echo shar: error transmitting "'cmd.c'" '(should have been 7983 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'curses.c'" '(11058 characters)'
if test -f 'curses.c'
then
echo shar: will not over-write existing file "'curses.c'"
else
sed 's/^X//' << \SHAR_EOF > 'curses.c'
/*
*************
* DISTRIBUTION NOTICE July 30 1985
* A Revised Edition of WM, by Matt Lennon and Tom Truscott,
* Research Triangle Institute, (919) 541-7005.
* Based on the original by Robert Jacob (decvax!nrl-css!jacob),
* Naval Research Laboratory, (202) 767-3365.
* No claims or warranties of any sort are made for this distribution.
* General permission is granted to copy, but not for profit,
* any of this distribution, provided that this notice
* is always included in the copies.
*************
*/
/*
* curses.c R. Jacob
*/
#include "wm.h"
static WINDOW *mw=NULL; /* message window */
static WINDOW *cmw=NULL; /* blank message window */
time_t msgbirth = 0;
/*
* Set up win structure and associated junk for new window w.
* Returns 0 if sucessful, else -1.
*/
NewWindow(w, lines, cols, begline, begcol)
register int w;
int lines, cols, begline, begcol;
{
register WINDOW *wp, *owp;
if ((wp=newwin(lines,cols,begline,begcol)) == NULL) {
showmsg("\007Cannot %sconstruct window #%d!.",
((win[w].flags&INUSE)? "re": ""), w);
FreeWindow(w);
return(-1);
}
leaveok(wp, TRUE);
/* If the window is already in use, copy old window to new one
* anchored at bottom left of the windows.
* We move the bottom left of both windows to the bottom left
* of the screen, overwrite, then move the windows back.
* (Actually, we do not bother to move the old window back.)
*/
if (win[w].flags&INUSE) {
owp = win[w].wptr;
mvwin(owp, LINES-wlines(owp), 0);
mvwin(wp, LINES-wlines(wp), 0);
overwrite(owp, wp);
mvwin(wp, begline, begcol);
wmove(wp, wcury(owp) + (wlines(wp)-wlines(owp)), wcurx(owp));
FreeWindow(w);
}
win[w].wptr = wp;
if (MakeBorders(w) != 0)
{
showmsg("\007Cannot construct borders for window #%d!.", w);
FreeWindow(w);
return(-1);
}
win[w].flags |= INUSE;
if (has_scroll_window
|| (cols == COLS
&& (has_scroll_region || has_insdel_line || lines == LINES-1)))
win[w].flags |= FAST;
return(0);
}
/*
* Deallocate win structure and associated junk.
*/
XFreeWindow(w)
register int w;
{
win[w].flags = 0;
if (win[w].wptr) {delwin(win[w].wptr); win[w].wptr = 0;}
if (win[w].boxbot) {delwin(win[w].boxbot); win[w].boxbot = 0;}
if (win[w].boxtop) {delwin(win[w].boxtop); win[w].boxtop = 0;}
if (win[w].boxright) {delwin(win[w].boxright); win[w].boxright = 0;}
if (win[w].boxleft) {delwin(win[w].boxleft); win[w].boxleft = 0;}
}
#ifdef notdef
/*
* Redraw window w.
*/
RedrawWindow(w)
register int w;
{
register WINDOW *wp;
if (!iswindow(w))
return;
if (wp=win[w].wptr) { touchwin(wp); wrefresh(wp); }
if (wp=win[w].boxbot) { touchwin(wp); wrefresh(wp); }
if (wp=win[w].boxtop) { touchwin(wp); wrefresh(wp); }
if (wp=win[w].boxright) { touchwin(wp); wrefresh(wp); }
if (wp=win[w].boxleft) { touchwin(wp); wrefresh(wp); }
}
#endif
/*
* Redraw the entire screen.
* Uses Curses' standard screen, stdscr.
*/
RedrawScreen()
{
register int w, base;
register WINDOW *wp;
/* speed hack: start with the topmost full-screen window.
* (Smarter hacks come to mind, but this one is easy.)
*/
base = botw;
for (w=base; w>=0; w=win[w].next)
if ((wp = win[w].wptr) && wcols(wp) == COLS && wlines(wp) >= LINES-1)
base = w;
werase(stdscr);
/* Write contents of all windows into stdscr, then refresh.
*/
for (w=base; w>=0; w=win[w].next)
{
if (wp=win[w].wptr) overwrite(wp, stdscr);
if (wp=win[w].boxtop) overwrite(wp, stdscr);
if (wp=win[w].boxbot) overwrite(wp, stdscr);
if (wp=win[w].boxright) overwrite(wp, stdscr);
if (wp=win[w].boxleft) overwrite(wp, stdscr);
}
if (msgbirth)
overwrite(mw, stdscr);
touchwin(stdscr);
wrefresh(stdscr);
RestoreCursor();
}
/*
* Identify windows.
* Draw each window in turn, from bottom to top.
* Uses Curses' standard screen, stdscr.
*/
IdentWindows()
{
register int w; /* window index */
register WINDOW *wp;
register int canceled=FALSE; /* TRUE if user cancels this command */
register int c;
/* Erase the screen (and stdscr).
*/
ClearScreen();
/* Write contents of each window into stdscr, then refresh.
*/
for (w=botw; w>=0; w=win[w].next)
{
if (wp=win[w].wptr) overwrite(wp, stdscr);
if (wp=win[w].boxtop) overwrite(wp, stdscr);
if (wp=win[w].boxbot) overwrite(wp, stdscr);
if (wp=win[w].boxright) overwrite(wp, stdscr);
if (wp=win[w].boxleft) overwrite(wp, stdscr);
if (canceled)
continue;
#ifdef BUGGYTERMINFO
/* buggyterminfo seems to require this */
touchwin(stdscr);
#endif
wrefresh(stdscr);
if (w != topw)
{
showmsg("Window #%d. Hit any key to see next window.", w);
c = tty_getch();
if (c == CANCEL1 || c == CANCEL2)
{
showmsg("Canceled.");
canceled = TRUE;
}
}
else
{
showmsg("Window #%d (top window). Hit any key to continue.", w);
(void) tty_getch();
}
}
if (canceled)
wrefresh(stdscr);
RestoreMsg();
RestoreCursor();
}
/*
* Show message s on bottom of screen.
*/
/*VARARGS1*/
showmsg(s, arg1, arg2)
register char *s;
{
char buf[256];
/* Initialize message window first time 'round.
*/
if (mw == NULL) {
mw=newwin(1, 0, LINES-1, 0);
cmw=newwin(1, 0, LINES-1, 0);
if (!mw || !cmw) {
fprintf(stderr, "Cannot create message window!\n\r");
Shutdown(1);
}
leaveok(cmw, TRUE);
werase(cmw);
/* (leaveok for mw & cursor positioning for prompts needs thought) */
wstandout(mw);
}
#ifdef notdef
/* pause to let user ponder a previous message */
if (msgbirth && *s && (t = 2-abs(msgbirth - time((time_t *)0))) > 0)
sleep((unsigned int)t);
#endif
/* Format the message */
(void) sprintf(buf, s, arg1, arg2);
s = buf;
s[wcols(mw)-1] = '\0'; /* make sure it fits */
/* hack to honk but once */
if (*s == '\007') {
flash();
s++;
}
werase(mw);
waddstr(mw, s);
touchwin(mw);
wrefresh(mw);
msgbirth = s[0]? time((time_t *)0): 0;
}
ZapMsgLine()
{
if (msgbirth) {
touchwin(cmw);
wrefresh(cmw);
}
}
RestoreMsg()
{
if (msgbirth) {
touchwin(mw);
wrefresh(mw);
}
}
/*
* Restore cursor in top window.
*/
RestoreCursor()
{
register WINDOW *wp; /* pointer to top window */
wp = win[topw].wptr;
if (movecursor(wbegy(wp)+wcury(wp), wbegx(wp)+wcurx(wp)))
(void) fflush(stdout);
}
/*
* Clear the whole screen
*/
ClearScreen()
{
wclear(stdscr);
wrefresh(stdscr);
}
/*
* Creates windows containing
* a border to surround window w
* and puts pointer to the new windows
* into proper places in global win[].
* Borders appear in standout mode if
* terminal has that capability.
* Returns 0 if sucessful, else -1.
*/
MakeBorders(w)
register int w; /* make borders for this window */
{
int left, right, top, bottom; /* border flags */
int begx, begy, cols, lines; /* window dimensions */
register WINDOW *wp; /* window pointer */
register int i; /* index */
/* Get window dimensions.
*/
wp = win[w].wptr;
begx = wbegx(wp);
begy = wbegy(wp);
cols = wcols(wp);
lines = wlines(wp);
/* Determine which sides of the window need borders.
*/
left = (begx > 0);
right = (begx+cols < COLS);
top = (begy > 0);
bottom = (begy+lines < LINES-1); /* bottom line for msgs */
if (top)
--begy, ++lines;
if (bottom)
lines++;
/* Make left border using '>'.
*/
if (left)
{
if ((win[w].boxleft = wp = newwin(lines,1,begy,begx-1)) == NULL)
return(-1);
leaveok(wp, TRUE);
wstandout(wp);
for (i=0; i<lines; i++)
waddch(wp, '>');
}
/* Make right border using '<'.
*/
if (right)
{
if ((win[w].boxright = wp = newwin(lines,1,begy,begx+cols)) == NULL)
return(-1);
leaveok(wp, TRUE);
wstandout(wp);
for (i=0; i<lines; i++)
waddch(wp, '<');
}
/* Make top border using window number.
*/
if (top)
{
if ((win[w].boxtop = wp = newwin(1,cols,begy,begx)) == NULL)
return(-1);
leaveok(wp, TRUE);
wstandout(wp);
for (i=0; i<cols; i++)
waddch(wp, itoc(w));
}
/* Make bottom border using window number.
*/
if (bottom)
{
if ((win[w].boxbot = wp = newwin(1,cols,begy+lines-1,begx)) == NULL)
return(-1);
leaveok(wp, TRUE);
wstandout(wp);
for (i=0; i<cols; i++)
waddch(wp, itoc(w));
}
return(0);
}
/*
* Dump.
* Dump the contents of the current window to file 'wmdump'
* in the current directory.
* Returns 0 on sucessful completion, -1 otherwise.
*/
DumpWindow(w, dumpfile)
int w; /* number of window we're to dump */
char *dumpfile; /* file we're dumping to */
{
register WINDOW *wp; /* top window */
register FILE *dfp; /* dump file pointer */
register int line, col; /* current line, column of window */
register int lastcol; /* column of rightmost non-blank */
int oldy, oldx; /* saved cursor position */
if ((dfp = fopen(dumpfile, "w")) == NULL)
return(-1);
wp = win[w].wptr;
getyx(wp, oldy, oldx);
for (line = 0; line < wlines(wp); line++)
{
lastcol = wcols(wp);
while (--lastcol >= 0)
if (toascii(mvwinch(wp, line, lastcol)) != ' ')
break;
for (col = 0; col <= lastcol; col++)
putc(toascii(mvwinch(wp, line, col)), dfp);
putc('\n', dfp);
}
(void) fclose(dfp);
wmove(wp, oldy, oldx);
return(0);
}
#define BUFLEN 80
/* Prompt user for a string.
*/
char *
WPrompt(prompt, dflt)
char *prompt; /* prompt */
char *dflt; /* default response */
{
register int c; /* character in string */
static char buf[BUFLEN+1]; /* string buffer */
register int i=0; /* buffer index */
int maxlen, x; /* how long can string be? */
/* Print prompt and default response
* on bottom line of screen.
*/
showmsg("%s? [%s] ", prompt, dflt);
/* Determine length of longest string
* that will fit in window.
*/
x = wcurx(mw);
maxlen = (BUFLEN < wcols(mw)-2-x ? BUFLEN : wcols(mw)-2-x);
/* Read string. Process line kill & backspace chars.
*/
while ((c = tty_getch()) != EOF && c != '\n' && c != '\r')
{
if (c==CANCEL1 || c==CANCEL2) /* cancel */
{
showmsg("Canceled.");
return(NULL);
}
if (c==erasechar() || c == KEY_BACKSPACE || c == KEY_LEFT)
{
if (i > 0)
{
i--;
waddstr(mw, "\b \b");
}
}
else if (c == killchar())
{
i = 0;
wmove(mw, 0, x);
wclrtoeol(mw);
}
else if (i > maxlen) /* is string too long? */
flash();
else if (isspace(c) || !isprint(c)) /* is character inappropriate? */
flash();
else /* regular char: add to string */
{
waddch(mw, c);
buf[i++] = c;
}
wrefresh(mw);
}
/* If user didn't respond, just return default response.
*/
if (i == 0)
strcpy(buf, dflt);
else
buf[i] = '\0';
return(buf);
}
SHAR_EOF
if test 11058 -ne "`wc -c < 'curses.c'`"
then
echo shar: error transmitting "'curses.c'" '(should have been 11058 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'getch.c'" '(6283 characters)'
if test -f 'getch.c'
then
echo shar: will not over-write existing file "'getch.c'"
else
sed 's/^X//' << \SHAR_EOF > 'getch.c'
/*
*************
* DISTRIBUTION NOTICE July 30 1985
* A Revised Edition of WM, by Matt Lennon and Tom Truscott,
* Research Triangle Institute, (919) 541-7005.
* Based on the original by Robert Jacob (decvax!nrl-css!jacob),
* Naval Research Laboratory, (202) 767-3365.
* No claims or warranties of any sort are made for this distribution.
* General permission is granted to copy, but not for profit,
* any of this distribution, provided that this notice
* is always included in the copies.
*************
*/
#include "wm.h"
#include <signal.h>
char keycap[200]; /* termcap entries for keypad functions */
int tty_backcnt; /* number of pre-read terminal chars */
char tty_backbuf[10]; /* stack of pre-read chars */
char tty_text[10]; /* actual text corresponding to tty_getch code */
int tty_textlen; /* strlen(tty_text) */
/*
* Returns true iff a call to tty_realgetch would not block.
*/
tty_inputpending()
{
long n;
if (tty_backcnt > 0)
return(TRUE);
if (ioctl(0, (int)FIONREAD, (char *)&n) == 0 && n > 0)
return(TRUE);
return(FALSE);
}
/*
* Read the next character from the terminal (or the backbuf),
* return EOF if end of file, else (int)the_char, sans parity
*/
int
tty_realgetch()
{
char c;
if (tty_backcnt > 0)
c = tty_backbuf[--tty_backcnt];
else if (read(0, &c, 1) <= 0) {
tty_text[0] = '\0';
tty_textlen = 0;
return(EOF);
}
c = toascii(c);
tty_text[0] = c;
tty_text[1] = '\0';
tty_textlen = 1;
return(c);
}
#ifdef GAGMEKEYPAD
init_keypad()
{
register int i;
register char *p;
char buf1[10];
if (p = getcap("ks"))
putp(p);
for (i=1,p = "kbkukdklkrkhk0k1k2k3k4k5k6k7k8k9"; *p; i++,p+= 2) {
(void) sprintf(buf1, "%2.2s", p);
add_to_try(buf1, i+0400);
}
}
/*
** add_to_try() (Copyright Pavel Curtis, see notice in hacks.c)
**
** Construct the try for the current terminal's keypad keys.
**
*/
struct try
{
struct try *child; /* ptr to child. NULL if none */
struct try *sibling; /* ptr to sibling. NULL if none */
char ch; /* character at this node */
short value; /* code of string so far. NULL if none */
};
static struct try *newtry;
add_to_try(capname, code)
char *capname;
int code;
{
register struct try *ptr, *savedptr;
register char *str, *s;
static bool out_of_memory = FALSE;
str = getcap(capname);
if (! str || out_of_memory)
return;
strcat(keycap, capname); strcat(keycap, "=");
for (s = str; *s; s++) {
strcat(keycap, mkprint(*s));
}
strcat(keycap, ":");
if (newtry != NULL)
{
ptr = newtry;
for (;;)
{
while (ptr->ch != *str && ptr->sibling != NULL)
ptr = ptr->sibling;
if (ptr->ch == *str)
{
if (*(++str))
{
if (ptr->child != NULL)
ptr = ptr->child;
else
break;
}
else
{
ptr->value = code;
return;
}
}
else
{
if ((ptr->sibling = alloc(1, struct try)) == NULL)
{
out_of_memory = TRUE;
return;
}
savedptr = ptr = ptr->sibling;
ptr->child = ptr->sibling = NULL;
ptr->ch = *str++;
ptr->value = NULL;
break;
}
} /* end for (;;) */
}
else /* newtry == NULL :: First sequence to be added */
{
savedptr = ptr = newtry = alloc(1, struct try);
if (ptr == NULL)
{
out_of_memory = TRUE;
return;
}
ptr->child = ptr->sibling = NULL;
ptr->ch = *(str++);
ptr->value = NULL;
}
/* at this point, we are adding to the try. ptr->child == NULL */
while (*str)
{
ptr->child = alloc(1, struct try);
ptr = ptr->child;
if (ptr == NULL)
{
out_of_memory = TRUE;
ptr = savedptr;
while (ptr != NULL)
{
savedptr = ptr->child;
free((char *)ptr);
ptr = savedptr;
}
return;
}
ptr->child = ptr->sibling = NULL;
ptr->ch = *(str++);
ptr->value = NULL;
}
ptr->value = code;
return;
}
#include <setjmp.h>
static jmp_buf jmpbuf;
/*
** tty_getch() (Copyright Pavel Curtis, see notice in hacks.c)
**
** Get an input character, but take care of keypad sequences, returning
** an appropriate code when one matches the input. After each character
** is received, set an alarm call. If no more of the sequence
** is received by the time the alarm goes off, pass through the sequence
** gotten so far.
**
*/
tty_getch()
{
/* longjmp alert! beware of register variables */
register struct try *ptr;
int ch;
char buffer[10]; /* Assume no sequences longer than 10 */
char *bufp = buffer;
int (*oldsigalrm)();
int sigalrm();
bool alarmset;
ptr = newtry;
alarmset = FALSE;
oldsigalrm = SIG_DFL; /* to quiet lint */
do
{
if (setjmp(jmpbuf))
break;
ch = tty_realgetch();
if (ch != EOF) /* returns EOF on error, too */
*(bufp++) = ch;
while (ptr != NULL && ptr->ch != ch)
ptr = ptr->sibling;
if (ptr != NULL)
{
if (ptr->value != NULL)
{
if (alarmset) {
(void) ualarm(0L);
(void) signal(SIGALRM, oldsigalrm);
}
tty_textlen = bufp-buffer;
bcopy(buffer, tty_text, tty_textlen);
return(ptr->value);
}
else
{
ptr = ptr->child;
if (!alarmset) {
alarmset = TRUE;
oldsigalrm = signal(SIGALRM, sigalrm);
}
(void) ualarm(200000L);
}
}
} while (ptr != NULL);
if (alarmset) {
(void) ualarm(0L);
(void) signal(SIGALRM, oldsigalrm);
}
if (bufp <= buffer)
return(EOF);
while (--bufp > buffer)
tty_backbuf[tty_backcnt++] = *bufp;
return(*bufp);
}
static
sigalrm()
{
longjmp(jmpbuf, 1);
}
/*
* ualarm(usec). If this doesn't compile, just use alarm(0) and alarm(1).
*/
#include <sys/time.h>
#define MILLION 1000000L
ualarm(usecs)
long usecs;
{
struct itimerval it, oitv;
register struct itimerval *itp = ⁢
timerclear(&itp->it_interval);
itp->it_value.tv_sec = usecs/MILLION;
itp->it_value.tv_usec = usecs%MILLION;
if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
return (-1);
return (oitv.it_value.tv_sec*MILLION+oitv.it_value.tv_usec);
}
#endif
SHAR_EOF
if test 6283 -ne "`wc -c < 'getch.c'`"
then
echo shar: error transmitting "'getch.c'" '(should have been 6283 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'hacks.c'" '(11742 characters)'
if test -f 'hacks.c'
then
echo shar: will not over-write existing file "'hacks.c'"
else
sed 's/^X//' << \SHAR_EOF > 'hacks.c'
/*
*************
* DISTRIBUTION NOTICE July 30 1985
* A Revised Edition of WM, by Matt Lennon and Tom Truscott,
* Research Triangle Institute, (919) 541-7005.
* Based on the original by Robert Jacob (decvax!nrl-css!jacob),
* Naval Research Laboratory, (202) 767-3365.
* No claims or warranties of any sort are made for this distribution.
* General permission is granted to copy, but not for profit,
* any of this distribution, provided that this notice
* is always included in the copies.
*************
*/
/*
* hacks.c
* curses-package routines missing in one version or another,
* or corrections for routines in one version or another,
* or whatever.
*/
#include "wm.h"
/*
* Special redefinitions. We get right into the dirt here.
*/
#ifndef TERMINFO
#define _line _y
#define chtype char
#define _firstchar _firstch
#define _lastchar _lastch
#endif
/*
* Move physical cursor to (y,x).
* If y is past the end of the screen, scroll the screen up.
* This is an ugly routine in either version of curses,
* perhaps because no one worried about this sort of thing.
* (It would be nice to be able to request 'anywhere on line y',
* or 'anywhere in column x', since more optimizations are then possible.)
*/
movecursor(y,x)
register int y, x;
{
if (cursrow() == y && curscol() == x)
return(0);
#ifdef TERMINFO
if (y >= LINES) {
(void) movecursor(y-1,x);
vidattr(A_NORMAL);
putp(scroll_forward);
return(1);
}
Untouchwin(stdscr);
leaveok(stdscr, FALSE);
wmove(stdscr, y, x);
wrefresh(stdscr);
leaveok(stdscr, TRUE);
#else
/* Couldn't mvcur handle the move_standout_mode problem? */
if ((curscr->_flags&_STANDOUT) && !move_standout_mode) {
putp(exit_standout_mode);
curscr->_flags &= ~_STANDOUT;
}
/* speed hack: short circuit mvcur for simple scrolling */
if (y == LINES && curscol() == x && cursrow()+2 == y && cursor_down) {
putp(cursor_down);
putp(scroll_forward);
}
else
mvcur(cursrow(), curscol(), y, x);
/* Couldn't mvcur update curscr's current (y,x) coordinate? */
if (y >= LINES)
y = LINES-1;
cursrow() = y; curscol() = x;
#endif
return(1);
}
/*
* Make it appear that every location on the window is unchanged.
*/
untouchwin(wp)
register WINDOW *wp;
{
register int i;
for (i=0; i<wlines(wp); i++) {
wp->_firstchar[i] = _NOCHANGE;
#ifdef TERMINFO
wp->_lastchar[i] = _NOCHANGE;
wp->_numchngd[i] = 0;
#endif
}
}
/*
* This is a replacement overwrite() routine for both curses versions.
* The termcap version is slow and has some minor bugs.
* The terminfo version aligns the two windows at their origins,
* rather than on the virtual screen, making it less useful
* as one cannot use 'mvwin' &etc to paint one window at an
* arbitrary place on another.
* Neither version documents what is done with 'standout' information.
* This version copies the standout information for each character
* so that a truly identical copy is made, which is handy for painting.
*/
/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
/*
**
** overwrite(win1, win2)
**
**
** overwrite() writes win1 on win2 destructively.
**
**/
overwrite(win1, win2)
WINDOW *win1, *win2;
{
register chtype *w1ptr, *w2ptr;
register int col, end_col;
int line, offset_line, offset_col, start_line, start_col, end_line;
short *firstchar, *lastchar;
#ifdef TRACE
if (_tracing)
_tracef("overwrite(%o, %o) called", win1, win2);
#endif
offset_line = wbegy(win1) - wbegy(win2);
offset_col = wbegx(win1) - wbegx(win2);
start_line = MAX(offset_line, 0);
start_col = MAX(offset_col, 0);
end_line = offset_line + wlines(win1) - wlines(win2);
end_line = wlines(win2) + MIN(end_line, 0);
end_col = offset_col + wcols(win1) - wcols(win2);
end_col = wcols(win2) + MIN(end_col, 0);
firstchar = &win2->_firstchar[start_line];
lastchar = &win2->_lastchar[start_line];
for(line = start_line; line < end_line; line++)
{
short fc, lc;
w1ptr = &win1->_line[line-offset_line][start_col-offset_col];
w2ptr = &win2->_line[line][start_col];
fc = lc = _NOCHANGE;
for(col = start_col; col < end_col; col++)
{
if (*w1ptr != *w2ptr)
{
*w2ptr = *w1ptr;
if (fc == _NOCHANGE)
fc = col;
lc = col;
}
w1ptr++;
w2ptr++;
}
if (*firstchar == _NOCHANGE)
{
*firstchar = fc;
*lastchar = lc;
}
else if (fc != _NOCHANGE)
{
if (fc < *firstchar)
*firstchar = fc;
if (lc > *lastchar)
*lastchar = lc;
}
firstchar++;
lastchar++;
}
}
#ifndef TERMINFO
/*
* Emulators for terminfo curses procedures.
*/
#ifdef SET_WINDOW
/*
* tparm.c (Copyright Pavel Curtis, copyright notice above applies)
*/
/*
* char *
* tparm(string, parms)
*
* Substitute the given parameters into the given string.
*/
#define STACKSIZE 20
#define npush(x) if (stack_ptr < STACKSIZE) {stack[stack_ptr].num = x;\
stack_ptr++;\
}
#define npop() (stack_ptr > 0 ? stack[--stack_ptr].num : 0)
#define spop() (stack_ptr > 0 ? stack[--stack_ptr].str : (char *) 0)
typedef union
{
unsigned int num;
char *str;
} stack_frame;
stack_frame stack[STACKSIZE];
static int stack_ptr;
static char buffer[256];
static int *param;
static char *bufptr;
static int variable[26];
/*VARARGS1*/
char *
tparm(string, parms)
char *string;
int parms;
{
char len;
int number;
int level;
int x, y;
param = &parms;
stack_ptr = 0;
bufptr = buffer;
while (*string)
{
if (*string != '%')
*(bufptr++) = *string;
else
{
string++;
switch (*string)
{
default:
break;
case '%':
*(bufptr++) = '%';
break;
case 'd':
(void) sprintf(bufptr, "%d", npop());
bufptr += strlen(bufptr);
break;
case '0':
string++;
len = *string;
if ((len == '2' || len == '3') && *++string == 'd')
{
if (len == '2')
(void) sprintf(bufptr, "%02d", npop());
else
(void) sprintf(bufptr, "%03d", npop());
bufptr += strlen(bufptr);
}
break;
case '2':
string++;
if (*string == 'd')
{
(void) sprintf(bufptr, "%2d", npop());
bufptr += strlen(bufptr);
}
break;
case '3':
string++;
if (*string == 'd')
{
(void) sprintf(bufptr, "%3d", npop());
bufptr += strlen(bufptr);
}
break;
case 'c':
*(bufptr++) = (char) npop();
break;
case 's':
strcpy(bufptr, spop());
bufptr += strlen(bufptr);
break;
case 'p':
string++;
if (*string >= '1' && *string <= '9')
npush(param[*string - '1']);
break;
case 'P':
string++;
if (*string >= 'a' && *string <= 'z')
variable[*string - 'a'] = npop();
break;
case 'g':
string++;
if (*string >= 'a' && *string <= 'z')
npush(variable[*string - 'a']);
break;
case '\'':
string++;
npush(*string);
string++;
break;
case '{':
number = 0;
string++;
while (*string >= '0' && *string <= '9')
{
number = number * 10 + *string - '0';
string++;
}
npush(number);
break;
case '+':
y = npop();
x = npop();
npush(x + y);
break;
case '-':
y = npop();
x = npop();
npush(x - y);
break;
case '*':
y = npop();
x = npop();
npush(x * y);
break;
case '/':
y = npop();
x = npop();
npush(x / y);
break;
case 'm':
y = npop();
x = npop();
npush(x % y);
break;
case '&':
y = npop();
x = npop();
npush(x & y);
break;
case '|':
y = npop();
x = npop();
npush(x | y);
break;
case '^':
y = npop();
x = npop();
npush(x ^ y);
break;
case '=':
y = npop();
x = npop();
npush(x == y);
break;
case '<':
y = npop();
x = npop();
npush(x < y);
break;
case '>':
y = npop();
x = npop();
npush(x > y);
break;
case '!':
x = npop();
npush(! x);
break;
case '~':
x = npop();
npush(~ x);
break;
case 'i':
param[0]++;
param[1]++;
break;
case '?':
break;
case 't':
x = npop();
if (x)
{
/* do nothing; keep executing */
}
else
{
/* scan forward for %e or %; at level zero */
string++;
level = 0;
while (*string)
{
if (*string == '%')
{
string++;
if (*string == '?')
level++;
else if (*string == ';')
{
if (level > 0)
level--;
else
break;
}
else if (*string == 'e' && level == 0)
break;
}
if (*string)
string++;
}
}
break;
case 'e':
/* scan forward for a %; at level zero */
string++;
level = 0;
while (*string)
{
if (*string == '%')
{
string++;
if (*string == '?')
level++;
else if (*string == ';')
{
if (level > 0)
level--;
else
break;
}
}
if (*string)
string++;
}
break;
case ';':
break;
} /* endswitch (*string) */
} /* endelse (*string == '%') */
if (*string == '\0')
break;
string++;
} /* endwhile (*string) */
*bufptr = '\0';
return(buffer);
}
#endif
/*
* Ring Bell.
*/
beep()
{
putchar('\007');
}
/*
* 'Ring' visual bell if available, otherwise audible bell.
*/
flash()
{
/* If you get a syntax error on this routine,
* you are not using the new curses.h! Put
* it in this directory or in /usr/include (saving the old one).
* And double check that you are linking with the new libcurses.a
*/
if (flash_screen)
putp(flash_screen);
else
beep();
}
/*
* Return the baud rate of the current terminal.
*/
baudrate()
{
#ifdef B9600
if (_tty.sg_ospeed >= B9600)
return(9600);
#endif
#ifdef B4800
if (_tty.sg_ospeed >= B4800)
return(4800);
#endif
return(1200);
}
erasechar() { return(_tty.sg_erase); }
killchar() { return(_tty.sg_kill); }
#endif
SHAR_EOF
if test 11742 -ne "`wc -c < 'hacks.c'`"
then
echo shar: error transmitting "'hacks.c'" '(should have been 11742 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'help.c'" '(2137 characters)'
if test -f 'help.c'
then
echo shar: will not over-write existing file "'help.c'"
else
sed 's/^X//' << \SHAR_EOF > 'help.c'
/*
*************
* DISTRIBUTION NOTICE July 30 1985
* A Revised Edition of WM, by Matt Lennon and Tom Truscott,
* Research Triangle Institute, (919) 541-7005.
* Based on the original by Robert Jacob (decvax!nrl-css!jacob),
* Naval Research Laboratory, (202) 767-3365.
* No claims or warranties of any sort are made for this distribution.
* General permission is granted to copy, but not for profit,
* any of this distribution, provided that this notice
* is always included in the copies.
*************
*/
#include "wm.h"
/*
* print a command summary over the top of the screen, then redraw
*/
helpmsg()
{
printf("Code Command Description\r\n");
printf("---- ------- -----------\r\n");
printf("%d..%d change Change to the named window\r\n",
MINWINDOW, MAXWINDOWS-1);
printf("d dump dump current window contents to a file\r\n");
printf("h or ? help print this help message\r\n");
printf("i identify identify windows\r\n");
printf("k kill kill a window permanently\r\n");
printf("l last change to last-used window\r\n");
printf("m move move and/or change size of current window\r\n");
printf("n new make a new window\r\n");
printf("p prefix change WM prefix character (See EXECUTE below)\r\n");
printf("q quit quit WM\r\n");
printf("r redraw redraw entire screen\r\n");
printf("s save save current window configuration\r\n");
printf("t termcap reset $TERM and $TERMCAP of current window\r\n");
printf("z suspend suspend WM (or spawn non-window subshell)\r\n");
printf("----------------------------------------------------------\r\n");
printf("To EXECUTE a command, type the WM prefix character (%s) then the command code.\r\n", mkprint(prefix));
printf("To ENTER the prefix character itself, type it twice.\r\n");
printf("To CANCEL a WM command before it executes, type <ESC> or <DEL>.\r\n");
printf("For FUTHER INFORMATION, consult the 'wm' manual entry.\r\n");
printf("------------------------------\r\n");
printf("Now hit any key to return to WM");
(void)fflush(stdout);
}
SHAR_EOF
if test 2137 -ne "`wc -c < 'help.c'`"
then
echo shar: error transmitting "'help.c'" '(should have been 2137 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Mod.sources
mailing list