X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fxflame.c;h=1037460afb35d00433b6ea19fff3ce3f713597d8;hb=c85f503f5793839a6be4c818332aca4a96927bb2;hp=717689baef0454673ef9c290f91b9e462c4fcf5c;hpb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;p=xscreensaver diff --git a/hacks/xflame.c b/hacks/xflame.c index 717689ba..1037460a 100644 --- a/hacks/xflame.c +++ b/hacks/xflame.c @@ -1,4 +1,4 @@ -/* xflame, Copyright (c) 1996-2002 Carsten Haitzler +/* xflame, Copyright (c) 1996-2018 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 @@ -41,6 +41,7 @@ * 4-Oct-99, jwz: added support for packed-24bpp (versus 32bpp.) * 16-Jan-2002, jwz: added gdk_pixbuf support. + * 9-Oct-2016, Dave Odell : Updated for new xshm.c. */ @@ -48,17 +49,20 @@ #include "screenhack.h" -#include "xpm-pixmap.h" +#include "ximage-loader.h" #include #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) -#ifdef HAVE_XSHM_EXTENSION -# include "xshm.h" -#endif /* HAVE_XSHM_EXTENSION */ +# undef MAX +# undef MIN +# define MAX(A,B) ((A)>(B)?(A):(B)) +# define MIN(A,B) ((A)<(B)?(A):(B)) -#include "images/bob.xbm" +#include "xshm.h" + +#include "images/gen/bob_png.h" #define MAX_VAL 255 @@ -71,12 +75,9 @@ struct state { Colormap colormap; Visual *visual; Screen *screen; - Bool shared; Bool bloom; XImage *xim; -#ifdef HAVE_XSHM_EXTENSION XShmSegmentInfo shminfo; -#endif /* HAVE_XSHM_EXTENSION */ GC gc; int ctab[256]; @@ -125,30 +126,19 @@ MakeImage(struct state *st) { XGCValues gcv; -#ifdef HAVE_XSHM_EXTENSION - st->shared = True; - st->xim = create_xshm_image (st->dpy, st->visual, st->depth, ZPixmap, NULL, - &st->shminfo, st->width, st->height); -#else /* !HAVE_XSHM_EXTENSION */ - st->xim = 0; -#endif /* !HAVE_XSHM_EXTENSION */ + if (st->xim) + destroy_xshm_image (st->dpy, st->xim, &st->shminfo); + st->xim = create_xshm_image (st->dpy, st->visual, st->depth, ZPixmap, + &st->shminfo, st->width, st->height); if (!st->xim) { - st->shared = False; - st->xim = XCreateImage (st->dpy, st->visual, st->depth, ZPixmap, 0, NULL, - st->width, st->height, 32, 0); - if (st->xim) - st->xim->data = (char *) calloc(st->xim->height, st->xim->bytes_per_line); - if (!st->xim || !st->xim->data) - { - fprintf(stderr,"%s: out of memory.\n", progname); - exit(1); - } + fprintf(stderr,"%s: out of memory.\n", progname); + exit(1); } - st->gc = XCreateGC(st->dpy,st->window,0,&gcv); - if (!st->gc) exit (1); + if (! st->gc) + st->gc = XCreateGC(st->dpy,st->window,0,&gcv); } @@ -199,14 +189,9 @@ InitColors(struct state *st) static void DisplayImage(struct state *st) { -#ifdef HAVE_XSHM_EXTENSION - if (st->shared) - XShmPutImage(st->dpy, st->window, st->gc, st->xim, 0,(st->top - 1) << 1, 0, - (st->top - 1) << 1, st->width, st->height - ((st->top - 1) << 1), False); - else -#endif /* HAVE_XSHM_EXTENSION */ - XPutImage(st->dpy, st->window, st->gc, st->xim, 0, (st->top - 1) << 1, 0, - (st->top - 1) << 1, st->width, st->height - ((st->top - 1) << 1)); + put_xshm_image(st->dpy, st->window, st->gc, st->xim, 0,(st->top - 1) << 1, 0, + (st->top - 1) << 1, st->width, st->height - ((st->top - 1) << 1), + &st->shminfo); } @@ -215,6 +200,8 @@ InitFlame(struct state *st) { st->fwidth = st->width / 2; st->fheight = st->height / 2; + + if (st->flame) free (st->flame); st->flame = (unsigned char *) malloc((st->fwidth + 2) * (st->fheight + 2) * sizeof(unsigned char)); @@ -244,7 +231,15 @@ InitFlame(struct state *st) THROTTLE (st->vartrend, "vartrend"); # undef THROTTLE - +#if 0 + if (st->width > 2560) /* Retina displays */ + { + /* #### One of these knobs must mean "make the fire be twice as tall" + but I can't figure out how. Changing any of the default values + of any of these seems to just make it all go crappy. */ + st->ivspread = MAX (0, MIN (255, st->ivspread + 1)); + } +#endif st->hspread = st->ihspread; st->vspread = st->ivspread; @@ -602,105 +597,117 @@ FlamePasteData(struct state *st, } +static XImage * +double_ximage (Display *dpy, Visual *visual, XImage *image) +{ + int x, y; + XImage *out = XCreateImage (dpy, visual, image->depth, ZPixmap, 0, 0, + image->width * 2, image->height * 2, 8, 0); + out->data = (char *) malloc (out->height * out->bytes_per_line); + for (y = 0; y < image->width; y++) + for (x = 0; x < image->height; x++) + { + unsigned long p = XGetPixel (image, x, y); + XPutPixel (out, x*2, y*2, p); + XPutPixel (out, x*2+1, y*2, p); + XPutPixel (out, x*2, y*2+1, p); + XPutPixel (out, x*2+1, y*2+1, p); + } + XDestroyImage (image); + return out; +} + + static unsigned char * -loadBitmap(struct state *st, int *w, int *h) +gaussian_blur (unsigned char *in, int w, int h, double r) { - char *bitmap_name = get_string_resource (st->dpy, "bitmap", "Bitmap"); + unsigned char *out = malloc(w * h); + int rs = (int) ((r * 2.57) + 0.5); + int i, j; + + for (i = 0; i < h; i ++) + for (j = 0; j < w; j++) + { + double val = 0, wsum = 0; + int ix, iy; + for (iy = i-rs; iydpy, "bitmap", "Bitmap"); +# endif + XImage *image = 0; 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 = ((st->width > bob_width * 11) ? 2 : 1); - - memcpy (bits, bob_bits, sizeof(bob_bits)); - ximage = XCreateImage (st->dpy, st->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_COCOA - abort(); /* #### fix me */ -#else - { - Pixmap pixmap = - xpm_file_to_pixmap (st->dpy, st->window, bitmap_name, &st->width, &st->height, 0); - XImage *image; - int x, y; - unsigned char *result, *o; - XColor colors[256]; - Bool cmap_p = has_writable_cells (st->screen, st->visual); + image = image_data_to_ximage (st->dpy, st->visual, + bob_png, sizeof(bob_png)); + else + image = file_to_ximage (st->dpy, st->visual, bitmap_name); - if (cmap_p) - { - int i; - for (i = 0; i < countof (colors); i++) - colors[i].pixel = i; - XQueryColors (st->dpy, st->colormap, colors, countof (colors)); - } + if (! image) return 0; - image = XGetImage (st->dpy, pixmap, 0, 0, st->width, st->height, ~0L, ZPixmap); - XFreePixmap(st->dpy, pixmap); - - result = (unsigned char *) malloc (st->width * st->height); - o = result; - for (y = 0; y < st->height; y++) - for (x = 0; x < st->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 = st->width; - *h = st->height; - return result; + while (image->width < st->width / 10 && + image->height < st->height / 10) + { + image = double_ximage (st->dpy, st->visual, image); + blur++; } -#endif /* !HAVE_COCOA */ - *w = 0; - *h = 0; - return 0; + result = (unsigned char *) malloc (image->width * image->height); + o = result; + for (y = 0; y < image->height; y++) + for (x = 0; x < image->width; x++) + { + unsigned long agbr = XGetPixel (image, x, image->height - y - 1); + unsigned long a = (agbr >> 24) & 0xFF; + unsigned long gray = (a == 0 + ? 0xFF + : ((((agbr >> 16) & 0xFF) + + ((agbr >> 8) & 0xFF) + + ((agbr >> 0) & 0xFF)) + / 3)); + if (gray < 96) gray /= 2; /* a little more contrast */ + *o++ = 255 - gray; + } + /* If we enlarged the image, file off the sharp edges. */ + if (blur > 0) + result = gaussian_blur (result, image->width, image->height, blur * 1.7); + + st->theimx = image->width; + st->theimy = image->height; + XDestroyImage (image); + return result; } + static void * xflame_init (Display *dpy, Window win) { @@ -715,13 +722,7 @@ xflame_init (Display *dpy, Window win) GetXInfo(st); InitColors(st); - st->theim = loadBitmap(st, &st->theimx, &st->theimy); - - /* utils/xshm.c doesn't provide a way to free the shared-memory image, which - makes it hard for us to react to window resizing. So, punt for now. The - size of the window at startup is the size it will stay. - */ - GetXInfo(st); + st->theim = loadBitmap(st); MakeImage(st); InitFlame(st); @@ -751,6 +752,12 @@ static void xflame_reshape (Display *dpy, Window window, void *closure, unsigned int w, unsigned int h) { + struct state *st = (struct state *) closure; + GetXInfo(st); + MakeImage(st); + InitFlame(st); + FlameFill(st,0); + XClearWindow (dpy, window); } static Bool @@ -770,6 +777,8 @@ xflame_free (Display *dpy, Window window, void *closure) static const char *xflame_defaults [] = { ".background: black", ".foreground: #FFAF5F", + "*fpsTop: true", + "*fpsSolid: true", "*bitmap: (default)", "*bitmapBaseline: 20", "*delay: 10000",