inputhandler.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,569 行 · 第 1/4 页
C
1,569 行
Character = BOXDRAW_HORIZONTAL;
}
PrintChar (Character);
}
Character = BOXDRAW_DOWN_LEFT;
PrintChar (Character);
Character = BOXDRAW_VERTICAL;
for (Index = Top + 1; Index < Bottom; Index++) {
PrintCharAt (Start, Index, Character);
PrintCharAt (End - 1, Index, Character);
}
//
// Display the One of options
//
Index2 = Top + 1;
for (Index = MenuOption->TagIndex + TopOptionIndex;
(MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP) && (Index2 < Bottom);
Index++
) {
if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
Token = MenuOption->Tags[Index].Text;
if (Initialized) {
for (ValueBackup = (UINT8) MenuOption->TagIndex;
MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_ONE_OF_OP;
ValueBackup++
) {
if (MenuOption->Tags[ValueBackup].Value == ((UINT8 *) ValueArrayBackup)[Index - MenuOption->TagIndex - 1]) {
StringPtr = GetToken (MenuOption->Tags[ValueBackup].Text, MenuOption->Handle);
break;
}
}
} else {
ValueBackup = (UINT8) Index;
StringPtr = GetToken (Token, MenuOption->Handle);
}
//
// If the string occupies multiple lines, truncate it to fit in one line,
// and append a "..." for indication.
//
if (EfiStrLen (StringPtr) > (PopUpWidth - 1)) {
TempStringPtr = EfiLibAllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1));
ASSERT ( TempStringPtr != NULL );
EfiCopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));
gBS->FreePool (StringPtr);
StringPtr = TempStringPtr;
EfiStrCat (StringPtr, L"...");
}
//
// Code to display the text should go here. Follwed by the [*]
//
if (MenuOption->Tags[ValueBackup].Suppress == TRUE) {
//
// Don't show the one, so decrease the Index2 for balance
//
Index2--;
} else if (MenuOption->Tags[ValueBackup].GrayOut == TRUE) {
//
// Gray Out the one
//
gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | POPUP_BACKGROUND);
PrintStringAt (Start + 2, Index2, StringPtr);
gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
} else if (MenuOption->Tags[ValueBackup].Value == TempValue) {
//
// Highlight the selected one
//
gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND);
PrintStringAt (Start + 2, Index2, StringPtr);
gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
HighlightPosition = Index2;
} else {
gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
PrintStringAt (Start + 2, Index2, StringPtr);
}
gBS->FreePool (StringPtr);
Index2 = Index2 + 1;
}
}
Character = BOXDRAW_UP_RIGHT;
PrintCharAt (Start, Bottom, Character);
for (Index = Start; Index + 2 < End; Index++) {
if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {
Character = GEOMETRICSHAPE_DOWN_TRIANGLE;
} else {
Character = BOXDRAW_HORIZONTAL;
}
PrintChar (Character);
}
Character = BOXDRAW_UP_LEFT;
PrintChar (Character);
//
// Get User selection and change TempValue if necessary
//
//
// Stop: One of pop-up menu
//
Key.UnicodeChar = CHAR_NULL;
if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {
Key.ScanCode = gDirection;
gDirection = 0;
goto TheKey;
}
if (!KeyInitialized) {
if (MenuOption->ThisTag->Operand == EFI_IFR_ONE_OF_OP) {
*KeyValue = MenuOption->Tags[MenuOption->TagIndex + 1].Key;
} else {
*KeyValue = MenuOption->ThisTag->Key;
}
KeyInitialized = TRUE;
}
Status = WaitForKeyStroke (&Key);
TheKey:
switch (Key.UnicodeChar) {
case '+':
case '-':
//
// If an ordered list op-code, we will allow for a popup of +/- keys
// to create an ordered list of items
//
if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {
if (Key.UnicodeChar == '+') {
if ((TopOptionIndex > 1) && (HighlightPosition == (Top + 1))) {
//
// Highlight reaches the top of the popup window, scroll one menu item.
//
TopOptionIndex--;
ShowDownArrow = TRUE;
}
if (TopOptionIndex == 1) {
ShowUpArrow = FALSE;
}
} else {
if (((TopOptionIndex + MenuLinesInView) <= PopUpMenuLines) && (HighlightPosition == (Bottom - 1))) {
//
// Highlight reaches the bottom of the popup window, scroll one menu item.
//
TopOptionIndex++;
ShowUpArrow = TRUE;
}
if ((TopOptionIndex + MenuLinesInView) == (PopUpMenuLines + 1)) {
ShowDownArrow = FALSE;
}
}
for (Index = MenuOption->TagIndex + TopOptionIndex;
MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP;
Index++
) {
if (MenuOption->Tags[Index].Operand == EFI_IFR_ORDERED_LIST_OP) {
continue;
}
if (Key.UnicodeChar == '+') {
TempIndex = Index - 1;
} else {
TempIndex = Index + 1;
}
//
// Is this the current tag we are on?
//
if (MenuOption->Tags[Index].Value == TempValue) {
//
// Is this prior tag a valid choice? If not, bail out
//
if (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
//
// Copy the destination tag to the local variable
//
EfiCopyMem (&TagBackup, &MenuOption->Tags[TempIndex], sizeof (EFI_TAG));
//
// Copy the current tag to the tag location before us
//
EfiCopyMem (&MenuOption->Tags[TempIndex], &MenuOption->Tags[Index], sizeof (EFI_TAG));
//
// Copy the backed up tag to the current location
//
EfiCopyMem (&MenuOption->Tags[Index], &TagBackup, sizeof (EFI_TAG));
//
// Adjust the array of values
//
for (Index = 0; Index < ValueCount; Index++) {
if (ValueArrayBackup[Index] == (UINT8) TempValue) {
if (Key.UnicodeChar == '+') {
if (Index == 0) {
//
// It is the top of the array already
//
break;
}
TempIndex = Index - 1;
} else {
if ((Index + 1) == ValueCount) {
//
// It is the bottom of the array already
//
break;
}
TempIndex = Index + 1;
}
ValueBackup = ValueArrayBackup[TempIndex];
ValueArrayBackup[TempIndex] = ValueArrayBackup[Index];
ValueArrayBackup[Index] = ValueBackup;
Initialized = TRUE;
break;
}
}
break;
} else {
break;
}
}
}
}
break;
case CHAR_NULL:
switch (Key.ScanCode) {
case SCAN_UP:
case SCAN_DOWN:
if (Key.ScanCode == SCAN_UP) {
if ((TopOptionIndex > 1) && (HighlightPosition == (Top + 1))) {
//
// Highlight reaches the top of the popup window, scroll one menu item.
//
TopOptionIndex--;
ShowDownArrow = TRUE;
}
if (TopOptionIndex == 1) {
ShowUpArrow = FALSE;
}
} else {
if (((TopOptionIndex + MenuLinesInView) <= PopUpMenuLines) && (HighlightPosition == (Bottom - 1))) {
//
// Highlight reaches the bottom of the popup window, scroll one menu item.
//
TopOptionIndex++;
ShowUpArrow = TRUE;
}
if ((TopOptionIndex + MenuLinesInView) == (PopUpMenuLines + 1)) {
ShowDownArrow = FALSE;
}
}
for (Index = MenuOption->TagIndex + TopOptionIndex;
MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP;
Index++
) {
if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
if (Initialized) {
for (Index = 0; (ValueArrayBackup[Index] != TempValue) && (Index < ValueCount); Index++)
;
//
// Did we hit the end of the array? Either get the first TempValue or the next one
//
if (Key.ScanCode == SCAN_UP) {
if (Index == 0) {
TempValue = ValueArrayBackup[0];
} else {
TempValue = ValueArrayBackup[Index - 1];
}
} else {
if ((Index + 1) == ValueCount) {
TempValue = ValueArrayBackup[Index];
} else {
TempValue = ValueArrayBackup[Index + 1];
}
}
break;
} else {
if (Key.ScanCode == SCAN_UP) {
TempIndex = Index - 1;
//
// Keep going until meets meaningful tag.
//
while ((MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OPTION_OP &&
MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OP &&
MenuOption->Tags[TempIndex].Operand != EFI_IFR_END_ONE_OF_OP)
||
(MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP &&
(MenuOption->Tags[TempIndex].Suppress || MenuOption->Tags[TempIndex].GrayOut))) {
TempIndex--;
}
} else {
TempIndex = Index + 1;
//
// Keep going until meets meaningful tag.
//
while ((MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OPTION_OP &&
MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OP &&
MenuOption->Tags[TempIndex].Operand != EFI_IFR_END_ONE_OF_OP)
||
(MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP &&
(MenuOption->Tags[TempIndex].Suppress || MenuOption->Tags[TempIndex].GrayOut))) {
TempIndex++;
}
}
//
// The option value is the same as what is stored in NV store. This is where we take action
//
if (MenuOption->Tags[Index].Value == TempValue) {
//
// Only if the previous op-code is an option can we select it, otherwise we are at the left-most option
//
if (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
TempValue = MenuOption->Tags[TempIndex].Value;
*KeyValue = MenuOption->Tags[TempIndex].Key;
} else {
TempValue = MenuOption->Tags[Index].Value;
*KeyValue = MenuOption->Tags[Index].Key;
}
break;
}
}
}
}
break;
case SCAN_ESC:
gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
if (ValueArrayBackup != NULL) {
gBS->FreePool (ValueArrayBackup);
}
return EFI_DEVICE_ERROR;
default:
break;
}
break;
case CHAR_CARRIAGE_RETURN:
//
// return the current selection
//
if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {
EfiCopyMem (ValueArray, ValueArrayBackup, ValueCount);
gBS->FreePool (ValueArrayBackup);
} else {
*Value = TempValue;
}
gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
return EFI_SUCCESS;
default:
break;
}
} while (1);
gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
return EFI_SUCCESS;
}
EFI_STATUS
WaitForKeyStroke (
OUT EFI_INPUT_KEY *Key
)
{
EFI_STATUS Status;
do {
UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
} while (EFI_ERROR(Status));
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?