Subject: v16i049: Terminal emulator for NeWS window system, Part02/04 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: hoptoad!gnu (John Gilmore) Posting-number: Volume 16, Issue 49 Archive-name: psterm/part02 : psterm part 2 of 4 : To unbundle, sh this file echo sampl.pstermrc cat >sampl.pstermrc <<'@@@ Fin de sampl.pstermrc' % % @(#)$Header: sampl.pstermrc,v 2.0 88/09/16 00:19:10 eric Release $ % to use this file, just copy it to ~/.pstermrc % see the beginning of /usr/NeWS/lib/psterm.ps for more % customizable things PSTermDict begin /DefaultTerminalFont /Courier-Bold def /NoTopBorder { % use psterm -ui NoTopBorder /UserWindowCustom { /BorderTop 3 def /PaintFrameControls nullproc def /PaintFrameLabel nullproc def /PaintFocus nullproc def } def } def /NoIconLabel { % use psterm -ui NoIconLabel /UserWindowCustom { /MyIconLabel () store /IconFont OnePointFont def } def } def % this is just a combination of NoTopBorder and NoIconLabel /BareBones { % use psterm -ui BareBones /UserWindowCustom { /BorderTop 3 def /PaintFrameControls nullproc def /PaintFrameLabel nullproc def /PaintFocus nullproc def /MyIconLabel () store /IconFont OnePointFont def } def } def end @@@ Fin de sampl.pstermrc echo sampl.user.ps cat >sampl.user.ps <<'@@@ Fin de sampl.user.ps' % % @(#)$Header: sampl.user.ps,v 2.1 88/10/04 05:59:50 gnu Release $ % to use this file, copy it to ~/user.ps % % these guys switch on and off some of the parts of the file... /narrowborders true def % give all windows nice skinny borders /startclock false def % start a clock up for me /startconsole false def % start a console window for me /changefocus false def % make the focus paint around the borders /newstretch true def % twiddle with the shape of the stretch box /initialrootimage null def % put the name of a picture here if you want /NetSecurityWanted false store % stop annoying ``security violation'' popups %%%% Redirect stderr for process that have been 'forkunix'ed %% This is done so that error message from forked processed can be seen. %% Note: only available under A/UX, hence the errored... {(/dev/console) setforkunixstderr} errored pop %%%% Set up LiteMenus so that submenus are stroked (outlined) and %% things you can select are inverted. { /OrigPaintBox /PaintBox load def /DiffPaintBox { % value => - dup null ne { dup % save a copy for the getmenuaction MenuItems exch get begin X Y W H end rectpath 5 setrasteropcode getmenuaction type /dicttype eq {stroke} {fill} ifelse } {pop} ifelse } def /PaintBox /DiffPaintBox load def } LitePullRightMenu send DefaultMenu begin /StrokeSelection true def /Shadow 4 def /ShadowColor 0 0 0 rgbcolor def end narrowborders { DefaultWindow begin /FrameFont /Times-Roman findfont 12 scalefont def /ZoomSteps 0 def /BorderLeft 3 def /BorderRight 3 def /BorderBottom 3 def /BorderTop 16 def /stroketop? true def changefocus { /PaintFocus { gsave FrameCanvas setcanvas KeyFocus? {KeyFocusColor} {FrameFillColor} ifelse setcolor stroketop? { BorderLeft FrameHeight BorderTop sub 2 add moveto FrameWidth BorderRight sub FrameHeight BorderTop sub 2 add lineto } { BorderLeft 2 div FrameHeight BorderTop sub moveto BorderLeft 2 div BorderBottom 2 div lineto FrameWidth BorderRight 2 div sub BorderBottom 2 div lineto FrameWidth BorderRight 2 div sub FrameHeight BorderTop sub lineto } ifelse stroke grestore } def /PaintFrameControls nullproc def } if end } if newstretch { DefaultWindow begin /MoveFrameControls { % - => - ([Re]set frame control shapes) gsave CloseControl setcanvas 0 FrameHeight BorderTop sub BorderTop ControlSize sub 2 div add movecanvas StretchControl setcanvas FrameWidth ControlSize sub 0 movecanvas grestore } def /CreateFrameControls { % - => - (Create frame control canvases/items) gsave FrameCanvas setcanvas /CloseControl FrameCanvas newcanvas dup begin /Mapped true def /EventsConsumed /AllEvents def end def /StretchControl FrameCanvas newcanvas dup begin /Mapped true def /EventsConsumed /AllEvents def end def 0 0 ControlSize dup BorderTop le exch BorderLeft le or {ControlSize ControlSize} {BorderTop BorderTop} ifelse rectpath CloseControl reshapecanvas ControlSize BorderRight gt ControlSize BorderBottom gt and { newpath 0 0 moveto 0 BorderBottom lineto ControlSize BorderRight sub BorderBottom lineto ControlSize BorderRight sub ControlSize lineto ControlSize ControlSize lineto ControlSize 0 lineto closepath } { 0 0 ControlSize ControlSize rectpath } ifelse StretchControl reshapecanvas grestore } def end } if /davincipicturemenu [ (angel) (ermine) (lady) (man) (mona-face) (mona-hands) (mona-smile) % (mona-hires) (mona) (stjerome) (virgin) (virgino) ] [{currentkey setrootpicture}] /new DefaultMenu send def /japanesepicturemenu [ (cherries) (fuji) (geese) (puppet) (snow) (stormy) (washing) % (wash-hires) (writing) ] [{currentkey setrootpicture}] /new DefaultMenu send def /sunpicturemenu [ (founders) (sun3110) (sun3160c) (sun3160m) (sun3260h) (sun350) (sun352) (sun352w) (sunballs) (suncase) (sungame) (sunnet) (sunnfs) (sunprism) ] [{currentkey setrootpicture}] /new DefaultMenu send def /travelpicturemenu [ (bryce) (harem) (joshua) (lascruces) (new_york) (pagosa) (saturn) (fullmoon) (shroom) (taj-detail) (taj) (vla) (zion) ] [{currentkey setrootpicture}] /new DefaultMenu send def /picturerootmenu [ (Da Vinci =>) davincipicturemenu (Japanese =>) japanesepicturemenu % (Sun =>) sunpicturemenu (Travel =>) travelpicturemenu ] /new DefaultMenu send def systemdict begin /setrootpicture { gsave framebuffer /Retained true put (NEWSHOME) getenv (/images/) append exch append (.im8) append readcanvas systemdict begin /RootImageCanvas exch def /PaintRoot { gsave framebuffer setcanvas clippath pathbbox scale pop pop RootImageCanvas imagecanvas } def end PaintRoot grestore } def end /roots [ (random) { systemdict begin /DefaultRootGrayOrColor {random random random hsbcolor} def framebuffer /Retained false put PaintRoot end } (normal) { systemdict begin /DefaultRootGrayOrColor {.5 .5 .5 hsbcolor} def framebuffer /Retained false put PaintRoot end } % (wedge) { (pscode/wl.root.ps) run PaintRoot } (dull) { systemdict begin /PaintRoot systemdict /DullPaintRoot get def PaintRoot /RootImageCanvas null def end } (pictures...) picturerootmenu ] /new DefaultMenu send def /term (psterm -ls -t psterm -li 66 -co 132) def % I like big windows /loginmenu [ (local) { term forkunix } % change rsh below to remsh under A/UX (hoptoad) { (rsh hoptoad ) term append forkunix } (polliwog) { (rsh polliwog ) term append forkunix } (pondscum) { (rsh pondscum ) term append forkunix } (console) { (psterm -C -t sun -sl 512 -il Console -fl Console) forkunix } ] /new DefaultMenu send def 0 (Roots =>) roots /insertitem rootmenu send 0 (Login =>) loginmenu /insertitem rootmenu send systemdict begin /DefaultRootGrayOrColor {.5 .5 .5 hsbcolor} def systemdict /DullPaintRoot known not { /DullPaintRoot systemdict /PaintRoot get def } if initialrootimage null ne { initialrootimage setrootpicture } { PaintRoot } ifelse end startclock { (/usr/NeWS/demo/roundclock -s) forkunix pause } if startconsole { (psterm -C -t sun -sl 512 -il Console -fl Console) forkunix pause } if /dragframe? false store % false means continuously repaint % /xhair /xhair_m framebuffer setstandardcursor @@@ Fin de sampl.user.ps echo psterm.tcap cat >psterm.tcap <<'@@@ Fin de psterm.tcap' # # Grasshopper Group NeWS Termcaps 1.8 -HD 88/08/23 # @(#)$Header: psterm.tcap,v 2.1 88/09/23 19:12:35 hugh Release $ # # nterm is a fancy vt220 terminal emulator for the NeWS window system nt|nterm:\ :cr=^M:do=^J:nl=^J:bl=^G:le=^H:ho=\E[H:\ :co#80:li#65:cl=\E[H\E[2J:bs:am:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:\ :ce=\E[K:cd=\E[J:so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\ :md=\E[1m:mr=\E[7m:me=\E[m:\ :ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D:kb=^H:\ :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:pt:sf=\n:sr=\EM:\ :al=\E[L:dl=\E[M:dc=\E[P:\ :MT:ks=\E[?1h\E=:ke=\E[?1l\E>:\ :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l:\ :rs=\E[r\E<\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l:xn:\ :AL=\E[%dL:DL=\E[%dM:IC=\E[%d@:DC=\E[%dP:\ :ti=\E[2J\E[?47h:te=\E[?47l:im=\E[4h:ei=\E[4l:\ :ts=\E[?E\E[?%i%dT:fs=\E[?F:es:ds=\E[?E: nt|nterms|nterm terminal emulator (small)(NeWS window system):\ :co#80:li#24:tc=nterm: # # Termcap for NeWS's psterm from Eric Messick & Hugh Daniel p1|psterm-96x48:\ :co#96:li#48:tc=psterm-basic: p1|psterm-90x28:\ :co#90:li#28:tc=psterm-basic: p1|psterm-80x24:\ :co#80:li#24:tc=psterm-basic: p1|psterm|psterm-basic|psterm-80x34:\ :am:bs:al=\EA:cd=\EB:ce=\EC:cl=^L:cm=\E%d;%d;:cs=\EE%d;%d;:\ :dc=\EF:dl=\EK:do=\EP:ei=\ENi:el=\ENl:fs=\ENl:\ :ho=\ER:hs:im=\EOi:is=\EN*:km:\ :kd=\E[B:ku=\E[A:kr=\E[C:kl=\E[D:\ :mb=\EOb:md=\EOd:\ :me=\EN*:mr=\EOr:nd=\EV:pt:rc=\034:rs=\EN*:sc=\035:\ :se=\ENo:sf=\EW:sl=\EOl:so=\EOo:sr=\EX:te=\ENt:\ :ti=\EOt:ts=\EOl:ue=\ENu:\ :le=\ET:ll=\EU:ul:up=\EY:us=\EOu:vb=\EZ:\ :co#80:li#34: # This is a faster termcap for psterm, Warning: if you use this termcap # some control characters you type will do strange things to the screen. p1|psterm-fast:\ :am:bs:al=^A:cd=^B:ce=^C:cl=^L:cm=^D%d;%d;:cs=^E%d;%d;:\ :dc=^F:dl=^K:do=^P:ei=^Ni:el=^Nl:fs=^Nl:\ :ho=^R:hs:im=^Oi:is=^N*:km:\ :kd=\E[B:ku=\E[A:kr=\E[C:kl=\E[D:\ :mb=^Ob:md=^Od:\ :me=^N*:mr=^Or:nd=^V:pt:rc=\034:rs=^N*:sc=\035:\ :se=^No:sf=^W:sl=^Ol:so=^Oo:sr=^X:te=^Nt:\ :ti=^Ot:ts=^Ol:ue=^Nu:\ :le=^T:ll=^U:ul:up=^Y:us=^Ou:vb=^Z:\ :co#80:li#34: #### End of stuff added by Grasshopper Group @@@ Fin de psterm.tcap echo psterm.tinfo cat >psterm.tinfo <<'@@@ Fin de psterm.tinfo' # # Grasshopper Group NeWS Termcaps 1.9 -HD 88/9/03 # @(#)$Header: psterm.tinfo,v 2.2 88/10/05 17:36:11 eric Release $ # # nterm is a fancy vt220 terminal emulator for the NeWS window system nterm, am, xenl, eslok, cols#80, lines#65, bel=^G, cr=\r, clear=\E[H\E[2J, el=\E[K, ed=\E[J, cup=\E[%i%p1%d;%p2%dH, cud1=\n, home=\E[H, cub1=\b, cuf1=\E[C, cuu1=\E[A, dch1=\E[P, dl1=\E[M, dsl=\E[?E, bold=\E[1m, smcup=\E[2J\E[?47h, smir=\E[4h, rev=\E[7m, smso=\E[7m, smul=\E[4m, sgr0=\E[m, rmcup=\E[?47l, rmir=\E[4l, rmso=\E[m, rmul=\E[m, fsl=\E[?F, is1=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l, il1=\E[L, kbs=\b, kcud1=\E[B, kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, kcub1=\E[D, kcuf1=\E[C, kcuu1=\E[A, rmkx=\E[?1l\E>, smkx=\E[?1h\E=, nel=\r\n, dch=\E[%p1%dP, dl=\E[%p1%dM, ich=\E[%p1%d@, il=\E[%p1%dL, rs1=\E[r\E<\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l, ind=\n, ri=\EM, ht=\t, tsl=\E[?E\E[?%i%p1%dT, # Small nterm terminal emulator termcap nterms|small nterm, cols#80, lines#24, bel=^G, cr=\r, cud1=\n, cub1=\b, kbs=\b, kcud1=\n, kcub1=\b, nel=\r\n, ind=\n, use=nterm, # # Termcap for NeWS's psterm from Eric Messick & Hugh Daniel psterm-96x48, cols#96, lines#48, bel=^G, cr=\r, cud1=\n, cub1=\b, kbs=\b, kcud1=\n, kcub1=\b, nel=\r\n, ind=\n, use=psterm-basic, psterm-90x28, cols#90, lines#28, bel=^G, cr=\r, cud1=\n, cub1=\b, kbs=\b, kcud1=\n, kcub1=\b, nel=\r\n, ind=\n, use=psterm-basic, psterm-80x24, cols#80, lines#24, bel=^G, cr=\r, cud1=\n, cub1=\b, kbs=\b, kcud1=\n, kcub1=\b, nel=\r\n, ind=\n, use=psterm-basic, psterm|psterm-basic|psterm-80x34, am, km, hs, ul, cols#80, lines#34, bel=^G, cr=\r, csr=\EE%p1%d;%p2%d;, clear=\f, el=\EC, ed=\EB, cup=\E%p1%d;%p2%d;, cud1=\EP, home=\ER, cub1=\ET, cuf1=\EV, ll=\EU, cuu1=\EY, dch1=\EF, dl1=\EK, blink=\EOb, bold=\EOd, smcup=\EOt, smir=\EOi, rev=\EOr, smso=\EOo, smul=\EOu, sgr0=\EN*, rmcup=\ENt, rmir=\ENi, rmso=\ENo, rmul=\ENu, flash=\EZ, fsl=\ENl, is1=\EN*, il1=\EA, kbs=\b, kcud1=\E[B, kcub1=\E[D, kcuf1=\E[C, kcuu1=\E[A, nel=\r\n, rs1=\EN*, rc=^\, sc=^], ind=\EW, ri=\EX, ht=\t, tsl=\EOl, # This is a faster termcap for psterm, Warning: if you use this termcap # some control characters you type will do strange things to the screen # on systems that echo typed control characters to the users terminal. psterm-fast, am, km, hs, ul, cols#80, lines#34, bel=^G, cr=\r, csr=^E%p1%d;%p2%d;, clear=\f, el=^C, ed=^B, cup=^D%p1%d;%p2%d;, cud1=^P, home=^R, cub1=^T, cuf1=^V, ll=^U, cuu1=^Y, dch1=^F, dl1=^K, blink=^Ob, bold=^Od, smcup=^Ot, smir=^Oi, rev=^Or, smso=^Oo, smul=^Ou, sgr0=^N*, rmcup=^Nt, rmir=^Ni, rmso=^No, rmul=^Nu, flash=^Z, fsl=^Nl, is1=^N*, il1=^A, kbs=\b, kcud1=\E[B, kcub1=\E[D, kcuf1=\E[C, kcuu1=\E[A, nel=\r\n, rs1=^N*, rc=^\, sc=^], ind=^W, ri=^X, ht=\t, tsl=^Ol, #### End of stuff added by Grasshopper Group @@@ Fin de psterm.tinfo echo slave.c cat >slave.c <<'@@@ Fin de slave.c' /* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. * Users may copy, modify or distribute this file at will. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * This file is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even * if Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * Modifications to the original Sun Microsystems, Inc. source code * made by the Grasshopper Group are in the Public Domain. * * Extensions to this file by Eric Messick of the Grasshopper Group. * * Grasshopper Group * 212 Clayton St * San Francisco, CA 94117 * */ #ifndef lint static char sccsid[] = "@(#)slave.c 9.6 88/01/19 Copyright 1985 Sun Micro"; static char RCSid[] = "@(#)$Header: slave.c,v 2.1 88/10/04 04:22:54 eric Release $"; #endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ /*- slave.c slave.c, Tue Apr 1 09:17:08 1986 David Rosenthal, Sun Microsystems */ #include #include #include #ifdef REF #include #endif extern void exit(); extern unsigned sleep(); extern void perror(); #ifndef HAVE_VFORK #define vfork() fork() #endif int Mfd, Sfd; /* XXX - there should be a library routine to get a pty */ char ptcname[] = "/dev/ptyXX"; char ptsname[] = "/dev/ttyXX"; int pgrp; extern int errno; extern int BackGround; FILE * spawn_slave(name, args) char *name, **args; { FILE *Master; int i, pid, uid, gid; unsigned delay = 2 ; #define MAXDELAY 120 char *gp, *tp; GetTTYDefaults(); #ifdef SYSVREF /* Micom-Interlan software installs some non-streams based pty's on 'p' */ #ifdef INTERLANTCP for (gp = "qrst"; *gp; gp++) #else for (gp = "pqrst"; *gp; gp++) #endif #else for (gp = "pqrst"; *gp; gp++) #endif for (tp = "0123456789abcdef"; *tp; tp++) { ptcname[sizeof ("/dev/pty")-1] = *gp; ptcname[sizeof ("/dev/ptyX")-1] = *tp; if ((Mfd = open(ptcname, 2)) < 0) continue; ptsname[sizeof ("/dev/pty")-1] = *gp; ptsname[sizeof ("/dev/ptyX")-1] = *tp; if ((Sfd = open(ptsname, 2)) >= 0) goto done; close(Mfd); } done: if (Mfd < 0 || Sfd < 0) return (NULL); uid = getuid(), gid = getgid(); (void) chown(ptsname, uid, gid); /* set tty ownership */ (void) chmod(ptsname, 0622); /* set tty protection */ /* * Establish tty state. */ SetTTYState(Sfd); /* * If we're to operate in the background, fork * to return control to the shell and disassociate * ourselves from the tty. The caller closes * file descriptors so that, for example, rsh * will not be kept around. */ if (BackGround) { if (fork()) exit(0); (void) setpgrp(0, getpid()); DisAssociateTTY(); } else AssociateTTY(); Master = fdopen(Mfd, "r+"); while ((pid = vfork()) < 0 && errno == EAGAIN) { sleep(delay); if ((delay <<= 1) > MAXDELAY) { close (Mfd); close (Sfd); return (NULL); } } if (pid == 0) { /* * Setup controlling tty. */ for (i = 0; i < 3; i++) (void) dup2(Sfd, i); addut(uid, ptsname); for (i = getdtablesize(); i > 2; i--) (void) close(i); SetupControllingTTY(ptsname); (void) setuid(uid), (void) setgid(gid); execvp(name, args); perror(name); exit(errno); } pgrp = pid; close(Sfd); return (Master); } CleanupPty() { rmut(); (void) chown(ptsname, 0, 0); /* revoke ownership */ (void) chmod(ptsname, 0666); /* revoke protection */ } @@@ Fin de slave.c echo io.c cat >io.c <<'@@@ Fin de io.c' /* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. * Users may copy, modify or distribute this file at will. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * This file is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even * if Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * Modifications to the original Sun Microsystems, Inc. source code * made by the Grasshopper Group are in the Public Domain. * * Extensions to this file by Eric Messick of the Grasshopper Group. * * Grasshopper Group * 212 Clayton St * San Francisco, CA 94117 * */ #ifndef lint static char sccsid[] = "@(#)io.c 9.7 88/01/19 Copyright 1985 Sun Micro"; static char RCSid[] = "@(#)$Header: io.c,v 2.1 88/10/04 04:22:45 eric Release $"; #endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ #ifdef REF #include #include #endif #ifndef HAVE_SELECT #ifdef INTERLANTCP #include #endif #include #include #endif #include #include #include #include #include extern void perror(); #define MAX(a,b) ((a)>(b)?(a):(b)) #define KBDBUFSIZE 4096 #define PTYBUFSIZE 8192 static char kbdbuf[KBDBUFSIZE], *kbdfront, *kbdback, *kbdend; static char ptybuf[PTYBUFSIZE]; /* buffer for reading from pty slave */ static int wfproto; /* prototype for write select mask */ extern int Mfd; extern int errno; extern PSFILE *PostScript; extern int PageMode; extern int PageFull; extern int fontisfixedwidth; extern int FastPaint; extern int DoScrolling; static int pty_out(); static int kbd_input(); /* * Input dispatcher: take data from postscript * program and pty, dispatching each to the * appropriate handler. */ terminal(cfd, kfd) { register int n; #ifdef HAVE_SELECT int rf, wf; int max; #else /* !HAVE_SELECT */ #define PTY 0 #define KEYBOARD 1 #define POSTSCRIPT 2 #define NFDS 3 struct pollfd rwf[NFDS]; int i; #endif /* !HAVE_SELECT */ int keyboard, pty, postscript, ndeferred; char *deferred; PageFull = 0; /* not inhibiting scrolling */ ndeferred = 0; /* no deferred output */ keyboard = 1< 0) kbd_input(n); } /* * If pty_out or kbd_input changed * PageFull, loop to inhibit output. */ if (PageFull) /* loop if inhibiting output */ continue; /* * If screen output was blocked due to previous PageFull condition, * resume it. Note that this may leave us back in PageFull mode, * and interrupted tcap ops may still need the chars in ptybuf. */ #ifdef lint deferred = (char *)0 ; #endif if (ndeferred) { n = tc_display((u_char *)deferred, ndeferred); if (n > 0) deferred += (ndeferred - n); ndeferred = n; tc_refresh(0); if (PageFull) /* if PageFull, can't touch ptybuf */ continue; } /* * Finally, take pty stuff and send it to the display * except when we're already flush with output. */ #ifdef HAVE_SELECT if ((wfproto & postscript) == 0 && rf & pty) #else if ((wfproto & postscript) == 0 && rwf[PTY].revents & POLLIN) #endif { errno = 0; n = read(cfd, ptybuf, PTYBUFSIZE); #ifdef HAVE_SELECT if (n < 0) { if (errno != EIO) { /* BEGIN SUN BUG WORKAROUND */ if (errno == EWOULDBLOCK) continue; /* END SUN BUG WORKAROUND */ perror("pty"); } break; } #else if (n == 0) continue; if (n < 0) { if (errno == EAGAIN) continue; perror("pty"); break; } #endif ndeferred = tc_display((u_char *)ptybuf, n); if (ndeferred) deferred = ptybuf + (n - ndeferred); tc_refresh(0); } #ifdef notdef if (wfproto & postscript) fprintf(stderr, "blocked\n"); #endif } } /* * Flush PostScript destined for window. * If all data was not written, then mark * the select mask to find out when data * has been flushed to the network. */ FlushPostScript() { if (!(psio_flush(PostScript) == 0)) wfproto |= 1< 0) { if (PageMode) { if (PageFull) { switch (*kbdback) { case '\r': --cc, kbdback++; scrollreset(1); break; case ' ': --cc, kbdback++; /* fall thru... */ default: scrollreset(0); break; } if (cc < 1) { kbdfront = kbdback = kbdbuf; return; } } else scrollreset(0); } cc = write(Mfd, kbdback, (unsigned)cc); if (cc < 0) { if (errno != EWOULDBLOCK) perror("master pty"); } else kbdback += cc; } if (kbdfront != kbdback) wfproto |= 1< 0 && *p++ != '\n') ; for (p = (unsigned char *)kbdfront, n2 = 0, d = p; n > 0;) { if (*p == EVENT_ESCAPE) { p++ ; if (--n > 0) { n-- ; switch (*p++) { case EVENT_TOGGLEAM: toggleautomargins(); break; case EVENT_TOGGLEPM: togglepagemode(); if (PageFull) { /* resume output if blocked */ scrollreset(0); dorefresh++; } break; case EVENT_REPAIR: RefreshSuppressed = 0 ; doresize++ ; break; case EVENT_RECTSEL: rect = 1 ; /* fall through... */ case EVENT_BEGINSEL: /* col row rank size mode preview */ if (n>0) { col = atoi((char *)p); NEXTVAL; } if (n>0) { row = atoi((char *)p); NEXTVAL; } if (n>0) { rank = atoi((char *)p); NEXTVAL; tc_deselect(rank); tc_extend_selection(col, row, rank, rect); dorefresh++; rect = 0 ; } break; case EVENT_EXTRECT: rect = 1 ; /* fall through... */ case EVENT_EXTSEL: /* col row rank size mode preview */ if (n>0) { col = atoi((char *)p); NEXTVAL; } if (n>0) { row = atoi((char *)p); NEXTVAL; } if (n>0) { rank = atoi((char *)p); NEXTVAL; tc_extend_selection(col, row, rank, rect); dorefresh++; rect = 0 ; } break; case EVENT_ENDSEL: /* col row rank size mode preview */ if (n>0) { col = atoi((char *)p); NEXTVAL; } if (n>0) { row = atoi((char *)p); NEXTVAL; } if (n>0) { rank = atoi((char *)p); NEXTVAL; tc_extend_selection(col, row, rank, rect); tc_report_selection(rank); dorefresh++; } break; case EVENT_ESCAPE: *d++ = EVENT_ESCAPE ; n2++ ; break; case EVENT_ROWCOL: if (n>0) { col = atoi((char *)p); NEXTVAL; } if (n>0) { row = atoi((char *)p); NEXTVAL; change_rowcol(row, col); } break; case EVENT_FONTFIXED: fontisfixedwidth = 1 ; break; case EVENT_FONTVAR: fontisfixedwidth = 0 ; break; case EVENT_SCROLL: if (n>0) { row = atoi((char *)p); NEXTVAL; scroll_to(row); dorefresh++; } break; case EVENT_SAVESIZE: if (n>0) { row = atoi((char *)p); NEXTVAL; set_scroll_save(row); dorefresh++; } break; case EVENT_ENDREFRESH: end_refresh(); dorefresh++; break; case EVENT_FASTPAINT: if (n>0) { FastPaint = atoi((char *)p); NEXTVAL; } break; case EVENT_DOSCROLL: if (n>0) { DoScrolling = atoi((char *)p); NEXTVAL; } break; } } } else { *d++ = *p++ ; n-- ; n2++ ; } } if (doresize) do_display_resize(); if (n2 > 0) kbdfront += n2; if (kbdfront != kbdback) { tc_deselect(1); pty_out(); } if (dorefresh) tc_refresh(0); } @@@ Fin de io.c echo main.c cat >main.c <<'@@@ Fin de main.c' /* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. * Users may copy, modify or distribute this file at will. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * This file is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even * if Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * Modifications to the original Sun Microsystems, Inc. source code * made by the Grasshopper Group are in the Public Domain. * * Extensions to this file by Eric Messick of the Grasshopper Group. * * Grasshopper Group * 212 Clayton St * San Francisco, CA 94117 * */ #ifndef lint static char sccsid[] = "@(#)main.c 9.7 88/01/19 Copyright 1985 Sun Micro"; static char RCSid[] = "@(#)$Header: main.c,v 2.2 88/10/04 04:22:48 eric Release $"; #endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ #include #include #include #include #include #include #include #ifdef SYSVREF #ifdef INTERLANTCP #include #include #include #include #else #include #endif #else #ifdef REF #include #endif #include #include #include #endif #ifdef REF #include #endif #ifdef SYSVREF #define SIGCHLD SIGCLD #else #include #endif extern void exit(); extern void perror(); extern char *strcpy(); #ifndef bcopy extern void bcopy(); #endif extern void endpwent(); extern void free(); extern char *strcat(); extern PSFILE *Connect_To_Server(); int console; static int KillChild(); static int ReapChild(); static char *term = NULL; static int seed = 0; static int Persist; static int loginshell = 0; static int tflag = 0; static char *framelabel = NULL; static char *iconlabel = NULL; static char *userinit = "" ; static char *font = "" ; static int xorg = -1; static int yorg = -1; static int iconx = -1; static int icony = -1; static int reload = 0; static int starticonic = 0 ; static int save_lines = 0 ; int fontsize = -1; int BackGround = 1; int PageMode = 0; /* "pause on end of page" mode */ int userCharsPerLine = -1; int userLinesPerScreen = -1; main(argc,argv) int argc; char **argv; { char *s_name, **s_args, *argv0 = argv[0]; FILE *Client; PSFILE *Keyboard; extern char *getenv(); extern PSFILE *tc_init_screen(); extern FILE *spawn_slave(); BackGround = isatty(0) ; for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { if (strcmp(argv[0], "-bg") == 0 || strcmp(argv[0], "-ga") == 0) { BackGround++; /* put ourself in the background */ continue; } if (strcmp(argv[0], "-C") == 0) { console++; continue; } if (strcmp(argv[0], "-co") == 0) { if (--argc > 0) userCharsPerLine = atoi(*++argv); continue; } if (strcmp(argv[0], "-F") == 0) { if (--argc > 0) { font = *++argv; } continue; } if (strcmp(argv[0], "-f") == 0) { continue; } if (strcmp(argv[0], "-fg") == 0) { BackGround = 0 ; /* don't put ourself in the background */ continue; } if (strcmp(argv[0], "-fl") == 0) { if (--argc > 0) framelabel = *++argv; continue; } if (strcmp(argv[0], "-fs") == 0) { if (--argc > 0) fontsize = atoi(*++argv); continue; } if (strcmp(argv[0], "-ic") == 0) { starticonic++; continue; } if (strcmp(argv[0], "-il") == 0) { if (--argc > 0) iconlabel = *++argv; continue; } if (strcmp(argv[0], "-ixy") == 0) { if (--argc > 0) iconx = atoi(*++argv); if (--argc > 0) iconx = atoi(*++argv); if (iconx >= 0 && icony >= 0) continue; } if (strcmp(argv[0], "-li") == 0) { if (--argc > 0) userLinesPerScreen = atoi(*++argv); continue; } if (strcmp(argv[0], "-ls") == 0) { loginshell++; continue; } if (strcmp(argv[0], "-pm") == 0 || strcmp(argv[0], "-ps") == 0) { PageMode++; /* enable page mode */ continue; } if (strcmp(argv[0], "-r") == 0) { reload++; continue; } if (strcmp(argv[0], "-s") == 0) { if (--argc > 0) seed = atoi(*++argv); continue; } if (strcmp(argv[0], "-sl") == 0) { if (--argc > 0) save_lines = atoi(*++argv); continue; } if (strcmp(argv[0], "-t") == 0) { if (--argc > 0) { term = *++argv; tflag++; } continue; } if (strcmp(argv[0], "-ui") == 0) { if (--argc > 0) { userinit = *++argv; } continue; } if (strcmp(argv[0], "-w") == 0) { Persist++; continue; } if (strcmp(argv[0], "-xy") == 0) { if (--argc > 0) xorg = atoi(*++argv); if (--argc > 0) yorg = atoi(*++argv); if (xorg >= 0 && yorg >= 0) continue; } fprintf(stderr, "Usage: %s %s \\\n\t%s \\\n\t%s \\\n\t%s\n", argv0, "[-bg] [-C] [-co columns] [-F font] [-f] [-fg] [-fl framelabel]", "[-fs fontsize] [-ic] [-il iconlabel] [-ixy x y] [-li lines]", "[-ls] [-pm] [-r] [-sl savelines] [-t termtype] [-ui userinit] [-w]", "[-xy x y] [command]"); (void) Connect_To_Server(); Fatal("psterm: error in arguments", (char *)NULL); } if (loginshell) { char *s, *p, *malloc(); #ifndef SYSVREF char *rindex(), *index(); #else #define index(s, c) (char *)strchr(s, c) #endif struct passwd *pw, *getpwuid(); static char *loginargv[4]; s_name = "/bin/sh"; /* default shell name */ s_args = loginargv; s_args[0] = "-sh"; s_args[1] = 0; if (pw = getpwuid(getuid())) { if (pw->pw_dir) set_environment_var("HOME", pw->pw_dir); if (pw->pw_name) { set_environment_var("LOGNAME", pw->pw_name); set_environment_var("USER", pw->pw_name); } if (pw->pw_shell) { if (s = rindex(pw->pw_shell,'/')) { p = malloc ((unsigned)strlen(s)+4); if (p) { sprintf(p, "-%s", s+1); s_args[0] = p; } p = malloc((unsigned)strlen(pw->pw_shell)+4); if (p) { s_name = p; strcpy(s_name, pw->pw_shell); } set_environment_var("SHELL",pw->pw_shell); } } endpwent(); } if (argc > 0) { int i, count = 0; /* * This goofy business in case someone wants to run complex * shell commands after login-shell initialization... */ for (i=0; ih_name); set_environment_var("NEWSSERVER", srv); } } } if (framelabel == NULL) { static char labelbuf[128]; gethostname(labelbuf, sizeof labelbuf); if ((p = index(labelbuf, '.')) != NULL) *p = 0; if (argc > 0) { strcat(labelbuf, " "); strcat (labelbuf, argv[0]); } framelabel = labelbuf; } if (iconlabel == NULL) iconlabel = framelabel; } else if (argc > 0) { s_name = *argv; s_args = argv; } else { #ifndef SYSVREF static char *def_argv[] = { "csh", NULL}; #else static char *def_argv[] = { "-sh", NULL}; #endif s_args = def_argv; if ((s_name = getenv("SHELL")) == NULL) { #ifndef SYSVREF s_name = *def_argv; s_args[0] = s_name; #else s_name = "sh"; #endif } else { s_args[0] = s_name; } } if ( !tflag || term == NULL) { #ifdef RandomBehaviour /* Choose one at random - should scan termcap? */ static char * def_term[] = { "ansi", "h19", "wyse", }; if (seed == 0) seed = getpid(); srand(seed); term = def_term[(rand()>>4)%((sizeof def_term)/(sizeof def_term[0]))]; #else term = "psterm"; #endif } if (BackGround) { int i; /* * Close any extraneous files. */ for (i = getdtablesize(); i > 2; i--) close(i); } if (xorg < 0) xorg = 0; if (yorg < 0) yorg = 0; Keyboard = tc_init_screen(term, xorg, yorg, fontsize, framelabel, iconlabel, reload, userinit, font, starticonic, iconx, icony, save_lines); if (Keyboard == NULL) { char *foo; foo = getenv("NEWSSERVER"); if (foo) Fatal("Can't connect to NeWS server at: %s", foo); else Fatal("Can't connect to NeWS server; did you set NEWSSERVER?", (char *)NULL); } tc_initmodemenu(); set_environment_var("TERM", term); if ((Client = spawn_slave(s_name, s_args)) == NULL) Fatal("Cannot spawn %s", s_name); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, KillChild); if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, KillChild); signal(SIGHUP, KillChild); signal(SIGTERM, KillChild); signal(SIGCHLD, ReapChild); terminal(fileno(Client), psio_fileno(Keyboard)); Exit(0); /*NOTREACHED*/ } Fatal(fmt, a1) char *fmt, *a1; { extern int ConnectionEstablished; char buf[1024]; if (ConnectionEstablished) { sprintf(buf, fmt, a1); PostScriptErrorMessage(buf); } else { fprintf(stderr, "psterm: "); fprintf(stderr, fmt, a1); fprintf(stderr, ".\n"); } Exit(1); } Exit(status) { CleanupPty(); exit(status); } static KillChild(sig) { extern int pgrp; if (pgrp != 0) killpg(pgrp, sig); CleanupPty(); signal(sig, SIG_DFL); kill(0, sig); } static ReapChild() { #ifdef HAVE_WAIT3 union wait status; int pid = wait3(&status, WNOHANG, 0); #else /* !HAVE_WAIT3 */ int status, pid = wait(&status); signal(SIGCHLD, ReapChild); #endif if (pid < 0) perror("fruitless wait3"); else if (Persist == 0) Exit(0); } set_environment_var(name, value) char *name, *value; { register len; register char **ap; register char **new; register char *buf; static alloced = 0; extern char **environ; len = strlen(name); buf = (char *) malloc((unsigned)(len + strlen(value) + 2)); if (buf==NULL) return; sprintf(buf, "%s=%s", name, value); for (ap = environ; *ap; ap++) if (strncmp(*ap, buf, len+1) == 0) { *ap = buf; return; } len = ap - environ; new = (char **) malloc((unsigned)((len + 2) * sizeof(char *))); if (new==NULL) return; bcopy((char *)environ, (char *)new, len * sizeof(char *)); new[len] = buf; new[len + 1] = 0; if (alloced) free((char *)environ); alloced = 1 ; environ = new; } unsetenv(name) char *name; { register len; register char **ap; register char **new; extern char **environ; len = strlen(name); for (new = ap = environ; (*new = *ap) != NULL; ap++) { if (strncmp(*ap, name, len) == 0 && (*ap)[len] == '=') { /* Memory leak bug: we cannot free(*ap) here, because we don't know * whether *ap was created with putenv(). */ } else new++; } } @@@ Fin de main.c echo display.c cat >display.c <<'@@@ Fin de display.c' /* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. * Users may copy, modify or distribute this file at will. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * This file is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even * if Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * Modifications to the original Sun Microsystems, Inc. source code * made by the Grasshopper Group are in the Public Domain. * * Extensions to this file by Eric Messick of the Grasshopper Group. * * Grasshopper Group * 212 Clayton St * San Francisco, CA 94117 * */ #ifndef lint static char sccsid[] = "@(#)display.c 9.5 88/01/19 Copyright 1985 Sun Micro"; static char RCSid[] = "@(#)$Header: display.c,v 2.2 88/10/04 05:11:23 eric Release $"; #endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ /*- display.c display.c, Wed Mar 26 15:56:31 1986 David Rosenthal, Sun Microsystems */ #ifdef notdef #define Diagnose #endif /* * Screen display module * * The external interface of this module is the routine tc_refresh(), and the * initialization routine tc_init_screen(). */ #include #ifdef REF #include #endif #include #include #include #include "screen.h" #include "tcap.h" extern void free(); #ifndef bzero extern void bzero(); #endif #ifndef bcopy extern void bcopy(); #endif extern void perror(); #define CHARS_PER_LINE 80 #define LINES_PER_SCREEN 24 #define TypicalWidth 80 #define min(x, y) (((x)<(y))?(x):(y)) int CharsPerLine = CHARS_PER_LINE; int LinesPerScreen = LINES_PER_SCREEN; struct pair Dot = {0, 0}; int fontisfixedwidth = 1 ; int ConnectionEstablished = 0 ; static Repairing; static struct pair ScreenDot = {0, 0}; static char *CursorChar = " "; static u_char CursorProp = 0 ; extern int PageFull; int RefreshSuppressed = 1; int TotalScrollLength = 0 ; int ScrollLength = 0 ; int ScrollY = 0 ; int ScrollLinesSaved = 0 ; int userScrollLength = 0 ; int FastPaint = 1 ; int DoScrolling = 1 ; struct line **scroll_area; char * Malloc(size) int size; { extern char *malloc(); char *ret; if ((ret=malloc((unsigned)size))==NULL) Fatal("Out of Memory", (char *)NULL); return ret; } static RemoveCursor() { if ((ScreenDot.x >= 0) && (! (CursorProp & ReverseVideoLook))) CursorDown(ScreenDot.x, ScreenDot.y, CursorChar, 1); ScreenDot.x = -1; } static PlaceCursor(x, y) { register struct line *l; if (x >= CharsPerLine) x = CharsPerLine - 1; if (x < 0) x = 0; if (y >= LinesPerScreen) y = LinesPerScreen - 1; if (y < 0) y = 0; ScreenDot.x = x ; ScreenDot.y = y + ScrollLength - LinesPerScreen - ScrollY ; l = screen[y]; CursorChar = l->body + x ; CursorProp = l->prop[x] ; if (ScreenDot.y >= LinesPerScreen) { ScreenDot.x = -1 ; return; } if (!PageFull) /* hide cursor if output blocked */ CursorUp(ScreenDot.x, ScreenDot.y, CursorChar, 1); } set_scroll_save(length) int length; { int i, j, delta; struct line *line, **new_lines; char *body; u_char *prop; tc_deselect(0); /* do this before we move the lines around */ userScrollLength = length ; if (!RefreshSuppressed) ToggleScrollBar(length); if (length < LinesPerScreen) length = LinesPerScreen ; if (length > TotalScrollLength) { new_lines = (struct line **) Malloc(2 * length * sizeof(struct line *)) ; for (i=length-ScrollLength, j=0; j0) { for (i=0; ibody) free(lines[i]->body); if (lines[i]->prop) free((char *)lines[i]->prop); free((char *)lines[i]); } lines[i] = lines[i+delta] ; lines[i+delta] = NULL ; } } else for (i=ScrollLength-1; i>=0; i--) lines[i-delta] = lines[i] ; } for (i=0; ibody = Malloc(TypicalWidth) ; for (j=0; jbody[j] = ' ' ; line->prop = (u_char *)Malloc(TypicalWidth) ; bzero((char *)line->prop, TypicalWidth); line->buffer_length = TypicalWidth ; line->length = 0 ; line->changeposition = 0 ; line->end_of_changes = 0 ; line->usedtobe = -1 ; line->flags = 0 ; lines[i] = line ; } ScrollY += length - ScrollLength ; ScrollLength = length ; if (ScrollY < 0) ScrollY = 0 ; if (ScrollY > ScrollLength - LinesPerScreen) ScrollY = ScrollLength - LinesPerScreen ; for (i=ScrollLength-LinesPerScreen; i < ScrollLength; i++) { if (lines[i]->buffer_length <= CharsPerLine) { body = Malloc(CharsPerLine+1); prop = (u_char *) Malloc(CharsPerLine+1); length = lines[i]->length ; if (lines[i]->buffer_length > 0) { bcopy(lines[i]->body, body, length); bcopy((char *)lines[i]->prop, (char *)prop, length); free(lines[i]->body); free((char *)lines[i]->prop); } bzero((char *)&prop[length], CharsPerLine - length + 1); for (; length <= CharsPerLine; length++) body[length] = ' ' ; lines[i]->body = body ; lines[i]->prop = prop ; lines[i]->buffer_length = CharsPerLine + 1 ; } } /* if (ScrollLinesSaved > ScrollLength) */ ScrollLinesSaved = ScrollLength ; if (ScrollLinesSaved < LinesPerScreen) ScrollLinesSaved = LinesPerScreen ; screen = &lines[ScrollLength - LinesPerScreen] ; } scroll_to_bottom() { scroll_to(ScrollLinesSaved - LinesPerScreen); } scroll_to(scrolly) int scrolly; { int i, lesser, greater; scrolly += ScrollLength - ScrollLinesSaved ; if (scrolly < 0) scrolly = 0 ; if (scrolly > ScrollLength - LinesPerScreen) scrolly = ScrollLength - LinesPerScreen ; if (scrolly != ScrollY) { if (scrolly < ScrollY) { lesser = scrolly; greater = ScrollY; } else { lesser = ScrollY; greater = scrolly; } for (i=lesser; iusedtobe = -1 ; for (i=lesser+LinesPerScreen; iusedtobe = -1 ; } ScrollY = scrolly ; } ScrollSaveLine(line) struct line *line; { int i; struct line *new; if (ScrollLength <= LinesPerScreen) return; if (ScrollLinesSaved < ScrollLength) ScrollLinesSaved++; for (i=ScrollLength; i>ScrollLength-LinesPerScreen; i--) lines[i] = lines[i-1] ; new = lines[i] = lines[0] ; if (new->buffer_length < line->length + 1) { free(new->body); free((char *)new->prop); new->body = Malloc((int)line->length + 1); new->prop = (u_char *) Malloc((int)line->length + 1); new->buffer_length = line->length + 1 ; } bcopy(line->body, new->body, (int)line->length+1); bcopy((char *)line->prop, (char *)new->prop, (int)line->length+1); new->length = line->length ; new->changeposition = 0 ; new->end_of_changes = CharsPerLine + 1 ; new->usedtobe = line->usedtobe ; new->flags = line->flags ; lines++ ; if (&lines[ScrollLength] >= &scroll_area[TotalScrollLength * 2]) { bcopy((char *)lines, (char *)scroll_area, sizeof(struct line **)*ScrollLength); lines = scroll_area ; } screen = &lines[ScrollLength - LinesPerScreen] ; } /* --------------- External Routines Below ------------------- */ do_display_resize() { register i; /* tc_refresh(0);*/ BeginRepair(); Repairing++; ReInitialize(); for (i = 0; ichangeposition = 0; lines[i+ScrollY]->end_of_changes = CharsPerLine ; } tc_refresh(0); tc_refresh_selection(); psio_flush(PostScript); } PSFILE * Connect_To_Server() { extern PSFILE *ps_open_PostScript(); PSFILE *f; if ((f = ps_open_PostScript()) == NULL) { return (NULL); } ConnectionEstablished = 1 ; return f; } PSFILE * tc_init_screen(term, xorg, yorg, font_size, framelabel, iconlabel, reload, userinit, font, starticonic, iconx, icony, savelines) char *term; int xorg, yorg, font_size; char *framelabel, *iconlabel; int reload; char *userinit, *font; int starticonic, iconx, icony, savelines; { PSFILE *f; char frametitle[100]; char host[100]; f = Connect_To_Server(); if (f==NULL) return NULL; PSDefs(reload); psio_flush(PostScript); if (framelabel == NULL) { static char te[] = " terminal emulator"; sprintf(frametitle, "%.*s%s", sizeof(frametitle)-sizeof(te)-strlen(term), term, te); framelabel = frametitle; } if (iconlabel == NULL) { gethostname(host, sizeof (host)); host[sizeof(host)-1] = '\0'; iconlabel = host; } if (tc_initialize(term)) Fatal("%s: Unknown terminal type or bad termcap description", term); set_scroll_save(savelines); scroll_to_bottom(); tc_init_selection(); PSInitCode(userinit); CreateWindow(xorg, yorg, font_size, CharsPerLine, LinesPerScreen, framelabel, iconlabel, font, starticonic, iconx, icony); ToggleScrollBar(savelines); StartInput(); /* XXX - set up PostScript process for i/p etc. */ psio_flush(PostScript); return (f); } PostScriptErrorMessage(s) char *s; { PopMsg(s); psio_flush(PostScript); } #define Finished_Dammage 1 #define Finished_NoDammage 2 #define Painting_Dammage 3 #define Painting_NoDammage 4 static int RefreshState = Finished_Dammage ; end_refresh() { switch (RefreshState) { case Painting_Dammage: RefreshState = Finished_Dammage ; break; case Painting_NoDammage: RefreshState = Finished_NoDammage ; break; case Finished_Dammage: RefreshState = Finished_Dammage ; break; case Finished_NoDammage: RefreshState = Finished_NoDammage ; break; } } /*ARGSUSED*/ tc_refresh(full) int full; { register struct line *l; register int i, pos, c; register u_char *cp; register struct line **sp; int delta, curdelta, len; int linesscrolledforward, linesscrolledreverse; int paintfromtop; int x, y; static int CursorLine = 0 ; static int CursorCol = 0 ; static int oldlinessaved = 0 ; static int oldlinesperscreen = 0 ; static int oldscrolly = 0 ; u_char *tp, *ep, hit[MaxLinesPerScreen]; if (RefreshSuppressed) return; switch (RefreshState) { case Painting_Dammage: if (FastPaint) return ; break; case Painting_NoDammage: RefreshState = Painting_Dammage ; if (FastPaint) return ; break; case Finished_Dammage: RefreshState = Painting_NoDammage ; break; case Finished_NoDammage: RefreshState = Finished_Dammage ; return; } if (ScrollY != oldscrolly) tc_take_down_selection(); bzero((char *)hit, LinesPerScreen); linesscrolledforward = linesscrolledreverse = 0 ; if (!fontisfixedwidth) { y = Dot.y + ScrollLength - LinesPerScreen - ScrollY ; if (y >= 0 && y < LinesPerScreen) hit[y] = 1 ; y = CursorLine + ScrollLength - LinesPerScreen - ScrollY ; if (y >= 0 && y < LinesPerScreen) hit[y] = 1 ; } else RemoveCursor(); /* * Figure out which lines have moved and by * how much. Accumulate delta line movements * and copy lines to perform scrolling. */ curdelta = 0; /* positive delta means lines are travelling in this direction * | | * | | * \ / * \ / * \/ */ sp = &lines[ScrollY]; for (i = 0; i < LinesPerScreen; i++) { l = *sp++; pos = l->usedtobe ; /* this line just moved from position pos */ delta = i - pos ; /* it moved this far in getting here */ if (pos >= LinesPerScreen || pos < 0 || hit[pos] || (delta && !DoScrolling)) { delta = 0 ; /* this line has been scribbled on, * so it stays put */ l->changeposition = 0 ; /* but has been dammaged */ l->end_of_changes = CharsPerLine ; } l->usedtobe = i; #ifdef lint c = 0 ; #endif /* * If the delta changes, we need to start a new * run of lines to copy. If there was a previous * run, then copy those first. */ if (delta != curdelta) { if (curdelta != 0) { for (pos = c; pos < i; pos++) hit[pos] = 1 ; if (curdelta > 0) linesscrolledreverse += i - c ; else linesscrolledforward += i - c ; CopyLines(c - curdelta, curdelta, CharsPerLine, i - c); } curdelta = delta; /* delta for current run */ c = i; /* starting line of run */ } } /* * Catch any trailing run needing to be copied. */ if (curdelta != 0) { if (curdelta > 0) linesscrolledreverse += i - c ; else linesscrolledforward += i - c ; CopyLines(c - curdelta, curdelta, CharsPerLine, i - c); } #ifdef lint paintfromtop = linesscrolledreverse > linesscrolledforward ; #endif paintfromtop = 1 ; /* * Finally, perform any erasures * and/or text painting required. */ if (paintfromtop) sp = &lines[ScrollY] ; else sp = &lines[ScrollY + LinesPerScreen - 1]; for (i = 0; i < LinesPerScreen; (paintfromtop ? sp++ : sp--), i++) { l = *sp; pos = l->changeposition; if (posend_of_changes+MaxCharsPerLine, l->length)+1) { if (!fontisfixedwidth) pos = 0 ; x = pos ; y = l->usedtobe ; MoveTo(x, y); if (l->buffer_length == 0) { PaintNor(" ", 1); continue; } ep = &l->prop[l->length+1]; for (cp = &l->prop[pos]; cp < ep; pos += len) { /* * Calculate longest sub-string of * changed text with identical properties. */ tp = cp; if (!fontisfixedwidth && y == Dot.y + ScrollLength - LinesPerScreen - ScrollY) { c = *cp++ ; if (x++==Dot.x) c ^= ReverseVideoLook ; for (; c==*cp && cpbody[pos], len); else PaintUnderNor(&l->body[pos], len); } else { if (c & ReverseVideoLook) PaintRev(&l->body[pos], len); else PaintNor(&l->body[pos], len); } } l->changeposition = CharsPerLine + 1 ; l->end_of_changes = 0 ; } } if (fontisfixedwidth) PlaceCursor(Dot.x, Dot.y); CursorLine = Dot.y ; CursorCol = Dot.x ; #ifdef lint CursorLine = CursorCol ; #endif if (Repairing) { EndRepair(); Repairing = 0; } if (oldlinessaved != ScrollLinesSaved || oldlinesperscreen != LinesPerScreen) { SetScrollBarValue(ScrollLinesSaved, ScrollY + ScrollLinesSaved - ScrollLength); oldlinessaved = ScrollLinesSaved ; oldlinesperscreen = LinesPerScreen ; } if (ScrollY != oldscrolly) tc_refresh_selection(); oldscrolly = ScrollY ; EndRefresh(); FlushPostScript(); } change_rowcol(row, col) int row, col; { extern int Mfd; /* Master pty fd */ int pgroup; if (row >= MaxLinesPerScreen) row = MaxLinesPerScreen - 1 ; if (col >= MaxCharsPerLine) col = MaxCharsPerLine - 1 ; if (row != LinesPerScreen || col != CharsPerLine) { #ifdef sun #ifdef TIOCSSIZE struct ttysize ts; ts.ts_lines = row; ts.ts_cols = col; ioctl(Mfd, TIOCSSIZE, &ts); #endif TIOCSSIZE #else sun #ifdef TIOCSWINSZ struct winsize ws; ws.ws_row = row; ws.ws_col = col; ws.ws_xpixel = row; /* don't know */ ws.ws_ypixel = col; /* don't know */ ioctl(Mfd, TIOCSWINSZ, &ws); #endif TIOCSWINSZ #endif sun ScrollY += LinesPerScreen - row ; resetscreensize(row, col); #ifdef sun if (ioctl(Mfd, TIOCGPGRP, &pgroup)<0) perror("ioctl TIOCGPGRP"); else if (killpg(pgroup, SIGWINCH)<0) perror("kill SIGWINCH"); #endif sun } for (row=0; rowusedtobe = -1 ; /* allocate full length lines for whole screen */ set_scroll_save(userScrollLength); scroll_to(ScrollY - ScrollLength + ScrollLinesSaved); } @@@ Fin de display.c exit 0