/** @file | |
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> | |
This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
Module Name: | |
WinGopInput.c | |
Abstract: | |
This file produces the Simple Text In for an Gop window. | |
This stuff is linked at the hip to the Window, since the window | |
processing is done in a thread kicked off in WinNtGopImplementation.c | |
Since the window information is processed in an other thread we need | |
a keyboard Queue to pass data about. The Simple Text In code just | |
takes data off the Queue. The WinProc message loop takes keyboard input | |
and places it in the Queue. | |
**/ | |
#include "WinGop.h" | |
/** | |
TODO: Add function description | |
@param Private TODO: add argument description | |
@retval EFI_SUCCESS TODO: Add description for return value | |
**/ | |
EFI_STATUS | |
GopPrivateCreateQ ( | |
IN GRAPHICS_PRIVATE_DATA *Private, | |
IN GOP_QUEUE_FIXED *Queue | |
) | |
{ | |
InitializeCriticalSection (&Queue->Cs); | |
Queue->Front = 0; | |
Queue->Rear = 0; | |
return EFI_SUCCESS; | |
} | |
/** | |
TODO: Add function description | |
@param Private TODO: add argument description | |
@retval EFI_SUCCESS TODO: Add description for return value | |
**/ | |
EFI_STATUS | |
GopPrivateDestroyQ ( | |
IN GRAPHICS_PRIVATE_DATA *Private, | |
IN GOP_QUEUE_FIXED *Queue | |
) | |
{ | |
Queue->Front = 0; | |
Queue->Rear = 0; | |
DeleteCriticalSection (&Queue->Cs); | |
return EFI_SUCCESS; | |
} | |
/** | |
TODO: Add function description | |
@param Private TODO: add argument description | |
@param Key TODO: add argument description | |
@retval EFI_NOT_READY TODO: Add description for return value | |
@retval EFI_SUCCESS TODO: Add description for return value | |
**/ | |
EFI_STATUS | |
GopPrivateAddQ ( | |
IN GRAPHICS_PRIVATE_DATA *Private, | |
IN GOP_QUEUE_FIXED *Queue, | |
IN EFI_KEY_DATA *KeyData | |
) | |
{ | |
EnterCriticalSection (&Queue->Cs); | |
if ((Queue->Rear + 1) % MAX_Q == Queue->Front) { | |
LeaveCriticalSection (&Queue->Cs); | |
return EFI_NOT_READY; | |
} | |
CopyMem (&Queue->Q[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA)); | |
Queue->Rear = (Queue->Rear + 1) % MAX_Q; | |
LeaveCriticalSection (&Queue->Cs); | |
return EFI_SUCCESS; | |
} | |
/** | |
TODO: Add function description | |
@param Private TODO: add argument description | |
@param Key TODO: add argument description | |
@retval EFI_NOT_READY TODO: Add description for return value | |
@retval EFI_SUCCESS TODO: Add description for return value | |
**/ | |
EFI_STATUS | |
GopPrivateDeleteQ ( | |
IN GRAPHICS_PRIVATE_DATA *Private, | |
IN GOP_QUEUE_FIXED *Queue, | |
OUT EFI_KEY_DATA *Key | |
) | |
{ | |
EnterCriticalSection (&Queue->Cs); | |
if (Queue->Front == Queue->Rear) { | |
LeaveCriticalSection (&Queue->Cs); | |
return EFI_NOT_READY; | |
} | |
CopyMem (Key, &Queue->Q[Queue->Front], sizeof (EFI_KEY_DATA)); | |
Queue->Front = (Queue->Front + 1) % MAX_Q; | |
if (Key->Key.ScanCode == SCAN_NULL && Key->Key.UnicodeChar == CHAR_NULL) { | |
if (!Private->IsPartialKeySupport) { | |
// | |
// If partial keystrok is not enabled, don't return the partial keystroke. | |
// | |
LeaveCriticalSection (&Queue->Cs); | |
ZeroMem (Key, sizeof (EFI_KEY_DATA)); | |
return EFI_NOT_READY; | |
} | |
} | |
LeaveCriticalSection (&Queue->Cs); | |
return EFI_SUCCESS; | |
} | |
/** | |
TODO: Add function description | |
@param Private TODO: add argument description | |
@retval EFI_NOT_READY TODO: Add description for return value | |
@retval EFI_SUCCESS TODO: Add description for return value | |
**/ | |
EFI_STATUS | |
GopPrivateCheckQ ( | |
IN GOP_QUEUE_FIXED *Queue | |
) | |
{ | |
if (Queue->Front == Queue->Rear) { | |
return EFI_NOT_READY; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Initialize the key state. | |
@param Private The GOP_PRIVATE_DATA instance. | |
@param KeyState A pointer to receive the key state information. | |
**/ | |
VOID | |
InitializeKeyState ( | |
IN GRAPHICS_PRIVATE_DATA *Private, | |
IN EFI_KEY_STATE *KeyState | |
) | |
{ | |
KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID; | |
KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID; | |
// | |
// Record Key shift state and toggle state | |
// | |
if (Private->LeftCtrl) { | |
KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED; | |
} | |
if (Private->RightCtrl) { | |
KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED; | |
} | |
if (Private->LeftAlt) { | |
KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED; | |
} | |
if (Private->RightAlt) { | |
KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED; | |
} | |
if (Private->LeftShift) { | |
KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; | |
} | |
if (Private->RightShift) { | |
KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; | |
} | |
if (Private->LeftLogo) { | |
KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED; | |
} | |
if (Private->RightLogo) { | |
KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; | |
} | |
if (Private->Menu) { | |
KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED; | |
} | |
if (Private->SysReq) { | |
KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED; | |
} | |
if (Private->CapsLock) { | |
KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; | |
} | |
if (Private->NumLock) { | |
KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE; | |
} | |
if (Private->ScrollLock) { | |
KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE; | |
} | |
if (Private->IsPartialKeySupport) { | |
KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED; | |
} | |
} | |
/** | |
TODO: Add function description | |
@param Private TODO: add argument description | |
@param Key TODO: add argument description | |
@retval EFI_NOT_READY TODO: Add description for return value | |
@retval EFI_SUCCESS TODO: Add description for return value | |
**/ | |
EFI_STATUS | |
GopPrivateAddKey ( | |
IN GRAPHICS_PRIVATE_DATA *Private, | |
IN EFI_INPUT_KEY Key | |
) | |
{ | |
EFI_KEY_DATA KeyData; | |
KeyData.Key = Key; | |
InitializeKeyState (Private, &KeyData.KeyState); | |
// | |
// Convert Ctrl+[1-26] to Ctrl+[A-Z] | |
// | |
if ((Private->LeftCtrl || Private->RightCtrl) && | |
(KeyData.Key.UnicodeChar >= 1) && (KeyData.Key.UnicodeChar <= 26) | |
) { | |
if ((Private->LeftShift || Private->RightShift) == Private->CapsLock) { | |
KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'a' - 1); | |
} else { | |
KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'A' - 1); | |
} | |
} | |
// | |
// Unmask the Shift bit for printable char | |
// | |
if (((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) || | |
((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) | |
) { | |
KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED); | |
} | |
GopPrivateAddQ (Private, &Private->QueueForRead, &KeyData); | |
if (Private->MakeRegisterdKeyCallback != NULL) { | |
Private->MakeRegisterdKeyCallback (Private->RegisterdKeyCallbackContext, &KeyData); | |
} | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
WinNtWndCheckKey ( | |
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo | |
) | |
{ | |
GRAPHICS_PRIVATE_DATA *Private; | |
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); | |
return GopPrivateCheckQ (&Private->QueueForRead); | |
} | |
EFI_STATUS | |
EFIAPI | |
WinNtWndGetKey ( | |
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, | |
IN EFI_KEY_DATA *KeyData | |
) | |
/*++ | |
Routine Description: | |
Reads the next keystroke from the input device. The WaitForKey Event can | |
be used to test for existance of a keystroke via WaitForEvent () call. | |
Arguments: | |
Private - The private structure of WinNt Gop device. | |
KeyData - A pointer to a buffer that is filled in with the keystroke | |
state data for the key that was pressed. | |
Returns: | |
EFI_SUCCESS - The keystroke information was returned. | |
EFI_NOT_READY - There was no keystroke data availiable. | |
EFI_DEVICE_ERROR - The keystroke information was not returned due to | |
hardware errors. | |
EFI_INVALID_PARAMETER - KeyData is NULL. | |
--*/ | |
{ | |
EFI_STATUS Status; | |
GRAPHICS_PRIVATE_DATA *Private; | |
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); | |
ZeroMem (&KeyData->Key, sizeof (KeyData->Key)); | |
InitializeKeyState (Private, &KeyData->KeyState); | |
Status = GopPrivateCheckQ (&Private->QueueForRead); | |
if (!EFI_ERROR (Status)) { | |
// | |
// If a Key press exists try and read it. | |
// | |
Status = GopPrivateDeleteQ (Private, &Private->QueueForRead, KeyData); | |
if (!EFI_ERROR (Status)) { | |
// | |
// If partial keystroke is not enabled, check whether it is value key. If not return | |
// EFI_NOT_READY. | |
// | |
if (!Private->IsPartialKeySupport) { | |
if (KeyData->Key.ScanCode == SCAN_NULL && KeyData->Key.UnicodeChar == CHAR_NULL) { | |
Status = EFI_NOT_READY; | |
} | |
} | |
} | |
} | |
return Status; | |
} | |
EFI_STATUS | |
EFIAPI | |
WinNtWndKeySetState ( | |
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, | |
IN EFI_KEY_TOGGLE_STATE *KeyToggleState | |
) | |
{ | |
GRAPHICS_PRIVATE_DATA *Private; | |
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); | |
Private->KeyState.KeyToggleState = *KeyToggleState; | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
WinNtWndRegisterKeyNotify ( | |
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, | |
IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack, | |
IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack, | |
IN VOID *Context | |
) | |
{ | |
GRAPHICS_PRIVATE_DATA *Private; | |
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); | |
Private->MakeRegisterdKeyCallback = MakeCallBack; | |
Private->BreakRegisterdKeyCallback = BreakCallBack; | |
Private->RegisterdKeyCallbackContext = Context; | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
WinNtWndCheckPointer ( | |
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo | |
) | |
{ | |
GRAPHICS_PRIVATE_DATA *Private; | |
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); | |
return EFI_NOT_READY; | |
} | |
EFI_STATUS | |
EFIAPI | |
WinNtWndGetPointerState ( | |
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, | |
IN EFI_SIMPLE_POINTER_STATE *State | |
) | |
{ | |
GRAPHICS_PRIVATE_DATA *Private; | |
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); | |
return EFI_NOT_READY; | |
} |