comparison gtk4/dw.c @ 2337:ef078d219bfc

GTK4: Add a shadow surface to GtkDrawingArea widgets, which all the drawing functions draw on. When drawing to a widget add it to the dirty list if it doesn't already exist. dw_flush() will trigger a redraw on all dirty widgets, and then clear the dirty list.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 02 Mar 2021 14:55:01 +0000
parents dd1b2cc95c91
children b9b10bb1f689
comparison
equal deleted inserted replaced
2336:dd1b2cc95c91 2337:ef078d219bfc
384 384
385 #ifndef min 385 #ifndef min
386 # define min(a,b) (((a) < (b)) ? (a) : (b)) 386 # define min(a,b) (((a) < (b)) ? (a) : (b))
387 #endif 387 #endif
388 388
389 pthread_key_t _dw_fg_color_key; 389 static pthread_key_t _dw_fg_color_key;
390 pthread_key_t _dw_bg_color_key; 390 static pthread_key_t _dw_bg_color_key;
391 pthread_key_t _dw_event_key; 391 static pthread_key_t _dw_event_key;
392 392
393 static pthread_t _dw_thread = (pthread_t)-1; 393 static pthread_t _dw_thread = (pthread_t)-1;
394
395 static GList *_dw_dirty_list = NULL;
394 396
395 #define _DW_TREE_TYPE_CONTAINER 1 397 #define _DW_TREE_TYPE_CONTAINER 1
396 #define _DW_TREE_TYPE_TREE 2 398 #define _DW_TREE_TYPE_TREE 2
397 #define _DW_TREE_TYPE_LISTBOX 3 399 #define _DW_TREE_TYPE_LISTBOX 3
398 #define _DW_TREE_TYPE_COMBOBOX 4 400 #define _DW_TREE_TYPE_COMBOBOX 4
826 retval = sizefunc(work.window, width, height, work.data); 828 retval = sizefunc(work.window, width, height, work.data);
827 } 829 }
828 return retval; 830 return retval;
829 } 831 }
830 832
833 cairo_t *_dw_cairo_update(GtkWidget *widget, int width, int height)
834 {
835 cairo_t *wincr = g_object_get_data(G_OBJECT(widget), "_dw_cr");
836 cairo_surface_t *surface = g_object_get_data(G_OBJECT(widget), "_dw_cr_surface");
837
838 if(width == -1 && height == -1 && g_list_find(_dw_dirty_list, widget) == NULL)
839 _dw_dirty_list = g_list_append(_dw_dirty_list, widget);
840
841 if(width == -1)
842 width = gtk_widget_get_width(widget);
843 if(height == -1)
844 height = gtk_widget_get_height(widget);
845
846 if(!wincr || GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_width")) != width ||
847 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_height")) != height)
848 {
849 if(wincr)
850 cairo_destroy(wincr);
851 if(surface)
852 cairo_surface_destroy(surface);
853 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
854 wincr = cairo_create(surface);
855 /* Save the cairo context for use in the drawing functions */
856 g_object_set_data(G_OBJECT(widget), "_dw_cr", (gpointer)wincr);
857 g_object_set_data(G_OBJECT(widget), "_dw_cr_surface", (gpointer)surface);
858 g_object_set_data(G_OBJECT(widget), "_dw_width", GINT_TO_POINTER(width));
859 g_object_set_data(G_OBJECT(widget), "_dw_height", GINT_TO_POINTER(height));
860 }
861 return wincr;
862 }
863
831 static gint _dw_expose_event(GtkWidget *widget, cairo_t *cr, int width, int height, gpointer data) 864 static gint _dw_expose_event(GtkWidget *widget, cairo_t *cr, int width, int height, gpointer data)
832 { 865 {
833 int retval = FALSE; 866 int retval = FALSE;
834 867
835 if(widget && GTK_IS_DRAWING_AREA(widget)) 868 if(widget && GTK_IS_DRAWING_AREA(widget))
836 { 869 {
837 DWExpose exp; 870 DWExpose exp;
838 int (*exposefunc)(HWND, DWExpose *, void *) = g_object_get_data(G_OBJECT(widget), "_dw_expose_func"); 871 int (*exposefunc)(HWND, DWExpose *, void *) = g_object_get_data(G_OBJECT(widget), "_dw_expose_func");
872
873 _dw_cairo_update(widget, width, height);
839 874
840 exp.x = exp.y = 0; 875 exp.x = exp.y = 0;
841 exp.width = width; 876 exp.width = width;
842 exp.height = height; 877 exp.height = height;
843 /* Save the cairo context for use in the drawing functions */
844 g_object_set_data(G_OBJECT(widget), "_dw_cr", (gpointer)cr);
845 retval = exposefunc((HWND)widget, &exp, data); 878 retval = exposefunc((HWND)widget, &exp, data);
846 g_object_set_data(G_OBJECT(widget), "_dw_cr", NULL); 879 /* Copy the cached image to the outbut surface */
880 cairo_set_source_surface(cr, g_object_get_data(G_OBJECT(widget), "_dw_cr_surface"), 0, 0);
881 cairo_rectangle(cr, 0, 0, width, height);
882 cairo_fill(cr);
847 } 883 }
848 return retval; 884 return retval;
849 } 885 }
850 886
851 static gint _dw_combobox_select_event(GtkWidget *widget, gpointer data) 887 static gint _dw_combobox_select_event(GtkWidget *widget, gpointer data)
2191 pfont = pango_context_get_font_description(pcontext); 2227 pfont = pango_context_get_font_description(pcontext);
2192 if(pfont) 2228 if(pfont)
2193 { 2229 {
2194 int len, x; 2230 int len, x;
2195 2231
2196 font = pango_font_description_to_string( pfont ); 2232 font = pango_font_description_to_string(pfont);
2197 retfont = strdup(font); 2233 retfont = strdup(font);
2198 len = strlen(font); 2234 len = strlen(font);
2199 /* Convert to Dynamic Windows format if we can... */ 2235 /* Convert to Dynamic Windows format if we can... */
2200 if(len > 0 && isdigit(font[len-1])) 2236 if(len > 0 && isdigit(font[len-1]))
2201 { 2237 {
6444 DW_FUNCTION_ADD_PARAM4(handle, pixmap, x, y) 6480 DW_FUNCTION_ADD_PARAM4(handle, pixmap, x, y)
6445 DW_FUNCTION_NO_RETURN(dw_draw_point) 6481 DW_FUNCTION_NO_RETURN(dw_draw_point)
6446 DW_FUNCTION_RESTORE_PARAM4(handle, HWND, pixmap, HPIXMAP, x, int, y, int) 6482 DW_FUNCTION_RESTORE_PARAM4(handle, HWND, pixmap, HPIXMAP, x, int, y, int)
6447 { 6483 {
6448 cairo_t *cr = NULL; 6484 cairo_t *cr = NULL;
6449 GdkDrawContext *dc = NULL;
6450 int cached = FALSE; 6485 int cached = FALSE;
6451 6486
6452 if(handle) 6487 if(handle)
6453 { 6488 {
6454 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) 6489 if((cr = _dw_cairo_update(handle, -1, -1)))
6455 cached = TRUE; 6490 cached = TRUE;
6456 else
6457 {
6458 GtkNative *native = gtk_widget_get_native(handle);
6459 GdkSurface *surface = gtk_native_get_surface(native);
6460
6461 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
6462 {
6463 cairo_region_t *region = cairo_region_create();
6464 gdk_draw_context_begin_frame(dc, region);
6465 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
6466 cairo_region_destroy(region);
6467 }
6468 }
6469 } 6491 }
6470 else if(pixmap) 6492 else if(pixmap)
6471 cr = cairo_create(pixmap->image); 6493 cr = cairo_create(pixmap->image);
6472 if(cr) 6494 if(cr)
6473 { 6495 {
6478 cairo_move_to(cr, x, y); 6500 cairo_move_to(cr, x, y);
6479 cairo_stroke(cr); 6501 cairo_stroke(cr);
6480 /* If we are using a drawing context... 6502 /* If we are using a drawing context...
6481 * we don't own the cairo context so don't destroy it. 6503 * we don't own the cairo context so don't destroy it.
6482 */ 6504 */
6483 if(dc) 6505 if(!cached)
6484 gdk_draw_context_end_frame(dc);
6485 else if(!cached)
6486 cairo_destroy(cr); 6506 cairo_destroy(cr);
6487 } 6507 }
6488 DW_FUNCTION_RETURN_NOTHING; 6508 DW_FUNCTION_RETURN_NOTHING;
6489 } 6509 }
6490 6510
6501 DW_FUNCTION_ADD_PARAM6(handle, pixmap, x1, y1, x2, y2) 6521 DW_FUNCTION_ADD_PARAM6(handle, pixmap, x1, y1, x2, y2)
6502 DW_FUNCTION_NO_RETURN(dw_draw_line) 6522 DW_FUNCTION_NO_RETURN(dw_draw_line)
6503 DW_FUNCTION_RESTORE_PARAM6(handle, HWND, pixmap, HPIXMAP, x1, int, y1, int, x2, int, y2, int) 6523 DW_FUNCTION_RESTORE_PARAM6(handle, HWND, pixmap, HPIXMAP, x1, int, y1, int, x2, int, y2, int)
6504 { 6524 {
6505 cairo_t *cr = NULL; 6525 cairo_t *cr = NULL;
6506 GdkDrawContext *dc = NULL;
6507 int cached = FALSE; 6526 int cached = FALSE;
6508 6527
6509 if(handle) 6528 if(handle)
6510 { 6529 {
6511 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) 6530 if((cr = _dw_cairo_update(handle, -1, -1)))
6512 cached = TRUE; 6531 cached = TRUE;
6513 else
6514 {
6515 GtkNative *native = gtk_widget_get_native(handle);
6516 GdkSurface *surface = gtk_native_get_surface(native);
6517
6518 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
6519 {
6520 cairo_region_t *region = cairo_region_create();
6521 gdk_draw_context_begin_frame(dc, region);
6522 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
6523 cairo_region_destroy(region);
6524 }
6525 }
6526 } 6532 }
6527 else if(pixmap) 6533 else if(pixmap)
6528 cr = cairo_create(pixmap->image); 6534 cr = cairo_create(pixmap->image);
6529 if(cr) 6535 if(cr)
6530 { 6536 {
6536 cairo_line_to(cr, x2, y2); 6542 cairo_line_to(cr, x2, y2);
6537 cairo_stroke(cr); 6543 cairo_stroke(cr);
6538 /* If we are using a drawing context... 6544 /* If we are using a drawing context...
6539 * we don't own the cairo context so don't destroy it. 6545 * we don't own the cairo context so don't destroy it.
6540 */ 6546 */
6541 if(dc) 6547 if(!cached)
6542 gdk_draw_context_end_frame(dc);
6543 else if(!cached)
6544 cairo_destroy(cr); 6548 cairo_destroy(cr);
6545 } 6549 }
6546 DW_FUNCTION_RETURN_NOTHING; 6550 DW_FUNCTION_RETURN_NOTHING;
6547 } 6551 }
6548 6552
6560 DW_FUNCTION_NO_RETURN(dw_draw_polygon) 6564 DW_FUNCTION_NO_RETURN(dw_draw_polygon)
6561 DW_FUNCTION_RESTORE_PARAM6(handle, HWND, pixmap, HPIXMAP, flags, int, npoints, int, x, int *, y, int *) 6565 DW_FUNCTION_RESTORE_PARAM6(handle, HWND, pixmap, HPIXMAP, flags, int, npoints, int, x, int *, y, int *)
6562 { 6566 {
6563 cairo_t *cr = NULL; 6567 cairo_t *cr = NULL;
6564 int z; 6568 int z;
6565 GdkDrawContext *dc = NULL;
6566 int cached = FALSE; 6569 int cached = FALSE;
6567 6570
6568 if(handle) 6571 if(handle)
6569 { 6572 {
6570 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) 6573 if((cr = _dw_cairo_update(handle, -1, -1)))
6571 cached = TRUE; 6574 cached = TRUE;
6572 else
6573 {
6574 GtkNative *native = gtk_widget_get_native(handle);
6575 GdkSurface *surface = gtk_native_get_surface(native);
6576
6577 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
6578 {
6579 cairo_region_t *region = cairo_region_create();
6580 gdk_draw_context_begin_frame(dc, region);
6581 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
6582 cairo_region_destroy(region);
6583 }
6584 }
6585 } 6575 }
6586 else if(pixmap) 6576 else if(pixmap)
6587 cr = cairo_create(pixmap->image); 6577 cr = cairo_create(pixmap->image);
6588 if(cr) 6578 if(cr)
6589 { 6579 {
6603 cairo_fill(cr); 6593 cairo_fill(cr);
6604 cairo_stroke(cr); 6594 cairo_stroke(cr);
6605 /* If we are using a drawing context... 6595 /* If we are using a drawing context...
6606 * we don't own the cairo context so don't destroy it. 6596 * we don't own the cairo context so don't destroy it.
6607 */ 6597 */
6608 if(dc) 6598 if(!cached)
6609 gdk_draw_context_end_frame(dc);
6610 else if(!cached)
6611 cairo_destroy(cr); 6599 cairo_destroy(cr);
6612 } 6600 }
6613 DW_FUNCTION_RETURN_NOTHING; 6601 DW_FUNCTION_RETURN_NOTHING;
6614 } 6602 }
6615 6603
6627 DW_FUNCTION_ADD_PARAM7(handle, pixmap, flags, x, y, width, height) 6615 DW_FUNCTION_ADD_PARAM7(handle, pixmap, flags, x, y, width, height)
6628 DW_FUNCTION_NO_RETURN(dw_draw_rect) 6616 DW_FUNCTION_NO_RETURN(dw_draw_rect)
6629 DW_FUNCTION_RESTORE_PARAM7(handle, HWND, pixmap, HPIXMAP, flags, int, x, int, y, int, width, int, height, int) 6617 DW_FUNCTION_RESTORE_PARAM7(handle, HWND, pixmap, HPIXMAP, flags, int, x, int, y, int, width, int, height, int)
6630 { 6618 {
6631 cairo_t *cr = NULL; 6619 cairo_t *cr = NULL;
6632 GdkDrawContext *dc = NULL;
6633 int cached = FALSE; 6620 int cached = FALSE;
6634 6621
6635 if(handle) 6622 if(handle)
6636 { 6623 {
6637 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) 6624 if((cr = _dw_cairo_update(handle, -1, -1)))
6638 cached = TRUE; 6625 cached = TRUE;
6639 else
6640 {
6641 GtkNative *native = gtk_widget_get_native(handle);
6642 GdkSurface *surface = gtk_native_get_surface(native);
6643
6644 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
6645 {
6646 cairo_region_t *region = cairo_region_create();
6647 gdk_draw_context_begin_frame(dc, region);
6648 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
6649 cairo_region_destroy(region);
6650 }
6651 }
6652 } 6626 }
6653 else if(pixmap) 6627 else if(pixmap)
6654 cr = cairo_create(pixmap->image); 6628 cr = cairo_create(pixmap->image);
6655 if(cr) 6629 if(cr)
6656 { 6630 {
6669 cairo_fill(cr); 6643 cairo_fill(cr);
6670 cairo_stroke(cr); 6644 cairo_stroke(cr);
6671 /* If we are using a drawing context... 6645 /* If we are using a drawing context...
6672 * we don't own the cairo context so don't destroy it. 6646 * we don't own the cairo context so don't destroy it.
6673 */ 6647 */
6674 if(dc) 6648 if(!cached)
6675 gdk_draw_context_end_frame(dc);
6676 else if(!cached)
6677 cairo_destroy(cr); 6649 cairo_destroy(cr);
6678 } 6650 }
6679 DW_FUNCTION_RETURN_NOTHING; 6651 DW_FUNCTION_RETURN_NOTHING;
6680 } 6652 }
6681 6653
6696 DW_FUNCTION_ADD_PARAM9(handle, pixmap, flags, xorigin, yorigin, x1, y1, x2, y2) 6668 DW_FUNCTION_ADD_PARAM9(handle, pixmap, flags, xorigin, yorigin, x1, y1, x2, y2)
6697 DW_FUNCTION_NO_RETURN(dw_draw_arc) 6669 DW_FUNCTION_NO_RETURN(dw_draw_arc)
6698 DW_FUNCTION_RESTORE_PARAM9(handle, HWND, pixmap, HPIXMAP, flags, int, xorigin, int, yorigin, int, x1, int, y1, int, x2, int, y2, int) 6670 DW_FUNCTION_RESTORE_PARAM9(handle, HWND, pixmap, HPIXMAP, flags, int, xorigin, int, yorigin, int, x1, int, y1, int, x2, int, y2, int)
6699 { 6671 {
6700 cairo_t *cr = NULL; 6672 cairo_t *cr = NULL;
6701 GdkDrawContext *dc = NULL;
6702 int cached = FALSE; 6673 int cached = FALSE;
6703 6674
6704 if(handle) 6675 if(handle)
6705 { 6676 {
6706 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) 6677 if((cr = _dw_cairo_update(handle, -1, -1)))
6707 cached = TRUE; 6678 cached = TRUE;
6708 else
6709 {
6710 GtkNative *native = gtk_widget_get_native(handle);
6711 GdkSurface *surface = gtk_native_get_surface(native);
6712
6713 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
6714 {
6715 cairo_region_t *region = cairo_region_create();
6716 gdk_draw_context_begin_frame(dc, region);
6717 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
6718 cairo_region_destroy(region);
6719 }
6720 }
6721 } 6679 }
6722 else if(pixmap) 6680 else if(pixmap)
6723 cr = cairo_create(pixmap->image); 6681 cr = cairo_create(pixmap->image);
6724 if(cr) 6682 if(cr)
6725 { 6683 {
6750 cairo_fill(cr); 6708 cairo_fill(cr);
6751 cairo_stroke(cr); 6709 cairo_stroke(cr);
6752 /* If we are using a drawing context... 6710 /* If we are using a drawing context...
6753 * we don't own the cairo context so don't destroy it. 6711 * we don't own the cairo context so don't destroy it.
6754 */ 6712 */
6755 if(dc) 6713 if(!cached)
6756 gdk_draw_context_end_frame(dc);
6757 else if(!cached)
6758 cairo_destroy(cr); 6714 cairo_destroy(cr);
6759 } 6715 }
6760 DW_FUNCTION_RETURN_NOTHING; 6716 DW_FUNCTION_RETURN_NOTHING;
6761 } 6717 }
6762 6718
6776 if(text) 6732 if(text)
6777 { 6733 {
6778 cairo_t *cr = NULL; 6734 cairo_t *cr = NULL;
6779 PangoFontDescription *font; 6735 PangoFontDescription *font;
6780 char *tmpname, *fontname = "monospace 10"; 6736 char *tmpname, *fontname = "monospace 10";
6781 GdkDrawContext *dc = NULL;
6782 int cached = FALSE; 6737 int cached = FALSE;
6783 6738
6784 if(handle) 6739 if(handle)
6785 { 6740 {
6786 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr"))) 6741 if((cr = _dw_cairo_update(handle, -1, -1)))
6787 cached = TRUE; 6742 cached = TRUE;
6788 else
6789 {
6790 GtkNative *native = gtk_widget_get_native(handle);
6791 GdkSurface *surface = gtk_native_get_surface(native);
6792
6793 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
6794 {
6795 cairo_region_t *region = cairo_region_create();
6796 gdk_draw_context_begin_frame(dc, region);
6797 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
6798 cairo_region_destroy(region);
6799 }
6800 }
6801 if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"))) 6743 if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname")))
6802 fontname = tmpname; 6744 fontname = tmpname;
6803 } 6745 }
6804 else if(pixmap) 6746 else if(pixmap)
6805 { 6747 {
6854 pango_font_description_free(font); 6796 pango_font_description_free(font);
6855 } 6797 }
6856 /* If we are using a drawing context... 6798 /* If we are using a drawing context...
6857 * we don't own the cairo context so don't destroy it. 6799 * we don't own the cairo context so don't destroy it.
6858 */ 6800 */
6859 if(dc) 6801 if(!cached)
6860 gdk_draw_context_end_frame(dc);
6861 else if(!cached)
6862 cairo_destroy(cr); 6802 cairo_destroy(cr);
6863 } 6803 }
6864 } 6804 }
6865 DW_FUNCTION_RETURN_NOTHING; 6805 DW_FUNCTION_RETURN_NOTHING;
6866 } 6806 }
7109 pixmap->handle = handle; 7049 pixmap->handle = handle;
7110 } 7050 }
7111 DW_FUNCTION_RETURN_THIS(pixmap); 7051 DW_FUNCTION_RETURN_THIS(pixmap);
7112 } 7052 }
7113 7053
7054 static void _dw_flush_dirty(gpointer widget, gpointer data)
7055 {
7056 gtk_widget_queue_draw(GTK_WIDGET(widget));
7057 }
7058
7114 /* Call this after drawing to the screen to make sure 7059 /* Call this after drawing to the screen to make sure
7115 * anything you have drawn is visible. 7060 * anything you have drawn is visible.
7116 */ 7061 */
7117 void API dw_flush(void) 7062 DW_FUNCTION_DEFINITION(dw_flush, void)
7118 { 7063 DW_FUNCTION_ADD_PARAM
7064 DW_FUNCTION_NO_RETURN(dw_flush)
7065 {
7066 g_list_foreach(_dw_dirty_list, _dw_flush_dirty, NULL);
7067 g_list_free(_dw_dirty_list);
7068 _dw_dirty_list = NULL;
7069 DW_FUNCTION_RETURN_NOTHING;
7119 } 7070 }
7120 7071
7121 /* 7072 /*
7122 * Sets the font used by a specified pixmap. 7073 * Sets the font used by a specified pixmap.
7123 * Normally the pixmap font is obtained from the associated window handle. 7074 * Normally the pixmap font is obtained from the associated window handle.
7206 DW_FUNCTION_RESTORE_PARAM12(dest, HWND, destp, HPIXMAP, xdest, int, ydest, int, width, int, height, int, src, HWND, srcp, HPIXMAP, xsrc, int, ysrc, int, srcwidth, int, srcheight, int) 7157 DW_FUNCTION_RESTORE_PARAM12(dest, HWND, destp, HPIXMAP, xdest, int, ydest, int, width, int, height, int, src, HWND, srcp, HPIXMAP, xsrc, int, ysrc, int, srcwidth, int, srcheight, int)
7207 7158
7208 { 7159 {
7209 cairo_t *cr = NULL; 7160 cairo_t *cr = NULL;
7210 int retval = DW_ERROR_GENERAL; 7161 int retval = DW_ERROR_GENERAL;
7211 GdkDrawContext *dc = NULL;
7212 int cached = FALSE; 7162 int cached = FALSE;
7213 7163
7214 if(dest) 7164 if(dest)
7215 { 7165 {
7216 if((cr = g_object_get_data(G_OBJECT(dest), "_dw_cr"))) 7166 if((cr = _dw_cairo_update(dest, -1, -1)))
7217 cached = TRUE; 7167 cached = TRUE;
7218 else
7219 {
7220 GtkNative *native = gtk_widget_get_native(dest);
7221 GdkSurface *surface = gtk_native_get_surface(native);
7222
7223 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
7224 {
7225 cairo_region_t *region = cairo_region_create();
7226 gdk_draw_context_begin_frame(dc, region);
7227 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
7228 cairo_region_destroy(region);
7229 }
7230 }
7231 } 7168 }
7232 else if(destp) 7169 else if(destp)
7233 cr = cairo_create(destp->image); 7170 cr = cairo_create(destp->image);
7234 7171
7235 if(cr) 7172 if(cr)
7242 yscale = (double)height / (double)srcheight; 7179 yscale = (double)height / (double)srcheight;
7243 cairo_scale(cr, xscale, yscale); 7180 cairo_scale(cr, xscale, yscale);
7244 } 7181 }
7245 7182
7246 if(src) 7183 if(src)
7247 ; 7184 {
7248 #ifdef GTK3 /* TODO: See how to do this in GTK4 */ 7185 cairo_surface_t *surface = g_object_get_data(G_OBJECT(src), "_dw_cr_surface");
7249 gdk_cairo_set_source_window (cr, gtk_widget_get_window(src), (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); 7186 if(surface)
7250 #endif 7187 cairo_set_source_surface (cr, surface, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale);
7188 }
7251 else if(srcp) 7189 else if(srcp)
7252 cairo_set_source_surface (cr, srcp->image, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); 7190 cairo_set_source_surface (cr, srcp->image, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale);
7253 7191
7254 cairo_rectangle(cr, xdest / xscale, ydest / yscale, width, height); 7192 cairo_rectangle(cr, xdest / xscale, ydest / yscale, width, height);
7255 cairo_fill(cr); 7193 cairo_fill(cr);
7256 /* If we are using a drawing context... 7194 /* If we are using a drawing context...
7257 * we don't own the cairo context so don't destroy it. 7195 * we don't own the cairo context so don't destroy it.
7258 */ 7196 */
7259 if(dc) 7197 if(!cached)
7260 gdk_draw_context_end_frame(dc);
7261 else if(!cached)
7262 cairo_destroy(cr); 7198 cairo_destroy(cr);
7263 retval = DW_ERROR_NONE; 7199 retval = DW_ERROR_NONE;
7264 } 7200 }
7265 DW_FUNCTION_RETURN_THIS(retval); 7201 DW_FUNCTION_RETURN_THIS(retval);
7266 } 7202 }