TianoCore EDK2 master
Loading...
Searching...
No Matches
VirtualKeyboard.c
Go to the documentation of this file.
1
11#include "VirtualKeyboard.h"
12
13//
14// RAM Keyboard Driver Binding Protocol Instance
15//
16EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding = {
20 0x10,
21 NULL,
22 NULL
23};
24
25//
26// EFI Driver Binding Protocol Functions
27//
28
41EFIAPI
44 IN EFI_HANDLE Controller,
45 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
46 )
47{
48 EFI_STATUS Status;
49 PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual;
50
51 Status = gBS->OpenProtocol (
52 Controller,
53 &gPlatformVirtualKeyboardProtocolGuid,
54 (VOID **)&PlatformVirtual,
55 This->DriverBindingHandle,
56 Controller,
57 EFI_OPEN_PROTOCOL_BY_DRIVER
58 );
59 if (EFI_ERROR (Status)) {
60 return Status;
61 }
62
63 gBS->CloseProtocol (
64 Controller,
65 &gPlatformVirtualKeyboardProtocolGuid,
66 This->DriverBindingHandle,
67 Controller
68 );
69 return Status;
70}
71
85EFIAPI
88 IN EFI_HANDLE Controller,
89 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
90 )
91{
92 EFI_STATUS Status;
93 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
94 PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual;
95
96 Status = gBS->OpenProtocol (
97 Controller,
98 &gPlatformVirtualKeyboardProtocolGuid,
99 (VOID **)&PlatformVirtual,
100 This->DriverBindingHandle,
101 Controller,
102 EFI_OPEN_PROTOCOL_BY_DRIVER
103 );
104 if (EFI_ERROR (Status)) {
105 return Status;
106 }
107
108 //
109 // Allocate the private device structure
110 //
111 VirtualKeyboardPrivate = (VIRTUAL_KEYBOARD_DEV *)AllocateZeroPool (sizeof (VIRTUAL_KEYBOARD_DEV));
112 if (VirtualKeyboardPrivate == NULL) {
113 Status = EFI_OUT_OF_RESOURCES;
114 goto Done;
115 }
116
117 //
118 // Initialize the private device structure
119 //
120 VirtualKeyboardPrivate->Signature = VIRTUAL_KEYBOARD_DEV_SIGNATURE;
121 VirtualKeyboardPrivate->Handle = Controller;
122 VirtualKeyboardPrivate->PlatformVirtual = PlatformVirtual;
123 VirtualKeyboardPrivate->Queue.Front = 0;
124 VirtualKeyboardPrivate->Queue.Rear = 0;
125 VirtualKeyboardPrivate->QueueForNotify.Front = 0;
126 VirtualKeyboardPrivate->QueueForNotify.Rear = 0;
127
128 VirtualKeyboardPrivate->SimpleTextIn.Reset = VirtualKeyboardReset;
129 VirtualKeyboardPrivate->SimpleTextIn.ReadKeyStroke = VirtualKeyboardReadKeyStroke;
130
131 VirtualKeyboardPrivate->SimpleTextInputEx.Reset = VirtualKeyboardResetEx;
132 VirtualKeyboardPrivate->SimpleTextInputEx.ReadKeyStrokeEx = VirtualKeyboardReadKeyStrokeEx;
133 VirtualKeyboardPrivate->SimpleTextInputEx.SetState = VirtualKeyboardSetState;
134
135 VirtualKeyboardPrivate->SimpleTextInputEx.RegisterKeyNotify = VirtualKeyboardRegisterKeyNotify;
136 VirtualKeyboardPrivate->SimpleTextInputEx.UnregisterKeyNotify = VirtualKeyboardUnregisterKeyNotify;
137 InitializeListHead (&VirtualKeyboardPrivate->NotifyList);
138
139 Status = PlatformVirtual->Register ();
140 if (EFI_ERROR (Status)) {
141 goto Done;
142 }
143
144 //
145 // Report that the keyboard is being enabled
146 //
149 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE
150 );
151
152 //
153 // Setup the WaitForKey event
154 //
155 Status = gBS->CreateEvent (
156 EVT_NOTIFY_WAIT,
157 TPL_NOTIFY,
159 &(VirtualKeyboardPrivate->SimpleTextIn),
160 &((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey)
161 );
162 if (EFI_ERROR (Status)) {
163 (VirtualKeyboardPrivate->SimpleTextIn).WaitForKey = NULL;
164 goto Done;
165 }
166
167 Status = gBS->CreateEvent (
168 EVT_NOTIFY_WAIT,
169 TPL_NOTIFY,
171 &(VirtualKeyboardPrivate->SimpleTextInputEx),
172 &(VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx)
173 );
174 if (EFI_ERROR (Status)) {
175 VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx = NULL;
176 goto Done;
177 }
178
179 //
180 // Setup a periodic timer, used for reading keystrokes at a fixed interval
181 //
182 Status = gBS->CreateEvent (
183 EVT_TIMER | EVT_NOTIFY_SIGNAL,
184 TPL_NOTIFY,
186 VirtualKeyboardPrivate,
187 &VirtualKeyboardPrivate->TimerEvent
188 );
189 if (EFI_ERROR (Status)) {
190 Status = EFI_OUT_OF_RESOURCES;
191 goto Done;
192 }
193
194 Status = gBS->SetTimer (
195 VirtualKeyboardPrivate->TimerEvent,
197 KEYBOARD_TIMER_INTERVAL
198 );
199 if (EFI_ERROR (Status)) {
200 Status = EFI_OUT_OF_RESOURCES;
201 goto Done;
202 }
203
204 Status = gBS->CreateEvent (
205 EVT_NOTIFY_SIGNAL,
206 TPL_CALLBACK,
208 VirtualKeyboardPrivate,
209 &VirtualKeyboardPrivate->KeyNotifyProcessEvent
210 );
211 if (EFI_ERROR (Status)) {
212 Status = EFI_OUT_OF_RESOURCES;
213 goto Done;
214 }
215
216 //
217 // Reset the keyboard device
218 //
219 Status = VirtualKeyboardPrivate->SimpleTextInputEx.Reset (
220 &VirtualKeyboardPrivate->SimpleTextInputEx,
221 FALSE
222 );
223 if (EFI_ERROR (Status)) {
224 DEBUG ((DEBUG_ERROR, "[KBD]Reset Failed. Status - %r\n", Status));
225 goto Done;
226 }
227
228 //
229 // Install protocol interfaces for the keyboard device.
230 //
231 Status = gBS->InstallMultipleProtocolInterfaces (
232 &Controller,
233 &gEfiSimpleTextInProtocolGuid,
234 &VirtualKeyboardPrivate->SimpleTextIn,
235 &gEfiSimpleTextInputExProtocolGuid,
236 &VirtualKeyboardPrivate->SimpleTextInputEx,
237 NULL
238 );
239
240Done:
241 if (EFI_ERROR (Status)) {
242 if (VirtualKeyboardPrivate != NULL) {
243 if ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey != NULL) {
244 gBS->CloseEvent ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey);
245 }
246
247 if ((VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx != NULL) {
248 gBS->CloseEvent (
249 (VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx
250 );
251 }
252
253 if (VirtualKeyboardPrivate->KeyNotifyProcessEvent != NULL) {
254 gBS->CloseEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent);
255 }
256
257 VirtualKeyboardFreeNotifyList (&VirtualKeyboardPrivate->NotifyList);
258
259 if (VirtualKeyboardPrivate->TimerEvent != NULL) {
260 gBS->CloseEvent (VirtualKeyboardPrivate->TimerEvent);
261 }
262
263 FreePool (VirtualKeyboardPrivate);
264 }
265 }
266
267 gBS->CloseProtocol (
268 Controller,
269 &gPlatformVirtualKeyboardProtocolGuid,
270 This->DriverBindingHandle,
271 Controller
272 );
273
274 return Status;
275}
276
293EFIAPI
296 IN EFI_HANDLE Controller,
297 IN UINTN NumberOfChildren,
298 IN EFI_HANDLE *ChildHandleBuffer
299 )
300{
301 return EFI_SUCCESS;
302}
303
316 IN SIMPLE_QUEUE *Queue,
317 IN EFI_KEY_DATA *KeyData
318 )
319{
320 if ((Queue->Rear + 1) % QUEUE_MAX_COUNT == Queue->Front) {
321 return EFI_NOT_READY;
322 }
323
324 CopyMem (&Queue->Buffer[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));
325 Queue->Rear = (Queue->Rear + 1) % QUEUE_MAX_COUNT;
326
327 return EFI_SUCCESS;
328}
329
342 IN SIMPLE_QUEUE *Queue,
343 IN EFI_KEY_DATA *KeyData
344 )
345{
346 if (Queue->Front == Queue->Rear) {
347 return EFI_NOT_READY;
348 }
349
350 CopyMem (KeyData, &Queue->Buffer[Queue->Front], sizeof (EFI_KEY_DATA));
351 Queue->Front = (Queue->Front + 1) % QUEUE_MAX_COUNT;
352
353 return EFI_SUCCESS;
354}
355
367 IN SIMPLE_QUEUE *Queue
368 )
369{
370 if (Queue->Front == Queue->Rear) {
371 return EFI_NOT_READY;
372 }
373
374 return EFI_SUCCESS;
375}
376
387EFIAPI
390 )
391{
392 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
393
394 VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
395
396 return CheckQueue (&VirtualKeyboardPrivate->Queue);
397}
398
410 IN OUT LIST_ENTRY *ListHead
411 )
412{
414
415 if (ListHead == NULL) {
416 return EFI_INVALID_PARAMETER;
417 }
418
419 while (!IsListEmpty (ListHead)) {
420 NotifyNode = CR (
421 ListHead->ForwardLink,
423 NotifyEntry,
424 VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
425 );
426 RemoveEntryList (ListHead->ForwardLink);
427 gBS->FreePool (NotifyNode);
428 }
429
430 return EFI_SUCCESS;
431}
432
447BOOLEAN
449 IN EFI_KEY_DATA *RegsiteredData,
450 IN EFI_KEY_DATA *InputData
451 )
452
453{
454 ASSERT (RegsiteredData != NULL && InputData != NULL);
455
456 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
457 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))
458 {
459 return FALSE;
460 }
461
462 //
463 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means
464 // these state could be ignored.
465 //
466 if ((RegsiteredData->KeyState.KeyShiftState != 0) &&
467 (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))
468 {
469 return FALSE;
470 }
471
472 if ((RegsiteredData->KeyState.KeyToggleState != 0) &&
473 (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))
474 {
475 return FALSE;
476 }
477
478 return TRUE;
479}
480
489VOID
490EFIAPI
492 IN EFI_EVENT Event,
493 IN VOID *Context
494 )
495{
496 //
497 // Stall 1ms to give a chance to let other driver interrupt this routine
498 // for their timer event.
499 // e.g. UI setup or Shell, other drivers which are driven by timer event
500 // will have a bad performance during this period,
501 // e.g. usb keyboard driver.
502 // Add a stall period can greatly increate other driver performance during
503 // the WaitForKey is recursivly invoked. 1ms delay will make little impact
504 // to the thunk keyboard driver, and user can not feel the delay at all when
505 // input.
506 //
507 gBS->Stall (1000);
508 //
509 // Use TimerEvent callback function to check whether there's any key pressed
510 //
511 VirtualKeyboardTimerHandler (NULL, VIRTUAL_KEYBOARD_DEV_FROM_THIS (Context));
512
513 if (!EFI_ERROR (VirtualKeyboardCheckForKey (Context))) {
514 gBS->SignalEvent (Event);
515 }
516}
517
526VOID
527EFIAPI
529 IN EFI_EVENT Event,
530 IN VOID *Context
531 )
532
533{
534 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
535
536 VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (Context);
537 VirtualKeyboardWaitForKey (Event, &VirtualKeyboardPrivate->SimpleTextIn);
538}
539
540//
541// EFI Simple Text In Protocol Functions
542//
543
557EFIAPI
560 IN BOOLEAN ExtendedVerification
561 )
562{
563 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
564 EFI_STATUS Status;
565 EFI_TPL OldTpl;
566
567 VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
568
569 //
570 // Raise TPL to avoid mouse operation impact
571 //
572 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
573
574 if (VirtualKeyboardPrivate->PlatformVirtual &&
575 VirtualKeyboardPrivate->PlatformVirtual->Reset)
576 {
577 Status = VirtualKeyboardPrivate->PlatformVirtual->Reset ();
578 } else {
579 Status = EFI_INVALID_PARAMETER;
580 }
581
582 //
583 // resume priority of task level
584 //
585 gBS->RestoreTPL (OldTpl);
586
587 return Status;
588}
589
602EFIAPI
605 IN BOOLEAN ExtendedVerification
606 )
607{
608 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
609 EFI_STATUS Status;
610 EFI_TPL OldTpl;
611
612 VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
613
614 Status = VirtualKeyboardPrivate->SimpleTextIn.Reset (
615 &VirtualKeyboardPrivate->SimpleTextIn,
616 ExtendedVerification
617 );
618 if (EFI_ERROR (Status)) {
619 return EFI_DEVICE_ERROR;
620 }
621
622 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
623
624 gBS->RestoreTPL (OldTpl);
625
626 return EFI_SUCCESS;
627}
628
647 IN VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate,
648 OUT EFI_KEY_DATA *KeyData
649 )
650{
651 EFI_STATUS Status;
652 EFI_TPL OldTpl;
653
654 if (KeyData == NULL) {
655 return EFI_INVALID_PARAMETER;
656 }
657
658 //
659 // Use TimerEvent callback function to check whether there's any key pressed
660 //
661
662 //
663 // Stall 1ms to give a chance to let other driver interrupt this routine for
664 // their timer event.
665 // e.g. OS loader, other drivers which are driven by timer event will have a
666 // bad performance during this period,
667 // e.g. usb keyboard driver.
668 // Add a stall period can greatly increate other driver performance during
669 // the WaitForKey is recursivly invoked. 1ms delay will make little impact
670 // to the thunk keyboard driver, and user can not feel the delay at all when
671 // input.
672 //
673 gBS->Stall (1000);
674
675 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
676
677 VirtualKeyboardTimerHandler (NULL, VirtualKeyboardPrivate);
678 //
679 // If there's no key, just return
680 //
681 Status = CheckQueue (&VirtualKeyboardPrivate->Queue);
682 if (EFI_ERROR (Status)) {
683 gBS->RestoreTPL (OldTpl);
684 return EFI_NOT_READY;
685 }
686
687 Status = Dequeue (&VirtualKeyboardPrivate->Queue, KeyData);
688
689 gBS->RestoreTPL (OldTpl);
690
691 return EFI_SUCCESS;
692}
693
706EFIAPI
709 OUT EFI_INPUT_KEY *Key
710 )
711{
712 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
713 EFI_STATUS Status;
714 EFI_KEY_DATA KeyData;
715
716 VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
717
718 Status = KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, &KeyData);
719 if (EFI_ERROR (Status)) {
720 return Status;
721 }
722
723 //
724 // Convert the Ctrl+[a-z] to Ctrl+[1-26]
725 //
726 if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
727 if ((KeyData.Key.UnicodeChar >= L'a') &&
728 (KeyData.Key.UnicodeChar <= L'z'))
729 {
730 KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'a' + 1);
731 } else if ((KeyData.Key.UnicodeChar >= L'A') &&
732 (KeyData.Key.UnicodeChar <= L'Z'))
733 {
734 KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'A' + 1);
735 }
736 }
737
738 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
739
740 return EFI_SUCCESS;
741}
742
760EFIAPI
763 OUT EFI_KEY_DATA *KeyData
764 )
765{
766 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
767
768 if (KeyData == NULL) {
769 return EFI_INVALID_PARAMETER;
770 }
771
772 VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
773
774 return KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, KeyData);
775}
776
793EFIAPI
796 IN EFI_KEY_TOGGLE_STATE *KeyToggleState
797 )
798{
799 if (KeyToggleState == NULL) {
800 return EFI_INVALID_PARAMETER;
801 }
802
803 return EFI_SUCCESS;
804}
805
828EFIAPI
831 IN EFI_KEY_DATA *KeyData,
832 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
833 OUT VOID **NotifyHandle
834 )
835{
836 EFI_STATUS Status;
837 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
838 EFI_TPL OldTpl;
840 LIST_ENTRY *Link;
842
843 if ((KeyData == NULL) ||
844 (NotifyHandle == NULL) ||
845 (KeyNotificationFunction == NULL))
846 {
847 return EFI_INVALID_PARAMETER;
848 }
849
850 VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
851
852 //
853 // Enter critical section
854 //
855 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
856
857 //
858 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already
859 // registered.
860 //
861 for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink;
862 Link != &VirtualKeyboardPrivate->NotifyList;
863 Link = Link->ForwardLink)
864 {
865 CurrentNotify = CR (
866 Link,
868 NotifyEntry,
869 VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
870 );
871 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
872 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
873 *NotifyHandle = CurrentNotify;
874 Status = EFI_SUCCESS;
875 goto Exit;
876 }
877 }
878 }
879
880 //
881 // Allocate resource to save the notification function
882 //
883
885 if (NewNotify == NULL) {
886 Status = EFI_OUT_OF_RESOURCES;
887 goto Exit;
888 }
889
890 NewNotify->Signature = VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
891 NewNotify->KeyNotificationFn = KeyNotificationFunction;
892 CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
893 InsertTailList (&VirtualKeyboardPrivate->NotifyList, &NewNotify->NotifyEntry);
894
895 *NotifyHandle = NewNotify;
896 Status = EFI_SUCCESS;
897
898Exit:
899 //
900 // Leave critical section and return
901 //
902 gBS->RestoreTPL (OldTpl);
903 return Status;
904}
905
919EFIAPI
922 IN VOID *NotificationHandle
923 )
924{
925 EFI_STATUS Status;
926 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
927 EFI_TPL OldTpl;
928 LIST_ENTRY *Link;
930
931 //
932 // Check incoming notification handle
933 //
934 if (NotificationHandle == NULL) {
935 return EFI_INVALID_PARAMETER;
936 }
937
938 if (((VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *)NotificationHandle)->Signature !=
939 VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE)
940 {
941 return EFI_INVALID_PARAMETER;
942 }
943
944 VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
945
946 //
947 // Enter critical section
948 //
949 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
950
951 for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink;
952 Link != &VirtualKeyboardPrivate->NotifyList;
953 Link = Link->ForwardLink)
954 {
955 CurrentNotify = CR (
956 Link,
958 NotifyEntry,
959 VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
960 );
961 if (CurrentNotify == NotificationHandle) {
962 //
963 // Remove the notification function from NotifyList and free resources
964 //
965 RemoveEntryList (&CurrentNotify->NotifyEntry);
966
967 Status = EFI_SUCCESS;
968 goto Exit;
969 }
970 }
971
972 //
973 // Can not find the specified Notification Handle
974 //
975 Status = EFI_INVALID_PARAMETER;
976
977Exit:
978 //
979 // Leave critical section and return
980 //
981 gBS->RestoreTPL (OldTpl);
982 return Status;
983}
984
996VOID
997EFIAPI
999 IN EFI_EVENT Event,
1000 IN VOID *Context
1001 )
1002{
1003 EFI_TPL OldTpl;
1004 LIST_ENTRY *Link;
1005 EFI_KEY_DATA KeyData;
1007 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
1008 VIRTUAL_KBD_KEY VirtualKey;
1009
1010 VirtualKeyboardPrivate = Context;
1011
1012 //
1013 // Enter critical section
1014 //
1015 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1016
1017 if (VirtualKeyboardPrivate->PlatformVirtual &&
1018 VirtualKeyboardPrivate->PlatformVirtual->Query)
1019 {
1020 if (VirtualKeyboardPrivate->PlatformVirtual->Query (&VirtualKey) ==
1021 FALSE)
1022 {
1023 goto Exit;
1024 }
1025
1026 // Found key
1027 KeyData.Key.ScanCode = VirtualKey.Key.ScanCode;
1028 KeyData.Key.UnicodeChar = VirtualKey.Key.UnicodeChar;
1029 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
1030 KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
1031 if (VirtualKeyboardPrivate->PlatformVirtual->Clear) {
1032 VirtualKeyboardPrivate->PlatformVirtual->Clear (&VirtualKey);
1033 }
1034 } else {
1035 goto Exit;
1036 }
1037
1038 //
1039 // Signal KeyNotify process event if this key pressed matches any key registered.
1040 //
1041 for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink;
1042 Link != &VirtualKeyboardPrivate->NotifyList;
1043 Link = Link->ForwardLink)
1044 {
1045 CurrentNotify = CR (
1046 Link,
1048 NotifyEntry,
1049 VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1050 );
1051 if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
1052 //
1053 // The key notification function needs to run at TPL_CALLBACK
1054 // while current TPL is TPL_NOTIFY. It will be invoked in
1055 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
1056 //
1057 Enqueue (&VirtualKeyboardPrivate->QueueForNotify, &KeyData);
1058 gBS->SignalEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent);
1059 break;
1060 }
1061 }
1062
1063 Enqueue (&VirtualKeyboardPrivate->Queue, &KeyData);
1064
1065Exit:
1066 //
1067 // Leave critical section and return
1068 //
1069 gBS->RestoreTPL (OldTpl);
1070}
1071
1078VOID
1079EFIAPI
1081 IN EFI_EVENT Event,
1082 IN VOID *Context
1083 )
1084{
1085 EFI_STATUS Status;
1086 VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
1087 EFI_KEY_DATA KeyData;
1088 LIST_ENTRY *Link;
1089 LIST_ENTRY *NotifyList;
1091 EFI_TPL OldTpl;
1092
1093 VirtualKeyboardPrivate = (VIRTUAL_KEYBOARD_DEV *)Context;
1094
1095 //
1096 // Invoke notification functions.
1097 //
1098 NotifyList = &VirtualKeyboardPrivate->NotifyList;
1099 while (TRUE) {
1100 //
1101 // Enter critical section
1102 //
1103 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1104 Status = Dequeue (&VirtualKeyboardPrivate->QueueForNotify, &KeyData);
1105 //
1106 // Leave critical section
1107 //
1108 gBS->RestoreTPL (OldTpl);
1109 if (EFI_ERROR (Status)) {
1110 break;
1111 }
1112
1113 for (Link = GetFirstNode (NotifyList);
1114 !IsNull (NotifyList, Link);
1115 Link = GetNextNode (NotifyList, Link))
1116 {
1117 CurrentNotify = CR (
1118 Link,
1120 NotifyEntry,
1121 VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1122 );
1123 if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
1124 CurrentNotify->KeyNotificationFn (&KeyData);
1125 }
1126 }
1127 }
1128}
1129
1142EFIAPI
1144 IN EFI_HANDLE ImageHandle,
1145 IN EFI_SYSTEM_TABLE *SystemTable
1146 )
1147{
1148 EFI_STATUS Status;
1149
1150 //
1151 // Install driver model protocol(s).
1152 //
1154 ImageHandle,
1155 SystemTable,
1156 &gVirtualKeyboardDriverBinding,
1157 ImageHandle,
1158 &gVirtualKeyboardComponentName,
1159 &gVirtualKeyboardComponentName2
1160 );
1161 ASSERT_EFI_ERROR (Status);
1162
1163 return Status;
1164}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
#define REPORT_STATUS_CODE(Type, Value)
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
UINT8 EFI_KEY_TOGGLE_STATE
EFI_STATUS(EFIAPI * EFI_KEY_NOTIFY_FUNCTION)(IN EFI_KEY_DATA *KeyData)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ TimerPeriodic
Definition: UefiSpec.h:535
VOID EFIAPI VirtualKeyboardWaitForKeyEx(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS KeyboardReadKeyStrokeWorker(IN VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate, OUT EFI_KEY_DATA *KeyData)
VOID EFIAPI KeyNotifyProcessHandler(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI VirtualKeyboardTimerHandler(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI VirtualKeyboardReadKeyStroke(IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key)
EFI_STATUS EFIAPI VirtualKeyboardCheckForKey(IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This)
EFI_STATUS EFIAPI VirtualKeyboardReset(IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS Dequeue(IN SIMPLE_QUEUE *Queue, IN EFI_KEY_DATA *KeyData)
EFI_STATUS VirtualKeyboardFreeNotifyList(IN OUT LIST_ENTRY *ListHead)
EFI_STATUS EFIAPI VirtualKeyboardRegisterKeyNotify(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_DATA *KeyData, IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, OUT VOID **NotifyHandle)
EFI_STATUS EFIAPI VirtualKeyboardDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS EFIAPI VirtualKeyboardUnregisterKeyNotify(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN VOID *NotificationHandle)
VOID EFIAPI VirtualKeyboardWaitForKey(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI VirtualKeyboardDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS EFIAPI VirtualKeyboardReadKeyStrokeEx(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, OUT EFI_KEY_DATA *KeyData)
EFI_STATUS EFIAPI InitializeVirtualKeyboard(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI VirtualKeyboardResetEx(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS EFIAPI VirtualKeyboardDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
EFI_STATUS CheckQueue(IN SIMPLE_QUEUE *Queue)
EFI_STATUS EFIAPI VirtualKeyboardSetState(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_TOGGLE_STATE *KeyToggleState)
EFI_STATUS Enqueue(IN SIMPLE_QUEUE *Queue, IN EFI_KEY_DATA *KeyData)
BOOLEAN IsKeyRegistered(IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *InputData)
EFI_KEY_TOGGLE_STATE KeyToggleState
UINT32 KeyShiftState
EFI_INPUT_KEY Key
EFI_KEY_STATE KeyState