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