Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenkeytrans.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2002 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* 00020 * COPYRIGHT: See COPYING in the top level directory 00021 * PROJECT: ReactOS text-mode setup 00022 * FILE: subsys/system/usetup/keytrans.c 00023 * PURPOSE: Console support functions: keyboard translation 00024 * PROGRAMMER: Tinus 00025 * 00026 * NB: Hardcoded to US keyboard 00027 */ 00028 #include "usetup.h" 00029 #include "keytrans.h" 00030 00031 #define NDEBUG 00032 #include <debug.h> 00033 00034 static WORD KeyTable[] = { 00035 /* 0x00 */ 00036 0x00, VK_ESCAPE, 0x31, 0x32, 00037 0x33, 0x34, 0x35, 0x36, 00038 0x37, 0x38, 0x39, 0x30, 00039 VK_OEM_MINUS, VK_OEM_PLUS, VK_BACK, VK_TAB, 00040 /* 0x10 */ 00041 0x51, 0x57, 0x45, 0x52, 00042 0x54, 0x59, 0x55, 0x49, 00043 0x4f, 0x50, VK_OEM_4, VK_OEM_6, 00044 VK_RETURN, VK_CONTROL, 0x41, 0x53, 00045 /* 0x20 */ 00046 0x44, 0x46, 0x47, 0x48, 00047 0x4a, 0x4b, 0x4c, VK_OEM_1, 00048 VK_OEM_7, 0xc0, VK_LSHIFT, VK_OEM_5, 00049 0x5a, 0x58, 0x43, 0x56, 00050 /* 0x30 */ 00051 0x42, 0x4e, 0x4d, VK_OEM_COMMA, 00052 VK_OEM_PERIOD, VK_OEM_2, VK_RSHIFT, VK_MULTIPLY, 00053 VK_LMENU, VK_SPACE, VK_CAPITAL, VK_F1, 00054 VK_F2, VK_F3, VK_F4, VK_F5, 00055 /* 0x40 */ 00056 VK_F6, VK_F7, VK_F8, VK_F9, 00057 VK_F10, VK_NUMLOCK, VK_SCROLL, VK_HOME, 00058 VK_UP, VK_PRIOR, VK_SUBTRACT, VK_LEFT, 00059 0, VK_RIGHT, VK_ADD, VK_END, 00060 /* 0x50 */ 00061 VK_DOWN, VK_NEXT, VK_INSERT, VK_DELETE, 00062 0, 0, 0, VK_F11, 00063 VK_F12, 0, 0, 0, 00064 0, 0, 0, 0, 00065 /* 0x60 */ 00066 0, 0, 0, 0, 00067 0, 0, 0, 0, 00068 0, 0, 0, 0, 00069 0, 0, 0, 0, 00070 /* 0x70 */ 00071 0, 0, 0, 0, 00072 0, 0, 0, 0, 00073 0, 0, 0, 0, 00074 0, 0, 0, 0 00075 }; 00076 00077 static WORD KeyTableEnhanced[] = { 00078 /* 0x00 */ 00079 0, 0, 0, 0, 00080 0, 0, 0, 0, 00081 0, 0, 0, 0, 00082 0, 0, 0, 0, 00083 /* 0x10 */ 00084 0, 0, 0, 0, 00085 0, 0, 0, 0, 00086 0, 0, 0, 0, 00087 VK_RETURN, VK_RCONTROL, 0, 0, 00088 /* 0x20 */ 00089 0, 0, 0, 0, 00090 0, 0, 0, 0, 00091 0, 0, 0, 0, 00092 0, 0, 0, 0, 00093 /* 0x30 */ 00094 0, 0, 0, 0, 00095 0, VK_DIVIDE, 0, VK_SNAPSHOT, 00096 VK_RMENU, 0, 0, 0, 00097 0, 0, 0, 0, 00098 /* 0x40 */ 00099 0, 0, 0, 0, 00100 0, 0, 0, VK_HOME, 00101 VK_UP, VK_PRIOR, 0, VK_LEFT, 00102 0, VK_RIGHT, 0, VK_END, 00103 /* 0x50 */ 00104 VK_DOWN, VK_NEXT, VK_INSERT, VK_DELETE, 00105 0, 0, 0, 0, 00106 0, 0, 0, 0, 00107 0, 0, 0, 0, 00108 /* 0x60 */ 00109 0, 0, 0, 0, 00110 0, 0, 0, 0, 00111 0, 0, 0, 0, 00112 0, 0, 0, 0, 00113 /* 0x70 */ 00114 0, 0, 0, 0, 00115 0, 0, 0, 0, 00116 0, 0, 0, 0, 00117 0, 0, 0, 0 00118 }; 00119 00120 /* 00121 * Note how the keyboard lights are not handled, so while NUMLOCK_ON can 00122 * be on, the light will never be. If this starts to be a problem it can be 00123 * fixed, but it's too much work for too little gain to do now. 00124 * Look in win32k/ntuser/input.c for an example. 00125 */ 00126 00127 static WORD KeyTableNumlock[] = { 00128 /* 0x00 */ 00129 0, 0, 0, 0, 00130 0, 0, 0, 0, 00131 0, 0, 0, 0, 00132 0, 0, 0, 0, 00133 /* 0x10 */ 00134 0, 0, 0, 0, 00135 0, 0, 0, 0, 00136 0, 0, 0, 0, 00137 0, 0, 0, 0, 00138 /* 0x20 */ 00139 0, 0, 0, 0, 00140 0, 0, 0, 0, 00141 0, 0, 0, 0, 00142 0, 0, 0, 0, 00143 /* 0x30 */ 00144 0, 0, 0, 0, 00145 0, 0, 0, 0, 00146 0, 0, 0, 0, 00147 0, 0, 0, 0, 00148 /* 0x40 */ 00149 0, 0, 0, 0, 00150 0, 0, 0, VK_NUMPAD7, 00151 VK_NUMPAD8, VK_NUMPAD9, 0, VK_NUMPAD4, 00152 VK_NUMPAD5, VK_NUMPAD6, 0, VK_NUMPAD1, 00153 /* 0x50 */ 00154 VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD0, 0, 00155 0, 0, 0, 0, 00156 0, 0, 0, 0, 00157 0, 0, 0, 0, 00158 /* 0x60 */ 00159 0, 0, 0, 0, 00160 0, 0, 0, 0, 00161 0, 0, 0, 0, 00162 0, 0, 0, 0, 00163 /* 0x70 */ 00164 0, 0, 0, 0, 00165 0, 0, 0, 0, 00166 0, 0, 0, 0, 00167 0, 0, 0, 0 00168 }; 00169 00170 typedef struct _SCANTOASCII { 00171 USHORT ScanCode; 00172 USHORT Enhanced; 00173 UCHAR Normal; 00174 UCHAR Shift; 00175 UCHAR NumLock; 00176 } SCANTOASCII, *PSCANTOASCII; 00177 00178 SCANTOASCII ScanToAscii[] = { 00179 { 0x1e, 0, 'a', 'A', 0 }, 00180 { 0x30, 0, 'b', 'B', 0 }, 00181 { 0x2e, 0, 'c', 'C', 0 }, 00182 { 0x20, 0, 'd', 'D', 0 }, 00183 { 0x12, 0, 'e', 'E', 0 }, 00184 { 0x21, 0, 'f', 'F', 0 }, 00185 { 0x22, 0, 'g', 'G', 0 }, 00186 { 0x23, 0, 'h', 'H', 0 }, 00187 { 0x17, 0, 'i', 'I', 0 }, 00188 { 0x24, 0, 'j', 'J', 0 }, 00189 { 0x25, 0, 'k', 'K', 0 }, 00190 { 0x26, 0, 'l', 'L', 0 }, 00191 { 0x32, 0, 'm', 'M', 0 }, 00192 { 0x31, 0, 'n', 'N', 0 }, 00193 { 0x18, 0, 'o', 'O', 0 }, 00194 { 0x19, 0, 'p', 'P', 0 }, 00195 { 0x10, 0, 'q', 'Q', 0 }, 00196 { 0x13, 0, 'r', 'R', 0 }, 00197 { 0x1f, 0, 's', 'S', 0 }, 00198 { 0x14, 0, 't', 'T', 0 }, 00199 { 0x16, 0, 'u', 'U', 0 }, 00200 { 0x2f, 0, 'v', 'V', 0 }, 00201 { 0x11, 0, 'w', 'W', 0 }, 00202 { 0x2d, 0, 'x', 'X', 0 }, 00203 { 0x15, 0, 'y', 'Y', 0 }, 00204 { 0x2c, 0, 'z', 'Z', 0 }, 00205 00206 { 0x02, 0, '1', '!', 0 }, 00207 { 0x03, 0, '2', '@', 0 }, 00208 { 0x04, 0, '3', '#', 0 }, 00209 { 0x05, 0, '4', '$', 0 }, 00210 { 0x06, 0, '5', '%', 0 }, 00211 { 0x07, 0, '6', '^', 0 }, 00212 { 0x08, 0, '7', '&', 0 }, 00213 { 0x09, 0, '8', '*', 0 }, 00214 { 0x0a, 0, '9', '(', 0 }, 00215 { 0x0b, 0, '0', ')', 0 }, 00216 00217 { 0x29, 0, '\'', '~', 0 }, 00218 { 0x0c, 0, '-', '_', 0 }, 00219 { 0x0d, 0, '=', '+', 0 }, 00220 { 0x1a, 0, '[', '{', 0 }, 00221 { 0x1b, 0, ']', '}', 0 }, 00222 { 0x2b, 0, '\\', '|', 0 }, 00223 { 0x27, 0, ';', ':', 0 }, 00224 { 0x28, 0, '\'', '"', 0 }, 00225 { 0x33, 0, ',', '<', 0 }, 00226 { 0x34, 0, '.', '>', 0 }, 00227 { 0x35, 0, '/', '?', 0 }, 00228 00229 { 0x4f, 0, 0, 0, '1' }, 00230 { 0x50, 0, 0, 0, '2' }, 00231 { 0x51, 0, 0, 0, '3' }, 00232 { 0x4b, 0, 0, 0, '4' }, 00233 { 0x4c, 0, 0, 0, '5' }, 00234 { 0x4d, 0, 0, 0, '6' }, 00235 { 0x47, 0, 0, 0, '7' }, 00236 { 0x48, 0, 0, 0, '8' }, 00237 { 0x49, 0, 0, 0, '9' }, 00238 { 0x52, 0, 0, 0, '0' }, 00239 00240 { 0x4a, 0, '-', '-', 0 }, 00241 { 0x4e, 0, '+', '+', 0 }, 00242 { 0x37, 0, '*', '*', 0 }, 00243 { 0x35, 1, '/', '/', 0 }, 00244 { 0x53, 0, 0, 0, '.' }, 00245 00246 { 0x39, 0, ' ', ' ', 0 }, 00247 00248 { 0x1c, 0, '\r', '\r', 0 }, 00249 { 0x1c, 1, '\r', '\r', 0 }, 00250 { 0x0e, 0, 0x08, 0x08, 0 }, /* backspace */ 00251 00252 { 0, 0, 0, 0, 0 } 00253 }; 00254 00255 00256 static void 00257 IntUpdateControlKeyState(LPDWORD State, PKEYBOARD_INPUT_DATA InputData) 00258 { 00259 DWORD Value = 0; 00260 00261 if (InputData->Flags & KEY_E1) /* Only the pause key has E1 */ 00262 return; 00263 00264 if (!(InputData->Flags & KEY_E0)) { 00265 switch (InputData->MakeCode) { 00266 case 0x2a: 00267 case 0x36: 00268 Value = SHIFT_PRESSED; 00269 break; 00270 00271 case 0x1d: 00272 Value = LEFT_CTRL_PRESSED; 00273 break; 00274 00275 case 0x38: 00276 Value = LEFT_ALT_PRESSED; 00277 break; 00278 00279 case 0x45: 00280 Value = NUMLOCK_ON; 00281 if (!(InputData->Flags & KEY_BREAK)) 00282 *State ^= Value; 00283 return; 00284 default: 00285 return; 00286 } 00287 } else { 00288 switch (InputData->MakeCode) { 00289 case 0x1d: 00290 Value = RIGHT_CTRL_PRESSED; 00291 break; 00292 00293 case 0x38: 00294 Value = RIGHT_ALT_PRESSED; 00295 break; 00296 00297 default: 00298 return; 00299 } 00300 } 00301 00302 if (InputData->Flags & KEY_BREAK) 00303 *State &= ~Value; 00304 else 00305 *State |= Value; 00306 } 00307 00308 static DWORD 00309 IntVKFromKbdInput(PKEYBOARD_INPUT_DATA InputData, DWORD KeyState) 00310 { 00311 if (!(KeyState & ENHANCED_KEY)) { 00312 if ((KeyState & NUMLOCK_ON) && 00313 KeyTableNumlock[InputData->MakeCode & 0x7f]) { 00314 DPRINT("Numlock, using %x\n", 00315 InputData->MakeCode & 0x7f); 00316 return KeyTableNumlock[InputData->MakeCode & 0x7f]; 00317 } 00318 DPRINT("Not enhanced, using %x\n", InputData->MakeCode & 0x7f); 00319 return KeyTable[InputData->MakeCode & 0x7f]; 00320 } 00321 00322 DPRINT("Enhanced, using %x\n", InputData->MakeCode & 0x7f); 00323 return KeyTableEnhanced[InputData->MakeCode & 0x7f]; 00324 } 00325 00326 static UCHAR 00327 IntAsciiFromInput(PKEYBOARD_INPUT_DATA InputData, DWORD KeyState) 00328 { 00329 UINT Counter = 0; 00330 USHORT Enhanced = 0; 00331 00332 if (KeyState & ENHANCED_KEY) Enhanced = 1; 00333 00334 while (ScanToAscii[Counter].ScanCode != 0) { 00335 if ((ScanToAscii[Counter].ScanCode == InputData->MakeCode) && 00336 (ScanToAscii[Counter].Enhanced == Enhanced)) { 00337 if (ScanToAscii[Counter].NumLock) { 00338 if ((KeyState & NUMLOCK_ON) && 00339 !(KeyState & SHIFT_PRESSED)) { 00340 return ScanToAscii[Counter].NumLock; 00341 } else { 00342 return ScanToAscii[Counter].Normal; 00343 } 00344 } 00345 if (KeyState & SHIFT_PRESSED) 00346 return ScanToAscii[Counter].Shift; 00347 00348 return ScanToAscii[Counter].Normal; 00349 } 00350 Counter++; 00351 } 00352 00353 return 0; 00354 } 00355 00356 /* This is going to be quick and messy. The usetup app runs in native mode 00357 * so it cannot use the translation routines in win32k which means it'll have 00358 * to be done here too. 00359 * 00360 * Only the bKeyDown, AsciiChar and wVirtualKeyCode members are used 00361 * in the app so I'll just fill the others with somewhat sane values 00362 */ 00363 NTSTATUS 00364 IntTranslateKey(PKEYBOARD_INPUT_DATA InputData, KEY_EVENT_RECORD *Event) 00365 { 00366 static DWORD dwControlKeyState; 00367 00368 RtlZeroMemory(Event, sizeof(KEY_EVENT_RECORD)); 00369 00370 if (!(InputData->Flags & KEY_BREAK)) 00371 Event->bKeyDown = TRUE; 00372 else 00373 Event->bKeyDown = FALSE; 00374 00375 Event->wRepeatCount = 1; 00376 Event->wVirtualScanCode = InputData->MakeCode; 00377 00378 DPRINT("Translating: %x\n", InputData->MakeCode); 00379 00380 IntUpdateControlKeyState(&dwControlKeyState, InputData); 00381 Event->dwControlKeyState = dwControlKeyState; 00382 00383 if (InputData->Flags & KEY_E0) 00384 Event->dwControlKeyState |= ENHANCED_KEY; 00385 00386 Event->wVirtualKeyCode = IntVKFromKbdInput(InputData, 00387 Event->dwControlKeyState); 00388 00389 DPRINT("Result: %x\n", Event->wVirtualKeyCode); 00390 00391 if (Event->bKeyDown) { 00392 Event->uChar.AsciiChar = 00393 IntAsciiFromInput(InputData, 00394 Event->dwControlKeyState); 00395 DPRINT("Char: %x\n", Event->uChar.AsciiChar); 00396 } else { 00397 Event->uChar.AsciiChar = 0; 00398 } 00399 00400 return STATUS_SUCCESS; 00401 } Generated on Sat May 26 2012 04:16:59 for ReactOS by
1.7.6.1
|