diff options
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/Makefile | 2 | ||||
-rw-r--r-- | desktop/browser.c | 92 | ||||
-rw-r--r-- | desktop/download.c | 9 | ||||
-rw-r--r-- | desktop/gui.h | 408 | ||||
-rw-r--r-- | desktop/gui_factory.c | 440 | ||||
-rw-r--r-- | desktop/gui_factory.h (renamed from desktop/401login.h) | 26 | ||||
-rw-r--r-- | desktop/netsurf.c | 18 | ||||
-rw-r--r-- | desktop/netsurf.h | 4 | ||||
-rw-r--r-- | desktop/save_complete.c | 7 | ||||
-rw-r--r-- | desktop/searchweb.c | 3 | ||||
-rw-r--r-- | desktop/selection.c | 9 | ||||
-rw-r--r-- | desktop/textarea.c | 6 | ||||
-rw-r--r-- | desktop/textinput.c | 8 |
13 files changed, 855 insertions, 177 deletions
diff --git a/desktop/Makefile b/desktop/Makefile index f7020074e..0e2e460de 100644 --- a/desktop/Makefile +++ b/desktop/Makefile @@ -13,7 +13,7 @@ desktop/version.c: testament utils/testament.h # S_BROWSER are sources related to full browsers but are common # between RISC OS, GTK, BeOS and AmigaOS builds S_BROWSER := browser.c download.c frames.c local_history.c netsurf.c \ - save_complete.c save_text.c selection.c textinput.c + save_complete.c save_text.c selection.c textinput.c gui_factory.c S_BROWSER := $(addprefix desktop/,$(S_BROWSER)) diff --git a/desktop/browser.c b/desktop/browser.c index 6ec31d22f..f66e27576 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -41,12 +41,12 @@ #include "content/fetch.h" #include "content/hlcache.h" #include "content/urldb.h" -#include "desktop/401login.h" #include "desktop/browser_private.h" #include "desktop/download.h" #include "desktop/frames.h" #include "desktop/global_history.h" #include "desktop/gui.h" +#include "desktop/gui_factory.h" #include "desktop/hotlist.h" #include "desktop/knockout.h" #include "desktop/local_history.h" @@ -300,7 +300,7 @@ void browser_window_update_extent(struct browser_window *bw) { if (bw->window != NULL) /* Front end window */ - gui_window_update_extent(bw->window); + guit->window->update_extent(bw->window); else /* Core-managed browser window */ browser_window_handle_scrollbars(bw); @@ -391,7 +391,7 @@ void browser_window_set_drag_type(struct browser_window *bw, break; } - gui_window_drag_start(top_bw->window, gtype, rect); + guit->window->drag_start(top_bw->window, gtype, rect); } } @@ -484,7 +484,7 @@ void browser_window_scroll_visible(struct browser_window *bw, if (bw->window != NULL) { /* Front end window */ - gui_window_scroll_visible(bw->window, + guit->window->scroll_visible(bw->window, rect->x0, rect->y0, rect->x1, rect->y1); } else { /* Core managed browser window */ @@ -499,7 +499,7 @@ void browser_window_scroll_visible(struct browser_window *bw, void browser_window_set_scroll(struct browser_window *bw, int x, int y) { if (bw->window != NULL) { - gui_window_set_scroll(bw->window, x, y); + guit->window->set_scroll(bw->window, x, y); } else { if (bw->scroll_x != NULL) scrollbar_set(bw->scroll_x, x, false); @@ -732,9 +732,7 @@ browser_window_create(enum browser_window_nav_flags flags, * so find that. */ top = browser_window_get_root(clone); - bw->window = gui_create_browser_window(bw, - top, - ((flags & BROWSER_WINDOW_TAB) != 0)); + bw->window = guit->window->create(bw, top, ((flags & BROWSER_WINDOW_TAB) != 0)); if (bw->window == NULL) { browser_window_destroy(bw); @@ -815,7 +813,7 @@ browser_window_download(struct browser_window *bw, NULL, NULL, &l); if (error == NSERROR_NO_FETCH_HANDLER) { /* no internal handler for this type, call out to frontend */ - gui_launch_url(nsurl_access(url)); + guit->browser->launch_url(nsurl_access(url)); } else if (error != NSERROR_OK) { LOG(("Failed to fetch download: %d", error)); } else { @@ -868,7 +866,7 @@ static void browser_window_start_throbber(struct browser_window *bw) while (bw->parent) bw = bw->parent; - gui_window_start_throbber(bw->window); + guit->window->start_throbber(bw->window); } @@ -885,8 +883,9 @@ static void browser_window_stop_throbber(struct browser_window *bw) while (bw->parent) bw = bw->parent; - if (!browser_window_check_throbber(bw)) - gui_window_stop_throbber(bw->window); + if (!browser_window_check_throbber(bw)) { + guit->window->stop_throbber(bw->window); + } } @@ -919,7 +918,7 @@ static nserror browser_window_favicon_callback(hlcache_handle *c, /* content_get_bitmap on the hlcache_handle should give * us the favicon bitmap at this point */ - gui_window_set_icon(bw->window, c); + guit->window->set_icon(bw->window, c); break; case CONTENT_MSG_ERROR: @@ -1234,7 +1233,7 @@ static nserror browser_window_callback(hlcache_handle *c, browser_window_remove_caret(bw, false); if (bw->window != NULL) { - gui_window_new_content(bw->window); + guit->window->new_content(bw->window); browser_window_refresh_url_bar(bw, hlcache_handle_get_url(bw->current_content), @@ -1485,20 +1484,23 @@ static nserror browser_window_callback(hlcache_handle *c, switch(event->data.dragsave.type) { case CONTENT_SAVE_ORIG: - gui_drag_save_object(GUI_SAVE_OBJECT_ORIG, save, - root->window); + guit->window->drag_save_object(root->window, save, + GUI_SAVE_OBJECT_ORIG); break; + case CONTENT_SAVE_NATIVE: - gui_drag_save_object(GUI_SAVE_OBJECT_NATIVE, save, - root->window); + guit->window->drag_save_object(root->window, save, + GUI_SAVE_OBJECT_NATIVE); break; + case CONTENT_SAVE_COMPLETE: - gui_drag_save_object(GUI_SAVE_COMPLETE, save, - root->window); + guit->window->drag_save_object(root->window, save, + GUI_SAVE_COMPLETE); break; + case CONTENT_SAVE_SOURCE: - gui_drag_save_object(GUI_SAVE_SOURCE, save, - root->window); + guit->window->drag_save_object(root->window, save, + GUI_SAVE_SOURCE); break; } } @@ -1508,7 +1510,7 @@ static nserror browser_window_callback(hlcache_handle *c, { /* Content wants a link to be saved */ struct browser_window *root = browser_window_get_root(bw); - gui_window_save_link(root->window, + guit->window->save_link(root->window, event->data.savelink.url, event->data.savelink.title); } @@ -1564,7 +1566,7 @@ static nserror browser_window_callback(hlcache_handle *c, case CONTENT_MSG_GADGETCLICK: if (event->data.gadget_click.gadget->type == GADGET_FILE) { - gui_file_gadget_open(bw->window, c, + guit->window->file_gadget_open(bw->window, c, event->data.gadget_click.gadget); } @@ -1644,7 +1646,7 @@ void browser_window_destroy_internal(struct browser_window *bw) if (bw->window) { /* Only the root window has a GUI window */ - gui_window_destroy(bw->window); + guit->window->destroy(bw->window); } if (bw->loading_content != NULL) { @@ -1870,7 +1872,7 @@ nserror browser_window_navigate(struct browser_window *bw, case NSERROR_NO_FETCH_HANDLER: /* no handler for this type */ /** @todo does this always try and download even unverifiable content? */ - gui_launch_url(nsurl_access(url)); + guit->browser->launch_url(nsurl_access(url)); break; default: /* report error to user */ @@ -1913,7 +1915,7 @@ void browser_window_get_dimensions(struct browser_window *bw, *height = bw->height; } else { /* Front end window */ - gui_window_get_dimensions(bw->window, width, height, scaled); + guit->window->get_dimensions(bw->window, width, height, scaled); } } @@ -1960,7 +1962,7 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top) case BROWSER_WINDOW_NORMAL: /* Root browser window, constituting a front end window/tab */ - gui_window_set_title(bw->window, + guit->window->set_title(bw->window, content_get_title(bw->current_content)); browser_window_update_extent(bw); @@ -1975,7 +1977,7 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top) browser_window_set_scroll(bw, x, y); } - gui_window_redraw_window(bw->window); + guit->window->redraw(bw->window); break; @@ -2041,7 +2043,7 @@ void browser_window_update_box(struct browser_window *bw, struct rect *rect) if (bw->window != NULL) { /* Front end window */ - gui_window_update_box(bw->window, rect); + guit->window->update(bw->window, rect); } else { /* Core managed browser window */ browser_window_get_position(bw, true, &pos_x, &pos_y); @@ -2053,7 +2055,7 @@ void browser_window_update_box(struct browser_window *bw, struct rect *rect) rect->x1 += pos_x / bw->scale; rect->y1 += pos_y / bw->scale; - gui_window_update_box(top->window, rect); + guit->window->update(top->window, rect); } } @@ -2194,7 +2196,7 @@ void browser_window_set_status(struct browser_window *bw, const char *text) } bw->status_miss++; - gui_window_set_status(bw->window, bw->status_text); + guit->window->set_status(bw->window, bw->status_text); } @@ -2236,7 +2238,7 @@ void browser_window_set_pointer(struct browser_window *bw, gui_shape = (gui_pointer_shape)shape; } - gui_window_set_pointer(root->window, gui_shape); + guit->window->set_pointer(root->window, gui_shape); } @@ -2360,7 +2362,7 @@ void browser_window_refresh_url_bar(struct browser_window *bw, nsurl *url, /* With no fragment, we may as well pass url straight through * saving a malloc, copy, free cycle. */ - gui_window_set_url(bw->window, nsurl_access(url)); + guit->window->set_url(bw->window, nsurl_access(url)); } else { nsurl *display_url; nserror error; @@ -2371,7 +2373,7 @@ void browser_window_refresh_url_bar(struct browser_window *bw, nsurl *url, return; } - gui_window_set_url(bw->window, nsurl_access(display_url)); + guit->window->set_url(bw->window, nsurl_access(display_url)); nsurl_unref(display_url); } } @@ -2894,14 +2896,14 @@ void browser_window_mouse_click(struct browser_window *bw, break; default: if (mouse & BROWSER_MOUSE_MOD_2) { - if (mouse & BROWSER_MOUSE_DRAG_2) - gui_drag_save_object(GUI_SAVE_OBJECT_NATIVE, c, - bw->window); - else if (mouse & BROWSER_MOUSE_DRAG_1) - gui_drag_save_object(GUI_SAVE_OBJECT_ORIG, c, - bw->window); - } - else if (mouse & (BROWSER_MOUSE_DRAG_1 | + if (mouse & BROWSER_MOUSE_DRAG_2) { + guit->window->drag_save_object(bw->window, c, + GUI_SAVE_OBJECT_NATIVE); + } else if (mouse & BROWSER_MOUSE_DRAG_1) { + guit->window->drag_save_object(bw->window, c, + GUI_SAVE_OBJECT_ORIG); + } + } else if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) { browser_window_page_drag_start(bw, x, y); browser_window_set_pointer(bw, BROWSER_POINTER_MOVE); @@ -2947,10 +2949,10 @@ void browser_window_page_drag_start(struct browser_window *bw, int x, int y) if (bw->window != NULL) { /* Front end window */ - gui_window_get_scroll(bw->window, &bw->drag_start_scroll_x, + guit->window->get_scroll(bw->window, &bw->drag_start_scroll_x, &bw->drag_start_scroll_y); - gui_window_scroll_start(bw->window); + guit->window->scroll_start(bw->window); } else { /* Core managed browser window */ bw->drag_start_scroll_x = scrollbar_get_offset(bw->scroll_x); diff --git a/desktop/download.c b/desktop/download.c index b775eb18e..14390c78a 100644 --- a/desktop/download.c +++ b/desktop/download.c @@ -27,6 +27,7 @@ #include "content/llcache.h" #include "desktop/download.h" #include "desktop/gui.h" +#include "desktop/gui_factory.h" #include "utils/http.h" #include "utils/url.h" #include "utils/utils.h" @@ -160,7 +161,7 @@ static nserror download_context_process_headers(download_context *ctx) } /* Create the frontend window */ - ctx->window = gui_download_window_create(ctx, ctx->parent); + ctx->window = guit->download->create(ctx, ctx->parent); if (ctx->window == NULL) { free(ctx->filename); ctx->filename = NULL; @@ -210,7 +211,7 @@ static nserror download_callback(llcache_handle *handle, if (error == NSERROR_OK) { /** \todo Lose ugly cast */ - error = gui_download_window_data(ctx->window, + error = guit->download->data(ctx->window, (char *) event->data.data.buf, event->data.data.len); if (error != NSERROR_OK) @@ -222,7 +223,7 @@ static nserror download_callback(llcache_handle *handle, case LLCACHE_EVENT_DONE: /* There may be no associated window if there was no data or headers */ if (ctx->window != NULL) - gui_download_window_done(ctx->window); + guit->download->done(ctx->window); else download_context_destroy(ctx); @@ -230,7 +231,7 @@ static nserror download_callback(llcache_handle *handle, case LLCACHE_EVENT_ERROR: if (ctx->window != NULL) - gui_download_window_error(ctx->window, event->data.msg); + guit->download->error(ctx->window, event->data.msg); else download_context_destroy(ctx); diff --git a/desktop/gui.h b/desktop/gui.h index 9317e8576..5252737f9 100644 --- a/desktop/gui.h +++ b/desktop/gui.h @@ -1,6 +1,5 @@ /* - * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net> - * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -24,6 +23,12 @@ #ifndef _NETSURF_DESKTOP_GUI_H_ #define _NETSURF_DESKTOP_GUI_H_ +#include <stdbool.h> + +#include "content/hlcache.h" +#include "desktop/download.h" +#include "utils/errors.h" + typedef enum { GUI_SAVE_SOURCE, GUI_SAVE_DRAW, @@ -52,121 +57,330 @@ struct gui_window; struct gui_download_window; struct browser_window; struct form_control; +struct ssl_cert_info; -#include <stdbool.h> +typedef struct nsnsclipboard_styles { + size_t start; /**< Start of run */ -#include <libwapcaplet/libwapcaplet.h> -#include <libcss/libcss.h> + plot_font_style_t style; /**< Style to give text run */ +} nsclipboard_styles; -#include "utils/config.h" -#include "content/hlcache.h" -#include "desktop/download.h" -#include "desktop/mouse.h" -#include "desktop/search.h" -#include "utils/errors.h" +/** Graphical user interface window function table + * + * function table implementing window operations + */ +struct gui_window_table { + + /* Mandantory entries */ + + /** create a gui window for a browsing context */ + struct gui_window *(*create)(struct browser_window *bw, struct browser_window *clone, bool new_tab); + + /** destroy previously created gui window */ + void (*destroy)(struct gui_window *g); + + /** + * Force a redraw of the entire contents of a window. + * + * @todo this API should be merged with update. + * + * \param g gui_window to redraw + */ + void (*redraw)(struct gui_window *g); + + /** + * Redraw an area of a window. + * + * \param g gui_window + * \param rect area to redraw + */ + void (*update)(struct gui_window *g, const struct rect *rect); + + /** + * Get the scroll position of a browser window. + * + * \param g gui_window + * \param sx receives x ordinate of point at top-left of window + * \param sy receives y ordinate of point at top-left of window + * \return true iff successful + */ + bool (*get_scroll)(struct gui_window *g, int *sx, int *sy); + + /** + * Set the scroll position of a browser window. + * + * \param g gui_window to scroll + * \param sx point to place at top-left of window + * \param sy point to place at top-left of window + */ + void (*set_scroll)(struct gui_window *g, int sx, int sy); + + /** + * Find the current dimensions of a browser window's content area. + * + * @todo The implementations of this are buggy and its only + * used from frames code. + * + * \param g gui_window to measure + * \param width receives width of window + * \param height receives height of window + * \param scaled whether to return scaled values + */ + void (*get_dimensions)(struct gui_window *g, int *width, int *height, bool scaled); + + /** + * Update the extent of the inside of a browser window to that of the + * current content. + * + * @todo this is used to update scroll bars does it need + * renaming? some frontends (windows) do not even implement it. + * + * \param g gui_window to update the extent of + */ + void (*update_extent)(struct gui_window *g); + + + + /* Optional entries */ + + /** + * Set the title of a window. + * + * \param g window to update + * \param title new window title + */ + void (*set_title)(struct gui_window *g, const char *title); + + /** set the navigation url. */ + void (*set_url)(struct gui_window *g, const char *url); + + /** set favicon */ + void (*set_icon)(struct gui_window *g, hlcache_handle *icon); + + /** + * Set the status bar of a browser window. + * + * \param g gui_window to update + * \param text new status text + */ + void (*set_status)(struct gui_window *g, const char *text); + + /** + * Change mouse pointer shape + */ + void (*set_pointer)(struct gui_window *g, gui_pointer_shape shape); + + /** + * Place the caret in a browser window. + * + * \param g window with caret + * \param x coordinates of caret + * \param y coordinates of caret + * \param height height of caret + * \param clip clip rectangle, or NULL if none + */ + void (*place_caret)(struct gui_window *g, int x, int y, int height, const struct rect *clip); + + /** + * Remove the caret, if present. + * + * \param g window with caret + */ + void (*remove_caret)(struct gui_window *g); -void gui_poll(bool active); -void gui_quit(void); - -struct gui_window *gui_create_browser_window(struct browser_window *bw, - struct browser_window *clone, bool new_tab); -void gui_window_destroy(struct gui_window *g); -void gui_window_set_title(struct gui_window *g, const char *title); -void gui_window_redraw_window(struct gui_window *g); -void gui_window_update_box(struct gui_window *g, - const struct rect *rect); -bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy); -void gui_window_set_scroll(struct gui_window *g, int sx, int sy); -void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, - int x1, int y1); -void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, - bool scaled); -void gui_window_update_extent(struct gui_window *g); -void gui_window_set_status(struct gui_window *g, const char *text); -void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape); -void gui_window_hide_pointer(struct gui_window *g); -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_set_icon(struct gui_window *g, hlcache_handle *icon); -void gui_window_set_search_ico(hlcache_handle *ico); -void gui_window_place_caret(struct gui_window *g, int x, int y, int height, - const struct rect *clip); -void gui_window_remove_caret(struct gui_window *g); -void gui_window_new_content(struct gui_window *g); -bool gui_window_scroll_start(struct gui_window *g); - -bool gui_window_drag_start(struct gui_window *g, gui_drag_type type, - const struct rect *rect); - -void gui_window_save_link(struct gui_window *g, const char *url, - const char *title); - -struct gui_download_window *gui_download_window_create(download_context *ctx, - struct gui_window *parent); -nserror gui_download_window_data(struct gui_download_window *dw, - const char *data, unsigned int size); -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_drag_save_object(gui_save_type type, hlcache_handle *c, - struct gui_window *g); -void gui_drag_save_selection(struct gui_window *g, const char *selection); -void gui_start_selection(struct gui_window *g); -void gui_clear_selection(struct gui_window *g); - -void gui_file_gadget_open(struct gui_window *g, hlcache_handle *hl, - struct form_control *gadget); + /** start the navigation throbber. */ + void (*start_throbber)(struct gui_window *g); + + /** stop the navigation throbber. */ + void (*stop_throbber)(struct gui_window *g); + + /** start a drag operation within a window */ + bool (*drag_start)(struct gui_window *g, gui_drag_type type, const struct rect *rect); + + /** save link operation */ + void (*save_link)(struct gui_window *g, const char *url, const char *title); + + /** + * Scrolls the specified area of a browser window into view. + * + * @todo investigate if this can be merged with set_scroll + * which is what the default implementation used by most + * toolkits uses. + * + * \param g gui_window to scroll + * \param x0 left point to ensure visible + * \param y0 bottom point to ensure visible + * \param x1 right point to ensure visible + * \param y1 top point to ensure visible + */ + void (*scroll_visible)(struct gui_window *g, int x0, int y0, int x1, int y1); + + /** + * Starts drag scrolling of a browser window + * + * \param g the window to scroll + */ + bool (*scroll_start)(struct gui_window *g); + + /** + * Called when the gui_window has new content. + * + * \param g the gui_window that has new content + */ + void (*new_content)(struct gui_window *g); + + /** + * Called when file chooser gadget is activated + */ + void (*file_gadget_open)(struct gui_window *g, hlcache_handle *hl, struct form_control *gadget); + + /** object dragged to window*/ + void (*drag_save_object)(struct gui_window *g, hlcache_handle *c, gui_save_type type); + + /** drag selection save */ + void (*drag_save_selection)(struct gui_window *g, const char *selection); + + /** selection started */ + void (*start_selection)(struct gui_window *g); +}; /** - * Core asks front end for clipboard contents. - * - * \param buffer UTF-8 text, allocated by front end, ownership yeilded to core - * \param length Byte length of UTF-8 text in buffer + * function table for download windows */ -void gui_get_clipboard(char **buffer, size_t *length); +struct gui_download_table { + struct gui_download_window *(*create)(download_context *ctx, struct gui_window *parent); -typedef struct nsnsclipboard_styles { - size_t start; /**< Start of run */ + nserror (*data)(struct gui_download_window *dw, const char *data, unsigned int size); + + void (*error)(struct gui_download_window *dw, const char *error_msg); + + void (*done)(struct gui_download_window *dw); +}; - plot_font_style_t style; /**< Style to give text run */ -} nsclipboard_styles; /** - * Core tells front end to put given text in clipboard + * function table for clipboard operations + */ +struct gui_clipboard_table { + /** + * Core asks front end for clipboard contents. + * + * \param buffer UTF-8 text, allocated by front end, ownership yeilded to core + * \param length Byte length of UTF-8 text in buffer + */ + void (*get)(char **buffer, size_t *length); + + /** + * Core tells front end to put given text in clipboard + * + * \param buffer UTF-8 text, owned by core + * \param length Byte length of UTF-8 text in buffer + * \param styles Array of styles given to text runs, owned by core, or NULL + * \param n_styles Number of text run styles in array + */ + void (*set)(const char *buffer, size_t length, nsclipboard_styles styles[], int n_styles); +}; + +/** Graphical user interface browser misc function table * - * \param buffer UTF-8 text, owned by core - * \param length Byte length of UTF-8 text in buffer - * \param styles Array of styles given to text runs, owned by core, or NULL - * \param n_styles Number of text run styles in array + * function table implementing GUI interface to miscelaneous browser + * functionality */ -void gui_set_clipboard(const char *buffer, size_t length, - nsclipboard_styles styles[], int n_styles); +struct gui_browser_table { + /* Mandantory entries */ + /** + * called to let the frontend update its state and run any + * I/O operations. + */ + void (*poll)(bool active); + /** + * Return the filename part of a full path + * + * \param path full path and filename + * \return filename (will be freed with free()) + */ + char *(*filename_from_path)(char *path); -void gui_create_form_select_menu(struct browser_window *bw, - struct form_control *control); + /** + * Add a path component/filename to an existing path + * + * \param path buffer containing path + free space + * \param length length of buffer "path" + * \param newpart string containing path component to add to path + * \return true on success + */ + bool (*path_add_part)(char *path, int length, const char *newpart); -void gui_launch_url(const char *url); + /* Optional entries */ -struct ssl_cert_info; + /** called to allow the gui to cleanup */ + void (*quit)(void); -void gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs, - unsigned long num, nserror (*cb)(bool proceed, void *pw), - void *cbpw); + /** + * set gui display of a retrieved favicon representing the + * search provider + * + * \param ico may be NULL for local calls; then access current + * cache from search_web_ico() + */ + void (*set_search_ico)(hlcache_handle *ico); -/** - * Callback to translate resource to full url. - * - * Transforms a resource: path into a full URL. The returned URL - * is used as the target for a redirect. The caller takes ownership of - * the returned nsurl including unrefing it when finished with it. + /** + * Callback to translate resource to full url. + * + * Transforms a resource: path into a full URL. The returned URL + * is used as the target for a redirect. The caller takes ownership of + * the returned nsurl including unrefing it when finished with it. + * + * \param path The path of the resource to locate. + * \return A string containing the full URL of the target object or + * NULL if no suitable resource can be found. + */ + nsurl* (*get_resource_url)(const char *path); + + /** + * core has no fetcher for url + */ + void (*launch_url)(const char *url); + + /** + * create a form select menu + */ + void (*create_form_select_menu)(struct browser_window *bw, struct form_control *control); + + /** + * verify certificate + */ + void (*cert_verify)(nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw); + + /** + * Prompt user for login + */ + void (*login)(nsurl *url, const char *realm, + nserror (*cb)(bool proceed, void *pw), void *cbpw); + +}; + + +/** Graphical user interface function table * - * \param path The path of the resource to locate. - * \return A string containing the full URL of the target object or - * NULL if no suitable resource can be found. + * function table implementing GUI interface to browser core */ -nsurl* gui_get_resource_url(const char *path); +struct gui_table { + + /** Browser table */ + struct gui_browser_table *browser; + + /** Window table */ + struct gui_window_table *window; + + /** Download table */ + struct gui_download_table *download; + + /** Clipboard table */ + struct gui_clipboard_table *clipboard; +}; + #endif diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c new file mode 100644 index 000000000..104f4906d --- /dev/null +++ b/desktop/gui_factory.c @@ -0,0 +1,440 @@ +/* + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "desktop/gui.h" +#include "desktop/gui_factory.h" + +/** The global GUI interface table */ +struct gui_table *guit = NULL; + + + +static void gui_default_window_set_title(struct gui_window *g, const char *title) +{ +} + +static void gui_default_window_set_url(struct gui_window *g, const char *url) +{ +} + +static void gui_default_window_start_throbber(struct gui_window *g) +{ +} + +static void gui_default_window_stop_throbber(struct gui_window *g) +{ +} + +static bool gui_default_window_drag_start(struct gui_window *g, + gui_drag_type type, + const struct rect *rect) +{ + return true; +} + +static void gui_default_window_save_link(struct gui_window *g, + const char *url, + const char *title) +{ +} + +static void gui_default_window_set_icon(struct gui_window *g, + hlcache_handle *icon) +{ +} + +static void gui_default_window_scroll_visible(struct gui_window *g, + int x0, int y0, + int x1, int y1) +{ + guit->window->set_scroll(g, x0, y0); +} + +static void gui_default_window_new_content(struct gui_window *g) +{ +} + + +static bool gui_default_window_scroll_start(struct gui_window *g) +{ + return true; +} + +static void gui_default_window_set_pointer(struct gui_window *g, + gui_pointer_shape shape) +{ +} + +static void gui_default_window_set_status(struct gui_window *g, + const char *text) +{ +} + +static void gui_default_window_place_caret(struct gui_window *g, + int x, int y, int height, + const struct rect *clip) +{ +} + +static void gui_default_window_remove_caret(struct gui_window *g) +{ +} + +static void gui_default_window_file_gadget_open(struct gui_window *g, + hlcache_handle *hl, + struct form_control *gadget) +{ +} + +static void gui_default_window_drag_save_object(struct gui_window *g, + hlcache_handle *c, + gui_save_type type) +{ +} + +static void gui_default_window_drag_save_selection(struct gui_window *g, + const char *selection) +{ +} + +static void gui_default_window_start_selection(struct gui_window *g) +{ +} + + +/** verify window table is valid */ +static nserror verify_window_register(struct gui_window_table *gwt) +{ + /* check table is present */ + if (gwt == NULL) { + return NSERROR_BAD_PARAMETER; + } + + /* check the mandantory fields are set */ + if (gwt->create == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gwt->destroy == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gwt->redraw == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gwt->update == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gwt->get_scroll == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gwt->set_scroll == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gwt->get_dimensions == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gwt->update_extent == NULL) { + return NSERROR_BAD_PARAMETER; + } + + + /* fill in the optional entries with defaults */ + if (gwt->set_title == NULL) { + gwt->set_title = gui_default_window_set_title; + } + if (gwt->set_url == NULL) { + gwt->set_url = gui_default_window_set_url; + } + if (gwt->set_icon == NULL) { + gwt->set_icon = gui_default_window_set_icon; + } + if (gwt->set_status == NULL) { + gwt->set_status = gui_default_window_set_status; + } + if (gwt->set_pointer == NULL) { + gwt->set_pointer = gui_default_window_set_pointer; + } + if (gwt->place_caret == NULL) { + gwt->place_caret = gui_default_window_place_caret; + } + if (gwt->remove_caret == NULL) { + gwt->remove_caret = gui_default_window_remove_caret; + } + if (gwt->start_throbber == NULL) { + gwt->start_throbber = gui_default_window_start_throbber; + } + if (gwt->stop_throbber == NULL) { + gwt->stop_throbber = gui_default_window_stop_throbber; + } + if (gwt->drag_start == NULL) { + gwt->drag_start = gui_default_window_drag_start; + } + if (gwt->save_link == NULL) { + gwt->save_link = gui_default_window_save_link; + } + if (gwt->scroll_visible == NULL) { + gwt->scroll_visible = gui_default_window_scroll_visible; + } + if (gwt->new_content == NULL) { + gwt->new_content = gui_default_window_new_content; + } + if (gwt->scroll_start == NULL) { + gwt->scroll_start = gui_default_window_scroll_start; + } + if (gwt->file_gadget_open == NULL) { + gwt->file_gadget_open = gui_default_window_file_gadget_open; + } + if (gwt->drag_save_object == NULL) { + gwt->drag_save_object = gui_default_window_drag_save_object; + } + if (gwt->drag_save_selection == NULL) { + gwt->drag_save_selection = gui_default_window_drag_save_selection; + } + if (gwt->start_selection == NULL) { + gwt->start_selection = gui_default_window_start_selection; + } + + return NSERROR_OK; +} + + + +static struct gui_download_window * +gui_default_download_create(download_context *ctx, struct gui_window *parent) +{ + return NULL; +} + +static nserror gui_default_download_data(struct gui_download_window *dw, + const char *data, unsigned int size) +{ + return NSERROR_OK; +} + +static void gui_default_download_error(struct gui_download_window *dw, + const char *error_msg) +{ +} + +static void gui_default_download_done(struct gui_download_window *dw) +{ +} + + +/** verify download window table is valid */ +static nserror verify_download_register(struct gui_download_table *gdt) +{ + /* check table is present */ + if (gdt == NULL) { + return NSERROR_BAD_PARAMETER; + } + + /* all enties are mandantory */ + if (gdt->create == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gdt->data == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gdt->error == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gdt->done == NULL) { + return NSERROR_BAD_PARAMETER; + } + + return NSERROR_OK; +} + +static void gui_default_get_clipboard(char **buffer, size_t *length) +{ + *buffer = NULL; + *length = 0; +} + +static void gui_default_set_clipboard(const char *buffer, size_t length, + nsclipboard_styles styles[], int n_styles) +{ +} + +/** verify clipboard table is valid */ +static nserror verify_clipboard_register(struct gui_clipboard_table *gct) +{ + /* check table is present */ + if (gct == NULL) { + return NSERROR_BAD_PARAMETER; + } + + /* optional operations */ + if (gct->get == NULL) { + gct->get = gui_default_get_clipboard; + } + if (gct->set == NULL) { + gct->set = gui_default_set_clipboard; + } + return NSERROR_OK; +} + + +static void gui_default_quit(void) +{ +} + +static void gui_default_set_search_ico(hlcache_handle *ico) +{ +} + +static nsurl *gui_default_get_resource_url(const char *path) +{ + return NULL; +} + +static void gui_default_launch_url(const char *url) +{ +} + +static void gui_default_create_form_select_menu(struct browser_window *bw, + struct form_control *control) +{ +} + + +static void gui_default_cert_verify(nsurl *url, + const struct ssl_cert_info *certs, + unsigned long num, + nserror (*cb)(bool proceed, void *pw), + void *cbpw) +{ + cb(false, cbpw); +} + +static void gui_default_401login_open(nsurl *url, const char *realm, + nserror (*cb)(bool proceed, void *pw), void *cbpw) +{ + cb(false, cbpw); +} + +/** verify browser table is valid */ +static nserror verify_browser_register(struct gui_browser_table *gbt) +{ + /* check table is present */ + if (gbt == NULL) { + return NSERROR_BAD_PARAMETER; + } + + /* check the mandantory fields are set */ + if (gbt->poll == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gbt->filename_from_path == NULL) { + return NSERROR_BAD_PARAMETER; + } + if (gbt->path_add_part == NULL) { + return NSERROR_BAD_PARAMETER; + } + + + /* fill in the optional entries with defaults */ + if (gbt->quit == NULL) { + gbt->quit = gui_default_quit; + } + if (gbt->set_search_ico == NULL) { + gbt->set_search_ico = gui_default_set_search_ico; + } + if (gbt->get_resource_url == NULL) { + gbt->get_resource_url = gui_default_get_resource_url; + } + if (gbt->launch_url == NULL) { + gbt->launch_url = gui_default_launch_url; + } + if (gbt->create_form_select_menu == NULL) { + gbt->create_form_select_menu = gui_default_create_form_select_menu; + } + if (gbt->cert_verify == NULL) { + gbt->cert_verify = gui_default_cert_verify; + } + if (gbt->login == NULL) { + gbt->login = gui_default_401login_open; + } + return NSERROR_OK; +} + + + +static struct gui_download_table default_download_table = { + .create = gui_default_download_create, + .data = gui_default_download_data, + .error = gui_default_download_error, + .done = gui_default_download_done, +}; + +static struct gui_clipboard_table default_clipboard_table = { + .get = gui_default_get_clipboard, + .set = gui_default_set_clipboard, +}; + +/* exported interface documented in desktop/gui_factory.h */ +nserror gui_factory_register(struct gui_table *gt) +{ + nserror err; + + /* ensure not already initialised */ + if (guit != NULL) { + return NSERROR_INIT_FAILED; + } + + /* check table is present */ + if (gt == NULL) { + return NSERROR_BAD_PARAMETER; + } + + /* browser table */ + err = verify_browser_register(gt->browser); + if (err != NSERROR_OK) { + return err; + } + + /* window table */ + err = verify_window_register(gt->window); + if (err != NSERROR_OK) { + return err; + } + + /* download table */ + if (gt->download == NULL) { + /* set default download table */ + gt->download = &default_download_table; + } + err = verify_download_register(gt->download); + if (err != NSERROR_OK) { + return err; + } + + /* clipboard table */ + if (gt->clipboard == NULL) { + /* set default clipboard table */ + gt->clipboard = &default_clipboard_table; + } + err = verify_clipboard_register(gt->clipboard); + if (err != NSERROR_OK) { + return err; + } + + guit = gt; + + return NSERROR_OK; +} diff --git a/desktop/401login.h b/desktop/gui_factory.h index 1c8140bae..dc94b3a16 100644 --- a/desktop/401login.h +++ b/desktop/gui_factory.h @@ -1,5 +1,5 @@ /* - * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2014 vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -16,16 +16,24 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef NETSURF_DESKTOP_401LOGIN_H -#define NETSURF_DESKTOP_401LOGIN_H +/** \file + * Interface to gui interface factory + */ + +#ifndef _NETSURF_DESKTOP_GUI_FACTORY_H_ +#define _NETSURF_DESKTOP_GUI_FACTORY_H_ -#include <stdbool.h> +#include "desktop/gui.h" -#include "utils/config.h" -#include "utils/nsurl.h" -#include "utils/errors.h" +/** The global operation table */ +extern struct gui_table *guit; -void gui_401login_open(nsurl *url, const char *realm, - nserror (*cb)(bool proceed, void *pw), void *cbpw); +/** register and verify global operation table + * + * @param gt The global table to register + * @return NSERROR_OK on success or error code on faliure. On faliure + * global table will not be initialised + */ +nserror gui_factory_register(struct gui_table *gt); #endif diff --git a/desktop/netsurf.c b/desktop/netsurf.c index 36b0b589a..d294073ba 100644 --- a/desktop/netsurf.c +++ b/desktop/netsurf.c @@ -37,10 +37,9 @@ #include "image/image.h" #include "image/image_cache.h" #include "desktop/netsurf.h" -#include "desktop/401login.h" #include "desktop/browser.h" #include "desktop/system_colour.h" -#include "desktop/gui.h" +#include "desktop/gui_factory.h" #include "utils/nsoption.h" #include "desktop/searchweb.h" @@ -95,14 +94,14 @@ static nserror netsurf_llcache_query_handler(const llcache_query *query, { switch (query->type) { case LLCACHE_QUERY_AUTH: - gui_401login_open(query->url, query->data.auth.realm, cb, cbpw); + guit->browser->login(query->url, query->data.auth.realm, cb, cbpw); break; case LLCACHE_QUERY_REDIRECT: /** \todo Need redirect query dialog */ /* For now, do nothing, as this query type isn't emitted yet */ break; case LLCACHE_QUERY_SSL: - gui_cert_verify(query->url, query->data.ssl.certs, + guit->browser->cert_verify(query->url, query->data.ssl.certs, query->data.ssl.num, cb, cbpw); break; } @@ -116,7 +115,7 @@ static nserror netsurf_llcache_query_handler(const llcache_query *query, * Initialise components used by gui NetSurf. */ -nserror netsurf_init(const char *messages) +nserror netsurf_init(const char *messages, struct gui_table *gt) { nserror error; struct utsname utsname; @@ -150,6 +149,11 @@ nserror netsurf_init(const char *messages) utsname.nodename, utsname.release, utsname.version, utsname.machine)); + /* register the gui handlers */ + error = gui_factory_register(gt); + if (error != NSERROR_OK) + return error; + messages_load(messages); /* corestrings init */ @@ -228,7 +232,7 @@ nserror netsurf_init(const char *messages) int netsurf_main_loop(void) { while (!netsurf_quit) { - gui_poll(fetch_active); + guit->browser->poll(fetch_active); hlcache_poll(); } @@ -244,7 +248,7 @@ void netsurf_exit(void) hlcache_stop(); LOG(("Closing GUI")); - gui_quit(); + guit->browser->quit(); LOG(("Finalising JavaScript")); js_finalise(); diff --git a/desktop/netsurf.h b/desktop/netsurf.h index aa1796f7c..e6858ad66 100644 --- a/desktop/netsurf.h +++ b/desktop/netsurf.h @@ -28,8 +28,10 @@ extern const char * const netsurf_version; extern const int netsurf_version_major; extern const int netsurf_version_minor; +struct gui_table; + /** Initialise netsurf core */ -nserror netsurf_init(const char *messages); +nserror netsurf_init(const char *messages, struct gui_table *gt); /** Run primary event loop */ extern int netsurf_main_loop(void); diff --git a/desktop/save_complete.c b/desktop/save_complete.c index 3e5234af4..bd2ed4dea 100644 --- a/desktop/save_complete.c +++ b/desktop/save_complete.c @@ -37,6 +37,7 @@ #include "content/hlcache.h" #include "css/css.h" #include "desktop/save_complete.h" +#include "desktop/gui_factory.h" #include "render/box.h" #include "render/html.h" #include "utils/corestrings.h" @@ -147,7 +148,7 @@ static bool save_complete_save_buffer(save_complete_ctx *ctx, char fullpath[PATH_MAX]; strncpy(fullpath, ctx->path, sizeof fullpath); - error = path_add_part(fullpath, sizeof fullpath, leafname); + error = guit->browser->path_add_part(fullpath, sizeof fullpath, leafname); if (error == false) { warn_user("NoMemory", NULL); return false; @@ -1048,7 +1049,7 @@ static bool save_complete_save_html_document(save_complete_ctx *ctx, else snprintf(filename, sizeof filename, "%p", c); - error = path_add_part(fullpath, sizeof fullpath, filename); + error = guit->browser->path_add_part(fullpath, sizeof fullpath, filename); if (error == false) { warn_user("NoMemory", NULL); return false; @@ -1125,7 +1126,7 @@ static bool save_complete_inventory(save_complete_ctx *ctx) char fullpath[PATH_MAX]; strncpy(fullpath, ctx->path, sizeof fullpath); - error = path_add_part(fullpath, sizeof fullpath, "Inventory"); + error = guit->browser->path_add_part(fullpath, sizeof fullpath, "Inventory"); if (error == false) { warn_user("NoMemory", NULL); return false; diff --git a/desktop/searchweb.c b/desktop/searchweb.c index 4c050d97a..30b424cb3 100644 --- a/desktop/searchweb.c +++ b/desktop/searchweb.c @@ -27,6 +27,7 @@ #include "content/hlcache.h" #include "desktop/browser.h" #include "desktop/gui.h" +#include "desktop/gui_factory.h" #include "utils/nsoption.h" #include "desktop/searchweb.h" #include "utils/config.h" @@ -307,7 +308,7 @@ nserror search_web_ico_callback(hlcache_handle *ico, case CONTENT_MSG_DONE: LOG(("got favicon '%s'", nsurl_access(hlcache_handle_get_url(ico)))); - gui_window_set_search_ico(search_ico); + guit->browser->set_search_ico(search_ico); break; case CONTENT_MSG_ERROR: diff --git a/desktop/selection.c b/desktop/selection.c index 13a1293e3..96c7e0c3c 100644 --- a/desktop/selection.c +++ b/desktop/selection.c @@ -30,6 +30,7 @@ #include "desktop/browser_private.h" #include "desktop/gui.h" +#include "desktop/gui_factory.h" #include "desktop/mouse.h" #include "desktop/plotters.h" #include "desktop/save_text.h" @@ -274,7 +275,7 @@ bool selection_click(struct selection *s, browser_mouse_state mouse, (modkeys && (mouse & BROWSER_MOUSE_DRAG_2)))) { /* drag-saving selection */ char *sel = selection_get_copy(s); - gui_drag_save_selection(top->window, sel); + guit->window->drag_save_selection(top->window, sel); free(sel); } else if (!modkeys) { @@ -293,7 +294,7 @@ bool selection_click(struct selection *s, browser_mouse_state mouse, s->drag_state = DRAG_END; - gui_start_selection(top->window); + guit->window->start_selection(top->window); } else if (mouse & BROWSER_MOUSE_DRAG_2) { @@ -312,7 +313,7 @@ bool selection_click(struct selection *s, browser_mouse_state mouse, s->drag_state = DRAG_START; } - gui_start_selection(top->window); + guit->window->start_selection(top->window); } else if (mouse & BROWSER_MOUSE_CLICK_2) { @@ -844,7 +845,7 @@ bool selection_copy_to_clipboard(struct selection *s) return false; } - gui_set_clipboard(sel_string.buffer, sel_string.length, + guit->clipboard->set(sel_string.buffer, sel_string.length, sel_string.styles, sel_string.n_styles); free(sel_string.buffer); diff --git a/desktop/textarea.c b/desktop/textarea.c index f9712ac84..209a6c6d7 100644 --- a/desktop/textarea.c +++ b/desktop/textarea.c @@ -24,11 +24,13 @@ #include <stdint.h> #include <string.h> #include "css/utils.h" + #include "desktop/mouse.h" #include "desktop/textarea.h" #include "desktop/textinput.h" #include "desktop/plotters.h" #include "desktop/scrollbar.h" +#include "desktop/gui_factory.h" #include "render/font.h" #include "utils/log.h" #include "utils/utf8.h" @@ -1417,7 +1419,7 @@ static bool textarea_replace_text_internal(struct textarea *ta, size_t b_start, /* Place CUTs on clipboard */ if (add_to_clipboard) { - gui_set_clipboard(ta->show->data + b_start, b_end - b_start, + guit->clipboard->set(ta->show->data + b_start, b_end - b_start, NULL, 0); } @@ -2484,7 +2486,7 @@ bool textarea_keypress(struct textarea *ta, uint32_t key) if (readonly) break; - gui_get_clipboard(&clipboard, &clipboard_length); + guit->clipboard->get(&clipboard, &clipboard_length); if (clipboard == NULL) return false; diff --git a/desktop/textinput.c b/desktop/textinput.c index e804829fa..c61b838fe 100644 --- a/desktop/textinput.c +++ b/desktop/textinput.c @@ -31,6 +31,7 @@ #include "desktop/browser_private.h" #include "desktop/gui.h" +#include "desktop/gui_factory.h" #include "desktop/mouse.h" #include "desktop/scrollbar.h" #include "desktop/selection.h" @@ -85,7 +86,7 @@ void browser_window_place_caret(struct browser_window *bw, int x, int y, /* TODO: intersect with bw viewport */ - gui_window_place_caret(root_bw->window, x, y, height * bw->scale, crp); + guit->window->place_caret(root_bw->window, x, y, height * bw->scale, crp); /* Set focus browser window */ root_bw->focus = bw; @@ -110,8 +111,9 @@ void browser_window_remove_caret(struct browser_window *bw, bool only_hide) else root_bw->can_edit = false; - if (root_bw->window) - gui_window_remove_caret(root_bw->window); + if (root_bw->window) { + guit->window->remove_caret(root_bw->window); + } } |