summaryrefslogtreecommitdiff
path: root/riscos/menus.c
diff options
context:
space:
mode:
Diffstat (limited to 'riscos/menus.c')
-rw-r--r--riscos/menus.c958
1 files changed, 0 insertions, 958 deletions
diff --git a/riscos/menus.c b/riscos/menus.c
deleted file mode 100644
index 37285c9d1..000000000
--- a/riscos/menus.c
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
- * Copyright 2005 James Bursa <bursa@users.sourceforge.net>
- * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
- * Copyright 2005 Richard Wilson <info@tinct.net>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf 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; version 2 of the License.
- *
- * NetSurf 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 <http://www.gnu.org/licenses/>.
- */
-
-/**
- * \file
- * Menu creation and handling implementation.
- */
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include "oslib/os.h"
-#include "oslib/osbyte.h"
-#include "oslib/osgbpb.h"
-#include "oslib/territory.h"
-#include "oslib/wimp.h"
-
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/utf8.h"
-#include "content/content.h"
-#include "content/hlcache.h"
-#include "content/urldb.h"
-#include "desktop/cookie_manager.h"
-#include "desktop/browser.h"
-#include "desktop/textinput.h"
-
-#include "riscos/dialog.h"
-#include "riscos/configure.h"
-#include "riscos/cookies.h"
-#include "riscos/gui.h"
-#include "riscos/global_history.h"
-#include "riscos/help.h"
-#include "riscos/hotlist.h"
-#include "riscos/menus.h"
-#include "utils/nsoption.h"
-#include "riscos/save.h"
-#include "riscos/tinct.h"
-#include "riscos/toolbar.h"
-#include "riscos/treeview.h"
-#include "riscos/url_suggest.h"
-#include "riscos/wimp.h"
-#include "riscos/wimp_event.h"
-#include "riscos/ucstables.h"
-
-struct menu_definition_entry {
- menu_action action; /**< menu action */
- wimp_menu_entry *menu_entry; /**< corresponding menu entry */
- const char *entry_key; /**< Messages key for entry text */
- struct menu_definition_entry *next; /**< next menu entry */
-};
-
-struct menu_definition {
- wimp_menu *menu; /**< corresponding menu */
- const char *title_key; /**< Messages key for title text */
- int current_encoding; /**< Identifier for current text encoding of menu text (as per OS_Byte,71,127) */
- struct menu_definition_entry *entries; /**< menu entries */
- struct menu_definition *next; /**< next menu */
-};
-
-static void ro_gui_menu_closed(void);
-static 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);
-static struct menu_definition *ro_gui_menu_find_menu(wimp_menu *menu);
-static struct menu_definition_entry *ro_gui_menu_find_entry(wimp_menu *menu,
- menu_action action);
-static menu_action ro_gui_menu_find_action(wimp_menu *menu,
- wimp_menu_entry *menu_entry);
-static int ro_gui_menu_get_checksum(void);
-static bool ro_gui_menu_translate(struct menu_definition *menu);
-
-
-/* default menu item flags */
-#define DEFAULT_FLAGS (wimp_ICON_TEXT | wimp_ICON_FILLED | \
- (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | \
- (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT))
-
-/** The currently defined menus to perform actions for */
-static struct menu_definition *ro_gui_menu_definitions;
-/** The current menu being worked with (may not be open) */
-wimp_menu *current_menu;
-/** Whether a menu is currently open */
-bool current_menu_open = false;
-/** Window that owns the current menu */
-wimp_w current_menu_window;
-/** Icon that owns the current menu (only valid for popup menus) */
-static wimp_i current_menu_icon;
-/** The available menus */
-wimp_menu *image_quality_menu, *proxy_type_menu, *languages_menu;
-
-/* the values given in PRM 3-157 for how to check menus/windows are
- * incorrect so we use a hack of checking if the sub-menu has bit 0
- * set which is undocumented but true of window handles on
- * all target OS versions */
-#define IS_MENU(menu) !((int)(menu) & 1)
-
-/**
- * Create menu structures.
- */
-
-void ro_gui_menu_init(void)
-{
- /* image quality menu */
- static const struct ns_menu images_definition = {
- "Display", {
- { "ImgStyle0", NO_ACTION, 0 },
- { "ImgStyle1", NO_ACTION, 0 },
- { "ImgStyle2", NO_ACTION, 0 },
- { "ImgStyle3", NO_ACTION, 0 },
- {NULL, 0, 0}
- }
- };
- image_quality_menu = ro_gui_menu_define_menu(&images_definition);
-
- /* proxy menu */
- static const struct ns_menu proxy_type_definition = {
- "ProxyType", {
- { "ProxyNone", NO_ACTION, 0 },
- { "ProxyNoAuth", NO_ACTION, 0 },
- { "ProxyBasic", NO_ACTION, 0 },
- { "ProxyNTLM", NO_ACTION, 0 },
- {NULL, 0, 0}
- }
- };
- proxy_type_menu = ro_gui_menu_define_menu(&proxy_type_definition);
-
- /* special case menus */
- ro_gui_url_suggest_init();
-
- /* Note: This table *must* be kept in sync with the LangNames file */
- static const struct ns_menu lang_definition = {
- "Languages", {
- { "lang_af", NO_ACTION, 0 },
- { "lang_bm", NO_ACTION, 0 },
- { "lang_ca", NO_ACTION, 0 },
- { "lang_cs", NO_ACTION, 0 },
- { "lang_cy", NO_ACTION, 0 },
- { "lang_da", NO_ACTION, 0 },
- { "lang_de", NO_ACTION, 0 },
- { "lang_en", NO_ACTION, 0 },
- { "lang_es", NO_ACTION, 0 },
- { "lang_et", NO_ACTION, 0 },
- { "lang_eu", NO_ACTION, 0 },
- { "lang_ff", NO_ACTION, 0 },
- { "lang_fi", NO_ACTION, 0 },
- { "lang_fr", NO_ACTION, 0 },
- { "lang_ga", NO_ACTION, 0 },
- { "lang_gl", NO_ACTION, 0 },
- { "lang_ha", NO_ACTION, 0 },
- { "lang_hr", NO_ACTION, 0 },
- { "lang_hu", NO_ACTION, 0 },
- { "lang_id", NO_ACTION, 0 },
- { "lang_is", NO_ACTION, 0 },
- { "lang_it", NO_ACTION, 0 },
- { "lang_lt", NO_ACTION, 0 },
- { "lang_lv", NO_ACTION, 0 },
- { "lang_ms", NO_ACTION, 0 },
- { "lang_mt", NO_ACTION, 0 },
- { "lang_nl", NO_ACTION, 0 },
- { "lang_no", NO_ACTION, 0 },
- { "lang_pl", NO_ACTION, 0 },
- { "lang_pt", NO_ACTION, 0 },
- { "lang_rn", NO_ACTION, 0 },
- { "lang_ro", NO_ACTION, 0 },
- { "lang_rw", NO_ACTION, 0 },
- { "lang_sk", NO_ACTION, 0 },
- { "lang_sl", NO_ACTION, 0 },
- { "lang_so", NO_ACTION, 0 },
- { "lang_sq", NO_ACTION, 0 },
- { "lang_sr", NO_ACTION, 0 },
- { "lang_sv", NO_ACTION, 0 },
- { "lang_sw", NO_ACTION, 0 },
- { "lang_tr", NO_ACTION, 0 },
- { "lang_uz", NO_ACTION, 0 },
- { "lang_vi", NO_ACTION, 0 },
- { "lang_wo", NO_ACTION, 0 },
- { "lang_xs", NO_ACTION, 0 },
- { "lang_yo", NO_ACTION, 0 },
- { "lang_zu", NO_ACTION, 0 },
- { NULL, 0, 0 }
- }
- };
- languages_menu = ro_gui_menu_define_menu(&lang_definition);
-}
-
-
-/**
- * Display a menu.
- *
- * \param *menu Pointer to the menu to be displayed.
- * \param x The x position.
- * \param y The y position.
- * \param w The window that the menu belongs to.
- */
-
-void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w)
-{
- os_error *error;
- struct menu_definition *definition;
-
- /* translate menu, if necessary (this returns quickly
- * if there's nothing to be done) */
- definition = ro_gui_menu_find_menu(menu);
- if (definition) {
- if (!ro_gui_menu_translate(definition)) {
- ro_warn_user("NoMemory", 0);
- return;
- }
- }
-
- /* store the menu characteristics */
- current_menu = menu;
- current_menu_window = w;
- current_menu_icon = wimp_ICON_WINDOW;
-
- /* create the menu */
- current_menu_open = true;
- error = xwimp_create_menu(menu, x - 64, y);
- if (error) {
- LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MenuError", error->errmess);
- ro_gui_menu_closed();
- }
-}
-
-
-/**
- * Display a pop-up menu next to the specified icon.
- *
- * \param menu menu to open
- * \param w window handle
- * \param i icon handle
- */
-
-void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i)
-{
- wimp_window_state state;
- wimp_icon_state icon_state;
- os_error *error;
-
- state.w = w;
- icon_state.w = w;
- icon_state.i = i;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MenuError", error->errmess);
- return;
- }
-
- error = xwimp_get_icon_state(&icon_state);
- if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MenuError", error->errmess);
- return;
- }
-
- ro_gui_menu_create(menu,
- state.visible.x0 + icon_state.icon.extent.x1 + 64,
- state.visible.y1 + icon_state.icon.extent.y1 -
- state.yscroll, w);
- current_menu_icon = i;
-}
-
-
-/**
- * Forcibly close any menu or transient dialogue box that is currently open.
- */
-
-void ro_gui_menu_destroy(void)
-{
- os_error *error;
-
- if (current_menu == NULL)
- return;
-
- error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0);
- if (error) {
- LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MenuError", error->errmess);
- }
-
- ro_gui_menu_closed();
-}
-
-
-/**
- * Allow the current menu window to change, if the window is deleted and
- * recreated while a menu is active on an Adjust-click.
- *
- * \param from The original window handle.
- * \param to The new replacement window handle.
- */
-
-void ro_gui_menu_window_changed(wimp_w from, wimp_w to)
-{
-
- if (from == current_menu_window)
- current_menu_window = to;
-}
-
-
-/**
- * Handle menu selection.
- */
-
-void ro_gui_menu_selection(wimp_selection *selection)
-{
- int i; //, j;
- wimp_menu_entry *menu_entry;
- menu_action action;
- wimp_pointer pointer;
- os_error *error;
- int previous_menu_icon = current_menu_icon;
-
- /* if we are using gui_multitask then menu selection events
- * may be delivered after the menu has been closed. As such,
- * we simply ignore these events. */
- if (!current_menu)
- return;
-
- assert(current_menu_window);
-
- /* get the menu entry and associated action and definition */
- menu_entry = &current_menu->entries[selection->items[0]];
- for (i = 1; selection->items[i] != -1; i++)
- menu_entry = &menu_entry->sub_menu->
- entries[selection->items[i]];
- action = ro_gui_menu_find_action(current_menu, menu_entry);
-
- /* Deal with the menu action. If this manages to re-prepare the
- * menu for re-opening, we test for and act on Adjust clicks.
- */
-
- if (!ro_gui_wimp_event_menu_selection(current_menu_window,
- current_menu_icon, current_menu, selection, action))
- return;
-
- /* re-open the menu for Adjust clicks */
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- ro_gui_menu_closed();
- return;
- }
-
- if (pointer.buttons != wimp_CLICK_ADJUST) {
- ro_gui_menu_closed();
- return;
- }
-
- ro_gui_menu_create(current_menu, 0, 0, current_menu_window);
- current_menu_icon = previous_menu_icon;
-}
-
-
-/**
- * Handle Message_MenuWarning.
- */
-void ro_gui_menu_warning(wimp_message_menu_warning *warning)
-{
- int i;
- menu_action action;
- wimp_menu_entry *menu_entry;
- os_error *error;
-
- assert(current_menu);
- assert(current_menu_window);
-
- /* get the sub-menu of the warning */
- if (warning->selection.items[0] == -1)
- return;
- menu_entry = &current_menu->entries[warning->selection.items[0]];
- for (i = 1; warning->selection.items[i] != -1; i++)
- menu_entry = &menu_entry->sub_menu->
- entries[warning->selection.items[i]];
- action = ro_gui_menu_find_action(current_menu, menu_entry);
-
- /* Process the warning via Wimp_Event, then register the resulting
- * submenu with the module.
- */
-
- ro_gui_wimp_event_submenu_warning(current_menu_window,
- current_menu_icon, current_menu, &(warning->selection),
- action);
-
- if (IS_MENU(menu_entry->sub_menu)) {
- ro_gui_wimp_event_register_submenu((wimp_w) 0);
- } else {
- ro_gui_wimp_event_register_submenu((wimp_w)
- menu_entry->sub_menu);
-
- /* If this is a dialogue box, remove the close and back icons.
- */
-
- ro_gui_wimp_update_window_furniture((wimp_w)
- menu_entry->sub_menu,
- wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_BACK_ICON,
- 0);
- }
-
- /* open the sub-menu */
-
- error = xwimp_create_sub_menu(menu_entry->sub_menu,
- warning->pos.x, warning->pos.y);
- if (error) {
- LOG("xwimp_create_sub_menu: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MenuError", error->errmess);
- }
-}
-
-
-/**
- * Handle Message_MenusDeleted, removing our current record of an open menu
- * if it matches the deleted menu handle.
- *
- * \param *deleted The message block.
- */
-
-void ro_gui_menu_message_deleted(wimp_message_menus_deleted *deleted)
-{
- if (deleted != NULL && deleted->menu == current_menu)
- ro_gui_menu_closed();
-}
-
-
-/**
- * Clean up after a menu has been closed, or forcibly close an open menu.
- */
-
-static void ro_gui_menu_closed(void)
-{
- if (current_menu != NULL)
- ro_gui_wimp_event_menus_closed(current_menu_window,
- current_menu_icon, current_menu);
-
- current_menu = NULL;
- current_menu_window = NULL;
- current_menu_icon = 0;
- current_menu_open = false;
-}
-
-
-/**
- * Update the current menu by sending it a Menu Prepare event through wimp_event
- * and then reopening it if the contents has changed.
- *
- * \param *menu The menu to refresh: if 0, the current menu will be
- * refreshed regardless, otherwise it will be refreshed
- * only if it matches the supplied handle.
- */
-
-void ro_gui_menu_refresh(wimp_menu *menu)
-{
- int checksum = 0;
-
- if (!current_menu_open)
- return;
-
- checksum = ro_gui_menu_get_checksum();
-
- if (!ro_gui_wimp_event_prepare_menu(current_menu_window,
- current_menu_icon, current_menu))
- return;
-
- /* \TODO -- Call the menu's event handler here. */
-
- if (checksum != ro_gui_menu_get_checksum()) {
- os_error *error;
- error = xwimp_create_menu(current_menu, 0, 0);
- if (error) {
- LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MenuError", error->errmess);
- }
- }
-}
-
-
-
-
-/**
- * Creates a wimp_menu and adds it to the list to handle actions for.
- *
- * \param menu The data to create the menu with
- * \return The menu created, or NULL on failure
- */
-wimp_menu *ro_gui_menu_define_menu(const struct ns_menu *menu)
-{
- struct menu_definition *definition;
- int entry;
-
- definition = calloc(sizeof(struct menu_definition), 1);
- if (!definition) {
- die("No memory to create menu definition.");
- return NULL; /* For the benefit of scan-build */
- }
-
- /* link in the menu to our list */
- definition->next = ro_gui_menu_definitions;
- ro_gui_menu_definitions = definition;
-
- /* count number of menu entries */
- for (entry = 0; menu->entries[entry].text; entry++)
- /* do nothing */;
-
- /* create our definitions */
- ro_gui_menu_define_menu_add(definition, menu, 0, NULL,
- 0, entry, NULL, 0);
-
- /* and translate menu into current encoding */
- if (!ro_gui_menu_translate(definition))
- die("No memory to translate menu.");
-
- return definition->menu;
-}
-
-/**
- * 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;
- int entries = 0;
- int matches[last - first + 1];
- 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++) {
- const char *match;
- int 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 */
- int 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;
-}
-
-
-/**
- * Initialise the basic state of a menu structure so all entries are
- * indirected text with no flags, no submenu.
- */
-void ro_gui_menu_init_structure(wimp_menu *menu, int entries)
-{
- int i;
-
- menu->title_fg = wimp_COLOUR_BLACK;
- menu->title_bg = wimp_COLOUR_LIGHT_GREY;
- menu->work_fg = wimp_COLOUR_BLACK;
- menu->work_bg = wimp_COLOUR_WHITE;
- menu->width = 200;
- menu->height = wimp_MENU_ITEM_HEIGHT;
- menu->gap = wimp_MENU_ITEM_GAP;
-
- for (i = 0; i < entries; i++) {
- menu->entries[i].menu_flags = 0;
- menu->entries[i].sub_menu = wimp_NO_SUB_MENU;
- menu->entries[i].icon_flags =
- DEFAULT_FLAGS | wimp_ICON_INDIRECTED;
- menu->entries[i].data.indirected_text.validation =
- (char *)-1;
- }
- menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED;
- menu->entries[i - 1].menu_flags |= wimp_MENU_LAST;
-}
-
-
-/**
- * Finds the menu_definition corresponding to a wimp_menu.
- *
- * \param menu the menu to find the definition for
- * \return the associated definition, or NULL if one could not be found
- */
-struct menu_definition *ro_gui_menu_find_menu(wimp_menu *menu)
-{
- struct menu_definition *definition;
-
- if (!menu)
- return NULL;
-
- for (definition = ro_gui_menu_definitions; definition;
- definition = definition->next)
- if (definition->menu == menu)
- return definition;
- return NULL;
-}
-
-
-/**
- * Finds the key associated with a menu entry translation.
- *
- * \param menu the menu to search
- * \param translated the translated text
- * \return the original message key, or NULL if one could not be found
- */
-const char *ro_gui_menu_find_menu_entry_key(wimp_menu *menu,
- const char *translated)
-{
- struct menu_definition_entry *entry;
- struct menu_definition *definition = ro_gui_menu_find_menu(menu);
-
- if (!definition)
- return NULL;
-
- for (entry = definition->entries; entry; entry = entry->next)
- if (!strcmp(entry->menu_entry->data.indirected_text.text, translated))
- return entry->entry_key;
- return NULL;
-}
-
-
-/**
- * Finds the menu_definition_entry corresponding to an action for a wimp_menu.
- *
- * \param menu the menu to search for an action within
- * \param action the action to find
- * \return the associated menu entry, or NULL if one could not be found
- */
-struct menu_definition_entry *ro_gui_menu_find_entry(wimp_menu *menu,
- menu_action action)
-{
- struct menu_definition_entry *entry;
- struct menu_definition *definition = ro_gui_menu_find_menu(menu);
-
- if (!definition)
- return NULL;
-
- for (entry = definition->entries; entry; entry = entry->next)
- if (entry->action == action)
- return entry;
- return NULL;
-}
-
-
-/**
- * Finds the action corresponding to a wimp_menu_entry for a wimp_menu.
- *
- * \param menu the menu to search for an action within
- * \param menu_entry the menu_entry to find
- * \return the associated action, or 0 if one could not be found
- */
-menu_action ro_gui_menu_find_action(wimp_menu *menu, wimp_menu_entry *menu_entry)
-{
- struct menu_definition_entry *entry;
- struct menu_definition *definition = ro_gui_menu_find_menu(menu);
-
- if (!definition)
- return NO_ACTION;
-
- for (entry = definition->entries; entry; entry = entry->next) {
- if (entry->menu_entry == menu_entry)
- return entry->action;
- }
- return NO_ACTION;
-}
-
-
-/**
- * Sets an action within a menu as having a specific ticked status.
- *
- * \param menu the menu containing the action
- * \param action the action to tick/untick
- * \param shaded whether to set the item as shaded
- */
-void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action,
- bool shaded)
-{
- struct menu_definition_entry *entry;
- struct menu_definition *definition = ro_gui_menu_find_menu(menu);
-
- if (!definition)
- return;
-
- /* we can't use find_entry as multiple actions may appear in one menu */
- for (entry = definition->entries; entry; entry = entry->next)
- if (entry->action == action) {
- if (shaded)
- entry->menu_entry->icon_flags |= wimp_ICON_SHADED;
- else
- entry->menu_entry->icon_flags &= ~wimp_ICON_SHADED;
- }
-}
-
-
-/**
- * Sets an action within a menu as having a specific ticked status.
- *
- * \param menu the menu containing the action
- * \param action the action to tick/untick
- * \param ticked whether to set the item as ticked
- */
-void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action,
- bool ticked)
-{
- struct menu_definition_entry *entry =
- ro_gui_menu_find_entry(menu, action);
- if (entry) {
- if (ticked)
- entry->menu_entry->menu_flags |= wimp_MENU_TICKED;
- else
- entry->menu_entry->menu_flags &= ~wimp_MENU_TICKED;
- }
-}
-
-
-/**
- * Calculates a simple checksum for the current menu state
- */
-int ro_gui_menu_get_checksum(void)
-{
- wimp_selection menu_tree;
- int i = 0, j, checksum = 0;
- os_error *error;
- wimp_menu *menu;
-
- if (!current_menu_open)
- return 0;
-
- error = xwimp_get_menu_state((wimp_menu_state_flags)0,
- &menu_tree, 0, 0);
- if (error) {
- LOG("xwimp_get_menu_state: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MenuError", error->errmess);
- return 0;
- }
-
- menu = current_menu;
- do {
- j = 0;
- do {
- if (menu->entries[j].icon_flags & wimp_ICON_SHADED)
- checksum ^= (1 << (i + j * 2));
- if (menu->entries[j].menu_flags & wimp_MENU_TICKED)
- checksum ^= (2 << (i + j * 2));
- } while (!(menu->entries[j++].menu_flags & wimp_MENU_LAST));
-
- j = menu_tree.items[i++];
- if (j != -1) {
- menu = menu->entries[j].sub_menu;
- if ((!menu) || (menu == wimp_NO_SUB_MENU) || (!IS_MENU(menu)))
- break;
- }
- } while (j != -1);
-
- return checksum;
-}
-
-/**
- * Translate a menu's textual content into the system local encoding
- *
- * \param menu The menu to translate
- * \return false if out of memory, true otherwise
- */
-bool ro_gui_menu_translate(struct menu_definition *menu)
-{
- os_error *error;
- int alphabet;
- struct menu_definition_entry *entry;
- char *translated;
- nserror err;
-
- /* read current alphabet */
- error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet);
- if (error) {
- LOG("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess);
- /* assume Latin1 */
- alphabet = territory_ALPHABET_LATIN1;
- }
-
- if (menu->current_encoding == alphabet)
- /* menu text is already in the correct encoding */
- return true;
-
- /* translate root menu title text */
- free(menu->menu->title_data.indirected_text.text);
- err = utf8_to_local_encoding(messages_get(menu->title_key),
- 0, &translated);
- if (err != NSERROR_OK) {
- assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
- return false;
- }
-
- /* and fill in WIMP menu field */
- menu->menu->title_data.indirected_text.text = translated;
-
- /* now the menu entries */
- for (entry = menu->entries; entry; entry = entry->next) {
- wimp_menu *submenu = entry->menu_entry->sub_menu;
-
- /* tranlate menu entry text */
- free(entry->menu_entry->data.indirected_text.text);
- err = utf8_to_local_encoding(messages_get(entry->entry_key),
- 0, &translated);
- if (err != NSERROR_OK) {
- assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
- return false;
- }
-
- /* fill in WIMP menu fields */
- entry->menu_entry->data.indirected_text.text = translated;
- entry->menu_entry->data.indirected_text.validation =
- (char *) -1;
- entry->menu_entry->data.indirected_text.size =
- strlen(translated);
-
- /* child menu title - this is the same as the text of
- * the parent menu entry, so just copy the pointer */
- if (submenu != wimp_NO_SUB_MENU && IS_MENU(submenu)) {
- submenu->title_data.indirected_text.text =
- translated;
- }
- }
-
- /* finally, set the current encoding of the menu */
- menu->current_encoding = alphabet;
-
- return true;
-}
-