home *** CD-ROM | disk | FTP | other *** search
- /* atari.c */
-
- /* Author:
- * Guntram Blohm
- * Buchenstrasse 19
- * 7904 Erbach, West Germany
- * Tel. ++49-7305-6997
- * sorry - no regular network connection
- */
-
- /*
- * This file contains the 'standard' functions which are not supported
- * by Atari/Mark Williams, and some other TOS-only requirements.
- */
-
- #include "config.h"
- #include "vi.h"
-
- #if TOS || MINT
- #include <osbind.h>
-
- # if !MINT /* MiNT's library is a little more complete :-) */
-
- /* vi uses mode==0 only ... */
- int access(file, mode)
- char *file;
- {
- int fd=Fopen(file, 0);
- if (fd<0)
- return -1;
- Fclose(fd);
- return 0;
- }
-
- char *mktemp(template)
- char *template;
- {
- return template;
- }
-
- # endif
-
- # ifndef __GNUC__
- char *getcwd(buf, size)
- char *buf;
- {
- if (size < 2 + 64)
- return (char *)0;
- buf[0] = Dgetdrv() + 'A';
- buf[1] = ':';
- Dgetpath(buf + 2, 0);
- return buf;
- }
- # endif
-
- /* read -- text mode, compress \r\n to \n
- * warning: might fail when maxlen==1 and at eol
- * ...no longer :-) -nox
- */
-
- int tread(fd, buf, maxlen)
- int fd;
- char *buf;
- int maxlen;
- {
- int i, j, nread=read(fd, buf, (unsigned)maxlen);
-
- if (nread && buf[nread-1]=='\r')
- {
- if (--nread)
- lseek(fd, -1l, 1);
- else {
- if (read(fd, buf, 1) && *buf != '\n') {
- *buf = '\r';
- lseek(fd, -1l, 1);
- }
- return 1;
- }
- }
- for (i=j=0; j<nread; i++,j++)
- { if (buf[j]=='\r' && buf[j+1]=='\n')
- j++;
- buf[i]=buf[j];
- }
- return i;
- }
-
- int twrite(fd, buf, maxlen)
- int fd;
- char *buf;
- int maxlen;
- {
- # if 1
- int i, j;
- /* uh, we can have that easier... -nox */
- static char writbuf[BLKSIZE*2];
-
- for (i=j=0; j<maxlen; )
- {
- if ((writbuf[i++]=buf[j++])=='\n')
- { writbuf[i-1]='\r';
- writbuf[i++]='\n';
- }
- }
- /* ...and make the result a little bit more reasonable too :-) */
- if (!i || !(maxlen = write(fd, writbuf, (unsigned)i)))
- return 0;
- return j - i + maxlen;
- }
- # else
- int i, j, nwritten=0, hadnl=0;
- char writbuf[BLKSIZE];
-
- for (i=j=0; j<maxlen; )
- {
- if ((writbuf[i++]=buf[j++])=='\n')
- { writbuf[i-1]='\r';
- if (i<BLKSIZE)
- writbuf[i++]='\n';
- else
- hadnl=1;
- }
- if (i==BLKSIZE)
- {
- write(fd, writbuf, (unsigned)i);
- i=0;
- }
- if (hadnl)
- {
- writbuf[i++]='\n';
- hadnl=0;
- }
- }
- if (i)
- write(fd, writbuf, (unsigned)i);
- return j;
- }
- # endif
-
- /* The "timer" variable is used as a shadow of the system's timer. Since the
- * system's timer can only be accessed in Supervisor mode, we are forced to
- * do a Supexec(gettime) to copy the system's timer in to the User-mode "timer"
- * variable.
- */
- static long timer;
- static void gettime()
- {
- timer = *(long *)(0x4ba);
- }
- #endif /* TOS || MINT */
-
- #if TOS
- /* This function implements a read-with-timeout from the keyboard. */
- /*ARGSUSED*/
- int ttyread(buf, len, time)
- char *buf; /* where to store the gotten characters */
- int len; /* maximum number of characters to get -- ignored */
- int time; /* maximum time to allow for reading */
- {
- int pos=0;
- long l;
- long endtime;
-
- /* compute the ending time, in increments of 1/200th seconds */
- (void) Supexec(gettime);
- endtime = time * 20 + timer;
-
- /* wait until time runs out, or we get a keystroke */
- while (!pos && (!time || (timer-endtime) < 0))
- {
- if (Bconstat(2))
- {
- l = Bconin(2);
- buf[pos] = l;
- if (buf[pos++] == '\0')
- {
- buf[pos - 1] = '#';
- buf[pos++] = l >> 16;
- }
- }
- (void) Supexec(gettime);
- }
- return pos;
- }
-
- /* This function writes characters to the screen */
- ttywrite(buf, len)
- char *buf;
- int len;
- {
- while (len--)
- Bconout(2, *buf++);
- }
- #endif /* TOS */
-
- #if MINT
- extern int __mint;
-
- # include <signal.h>
- # include <setjmp.h>
-
- static jmp_buf env;
-
- /* ctputs(): same as tputs(), but recognizes #blink / #noblink to
- set the cursormode (have to do it this way because those are not
- available thru the ST's `VT52' emulator...) */
-
- void ctputs(cp, affcnt, outfn)
- char *cp;
- int affcnt;
- int (*outfn)();
- {
- if (!strcmp(cp, "#blink")) {
- (void) Cursconf(2, 0);
- return;
- }
- if (!strcmp(cp, "#noblink")) {
- (void) Cursconf(3, 0);
- return;
- }
- tputs(cp, affcnt, outfn);
- }
-
- /* this turns those shifted cursor- / insert / home keys into
- something useful (without this, they would return digits...) */
-
- static long fixkey(l)
- long l;
- {
- if (l < 0 || !(char) l)
- return l;
- switch ((unsigned char) (l >> 16)) {
- case 72: /* shift- ^ -> PgUp */
- return 73l << 16;
- case 80: /* shift- v -> PgDn */
- return 81l << 16;
- case 71: /* shift-Home -> End */
- return 79l << 16;
- case 75: /* shift- <- -> ctrl- <- */
- return 115l << 16;
- case 77: /* shift- -> -> ctrl- -> */
- return 116l << 16;
- case 82: /* shift-Insert -> Printscreen */
- return 55l << 16;
- }
- return l;
- }
-
- /*ARGSUSED*/
- static void dummy(signo)
- int signo;
- {
- longjmp(env, 1);
- }
-
- /* This function implements a read-with-timeout from the keyboard. */
- /*ARGSUSED*/
- int ttyread(buf, len, time)
- char *buf; /* where to store the gotten characters */
- int len; /* maximum number of characters to get -- ignored on terminals */
- int time; /* maximum time to allow for reading */
- {
- int pos=0;
- long l;
- long endtime;
- static tty; /* 'y' if reading from tty, or 'n' if not a tty */
- extern int got_winch; /* flag from our getsize() SIGWINCH handler */
-
- /* do we know whether this is a tty or not? */
- if (!tty)
- tty = (isatty(0) ? 'y' : 'n');
-
- if (tty != 'y')
- return read(0, buf, (unsigned) len);
-
- if (!__mint) {
- /* no MiNT -> eat cycles :-) */
-
- /* compute the ending time, in increments of 1/200th seconds */
- (void) Supexec(gettime);
- endtime = time * 20 + timer;
-
- /* wait until time runs out, or we get a keystroke */
- while (!pos && (!time || (timer-endtime) < 0))
- {
- if (*o_stbios ? Bconstat(2) : Cconis())
- {
- l = fixkey(*o_stbios ? Bconin(2) : Crawcin());
- if (l < 0)
- return l;
- buf[pos] = l;
- if (buf[pos++] == '\0')
- {
- buf[pos-1] = '#';
- buf[pos++] = l >> 16;
- }
- }
- (void) Supexec(gettime);
- }
- return pos;
- }
- /* MiNT is there -> do it with alarm()
- [yes MiNT also has select(), but as of MiNT version 0.94
- that won't yet work over e.g. a serial line...] */
-
- /* arrange for timeout */
- # if __GNUC__
- signal(SIGALRM, (void (*)()) dummy);
- # else
- signal(SIGALRM, dummy);
- # endif
- alarm(time);
-
- if (setjmp(env))
- return 0;
- do {
- l = fixkey(*o_stbios ? Bconin(2) : Crawcin());
-
- if (got_winch) {
- got_winch = 0;
- if (*o_lines != LINES || *o_columns != COLS) {
- *o_lines = LINES;
- *o_columns = COLS;
- #ifndef CRUNCH
- if (!wset)
- {
- *o_window = LINES - 1;
- }
- #endif
- if (mode != MODE_EX && mode != MODE_COLON)
- /* pretend the user hit ^L */
- buf[pos++] = ctrl('L');
- }
- }
- if (l > 0 && (buf[pos++]=l) == '\0')
- {
- buf[pos-1] = '#';
- buf[pos++] = l>>16;
- }
- } while (!pos);
-
- /* cancel the alarm */
- alarm(0);
-
- /* return the number of bytes read */
- return pos;
- }
-
- void ttywrite(buf, len)
- char *buf;
- int len;
- {
- if (!*o_stbios) {
- write(1, buf, (unsigned) len);
- return;
- }
- while (len--)
- (void) Bconout(2, *buf++);
- }
- #endif /* MINT */
-