summaryrefslogtreecommitdiff
path: root/tvision/classes/win32/win32key.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tvision/classes/win32/win32key.cc')
-rw-r--r--tvision/classes/win32/win32key.cc464
1 files changed, 464 insertions, 0 deletions
diff --git a/tvision/classes/win32/win32key.cc b/tvision/classes/win32/win32key.cc
new file mode 100644
index 0000000..f467d70
--- /dev/null
+++ b/tvision/classes/win32/win32key.cc
@@ -0,0 +1,464 @@
+/**[txh]********************************************************************
+
+ Copyright (c) 2002 by Salvador E. Tropea (SET)
+ It said:
+ Keyboard handler for Win32 by Vadim Beloborodov
+ Based on code by Salvador E. Tropea (SET) (c) (1998)
+
+ Description:
+ Win32 Keyboard routines.
+ The original implementation was done by Vadim, I removed some code, added
+some routines and adapted it to the new architecture.
+ One important detail is that Vadim implemented it with threads. So we have
+here an events handler with a queue.
+
+***************************************************************************/
+
+#include <tv/configtv.h>
+
+#define Uses_string
+#define Uses_TEvent
+#define Uses_TGKey
+#define Uses_TKeys
+#define Uses_TKeys_Extended
+#define Uses_ctype
+#define Uses_TDisplay
+#define Uses_TScreen
+#include <tv.h>
+
+// I delay the check to generate as much dependencies as possible
+#ifdef TVOS_Win32
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <tv/win32/screen.h>
+#include <tv/win32/key.h>
+
+KeyDownEvent *TGKeyWin32::evKeyboardIn;
+KeyDownEvent *TGKeyWin32::evKeyboardOut;
+KeyDownEvent TGKeyWin32::evKeyboardQueue[eventKeyboardQSize];
+unsigned TGKeyWin32::evKeyboardLength;
+CRITICAL_SECTION TGKeyWin32::lockKeyboard;
+ushort TGKeyWin32::LastControlKeyState=0;
+
+void TGKeyWin32::Init()
+{
+ TGKey::kbhit=KbHit;
+ TGKey::getShiftState=GetShiftState;
+ TGKey::fillTEvent=FillTEvent;
+
+ InitializeCriticalSection(&lockKeyboard);
+ evKeyboardLength=0;
+ evKeyboardIn=evKeyboardOut=&evKeyboardQueue[0];
+}
+
+void TGKeyWin32::DeInit()
+{
+ DeleteCriticalSection(&lockKeyboard);
+}
+
+int TGKeyWin32::KbHit(void)
+{
+ return evKeyboardLength>0;
+}
+
+void TGKeyWin32::FillTEvent(TEvent &e)
+{
+ getConsoleKeyboardEvent(e.keyDown);
+ e.what=evKeyDown;
+}
+
+ushort TGKeyWin32::transShiftState(DWORD state)
+{
+ ushort tvstate=0;
+ if (state & (RIGHT_ALT_PRESSED |LEFT_ALT_PRESSED) ) tvstate|=kbAltShift;
+ if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED)) tvstate|=kbCtrlShift;
+ if (state & SHIFT_PRESSED) tvstate|=kbLeftShift;
+ if (state & NUMLOCK_ON ) tvstate|=kbNumState;
+ if (state & SCROLLLOCK_ON) tvstate|=kbScrollState;
+ if (state & CAPSLOCK_ON ) tvstate|=kbCapsState;
+
+ return tvstate;
+}
+
+/*
+ Translate keyboard events to Salvador E. Tropea's key codes
+ by Vadim Beloborodov
+ Originally in trans.cc
+*/
+
+const char TGKeyWin32::KeyTo[256]=
+{
+ /* 00 */ 0,
+ /* 01 VK_LBUTTON */ 0,
+ /* 02 VK_RBUTTON */ 0,
+ /* 03 VK_CANCEL */ 0,
+ /* 04 VK_MBUTTON */ 0,
+ /* 05 unassigned */ 0,
+ /* 06 unassigned */ 0,
+ /* 07 unassigned */ 0,
+ /* 08 VK_BACK */ kbBackSpace,
+ /* 09 VK_TAB */ kbTab,
+ /* 0A unassigned */ 0,
+ /* 0B unassigned */ 0,
+ /* 0C VK_CLEAR ?? */ 0,
+ /* 0D VK_RETURN */ kbEnter,
+ /* 0E unassigned */ 0,
+ /* 0F unassigned */ 0,
+ /* 10 VK_SHIFT */ 0,
+ /* 11 VK_CONTROL */ 0,
+ /* 12 VK_MENU */ 0,
+ /* 13 VK_PAUSE */ 0,
+ /* 14 VK_CAPITAL */ 0,
+ /* 15 Kanji systems*/ 0,
+ /* 16 Kanji systems*/ 0,
+ /* 17 Kanji systems*/ 0,
+ /* 18 Kanji systems*/ 0,
+ /* 19 Kanji systems*/ 0,
+ /* 1A unassigned */ 0,
+ /* 1B VK_ESCAPE */ kbEsc,
+ /* 1C Kanji systems*/ 0,
+ /* 1D Kanji systems*/ 0,
+ /* 1E Kanji systems*/ 0,
+ /* 1F Kanji systems*/ 0,
+ /* 20 VK_SPACE */ kbSpace,
+ /* 21 VK_PRIOR */ kbPgUp,
+ /* 22 VK_NEXT */ kbPgDn,
+ /* 23 VK_END */ kbEnd,
+ /* 24 VK_HOME */ kbHome,
+ /* 25 VK_LEFT */ kbLeft,
+ /* 26 VK_UP */ kbUp,
+ /* 27 VK_RIGHT */ kbRight,
+ /* 28 VK_DOWN */ kbDown,
+ /* 29 VK_SELECT */ 0,
+ /* 2A OEM specific */ 0,
+ /* 2B VK_EXECUTE */ 0,
+ /* 2C VK_SNAPSHOT */ 0,
+ /* 2D VK_INSERT */ kbInsert,
+ /* 2E VK_DELETE */ kbDelete,
+ /* 2F VK_HELP */ 0,
+ /* 30 VK_0 '0' */ kb0,
+ /* 31 VK_1 '1' */ kb1,
+ /* 32 VK_2 '2' */ kb2,
+ /* 33 VK_3 '3' */ kb3,
+ /* 34 VK_4 '4' */ kb4,
+ /* 35 VK_5 '5' */ kb5,
+ /* 36 VK_6 '6' */ kb6,
+ /* 37 VK_7 '7' */ kb7,
+ /* 38 VK_8 '8' */ kb8,
+ /* 39 VK_9 '9' */ kb9,
+ /* 3A unassigned */ 0,
+ /* 3B unassigned */ 0,
+ /* 3C unassigned */ 0,
+ /* 3D unassigned */ 0,
+ /* 3E unassigned */ 0,
+ /* 3F unassigned */ 0,
+ /* 40 unassigned */ 0,
+ /* 41 VK_A 'A' */ kbA,
+ /* 42 VK_B 'B' */ kbB,
+ /* 43 VK_C 'C' */ kbC,
+ /* 44 VK_D 'D' */ kbD,
+ /* 45 VK_E 'E' */ kbE,
+ /* 46 VK_F 'F' */ kbF,
+ /* 47 VK_G 'G' */ kbG,
+ /* 48 VK_H 'H' */ kbH,
+ /* 49 VK_I 'I' */ kbI,
+ /* 4A VK_J 'J' */ kbJ,
+ /* 4B VK_K 'K' */ kbK,
+ /* 4C VK_L 'L' */ kbL,
+ /* 4D VK_M 'M' */ kbM,
+ /* 4E VK_N 'N' */ kbN,
+ /* 4F VK_O 'O' */ kbO,
+ /* 50 VK_P 'P' */ kbP,
+ /* 51 VK_Q 'Q' */ kbQ,
+ /* 52 VK_R 'R' */ kbR,
+ /* 53 VK_S 'S' */ kbS,
+ /* 54 VK_T 'T' */ kbT,
+ /* 55 VK_U 'U' */ kbU,
+ /* 56 VK_V 'V' */ kbV,
+ /* 57 VK_W 'W' */ kbW,
+ /* 58 VK_X 'X' */ kbX,
+ /* 59 VK_Y 'Y' */ kbY,
+ /* 5A VK_Z 'Z' */ kbZ,
+ /* 5B unassigned */ 0,
+ /* 5C unassigned */ 0,
+ /* 5D unassigned */ 0,
+ /* 5E unassigned */ 0,
+ /* 5F unassigned */ 0,
+ /* 60 VK_NUMPAD0 NumKeyPad '0' */ kb0,
+ /* 61 VK_NUMPAD1 NumKeyPad '1' */ kb1,
+ /* 62 VK_NUMPAD2 NumKeyPad '2' */ kb2,
+ /* 63 VK_NUMPAD3 NumKeyPad '3' */ kb3,
+ /* 64 VK_NUMPAD4 NumKeyPad '4' */ kb4,
+ /* 65 VK_NUMPAD5 NumKeyPad '5' */ kb5,
+ /* 66 VK_NUMPAD6 NumKeyPad '6' */ kb6,
+ /* 67 VK_NUMPAD7 NumKeyPad '7' */ kb7,
+ /* 68 VK_NUMPAD8 NumKeyPad '8' */ kb8,
+ /* 69 VK_NUMPAD9 NumKeyPad '9' */ kb9,
+ /* 6A VK_MULTIPLY */ kbAsterisk,
+ /* 6B VK_ADD */ kbPlus,
+ /* 6C VK_SEPARATOR */ kbBackSlash,
+ /* 6D VK_SUBSTRACT */ kbMinus,
+ /* 6E VK_DECIMAL */ kbGrave,
+ /* 6F VK_DIVIDE */ kbSlash,
+ /* 70 VK_F1 'F1' */ kbF1,
+ /* 71 VK_F2 'F2' */ kbF2,
+ /* 72 VK_F3 'F3' */ kbF3,
+ /* 73 VK_F4 'F4' */ kbF4,
+ /* 74 VK_F5 'F5' */ kbF5,
+ /* 75 VK_F6 'F6' */ kbF6,
+ /* 76 VK_F7 'F7' */ kbF7,
+ /* 77 VK_F8 'F8' */ kbF8,
+ /* 78 VK_F9 'F9' */ kbF9,
+ /* 79 VK_F10 'F10' */ kbF10,
+ /* 7A VK_F11 'F11' */ kbF11,
+ /* 7B VK_F12 'F12' */ kbF12,
+ /* 7C VK_F13 */ 0,
+ /* 7D VK_F14 */ 0,
+ /* 7E VK_F15 */ 0,
+ /* 7F VK_F16 */ 0,
+ /* 80 VK_F17 */ 0,
+ /* 81 VK_F18 */ 0,
+ /* 82 VK_F19 */ 0,
+ /* 83 VK_F20 */ 0,
+ /* 84 VK_F21 */ 0,
+ /* 85 VK_F22 */ 0,
+ /* 86 VK_F23 */ 0,
+ /* 87 VK_F24 */ 0,
+ /* 88 unassigned */ 0,
+ /* 89 VK_NUMLOCK */ 0,
+ /* 8A VK_SCROLL */ 0,
+ /* 8B unassigned */ 0,
+ /* 8C unassigned */ 0,
+ /* 8D unassigned */ 0,
+ /* 8E unassigned */ 0,
+ /* 8F unassigned */ 0,
+ /* 90 unassigned */ 0,
+ /* 91 unassigned */ 0,
+ /* 92 unassigned */ 0,
+ /* 93 unassigned */ 0,
+ /* 94 unassigned */ 0,
+ /* 95 unassigned */ 0,
+ /* 96 unassigned */ 0,
+ /* 97 unassigned */ 0,
+ /* 98 unassigned */ 0,
+ /* 99 unassigned */ 0,
+ /* 9A unassigned */ 0,
+ /* 9B unassigned */ 0,
+ /* 9C unassigned */ 0,
+ /* 9D unassigned */ 0,
+ /* 9E unassigned */ 0,
+ /* 9F unassigned */ 0,
+ /* A0 unassigned */ 0,
+ /* A1 unassigned */ 0,
+ /* A2 unassigned */ 0,
+ /* A3 unassigned */ 0,
+ /* A4 unassigned */ 0,
+ /* A5 unassigned */ 0,
+ /* A6 unassigned */ 0,
+ /* A7 unassigned */ 0,
+ /* A8 unassigned */ 0,
+ /* A9 unassigned */ 0,
+ /* AA unassigned */ 0,
+ /* AB unassigned */ 0,
+ /* AC unassigned */ 0,
+ /* AD unassigned */ 0,
+ /* AE unassigned */ 0,
+ /* AF unassigned */ 0,
+ /* B0 unassigned */ 0,
+ /* B1 unassigned */ 0,
+ /* B2 unassigned */ 0,
+ /* B3 unassigned */ 0,
+ /* B4 unassigned */ 0,
+ /* B5 unassigned */ 0,
+ /* B6 unassigned */ 0,
+ /* B7 unassigned */ 0,
+ /* B8 unassigned */ 0,
+ /* B9 unassigned */ 0,
+ /* BA OEM specific */ 0,
+ /* BB OEM specific */ 0,
+ /* BC OEM specific */ 0,
+ /* BD OEM specific */ 0,
+ /* BE OEM specific */ 0,
+ /* BF OEM specific */ 0,
+ /* C0 OEM specific */ 0,
+ /* C1 unassigned */ 0,
+ /* C2 unassigned */ 0,
+ /* C3 unassigned */ 0,
+ /* C4 unassigned */ 0,
+ /* C5 unassigned */ 0,
+ /* C6 unassigned */ 0,
+ /* C7 unassigned */ 0,
+ /* C8 unassigned */ 0,
+ /* C9 unassigned */ 0,
+ /* CA unassigned */ 0,
+ /* CB unassigned */ 0,
+ /* CC unassigned */ 0,
+ /* CD unassigned */ 0,
+ /* CE unassigned */ 0,
+ /* CF unassigned */ 0,
+ /* D0 unassigned */ 0,
+ /* D1 unassigned */ 0,
+ /* D2 unassigned */ 0,
+ /* D3 unassigned */ 0,
+ /* D4 unassigned */ 0,
+ /* D5 unassigned */ 0,
+ /* D6 unassigned */ 0,
+ /* D7 unassigned */ 0,
+ /* D8 unassigned */ 0,
+ /* D9 unassigned */ 0,
+ /* DA unassigned */ 0,
+ /* DB OEM specific */ 0,
+ /* DC OEM specific */ 0,
+ /* DD OEM specific */ 0,
+ /* DE OEM specific */ 0,
+ /* DF OEM specific */ 0,
+ /* E0 OEM specific */ 0,
+ /* E1 OEM specific */ 0,
+ /* E2 OEM specific */ 0,
+ /* E3 OEM specific */ 0,
+ /* E4 OEM specific */ 0,
+ /* E5 unassigned */ 0,
+ /* E6 OEM specific */ 0,
+ /* E7 unassigned */ 0,
+ /* E8 unassigned */ 0,
+ /* E9 OEM specific */ 0,
+ /* EA OEM specific */ 0,
+ /* EB OEM specific */ 0,
+ /* EC OEM specific */ 0,
+ /* ED OEM specific */ 0,
+ /* EE OEM specific */ 0,
+ /* EF OEM specific */ 0,
+ /* F0 OEM specific */ 0,
+ /* F1 OEM specific */ 0,
+ /* F2 OEM specific */ 0,
+ /* F3 OEM specific */ 0,
+ /* F4 OEM specific */ 0,
+ /* F5 OEM specific */ 0,
+ /* F6 unassigned */ 0,
+ /* F7 unassigned */ 0,
+ /* F8 unassigned */ 0,
+ /* F9 unassigned */ 0,
+ /* FA unassigned */ 0,
+ /* FB unassigned */ 0,
+ /* FC unassigned */ 0,
+ /* FD unassigned */ 0,
+ /* FE unassigned */ 0,
+ /* FF unassigned */ 0
+};
+
+int TGKeyWin32::transKeyEvent(KeyDownEvent& dst, KEY_EVENT_RECORD& src)
+{
+ if (src.wVirtualKeyCode!=VK_MENU &&
+ src.wVirtualKeyCode!=VK_CONTROL &&
+ src.wVirtualKeyCode!=VK_SHIFT)
+ {
+ dst.keyCode=KeyTo[src.wVirtualKeyCode];
+ dst.charScan.charCode=src.uChar.AsciiChar;
+ dst.charScan.scanCode=(uchar)src.wVirtualScanCode;
+ dst.raw_scanCode=(uchar)src.wVirtualScanCode;
+ dst.shiftState=transShiftState(src.dwControlKeyState);
+ if (dst.shiftState&kbAltShift) dst.keyCode|=kbAltLCode;
+ if (dst.shiftState&kbCtrlShift) dst.keyCode|=kbCtrlCode;
+ if (dst.shiftState&kbShift) dst.keyCode|=kbShiftCode;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ Win32 console events handlers
+ by Vadim Beloborodov
+ Originally in console.cc
+*/
+
+const char TGKeyWin32::testChars[]=
+"`1234567890-="
+"~!@#$%^&*()_+"
+"qwertyuiop[]"
+"QWERTYUIOP{}"
+"asdfghjkl;'\\"
+"ASDFGHJKL:\"|"
+"zxcvbnm,./"
+"ZXCVBNM<>?";
+
+unsigned TGKeyWin32::GetShiftState()
+{
+ return LastControlKeyState;
+}
+
+void TGKeyWin32::putConsoleKeyboardEvent(KeyDownEvent &key)
+{
+ EnterCriticalSection(&lockKeyboard);
+ if (evKeyboardLength<eventKeyboardQSize)
+ {
+ evKeyboardLength++;
+ *evKeyboardIn=key;
+ if (++evKeyboardIn>=&evKeyboardQueue[eventKeyboardQSize])
+ evKeyboardIn=&evKeyboardQueue[0];
+ }
+ LeaveCriticalSection(&lockKeyboard);
+}
+
+int TGKeyWin32::getConsoleKeyboardEvent(KeyDownEvent &key)
+{
+ EnterCriticalSection(&lockKeyboard);
+ int haskeyevent=evKeyboardLength>0;
+ if (haskeyevent)
+ {
+ evKeyboardLength--;
+ key=*evKeyboardOut;
+ if (++evKeyboardOut>=&evKeyboardQueue[eventKeyboardQSize])
+ evKeyboardOut=&evKeyboardQueue[0];
+ }
+ LeaveCriticalSection(&lockKeyboard);
+ return haskeyevent;
+}
+
+void TGKeyWin32::HandleKeyEvent()
+{
+ INPUT_RECORD ir;
+ DWORD dwRead;
+ PeekConsoleInput(TScreenWin32::hIn,&ir,1,&dwRead);
+ if ((dwRead==1) && (ir.EventType==KEY_EVENT))
+ {
+ if (ir.Event.KeyEvent.bKeyDown)
+ {
+ //support for non US keyboard layout on Windows95
+ if (((ir.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED|RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))==0) &&
+ (ir.Event.KeyEvent.uChar.AsciiChar) &&
+ strchr(testChars,ir.Event.KeyEvent.uChar.AsciiChar))
+ {
+ uchar chr;
+ ReadConsole(TScreenWin32::hIn,&chr,1,&dwRead,NULL);
+ ir.Event.KeyEvent.uChar.AsciiChar=chr;
+ dwRead=0;
+ }
+ else
+ {
+ ReadConsoleInput(TScreenWin32::hIn,&ir,1,&dwRead);
+ dwRead = 0;
+ }
+ //translate event
+ KeyDownEvent key;
+ if (transKeyEvent(key,ir.Event.KeyEvent))
+ putConsoleKeyboardEvent(key);
+ }
+ ProcessControlKeyState(&ir);
+ }
+ if (dwRead==1)
+ ReadConsoleInput(TScreenWin32::hIn,&ir,1,&dwRead);
+}
+
+void TGKeyWin32::ProcessControlKeyState(INPUT_RECORD *ir)
+{
+ LastControlKeyState=transShiftState(ir->Event.KeyEvent.dwControlKeyState);
+}
+#else
+
+#include <tv/win32/screen.h>
+#include <tv/win32/key.h>
+
+#endif // TVOS_Win32
+