gpt4 book ai didi

cairo/xlib 不更新窗口内容

转载 作者:行者123 更新时间:2023-11-30 14:47:09 25 4
gpt4 key购买 nike

我正在尝试学习如何使用 Cairo 2D drawing library与 xlib 曲面。

我编写了一个允许创建多个窗口的小测试程序。每个函数可能有一个自定义的paint()函数,定期调用该函数以向窗口添加一些图形内容,或者根据需要完全重绘它。还有一个选项可以定义鼠标和按键监听器。主例程检查 X 事件(将它们委托(delegate)给鼠标和按键监听器)以及定期调用这些 Paint() 函数的超时。

我尝试使用 Cairo 1.14.6 版本(目前在 Ubuntu 16.04 中以软件包形式提供)和最新的 1.15.12,但结果是相同的。

此演示的预期行为是打开 3 个窗口。一个将添加随机矩形,另一个随机文本,第三个随机圆圈。

此外,单击窗口应产生线条(连接到鼠标单击,或随机),使用箭头键应在窗口中绘制一 strip 圆圈的红线。

圆圈和文本似乎按预期定期显示。所有三个窗口都应具有白色背景,但其中两个窗口是黑色的。最糟糕的是,带有矩形的窗口没有得到太多更新(无论它是否是第一个创建的窗口都没关系,它总是矩形无法正确显示)。

它们仅在焦点更改为该窗口或从该窗口更改时显示 - 然后应同时绘制的其余矩形突然出现。

添加任何内容后,我在每个窗口的表面上调用 cairo_surface_flush() ,但这没有帮助。我还尝试将 XEvents 发布到各种类型的窗口(例如焦点),它们到达了,但矩形没有显示。

此外,即使用鼠标画线效果很好,但用方向键画线也会遇到同样的问题 - 它被画出来了,但没有正确显示。

我对这个库可以做什么的一些假设显然是错误的,但我不确定在哪里。

似乎显示了两个相互竞争的绘图版本,因为有时会出现一两个矩形或红线的碎片闪烁。某种奇怪的缓冲、缓存?这可能只是我的程序中的一些错误,我不知道。

另一个观察结果 - 黑色背景是因为在显示窗口之前绘制白色背景,因此这些 cairo_paint 调用会以某种方式被丢弃。我不知道如何使窗口更早出现,似乎只有在屏幕上进行一些后续更改后才会出现。

经过几天绝望的日子后,我陷入了困境,你能至少部分地帮助我吗?

程序在这里:test_cairo.c

屏幕截图示例(用按键绘制一条红色虚线,并且矩形未正确显示):test_cairo.png

编译(在 Ubuntu 16.04 或类似系统上):

gcc -o test_cairo test_cairo.c -I/usr/include/cairo -lX11 -lcairo 

最佳答案

X11 不会为您保留窗口内容。当您收到 Expose 事件时,您必须完全重新绘制该事件所描述的区域。

All three windows should have white background, but two of them are black.

您使用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++)

关于cairo/xlib 不更新窗口内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51569047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com