3 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2010, Apple, Inc. All rights reserved.
5 Portions copyright (c) 2010, Apple Inc. All rights reserved.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 GopPrivateIsKeyRegistered (
22 IN EFI_KEY_DATA
*RegsiteredData
,
23 IN EFI_KEY_DATA
*InputData
31 RegsiteredData - A pointer to a buffer that is filled in with the keystroke
32 state data for the key that was registered.
33 InputData - A pointer to a buffer that is filled in with the keystroke
34 state data for the key that was pressed.
37 TRUE - Key be pressed matches a registered key.
42 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
44 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
45 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
50 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
52 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
53 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
56 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
57 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
68 GopPrivateInvokeRegisteredFunction (
70 IN EFI_KEY_DATA
*KeyData
74 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*CurrentNotify
;
75 GOP_PRIVATE_DATA
*Private
= (GOP_PRIVATE_DATA
*)Context
;
77 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
80 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
,
82 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
84 if (GopPrivateIsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
85 // We could be called at a high TPL so signal an event to call the registered function
87 gBS
->SignalEvent (CurrentNotify
->Event
);
95 // Simple Text In implementation.
99 Reset the input device and optionally run diagnostics
101 @param This Protocol instance pointer.
102 @param ExtendedVerification Driver may perform diagnostics on reset.
104 @retval EFI_SUCCESS The device was reset.
105 @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset.
110 UnixGopSimpleTextInReset (
111 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
112 IN BOOLEAN ExtendedVerification
115 GOP_PRIVATE_DATA
*Private
;
116 EFI_KEY_DATA KeyData
;
119 Private
= GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This
);
120 if (Private
->UgaIo
== NULL
) {
125 // Enter critical section
127 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
130 // A reset is draining the Queue
132 while (Private
->UgaIo
->UgaGetKey (Private
->UgaIo
, &KeyData
) == EFI_SUCCESS
)
136 // Leave critical section and return
138 gBS
->RestoreTPL (OldTpl
);
144 Reads the next keystroke from the input device. The WaitForKey Event can
145 be used to test for existence of a keystroke via WaitForEvent () call.
147 @param This Protocol instance pointer.
148 @param Key A pointer to a buffer that is filled in with the keystroke
149 information for the key that was pressed.
151 @retval EFI_SUCCESS The keystroke information was returned.
152 @retval EFI_NOT_READY There was no keystroke data available.
153 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
159 UnixGopSimpleTextInReadKeyStroke (
160 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
161 OUT EFI_INPUT_KEY
*Key
164 GOP_PRIVATE_DATA
*Private
;
167 EFI_KEY_DATA KeyData
;
169 Private
= GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This
);
170 if (Private
->UgaIo
== NULL
) {
171 return EFI_NOT_READY
;
175 // Enter critical section
177 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
179 Status
= Private
->UgaIo
->UgaGetKey(Private
->UgaIo
, &KeyData
);
180 CopyMem (Key
, &KeyData
.Key
, sizeof (EFI_INPUT_KEY
));
183 // Leave critical section and return
185 gBS
->RestoreTPL (OldTpl
);
193 SimpleTextIn and SimpleTextInEx Notify Wait Event
195 @param Event Event whose notification function is being invoked.
196 @param Context Pointer to GOP_PRIVATE_DATA.
201 UnixGopSimpleTextInWaitForKey (
206 GOP_PRIVATE_DATA
*Private
;
210 Private
= (GOP_PRIVATE_DATA
*) Context
;
211 if (Private
->UgaIo
== NULL
) {
216 // Enter critical section
218 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
220 Status
= Private
->UgaIo
->UgaCheckKey (Private
->UgaIo
);
221 if (!EFI_ERROR (Status
)) {
223 // If a there is a key in the queue signal our event.
225 gBS
->SignalEvent (Event
);
228 // Leave critical section and return
230 gBS
->RestoreTPL (OldTpl
);
235 // Simple Text Input Ex protocol functions
240 The Reset() function resets the input device hardware. As part
241 of initialization process, the firmware/device will make a quick
242 but reasonable attempt to verify that the device is functioning.
243 If the ExtendedVerification flag is TRUE the firmware may take
244 an extended amount of time to verify the device is operating on
245 reset. Otherwise the reset operation is to occur as quickly as
246 possible. The hardware verification process is not defined by
247 this specification and is left up to the platform firmware or
250 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
252 @param ExtendedVerification Indicates that the driver may
253 perform a more exhaustive
254 verification operation of the
258 @retval EFI_SUCCESS The device was reset.
260 @retval EFI_DEVICE_ERROR The device is not functioning
261 correctly and could not be reset.
266 UnixGopSimpleTextInExResetEx (
267 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
268 IN BOOLEAN ExtendedVerification
273 Reset the input device and optionaly run diagnostics
276 This - Protocol instance pointer.
277 ExtendedVerification - Driver may perform diagnostics on reset.
280 EFI_SUCCESS - The device was reset.
284 GOP_PRIVATE_DATA
*Private
;
286 Private
= GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This
);
294 The function reads the next keystroke from the input device. If
295 there is no pending keystroke the function returns
296 EFI_NOT_READY. If there is a pending keystroke, then
297 KeyData.Key.ScanCode is the EFI scan code defined in Error!
298 Reference source not found. The KeyData.Key.UnicodeChar is the
299 actual printable character or is zero if the key does not
300 represent a printable character (control key, function key,
301 etc.). The KeyData.KeyState is shift state for the character
302 reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode .
303 When interpreting the data from this function, it should be
304 noted that if a class of printable characters that are
305 normally adjusted by shift modifiers (e.g. Shift Key + "f"
306 key) would be presented solely as a KeyData.Key.UnicodeChar
307 without the associated shift state. So in the previous example
308 of a Shift Key + "f" key being pressed, the only pertinent
309 data returned would be KeyData.Key.UnicodeChar with the value
310 of "F". This of course would not typically be the case for
311 non-printable characters such as the pressing of the Right
312 Shift Key + F10 key since the corresponding returned data
313 would be reflected both in the KeyData.KeyState.KeyShiftState
314 and KeyData.Key.ScanCode values. UEFI drivers which implement
315 the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return
316 KeyData.Key and KeyData.KeyState values. These drivers must
317 always return the most current state of
318 KeyData.KeyState.KeyShiftState and
319 KeyData.KeyState.KeyToggleState. It should also be noted that
320 certain input devices may not be able to produce shift or toggle
321 state information, and in those cases the high order bit in the
322 respective Toggle and Shift state fields should not be active.
325 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
327 @param KeyData A pointer to a buffer that is filled in with
328 the keystroke state data for the key that was
332 @retval EFI_SUCCESS The keystroke information was
335 @retval EFI_NOT_READY There was no keystroke data available.
336 EFI_DEVICE_ERROR The keystroke
337 information was not returned due to
344 UnixGopSimpleTextInExReadKeyStrokeEx (
345 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
346 OUT EFI_KEY_DATA
*KeyData
351 Reads the next keystroke from the input device. The WaitForKey Event can
352 be used to test for existance of a keystroke via WaitForEvent () call.
355 This - Protocol instance pointer.
356 KeyData - A pointer to a buffer that is filled in with the keystroke
357 state data for the key that was pressed.
360 EFI_SUCCESS - The keystroke information was returned.
361 EFI_NOT_READY - There was no keystroke data availiable.
362 EFI_DEVICE_ERROR - The keystroke information was not returned due to
364 EFI_INVALID_PARAMETER - KeyData is NULL.
369 GOP_PRIVATE_DATA
*Private
;
373 if (KeyData
== NULL
) {
374 return EFI_INVALID_PARAMETER
;
377 Private
= GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This
);
378 if (Private
->UgaIo
== NULL
) {
379 return EFI_NOT_READY
;
383 // Enter critical section
385 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
387 Status
= Private
->UgaIo
->UgaGetKey(Private
->UgaIo
, KeyData
);
390 // Leave critical section and return
392 gBS
->RestoreTPL (OldTpl
);
400 The SetState() function allows the input device hardware to
401 have state settings adjusted.
403 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
405 @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to
406 set the state for the input device.
409 @retval EFI_SUCCESS The device state was set appropriately.
411 @retval EFI_DEVICE_ERROR The device is not functioning
412 correctly and could not have the
415 @retval EFI_UNSUPPORTED The device does not support the
416 ability to have its state set.
421 UnixGopSimpleTextInExSetState (
422 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
423 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
426 GOP_PRIVATE_DATA
*Private
;
430 Private
= GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This
);
431 if (Private
->UgaIo
== NULL
) {
432 return EFI_NOT_READY
;
436 // Enter critical section
438 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
440 Status
= Private
->UgaIo
->UgaKeySetState (Private
->UgaIo
, KeyToggleState
);
442 // Leave critical section and return
444 gBS
->RestoreTPL (OldTpl
);
451 SimpleTextIn and SimpleTextInEx Notify Wait Event
453 @param Event Event whose notification function is being invoked.
454 @param Context Pointer to GOP_PRIVATE_DATA.
459 UnixGopRegisterKeyCallback (
464 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*ExNotify
= (UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*)Context
;
466 ExNotify
->KeyNotificationFn (&ExNotify
->KeyData
);
472 The RegisterKeystrokeNotify() function registers a function
473 which will be called when a specified keystroke will occur.
475 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
477 @param KeyData A pointer to a buffer that is filled in with
478 the keystroke information for the key that was
481 @param KeyNotificationFunction Points to the function to be
482 called when the key sequence
483 is typed specified by KeyData.
486 @param NotifyHandle Points to the unique handle assigned to
487 the registered notification.
489 @retval EFI_SUCCESS The device state was set
492 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary
498 UnixGopSimpleTextInExRegisterKeyNotify (
499 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
500 IN EFI_KEY_DATA
*KeyData
,
501 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
502 OUT EFI_HANDLE
*NotifyHandle
506 GOP_PRIVATE_DATA
*Private
;
507 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*CurrentNotify
;
509 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*NewNotify
;
511 if (KeyData
== NULL
|| KeyNotificationFunction
== NULL
|| NotifyHandle
== NULL
) {
512 return EFI_INVALID_PARAMETER
;
515 Private
= GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This
);
518 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
520 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
523 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
,
525 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
527 if (GopPrivateIsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
528 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
529 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
536 // Allocate resource to save the notification function
538 NewNotify
= (UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*) AllocateZeroPool (sizeof (UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
));
539 if (NewNotify
== NULL
) {
540 return EFI_OUT_OF_RESOURCES
;
543 NewNotify
->Signature
= UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
;
544 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
545 NewNotify
->NotifyHandle
= (EFI_HANDLE
) NewNotify
;
546 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (KeyData
));
547 InsertTailList (&Private
->NotifyList
, &NewNotify
->NotifyEntry
);
549 Status
= gBS
->CreateEvent (
552 UnixGopRegisterKeyCallback
,
556 ASSERT_EFI_ERROR (Status
);
559 *NotifyHandle
= NewNotify
->NotifyHandle
;
567 The UnregisterKeystrokeNotify() function removes the
568 notification which was previously registered.
570 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
572 @param NotificationHandle The handle of the notification
573 function being unregistered.
575 @retval EFI_SUCCESS The device state was set appropriately.
577 @retval EFI_INVALID_PARAMETER The NotificationHandle is
583 UnixGopSimpleTextInExUnregisterKeyNotify (
584 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
585 IN EFI_HANDLE NotificationHandle
590 Remove a registered notification function from a particular keystroke.
593 This - Protocol instance pointer.
594 NotificationHandle - The handle of the notification function being unregistered.
597 EFI_SUCCESS - The notification function was unregistered successfully.
598 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
602 GOP_PRIVATE_DATA
*Private
;
604 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*CurrentNotify
;
606 if (NotificationHandle
== NULL
) {
607 return EFI_INVALID_PARAMETER
;
610 if (((UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*) NotificationHandle
)->Signature
!= UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
) {
611 return EFI_INVALID_PARAMETER
;
614 Private
= GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This
);
616 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
619 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
,
621 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
623 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
625 // Remove the notification function from NotifyList and free resources
627 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
629 gBS
->CloseEvent (CurrentNotify
->Event
);
631 gBS
->FreePool (CurrentNotify
);
637 // Can not find the specified Notification Handle
639 return EFI_INVALID_PARAMETER
;
645 Initialize SimplelTextIn and SimpleTextInEx protocols in the Private
648 @param Private Context structure to fill in.
650 @return EFI_SUCCESS Initialization was a success
654 UnixGopInitializeSimpleTextInForWindow (
655 IN GOP_PRIVATE_DATA
*Private
661 // Initialize Simple Text In protoocol
663 Private
->SimpleTextIn
.Reset
= UnixGopSimpleTextInReset
;
664 Private
->SimpleTextIn
.ReadKeyStroke
= UnixGopSimpleTextInReadKeyStroke
;
666 Status
= gBS
->CreateEvent (
669 UnixGopSimpleTextInWaitForKey
,
671 &Private
->SimpleTextIn
.WaitForKey
673 ASSERT_EFI_ERROR (Status
);
677 // Initialize Simple Text In Ex
680 Private
->SimpleTextInEx
.Reset
= UnixGopSimpleTextInExResetEx
;
681 Private
->SimpleTextInEx
.ReadKeyStrokeEx
= UnixGopSimpleTextInExReadKeyStrokeEx
;
682 Private
->SimpleTextInEx
.SetState
= UnixGopSimpleTextInExSetState
;
683 Private
->SimpleTextInEx
.RegisterKeyNotify
= UnixGopSimpleTextInExRegisterKeyNotify
;
684 Private
->SimpleTextInEx
.UnregisterKeyNotify
= UnixGopSimpleTextInExUnregisterKeyNotify
;
686 Private
->SimpleTextInEx
.Reset (&Private
->SimpleTextInEx
, FALSE
);
688 InitializeListHead (&Private
->NotifyList
);
690 Status
= gBS
->CreateEvent (
693 UnixGopSimpleTextInWaitForKey
,
695 &Private
->SimpleTextInEx
.WaitForKeyEx
697 ASSERT_EFI_ERROR (Status
);
710 // Simple Pointer implementation.
715 Resets the pointer device hardware.
717 @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
719 @param ExtendedVerification Indicates that the driver may perform a more exhaustive
720 verification operation of the device during reset.
722 @retval EFI_SUCCESS The device was reset.
723 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset.
728 UnixGopSimplePointerReset (
729 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
730 IN BOOLEAN ExtendedVerification
733 GOP_PRIVATE_DATA
*Private
;
734 EFI_SIMPLE_POINTER_STATE State
;
737 Private
= GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This
);
738 if (Private
->UgaIo
== NULL
) {
743 // Enter critical section
745 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
748 // A reset is draining the Queue
750 while (Private
->UgaIo
->UgaGetPointerState (Private
->UgaIo
, &State
) == EFI_SUCCESS
)
754 // Leave critical section and return
756 gBS
->RestoreTPL (OldTpl
);
762 Retrieves the current state of a pointer device.
764 @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
766 @param State A pointer to the state information on the pointer device.
768 @retval EFI_SUCCESS The state of the pointer device was returned in State.
769 @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to
771 @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's
777 UnixGopSimplePointerGetState (
778 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
779 IN OUT EFI_SIMPLE_POINTER_STATE
*State
782 GOP_PRIVATE_DATA
*Private
;
786 Private
= GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This
);
787 if (Private
->UgaIo
== NULL
) {
788 return EFI_NOT_READY
;
792 // Enter critical section
794 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
796 Status
= Private
->UgaIo
->UgaGetPointerState (Private
->UgaIo
, State
);
798 // Leave critical section and return
800 gBS
->RestoreTPL (OldTpl
);
807 SimplePointer Notify Wait Event
809 @param Event Event whose notification function is being invoked.
810 @param Context Pointer to GOP_PRIVATE_DATA.
815 UnixGopSimplePointerWaitForInput (
820 GOP_PRIVATE_DATA
*Private
;
824 Private
= (GOP_PRIVATE_DATA
*) Context
;
825 if (Private
->UgaIo
== NULL
) {
830 // Enter critical section
832 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
834 Status
= Private
->UgaIo
->UgaCheckPointer (Private
->UgaIo
);
835 if (!EFI_ERROR (Status
)) {
837 // If the pointer state has changed, signal our event.
839 gBS
->SignalEvent (Event
);
842 // Leave critical section and return
844 gBS
->RestoreTPL (OldTpl
);
849 SimplePointer constructor
851 @param Private Context structure to fill in.
853 @retval EFI_SUCCESS Constructor had success
857 UnixGopInitializeSimplePointerForWindow (
858 IN GOP_PRIVATE_DATA
*Private
864 // Initialize Simple Pointer protoocol
866 Private
->PointerMode
.ResolutionX
= 1;
867 Private
->PointerMode
.ResolutionY
= 1;
868 Private
->PointerMode
.ResolutionZ
= 1;
869 Private
->PointerMode
.LeftButton
= TRUE
;
870 Private
->PointerMode
.RightButton
= TRUE
;
872 Private
->SimplePointer
.Reset
= UnixGopSimplePointerReset
;
873 Private
->SimplePointer
.GetState
= UnixGopSimplePointerGetState
;
874 Private
->SimplePointer
.Mode
= &Private
->PointerMode
;
876 Status
= gBS
->CreateEvent (
879 UnixGopSimplePointerWaitForInput
,
881 &Private
->SimplePointer
.WaitForInput