Centralise keypress handling (download and query dialogs still need porting over to wimp_event)

Make core browser window invalidate caret callback on mouse clicks

svn path=/trunk/netsurf/; revision=2746
This commit is contained in:
John Mark Bell 2006-07-13 21:57:35 +00:00
parent 3716a5853e
commit 25501c695e
8 changed files with 285 additions and 359 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -3,7 +3,7 @@
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
* Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk>
* Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
* Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
*/
/** \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);

View File

@ -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;
}

View File

@ -15,9 +15,12 @@
#include <stdio.h>
#include <string.h>
#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)) {

View File

@ -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);

View File

@ -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+<qwerty>
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;