1 #include <xcb/xcb.h> 2 #include <xcb/xcb_aux.h> 3 #include <xcb/xcb_image.h> 4 #include <stdint.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <getopt.h> 8 #include <ctype.h> 9 #include <unistd.h> 10 11 /* 12 * This is a test which try to test correct glamor colors when rendered. 13 * It should be run with fullscreen Xephyr (with glamor) with present and with 14 * etalon high-level Xserver (can be any, on CI - Xvfb). For testing this test 15 * creates an image in Xephyr X server, which filled by one of colors defined in 16 * test_pixels. Then it captures central pixel from both Xephyr and Xserver above. 17 * If pixels differ - test failed. Sleep is used to ensure than presentation on both 18 * Xephyr and Xvfb kicks (xcb_aux_sync was not enough) and test results will be actual 19 */ 20 21 #define WIDTH 300 22 #define HEIGHT 300 23 24 int get_display_pixel(xcb_connection_t* c, xcb_drawable_t win); 25 void draw_display_pixel(xcb_connection_t* c, xcb_drawable_t win, uint32_t pixel_color); 26 27 int get_display_pixel(xcb_connection_t* c, xcb_drawable_t win) 28 { 29 xcb_image_t *image; 30 uint32_t pixel; 31 int format = XCB_IMAGE_FORMAT_XY_PIXMAP; 32 33 image = xcb_image_get (c, win, 34 0, 0, WIDTH, HEIGHT, 35 UINT32_MAX, 36 format); 37 if (!image) { 38 printf("xcb_image_get failed: exiting\n"); 39 exit(1); 40 } 41 42 pixel = xcb_image_get_pixel(image, WIDTH/2, HEIGHT/2); 43 44 return pixel; 45 } 46 47 void draw_display_pixel(xcb_connection_t* c, xcb_drawable_t win, uint32_t pixel_color) 48 { 49 xcb_gcontext_t foreground; 50 uint32_t mask = 0; 51 52 xcb_rectangle_t rectangles[] = { 53 {0, 0, WIDTH, HEIGHT}, 54 }; 55 56 foreground = xcb_generate_id (c); 57 mask = XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH | XCB_GC_SUBWINDOW_MODE; 58 59 uint32_t values[] = { 60 pixel_color, 61 20, 62 XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS 63 }; 64 65 xcb_create_gc (c, foreground, win, mask, values); 66 67 xcb_poly_fill_rectangle (c, win, foreground, 1, rectangles); 68 xcb_aux_sync ( c ); 69 } 70 71 72 int main(int argc, char* argv[]) 73 { 74 xcb_connection_t *c, *r; 75 xcb_screen_t *screen1, *screen2; 76 xcb_drawable_t win1, win2; 77 char *name_test = NULL, *name_relevant = NULL; 78 uint32_t pixel_server1, pixel_server2; 79 int result = 0; 80 uint32_t test_pixels[3] = {0xff0000, 0x00ff00, 0x0000ff}; 81 int gv; 82 83 while ((gv = getopt (argc, argv, "t:r:")) != -1) 84 switch (gv) 85 { 86 case 't': 87 name_test = optarg; 88 break; 89 case 'r': 90 name_relevant = optarg; 91 break; 92 case '?': 93 if (optopt == 't' || optopt == 'r') 94 fprintf (stderr, "Option -%c requires an argument - test screen name.\n", optopt); 95 else if (isprint (optopt)) 96 fprintf (stderr, "Unknown option `-%c'.\n", optopt); 97 else 98 fprintf (stderr, 99 "Unknown option character `\\x%x'.\n", 100 optopt); 101 return 1; 102 default: 103 abort (); 104 } 105 106 printf("test=%s, rel=%s\n", name_test, name_relevant); 107 108 c = xcb_connect (name_test, NULL); 109 r = xcb_connect (name_relevant, NULL); 110 111 /* get the first screen */ 112 screen1 = xcb_setup_roots_iterator (xcb_get_setup (c)).data; 113 114 win1 = xcb_generate_id (c); 115 xcb_create_window (c, /* Connection */ 116 XCB_COPY_FROM_PARENT, /* depth (same as root)*/ 117 win1, /* window Id */ 118 screen1->root, /* parent window */ 119 0, 0, /* x, y */ 120 WIDTH, HEIGHT, /* width, height */ 121 20, /* border_width */ 122 XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */ 123 screen1->root_visual, /* visual */ 124 0, NULL ); /* masks, not used yet */ 125 126 127 /* Map the window on the screen */ 128 xcb_map_window (c, win1); 129 xcb_aux_sync(c); 130 131 /* get the first screen */ 132 screen2 = xcb_setup_roots_iterator (xcb_get_setup (r)).data; 133 134 /* root window */ 135 win2 = screen2->root; 136 137 for(int i = 0; i < 3; i++) 138 { 139 draw_display_pixel(c, win1, test_pixels[i]); 140 xcb_aux_sync(r); 141 pixel_server1 = get_display_pixel(c, win1); 142 sleep(1); 143 pixel_server2 = get_display_pixel(r, win2); 144 xcb_aux_sync(r); 145 printf("p=0x%x, p2=0x%x\n", pixel_server1, pixel_server2); 146 result+= pixel_server1 == pixel_server2; 147 } 148 return result == 3 ? 0 : 1; 149 } 150