如何使用 XCB 在根 window 上绘制?
How to draw on root window with XCB?
我有一个 XLib 代码可以正常使用:
Display *display = XOpenDisplay(NULL);
int screen_num = DefaultScreen(display);
Window root_win = RootWindow ( display, screen_num );
// Create a GC (Graphics Context) for the line
XGCValues gc_val;
gc_val.function = GXxor;
gc_val.plane_mask = AllPlanes;
gc_val.foreground = WhitePixel(display, screen_num);
gc_val.background = BlackPixel(display, screen_num);
gc_val.line_width = 4;
gc_val.line_style = LineSolid;
gc_val.cap_style = CapButt;
gc_val.join_style = JoinMiter;
gc_val.fill_style = FillOpaqueStippled;
gc_val.fill_rule = WindingRule;
gc_val.graphics_exposures = False;
gc_val.clip_x_origin = 0;
gc_val.clip_y_origin = 0;
gc_val.clip_mask = None;
gc_val.subwindow_mode = IncludeInferiors;
GC gc_line = XCreateGC(display, root_win, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCLineWidth | GCLineStyle |
GCCapStyle | GCJoinStyle | GCFillStyle | GCFillRule | GCGraphicsExposures |
GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode, &gc_val);
//XSetForeground(display, gc_line, some_color);
XDrawRectangle(display, root_win, gc_line, 50, 50, 400, 400);
XFlush(display);
...我需要对 XCB 做同样的事情。
我写了尽可能多的与XCB相似的代码:
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_generic_event_t *e;
uint32_t mask = 0;
xcb_gcontext_t gc = { 0 }; /* the returned default graphic context */
xcb_drawable_t draw;
xcb_rectangle_t rectangles[] = {
{0, 0, 100, 100},
};
c = xcb_connect (NULL, NULL);
/* get the first screen */
screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
gc = xcb_generate_id (c);
/* root window */
draw = screen->root;
mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FUNCTION | XCB_GC_CAP_STYLE | XCB_GC_JOIN_STYLE | XCB_GC_FILL_STYLE | XCB_GC_FILL_RULE | XCB_GC_GRAPHICS_EXPOSURES
| XCB_GC_CLIP_ORIGIN_X | XCB_GC_CLIP_ORIGIN_Y | XCB_GC_CLIP_MASK | XCB_GC_SUBWINDOW_MODE;
uint32_t values[] = {
screen->black_pixel,
screen->white_pixel,
XCB_GX_XOR,
XCB_CAP_STYLE_BUTT,
XCB_JOIN_STYLE_MITER,
XCB_FILL_STYLE_OPAQUE_STIPPLED,
XCB_FILL_RULE_WINDING,
1,
0,
0,
XCB_NONE,
XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS
};
xcb_create_gc (c, gc, draw, mask, values);
xcb_map_window (c, draw);
xcb_flush(c);
while (1)
{
xcb_poly_rectangle (c, draw, gc, 1, rectangles);
xcb_flush(c);
}
但是在程序开始时我没有看到矩形。
我做错了什么?
我真的不知道,但在搜索和修改您的代码后,我能够使用这个简单的代码在根部 window 上绘制:
#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
int
main ()
{
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_generic_event_t *e;
uint32_t mask = 0;
xcb_gcontext_t gc = { 0 }; /* the returned default graphic context */
xcb_drawable_t draw;
xcb_rectangle_t rectangles[] = {
{ 200, 200, 400, 400 },
};
c = xcb_connect (NULL, NULL);
/* get the first screen */
screen = xcb_setup_roots_iterator ( xcb_get_setup ( c ) ).data;
gc = xcb_generate_id ( c );
/* root window */
draw = screen->root;
mask = XCB_GC_FUNCTION | XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_LINE_WIDTH| XCB_GC_LINE_STYLE | XCB_GC_GRAPHICS_EXPOSURES;
uint32_t values[] = {
XCB_GX_XOR,
screen->white_pixel,
screen->black_pixel,
1,
XCB_LINE_STYLE_ON_OFF_DASH,
0
};
xcb_create_gc ( c, gc, draw, mask, values );
xcb_poly_rectangle (c, draw, gc, 3, rectangles);
xcb_map_window (c, draw);
xcb_flush(c);
pause();
return 0;
}
我认为您的问题是如何根据需要更新根目录 window...(也许)。如果您找到解决方案,请向您展示代码。
我用于测试:
Xephyr -br -noreset -screen "1024x640" :1&
DISPLAY=:1.0 ./mylittletest
我有一些进步。
看起来是 GC 参数组合的问题。
截图中显示的代码:
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_drawable_t win;
xcb_gcontext_t foreground;
uint32_t mask = 0;
xcb_rectangle_t rectangles[] = {
{50, 50, 600, 400},
};
c = xcb_connect (NULL, NULL);
/* get the first screen */
screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
/* root window */
win = screen->root;
foreground = xcb_generate_id (c);
mask = XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH | XCB_GC_SUBWINDOW_MODE;
uint32_t values[] = {
screen->black_pixel,
4,
XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS
};
xcb_create_gc (c, foreground, win, mask, values);
while(1)
{
xcb_poly_rectangle (c, win, foreground, 1, rectangles);
xcb_flush ( c );
}
我有一个 XLib 代码可以正常使用:
Display *display = XOpenDisplay(NULL);
int screen_num = DefaultScreen(display);
Window root_win = RootWindow ( display, screen_num );
// Create a GC (Graphics Context) for the line
XGCValues gc_val;
gc_val.function = GXxor;
gc_val.plane_mask = AllPlanes;
gc_val.foreground = WhitePixel(display, screen_num);
gc_val.background = BlackPixel(display, screen_num);
gc_val.line_width = 4;
gc_val.line_style = LineSolid;
gc_val.cap_style = CapButt;
gc_val.join_style = JoinMiter;
gc_val.fill_style = FillOpaqueStippled;
gc_val.fill_rule = WindingRule;
gc_val.graphics_exposures = False;
gc_val.clip_x_origin = 0;
gc_val.clip_y_origin = 0;
gc_val.clip_mask = None;
gc_val.subwindow_mode = IncludeInferiors;
GC gc_line = XCreateGC(display, root_win, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCLineWidth | GCLineStyle |
GCCapStyle | GCJoinStyle | GCFillStyle | GCFillRule | GCGraphicsExposures |
GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode, &gc_val);
//XSetForeground(display, gc_line, some_color);
XDrawRectangle(display, root_win, gc_line, 50, 50, 400, 400);
XFlush(display);
...我需要对 XCB 做同样的事情。
我写了尽可能多的与XCB相似的代码:
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_generic_event_t *e;
uint32_t mask = 0;
xcb_gcontext_t gc = { 0 }; /* the returned default graphic context */
xcb_drawable_t draw;
xcb_rectangle_t rectangles[] = {
{0, 0, 100, 100},
};
c = xcb_connect (NULL, NULL);
/* get the first screen */
screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
gc = xcb_generate_id (c);
/* root window */
draw = screen->root;
mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FUNCTION | XCB_GC_CAP_STYLE | XCB_GC_JOIN_STYLE | XCB_GC_FILL_STYLE | XCB_GC_FILL_RULE | XCB_GC_GRAPHICS_EXPOSURES
| XCB_GC_CLIP_ORIGIN_X | XCB_GC_CLIP_ORIGIN_Y | XCB_GC_CLIP_MASK | XCB_GC_SUBWINDOW_MODE;
uint32_t values[] = {
screen->black_pixel,
screen->white_pixel,
XCB_GX_XOR,
XCB_CAP_STYLE_BUTT,
XCB_JOIN_STYLE_MITER,
XCB_FILL_STYLE_OPAQUE_STIPPLED,
XCB_FILL_RULE_WINDING,
1,
0,
0,
XCB_NONE,
XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS
};
xcb_create_gc (c, gc, draw, mask, values);
xcb_map_window (c, draw);
xcb_flush(c);
while (1)
{
xcb_poly_rectangle (c, draw, gc, 1, rectangles);
xcb_flush(c);
}
但是在程序开始时我没有看到矩形。
我做错了什么?
我真的不知道,但在搜索和修改您的代码后,我能够使用这个简单的代码在根部 window 上绘制:
#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
int
main ()
{
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_generic_event_t *e;
uint32_t mask = 0;
xcb_gcontext_t gc = { 0 }; /* the returned default graphic context */
xcb_drawable_t draw;
xcb_rectangle_t rectangles[] = {
{ 200, 200, 400, 400 },
};
c = xcb_connect (NULL, NULL);
/* get the first screen */
screen = xcb_setup_roots_iterator ( xcb_get_setup ( c ) ).data;
gc = xcb_generate_id ( c );
/* root window */
draw = screen->root;
mask = XCB_GC_FUNCTION | XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_LINE_WIDTH| XCB_GC_LINE_STYLE | XCB_GC_GRAPHICS_EXPOSURES;
uint32_t values[] = {
XCB_GX_XOR,
screen->white_pixel,
screen->black_pixel,
1,
XCB_LINE_STYLE_ON_OFF_DASH,
0
};
xcb_create_gc ( c, gc, draw, mask, values );
xcb_poly_rectangle (c, draw, gc, 3, rectangles);
xcb_map_window (c, draw);
xcb_flush(c);
pause();
return 0;
}
我认为您的问题是如何根据需要更新根目录 window...(也许)。如果您找到解决方案,请向您展示代码。
我用于测试:
Xephyr -br -noreset -screen "1024x640" :1&
DISPLAY=:1.0 ./mylittletest
我有一些进步。
看起来是 GC 参数组合的问题。
截图中显示的代码:
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_drawable_t win;
xcb_gcontext_t foreground;
uint32_t mask = 0;
xcb_rectangle_t rectangles[] = {
{50, 50, 600, 400},
};
c = xcb_connect (NULL, NULL);
/* get the first screen */
screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
/* root window */
win = screen->root;
foreground = xcb_generate_id (c);
mask = XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH | XCB_GC_SUBWINDOW_MODE;
uint32_t values[] = {
screen->black_pixel,
4,
XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS
};
xcb_create_gc (c, foreground, win, mask, values);
while(1)
{
xcb_poly_rectangle (c, win, foreground, 1, rectangles);
xcb_flush ( c );
}