Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site seismo.UUCP Posting-Version: version B 2.10.2 9/3/84; site genrad.UUCP Path: seismo!harvard!talcott!panda!genrad!sources-request From: sources-request@genrad.UUCP Newsgroups: mod.sources Subject: wm - a window manager (part 1 of 4) Message-ID: <999@genrad.UUCP> Date: 2 Aug 85 17:35:53 GMT Sender: john@genrad.UUCP Lines: 1485 Approved: john@genrad.UUCP Mod.sources: Volume 2, Issue 31 Submitted by: Tom Truscott #! /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: # README # wm.1 # USINGWM # Paper.jacob # This archive created: Fri Aug 2 13:13:13 1985 export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(1606 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^X//' << \SHAR_EOF > 'README' A Revised Edition of the `wm' window manager Matt Lennon (919) 541-6919 Tom Truscott (919) 541-7005 Research Triangle Institute, NC P.O. Box 12194 RTP, NC 27709 To install WM: 1) Install the provided version of the Curses library. This library has bug fixes *necessary* to the proper operation of WM. If you don't actually install libcurses.a in /usr/lib, you must indicate this in the WM Makefile (the LIBCURSES macro), and you must copy the provided curses.h to this directory so that it will be included during compilation. 2) Set the value of BIN in the WM makefile to the directory where the WM program should reside. 3) Type 'make install'. 4) Install the WM manual page, wm.1, in the appropriate place. Note 1: This version of WM is horribly 4.2bsd-dependent, using pseudo-ttys, the 'select()' system call, 4.2-specific ioctl's, etc. Conceivably, it could be made to run under 4.1bsd with some minor mods, but porting to other versions of UNIX would probably entail a major rewrite. Note 2: The paper 'USINGWM' is a brief essay on how we use WM here at RTI, and should prove helpful in getting used to the WM style of doing things. It also describes some problems/glitches with WM that you should be aware of. Note 3: Included in this distribution is a paper (Paper.jacob) by the original WM author that describe WM's development and structure. While the description of the 4.2bsd version of WM pertains to an earlier version, the basics are still the same, and this paper is good reading. SHAR_EOF if test 1606 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 1606 characters)' fi fi # end of overwriting check echo shar: extracting "'wm.1'" '(5635 characters)' if test -f 'wm.1' then echo shar: will not over-write existing file "'wm.1'" else sed 's/^X//' << \SHAR_EOF > 'wm.1' X.TH WM local wm X.SH NAME wm \- window manager X.SH SYNOPSIS X.B wm [ \fB\-n\fP ] [ \fB\-f\fP rfile ] X.SH DESCRIPTION X.I Wm manages a collection of windows on a display terminal. X.PP It determines what type of terminal you are using from the environment parameter $TERM (see X.IR environ (5)) and then uses X.IR curses (3) to adapt to it. X.PP Each window has its own UNIX shell (as specified by the environment parameter $SHELL; the default is X.IR sh (1)), running in parallel with those in the other windows. The idea behind this scheme is that you can use each window for a series of commands dealing with a single topic. Then, you can change back and forth between the windows without losing your place in any of them. X.PP At any time, you can give commands to change the window you are typing in, to move a window or change its size, or to create or kill a window. Windows can overlap or completely obscure one another. Obscured windows can subsequently be "lifted" up and placed on top of the other windows. When a window is partially or completely obscured, subsequent output to that window will be held until the window becomes completely visible again, effectively suspending the job running in the obscured window. X.PP When the program is started, it will attempt to restore the sizes and positions of the windows in use when you last ran X.IR wm (unless you use X.B \-n option). If you give the X.B \-f X.I rfile option, X.I wm tries to restore windows from the file X.I rfile. Otherwise, it first tries the file X.I .wmrc in the current directory, then, if necessary, X.I .wmrc in your home directory. XFailing all this, X.I wm will give you a window the size of your screen. Now, you can type UNIX commands in the new window. X.PP X.I Wm commands can be issued at any time. Every X.I wm command consists of a prefix character \fI\fP followed by one more character, possibly followed by some arguments. Any other characters typed on the terminal are treated as input to the program in the current window. To enter \fI\fP itself as input to a program, type it twice. The \fI\fP is initially set to ASCII ESC, but there is a command for changing it. X.PP The available X.I wm commands are \fI\fP followed by: X.IP \fBn\fP Create a new window. To do this, move the cursor to the position you want the lower left corner of your window to occupy, using the keys X.B k (up), X.B j (down), X.B h (left), and X.B l (right) and also X.BR K , X.BR J , X.BR H , and X.B L (for large increments in the respective directions). Then type an X.BR x . Then move the cursor (using the same commands) to the upper right corner, and type another X.BR x . X.IP \fBi\fP Identify each window by outlining it with its window number (each window has a one digit name, e.g. #\fB1\fP, #\fB2\fP, #\fB3\fP, used in referring to that window). X.IP \fIdigit\fP Change the current window. The named window is placed on "top" of the screen (that is, in front of any other windows that had been obscuring it). Input from the keyboard will now be sent to this window. (Delayed responses to commands entered in other windows will, of course, continue to be routed to their correct windows.) X.IP \fBl\fP Change to the last-used window. Change back to the window that had most recently been the current window. X.IP \fBm\fP Move and/or change the size of the current window. X.I Wm asks for the lower left and upper right corners of desired new position of the window (same convention as for new windows). It is not advisable to move a window except when the program running in it is at the shell prompt level. In particular, screen-oriented programs such as X.I vi can get very confused if their window size is changed while they are running. X.IP \fBt\fP Reset the environment variables $TERM and $TERMCAP for the current window. This may be necessary if these variables get unset or scrambled, for instance during a remote login. This command should only be invoked when the program running in it is at the shell prompt level because it operates by sending commands to the shell as if they were typed in from the keyboard. X.IP \fBd\fP Dump current window contents. An image of the current window is written to the file X.I wmdump in the current directory. X.IP \fBk\fP Kill the named window. XSends the signal SIGHUP (hangup) to the processes associated with the window, then erases the window. (The X.I name of this window may later be re-used in creating a new window.) X.IP \fBp\fP Change the prefix character. X.IP \fBr\fP Redraw the screen. Clears the entire screen and redraws what should be there. Helpful after garbage (like a broadcast message) has arrived. X.IP \fBq\fP Quit. End the current X.I wm session. XFirst terminates the processes associated with each X.I wm, window by sending them the signal SIGHUP (hangup). Then, if you have changed the window configuration during the session (and didn't specify the 'no restore' (\fB\-n\fP) option), asks you if you want to save the current window configuration for the next session. Then exits. X.IP \fBz\fP XSuspend X.I wm by using the Berkeley job control system, or perhaps by spawning a non-window subshell. X.IP "\fBh\fP or \fB?\fP" Help. Displays a summary of X.I wm commands. X.SH FILES X.IP \fI.wmrc\fP X.IP \fI$HOME/.wmrc\fP used to save the arrangement of your windows from one session to the next. X.SH BUGS It'll never beat a BLIT. X.SH "SEE ALSO" R.J.K. Jacob, "User-Level Window Managers for UNIX," X.I "Proc. UniForum International Conference on UNIX," pp. 123-133 (1984). X.SH AUTHOR Robert J.K. Jacob X.br Naval Research Laboratory X.sp Revised by Matt Lennon and Tom Truscott X.br Research Triangle Institute SHAR_EOF if test 5635 -ne "`wc -c < 'wm.1'`" then echo shar: error transmitting "'wm.1'" '(should have been 5635 characters)' fi fi # end of overwriting check echo shar: extracting "'USINGWM'" '(17319 characters)' if test -f 'USINGWM' then echo shar: will not over-write existing file "'USINGWM'" else sed 's/^X//' << \SHAR_EOF > 'USINGWM' X.TL How I use WM X.AU Tom Truscott X.AI Research Triangle Institute P.O. Box 12194 RTP, NC 27709 (919) 541-7005 X.SH XStarting up wm X.PP The last line in my .profile is X.DS X.ft PO exec wm X.ft P X.DE which puts me into the window manager, so I am always in it. When I need a real terminal (e.g. to run `talk') I can type \fI\fPz. XSince I go right into wm it is important that TERM be set correctly. Earlier in my .profile I have X.DS X.ft PO export TERM case "$TERM" in sw|su) TERM=`whatterm`;; esac X.ft P X.DE XSo that if the TERM variable is su or sw (dataSWitch) John Menges' whatterm program is invoked to figure things out. (Whatterm depends on the response characteristics of a dozen or so terminals. A more general version, using a `responsecap' database, is planned.) Whatterm is doomed to fail on an ADM terminal (unless it has the HERE-IS option) and also fails if the user is already in wm and and logging in to another computer, because `wm' itself does not respond to any escape sequences. It probably should, so whatterm will work! Actually, nested invocations of wm, while amusing, are probably unnecessarily confusing. X.SH Choosing window layout X.PP That is largely a matter of individual taste. My ``#1'' window is full-screen (except for the bottom line), my #2 window is the top half of the screen and my #3 window is the bottom half (with an unused line between them), and my #4 window is just like #1. I am normally (99%) in the #1 window and am generally unaware of the existence of wm. But when I want to escape from the current window I can change to window #4 to get a fresh screen (one wm nuisance is that it puts me back in my home directory on my home machine). Or if I want split screens, say for debugging or file comparison, I can change to window #2 and then alternate between #2 and #3. I think of having three window layers, the #1 layer, the #2/#3 layer, and the #4 layer. (In reality, wm maintains a window display order, and changing to a window puts that window on `top', so there is not really a #2/#3 layer.) On a 66 line display I bet things would be much nicer. XSome people have a window which covers all but the top line, so they can put a clock or periodic `uptime' in the top line. (Note: two windows \fImust\fP have an unused line between them or else they cannot be used for simultaneous displays.) Also, some people change the wm prefix character to `^W' or `^P' so that `vi' is easier to use. X.PP The undocumented experimental \fI\fPf (`fit') command is also handy. XFor example, suppose I am in my #1 window and type ``make''. It might take a while, so I would like to switch to another window and read news. But I would also like to see the progress of the make. XSo I switch to a half-screen window and type `\fI\fPf 1', which relocates the #1 window so that it is no longer obscured. Now I can read news and keep up with the ``make'' at the same time. This can really jumble up the windows, but in this case I can change back to #1 and do a `\fI\fPf 1' to make it full-screen again. X.SH Window ``Performance'' Considerations X.PP There are some important performance details to consider. XFirst, your terminal needs insert-line/delete-line or scrolling region support for wm to work well on anything but full-screen windows. In particular, my #2/#3 windows are sloowww without such support. The scrolling region is best because with insert/delete-line scrolling in the #2 window causes the #3 window to jitter up and down. By the way, the scrolling region capability is often omitted in many termcap entries, so you might need to put it in. Here is the relevant vt100 stuff, which is probably the only scrolling region support you are likely to find: X.DS X.ft PO X.\" note: the '\e' below is troff's way of saying '\' :sc=\eE7:rc=\eE8:cs=\eE[%i%d;%dr:sr=5\eEM: X.ft P X.DE XFor now, all of ``cs'', ``sc'', ``rc'', and ``sr'' must be specified or wm will not use scrolling regions. X.PP By all means you should make windows be the full width of the screen. Without that wm scrolls by redrawing the whole window. The painful slowness is tolerable for smaller windows, and also for faster terminal speeds. My office terminal is at 4800 baud, and wm is okay at that speed, but even 19200 is probably too slow for a window that is full-screen except for the right-most column. X.SH WM Enhancements X.PP The ``Hacking WM'' document mentions several possible enhancements. XSuggestions for other improvements to wm are welcome. Code for any new improvements are even more welcome! X.bp X.TL Hacking WM (Obscure Details for the Hard-Core User) X.AU Tom Truscott X.AI Research Triangle Institute P.O. Box 12194 RTP, NC 27709 (919) 541-7005 X.SH In Praise of Matt Lennon X.PP Matt Lennon took an interest in Robert Jacob's Usenet wm distribution, got it running here, and talked others into trying it out. XFrankly, the original version was too slow to be usable, although it was indeed interesting. (Perhaps most interesting of all was that Jacob had a version of wm running under UNIX V6!) Matt reorganized the program internally and put in the first of a series of scrolling hacks (in WMinsertln and WMdeleteln). The resulting program shares with the original wm a simplicity of design that is important in any program, but particularly in a window manager. I think of the revised wm as the ``A'' version. I am afraid a ``B'' version will be along all too soon. X.SH Problems with Running Programs under WM X.PP There are three common problems when running programs under wm. One problem is that some programs assume the screen is at least some minimum size, such as 24 lines and 80 columns. Typical programs betray themselves by scribbling text intended for ``line 24'' at random places on the screen, or by dumping core after the ``newwin'' curses routine refuses to create a window that encompasses that line. XFixing such programs can be a chore, but often one can just substitute `COLS' for 80, `LINES-1' for 23, and so on. Rogomatic demands 24 lines so I hacked it to overlay all lines >= LINES onto line LINES-1, which is messy but tolerable. XFor programs beyond hope, type \fI\fPz and run the program on the real terminal. X.PP A second problem is with programs that assume a specific terminal type, such as "vt100". Wm currently understands only the pseudo-terminal type "wmvirt", so such programs cannot be run under wm. It would be nice if wm could emulate an arbitrary terminal type. Then one could run wm on an ADM terminal with one window emulating a vt100 and another emulating a Tektronix 4014. Of course, wm would need to support viewports into windows. Viewports are trivial compared to emulating 4014 graphics, however. X.PP A third problem is that some programs use getlogin to determine the user's login name, but under wm getlogin fails since no one is logged in on the window's control terminal (pseudo-tty). The easiest fix is to replace calls to getlogin with calls to safegetlogin: X.DS X.ft PO /* * Returns a user name such that uid(user name) == getuid(). * If feasible, the session login name is used, * but if the real uid has been changed (e.g. via 'su') * or if certain file descriptors have been munged * then a user name corresponding to the real uid is returned instead. * Returns NULL if everything fails. * Beware! Clobbers static data from earlier calls to getpw*. */ #include char * safegetlogin() { register char *p; register int uid; register struct passwd *pwd; static char namebuf[50]; extern char *getlogin(); uid = getuid(); p = getlogin(); /* cannot trust getlogin, so here is a security check */ if (!p || !(pwd = getpwnam(p)) || uid != pwd->pw_uid) p = 0; /* if getlogin failed, try the real uid */ if (!p && (pwd = getpwuid(uid))) p = pwd->pw_name; if (p) { strncpy(namebuf, p, sizeof(namebuf)-1); p = namebuf; } return(p); } X.ft P X.DE This fixes the `galaxy' and `robots' programs, for example. We keep this routine in /usr/local/liblocal.a and link programs that call it with `-llocal'. Alas, one case that this misses is the command ``who am i''. The trade secret status of ``who'' precludes a clearer explanation. X.SH XSupport for Fast Scrolling of any Rectangular Window X.PP A (very) few terminals support general ``scrolling rectangles.'' These are wonderful for wm because then non-full-width windows scroll quickly. Terminfo already has the ``set_window'' string capability, described in `tparm' format, to set up a scrolling rectangle. There is no such capability in termcap so a new ``sw'' capability was invented, using the same format as terminfo. XFor example, for the HDS Concept 108 we have: X.DS X.ft PO X.\" note: the '\e' below is troff's way of saying '\' :sw=\eEv%p1%' '%+%c%p3%' '%+%c%p2%p1%-%'!'%+%c%p4%p3%-%'!'%+%c:\e X.ft P X.DE XFor the HDS 200 we have (sorry, this is untested): X.DS X.ft PO X.\" note: the '\e' below is troff's way of saying '\' :sw=\eE[%p1%{1}%+%d;%p2%{1}%+%d;%p3%{1}%+%d;%p4%{1}%+%dr:\e X.ft P X.DE You also need ``sr'' (scroll_reverse) for wm to use set_window. Wm assumes that the set_window command moves the cursor to the rectangle's home position (upper left), that cursor motion commands work in the rectangle, and that the motions are relative to the origin of the rectangle. If your terminal works differently, and it probably will, you might have to hack wm. Look for "SET_WINDOW" which, if defined, causes code to be generated to support scroll rectangles. X.SH LIBCURSES X.PP Wm depends heavily on the underlying screen management software (libcurses) for correctness and efficiency. A number of changes were found to be needed in libcurses to provide correctness. The major efficiency problem has been that of providing fast scrolling. Libcurses itself does not support insert/delete line or scrolling regions to provide fast scrolling. We decided not to put such support into libcurses, because that was considered too far-reaching, so insert/delete line and scrolling regions are handled within special code in wm itself, and the libcurses windows are accordingly fixed up. Wm could support scrolling regions more efficiently (by not switching back and forth between full screen and window-sized regions on every newline). It could also handle certain non-full-width windows better. XFor example to scroll a window that covers all but the rightmost column it could scroll all lines involved and then redraw the rightmost column. Perhaps the termlib or other packages do that sort of thing. Also, for non-full-width windows wm could perhaps scroll two or more lines at a time, or possibly even wrap around to the top line rather than scroll. X.SH WM and TERMINFO X.PP Wm can be compiled with Pavel Curtis' public domain ``terminfo'' library in addition to the usual one (``Curses Classic''). During compilation the TERMINFO preprocessor variable is defined if compilation with terminfo curses is detected, so that appropriate code is generated. The terminfo conventions are nicer than the classic version so wm uses the terminfo functions and variable names, and Curses Classic is supported by redefinitions and emulation routines. X.PP However, wm really should only be compiled with Curses Classic. The terminfo version is slower, bigger, buggier, and does not support arrow keys. Terminfo also has more fundamental problems. It does not provide support for the TERMCAP environment variable, and there is no easy way to construct a terminfo binary file analogous to the 'wmvirt' TERMCAP string. As a result wm cannot support any terminfo-compiled applications programs. When (if) this becomes a problem there will be additional incentive for wm to be able to emulate an arbitrary terminal (also see ``problems with running programs under wm'', above). Then, in conjunction with the 4.3 kernel support for window sizes, wm can dispense with the TERMCAP variable and emulate whatever terminal is desired, thus supporting both termcap and terminfo. (\fI\fPt will still be needed for tip and cu.) X.SH WM response sluggishness X.PP An unfortunate current side-effect of wm is that certain normally responsive terminal operations are now sluggish. XFor example, if you cat a file and press several lines will be printed before the interrupt takes effect. Other similar special characters are also handled slowly. The reason is that wm runs in raw mode, so such characters are not ``instantly'' handled in the kernel. Instead they are passed to the currently selected pseudo-tty, which then interrupts or stops or whatever. But any characters currently queued by wm for the user's terminal are still printed! (The script program has the same behavior, but it is tolerable for the normal uses of that command.) There does not seem to be a good way around this problem. Wm's current approach is to X.IP a) Only read a few (currently 64) characters from each pseudo-tty at a time, to avoid large queues from wm to the real tty. X.IP b) Have wm check the size of the output queue using the undocumented TIOCOUTQ ioctl, and delay reading from the pseudo-ttys if the output queue is large. X.IP c) Have wm reduce the read and queue sizes for a while after the user types Control-S. X.LP The first two hacks keep the response to at a tolerable level. They also keep the tty high water mark from being reached, which would put wm to sleep, which would make response very sluggish indeed. The last hack gives somewhat better response to Control-S. X.PP This approach to wm sluggishness is quite new, so more tuning and better approaches to the problem are possibilities. Also, the parameters have been tuned for a Gould 9050, which is quite a fast machine, and the resulting extra cpu involved might be intolerable on a VAX. An easy `fix' is to comment out the TIOCOUTQ code in wm.c (you can probably just #undef TIOCOUTQ at the top). You might want to remove the Control-S hack as well. X.SH The `.wmrc' File X.PP The first line of .wmrc is the prefix character. The remaining lines describe the configured windows from bottom to top. (The last line describes the window in which the user starts.) Each line consists of the window name, the number of rows and columns, and the starting row and column (zero indexed). If the number of rows (columns) is given as zero then that dimension ``flexes'' to the height (width) of the screen, which supposedly is useful when switching among terminals of different sizes. X.PP XSeveral users have asked for the ability to specify an alternate ``shell'' in a window. That could be done by extending the .wmrc lines to include a command to be executed in lieu of the shell. Other users have requested the ability to set the shell prompts in a window dependent way, among other things. I do not know how that might be done. X.SH The ``SNEAKYTERMCAP'' Method X.PP Ordinarily, when a window changes size, wm blasts the window with a shell command that sets TERM and TERMCAP to indicate the new window's size. (This is the same shell command generated by \fI\fPt.) This not only produces clutter, it can also confuse non-shell programs running in that window. If your version of wm was compiled with SNEAKYTERMCAP defined, however, a different method is used. The TERMCAP variable is set to a filename such as /tmp/WM.33445.1 and the file contains the termcap capability string. Then, when a window changes size the /tmp file is simply rewritten. But there is a security problem with this method (or with any command that uses /tmp) and /tmp gets cluttered up with lots of ``WM'' files. It would be better if the files were kept in a subdirectory of each user's home directory, and if wm itself cleaned up dead temporary files (e.g. due to a system crash). X.SH Browsing About in WM Windows X.PP XSome terminals have extra memory so one can look back at text that scrolls off the screen. It would be nice if wm provided that too. One hundred lines of scrolled typescript should be adequate. A plausible approach would be to type \fI\fPv (for `view') to put the window in browse mode. Then input to that window is interpreted as requests to move back and forth in the typescript, like the `vi' scrolling commands. Any output to the real window is held pending exit from browse mode, which might be by typing ``:q'', at which time the window is reset to its state on entry to browse mode. Of course, while a window is in browse mode one can still switch between windows, move, create, and kill windows, and so on. X.PP All this can be implemented cleanly with about 100 lines of code scattered here and there (it has been written), but what about text searching and the ability to write parts of the typescript into UNIX files? What about all the other nifty `vi' commands? Why not just run `vi' (or your favorite viewing program) in the browse window!? Well, here is why not. Vi has to position itself at the end of the typescript in order to provide a ``seamless interface'' to wm. Okay, that's easy. We need an ``ignore first clear'' kludge so that when vi initially redraws the screen the window is not really redrawn. Uh, well, wm already has kludges. We need to suppress the vi status line (``seamless interface'' remember), say by displaying it instead in wm's status area. Er, uhm. Yuck! It could be done, but it sure would be ugly. Alas, wm does not yet support browse mode. SHAR_EOF if test 17319 -ne "`wc -c < 'USINGWM'`" then echo shar: error transmitting "'USINGWM'" '(should have been 17319 characters)' fi fi # end of overwriting check echo shar: extracting "'Paper.jacob'" '(22963 characters)' if test -f 'Paper.jacob' then echo shar: will not over-write existing file "'Paper.jacob'" else sed 's/^X//' << \SHAR_EOF > 'Paper.jacob' X.rm CH X.ds CF "\(hy \\n(PN \(hy X.\" X.ds >. . X.rm <. X.ds >, , X.rm <, X.ds [. " [ X.ds .] ] X.\" X.TL User-Level Window Managers for UNIX X.AU Robert J.K. Jacob X.AI Naval Research Laboratory Washington, D.C. 20375 X.AB X.I Wm manages a collection of windows on a display terminal. Each window has its own shell or other interactive program, running in parallel with those in the other windows. This permits a user to conduct several interactions with the system in parallel, each in its own window. The user can move from one window to another, re-position a window, or create or delete a window at any time without losing his or her place in any of the windows. Windows can overlap or completely obscure one another; obscured windows can be "lifted" up and placed on top of the other windows. X.PP This paper describes how such a window manager for UNIX\(dg X.FS X.PP \(dgUNIX is a trademark of Bell Laboratories. X.FE is implemented as a set of user processes, without modifications to the UNIX kernel. It shows how the simple, but well-chosen facilities provided by the original (Version 6) UNIX kernel are sufficient to support X.I wm . In addition, subsequent versions of X.I wm exploit features of the kernel introduced into newer versions of UNIX to provide faster and more sophisticated window operations, still implemented entirely at the user level. X.AE X.SH Introduction X.PP This paper describes the design of a display window manager for UNIX implemented entirely as a set of user processes, without modifications to the UNIX kernel. It shows how the simple facilities provided by the original (Version 6) UNIX kernel are sufficient to support such a window manager. In addition, more recent versions of the window manager exploit features of the kernel introduced into newer versions of UNIX to provide faster and more sophisticated operations in windows, still implemented entirely outside the kernel. X.PP This window manager, X.I wm , provides a UNIX user the ability to conduct several interactions in parallel, each in a different window on a text display terminal. The windows may be created, moved, and temporarily or permanently erased at any time. They may also overlap or completely obscure one another, and such hidden or partially hidden windows may be "lifted" and placed on top of the other windows as desired. XFigure 1 shows a snapshot of a X.I wm session in progress. X.SH User Interface X.PP The notion of organizing computer data spatially was propounded and exploited by Nicholas Negroponte in the Spatial Data Management System\*(<.\*([.2,\|3\*(.]\*(>. In X.I wm , however, spatial cues are used only to specify a context for a dialogue. Once a window is selected, further interactions within that window make use of the power and abstraction of more conventional user interface techniques. Teitelman\*([.8\*(.] made good use of display screen windows for a collection of parallel interactions with an INTERLISP system. More recently, several personal computers and workstations have adopted this window-oriented style of dialogue as their principal mode of interaction. Other systems similar to the present one have also been provided under UNIX\*(<.\*([.4,\|7,\|9\*(.]\*(>. X.PP Traditional user interfaces for computers that handle parallel processes place all inputs and outputs in one chronological stream, identifying the process associated with each, but interleaving the data. The Berkeley job control facilities for UNIX provide a first attempt at improving this situation\*(<.\*([.5\*(.]\*(>. X.PP By contrast, a window-based user interface enables a user to manage a collection of dialogues by associating a spatial location with each dialogue, in much the same way one organizes a desk. On a desk, all input papers on all topics are not (one hopes) placed on a single pile in chronological order, but rather they are divided into piles by topic. When input for a particular topic is received, the corresponding pile is located, lifted, and placed on top of other papers, and the necessary work is done on that pile. Each topic may thus be associated with and remembered in terms of a location on the desk. Recent empirical evidence showed that such a window-oriented user interface induced better user performance than a more traditional scrolled message interface in a particular situation involving several parallel interactions\*(<.\*([.6\*(.]\*(>. X.PP X.I Wm conducts several concurrent dialogues with a UNIX user. Each takes the form of a UNIX shell, to which UNIX commands can be given and from which other interactive programs can be initiated. Each dialogue is conducted in a separate area of the screen or X.I window designated by the user. At any moment, one of the windows is considered the current input window, and all keyboard inputs (except for X.I wm commands themselves) are sent to the shell or program associated with that window. At any time (including in the middle of typing a command in a window), the designation of the current window may be changed and a different dialogue begun or resumed. Outputs resulting from these dialogues will appear in their appropriate windows as they are generated, regardless of which window is the current input window. Output destined for a portion of a window that is obscured by another window will appear whenever that portion of the window is uncovered. Windows can be "piled" on one another in any sequence. X.PP X.I Wm was originally designed for use in an intelligent terminal that could communicate with several computers simultaneously. Each dialogue with a different computer was associated with a window. The method is equally applicable to a collection of dialogues, all with the same computer but on different topics. XStill, any or all of the present windows can run programs to conduct interactive dialogues with other computers (such as X.I telnet ). X.SH Design for "Vanilla" UNIX X.PP To implement a system of this sort, it is necessary for one user process to be able to manage a collection of other user processes and to mediate all of their inputs and outputs. XFor the inputs, it must act as a switch, directing input from the keyboard to different programs in response to user commands. XFor the program outputs, it must place the output of each program in its correct position on the screen. X.PP If adequate primitives for creating and manipulating processes and for catching their inputs and outputs are provided by the operating system, a window manager can be built entirely as a user program. The original design of UNIX, with its X.I pipe and X.I fork mechanisms provides a user the right primitives to design such a system in an elegant fashion without kernel modifications. X.PP X.I Wm initiates and manages its own collection of UNIX processes, including those run in response to entered commands. Any conventional UNIX program can be used from X.I wm , provided it does not make significant assumptions about the nature of its input and output devices\-that is, it should treat input and output from a pipe as equivalent to input and output from a terminal or other source. X.PP X.I Wm runs as X.I 2n+2 parallel UNIX processes of four different types (where X.I n is the number of windows in use). The division into processes is dictated by the fact that the original UNIX X.I read call on an empty pipe or input device causes a process to block until input becomes available. Hence there is a separate process for each pipe or device that must be read asynchronously. Each such process contains a loop that reads from its particular pipe or device, processes the input, and then waits for more. XFigure 2 shows the processes and pipes that comprise X.I wm . X.PP The X.B main process reads from and waits for input from the keyboard. Input consisting of text is sent to the shell process associated with the current window and also to the X.B scrn process, described below, for echoing. Input consisting of X.I wm commands is interpreted by X.B main , translated into one or more primitive commands plus arguments, and sent to X.B scrn for execution. XSimple changes in the input command language are thus localized in X.B main . To change the name, input syntax, or prompt for a command, only the code in X.B main need be modified. XSince input commands are reduced to a somewhat more general set of primitive commands, some simple new commands may be implemented entirely in X.B main as aliases for specific uses or combinations of the existing primitive commands. X.PP The X.B scrn process handles all outputs to the screen. All processes that want to affect the screen must thus place requests to do so on a common pipe. X.B Scrn reads these instructions from the pipe and makes appropriate modifications to the screen. X.I Wm commands that affect the screen layout, such as moving a window, are placed on this pipe by X.B main and handled by X.B scrn . Output text characters from the individual shell processes that belong in a window are also placed on this pipe along with a window identifier and a bit indicating whether the character should be displayed immediately or just remembered for the next time the display is refreshed. X.B Scrn then compares the desired configuration of the screen to a buffer containing the actual configuration and transmits the necessary updates.\(dg\ X.FS X.PP \(dgThe update algorithm is less sophisticated than the optimization performed in the X.I curses package\*(<,\*([.1\*(.]\*(>, but X.I curses was not available in Version 6 UNIX. This update algorithm is also somewhat easier to adapt to unusual terminals, as seen below. X.FE X.PP There is a X.B shell process associated with each window. This is simply the standard UNIX X.I sh (or any other designated program). These X.B shell processes have no direct access to the terminal, but run as captives of X.I wm , connected by pipes, so that their inputs and outputs can be mediated. The input to each of these processes is a pipe from X.B main , since X.B main knows which window is the current input window and can place the typed input text on the pipe to the corresponding X.B shell process. All outputs of the X.B shell processes must be sent to X.B scrn to be displayed, but they must first be tagged with the name of the window in which they belong. X.PP To do this, each window has a X.B shmon process that monitors the output of the corresponding X.B shell process. The output of each X.B shell process is a pipe to a corresponding X.B shmon process. Each time output appears on that pipe, X.B shmon reads it, packages it with a header identifying its window, and then places it on the common request pipe to X.B scrn . X.PP X.I Wm comprises about 1000 lines of C code\-about 500 each for the X.B main and X.B scrn processes and less than 50 for the X.B shmon process. X.SH Remarks and Problems with "Vanilla" UNIX X.PP Each window in X.I wm emulates an individual glass teletype. Inputs appear in the bottom and scroll off the top of a window. XSince the standard input and output for all programs run by X.I wm are really pipes, all programs run under X.I wm should treat their inputs and outputs simply as streams of characters, without distinctions between terminals and pipes. The fact that UNIX and most of its original programs permit a pipe to be substituted for a terminal input or output stream is an elegant aspect of UNIX that is crucial to X.I wm . This obtains for most UNIX programs; they perform individual "building-block" functions and are thus intended to be equally usable individually from the terminal or as filters connected to other programs to perform more complex tasks. Programs that try to determine whether they have access to a real terminal may behave differently or even refuse to run with X.I wm . XFor example, X.I stty is meaningless when applied to a pipe rather than a terminal, X.I vi will refuse to run from a pipe, and X.I csh will not allow job control if it cannot access the terminal. (However, note that X.I wm is really an alternate approach to controlling concurrent jobs.)\ X.PP A very rudimentary facility for supporting a whole-screen-oriented program is provided. It creates a special temporary window, creates a X.I termcap description of a "terminal" that occupies only the corresponding area of the actual screen, and then provides that description and direct access to the terminal to the screen-oriented program until the latter exits. X.PP XSince X.I wm operates with the terminal in raw mode, it must provide for itself the input line editing functions normally provided by the teletype driver. X.PP Because of the architecture of X.I wm , there are no pipes that connect one window to another, hence there is no explicit facility for communication between windows. It can be achieved, however, through the file system. A program in one window can append to a file while one in another window continuously tries to read from the end of that file. X.SH Terminal Dependencies X.PP While the newer version of X.I wm uses X.I curses to perform all terminal-dependent operations in a terminal-independent fashion, terminal dependencies can be isolated fairly easily even without X.I curses . All terminal-dependent code in the original X.I wm is restricted to a collection of five simple procedures. They were originally written separately for each type of terminal, but have also been written in terms of the terminal-independent interface, X.I termcap , for systems that have it. X.PP The five procedures perform the following tasks: X.RS X.IP \fBttyinit\fP 15 Performs any necessary initialization for the terminal. X.IP \fBttyclose\fP 15 Performs any necessary closing for the terminal before X.I wm exits or suspends. X.IP \fBttymov\fP 15 Moves the terminal cursor to a given row and column. X.IP \fBclearscreen\fP 15 Clears the terminal screen. X.IP \fBclearline\fP 15 Clears from the cursor to end of the current line (not mandatory). X.RE X.LP XFor each of several common terminals, the definitions of these procedures comprise about 15 lines of code altogether. X.PP This approach isolates terminal dependencies sufficiently that X.I wm can also be adapted for use on graphic displays by replacing the above procedures and making other minor changes. XSuch a version of X.I wm has been written to produce output suitable for the standard UNIX plot filters (plus some added commands for raster graphic displays) and used with a Genisco frame buffer. Windows may be in various colors and may use different fonts for their text. X.SH Design for Version 4.2 UNIX X.PP Berkeley Version 4.2 VAX UNIX provides new features that make it possible to improve X.I wm significantly. By using pseudo-terminals instead of pipes for interprocess communication, several of the problems discussed above disappear. In addition, the synchronous input/output multiplexing feature of the new UNIX makes the former division of X.I wm into processes as dictated by the blocking read unnecessary. A revised version of X.I wm , then, solves many of the earlier problems and runs in a single process (plus the user's shells). It is, however, less interesting and certainly less portable than the initial version. Again, the facilities are provided entirely in user-level processes, without the need for kernel modifications. X.PP This version of X.I wm reads from the keyboard and also from the pseudo-terminals associated with each window, in a round-robin, using the multiplexed read call X.I (select) . Keyboard input consisting of text is sent to the pseudo-terminal associated with the current window. The pseudo-terminal driver itself handles echoing (when enabled) and intraline editing, obviating the need for X.I wm to duplicate these functions. Keyboard input consisting of X.I wm commands is processed directly; text input is sent to the appropriate pseudo-terminal. Output from the pseudo-terminals is read by X.I wm , interpreted in terms of the cursor control commands of a simple virtual terminal defined by X.I wm , and then added to the appropriate screen window for processing by the X.I curses package\*(<.\*([.1\*(.]\*(>. X.PP This version of X.I wm comprises about 1000 lines of C code, all in a single process. XFigure 3 shows the architecture of the program. X.SH Remarks and Problems with Version 4.2 UNIX X.PP XSince each window is implemented with a pseudo-terminal, the fact that a program is running in a window rather than on a real terminal is transparent to most programs. XSpecifically, most screen editors and games may be used, and X.I stty may be called to change characteristics such as echoing or line editing individually for each window. XFor example, note that one of the windows in Figure 1 is running X.I vi , which has adjusted itself to the window size. XSome programs, however, assume that their output devices are of some minimum size; they will not run well in very small windows. Also, programs that attempt to manipulate the controlling terminals of process groups will not work properly under X.I wm . XFor this reason, X.I csh cannot currently be run in the individual windows instead of X.I sh . X.PP It is generally not possible to move a window while an interactive program (other than a shell) is running in it. XFirst, this is necessary because, whenever a window is moved, X.I wm sends a shell command to change the X.I TERMCAP variable for the shell in that window, to describe its new size. A more fundamental reason is that the X.I curses library routines (sensibly) do not expect the terminal description to change while a program is running, and so make no provision for checking for or adapting to such changes. X.PP XSince pseudo-terminals are a system-wide resource and are usually fixed in number, the total number of windows that can be in use by all users at any one time is limited to the number of pseudo-terminals made available to X.I wm . X.PP A facility for communicating between windows is now easy to provide. XSince each window uses a pseudo-terminal, any data sent to its slave pseudo-terminal will appear in the window; and pseudo-terminals are in the name space of the UNIX file system and thus available to other processes. To simplify use of this feature, when a window is created and a pseudo-terminal obtained for it, a link to the name of its slave pseudo-terminal is created in the user's current directory. Any program inside or outside X.I wm can then write to or read from that file name without prearrangement. X.SH Program Versions X.PP These programs are written in C for use with UNIX. There are three principal versions: X.B wm.v6 , X.B wm.v7 , and X.B wm.v42 . The first, as described above, runs under unmodified Version 6 UNIX on a PDP-11. The code for this version was frozen and abandoned several years ago, but it is still available. X.B Wm.v7 runs under Version 7 UNIX, and the same code also runs on Berkeley 2.8 and also on a VAX on Berkeley 4.1 and 4.2. No changes in the source code are required between the PDP-11 and VAX, except that constants for the maximum number and size of windows are limited by the available memory on a PDP-11. This version is similar in design to X.B wm.v6 , which was described above, but has a number of improvements. The newest version, X.B wm.v42 , runs only under Berkeley 4.2 on a VAX, as described in this paper. It uses the X.I select synchronous input/output multiplexing call, which is unique to 4.2, and also other features that are found in some, but not all, versions of UNIX, such as pseudo-terminals and X.I curses . At this writing, this version is not yet thoroughly tested on 4.2. An intermediate version for use with Versions 2.8 or 4.1 can also be constructed by adapting some of the features of X.B wm.v42 to X.B wm.v7 . XFor example, the use of X.I curses can certainly be adapted to 2.8; pseudo-terminals are available on some versions of 4.1; and some versions of 4.1 can also simulate a non-blocking read on a pseudo-terminal or a short time-out. X.SH Availability X.PP Three versions of X.I wm are available to interested researchers. X.RS X.IP "\fBwm.v6\fP" 10 XFor Version 6 UNIX. X.IP "\fBwm.v7\fP" 10 XFor Version 7 UNIX, also runs on Berkeley 2.8, 4.1, and 4.2. X.IP "\fBwm.v42\fP" 10 XFor Berkeley 4.2 UNIX only (but has some features than can be retrofitted to X.B wm.v7 ). X.RE X.LP The code can be obtained over the Arpanet by sending a request to X.\" the two (hy is to prevent the hyphenation algorithm from splitting nrl-css jacob@nrl\(hycss. The author can also be reached via uucp at ...!decvax!linus!nrl\(hycss!jacob. X.SH Conclusions X.PP It is demonstrably feasible to provide a useful and efficient display window management facility in UNIX at the user level, without support from kernel modifications. XSuch a facility can even be provided for the original Version 6 UNIX, although some improvements are obtainable by exploiting features provided by more recent versions of UNIX. X.SH Acknowledgments X.PP I would like to thank Mark Cornwell, Rudy Krutar, Alan Parker, and Mark Weiser for helpful discussions of this work. X.]< X.\"Arnold.K.-1980-1 X.ds [F 1 X.]- X.ds [A K. Arnold X.ds [T Screen Updating and Cursor Movement Optimization X.ds [R University of California, Berkeley X.ds [D 1980 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 4 tech-report X.\"Bolt.R.-1979-2 X.ds [F 2 X.]- X.ds [A R. Bolt X.ds [T Spatial Data Management X.ds [I Architecture Machine Group, Massachusetts Institute of Technology X.ds [R Technical Report X.ds [D 1979 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 4 tech-report X.\"Herot.C.F.-1980-3 X.ds [F 3 X.]- X.ds [A C.F. Herot X.as [A ", R. Carling X.as [A ", M. Friedell X.as [A ", and D. Kramlich X.ds [T A Prototype Spatial Data Management System X.ds [J Computer Graphics X.ds [V 14 X.ds [N 3 X.ds [P 63-70 X.nr [P 1 X.ds [D 1980 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 1 journal-article X.\"Horton.M.-1982-4 X.ds [F 4 X.]- X.ds [A M. Horton X.ds [I personal communication X.ds [D September 8, 1982 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 2 book X.\"Joy.W.-1980-5 X.ds [F 5 X.]- X.ds [A W. Joy X.ds [T An Introduction to the C Shell X.ds [R University of California, Berkeley X.ds [D November 1980 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 4 tech-report X.\"Murrel.S.-1983-6 X.ds [F 6 X.]- X.ds [A S. Murrel X.ds [T Computer Communication System Design Affects Group Decision Making X.ds [J Proc. Human Factors in Computer Systems Conference X.ds [D 1983 X.ds [P 63-67 X.nr [P 1 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 1 journal-article X.\"Pike.R.-1983-7 X.ds [F 7 X.]- X.ds [A R. Pike X.ds [T Graphics in Overlapping Bitmap Layers X.ds [J ACM Transactions on Graphics X.ds [V 2 X.ds [N 2 X.ds [D 1983 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 1 journal-article X.\"Teitelman.W.-1979-8 X.ds [F 8 X.]- X.ds [A W. Teitelman X.ds [T A Display Oriented Programmer's Assistant X.ds [J International Journal of Man-Machine Studies X.ds [V 11 X.ds [P 157-187 X.nr [P 1 X.ds [D 1979 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 1 journal-article X.\"Weiser.M.-1983-9 X.ds [F 9 X.]- X.ds [A M. Weiser X.as [A ", C. Torek X.as [A ", R. Trigg X.as [A ", and R. Wood X.ds [T The Maryland Window System X.ds [R Technical Report 1271 X.ds [I Computer Science Department, University of Maryland X.ds [D 1983 X.nr [T 0 X.nr [A 0 X.nr [O 0 X.][ 4 tech-report X.]> SHAR_EOF if test 22963 -ne "`wc -c < 'Paper.jacob'`" then echo shar: error transmitting "'Paper.jacob'" '(should have been 22963 characters)' fi fi # end of overwriting check # End of shell archive exit 0