xcb.c 3.32 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
    Copyright (C) 2016  Jeremy White <jwhite@codeweavers.com>
    All rights reserved.

    This file is part of x11spice

    x11spice is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    x11spice is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with x11spice.  If not, see <http://www.gnu.org/licenses/>.
*/


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <xcb/xcb.h>


29 30
static void lookup_color(xcb_connection_t *c, xcb_screen_t *screen, const char *color,
                         uint32_t *pixel)
31 32 33 34 35
{
    xcb_lookup_color_cookie_t cookie;
    xcb_lookup_color_reply_t *r;
    xcb_alloc_color_cookie_t acookie;
    xcb_alloc_color_reply_t *ar;
36

37 38 39
    cookie = xcb_lookup_color(c, screen->default_colormap, strlen(color), color);
    r = xcb_lookup_color_reply(c, cookie, NULL);

40 41
    acookie =
        xcb_alloc_color(c, screen->default_colormap, r->exact_red, r->exact_green, r->exact_blue);
42 43 44 45 46 47 48
    free(r);

    ar = xcb_alloc_color_reply(c, acookie, NULL);
    *pixel = ar->pixel;
    free(ar);
}

49
static void create_rectangles(xcb_rectangle_t * red, xcb_rectangle_t * green, int w, int h)
50 51 52 53 54
{
    int x, y;
    int r, g;
    int i;

55
    for (i = 0; i < 32; i++) {
56 57 58 59 60 61
        red[i].width = green[i].width = w / 8;
        red[i].height = green[i].height = h / 8;
    }

    r = g = 0;
    for (x = 0; x < 8; x++)
62 63
        for (y = 0; y < 8; y++) {
            if (((y * 8) + x) % 2 == y % 2) {
64 65 66 67
                red[r].x = x * (w / 8);
                red[r].y = y * (h / 8);
                r++;
            }
68
            else {
69 70 71 72 73 74 75 76 77 78 79
                green[g].x = x * (w / 8);
                green[g].y = y * (h / 8);
                g++;
            }
        }
}

int xcb_draw_grid(const char *display)
{
    uint32_t pixels[2];

80 81 82 83
    xcb_connection_t *c;
    xcb_screen_t *screen;
    xcb_gcontext_t red_fg;
    xcb_gcontext_t green_fg;
84 85 86 87 88 89

    xcb_rectangle_t red_rectangles[32];
    xcb_rectangle_t green_rectangles[32];

    /* Open the connection to the X server */
    c = xcb_connect(display, NULL);
90 91
    if (xcb_connection_has_error(c))
        return 1;
92 93 94 95 96 97 98 99 100 101 102 103 104 105

    /* Get the first screen */
    screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data;

    red_fg = xcb_generate_id(c);
    lookup_color(c, screen, "red", &pixels[0]);
    pixels[1] = 0;
    xcb_create_gc(c, red_fg, screen->root, XCB_GC_FOREGROUND, pixels);

    green_fg = xcb_generate_id(c);
    lookup_color(c, screen, "green", &pixels[0]);
    pixels[1] = 0;
    xcb_create_gc(c, green_fg, screen->root, XCB_GC_FOREGROUND, pixels);

106 107
    create_rectangles(red_rectangles, green_rectangles, screen->width_in_pixels,
                      screen->height_in_pixels);
108 109 110 111 112 113

    /* We draw the rectangles */
    xcb_poly_fill_rectangle_checked(c, screen->root, red_fg, 32, red_rectangles);
    xcb_poly_fill_rectangle_checked(c, screen->root, green_fg, 32, green_rectangles);

    /* We flush the request */
114
    xcb_flush(c);
115 116 117 118 119

    xcb_disconnect(c);

    return 0;
}