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