Mercurial > dwindows
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 } |