X-Git-Url: https://code.delx.au/refind/blobdiff_plain/a3dd82017d0be4d3fdca46a722b41b5ff3777139..480ba418c97ece5557ac0efc5dc189ff19fb8b8f:/refind/screen.c diff --git a/refind/screen.c b/refind/screen.c index 7ee1a18..a408430 100644 --- a/refind/screen.c +++ b/refind/screen.c @@ -34,13 +34,26 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Modifications copyright (c) 2012 Roderick W. Smith + * Modifications copyright (c) 2012-2015 Roderick W. Smith * * Modifications distributed under the terms of the GNU General Public - * License (GPL) version 3 (GPLv3), a copy of which must be distributed - * with this source code or binaries made from it. + * License (GPL) version 3 (GPLv3), or (at your option) any later version. * */ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include "global.h" #include "screen.h" @@ -58,8 +71,6 @@ UINTN ConWidth; UINTN ConHeight; CHAR16 *BlankLine = NULL; -static VOID DrawScreenHeader(IN CHAR16 *Title); - // UGA defines and variables UINTN UGAWidth; @@ -119,7 +130,7 @@ VOID InitScreen(VOID) PrepareBlankLine(); // show the banner if in text mode - if (GlobalConfig.TextOnly) + if (GlobalConfig.TextOnly && (GlobalConfig.ScreensaverTime != -1)) DrawScreenHeader(L"Initializing..."); } @@ -168,7 +179,11 @@ VOID SetupScreen(VOID) // clear screen and show banner // (now we know we'll stay in graphics mode) SwitchToGraphics(); - BltClearScreen(TRUE); + if (GlobalConfig.ScreensaverTime != -1) { + BltClearScreen(TRUE); + } else { // start with screen blanked + GraphicsScreenDirty = TRUE; + } } } // VOID SetupScreen() @@ -262,7 +277,7 @@ VOID TerminateScreen(VOID) refit_call2_wrapper(ST->ConOut->EnableCursor, ST->ConOut, TRUE); } -static VOID DrawScreenHeader(IN CHAR16 *Title) +VOID DrawScreenHeader(IN CHAR16 *Title) { UINTN y; @@ -291,7 +306,7 @@ static VOID DrawScreenHeader(IN CHAR16 *Title) // Keyboard input // -static BOOLEAN ReadAllKeyStrokes(VOID) +BOOLEAN ReadAllKeyStrokes(VOID) { BOOLEAN GotKeyStrokes; EFI_STATUS Status; @@ -326,6 +341,11 @@ VOID PauseForKey(VOID) Print(L"\n"); } +// Pause a specified number of seconds +VOID PauseSeconds(UINTN Seconds) { + refit_call1_wrapper(BS->Stall, 1000000 * Seconds); +} // VOID PauseSeconds() + #if REFIT_DEBUG > 0 VOID DebugPause(VOID) { @@ -394,7 +414,6 @@ BOOLEAN CheckFatalError(IN EFI_STATUS Status, IN CHAR16 *where) if (!EFI_ERROR(Status)) return FALSE; -// StatusToString(ErrorName, Status); gST->ConOut->SetAttribute (gST->ConOut, ATTR_ERROR); Print(L"Fatal Error: %r %s\n", Status, where); gST->ConOut->SetAttribute (gST->ConOut, ATTR_BASIC); @@ -407,12 +426,9 @@ BOOLEAN CheckFatalError(IN EFI_STATUS Status, IN CHAR16 *where) BOOLEAN CheckError(IN EFI_STATUS Status, IN CHAR16 *where) { -// CHAR16 ErrorName[64]; - if (!EFI_ERROR(Status)) return FALSE; -// StatusToString(ErrorName, Status); gST->ConOut->SetAttribute (gST->ConOut, ATTR_ERROR); Print(L"Error: %r %s\n", Status, where); gST->ConOut->SetAttribute (gST->ConOut, ATTR_BASIC); @@ -433,52 +449,64 @@ VOID SwitchToGraphicsAndClear(VOID) BltClearScreen(TRUE); } -VOID BltClearScreen(IN BOOLEAN ShowBanner) +VOID BltClearScreen(BOOLEAN ShowBanner) { - static EG_IMAGE *Banner = NULL, *CroppedBanner; + static EG_IMAGE *Banner = NULL; + EG_IMAGE *NewBanner = NULL; INTN BannerPosX, BannerPosY; + EG_PIXEL Black = { 0x0, 0x0, 0x0, 0 }; if (ShowBanner && !(GlobalConfig.HideUIFlags & HIDEUI_FLAG_BANNER)) { // load banner on first call if (Banner == NULL) { - if (GlobalConfig.BannerFileName == NULL) { - Banner = egPrepareEmbeddedImage(&egemb_refind_banner, FALSE); - } else { + if (GlobalConfig.BannerFileName) Banner = egLoadImage(SelfDir, GlobalConfig.BannerFileName, FALSE); - if (Banner && ((Banner->Width > UGAWidth) || (Banner->Height > UGAHeight))) { - CroppedBanner = egCropImage(Banner, 0, 0, (Banner->Width > UGAWidth) ? UGAWidth : Banner->Width, - (Banner->Height > UGAHeight) ? UGAHeight : Banner->Height); - MyFreePool(Banner); - Banner = CroppedBanner; - } // if image too big - if (Banner == NULL) { - Banner = egPrepareEmbeddedImage(&egemb_refind_banner, FALSE); - } // if unusable image - } - if (Banner != NULL) - MenuBackgroundPixel = Banner->PixelData[0]; + if (Banner == NULL) + Banner = egPrepareEmbeddedImage(&egemb_refind_banner, FALSE); } + if (Banner) { + if (GlobalConfig.BannerScale == BANNER_FILLSCREEN) { + if ((Banner->Height != UGAHeight) || (Banner->Width != UGAWidth)) { + NewBanner = egScaleImage(Banner, UGAWidth, UGAHeight); + } // if + } else if ((Banner->Width > UGAWidth) || (Banner->Height > UGAHeight)) { + NewBanner = egCropImage(Banner, 0, 0, (Banner->Width > UGAWidth) ? UGAWidth : Banner->Width, + (Banner->Height > UGAHeight) ? UGAHeight : Banner->Height); + } // if/elseif + if (NewBanner) { + MyFreePool(Banner); + Banner = NewBanner; + } + MenuBackgroundPixel = Banner->PixelData[0]; + } // if Banner exists + // clear and draw banner - egClearScreen(&MenuBackgroundPixel); + if (GlobalConfig.ScreensaverTime != -1) + egClearScreen(&MenuBackgroundPixel); + else + egClearScreen(&Black); + if (Banner != NULL) { BannerPosX = (Banner->Width < UGAWidth) ? ((UGAWidth - Banner->Width) / 2) : 0; - BannerPosY = (ComputeRow0PosX() / 2) - Banner->Height; + BannerPosY = (INTN) (ComputeRow0PosY() / 2) - (INTN) Banner->Height; if (BannerPosY < 0) BannerPosY = 0; GlobalConfig.BannerBottomEdge = BannerPosY + Banner->Height; - BltImage(Banner, (UINTN) BannerPosX, (UINTN) BannerPosY); + if (GlobalConfig.ScreensaverTime != -1) + BltImage(Banner, (UINTN) BannerPosX, (UINTN) BannerPosY); } - } else { - // clear to standard background color - egClearScreen(&StdBackgroundPixel); + } else { // not showing banner + // clear to menu background color + egClearScreen(&MenuBackgroundPixel); } GraphicsScreenDirty = FALSE; egFreeImage(GlobalConfig.ScreenBackground); GlobalConfig.ScreenBackground = egCopyScreen(); -} +} // VOID BltClearScreen() + VOID BltImage(IN EG_IMAGE *Image, IN UINTN XPos, IN UINTN YPos) { @@ -560,198 +588,12 @@ VOID BltImageCompositeBadge(IN EG_IMAGE *BaseImage, IN EG_IMAGE *TopImage, IN EG } // blit to screen and clean up - if (CompImage->HasAlpha) - egDrawImageWithTransparency(CompImage, NULL, XPos, YPos, CompImage->Width, CompImage->Height); - else - egDrawImage(CompImage, XPos, YPos); - egFreeImage(CompImage); - GraphicsScreenDirty = TRUE; -} - -// Line-editing functions borrowed from gummiboot (cursor_left(), cursor_right(), & line_edit()). -// gummiboot is copyright (c) 2012 by Kay Sievers and Harald Hoyer -// and is licensed under the LGPL 2.1. - -static void cursor_left(UINTN *cursor, UINTN *first) -{ - if ((*cursor) > 0) - (*cursor)--; - else if ((*first) > 0) - (*first)--; -} - -static void cursor_right(UINTN *cursor, UINTN *first, UINTN x_max, UINTN len) -{ - if ((*cursor)+2 < x_max) - (*cursor)++; - else if ((*first) + (*cursor) < len) - (*first)++; + if (CompImage != NULL) { + if (CompImage->HasAlpha) + egDrawImageWithTransparency(CompImage, NULL, XPos, YPos, CompImage->Width, CompImage->Height); + else + egDrawImage(CompImage, XPos, YPos); + egFreeImage(CompImage); + GraphicsScreenDirty = TRUE; + } } - -BOOLEAN line_edit(CHAR16 *line_in, CHAR16 **line_out, UINTN x_max) { - CHAR16 *line; - UINTN size; - UINTN len; - UINTN first; - UINTN y_pos = 3; - CHAR16 *print; - UINTN cursor; - BOOLEAN exit; - BOOLEAN enter; - - DrawScreenHeader(L"Line Editor"); - refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, (ConWidth - 71) / 2, ConHeight - 1); - refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, - L"Use cursor keys to edit, Esc to exit, Enter to boot with edited options"); - - if (!line_in) - line_in = L""; - size = StrLen(line_in) + 1024; - line = AllocatePool(size * sizeof(CHAR16)); - StrCpy(line, line_in); - len = StrLen(line); - print = AllocatePool(x_max * sizeof(CHAR16)); - - refit_call2_wrapper(ST->ConOut->EnableCursor, ST->ConOut, TRUE); - - first = 0; - cursor = 0; - enter = FALSE; - exit = FALSE; - while (!exit) { - UINTN index; - EFI_STATUS err; - EFI_INPUT_KEY key; - UINTN i; - - i = len - first; - if (i >= x_max-2) - i = x_max-2; - CopyMem(print, line + first, i * sizeof(CHAR16)); - print[i++] = ' '; - print[i] = '\0'; - - refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 0, y_pos); - refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, print); - refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, cursor, y_pos); - - refit_call3_wrapper(BS->WaitForEvent, 1, &ST->ConIn->WaitForKey, &index); - err = refit_call2_wrapper(ST->ConIn->ReadKeyStroke, ST->ConIn, &key); - if (EFI_ERROR(err)) - continue; - - switch (key.ScanCode) { - case SCAN_ESC: - exit = TRUE; - break; - case SCAN_HOME: - cursor = 0; - first = 0; - continue; - case SCAN_END: - cursor = len; - if (cursor >= x_max) { - cursor = x_max-2; - first = len - (x_max-2); - } - continue; - case SCAN_UP: - while((first + cursor) && line[first + cursor] == ' ') - cursor_left(&cursor, &first); - while((first + cursor) && line[first + cursor] != ' ') - cursor_left(&cursor, &first); - while((first + cursor) && line[first + cursor] == ' ') - cursor_left(&cursor, &first); - if (first + cursor != len && first + cursor) - cursor_right(&cursor, &first, x_max, len); - refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, cursor, y_pos); - continue; - case SCAN_DOWN: - while(line[first + cursor] && line[first + cursor] == ' ') - cursor_right(&cursor, &first, x_max, len); - while(line[first + cursor] && line[first + cursor] != ' ') - cursor_right(&cursor, &first, x_max, len); - while(line[first + cursor] && line[first + cursor] == ' ') - cursor_right(&cursor, &first, x_max, len); - refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, cursor, y_pos); - continue; - case SCAN_RIGHT: - if (first + cursor == len) - continue; - cursor_right(&cursor, &first, x_max, len); - refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, cursor, y_pos); - continue; - case SCAN_LEFT: - cursor_left(&cursor, &first); - refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, cursor, y_pos); - continue; - case SCAN_DELETE: - if (len == 0) - continue; - if (first + cursor == len) - continue; - for (i = first + cursor; i < len; i++) - line[i] = line[i+1]; - line[len-1] = ' '; - len--; - continue; - } - - switch (key.UnicodeChar) { - case CHAR_LINEFEED: - case CHAR_CARRIAGE_RETURN: - *line_out = line; - line = NULL; - enter = TRUE; - exit = TRUE; - break; - case CHAR_BACKSPACE: - if (len == 0) - continue; - if (first == 0 && cursor == 0) - continue; - for (i = first + cursor-1; i < len; i++) - line[i] = line[i+1]; - len--; - if (cursor > 0) - cursor--; - if (cursor > 0 || first == 0) - continue; - /* show full line if it fits */ - if (len < x_max-2) { - cursor = first; - first = 0; - continue; - } - /* jump left to see what we delete */ - if (first > 10) { - first -= 10; - cursor = 10; - } else { - cursor = first; - first = 0; - } - continue; - case '\t': - case ' ' ... '~': - case 0x80 ... 0xffff: - if (len+1 == size) - continue; - for (i = len; i > first + cursor; i--) - line[i] = line[i-1]; - line[first + cursor] = key.UnicodeChar; - len++; - line[len] = '\0'; - if (cursor+2 < x_max) - cursor++; - else if (first + cursor < len) - first++; - continue; - } - } - - refit_call2_wrapper(ST->ConOut->EnableCursor, ST->ConOut, FALSE); - FreePool(print); - FreePool(line); - return enter; -} /* BOOLEAN line_edit() */