alder_lake_bios/Insyde/InsydeSetupPkg/Drivers/H2ODisplayEngineLocalTextDxe/LTDEQuestions/LTDEDateTimeQuestion.c

648 lines
20 KiB
C

/** @file
Date and Time questions related functions.
;******************************************************************************
;* Copyright (c) 2015 - 2020, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "LTDEQuestions.h"
#include "LTDEPanels.h"
#include "LTDEPrint.h"
#include "LTDEMisc.h"
extern EFI_SETUP_MOUSE_PROTOCOL *mSetupMouse;
/**
Check if query control or question is date or time opcode.
@param[in] Control A pointer to control
@param[in] Question A pointer to question
@retval TRUE It is date or time opcode.
@retval FALSE It is not date or time opcode.
**/
STATIC
BOOLEAN
IsDateTimeOpCode (
IN H2O_LTDE_CONTROL *Control OPTIONAL,
IN H2O_FORM_BROWSER_Q *Question OPTIONAL
)
{
return (BOOLEAN) ((Control != NULL && (Control->Operand == EFI_IFR_DATE_OP || Control->Operand == EFI_IFR_TIME_OP)) ||
(Question != NULL && (Question->Operand == EFI_IFR_DATE_OP || Question->Operand == EFI_IFR_TIME_OP)));
}
/**
Check if query date or time control is being modifying.
@param[in] Control A pointer to control
@retval TRUE Control is being modifying.
@retval FALSE Control is not being modifying.
**/
BOOLEAN
IsDateTimeOpCodeBeingModified (
IN H2O_LTDE_CONTROL *Control
)
{
return (BOOLEAN) (Control != NULL &&
IsDateTimeOpCode (Control, NULL) &&
Control->ValueStrInfo.String != NULL &&
StrStr (Control->ValueStrInfo.String, L" ") != NULL);
}
STATIC
EFI_STATUS
DateTimeOpCodeRestoreValueStr (
IN H2O_LTDE_CONTROL *Control
)
{
H2O_LTDE_PANEL *SetupPagePanel;
EFI_STATUS Status;
H2O_FORM_BROWSER_S *Statement;
SetupPagePanel = GetPanel (SETUP_PAGE_PANEL_ID);
if (SetupPagePanel == NULL) {
return EFI_UNSUPPORTED;
}
Status = mDEPrivate->FBProtocol->GetSInfo (mDEPrivate->FBProtocol, Control->PageId, Control->StatementId, &Statement);
if (EFI_ERROR (Status)) {
return Status;
}
SafeFreePool ((VOID **) &Control->ValueStrInfo.String);
Control->ValueStrInfo.String = DateTimeOpCodeCreateValueStr (Statement);
SafeFreePool ((VOID **) &Statement);
DateTimeOpCodeDisplayControl (SetupPagePanel, Control);
return EFI_SUCCESS;
}
H2O_DATE_TIME_ITEM
DateTimeOpCodeGetItemValue (
IN H2O_LTDE_CONTROL *Control
)
{
if (Control == NULL || !IsDateTimeOpCode (Control, NULL)) {
return UnknownItem;
}
//
// Date display format: L"[12/31/2014]"
// Time display format: L"[23:59:59]"
//
switch (Control->Sequence) {
case 0:
return (Control->Operand == EFI_IFR_DATE_OP) ? MonthItem : HourItem;
case 1:
return (Control->Operand == EFI_IFR_DATE_OP) ? DayItem : MinuteItem;
case 2:
return (Control->Operand == EFI_IFR_DATE_OP) ? YearItem : SecondItem;
default:
break;
}
return UnknownItem;
}
CHAR16 *
DateTimeOpCodeCreateValueStr (
IN H2O_FORM_BROWSER_Q *Question
)
{
if (Question == NULL || !IsDateTimeOpCode (NULL, Question)) {
return NULL;
}
if (Question->Operand == EFI_IFR_DATE_OP) {
return CatSPrint (
NULL,
L"%c%02d%c%02d%c%04d%c",
LEFT_NUMERIC_DELIMITER,
Question->HiiValue.Value.date.Month,
DATE_SEPARATOR,
Question->HiiValue.Value.date.Day,
DATE_SEPARATOR,
Question->HiiValue.Value.date.Year,
RIGHT_NUMERIC_DELIMITER
);
} else {
return CatSPrint (
NULL,
L"%c%02d%c%02d%c%02d%c",
LEFT_NUMERIC_DELIMITER,
Question->HiiValue.Value.time.Hour,
TIME_SEPARATOR,
Question->HiiValue.Value.time.Minute,
TIME_SEPARATOR,
Question->HiiValue.Value.time.Second,
RIGHT_NUMERIC_DELIMITER
);
}
}
EFI_STATUS
DateTimeOpCodeDisplayControl (
IN H2O_LTDE_PANEL *SetupPagePanel,
IN H2O_LTDE_CONTROL *Control
)
{
H2O_LTDE_PANEL_ITEM *PanelItem;
INT32 StartY;
INT32 EndY;
INT32 X;
INT32 Y;
UINT32 NormalAttribute;
UINT32 HighlightAttribute;
BOOLEAN IsHighlight;
UINTN ValueStrSize;
CHAR16 *StrPtr;
CHAR16 CharStr[2] = {0};
BOOLEAN IsDate;
if (Control == NULL || !IsDateTimeOpCode (Control, NULL) || Control->ValueStrInfo.String == NULL || (H2O_LTDE_FIELD_HEIGHT (&Control->ControlField) != 1)) {
return EFI_INVALID_PARAMETER;
}
PanelItem = GetPanelItemByControl (SetupPagePanel, Control);
if (PanelItem == NULL) {
return EFI_NOT_FOUND;
}
StartY = PanelItem->CurrentPos;
EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&PanelItem->ItemField) - 1;
if (!IS_OVERLAP (Control->ControlField.top, Control->ControlField.bottom, StartY, EndY)) {
return EFI_SUCCESS;
}
IsDate = (Control->Operand == EFI_IFR_DATE_OP) ? TRUE : FALSE;
ValueStrSize = StrSize (Control->ValueStrInfo.String);
if ((IsDate && ValueStrSize != sizeof (L"[12/31/2014]")) ||
(!IsDate && ValueStrSize != sizeof (L"[23:59:59]"))) {
return EFI_INVALID_PARAMETER;
}
IsHighlight = IsCurrentHighlight (Control->PageId, Control->QuestionId, Control->IfrOpCode);
GetPanelColorAttribute (SetupPagePanel->VfcfPanelInfo, NULL, H2O_IFR_STYLE_TYPE_PANEL, Control->ControlStyle.PseudoClass, &NormalAttribute);
GetPanelColorAttribute (SetupPagePanel->VfcfPanelInfo, NULL, H2O_IFR_STYLE_TYPE_PANEL, H2O_STYLE_PSEUDO_CLASS_HIGHLIGHT , &HighlightAttribute);
//
// Display prompt string
//
DEConOutSetAttribute (IsHighlight ? HighlightAttribute : NormalAttribute);
StrPtr = GetAlignmentString (
Control->Text.String,
H2O_LTDE_FIELD_WIDTH (&Control->Text.StringField) + PROMPT_VALUE_SEPARATOR_WIDTH,
LTDE_STRING_ALIGNMENT_ACTION_FLUSH_LEFT
);
DisplayString (
PanelItem->ItemField.left,
PanelItem->ItemField.top + (Control->ControlField.top - PanelItem->CurrentPos),
StrPtr
);
FreePool (StrPtr);
//
// Display value string
//
StrPtr = GetAlignmentString (
Control->ValueStrInfo.String,
H2O_LTDE_FIELD_WIDTH (&Control->ValueStrInfo.StringField),
LTDE_STRING_ALIGNMENT_ACTION_FLUSH_LEFT
);
if (StrPtr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
X = PanelItem->ItemField.left + Control->ValueStrInfo.StringField.left;
Y = PanelItem->ItemField.top + (Control->ControlField.top - PanelItem->CurrentPos);
DEConOutSetAttribute (NormalAttribute);
if (IsHighlight) {
CharStr[0] = LEFT_NUMERIC_DELIMITER;
DisplayString (X, Y, CharStr);
StrPtr[0] = CHAR_NULL;
CharStr[0] = IsDate ? DATE_SEPARATOR : TIME_SEPARATOR;
DisplayString (X + 3, Y, CharStr);
DisplayString (X + 6, Y, CharStr);
StrPtr[3] = CHAR_NULL;
StrPtr[6] = CHAR_NULL;
CharStr[0] = RIGHT_NUMERIC_DELIMITER;
if (IsDate) {
DisplayString (X + 11, Y, &StrPtr[11]);
StrPtr[11] = CHAR_NULL;
} else {
CharStr[0] = RIGHT_NUMERIC_DELIMITER;
DisplayString (X + 9, Y, &StrPtr[9]);
StrPtr[9] = CHAR_NULL;
}
DEConOutSetAttribute ((Control->Sequence == 0) ? HighlightAttribute : NormalAttribute);
DisplayString (X + 1, Y, &StrPtr[1]);
DEConOutSetAttribute ((Control->Sequence == 1) ? HighlightAttribute : NormalAttribute);
DisplayString (X + 4, Y, &StrPtr[4]);
DEConOutSetAttribute ((Control->Sequence == 2) ? HighlightAttribute : NormalAttribute);
DisplayString (X + 7, Y, &StrPtr[7]);
} else {
DisplayString (X, Y, StrPtr);
}
FreePool (StrPtr);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
DateTimeOpCodeGetSequenceValue (
IN BOOLEAN IsDate,
IN RECT *ValueStrAbsField,
IN UINT32 StartX,
IN UINT32 StartY,
OUT UINT8 *Sequence
)
{
INT32 Offset;
if (ValueStrAbsField == NULL || Sequence == NULL) {
return EFI_INVALID_PARAMETER;
}
if (!IsPointOnField (ValueStrAbsField, (INT32) StartX, (INT32) StartY)) {
return EFI_NOT_FOUND;
}
Offset = (INT32) StartX - ValueStrAbsField->left;
if (Offset >= 1 && Offset <= 2) {
*Sequence = 0;
} else if (Offset >= 4 && Offset <= 5) {
*Sequence = 1;
} else if ((IsDate && Offset >= 7 && Offset <= 10) ||
(!IsDate && Offset >= 7 && Offset <= 8)) {
*Sequence = 2;
} else {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
DateTimeOpCodeGetHiiValueFromValueStr (
IN H2O_LTDE_CONTROL *Control,
OUT EFI_HII_VALUE *HiiValue
)
{
CHAR16 *ValueStr;
EFI_HII_VALUE StrHiiValue;
BOOLEAN IsDate;
EFI_TIME StrEfiTime;
if (Control == NULL || !IsDateTimeOpCode (Control, NULL) || Control->ValueStrInfo.String == NULL) {
return EFI_UNSUPPORTED;
}
CopyMem (&StrHiiValue, &Control->HiiValue, sizeof (EFI_HII_VALUE));
ValueStr = AllocateCopyPool (StrSize (Control->ValueStrInfo.String), Control->ValueStrInfo.String);
if (ValueStr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Date display format: L"[12/31/2014]"
// Time display format: L"[23:59:59]"
//
IsDate = (Control->Operand == EFI_IFR_DATE_OP) ? TRUE : FALSE;
if (IsDate) {
ValueStr[3] = CHAR_NULL;
ValueStr[6] = CHAR_NULL;
ValueStr[11] = CHAR_NULL;
StrHiiValue.Value.date.Month = (UINT8) StrDecimalToUint64 (&ValueStr[1]);
StrHiiValue.Value.date.Day = (UINT8) StrDecimalToUint64 (&ValueStr[4]);
StrHiiValue.Value.date.Year = (UINT16) StrDecimalToUint64 (&ValueStr[7]);
} else {
ValueStr[3] = CHAR_NULL;
ValueStr[6] = CHAR_NULL;
ValueStr[9] = CHAR_NULL;
StrHiiValue.Value.time.Hour = (UINT8) StrDecimalToUint64 (&ValueStr[1]);
StrHiiValue.Value.time.Minute = (UINT8) StrDecimalToUint64 (&ValueStr[4]);
StrHiiValue.Value.time.Second = (UINT8) StrDecimalToUint64 (&ValueStr[7]);
}
FreePool ((VOID *) ValueStr);
TransferHiiValueToEfiTime (&StrHiiValue, &StrEfiTime);
if ((IsDate && !IsDayValid (&StrEfiTime)) ||
(!IsDate && !IsTimeValid (&StrEfiTime))) {
return EFI_UNSUPPORTED;
}
CopyMem (HiiValue, &StrHiiValue, sizeof (StrHiiValue));
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
DateTimeOpCodeInputOnTheFly (
IN H2O_LTDE_PANEL *SetupPagePanel,
IN H2O_LTDE_CONTROL *Control,
IN EFI_INPUT_KEY *Key
)
{
CHAR16 *StrPtr;
EFI_STATUS Status;
EFI_HII_VALUE HiiValue;
if (SetupPagePanel == NULL || Control == NULL || Key == NULL || !IsDecChar (Key->UnicodeChar)) {
return EFI_INVALID_PARAMETER;
}
if (IsDateTimeOpCodeBeingModified (Control)) {
StrPtr = StrStr (Control->ValueStrInfo.String, L" ");
if (StrPtr == NULL) {
return EFI_ABORTED;
}
*StrPtr = Key->UnicodeChar;
if (IsDateTimeOpCodeBeingModified (Control)) {
DateTimeOpCodeDisplayControl (SetupPagePanel, Control);
} else {
Status = DateTimeOpCodeGetHiiValueFromValueStr (Control, &HiiValue);
if (!EFI_ERROR (Status)) {
SendChangeQNotify (Control->PageId, Control->QuestionId, &HiiValue);
} else {
DateTimeOpCodeRestoreValueStr (Control);
}
}
} else {
//
// Date display format: L"[12/31/2014]"
//
switch (Control->Sequence) {
case 0:
CopyMem (&Control->ValueStrInfo.String[1], L" ", sizeof (L" ") - sizeof (CHAR16));
break;
case 1:
CopyMem (&Control->ValueStrInfo.String[4], L" ", sizeof (L" ") - sizeof (CHAR16));
break;
case 2:
if (Control->Operand == EFI_IFR_DATE_OP) {
CopyMem (&Control->ValueStrInfo.String[7], L" ", sizeof (L" ") - sizeof (CHAR16));
} else {
CopyMem (&Control->ValueStrInfo.String[7], L" " , sizeof (L" ") - sizeof (CHAR16));
}
break;
default:
ASSERT(FALSE);
return EFI_ABORTED;
}
StrPtr = StrStr (Control->ValueStrInfo.String, L" ");
if (StrPtr == NULL) {
return EFI_ABORTED;
}
*StrPtr = Key->UnicodeChar;
DateTimeOpCodeDisplayControl (SetupPagePanel, Control);
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
DateTimeOpCodeProcessInputEvt (
IN CONST H2O_DISPLAY_ENGINE_EVT *Notify,
IN H2O_DISPLAY_ENGINE_USER_INPUT_DATA *UserInputData
)
{
EFI_STATUS Status;
EFI_INPUT_KEY *Key;
EFI_HII_VALUE HiiValue;
EFI_TIME EfiTime;
RECT ControlAbsField;
UINT8 Sequence;
BOOLEAN IsInputingOnTheFly;
H2O_LTDE_PANEL *SetupPagePanel;
H2O_LTDE_PANEL_ITEM *ContentItem;
H2O_LTDE_PANEL_ITEM *SelectedPanelItem;
H2O_LTDE_CONTROL *SelectedControl;
KEYBOARD_ATTRIBUTES KeyboardAttributes;
SetupPagePanel = GetPanel (SETUP_PAGE_PANEL_ID);
if (SetupPagePanel == NULL || SetupPagePanel->SelectedControl == NULL) {
return EFI_UNSUPPORTED;
}
Status = EFI_UNSUPPORTED;
SelectedControl = SetupPagePanel->SelectedControl;
IsInputingOnTheFly = IsDateTimeOpCodeBeingModified (SelectedControl);
if (!UserInputData->IsKeyboard) {
ContentItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT);
if (ContentItem == NULL) {
return EFI_UNSUPPORTED;
}
CopyRect (&ControlAbsField, &SelectedControl->ControlField);
OffsetRect (&ControlAbsField, ContentItem->ItemField.left, ContentItem->ItemField.top - ContentItem->CurrentPos);
if (IsInputingOnTheFly) {
if (IsVirtualKbVisibled() && mSetupMouse != NULL && UserInputData->KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
Status = mSetupMouse->GetKeyboardAttributes (mSetupMouse, &KeyboardAttributes);
if (!EFI_ERROR (Status) && !KeyboardAttributes.IsStart) {
InitializeVirtualKb (&ControlAbsField);
}
}
return EFI_SUCCESS;
}
if (UserInputData->KeyData.Key.UnicodeChar != CHAR_CARRIAGE_RETURN) {
return Status;
}
if (!IsPointOnField (&ControlAbsField, (INT32) UserInputData->CursorX, (INT32) UserInputData->CursorY)) {
if (!IsPointOnField (&SetupPagePanel->PanelField, UserInputData->CursorX, UserInputData->CursorY)) {
ShutdownVirtualKb ();
}
SelectedPanelItem = NULL;
Status = GetControlByMouse (SetupPagePanel, UserInputData->CursorX, UserInputData->CursorY, &SelectedPanelItem, &SelectedControl);
if (EFI_ERROR (Status)) {
ShutdownVirtualKb ();
}
if (SelectedControl == NULL || SelectedControl != SetupPagePanel->SelectedControl) {
ShutdownVirtualKb ();
}
return EFI_UNSUPPORTED;
}
CopyRect (&ControlAbsField, &SelectedControl->ValueStrInfo.StringField);
OffsetRect (&ControlAbsField, ContentItem->ItemField.left, ContentItem->ItemField.top - ContentItem->CurrentPos);
Status = DateTimeOpCodeGetSequenceValue ((SelectedControl->Operand == EFI_IFR_DATE_OP), &ControlAbsField, (INT32) UserInputData->CursorX, (INT32) UserInputData->CursorY, &Sequence);
if (!EFI_ERROR (Status)) {
if (Sequence != SelectedControl->Sequence) {
SelectedControl->Sequence = Sequence;
DateTimeOpCodeDisplayControl (SetupPagePanel, SelectedControl);
} else {
InitializeVirtualKb (&ControlAbsField);
}
}
return EFI_SUCCESS;
}
Key = &UserInputData->KeyData.Key;
switch (Key->ScanCode) {
case SCAN_ESC:
if (IsInputingOnTheFly) {
DateTimeOpCodeRestoreValueStr (SelectedControl);
Status = EFI_SUCCESS;
}
return Status;
default:
break;
}
switch (Key->UnicodeChar) {
case CHAR_CARRIAGE_RETURN:
case CHAR_TAB:
if (IsInputingOnTheFly) {
Status = DateTimeOpCodeGetHiiValueFromValueStr (SelectedControl, &HiiValue);
if (!EFI_ERROR (Status)) {
SendChangeQNotify (SelectedControl->PageId, SelectedControl->QuestionId, &HiiValue);
}
DateTimeOpCodeRestoreValueStr (SelectedControl);
} else {
SelectedControl->Sequence = (SelectedControl->Sequence == 2) ? 0 : SelectedControl->Sequence + 1;
DateTimeOpCodeDisplayControl (SetupPagePanel, SelectedControl);
}
return EFI_SUCCESS;
case CHAR_ADD:
case CHAR_SUB:
if (IsInputingOnTheFly) {
break;
}
TransferHiiValueToEfiTime (&SelectedControl->HiiValue, &EfiTime);
Status = GetNextDateTimeValue (
DateTimeOpCodeGetItemValue (SelectedControl),
(Key->UnicodeChar == CHAR_ADD),
&EfiTime
);
if (!EFI_ERROR (Status)) {
TransferEfiTimeToHiiValue (SelectedControl->Operand == EFI_IFR_DATE_OP, &EfiTime, &SelectedControl->HiiValue);
SendChangeQNotify (
SelectedControl->PageId,
SelectedControl->QuestionId,
&SelectedControl->HiiValue
);
}
return EFI_SUCCESS;
case CHAR_BACKSPACE:
if (IsInputingOnTheFly) {
DateTimeOpCodeRestoreValueStr (SelectedControl);
Status = EFI_SUCCESS;
}
return Status;
default:
if (IsInputingOnTheFly) {
if (!IsDecChar (Key->UnicodeChar)) {
DateTimeOpCodeRestoreValueStr (SelectedControl);
return EFI_SUCCESS;
}
DateTimeOpCodeInputOnTheFly (SetupPagePanel, SelectedControl, Key);
} else {
if (!IsVisibleChar (Key->UnicodeChar)) {
ShutdownVirtualKb ();
}
if (!IsDecChar (Key->UnicodeChar)) {
return EFI_UNSUPPORTED;
}
DateTimeOpCodeInputOnTheFly (SetupPagePanel, SelectedControl, Key);
}
break;
}
return EFI_SUCCESS;
}
EFI_STATUS
DateTimeOpCodeProcessEvt (
IN CONST H2O_DISPLAY_ENGINE_EVT *Notify,
IN H2O_DISPLAY_ENGINE_USER_INPUT_DATA *UserInputData,
IN H2O_LTDE_PANEL *QuestionPanel
)
{
EFI_STATUS Status;
if (Notify == NULL || QuestionPanel == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = EFI_UNSUPPORTED;
switch (Notify->Type) {
case H2O_DISPLAY_ENGINE_EVT_TYPE_KEYPRESS:
case H2O_DISPLAY_ENGINE_EVT_TYPE_REL_PTR_MOVE:
case H2O_DISPLAY_ENGINE_EVT_TYPE_ABS_PTR_MOVE:
if (UserInputData == NULL) {
return EFI_INVALID_PARAMETER;
}
if (mDEPrivate->DEStatus == DISPLAY_ENGINE_STATUS_AT_MENU) {
Status = DateTimeOpCodeProcessInputEvt (Notify, UserInputData);
}
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_D:
case H2O_DISPLAY_ENGINE_EVT_TYPE_SHUT_D:
Status = EFI_SUCCESS;
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_CHANGING_Q:
default:
break;
}
return Status;
}