/*
 * VT52 protocol module
 * This file must be processed by MKS Lex
 * 
 * Copyright (c) 1990, 1991 by
 * William S. Hall
 * 3665 Benton Street  #66
 * Santa Clara, CA 95051
 *
 */

%{
#define NOKANJI
#define NOATOM
#define NOMINMAX
#define NOSOUND
#include <windows.h>
#ifdef COLUMBIA
#include "wktsmt.h"
#include "wkt100.h"
#else
#include "smterm.h"
#include "win600.h"
#endif
#ifdef WIN600
#include "grterm.h"
#endif

#undef YYLEX
#define YYLEX vt52

#undef YYLMAX
#define YYLMAX (BUFSIZE + 1)

#define YY_PRESERVE

#undef YY_INTERACTIVE
#define YY_INTERACTIVE	0

#undef output
#define output	;

#undef yygetc
#define yygetc mygetc

#undef YY_FATAL
#define YY_FATAL(msg) {HWND hError = GetTopWindow(MWnd.hWnd); \
		       if (!hError) hError = MWnd.hWnd; \
		       MessageBox(hError,msg,szAppName, \
				  MB_OK | MB_ICONEXCLAMATION); \
		       PostMessage(MWnd.hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L); \
}

static int NEAR mygetc(void);
static short currow;

%}

ENQ	[\005]
BEL	[\007]
BS	[\010]
HT	[\011]
LF	[\012]
VT	[\013]
FF	[\014]
CR	[\015]
SO	[\016]
SI	[\017]
CAN	[\030]
EM	[\031]
SUB	[\032]
ESC	[\033]
FS	[\034]
GS	[\035]
RS	[\036]
US	[\037]
SPC	[\040]
DEL	[\177]
ANSI	[\040-\176\221-\222\240-\377]
CTRL	[\000-\037\177\200-\220\223-\237]

%s esc row rowesc col
%x ctrl

%%

<ctrl>[\012-\014] {
    SendMessage(hWndText,SMT_STRINGINPUT,yyleng,(LONG)(LPSTR)yytext);
    SendMessage(hWndText, SMT_COMMAND, SM_NEXTLINE, (LONG)yyleng);
}

<ctrl>[\000-\011\015-\377]+ {
    SendMessage(hWndText,SMT_STRINGINPUT,yyleng,(LONG)(LPSTR)yytext);
}

{ENQ}+ {
    if (MWnd.AutoAnswer) {
	while (yyleng--)
	    ShowAnswerBack();
    }
}

{BEL}+ {
    if (MWnd.WarningBell) {
	while (yyleng--)
	    MessageBeep(0);
    }
}

{BS}+ {
    SendMessage(hWndActive, SMT_COMMAND, SM_BKSP, (LONG)yyleng);
}    

{HT}+ {
    SendMessage(hWndActive, SMT_COMMAND, SM_TAB, (LONG)yyleng);
}    

[\012-\014]+ {
    SendMessage(hWndActive, SMT_COMMAND,
		MWnd.LFCR ? SM_NEXTLINE : SM_INDEX, (LONG)yyleng);
}

{CR}+ {
    SendMessage(hWndActive, SMT_COMMAND, SM_LEFTMARGIN, (LONG)yyleng);
}

{CAN}+ {
    BEGIN 0;
}

{SUB}+ {
    SendMessage(hWndActive,SMT_STRINGINPUT,yyleng,(LONG)(LPSTR)yytext);
    BEGIN 0;
}

<0>{ESC} {
    BEGIN esc;
}

{CTRL} {
    ;
}

<0>{ANSI}+ {
    SendMessage(hWndActive,SMT_STRINGINPUT,yyleng,(LONG)(LPSTR)yytext);
}

<esc>{ESC} {
    ;
}

<esc>\< {
    SendMessage(hWndActive,SMT_COMMAND,SM_SETCHARSET,(LONG)ANSI_CHARSET);
    SetAlphaParams(100);
    if (input() != EOF)
        pushback();
    return 1;
}

<esc>= {
    MWnd.ApplMode = TRUE;
    BEGIN 0;
}

<esc>\> {
    MWnd.ApplMode = FALSE;
    BEGIN 0;
}

<esc>A {
    SendMessage(hWndActive, SMT_COMMAND, SM_CURSORUP,1L);
    BEGIN 0;
}
    
<esc>B {
    SendMessage(hWndActive, SMT_COMMAND, SM_CURSORDOWN,1L);
    BEGIN 0;
}
    
<esc>C {
    SendMessage(hWndActive, SMT_COMMAND, SM_CURSORRIGHT,1L);
    BEGIN 0;
}
    
<esc>D {
    SendMessage(hWndActive, SMT_COMMAND, SM_CURSORLEFT,1L);
    BEGIN 0;
}

<esc>F {
    // Enter line drawing graphics
    SendMessage(hWndActive,SMT_COMMAND,SM_SETCHARSET,(LONG)SYMBOL_CHARSET);
    BEGIN 0;
}

<esc>G {
    // Exit line drawing graphics
    SendMessage(hWndActive,SMT_COMMAND,SM_SETCHARSET,(LONG)0);
    BEGIN 0;
}

<esc>H {
    SendMessage(hWndActive, SMT_COMMAND, SM_CURSORHOME,0L);
    BEGIN 0;
}

<esc>I {
    SendMessage(hWndActive, SMT_COMMAND, SM_REVERSEINDEX, 1L);
    BEGIN 0;
}

<esc>J {
    SendMessage(hWndActive, SMT_COMMAND, SM_CLRTOENDOFPAGE,0L);
    BEGIN 0;
}

<esc>K {
    SendMessage(hWndActive, SMT_COMMAND, SM_CLRTOENDOFLINE, 0L);
    BEGIN 0;
}

<esc>V {
    // Print line of cursor
    BEGIN 0;
}

<esc>W {
    // enter printer controller mode
    BEGIN 0;
}

<esc>X {
    // exit printer controller mode
    BEGIN 0;
}

<esc>Y {
    BEGIN row;
}

<esc>Z {
    IdentifyTerm(52);
    BEGIN 0;
}

<esc>\] {
    // Print page
    BEGIN 0;
}

<esc>\^ {
    // enter autoprint mode
    BEGIN 0;
}

<esc>\_ {
    // exit autoprint mode
    BEGIN 0;
}

<esc>{ANSI} {
    BEGIN 0;
}

<row>{ESC} {
    BEGIN rowesc;
}

<row>{ANSI} {
    currow = *yytext - 31;
    BEGIN col;
}

<rowesc>{ESC} {
    ;
}

<rowesc>{ANSI} {
    BEGIN row;
}

<col>{ESC} {
    BEGIN rowesc;
}

<col>{ANSI} {
    SendMessage(hWndActive,SMT_COMMAND,SM_POSITIONCURSOR,
					MAKELONG(currow, *yytext - 31));
    BEGIN 0;
}

%%

void FAR vt52SetState(int state)
{
    if (state < 0)
	BEGIN ctrl;
    else
        BEGIN state;
}

static int NEAR mygetc()
{

    if (pBuf->len > 0) {
	pBuf->len--;
	return (*pBuf->ptr++) & curproto.mask;
    }	
    else
	return EOF;
    
}

void FAR VT52SpecialKeys(int item)
{

    int index;

    static char *VT52Keys[] = {
        "\033A","\033B","\033C","\033D","\033H",	// 4
	"\033P","\033Q","\033R","\033S",		// 8
	"\033?p","0",
	"\033?q","1",
	"\033?r","2",
	"\033?s","3",
	"\033?t","4",
	"\033?u","5",
	"\033?v","6",
	"\033?w","7",
	"\033?x","8",
	"\033?y","9",
	"\033?l","+",	// 29
	"\033?m","-",
	"\033?n",".",
	"\033?M","*",
    };

    switch(item) {
	case IDM_UP:
	case IDM_S_UP:
	case IDM_C_UP:
	case IDM_CS_UP:
	    index = 0;
	    break;

	case IDM_DOWN:
	case IDM_S_DOWN:
	case IDM_C_DOWN:
	case IDM_CS_DOWN:
	    index = 1;
	    break;

	case IDM_RIGHT:
	case IDM_S_RIGHT:
	case IDM_C_RIGHT:
	case IDM_CS_RIGHT:
	    index = 2;
	    break;

	case IDM_LEFT:
	case IDM_S_LEFT:
	case IDM_C_LEFT:
	case IDM_CS_LEFT:
	    index = 3;
	    break;

	case IDM_HOME:
	case IDM_S_HOME:
	case IDM_C_HOME:
	case IDM_CS_HOME:
	    index = 4;
	    break;

	case IDM_F1:
	    index = 5;
	    break;

	case IDM_F2:
	    index = 6;
	    break;

	case IDM_F3:
	    index = 7;
	    break;

	case IDM_F4:
	    index = 8;
	    break;

	case IDM_NUM0:
//	case IDM_S_NUM0:
	case IDM_C_NUM0:
//	case IDM_CS_NUM0:
	    index = (MWnd.ApplMode ? 9 : 10);
	    break;

	case IDM_NUM1:
//	case IDM_S_NUM1:
	case IDM_C_NUM1:
//	case IDM_CS_NUM1:
	    index = (MWnd.ApplMode ? 11 : 12);
	    break;

	case IDM_NUM2:
//	case IDM_S_NUM2:
	case IDM_C_NUM2:
//	case IDM_CS_NUM2:
	    index = (MWnd.ApplMode ? 13 : 14);
	    break;

	case IDM_NUM3:
//	case IDM_S_NUM3:
	case IDM_C_NUM3:
//	case IDM_CS_NUM3:
	    index = (MWnd.ApplMode ? 15 : 16);
	    break;

	case IDM_NUM4:
//	case IDM_S_NUM4:
	case IDM_C_NUM4:
//	case IDM_CS_NUM4:
	    index = (MWnd.ApplMode ? 17 : 18);
	    break;

	case IDM_NUM5:
//	case IDM_S_NUM5:
	case IDM_C_NUM5:
//	case IDM_CS_NUM5:
	    index = (MWnd.ApplMode ? 19 : 20);
	    break;

	case IDM_NUM6:
//	case IDM_S_NUM6:
	case IDM_C_NUM6:
//	case IDM_CS_NUM6:
	    index = (MWnd.ApplMode ? 21 : 22);
	    break;

	case IDM_NUM7:
//	case IDM_S_NUM7:
	case IDM_C_NUM7:
//	case IDM_CS_NUM7:
	    index = (MWnd.ApplMode ? 23 : 24);
	    break;

	case IDM_NUM8:
//	case IDM_S_NUM8:
	case IDM_C_NUM8:
//	case IDM_CS_NUM8:
	    index = (MWnd.ApplMode ? 25 : 26);
	    break;

	case IDM_NUM9:
//	case IDM_S_NUM9:
	case IDM_C_NUM9:
//	case IDM_CS_NUM9:
	    index = (MWnd.ApplMode ? 27 : 28);
	    break;

	case IDM_ADD:		// replacing VT100 keypad comma for keypad
//	case IDM_S_ADD:
	case IDM_C_ADD:
//	case IDM_CS_ADD:
	    index = 
		(MWnd.ApplMode && (GetKeyState(VK_NUMLOCK) & 1) ? 29 : 30);
	    break;

	case IDM_SUBTRACT:
//	case IDM_S_SUBTRACT:
	case IDM_C_SUBTRACT:
//	case IDM_CS_SUBTRACT:
	    index = 
		(MWnd.ApplMode && (GetKeyState(VK_NUMLOCK) & 1) ? 31 : 32);
	    break;

	case IDM_DECIMAL:
//	case IDM_S_DECIMAL:
	case IDM_C_DECIMAL:
//	case IDM_CS_DECIMAL:
	    index = (MWnd.ApplMode ? 33 : 34);
	    break;

	case IDM_MULTIPLY:	// replacing VT100 enter key for keypad
//	case IDM_S_MULTIPLY:
	case IDM_C_MULTIPLY:
//	case IDM_CS_MULTIPLY:
	    index = 
		(MWnd.ApplMode && (GetKeyState(VK_NUMLOCK) & 1) ? 35 : 36);
	    break;

	default:
	    return;
    }
    WriteToComm(VT52Keys[index], strlen(VT52Keys[index]));
}
