ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

keytrans.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.