summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--!NetSurf/Resources/en/Messages9
-rw-r--r--!NetSurf/Resources/fr/Messages9
-rw-r--r--desktop/browser.c592
-rw-r--r--desktop/browser.h33
-rw-r--r--desktop/gui.h24
-rw-r--r--render/box.c128
-rw-r--r--render/box.h3
-rw-r--r--riscos/gui.c50
-rw-r--r--riscos/menus.c117
-rw-r--r--riscos/textselection.c10
-rw-r--r--riscos/window.c40
11 files changed, 519 insertions, 496 deletions
diff --git a/!NetSurf/Resources/en/Messages b/!NetSurf/Resources/en/Messages
index 6b4f40d3f..0d97b1d8c 100644
--- a/!NetSurf/Resources/en/Messages
+++ b/!NetSurf/Resources/en/Messages
@@ -108,6 +108,15 @@ Form_Reset:Reset
Form_None:
Form_Many:(Many)
Form_Drop:Drop file here
+FormSelect:Click to choose a form item
+FormCheckbox:Click to check this option
+FormRadio:Click to choose this option
+FormSubmit:Send form to %s
+FormBadSubmit:Warning: form can not be submitted
+FormTextarea:Click to edit the text
+FormTextbox:Click to edit this field
+FormReset:Reset form (not implemented)
+FormFile:Drop a file here to upload it
Not2xx:Server returned an error
diff --git a/!NetSurf/Resources/fr/Messages b/!NetSurf/Resources/fr/Messages
index 4f0e614fb..f3fc31918 100644
--- a/!NetSurf/Resources/fr/Messages
+++ b/!NetSurf/Resources/fr/Messages
@@ -108,6 +108,15 @@ Form_Reset:Effacer
Form_None:
Form_Many:(Plusieurs)
Form_Drop:Déposer les fichiers ici
+FormSelect:Click to choose a form item
+FormCheckbox:Click to check this option
+FormRadio:Click to choose this option
+FormSubmit:Send form to %s
+FormBadSubmit:Warning: form can not be submitted
+FormTextarea:Click to edit the text
+FormTextbox:Click to edit this field
+FormReset:Reset form (not implemented)
+FormFile:Drop a file here to upload it
Not2xx:Le serveur a renvoyé une erreur
diff --git a/desktop/browser.c b/desktop/browser.c
index 075df260b..c83fe9c9a 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -49,6 +49,8 @@ static void browser_window_set_status(struct browser_window *bw,
static void browser_window_set_pointer(gui_pointer_shape shape);
static void download_window_callback(fetch_msg msg, void *p, const char *data,
unsigned long size);
+static void browser_window_mouse_click_html(struct browser_window *bw,
+ browser_mouse_click click, int x, int y);
static void browser_window_text_selection(struct browser_window* bw,
unsigned long click_x, unsigned long click_y, int click_type);
@@ -58,13 +60,9 @@ static int redraw_box_list(struct browser_window* bw, struct box* current,
unsigned long x, unsigned long y, struct box_position* start,
struct box_position* end, int* plot);
static void browser_window_redraw_boxes(struct browser_window* bw, struct box_position* start, struct box_position* end);
-static void browser_window_follow_link(struct browser_window* bw,
- unsigned long click_x, unsigned long click_y, int click_type);
static void clear_radio_gadgets(struct browser_window* bw, struct box* box, struct form_control* group);
static void gui_redraw_gadget2(struct browser_window* bw, struct box* box, struct form_control* g,
unsigned long x, unsigned long y);
-static void browser_window_gadget_select(struct browser_window* bw, struct form_control* g, int item);
-static int browser_window_gadget_click(struct browser_window* bw, unsigned long click_x, unsigned long click_y);
static void browser_form_submit(struct browser_window *bw, struct form *form,
struct form_control *submit_button);
static void browser_window_textarea_click(struct browser_window* bw,
@@ -533,6 +531,204 @@ void download_window_callback(fetch_msg msg, void *p, const char *data,
}
+/**
+ * Handle mouse clicks in a browser window.
+ *
+ * \param bw browser window
+ * \param click type of mouse click
+ * \param x coordinate of mouse
+ * \param y coordinate of mouse
+ */
+
+void browser_window_mouse_click(struct browser_window *bw,
+ browser_mouse_click click, int x, int y)
+{
+ if (!bw->current_content)
+ return;
+
+ if (bw->current_content->type == CONTENT_HTML)
+ browser_window_mouse_click_html(bw, click, x, y);
+}
+
+
+/**
+ * Handle mouse clicks in an HTML content window.
+ *
+ * \param bw browser window
+ * \param click type of mouse click
+ * \param x coordinate of mouse
+ * \param y coordinate of mouse
+ */
+
+void browser_window_mouse_click_html(struct browser_window *bw,
+ browser_mouse_click click, int x, int y)
+{
+ struct content *c = bw->current_content;
+ struct box *box = c->data.html.layout;
+ int box_x = 0, box_y = 0;
+ struct content *content = c;
+ struct content *gadget_content = c;
+ char *base_url = 0;
+ char *href = 0;
+ char *title = 0;
+ struct form_control *gadget = 0;
+ const char *status = 0;
+ char status_buffer[200];
+ gui_pointer_shape pointer = GUI_POINTER_DEFAULT;
+ char *url;
+
+ /* search the box tree for a link, imagemap, or form control */
+ while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
+ if (box->style &&
+ box->style->visibility == CSS_VISIBILITY_HIDDEN)
+ continue;
+
+ if (box->href) {
+ base_url = content->data.html.base_url;
+ href = box->href;
+ }
+
+ if (box->usemap) {
+ base_url = content->data.html.base_url;
+ href = imagemap_get(content, box->usemap,
+ box_x, box_y, x, y);
+ }
+
+ if (box->gadget) {
+ gadget_content = content;
+ base_url = content->data.html.base_url;
+ gadget = box->gadget;
+ }
+
+ if (box->title)
+ title = box->title;
+
+ if (box->style && box->style->cursor != CSS_CURSOR_UNKNOWN)
+ pointer = get_pointer_shape(box->style->cursor);
+ }
+
+ if (gadget) {
+ switch (gadget->type) {
+ case GADGET_SELECT:
+ status = messages_get("FormSelect");
+ pointer = GUI_POINTER_MENU;
+ if (click == BROWSER_MOUSE_CLICK_1)
+ gui_create_form_select_menu(bw, gadget);
+ break;
+ case GADGET_CHECKBOX:
+ status = messages_get("FormCheckbox");
+ if (click == BROWSER_MOUSE_CLICK_1) {
+ gadget->selected = !gadget->selected;
+ gui_redraw_gadget(bw, gadget);
+ }
+ break;
+ case GADGET_RADIO:
+ status = messages_get("FormRadio");
+ if (click == BROWSER_MOUSE_CLICK_1) {
+ clear_radio_gadgets(bw,
+ gadget_content->data.html.
+ layout, gadget);
+ gadget->selected = true;
+ gui_redraw_gadget(bw, gadget);
+ }
+ break;
+ case GADGET_IMAGE:
+ if (click == BROWSER_MOUSE_CLICK_1) {
+ gadget->data.image.mx = x - box_x;
+ gadget->data.image.my = y - box_y;
+ }
+ /* drop through */
+ case GADGET_SUBMIT:
+ if (gadget->form) {
+ url = url_join(gadget->form->action, base_url);
+ snprintf(status_buffer, sizeof status_buffer,
+ messages_get("FormSubmit"),
+ url ? url :
+ gadget->form->action);
+ status = status_buffer;
+ pointer = GUI_POINTER_POINT;
+ if (click == BROWSER_MOUSE_CLICK_1)
+ browser_form_submit(bw, gadget->form,
+ gadget);
+ } else {
+ status = messages_get("FormBadSubmit");
+ }
+ break;
+ case GADGET_TEXTAREA:
+ status = messages_get("FormTextarea");
+ pointer = GUI_POINTER_CARET;
+ if (click == BROWSER_MOUSE_CLICK_1)
+ browser_window_textarea_click(bw,
+ box_x, box_y,
+ x - box_x, y - box_y,
+ box);
+ break;
+ case GADGET_TEXTBOX:
+ case GADGET_PASSWORD:
+ status = messages_get("FormTextbox");
+ pointer = GUI_POINTER_CARET;
+ if (click == BROWSER_MOUSE_CLICK_1)
+ browser_window_input_click(bw,
+ box_x, box_y,
+ x - box_x, y - box_y,
+ box);
+ break;
+ case GADGET_HIDDEN:
+ /* not possible: no box generated */
+ break;
+ case GADGET_RESET:
+ status = messages_get("FormReset");
+ break;
+ case GADGET_FILE:
+ status = messages_get("FormFile");
+ break;
+ }
+
+ } else if (href) {
+ url = url_join(href, base_url);
+ if (!url)
+ return;
+
+ if (title) {
+ snprintf(status_buffer, sizeof status_buffer, "%s: %s",
+ title, url);
+ status = status_buffer;
+ } else
+ status = url;
+
+ pointer = GUI_POINTER_POINT;
+
+ if (click == BROWSER_MOUSE_CLICK_1 ||
+ click == BROWSER_MOUSE_CLICK_2) {
+ if (fetch_can_fetch(url)) {
+ if (click == BROWSER_MOUSE_CLICK_1)
+ browser_window_go(bw, url);
+ else
+ browser_window_create(url, bw);
+ } else {
+ gui_launch_url(url);
+ }
+ }
+
+ } else if (title) {
+ status = title;
+
+ } else {
+ if (bw->loading_content)
+ status = bw->loading_content->status_message;
+ else
+ status = c->status_message;
+ }
+
+ assert(status);
+
+ browser_window_set_status(bw, status);
+ browser_window_set_pointer(pointer);
+}
+
+
+
+
void clear_radio_gadgets(struct browser_window *bw, struct box *box,
struct form_control *group)
{
@@ -587,138 +783,8 @@ void gui_redraw_gadget(struct browser_window* bw, struct form_control* g)
gui_redraw_gadget2(bw, bw->current_content->data.html.layout->children, g, 0, 0);
}
-void browser_window_gadget_select(struct browser_window* bw, struct form_control* g, int item)
-{
- struct form_option* o;
- int count;
- struct box *inline_box = g->box->children->children;
- int x, y;
-
- for (count = 0, o = g->data.select.items;
- o != NULL;
- count++, o = o->next) {
- if (!g->data.select.multiple)
- o->selected = false;
- if (count == item) {
- if (g->data.select.multiple) {
- if (o->selected) {
- o->selected = false;
- g->data.select.num_selected--;
- } else {
- o->selected = true;
- g->data.select.num_selected++;
- }
- } else {
- o->selected = true;
- }
- }
- if (o->selected)
- g->data.select.current = o;
- }
-
- xfree(inline_box->text);
- if (g->data.select.num_selected == 0)
- inline_box->text = xstrdup(messages_get("Form_None"));
- else if (g->data.select.num_selected == 1)
- inline_box->text = xstrdup(g->data.select.current->text);
- else
- inline_box->text = xstrdup(messages_get("Form_Many"));
- inline_box->width = g->box->width;
- inline_box->length = strlen(inline_box->text);
-
- box_coords(g->box, &x, &y);
- gui_window_redraw(bw->window, (unsigned int)x, (unsigned int)y,
- (unsigned int)(x + g->box->width),
- (unsigned int)(y + g->box->height));
-}
-
-int browser_window_gadget_click(struct browser_window* bw, unsigned long click_x, unsigned long click_y)
-{
- struct box_selection* click_boxes;
- int found, plot_index;
- int i;
- int x, y;
-
- found = 0;
- click_boxes = NULL;
- plot_index = 0;
-
- assert(bw->current_content->type == CONTENT_HTML);
- box_under_area(bw->current_content,
- bw->current_content->data.html.layout->children,
- click_x, click_y, 0, 0, &click_boxes, &found, &plot_index);
-
- if (found == 0)
- return 0;
-
- for (i = found - 1; i >= 0; i--)
- {
- if (click_boxes[i].box->style->visibility == CSS_VISIBILITY_HIDDEN)
- continue;
-
- if (click_boxes[i].box->gadget)
- {
- struct form_control* g = click_boxes[i].box->gadget;
-
- /* gadget clicked */
- switch (g->type)
- {
- case GADGET_SELECT:
- gui_gadget_combo(bw, g, click_x, click_y);
- break;
- case GADGET_CHECKBOX:
- g->selected = !g->selected;
- gui_redraw_gadget(bw, g);
- break;
- case GADGET_RADIO:
- clear_radio_gadgets(bw, click_boxes[i].content->data.html.layout->children, g);
- g->selected = true;
- gui_redraw_gadget(bw, g);
- break;
- case GADGET_SUBMIT:
- if (g->form)
- browser_form_submit(bw, g->form, g);
- break;
- case GADGET_TEXTAREA:
- browser_window_textarea_click(bw,
- (unsigned int)click_boxes[i].actual_x,
- (unsigned int)click_boxes[i].actual_y,
- (int)(click_x - click_boxes[i].actual_x),
- (int)(click_y - click_boxes[i].actual_y),
- click_boxes[i].box);
- break;
- case GADGET_TEXTBOX:
- case GADGET_PASSWORD:
- browser_window_input_click(bw,
- (unsigned int)click_boxes[i].actual_x,
- (unsigned int)click_boxes[i].actual_y,
- click_x - click_boxes[i].actual_x,
- click_y - click_boxes[i].actual_y,
- click_boxes[i].box);
- break;
- case GADGET_HIDDEN:
- break;
- case GADGET_IMAGE:
- box_coords(click_boxes[i].box, &x, &y);
- g->data.image.mx = click_x - x;
- g->data.image.my = click_y - y;
- if (g->form)
- browser_form_submit(bw, g->form, g);
- break;
- case GADGET_RESET:
- break;
- case GADGET_FILE:
- break;
- }
- xfree(click_boxes);
- return 1;
- }
- }
- xfree(click_boxes);
- return 0;
-}
/**
@@ -1342,47 +1408,67 @@ bool browser_window_key_press(struct browser_window *bw, char key)
}
-int browser_window_action(struct browser_window *bw,
- struct browser_action *act)
+/**
+ * Process a selection from a form select menu.
+ *
+ * \param bw browser window with menu
+ * \param control form control with menu
+ * \param item index of item selected from the menu
+ */
+
+void browser_window_form_select(struct browser_window *bw,
+ struct form_control *control, int item)
{
- switch (act->type) {
- case act_MOUSE_AT:
- browser_window_follow_link(bw, act->data.mouse.x,
- act->data.mouse.y, 0);
- break;
- case act_MOUSE_CLICK:
- return browser_window_gadget_click(bw, act->data.mouse.x,
- act->data.mouse.y);
- break;
- case act_CLEAR_SELECTION:
-// browser_window_text_selection(bw, act->data.mouse.x,
-// act->data.mouse.y, 0);
- break;
- case act_START_NEW_SELECTION:
-// browser_window_text_selection(bw, act->data.mouse.x,
-// act->data.mouse.y, 1);
- break;
- case act_ALTER_SELECTION:
-// browser_window_text_selection(bw, act->data.mouse.x,
-// act->data.mouse.y, 2);
- break;
- case act_FOLLOW_LINK:
- browser_window_follow_link(bw, act->data.mouse.x,
- act->data.mouse.y, 1);
- break;
- case act_FOLLOW_LINK_NEW_WINDOW:
- browser_window_follow_link(bw, act->data.mouse.x,
- act->data.mouse.y, 2);
- break;
- case act_GADGET_SELECT:
- browser_window_gadget_select(bw, act->data.gadget_select.g,
- act->data.gadget_select.item);
- default:
- break;
+ struct form_option *o;
+ int count;
+ struct box *inline_box = control->box->children->children;
+ int x, y;
+
+ for (count = 0, o = control->data.select.items;
+ o != NULL;
+ count++, o = o->next) {
+ if (!control->data.select.multiple)
+ o->selected = false;
+ if (count == item) {
+ if (control->data.select.multiple) {
+ if (o->selected) {
+ o->selected = false;
+ control->data.select.num_selected--;
+ } else {
+ o->selected = true;
+ control->data.select.num_selected++;
+ }
+ } else {
+ o->selected = true;
+ }
+ }
+ if (o->selected)
+ control->data.select.current = o;
}
- return 0;
+
+ free(inline_box->text);
+ inline_box->text = 0;
+ if (control->data.select.num_selected == 0)
+ inline_box->text = strdup(messages_get("Form_None"));
+ else if (control->data.select.num_selected == 1)
+ inline_box->text = strdup(control->data.select.current->text);
+ else
+ inline_box->text = strdup(messages_get("Form_Many"));
+ if (!inline_box->text) {
+ warn_user("NoMemory", 0);
+ inline_box->length = 0;
+ } else
+ inline_box->length = strlen(inline_box->text);
+ inline_box->width = control->box->width;
+
+ box_coords(control->box, &x, &y);
+ gui_window_redraw(bw->window, x, y,
+ x + control->box->width, y + control->box->height);
}
+
+
+
void box_under_area(struct content *content, struct box *box,
unsigned long x, unsigned long y,
unsigned long ox, unsigned long oy,
@@ -1471,170 +1557,6 @@ gui_pointer_shape get_pointer_shape(css_cursor cursor) {
return pointer;
}
-void browser_window_follow_link(struct browser_window *bw,
- unsigned long click_x,
- unsigned long click_y, int click_type)
-{
- struct box_selection *click_boxes;
- int found, plot_index;
- int i;
- int done = 0;
- struct css_style *style;
- gui_pointer_shape pointer = GUI_POINTER_DEFAULT;
-
- found = 0;
- click_boxes = NULL;
- plot_index = 0;
-
- if (bw->current_content->type != CONTENT_HTML)
- return;
-
- box_under_area(bw->current_content,
- bw->current_content->data.html.layout->children,
- click_x, click_y, 0, 0, &click_boxes, &found,
- &plot_index);
-
- if (found == 0)
- return;
-
- for (i = found - 1; i >= 0; i--) {
- style = click_boxes[i].box->style;
- if (style != 0 && style->visibility == CSS_VISIBILITY_HIDDEN)
- continue;
- if (click_boxes[i].box->href != NULL) {
- char *url =
- url_join((char *) click_boxes[i].box->href,
- click_boxes[i].content->data.html.
- base_url);
- if (!url)
- continue;
-
- if (click_type == 1) {
- if (fetch_can_fetch(url)) {
- browser_window_go(bw, url);
- }
- else {
- gui_launch_url(url);
- done = 1;
- }
- } else if (click_type == 2) {
- if (fetch_can_fetch(url)) {
- browser_window_create(url, bw);
- }
- else {
- gui_launch_url(url);
- done = 1;
- }
- } else if (click_type == 0) {
- browser_window_set_status(bw, url);
- pointer = GUI_POINTER_POINT;
- done = 1;
- }
- free(url);
- break;
- }
- if (click_boxes[i].box->usemap != NULL) {
- char *href, *url;
-
- href = imagemap_get(click_boxes[i].content,
- click_boxes[i].box->usemap,
- click_boxes[i].actual_x,
- click_boxes[i].actual_y,
- click_x, click_y);
- if (!href)
- continue;
-
- url = url_join(href,
- click_boxes[i].content->data.html.
- base_url);
- if (!url)
- continue;
-
- if (click_type == 1) {
- if (fetch_can_fetch(url)) {
- browser_window_go(bw, url);
- }
- else {
- gui_launch_url(url);
- done = 1;
- }
- } else if (click_type == 2) {
- if (fetch_can_fetch(url)) {
- browser_window_create(url, NULL);
- }
- else {
- gui_launch_url(url);
- done = 1;
- }
- } else if (click_type == 0) {
- browser_window_set_status(bw, url);
- pointer = GUI_POINTER_POINT;
- done = 1;
- }
- free(url);
- break;
- }
- if (click_type == 0 && click_boxes[i].box->gadget != NULL) {
- if (click_boxes[i].box->gadget->type == GADGET_TEXTBOX ||
- click_boxes[i].box->gadget->type == GADGET_TEXTAREA ||
- click_boxes[i].box->gadget->type == GADGET_PASSWORD) {
- pointer = GUI_POINTER_CARET;
- done = 1;
- break;
- }
- else if (click_boxes[i].box->gadget->type == GADGET_SELECT) {
- pointer = GUI_POINTER_MENU;
- done = 1;
- break;
- }
- else if (click_boxes[i].box->gadget->type == GADGET_SUBMIT || click_boxes[i].box->gadget->type == GADGET_IMAGE) {
- struct form *form;
- char *url, *href;
- form = click_boxes[i].box->gadget->form;
- if (!form) continue;
- href = form->action;
- if (!href) continue;
- url = url_join(href, click_boxes[i].content->data.html.base_url);
- if (!url) continue;
- browser_window_set_status(bw, url);
- free(url);
- done = 1;
- break;
- }
- }
- if (click_type == 0 && click_boxes[i].box->title != NULL) {
- browser_window_set_status(bw,
- click_boxes[i].box->
- title);
- done = 1;
- break;
- }
- if (click_type == 0 && style != 0 &&
- style->cursor != CSS_CURSOR_UNKNOWN &&
- pointer == GUI_POINTER_DEFAULT) {
- pointer = get_pointer_shape(click_boxes[i].box->style->cursor);
- }
- }
-
- if (click_type == 0 && done == 0) {
- if (bw->loading_content != 0) {
- browser_window_set_status(bw,
- bw->loading_content->
- status_message);
- }
- else {
- browser_window_set_status(bw,
- bw->current_content->
- status_message);
- }
- }
-
- browser_window_set_pointer(pointer);
-
- free(click_boxes);
-
- return;
-}
void browser_window_text_selection(struct browser_window *bw,
unsigned long click_x,
diff --git a/desktop/browser.h b/desktop/browser.h
index 1a3427107..cd6cc202c 100644
--- a/desktop/browser.h
+++ b/desktop/browser.h
@@ -53,25 +53,12 @@ struct browser_window
};
-struct browser_action
-{
- enum { act_UNKNOWN,
- act_MOUSE_AT, act_MOUSE_CLICK, act_START_NEW_SELECTION,
- act_ALTER_SELECTION, act_CLEAR_SELECTION,
- act_FOLLOW_LINK, act_FOLLOW_LINK_NEW_WINDOW,
- act_GADGET_SELECT
- } type;
- union {
- struct {
- unsigned long x;
- unsigned long y;
- } mouse;
- struct {
- struct form_control* g;
- int item;
- } gadget_select;
- } data;
-};
+typedef enum {
+ BROWSER_MOUSE_CLICK_1,
+ BROWSER_MOUSE_CLICK_2,
+ BROWSER_MOUSE_HOVER,
+} browser_mouse_click;
+
struct box_selection
{
@@ -93,7 +80,11 @@ void browser_window_stop(struct browser_window *bw);
void browser_window_reload(struct browser_window *bw, bool all);
void browser_window_destroy(struct browser_window *bw);
-int browser_window_action(struct browser_window* bw, struct browser_action* act);
+void browser_window_mouse_click(struct browser_window *bw,
+ browser_mouse_click click, int x, int y);
+bool browser_window_key_press(struct browser_window *bw, char key);
+void browser_window_form_select(struct browser_window *bw,
+ struct form_control *control, int item);
void box_under_area(struct content *content, struct box* box, unsigned long x, unsigned long y, unsigned long ox, unsigned long oy,
struct box_selection** found, int* count, int* plot_index);
@@ -105,8 +96,6 @@ int box_position_distance(struct box_position* x, struct box_position* y);
void gui_redraw_gadget(struct browser_window* bw, struct form_control* g);
-bool browser_window_key_press(struct browser_window *bw, char key);
-
/* In platform specific hotlist.c. */
void hotlist_visited(struct content *content);
diff --git a/desktop/gui.h b/desktop/gui.h
index bef7f2362..e0ad49aa0 100644
--- a/desktop/gui.h
+++ b/desktop/gui.h
@@ -25,6 +25,11 @@ typedef enum { GUI_POINTER_DEFAULT, GUI_POINTER_POINT, GUI_POINTER_CARET,
#include "netsurf/content/content.h"
#include "netsurf/desktop/browser.h"
+void gui_init(int argc, char** argv);
+void gui_multitask(void);
+void gui_poll(bool active);
+void gui_quit(void);
+
struct gui_window *gui_create_browser_window(struct browser_window *bw,
struct browser_window *clone);
void gui_window_destroy(struct gui_window *g);
@@ -39,6 +44,10 @@ void gui_window_set_extent(struct gui_window *g, int width, int height);
void gui_window_set_status(struct gui_window *g, const char *text);
void gui_window_set_pointer(gui_pointer_shape shape);
void gui_window_set_url(struct gui_window *g, const char *url);
+void gui_window_start_throbber(struct gui_window *g);
+void gui_window_stop_throbber(struct gui_window *g);
+void gui_window_place_caret(struct gui_window *g, int x, int y, int height);
+void gui_window_new_content(struct gui_window *g);
struct gui_download_window *gui_download_window_create(const char *url,
const char *mime_type, struct fetch *fetch,
@@ -49,20 +58,9 @@ void gui_download_window_error(struct gui_download_window *dw,
const char *error_msg);
void gui_download_window_done(struct gui_download_window *dw);
-void gui_init(int argc, char** argv);
-void gui_multitask(void);
-void gui_poll(bool active);
-void gui_quit(void);
-
-void gui_window_start_throbber(struct gui_window *g);
-void gui_window_stop_throbber(struct gui_window *g);
-
-void gui_gadget_combo(struct browser_window* bw, struct form_control* g, unsigned long mx, unsigned long my);
-
-void gui_window_place_caret(struct gui_window *g, int x, int y, int height);
+void gui_create_form_select_menu(struct browser_window *bw,
+ struct form_control *control);
void gui_launch_url(const char *url);
-void gui_window_new_content(struct gui_window *g);
-
#endif
diff --git a/render/box.c b/render/box.c
index 29d2bfdb6..ef3b60283 100644
--- a/render/box.c
+++ b/render/box.c
@@ -2454,32 +2454,6 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
}
-/**
- * Find the absolute coordinates of a box.
- *
- * \param box the box to calculate coordinates of
- * \param x updated to x coordinate
- * \param y updated to y coordinate
- */
-
-void box_coords(struct box *box, int *x, int *y)
-{
- *x = box->x;
- *y = box->y;
- while (box->parent) {
- if (box->type == BOX_FLOAT_LEFT ||
- box->type == BOX_FLOAT_RIGHT) {
- do {
- box = box->parent;
- } while (!box->float_children);
- } else
- box = box->parent;
- *x += box->x;
- *y += box->y;
- }
-}
-
-
struct box_result box_frameset(xmlNode *n, struct box_status *status,
struct css_style *style)
{
@@ -2709,3 +2683,105 @@ struct box_multi_length *box_parse_multi_lengths(const char *s,
*count = n;
return length;
}
+
+
+/**
+ * Find the absolute coordinates of a box.
+ *
+ * \param box the box to calculate coordinates of
+ * \param x updated to x coordinate
+ * \param y updated to y coordinate
+ */
+
+void box_coords(struct box *box, int *x, int *y)
+{
+ *x = box->x;
+ *y = box->y;
+ while (box->parent) {
+ if (box->type == BOX_FLOAT_LEFT ||
+ box->type == BOX_FLOAT_RIGHT) {
+ do {
+ box = box->parent;
+ } while (!box->float_children);
+ } else
+ box = box->parent;
+ *x += box->x;
+ *y += box->y;
+ }
+}
+
+
+/**
+ * Find the boxes at a point.
+ *
+ * \param box box to search children of
+ * \param x point to find, in global document coordinates
+ * \param y point to find, in global document coordinates
+ * \param box_x position of box, in global document coordinates, updated
+ * to position of returned box, if any
+ * \param box_y position of box, in global document coordinates, updated
+ * to position of returned box, if any
+ * \param content updated to content of object that returned box is in, if any
+ * \return box at given point, or 0 if none found
+ *
+ * To find all the boxes in the heirarchy at a certain point, use code like
+ * this:
+ * \code
+ * struct box *box = top_of_document_to_search;
+ * int box_x = 0, box_y = 0;
+ * struct content *content = document_to_search;
+ *
+ * while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
+ * // process box
+ * }
+ * \endcode
+ */
+
+struct box *box_at_point(struct box *box, int x, int y,
+ int *box_x, int *box_y,
+ struct content **content)
+{
+ struct box *child;
+
+ assert(box);
+
+ /* drill into HTML objects */
+ if (box->object) {
+ if (box->object->type == CONTENT_HTML &&
+ box->object->data.html.layout) {
+ *content = box->object;
+ box = box->object->data.html.layout;
+ } else {
+ return 0;
+ }
+ }
+
+ /* consider floats first, since they will often overlap other boxes */
+ for (child = box->float_children; child; child = child->next_float) {
+ if (*box_x + child->x <= x &&
+ x < *box_x + child->x + child->width &&
+ *box_y + child->y <= y &&
+ y < *box_y + child->y + child->height) {
+ *box_x += child->x;
+ *box_y += child->y;
+ return child;
+ }
+ }
+
+ /* non-float children */
+ for (child = box->children; child; child = child->next) {
+ if (child->type == BOX_FLOAT_LEFT ||
+ child->type == BOX_FLOAT_RIGHT)
+ continue;
+ if (*box_x + child->x <= x &&
+ x < *box_x + child->x + child->width &&
+ *box_y + child->y <= y &&
+ y < *box_y + child->y + child->height) {
+ *box_x += child->x;
+ *box_y += child->y;
+ return child;
+ }
+ }
+
+ return 0;
+}
diff --git a/render/box.h b/render/box.h
index 815a5fcf8..d97406352 100644
--- a/render/box.h
+++ b/render/box.h
@@ -248,5 +248,8 @@ void box_add_child(struct box * parent, struct box * child);
void box_insert_sibling(struct box *box, struct box *new_box);
void box_free(struct box *box);
void box_coords(struct box *box, int *x, int *y);
+struct box *box_at_point(struct box *box, int x, int y,
+ int *box_x, int *box_y,
+ struct content **content);
#endif
diff --git a/riscos/gui.c b/riscos/gui.c
index c629da12b..f3a05f9ae 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -35,7 +35,6 @@
#include "netsurf/desktop/netsurf.h"
#include "netsurf/desktop/options.h"
#include "netsurf/render/font.h"
-#include "netsurf/render/form.h"
#include "netsurf/render/html.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/help.h"
@@ -62,8 +61,6 @@ const char *__dynamic_da_name = "NetSurf"; /**< For UnixLib. */
int __feature_imagefs_is_file = 1; /**< For UnixLib. */
char *NETSURF_DIR;
-wimp_menu *combo_menu;
-struct form_control *current_gadget;
/** The pointer is over a window which is tracking mouse movement. */
static bool gui_track = false;
@@ -958,53 +955,6 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message)
}
-void gui_gadget_combo(struct browser_window* bw, struct form_control* g, unsigned long mx, unsigned long my)
-{
- int count;
- struct form_option* o;
- wimp_pointer pointer;
-
- if (combo_menu != NULL)
- xfree(combo_menu);
-
- for (count = 0, o = g->data.select.items; o != NULL; ++count, o = o->next)
- /* no body */;
-
- combo_menu = xcalloc(1, wimp_SIZEOF_MENU(count));
-
- combo_menu->title_data.indirected_text.text =
- messages_get("SelectMenu");
- combo_menu->title_fg = wimp_COLOUR_BLACK;
- combo_menu->title_bg = wimp_COLOUR_LIGHT_GREY;
- combo_menu->work_fg = wimp_COLOUR_BLACK;
- combo_menu->work_bg = wimp_COLOUR_WHITE;
- combo_menu->width = 0;
- combo_menu->height = wimp_MENU_ITEM_HEIGHT;
- combo_menu->gap = wimp_MENU_ITEM_GAP;
-
- for (count = 0, o = g->data.select.items; o != NULL; ++count, o = o->next) {
- combo_menu->entries[count].menu_flags = 0;
- if (count == 0)
- combo_menu->entries[count].menu_flags = wimp_MENU_TITLE_INDIRECTED;
- if (o->selected)
- combo_menu->entries[count].menu_flags |= wimp_MENU_TICKED;
- if (o->next == NULL)
- combo_menu->entries[count].menu_flags |= wimp_MENU_LAST;
-
- combo_menu->entries[count].sub_menu = wimp_NO_SUB_MENU;
- combo_menu->entries[count].icon_flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | wimp_ICON_FILLED | wimp_ICON_VCENTRED | (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT) | (wimp_BUTTON_MENU_ICON << wimp_ICON_BUTTON_TYPE_SHIFT);
- /* \todo combo_menu->entries[count].data.indirected_text.text needs to be free() when menu gets closed. */
- combo_menu->entries[count].data.indirected_text.text = cnv_str_local_enc(o->text);
- combo_menu->entries[count].data.indirected_text.validation = "\0";
- combo_menu->entries[count].data.indirected_text.size = strlen(combo_menu->entries[count].data.indirected_text.text) + 1;
- }
-
- wimp_get_pointer_info(&pointer);
- current_gadget = g;
- ro_gui_create_menu(combo_menu, pointer.pos.x - 64, pointer.pos.y, bw->window);
-}
-
-
/**
* Handle Message_DataLoad (file dragged in).
*/
diff --git a/riscos/menus.c b/riscos/menus.c
index 4211642c2..5039d973a 100644
--- a/riscos/menus.c
+++ b/riscos/menus.c
@@ -18,6 +18,7 @@
#include "oslib/wimp.h"
#include "oslib/wimpspriteop.h"
#include "netsurf/desktop/gui.h"
+#include "netsurf/render/form.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/help.h"
#include "netsurf/riscos/options.h"
@@ -57,6 +58,12 @@ struct gui_window *current_gui;
wimp_menu *current_menu;
static int current_menu_x, current_menu_y;
+/** Menu of options for form select controls. */
+static wimp_menu *gui_form_select_menu = 0;
+/** Form control which gui_form_select_menu is for. */
+static struct form_control *gui_form_select_control;
+
+
/* Default menu item flags
*/
#define DEFAULT_FLAGS (wimp_ICON_TEXT | wimp_ICON_FILLED | \
@@ -512,18 +519,16 @@ void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i)
void ro_gui_menu_selection(wimp_selection *selection)
{
- struct browser_action msg;
wimp_pointer pointer;
wimp_window_state state;
os_error *error;
wimp_get_pointer_info(&pointer);
- if (current_menu == combo_menu && selection->items[0] >= 0) {
- msg.type = act_GADGET_SELECT;
- msg.data.gadget_select.g = current_gadget;
- msg.data.gadget_select.item = selection->items[0];
- browser_window_action(current_gui->bw, &msg);
+ if (current_menu == gui_form_select_menu && 0 <= selection->items[0]) {
+ browser_window_form_select(current_gui->bw,
+ gui_form_select_control,
+ selection->items[0]);
} else if (current_menu == iconbar_menu) {
switch (selection->items[0]) {
@@ -655,8 +660,6 @@ void ro_gui_menu_selection(wimp_selection *selection)
case 1: /* Select all */
break;
case 2: /* Clear */
- msg.type = act_CLEAR_SELECTION;
- browser_window_action(current_gui->bw, &msg);
break;
}
break;
@@ -807,10 +810,13 @@ void ro_gui_menu_selection(wimp_selection *selection)
}
if (pointer.buttons == wimp_CLICK_ADJUST) {
- if (current_menu == combo_menu)
- gui_gadget_combo(current_gui->bw, current_gadget, (unsigned int)current_menu_x, (unsigned int)current_menu_y);
+ if (current_menu == gui_form_select_menu)
+ gui_create_form_select_menu(current_gui->bw,
+ gui_form_select_control);
else
- ro_gui_create_menu(current_menu, current_menu_x, current_menu_y, current_gui);
+ ro_gui_create_menu(current_menu,
+ current_menu_x, current_menu_y,
+ current_gui);
} else {
if (current_menu == hotlist_menu) {
ro_gui_hotlist_menu_closed();
@@ -1458,3 +1464,92 @@ void ro_gui_menu_object_reload(void)
}
}
+
+/**
+ * Display a menu of options for a form select control.
+ *
+ * \param bw browser window containing form control
+ * \param control form control of type GADGET_SELECT
+ */
+
+void gui_create_form_select_menu(struct browser_window *bw,
+ struct form_control *control)
+{
+ unsigned int i = 0, j;
+ struct form_option *option;
+ wimp_pointer pointer;
+ os_error *error;
+
+ for (option = control->data.select.items; option; option = option->next)
+ i++;
+
+ if (i == 0)
+ return;
+
+ if (gui_form_select_menu) {
+ for (j = 0; ; j++) {
+ free(gui_form_select_menu->entries[j].data.
+ indirected_text.text);
+ if (gui_form_select_menu->entries[j].menu_flags &
+ wimp_MENU_LAST)
+ break;
+ }
+ free(gui_form_select_menu);
+ gui_form_select_menu = 0;
+ }
+
+ gui_form_select_menu = malloc(wimp_SIZEOF_MENU(i));
+ if (!gui_form_select_menu) {
+ warn_user("NoMemory", 0);
+ return;
+ }
+
+ gui_form_select_menu->title_data.indirected_text.text =
+ messages_get("SelectMenu");
+ gui_form_select_menu->title_fg = wimp_COLOUR_BLACK;
+ gui_form_select_menu->title_bg = wimp_COLOUR_LIGHT_GREY;
+ gui_form_select_menu->work_fg = wimp_COLOUR_BLACK;
+ gui_form_select_menu->work_bg = wimp_COLOUR_WHITE;
+ gui_form_select_menu->width = 200;
+ gui_form_select_menu->height = wimp_MENU_ITEM_HEIGHT;
+ gui_form_select_menu->gap = wimp_MENU_ITEM_GAP;
+
+ for (i = 0, option = control->data.select.items; option;
+ i++, option = option->next) {
+ gui_form_select_menu->entries[i].menu_flags = 0;
+ if (option->selected)
+ gui_form_select_menu->entries[i].menu_flags =
+ wimp_MENU_TICKED;
+ gui_form_select_menu->entries[i].sub_menu = wimp_NO_SUB_MENU;
+ gui_form_select_menu->entries[i].icon_flags = wimp_ICON_TEXT |
+ wimp_ICON_INDIRECTED | wimp_ICON_FILLED |
+ (wimp_COLOUR_BLACK <<
+ wimp_ICON_FG_COLOUR_SHIFT) |
+ (wimp_COLOUR_WHITE <<
+ wimp_ICON_BG_COLOUR_SHIFT);
+ /* \todo can cnv_str_local_enc() fail? */
+ gui_form_select_menu->entries[i].data.indirected_text.text =
+ cnv_str_local_enc(option->text);
+ gui_form_select_menu->entries[i].data.indirected_text.
+ validation = "\0";
+ gui_form_select_menu->entries[i].data.indirected_text.size =
+ strlen(gui_form_select_menu->entries[i].
+ data.indirected_text.text) + 1;
+ }
+
+ gui_form_select_menu->entries[0].menu_flags |=
+ wimp_MENU_TITLE_INDIRECTED;
+ gui_form_select_menu->entries[i - 1].menu_flags |= wimp_MENU_LAST;
+
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG(("xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+
+ current_gui = bw->window;
+ gui_form_select_control = control;
+ ro_gui_create_menu(gui_form_select_menu,
+ pointer.pos.x - 64, pointer.pos.y, bw->window);
+}
diff --git a/riscos/textselection.c b/riscos/textselection.c
index 34be842d7..7129fd2ac 100644
--- a/riscos/textselection.c
+++ b/riscos/textselection.c
@@ -35,7 +35,7 @@ void ro_gui_start_selection(wimp_pointer *pointer, wimp_window_state *state,
void ro_gui_selection_drag_end(wimp_dragged *drag)
{
- struct browser_action msg;
+/* struct browser_action msg; */
int final_x0, final_y0;
wimp_window_state state;
@@ -45,16 +45,16 @@ void ro_gui_selection_drag_end(wimp_dragged *drag)
final_x0 = window_x_units(drag->final.x0, &state) / 2;
final_y0 = window_y_units(drag->final.y0, &state) / 2;
- msg.data.mouse.x = final_x0;
+/* msg.data.mouse.x = final_x0;
msg.data.mouse.y = final_y0;
msg.type = act_ALTER_SELECTION;
- browser_window_action(current_gui->bw, &msg);
+ browser_window_action(current_gui->bw, &msg);*/
if (box_position_eq(&(current_gui->bw->current_content->data.html.text_selection.start),
&(current_gui->bw->current_content->data.html.text_selection.end)))
{
- msg.type = act_CLEAR_SELECTION;
- browser_window_action(current_gui->bw, &msg);
+/* msg.type = act_CLEAR_SELECTION;
+ browser_window_action(current_gui->bw, &msg);*/
}
current_gui->bw->current_content->data.html.text_selection.altering = alter_UNKNOWN;
}
diff --git a/riscos/window.c b/riscos/window.c
index 2c86918d1..01de4839d 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -908,14 +908,7 @@ void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer)
x = window_x_units(pointer->pos.x, &state) / 2 / g->option.scale;
y = -window_y_units(pointer->pos.y, &state) / 2 / g->option.scale;
- if (g->bw->current_content != NULL)
- {
- struct browser_action msg;
- msg.type = act_MOUSE_AT;
- msg.data.mouse.x = x;
- msg.data.mouse.y = y;
- browser_window_action(g->bw, &msg);
- }
+ browser_window_mouse_click(g->bw, BROWSER_MOUSE_HOVER, x, y);
}
@@ -1034,7 +1027,6 @@ void ro_gui_status_click(struct gui_window *g, wimp_pointer *pointer)
void ro_gui_window_click(struct gui_window *g, wimp_pointer *pointer)
{
- struct browser_action msg;
int x, y;
wimp_window_state state;
os_error *error;
@@ -1066,33 +1058,13 @@ void ro_gui_window_click(struct gui_window *g, wimp_pointer *pointer)
}
}
- if (pointer->buttons == wimp_CLICK_MENU) {
+ if (pointer->buttons == wimp_CLICK_MENU)
ro_gui_create_menu(browser_menu, pointer->pos.x - 64,
pointer->pos.y, g);
- return;
- }
-
- if (pointer->buttons == wimp_CLICK_SELECT) {
- msg.type = act_MOUSE_CLICK;
- msg.data.mouse.x = x;
- msg.data.mouse.y = y;
- if (browser_window_action(
- g->bw, &msg) == 1)
- return;
- msg.type = act_UNKNOWN;
- }
-
- if (pointer->buttons == wimp_CLICK_SELECT
- || pointer->buttons == wimp_CLICK_ADJUST) {
-
- if (pointer->buttons == wimp_CLICK_SELECT)
- msg.type = act_FOLLOW_LINK;
- else
- msg.type = act_FOLLOW_LINK_NEW_WINDOW;
- msg.data.mouse.x = x;
- msg.data.mouse.y = y;
- browser_window_action(g->bw, &msg);
- }
+ else if (pointer->buttons == wimp_CLICK_SELECT)
+ browser_window_mouse_click(g->bw, BROWSER_MOUSE_CLICK_1, x, y);
+ else if (pointer->buttons == wimp_CLICK_ADJUST)
+ browser_window_mouse_click(g->bw, BROWSER_MOUSE_CLICK_2, x, y);
}