3 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2010, Apple, Inc. All rights reserved.<BR>
5 Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
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 VOID
**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
;
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 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (KeyData
));
546 InsertTailList (&Private
->NotifyList
, &NewNotify
->NotifyEntry
);
548 Status
= gBS
->CreateEvent (
551 UnixGopRegisterKeyCallback
,
555 ASSERT_EFI_ERROR (Status
);
558 *NotifyHandle
= NewNotify
;
566 The UnregisterKeystrokeNotify() function removes the
567 notification which was previously registered.
569 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
571 @param NotificationHandle The handle of the notification
572 function being unregistered.
574 @retval EFI_SUCCESS The device state was set appropriately.
576 @retval EFI_INVALID_PARAMETER The NotificationHandle is
582 UnixGopSimpleTextInExUnregisterKeyNotify (
583 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
584 IN VOID
*NotificationHandle
589 Remove a registered notification function from a particular keystroke.
592 This - Protocol instance pointer.
593 NotificationHandle - The handle of the notification function being unregistered.
596 EFI_SUCCESS - The notification function was unregistered successfully.
597 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
601 GOP_PRIVATE_DATA
*Private
;
603 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*CurrentNotify
;
605 if (NotificationHandle
== NULL
) {
606 return EFI_INVALID_PARAMETER
;
609 if (((UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
*) NotificationHandle
)->Signature
!= UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
) {
610 return EFI_INVALID_PARAMETER
;
613 Private
= GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This
);
615 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
618 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY
,
620 UNIX_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
622 if (CurrentNotify
== NotificationHandle
) {
624 // Remove the notification function from NotifyList and free resources
626 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
628 gBS
->CloseEvent (CurrentNotify
->Event
);
630 gBS
->FreePool (CurrentNotify
);
636 // Can not find the specified Notification Handle
638 return EFI_INVALID_PARAMETER
;
644 Initialize SimplelTextIn and SimpleTextInEx protocols in the Private
647 @param Private Context structure to fill in.
649 @return EFI_SUCCESS Initialization was a success
653 UnixGopInitializeSimpleTextInForWindow (
654 IN GOP_PRIVATE_DATA
*Private
660 // Initialize Simple Text In protoocol
662 Private
->SimpleTextIn
.Reset
= UnixGopSimpleTextInReset
;
663 Private
->SimpleTextIn
.ReadKeyStroke
= UnixGopSimpleTextInReadKeyStroke
;
665 Status
= gBS
->CreateEvent (
668 UnixGopSimpleTextInWaitForKey
,
670 &Private
->SimpleTextIn
.WaitForKey
672 ASSERT_EFI_ERROR (Status
);
676 // Initialize Simple Text In Ex
679 Private
->SimpleTextInEx
.Reset
= UnixGopSimpleTextInExResetEx
;
680 Private
->SimpleTextInEx
.ReadKeyStrokeEx
= UnixGopSimpleTextInExReadKeyStrokeEx
;
681 Private
->SimpleTextInEx
.SetState
= UnixGopSimpleTextInExSetState
;
682 Private
->SimpleTextInEx
.RegisterKeyNotify
= UnixGopSimpleTextInExRegisterKeyNotify
;
683 Private
->SimpleTextInEx
.UnregisterKeyNotify
= UnixGopSimpleTextInExUnregisterKeyNotify
;
685 Private
->SimpleTextInEx
.Reset (&Private
->SimpleTextInEx
, FALSE
);
687 InitializeListHead (&Private
->NotifyList
);
689 Status
= gBS
->CreateEvent (
692 UnixGopSimpleTextInWaitForKey
,
694 &Private
->SimpleTextInEx
.WaitForKeyEx
696 ASSERT_EFI_ERROR (Status
);
709 // Simple Pointer implementation.
714 Resets the pointer device hardware.
716 @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
718 @param ExtendedVerification Indicates that the driver may perform a more exhaustive
719 verification operation of the device during reset.
721 @retval EFI_SUCCESS The device was reset.
722 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset.
727 UnixGopSimplePointerReset (
728 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
729 IN BOOLEAN ExtendedVerification
732 GOP_PRIVATE_DATA
*Private
;
733 EFI_SIMPLE_POINTER_STATE State
;
736 Private
= GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This
);
737 if (Private
->UgaIo
== NULL
) {
742 // Enter critical section
744 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
747 // A reset is draining the Queue
749 while (Private
->UgaIo
->UgaGetPointerState (Private
->UgaIo
, &State
) == EFI_SUCCESS
)
753 // Leave critical section and return
755 gBS
->RestoreTPL (OldTpl
);
761 Retrieves the current state of a pointer device.
763 @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
765 @param State A pointer to the state information on the pointer device.
767 @retval EFI_SUCCESS The state of the pointer device was returned in State.
768 @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to
770 @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's
776 UnixGopSimplePointerGetState (
777 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
778 IN OUT EFI_SIMPLE_POINTER_STATE
*State
781 GOP_PRIVATE_DATA
*Private
;
785 Private
= GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This
);
786 if (Private
->UgaIo
== NULL
) {
787 return EFI_NOT_READY
;
791 // Enter critical section
793 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
795 Status
= Private
->UgaIo
->UgaGetPointerState (Private
->UgaIo
, State
);
797 // Leave critical section and return
799 gBS
->RestoreTPL (OldTpl
);
806 SimplePointer Notify Wait Event
808 @param Event Event whose notification function is being invoked.
809 @param Context Pointer to GOP_PRIVATE_DATA.
814 UnixGopSimplePointerWaitForInput (
819 GOP_PRIVATE_DATA
*Private
;
823 Private
= (GOP_PRIVATE_DATA
*) Context
;
824 if (Private
->UgaIo
== NULL
) {
829 // Enter critical section
831 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
833 Status
= Private
->UgaIo
->UgaCheckPointer (Private
->UgaIo
);
834 if (!EFI_ERROR (Status
)) {
836 // If the pointer state has changed, signal our event.
838 gBS
->SignalEvent (Event
);
841 // Leave critical section and return
843 gBS
->RestoreTPL (OldTpl
);
848 SimplePointer constructor
850 @param Private Context structure to fill in.
852 @retval EFI_SUCCESS Constructor had success
856 UnixGopInitializeSimplePointerForWindow (
857 IN GOP_PRIVATE_DATA
*Private
863 // Initialize Simple Pointer protoocol
865 Private
->PointerMode
.ResolutionX
= 1;
866 Private
->PointerMode
.ResolutionY
= 1;
867 Private
->PointerMode
.ResolutionZ
= 1;
868 Private
->PointerMode
.LeftButton
= TRUE
;
869 Private
->PointerMode
.RightButton
= TRUE
;
871 Private
->SimplePointer
.Reset
= UnixGopSimplePointerReset
;
872 Private
->SimplePointer
.GetState
= UnixGopSimplePointerGetState
;
873 Private
->SimplePointer
.Mode
= &Private
->PointerMode
;
875 Status
= gBS
->CreateEvent (
878 UnixGopSimplePointerWaitForInput
,
880 &Private
->SimplePointer
.WaitForInput