TianoCore EDK2 master
Loading...
Searching...
No Matches
GopInput.c
1/*++ @file
2
3Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
4Portions copyright (c) 2010 0 2011,Apple Inc. All rights reserved.<BR>
5SPDX-License-Identifier: BSD-2-Clause-Patent
6
7
8**/
9
10#include "Gop.h"
11
12BOOLEAN
13GopPrivateIsKeyRegistered (
14 IN EFI_KEY_DATA *RegsiteredData,
15 IN EFI_KEY_DATA *InputData
16 )
17
18/*++
19
20Routine Description:
21
22Arguments:
23
24 RegsiteredData - A pointer to a buffer that is filled in with the keystroke
25 state data for the key that was registered.
26 InputData - A pointer to a buffer that is filled in with the keystroke
27 state data for the key that was pressed.
28
29Returns:
30 TRUE - Key be pressed matches a registered key.
31 FLASE - Match failed.
32
33**/
34{
35 ASSERT (RegsiteredData != NULL && InputData != NULL);
36
37 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
38 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))
39 {
40 return FALSE;
41 }
42
43 //
44 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
45 //
46 if ((RegsiteredData->KeyState.KeyShiftState != 0) &&
47 (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))
48 {
49 return FALSE;
50 }
51
52 if ((RegsiteredData->KeyState.KeyToggleState != 0) &&
53 (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))
54 {
55 return FALSE;
56 }
57
58 return TRUE;
59}
60
61VOID
62EFIAPI
63GopPrivateMakeCallbackFunction (
64 IN VOID *Context,
65 IN EFI_KEY_DATA *KeyData
66 )
67{
68 LIST_ENTRY *Link;
70 GOP_PRIVATE_DATA *Private = (GOP_PRIVATE_DATA *)Context;
71
72 KeyMapMake (KeyData);
73
74 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
75 CurrentNotify = CR (
76 Link,
78 NotifyEntry,
79 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
80 );
81 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
82 // We could be called at a high TPL so signal an event to call the registered function
83 // at a lower TPL.
84 gBS->SignalEvent (CurrentNotify->Event);
85 }
86 }
87}
88
89VOID
90EFIAPI
91GopPrivateBreakCallbackFunction (
92 IN VOID *Context,
93 IN EFI_KEY_DATA *KeyData
94 )
95{
96 KeyMapBreak (KeyData);
97}
98
99//
100// Simple Text In implementation.
101//
102
114EFIAPI
115EmuGopSimpleTextInReset (
117 IN BOOLEAN ExtendedVerification
118 )
119{
120 GOP_PRIVATE_DATA *Private;
121 EFI_KEY_DATA KeyData;
122 EFI_TPL OldTpl;
123
124 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
125 if (Private->EmuGraphicsWindow == NULL) {
126 return EFI_SUCCESS;
127 }
128
129 //
130 // Enter critical section
131 //
132 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
133
134 //
135 // A reset is draining the Queue
136 //
137 while (Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData) == EFI_SUCCESS) {
138 }
139
140 //
141 // Leave critical section and return
142 //
143 gBS->RestoreTPL (OldTpl);
144 return EFI_SUCCESS;
145}
146
163EFIAPI
164EmuGopSimpleTextInReadKeyStroke (
166 OUT EFI_INPUT_KEY *Key
167 )
168{
169 GOP_PRIVATE_DATA *Private;
170 EFI_STATUS Status;
171 EFI_TPL OldTpl;
172 EFI_KEY_DATA KeyData;
173
174 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
175 if (Private->EmuGraphicsWindow == NULL) {
176 return EFI_NOT_READY;
177 }
178
179 //
180 // Enter critical section
181 //
182 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
183
184 Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData);
185 if (!EFI_ERROR (Status)) {
186 if ((KeyData.Key.ScanCode == 0) && (KeyData.Key.UnicodeChar == 0)) {
187 // Modifier key was pressed
188 Status = EFI_NOT_READY;
189 } else {
190 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
191 }
192 }
193
194 //
195 // Leave critical section and return
196 //
197 gBS->RestoreTPL (OldTpl);
198
199 return Status;
200}
201
209VOID
210EFIAPI
211EmuGopSimpleTextInWaitForKey (
212 IN EFI_EVENT Event,
213 IN VOID *Context
214 )
215{
216 GOP_PRIVATE_DATA *Private;
217 EFI_STATUS Status;
218 EFI_TPL OldTpl;
219
220 Private = (GOP_PRIVATE_DATA *)Context;
221 if (Private->EmuGraphicsWindow == NULL) {
222 return;
223 }
224
225 //
226 // Enter critical section
227 //
228 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
229
230 Status = Private->EmuGraphicsWindow->CheckKey (Private->EmuGraphicsWindow);
231 if (!EFI_ERROR (Status)) {
232 //
233 // If a there is a key in the queue signal our event.
234 //
235 gBS->SignalEvent (Event);
236 }
237
238 //
239 // Leave critical section and return
240 //
241 gBS->RestoreTPL (OldTpl);
242}
243
244//
245// Simple Text Input Ex protocol functions
246//
247
274EFIAPI
275EmuGopSimpleTextInExResetEx (
277 IN BOOLEAN ExtendedVerification
278 )
279
280/*++
281
282 Routine Description:
283 Reset the input device and optionaly run diagnostics
284
285 Arguments:
286 This - Protocol instance pointer.
287 ExtendedVerification - Driver may perform diagnostics on reset.
288
289 Returns:
290 EFI_SUCCESS - The device was reset.
291
292**/
293{
294 return EFI_SUCCESS;
295}
296
348EFIAPI
349EmuGopSimpleTextInExReadKeyStrokeEx (
351 OUT EFI_KEY_DATA *KeyData
352 )
353
354/*++
355
356 Routine Description:
357 Reads the next keystroke from the input device. The WaitForKey Event can
358 be used to test for existance of a keystroke via WaitForEvent () call.
359
360 Arguments:
361 This - Protocol instance pointer.
362 KeyData - A pointer to a buffer that is filled in with the keystroke
363 state data for the key that was pressed.
364
365 Returns:
366 EFI_SUCCESS - The keystroke information was returned.
367 EFI_NOT_READY - There was no keystroke data availiable.
368 EFI_DEVICE_ERROR - The keystroke information was not returned due to
369 hardware errors.
370 EFI_INVALID_PARAMETER - KeyData is NULL.
371
372**/
373{
374 EFI_STATUS Status;
375 GOP_PRIVATE_DATA *Private;
376 EFI_TPL OldTpl;
377
378 if (KeyData == NULL) {
379 return EFI_INVALID_PARAMETER;
380 }
381
382 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
383 if (Private->EmuGraphicsWindow == NULL) {
384 return EFI_NOT_READY;
385 }
386
387 //
388 // Enter critical section
389 //
390 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
391
392 Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, KeyData);
393
394 //
395 // Leave critical section and return
396 //
397 gBS->RestoreTPL (OldTpl);
398
399 return Status;
400}
401
423EFIAPI
424EmuGopSimpleTextInExSetState (
426 IN EFI_KEY_TOGGLE_STATE *KeyToggleState
427 )
428{
429 GOP_PRIVATE_DATA *Private;
430 EFI_STATUS Status;
431 EFI_TPL OldTpl;
432
433 if (KeyToggleState == NULL) {
434 return EFI_INVALID_PARAMETER;
435 }
436
437 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
438 if (Private->EmuGraphicsWindow == NULL) {
439 return EFI_NOT_READY;
440 }
441
442 if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
443 ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID))
444 {
445 return EFI_UNSUPPORTED;
446 }
447
448 //
449 // Enter critical section
450 //
451 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
452
453 Status = Private->EmuGraphicsWindow->KeySetState (Private->EmuGraphicsWindow, KeyToggleState);
454 //
455 // Leave critical section and return
456 //
457 gBS->RestoreTPL (OldTpl);
458
459 return Status;
460}
461
469VOID
470EFIAPI
471EmuGopRegisterKeyCallback (
472 IN EFI_EVENT Event,
473 IN VOID *Context
474 )
475{
477
478 ExNotify->KeyNotificationFn (&ExNotify->KeyData);
479}
480
507EFIAPI
508EmuGopSimpleTextInExRegisterKeyNotify (
510 IN EFI_KEY_DATA *KeyData,
511 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
512 OUT VOID **NotifyHandle
513 )
514{
515 EFI_STATUS Status;
516 GOP_PRIVATE_DATA *Private;
517 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
518 LIST_ENTRY *Link;
520
521 if ((KeyData == NULL) || (KeyNotificationFunction == NULL) || (NotifyHandle == NULL)) {
522 return EFI_INVALID_PARAMETER;
523 }
524
525 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
526
527 //
528 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
529 //
530 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
531 CurrentNotify = CR (
532 Link,
534 NotifyEntry,
535 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
536 );
537 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
538 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
539 *NotifyHandle = CurrentNotify->NotifyHandle;
540 return EFI_SUCCESS;
541 }
542 }
543 }
544
545 //
546 // Allocate resource to save the notification function
547 //
549 if (NewNotify == NULL) {
550 return EFI_OUT_OF_RESOURCES;
551 }
552
553 NewNotify->Signature = EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;
554 NewNotify->KeyNotificationFn = KeyNotificationFunction;
555 NewNotify->NotifyHandle = (EFI_HANDLE)NewNotify;
556 CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
557 InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);
558
559 Status = gBS->CreateEvent (
560 EVT_NOTIFY_SIGNAL,
561 TPL_NOTIFY,
562 EmuGopRegisterKeyCallback,
563 NewNotify,
564 &NewNotify->Event
565 );
566 ASSERT_EFI_ERROR (Status);
567
568 *NotifyHandle = NewNotify->NotifyHandle;
569
570 return EFI_SUCCESS;
571}
572
589EFIAPI
590EmuGopSimpleTextInExUnregisterKeyNotify (
592 IN VOID *NotificationHandle
593 )
594
595/*++
596
597 Routine Description:
598 Remove a registered notification function from a particular keystroke.
599
600 Arguments:
601 This - Protocol instance pointer.
602 NotificationHandle - The handle of the notification function being unregistered.
603
604 Returns:
605 EFI_SUCCESS - The notification function was unregistered successfully.
606 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
607
608**/
609{
610 GOP_PRIVATE_DATA *Private;
611 LIST_ENTRY *Link;
612 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
613
614 if (NotificationHandle == NULL) {
615 return EFI_INVALID_PARAMETER;
616 }
617
618 if (((EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)NotificationHandle)->Signature != EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) {
619 return EFI_INVALID_PARAMETER;
620 }
621
622 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
623
624 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
625 CurrentNotify = CR (
626 Link,
628 NotifyEntry,
629 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
630 );
631 if (CurrentNotify->NotifyHandle == NotificationHandle) {
632 //
633 // Remove the notification function from NotifyList and free resources
634 //
635 RemoveEntryList (&CurrentNotify->NotifyEntry);
636
637 gBS->CloseEvent (CurrentNotify->Event);
638
639 gBS->FreePool (CurrentNotify);
640 return EFI_SUCCESS;
641 }
642 }
643
644 //
645 // Can not find the specified Notification Handle
646 //
647 return EFI_INVALID_PARAMETER;
648}
649
660EmuGopInitializeSimpleTextInForWindow (
661 IN GOP_PRIVATE_DATA *Private
662 )
663{
664 EFI_STATUS Status;
665
666 //
667 // Initialize Simple Text In protoocol
668 //
669 Private->SimpleTextIn.Reset = EmuGopSimpleTextInReset;
670 Private->SimpleTextIn.ReadKeyStroke = EmuGopSimpleTextInReadKeyStroke;
671
672 Status = gBS->CreateEvent (
673 EVT_NOTIFY_WAIT,
674 TPL_NOTIFY,
675 EmuGopSimpleTextInWaitForKey,
676 Private,
677 &Private->SimpleTextIn.WaitForKey
678 );
679 ASSERT_EFI_ERROR (Status);
680
681 //
682 // Initialize Simple Text In Ex
683 //
684
685 Private->SimpleTextInEx.Reset = EmuGopSimpleTextInExResetEx;
686 Private->SimpleTextInEx.ReadKeyStrokeEx = EmuGopSimpleTextInExReadKeyStrokeEx;
687 Private->SimpleTextInEx.SetState = EmuGopSimpleTextInExSetState;
688 Private->SimpleTextInEx.RegisterKeyNotify = EmuGopSimpleTextInExRegisterKeyNotify;
689 Private->SimpleTextInEx.UnregisterKeyNotify = EmuGopSimpleTextInExUnregisterKeyNotify;
690
691 Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);
692
693 InitializeListHead (&Private->NotifyList);
694
695 Status = gBS->CreateEvent (
696 EVT_NOTIFY_WAIT,
697 TPL_NOTIFY,
698 EmuGopSimpleTextInWaitForKey,
699 Private,
700 &Private->SimpleTextInEx.WaitForKeyEx
701 );
702 ASSERT_EFI_ERROR (Status);
703
704 return Status;
705}
706
707//
708// Simple Pointer implementation.
709//
710
724EFIAPI
725EmuGopSimplePointerReset (
727 IN BOOLEAN ExtendedVerification
728 )
729{
730 GOP_PRIVATE_DATA *Private;
732 EFI_TPL OldTpl;
733
734 Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This);
735 if (Private->EmuGraphicsWindow == NULL) {
736 return EFI_SUCCESS;
737 }
738
739 //
740 // Enter critical section
741 //
742 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
743
744 //
745 // A reset is draining the Queue
746 //
747 while (Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, &State) == EFI_SUCCESS) {
748 }
749
750 //
751 // Leave critical section and return
752 //
753 gBS->RestoreTPL (OldTpl);
754 return EFI_SUCCESS;
755}
756
772EFIAPI
773EmuGopSimplePointerGetState (
776 )
777{
778 GOP_PRIVATE_DATA *Private;
779 EFI_STATUS Status;
780 EFI_TPL OldTpl;
781
782 Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This);
783 if (Private->EmuGraphicsWindow == NULL) {
784 return EFI_NOT_READY;
785 }
786
787 //
788 // Enter critical section
789 //
790 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
791
792 Status = Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, State);
793 //
794 // Leave critical section and return
795 //
796 gBS->RestoreTPL (OldTpl);
797
798 return Status;
799}
800
808VOID
809EFIAPI
810EmuGopSimplePointerWaitForInput (
811 IN EFI_EVENT Event,
812 IN VOID *Context
813 )
814{
815 GOP_PRIVATE_DATA *Private;
816 EFI_STATUS Status;
817 EFI_TPL OldTpl;
818
819 Private = (GOP_PRIVATE_DATA *)Context;
820 if (Private->EmuGraphicsWindow == NULL) {
821 return;
822 }
823
824 //
825 // Enter critical section
826 //
827 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
828
829 Status = Private->EmuGraphicsWindow->CheckPointer (Private->EmuGraphicsWindow);
830 if (!EFI_ERROR (Status)) {
831 //
832 // If the pointer state has changed, signal our event.
833 //
834 gBS->SignalEvent (Event);
835 }
836
837 //
838 // Leave critical section and return
839 //
840 gBS->RestoreTPL (OldTpl);
841}
842
852EmuGopInitializeSimplePointerForWindow (
853 IN GOP_PRIVATE_DATA *Private
854 )
855{
856 EFI_STATUS Status;
857
858 //
859 // Initialize Simple Pointer protoocol
860 //
861 Private->PointerMode.ResolutionX = 1;
862 Private->PointerMode.ResolutionY = 1;
863 Private->PointerMode.ResolutionZ = 1;
864 Private->PointerMode.LeftButton = TRUE;
865 Private->PointerMode.RightButton = TRUE;
866
867 Private->SimplePointer.Reset = EmuGopSimplePointerReset;
868 Private->SimplePointer.GetState = EmuGopSimplePointerGetState;
869 Private->SimplePointer.Mode = &Private->PointerMode;
870
871 Status = gBS->CreateEvent (
872 EVT_NOTIFY_WAIT,
873 TPL_NOTIFY,
874 EmuGopSimplePointerWaitForInput,
875 Private,
876 &Private->SimplePointer.WaitForInput
877 );
878
879 return Status;
880}
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)
#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 CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
UINT8 EFI_KEY_TOGGLE_STATE
EFI_STATUS(EFIAPI * EFI_KEY_NOTIFY_FUNCTION)(IN EFI_KEY_DATA *KeyData)
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_KEY_TOGGLE_STATE KeyToggleState
EFI_INPUT_KEY Key