# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1612338198 0 # Node ID 0e93b09ed0e137c292ddc2e781c90468646cd1e5 # Parent 7902be60c5424be2ebc7307ffcb0eff04ce41288 GTK4: Cache the cairo context during the drawing area callback. This allows drawing to work for now. However drawing outside of the callback to widgets is currently broken, and not entirely sure it can be fixed with GTK4. diff -r 7902be60c542 -r 0e93b09ed0e1 gtk4/dw.c --- a/gtk4/dw.c Wed Feb 03 06:40:36 2021 +0000 +++ b/gtk4/dw.c Wed Feb 03 07:43:18 2021 +0000 @@ -545,18 +545,20 @@ static gint _dw_expose_event(GtkWidget *widget, cairo_t *cr, int width, int height, gpointer data) { - SignalHandler work = _dw_get_signal_handler(data); int retval = FALSE; - if(work.window) + if(widget && GTK_IS_DRAWING_AREA(widget)) { DWExpose exp; - int (*exposefunc)(HWND, DWExpose *, void *) = work.func; + int (*exposefunc)(HWND, DWExpose *, void *) = g_object_get_data(G_OBJECT(widget), "_dw_expose_func"); exp.x = exp.y = 0; exp.width = width; exp.height = height; - retval = exposefunc(work.window, &exp, work.data); + /* Save the cairo context for use in the drawing functions */ + g_object_set_data(G_OBJECT(widget), "_dw_cr", (gpointer)cr); + retval = exposefunc((HWND)widget, &exp, data); + g_object_set_data(G_OBJECT(widget), "_dw_cr", NULL); } return retval; } @@ -5474,21 +5476,27 @@ { cairo_t *cr = NULL; GdkDrawContext *dc = NULL; + int cached = FALSE; if(handle) { - GtkNative *native = gtk_widget_get_native(handle); - GdkSurface *surface = gtk_native_get_surface(native); - - if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) - { - cairo_region_t *region = cairo_region_create(); - gdk_draw_context_begin_frame(dc, region); - cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); - cairo_region_destroy(region); - } + if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) + cached = TRUE; else - return; + { + GtkNative *native = gtk_widget_get_native(handle); + GdkSurface *surface = gtk_native_get_surface(native); + + if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) + { + cairo_region_t *region = cairo_region_create(); + gdk_draw_context_begin_frame(dc, region); + cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); + cairo_region_destroy(region); + } + else + return; + } } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5505,7 +5513,7 @@ */ if(dc) gdk_draw_context_end_frame(dc); - else + else if(!cached) cairo_destroy(cr); } } @@ -5523,21 +5531,27 @@ { cairo_t *cr = NULL; GdkDrawContext *dc = NULL; + int cached = FALSE; if(handle) { - GtkNative *native = gtk_widget_get_native(handle); - GdkSurface *surface = gtk_native_get_surface(native); - - if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) - { - cairo_region_t *region = cairo_region_create(); - gdk_draw_context_begin_frame(dc, region); - cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); - cairo_region_destroy(region); - } + if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) + cached = TRUE; else - return; + { + GtkNative *native = gtk_widget_get_native(handle); + GdkSurface *surface = gtk_native_get_surface(native); + + if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) + { + cairo_region_t *region = cairo_region_create(); + gdk_draw_context_begin_frame(dc, region); + cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); + cairo_region_destroy(region); + } + else + return; + } } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5555,7 +5569,7 @@ */ if(dc) gdk_draw_context_end_frame(dc); - else + else if(!cached) cairo_destroy(cr); } } @@ -5574,21 +5588,27 @@ cairo_t *cr = NULL; int z; GdkDrawContext *dc = NULL; + int cached = FALSE; if(handle) { - GtkNative *native = gtk_widget_get_native(handle); - GdkSurface *surface = gtk_native_get_surface(native); - - if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) - { - cairo_region_t *region = cairo_region_create(); - gdk_draw_context_begin_frame(dc, region); - cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); - cairo_region_destroy(region); - } + if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) + cached = TRUE; else - return; + { + GtkNative *native = gtk_widget_get_native(handle); + GdkSurface *surface = gtk_native_get_surface(native); + + if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) + { + cairo_region_t *region = cairo_region_create(); + gdk_draw_context_begin_frame(dc, region); + cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); + cairo_region_destroy(region); + } + else + return; + } } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5614,7 +5634,7 @@ */ if(dc) gdk_draw_context_end_frame(dc); - else + else if(!cached) cairo_destroy(cr); } } @@ -5633,21 +5653,27 @@ { cairo_t *cr = NULL; GdkDrawContext *dc = NULL; + int cached = FALSE; if(handle) { - GtkNative *native = gtk_widget_get_native(handle); - GdkSurface *surface = gtk_native_get_surface(native); - - if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) - { - cairo_region_t *region = cairo_region_create(); - gdk_draw_context_begin_frame(dc, region); - cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); - cairo_region_destroy(region); - } + if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) + cached = TRUE; else - return; + { + GtkNative *native = gtk_widget_get_native(handle); + GdkSurface *surface = gtk_native_get_surface(native); + + if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) + { + cairo_region_t *region = cairo_region_create(); + gdk_draw_context_begin_frame(dc, region); + cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); + cairo_region_destroy(region); + } + else + return; + } } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5672,7 +5698,7 @@ */ if(dc) gdk_draw_context_end_frame(dc); - else + else if(!cached) cairo_destroy(cr); } } @@ -5694,21 +5720,27 @@ { cairo_t *cr = NULL; GdkDrawContext *dc = NULL; + int cached = FALSE; if(handle) { - GtkNative *native = gtk_widget_get_native(handle); - GdkSurface *surface = gtk_native_get_surface(native); - - if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) - { - cairo_region_t *region = cairo_region_create(); - gdk_draw_context_begin_frame(dc, region); - cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); - cairo_region_destroy(region); - } + if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) + cached = TRUE; else - return; + { + GtkNative *native = gtk_widget_get_native(handle); + GdkSurface *surface = gtk_native_get_surface(native); + + if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) + { + cairo_region_t *region = cairo_region_create(); + gdk_draw_context_begin_frame(dc, region); + cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); + cairo_region_destroy(region); + } + else + return; + } } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5745,7 +5777,7 @@ */ if(dc) gdk_draw_context_end_frame(dc); - else + else if(!cached) cairo_destroy(cr); } } @@ -5764,24 +5796,30 @@ PangoFontDescription *font; char *tmpname, *fontname = "monospace 10"; GdkDrawContext *dc = NULL; + int cached = FALSE; if(!text) return; if(handle) { - GtkNative *native = gtk_widget_get_native(handle); - GdkSurface *surface = gtk_native_get_surface(native); - - if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) - { - cairo_region_t *region = cairo_region_create(); - gdk_draw_context_begin_frame(dc, region); - cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); - cairo_region_destroy(region); - } + if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) + cached = TRUE; else - return; + { + GtkNative *native = gtk_widget_get_native(handle); + GdkSurface *surface = gtk_native_get_surface(native); + + if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) + { + cairo_region_t *region = cairo_region_create(); + gdk_draw_context_begin_frame(dc, region); + cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); + cairo_region_destroy(region); + } + else + return; + } if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"))) fontname = tmpname; } @@ -5842,7 +5880,7 @@ */ if(dc) gdk_draw_context_end_frame(dc); - else + else if(!cached) cairo_destroy(cr); } } @@ -6161,24 +6199,30 @@ cairo_t *cr = NULL; int retval = DW_ERROR_GENERAL; GdkDrawContext *dc = NULL; + int cached = FALSE; if((!dest && (!destp || !destp->image)) || (!src && (!srcp || !srcp->image))) return retval; if(dest) { - GtkNative *native = gtk_widget_get_native(dest); - GdkSurface *surface = gtk_native_get_surface(native); - - if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) - { - cairo_region_t *region = cairo_region_create(); - gdk_draw_context_begin_frame(dc, region); - cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); - cairo_region_destroy(region); - } + if((cr = g_object_get_data(G_OBJECT(dest), "_dw_cr"))) + cached = TRUE; else - return retval; + { + GtkNative *native = gtk_widget_get_native(dest); + GdkSurface *surface = gtk_native_get_surface(native); + + if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface)))) + { + cairo_region_t *region = cairo_region_create(); + gdk_draw_context_begin_frame(dc, region); + cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc)); + cairo_region_destroy(region); + } + else + return retval; + } } else if(destp) cr = cairo_create(destp->image); @@ -6209,7 +6253,7 @@ */ if(dc) gdk_draw_context_end_frame(dc); - else + else if(!cached) cairo_destroy(cr); retval = DW_ERROR_NONE; } @@ -9539,9 +9583,8 @@ { if(GTK_IS_DRAWING_AREA(object)) { - /* TODO: Might need to use the disconnect paramater since this isn't a normal signal handler */ + g_object_set_data(object, "_dw_expose_func", sigfunc); gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(object), signal->func, data, NULL); - _dw_set_signal_handler(object, (HWND)object, sigfunc, data, signal->func, discfunc); return NULL; } return object;