home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
stg_v4.lzh
/
pop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-11
|
13KB
|
599 lines
/*
* pop - utility to create a new window
*
* Version History:
* V0.? - Original version in C by StG (probably late '87)
* V1.0 - First assembly version by StG (source ate by disk) for StGNet
* V2.0 - Disassembled by Bug and hacked for more options
* (not released due to bugs in VDG support)
* V3.0 - Rewrote by Bug and added -c option
* (modeled after my type utility in the RBW)
* V4.0 - Rewrite by Bug in C with VDG support fixed (help from StG)
* V5.0 - trashed and recoded by StG for OSK support, new var naming style
* V5.1 - included patches for awkward SELECT in KDwin and tmode pag setting
* V5.2 - added auto termcap features from edit
* V5.3 - fixed window flip problem (caused by DWSET bug) and added -s opt
* V5.4 - use SHELL variable for default program and options
* V5.5 - created setenv() to fix environ mod'ing problems, added set to PORT
* V6.0 - changed 0/1 path order (KD finally matched coco) and added modes
*
* Future enhancements:
*
* -v = vertical split screen (put []'s on ends of label)
* -h = horizontal split screen
* -d = auto SRCDBG mode (pop 2 windows)
* $ = separation character for multiple commands (for split, etc)
* -f = select a font file(?)
* -i = interactive mode (mousey)
*/
#include <stdio.h>
#include <sgstat.h>
#define VER "V6.0"
#define ERR (-1)
#define MAXBUF 512
#define dash(v) while(*++v && **v=='-') while (*++*v) switch(tolower(**v))
extern int errno;
int os9fork();
int chain();
char *modlink();
char *malloc();
char *getenv();
extern char **environ;
int iPopCurWin=0;
int iNoLabel=0;
int iNoSelect=0;
int iPopVdg=0;
int iWait=0;
int iNoTCap=0;
char acBuf[MAXBUF];
struct sgbuf sPathDesc;
char acWinName[32];
char *pcWinDesc;
char *pcInitMod;
char **ppcWinTypes;
int iCol,iRow,iFor,iBack,iBord;
int iTemp;
int hFile;
char acEnt[MAXBUF];
char *gen1="Win|KD Windows Termcap created by POP:\\\n";
char *gen2=" :cl=\\E[;H\\E[2J:cm=\\E[%i%d;%dH:nd=\\E[C:up=\\E[A:\\\n";
char *gen3=" :so=\\E[7m:se=\\E[m:us=\\E[4m:ue=\\E[m:md=\\E[1m:mr=\\E[7m:\\\n";
char *gen4=" :mb=\\E[5m:me=\\E[m:ce=\\E[K:ho=\\E[H:bs:am:pt:\n";
#ifndef _OSK
int iWinType=2;
#else
int iWinType=0;
#endif
char *apcWinTypeList[]=
{
/* Fg Bg # XX-YY Desc */
#ifndef _OSK
" 0 2 1 = 40x25 Text",
" 0 2 2 = 80x25 Text",
" 0 1 5 = 80x24 ???x??? Graphics",
" 0 2 6 = 40x24 ???x??? Graphics",
" 0 2 7 = 80x24 ???x??? Graphics",
" 0 2 8 = 40x24 ???x??? Graphics",
#else
"255 002 0 = 80x26 640x208 16 Color",
"255 002 1 = 80x26 640x416 16 Color Interlaced",
"255 002 2 = 80x52 640x416 16 Color Interlaced",
"255 002 3 = 40x26 320x208 256 Color",
"255 002 4 = 40x26 320x416 256 Color Interlaced",
"255 002 5 = 40x52 320x416 256 Color Interlaced",
"255 002 6 = 90x30 720x240 16 Color Overscan",
"255 002 7 = 90x60 720x480 16 Color Interlaced/Overscan",
"255 002 8 = 48x30 384x240 256 Color Overscan",
"255 002 9 = 48x60 384x480 256 Color Interlaced/Overscan",
#endif
0
};
char *pcTemp;
/*
_gs_winfo(path,data)
int path;
char *data;
{
#asm
move.l 0(sp),d0
movea.l 4(sp),a0
move.l #$A1,d1
os9 I$GetStt
bcs err
move.l a0,d0
bra dun
err:
move.l d1,errno(a6)
moveq.l #-1,d0
dun:
#endasm
}
*/
#ifdef BOGUS
setenv(pcVar,pcSet)
char *pcVar,*pcSet;
{
static char **ppcEnviron=0;
static int iEnviron;
char **ppcTemp;
if (environ!=ppcEnviron)
{
iEnviron=0;
ppcTemp=environ;
while (*ppcTemp)
{
iEnviron++;
ppcTemp++;
}
iEnviron+=8;
ppcEnviron=(char**)malloc(4*iEnviron+4);
if (!ppcEnviron) exit(errno);
ppcTemp=ppcEnviron;
while (*environ) *ppcTemp++=*environ++;
*ppcTemp=0;
environ=ppcEnviron;
}
ppcTemp=ppcEnviron;
while (*ppcTemp)
{
if (!strncmp(*ppcTemp,pcVar,strlen(pcVar)))
{
if (*(*ppcTemp+strlen(pcVar))=='=') break;
}
ppcTemp++;
}
if (!*ppcTemp)
{
if (ppcTemp-ppcEnviron>=iEnviron)
{
iEnviron+=8;
ppcTemp=(char**)malloc(4*iEnviron+4);
if (!ppcTemp) exit(errno);
environ=ppcTemp;
while (*ppcEnviron) *ppcTemp++=*ppcEnviron++;
*ppcTemp=0;
ppcEnviron=environ;
}
}
*ppcTemp=malloc(strlen(pcVar)+1+strlen(pcSet)+1);
if (!*ppcTemp) exit(errno);
strcpy(*ppcTemp,pcVar);
strcat(*ppcTemp,"=");
strcat(*ppcTemp,pcSet);
*++ppcTemp=0;
return(0);
}
#endif
#include "setenv.c"
/* debugging code!
pargs(ppcList)
char **ppcList;
{
printf("%08X:->\n",ppcList);
while (*ppcList)
{
printf("%08X:%s\n",*ppcList,*ppcList);
ppcList++;
}
printf("%08X.\n",*ppcList);
}
*/
char **
args(pcCmd)
char *pcCmd;
{
char **ppcRoot,**ppcTemp,*pcTemp,*pcLast,*pcCopy;
int iArgs=0;
pcTemp=pcCmd;
iArgs++;
while (*pcTemp) if (*pcTemp++==' ') iArgs++;
ppcTemp=ppcRoot=(char**)malloc(4*iArgs+4);
if (!ppcRoot) exit(errno);
pcLast=pcTemp=pcCmd;
while (*pcTemp)
{
while (*pcTemp) if (*pcTemp++==' ') break;
if (!*pcTemp) pcTemp++;
pcCopy=*ppcTemp=malloc(pcTemp-pcLast);
if (!pcCopy) exit(errno);
while (pcTemp-pcLast) *pcCopy++=*pcLast++;
*--pcCopy=0;
ppcTemp++;
if (!--iArgs) break;
}
*ppcTemp=0;
return(ppcRoot);
}
main(argc,argv)
char **argv;
{
#ifdef OSK
strcpy(acBuf,"\x01\x06\x01\x0c");
iTemp=4;
while (iTemp) acBuf[--iTemp]+=0x68;
pcInitMod=modlink(acBuf,0,0);
if ((int)pcInitMod==ERR) exit(errno);
iTemp=*((unsigned short *)(pcInitMod+0x50));
if
(
*(pcInitMod+iTemp+0)!='I' ||
*(pcInitMod+iTemp+1)!='M' ||
*(pcInitMod+iTemp+2)!='S'
)
if
(
*(pcInitMod+iTemp+0)!='M' ||
*(pcInitMod+iTemp+1)!='M' ||
*(pcInitMod+iTemp+2)!='1'
)
{
printf("pop: cant identify system\n");
printf("Please call StG @ (317) 241-6401 and report error\n");
exit(1);
}
munlink(pcInitMod);
#endif
iFor=iBack=iBord=-1;
/* process options */
dash(argv)
{
case 'c': iPopCurWin++; break;
case 'l': iNoLabel++; break;
case 's': iNoSelect++; break;
case 'w': iWait++; break;
case 't': iNoTCap++; break;
case 'f': if (*++*argv=='=') ++*argv; iFor=atoi(*argv); *(*argv+1)=0; break;
case 'b': if (*++*argv=='=') ++*argv; iBack=atoi(*argv); *(*argv+1)=0; break;
case 'o': if (*++*argv=='=') ++*argv; iBord=atoi(*argv); *(*argv+1)=0; break;
#ifndef _OSK
case 'v': iPopVDG++; break;
#endif
case '?':
printf("Pop {-opt} {program} - create new window\n");
printf(" -l = don't label the window\n");
printf(" -s = don't switch to window\n");
printf(" -c = replace current window\n");
printf(" -w = wait on program to die\n");
printf(" -t = don't complain if no access to termcap\n");
printf(" -f=# = set foreground color\n");
printf(" -b=# = set background color\n");
printf(" -o=# = set border color\n");
#ifndef _OSK
printf(" -v = pop a VDG window\n");
#endif
ppcWinTypes=apcWinTypeList;
while (*ppcWinTypes)
{
printf(" -%s",*ppcWinTypes+8);
if (atoi(*ppcWinTypes+8)==iWinType) printf(" [default]");
printf("\n");
ppcWinTypes++;
}
printf("\nPOP %s (c) 1991 by StG Computers inc.\n",VER);
printf("Written by Chris Swinefurth (The Bug) and StG\n");
printf("\nThis program is SHAREWARE! If you like it, please send $10 to:\n");
printf(" StG Computers inc., P.O. Box 24285, Speedway IN 46224\n");
exit(0);
default:
if (**argv!='0' && !atoi(*argv))
{
printf("Unknown option code: %s\n",*argv);
exit(1);
}
iWinType=atoi(*argv);
ppcWinTypes=apcWinTypeList;
while (*ppcWinTypes)
{
if (atoi(*ppcWinTypes+8)==iWinType) break;
ppcWinTypes++;
}
if (!*ppcWinTypes)
{
printf("Unknown window type: %d\n",iWinType);
exit(1);
}
}
ppcWinTypes=apcWinTypeList;
while (*ppcWinTypes)
{
if (atoi(*ppcWinTypes+8)==iWinType) break;
ppcWinTypes++;
}
if (!*ppcWinTypes) exit(-1);
pcTemp=getenv("SHELL");
if (!pcTemp) pcTemp="SHELL";
if (!*argv) argv=args(pcTemp);
/* in case stdin is from a script file, reopen as stdout */
close(0);
dup(1);
#ifndef _OSK
if (iPopCurWin) /* insure user is not trying to pop a vdg over current */
{
/* get path descriptor */
_gs_opt(0,&sPathDesc);
if (!(sPathDesc.sg_parity & 0x80) !! iPopVDG)
{
printf("Cannot pop current window with/from VDG\n);
exit(1;
}
}
#endif OSK
if (!iPopCurWin)
{
#ifndef BOGUS
close(1);
#else
close(0);
#endif
errno=1;
if (open("/w",3)==ERR)
{
writeln(2,"pop: cant open /w\n",80);
exit(errno);
}
}
*acWinName='/';
#ifndef BOGUS
_gs_devn(1,acWinName+1);
#else
_gs_devn(0,acWinName+1);
#endif
strhcpy(acWinName+1,acWinName+1);
#ifndef OSK
if (iPopVDG)
{
if ((pcWinDesc=modlink(acWinName+1,0x0f,0x01))==ERR)
{
writeln(2,"pop: cant link to window descriptor\n",80);
exit(errno);
}
*(pcWinDesc+0x26)=0x01; /* set VDG type */
dup(2);
dup(1);
close(1);
errno=1;
if (open(acWinName,3))!=1)
{
writeln(2,"pop: cant open VDG window\n",80);
exit(errno);
}
/* double check type code */
_gs_opt(1,&sPathDesc);
if (sPathDesc.sg_parity!=0x01)
{
writeln(2,"pop: window did not open as VDG\n",80);
exit(1);
}
*(pcWinDesc+0x26)=0x80; /* set back to normal */
munlink(pcWinDesc); /* and unlink descriptor module */
close(0);
close(2);
dup(1);
dup(1);
goto exec;
}
#endif
if (iPopCurWin)
{
/* end current window */
write(1,"\x1B\x24",2);
}
iCol=atoi(*ppcWinTypes+12);
iRow=atoi(*ppcWinTypes+15);
if (iFor==-1) iFor=atoi(*ppcWinTypes);
if (iBack==-1) iBack=atoi(*ppcWinTypes+4);
if (iBord==-1) iBord=atoi(acWinName+2);
/* define new window */
*(acBuf+0)=0x1b;
*(acBuf+1)=0x20;
*(acBuf+2)=iWinType;
*(acBuf+3)=0; /* start X */
*(acBuf+4)=0; /* start Y */
*(acBuf+5)=iCol; /* size X */
*(acBuf+6)=iRow; /* size Y */
*(acBuf+7)=iFor; /* foreground color */
*(acBuf+8)=iBack; /* background color */
*(acBuf+9)=iBord; /* border color */
*(acBuf+10)=0; /* nulls to overide bug in DWSET */
*(acBuf+11)=0;
#ifndef BOGUS
write(1,acBuf,12);
if (!iNoSelect) write(1,"\x1b\x21",2);
write(1,"\x0c",1);
#else
write(0,acBuf,12);
if (!iNoSelect) write(0,"\x1b\x21",2);
write(0,"\x0c",1);
#endif
/* hack because border color isn't getting set in KDwin
#ifdef OSK
*(acBuf+0)=0x1b;
*(acBuf+1)=0x34;
*(acBuf+2)=iBord;
write(0,acBuf,3);
#endif
*/
/* keep a copy of stderr on path 3 in case... */
dup(2);
/* reset stdin and stderr to new window */
#ifndef BOGUS
close(0);
close(2);
dup(1);
dup(1);
#else
close(1);
close(2);
dup(0);
dup(0);
#endif
if (!iNoLabel)
{
write(1,"\x1f\x20",2);
iTemp=0;
while (iTemp<iCol) acBuf[iTemp++]=' ';
acBuf[iTemp++]=0;
iTemp=iCol-strlen(acWinName+1);
iTemp/=2;
strncpy(acBuf+iTemp,acWinName+1,strlen(acWinName+1));
write(1,acBuf,iCol);
write(1,"\x1f\x21",2);
*(acBuf+0)=0x1b;
*(acBuf+1)=0x25;
*(acBuf+2)=0;
*(acBuf+3)=1;
*(acBuf+4)=iCol;
*(acBuf+5)=--iRow;
write(1,acBuf,6);
}
_gs_opt(0,&sPathDesc);
sPathDesc.sg_page=iRow-1;
_ss_opt(0,&sPathDesc);
#ifdef OSK
hFile=open("/dd/sys/termcap",3);
if (hFile==ERR)
{
hFile=open("/h0/sys/termcap",3);
if (hFile==ERR)
{
hFile=open("/d0/sys/termcap",3);
if (hFile==ERR)
{
if (!iNoTCap)
{
writeln(2,"pop: cant open termcap file",80);
prerr(2,(short)errno);
}
goto exec;
}
}
}
while ((iTemp=readln(hFile,acBuf,MAXBUF))>0)
{
*(acBuf+iTemp)=0;
if (!strncmp(acBuf,gen1,4)) goto genok;
}
writeln(hFile,"\n",80);
writeln(hFile,gen1,80);
writeln(hFile,gen2,80);
writeln(hFile,gen3,80);
writeln(hFile,gen4,80);
writeln(hFile,"\n",80);
genok:
sprintf(acEnt,"Win%dx%d|KD Window %d X %d:co#%d:li#%d:tc=Win:\n",iCol,iRow,iCol,iRow,iCol,iRow);
while ((iTemp=readln(hFile,acBuf,MAXBUF))>0)
{
*(acBuf+iTemp)=0;
if (!strcmp(acBuf,acEnt)) goto entok;
}
writeln(hFile,acEnt,80);
entok:
sprintf(acEnt,"Win%dx%d",iCol,iRow);
iTemp=0;
if (!getenv("TERM") || strcmp(getenv("TERM"),acEnt))
{
/* TERM entry needs set/changed */
if (iPopCurWin)
{
sprintf(acEnt,"TERM=Win%dx%d",iCol,iRow);
printf("Termcap entry is incorrect - please enter:\nsetenv %s\n",acEnt);
}
else
{
setenv("TERM",acEnt);
}
}
if (!getenv("PORT"))
{
setenv("PORT",acWinName);
}
#endif
exec:
if (iPopCurWin) exit(0);
if (iWait)
{
if (os9exec(chain,*argv,argv,environ,0,0)==ERR)
{
writeln(3,"pop: cant chain program\n",80);
exit(errno);
}
exit(-1);
}
if (os9exec(os9fork,*argv,argv,environ,0,0)==ERR)
{
writeln(3,"pop: cant fork program\n",80);
exit(errno);
}
}