From ca5b165c85e1e8cc7df286b6a0a9a061de99bcaa Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 31 Jul 2016 00:13:41 +0100 Subject: add nsgtk support for core window API --- frontends/gtk/Makefile | 2 +- frontends/gtk/corewindow.c | 638 +++++++++++++++++++++++++++++++++++++++++++++ frontends/gtk/corewindow.h | 104 ++++++++ 3 files changed, 743 insertions(+), 1 deletion(-) create mode 100644 frontends/gtk/corewindow.c create mode 100644 frontends/gtk/corewindow.h (limited to 'frontends') diff --git a/frontends/gtk/Makefile b/frontends/gtk/Makefile index aae1d4465..f8f7d8c69 100644 --- a/frontends/gtk/Makefile +++ b/frontends/gtk/Makefile @@ -163,7 +163,7 @@ S_FRONTEND := gui.c schedule.c layout_pango.c bitmap.c plotters.c \ selection.c history.c window.c fetch.c download.c menu.c \ print.c search.c tabs.c toolbar.c gettext.c \ compat.c cookies.c hotlist.c viewdata.c viewsource.c \ - preferences.c about.c ssl_cert.c resources.c + preferences.c about.c ssl_cert.c resources.c corewindow.c # This is the final source build list # Note this is deliberately *not* expanded here as common and image diff --git a/frontends/gtk/corewindow.c b/frontends/gtk/corewindow.c new file mode 100644 index 000000000..11dec832e --- /dev/null +++ b/frontends/gtk/corewindow.c @@ -0,0 +1,638 @@ +/* + * Copyright 2016 Vincent Sanders + * + * 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 . + */ + +/** + * \file + * GTK generic core window interface. + * + * Provides interface for core renderers to the gtk toolkit drawable area. + * \todo should the interface really be called coredrawable? + * + + * This module is an object that must be encapsulated. Client users + * should embed a struct nsgtk_corewindow at the beginning of their + * context for this display surface, fill in relevant data and then + * call nsgtk_corewindow_init() + * + * The nsgtk core window structure requires the drawing area and + * scrollable widgets are present and the callback for draw, key and + * mouse operations. + */ + +#include +#include +#include +#include + +#include "utils/log.h" +#include "utils/utils.h" +#include "utils/messages.h" +#include "utils/utf8.h" +#include "netsurf/keypress.h" +#include "netsurf/mouse.h" +#include "desktop/plot_style.h" + +#include "gtk/compat.h" +#include "gtk/gui.h" /* just for gtk_gui_gdkkey_to_nskey */ +#include "gtk/plotters.h" +#include "gtk/corewindow.h" + +/** + * Convert GDK mouse event to netsurf mouse state + */ +static browser_mouse_state nsgtk_cw_gdkbutton_to_nsstate(GdkEventButton *event) +{ + browser_mouse_state ms; + + if (event->type == GDK_2BUTTON_PRESS) { + ms = BROWSER_MOUSE_DOUBLE_CLICK; + } else { + ms = BROWSER_MOUSE_HOVER; + } + + /* button state */ + switch (event->button) { + case 1: + ms |= BROWSER_MOUSE_PRESS_1; + break; + + case 2: + ms |= BROWSER_MOUSE_PRESS_2; + break; + } + + /* Handle the modifiers too */ + if (event->state & GDK_SHIFT_MASK) { + ms |= BROWSER_MOUSE_MOD_1; + } + + if (event->state & GDK_CONTROL_MASK) { + ms |= BROWSER_MOUSE_MOD_2; + } + + if (event->state & GDK_MOD1_MASK) { + ms |= BROWSER_MOUSE_MOD_3; + } + + return ms; +} + +/** + * gtk event on mouse button press. + * + * \param widget The gtk widget the event occoured for. + * \param event The event that occoured. + * \param g The context pointer passed when teh event was registered. + */ +static gboolean +nsgtk_cw_button_press_event(GtkWidget *widget, + GdkEventButton *event, + gpointer g) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g; + struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state; + + gtk_im_context_reset(nsgtk_cw->input_method); + gtk_widget_grab_focus(GTK_WIDGET(nsgtk_cw->drawing_area)); + + /* record event information for potentially starting a drag. */ + mouse->pressed_x = mouse->last_x = event->x; + mouse->pressed_y = mouse->last_y = event->y; + mouse->pressed = true; + + mouse->state = nsgtk_cw_gdkbutton_to_nsstate(event); + + nsgtk_cw->mouse(nsgtk_cw, mouse->state, event->x, event->y); + + return TRUE; +} + +static gboolean +nsgtk_cw_button_release_event(GtkWidget *widget, + GdkEventButton *event, + gpointer g) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g; + struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state; + + /* only button 1 clicks are considered double clicks. If the + * mouse state is PRESS then we are waiting for a release to + * emit a click event, otherwise just reset the state to nothing. + */ + if (mouse->state & BROWSER_MOUSE_DOUBLE_CLICK) { + if (mouse->state & BROWSER_MOUSE_PRESS_1) { + mouse->state ^= BROWSER_MOUSE_PRESS_1 | + BROWSER_MOUSE_CLICK_1; + } else if (mouse->state & BROWSER_MOUSE_PRESS_2) { + mouse->state ^= (BROWSER_MOUSE_PRESS_2 | + BROWSER_MOUSE_CLICK_2 | + BROWSER_MOUSE_DOUBLE_CLICK); + } + } else if (mouse->state & BROWSER_MOUSE_PRESS_1) { + mouse->state ^= (BROWSER_MOUSE_PRESS_1 | + BROWSER_MOUSE_CLICK_1); + } else if (mouse->state & BROWSER_MOUSE_PRESS_2) { + mouse->state ^= (BROWSER_MOUSE_PRESS_2 | + BROWSER_MOUSE_CLICK_2); + } else if (mouse->state & BROWSER_MOUSE_HOLDING_1) { + mouse->state ^= (BROWSER_MOUSE_HOLDING_1 | + BROWSER_MOUSE_DRAG_ON); + } else if (mouse->state & BROWSER_MOUSE_HOLDING_2) { + mouse->state ^= (BROWSER_MOUSE_HOLDING_2 | + BROWSER_MOUSE_DRAG_ON); + } + + /* Handle modifiers being removed */ + if ((mouse->state & BROWSER_MOUSE_MOD_1) && + !(event->state & GDK_SHIFT_MASK)) { + mouse->state ^= BROWSER_MOUSE_MOD_1; + } + if ((mouse->state & BROWSER_MOUSE_MOD_2) && + !(event->state & GDK_CONTROL_MASK)) { + mouse->state ^= BROWSER_MOUSE_MOD_2; + } + if ((mouse->state & BROWSER_MOUSE_MOD_3) && + !(event->state & GDK_MOD1_MASK)) { + mouse->state ^= BROWSER_MOUSE_MOD_3; + } + + /* end drag with modifiers */ + if (mouse->state & (BROWSER_MOUSE_MOD_1 | + BROWSER_MOUSE_MOD_2 | + BROWSER_MOUSE_MOD_3)) { + mouse->state = BROWSER_MOUSE_HOVER; + } + + nsgtk_cw->mouse(nsgtk_cw, mouse->state, event->x, event->y); + + mouse->pressed = false; + + return TRUE; +} + +static gboolean +nsgtk_cw_motion_notify_event(GtkWidget *widget, + GdkEventMotion *event, gpointer g) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g; + struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state; + + if (mouse->pressed == false) { + return TRUE; + } + + if ((fabs(event->x - mouse->last_x) < 5.0) && + (fabs(event->y - mouse->last_y) < 5.0)) { + /* Mouse hasn't moved far enough from press coordinate + * for this to be considered a drag. + */ + return FALSE; + } + + /* This is a drag, ensure it's always treated as such, even if + * we drag back over the press location. + */ + mouse->last_x = INT_MIN; + mouse->last_y = INT_MIN; + + + if (mouse->state & BROWSER_MOUSE_PRESS_1) { + /* Start button 1 drag */ + nsgtk_cw->mouse(nsgtk_cw, + BROWSER_MOUSE_DRAG_1, + mouse->pressed_x, + mouse->pressed_y); + + /* Replace PRESS with HOLDING and declare drag in progress */ + mouse->state ^= (BROWSER_MOUSE_PRESS_1 | + BROWSER_MOUSE_HOLDING_1); + mouse->state |= BROWSER_MOUSE_DRAG_ON; + + } else if (mouse->state & BROWSER_MOUSE_PRESS_2) { + /* Start button 2s drag */ + nsgtk_cw->mouse(nsgtk_cw, + BROWSER_MOUSE_DRAG_2, + mouse->pressed_x, + mouse->pressed_y); + + /* Replace PRESS with HOLDING and declare drag in progress */ + mouse->state ^= (BROWSER_MOUSE_PRESS_2 | + BROWSER_MOUSE_HOLDING_2); + mouse->state |= BROWSER_MOUSE_DRAG_ON; + + } else { + /* continue drag */ + + /* Handle modifiers being removed */ + if ((mouse->state & BROWSER_MOUSE_MOD_1) && + !(event->state & GDK_SHIFT_MASK)) { + mouse->state ^= BROWSER_MOUSE_MOD_1; + } + if ((mouse->state & BROWSER_MOUSE_MOD_2) && + !(event->state & GDK_CONTROL_MASK)) { + mouse->state ^= BROWSER_MOUSE_MOD_2; + } + if ((mouse->state & BROWSER_MOUSE_MOD_3) && + !(event->state & GDK_MOD1_MASK)) { + mouse->state ^= BROWSER_MOUSE_MOD_3; + } + + if (mouse->state & + (BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_HOLDING_2)) { + nsgtk_cw->mouse(nsgtk_cw, + mouse->state, + event->x, event->y); + } + } + + return TRUE; +} + + +/** + * Deal with keypress events not handled but input method or callback + * + * \param nsgtk_cw nsgtk core window key event happened in. + * \param nskey The netsurf keycode of the event. + * \return NSERROR_OK on sucess otherwise an error code. + */ +static nserror nsgtk_cw_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey) +{ + double value; + GtkAdjustment *vscroll; + GtkAdjustment *hscroll; + GtkAdjustment *scroll = NULL; + gdouble hpage, vpage; + + vscroll = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled); + hscroll = gtk_scrolled_window_get_hadjustment(nsgtk_cw->scrolled); + g_object_get(vscroll, "page-size", &vpage, NULL); + g_object_get(hscroll, "page-size", &hpage, NULL); + + switch(nskey) { + case NS_KEY_TEXT_START: + scroll = vscroll; + value = nsgtk_adjustment_get_lower(scroll); + break; + + case NS_KEY_TEXT_END: + scroll = vscroll; + value = nsgtk_adjustment_get_upper(scroll) - vpage; + if (value < nsgtk_adjustment_get_lower(scroll)) + value = nsgtk_adjustment_get_lower(scroll); + break; + + case NS_KEY_LEFT: + scroll = hscroll; + value = gtk_adjustment_get_value(scroll) - + nsgtk_adjustment_get_step_increment(scroll); + if (value < nsgtk_adjustment_get_lower(scroll)) + value = nsgtk_adjustment_get_lower(scroll); + break; + + case NS_KEY_RIGHT: + scroll = hscroll; + value = gtk_adjustment_get_value(scroll) + + nsgtk_adjustment_get_step_increment(scroll); + if (value > nsgtk_adjustment_get_upper(scroll) - hpage) + value = nsgtk_adjustment_get_upper(scroll) - hpage; + break; + case NS_KEY_UP: + scroll = vscroll; + value = gtk_adjustment_get_value(scroll) - + nsgtk_adjustment_get_step_increment(scroll); + if (value < nsgtk_adjustment_get_lower(scroll)) + value = nsgtk_adjustment_get_lower(scroll); + break; + + case NS_KEY_DOWN: + scroll = vscroll; + value = gtk_adjustment_get_value(scroll) + + nsgtk_adjustment_get_step_increment(scroll); + if (value > nsgtk_adjustment_get_upper(scroll) - vpage) + value = nsgtk_adjustment_get_upper(scroll) - vpage; + break; + + case NS_KEY_PAGE_UP: + scroll = vscroll; + value = gtk_adjustment_get_value(scroll) - + nsgtk_adjustment_get_page_increment(scroll); + + if (value < nsgtk_adjustment_get_lower(scroll)) + value = nsgtk_adjustment_get_lower(scroll); + + break; + + case NS_KEY_PAGE_DOWN: + scroll = vscroll; + value = gtk_adjustment_get_value(scroll) + + nsgtk_adjustment_get_page_increment(scroll); + + if (value > nsgtk_adjustment_get_upper(scroll) - vpage) + value = nsgtk_adjustment_get_upper(scroll) - vpage; + break; + + } + + if (scroll != NULL) { + gtk_adjustment_set_value(scroll, value); + } + + return NSERROR_OK; +} + +/** + * gtk event on key press. + * + * \param widget The gtk widget the event occoured for. + * \param event The event that occoured. + * \param g The context pointer passed when teh event was registered. + */ +static gboolean +nsgtk_cw_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer g) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g; + nserror res; + uint32_t nskey; + + /* check to see if gtk input method swallowed the keypress */ + if (gtk_im_context_filter_keypress(nsgtk_cw->input_method, event)) { + return TRUE; + } + + /* convert gtk event to nskey */ + nskey = gtk_gui_gdkkey_to_nskey(event); + + /* attempt to handle keypress in caller */ + res = nsgtk_cw->key(nsgtk_cw, nskey); + if (res == NSERROR_OK) { + return TRUE; + } else if (res != NSERROR_NOT_IMPLEMENTED) { + LOG("%s", messages_get_errorcode(res)); + return FALSE; + } + + /* deal with unprocessed keypress */ + res = nsgtk_cw_key(nsgtk_cw, nskey); + if (res != NSERROR_OK) { + LOG("%s", messages_get_errorcode(res)); + return FALSE; + } + return TRUE; +} + + +static gboolean +nsgtk_cw_keyrelease_event(GtkWidget *widget, GdkEventKey *event, gpointer g) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g; + + return gtk_im_context_filter_keypress(nsgtk_cw->input_method, event); +} + + +static void +nsgtk_cw_input_method_commit(GtkIMContext *ctx, const gchar *str, gpointer g) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g; + size_t len; + size_t offset = 0; + uint32_t nskey; + + len = strlen(str); + + while (offset < len) { + nskey = utf8_to_ucs4(str + offset, len - offset); + + nsgtk_cw->key(nsgtk_cw, nskey); + + offset = utf8_next(str, len, offset); + } +} + + +#if GTK_CHECK_VERSION(3,0,0) + +/* signal handler for core window redraw */ +static gboolean +nsgtk_cw_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)data; + double x1; + double y1; + double x2; + double y2; + struct rect clip; + + current_widget = widget; + current_cr = cr; + + cairo_clip_extents(cr, &x1, &y1, &x2, &y2); + + if (tv->tree_flags == TREE_SSLCERT) { + ssl_current_session = tv->ssl_data; + } + + clip.x0 = x1; + clip.y0 = y1; + clip.x1 = x2; + clip.y1 = y2; + + nsgtk_cw->draw(nsgtk_cw, &clip); + + current_widget = NULL; + + return FALSE; +} + +#else + +/* signal handler for core window redraw */ +static gboolean +nsgtk_cw_draw_event(GtkWidget *widget, + GdkEventExpose *event, + gpointer g) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g; + struct rect clip; + + clip.x0 = event->area.x; + clip.y0 = event->area.y; + clip.x1 = event->area.x + event->area.width; + clip.y1 = event->area.y + event->area.height; + + current_widget = widget; + current_cr = gdk_cairo_create(nsgtk_widget_get_window(widget)); + + nsgtk_cw->draw(nsgtk_cw, &clip); + + current_widget = NULL; + cairo_destroy(current_cr); + + return FALSE; +} + +#endif + +/** + * callback from core to request a redraw + */ +static void +nsgtk_cw_redraw_request(struct core_window *cw, const struct rect *r) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw; + + gtk_widget_queue_draw_area(GTK_WIDGET(nsgtk_cw->drawing_area), + r->x0, r->y0, + r->x1 - r->x0, r->y1 - r->y0); +} + + +static void +nsgtk_cw_update_size(struct core_window *cw, int width, int height) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw; + + gtk_widget_set_size_request(GTK_WIDGET(nsgtk_cw->drawing_area), + width, height); +} + + +static void +nsgtk_cw_scroll_visible(struct core_window *cw, const struct rect *r) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw; + int y = 0, height = 0, y0, y1; + gdouble page; + GtkAdjustment *vadj; + + vadj = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled); + + assert(vadj); + + g_object_get(vadj, "page-size", &page, NULL); + + y0 = (int)(gtk_adjustment_get_value(vadj)); + y1 = y0 + page; + + if ((y >= y0) && (y + height <= y1)) + return; + if (y + height > y1) + y0 = y0 + (y + height - y1); + if (y < y0) + y0 = y; + gtk_adjustment_set_value(vadj, y0); +} + + +static void +nsgtk_cw_get_window_dimensions(struct core_window *cw, int *width, int *height) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw; + GtkAdjustment *vadj; + GtkAdjustment *hadj; + gdouble page; + + if (width != NULL) { + hadj = gtk_scrolled_window_get_hadjustment(nsgtk_cw->scrolled); + g_object_get(hadj, "page-size", &page, NULL); + *width = page; + } + + if (height != NULL) { + vadj = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled); + g_object_get(vadj, "page-size", &page, NULL); + *height = page; + }} + + +static void +nsgtk_cw_drag_status(struct core_window *cw, core_window_drag_status ds) +{ + struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw; + nsgtk_cw->drag_staus = ds; +} + + +struct core_window_callback_table nsgtk_cw_cb_table = { + .redraw_request = nsgtk_cw_redraw_request, + .update_size = nsgtk_cw_update_size, + .scroll_visible = nsgtk_cw_scroll_visible, + .get_window_dimensions = nsgtk_cw_get_window_dimensions, + .drag_status = nsgtk_cw_drag_status +}; + +/* exported function documented gtk/corewindow.h */ +nserror nsgtk_corewindow_init(struct nsgtk_corewindow *nsgtk_cw) +{ + nsgtk_cw->cb_table = &nsgtk_cw_cb_table; + + /* input method setup */ + nsgtk_cw->input_method = gtk_im_multicontext_new(); + gtk_im_context_set_client_window(nsgtk_cw->input_method, + gtk_widget_get_parent_window(GTK_WIDGET(nsgtk_cw->drawing_area))); + gtk_im_context_set_use_preedit(nsgtk_cw->input_method, FALSE); + + g_signal_connect(G_OBJECT(nsgtk_cw->input_method), + "commit", + G_CALLBACK(nsgtk_cw_input_method_commit), + nsgtk_cw); + + nsgtk_connect_draw_event(GTK_WIDGET(nsgtk_cw->drawing_area), + G_CALLBACK(nsgtk_cw_draw_event), + nsgtk_cw); + + g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area), + "button-press-event", + G_CALLBACK(nsgtk_cw_button_press_event), + nsgtk_cw); + + g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area), + "button-release-event", + G_CALLBACK(nsgtk_cw_button_release_event), + nsgtk_cw); + + g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area), + "motion-notify-event", + G_CALLBACK(nsgtk_cw_motion_notify_event), + nsgtk_cw); + + g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area), + "key-press-event", + G_CALLBACK(nsgtk_cw_keypress_event), + nsgtk_cw); + + g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area), + "key-release-event", + G_CALLBACK(nsgtk_cw_keyrelease_event), + nsgtk_cw); + + nsgtk_widget_override_background_color( + GTK_WIDGET(nsgtk_cw->drawing_area), + GTK_STATE_NORMAL, + 0, 0xffff, 0xffff, 0xffff); + + return NSERROR_OK; +} + +nserror nsgtk_corewindow_fini(struct nsgtk_corewindow *nsgtk_cw) +{ + g_object_unref(nsgtk_cw->input_method); + + return NSERROR_OK; +} diff --git a/frontends/gtk/corewindow.h b/frontends/gtk/corewindow.h new file mode 100644 index 000000000..d6f3011ba --- /dev/null +++ b/frontends/gtk/corewindow.h @@ -0,0 +1,104 @@ +/* + * Copyright 2016 Vincent Sanders + * + * 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 . + */ + +#ifndef GTK_COREWINDOW_H +#define GTK_COREWINDOW_H + +#include "desktop/core_window.h" + +/** + * nsgtk core window mouse state + */ +struct nsgtk_corewindow_mouse { + browser_mouse_state state; /**< last event status */ + bool pressed; + int pressed_x; + int pressed_y; + int last_x; + int last_y; +}; + +/** + * nsgtk core window state + */ +struct nsgtk_corewindow { + /* public variables */ + /** GTK drawable widget */ + GtkDrawingArea *drawing_area; + /** scrollable area drawing area is within */ + GtkScrolledWindow *scrolled; + + /* private variables */ + /** Input method */ + GtkIMContext *input_method; + /** table of callbacks for core window operations */ + struct core_window_callback_table *cb_table; + /** mouse state */ + struct nsgtk_corewindow_mouse mouse_state; + /** drag status set by core */ + core_window_drag_status drag_staus; + + /** + * callback to draw on drawable area of nsgtk core window + * + * \param nsgtk_cw The nsgtk core window structure. + * \param r The rectangle of the window that needs updating. + * \return NSERROR_OK on success otherwise apropriate error code + */ + nserror (*draw)(struct nsgtk_corewindow *nsgtk_cw, struct rect *r); + + /** + * callback for keypress on nsgtk core window + * + * \param nsgtk_cw The nsgtk core window structure. + * \param nskey The netsurf key code. + * \return NSERROR_OK if key processed, + * NSERROR_NOT_IMPLEMENTED if key not processed + * otherwise apropriate error code + */ + nserror (*key)(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey); + + /** + * callback for mouse event on nsgtk core window + * + * \param nsgtk_cw The nsgtk core window structure. + * \param mouse_state mouse state + * \param x location of event + * \param y location of event + * \return NSERROR_OK on sucess otherwise apropriate error code. + */ + nserror (*mouse)(struct nsgtk_corewindow *nsgtk_cw, browser_mouse_state mouse_state, int x, int y); +}; + +/** + * initialise elements of gtk core window. + * + * \param nsgtk_cw A gtk core window structure to initialise + * \return NSERROR_OK on successful initialisation otherwise error code. + */ +nserror nsgtk_corewindow_init(struct nsgtk_corewindow *nsgtk_cw); + +/** + * finalise elements of gtk core window. + * + * \param nsgtk_cw A gtk core window structure to initialise + * \return NSERROR_OK on successful finalisation otherwise error code. + */ +nserror nsgtk_corewindow_fini(struct nsgtk_corewindow *nsgtk_cw); + +#endif -- cgit v1.2.3