]> git.proxmox.com Git - mirror_edk2.git/blob - EmulatorPkg/EmuGopDxe/GopInput.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmulatorPkg / EmuGopDxe / GopInput.c
1 /*++ @file
2
3 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2010 0 2011,Apple Inc. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7
8 **/
9
10 #include "Gop.h"
11
12 BOOLEAN
13 GopPrivateIsKeyRegistered (
14 IN EFI_KEY_DATA *RegsiteredData,
15 IN EFI_KEY_DATA *InputData
16 )
17
18 /*++
19
20 Routine Description:
21
22 Arguments:
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
29 Returns:
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
61 VOID
62 EFIAPI
63 GopPrivateMakeCallbackFunction (
64 IN VOID *Context,
65 IN EFI_KEY_DATA *KeyData
66 )
67 {
68 LIST_ENTRY *Link;
69 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
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,
77 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
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
89 VOID
90 EFIAPI
91 GopPrivateBreakCallbackFunction (
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
103 /**
104 Reset the input device and optionally run diagnostics
105
106 @param This Protocol instance pointer.
107 @param ExtendedVerification Driver may perform diagnostics on reset.
108
109 @retval EFI_SUCCESS The device was reset.
110 @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset.
111
112 **/
113 EFI_STATUS
114 EFIAPI
115 EmuGopSimpleTextInReset (
116 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
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
147 /**
148 Reads the next keystroke from the input device. The WaitForKey Event can
149 be used to test for existence of a keystroke via WaitForEvent () call.
150
151 @param This Protocol instance pointer.
152 @param Key A pointer to a buffer that is filled in with the keystroke
153 information for the key that was pressed.
154
155 @retval EFI_SUCCESS The keystroke information was returned.
156 @retval EFI_NOT_READY There was no keystroke data available.
157 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
158 hardware errors.
159
160 **/
161 EFI_STATUS
162 EFIAPI
163 EmuGopSimpleTextInReadKeyStroke (
164 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
165 OUT EFI_INPUT_KEY *Key
166 )
167 {
168 GOP_PRIVATE_DATA *Private;
169 EFI_STATUS Status;
170 EFI_TPL OldTpl;
171 EFI_KEY_DATA KeyData;
172
173 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
174 if (Private->EmuGraphicsWindow == NULL) {
175 return EFI_NOT_READY;
176 }
177
178 //
179 // Enter critical section
180 //
181 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
182
183 Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData);
184 if (!EFI_ERROR (Status)) {
185 if ((KeyData.Key.ScanCode == 0) && (KeyData.Key.UnicodeChar == 0)) {
186 // Modifier key was pressed
187 Status = EFI_NOT_READY;
188 } else {
189 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
190 }
191 }
192
193 //
194 // Leave critical section and return
195 //
196 gBS->RestoreTPL (OldTpl);
197
198 return Status;
199 }
200
201 /**
202 SimpleTextIn and SimpleTextInEx Notify Wait Event
203
204 @param Event Event whose notification function is being invoked.
205 @param Context Pointer to GOP_PRIVATE_DATA.
206
207 **/
208 VOID
209 EFIAPI
210 EmuGopSimpleTextInWaitForKey (
211 IN EFI_EVENT Event,
212 IN VOID *Context
213 )
214 {
215 GOP_PRIVATE_DATA *Private;
216 EFI_STATUS Status;
217 EFI_TPL OldTpl;
218
219 Private = (GOP_PRIVATE_DATA *)Context;
220 if (Private->EmuGraphicsWindow == NULL) {
221 return;
222 }
223
224 //
225 // Enter critical section
226 //
227 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
228
229 Status = Private->EmuGraphicsWindow->CheckKey (Private->EmuGraphicsWindow);
230 if (!EFI_ERROR (Status)) {
231 //
232 // If a there is a key in the queue signal our event.
233 //
234 gBS->SignalEvent (Event);
235 }
236
237 //
238 // Leave critical section and return
239 //
240 gBS->RestoreTPL (OldTpl);
241 }
242
243 //
244 // Simple Text Input Ex protocol functions
245 //
246
247 /**
248 The Reset() function resets the input device hardware. As part
249 of initialization process, the firmware/device will make a quick
250 but reasonable attempt to verify that the device is functioning.
251 If the ExtendedVerification flag is TRUE the firmware may take
252 an extended amount of time to verify the device is operating on
253 reset. Otherwise the reset operation is to occur as quickly as
254 possible. The hardware verification process is not defined by
255 this specification and is left up to the platform firmware or
256 driver to implement.
257
258 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
259
260 @param ExtendedVerification Indicates that the driver may
261 perform a more exhaustive
262 verification operation of the
263 device during reset.
264
265
266 @retval EFI_SUCCESS The device was reset.
267
268 @retval EFI_DEVICE_ERROR The device is not functioning
269 correctly and could not be reset.
270
271 **/
272 EFI_STATUS
273 EFIAPI
274 EmuGopSimpleTextInExResetEx (
275 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
276 IN BOOLEAN ExtendedVerification
277 )
278
279 /*++
280
281 Routine Description:
282 Reset the input device and optionaly run diagnostics
283
284 Arguments:
285 This - Protocol instance pointer.
286 ExtendedVerification - Driver may perform diagnostics on reset.
287
288 Returns:
289 EFI_SUCCESS - The device was reset.
290
291 **/
292 {
293 return EFI_SUCCESS;
294 }
295
296 /**
297 The function reads the next keystroke from the input device. If
298 there is no pending keystroke the function returns
299 EFI_NOT_READY. If there is a pending keystroke, then
300 KeyData.Key.ScanCode is the EFI scan code defined in Error!
301 Reference source not found. The KeyData.Key.UnicodeChar is the
302 actual printable character or is zero if the key does not
303 represent a printable character (control key, function key,
304 etc.). The KeyData.KeyState is shift state for the character
305 reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode .
306 When interpreting the data from this function, it should be
307 noted that if a class of printable characters that are
308 normally adjusted by shift modifiers (e.g. Shift Key + "f"
309 key) would be presented solely as a KeyData.Key.UnicodeChar
310 without the associated shift state. So in the previous example
311 of a Shift Key + "f" key being pressed, the only pertinent
312 data returned would be KeyData.Key.UnicodeChar with the value
313 of "F". This of course would not typically be the case for
314 non-printable characters such as the pressing of the Right
315 Shift Key + F10 key since the corresponding returned data
316 would be reflected both in the KeyData.KeyState.KeyShiftState
317 and KeyData.Key.ScanCode values. UEFI drivers which implement
318 the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return
319 KeyData.Key and KeyData.KeyState values. These drivers must
320 always return the most current state of
321 KeyData.KeyState.KeyShiftState and
322 KeyData.KeyState.KeyToggleState. It should also be noted that
323 certain input devices may not be able to produce shift or toggle
324 state information, and in those cases the high order bit in the
325 respective Toggle and Shift state fields should not be active.
326
327
328 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
329
330 @param KeyData A pointer to a buffer that is filled in with
331 the keystroke state data for the key that was
332 pressed.
333
334
335 @retval EFI_SUCCESS The keystroke information was
336 returned.
337
338 @retval EFI_NOT_READY There was no keystroke data available.
339 EFI_DEVICE_ERROR The keystroke
340 information was not returned due to
341 hardware errors.
342
343
344 **/
345 EFI_STATUS
346 EFIAPI
347 EmuGopSimpleTextInExReadKeyStrokeEx (
348 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
349 OUT EFI_KEY_DATA *KeyData
350 )
351
352 /*++
353
354 Routine Description:
355 Reads the next keystroke from the input device. The WaitForKey Event can
356 be used to test for existance of a keystroke via WaitForEvent () call.
357
358 Arguments:
359 This - Protocol instance pointer.
360 KeyData - A pointer to a buffer that is filled in with the keystroke
361 state data for the key that was pressed.
362
363 Returns:
364 EFI_SUCCESS - The keystroke information was returned.
365 EFI_NOT_READY - There was no keystroke data availiable.
366 EFI_DEVICE_ERROR - The keystroke information was not returned due to
367 hardware errors.
368 EFI_INVALID_PARAMETER - KeyData is NULL.
369
370 **/
371 {
372 EFI_STATUS Status;
373 GOP_PRIVATE_DATA *Private;
374 EFI_TPL OldTpl;
375
376 if (KeyData == NULL) {
377 return EFI_INVALID_PARAMETER;
378 }
379
380 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
381 if (Private->EmuGraphicsWindow == NULL) {
382 return EFI_NOT_READY;
383 }
384
385 //
386 // Enter critical section
387 //
388 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
389
390 Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, KeyData);
391
392 //
393 // Leave critical section and return
394 //
395 gBS->RestoreTPL (OldTpl);
396
397 return Status;
398 }
399
400 /**
401 The SetState() function allows the input device hardware to
402 have state settings adjusted.
403
404 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
405
406 @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to
407 set the state for the input device.
408
409
410 @retval EFI_SUCCESS The device state was set appropriately.
411
412 @retval EFI_DEVICE_ERROR The device is not functioning
413 correctly and could not have the
414 setting adjusted.
415
416 @retval EFI_UNSUPPORTED The device does not support the
417 ability to have its state set.
418
419 **/
420 EFI_STATUS
421 EFIAPI
422 EmuGopSimpleTextInExSetState (
423 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
424 IN EFI_KEY_TOGGLE_STATE *KeyToggleState
425 )
426 {
427 GOP_PRIVATE_DATA *Private;
428 EFI_STATUS Status;
429 EFI_TPL OldTpl;
430
431 if (KeyToggleState == NULL) {
432 return EFI_INVALID_PARAMETER;
433 }
434
435 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
436 if (Private->EmuGraphicsWindow == NULL) {
437 return EFI_NOT_READY;
438 }
439
440 if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
441 ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID))
442 {
443 return EFI_UNSUPPORTED;
444 }
445
446 //
447 // Enter critical section
448 //
449 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
450
451 Status = Private->EmuGraphicsWindow->KeySetState (Private->EmuGraphicsWindow, KeyToggleState);
452 //
453 // Leave critical section and return
454 //
455 gBS->RestoreTPL (OldTpl);
456
457 return Status;
458 }
459
460 /**
461 SimpleTextIn and SimpleTextInEx Notify Wait Event
462
463 @param Event Event whose notification function is being invoked.
464 @param Context Pointer to GOP_PRIVATE_DATA.
465
466 **/
467 VOID
468 EFIAPI
469 EmuGopRegisterKeyCallback (
470 IN EFI_EVENT Event,
471 IN VOID *Context
472 )
473 {
474 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *ExNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)Context;
475
476 ExNotify->KeyNotificationFn (&ExNotify->KeyData);
477 }
478
479 /**
480 The RegisterKeystrokeNotify() function registers a function
481 which will be called when a specified keystroke will occur.
482
483 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
484
485 @param KeyData A pointer to a buffer that is filled in with
486 the keystroke information for the key that was
487 pressed.
488
489 @param KeyNotificationFunction Points to the function to be
490 called when the key sequence
491 is typed specified by KeyData.
492
493
494 @param NotifyHandle Points to the unique handle assigned to
495 the registered notification.
496
497 @retval EFI_SUCCESS The device state was set
498 appropriately.
499
500 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary
501 data structures.
502
503 **/
504 EFI_STATUS
505 EFIAPI
506 EmuGopSimpleTextInExRegisterKeyNotify (
507 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
508 IN EFI_KEY_DATA *KeyData,
509 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
510 OUT VOID **NotifyHandle
511 )
512 {
513 EFI_STATUS Status;
514 GOP_PRIVATE_DATA *Private;
515 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
516 LIST_ENTRY *Link;
517 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify;
518
519 if ((KeyData == NULL) || (KeyNotificationFunction == NULL) || (NotifyHandle == NULL)) {
520 return EFI_INVALID_PARAMETER;
521 }
522
523 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
524
525 //
526 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
527 //
528 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
529 CurrentNotify = CR (
530 Link,
531 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
532 NotifyEntry,
533 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
534 );
535 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
536 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
537 *NotifyHandle = CurrentNotify->NotifyHandle;
538 return EFI_SUCCESS;
539 }
540 }
541 }
542
543 //
544 // Allocate resource to save the notification function
545 //
546 NewNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)AllocateZeroPool (sizeof (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY));
547 if (NewNotify == NULL) {
548 return EFI_OUT_OF_RESOURCES;
549 }
550
551 NewNotify->Signature = EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;
552 NewNotify->KeyNotificationFn = KeyNotificationFunction;
553 NewNotify->NotifyHandle = (EFI_HANDLE)NewNotify;
554 CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
555 InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);
556
557 Status = gBS->CreateEvent (
558 EVT_NOTIFY_SIGNAL,
559 TPL_NOTIFY,
560 EmuGopRegisterKeyCallback,
561 NewNotify,
562 &NewNotify->Event
563 );
564 ASSERT_EFI_ERROR (Status);
565
566 *NotifyHandle = NewNotify->NotifyHandle;
567
568 return EFI_SUCCESS;
569 }
570
571 /**
572 The UnregisterKeystrokeNotify() function removes the
573 notification which was previously registered.
574
575 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
576
577 @param NotificationHandle The handle of the notification
578 function being unregistered.
579
580 @retval EFI_SUCCESS The device state was set appropriately.
581
582 @retval EFI_INVALID_PARAMETER The NotificationHandle is
583 invalid.
584
585 **/
586 EFI_STATUS
587 EFIAPI
588 EmuGopSimpleTextInExUnregisterKeyNotify (
589 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
590 IN VOID *NotificationHandle
591 )
592
593 /*++
594
595 Routine Description:
596 Remove a registered notification function from a particular keystroke.
597
598 Arguments:
599 This - Protocol instance pointer.
600 NotificationHandle - The handle of the notification function being unregistered.
601
602 Returns:
603 EFI_SUCCESS - The notification function was unregistered successfully.
604 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
605
606 **/
607 {
608 GOP_PRIVATE_DATA *Private;
609 LIST_ENTRY *Link;
610 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
611
612 if (NotificationHandle == NULL) {
613 return EFI_INVALID_PARAMETER;
614 }
615
616 if (((EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)NotificationHandle)->Signature != EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) {
617 return EFI_INVALID_PARAMETER;
618 }
619
620 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
621
622 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
623 CurrentNotify = CR (
624 Link,
625 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
626 NotifyEntry,
627 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
628 );
629 if (CurrentNotify->NotifyHandle == NotificationHandle) {
630 //
631 // Remove the notification function from NotifyList and free resources
632 //
633 RemoveEntryList (&CurrentNotify->NotifyEntry);
634
635 gBS->CloseEvent (CurrentNotify->Event);
636
637 gBS->FreePool (CurrentNotify);
638 return EFI_SUCCESS;
639 }
640 }
641
642 //
643 // Can not find the specified Notification Handle
644 //
645 return EFI_INVALID_PARAMETER;
646 }
647
648 /**
649 Initialize SimplelTextIn and SimpleTextInEx protocols in the Private
650 context structure.
651
652 @param Private Context structure to fill in.
653
654 @return EFI_SUCCESS Initialization was a success
655
656 **/
657 EFI_STATUS
658 EmuGopInitializeSimpleTextInForWindow (
659 IN GOP_PRIVATE_DATA *Private
660 )
661 {
662 EFI_STATUS Status;
663
664 //
665 // Initialize Simple Text In protoocol
666 //
667 Private->SimpleTextIn.Reset = EmuGopSimpleTextInReset;
668 Private->SimpleTextIn.ReadKeyStroke = EmuGopSimpleTextInReadKeyStroke;
669
670 Status = gBS->CreateEvent (
671 EVT_NOTIFY_WAIT,
672 TPL_NOTIFY,
673 EmuGopSimpleTextInWaitForKey,
674 Private,
675 &Private->SimpleTextIn.WaitForKey
676 );
677 ASSERT_EFI_ERROR (Status);
678
679 //
680 // Initialize Simple Text In Ex
681 //
682
683 Private->SimpleTextInEx.Reset = EmuGopSimpleTextInExResetEx;
684 Private->SimpleTextInEx.ReadKeyStrokeEx = EmuGopSimpleTextInExReadKeyStrokeEx;
685 Private->SimpleTextInEx.SetState = EmuGopSimpleTextInExSetState;
686 Private->SimpleTextInEx.RegisterKeyNotify = EmuGopSimpleTextInExRegisterKeyNotify;
687 Private->SimpleTextInEx.UnregisterKeyNotify = EmuGopSimpleTextInExUnregisterKeyNotify;
688
689 Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);
690
691 InitializeListHead (&Private->NotifyList);
692
693 Status = gBS->CreateEvent (
694 EVT_NOTIFY_WAIT,
695 TPL_NOTIFY,
696 EmuGopSimpleTextInWaitForKey,
697 Private,
698 &Private->SimpleTextInEx.WaitForKeyEx
699 );
700 ASSERT_EFI_ERROR (Status);
701
702 return Status;
703 }
704
705 //
706 // Simple Pointer implementation.
707 //
708
709 /**
710 Resets the pointer device hardware.
711
712 @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
713 instance.
714 @param ExtendedVerification Indicates that the driver may perform a more exhaustive
715 verification operation of the device during reset.
716
717 @retval EFI_SUCCESS The device was reset.
718 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset.
719
720 **/
721 EFI_STATUS
722 EFIAPI
723 EmuGopSimplePointerReset (
724 IN EFI_SIMPLE_POINTER_PROTOCOL *This,
725 IN BOOLEAN ExtendedVerification
726 )
727 {
728 GOP_PRIVATE_DATA *Private;
729 EFI_SIMPLE_POINTER_STATE State;
730 EFI_TPL OldTpl;
731
732 Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This);
733 if (Private->EmuGraphicsWindow == NULL) {
734 return EFI_SUCCESS;
735 }
736
737 //
738 // Enter critical section
739 //
740 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
741
742 //
743 // A reset is draining the Queue
744 //
745 while (Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, &State) == EFI_SUCCESS) {
746 }
747
748 //
749 // Leave critical section and return
750 //
751 gBS->RestoreTPL (OldTpl);
752 return EFI_SUCCESS;
753 }
754
755 /**
756 Retrieves the current state of a pointer device.
757
758 @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
759 instance.
760 @param State A pointer to the state information on the pointer device.
761
762 @retval EFI_SUCCESS The state of the pointer device was returned in State.
763 @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to
764 GetState().
765 @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's
766 current state.
767
768 **/
769 EFI_STATUS
770 EFIAPI
771 EmuGopSimplePointerGetState (
772 IN EFI_SIMPLE_POINTER_PROTOCOL *This,
773 IN OUT EFI_SIMPLE_POINTER_STATE *State
774 )
775 {
776 GOP_PRIVATE_DATA *Private;
777 EFI_STATUS Status;
778 EFI_TPL OldTpl;
779
780 Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This);
781 if (Private->EmuGraphicsWindow == NULL) {
782 return EFI_NOT_READY;
783 }
784
785 //
786 // Enter critical section
787 //
788 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
789
790 Status = Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, State);
791 //
792 // Leave critical section and return
793 //
794 gBS->RestoreTPL (OldTpl);
795
796 return Status;
797 }
798
799 /**
800 SimplePointer Notify Wait Event
801
802 @param Event Event whose notification function is being invoked.
803 @param Context Pointer to GOP_PRIVATE_DATA.
804
805 **/
806 VOID
807 EFIAPI
808 EmuGopSimplePointerWaitForInput (
809 IN EFI_EVENT Event,
810 IN VOID *Context
811 )
812 {
813 GOP_PRIVATE_DATA *Private;
814 EFI_STATUS Status;
815 EFI_TPL OldTpl;
816
817 Private = (GOP_PRIVATE_DATA *)Context;
818 if (Private->EmuGraphicsWindow == NULL) {
819 return;
820 }
821
822 //
823 // Enter critical section
824 //
825 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
826
827 Status = Private->EmuGraphicsWindow->CheckPointer (Private->EmuGraphicsWindow);
828 if (!EFI_ERROR (Status)) {
829 //
830 // If the pointer state has changed, signal our event.
831 //
832 gBS->SignalEvent (Event);
833 }
834
835 //
836 // Leave critical section and return
837 //
838 gBS->RestoreTPL (OldTpl);
839 }
840
841 /**
842 SimplePointer constructor
843
844 @param Private Context structure to fill in.
845
846 @retval EFI_SUCCESS Constructor had success
847
848 **/
849 EFI_STATUS
850 EmuGopInitializeSimplePointerForWindow (
851 IN GOP_PRIVATE_DATA *Private
852 )
853 {
854 EFI_STATUS Status;
855
856 //
857 // Initialize Simple Pointer protoocol
858 //
859 Private->PointerMode.ResolutionX = 1;
860 Private->PointerMode.ResolutionY = 1;
861 Private->PointerMode.ResolutionZ = 1;
862 Private->PointerMode.LeftButton = TRUE;
863 Private->PointerMode.RightButton = TRUE;
864
865 Private->SimplePointer.Reset = EmuGopSimplePointerReset;
866 Private->SimplePointer.GetState = EmuGopSimplePointerGetState;
867 Private->SimplePointer.Mode = &Private->PointerMode;
868
869 Status = gBS->CreateEvent (
870 EVT_NOTIFY_WAIT,
871 TPL_NOTIFY,
872 EmuGopSimplePointerWaitForInput,
873 Private,
874 &Private->SimplePointer.WaitForInput
875 );
876
877 return Status;
878 }