comparison gtk3/dw.c @ 2343:347b0f97c295

GTK3: Back port Wayland fixes from the GTK4 code. Wayland can't draw to a widget outside of an expose event. Any attempts to draw to a widget outside of an expose will mark the widget as dirty. Calling dw_flush() will trigger expose events on all dirty widgets. On X11 draw directly as we used to do, dirty list should remain empty. This will allow code written with the assumption we can draw any time to function. In the future, design code to only draw in the expose callback.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 04 Mar 2021 02:00:23 +0000
parents 5437aed23151
children 88f7e871b283
comparison
equal deleted inserted replaced
2342:5437aed23151 2343:347b0f97c295
117 117
118 #ifndef min 118 #ifndef min
119 # define min(a,b) (((a) < (b)) ? (a) : (b)) 119 # define min(a,b) (((a) < (b)) ? (a) : (b))
120 #endif 120 #endif
121 121
122 pthread_key_t _dw_fg_color_key; 122 static pthread_key_t _dw_fg_color_key;
123 pthread_key_t _dw_bg_color_key; 123 static pthread_key_t _dw_bg_color_key;
124 pthread_key_t _dw_mutex_key; 124 static pthread_key_t _dw_mutex_key;
125 125
126 GtkWidget *last_window = NULL, *popup = NULL; 126 static GList *_dw_dirty_list = NULL;
127
128 static GtkWidget *_dw_popup = NULL;
127 129
128 static int _dw_ignore_click = 0, _dw_ignore_expand = 0; 130 static int _dw_ignore_click = 0, _dw_ignore_expand = 0;
129 static pthread_t _dw_thread = (pthread_t)-1; 131 static pthread_t _dw_thread = (pthread_t)-1;
130 132
131 void (*_dw_gdk_threads_init)(void) = NULL; 133 void (*_dw_gdk_threads_init)(void) = NULL;
1476 1478
1477 if(work.window && !_dw_ignore_click) 1479 if(work.window && !_dw_ignore_click)
1478 { 1480 {
1479 int (*activatefunc)(HWND, void *) = work.func; 1481 int (*activatefunc)(HWND, void *) = work.func;
1480 1482
1481 retval = activatefunc(popup ? popup : work.window, work.data); 1483 retval = activatefunc(_dw_popup ? _dw_popup : work.window, work.data);
1482 popup = NULL; 1484 _dw_popup = NULL;
1483 } 1485 }
1484 return retval; 1486 return retval;
1485 } 1487 }
1486 1488
1487 static gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data) 1489 static gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
1509 int (*exposefunc)(HWND, DWExpose *, void *) = work.func; 1511 int (*exposefunc)(HWND, DWExpose *, void *) = work.func;
1510 1512
1511 exp.x = exp.y = 0; 1513 exp.x = exp.y = 0;
1512 exp.width = gtk_widget_get_allocated_width(widget); 1514 exp.width = gtk_widget_get_allocated_width(widget);
1513 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));
1514 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);
1515 } 1519 }
1516 return retval; 1520 return retval;
1517 } 1521 }
1518 1522
1519 static gint _combobox_select_event(GtkWidget *widget, gpointer data) 1523 static gint _combobox_select_event(GtkWidget *widget, gpointer data)
3196 GtkWidget *box = dw_box_new(DW_VERT, 0); 3200 GtkWidget *box = dw_box_new(DW_VERT, 0);
3197 GtkWidget *grid = gtk_grid_new(); 3201 GtkWidget *grid = gtk_grid_new();
3198 3202
3199 gtk_widget_show_all(grid); 3203 gtk_widget_show_all(grid);
3200 3204
3201 last_window = tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL); 3205 tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3202 3206
3203 gtk_window_set_title(GTK_WINDOW(tmp), title); 3207 gtk_window_set_title(GTK_WINDOW(tmp), title);
3204 gtk_window_set_resizable(GTK_WINDOW(tmp), (flStyle & DW_FCF_SIZEBORDER) ? TRUE : FALSE); 3208 gtk_window_set_resizable(GTK_WINDOW(tmp), (flStyle & DW_FCF_SIZEBORDER) ? TRUE : FALSE);
3205 3209
3206 gtk_widget_realize(tmp); 3210 gtk_widget_realize(tmp);
3815 int _locked_by_me = FALSE; 3819 int _locked_by_me = FALSE;
3816 3820
3817 if(!menu || !*menu) 3821 if(!menu || !*menu)
3818 return; 3822 return;
3819 3823
3820 popup = parent; 3824 _dw_popup = parent;
3821 3825
3822 DW_MUTEX_LOCK; 3826 DW_MUTEX_LOCK;
3823 #if GTK_CHECK_VERSION(3,22,0) 3827 #if GTK_CHECK_VERSION(3,22,0)
3824 gtk_menu_popup_at_pointer(GTK_MENU(*menu), NULL); 3828 gtk_menu_popup_at_pointer(GTK_MENU(*menu), NULL);
3825 #else 3829 #else
3836 * x: Pointer to variable to store X coordinate. 3840 * x: Pointer to variable to store X coordinate.
3837 * y: Pointer to variable to store Y coordinate. 3841 * y: Pointer to variable to store Y coordinate.
3838 */ 3842 */
3839 void dw_pointer_query_pos(long *x, long *y) 3843 void dw_pointer_query_pos(long *x, long *y)
3840 { 3844 {
3845 int gx = 0, gy = 0;
3846 #ifdef GDK_WINDOWING_X11
3841 GdkModifierType state = 0; 3847 GdkModifierType state = 0;
3842 int gx, gy;
3843 int _locked_by_me = FALSE; 3848 int _locked_by_me = FALSE;
3844 GdkDisplay *display; 3849 GdkDisplay *display;
3845 3850
3846 DW_MUTEX_LOCK; 3851 DW_MUTEX_LOCK;
3847 #ifdef GDK_WINDOWING_X11
3848 display = gdk_display_get_default(); 3852 display = gdk_display_get_default();
3849 3853
3850 if(display && GDK_IS_X11_DISPLAY(display)) 3854 if(display && GDK_IS_X11_DISPLAY(display))
3851 { 3855 {
3852 #if GTK_CHECK_VERSION(3,20,0) 3856 #if GTK_CHECK_VERSION(3,20,0)
3857 GdkDevice *device = gdk_device_manager_get_client_pointer(manager); 3861 GdkDevice *device = gdk_device_manager_get_client_pointer(manager);
3858 #endif 3862 #endif
3859 gdk_window_get_device_position(gdk_x11_window_lookup_for_display(display, GDK_ROOT_WINDOW()), 3863 gdk_window_get_device_position(gdk_x11_window_lookup_for_display(display, GDK_ROOT_WINDOW()),
3860 device, &gx, &gy, &state); 3864 device, &gx, &gy, &state);
3861 } 3865 }
3866 DW_MUTEX_UNLOCK;
3862 #endif 3867 #endif
3863 if(x) 3868 if(x)
3864 *x = gx; 3869 *x = gx;
3865 if(y) 3870 if(y)
3866 *y = gy; 3871 *y = gy;
3867 DW_MUTEX_UNLOCK;
3868 } 3872 }
3869 3873
3870 /* 3874 /*
3871 * Sets the X and Y coordinates of the mouse pointer. 3875 * Sets the X and Y coordinates of the mouse pointer.
3872 * Parameters: 3876 * Parameters:
3876 void dw_pointer_set_pos(long x, long y) 3880 void dw_pointer_set_pos(long x, long y)
3877 { 3881 {
3878 #ifdef GDK_WINDOWING_X11 3882 #ifdef GDK_WINDOWING_X11
3879 int _locked_by_me = FALSE; 3883 int _locked_by_me = FALSE;
3880 GdkDisplay *display; 3884 GdkDisplay *display;
3881 GdkDevice *device;
3882 3885
3883 DW_MUTEX_LOCK; 3886 DW_MUTEX_LOCK;
3884 display = gdk_display_get_default(); 3887 display = gdk_display_get_default();
3885 3888
3886 if(display && GDK_IS_X11_DISPLAY(display)) 3889 if(display && GDK_IS_X11_DISPLAY(display))
7081 status = g_object_get_data(G_OBJECT(handle), "_dw_taskbar"); 7084 status = g_object_get_data(G_OBJECT(handle), "_dw_taskbar");
7082 g_object_unref(G_OBJECT(status)); 7085 g_object_unref(G_OBJECT(status));
7083 DW_MUTEX_UNLOCK; 7086 DW_MUTEX_UNLOCK;
7084 } 7087 }
7085 7088
7089 /* Make sure the widget is out of the dirty list if it is destroyed */
7090 static void _dw_render_destroy(GtkWidget *widget, gpointer data)
7091 {
7092 _dw_dirty_list = g_list_remove(_dw_dirty_list, widget);
7093 }
7094
7086 /* 7095 /*
7087 * Creates a rendering context widget (window) to be packed. 7096 * Creates a rendering context widget (window) to be packed.
7088 * Parameters: 7097 * Parameters:
7089 * id: An id to be used with dw_window_from_id. 7098 * id: An id to be used with dw_window_from_id.
7090 * Returns: 7099 * Returns:
7103 | GDK_BUTTON_RELEASE_MASK 7112 | GDK_BUTTON_RELEASE_MASK
7104 | GDK_KEY_PRESS_MASK 7113 | GDK_KEY_PRESS_MASK
7105 | GDK_POINTER_MOTION_MASK 7114 | GDK_POINTER_MOTION_MASK
7106 | GDK_POINTER_MOTION_HINT_MASK); 7115 | GDK_POINTER_MOTION_HINT_MASK);
7107 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); 7116 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id));
7117 g_signal_connect(G_OBJECT(tmp), "destroy", G_CALLBACK(_dw_render_destroy), NULL);
7108 gtk_widget_set_can_focus(tmp, TRUE); 7118 gtk_widget_set_can_focus(tmp, TRUE);
7109 gtk_widget_show(tmp); 7119 gtk_widget_show(tmp);
7110 if(_DWDefaultFont) 7120 if(_DWDefaultFont)
7111 dw_window_set_font(tmp, _DWDefaultFont); 7121 dw_window_set_font(tmp, _DWDefaultFont);
7112 DW_MUTEX_UNLOCK; 7122 DW_MUTEX_UNLOCK;
7303 #endif 7313 #endif
7304 7314
7305 DW_MUTEX_LOCK; 7315 DW_MUTEX_LOCK;
7306 if(handle) 7316 if(handle)
7307 { 7317 {
7308 GdkWindow *window = gtk_widget_get_window(handle); 7318 GdkDisplay *display = gdk_display_get_default();
7309 /* Safety check for non-existant windows */ 7319
7310 if(!window || !GDK_IS_WINDOW(window)) 7320 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose"))
7311 { 7321 {
7312 DW_MUTEX_UNLOCK; 7322 GdkWindow *window = gtk_widget_get_window(handle);
7313 return; 7323 /* Safety check for non-existant windows */
7314 } 7324 if(!window || !GDK_IS_WINDOW(window))
7315 #if GTK_CHECK_VERSION(3,22,0) 7325 {
7316 clip = gdk_window_get_clip_region(window); 7326 DW_MUTEX_UNLOCK;
7317 dc = gdk_window_begin_draw_frame(window, clip); 7327 return;
7318 cr = gdk_drawing_context_get_cairo_context(dc); 7328 }
7319 #else 7329 #if GTK_CHECK_VERSION(3,22,0)
7320 cr = gdk_cairo_create(window); 7330 clip = gdk_window_get_clip_region(window);
7321 #endif 7331 dc = gdk_window_begin_draw_frame(window, clip);
7332 cr = gdk_drawing_context_get_cairo_context(dc);
7333 #else
7334 cr = gdk_cairo_create(window);
7335 #endif
7336 }
7337 else
7338 {
7339 /* If not X11, just mark the widget dirty.. and trigger draw in dw_flush() */
7340 if(g_list_find(_dw_dirty_list, handle) == NULL)
7341 _dw_dirty_list = g_list_append(_dw_dirty_list, handle);
7342 }
7322 } 7343 }
7323 else if(pixmap) 7344 else if(pixmap)
7324 cr = cairo_create(pixmap->image); 7345 cr = cairo_create(pixmap->image);
7325 if(cr) 7346 if(cr)
7326 { 7347 {
7364 #endif 7385 #endif
7365 7386
7366 DW_MUTEX_LOCK; 7387 DW_MUTEX_LOCK;
7367 if(handle) 7388 if(handle)
7368 { 7389 {
7369 GdkWindow *window = gtk_widget_get_window(handle); 7390 GdkDisplay *display = gdk_display_get_default();
7370 /* Safety check for non-existant windows */ 7391
7371 if(!window || !GDK_IS_WINDOW(window)) 7392 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose"))
7372 { 7393 {
7373 DW_MUTEX_UNLOCK; 7394 GdkWindow *window = gtk_widget_get_window(handle);
7374 return; 7395 /* Safety check for non-existant windows */
7375 } 7396 if(!window || !GDK_IS_WINDOW(window))
7376 #if GTK_CHECK_VERSION(3,22,0) 7397 {
7377 clip = gdk_window_get_clip_region(window); 7398 DW_MUTEX_UNLOCK;
7378 dc = gdk_window_begin_draw_frame(window, clip); 7399 return;
7379 cr = gdk_drawing_context_get_cairo_context(dc); 7400 }
7380 #else 7401 #if GTK_CHECK_VERSION(3,22,0)
7381 cr = gdk_cairo_create(window); 7402 clip = gdk_window_get_clip_region(window);
7382 #endif 7403 dc = gdk_window_begin_draw_frame(window, clip);
7404 cr = gdk_drawing_context_get_cairo_context(dc);
7405 #else
7406 cr = gdk_cairo_create(window);
7407 #endif
7408 }
7409 else
7410 {
7411 /* If not X11, just mark the widget dirty.. and trigger draw in dw_flush() */
7412 if(g_list_find(_dw_dirty_list, handle) == NULL)
7413 _dw_dirty_list = g_list_append(_dw_dirty_list, handle);
7414 }
7383 } 7415 }
7384 else if(pixmap) 7416 else if(pixmap)
7385 cr = cairo_create(pixmap->image); 7417 cr = cairo_create(pixmap->image);
7386 if(cr) 7418 if(cr)
7387 { 7419 {
7427 #endif 7459 #endif
7428 7460
7429 DW_MUTEX_LOCK; 7461 DW_MUTEX_LOCK;
7430 if(handle) 7462 if(handle)
7431 { 7463 {
7432 GdkWindow *window = gtk_widget_get_window(handle); 7464 GdkDisplay *display = gdk_display_get_default();
7433 /* Safety check for non-existant windows */ 7465
7434 if(!window || !GDK_IS_WINDOW(window)) 7466 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose"))
7435 { 7467 {
7436 DW_MUTEX_UNLOCK; 7468 GdkWindow *window = gtk_widget_get_window(handle);
7437 return; 7469 /* Safety check for non-existant windows */
7438 } 7470 if(!window || !GDK_IS_WINDOW(window))
7439 #if GTK_CHECK_VERSION(3,22,0) 7471 {
7440 clip = gdk_window_get_clip_region(window); 7472 DW_MUTEX_UNLOCK;
7441 dc = gdk_window_begin_draw_frame(window, clip); 7473 return;
7442 cr = gdk_drawing_context_get_cairo_context(dc); 7474 }
7443 #else 7475 #if GTK_CHECK_VERSION(3,22,0)
7444 cr = gdk_cairo_create(window); 7476 clip = gdk_window_get_clip_region(window);
7445 #endif 7477 dc = gdk_window_begin_draw_frame(window, clip);
7478 cr = gdk_drawing_context_get_cairo_context(dc);
7479 #else
7480 cr = gdk_cairo_create(window);
7481 #endif
7482 }
7483 else
7484 {
7485 /* If not X11, just mark the widget dirty.. and trigger draw in dw_flush() */
7486 if(g_list_find(_dw_dirty_list, handle) == NULL)
7487 _dw_dirty_list = g_list_append(_dw_dirty_list, handle);
7488 }
7446 } 7489 }
7447 else if(pixmap) 7490 else if(pixmap)
7448 cr = cairo_create(pixmap->image); 7491 cr = cairo_create(pixmap->image);
7449 if(cr) 7492 if(cr)
7450 { 7493 {
7498 #endif 7541 #endif
7499 7542
7500 DW_MUTEX_LOCK; 7543 DW_MUTEX_LOCK;
7501 if(handle) 7544 if(handle)
7502 { 7545 {
7503 GdkWindow *window = gtk_widget_get_window(handle); 7546 GdkDisplay *display = gdk_display_get_default();
7504 /* Safety check for non-existant windows */ 7547
7505 if(!window || !GDK_IS_WINDOW(window)) 7548 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose"))
7506 { 7549 {
7507 DW_MUTEX_UNLOCK; 7550 GdkWindow *window = gtk_widget_get_window(handle);
7508 return; 7551 /* Safety check for non-existant windows */
7509 } 7552 if(!window || !GDK_IS_WINDOW(window))
7510 #if GTK_CHECK_VERSION(3,22,0) 7553 {
7511 clip = gdk_window_get_clip_region(window); 7554 DW_MUTEX_UNLOCK;
7512 dc = gdk_window_begin_draw_frame(window, clip); 7555 return;
7513 cr = gdk_drawing_context_get_cairo_context(dc); 7556 }
7514 #else 7557 #if GTK_CHECK_VERSION(3,22,0)
7515 cr = gdk_cairo_create(window); 7558 clip = gdk_window_get_clip_region(window);
7516 #endif 7559 dc = gdk_window_begin_draw_frame(window, clip);
7560 cr = gdk_drawing_context_get_cairo_context(dc);
7561 #else
7562 cr = gdk_cairo_create(window);
7563 #endif
7564 }
7565 else
7566 {
7567 /* If not X11, just mark the widget dirty.. and trigger draw in dw_flush() */
7568 if(g_list_find(_dw_dirty_list, handle) == NULL)
7569 _dw_dirty_list = g_list_append(_dw_dirty_list, handle);
7570 }
7517 } 7571 }
7518 else if(pixmap) 7572 else if(pixmap)
7519 cr = cairo_create(pixmap->image); 7573 cr = cairo_create(pixmap->image);
7520 if(cr) 7574 if(cr)
7521 { 7575 {
7571 #endif 7625 #endif
7572 7626
7573 DW_MUTEX_LOCK; 7627 DW_MUTEX_LOCK;
7574 if(handle) 7628 if(handle)
7575 { 7629 {
7576 GdkWindow *window = gtk_widget_get_window(handle); 7630 GdkDisplay *display = gdk_display_get_default();
7577 /* Safety check for non-existant windows */ 7631
7578 if(!window || !GDK_IS_WINDOW(window)) 7632 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose"))
7579 { 7633 {
7580 DW_MUTEX_UNLOCK; 7634 GdkWindow *window = gtk_widget_get_window(handle);
7581 return; 7635 /* Safety check for non-existant windows */
7582 } 7636 if(!window || !GDK_IS_WINDOW(window))
7583 #if GTK_CHECK_VERSION(3,22,0) 7637 {
7584 clip = gdk_window_get_clip_region(window); 7638 DW_MUTEX_UNLOCK;
7585 dc = gdk_window_begin_draw_frame(window, clip); 7639 return;
7586 cr = gdk_drawing_context_get_cairo_context(dc); 7640 }
7587 #else 7641 #if GTK_CHECK_VERSION(3,22,0)
7588 cr = gdk_cairo_create(window); 7642 clip = gdk_window_get_clip_region(window);
7589 #endif 7643 dc = gdk_window_begin_draw_frame(window, clip);
7644 cr = gdk_drawing_context_get_cairo_context(dc);
7645 #else
7646 cr = gdk_cairo_create(window);
7647 #endif
7648 }
7649 else
7650 {
7651 /* If not X11, just mark the widget dirty.. and trigger draw in dw_flush() */
7652 if(g_list_find(_dw_dirty_list, handle) == NULL)
7653 _dw_dirty_list = g_list_append(_dw_dirty_list, handle);
7654 }
7590 } 7655 }
7591 else if(pixmap) 7656 else if(pixmap)
7592 cr = cairo_create(pixmap->image); 7657 cr = cairo_create(pixmap->image);
7593 if(cr) 7658 if(cr)
7594 { 7659 {
7656 return; 7721 return;
7657 7722
7658 DW_MUTEX_LOCK; 7723 DW_MUTEX_LOCK;
7659 if(handle) 7724 if(handle)
7660 { 7725 {
7661 GdkWindow *window = gtk_widget_get_window(handle); 7726 GdkDisplay *display = gdk_display_get_default();
7662 /* Safety check for non-existant windows */ 7727
7663 if(!window || !GDK_IS_WINDOW(window)) 7728 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(handle), "_dw_expose"))
7664 { 7729 {
7665 DW_MUTEX_UNLOCK; 7730 GdkWindow *window = gtk_widget_get_window(handle);
7666 return; 7731 /* Safety check for non-existant windows */
7667 } 7732 if(!window || !GDK_IS_WINDOW(window))
7668 #if GTK_CHECK_VERSION(3,22,0) 7733 {
7669 clip = gdk_window_get_clip_region(window); 7734 DW_MUTEX_UNLOCK;
7670 dc = gdk_window_begin_draw_frame(window, clip); 7735 return;
7671 cr = gdk_drawing_context_get_cairo_context(dc); 7736 }
7672 #else 7737 #if GTK_CHECK_VERSION(3,22,0)
7673 cr = gdk_cairo_create(window); 7738 clip = gdk_window_get_clip_region(window);
7674 #endif 7739 dc = gdk_window_begin_draw_frame(window, clip);
7675 if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"))) 7740 cr = gdk_drawing_context_get_cairo_context(dc);
7676 fontname = tmpname; 7741 #else
7742 cr = gdk_cairo_create(window);
7743 #endif
7744 if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname")))
7745 fontname = tmpname;
7746 }
7747 else
7748 {
7749 /* If not X11, just mark the widget dirty.. and trigger draw in dw_flush() */
7750 if(g_list_find(_dw_dirty_list, handle) == NULL)
7751 _dw_dirty_list = g_list_append(_dw_dirty_list, handle);
7752 }
7677 } 7753 }
7678 else if(pixmap) 7754 else if(pixmap)
7679 { 7755 {
7680 if(pixmap->font) 7756 if(pixmap->font)
7681 fontname = pixmap->font; 7757 fontname = pixmap->font;
7982 pixmap->pixbuf = gdk_pixbuf_copy(_find_pixbuf((HICN)id, &pixmap->width, &pixmap->height)); 8058 pixmap->pixbuf = gdk_pixbuf_copy(_find_pixbuf((HICN)id, &pixmap->width, &pixmap->height));
7983 DW_MUTEX_UNLOCK; 8059 DW_MUTEX_UNLOCK;
7984 return pixmap; 8060 return pixmap;
7985 } 8061 }
7986 8062
8063 static void _dw_flush_dirty(gpointer widget, gpointer data)
8064 {
8065 if(widget && GTK_IS_WIDGET(widget))
8066 gtk_widget_queue_draw(GTK_WIDGET(widget));
8067 }
8068
7987 /* Call this after drawing to the screen to make sure 8069 /* Call this after drawing to the screen to make sure
7988 * anything you have drawn is visible. 8070 * anything you have drawn is visible.
7989 */ 8071 */
7990 void dw_flush(void) 8072 void dw_flush(void)
7991 { 8073 {
8074 int _locked_by_me = FALSE;
8075
8076 DW_MUTEX_LOCK;
8077 g_list_foreach(_dw_dirty_list, _dw_flush_dirty, NULL);
8078 g_list_free(_dw_dirty_list);
8079 _dw_dirty_list = NULL;
8080 DW_MUTEX_UNLOCK;
7992 } 8081 }
7993 8082
7994 /* 8083 /*
7995 * Sets the font used by a specified pixmap. 8084 * Sets the font used by a specified pixmap.
7996 * Normally the pixmap font is obtained from the associated window handle. 8085 * Normally the pixmap font is obtained from the associated window handle.
8087 return retval; 8176 return retval;
8088 8177
8089 DW_MUTEX_LOCK; 8178 DW_MUTEX_LOCK;
8090 if(dest) 8179 if(dest)
8091 { 8180 {
8092 GdkWindow *window = gtk_widget_get_window(dest); 8181 GdkDisplay *display = gdk_display_get_default();
8093 /* Safety check for non-existant windows */ 8182
8094 if(!window || !GDK_IS_WINDOW(window)) 8183 if((display && GDK_IS_X11_DISPLAY(display)) || g_object_get_data(G_OBJECT(dest), "_dw_expose"))
8095 { 8184 {
8096 DW_MUTEX_UNLOCK; 8185 GdkWindow *window = gtk_widget_get_window(dest);
8097 return retval; 8186 /* Safety check for non-existant windows */
8098 } 8187 if(!window || !GDK_IS_WINDOW(window))
8188 {
8189 DW_MUTEX_UNLOCK;
8190 return retval;
8191 }
8099 #if GTK_CHECK_VERSION(3,22,0) 8192 #if GTK_CHECK_VERSION(3,22,0)
8100 clip = gdk_window_get_clip_region(window); 8193 clip = gdk_window_get_clip_region(window);
8101 dc = gdk_window_begin_draw_frame(window, clip); 8194 dc = gdk_window_begin_draw_frame(window, clip);
8102 cr = gdk_drawing_context_get_cairo_context(dc); 8195 cr = gdk_drawing_context_get_cairo_context(dc);
8103 #else 8196 #else
8104 cr = gdk_cairo_create(window); 8197 cr = gdk_cairo_create(window);
8105 #endif 8198 #endif
8199 }
8200 else
8201 {
8202 /* If not X11, just mark the widget dirty.. and trigger draw in dw_flush() */
8203 if(g_list_find(_dw_dirty_list, dest) == NULL)
8204 _dw_dirty_list = g_list_append(_dw_dirty_list, dest);
8205 }
8106 } 8206 }
8107 else if(destp) 8207 else if(destp)
8108 cr = cairo_create(destp->image); 8208 cr = cairo_create(destp->image);
8109 8209
8110 if(cr) 8210 if(cr)