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