1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Console Server DLL 4 * FILE: win32ss/user/winsrv/consrv/frontends/input.c 5 * PURPOSE: Common Front-Ends Input functions 6 * PROGRAMMERS: Jeffrey Morlan 7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr) 8 */ 9 10 /* INCLUDES *******************************************************************/ 11 12 #include "consrv.h" 13 #include "include/term.h" 14 #include "coninput.h" 15 16 #define NDEBUG 17 #include <debug.h> 18 19 20 /* PRIVATE FUNCTIONS **********************************************************/ 21 22 static DWORD 23 ConioGetShiftState(PBYTE KeyState, LPARAM lParam) 24 { 25 DWORD ssOut = 0; 26 27 if (KeyState[VK_CAPITAL] & 0x01) 28 ssOut |= CAPSLOCK_ON; 29 30 if (KeyState[VK_NUMLOCK] & 0x01) 31 ssOut |= NUMLOCK_ON; 32 33 if (KeyState[VK_SCROLL] & 0x01) 34 ssOut |= SCROLLLOCK_ON; 35 36 if (KeyState[VK_SHIFT] & 0x80) 37 // || (KeyState[VK_LSHIFT] & 0x80) || (KeyState[VK_RSHIFT] & 0x80) 38 ssOut |= SHIFT_PRESSED; 39 40 if (KeyState[VK_LCONTROL] & 0x80) 41 ssOut |= LEFT_CTRL_PRESSED; 42 if (KeyState[VK_RCONTROL] & 0x80) 43 ssOut |= RIGHT_CTRL_PRESSED; 44 // if (KeyState[VK_CONTROL] & 0x80) { ... } 45 46 if (KeyState[VK_LMENU] & 0x80) 47 ssOut |= LEFT_ALT_PRESSED; 48 if (KeyState[VK_RMENU] & 0x80) 49 ssOut |= RIGHT_ALT_PRESSED; 50 // if (KeyState[VK_MENU] & 0x80) { ... } 51 52 /* See WM_CHAR MSDN documentation for instance */ 53 if (lParam & 0x01000000) 54 ssOut |= ENHANCED_KEY; 55 56 return ssOut; 57 } 58 59 VOID NTAPI 60 ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg) 61 { 62 static BYTE KeyState[256] = { 0 }; 63 /* MSDN mentions that you should use the last virtual key code received 64 * when putting a virtual key identity to a WM_CHAR message since multiple 65 * or translated keys may be involved. */ 66 static UINT LastVirtualKey = 0; 67 DWORD ShiftState; 68 WCHAR UnicodeChar; 69 UINT VirtualKeyCode; 70 UINT VirtualScanCode; 71 BOOL Down = FALSE; 72 BOOLEAN Fake; // Synthesized, not a real event 73 BOOLEAN NotChar; // Message should not be used to return a character 74 75 INPUT_RECORD er; 76 77 if (Console == NULL) 78 { 79 DPRINT1("No Active Console!\n"); 80 return; 81 } 82 83 VirtualScanCode = HIWORD(msg->lParam) & 0xFF; 84 Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || 85 msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; 86 87 GetKeyboardState(KeyState); 88 ShiftState = ConioGetShiftState(KeyState, msg->lParam); 89 90 if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) 91 { 92 VirtualKeyCode = LastVirtualKey; 93 UnicodeChar = msg->wParam; 94 } 95 else 96 { 97 WCHAR Chars[2]; 98 INT RetChars = 0; 99 100 VirtualKeyCode = msg->wParam; 101 RetChars = ToUnicodeEx(VirtualKeyCode, 102 VirtualScanCode, 103 KeyState, 104 Chars, 105 2, 106 0, 107 NULL); 108 UnicodeChar = (RetChars == 1 ? Chars[0] : 0); 109 } 110 111 Fake = UnicodeChar && 112 (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && 113 msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); 114 NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); 115 if (NotChar) LastVirtualKey = msg->wParam; 116 117 DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n", 118 Down ? "down" : "up ", 119 (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? 120 "char" : "key ", 121 Fake ? "fake" : "real", 122 NotChar ? "notc" : "char", 123 VirtualScanCode, 124 VirtualKeyCode, 125 (UnicodeChar >= L' ') ? UnicodeChar : L'.', 126 ShiftState); 127 128 if (Fake) return; 129 130 // 131 // FIXME: Scrolling via keyboard shortcuts must be done differently, 132 // without touching the internal VirtualY variable. 133 // 134 #if 0 135 if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 && 136 (VirtualKeyCode == VK_UP || VirtualKeyCode == VK_DOWN) ) 137 { 138 if (!Down) return; 139 140 /* Scroll up or down */ 141 if (VirtualKeyCode == VK_UP) 142 { 143 /* Only scroll up if there is room to scroll up into */ 144 if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1) 145 { 146 Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 147 Console->ActiveBuffer->ScreenBufferSize.Y - 1) % 148 Console->ActiveBuffer->ScreenBufferSize.Y; 149 Console->ActiveBuffer->CursorPosition.Y++; 150 } 151 } 152 else 153 { 154 /* Only scroll down if there is room to scroll down into */ 155 if (Console->ActiveBuffer->CursorPosition.Y != 0) 156 { 157 Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % 158 Console->ActiveBuffer->ScreenBufferSize.Y; 159 Console->ActiveBuffer->CursorPosition.Y--; 160 } 161 } 162 163 ConioDrawConsole(Console); 164 return; 165 } 166 #endif 167 168 /* Send the key press to the console driver */ 169 170 er.EventType = KEY_EVENT; 171 er.Event.KeyEvent.bKeyDown = Down; 172 er.Event.KeyEvent.wRepeatCount = 1; 173 er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; 174 er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; 175 er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; 176 er.Event.KeyEvent.dwControlKeyState = ShiftState; 177 178 ConioProcessInputEvent(Console, &er); 179 } 180 181 DWORD 182 ConioEffectiveCursorSize(PCONSRV_CONSOLE Console, DWORD Scale) 183 { 184 DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100; 185 /* If line input in progress, perhaps adjust for insert toggle */ 186 if (Console->LineBuffer && !Console->LineComplete && (Console->InsertMode ? !Console->LineInsertToggle : Console->LineInsertToggle)) 187 return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2); 188 return Size; 189 } 190 191 /* EOF */ 192