be3b217e9c11dafa5b0f8e6ab3ee27e5339f2c1c
[framework/uifw/xorg/xcb/xcb-util.git] / image / test_formats.c
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
40 static uint32_t
41 color (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
56 static 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
69 static 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
82 static 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
91 static 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
105 typedef struct {
106         char *name;
107         xcb_image_format_t format;
108         uint8_t depth;
109 } format_t;
110
111 static 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
119 static format_t *
120 parse_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
131 int 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 }