+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;
+
+}
+
+