mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-20 12:50:04 +01:00
read-only mirror of https://gitlab.freedesktop.org/xorg/xserver
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;
}
(cherry picked from commit
|
||
|---|---|---|
| composite | ||
| config | ||
| damageext | ||
| dbe | ||
| dix | ||
| doc | ||
| dri3 | ||
| exa | ||
| fb | ||
| 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