When ESC is pressed, change the color of the character.

本文介绍了一种通过键盘输入改变屏幕字符颜色的方法,利用中断处理实现ESC按键触发颜色变化,适用于初学者理解和实践。
部署运行你感兴趣的模型镜像

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

详细分析解释一下chromium源码中的下面的函数: class OmniboxViewViews : public OmniboxView, public views::Textfield, #if BUILDFLAG(IS_CHROMEOS) public ash::input_method::InputMethodManager::CandidateWindowObserver, #endif public views::TextfieldController, public ui::CompositorObserver, public TemplateURLServiceObserver { METADATA_HEADER(OmniboxViewViews, views::Textfield) public: // Max width of the gradient mask used to smooth ElideAnimation edges. static const int kSmoothingGradientMaxWidth = 15; OmniboxViewViews(std::unique_ptr<OmniboxClient> client, bool popup_window_mode, LocationBarView* location_bar_view, const gfx::FontList& font_list); OmniboxViewViews(const OmniboxViewViews&) = delete; OmniboxViewViews& operator=(const OmniboxViewViews&) = delete; ~OmniboxViewViews() override; // Initialize, create the underlying views, etc. void Init(); // Exposes the RenderText for tests. #if defined(UNIT_TEST) gfx::RenderText* GetRenderText() { return views::Textfield::GetRenderText(); } #endif // For use when switching tabs, this saves the current state onto the tab so // that it can be restored during a later call to Update(). void SaveStateToTab(content::WebContents* tab); // Called when the window's active tab changes. void OnTabChanged(const content::WebContents* web_contents); // Called to clear the saved state for |web_contents|. void ResetTabState(content::WebContents* web_contents); // Installs the placeholder text with the name of the current default search // provider. For example, if Google is the default search provider, this shows // "Search Google or type a URL" when the Omnibox is empty and unfocused. void InstallPlaceholderText(); // Indicates if the cursor is at the end of the input. Requires that both // ends of the selection reside there. bool GetSelectionAtEnd() const; // Returns the width in pixels needed to display the current text. The // returned value includes margins. int GetTextWidth() const; // Returns the width in pixels needed to display the current text unelided. int GetUnelidedTextWidth() const; // Returns the omnibox's width in pixels. int GetWidth() const; // OmniboxView: void EmphasizeURLComponents() override; void Update() override; std::u16string GetText() const override; using OmniboxView::SetUserText; void SetUserText(const std::u16string& text, bool update_popup) override; void SetWindowTextAndCaretPos(const std::u16string& text, size_t caret_pos, bool update_popup, bool notify_text_changed) override; void SetAdditionalText(const std::u16string& additional_text) override; void EnterKeywordModeForDefaultSearchProvider() override; bool IsSelectAll() const override; void GetSelectionBounds(std::u16string::size_type* start, std::u16string::size_type* end) const override; void SelectAll(bool reversed) override; void RevertAll() override; void SetFocus(bool is_user_initiated) override; bool IsImeComposing() const override; gfx::NativeView GetRelativeWindowForPopup() const override; bool IsImeShowingPopup() const override; // views::Textfield: gfx::Size GetMinimumSize() const override; bool OnMousePressed(const ui::MouseEvent& event) override; bool OnMouseDragged(const ui::MouseEvent& event) override; void OnMouseReleased(const ui::MouseEvent& event) override; void OnPaint(gfx::Canvas* canvas) override; void ExecuteCommand(int command_id, int event_flags) override; void OnInputMethodChanged() override; void AddedToWidget() override; void RemovedFromWidget() override; std::u16string GetLabelForCommandId(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override; // For testing only. OmniboxPopupView* GetPopupViewForTesting() const; protected: // OmniboxView: void UpdateSchemeStyle(const gfx::Range& range) override; // views::Textfield: void OnThemeChanged() override; bool IsDropCursorForInsertion() const override; // Wrappers around Textfield methods that tests can override. virtual void ApplyColor(SkColor color, const gfx::Range& range); virtual void ApplyStyle(gfx::TextStyle style, bool value, const gfx::Range& range); private: friend class TestingOmniboxView; FRIEND_TEST_ALL_PREFIXES(OmniboxPopupViewViewsTest, EmitAccessibilityEvents); // TODO(tommycli): Remove the rest of these friends after porting these // browser tests to unit tests. FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, FriendlyAccessibleLabel); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, DoNotNavigateOnDrop); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, AyncDropCallback); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, AccessibleTextSelectBoundTest); enum class UnelisionGesture { HOME_KEY_PRESSED, MOUSE_RELEASE, OTHER, }; // Update the field with |text| and set the selection. |ranges| should not be // empty; even text with no selections must have at least 1 empty range in // |ranges| to indicate the cursor position. void SetTextAndSelectedRange(const std::u16string& text, const gfx::Range& selection); // Returns the selected text. std::u16string_view GetSelectedText() const; void UpdateAccessibleTextSelection() override; // Paste text from the clipboard into the omnibox. // Textfields implementation of Paste() pastes the contents of the clipboard // as is. We want to strip whitespace and other things (see GetClipboardText() // for details). The function invokes OnBefore/AfterPossibleChange() as // necessary. void OnOmniboxPaste(); // Handle keyword hint tab-to-search and tabbing through dropdown results. bool HandleEarlyTabActions(const ui::KeyEvent& event); void ClearAccessibilityLabel(); void SetAccessibilityLabel(const std::u16string& display_text, const AutocompleteMatch& match, bool notify_text_changed) override; // Returns true if the user text was updated with the full URL (without // steady-state elisions). |gesture| is the user gesture causing unelision. bool UnapplySteadyStateElisions(UnelisionGesture gesture); #if BUILDFLAG(IS_MAC) void AnnounceFriendlySuggestionText(); #endif // Get the preferred text input type, this checks the IME locale on Windows. ui::TextInputType GetPreferredTextInputType() const; // OmniboxView: void SetCaretPos(size_t caret_pos) override; void UpdatePopup() override; void ApplyCaretVisibility() override; void OnTemporaryTextMaybeChanged(const std::u16string& display_text, const AutocompleteMatch& match, bool save_original_selection, bool notify_text_changed) override; void OnInlineAutocompleteTextMaybeChanged( const std::u16string& user_text, const std::u16string& inline_autocompletion) override; void OnInlineAutocompleteTextCleared() override; void OnRevertTemporaryText(const std::u16string& display_text, const AutocompleteMatch& match) override; void OnBeforePossibleChange() override; bool OnAfterPossibleChange(bool allow_keyword_ui_change) override; void OnKeywordPlaceholderTextChange() override; gfx::NativeView GetNativeView() const override; void ShowVirtualKeyboardIfEnabled() override; void HideImeIfNeeded() override; int GetOmniboxTextLength() const override; void SetEmphasis(bool emphasize, const gfx::Range& range) override; // views::View void OnMouseMoved(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override; // views::Textfield: bool IsItemForCommandIdDynamic(int command_id) const override; void OnGestureEvent(ui::GestureEvent* event) override; bool SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) override; bool HandleAccessibleAction(const ui::AXActionData& action_data) override; void OnFocus() override; void OnBlur() override; std::u16string GetSelectionClipboardText() const override; void DoInsertChar(char16_t ch) override; bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override; void ExecuteTextEditCommand(ui::TextEditCommand command) override; bool ShouldShowPlaceholderText() const override; void UpdateAccessibleValue() override; // ash::input_method::InputMethodManager::CandidateWindowObserver: #if BUILDFLAG(IS_CHROMEOS) void CandidateWindowOpened( ash::input_method::InputMethodManager* manager) override; void CandidateWindowClosed( ash::input_method::InputMethodManager* manager) override; #endif // views::TextfieldController: void ContentsChanged(views::Textfield* sender, const std::u16string& new_contents) override; bool HandleKeyEvent(views::Textfield* sender, const ui::KeyEvent& key_event) override; void OnBeforeUserAction(views::Textfield* sender) override; void OnAfterUserAction(views::Textfield* sender) override; void OnAfterCutOrCopy(ui::ClipboardBuffer clipboard_buffer) override; void OnWriteDragData(ui::OSExchangeData* data) override; void OnGetDragOperationsForTextfield(int* drag_operations) override; void AppendDropFormats( int* formats, std::set<ui::ClipboardFormatType>* format_types) override; ui::mojom::DragOperation OnDrop(const ui::DropTargetEvent& event) override; views::View::DropCallback CreateDropCallback( const ui::DropTargetEvent& event) override; void UpdateContextMenu(ui::SimpleMenuModel* menu_contents) override; // ui::SimpleMenuModel::Delegate: bool IsCommandIdChecked(int id) const override; // ui::CompositorObserver: void OnCompositingDidCommit(ui::Compositor* compositor) override; void OnCompositingStarted(ui::Compositor* compositor, base::TimeTicks start_time) override; void OnDidPresentCompositorFrame( uint32_t frame_token, const gfx::PresentationFeedback& feedback) override; void OnCompositingShuttingDown(ui::Compositor* compositor) override; // TemplateURLServiceObserver: void OnTemplateURLServiceChanged() override; // Permits launch of the external protocol handler after user actions in // the omnibox. The handler needs to be informed that omnibox input should // always be considered "user gesture-triggered", lest it always return BLOCK. void PermitExternalProtocolHandler(); // Drops dragged text and updates `output_drag_op` accordingly. void PerformDrop(const ui::DropTargetEvent& event, ui::mojom::DragOperation& output_drag_op, std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner); // Helper method to construct part of the context menu. void MaybeAddSendTabToSelfItem(ui::SimpleMenuModel* menu_contents); // Called when the popup view becomes visible. void OnPopupOpened(); // Helper for updating placeholder color depending on whether its a keyword or // DSE placeholder. void UpdatePlaceholderTextColor(); // When true, the location bar view is read only and also is has a slightly // different presentation (smaller font size). This is used for popups. bool popup_window_mode_; // Owns either an OmniboxPopupViewViews or an OmniboxPopupViewWebUI. std::unique_ptr<OmniboxPopupView> popup_view_; base::CallbackListSubscription popup_view_opened_subscription_; // Selection persisted across temporary text changes, like popup suggestions. gfx::Range saved_temporary_selection_; // Holds the user's selection across focus changes. There is only a saved // selection if this range IsValid(). gfx::Range saved_selection_for_focus_change_; // Tracking state before and after a possible change. State state_before_change_; bool ime_composing_before_change_ = false; // |location_bar_view_| can be NULL in tests. raw_ptr<LocationBarView> location_bar_view_; #if BUILDFLAG(IS_CHROMEOS) // True if the IME candidate window is open. When this is true, we want to // avoid showing the popup. So far, the candidate window is detected only // on Chrome OS. bool ime_candidate_window_open_ = false; #endif // True if any mouse button is currently depressed. bool is_mouse_pressed_ = false; // Applies a minimum threshold to drag events after unelision. Because the // text shifts after unelision, we don't want unintentional mouse drags to // change the selection. bool filter_drag_events_for_unelision_ = false; // Should we select all the text when we see the mouse button get released? // We select in response to a click that focuses the omnibox, but we defer // until release, setting this variable back to false if we saw a drag, to // allow the user to select just a portion of the text. bool select_all_on_mouse_release_ = false; // Indicates if we want to select all text in the omnibox when we get a // GESTURE_TAP. We want to select all only when the textfield is not in focus // and gets a tap. So we use this variable to remember focus state before tap. bool select_all_on_gesture_tap_ = false; // Whether the user should be notified if the clipboard is restricted. bool show_rejection_ui_if_any_ = false; // Keep track of the word that would be selected if URL is unelided between // a single and double click. This is an edge case where the elided URL is // selected. On the double click, unelision is performed in between the first // and second clicks. This results in both the wrong word to be selected and // the wrong selection length. For example, if example.com is shown and you // try to double click on the "x", it unelides to https://example.com after // the first click, resulting in "https" being selected. size_t next_double_click_selection_len_ = 0; size_t next_double_click_selection_offset_ = 0; // The time of the first character insert operation that has not yet been // painted. Used to measure omnibox responsiveness with a histogram. base::TimeTicks insert_char_time_; // The state machine for logging the Omnibox.CharTypedToRepaintLatency // histogram. enum { NOT_ACTIVE, // Not currently tracking a char typed event. CHAR_TYPED, // Character was typed. ON_PAINT_CALLED, // Character was typed and OnPaint() called. COMPOSITING_COMMIT, // Compositing was committed after OnPaint(). COMPOSITING_STARTED, // Compositing was started. } latency_histogram_state_; // The currently selected match, if any, with additional labelling text // such as the document title and the type of search, for example: // "Google https://google.com location from bookmark", or // "cats are liquid search suggestion". std::u16string friendly_suggestion_text_; // The number of added labelling characters before editable text begins. // For example, "Google https://google.com location from history", // this is set to 7 (the length of "Google "). int friendly_suggestion_text_prefix_length_; base::ScopedObservation<ui::Compositor, ui::CompositorObserver> scoped_compositor_observation_{this}; base::ScopedObservation<TemplateURLService, TemplateURLServiceObserver> scoped_template_url_service_observation_{this}; PrefChangeRegistrar pref_change_registrar_; base::WeakPtrFactory<OmniboxViewViews> weak_factory_{this}; };
08-02
/** @file The application to show the Boot Manager Menu. Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "BootManagerMenu.h" EFI_HII_HANDLE gStringPackHandle; BOOLEAN mModeInitialized = FALSE; // // Boot video resolution and text mode. // UINT32 mBootHorizontalResolution = 0; UINT32 mBootVerticalResolution = 0; UINT32 mBootTextModeColumn = 0; UINT32 mBootTextModeRow = 0; // // BIOS setup video resolution and text mode. // UINT32 mSetupTextModeColumn = 0; UINT32 mSetupTextModeRow = 0; UINT32 mSetupHorizontalResolution = 0; UINT32 mSetupVerticalResolution = 0; /** Prints a unicode string to the default console, at the supplied cursor position, using L"%s" format. @param Column The cursor position to print the string at. @param Row The cursor position to print the string at @param String String pointer. @return Length of string printed to the console **/ UINTN PrintStringAt ( IN UINTN Column, IN UINTN Row, IN CHAR16 *String ) { UINTN ScreenWidth; UINTN ScreenRows; CHAR16 *TurncateString; EFI_STATUS Status; UINTN ShowingLength; gST->ConOut->SetCursorPosition (gST->ConOut, Column, Row); gST->ConOut->QueryMode ( gST->ConOut, gST->ConOut->Mode->Mode, &ScreenWidth, &ScreenRows ); if ((Column > (ScreenWidth - 1)) || (Row > (ScreenRows - 1))) { return 0; } if ((StrLen (String) + Column) > (ScreenWidth - 1)) { // // | - ScreenWidth - | // ...Column..................... // TurncateString length should leave one character for draw box and // require one character for string end. // ShowingLength = ScreenWidth - Column - 1; TurncateString = AllocatePool ((ShowingLength + 1) * sizeof (CHAR16)); if (TurncateString == NULL) { return 0; } Status = StrnCpyS (TurncateString, ShowingLength + 1, String, ShowingLength - 3); if (EFI_ERROR (Status)) { FreePool (TurncateString); return 0; } *(TurncateString + ShowingLength - 3) = L'.'; *(TurncateString + ShowingLength - 2) = L'.'; *(TurncateString + ShowingLength - 1) = L'.'; *(TurncateString + ShowingLength) = L'\0'; ShowingLength = Print (L"%s", TurncateString); FreePool (TurncateString); return ShowingLength; } else { return Print (L"%s", String); } } /** Prints a character to the default console, at the supplied cursor position, using L"%c" format. @param Column The cursor position to print the string at. @param Row The cursor position to print the string at. @param Character Character to print. @return Length of string printed to the console. **/ UINTN PrintCharAt ( IN UINTN Column, IN UINTN Row, CHAR16 Character ) { UINTN ScreenWidth; UINTN ScreenRows; gST->ConOut->SetCursorPosition (gST->ConOut, Column, Row); gST->ConOut->QueryMode ( gST->ConOut, gST->ConOut->Mode->Mode, &ScreenWidth, &ScreenRows ); if ((Column > (ScreenWidth - 1)) || (Row > (ScreenRows - 1))) { return 0; } return Print (L"%c", Character); } /** Count the storage space of a Unicode string which uses current language to get from input string ID. @param StringId The input string to be counted. @return Storage space for the input string. **/ UINTN GetLineWidth ( IN EFI_STRING_ID StringId ) { UINTN Index; UINTN IncrementValue; EFI_STRING String; UINTN LineWidth; LineWidth = 0; String = HiiGetString (gStringPackHandle, StringId, NULL); if (String != NULL) { Index = 0; IncrementValue = 1; do { // // Advance to the null-terminator or to the first width directive // for ( ; (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0); Index++, LineWidth = LineWidth + IncrementValue ) { } // // We hit the null-terminator, we now have a count // if (String[Index] == 0) { break; } // // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2) // if (String[Index] == NARROW_CHAR) { // // Skip to the next character // Index++; IncrementValue = 1; } else { // // Skip to the next character // Index++; IncrementValue = 2; } } while (String[Index] != 0); FreePool (String); } return LineWidth; } /** This function uses calculate the boot menu location, size and scroll bar information. @param BootMenuData The boot menu data to be processed. @return EFI_SUCCESS calculate boot menu information successful. @retval EFI_INVALID_PARAMETER Input parameter is invalid **/ EFI_STATUS InitializeBootMenuScreen ( IN OUT BOOT_MENU_POPUP_DATA *BootMenuData ) { UINTN MaxStrWidth; UINTN StrWidth; UINTN Index; UINTN Column; UINTN Row; UINTN MaxPrintRows; UINTN UnSelectableItmes; if (BootMenuData == NULL) { return EFI_INVALID_PARAMETER; } // // Get maximum string width // MaxStrWidth = 0; for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++) { StrWidth = GetLineWidth (BootMenuData->TitleToken[Index]); MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth; } for (Index = 0; Index < BootMenuData->ItemCount; Index++) { StrWidth = GetLineWidth (BootMenuData->PtrTokens[Index]); MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth; } for (Index = 0; Index < HELP_TOKEN_COUNT; Index++) { StrWidth = GetLineWidth (BootMenuData->HelpToken[Index]); MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth; } // // query current row and column to calculate boot menu location // gST->ConOut->QueryMode ( gST->ConOut, gST->ConOut->Mode->Mode, &Column, &Row ); MaxPrintRows = Row - 6; UnSelectableItmes = TITLE_TOKEN_COUNT + 2 + HELP_TOKEN_COUNT + 2; if (MaxStrWidth + 8 > Column) { BootMenuData->MenuScreen.Width = Column; } else { BootMenuData->MenuScreen.Width = MaxStrWidth + 8; } if (BootMenuData->ItemCount + UnSelectableItmes > MaxPrintRows) { BootMenuData->MenuScreen.Height = MaxPrintRows; BootMenuData->ScrollBarControl.HasScrollBar = TRUE; BootMenuData->ScrollBarControl.ItemCountPerScreen = MaxPrintRows - UnSelectableItmes; BootMenuData->ScrollBarControl.FirstItem = 0; BootMenuData->ScrollBarControl.LastItem = MaxPrintRows - UnSelectableItmes - 1; } else { BootMenuData->MenuScreen.Height = BootMenuData->ItemCount + UnSelectableItmes; BootMenuData->ScrollBarControl.HasScrollBar = FALSE; BootMenuData->ScrollBarControl.ItemCountPerScreen = BootMenuData->ItemCount; BootMenuData->ScrollBarControl.FirstItem = 0; BootMenuData->ScrollBarControl.LastItem = BootMenuData->ItemCount - 1; } BootMenuData->MenuScreen.StartCol = (Column - BootMenuData->MenuScreen.Width) / 2; BootMenuData->MenuScreen.StartRow = (Row - BootMenuData->MenuScreen.Height) / 2; return EFI_SUCCESS; } /** This function uses check boot option is wheher setup application or no @param BootOption Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array. @retval TRUE This boot option is setup application. @retval FALSE This boot options isn't setup application **/ BOOLEAN IsBootManagerMenu ( IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { EFI_STATUS Status; EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu; Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu); if (!EFI_ERROR (Status)) { EfiBootManagerFreeLoadOption (&BootManagerMenu); } return (BOOLEAN)(!EFI_ERROR (Status) && (BootOption->OptionNumber == BootManagerMenu.OptionNumber)); } /** Return whether to ignore the boot option. @param BootOption Pointer to EFI_BOOT_MANAGER_LOAD_OPTION to check. @retval TRUE Ignore the boot option. @retval FALSE Do not ignore the boot option. **/ BOOLEAN IgnoreBootOption ( IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; // // Ignore myself. // Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID **)&ImageDevicePath); ASSERT_EFI_ERROR (Status); if (CompareMem (BootOption->FilePath, ImageDevicePath, GetDevicePathSize (ImageDevicePath)) == 0) { return TRUE; } // // Do not ignore Boot Manager Menu. // if (IsBootManagerMenu (BootOption)) { return FALSE; } // // Ignore the hidden/inactive boot option. // if (((BootOption->Attributes & LOAD_OPTION_HIDDEN) != 0) || ((BootOption->Attributes & LOAD_OPTION_ACTIVE) == 0)) { return TRUE; } return FALSE; } /** This function uses to initialize boot menu data @param BootOption Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array. @param BootOptionCount Number of boot option. @param BootMenuData The Input BootMenuData to be initialized. @retval EFI_SUCCESS Initialize boot menu data successful. @retval EFI_INVALID_PARAMETER Input parameter is invalid. **/ EFI_STATUS InitializeBootMenuData ( IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption, IN UINTN BootOptionCount, OUT BOOT_MENU_POPUP_DATA *BootMenuData ) { UINTN Index; UINTN StrIndex; if ((BootOption == NULL) || (BootMenuData == NULL)) { return EFI_INVALID_PARAMETER; } BootMenuData->TitleToken[0] = STRING_TOKEN (STR_BOOT_POPUP_MENU_TITLE_STRING); BootMenuData->PtrTokens = AllocateZeroPool (BootOptionCount * sizeof (EFI_STRING_ID)); ASSERT (BootMenuData->PtrTokens != NULL); // // Skip boot option which created by BootNext Variable // for (StrIndex = 0, Index = 0; Index < BootOptionCount; Index++) { if (IgnoreBootOption (&BootOption[Index])) { continue; } ASSERT (BootOption[Index].Description != NULL); BootMenuData->PtrTokens[StrIndex++] = HiiSetString ( gStringPackHandle, 0, BootOption[Index].Description, NULL ); } BootMenuData->ItemCount = StrIndex; BootMenuData->HelpToken[0] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP1_STRING); BootMenuData->HelpToken[1] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP2_STRING); BootMenuData->HelpToken[2] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP3_STRING); InitializeBootMenuScreen (BootMenuData); BootMenuData->SelectItem = 0; return EFI_SUCCESS; } /** This function uses input select item to highlight selected item and set current selected item in BootMenuData @param WantSelectItem The user wants to select item. @param BootMenuData The boot menu data to be processed @return EFI_SUCCESS Highlight selected item and update current selected item successful @retval EFI_INVALID_PARAMETER Input parameter is invalid **/ EFI_STATUS BootMenuSelectItem ( IN UINTN WantSelectItem, IN OUT BOOT_MENU_POPUP_DATA *BootMenuData ) { INT32 SavedAttribute; EFI_STRING String; UINTN StartCol; UINTN StartRow; UINTN PrintCol; UINTN PrintRow; UINTN TopShadeNum; UINTN LowShadeNum; UINTN FirstItem; UINTN LastItem; UINTN ItemCountPerScreen; UINTN Index; BOOLEAN RePaintItems; if ((BootMenuData == NULL) || (WantSelectItem >= BootMenuData->ItemCount)) { return EFI_INVALID_PARAMETER; } ASSERT (BootMenuData->ItemCount != 0); SavedAttribute = gST->ConOut->Mode->Attribute; RePaintItems = FALSE; StartCol = BootMenuData->MenuScreen.StartCol; StartRow = BootMenuData->MenuScreen.StartRow; // // print selectable items again and adjust scroll bar if need // if (BootMenuData->ScrollBarControl.HasScrollBar && ((WantSelectItem < BootMenuData->ScrollBarControl.FirstItem) || (WantSelectItem > BootMenuData->ScrollBarControl.LastItem) || (WantSelectItem == BootMenuData->SelectItem))) { ItemCountPerScreen = BootMenuData->ScrollBarControl.ItemCountPerScreen; // // Set first item and last item // if (WantSelectItem < BootMenuData->ScrollBarControl.FirstItem) { BootMenuData->ScrollBarControl.FirstItem = WantSelectItem; BootMenuData->ScrollBarControl.LastItem = WantSelectItem + ItemCountPerScreen - 1; } else if (WantSelectItem > BootMenuData->ScrollBarControl.LastItem) { BootMenuData->ScrollBarControl.FirstItem = WantSelectItem - ItemCountPerScreen + 1; BootMenuData->ScrollBarControl.LastItem = WantSelectItem; } gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE); FirstItem = BootMenuData->ScrollBarControl.FirstItem; LastItem = BootMenuData->ScrollBarControl.LastItem; TopShadeNum = 0; if (FirstItem != 0) { TopShadeNum = (FirstItem * ItemCountPerScreen) / BootMenuData->ItemCount; if ((FirstItem * ItemCountPerScreen) % BootMenuData->ItemCount != 0) { TopShadeNum++; } PrintCol = StartCol + BootMenuData->MenuScreen.Width - 2; PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; for (Index = 0; Index < TopShadeNum; Index++, PrintRow++) { PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_LIGHT_SHADE); } } LowShadeNum = 0; if (LastItem != BootMenuData->ItemCount - 1) { LowShadeNum = ((BootMenuData->ItemCount - 1 - LastItem) * ItemCountPerScreen) / BootMenuData->ItemCount; if (((BootMenuData->ItemCount - 1 - LastItem) * ItemCountPerScreen) % BootMenuData->ItemCount != 0) { LowShadeNum++; } PrintCol = StartCol + BootMenuData->MenuScreen.Width - 2; PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + ItemCountPerScreen - LowShadeNum; for (Index = 0; Index < LowShadeNum; Index++, PrintRow++) { PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_LIGHT_SHADE); } } PrintCol = StartCol + BootMenuData->MenuScreen.Width - 2; PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + TopShadeNum; for (Index = TopShadeNum; Index < ItemCountPerScreen - LowShadeNum; Index++, PrintRow++) { PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_FULL_BLOCK); } // // Clear selectable items first // PrintCol = StartCol + 1; PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; String = AllocateZeroPool ((BootMenuData->MenuScreen.Width - 2) * sizeof (CHAR16)); ASSERT (String != NULL); for (Index = 0; Index < BootMenuData->MenuScreen.Width - 3; Index++) { String[Index] = 0x20; } for (Index = 0; Index < ItemCountPerScreen; Index++) { PrintStringAt (PrintCol, PrintRow + Index, String); } FreePool (String); // // print selectable items // for (Index = 0; Index < ItemCountPerScreen; Index++, PrintRow++) { String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[Index + FirstItem], NULL); PrintStringAt (PrintCol, PrintRow, String); FreePool (String); } RePaintItems = TRUE; } // // if Want Select and selected item isn't the same and doesn't re-draw selectable // items, clear select item // FirstItem = BootMenuData->ScrollBarControl.FirstItem; if ((WantSelectItem != BootMenuData->SelectItem) && !RePaintItems) { gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE); String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[BootMenuData->SelectItem], NULL); PrintCol = StartCol + 1; PrintRow = StartRow + 3 + BootMenuData->SelectItem - FirstItem; PrintStringAt (PrintCol, PrintRow, String); FreePool (String); } // // Print want to select item // gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLACK); String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[WantSelectItem], NULL); PrintCol = StartCol + 1; PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + WantSelectItem - FirstItem; PrintStringAt (PrintCol, PrintRow, String); FreePool (String); gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); BootMenuData->SelectItem = WantSelectItem; return EFI_SUCCESS; } /** This function uses to draw boot popup menu @param BootMenuData The Input BootMenuData to be processed. @retval EFI_SUCCESS Draw boot popup menu successful. **/ EFI_STATUS DrawBootPopupMenu ( IN BOOT_MENU_POPUP_DATA *BootMenuData ) { EFI_STRING String; UINTN Index; UINTN Width; UINTN StartCol; UINTN StartRow; UINTN PrintRow; UINTN PrintCol; UINTN LineWidth; INT32 SavedAttribute; UINTN ItemCountPerScreen; gST->ConOut->ClearScreen (gST->ConOut); SavedAttribute = gST->ConOut->Mode->Attribute; gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE); Width = BootMenuData->MenuScreen.Width; StartCol = BootMenuData->MenuScreen.StartCol; StartRow = BootMenuData->MenuScreen.StartRow; ItemCountPerScreen = BootMenuData->ScrollBarControl.ItemCountPerScreen; PrintRow = StartRow; gST->ConOut->EnableCursor (gST->ConOut, FALSE); // // Draw Boot popup menu screen // PrintCharAt (StartCol, PrintRow, BOXDRAW_DOWN_RIGHT); for (Index = 1; Index < Width - 1; Index++) { PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); } PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_DOWN_LEFT); // // Draw the screen for title // String = AllocateZeroPool ((Width - 1) * sizeof (CHAR16)); ASSERT (String != NULL); for (Index = 0; Index < Width - 2; Index++) { String[Index] = 0x20; } for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++) { PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL); PrintStringAt (StartCol + 1, PrintRow, String); PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL); } PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL_RIGHT); for (Index = 1; Index < Width - 1; Index++) { PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); } PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL_LEFT); // // Draw screen for selectable items // for (Index = 0; Index < ItemCountPerScreen; Index++) { PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL); PrintStringAt (StartCol + 1, PrintRow, String); PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL); } PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL_RIGHT); for (Index = 1; Index < Width - 1; Index++) { PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); } PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL_LEFT); // // Draw screen for Help // for (Index = 0; Index < HELP_TOKEN_COUNT; Index++) { PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL); PrintStringAt (StartCol + 1, PrintRow, String); PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL); } FreePool (String); PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_UP_RIGHT); for (Index = 1; Index < Width - 1; Index++) { PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); } PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_UP_LEFT); // // print title strings // PrintRow = StartRow + 1; for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++, PrintRow++) { String = HiiGetString (gStringPackHandle, BootMenuData->TitleToken[Index], NULL); LineWidth = GetLineWidth (BootMenuData->TitleToken[Index]); PrintCol = StartCol + (Width - LineWidth) / 2; PrintStringAt (PrintCol, PrintRow, String); FreePool (String); } // // print selectable items // PrintCol = StartCol + 1; PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; for (Index = 0; Index < ItemCountPerScreen; Index++, PrintRow++) { String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[Index], NULL); PrintStringAt (PrintCol, PrintRow, String); FreePool (String); } // // Print Help strings // PrintRow++; for (Index = 0; Index < HELP_TOKEN_COUNT; Index++, PrintRow++) { String = HiiGetString (gStringPackHandle, BootMenuData->HelpToken[Index], NULL); LineWidth = GetLineWidth (BootMenuData->HelpToken[Index]); PrintCol = StartCol + (Width - LineWidth) / 2; PrintStringAt (PrintCol, PrintRow, String); FreePool (String); } // // Print scroll bar if has scroll bar // if (BootMenuData->ScrollBarControl.HasScrollBar) { PrintCol = StartCol + Width - 2; PrintRow = StartRow + 2; PrintCharAt (PrintCol, PrintRow, GEOMETRICSHAPE_UP_TRIANGLE); PrintCharAt (PrintCol + 1, PrintRow, BOXDRAW_VERTICAL); PrintRow += (ItemCountPerScreen + 1); PrintCharAt (PrintCol, PrintRow, GEOMETRICSHAPE_DOWN_TRIANGLE); PrintCharAt (PrintCol + 1, PrintRow, BOXDRAW_VERTICAL); } gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); // // Print Selected item // BootMenuSelectItem (BootMenuData->SelectItem, BootMenuData); return EFI_SUCCESS; } /** This function uses to boot from selected item @param BootOptions Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array. @param BootOptionCount Number of boot option. @param SelectItem Current selected item. **/ VOID BootFromSelectOption ( IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions, IN UINTN BootOptionCount, IN UINTN SelectItem ) { UINTN ItemNum; UINTN Index; ASSERT (BootOptions != NULL); for (ItemNum = 0, Index = 0; Index < BootOptionCount; Index++) { if (IgnoreBootOption (&BootOptions[Index])) { continue; } if (ItemNum++ == SelectItem) { EfiBootManagerBoot (&BootOptions[Index]); break; } } } /** This function will change video resolution and text mode according to defined setup mode or defined boot mode @param IsSetupMode Indicate mode is changed to setup mode or boot mode. @retval EFI_SUCCESS Mode is changed successfully. @retval Others Mode failed to be changed. **/ EFI_STATUS EFIAPI BdsSetConsoleMode ( BOOLEAN IsSetupMode ) { EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; UINTN SizeOfInfo; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; UINT32 MaxGopMode; UINT32 MaxTextMode; UINT32 ModeNumber; UINT32 NewHorizontalResolution; UINT32 NewVerticalResolution; UINT32 NewColumns; UINT32 NewRows; UINTN HandleCount; EFI_HANDLE *HandleBuffer; EFI_STATUS Status; UINTN Index; UINTN CurrentColumn; UINTN CurrentRow; MaxGopMode = 0; MaxTextMode = 0; // // Get current video resolution and text mode // Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput ); if (EFI_ERROR (Status)) { GraphicsOutput = NULL; } Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiSimpleTextOutProtocolGuid, (VOID **)&SimpleTextOut ); if (EFI_ERROR (Status)) { SimpleTextOut = NULL; } if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) { return EFI_UNSUPPORTED; } if (IsSetupMode) { // // The required resolution and text mode is setup mode. // NewHorizontalResolution = mSetupHorizontalResolution; NewVerticalResolution = mSetupVerticalResolution; NewColumns = mSetupTextModeColumn; NewRows = mSetupTextModeRow; } else { // // The required resolution and text mode is boot mode. // NewHorizontalResolution = mBootHorizontalResolution; NewVerticalResolution = mBootVerticalResolution; NewColumns = mBootTextModeColumn; NewRows = mBootTextModeRow; } if (GraphicsOutput != NULL) { MaxGopMode = GraphicsOutput->Mode->MaxMode; } if (SimpleTextOut != NULL) { MaxTextMode = SimpleTextOut->Mode->MaxMode; } // // 1. If current video resolution is same with required video resolution, // video resolution need not be changed. // 1.1. If current text mode is same with required text mode, text mode need not be changed. // 1.2. If current text mode is different from required text mode, text mode need be changed. // 2. If current video resolution is different from required video resolution, we need restart whole console drivers. // for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) { Status = GraphicsOutput->QueryMode ( GraphicsOutput, ModeNumber, &SizeOfInfo, &Info ); if (!EFI_ERROR (Status)) { if ((Info->HorizontalResolution == NewHorizontalResolution) && (Info->VerticalResolution == NewVerticalResolution)) { if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) && (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) { // // Current resolution is same with required resolution, check if text mode need be set // Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow); ASSERT_EFI_ERROR (Status); if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) { // // If current text mode is same with required text mode. Do nothing // FreePool (Info); return EFI_SUCCESS; } else { // // If current text mode is different from required text mode. Set new video mode // for (Index = 0; Index < MaxTextMode; Index++) { Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow); if (!EFI_ERROR (Status)) { if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) { // // Required text mode is supported, set it. // Status = SimpleTextOut->SetMode (SimpleTextOut, Index); ASSERT_EFI_ERROR (Status); // // Update text mode PCD. // Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow); ASSERT_EFI_ERROR (Status); FreePool (Info); return EFI_SUCCESS; } } } if (Index == MaxTextMode) { // // If required text mode is not supported, return error. // FreePool (Info); return EFI_UNSUPPORTED; } } } else { // // If current video resolution is not same with the new one, set new video resolution. // In this case, the driver which produces simple text out need be restarted. // Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber); if (!EFI_ERROR (Status)) { FreePool (Info); break; } } } FreePool (Info); } } if (ModeNumber == MaxGopMode) { // // If the resolution is not supported, return error. // return EFI_UNSUPPORTED; } // // Set PCD to Inform GraphicsConsole to change video resolution. // Set PCD to Inform Consplitter to change text mode. // Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdConOutColumn, NewColumns); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdConOutRow, NewRows); ASSERT_EFI_ERROR (Status); // // Video mode is changed, so restart graphics console driver and higher level driver. // Reconnect graphics console driver and higher level driver. // Locate all the handles with GOP protocol and reconnect it. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleTextOutProtocolGuid, NULL, &HandleCount, &HandleBuffer ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < HandleCount; Index++) { gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); } for (Index = 0; Index < HandleCount; Index++) { gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); } if (HandleBuffer != NULL) { FreePool (HandleBuffer); } } return EFI_SUCCESS; } /** Display the boot popup menu and allow user select boot item. @param ImageHandle The image handle. @param SystemTable The system table. @retval EFI_SUCCESS Boot from selected boot option, and return success from boot option @retval EFI_NOT_FOUND User select to enter setup or can not find boot option **/ EFI_STATUS EFIAPI BootManagerMenuEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_BOOT_MANAGER_LOAD_OPTION *BootOption; UINTN BootOptionCount; EFI_STATUS Status; BOOT_MENU_POPUP_DATA BootMenuData; UINTN Index; EFI_INPUT_KEY Key; BOOLEAN ExitApplication; UINTN SelectItem; EFI_BOOT_LOGO_PROTOCOL *BootLogo; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; UINTN BootTextColumn; UINTN BootTextRow; EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; Status = gBS->LocateProtocol( &gEfiSimpleTextInputExProtocolGuid, NULL, (VOID **)&TextInputEx ); if (EFI_ERROR(Status)) { TextInputEx = NULL; } // // Set Logo status invalid when boot manager menu is launched // BootLogo = NULL; Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **)&BootLogo); if (!EFI_ERROR (Status) && (BootLogo != NULL)) { Status = BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0); ASSERT_EFI_ERROR (Status); } gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); gStringPackHandle = HiiAddPackages ( &gEfiCallerIdGuid, gImageHandle, BootManagerMenuAppStrings, NULL ); ASSERT (gStringPackHandle != NULL); // // Connect all prior to entering the platform setup menu. // EfiBootManagerConnectAll (); EfiBootManagerRefreshAllBootOption (); BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); if (!mModeInitialized) { // // After the console is ready, get current video resolution // and text mode before launching setup at first time. // Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput ); if (EFI_ERROR (Status)) { GraphicsOutput = NULL; } Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiSimpleTextOutProtocolGuid, (VOID **)&SimpleTextOut ); if (EFI_ERROR (Status)) { SimpleTextOut = NULL; } if (GraphicsOutput != NULL) { // // Get current video resolution and text mode. // mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution; mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution; } if (SimpleTextOut != NULL) { Status = SimpleTextOut->QueryMode ( SimpleTextOut, SimpleTextOut->Mode->Mode, &BootTextColumn, &BootTextRow ); mBootTextModeColumn = (UINT32)BootTextColumn; mBootTextModeRow = (UINT32)BootTextRow; } // // Get user defined text mode for setup. // mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution); mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn); mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow); mModeInitialized = TRUE; } // // Set back to conventional setup resolution // BdsSetConsoleMode (TRUE); // // Initialize Boot menu data // Status = InitializeBootMenuData (BootOption, BootOptionCount, &BootMenuData); // // According to boot menu data to draw boot popup menu // DrawBootPopupMenu (&BootMenuData); // // check user input to determine want to re-draw or boot from user selected item // ExitApplication = FALSE; EFI_KEY_DATA KeyData; BOOLEAN UseEx = (TextInputEx != NULL); while (!ExitApplication) { gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index); if (UseEx){ Status=TextInputEx->ReadKeyStrokeEx(TextInputEx,&KeyData); if (Status == EFI_SUCCESS){ Key=KeyData.Key; } } else{ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); } if (!EFI_ERROR (Status)) { if (UseEx){ if ((Key.UnicodeChar == 0x4C || Key.UnicodeChar == 0x6C) && (KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED))) { gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); CpuDeadLoop (); } } switch (Key.UnicodeChar) { case CHAR_NULL: switch (Key.ScanCode) { case SCAN_UP: SelectItem = BootMenuData.SelectItem == 0 ? BootMenuData.ItemCount - 1 : BootMenuData.SelectItem - 1; BootMenuSelectItem (SelectItem, &BootMenuData); break; case SCAN_DOWN: SelectItem = BootMenuData.SelectItem == BootMenuData.ItemCount - 1 ? 0 : BootMenuData.SelectItem + 1; BootMenuSelectItem (SelectItem, &BootMenuData); break; case SCAN_ESC: gST->ConOut->ClearScreen (gST->ConOut); ExitApplication = TRUE; // // Set boot resolution for normal boot // BdsSetConsoleMode (FALSE); break; default: break; } break; case CHAR_CARRIAGE_RETURN: gST->ConOut->ClearScreen (gST->ConOut); // // Set boot resolution for normal boot // BdsSetConsoleMode (FALSE); BootFromSelectOption (BootOption, BootOptionCount, BootMenuData.SelectItem); // // Back to boot manager menu again, set back to setup resolution // BdsSetConsoleMode (TRUE); DrawBootPopupMenu (&BootMenuData); break; default: break; } } } EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount); FreePool (BootMenuData.PtrTokens); HiiRemovePackages (gStringPackHandle); return Status; } 现在可以使用,如果我要注册一个热键事件怎么办
08-16
内容概要:本文系统阐述了企业新闻发稿在生成式引擎优化(GEO)时代下的全渠道策略与效果评估体系,涵盖当前企业传播面临的预算、资源、内容与效果评估四大挑战,并深入分析2025年新闻发稿行业五大趋势,包括AI驱动的智能化转型、精准化传播、首发内容价值提升、内容资产化及数据可视化。文章重点解析央媒、地方官媒、综合门户和自媒体四类媒体资源的特性、传播优势与发稿策略,提出基于内容适配性、时间节奏、话题设计的策略制定方法,并构建涵盖品牌价值、销售转化与GEO优化的多维评估框架。此外,结合“传声港”工具实操指南,提供AI智能投放、效果监测、自媒体管理与舆情应对的全流程解决方案,并针对科技、消费、B2B、区域品牌四大行业推出定制化发稿方案。; 适合人群:企业市场/公关负责人、品牌传播管理者、数字营销从业者及中小企业决策者,具备一定媒体传播经验并希望提升发稿效率与ROI的专业人士。; 使用场景及目标:①制定科学的新闻发稿策略,实现从“流量思维”向“价值思维”转型;②构建央媒定调、门户扩散、自媒体互动的立体化传播矩阵;③利用AI工具实现精准投放与GEO优化,提升品牌在AI搜索中的权威性与可见性;④通过数据驱动评估体系量化品牌影响力与销售转化效果。; 阅读建议:建议结合文中提供的实操清单、案例分析与工具指南进行系统学习,重点关注媒体适配性策略与GEO评估指标,在实际发稿中分阶段试点“AI+全渠道”组合策略,并定期复盘优化,以实现品牌传播的长期复利效应。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值