From 2622adaa1fd3a6f24ed3ba527ee132148fd25beb Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 16 May 2012 19:57:43 +0000 Subject: allow netsurf to build with gtk3 svn path=/trunk/netsurf/; revision=13926 --- gtk/window.c | 479 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 283 insertions(+), 196 deletions(-) (limited to 'gtk/window.c') diff --git a/gtk/window.c b/gtk/window.c index 14a17df40..bf5f022da 100644 --- a/gtk/window.c +++ b/gtk/window.c @@ -22,7 +22,9 @@ #include #include +#include #include +#include #include "content/hlcache.h" #include "gtk/window.h" @@ -43,6 +45,8 @@ #include "utils/log.h" #include "utils/utils.h" +extern const GdkPixdata menu_cursor_pixdata; + struct gui_window { /** The gtk scaffold object containing menu, buttons, url bar, [tabs], * drawing area, etc that may contain one or more gui_windows. @@ -143,10 +147,12 @@ float nsgtk_get_scale_for_gui(struct gui_window *g) return g->bw->scale; } -static gboolean nsgtk_window_expose_event(GtkWidget *widget, - GdkEventExpose *event, gpointer data) +#if GTK_CHECK_VERSION(3,0,0) + +static gboolean +nsgtk_window_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data) { - struct gui_window *g = data; + struct gui_window *gw = data; struct gui_window *z; struct rect clip; struct redraw_context ctx = { @@ -155,34 +161,85 @@ static gboolean nsgtk_window_expose_event(GtkWidget *widget, .plot = &nsgtk_plotters }; - assert(g); - assert(g->bw); + double x1; + double y1; + double x2; + double y2; + + assert(gw); + assert(gw->bw); + + for (z = window_list; z && z != gw; z = z->next) + continue; + assert(z); + assert(GTK_WIDGET(gw->layout) == widget); + + current_widget = (GtkWidget *)gw->layout; + current_cr = cr; + + cairo_clip_extents(cr, &x1, &y1, &x2, &y2); + + clip.x0 = x1; + clip.y0 = y1; + clip.x1 = x2; + clip.y1 = y2; + + browser_window_redraw(gw->bw, 0, 0, &clip, &ctx); + + if (gw->careth != 0) { + nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth); + } + + current_widget = NULL; + + return FALSE; +} + +#else + +static gboolean +nsgtk_window_draw_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) +{ + struct gui_window *gw = data; + struct gui_window *z; + struct rect clip; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &nsgtk_plotters + }; - for (z = window_list; z && z != g; z = z->next) + assert(gw); + assert(gw->bw); + + for (z = window_list; z && z != gw; z = z->next) continue; assert(z); - assert(GTK_WIDGET(g->layout) == widget); + assert(GTK_WIDGET(gw->layout) == widget); - current_widget = (GtkWidget *)g->layout; - current_cr = gdk_cairo_create(g->layout->bin_window); + current_widget = (GtkWidget *)gw->layout; + current_cr = gdk_cairo_create(gtk_layout_get_bin_window(gw->layout)); 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; - browser_window_redraw(g->bw, 0, 0, &clip, &ctx); + browser_window_redraw(gw->bw, 0, 0, &clip, &ctx); - if (g->careth != 0) { - nsgtk_plot_caret(g->caretx, g->carety, g->careth); + if (gw->careth != 0) { + nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth); } - current_widget = NULL; cairo_destroy(current_cr); + current_widget = NULL; + return FALSE; } +#endif + static gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) { @@ -320,79 +377,102 @@ static gboolean nsgtk_window_scroll_event(GtkWidget *widget, { struct gui_window *g = data; double value; - GtkAdjustment *vscroll = gtk_layout_get_vadjustment(g->layout); - GtkAdjustment *hscroll = gtk_layout_get_hadjustment(g->layout); - GtkAdjustment *scroll; - const GtkAllocation *const alloc = - >K_WIDGET(g->layout)->allocation; + GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout); + GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout); + GtkAllocation alloc; + LOG(("%d", event->direction)); switch (event->direction) { case GDK_SCROLL_LEFT: if (browser_window_scroll_at_point(g->bw, event->x / g->bw->scale, event->y / g->bw->scale, - -100, 0) == true) - /* Core handled it */ - return TRUE; - - scroll = hscroll; - value = gtk_adjustment_get_value(scroll) - - (scroll->step_increment * 2); - if (value < scroll->lower) - value = scroll->lower; + -100, 0) != true) { + /* core did not handle event do horizontal scroll */ + + value = gtk_adjustment_get_value(hscroll) - + (gtk_adjustment_get_step_increment(hscroll) *2); + + if (value < gtk_adjustment_get_lower(hscroll)) { + value = gtk_adjustment_get_lower(hscroll); + } + + gtk_adjustment_set_value(hscroll, value); + } break; case GDK_SCROLL_UP: if (browser_window_scroll_at_point(g->bw, event->x / g->bw->scale, event->y / g->bw->scale, - 0, -100) == true) - /* Core handled it */ - return TRUE; - - scroll = vscroll; - value = gtk_adjustment_get_value(scroll) - - (scroll->step_increment * 2); - if (value < scroll->lower) - value = scroll->lower; + 0, -100) != true) { + /* core did not handle event change vertical + * adjustment. + */ + + value = gtk_adjustment_get_value(vscroll) - + (gtk_adjustment_get_step_increment(vscroll) * 2); + + if (value < gtk_adjustment_get_lower(vscroll)) { + value = gtk_adjustment_get_lower(vscroll); + } + + gtk_adjustment_set_value(vscroll, value); + } break; case GDK_SCROLL_RIGHT: if (browser_window_scroll_at_point(g->bw, event->x / g->bw->scale, event->y / g->bw->scale, - 100, 0) == true) - /* Core handled it */ - return TRUE; - - scroll = hscroll; - value = gtk_adjustment_get_value(scroll) + - (scroll->step_increment * 2); - if (value > scroll->upper - alloc->width) - value = scroll->upper - alloc->width; + 100, 0) != true) { + + /* core did not handle event change horizontal + * adjustment. + */ + + value = gtk_adjustment_get_value(hscroll) + + (gtk_adjustment_get_step_increment(hscroll) * 2); + + /* @todo consider gtk_widget_get_allocated_width() */ + gtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); + + if (value > gtk_adjustment_get_upper(hscroll) - alloc.width) { + value = gtk_adjustment_get_upper(hscroll) - + alloc.width; + } + + gtk_adjustment_set_value(hscroll, value); + } break; case GDK_SCROLL_DOWN: if (browser_window_scroll_at_point(g->bw, event->x / g->bw->scale, event->y / g->bw->scale, - 0, 100) == true) - /* Core handled it */ - return TRUE; - - scroll = vscroll; - value = gtk_adjustment_get_value(scroll) + - (scroll->step_increment * 2); - if (value > scroll->upper - alloc->height) - value = scroll->upper - alloc->height; + 0, 100) != true) { + /* core did not handle event change vertical + * adjustment. + */ + + value = gtk_adjustment_get_value(vscroll) + + (gtk_adjustment_get_step_increment(vscroll) * 2); + /* @todo consider gtk_widget_get_allocated_height */ + gtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); + + if (value > gtk_adjustment_get_upper(vscroll) - alloc.height) { + value = gtk_adjustment_get_upper(vscroll) - + alloc.height; + } + + gtk_adjustment_set_value(vscroll, value); + } break; default: - return TRUE; + break; } - gtk_adjustment_set_value(scroll, value); - return TRUE; } @@ -405,88 +485,104 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *widget, if (browser_window_key_press(g->bw, nskey)) return TRUE; - if ((event->state & 0x7) == 0) { - double value; - GtkAdjustment *vscroll = gtk_layout_get_vadjustment(g->layout); - GtkAdjustment *hscroll = gtk_layout_get_hadjustment(g->layout); - GtkAdjustment *scroll; - const GtkAllocation *const alloc = - >K_WIDGET(g->layout)->allocation; - - switch (event->keyval) { - default: - return TRUE; - - case GDK_Home: - case GDK_KP_Home: - scroll = vscroll; - value = scroll->lower; - break; - - case GDK_End: - case GDK_KP_End: - scroll = vscroll; - value = scroll->upper - alloc->height; - if (value < scroll->lower) - value = scroll->lower; - break; - - case GDK_Left: - case GDK_KP_Left: - scroll = hscroll; - value = gtk_adjustment_get_value(scroll) - - scroll->step_increment; - if (value < scroll->lower) - value = scroll->lower; - break; - - case GDK_Up: - case GDK_KP_Up: - scroll = vscroll; - value = gtk_adjustment_get_value(scroll) - - scroll->step_increment; - if (value < scroll->lower) - value = scroll->lower; - break; - - case GDK_Right: - case GDK_KP_Right: - scroll = hscroll; - value = gtk_adjustment_get_value(scroll) + - scroll->step_increment; - if (value > scroll->upper - alloc->width) - value = scroll->upper - alloc->width; - break; - - case GDK_Down: - case GDK_KP_Down: - scroll = vscroll; - value = gtk_adjustment_get_value(scroll) + - scroll->step_increment; - if (value > scroll->upper - alloc->height) - value = scroll->upper - alloc->height; - break; - - case GDK_Page_Up: - case GDK_KP_Page_Up: - scroll = vscroll; - value = gtk_adjustment_get_value(scroll) - - scroll->page_increment; - if (value < scroll->lower) - value = scroll->lower; - break; - - case GDK_Page_Down: - case GDK_KP_Page_Down: - scroll = vscroll; - value = gtk_adjustment_get_value(scroll) + - scroll->page_increment; - if (value > scroll->upper - alloc->height) - value = scroll->upper - alloc->height; - break; - } + if ((event->state & 0x7) != 0) + return TRUE; + + double value; + GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout); + GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout); + GtkAllocation alloc; + + /* @todo consider gtk_widget_get_allocated_width() */ + gtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); + + switch (event->keyval) { + + case GDK_KEY(Home): + case GDK_KEY(KP_Home): + value = gtk_adjustment_get_lower(vscroll); + gtk_adjustment_set_value(vscroll, value); + break; + + case GDK_KEY(End): + case GDK_KEY(KP_End): + value = gtk_adjustment_get_upper(vscroll) - alloc.height; + + if (value < gtk_adjustment_get_lower(vscroll)) + value = gtk_adjustment_get_lower(vscroll); + + gtk_adjustment_set_value(vscroll, value); + break; + + case GDK_KEY(Left): + case GDK_KEY(KP_Left): + value = gtk_adjustment_get_value(hscroll) - + gtk_adjustment_get_step_increment(hscroll); + + if (value < gtk_adjustment_get_lower(hscroll)) + value = gtk_adjustment_get_lower(hscroll); + + gtk_adjustment_set_value(hscroll, value); + break; + + case GDK_KEY(Up): + case GDK_KEY(KP_Up): + value = gtk_adjustment_get_value(vscroll) - + gtk_adjustment_get_step_increment(vscroll); + + if (value < gtk_adjustment_get_lower(vscroll)) + value = gtk_adjustment_get_lower(vscroll); + + gtk_adjustment_set_value(vscroll, value); + break; + + case GDK_KEY(Right): + case GDK_KEY(KP_Right): + value = gtk_adjustment_get_value(hscroll) + + gtk_adjustment_get_step_increment(hscroll); + + if (value > gtk_adjustment_get_upper(hscroll) - alloc.width) + value = gtk_adjustment_get_upper(hscroll) - alloc.width; + + gtk_adjustment_set_value(hscroll, value); + break; + + case GDK_KEY(Down): + case GDK_KEY(KP_Down): + value = gtk_adjustment_get_value(vscroll) + + gtk_adjustment_get_step_increment(vscroll); + + if (value > gtk_adjustment_get_upper(vscroll) - alloc.height) + value = gtk_adjustment_get_upper(vscroll) - alloc.height; + + gtk_adjustment_set_value(vscroll, value); + break; + + case GDK_KEY(Page_Up): + case GDK_KEY(KP_Page_Up): + value = gtk_adjustment_get_value(vscroll) - + gtk_adjustment_get_page_increment(vscroll); + + if (value < gtk_adjustment_get_lower(vscroll)) + value = gtk_adjustment_get_lower(vscroll); + + gtk_adjustment_set_value(vscroll, value); + break; + + case GDK_KEY(Page_Down): + case GDK_KEY(KP_Page_Down): + value = gtk_adjustment_get_value(vscroll) + + gtk_adjustment_get_page_increment(vscroll); + + if (value > gtk_adjustment_get_upper(vscroll) - alloc.height) + value = gtk_adjustment_get_upper(vscroll) - alloc.height; + + gtk_adjustment_set_value(vscroll, value); + break; + + default: + break; - gtk_adjustment_set_value(scroll, value); } return TRUE; @@ -558,26 +654,27 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, /* Construct our primary elements */ /* top-level document (not a frame) => create a new tab */ - GladeXML *xml = glade_xml_new(glade_file_location->netsurf, - "tabContents", NULL); - if (!xml) { - warn_user("MiscError", "Failed to create tab contents"); - free(g); + GError* error = NULL; + GtkBuilder* xml = gtk_builder_new(); + if (!gtk_builder_add_from_file(xml, + glade_file_location->tabcontents, + &error)) { + g_warning ("Couldn't load builder file: %s", error->message); + g_error_free(error); return 0; } - GtkWidget *tab_contents = glade_xml_get_widget(xml, "tabContents"); - g->layout = GTK_LAYOUT(glade_xml_get_widget(xml, "layout")); - g->status_bar = GTK_LABEL(glade_xml_get_widget(xml, "status_bar")); - g->paned = GTK_PANED(glade_xml_get_widget(xml, "hpaned1")); + g->layout = GTK_LAYOUT(gtk_builder_get_object(xml, "layout")); + g->status_bar = GTK_LABEL(gtk_builder_get_object(xml, "status_bar")); + g->paned = GTK_PANED(gtk_builder_get_object(xml, "hpaned1")); /* connect the scrollbars to the layout widget */ - gtk_layout_set_hadjustment(g->layout, + nsgtk_layout_set_hadjustment(g->layout, gtk_range_get_adjustment(GTK_RANGE( - glade_xml_get_widget(xml, "hscrollbar")))); - gtk_layout_set_vadjustment(g->layout, + gtk_builder_get_object(xml, "hscrollbar")))); + nsgtk_layout_set_vadjustment(g->layout, gtk_range_get_adjustment(GTK_RANGE( - glade_xml_get_widget(xml, "vscrollbar")))); + gtk_builder_get_object(xml, "vscrollbar")))); /* add the tab to the scaffold */ bool tempback = true; @@ -592,6 +689,8 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, tempback = true; break; } + + GtkWidget *tab_contents = GTK_WIDGET(gtk_builder_get_object(xml, "tabContents")); g_object_set_data(G_OBJECT(tab_contents), "gui_window", g); nsgtk_tab_add(g, tab_contents, tempback); @@ -620,14 +719,15 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, nsgtk_widget_set_can_focus(GTK_WIDGET(g->layout), TRUE); /* set the default background colour of the drawing area to white. */ - gtk_widget_modify_bg(GTK_WIDGET(g->layout), GTK_STATE_NORMAL, - &((GdkColor) { 0, 0xffff, 0xffff, 0xffff } )); + nsgtk_widget_override_background_color(GTK_WIDGET(g->layout), + GTK_STATE_NORMAL, 0, 0xffff, 0xffff, 0xffff); + + + nsgtk_connect_draw_event(GTK_WIDGET(g->layout), G_CALLBACK(nsgtk_window_draw_event), g); #define CONNECT(obj, sig, callback, ptr) \ g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) - g->signalhandler[NSGTK_WINDOW_SIGNAL_REDRAW] = - CONNECT(g->layout, "expose_event", - nsgtk_window_expose_event, g); + CONNECT(g->layout, "motion_notify_event", nsgtk_window_motion_notify_event, g); g->signalhandler[NSGTK_WINDOW_SIGNAL_CLICK] = @@ -665,16 +765,19 @@ void nsgtk_reflow_all_windows(void) void nsgtk_window_process_reformats(void) { struct gui_window *g; + GtkAllocation alloc; browser_reformat_pending = false; for (g = window_list; g; g = g->next) { - GtkWidget *widget = GTK_WIDGET(g->layout); if (!g->bw->reformat_pending) continue; + g->bw->reformat_pending = false; - browser_window_reformat(g->bw, false, - widget->allocation.width, - widget->allocation.height); + + /* @todo consider gtk_widget_get_allocated_width() */ + gtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); + + browser_window_reformat(g->bw, false, alloc.width, alloc.height); } } @@ -797,8 +900,8 @@ void gui_window_set_status(struct gui_window *g, const char *text) bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) { - GtkAdjustment *vadj = gtk_layout_get_vadjustment(g->layout); - GtkAdjustment *hadj = gtk_layout_get_hadjustment(g->layout); + GtkAdjustment *vadj = nsgtk_layout_get_vadjustment(g->layout); + GtkAdjustment *hadj = nsgtk_layout_get_hadjustment(g->layout); assert(vadj); assert(hadj); @@ -811,8 +914,8 @@ 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) { - GtkAdjustment *vadj = gtk_layout_get_vadjustment(g->layout); - GtkAdjustment *hadj = gtk_layout_get_hadjustment(g->layout); + GtkAdjustment *vadj = nsgtk_layout_get_vadjustment(g->layout); + GtkAdjustment *hadj = nsgtk_layout_get_hadjustment(g->layout); gdouble vlower, vpage, vupper, hlower, hpage, hupper, x = (double)sx, y = (double)sy; assert(vadj); @@ -853,35 +956,13 @@ void gui_window_update_extent(struct gui_window *g) static GdkCursor *nsgtk_create_menu_cursor(void) { - static char menu_cursor_bits[] = { - 0x00, 0x00, 0x80, 0x7F, 0x88, 0x40, 0x9E, 0x5E, 0x88, 0x40, 0x80, 0x56, - 0x80, 0x40, 0x80, 0x5A, 0x80, 0x40, 0x80, 0x5E, 0x80, 0x40, 0x80, 0x56, - 0x80, 0x40, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, }; - - static char menu_cursor_mask_bits[] = { - 0xC0, 0xFF, 0xC8, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xC8, 0xFF, - 0xC0, 0xFF, 0xC0, 0xFF, 0xC0, 0xFF, 0xC0, 0xFF, 0xC0, 0xFF, 0xC0, 0xFF, - 0xC0, 0xFF, 0xC0, 0xFF, 0xC0, 0xFF, 0x00, 0x00, }; - - static GdkCursor *r; - static GdkColor fg = { 0, 0, 0, 0 }; - static GdkColor bg = { 0, 65535, 65535, 65535 }; - - GdkPixmap *source, *mask; - - if (r != NULL) - return r; - - source = gdk_bitmap_create_from_data(NULL, menu_cursor_bits, - 16, 16); - mask = gdk_bitmap_create_from_data (NULL, menu_cursor_mask_bits, - 16, 16); - - r = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 0, 3); - g_object_unref(source); - g_object_unref(mask); + GdkCursor *cursor = NULL; + GdkPixbuf *pixbuf; + pixbuf = gdk_pixbuf_from_pixdata(&menu_cursor_pixdata, FALSE, NULL); + cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, 0, 3); + g_object_unref (pixbuf); - return r; + return cursor; } void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) @@ -961,10 +1042,11 @@ void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) gtk_widget_get_display( GTK_WIDGET(g->layout)), cursortype); - gdk_window_set_cursor(GTK_WIDGET(g->layout)->window, cursor); + gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(g->layout)), + cursor); if (!nullcursor) - gdk_cursor_unref(cursor); + nsgdk_cursor_unref(cursor); } void gui_window_hide_pointer(struct gui_window *g) @@ -1015,8 +1097,13 @@ void gui_drag_save_selection(struct selection *s, struct gui_window *g) void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bool scaled) { - *width = GTK_WIDGET(g->layout)->allocation.width; - *height = GTK_WIDGET(g->layout)->allocation.height; + GtkAllocation alloc; + + /* @todo consider gtk_widget_get_allocated_width() */ + gtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); + + *width = alloc.width; + *height = alloc.height; if (scaled) { *width /= g->bw->scale; -- cgit v1.2.3