home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume16
/
psterm
/
part02
< prev
next >
Wrap
Text File
|
1988-11-01
|
59KB
|
2,364 lines
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 <stdio.h>
#include <errno.h>
#include <sys/types.h>
#ifdef REF
#include <ref/config.h>
#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 <sys/types.h>
#include <ref/config.h>
#endif
#ifndef HAVE_SELECT
#ifdef INTERLANTCP
#include <interlan/il_errno.h>
#endif
#include <stropts.h>
#include <poll.h>
#endif
#include <stdio.h>
#include <psio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/time.h>
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<<kfd;
pty = 1<<cfd;
postscript = 1<<psio_fileno(PostScript);
#ifdef HAVE_FNDELAY
(void) fcntl(cfd, F_SETFL, fcntl(cfd, F_GETFL, 0)|FNDELAY);
(void) fcntl(kfd, F_SETFL, fcntl(kfd, F_GETFL, 0)|FNDELAY);
#else
(void) fcntl(cfd, F_SETFL, fcntl(cfd, F_GETFL, 0)|O_NDELAY);
(void) fcntl(kfd, F_SETFL, fcntl(kfd, F_GETFL, 0)|O_NDELAY);
#endif
#ifdef HAVE_SELECT
max = MAX(kfd, cfd) + 1;
#endif
kbdend = kbdbuf + KBDBUFSIZE;
kbdfront = kbdback = kbdbuf;
wfproto = 0;
for (;;) {
/*
* Don't poll for input to be sent to the display
* if we have a full screen, or we are blocked already
* trying to transmit to the server.
*/
#ifdef HAVE_SELECT
rf = (PageFull || (wfproto & postscript)) ? 0 : pty;
wf = wfproto;
if (kbdfront != kbdend) /* space to read from kbd */
rf |= keyboard;
if (select(max, &rf, &wf, (int *)NULL, (struct timeval *)NULL) < 0) {
if (errno == EINTR)
continue;
perror("select");
break;
}
#else
rwf[PTY].fd = -1;
rwf[PTY].events = 0;
rwf[KEYBOARD].fd = -1;
rwf[KEYBOARD].events = 0;
rwf[POSTSCRIPT].fd = -1;
rwf[POSTSCRIPT].events = 0;
if (!(PageFull || (wfproto & postscript))) {
rwf[PTY].fd = cfd;
rwf[PTY].events |= POLLIN;
}
if (wfproto & pty) {
rwf[PTY].fd = cfd;
rwf[PTY].events |= POLLOUT;
}
if (wfproto & postscript) {
rwf[POSTSCRIPT].fd = psio_fileno(PostScript);
rwf[POSTSCRIPT].events |= POLLOUT;
}
if (kbdfront != kbdend) { /* space to read from kbd */
rwf[KEYBOARD].fd = kfd;
rwf[KEYBOARD].events |= POLLIN;
}
if (poll(rwf, NFDS, -1) < 0) {
if (errno == EINTR)
continue;
perror("poll");
break_here:
break;
}
/* check to see if any connections were hung up */
if (rwf[KEYBOARD].revents & POLLHUP || rwf[PTY].revents & POLLHUP
|| rwf[POSTSCRIPT].revents & POLLHUP)
break;
/* look for exceptional conditions on fd's */
for (i = 0; i < NFDS; i++) {
if (rwf[i].revents & (POLLERR | POLLNVAL)) {
fprintf(stderr, "Error on an fd in poll ");
fprintf(stderr, "[POLLERR | POLLNVAL]\n");
goto break_here; /* should be break, but C has */
/* no multi-level break */
}
}
#endif
/*
* Flush PostScript descriptor.
*/
#ifdef HAVE_SELECT
if (wf & postscript && (psio_flush(PostScript) == 0))
#else
if (rwf[POSTSCRIPT].revents & POLLOUT && (psio_flush(PostScript) == 0))
#endif
wfproto &= ~postscript;
/*
* Try to flush pty, if clogged, before reading from keyboard.
*/
#ifdef HAVE_SELECT
if (wf & pty)
#else
if (rwf[PTY].revents & POLLOUT)
#endif
{
wfproto &= ~pty;
pty_out();
}
/*
* Take keyboard input.
*/
#ifdef HAVE_SELECT
if (rf & keyboard)
#else
if (rwf[KEYBOARD].revents & POLLIN)
#endif
{
errno = 0;
n = read(kfd, kbdfront, (unsigned)(kbdend-kbdfront));
if (n <= 0) {
if (errno != EWOULDBLOCK) {
#ifdef HAVE_SELECT /* Connection Reset is checked above in SYSVREF */
if (n < 0 && errno != ECONNRESET)
#endif
perror("keyboard");
break;
}
} else if (n > 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<<psio_fileno(PostScript);
}
/*
* Flush output to pty.
*/
static
pty_out()
{
register int cc;
if ((cc = kbdfront - kbdback) > 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<<Mfd; /* must explicity reenable */
else
kbdfront = kbdback = kbdbuf;
}
#define EVENT_ESCAPE 0200 /* introduce event packet */
#define EVENT_REPAIR 'a' /* window resized or damaged */
#define EVENT_BEGINSEL 'b' /* set selection start */
#define EVENT_EXTSEL 'c' /* drag end of current selection */
#define EVENT_ENDSEL 'd' /* complete selection */
#define EVENT_TOGGLEAM 'e' /* toggle auto-margins */
#define EVENT_TOGGLEPM 'f' /* toggle page mode */
#define EVENT_ROWCOL 'g' /* new row/col size selected */
#define EVENT_FONTFIXED 'h' /* just switched to a fixed width font */
#define EVENT_FONTVAR 'i' /* just switched to a variable width font */
#define EVENT_RECTSEL 'j' /* set rect selection start */
#define EVENT_EXTRECT 'k' /* extend rect selection */
#define EVENT_SCROLL 'l' /* scrollbar movement report */
#define EVENT_SAVESIZE 'm' /* change number of lines saved */
#define EVENT_ENDREFRESH 'n' /* postscript side has completed refresh */
#define EVENT_FASTPAINT 'o' /* set or clear fastpaint */
#define EVENT_DOSCROLL 'p' /* set or clear use of scrolling */
/*
* Handle keyboard input + postscript events.
*/
static
kbd_input(n)
register int n;
{
register unsigned char *p, *d;
register n2;
extern int RefreshSuppressed;
int col, row, rank, dorefresh = 0, doresize = 0, rect = 0 ;
#define NEXTVAL while (n-- > 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 <stdio.h>
#include <psio.h>
#include <signal.h>
#include <pwd.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#ifdef SYSVREF
#ifdef INTERLANTCP
#include <interlan/il_types.h>
#include <interlan/socket.h>
#include <interlan/in.h>
#include <interlan/netdb.h>
#else
#include <sys/types.h>
#endif
#else
#ifdef REF
#include <sys/types.h>
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#ifdef REF
#include <ref/config.h>
#endif
#ifdef SYSVREF
#define SIGCHLD SIGCLD
#else
#include <sys/wait.h>
#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; i<argc; i++) {
count += strlen(argv[i]);
}
if (s_args[2] = malloc((unsigned)count+argc+4)) {
s_args[2][0] = 0;
for (i=0; i<argc; i++) {
if (i)
strcat(s_args[2], " ");
strcat(s_args[2], argv[i]);
}
s_args[0]++;
s_args[1] = "-c";
s_args[3] = 0;
}
}
/*
* if $NEWSSERVER isn't defined and stdin is a socket, chances
* are we're being invoked with rsh, so figure out where the
* rsh command came from and use that for NEWSSERVER.
*/
if (getenv("NEWSSERVER")==0) {
struct hostent *hp;
struct sockaddr_in remote;
int n = sizeof remote;
if (getpeername(0, (struct sockaddr *)&remote, &n) == 0) {
if (remote.sin_family == AF_INET) {
char srv[128];
sprintf(srv, "%lu.%d;",
ntohl(remote.sin_addr.s_addr), 2000);
hp = gethostbyaddr((char*) &remote.sin_addr,
sizeof (remote.sin_addr),
remote.sin_family);
if (hp)
strcat(srv,hp->h_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 <sys/types.h>
#ifdef REF
#include <ref/config.h>
#endif
#include <sys/ioctl.h>
#include <sys/signal.h>
#include <sys/file.h>
#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; j<ScrollLength; j++, i++) {
new_lines[i] = lines[j] ;
}
TotalScrollLength = length ;
if (scroll_area) free((char *)scroll_area);
scroll_area = lines = new_lines ;
}
else {
delta = ScrollLength - length ;
if (delta>0) {
for (i=0; i<length; i++) {
if (lines[i]) {
if (lines[i]->body)
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; i<length-ScrollLength; i++) {
line = (struct line *) Malloc(sizeof(struct line));
line->body = Malloc(TypicalWidth) ;
for (j=0; j<TypicalWidth; j++)
line->body[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; i<greater; i++)
if (lines[i])
lines[i]->usedtobe = -1 ;
for (i=lesser+LinesPerScreen; i<greater+LinesPerScreen; i++)
if (lines[i])
lines[i]->usedtobe = -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; i<LinesPerScreen; i++) {
lines[i+ScrollY]->changeposition = 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 (pos<min(l->end_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 && cp<ep && x!=Dot.x;
cp++, x++)
;
}
else {
for (c = *cp++; c==*cp && cp<ep; cp++)
;
}
len = cp - tp;
/*
* Paint sub-string according to properties.
*/
if (c & UnderlineLook) {
if (c & ReverseVideoLook)
PaintUnderRev(&l->body[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; row<ScrollLength; row++)
if (lines[row])
lines[row]->usedtobe = -1 ;
/* allocate full length lines for whole screen */
set_scroll_save(userScrollLength);
scroll_to(ScrollY - ScrollLength + ScrollLinesSaved);
}
@@@ Fin de display.c
exit 0