From http://www.jwz.org/xscreensaver/xscreensaver-5.40.tar.gz
[xscreensaver] / jwxyz / jwxyz-common.c
index 849c4567881677114550b36b9cb619c8ee5482ce..1a31ae37a1dce4356b1df08d9cf29d3243decb65 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1991-2018 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -27,6 +27,7 @@
 
 #include <stdarg.h>
 #include <stdio.h>
+#include <string.h>
 
 #include "jwxyzI.h"
 #include "pow2.h"
@@ -102,21 +103,21 @@ XDisplayHeightMM (Display *dpy, int screen)
 unsigned long
 XBlackPixelOfScreen(Screen *screen)
 {
-  return DefaultVisualOfScreen (screen)->rgba_masks[3];
+  return DefaultVisualOfScreen (screen)->alpha_mask;
 }
 
 unsigned long
 XWhitePixelOfScreen(Screen *screen)
 {
-  const unsigned long *masks = DefaultVisualOfScreen (screen)->rgba_masks;
-  return masks[0] | masks[1] | masks[2] | masks[3];
+  Visual *v = DefaultVisualOfScreen (screen);
+  return (v->red_mask | v->green_mask |v->blue_mask | v->alpha_mask);
 }
 
 unsigned long
 XCellsOfScreen(Screen *screen)
 {
-  const unsigned long *masks = DefaultVisualOfScreen (screen)->rgba_masks;
-  return masks[0] | masks[1] | masks[2];
+  Visual *v = DefaultVisualOfScreen (screen);
+  return (v->red_mask | v->green_mask |v->blue_mask);
 }
 
 void
@@ -578,13 +579,12 @@ XGetGeometry (Display *dpy, Drawable d, Window *root_ret,
 Status
 XAllocColor (Display *dpy, Colormap cmap, XColor *color)
 {
-  const unsigned long *masks =
-    DefaultVisualOfScreen(DefaultScreenOfDisplay(dpy))->rgba_masks;
+  Visual *v = DefaultVisualOfScreen (DefaultScreenOfDisplay (dpy));
   color->pixel =
-    (((color->red   << 16) >> (31 - i_log2(masks[0]))) & masks[0]) |
-    (((color->green << 16) >> (31 - i_log2(masks[1]))) & masks[1]) |
-    (((color->blue  << 16) >> (31 - i_log2(masks[2]))) & masks[2]) |
-    masks[3];
+    (((color->red   << 16) >> (31 - i_log2(v->red_mask)))   & v->red_mask)   |
+    (((color->green << 16) >> (31 - i_log2(v->green_mask))) & v->green_mask) |
+    (((color->blue  << 16) >> (31 - i_log2(v->blue_mask)))  & v->blue_mask)  |
+    v->alpha_mask;
   return 1;
 }
 
@@ -712,6 +712,25 @@ ximage_putpixel_1 (XImage *ximage, int x, int y, unsigned long pixel)
   return 0;
 }
 
+static unsigned long
+ximage_getpixel_8 (XImage *ximage, int x, int y)
+{
+  return ((unsigned long)
+          *((uint8_t *) ximage->data +
+            (y * ximage->bytes_per_line) +
+            x));
+}
+
+static int
+ximage_putpixel_8 (XImage *ximage, int x, int y, unsigned long pixel)
+{
+  *((uint8_t *) ximage->data +
+    (y * ximage->bytes_per_line) +
+    x) = (uint8_t) pixel;
+  return 0;
+}
+
+
 static unsigned long
 ximage_getpixel_32 (XImage *ximage, int x, int y)
 {
@@ -735,9 +754,9 @@ Status
 XInitImage (XImage *ximage)
 {
   if (!ximage->bytes_per_line)
-    ximage->bytes_per_line = (ximage->depth == 1
-                              ? (ximage->width + 7) / 8
-                              ximage->width * 4);
+    ximage->bytes_per_line = (ximage->depth == 1 ? (ximage->width + 7) / 8 :
+                              ximage->depth == 8 ? ximage->width :
+                              ximage->width * 4);
 
   if (ximage->depth == 1) {
     ximage->f.put_pixel = ximage_putpixel_1;
@@ -745,6 +764,9 @@ XInitImage (XImage *ximage)
   } else if (ximage->depth == 32 || ximage->depth == 24) {
     ximage->f.put_pixel = ximage_putpixel_32;
     ximage->f.get_pixel = ximage_getpixel_32;
+  } else if (ximage->depth == 8) {
+    ximage->f.put_pixel = ximage_putpixel_8;
+    ximage->f.get_pixel = ximage_getpixel_8;
   } else {
     Assert (0, "unknown depth");
   }
@@ -769,9 +791,9 @@ XCreateImage (Display *dpy, Visual *visual, unsigned int depth,
   ximage->bitmap_pad = bitmap_pad;
   ximage->depth = depth;
   Visual *v = DefaultVisualOfScreen (DefaultScreenOfDisplay (dpy));
-  ximage->red_mask   = (depth == 1 ? 0 : v->rgba_masks[0]);
-  ximage->green_mask = (depth == 1 ? 0 : v->rgba_masks[1]);
-  ximage->blue_mask  = (depth == 1 ? 0 : v->rgba_masks[2]);
+  ximage->red_mask   = (depth == 1 ? 0 : v->red_mask);
+  ximage->green_mask = (depth == 1 ? 0 : v->green_mask);
+  ximage->blue_mask  = (depth == 1 ? 0 : v->blue_mask);
   ximage->bits_per_pixel = (depth == 1 ? 1 : visual_depth (NULL, NULL));
   ximage->bytes_per_line = bytes_per_line;
 
@@ -1035,6 +1057,9 @@ try_native_font (Display *dpy, const char *name, Font fid)
       fid->xa_font = strdup (name); // Maybe this should be an XLFD?
       break;
     } else {
+      // To list fonts:
+      //  po [UIFont familyNames]
+      //  po [UIFont fontNamesForFamilyName:@"Arial"]
       Log("No native font: \"%s\" %.0f", name2, size);
     }
   }
@@ -1493,11 +1518,10 @@ jwxyz_draw_string (Display *dpy, Drawable d, GC gc, int x, int y,
   {
 # define ROTL(x, rot) (((x) << ((rot) & 31)) | ((x) >> (32 - ((rot) & 31))))
 
-    const unsigned long *masks =
-      DefaultVisualOfScreen (DefaultScreenOfDisplay(dpy))->rgba_masks;
-    unsigned shift = (i_log2 (masks[3]) - i_log2 (masks[1])) & 31;
-    uint32_t mask = ROTL(masks[1], shift) & masks[3],
-             color = gcv->foreground & ~masks[3];
+    Visual *v = DefaultVisualOfScreen (DefaultScreenOfDisplay(dpy));
+    unsigned shift = (i_log2 (v->alpha_mask) - i_log2 (v->green_mask)) & 31;
+    uint32_t mask = ROTL(v->green_mask, shift) & v->alpha_mask,
+             color = gcv->foreground & ~v->alpha_mask;
     uint32_t *s = (uint32_t *)data;
     uint32_t *end = s + (w * h);
     while (s < end) {
@@ -1566,9 +1590,13 @@ XDrawImageString (Display *dpy, Drawable d, GC gc, int x, int y,
   jwxyz_fill_rect (dpy, d, gc,
                    x + MIN (0, cs.lbearing),
                    y - MAX (0, ascent),
+
+                   /* The +1 here is almost certainly wrong, but BSOD
+                      requires it; and only BSOD, fluidballs, juggle
+                      and grabclient call XDrawImageString... */
                    MAX (MAX (0, cs.rbearing) -
                         MIN (0, cs.lbearing),
-                        cs.width),
+                        cs.width) + 1,
                    MAX (0, ascent) + MAX (0, descent),
                    VTBL->gc_gcv(gc)->background);
   return XDrawString (dpy, d, gc, x, y, str, len);
@@ -1760,7 +1788,7 @@ visual_depth (Screen *s, Visual *v)
 int
 visual_cells (Screen *s, Visual *v)
 {
-  return (int)(v->rgba_masks[0] | v->rgba_masks[1] | v->rgba_masks[2]);
+  return (int)(v->red_mask | v->green_mask | v->blue_mask);
 }
 
 int
@@ -1773,9 +1801,9 @@ void
 visual_rgb_masks (Screen *s, Visual *v, unsigned long *red_mask,
                   unsigned long *green_mask, unsigned long *blue_mask)
 {
-  *red_mask = v->rgba_masks[0];
-  *green_mask = v->rgba_masks[1];
-  *blue_mask = v->rgba_masks[2];
+  *red_mask = v->red_mask;
+  *green_mask = v->green_mask;
+  *blue_mask = v->blue_mask;
 }
 
 int