/* Get the icon for the specified class CLASS_NAME. If an icon for CLASS_NAME already exists in the cache, then a reference to the cached bitmap is returned. If it is not cached, then it is loaded and cached. If no icon could be could for CLASS_NAME, then 0 is returned. */ static struct grub_video_bitmap * get_icon_by_class (grub_gfxmenu_icon_manager_t mgr, const char *class_name) { /* First check the icon cache. */ icon_entry_t entry; for (entry = mgr->cache.next; entry; entry = entry->next) { if (grub_strcmp (entry->class_name, class_name) == 0) return entry->bitmap; } if (! mgr->theme_path) return 0; /* Otherwise, we search for an icon to load. */ char *theme_dir = grub_get_dirname (mgr->theme_path); char *icons_dir; struct grub_video_bitmap *icon; icon = 0; /* First try the theme's own icons, from "grub/themes/NAME/icons/" */ icons_dir = grub_resolve_relative_path (theme_dir, "icons/"); if (icons_dir) { icon = try_loading_icon (mgr, icons_dir, class_name); grub_free (icons_dir); } grub_free (theme_dir); if (! icon) { const char *icondir; icondir = grub_env_get ("icondir"); if (icondir) icon = try_loading_icon (mgr, icondir, class_name); } /* No icon was found. */ /* This should probably be noted in the cache, so that a search is not performed each time an icon for CLASS_NAME is requested. */ if (! icon) return 0; /* Insert a new cache entry for this icon. */ entry = grub_malloc (sizeof (*entry)); if (! entry) { grub_video_bitmap_destroy (icon); return 0; } entry->class_name = grub_strdup (class_name); entry->bitmap = icon; entry->next = mgr->cache.next; mgr->cache.next = entry; /* Link it into the cache. */ return entry->bitmap; }
/* Set properties on the view based on settings from the specified theme file. */ grub_err_t grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) { grub_file_t file; struct parsebuf p; p.view = view; p.theme_dir = grub_get_dirname (theme_path); file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME); if (! file) { grub_free (p.theme_dir); return grub_errno; } p.len = grub_file_size (file); p.buf = grub_malloc (p.len); p.pos = 0; p.line_num = 1; p.col_num = 1; p.filename = theme_path; if (! p.buf) { grub_file_close (file); grub_free (p.theme_dir); return grub_errno; } if (grub_file_read (file, p.buf, p.len) != p.len) { grub_free (p.buf); grub_file_close (file); grub_free (p.theme_dir); return grub_errno; } if (view->canvas) view->canvas->component.ops->destroy (view->canvas); view->canvas = grub_gui_canvas_new (); if (!view->canvas) goto fail; ((grub_gui_component_t) view->canvas) ->ops->set_bounds ((grub_gui_component_t) view->canvas, &view->screen); while (has_more (&p)) { /* Skip comments (lines beginning with #). */ if (peek_char (&p) == '#') { advance_to_next_line (&p); continue; } /* Find the first non-whitespace character. */ skip_whitespace (&p); /* Handle the content. */ if (peek_char (&p) == '+') { /* Skip the '+'. */ read_char (&p); read_object (&p, view->canvas); } else { read_property (&p); } if (grub_errno != GRUB_ERR_NONE) goto fail; } /* Set the new theme path. */ grub_free (view->theme_path); view->theme_path = grub_strdup (theme_path); goto cleanup; fail: if (view->canvas) { view->canvas->component.ops->destroy (view->canvas); view->canvas = 0; } cleanup: grub_free (p.buf); grub_file_close (file); grub_free (p.theme_dir); return grub_errno; }