home *** CD-ROM | disk | FTP | other *** search
- /*
- *************
- * 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.");
- }
- }
-