983e30361f
If a source picture doesn't repeat and a mask format is specified, the incorrect calulation of the origin of the glyphs caused the glyphs to not be drawn at all. Noticed when running gtk-demo from RHEL 6.5 and selecting "Rotated Text". Signed-off-by: Peter Harris <pharris@opentext.com> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com> /* Test for this bug cc -std=c99 -o glyph glyph.c `pkg-config --cflags --libs xcb-render` */ // 16 x 16 pictfmt_a8 "glyph" static const char glyph[] = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, }; static struct { uint8_t len; uint8_t pad[3]; uint16_t deltax, deltay; uint8_t glyph; uint8_t pad2[3]; } elt = { len:1, glyph:1, deltax:WIN_SIZE/2 - GLYPH_SIZE/2, deltay:WIN_SIZE/2 - GLYPH_SIZE/2 }; int main(int argc, char *argv[]) { int screen; xcb_connection_t *c = xcb_connect(NULL, &screen); if (!c || xcb_connection_has_error(c)) { fprintf(stderr, "Cannot open default display \"%s\"\n", getenv("DISPLAY")); return EXIT_FAILURE; } // Find root window and depth const xcb_setup_t *setup = xcb_get_setup(c); if (screen >= setup->roots_len) screen = 0; xcb_screen_iterator_t si = xcb_setup_roots_iterator(setup); for (int i=0; i < screen; i++) xcb_screen_next(&si); xcb_window_t root = si.data->root; uint8_t depth = si.data->root_depth; xcb_visualid_t visual = si.data->root_visual; // Find picture formats xcb_render_query_pict_formats_reply_t *qpf; qpf = xcb_render_query_pict_formats_reply(c, xcb_render_query_pict_formats(c), NULL); if (!qpf) { fprintf(stderr, "Cannot query RENDER picture formats\n"); return EXIT_FAILURE; } xcb_render_pictformat_t fmt_a8 = 0; xcb_render_pictforminfo_iterator_t pfi = xcb_render_query_pict_formats_formats_iterator(qpf); for (int i = 0; i < xcb_render_query_pict_formats_formats_length(qpf); i++) { if (pfi.data->depth == 8 && pfi.data->type == XCB_RENDER_PICT_TYPE_DIRECT && pfi.data->direct.alpha_mask == 0xFF) { fmt_a8 = pfi.data->id; break; } xcb_render_pictforminfo_next(&pfi); } if (!fmt_a8) { fprintf(stderr, "Cannot find a8 RENDER picture format\n"); return EXIT_FAILURE; } xcb_render_pictformat_t fmt_visual = 0; xcb_render_pictscreen_iterator_t psi = xcb_render_query_pict_formats_screens_iterator(qpf); for (int i = 0; i < xcb_render_query_pict_formats_screens_length(qpf); i++) { xcb_render_pictdepth_iterator_t pdi = xcb_render_pictscreen_depths_iterator(psi.data); for (int j = 0; i < xcb_render_pictscreen_depths_length(psi.data); i++) { xcb_render_pictvisual_iterator_t pvi = xcb_render_pictdepth_visuals_iterator(pdi.data); for (int k = 0; k < xcb_render_pictdepth_visuals_length(pdi.data); i++) { if (pvi.data->visual == visual) { fmt_visual = pvi.data->format; goto found_visual; } xcb_render_pictvisual_next(&pvi); } xcb_render_pictdepth_next(&pdi); } xcb_render_pictscreen_next(&psi); } found_visual: if (!fmt_visual) { fprintf(stderr, "Cannot find visual RENDER picture format\n"); return EXIT_FAILURE; } xcb_render_glyphset_t glyphset = xcb_generate_id(c); xcb_render_create_glyph_set(c, glyphset, fmt_a8); uint32_t glyph_ids[] = {1}; xcb_render_add_glyphs(c, glyphset, 1, glyph_ids, &(xcb_render_glyphinfo_t){width:GLYPH_SIZE, height:GLYPH_SIZE}, sizeof(glyph), glyph); // Create window, pixmap, and gc xcb_window_t window = xcb_generate_id(c); uint32_t list[] = { si.data->black_pixel, XCB_EVENT_MASK_EXPOSURE }; xcb_create_window(c, XCB_COPY_FROM_PARENT, window, root, 0, 0, WIN_SIZE, WIN_SIZE, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, list); xcb_map_window(c, window); xcb_render_picture_t winpic = xcb_generate_id(c); xcb_render_create_picture(c, winpic, window, fmt_visual, 0, NULL); xcb_pixmap_t pixmap = xcb_generate_id(c); xcb_create_pixmap(c, depth, pixmap, window, GLYPH_SIZE, GLYPH_SIZE); xcb_render_picture_t pixpic = xcb_generate_id(c); xcb_render_create_picture(c, pixpic, pixmap, fmt_visual, 0, NULL); xcb_render_fill_rectangles(c, XCB_RENDER_PICT_OP_SRC, pixpic, (xcb_render_color_t){green:0xFFFF, alpha:0xFFFF}, 1, &(xcb_rectangle_t){width:GLYPH_SIZE, height:GLYPH_SIZE} ); xcb_flush(c); for (xcb_generic_event_t *ev = xcb_wait_for_event(c); ev; ev = xcb_wait_for_event(c)) { int type = ev->response_type; free(ev); if (type == XCB_EXPOSE) { xcb_clear_area(c, 0, window, 0, 0, 0, 0); xcb_render_composite_glyphs_8(c, XCB_RENDER_PICT_OP_SRC, pixpic, winpic, fmt_a8, glyphset, 0, 0, sizeof(elt), (uint8_t *)&elt); xcb_flush(c); } } return EXIT_SUCCESS; } |
||
---|---|---|
composite | ||
config | ||
damageext | ||
dbe | ||
dix | ||
doc | ||
dri3 | ||
exa | ||
fb | ||
glamor | ||
glx | ||
hw | ||
include | ||
m4 | ||
man | ||
mi | ||
miext | ||
os | ||
present | ||
pseudoramiX | ||
randr | ||
record | ||
render | ||
test | ||
Xext | ||
xfixes | ||
Xi | ||
xkb | ||
.dir-locals.el | ||
.gitignore | ||
autogen.sh | ||
configure.ac | ||
COPYING | ||
devbook.am | ||
docbook.am | ||
fix-miregion | ||
fix-miregion-private | ||
fix-patch-whitespace | ||
fix-region | ||
Makefile.am | ||
manpages.am | ||
README | ||
xorg-server.m4 | ||
xorg-server.pc.in | ||
xserver.ent.in |
X Server The X server accepts requests from client applications to create windows, which are (normally rectangular) "virtual screens" that the client program can draw into. Windows are then composed on the actual screen by the X server (or by a separate composite manager) as directed by the window manager, which usually communicates with the user via graphical controls such as buttons and draggable titlebars and borders. For a comprehensive overview of X Server and X Window System, consult the following article: http://en.wikipedia.org/wiki/X_server All questions regarding this software should be directed at the Xorg mailing list: http://lists.freedesktop.org/mailman/listinfo/xorg Please submit bug reports to the Xorg bugzilla: https://bugs.freedesktop.org/enter_bug.cgi?product=xorg The master development code repository can be found at: git://anongit.freedesktop.org/git/xorg/xserver http://cgit.freedesktop.org/xorg/xserver For patch submission instructions, see: http://www.x.org/wiki/Development/Documentation/SubmittingPatches For more information on the git code manager, see: http://wiki.x.org/wiki/GitPage