-/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright © 1991-2022 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
/* JWXYZ Is Not Xlib.
- But it's a bunch of function definitions that bear some resemblance to
- Xlib and that do Cocoa-ish or OpenGL-ish things that bear some resemblance
- to the things that Xlib might have done.
+ macOS and iOS:
+
+ jwxyz.m -- Xlib in terms of Quartz / Core Graphics rendering,
+ Renders into a CGContextRef that points to a CGImage
+ in CPU RAM.
+ jwxyz-cocoa.m -- Cocoa glue: fonts and such.
+
+ Android:
+
+ jwxyz-android.c -- Java / JNI glue. Renders into an FBO texture if
+ possible, otherwise an EGL PBuffer.
+
+ jwxyz-image.c -- Pixmaps implemented in CPU RAM, for OpenGL hacks.
+ Renders into an XImage, basically.
+
+ jwxyz-gl.c -- Pixmaps implemented in terms of OpenGL textures,
+ for X11 hacks (except kumppa, petri and slip).
+
+ Shared code:
+
+ jwxyz-common.c -- Most of the Xlib implementation, used by all 3 OSes.
+ jwzgles.c -- OpenGL 1.3 implemented in terms of OpenGLES 1.1.
+
+
+ Why two implemementations of Pixmaps for Android?
+
+ - GL hacks don't tend to need much in the way of Xlib, and having a
+ GL context to render Xlib alongside a GL context for rendering GL
+ seemed like trouble.
+
+ - X11 hacks render to a GL context because hardware acceleration tends
+ to work well with Xlib geometric stuff. Better framerates, lower
+ power.
+
+ Why not eliminate jwxyz-cocoa.m and use jwxyz-gl.c on macOS and iOS
+ as well?
+
+ - Yeah, maybe.
- This is the version of jwxyz for Android. The version used by MacOS
- and iOS is in jwxyz.m.
*/
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdarg.h>
#include <stdio.h>
+#include <string.h>
#include "jwxyzI.h"
#include "pow2.h"
unsigned long
XBlackPixelOfScreen(Screen *screen)
{
- return DefaultVisualOfScreen (screen)->rgba_masks[3];
+ if (! screen) abort();
+ 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
if (depth == 1)
Assert ((pixel == 0 || pixel == 1), "bogus mono pixel: 0x%08X", pixel);
+
+# if !defined __OPTIMIZE__
+ // This test fails somewhat regularly with certain X11 hacks. This might
+ // indicate the use of uninitialized data, or an assumption that BlackPixel
+ // is 0, but either way, crashing here is not super helpful.
else if (!alpha_allowed_p)
Assert (((pixel & BlackPixel(dpy,0)) == BlackPixel(dpy,0)),
"bogus color pixel: 0x%08X", pixel);
+# endif
}
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;
}
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)
{
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;
} 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");
}
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;
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);
}
}
// This used to substitute Georgia for Times. Now it doesn't.
if (CMP ("random")) {
rand = True;
- } else if (CMP ("fixed")) {
+ } else if (CMP ("fixed") || CMP ("monospace")) {
require |= JWXYZ_STYLE_MONOSPACE;
family_name = "Courier";
family_name_size = strlen(family_name);
{
# 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) {
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);
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
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
return 0;
}
-// declared in utils/grabclient.h
-Bool
-use_subwindow_mode_p (Screen *screen, Window window)
-{
- return False;
-}
-
#endif /* HAVE_JWXYZ */