mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-23 23:09:39 +03:00
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:
parent
3716a5853e
commit
25501c695e
@ -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 */
|
||||
|
12
riscos/gui.c
12
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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
257
riscos/window.c
257
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+<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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user