/****************************************************
 * vt100 emulator - window/keyboard support
 *
 *	     860823 DBW - Integrated and rewrote lots of code
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ****************************************************/

#define MODULE_WINDOW 1
#include "vt100.h"

/* forward declarations for LATTICE */
void filename();
void emits();
void emit();
void emitbatch();
void cursoroff();
void cursoron();

/*************************************************
*  function to get file name
*************************************************/
void filename(name)
char name[];
    {
    char c;
    ULONG class;
    unsigned int code;
    int keepgoing,i;
    keepgoing = TRUE;
    i=0;
    while (keepgoing) {
	while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
	    {
	    class = NewMessage->Class;
	    code = NewMessage->Code;
	    ReplyMsg( NewMessage );
	    if (class=RAWKEY)
		{
		c = toasc(code,1);
		name[i]=c;
		if (name[i] != 0)
		    {
		    if (name[i] == 13)
			{
			name[i]=0;
			keepgoing = FALSE;
			}
		    else
			{
			if (name[i] == 8 || name[i] == 127)
			    {
			    i -= 2;
			    if (i < -1)  i = -1;
			    else {
				if (x == MINX) { y -= 8; x = MAXX; }
				emit(8);
				emit(32);
				emit(8);
				}
			    }
			else
			emit(c);
			if (x == MAXX) emits("\n");
			}
		    i += 1;
		    }
		}
	    } /* end of new message loop */
	}   /* end of god knows what */
    emit(13);
    emit(10);
    } /* end of function */


/*************************************************
*  function to print a string
*************************************************/
void emits(string)
char string[];
    {
    int i;
    char c;

    i=0;
    while (string[i] != 0)
	{
	c=string[i];
	if (c == 10) emit(13);
	emit(c);
	i += 1;
	}
    }

/*************************************************
*  function to output ascii chars to window
*************************************************/
void emit(c)
char c;
    {
    Move(mywindow->RPort,(long)x,(long)y);

    c &= 0x7F;
    switch( c )
	{
	case '\t':
	x += 64 - ((x-MINX) % 64);
	break;

	case 10:  /* lf */
	y += 8;
	break;

	case 13:  /* cr */
	x = MINX;
	break;

	case 8:   /* backspace */
	x -= 8;
	if (x < MINX) x = MINX;
	break;

	case 12:     /* page */
	x = MINX;
	y = MINY;
	SetAPen(mywindow->RPort,0L);
	RectFill(mywindow->RPort,(long)MINX,
	    (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
	SetAPen(mywindow->RPort,1L);
	break;

	case 7:     /* bell */
	DisplayBeep(NULL);
	ClipBlit(mywindow->RPort,0L,0L,mywindow->RPort,0L,0L,
	    (long)MAXX,(long)MAXY,0x50L);
	ClipBlit(mywindow->RPort,0L,0L,mywindow->RPort,0L,0L,
	    (long)MAXX,(long)MAXY,0x50L);
	break;

	default:
	if (c < ' ' || c > '~') break;
	if (curmode&REVERSE) {
	    Text(mywindow->RPort," ",1L);
	    Move(mywindow->RPort,(long)x,(long)y);
	    SetDrMd(mywindow->RPort,(long)INVERSVID);
	    if (curmode&BOLD)
		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
	    Text(mywindow->RPort,&c,1L);
	    if (curmode&UNDERLINE) RectFill(mywindow->RPort,
		(long)(x-1),(long)(y+1),(long)(x+8),(long)(y+1));
	    if (curmode&BOLD) SetAPen(mywindow->RPort,1L);
	    SetDrMd(mywindow->RPort,(long)JAM2);
	    }
	else {
	    if (curmode&BOLD)
		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
	    Text(mywindow->RPort,&c,1L);
	    if (curmode&UNDERLINE) RectFill(mywindow->RPort,
		(long)(x-1),(long)(y+1),(long)(x+8),(long)(y+1));
	    if (curmode&BOLD) SetAPen(mywindow->RPort,1L);
	    }
	x += 8;
	} /* end of switch */

    while (x > MAXX) x -= 8;
    while (y > MAXY) {
	y -= 8;
	x  = MINX;
	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
	}
    }

/*************************************************
*  function to output ascii chars to window (batched)
*************************************************/
void emitbatch(la,lookahead)
int la;
char *lookahead;
    {
    int i;	
    Move(mywindow->RPort,(long)x,(long)y);
    i = x / 8;
    if (i+la > maxcol) la = maxcol-i;
    if (curmode&REVERSE) {
	Text(mywindow->RPort,blanks,(long)la);
	Move(mywindow->RPort,(long)x,(long)y);
	SetDrMd(mywindow->RPort,(long)INVERSVID);
	if (curmode&BOLD)
		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
	Text(mywindow->RPort,lookahead,(long)la);
	if (curmode&UNDERLINE) RectFill(mywindow->RPort,
	    (long)(x-1),(long)(y+1),(long)((x+8*la)+8),(long)(y+1));
	if (curmode&BOLD) SetAPen(mywindow->RPort,1L);
	SetDrMd(mywindow->RPort,(long)JAM2);
	}
    else {
	if (curmode&BOLD)
		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
	Text(mywindow->RPort,lookahead,(long)la);
	if (curmode&UNDERLINE) RectFill(mywindow->RPort,
	    (long)(x-1),(long)(y+1),(long)((x+8*la)+8),(long)(y+1));
	if (curmode&BOLD) SetAPen(mywindow->RPort,1L);
	}
    x += (8 * la);
    }

/******************************
* Manipulate cursor
******************************/
void cursoroff()
    {
    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
    SetAPen(mywindow->RPort,3L);
    RectFill(mywindow->RPort,
	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
    SetAPen(mywindow->RPort,1L);
    SetDrMd(mywindow->RPort,(long)JAM2);
    }

void cursoron()
    {
    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
    SetAPen(mywindow->RPort,3L);
    RectFill(mywindow->RPort,
	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
    SetAPen(mywindow->RPort,1L);
    SetDrMd(mywindow->RPort,(long)JAM2);
    }

/************************************************
*  function to take raw key data and convert it 
*  into ascii chars
**************************************************/
int toasc(code,local)
unsigned int code;
int local;
    {
    static int ctrl = FALSE;
    static int shift = FALSE;
    static int capsl = FALSE;
    char c;
    static char keys[75] = {
	'`','1','2','3','4','5','6','7','8','9','0','-' ,
	'=','\\', 0, '0','q','w','e','r','t','y','u','i','o' ,
	'p','[',']', 0, '1','2','3','a','s','d','f','g','h' ,
	'j','k','l',';','\'', 0, 0, '4','5','6', 0, 'z','x','c','v',
	'b','n','m',44,'.','/', 0, '.','7','8','9',' ',8,
	'\t',13,13,27,127,0,0,0,'-' } ;

    switch ( code )
	{
	case 98:   capsl = TRUE; c = 0;break;
	case 226:  capsl = FALSE;c = 0;break;
	case 99:   ctrl = TRUE;  c = 0;break;
	case 227:  ctrl = FALSE; c = 0;break;
	case 96:
	case 97:   shift = TRUE; c = 0;break;
	case 224:
	case 225:  shift = FALSE;c = 0;break;
	case 0x50: 
	case 0x51: 
	case 0x52: 
	case 0x53: 
	case 0x54: 
	case 0x55: 
	case 0x56: 
	case 0x57: 
	case 0x58: 
	case 0x59:  c = 0;
		    if (shift)	sendstring(p_F[code - 0x50]);
		    else	sendstring(p_f[code - 0x50]);
		    break;
	case 0x0f: c=0; sendstring("\033Op"); break;
	case 0x1d: c=0; sendstring("\033Oq"); break;
	case 0x1e: c=0; sendstring("\033Or"); break;
	case 0x1f: c=0; sendstring("\033Os"); break;
	case 0x2d: c=0; sendstring("\033Ot"); break;
	case 0x2e: c=0; sendstring("\033Ou"); break;
	case 0x2f: c=0; sendstring("\033Ov"); break;
	case 0x3d: c=0; sendstring("\033Ow"); break;
	case 0x3e: c=0; sendstring("\033Ox"); break;
	case 0x3f: c=0; sendstring("\033Oy"); break;
	case 0x43: c=0; sendstring("\033OM"); break;
	case 0x4a: c=0; sendstring("\033Ol"); break;
	case 0x5f: c=0; sendstring("\033Om"); break;
	case 0x3c: c=0; sendstring("\033On"); break;
	case 0x4c: c=0; sendstring("\033[A"); break;
	case 0x4d: c=0; sendstring("\033[B"); break;
	case 0x4e: c=0; sendstring("\033[C"); break;
	case 0x4f: c=0; sendstring("\033[D"); break;

	default:
	if (code < 75) c = keys[code];
	else c = 0;
	}

    /* add modifiers to the keys */

    if (c != 0) {
	if (shift) {
	    if ((c <= 'z') && (c >= 'a')) c -= 32;
	    else
	    switch( c ) {
		case '[':  c = '{'; break;
		case ']':  c = '}'; break;
		case '\\': c = '|'; break;
		case '\'': c = '"'; break;
		case ';':  c = ':'; break;
		case '/':  c = '?'; break;
		case '.':  c = '>'; break;
		case ',':  c = '<'; break;
		case '`':  c = '~'; break;
		case '=':  c = '+'; break;
		case '-':  c = '_'; break;
		case '1':  c = '!'; break;
		case '2':  c = '@'; break;
		case '3':  c = '#'; break;
		case '4':  c = '$'; break;
		case '5':  c = '%'; break;
		case '6':  c = '^'; break;
		case '7':  c = '&'; break;
		case '8':  c = '*'; break;
		case '9':  c = '('; break;
		case '0':  c = ')'; break;
		default:            break;
		}
	    }
	else if (capsl && (c <= 'z') && (c >= 'a')) c -= 32;
	}
    if (ctrl) {
	if (c >= '`' && c <= 127) c -= 96;
	else if (c >= '@' && c <= '_') c -= 64;
	}
    if (c != 0 && (!local)) sendchar(c);
    return((int)c);
    }

