comparison gtk3/dw.c @ 2358:314d417e55c4

GTK3: Cache the cairo_t from the draw callback and use it for drawing. This fixes issues with GtkDrawingArea within a GtkScrolledWindow when contents of the scrolled window clip.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 08 Mar 2021 23:50:57 +0000
parents fad0821cb953
children 77686ad495ba
comparison
equal deleted inserted replaced
2357:c9b776655725 2358:314d417e55c4
1511 int (*exposefunc)(HWND, DWExpose *, void *) = work.func; 1511 int (*exposefunc)(HWND, DWExpose *, void *) = work.func;
1512 1512
1513 exp.x = exp.y = 0; 1513 exp.x = exp.y = 0;
1514 exp.width = gtk_widget_get_allocated_width(widget); 1514 exp.width = gtk_widget_get_allocated_width(widget);
1515 exp.height = gtk_widget_get_allocated_height(widget); 1515 exp.height = gtk_widget_get_allocated_height(widget);
1516 g_object_set_data(G_OBJECT(work.window), "_dw_expose", GINT_TO_POINTER(TRUE)); 1516 g_object_set_data(G_OBJECT(work.window), "_dw_cr", (gpointer)cr);
1517 retval = exposefunc(work.window, &exp, work.data); 1517 retval = exposefunc(work.window, &exp, work.data);
1518 g_object_set_data(G_OBJECT(work.window), "_dw_expose", NULL); 1518 g_object_set_data(G_OBJECT(work.window), "_dw_cr", NULL);
1519 } 1519 }
1520 return retval; 1520 return retval;
1521 } 1521 }
1522 1522
1523 static gint _combobox_select_event(GtkWidget *widget, gpointer data) 1523 static gint _combobox_select_event(GtkWidget *widget, gpointer data)
7322 */ 7322 */
7323 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) 7323 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
7324 { 7324 {
7325 int _locked_by_me = FALSE; 7325 int _locked_by_me = FALSE;
7326 cairo_t *cr = NULL; 7326 cairo_t *cr = NULL;
7327 int cached = FALSE;
7327 #if GTK_CHECK_VERSION(3,22,0) 7328 #if GTK_CHECK_VERSION(3,22,0)
7328 GdkDrawingContext *dc = NULL; 7329 GdkDrawingContext *dc = NULL;
7329 cairo_region_t *clip = NULL; 7330 cairo_region_t *clip = NULL;
7330 #endif 7331 #endif
7331 7332
7332 DW_MUTEX_LOCK; 7333 DW_MUTEX_LOCK;
7333 if(handle) 7334 if(handle)
7334 { 7335 {
7335 GdkDisplay *display = gdk_display_get_default(); 7336 GdkDisplay *display = gdk_display_get_default();
7336 7337
7337 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose")) 7338 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
7339 cached = TRUE;
7340 else if((display && GDK_IS_X11_DISPLAY(display)))
7338 { 7341 {
7339 GdkWindow *window = gtk_widget_get_window(handle); 7342 GdkWindow *window = gtk_widget_get_window(handle);
7340 /* Safety check for non-existant windows */ 7343 /* Safety check for non-existant windows */
7341 if(!window || !GDK_IS_WINDOW(window)) 7344 if(!window || !GDK_IS_WINDOW(window))
7342 { 7345 {
7376 */ 7379 */
7377 if(dc) 7380 if(dc)
7378 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); 7381 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc);
7379 else 7382 else
7380 #endif 7383 #endif
7381 cairo_destroy(cr); 7384 if(!cached)
7385 cairo_destroy(cr);
7382 } 7386 }
7383 DW_MUTEX_UNLOCK; 7387 DW_MUTEX_UNLOCK;
7384 } 7388 }
7385 7389
7386 /* Draw a line on a window (preferably a render window). 7390 /* Draw a line on a window (preferably a render window).
7394 */ 7398 */
7395 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) 7399 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
7396 { 7400 {
7397 int _locked_by_me = FALSE; 7401 int _locked_by_me = FALSE;
7398 cairo_t *cr = NULL; 7402 cairo_t *cr = NULL;
7403 int cached = FALSE;
7399 #if GTK_CHECK_VERSION(3,22,0) 7404 #if GTK_CHECK_VERSION(3,22,0)
7400 GdkDrawingContext *dc = NULL; 7405 GdkDrawingContext *dc = NULL;
7401 cairo_region_t *clip = NULL; 7406 cairo_region_t *clip = NULL;
7402 #endif 7407 #endif
7403 7408
7404 DW_MUTEX_LOCK; 7409 DW_MUTEX_LOCK;
7405 if(handle) 7410 if(handle)
7406 { 7411 {
7407 GdkDisplay *display = gdk_display_get_default(); 7412 GdkDisplay *display = gdk_display_get_default();
7408 7413
7409 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose")) 7414 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
7415 cached = TRUE;
7416 else if((display && GDK_IS_X11_DISPLAY(display)))
7410 { 7417 {
7411 GdkWindow *window = gtk_widget_get_window(handle); 7418 GdkWindow *window = gtk_widget_get_window(handle);
7412 /* Safety check for non-existant windows */ 7419 /* Safety check for non-existant windows */
7413 if(!window || !GDK_IS_WINDOW(window)) 7420 if(!window || !GDK_IS_WINDOW(window))
7414 { 7421 {
7449 */ 7456 */
7450 if(dc) 7457 if(dc)
7451 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); 7458 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc);
7452 else 7459 else
7453 #endif 7460 #endif
7454 cairo_destroy(cr); 7461 if(!cached)
7462 cairo_destroy(cr);
7455 } 7463 }
7456 DW_MUTEX_UNLOCK; 7464 DW_MUTEX_UNLOCK;
7457 } 7465 }
7458 7466
7459 /* Draw a closed polygon on a window (preferably a render window). 7467 /* Draw a closed polygon on a window (preferably a render window).
7467 */ 7475 */
7468 void dw_draw_polygon(HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y) 7476 void dw_draw_polygon(HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y)
7469 { 7477 {
7470 int _locked_by_me = FALSE; 7478 int _locked_by_me = FALSE;
7471 cairo_t *cr = NULL; 7479 cairo_t *cr = NULL;
7480 int cached = FALSE;
7472 int z; 7481 int z;
7473 #if GTK_CHECK_VERSION(3,22,0) 7482 #if GTK_CHECK_VERSION(3,22,0)
7474 GdkDrawingContext *dc = NULL; 7483 GdkDrawingContext *dc = NULL;
7475 cairo_region_t *clip = NULL; 7484 cairo_region_t *clip = NULL;
7476 #endif 7485 #endif
7478 DW_MUTEX_LOCK; 7487 DW_MUTEX_LOCK;
7479 if(handle) 7488 if(handle)
7480 { 7489 {
7481 GdkDisplay *display = gdk_display_get_default(); 7490 GdkDisplay *display = gdk_display_get_default();
7482 7491
7483 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose")) 7492 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
7493 cached = TRUE;
7494 else if((display && GDK_IS_X11_DISPLAY(display)))
7484 { 7495 {
7485 GdkWindow *window = gtk_widget_get_window(handle); 7496 GdkWindow *window = gtk_widget_get_window(handle);
7486 /* Safety check for non-existant windows */ 7497 /* Safety check for non-existant windows */
7487 if(!window || !GDK_IS_WINDOW(window)) 7498 if(!window || !GDK_IS_WINDOW(window))
7488 { 7499 {
7531 */ 7542 */
7532 if(dc) 7543 if(dc)
7533 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); 7544 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc);
7534 else 7545 else
7535 #endif 7546 #endif
7536 cairo_destroy(cr); 7547 if(!cached)
7548 cairo_destroy(cr);
7537 } 7549 }
7538 DW_MUTEX_UNLOCK; 7550 DW_MUTEX_UNLOCK;
7539 } 7551 }
7540 7552
7541 /* Draw a rectangle on a window (preferably a render window). 7553 /* Draw a rectangle on a window (preferably a render window).
7550 */ 7562 */
7551 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height) 7563 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height)
7552 { 7564 {
7553 int _locked_by_me = FALSE; 7565 int _locked_by_me = FALSE;
7554 cairo_t *cr = NULL; 7566 cairo_t *cr = NULL;
7567 int cached = FALSE;
7555 #if GTK_CHECK_VERSION(3,22,0) 7568 #if GTK_CHECK_VERSION(3,22,0)
7556 GdkDrawingContext *dc = NULL; 7569 GdkDrawingContext *dc = NULL;
7557 cairo_region_t *clip = NULL; 7570 cairo_region_t *clip = NULL;
7558 #endif 7571 #endif
7559 7572
7560 DW_MUTEX_LOCK; 7573 DW_MUTEX_LOCK;
7561 if(handle) 7574 if(handle)
7562 { 7575 {
7563 GdkDisplay *display = gdk_display_get_default(); 7576 GdkDisplay *display = gdk_display_get_default();
7564 7577
7565 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose")) 7578 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
7579 cached = TRUE;
7580 else if((display && GDK_IS_X11_DISPLAY(display)))
7566 { 7581 {
7567 GdkWindow *window = gtk_widget_get_window(handle); 7582 GdkWindow *window = gtk_widget_get_window(handle);
7568 /* Safety check for non-existant windows */ 7583 /* Safety check for non-existant windows */
7569 if(!window || !GDK_IS_WINDOW(window)) 7584 if(!window || !GDK_IS_WINDOW(window))
7570 { 7585 {
7612 */ 7627 */
7613 if(dc) 7628 if(dc)
7614 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); 7629 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc);
7615 else 7630 else
7616 #endif 7631 #endif
7617 cairo_destroy(cr); 7632 if(!cached)
7633 cairo_destroy(cr);
7618 } 7634 }
7619 DW_MUTEX_UNLOCK; 7635 DW_MUTEX_UNLOCK;
7620 } 7636 }
7621 7637
7622 /* Draw an arc on a window (preferably a render window). 7638 /* Draw an arc on a window (preferably a render window).
7634 */ 7650 */
7635 void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) 7651 void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2)
7636 { 7652 {
7637 int _locked_by_me = FALSE; 7653 int _locked_by_me = FALSE;
7638 cairo_t *cr = NULL; 7654 cairo_t *cr = NULL;
7655 int cached = FALSE;
7639 #if GTK_CHECK_VERSION(3,22,0) 7656 #if GTK_CHECK_VERSION(3,22,0)
7640 GdkDrawingContext *dc = NULL; 7657 GdkDrawingContext *dc = NULL;
7641 cairo_region_t *clip = NULL; 7658 cairo_region_t *clip = NULL;
7642 #endif 7659 #endif
7643 7660
7644 DW_MUTEX_LOCK; 7661 DW_MUTEX_LOCK;
7645 if(handle) 7662 if(handle)
7646 { 7663 {
7647 GdkDisplay *display = gdk_display_get_default(); 7664 GdkDisplay *display = gdk_display_get_default();
7648 7665
7649 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose")) 7666 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
7667 cached = TRUE;
7668 else if((display && GDK_IS_X11_DISPLAY(display)))
7650 { 7669 {
7651 GdkWindow *window = gtk_widget_get_window(handle); 7670 GdkWindow *window = gtk_widget_get_window(handle);
7652 /* Safety check for non-existant windows */ 7671 /* Safety check for non-existant windows */
7653 if(!window || !GDK_IS_WINDOW(window)) 7672 if(!window || !GDK_IS_WINDOW(window))
7654 { 7673 {
7708 */ 7727 */
7709 if(dc) 7728 if(dc)
7710 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); 7729 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc);
7711 else 7730 else
7712 #endif 7731 #endif
7713 cairo_destroy(cr); 7732 if(!cached)
7733 cairo_destroy(cr);
7714 } 7734 }
7715 DW_MUTEX_UNLOCK; 7735 DW_MUTEX_UNLOCK;
7716 } 7736 }
7717 7737
7718 /* Draw text on a window (preferably a render window). 7738 /* Draw text on a window (preferably a render window).
7725 */ 7745 */
7726 void dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, const char *text) 7746 void dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, const char *text)
7727 { 7747 {
7728 int _locked_by_me = FALSE; 7748 int _locked_by_me = FALSE;
7729 cairo_t *cr = NULL; 7749 cairo_t *cr = NULL;
7750 int cached = FALSE;
7730 PangoFontDescription *font; 7751 PangoFontDescription *font;
7731 char *tmpname, *fontname = "monospace 10"; 7752 char *tmpname, *fontname = "monospace 10";
7732 #if GTK_CHECK_VERSION(3,22,0) 7753 #if GTK_CHECK_VERSION(3,22,0)
7733 GdkDrawingContext *dc = NULL; 7754 GdkDrawingContext *dc = NULL;
7734 cairo_region_t *clip = NULL; 7755 cairo_region_t *clip = NULL;
7740 DW_MUTEX_LOCK; 7761 DW_MUTEX_LOCK;
7741 if(handle) 7762 if(handle)
7742 { 7763 {
7743 GdkDisplay *display = gdk_display_get_default(); 7764 GdkDisplay *display = gdk_display_get_default();
7744 7765
7745 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose")) 7766 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
7767 cached = TRUE;
7768 else if((display && GDK_IS_X11_DISPLAY(display)))
7746 { 7769 {
7747 GdkWindow *window = gtk_widget_get_window(handle); 7770 GdkWindow *window = gtk_widget_get_window(handle);
7748 /* Safety check for non-existant windows */ 7771 /* Safety check for non-existant windows */
7749 if(!window || !GDK_IS_WINDOW(window)) 7772 if(!window || !GDK_IS_WINDOW(window))
7750 { 7773 {
7828 */ 7851 */
7829 if(dc) 7852 if(dc)
7830 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); 7853 gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc);
7831 else 7854 else
7832 #endif 7855 #endif
7833 cairo_destroy(cr); 7856 if(!cached)
7857 cairo_destroy(cr);
7834 } 7858 }
7835 DW_MUTEX_UNLOCK; 7859 DW_MUTEX_UNLOCK;
7836 } 7860 }
7837 7861
7838 /* Query the width and height of a text string. 7862 /* Query the width and height of a text string.
8181 */ 8205 */
8182 int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight) 8206 int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight)
8183 { 8207 {
8184 int _locked_by_me = FALSE; 8208 int _locked_by_me = FALSE;
8185 cairo_t *cr = NULL; 8209 cairo_t *cr = NULL;
8210 int cached = FALSE;
8186 int retval = DW_ERROR_GENERAL; 8211 int retval = DW_ERROR_GENERAL;
8187 #if GTK_CHECK_VERSION(3,22,0) 8212 #if GTK_CHECK_VERSION(3,22,0)
8188 GdkDrawingContext *dc = NULL; 8213 GdkDrawingContext *dc = NULL;
8189 cairo_region_t *clip = NULL; 8214 cairo_region_t *clip = NULL;
8190 #endif 8215 #endif
8195 DW_MUTEX_LOCK; 8220 DW_MUTEX_LOCK;
8196 if(dest) 8221 if(dest)
8197 { 8222 {
8198 GdkDisplay *display = gdk_display_get_default(); 8223 GdkDisplay *display = gdk_display_get_default();
8199 8224
8200 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(dest), "_dw_expose")) 8225 if((cr = g_object_get_data(G_OBJECT(dest), "_dw_cr")))
8226 cached = TRUE;
8227 else if((display && GDK_IS_X11_DISPLAY(display)))
8201 { 8228 {
8202 GdkWindow *window = gtk_widget_get_window(dest); 8229 GdkWindow *window = gtk_widget_get_window(dest);
8203 /* Safety check for non-existant windows */ 8230 /* Safety check for non-existant windows */
8204 if(!window || !GDK_IS_WINDOW(window)) 8231 if(!window || !GDK_IS_WINDOW(window))
8205 { 8232 {
8250 */ 8277 */
8251 if(dc) 8278 if(dc)
8252 gdk_window_end_draw_frame(gtk_widget_get_window(dest), dc); 8279 gdk_window_end_draw_frame(gtk_widget_get_window(dest), dc);
8253 else 8280 else
8254 #endif 8281 #endif
8255 cairo_destroy(cr); 8282 if(!cached)
8283 cairo_destroy(cr);
8256 retval = DW_ERROR_NONE; 8284 retval = DW_ERROR_NONE;
8257 } 8285 }
8258 DW_MUTEX_UNLOCK; 8286 DW_MUTEX_UNLOCK;
8259 return retval; 8287 return retval;
8260 } 8288 }