我正在尝试制作一个简单的 xcb 程序来学习基础知识并希望在其他项目中使用它,但我遇到了一个奇怪的问题。创建像素图后,我可以使用 xcb_poly_fill_rectangle 函数绘制它,然后 xcb_copy_area 与 xcb_flush 一起使其显示在屏幕上。当无论我尝试什么都无法使 xcb_poly_segment 绘制一些线段时,问题就出现了。
我是新来的,所以对我应该提出的问题的任何建议或更正都会被接受。
这是代码(也许有一些关于该问题的额外不必要的代码):
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/xcb_image.h>
int main(void)
{
/* Misc declarations */
int screen_num;
xcb_get_geometry_reply_t *window_size;
xcb_generic_error_t **window_size_error;
uint32_t mask;
uint32_t values[3];
/* Open the connection to the X server */
xcb_connection_t *connection = xcb_connect(NULL, &screen_num);
if (xcb_connection_has_error(connection)) {
fprintf(stderr, "Error: connection failed");
return 1;
}
/* Get the current screen */
const xcb_setup_t *setup = xcb_get_setup(connection);
xcb_screen_iterator_t iterator = xcb_setup_roots_iterator(setup);
for (int i = 0; i < screen_num; ++i) {
xcb_screen_next(&iterator);
}
xcb_screen_t *screen = iterator.data;
/* Create white (foreground) graphic context */
xcb_gcontext_t white = xcb_generate_id(connection);
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
values[0] = screen->white_pixel;
values[1] = 0;
xcb_create_gc(connection, white, screen->root, mask, values);
/* Create text (foreground) graphic context */
xcb_gcontext_t text = xcb_generate_id(connection);
mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_GRAPHICS_EXPOSURES;
values[0] = 0x00FF00FF;
values[1] = 0xFF00FF00;
values[2] = 0;
xcb_create_gc(connection, text, screen->root, mask, values);
/* Create black graphic context */ /* Eraseable */
xcb_gcontext_t black = xcb_generate_id(connection);
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
values[0] = screen->black_pixel;
values[1] = 0;
xcb_create_gc(connection, black, screen->root, mask, values);
/* Create a window */
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
values[0] = screen->black_pixel; /* bg color */
values[1] = XCB_EVENT_MASK_EXPOSURE;
xcb_window_t window = xcb_generate_id(connection);
xcb_create_window(connection,
XCB_COPY_FROM_PARENT,
window,
screen->root,
0, 0,
640, 360,
10,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
mask, values);
/* Map the window on the screen and flush*/
xcb_map_window(connection, window);
xcb_flush(connection);
/* Eraseable */
xcb_segment_t segments[] = {
{50, 50, 100, 100},
{50, 100, 100, 50},
};
xcb_rectangle_t rectangle = {
0, 0,
50, 50
};
xcb_pixmap_t pixmap = xcb_generate_id(connection);
xcb_create_pixmap(connection, screen->root_depth,
pixmap, window, 16, 16);
/* draw primitives */
xcb_generic_event_t *event;
xcb_expose_event_t *ex_event;
while ((event = xcb_wait_for_event(connection))) {
switch (event->response_type & ~0x80) {
case XCB_EXPOSE:
/* Eraseable */
ex_event = (xcb_expose_event_t *) event;
xcb_poly_fill_rectangle(connection, pixmap, white, 1, &rectangle);
xcb_poly_segment(connection, pixmap, white, 2, segments);
xcb_copy_area(connection, pixmap, window, white,
ex_event->x, ex_event->y,
ex_event->x, ex_event->y,
ex_event->width, ex_event->height);
/* Reflush */
xcb_flush(connection);
break;
case XCB_KEY_PRESS:
/* TODO */
break;
default:
break;
}
free(event);
}
xcb_disconnect(connection);
return 0;
}
我尝试将 xcb_poly_segment 的可绘制对象更改为窗口,并在复制像素图后调用该函数(因此它不会覆盖)并且工作正常,但我无法使用“文本”图形上下文和其他一些变体一样,但没用。
我还寻找了一种方法来了解多段函数通过 cookie 返回的任何错误。我想我搜索得不够努力。
非常感谢任何回应。
编辑:找到答案,但没有解释:(
出于我不知道的原因,xcb_flush 函数破坏了某些东西。通过玩弄窗户,我可以在短时间内看到这些片段,然后消失在存在的虚空中。我认为它试图快速刷新,或者刷新速度很慢,但我不知道。
还修复了像素图尺寸过小的问题(小于绘制矩形和线段所需的区域)。
我对您的程序进行了以下更改:
--- t.c.orig 2024-07-02 17:07:30.085952668 +0200
+++ t.c 2024-07-02 17:11:07.498782376 +0200
@@ -86,12 +86,16 @@ int main(void)
xcb_rectangle_t rectangle = {
0, 0,
- 50, 50
+ 300, 300
};
xcb_pixmap_t pixmap = xcb_generate_id(connection);
xcb_create_pixmap(connection, screen->root_depth,
- pixmap, window, 16, 16);
+ pixmap, window, 300, 300);
+
+ /* I moved this up here since it only draws to the pixmap and that one keeps its content */
+ xcb_poly_fill_rectangle(connection, pixmap, white, 1, &rectangle);
+ xcb_poly_segment(connection, pixmap, black, 2, segments);
/* draw primitives */
xcb_generic_event_t *event;
@@ -102,10 +106,6 @@ int main(void)
/* Eraseable */
ex_event = (xcb_expose_event_t *) event;
- xcb_poly_fill_rectangle(connection, pixmap, white, 1, &rectangle);
-
- xcb_poly_segment(connection, pixmap, white, 2, segments);
-
xcb_copy_area(connection, pixmap, window, white,
ex_event->x, ex_event->y,
ex_event->x, ex_event->y,
xcb_poly_segment()
调用以使用 black
GC 而不是 white
GC。在白色上画白色没有明显的结果。结果看起来像这样,我希望这是你所期望的: