1 /*****************************************************************************/
3 /*****************************************************************************/
5 /* The Rasterman (Carsten Haitzler) */
6 /* Copyright (C) 1996 */
7 /*****************************************************************************/
9 /* d'Oursse (Vincent TORRI), 2006 */
10 /*****************************************************************************/
11 /* This code is Freeware. You may copy it, modify it or do with it as you */
12 /* please, but you may not claim copyright on any code wholly or partly */
13 /* based on this code. I accept no responisbility for any consequences of */
14 /* using this code, be they proper or otherwise. */
15 /*****************************************************************************/
16 /* Okay, now all the legal mumbo-jumbo is out of the way, I will just say */
17 /* this: enjoy this program, do with it as you please and watch out for more */
18 /* code releases from The Rasterman running under X... the only way to code. */
19 /*****************************************************************************/
21 /* standard library */
29 #include <X11/XCB/xcb.h>
30 #include <X11/XCB/shm.h>
31 #include <X11/XCB/xcb_aux.h>
32 #include <X11/XCB/xcb_image.h>
33 #include <X11/XCB/xcb_icccm.h>
35 /* some defines for the flame */
42 /* default width and height of the window */
61 unsigned int pal[IMAX];
65 /* the flame arrays */
72 static void title_set (flame *f, const char *title);
73 static int ilog2 (unsigned int n);
74 static void flame_set_palette (flame *f);
75 static void flame_set_flame_zero (flame *f);
76 static void flame_set_random_flame_base (flame *f);
77 static void flame_modify_flame_base (flame *f);
78 static void flame_process_flame (flame *f);
79 static void flame_draw_flame (flame *f);
86 XCBGCONTEXT gc = { 0 };
93 XCBRECTANGLE rect_coord = { 0, 0, BG_W, BG_H};
95 f = (flame *)malloc (sizeof (flame));
99 f->xcb.c = XCBConnect (NULL, &screen_nbr);
105 screen = XCBAuxGetScreen (f->xcb.c, screen_nbr);
107 f->xcb.draw.window = screen->root;
108 f->xcb.gc = XCBGCONTEXTNew (f->xcb.c);
109 mask = XCBGCForeground | XCBGCGraphicsExposures;
110 values[0] = screen->black_pixel;
111 values[1] = 0; /* no graphics exposures */
112 XCBCreateGC (f->xcb.c, f->xcb.gc, f->xcb.draw, mask, values);
114 gc = XCBGCONTEXTNew (f->xcb.c);
115 mask = XCBGCForeground | XCBGCGraphicsExposures;
116 values[0] = screen->white_pixel;
117 values[1] = 0; /* no graphics exposures */
118 XCBCreateGC (f->xcb.c, gc, f->xcb.draw, mask, values);
120 f->xcb.depth = XCBAuxGetDepth (f->xcb.c, screen);
121 mask = XCBCWBackPixel | XCBCWEventMask;
122 values[0] = screen->white_pixel;
123 values[1] = XCBEventMaskExposure | XCBEventMaskButtonPress;
124 f->xcb.draw.window = XCBWINDOWNew (f->xcb.c);
125 XCBCreateWindow (f->xcb.c, f->xcb.depth,
130 XCBWindowClassInputOutput,
133 title_set (f, "XCB Flames");
135 f->xcb.pixmap.pixmap = XCBPIXMAPNew (f->xcb.c);
136 XCBCreatePixmap (f->xcb.c, f->xcb.depth,
137 f->xcb.pixmap.pixmap, f->xcb.draw,
139 XCBPolyFillRectangle(f->xcb.c, f->xcb.pixmap, gc, 1, &rect_coord);
141 XCBMapWindow (f->xcb.c, f->xcb.draw.window);
144 f->xcb.cmap = XCBCOLORMAPNew (f->xcb.c);
145 XCBCreateColormap (f->xcb.c,
146 XCBColormapAllocNone,
149 screen->root_visual);
151 /* Allocation of the flame arrays */
152 flame_width = BG_W >> 1;
153 flame_height = BG_H >> 1;
154 f->ws = ilog2 (flame_width);
155 size = (1 << f->ws) * flame_height * sizeof (unsigned int);
156 f->flame = (unsigned int *)malloc (size);
159 XCBDisconnect (f->xcb.c);
163 f->flame2 = (unsigned int *)malloc (size);
167 XCBDisconnect (f->xcb.c);
172 /* allocation of the image */
173 f->ims = ilog2 (BG_W);
175 /* initialization of the palette */
176 flame_set_palette (f);
182 flame_shutdown (flame *f)
189 XCBDisconnect (f->xcb.c);
198 XCBGCONTEXT gc = { 0 };
203 printf ("Can't initialize global data\nExiting...\n");
207 flame_set_flame_zero (f);
208 flame_set_random_flame_base (f);
212 if ((e = XCBPollForEvent (f->xcb.c, NULL)))
214 switch (e->response_type)
217 XCBCopyArea(f->xcb.c, f->xcb.pixmap, f->xcb.draw, gc,
218 0, 0, 0, 0, BG_W, BG_H);
222 printf ("Exiting...\n");
228 flame_draw_flame (f);
229 XCBSync (f->xcb.c, 0);
238 static void title_set (flame *f, const char *title)
240 XCBInternAtomRep *rep;
245 atom_name = "UTF8_STRING";
246 rep = XCBInternAtomReply (f->xcb.c,
247 XCBInternAtom (f->xcb.c,
252 encoding = rep->atom;
256 /* SetWMName (f->xcb.c, f->xcb.draw.window, encoding, strlen (title), title); */
259 atom_name = "_NET_WM_NAME";
260 rep = XCBInternAtomReply (f->xcb.c,
261 XCBInternAtom (f->xcb.c,
266 XCBChangeProperty(f->xcb.c, XCBPropModeReplace,
268 rep->atom, encoding, 8, strlen (title), title);
273 flame_draw_flame (flame *f)
287 /* modify the base of the flame */
288 flame_modify_flame_base (f);
289 /* process the flame array, propagating the flames up the array */
290 flame_process_flame (f);
292 image = XCBImageGet (f->xcb.c, f->xcb.draw,
294 XCBAllPlanes, XCBImageFormatZPixmap);
295 f->im = (unsigned int *)image->data;
297 for (y = 0 ; y < ((BG_H >> 1) - 1) ; y++)
299 for (x = 0 ; x < ((BG_W >> 1) - 1) ; x++)
304 ptr = f->flame2 + (y << f->ws) + x;
305 cl1 = cl = (int)*ptr;
306 ptr = f->flame2 + (y << f->ws) + x + 1;
308 ptr = f->flame2 + ((y + 1) << f->ws) + x + 1;
310 ptr = f->flame2 + ((y + 1) << f->ws) + x;
314 XCBImagePutPixel (image,
317 XCBImagePutPixel (image,
319 f->pal[((cl1+cl2) >> 1)]);
320 XCBImagePutPixel (image,
322 f->pal[((cl1 + cl3) >> 1)]);
323 XCBImagePutPixel (image,
325 f->pal[((cl1 + cl4) >> 1)]);
328 XCBImagePut (f->xcb.c, f->xcb.draw, f->xcb.gc, image,
329 0, 0, 0, 0, BG_W, BG_H);
330 XCBImageDestroy (image);
333 /* set the flame palette */
335 flame_set_palette (flame *f)
337 XCBAllocColorCookie cookies[IMAX];
338 XCBAllocColorRep *rep;
344 for (i = 0 ; i < IMAX ; i++)
351 if (r > 255) r = 255;
353 if (g > 255) g = 255;
355 if (b > 255) b = 255;
357 cookies[i] = XCBAllocColor (f->xcb.c, f->xcb.cmap,
358 r << 8, g << 8, b << 8);
361 for (i = 0 ; i < IMAX ; i++)
363 rep = XCBAllocColorReply (f->xcb.c, cookies[i], NULL);
364 f->pal[i] = rep->pixel;
369 /* set the flame array to zero */
371 flame_set_flame_zero (flame *f)
377 for (y = 0 ; y < (BG_H >> 1) ; y++)
379 for (x = 0 ; x < (BG_W >> 1) ; x++)
381 ptr = f->flame + (y << f->ws) + x;
388 flame_set_random_flame_base (flame *f)
394 /* initialize a random number seed from the time, so we get random */
395 /* numbers each time */
398 for (x = 0 ; x < (BG_W >> 1) ; x++)
400 ptr = f->flame + (y << f->ws) + x;
405 /* modify the base of the flame with random values */
407 flame_modify_flame_base (flame *f)
415 for (x = 0 ; x < (BG_W >> 1) ; x++)
417 ptr = f->flame + (y << f->ws) + x;
418 *ptr += ((rand ()%VARIANCE) - VARTREND);
420 if (val > IMAX) *ptr = 0;
421 if (val < 0) *ptr = 0;
425 /* process entire flame array */
427 flame_process_flame (flame *f)
436 for (y = ((BG_H >> 1) - 1) ; y >= 2 ; y--)
438 for (x = 1 ; x < ((BG_W >> 1) - 1) ; x++)
440 ptr = f->flame + (y << f->ws) + x;
441 val = (unsigned int)*ptr;
443 *ptr = (unsigned int)IMAX;
444 val = (unsigned int)*ptr;
447 tmp = (val * VSPREAD) >> 8;
448 p = ptr - (2 << f->ws);
449 *p = *p + (tmp >> 1);
450 p = ptr - (1 << f->ws);
452 tmp = (val * HSPREAD) >> 8;
453 p = ptr - (1 << f->ws) - 1;
455 p = ptr - (1 << f->ws) + 1;
458 *p = *p + (tmp >>1 );
460 *p = *p + (tmp >> 1);
461 p = f->flame2 + (y << f->ws) + x;
463 if (y < ((BG_H >> 1) - 1))
464 *ptr = (val * RESIDUAL) >> 8;
471 ilog2 (unsigned int n)