home *** CD-ROM | disk | FTP | other *** search
- /* AmiStuff.c - Amiga specific routines */
- /* Copyright (c) 1990 by J.K. Lindsey */
- /* Additions to XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
- /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
- /* You may give out copies of this software; for conditions see the */
- /* file COPYING included with this distribution. */
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <graphics/gfxbase.h>
- #include <graphics/display.h>
- #include <libraries/dosextens.h>
- #include <rexx/rxslib.h>
- #include <rexx/simplerexx.h>
- #include <math.h>
- #include <time.h>
- #include <stdlib.h>
- #include <string.h>
- #include "autil2.h"
- #include "version.h"
- #include "xlisp.h"
- #include "osdef.h"
- #include "xlproto.h"
- #include "xlsproto.h"
- #include "iviewproto.h"
- #include "Stproto.h"
- #include "osproto.h"
- #include "xlvar.h"
- #include "xlsvar.h"
- #define extern
- #include "amivar.h"
- #undef extern
-
- /* input buffer allows about 20 lines of text from ARexx */
- #define LBSIZE 1600
-
- char deftool[100]="";
-
- /* line buffer variables */
- static char lbuf[LBSIZE];
- static char rexxerror[]="Commands truncated (too large for buffer).";
- static int lpos[LBSIZE],lindex,lcount,lposition,start_time,numparen=0;
-
- static struct FileHandle *fh=0;
- static struct IOStdReq *OutConWM,*OutConRM;
- static struct MsgPort *wport,*rport;
- static struct BitMap bm,bm1,bm2;
- static struct TextAttr StdFont={
- "topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT};
- static short hch,wch;
- static unsigned long rportsig,rexxsig;
- static unsigned short colormap[]={
- RWHITE,RBLACK,RRED,RGREEN,RBLUE,RCYAN,RMAGENTA,RYELLOW,RBLUE,RGREEN,
- RRED,RYELLOW,RMAGENTA,RCYAN,RWHITE,RBLACK};
- static char ch;
- static AREXXCONTEXT RexxStuff;
-
- /* forward declarations */
- void xputc(int),xflush(void);
- int xgetc(void),xcheck(void),dokeys(void),dorexx(void),
- DeadKeyConvert(unsigned short,unsigned short,char **,char *,int);
- LVAL get_menu_by_id(int);
-
- /* disable Lattice ctrl-C */
- int CXBRK(void){return(0);}
- int chkabort(void){return(0);}
-
- /* osinit - initialize */
- void osinit(char *banner){
- struct NewScreen ns;
- struct NewWindow nw;
- struct RastPort *orp;
- unsigned long clock[2];
- char buffer[80],*b;
- int i;
- timer(clock);
- start_time=clock[0];
-
- /* open custom screen */
- screen=0;
- screentype=CUSTOMSCREEN;
- OutConWM=OutConRM=0;
- rport=wport=0;
- if(openlibs())xlfatal("cannot open libraries");
- screenw=GfxBase->NormalDisplayColumns;
- screenh=2*GfxBase->NormalDisplayRows;
- ns.LeftEdge=0;
- ns.TopEdge=0;
- ns.Width=screenw;
- ns.Height=screenh;
- ns.Depth=PLANES;
- ns.DetailPen=WHITE;
- ns.BlockPen=BLACK;
- ns.ViewModes=HIRES|INTERLACE;
- ns.Type=screentype;
- ns.Font=&StdFont;
- ns.DefaultTitle="Xlisp-Stat by Luke Tierney";
- ns.Gadgets=0;
- ns.CustomBitMap=0;
- if(!(screen=OpenScreen(&ns)))xlfatal("cannot open xlisp screen");
- LoadRGB4(&screen->ViewPort,colormap,16);
-
- /* open backdrop window */
- nw.LeftEdge=0;
- nw.TopEdge=11;
- nw.Width=screenw;
- nw.Height=screenh-11;
- nw.DetailPen=WHITE;
- nw.BlockPen=BLACK;
- nw.IDCMPFlags=GADGETUP|MENUPICK;
- nw.Flags=SMART_REFRESH|ACTIVATE|BACKDROP|BORDERLESS|NOCAREREFRESH;
- nw.FirstGadget=0;
- nw.CheckMark=0;
- nw.Title=0;
- nw.Screen=screen;
- nw.BitMap=0;
- nw.MinWidth=100;
- nw.MinHeight=50;
- nw.MaxWidth=0;
- nw.MaxHeight=0;
- nw.Type=screentype;
- if(!(window=OpenWindow(&nw)))xlfatal("cannot open xlisp window");
- screen->FirstWindow->UserData=0;
-
- /* initialize double buffering raster */
- orp=screen->FirstWindow->RPort;
- dbsize=screenh>screenw?screenh:screenw;
- InitBitMap(&bm,PLANES,dbsize,dbsize);
- for(i=0;i<PLANES;i++){
- if(!(bm.Planes[i]=(PLANEPTR)AllocRaster(dbsize,dbsize)))xlfatal("raster allocation failed");}
- InitRastPort(&dbrp);
- dbrp.BitMap=&bm;
- dbrp.Font=orp->Font;
- dbrp.TxFlags=orp->TxFlags;
- dbrp.TxHeight=orp->TxHeight;
- dbrp.TxWidth=orp->TxWidth;
- dbrp.TxBaseline=orp->TxBaseline;
- dbrp.TxSpacing=orp->TxSpacing;
- dbflag=0;
-
- /* initialize rasters for writing vertical text */
- wch=16;
- hch=16;
- InitBitMap(&bm1,PLANES,wch,hch);
- InitBitMap(&bm2,PLANES,hch,wch);
- for(i=0;i<PLANES;i++){
- if(!(bm1.Planes[i]=(PLANEPTR)AllocRaster(wch,hch)))xlfatal("raster allocation failed");
- if(!(bm2.Planes[i]=(PLANEPTR)AllocRaster(hch,wch)))xlfatal("raster allocation failed");}
- InitRastPort(&rp1);
- InitRastPort(&rp2);
- rp1.BitMap=&bm1;
- rp2.BitMap=&bm2;
- rp1.Font=orp->Font;
- rp1.TxFlags=orp->TxFlags;
- rp1.TxHeight=hch;
- rp1.TxWidth=wch;
- rp1.TxBaseline=orp->TxBaseline;
- rp1.TxSpacing=orp->TxSpacing;
-
- RexxStuff=InitARexx("XLisp",0);
- rexxsig=ARexxSignal(RexxStuff);
- if(OpenConsole(&OutConWM,&OutConRM,&wport,&rport,0,0,screen->FirstWindow))xlfatal("cannot open console");
- rportsig=1<<rport->mp_SigBit;
- QueueRead(OutConRM,&ch);
- while(*banner!='\000')xputc(*banner++);
- xputc('\n');
- sprintf(buffer, "XLISP-STAT version %s, Copyright (c) 1989, by Luke Tierney.",
- XLISPSTAT_VERSION);
- b=buffer;
- while(*b!='\000')xputc(*b++);
- xputc('\n');
- strcpy(buffer,"Several files will be loaded; this may take a few minutes.");
- b=buffer;
- while(*b!='\000')xputc(*b++);
- xputc('\n');
- xputc('\n');
- lposition=lindex=lcount=0;
- Menu_Ptr=0;}
-
- void osfinish (void){
- struct Window *l,*ll;
- int i;
- if(fh&&fh!=(struct FileHandle *)Output())Close((BPTR)fh);
- for(i=0;i<PLANES;i++){
- FreeRaster(bm.Planes[i],dbsize,dbsize);
- FreeRaster(bm1.Planes[i],wch,hch);
- FreeRaster(bm2.Planes[i],hch,wch);}
- FreeARexx(RexxStuff);
- if(OutConWM)DelConsole(OutConWM,OutConRM,wport,rport);
- l=screen->FirstWindow;
- while(ll=l){
- l=l->NextWindow;
- if(ll!=window)StGWRemove((StGWWinInfo *)ll->UserData);}
- ClearMenuStrip(screen->FirstWindow);
- CloseWindow(screen->FirstWindow);
- if(screen)CloseScreen(screen);
- closelibs();}
-
- /* osrand - return a random number between 0 and n-1 */
- int osrand(unsigned n){
- return((int)(rand()%n));}
-
-
- /* oscheck - check for control characters during execution */
- void oscheck(void){
- int ch;
- if(ch=xcheck())switch (ch) {
- case '\002': osflush(); xlbreak("BREAK",s_unbound); break;
- case '\004': osflush(); xltoplevel(); break;}}
-
- /* osflush - flush the input line buffer */
- void osflush(void){
- lindex=lcount=0;}
-
- /* xgetc - get a character from the terminal without echo */
- static int xgetc(void){
- register temp;
- struct IOStdReq *readreq;
- if(!(readreq=(struct IOStdReq *)GetMsg(rport)))return(-1);
- temp=ch;
- QueueRead(readreq,&ch);
- return(temp&0xFF);}
-
- /* xputc - put a character to the terminal */
- static void xputc(int ch){
- char chout;
- chout=ch;
- ConsoleWrite(OutConWM,&chout,1);}
-
- /* xcheck - check for a character */
- static int xcheck(void){
- int c;
- if((c=ConsoleMayRead(rport,&ch))==-1)return(0);
- return (c&0xFF);}
-
- /* osclose - close a file */
- int osclose(FILE *fp){
- return (fclose(fp));}
-
- /* ostputc - put a character to the terminal */
- int ostputc(int ch){
- /* check for control characters */
- oscheck();
-
- /* output the character */
- if(ch=='\n') {
- xputc('\r');
- xputc('\n');
- lposition=0;}
- else {
- xputc(ch);
- lposition++;}
-
- /* output the character to the transcript file */
- if(tfp)osaputc(ch,tfp);
- return(0);}
-
- /* ostgetc - get a character from the terminal */
- int ostgetc(void){
- struct IntuiMessage *message;
- struct MenuItem *item;
- struct Window *w;
- struct Gadget *address;
- StGWWinInfo *gwinfo;
- int mn,in,active;
- #ifdef RMOUSE
- int x,y;
- #endif RMOUSE
- unsigned long wsig,signal,class,iflags;
- unsigned short code,qualifier;
-
- /* check for a buffered character */
- if(lcount--){
- /*printf("lcount=%d lindex=%d %c\n",lcount,lindex,lbuf[lindex]);*/
- return((int)lbuf[lindex++]);}
-
- /* get an input event */
- for(message=0,lcount=0;;){
- /*printf("\nready for event\n");*/
- for(active=0;;){ /* not friendly to other tasks, but I haven't found */
- if(window->Flags&WINDOWACTIVE)break; /* another way to do it */
- w=screen->FirstWindow;
- while(w){
- if(!(gwinfo=(StGWWinInfo *)w->UserData)){
- w=w->NextWindow;
- continue;}
- if(w->Flags&WINDOWACTIVE&&!dialog_p(gwinfo->Object)){
- active=1;
- ami_do_cursor(gwinfo);
- for(;;){
- #ifdef RMOUSE
- StGWObDoIdle(gwinfo->Object);
- #else
- idle_action(gwinfo);
- #endif RMOUSE
- if(message=(struct IntuiMessage *)GetMsg(w->UserPort))goto S1;}}
- else if(dialog_p(gwinfo->Object)&&(message=(struct IntuiMessage *)GetMsg(w->UserPort)))goto S1;
- w=w->NextWindow;}
- if(!active)break;}
- S1: if(!message){
- w=screen->FirstWindow; /* must be inside loop in case */
- wsig=0; /* windows are created or closed */
- while(w){
- wsig|=1<<w->UserPort->mp_SigBit;
- w=w->NextWindow;}
- signal=Wait(rexxsig|rportsig|wsig);
- /*printf("message received\n");*/
- if(signal&rportsig){
- if((in=dokeys())!=-1&&in!=-2)return(in);}
- else if((signal&rexxsig)&&(in=dorexx()))return(in);
- else if(signal&wsig){
- w=screen->FirstWindow;
- while(w){
- if(signal&(1<<w->UserPort->mp_SigBit))break;
- w=w->NextWindow;}}}
- if(message||signal&wsig)for(;;){
- if(!message)message=(struct IntuiMessage *)GetMsg(w->UserPort);
- if(message){
- #ifdef RMOUSE
- ReportMouse(w,0);
- #endif RMOUSE
- class=message->Class;
- code=message->Code;
- address=(struct Gadget *)message->IAddress;
- qualifier=message->Qualifier;
- #ifdef RMOUSE
- x=message->MouseX;
- y=message->MouseY;
- #endif RMOUSE
- ReplyMsg((struct Message *)message);
- message=0;
- if((w!=window)&&!(gwinfo=(StGWWinInfo *)w->UserData))continue;
- iflags=w->IDCMPFlags;
- switch(class){
- #ifdef RMOUSE
- case MOUSEMOVE: {
- StGWObDoMouse(gwinfo->Object,x-w->BorderLeft,y-w->BorderTop,MouseMove,0);
- break;}
- #endif RMOUSE
- case INACTIVEWINDOW:
- case ACTIVEWINDOW: {
- send_message_1L(gwinfo->Object,sk_activate,class==ACTIVEWINDOW?s_true:0);
- break;}
- case VANILLAKEY: {
- key_action(gwinfo,(char)code,qualifier);
- break;}
- case GADGETDOWN:
- case GADGETUP: {
- if(dialog_p(gwinfo->Object)){
- Dodo(w,0);
- doDialog(address->GadgetID,w);
- Dodo(w,iflags);}
- else if(gwinfo->hasVscroll||gwinfo->hasHscroll){
- scroll_action(gwinfo,address->GadgetID);}
- break;}
- case MOUSEBUTTONS: {
- if(code==SELECTDOWN&&!dialog_p(gwinfo->Object))mouse_action(gwinfo,qualifier);
- break;}
- case CLOSEWINDOW: {
- if(dialog_p(gwinfo->Object))DialogRemove(GetDialogObject(w));
- else send_message(gwinfo->Object,sk_close);
- break;}
- case NEWSIZE: {
- Dodo(w,0);
- send_message_1L(gwinfo->Object,sk_update,s_true);
- Dodo(w,iflags);
- break;}
- case MENUPICK: {
- while(code!=MENUNULL){
- item=ItemAddress(mymenu,code);
- mn=MENUNUM(code);
- in=ITEMNUM(code);
- code=item->NextSelect;
- send_message1(get_menu_by_id(mn),sk_select,in+1);}
- break;}}}
- else break;
- if(class==CLOSEWINDOW||class==MENUPICK)break;}
- #ifdef RMOUSE
- ReportMouse(w,1);
- #endif RMOUSE
- }}
-
- /* xflush - flush the input line buffer */
- static void xflush(void){
- ostputc('\n');
- osflush();}
-
- /* osaopen - open an ascii file */
- #include "icon.h"
- void wfile(char *fname){
- static struct IntuiText ptext={0,1,JAM2,5,3,&StdFont,"OK",0},
- ntext={0,1,JAM2,5,3,&StdFont,"CANCEL",0},
- btext={0,1,JAM2,5,15,&StdFont,"File exists! OverWrite?",0};
- BPTR lock;
- if(lock=Lock(fname,ACCESS_WRITE)){
- UnLock(lock);
- if(!AutoRequest(window,&btext,&ptext,&ntext,0,0,215,70))xlfail("file open cancelled");}
- MakeIcon(icon,80,42,deftool,fname,20000);}
-
- FILE *osaopen(char *name,char *mode){
- char buffer[120],*m;
- strcpy(buffer,name);
- if(mode[0]=='w'){
- if(stcpm(buffer,".lsp",&m)!=4)strcat(buffer,".lsp");
- wfile(buffer);}
- return(fopen(buffer,mode));}
-
- /* oserror - print an error message */
- void oserror(char *msg){
- printf("error: %s\n",msg);}
-
- /* xsystem - the built-in function 'system' */
- LVAL xsystem(void){
- char *str;
- int result;
-
- /* get the command string */
- str=getstring(xlgastring());
- xllastarg();
- if(!fh&&!(fh=(struct FileHandle *)Output())&&
- !(fh=(struct FileHandle *)Open("CON:0/10/640/100/XLisp CLI",MODE_NEWFILE)))
- xlfail("unable to open CLI");
- result=Execute(str,0,(BPTR)fh);
- return(cvfixnum((FIXTYPE)result));}
-
- /* xarexx - the built-in function 'arexx' */
- LVAL xarexx(void){
- char *str;
- int result;
-
- /* get the command string */
- str=getstring(xlgastring());
- xllastarg();
- if(!RexxStuff)xlfail("no AREXX port");
- result=SendARexxMsg(RexxStuff,str,0);
- return(cvfixnum((FIXTYPE)result));}
-
- /* osagetc - get a character from an ascii file */
- int osagetc(FILE *fp){
- return(getc(fp));}
-
- /* osaputc - put a character to an ascii file */
- int osaputc(int ch,FILE *fp){
- return(putc(ch,fp));}
-
- /* ossymbols - lookup important symbols */
- void ossymbols(void){
- statsymbols();}
-
- unsigned long run_tick_count(void){
- unsigned int clock[2];
- timer(clock);
- return((unsigned long)(6e-5*(1e6*(clock[0]-start_time)+clock[1])));}
-
- #ifndef HZ
- #define HZ 60
- #endif
-
- unsigned long real_tick_count(void){
- return((unsigned long)(HZ*(time((unsigned long *)NULL)-time_stamp)));}
-
- unsigned long ticks_per_second(void){
- return((unsigned long)HZ);}
-
- void SysBeep(int n){
- DisplayBeep(0);}
-
- void bzero(char *p,int n){
- while(n-->0)*p++=0;}
-
- void osfinit(void){
- statfinit();}
-
- void osreset(void){
- }
-
- FILE *osbopen(char *name,char *mode){
- char nmode[4];
- strcpy(nmode,mode);
- strcat(nmode,"b");
- return(fopen(name,nmode));}
-
- int osbgetc(FILE *fp){
- return(getc(fp));}
-
- int osbputc(int ch,FILE *fp){
- return(putc(ch,fp));}
-
- extern unsigned short bag[];
- void set_gc_cursor(int on){
- struct Window *w;
- w=screen->FirstWindow;
- while(w){
- if(w->Flags&WINDOWACTIVE)break;
- w=w->NextWindow;}
- if(w){
- if(on){
- SetPointer(w,bag,16,16,-2,-1);}
- else {
- if(w==window)SetPointer(w,0,0,0,0,0);
- else ami_do_cursor((StGWWinInfo *)*w->UserData);}}}
-
- /* find lisp menu with a specified Amiga ID */
- static LVAL get_menu_by_id(int m){
- struct SuperMenu *this;
- int i;
- this=Menu_Ptr;
- i=0;
- while(this&&i!=m){
- i++;
- this=this->Next;}
- if(!this)xlfail("menu not found");
- return(get_menu_by_hardware((IVIEW_MENU)this));}
-
- static int dokeys(void){
- int ch,i;
- if((ch=xgetc())!=-1)switch(ch){
- case '\r': {
- lbuf[lcount]='\n';
- xputc('\r');
- xputc('\n');
- lposition=0;
- if(tfp)for(lindex=0;lindex<lcount+1;lindex++)osaputc(lbuf[lindex],tfp);
- lindex=1;
- return((int)lbuf[0]);}
- case '\010':
- case '\177': {
- if(lcount){
- lcount--;
- while(lposition>lpos[lcount]){
- xputc('\010');
- xputc(' ');
- xputc('\010');
- lposition--;}}
- return(-2);}
- default: {
- if(ch=='(')numparen++;
- else if(ch==')'&&numparen>0)numparen--;
- if(ch=='\t'||(ch>=0x20&&ch<0x7F)){
- lbuf[lcount]=ch;
- lpos[lcount]=lposition;
- if(ch=='\t'){
- if(!lposition)for(i=0;i<3*numparen;lposition++,i++)xputc(' ');
- else do {
- xputc(' ');}
- while(++lposition&7);}
- else {
- xputc(ch);
- lposition++;}
- lcount++;
- return(-2);}
- else {
- numparen=0;
- xflush();
- switch (ch) {
- case '\003': xltoplevel(); /* control-c */
- case '\007': xlcleanup(); /* control-g */
- case '\020': xlcontinue(); /* control-p */
- case '\032': return(EOF); /* control-z */
- default: return(-2);}}}}
- else return(ch);}
-
- static int dorexx(void){
- struct RexxMsg *rmsg;
- char *nc,*error=0;
- int errlevel=0;
- if(rmsg=GetARexxMsg(RexxStuff)){
- if(strlen(ARG0(rmsg))>LBSIZE){
- errlevel=5;
- error=rexxerror;}
- lcount=stccpy(lbuf,ARG0(rmsg),LBSIZE)-1;
- if(error)SetARexxLastError(RexxStuff,rmsg,error);
- ReplyARexxMsg(RexxStuff,rmsg,0,errlevel);
- nc=lbuf;
- while(*nc)xputc(*nc++);
- xputc('\r');
- xputc('\n');
- lposition=0;
- lbuf[lcount]='\n';
- if(tfp)for(lindex=0;lindex<lcount+1;lindex++)osaputc(lbuf[lindex],tfp);
- lindex=1;
- return((int)lbuf[0]);}
- else return(0);}
-
- extern unsigned short snooze[];
- void Dodo(struct Window *w,unsigned long iflags){
- if(iflags){
- ClearPointer(w);
- ModifyIDCMP(w,iflags);}
- else {
- ModifyIDCMP(w,0);
- SetPointer(w,snooze,22,16,-7,-8);}}
-