bool ro_gui_options_fonts_init_menu(void) { unsigned int i; if (default_menu) /* Already exists */ return true; default_menu = malloc(wimp_SIZEOF_MENU(5)); if (!default_menu) { warn_user("NoMemory", 0); return false; } default_menu->title_data.indirected_text.text = (char *) messages_get("DefaultFonts"); ro_gui_menu_init_structure(default_menu, 5); for (i = 0; i < 5; i++) { default_menu->entries[i].data.indirected_text.text = (char *) font_names[i]; default_menu->entries[i].data.indirected_text.size = strlen(font_names[i]); } return true; }
/** * Create a wimp menu tree from ns_menu data. * This function does *not* deal with the menu textual content - it simply * creates and populates the appropriate structures. Textual content is * generated by ro_gui_menu_translate_menu() * * \param definition Top level menu definition * \param menu Menu declaration data * \param depth Depth of menu we're currently building * \param parent_entry Entry in parent menu, or NULL if root menu * \param first First index in declaration data that is used by this menu * \param last Last index in declaration data that is used by this menu * \param prefix Prefix pf menu declaration string already seen * \param prefix_length Length of prefix */ void ro_gui_menu_define_menu_add(struct menu_definition *definition, const struct ns_menu *menu, int depth, wimp_menu_entry *parent_entry, int first, int last, const char *prefix, int prefix_length) { int entry, id, cur_depth; int entries = 0; int matches[last - first + 1]; const char *match; const char *text, *menu_text; wimp_menu *new_menu; struct menu_definition_entry *definition_entry; /* step 1: store the matches for depth and subset string */ for (entry = first; entry < last; entry++) { cur_depth = 0; match = menu->entries[entry].text; /* skip specials at start of string */ while (!isalnum(*match)) match++; /* attempt prefix match */ if ((prefix) && (strncmp(match, prefix, prefix_length))) continue; /* Find depth of this entry */ while (*match) if (*match++ == '.') cur_depth++; if (depth == cur_depth) matches[entries++] = entry; } matches[entries] = last; /* no entries, so exit */ if (entries == 0) return; /* step 2: build and link the menu. we must use realloc to stop * our memory fragmenting so we can test for sub-menus easily */ new_menu = (wimp_menu *)malloc(wimp_SIZEOF_MENU(entries)); if (!new_menu) die("No memory to create menu."); if (parent_entry) { /* Fix up sub menu pointer */ parent_entry->sub_menu = new_menu; } else { /* Root menu => fill in definition struct */ definition->title_key = menu->title; definition->current_encoding = 0; definition->menu = new_menu; } /* this is fixed up in ro_gui_menu_translate() */ new_menu->title_data.indirected_text.text = NULL; /* fill in menu flags */ ro_gui_menu_init_structure(new_menu, entries); /* and then create the entries */ for (entry = 0; entry < entries; entry++) { /* add the entry */ id = matches[entry]; text = menu->entries[id].text; /* fill in menu flags from specials at start of string */ new_menu->entries[entry].menu_flags = 0; while (!isalnum(*text)) { if (*text == '_') new_menu->entries[entry].menu_flags |= wimp_MENU_SEPARATE; text++; } /* get messages key for menu entry */ menu_text = strrchr(text, '.'); if (!menu_text) /* no '.' => top-level entry */ menu_text = text; else menu_text++; /* and move past the '.' */ /* fill in submenu data */ if (menu->entries[id].sub_window) new_menu->entries[entry].sub_menu = (wimp_menu *) (*menu->entries[id].sub_window); /* this is fixed up in ro_gui_menu_translate() */ new_menu->entries[entry].data.indirected_text.text = NULL; /* create definition entry */ definition_entry = malloc(sizeof(struct menu_definition_entry)); if (!definition_entry) die("Unable to create menu definition entry"); definition_entry->action = menu->entries[id].action; definition_entry->menu_entry = &new_menu->entries[entry]; definition_entry->entry_key = menu_text; definition_entry->next = definition->entries; definition->entries = definition_entry; /* recurse */ if (new_menu->entries[entry].sub_menu == wimp_NO_SUB_MENU) { ro_gui_menu_define_menu_add(definition, menu, depth + 1, &new_menu->entries[entry], matches[entry], matches[entry + 1], text, strlen(text)); } /* give menu warnings */ if (new_menu->entries[entry].sub_menu != wimp_NO_SUB_MENU) new_menu->entries[entry].menu_flags |= wimp_MENU_GIVE_WARNING; } new_menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED; new_menu->entries[entries - 1].menu_flags |= wimp_MENU_LAST; }