/* grab-ximage.c --- grab the screen to an XImage for use with OpenGL.
- * xscreensaver, Copyright (c) 2001 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 2001, 2003 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
}
+static Bool
+bigendian (void)
+{
+ union { int i; char c[sizeof(int)]; } u;
+ u.i = 1;
+ return !u.c[0];
+}
+
+
/* Returns an XImage structure containing an image of the desktop.
- (As a side-effect, that image will be painted onto the given Window.)
+ (As a side-effect, that image *may* be painted onto the given Window.)
This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the
extra byte set to 0xFF.
*/
XImage *
-screen_to_ximage (Screen *screen, Window window)
+screen_to_ximage (Screen *screen, Window window, char **filename_return)
{
Display *dpy = DisplayOfScreen (screen);
+ Pixmap pixmap = 0;
XWindowAttributes xgwa;
int win_width, win_height;
int tex_width, tex_height;
- grab_screen_image (screen, window);
-
XGetWindowAttributes (dpy, window, &xgwa);
win_width = xgwa.width;
win_height = xgwa.height;
+ pixmap = XCreatePixmap(dpy, window, xgwa.width, xgwa.height, xgwa.depth);
+ load_random_image (screen, window, pixmap, filename_return);
+
/* GL texture sizes must be powers of two. */
tex_width = to_pow2(win_width);
tex_height = to_pow2(win_height);
- /* Convert the server-side Drawable to a client-side GL-ordered XImage.
+ /* Convert the server-side Pixmap to a client-side GL-ordered XImage.
*/
{
XImage *ximage1, *ximage2;
XColor *colors = 0;
- ximage1 = XGetImage (dpy, window, 0, 0, win_width, win_height, ~0L,
+ ximage1 = XGetImage (dpy, pixmap, 0, 0, win_width, win_height, ~0L,
ZPixmap);
+ XFreePixmap (dpy, pixmap);
+ pixmap = 0;
+
ximage2 = XCreateImage (dpy, xgwa.visual, 32, ZPixmap, 0, 0,
tex_width, tex_height, 32, 0);
*/
{
int x, y;
- int crpos, cgpos, cbpos, capos; /* bitfield positions */
- int srpos, sgpos, sbpos;
- int srmsk, sgmsk, sbmsk;
- int srsiz, sgsiz, sbsiz;
+ unsigned int crpos=0, cgpos=0, cbpos=0, capos=0; /* bitfield positions */
+ unsigned int srpos=0, sgpos=0, sbpos=0;
+ unsigned int srmsk=0, sgmsk=0, sbmsk=0;
+ unsigned int srsiz=0, sgsiz=0, sbsiz=0;
int i;
unsigned char spread_map[3][256];
- srmsk = ximage1->red_mask;
- sgmsk = ximage1->green_mask;
- sbmsk = ximage1->blue_mask;
+ if (colors == 0) /* truecolor */
+ {
+ srmsk = ximage2->red_mask;
+ sgmsk = ximage2->green_mask;
+ sbmsk = ximage2->blue_mask;
- decode_mask (srmsk, &srpos, &srsiz);
- decode_mask (sgmsk, &sgpos, &sgsiz);
- decode_mask (sbmsk, &sbpos, &sbsiz);
+ decode_mask (srmsk, &srpos, &srsiz);
+ decode_mask (sgmsk, &sgpos, &sgsiz);
+ decode_mask (sbmsk, &sbpos, &sbsiz);
+ }
/* Note that unlike X, which is endianness-agnostic (since any XImage
can have its own specific bit ordering, with the server reversing
we need to pack things in "RGBA" order on the client machine,
regardless of its endianness.
*/
- crpos = 0, cgpos = 8, cbpos = 16, capos = 24;
+ if (bigendian())
+ crpos = 24, cgpos = 16, cbpos = 8, capos = 0;
+ else
+ crpos = 0, cgpos = 8, cbpos = 16, capos = 24;
- for (i = 0; i < 256; i++)
+ if (colors == 0) /* truecolor */
{
- spread_map[0][i] = spread_bits (i, srsiz);
- spread_map[1][i] = spread_bits (i, sgsiz);
- spread_map[2][i] = spread_bits (i, sbsiz);
+ for (i = 0; i < 256; i++)
+ {
+ spread_map[0][i] = spread_bits (i, srsiz);
+ spread_map[1][i] = spread_bits (i, sgsiz);
+ spread_map[2][i] = spread_bits (i, sbsiz);
+ }
}
for (y = 0; y < win_height; y++)
}
}
+ if (pixmap) XFreePixmap (dpy, pixmap);
if (colors) free (colors);
free (ximage1->data);
ximage1->data = 0;