6 my_handler(Display *display, XErrorEvent *error) {
9 XGetErrorText(display, error->error_code, buffer, sizeof(buffer));
10 i_push_error(error->error_code, buffer);
14 imss_x11(unsigned long display_ul, unsigned long window_id) {
15 Display *display = (Display *)display_ul;
16 int own_display = 0; /* non-zero if we connect */
19 XWindowAttributes attr;
24 XErrorHandler old_handler;
28 /* we don't want the default noisy error handling */
29 old_handler = XSetErrorHandler(my_handler);
32 display = XOpenDisplay(NULL);
35 XSetErrorHandler(old_handler);
36 i_push_error(0, "No display supplied and cannot connect");
42 int screen = DefaultScreen(display);
43 window_id = RootWindow(display, 0);
46 if (!XGetWindowAttributes(display, window_id, &attr)) {
47 XSetErrorHandler(old_handler);
49 XCloseDisplay(display);
50 i_push_error(0, "Cannot XGetWindowAttributes");
54 image = XGetImage(display, window_id, 0, 0, attr.width, attr.height,
57 XSetErrorHandler(old_handler);
59 XCloseDisplay(display);
60 i_push_error(0, "Cannot XGetImage");
64 result = i_img_8_new(attr.width, attr.height, 3);
65 line = mymalloc(sizeof(i_color) * attr.width);
66 colors = mymalloc(sizeof(XColor) * attr.width);
67 for (y = 0; y < attr.height; ++y) {
69 /* XQueryColors seems to be a round-trip, so do one big request
70 instead of one per pixel */
71 for (x = 0; x < attr.width; ++x) {
72 colors[x].pixel = XGetPixel(image, x, y);
74 XQueryColors(display, attr.colormap, colors, attr.width);
75 for (x = 0; x < attr.width; ++x) {
76 cp->rgb.r = colors[x].red >> 8;
77 cp->rgb.g = colors[x].green >> 8;
78 cp->rgb.b = colors[x].blue >> 8;
81 i_plin(result, 0, attr.width, y, line);
84 XSetErrorHandler(old_handler);
86 XCloseDisplay(display);
92 imss_x11_open(char const *display_name) {
93 XErrorHandler old_handler;
97 XSetErrorHandler(my_handler);
98 display = XOpenDisplay(display_name);
100 i_push_errorf(0, "Cannot connect to X server %s", XDisplayName(display_name));
102 XSetErrorHandler(old_handler);
104 return (unsigned long)display;
108 imss_x11_close(unsigned long display) {
109 XCloseDisplay((Display *)display);