]> git.proxmox.com Git - mirror_edk2.git/blame - EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ConsoleIn.c
Add some definitions for efi event in Uefi/UefiSpec.h to follow spec.
[mirror_edk2.git] / EdkNt32Pkg / Dxe / WinNtThunk / Bus / Console / ConsoleIn.c
CommitLineData
878ddf1f 1/*++\r
2\r
fa332de7 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
878ddf1f 11\r
12Module Name:\r
13\r
14 ConsoleIn.c\r
15\r
16Abstract:\r
17\r
fa332de7 18 Console based on Win32 APIs.\r
878ddf1f 19\r
20 This file attaches a SimpleTextIn protocol to a previously open window.\r
fa332de7 21\r
878ddf1f 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
fa332de7 24 Thus this code must run after the constructor for the SimpleTextOut\r
878ddf1f 25 protocol\r
fa332de7 26\r
878ddf1f 27--*/\r
28\r
29#include "Console.h"\r
30\r
31//\r
32// Private worker functions\r
33//\r
34STATIC\r
35EFI_STATUS\r
36WinNtSimpleTextInCheckKey (\r
37 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private\r
38 );\r
39\r
40EFI_STATUS\r
41EFIAPI\r
42WinNtSimpleTextInReset (\r
43 IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,\r
44 IN BOOLEAN ExtendedVerification\r
45 )\r
46/*++\r
47\r
48Routine Description:\r
49\r
50 TODO: Add function description\r
51\r
52Arguments:\r
53\r
54 This - TODO: add argument description\r
55 ExtendedVerification - TODO: add argument description\r
56\r
57Returns:\r
58\r
59 EFI_SUCCESS - TODO: Add description for return value\r
60\r
61--*/\r
62{\r
63 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;\r
64\r
65 Private = WIN_NT_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS (This);\r
66 return EFI_SUCCESS;\r
67}\r
68\r
69STATIC\r
70EFI_STATUS\r
71WinNtConvertInputRecordToEfiKey (\r
72 IN INPUT_RECORD *InputRecord,\r
73 OUT EFI_INPUT_KEY *Key\r
74 )\r
75/*++\r
76\r
77Routine Description:\r
78\r
79 TODO: Add function description\r
80\r
81Arguments:\r
82\r
83 InputRecord - TODO: add argument description\r
84 Key - TODO: add argument description\r
85\r
86Returns:\r
87\r
88 EFI_NOT_READY - TODO: Add description for return value\r
89 EFI_NOT_READY - TODO: Add description for return value\r
90 EFI_NOT_READY - TODO: Add description for return value\r
91 EFI_SUCCESS - TODO: Add description for return value\r
92\r
93--*/\r
94{\r
95 //\r
96 // Make sure InputRecord is an event that represents a keypress\r
97 //\r
98 if (InputRecord->EventType == KEY_EVENT) {\r
99 if (!InputRecord->Event.KeyEvent.bKeyDown) {\r
100 return EFI_NOT_READY;\r
101 }\r
102 } else {\r
103 return EFI_NOT_READY;\r
104 }\r
fa332de7 105\r
878ddf1f 106 //\r
107 // Check to see if we should return a scan code in place of Unicode character.\r
108 //\r
109 Key->ScanCode = 0;\r
110 Key->UnicodeChar = 0;\r
111 if ((InputRecord->Event.KeyEvent.dwControlKeyState & (NUMLOCK_ON | ENHANCED_KEY)) != NUMLOCK_ON) {\r
112 //\r
113 // Only check these scan codes if num lock is off.\r
114 //\r
115 switch (InputRecord->Event.KeyEvent.wVirtualScanCode) {\r
116 case 0x48: Key->ScanCode = SCAN_UP; break;\r
117 case 0x50: Key->ScanCode = SCAN_DOWN; break;\r
118 case 0x4d: Key->ScanCode = SCAN_RIGHT; break;\r
119 case 0x4b: Key->ScanCode = SCAN_LEFT; break;\r
120 case 0x47: Key->ScanCode = SCAN_HOME; break;\r
121 case 0x4F: Key->ScanCode = SCAN_END; break;\r
122 case 0x52: Key->ScanCode = SCAN_INSERT; break;\r
123 case 0x53: Key->ScanCode = SCAN_DELETE; break;\r
124 case 0x49: Key->ScanCode = SCAN_PAGE_UP; break;\r
125 case 0x51: Key->ScanCode = SCAN_PAGE_DOWN; break;\r
126 }\r
127 }\r
128\r
129 switch (InputRecord->Event.KeyEvent.wVirtualScanCode) {\r
130 case 0x3b: Key->ScanCode = SCAN_F1; break;\r
131 case 0x3c: Key->ScanCode = SCAN_F2; break;\r
132 case 0x3d: Key->ScanCode = SCAN_F3; break;\r
133 case 0x3e: Key->ScanCode = SCAN_F4; break;\r
134 case 0x3f: Key->ScanCode = SCAN_F5; break;\r
135 case 0x40: Key->ScanCode = SCAN_F6; break;\r
136 case 0x41: Key->ScanCode = SCAN_F7; break;\r
137 case 0x42: Key->ScanCode = SCAN_F8; break;\r
138 case 0x43: Key->ScanCode = SCAN_F9; break;\r
139 case 0x44: Key->ScanCode = SCAN_F10; break;\r
140 case 0x01: Key->ScanCode = SCAN_ESC; break;\r
141 }\r
142\r
143 //\r
144 // If there's a scan code pass it, and don't pass the char code\r
145 //\r
146 if (Key->ScanCode == 0) {\r
147 Key->UnicodeChar = InputRecord->Event.KeyEvent.uChar.UnicodeChar;\r
148 if (Key->UnicodeChar == 0) {\r
149 return EFI_NOT_READY;\r
150 }\r
151 }\r
152\r
153 return EFI_SUCCESS;\r
154}\r
155\r
156STATIC\r
157EFI_STATUS\r
158EFIAPI\r
159WinNtSimpleTextInReadKeyStroke (\r
160 IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,\r
161 OUT EFI_INPUT_KEY *Key\r
162 )\r
163/*++\r
164\r
165Routine Description:\r
166\r
167 TODO: Add function description\r
168\r
169Arguments:\r
170\r
171 This - TODO: add argument description\r
172 Key - TODO: add argument description\r
173\r
174Returns:\r
175\r
176 EFI_DEVICE_ERROR - TODO: Add description for return value\r
177 EFI_NOT_READY - TODO: Add description for return value\r
178\r
179--*/\r
180{\r
181 EFI_STATUS Status;\r
182 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;\r
183 INPUT_RECORD InputRecord;\r
184 DWORD NtEventCount;\r
185\r
186 Private = WIN_NT_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS (This);\r
187\r
188 Status = WinNtSimpleTextInCheckKey (Private);\r
189 if (EFI_ERROR (Status)) {\r
190 return Status;\r
191 }\r
192\r
193 do {\r
194\r
195 if (!Private->WinNtThunk->ReadConsoleInput (Private->NtInHandle, &InputRecord, 1, &NtEventCount)) {\r
196 return EFI_DEVICE_ERROR;\r
197 }\r
198\r
199 if (NtEventCount == 0) {\r
200 return EFI_NOT_READY;\r
201 }\r
202\r
203 //\r
204 // Convert the Input Record to an EFI Keystroke.\r
205 //\r
206 Status = WinNtConvertInputRecordToEfiKey (&InputRecord, Key);\r
207 } while (EFI_ERROR (Status));\r
208\r
209 return Status;\r
210}\r
211\r
212STATIC\r
213VOID\r
214EFIAPI\r
215WinNtSimpleTextInWaitForKey (\r
216 IN EFI_EVENT Event,\r
217 IN VOID *Context\r
218 )\r
219/*++\r
220\r
221Routine Description:\r
222\r
223 TODO: Add function description\r
224\r
225Arguments:\r
226\r
227 Event - TODO: add argument description\r
228 Context - TODO: add argument description\r
229\r
230Returns:\r
231\r
232 TODO: add return values\r
233\r
234--*/\r
235{\r
236 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;\r
237 EFI_STATUS Status;\r
238\r
239 Private = (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *) Context;\r
240 Status = WinNtSimpleTextInCheckKey (Private);\r
241 if (!EFI_ERROR (Status)) {\r
242 gBS->SignalEvent (Event);\r
243 }\r
244}\r
245\r
246STATIC\r
247EFI_STATUS\r
248WinNtSimpleTextInCheckKey (\r
249 WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private\r
250 )\r
251/*++\r
252\r
253Routine Description:\r
254\r
255 TODO: Add function description\r
256\r
257Arguments:\r
258\r
259 Private - TODO: add argument description\r
260\r
261Returns:\r
262\r
263 TODO: add return values\r
264\r
265--*/\r
266{\r
267 INPUT_RECORD *InputRecord;\r
268 DWORD NtEventCount;\r
269 DWORD ActualNtEventCount;\r
270 EFI_STATUS Status;\r
271 BOOLEAN Success;\r
272 UINTN Index;\r
273 EFI_INPUT_KEY Key;\r
274\r
275 InputRecord = NULL;\r
276 NtEventCount = 0;\r
277 Private->WinNtThunk->GetNumberOfConsoleInputEvents (Private->NtInHandle, &NtEventCount);\r
278 if (NtEventCount == 0) {\r
279 Status = EFI_NOT_READY;\r
280 goto Done;\r
281 }\r
282\r
fa332de7 283 InputRecord = AllocatePool (sizeof (INPUT_RECORD) * NtEventCount);\r
284 if (InputRecord == NULL) {\r
878ddf1f 285 Status = EFI_NOT_READY;\r
286 goto Done;\r
287 }\r
288\r
289 Success = (BOOLEAN) Private->WinNtThunk->PeekConsoleInput (\r
290 Private->NtInHandle,\r
291 InputRecord,\r
292 NtEventCount,\r
293 &ActualNtEventCount\r
294 );\r
295 if (!Success) {\r
296 Status = EFI_NOT_READY;\r
297 goto Done;\r
298 }\r
299\r
300 Status = EFI_NOT_READY;\r
301 for (Index = 0; Index < (UINTN) ActualNtEventCount; Index++) {\r
302 //\r
303 // Convert the Input Record to an EFI Keystroke.\r
304 //\r
305 Status = WinNtConvertInputRecordToEfiKey (&InputRecord[Index], &Key);\r
306 if (!EFI_ERROR (Status)) {\r
307 Status = EFI_SUCCESS;\r
308 goto Done;\r
309 }\r
310 }\r
311\r
312Done:\r
313 if (InputRecord != NULL) {\r
fa332de7 314 FreePool (InputRecord);\r
878ddf1f 315 }\r
316\r
317 return Status;\r
318}\r
319\r
320EFI_STATUS\r
321WinNtSimpleTextInAttachToWindow (\r
322 IN WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private\r
323 )\r
324/*++\r
325\r
326Routine Description:\r
327\r
328 TODO: Add function description\r
329\r
330Arguments:\r
331\r
332 Private - TODO: add argument description\r
333\r
334Returns:\r
335\r
336 TODO: add return values\r
337\r
338--*/\r
339{\r
340 EFI_STATUS Status;\r
341\r
342 Private->NtInHandle = Private->WinNtThunk->GetStdHandle (STD_INPUT_HANDLE);\r
343\r
344 Private->SimpleTextIn.Reset = WinNtSimpleTextInReset;\r
345 Private->SimpleTextIn.ReadKeyStroke = WinNtSimpleTextInReadKeyStroke;\r
346\r
347 Status = gBS->CreateEvent (\r
93b0fbc8 348 EVT_NOTIFY_WAIT,\r
349 TPL_NOTIFY,\r
878ddf1f 350 WinNtSimpleTextInWaitForKey,\r
351 Private,\r
352 &Private->SimpleTextIn.WaitForKey\r
353 );\r
354 ASSERT_EFI_ERROR (Status);\r
355\r
356 return Status;\r
357}\r