X11 不会为您保留窗口内容。当您收到 Expose 事件时,您必须完全重新绘制该事件所描述的区域。
所有三个窗口都应该有白色背景,但其中两个是黑色的。
您使用XCreateSimpleWindow 创建窗口,因此它们的背景属性设置为黑色。 X11 服务器会在发送暴露事件之前为您用黑色填充暴露区域。由于您没有告诉 cairo 绘制白色背景,因此黑色会保留。
试试这个:
--- test_cairo.c.orig 2018-07-28 09:53:10.000000000 +0200
+++ test_cairo.c 2018-07-29 10:52:43.268867754 +0200
@@ -63,6 +63,7 @@ static gui_mouse_callback mouse_callback
static cairo_t *windows[MAX_GUI_WINDOWS_COUNT];
static cairo_surface_t *surfaces[MAX_GUI_WINDOWS_COUNT];
+static cairo_surface_t *real_surfaces[MAX_GUI_WINDOWS_COUNT];
static Window x11windows[MAX_GUI_WINDOWS_COUNT];
static char *window_names[MAX_GUI_WINDOWS_COUNT];
@@ -79,7 +80,12 @@ long long usec()
void repaint_window(int window_handle)
{
draw_callbacks[window_handle](windows[window_handle]);
- cairo_surface_flush(surfaces[window_handle]);
+
+ cairo_t *cr = cairo_create(real_surfaces[window_handle]);
+ cairo_set_source_surface(cr, surfaces[window_handle], 0, 0);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+ cairo_surface_flush(real_surfaces[window_handle]);
}
int gui_cairo_check_event(int *xclick, int *yclick, int *win)
@@ -149,7 +155,6 @@ void draw_windows_title(int window_handl
sprintf(fullname, "Mikes - %d - [%s]", window_handle, context_names[current_context]);
else
sprintf(fullname, "Mikes - %s - [%s]", window_names[window_handle], context_names[current_context]);
- cairo_surface_flush(surfaces[window_handle]);
XStoreName(dsp, x11windows[window_handle], fullname);
}
@@ -179,20 +184,17 @@ int gui_open_window(gui_draw_callback pa
}
if (window_handle < 0) return -1;
- surfaces[window_handle] = gui_cairo_create_x11_surface(&width, &height, window_handle);
+ real_surfaces[window_handle] = gui_cairo_create_x11_surface(&width, &height, window_handle);
+ surfaces[window_handle] = cairo_surface_create_similar(real_surfaces[window_handle], CAIRO_CONTENT_COLOR, width, height);
windows[window_handle] = cairo_create(surfaces[window_handle]);
mouse_callbacks[window_handle] = 0;
draw_callbacks[window_handle] = paint;
window_update_periods[window_handle] = update_period_in_ms;
window_names[window_handle] = 0;
-
- cairo_surface_flush(surfaces[window_handle]);
cairo_set_source_rgb(windows[window_handle], 1, 1, 1);
cairo_paint(windows[window_handle]);
-
- cairo_surface_flush(surfaces[window_handle]);
draw_callbacks[window_handle](windows[window_handle]);
@@ -201,7 +203,6 @@ int gui_open_window(gui_draw_callback pa
else next_window_update[window_handle] = 0;
draw_windows_title(window_handle);
- cairo_surface_flush(surfaces[window_handle]);
window_in_use[window_handle] = 1;
return window_handle;
@@ -213,6 +214,7 @@ void gui_close_window(int window_handle)
cairo_destroy(windows[window_handle]);
cairo_surface_destroy(surfaces[window_handle]);
+ cairo_surface_destroy(real_surfaces[window_handle]);
window_in_use[window_handle] = 0;
int no_more_windows = 1;
for (int i = 0; i < MAX_GUI_WINDOWS_COUNT; i++)