-/* xflame, Copyright (c) 1996-1999 Carsten Haitzler <raster@redhat.com>
+/* xflame, Copyright (c) 1996-2002 Carsten Haitzler <raster@redhat.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
behavioral constants.
- General cleanup and portability tweaks.
+
+ * 4-Oct-99, jwz: added support for packed-24bpp (versus 32bpp.)
+ * 16-Jan-2002, jwz: added gdk_pixbuf support.
+
*/
#include "screenhack.h"
+#include "xpm-pixmap.h"
#include <X11/Xutil.h>
#include <limits.h>
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
#ifdef HAVE_XSHM_EXTENSION
# include "xshm.h"
#endif /* HAVE_XSHM_EXTENSION */
-#ifdef HAVE_XPM
-# include <X11/xpm.h>
-# ifndef PIXEL_ALREADY_TYPEDEFED
-# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */
-# endif
-#endif
-
-#ifdef HAVE_XMU
-# ifndef VMS
-# include <X11/Xmu/Drawing.h>
-# else /* VMS */
-# include <Xmu/Drawing.h>
-# endif /* VMS */
-#endif /* HAVE_XMU */
+#include "images/bob.xbm"
-#define MAX 255
+#define MAX_VAL 255
static Display *display;
static Window window;
static int height;
static Colormap colormap;
static Visual *visual;
+static Screen *screen;
static Bool shared;
+static Bool bloom;
static XImage *xim;
#ifdef HAVE_XSHM_EXTENSION
static XShmSegmentInfo shminfo;
colormap = xwa.colormap;
depth = xwa.depth;
visual = xwa.visual;
+ screen = xwa.screen;
width = xwa.width;
height = xwa.height;
static void
InitColors(void)
{
- int i = 0, j = 0;
+ int i = 0, j = 0, red = 0, green = 0, blue = 0;
+ XColor fg;
+
+ /* Make it possible to set the color of the flames,
+ by Raymond Medeiros <ray@stommel.marine.usf.edu> and jwz.
+ */
+ fg.pixel = get_pixel_resource ("foreground", "Foreground",
+ display, colormap);
+ XQueryColor (display, colormap, &fg);
+
+ red = 255 - (fg.red >> 8);
+ green = 255 - (fg.green >> 8);
+ blue = 255 - (fg.blue >> 8);
+
+
for (i = 0; i < 256 * 2; i += 2)
{
XColor xcl;
- int r = (i - 0) * 3;
- int g = (i - 80) * 3;
- int b = (i - 160) * 3;
+ int r = (i - red) * 3;
+ int g = (i - green) * 3;
+ int b = (i - blue) * 3;
if (r < 0) r = 0;
if (r > 255) r = 255;
iresidual = get_integer_resource("residual", "Integer");
variance = get_integer_resource("variance", "Integer");
vartrend = get_integer_resource("vartrend", "Integer");
+ bloom = get_boolean_resource("bloom", "Boolean");
# define THROTTLE(VAR,NAME) \
if (VAR < 0 || VAR > 255) { \
}
}
+static void
+Flame2Image24(void)
+{
+ int x,y;
+ unsigned char *ptr;
+ unsigned char *ptr1;
+ int v1,v2,v3,v4;
+
+ ptr = (unsigned char *)xim->data;
+ ptr += (top << 1) * xim->bytes_per_line;
+ ptr1 = flame + 1 + (top * (fwidth + 2));
+
+ for( y = top; y < fheight; y++)
+ {
+ unsigned char *last_ptr = ptr;
+ for( x = 0; x < fwidth; x++)
+ {
+ v1 = (int)*ptr1;
+ v2 = (int)*(ptr1 + 1);
+ v3 = (int)*(ptr1 + fwidth + 2);
+ v4 = (int)*(ptr1 + fwidth + 2 + 1);
+ ptr1++;
+
+ ptr[2] = ((unsigned int)ctab[v1] & 0x00FF0000) >> 16;
+ ptr[1] = ((unsigned int)ctab[v1] & 0x0000FF00) >> 8;
+ ptr[0] = ((unsigned int)ctab[v1] & 0x000000FF);
+ ptr += 3;
+
+ ptr[2] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x00FF0000) >> 16;
+ ptr[1] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x0000FF00) >> 8;
+ ptr[0] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x000000FF);
+ ptr += ((width - 1) * 3);
+
+ ptr[2] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x00FF0000) >> 16;
+ ptr[1] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x0000FF00) >> 8;
+ ptr[0] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x000000FF);
+ ptr += 3;
+
+ ptr[2] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x00FF0000) >> 16;
+ ptr[1] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x0000FF00) >> 8;
+ ptr[0] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x000000FF);
+ ptr -= ((width - 1) * 3);
+ }
+
+ ptr = last_ptr + (xim->bytes_per_line << 1);
+ ptr1 += 2;
+ }
+}
+
static void
Flame2Image8(void)
{
static void
Flame2Image(void)
{
- if (depth >= 24) Flame2Image32();
- else if (depth == 16) Flame2Image16();
- else if (depth == 8) Flame2Image8();
- else if (depth == 15) Flame2Image16();
- else if (depth < 8) Flame2Image1234567();
- else if (depth == 12) Flame2Image16();
+ switch (xim->bits_per_pixel)
+ {
+ case 32: Flame2Image32(); break;
+ case 24: Flame2Image24(); break;
+ case 16: Flame2Image16(); break;
+ case 8: Flame2Image8(); break;
+ default:
+ if (xim->bits_per_pixel <= 7)
+ Flame2Image1234567();
+ else
+ abort();
+ break;
+ }
}
+
static void
FlameActive(void)
{
*ptr1++ = v1 % 255;
}
- v1= (random() % 100);
- if (v1 == 10)
- residual += (random()%10);
- else if (v1 == 20)
- hspread += (random()%15);
- else if (v1 == 30)
- vspread += (random()%20);
+ if (bloom)
+ {
+ v1= (random() % 100);
+ if (v1 == 10)
+ residual += (random()%10);
+ else if (v1 == 20)
+ hspread += (random()%15);
+ else if (v1 == 30)
+ vspread += (random()%20);
+ }
residual = ((iresidual* 10) + (residual *90)) / 100;
hspread = ((ihspread * 10) + (hspread *90)) / 100;
v3 = (v1 * vspread) >> 8;
v2 = (int)*(ptr2);
v2 += v3;
- if (v2 > MAX)
- v2 = MAX;
+ if (v2 > MAX_VAL)
+ v2 = MAX_VAL;
*(ptr2) = (unsigned char)v2;
v3 = (v1 * hspread) >> 8;
v2 = (int)*(ptr2 + 1);
v2 += v3;
- if (v2 > MAX)
- v2 = MAX;
+ if (v2 > MAX_VAL)
+ v2 = MAX_VAL;
*(ptr2 + 1) = (unsigned char)v2;
v2 = (int)*(ptr2 - 1);
v2 += v3;
- if (v2 > MAX)
- v2 = MAX;
+ if (v2 > MAX_VAL)
+ v2 = MAX_VAL;
*(ptr2 - 1) = (unsigned char)v2;
if (used)
newtop = y - 1;
}
+
+ /* clean up the right gutter */
+ {
+ int v1 = (int)*ptr1;
+ v1 = (v1 * residual) >> 8;
+ *ptr1 = (unsigned char)v1;
+ }
}
top = newtop - 1;
{
char *bitmap_name = get_string_resource ("bitmap", "Bitmap");
- if (bitmap_name &&
- *bitmap_name &&
- !!strcmp(bitmap_name, "none"))
+ if (!bitmap_name ||
+ !*bitmap_name ||
+ !strcmp(bitmap_name, "none"))
+ ;
+ else if (!strcmp(bitmap_name, "(default)")) /* use the builtin */
+ {
+ XImage *ximage;
+ unsigned char *result, *o;
+ char *bits = (char *) malloc (sizeof(bob_bits));
+ int x, y;
+ int scale = ((width > bob_width * 11) ? 2 : 1);
+
+ memcpy (bits, bob_bits, sizeof(bob_bits));
+ ximage = XCreateImage (display, visual, 1, XYBitmap, 0, bits,
+ bob_width, bob_height, 8, 0);
+ ximage->byte_order = LSBFirst;
+ ximage->bitmap_bit_order = LSBFirst;
+ *w = ximage->width * scale;
+ *h = ximage->height * scale;
+ o = result = (unsigned char *) malloc ((*w * scale) * (*h * scale));
+ for (y = 0; y < *h; y++)
+ for (x = 0; x < *w; x++)
+ *o++ = (XGetPixel(ximage, x/scale, y/scale) ? 255 : 0);
+
+ return result;
+ }
+ else /* load a bitmap file */
{
-#ifdef HAVE_XPM
- XpmInfo xpm_info = { 0, };
- XpmImage xpm_image = { 0, };
+ Pixmap pixmap =
+ xpm_file_to_pixmap (display, window, bitmap_name, &width, &height, 0);
+ XImage *image;
+ int x, y;
+ unsigned char *result, *o;
+ XColor colors[256];
+ Bool cmap_p = has_writable_cells (screen, visual);
- int result = XpmReadFileToXpmImage (bitmap_name, &xpm_image, &xpm_info);
- if (result == XpmSuccess)
+ if (cmap_p)
{
- int x, y;
- unsigned char *result, *o;
- unsigned char *grays;
- XWindowAttributes xgwa;
-
- *w = xpm_image.width;
- *h = xpm_image.height;
- result = (unsigned char *) malloc ((*w) * (*h));
- if (!result)
- {
- fprintf(stderr, "%s: out of memory loading %s\n",
- progname, bitmap_name);
- exit (1);
- }
-
- XGetWindowAttributes (display, window, &xgwa);
-
- grays = (unsigned char *) calloc (xpm_image.ncolors+1, 1);
- for (x = 0; x < xpm_image.ncolors; x++)
- {
- XColor xc;
- XpmColor *xpmc = &xpm_image.colorTable[x];
- char *cstring = 0;
- if (xpmc->g_color && *xpmc->g_color)
- cstring = xpmc->g_color;
- else if (xpmc->g4_color && *xpmc->g4_color)
- cstring = xpmc->g4_color;
- else if (xpmc->c_color && *xpmc->c_color)
- cstring = xpmc->c_color;
- else
- cstring = xpmc->m_color;
-
- memset (&xc, 0, sizeof(xc));
- if (!cstring ||
- !*cstring ||
- !XParseColor (display, xgwa.colormap, cstring, &xc))
- grays[x] = 0;
- else
- grays[x] = (int) (((xc.red * 0.299) +
- (xc.green * 0.587) +
- (xc.blue * 0.114))
- / 255);
- }
-
- o = result;
- for (y = 0; y < *h; y++)
- for (x = 0; x < *w; x++)
- {
- int color = xpm_image.data[(y * (*w)) + x];
- if (color < 0 || color > xpm_image.ncolors) abort();
- *o++ = grays[color];
- }
- return result;
+ int i;
+ for (i = 0; i < countof (colors); i++)
+ colors[i].pixel = i;
+ XQueryColors (display, colormap, colors, countof (colors));
}
- else /* failed to read XPM -- fall through and try XBM */
-#endif /* HAVE_XPM */
- {
-#ifdef HAVE_XMU
- XImage *ximage = 0;
- int width, height, xh, yh;
- int x, y;
- unsigned char *result, *o;
- Pixmap bitmap =
- XmuLocateBitmapFile (DefaultScreenOfDisplay (display),
- bitmap_name, 0, 0, &width, &height, &xh, &yh);
- if (!bitmap)
- {
- fprintf(stderr, "%s: unable to load bitmap file %s\n",
- progname, bitmap_name);
- exit (1);
- }
- ximage = XGetImage (display, bitmap, 0, 0, width, height,
- 1L, XYPixmap);
- XFreePixmap (display, bitmap);
- if (ximage->depth != 1) abort();
-
- *w = ximage->width;
- *h = ximage->height;
- result = (unsigned char *) malloc ((*w) * (*h));
- if (!result)
- {
- fprintf(stderr, "%s: out of memory loading %s\n",
- progname, bitmap_name);
- exit (1);
- }
-
- o = result;
- for (y = 0; y < *h; y++)
- for (x = 0; x < *w; x++)
- *o++ = (XGetPixel(ximage, x, y) ? 255 : 0);
-
- return result;
-
-#else /* !XMU */
- fprintf (stderr,
- "%s: your vendor doesn't ship the standard Xmu library.\n",
- progname);
- fprintf (stderr, "\tWe can't load XBM files without it.\n");
- exit (1);
-#endif /* !XMU */
- }
+ image = XGetImage (display, pixmap, 0, 0, width, height, ~0L, ZPixmap);
+ XFreePixmap(display, pixmap);
+
+ result = (unsigned char *) malloc (width * height);
+ o = result;
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++)
+ {
+ int rgba = XGetPixel (image, x, y);
+ int gray;
+ if (cmap_p)
+ gray = ((200 - ((((colors[rgba].red >> 8) & 0xFF) +
+ ((colors[rgba].green >> 8) & 0xFF) +
+ ((colors[rgba].blue >> 8) & 0xFF))
+ >> 1))
+ & 0xFF);
+ else
+ /* This is *so* not handling all the cases... */
+ gray = (image->depth > 16
+ ? ((((rgba >> 24) & 0xFF) +
+ ((rgba >> 16) & 0xFF) +
+ ((rgba >> 8) & 0xFF) +
+ ((rgba ) & 0xFF)) >> 2)
+ : ((((rgba >> 12) & 0x0F) +
+ ((rgba >> 8) & 0x0F) +
+ ((rgba >> 4) & 0x0F) +
+ ((rgba ) & 0x0F)) >> 1));
+
+ *o++ = 255 - gray;
+ }
+
+ XFree (image->data);
+ image->data = 0;
+ XDestroyImage (image);
+
+ *w = width;
+ *h = height;
+ return result;
}
*w = 0;
char *defaults [] = {
".background: black",
- ".foreground: red",
- "*bitmap: none",
+ ".foreground: #FFAF5F",
+ "*bitmap: (default)",
"*bitmapBaseline: 20",
"*delay: 10000",
"*hspread: 30",
"*residual: 99",
"*variance: 50",
"*vartrend: 20",
+ "*bloom: True",
#ifdef HAVE_XSHM_EXTENSION
"*useSHM: False", /* xshm turns out not to help. */
{ "-residual", ".residual", XrmoptionSepArg, 0 },
{ "-variance", ".variance", XrmoptionSepArg, 0 },
{ "-vartrend", ".vartrend", XrmoptionSepArg, 0 },
+ { "-bloom", ".bloom", XrmoptionNoArg, "True" },
+ { "-no-bloom", ".bloom", XrmoptionNoArg, "False" },
#ifdef HAVE_XSHM_EXTENSION
{ "-shm", ".useSHM", XrmoptionNoArg, "True" },
{ "-no-shm", ".useSHM", XrmoptionNoArg, "False" },