/****************************************************************************
File    : KeyboardDlg.cpp
/*
@(#) #SY# Atari800Win PLus
@(#) #IS# CKeyboardDlg implementation file
@(#) #BY# Tomasz Szymankowski
@(#) #LM# 17.03.2002
*/

#include "StdAfx.h"
#include "Atari800Win.h"
#include "Helpers.h"
#include "KeyTemplateDlg.h"
#include "KeyboardDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define IDC_KEYBOARD_FIRST			IDC_KEYBOARD_ARROWKEYS
#define IDC_KEYBOARD_LAST			IDC_KEYBOARD_CANCEL


/////////////////////////////////////////////////////////////////////////////
// Global objects

int g_anKBTable[ KEYBOARD_TABLE_SIZE ];

int g_anNormKeys[ KEYBOARD_TABLE_SIZE ] =
{
/*  0*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BREAK,		
/*  4*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*  8*/		AKEY_BACKSPACE,			AKEY_TAB,				AKEY_NONE,				AKEY_NONE,
/* 12*/		AKEY_CLEAR,				AKEY_RETURN,			AKEY_NONE,				AKEY_NONE,
/* 16*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BREAK,
/* 20*/		AKEY_CAPSTOGGLE,		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 24*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_ESCAPE,
/* 28*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 32*/		AKEY_SPACE,				AKEY_CAPSLOCK,			AKEY_HELP|SPECIAL,		AKEY_ATARI,
/* 36*/		AKEY_CLEAR,				AKEY_LEFT,				AKEY_UP,				AKEY_RIGHT,
/* 40*/		AKEY_DOWN,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 44*/		AKEY_NONE,				AKEY_INSERT_CHAR,		AKEY_DELETE_CHAR,		AKEY_HELP|SPECIAL,
/* 48*/		AKEY_0,					AKEY_1,					AKEY_2,					AKEY_3,
/* 52*/		AKEY_4,					AKEY_5,					AKEY_6,					AKEY_7,
/* 56*/		AKEY_8,					AKEY_9,					AKEY_NONE,				AKEY_NONE,
/* 60*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 64*/		AKEY_NONE,				AKEY_a,					AKEY_b,					AKEY_c,
/* 68*/		AKEY_d,					AKEY_e,					AKEY_f,					AKEY_g,
/* 72*/		AKEY_h,					AKEY_i,					AKEY_j,					AKEY_k,
/* 76*/		AKEY_l,					AKEY_m,					AKEY_n,					AKEY_o,
/* 80*/		AKEY_p,					AKEY_q,					AKEY_r,					AKEY_s,
/* 84*/		AKEY_t,					AKEY_u,					AKEY_v,					AKEY_w,
/* 88*/		AKEY_x,					AKEY_y,					AKEY_z,					AKEY_ATARI,
/* 92*/		AKEY_ATARI,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 96*/		AKEY_0,					AKEY_1,					AKEY_2,					AKEY_3,
/*100*/		AKEY_4,					AKEY_5,					AKEY_6,					AKEY_7,
/*104*/		AKEY_8,					AKEY_9,					AKEY_ASTERISK,			AKEY_PLUS,
/*108*/		AKEY_NONE,				AKEY_MINUS,				AKEY_FULLSTOP,			AKEY_SLASH,
/*112*/		AKEY_NONE,				AKEY_OPTIONDWN,			AKEY_SELECTDWN,			AKEY_STARTDWN,
/*116*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*120*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*124*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*128*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*132*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*136*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*140*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*144*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*148*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*152*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*156*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*160*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*164*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*168*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*172*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*176*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*180*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*184*/		AKEY_NONE,				AKEY_NONE,				AKEY_SEMICOLON,			AKEY_EQUAL,
/*188*/		AKEY_COMMA,				AKEY_MINUS,				AKEY_FULLSTOP,			AKEY_SLASH,
/*192*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*196*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*200*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*204*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*208*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*212*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*216*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BRACKETLEFT,
/*220*/		AKEY_BACKSLASH,			AKEY_BRACKETRIGHT,		AKEY_QUOTE,				AKEY_NONE,
/*224*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*228*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*232*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*236*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*240*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*244*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*248*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*252*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE
};

int g_anShftKeys[ KEYBOARD_TABLE_SIZE ] =
{
/*  0*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BREAK|SHFT,		
/*  4*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*  8*/		AKEY_DELETE_CHAR,		AKEY_SETTAB,			AKEY_NONE,				AKEY_NONE,
/* 12*/		AKEY_CLEAR,				AKEY_RETURN|SHFT,		AKEY_NONE,				AKEY_NONE,
/* 16*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BREAK,
/* 20*/		AKEY_CAPSTOGGLE|SHFT,	AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 24*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_ESCAPE|SHFT,
/* 28*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 32*/		AKEY_SPACE|SHFT,		AKEY_CAPSLOCK,			AKEY_HELP|SHFT|SPECIAL,	AKEY_ATARI|SHFT,
/* 36*/		AKEY_CLEAR,				AKEY_LEFT,				AKEY_UP,				AKEY_RIGHT,
/* 40*/		AKEY_DOWN,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 44*/		AKEY_NONE,				AKEY_INSERT_LINE,		AKEY_DELETE_LINE,		AKEY_HELP|SHFT|SPECIAL,
/* 48*/		AKEY_0|SHFT,			AKEY_1|SHFT,			AKEY_AT,				AKEY_3|SHFT,
/* 52*/		AKEY_4|SHFT,			AKEY_5|SHFT,			AKEY_CARET,				AKEY_AMPERSAND,
/* 56*/		AKEY_ASTERISK,			AKEY_9|SHFT,			AKEY_NONE,				AKEY_NONE,
/* 60*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 64*/		AKEY_NONE,				AKEY_A,					AKEY_B,					AKEY_C,
/* 68*/		AKEY_D,					AKEY_E,					AKEY_F,					AKEY_G,
/* 72*/		AKEY_H,					AKEY_I,					AKEY_J,					AKEY_K,
/* 76*/		AKEY_L,					AKEY_M,					AKEY_N,					AKEY_O,
/* 80*/		AKEY_P,					AKEY_Q,					AKEY_R,					AKEY_S,
/* 84*/		AKEY_T,					AKEY_U,					AKEY_V,					AKEY_W,
/* 88*/		AKEY_X,					AKEY_Y,					AKEY_Z,					AKEY_ATARI|SHFT,
/* 92*/		AKEY_ATARI|SHFT,		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 96*/		AKEY_0,					AKEY_1,					AKEY_2,					AKEY_3,
/*100*/		AKEY_4,					AKEY_5,					AKEY_6,					AKEY_7,
/*104*/		AKEY_8,					AKEY_9,					AKEY_ASTERISK,			AKEY_PLUS,
/*108*/		AKEY_NONE,				AKEY_MINUS,				AKEY_GREATER,			AKEY_SLASH,
/*112*/		AKEY_NONE,				AKEY_OPTIONDWN|SHFT,	AKEY_SELECTDWN|SHFT,	AKEY_STARTDWN|SHFT,
/*116*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*120*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*124*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*128*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*132*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*136*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*140*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*144*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*148*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*152*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*156*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*160*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*164*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*168*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*172*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*176*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*180*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*184*/		AKEY_NONE,				AKEY_NONE,				AKEY_COLON,				AKEY_PLUS,
/*188*/		AKEY_LESS,				AKEY_UNDERSCORE,		AKEY_GREATER,			AKEY_QUESTION,
/*192*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*196*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*200*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*204*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*208*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*212*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*216*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BRACKETLEFT,
/*220*/		AKEY_BAR,				AKEY_BRACKETRIGHT,		AKEY_DBLQUOTE,			AKEY_NONE,
/*224*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*228*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*232*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*236*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*240*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*244*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*248*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*252*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE
};

int g_anCtrlKeys[ KEYBOARD_TABLE_SIZE ] =
{
/*  0*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BREAK|CTRL,		
/*  4*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*  8*/		AKEY_BACKSPACE|CTRL,	AKEY_CLRTAB,			AKEY_NONE,				AKEY_NONE,
/* 12*/		AKEY_CLEAR,				AKEY_RETURN|CTRL,		AKEY_NONE,				AKEY_NONE,
/* 16*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_CTRL_1,
/* 20*/		AKEY_CAPSTOGGLE|CTRL,	AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 24*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_ESCAPE|CTRL,
/* 28*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 32*/		AKEY_SPACE|CTRL,		AKEY_CAPSLOCK|CTRL,		AKEY_HELP|CTRL|SPECIAL,	AKEY_ATARI|CTRL,
/* 36*/		AKEY_CLEAR,				AKEY_LEFT,				AKEY_UP,				AKEY_RIGHT,
/* 40*/		AKEY_DOWN,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 44*/		AKEY_NONE,				AKEY_INSERT_CHAR|CTRL,	AKEY_DELETE_CHAR|CTRL,	AKEY_HELP|CTRL|SPECIAL,
/* 48*/		AKEY_0|CTRL,			AKEY_1|CTRL,			AKEY_2|CTRL,			AKEY_3|CTRL,
/* 52*/		AKEY_4|CTRL,			AKEY_5|CTRL,			AKEY_6|CTRL,			AKEY_7|CTRL,
/* 56*/		AKEY_8|CTRL,			AKEY_9|CTRL,			AKEY_NONE,				AKEY_NONE,
/* 60*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 64*/		AKEY_NONE,				AKEY_CTRL_a,			AKEY_CTRL_b,			AKEY_CTRL_c,
/* 68*/		AKEY_CTRL_d,			AKEY_CTRL_e,			AKEY_CTRL_f,			AKEY_CTRL_g,
/* 72*/		AKEY_CTRL_h,			AKEY_CTRL_i,			AKEY_CTRL_j,			AKEY_CTRL_k,
/* 76*/		AKEY_CTRL_l,			AKEY_CTRL_m,			AKEY_CTRL_n,			AKEY_CTRL_o,
/* 80*/		AKEY_CTRL_p,			AKEY_CTRL_q,			AKEY_CTRL_r,			AKEY_CTRL_s,
/* 84*/		AKEY_CTRL_t,			AKEY_CTRL_u,			AKEY_CTRL_v,			AKEY_CTRL_w,
/* 88*/		AKEY_CTRL_x,			AKEY_CTRL_y,			AKEY_CTRL_z,			AKEY_ATARI|CTRL,
/* 92*/		AKEY_ATARI|CTRL,		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 96*/		AKEY_0,					AKEY_1,					AKEY_2,					AKEY_3,
/*100*/		AKEY_4,					AKEY_5,					AKEY_6,					AKEY_7,
/*104*/		AKEY_8,					AKEY_9,					AKEY_ASTERISK,			AKEY_PLUS,
/*108*/		AKEY_NONE,				AKEY_UNDERSCORE,		AKEY_FULLSTOP,			AKEY_SLASH,
/*112*/		AKEY_NONE,				AKEY_OPTIONDWN|CTRL,	AKEY_SELECTDWN|CTRL,	AKEY_STARTDWN|CTRL,
/*116*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*120*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*124*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*128*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*132*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*136*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*140*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*144*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*148*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*152*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*156*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*160*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*164*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*168*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*172*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*176*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*180*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*184*/		AKEY_NONE,				AKEY_NONE,				AKEY_SEMICOLON|CTRL,	AKEY_EQUAL|CTRL,
/*188*/		AKEY_COMMA|CTRL,		AKEY_MINUS|CTRL,		AKEY_FULLSTOP|CTRL,		AKEY_SLASH|CTRL,
/*192*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*196*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*200*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*204*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*208*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*212*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*216*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BRACKETLEFT,
/*220*/		AKEY_BACKSLASH,			AKEY_BRACKETRIGHT,		AKEY_QUOTE,				AKEY_NONE,
/*224*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*228*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*232*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*236*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*240*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*244*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*248*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*252*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE
};

/* Following keys cannot be read with both shift and control pressed:
   J K L ; + * Z X C V B F1 F2 F3 F4 HELP */
int g_anShftCtrlKeys[ KEYBOARD_TABLE_SIZE ] =
{
/*  0*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BREAK|CSFT,		
/*  4*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*  8*/		AKEY_BACKSPACE|CSFT,	AKEY_TAB|CSFT,			AKEY_NONE,				AKEY_NONE,
/* 12*/		AKEY_CLEAR|CSFT,		AKEY_RETURN|CSFT,		AKEY_NONE,				AKEY_NONE,
/* 16*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_CTRL_1,
/* 20*/		AKEY_CAPSTOGGLE|CSFT,	AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 24*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_ESCAPE,
/* 28*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 32*/		AKEY_SPACE|CSFT,		AKEY_CAPSLOCK|CSFT,		AKEY_HELP|CSFT|SPECIAL,	AKEY_ATARI,
/* 36*/		AKEY_CLEAR|CSFT,		AKEY_LEFT,				AKEY_UP,				AKEY_RIGHT,
/* 40*/		AKEY_DOWN,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 44*/		AKEY_NONE,				AKEY_INSERT_CHAR|CSFT,	AKEY_DELETE_CHAR|CSFT,	AKEY_NONE,
/* 48*/		AKEY_0|CSFT,			AKEY_1|CSFT,			AKEY_2|CSFT,			AKEY_3|CSFT,
/* 52*/		AKEY_4|CSFT,			AKEY_5|CSFT,			AKEY_6|CSFT,			AKEY_7|CSFT,
/* 56*/		AKEY_8|CSFT,			AKEY_9|CSFT,			AKEY_NONE,				AKEY_NONE,
/* 60*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 64*/		AKEY_NONE,				AKEY_a|CSFT,			AKEY_NONE,				AKEY_NONE,
/* 68*/		AKEY_d|CSFT,			AKEY_e|CSFT,			AKEY_f|CSFT,			AKEY_g|CSFT,
/* 72*/		AKEY_h|CSFT,			AKEY_i|CSFT,			AKEY_NONE,				AKEY_NONE,
/* 76*/		AKEY_NONE,				AKEY_m|CSFT,			AKEY_n|CSFT,			AKEY_o|CSFT,
/* 80*/		AKEY_p|CSFT,			AKEY_q|CSFT,			AKEY_r|CSFT,			AKEY_s|CSFT,
/* 84*/		AKEY_t|CSFT,			AKEY_u|CSFT,			AKEY_NONE,				AKEY_w|CSFT,
/* 88*/		AKEY_NONE,				AKEY_y|CSFT,			AKEY_NONE,				AKEY_ATARI,
/* 92*/		AKEY_ATARI|CSFT,		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/* 96*/		AKEY_0,					AKEY_1,					AKEY_2,					AKEY_3,
/*100*/		AKEY_4,					AKEY_5,					AKEY_6,					AKEY_7,
/*104*/		AKEY_8,					AKEY_9,					AKEY_ASTERISK,			AKEY_PLUS,
/*108*/		AKEY_NONE,				AKEY_MINUS,				AKEY_FULLSTOP,			AKEY_SLASH,
/*112*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*116*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*120*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*124*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*128*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*132*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*136*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*140*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*144*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*148*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*152*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*156*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*160*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*164*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*168*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*172*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*176*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*180*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*184*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_EQUAL|CSFT,
/*188*/		AKEY_COMMA|CSFT,		AKEY_MINUS|CSFT,		AKEY_FULLSTOP|CSFT,		AKEY_SLASH|CSFT,
/*192*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*196*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*200*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*204*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*208*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*212*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*216*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_BRACKETLEFT,
/*220*/		AKEY_BAR,				AKEY_BRACKETRIGHT,		AKEY_DBLQUOTE,			AKEY_NONE,
/*224*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*228*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*232*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*236*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*240*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*244*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*248*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE,
/*252*/		AKEY_NONE,				AKEY_NONE,				AKEY_NONE,				AKEY_NONE
};

int g_anToggleKeys[ KEYBOARD_TABLE_SIZE ] =
{
/*  0*/	0,	0,	0,	0,	0,	0,	0,	0,
/*  8*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 16*/	1,	1,	0,	0,	0,	0,	0,	0,	// Shift and Control
/* 24*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 32*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 40*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 48*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 56*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 64*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 72*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 80*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 88*/	0,	0,	0,	0,	0,	0,	0,	0,
/* 96*/	0,	0,	0,	0,	0,	0,	0,	0,
/*104*/	0,	0,	0,	0,	0,	0,	0,	0,
/*112*/	0,	1,	1,	1,	0,	0,	0,	0,	// Option, Select, Start
/*120*/	0,	0,	0,	0,	0,	0,	0,	0,
/*128*/	0,	0,	0,	0,	0,	0,	0,	0,
/*136*/	0,	0,	0,	0,	0,	0,	0,	0,
/*144*/	0,	0,	0,	0,	0,	0,	0,	0,
/*152*/	0,	0,	0,	0,	0,	0,	0,	0,
/*160*/	0,	0,	0,	0,	0,	0,	0,	0,
/*168*/	0,	0,	0,	0,	0,	0,	0,	0,
/*176*/	0,	0,	0,	0,	0,	0,	0,	0,
/*184*/	0,	0,	0,	0,	0,	0,	0,	0,
/*192*/	0,	0,	0,	0,	0,	0,	0,	0,
/*200*/	0,	0,	0,	0,	0,	0,	0,	0,
/*208*/	0,	0,	0,	0,	0,	0,	0,	0,
/*216*/	0,	0,	0,	0,	0,	0,	0,	0,
/*224*/	0,	0,	0,	0,	0,	0,	0,	0,
/*232*/	0,	0,	0,	0,	0,	0,	0,	0,
/*240*/	0,	0,	0,	0,	0,	0,	0,	0,
/*248*/	0,	0,	0,	0,	0,	0,	0,	0
};

UCHAR g_aucKeysCovered[ KEYBOARD_TABLE_SIZE ] =
{
/*  0*/	0,	0,	0,	0,	0,	0,	0,	0,	// BACKSPACE
/*  8*/	1,	1,	0,	0,	0,	1,	0,	0,	// TAB RET
/* 16*/	0,	0,	0,	0,	1,	0,	0,	0,	// CAPS LOCK
/* 24*/	0,	0,	0,	1,	0,	0,	0,	0,	// ESC SPACE
/* 32*/ 1,	0,	0,	0,	0,	1,	1,	1,	// LEFT UP RIGHT DOWN
/* 40*/	1,	0,	0,	0,	0,	0,	0,	0,	// 0
/* 48*/	1,	1,	1,	1,	1,	1,	1,	1,	// 1 2 3 4 5 6 7 8
/* 56*/	1,	1,	0,	0,	0,	0,	0,	0,	// 9 
/* 64*/	0,	1,	1,	1,	1,	1,	1,	1,	// a b c d e f g h
/* 72*/	1,	1,	1,	1,	1,	1,	1,	1,	// i j k l m n o p 
/* 80*/	1,	1,	1,	1,	1,	1,	1,	1,	// q r s t u v w x 
/* 88*/	1,	1,	1,	0,	0,	0,	0,	0,	// y z PAD0
/* 96*/	1,	1,	1,	1,	1,	1,	1,	1,	// PAD1 PAD2 PAD3 PAD4 PAD5 PAD6 PAD7 PAD8
/*104*/	1,	1,	1,	1,	0,	1,	1,	1,	// PAD9 PAD* PAD+ PAD- PAD. PAD/
/*112*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*120*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*128*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*136*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*144*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*152*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*160*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*168*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*176*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*184*/	0,	0,	1,	1,	1,	1,	1,	1, 
/*192*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*200*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*208*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*216*/	0,	0,	0,	1,	1,	1,	1,	0, 
/*224*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*232*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*240*/	0,	0,	0,	0,	0,	0,	0,	0, 
/*248*/	0,	0,	0,	0,	0,	0,	0,	0
};

/////////////////////////////////////////////////////////////////////////////
// Static objects

static const int s_anNormArrows[ 3 ][ 4 ] =
{
	{ AKEY_LEFT, AKEY_UP,    AKEY_RIGHT,    AKEY_DOWN  },
	{ AKEY_PLUS, AKEY_MINUS, AKEY_ASTERISK, AKEY_EQUAL },
	{ AKEY_F3,   AKEY_F1,    AKEY_F4,       AKEY_F2    }
};

static const int s_anShftArrows[ 3 ][ 4 ] =
{
	{ AKEY_NONE,             AKEY_SHFT | AKEY_UP,    AKEY_NONE,                 AKEY_SHFT | AKEY_DOWN  },
	{ AKEY_SHFT | AKEY_PLUS, AKEY_SHFT | AKEY_MINUS, AKEY_SHFT | AKEY_ASTERISK, AKEY_SHFT | AKEY_EQUAL },
	{ AKEY_SHFT | AKEY_F3,   AKEY_SHFT | AKEY_F1,    AKEY_SHFT | AKEY_F4,       AKEY_SHFT | AKEY_F2    }
};

static const int s_anCtrlArrows[ 3 ][ 4 ] =
{
	{ AKEY_PLUS,             AKEY_MINUS,             AKEY_ASTERISK,             AKEY_EQUAL             },
	{ AKEY_CTRL | AKEY_PLUS, AKEY_CTRL | AKEY_MINUS, AKEY_CTRL | AKEY_ASTERISK, AKEY_CTRL | AKEY_EQUAL },
	{ AKEY_CTRL | AKEY_F3,   AKEY_CTRL | AKEY_F1,    AKEY_CTRL | AKEY_F4,       AKEY_CTRL | AKEY_F2    }
};

static const int s_anShftCtrlArrows[ 3 ][ 4 ] =
{
	{ AKEY_SHFT | AKEY_PLUS, AKEY_SHFT | AKEY_MINUS, AKEY_SHFT | AKEY_ASTERISK, AKEY_SHFT | AKEY_EQUAL },
	{ AKEY_NONE,             AKEY_SHFT | AKEY_UP,    AKEY_NONE,                 AKEY_SHFT | AKEY_DOWN  },
	{ AKEY_NONE,             AKEY_NONE,              AKEY_NONE,                 AKEY_NONE              }
};

static int s_anKBTable[ KEYBOARD_TABLE_SIZE ];


/////////////////////////////////////////////////////////////////////////////
// CKeyboardDlg dialog

BEGIN_MESSAGE_MAP(CKeyboardDlg, CCommonDlg)
	//{{AFX_MSG_MAP(CKeyboardDlg)
	ON_CBN_SELCHANGE(IDC_KEYBOARD_ARROWKEYS, OnSelchangeArrowKeys)
	ON_BN_CLICKED(IDC_KEYBOARD_TYPEMATICRATE, OnTypematicRate)
	ON_BN_CLICKED(IDC_KEYBOARD_CAPTURECTRLESC, OnCaptureCtrlEsc)
	ON_BN_CLICKED(IDC_KEYBOARD_EDITTEMPLATE, OnEditTemplate)
	ON_BN_CLICKED(IDC_KEYBOARD_LOADTEMPLATE, OnLoadTemplate)
	ON_BN_CLICKED(IDC_KEYBOARD_USETEMPLATE, OnUseTemplate)
	ON_EN_KILLFOCUS(IDC_KEYBOARD_TEMPLATEFILE, OnKillfocusTemplateFile)
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_KEYBOARD_CANCEL, OnCancel)
	ON_BN_CLICKED(IDC_KEYBOARD_OK, OnOK)
END_MESSAGE_MAP()

/*========================================================
Method   : CKeyboardDlg::CKeyboardDlg
=========================================================*/
/* #FN#
   Standard constructor */
CKeyboardDlg::
CKeyboardDlg(
	CWnd *pParent /*=NULL*/ /* #IN# Pointer to the parent window */
)
	: CCommonDlg( CKeyboardDlg::IDD, pParent )
{
	//{{AFX_DATA_INIT(CKeyboardDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT

	m_bExitPass  = FALSE;
	m_nFirstCtrl = IDC_KEYBOARD_FIRST;
	m_nLastCtrl  = IDC_KEYBOARD_LAST;
} /* #OF# CKeyboardDlg::CKeyboardDlg */

/*========================================================
Method   : CKeyboardDlg::DoDataExchange
=========================================================*/
/* #FN#
   Dynamic Data Exchange (not used) */
void
/* #AS#
   Nothing */
CKeyboardDlg::
DoDataExchange(
	CDataExchange *pDX /* #IN# Pointer to CDataExchange object */
)
{
	CCommonDlg::DoDataExchange( pDX );
	//{{AFX_DATA_MAP(CKeyboardDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
} /* #OF# CKeyboardDlg::DoDataExchange */


/////////////////////////////////////////////////////////////////////////////
// CKeyboardDlg implementation

/*========================================================
Method   : CKeyboardDlg::SetArrowKeys
=========================================================*/
/* #FN#
   Sets the PC arrows key working mode */
void
/* #AS#
   Nothing */
CKeyboardDlg::
SetArrowKeys(
	int nMode /* #IN# Code of the requested working mode */
)
{
	for( int i = 0; i < 4; i++ )
	{
		g_anNormKeys    [ 37 + i ] = s_anNormArrows    [ nMode ][ i ];
		g_anShftKeys    [ 37 + i ] = s_anShftArrows    [ nMode ][ i ];
		g_anCtrlKeys    [ 37 + i ] = s_anCtrlArrows    [ nMode ][ i ];
		g_anShftCtrlKeys[ 37 + i ] = s_anShftCtrlArrows[ nMode ][ i ];
	}
} /* #OF# CKeyboardDlg::SetArrowKeys */

/*========================================================
Method   : CKeyboardDlg::PrepareTemplate
=========================================================*/
/* #FN#
   Reads a keyboard template from a given file */
BOOL
/* #AS#
   TRUE if succeeded, otherwise FALSE */
CKeyboardDlg::
PrepareTemplate(
	LPSTR pszTemplateFile,
	LPSTR pszTemplateDesc,
	BOOL  bCheckIfExists /*=TRUE*/
)
{
	BOOL bResult = FALSE;

	if( _IsPathAvailable( pszTemplateFile ) )
	{
		CFileStatus fsStatus;

		if( !bCheckIfExists || CFile::GetStatus( pszTemplateFile, fsStatus ) )
		{
			if( !CKeyTemplateDlg::ReadKeyTemplate( pszTemplateFile, pszTemplateDesc, s_anKBTable, GetSafeHwnd() ) )
			{
				DisplayMessage( GetSafeHwnd(), IDS_ERROR_A8K_LOAD, 0, MB_ICONEXCLAMATION | MB_OK );
				strcpy( pszTemplateFile, "None" );
			}
			else
				bResult = TRUE;
		}
	}
	/* Clear the template description */
	if( !bResult )
		*pszTemplateDesc = '\0';

	return bResult;
} /* #OF# CKeyboardDlg::PrepareTemplate */

/*========================================================
Method   : CKeyboardDlg::SetDlgState
=========================================================*/
/* #FN#
   Sets up the state of the dialog controls */
void
/* #AS#
   Nothing */
CKeyboardDlg::
SetDlgState()
{
	CComboBox  *pCombo  = (CComboBox *)GetDlgItem( IDC_KEYBOARD_ARROWKEYS );
	CButton    *pButton = NULL;
	CFileStatus fsStatus;

	/* Check if there is the pointed template file */
	BOOL bTemplate = _IsPathAvailable( m_szTemplateFile ) &&
					 CFile::GetStatus( m_szTemplateFile, fsStatus );

	if( !bTemplate )
		/* Clear "Use keyboard template" flag if there is no file */
		m_ulInputState &= ~IS_KEY_USE_TEMPLATE;

	/* Arrow keys mode */
	ASSERT(pCombo);
	if( CB_ERR == pCombo->SetCurSel( m_nArrowsMode ) )
		pCombo->SetCurSel( 0 );

	/* Under Win 9x the Ctrl+Esc keystroke capturing may be turn off only in
	   windowed modes. This feature is always enabled for full-screen modes */
	pButton = (CButton *)GetDlgItem( IDC_KEYBOARD_CAPTURECTRLESC );
	ASSERT(pButton);
	pButton->EnableWindow( g_Screen.ulState & SM_MODE_WIND || g_Misc.unSystemInfo & SYS_WIN_NT );

	if( ST_CTRLESC_CAPTURED )
		pButton->SetCheck( 1 );

	pButton = (CButton *)GetDlgItem( IDC_KEYBOARD_TYPEMATICRATE );
	ASSERT(pButton);
	pButton->SetCheck( (m_ulInputState & IS_KEY_TYPEMATIC_RATE) != 0 );
	
	pButton = (CButton *)GetDlgItem( IDC_KEYBOARD_USETEMPLATE );
	ASSERT(pButton);
	pButton->SetCheck( (m_ulInputState & IS_KEY_USE_TEMPLATE) != 0 );
	pButton->EnableWindow( bTemplate );

	pButton = (CButton *)GetDlgItem( IDC_KEYBOARD_EDITTEMPLATE );
	ASSERT(pButton);
	pButton->EnableWindow( bTemplate );

	SetDlgItemText( IDC_KEYBOARD_TEMPLATEFILE, m_szTemplateFile );
	SetDlgItemText( IDC_KEYBOARD_TEMPLATEDESC, m_szTemplateDesc );
} /* #OF# CKeyboardDlg::SetDlgState */


/////////////////////////////////////////////////////////////////////////////
// CKeyboardDlg message handlers

/*========================================================
Method   : CKeyboardDlg::OnInitDialog
=========================================================*/
/* #FN#
   Performs special processing when the dialog box is initialized */
BOOL
/* #AS#
   TRUE unless you set the focus to a control */
CKeyboardDlg::
OnInitDialog() 
{
	CCommonDlg::OnInitDialog();

	m_ulInputState = g_Input.ulState;
	m_nArrowsMode  = g_Input.Key.nArrowsMode;

	strncpy( m_szTemplateFile, g_szTemplateFile, MAX_PATH );
	strncpy( m_szTemplateDesc, g_szTemplateDesc, TEMPLATE_DESC_LENGTH );

	/* Read the template from a file */
	PrepareTemplate( m_szTemplateFile, m_szTemplateDesc );

	SetDlgState();

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
} /* #OF# CKeyboardDlg::OnInitDialog */

/*========================================================
Method   : CKeyboardDlg::OnSelchangeArrowKeys
=========================================================*/
/* #FN#
   Sets a state of the object regarding to an appropriate combo box */
void
/* #AS#
   Nothing */
CKeyboardDlg::
OnSelchangeArrowKeys()
{
	CComboBox *pCombo = (CComboBox *)GetDlgItem( IDC_KEYBOARD_ARROWKEYS );
	ASSERT(pCombo != NULL);
	m_nArrowsMode = pCombo->GetCurSel();
} /* #OF# CKeyboardDlg::OnSelchangeArrowKeys */

/*========================================================
Method   : CKeyboardDlg::OnTypematicRate
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CKeyboardDlg::
OnTypematicRate()
{
	_ClickButton( IDC_KEYBOARD_TYPEMATICRATE, m_ulInputState, IS_KEY_TYPEMATIC_RATE );
} /* #OF# CKeyboardDlg::OnTypematicRate */

/*========================================================
Method   : CKeyboardDlg::OnCaptureCtrlEsc
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CKeyboardDlg::
OnCaptureCtrlEsc()
{
	_ClickButton( IDC_KEYBOARD_CAPTURECTRLESC, m_ulInputState, IS_CAPTURE_CTRLESC );
} /* #OF# CKeyboardDlg::OnCaptureCtrlEsc */

/*========================================================
Method   : CKeyboardDlg::OnKillfocusTemplateFile
=========================================================*/
/* #FN#
   The framework calls this function before an edit losing input focus */
void
/* #AS#
   Nothing */
CKeyboardDlg::
OnKillfocusTemplateFile()
{
	char szTemplateOld[ MAX_PATH ];

	strcpy( szTemplateOld, m_szTemplateFile );
	GetDlgItemText( IDC_KEYBOARD_TEMPLATEFILE, m_szTemplateFile, MAX_PATH );

	if( !m_bExitPass &&
		_stricmp( szTemplateOld, m_szTemplateFile ) != 0 )
	{
		/* Read the template from a file */
		PrepareTemplate( m_szTemplateFile, m_szTemplateDesc );
		/* Set the dialog controls */
		SetDlgState();
	}
} /* #OF# CKeyboardDlg::OnKillfocusTemplateFile */

/*========================================================
Method   : CKeyboardDlg::OnLoadTemplate
=========================================================*/
/* #FN#
   Allows selecting a keyboard template using FileDialog window */
void
/* #AS#
   Nothing */
CKeyboardDlg::
OnLoadTemplate()
{
	char szTemplateOld[ MAX_PATH ];

	strcpy( szTemplateOld, m_szTemplateFile );

	if( PickFileName( TRUE, m_szTemplateFile, IDS_SELECT_A8K_LOAD, IDS_FILTER_A8K,
					  "a8k", PF_LOAD_FLAGS, FALSE, "None", this ) &&
		*m_szTemplateFile != '\0' )
	{
		/* Read the template from a file */
		PrepareTemplate( m_szTemplateFile, m_szTemplateDesc, FALSE );
		/* Set the dialog controls */
		SetDlgState();
	}
} /* #OF# CKeyboardDlg::OnLoadTemplate */

/*========================================================
Method   : CKeyboardDlg::OnEditTemplate
=========================================================*/
/* #FN#
   Displays "Keyboard Template" dialog box */
void
/* #AS#
   Nothing */
CKeyboardDlg::
OnEditTemplate()
{
	CKeyTemplateDlg dlgKeyTemplate( m_szTemplateFile, m_szTemplateDesc, s_anKBTable, this );

	dlgKeyTemplate.DoModal();

	/* Read the template from a file */
	PrepareTemplate( m_szTemplateFile, m_szTemplateDesc );
	/* Set the dialog controls */
	SetDlgState();
} /* #OF# CKeyboardDlg::OnEditTemplate */

/*========================================================
Method   : CKeyboardDlg::OnUseTemplate
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CKeyboardDlg::
OnUseTemplate()
{
	_ClickButton( IDC_KEYBOARD_USETEMPLATE, m_ulInputState, IS_KEY_USE_TEMPLATE );
	/* Read the template from a file */
	if( m_ulInputState & IS_KEY_USE_TEMPLATE )
	{
		PrepareTemplate( m_szTemplateFile, m_szTemplateDesc );
	}
	/* Set the dialog controls */
	SetDlgState();
} /* #OF# CKeyboardDlg::OnUseTemplate */

/*========================================================
Method   : CKeyboardDlg::ReceiveFocused
=========================================================*/
/* #FN#
   Receive the edit controls content again. The user could press
   'Enter' or 'Alt-O' and then all changes he's made in the last
   edited control would be lost. */
void
/* #AS#
   Nothing */
CKeyboardDlg::
ReceiveFocused()
{
	CWnd *pWnd    = GetFocus();
	UINT  nCtrlID = pWnd ? pWnd->GetDlgCtrlID() : 0;

	if( IDC_KEYBOARD_TEMPLATEFILE == nCtrlID )
	{
		OnKillfocusTemplateFile();
	}
} /* #OF# CKeyboardDlg::ReceiveFocused */

/*========================================================
Method   : CKeyboardDlg::OnOK
=========================================================*/
/* #FN#
   Called when the user clicks the OK button */
void
/* #AS#
   Nothing */
CKeyboardDlg::
OnOK() 
{
	/* There is a problem with messages routing when the dialog is
	   closed with Enter/Alt-O key. KILLFOCUS message arrives
       to late and we have to invoke KillFocus handlers in OnOK
       method by ourselves. That's why we use this member. */
	m_bExitPass = TRUE;

	/* Unfortunately, edit controls do not lose the focus before
	   handling this when the user uses accelerators */
	ReceiveFocused();

	if( m_nArrowsMode != g_Input.Key.nArrowsMode )
	{
		g_Input.Key.nArrowsMode = m_nArrowsMode;
		WriteRegDWORD( NULL, REG_ARROWS_MODE, g_Input.Key.nArrowsMode );

		SetArrowKeys( g_Input.Key.nArrowsMode );
	}
	/* Always reload the selected template */
	if( !PrepareTemplate( m_szTemplateFile, m_szTemplateDesc ) )
	{
		if( m_ulInputState & IS_KEY_USE_TEMPLATE )
		{
			m_ulInputState &= ~IS_KEY_USE_TEMPLATE;
			DisplayMessage( GetSafeHwnd(), IDS_ERROR_NO_KEYTEMP, 0, MB_ICONEXCLAMATION | MB_OK, m_szTemplateFile );
		}
	}
	else
		/* Fill the template table */
		CopyMemory( g_anKBTable, s_anKBTable, KEYBOARD_TABLE_SIZE * sizeof(int) );

	if( _stricmp( g_szTemplateDesc, m_szTemplateDesc ) != 0 )
		strcpy( g_szTemplateDesc, m_szTemplateDesc );

	/* Windows NT doesn't like empty strings in Registry */
	if( *m_szTemplateFile == '\0' )
		strcpy( m_szTemplateFile, DEFAULT_A8K );

	if( _stricmp( g_szTemplateFile, m_szTemplateFile ) != 0 )
	{
		strcpy( g_szTemplateFile, m_szTemplateFile );
		WriteRegString( NULL, REG_FILE_TEMPLATE, g_szTemplateFile );
	}
	/* Check the miscellanous states */
	if( m_ulInputState != g_Input.ulState )
	{
		if( g_Input.ulState & IS_CAPTURE_CTRLESC ^
			m_ulInputState & IS_CAPTURE_CTRLESC )
		{
			Input_EnableEscCapture( m_ulInputState & IS_CAPTURE_CTRLESC );
		}
		g_Input.ulState = m_ulInputState;
		WriteRegDWORD( NULL, REG_INPUT_STATE, g_Input.ulState);
	}
	CCommonDlg::OnOK();
} /* #OF# CKeyboardDlg::OnOK */
