]> git.proxmox.com Git - mirror_edk2.git/blame - EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ConsoleIn.c
Fix VS 2005 compatibility issue
[mirror_edk2.git] / EdkNt32Pkg / Dxe / WinNtThunk / Bus / Console / ConsoleIn.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, 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#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
105 \r
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
283 Status = gBS->AllocatePool (\r
284 EfiBootServicesData,\r
285 sizeof (INPUT_RECORD) * NtEventCount,\r
286 &InputRecord\r
287 );\r
288 if (EFI_ERROR (Status)) {\r
289 Status = EFI_NOT_READY;\r
290 goto Done;\r
291 }\r
292\r
293 Success = (BOOLEAN) Private->WinNtThunk->PeekConsoleInput (\r
294 Private->NtInHandle,\r
295 InputRecord,\r
296 NtEventCount,\r
297 &ActualNtEventCount\r
298 );\r
299 if (!Success) {\r
300 Status = EFI_NOT_READY;\r
301 goto Done;\r
302 }\r
303\r
304 Status = EFI_NOT_READY;\r
305 for (Index = 0; Index < (UINTN) ActualNtEventCount; Index++) {\r
306 //\r
307 // Convert the Input Record to an EFI Keystroke.\r
308 //\r
309 Status = WinNtConvertInputRecordToEfiKey (&InputRecord[Index], &Key);\r
310 if (!EFI_ERROR (Status)) {\r
311 Status = EFI_SUCCESS;\r
312 goto Done;\r
313 }\r
314 }\r
315\r
316Done:\r
317 if (InputRecord != NULL) {\r
318 gBS->FreePool (InputRecord);\r
319 }\r
320\r
321 return Status;\r
322}\r
323\r
324EFI_STATUS\r
325WinNtSimpleTextInAttachToWindow (\r
326 IN WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private\r
327 )\r
328/*++\r
329\r
330Routine Description:\r
331\r
332 TODO: Add function description\r
333\r
334Arguments:\r
335\r
336 Private - TODO: add argument description\r
337\r
338Returns:\r
339\r
340 TODO: add return values\r
341\r
342--*/\r
343{\r
344 EFI_STATUS Status;\r
345\r
346 Private->NtInHandle = Private->WinNtThunk->GetStdHandle (STD_INPUT_HANDLE);\r
347\r
348 Private->SimpleTextIn.Reset = WinNtSimpleTextInReset;\r
349 Private->SimpleTextIn.ReadKeyStroke = WinNtSimpleTextInReadKeyStroke;\r
350\r
351 Status = gBS->CreateEvent (\r
352 EFI_EVENT_NOTIFY_WAIT,\r
353 EFI_TPL_NOTIFY,\r
354 WinNtSimpleTextInWaitForKey,\r
355 Private,\r
356 &Private->SimpleTextIn.WaitForKey\r
357 );\r
358 ASSERT_EFI_ERROR (Status);\r
359\r
360 return Status;\r
361}\r