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