xserver/test/bugs/bug1354.c

150 lines
4.3 KiB
C

#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_image.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>
#include <unistd.h>
/*
* This is a test which try to test correct glamor colors when rendered.
* It should be run with fullscreen Xephyr (with glamor) with present and with
* etalon high-level Xserver (can be any, on CI - Xvfb). For testing this test
* creates an image in Xephyr X server, which filled by one of colors defined in
* test_pixels. Then it captures central pixel from both Xephyr and Xserver above.
* If pixels differ - test failed. Sleep is used to ensure than presentation on both
* Xephyr and Xvfb kicks (xcb_aux_sync was not enough) and test results will be actual
*/
#define WIDTH 300
#define HEIGHT 300
int get_display_pixel(xcb_connection_t* c, xcb_drawable_t win);
void draw_display_pixel(xcb_connection_t* c, xcb_drawable_t win, uint32_t pixel_color);
int get_display_pixel(xcb_connection_t* c, xcb_drawable_t win)
{
xcb_image_t *image;
uint32_t pixel;
int format = XCB_IMAGE_FORMAT_XY_PIXMAP;
image = xcb_image_get (c, win,
0, 0, WIDTH, HEIGHT,
UINT32_MAX,
format);
if (!image) {
printf("xcb_image_get failed: exiting\n");
exit(1);
}
pixel = xcb_image_get_pixel(image, WIDTH/2, HEIGHT/2);
return pixel;
}
void draw_display_pixel(xcb_connection_t* c, xcb_drawable_t win, uint32_t pixel_color)
{
xcb_gcontext_t foreground;
uint32_t mask = 0;
xcb_rectangle_t rectangles[] = {
{0, 0, WIDTH, HEIGHT},
};
foreground = xcb_generate_id (c);
mask = XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH | XCB_GC_SUBWINDOW_MODE;
uint32_t values[] = {
pixel_color,
20,
XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS
};
xcb_create_gc (c, foreground, win, mask, values);
xcb_poly_fill_rectangle (c, win, foreground, 1, rectangles);
xcb_aux_sync ( c );
}
int main(int argc, char* argv[])
{
xcb_connection_t *c, *r;
xcb_screen_t *screen1, *screen2;
xcb_drawable_t win1, win2;
char *name_test = NULL, *name_relevant = NULL;
uint32_t pixel_server1, pixel_server2;
int result = 0;
uint32_t test_pixels[3] = {0xff0000, 0x00ff00, 0x0000ff};
int gv;
while ((gv = getopt (argc, argv, "t:r:")) != -1)
switch (gv)
{
case 't':
name_test = optarg;
break;
case 'r':
name_relevant = optarg;
break;
case '?':
if (optopt == 't' || optopt == 'r')
fprintf (stderr, "Option -%c requires an argument - test screen name.\n", optopt);
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
printf("test=%s, rel=%s\n", name_test, name_relevant);
c = xcb_connect (name_test, NULL);
r = xcb_connect (name_relevant, NULL);
/* get the first screen */
screen1 = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
win1 = xcb_generate_id (c);
xcb_create_window (c, /* Connection */
XCB_COPY_FROM_PARENT, /* depth (same as root)*/
win1, /* window Id */
screen1->root, /* parent window */
0, 0, /* x, y */
WIDTH, HEIGHT, /* width, height */
20, /* border_width */
XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
screen1->root_visual, /* visual */
0, NULL ); /* masks, not used yet */
/* Map the window on the screen */
xcb_map_window (c, win1);
xcb_aux_sync(c);
/* get the first screen */
screen2 = xcb_setup_roots_iterator (xcb_get_setup (r)).data;
/* root window */
win2 = screen2->root;
for(int i = 0; i < 3; i++)
{
draw_display_pixel(c, win1, test_pixels[i]);
xcb_aux_sync(r);
pixel_server1 = get_display_pixel(c, win1);
sleep(1);
pixel_server2 = get_display_pixel(r, win2);
xcb_aux_sync(r);
printf("p=0x%x, p2=0x%x\n", pixel_server1, pixel_server2);
result+= pixel_server1 == pixel_server2;
}
return result == 3 ? 0 : 1;
}