Replace deprecated Automake INCLUDES variable with AM_CPPFLAGS
[free-sw/xcb/demo] / tests / julia.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdbool.h>
4 #include <string.h>
5 #include <assert.h>
6
7 #include <xcb/xcb.h>
8 #include <xcb/shm.h>
9 #include <xcb/xcb_aux.h>
10 #include <xcb/xcb_image.h>
11 #include <xcb/xcb_atom.h>
12 #define XCB_ALL_PLANES ~0
13
14 /* Needed for xcb_set_wm_protocols() */
15 #include <xcb/xcb_icccm.h>
16
17 #include "julia.h"
18
19 #define W_W 640
20 #define W_H 480
21
22 /* Parameters of the fractal */
23
24 /* double cr = -0.7927; */
25 /* double ci = 0.1609; */
26
27 /* double cr = 0.32; */
28 /* double ci = 0.043; */
29
30 /* double cr = -1.1380; */
31 /* double ci = -0.2403; */
32
33 /* double cr = -0.0986; */
34 /* double ci = -0.65186; */
35
36 /* double cr = -0.1225; */
37 /* double ci = 0.7449; */
38
39 double cr = -0.3380;
40 double ci = -0.6230;
41 double origin_x = -1.8;
42 double origin_y = -1.2;
43 double width = 3.6;
44 double height = 2.4;
45
46 /* Numbers of colors in the palette */
47 int cmax = 316;
48
49 void
50 palette_julia (Data *datap)
51 {
52   xcb_alloc_color_reply_t *rep;
53   int               i;
54
55   datap->palette = (uint32_t *)malloc (sizeof (uint32_t) * cmax);
56   
57   for (i = 0 ; i < cmax ; i++)
58     {
59       if (i < 128)
60         rep = xcb_alloc_color_reply (datap->conn,
61                                   xcb_alloc_color (datap->conn,
62                                                  datap->cmap,
63                                                  i<<9, 0, 0),
64                                   0);
65       else if (i < 255)
66         rep = xcb_alloc_color_reply (datap->conn,
67                                   xcb_alloc_color (datap->conn,
68                                                  datap->cmap,
69                                                  65535, (i-127)<<9, 0),
70                                   0);
71       else
72         rep = xcb_alloc_color_reply (datap->conn,
73                                   xcb_alloc_color (datap->conn,
74                                                  datap->cmap,
75                                                  65535, 65535, (i-255)<<10),
76                                   0);
77       
78       if (!rep)
79         datap->palette[i] = 0;
80       else
81         datap->palette[i] = rep->pixel;
82       free (rep);
83     }
84   
85 }
86
87 void
88 draw_julia (Data *datap)
89 {
90   double    zr, zi, t;
91   int       c;
92   int       i, j;
93   
94   datap->image = xcb_image_get (datap->conn, datap->draw,
95                        0, 0, W_W, W_H,
96                        XCB_ALL_PLANES, datap->format);
97   
98   assert(datap->image);
99
100   for (i = 0 ; i < datap->image->width ; i++)
101     for (j = 0 ; j < datap->image->height ; j++)
102       {
103         zr = origin_x + width * (double)i / (double)datap->image->width;
104         zi = origin_y + height * (double)j / (double)datap->image->height;
105         c = 0;
106         while ((zr*zr + zi*zi < 4.0) &&
107                (c < cmax-1))
108           {
109             t = zr;
110             zr = zr*zr - zi*zi + cr;
111             zi = 2.0*t*zi + ci;
112             c++;
113           }
114         xcb_image_put_pixel (datap->image,
115                           i,j,
116                           datap->palette[c]);
117       }
118
119   xcb_image_put (datap->conn, datap->draw, datap->gc, datap->image,
120                0, 0, 0);
121 }
122
123 int
124 main (int argc, char *argv[])
125 {
126   Data             data;
127   xcb_screen_t       *screen;
128   xcb_drawable_t      win;
129   xcb_drawable_t      rect;
130   xcb_gcontext_t      bgcolor;
131   uint32_t           mask;
132   uint32_t           valgc[2];
133   uint32_t           valwin[3];
134   xcb_rectangle_t     rect_coord = { 0, 0, W_W, W_H};
135   int              screen_num;
136   
137   data.conn = xcb_connect (0, &screen_num);
138   screen = xcb_aux_get_screen (data.conn, screen_num);
139   data.depth = xcb_aux_get_depth (data.conn, screen);
140
141   win = screen->root;
142
143   data.gc = xcb_generate_id (data.conn);
144   mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
145   valgc[0] = screen->black_pixel;
146   valgc[1] = 0; /* no graphics exposures */
147   xcb_create_gc (data.conn, data.gc, win, mask, valgc);
148
149   bgcolor = xcb_generate_id (data.conn);
150   mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
151   valgc[0] = screen->white_pixel;
152   valgc[1] = 0; /* no graphics exposures */
153   xcb_create_gc (data.conn, bgcolor, win, mask, valgc);
154
155   data.draw = xcb_generate_id (data.conn);
156   mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
157   valwin[0] = screen->white_pixel;
158   valwin[1] = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE;
159   valwin[2] = XCB_EVENT_MASK_BUTTON_PRESS;
160   xcb_create_window (data.conn, 0,
161                    data.draw,
162                    screen->root,
163                    0, 0, W_W, W_H,
164                    10,
165                    XCB_WINDOW_CLASS_INPUT_OUTPUT,
166                    screen->root_visual,
167                    mask, valwin);
168   xcb_map_window (data.conn, data.draw);
169
170   rect = xcb_generate_id (data.conn);
171   xcb_create_pixmap (data.conn, data.depth,
172                    rect, data.draw,
173                    W_W, W_H);
174   xcb_poly_fill_rectangle(data.conn, rect, bgcolor, 1, &rect_coord);
175
176   xcb_map_window (data.conn, data.draw);
177
178   data.format = XCB_IMAGE_FORMAT_Z_PIXMAP;
179
180   data.cmap = xcb_generate_id (data.conn);
181   xcb_create_colormap (data.conn,
182                      XCB_COLORMAP_ALLOC_NONE,
183                      data.cmap,
184                      data.draw,
185                      screen->root_visual);
186
187   palette_julia (&data);
188
189   xcb_atom_t deleteWindowAtom = xcb_atom_get(data.conn, "WM_DELETE_WINDOW");
190   xcb_atom_t wmprotocolsAtom = xcb_atom_get(data.conn, "WM_PROTOCOLS");
191   /* Listen to X client messages in order to be able to pickup
192      the "delete window" message that is generated for example
193      when someone clicks the top-right X button within the window
194      manager decoration (or when user hits ALT-F4). */
195   xcb_set_wm_protocols (data.conn, wmprotocolsAtom, data.draw, 1, &deleteWindowAtom);
196
197   xcb_flush (data.conn); 
198
199   bool finished = false;
200   while (!finished)
201     {
202       xcb_generic_event_t *e;
203       if (e = xcb_wait_for_event(data.conn))
204         {
205           switch (XCB_EVENT_RESPONSE_TYPE(e))
206             {
207             case XCB_EXPOSE:
208               {
209                 xcb_copy_area(data.conn, rect, data.draw, bgcolor,
210                                 0, 0, 0, 0, W_W, W_H);
211                 draw_julia (&data);
212                 xcb_flush (data.conn);
213                 break;
214               }
215             case XCB_CLIENT_MESSAGE:
216               {
217                 if (((xcb_client_message_event_t *)e)->data.data32[0] == deleteWindowAtom)
218                   {
219                     finished = true;
220                   }
221                 break;
222               }
223             case XCB_BUTTON_PRESS:
224               {
225                 finished = true;
226                 break;
227               }
228           }
229         free (e);
230       }
231     }
232
233   if (data.palette)
234     free (data.palette);
235   if (data.image)
236     xcb_image_destroy (data.image);
237   xcb_disconnect (data.conn);
238
239   return 0;
240 }