00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "htkeyb.h"
00022
00023 #define WIN32_LEAN_AND_MEAN
00024 #include <windows.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027
00028
00029 HANDLE input_handle;
00030 INPUT_RECORD key_event_record;
00031 bool key_pending=false;
00032 bool k_shift_state=false;
00033 bool k_ctrl_state=false;
00034 bool k_alt_state=false;
00035
00036
00037
00038 #ifdef KEY_DEBUG
00039 FILE *kd;
00040 #endif
00041
00042 struct ht_key_keycode {
00043 ht_key key;
00044 int keycode;
00045 };
00046
00047 #define HT_VK 0x300
00048 #define HT_VK_ALT (0x1000)
00049 #define HT_VK_SHIFT (0x2000)
00050 #define HT_VK_CTRL (0x3000)
00051
00052 ht_key_keycode ht_win32_key_defs[] = {
00053
00054 {K_Control_A, (0x001+HT_VK_CTRL)},
00055 {K_Control_B, (0x002+HT_VK_CTRL)},
00056 {K_Control_C, (0x003+HT_VK_CTRL)},
00057 {K_Control_D, (0x004+HT_VK_CTRL)},
00058 {K_Control_E, (0x005+HT_VK_CTRL)},
00059 {K_Control_F, (0x006+HT_VK_CTRL)},
00060 {K_Control_G, (0x007+HT_VK_CTRL)},
00061 {K_Backspace, 0x008},
00062 {K_Control_H, (0x008+HT_VK_CTRL)},
00063 {K_Tab, 0x009},
00064 {K_Control_I, (0x009+HT_VK_CTRL)},
00065 {K_Control_J, (0x00a+HT_VK_CTRL)},
00066 {K_Control_K, (0x00b+HT_VK_CTRL)},
00067 {K_Control_L, (0x00c+HT_VK_CTRL)},
00068 {K_Return, 0x00d},
00069 {K_Control_M, (0x00d+HT_VK_CTRL)},
00070 {K_Control_N, (0x00e + HT_VK_CTRL)},
00071 {K_Control_O, (0x00f+HT_VK_CTRL)},
00072 {K_Control_P, (0x010+HT_VK_CTRL)},
00073 {K_Control_Q, (0x011+HT_VK_CTRL)},
00074 {K_Control_R, (0x012+HT_VK_CTRL)},
00075 {K_Control_S, (0x013+HT_VK_CTRL)},
00076 {K_Control_T, (0x014+HT_VK_CTRL)},
00077 {K_Control_U, (0x015+HT_VK_CTRL)},
00078 {K_Control_V, (0x016+HT_VK_CTRL)},
00079 {K_Control_W, (0x017+HT_VK_CTRL)},
00080 {K_Control_X, (0x018+HT_VK_CTRL)},
00081 {K_Control_Y, (0x019+HT_VK_CTRL)},
00082 {K_Control_Z, (0x01a+HT_VK_CTRL)},
00083 {K_Escape, 0x01b},
00084
00085
00086
00087
00088
00089
00090
00091 {K_Alt_Escape, (K_Escape+HT_VK_ALT)},
00092
00093 {K_Alt_Backspace, (K_Backspace+HT_VK_ALT)},
00094 {K_BackTab, HT_VK_SHIFT+0x0009},
00095 {K_Alt_Q, ('q'+HT_VK_ALT)},
00096 {K_Alt_W, ('w'+HT_VK_ALT)},
00097 {K_Alt_E, ('e'+HT_VK_ALT)},
00098 {K_Alt_R, ('r'+HT_VK_ALT)},
00099 {K_Alt_T, ('t'+HT_VK_ALT)},
00100 {K_Alt_Y, ('y'+HT_VK_ALT)},
00101 {K_Alt_U, ('u'+HT_VK_ALT)},
00102 {K_Alt_I, ('i'+HT_VK_ALT)},
00103 {K_Alt_O, ('o'+HT_VK_ALT)},
00104 {K_Alt_P, ('p'+HT_VK_ALT)},
00105
00106
00107
00108 {K_Alt_A, ('a'+HT_VK_ALT)},
00109 {K_Alt_S, ('s'+HT_VK_ALT)},
00110 {K_Alt_D, ('d'+HT_VK_ALT)},
00111 {K_Alt_F, ('f'+HT_VK_ALT)},
00112 {K_Alt_G, ('g'+HT_VK_ALT)},
00113 {K_Alt_H, ('h'+HT_VK_ALT)},
00114 {K_Alt_J, ('j'+HT_VK_ALT)},
00115 {K_Alt_K, ('k'+HT_VK_ALT)},
00116 {K_Alt_L, ('l'+HT_VK_ALT)},
00117
00118
00119
00120
00121 {K_Alt_Z, ('z'+HT_VK_ALT)},
00122 {K_Alt_X, ('x'+HT_VK_ALT)},
00123 {K_Alt_C, ('c'+HT_VK_ALT)},
00124 {K_Alt_V, ('v'+HT_VK_ALT)},
00125 {K_Alt_B, ('b'+HT_VK_ALT)},
00126 {K_Alt_N, ('n'+HT_VK_ALT)},
00127 {K_Alt_M, ('m'+HT_VK_ALT)},
00128
00129
00130
00131
00132 {K_F1, (VK_F1+HT_VK)},
00133 {K_F2, (VK_F2+HT_VK)},
00134 {K_F3, (VK_F3+HT_VK)},
00135 {K_F4, (VK_F4+HT_VK)},
00136 {K_F5, (VK_F5+HT_VK)},
00137 {K_F6, (VK_F6+HT_VK)},
00138 {K_F7, (VK_F7+HT_VK)},
00139 {K_F8, (VK_F8+HT_VK)},
00140 {K_F9, (VK_F9+HT_VK)},
00141 {K_F10, (VK_F10+HT_VK)},
00142 {K_Home, (VK_HOME+HT_VK)},
00143 {K_Up, (VK_UP+HT_VK)},
00144 {K_PageUp, (VK_PRIOR+HT_VK)},
00145
00146 {K_Left, (VK_LEFT+HT_VK)},
00147
00148 {K_Right, (VK_RIGHT+HT_VK)},
00149
00150 {K_End, (VK_END+HT_VK)},
00151 {K_Down, (VK_DOWN+HT_VK)},
00152 {K_PageDown, (VK_NEXT+HT_VK)},
00153 {K_Insert, (VK_INSERT+HT_VK)},
00154 {K_Delete, (VK_DELETE+HT_VK)},
00155 {K_Shift_F1, (VK_F1+HT_VK+HT_VK_SHIFT)},
00156 {K_Shift_F2, (VK_F2+HT_VK+HT_VK_SHIFT)},
00157 {K_Shift_F3, (VK_F3+HT_VK+HT_VK_SHIFT)},
00158 {K_Shift_F4, (VK_F4+HT_VK+HT_VK_SHIFT)},
00159 {K_Shift_F5, (VK_F5+HT_VK+HT_VK_SHIFT)},
00160 {K_Shift_F6, (VK_F6+HT_VK+HT_VK_SHIFT)},
00161 {K_Shift_F7, (VK_F7+HT_VK+HT_VK_SHIFT)},
00162 {K_Shift_F8, (VK_F8+HT_VK+HT_VK_SHIFT)},
00163 {K_Shift_F9, (VK_F9+HT_VK+HT_VK_SHIFT)},
00164 {K_Shift_F10, (VK_F10+HT_VK+HT_VK_SHIFT)},
00165 {K_Control_F1, (VK_F1+HT_VK+HT_VK_CTRL)},
00166 {K_Control_F2, (VK_F2+HT_VK+HT_VK_CTRL)},
00167 {K_Control_F3, (VK_F3+HT_VK+HT_VK_CTRL)},
00168 {K_Control_F4, (VK_F4+HT_VK+HT_VK_CTRL)},
00169 {K_Control_F5, (VK_F5+HT_VK+HT_VK_CTRL)},
00170 {K_Control_F6, (VK_F6+HT_VK+HT_VK_CTRL)},
00171 {K_Control_F7, (VK_F7+HT_VK+HT_VK_CTRL)},
00172 {K_Control_F8, (VK_F8+HT_VK+HT_VK_CTRL)},
00173 {K_Control_F9, (VK_F9+HT_VK+HT_VK_CTRL)},
00174 {K_Control_F10, (VK_F10+HT_VK+HT_VK_CTRL)},
00175 {K_Alt_F1, (VK_F1+HT_VK+HT_VK_ALT)},
00176 {K_Alt_F2, (VK_F2+HT_VK+HT_VK_ALT)},
00177 {K_Alt_F3, (VK_F3+HT_VK+HT_VK_ALT)},
00178 {K_Alt_F4, (VK_F4+HT_VK+HT_VK_ALT)},
00179 {K_Alt_F5, (VK_F5+HT_VK+HT_VK_ALT)},
00180 {K_Alt_F6, (VK_F6+HT_VK+HT_VK_ALT)},
00181 {K_Alt_F7, (VK_F7+HT_VK+HT_VK_ALT)},
00182 {K_Alt_F8, (VK_F8+HT_VK+HT_VK_ALT)},
00183 {K_Alt_F9, (VK_F9+HT_VK+HT_VK_ALT)},
00184 {K_Alt_F10, (VK_F10+HT_VK+HT_VK_ALT)},
00185
00186 {K_Control_Left, (VK_LEFT+HT_VK_CTRL+HT_VK)},
00187 {K_Control_Right, (VK_RIGHT+HT_VK_CTRL+HT_VK)},
00188 {K_Control_End, (VK_END+HT_VK_CTRL+HT_VK)},
00189 {K_Control_PageDown, (VK_NEXT+HT_VK_CTRL+HT_VK)},
00190 {K_Control_Home, (VK_HOME+HT_VK_CTRL+HT_VK)},
00191 {K_Alt_1, ('1'+HT_VK_ALT)},
00192 {K_Alt_2, ('2'+HT_VK_ALT)},
00193 {K_Alt_3, ('3'+HT_VK_ALT)},
00194 {K_Alt_4, ('4'+HT_VK_ALT)},
00195 {K_Alt_5, ('5'+HT_VK_ALT)},
00196 {K_Alt_6, ('6'+HT_VK_ALT)},
00197 {K_Alt_7, ('7'+HT_VK_ALT)},
00198 {K_Alt_8, ('8'+HT_VK_ALT)},
00199 {K_Alt_9, ('9'+HT_VK_ALT)},
00200 {K_Alt_0, ('0'+HT_VK_ALT)},
00201
00202
00203 {K_Control_PageUp, (VK_PRIOR+HT_VK_CTRL+HT_VK)},
00204 {K_F11, (VK_F11+HT_VK+HT_VK)},
00205 {K_F12, (VK_F12+HT_VK+HT_VK)},
00206 {K_Shift_F11, (VK_F11+HT_VK+HT_VK_SHIFT)},
00207 {K_Shift_F12, (VK_F12+HT_VK+HT_VK_SHIFT)},
00208 {K_Control_F11, (VK_F11+HT_VK+HT_VK_CTRL)},
00209 {K_Control_F12, (VK_F12+HT_VK+HT_VK_CTRL)},
00210 {K_Alt_F11, (VK_F11+HT_VK+HT_VK_ALT)},
00211 {K_Alt_F12, (VK_F12+HT_VK+HT_VK_ALT)},
00212 {K_Control_Up, (VK_UP+HT_VK_CTRL+HT_VK)},
00213
00214
00215
00216 {K_Control_Down, (VK_DOWN+HT_VK_CTRL+HT_VK)},
00217 {K_Control_Insert, (VK_INSERT+HT_VK_CTRL+HT_VK)},
00218 {K_Control_Delete, (VK_DELETE+HT_VK_CTRL+HT_VK)},
00219
00220
00221 {K_Alt_Tab, (0x0009+HT_VK_ALT+HT_VK)},
00222 {K_Alt_Enter, 0x1a6},
00223
00224 {K_Shift_Up, (HT_VK_SHIFT+VK_UP+HT_VK)},
00225 {K_Shift_Down, (HT_VK_SHIFT+VK_DOWN+HT_VK)},
00226 {K_Shift_Left, (HT_VK_SHIFT+VK_LEFT+HT_VK)},
00227 {K_Shift_Right, (HT_VK_SHIFT+VK_RIGHT+HT_VK)},
00228 {K_Shift_PageUp, (HT_VK_SHIFT+VK_PRIOR+HT_VK)},
00229 {K_Shift_PageDown, (HT_VK_SHIFT+VK_NEXT+HT_VK)},
00230
00231 {K_Shift_Home, (HT_VK_SHIFT+VK_HOME+HT_VK)},
00232 {K_Shift_End, (HT_VK_SHIFT+VK_END+HT_VK)},
00233 {K_Shift_Delete, (HT_VK_SHIFT+VK_DELETE+HT_VK)},
00234 {K_Shift_Insert, (HT_VK_SHIFT+VK_INSERT+HT_VK)},
00235
00236 {K_INVALID, -1}
00237
00238 };
00239
00240 bool ht_keypressed()
00241 {
00242 DWORD read;
00243 if (key_pending) return true;
00244 while (1) {
00245 PeekConsoleInputA(input_handle, &key_event_record, 1, &read);
00246 if (!read) return false;
00247 ReadConsoleInputA(input_handle, &key_event_record, 1, &read);
00248 if (key_event_record.EventType & KEY_EVENT) {
00249 switch (key_event_record.Event.KeyEvent.wVirtualKeyCode) {
00250 case VK_CONTROL:
00251 k_ctrl_state=key_event_record.Event.KeyEvent.bKeyDown;
00252 break;
00253 case VK_MENU:
00254 k_alt_state=key_event_record.Event.KeyEvent.bKeyDown;
00255 break;
00256 }
00257 if (key_event_record.Event.KeyEvent.bKeyDown) {
00258 key_pending = true;
00259 return true;
00260 }
00261 }
00262 }
00263 }
00264
00265 int ht_key_meta(bool shift, bool alt)
00266 {
00267 return (((key_event_record.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) && (shift)) ? HT_VK_SHIFT : 0)
00268 +((key_event_record.Event.KeyEvent.dwControlKeyState &(LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) ? HT_VK_CTRL : 0)
00269 +(((key_event_record.Event.KeyEvent.dwControlKeyState &(LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) && (alt)) ? HT_VK_ALT : 0);
00270 }
00271
00272 int ht_raw_getkey()
00273 {
00274 if (!ht_keypressed()) return -1;
00275 key_pending = false;
00276 #ifdef KEY_DEBUG
00277 if (key_event_record.Event.KeyEvent.uChar.AsciiChar) {
00278 fprintf(kd, "Ascii: %3d [%c]\n", key_event_record.Event.KeyEvent.uChar.AsciiChar + ht_key_meta(false, false), key_event_record.Event.KeyEvent.uChar.AsciiChar + ht_key_meta(false, false));
00279 } else {
00280 fprintf(kd, "VK: %3d shift: %d, alt: %d, ctrl: %d\n", key_event_record.Event.KeyEvent.wVirtualKeyCode, k_shift_state, k_alt_state, k_ctrl_state);
00281 }
00282 #endif
00283 if (key_event_record.Event.KeyEvent.uChar.AsciiChar && !(key_event_record.Event.KeyEvent.dwControlKeyState & 256)) {
00284
00285
00286
00287
00288
00289 switch (key_event_record.Event.KeyEvent.uChar.AsciiChar) {
00290 case '\\':
00291 case '@':
00292 case '|':
00293 case 'ý':
00294 case '~':
00295 case '{':
00296 case '}':
00297 case '[':
00298 case ']':
00299 return ((unsigned char)key_event_record.Event.KeyEvent.uChar.AsciiChar) + ht_key_meta(false, false);
00300 default:
00301 return ((unsigned char)key_event_record.Event.KeyEvent.uChar.AsciiChar) + ht_key_meta(false, true);
00302 }
00303 } else {
00304
00305 return key_event_record.Event.KeyEvent.wVirtualKeyCode + HT_VK + ht_key_meta(true, true);
00306 }
00307 }
00308
00309 ht_key ht_getkey()
00310 {
00311 UINT r=ht_raw_getkey();
00312 ht_key k=ht_rawkey2key(r);
00313 if ((k==K_INVALID) && (r<=255)) return (ht_key)r;
00314 return k;
00315 }
00316
00317 bool init_keyb()
00318 {
00319 input_handle = GetStdHandle(STD_INPUT_HANDLE);
00320 SetConsoleMode(input_handle, 0);
00321 #ifdef KEY_DEBUG
00322 kd = fopen("_kd.kd", "wt");
00323 #endif
00324
00325 int i;
00326
00327 for (i=0; i<K_COUNT; i++) {
00328 ht_set_key((ht_key)i, -1);
00329 }
00330
00331 for (i=0; ht_win32_key_defs[i].key!=K_INVALID; i++) {
00332 ht_set_key(ht_win32_key_defs[i].key, ht_win32_key_defs[i].keycode);
00333 }
00334
00335 return true;
00336 }
00337
00338 void done_keyb()
00339 {
00340 #ifdef KEY_DEBUG
00341 fclose(kd);
00342 #endif
00343 }