1ecce36beSmrg/* 2ecce36beSmrg * Copyright © 2008 Bart Massey <bart@cs.pdx.edu> 3ecce36beSmrg * 4ecce36beSmrg * Permission is hereby granted, free of charge, to any person 5ecce36beSmrg * obtaining a copy of this software and associated documentation 6ecce36beSmrg * files (the "Software"), to deal in the Software without 7ecce36beSmrg * restriction, including without limitation the rights to use, copy, 8ecce36beSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies 9ecce36beSmrg * of the Software, and to permit persons to whom the Software is 10ecce36beSmrg * furnished to do so, subject to the following conditions: 11ecce36beSmrg * 12ecce36beSmrg * The above copyright notice and this permission notice shall be 13ecce36beSmrg * included in all copies or substantial portions of the Software. 14ecce36beSmrg * 15ecce36beSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16ecce36beSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17ecce36beSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18ecce36beSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 19ecce36beSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20ecce36beSmrg * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21ecce36beSmrg * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22ecce36beSmrg * 23ecce36beSmrg * Except as contained in this notice, the names of the authors or 24ecce36beSmrg * their institutions shall not be used in advertising or otherwise to 25ecce36beSmrg * promote the sale, use or other dealings in this Software without 26ecce36beSmrg * prior written authorization from the authors. 27ecce36beSmrg */ 28ecce36beSmrg 29ecce36beSmrg#include <stdio.h> 30ecce36beSmrg#include <stdlib.h> 31ecce36beSmrg#include <string.h> 32ecce36beSmrg#include <xcb/xcb.h> 33ecce36beSmrg#include "../aux/xcb_aux.h" 34ecce36beSmrg#include "../aux/xcb_bitops.h" 35ecce36beSmrg#include "xcb_image.h" 36ecce36beSmrg 37ecce36beSmrg#define WIDTH 50 38ecce36beSmrg#define HEIGHT 50 39ecce36beSmrg 40ecce36beSmrgstatic uint32_t 41ecce36beSmrgcolor (uint32_t depth, uint32_t x, uint32_t y) 42ecce36beSmrg{ 43ecce36beSmrg uint32_t p; 44ecce36beSmrg 45ecce36beSmrg if (depth == 1) { 46ecce36beSmrg extern long random(); 47ecce36beSmrg int frac = random() % (WIDTH * HEIGHT); 48ecce36beSmrg p = x * y >= frac; 49ecce36beSmrg return p; 50ecce36beSmrg } 51ecce36beSmrg depth /= 3; 52ecce36beSmrg p = ((1 << depth) - 1) * x * y / WIDTH / HEIGHT; 53ecce36beSmrg return (p << depth) | (p << (2 * depth)); 54ecce36beSmrg} 55ecce36beSmrg 56ecce36beSmrgstatic xcb_image_t *create_image(xcb_connection_t *c, int depth, int format) 57ecce36beSmrg{ 58ecce36beSmrg xcb_image_t *im; 59ecce36beSmrg int x, y; 60ecce36beSmrg printf("Image depth %d, format %d\n", depth, format); 61ecce36beSmrg im = xcb_image_create_native(c, WIDTH, HEIGHT, 62ecce36beSmrg format, depth, 0, 0, 0); 63ecce36beSmrg for(x = 0; x < WIDTH; ++x) 64ecce36beSmrg for(y = 0; y < HEIGHT; ++y) 65ecce36beSmrg xcb_image_put_pixel(im, x, y, color(depth, x, y)); 66ecce36beSmrg return im; 67ecce36beSmrg} 68ecce36beSmrg 69ecce36beSmrgstatic xcb_window_t create_window(xcb_connection_t *c, xcb_screen_t *root) 70ecce36beSmrg{ 71ecce36beSmrg static const uint32_t mask = XCB_CW_EVENT_MASK; 72ecce36beSmrg static const uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE }; 73ecce36beSmrg unsigned int seq; 74ecce36beSmrg xcb_window_t w = xcb_generate_id(c); 75ecce36beSmrg seq = xcb_create_window(c, root->root_depth, w, root->root, 30, 30, WIDTH, HEIGHT, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, root->root_visual, mask, values).sequence; 76ecce36beSmrg printf("CreateWindow sequence %d, depth %d\n", seq, root->root_depth); 77ecce36beSmrg seq = xcb_map_window(c, w).sequence; 78ecce36beSmrg printf("MapWindow sequence %d\n", seq); 79ecce36beSmrg return w; 80ecce36beSmrg} 81ecce36beSmrg 82ecce36beSmrgstatic xcb_pixmap_t create_pixmap(xcb_connection_t *c, xcb_drawable_t d, uint8_t depth) 83ecce36beSmrg{ 84ecce36beSmrg xcb_pixmap_t p = xcb_generate_id(c); 85ecce36beSmrg unsigned int seq; 86ecce36beSmrg seq = xcb_create_pixmap(c, depth, p, d, WIDTH, HEIGHT).sequence; 87ecce36beSmrg printf("CreatePixmap sequence %d, depth %d\n", seq, depth); 88ecce36beSmrg return p; 89ecce36beSmrg} 90ecce36beSmrg 91ecce36beSmrgstatic xcb_gcontext_t create_gcontext(xcb_connection_t *c, 92ecce36beSmrg xcb_drawable_t d, 93ecce36beSmrg xcb_screen_t *root) 94ecce36beSmrg{ 95ecce36beSmrg static const uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; 96ecce36beSmrg const uint32_t values[] = { root->black_pixel, 0xffff }; 97ecce36beSmrg unsigned int seq; 98ecce36beSmrg xcb_gcontext_t gc = xcb_generate_id(c); 99ecce36beSmrg seq = xcb_create_gc(c, gc, d, mask, values).sequence; 100ecce36beSmrg printf("CreateGC sequence %d\n", seq); 101ecce36beSmrg return gc; 102ecce36beSmrg} 103ecce36beSmrg 104ecce36beSmrg 105ecce36beSmrgtypedef struct { 106ecce36beSmrg char *name; 107ecce36beSmrg xcb_image_format_t format; 108ecce36beSmrg uint8_t depth; 109ecce36beSmrg} format_t; 110ecce36beSmrg 111ecce36beSmrgstatic format_t formats[] = { 112ecce36beSmrg {"z-pixmap", XCB_IMAGE_FORMAT_Z_PIXMAP, 24}, 113ecce36beSmrg {"xy-bitmap", XCB_IMAGE_FORMAT_XY_BITMAP, 1}, 114ecce36beSmrg {"xy-pixmap-1", XCB_IMAGE_FORMAT_XY_PIXMAP, 1}, 115ecce36beSmrg {"xy-pixmap-24", XCB_IMAGE_FORMAT_XY_PIXMAP, 24}, 116ecce36beSmrg {0, 0, 0} 117ecce36beSmrg}; 118ecce36beSmrg 119ecce36beSmrgstatic format_t * 120ecce36beSmrgparse_format (char *name) { 121ecce36beSmrg format_t *f; 122ecce36beSmrg for (f = formats; f->name; f++) 123ecce36beSmrg if (!strcmp(name, f->name)) 124ecce36beSmrg return f; 125ecce36beSmrg fprintf(stderr, "%s: bad format: known formats are:\n", name); 126ecce36beSmrg for (f = formats; f->name; f++) 127ecce36beSmrg fprintf(stderr, "\t%s\n", f->name); 128ecce36beSmrg exit(1); 129ecce36beSmrg} 130ecce36beSmrg 131ecce36beSmrgint main(int argc, char **argv) 132ecce36beSmrg{ 133ecce36beSmrg int screen, depth; 134ecce36beSmrg format_t *format = &formats[0]; 135ecce36beSmrg xcb_screen_t *root; 136ecce36beSmrg xcb_visualtype_t *visual; 137ecce36beSmrg xcb_image_t *im; 138ecce36beSmrg xcb_drawable_t d, w = XCB_NONE; 139ecce36beSmrg xcb_gcontext_t dgc, wgc = 0; 140ecce36beSmrg xcb_generic_event_t *ev; 141ecce36beSmrg xcb_connection_t *c = xcb_connect(0, &screen); 142ecce36beSmrg if(!c) 143ecce36beSmrg { 144ecce36beSmrg printf("Connection failed.\n"); 145ecce36beSmrg exit(1); 146ecce36beSmrg } 147ecce36beSmrg root = xcb_aux_get_screen(c, screen); 148ecce36beSmrg assert(root); 149ecce36beSmrg visual = xcb_aux_find_visual_by_id(root, root->root_visual); 150ecce36beSmrg assert(visual); 151ecce36beSmrg if(argc > 1) 152ecce36beSmrg format = parse_format(argv[1]); 153ecce36beSmrg if (root->root_depth != 24 || 154ecce36beSmrg visual->_class != XCB_VISUAL_CLASS_TRUE_COLOR) 155ecce36beSmrg { 156ecce36beSmrg printf("Only 24 bit TrueColor visuals for now\n"); 157ecce36beSmrg exit(1); 158ecce36beSmrg } 159ecce36beSmrg depth = format->depth; 160ecce36beSmrg 161ecce36beSmrg im = create_image(c, depth, format->format); 162ecce36beSmrg d = create_window(c, root); 163ecce36beSmrg if(format->format == XCB_IMAGE_FORMAT_XY_PIXMAP && depth == 1) 164ecce36beSmrg { 165ecce36beSmrg w = d; 166ecce36beSmrg d = create_pixmap(c, w, depth); 167ecce36beSmrg } 168ecce36beSmrg dgc = create_gcontext(c, d, root); 169ecce36beSmrg if (w) 170ecce36beSmrg wgc = create_gcontext(c, w, root); 171ecce36beSmrg xcb_flush(c); 172ecce36beSmrg 173ecce36beSmrg if(im) 174ecce36beSmrg { 175ecce36beSmrg while((ev = xcb_wait_for_event(c))) 176ecce36beSmrg { 177ecce36beSmrg if(ev->response_type == XCB_EXPOSE && ((xcb_expose_event_t *) ev)->count == 0) 178ecce36beSmrg { 179ecce36beSmrg printf("ImagePut sequence %d\n", xcb_image_put(c, d, dgc, im, 0, 0, 0).sequence); 180ecce36beSmrg if(w) 181ecce36beSmrg { 182ecce36beSmrg unsigned int seq; 183ecce36beSmrg seq = xcb_copy_plane(c, d, w, wgc, 184ecce36beSmrg 0, 0, 0, 0, 185ecce36beSmrg WIDTH, HEIGHT, 1).sequence; 186ecce36beSmrg printf("CopyPlane sequence %d\n", seq); 187ecce36beSmrg } 188ecce36beSmrg xcb_flush(c); 189ecce36beSmrg } 190ecce36beSmrg else if(ev->response_type == 0) 191ecce36beSmrg { 192ecce36beSmrg xcb_generic_error_t *err = (xcb_generic_error_t *) ev; 193ecce36beSmrg printf("Error: %d after sequence %d\n", err->error_code, (unsigned int) err->full_sequence); 194ecce36beSmrg } 195ecce36beSmrg free(ev); 196ecce36beSmrg } 197ecce36beSmrg xcb_image_destroy(im); 198ecce36beSmrg } 199ecce36beSmrg 200ecce36beSmrg xcb_disconnect(c); 201ecce36beSmrg exit(0); 202ecce36beSmrg} 203