summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2017-06-11 10:46:18 (GMT)
committer Vincent Sanders <vince@kyllikki.org>2017-06-11 10:46:50 (GMT)
commit449e760d7162b62790b3cc39692a597d5ace4428 (patch)
tree4bbaa652b232fccba1811370a6c9941309e4b28e
parentee749f2b11276533f3c7fd139bb96f69103ae08f (diff)
downloadnetsurf-449e760d7162b62790b3cc39692a597d5ace4428.tar.gz
netsurf-449e760d7162b62790b3cc39692a597d5ace4428.tar.bz2
rationalise the RISC OS browser window implementation
-rw-r--r--frontends/riscos/corewindow.c1
-rw-r--r--frontends/riscos/dialog.c1
-rw-r--r--frontends/riscos/gui.h29
-rw-r--r--frontends/riscos/save.c1
-rw-r--r--frontends/riscos/textselection.c1
-rw-r--r--frontends/riscos/url_complete.c1
-rw-r--r--frontends/riscos/window.c5841
-rw-r--r--frontends/riscos/window.h193
8 files changed, 3078 insertions, 2990 deletions
diff --git a/frontends/riscos/corewindow.c b/frontends/riscos/corewindow.c
index a885977..77dd1c3 100644
--- a/frontends/riscos/corewindow.c
+++ b/frontends/riscos/corewindow.c
@@ -42,6 +42,7 @@
#include "riscos/wimp_event.h"
#include "riscos/dialog.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/toolbar.h"
#include "riscos/mouse.h"
#include "riscos/corewindow.h"
diff --git a/frontends/riscos/dialog.c b/frontends/riscos/dialog.c
index 7a0197c..6414778 100644
--- a/frontends/riscos/dialog.c
+++ b/frontends/riscos/dialog.c
@@ -47,6 +47,7 @@
#include "riscos/local_history.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/save.h"
diff --git a/frontends/riscos/gui.h b/frontends/riscos/gui.h
index 35be4e1..49a8ba4 100644
--- a/frontends/riscos/gui.h
+++ b/frontends/riscos/gui.h
@@ -139,35 +139,6 @@ void ro_gui_401login_init(void);
void gui_401login_open(struct nsurl *url, const char *realm,
nserror (*cb)(bool proceed, void *pw), void *cbpw);
-/* in window.c */
-void ro_gui_window_set_scale(struct gui_window *g, float scale);
-bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message);
-void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data);
-void ro_gui_window_iconise(struct gui_window *g,
- wimp_full_message_window_info *wi);
-bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message);
-void ro_gui_window_redraw_all(void);
-void ro_gui_window_update_boxes(void);
-void ro_gui_window_quit(void);
-/* void ro_gui_window_close_all(void); */
-#define ro_gui_window_close_all ro_gui_window_quit /* no need for a separate fn */
-void ro_gui_throb(void);
-void ro_gui_window_default_options(struct gui_window *gui);
-struct gui_window *ro_gui_window_lookup(wimp_w window);
-struct gui_window *ro_gui_toolbar_lookup(wimp_w window);
-bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
- os_coord *pos);
-bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
- os_coord *pos);
-enum browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
- wimp_icon_flags type);
-enum browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
- wimp_icon_flags type);
-bool ro_gui_shift_pressed(void);
-bool ro_gui_ctrl_pressed(void);
-bool ro_gui_alt_pressed(void);
-void gui_window_set_pointer(struct gui_window *g, enum gui_pointer_shape shape);
-
/* in schedule.c */
extern bool sched_active;
extern os_t sched_time;
diff --git a/frontends/riscos/save.c b/frontends/riscos/save.c
index 37474b8..bed0f5d 100644
--- a/frontends/riscos/save.c
+++ b/frontends/riscos/save.c
@@ -56,6 +56,7 @@
#include "riscos/bitmap.h"
#include "riscos/dialog.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/menus.h"
#include "riscos/message.h"
#include "riscos/mouse.h"
diff --git a/frontends/riscos/textselection.c b/frontends/riscos/textselection.c
index bce3575..5a430c0 100644
--- a/frontends/riscos/textselection.c
+++ b/frontends/riscos/textselection.c
@@ -36,6 +36,7 @@
#include "netsurf/browser_window.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/menus.h"
#include "riscos/message.h"
#include "riscos/mouse.h"
diff --git a/frontends/riscos/url_complete.c b/frontends/riscos/url_complete.c
index 3ca9be4..16c6e3a 100644
--- a/frontends/riscos/url_complete.c
+++ b/frontends/riscos/url_complete.c
@@ -36,6 +36,7 @@
#include "riscos/global_history.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/mouse.h"
#include "riscos/toolbar.h"
#include "riscos/url_complete.h"
diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c
index c827106..6dbcc32 100644
--- a/frontends/riscos/window.c
+++ b/frontends/riscos/window.c
@@ -91,70 +91,6 @@
#include "riscos/ucstables.h"
#include "riscos/filetype.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_scroll(wimp_scroll *scroll);
-static void ro_gui_window_pointer_entering(wimp_entering *entering);
-static void ro_gui_window_track_end(wimp_leaving *leaving, void *data);
-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 bool ro_gui_window_toolbar_keypress(void *data, wimp_key *key);
-static bool 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_scroll_end(wimp_dragged *drag, void *data);
-
-static void ro_gui_window_scroll_action(struct gui_window *g,
- int scroll_x, int scroll_y);
-
-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(struct hlcache_handle *h,
- bool *export_draw, bool *export_sprite);
-static void ro_gui_window_prepare_pageinfo(struct gui_window *g);
-static void ro_gui_window_prepare_objectinfo(struct hlcache_handle *object,
- nsurl *target_url);
-
-static void ro_gui_window_launch_url(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_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_remove_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);
-static void ro_gui_window_clone_options(
- struct gui_window *new_gui,
- struct gui_window *old_gui);
-
-static bool ro_gui_window_prepare_form_select_menu(struct gui_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
@@ -210,7 +146,8 @@ struct ro_gui_pointer_entry {
int yactive;
};
-/** Map from gui_pointer_shape to pointer sprite data. Must be ordered as
+/**
+ * Map from gui_pointer_shape to pointer sprite data. Must be ordered as
* enum gui_pointer_shape. */
struct ro_gui_pointer_entry ro_gui_pointer_table[] = {
{ true, "ptr_default", 0, 0 },
@@ -247,143 +184,22 @@ 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.HelpCredits", HELP_OPEN_CREDITS, 0 },
- { "_Help.HelpLicence", HELP_OPEN_LICENCE, 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
- */
/**
* Place the caret in a browser window.
*
- * \param g window with caret
- * \param x coordinates of caret
- * \param y coordinates of caret
- * \param height height of caret
- * \param clip clip rectangle, or NULL if none
+ * \param g window with caret
+ * \param x coordinates of caret
+ * \param y coordinates of caret
+ * \param height height of caret
+ * \param clip clip rectangle, or NULL if none
*/
-
-static void gui_window_place_caret(struct gui_window *g, int x, int y, int height,
- const struct rect *clip)
+static void
+gui_window_place_caret(struct gui_window *g,
+ int x,
+ int y,
+ int height,
+ const struct rect *clip)
{
os_error *error;
@@ -395,552 +211,229 @@ static void gui_window_place_caret(struct gui_window *g, int x, int y, int heigh
}
}
+
/**
- * Create and open a new browser window.
+ * Updates a windows extent.
*
- * \param bw bw to create gui_window for
- * \param existing an existing gui_window, may be NULL
- * \param flags flags for gui window creation
- * \return gui window, or NULL on error
+ * \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
*/
-
-static struct gui_window *gui_window_create(struct browser_window *bw,
- struct gui_window *existing,
- gui_window_create_flags flags)
+static void gui_window_set_extent(struct gui_window *g, int width, int height)
{
- int screen_width, screen_height;
- static int window_count = 2;
- wimp_window window;
+ int screen_width;
+ int toolbar_height = 0;
wimp_window_state state;
os_error *error;
- bool open_centred = true;
- struct gui_window *g;
- g = malloc(sizeof *g);
- if (!g) {
- ro_warn_user("NoMemory", 0);
- return 0;
+ if (g->toolbar) {
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
}
- g->bw = bw;
- g->toolbar = 0;
- g->status_bar = 0;
- g->old_width = 0;
- g->old_height = 0;
- g->update_extent = true;
- g->active = false;
- strcpy(g->title, "NetSurf");
- g->iconise_icon = -1;
- g->scale = browser_window_get_scale(bw);
- /* Set the window position */
- if (existing != NULL &&
- flags & GW_CREATE_CLONE &&
- nsoption_bool(window_size_clone)) {
- state.w = existing->window;
+ /* 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);
ro_warn_user("WimpError", error->errmess);
+ return;
}
- window.visible.x0 = state.visible.x0;
- window.visible.x1 = state.visible.x1;
- window.visible.y0 = state.visible.y0 - 48;
- window.visible.y1 = state.visible.y1 - 48;
- open_centred = false;
- } else {
- int win_width, win_height;
- ro_gui_screen_size(&screen_width, &screen_height);
-
- /* Check if we have a preferred position */
- if ((nsoption_int(window_screen_width) != 0) &&
- (nsoption_int(window_screen_height) != 0)) {
- win_width = (nsoption_int(window_width) *
- screen_width) /
- nsoption_int(window_screen_width);
- win_height = (nsoption_int(window_height) *
- screen_height) /
- nsoption_int(window_screen_height);
- window.visible.x0 = (nsoption_int(window_x) *
- screen_width) /
- nsoption_int(window_screen_width);
- window.visible.y0 = (nsoption_int(window_y) *
- screen_height) /
- nsoption_int(window_screen_height);
- if (nsoption_bool(window_stagger)) {
- window.visible.y0 += 96 -
- (48 * (window_count % 5));
- }
- open_centred = false;
- if (win_width < 100)
- win_width = 100;
- if (win_height < 100)
- win_height = 100;
- } else {
-
- /* Base how we define the window height/width
- on the compile time options set */
- win_width = screen_width * 3 / 4;
- if (1600 < win_width)
- win_width = 1600;
- win_height = win_width * 3 / 4;
-
- window.visible.x0 = (screen_width - win_width) / 2;
- window.visible.y0 = ((screen_height - win_height) / 2) +
- 96 - (48 * (window_count % 5));
+ if (width == -1)
+ width = state.visible.x1 - state.visible.x0;
+ if (height == -1) {
+ height = state.visible.y1 - state.visible.y0;
+ height -= toolbar_height;
}
- window.visible.x1 = window.visible.x0 + win_width;
- window.visible.y1 = window.visible.y0 + win_height;
}
- /* General flags for a non-movable, non-resizable, no-title bar window */
- window.xscroll = 0;
- window.yscroll = 0;
- window.next = wimp_TOP;
- window.flags = wimp_WINDOW_MOVEABLE |
- wimp_WINDOW_NEW_FORMAT |
- wimp_WINDOW_VSCROLL |
- wimp_WINDOW_HSCROLL |
- wimp_WINDOW_IGNORE_XEXTENT |
- wimp_WINDOW_IGNORE_YEXTENT |
- wimp_WINDOW_SCROLL_REPEAT;
- window.title_fg = wimp_COLOUR_BLACK;
- window.title_bg = wimp_COLOUR_LIGHT_GREY;
- window.work_fg = wimp_COLOUR_LIGHT_GREY;
- window.work_bg = wimp_COLOUR_TRANSPARENT;
- window.scroll_outer = wimp_COLOUR_DARK_GREY;
- window.scroll_inner = wimp_COLOUR_MID_LIGHT_GREY;
- window.highlight_bg = wimp_COLOUR_CREAM;
- window.extra_flags = wimp_WINDOW_USE_EXTENDED_SCROLL_REQUEST |
- wimp_WINDOW_GIVE_SHADED_ICON_INFO;
- window.extent.x0 = 0;
- window.extent.y0 = -(window.visible.y1 - window.visible.y0);
- window.extent.x1 = window.visible.x1 - window.visible.x0;
- window.extent.y1 = 0;
- window.title_flags = wimp_ICON_TEXT |
- wimp_ICON_INDIRECTED |
- wimp_ICON_HCENTRED;
- window.work_flags = wimp_BUTTON_DOUBLE_CLICK_DRAG <<
- wimp_ICON_BUTTON_TYPE_SHIFT;
- window.sprite_area = wimpspriteop_AREA;
- window.xmin = 1;
- window.ymin = 1;
- window.title_data.indirected_text.text = g->title;
- window.title_data.indirected_text.validation = (char *) -1;
- window.title_data.indirected_text.size = 255;
- window.icon_count = 0;
-
- /* Add in flags */
- window.flags |= wimp_WINDOW_SIZE_ICON |
- wimp_WINDOW_BACK_ICON |
- wimp_WINDOW_CLOSE_ICON |
- wimp_WINDOW_TITLE_ICON |
- wimp_WINDOW_TOGGLE_ICON;
-
- if (open_centred) {
- int scroll_width = ro_get_vscroll_width(NULL);
- window.visible.x0 -= scroll_width;
- }
-
- error = xwimp_create_window(&window, &g->window);
- if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- free(g);
- return 0;
+ /* 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 (browser_window_is_frameset(g->bw)) {
+ 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);
}
-
- /* Link into window list */
- g->prev = 0;
- g->next = window_list;
- if (window_list)
- window_list->prev = g;
- window_list = g;
- window_count++;
-
- /* Add in a toolbar and status bar */
- g->status_bar = ro_gui_status_bar_create(g->window,
- nsoption_int(toolbar_status_size));
- 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,
- nsoption_charp(toolbar_browser));
- ro_toolbar_add_url(g->toolbar);
- ro_toolbar_add_throbber(g->toolbar);
- ro_toolbar_rebuild(g->toolbar);
+ if (browser_window_has_content(g->bw)) {
+ int w, h;
+ browser_window_get_extents(g->bw, true, &w, &h);
+ width = max(width, w * 2);
+ height = max(height, h * 2);
}
-
- /* 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_scroll_window(g->window, ro_gui_window_scroll);
- ro_gui_wimp_event_register_pointer_entering_window(g->window, ro_gui_window_pointer_entering);
- ro_gui_wimp_event_register_keypress(g->window, 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 */
- ro_gui_window_clone_options(g, existing);
- ro_gui_window_update_toolbar_buttons(g);
-
- /* Open the window at the top of the stack */
- state.w = g->window;
- error = xwimp_get_window_state(&state);
+ os_box extent = { 0, -height, width, toolbar_height };
+ error = xwimp_set_extent(g->window, &extent);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
- return g;
+ return;
}
-
- state.next = wimp_TOP;
-
- ro_gui_window_open(PTR_WIMP_OPEN(&state));
-
- /* Claim the caret */
- if (ro_toolbar_take_caret(g->toolbar))
- ro_gui_url_complete_start(g->toolbar);
- else
- gui_window_place_caret(g, -100, -100, 0, NULL);
-
- return g;
}
/**
- * Close a browser window and free any related resources.
+ * Open a window
*
- * \param g gui_window to destroy
+ * opens a window using the given wimp_open, handling toolbars and resizing.
+ *
+ * \param open the window open event information
*/
-
-static void gui_window_destroy(struct gui_window *g)
+static void ro_gui_window_open(wimp_open *open)
{
+ struct gui_window *g;
+ int width = open->visible.x1 - open->visible.x0;
+ int height = open->visible.y1 - open->visible.y0;
+ browser_scrolling h_scroll;
+ browser_scrolling v_scroll;
+ int toolbar_height = 0;
+ float new_scale = 0;
+ wimp_window_state state;
os_error *error;
- wimp_w w;
-
- assert(g);
-
- /* stop any tracking */
- ro_mouse_kill(g);
+ wimp_w parent;
+ bits linkage;
+ bool have_content;
- /* remove from list */
- if (g->prev)
- g->prev->next = g->next;
- else
- window_list = g->next;
- if (g->next)
- g->next->prev = g->prev;
+ g = (struct gui_window *)ro_gui_wimp_event_get_user_data(open->w);
- /* destroy toolbar */
- if (g->toolbar)
- ro_toolbar_destroy(g->toolbar);
- if (g->status_bar)
- ro_gui_status_bar_destroy(g->status_bar);
+ if (open->next == wimp_TOP && g->iconise_icon >= 0) {
+ /* window is no longer iconised, release its sprite number */
+ iconise_used[g->iconise_icon] = false;
+ g->iconise_icon = -1;
+ }
- w = g->window;
- ro_gui_url_complete_close();
- ro_gui_dialog_close_persistent(w);
- if (current_menu_window == w)
- ro_gui_menu_destroy();
- ro_gui_window_remove_update_boxes(g);
+ have_content = browser_window_has_content(g->bw);
- /* delete window */
- error = xwimp_delete_window(w);
+ /* get the current flags/nesting state */
+ state.w = g->window;
+ error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage);
if (error) {
- LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
+ LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
+ return;
}
- ro_gui_wimp_event_finalise(w);
- free(g);
-}
-
-
-/**
- * Set the title of a browser window.
- *
- * \param g gui_window to update
- * \param title new window title, copied
- */
-
-static void gui_window_set_title(struct gui_window *g, const char *title)
-{
- assert(g);
- assert(title);
-
- if (g->scale != 1.0) {
- int scale_disp = g->scale * 100;
-
- if (ABS((float)scale_disp - g->scale * 100) >= 0.05)
- snprintf(g->title, sizeof g->title, "%s (%.1f%%)",
- title, g->scale * 100);
- else
- snprintf(g->title, sizeof g->title, "%s (%i%%)",
- title, scale_disp);
- } else {
- strncpy(g->title, title, sizeof g->title);
- }
+ /* account for toolbar height, if present */
+ if (g->toolbar)
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
+ height -= toolbar_height;
- ro_gui_set_window_title(g->window, g->title);
-}
+ /* work with the state from now on so we can modify flags */
+ state.visible = open->visible;
+ state.xscroll = open->xscroll;
+ state.yscroll = open->yscroll;
+ state.next = open->next;
-/* exported interface documented in riscos/window.h */
-nserror ro_gui_window_invalidate_area(struct gui_window *g,
- const struct rect *rect)
-{
- bool use_buffer;
- int x0, y0, x1, y1;
- struct update_box *cur;
- wimp_window_info info;
- os_error *error;
+ browser_window_get_scrollbar_type(g->bw, &h_scroll, &v_scroll);
- assert(g);
+ /* handle 'auto' scroll bars' and non-fitting scrollbar removal */
+ if ((h_scroll != BW_SCROLLING_NO) && (v_scroll != BW_SCROLLING_NO)) {
+ int size;
- if (rect == NULL) {
- info.w = g->window;
- error = xwimp_get_window_info_header_only(&info);
- if (error) {
- LOG("xwimp_get_window_info_header_only: 0x%x: %s",
- error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return NSERROR_INVALID;
- }
+ /* windows lose scrollbars when containing a frameset */
+ bool no_hscroll = false;
+ bool no_vscroll = browser_window_is_frameset(g->bw);
- error = xwimp_force_redraw(g->window,
- info.extent.x0, info.extent.y0,
- info.extent.x1, info.extent.y1);
- if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s",
- error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return NSERROR_INVALID;
+ /* hscroll */
+ size = ro_get_hscroll_height(NULL);
+ size -= 2; /* 1px border on both sides */
+ if (!no_hscroll) {
+ if (!(state.flags & wimp_WINDOW_HSCROLL)) {
+ height -= size;
+ state.visible.y0 += size;
+ if (have_content) {
+ browser_window_schedule_reformat(g->bw);
+ }
+ }
+ state.flags |= wimp_WINDOW_HSCROLL;
+ } else {
+ if (state.flags & wimp_WINDOW_HSCROLL) {
+ height += size;
+ state.visible.y0 -= size;
+ if (have_content) {
+ browser_window_schedule_reformat(g->bw);
+ }
+ }
+ state.flags &= ~wimp_WINDOW_HSCROLL;
}
- return NSERROR_OK;
- }
- x0 = floorf(rect->x0 * 2 * g->scale);
- y0 = -ceilf(rect->y1 * 2 * g->scale);
- x1 = ceilf(rect->x1 * 2 * g->scale) + 1;
- y1 = -floorf(rect->y0 * 2 * g->scale) + 1;
- use_buffer =
- (g->option.buffer_everything || g->option.buffer_animations);
-
- /* try to optimise buffered redraws */
- if (use_buffer) {
- for (cur = pending_updates; cur != NULL; cur = cur->next) {
- if ((cur->g != g) || (!cur->use_buffer)) {
- continue;
+ /* vscroll */
+ size = ro_get_vscroll_width(NULL);
+ size -= 2; /* 1px border on both sides */
+ if (!no_vscroll) {
+ if (!(state.flags & wimp_WINDOW_VSCROLL)) {
+ width -= size;
+ state.visible.x1 -= size;
+ if (have_content) {
+ browser_window_schedule_reformat(g->bw);
+ }
}
- if ((((cur->x0 - x1) < MARGIN) ||
- ((cur->x1 - x0) < MARGIN)) &&
- (((cur->y0 - y1) < MARGIN) ||
- ((cur->y1 - y0) < MARGIN))) {
- cur->x0 = min(cur->x0, x0);
- cur->y0 = min(cur->y0, y0);
- cur->x1 = max(cur->x1, x1);
- cur->y1 = max(cur->y1, y1);
- return NSERROR_OK;
+ state.flags |= wimp_WINDOW_VSCROLL;
+ } else {
+ if (state.flags & wimp_WINDOW_VSCROLL) {
+ width += size;
+ state.visible.x1 += size;
+ if (have_content) {
+ browser_window_schedule_reformat(g->bw);
+ }
}
+ state.flags &= ~wimp_WINDOW_VSCROLL;
}
}
- cur = malloc(sizeof(struct update_box));
- if (!cur) {
- LOG("No memory for malloc.");
- return NSERROR_NOMEM;
- }
-
- cur->x0 = x0;
- cur->y0 = y0;
- cur->x1 = x1;
- cur->y1 = y1;
- cur->next = pending_updates;
- pending_updates = cur;
- cur->g = g;
- cur->use_buffer = use_buffer;
-
- return NSERROR_OK;
-}
-
-
-/**
- * Get the scroll position of a browser window.
- *
- * \param g gui_window
- * \param sx receives x ordinate of point at top-left of window
- * \param sy receives y ordinate of point at top-left of window
- * \return true iff successful
- */
-static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
-{
- wimp_window_state state;
- os_error *error;
- int toolbar_height = 0;
-
- 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);
- ro_warn_user("WimpError", error->errmess);
- return false;
+ /* reformat or change extent if necessary */
+ if (have_content &&
+ (g->old_width != width || g->old_height != height)) {
+ /* Ctrl-resize of a top-level window scales the content size */
+ if ((g->old_width > 0) && (g->old_width != width) &&
+ (ro_gui_ctrl_pressed()))
+ new_scale = (g->scale * width) / g->old_width;
+ browser_window_schedule_reformat(g->bw);
+ }
+ if (g->update_extent || g->old_width != width ||
+ g->old_height != height) {
+ g->old_width = width;
+ g->old_height = height;
+ g->update_extent = false;
+ gui_window_set_extent(g, width, height);
}
- if (g->toolbar)
- toolbar_height = ro_toolbar_full_height(g->toolbar);
- *sx = state.xscroll / (2 * g->scale);
- *sy = -(state.yscroll - toolbar_height) / (2 * g->scale);
- return true;
-}
-
+ /* first resize stops any flickering by making the URL window on top */
+ ro_gui_url_complete_resize(g->toolbar, PTR_WIMP_OPEN(&state));
-/**
- * Set the scroll position of a riscos browser window.
- *
- * Scrolls the viewport to ensure the specified rectangle of the
- * content is shown.
- *
- * \param g gui window to scroll
- * \param rect The rectangle to ensure is shown.
- * \return NSERROR_OK on success or apropriate error code.
- */
-static nserror
-gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
-{
- wimp_window_state state;
- os_error *error;
- int toolbar_height = 0;
+ /* Windows containing framesets can only be scrolled via the core, which
+ * is implementing frame scrollbars itself. The x and y offsets are
+ * therefore fixed.
+ */
- assert(g);
+ if (browser_window_is_frameset(g->bw)) {
+ state.xscroll = 0;
+ state.yscroll = toolbar_height;
+ }
- state.w = g->window;
- error = xwimp_get_window_state(&state);
+ error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
- return NSERROR_BAD_PARAMETER;
+ return;
}
+ /* update the toolbar */
+ if (g->status_bar)
+ ro_gui_status_bar_resize(g->status_bar);
if (g->toolbar) {
- toolbar_height = ro_toolbar_full_height(g->toolbar);
- }
-
- if ((rect->x0 == rect->x1) && (rect->y0 == rect->y1)) {
- /* scroll to top */
- state.xscroll = rect->x0 * 2 * g->scale;
- state.yscroll = (-rect->y0 * 2 * g->scale) + toolbar_height;
- } else {
- /* scroll area into view with padding */
- int x0, y0, x1, y1;
- int cx0, cy0, width, height;
- int padding_available;
- int correction;
-
- x0 = rect->x0 * 2 * g->scale;
- y0 = rect->y0 * 2 * g->scale;
- x1 = rect->x1 * 2 * g->scale;
- y1 = rect->y1 * 2 * g->scale;
-
- cx0 = state.xscroll;
- cy0 = -state.yscroll + toolbar_height;
- width = state.visible.x1 - state.visible.x0;
- height = state.visible.y1 - state.visible.y0 - toolbar_height;
-
- /* make sure we're visible */
- correction = (x1 - cx0 - width);
- if (correction > 0) {
- cx0 += correction;
- }
- correction = (y1 - cy0 - height);
- if (correction > 0) {
- cy0 += correction;
- }
- if (x0 < cx0) {
- cx0 = x0;
- }
- if (y0 < cy0) {
- cy0 = y0;
- }
-
- /* try to give a SCROLL_VISIBLE_PADDING border of space around us */
- padding_available = (width - x1 + x0) / 2;
- if (padding_available > 0) {
- if (padding_available > SCROLL_VISIBLE_PADDING) {
- padding_available = SCROLL_VISIBLE_PADDING;
- }
- correction = (cx0 + width - x1);
- if (correction < padding_available) {
- cx0 += padding_available;
- }
- correction = (x0 - cx0);
- if (correction < padding_available) {
- cx0 -= padding_available;
- }
- }
- padding_available = (height - y1 + y0) / 2;
- if (padding_available > 0) {
- if (padding_available > SCROLL_VISIBLE_PADDING) {
- padding_available = SCROLL_VISIBLE_PADDING;
- }
- correction = (cy0 + height - y1);
- if (correction < padding_available) {
- cy0 += padding_available;
- }
- correction = (y0 - cy0);
- if (correction < padding_available) {
- cy0 -= padding_available;
- }
- }
-
- state.xscroll = cx0;
- state.yscroll = -cy0 + toolbar_height;
+ ro_toolbar_process(g->toolbar, -1, false);
+ /* second resize updates to the new URL bar width */
+ ro_gui_url_complete_resize(g->toolbar, open);
}
- ro_gui_window_open(PTR_WIMP_OPEN(&state));
-
- return NSERROR_OK;
-}
-
-/**
- * Find the current dimensions of a browser window's content area.
- *
- * \param gw gui window to measure
- * \param width receives width of window
- * \param height receives height of window
- * \param scaled whether to return scaled values
- */
-static nserror
-gui_window_get_dimensions(struct gui_window *gw,
- int *width, int *height,
- bool scaled)
-{
- /* use the cached window sizes */
- *width = gw->old_width / 2;
- *height = gw->old_height / 2;
-
- if (scaled) {
- *width /= gw->scale;
- *height /= gw->scale;
+ /* set the new scale from a ctrl-resize. this must be done at the end as
+ * it may cause a frameset recalculation based on the new window size.
+ */
+ if (new_scale > 0) {
+ ro_gui_window_set_scale(g, new_scale);
}
- return NSERROR_OK;
}
@@ -948,20 +441,20 @@ gui_window_get_dimensions(struct gui_window *gw,
* 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
*/
-
static void gui_window_update_extent(struct gui_window *g)
{
- os_error *error;
- wimp_window_info info;
+ os_error *error;
+ wimp_window_info info;
assert(g);
info.w = g->window;
error = xwimp_get_window_info_header_only(&info);
if (error) {
- LOG("xwimp_get_window_info_header_only: 0x%x: %s", error->errnum, error->errmess);
+ LOG("xwimp_get_window_info_header_only: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -979,872 +472,736 @@ static void gui_window_update_extent(struct gui_window *g)
/**
- * Set the status bar of a browser window.
+ * Update a window and its toolbar
*
- * \param g gui_window to update
- * \param text new status text
+ * makes a window and toolbar 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.
*/
-
-static void riscos_window_set_status(struct gui_window *g, const char *text)
+static void ro_gui_window_update_theme(void *data, bool ok)
{
- if (g->status_bar)
- ro_gui_status_bar_set_text(g->status_bar, text);
+ 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;
+ }
+ }
}
/**
- * Change mouse pointer shape
+ * 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
*/
+static void ro_gui_window_update_toolbar(void *data)
+{
+ struct gui_window *g = (struct gui_window *) data;
-void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
+ if (g != NULL) {
+ gui_window_update_extent(g);
+ }
+}
+
+
+/**
+ * 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.
+ */
+static void ro_gui_window_update_toolbar_buttons(struct gui_window *g)
{
- static gui_pointer_shape curr_pointer = GUI_POINTER_DEFAULT;
- struct ro_gui_pointer_entry *entry;
- os_error *error;
+ struct browser_window *bw;
+ struct toolbar *toolbar;
- if (shape == curr_pointer)
+ if (g == NULL || g->toolbar == NULL)
return;
- assert(shape < sizeof ro_gui_pointer_table /
- sizeof ro_gui_pointer_table[0]);
+ bw = g->bw;
+ toolbar = g->toolbar;
- entry = &ro_gui_pointer_table[shape];
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_RELOAD,
+ !browser_window_reload_available(bw));
- if (entry->wimp_area) {
- /* pointer in the Wimp's sprite area */
- error = xwimpspriteop_set_pointer_shape(entry->sprite_name,
- 1, entry->xactive, entry->yactive, 0, 0);
- if (error) {
- LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- } else {
- /* pointer in our own sprite area */
- error = xosspriteop_set_pointer_shape(osspriteop_USER_AREA,
- gui_sprites,
- (osspriteop_id) entry->sprite_name,
- 1, entry->xactive, entry->yactive, 0, 0);
- if (error) {
- LOG("xosspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- }
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_STOP,
+ !browser_window_stop_available(bw));
- curr_pointer = shape;
-}
+ 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));
-/* exported function documented in riscos/window.h */
-nserror ro_gui_window_set_url(struct gui_window *g, nsurl *url)
-{
- size_t idn_url_l;
- char *idn_url_s = NULL;
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_UP,
+ !browser_window_up_available(bw));
- if (g->toolbar) {
- if (nsoption_bool(display_decoded_idn) == true) {
- if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK)
- idn_url_s = NULL;
- }
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SEARCH,
+ !browser_window_can_search(bw));
- ro_toolbar_set_url(g->toolbar, idn_url_s ? idn_url_s : nsurl_access(url), true, false);
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SCALE,
+ !browser_window_has_content(bw));
- if (idn_url_s)
- free(idn_url_s);
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_PRINT,
+ !browser_window_has_content(bw));
- ro_gui_url_complete_start(g->toolbar);
- }
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SAVE_SOURCE,
+ !browser_window_has_content(bw));
- return NSERROR_OK;
+ ro_toolbar_update_urlsuggest(toolbar);
}
/**
- * Update the interface to reflect start of page loading.
+ * Add a hotlist entry for a browser window.
*
- * \param g window with start of load
+ * \param g The browser window to act on.
*/
-
-static void gui_window_start_throbber(struct gui_window *g)
+static void ro_gui_window_action_add_bookmark(struct gui_window *g)
{
- 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);
- g->active = true;
-}
-
+ nsurl *url;
+ if (g == NULL || g->bw == NULL || g->toolbar == NULL ||
+ browser_window_has_content(g->bw) == false)
+ return;
-/**
- * Update the interface to reflect page loading stopped.
- *
- * \param g window with start of load
- */
+ url = browser_window_get_url(g->bw);
-static void gui_window_stop_throbber(struct gui_window *g)
-{
- 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);
- g->active = false;
+ ro_gui_hotlist_add_page(url);
+ ro_toolbar_update_hotlist(g->toolbar);
}
+
/**
- * set favicon
+ * Remove a hotlist entry for a browser window.
+ *
+ * \param g The browser window to act on.
*/
-
-static void gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon)
+static void ro_gui_window_action_remove_bookmark(struct gui_window *g)
{
- if (g == NULL || g->toolbar == NULL)
+ nsurl *url;
+
+ if (g == NULL || g->bw == NULL || g->toolbar == NULL ||
+ browser_window_has_content(g->bw) == false)
return;
- ro_toolbar_set_site_favicon(g->toolbar, icon);
-}
+ url = browser_window_get_url(g->bw);
+ ro_gui_hotlist_remove_page(url);
+}
/**
- * Remove the caret, if present.
+ * Open a local history pane for a browser window.
*
- * \param g window with caret
+ * \param gw The browser window to act on.
*/
-
-static void gui_window_remove_caret(struct gui_window *g)
+static void ro_gui_window_action_local_history(struct gui_window *gw)
{
- wimp_caret caret;
- os_error *error;
+ nserror res;
- error = xwimp_get_caret_position(&caret);
- if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
+ if ((gw == NULL) || (gw->bw == NULL)) {
return;
}
- if (caret.w != g->window)
- /* we don't have the caret: do nothing */
- return;
+ res = ro_gui_local_history_present(gw->window, gw->bw);
- /* hide caret, but keep input focus */
- gui_window_place_caret(g, -100, -100, 0, NULL);
+ if (res != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(res), 0);
+ }
}
/**
- * Called when the gui_window has new content.
+ * Perform a Navigate Home action on a browser window.
*
- * \param g the gui_window that has new content
+ * \param g The browser window to act on.
*/
-
-static void gui_window_new_content(struct gui_window *g)
+static void ro_gui_window_action_home(struct gui_window *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);
-}
-
-
-/**
- * Starts drag scrolling of a browser window
- *
- * \param g the window to scroll
- */
+ static const char *addr = NETSURF_HOMEPAGE;
+ nsurl *url;
+ nserror error;
-static bool gui_window_scroll_start(struct gui_window *g)
-{
- wimp_window_info_base info;
- wimp_pointer pointer;
- os_error *error;
- wimp_drag drag;
- int height;
- int width;
+ if (g == NULL || g->bw == NULL)
+ return;
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
+ if (nsoption_charp(homepage_url) != NULL) {
+ addr = nsoption_charp(homepage_url);
}
- info.w = g->window;
- error = xwimp_get_window_info_header_only((wimp_window_info*)&info);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
+ error = nsurl_create(addr, &url);
+ if (error == NSERROR_OK) {
+ error = browser_window_navigate(g->bw,
+ url,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
}
-
- width = info.extent.x1 - info.extent.x0;
- height = info.extent.y1 - info.extent.y0;
-
- drag.type = wimp_DRAG_USER_POINT;
- drag.bbox.x1 = pointer.pos.x + info.xscroll;
- drag.bbox.y0 = pointer.pos.y + info.yscroll;
- drag.bbox.x0 = drag.bbox.x1 - (width - (info.visible.x1 - info.visible.x0));
- drag.bbox.y1 = drag.bbox.y0 + (height - (info.visible.y1 - info.visible.y0));
-
- if (g->toolbar) {
- int tbar_height = ro_toolbar_full_height(g->toolbar);
- drag.bbox.y0 -= tbar_height;
- drag.bbox.y1 -= tbar_height;
+ if (error != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(error), 0);
}
+}
- error = xwimp_drag_box(&drag);
- if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
- }
- ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at,
- NULL, g);
- return true;
+/**
+ * Open a text search dialogue for a browser window.
+ *
+ * \param g The browser window to act on.
+ */
+static void ro_gui_window_action_search(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || !browser_window_can_search(g->bw))
+ return;
+
+ ro_gui_search_prepare(g->bw);
+ ro_gui_dialog_open_persistent(g->window, dialog_search, true);
}
/**
- * Platform-dependent part of starting drag operation.
+ * Open a zoom dialogue for a browser window.
*
- * \param g gui window containing the drag
- * \param type type of drag the core is performing
- * \param rect rectangle to constrain pointer to (relative to drag start coord)
- * \return true iff succesful
+ * \param g The browser window to act on.
*/
-
-static bool gui_window_drag_start(struct gui_window *g, gui_drag_type type,
- const struct rect *rect)
+static void ro_gui_window_action_zoom(struct gui_window *g)
{
- wimp_pointer pointer;
- wimp_drag drag;
+ if (g == NULL)
+ return;
- if (rect != NULL) {
- /* We have a box to constrain the pointer to, for the drag
- * duration */
- os_error *error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
- }
+ ro_gui_dialog_prepare_zoom(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_zoom, true);
+}
- drag.type = wimp_DRAG_USER_POINT;
- drag.bbox.x0 = pointer.pos.x +
- (int)(rect->x0 * 2 * g->scale);
- drag.bbox.y0 = pointer.pos.y +
- (int)(rect->y0 * 2 * g->scale);
- drag.bbox.x1 = pointer.pos.x +
- (int)(rect->x1 * 2 * g->scale);
- drag.bbox.y1 = pointer.pos.y +
- (int)(rect->y1 * 2 * g->scale);
- error = xwimp_drag_box(&drag);
- if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
- }
- }
+/**
+ * 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.
+ */
+static void
+ro_gui_window_action_save(struct gui_window *g, gui_save_type save_type)
+{
+ struct hlcache_handle *h;
- switch (type) {
- case GDRAGGING_SCROLLBAR:
- /* Dragging a core scrollbar */
- ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at,
- NULL, g);
- break;
+ if (g == NULL || g->bw == NULL || !browser_window_has_content(g->bw))
+ return;
- default:
- /* Not handled here yet */
- break;
- }
+ h = browser_window_get_content(g->bw);
+ if (h == NULL)
+ return;
- return true;
+ ro_gui_save_prepare(save_type, h, NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
}
/**
- * Save the specified content as a link.
+ * Open a print dialogue for a browser window.
*
- * \param g The window containing the content
- * \param url The url of the link
- * \param title The title of the link
+ * \param g The browser window to act on.
*/
-static nserror
-gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
+static void ro_gui_window_action_print(struct gui_window *g)
{
- ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, url, title);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
- return NSERROR_OK;
+ if (g != NULL) {
+ ro_gui_print_prepare(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_print, true);
+ }
}
/**
- * Updates a windows extent.
+ * Prepare the page info window for use.
*
- * \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
+ * \param g The GUI window block to use.
*/
-
-void gui_window_set_extent(struct gui_window *g, int width, int height)
+static void ro_gui_window_prepare_pageinfo(struct gui_window *g)
{
- int screen_width;
- int toolbar_height = 0;
- wimp_window_state state;
- os_error *error;
+ struct hlcache_handle *h = browser_window_get_content(g->bw);
+ char icon_buf[20] = "file_xxx";
+ char enc_buf[40];
+ const char *icon = icon_buf;
+ const char *title, *url;
+ lwc_string *mime;
+ const char *enc = "-";
- if (g->toolbar)
- toolbar_height = ro_toolbar_full_height(g->toolbar);
+ assert(h);
- /* 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);
- ro_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;
+ title = content_get_title(h);
+ if (title == NULL)
+ title = "-";
+ url = nsurl_access(hlcache_handle_get_url(h));
+ if (url == NULL)
+ url = "-";
+ mime = content_get_mime_type(h);
+
+ 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 (content_get_encoding(h, CONTENT_ENCODING_NORMAL)) {
+ snprintf(enc_buf, sizeof enc_buf, "%s (%s)",
+ content_get_encoding(h, CONTENT_ENCODING_NORMAL),
+ content_get_encoding(h, CONTENT_ENCODING_SOURCE));
+ enc = enc_buf;
+ } else {
+ enc = messages_get("EncodingUnk");
}
}
- /* 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 (browser_window_is_frameset(g->bw)) {
- 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 (browser_window_has_content(g->bw)) {
- int w, h;
- browser_window_get_extents(g->bw, true, &w, &h);
- width = max(width, w * 2);
- height = max(height, h * 2);
- }
- 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);
- ro_warn_user("WimpError", error->errmess);
- return;
- }
+ 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,
+ lwc_string_data(mime), true);
+
+ lwc_string_unref(mime);
}
/**
- * Display a menu of options for a form select control.
+ * Open a page info box for a browser window.
*
- * \param g gui window containing form control
- * \param control form control of type GADGET_SELECT
+ * \param g The browser window to act on.
*/
-
-static void gui_window_create_form_select_menu(struct gui_window *g,
- struct form_control *control)
+static void ro_gui_window_action_page_info(struct gui_window *g)
{
- os_error *error;
- wimp_pointer pointer;
+ if (g == NULL || g->bw == NULL ||
+ browser_window_has_content(g->bw) == false)
+ return;
- /* 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.
- */
+ ro_gui_window_prepare_pageinfo(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_pageinfo, false);
+}
- if (!ro_gui_window_prepare_form_select_menu(g, control))
- return;
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- ro_gui_menu_destroy();
+/**
+ * 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.
+ */
+static void
+ro_gui_window_toolbar_click(void *data,
+ toolbar_action_type action_type,
+ union toolbar_action action)
+{
+ struct gui_window *g = data;
+ nserror err;
+
+ if (g == NULL)
return;
- }
- gui_form_select_control = control;
- ro_gui_menu_create(gui_form_select_menu,
- pointer.pos.x, pointer.pos.y, g->window);
-}
+ if (action_type == TOOLBAR_ACTION_URL) {
+ switch (action.url) {
+ case TOOLBAR_URL_DRAG_URL:
+ {
+ gui_save_type save_type;
-/*
- * RISC OS Wimp Event Handlers
- */
+ if (!browser_window_has_content(g->bw))
+ break;
+ if (ro_gui_shift_pressed())
+ save_type = GUI_SAVE_LINK_URL;
+ else
+ save_type = GUI_SAVE_LINK_TEXT;
-/**
- * Handle a Redraw_Window_Request for a browser window.
- */
+ ro_gui_drag_save_link(save_type,
+ browser_window_get_url(g->bw),
+ browser_window_get_title(g->bw), g);
+ }
+ break;
-void ro_gui_window_redraw(wimp_draw *redraw)
-{
- osbool more;
- struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(redraw->w);
- os_error *error;
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &ro_plotters
- };
+ case TOOLBAR_URL_SELECT_HOTLIST:
+ ro_gui_window_action_add_bookmark(g);
+ break;
- /* We can't render locked contents. If the browser window is not
- * ready for redraw, do nothing. Else, in the case of buffered
- * rendering we'll show random data. */
- if (!browser_window_redraw_ready(g->bw))
- return;
+ case TOOLBAR_URL_ADJUST_HOTLIST:
+ ro_gui_window_action_remove_bookmark(g);
+ break;
- ro_gui_current_redraw_gui = g;
+ default:
+ break;
+ }
- error = xwimp_redraw_window(redraw, &more);
- if (error) {
- LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
return;
}
- while (more) {
- struct rect clip;
- /* OS's redraw request coordinates are in screen coordinates,
- * with an origin at the bottom left of the screen.
- * Find the coordinate of the top left of the document in terms
- * of OS screen coordinates.
- * NOTE: OS units are 2 per px. */
- ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
- ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;
- /* Convert OS redraw rectangle request coordinates into NetSurf
- * coordinates. NetSurf coordinates have origin at top left of
- * document and units are in px. */
- clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; /* left */
- clip.y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; /* top */
- clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; /* right */
- clip.y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; /* bottom */
+ /* By now, the only valid action left is a button click. If it isn't
+ * one of those, give up.
+ */
- if (ro_gui_current_redraw_gui->option.buffer_everything)
- ro_gui_buffer_open(redraw);
+ if (action_type != TOOLBAR_ACTION_BUTTON)
+ return;
- browser_window_redraw(g->bw, 0, 0, &clip, &ctx);
+ switch (action.button) {
+ case TOOLBAR_BUTTON_BACK:
+ if (g->bw != NULL)
+ browser_window_history_back(g->bw, false);
+ break;
- if (ro_gui_current_redraw_gui->option.buffer_everything)
- ro_gui_buffer_close();
+ case TOOLBAR_BUTTON_BACK_NEW:
+ if (g->bw != NULL)
+ browser_window_history_back(g->bw, true);
+ break;
- /* Check to see if there are more rectangles to draw and
- * get next one */
- error = xwimp_get_rectangle(redraw, &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 && !(ro_gui_current_redraw_gui->
- option.buffer_everything &&
- error->errnum == error_WIMP_GET_RECT)) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- ro_gui_current_redraw_gui = NULL;
- return;
- }
- }
- ro_gui_current_redraw_gui = NULL;
-}
+ case TOOLBAR_BUTTON_FORWARD:
+ if (g->bw != NULL)
+ browser_window_history_forward(g->bw, false);
+ break;
+ case TOOLBAR_BUTTON_FORWARD_NEW:
+ if (g->bw != NULL)
+ browser_window_history_forward(g->bw, true);
+ break;
-/**
- * Set a gui_window's scale
- */
-void ro_gui_window_set_scale(struct gui_window *g, float scale)
-{
- g->scale = scale;
- browser_window_set_scale(g->bw, scale, true);
-}
+ 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;
-/**
- * Open a window using the given wimp_open, handling toolbars and resizing.
- */
+ case TOOLBAR_BUTTON_RELOAD_ALL:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, true);
+ break;
-void ro_gui_window_open(wimp_open *open)
-{
- struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(open->w);
- int width = open->visible.x1 - open->visible.x0;
- int height = open->visible.y1 - open->visible.y0;
- browser_scrolling h_scroll;
- browser_scrolling v_scroll;
- int toolbar_height = 0;
- float new_scale = 0;
- wimp_window_state state;
- os_error *error;
- wimp_w parent;
- bits linkage;
- bool have_content;
+ case TOOLBAR_BUTTON_HISTORY_LOCAL:
+ ro_gui_window_action_local_history(g);
+ break;
- if (open->next == wimp_TOP && g->iconise_icon >= 0) {
- /* window is no longer iconised, release its sprite number */
- iconise_used[g->iconise_icon] = false;
- g->iconise_icon = -1;
- }
+ case TOOLBAR_BUTTON_HISTORY_GLOBAL:
+ ro_gui_global_history_present();
+ break;
- have_content = browser_window_has_content(g->bw);
+ case TOOLBAR_BUTTON_HOME:
+ ro_gui_window_action_home(g);
+ break;
- /* get the current flags/nesting state */
- state.w = g->window;
- error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return;
- }
+ case TOOLBAR_BUTTON_SEARCH:
+ ro_gui_window_action_search(g);
+ break;
- /* account for toolbar height, if present */
- if (g->toolbar)
- toolbar_height = ro_toolbar_full_height(g->toolbar);
- height -= toolbar_height;
+ case TOOLBAR_BUTTON_SCALE:
+ ro_gui_window_action_zoom(g);
+ break;
- /* work with the state from now on so we can modify flags */
- state.visible = open->visible;
- state.xscroll = open->xscroll;
- state.yscroll = open->yscroll;
- state.next = open->next;
+ case TOOLBAR_BUTTON_BOOKMARK_OPEN:
+ ro_gui_hotlist_present();
+ break;
- browser_window_get_scrollbar_type(g->bw, &h_scroll, &v_scroll);
+ case TOOLBAR_BUTTON_BOOKMARK_ADD:
+ ro_gui_window_action_add_bookmark(g);
+ break;
- /* handle 'auto' scroll bars' and non-fitting scrollbar removal */
- if ((h_scroll != BW_SCROLLING_NO) && (v_scroll != BW_SCROLLING_NO)) {
- int size;
+ case TOOLBAR_BUTTON_SAVE_SOURCE:
+ ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
+ break;
- /* windows lose scrollbars when containing a frameset */
- bool no_hscroll = false;
- bool no_vscroll = browser_window_is_frameset(g->bw);
+ case TOOLBAR_BUTTON_SAVE_COMPLETE:
+ ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
+ break;
- /* hscroll */
- size = ro_get_hscroll_height(NULL);
- size -= 2; /* 1px border on both sides */
- if (!no_hscroll) {
- if (!(state.flags & wimp_WINDOW_HSCROLL)) {
- height -= size;
- state.visible.y0 += size;
- if (have_content) {
- browser_window_schedule_reformat(g->bw);
- }
- }
- state.flags |= wimp_WINDOW_HSCROLL;
- } else {
- if (state.flags & wimp_WINDOW_HSCROLL) {
- height += size;
- state.visible.y0 -= size;
- if (have_content) {
- browser_window_schedule_reformat(g->bw);
- }
- }
- state.flags &= ~wimp_WINDOW_HSCROLL;
+ case TOOLBAR_BUTTON_PRINT:
+ ro_gui_window_action_print(g);
+ break;
+
+ case TOOLBAR_BUTTON_UP:
+ err = browser_window_navigate_up(g->bw, false);
+ if (err != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(err), NULL);
}
+ break;
- /* vscroll */
- size = ro_get_vscroll_width(NULL);
- size -= 2; /* 1px border on both sides */
- if (!no_vscroll) {
- if (!(state.flags & wimp_WINDOW_VSCROLL)) {
- width -= size;
- state.visible.x1 -= size;
- if (have_content) {
- browser_window_schedule_reformat(g->bw);
- }
- }
- state.flags |= wimp_WINDOW_VSCROLL;
- } else {
- if (state.flags & wimp_WINDOW_VSCROLL) {
- width += size;
- state.visible.x1 += size;
- if (have_content) {
- browser_window_schedule_reformat(g->bw);
- }
- }
- state.flags &= ~wimp_WINDOW_VSCROLL;
+ case TOOLBAR_BUTTON_UP_NEW:
+ err = browser_window_navigate_up(g->bw, true);
+ if (err != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(err), NULL);
}
- }
+ break;
- /* reformat or change extent if necessary */
- if (have_content &&
- (g->old_width != width || g->old_height != height)) {
- /* Ctrl-resize of a top-level window scales the content size */
- if ((g->old_width > 0) && (g->old_width != width) &&
- (ro_gui_ctrl_pressed()))
- new_scale = (g->scale * width) / g->old_width;
- browser_window_schedule_reformat(g->bw);
- }
- if (g->update_extent || g->old_width != width ||
- g->old_height != height) {
- g->old_width = width;
- g->old_height = height;
- g->update_extent = false;
- gui_window_set_extent(g, width, height);
+ default:
+ break;
}
- /* first resize stops any flickering by making the URL window on top */
- ro_gui_url_complete_resize(g->toolbar, PTR_WIMP_OPEN(&state));
+ ro_gui_window_update_toolbar_buttons(g);
+}
- /* Windows containing framesets can only be scrolled via the core, which
- * is implementing frame scrollbars itself. The x and y offsets are
- * therefore fixed.
- */
- if (browser_window_is_frameset(g->bw)) {
- state.xscroll = 0;
- state.yscroll = toolbar_height;
- }
+/**
+ * Launch a new url in the given window.
+ *
+ * \param g gui_window to update
+ * \param url1 url to be launched
+ */
+static void ro_gui_window_launch_url(struct gui_window *g, const char *url1)
+{
+ nserror error;
+ nsurl *url;
- error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
- if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
+ if (url1 == NULL)
return;
- }
- /* update the toolbar */
- if (g->status_bar)
- ro_gui_status_bar_resize(g->status_bar);
- if (g->toolbar) {
- ro_toolbar_process(g->toolbar, -1, false);
- /* second resize updates to the new URL bar width */
- ro_gui_url_complete_resize(g->toolbar, open);
- }
+ ro_gui_url_complete_close();
- /* set the new scale from a ctrl-resize. this must be done at the end as
- * it may cause a frameset recalculation based on the new window size.
- */
- if (new_scale > 0) {
- ro_gui_window_set_scale(g, new_scale);
+ error = nsurl_create(url1, &url);
+ if (error != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(error), 0);
+ } else {
+ ro_gui_window_set_url(g, url);
+
+ browser_window_navigate(g->bw, url,
+ NULL, BW_NAVIGATE_HISTORY,
+ NULL, NULL, NULL);
+ nsurl_unref(url);
}
}
/**
- * Handle wimp closing event
+ * Open a new browser window.
+ *
+ * \param g The browser window to act on.
*/
-
-void ro_gui_window_close(wimp_w w)
+static void ro_gui_window_action_new_window(struct gui_window *g)
{
- struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(w);
- wimp_pointer pointer;
- os_error *error;
- char *temp_name;
- char *filename = NULL;
- struct nsurl *url;
- bool destroy;
+ nserror error;
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
+ if (g == NULL || g->bw == NULL)
return;
- }
- if (pointer.buttons & wimp_CLICK_ADJUST) {
- destroy = !ro_gui_shift_pressed();
+ error = browser_window_create(BW_CREATE_CLONE,
+ browser_window_get_url(g->bw),
+ NULL, g->bw, NULL);
- url = browser_window_get_url(g->bw);
- if (url != NULL) {
- netsurf_nsurl_to_path(url, &filename);
- }
- if (filename != NULL) {
- temp_name = malloc(strlen(filename) + 32);
- if (temp_name) {
- char *r;
- sprintf(temp_name, "Filer_OpenDir %s",
- filename);
- r = temp_name + strlen(temp_name);
- while (r > temp_name) {
- if (*r == '.') {
- *r = '\0';
- break;
- }
- r--;
- }
- error = xos_cli(temp_name);
- if (error) {
- LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MiscError", error->errmess);
- return;
- }
- free(temp_name);
- }
- free(filename);
- } else {
- /* this is pointless if we are about to close the
- * window */
- if (!destroy && url != NULL)
- browser_window_navigate_up(g->bw, false);
- }
+ if (error != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(error), 0);
}
- else
- destroy = true;
-
- if (destroy)
- browser_window_destroy(g->bw);
}
/**
- * Handle Mouse_Click events in a browser window. This should never see
- * Menu clicks, as these will be routed to the menu handlers.
+ * Scroll a browser window.
+ *
+ * the scroll is either via the core or directly using the normal
+ * Wimp_OpenWindow interface.
+ *
+ * Scroll steps are supplied in terms of the (extended) Scroll Event direction
+ * values returned by Wimp_Poll. Special values of 0x7fffffff and 0x80000000
+ * are added to mean "Home" and "End".
*
- * \param *pointer details of mouse click
- * \return true if click handled, false otherwise
+ * \param g The GUI Window to be scrolled.
+ * \param scroll_x The X scroll step to be applied.
+ * \param scroll_y The Y scroll step to be applied.
*/
-
-bool ro_gui_window_click(wimp_pointer *pointer)
+static void
+ro_gui_window_scroll_action(struct gui_window *g,
+ wimp_scroll_direction scroll_x,
+ wimp_scroll_direction scroll_y)
{
- struct gui_window *g;
- os_coord pos;
+ int visible_x, visible_y;
+ int step_x = 0, step_y = 0;
+ int toolbar_y;
+ wimp_window_state state;
+ wimp_pointer pointer;
+ os_error *error;
+ os_coord pos;
+ bool handled = false;
+ struct toolbar *toolbar;
- /* We should never see Menu clicks. */
+ if (g == NULL)
+ return;
- if (pointer->buttons == wimp_CLICK_MENU)
- return false;
+ /* Get the current window, toolbar and pointer details. */
- g = (struct gui_window *) ro_gui_wimp_event_get_user_data(pointer->w);
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ return;
+ }
- /* try to close url-completion */
- ro_gui_url_complete_close();
+ toolbar = ro_toolbar_parent_window_lookup(g->window);
+ assert(g == NULL || g->toolbar == NULL || g->toolbar == toolbar);
- /* set input focus */
- if (pointer->buttons & (wimp_SINGLE_SELECT | wimp_SINGLE_ADJUST))
- gui_window_place_caret(g, -100, -100, 0, NULL);
+ toolbar_y = (toolbar == NULL) ? 0 : ro_toolbar_full_height(toolbar);
- 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_DOUBLE_CLICK_DRAG),
- pos.x, pos.y);
+ visible_x = state.visible.x1 - state.visible.x0 - 32;
+ visible_y = state.visible.y1 - state.visible.y0 - 32 - toolbar_y;
- return true;
-}
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return;
+ }
+ /* Turn the scroll requirement from Scroll Event codes into coordinates
+ * that the core can understand.
+ */
-/**
- * Process Key_Pressed events in a browser window.
- *
- * \param *key The wimp keypress block for the event.
- * \return true if the event was handled, else false.
- */
+ switch (scroll_x) {
+ case wimp_SCROLL_PAGE_LEFT:
+ step_x = SCROLL_PAGE_DOWN;
+ break;
+ case wimp_SCROLL_AUTO_LEFT:
+ case wimp_SCROLL_COLUMN_LEFT:
+ step_x = -16;
+ break;
+ case wimp_SCROLL_AUTO_RIGHT:
+ case wimp_SCROLL_COLUMN_RIGHT:
+ step_x = 16;
+ break;
+ case wimp_SCROLL_PAGE_RIGHT:
+ step_x = SCROLL_PAGE_UP;
+ break;
+ case 0x80000000:
+ step_x = SCROLL_BOTTOM;
+ break;
+ case 0x7fffffff:
+ step_x = SCROLL_TOP;
+ break;
+ default:
+ step_x = (visible_x * (scroll_x>>2)) >> 2;
+ break;
+ }
-bool ro_gui_window_keypress(wimp_key *key)
-{
- struct gui_window *g;
- uint32_t c = (uint32_t) key->c;
+ switch (scroll_y) {
+ case wimp_SCROLL_PAGE_UP:
+ step_y = SCROLL_PAGE_UP;
+ break;
+ case wimp_SCROLL_AUTO_UP:
+ case wimp_SCROLL_LINE_UP:
+ step_y = -16;
+ break;
+ case wimp_SCROLL_AUTO_DOWN:
+ case wimp_SCROLL_LINE_DOWN:
+ step_y = 16;
+ break;
+ case wimp_SCROLL_PAGE_DOWN:
+ step_y = SCROLL_PAGE_DOWN;
+ break;
+ case 0x80000000:
+ step_y = SCROLL_BOTTOM;
+ break;
+ case 0x7fffffff:
+ step_y = SCROLL_TOP;
+ break;
+ default:
+ step_y = -((visible_y * (scroll_y>>2)) >> 2);
+ break;
+ }
- g = (struct gui_window *) ro_gui_wimp_event_get_user_data(key->w);
- if (g == NULL)
- return false;
+ /* If no scrolling is required, there's no point trying to do any. */
- /* First send the key to the browser window, eg. form fields. */
+ if (step_x == 0 && step_y == 0)
+ return;
- 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;
+ /* If the pointer is over the window being scrolled, then try to get
+ * the core to do the scrolling on the object under the pointer.
+ */
- /* cursor movement keys */
- case wimp_KEY_HOME:
- case wimp_KEY_CONTROL | wimp_KEY_LEFT:
- c = NS_KEY_LINE_START;
+ if (pointer.w == g->window &&
+ ro_gui_window_to_window_pos(g,
+ pointer.pos.x, pointer.pos.y, &pos))
+ handled = browser_window_scroll_at_point(g->bw, pos.x, pos.y,
+ step_x, step_y);
+
+ /* If the core didn't do the scrolling, handle it via the Wimp.
+ * Windows which contain frames can only be scrolled by the core,
+ * because it implements frame scroll bars.
+ */
+
+ if (!handled && (browser_window_is_frameset(g->bw) == false)) {
+ switch (step_x) {
+ case SCROLL_TOP:
+ state.xscroll -= 0x10000000;
break;
- case wimp_KEY_END:
- if (os_version >= RISCOS5)
- c = NS_KEY_LINE_END;
- else
- c = NS_KEY_DELETE_RIGHT;
+ case SCROLL_BOTTOM:
+ state.xscroll += 0x10000000;
break;
- case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = NS_KEY_LINE_END; break;
- case wimp_KEY_CONTROL | wimp_KEY_UP: c = NS_KEY_TEXT_START; break;
- case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = NS_KEY_TEXT_END; break;
- case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = NS_KEY_WORD_LEFT ; break;
- case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = NS_KEY_WORD_RIGHT; break;
- case wimp_KEY_SHIFT | wimp_KEY_UP: c = NS_KEY_PAGE_UP; break;
- case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = NS_KEY_PAGE_DOWN; break;
- case wimp_KEY_LEFT: c = NS_KEY_LEFT; break;
- case wimp_KEY_RIGHT: c = NS_KEY_RIGHT; break;
- case wimp_KEY_UP: c = NS_KEY_UP; break;
- case wimp_KEY_DOWN: c = NS_KEY_DOWN; break;
-
- /* editing */
- case wimp_KEY_CONTROL | wimp_KEY_END:
- c = NS_KEY_DELETE_LINE_END;
+ case SCROLL_PAGE_UP:
+ state.xscroll += visible_x;
break;
- case wimp_KEY_DELETE:
- if (ro_gui_ctrl_pressed())
- c = NS_KEY_DELETE_LINE_START;
- else if (os_version < RISCOS5)
- c = NS_KEY_DELETE_LEFT;
+ case SCROLL_PAGE_DOWN:
+ state.xscroll -= visible_x;
break;
+ default:
+ state.xscroll += 2 * step_x;
+ break;
+ }
- case wimp_KEY_F8:
- c = NS_KEY_UNDO;
+ switch (step_y) {
+ case SCROLL_TOP:
+ state.yscroll += 0x10000000;
break;
- case wimp_KEY_F9:
- c = NS_KEY_REDO;
+ case SCROLL_BOTTOM:
+ state.yscroll -= 0x10000000;
+ break;
+ case SCROLL_PAGE_UP:
+ state.yscroll += visible_y;
+ break;
+ case SCROLL_PAGE_DOWN:
+ state.yscroll -= visible_y;
break;
-
default:
+ state.yscroll -= 2 * step_y;
break;
}
- }
- if (!(c & IS_WIMP_KEY)) {
- if (browser_window_key_press(g->bw, c))
- return true;
+ error = xwimp_open_window((wimp_open *) &state);
+ if (error) {
+ LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ }
}
-
- return ro_gui_window_handle_local_keypress(g, key, false);
}
/**
- * Callback handler for keypresses within browser window toolbars.
+ * Handle keypresses within the RISC OS GUI
*
- * \param *data Client data, pointing to the GUI Window.
- * \param *key The keypress data.
- * \return true if the keypress was handled; else false.
- */
-
-bool ro_gui_window_toolbar_keypress(void *data, wimp_key *key)
-{
- struct gui_window *g = (struct gui_window *) data;
-
- if (g != NULL)
- return ro_gui_window_handle_local_keypress(g, key, true);
-
- return false;
-}
-
-
-/**
- * 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.
+ * 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.
- * \return true if the keypress was claimed; else false.
+ * \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.
+ * \return true if the keypress was claimed; else false.
*/
-
-bool ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key,
- bool is_toolbar)
+static bool
+ro_gui_window_handle_local_keypress(struct gui_window *g,
+ wimp_key *key,
+ bool is_toolbar)
{
struct browser_window_features cont;
os_error *ro_error;
@@ -2107,18 +1464,643 @@ bool ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key,
/**
- * Prepare the browser window menu for (re-)opening
+ * Callback handler for keypresses within browser window toolbars.
+ *
+ * \param data Client data, pointing to the GUI Window.
+ * \param key The keypress data.
+ * \return true if the keypress was handled; else false.
+ */
+static bool ro_gui_window_toolbar_keypress(void *data, wimp_key *key)
+{
+ struct gui_window *g = (struct gui_window *) data;
+
+ if (g != NULL) {
+ return ro_gui_window_handle_local_keypress(g, key, true);
+ }
+
+ return false;
+}
+
+
+/**
+ * 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.
+ */
+static void ro_gui_window_save_toolbar_buttons(void *data, char *config)
+{
+ nsoption_set_charp(toolbar_browser, config);
+ ro_gui_save_options();
+}
+
+
+/**
+ * toolbar callbacks for a browser window.
+ */
+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
+};
+
+
+/**
+ * Handle wimp closing event
+ *
+ * \param w The window handle the event occoured on
+ */
+static void ro_gui_window_close(wimp_w w)
+{
+ struct gui_window *g;
+ wimp_pointer pointer;
+ os_error *error;
+ char *temp_name;
+ char *filename = NULL;
+ struct nsurl *url;
+ bool destroy;
+
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return;
+ }
+
+ g = (struct gui_window *)ro_gui_wimp_event_get_user_data(w);
+
+ if (pointer.buttons & wimp_CLICK_ADJUST) {
+ destroy = !ro_gui_shift_pressed();
+
+ url = browser_window_get_url(g->bw);
+ if (url != NULL) {
+ netsurf_nsurl_to_path(url, &filename);
+ }
+ if (filename != NULL) {
+ temp_name = malloc(strlen(filename) + 32);
+ if (temp_name) {
+ char *r;
+ sprintf(temp_name, "Filer_OpenDir %s",
+ filename);
+ r = temp_name + strlen(temp_name);
+ while (r > temp_name) {
+ if (*r == '.') {
+ *r = '\0';
+ break;
+ }
+ r--;
+ }
+ error = xos_cli(temp_name);
+ if (error) {
+ LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("MiscError", error->errmess);
+ return;
+ }
+ free(temp_name);
+ }
+ free(filename);
+ } else {
+ /* this is pointless if we are about to close the
+ * window */
+ if (!destroy && url != NULL)
+ browser_window_navigate_up(g->bw, false);
+ }
+ } else {
+ destroy = true;
+ }
+
+ if (destroy) {
+ browser_window_destroy(g->bw);
+ }
+}
+
+
+/**
+ * Handle a Redraw_Window_Request for a browser window.
+ *
+ * \param redraw The redraw event
+ */
+static void ro_gui_window_redraw(wimp_draw *redraw)
+{
+ osbool more;
+ struct gui_window *g;
+ os_error *error;
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &ro_plotters
+ };
+
+ g = (struct gui_window *)ro_gui_wimp_event_get_user_data(redraw->w);
+
+ /* We cannot render locked contents. If the browser window is not
+ * ready for redraw, do nothing. Else, in the case of buffered
+ * rendering we'll show random data. */
+ if (!browser_window_redraw_ready(g->bw)) {
+ return;
+ }
+
+ ro_gui_current_redraw_gui = g;
+
+ error = xwimp_redraw_window(redraw, &more);
+ if (error) {
+ LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return;
+ }
+ while (more) {
+ struct rect clip;
+
+ /* OS's redraw request coordinates are in screen coordinates,
+ * with an origin at the bottom left of the screen.
+ * Find the coordinate of the top left of the document in terms
+ * of OS screen coordinates.
+ * NOTE: OS units are 2 per px. */
+ ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
+ ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;
+
+ /* Convert OS redraw rectangle request coordinates into NetSurf
+ * coordinates. NetSurf coordinates have origin at top left of
+ * document and units are in px. */
+ clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; /* left */
+ clip.y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; /* top */
+ clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; /* right */
+ clip.y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; /* bottom */
+
+ if (ro_gui_current_redraw_gui->option.buffer_everything)
+ ro_gui_buffer_open(redraw);
+
+ browser_window_redraw(g->bw, 0, 0, &clip, &ctx);
+
+ if (ro_gui_current_redraw_gui->option.buffer_everything)
+ ro_gui_buffer_close();
+
+ /* Check to see if there are more rectangles to draw and
+ * get next one */
+ error = xwimp_get_rectangle(redraw, &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 && !(ro_gui_current_redraw_gui->
+ option.buffer_everything &&
+ error->errnum == error_WIMP_GET_RECT)) {
+ LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ ro_gui_current_redraw_gui = NULL;
+ return;
+ }
+ }
+ ro_gui_current_redraw_gui = NULL;
+}
+
+
+/**
+ * Process Scroll_Request events in a browser window.
+ *
+ * \param scroll The wimp scroll event data block.
+ */
+static void ro_gui_window_scroll(wimp_scroll *scroll)
+{
+ struct gui_window *g = ro_gui_window_lookup(scroll->w);
+
+ if (g && browser_window_has_content(g->bw) && ro_gui_shift_pressed()) {
+ /* extended scroll request with shift held down; change zoom */
+ float scale, inc;
+
+ if (scroll->ymin & 3)
+ inc = 0.02; /* RO5 sends the msg 5 times;
+ * don't ask me why
+ *
+ * @todo this is liable to break if
+ * HID is configured optimally for
+ * frame scrolling. *5 appears to be
+ * an artifact of non-HID mode scrolling.
+ */
+ else
+ inc = (1 << (ABS(scroll->ymin)>>2)) / 20.0F;
+
+ if (scroll->ymin > 0) {
+ scale = g->scale + inc;
+ if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1])
+ scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1];
+ } else {
+ scale = g->scale - inc;
+ if (scale < scale_snap_to[0])
+ scale = scale_snap_to[0];
+ }
+ if (g->scale != scale)
+ ro_gui_window_set_scale(g, scale);
+ } else if (g != NULL) {
+ ro_gui_window_scroll_action(g, scroll->xmin, scroll->ymin);
+ }
+}
+
+
+/**
+ * Process Pointer Leaving Window events in a browser window.
+ *
+ * These arrive via the termination callback handler from ro_mouse's
+ * mouse tracking.
+ *
+ * \param leaving The wimp pointer leaving event data block.
+ * \param data The GUI window that the pointer is leaving.
+ */
+static void ro_gui_window_track_end(wimp_leaving *leaving, void *data)
+{
+ struct gui_window *g = (struct gui_window *)data;
+
+ if (g != NULL) {
+ gui_window_set_pointer(g, GUI_POINTER_DEFAULT);
+ }
+}
+
+
+/**
+ * Process Pointer Entering Window events in a browser window.
+ *
+ * \param entering The wimp pointer entering event data block.
+ */
+static void ro_gui_window_pointer_entering(wimp_entering *entering)
+{
+ struct gui_window *g = ro_gui_window_lookup(entering->w);
+
+ if (g != NULL) {
+ ro_mouse_track_start(ro_gui_window_track_end,
+ ro_gui_window_mouse_at,
+ g);
+ }
+}
+
+
+/**
+ * Process Key_Pressed events in a browser window.
+ *
+ * \param key The wimp keypress block for the event.
+ * \return true if the event was handled, else false.
+ */
+static bool ro_gui_window_keypress(wimp_key *key)
+{
+ struct gui_window *g;
+ 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;
+ }
+
+ /* First send the key to the browser window, eg. form fields. */
+
+ 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 = NS_KEY_LINE_START;
+ break;
+
+ case wimp_KEY_END:
+ if (os_version >= RISCOS5) {
+ c = NS_KEY_LINE_END;
+ } else {
+ c = NS_KEY_DELETE_RIGHT;
+ }
+ break;
+
+ case wimp_KEY_CONTROL | wimp_KEY_RIGHT:
+ c = NS_KEY_LINE_END;
+ break;
+
+ case wimp_KEY_CONTROL | wimp_KEY_UP:
+ c = NS_KEY_TEXT_START;
+ break;
+
+ case wimp_KEY_CONTROL | wimp_KEY_DOWN:
+ c = NS_KEY_TEXT_END;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_LEFT:
+ c = NS_KEY_WORD_LEFT ;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_RIGHT:
+ c = NS_KEY_WORD_RIGHT;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_UP:
+ c = NS_KEY_PAGE_UP;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_DOWN:
+ c = NS_KEY_PAGE_DOWN;
+ break;
+
+ case wimp_KEY_LEFT:
+ c = NS_KEY_LEFT;
+ break;
+
+ case wimp_KEY_RIGHT:
+ c = NS_KEY_RIGHT;
+ break;
+
+ case wimp_KEY_UP:
+ c = NS_KEY_UP;
+ break;
+
+ case wimp_KEY_DOWN:
+ c = NS_KEY_DOWN;
+ break;
+
+ /* editing */
+ case wimp_KEY_CONTROL | wimp_KEY_END:
+ c = NS_KEY_DELETE_LINE_END;
+ break;
+
+ case wimp_KEY_DELETE:
+ if (ro_gui_ctrl_pressed()) {
+ c = NS_KEY_DELETE_LINE_START;
+ } else if (os_version < RISCOS5) {
+ c = NS_KEY_DELETE_LEFT;
+ }
+ break;
+
+ case wimp_KEY_F8:
+ c = NS_KEY_UNDO;
+ break;
+
+ case wimp_KEY_F9:
+ c = NS_KEY_REDO;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!(c & IS_WIMP_KEY)) {
+ if (browser_window_key_press(g->bw, c)) {
+ return true;
+ }
+ }
+
+ return ro_gui_window_handle_local_keypress(g, key, false);
+}
+
+
+/**
+ * Handle Mouse_Click events in a browser window.
+ *
+ * This should never see Menu clicks, as these will be routed to the
+ * menu handlers.
+ *
+ * \param pointer details of mouse click
+ * \return true if click handled, false otherwise
+ */
+static bool ro_gui_window_click(wimp_pointer *pointer)
+{
+ struct gui_window *g;
+ os_coord pos;
+
+ /* We should never see Menu clicks. */
+
+ if (pointer->buttons == wimp_CLICK_MENU) {
+ return false;
+ }
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(pointer->w);
+
+ /* try to close url-completion */
+ ro_gui_url_complete_close();
+
+ /* set input focus */
+ if (pointer->buttons & (wimp_SINGLE_SELECT | wimp_SINGLE_ADJUST))
+ gui_window_place_caret(g, -100, -100, 0, NULL);
+
+ 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_DOUBLE_CLICK_DRAG),
+ pos.x, pos.y);
+ }
+
+ return true;
+}
+
+
+/**
+ * Prepare or reprepare a form select menu
+ *
+ * setting up the menu handle globals in the process.
+ *
+ * \param g The RISC OS gui window the menu is in.
+ * \param control The form control needing a menu.
+ * \return true if the menu is OK to be opened; else false.
+ */
+static bool
+ro_gui_window_prepare_form_select_menu(struct gui_window *g,
+ struct form_control *control)
+{
+ unsigned int item, entries;
+ char *text_convert, *temp;
+ struct form_option *option;
+ bool reopen = true;
+ nserror err;
+
+ assert(control);
+
+ /* enumerate the entries */
+ entries = 0;
+ option = form_select_get_option(control, entries);
+ while (option != NULL) {
+ entries++;
+ option = form_select_get_option(control, entries);
+ }
+
+ if (entries == 0) {
+ /* no menu to display */
+ ro_gui_menu_destroy();
+ return false;
+ }
+
+ /* free riscos menu if there already is one */
+ if ((gui_form_select_menu) && (control != gui_form_select_control)) {
+ for (item = 0; ; item++) {
+ free(gui_form_select_menu->entries[item].data.
+ indirected_text.text);
+ if (gui_form_select_menu->entries[item].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;
+ }
+
+ /* allocate new riscos menu */
+ if (!gui_form_select_menu) {
+ reopen = false;
+ gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries));
+ if (!gui_form_select_menu) {
+ ro_warn_user("NoMemory", 0);
+ ro_gui_menu_destroy();
+ return false;
+ }
+ err = utf8_to_local_encoding(messages_get("SelectMenu"), 0,
+ &text_convert);
+ if (err != NSERROR_OK) {
+ /* badenc should never happen */
+ assert(err != NSERROR_BAD_ENCODING);
+ LOG("utf8_to_local_encoding failed");
+ ro_warn_user("NoMemory", 0);
+ ro_gui_menu_destroy();
+ return false;
+ }
+ gui_form_select_menu->title_data.indirected_text.text =
+ text_convert;
+ ro_gui_menu_init_structure(gui_form_select_menu, entries);
+ }
+
+ /* initialise menu entries from form control */
+ for (item = 0; item < entries; item++) {
+ option = form_select_get_option(control, item);
+ gui_form_select_menu->entries[item].menu_flags = 0;
+ if (option->selected)
+ gui_form_select_menu->entries[item].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");
+ ro_warn_user("NoMemory", 0);
+ ro_gui_menu_destroy();
+ return false;
+ }
+
+ err = utf8_to_local_encoding(temp,
+ 0, &text_convert);
+ if (err != NSERROR_OK) {
+ /* A bad encoding should never happen,
+ * so assert this */
+ assert(err != NSERROR_BAD_ENCODING);
+ LOG("utf8_to_enc failed");
+ ro_warn_user("NoMemory", 0);
+ ro_gui_menu_destroy();
+ return false;
+ }
+
+ free(temp);
+
+ gui_form_select_menu->entries[item].data.indirected_text.text =
+ text_convert;
+ gui_form_select_menu->entries[item].data.indirected_text.size =
+ strlen(gui_form_select_menu->entries[item].
+ data.indirected_text.text) + 1;
+ }
+ }
+
+ gui_form_select_menu->entries[0].menu_flags |=
+ wimp_MENU_TITLE_INDIRECTED;
+ gui_form_select_menu->entries[item - 1].menu_flags |= wimp_MENU_LAST;
+
+ return true;
+}
+
+
+/**
+ * Return boolean flags to show what RISC OS types we can sensibly convert
+ * the given object into.
*
- * \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.
+ * \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.
*/
+static bool
+ro_gui_window_content_export_types(struct 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;
+ }
-bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
- wimp_pointer *pointer)
+ if (h != NULL && content_get_type(h) == CONTENT_IMAGE) {
+ switch (ro_content_native_type(h)) {
+ case osfile_TYPE_SPRITE:
+ /* bitmap types (Sprite export possible) */
+ found_type = true;
+ if (export_sprite != NULL) {
+ *export_sprite = true;
+ }
+ break;
+
+ case osfile_TYPE_DRAW:
+ /* vector types (Draw export possible) */
+ found_type = true;
+ if (export_draw != NULL) {
+ *export_draw = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return found_type;
+}
+
+
+/**
+ * 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.
+ */
+static 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;
@@ -2143,13 +2125,13 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
gui_form_select_control);
}
- if (menu != ro_gui_browser_window_menu)
+ 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();
@@ -2260,13 +2242,14 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_TEXT,
current_menu_object == NULL);
- if (current_menu_object != NULL)
+ if (current_menu_object != NULL) {
ro_gui_window_content_export_types(current_menu_object,
&export_draw, &export_sprite);
- else
+ } else {
ro_gui_window_content_export_types(
browser_window_get_content(bw),
&export_draw, &export_sprite);
+ }
ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT,
(!have_content && current_menu_object == NULL)
@@ -2324,14 +2307,15 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
/* View Submenu */
ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_FOREGROUND,
- g != NULL && nsoption_bool(foreground_images));
+ g != NULL && nsoption_bool(foreground_images));
ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_BACKGROUND,
- g != NULL && nsoption_bool(background_images));
+ g != NULL && nsoption_bool(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 &&
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ANIMS,
+ g != NULL &&
(g->option.buffer_animations ||
g->option.buffer_everything));
@@ -2342,16 +2326,16 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
ro_gui_menu_set_entry_shaded(menu, BROWSER_SCALE_VIEW, !have_content);
ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_STAGGER,
- nsoption_int(window_screen_width) == 0);
+ nsoption_int(window_screen_width) == 0);
ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_STAGGER,
- ((nsoption_int(window_screen_width) == 0) ||
- nsoption_bool(window_stagger)));
+ ((nsoption_int(window_screen_width) == 0) ||
+ nsoption_bool(window_stagger)));
ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_COPY,
- nsoption_bool(window_size_clone));
+ nsoption_bool(window_size_clone));
ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_RESET,
- nsoption_int(window_screen_width) == 0);
+ nsoption_int(window_screen_width) == 0);
/* Utilities Submenu */
@@ -2375,199 +2359,72 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
/**
- * Handle submenu warnings for a browser window menu
+ * Process selections from a form select menu, passing them back to the core.
*
- * \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.
+ * \param g The browser window affected by the menu.
+ * \param selection The menu selection.
*/
-
-void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
- wimp_selection *selection, menu_action action)
+static void
+ro_gui_window_process_form_select_menu(struct gui_window *g,
+ wimp_selection *selection)
{
- struct gui_window *g;
- struct hlcache_handle *h;
- bool export;
-
- if (menu != ro_gui_browser_window_menu)
- return;
-
- g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
- h = browser_window_get_content(g->bw);
-
- 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 (browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY)
- ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
- browser_window_get_selection(g->bw),
- NULL, NULL);
- break;
-
- case BROWSER_SAVE_URL_URI:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
- hlcache_handle_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,
- hlcache_handle_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,
- hlcache_handle_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,
- hlcache_handle_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,
- hlcache_handle_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,
- hlcache_handle_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;
+ assert(g != NULL);
- 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;
+ if (selection->items[0] >= 0) {
+ form_select_process_selection(gui_form_select_control,
+ selection->items[0]);
+ }
+}
- 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);
+/**
+ * Prepare the object info window for use
+ *
+ * \param object the object for which information is to be displayed
+ * \param target_url corresponding url, if any
+ */
+static void
+ro_gui_window_prepare_objectinfo(struct hlcache_handle *object,
+ nsurl *target_url)
+{
+ char icon_buf[20] = "file_xxx";
+ const char *url;
+ lwc_string *mime;
+ const char *target = "-";
- if (export)
- ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
- h, NULL, NULL, NULL);
- }
- break;
+ sprintf(icon_buf, "file_%.3x",ro_content_filetype(object));
+ if (!ro_gui_wimp_sprite_exists(icon_buf)) {
+ sprintf(icon_buf, "file_xxx");
+ }
- case BROWSER_OBJECT_EXPORT_DRAW:
- if (current_menu_object != NULL) {
- ro_gui_window_content_export_types(current_menu_object,
- &export, NULL);
+ url = nsurl_access(hlcache_handle_get_url(object));
+ if (url == NULL) {
+ url = "-";
+ }
+ mime = content_get_mime_type(object);
- 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 (target_url != NULL) {
+ target = nsurl_access(target_url);
+ }
- if (export)
- ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
- h, NULL, NULL, NULL);
- }
- break;
+ 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,
+ lwc_string_data(mime), true);
- default:
- break;
- }
+ lwc_string_unref(mime);
}
+/**
+ * callback to handle window paste operation
+ *
+ * \param pw context containing browser window
+ */
static void ro_gui_window_paste_cb(void *pw)
{
struct browser_window *bw = pw;
@@ -2579,22 +2436,25 @@ static void ro_gui_window_paste_cb(void *pw)
/**
* 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.
+ * \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)
+static 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;
- struct hlcache_handle *h;
- struct toolbar *toolbar;
- wimp_window_state state;
+ struct gui_window *g;
+ struct browser_window *bw;
+ struct hlcache_handle *h;
+ struct toolbar *toolbar;
+ wimp_window_state state;
nsurl *url;
nserror error = NSERROR_OK;
@@ -2606,7 +2466,6 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
/* 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);
@@ -2624,10 +2483,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("http://www.netsurf-browser.org/documentation/", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2636,10 +2495,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("http://www.netsurf-browser.org/documentation/guide", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2648,10 +2507,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("http://www.netsurf-browser.org/documentation/info", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2660,10 +2519,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("about:credits", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2672,10 +2531,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("about:licence", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2685,7 +2544,8 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
ro_gui_interactive_help_start();
nsoption_set_bool(interactive_help, true);
} else {
- nsoption_set_bool(interactive_help, !nsoption_bool(interactive_help));
+ nsoption_set_bool(interactive_help,
+ !nsoption_bool(interactive_help));
}
break;
@@ -2737,9 +2597,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
case BROWSER_OBJECT_INFO:
if (current_menu_object != NULL) {
ro_gui_window_prepare_objectinfo(current_menu_object,
- current_menu_url);
+ current_menu_url);
ro_gui_dialog_open_persistent(g->window,
- dialog_objinfo, false);
+ dialog_objinfo,
+ false);
}
break;
case BROWSER_OBJECT_RELOAD:
@@ -2752,50 +2613,62 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
/* 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,
+ 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,
+ 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,
+ 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) {
- error = browser_window_navigate(bw,
- current_menu_url,
- browser_window_get_url(bw),
- BW_NAVIGATE_DOWNLOAD,
- NULL,
- NULL,
- NULL);
+ error = browser_window_navigate(
+ bw,
+ current_menu_url,
+ browser_window_get_url(bw),
+ BW_NAVIGATE_DOWNLOAD,
+ NULL,
+ NULL,
+ NULL);
}
break;
case BROWSER_LINK_NEW_WINDOW:
if (current_menu_url != NULL) {
error = browser_window_create(
- BW_CREATE_HISTORY |
- BW_CREATE_CLONE,
- current_menu_url,
- browser_window_get_url(bw),
- bw,
- NULL);
+ BW_CREATE_HISTORY | BW_CREATE_CLONE,
+ current_menu_url,
+ browser_window_get_url(bw),
+ bw,
+ NULL);
}
break;
@@ -2804,24 +2677,36 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
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,
+ 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,
+ 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,
+ current_menu_object,
+ NULL,
+ NULL,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
@@ -2853,10 +2738,13 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
/* selection actions */
case BROWSER_SELECTION_SAVE:
if (h != NULL) {
- ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
+ ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION,
+ NULL,
browser_window_get_selection(bw),
- NULL, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ NULL,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
@@ -2975,19 +2863,19 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
case TOOLBAR_BUTTONS:
assert(toolbar);
ro_toolbar_set_display_buttons(toolbar,
- !ro_toolbar_get_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));
+ !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));
+ !ro_toolbar_get_display_throbber(toolbar));
break;
case TOOLBAR_EDIT:
assert(toolbar);
@@ -3007,467 +2895,875 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
/**
- * Handle the closure of a browser window menu
+ * 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 that is being closed.
+ * \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_close(wimp_w w, wimp_i i, wimp_menu *menu)
+static void
+ro_gui_window_menu_warning(wimp_w w,
+ wimp_i i,
+ wimp_menu *menu,
+ wimp_selection *selection,
+ menu_action action)
{
- 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;
+ struct gui_window *g;
+ struct hlcache_handle *h;
+ bool export;
+
+ if (menu != ro_gui_browser_window_menu) {
+ return;
}
-}
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
+ h = browser_window_get_content(g->bw);
-/**
- * Process Scroll_Request events in a browser window.
- *
- * \param *scroll The wimp scroll event data block.
- */
+ switch (action) {
+ case BROWSER_PAGE_INFO:
+ if (h != NULL) {
+ ro_gui_window_prepare_pageinfo(g);
+ }
+ break;
-void ro_gui_window_scroll(wimp_scroll *scroll)
-{
- struct gui_window *g = ro_gui_window_lookup(scroll->w);
+ 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;
- if (g && browser_window_has_content(g->bw) && ro_gui_shift_pressed()) {
- /* extended scroll request with shift held down; change zoom */
- float scale, inc;
+ case BROWSER_SCALE_VIEW:
+ if (h != NULL) {
+ ro_gui_dialog_prepare_zoom(g);
+ }
+ break;
- if (scroll->ymin & 3)
- inc = 0.02; /* RO5 sends the msg 5 times;
- * don't ask me why
- *
- * @todo this is liable to break if
- * HID is configured optimally for
- * frame scrolling. *5 appears to be
- * an artifact of non-HID mode scrolling.
- */
- else
- inc = (1 << (ABS(scroll->ymin)>>2)) / 20.0F;
+ case BROWSER_PRINT:
+ if (h != NULL) {
+ ro_gui_print_prepare(g);
+ }
+ break;
- if (scroll->ymin > 0) {
- scale = g->scale + inc;
- if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1])
- scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1];
- } else {
- scale = g->scale - inc;
- if (scale < scale_snap_to[0])
- scale = scale_snap_to[0];
+ case BROWSER_OBJECT_INFO:
+ if (current_menu_object != NULL) {
+ ro_gui_window_prepare_objectinfo(current_menu_object,
+ current_menu_url);
}
- if (g->scale != scale)
- ro_gui_window_set_scale(g, scale);
- } else if (g != NULL) {
- ro_gui_window_scroll_action(g, scroll->xmin, scroll->ymin);
+ 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 (browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY)
+ ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
+ browser_window_get_selection(g->bw),
+ NULL, NULL);
+ break;
+
+ case BROWSER_SAVE_URL_URI:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ hlcache_handle_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,
+ hlcache_handle_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,
+ hlcache_handle_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,
+ hlcache_handle_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,
+ hlcache_handle_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,
+ hlcache_handle_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;
}
}
+
/**
- * Process Pointer Entering Window events in a browser window.
+ * Handle the closure of a browser window menu
*
- * \param *entering The wimp pointer entering event data block.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param menu The menu that is being closed.
*/
-
-static void ro_gui_window_pointer_entering(wimp_entering *entering)
+static void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu)
{
- struct gui_window *g = ro_gui_window_lookup(entering->w);
-
- if (g != NULL)
- ro_mouse_track_start(ro_gui_window_track_end,
- ro_gui_window_mouse_at, g);
+ 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 Pointer Leaving Window events in a browser window. These arrive via
- * the termination callback handler from ro_mouse's mouse tracking.
+ * Clones a browser window's options.
*
- * \param *leaving The wimp pointer leaving event data block.
- * \param *data The GUI window that the pointer is leaving.
+ * \param new_gui the new gui window
+ * \param old_gui the gui window to clone from, or NULL for default
*/
-
-static void ro_gui_window_track_end(wimp_leaving *leaving, void *data)
+static void
+ro_gui_window_clone_options(struct gui_window *new_gui,
+ struct gui_window *old_gui)
{
- struct gui_window *g = (struct gui_window *) data;
+ assert(new_gui);
- if (g != NULL)
- gui_window_set_pointer(g, GUI_POINTER_DEFAULT);
+ /* Clone the basic options
+ */
+ if (!old_gui) {
+ new_gui->option.buffer_animations = nsoption_bool(buffer_animations);
+ new_gui->option.buffer_everything = nsoption_bool(buffer_everything);
+ } else {
+ new_gui->option = old_gui->option;
+ }
+
+ /* Set up the toolbar
+ */
+ if (new_gui->toolbar) {
+ ro_toolbar_set_display_buttons(new_gui->toolbar,
+ nsoption_bool(toolbar_show_buttons));
+ ro_toolbar_set_display_url(new_gui->toolbar,
+ nsoption_bool(toolbar_show_address));
+ ro_toolbar_set_display_throbber(new_gui->toolbar,
+ nsoption_bool(toolbar_show_throbber));
+ if ((old_gui) && (old_gui->toolbar)) {
+ 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);
+ }
+ }
}
/**
- * Scroll a browser window, either via the core or directly using the
- * normal Wimp_OpenWindow interface.
- *
- * Scroll steps are supplied in terms of the (extended) Scroll Event direction
- * values returned by Wimp_Poll. Special values of 0x7fffffff and 0x80000000
- * are added to mean "Home" and "End".
+ * Create and open a new browser window.
*
- * \param *g The GUI Window to be scrolled.
- * \param scroll_x The X scroll step to be applied.
- * \param scroll_y The Y scroll step to be applied.
+ * \param bw bw to create gui_window for
+ * \param existing an existing gui_window, may be NULL
+ * \param flags flags for gui window creation
+ * \return gui window, or NULL on error
*/
-
-void ro_gui_window_scroll_action(struct gui_window *g,
- wimp_scroll_direction scroll_x, wimp_scroll_direction scroll_y)
+static struct gui_window *gui_window_create(struct browser_window *bw,
+ struct gui_window *existing,
+ gui_window_create_flags flags)
{
- int visible_x, visible_y;
- int step_x = 0, step_y = 0;
- int toolbar_y;
- wimp_window_state state;
- wimp_pointer pointer;
- os_error *error;
- os_coord pos;
- bool handled = false;
- struct toolbar *toolbar;
+ int screen_width, screen_height;
+ static int window_count = 2;
+ wimp_window window;
+ wimp_window_state state;
+ os_error *error;
+ bool open_centred = true;
+ struct gui_window *g;
- if (g == NULL)
- return;
+ g = malloc(sizeof *g);
+ if (!g) {
+ ro_warn_user("NoMemory", 0);
+ return 0;
+ }
+ g->bw = bw;
+ g->toolbar = 0;
+ g->status_bar = 0;
+ g->old_width = 0;
+ g->old_height = 0;
+ g->update_extent = true;
+ g->active = false;
+ strcpy(g->title, "NetSurf");
+ g->iconise_icon = -1;
+ g->scale = browser_window_get_scale(bw);
- /* Get the current window, toolbar and pointer details. */
+ /* Set the window position */
+ if (existing != NULL &&
+ flags & GW_CREATE_CLONE &&
+ nsoption_bool(window_size_clone)) {
+ state.w = existing->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ window.visible.x0 = state.visible.x0;
+ window.visible.x1 = state.visible.x1;
+ window.visible.y0 = state.visible.y0 - 48;
+ window.visible.y1 = state.visible.y1 - 48;
+ open_centred = false;
+ } else {
+ int win_width, win_height;
+ ro_gui_screen_size(&screen_width, &screen_height);
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- return;
+ /* Check if we have a preferred position */
+ if ((nsoption_int(window_screen_width) != 0) &&
+ (nsoption_int(window_screen_height) != 0)) {
+ win_width = (nsoption_int(window_width) *
+ screen_width) /
+ nsoption_int(window_screen_width);
+ win_height = (nsoption_int(window_height) *
+ screen_height) /
+ nsoption_int(window_screen_height);
+ window.visible.x0 = (nsoption_int(window_x) *
+ screen_width) /
+ nsoption_int(window_screen_width);
+ window.visible.y0 = (nsoption_int(window_y) *
+ screen_height) /
+ nsoption_int(window_screen_height);
+ if (nsoption_bool(window_stagger)) {
+ window.visible.y0 += 96 -
+ (48 * (window_count % 5));
+ }
+ open_centred = false;
+ if (win_width < 100)
+ win_width = 100;
+ if (win_height < 100)
+ win_height = 100;
+ } else {
+
+ /* Base how we define the window height/width
+ on the compile time options set */
+ win_width = screen_width * 3 / 4;
+ if (1600 < win_width)
+ win_width = 1600;
+ win_height = win_width * 3 / 4;
+
+ window.visible.x0 = (screen_width - win_width) / 2;
+ window.visible.y0 = ((screen_height - win_height) / 2) +
+ 96 - (48 * (window_count % 5));
+ }
+ window.visible.x1 = window.visible.x0 + win_width;
+ window.visible.y1 = window.visible.y0 + win_height;
}
- toolbar = ro_toolbar_parent_window_lookup(g->window);
- assert(g == NULL || g->toolbar == NULL || g->toolbar == toolbar);
+ /* General flags for a non-movable, non-resizable, no-title bar window */
+ window.xscroll = 0;
+ window.yscroll = 0;
+ window.next = wimp_TOP;
+ window.flags = wimp_WINDOW_MOVEABLE |
+ wimp_WINDOW_NEW_FORMAT |
+ wimp_WINDOW_VSCROLL |
+ wimp_WINDOW_HSCROLL |
+ wimp_WINDOW_IGNORE_XEXTENT |
+ wimp_WINDOW_IGNORE_YEXTENT |
+ wimp_WINDOW_SCROLL_REPEAT;
+ window.title_fg = wimp_COLOUR_BLACK;
+ window.title_bg = wimp_COLOUR_LIGHT_GREY;
+ window.work_fg = wimp_COLOUR_LIGHT_GREY;
+ window.work_bg = wimp_COLOUR_TRANSPARENT;
+ window.scroll_outer = wimp_COLOUR_DARK_GREY;
+ window.scroll_inner = wimp_COLOUR_MID_LIGHT_GREY;
+ window.highlight_bg = wimp_COLOUR_CREAM;
+ window.extra_flags = wimp_WINDOW_USE_EXTENDED_SCROLL_REQUEST |
+ wimp_WINDOW_GIVE_SHADED_ICON_INFO;
+ window.extent.x0 = 0;
+ window.extent.y0 = -(window.visible.y1 - window.visible.y0);
+ window.extent.x1 = window.visible.x1 - window.visible.x0;
+ window.extent.y1 = 0;
+ window.title_flags = wimp_ICON_TEXT |
+ wimp_ICON_INDIRECTED |
+ wimp_ICON_HCENTRED;
+ window.work_flags = wimp_BUTTON_DOUBLE_CLICK_DRAG <<
+ wimp_ICON_BUTTON_TYPE_SHIFT;
+ window.sprite_area = wimpspriteop_AREA;
+ window.xmin = 1;
+ window.ymin = 1;
+ window.title_data.indirected_text.text = g->title;
+ window.title_data.indirected_text.validation = (char *) -1;
+ window.title_data.indirected_text.size = 255;
+ window.icon_count = 0;
- toolbar_y = (toolbar == NULL) ? 0 : ro_toolbar_full_height(toolbar);
+ /* Add in flags */
+ window.flags |= wimp_WINDOW_SIZE_ICON |
+ wimp_WINDOW_BACK_ICON |
+ wimp_WINDOW_CLOSE_ICON |
+ wimp_WINDOW_TITLE_ICON |
+ wimp_WINDOW_TOGGLE_ICON;
- visible_x = state.visible.x1 - state.visible.x0 - 32;
- visible_y = state.visible.y1 - state.visible.y0 - 32 - toolbar_y;
+ if (open_centred) {
+ int scroll_width = ro_get_vscroll_width(NULL);
+ window.visible.x0 -= scroll_width;
+ }
- error = xwimp_get_pointer_info(&pointer);
+ error = xwimp_create_window(&window, &g->window);
if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
- return;
+ free(g);
+ return 0;
}
- /* Turn the scroll requirement from Scroll Event codes into coordinates
- * that the core can understand.
- */
+ /* Link into window list */
+ g->prev = 0;
+ g->next = window_list;
+ if (window_list)
+ window_list->prev = g;
+ window_list = g;
+ window_count++;
- switch (scroll_x) {
- case wimp_SCROLL_PAGE_LEFT:
- step_x = SCROLL_PAGE_DOWN;
- break;
- case wimp_SCROLL_AUTO_LEFT:
- case wimp_SCROLL_COLUMN_LEFT:
- step_x = -16;
- break;
- case wimp_SCROLL_AUTO_RIGHT:
- case wimp_SCROLL_COLUMN_RIGHT:
- step_x = 16;
- break;
- case wimp_SCROLL_PAGE_RIGHT:
- step_x = SCROLL_PAGE_UP;
- break;
- case 0x80000000:
- step_x = SCROLL_BOTTOM;
- break;
- case 0x7fffffff:
- step_x = SCROLL_TOP;
- break;
- default:
- step_x = (visible_x * (scroll_x>>2)) >> 2;
- break;
+ /* Add in a toolbar and status bar */
+ g->status_bar = ro_gui_status_bar_create(g->window,
+ nsoption_int(toolbar_status_size));
+ 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,
+ nsoption_charp(toolbar_browser));
+ ro_toolbar_add_url(g->toolbar);
+ ro_toolbar_add_throbber(g->toolbar);
+ ro_toolbar_rebuild(g->toolbar);
}
- switch (scroll_y) {
- case wimp_SCROLL_PAGE_UP:
- step_y = SCROLL_PAGE_UP;
- break;
- case wimp_SCROLL_AUTO_UP:
- case wimp_SCROLL_LINE_UP:
- step_y = -16;
- break;
- case wimp_SCROLL_AUTO_DOWN:
- case wimp_SCROLL_LINE_DOWN:
- step_y = 16;
- break;
- case wimp_SCROLL_PAGE_DOWN:
- step_y = SCROLL_PAGE_DOWN;
- break;
- case 0x80000000:
- step_y = SCROLL_BOTTOM;
- break;
- case 0x7fffffff:
- step_y = SCROLL_TOP;
- break;
- default:
- step_y = -((visible_y * (scroll_y>>2)) >> 2);
- break;
- }
+ /* 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_scroll_window(g->window,
+ ro_gui_window_scroll);
+ ro_gui_wimp_event_register_pointer_entering_window(g->window,
+ ro_gui_window_pointer_entering);
+ ro_gui_wimp_event_register_keypress(g->window,
+ 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);
- /* If no scrolling is required, there's no point trying to do any. */
+ /* Set the window options */
+ ro_gui_window_clone_options(g, existing);
+ ro_gui_window_update_toolbar_buttons(g);
- if (step_x == 0 && step_y == 0)
- return;
+ /* Open the window at the top of the stack */
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return g;
+ }
- /* If the pointer is over the window being scrolled, then try to get
- * the core to do the scrolling on the object under the pointer.
- */
+ state.next = wimp_TOP;
- if (pointer.w == g->window &&
- ro_gui_window_to_window_pos(g,
- pointer.pos.x, pointer.pos.y, &pos))
- handled = browser_window_scroll_at_point(g->bw, pos.x, pos.y,
- step_x, step_y);
+ ro_gui_window_open(PTR_WIMP_OPEN(&state));
- /* If the core didn't do the scrolling, handle it via the Wimp.
- * Windows which contain frames can only be scrolled by the core,
- * because it implements frame scroll bars.
- */
+ /* Claim the caret */
+ if (ro_toolbar_take_caret(g->toolbar)) {
+ ro_gui_url_complete_start(g->toolbar);
+ } else {
+ gui_window_place_caret(g, -100, -100, 0, NULL);
+ }
- if (!handled && (browser_window_is_frameset(g->bw) == false)) {
- switch (step_x) {
- case SCROLL_TOP:
- state.xscroll -= 0x10000000;
- break;
- case SCROLL_BOTTOM:
- state.xscroll += 0x10000000;
- break;
- case SCROLL_PAGE_UP:
- state.xscroll += visible_x;
- break;
- case SCROLL_PAGE_DOWN:
- state.xscroll -= visible_x;
- break;
- default:
- state.xscroll += 2 * step_x;
- break;
- }
+ return g;
+}
- switch (step_y) {
- case SCROLL_TOP:
- state.yscroll += 0x10000000;
- break;
- case SCROLL_BOTTOM:
- state.yscroll -= 0x10000000;
- break;
- case SCROLL_PAGE_UP:
- state.yscroll += visible_y;
- break;
- case SCROLL_PAGE_DOWN:
- state.yscroll -= visible_y;
- break;
- default:
- state.yscroll -= 2 * step_y;
- break;
- }
- error = xwimp_open_window((wimp_open *) &state);
- if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+/**
+ * Remove all pending update boxes for a window
+ *
+ * \param g gui_window
+ */
+static 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;
}
}
}
/**
- * Handle Message_DataLoad (file dragged in) for a window.
- *
- * \param g window
- * \param message Message_DataLoad block
- * \return true if the load was processed
+ * Close a browser window and free any related resources.
*
- * If the file was dragged into a form file input, it is used as the value.
+ * \param g gui_window to destroy
*/
-
-bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
+static void gui_window_destroy(struct gui_window *g)
{
os_error *error;
- os_coord pos;
+ wimp_w w;
- /* Ignore directories etc. */
- if (0x1000 <= message->data.data_xfer.file_type)
- return false;
+ assert(g);
- if (!ro_gui_window_to_window_pos(g, message->data.data_xfer.pos.x,
- message->data.data_xfer.pos.y, &pos))
- return false;
+ /* stop any tracking */
+ ro_mouse_kill(g);
- if (browser_window_drop_file_at_point(g->bw, pos.x, pos.y,
- message->data.data_xfer.file_name) == false)
- return false;
+ /* remove from list */
+ if (g->prev)
+ g->prev->next = g->next;
+ else
+ window_list = g->next;
+ if (g->next)
+ g->next->prev = g->prev;
- /* send DataLoadAck */
- message->action = message_DATA_LOAD_ACK;
- message->your_ref = message->my_ref;
- error = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
+ /* destroy toolbar */
+ if (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();
+ ro_gui_dialog_close_persistent(w);
+ if (current_menu_window == w)
+ ro_gui_menu_destroy();
+ ro_gui_window_remove_update_boxes(g);
+
+ /* delete window */
+ error = xwimp_delete_window(w);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
+ LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
+ ro_gui_wimp_event_finalise(w);
- return true;
+ free(g);
}
/**
- * Handle pointer movements in a browser window.
+ * Set the title of a browser window.
*
- * \param *pointer new mouse position
- * \param *data browser window that the pointer is in
+ * \param g gui_window to update
+ * \param title new window title, copied
*/
-
-void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data)
+static void gui_window_set_title(struct gui_window *g, const char *title)
{
- os_coord pos;
- struct gui_window *g = (struct gui_window *) data;
+ assert(g);
+ assert(title);
- 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_DOUBLE_CLICK_DRAG),
- pos.x, pos.y);
+ if (g->scale != 1.0) {
+ int scale_disp = g->scale * 100;
+
+ if (ABS((float)scale_disp - g->scale * 100) >= 0.05)
+ snprintf(g->title, sizeof g->title, "%s (%.1f%%)",
+ title, g->scale * 100);
+ else
+ snprintf(g->title, sizeof g->title, "%s (%i%%)",
+ title, scale_disp);
+ } else {
+ strncpy(g->title, title, sizeof g->title);
+ }
+
+ ro_gui_set_window_title(g->window, g->title);
}
/**
- * 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
+ * Get the scroll position of a browser window.
*
- * \param g the gui window being iconised
- * \param wi the WindowInfo message from the iconiser
+ * \param g gui_window
+ * \param sx receives x ordinate of point at top-left of window
+ * \param sy receives y ordinate of point at top-left of window
+ * \return true iff successful
*/
+static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
+{
+ wimp_window_state state;
+ os_error *error;
+ int toolbar_height = 0;
+
+ 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);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
+ }
-void ro_gui_window_iconise(struct gui_window *g,
- wimp_full_message_window_info *wi)
+ if (g->toolbar)
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
+ *sx = state.xscroll / (2 * g->scale);
+ *sy = -(state.yscroll - toolbar_height) / (2 * g->scale);
+ return true;
+}
+
+
+/**
+ * Set the scroll position of a riscos browser window.
+ *
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown.
+ *
+ * \param g gui window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror
+gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
{
- /* 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;
- struct hlcache_handle *h;
+ wimp_window_state state;
os_error *error;
- int len, id;
+ int toolbar_height = 0;
- assert(bw);
+ assert(g);
- h = browser_window_get_content(bw);
- if (!h) return;
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return NSERROR_BAD_PARAMETER;
+ }
- /* 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);
- ro_warn_user("MiscError", error->errmess);
- overlay = NULL;
+ if (g->toolbar) {
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
+ }
+
+ if ((rect->x0 == rect->x1) && (rect->y0 == rect->y1)) {
+ /* scroll to top */
+ state.xscroll = rect->x0 * 2 * g->scale;
+ state.yscroll = (-rect->y0 * 2 * g->scale) + toolbar_height;
+ } else {
+ /* scroll area into view with padding */
+ int x0, y0, x1, y1;
+ int cx0, cy0, width, height;
+ int padding_available;
+ int correction;
+
+ x0 = rect->x0 * 2 * g->scale;
+ y0 = rect->y0 * 2 * g->scale;
+ x1 = rect->x1 * 2 * g->scale;
+ y1 = rect->y1 * 2 * g->scale;
+
+ cx0 = state.xscroll;
+ cy0 = -state.yscroll + toolbar_height;
+ width = state.visible.x1 - state.visible.x0;
+ height = state.visible.y1 - state.visible.y0 - toolbar_height;
+
+ /* make sure we're visible */
+ correction = (x1 - cx0 - width);
+ if (correction > 0) {
+ cx0 += correction;
}
- else if (sprite_bpp(overlay) != 8) {
- LOG("overlay sprite is not 8bpp");
- overlay = NULL;
+ correction = (y1 - cy0 - height);
+ if (correction > 0) {
+ cy0 += correction;
+ }
+ if (x0 < cx0) {
+ cx0 = x0;
+ }
+ if (y0 < cy0) {
+ cy0 = y0;
}
- }
- /* create the thumbnail sprite */
- bitmap = riscos_bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE |
- BITMAP_CLEAR_MEMORY);
- if (!bitmap) {
- LOG("Thumbnail initialisation failed.");
- return;
+ /* try to give a SCROLL_VISIBLE_PADDING border of space around us */
+ padding_available = (width - x1 + x0) / 2;
+ if (padding_available > 0) {
+ if (padding_available > SCROLL_VISIBLE_PADDING) {
+ padding_available = SCROLL_VISIBLE_PADDING;
+ }
+ correction = (cx0 + width - x1);
+ if (correction < padding_available) {
+ cx0 += padding_available;
+ }
+ correction = (x0 - cx0);
+ if (correction < padding_available) {
+ cx0 -= padding_available;
+ }
+ }
+ padding_available = (height - y1 + y0) / 2;
+ if (padding_available > 0) {
+ if (padding_available > SCROLL_VISIBLE_PADDING) {
+ padding_available = SCROLL_VISIBLE_PADDING;
+ }
+ correction = (cy0 + height - y1);
+ if (correction < padding_available) {
+ cy0 += padding_available;
+ }
+ correction = (y0 - cy0);
+ if (correction < padding_available) {
+ cy0 -= padding_available;
+ }
+ }
+
+ state.xscroll = cx0;
+ state.yscroll = -cy0 + toolbar_height;
}
- riscos_bitmap_render(bitmap, h);
- if (overlay) {
- riscos_bitmap_overlay_sprite(bitmap, overlay);
+ ro_gui_window_open(PTR_WIMP_OPEN(&state));
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Find the current dimensions of a browser window's content area.
+ *
+ * \param gw gui window to measure
+ * \param width receives width of window
+ * \param height receives height of window
+ * \param scaled whether to return scaled values
+ */
+static nserror
+gui_window_get_dimensions(struct gui_window *gw,
+ int *width, int *height,
+ bool scaled)
+{
+ /* use the cached window sizes */
+ *width = gw->old_width / 2;
+ *height = gw->old_height / 2;
+
+ if (scaled) {
+ *width /= gw->scale;
+ *height /= gw->scale;
}
- area = riscos_bitmap_convert_8bpp(bitmap);
- riscos_bitmap_destroy(bitmap);
- if (!area) {
- LOG("Thumbnail conversion failed.");
- return;
+ return NSERROR_OK;
+}
+
+
+/**
+ * Set the status bar of a browser window.
+ *
+ * \param g gui_window to update
+ * \param text new status text
+ */
+static void riscos_window_set_status(struct gui_window *g, const char *text)
+{
+ if (g->status_bar) {
+ ro_gui_status_bar_set_text(g->status_bar, text);
}
+}
- /* 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);
+/**
+ * Update the interface to reflect start of page loading.
+ *
+ * \param g window with start of load
+ */
+static void gui_window_start_throbber(struct gui_window *g)
+{
+ 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);
+ g->active = true;
+}
- 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);
- ro_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);
- ro_warn_user("WimpError", error->errmess);
- remove(temp_fname);
- free(area);
+
+/**
+ * Update the interface to reflect page loading stopped.
+ *
+ * \param g window with start of load
+ */
+static void gui_window_stop_throbber(struct gui_window *g)
+{
+ 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);
+ g->active = false;
+}
+
+/**
+ * set favicon
+ */
+static void
+gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon)
+{
+ if (g == NULL || g->toolbar == NULL)
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';
+ ro_toolbar_set_site_favicon(g->toolbar, icon);
+}
- 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);
+
+/**
+ * Remove the caret, if present.
+ *
+ * \param g window with caret
+ */
+static void gui_window_remove_caret(struct gui_window *g)
+{
+ wimp_caret caret;
+ os_error *error;
+
+ error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
+ LOG("xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
+ return;
}
- else {
- g->iconise_icon = id;
- iconise_used[id] = true;
+
+ if (caret.w == g->window) {
+ /* we have the caret: hide caret, but keep input focus */
+ gui_window_place_caret(g, -100, -100, 0, NULL);
}
+}
- free(area);
+
+/**
+ * Called when the gui_window has new content.
+ *
+ * \param g the gui_window that has new content
+ */
+static void gui_window_new_content(struct gui_window *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);
}
/**
* Completes scrolling of a browser window
*
- * \param *drag The DragEnd event data block.
- * \param *data gui window block pointer.
+ * \param drag The DragEnd event data block.
+ * \param data gui window block pointer.
*/
-
static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data)
{
wimp_pointer pointer;
@@ -3503,611 +3799,703 @@ static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data)
/**
- * 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.
+ * Starts drag scrolling of a browser window
*
- * \param *data The GUI window associated with the click.
- * \param action_type The action type to be handled.
- * \param action The action to process.
+ * \param g the window to scroll
*/
-
-void ro_gui_window_toolbar_click(void *data,
- toolbar_action_type action_type, union toolbar_action action)
+static bool gui_window_scroll_start(struct gui_window *g)
{
- struct gui_window *g = data;
- nserror err;
-
- if (g == NULL)
- return;
-
-
- if (action_type == TOOLBAR_ACTION_URL) {
- switch (action.url) {
- case TOOLBAR_URL_DRAG_URL:
- {
- gui_save_type save_type;
-
- if (!browser_window_has_content(g->bw))
- break;
-
- 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,
- browser_window_get_url(g->bw),
- browser_window_get_title(g->bw), g);
- }
- break;
-
- case TOOLBAR_URL_SELECT_HOTLIST:
- ro_gui_window_action_add_bookmark(g);
- break;
-
- case TOOLBAR_URL_ADJUST_HOTLIST:
- ro_gui_window_action_remove_bookmark(g);
- break;
-
- default:
- break;
- }
+ wimp_window_info_base info;
+ wimp_pointer pointer;
+ os_error *error;
+ wimp_drag drag;
+ int height;
+ int width;
- return;
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
}
+ info.w = g->window;
+ error = xwimp_get_window_info_header_only((wimp_window_info*)&info);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
+ }
- /* 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)
- browser_window_history_back(g->bw, false);
- break;
-
- case TOOLBAR_BUTTON_BACK_NEW:
- if (g->bw != NULL)
- browser_window_history_back(g->bw, true);
- break;
-
- case TOOLBAR_BUTTON_FORWARD:
- if (g->bw != NULL)
- browser_window_history_forward(g->bw, false);
- break;
-
- case TOOLBAR_BUTTON_FORWARD_NEW:
- if (g->bw != NULL)
- browser_window_history_forward(g->bw, true);
- 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_present();
- break;
+ width = info.extent.x1 - info.extent.x0;
+ height = info.extent.y1 - info.extent.y0;
- case TOOLBAR_BUTTON_HOME:
- ro_gui_window_action_home(g);
- break;
+ drag.type = wimp_DRAG_USER_POINT;
+ drag.bbox.x1 = pointer.pos.x + info.xscroll;
+ drag.bbox.y0 = pointer.pos.y + info.yscroll;
+ drag.bbox.x0 = drag.bbox.x1 - (width - (info.visible.x1 - info.visible.x0));
+ drag.bbox.y1 = drag.bbox.y0 + (height - (info.visible.y1 - info.visible.y0));
- case TOOLBAR_BUTTON_SEARCH:
- ro_gui_window_action_search(g);
- break;
+ if (g->toolbar) {
+ int tbar_height = ro_toolbar_full_height(g->toolbar);
+ drag.bbox.y0 -= tbar_height;
+ drag.bbox.y1 -= tbar_height;
+ }
- case TOOLBAR_BUTTON_SCALE:
- ro_gui_window_action_zoom(g);
- break;
+ error = xwimp_drag_box(&drag);
+ if (error) {
+ LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
+ }
- case TOOLBAR_BUTTON_BOOKMARK_OPEN:
- ro_gui_hotlist_present();
- break;
+ ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at,
+ NULL, g);
+ return true;
+}
- 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;
+/**
+ * Platform-dependent part of starting drag operation.
+ *
+ * \param g gui window containing the drag
+ * \param type type of drag the core is performing
+ * \param rect rectangle to constrain pointer to (relative to drag start coord)
+ * \return true iff succesful
+ */
+static bool
+gui_window_drag_start(struct gui_window *g,
+ gui_drag_type type,
+ const struct rect *rect)
+{
+ wimp_pointer pointer;
+ wimp_drag drag;
- case TOOLBAR_BUTTON_SAVE_COMPLETE:
- ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
- break;
+ if (rect != NULL) {
+ /* We have a box to constrain the pointer to, for the drag
+ * duration */
+ os_error *error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
+ }
- case TOOLBAR_BUTTON_PRINT:
- ro_gui_window_action_print(g);
- break;
+ drag.type = wimp_DRAG_USER_POINT;
+ drag.bbox.x0 = pointer.pos.x +
+ (int)(rect->x0 * 2 * g->scale);
+ drag.bbox.y0 = pointer.pos.y +
+ (int)(rect->y0 * 2 * g->scale);
+ drag.bbox.x1 = pointer.pos.x +
+ (int)(rect->x1 * 2 * g->scale);
+ drag.bbox.y1 = pointer.pos.y +
+ (int)(rect->y1 * 2 * g->scale);
- case TOOLBAR_BUTTON_UP:
- err = browser_window_navigate_up(g->bw, false);
- if (err != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(err), NULL);
+ error = xwimp_drag_box(&drag);
+ if (error) {
+ LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
}
- break;
+ }
- case TOOLBAR_BUTTON_UP_NEW:
- err = browser_window_navigate_up(g->bw, true);
- if (err != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(err), NULL);
- }
+ switch (type) {
+ case GDRAGGING_SCROLLBAR:
+ /* Dragging a core scrollbar */
+ ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at,
+ NULL, g);
break;
default:
+ /* Not handled here yet */
break;
}
- ro_gui_window_update_toolbar_buttons(g);
+ return true;
}
/**
- * 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.
+ * Save the specified content as a link.
*
- * \param g window
- * \param message Message_DataLoad block
- * \return true if the load was processed
+ * \param g The window containing the content
+ * \param url The url of the link
+ * \param title The title of the link
*/
-
-bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
+static nserror
+gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
{
- if (message->data.data_xfer.file_type == osfile_TYPE_TEXT &&
- ro_gui_window_import_text(g,
- message->data.data_xfer.file_name)) {
- os_error *error;
-
- /* send DataLoadAck */
- message->action = message_DATA_LOAD_ACK;
- message->your_ref = message->my_ref;
- error = xwimp_send_message(wimp_USER_MESSAGE, message,
- message->sender);
- if (error) {
- LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- return true;
- }
- return false;
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, url, title);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
+ return NSERROR_OK;
}
-/*
- * Helper code for the Wimp Event Handlers.
- */
-
/**
- * Check if a particular menu handle is a browser window menu
+ * Display a menu of options for a form select control.
*
- * \param *menu The menu in question.
- * \return true if this menu is a browser window menu
+ * \param g gui window containing form control
+ * \param control form control of type GADGET_SELECT
*/
-
-bool ro_gui_window_check_menu(wimp_menu *menu)
+static void
+gui_window_create_form_select_menu(struct gui_window *g,
+ struct form_control *control)
{
- 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.
- */
+ os_error *error;
+ wimp_pointer pointer;
-bool ro_gui_window_content_export_types(struct hlcache_handle *h,
- bool *export_draw, bool *export_sprite)
-{
- bool found_type = false;
+ /* 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 (export_draw != NULL)
- *export_draw = false;
- if (export_sprite != NULL)
- *export_sprite = false;
+ if (!ro_gui_window_prepare_form_select_menu(g, control))
+ return;
- if (h != NULL && content_get_type(h) == CONTENT_IMAGE) {
- switch (ro_content_native_type(h)) {
- case osfile_TYPE_SPRITE:
- /* bitmap types (Sprite export possible) */
- found_type = true;
- if (export_sprite != NULL)
- *export_sprite = true;
- break;
- case osfile_TYPE_DRAW:
- /* vector types (Draw export possible) */
- found_type = true;
- if (export_draw != NULL)
- *export_draw = true;
- break;
- default:
- break;
- }
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ ro_gui_menu_destroy();
+ return;
}
- return found_type;
+ gui_form_select_control = control;
+ ro_gui_menu_create(gui_form_select_menu,
+ pointer.pos.x, pointer.pos.y, g->window);
}
/**
- * Prepare the page info window for use.
+ * Import text file into window
*
- * \param *g The GUI window block to use.
+ * \param g gui window containing textarea
+ * \param filename pathname of file to be imported
+ * \return true iff successful
*/
-
-void ro_gui_window_prepare_pageinfo(struct gui_window *g)
+static bool
+ro_gui_window_import_text(struct gui_window *g, const char *filename)
{
- struct hlcache_handle *h = browser_window_get_content(g->bw);
- char icon_buf[20] = "file_xxx";
- char enc_buf[40];
- const char *icon = icon_buf;
- const char *title, *url;
- lwc_string *mime;
- const char *enc = "-";
-
- assert(h);
-
- title = content_get_title(h);
- if (title == NULL)
- title = "-";
- url = nsurl_access(hlcache_handle_get_url(h));
- if (url == NULL)
- url = "-";
- mime = content_get_mime_type(h);
-
- sprintf(icon_buf, "file_%x", ro_content_filetype(h));
- if (!ro_gui_wimp_sprite_exists(icon_buf))
- sprintf(icon_buf, "file_xxx");
+ fileswitch_object_type obj_type;
+ os_error *error;
+ char *buf, *utf8_buf, *sp;
+ int size;
+ nserror ret;
+ const char *ep;
+ char *p;
- if (content_get_type(h) == CONTENT_HTML) {
- if (content_get_encoding(h, CONTENT_ENCODING_NORMAL)) {
- snprintf(enc_buf, sizeof enc_buf, "%s (%s)",
- content_get_encoding(h, CONTENT_ENCODING_NORMAL),
- content_get_encoding(h, CONTENT_ENCODING_SOURCE));
- enc = enc_buf;
- } else {
- enc = messages_get("EncodingUnk");
- }
+ 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);
+ ro_warn_user("FileError", error->errmess);
+ return true; /* was for us, but it didn't work! */
}
- 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,
- lwc_string_data(mime), true);
-
- lwc_string_unref(mime);
-}
-
+ /* Allocate one byte more than needed to ensure that the buffer is
+ * always terminated, regardless of file contents.
+ */
-/**
- * Prepare the object info window for use
- *
- * \param *object the object for which information is to be displayed
- * \param *target_url corresponding url, if any
- */
+ buf = calloc(size + 1, sizeof(char));
+ if (!buf) {
+ ro_warn_user("NoMemory", NULL);
+ return true;
+ }
-void ro_gui_window_prepare_objectinfo(struct hlcache_handle *object, nsurl *target_url)
-{
- char icon_buf[20] = "file_xxx";
- const char *url;
- lwc_string *mime;
- const char *target = "-";
+ error = xosfile_load_stamped(filename, (byte*)buf,
+ NULL, NULL, NULL, NULL, NULL);
- sprintf(icon_buf, "file_%.3x",ro_content_filetype(object));
- if (!ro_gui_wimp_sprite_exists(icon_buf)) {
- sprintf(icon_buf, "file_xxx");
+ if (error) {
+ LOG("xosfile_load_stamped: 0x%x:%s", error->errnum, error->errmess);
+ ro_warn_user("LoadError", error->errmess);
+ free(buf);
+ return true;
}
- url = nsurl_access(hlcache_handle_get_url(object));
- if (url == NULL) {
- url = "-";
+ ret = utf8_from_local_encoding(buf, size, &utf8_buf);
+ if (ret != NSERROR_OK) {
+ /* bad encoding shouldn't happen */
+ assert(ret != NSERROR_BAD_ENCODING);
+ LOG("utf8_from_local_encoding failed");
+ free(buf);
+ ro_warn_user("NoMemory", NULL);
+ return true;
}
- mime = content_get_mime_type(object);
+ size = strlen(utf8_buf);
- if (target_url != NULL) {
- target = nsurl_access(target_url);
- }
+ ep = utf8_buf + size;
+ p = utf8_buf;
- 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,
- lwc_string_data(mime), true);
+ /* skip leading whitespace */
+ while (isspace(*p)) p++;
- lwc_string_unref(mime);
-}
+ 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);
+
+ free(buf);
+ free(utf8_buf);
+ return true;
+}
-/*
- * User Actions in the browser window
- */
/**
- * Launch a new url in the given window.
- *
- * \param g gui_window to update
- * \param url1 url to be launched
+ * RISC OS browser window operation table
*/
+static struct gui_window_table window_table = {
+ .create = gui_window_create,
+ .destroy = gui_window_destroy,
+ .invalidate = ro_gui_window_invalidate_area,
+ .get_scroll = gui_window_get_scroll,
+ .set_scroll = gui_window_set_scroll,
+ .get_dimensions = gui_window_get_dimensions,
+ .update_extent = gui_window_update_extent,
-void ro_gui_window_launch_url(struct gui_window *g, const char *url1)
-{
- nserror error;
- nsurl *url;
-
- if (url1 == NULL)
- return;
-
- ro_gui_url_complete_close();
+ .set_title = gui_window_set_title,
+ .set_url = ro_gui_window_set_url,
+ .set_icon = gui_window_set_icon,
+ .set_status = riscos_window_set_status,
+ .set_pointer = gui_window_set_pointer,
+ .place_caret = gui_window_place_caret,
+ .remove_caret = gui_window_remove_caret,
+ .save_link = gui_window_save_link,
+ .drag_start = gui_window_drag_start,
+ .scroll_start = gui_window_scroll_start,
+ .new_content = gui_window_new_content,
+ .start_throbber = gui_window_start_throbber,
+ .stop_throbber = gui_window_stop_throbber,
+ .create_form_select_menu = gui_window_create_form_select_menu,
- error = nsurl_create(url1, &url);
- if (error != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(error), 0);
- } else {
- ro_gui_window_set_url(g, url);
+ /* from save */
+ .drag_save_object = gui_drag_save_object,
+ .drag_save_selection =gui_drag_save_selection,
- browser_window_navigate(g->bw, url,
- NULL, BW_NAVIGATE_HISTORY,
- NULL, NULL, NULL);
- nsurl_unref(url);
- }
-}
+ /* from textselection */
+ .start_selection = gui_start_selection,
+};
+struct gui_window_table *riscos_window_table = &window_table;
-/**
- * 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)
+/* exported interface documented in riscos/window.h */
+void ro_gui_window_initialise(void)
{
- static const char *addr = NETSURF_HOMEPAGE;
- nsurl *url;
- nserror error;
-
- if (g == NULL || g->bw == NULL)
- return;
+ /* Build the browser window menu. */
- if (nsoption_charp(homepage_url) != NULL) {
- addr = nsoption_charp(homepage_url);
- }
+ 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.HelpCredits", HELP_OPEN_CREDITS, 0 },
+ { "_Help.HelpLicence", HELP_OPEN_LICENCE, 0 },
+ { "Help.HelpInter", HELP_LAUNCH_INTERACTIVE, 0 },
+ {NULL, 0, 0}
+ }
+ };
+ ro_gui_browser_window_menu =
+ ro_gui_menu_define_menu(&browser_definition);
- error = nsurl_create(addr, &url);
- if (error == NSERROR_OK) {
- error = browser_window_navigate(g->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- if (error != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(error), 0);
- }
}
-/**
- * Open a new browser window.
- *
- * \param *g The browser window to act on.
- */
-
-void ro_gui_window_action_new_window(struct gui_window *g)
+/* exported interface documented in riscos/window.h */
+nserror
+ro_gui_window_invalidate_area(struct gui_window *g, const struct rect *rect)
{
- nserror error;
+ bool use_buffer;
+ int x0, y0, x1, y1;
+ struct update_box *cur;
+ wimp_window_info info;
+ os_error *error;
- if (g == NULL || g->bw == NULL)
- return;
+ assert(g);
- error = browser_window_create(BW_CREATE_CLONE,
- browser_window_get_url(g->bw),
- NULL, g->bw, NULL);
+ if (rect == NULL) {
+ info.w = g->window;
+ error = xwimp_get_window_info_header_only(&info);
+ if (error) {
+ LOG("xwimp_get_window_info_header_only: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return NSERROR_INVALID;
+ }
- if (error != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(error), 0);
+ error = xwimp_force_redraw(g->window,
+ info.extent.x0, info.extent.y0,
+ info.extent.x1, info.extent.y1);
+ if (error) {
+ LOG("xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
}
+
+ x0 = floorf(rect->x0 * 2 * g->scale);
+ y0 = -ceilf(rect->y1 * 2 * g->scale);
+ x1 = ceilf(rect->x1 * 2 * g->scale) + 1;
+ y1 = -floorf(rect->y0 * 2 * g->scale) + 1;
+ use_buffer =
+ (g->option.buffer_everything || g->option.buffer_animations);
+
+ /* try to optimise buffered redraws */
+ if (use_buffer) {
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ if ((cur->g != g) || (!cur->use_buffer)) {
+ continue;
+ }
+ if ((((cur->x0 - x1) < MARGIN) ||
+ ((cur->x1 - x0) < MARGIN)) &&
+ (((cur->y0 - y1) < MARGIN) ||
+ ((cur->y1 - y0) < MARGIN))) {
+ cur->x0 = min(cur->x0, x0);
+ cur->y0 = min(cur->y0, y0);
+ cur->x1 = max(cur->x1, x1);
+ cur->y1 = max(cur->y1, y1);
+ return NSERROR_OK;
+ }
+ }
+ }
+ cur = malloc(sizeof(struct update_box));
+ if (!cur) {
+ LOG("No memory for malloc.");
+ return NSERROR_NOMEM;
+ }
+
+ cur->x0 = x0;
+ cur->y0 = y0;
+ cur->x1 = x1;
+ cur->y1 = y1;
+ cur->next = pending_updates;
+ pending_updates = cur;
+ cur->g = g;
+ cur->use_buffer = use_buffer;
+
+ return NSERROR_OK;
}
-/**
- * Open a local history pane for a browser window.
- *
- * \param gw The browser window to act on.
- */
-void ro_gui_window_action_local_history(struct gui_window *gw)
+/* exported function documented in riscos/window.h */
+nserror ro_gui_window_set_url(struct gui_window *g, nsurl *url)
{
- nserror res;
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
- if ((gw == NULL) || (gw->bw == NULL)) {
- return;
- }
+ if (g->toolbar) {
+ if (nsoption_bool(display_decoded_idn) == true) {
+ if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK)
+ idn_url_s = NULL;
+ }
- res = ro_gui_local_history_present(gw->window, gw->bw);
+ ro_toolbar_set_url(g->toolbar, idn_url_s ? idn_url_s : nsurl_access(url), true, false);
- if (res != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(res), 0);
+ if (idn_url_s)
+ free(idn_url_s);
+
+ ro_gui_url_complete_start(g->toolbar);
}
-}
+ return NSERROR_OK;
+}
-/**
- * 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)
+/* exported interface documented in riscos/window.h */
+void ro_gui_window_set_scale(struct gui_window *g, float scale)
{
- struct hlcache_handle *h;
+ g->scale = scale;
+ browser_window_set_scale(g->bw, scale, true);
+}
- if (g == NULL || g->bw == NULL || !browser_window_has_content(g->bw))
- return;
- h = browser_window_get_content(g->bw);
- if (h == NULL)
- return;
+/* exported interface documented in riscos/window.h */
+bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
+{
+ os_error *error;
+ os_coord pos;
- ro_gui_save_prepare(save_type, h, NULL, NULL, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
-}
+ /* Ignore directories etc. */
+ if (0x1000 <= message->data.data_xfer.file_type)
+ return false;
+ if (!ro_gui_window_to_window_pos(g, message->data.data_xfer.pos.x,
+ message->data.data_xfer.pos.y, &pos))
+ return false;
-/**
- * Open a text search dialogue for a browser window.
- *
- * \param *g The browser window to act on.
- */
+ if (browser_window_drop_file_at_point(g->bw, pos.x, pos.y,
+ message->data.data_xfer.file_name) == false)
+ return false;
-void ro_gui_window_action_search(struct gui_window *g)
-{
- if (g == NULL || g->bw == NULL || !browser_window_can_search(g->bw))
- return;
+ /* send DataLoadAck */
+ message->action = message_DATA_LOAD_ACK;
+ message->your_ref = message->my_ref;
+ error = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
+ if (error) {
+ LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
- ro_gui_search_prepare(g->bw);
- ro_gui_dialog_open_persistent(g->window, dialog_search, true);
+ return 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)
+/* exported interface documented in riscos/window.h */
+void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data)
{
- if (g == NULL)
- return;
+ os_coord pos;
+ struct gui_window *g = (struct gui_window *) data;
- ro_gui_dialog_prepare_zoom(g);
- ro_gui_dialog_open_persistent(g->window, dialog_zoom, true);
+ 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_DOUBLE_CLICK_DRAG),
+ pos.x, pos.y);
}
-/**
- * Add a hotlist entry for a browser window.
- *
- * \param *g The browser window to act on.
- */
-
-static void ro_gui_window_action_add_bookmark(struct gui_window *g)
+/* exported interface documented in riscos/window.h */
+void
+ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
{
- nsurl *url;
+ /* 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;
+ struct hlcache_handle *h;
+ os_error *error;
+ int len, id;
- if (g == NULL || g->bw == NULL || g->toolbar == NULL ||
- browser_window_has_content(g->bw) == false)
- return;
+ assert(bw);
- url = browser_window_get_url(g->bw);
+ h = browser_window_get_content(bw);
+ if (!h) return;
- ro_gui_hotlist_add_page(url);
- ro_toolbar_update_hotlist(g->toolbar);
-}
+ /* 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);
+ ro_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 = riscos_bitmap_create(width, height,
+ BITMAP_NEW | BITMAP_OPAQUE | BITMAP_CLEAR_MEMORY);
+ if (!bitmap) {
+ LOG("Thumbnail initialisation failed.");
+ return;
+ }
+ riscos_bitmap_render(bitmap, h);
+ if (overlay) {
+ riscos_bitmap_overlay_sprite(bitmap, overlay);
+ }
+ area = riscos_bitmap_convert_8bpp(bitmap);
+ riscos_bitmap_destroy(bitmap);
+ if (!area) {
+ LOG("Thumbnail conversion failed.");
+ return;
+ }
-/**
- * Remove a hotlist entry for a browser window.
- *
- * \param *g The browser window to act on.
- */
+ /* 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;
+ }
-static void ro_gui_window_action_remove_bookmark(struct gui_window *g)
-{
- nsurl *url;
+ sprite_header = (osspriteop_header *)(area + 1);
+ len = sprintf(sprite_header->name, "ic_netsf%.2d", id);
- if (g == NULL || g->bw == NULL || g->toolbar == NULL ||
- browser_window_has_content(g->bw) == false)
+ 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);
+ ro_warn_user("MiscError", error->errmess);
+ free(area);
return;
+ }
- url = browser_window_get_url(g->bw);
-
- ro_gui_hotlist_remove_page(url);
-}
+ error = xwimpspriteop_merge_sprite_file(temp_fname);
+ if (error) {
+ LOG("xwimpspriteop_merge_sprite_file: 0x%x:%s", error->errnum, error->errmess);
+ ro_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';
-/**
- * Open a print dialogue for a browser window.
- *
- * \param *g The browser window to act on.
- */
+ 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';
+ }
-void ro_gui_window_action_print(struct gui_window *g)
-{
- if (g == NULL)
- return;
+ 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);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ else {
+ g->iconise_icon = id;
+ iconise_used[id] = true;
+ }
- ro_gui_print_prepare(g);
- ro_gui_dialog_open_persistent(g->window, dialog_print, true);
+ free(area);
}
-/**
- * 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)
+/* exported interface documented in riscos/window.h */
+bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
{
- if (g == NULL || g->bw == NULL ||
- browser_window_has_content(g->bw) == false)
- return;
+ if (message->data.data_xfer.file_type == osfile_TYPE_TEXT &&
+ ro_gui_window_import_text(g,
+ message->data.data_xfer.file_name)) {
+ os_error *error;
- ro_gui_window_prepare_pageinfo(g);
- ro_gui_dialog_open_persistent(g->window, dialog_pageinfo, false);
+ /* send DataLoadAck */
+ message->action = message_DATA_LOAD_ACK;
+ message->your_ref = message->my_ref;
+ error = xwimp_send_message(wimp_USER_MESSAGE, message,
+ message->sender);
+ if (error) {
+ LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ return true;
+ }
+ return false;
}
-/*
- * Window and Toolbar Redraw and Update
- */
+/* exported interface documented in riscos/window.h */
+bool ro_gui_window_check_menu(wimp_menu *menu)
+{
+ return (ro_gui_browser_window_menu == menu) ? true : false;
+}
-/**
- * Redraws the content for all windows.
- */
+/* exported interface documented in riscos/window.h */
void ro_gui_window_redraw_all(void)
{
struct gui_window *g;
@@ -4117,25 +4505,7 @@ void ro_gui_window_redraw_all(void)
}
-/**
- * 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.
- */
+/* exported interface documented in riscos/window.h */
void ro_gui_window_update_boxes(void)
{
osbool more;
@@ -4218,10 +4588,7 @@ void ro_gui_window_update_boxes(void)
}
-/**
- * Destroy all browser windows.
- */
-
+/* exported interface documented in riscos/window.h */
void ro_gui_window_quit(void)
{
while (window_list) {
@@ -4233,13 +4600,10 @@ void ro_gui_window_quit(void)
}
-/**
- * Animate the "throbbers" of all browser windows.
- */
-
+/* exported interface documented in riscos/window.h */
void ro_gui_throb(void)
{
- struct gui_window *g;
+ struct gui_window *g;
for (g = window_list; g; g = g->next) {
if (!g->active)
@@ -4250,245 +4614,7 @@ void ro_gui_throb(void)
}
-/**
- * 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;
- struct toolbar *toolbar;
-
- if (g == NULL || g->toolbar == NULL)
- return;
-
- bw = g->bw;
- 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,
- !browser_window_up_available(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SEARCH,
- !browser_window_can_search(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SCALE,
- !browser_window_has_content(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_PRINT,
- !browser_window_has_content(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SAVE_SOURCE,
- !browser_window_has_content(bw));
-
- 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)
-{
- nsoption_set_charp(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
- *
- * \param g gui window containing textarea
- * \param filename pathname of file to be imported
- * \return true iff successful
- */
-
-bool ro_gui_window_import_text(struct gui_window *g, const char *filename)
-{
- fileswitch_object_type obj_type;
- os_error *error;
- char *buf, *utf8_buf, *sp;
- int size;
- nserror ret;
- const char *ep;
- char *p;
-
- 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);
- ro_warn_user("FileError", error->errmess);
- return true; /* was for us, but it didn't work! */
- }
-
- /* Allocate one byte more than needed to ensure that the buffer is
- * always terminated, regardless of file contents.
- */
-
- buf = calloc(size + 1, sizeof(char));
- if (!buf) {
- ro_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);
- ro_warn_user("LoadError", error->errmess);
- free(buf);
- return true;
- }
-
- ret = utf8_from_local_encoding(buf, size, &utf8_buf);
- if (ret != NSERROR_OK) {
- /* bad encoding shouldn't happen */
- assert(ret != NSERROR_BAD_ENCODING);
- LOG("utf8_from_local_encoding failed");
- free(buf);
- ro_warn_user("NoMemory", NULL);
- return true;
- }
- size = strlen(utf8_buf);
-
- ep = utf8_buf + size;
- 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);
-
- free(buf);
- free(utf8_buf);
- return true;
-}
-
-
-/**
- * Clones a browser window's options.
- *
- * \param new_gui the new gui window
- * \param old_gui the gui window to clone from, or NULL for default
- */
-
-void ro_gui_window_clone_options(
- struct gui_window *new_gui,
- struct gui_window *old_gui)
-{
- assert(new_gui);
-
- /* Clone the basic options
- */
- if (!old_gui) {
- new_gui->option.buffer_animations = nsoption_bool(buffer_animations);
- new_gui->option.buffer_everything = nsoption_bool(buffer_everything);
- } else {
- new_gui->option = old_gui->option;
- }
-
- /* Set up the toolbar
- */
- if (new_gui->toolbar) {
- ro_toolbar_set_display_buttons(new_gui->toolbar,
- nsoption_bool(toolbar_show_buttons));
- ro_toolbar_set_display_url(new_gui->toolbar,
- nsoption_bool(toolbar_show_address));
- ro_toolbar_set_display_throbber(new_gui->toolbar,
- nsoption_bool(toolbar_show_throbber));
- if ((old_gui) && (old_gui->toolbar)) {
- 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);
- }
- }
-}
-
-
-/**
- * Makes a browser window's options the default.
- *
- * \param gui The riscos gui window to set default options in.
- */
-
+/* exported interface documented in riscos/window.h */
void ro_gui_window_default_options(struct gui_window *gui)
{
if (gui == NULL)
@@ -4516,179 +4642,20 @@ void ro_gui_window_default_options(struct gui_window *gui)
}
-/*
- * Custom Menu Support
- */
-
-/**
- * Prepare or reprepare a form select menu, setting up the menu handle
- * globals in the process.
- *
- * \param g The RISC OS gui window the menu is in.
- * \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 gui_window *g,
- struct form_control *control)
-{
- unsigned int item, entries;
- char *text_convert, *temp;
- struct form_option *option;
- bool reopen = true;
- nserror err;
-
- assert(control);
-
- /* enumerate the entries */
- entries = 0;
- option = form_select_get_option(control, entries);
- while (option != NULL) {
- entries++;
- option = form_select_get_option(control, entries);
- }
-
- if (entries == 0) {
- /* no menu to display */
- ro_gui_menu_destroy();
- return false;
- }
-
- /* free riscos menu if there already is one */
- if ((gui_form_select_menu) && (control != gui_form_select_control)) {
- for (item = 0; ; item++) {
- free(gui_form_select_menu->entries[item].data.
- indirected_text.text);
- if (gui_form_select_menu->entries[item].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;
- }
-
- /* allocate new riscos menu */
- if (!gui_form_select_menu) {
- reopen = false;
- gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries));
- if (!gui_form_select_menu) {
- ro_warn_user("NoMemory", 0);
- ro_gui_menu_destroy();
- return false;
- }
- err = utf8_to_local_encoding(messages_get("SelectMenu"), 0,
- &text_convert);
- if (err != NSERROR_OK) {
- /* badenc should never happen */
- assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_local_encoding failed");
- ro_warn_user("NoMemory", 0);
- ro_gui_menu_destroy();
- return false;
- }
- gui_form_select_menu->title_data.indirected_text.text =
- text_convert;
- ro_gui_menu_init_structure(gui_form_select_menu, entries);
- }
-
- /* initialise menu entries from form control */
- for (item = 0; item < entries; item++) {
- option = form_select_get_option(control, item);
- gui_form_select_menu->entries[item].menu_flags = 0;
- if (option->selected)
- gui_form_select_menu->entries[item].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");
- ro_warn_user("NoMemory", 0);
- ro_gui_menu_destroy();
- return false;
- }
-
- err = utf8_to_local_encoding(temp,
- 0, &text_convert);
- if (err != NSERROR_OK) {
- /* A bad encoding should never happen,
- * so assert this */
- assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
- ro_warn_user("NoMemory", 0);
- ro_gui_menu_destroy();
- return false;
- }
-
- free(temp);
-
- gui_form_select_menu->entries[item].data.indirected_text.text =
- text_convert;
- gui_form_select_menu->entries[item].data.indirected_text.size =
- strlen(gui_form_select_menu->entries[item].
- data.indirected_text.text) + 1;
- }
- }
-
- gui_form_select_menu->entries[0].menu_flags |=
- wimp_MENU_TITLE_INDIRECTED;
- gui_form_select_menu->entries[item - 1].menu_flags |= wimp_MENU_LAST;
-
- return true;
-}
-
-/**
- * Process selections from a form select menu, passing them back to the core.
- *
- * \param *g The browser window affected by the menu.
- * \param *selection The menu selection.
- */
-
-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(gui_form_select_control,
- selection->items[0]);
-}
-
-
-/*
- * Window and Toolbar Lookup
- */
-
-/**
- * Convert a RISC OS window handle to a gui_window.
- *
- * \param window RISC OS window handle.
- * \return A pointer to a riscos gui window if found or NULL.
- */
-
+/* exported interface documented in riscos/window.h */
struct gui_window *ro_gui_window_lookup(wimp_w window)
{
struct gui_window *g;
- for (g = window_list; g; g = g->next)
- if (g->window == window)
+ for (g = window_list; g; g = g->next) {
+ if (g->window == window) {
return g;
+ }
+ }
return NULL;
}
-/**
- * Convert a toolbar RISC OS window handle to a gui_window.
- *
- * \param window RISC OS window handle of a toolbar
- * \return pointer to a structure if found, NULL otherwise
- */
-
+/* exported interface documented in riscos/window.h */
struct gui_window *ro_gui_toolbar_lookup(wimp_w window)
{
struct gui_window *g = NULL;
@@ -4706,22 +4673,9 @@ struct gui_window *ro_gui_toolbar_lookup(wimp_w window)
}
-/*
- * 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)
+/* exported interface documented in riscos/window.h */
+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;
@@ -4741,18 +4695,11 @@ bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
}
-/**
- * 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)
+/* exported interface documented in riscos/window.h */
+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;
@@ -4772,24 +4719,9 @@ bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
}
-/*
- * 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.
- *
- * \param buttons Wimp button state.
- * \param type Wimp work-area/icon type for decoding.
- * \return NetSurf core button state.
- */
-
-browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
- wimp_icon_flags type)
+/* exported interface documented in riscos/window.h */
+enum browser_mouse_state
+ro_gui_mouse_click_state(wimp_mouse_state buttons, wimp_icon_flags type)
{
browser_mouse_state state = 0; /* Blank state with nothing set */
static struct {
@@ -4904,18 +4836,9 @@ browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
}
-/**
- * Returns the state of the mouse buttons and modifiers keys whilst
- * dragging, for passing to the OS-independent browser window/ treeview/
- * etc code
- *
- * \param buttons Wimp button state.
- * \param type Wimp work-area/icon type for decoding.
- * \return NetSurf core button state.
- */
-
-browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
- wimp_icon_flags type)
+/* exported interface documented in riscos/window.h */
+browser_mouse_state
+ro_gui_mouse_drag_state(wimp_mouse_state buttons, wimp_icon_flags type)
{
browser_mouse_state state = 0; /* Blank state with nothing set */
@@ -4943,10 +4866,7 @@ browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
}
-/**
- * Returns true iff one or more Shift keys is held down
- */
-
+/* exported interface documented in riscos/window.h */
bool ro_gui_shift_pressed(void)
{
int shift = 0;
@@ -4955,10 +4875,7 @@ bool ro_gui_shift_pressed(void)
}
-/**
- * Returns true iff one or more Ctrl keys is held down
- */
-
+/* exported interface documented in riscos/window.h */
bool ro_gui_ctrl_pressed(void)
{
int ctrl = 0;
@@ -4967,10 +4884,7 @@ bool ro_gui_ctrl_pressed(void)
}
-/**
- * Returns true iff one or more Alt keys is held down
- */
-
+/* exported interface documented in riscos/window.h */
bool ro_gui_alt_pressed(void)
{
int alt = 0;
@@ -4978,36 +4892,41 @@ bool ro_gui_alt_pressed(void)
return (alt == 0xff);
}
-static struct gui_window_table window_table = {
- .create = gui_window_create,
- .destroy = gui_window_destroy,
- .invalidate = ro_gui_window_invalidate_area,
- .get_scroll = gui_window_get_scroll,
- .set_scroll = gui_window_set_scroll,
- .get_dimensions = gui_window_get_dimensions,
- .update_extent = gui_window_update_extent,
- .set_title = gui_window_set_title,
- .set_url = ro_gui_window_set_url,
- .set_icon = gui_window_set_icon,
- .set_status = riscos_window_set_status,
- .set_pointer = gui_window_set_pointer,
- .place_caret = gui_window_place_caret,
- .remove_caret = gui_window_remove_caret,
- .save_link = gui_window_save_link,
- .drag_start = gui_window_drag_start,
- .scroll_start = gui_window_scroll_start,
- .new_content = gui_window_new_content,
- .start_throbber = gui_window_start_throbber,
- .stop_throbber = gui_window_stop_throbber,
- .create_form_select_menu = gui_window_create_form_select_menu,
+/* exported interface documented in riscos/window.h */
+void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
+{
+ static gui_pointer_shape curr_pointer = GUI_POINTER_DEFAULT;
+ struct ro_gui_pointer_entry *entry;
+ os_error *error;
- /* from save */
- .drag_save_object = gui_drag_save_object,
- .drag_save_selection =gui_drag_save_selection,
+ if (shape == curr_pointer)
+ return;
- /* from textselection */
- .start_selection = gui_start_selection,
-};
+ assert(shape < sizeof ro_gui_pointer_table /
+ sizeof ro_gui_pointer_table[0]);
-struct gui_window_table *riscos_window_table = &window_table;
+ entry = &ro_gui_pointer_table[shape];
+
+ if (entry->wimp_area) {
+ /* pointer in the Wimp's sprite area */
+ error = xwimpspriteop_set_pointer_shape(entry->sprite_name,
+ 1, entry->xactive, entry->yactive, 0, 0);
+ if (error) {
+ LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ } else {
+ /* pointer in our own sprite area */
+ error = xosspriteop_set_pointer_shape(osspriteop_USER_AREA,
+ gui_sprites,
+ (osspriteop_id) entry->sprite_name,
+ 1, entry->xactive, entry->yactive, 0, 0);
+ if (error) {
+ LOG("xosspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ }
+
+ curr_pointer = shape;
+}
diff --git a/frontends/riscos/window.h b/frontends/riscos/window.h
index 30b0965..0a5bd43 100644
--- a/frontends/riscos/window.h
+++ b/frontends/riscos/window.h
@@ -30,10 +30,21 @@ struct nsurl;
extern struct gui_window_table *riscos_window_table;
+/**
+ * Initialise the browser window module and its menus.
+ */
void ro_gui_window_initialise(void);
+
+/**
+ * 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);
+
/**
* Set the contents of a window's address bar.
*
@@ -42,6 +53,7 @@ bool ro_gui_window_check_menu(wimp_menu *menu);
*/
nserror ro_gui_window_set_url(struct gui_window *g, struct nsurl *url);
+
/**
* Cause an area of a window to be invalidated
*
@@ -56,5 +68,186 @@ nserror ro_gui_window_set_url(struct gui_window *g, struct nsurl *url);
*/
nserror ro_gui_window_invalidate_area(struct gui_window *g, const struct rect *rect);
+
+/**
+ * Set a gui_window's scale
+ */
+void ro_gui_window_set_scale(struct gui_window *g, float scale);
+
+
+/**
+ * Handle Message_DataLoad (file dragged in) for a window.
+ *
+ * If the file was dragged into a form file input, it is used as the value.
+ *
+ * \param g window
+ * \param message Message_DataLoad block
+ * \return true if the load was processed
+ */
+bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message);
+
+
+/**
+ * Handle pointer movements in a browser window.
+ *
+ * \param pointer new mouse position
+ * \param data browser window that the pointer is in
+ */
+void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data);
+
+
+/**
+ * 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);
+
+
+/**
+ * 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
+ */
+bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message);
+
+
+/**
+ * Redraws the content for all windows.
+ */
+void ro_gui_window_redraw_all(void);
+
+
+/**
+ * Redraw any pending update boxes.
+ */
+void ro_gui_window_update_boxes(void);
+
+
+/**
+ * Destroy all browser windows.
+ */
+void ro_gui_window_quit(void);
+
+
+/**
+ * Close all browser windows
+ *
+ * no need for a separate fn same operation as quit
+*/
+#define ro_gui_window_close_all ro_gui_window_quit
+
+
+/**
+ * Animate the "throbbers" of all browser windows.
+ */
+void ro_gui_throb(void);
+
+/**
+ * Makes a browser window's options the default.
+ *
+ * \param gui The riscos gui window to set default options in.
+ */
+void ro_gui_window_default_options(struct gui_window *gui);
+
+
+/**
+ * Convert a RISC OS window handle to a gui_window.
+ *
+ * \param window RISC OS window handle.
+ * \return A pointer to a riscos gui window if found or NULL.
+ */
+struct gui_window *ro_gui_window_lookup(wimp_w window);
+
+
+/**
+ * Convert a toolbar RISC OS window handle to a gui_window.
+ *
+ * \param window RISC OS window handle of a toolbar
+ * \return pointer to a structure if found, NULL otherwise
+ */
+struct gui_window *ro_gui_toolbar_lookup(wimp_w window);
+
+
+/**
+ * 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);
+
+
+/**
+ * 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);
+
+/**
+ * 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.
+ *
+ * \param buttons Wimp button state.
+ * \param type Wimp work-area/icon type for decoding.
+ * \return NetSurf core button state.
+ */
+enum browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons, wimp_icon_flags type);
+
+
+/**
+ * Returns the state of the mouse buttons and modifiers keys whilst
+ * dragging, for passing to the OS-independent browser window/ treeview/
+ * etc code
+ *
+ * \param buttons Wimp button state.
+ * \param type Wimp work-area/icon type for decoding.
+ * \return NetSurf core button state.
+ */
+enum browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons, wimp_icon_flags type);
+
+
+/**
+ * Returns true iff one or more Shift keys is held down
+ */
+bool ro_gui_shift_pressed(void);
+
+
+/**
+ * Returns true iff one or more Ctrl keys is held down
+ */
+bool ro_gui_ctrl_pressed(void);
+
+
+/**
+ * Returns true iff one or more Alt keys is held down
+ */
+bool ro_gui_alt_pressed(void);
+
+
+/**
+ * Change mouse pointer shape
+ */
+void gui_window_set_pointer(struct gui_window *g, enum gui_pointer_shape shape);
+
#endif