#include "precomp.h"
#define KEYEVENT InputRecord[i].Event.KeyEvent
#define KEYEVENT_CHAR KEYEVENT.uChar.AsciiChar
#define KEYEVENT_PCHAR &KEYEVENT_CHAR
inline void DoEcho(const char *p, int l, TConsole &Console,
TNetwork &Network, NetParams *pParams) {
if(Network.get_local_echo()) {
ResetEvent(pParams->hUnPause);
SetEvent(pParams->hPause);
while (!*pParams->bNetPaused);
Console.WriteCtrlString(p, l);
SetEvent(pParams->hUnPause);
}
}
static char buffer[1024];
static unsigned int bufptr = 0;
inline bool DoLineModeSpecial(char keychar, TConsole &Console, TNetwork &Network,
NetParams *pParams) {
if(keychar == VK_BACK) {
if(bufptr) bufptr--;
DoEcho("\b \b", 3, Console, Network, pParams);
return true;
} else if(keychar == VK_RETURN) {
Network.WriteString(buffer, bufptr);
Network.WriteString("\012", 1);
DoEcho("\r\n", 2, Console, Network, pParams);
bufptr = 0;
return true;
}
return false;
}
inline void DoLineMode(const char *p, int p_len, TConsole &Console,
TNetwork &Network) {
if(Network.get_line_mode()) {
if(bufptr < sizeof(buffer) + p_len - 1) {
memcpy(buffer + bufptr, p, p_len);
bufptr += p_len;
} else {
Console.Beep();
}
} else {
Network.WriteString(p, p_len);
}
}
const char *ClosestStateKey(WORD keyCode, DWORD keyState,
KeyTranslator &KeyTrans) {
char const *p;
if((p = KeyTrans.TranslateKey(keyCode, keyState))) return p;
if((p = KeyTrans.TranslateKey(keyCode, keyState & ~NUMLOCK_ON))) return p;
if((p = KeyTrans.TranslateKey(keyCode, keyState & ~ENHANCED_KEY
& ~NUMLOCK_ON))) return p;
if((p = KeyTrans.TranslateKey(keyCode, keyState & ~SCROLLLOCK_ON))) return p;
if((p = KeyTrans.TranslateKey(keyCode, keyState & ~ENHANCED_KEY
& ~SCROLLLOCK_ON))) return p;
if((p = KeyTrans.TranslateKey(keyCode, keyState & ~ENHANCED_KEY))) return p;
if((p = KeyTrans.TranslateKey(keyCode, keyState & ~CAPSLOCK_ON))) return p;
if((p = KeyTrans.TranslateKey(keyCode, keyState & ~ENHANCED_KEY
& ~CAPSLOCK_ON))) return p;
return 0;
}
const char *FindClosestKey(WORD keyCode, DWORD keyState,
KeyTranslator &KeyTrans) {
char const *p;
if(ini.get_alt_erase()) {
if(keyCode == VK_BACK) {
keyCode = VK_DELETE;
keyState |= ENHANCED_KEY;
} else if(keyCode == VK_DELETE && (keyState & ENHANCED_KEY)) {
keyCode = VK_BACK;
keyState &= ~ENHANCED_KEY;
}
}
DWORD ext_mode = KeyTrans.get_ext_mode();
if(ext_mode) {
for(DWORD j = ext_mode; j >= APP_KEY; j -= APP_KEY) {
if((j | ext_mode) == ext_mode) {
if((p = ClosestStateKey(keyCode, keyState | j,
KeyTrans))) return p;
}
}
}
return ClosestStateKey(keyCode, keyState, KeyTrans);
}
int do_op(tn_ops op, TNetwork &Network, Tnclip &Clipboard) {
switch(op) {
case TN_ESCAPE:
return TNPROMPT;
case TN_SCROLLBACK:
return TNSCROLLBACK;
case TN_DIAL:
return TNSPAWN;
case TN_PASTE:
if(ini.get_keyboard_paste()) Clipboard.Paste();
else return 0;
break;
case TN_NULL:
Network.WriteString("", 1);
return 0;
case TN_CR:
Network.WriteString("\r", 2);
return 0;
case TN_CRLF:
Network.WriteString("\r\n", 2);
return 0;
}
return 0;
}
int telProcessConsole(NetParams *pParams, KeyTranslator &KeyTrans,
TConsole &Console, TNetwork &Network, TMouse &Mouse,
Tnclip &Clipboard, HANDLE hThread)
{
KeyDefType_const keydef;
const char *p;
int p_len;
unsigned int i;
int opval;
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleMode(hConsole, ini.get_enable_mouse() ? ENABLE_MOUSE_INPUT : 0);
const DWORD nHandle = 2;
HANDLE hHandle[nHandle] = {hConsole, pParams->hExit};
for (;;) {
DWORD dwInput;
switch (WaitForMultipleObjects(nHandle, hHandle, FALSE, INFINITE)) {
case WAIT_OBJECT_0: {
if(ini.get_input_redir()) {
char InputBuffer[10];
int bResult;
bResult = ReadFile(hConsole, InputBuffer, 10, &dwInput, 0);
if(bResult && dwInput == 0) return TNNOCON;
Network.WriteString(InputBuffer, dwInput);
break;
}
INPUT_RECORD InputRecord[11];
if (!ReadConsoleInput(hConsole, &InputRecord[0], 10, &dwInput))
return TNPROMPT;
for (i = 0; (unsigned)i < dwInput; i++){
switch (InputRecord[i].EventType) {
case KEY_EVENT:{
if (KEYEVENT.bKeyDown) {
WORD keyCode = KEYEVENT.wVirtualKeyCode;
DWORD keyState = KEYEVENT.dwControlKeyState;
keydef.szKeyDef = FindClosestKey(keyCode,
keyState, KeyTrans);
if(keydef.szKeyDef) {
if(!keydef.op->sendstr)
if((opval = do_op(keydef.op->the_op, Network,
Clipboard)) != 0)
return opval;
}
if(Network.get_line_mode()) {
if(DoLineModeSpecial(KEYEVENT_CHAR, Console, Network, pParams))
continue;
}
p = keydef.szKeyDef;
if (p == NULL) {
if(!KEYEVENT_CHAR) continue;
p_len = 1;
p = KEYEVENT_PCHAR;
} else {
p_len = strlen(p);
}
DoEcho(p, p_len, Console, Network, pParams);
DoLineMode(p, p_len, Console, Network);
}
}
break;
case MOUSE_EVENT:
if(!InputRecord[i].Event.MouseEvent.dwEventFlags) {
ResetEvent(pParams->hUnPause);
SetEvent(pParams->hPause);
while (!*pParams->bNetPaused);
DWORD Result;
WriteConsoleInput(hConsole, &InputRecord[i], 1,
&Result);
Mouse.doMouse();
SetEvent(pParams->hUnPause);
}
break;
case FOCUS_EVENT:
break;
case WINDOW_BUFFER_SIZE_EVENT:
Console.sync();
Network.do_naws(Console.GetWidth(), Console.GetHeight());
break;
}
}
break;
}
default:
return TNNOCON;
}
}
}
WORD scrollkeys() {
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD InputRecord;
BOOL done = FALSE;
while (!done) {
DWORD dwInput;
WaitForSingleObject( hConsole, INFINITE );
if (!ReadConsoleInput(hConsole, &InputRecord, 1, &dwInput)){
done = TRUE;
continue;
}
if (InputRecord.EventType == KEY_EVENT &&
InputRecord.Event.KeyEvent.bKeyDown ) {
return InputRecord.Event.KeyEvent.wVirtualKeyCode;
} else if(InputRecord.EventType == MOUSE_EVENT) {
if(!InputRecord.Event.MouseEvent.dwEventFlags) {
WriteConsoleInput(hConsole, &InputRecord, 1, &dwInput);
return SC_MOUSE;
}
}
}
return SC_ESC;
}
static TNetwork net;
void setTNetwork(TNetwork tnet) {
net = tnet;
}
BOOL WINAPI ControlEventHandler(DWORD event) {
switch(event) {
case CTRL_BREAK_EVENT:
if(ini.get_control_break_as_c()) net.WriteString("\x3",1);
return TRUE;
default:
return FALSE;
}
}