home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * This defines Archimedes screen-handling and spawning fns - div
- * (based on vt52.c & msdos files, so not necessarily the way i
- would have done it - might redo it when i understand it !)
- */
-
- #define termdef 1 /* don't define "term" external */
-
- /*{{{ include files*/
- #include <stdio.h>
- #include <kernel.h>
- #include <time.h>
- #include "estruct.h"
- #include "etype.h"
- #include "edef.h"
- #include "elang.h"
- /*}}}*/
-
- /*{{{ part one - terminal control stuff*/
-
- #if RISCOS
-
- /*{{{ various #defines*/
- #define NROW 31 /* Screen size. */
- #define NCOL 80 /* Edit if you want to. */
- #define MARGIN 8 /* size of minimim margin and */
- #define SCRSIZ 64 /* scroll size for extended lines */
- #define NPAUSE 500 /* # times thru update to pause */
- #define ESC 0x1B /* ESC character. */
- #define BEL 0x07 /* ascii bell character */
- /*}}}*/
- /*{{{ function prototypes*/
- extern int ttopen(); /* Forward references. */
- extern int ttgetc();
- extern int ttputc();
- extern int ttflush();
- extern int ttclose();
- extern int armmove();
- extern int armeeol();
- extern int armeeop();
- extern int armbeep();
- extern int armopen();
- extern int armrev();
- extern int armcres();
- extern int armkopen();
- extern int armkclose();
-
- #if COLOR
- extern int armfcol();
- extern int armbcol();
- #endif
- /*}}}*/
-
- /*{{{ despatch table*/
- /*
- * Dispatch table. All the
- * hard fields just point into the
- * terminal I/O code.
- */
- TERM term = {
- NROW-1,
- NROW-1,
- NCOL,
- NCOL,
- MARGIN,
- SCRSIZ,
- NPAUSE,
- armopen,
- ttclose,
- armkopen,
- armkclose,
- ttgetc,
- ttputc,
- ttflush,
- armmove,
- armeeol,
- armeeop,
- armbeep,
- armrev,
- armcres
- #if COLOR
- , armfcol,
- armbcol
- #endif
- };
- /*}}}*/
-
- /*{{{ the functions*/
-
- /*{{{ armmove(row, col)*/
- armmove(row, col)
- {
- _kernel_oswrch(31);
- _kernel_oswrch(col);
- _kernel_oswrch(row);
- }
- /*}}}*/
- /*{{{ armeeol()*/
- armeeol()
- {
- _kernel_oswrch(23); _kernel_oswrch(8); /* vdu 23,8.. clears block */
- _kernel_oswrch(5); _kernel_oswrch(6); /* 5,6 = current posn->eol */
- _kernel_oswrch(0); _kernel_oswrch(0); /* lots of zeroes means no */
- _kernel_oswrch(0); _kernel_oswrch(0); /* offsets involved */
- _kernel_oswrch(0); _kernel_oswrch(0);
- }
- /*}}}*/
- /*{{{ armeeop()*/
- armeeop()
- {
- #if COLOR
- armbcol(gbcolor); /* seem to need this - dunno why ! */
- #endif
-
- _kernel_oswrch(23); _kernel_oswrch(8); /* vdu 23,8 clears a block */
- _kernel_oswrch(5); _kernel_oswrch(10); /* from curent posn to eop */
- _kernel_oswrch(0); _kernel_oswrch(0); /* start at current posn */
- _kernel_oswrch(0); _kernel_oswrch(0);
- _kernel_oswrch(0); _kernel_oswrch(0);
-
- }
- /*}}}*/
- /*{{{ armrev(status)*/
- armrev(status) /* set the reverse video state */
-
- int status; /* TRUE = reverse video, FALSE = normal video */
-
- { static int rev_vid=FALSE;
- if (status != rev_vid)
- { _kernel_oswrch(23); _kernel_oswrch(17);
- _kernel_oswrch(5); _kernel_oswrch(0);
- _kernel_oswrch(0); _kernel_oswrch(0);
- _kernel_oswrch(0); _kernel_oswrch(0);
- _kernel_oswrch(0); _kernel_oswrch(0);
- rev_vid=status;
- }
- }
- /*}}}*/
- /*{{{ armcres()*/
- armcres(res)
- char *res;
- { int i=0;
- printf("[cres %s]", res);
- if ( (strcmp(res, "0")) && ( (i=asc_int(res))==0))
- return(FALSE);
-
- scinit(i);
- return(TRUE);
-
- }
- /*}}}*/
- /*{{{ spal()*/
- spal() /* change palette string */
-
- {
- /* Does nothing here */
- }
- /*}}}*/
-
- #if COLOR
- /*{{{ armfcol()*/
- armfcol(colour) /* set the forground color */
- int colour;
- {
- _kernel_oswrch(17); _kernel_oswrch(colour);
- }
- /*}}}*/
- /*{{{ armbcol()*/
- armbcol(colour) /* set the background color */
- int colour;
- {
- _kernel_oswrch(17); _kernel_oswrch(colour | 128);
- }
- /*}}}*/
- #endif
-
- /*{{{ armbeep()*/
- armbeep()
- {
- #ifdef BEL
- ttputc(BEL);
- ttflush();
- #endif
- }
- /*}}}*/
- /*{{{ armopen()*/
- armopen()
- {
- scinit(-1);
- ttopen();
- }
- /*}}}*/
- /*{{{ armkopen()*/
- armkopen()
-
- {
- }
- /*}}}*/
- /*{{{ armkclose()*/
- armkclose()
-
- {
- }
- /*}}}*/
-
- #if FLABEL
- /*{{{ fnclabel(f, n)*/
- fnclabel(f, n) /* label a function key */
-
- int f,n; /* default flag, numeric argument [unused] */
-
- {
- /* on machines with no function keys...don't bother */
- return(TRUE);
- }
- /*}}}*/
- #endif
-
- /*}}}*/
-
- #else
-
- /*{{{ armhello()*/
- armhello()
-
- {
- }
- /*}}}*/
-
- #endif
- /*}}}*/
-
- /*{{{ part two - lowlevel stuff (fn spawning, etc)*/
-
- /*
- * This bit is based on msdos.c
- * I may tidy up when i get round to understanding how it all works
- */
-
-
- /*{{{ Mouse stuff*/
- /* The Mouse driver only works with typeahead defined */
- #if MOUSE
- #undef TYPEAH
- #define TYPEAH 1
- #endif
- /*}}}*/
-
- /* Some global variable */
- #define INBUFSIZ 40
- static int mexist; /* is the mouse driver installed? */
- static int nbuttons; /* number of buttons on the mouse */
- static int oldbut; /* Previous state of mouse buttons */
-
- /* input buffers and pointers */
-
- #define IBUFSIZE 64 /* this must be a power of 2 */
-
- unsigned char in_buf[IBUFSIZE]; /* input character buffer */
- int in_next = 0; /* pos to retrieve next input character */
- int in_last = 0; /* pos to place most recent input character */
-
- /*{{{ in_init()*/
- in_init() /* initialize the input buffer */
-
- {
- in_next = in_last = 0;
- }
- /*}}}*/
- /*{{{ in_check()*/
- in_check() /* is the input buffer non-empty? */
-
- {
- if (in_next == in_last)
- return(FALSE);
- else
- return(TRUE);
- }
- /*}}}*/
- /*{{{ in_put(event)*/
- in_put(event)
-
- int event; /* event to enter into the input buffer */
-
- {
- in_buf[in_last++] = event;
- in_last &= (IBUFSIZE - 1);
- }
- /*}}}*/
- /*{{{ int in_get()*/
- int in_get() /* get an event from the input buffer */
-
- {
- register int event; /* event to return */
-
- event = in_buf[in_next++];
- in_next &= (IBUFSIZE - 1);
- return(event);
- }
- /*}}}*/
- /*{{{ stuff to set up the keyboard*/
-
- /* This is for setting up the keyboard...
- *fx 4,2 sets cursor keys as fn keys
- *fx 220,0 makes ^@ the escape key (change to no interrupt when working)
- *fx 221 to *fx 228 control action of blocks of 16 codes above &80
- *fx 238 sets the base of the numeric keypad
- *fx 254 sets action of control on num keys
- */
-
-
- static unsigned char armswis[]=
- {4, 221, 222 ,223, 224, 225, 226, 227, 228, 229, 238, 254 };
- static unsigned char armvals[]=
- {2, 0xc0, 0xd0, 0xe0, 0xf0, 0x80, 0x90, 0xa0, 0xb0, 1, 0xc0, 0};
-
- #define no_fxs (sizeof(armswis))
-
- static armstore[no_fxs];
- /*}}}*/
- /*{{{ PASCAL NEAR ttopen()*/
- PASCAL NEAR ttopen()
- /*
- * This function is called once to set up the terminal device streams.
- */
-
- { _kernel_swi_regs regs;
- int i;
-
-
- /* on all screens we are not sure of the initial position
- of the cursor */
- ttrow = 999;
- ttcol = 999;
-
- for (i=0; i<no_fxs; ++i)
- { regs.r[0]=armswis[i];
- regs.r[1]=armvals[i];
- regs.r[2]=0;
- _kernel_swi(6, ®s, ®s);
- armstore[i]=regs.r[1];
- }
-
-
-
- }
- /*}}}*/
- /*{{{ maxlines(lines)*/
- maxlines(lines) /* set number of vertical rows for mouse */
-
- int lines; /* # of vertical lines */
-
- {
-
- }
- /*}}}*/
- /*{{{ PASCAL NEAR ttclose()*/
- PASCAL NEAR ttclose()
-
- /*
- * This function gets called just before we go back home to the command
- * interpreter. On VMS it puts the terminal back in a reasonable state.
- * Another no-operation on CPM.
- */
-
- { _kernel_swi_regs regs;
- int i;
-
- for (i=0; i<no_fxs; ++i)
- { regs.r[0]=armswis[i];
- regs.r[1]=armstore[i];
- regs.r[2]=0;
- _kernel_swi(6, ®s, ®s);
- }
- }
- /*}}}*/
- /*{{{ PASCAL NEAR ttputc(c)*/
- PASCAL NEAR ttputc(c)
-
- /*
- * Write a character to the display. On VMS, terminal output is buffered, and
- * we just put the characters in the big array, after checking for overflow.
- * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
- * MS-DOS (use the very very raw console output routine).
- */
-
- {
- _kernel_oswrch(c);
- }
- /*}}}*/
- /*{{{ PASCAL NEAR ttflush()*/
- PASCAL NEAR ttflush()
- /*
- * Flush terminal buffer. Does real work where the terminal output is buffered
- * up. A no-operation on systems where byte at a time terminal I/O is done.
- */
- {
- }
- /*}}}*/
- /*{{{ int doschar()*/
- int doschar() /* call the dos to get a char */
-
- { int mask=SPEC; /* only used if a fn key */
- int num;
-
- if ((num=_kernel_osrdch()) < 0x80 ) return(num);
-
- /* its a control key - have a look at shift/ctrl and set flags */
-
- num -= 0x80;
-
- /*{{{ register shift and control bits*/
- if (num & 0x10) num -= 0x10, mask|=SHFT;
- if (num & 0x20) num -= 0x20, mask|=CTRL;
- /*}}}*/
-
- /* this seems the way to do it ??? */
-
- in_put(mask>>8);
-
- /*{{{ map keypad 2,4,6,8 to cursor keys*/
- switch (num)
- { case 0x42 : in_put('E'); return(0); /* keypad 2 = down */
- case 0x44 : in_put('C'); return(0); /* keypad 4 = left */
- case 0x46 : in_put('D'); return(0); /* keypad 6 = right */
- case 0x48 : in_put('F'); return(0); /* keypad 4 = up */
- }
- /*}}}*/
-
- /*{{{ map other keys to useful FN names*/
- if (num < 10) in_put(num+'0'); /* fn keys are FN0 to FN9 */
- else if (num < 16) in_put(num-10+'A'); /* cursor keys are FNA to FNF */
- else in_put(num - 0x40 + 'G'); /* num keypad is FNG to ... */
- /*}}}*/
-
- return(0); /* tell it that a special code is waiting in the buffer */
- }
- /*}}}*/
- /*{{{ PASCAL NEAR ttgetc()*/
- PASCAL NEAR ttgetc()
-
- /*
- * Read a character from the terminal, performing no editing and doing no echo
- * at all. Also mouse events are forced into the input stream here.
- */
-
- {
- register int c; /* character read */
-
- ttc: /* return any keystrokes waiting in the
- type ahead buffer */
- if (in_check())
- return(in_get());
-
- if (typahead())
- return(doschar());
-
- /* with no mouse, this is a simple get char routine */
- if (mexist == FALSE || mouseflag == FALSE)
- return(doschar());
-
- #if MOUSE
- /* turn the mouse cursor on */
- rg.x.ax = 1; /* Show Cursor */
- int86(0x33, &rg, &rg);
-
- /* loop waiting for something to happen */
- while (TRUE) {
- if (typahead())
- break;
- if (checkmouse())
- break;
- }
-
- /* turn the mouse cursor back off */
- rg.x.ax = 2; /* Hide Cursor */
- int86(0x33, &rg, &rg);
-
- goto ttc;
- #endif
- }
- /*}}}*/
-
- /*{{{ scinit()*/
- scinit(mode)
- int mode; /* -1 means current mode */
- { static int dtype=-1; /* current mode */
- if (mode==dtype)
- return(FALSE);
-
- _kernel_oswrch(22); _kernel_oswrch(mode);
-
- sprintf(sres, "%d", dtype=mode); /* update $sres env var */
- return(TRUE);
- }
-
- /*}}}*/
-
- #if MOUSE
- /*{{{ checkmouse()*/
- checkmouse()
-
- {
- register int k; /* current bit/button of mouse */
- register int event; /* encoded mouse event */
- int newbut; /* new state of the mouse buttons */
- int mousecol; /* current mouse column */
- int mouserow; /* current mouse row */
- int sstate; /* current shift key status */
-
- /* check to see if any mouse buttons are different */
- rg.x.ax = 3; /* Get button status and mouse position */
- int86(0x33, &rg, &rg);
- newbut = rg.x.bx;
- mousecol = rg.x.cx >> 3;
- mouserow = rg.x.dx >> 3;
-
- /* get the shift key status as well */
- sstate = 0;
- rg.h.ah = 2; /* return current shift status */
- int86(0x16, &rg, &rg);
- sstate = rg.h.al;
-
- for (k=1; k != (1 << nbuttons); k = k<<1) {
- /* For each button on the mouse */
- if ((oldbut&k) != (newbut&k)) {
- /* This button changed, generate an event */
- in_put(0);
- in_put(MOUS >> 8);
- in_put(mousecol);
- in_put(mouserow);
- event = ((newbut&k) ? 0 : 1); /* up or down? */
- if (k == 2) /* center button? */
- event += 4;
- if (k == 4) /* right button? */
- event += 2;
- if (sstate & 3) /* shifted */
- event += 'A';
- else if (sstate & 4) /* controled? */
- event += 1;
- else
- event += 'a'; /* plain */
- in_put(event);
- oldbut = newbut;
- return(TRUE);
- }
- }
- return(FALSE);
- }
- /*}}}*/
- #endif
-
- #if TYPEAH
- /*{{{ PASCAL NEAR typahead()*/
- PASCAL NEAR typahead()
- /* typahead: Check to see if any characters are already in the
- keyboard buffer
- osbyte 152 returns carry set for an empty buffer
- */
-
- {
- return(!(_kernel_osbyte(152,0,0) >> 16));
- }
- /*}}}*/
- #endif
-
- /*{{{ PASCAL NEAR spawncli(f, n)*/
- PASCAL NEAR spawncli(f, n)
- /*
- * Create a subjob with a copy of the command intrepreter in it. When the
- * command interpreter exits, mark the screen as garbage so that you do a full
- * repaint. Bound to "^X C".
- */
-
- {
- /* don't allow this command if restricted */
- if (restflag)
- return(resterr());
-
- movecursor(term.t_nrow, 0); /* Seek to last line. */
- TTflush();
- TTkclose();
- shellprog("");
- TTkopen();
- sgarbf = TRUE;
- return(TRUE);
- }
- /*}}}*/
- /*{{{ PASCAL NEAR spawn(f, n)*/
- PASCAL NEAR spawn(f, n)
- /*
- * Run a one-liner in a subjob. When the command returns, wait for a single
- * character to be typed, then mark the screen as garbage so a full repaint is
- * done. Bound to "C-X !".
- */
- {
- register int s;
- char line[NLINE];
-
- /* don't allow this command if restricted */
- if (restflag)
- return(resterr());
-
- if ((s=mlreply("!", line, NLINE)) != TRUE)
- return(s);
- movecursor(term.t_nrow - 1, 0);
- TTkclose();
- shellprog(line);
- TTkopen();
- /* if we are interactive, pause here */
- if (clexec == FALSE) {
- mlputs(TEXT6);
- /* "\r\n\n[End]" */
- tgetc();
- }
- sgarbf = TRUE;
- return (TRUE);
- }
- /*}}}*/
- /*{{{ PASCAL NEAR execprg(f, n)*/
- PASCAL NEAR execprg(f, n)
- /*
- * Run an external program with arguments. When it returns, wait for a single
- * character to be typed, then mark the screen as garbage so a full repaint is
- * done. Bound to "C-X $".
- */
-
- {
- register int s;
- char line[NLINE];
-
- /* don't allow this command if restricted */
- if (restflag)
- return(resterr());
-
- if ((s=mlreply("$", line, NLINE)) != TRUE)
- return(s);
- movecursor(term.t_nrow - 1, 0);
- TTkclose();
- execprog(line);
- TTkopen();
- /* if we are interactive, pause here */
- if (clexec == FALSE) {
- mlputs(TEXT6);
- /* "\r\n\n[End]" */
- tgetc();
- }
- sgarbf = TRUE;
- return (TRUE);
- }
- /*}}}*/
- /*{{{ PASCAL NEAR pipecmd(f, n)*/
- PASCAL NEAR pipecmd(f, n)
- /*
- * Pipe a one line command into a window
- * Bound to ^X @
- */
- {
-
- }
- /*}}}*/
- /*{{{ PASCAL NEAR filter(f, n)*/
- PASCAL NEAR filter(f, n)
-
- /*
- * filter a buffer through an external DOS program
- * Bound to ^X #
- */
- {
-
- }
- /*}}}*/
-
- /*{{{ PASCAL NEAR shellprog(cmd)*/
- PASCAL NEAR shellprog(cmd)
-
- /* SHELLPROG: Execute a command in a subshell */
-
- char *cmd; /* Incoming command line to execute */
-
- {
-
- }
- /*}}}*/
- /*{{{ PASCAL NEAR execprog(cmd)*/
- PASCAL NEAR execprog(cmd)
-
- /* EXECPROG: A function to execute a named program
- with arguments
- */
-
- #if LATTICE | AZTEC | MWC
- #define CFLAG 1
- #endif
-
- char *cmd; /* Incoming command line to execute */
-
- {
-
- }
- /*}}}*/
-
- /*{{{ char *PASCAL NEAR timeset()*/
- char *PASCAL NEAR timeset()
- /* return a system dependant string with the current time */
-
- { static char buffer[40];
- time_t now;
- time(&now);
- if (strftime(buffer, 40, "%c", localtime(&now)))
- return (buffer);
- return (NULL);
- }
- /*}}}*/
-
-
- /* FILE Directory routines */
-
- #if COMPLET & (TURBO)
-
- char path[NFILEN]; /* path of file to find */
- char rbuf[NFILEN]; /* return file buffer */
-
- /*{{{ char *PASCAL NEAR getffile(fspec)*/
- char *PASCAL NEAR getffile(fspec)
- /* do a wild card directory search (for file name completion) */
-
- char *fspec; /* pattern to match */
-
- {
- register int index; /* index into various strings */
- register int point; /* index into other strings */
- register int extflag; /* does the file have an extention? */
- char fname[NFILEN]; /* file/path for DOS call */
-
- /* first parse the file path off the file spec */
- strcpy(path, fspec);
- index = strlen(path) - 1;
- while (index >= 0 && (path[index] != '/' &&
- path[index] != '\\' && path[index] != ':'))
- --index;
- path[index+1] = 0;
-
- /* check for an extension */
- point = strlen(fspec) - 1;
- extflag = FALSE;
- while (point >= 0) {
- if (fspec[point] == '.') {
- extflag = TRUE;
- break;
- }
- point--;
- }
-
- /* construct the composite wild card spec */
- strcpy(fname, path);
- strcat(fname, &fspec[index+1]);
- strcat(fname, "*");
- if (extflag == FALSE)
- strcat(fname, ".*");
-
- /* and call for the first file */
- if (findfirst(fname, &fileblock, 0) == -1)
- return(NULL);
-
- /* return the first file name! */
- strcpy(rbuf, path);
- strcat(rbuf, fileblock.ff_name);
- mklower(rbuf);
- return(rbuf);
- }
- /*}}}*/
- /*{{{ char *PASCAL NEAR getnfile()*/
- char *PASCAL NEAR getnfile()
-
- {
- register int index; /* index into various strings */
- register int point; /* index into other strings */
- register int extflag; /* does the file have an extention? */
- char fname[NFILEN]; /* file/path for DOS call */
-
- /* and call for the first file */
- if (findnext(&fileblock) == -1)
- return(NULL);
-
- /* return the first file name! */
- strcpy(rbuf, path);
- strcat(rbuf, fileblock.ff_name);
- mklower(rbuf);
- return(rbuf);
- }
- /*}}}*/
-
- #else
-
- /*{{{ char *PASCAL NEAR getffile(fspec)*/
- char *PASCAL NEAR getffile(fspec)
-
- char *fspec; /* file to match */
-
- {
- return(NULL);
- }
- /*}}}*/
- /*{{{ char *PASCAL NEAR getnfile()*/
- char *PASCAL NEAR getnfile()
-
- {
- return(NULL);
- }
- /*}}}*/
-
- #endif
- /*}}}*/
-