######################################################################### GRUB 2 Graphical Menu Software Design ######################################################################### :Author: Colin D. Bennett :Date: 17 August 2008 .. contents:: Introduction ============ The ``gfxmenu`` module provides a graphical menu interface for GRUB 2. It functions as an alternative to the menu interface provided by the ``normal`` module, which uses the grub terminal interface to display a menu on a character-oriented terminal. The graphical menu uses the GRUB video API, which is currently for the VESA BIOS extensions (VBE) 2.0+. This is supported on the i386-pc platform. However, the graphical menu itself does not depend on using VBE, so if another GRUB video driver were implemented, the ``gfxmenu`` graphical menu would work on the new video driver as well. Startup Sequence ================ | grub_enter_normal_mode [normal/main.c] | grub_normal_execute [normal/main.c] | read_config_file [normal/main.c] | (When ``gfxmenu.mod`` is loaded with ``insmod``, it will | call ``grub_menu_viewer_register()`` to register itself.) | GRUB_MOD_INIT (gfxmenu) [gfxmenu/gfxmenu.c] | grub_menu_viewer_register [kern/menu_viewer.c] | grub_menu_viewer_show_menu [kern/menu_viewer.c] | get_current_menu_viewer() [kern/menu_viewer.c] | show_menu() [gfxmenu/gfxmenu.c] | grub_gfxmenu_model_new [gfxmenu/model.c] | grub_gfxmenu_view_new [gfxmenu/view.c] | set_graphics_mode [gfxmenu/view.c] | grub_gfxmenu_view_load_theme [gfxmenu/theme_loader.c] GUI Components ============== The graphical menu implements a GUI component system that supports a container-based layout system. Components can be added to containers, and containers (which are a type of component) can then be added to other containers, to form a tree of components. Currently, the root component of this tree is a *canvas* component, which allows manual layout of its child components. Components (non-container): - label - image - progress_bar - circular_progress - list (currently hard coded to be a boot menu list) Containers: - canvas - hbox - vbox The GUI component instances are created by the theme loader in ``gfxmenu/theme_loader.c`` when a theme is loaded. Theme files specify statements such as ``+vbox{ +label{ text="Hello" } +label{ text="World" } }`` to add components to the component tree root. By nesting the component creation statements in the theme file, the instantiated components are nested the same way. When a component is added to a container, that new child is considered *owned* by the container. Great care should be taken if the caller retains a reference to the child component, since it will be destroyed if its parent container is destroyed. A better choice instead of storing a pointer to the child component is to use the component ID to find the desired component. Component IDs do not have to be unique (it is often useful to have multiple components with an ID of "__timeout__", for instance). In order to access and use components in the component tree, there are two functions (defined in ``gfxmenu/gui_util.c``) that are particularly useful: - ``grub_gui_find_by_id (root, id, callback, userdata)``: This function ecursively traverses the component tree rooted at *root*, and for every component that has an ID equal to *id*, calls the function pointed to by *callback* with the matching component and the void pointer *userdata* as arguments. The callback function can do whatever is desired to use the component passed in. - ``grub_gui_iterate_recursively (root, callback, userdata)``: This function calls the function pointed to by *callback* for every component that is a descendant of *root* in the component tree. When the callback function is called, the component and the void pointer *userdata* as arguments. The callback function can do whatever is desired to use the component passed in. Command Line Window =================== The terminal window used to provide command line access within the graphical menu is managed by ``gfxmenu/view.c``. The ``gfxterm`` terminal is used, and it has been modified to allow rendering to an offscreen render target to allow it to be composed into the double buffering system that the graphical menu view uses. This is bad for performance, however, so it would probably be a good idea to make it possible to temporarily disable double buffering as long as the terminal window is visible. There are still unresolved problems that occur when commands are executed from the terminal window that change the graphics mode. It's possible that making ``grub_video_restore()`` return to the graphics mode that was in use before ``grub_video_setup()`` was called might fix some of the problems. .. vim: set filetype=rst sw=3 ts=3 et: