-/* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1992-1997 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
*/
#include "screenhack.h"
+#include "xpm-pixmap.h"
#include <stdio.h>
-#ifdef HAVE_XPM
-# include <X11/xpm.h>
-# ifndef PIXEL_ALREADY_TYPEDEFED
-# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */
-# endif
-#endif
-
-#include <X11/Xmu/Drawing.h>
-
-#include "default.xbm"
+#include "images/som.xbm"
static Display *dpy;
static Window window;
static int depth;
static unsigned int fg, bg;
-static void rotate(), init (), display ();
+static void display (Pixmap);
#define copy_all_to(from, xoff, yoff, to, gc) \
XCopyArea (dpy, (from), (to), (gc), 0, 0, \
size-(xoff), size-(yoff), 0, 0)
static void
-rotate ()
+rotate (void)
{
int qwad; /* fuckin' C, man... who needs namespaces? */
XFillRectangle (dpy, mask, CLR, 0, 0, size, size);
}
}
-static void
-read_bitmap (bitmap_name, widthP, heightP)
- char *bitmap_name;
- int *widthP, *heightP;
+static Pixmap
+read_screen (Display *dpy, Window window, int *widthP, int *heightP)
{
-#ifdef HAVE_XPM
- XpmAttributes xpmattrs;
- int result;
- xpmattrs.valuemask = 0;
- bitmap = 0;
- result = XpmReadFileToPixmap (dpy, window, bitmap_name, &bitmap, 0,
- &xpmattrs);
- switch (result)
- {
- case XpmColorError:
- fprintf (stderr, "%s: warning: xpm color substitution performed\n",
- progname);
- /* fall through */
- case XpmSuccess:
- *widthP = xpmattrs.width;
- *heightP = xpmattrs.height;
- break;
- case XpmFileInvalid:
- case XpmOpenFailed:
- bitmap = 0;
- break;
- case XpmColorFailed:
- fprintf (stderr, "%s: xpm: color allocation failed\n", progname);
- exit (-1);
- case XpmNoMemory:
- fprintf (stderr, "%s: xpm: out of memory\n", progname);
- exit (-1);
- default:
- fprintf (stderr, "%s: xpm: unknown error code %d\n", progname, result);
- exit (-1);
- }
- if (! bitmap)
-#endif
- {
- int xh, yh;
- Pixmap b2;
- bitmap = XmuLocateBitmapFile (DefaultScreenOfDisplay (dpy), bitmap_name,
- 0, 0, widthP, heightP, &xh, &yh);
- if (! bitmap)
- {
- fprintf (stderr, "%s: couldn't find bitmap %s\n", progname,
- bitmap_name);
- exit (1);
- }
- b2 = XmuCreatePixmapFromBitmap (dpy, window, bitmap, *widthP, *heightP,
- depth, fg, bg);
- XFreePixmap (dpy, bitmap);
- bitmap = b2;
- }
+ Pixmap p;
+ XWindowAttributes xgwa;
+ XGCValues gcv;
+ GC gc;
+ XGetWindowAttributes (dpy, window, &xgwa);
+ *widthP = xgwa.width;
+ *heightP = xgwa.height;
+
+ grab_screen_image(xgwa.screen, window);
+ p = XCreatePixmap(dpy, window, *widthP, *heightP, xgwa.depth);
+ gcv.function = GXcopy;
+ gc = XCreateGC (dpy, window, GCFunction, &gcv);
+ XCopyArea (dpy, window, p, gc, 0, 0, *widthP, *heightP, 0, 0);
+
+ /* Reset the window's background color... */
+ XSetWindowBackground (dpy, window,
+ get_pixel_resource ("background", "Background",
+ dpy, xgwa.colormap));
+ XCopyArea (dpy, p, window, gc, 0, 0, *widthP, *heightP, 0, 0);
+ XFreeGC (dpy, gc);
+
+ return p;
+}
+
+
+static int
+to_pow2(int n, Bool up)
+{
+ /* sizeof(Dimension) == 2. */
+ int powers_of_2[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,
+ 2048, 4096, 8192, 16384, 32768, 65536 };
+ int i = 0;
+ if (n > 65536) size = 65536;
+ while (n >= powers_of_2[i]) i++;
+ if (n == powers_of_2[i-1])
+ return n;
+ else
+ return powers_of_2[up ? i : i-1];
}
static void
-init ()
+init (void)
{
XWindowAttributes xgwa;
Colormap cmap;
XGCValues gcv;
int width, height;
- unsigned int real_size;
char *bitmap_name;
- int i;
+ Bool scale_up;
XGetWindowAttributes (dpy, window, &xgwa);
cmap = xgwa.colormap;
if (!strcmp (bitmap_name, "(default)"))
{
- width = logo_width;
- height = logo_height;
- bitmap = XCreatePixmapFromBitmapData (dpy, window, (char *) logo_bits,
+ width = som_width;
+ height = som_height;
+ bitmap = XCreatePixmapFromBitmapData (dpy, window, (char *) som_bits,
width, height, fg, bg, depth);
+ scale_up = True; /* definitely. */
+ }
+ else if (!strcmp (bitmap_name, "(screen)"))
+ {
+ bitmap = read_screen (dpy, window, &width, &height);
+ scale_up = True; /* maybe? */
}
else
{
- read_bitmap (bitmap_name, &width, &height);
+ bitmap = xpm_file_to_pixmap (dpy, window, bitmap_name,
+ &width, &height, 0);
+ scale_up = True; /* probably? */
}
- real_size = (width > height) ? width : height;
+ size = (width < height) ? height : width; /* make it square */
+ size = to_pow2(size, scale_up); /* round up to power of 2 */
+ { /* don't exceed screen size */
+ int s = XScreenNumberOfScreen(xgwa.screen);
+ int w = to_pow2(XDisplayWidth(dpy, s), False);
+ int h = to_pow2(XDisplayHeight(dpy, s), False);
+ if (size > w) size = w;
+ if (size > h) size = h;
+ }
- size = real_size;
- /* semi-sleazy way of doing (setq size (expt 2 (ceiling (log size 2)))). */
- for (i = 31; i > 0; i--)
- if (size & (1<<i)) break;
- if (size & (~(1<<i)))
- size = (size>>i)<<(i+1);
self = XCreatePixmap (dpy, window, size, size, depth);
temp = XCreatePixmap (dpy, window, size, size, depth);
mask = XCreatePixmap (dpy, window, size, size, depth);
XCopyArea (dpy, bitmap, self, CPY, 0, 0, width, height,
(size - width)>>1, (size - height)>>1);
+ XFreePixmap(dpy, bitmap);
+
+ display (self);
+ XSync(dpy, False);
+ screenhack_handle_events (dpy);
}
static void
-display (pixmap)
- Pixmap pixmap;
+display (Pixmap pixmap)
{
XWindowAttributes xgwa;
static int last_w = 0, last_h = 0;
last_w = xgwa.width;
last_h = xgwa.height;
}
-#ifdef HAVE_XPM
if (depth != 1)
XCopyArea (dpy, pixmap, window, gc, 0, 0, size, size,
(xgwa.width-size)>>1, (xgwa.height-size)>>1);
else
-#endif
XCopyPlane (dpy, pixmap, window, gc, 0, 0, size, size,
(xgwa.width-size)>>1, (xgwa.height-size)>>1, 1);
/*
((xgwa.width-size)>>1)-1, ((xgwa.height-size)>>1)-1,
size+2, size+2);
*/
- XSync (dpy, True);
+ XSync (dpy, False);
+ screenhack_handle_events (dpy);
}
\f
char *progclass = "BlitSpin";
char *defaults [] = {
- "BlitSpin.background: black", /* to placate SGI */
- "BlitSpin.foreground: white",
+ ".background: black",
+ ".foreground: white",
"*delay: 500000",
"*delay2: 500000",
"*bitmap: (default)",
+ "*geometry: 512x512",
0
};
XrmOptionDescRec options [] = {
{ "-delay", ".delay", XrmoptionSepArg, 0 },
{ "-delay2", ".delay2", XrmoptionSepArg, 0 },
- { "-bitmap", ".bitmap", XrmoptionSepArg, 0 }
+ { "-bitmap", ".bitmap", XrmoptionSepArg, 0 },
+ { "-grab-screen", ".bitmap", XrmoptionNoArg, "(screen)" },
+ { 0, 0, 0, 0 }
};
-int options_size = (sizeof (options) / sizeof (options[0]));
void
-screenhack (d, w)
- Display *d;
- Window w;
+screenhack (Display *d, Window w)
{
dpy = d;
window = w;
init ();
+ if (delay2) usleep (delay2 * 2);
while (1)
{
rotate ();
+ screenhack_handle_events (d);
if (delay2) usleep (delay2);
}
}