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