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