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/* gcc -g -O2 -Wall `pkg-config --cflags --libs xcb` -o test xcb_image.o test_xcb_image.c */
30ecce36beSmrg
31ecce36beSmrg#include <stdlib.h>
32ecce36beSmrg#include <stdio.h>
33ecce36beSmrg
34ecce36beSmrg#include <xcb/xcb.h>
35ecce36beSmrg
36ecce36beSmrg#include "../aux/xcb_aux.h"
37ecce36beSmrg#include "xcb_image.h"
38ecce36beSmrg
39ecce36beSmrg#define W_W 64
40ecce36beSmrg#define W_H 64
41ecce36beSmrg
42ecce36beSmrgvoid
43ecce36beSmrgreflect_window (xcb_connection_t *c,
44ecce36beSmrg		xcb_drawable_t win,
45ecce36beSmrg		xcb_drawable_t new_win,
46ecce36beSmrg		xcb_gcontext_t gc,
47ecce36beSmrg		uint16_t      width,
48ecce36beSmrg		uint16_t      height)
49ecce36beSmrg{
50ecce36beSmrg  xcb_image_t *image;
51ecce36beSmrg  uint32_t    pixel1;
52ecce36beSmrg  uint32_t    pixel2;
53ecce36beSmrg  int32_t     left_x;
54ecce36beSmrg  int32_t     right_x;
55ecce36beSmrg  int32_t     y;
56ecce36beSmrg  int         format;
57ecce36beSmrg
58ecce36beSmrg  format = XCB_IMAGE_FORMAT_Z_PIXMAP;
59ecce36beSmrg
60ecce36beSmrg  printf ("get_image %d %d\n", width, height);
61ecce36beSmrg  image = xcb_image_get (c, win,
62ecce36beSmrg			 0, 0, width, height,
63ecce36beSmrg			 ~0,
64ecce36beSmrg			 format);
65ecce36beSmrg
66ecce36beSmrg  printf ("Create image summary:\n");
67ecce36beSmrg  printf (" * format................: %d\n", image->format);
68ecce36beSmrg  printf (" * byte order............: %d\n", image->byte_order);
69ecce36beSmrg  printf (" * bitmap order..........: %d\n", image->bit_order);
70ecce36beSmrg  printf (" * bitmap pad............: %d\n", image->scanline_pad);
71ecce36beSmrg  printf (" * depth.................: %d\n", image->depth);
72ecce36beSmrg  printf (" * bytes/line............: %d\n", image->stride);
73ecce36beSmrg  printf (" * bits/pixel (or unit)..: %d\n", image->bpp);
74ecce36beSmrg
75ecce36beSmrg  printf ("bpl %d %d\n", image->stride, image->height);
76ecce36beSmrg
77ecce36beSmrg  printf("calculating reflection -- this may take awhile...\n");
78ecce36beSmrg
79ecce36beSmrg  for (left_x = 0 ; left_x < width/2 ; left_x++)
80ecce36beSmrg    {
81ecce36beSmrg      for (y = 0 ; y < height ; y++)
82ecce36beSmrg	{
83ecce36beSmrg	  pixel1 = xcb_image_get_pixel (image, left_x, y);
84ecce36beSmrg	  right_x = width - left_x-1;
85ecce36beSmrg	  if (left_x != right_x)
86ecce36beSmrg	    {
87ecce36beSmrg	      pixel2 = xcb_image_get_pixel (image, right_x, y);
88ecce36beSmrg	      xcb_image_put_pixel (image, left_x, y, pixel2);
89ecce36beSmrg	    }
90ecce36beSmrg	  xcb_image_put_pixel (image, right_x, y, pixel1);
91ecce36beSmrg	}
92ecce36beSmrg    }
93ecce36beSmrg
94ecce36beSmrg  printf("putting image\n");
95ecce36beSmrg
96ecce36beSmrg  xcb_image_put (c, new_win, gc, image, 0, 0, 0);
97ecce36beSmrg  image = xcb_image_get (c, new_win,
98ecce36beSmrg			 0, 0, width, height,
99ecce36beSmrg			 ~0,
100ecce36beSmrg			 format);
101ecce36beSmrg
102ecce36beSmrg  printf ("done\n");
103ecce36beSmrg}
104ecce36beSmrg
105ecce36beSmrgint
106ecce36beSmrgmain (int argc, char *argv[])
107ecce36beSmrg{
108ecce36beSmrg  xcb_connection_t   *c;
109ecce36beSmrg  xcb_screen_t       *screen;
110ecce36beSmrg  xcb_drawable_t      win;
111ecce36beSmrg  xcb_drawable_t      new_win;
112ecce36beSmrg  xcb_drawable_t      rect;
113ecce36beSmrg  xcb_rectangle_t     rect_coord = { 0, 0, W_W, W_H};
114ecce36beSmrg  xcb_gcontext_t      bgcolor, fgcolor;
115ecce36beSmrg  xcb_point_t         points[2];
116ecce36beSmrg  uint32_t           mask;
117ecce36beSmrg  uint32_t           valgc[2];
118ecce36beSmrg  uint32_t           valwin[3];
119ecce36beSmrg  int              depth;
120ecce36beSmrg  int              screen_nbr;
121ecce36beSmrg  xcb_generic_event_t *e;
122ecce36beSmrg
123ecce36beSmrg  /* Open the connexion to the X server and get the first screen */
124ecce36beSmrg  c = xcb_connect (NULL, &screen_nbr);
125ecce36beSmrg  screen = xcb_aux_get_screen (c, screen_nbr);
126ecce36beSmrg  depth = xcb_aux_get_depth (c, screen);
127ecce36beSmrg
128ecce36beSmrg  /* Create a black graphic context for drawing in the foreground */
129ecce36beSmrg  win = screen->root;
130ecce36beSmrg
131ecce36beSmrg  fgcolor = xcb_generate_id(c);
132ecce36beSmrg  mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
133ecce36beSmrg  valgc[0] = screen->black_pixel;
134ecce36beSmrg  valgc[1] = 0; /* no graphics exposures */
135ecce36beSmrg  xcb_create_gc(c, fgcolor, win, mask, valgc);
136ecce36beSmrg
137ecce36beSmrg  bgcolor = xcb_generate_id(c);
138ecce36beSmrg  mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
139ecce36beSmrg  valgc[0] = screen->white_pixel;
140ecce36beSmrg  valgc[1] = 0; /* no graphics exposures */
141ecce36beSmrg  xcb_create_gc(c, bgcolor, win, mask, valgc);
142ecce36beSmrg
143ecce36beSmrg  /* Ask for our window's Id */
144ecce36beSmrg  win = xcb_generate_id(c);
145ecce36beSmrg
146ecce36beSmrg  /* Create the window */
147ecce36beSmrg  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
148ecce36beSmrg  valwin[0] = screen->white_pixel;
149ecce36beSmrg  valwin[1] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE;
150ecce36beSmrg  valwin[2] = XCB_EVENT_MASK_BUTTON_PRESS;
151ecce36beSmrg  xcb_create_window (c,                        /* Connection          */
152ecce36beSmrg 		   0,                        /* depth               */
153ecce36beSmrg		   win,                      /* window Id           */
154ecce36beSmrg		   screen->root,             /* parent window       */
155ecce36beSmrg		   0, 0,                     /* x, y                */
156ecce36beSmrg		   W_W, W_H,                 /* width, height       */
157ecce36beSmrg		   10,                       /* border_width        */
158ecce36beSmrg		   XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class               */
159ecce36beSmrg		   screen->root_visual,      /* visual              */
160ecce36beSmrg		   mask, valwin);                 /* masks, not used yet */
161ecce36beSmrg
162ecce36beSmrg  /* Map the window on the screen */
163ecce36beSmrg  xcb_map_window (c, win);
164ecce36beSmrg
165ecce36beSmrg  /* Create a Pixmap that will fill the window */
166ecce36beSmrg  rect = xcb_generate_id (c);
167ecce36beSmrg  xcb_create_pixmap(c, depth, rect, win, W_W, W_H);
168ecce36beSmrg  xcb_poly_fill_rectangle(c, rect, bgcolor, 1, &rect_coord);
169ecce36beSmrg  points[0].x = 0;
170ecce36beSmrg  points[0].y = 0;
171ecce36beSmrg  points[1].x = W_W;
172ecce36beSmrg  points[1].y = W_H;
173ecce36beSmrg  xcb_poly_line(c, XCB_COORD_MODE_ORIGIN, rect, fgcolor, 2, points);
174ecce36beSmrg  points[0].x = W_W / 4;
175ecce36beSmrg  points[0].y = 0;
176ecce36beSmrg  points[1].x = W_W / 2;
177ecce36beSmrg  points[1].y = W_H / 2;
178ecce36beSmrg  xcb_poly_line(c, XCB_COORD_MODE_ORIGIN, rect, fgcolor, 2, points);
179ecce36beSmrg
180ecce36beSmrg  /* Ask for our window's Id */
181ecce36beSmrg  new_win = xcb_generate_id(c);
182ecce36beSmrg
183ecce36beSmrg  /* Create the window */
184ecce36beSmrg  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
185ecce36beSmrg  valwin[0] = screen->white_pixel;
186ecce36beSmrg  valwin[1] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE;
187ecce36beSmrg  valwin[2] = XCB_EVENT_MASK_BUTTON_PRESS;
188ecce36beSmrg  xcb_create_window (c,                        /* Connection          */
189ecce36beSmrg 		   0,                        /* depth               */
190ecce36beSmrg		   new_win,                  /* window Id           */
191ecce36beSmrg		   screen->root,             /* parent window       */
192ecce36beSmrg		   0, 0,                     /* x, y                */
193ecce36beSmrg		   W_W, W_H,                 /* width, height       */
194ecce36beSmrg		   10,                       /* border_width        */
195ecce36beSmrg		   XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class               */
196ecce36beSmrg		   screen->root_visual,      /* visual              */
197ecce36beSmrg		   mask, valwin);                 /* masks, not used yet */
198ecce36beSmrg
199ecce36beSmrg
200ecce36beSmrg
201ecce36beSmrg  /* Map the window on the screen */
202ecce36beSmrg  xcb_map_window (c, new_win);
203ecce36beSmrg
204ecce36beSmrg
205ecce36beSmrg  xcb_flush (c);
206ecce36beSmrg
207ecce36beSmrg  while ((e = xcb_wait_for_event(c)))
208ecce36beSmrg    {
209ecce36beSmrg      switch (e->response_type)
210ecce36beSmrg	{
211ecce36beSmrg	case XCB_EXPOSE:
212ecce36beSmrg	  {
213ecce36beSmrg	    xcb_copy_area(c, rect, win, bgcolor,
214ecce36beSmrg			0, 0, 0, 0, W_W, W_H);
215ecce36beSmrg	    reflect_window (c, win, new_win,
216ecce36beSmrg			    fgcolor,
217ecce36beSmrg			    W_W, W_H);
218ecce36beSmrg	    xcb_flush (c);
219ecce36beSmrg	    break;
220ecce36beSmrg	  }
221ecce36beSmrg	}
222ecce36beSmrg      free (e);
223ecce36beSmrg    }
224ecce36beSmrg
225ecce36beSmrg  return 1;
226ecce36beSmrg}
227