EmulatorPkg/Win: Add input/output support
The patch adds GOP and SimpleTextIn[Ex] support. Now firmware can boot to UI and Shell but timer doesn't work. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Andrew Fish <afish@apple.com> Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
This commit is contained in:
417
EmulatorPkg/Win/Host/WinGopInput.c
Normal file
417
EmulatorPkg/Win/Host/WinGopInput.c
Normal file
@@ -0,0 +1,417 @@
|
||||
/** @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;
|
||||
}
|
Reference in New Issue
Block a user