diff --git a/frontends/monkey/Makefile b/frontends/monkey/Makefile index d2dae3e..d83415f 100644 --- a/frontends/monkey/Makefile +++ b/frontends/monkey/Makefile @@ -50,7 +50,7 @@ endif # ---------------------------------------------------------------------------- # S_MONKEY are sources purely for the MONKEY build -S_FRONTEND := main.c output.c filetype.c schedule.c bitmap.c plot.c browser.c \ +S_FRONTEND := main.c output.c filetype.c schedule.c bitmap.c plot.c browser.c montauk_ui.c \ download.c 401login.c layout.c dispatch.c fetch.c diff --git a/frontends/monkey/browser.c b/frontends/monkey/browser.c index 4a33fae..d2b0c78 100644 --- a/frontends/monkey/browser.c +++ b/frontends/monkey/browser.c @@ -41,11 +41,92 @@ #include "monkey/output.h" #include "monkey/browser.h" #include "monkey/plot.h" +#if defined(__montauk__) +#include "monkey/montauk_ui.h" +#include "content/fetchers/montauk_bridge.h" +#endif static uint32_t win_ctr = 0; static struct gui_window *gw_ring = NULL; +#if defined(__montauk__) +static struct gui_window *native_active; + +struct gui_window *monkey_native_get_window(void) +{ + return native_active != NULL ? native_active : gw_ring; +} + +size_t monkey_native_tab_count(void) +{ + size_t count = 0; + struct gui_window *item = gw_ring; + if (item != NULL) do { + if (native_active == NULL || item->native_id == native_active->native_id) count++; + item = item->r_next; + } while (item != gw_ring); + return count; +} + +struct gui_window *monkey_native_tab_at(size_t index) +{ + struct gui_window *item = gw_ring; + if (item != NULL) do { + if (native_active == NULL || item->native_id == native_active->native_id) { + if (index == 0) return item; + index--; + } + item = item->r_next; + } while (item != gw_ring); + return NULL; +} + +void monkey_native_activate_window(struct gui_window *gw) +{ + if (gw != NULL) { + native_active = gw; + gw->dirty = true; + } +} + +void monkey_native_resize_tabs(struct gui_window *gw, int width, int height, + uint32_t *pixels) +{ + struct gui_window *item = gw_ring; + if (item != NULL) do { + if (item->native_id == gw->native_id) { + item->width = width; + item->height = height; + item->pixels = pixels; + item->dirty = true; + browser_window_schedule_reformat(item->bw); + } + item = item->r_next; + } while (item != gw_ring); +} + +void monkey_native_set_scale(struct gui_window *gw, int scale) +{ + struct gui_window *item = gw_ring; + if (scale < 0) scale = 0; + if (scale > 2) scale = 2; + if (item != NULL) do { + if (item->native_id == gw->native_id) { + struct mtk_netsurf_chrome_metrics metrics; + mtk_netsurf_chrome_metrics(scale, item->width, + (int)monkey_native_tab_count(), &metrics); + item->ui_scale = scale; + item->chrome_height = metrics.chrome_h; + item->status_height = metrics.status_h; + item->dirty = true; + browser_window_schedule_reformat(item->bw); + } + item = item->r_next; + } while (item != gw_ring); +} +#endif + /* exported function documented in monkey/browser.h */ nserror monkey_warn_user(const char *warning, const char *detail) { @@ -88,18 +169,39 @@ gui_window_create(struct browser_window *bw, ret->win_num = win_ctr++; ret->bw = bw; - ret->width = 800; - ret->height = 600; + ret->width = 1000; + ret->height = 700; #if defined(__montauk__) - mtk_win_result native; - if (mtk_win_create("NetSurf", ret->width, ret->height, &native) != 0) { - free(ret); - return NULL; + if ((flags & GW_CREATE_TAB) && existing != NULL) { + ret->width = existing->width; + ret->height = existing->height; + ret->native_id = existing->native_id; + ret->pixels = existing->pixels; + ret->ui_scale = existing->ui_scale; + ret->chrome_height = existing->chrome_height; + ret->status_height = existing->status_height; + } else { + mtk_win_result native; + if (mtk_win_create("NetSurf", ret->width, ret->height, &native) != 0) { + free(ret); + return NULL; + } + ret->native_id = native.id; + ret->pixels = (uint32_t *)(uintptr_t)native.pixels; + ret->ui_scale = mtk_win_getscale(); + if (ret->ui_scale < 0) ret->ui_scale = 0; + if (ret->ui_scale > 2) ret->ui_scale = 2; + struct mtk_netsurf_chrome_metrics metrics; + mtk_netsurf_chrome_metrics(ret->ui_scale, ret->width, 1, &metrics); + ret->chrome_height = metrics.chrome_h; + ret->status_height = metrics.status_h; } - ret->native_id = native.id; - ret->pixels = (uint32_t *)(uintptr_t)native.pixels; ret->clip_x1 = ret->width; ret->clip_y1 = ret->height; + ret->mouse_x = ret->mouse_y = -1; + ret->dirty = true; + strcpy(ret->title, "New Tab"); + strcpy(ret->status, "Loading..."); #endif moutf(MOUT_WINDOW, @@ -112,6 +214,10 @@ gui_window_create(struct browser_window *bw, ret->win_num, ret->width, ret->height); RING_INSERT(gw_ring, ret); +#if defined(__montauk__) + if (native_active == NULL || (flags & GW_CREATE_FOREGROUND)) + native_active = ret; +#endif return ret; } @@ -121,7 +227,16 @@ gui_window_destroy(struct gui_window *g) { moutf(MOUT_WINDOW, "DESTROY WIN %u", g->win_num); #if defined(__montauk__) - mtk_win_destroy(g->native_id); + mtk_netsurf_address_input_destroy((uintptr_t)g); + bool shared = false; + struct gui_window *item = gw_ring; + if (item != NULL) do { + if (item != g && item->native_id == g->native_id) shared = true; + item = item->r_next; + } while (item != gw_ring); + if (!shared) mtk_win_destroy(g->native_id); + if (native_active == g) + native_active = shared ? (g->r_next != g ? g->r_next : NULL) : NULL; #endif RING_REMOVE(gw_ring, g); free(g); @@ -130,6 +245,13 @@ gui_window_destroy(struct gui_window *g) static void gui_window_set_title(struct gui_window *g, const char *title) { +#if defined(__montauk__) + if (title != NULL) { + strncpy(g->title, title, sizeof(g->title) - 1); + g->title[sizeof(g->title) - 1] = 0; + g->dirty = true; + } +#endif moutf(MOUT_WINDOW, "TITLE WIN %u STR %s", g->win_num, title); } @@ -146,6 +268,12 @@ gui_window_get_dimensions(struct gui_window *g, int *width, int *height) { *width = g->width; *height = g->height; +#if defined(__montauk__) + *width = mtk_netsurf_page_view_width(*width); + *height -= g->chrome_height + g->status_height; + if (*width < 1) *width = 1; + if (*height < 1) *height = 1; +#endif moutf(MOUT_WINDOW, "GET_DIMENSIONS WIN %u WIDTH %d HEIGHT %d", @@ -169,6 +297,10 @@ gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon) static void gui_window_start_throbber(struct gui_window *g) { +#if defined(__montauk__) + g->loading = true; + g->dirty = true; +#endif moutf(MOUT_WINDOW, "START_THROBBER WIN %u", g->win_num); } @@ -176,24 +308,8 @@ static void gui_window_stop_throbber(struct gui_window *g) { #if defined(__montauk__) - struct rect clip = { - .x0 = 0, - .y0 = 0, - .x1 = g->width, - .y1 = g->height - }; - struct redraw_context ctx = { - .interactive = true, - .background_images = true, - .plot = monkey_plotters, - .priv = g - }; - for (int y = 0; y < g->height; y++) { - for (int x = 0; x < g->width; x++) - g->pixels[y * g->width + x] = 0xffffffffu; - } - browser_window_redraw(g->bw, g->scrollx, g->scrolly, &clip, &ctx); - mtk_win_present(g->native_id); + g->loading = false; + g->dirty = true; #endif moutf(MOUT_WINDOW, "STOP_THROBBER WIN %u", g->win_num); } @@ -214,6 +330,9 @@ gui_window_set_scroll(struct gui_window *gw, const struct rect *rect) { gw->scrollx = rect->x0; gw->scrolly = rect->y0; +#if defined(__montauk__) + gw->dirty = true; +#endif moutf(MOUT_WINDOW, "SET_SCROLL WIN %u X %d Y %d", gw->win_num, rect->x0, rect->y0); @@ -231,6 +350,9 @@ gui_window_set_scroll(struct gui_window *gw, const struct rect *rect) static nserror monkey_window_invalidate_area(struct gui_window *gw, const struct rect *rect) { +#if defined(__montauk__) + gw->dirty = true; +#endif if (rect != NULL) { moutf(MOUT_WINDOW, "INVALIDATE_AREA WIN %u X %d Y %d WIDTH %d HEIGHT %d", @@ -249,8 +371,13 @@ gui_window_update_extent(struct gui_window *g) { int width, height; - if (browser_window_get_extents(g->bw, false, &width, &height) != NSERROR_OK) + if (browser_window_get_extents(g->bw, true, &width, &height) != NSERROR_OK) return; +#if defined(__montauk__) + g->extent_width = width; + g->extent_height = height; + g->dirty = true; +#endif moutf(MOUT_WINDOW, "UPDATE_EXTENT WIN %u WIDTH %d HEIGHT %d", g->win_num, width, height); @@ -259,6 +386,13 @@ gui_window_update_extent(struct gui_window *g) static void gui_window_set_status(struct gui_window *g, const char *text) { +#if defined(__montauk__) + if (text != NULL) { + strncpy(g->status, text, sizeof(g->status) - 1); + g->status[sizeof(g->status) - 1] = 0; + g->dirty = true; + } +#endif moutf(MOUT_WINDOW, "SET_STATUS WIN %u STR %s", g->win_num, text); } @@ -336,11 +470,39 @@ gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) static nserror gui_window_set_url(struct gui_window *g, nsurl *url) { +#if defined(__montauk__) + strncpy(g->address, nsurl_access(url), sizeof(g->address) - 1); + g->address[sizeof(g->address) - 1] = 0; + g->dirty = true; +#endif moutf(MOUT_WINDOW, "SET_URL WIN %u URL %s", g->win_num, nsurl_access(url)); return NSERROR_OK; } +#if defined(__montauk__) +void monkey_native_redraw(struct gui_window *g) +{ + if (g == NULL || g->pixels == NULL) return; + const int chrome_h = g->chrome_height, status_h = g->status_height; + int content_h = g->height - chrome_h - status_h; + if (content_h < 1) content_h = 1; + for (int y = chrome_h; y < g->height - status_h; y++) + for (int x = 0; x < g->width; x++) + g->pixels[y * g->width + x] = 0xffffffffu; + struct rect clip = { .x0 = 0, .y0 = 0, + .x1 = mtk_netsurf_page_view_width(g->width), .y1 = content_h }; + struct redraw_context ctx = { + .interactive = true, .background_images = true, + .plot = monkey_plotters, .priv = g + }; + browser_window_redraw(g->bw, -g->scrollx, -g->scrolly, &clip, &ctx); + monkey_native_draw_chrome(g); + mtk_win_present(g->native_id); + g->dirty = false; +} +#endif + static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) { @@ -364,6 +526,13 @@ static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, const struct rect *clip) { +#if defined(__montauk__) + g->caret_x = x; + g->caret_y = y; + g->caret_height = height; + g->caret_visible = true; + g->dirty = true; +#endif moutf(MOUT_WINDOW, "PLACE_CARET WIN %u X %d Y %d HEIGHT %d", g->win_num, x, y, height); } @@ -371,6 +540,10 @@ gui_window_place_caret(struct gui_window *g, int x, int y, int height, static void gui_window_remove_caret(struct gui_window *g) { +#if defined(__montauk__) + g->caret_visible = false; + g->dirty = true; +#endif moutf(MOUT_WINDOW, "REMOVE_CARET WIN %u", g->win_num); } @@ -390,6 +563,18 @@ gui_window_save_link(struct gui_window *g, nsurl *url, const char *title) return NSERROR_OK; } +#if defined(__montauk__) +static void gui_window_file_gadget_open(struct gui_window *g, + struct hlcache_handle *hl, struct form_control *gadget) +{ + char path[512]; + (void)hl; + if (mtk_netsurf_open_file(path, sizeof(path))) + browser_window_set_gadget_filename(g->bw, gadget, path); + g->dirty = true; +} +#endif + static void gui_window_console_log(struct gui_window *g, browser_window_console_source src, @@ -448,6 +633,10 @@ static void gui_window_report_page_info(struct gui_window *g) { const char *state = "***WAH***"; +#if defined(__montauk__) + g->page_state = browser_window_get_page_info_state(g->bw); + g->dirty = true; +#endif switch (browser_window_get_page_info_state(g->bw)) { case PAGE_STATE_UNKNOWN: @@ -911,6 +1100,9 @@ static struct gui_window_table window_table = { .place_caret = gui_window_place_caret, .drag_start = gui_window_drag_start, .save_link = gui_window_save_link, +#if defined(__montauk__) + .file_gadget_open = gui_window_file_gadget_open, +#endif .console_log = gui_window_console_log, }; diff --git a/frontends/monkey/browser.h b/frontends/monkey/browser.h index 8e90e0c..09399ab 100644 --- a/frontends/monkey/browser.h +++ b/frontends/monkey/browser.h @@ -37,7 +37,19 @@ struct gui_window { #if defined(__montauk__) int native_id; uint32_t *pixels; + int ui_scale, chrome_height, status_height; + int mouse_x, mouse_y; int clip_x0, clip_y0, clip_x1, clip_y1; + int extent_width, extent_height; + uint8_t dirty, loading, address_focus; + uint8_t caret_visible; + uint8_t find_focus, menu_open, page_state; + int scrollbar_hover, scrollbar_dragging, scrollbar_drag_offset; + int caret_x, caret_y, caret_height; + char find_text[256]; + char address[2048]; + char title[128]; + char status[256]; #endif char *host; /* Ignore this, it's in case RING*() gets debugging for fetchers */ @@ -50,6 +62,17 @@ void monkey_window_process_reformats(void); void monkey_window_handle_command(int argc, char **argv); void monkey_kill_browser_windows(void); +#if defined(__montauk__) +struct gui_window *monkey_native_get_window(void); +size_t monkey_native_tab_count(void); +struct gui_window *monkey_native_tab_at(size_t index); +void monkey_native_activate_window(struct gui_window *gw); +void monkey_native_resize_tabs(struct gui_window *gw, int width, int height, + uint32_t *pixels); +void monkey_native_set_scale(struct gui_window *gw, int scale); +void monkey_native_redraw(struct gui_window *gw); +#endif + nserror monkey_warn_user(const char *warning, const char *detail); #endif /* NETSURF_MONKEY_BROWSER_H */ diff --git a/frontends/monkey/main.c b/frontends/monkey/main.c index 578d148..ebd940a 100644 --- a/frontends/monkey/main.c +++ b/frontends/monkey/main.c @@ -46,6 +46,9 @@ #include "monkey/401login.h" #include "monkey/filetype.h" #include "monkey/fetch.h" +#if defined(__montauk__) +#include "monkey/montauk_ui.h" +#endif #include "monkey/schedule.h" #include "monkey/bitmap.h" #include "monkey/layout.h" @@ -274,7 +277,7 @@ static struct gui_misc_table monkey_misc_table = { .present_cookies = gui_present_cookies, }; -static void monkey_run(void) +static void __attribute__((unused)) monkey_run(void) { fd_set read_fd_set, write_fd_set, exc_fd_set; int max_fd; @@ -399,6 +402,10 @@ main(int argc, char **argv) .fetch = monkey_fetch_table, .bitmap = monkey_bitmap_table, .layout = monkey_layout_table, +#if defined(__montauk__) + .clipboard = &monkey_native_clipboard_table, + .search = &monkey_native_search_table, +#endif .llcache = filesystem_llcache_table, }; @@ -491,7 +498,11 @@ main(int argc, char **argv) moutf(MOUT_GENERIC, "STARTED"); +#if defined(__montauk__) + monkey_native_run(argc > 1 ? argv[1] : NULL); +#else monkey_run(); +#endif moutf(MOUT_GENERIC, "CLOSING_DOWN"); monkey_kill_browser_windows(); diff --git a/frontends/monkey/plot.c b/frontends/monkey/plot.c index 6f762f9..f6bf09a 100644 --- a/frontends/monkey/plot.c +++ b/frontends/monkey/plot.c @@ -53,6 +53,7 @@ static uint32_t native_colour(colour c) static void native_pixel(struct gui_window *gw, int x, int y, uint32_t colour) { + y += gw->chrome_height; if (gw == NULL || gw->pixels == NULL || x < gw->clip_x0 || y < gw->clip_y0 || x >= gw->clip_x1 || y >= gw->clip_y1 || x < 0 || y < 0 || x >= gw->width || y >= gw->height || colour == 0) return; @@ -63,6 +64,7 @@ static void native_fill(struct gui_window *gw, int x0, int y0, int x1, int y1, uint32_t colour) { if (gw == NULL || colour == 0) return; + y0 += gw->chrome_height; y1 += gw->chrome_height; if (x0 < gw->clip_x0) x0 = gw->clip_x0; if (y0 < gw->clip_y0) y0 = gw->clip_y0; if (x1 > gw->clip_x1) x1 = gw->clip_x1; @@ -96,7 +98,7 @@ static void native_text(struct gui_window *gw, int x, int baseline, if (gw == NULL || gw->pixels == NULL) return; mtk_netsurf_font_draw(gw->pixels, gw->width, gw->height, gw->clip_x0, gw->clip_y0, gw->clip_x1, gw->clip_y1, - x, baseline, text, length, native_colour(style->foreground), + x, baseline + gw->chrome_height, text, length, native_colour(style->foreground), style->family, style->weight, style->flags, px); } #endif @@ -116,9 +118,9 @@ monkey_plot_clip(const struct redraw_context *ctx, const struct rect *clip) struct gui_window *gw = ctx->priv; if (gw != NULL) { gw->clip_x0 = clip->x0; - gw->clip_y0 = clip->y0; + gw->clip_y0 = clip->y0 + gw->chrome_height; gw->clip_x1 = clip->x1; - gw->clip_y1 = clip->y1; + gw->clip_y1 = clip->y1 + gw->chrome_height; } #endif moutf(MOUT_PLOT, "CLIP X0 %d Y0 %d X1 %d Y1 %d", @@ -338,7 +340,7 @@ monkey_plot_bitmap(const struct redraw_context *ctx, uint32_t out = 0xff000000u | ((p & 0xffu) << 16) | (p & 0xff00u) | ((p >> 16) & 0xffu); if (a != 255) { - int tx = x + dx, ty = y + dy; + int tx = x + dx, ty = y + dy + gw->chrome_height; if (tx >= 0 && ty >= 0 && tx < gw->width && ty < gw->height) { uint32_t d = gw->pixels[ty * gw->width + tx]; unsigned r = (((out >> 16) & 255) * a + ((d >> 16) & 255) * (255-a)) / 255;