diff options
author | Richard Wilson <rjw@netsurf-browser.org> | 2006-09-06 22:15:58 +0000 |
---|---|---|
committer | Richard Wilson <rjw@netsurf-browser.org> | 2006-09-06 22:15:58 +0000 |
commit | 3e0c02e8e59fe41a250d54b760b0cd675044697f (patch) | |
tree | 3265bb4c158ee96f7cbee0420692d234f3a9ca32 | |
parent | d5540f344d5048ce06ef86fa9072fbf38a260a48 (diff) | |
download | netsurf-3e0c02e8e59fe41a250d54b760b0cd675044697f.tar.gz netsurf-3e0c02e8e59fe41a250d54b760b0cd675044697f.tar.bz2 |
Simplify and tidy up RISC OS gui_ functions. Fix toolbar height changing issues for framesets.
svn path=/trunk/netsurf/; revision=2924
-rw-r--r-- | desktop/browser.c | 15 | ||||
-rw-r--r-- | desktop/gui.h | 7 | ||||
-rw-r--r-- | riscos/gui.h | 6 | ||||
-rw-r--r-- | riscos/menus.c | 33 | ||||
-rw-r--r-- | riscos/textselection.c | 47 | ||||
-rw-r--r-- | riscos/theme.c | 20 | ||||
-rw-r--r-- | riscos/theme.h | 3 | ||||
-rw-r--r-- | riscos/treeview.c | 17 | ||||
-rw-r--r-- | riscos/treeview.h | 1 | ||||
-rw-r--r-- | riscos/window.c | 1670 |
10 files changed, 843 insertions, 976 deletions
diff --git a/desktop/browser.c b/desktop/browser.c index 8ab99338e..e4a1f8d49 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -263,7 +263,7 @@ void browser_window_recalculate_iframes(struct browser_window *bw) { assert(bw); /* update window dimensions */ - gui_window_get_dimensions(bw->window, &bw_width, &bw_height); + gui_window_get_dimensions(bw->window, &bw_width, &bw_height, false); if (!bw->parent) { bw->x0 = 0; bw->y0 = 0; @@ -383,7 +383,7 @@ void browser_window_recalculate_frameset(struct browser_window *bw) { /* window dimensions */ if (!bw->parent) { - gui_window_get_dimensions(bw->window, &bw_width, &bw_height); + gui_window_get_dimensions(bw->window, &bw_width, &bw_height, false); bw->x0 = 0; bw->y0 = 0; bw->x1 = bw_width; @@ -751,6 +751,7 @@ void browser_window_go_post(struct browser_window *bw, const char *url, char url_buf[256]; int depth = 0; struct browser_window *cur; + int width, height; LOG(("bw %p, url %s", bw, url)); assert(bw); @@ -810,13 +811,13 @@ void browser_window_go_post(struct browser_window *bw, const char *url, browser_window_remove_caret(bw); browser_window_destroy_children(bw); + gui_window_get_dimensions(bw->window, &width, &height, true); + browser_window_set_status(bw, messages_get("Loading")); bw->history_add = history_add; bw->time0 = clock(); c = fetchcache(url2, browser_window_callback, (intptr_t) bw, 0, - gui_window_get_width(bw->window), - gui_window_get_height(bw->window), - false, + width, height, false, post_urlenc, post_multipart, true, download); free(url2); if (!c) { @@ -835,9 +836,7 @@ void browser_window_go_post(struct browser_window *bw, const char *url, bw->download = download; fetchcache_go(c, option_send_referer ? referer : 0, - browser_window_callback, (intptr_t) bw, 0, - gui_window_get_width(bw->window), - gui_window_get_height(bw->window), + browser_window_callback, (intptr_t) bw, 0, width, height, post_urlenc, post_multipart, true); } diff --git a/desktop/gui.h b/desktop/gui.h index 4d09921a8..b50fe82ed 100644 --- a/desktop/gui.h +++ b/desktop/gui.h @@ -67,9 +67,8 @@ void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, int x1, int y1); void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int y1); -void gui_window_get_dimensions(struct gui_window *g, int *width, int *height); -int gui_window_get_width(struct gui_window *g); -int gui_window_get_height(struct gui_window *g); +void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, + bool scaled); void gui_window_update_extent(struct gui_window *g); void gui_window_set_status(struct gui_window *g, const char *text); void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape); @@ -83,8 +82,8 @@ void gui_window_new_content(struct gui_window *g); bool gui_window_scroll_start(struct gui_window *g); bool gui_window_box_scroll_start(struct gui_window *g, int x0, int y0, int x1, int y1); -void gui_window_save_as_link(struct gui_window *g, struct content *c); bool gui_window_frame_resize_start(struct gui_window *g); +void gui_window_save_as_link(struct gui_window *g, struct content *c); struct gui_download_window *gui_download_window_create(const char *url, const char *mime_type, struct fetch *fetch, diff --git a/riscos/gui.h b/riscos/gui.h index b40335f16..ea63558b0 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -137,7 +137,6 @@ void ro_gui_cert_open(struct tree *tree, struct node *node); /* in window.c */ void ro_gui_window_quit(void); void ro_gui_window_update_theme(void); -void ro_gui_window_update_dimensions(struct gui_window *g, int yscroll); void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer); bool ro_gui_toolbar_click(wimp_pointer *pointer); bool ro_gui_status_click(wimp_pointer *pointer); @@ -146,9 +145,8 @@ struct gui_window *ro_gui_window_lookup(wimp_w window); struct gui_window *ro_gui_toolbar_lookup(wimp_w window); struct gui_window *ro_gui_status_lookup(wimp_w window); void ro_gui_scroll_request(wimp_scroll *scroll); -int window_x_units(int x, wimp_window_state *state); -int window_y_units(int y, wimp_window_state *state); -bool window_screen_pos(struct gui_window *g, int x, int y, os_coord *pos); +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); bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message); bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message); void ro_gui_window_process_reformats(void); diff --git a/riscos/menus.c b/riscos/menus.c index 9d73cde11..685dd3694 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -447,10 +447,9 @@ void ro_gui_menu_init(void) * Display a menu. */ void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w) { - int doc_x, doc_y; - wimp_window_state state; struct gui_window *g; os_error *error; + os_coord pos; int i; menu_action action; struct menu_definition *definition; @@ -467,26 +466,14 @@ void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w) { /* read the object under the pointer for a new gui_window menu */ if ((!current_menu) && (menu == browser_menu)) { - state.w = w; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - g = ro_gui_window_lookup(w); - assert(g); - - doc_x = window_x_units(x, &state) / 2 / g->option.scale; - doc_y = -window_y_units(y, &state) / 2 / g->option.scale; - + + if (!ro_gui_window_to_window_pos(g, x, y, &pos)) + return; current_menu_object_box = NULL; if (g->bw->current_content && g->bw->current_content->type == CONTENT_HTML) - current_menu_object_box = box_object_at_point( - g->bw->current_content, doc_x, doc_y); + current_menu_object_box = box_object_at_point(g->bw->current_content, pos.x, pos.y); } /* store the menu characteristics */ @@ -776,17 +763,13 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning) { * \param toolbar the toolbar to update */ void ro_gui_menu_refresh_toolbar(struct toolbar *toolbar) { - int height; assert(toolbar); toolbar->reformat_buttons = true; - height = toolbar->height; ro_gui_theme_process_toolbar(toolbar, -1); if (toolbar->type == THEME_BROWSER_TOOLBAR) { - ro_gui_window_update_dimensions( - ro_gui_window_lookup(current_menu_window), - height - toolbar->height); + gui_window_update_extent(ro_gui_window_lookup(current_menu_window)); } else if (toolbar->type == THEME_HOTLIST_TOOLBAR) { tree_resized(hotlist_tree); xwimp_force_redraw((wimp_w)hotlist_tree->handle, @@ -795,6 +778,10 @@ void ro_gui_menu_refresh_toolbar(struct toolbar *toolbar) { tree_resized(global_history_tree); xwimp_force_redraw((wimp_w)global_history_tree->handle, 0,-16384, 16384, 16384); + } else if (toolbar->type == THEME_COOKIES_TOOLBAR) { + tree_resized(cookies_tree); + xwimp_force_redraw((wimp_w)cookies_tree->handle, + 0,-16384, 16384, 16384); } } diff --git a/riscos/textselection.c b/riscos/textselection.c index a6745ff6d..7252f7b3d 100644 --- a/riscos/textselection.c +++ b/riscos/textselection.c @@ -137,10 +137,9 @@ void gui_start_selection(struct gui_window *g) void ro_gui_selection_drag_end(struct gui_window *g, wimp_dragged *drag) { wimp_auto_scroll_info scroll; - wimp_window_state state; wimp_pointer pointer; os_error *error; - int x, y; + os_coord pos; LOG(("ending text selection drag")); @@ -167,20 +166,10 @@ void ro_gui_selection_drag_end(struct gui_window *g, wimp_dragged *drag) 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)); - warn_user("WimpError", error->errmess); - return; - } - - x = window_x_units(drag->final.x0, &state) / 2 / g->option.scale; - y = -window_y_units(drag->final.y0, &state) / 2 / g->option.scale; - - browser_window_mouse_drag_end(g->bw, - ro_gui_mouse_click_state(pointer.buttons), x, y); + if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) + browser_window_mouse_drag_end(g->bw, + ro_gui_mouse_click_state(pointer.buttons), + pos.x, pos.y); } @@ -369,7 +358,7 @@ void gui_paste_from_clipboard(struct gui_window *g, int x, int y) os_error *error; os_coord pos; - if (!window_screen_pos(g, x, y, &pos)) + if (!ro_gui_window_to_screen_pos(g, x, y, &pos)) return; msg.size = sizeof(msg); @@ -510,15 +499,13 @@ void ro_gui_selection_dragging(wimp_message *message) struct box *textarea = NULL; struct box *text_box = NULL; struct browser_window *bw; - wimp_window_state state; struct content *content; int gadget_box_x = 0; int gadget_box_y = 0; struct gui_window *g; - os_error *error; + os_coord pos; int box_x = 0; int box_y = 0; - int x, y; /* with autoscrolling, we will probably need to remember the gui_window and override the drag->w window handle which could be any window on the desktop */ @@ -535,20 +522,8 @@ void ro_gui_selection_dragging(wimp_message *message) return; } - state.w = drag->w; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s\n", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - drag_claimed = false; + if (!ro_gui_window_to_window_pos(g, drag->pos.x, drag->pos.y, &pos)) return; - } - - x = window_x_units(drag->pos.x, &state) / 2 / - g->option.scale; - y = -window_y_units(drag->pos.y, &state) / 2 / - g->option.scale; bw = g->bw; content = bw->current_content; @@ -557,7 +532,7 @@ void ro_gui_selection_dragging(wimp_message *message) struct box *box = content->data.html.layout; - while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) { + while ((box = box_at_point(box, pos.x, pos.y, &box_x, &box_y, &content))) { if (box->style && box->style->visibility == CSS_VISIBILITY_HIDDEN) continue; @@ -591,8 +566,8 @@ void ro_gui_selection_dragging(wimp_message *message) else gui_window_set_pointer(g, GUI_POINTER_CARET); - text_box = textarea_get_position(textarea, x - gadget_box_x, - y - gadget_box_y, &char_offset, &pixel_offset); + text_box = textarea_get_position(textarea, pos.x - gadget_box_x, + pos.y - gadget_box_y, &char_offset, &pixel_offset); caret_set_position(&ghost_caret, bw, text_box, char_offset, pixel_offset); drag_claimed = true; diff --git a/riscos/theme.c b/riscos/theme.c index 53aee65e9..24cf3e3e3 100644 --- a/riscos/theme.c +++ b/riscos/theme.c @@ -568,6 +568,9 @@ bool ro_gui_theme_apply(struct theme_descriptor *descriptor) { /* apply the theme to all the current windows */ ro_gui_window_update_theme(); + ro_gui_tree_update_theme(hotlist_tree); + ro_gui_tree_update_theme(global_history_tree); + ro_gui_tree_update_theme(cookies_tree); ro_gui_theme_close(theme_previous, false); return true; } @@ -833,6 +836,7 @@ struct toolbar *ro_gui_theme_create_toolbar(struct theme_descriptor *descriptor, ro_gui_theme_destroy_toolbar(toolbar); return NULL; } + toolbar->old_height = ro_gui_theme_toolbar_full_height(toolbar); return toolbar; } @@ -1751,7 +1755,6 @@ void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar) { * \param toolbar the toolbar to toggle editing for */ void ro_gui_theme_toggle_edit(struct toolbar *toolbar) { - int height; int icons = 0; struct toolbar_icon *icon; struct gui_window *g = NULL; @@ -1812,14 +1815,13 @@ void ro_gui_theme_toggle_edit(struct toolbar *toolbar) { } /* turn off editing */ - height = toolbar->editor->height; ro_gui_theme_destroy_toolbar(toolbar->editor); toolbar->editor = NULL; ro_gui_theme_update_toolbar(toolbar->descriptor, toolbar); switch (toolbar->type) { case THEME_BROWSER_TOOLBAR: if (g) - ro_gui_window_update_dimensions(g, height); + gui_window_update_extent(g); break; default: if (toolbar->parent_handle) @@ -1863,8 +1865,7 @@ void ro_gui_theme_toggle_edit(struct toolbar *toolbar) { switch (toolbar->type) { case THEME_BROWSER_TOOLBAR: if (g) - ro_gui_window_update_dimensions(g, - -toolbar->editor->height); + gui_window_update_extent(g); break; default: if (toolbar->parent_handle) { @@ -2426,3 +2427,12 @@ void ro_gui_theme_status_open(wimp_open *open) { if (toolbar->status_width > 10000) toolbar->status_width = 10000; ro_gui_theme_process_toolbar(toolbar, -1); } + +int ro_gui_theme_height_change(struct toolbar *toolbar) { + int height, cur_height; + + cur_height = ro_gui_theme_toolbar_full_height(toolbar); + height = toolbar->old_height - cur_height; + toolbar->old_height = cur_height; + return height; +} diff --git a/riscos/theme.h b/riscos/theme.h index 687430c5d..1b6f3b571 100644 --- a/riscos/theme.h +++ b/riscos/theme.h @@ -108,6 +108,7 @@ struct toolbar { int toolbar_current; /**< the size of the toolbar window in OS units */ int height; /**< vertical extent of the toolbar (read only) */ int max_height; /**< allowed vertical extent (read only) */ + int old_height; /**< height on last test (read only) */ wimp_w toolbar_handle; /**< toolbar window handle */ wimp_w status_handle; /**< status window handle (if applicable) */ wimp_w parent_handle; /**< parent window handle (read only) */ @@ -162,6 +163,8 @@ void ro_gui_theme_toolbar_editor_sync(struct toolbar *toolbar); void ro_gui_theme_toolbar_editor_click(struct toolbar *toolbar, wimp_pointer *pointer); void ro_gui_theme_toolbar_editor_drag_end(wimp_dragged *drag); +int ro_gui_theme_height_change(struct toolbar *toolbar); + struct toolbar_icon *ro_gui_theme_toolbar_get_icon(struct toolbar *toolbar, int x, int y); #define ro_gui_theme_toolbar_height(toolbar) toolbar->height + \ diff --git a/riscos/treeview.c b/riscos/treeview.c index 4978f9cd7..7bde041c7 100644 --- a/riscos/treeview.c +++ b/riscos/treeview.c @@ -1490,3 +1490,20 @@ bool ro_gui_tree_launch_node(struct tree *tree, struct node *node) { int ro_gui_tree_help(int x, int y) { return -1; } + + +void ro_gui_tree_update_theme(struct tree *tree) { + if ((tree) && (tree->toolbar)) { + if (tree->toolbar->editor) + if (!ro_gui_theme_update_toolbar(NULL, tree->toolbar->editor)) + tree->toolbar->editor = NULL; + if (!ro_gui_theme_update_toolbar(NULL, tree->toolbar)) { + ro_gui_theme_destroy_toolbar(tree->toolbar); + tree->toolbar = NULL; + } + ro_gui_theme_toolbar_editor_sync(tree->toolbar); + ro_gui_theme_attach_toolbar(tree->toolbar, (wimp_w)tree->handle); + tree_resized(tree); + xwimp_force_redraw((wimp_w)tree->handle, 0, -16384, 16384, 16384); + } +} diff --git a/riscos/treeview.h b/riscos/treeview.h index bfaeffd86..229974aee 100644 --- a/riscos/treeview.h +++ b/riscos/treeview.h @@ -45,5 +45,6 @@ void ro_gui_tree_scroll_visible(struct tree *tree, struct node_element *element) void ro_gui_tree_get_tree_coordinates(struct tree *tree, int x, int y, int *tree_x, int *tree_y); int ro_gui_tree_help(int x, int y); +void ro_gui_tree_update_theme(struct tree *tree); #endif diff --git a/riscos/window.c b/riscos/window.c index ccc29ad55..44bd0d407 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -79,6 +79,41 @@ static float scale_snap_to[] = {0.10, 0.125, 0.25, 0.333, 0.5, 0.75, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0}; #define SCALE_SNAP_TO_SIZE (sizeof scale_snap_to) / (sizeof(float)) + + +/** An entry in ro_gui_pointer_table. */ +struct ro_gui_pointer_entry { + bool wimp_area; /** The pointer is in the Wimp's sprite area. */ + char sprite_name[12]; + int xactive; + int yactive; +}; + +/** 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 }, + { false, "ptr_point", 6, 0 }, + { false, "ptr_caret", 4, 9 }, + { false, "ptr_menu", 6, 4 }, + { false, "ptr_ud", 6, 7 }, + { false, "ptr_ud", 6, 7 }, + { false, "ptr_lr", 7, 6 }, + { false, "ptr_lr", 7, 6 }, + { false, "ptr_ld", 7, 7 }, + { false, "ptr_ld", 7, 7 }, + { false, "ptr_rd", 7, 7 }, + { false, "ptr_rd", 6, 7 }, + { false, "ptr_cross", 7, 7 }, + { false, "ptr_move", 8, 0 }, + { false, "ptr_wait", 7, 10 }, + { false, "ptr_help", 0, 0 }, + { false, "ptr_nodrop", 0, 0 }, + { false, "ptr_nt_allwd", 10, 10 }, + { false, "ptr_progress", 0, 0 }, +}; + + static void ro_gui_window_open(wimp_open *open); static void ro_gui_window_close(wimp_w w); static void ro_gui_window_redraw(wimp_draw *redraw); @@ -105,6 +140,7 @@ struct update_box { struct update_box *pending_updates; #define MARGIN 4 + /** * Create and open a new browser window. * @@ -194,7 +230,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, } else { /* Base how we define the window height/width - on the compile time options set */ + on the compile time options set */ win_width = screen_width * 3 / 4; if (1600 < win_width) win_width = 1600; @@ -264,7 +300,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, unsigned int col; col = bw->border_colour & 0xffffff; sprintf(g->validation, "C%.6x", col); - window.extra_flags |= wimp_WINDOW_USE_TITLE_VALIDATION_STRING; + window.extra_flags |= wimp_WINDOW_USE_TITLE_VALIDATION_STRING; window.title_data.indirected_text.validation = g->validation; } break; @@ -273,7 +309,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | - wimp_WINDOW_TOGGLE_ICON; + wimp_WINDOW_TOGGLE_ICON; break; } @@ -334,7 +370,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, } state.next = wimp_TOP; if (bw->parent) { - top = browser_window_owner(bw); + top = browser_window_owner(bw); error = xwimp_open_window_nested((wimp_open *)&state, top->window->window, wimp_CHILD_LINKS_PARENT_WORK_AREA << wimp_CHILD_XORIGIN_SHIFT | @@ -388,44 +424,25 @@ void gui_window_destroy(struct gui_window *g) if (g->next) g->next->prev = g->prev; + /* destroy toolbar */ if (g->toolbar) ro_gui_theme_destroy_toolbar(g->toolbar); - - /* remove our wimp event bindings */ - ro_gui_wimp_event_finalise(g->window); /* delete window */ + ro_gui_dialog_close(g->window); error = xwimp_delete_window(g->window); if (error) { LOG(("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } + ro_gui_wimp_event_finalise(g->window); free(g); } /** - * Destroy all browser windows. - */ - -void ro_gui_window_quit(void) -{ - struct gui_window *cur; - - while (window_list) { - cur = window_list; - window_list = window_list->next; - - /* framesets and iframes are destroyed by their parents */ - if (!cur->bw->parent) - browser_window_destroy(cur->bw); - } -} - - -/** * Set the title of a browser window. * * \param g gui_window to update @@ -457,22 +474,6 @@ void gui_window_set_title(struct gui_window *g, const char *title) /** - * Save the specified content as a link. - * - * \param g gui_window containing the content - * \param c the content to save - */ - -void gui_window_save_as_link(struct gui_window *g, struct content *c) -{ - if (!c) - return; - ro_gui_save_prepare(GUI_SAVE_LINK_URL, c); - ro_gui_dialog_open_persistent(g->window, dialog_saveas, true); -} - - -/** * Force a redraw of part of the contents of a browser window. * * \param g gui_window to redraw @@ -498,23 +499,10 @@ void gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1) /** - * Redraws the content for all windows. - */ - -void ro_gui_window_redraw_all(void) -{ - struct gui_window *g; - for (g = window_list; g; g = g->next) - gui_window_redraw_window(g); -} - - -/** * Force a redraw of the entire contents of a browser window. * * \param g gui_window to redraw */ - void gui_window_redraw_window(struct gui_window *g) { wimp_window_info info; @@ -542,226 +530,6 @@ void gui_window_redraw_window(struct gui_window *g) /** - * Handle a Redraw_Window_Request for a browser window. - */ - -void ro_gui_window_redraw(wimp_draw *redraw) -{ - osbool more; - bool knockout = true; - struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(redraw->w); - float scale = g->option.scale; - struct content *c = g->bw->current_content; - int clip_x0, clip_y0, clip_x1, clip_y1, clear_x1, clear_y1; - os_error *error; - - /* Handle no content quickly - */ - if (!c) { - ro_gui_user_redraw(redraw, true, os_COLOUR_WHITE); - return; - } - - plot = ro_plotters; - ro_plot_set_scale(scale); - ro_gui_current_redraw_gui = g; - current_redraw_browser = g->bw; - - /* rendering textplain has no advantages using knockout rendering other than to - * slow things down. */ - if (c->type == CONTENT_TEXTPLAIN) - knockout = false; - - /* HTML rendering handles scale itself */ - if (c->type == CONTENT_HTML) - scale = 1; - - error = xwimp_redraw_window(redraw, &more); - if (error) { - LOG(("xwimp_redraw_window: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - while (more) { - ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; - ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; - clip_x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; - clip_y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; - clip_x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; - clip_y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; - clear_x1 = redraw->clip.x1 - ro_plot_origin_x; - clear_y1 = redraw->clip.y0 - ro_plot_origin_y; - - if (ro_gui_current_redraw_gui->option.buffer_everything) - ro_gui_buffer_open(redraw); - - if (knockout) { - knockout_plot_start(&plot); - plot.clip(clip_x0, clip_y0, clip_x1, clip_y1); - plot.clg(0x00ffffff); - } - - content_redraw(c, 0, 0, - c->width * scale, c->height * scale, - clip_x0, clip_y0, clip_x1, clip_y1, - g->option.scale, - 0xFFFFFF); - if (knockout) - knockout_plot_end(); - if (ro_gui_current_redraw_gui->option.buffer_everything) - ro_gui_buffer_close(); - - 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)); - warn_user("WimpError", error->errmess); - ro_gui_current_redraw_gui = NULL; - current_redraw_browser = NULL; - return; - } - } - ro_gui_current_redraw_gui = NULL; - current_redraw_browser = NULL; -} - - -/** - * Redraw any pending update boxes. - */ -void ro_gui_window_update_boxes(void) { - struct content *c; - osbool more; - bool clear_background = false; - bool use_buffer; - wimp_draw update; - int clip_x0, clip_y0, clip_x1, clip_y1; - os_error *error; - struct update_box *cur; - struct gui_window *g; - const union content_msg_data *data; - - for (cur = pending_updates; cur != NULL; cur = cur->next) { - g = cur->g; - c = g->bw->current_content; - data = &cur->data; - use_buffer = cur->use_buffer; - if (!c) - continue; - - update.w = g->window; - update.box.x0 = cur->x0; - update.box.y0 = cur->y0; - update.box.x1 = cur->x1; - update.box.y1 = cur->y1; - - error = xwimp_update_window(&update, &more); - if (error) { - LOG(("xwimp_update_window: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - continue; - } - - /* Set the current redraw gui_window to get options from - */ - ro_gui_current_redraw_gui = g; - current_redraw_browser = g->bw; - - plot = ro_plotters; - ro_plot_origin_x = update.box.x0 - update.xscroll; - ro_plot_origin_y = update.box.y1 - update.yscroll; - ro_plot_set_scale(g->option.scale); - - /* We should clear the background, except for HTML. - */ - if (c->type != CONTENT_HTML) - clear_background = true; - - while (more) { - clip_x0 = (update.clip.x0 - ro_plot_origin_x) / 2; - clip_y0 = (ro_plot_origin_y - update.clip.y1) / 2; - clip_x1 = (update.clip.x1 - ro_plot_origin_x) / 2; - clip_y1 = (ro_plot_origin_y - update.clip.y0) / 2; - - if (use_buffer) - ro_gui_buffer_open(&update); - if (data->redraw.full_redraw) { - if (clear_background) { - error = xcolourtrans_set_gcol(os_COLOUR_WHITE, - colourtrans_SET_BG, - os_ACTION_OVERWRITE, 0, 0); - if (error) { - LOG(("xcolourtrans_set_gcol: 0x%x: %s", - error->errnum, - error->errmess)); - warn_user("MiscError", error->errmess); - } - os_clg(); - } - - content_redraw(c, 0, 0, - c->width, c->height, - clip_x0, clip_y0, clip_x1, clip_y1, - g->option.scale, - 0xFFFFFF); - } else { - assert(data->redraw.object); - content_redraw(data->redraw.object, - floorf(data->redraw.object_x * - g->option.scale), - ceilf(data->redraw.object_y * - g->option.scale), - data->redraw.object_width * - g->option.scale, - data->redraw.object_height * - g->option.scale, - clip_x0, clip_y0, clip_x1, clip_y1, - g->option.scale, - 0xFFFFFF); - } - - if (use_buffer) - ro_gui_buffer_close(); - error = xwimp_get_rectangle(&update, &more); - /* RISC OS 3.7 returns an error here if enough buffer was - claimed to cause a new dynamic area to be created. It - doesn't actually stop anything working, so we mask it out - for now until a better fix is found. This appears to be a - bug in RISC OS. */ - if (error && !(use_buffer && - error->errnum == error_WIMP_GET_RECT)) { - LOG(("xwimp_get_rectangle: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - ro_gui_current_redraw_gui = NULL; - current_redraw_browser = NULL; - continue; - } - } - - /* Reset the current redraw gui_window to prevent thumbnails from - retaining options - */ - ro_gui_current_redraw_gui = NULL; - current_redraw_browser = NULL; - } - while (pending_updates) { - cur = pending_updates; - pending_updates = pending_updates->next; - free(cur); - } - -} -/** * Redraw an area of a window. * * \param g gui_window @@ -833,6 +601,7 @@ 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); @@ -844,16 +613,12 @@ bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) warn_user("WimpError", error->errmess); return false; } - else { - int toolbar_height = 0; - - if (g->toolbar) - toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar); - *sx = state.xscroll / (2 * g->option.scale); - *sy = -(state.yscroll - toolbar_height) / (2 * g->option.scale); - return true; - } + if (g->toolbar) + toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar); + *sx = state.xscroll / (2 * g->option.scale); + *sy = -(state.yscroll - toolbar_height) / (2 * g->option.scale); + return true; } @@ -998,7 +763,7 @@ void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int parent = bw->parent; assert(parent); top = browser_window_owner(bw); - + /* store position for children */ if (parent->browser_window_type == BROWSER_WINDOW_IFRAME) { bw->x0 = x0; @@ -1065,12 +830,15 @@ void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int /** - * Find the current unscaled dimensions of a browser window's content area. + * Find the current dimensions of a browser window's content area. * - * \param g gui_window to measure + * \param g gui_window to measure + * \param width receives width of window + * \param height receives height of window + * \param scaled whether to return scaled values */ -void gui_window_get_dimensions(struct gui_window *g, int *width, int *height) +void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bool scaled) { wimp_window_state state; os_error *error; @@ -1088,86 +856,31 @@ void gui_window_get_dimensions(struct gui_window *g, int *width, int *height) } *width = (state.visible.x1 - state.visible.x0) / 2; - *height = (state.visible.y1 - state.visible.y0 - (g->toolbar ? - ro_gui_theme_toolbar_full_height(g->toolbar) : 0)) / 2; -} - - -/** - * Find the current scaled width of a browser window. - * - * \param g gui_window to measure - * \return width of window - */ - -int gui_window_get_width(struct gui_window *g) -{ - wimp_window_state state; - os_error *error; - - state.w = g->window; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return 800; - } - return (state.visible.x1 - state.visible.x0) / 2 / g->option.scale; -} - - -/** - * Find the current scaled height of a browser window. - * - * \param g gui_window to measure - * \return height of window - */ - -int gui_window_get_height(struct gui_window *g) -{ - wimp_window_state state; - os_error *error; - - state.w = g->window; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return 800; + *height = ((state.visible.y1 - state.visible.y0) - + (g->toolbar ? ro_gui_theme_toolbar_full_height(g->toolbar) : 0)) / 2; + if (scaled) { + *width /= g->option.scale; + *height /= g->option.scale; } - return (state.visible.y1 - state.visible.y0 - (g->toolbar ? - ro_gui_theme_toolbar_full_height(g->toolbar) : 0)) / - 2 / g->option.scale; } /** * Update the extent of the inside of a browser window to that of the current content. * - * \param g gui_window to resize + * \param g gui_window to update the extent of */ void gui_window_update_extent(struct gui_window *g) { - ro_gui_window_update_dimensions(g, 0); -} - - -/** - * Forces the windows extent to be updated - * - * /param g the gui window to update - * /param yscroll an amount to scroll the vertical scroll bar by - */ -void ro_gui_window_update_dimensions(struct gui_window *g, int yscroll) { os_error *error; wimp_window_state state; bool update; unsigned int flags; - - if (!g) return; + int scroll = 0; + + assert(g); + state.w = g->window; error = xwimp_get_window_state(&state); if (error) { @@ -1176,14 +889,21 @@ void ro_gui_window_update_dimensions(struct gui_window *g, int yscroll) { warn_user("WimpError", error->errmess); return; } - state.yscroll -= yscroll; g->old_height = -1; - + + /* scroll on toolbar height change */ + if (g->toolbar) { + scroll = ro_gui_theme_height_change(g->toolbar); + state.yscroll -= scroll; + if (state.yscroll < 0) + state.yscroll = 0; + } + /* only allow a further reformat if we've gained/lost scrollbars */ flags = state.flags & (wimp_WINDOW_HSCROLL | wimp_WINDOW_VSCROLL); update = g->reformat_pending; ro_gui_window_open((wimp_open *)&state); - + state.w = g->window; error = xwimp_get_window_state(&state); if (error) { @@ -1194,6 +914,9 @@ void ro_gui_window_update_dimensions(struct gui_window *g, int yscroll) { } if (flags == (state.flags & (wimp_WINDOW_HSCROLL | wimp_WINDOW_VSCROLL))) g->reformat_pending = update; + + if ((scroll != 0) && (g->bw->children)) + browser_window_recalculate_frameset(g->bw); } @@ -1215,6 +938,67 @@ void gui_window_set_status(struct gui_window *g, const char *text) /** + * Change mouse pointer shape + */ + +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; + + if (shape == curr_pointer) + return; + + assert(shape < sizeof ro_gui_pointer_table / + sizeof ro_gui_pointer_table[0]); + + 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)); + 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)); + warn_user("WimpError", error->errmess); + } + } + + curr_pointer = shape; +} + + +/** + * Remove the mouse pointer from the screen + */ + +void gui_window_hide_pointer(struct gui_window *g) +{ + os_error *error; + + error = xwimpspriteop_set_pointer_shape(NULL, 0x30, 0, 0, 0, 0); + if (error) { + LOG(("xwimpspriteop_set_pointer_shape: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } +} + + +/** * Set the contents of a window's address bar. * * \param g gui_window to update @@ -1262,6 +1046,543 @@ void gui_window_set_url(struct gui_window *g, const char *url) /** + * Update the interface to reflect start of page loading. + * + * \param g window with start of load + */ + +void gui_window_start_throbber(struct gui_window *g) +{ + ro_gui_menu_objects_moved(); + ro_gui_prepare_navigate(g); + xos_read_monotonic_time(&g->throbtime); + g->throbber = 0; +} + + + +/** + * Update the interface to reflect page loading stopped. + * + * \param g window with start of load + */ + +void gui_window_stop_throbber(struct gui_window *g) +{ + char throb_buf[12]; + ro_gui_prepare_navigate(g); + g->throbber = 0; + if (g->toolbar) { + strcpy(throb_buf, "throbber0"); + ro_gui_set_icon_string(g->toolbar->toolbar_handle, + ICON_TOOLBAR_THROBBER, throb_buf); + if ((g->toolbar->descriptor) && (g->toolbar->descriptor->throbber_redraw)) + ro_gui_force_redraw_icon(g->toolbar->toolbar_handle, + ICON_TOOLBAR_THROBBER); + } +} + + +/** + * 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 + */ + +void gui_window_place_caret(struct gui_window *g, int x, int y, int height) +{ + os_error *error; + + error = xwimp_set_caret_position(g->window, -1, + x * 2 * g->option.scale, + -(y + height) * 2 * g->option.scale, + height * 2 * g->option.scale, -1); + if (error) { + LOG(("xwimp_set_caret_position: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } +} + + +/** + * Remove the caret, if present. + * + * \param g window with caret + */ + +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_get_caret_position: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + + if (caret.w != g->window) + /* we don't have the caret: do nothing */ + return; + + /* hide caret, but keep input focus */ + gui_window_place_caret(g, -100, -100, 0); +} + + +/** + * Called when the gui_window has new content. + * + * \param g the gui_window that has new content + */ + +void gui_window_new_content(struct gui_window *g) +{ + ro_gui_menu_objects_moved(); + ro_gui_prepare_navigate(g); + ro_gui_dialog_close_persistent(g->window); +} + + +/** + * Starts drag scrolling of a browser window + * + * \param gw gui window + */ + +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; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG(("xwimp_get_pointer_info 0x%x : %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return 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)); + warn_user("WimpError", error->errmess); + return false; + } + + 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_gui_theme_toolbar_full_height(g->toolbar); + drag.bbox.y0 -= tbar_height; + drag.bbox.y1 -= tbar_height; + } + + error = xwimp_drag_box(&drag); + if (error) { + LOG(("xwimp_drag_box: 0x%x : %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return false; + } + + gui_current_drag_type = GUI_DRAG_SCROLL; + return true; +} + + +/** + * Platform-dependent part of starting a box scrolling operation, + * for frames and textareas. + * + * \param x0 minimum x ordinate of box relative to mouse pointer + * \param y0 minimum y ordinate + * \param x1 maximum x ordinate + * \param y1 maximum y ordinate + * \return true iff succesful + */ + +bool gui_window_box_scroll_start(struct gui_window *g, int x0, int y0, int x1, int y1) +{ + wimp_pointer pointer; + os_error *error; + wimp_drag drag; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG(("xwimp_get_pointer_info 0x%x : %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return false; + } + + drag.type = wimp_DRAG_USER_POINT; + drag.bbox.x0 = pointer.pos.x + (int)(x0 * 2 * g->option.scale); + drag.bbox.y0 = pointer.pos.y + (int)(y0 * 2 * g->option.scale); + drag.bbox.x1 = pointer.pos.x + (int)(x1 * 2 * g->option.scale); + drag.bbox.y1 = pointer.pos.y + (int)(y1 * 2 * g->option.scale); + + error = xwimp_drag_box(&drag); + if (error) { + LOG(("xwimp_drag_box: 0x%x : %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return false; + } + + gui_current_drag_type = GUI_DRAG_SCROLL; + return true; +} + + +/** + * Starts drag resizing of a browser frame + * + * \param gw gui window + */ + +bool gui_window_frame_resize_start(struct gui_window *g) +{ + wimp_pointer pointer; + os_error *error; + wimp_drag drag; + int x0, y0, x1, y1; + int row = -1, col = -1, i; + struct browser_window *top, *bw; + wimp_window_state state; + + /* get the maximum drag box (collapse all surrounding frames */ + bw = g->bw; + x0 = bw->x0; + y0 = bw->y0; + x1 = bw->x1; + y1 = bw->y1; + for (i = 0; i < (bw->parent->cols * bw->parent->rows); i++) { + if (&bw->parent->children[i] == bw) { + col = i % bw->parent->cols; + row = i / bw->parent->cols; + } + } + assert((row >= 0) && (col >= 0)); + + if (g->bw->drag_resize_left) + x0 = bw->parent->children[row * bw->parent->cols + (col - 1)].x0; + if (g->bw->drag_resize_right) + x1 = bw->parent->children[row * bw->parent->cols + (col + 1)].x1; + if (g->bw->drag_resize_up) + y0 = bw->parent->children[(row - 1) * bw->parent->cols + col].y0; + if (g->bw->drag_resize_down) + y1 = bw->parent->children[(row + 1) * bw->parent->cols + col].y1; + + /* convert to screen co-ordinates */ + top = browser_window_owner(bw); + state.w = top->window->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return false; + } + x0 = state.visible.x0 + x0 * 2; + y0 = state.visible.y0 + y0 * 2; + x1 = state.visible.x0 + x1 * 2 - 1; + y1 = state.visible.y0 + y1 * 2 - 1; + + /* get the pointer position */ + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG(("xwimp_get_pointer_info 0x%x : %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return false; + } + + /* stop dragging in directions we can't extend */ + if (!(g->bw->drag_resize_left || g->bw->drag_resize_right)) { + x0 = pointer.pos.x; + x1 = pointer.pos.x; + } + if (!(g->bw->drag_resize_up || g->bw->drag_resize_down)) { + y0 = pointer.pos.y; + y1 = pointer.pos.y; + } + + /* start the drag */ + drag.type = wimp_DRAG_USER_POINT; + drag.bbox.x0 = x0; + drag.bbox.y0 = y0; + drag.bbox.x1 = x1; + drag.bbox.y1 = y1; + + error = xwimp_drag_box(&drag); + if (error) { + LOG(("xwimp_drag_box: 0x%x : %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return false; + } + + /* we may not be the window the pointer is currently over */ + gui_track_gui_window = bw->window; + gui_current_drag_type = GUI_DRAG_FRAME; + return true; +} + + +/** + * Redraws the content for all windows. + */ + +void ro_gui_window_redraw_all(void) +{ + struct gui_window *g; + for (g = window_list; g; g = g->next) + gui_window_redraw_window(g); +} + +/** + * Handle a Redraw_Window_Request for a browser window. + */ + +void ro_gui_window_redraw(wimp_draw *redraw) +{ + osbool more; + bool knockout = true; + struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(redraw->w); + float scale = g->option.scale; + struct content *c = g->bw->current_content; + int clip_x0, clip_y0, clip_x1, clip_y1, clear_x1, clear_y1; + os_error *error; + + /* Handle no content quickly + */ + if (!c) { + ro_gui_user_redraw(redraw, true, os_COLOUR_WHITE); + return; + } + + plot = ro_plotters; + ro_plot_set_scale(scale); + ro_gui_current_redraw_gui = g; + current_redraw_browser = g->bw; + + /* rendering textplain has no advantages using knockout rendering other than to + * slow things down. */ + if (c->type == CONTENT_TEXTPLAIN) + knockout = false; + + /* HTML rendering handles scale itself */ + if (c->type == CONTENT_HTML) + scale = 1; + + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG(("xwimp_redraw_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + while (more) { + ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; + ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; + clip_x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; + clip_y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; + clip_x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; + clip_y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; + clear_x1 = redraw->clip.x1 - ro_plot_origin_x; + clear_y1 = redraw->clip.y0 - ro_plot_origin_y; + + if (ro_gui_current_redraw_gui->option.buffer_everything) + ro_gui_buffer_open(redraw); + + if (knockout) { + knockout_plot_start(&plot); + plot.clip(clip_x0, clip_y0, clip_x1, clip_y1); + plot.clg(0x00ffffff); + } + + content_redraw(c, 0, 0, + c->width * scale, c->height * scale, + clip_x0, clip_y0, clip_x1, clip_y1, + g->option.scale, + 0xFFFFFF); + if (knockout) + knockout_plot_end(); + if (ro_gui_current_redraw_gui->option.buffer_everything) + ro_gui_buffer_close(); + + 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)); + warn_user("WimpError", error->errmess); + ro_gui_current_redraw_gui = NULL; + current_redraw_browser = NULL; + return; + } + } + ro_gui_current_redraw_gui = NULL; + current_redraw_browser = NULL; +} + + +/** + * Redraw any pending update boxes. + */ +void ro_gui_window_update_boxes(void) { + struct content *c; + osbool more; + bool clear_background = false; + bool use_buffer; + wimp_draw update; + int clip_x0, clip_y0, clip_x1, clip_y1; + os_error *error; + struct update_box *cur; + struct gui_window *g; + const union content_msg_data *data; + + for (cur = pending_updates; cur != NULL; cur = cur->next) { + g = cur->g; + c = g->bw->current_content; + data = &cur->data; + use_buffer = cur->use_buffer; + if (!c) + continue; + + update.w = g->window; + update.box.x0 = cur->x0; + update.box.y0 = cur->y0; + update.box.x1 = cur->x1; + update.box.y1 = cur->y1; + + error = xwimp_update_window(&update, &more); + if (error) { + LOG(("xwimp_update_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + continue; + } + + /* Set the current redraw gui_window to get options from + */ + ro_gui_current_redraw_gui = g; + current_redraw_browser = g->bw; + + plot = ro_plotters; + ro_plot_origin_x = update.box.x0 - update.xscroll; + ro_plot_origin_y = update.box.y1 - update.yscroll; + ro_plot_set_scale(g->option.scale); + + /* We should clear the background, except for HTML. + */ + if (c->type != CONTENT_HTML) + clear_background = true; + + while (more) { + clip_x0 = (update.clip.x0 - ro_plot_origin_x) / 2; + clip_y0 = (ro_plot_origin_y - update.clip.y1) / 2; + clip_x1 = (update.clip.x1 - ro_plot_origin_x) / 2; + clip_y1 = (ro_plot_origin_y - update.clip.y0) / 2; + + if (use_buffer) + ro_gui_buffer_open(&update); + if (data->redraw.full_redraw) { + if (clear_background) { + error = xcolourtrans_set_gcol(os_COLOUR_WHITE, + colourtrans_SET_BG, + os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG(("xcolourtrans_set_gcol: 0x%x: %s", + error->errnum, + error->errmess)); + warn_user("MiscError", error->errmess); + } + os_clg(); + } + + content_redraw(c, 0, 0, + c->width, c->height, + clip_x0, clip_y0, clip_x1, clip_y1, + g->option.scale, + 0xFFFFFF); + } else { + assert(data->redraw.object); + content_redraw(data->redraw.object, + floorf(data->redraw.object_x * + g->option.scale), + ceilf(data->redraw.object_y * + g->option.scale), + data->redraw.object_width * + g->option.scale, + data->redraw.object_height * + g->option.scale, + clip_x0, clip_y0, clip_x1, clip_y1, + g->option.scale, + 0xFFFFFF); + } + + if (use_buffer) + ro_gui_buffer_close(); + error = xwimp_get_rectangle(&update, &more); + /* RISC OS 3.7 returns an error here if enough buffer was + claimed to cause a new dynamic area to be created. It + doesn't actually stop anything working, so we mask it out + for now until a better fix is found. This appears to be a + bug in RISC OS. */ + if (error && !(use_buffer && + error->errnum == error_WIMP_GET_RECT)) { + LOG(("xwimp_get_rectangle: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + ro_gui_current_redraw_gui = NULL; + current_redraw_browser = NULL; + continue; + } + } + + /* Reset the current redraw gui_window to prevent thumbnails from + retaining options + */ + ro_gui_current_redraw_gui = NULL; + current_redraw_browser = NULL; + } + while (pending_updates) { + cur = pending_updates; + pending_updates = pending_updates->next; + free(cur); + } + +} + + +/** * Launch a new url in the given window. * * \param g gui_window to update @@ -1286,60 +1607,22 @@ void ro_gui_window_launch_url(struct gui_window *g, const char *url) /** * Forces all windows to be set to the current theme - * - * /param g the gui window to update */ void ro_gui_window_update_theme(void) { - int height; struct gui_window *g; for (g = window_list; g; g = g->next) { if (g->toolbar) { - height = ro_gui_theme_toolbar_height(g->toolbar); if (g->toolbar->editor) if (!ro_gui_theme_update_toolbar(NULL, g->toolbar->editor)) g->toolbar->editor = NULL; if (!ro_gui_theme_update_toolbar(NULL, g->toolbar)) { ro_gui_theme_destroy_toolbar(g->toolbar); g->toolbar = NULL; - if (height != 0) - ro_gui_window_update_dimensions(g, height); - } else { - if (height != (ro_gui_theme_toolbar_height(g->toolbar))) - ro_gui_window_update_dimensions(g, height - - ro_gui_theme_toolbar_height(g->toolbar)); } ro_gui_theme_toolbar_editor_sync(g->toolbar); + gui_window_update_extent(g); } } - if ((hotlist_tree) && (hotlist_tree->toolbar)) { - if (hotlist_tree->toolbar->editor) - if (!ro_gui_theme_update_toolbar(NULL, hotlist_tree->toolbar->editor)) - hotlist_tree->toolbar->editor = NULL; - if (!ro_gui_theme_update_toolbar(NULL, hotlist_tree->toolbar)) { - ro_gui_theme_destroy_toolbar(hotlist_tree->toolbar); - hotlist_tree->toolbar = NULL; - } - ro_gui_theme_toolbar_editor_sync(hotlist_tree->toolbar); - ro_gui_theme_attach_toolbar(hotlist_tree->toolbar, - (wimp_w)hotlist_tree->handle); - xwimp_force_redraw((wimp_w)hotlist_tree->handle, - 0, -16384, 16384, 16384); - } - if ((global_history_tree) && (global_history_tree->toolbar)) { - if (global_history_tree->toolbar->editor) - if (!ro_gui_theme_update_toolbar(NULL, - global_history_tree->toolbar->editor)) - global_history_tree->toolbar->editor = NULL; - if (!ro_gui_theme_update_toolbar(NULL, global_history_tree->toolbar)) { - ro_gui_theme_destroy_toolbar(global_history_tree->toolbar); - global_history_tree->toolbar = NULL; - } - ro_gui_theme_toolbar_editor_sync(global_history_tree->toolbar); - ro_gui_theme_attach_toolbar(global_history_tree->toolbar, - (wimp_w)global_history_tree->handle); - xwimp_force_redraw((wimp_w)global_history_tree->handle, - 0, -16384, 16384, 16384); - } } @@ -1385,7 +1668,7 @@ void ro_gui_window_open(wimp_open *open) if (g->toolbar) toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar); height -= toolbar_height; - + /* work with the state from now on so we can modify flags */ state.visible.x0 = open->visible.x0; state.visible.y0 = open->visible.y0; @@ -1394,7 +1677,7 @@ void ro_gui_window_open(wimp_open *open) state.xscroll = open->xscroll; state.yscroll = open->yscroll; state.next = open->next; - + /* frameset windows shouldn't be shown */ if ((g->bw->parent) && (g->bw->children)) state.next = wimp_HIDDEN; @@ -1405,7 +1688,7 @@ void ro_gui_window_open(wimp_open *open) no_hscroll = (g->bw->children && (g->bw->browser_window_type != BROWSER_WINDOW_NORMAL)); no_vscroll = g->bw->children; - + /* hscroll */ size = ro_get_hscroll_height(NULL); if (g->bw->border) @@ -1438,7 +1721,7 @@ void ro_gui_window_open(wimp_open *open) } state.flags &= ~wimp_WINDOW_HSCROLL; } - + /* vscroll */ size = ro_get_vscroll_width(NULL); if (g->bw->border) @@ -1476,7 +1759,7 @@ void ro_gui_window_open(wimp_open *open) /* change extent if necessary */ if (g->old_width != width || g->old_height != height) { if (content) { - if (g->old_width != width) { + if (g->old_width != width) { xosbyte1(osbyte_SCAN_KEYBOARD, 1 ^ 0x80, 0, &key_down); if (key_down) g->option.scale = (g->option.scale * width) / g->old_width; @@ -1487,7 +1770,7 @@ void ro_gui_window_open(wimp_open *open) g->old_width = width; g->old_height = height; - + if (content && height < content->height * 2 * g->option.scale) height = content->height * 2 * g->option.scale; if (content && width < content->width * 2 * g->option.scale) @@ -1567,9 +1850,9 @@ void ro_gui_window_close(wimp_w w) { } free(filename); } else { - /* this is pointless if we are about to close the window */ - if (ro_gui_shift_pressed()) - ro_gui_menu_handle_action(w, BROWSER_NAVIGATE_UP, true); + /* this is pointless if we are about to close the window */ + if (ro_gui_shift_pressed()) + ro_gui_menu_handle_action(w, BROWSER_NAVIGATE_UP, true); } } if (ro_gui_shift_pressed()) @@ -1578,7 +1861,26 @@ void ro_gui_window_close(wimp_w w) { ro_gui_dialog_close_persistent(w); browser_window_destroy(g->bw); return; - + +} + + +/** + * Destroy all browser windows. + */ + +void ro_gui_window_quit(void) +{ + struct gui_window *cur; + + while (window_list) { + cur = window_list; + window_list = window_list->next; + + /* framesets and iframes are destroyed by their parents */ + if (!cur->bw->parent) + browser_window_destroy(cur->bw); + } } @@ -1682,29 +1984,13 @@ struct gui_window *ro_gui_status_lookup(wimp_w window) void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer) { - int x, y; - wimp_window_state state; - os_error *error; - - assert(g); + os_coord pos; - state.w = g->window; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); -/* - * the WIMP sometimes fails to realise the pointer has left a NetSurf window - * so we get an error -- there is no gain from telling the user about this - * - * warn_user("WimpError", error->errmess); -*/ return; - } - - x = window_x_units(pointer->pos.x, &state) / 2 / g->option.scale; - y = -window_y_units(pointer->pos.y, &state) / 2 / g->option.scale; - - browser_window_mouse_track(g->bw, ro_gui_mouse_drag_state(pointer->buttons), x, y); + 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), + pos.x, pos.y); + LOG(("(%i, %i) -> (%i, %i)", pointer->pos.x, pointer->pos.y, pos.x, pos.y)); } @@ -1910,131 +2196,27 @@ bool ro_gui_status_click(wimp_pointer *pointer) bool ro_gui_window_click(wimp_pointer *pointer) { struct gui_window *g; - wimp_window_state state; - os_error *error; - int x, y; + os_coord pos; g = (struct gui_window *)ro_gui_wimp_event_get_user_data(pointer->w); /* try to close url-completion */ ro_gui_url_complete_close(g, pointer->i); - state.w = pointer->w; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, - error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - x = window_x_units(pointer->pos.x, &state) / 2 / g->option.scale; - y = -window_y_units(pointer->pos.y, &state) / 2 / g->option.scale; - /* set input focus */ if (pointer->buttons == wimp_CLICK_SELECT || pointer->buttons == wimp_CLICK_ADJUST) gui_window_place_caret(g, -100, -100, 0); - if (pointer->buttons == wimp_CLICK_MENU) - ro_gui_menu_create(browser_menu, pointer->pos.x, - pointer->pos.y, pointer->w); - else - browser_window_mouse_click(g->bw, - ro_gui_mouse_click_state(pointer->buttons), x, y); - - return true; -} - - -/** - * Update the interface to reflect start of page loading. - * - * \param g window with start of load - */ - -void gui_window_start_throbber(struct gui_window *g) -{ - ro_gui_menu_objects_moved(); - ro_gui_prepare_navigate(g); - xos_read_monotonic_time(&g->throbtime); - g->throbber = 0; -} - - - -/** - * Update the interface to reflect page loading stopped. - * - * \param g window with start of load - */ - -void gui_window_stop_throbber(struct gui_window *g) -{ - char throb_buf[12]; - ro_gui_prepare_navigate(g); - g->throbber = 0; - if (g->toolbar) { - strcpy(throb_buf, "throbber0"); - ro_gui_set_icon_string(g->toolbar->toolbar_handle, - ICON_TOOLBAR_THROBBER, throb_buf); - if ((g->toolbar->descriptor) && (g->toolbar->descriptor->throbber_redraw)) - ro_gui_force_redraw_icon(g->toolbar->toolbar_handle, - ICON_TOOLBAR_THROBBER); - } -} - - -/** - * 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 - */ - -void gui_window_place_caret(struct gui_window *g, int x, int y, int height) -{ - os_error *error; - - error = xwimp_set_caret_position(g->window, -1, - x * 2 * g->option.scale, - -(y + height) * 2 * g->option.scale, - height * 2 * g->option.scale, -1); - if (error) { - LOG(("xwimp_set_caret_position: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - } -} - - -/** - * Remove the caret, if present. - * - * \param g window with caret - */ - -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_get_caret_position: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; + if (pointer->buttons == wimp_CLICK_MENU) { + ro_gui_menu_create(browser_menu, pointer->pos.x, pointer->pos.y, pointer->w); + } else { + if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos)) + browser_window_mouse_click(g->bw, + ro_gui_mouse_click_state(pointer->buttons), + pos.x, pos.y); } - - if (caret.w != g->window) - /* we don't have the caret: do nothing */ - return; - - /* hide caret, but keep input focus */ - gui_window_place_caret(g, -100, -100, 0); + return true; } @@ -2446,28 +2628,33 @@ void ro_gui_scroll_request(wimp_scroll *scroll) /** - * Convert x from screen to window coordinates. + * Convert x,y screen co-ordinates into window co-ordinates. * - * \param x x coordinate / os units - * \param state window state - * \return x coordinate in window / os units + * \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 */ -//#define window_x_units(x, state) (x - (state->visible.x0 - state->xscroll)) -int window_x_units(int x, wimp_window_state *state) { - return x - (state->visible.x0 - state->xscroll); -} +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; -/** - * Convert y from screen to window coordinates. - * - * \param y y coordinate / os units - * \param state window state - * \return y coordinate in window / os units - */ -//#define window_y_units(y, state) (y - (state->visible.y1 - state->yscroll)) -int window_y_units(int y, wimp_window_state *state) { - return y - (state->visible.y1 - state->yscroll); + assert(g); + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x:%s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return false; + } + pos->x = (x - (state.visible.x0 - state.xscroll)) / 2 / g->option.scale; + pos->y = ((state.visible.y1 - state.yscroll) - y) / 2 / g->option.scale; + return true; } @@ -2481,11 +2668,13 @@ int window_y_units(int y, wimp_window_state *state) { * \return true iff conversion successful */ -bool window_screen_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) { wimp_window_state state; os_error *error; + assert(g); + state.w = g->window; error = xwimp_get_window_state(&state); if (error) { @@ -2494,8 +2683,8 @@ bool window_screen_pos(struct gui_window *g, int x, int y, os_coord *pos) warn_user("WimpError", error->errmess); return false; } - pos->x = state.visible.x0 + ((x * 2 * g->option.scale) - state.xscroll); - pos->y = state.visible.y1 + ((-y * 2 * g->option.scale) - state.yscroll); + pos->x = (x * 2 * g->option.scale) + (state.visible.x0 - state.xscroll); + pos->y = (state.visible.y1 - state.yscroll) - (y * 2 * g->option.scale); return true; } @@ -2513,14 +2702,13 @@ bool window_screen_pos(struct gui_window *g, int x, int y, os_coord *pos) bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message) { int box_x = 0, box_y = 0; - int x, y; struct box *box; struct box *file_box = 0; struct box *text_box = 0; struct browser_window *bw = g->bw; struct content *content; - wimp_window_state state; os_error *error; + os_coord pos; /* HTML content only. */ if (!bw->current_content || bw->current_content->type != CONTENT_HTML) @@ -2530,24 +2718,13 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message) if (0x1000 <= message->data.data_xfer.file_type) return false; - /* Search for a file input or text area at the drop point. */ - state.w = message->data.data_xfer.w; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s\n", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); + if (!ro_gui_window_to_window_pos(g, message->data.data_xfer.pos.x, + message->data.data_xfer.pos.x, &pos)) return false; - } - - x = window_x_units(message->data.data_xfer.pos.x, &state) / 2 / - g->option.scale; - y = -window_y_units(message->data.data_xfer.pos.y, &state) / 2 / - g->option.scale; content = bw->current_content; box = content->data.html.layout; - while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) { + while ((box = box_at_point(box, pos.x, pos.y, &box_x, &box_y, &content))) { if (box->style && box->style->visibility == CSS_VISIBILITY_HIDDEN) continue; @@ -2593,15 +2770,15 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message) file_box->gadget->value = utf8_fn; /* Redraw box. */ - box_coords(file_box, &x, &y); - gui_window_redraw(bw->window, x, y, - x + file_box->width, - y + file_box->height); + box_coords(file_box, &pos.x, &pos.y); + gui_window_redraw(bw->window, pos.x, pos.y, + pos.x + file_box->width, + pos.y + file_box->height); } else { const char *filename = message->data.data_xfer.file_name; - browser_window_mouse_click(g->bw, BROWSER_MOUSE_CLICK_1, x, y); + browser_window_mouse_click(g->bw, BROWSER_MOUSE_CLICK_1, pos.x, pos.y); if (!ro_gui_window_import_text(g, filename, false)) return true; /* it was for us, it just didn't work! */ @@ -2666,7 +2843,7 @@ void ro_gui_window_process_reformats(void) g->reformat_pending = false; content_reformat(g->bw->current_content, g->old_width / 2 / g->option.scale, - gui_window_get_height(g)); + g->old_height / 2 / g->option.scale); } } @@ -2759,111 +2936,6 @@ void ro_gui_window_default_options(struct browser_window *bw) { } -/** An entry in ro_gui_pointer_table. */ -struct ro_gui_pointer_entry { - bool wimp_area; /** The pointer is in the Wimp's sprite area. */ - char sprite_name[12]; - int xactive; - int yactive; -}; - -/** 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 }, - { false, "ptr_point", 6, 0 }, - { false, "ptr_caret", 4, 9 }, - { false, "ptr_menu", 6, 4 }, - { false, "ptr_ud", 6, 7 }, - { false, "ptr_ud", 6, 7 }, - { false, "ptr_lr", 7, 6 }, - { false, "ptr_lr", 7, 6 }, - { false, "ptr_ld", 7, 7 }, - { false, "ptr_ld", 7, 7 }, - { false, "ptr_rd", 7, 7 }, - { false, "ptr_rd", 6, 7 }, - { false, "ptr_cross", 7, 7 }, - { false, "ptr_move", 8, 0 }, - { false, "ptr_wait", 7, 10 }, - { false, "ptr_help", 0, 0 }, - { false, "ptr_nodrop", 0, 0 }, - { false, "ptr_nt_allwd", 10, 10 }, - { false, "ptr_progress", 0, 0 }, -}; - -/** - * Change mouse pointer shape - */ - -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; - - if (shape == curr_pointer) - return; - - assert(shape < sizeof ro_gui_pointer_table / - sizeof ro_gui_pointer_table[0]); - - 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)); - 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)); - warn_user("WimpError", error->errmess); - } - } - - curr_pointer = shape; -} - - -/** - * Remove the mouse pointer from the screen - */ - -void gui_window_hide_pointer(struct gui_window *g) -{ - os_error *error; - - error = xwimpspriteop_set_pointer_shape(NULL, 0x30, 0, 0, 0, 0); - if (error) { - LOG(("xwimpspriteop_set_pointer_shape: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - } -} - - -/** - * Called when the gui_window has new content. - * - * \param g the gui_window that has new content - */ - -void gui_window_new_content(struct gui_window *g) -{ - ro_gui_menu_objects_moved(); - ro_gui_prepare_navigate(g); - ro_gui_dialog_close_persistent(g->window); -} /** @@ -2947,110 +3019,6 @@ bool ro_gui_ctrl_pressed(void) /** - * Platform-dependent part of starting a box scrolling operation, - * for frames and textareas. - * - * \param x0 minimum x ordinate of box relative to mouse pointer - * \param y0 minimum y ordinate - * \param x1 maximum x ordinate - * \param y1 maximum y ordinate - * \return true iff succesful - */ - -bool gui_window_box_scroll_start(struct gui_window *g, int x0, int y0, int x1, int y1) -{ - wimp_pointer pointer; - os_error *error; - wimp_drag drag; - - error = xwimp_get_pointer_info(&pointer); - if (error) { - LOG(("xwimp_get_pointer_info 0x%x : %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - drag.type = wimp_DRAG_USER_POINT; - drag.bbox.x0 = pointer.pos.x + (int)(x0 * 2 * g->option.scale); - drag.bbox.y0 = pointer.pos.y + (int)(y0 * 2 * g->option.scale); - drag.bbox.x1 = pointer.pos.x + (int)(x1 * 2 * g->option.scale); - drag.bbox.y1 = pointer.pos.y + (int)(y1 * 2 * g->option.scale); - - error = xwimp_drag_box(&drag); - if (error) { - LOG(("xwimp_drag_box: 0x%x : %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - gui_current_drag_type = GUI_DRAG_SCROLL; - return true; -} - - -/** - * Starts drag scrolling of a browser window - * - * \param gw gui window - */ - -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; - - error = xwimp_get_pointer_info(&pointer); - if (error) { - LOG(("xwimp_get_pointer_info 0x%x : %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return 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)); - warn_user("WimpError", error->errmess); - return false; - } - - 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_gui_theme_toolbar_full_height(g->toolbar); - drag.bbox.y0 -= tbar_height; - drag.bbox.y1 -= tbar_height; - } - - error = xwimp_drag_box(&drag); - if (error) { - LOG(("xwimp_drag_box: 0x%x : %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - gui_current_drag_type = GUI_DRAG_SCROLL; - return true; -} - - -/** * Completes scrolling of a browser window * * \param g gui window @@ -3058,10 +3026,9 @@ bool gui_window_scroll_start(struct gui_window *g) void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag) { - wimp_window_state state; wimp_pointer pointer; os_error *error; - int x, y; + os_coord pos; gui_current_drag_type = GUI_DRAG_NONE; if (!g) @@ -3089,115 +3056,26 @@ void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag) warn_user("WimpError", error->errmess); } - state.w = g->window; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state 0x%x : %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - - x = window_x_units(drag->final.x0, &state) / 2 / g->option.scale; - y = -window_y_units(drag->final.y0, &state) / 2 / g->option.scale; - - browser_window_mouse_drag_end(g->bw, - ro_gui_mouse_click_state(pointer.buttons), x, y); + if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) + browser_window_mouse_drag_end(g->bw, + ro_gui_mouse_click_state(pointer.buttons), + pos.x, pos.y); } /** - * Starts drag resizing of a browser frame + * Save the specified content as a link. * - * \param gw gui window + * \param g gui_window containing the content + * \param c the content to save */ -bool gui_window_frame_resize_start(struct gui_window *g) +void gui_window_save_as_link(struct gui_window *g, struct content *c) { - wimp_pointer pointer; - os_error *error; - wimp_drag drag; - int x0, y0, x1, y1; - int row = -1, col = -1, i; - struct browser_window *top, *bw; - wimp_window_state state; - - /* get the maximum drag box (collapse all surrounding frames */ - bw = g->bw; - x0 = bw->x0; - y0 = bw->y0; - x1 = bw->x1; - y1 = bw->y1; - for (i = 0; i < (bw->parent->cols * bw->parent->rows); i++) { - if (&bw->parent->children[i] == bw) { - col = i % bw->parent->cols; - row = i / bw->parent->cols; - } - } - assert((row >= 0) && (col >= 0)); - - if (g->bw->drag_resize_left) - x0 = bw->parent->children[row * bw->parent->cols + (col - 1)].x0; - if (g->bw->drag_resize_right) - x1 = bw->parent->children[row * bw->parent->cols + (col + 1)].x1; - if (g->bw->drag_resize_up) - y0 = bw->parent->children[(row - 1) * bw->parent->cols + col].y0; - if (g->bw->drag_resize_down) - y1 = bw->parent->children[(row + 1) * bw->parent->cols + col].y1; - - /* convert to screen co-ordinates */ - top = browser_window_owner(bw); - state.w = top->window->window; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - x0 = state.visible.x0 + x0 * 2; - y0 = state.visible.y0 + y0 * 2; - x1 = state.visible.x0 + x1 * 2 - 1; - y1 = state.visible.y0 + y1 * 2 - 1; - - /* get the pointer position */ - error = xwimp_get_pointer_info(&pointer); - if (error) { - LOG(("xwimp_get_pointer_info 0x%x : %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - /* stop dragging in directions we can't extend */ - if (!(g->bw->drag_resize_left || g->bw->drag_resize_right)) { - x0 = pointer.pos.x; - x1 = pointer.pos.x; - } - if (!(g->bw->drag_resize_up || g->bw->drag_resize_down)) { - y0 = pointer.pos.y; - y1 = pointer.pos.y; - } - - /* start the drag */ - drag.type = wimp_DRAG_USER_POINT; - drag.bbox.x0 = x0; - drag.bbox.y0 = y0; - drag.bbox.x1 = x1; - drag.bbox.y1 = y1; - - error = xwimp_drag_box(&drag); - if (error) { - LOG(("xwimp_drag_box: 0x%x : %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - /* we may not be the window the pointer is currently over */ - gui_track_gui_window = bw->window; - gui_current_drag_type = GUI_DRAG_FRAME; - return true; + if (!c) + return; + ro_gui_save_prepare(GUI_SAVE_LINK_URL, c); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, true); } @@ -3209,7 +3087,7 @@ bool gui_window_frame_resize_start(struct gui_window *g) void ro_gui_window_frame_resize_end(struct gui_window *g, wimp_dragged *drag) { - /* our clean-up is the same as for page scrolling */ + /* our clean-up is the same as for page scrolling */ ro_gui_window_scroll_end(g, drag); } |