X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fxflame.c;h=622a59de97e74659d5a05f7a6118cc09d757aac2;hb=4cecfc89e5e889c7232693897c06168fb378bd5c;hp=360ef379fc1d2515073e1335d37dc8870d8b79d8;hpb=a719ec12b8b2563112366a8ac3196816fd64d2c7;p=xscreensaver diff --git a/hacks/xflame.c b/hacks/xflame.c index 360ef379..622a59de 100755 --- a/hacks/xflame.c +++ b/hacks/xflame.c @@ -1,4 +1,4 @@ -/* xflame, Copyright (c) 1996-1999 Carsten Haitzler +/* xflame, Copyright (c) 1996-2002 Carsten Haitzler * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -38,6 +38,10 @@ 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. + */ @@ -45,29 +49,20 @@ #include "screenhack.h" +#include "xpm-pixmap.h" #include #include +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + #ifdef HAVE_XSHM_EXTENSION # include "xshm.h" #endif /* HAVE_XSHM_EXTENSION */ -#ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif +#include "images/bob.xbm" -#ifdef HAVE_XMU -# ifndef VMS -# include -# else /* VMS */ -# include -# endif /* VMS */ -#endif /* HAVE_XMU */ - -#define MAX 255 +#define MAX_VAL 255 static Display *display; static Window window; @@ -76,7 +71,9 @@ static int width; 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; @@ -111,6 +108,7 @@ GetXInfo(Display *disp, Window win) colormap = xwa.colormap; depth = xwa.depth; visual = xwa.visual; + screen = xwa.screen; width = xwa.width; height = xwa.height; @@ -125,9 +123,14 @@ MakeImage(void) { XGCValues gcv; +#ifdef HAVE_XSHM_EXTENSION shared = True; xim = create_xshm_image (display, visual, depth, ZPixmap, NULL, &shminfo, width, height); +#else /* !HAVE_XSHM_EXTENSION */ + xim = 0; +#endif /* !HAVE_XSHM_EXTENSION */ + if (!xim) { shared = False; @@ -150,13 +153,27 @@ MakeImage(void) 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 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; @@ -180,10 +197,12 @@ InitColors(void) static void DisplayImage(void) { +#ifdef HAVE_XSHM_EXTENSION if (shared) XShmPutImage(display, window, gc, xim, 0,(top - 1) << 1, 0, (top - 1) << 1, width, height - ((top - 1) << 1), False); else +#endif /* HAVE_XSHM_EXTENSION */ XPutImage(display, window, gc, xim, 0, (top - 1) << 1, 0, (top - 1) << 1, width, height - ((top - 1) << 1)); } @@ -209,6 +228,7 @@ InitFlame(void) 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) { \ @@ -296,6 +316,55 @@ Flame2Image32(void) } } +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) { @@ -358,14 +427,22 @@ Flame2Image1234567(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) { @@ -381,13 +458,16 @@ 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; @@ -417,21 +497,21 @@ FlameAdvance(void) 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; @@ -445,6 +525,13 @@ FlameAdvance(void) 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; @@ -517,117 +604,88 @@ loadBitmap(int *w, int *h) { 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 */ { - 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 */ - { -#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; @@ -642,8 +700,8 @@ char *progclass = "XFlame"; char *defaults [] = { ".background: black", - ".foreground: red", - "*bitmap: none", + ".foreground: #FFAF5F", + "*bitmap: (default)", "*bitmapBaseline: 20", "*delay: 10000", "*hspread: 30", @@ -651,6 +709,7 @@ char *defaults [] = { "*residual: 99", "*variance: 50", "*vartrend: 20", + "*bloom: True", #ifdef HAVE_XSHM_EXTENSION "*useSHM: False", /* xshm turns out not to help. */ @@ -667,6 +726,8 @@ XrmOptionDescRec options [] = { { "-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" },