]> git.proxmox.com Git - mirror_edk2.git/blob - Nt32Pkg/WinNtConsoleDxe/ConsoleIn.c
Remove the EDK prefix from library instance folder's name
[mirror_edk2.git] / Nt32Pkg / WinNtConsoleDxe / ConsoleIn.c
1 /*++
2
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 ConsoleIn.c
15
16 Abstract:
17
18 Console based on Win32 APIs.
19
20 This file attaches a SimpleTextIn protocol to a previously open window.
21
22 The constructor for this protocol depends on an open window. Currently
23 the SimpleTextOut protocol creates a window when it's constructor is called.
24 Thus this code must run after the constructor for the SimpleTextOut
25 protocol
26
27 --*/
28 //
29 // The package level header files this module uses
30 //
31 #include <Uefi.h>
32 #include <WinNtDxe.h>
33 //
34 // The protocols, PPI and GUID defintions for this module
35 //
36 #include <Protocol/SimpleTextIn.h>
37 #include <Protocol/WinNtIo.h>
38 #include <Protocol/SimpleTextOut.h>
39 #include <Protocol/ComponentName.h>
40 #include <Protocol/DriverBinding.h>
41 //
42 // The Library classes this module consumes
43 //
44 #include <Library/DebugLib.h>
45 #include <Library/BaseLib.h>
46 #include <Library/UefiDriverEntryPoint.h>
47 #include <Library/UefiLib.h>
48 #include <Library/BaseMemoryLib.h>
49 #include <Library/UefiBootServicesTableLib.h>
50 #include <Library/MemoryAllocationLib.h>
51 #include "Console.h"
52
53 //
54 // Private worker functions
55 //
56 STATIC
57 EFI_STATUS
58 WinNtSimpleTextInCheckKey (
59 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private
60 );
61
62 EFI_STATUS
63 EFIAPI
64 WinNtSimpleTextInReset (
65 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
66 IN BOOLEAN ExtendedVerification
67 )
68 /*++
69
70 Routine Description:
71
72 TODO: Add function description
73
74 Arguments:
75
76 This - TODO: add argument description
77 ExtendedVerification - TODO: add argument description
78
79 Returns:
80
81 EFI_SUCCESS - TODO: Add description for return value
82
83 --*/
84 {
85 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
86
87 Private = WIN_NT_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS (This);
88 return EFI_SUCCESS;
89 }
90
91 STATIC
92 EFI_STATUS
93 WinNtConvertInputRecordToEfiKey (
94 IN INPUT_RECORD *InputRecord,
95 OUT EFI_INPUT_KEY *Key
96 )
97 /*++
98
99 Routine Description:
100
101 TODO: Add function description
102
103 Arguments:
104
105 InputRecord - TODO: add argument description
106 Key - TODO: add argument description
107
108 Returns:
109
110 EFI_NOT_READY - TODO: Add description for return value
111 EFI_NOT_READY - TODO: Add description for return value
112 EFI_NOT_READY - TODO: Add description for return value
113 EFI_SUCCESS - TODO: Add description for return value
114
115 --*/
116 {
117 //
118 // Make sure InputRecord is an event that represents a keypress
119 //
120 if (InputRecord->EventType == KEY_EVENT) {
121 if (!InputRecord->Event.KeyEvent.bKeyDown) {
122 return EFI_NOT_READY;
123 }
124 } else {
125 return EFI_NOT_READY;
126 }
127
128 //
129 // Check to see if we should return a scan code in place of Unicode character.
130 //
131 Key->ScanCode = 0;
132 Key->UnicodeChar = 0;
133 if ((InputRecord->Event.KeyEvent.dwControlKeyState & (NUMLOCK_ON | ENHANCED_KEY)) != NUMLOCK_ON) {
134 //
135 // Only check these scan codes if num lock is off.
136 //
137 switch (InputRecord->Event.KeyEvent.wVirtualScanCode) {
138 case 0x48: Key->ScanCode = SCAN_UP; break;
139 case 0x50: Key->ScanCode = SCAN_DOWN; break;
140 case 0x4d: Key->ScanCode = SCAN_RIGHT; break;
141 case 0x4b: Key->ScanCode = SCAN_LEFT; break;
142 case 0x47: Key->ScanCode = SCAN_HOME; break;
143 case 0x4F: Key->ScanCode = SCAN_END; break;
144 case 0x52: Key->ScanCode = SCAN_INSERT; break;
145 case 0x53: Key->ScanCode = SCAN_DELETE; break;
146 case 0x49: Key->ScanCode = SCAN_PAGE_UP; break;
147 case 0x51: Key->ScanCode = SCAN_PAGE_DOWN; break;
148 }
149 }
150
151 switch (InputRecord->Event.KeyEvent.wVirtualScanCode) {
152 case 0x3b: Key->ScanCode = SCAN_F1; break;
153 case 0x3c: Key->ScanCode = SCAN_F2; break;
154 case 0x3d: Key->ScanCode = SCAN_F3; break;
155 case 0x3e: Key->ScanCode = SCAN_F4; break;
156 case 0x3f: Key->ScanCode = SCAN_F5; break;
157 case 0x40: Key->ScanCode = SCAN_F6; break;
158 case 0x41: Key->ScanCode = SCAN_F7; break;
159 case 0x42: Key->ScanCode = SCAN_F8; break;
160 case 0x43: Key->ScanCode = SCAN_F9; break;
161 case 0x44: Key->ScanCode = SCAN_F10; break;
162 case 0x01: Key->ScanCode = SCAN_ESC; break;
163 }
164
165 //
166 // If there's a scan code pass it, and don't pass the char code
167 //
168 if (Key->ScanCode == 0) {
169 Key->UnicodeChar = InputRecord->Event.KeyEvent.uChar.UnicodeChar;
170 if (Key->UnicodeChar == 0) {
171 return EFI_NOT_READY;
172 }
173 }
174
175 return EFI_SUCCESS;
176 }
177
178 STATIC
179 EFI_STATUS
180 EFIAPI
181 WinNtSimpleTextInReadKeyStroke (
182 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
183 OUT EFI_INPUT_KEY *Key
184 )
185 /*++
186
187 Routine Description:
188
189 TODO: Add function description
190
191 Arguments:
192
193 This - TODO: add argument description
194 Key - TODO: add argument description
195
196 Returns:
197
198 EFI_DEVICE_ERROR - TODO: Add description for return value
199 EFI_NOT_READY - TODO: Add description for return value
200
201 --*/
202 {
203 EFI_STATUS Status;
204 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
205 INPUT_RECORD InputRecord;
206 DWORD NtEventCount;
207
208 Private = WIN_NT_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS (This);
209
210 Status = WinNtSimpleTextInCheckKey (Private);
211 if (EFI_ERROR (Status)) {
212 return Status;
213 }
214
215 do {
216
217 if (!Private->WinNtThunk->ReadConsoleInput (Private->NtInHandle, &InputRecord, 1, &NtEventCount)) {
218 return EFI_DEVICE_ERROR;
219 }
220
221 if (NtEventCount == 0) {
222 return EFI_NOT_READY;
223 }
224
225 //
226 // Convert the Input Record to an EFI Keystroke.
227 //
228 Status = WinNtConvertInputRecordToEfiKey (&InputRecord, Key);
229 } while (EFI_ERROR (Status));
230
231 return Status;
232 }
233
234 STATIC
235 VOID
236 EFIAPI
237 WinNtSimpleTextInWaitForKey (
238 IN EFI_EVENT Event,
239 IN VOID *Context
240 )
241 /*++
242
243 Routine Description:
244
245 TODO: Add function description
246
247 Arguments:
248
249 Event - TODO: add argument description
250 Context - TODO: add argument description
251
252 Returns:
253
254 TODO: add return values
255
256 --*/
257 {
258 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
259 EFI_STATUS Status;
260
261 Private = (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *) Context;
262 Status = WinNtSimpleTextInCheckKey (Private);
263 if (!EFI_ERROR (Status)) {
264 gBS->SignalEvent (Event);
265 }
266 }
267
268 STATIC
269 EFI_STATUS
270 WinNtSimpleTextInCheckKey (
271 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private
272 )
273 /*++
274
275 Routine Description:
276
277 TODO: Add function description
278
279 Arguments:
280
281 Private - TODO: add argument description
282
283 Returns:
284
285 TODO: add return values
286
287 --*/
288 {
289 INPUT_RECORD *InputRecord;
290 DWORD NtEventCount;
291 DWORD ActualNtEventCount;
292 EFI_STATUS Status;
293 BOOLEAN Success;
294 UINTN Index;
295 EFI_INPUT_KEY Key;
296
297 InputRecord = NULL;
298 NtEventCount = 0;
299 Private->WinNtThunk->GetNumberOfConsoleInputEvents (Private->NtInHandle, &NtEventCount);
300 if (NtEventCount == 0) {
301 Status = EFI_NOT_READY;
302 goto Done;
303 }
304
305 InputRecord = AllocatePool (sizeof (INPUT_RECORD) * NtEventCount);
306 if (InputRecord == NULL) {
307 Status = EFI_NOT_READY;
308 goto Done;
309 }
310
311 Success = (BOOLEAN) Private->WinNtThunk->PeekConsoleInput (
312 Private->NtInHandle,
313 InputRecord,
314 NtEventCount,
315 &ActualNtEventCount
316 );
317 if (!Success) {
318 Status = EFI_NOT_READY;
319 goto Done;
320 }
321
322 Status = EFI_NOT_READY;
323 for (Index = 0; Index < (UINTN) ActualNtEventCount; Index++) {
324 //
325 // Convert the Input Record to an EFI Keystroke.
326 //
327 Status = WinNtConvertInputRecordToEfiKey (&InputRecord[Index], &Key);
328 if (!EFI_ERROR (Status)) {
329 Status = EFI_SUCCESS;
330 goto Done;
331 }
332 }
333
334 Done:
335 if (InputRecord != NULL) {
336 FreePool (InputRecord);
337 }
338
339 return Status;
340 }
341
342 EFI_STATUS
343 WinNtSimpleTextInAttachToWindow (
344 IN WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private
345 )
346 /*++
347
348 Routine Description:
349
350 TODO: Add function description
351
352 Arguments:
353
354 Private - TODO: add argument description
355
356 Returns:
357
358 TODO: add return values
359
360 --*/
361 {
362 EFI_STATUS Status;
363
364 Private->NtInHandle = Private->WinNtThunk->GetStdHandle (STD_INPUT_HANDLE);
365
366 Private->SimpleTextIn.Reset = WinNtSimpleTextInReset;
367 Private->SimpleTextIn.ReadKeyStroke = WinNtSimpleTextInReadKeyStroke;
368
369 Status = gBS->CreateEvent (
370 EVT_NOTIFY_WAIT,
371 TPL_NOTIFY,
372 WinNtSimpleTextInWaitForKey,
373 Private,
374 &Private->SimpleTextIn.WaitForKey
375 );
376 ASSERT_EFI_ERROR (Status);
377
378 return Status;
379 }