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