X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fxflame.c;h=25283401fea17b10e5a89b5301f6bcf5b2841dba;hb=78add6e627ee5f10e1fa6f3852602ea5066eee5a;hp=04b82c1a96d689061722c8b59bab9932dcbe0ca7;hpb=07faf451b99879183ed7e909e43a0e065be1ee7f;p=xscreensaver diff --git a/hacks/xflame.c b/hacks/xflame.c index 04b82c1a..25283401 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,15 @@ #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 */ +#include "xshm.h" -#include "images/bob.xbm" +#include "images/gen/bob_png.h" #define MAX_VAL 255 @@ -71,12 +70,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 +121,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 +184,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 +195,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)); @@ -602,107 +584,141 @@ FlamePasteData(struct state *st, } +static Pixmap +double_pixmap (Display *dpy, Visual *visual, int depth, Pixmap pixmap, + int pix_w, int pix_h) +{ + int x, y; + Pixmap p2 = XCreatePixmap(dpy, pixmap, pix_w*2, pix_h*2, depth); + XImage *i1 = XGetImage (dpy, pixmap, 0, 0, pix_w, pix_h, ~0L, + (depth == 1 ? XYPixmap : ZPixmap)); + XImage *i2 = XCreateImage (dpy, visual, depth, + (depth == 1 ? XYPixmap : ZPixmap), 0, 0, + pix_w*2, pix_h*2, 8, 0); + XGCValues gcv; + GC gc = XCreateGC (dpy, p2, 0, &gcv); + i2->data = (char *) calloc(i2->height, i2->bytes_per_line); + for (y = 0; y < pix_h; y++) + for (x = 0; x < pix_w; x++) + { + unsigned long p = XGetPixel(i1, x, y); + XPutPixel(i2, x*2, y*2, p); + XPutPixel(i2, x*2+1, y*2, p); + XPutPixel(i2, x*2, y*2+1, p); + XPutPixel(i2, x*2+1, y*2+1, p); + } + free(i1->data); i1->data = 0; + XDestroyImage(i1); + XPutImage(dpy, p2, gc, i2, 0, 0, 0, 0, i2->width, i2->height); + XFreeGC (dpy, gc); + free(i2->data); i2->data = 0; + XDestroyImage(i2); + XFreePixmap(dpy, pixmap); + return p2; +} + + +static unsigned char * +reformat_pixmap (struct state *st, Pixmap pixmap, Pixmap mask, int *w, int *h) +{ + XImage *image = 0, *mimage = 0; + int x, y; + unsigned char *result, *o; + XColor colors[256]; + Bool cmap_p = has_writable_cells (st->screen, st->visual); + + while (*w < st->width / 10 && + *h < st->height / 10) + { + pixmap = double_pixmap (st->dpy, st->visual, st->depth, pixmap, *w, *h); + if (mask) + mask = double_pixmap (st->dpy, st->visual, st->depth, mask, *w, *h); + *w *= 2; + *h *= 2; + } + + if (cmap_p) + { + int i; + for (i = 0; i < countof (colors); i++) + colors[i].pixel = i; + XQueryColors (st->dpy, st->colormap, colors, countof (colors)); + } + + image = XGetImage (st->dpy, pixmap, 0, 0, *w, *h, ~0L, ZPixmap); + XFreePixmap(st->dpy, pixmap); + + if (mask) + { + mimage = XGetImage (st->dpy, mask, 0, 0, *w, *h, ~0L, ZPixmap); + XFreePixmap(st->dpy, mask); + } + + 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 rgb = XGetPixel (image, x, y); + unsigned long a = mimage ? XGetPixel (mimage, x, y) : 1; + unsigned long gray; + if (!a) + rgb = 0xFFFFFFFFL; + if (cmap_p) + gray = ((200 - ((((colors[rgb].red >> 8) & 0xFF) + + ((colors[rgb].green >> 8) & 0xFF) + + ((colors[rgb].blue >> 8) & 0xFF)) + >> 1)) + & 0xFF); + else + /* This is *so* not handling all the cases... */ + gray = (image->depth > 16 + ? ((((rgb >> 24) & 0xFF) + + ((rgb >> 16) & 0xFF) + + ((rgb >> 8) & 0xFF) + + ((rgb ) & 0xFF)) >> 2) + : ((((rgb >> 12) & 0x0F) + + ((rgb >> 8) & 0x0F) + + ((rgb >> 4) & 0x0F) + + ((rgb ) & 0x0F)) >> 1)); + + *o++ = 255 - gray; + } + + *w = image->width; + *h = image->height; + XDestroyImage (image); + if (mimage) + XDestroyImage (mimage); + + return result; + +} + + static unsigned char * loadBitmap(struct state *st, int *w, int *h) { +# ifdef HAVE_JWXYZ + const char *bitmap_name = "(default)"; /* #### always use builtin */ +# else char *bitmap_name = get_string_resource (st->dpy, "bitmap", "Bitmap"); - -#ifdef HAVE_COCOA - bitmap_name = "(default)"; /* #### always use builtin */ -#endif /* HAVE_COCOA */ - +# endif + Pixmap p = 0, mask = 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; - } + p = image_data_to_pixmap (st->dpy, st->window, + bob_png, sizeof(bob_png), + w, h, &mask); 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); - - if (cmap_p) - { - int i; - for (i = 0; i < countof (colors); i++) - colors[i].pixel = i; - XQueryColors (st->dpy, st->colormap, colors, countof (colors)); - } - - 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; - } -#endif /* !HAVE_COCOA */ - - *w = 0; - *h = 0; - return 0; + p = file_to_pixmap (st->dpy, st->window, bitmap_name, + &st->width, &st->height, 0); + if (!p) return 0; + return reformat_pixmap (st, p, mask, w, h); } static void * @@ -721,12 +737,6 @@ xflame_init (Display *dpy, Window win) 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); - MakeImage(st); InitFlame(st); FlameFill(st,0); @@ -755,6 +765,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 @@ -774,6 +790,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",