diff --git a/desktop/browser.c b/desktop/browser.c index ea3f9814f..9a983d644 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -785,6 +785,8 @@ void browser_window_mouse_click(struct browser_window *bw, if (!c) return; + browser_window_remove_caret(bw); + switch (c->type) { case CONTENT_HTML: browser_window_mouse_action_html(bw, mouse, x, y); @@ -1905,7 +1907,7 @@ void browser_form_submit(struct browser_window *bw, struct form *form, warn_user("NoMemory", 0); return; } - + if (new_window) { target = browser_window_create(NULL, bw, NULL, false); /* any error has already been reported */ diff --git a/riscos/gui.c b/riscos/gui.c index a2206d759..808682f9e 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -865,7 +865,7 @@ void gui_poll(bool active) ro_gui_handle_event(event, &block); schedule_run(); ro_gui_window_update_boxes(); - + if (gui_reformat_pending && event == wimp_NULL_REASON_CODE) ro_gui_window_process_reformats(); else if (bitmap_maintenance_priority || @@ -1180,14 +1180,11 @@ void ro_gui_pointer_entering_window(wimp_entering *entering) void ro_gui_mouse_click(wimp_pointer *pointer) { - struct gui_window *g; struct gui_download_window *dw; struct gui_query_window *qw; if (ro_gui_wimp_event_mouse_click(pointer)) return; - else if ((g = ro_gui_window_lookup(pointer->w)) != NULL) - ro_gui_window_click(g, pointer); else if ((dw = ro_gui_download_window_lookup(pointer->w)) != NULL) ro_gui_download_window_click(dw, pointer); else if ((qw = ro_gui_query_window_lookup(pointer->w)) != NULL) @@ -1284,15 +1281,10 @@ void ro_gui_keypress(wimp_key *key) struct gui_download_window *dw; struct gui_query_window *qw; bool handled = false; - struct gui_window *g; os_error *error; if (ro_gui_wimp_event_keypress(key)) handled = true; - else if ((g = ro_gui_window_lookup(key->w)) != NULL) - handled = ro_gui_window_keypress(g, key->c, false); - else if ((g = ro_gui_toolbar_lookup(key->w)) != NULL) - handled = ro_gui_window_keypress(g, key->c, true); else if ((qw = ro_gui_query_window_lookup(key->w)) != NULL) handled = ro_gui_query_window_keypress(qw, key); else if ((dw = ro_gui_download_window_lookup(key->w)) != NULL) @@ -1996,7 +1988,7 @@ void ro_msg_window_info(wimp_message *message) /* allow the user to turn off thumbnail icons */ if (!option_thumbnail_iconise) return; - + wi = (wimp_full_message_window_info*)message; g = ro_gui_window_lookup(wi->w); diff --git a/riscos/gui.h b/riscos/gui.h index 743e701ea..17fb86903 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -133,7 +133,6 @@ void ro_gui_cert_init(void); /* in window.c */ void ro_gui_window_quit(void); -void ro_gui_window_click(struct gui_window *g, wimp_pointer *mouse); void ro_gui_window_update_theme(void); void ro_gui_window_update_dimensions(struct gui_window *g, int yscroll); void ro_gui_window_open(struct gui_window *g, wimp_open *open); @@ -145,7 +144,6 @@ void ro_gui_throb(void); 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); -bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar); 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); diff --git a/riscos/search.c b/riscos/search.c index 08497c9b1..8d11ed081 100644 --- a/riscos/search.c +++ b/riscos/search.c @@ -3,7 +3,7 @@ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license * Copyright 2004 John M Bell - * Copyright 2005 Adrian Lees + * Copyright 2005 Adrian Lees */ /** \file @@ -152,7 +152,7 @@ void ro_gui_search_add_recent(char *search) { if ((recent_search[0] != NULL) && (!strcmp(recent_search[0], search))) - return; + return; tmp = strdup(search); if (!tmp) { @@ -164,7 +164,7 @@ void ro_gui_search_add_recent(char *search) { recent_search[i] = recent_search[i - 1]; recent_search[0] = tmp; search_insert = false; - + ro_gui_set_icon_shaded_state(dialog_search, ICON_SEARCH_MENU, false); ro_gui_search_prepare_menu(); } @@ -173,7 +173,7 @@ bool ro_gui_search_prepare_menu(void) { os_error *error; int i; int suggestions = 0; - + for (i = 0; i < RECENT_SEARCHES; i++) if (recent_search[i] != NULL) suggestions++; @@ -260,11 +260,11 @@ bool ro_gui_search_keypress(wimp_key *key) ro_gui_set_icon_selected_state(dialog_search, ICON_SEARCH_CASE_SENSITIVE, !state); start_search(true); return true; - case wimp_KEY_UP: + case IS_WIMP_KEY | wimp_KEY_UP: search_insert = true; start_search(false); return true; - case wimp_KEY_DOWN: + case IS_WIMP_KEY | wimp_KEY_DOWN: search_insert = true; start_search(true); return true; @@ -533,7 +533,7 @@ const char *find_pattern(const char *string, int s_len, const char *pattern, /* anything matches a # so continue matching from here, and stack a context that will try to match the wildcard against the next character */ - + ch = *p; if (ch != '#') { /* scan forwards until we find a match for this char */ @@ -592,7 +592,7 @@ const char *find_pattern(const char *string, int s_len, const char *pattern, else { /* doesn't match, resume with stacked context if we have one */ if (--top < 0) return NULL; /* no match, give up */ - + ss = context[top].ss; s = context[top].s; p = context[top].p; @@ -689,7 +689,7 @@ bool find_occurrences_text(const char *pattern, int p_len, const char *pos = find_pattern(text, length, pattern, p_len, case_sens, &match_length); if (!pos) break; - + /* found string in line => add to list */ start_idx = offset + (pos - text); entry = add_entry(start_idx, start_idx + match_length); diff --git a/riscos/textarea.c b/riscos/textarea.c index 2a8d84efa..adfcd843a 100644 --- a/riscos/textarea.c +++ b/riscos/textarea.c @@ -130,7 +130,7 @@ uintptr_t textarea_create(wimp_w parent, wimp_i icon, unsigned int flags, LOG(("malloc failed")); return 0; } - + ret->parent = parent; ret->icon = icon; ret->magic = MAGIC; @@ -210,9 +210,9 @@ uintptr_t textarea_create(wimp_w parent, wimp_i icon, unsigned int flags, if (flags & TEXTAREA_READONLY) { state.visible.x0 += 2; - state.visible.x1 -= 4; + state.visible.x1 -= 4; state.visible.y0 += 4; - state.visible.y1 -= 2; + state.visible.y1 -= 2; } /* set our width/height */ @@ -918,7 +918,7 @@ void textarea_reflow(struct text_area *ta, unsigned int line) bool textarea_mouse_click(wimp_pointer *pointer) { struct text_area *ta; - + ta = textarea_from_w(pointer->w); if (!ta) return false; @@ -935,16 +935,13 @@ bool textarea_mouse_click(wimp_pointer *pointer) */ bool textarea_key_press(wimp_key *key) { - static int *ucstable = NULL; - static int alphabet = 0; - static wchar_t wc = 0; /* buffer for UTF8 alphabet */ - static int shift = 0; + wchar_t c = (wchar_t)key->c; wimp_key keypress; struct text_area *ta; - wchar_t c = (wchar_t)key->c; - int t_alphabet; char utf8[7]; size_t utf8_len; + bool redraw = false; + unsigned int c_pos; os_error *error; ta = textarea_from_w(key->w); @@ -954,139 +951,33 @@ bool textarea_key_press(wimp_key *key) if (ta->flags & TEXTAREA_READONLY) return true; - /* In order to make sensible use of the 0x80->0xFF ranges specified - * in the RISC OS 8bit alphabets, we must do the following: - * - * + Read the currently selected alphabet - * + Acquire a pointer to the UCS conversion table for this alphabet: - * + Try using ServiceInternational 8 to get the table - * + If that fails, use our internal table (see ucstables.c) - * + If the alphabet is not UTF8 and the conversion table exists: - * + Lookup UCS code in the conversion table - * + If code is -1 (i.e. undefined): - * + Use codepoint 0xFFFD instead - * + If the alphabet is UTF8, we must buffer input, thus: - * + If the keycode is < 0x80: - * + Handle it directly - * + If the keycode is a UTF8 sequence start: - * + Initialise the buffer appropriately - * + Otherwise: - * + OR in relevant bits from keycode to buffer - * + If we've received an entire UTF8 character: - * + Handle UCS code - * + Otherwise: - * + Simply handle the keycode directly, as there's no easy way - * of performing the mapping from keycode -> UCS4 codepoint. - */ - error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &t_alphabet); - if (error) { - LOG(("failed reading alphabet: 0x%x: %s", - error->errnum, error->errmess)); - /* prevent any corruption of ucstable */ - t_alphabet = alphabet; - } + if (!(c & IS_WIMP_KEY || + (c <= 0x001f || (0x007f <= c && c <= 0x009f)))) { + /* normal character - insert */ + utf8_len = utf8_from_ucs4(c, utf8); + utf8[utf8_len] = '\0'; - if (t_alphabet != alphabet) { - osbool unclaimed; - /* Alphabet has changed, so read UCS table location */ - alphabet = t_alphabet; - - error = xserviceinternational_get_ucs_conversion_table( - alphabet, &unclaimed, - (void**)&ucstable); - if (error) { - LOG(("failed reading UCS conversion table: 0x%x: %s", - error->errnum, error->errmess)); - /* try using our own table instead */ - ucstable = ucstable_from_alphabet(alphabet); - } - if (unclaimed) - /* Service wasn't claimed so use our own ucstable */ - ucstable = ucstable_from_alphabet(alphabet); - } - - if (c < 256) { - if (alphabet != 111 /* UTF8 */ && ucstable != NULL) { - /* defined in this alphabet? */ - if (ucstable[c] == -1) - return true; - - /* read UCS4 value out of table */ - c = ucstable[c]; - } - else if (alphabet == 111 /* UTF8 */) { - if ((c & 0x80) == 0x00 || (c & 0xC0) == 0xC0) { - /* UTF8 start sequence */ - if ((c & 0xE0) == 0xC0) { - wc = ((c & 0x1F) << 6); - shift = 1; - return true; - } - else if ((c & 0xF0) == 0xE0) { - wc = ((c & 0x0F) << 12); - shift = 2; - return true; - } - else if ((c & 0xF8) == 0xF0) { - wc = ((c & 0x07) << 18); - shift = 3; - return true; - } - /* These next two have been removed - * from RFC3629, but there's no - * guarantee that RISC OS won't - * generate a UCS4 value outside the - * UTF16 plane, so we handle them - * anyway. */ - else if ((c & 0xFC) == 0xF8) { - wc = ((c & 0x03) << 24); - shift = 4; - } - else if ((c & 0xFE) == 0xFC) { - wc = ((c & 0x01) << 30); - shift = 5; - } - else if (c >= 0x80) { - /* If this ever happens, - * RISC OS' UTF8 keyboard - * drivers are broken */ - LOG(("unexpected UTF8 start" - " byte %x (ignoring)", - c)); - return true; - } - /* Anything else is ASCII, so just - * handle it directly. */ - } - else { - if ((c & 0xC0) != 0x80) { - /* If this ever happens, - * RISC OS' UTF8 keyboard - * drivers are broken */ - LOG(("unexpected keycode: " - "%x (ignoring)", c)); - return true; - } - - /* Continuation of UTF8 character */ - wc |= ((c & 0x3F) << (6 * --shift)); - if (shift > 0) - /* partial character */ - return true; - else - /* got entire character, so - * fetch from buffer and - * handle it */ - c = wc; - } - } + c_pos = textarea_get_caret((uintptr_t)ta); + textarea_insert_text((uintptr_t)ta, c_pos, utf8); + textarea_set_caret((uintptr_t)ta, ++c_pos); + redraw = true; + } else { /** \todo handle command keys */ - switch (c) { + switch (c & ~IS_WIMP_KEY) { /** pass on RETURN and ESCAPE to the parent icon */ case wimp_KEY_RETURN: - if (ta->flags & TEXTAREA_MULTILINE) + if (ta->flags & TEXTAREA_MULTILINE) { + /* Insert newline */ + c_pos = textarea_get_caret( + (uintptr_t)ta); + textarea_insert_text( + (uintptr_t)ta, c_pos, + "\n"); + textarea_set_caret((uintptr_t)ta, + ++c_pos); break; + } /* fall through */ case wimp_KEY_ESCAPE: keypress = *key; @@ -1100,27 +991,21 @@ bool textarea_key_press(wimp_key *key) LOG(("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess)); } - return true; - } - - utf8_len = utf8_from_ucs4(c, utf8); - utf8[utf8_len] = '\0'; - - { - wimp_draw update; - unsigned int c_pos = - textarea_get_caret((uintptr_t)ta); - textarea_insert_text((uintptr_t)ta, c_pos, utf8); - textarea_set_caret((uintptr_t)ta, ++c_pos); - - update.w = ta->window; - update.box.x0 = 0; - update.box.y1 = 0; - update.box.x1 = ta->vis_width; - update.box.y0 = -ta->line_height * (ta->line_count + 1); - textarea_redraw_internal(&update, true); + break; } } + + if (redraw) { + wimp_draw update; + + update.w = ta->window; + update.box.x0 = 0; + update.box.y1 = 0; + update.box.x1 = ta->vis_width; + update.box.y0 = -ta->line_height * (ta->line_count + 1); + textarea_redraw_internal(&update, true); + } + return true; } diff --git a/riscos/wimp_event.c b/riscos/wimp_event.c index 3e4204289..977134922 100644 --- a/riscos/wimp_event.c +++ b/riscos/wimp_event.c @@ -15,9 +15,12 @@ #include #include #include "oslib/os.h" +#include "oslib/osbyte.h" +#include "oslib/serviceinternational.h" #include "oslib/wimp.h" #include "netsurf/riscos/dialog.h" #include "netsurf/riscos/menus.h" +#include "netsurf/riscos/ucstables.h" #include "netsurf/riscos/wimp.h" #include "netsurf/riscos/wimp_event.h" #include "netsurf/utils/log.h" @@ -629,17 +632,159 @@ void ro_gui_wimp_event_ok_click(struct event_window *window, wimp_mouse_state st * Handle any registered keypresses, and the standard RISC OS ones * * \param key the key state + * \return true if keypress handled, false otherwise */ bool ro_gui_wimp_event_keypress(wimp_key *key) { + static int *ucstable = NULL; + static int alphabet = 0; + static wchar_t wc = 0; /* buffer for UTF8 alphabet */ + static int shift = 0; struct event_window *window; + wimp_key k; + wchar_t c = (wchar_t)key->c; + int t_alphabet; + os_error *error; window = ro_gui_wimp_event_find_window(key->w); if (!window) return false; + /* copy key state so we can corrupt it safely */ + memcpy(&k, key, sizeof(wimp_key)); + + /* In order to make sensible use of the 0x80->0xFF ranges specified + * in the RISC OS 8bit alphabets, we must do the following: + * + * + Read the currently selected alphabet + * + Acquire a pointer to the UCS conversion table for this alphabet: + * + Try using ServiceInternational 8 to get the table + * + If that fails, use our internal table (see ucstables.c) + * + If the alphabet is not UTF8 and the conversion table exists: + * + Lookup UCS code in the conversion table + * + If code is -1 (i.e. undefined): + * + Use codepoint 0xFFFD instead + * + If the alphabet is UTF8, we must buffer input, thus: + * + If the keycode is < 0x80: + * + Handle it directly + * + If the keycode is a UTF8 sequence start: + * + Initialise the buffer appropriately + * + Otherwise: + * + OR in relevant bits from keycode to buffer + * + If we've received an entire UTF8 character: + * + Handle UCS code + * + Otherwise: + * + Simply handle the keycode directly, as there's no easy way + * of performing the mapping from keycode -> UCS4 codepoint. + */ + error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &t_alphabet); + if (error) { + LOG(("failed reading alphabet: 0x%x: %s", + error->errnum, error->errmess)); + /* prevent any corruption of ucstable */ + t_alphabet = alphabet; + } + + if (t_alphabet != alphabet) { + osbool unclaimed; + /* Alphabet has changed, so read UCS table location */ + alphabet = t_alphabet; + + error = xserviceinternational_get_ucs_conversion_table( + alphabet, &unclaimed, + (void**)&ucstable); + if (error) { + LOG(("failed reading UCS conversion table: 0x%x: %s", + error->errnum, error->errmess)); + /* try using our own table instead */ + ucstable = ucstable_from_alphabet(alphabet); + } + if (unclaimed) + /* Service wasn't claimed so use our own ucstable */ + ucstable = ucstable_from_alphabet(alphabet); + } + + if (c < 256) { + if (alphabet != 111 /* UTF8 */ && ucstable != NULL) { + /* defined in this alphabet? */ + if (ucstable[c] == -1) + return true; + + /* read UCS4 value out of table */ + k.c = ucstable[c]; + } + else if (alphabet == 111 /* UTF8 */) { + if ((c & 0x80) == 0x00 || (c & 0xC0) == 0xC0) { + /* UTF8 start sequence */ + if ((c & 0xE0) == 0xC0) { + wc = ((c & 0x1F) << 6); + shift = 1; + return true; + } + else if ((c & 0xF0) == 0xE0) { + wc = ((c & 0x0F) << 12); + shift = 2; + return true; + } + else if ((c & 0xF8) == 0xF0) { + wc = ((c & 0x07) << 18); + shift = 3; + return true; + } + /* These next two have been removed + * from RFC3629, but there's no + * guarantee that RISC OS won't + * generate a UCS4 value outside the + * UTF16 plane, so we handle them + * anyway. */ + else if ((c & 0xFC) == 0xF8) { + wc = ((c & 0x03) << 24); + shift = 4; + } + else if ((c & 0xFE) == 0xFC) { + wc = ((c & 0x01) << 30); + shift = 5; + } + else if (c >= 0x80) { + /* If this ever happens, + * RISC OS' UTF8 keyboard + * drivers are broken */ + LOG(("unexpected UTF8 start" + " byte %x (ignoring)", + c)); + return true; + } + /* Anything else is ASCII, so just + * handle it directly. */ + } + else { + if ((c & 0xC0) != 0x80) { + /* If this ever happens, + * RISC OS' UTF8 keyboard + * drivers are broken */ + LOG(("unexpected keycode: " + "%x (ignoring)", c)); + return true; + } + + /* Continuation of UTF8 character */ + wc |= ((c & 0x3F) << (6 * --shift)); + if (shift > 0) + /* partial character */ + return true; + else + /* got entire character, so + * fetch from buffer and + * handle it */ + k.c = wc; + } + } + } else { + k.c |= (1u<<31); + } + /* registered routines take priority */ if (window->keypress) - if (window->keypress(key)) + if (window->keypress(&k)) return true; switch (key->c) { @@ -882,6 +1027,11 @@ bool ro_gui_wimp_event_register_mouse_click(wimp_w w, /** * Register a function to be called for all keypresses within a * particular window. + * + * Important: the character code passed to the callback in key->c + * is UTF-32 (i.e. in the range [0, &10ffff]). WIMP keys (e.g. F1) + * will have bit 31 set. + * */ bool ro_gui_wimp_event_register_keypress(wimp_w w, bool (*callback)(wimp_key *key)) { diff --git a/riscos/wimp_event.h b/riscos/wimp_event.h index c244e6f5f..b48b59c9d 100644 --- a/riscos/wimp_event.h +++ b/riscos/wimp_event.h @@ -21,6 +21,8 @@ #include "oslib/os.h" #include "oslib/wimp.h" +#define IS_WIMP_KEY (1u<<31) + bool ro_gui_wimp_event_memorise(wimp_w w); bool ro_gui_wimp_event_restore(wimp_w w); bool ro_gui_wimp_event_validate(wimp_w w); diff --git a/riscos/window.c b/riscos/window.c index 6dd21536b..a2a3723fc 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -25,7 +25,6 @@ #include "oslib/osbyte.h" #include "oslib/osfile.h" #include "oslib/osspriteop.h" -#include "oslib/serviceinternational.h" #include "oslib/wimp.h" #include "oslib/wimpspriteop.h" #include "netsurf/utils/config.h" @@ -50,9 +49,9 @@ #include "netsurf/riscos/save.h" #include "netsurf/riscos/theme.h" #include "netsurf/riscos/thumbnail.h" -#include "netsurf/riscos/ucstables.h" #include "netsurf/riscos/url_complete.h" #include "netsurf/riscos/wimp.h" +#include "netsurf/riscos/wimp_event.h" #include "netsurf/utils/log.h" #include "netsurf/utils/talloc.h" #include "netsurf/utils/url.h" @@ -80,6 +79,8 @@ 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)) +static bool ro_gui_window_click(wimp_pointer *mouse); +static bool ro_gui_window_keypress(wimp_key *key); static void ro_gui_window_launch_url(struct gui_window *g, const char *url); static void ro_gui_window_clone_options(struct browser_window *new_bw, struct browser_window *old_bw); @@ -88,14 +89,14 @@ static bool ro_gui_window_import_text(struct gui_window *g, const char *filename bool toolbar); struct update_box { - int x0; - int y0; - int x1; - int y1; - bool use_buffer; - struct gui_window *g; - union content_msg_data data; - struct update_box *next; + int x0; + int y0; + int x1; + int y1; + bool use_buffer; + struct gui_window *g; + union content_msg_data data; + struct update_box *next; }; struct update_box *pending_updates; @@ -318,6 +319,15 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, return g; } + /* and register event handlers */ + ro_gui_wimp_event_register_keypress(g->window, + ro_gui_window_keypress); + ro_gui_wimp_event_register_keypress(g->toolbar->toolbar_handle, + ro_gui_window_keypress); + + ro_gui_wimp_event_register_mouse_click(g->window, + ro_gui_window_click); + return g; } @@ -510,7 +520,7 @@ void ro_gui_window_redraw(struct gui_window *g, wimp_draw *redraw) * slow things down. */ if (c->type == CONTENT_TEXTPLAIN) knockout = false; - + /* HTML rendering handles scale itself */ if (c->type == CONTENT_HTML) scale = 1; @@ -587,7 +597,7 @@ void ro_gui_window_update_boxes(void) { 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; @@ -698,7 +708,7 @@ void ro_gui_window_update_boxes(void) { pending_updates = pending_updates->next; free(cur); } - + } /** * Redraw an area of a window. @@ -724,7 +734,7 @@ void gui_window_update_box(struct gui_window *g, y1 = -floorf(data->redraw.y * 2 * g->option.scale) + 1; use_buffer = (data->redraw.full_redraw) && (g->option.buffer_everything || g->option.buffer_animations); - + /* try to optimise buffered redraws */ if (use_buffer) { for (cur = pending_updates; cur != NULL; cur = cur->next) { @@ -736,10 +746,10 @@ void gui_window_update_box(struct gui_window *g, cur->y0 = min(cur->y0, y0); cur->x1 = max(cur->x1, x1); cur->y1 = max(cur->y1, y1); - return; + return; } - - } + + } } cur = malloc(sizeof(struct update_box)); if (!cur) { @@ -1482,7 +1492,7 @@ bool ro_gui_toolbar_click(wimp_pointer *pointer) new_bw = browser_window_create(NULL, g->bw, NULL, false); ro_gui_menu_handle_action(new_bw->window->window, - BROWSER_NAVIGATE_BACK, true); + BROWSER_NAVIGATE_BACK, true); } else { ro_gui_menu_handle_action(g->window, BROWSER_NAVIGATE_BACK, true); @@ -1494,7 +1504,7 @@ bool ro_gui_toolbar_click(wimp_pointer *pointer) new_bw = browser_window_create(NULL, g->bw, NULL, false); ro_gui_menu_handle_action(new_bw->window->window, - BROWSER_NAVIGATE_FORWARD, true); + BROWSER_NAVIGATE_FORWARD, true); } else { ro_gui_menu_handle_action(g->window, BROWSER_NAVIGATE_FORWARD, true); @@ -1638,17 +1648,20 @@ bool ro_gui_status_click(wimp_pointer *pointer) /** * Handle Mouse_Click events in a browser window. * - * \param g browser window * \param pointer details of mouse click + * \return true if click handled, false otherwise */ -void ro_gui_window_click(struct gui_window *g, 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; - assert(g); + g = ro_gui_window_lookup(pointer->w); + if (!g) + return false; /* try to close url-completion */ ro_gui_url_complete_close(g, pointer->i); @@ -1659,7 +1672,7 @@ void ro_gui_window_click(struct gui_window *g, wimp_pointer *pointer) LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); - return; + return false; } x = window_x_units(pointer->pos.x, &state) / 2 / g->option.scale; @@ -1674,7 +1687,7 @@ void ro_gui_window_click(struct gui_window *g, wimp_pointer *pointer) LOG(("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); - return; + return false; } } @@ -1684,6 +1697,8 @@ void ro_gui_window_click(struct gui_window *g, wimp_pointer *pointer) else browser_window_mouse_click(g->bw, ro_gui_mouse_click_state(pointer->buttons), x, y); + + return true; } @@ -1789,17 +1804,30 @@ void gui_window_remove_caret(struct gui_window *g) * Process Key_Pressed events in a browser window. */ -bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) +bool ro_gui_window_keypress(wimp_key *key) { - struct content *content = g->bw->current_content; + struct gui_window *g; + bool toolbar; + struct content *content; wimp_window_state state; - int y, t_alphabet; + int y; char *toolbar_url; os_error *error; wimp_pointer pointer; float old_scale; - static int *ucstable = NULL; - static int alphabet = 0; + wchar_t c = (wchar_t)key->c; + + /* Find gui window */ + if ((g = ro_gui_window_lookup(key->w)) != NULL) { + toolbar = false; + } else if ((g = ro_gui_toolbar_lookup(key->w)) != NULL) { + toolbar = true; + } else { + /* nothing to do with us */ + return false; + } + + content = g->bw->current_content; error = xwimp_get_pointer_info(&pointer); if (error) { @@ -1809,76 +1837,21 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) return false; } - /* In order to make sensible use of the 0x80->0xFF ranges specified - * in the RISC OS 8bit alphabets, we must do the following: - * - * + Read the currently selected alphabet - * + Acquire a pointer to the UCS conversion table for this alphabet: - * + Try using ServiceInternational 8 to get the table - * + If that fails, use our internal table (see ucstables.c) - * + If the alphabet is not UTF8 and the conversion table exists: - * + Lookup UCS code in the conversion table - * + If code is -1 (i.e. undefined): - * + Use codepoint 0xFFFD instead - * + If the alphabet is UTF8, we must buffer input, thus: - * + If the keycode is < 0x80: - * + Handle it directly - * + If the keycode is a UTF8 sequence start: - * + Initialise the buffer appropriately - * + Otherwise: - * + OR in relevant bits from keycode to buffer - * + If we've received an entire UTF8 character: - * + Handle UCS code - * + Otherwise: - * + Simply handle the keycode directly, as there's no easy way - * of performing the mapping from keycode -> UCS4 codepoint. - */ - error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &t_alphabet); - if (error) { - LOG(("failed reading alphabet: 0x%x: %s", - error->errnum, error->errmess)); - /* prevent any corruption of ucstable */ - t_alphabet = alphabet; - } - - if (t_alphabet != alphabet) { - osbool unclaimed; - /* Alphabet has changed, so read UCS table location */ - alphabet = t_alphabet; - - error = xserviceinternational_get_ucs_conversion_table( - alphabet, &unclaimed, - (void**)&ucstable); - if (error) { - LOG(("failed reading UCS conversion table: 0x%x: %s", - error->errnum, error->errmess)); - /* try using our own table instead */ - ucstable = ucstable_from_alphabet(alphabet); - } - if (unclaimed) - /* Service wasn't claimed so use our own ucstable */ - ucstable = ucstable_from_alphabet(alphabet); - } - /* First send the key to the browser window, eg. form fields. */ if (!toolbar) { - wchar_t c = (wchar_t)key; - static wchar_t wc = 0; /* buffer for UTF8 alphabet */ - static int shift = 0; - bool ctrl_key = true; - - /* Munge cursor keys into unused control chars */ + if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) || + (c & IS_WIMP_KEY)) { + /* Munge control keys into unused control chars */ /* We can't map onto 1->26 (reserved for ctrl+ That leaves 27->31 and 128->159 */ - - switch (key) { + switch (c & ~IS_WIMP_KEY) { case wimp_KEY_TAB: c = 9; break; case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break; /* cursor movement keys */ case wimp_KEY_HOME: case wimp_KEY_CONTROL | wimp_KEY_LEFT: - c = KEY_LINE_START; break; + c = KEY_LINE_START; break; case wimp_KEY_END: if (os_version >= RISCOS5) @@ -1910,95 +1883,19 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) break; default: - ctrl_key = false; break; + } } - if (c < 256) { - if (ctrl_key) - /* do nothing, these are our control chars */; - else if (alphabet != 111 /* UTF8 */ && - ucstable != NULL) { - /* defined in this alphabet? */ - if (ucstable[c] == -1) - return true; - - /* read UCS4 value out of table */ - c = ucstable[c]; - } - else if (alphabet == 111 /* UTF8 */) { - if ((c & 0x80) == 0x00 || - (c & 0xC0) == 0xC0) { - /* UTF8 start sequence */ - if ((c & 0xE0) == 0xC0) { - wc = ((c & 0x1F) << 6); - shift = 1; - return true; - } - else if ((c & 0xF0) == 0xE0) { - wc = ((c & 0x0F) << 12); - shift = 2; - return true; - } - else if ((c & 0xF8) == 0xF0) { - wc = ((c & 0x07) << 18); - shift = 3; - return true; - } - /* These next two have been removed - * from RFC3629, but there's no - * guarantee that RISC OS won't - * generate a UCS4 value outside the - * UTF16 plane, so we handle them - * anyway. */ - else if ((c & 0xFC) == 0xF8) { - wc = ((c & 0x03) << 24); - shift = 4; - } - else if ((c & 0xFE) == 0xFC) { - wc = ((c & 0x01) << 30); - shift = 5; - } - else if (c >= 0x80) { - /* If this ever happens, - * RISC OS' UTF8 keyboard - * drivers are broken */ - LOG(("unexpected UTF8 start" - " byte %x (ignoring)", - c)); - return true; - } - /* Anything else is ASCII, so just - * handle it directly. */ - } - else { - if ((c & 0xC0) != 0x80) { - /* If this ever happens, - * RISC OS' UTF8 keyboard - * drivers are broken */ - LOG(("unexpected keycode: " - "%x (ignoring)", c)); - return true; - } - - /* Continuation of UTF8 character */ - wc |= ((c & 0x3F) << (6 * --shift)); - if (shift > 0) - /* partial character */ - return true; - else - /* got entire character, so - * fetch from buffer and - * handle it */ - c = wc; - } - } + if (!(c & IS_WIMP_KEY)) { if (browser_window_key_press(g->bw, c)) return true; } } - switch (key) { + c &= ~IS_WIMP_KEY; + + switch (c) { case wimp_KEY_F1: /* Help. */ return ro_gui_menu_handle_action(g->window, HELP_OPEN_CONTENTS, false); @@ -2135,7 +2032,7 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) } } } else { - return ro_gui_url_complete_keypress(g, key); + return ro_gui_url_complete_keypress(g, c); } break; @@ -2148,13 +2045,13 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) if (!content) break; old_scale = g->option.scale; - if (ro_gui_shift_pressed() && key == 17) + if (ro_gui_shift_pressed() && c == 17) g->option.scale = ((int) (10 * g->option.scale - 1)) / 10.0; - else if (ro_gui_shift_pressed() && key == 23) + else if (ro_gui_shift_pressed() && c == 23) g->option.scale = ((int) (10 * g->option.scale + 1)) / 10.0; - else if (key == 17) { + else if (c == 17) { for (int i = SCALE_SNAP_TO_SIZE - 1; i >= 0; i--) if (scale_snap_to[i] < old_scale) { g->option.scale = scale_snap_to[i]; @@ -2182,8 +2079,8 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) #ifdef WITH_PRINT case wimp_KEY_PRINT: - return ro_gui_menu_handle_action(g->window, - BROWSER_PRINT, false); + return ro_gui_menu_handle_action(g->window, + BROWSER_PRINT, false); #endif case wimp_KEY_UP: @@ -2193,11 +2090,11 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) case wimp_KEY_CONTROL | wimp_KEY_UP: case wimp_KEY_CONTROL | wimp_KEY_DOWN: if (toolbar) - return ro_gui_url_complete_keypress(g, key); + return ro_gui_url_complete_keypress(g, c); break; default: if (toolbar) - return ro_gui_url_complete_keypress(g, key); + return ro_gui_url_complete_keypress(g, c); return false; } @@ -2207,7 +2104,7 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) if (g->toolbar) y -= ro_gui_theme_toolbar_full_height(g->toolbar); - switch (key) { + switch (c) { case wimp_KEY_UP: state.yscroll += 32; break; @@ -3181,7 +3078,7 @@ bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) { char *parent; url_func_result res; bool compare; - + if (!g || (!g->bw)) return false;