]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Nt32Pkg/WinNtGopDxe/WinNtGopInput.c
Fix some typo and coding style issues in BaseCryptLib instances.
[mirror_edk2.git] / Nt32Pkg / WinNtGopDxe / WinNtGopInput.c
... / ...
CommitLineData
1/** @file\r
2\r
3Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
4This 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 WinNtGopInput.c\r
15\r
16Abstract:\r
17\r
18 This file produces the Simple Text In for an Gop window.\r
19\r
20 This stuff is linked at the hip to the Window, since the window\r
21 processing is done in a thread kicked off in WinNtGopImplementation.c\r
22\r
23 Since the window information is processed in an other thread we need\r
24 a keyboard Queue to pass data about. The Simple Text In code just\r
25 takes data off the Queue. The WinProc message loop takes keyboard input\r
26 and places it in the Queue.\r
27\r
28\r
29**/\r
30\r
31\r
32#include "WinNtGop.h"\r
33\r
34\r
35/**\r
36 TODO: Add function description\r
37\r
38 @param Private TODO: add argument description\r
39\r
40 @retval EFI_SUCCESS TODO: Add description for return value\r
41\r
42**/\r
43EFI_STATUS\r
44GopPrivateCreateQ (\r
45 IN GOP_PRIVATE_DATA *Private,\r
46 IN GOP_QUEUE_FIXED *Queue\r
47 )\r
48{\r
49 Private->WinNtThunk->InitializeCriticalSection (&Queue->Cs);\r
50 Queue->Front = 0;\r
51 Queue->Rear = 0;\r
52 return EFI_SUCCESS;\r
53}\r
54\r
55\r
56/**\r
57 TODO: Add function description\r
58\r
59 @param Private TODO: add argument description\r
60\r
61 @retval EFI_SUCCESS TODO: Add description for return value\r
62\r
63**/\r
64EFI_STATUS\r
65GopPrivateDestroyQ (\r
66 IN GOP_PRIVATE_DATA *Private,\r
67 IN GOP_QUEUE_FIXED *Queue\r
68 )\r
69{\r
70 Queue->Front = 0;\r
71 Queue->Rear = 0;\r
72 Private->WinNtThunk->DeleteCriticalSection (&Queue->Cs);\r
73 return EFI_SUCCESS;\r
74}\r
75\r
76\r
77/**\r
78 TODO: Add function description\r
79\r
80 @param Private TODO: add argument description\r
81 @param Key TODO: add argument description\r
82\r
83 @retval EFI_NOT_READY TODO: Add description for return value\r
84 @retval EFI_SUCCESS TODO: Add description for return value\r
85\r
86**/\r
87EFI_STATUS\r
88GopPrivateAddQ (\r
89 IN GOP_PRIVATE_DATA *Private,\r
90 IN GOP_QUEUE_FIXED *Queue,\r
91 IN EFI_KEY_DATA *KeyData\r
92 )\r
93{\r
94 Private->WinNtThunk->EnterCriticalSection (&Queue->Cs);\r
95\r
96 if ((Queue->Rear + 1) % MAX_Q == Queue->Front) {\r
97 Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);\r
98 return EFI_NOT_READY;\r
99 }\r
100\r
101 CopyMem (&Queue->Q[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));\r
102 Queue->Rear = (Queue->Rear + 1) % MAX_Q;\r
103\r
104 Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);\r
105 return EFI_SUCCESS;\r
106}\r
107\r
108\r
109/**\r
110 TODO: Add function description\r
111\r
112 @param Private TODO: add argument description\r
113 @param Key TODO: add argument description\r
114\r
115 @retval EFI_NOT_READY TODO: Add description for return value\r
116 @retval EFI_SUCCESS TODO: Add description for return value\r
117\r
118**/\r
119EFI_STATUS\r
120GopPrivateDeleteQ (\r
121 IN GOP_PRIVATE_DATA *Private,\r
122 IN GOP_QUEUE_FIXED *Queue,\r
123 OUT EFI_KEY_DATA *Key\r
124 )\r
125{\r
126 Private->WinNtThunk->EnterCriticalSection (&Queue->Cs);\r
127\r
128 if (Queue->Front == Queue->Rear) {\r
129 Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);\r
130 return EFI_NOT_READY;\r
131 }\r
132\r
133 CopyMem (Key, &Queue->Q[Queue->Front], sizeof (EFI_KEY_DATA));\r
134 Queue->Front = (Queue->Front + 1) % MAX_Q;\r
135\r
136 if (Key->Key.ScanCode == SCAN_NULL && Key->Key.UnicodeChar == CHAR_NULL) {\r
137 if (!Private->IsPartialKeySupport) {\r
138 //\r
139 // If partial keystrok is not enabled, don't return the partial keystroke.\r
140 //\r
141 Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);\r
142 ZeroMem (Key, sizeof (EFI_KEY_DATA));\r
143 return EFI_NOT_READY;\r
144 }\r
145 }\r
146 Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);\r
147 return EFI_SUCCESS;\r
148}\r
149\r
150\r
151/**\r
152 TODO: Add function description\r
153\r
154 @param Private TODO: add argument description\r
155\r
156 @retval EFI_NOT_READY TODO: Add description for return value\r
157 @retval EFI_SUCCESS TODO: Add description for return value\r
158\r
159**/\r
160EFI_STATUS\r
161GopPrivateCheckQ (\r
162 IN GOP_QUEUE_FIXED *Queue\r
163 )\r
164{\r
165 if (Queue->Front == Queue->Rear) {\r
166 return EFI_NOT_READY;\r
167 }\r
168\r
169 return EFI_SUCCESS;\r
170}\r
171\r
172BOOLEAN\r
173GopPrivateIsKeyRegistered (\r
174 IN EFI_KEY_DATA *RegsiteredData,\r
175 IN EFI_KEY_DATA *InputData\r
176 )\r
177/*++\r
178\r
179Routine Description:\r
180\r
181Arguments:\r
182\r
183 RegsiteredData - A pointer to a buffer that is filled in with the keystroke\r
184 state data for the key that was registered.\r
185 InputData - A pointer to a buffer that is filled in with the keystroke\r
186 state data for the key that was pressed.\r
187\r
188Returns:\r
189 TRUE - Key be pressed matches a registered key.\r
190 FLASE - Match failed.\r
191\r
192--*/\r
193{\r
194 ASSERT (RegsiteredData != NULL && InputData != NULL);\r
195\r
196 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
197 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
198 return FALSE;\r
199 }\r
200\r
201 //\r
202 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
203 //\r
204 if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
205 RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
206 return FALSE;\r
207 }\r
208 if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
209 RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
210 return FALSE;\r
211 }\r
212\r
213 return TRUE;\r
214\r
215}\r
216\r
217\r
218VOID\r
219GopPrivateInvokeRegisteredFunction (\r
220 IN GOP_PRIVATE_DATA *Private,\r
221 IN EFI_KEY_DATA *KeyData\r
222 )\r
223/*++\r
224\r
225Routine Description:\r
226\r
227 This function updates the status light of NumLock, ScrollLock and CapsLock.\r
228\r
229Arguments:\r
230\r
231 Private - The private structure of WinNt Gop device.\r
232 KeyData - A pointer to a buffer that is filled in with the keystroke\r
233 state data for the key that was pressed.\r
234\r
235Returns:\r
236\r
237 EFI_SUCCESS - The status light is updated successfully.\r
238\r
239--*/\r
240{\r
241 LIST_ENTRY *Link;\r
242 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
243\r
244 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
245 CurrentNotify = CR (\r
246 Link,\r
247 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,\r
248 NotifyEntry,\r
249 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
250 );\r
251 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
252 CurrentNotify->KeyNotificationFn (KeyData);\r
253 }\r
254 }\r
255}\r
256\r
257VOID\r
258WinNtGopSimpleTextInTimerHandler (\r
259 IN EFI_EVENT Event,\r
260 IN VOID *Context\r
261 )\r
262{\r
263 GOP_PRIVATE_DATA *Private;\r
264 EFI_KEY_DATA KeyData;\r
265\r
266 Private = (GOP_PRIVATE_DATA *)Context;\r
267 while (GopPrivateDeleteQ (Private, &Private->QueueForNotify, &KeyData) == EFI_SUCCESS) {\r
268 GopPrivateInvokeRegisteredFunction (Private, &KeyData);\r
269 }\r
270}\r
271\r
272/**\r
273 TODO: Add function description\r
274\r
275 @param Private TODO: add argument description\r
276 @param Key TODO: add argument description\r
277\r
278 @retval EFI_NOT_READY TODO: Add description for return value\r
279 @retval EFI_SUCCESS TODO: Add description for return value\r
280\r
281**/\r
282EFI_STATUS\r
283GopPrivateAddKey (\r
284 IN GOP_PRIVATE_DATA *Private,\r
285 IN EFI_INPUT_KEY Key\r
286 )\r
287{\r
288 EFI_KEY_DATA KeyData;\r
289\r
290 KeyData.Key = Key;\r
291\r
292 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
293 KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
294\r
295 //\r
296 // Record Key shift state and toggle state\r
297 //\r
298 if (Private->LeftCtrl) {\r
299 KeyData.KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
300 }\r
301 if (Private->RightCtrl) {\r
302 KeyData.KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
303 }\r
304 if (Private->LeftAlt) {\r
305 KeyData.KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
306 }\r
307 if (Private->RightAlt) {\r
308 KeyData.KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
309 }\r
310 if (Private->LeftShift) {\r
311 KeyData.KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
312 }\r
313 if (Private->RightShift) {\r
314 KeyData.KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
315 }\r
316 if (Private->LeftLogo) {\r
317 KeyData.KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
318 }\r
319 if (Private->RightLogo) {\r
320 KeyData.KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
321 }\r
322 if (Private->Menu) {\r
323 KeyData.KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
324 }\r
325 if (Private->SysReq) {\r
326 KeyData.KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
327 }\r
328 if (Private->CapsLock) {\r
329 KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
330 }\r
331 if (Private->NumLock) {\r
332 KeyData.KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
333 }\r
334 if (Private->ScrollLock) {\r
335 KeyData.KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
336 }\r
337 if (Private->IsPartialKeySupport) {\r
338 KeyData.KeyState.KeyToggleState |= EFI_KEY_STATE_EXPOSED;\r
339 }\r
340\r
341 //\r
342 // Convert Ctrl+[1-26] to Ctrl+[A-Z]\r
343 //\r
344 if ((Private->LeftCtrl || Private->RightCtrl) &&\r
345 (KeyData.Key.UnicodeChar >= 1) && (KeyData.Key.UnicodeChar <= 26)\r
346 ) {\r
347 if ((Private->LeftShift || Private->RightShift) == Private->CapsLock) {\r
348 KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'a' - 1);\r
349 } else {\r
350 KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'A' - 1);\r
351 }\r
352 }\r
353\r
354 //\r
355 // Unmask the Shift bit for printable char\r
356 //\r
357 if (((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) ||\r
358 ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z'))\r
359 ) {\r
360 KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);\r
361 }\r
362\r
363 GopPrivateAddQ (Private, &Private->QueueForNotify, &KeyData);\r
364\r
365 GopPrivateAddQ (Private, &Private->QueueForRead, &KeyData);\r
366\r
367 return EFI_SUCCESS;\r
368}\r
369\r
370EFI_STATUS\r
371GopPrivateUpdateStatusLight (\r
372 IN GOP_PRIVATE_DATA *Private\r
373 )\r
374/*++\r
375\r
376Routine Description:\r
377\r
378 This function updates the status light of NumLock, ScrollLock and CapsLock.\r
379\r
380Arguments:\r
381\r
382 Private - The private structure of WinNt console In/Out.\r
383\r
384Returns:\r
385\r
386 EFI_SUCCESS - The status light is updated successfully.\r
387\r
388--*/\r
389{\r
390 //\r
391 // BUGBUG:Only SendInput/keybd_event function can toggle\r
392 // NumLock, CapsLock and ScrollLock keys.\r
393 // Neither of these functions is included in EFI_WIN_NT_THUNK_PROTOCOL.\r
394 // Thus, return immediately without operation.\r
395 //\r
396 return EFI_SUCCESS;\r
397\r
398}\r
399\r
400\r
401EFI_STATUS\r
402GopPrivateResetWorker (\r
403 IN GOP_PRIVATE_DATA *Private\r
404 )\r
405/*++\r
406\r
407Routine Description:\r
408\r
409 This function is a worker function for SimpleTextIn/SimpleTextInEx.Reset().\r
410\r
411Arguments:\r
412\r
413 Private - WinNT GOP private structure\r
414\r
415Returns:\r
416\r
417 EFI_SUCCESS - Reset successfully\r
418\r
419--*/\r
420{\r
421 EFI_KEY_DATA KeyData;\r
422 EFI_TPL OldTpl;\r
423\r
424 //\r
425 // Enter critical section\r
426 //\r
427 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
428\r
429 //\r
430 // A reset is draining the Queue\r
431 //\r
432 while (GopPrivateDeleteQ (Private, &Private->QueueForRead, &KeyData) == EFI_SUCCESS)\r
433 ;\r
434 while (GopPrivateDeleteQ (Private, &Private->QueueForNotify, &KeyData) == EFI_SUCCESS)\r
435 ;\r
436\r
437 Private->LeftShift = FALSE;\r
438 Private->RightShift = FALSE;\r
439 Private->LeftAlt = FALSE;\r
440 Private->RightAlt = FALSE;\r
441 Private->LeftCtrl = FALSE;\r
442 Private->RightCtrl = FALSE;\r
443 Private->LeftLogo = FALSE;\r
444 Private->RightLogo = FALSE;\r
445 Private->Menu = FALSE;\r
446 Private->SysReq = FALSE;\r
447\r
448 Private->CapsLock = FALSE;\r
449 Private->NumLock = FALSE;\r
450 Private->ScrollLock = FALSE;\r
451 Private->IsPartialKeySupport = FALSE;\r
452\r
453 Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
454 Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
455\r
456 //\r
457 // Leave critical section and return\r
458 //\r
459 gBS->RestoreTPL (OldTpl);\r
460\r
461 return EFI_SUCCESS;\r
462}\r
463\r
464EFI_STATUS\r
465GopPrivateReadKeyStrokeWorker (\r
466 IN GOP_PRIVATE_DATA *Private,\r
467 OUT EFI_KEY_DATA *KeyData\r
468 )\r
469/*++\r
470\r
471 Routine Description:\r
472 Reads the next keystroke from the input device. The WaitForKey Event can\r
473 be used to test for existance of a keystroke via WaitForEvent () call.\r
474\r
475 Arguments:\r
476 Private - The private structure of WinNt Gop device.\r
477 KeyData - A pointer to a buffer that is filled in with the keystroke\r
478 state data for the key that was pressed.\r
479\r
480 Returns:\r
481 EFI_SUCCESS - The keystroke information was returned.\r
482 EFI_NOT_READY - There was no keystroke data availiable.\r
483 EFI_DEVICE_ERROR - The keystroke information was not returned due to\r
484 hardware errors.\r
485 EFI_INVALID_PARAMETER - KeyData is NULL.\r
486\r
487--*/\r
488{\r
489 EFI_STATUS Status;\r
490 EFI_TPL OldTpl;\r
491\r
492 if (KeyData == NULL) {\r
493 return EFI_INVALID_PARAMETER;\r
494 }\r
495\r
496 //\r
497 // Enter critical section\r
498 //\r
499 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
500\r
501 //\r
502 // Call hot key callback before telling caller there is a key available\r
503 //\r
504 WinNtGopSimpleTextInTimerHandler (NULL, Private);\r
505\r
506 Status = GopPrivateCheckQ (&Private->QueueForRead);\r
507 if (!EFI_ERROR (Status)) {\r
508 //\r
509 // If a Key press exists try and read it.\r
510 //\r
511 Status = GopPrivateDeleteQ (Private, &Private->QueueForRead, KeyData);\r
512 if (!EFI_ERROR (Status)) {\r
513 //\r
514 // If partial keystroke is not enabled, check whether it is value key. If not return\r
515 // EFI_NOT_READY.\r
516 //\r
517 if (!Private->IsPartialKeySupport) {\r
518 if (KeyData->Key.ScanCode == SCAN_NULL && KeyData->Key.UnicodeChar == CHAR_NULL) {\r
519 Status = EFI_NOT_READY;\r
520 }\r
521 }\r
522 }\r
523 }\r
524\r
525 //\r
526 // Leave critical section and return\r
527 //\r
528 gBS->RestoreTPL (OldTpl);\r
529\r
530 return Status;\r
531\r
532}\r
533\r
534\r
535//\r
536// Simple Text In implementation.\r
537//\r
538\r
539\r
540/**\r
541 TODO: Add function description\r
542\r
543 @param This TODO: add argument description\r
544 @param ExtendedVerification TODO: add argument description\r
545\r
546 @retval EFI_SUCCESS TODO: Add description for return value\r
547\r
548**/\r
549EFI_STATUS\r
550EFIAPI\r
551WinNtGopSimpleTextInReset (\r
552 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
553 IN BOOLEAN ExtendedVerification\r
554 )\r
555{\r
556 GOP_PRIVATE_DATA *Private;\r
557\r
558 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
559\r
560 return GopPrivateResetWorker (Private);\r
561}\r
562\r
563\r
564/**\r
565 TODO: Add function description\r
566\r
567 @param This TODO: add argument description\r
568 @param Key TODO: add argument description\r
569\r
570 @return TODO: add return values\r
571\r
572**/\r
573EFI_STATUS\r
574EFIAPI\r
575WinNtGopSimpleTextInReadKeyStroke (\r
576 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
577 OUT EFI_INPUT_KEY *Key\r
578 )\r
579{\r
580 GOP_PRIVATE_DATA *Private;\r
581 EFI_STATUS Status;\r
582 EFI_KEY_DATA KeyData;\r
583\r
584 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
585 //\r
586 // Considering if the partial keystroke is enabled, there maybe a partial\r
587 // keystroke in the queue, so here skip the partial keystroke and get the\r
588 // next key from the queue\r
589 //\r
590 while (1) {\r
591 Status = GopPrivateReadKeyStrokeWorker (Private, &KeyData);\r
592 if (EFI_ERROR (Status)) {\r
593 return Status;\r
594 }\r
595 if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
596 continue;\r
597 }\r
598 //\r
599 // Convert Ctrl+[A-Z] to Ctrl+[1-26]\r
600 //\r
601 if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {\r
602 if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {\r
603 KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);\r
604 } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {\r
605 KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);\r
606 }\r
607 }\r
608 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
609 return EFI_SUCCESS;\r
610 } \r
611}\r
612\r
613\r
614/**\r
615 TODO: Add function description\r
616\r
617 @param Event TODO: add argument description\r
618 @param Context TODO: add argument description\r
619\r
620 @return TODO: add return values\r
621\r
622**/\r
623VOID\r
624EFIAPI\r
625WinNtGopSimpleTextInWaitForKey (\r
626 IN EFI_EVENT Event,\r
627 IN VOID *Context\r
628 )\r
629{\r
630 GOP_PRIVATE_DATA *Private;\r
631 EFI_STATUS Status;\r
632 EFI_TPL OldTpl;\r
633 EFI_KEY_DATA KeyData;\r
634\r
635 Private = (GOP_PRIVATE_DATA *) Context;\r
636\r
637 //\r
638 // Enter critical section\r
639 //\r
640 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
641\r
642 //\r
643 // Call hot key callback before telling caller there is a key available\r
644 //\r
645 WinNtGopSimpleTextInTimerHandler (NULL, Private);\r
646 \r
647 //\r
648 // WaitforKey doesn't suppor the partial key.\r
649 // Considering if the partial keystroke is enabled, there maybe a partial\r
650 // keystroke in the queue, so here skip the partial keystroke and get the\r
651 // next key from the queue\r
652 //\r
653 while (1) {\r
654 Status = GopPrivateCheckQ (&Private->QueueForRead);\r
655 if (!EFI_ERROR (Status)) {\r
656 //\r
657 // If a there is a key in the queue and it is not partial keystroke, signal event.\r
658 //\r
659 if (Private->QueueForRead.Q[Private->QueueForRead.Front].Key.ScanCode == SCAN_NULL &&\r
660 Private->QueueForRead.Q[Private->QueueForRead.Front].Key.UnicodeChar == CHAR_NULL) {\r
661 GopPrivateDeleteQ (Private,&Private->QueueForRead,&KeyData);\r
662 continue;\r
663 }\r
664 gBS->SignalEvent (Event);\r
665 } else {\r
666 //\r
667 // We need to sleep or NT will schedule this thread with such high\r
668 // priority that WinProc thread will never run and we will not see\r
669 // keyboard input. This Sleep makes the syste run 10x faster, so don't\r
670 // remove it.\r
671 //\r
672 Private->WinNtThunk->Sleep (1);\r
673 }\r
674 break;\r
675 }\r
676\r
677 //\r
678 // Leave critical section and return\r
679 //\r
680 gBS->RestoreTPL (OldTpl);\r
681}\r
682\r
683//\r
684// Simple Text Input Ex protocol functions\r
685//\r
686\r
687EFI_STATUS\r
688EFIAPI\r
689WinNtGopSimpleTextInExResetEx (\r
690 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
691 IN BOOLEAN ExtendedVerification\r
692 )\r
693/*++\r
694\r
695 Routine Description:\r
696 Reset the input device and optionaly run diagnostics\r
697\r
698 Arguments:\r
699 This - Protocol instance pointer.\r
700 ExtendedVerification - Driver may perform diagnostics on reset.\r
701\r
702 Returns:\r
703 EFI_SUCCESS - The device was reset.\r
704\r
705--*/\r
706{\r
707 GOP_PRIVATE_DATA *Private;\r
708\r
709 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
710\r
711 return GopPrivateResetWorker (Private);\r
712}\r
713\r
714EFI_STATUS\r
715EFIAPI\r
716WinNtGopSimpleTextInExReadKeyStrokeEx (\r
717 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
718 OUT EFI_KEY_DATA *KeyData\r
719 )\r
720/*++\r
721\r
722 Routine Description:\r
723 Reads the next keystroke from the input device. The WaitForKey Event can\r
724 be used to test for existance of a keystroke via WaitForEvent () call.\r
725\r
726 Arguments:\r
727 This - Protocol instance pointer.\r
728 KeyData - A pointer to a buffer that is filled in with the keystroke\r
729 state data for the key that was pressed.\r
730\r
731 Returns:\r
732 EFI_SUCCESS - The keystroke information was returned.\r
733 EFI_NOT_READY - There was no keystroke data availiable.\r
734 EFI_DEVICE_ERROR - The keystroke information was not returned due to\r
735 hardware errors.\r
736 EFI_INVALID_PARAMETER - KeyData is NULL.\r
737\r
738--*/\r
739{\r
740 GOP_PRIVATE_DATA *Private;\r
741\r
742 if (KeyData == NULL) {\r
743 return EFI_INVALID_PARAMETER;\r
744 }\r
745\r
746 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
747\r
748 return GopPrivateReadKeyStrokeWorker (Private, KeyData);\r
749\r
750}\r
751\r
752EFI_STATUS\r
753EFIAPI\r
754WinNtGopSimpleTextInExSetState (\r
755 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
756 IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
757 )\r
758/*++\r
759\r
760 Routine Description:\r
761 Set certain state for the input device.\r
762\r
763 Arguments:\r
764 This - Protocol instance pointer.\r
765 KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
766 state for the input device.\r
767\r
768 Returns:\r
769 EFI_SUCCESS - The device state was set successfully.\r
770 EFI_DEVICE_ERROR - The device is not functioning correctly and could\r
771 not have the setting adjusted.\r
772 EFI_UNSUPPORTED - The device does not have the ability to set its state.\r
773 EFI_INVALID_PARAMETER - KeyToggleState is NULL.\r
774\r
775--*/\r
776{\r
777 EFI_STATUS Status;\r
778 GOP_PRIVATE_DATA *Private;\r
779\r
780 if (KeyToggleState == NULL) {\r
781 return EFI_INVALID_PARAMETER;\r
782 }\r
783\r
784 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
785\r
786 if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||\r
787 ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {\r
788 return EFI_UNSUPPORTED;\r
789 }\r
790\r
791 Private->ScrollLock = FALSE;\r
792 Private->NumLock = FALSE;\r
793 Private->CapsLock = FALSE;\r
794 Private->IsPartialKeySupport = FALSE;\r
795\r
796 if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
797 Private->ScrollLock = TRUE;\r
798 }\r
799 if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
800 Private->NumLock = TRUE;\r
801 }\r
802 if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
803 Private->CapsLock = TRUE;\r
804 }\r
805 if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {\r
806 Private->IsPartialKeySupport = TRUE;\r
807 }\r
808\r
809 Status = GopPrivateUpdateStatusLight (Private);\r
810 if (EFI_ERROR (Status)) {\r
811 return EFI_DEVICE_ERROR;\r
812 }\r
813\r
814 Private->KeyState.KeyToggleState = *KeyToggleState;\r
815 return EFI_SUCCESS;\r
816\r
817}\r
818\r
819EFI_STATUS\r
820EFIAPI\r
821WinNtGopSimpleTextInExRegisterKeyNotify (\r
822 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
823 IN EFI_KEY_DATA *KeyData,\r
824 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
825 OUT EFI_HANDLE *NotifyHandle\r
826 )\r
827/*++\r
828\r
829 Routine Description:\r
830 Register a notification function for a particular keystroke for the input device.\r
831\r
832 Arguments:\r
833 This - Protocol instance pointer.\r
834 KeyData - A pointer to a buffer that is filled in with the keystroke\r
835 information data for the key that was pressed.\r
836 KeyNotificationFunction - Points to the function to be called when the key\r
837 sequence is typed specified by KeyData.\r
838 NotifyHandle - Points to the unique handle assigned to the registered notification.\r
839\r
840 Returns:\r
841 EFI_SUCCESS - The notification function was registered successfully.\r
842 EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.\r
843 EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.\r
844\r
845--*/\r
846{\r
847 GOP_PRIVATE_DATA *Private;\r
848 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
849 LIST_ENTRY *Link;\r
850 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify;\r
851\r
852 if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) {\r
853 return EFI_INVALID_PARAMETER;\r
854 }\r
855\r
856 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
857\r
858 //\r
859 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
860 //\r
861 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
862 CurrentNotify = CR (\r
863 Link,\r
864 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,\r
865 NotifyEntry,\r
866 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
867 );\r
868 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
869 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
870 *NotifyHandle = CurrentNotify->NotifyHandle;\r
871 return EFI_SUCCESS;\r
872 }\r
873 }\r
874 }\r
875\r
876 //\r
877 // Allocate resource to save the notification function\r
878 //\r
879 NewNotify = (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY));\r
880 if (NewNotify == NULL) {\r
881 return EFI_OUT_OF_RESOURCES;\r
882 }\r
883\r
884 NewNotify->Signature = WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;\r
885 NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
886 NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;\r
887 CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
888 InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);\r
889\r
890 *NotifyHandle = NewNotify->NotifyHandle;\r
891\r
892 return EFI_SUCCESS;\r
893\r
894}\r
895\r
896EFI_STATUS\r
897EFIAPI\r
898WinNtGopSimpleTextInExUnregisterKeyNotify (\r
899 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
900 IN EFI_HANDLE NotificationHandle\r
901 )\r
902/*++\r
903\r
904 Routine Description:\r
905 Remove a registered notification function from a particular keystroke.\r
906\r
907 Arguments:\r
908 This - Protocol instance pointer.\r
909 NotificationHandle - The handle of the notification function being unregistered.\r
910\r
911 Returns:\r
912 EFI_SUCCESS - The notification function was unregistered successfully.\r
913 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.\r
914\r
915--*/\r
916{\r
917 GOP_PRIVATE_DATA *Private;\r
918 LIST_ENTRY *Link;\r
919 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
920\r
921 if (NotificationHandle == NULL) {\r
922 return EFI_INVALID_PARAMETER;\r
923 }\r
924\r
925 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
926\r
927 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
928 CurrentNotify = CR (\r
929 Link,\r
930 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,\r
931 NotifyEntry,\r
932 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
933 );\r
934 if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
935 //\r
936 // Remove the notification function from NotifyList and free resources\r
937 //\r
938 RemoveEntryList (&CurrentNotify->NotifyEntry);\r
939\r
940 gBS->FreePool (CurrentNotify);\r
941 return EFI_SUCCESS;\r
942 }\r
943 }\r
944\r
945 //\r
946 // Can not find the specified Notification Handle\r
947 //\r
948 return EFI_INVALID_PARAMETER;\r
949}\r
950\r
951\r
952/**\r
953 TODO: Add function description\r
954\r
955 @param Private TODO: add argument description\r
956\r
957 @return TODO: add return values\r
958\r
959**/\r
960EFI_STATUS\r
961WinNtGopInitializeSimpleTextInForWindow (\r
962 IN GOP_PRIVATE_DATA *Private\r
963 )\r
964{\r
965 EFI_STATUS Status;\r
966\r
967 GopPrivateCreateQ (Private, &Private->QueueForRead);\r
968 GopPrivateCreateQ (Private, &Private->QueueForNotify);\r
969\r
970 //\r
971 // Initialize Simple Text In protoocol\r
972 //\r
973 Private->SimpleTextIn.Reset = WinNtGopSimpleTextInReset;\r
974 Private->SimpleTextIn.ReadKeyStroke = WinNtGopSimpleTextInReadKeyStroke;\r
975\r
976 Status = gBS->CreateEvent (\r
977 EVT_NOTIFY_WAIT,\r
978 TPL_NOTIFY,\r
979 WinNtGopSimpleTextInWaitForKey,\r
980 Private,\r
981 &Private->SimpleTextIn.WaitForKey\r
982 );\r
983\r
984\r
985 Private->SimpleTextInEx.Reset = WinNtGopSimpleTextInExResetEx;\r
986 Private->SimpleTextInEx.ReadKeyStrokeEx = WinNtGopSimpleTextInExReadKeyStrokeEx;\r
987 Private->SimpleTextInEx.SetState = WinNtGopSimpleTextInExSetState;\r
988 Private->SimpleTextInEx.RegisterKeyNotify = WinNtGopSimpleTextInExRegisterKeyNotify;\r
989 Private->SimpleTextInEx.UnregisterKeyNotify = WinNtGopSimpleTextInExUnregisterKeyNotify;\r
990\r
991 Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);\r
992\r
993 InitializeListHead (&Private->NotifyList);\r
994\r
995 Status = gBS->CreateEvent (\r
996 EVT_NOTIFY_WAIT,\r
997 TPL_NOTIFY,\r
998 WinNtGopSimpleTextInWaitForKey,\r
999 Private,\r
1000 &Private->SimpleTextInEx.WaitForKeyEx\r
1001 );\r
1002 ASSERT_EFI_ERROR (Status);\r
1003\r
1004 //\r
1005 // Create the Timer to trigger hot key notifications\r
1006 //\r
1007 Status = gBS->CreateEvent (\r
1008 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
1009 TPL_NOTIFY,\r
1010 WinNtGopSimpleTextInTimerHandler,\r
1011 Private,\r
1012 &Private->TimerEvent\r
1013 );\r
1014 ASSERT_EFI_ERROR (Status);\r
1015\r
1016 Status = gBS->SetTimer (\r
1017 Private->TimerEvent,\r
1018 TimerPeriodic,\r
1019 KEYBOARD_TIMER_INTERVAL\r
1020 );\r
1021 ASSERT_EFI_ERROR (Status);\r
1022\r
1023 return Status;\r
1024}\r
1025\r
1026\r
1027\r
1028/**\r
1029 TODO: Add function description\r
1030\r
1031 @param Private TODO: add argument description\r
1032\r
1033 @retval EFI_SUCCESS TODO: Add description for return value\r
1034\r
1035**/\r
1036EFI_STATUS\r
1037WinNtGopDestroySimpleTextInForWindow (\r
1038 IN GOP_PRIVATE_DATA *Private\r
1039 )\r
1040{\r
1041 gBS->CloseEvent (Private->TimerEvent);\r
1042\r
1043 GopPrivateDestroyQ (Private, &Private->QueueForRead);\r
1044 GopPrivateDestroyQ (Private, &Private->QueueForNotify);\r
1045\r
1046 return EFI_SUCCESS;\r
1047}\r