summaryrefslogtreecommitdiff
path: root/riscos/window.c
diff options
context:
space:
mode:
authorSteve Fryatt <steve@stevefryatt.org.uk>2011-02-20 23:16:33 +0000
committerSteve Fryatt <steve@stevefryatt.org.uk>2011-02-20 23:16:33 +0000
commitcd9c0998e9849472473e577c4c04906e380896e1 (patch)
tree9bef19ebd3d56eccd03fa5613f1506c82762584b /riscos/window.c
parentf54fc080c2a96ffdb713a9c8b5d0ccb604197c07 (diff)
downloadnetsurf-cd9c0998e9849472473e577c4c04906e380896e1.tar.gz
netsurf-cd9c0998e9849472473e577c4c04906e380896e1.tar.bz2
Merge branches/stevef/toolbars to trunk.
svn path=/trunk/netsurf/; revision=11741
Diffstat (limited to 'riscos/window.c')
-rw-r--r--riscos/window.c4217
1 files changed, 2971 insertions, 1246 deletions
diff --git a/riscos/window.c b/riscos/window.c
index 1aa2a82f2..3f07e793d 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -5,7 +5,7 @@
* Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk>
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
- * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
+ * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -46,9 +46,13 @@
#include "content/urldb.h"
#include "css/css.h"
#include "desktop/browser.h"
+#include "desktop/cookies.h"
#include "desktop/frames.h"
+#include "desktop/history_core.h"
+#include "desktop/hotlist.h"
#include "desktop/mouse.h"
#include "desktop/plotters.h"
+#include "desktop/selection.h"
#include "desktop/textinput.h"
#include "desktop/thumbnail.h"
#include "desktop/tree.h"
@@ -57,21 +61,26 @@
#include "render/form.h"
#include "riscos/bitmap.h"
#include "riscos/buffer.h"
+#include "riscos/cookies.h"
#include "riscos/dialog.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
#include "riscos/gui/status_bar.h"
+#include "riscos/help.h"
+#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/oslib_pre7.h"
#include "riscos/save.h"
#include "riscos/sprite.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/thumbnail.h"
#include "riscos/url_complete.h"
+#include "riscos/url_suggest.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
#include "riscos/wimputils.h"
+#include "riscos/window.h"
#include "utils/log.h"
#include "utils/talloc.h"
#include "utils/url.h"
@@ -79,6 +88,66 @@
#include "utils/utils.h"
#include "utils/messages.h"
+
+static void gui_window_set_extent(struct gui_window *g, int width, int height);
+
+static void ro_gui_window_redraw(wimp_draw *redraw);
+static void ro_gui_window_open(wimp_open *open);
+static void ro_gui_window_close(wimp_w w);
+static bool ro_gui_window_click(wimp_pointer *mouse);
+static bool ro_gui_window_keypress(wimp_key *key);
+static void ro_gui_window_toolbar_keypress(void *data, wimp_key *key);
+static void ro_gui_window_handle_local_keypress(struct gui_window *g,
+ wimp_key *key, bool is_toolbar);
+static bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer);
+static void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu);
+
+static void ro_gui_window_toolbar_click(void *data,
+ toolbar_action_type action_type, union toolbar_action action);
+
+static bool ro_gui_window_content_export_types(hlcache_handle *h,
+ bool *export_draw, bool *export_sprite);
+static bool ro_gui_window_up_available(struct browser_window *bw);
+static void ro_gui_window_prepare_pageinfo(struct gui_window *g);
+static void ro_gui_window_prepare_objectinfo(hlcache_handle *object,
+ const char *href);
+
+static void ro_gui_window_launch_url(struct gui_window *g, const char *url);
+static bool ro_gui_window_navigate_up(struct gui_window *g, const char *url);
+static void ro_gui_window_action_home(struct gui_window *g);
+static void ro_gui_window_action_new_window(struct gui_window *g);
+static void ro_gui_window_action_local_history(struct gui_window *g);
+static void ro_gui_window_action_navigate_back_new(struct gui_window *g);
+static void ro_gui_window_action_navigate_forward_new(struct gui_window *g);
+static void ro_gui_window_action_save(struct gui_window *g,
+ gui_save_type save_type);
+static void ro_gui_window_action_search(struct gui_window *g);
+static void ro_gui_window_action_zoom(struct gui_window *g);
+static void ro_gui_window_action_add_bookmark(struct gui_window *g);
+static void ro_gui_window_action_print(struct gui_window *g);
+static void ro_gui_window_action_page_info(struct gui_window *g);
+
+static void ro_gui_window_remove_update_boxes(struct gui_window *g);
+static void ro_gui_window_update_toolbar_buttons(struct gui_window *g);
+static void ro_gui_window_update_toolbar(void *data);
+static void ro_gui_window_save_toolbar_buttons(void *data, char *config);
+static void ro_gui_window_update_theme(void *data, bool ok);
+
+static bool ro_gui_window_import_text(struct gui_window *g,
+ const char *filename, bool toolbar);
+static void ro_gui_window_clone_options(struct browser_window *new_bw,
+ struct browser_window *old_bw);
+
+static bool ro_gui_window_prepare_form_select_menu(struct browser_window *bw,
+ struct form_control *control);
+static void ro_gui_window_process_form_select_menu(struct gui_window *g,
+ wimp_selection *selection);
+
#ifndef wimp_KEY_END
#define wimp_KEY_END wimp_KEY_COPY
#endif
@@ -99,17 +168,25 @@ static bool mouse_drag_select;
static bool mouse_drag_adjust;
/** List of all browser windows. */
-static struct gui_window *window_list = 0;
+static struct gui_window *window_list = 0;
/** GUI window which is being redrawn. Valid only during redraw. */
-struct gui_window *ro_gui_current_redraw_gui;
+struct gui_window *ro_gui_current_redraw_gui;
+/** Form control which gui_form_select_menu is for. */
+static struct form_control *gui_form_select_control;
+/** The browser window menu handle. */
+static wimp_menu *ro_gui_browser_window_menu = NULL;
+/** Menu of options for form select controls. */
+static wimp_menu *gui_form_select_menu = NULL;
+/** Object under menu, or 0 if no object. */
+static hlcache_handle *current_menu_object = 0;
+/** URL of link under menu, or 0 if no link. */
+static const char *current_menu_url = 0;
static float scale_snap_to[] = {0.10, 0.125, 0.25, 0.333, 0.5, 0.75,
1.0,
1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0};
#define SCALE_SNAP_TO_SIZE (sizeof scale_snap_to) / (sizeof(float))
-
-
/** An entry in ro_gui_pointer_table. */
struct ro_gui_pointer_entry {
bool wimp_area; /** The pointer is in the Wimp's sprite area. */
@@ -142,20 +219,6 @@ struct ro_gui_pointer_entry ro_gui_pointer_table[] = {
{ false, "ptr_progress", 0, 0 },
};
-
-static void ro_gui_window_remove_update_boxes(struct gui_window *g);
-static void gui_window_set_extent(struct gui_window *g, int width, int height);
-static void ro_gui_window_open(wimp_open *open);
-static void ro_gui_window_close(wimp_w w);
-static void ro_gui_window_redraw(wimp_draw *redraw);
-static bool ro_gui_window_click(wimp_pointer *mouse);
-static bool ro_gui_window_keypress(wimp_key *key);
-static void ro_gui_window_launch_url(struct gui_window *g, const char *url);
-static void ro_gui_window_clone_options(struct browser_window *new_bw,
- struct browser_window *old_bw);
-static bool ro_gui_window_import_text(struct gui_window *g,
- const char *filename, bool toolbar);
-
struct update_box {
int x0;
int y0;
@@ -170,6 +233,129 @@ struct update_box {
struct update_box *pending_updates;
#define MARGIN 4
+static const struct toolbar_callbacks ro_gui_window_toolbar_callbacks = {
+ ro_gui_window_update_theme,
+ ro_gui_window_update_toolbar,
+ (void (*)(void *)) ro_gui_window_update_toolbar_buttons,
+ ro_gui_window_toolbar_click,
+ ro_gui_window_toolbar_keypress,
+ ro_gui_window_save_toolbar_buttons
+};
+
+
+/**
+ * Initialise the browser window module and its menus.
+ */
+
+void ro_gui_window_initialise(void)
+{
+ /* Build the browser window menu. */
+
+ static const struct ns_menu browser_definition = {
+ "NetSurf", {
+ { "Page", BROWSER_PAGE, 0 },
+ { "Page.PageInfo",BROWSER_PAGE_INFO, &dialog_pageinfo },
+ { "Page.Save", BROWSER_SAVE, &dialog_saveas },
+ { "Page.SaveComp", BROWSER_SAVE_COMPLETE, &dialog_saveas },
+ { "Page.Export", NO_ACTION, 0 },
+#ifdef WITH_DRAW_EXPORT
+ { "Page.Export.Draw", BROWSER_EXPORT_DRAW, &dialog_saveas },
+#endif
+#ifdef WITH_PDF_EXPORT
+ { "Page.Export.PDF", BROWSER_EXPORT_PDF, &dialog_saveas },
+#endif
+ { "Page.Export.Text", BROWSER_EXPORT_TEXT, &dialog_saveas },
+ { "Page.SaveURL", NO_ACTION, 0 },
+ { "Page.SaveURL.URI", BROWSER_SAVE_URL_URI, &dialog_saveas },
+ { "Page.SaveURL.URL", BROWSER_SAVE_URL_URL, &dialog_saveas },
+ { "Page.SaveURL.LinkText", BROWSER_SAVE_URL_TEXT, &dialog_saveas },
+ { "_Page.Print", BROWSER_PRINT, &dialog_print },
+ { "Page.NewWindow", BROWSER_NEW_WINDOW, 0 },
+ { "Page.FindText", BROWSER_FIND_TEXT, &dialog_search },
+ { "Page.ViewSrc", BROWSER_VIEW_SOURCE, 0 },
+ { "Object", BROWSER_OBJECT, 0 },
+ { "Object.Object", BROWSER_OBJECT_OBJECT, 0 },
+ { "Object.Object.ObjInfo", BROWSER_OBJECT_INFO, &dialog_objinfo },
+ { "Object.Object.ObjSave", BROWSER_OBJECT_SAVE, &dialog_saveas },
+ { "Object.Object.Export", BROWSER_OBJECT_EXPORT, 0 },
+ { "Object.Object.Export.Sprite", BROWSER_OBJECT_EXPORT_SPRITE, &dialog_saveas },
+#ifdef WITH_DRAW_EXPORT
+ { "Object.Object.Export.ObjDraw", BROWSER_OBJECT_EXPORT_DRAW, &dialog_saveas },
+#endif
+ { "Object.Object.SaveURL", NO_ACTION, 0 },
+ { "Object.Object.SaveURL.URI", BROWSER_OBJECT_SAVE_URL_URI, &dialog_saveas },
+ { "Object.Object.SaveURL.URL", BROWSER_OBJECT_SAVE_URL_URL, &dialog_saveas },
+ { "Object.Object.SaveURL.LinkText", BROWSER_OBJECT_SAVE_URL_TEXT, &dialog_saveas },
+ { "Object.Object.ObjPrint", BROWSER_OBJECT_PRINT, 0 },
+ { "Object.Object.ObjReload", BROWSER_OBJECT_RELOAD, 0 },
+ { "Object.Link", BROWSER_OBJECT_LINK, 0 },
+ { "Object.Link.LinkSave", BROWSER_LINK_SAVE, 0 },
+ { "Object.Link.LinkSave.URI", BROWSER_LINK_SAVE_URI, &dialog_saveas },
+ { "Object.Link.LinkSave.URL", BROWSER_LINK_SAVE_URL, &dialog_saveas },
+ { "Object.Link.LinkSave.LinkText", BROWSER_LINK_SAVE_TEXT, &dialog_saveas },
+ { "_Object.Link.LinkDload", BROWSER_LINK_DOWNLOAD, 0 },
+ { "Object.Link.LinkNew", BROWSER_LINK_NEW_WINDOW, 0 },
+ { "Selection", BROWSER_SELECTION, 0 },
+ { "_Selection.SelSave", BROWSER_SELECTION_SAVE, &dialog_saveas },
+ { "Selection.Copy", BROWSER_SELECTION_COPY, 0 },
+ { "Selection.Cut", BROWSER_SELECTION_CUT, 0 },
+ { "_Selection.Paste", BROWSER_SELECTION_PASTE, 0 },
+ { "Selection.Clear", BROWSER_SELECTION_CLEAR, 0 },
+ { "Selection.SelectAll", BROWSER_SELECTION_ALL, 0 },
+ { "Navigate", NO_ACTION, 0 },
+ { "Navigate.Home", BROWSER_NAVIGATE_HOME, 0 },
+ { "Navigate.Back", BROWSER_NAVIGATE_BACK, 0 },
+ { "Navigate.Forward", BROWSER_NAVIGATE_FORWARD, 0 },
+ { "_Navigate.UpLevel", BROWSER_NAVIGATE_UP, 0 },
+ { "Navigate.Reload", BROWSER_NAVIGATE_RELOAD_ALL, 0 },
+ { "Navigate.Stop", BROWSER_NAVIGATE_STOP, 0 },
+ { "View", NO_ACTION, 0 },
+ { "View.ScaleView", BROWSER_SCALE_VIEW, &dialog_zoom },
+ { "View.Images", NO_ACTION, 0 },
+ { "View.Images.ForeImg", BROWSER_IMAGES_FOREGROUND, 0 },
+ { "View.Images.BackImg", BROWSER_IMAGES_BACKGROUND, 0 },
+ { "View.Toolbars", NO_ACTION, 0 },
+ { "View.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
+ { "View.Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 },
+ { "_View.Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 },
+ { "View.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 },
+ { "_View.Render", NO_ACTION, 0 },
+ { "View.Render.RenderAnims", BROWSER_BUFFER_ANIMS, 0 },
+ { "View.Render.RenderAll", BROWSER_BUFFER_ALL, 0 },
+ { "_View.OptDefault", BROWSER_SAVE_VIEW, 0 },
+ { "View.Window", NO_ACTION, 0 },
+ { "View.Window.WindowSave", BROWSER_WINDOW_DEFAULT, 0 },
+ { "View.Window.WindowStagr", BROWSER_WINDOW_STAGGER, 0 },
+ { "_View.Window.WindowSize", BROWSER_WINDOW_COPY, 0 },
+ { "View.Window.WindowReset", BROWSER_WINDOW_RESET, 0 },
+ { "Utilities", NO_ACTION, 0 },
+ { "Utilities.Hotlist", HOTLIST_SHOW, 0 },
+ { "Utilities.Hotlist.HotlistAdd", HOTLIST_ADD_URL, 0 },
+ { "Utilities.Hotlist.HotlistShow", HOTLIST_SHOW, 0 },
+ { "Utilities.History", HISTORY_SHOW_GLOBAL, 0 },
+ { "Utilities.History.HistLocal", HISTORY_SHOW_LOCAL, 0 },
+ { "Utilities.History.HistGlobal", HISTORY_SHOW_GLOBAL, 0 },
+ { "Utilities.Cookies", COOKIES_SHOW, 0 },
+ { "Utilities.Cookies.ShowCookies", COOKIES_SHOW, 0 },
+ { "Utilities.Cookies.DeleteCookies", COOKIES_DELETE, 0 },
+ { "Help", HELP_OPEN_CONTENTS, 0 },
+ { "Help.HelpContent", HELP_OPEN_CONTENTS, 0 },
+ { "Help.HelpGuide", HELP_OPEN_GUIDE, 0 },
+ { "_Help.HelpInfo", HELP_OPEN_INFORMATION, 0 },
+ { "_Help.HelpAbout", HELP_OPEN_ABOUT, 0 },
+ { "Help.HelpInter", HELP_LAUNCH_INTERACTIVE, 0 },
+ {NULL, 0, 0}
+ }
+ };
+ ro_gui_browser_window_menu =
+ ro_gui_menu_define_menu(&browser_definition);
+
+}
+
+
+/*
+ * Interface With Core
+ */
/**
* Create and open a new browser window.
@@ -203,8 +389,6 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
g->old_height = 0;
g->update_extent = true;
strcpy(g->title, "NetSurf");
- g->throbber = 0;
- g->throbtime = 0;
g->iconise_icon = -1;
/* Set the window position */
@@ -365,27 +549,47 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
/* Add in a toolbar and status bar */
if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) {
g->status_bar = ro_gui_status_bar_create(g->window, option_toolbar_status_width);
- g->toolbar = ro_gui_theme_create_toolbar(NULL, THEME_BROWSER_TOOLBAR);
- ro_gui_theme_attach_toolbar(g->toolbar, g->window);
+ g->toolbar = ro_toolbar_create(NULL, g->window,
+ THEME_STYLE_BROWSER_TOOLBAR, TOOLBAR_FLAGS_NONE,
+ &ro_gui_window_toolbar_callbacks, g,
+ "HelpToolbar");
+ if (g->toolbar != NULL) {
+ ro_toolbar_add_buttons(g->toolbar,
+ brower_toolbar_buttons,
+ option_toolbar_browser);
+ ro_toolbar_add_url(g->toolbar);
+ ro_toolbar_add_throbber(g->toolbar);
+ ro_toolbar_rebuild(g->toolbar);
+ }
} else {
g->toolbar = NULL;
}
- /* Set the window options */
- bw->window = g;
- ro_gui_window_clone_options(bw, clone);
- ro_gui_prepare_navigate(g);
-
- /* Register event handlers */
+ /* Register event handlers. Do this quickly, as some of the things
+ * that follow will indirectly look up our user data: this MUST
+ * be set first!
+ */
ro_gui_wimp_event_set_user_data(g->window, g);
ro_gui_wimp_event_register_open_window(g->window, ro_gui_window_open);
ro_gui_wimp_event_register_close_window(g->window, ro_gui_window_close);
ro_gui_wimp_event_register_redraw_window(g->window, ro_gui_window_redraw);
ro_gui_wimp_event_register_keypress(g->window, ro_gui_window_keypress);
- if (g->toolbar)
- ro_gui_wimp_event_register_keypress(g->toolbar->toolbar_handle,
- ro_gui_window_keypress);
ro_gui_wimp_event_register_mouse_click(g->window, ro_gui_window_click);
+ ro_gui_wimp_event_register_menu(g->window, ro_gui_browser_window_menu,
+ true, false);
+ ro_gui_wimp_event_register_menu_prepare(g->window,
+ ro_gui_window_menu_prepare);
+ ro_gui_wimp_event_register_menu_selection(g->window,
+ ro_gui_window_menu_select);
+ ro_gui_wimp_event_register_menu_warning(g->window,
+ ro_gui_window_menu_warning);
+ ro_gui_wimp_event_register_menu_close(g->window,
+ ro_gui_window_menu_close);
+
+ /* Set the window options */
+ bw->window = g;
+ ro_gui_window_clone_options(bw, clone);
+ ro_gui_window_update_toolbar_buttons(g);
/* Open the window at the top of the stack */
state.w = g->window;
@@ -417,17 +621,9 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
/* Claim the caret for top-level windows */
if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) {
- if (g->toolbar && g->toolbar->display_url) {
- error = xwimp_set_caret_position(
- g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, -1, -1, -1, 0);
- ro_gui_url_complete_start(g);
- if (error) {
- LOG(("xwimp_set_caret_position: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
- } else
+ if (ro_toolbar_take_caret(g->toolbar))
+ ro_gui_url_complete_start(g->toolbar);
+ else
gui_window_place_caret(g, -100, -100, 0);
}
return g;
@@ -463,15 +659,15 @@ void gui_window_destroy(struct gui_window *g)
/* destroy toolbar */
if (g->toolbar)
- ro_gui_theme_destroy_toolbar(g->toolbar);
+ ro_toolbar_destroy(g->toolbar);
if (g->status_bar)
ro_gui_status_bar_destroy(g->status_bar);
w = g->window;
- ro_gui_url_complete_close(NULL, 0);
+ ro_gui_url_complete_close();
ro_gui_dialog_close_persistent(w);
if (current_menu_window == w)
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
ro_gui_window_remove_update_boxes(g);
/* delete window */
@@ -659,7 +855,7 @@ bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
}
if (g->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
*sx = state.xscroll / (2 * g->bw->scale);
*sy = -(state.yscroll - toolbar_height) / (2 * g->bw->scale);
return true;
@@ -693,7 +889,7 @@ void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
state.xscroll = sx * 2 * g->bw->scale;
state.yscroll = -sy * 2 * g->bw->scale;
if (g->toolbar)
- state.yscroll += ro_gui_theme_toolbar_full_height(g->toolbar);
+ state.yscroll += ro_toolbar_full_height(g->toolbar);
ro_gui_window_open(PTR_WIMP_OPEN(&state));
}
@@ -728,7 +924,7 @@ void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, int x1, int
}
if (g->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
x0 = x0 * 2 * g->bw->scale;
y0 = y0 * 2 * g->bw->scale;
@@ -898,25 +1094,27 @@ void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bo
/**
- * Update the extent of the inside of a browser window to that of the current content.
+ * Update the extent of the inside of a browser window to that of the
+ * current content.
*
- * \param g gui_window to update the extent of
+ * \param g gui_window to update the extent of
*/
void gui_window_update_extent(struct gui_window *g)
{
- os_error *error;
- wimp_window_state state;
- bool update;
- unsigned int flags;
- int scroll = 0;
+ os_error *error;
+ wimp_window_info info;
+ wimp_window_state state;
+ bool update;
+ unsigned int flags;
+ int scroll = 0;
assert(g);
- state.w = g->window;
- error = xwimp_get_window_state(&state);
+ info.w = g->window;
+ error = xwimp_get_window_info_header_only(&info);
if (error) {
- LOG(("xwimp_get_window_state: 0x%x: %s",
+ LOG(("xwimp_get_window_info_header_only: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
return;
@@ -924,15 +1122,15 @@ void gui_window_update_extent(struct gui_window *g)
/* scroll on toolbar height change */
if (g->toolbar) {
- scroll = ro_gui_theme_height_change(g->toolbar);
- state.yscroll -= scroll;
+ scroll = ro_toolbar_height(g->toolbar) - info.extent.y1;
+ info.yscroll += scroll;
}
/* only allow a further reformat if we've gained/lost scrollbars */
- flags = state.flags & (wimp_WINDOW_HSCROLL | wimp_WINDOW_VSCROLL);
+ flags = info.flags & (wimp_WINDOW_HSCROLL | wimp_WINDOW_VSCROLL);
update = g->bw->reformat_pending;
g->update_extent = true;
- ro_gui_window_open(PTR_WIMP_OPEN(&state));
+ ro_gui_window_open(PTR_WIMP_OPEN(&info));
state.w = g->window;
error = xwimp_get_window_state(&state);
@@ -1033,41 +1231,11 @@ void gui_window_hide_pointer(struct gui_window *g)
void gui_window_set_url(struct gui_window *g, const char *url)
{
- wimp_caret caret;
- os_error *error;
- const char *toolbar_url;
-
if (!g->toolbar)
return;
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, url, true);
- ro_gui_force_redraw_icon(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_FAVICON);
-
- /* if the caret is in the address bar, move it to the end */
- error = xwimp_get_caret_position(&caret);
- if (error) {
- LOG(("xwimp_get_caret_position: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
-
- if (!(caret.w == g->toolbar->toolbar_handle &&
- caret.i == ICON_TOOLBAR_URL))
- return;
-
- toolbar_url = ro_gui_get_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL);
- error = xwimp_set_caret_position(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, 0, 0, -1, (int)strlen(toolbar_url));
- if (error) {
- LOG(("xwimp_set_caret_position: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
- ro_gui_url_complete_start(g);
+ ro_toolbar_set_url(g->toolbar, url, true, false);
+ ro_gui_url_complete_start(g->toolbar);
}
@@ -1079,10 +1247,10 @@ void gui_window_set_url(struct gui_window *g, const char *url)
void gui_window_start_throbber(struct gui_window *g)
{
- ro_gui_menu_objects_moved();
- ro_gui_prepare_navigate(g);
- xos_read_monotonic_time(&g->throbtime);
- g->throbber = 0;
+ ro_gui_window_update_toolbar_buttons(g);
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ if (g->toolbar != NULL)
+ ro_toolbar_start_throbbing(g->toolbar);
}
@@ -1095,24 +1263,22 @@ void gui_window_start_throbber(struct gui_window *g)
void gui_window_stop_throbber(struct gui_window *g)
{
- char throb_buf[12];
- ro_gui_prepare_navigate(g);
- g->throbber = 0;
- if (g->toolbar) {
- strcpy(throb_buf, "throbber0");
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER, throb_buf, true);
- if ((g->toolbar->descriptor) && (g->toolbar->descriptor->throbber_redraw))
- ro_gui_force_redraw_icon(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER);
- }
+ ro_gui_window_update_toolbar_buttons(g);
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ if (g->toolbar != NULL)
+ ro_toolbar_stop_throbbing(g->toolbar);
}
/**
* set favicon
*/
+
void gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
{
+ if (g == NULL || g->toolbar == NULL)
+ return;
+
+ ro_toolbar_set_site_favicon(g->toolbar, icon);
}
/**
@@ -1185,9 +1351,10 @@ void gui_window_remove_caret(struct gui_window *g)
void gui_window_new_content(struct gui_window *g)
{
- ro_gui_menu_objects_moved();
- ro_gui_prepare_navigate(g);
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ ro_gui_window_update_toolbar_buttons(g);
ro_gui_dialog_close_persistent(g->window);
+ ro_toolbar_set_content_favicon(g->toolbar, g->bw->current_content);
}
@@ -1233,7 +1400,7 @@ bool gui_window_scroll_start(struct gui_window *g)
drag.bbox.y1 = drag.bbox.y0 + (height - (info.visible.y1 - info.visible.y0));
if (g->toolbar) {
- int tbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
+ int tbar_height = ro_toolbar_full_height(g->toolbar);
drag.bbox.y0 -= tbar_height;
drag.bbox.y1 -= tbar_height;
}
@@ -1339,7 +1506,7 @@ bool gui_window_frame_resize_start(struct gui_window *g)
/* convert to screen co-ordinates */
top = browser_window_owner(bw);
if (top->window->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(top->window->toolbar);
+ toolbar_height = ro_toolbar_full_height(top->window->toolbar);
state.w = top->window->window;
error = xwimp_get_window_state(&state);
if (error) {
@@ -1422,16 +1589,111 @@ void gui_window_set_scale(struct gui_window *g, float scale)
/**
- * Redraws the content for all windows.
+ * Updates a windows extent.
+ *
+ * \param g the gui_window to update
+ * \param width the minimum width, or -1 to use window width
+ * \param height the minimum height, or -1 to use window height
*/
-void ro_gui_window_redraw_all(void)
+void gui_window_set_extent(struct gui_window *g, int width, int height)
{
- struct gui_window *g;
- for (g = window_list; g; g = g->next)
- gui_window_redraw_window(g);
+ int screen_width;
+ int toolbar_height = 0;
+ hlcache_handle *h;
+ wimp_window_state state;
+ os_error *error;
+
+ h = g->bw->current_content;
+ if (g->toolbar)
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
+
+ /* get the current state */
+ if ((height == -1) || (width == -1)) {
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG(("xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return;
+ }
+ if (width == -1)
+ width = state.visible.x1 - state.visible.x0;
+ if (height == -1) {
+ height = state.visible.y1 - state.visible.y0;
+ height -= toolbar_height;
+ }
+ }
+
+ /* the top-level framed window is a total pain. to get it to maximise
+ * to the top of the screen we need to fake it having a suitably large
+ * extent */
+ if (g->bw->children &&
+ (g->bw->browser_window_type == BROWSER_WINDOW_NORMAL)) {
+ ro_gui_screen_size(&screen_width, &height);
+ if (g->toolbar)
+ height -= ro_toolbar_full_height(g->toolbar);
+ height -= ro_get_hscroll_height(g->window);
+ height -= ro_get_title_height(g->window);
+ }
+ if (h) {
+ width = max(width, content_get_width(h) * 2 * g->bw->scale);
+ height = max(height, content_get_height(h) * 2 * g->bw->scale);
+ }
+ os_box extent = { 0, -height, width, toolbar_height };
+ error = xwimp_set_extent(g->window, &extent);
+ if (error) {
+ LOG(("xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return;
+ }
+}
+
+
+/**
+ * Display a menu of options for a form select control.
+ *
+ * \param bw browser window containing form control
+ * \param control form control of type GADGET_SELECT
+ */
+
+void gui_create_form_select_menu(struct browser_window *bw,
+ struct form_control *control)
+{
+ os_error *error;
+ wimp_pointer pointer;
+
+ /* The first time the menu is opened, control bypasses the normal
+ * Menu Prepare event and so we prepare here. On any re-opens,
+ * ro_gui_window_prepare_form_select_menu() is called from the
+ * normal wimp event.
+ */
+
+ if (!ro_gui_window_prepare_form_select_menu(bw, control))
+ return;
+
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG(("xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ ro_gui_menu_closed();
+ return;
+ }
+
+ gui_form_select_control = control;
+ ro_gui_menu_create(gui_form_select_menu,
+ pointer.pos.x, pointer.pos.y, bw->window->window);
}
+
+/*
+ * RISC OS Wimp Event Handlers
+ */
+
+
/**
* Handle a Redraw_Window_Request for a browser window.
*/
@@ -1512,218 +1774,6 @@ void ro_gui_window_redraw(wimp_draw *redraw)
}
-
-/**
- * Remove all pending update boxes for a window
- *
- * \param g gui_window
- */
-void ro_gui_window_remove_update_boxes(struct gui_window *g) {
- struct update_box *cur;
-
- for (cur = pending_updates; cur != NULL; cur = cur->next) {
- if (cur->g == g)
- cur->g = NULL;
- }
-}
-
-
-/**
- * Redraw any pending update boxes.
- */
-void ro_gui_window_update_boxes(void) {
- osbool more;
- bool use_buffer;
- wimp_draw update;
- struct rect clip;
- os_error *error;
- struct update_box *cur;
- struct gui_window *g;
- const union content_msg_data *data;
-
- for (cur = pending_updates; cur != NULL; cur = cur->next) {
- g = cur->g;
- if (!g)
- continue;
-
- data = &cur->data;
- use_buffer = cur->use_buffer;
-
- update.w = g->window;
- update.box.x0 = cur->x0;
- update.box.y0 = cur->y0;
- update.box.x1 = cur->x1;
- update.box.y1 = cur->y1;
-
- error = xwimp_update_window(&update, &more);
- if (error) {
- LOG(("xwimp_update_window: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- continue;
- }
-
- /* Set the current redraw gui_window to get options from */
- ro_gui_current_redraw_gui = g;
- current_redraw_browser = g->bw;
-
- plot = ro_plotters;
- ro_plot_origin_x = update.box.x0 - update.xscroll;
- ro_plot_origin_y = update.box.y1 - update.yscroll;
- ro_plot_set_scale(g->bw->scale);
-
- while (more) {
- clip.x0 = (update.clip.x0 - ro_plot_origin_x) / 2;
- clip.y0 = (ro_plot_origin_y - update.clip.y1) / 2;
- clip.x1 = (update.clip.x1 - ro_plot_origin_x) / 2;
- clip.y1 = (ro_plot_origin_y - update.clip.y0) / 2;
-
- if (use_buffer)
- ro_gui_buffer_open(&update);
-
- browser_window_redraw(g->bw, 0, 0, &clip);
-
- if (use_buffer)
- ro_gui_buffer_close();
-
- error = xwimp_get_rectangle(&update, &more);
- /* RISC OS 3.7 returns an error here if enough buffer
- * was claimed to cause a new dynamic area to be
- * created. It doesn't actually stop anything working,
- * so we mask it out for now until a better fix is
- * found. This appears to be a bug in RISC OS. */
- if (error && !(use_buffer &&
- error->errnum == error_WIMP_GET_RECT)) {
- LOG(("xwimp_get_rectangle: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- ro_gui_current_redraw_gui = NULL;
- current_redraw_browser = NULL;
- continue;
- }
- }
-
- /* Reset the current redraw gui_window to prevent
- * thumbnails from retaining options */
- ro_gui_current_redraw_gui = NULL;
- current_redraw_browser = NULL;
- }
- while (pending_updates) {
- cur = pending_updates;
- pending_updates = pending_updates->next;
- free(cur);
- }
-
-}
-
-
-/**
- * Launch a new url in the given window.
- *
- * \param g gui_window to update
- * \param url url to be launched
- */
-
-void ro_gui_window_launch_url(struct gui_window *g, const char *url)
-{
- url_func_result res;
- char *url_norm;
-
- ro_gui_url_complete_close(NULL, 0);
- res = url_normalize(url, &url_norm);
- if (res == URL_FUNC_OK) {
- gui_window_set_url(g, url_norm);
- browser_window_go(g->bw, url_norm, 0, true);
- free(url_norm);
- }
-}
-
-
-/**
- * Forces all windows to be set to the current theme
- */
-void ro_gui_window_update_theme(void) {
- struct gui_window *g;
- for (g = window_list; g; g = g->next) {
- if (g->toolbar) {
- if (g->toolbar->editor)
- if (!ro_gui_theme_update_toolbar(NULL, g->toolbar->editor))
- g->toolbar->editor = NULL;
- if (!ro_gui_theme_update_toolbar(NULL, g->toolbar)) {
- ro_gui_theme_destroy_toolbar(g->toolbar);
- g->toolbar = NULL;
- }
- ro_gui_theme_toolbar_editor_sync(g->toolbar);
- gui_window_update_extent(g);
- }
- }
-}
-
-
-/**
- * Updates a windows extent.
- *
- * \param g the gui_window to update
- * \param width the minimum width, or -1 to use window width
- * \param height the minimum height, or -1 to use window height
- */
-
-void gui_window_set_extent(struct gui_window *g, int width, int height)
-{
- int screen_width;
- int toolbar_height = 0;
- hlcache_handle *h;
- wimp_window_state state;
- os_error *error;
-
- h = g->bw->current_content;
- if (g->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
-
- /* get the current state */
- if ((height == -1) || (width == -1)) {
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG(("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
- if (width == -1)
- width = state.visible.x1 - state.visible.x0;
- if (height == -1) {
- height = state.visible.y1 - state.visible.y0;
- height -= toolbar_height;
- }
- }
-
- /* the top-level framed window is a total pain. to get it to maximise
- * to the top of the screen we need to fake it having a suitably large
- * extent */
- if (g->bw->children &&
- (g->bw->browser_window_type == BROWSER_WINDOW_NORMAL)) {
- ro_gui_screen_size(&screen_width, &height);
- if (g->toolbar)
- height -= ro_gui_theme_toolbar_full_height(g->toolbar);
- height -= ro_get_hscroll_height(g->window);
- height -= ro_get_title_height(g->window);
- }
- if (h) {
- width = max(width, content_get_width(h) * 2 * g->bw->scale);
- height = max(height, content_get_height(h) * 2 * g->bw->scale);
- }
- os_box extent = { 0, -height, width, toolbar_height };
- error = xwimp_set_extent(g->window, &extent);
- if (error) {
- LOG(("xwimp_set_extent: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
-}
-
-
/**
* Open a window using the given wimp_open, handling toolbars and resizing.
*/
@@ -1762,7 +1812,7 @@ void ro_gui_window_open(wimp_open *open)
/* account for toolbar height, if present */
if (g->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
height -= toolbar_height;
/* work with the state from now on so we can modify flags */
@@ -1871,7 +1921,7 @@ void ro_gui_window_open(wimp_open *open)
}
/* first resize stops any flickering by making the URL window on top */
- ro_gui_url_complete_resize(g, PTR_WIMP_OPEN(&state));
+ ro_gui_url_complete_resize(g->toolbar, PTR_WIMP_OPEN(&state));
error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
if (error) {
@@ -1885,9 +1935,9 @@ void ro_gui_window_open(wimp_open *open)
if (g->status_bar)
ro_gui_status_bar_resize(g->status_bar);
if (g->toolbar) {
- ro_gui_theme_process_toolbar(g->toolbar, -1);
+ ro_toolbar_process(g->toolbar, -1, false);
/* second resize updates to the new URL bar width */
- ro_gui_url_complete_resize(g, open);
+ ro_gui_url_complete_resize(g->toolbar, open);
}
/* set the new scale from a ctrl-resize. this must be done at the end as
@@ -1901,7 +1951,9 @@ void ro_gui_window_open(wimp_open *open)
/**
* Handle wimp closing event
*/
-void ro_gui_window_close(wimp_w w) {
+
+void ro_gui_window_close(wimp_w w)
+{
struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(w);
wimp_pointer pointer;
os_error *error;
@@ -1950,9 +2002,11 @@ void ro_gui_window_close(wimp_w w) {
} else {
/* this is pointless if we are about to close the
* window */
- if (!destroy)
- ro_gui_menu_handle_action(w,
- BROWSER_NAVIGATE_UP, true);
+ if (!destroy && g->bw != NULL &&
+ g->bw->current_content != NULL)
+ ro_gui_window_navigate_up(g->bw->window,
+ content_get_url(
+ g->bw->current_content));
}
}
else
@@ -1964,606 +2018,347 @@ void ro_gui_window_close(wimp_w w) {
/**
- * Destroy all browser windows.
- */
-
-void ro_gui_window_quit(void)
-{
- struct gui_window *cur;
-
- while (window_list) {
- cur = window_list;
- window_list = window_list->next;
-
- /* framesets and iframes are destroyed by their parents */
- if (!cur->bw->parent)
- browser_window_destroy(cur->bw);
- }
-}
-
-
-/**
- * Animate the "throbbers" of all browser windows.
- */
-
-void ro_gui_throb(void)
-{
- os_t t;
- struct gui_window *g, *top_g;
- struct browser_window *top;
- char throb_buf[12];
-
- xos_read_monotonic_time(&t);
-
- for (g = window_list; g; g = g->next) {
- if (!g->bw->throbbing)
- continue;
- for (top = g->bw; top->parent; top = top->parent);
- top_g = top->window;
- if (!top_g->toolbar || !top_g->toolbar->display_throbber ||
- !top_g->toolbar->descriptor ||
- !top_g->toolbar->descriptor->theme ||
- (t < top_g->throbtime + 10))
- continue;
- top_g->throbtime = t;
- top_g->throbber++;
- if (top_g->toolbar->descriptor->theme->throbber_frames < top_g->throbber)
- top_g->throbber = 1;
- sprintf(throb_buf, "throbber%i", top_g->throbber);
- ro_gui_set_icon_string(top_g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER, throb_buf, true);
- if (top_g->toolbar->descriptor->throbber_redraw)
- ro_gui_force_redraw_icon(top_g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER);
- }
-}
-
-
-/**
- * Convert a RISC OS window handle to a gui_window.
+ * Handle Mouse_Click events in a browser window. This should never see
+ * Menu clicks, as these will be routed to the menu handlers.
*
- * \param w RISC OS window handle
- * \return pointer to a structure if found, 0 otherwise
+ * \param *pointer details of mouse click
+ * \return true if click handled, false otherwise
*/
-struct gui_window *ro_gui_window_lookup(wimp_w window)
+bool ro_gui_window_click(wimp_pointer *pointer)
{
struct gui_window *g;
- for (g = window_list; g; g = g->next)
- if (g->window == window)
- return g;
- return 0;
-}
+ os_coord pos;
+ /* We should never see Menu clicks. */
-/**
- * Convert a toolbar RISC OS window handle to a gui_window.
- *
- * \param w RISC OS window handle of a toolbar
- * \return pointer to a structure if found, 0 otherwise
- */
-
-struct gui_window *ro_gui_toolbar_lookup(wimp_w window)
-{
- struct gui_window *g;
- for (g = window_list; g; g = g->next) {
- if ((g->toolbar) && ((g->toolbar->toolbar_handle == window) ||
- ((g->toolbar->editor) &&
- (g->toolbar->editor->toolbar_handle == window))))
- return g;
- }
- return 0;
-}
+ if (pointer->buttons == wimp_CLICK_MENU)
+ return false;
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(pointer->w);
-/**
- * Handle pointer movements in a browser window.
- *
- * \param g browser window that the pointer is in
- * \param pointer new mouse position
- */
+ /* try to close url-completion */
+ ro_gui_url_complete_close();
-void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer)
-{
- os_coord pos;
+ /* set input focus */
+ if (pointer->buttons == wimp_CLICK_SELECT ||
+ pointer->buttons == wimp_CLICK_ADJUST)
+ gui_window_place_caret(g, -100, -100, 0);
if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
- browser_window_mouse_track(g->bw,
- ro_gui_mouse_drag_state(pointer->buttons,
- wimp_BUTTON_CLICK_DRAG),
+ browser_window_mouse_click(g->bw,
+ ro_gui_mouse_click_state(pointer->buttons,
+ wimp_BUTTON_CLICK_DRAG),
pos.x, pos.y);
+
+ return true;
}
/**
- * Process Mouse_Click events in a toolbar.
+ * Process Key_Pressed events in a browser window.
*/
-bool ro_gui_toolbar_click(wimp_pointer *pointer)
+bool ro_gui_window_keypress(wimp_key *key)
{
- struct gui_window *g = ro_gui_toolbar_lookup(pointer->w);
- struct browser_window *new_bw;
-
- /* toolbars in the options window have no gui_window */
- if (!g)
- return true;
-
- /* try to close url-completion */
- ro_gui_url_complete_close(g, pointer->i);
+ struct gui_window *g;
+ hlcache_handle *h;
+ os_error *error;
+ wimp_pointer pointer;
+ uint32_t c = (uint32_t) key->c;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(key->w);
+ if (g == NULL)
+ return false;
- /* Handle Menu clicks */
- if (pointer->buttons == wimp_CLICK_MENU) {
- ro_gui_menu_create(browser_toolbar_menu, pointer->pos.x,
- pointer->pos.y, g->window, true);
- return true;
- }
+ h = g->bw->current_content;
- /* Handle toolbar edits */
- if ((g->toolbar->editor) && (pointer->i < ICON_TOOLBAR_URL)) {
- ro_gui_theme_toolbar_editor_click(g->toolbar, pointer);
- return true;
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG(("xwimp_get_pointer_info: 0x%x: %s\n",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
}
- /* Handle the buttons appropriately */
- switch (pointer->i) {
- case ICON_TOOLBAR_BACK:
- if (pointer->buttons == wimp_CLICK_ADJUST) {
- new_bw = browser_window_create(NULL,
- g->bw, NULL, false, false);
- ro_gui_menu_handle_action(
- new_bw->window->window,
- BROWSER_NAVIGATE_BACK, true);
- } else {
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_BACK, true);
- }
- break;
-
- case ICON_TOOLBAR_FORWARD:
- if (pointer->buttons == wimp_CLICK_ADJUST) {
- new_bw = browser_window_create(NULL,
- g->bw, NULL, false, false);
- ro_gui_menu_handle_action(
- new_bw->window->window,
- BROWSER_NAVIGATE_FORWARD, true);
- } else {
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_FORWARD, true);
- }
- break;
+ /* First send the key to the browser window, eg. form fields. */
- case ICON_TOOLBAR_STOP:
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_STOP, true);
- break;
+ if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) ||
+ (c & IS_WIMP_KEY)) {
+ /* Munge control keys into unused control chars */
+ /* We can't map onto 1->26 (reserved for ctrl+<qwerty>
+ That leaves 27->31 and 128->159 */
+ switch (c & ~IS_WIMP_KEY) {
+ case wimp_KEY_TAB: c = 9; break;
+ case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break;
- case ICON_TOOLBAR_RELOAD:
- if (pointer->buttons == wimp_CLICK_SELECT)
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_RELOAD, true);
- else if (pointer->buttons == wimp_CLICK_ADJUST)
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_RELOAD_ALL,
- true);
+ /* cursor movement keys */
+ case wimp_KEY_HOME:
+ case wimp_KEY_CONTROL | wimp_KEY_LEFT:
+ c = KEY_LINE_START;
break;
-
- case ICON_TOOLBAR_HISTORY:
- if (pointer->buttons == wimp_CLICK_SELECT)
- ro_gui_menu_handle_action(g->window,
- HISTORY_SHOW_LOCAL, true);
+ case wimp_KEY_END:
+ if (os_version >= RISCOS5)
+ c = KEY_LINE_END;
else
- ro_gui_menu_handle_action(g->window,
- HISTORY_SHOW_GLOBAL, true);
+ c = KEY_DELETE_RIGHT;
break;
- case ICON_TOOLBAR_HOME:
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_HOME, true);
+ case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = KEY_LINE_END; break;
+ case wimp_KEY_CONTROL | wimp_KEY_UP: c = KEY_TEXT_START; break;
+ case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = KEY_TEXT_END; break;
+ case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = KEY_WORD_LEFT ; break;
+ case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = KEY_WORD_RIGHT; break;
+ case wimp_KEY_SHIFT | wimp_KEY_UP: c = KEY_PAGE_UP; break;
+ case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = KEY_PAGE_DOWN; break;
+ case wimp_KEY_LEFT: c = KEY_LEFT; break;
+ case wimp_KEY_RIGHT: c = KEY_RIGHT; break;
+ case wimp_KEY_UP: c = KEY_UP; break;
+ case wimp_KEY_DOWN: c = KEY_DOWN; break;
+
+ /* editing */
+ case wimp_KEY_CONTROL | wimp_KEY_END:
+ c = KEY_DELETE_LINE_END;
break;
- case ICON_TOOLBAR_SEARCH:
- ro_gui_menu_handle_action(g->window,
- BROWSER_FIND_TEXT, true);
- break;
- case ICON_TOOLBAR_SCALE:
- ro_gui_menu_handle_action(g->window,
- BROWSER_SCALE_VIEW, true);
+ case wimp_KEY_DELETE:
+ if (ro_gui_ctrl_pressed())
+ c = KEY_DELETE_LINE_START;
+ else if (os_version < RISCOS5)
+ c = KEY_DELETE_LEFT;
break;
- case ICON_TOOLBAR_BOOKMARK:
- if (pointer->buttons == wimp_CLICK_ADJUST)
- ro_gui_menu_handle_action(g->window,
- HOTLIST_ADD_URL, true);
- else
- ro_gui_menu_handle_action(g->window,
- HOTLIST_SHOW, true);
+ default:
break;
+ }
+ }
- case ICON_TOOLBAR_SAVE:
- if (pointer->buttons == wimp_CLICK_ADJUST)
- ro_gui_menu_handle_action(g->window,
- BROWSER_SAVE_COMPLETE, true);
- else
- ro_gui_menu_handle_action(g->window,
- BROWSER_SAVE, true);
- break;
- case ICON_TOOLBAR_PRINT:
- ro_gui_menu_handle_action(g->window,
- BROWSER_PRINT, true);
- break;
- case ICON_TOOLBAR_UP:
- if (pointer->buttons == wimp_CLICK_ADJUST) {
- if (g->bw && g->bw->current_content) {
- hlcache_handle *h =
- g->bw->current_content;
- new_bw = browser_window_create(NULL,
- g->bw, NULL, false,
- false);
- /* do it without loading the content
- * into the new window */
- ro_gui_window_navigate_up(
- new_bw->window,
- content_get_url(h));
- }
- } else {
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_UP, true);
- }
- break;
- case ICON_TOOLBAR_URL:
- if (pointer->buttons &
- (wimp_DRAG_SELECT | wimp_DRAG_ADJUST)) {
- if (g->bw->current_content) {
- hlcache_handle *h =
- g->bw->current_content;
- gui_save_type save_type;
-
- if (ro_gui_shift_pressed())
- save_type = GUI_SAVE_LINK_URL;
- else
- save_type = GUI_SAVE_LINK_TEXT;
-
- ro_gui_drag_save_link(save_type,
- content_get_url(h),
- content_get_title(h),
- g);
- }
- }
- else
- ro_gui_url_complete_start(g);
- break;
- case ICON_TOOLBAR_SUGGEST:
- ro_gui_popup_menu(url_suggest_menu,
- g->toolbar->toolbar_handle,
- ICON_TOOLBAR_SUGGEST);
- break;
+ if (!(c & IS_WIMP_KEY)) {
+ if (browser_window_key_press(g->bw, c))
+ return true;
}
+
+ ro_gui_window_handle_local_keypress(g, key, false);
+
return true;
}
/**
- * Handle Mouse_Click events in a browser window.
+ * Callback handler for keypresses within browser window toolbars.
*
- * \param pointer details of mouse click
- * \return true if click handled, false otherwise
+ * \param *data Client data, pointing to the GUI Window.
+ * \param *key The keypress data.
*/
-bool ro_gui_window_click(wimp_pointer *pointer)
+void ro_gui_window_toolbar_keypress(void *data, wimp_key *key)
{
- struct gui_window *g;
- os_coord pos;
-
- g = (struct gui_window *)ro_gui_wimp_event_get_user_data(pointer->w);
-
- /* try to close url-completion */
- ro_gui_url_complete_close(g, pointer->i);
+ struct gui_window *g = (struct gui_window *) data;
- /* set input focus */
- if (pointer->buttons == wimp_CLICK_SELECT ||
- pointer->buttons == wimp_CLICK_ADJUST)
- gui_window_place_caret(g, -100, -100, 0);
-
- if (pointer->buttons == wimp_CLICK_MENU) {
- ro_gui_menu_create(browser_menu, pointer->pos.x, pointer->pos.y, pointer->w, true);
- } else {
- if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
- browser_window_mouse_click(g->bw,
- ro_gui_mouse_click_state(pointer->buttons,
- wimp_BUTTON_CLICK_DRAG),
- pos.x, pos.y);
- }
- return true;
+ if (g != NULL)
+ ro_gui_window_handle_local_keypress(g, key, true);
}
/**
- * Process Key_Pressed events in a browser window.
+ * Handle keypresses within the RISC OS GUI: this is to be called after the
+ * core has been given a chance to act, or on keypresses in the toolbar where
+ * the core doesn't get involved.
+ *
+ * \param *g The gui window to which the keypress applies.
+ * \param *key The keypress data.
+ * \param is_toolbar true if the keypress is from a toolbar;
+ * else false.
*/
-bool ro_gui_window_keypress(wimp_key *key)
+void ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key,
+ bool is_toolbar)
{
- struct gui_window *g;
- bool toolbar;
- hlcache_handle *h;
- wimp_window_state state;
- int y;
- const char *toolbar_url;
- os_error *error;
- wimp_pointer pointer;
- float scale;
- uint32_t c = (uint32_t) key->c;
-
- /* Find gui window */
- if ((g = ro_gui_window_lookup(key->w)) != NULL) {
- toolbar = false;
- } else if ((g = ro_gui_toolbar_lookup(key->w)) != NULL) {
- toolbar = true;
- } else {
- /* nothing to do with us */
- return false;
- }
+ hlcache_handle *h;
+ wimp_window_state state;
+ int y;
+ const char *toolbar_url;
+ os_error *error;
+ float scale;
+ uint32_t c = (uint32_t) key->c;
+
+ if (g == NULL)
+ return;
h = g->bw->current_content;
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG(("xwimp_get_pointer_info: 0x%x: %s\n",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return false;
- }
+ switch (c) {
+ case IS_WIMP_KEY + wimp_KEY_F1: /* Help. */
+ ro_gui_open_help_page("documentation/index");
+ return;
- /* First send the key to the browser window, eg. form fields. */
- if (!toolbar) {
- if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) ||
- (c & IS_WIMP_KEY)) {
- /* Munge control keys into unused control chars */
- /* We can't map onto 1->26 (reserved for ctrl+<qwerty>
- That leaves 27->31 and 128->159 */
- switch (c & ~IS_WIMP_KEY) {
- case wimp_KEY_TAB: c = 9; break;
- case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break;
-
- /* cursor movement keys */
- case wimp_KEY_HOME:
- case wimp_KEY_CONTROL | wimp_KEY_LEFT:
- c = KEY_LINE_START;
- break;
- case wimp_KEY_END:
- if (os_version >= RISCOS5)
- c = KEY_LINE_END;
- else
- c = KEY_DELETE_RIGHT;
- break;
- case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = KEY_LINE_END; break;
- case wimp_KEY_CONTROL | wimp_KEY_UP: c = KEY_TEXT_START; break;
- case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = KEY_TEXT_END; break;
- case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = KEY_WORD_LEFT ; break;
- case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = KEY_WORD_RIGHT; break;
- case wimp_KEY_SHIFT | wimp_KEY_UP: c = KEY_PAGE_UP; break;
- case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = KEY_PAGE_DOWN; break;
- case wimp_KEY_LEFT: c = KEY_LEFT; break;
- case wimp_KEY_RIGHT: c = KEY_RIGHT; break;
- case wimp_KEY_UP: c = KEY_UP; break;
- case wimp_KEY_DOWN: c = KEY_DOWN; break;
-
- /* editing */
- case wimp_KEY_CONTROL | wimp_KEY_END:
- c = KEY_DELETE_LINE_END;
- break;
- case wimp_KEY_DELETE:
- if (ro_gui_ctrl_pressed())
- c = KEY_DELETE_LINE_START;
- else if (os_version < RISCOS5)
- c = KEY_DELETE_LEFT;
- break;
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F1:
+ ro_gui_window_action_page_info(g);
+ return;
- default:
- break;
- }
- }
+ case IS_WIMP_KEY + wimp_KEY_F2:
+ if (g->toolbar == NULL)
+ return;
+ ro_gui_url_complete_close();
+ ro_toolbar_set_url(g->toolbar, "www.", true, true);
+ ro_gui_url_complete_start(g->toolbar);
+ ro_gui_url_complete_keypress(g->toolbar, wimp_KEY_DOWN);
+ return;
- if (!(c & IS_WIMP_KEY)) {
- if (browser_window_key_press(g->bw, c))
- return true;
- }
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F2:
+ /* Close window. */
+ ro_gui_url_complete_close();
+ browser_window_destroy(g->bw);
+ return;
- /* Reset c to incoming character / key code
- * as we may have corrupted it above */
- c = (uint32_t) key->c;
- }
+ case 19: /* Ctrl + S */
+ case IS_WIMP_KEY + wimp_KEY_F3:
+ ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
+ return;
- switch (c) {
- case IS_WIMP_KEY + wimp_KEY_F1: /* Help. */
- return ro_gui_menu_handle_action(g->window,
- HELP_OPEN_CONTENTS, false);
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F3:
+ ro_gui_window_action_save(g, GUI_SAVE_TEXT);
+ return;
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F1:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_PAGE_INFO, false);
+ case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F3:
+ ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
+ return;
- case IS_WIMP_KEY + wimp_KEY_F2:
- if (!g->toolbar)
- return false;
- ro_gui_url_complete_close(NULL, 0);
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, "www.", true);
- xwimp_set_caret_position(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, 0, 0, -1, 4);
- ro_gui_url_complete_start(g);
- ro_gui_url_complete_keypress(g, wimp_KEY_DOWN);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT + wimp_KEY_F3:
+ ro_gui_window_action_save(g, GUI_SAVE_DRAW);
+ return;
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F2:
- /* Close window. */
- ro_gui_url_complete_close(NULL, 0);
- browser_window_destroy(g->bw);
- return true;
+ case 6: /* Ctrl + F */
+ case IS_WIMP_KEY + wimp_KEY_F4: /* Search */
+ ro_gui_window_action_search(g);
+ return;
- case 19: /* Ctrl + S */
- case IS_WIMP_KEY + wimp_KEY_F3:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_SAVE, false);
-
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F3:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_EXPORT_TEXT, false);
-
- case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F3:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_SAVE_COMPLETE, false);
-
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT +
- wimp_KEY_F3:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_EXPORT_DRAW, false);
-
- case 6: /* Ctrl + F */
- case IS_WIMP_KEY + wimp_KEY_F4: /* Search */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_FIND_TEXT, false);
-
- case IS_WIMP_KEY + wimp_KEY_F5: /* Reload */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_RELOAD, false);
-
- case 18: /* Ctrl+R (Full reload) */
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F5:
- /* Full reload */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_RELOAD_ALL, false);
-
- case IS_WIMP_KEY + wimp_KEY_F6: /* Hotlist */
- return ro_gui_menu_handle_action(g->window,
- HOTLIST_SHOW, false);
-
- case IS_WIMP_KEY + wimp_KEY_F7: /* Show local history */
- return ro_gui_menu_handle_action(g->window,
- HISTORY_SHOW_LOCAL, false);
-
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F7:
- /* Show global history */
- return ro_gui_menu_handle_action(g->window,
- HISTORY_SHOW_GLOBAL, false);
-
- case IS_WIMP_KEY + wimp_KEY_F8: /* View source */
- ro_gui_view_source(h);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F5: /* Reload */
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, false);
+ return;
- case IS_WIMP_KEY + wimp_KEY_F9:
- /* Dump content for debugging. */
- ro_gui_dump_content(h);
- return true;
+ case 18: /* Ctrl+R (Full reload) */
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F5:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, true);
+ return;
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F9:
- urldb_dump();
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F6: /* Hotlist */
+ ro_gui_hotlist_open();
+ return;
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT +
- wimp_KEY_F9:
- talloc_report_full(0, stderr);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F7: /* Show local history */
+ ro_gui_window_action_local_history(g);
+ return;
- case IS_WIMP_KEY + wimp_KEY_F11: /* Zoom */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_SCALE_VIEW, false);
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F7:
+ /* Show global history */
+ ro_gui_global_history_open();
+ return;
- case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F11:
- /* Toggle display of box outlines. */
- html_redraw_debug = !html_redraw_debug;
- gui_window_redraw_window(g);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F8: /* View source */
+ ro_gui_view_source(h);
+ return;
- case wimp_KEY_RETURN:
- if (!toolbar)
- break;
- toolbar_url = ro_gui_get_icon_string(
- g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL);
- ro_gui_window_launch_url(g, toolbar_url);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F9:
+ /* Dump content for debugging. */
+ ro_gui_dump_content(h);
+ return;
- case wimp_KEY_ESCAPE:
- if (ro_gui_url_complete_close(NULL, 0)) {
- ro_gui_url_complete_start(g);
- return true;
- }
- return ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_STOP, false);
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F9:
+ urldb_dump();
+ return;
- case 8: /* CTRL+H / Backspace */
- if (toolbar)
- return ro_gui_url_complete_keypress(g, c);
- break;
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT + wimp_KEY_F9:
+ talloc_report_full(0, stderr);
+ return;
- case 14: /* CTRL+N */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_NEW_WINDOW, false);
+ case IS_WIMP_KEY + wimp_KEY_F11: /* Zoom */
+ ro_gui_window_action_zoom(g);
+ return;
- case 17: /* CTRL+Q (Zoom out) */
- case 23: /* CTRL+W (Zoom in) */
- if (!h)
- break;
- scale = g->bw->scale;
- if (ro_gui_shift_pressed() && c == 17)
- scale = g->bw->scale - 0.1;
- else if (ro_gui_shift_pressed() && c == 23)
- scale = g->bw->scale + 0.1;
- else if (c == 17) {
- for (int i = SCALE_SNAP_TO_SIZE - 1;
- i >= 0; i--)
- if (scale_snap_to[i] <
- g->bw->scale) {
- scale = scale_snap_to[i];
- break;
- }
- } else {
- for (unsigned int i = 0;
- i < SCALE_SNAP_TO_SIZE; i++)
- if (scale_snap_to[i] >
- g->bw->scale) {
- scale = scale_snap_to[i];
- break;
- }
- }
- if (scale < scale_snap_to[0])
- scale = scale_snap_to[0];
- if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1])
- scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1];
- if (g->bw->scale != scale) {
- browser_window_set_scale(g->bw, scale, true);
-// g->reformat_pending = true;
-// if ((h) && (content_get_type(h) != CONTENT_HTML))
-// browser_window_update(g->bw, false);
-// browser_reformat_pending = true;
- }
- return true;
+ case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F11:
+ /* Toggle display of box outlines. */
+ html_redraw_debug = !html_redraw_debug;
+ gui_window_redraw_window(g);
+ return;
- case IS_WIMP_KEY + wimp_KEY_PRINT:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_PRINT, false);
+ case wimp_KEY_RETURN:
+ if (is_toolbar) {
+ toolbar_url = ro_toolbar_get_url(g->toolbar);
+ if (toolbar_url != NULL)
+ ro_gui_window_launch_url(g, toolbar_url);
+ }
+ return;
- case IS_WIMP_KEY | wimp_KEY_LEFT:
- case IS_WIMP_KEY | wimp_KEY_RIGHT:
- case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_LEFT:
- case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_RIGHT:
- if (toolbar)
- return false;
- break;
- case IS_WIMP_KEY + wimp_KEY_UP:
- case IS_WIMP_KEY + wimp_KEY_DOWN:
- case IS_WIMP_KEY + wimp_KEY_PAGE_UP:
- case IS_WIMP_KEY + wimp_KEY_PAGE_DOWN:
- case wimp_KEY_HOME:
- case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP:
- case IS_WIMP_KEY + wimp_KEY_END:
- case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN:
- if (toolbar)
- return ro_gui_url_complete_keypress(g, c);
+ case wimp_KEY_ESCAPE:
+ if (ro_gui_url_complete_close()) {
+ ro_gui_url_complete_start(g->toolbar);
+ return;
+ }
+
+ if (g->bw != NULL)
+ browser_window_stop(g->bw);
+ return;
+
+ case 14: /* CTRL+N */
+ ro_gui_window_action_new_window(g);
+ return;
+
+ case 17: /* CTRL+Q (Zoom out) */
+ case 23: /* CTRL+W (Zoom in) */
+ if (!h)
break;
- default:
- if (toolbar)
- return ro_gui_url_complete_keypress(g, c);
- return false;
+ scale = g->bw->scale;
+ if (ro_gui_shift_pressed() && c == 17)
+ scale = g->bw->scale - 0.1;
+ else if (ro_gui_shift_pressed() && c == 23)
+ scale = g->bw->scale + 0.1;
+ else if (c == 17) {
+ for (int i = SCALE_SNAP_TO_SIZE - 1; i >= 0; i--)
+ if (scale_snap_to[i] < g->bw->scale) {
+ scale = scale_snap_to[i];
+ break;
+ }
+ } else {
+ for (unsigned int i = 0; i < SCALE_SNAP_TO_SIZE; i++)
+ if (scale_snap_to[i] > g->bw->scale) {
+ scale = scale_snap_to[i];
+ break;
+ }
+ }
+ if (scale < scale_snap_to[0])
+ scale = scale_snap_to[0];
+ if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1])
+ scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1];
+ if (g->bw->scale != scale) {
+ browser_window_set_scale(g->bw, scale, true);
+// g->reformat_pending = true;
+// if ((h) && (content_get_type(h) != CONTENT_HTML))
+// browser_window_update(g->bw, false);
+// browser_reformat_pending = true;
+ }
+ return;
+
+ case IS_WIMP_KEY + wimp_KEY_PRINT:
+ ro_gui_window_action_print(g);
+ return;
+
+ case IS_WIMP_KEY | wimp_KEY_LEFT:
+ case IS_WIMP_KEY | wimp_KEY_RIGHT:
+ case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_LEFT:
+ case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_RIGHT:
+ if (is_toolbar)
+ return;
+ break;
+ case IS_WIMP_KEY + wimp_KEY_UP:
+ case IS_WIMP_KEY + wimp_KEY_DOWN:
+ case IS_WIMP_KEY + wimp_KEY_PAGE_UP:
+ case IS_WIMP_KEY + wimp_KEY_PAGE_DOWN:
+ case wimp_KEY_HOME:
+ case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP:
+ case IS_WIMP_KEY + wimp_KEY_END:
+ default:
+ break;
}
state.w = g->window;
@@ -2571,12 +2366,12 @@ bool ro_gui_window_keypress(wimp_key *key)
if (error) {
LOG(("xwimp_get_window_state: 0x%x: %s",
error->errnum, error->errmess));
- return true;
+ return;
}
y = state.visible.y1 - state.visible.y0 - 32;
if (g->toolbar)
- y -= ro_gui_theme_toolbar_full_height(g->toolbar);
+ y -= ro_toolbar_full_height(g->toolbar);
switch (c) {
case IS_WIMP_KEY | wimp_KEY_LEFT:
@@ -2618,17 +2413,870 @@ bool ro_gui_window_keypress(wimp_key *key)
LOG(("xwimp_open_window: 0x%x: %s",
error->errnum, error->errmess));
}
+}
+
+
+/**
+ * Prepare the browser window menu for (re-)opening
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu about to be opened.
+ * \param *pointer Pointer to the relevant wimp event block, or
+ * NULL for an Adjust click.
+ * \return true if the event was handled; else false.
+ */
+
+bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
+{
+ struct gui_window *g;
+ struct browser_window *bw;
+ hlcache_handle *h;
+ struct toolbar *toolbar;
+ bool export_sprite, export_draw;
+ os_coord pos;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
+ toolbar = g->toolbar;
+ bw = g->bw;
+ h = bw->current_content;
+
+ /* If this is the form select menu, handle it now and then exit.
+ * Otherwise, carry on to the main browser window menu.
+ */
+
+ if (menu == gui_form_select_menu) {
+ return ro_gui_window_prepare_form_select_menu(g->bw,
+ gui_form_select_control);
+ }
+
+ if (menu != ro_gui_browser_window_menu)
+ return false;
+
+ /* If this is a new opening for the browser window menu (ie. not for a
+ * toolbar menu), get details of the object under the pointer.
+ */
+
+ if (pointer != NULL && g->window == w) {
+ ro_gui_url_complete_close();
+
+ current_menu_object = NULL;
+ current_menu_url = NULL;
+
+ if (h != NULL &&
+ ro_gui_window_to_window_pos(g, pointer->pos.x,
+ pointer->pos.y, &pos)) {
+ switch (content_get_type(h)) {
+ case CONTENT_HTML: {
+ struct box *box;
+ box = box_object_at_point(h, pos.x, pos.y);
+ current_menu_object = box ? box->object : NULL;
+ box = box_href_at_point(h, pos.x, pos.y);
+ current_menu_url = box ? box->href : NULL;
+ }
+ break;
+ case CONTENT_TEXTPLAIN:
+ /* no object, no url */
+ break;
+ default:
+ current_menu_object = h;
+ break;
+ }
+ }
+ }
+
+ /* Shade menu entries according to the state of the window and object
+ * under the pointer.
+ */
+
+ /* Toolbar (Sub)Menu */
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS,
+ ro_toolbar_menu_option_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS,
+ ro_toolbar_menu_buttons_tick(toolbar));
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_ADDRESS_BAR,
+ ro_toolbar_menu_edit_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_ADDRESS_BAR,
+ ro_toolbar_menu_url_tick(toolbar));
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_THROBBER,
+ ro_toolbar_menu_edit_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_THROBBER,
+ ro_toolbar_menu_throbber_tick(toolbar));
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT,
+ ro_toolbar_menu_edit_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT,
+ ro_toolbar_menu_edit_tick(toolbar));
+
+ /* Page Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_PAGE, h == NULL ||
+ (content_get_type(h) != CONTENT_HTML &&
+ content_get_type(h) != CONTENT_TEXTPLAIN));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_PAGE_INFO, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_PRINT, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NEW_WINDOW, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_FIND_TEXT,
+ h == NULL || (content_get_type(h) != CONTENT_HTML &&
+ content_get_type(h) != CONTENT_TEXTPLAIN));
+
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_VIEW_SOURCE, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_URI, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_URL, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_TEXT, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_COMPLETE, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_DRAW, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_PDF, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_TEXT, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_URI,
+ !current_menu_url);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_URL,
+ !current_menu_url);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_TEXT,
+ !current_menu_url);
+
+
+
+ /* Object Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT,
+ current_menu_object == NULL &&
+ current_menu_url == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_LINK,
+ current_menu_url == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_INFO,
+ current_menu_object == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_RELOAD,
+ current_menu_object == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_OBJECT,
+ current_menu_object == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_PRINT, true);
+ /* Not yet implemented */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE,
+ current_menu_object == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_URI,
+ current_menu_object == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_URL,
+ current_menu_object == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_TEXT,
+ current_menu_object == NULL);
+
+ if (current_menu_object != NULL)
+ ro_gui_window_content_export_types(current_menu_object,
+ &export_draw, &export_sprite);
+ else
+ ro_gui_window_content_export_types(h,
+ &export_draw, &export_sprite);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT,
+ (h == NULL && current_menu_object == NULL)
+ || !(export_sprite || export_draw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT_SPRITE,
+ (h == NULL && current_menu_object == NULL)
+ || !export_sprite);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT_DRAW,
+ (h == NULL && current_menu_object == NULL)
+ || !export_draw);
+
+
+ /* Selection Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION,
+ h == NULL || (content_get_type(h) != CONTENT_HTML &&
+ content_get_type(h) != CONTENT_TEXTPLAIN));
+ /* make menu available if there's anything that /could/
+ * be selected */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_SAVE, h == NULL ||
+ bw->sel == NULL || !selection_defined(bw->sel));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_COPY, h == NULL ||
+ bw->sel == NULL || !selection_defined(bw->sel));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_CUT, h == NULL ||
+ bw->sel == NULL || !selection_defined(bw->sel) ||
+ selection_read_only(bw->sel));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_PASTE,
+ h == NULL || bw->paste_callback == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_CLEAR, h == NULL ||
+ bw->sel == NULL || !selection_defined(bw->sel));
+
+
+ /* Navigate Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_BACK,
+ !browser_window_back_available(bw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_FORWARD,
+ !browser_window_forward_available(bw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_RELOAD_ALL,
+ !browser_window_reload_available(bw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_STOP,
+ !browser_window_stop_available(bw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_UP,
+ !ro_gui_window_up_available(bw));
+
+
+
+ /* View Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_IMAGES_FOREGROUND, true);
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_FOREGROUND, true);
+ /* Not yet implemented. */
+
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_BACKGROUND,
+ g != NULL && g->option.background_images);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_BUFFER_ANIMS,
+ g == NULL || g->option.buffer_everything);
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ANIMS, g != NULL &&
+ (g->option.buffer_animations ||
+ g->option.buffer_everything));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_BUFFER_ALL, g == NULL);
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ALL,
+ g != NULL && g->option.buffer_everything);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SCALE_VIEW, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_STAGGER,
+ option_window_screen_width == 0);
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_STAGGER,
+ ((option_window_screen_width == 0) ||
+ option_window_stagger));
+
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_COPY,
+ option_window_size_clone);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_RESET,
+ option_window_screen_width == 0);
+
+
+ /* Utilities Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, HOTLIST_ADD_URL, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, HISTORY_SHOW_LOCAL,
+ (bw == NULL || (bw->history == NULL) ||
+ !(h != NULL || history_back_available(bw->history) ||
+ history_forward_available(bw->history))));
+
+
+ /* Help Submenu */
+
+ ro_gui_menu_set_entry_ticked(menu, HELP_LAUNCH_INTERACTIVE,
+ ro_gui_interactive_help_available() &&
+ option_interactive_help);
return true;
}
/**
+ * Handle submenu warnings for a browser window menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu to which the warning applies.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ */
+
+void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action)
+{
+ struct gui_window *g;
+ struct browser_window *bw;
+ hlcache_handle *h;
+ struct toolbar *toolbar;
+ bool export;
+
+ if (menu != ro_gui_browser_window_menu)
+ return;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
+ toolbar = g->toolbar;
+ bw = g->bw;
+ h = bw->current_content;
+
+ switch (action) {
+ case BROWSER_PAGE_INFO:
+ if (h != NULL)
+ ro_gui_window_prepare_pageinfo(g);
+ break;
+
+ case BROWSER_FIND_TEXT:
+ if (h != NULL && (content_get_type(h) == CONTENT_HTML ||
+ content_get_type(h) == CONTENT_TEXTPLAIN))
+ ro_gui_search_prepare(g->bw);
+ break;
+
+ case BROWSER_SCALE_VIEW:
+ if (h != NULL)
+ ro_gui_dialog_prepare_zoom(g);
+ break;
+
+ case BROWSER_PRINT:
+ if (h != NULL)
+ ro_gui_print_prepare(g);
+ break;
+
+ case BROWSER_OBJECT_INFO:
+ if (current_menu_object != NULL)
+ ro_gui_window_prepare_objectinfo(current_menu_object,
+ current_menu_url);
+ break;
+
+ case BROWSER_OBJECT_SAVE:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
+ current_menu_object, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_SELECTION_SAVE:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
+ bw->sel, NULL, NULL);
+ break;
+
+ case BROWSER_SAVE_URL_URI:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ content_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_SAVE_URL_URL:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ content_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_SAVE_URL_TEXT:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ content_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_URI:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ content_get_url(current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_URL:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ content_get_url(current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_TEXT:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ content_get_url(current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_SAVE:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_SOURCE, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_SAVE_COMPLETE:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_COMPLETE, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_DRAW:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_DRAW, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_PDF:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_PDF, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_TEXT:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_TEXT, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_URI:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_URL:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_TEXT:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_OBJECT_EXPORT_SPRITE:
+ if (current_menu_object != NULL) {
+ ro_gui_window_content_export_types(current_menu_object,
+ NULL, &export);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object,
+ NULL, NULL, NULL);
+ } else if (h != NULL) {
+ ro_gui_window_content_export_types(h, NULL, &export);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ h, NULL, NULL, NULL);
+ }
+ break;
+
+ case BROWSER_OBJECT_EXPORT_DRAW:
+ if (current_menu_object != NULL) {
+ ro_gui_window_content_export_types(current_menu_object,
+ &export, NULL);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object,
+ NULL, NULL, NULL);
+ } else if (h != NULL) {
+ ro_gui_window_content_export_types(h, &export, NULL);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ h, NULL, NULL, NULL);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**
+ * Handle selections from a browser window menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu from which the selection was made.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ * \return true if action accepted; else false.
+ */
+
+bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action)
+{
+ struct gui_window *g;
+ struct browser_window *bw;
+ hlcache_handle *h;
+ struct toolbar *toolbar;
+ wimp_window_state state;
+ os_error *error;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
+ toolbar = g->toolbar;
+ bw = g->bw;
+ h = bw->current_content;
+
+ /* If this is a form menu from the core, handle it now and then exit.
+ * Otherwise, carry on to the main browser window menu.
+ */
+
+ if (menu == gui_form_select_menu && w == g->window) {
+ ro_gui_window_process_form_select_menu(g, selection);
+
+ return true;
+ }
+
+ /* We're now safe to assume that this is either the browser or
+ * toolbar window menu.
+ */
+
+ switch (action) {
+
+ /* help actions */
+ case HELP_OPEN_CONTENTS:
+ ro_gui_open_help_page("documentation/index");
+ break;
+ case HELP_OPEN_GUIDE:
+ ro_gui_open_help_page("documentation/guide");
+ break;
+ case HELP_OPEN_INFORMATION:
+ ro_gui_open_help_page("documentation/info");
+ break;
+ case HELP_OPEN_ABOUT:
+ ro_gui_open_help_page("about/index");
+ break;
+ case HELP_LAUNCH_INTERACTIVE:
+ if (!ro_gui_interactive_help_available()) {
+ ro_gui_interactive_help_start();
+ option_interactive_help = true;
+ } else {
+ option_interactive_help = !option_interactive_help;
+ }
+ break;
+
+ /* history actions */
+ case HISTORY_SHOW_LOCAL:
+ ro_gui_window_action_local_history(g);
+ break;
+ case HISTORY_SHOW_GLOBAL:
+ ro_gui_global_history_open();
+ break;
+
+ /* hotlist actions */
+ case HOTLIST_ADD_URL:
+ ro_gui_window_action_add_bookmark(g);
+ break;
+ case HOTLIST_SHOW:
+ ro_gui_hotlist_open();
+ break;
+
+ /* cookies actions */
+ case COOKIES_SHOW:
+ ro_gui_cookies_open();
+ break;
+
+ case COOKIES_DELETE:
+ cookies_delete_all();
+ break;
+
+ /* page actions */
+ case BROWSER_PAGE_INFO:
+ ro_gui_window_action_page_info(g);
+ break;
+ case BROWSER_PRINT:
+ ro_gui_window_action_print(g);
+ break;
+ case BROWSER_NEW_WINDOW:
+ ro_gui_window_action_new_window(g);
+ break;
+ case BROWSER_VIEW_SOURCE:
+ if (h != NULL)
+ ro_gui_view_source(h);
+ break;
+
+ /* object actions */
+ case BROWSER_OBJECT_INFO:
+ if (current_menu_object != NULL) {
+ ro_gui_window_prepare_objectinfo(current_menu_object,
+ current_menu_url);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_objinfo, false);
+ }
+ break;
+ case BROWSER_OBJECT_RELOAD:
+ if (current_menu_object != NULL) {
+ content_invalidate_reuse_data(current_menu_object);
+ browser_window_reload(bw, false);
+ }
+ break;
+
+ /* link actions */
+ case BROWSER_LINK_SAVE_URI:
+ if (current_menu_url != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ current_menu_url, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_LINK_SAVE_URL:
+ if (current_menu_url != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ current_menu_url, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_LINK_SAVE_TEXT:
+ if (current_menu_url != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ current_menu_url, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_LINK_DOWNLOAD:
+ if (current_menu_url != NULL)
+ browser_window_download(bw, current_menu_url,
+ content_get_url(h));
+ break;
+ case BROWSER_LINK_NEW_WINDOW:
+ if (current_menu_url != NULL)
+ browser_window_create(current_menu_url, bw,
+ content_get_url(h), true, false);
+ break;
+
+ /* save actions */
+ case BROWSER_OBJECT_SAVE:
+ if (current_menu_object != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
+ current_menu_object, NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_OBJECT_EXPORT_SPRITE:
+ if (current_menu_object != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object, NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_OBJECT_EXPORT_DRAW:
+ if (current_menu_object != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object, NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_SAVE:
+ ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
+ break;
+ case BROWSER_SAVE_COMPLETE:
+ ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
+ break;
+ case BROWSER_EXPORT_DRAW:
+ ro_gui_window_action_save(g, GUI_SAVE_DRAW);
+ break;
+ case BROWSER_EXPORT_PDF:
+ ro_gui_window_action_save(g, GUI_SAVE_PDF);
+ break;
+ case BROWSER_EXPORT_TEXT:
+ ro_gui_window_action_save(g, GUI_SAVE_TEXT);
+ break;
+ case BROWSER_SAVE_URL_URI:
+ ro_gui_window_action_save(g, GUI_SAVE_LINK_URI);
+ break;
+ case BROWSER_SAVE_URL_URL:
+ ro_gui_window_action_save(g, GUI_SAVE_LINK_URL);
+ break;
+ case BROWSER_SAVE_URL_TEXT:
+ ro_gui_window_action_save(g, GUI_SAVE_LINK_TEXT);
+ break;
+
+ /* selection actions */
+ case BROWSER_SELECTION_SAVE:
+ if (h != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
+ bw->sel, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_SELECTION_COPY:
+ browser_window_key_press(bw, KEY_COPY_SELECTION);
+ break;
+ case BROWSER_SELECTION_CUT:
+ browser_window_key_press(bw, KEY_CUT_SELECTION);
+ break;
+ case BROWSER_SELECTION_PASTE:
+ browser_window_key_press(bw, KEY_PASTE);
+ break;
+ case BROWSER_SELECTION_ALL:
+ browser_window_key_press(bw, KEY_SELECT_ALL);
+ break;
+ case BROWSER_SELECTION_CLEAR:
+ browser_window_key_press(bw, KEY_CLEAR_SELECTION);
+ break;
+
+ /* navigation actions */
+ case BROWSER_NAVIGATE_HOME:
+ ro_gui_window_action_home(g);
+ break;
+ case BROWSER_NAVIGATE_BACK:
+ if (bw != NULL && bw->history != NULL)
+ history_back(bw, bw->history);
+ break;
+ case BROWSER_NAVIGATE_FORWARD:
+ if (bw != NULL && bw->history != NULL)
+ history_forward(bw, bw->history);
+ break;
+ case BROWSER_NAVIGATE_UP:
+ if (bw != NULL && h != NULL)
+ ro_gui_window_navigate_up(bw->window,
+ content_get_url(h));
+ break;
+ case BROWSER_NAVIGATE_RELOAD_ALL:
+ if (bw != NULL)
+ browser_window_reload(bw, true);
+ break;
+ case BROWSER_NAVIGATE_STOP:
+ if (bw != NULL)
+ browser_window_stop(bw);
+ break;
+
+ /* browser window/display actions */
+ case BROWSER_SCALE_VIEW:
+ ro_gui_window_action_zoom(g);
+ break;
+ case BROWSER_FIND_TEXT:
+ ro_gui_window_action_search(g);
+ break;
+ case BROWSER_IMAGES_BACKGROUND:
+ if (g != NULL) {
+ g->option.background_images =
+ !g->option.background_images;
+ gui_window_redraw_window(g);
+ }
+ break;
+ case BROWSER_BUFFER_ANIMS:
+ if (g != NULL)
+ g->option.buffer_animations =
+ !g->option.buffer_animations;
+ break;
+ case BROWSER_BUFFER_ALL:
+ if (g != NULL)
+ g->option.buffer_everything =
+ !g->option.buffer_everything;
+ break;
+ case BROWSER_SAVE_VIEW:
+ if (bw != NULL) {
+ ro_gui_window_default_options(bw);
+ ro_gui_save_options();
+ }
+ break;
+ case BROWSER_WINDOW_DEFAULT:
+ if (g != NULL) {
+ ro_gui_screen_size(&option_window_screen_width,
+ &option_window_screen_height);
+ state.w = w;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG(("xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+ option_window_x = state.visible.x0;
+ option_window_y = state.visible.y0;
+ option_window_width =
+ state.visible.x1 - state.visible.x0;
+ option_window_height =
+ state.visible.y1 - state.visible.y0;
+ ro_gui_save_options();
+ }
+ break;
+ case BROWSER_WINDOW_STAGGER:
+ option_window_stagger = !option_window_stagger;
+ ro_gui_save_options();
+ break;
+ case BROWSER_WINDOW_COPY:
+ option_window_size_clone = !option_window_size_clone;
+ ro_gui_save_options();
+ break;
+ case BROWSER_WINDOW_RESET:
+ option_window_screen_width = 0;
+ option_window_screen_height = 0;
+ ro_gui_save_options();
+ break;
+
+ /* toolbar actions */
+ case TOOLBAR_BUTTONS:
+ assert(toolbar);
+ ro_toolbar_set_display_buttons(toolbar,
+ !ro_toolbar_get_display_buttons(toolbar));
+ break;
+ case TOOLBAR_ADDRESS_BAR:
+ assert(toolbar);
+ ro_toolbar_set_display_url(toolbar,
+ !ro_toolbar_get_display_url(toolbar));
+ if (ro_toolbar_get_display_url(toolbar))
+ ro_toolbar_take_caret(toolbar);
+ break;
+ case TOOLBAR_THROBBER:
+ assert(toolbar);
+ ro_toolbar_set_display_throbber(toolbar,
+ !ro_toolbar_get_display_throbber(toolbar));
+ break;
+ case TOOLBAR_EDIT:
+ assert(toolbar);
+ ro_toolbar_toggle_edit(toolbar);
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Handle the closure of a browser window menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu that is being closed.
+ */
+
+void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu)
+{
+ if (menu == ro_gui_browser_window_menu) {
+ current_menu_object = NULL;
+ current_menu_url = NULL;
+ } else if (menu == gui_form_select_menu) {
+ gui_form_select_control = NULL;
+ }
+}
+
+
+/**
* Process Scroll_Request events.
+ *
+ * \TODO -- This handles Scroll Events for all windows, not just browser
+ * windows. Either it needs to move somewhere else, or the
+ * code needs to be split and Scroll Events dispatched via the
+ * Wimp_Event module. Currently it doesn't properly handle
+ * events affecting treeview windows, anyway.
*/
+
void ro_gui_scroll_request(wimp_scroll *scroll)
{
- struct gui_window *g = ro_gui_window_lookup(scroll->w);
+ struct gui_window *g = ro_gui_window_lookup(scroll->w);
+ struct toolbar *toolbar;
if (g && g->bw->current_content && ro_gui_shift_pressed()) {
/* extended scroll request with shift held down; change zoom */
@@ -2656,8 +3304,12 @@ void ro_gui_scroll_request(wimp_scroll *scroll)
int y = scroll->visible.y1 - scroll->visible.y0 - 32;
os_error *error;
- if (g && g->toolbar)
- y -= ro_gui_theme_toolbar_full_height(g->toolbar);
+ /* This has to handle all windows, not just browser ones. */
+ toolbar = ro_toolbar_parent_window_lookup(scroll->w);
+ assert(g == NULL || g->toolbar == NULL ||
+ g->toolbar == toolbar);
+ if (toolbar != NULL)
+ y -= ro_toolbar_full_height(toolbar);
switch (scroll->xmin) {
case wimp_SCROLL_PAGE_LEFT:
@@ -2705,70 +3357,6 @@ void ro_gui_scroll_request(wimp_scroll *scroll)
/**
- * Convert x,y screen co-ordinates into window co-ordinates.
- *
- * \param g gui window
- * \param x x ordinate
- * \param y y ordinate
- * \param pos receives position in window co-ordinatates
- * \return true iff conversion successful
- */
-
-bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
- os_coord *pos)
-{
- wimp_window_state state;
- os_error *error;
-
- assert(g);
-
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG(("xwimp_get_window_state: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return false;
- }
- pos->x = (x - (state.visible.x0 - state.xscroll)) / 2 / g->bw->scale;
- pos->y = ((state.visible.y1 - state.yscroll) - y) / 2 / g->bw->scale;
- return true;
-}
-
-
-/**
- * Convert x,y window co-ordinates into screen co-ordinates.
- *
- * \param g gui window
- * \param x x ordinate
- * \param y y ordinate
- * \param pos receives position in screen co-ordinatates
- * \return true iff conversion successful
- */
-
-bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
- os_coord *pos)
-{
- wimp_window_state state;
- os_error *error;
-
- assert(g);
-
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG(("xwimp_get_window_state: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return false;
- }
- pos->x = (x * 2 * g->bw->scale) + (state.visible.x0 - state.xscroll);
- pos->y = (state.visible.y1 - state.yscroll) - (y * 2 * g->bw->scale);
- return true;
-}
-
-
-/**
* Handle Message_DataLoad (file dragged in) for a window.
*
* \param g window
@@ -2884,8 +3472,366 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
/**
+ * Handle pointer movements in a browser window.
+ *
+ * \param g browser window that the pointer is in
+ * \param pointer new mouse position
+ */
+
+void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer)
+{
+ os_coord pos;
+
+ if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
+ browser_window_mouse_track(g->bw,
+ ro_gui_mouse_drag_state(pointer->buttons,
+ wimp_BUTTON_CLICK_DRAG),
+ pos.x, pos.y);
+}
+
+
+/**
+ * Window is being iconised. Create a suitable thumbnail sprite
+ * (which, sadly, must be in the Wimp sprite pool), and return
+ * the sprite name and truncated title to the iconiser
+ *
+ * \param g the gui window being iconised
+ * \param wi the WindowInfo message from the iconiser
+ */
+
+void ro_gui_window_iconise(struct gui_window *g,
+ wimp_full_message_window_info *wi)
+{
+ /* sadly there is no 'legal' way to get the sprite into
+ * the Wimp sprite pool other than via a filing system */
+ const char *temp_fname = "Pipe:$._tmpfile";
+ struct browser_window *bw = g->bw;
+ osspriteop_header *overlay = NULL;
+ osspriteop_header *sprite_header;
+ struct bitmap *bitmap;
+ osspriteop_area *area;
+ int width = 34, height = 34;
+ hlcache_handle *h;
+ os_error *error;
+ int len, id;
+
+ assert(bw);
+
+ h = bw->current_content;
+ if (!h) return;
+
+ /* if an overlay sprite is defined, locate it and gets its dimensions
+ * so that we can produce a thumbnail with the same dimensions */
+ if (!ro_gui_wimp_get_sprite("ic_netsfxx", &overlay)) {
+ error = xosspriteop_read_sprite_info(osspriteop_PTR,
+ (osspriteop_area *)0x100,
+ (osspriteop_id)overlay, &width, &height, NULL,
+ NULL);
+ if (error) {
+ LOG(("xosspriteop_read_sprite_info: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("MiscError", error->errmess);
+ overlay = NULL;
+ }
+ else if (sprite_bpp(overlay) != 8) {
+ LOG(("overlay sprite is not 8bpp"));
+ overlay = NULL;
+ }
+ }
+
+ /* create the thumbnail sprite */
+ bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE |
+ BITMAP_CLEAR_MEMORY);
+ if (!bitmap) {
+ LOG(("Thumbnail initialisation failed."));
+ return;
+ }
+ thumbnail_create(h, bitmap, NULL);
+ if (overlay)
+ bitmap_overlay_sprite(bitmap, overlay);
+ area = thumbnail_convert_8bpp(bitmap);
+ bitmap_destroy(bitmap);
+ if (!area) {
+ LOG(("Thumbnail conversion failed."));
+ return;
+ }
+
+ /* choose a suitable sprite name */
+ id = 0;
+ while (iconise_used[id])
+ if ((unsigned)++id >= NOF_ELEMENTS(iconise_used)) {
+ id = iconise_next;
+ if ((unsigned)++iconise_next >=
+ NOF_ELEMENTS(iconise_used))
+ iconise_next = 0;
+ break;
+ }
+
+ sprite_header = (osspriteop_header *)(area + 1);
+ len = sprintf(sprite_header->name, "ic_netsf%.2d", id);
+
+ error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
+ area, temp_fname);
+ if (error) {
+ LOG(("xosspriteop_save_sprite_file: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("MiscError", error->errmess);
+ free(area);
+ return;
+ }
+
+ error = xwimpspriteop_merge_sprite_file(temp_fname);
+ if (error) {
+ LOG(("xwimpspriteop_merge_sprite_file: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ remove(temp_fname);
+ free(area);
+ return;
+ }
+
+ memcpy(wi->sprite_name, sprite_header->name + 3, len - 2); /* inc NUL */
+ strncpy(wi->title, g->title, sizeof(wi->title));
+ wi->title[sizeof(wi->title) - 1] = '\0';
+
+ if (wimptextop_string_width(wi->title, 0) > 182) {
+ /* work around bug in Pinboard where it will fail to display
+ * the icon if the text is very wide */
+ if (strlen(wi->title) > 10)
+ wi->title[10] = '\0'; /* pinboard does this anyway */
+ while (wimptextop_string_width(wi->title, 0) > 182)
+ wi->title[strlen(wi->title) - 1] = '\0';
+ }
+
+ wi->size = sizeof(wimp_full_message_window_info);
+ wi->your_ref = wi->my_ref;
+ error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)wi,
+ wi->sender);
+ if (error) {
+ LOG(("xwimp_send_message: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+ else {
+ g->iconise_icon = id;
+ iconise_used[id] = true;
+ }
+
+ free(area);
+}
+
+
+/**
+ * Completes scrolling of a browser window
+ *
+ * \param g gui window
+ */
+
+void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag)
+{
+ wimp_pointer pointer;
+ os_error *error;
+ os_coord pos;
+
+ gui_current_drag_type = GUI_DRAG_NONE;
+ if (!g)
+ return;
+
+ error = xwimp_drag_box((wimp_drag*)-1);
+ if (error) {
+ LOG(("xwimp_drag_box: 0x%x : %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG(("xwimp_get_pointer_info 0x%x : %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return;
+ }
+
+ error = xwimpspriteop_set_pointer_shape("ptr_default", 0x31, 0, 0, 0, 0);
+ if (error) {
+ LOG(("xwimpspriteop_set_pointer_shape: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+
+ if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos))
+ browser_window_mouse_drag_end(g->bw,
+ ro_gui_mouse_click_state(pointer.buttons,
+ wimp_BUTTON_CLICK_DRAG),
+ pos.x, pos.y);
+}
+
+
+/**
+ * Completes resizing of a browser frame
+ *
+ * \param g gui window
+ */
+
+void ro_gui_window_frame_resize_end(struct gui_window *g, wimp_dragged *drag)
+{
+ /* our clean-up is the same as for page scrolling */
+ ro_gui_window_scroll_end(g, drag);
+}
+
+
+/**
+ * Process Mouse_Click events in a toolbar's button bar. This does not handle
+ * other clicks in a toolbar: these are handled by the toolbar module itself.
+ *
+ * \param *data The GUI window associated with the click.
+ * \param action_type The action type to be handled.
+ * \param action The action to process.
+ */
+
+void ro_gui_window_toolbar_click(void *data,
+ toolbar_action_type action_type, union toolbar_action action)
+{
+ struct gui_window *g = data;
+ struct browser_window *new_bw;
+ gui_save_type save_type;
+
+ if (g == NULL)
+ return;
+
+
+ if (action_type == TOOLBAR_ACTION_URL &&
+ action.url == TOOLBAR_URL_DRAG_URL) {
+ if (g->bw->current_content) {
+ hlcache_handle *h = g->bw->current_content;
+
+ if (ro_gui_shift_pressed())
+ save_type = GUI_SAVE_LINK_URL;
+ else
+ save_type = GUI_SAVE_LINK_TEXT;
+
+ ro_gui_drag_save_link(save_type, content_get_url(h),
+ content_get_title(h), g);
+ }
+
+ return;
+ }
+
+
+ /* By now, the only valid action left is a button click. If it isn't
+ * one of those, give up.
+ */
+
+ if (action_type != TOOLBAR_ACTION_BUTTON)
+ return;
+
+ switch (action.button) {
+ case TOOLBAR_BUTTON_BACK:
+ if (g->bw != NULL && g->bw->history != NULL)
+ history_back(g->bw, g->bw->history);
+ break;
+
+ case TOOLBAR_BUTTON_BACK_NEW:
+ ro_gui_window_action_navigate_back_new(g);
+ break;
+
+ case TOOLBAR_BUTTON_FORWARD:
+ if (g->bw != NULL && g->bw->history != NULL)
+ history_forward(g->bw, g->bw->history);
+ break;
+
+ case TOOLBAR_BUTTON_FORWARD_NEW:
+ ro_gui_window_action_navigate_forward_new(g);
+ break;
+
+ case TOOLBAR_BUTTON_STOP:
+ if (g->bw != NULL)
+ browser_window_stop(g->bw);
+ break;
+
+ case TOOLBAR_BUTTON_RELOAD:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, false);
+ break;
+
+ case TOOLBAR_BUTTON_RELOAD_ALL:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, true);
+ break;
+
+ case TOOLBAR_BUTTON_HISTORY_LOCAL:
+ ro_gui_window_action_local_history(g);
+ break;
+
+ case TOOLBAR_BUTTON_HISTORY_GLOBAL:
+ ro_gui_global_history_open();
+ break;
+
+ case TOOLBAR_BUTTON_HOME:
+ ro_gui_window_action_home(g);
+ break;
+
+ case TOOLBAR_BUTTON_SEARCH:
+ ro_gui_window_action_search(g);
+ break;
+
+ case TOOLBAR_BUTTON_SCALE:
+ ro_gui_window_action_zoom(g);
+ break;
+
+ case TOOLBAR_BUTTON_BOOKMARK_OPEN:
+ ro_gui_hotlist_open();
+ break;
+
+ case TOOLBAR_BUTTON_BOOKMARK_ADD:
+ ro_gui_window_action_add_bookmark(g);
+ break;
+
+ case TOOLBAR_BUTTON_SAVE_SOURCE:
+ ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
+ break;
+
+ case TOOLBAR_BUTTON_SAVE_COMPLETE:
+ ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
+ break;
+
+ case TOOLBAR_BUTTON_PRINT:
+ ro_gui_window_action_print(g);
+ break;
+
+ case TOOLBAR_BUTTON_UP:
+ if (g->bw != NULL && g->bw->current_content != NULL)
+ ro_gui_window_navigate_up(g->bw->window,
+ content_get_url(g->bw->current_content));
+ break;
+
+ case TOOLBAR_BUTTON_UP_NEW:
+ if (g->bw && g->bw->current_content) {
+ hlcache_handle *h = g->bw->current_content;
+ new_bw = browser_window_create(NULL,
+ g->bw, NULL, false,
+ false);
+ /* do it without loading the content
+ * into the new window */
+ ro_gui_window_navigate_up(new_bw->window,
+ content_get_url(h));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ro_gui_window_update_toolbar_buttons(g);
+}
+
+
+/**
* Handle Message_DataLoad (file dragged in) for a toolbar
*
+ * \TODO -- This belongs in the toolbar module, and should be moved there
+ * once the module is able to usefully handle its own events.
+ *
* \param g window
* \param message Message_DataLoad block
* \return true if the load was processed
@@ -2913,6 +3859,591 @@ bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
}
+/*
+ * Helper code for the Wimp Event Handlers.
+ */
+
+/**
+ * Check if a particular menu handle is a browser window menu
+ *
+ * \param *menu The menu in question.
+ * \return true if this menu is a browser window menu
+ */
+
+bool ro_gui_window_check_menu(wimp_menu *menu)
+{
+ return (ro_gui_browser_window_menu == menu) ? true : false;
+}
+
+
+/**
+ * Return boolean flags to show what RISC OS types we can sensibly convert
+ * the given object into.
+ *
+ * \TODO -- This should probably be somewhere else but in window.c, and
+ * should probably even be done in content_().
+ *
+ * \param *h The object to test.
+ * \param *export_draw true on exit if a drawfile would be possible.
+ * \param *export_sprite true on exit if a sprite would be possible.
+ * \return true if valid data is returned; else false.
+ */
+
+bool ro_gui_window_content_export_types(hlcache_handle *h,
+ bool *export_draw, bool *export_sprite)
+{
+ bool found_type = false;
+
+ if (export_draw != NULL)
+ *export_draw = false;
+ if (export_sprite != NULL)
+ *export_sprite = false;
+
+ if (h != NULL) {
+ switch (content_get_type(h)) {
+ /* bitmap types (Sprite export possible) */
+#ifdef WITH_JPEG
+ case CONTENT_JPEG:
+#endif
+#ifdef WITH_MNG
+ case CONTENT_JNG:
+ case CONTENT_MNG:
+#endif
+#ifdef WITH_GIF
+ case CONTENT_GIF:
+#endif
+#ifdef WITH_BMP
+ case CONTENT_BMP:
+ case CONTENT_ICO:
+#endif
+#if defined(WITH_MNG) || defined(WITH_PNG)
+ case CONTENT_PNG:
+#endif
+#ifdef WITH_SPRITE
+ case CONTENT_SPRITE:
+#endif
+ found_type = true;
+ if (export_sprite != NULL)
+ *export_sprite = true;
+ break;
+
+ /* vector types (Draw export possible) */
+#if defined(WITH_NS_SVG) || defined(WITH_RSVG)
+ case CONTENT_SVG:
+#endif
+#ifdef WITH_DRAW
+ case CONTENT_DRAW:
+#endif
+ found_type = true;
+ if (export_draw != NULL)
+ *export_draw = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return found_type;
+}
+
+
+/**
+ * Return true if a browser window can navigate upwards.
+ *
+ * \TODO -- This should probably be somewhere else but in window.c.
+ *
+ * \param *bw the browser window to test.
+ * \return true if navigation up is possible; else false.
+ */
+
+bool ro_gui_window_up_available(struct browser_window *bw)
+{
+ bool result = false, compare;
+ char *parent;
+ url_func_result res;
+
+ if (bw != NULL && bw->current_content != NULL) {
+ res = url_parent(content_get_url(bw->current_content), &parent);
+
+ if (res == URL_FUNC_OK) {
+ res = url_compare(content_get_url(bw->current_content),
+ parent, false, &compare);
+ if (res == URL_FUNC_OK)
+ result = !compare;
+ free(parent);
+ } else {
+ result = false;
+ }
+ }
+
+ return result;
+}
+
+
+/**
+ * Prepare the page info window for use.
+ *
+ * \param *g The GUI window block to use.
+ */
+
+void ro_gui_window_prepare_pageinfo(struct gui_window *g)
+{
+ hlcache_handle *h = g->bw->current_content;
+ char icon_buf[20] = "file_xxx";
+ char enc_buf[40];
+ char enc_token[10] = "Encoding0";
+ const char *icon = icon_buf;
+ const char *title, *url, *mime;
+ const char *enc = "-";
+
+ assert(h);
+
+ title = content_get_title(h);
+ if (title == NULL)
+ title = "-";
+ url = content_get_url(h);
+ if (url == NULL)
+ url = "-";
+ mime = content_get_mime_type(h);
+ if (mime == NULL)
+ mime = "-";
+
+ sprintf(icon_buf, "file_%x", ro_content_filetype(h));
+ if (!ro_gui_wimp_sprite_exists(icon_buf))
+ sprintf(icon_buf, "file_xxx");
+
+ if (content_get_type(h) == CONTENT_HTML) {
+ if (html_get_encoding(h)) {
+ enc_token[8] = '0' + html_get_encoding_source(h);
+ snprintf(enc_buf, sizeof enc_buf, "%s (%s)",
+ html_get_encoding(h),
+ messages_get(enc_token));
+ enc = enc_buf;
+ } else {
+ enc = messages_get("EncodingUnk");
+ }
+ }
+
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ICON,
+ icon, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TITLE,
+ title, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_URL,
+ url, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ENC,
+ enc, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TYPE,
+ mime, true);
+}
+
+
+/**
+ * Prepare the object info window for use
+ *
+ * \param *object the object for which information is to be displayed
+ * \param *href corresponding href, if any
+ */
+
+void ro_gui_window_prepare_objectinfo(hlcache_handle *object, const char *href)
+{
+ char icon_buf[20] = "file_xxx";
+ const char *url, *mime;
+ const char *target = "-";
+
+ sprintf(icon_buf, "file_%.3x",
+ ro_content_filetype(object));
+ if (!ro_gui_wimp_sprite_exists(icon_buf))
+ sprintf(icon_buf, "file_xxx");
+
+ url = content_get_url(object);
+ if (url == NULL)
+ url = "-";
+ mime = content_get_mime_type(object);
+ if (mime == NULL)
+ mime = "-";
+
+ if (href)
+ target = href;
+
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON,
+ icon_buf, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL,
+ url, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET,
+ target, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE,
+ mime, true);
+}
+
+
+/*
+ * User Actions in the browser window
+ */
+
+/**
+ * Launch a new url in the given window.
+ *
+ * \param g gui_window to update
+ * \param url url to be launched
+ */
+
+void ro_gui_window_launch_url(struct gui_window *g, const char *url)
+{
+ url_func_result res;
+ char *url_norm;
+
+ ro_gui_url_complete_close();
+ res = url_normalize(url, &url_norm);
+ if (res == URL_FUNC_OK) {
+ gui_window_set_url(g, url_norm);
+ browser_window_go(g->bw, url_norm, 0, true);
+ free(url_norm);
+ }
+}
+
+
+/**
+ * Navigate up one level
+ *
+ * \param g the gui_window to open the parent link in
+ * \param url the URL to open the parent of
+ */
+bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) {
+ char *parent;
+ url_func_result res;
+ bool compare;
+
+ if (!g || (!g->bw))
+ return false;
+
+ res = url_parent(url, &parent);
+ if (res == URL_FUNC_OK) {
+ res = url_compare(url, parent, false, &compare);
+ if ((res == URL_FUNC_OK) && !compare)
+ browser_window_go(g->bw, parent, 0, true);
+ free(parent);
+ }
+ return true;
+}
+
+
+/**
+ * Perform a Navigate Home action on a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_home(struct gui_window *g)
+{
+ char url[80];
+
+ if (g == NULL || g->bw == NULL)
+ return;
+
+ if ((option_homepage_url) && (option_homepage_url[0])) {
+ browser_window_go(g->bw, option_homepage_url, 0, true);
+ } else {
+ snprintf(url, sizeof url,
+ "file:///<NetSurf$Dir>/Docs/welcome/index_%s",
+ option_language);
+ browser_window_go(g->bw, url, 0, true);
+ }
+}
+
+
+/**
+ * Navigate back from a browser window into a new window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_navigate_back_new(struct gui_window *g)
+{
+ struct browser_window *new_bw;
+
+ if (g == NULL || g->bw == NULL)
+ return;
+
+ new_bw = browser_window_create(NULL, g->bw, NULL, false, false);
+
+ if (new_bw != NULL && new_bw->history != NULL)
+ history_back(new_bw, new_bw->history);
+}
+
+
+/**
+ * Navigate forward from a browser window into a new window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_navigate_forward_new(struct gui_window *g)
+{
+ struct browser_window *new_bw;
+
+ if (g == NULL || g->bw == NULL)
+ return;
+
+ new_bw = browser_window_create(NULL, g->bw, NULL, false, false);
+
+ if (new_bw != NULL && new_bw->history != NULL)
+ history_forward(new_bw, new_bw->history);
+}
+
+
+/**
+ * Open a new browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_new_window(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL)
+ return;
+
+ browser_window_create(content_get_url(g->bw->current_content), g->bw,
+ 0, false, false);
+}
+
+
+/**
+ * Open a local history pane for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_local_history(struct gui_window *g)
+{
+ if (g != NULL && g->bw != NULL && g->bw->history != NULL)
+ ro_gui_history_open(g->bw, g->bw->history, true);
+}
+
+
+/**
+ * Open a save dialogue for a browser window contents.
+ *
+ * \param *g The browser window to act on.
+ * \param save_type The type of save to open.
+ */
+
+void ro_gui_window_action_save(struct gui_window *g, gui_save_type save_type)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL)
+ return;
+
+ ro_gui_save_prepare(save_type, g->bw->current_content,
+ NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
+}
+
+
+/**
+ * Open a text search dialogue for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_search(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL ||
+ (content_get_type(g->bw->current_content) !=
+ CONTENT_HTML &&
+ content_get_type(g->bw->current_content) !=
+ CONTENT_TEXTPLAIN))
+ return;
+
+ ro_gui_search_prepare(g->bw);
+ ro_gui_dialog_open_persistent(g->window, dialog_search, true);
+}
+
+
+/**
+ * Open a zoom dialogue for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_zoom(struct gui_window *g)
+{
+ if (g == NULL)
+ return;
+
+ ro_gui_dialog_prepare_zoom(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_zoom, true);
+}
+
+
+/**
+ * Add a hotlist entry for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_add_bookmark(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL ||
+ content_get_url(g->bw->current_content) == NULL)
+ return;
+
+ hotlist_add_page(content_get_url(g->bw->current_content));
+}
+
+
+/**
+ * Open a print dialogue for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_print(struct gui_window *g)
+{
+ if (g == NULL)
+ return;
+
+ ro_gui_print_prepare(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_print, true);
+}
+
+
+/**
+ * Open a page info box for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_page_info(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL)
+ return;
+
+ ro_gui_window_prepare_pageinfo(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_pageinfo, false);
+}
+
+
+/*
+ * Window and Toolbar Redraw and Update
+ */
+
+/**
+ * Redraws the content for all windows.
+ */
+
+void ro_gui_window_redraw_all(void)
+{
+ struct gui_window *g;
+ for (g = window_list; g; g = g->next)
+ gui_window_redraw_window(g);
+}
+
+
+/**
+ * Remove all pending update boxes for a window
+ *
+ * \param g gui_window
+ */
+void ro_gui_window_remove_update_boxes(struct gui_window *g)
+{
+ struct update_box *cur;
+
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ if (cur->g == g)
+ cur->g = NULL;
+ }
+}
+
+
+/**
+ * Redraw any pending update boxes.
+ */
+void ro_gui_window_update_boxes(void)
+{
+ osbool more;
+ bool use_buffer;
+ wimp_draw update;
+ struct rect clip;
+ os_error *error;
+ struct update_box *cur;
+ struct gui_window *g;
+ const union content_msg_data *data;
+
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ g = cur->g;
+ if (!g)
+ continue;
+
+ data = &cur->data;
+ use_buffer = cur->use_buffer;
+
+ update.w = g->window;
+ update.box.x0 = cur->x0;
+ update.box.y0 = cur->y0;
+ update.box.x1 = cur->x1;
+ update.box.y1 = cur->y1;
+
+ error = xwimp_update_window(&update, &more);
+ if (error) {
+ LOG(("xwimp_update_window: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ continue;
+ }
+
+ /* Set the current redraw gui_window to get options from */
+ ro_gui_current_redraw_gui = g;
+ current_redraw_browser = g->bw;
+
+ plot = ro_plotters;
+ ro_plot_origin_x = update.box.x0 - update.xscroll;
+ ro_plot_origin_y = update.box.y1 - update.yscroll;
+ ro_plot_set_scale(g->bw->scale);
+
+ while (more) {
+ clip.x0 = (update.clip.x0 - ro_plot_origin_x) / 2;
+ clip.y0 = (ro_plot_origin_y - update.clip.y1) / 2;
+ clip.x1 = (update.clip.x1 - ro_plot_origin_x) / 2;
+ clip.y1 = (ro_plot_origin_y - update.clip.y0) / 2;
+
+ if (use_buffer)
+ ro_gui_buffer_open(&update);
+
+ browser_window_redraw(g->bw, 0, 0, &clip);
+
+ if (use_buffer)
+ ro_gui_buffer_close();
+
+ error = xwimp_get_rectangle(&update, &more);
+ /* RISC OS 3.7 returns an error here if enough buffer
+ * was claimed to cause a new dynamic area to be
+ * created. It doesn't actually stop anything working,
+ * so we mask it out for now until a better fix is
+ * found. This appears to be a bug in RISC OS. */
+ if (error && !(use_buffer &&
+ error->errnum == error_WIMP_GET_RECT)) {
+ LOG(("xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ ro_gui_current_redraw_gui = NULL;
+ current_redraw_browser = NULL;
+ continue;
+ }
+ }
+
+ /* Reset the current redraw gui_window to prevent
+ * thumbnails from retaining options */
+ ro_gui_current_redraw_gui = NULL;
+ current_redraw_browser = NULL;
+ }
+ while (pending_updates) {
+ cur = pending_updates;
+ pending_updates = pending_updates->next;
+ free(cur);
+ }
+}
+
+
/**
* Process pending reformats
*/
@@ -2934,6 +4465,237 @@ void ro_gui_window_process_reformats(void)
/**
+ * Destroy all browser windows.
+ */
+
+void ro_gui_window_quit(void)
+{
+ struct gui_window *cur;
+
+ while (window_list) {
+ cur = window_list;
+ window_list = window_list->next;
+
+ /* framesets and iframes are destroyed by their parents */
+ if (!cur->bw->parent)
+ browser_window_destroy(cur->bw);
+ }
+}
+
+
+/**
+ * Animate the "throbbers" of all browser windows.
+ */
+
+void ro_gui_throb(void)
+{
+ struct gui_window *g;
+ struct browser_window *top;
+
+ for (g = window_list; g; g = g->next) {
+ if (!g->bw->throbbing)
+ continue;
+ for (top = g->bw; top->parent; top = top->parent);
+ if (top->window != NULL && top->window->toolbar != NULL)
+ ro_toolbar_throb(top->window->toolbar);
+ }
+}
+
+
+/**
+ * Update the toolbar buttons for a given browser window to reflect the
+ * current state of its contents.
+ *
+ * Note that the parameters to this function are arranged so that it can be
+ * supplied to the toolbar module as an button state update callback.
+ *
+ * \param *g The browser window to update.
+ */
+
+void ro_gui_window_update_toolbar_buttons(struct gui_window *g)
+{
+ struct browser_window *bw;
+ hlcache_handle *h;
+ struct toolbar *toolbar;
+
+ if (g == NULL || g->toolbar == NULL)
+ return;
+
+ bw = g->bw;
+ h = bw->current_content;
+ toolbar = g->toolbar;
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_RELOAD,
+ !browser_window_reload_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_STOP,
+ !browser_window_stop_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_BACK,
+ !browser_window_back_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_FORWARD,
+ !browser_window_forward_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_UP,
+ !ro_gui_window_up_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SEARCH,
+ h == NULL || (content_get_type(h) != CONTENT_HTML &&
+ content_get_type(h) != CONTENT_TEXTPLAIN));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SCALE,
+ h == NULL);
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_PRINT,
+ h == NULL);
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SAVE_SOURCE,
+ h == NULL);
+
+ ro_toolbar_update_urlsuggest(toolbar);
+}
+
+
+/**
+ * Update a window to reflect a change in toolbar size: used as a callback by
+ * the toolbar module when a toolbar height changes.
+ *
+ * \param *data void pointer the window's gui_window struct
+ */
+
+void ro_gui_window_update_toolbar(void *data)
+{
+ struct gui_window *g = (struct gui_window *) data;
+
+ if (g != NULL)
+ gui_window_update_extent(g);
+}
+
+
+/**
+ * Save a new toolbar button configuration: used as a callback by the toolbar
+ * module when a buttonbar edit has finished.
+ *
+ * \param *data void pointer to the window's gui_window struct
+ * \param *config pointer to a malloc()'d button config string.
+ */
+
+void ro_gui_window_save_toolbar_buttons(void *data, char *config)
+{
+ if (option_toolbar_browser != NULL)
+ free(option_toolbar_browser);
+ option_toolbar_browser = config;
+ ro_gui_save_options();
+}
+
+
+/**
+ * Update a window and its toolbar to reflect a new theme: used as a callback
+ * by the toolbar module when a theme change affects a toolbar.
+ *
+ * \param *data void pointer to the window's gui_window struct
+ * \param ok true if the bar still exists; else false.
+ */
+
+void ro_gui_window_update_theme(void *data, bool ok)
+{
+ struct gui_window *g = (struct gui_window *) data;
+
+ if (g != NULL && g->toolbar != NULL) {
+ if (ok) {
+ gui_window_update_extent(g);
+ } else {
+ g->toolbar = NULL;
+ }
+ }
+}
+
+
+/*
+ * General Window Support
+ */
+
+/**
+ * Import text file into window or its toolbar
+ *
+ * \param g gui window containing textarea
+ * \param filename pathname of file to be imported
+ * \param toolbar true iff imported to toolbar rather than main window
+ * \return true iff successful
+ */
+
+bool ro_gui_window_import_text(struct gui_window *g, const char *filename,
+ bool toolbar)
+{
+ fileswitch_object_type obj_type;
+ os_error *error;
+ char *buf, *utf8_buf;
+ int size;
+ utf8_convert_ret ret;
+
+ error = xosfile_read_stamped(filename, &obj_type, NULL, NULL,
+ &size, NULL, NULL);
+ if (error) {
+ LOG(("xosfile_read_stamped: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("FileError", error->errmess);
+ return true; /* was for us, but it didn't work! */
+ }
+
+ buf = malloc(size);
+ if (!buf) {
+ warn_user("NoMemory", NULL);
+ return true;
+ }
+
+ error = xosfile_load_stamped(filename, (byte*)buf,
+ NULL, NULL, NULL, NULL, NULL);
+ if (error) {
+ LOG(("xosfile_load_stamped: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("LoadError", error->errmess);
+ free(buf);
+ return true;
+ }
+
+ ret = utf8_from_local_encoding(buf, size, &utf8_buf);
+ if (ret != UTF8_CONVERT_OK) {
+ /* bad encoding shouldn't happen */
+ assert(ret != UTF8_CONVERT_BADENC);
+ LOG(("utf8_from_local_encoding failed"));
+ free(buf);
+ warn_user("NoMemory", NULL);
+ return true;
+ }
+ size = strlen(utf8_buf);
+
+ if (toolbar) {
+ const char *ep = utf8_buf + size;
+ const char *sp;
+ char *p = utf8_buf;
+
+ /* skip leading whitespace */
+ while (isspace(*p)) p++;
+
+ sp = p;
+ while (*p && *p != '\r' && *p != '\n')
+ p += utf8_next(p, ep - p, 0);
+ *p = '\0';
+
+ if (p > sp)
+ ro_gui_window_launch_url(g, sp);
+ }
+ else
+ browser_window_paste_text(g->bw, utf8_buf, size, true);
+
+ free(buf);
+ free(utf8_buf);
+ return true;
+}
+
+
+/**
* Clones a browser window's options.
*
* \param new_bw the new browser window
@@ -2941,7 +4703,8 @@ void ro_gui_window_process_reformats(void)
*/
void ro_gui_window_clone_options(struct browser_window *new_bw,
- struct browser_window *old_bw) {
+ struct browser_window *old_bw)
+{
struct gui_window *old_gui = NULL;
struct gui_window *new_gui;
@@ -2968,15 +4731,23 @@ void ro_gui_window_clone_options(struct browser_window *new_bw,
/* Set up the toolbar
*/
if (new_gui->toolbar) {
- new_gui->toolbar->display_buttons = option_toolbar_show_buttons;
- new_gui->toolbar->display_url = option_toolbar_show_address;
- new_gui->toolbar->display_throbber = option_toolbar_show_throbber;
+ ro_toolbar_set_display_buttons(new_gui->toolbar,
+ option_toolbar_show_buttons);
+ ro_toolbar_set_display_url(new_gui->toolbar,
+ option_toolbar_show_address);
+ ro_toolbar_set_display_throbber(new_gui->toolbar,
+ option_toolbar_show_throbber);
if ((old_gui) && (old_gui->toolbar)) {
- new_gui->toolbar->display_buttons = old_gui->toolbar->display_buttons;
- new_gui->toolbar->display_url = old_gui->toolbar->display_url;
- new_gui->toolbar->display_throbber = old_gui->toolbar->display_throbber;
- new_gui->toolbar->reformat_buttons = true;
- ro_gui_theme_process_toolbar(new_gui->toolbar, -1);
+ ro_toolbar_set_display_buttons(new_gui->toolbar,
+ ro_toolbar_get_display_buttons(
+ old_gui->toolbar));
+ ro_toolbar_set_display_url(new_gui->toolbar,
+ ro_toolbar_get_display_url(
+ old_gui->toolbar));
+ ro_toolbar_set_display_throbber(new_gui->toolbar,
+ ro_toolbar_get_display_throbber(
+ old_gui->toolbar));
+ ro_toolbar_process(new_gui->toolbar, -1, true);
}
}
}
@@ -2988,7 +4759,8 @@ void ro_gui_window_clone_options(struct browser_window *new_bw,
* \param bw the browser window to read options from
*/
-void ro_gui_window_default_options(struct browser_window *bw) {
+void ro_gui_window_default_options(struct browser_window *bw)
+{
struct gui_window *gui;
assert(bw);
@@ -3006,33 +4778,277 @@ void ro_gui_window_default_options(struct browser_window *bw) {
/* Set up the toolbar
*/
- if (gui->toolbar) {
- option_toolbar_show_buttons = gui->toolbar->display_buttons;
- option_toolbar_show_address = gui->toolbar->display_url;
- option_toolbar_show_throbber = gui->toolbar->display_throbber;
+ if (gui->toolbar != NULL) {
+ option_toolbar_show_buttons =
+ ro_toolbar_get_display_buttons(gui->toolbar);
+ option_toolbar_show_address =
+ ro_toolbar_get_display_url(gui->toolbar);
+ option_toolbar_show_throbber =
+ ro_toolbar_get_display_throbber(gui->toolbar);
}
- if (gui->status_bar)
- option_toolbar_status_width = ro_gui_status_bar_get_width(gui->status_bar);
+ if (gui->status_bar != NULL)
+ option_toolbar_status_width =
+ ro_gui_status_bar_get_width(gui->status_bar);
}
+/*
+ * Custom Menu Support
+ */
+/**
+ * Prepare or reprepare a form select menu, setting up the menu handle
+ * global in the process.
+ *
+ * \param *bw The browser window to contain the menu.
+ * \param *control The form control needing a menu.
+ * \return true if the menu is OK to be opened; else false.
+ */
+
+bool ro_gui_window_prepare_form_select_menu(struct browser_window *bw,
+ struct form_control *control)
+{
+ unsigned int i, entries;
+ char *text_convert, *temp;
+ struct form_option *option;
+ bool reopen = true;
+ utf8_convert_ret err;
+
+ assert(control);
+
+ for (entries = 0, option = control->data.select.items; option;
+ option = option->next)
+ entries++;
+ if (entries == 0) {
+ ro_gui_menu_closed();
+ return false;
+ }
+
+ if ((gui_form_select_menu) && (control != gui_form_select_control)) {
+ for (i = 0; ; i++) {
+ free(gui_form_select_menu->entries[i].data.
+ indirected_text.text);
+ if (gui_form_select_menu->entries[i].menu_flags &
+ wimp_MENU_LAST)
+ break;
+ }
+ free(gui_form_select_menu->title_data.indirected_text.text);
+ free(gui_form_select_menu);
+ gui_form_select_menu = 0;
+ }
+
+ if (!gui_form_select_menu) {
+ reopen = false;
+ gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries));
+ if (!gui_form_select_menu) {
+ warn_user("NoMemory", 0);
+ ro_gui_menu_closed();
+ return false;
+ }
+ err = utf8_to_local_encoding(messages_get("SelectMenu"), 0,
+ &text_convert);
+ if (err != UTF8_CONVERT_OK) {
+ /* badenc should never happen */
+ assert(err != UTF8_CONVERT_BADENC);
+ LOG(("utf8_to_local_encoding failed"));
+ warn_user("NoMemory", 0);
+ ro_gui_menu_closed();
+ return false;
+ }
+ gui_form_select_menu->title_data.indirected_text.text =
+ text_convert;
+ ro_gui_menu_init_structure(gui_form_select_menu, entries);
+ }
+
+ for (i = 0, option = control->data.select.items; option;
+ i++, option = option->next) {
+ gui_form_select_menu->entries[i].menu_flags = 0;
+ if (option->selected)
+ gui_form_select_menu->entries[i].menu_flags =
+ wimp_MENU_TICKED;
+ if (!reopen) {
+
+ /* convert spaces to hard spaces to stop things
+ * like 'Go Home' being treated as if 'Home' is a
+ * keyboard shortcut and right aligned in the menu.
+ */
+
+ temp = cnv_space2nbsp(option->text);
+ if (!temp) {
+ LOG(("cnv_space2nbsp failed"));
+ warn_user("NoMemory", 0);
+ ro_gui_menu_closed();
+ return false;
+ }
+
+ err = utf8_to_local_encoding(temp,
+ 0, &text_convert);
+ if (err != UTF8_CONVERT_OK) {
+ /* A bad encoding should never happen,
+ * so assert this */
+ assert(err != UTF8_CONVERT_BADENC);
+ LOG(("utf8_to_enc failed"));
+ warn_user("NoMemory", 0);
+ ro_gui_menu_closed();
+ return false;
+ }
+
+ free(temp);
+
+ gui_form_select_menu->entries[i].data.indirected_text.text =
+ text_convert;
+ gui_form_select_menu->entries[i].data.indirected_text.size =
+ strlen(gui_form_select_menu->entries[i].
+ data.indirected_text.text) + 1;
+ }
+ }
+
+ gui_form_select_menu->entries[0].menu_flags |=
+ wimp_MENU_TITLE_INDIRECTED;
+ gui_form_select_menu->entries[i - 1].menu_flags |= wimp_MENU_LAST;
+
+ return true;
+}
/**
- * Updates the navigation controls for all toolbars;
+ * Process selections from a form select menu, passing them back to the core.
*
- * \param g the gui_window to launch the URL into
- * \param url the URL to launch, or NULL to simply update the suggestion icon
+ * \param *g The browser window affected by the menu.
+ * \param *selection The menu selection.
*/
-void ro_gui_window_prepare_navigate_all(void) {
- struct gui_window *g;
+void ro_gui_window_process_form_select_menu(struct gui_window *g,
+ wimp_selection *selection)
+{
+ assert(g != NULL);
+
+ if (selection->items[0] >= 0)
+ form_select_process_selection(g->bw->current_content,
+ gui_form_select_control,
+ selection->items[0]);
+}
+
+
+/*
+ * Window and Toolbar Lookup
+ */
+
+/**
+ * Convert a RISC OS window handle to a gui_window.
+ *
+ * \param w RISC OS window handle
+ * \return pointer to a structure if found, 0 otherwise
+ */
+
+struct gui_window *ro_gui_window_lookup(wimp_w window)
+{
+ struct gui_window *g;
for (g = window_list; g; g = g->next)
- ro_gui_prepare_navigate(g);
+ if (g->window == window)
+ return g;
+ return 0;
}
/**
+ * Convert a toolbar RISC OS window handle to a gui_window.
+ *
+ * \param w RISC OS window handle of a toolbar
+ * \return pointer to a structure if found, 0 otherwise
+ */
+
+struct gui_window *ro_gui_toolbar_lookup(wimp_w window)
+{
+ struct gui_window *g = NULL;
+ struct toolbar *toolbar;
+ wimp_w parent;
+
+ toolbar = ro_toolbar_window_lookup(window);
+
+ if (toolbar != NULL) {
+ parent = ro_toolbar_get_parent_window(toolbar);
+ g = ro_gui_window_lookup(parent);
+ }
+
+ return g;
+}
+
+
+/*
+ * Core to RISC OS Conversions
+ */
+
+/**
+ * Convert x,y screen co-ordinates into window co-ordinates.
+ *
+ * \param g gui window
+ * \param x x ordinate
+ * \param y y ordinate
+ * \param pos receives position in window co-ordinatates
+ * \return true iff conversion successful
+ */
+
+bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
+ os_coord *pos)
+{
+ wimp_window_state state;
+ os_error *error;
+
+ assert(g);
+
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG(("xwimp_get_window_state: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+ pos->x = (x - (state.visible.x0 - state.xscroll)) / 2 / g->bw->scale;
+ pos->y = ((state.visible.y1 - state.yscroll) - y) / 2 / g->bw->scale;
+ return true;
+}
+
+
+/**
+ * Convert x,y window co-ordinates into screen co-ordinates.
+ *
+ * \param g gui window
+ * \param x x ordinate
+ * \param y y ordinate
+ * \param pos receives position in screen co-ordinatates
+ * \return true iff conversion successful
+ */
+
+bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
+ os_coord *pos)
+{
+ wimp_window_state state;
+ os_error *error;
+
+ assert(g);
+
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG(("xwimp_get_window_state: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+ pos->x = (x * 2 * g->bw->scale) + (state.visible.x0 - state.xscroll);
+ pos->y = (state.visible.y1 - state.yscroll) - (y * 2 * g->bw->scale);
+ return true;
+}
+
+
+/*
+ * Miscellaneous Functions
+ *
+ * \TODO -- These items might well belong elsewhere.
+ */
+
+/**
* Returns the state of the mouse buttons and modifiers keys for a
* mouse action, suitable for passing to the OS-independent
* browser window/ treeview/ etc code.
@@ -3099,6 +5115,7 @@ browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
return state;
}
+
/**
* Returns the state of the mouse buttons and modifiers keys whilst
* dragging, for passing to the OS-independent browser window/ treeview/
@@ -3173,295 +5190,3 @@ bool ro_gui_alt_pressed(void)
return (alt == 0xff);
}
-
-/**
- * Completes scrolling of a browser window
- *
- * \param g gui window
- */
-
-void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag)
-{
- wimp_pointer pointer;
- os_error *error;
- os_coord pos;
-
- gui_current_drag_type = GUI_DRAG_NONE;
- if (!g)
- return;
-
- error = xwimp_drag_box((wimp_drag*)-1);
- if (error) {
- LOG(("xwimp_drag_box: 0x%x : %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
-
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG(("xwimp_get_pointer_info 0x%x : %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
-
- error = xwimpspriteop_set_pointer_shape("ptr_default", 0x31, 0, 0, 0, 0);
- if (error) {
- LOG(("xwimpspriteop_set_pointer_shape: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
-
- if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos))
- browser_window_mouse_drag_end(g->bw,
- ro_gui_mouse_click_state(pointer.buttons,
- wimp_BUTTON_CLICK_DRAG),
- pos.x, pos.y);
-}
-
-
-/**
- * Completes resizing of a browser frame
- *
- * \param g gui window
- */
-
-void ro_gui_window_frame_resize_end(struct gui_window *g, wimp_dragged *drag)
-{
- /* our clean-up is the same as for page scrolling */
- ro_gui_window_scroll_end(g, drag);
-}
-
-/**
- * Import text file into window or its toolbar
- *
- * \param g gui window containing textarea
- * \param filename pathname of file to be imported
- * \param toolbar true iff imported to toolbar rather than main window
- * \return true iff successful
- */
-
-bool ro_gui_window_import_text(struct gui_window *g, const char *filename,
- bool toolbar)
-{
- fileswitch_object_type obj_type;
- os_error *error;
- char *buf, *utf8_buf;
- int size;
- utf8_convert_ret ret;
-
- error = xosfile_read_stamped(filename, &obj_type, NULL, NULL,
- &size, NULL, NULL);
- if (error) {
- LOG(("xosfile_read_stamped: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("FileError", error->errmess);
- return true; /* was for us, but it didn't work! */
- }
-
- buf = malloc(size);
- if (!buf) {
- warn_user("NoMemory", NULL);
- return true;
- }
-
- error = xosfile_load_stamped(filename, (byte*)buf,
- NULL, NULL, NULL, NULL, NULL);
- if (error) {
- LOG(("xosfile_load_stamped: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("LoadError", error->errmess);
- free(buf);
- return true;
- }
-
- ret = utf8_from_local_encoding(buf, size, &utf8_buf);
- if (ret != UTF8_CONVERT_OK) {
- /* bad encoding shouldn't happen */
- assert(ret != UTF8_CONVERT_BADENC);
- LOG(("utf8_from_local_encoding failed"));
- free(buf);
- warn_user("NoMemory", NULL);
- return true;
- }
- size = strlen(utf8_buf);
-
- if (toolbar) {
- const char *ep = utf8_buf + size;
- const char *sp;
- char *p = utf8_buf;
-
- /* skip leading whitespace */
- while (isspace(*p)) p++;
-
- sp = p;
- while (*p && *p != '\r' && *p != '\n')
- p += utf8_next(p, ep - p, 0);
- *p = '\0';
-
- if (p > sp)
- ro_gui_window_launch_url(g, sp);
- }
- else
- browser_window_paste_text(g->bw, utf8_buf, size, true);
-
- free(buf);
- free(utf8_buf);
- return true;
-}
-
-
-/**
- * Window is being iconised. Create a suitable thumbnail sprite
- * (which, sadly, must be in the Wimp sprite pool), and return
- * the sprite name and truncated title to the iconiser
- *
- * \param g the gui window being iconised
- * \param wi the WindowInfo message from the iconiser
- */
-
-void ro_gui_window_iconise(struct gui_window *g,
- wimp_full_message_window_info *wi)
-{
- /* sadly there is no 'legal' way to get the sprite into
- * the Wimp sprite pool other than via a filing system */
- const char *temp_fname = "Pipe:$._tmpfile";
- struct browser_window *bw = g->bw;
- osspriteop_header *overlay = NULL;
- osspriteop_header *sprite_header;
- struct bitmap *bitmap;
- osspriteop_area *area;
- int width = 34, height = 34;
- hlcache_handle *h;
- os_error *error;
- int len, id;
-
- assert(bw);
-
- h = bw->current_content;
- if (!h) return;
-
- /* if an overlay sprite is defined, locate it and gets its dimensions
- * so that we can produce a thumbnail with the same dimensions */
- if (!ro_gui_wimp_get_sprite("ic_netsfxx", &overlay)) {
- error = xosspriteop_read_sprite_info(osspriteop_PTR,
- (osspriteop_area *)0x100,
- (osspriteop_id)overlay, &width, &height, NULL,
- NULL);
- if (error) {
- LOG(("xosspriteop_read_sprite_info: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("MiscError", error->errmess);
- overlay = NULL;
- }
- else if (sprite_bpp(overlay) != 8) {
- LOG(("overlay sprite is not 8bpp"));
- overlay = NULL;
- }
- }
-
- /* create the thumbnail sprite */
- bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE |
- BITMAP_CLEAR_MEMORY);
- if (!bitmap) {
- LOG(("Thumbnail initialisation failed."));
- return;
- }
- thumbnail_create(h, bitmap, NULL);
- if (overlay)
- bitmap_overlay_sprite(bitmap, overlay);
- area = thumbnail_convert_8bpp(bitmap);
- bitmap_destroy(bitmap);
- if (!area) {
- LOG(("Thumbnail conversion failed."));
- return;
- }
-
- /* choose a suitable sprite name */
- id = 0;
- while (iconise_used[id])
- if ((unsigned)++id >= NOF_ELEMENTS(iconise_used)) {
- id = iconise_next;
- if ((unsigned)++iconise_next >=
- NOF_ELEMENTS(iconise_used))
- iconise_next = 0;
- break;
- }
-
- sprite_header = (osspriteop_header *)(area + 1);
- len = sprintf(sprite_header->name, "ic_netsf%.2d", id);
-
- error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
- area, temp_fname);
- if (error) {
- LOG(("xosspriteop_save_sprite_file: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("MiscError", error->errmess);
- free(area);
- return;
- }
-
- error = xwimpspriteop_merge_sprite_file(temp_fname);
- if (error) {
- LOG(("xwimpspriteop_merge_sprite_file: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- remove(temp_fname);
- free(area);
- return;
- }
-
- memcpy(wi->sprite_name, sprite_header->name + 3, len - 2); /* inc NUL */
- strncpy(wi->title, g->title, sizeof(wi->title));
- wi->title[sizeof(wi->title) - 1] = '\0';
-
- if (wimptextop_string_width(wi->title, 0) > 182) {
- /* work around bug in Pinboard where it will fail to display
- * the icon if the text is very wide */
- if (strlen(wi->title) > 10)
- wi->title[10] = '\0'; /* pinboard does this anyway */
- while (wimptextop_string_width(wi->title, 0) > 182)
- wi->title[strlen(wi->title) - 1] = '\0';
- }
-
- wi->size = sizeof(wimp_full_message_window_info);
- wi->your_ref = wi->my_ref;
- error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)wi,
- wi->sender);
- if (error) {
- LOG(("xwimp_send_message: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
- else {
- g->iconise_icon = id;
- iconise_used[id] = true;
- }
-
- free(area);
-}
-
-
-/**
- * Navigate up one level
- *
- * \param g the gui_window to open the parent link in
- * \param url the URL to open the parent of
- */
-bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) {
- char *parent;
- url_func_result res;
- bool compare;
-
- if (!g || (!g->bw))
- return false;
-
- res = url_parent(url, &parent);
- if (res == URL_FUNC_OK) {
- res = url_compare(url, parent, false, &compare);
- if ((res == URL_FUNC_OK) && !compare)
- browser_window_go(g->bw, parent, 0, true);
- free(parent);
- }
- return true;
-}