Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/5/84; site asuvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!hao!noao!terak!asuvax!system From: system@asuvax.UUCP (Marc Lesure) Newsgroups: net.sources Subject: 4.2 Window Management System (wms part 4 of 4) Message-ID: <293@asuvax.UUCP> Date: Fri, 20-Sep-85 01:42:09 EDT Article-I.D.: asuvax.293 Posted: Fri Sep 20 01:42:09 1985 Date-Received: Sun, 22-Sep-85 06:39:19 EDT Distribution: net Organization: Arizona State Univ, Tempe Lines: 1897 wms part 4 of 4 If your site decides on implementing wms, please send mail to the author so he can send updates (if any) in the future. Also, please send all bug reports, problems, fixes, etc. to the author rather than posting them to net.sources.bugs. Marc Lesure System Manager Engineering Computer Center Arizona State University Tempe, Arizona UUCP: ...!{ucbvax,ihnp4}!arizona!asuvax!lesure ...!ihnp4!terak!asuvax!lesure CSNET: lesure@asu ARPA: lesure%asu@csnet-relay ------------------------------------------------------------- # This is a shell archive. Remove all lines before this one. # Use 'sh ' to unpack the contents. # # contents: # release/source/relink # release/source/util.h # release/source/wty # release/source/wty/max.msh.h # release/source/wty/max.wty.h # release/source/wty/msh.h # release/source/wty/util.h # release/source/wty/wty.bind.c # release/source/wty/wty.c # release/source/wty/wty.h # echo x - release/source/relink sed 's/^@@//' > "release/source/relink" << '@@ END-OF-FILE' # source this script to aid source code symbolic linking for files in .../wms. # we assume ./util.h doesn't move. # if link targets move, update this variable (relative to msh,wty subdirs): set W = '../../public/wms' # cd msh rm max.msh.h ln -s $W/max.msh.h max.msh.h rm msh.h ln -s $W/msh.h msh.h cd ../wty rm max.msh.h ln -s $W/max.msh.h max.msh.h rm max.wty.h ln -s $W/max.wty.h max.wty.h rm msh.h ln -s $W/msh.h msh.h cd .. @@ END-OF-FILE echo x - release/source/util.h sed 's/^@@//' > "release/source/util.h" << '@@ END-OF-FILE' /****************************************************************************\ * Copyright 1985 by George Nelan, Arizona State University. * * All rights reserved. Permission to use, modify, and copy these programs * * and documentation is granted, provided that the copy is not sold and * * that this copyright and permission notice appear on all copies. * \****************************************************************************/ #define STDIN 0 #define STDOUT 1 #define STDERR 2 #define reg register typedef char bool; #define TRUE 1 #define FALSE 0 #define NIL (-1) #define fail(x) ((x)==(-1)) #define public @@ END-OF-FILE echo x - release/source/wty mkdir release/source/wty echo x - release/source/wty/max.msh.h ln -s ../../public/wms/max.msh.h release/source/wty/max.msh.h echo x - release/source/wty/max.wty.h ln -s ../../public/wms/max.wty.h release/source/wty/max.wty.h echo x - release/source/wty/msh.h ln -s ../../public/wms/msh.h release/source/wty/msh.h echo x - release/source/wty/util.h ln -s ../util.h release/source/wty/util.h echo x - release/source/wty/wty.bind.c sed 's/^@@//' > "release/source/wty/wty.bind.c" << '@@ END-OF-FILE' /****************************************************************************\ * Copyright 1985 by George Nelan, Arizona State University. * * All rights reserved. Permission to use, modify, and copy these programs * * and documentation is granted, provided that the copy is not sold and * * that this copyright and permission notice appear on all copies. * \****************************************************************************/ /* wty.bind: integrated version wty binder */ /* author: George Nelan */ #include "max.wty.h" /* from msh */ extern init_msh(); extern abort(); extern slave_driver(); /* from wty */ extern init_wty(); extern keyboard_driver(); extern screen_driver(); typedef struct { char buf[AMAXQBUF]; char *fp,*rp,*beg,*end; } queue; #define initq(q) {\ q.fp = q.rp = q.buf;\ q.beg = q.buf + 1;\ q.end = q.buf + MAXQBUF - 1;\ } #define nullq(q) (q.fp == q.buf) #define fullq(q) (q.fp == q.rp) int qresult; #define insertq(q,e) {\ qresult = 1;\ q.rp = (q.rp == q.end ? q.beg : q.rp + 1);\ if (fullq(q)) qresult = 0;\ else {\ *(q.rp) = (e);\ if (q.fp == q.buf) q.fp = q.beg;\ }\ } #define deleteq(q,ep) {\ qresult = 1;\ if (nullq(q)) qresult = 0;\ else {\ *(ep) = *q.fp;\ if (q.fp == q.rp) q.fp = q.rp = q.buf;\ else q.fp = (q.fp == q.end ? q.beg : q.fp + 1);\ }\ } static queue pq,mq; /* wty port, msh master queues */ /****************************************************************************/ main (argc,argv) int argc; char *argv[]; { initq(pq); initq(mq); init_msh(); init_wty(argc,argv); for (;;) screen_driver(); } /* main */ /****************************************************************************/ int get_master(chp) register char *chp; /* return > 0 if wty character ready, * else return <= 0 if not ready or error. */ { if (nullq(mq)) keyboard_driver(); if (!nullq(mq)) { deleteq(mq,chp); return (1); } return (0); } /* get_master */ /****************************************************************************/ put_port(chp,len) register char *chp; register int len; { register int i; for (i = 0; i < len; i++) { insertq(mq,*(chp + i)); if (!qresult) abort("wty: put_port q o/v"); } } /* put_port */ /****************************************************************************/ int get_port(chp) register char *chp; /* return > 0 if msh character ready, * else return <= 0 if not ready or error. */ { if (nullq(pq)) slave_driver(); if (!nullq(pq)) { deleteq(pq,chp); *chp &= 0177; /* make sure 7-bits */ return (1); } return (0); } /* get_port */ /****************************************************************************/ put_master(chp,len) register char *chp; register int len; { register int i; for (i = 0; i < len; i++) { insertq(pq,*(chp + i)); if (!qresult) abort("msh: put_master q o/v"); } } /* put_master */ @@ END-OF-FILE echo x - release/source/wty/wty.c sed 's/^@@//' > "release/source/wty/wty.c" << '@@ END-OF-FILE' /****************************************************************************\ * Copyright 1985 by George Nelan, Arizona State University. * * All rights reserved. Permission to use, modify, and copy these programs * * and documentation is granted, provided that the copy is not sold and * * that this copyright and permission notice appear on all copies. * \****************************************************************************/ /* wty: virtual windowing terminal emulator */ /* author: George Nelan */ #include #include #include #include #include #include #include extern int errno; #include "max.wty.h" #include "msh.h" #include "util.h" #include "wty.h" #define BELL '\07' static char cmdchr = '\01'; /* ^A */ /* initialization kludge for init_wty,do_CC */ static bool initflag; /* nice flag for inhibiting auto-resizes */ static bool niceflag = FALSE; static char WTYB[128]; /* buffer name prefix env. var. */ static char WTYP[AMAXTCODE]; /* wty proto. env. var. */ /* buffer stuff */ /* set by 'br' - tells keyboard_driver to take input from b_fpending */ static bool b_rpending = FALSE; /* reset @ EOF */ static FILE *b_fpending; static char b_label; /* saved during 'br' reads */ static bool b_nlitflag = TRUE; /* not-literal flag for 'brl' */ typedef struct { char label; /* constant == index + 1 */ bool isactive; /* are we attached to a shell... */ bool isvisible; /* are we not folded... */ /* buffer variables */ FILE *b_file; /* the buffer is a file */ bool b_isactive; /* are we attached to a file... */ bool b_isvisible; /* are we not folded... */ /* viewport variables */ int top0,bot0; /* 0-org wrt screen global CS */ int row0,col0; /* 0-org wrt window local CS */ int row0max; /* 0-org wrt window local CS MAX */ int col0max; /* 0-org wrt window local CS MAX */ /* state variables... (see screen_driver) */ short state; char s_code; short s_argc; short s_i; char s_argv[8]; } window_t; /* all windows... */ static window_t window[AMAXWINDOWS]; static window_t *iwindow = 0; /* current input window */ static window_t *owindow = 0; /* current output window */ static char ilabel; /* label of current input window */ static char olabel; /* label of current output window */ static char sav_olabel; /* saved olabel */ static bool new_olabel; /* new olabel due to do_SS */ /* note: the interaction between the keyboard driver side and the * screen driver side is indirect. see do_SS and screen_driver (new_olabel). */ static int nwindows = 0; /* n visible windows => row sizes */ static int ctop = (-1); /* current global CS cs limits */ static int cbot = (-1); /* current global CS cs limits */ /* screen driver not-ignore character table */ static bool s_nignore[128]; /* screen driver special character table (affects cursor other than by +1) */ static bool s_special[128]; /* screen driver function execution table - need speed here */ static int (*s_exec[128])(); /* screen driver function arguments */ /* since only CM needs arguments, this is quite an over-generalization */ static short s_argc[128]; static char *s_argvp; /* screen driver TERMCAP functions */ static int s_null(); static int s_AL(); static int s_BC(); static int s_CD(); static int s_CE(); static int s_CL(); static int s_CM(); static int s_CR(); static int s_DC(); static int s_DL(); static int s_DO(); static int s_HO(); static int s_IC(); static int s_IS(); static int s_KE(); static int s_KS(); static int s_ND(); static int s_NL(); static int s_SE(); static int s_SF(); static int s_SO(); static int s_SR(); static int s_UE(); static int s_UP(); static int s_US(); static int s_VE(); static int s_VS(); static int s_WE(); static int s_WS(); /* TERMCAP interface (extern stuff in termlib) */ static int put_screen(); static char t_nam[32]; static char t_buf[1024]; static char t_area[1024]; extern int tgetent(); extern int tgetnum(); extern int tgetflag(); extern char *tgetstr(); extern char *tgoto(); extern int tputs(); extern short ospeed; static char *AL; static int AM; extern char *BC; static char *CD; static char *CE; static char *CL; static char *CM; static int CO; static char *CR; static char *CS; static char *DC; static char *DL; static char *DO; static char *HO; static char *IC; static char *IS; static char *KE; static char *KS; static int LI; static char *ND; static char *NL; extern char PC; static char *SE; static char *SF; static int SG; static char *SO; static char *SR; static char *UE; static int UG; extern char *UP; static char *US; static char *VE; static char *VS; static char *WE; static char *WS; /****************************************************************************/ #define error() {put_screen(BELL);flush_screen();} /****************************************************************************/ #define atoi3(h,m,l) (((h)-'0')*100+((m)-'0')*10+((l)-'0')) /****************************************************************************/ /* send command string to msh */ #define exec_msh(str,len) {\ put_port(M_CSI,(sizeof M_CSI)-1);\ put_port(str,len);\ } /****************************************************************************/ #define read_port(chp) {\ while(get_port(chp)<=0);\ } /****************************************************************************/ #define read_keyboard(chp) {\ while(get_keyboard(chp)<=0);\ } /****************************************************************************/ #define tput(str,nla) {tputs(str,nla,put_screen);} /****************************************************************************/ /* keyboard driver routines */ /****************************************************************************/ /****************************************************************************/ public keyboard_driver() /* get input from keyboard|buffer. * process any local (e.g. function key) (not to mention msh) commands. * send to port. */ { char ch; reg char *chp = &ch; reg bool isacmd; /* take input from buffer if necessary */ if (b_rpending) { b_take(); if (b_rpending) return; } if (get_keyboard(chp) > 0) { isacmd = FALSE; if (*chp == cmdchr) { /* test for escape (two cmdchrs) */ read_keyboard(chp); isacmd = (*chp != cmdchr); } if (isacmd) k_exec(*chp); else put_port(chp,1); } } /* keyboard_driver */ /****************************************************************************/ /* read buffer input */ /* perform '\r''\n' => '\n' transformation unless b_nlitflag */ #define MAXB (MAXQBUF >> 4) static b_take() { int i; char ch; reg char *chp = &ch; /* if we are taking stuff out of a file buffer, any keyboard * input will terminate buffer input. */ for (i = 0; i < MAXB; i++) { if (get_keyboard(chp) > 0) { b_rpending = FALSE; b_nlitflag = TRUE; break; } if ((ch = getc(b_fpending)) != EOF) { if (b_nlitflag && ch == '\r') { char tch; tch = getc(b_fpending); i++; if (tch != EOF) { if (tch == '\n') put_port(&tch,1); else { put_port(&ch,1); put_port(&tch,1); } } else { /* EOF */ put_port(&ch,1); /* \r */ b_rpending = FALSE; b_nlitflag = TRUE; break; } } else /* not \r */ put_port(&ch,1); } else { /* EOF */ b_rpending = FALSE; b_nlitflag = TRUE; break; } } if (!b_rpending) { /* open up again (reset to BOF) due to previous read of EOF */ WTYB[strlen(WTYB) - 1] = b_label; if ((window[b_label - '1'].b_file = fopen(WTYB,"a")) == NULL) error(); } } /* b_take */ #undef MAXB /****************************************************************************/ /* keyboard wty command execution */ static k_exec(ch) reg char ch; { switch (ch) { case '=' : k_EQ(); break; case 'h' : k_HE(); break; case 'q' : k_QX(); break; case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : k_SS(ch); break; case 'c' : k_CC(); break; case 'u' : k_CU(); break; case 'r' : k_RS(); break; case 'd' : k_DS(); break; case 'l' : k_LS(); break; case 'f' : k_FW(); break; case 'o' : k_OW(); break; case 'b' : k_BU(); break; case '\032' : k_SX(); break; default : error(); break; } } /* k_exec */ /****************************************************************************/ /* keyboard driver execution routines */ /****************************************************************************/ /****************************************************************************/ /* set command prefix */ static k_EQ() { char newcmd; read_keyboard(&newcmd); do_EQ(newcmd); } /* k_EQ */ static do_EQ(nc) char nc; { cmdchr = nc; } /* do_EQ */ /****************************************************************************/ /* help */ static k_HE() { do_HE(); } /* k_HE */ static do_HE() { s_CL(); help(" - change current input window"); help("c - create new current input window"); help("cn - create (nicely)"); help("d - delete current input window"); help("dn - delete (nicely)"); help("f - fold current input window"); help("fn - fold (nicely)"); help("o - open another current input window"); help("on - open (nicely)"); help("bc - create new buffer for current input window"); help("bd - delete buffer for current input window"); help("bf - fold buffer for current input window"); help("bo - open buffer for current input window"); help("br - read buffer into current input window"); help("brl - read buffer literally"); help("r - resize current input window"); help("l - label all windows"); help("h - help"); help("= - set command prefix"); help(" - stop"); help("qy - quit"); flush_screen(); } /* do_HE */ static help(msg) char *msg; { int i, j; j = strlen(msg); for (i = 0; i < j; i++) put_screen(msg[i]); s_CR(); s_NL(); } /* help */ /****************************************************************************/ /* quit execution */ static k_QX() { char ch; read_keyboard(&ch); if (ch == 'y') do_QX(); else error(); } /* k_QX */ static do_QX() { int i; s_WE(); flush_screen(); for (i = 0; i < MAXWINDOWS; i++) if (window[i].b_isactive) { fclose(window[i].b_file); WTYB[strlen(WTYB) - 1] = i + '1'; unlink(WTYB); } exec_msh(M_QX,(sizeof M_QX)-1); } /* do_QX */ /****************************************************************************/ /* set current input shell to */ static k_SS(n) char n; { if (n < '1' || n > MAXLABEL || !window[n - '1'].isvisible) { error(); return; } do_SS(n); } /* k_SS */ static do_SS(n) char n; { iwindow = &window[n - '1']; ilabel = n; new_olabel = TRUE; exec_msh(M_SS,(sizeof M_SS)-1); put_port(&ilabel,1); } /* do_SS */ /****************************************************************************/ /* create new current input (csh) shell */ static k_CC() { char n; read_keyboard(&n); if (n == 'n') { niceflag = TRUE; read_keyboard(&n); } if (n < '1' || n > MAXLABEL || window[n - '1'].isactive) { error(); niceflag = FALSE; return; } do_CC(n); niceflag = FALSE; } /* k_CC */ static do_CC(n) char n; { char nn,tc[AMAXTCODE]; int r,c; ++nwindows; r = (int) LI/nwindows; c = CO; nn = n; mk_TC(tc,r,c); exec_msh(M_CC,(sizeof M_CC) - 1); put_port(&nn,1); put_port(tc,strlen(tc)); do_CCCU(n,r,c); } /* do_CC */ /****************************************************************************/ /* create new current input (user) shell */ static k_CU() { /* not implemented */ } /* k_CU */ static do_CU(n,shell) char n; char *shell; { char nn,tc[AMAXTCODE]; int r,c; ++nwindows; r = (int) LI/nwindows; c = CO; nn = n; mk_TC(tc,r,c); exec_msh(M_CC,(sizeof M_CC) - 1); put_port(&nn,1); put_port(tc,strlen(tc)); put_port(shell,strlen(shell)); /* must have \n at end */ do_CCCU(n,r,c); } /* do_CU */ do_CCCU(n,r,c) char n; int r,c; { int i,j; window_t *wp; wp = &window[n - '1']; wp->row0 = 0; wp->col0 = 0; wp->col0max = c - 1; wp->isactive = TRUE; wp->isvisible = TRUE; for (i = 0, j = 0, wp = &window[i]; i < MAXWINDOWS; i++, wp++) { if (wp->isvisible) { wp->top0 = r * j; wp->bot0 = r * (j + 1) - 1; wp->row0max = window[i].bot0 - window[i].top0; if (!initflag) { wgoto(i + '1'); s_CL(); flush_screen(); } /* don't do our self - CC/CU did it already */ if (n != ((char) i + '1') && !initflag) { do_SS(i + '1'); /* needed by do_RS */ do_RS(wp->row0max + 1, wp->col0max + 1); } j++; } } do_SS(n); } /* do_CCCU */ /****************************************************************************/ /* Resize current input shell */ static k_RS() { do_RS(iwindow->row0max + 1, iwindow->col0max + 1); } /* k_RS */ static do_RS(r,c) int r,c; { char tc[AMAXTCODE]; if (niceflag) return; mk_TC(tc,r,c); exec_msh(M_RS,(sizeof M_RS) - 1); put_port(tc,strlen(tc)); } /* do_RS */ /****************************************************************************/ /* delete current input shell; make new current */ static k_DS() { char n; read_keyboard(&n); /* new current iwindow */ if (n == 'n') { niceflag = TRUE; read_keyboard(&n); } if (n < '1' || n > MAXLABEL || !window[n - '1'].isvisible || n == ilabel) { error(); niceflag = FALSE; return; } do_DS(n); niceflag = FALSE; } /* k_DS */ static do_DS(n) char n; { int i,j,k; window_t *wp; char nn; nwindows--; nn = n; exec_msh(M_DS,(sizeof M_DS)-1); put_port(&nn,1); iwindow->isactive = FALSE; iwindow->isvisible = FALSE; do_SS(n); k = (int) LI/nwindows; for (i = 0, j = 0, wp = &window[i]; i < MAXWINDOWS; i++, wp++) { if (wp->isvisible) { wp->top0 = k * j; wp->bot0 = k * (j + 1) - 1; wp->row0max = window[i].bot0 - window[i].top0; do_SS(i + '1'); /* for do_RS */ do_RS(wp->row0max + 1, wp->col0max + 1); wgoto(i + '1'); s_CL(); flush_screen(); j++; } } do_SS(n); } /* do_DS */ /****************************************************************************/ /* label all shells */ static k_LS() { do_LS(); } /* k_LS */ static do_LS() { short i; window_t *wp; char ilab; ilab = ilabel; for (i = 0, wp = &window[i]; i < MAXWINDOWS; i++, wp++) { if (wp->isvisible) { int r,c; wgoto(wp->label); r = wp->row0; c = wp->col0; cmove(0,(wp->col0max) - 2*SG - 2); tput(SO,1); put_screen(wp->label); if (wp->b_isactive) if (wp->b_isvisible) put_screen('B'); else put_screen('b'); else put_screen(' '); tput(SE,1); flush_screen(); cmove(r,c); } } wgoto(ilab); flush_screen(); } /* do_LS */ /****************************************************************************/ /* fold current input window, make new current */ static k_FW() { char n; int i,j,k; window_t *wp; read_keyboard(&n); /* new current iwindow */ if (n == 'n') { niceflag = TRUE; read_keyboard(&n); } if (n < '1' || n > MAXLABEL || !window[n - '1'].isvisible || n == ilabel) { error(); niceflag = FALSE; return; } do_FW(n); niceflag = FALSE; } /* k_FW */ static do_FW(n) char n; { int i,j,k; window_t *wp; char nn; nwindows--; iwindow->isvisible = FALSE; do_SS(n); k = (int) LI/nwindows; for (i = 0, j = 0, wp = &window[i]; i < MAXWINDOWS; i++, wp++) { if (wp->isvisible) { wp->top0 = k * j; wp->bot0 = k * (j + 1) - 1; wp->row0max = window[i].bot0 - window[i].top0; do_SS(i + '1'); /* for do_RS */ do_RS(wp->row0max + 1, wp->col0max + 1); wgoto(i + '1'); s_CL(); flush_screen(); j++; } } do_SS(n); } /* do_FW */ /****************************************************************************/ /* open new current input window */ static k_OW() { char n; read_keyboard(&n); if (n == 'n') { niceflag = TRUE; read_keyboard(&n); } if (n < '1' || n > MAXLABEL || !window[n - '1'].isactive || window[n - '1'].isvisible) { error(); niceflag = FALSE; return; } do_OW(n); do_SS(n); niceflag = FALSE; } /* k_OW */ static do_OW(n) char n; { int i,j; window_t *wp; int r,c; nwindows++; r = (int) LI/nwindows; c = CO; wp = &window[n - '1']; wp->row0 = 0; wp->col0 = 0; wp->col0max = c - 1; wp->isvisible = TRUE; for (i = 0, j = 0, wp = &window[i]; i < MAXWINDOWS; i++, wp++) { if (wp->isvisible) { wp->top0 = r * j; wp->bot0 = r * (j + 1) - 1; wp->row0max = window[i].bot0 - window[i].top0; wgoto(i + '1'); s_CL(); do_SS(i + '1'); /* for do_RS */ do_RS(wp->row0max + 1, wp->col0max + 1); flush_screen(); j++; } } } /* do_OW */ /****************************************************************************/ /* Buffer operations */ static k_BU() { char op,arg; read_keyboard(&op); if (op == 'r') { read_keyboard(&arg); if (arg == 'l' /* ell */ ) { b_nlitflag = FALSE; read_keyboard(&arg); } if (arg < '1' || arg > MAXLABEL) { error(); return; } } do_BU(op,arg); } /* k_BU */ do_BU(op,arg) char op,arg; { struct stat sbuf; switch (op) { case 'c' : /* create buffer (new: must not exist) */ WTYB[strlen(WTYB) - 1] = ilabel; if (iwindow->b_isactive || stat(WTYB,&sbuf) != (-1) || (iwindow->b_file = fopen(WTYB,"w")) == NULL) { error(); break; } iwindow->b_isactive = TRUE; iwindow->b_isvisible = TRUE; break; case 'd' : /* delete buffer */ WTYB[strlen(WTYB) - 1] = ilabel; if (iwindow->b_isactive) { fclose(iwindow->b_file); unlink(WTYB); iwindow->b_isactive = FALSE; iwindow->b_isvisible = FALSE; } else error(); break; case 'f' : /* fold buffer */ if (iwindow->b_isvisible) { fflush(iwindow->b_file); iwindow->b_isvisible = FALSE; } else error(); break; case 'o' : /* open buffer */ if (iwindow->b_isactive && !iwindow->b_isvisible) iwindow->b_isvisible = TRUE; else error(); break; case 'r' : /* read buffer (close then open) */ if (!window[arg - '1'].b_isactive) { error(); break; } /* temp - see b_take for re-open at EOF */ b_label = arg; fclose(window[b_label - '1'].b_file); WTYB[strlen(WTYB) - 1] = arg; if ((b_fpending = fopen(WTYB,"r")) == NULL) { error(); break; } b_rpending = TRUE; break; default : error(); break; } } /* do_BU */ /****************************************************************************/ /* stop execution (of msh) (bsd) */ static k_SX() { do_SX(); } /* k_SX */ static do_SX() { tput(WE,1); exec_msh(M_SX,(sizeof M_SX)-1); put_port("0",1); tput(WS,1); } /* do_SX */ /****************************************************************************/ /* screen driver routines */ /****************************************************************************/ /****************************************************************************/ /* upon W_WG, save state, resume to indicated window at its state */ #define s_resume(resume) {\ char n;\ owindow->state = resume;\ read_port(&n);\ wgoto(n);\ continue;\ } /****************************************************************************/ /* send and cursor-process an output character to the screen */ #define s_put(ch) {\ if (s_nignore[ch]) \ if (s_special[ch]) {\ switch (ch) {\ case '\000' :\ case '\007' : put_screen(ch); break;\ case '\010' : s_BC();break;\ case '\012' : s_NL();break;\ case '\015' : s_CR();break;\ }\ } else {\ put_screen(ch);\ if (owindow->col0 < owindow->col0max)\ ++owindow->col0;\ else if (AM) {\ owindow->col0 = 0;\ if (owindow->row0 < owindow->row0max)\ ++owindow->row0;\ }\ }\ } /****************************************************************************/ #define next {owindow->state=0;continue;} /****************************************************************************/ #define b_write(chr) {\ if (owindow->b_isvisible)\ fprintf(owindow->b_file,"%c",chr);\ } /****************************************************************************/ /* Get input from port. * Process any control sequences. * Send to term. * Don't hog time. * Be careful of fragmented slave messages (use of s_resume). * Maintain cursor for each window. * Uh, BTW, this is a coroutine. */ public screen_driver() { char ch; reg char *chp = &ch; int i; bool first; first = TRUE; for (;;) { switch (owindow->state) { case 0 : if (get_port(chp) <= 0) goto done; if (first) { /* the cursor was at the point of expected * input, so lets get it back */ first = FALSE; wgoto(sav_olabel); } if (*chp == W_WG[0]) { s_resume(0); } if (*chp != W_CSI[0]) { /* normal case */ b_write(*chp); s_put(*chp); next; } /* we probably have a CSI */ case 1 : read_port(chp); if (*chp == W_WG[0]) { s_resume(1); } if (*chp != W_CSI[1]) { next; } /* we definitely have a CSI */ case 2 : read_port(chp); if (*chp == W_WG[0]) { s_resume(2); } /* pickup args if necess. */ owindow->s_argc = s_argc[owindow->s_code = *chp]; owindow->s_i = 0; case 3 : loop: if (owindow->s_i < owindow->s_argc) { read_port((char *) (chp = ((owindow->s_argv) + owindow->s_i))); if (*chp == W_WG[0]) { s_resume(3); } (owindow->s_i)++; goto loop; } s_argvp = (owindow->s_argv); b_write(W_CSI[0]); b_write(W_CSI[1]); b_write(owindow->s_code); for (i = 0; i < owindow->s_argc; i++) b_write(s_argvp[i]); (*(s_exec[owindow->s_code]))(); next; default : abort("wty: screen_driver state"); } /* switch */ } /* for (;;) */ done: if (!first || new_olabel) { /* move cursor back to point of expected input */ new_olabel = FALSE; sav_olabel = olabel; wgoto(ilabel); flush_screen(); } } /* screen_driver */ /****************************************************************************/ /* screen driver TERMCAP functions */ /****************************************************************************/ /****************************************************************************/ /* dummy */ static s_null() {} /****************************************************************************/ /* Add Line */ static s_AL() { tput(AL,1); } /* s_AL */ /****************************************************************************/ /* Backspace Character */ static s_BC() { if (owindow->col0 > 0) { --owindow->col0; tput(BC,1); } } /* s_BC */ /****************************************************************************/ /* Clear to end of Display */ static s_CD() { short i,r,c; tput(CE,1); r = owindow->row0; c = owindow->col0; for (i = r + 1; i <= owindow->row0max; i++) { cmove(i,0); tput(CE,1); } cmove(r,c); } /* s_CD */ /****************************************************************************/ /* Clear to End of line */ static s_CE() { reg int r,c; r = owindow->row0; c = owindow->col0; tput(CE,1); cmove(r,c); } /* s_CE */ /****************************************************************************/ /* CLear display */ static s_CL() { short i; for (i = 0; i <= owindow->row0max; i++) { cmove(i,0); tput(CE,1); } cmove(0,0); } /* s_CL */ /****************************************************************************/ /* Cursor Motion */ static s_CM() { reg int r,c; r = atoi3(*(s_argvp ), *(s_argvp+1), *(s_argvp+2)); c = atoi3(*(s_argvp+3), *(s_argvp+4), *(s_argvp+5)); cmove(r,c); } /* s_CM */ /****************************************************************************/ /* Carraige Return */ static s_CR() { tput(CR,1); owindow->col0 = 0; } /* s_CR */ /****************************************************************************/ /* Delete Character */ static s_DC() { tput(DC,1); } /* s_DC */ /****************************************************************************/ /* Delete Line */ static s_DL() { tput(DL,1); } /* s_DL */ /****************************************************************************/ /* DOwn line */ static s_DO() { tput(DO,1); if (owindow->row0 < owindow->row0max) ++owindow->row0; } /* s_DO */ /****************************************************************************/ /* HOme cursor */ static s_HO() { cmove(0,0); } /* s_HO */ /****************************************************************************/ /* Insert Character */ static s_IC() { tput(IC,1); } /* s_IC */ /****************************************************************************/ /* Initialization String */ static s_IS() { tput(IS,1); } /* s_IS */ /****************************************************************************/ /* Keypad End */ static s_KE() { tput(KE,1); } /* s_KE */ /****************************************************************************/ /* Keypad Start */ static s_KS() { tput(KS,1); } /* s_KS */ /****************************************************************************/ /* NonDestructive space */ static s_ND() { tput(ND,1); if (owindow->col0 < owindow->col0max) ++owindow->col0; else if (AM) { owindow->col0 = 0; if (owindow->row0 < owindow->row0max) ++owindow->row0; } } /* ND */ /****************************************************************************/ /* NewLine */ static s_NL() { tput(NL,1); if (owindow->row0 < owindow->row0max) ++owindow->row0; } /* NL */ /****************************************************************************/ /* Standout End */ static s_SE() { tput(SE,1); if (SG) { owindow->col0 += SG; if (owindow->col0 > owindow->col0max) if (AM) { owindow->col0 = 0; if (owindow->row0 < owindow->row0max) ++owindow->row0; } else owindow->col0 = owindow->col0max; } } /* s_SE */ /****************************************************************************/ /* Scroll Forwards (normal/up) */ static s_SF() { tput(SF,1); } /* s_SF */ /****************************************************************************/ /* StandOut start */ static s_SO() { tput(SO,1); if (SG) { owindow->col0 += SG; if (owindow->col0 > owindow->col0max) if (AM) { owindow->col0 = 0; if (owindow->row0 < owindow->row0max) ++owindow->row0; } else owindow->col0 = owindow->col0max; } } /* s_SO */ /****************************************************************************/ /* Scroll Reverse (backwords/down) */ static s_SR() { tput(SR,1); } /* s_SR */ /****************************************************************************/ /* Underscore End */ static s_UE() { tput(UE,1); if (UG) { owindow->col0 += UG; if (owindow->col0 > owindow->col0max) if (AM) { owindow->col0 = 0; if (owindow->row0 < owindow->row0max) ++owindow->row0; } else owindow->col0 = owindow->col0max; } } /* s_UE */ /****************************************************************************/ /* UP one line */ static s_UP() { tput(UP,1); if (owindow->row0 > 0) --owindow->row0; } /* s_UP */ /****************************************************************************/ /* Underscore start */ static s_US() { tput(US,1); if (UG) { owindow->col0 += UG; if (owindow->col0 > owindow->col0max) if (AM) { owindow->col0 = 0; if (owindow->row0 < owindow->row0max) ++owindow->row0; } else owindow->col0 = owindow->col0max; } } /* s_US */ /****************************************************************************/ /* Visual End */ static s_VE() { tput(VE,1); } /* s_VE */ /****************************************************************************/ /* Visual Start */ static s_VS() { tput(VS,1); } /* s_VS */ /****************************************************************************/ /* Wty End */ static s_WE() { tput(WE,1); } /* s_WE */ /****************************************************************************/ /* Wty Start */ static s_WS() { tput(WS,1); } /* s_WS */ /****************************************************************************/ /* Return > 0 if input ready else <= 0 */ static get_keyboard(chp) reg char *chp; { int tlen; if (fail(ioctl(STDIN,FIONREAD,&tlen))) { abort("wty: get_keyboard"); } if ((tlen > 0) && (fail(tlen = read(STDIN,chp,1)))) { abort("wty: get_keyboard[read]"); } return(tlen); } /* get_keyboard */ /****************************************************************************/ static char s_buf[AMAXCBUF]; /* screen output buffer */ static char *s_bufap = s_buf; /* add ptr */ static int s_len = 0; /* length */ /****************************************************************************/ /* Add one char to output buffer, flushing if necessary. * Also called from TERMCAP tputs routine. */ static put_screen(ch) char ch; { if (owindow->isvisible) { /* see if we need to flush our buffer first */ if (s_len >= MAXCBUF) flush_screen(); *s_bufap++ = ch; s_len++; } } /* put_screen */ /****************************************************************************/ /* this is the final output routine... */ static flush_screen() { if (s_len > 0) { write(STDOUT,s_buf,s_len); s_bufap = s_buf; s_len = 0; } } /* flush_screen */ /****************************************************************************/ /* goto new output window at its current row0,col0 */ wgoto(n) reg char n; { owindow = &window[n - '1']; olabel = n; if (owindow->bot0 != cbot || owindow->top0 != ctop) { cbot = owindow->bot0; ctop = owindow->top0; tput(tgoto(CS,cbot,ctop),1); } cmove(owindow->row0,owindow->col0); } /* wgoto */ /****************************************************************************/ /* move cursor absolute wrt current output window local CS (clipped) */ /* update window row0,col0 */ /* can't use currencies... */ cmove(r,c) reg int r,c; { reg int rr; rr = r + owindow->top0; rr = (rr > owindow->bot0 ? owindow->bot0 : rr); tput(tgoto(CM,c,rr),1); owindow->row0 = r; owindow->col0 = c; } /* cmove */ /****************************************************************************/ /* make terminal code string of form: "RxC;" */ static mk_TC(tc,r,c) char *tc; int r,c; { char cc[16]; strcpy(tc,WTYP); sprintf(cc,"%dx",r); strcat(tc,cc); sprintf(cc,"%d;",c); strcat(tc,cc); } /* mk_TC */ /****************************************************************************/ /* Initialize... */ public init_wty(argc,argv) int argc; char *argv[]; { int i; char *a,*p; bool f = FALSE; char *M_AL, *M_CD, *M_CE, *M_CL, *M_DC, *M_DL, *M_IC; char *M_ND, *M_SE, *M_SF, *M_SO, *M_SR, *M_UE, *M_US, *M_UP; int M_AM; struct sgttyb sgb; for (i = 0; i < 128; i++) { s_exec[i] = s_null; s_argc[i] = 0; s_nignore[i] = TRUE; s_special[i] = FALSE; } for (i = 1; i < 040; i++) s_nignore[i] = FALSE; /* ^A..^_ */ s_nignore[007] = TRUE; /* ^G */ s_nignore[010] = TRUE; /* ^H */ /* no ^I */ s_nignore[012] = TRUE; /* ^J */ s_nignore[015] = TRUE; /* ^M */ s_special[000] = TRUE; /* ^@ */ s_special[007] = TRUE; /* ^G */ s_special[010] = TRUE; /* ^H */ /* no ^I */ s_special[012] = TRUE; /* ^J */ s_special[015] = TRUE; /* ^M */ /* define TERMCAP execution entry points */ s_exec[W_AL[0]] = s_AL; s_exec[W_BC[0]] = s_BC; s_exec[W_CD[0]] = s_CD; s_exec[W_CE[0]] = s_CE; s_exec[W_CL[0]] = s_CL; s_exec[W_CM[0]] = s_CM; s_argc[W_CM[0]] = 6; s_exec[W_CR[0]] = s_CR; s_exec[W_DC[0]] = s_DC; s_exec[W_DL[0]] = s_DL; s_exec[W_DO[0]] = s_DO; s_exec[W_HO[0]] = s_HO; s_exec[W_IC[0]] = s_IC; s_exec[W_IS[0]] = s_IS; s_exec[W_KE[0]] = s_KE; s_exec[W_KS[0]] = s_KS; s_exec[W_ND[0]] = s_ND; s_exec[W_NL[0]] = s_NL; s_exec[W_SE[0]] = s_SE; s_exec[W_SF[0]] = s_SF; s_exec[W_SO[0]] = s_SO; s_exec[W_SR[0]] = s_SR; s_exec[W_UE[0]] = s_UE; s_exec[W_UP[0]] = s_UP; s_exec[W_US[0]] = s_US; s_exec[W_VE[0]] = s_VE; s_exec[W_VS[0]] = s_VS; s_exec[W_WE[0]] = s_WE; s_exec[W_WS[0]] = s_WS; /* get buffer name prefix */ if (strlen(strcpy(WTYB,getenv("WTYB"))) == 0) strcpy(WTYB,"wty.buf"); strcat(WTYB,".?"); /* setup TERMCAP interface */ #define bad(msg) {f=TRUE;printf("no %s in TERMCAP \n\r",msg);} strcpy(WTYP,getenv("WTYP")); /* verify that host terminal is at least as functional as prototype */ if ((i = tgetent(t_buf,WTYP)) < 0) {abort("wty: can't find TERMCAP database");} else if (i == 0) {abort("wty: can't find TERMCAP entry for wty prototype");} a = t_area; M_AL = tgetstr("al",&a); M_AM = tgetflag("am"); M_CD = tgetstr("cd",&a); M_CE = tgetstr("ce",&a); M_CL = tgetstr("cl",&a); M_DC = tgetstr("dc",&a); M_DL = tgetstr("dl",&a); M_IC = tgetstr("ic",&a); M_ND = tgetstr("nd",&a); M_SE = tgetstr("se",&a); M_SF = tgetstr("sf",&a); M_SO = tgetstr("so",&a); M_SR = tgetstr("sr",&a); M_UE = tgetstr("ue",&a); M_UP = tgetstr("up",&a); M_US = tgetstr("us",&a); /* load host TERMCAP entry */ strcpy(t_nam,getenv("TERM")); if ((i = tgetent(t_buf,t_nam)) < 0) {abort("wty: can't find TERMCAP database");} else if (i == 0) {abort("wty: can't find TERMCAP entry");} ioctl(STDOUT,TIOCGETP,&sgb); ospeed = sgb.sg_ospeed; a = t_area; if (!(AL = tgetstr("al",&a)) && M_AL) {bad("al");} if (!(AM = tgetflag("am")) && M_AM) {bad("am");} BC = a;if (!tgetstr("bc",&a)) {*a++ = '\010';*a++ = '\0';} if (!(CD = tgetstr("cd",&a)) && M_CD) {bad("cd");} if (!(CE = tgetstr("ce",&a)) && M_CE) {bad("ce");} if (!(CL = tgetstr("cl",&a)) && M_CL) {bad("cl");} if (!(CM = tgetstr("cm",&a))) {bad("cm");} if (!(CO = tgetnum("co"))) CO = 80; CR = a;if (!tgetstr("cr",&a)) {*a++ = '\015';*a++ = '\0';} if (!(CS = tgetstr("cs",&a))) {bad("cs");} if (!(DC = tgetstr("dc",&a)) && M_DC) {bad("dc");} if (!(DL = tgetstr("dl",&a)) && M_DL) {bad("dl");} DO = a;if (!tgetstr("do",&a)) {*a++ = '\012';*a++ = '\0';} HO = a;if (!tgetstr("ho",&a)) {*a++ = '\0';} if (!(IC = tgetstr("ic",&a)) && M_IC) {bad("ic");} IS = a;if (!tgetstr("is",&a)) {*a++ = '\0';} KE = a;if (!tgetstr("ke",&a)) {*a++ = '\0';} KS = a;if (!tgetstr("ks",&a)) {*a++ = '\0';} if (!(LI = tgetnum("li"))) LI = 24; if (!(ND = tgetstr("nd",&a)) && M_ND) {bad("nd");} NL = a;if (!tgetstr("nl",&a)) {*a++ = '\012';*a++ = '\0';} PC = ((p = tgetstr("pc",&a)) ? *p : '\0'); if (!(SE = tgetstr("se",&a)) && M_SE) {bad("se");} if (!(SF = tgetstr("sf",&a)) && M_SF) {bad("sf");} if (!(SG = tgetnum("sg"))) SG = 0; if (!(SO = tgetstr("so",&a)) && M_SO) {bad("so");} if (!(SR = tgetstr("sr",&a)) && M_SR) {bad("sr");} if (!(UE = tgetstr("ue",&a)) && M_UE) {bad("ue");} if (!(UG = tgetnum("ug"))) UG = 0; if (!(UP = tgetstr("up",&a)) && M_UP) {bad("up");} if (!(US = tgetstr("us",&a)) && M_US) {bad("us");} VE = a;if (!tgetstr("ve",&a)) {*a++ = '\0';} VS = a;if (!tgetstr("vs",&a)) {*a++ = '\0';} WE = a;if (!tgetstr("we",&a)) {*a++ = '\0';} WS = a;if (!tgetstr("ws",&a)) {*a++ = '\0';} if (f) {abort("wty: insufficent TERMCAP definition");} if (argc == 1) nwindows = 2; else if (argc == 2 && '0' < argv[1][0] && argv[1][0] <= MAXLABEL) nwindows = atoi(argv[1]); else abort("Usage: wty [n]"); s_WS(); flush_screen(); for (i = 0; i < MAXWINDOWS; i++) { window[i].state = 0; window[i].label = i + '1'; window[i].isactive = FALSE; window[i].isvisible = FALSE; window[i].b_isactive = FALSE; window[i].b_isvisible = FALSE; } initflag = TRUE; /* kludge: see do_CCCU */ for (i = 0; i < nwindows; i++) { --nwindows; /* kludge: see do_CC */ do_CC(i + '1'); } initflag = FALSE; do_SS('1'); wgoto('1'); sav_olabel = '1'; } /* init_wty */ @@ END-OF-FILE echo x - release/source/wty/wty.h sed 's/^@@//' > "release/source/wty/wty.h" << '@@ END-OF-FILE' /****************************************************************************\ * Copyright 1985 by George Nelan, Arizona State University. * * All rights reserved. Permission to use, modify, and copy these programs * * and documentation is granted, provided that the copy is not sold and * * that this copyright and permission notice appear on all copies. * \****************************************************************************/ /* Command Sequence Introducer */ #define W_CSI "\033@" /* ESC @ */ /* * ANSI function compatible TERMCAP entries for wty_. * Note: Capabilities marked with [*] are optional in the host definition. * Capabilities marked with (*) are optional only if the corresponding * wty_ TERMCAP capabilities are edited out of the wty_ entry. */ #define W_AL "A" /* Add Line (*) */ /* AM (Automatic Margin) (*) */ #define W_BC "B" /* Backspace Character [*] */ #define W_CD "C" /* Clear to end of Display (*) */ #define W_CE "D" /* Clear to End of line (*) */ #define W_CL "E" /* CLear display (*) */ #define W_CM "F" /* Cursor Motion */ /* CO# (# COlumns) [*] */ #define W_CR "G" /* Carriage Return [*] */ #define W_DC "H" /* Delete Character (*) */ #define W_DL "I" /* Delete Line (*) */ #define W_DO "J" /* DOwn line [*] */ #define W_HO "K" /* HOme cursor (*) */ #define W_IC "L" /* Insert Character (*) */ #define W_IS "M" /* Initialization String [*] */ #define W_KE "N" /* Keypad End [*] */ #define W_KS "O" /* Keypad Start [*] */ /* LI# (# LInes) [*] */ #define W_ND "P" /* NonDestructive space (*) */ #define W_NL "Q" /* NewLine [*] */ #define W_SE "R" /* Standout End (*) */ #define W_SF "S" /* Scroll Forwards (up) (*) */ /* SG# [*] */ #define W_SO "T" /* StandOut start (*) */ #define W_SR "U" /* Scroll Reverse (down) (*) */ #define W_UE "V" /* Underscore End (*) */ /* UG# [*] */ #define W_UP "W" /* UP Line (*) */ #define W_US "X" /* Underscore Start (*) */ #define W_VE "Y" /* Visual End [*] */ #define W_VS "Z" /* Visual Start [*] */ #define W_WE "a" /* Wty End [*] */ #define W_WS "b" /* Wty Start [*] */ @@ END-OF-FILE echo done Brought to you by Super Global Mega Corp .com