From 4a5dc6d5ccafcf0cb2efc656011e1ce693c511cb Mon Sep 17 00:00:00 2001 From: Adrian Lees Date: Sat, 16 Jul 2005 05:54:45 +0000 Subject: [project @ 2005-07-16 05:54:45 by adrianl] Thumbnails displayed and dragged for full page save; spelling correction svn path=/import/netsurf/; revision=1793 --- !NetSurf/Resources/de/Templates,fec | Bin 12300 -> 12300 bytes !NetSurf/Resources/en/Templates,fec | Bin 12244 -> 12244 bytes !NetSurf/Resources/fr/Templates,fec | Bin 12592 -> 12592 bytes !NetSurf/Resources/nl/Templates,fec | Bin 12402 -> 12363 bytes riscos/401login.c | 2 +- riscos/bitmap.c | 4 +- riscos/dialog.c | 52 +++--- riscos/gui.c | 3 +- riscos/gui.h | 10 +- riscos/history.c | 2 +- riscos/menus.c | 18 +- riscos/plotters.c | 56 ++---- riscos/save.c | 343 +++++++++++++++++++++++++++--------- riscos/wimp.c | 27 +++ riscos/window.c | 9 +- 15 files changed, 360 insertions(+), 166 deletions(-) diff --git a/!NetSurf/Resources/de/Templates,fec b/!NetSurf/Resources/de/Templates,fec index 3325a4245..e1f0a304e 100755 Binary files a/!NetSurf/Resources/de/Templates,fec and b/!NetSurf/Resources/de/Templates,fec differ diff --git a/!NetSurf/Resources/en/Templates,fec b/!NetSurf/Resources/en/Templates,fec index 839affc53..455227462 100644 Binary files a/!NetSurf/Resources/en/Templates,fec and b/!NetSurf/Resources/en/Templates,fec differ diff --git a/!NetSurf/Resources/fr/Templates,fec b/!NetSurf/Resources/fr/Templates,fec index ef6f20713..1ba6c3f9e 100644 Binary files a/!NetSurf/Resources/fr/Templates,fec and b/!NetSurf/Resources/fr/Templates,fec differ diff --git a/!NetSurf/Resources/nl/Templates,fec b/!NetSurf/Resources/nl/Templates,fec index 88d561db4..c4f22fdb7 100644 Binary files a/!NetSurf/Resources/nl/Templates,fec and b/!NetSurf/Resources/nl/Templates,fec differ diff --git a/riscos/401login.c b/riscos/401login.c index 4f68d463d..185558875 100644 --- a/riscos/401login.c +++ b/riscos/401login.c @@ -94,7 +94,7 @@ void ro_gui_401login_open(wimp_w parent, char *host, char* realm, char *fetchurl /* create and open the window */ dialog_401li = wimp_create_window(dialog_401_template); - ro_gui_dialog_open_persistant(parent, dialog_401li, false); + ro_gui_dialog_open_persistent(parent, dialog_401li, false); } bool ro_gui_401login_keypress(wimp_key *key) diff --git a/riscos/bitmap.c b/riscos/bitmap.c index f24ea06f6..6652e4d68 100644 --- a/riscos/bitmap.c +++ b/riscos/bitmap.c @@ -119,7 +119,7 @@ void bitmap_initialise_memory(void) } if (option_image_memory_compressed == -1) { /* claim 5% of free memory - min 256KB, max 4192KB */ - compressed_size = available_memory * 0.05; + compressed_size = available_memory / 20; if (compressed_size < (256 << 10)) compressed_size = 0; if (compressed_size > (4192 << 10)) @@ -463,7 +463,7 @@ bool bitmap_save(struct bitmap *bitmap, const char *path) /** - * The bitmap image has changed, so flush any persistant cache. + * The bitmap image has changed, so flush any persistent cache. * * \param bitmap a bitmap, as returned by bitmap_create() */ diff --git a/riscos/dialog.c b/riscos/dialog.c index 3b287e324..4baea65d0 100644 --- a/riscos/dialog.c +++ b/riscos/dialog.c @@ -7,6 +7,7 @@ * Copyright 2003 John M Bell * Copyright 2005 Richard Wilson * Copyright 2004 Andrew Timmins + * Copyright 2005 Adrian Lees */ #include @@ -32,10 +33,9 @@ #include "netsurf/utils/url.h" #include "netsurf/utils/utils.h" -/* The maximum number of persistant dialogues +/* The maximum number of persistent dialogues */ -#define MAX_PERSISTANT 8 - +#define MAX_PERSISTENT 8 wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br, @@ -94,7 +94,7 @@ static const char *ro_gui_image_name[] = { static struct { wimp_w dialog; wimp_w parent; -} persistant_dialog[MAX_PERSISTANT]; +} persistent_dialog[MAX_PERSISTENT]; static void ro_gui_dialog_config_prepare(void); static void ro_gui_dialog_set_image_quality(int icon, unsigned int tinct_options); @@ -129,7 +129,7 @@ void ro_gui_dialog_init(void) /* fill in about box version info */ ro_gui_set_icon_string(dialog_info, 4, netsurf_version); - dialog_saveas = ro_gui_dialog_create("saveas"); + dialog_saveas = ro_gui_saveas_create("saveas"); dialog_config = ro_gui_dialog_create("config"); dialog_config_br = ro_gui_dialog_create("config_br"); dialog_config_prox = ro_gui_dialog_create("config_prox"); @@ -182,6 +182,8 @@ wimp_w ro_gui_dialog_create(const char *template_name) /* the window definition is copied by the wimp and may be freed */ free(window); +LOG(("gui_dialog_create given handle %p", w)); + return w; } @@ -289,7 +291,7 @@ void ro_gui_dialog_open(wimp_w w) /** - * Open a persistant dialog box relative to the pointer. + * Open a persistent dialog box relative to the pointer. * * \param parent the owning window (NULL for no owner) * \param w the dialog window @@ -297,7 +299,7 @@ void ro_gui_dialog_open(wimp_w w) * otherwise) */ -void ro_gui_dialog_open_persistant(wimp_w parent, wimp_w w, bool pointer) { +void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer) { int dx, dy, i; wimp_window_state open; os_error *error; @@ -356,18 +358,18 @@ void ro_gui_dialog_open_persistant(wimp_w parent, wimp_w w, bool pointer) { */ if (parent == NULL) return; - for (i = 0; i < MAX_PERSISTANT; i++) { - if (persistant_dialog[i].dialog == NULL || - persistant_dialog[i].dialog == w) { - persistant_dialog[i].dialog = w; - persistant_dialog[i].parent = parent; + for (i = 0; i < MAX_PERSISTENT; i++) { + if (persistent_dialog[i].dialog == NULL || + persistent_dialog[i].dialog == w) { + persistent_dialog[i].dialog = w; + persistent_dialog[i].parent = parent; return; } } /* Log that we failed to create a mapping */ - LOG(("Unable to map persistant dialog to parent.")); + LOG(("Unable to map persistent dialog to parent.")); } @@ -377,16 +379,16 @@ void ro_gui_dialog_open_persistant(wimp_w parent, wimp_w w, bool pointer) { * \param parent the window to close children of */ -void ro_gui_dialog_close_persistant(wimp_w parent) { +void ro_gui_dialog_close_persistent(wimp_w parent) { int i; /* Check our mappings */ - for (i = 0; i < MAX_PERSISTANT; i++) { - if (persistant_dialog[i].parent == parent && - persistant_dialog[i].dialog != NULL) { - ro_gui_dialog_close(persistant_dialog[i].dialog); - persistant_dialog[i].dialog = NULL; + for (i = 0; i < MAX_PERSISTENT; i++) { + if (persistent_dialog[i].parent == parent && + persistent_dialog[i].dialog != NULL) { + ro_gui_dialog_close(persistent_dialog[i].dialog); + persistent_dialog[i].dialog = NULL; } } } @@ -1380,7 +1382,7 @@ void ro_gui_dialog_close(wimp_w close) /* Give the caret back to the parent window. This code relies on the fact that only tree windows and browser windows open - persistant dialogues, as the caret gets placed to no icon. + persistent dialogues, as the caret gets placed to no icon. */ error = xwimp_get_caret_position(&caret); if (error) { @@ -1388,13 +1390,13 @@ void ro_gui_dialog_close(wimp_w close) error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } else if (caret.w == close) { - /* Check if we are a persistant window + /* Check if we are a persistent window */ - for (i = 0; i < MAX_PERSISTANT; i++) { - if (persistant_dialog[i].dialog == close) { - persistant_dialog[i].dialog = NULL; + for (i = 0; i < MAX_PERSISTENT; i++) { + if (persistent_dialog[i].dialog == close) { + persistent_dialog[i].dialog = NULL; error = xwimp_set_caret_position( - persistant_dialog[i].parent, + persistent_dialog[i].parent, wimp_ICON_WINDOW, -100, -100, 32, -1); if (error) { diff --git a/riscos/gui.c b/riscos/gui.c index aa9e11d4e..ab9f3a1b0 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -599,6 +599,7 @@ void gui_quit(void) ro_gui_global_history_save(); ro_gui_hotlist_save(); ro_gui_history_quit(); + ro_gui_saveas_quit(); rufl_quit(); free(gui_sprites); xwimp_close_down(task_handle); @@ -971,7 +972,7 @@ void ro_gui_close_window_request(wimp_close *close) /* Check for children */ - ro_gui_dialog_close_persistant(close->w); + ro_gui_dialog_close_persistent(close->w); if (close->w == dialog_debug) ro_gui_debugwin_close(); diff --git a/riscos/gui.h b/riscos/gui.h index cfa96c62f..2ab7f7084 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -104,8 +104,8 @@ void ro_gui_dialog_init(void); wimp_w ro_gui_dialog_create(const char *template_name); wimp_window * ro_gui_dialog_load_template(const char *template_name); void ro_gui_dialog_open(wimp_w w); -void ro_gui_dialog_open_persistant(wimp_w parent, wimp_w w, bool pointer); -void ro_gui_dialog_close_persistant(wimp_w parent); +void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer); +void ro_gui_dialog_close_persistent(wimp_w parent); void ro_gui_dialog_click(wimp_pointer *pointer); void ro_gui_dialog_prepare_zoom(struct gui_window *g); void ro_gui_dialog_prepare_open_url(void); @@ -138,6 +138,8 @@ void ro_gui_selection_drag_end(struct gui_window *g, wimp_dragged *drag); void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim); void ro_gui_selection_data_request(wimp_full_message_data_request *req); bool ro_gui_save_clipboard(const char *path); +void ro_gui_selection_dragging(wimp_full_message_dragging *drag); +void ro_gui_selection_drag_claim(wimp_full_message_drag_claim *drag); /* in 401login.c */ #ifdef WITH_AUTH @@ -199,11 +201,13 @@ void ro_gui_hotlist_dialog_click(wimp_pointer *pointer); int ro_gui_hotlist_help(int x, int y); /* in save.c */ +wimp_w ro_gui_saveas_create(const char *template_name); +void ro_gui_saveas_quit(void); void ro_gui_save_prepare(gui_save_type save_type, struct content *c); void ro_gui_save_click(wimp_pointer *pointer); void ro_gui_drag_icon(int x, int y, const char *sprite); void ro_gui_save_drag_end(wimp_dragged *drag); -void ro_gui_send_datasave(gui_save_type save_type, const wimp_full_message_data_xfer *message, wimp_t to); +void ro_gui_send_datasave(gui_save_type save_type, wimp_full_message_data_xfer *message, wimp_t to); void ro_gui_save_datasave_ack(wimp_message *message); void ro_gui_save_ok(wimp_w w); void ro_gui_convert_save_path(char *dp, size_t len, const char *p); diff --git a/riscos/history.c b/riscos/history.c index 4389a41f8..4a2ac9456 100644 --- a/riscos/history.c +++ b/riscos/history.c @@ -351,7 +351,7 @@ void ro_gui_history_open(struct browser_window *bw, state.visible.y1 = height; state.next = wimp_HIDDEN; wimp_open_window((wimp_open *) &state); - ro_gui_dialog_open_persistant(bw->window->window, history_window, pointer); + ro_gui_dialog_open_persistent(bw->window->window, history_window, pointer); } diff --git a/riscos/menus.c b/riscos/menus.c index 1cb4cae05..86272a112 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -1346,14 +1346,14 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, if (!c) return false; ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant(g->window, dialog_pageinfo, + ro_gui_dialog_open_persistent(g->window, dialog_pageinfo, windows_at_pointer); return true; case BROWSER_PRINT: if (!c) return false; ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant(g->window, dialog_print, + ro_gui_dialog_open_persistent(g->window, dialog_print, windows_at_pointer); return true; case BROWSER_NEW_WINDOW: @@ -1372,7 +1372,7 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, if (!current_menu_object_box) return false; ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant(g->window, dialog_objinfo, + ro_gui_dialog_open_persistent(g->window, dialog_objinfo, windows_at_pointer); return true; case BROWSER_OBJECT_RELOAD: @@ -1402,7 +1402,7 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, case HOTLIST_EXPORT: case HISTORY_EXPORT: ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant(owner, dialog_saveas, + ro_gui_dialog_open_persistent(owner, dialog_saveas, windows_at_pointer); return true; @@ -1443,7 +1443,7 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, return true; case BROWSER_NAVIGATE_URL: ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant(NULL, dialog_openurl, + ro_gui_dialog_open_persistent(NULL, dialog_openurl, windows_at_pointer); return true; @@ -1452,14 +1452,14 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, if (!c) return false; ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant(g->window, dialog_zoom, + ro_gui_dialog_open_persistent(g->window, dialog_zoom, windows_at_pointer); return true; case BROWSER_FIND_TEXT: if (!c || c->type != CONTENT_HTML) return false; ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant(g->window, dialog_search, + ro_gui_dialog_open_persistent(g->window, dialog_search, windows_at_pointer); return true; case BROWSER_IMAGES_BACKGROUND: @@ -1518,12 +1518,12 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, /* tree actions */ case TREE_NEW_FOLDER: ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant((wimp_w)tree->handle, + ro_gui_dialog_open_persistent((wimp_w)tree->handle, dialog_folder, windows_at_pointer); return true; case TREE_NEW_LINK: ro_gui_menu_prepare_action(owner, action, true); - ro_gui_dialog_open_persistant((wimp_w)tree->handle, + ro_gui_dialog_open_persistent((wimp_w)tree->handle, dialog_entry, windows_at_pointer); return true; case TREE_EXPAND_ALL: diff --git a/riscos/plotters.c b/riscos/plotters.c index 8b3a5a80b..b1148b85a 100644 --- a/riscos/plotters.c +++ b/riscos/plotters.c @@ -233,6 +233,7 @@ bool ro_plot_clip(int clip_x0, int clip_y0, int clip_x1, int clip_y1) { os_error *error; + char buf[12]; clip_x0 = ro_plot_origin_x + clip_x0 * 2; clip_y0 = ro_plot_origin_y - clip_y0 * 2 - 1; @@ -245,50 +246,19 @@ bool ro_plot_clip(int clip_x0, int clip_y0, return false; } - error = xos_set_graphics_window(); + buf[0] = os_VDU_SET_GRAPHICS_WINDOW; + buf[1] = clip_x0; + buf[2] = clip_x0 >> 8; + buf[3] = clip_y1; + buf[4] = clip_y1 >> 8; + buf[5] = clip_x1; + buf[6] = clip_x1 >> 8; + buf[7] = clip_y0; + buf[8] = clip_y0 >> 8; + + error = xos_writen(buf, 9); if (error) { - LOG(("xos_set_graphics_window: 0x%x: %s", error->errnum, - error->errmess)); - return false; - } - error = xos_writec((char) (clip_x0 & 0xff)); - if (error) { - LOG(("xos_writec: 0x%x: %s", error->errnum, error->errmess)); - return false; - } - error = xos_writec((char) (clip_x0 >> 8)); - if (error) { - LOG(("xos_writec: 0x%x: %s", error->errnum, error->errmess)); - return false; - } - error = xos_writec((char) (clip_y1 & 0xff)); - if (error) { - LOG(("xos_writec: 0x%x: %s", error->errnum, error->errmess)); - return false; - } - error = xos_writec((char) (clip_y1 >> 8)); - if (error) { - LOG(("xos_writec: 0x%x: %s", error->errnum, error->errmess)); - return false; - } - error = xos_writec((char) (clip_x1 & 0xff)); - if (error) { - LOG(("xos_writec: 0x%x: %s", error->errnum, error->errmess)); - return false; - } - error = xos_writec((char) (clip_x1 >> 8)); - if (error) { - LOG(("xos_writec: 0x%x: %s", error->errnum, error->errmess)); - return false; - } - error = xos_writec((char) (clip_y0 & 0xff)); - if (error) { - LOG(("xos_writec: 0x%x: %s", error->errnum, error->errmess)); - return false; - } - error = xos_writec((char) (clip_y0 >> 8)); - if (error) { - LOG(("xos_writec: 0x%x: %s", error->errnum, error->errmess)); + LOG(("xos_writen: 0x%x: %s", error->errnum, error->errmess)); return false; } diff --git a/riscos/save.c b/riscos/save.c index 522759061..956bb8c6a 100644 --- a/riscos/save.c +++ b/riscos/save.c @@ -20,8 +20,10 @@ #include "oslib/dragasprite.h" #include "oslib/osbyte.h" #include "oslib/osfile.h" +#include "oslib/osmodule.h" #include "oslib/osspriteop.h" #include "oslib/wimp.h" +#include "oslib/wimpspriteop.h" #include "netsurf/desktop/save_text.h" #include "netsurf/desktop/selection.h" #include "netsurf/image/bitmap.h" @@ -45,7 +47,9 @@ static int gui_save_filetype; static bool using_dragasprite = true; static bool saving_from_dialog = true; +static osspriteop_area *saveas_area = NULL; static wimp_w gui_save_sourcew = (wimp_w)-1; +static char save_leafname[32]; typedef enum { LINK_ACORN, LINK_ANT, LINK_TEXT } link_format; @@ -53,6 +57,8 @@ static bool ro_gui_save_complete(struct content *c, char *path); static bool ro_gui_save_content(struct content *c, char *path); static void ro_gui_save_object_native(struct content *c, char *path); static bool ro_gui_save_link(struct content *c, link_format format, char *path); +static void ro_gui_save_set_state(struct content *c, gui_save_type save_type, char *leaf_buf, char *icon_buf); +static bool ro_gui_save_create_thumbnail(struct content *c, const char *name); /** An entry in gui_save_table. */ @@ -80,6 +86,87 @@ struct gui_save_table_entry gui_save_table[] = { }; +/** + * Create the saveas dialogue from the given template, and the sprite area + * necessary for our thumbnail (full page save) + * + * \param template_name name of template to be used + * \return window handle of created dialogue + */ + +wimp_w ro_gui_saveas_create(const char *template_name) +{ + const int sprite_size = (68 * 68 * 4) + ((68 * 68) / 8); /* 32bpp with mask */ + int area_size = sizeof(osspriteop_area) + sizeof(osspriteop_header) + + 256 * 8 + sprite_size; + wimp_window *window; + os_error *error; + wimp_icon *icons; + wimp_w w; + + window = ro_gui_dialog_load_template(template_name); + assert(window); + + icons = window->icons; + + error = xosmodule_alloc(area_size, (void**)&saveas_area); + if (error) { + LOG(("xosmodule_alloc: 0x%x: %s", error->errnum, error->errmess)); + xwimp_close_template(); + die(error->errmess); + } + else { + saveas_area->size = area_size; + saveas_area->first = 16; + + error = xosspriteop_clear_sprites(osspriteop_USER_AREA, saveas_area); + if (error) { + LOG(("xosspriteop_clear_sprites: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MiscError", error->errmess); + + xosmodule_free(saveas_area); + saveas_area = NULL; + } + } + + assert((icons[ICON_SAVE_ICON].flags & + (wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_INDIRECTED)) == + (wimp_ICON_SPRITE | wimp_ICON_INDIRECTED)); + icons[ICON_SAVE_ICON].data.indirected_sprite.area = saveas_area; + + /* create window */ + error = xwimp_create_window(window, &w); + if (error) { + LOG(("xwimp_create_window: 0x%x: %s", + error->errnum, error->errmess)); + xwimp_close_template(); + die(error->errmess); + } + + /* the window definition is copied by the wimp and may be freed */ + free(window); + + return w; +} + + +/** + * Clean-up function that releases our sprite area. + */ + +void ro_gui_saveas_quit(void) +{ + if (saveas_area) { + os_error *error = xosmodule_free(saveas_area); + if (error) { + LOG(("xosmodule_free: 0x%x: %s", error->errnum, error->errmess)); + warn_user("MiscError", error->errmess); + } + saveas_area = NULL; + } +} + /** * Prepares the save box to reflect gui_save_type and a content, and * opens it. @@ -94,35 +181,20 @@ struct gui_save_table_entry gui_save_table[] = { void ro_gui_save_prepare(gui_save_type save_type, struct content *c) { + char name_buf[64]; char icon_buf[20]; - const char *icon = icon_buf; - const char *name = ""; - const char *nice; - url_func_result res; assert((save_type == GUI_SAVE_HOTLIST_EXPORT_HTML) || (save_type == GUI_SAVE_HISTORY_EXPORT_HTML) || c); gui_save_current_type = save_type; gui_save_content = c; - gui_save_filetype = gui_save_table[save_type].filetype; - if (!gui_save_filetype) - gui_save_filetype = ro_content_filetype(c); - /* icon */ - sprintf(icon_buf, "file_%.3x", gui_save_filetype); - if (!ro_gui_wimp_sprite_exists(icon_buf)) - icon = "file_xxx"; - ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_ICON, icon); + ro_gui_save_set_state(c, save_type, name_buf, icon_buf); - /* filename */ - name = gui_save_table[save_type].name; - if (c && (res = url_nice(c->url, (char **)&nice)) == URL_FUNC_OK) - name = nice; - else - name = messages_get(name); + ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_ICON, icon_buf); - ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_PATH, name); + ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_PATH, name_buf); } /** @@ -198,7 +270,6 @@ void gui_drag_save_object(gui_save_type save_type, struct content *c, { wimp_pointer pointer; char icon_buf[20]; - const char *icon = icon_buf; os_error *error; /* Close the save window because otherwise we need two contexts @@ -217,20 +288,11 @@ void gui_drag_save_object(gui_save_type save_type, struct content *c, return; } - gui_save_current_type = save_type; - gui_save_content = c; - gui_save_filetype = gui_save_table[save_type].filetype; - if (!gui_save_filetype) - gui_save_filetype = ro_content_filetype(c); - - /* sprite to use */ - sprintf(icon_buf, "file_%.3x", gui_save_filetype); - if (!ro_gui_wimp_sprite_exists(icon_buf)) - icon = "file_xxx"; + ro_gui_save_set_state(c, save_type, save_leafname, icon_buf); gui_current_drag_type = GUI_DRAG_SAVE; - ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon); + ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon_buf); } @@ -245,7 +307,6 @@ void gui_drag_save_selection(struct selection *s, struct gui_window *g) { wimp_pointer pointer; char icon_buf[20]; - const char *icon = icon_buf; os_error *error; /* Close the save window because otherwise we need two contexts @@ -264,19 +325,13 @@ void gui_drag_save_selection(struct selection *s, struct gui_window *g) return; } - gui_save_current_type = GUI_SAVE_TEXT_SELECTION; - gui_save_content = NULL; gui_save_selection = s; - gui_save_filetype = gui_save_table[GUI_SAVE_TEXT_SELECTION].filetype; - /* sprite to use */ - sprintf(icon_buf, "file_%.3x", gui_save_filetype); - if (!ro_gui_wimp_sprite_exists(icon_buf)) - icon = "file_xxx"; + ro_gui_save_set_state(NULL, GUI_SAVE_TEXT_SELECTION, save_leafname, icon_buf); gui_current_drag_type = GUI_DRAG_SAVE; - ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon); + ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon_buf); } @@ -296,11 +351,28 @@ void ro_gui_drag_icon(int x, int y, const char *sprite) drag.initial.y1 = y + 34; if (sprite && (xosbyte2(osbyte_READ_CMOS, 28, 0, &r2) || (r2 & 2))) { + osspriteop_area *area = (osspriteop_area*)1; + + /* first try our local sprite area in case it's a thumbnail sprite */ + if (saveas_area) { + error = xosspriteop_select_sprite(osspriteop_USER_AREA, + saveas_area, (osspriteop_id)sprite, NULL); + if (error) { + if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) { + LOG(("xosspriteop_select_sprite: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MiscError", error->errmess); + } + } + else + area = saveas_area; + } + error = xdragasprite_start(dragasprite_HPOS_CENTRE | dragasprite_VPOS_CENTRE | dragasprite_BOUND_POINTER | dragasprite_DROP_SHADOW, - (osspriteop_area *) 1, sprite, &drag.initial, 0); + area, sprite, &drag.initial, 0); if (!error) { using_dragasprite = true; @@ -364,6 +436,23 @@ void ro_gui_save_drag_end(wimp_dragged *drag) os_error *error; char *dp, *ep; + if (using_dragasprite) { + error = xdragasprite_stop(); + if (error) { + LOG(("xdragasprite_stop: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + } + else { + error = xwimp_drag_box(NULL); + if (error) { + LOG(("xwimp_drag_box: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + } + error = xwimp_get_pointer_info(&pointer); if (error) { LOG(("xwimp_get_pointer_info: 0x%x: %s", @@ -378,15 +467,7 @@ void ro_gui_save_drag_end(wimp_dragged *drag) if (!saving_from_dialog) { /* saving directly from browser window, choose a name based upon the URL */ - struct content *c = gui_save_content; - const char *nice; - - name = gui_save_table[gui_save_current_type].name; - if (c) { - url_func_result res; - if ((res = url_nice(c->url, (char **)&nice)) == URL_FUNC_OK) - name = nice; - } + name = save_leafname; } else { char *dot; @@ -430,7 +511,7 @@ void ro_gui_save_drag_end(wimp_dragged *drag) * clipboard contents we're being asked for when the DataSaveAck reply arrives */ -void ro_gui_send_datasave(gui_save_type save_type, const wimp_full_message_data_xfer *message, wimp_t to) +void ro_gui_send_datasave(gui_save_type save_type, wimp_full_message_data_xfer *message, wimp_t to) { os_error *error; @@ -626,11 +707,6 @@ bool ro_gui_save_complete(struct content *c, char *path) char buf[256]; FILE *fp; os_error *error; - osspriteop_area *area; - osspriteop_header *sprite_header; - char *appname; - unsigned int index; - struct bitmap *bitmap; /* Create dir */ error = xosfile_create_dir(path, 0); @@ -661,31 +737,8 @@ bool ro_gui_save_complete(struct content *c, char *path) /* Create !Sprites */ snprintf(buf, sizeof buf, "%s.!Sprites", path); - appname = strrchr(path, '.'); - if (!appname) - appname = path; - bitmap = bitmap_create(34, 34, false); - if (!bitmap) { - LOG(("Thumbnail initialisation failed.")); - return false; - } - bitmap_set_opaque(bitmap, true); - thumbnail_create(c, bitmap, NULL); - area = thumbnail_convert_8bpp(bitmap); - bitmap_destroy(bitmap); - if (!area) { - LOG(("Thumbnail conversion failed.")); - return false; - } - sprite_header = (osspriteop_header *)(area + 1); - memset(sprite_header->name, 0x00, 12); - strncpy(sprite_header->name, appname + 1, 12); - /* Paint gets confused with uppercase characters */ - for (index = 0; index < 12; index++) - sprite_header->name[index] = tolower(sprite_header->name[index]); - error = xosspriteop_save_sprite_file(osspriteop_NAME, area, buf); - free(area); + error = xosspriteop_save_sprite_file(osspriteop_NAME, saveas_area, buf); if (error) { LOG(("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess)); @@ -779,3 +832,133 @@ bool ro_gui_save_link(struct content *c, link_format format, char *path) return true; } + + +/** + * Suggest a leafname and sprite name for the given content. + * + * \param c content being saved + * \param save_type type of save operation being performed + * \param leaf_buf buffer to receive suggested leafname + * \param icon_buf buffer to receive sprite name + */ + +void ro_gui_save_set_state(struct content *c, gui_save_type save_type, char *leaf_buf, char *icon_buf) +{ + /* filename */ + const char *name = gui_save_table[save_type].name; + url_func_result res; + bool done = false; + char *nice = NULL; + + /* parameters that we need to remember */ + gui_save_current_type = save_type; + gui_save_content = c; + + /* suggest a filetype based upon the content */ + gui_save_filetype = gui_save_table[save_type].filetype; + if (!gui_save_filetype) + gui_save_filetype = ro_content_filetype(c); + + /* leafname */ + if (c && (res = url_nice(c->url, (char **)&nice)) == URL_FUNC_OK) + name = nice; + else + name = messages_get(name); + strcpy(leaf_buf, name); + + /* sprite name used for icon and dragging */ + if (save_type == GUI_SAVE_COMPLETE) { + int index; + + /* Paint gets confused with uppercase characters and we need to + convert spaces to hard spaces */ + icon_buf[0] = '!'; + for (index = 0; index < 11 && name[index]; ) { + char ch = name[index]; + if (ch == ' ') + icon_buf[++index] = 0xa0; + else + icon_buf[++index] = tolower(ch); + } + memset(&icon_buf[index + 1], 0, 11 - index); + icon_buf[12] = '\0'; + + if (ro_gui_save_create_thumbnail(c, icon_buf)) + done = true; + } + + if (!done) { + osspriteop_header *sprite; + os_error *error; + + sprintf(icon_buf, "file_%.3x", gui_save_filetype); + + error = ro_gui_wimp_get_sprite(icon_buf, &sprite); + if (error) { + LOG(("ro_gui_wimp_get_sprite: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MiscError", error->errmess); + } else { + /* the sprite area should always be large enough for file_xxx sprites */ + assert(sprite->size <= saveas_area->size - saveas_area->first); + + memcpy((byte*)saveas_area + saveas_area->first, + sprite, + sprite->size); + + saveas_area->sprite_count = 1; + saveas_area->used = saveas_area->first + sprite->size; + } + } + + free(nice); +} + + + +/** + * Create a thumbnail sprite for the page being saved. + * + * \param c content to be converted + * \param name sprite name to use + * \return true iff successful + */ + +bool ro_gui_save_create_thumbnail(struct content *c, const char *name) +{ + osspriteop_header *sprite_header; + struct bitmap *bitmap; + osspriteop_area *area; + + bitmap = bitmap_create(34, 34, false); + if (!bitmap) { + LOG(("Thumbnail initialisation failed.")); + return false; + } + bitmap_set_opaque(bitmap, true); + thumbnail_create(c, bitmap, NULL); + area = thumbnail_convert_8bpp(bitmap); + bitmap_destroy(bitmap); + if (!area) { + LOG(("Thumbnail conversion failed.")); + return false; + } + + sprite_header = (osspriteop_header *)(area + 1); + memcpy(sprite_header->name, name, 12); + + /* we can't resize the saveas sprite area because it may move and we have + no elegant way to update the window definition on all OS versions */ + assert(sprite_header->size <= saveas_area->size - saveas_area->first); + + memcpy((byte*)saveas_area + saveas_area->first, + sprite_header, sprite_header->size); + + saveas_area->sprite_count = 1; + saveas_area->used = saveas_area->first + sprite_header->size; + + free(area); + + return true; +} diff --git a/riscos/wimp.c b/riscos/wimp.c index 9500c6abb..ec12545df 100644 --- a/riscos/wimp.c +++ b/riscos/wimp.c @@ -615,6 +615,33 @@ bool ro_gui_wimp_sprite_exists(const char *sprite) } +/** + * Locate a sprite in the Wimp sprite pool, returning a pointer to it. + * + * \param name sprite name + * \param sprite receives pointer to sprite if found + * \return error ptr iff not found + */ + +os_error *ro_gui_wimp_get_sprite(const char *name, osspriteop_header **sprite) +{ + osspriteop_area *rom_base, *ram_base; + os_error *error; + + error = xwimp_base_of_sprites(&rom_base, &ram_base); + if (error) return error; + + error = xosspriteop_select_sprite(osspriteop_USER_AREA, + rom_base, (osspriteop_id)name, sprite); + + if (error && error->errnum == error_SPRITE_OP_DOESNT_EXIST) + error = xosspriteop_select_sprite(osspriteop_USER_AREA, + ram_base, (osspriteop_id)name, sprite); + + return error; +} + + /** * Open a window as a pane in another window. * diff --git a/riscos/window.c b/riscos/window.c index 3d65abfdc..8abc6c9ed 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -2461,7 +2461,7 @@ void gui_window_new_content(struct gui_window *g) { ro_gui_menu_objects_moved(); ro_gui_prepare_navigate(g); - ro_gui_dialog_close_persistant(g->window); + ro_gui_dialog_close_persistent(g->window); } @@ -2635,6 +2635,13 @@ void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag) return; } + error = xwimpspriteop_set_pointer_shape(NULL, 0x31, 0, 0, 0, 0); + if (error) { + LOG(("xwimpspriteop_set_pointer_shape: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + state.w = g->window; error = xwimp_get_window_state(&state); if (error) { -- cgit v1.2.3