/* mint.c */

/* Author:
 *	Warwick Allison
 *	warwick@cs.uq.oz.au
 *
 * (Based on unix.c and atari.c)
 */


/* This file contains the mint-specific version the ttyread() functions.
 */

#include "config.h"

#if MINT
# include "vi.h"
# include <osbind.h>

/* For MINT, we copy V7 UNIX we set an alarm() before doing a blocking
 * read(), and assume that the SIGALRM signal will cause the read() function
 * to give up.
 */

#include <setjmp.h>

static jmp_buf env;

/*ARGSUSED*/
int dummy(signo)
	int	signo;
{
	longjmp(env, 1);
}
int ttyread(buf, len, time)
	char	*buf;	/* where to store the gotten characters */
	int	len;	/* maximum number of characters to read */
	int	time;	/* maximum time to allow for reading */
{
	/* arrange for timeout */
#if __GNUC__
	signal(SIGALRM, (void (*)()) dummy);
#else
	signal(SIGALRM, dummy);
#endif
	alarm(time);

	/* perform the blocking read */
	if (setjmp(env) == 0)
	{
		const int SHF=3;
		const int CNT=4;
		const int ALT=8;

		int pos=0;
		long l = Bconin(2);
		int meta = Kbshift(-1);

		if (len>1) {
			unsigned char sc=l>>16;
			unsigned char ch=l&0xff;

			char format[10]="#%s%c";

			if (sc >= 0x63 && sc <= 0x72 || sc == 0x4a || sc == 0x4e) {
				/* Keypad */
				strcpy(format,"#%sK%c");
				ch=0;
			} else if (sc >= 0x3b && sc <= 0x44) {
				/* F keys */
				if (sc == 0x44) sc-=10; /* Map F10 to F0 */
				sprintf(format,"#%%sF%d",sc-0x3b+1);
				ch=0;
			} else if (sc >= 0x54 && sc <= 0x5d) {
				/* Shifted F keys - convert back to unshifted */
				sc-=(0x54-0x3b);
				if (sc == 0x44) sc-=10;
				sprintf(format,"#%%sF%d",sc-0x3b+1);
				meta|=SHF; /* Will be set anyway */
				ch=0;
			} else if (sc >= 0x78 && sc <= 0x83) {
				/* Alt-numberkeys */
				sc-=(0x78-0x02);
				meta|=ALT;
			} else if (sc == 0x62) {
				/* Help */
				strcpy(format,"#%s?");
				ch=0;
			} else if (sc == 0x61) {
				/* Undo */
				strcpy(format,"#%s!");
				ch=0;
			} else if (sc == 0x52) {
				/* Ins */
				strcpy(format,"#%sI");
				ch=0;
			} else if (sc == 0x47) {
				/* Home */
				strcpy(format,"#%sH");
				ch=0;
			} else if (sc == 0x48) {
				/* Up */
				strcpy(format,"#%sU");
				ch=0;
			} else if (sc == 0x4b) {
				/* Left */
				strcpy(format,"#%sL");
				ch=0;
			} else if (sc == 0x50) {
				/* Down */
				strcpy(format,"#%sD");
				ch=0;
			} else if (sc == 0x4d) {
				/* Right */
				strcpy(format,"#%sR");
				ch=0;
			}
			if (!ch) {
				static char* keytable=0;
				char metastr[8];
				int m=0;

				if (meta) {
					metastr[m++]='<';
					if (meta&CNT) metastr[m++] = 'c';
					if (meta&SHF) metastr[m++] = 's';
					if (meta&ALT) metastr[m++] = 'a';
					metastr[m++]='>';
				}
				metastr[m]='\0';

				if (!keytable) {
					keytable=((char**)Keytbl(-1,-1,-1))[0];
				}

				ch=keytable[sc];
				if (!ch) ch='*';

				pos=sprintf(buf,format,metastr,ch);
			} else {
				buf[pos++]=ch;
			}
		} else {
			buf[pos++] = l;
		}

		len=pos;
	}
	else /* I guess we timed out */
	{
		len = 0;
	}

	/* cancel the alarm */
	signal(SIGALRM, dummy); /* <-- to work around a bug in Minix */
	alarm(0);

	/* return the number of bytes read */
	if (len < 0)
		len = 0;
	return len;
}

#endif /* MINT */
