#include "colorbars.h"
#include "visual.h"
#include "prefs.h"
+#include "version.h"
#include "vroot.h"
+#ifndef _XSCREENSAVER_VROOT_H_
+# error Error! You have an old version of vroot.h! Check -I args.
+#endif /* _XSCREENSAVER_VROOT_H_ */
+
#ifdef HAVE_GDK_PIXBUF
# undef HAVE_JPEGLIB
# ifdef HAVE_GTK2
#endif
+#ifdef __GNUC__
+ __extension__ /* shut up about "string length is greater than the length
+ ISO C89 compilers are required to support" when including
+ the .ad file... */
+#endif
+
static char *defaults[] = {
#include "../driver/XScreenSaver_ad.h"
0
static int
x_ehandler (Display *dpy, XErrorEvent *error)
{
- fprintf (stderr, "\nX error in %s:\n", progname);
- XmuPrintDefaultErrorMessage (dpy, error, stderr);
+ if (error->error_code == BadWindow || error->error_code == BadDrawable)
+ {
+ fprintf (stderr, "%s: target %s 0x%lx unexpectedly deleted\n", progname,
+ (error->error_code == BadWindow ? "window" : "pixmap"),
+ (unsigned long) error->resourceid);
+ }
+ else
+ {
+ fprintf (stderr, "\nX error in %s:\n", progname);
+ XmuPrintDefaultErrorMessage (dpy, error, stderr);
+ }
exit (-1);
return 0;
}
}
+/* Returns true if the window is the root window, or a virtual root window,
+ but *not* the xscreensaver window. That is, if it's a "real" desktop
+ root window of some kind.
+ */
+static Bool
+root_window_p (Screen *screen, Window window)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ Atom type;
+ int format;
+ unsigned long nitems, bytesafter;
+ char *version;
+
+ if (window != RootWindowOfScreen (screen))
+ return False;
+
+ if (XGetWindowProperty (dpy, window,
+ XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
+ 0, 1, False, XA_STRING,
+ &type, &format, &nitems, &bytesafter,
+ (unsigned char **) &version)
+ == Success
+ && type != None)
+ return False;
+
+ return True;
+}
+
+
/* Clear the window or pixmap to black, or its background color.
*/
static void
int th = src_h * r;
int pct = (r * 100);
+#if 0
+ /* this optimization breaks things */
if (pct < 95 || pct > 105) /* don't scale if it's close */
+#endif
{
if (verbose_p)
fprintf (stderr, "%s: scaling image by %d%% (%dx%d -> %dx%d)\n",
{
GdkPixbuf *pb;
Display *dpy = DisplayOfScreen (screen);
- unsigned int win_width, win_height;
+ unsigned int win_width, win_height, win_depth;
# ifdef HAVE_GTK2
GError *gerr = 0;
# endif /* HAVE_GTK2 */
+ /* Find the size of the Drawable. */
{
Window root;
int x, y;
- unsigned int bw, d;
- XWindowAttributes xgwa;
- XGetWindowAttributes (dpy, window, &xgwa);
- screen = xgwa.screen;
+ unsigned int bw;
XGetGeometry (dpy, drawable,
- &root, &x, &y, &win_width, &win_height, &bw, &d);
+ &root, &x, &y, &win_width, &win_height, &bw, &win_depth);
}
gdk_pixbuf_xlib_init (dpy, screen_number (screen));
int w = gdk_pixbuf_get_width (pb);
int h = gdk_pixbuf_get_height (pb);
int srcx, srcy, destx, desty, w2, h2;
+ Bool bg_p = False;
compute_image_scaling (w, h, win_width, win_height, verbose_p,
&srcx, &srcy, &destx, &desty, &w2, &h2);
fprintf (stderr, "%s: out of memory when scaling?\n", progname);
}
- clear_drawable (screen, drawable);
+ /* If we're rendering onto the root window (and it's not the
+ xscreensaver pseudo-root) then put the image in the window's
+ background. Otherwise, just paint the image onto the window.
+ */
+ bg_p = (window == drawable && root_window_p (screen, window));
+
+ if (bg_p)
+ {
+ XGCValues gcv;
+ GC gc;
+ drawable = XCreatePixmap (dpy, window,
+ win_width, win_height, win_depth);
+ gcv.foreground = BlackPixelOfScreen (screen);
+ gc = XCreateGC (dpy, drawable, GCForeground, &gcv);
+ XFillRectangle (dpy, drawable, gc, 0, 0, win_width, win_height);
+ XFreeGC (dpy, gc);
+ }
+ else
+ clear_drawable (screen, drawable);
/* #### Note that this always uses the default colormap! Morons!
Owen says that in Gnome 2.0, I should try using
GDK_PIXBUF_ALPHA_FULL, 127,
XLIB_RGB_DITHER_NORMAL,
0, 0);
- XSync (dpy, False);
+ if (bg_p)
+ {
+ XSetWindowBackgroundPixmap (dpy, window, drawable);
+ XClearWindow (dpy, window);
+ }
}
+ XSync (dpy, False);
return True;
}
ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, 0,
w, h, 8, 0);
if (ximage)
- ximage->data = (unsigned char *)
- calloc (ximage->height, ximage->bytes_per_line);
+ ximage->data = (char *) calloc (ximage->height, ximage->bytes_per_line);
if (!ximage || !ximage->data)
{
fprintf (stderr, "%s: out of memory loading %dx%d PPM file %s\n",
cinfo.output_width, cinfo.output_height,
8, 0);
if (ximage)
- ximage->data = (unsigned char *)
- calloc (ximage->height, ximage->bytes_per_line);
+ ximage->data = (char *) calloc (ximage->height, ximage->bytes_per_line);
if (ximage && ximage->data)
scanbuf = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE,
XImage *ximage2 = XCreateImage (dpy, visual, depth,
ZPixmap, 0, 0,
new_width, new_height, 8, 0);
- ximage2->data = (unsigned char *)
- calloc (ximage2->height, ximage2->bytes_per_line);
+ ximage2->data = (char *) calloc (ximage2->height, ximage2->bytes_per_line);
if (!ximage2->data)
{
unsigned int win_width, win_height, win_depth;
int srcx, srcy, destx, desty, w2, h2;
+ /* Find the size of the Drawable, and the Visual/Colormap of the Window. */
{
Window root;
int x, y;
unsigned int bw;
XWindowAttributes xgwa;
-
XGetWindowAttributes (dpy, window, &xgwa);
- screen = xgwa.screen;
visual = xgwa.visual;
cmap = xgwa.colormap;
-
XGetGeometry (dpy, drawable,
&root, &x, &y, &win_width, &win_height, &bw, &win_depth);
}
/* Finally, put the resized image on the window.
*/
- clear_drawable (screen, drawable);
{
GC gc;
XGCValues gcv;
- gc = XCreateGC (dpy, drawable, 0, &gcv);
- XPutImage (dpy, drawable, gc, ximage,
- srcx, srcy, destx, desty, ximage->width, ximage->height);
+
+ /* If we're rendering onto the root window (and it's not the xscreensaver
+ pseudo-root) then put the image in the window's background. Otherwise,
+ just paint the image onto the window.
+ */
+ if (window == drawable && root_window_p (screen, window))
+ {
+ Pixmap bg = XCreatePixmap (dpy, window,
+ win_width, win_height, win_depth);
+ gcv.foreground = BlackPixelOfScreen (screen);
+ gc = XCreateGC (dpy, drawable, GCForeground, &gcv);
+ XFillRectangle (dpy, bg, gc, 0, 0, win_width, win_height);
+ XPutImage (dpy, bg, gc, ximage,
+ srcx, srcy, destx, desty, ximage->width, ximage->height);
+ XSetWindowBackgroundPixmap (dpy, window, bg);
+ XClearWindow (dpy, window);
+ }
+ else
+ {
+ gc = XCreateGC (dpy, drawable, 0, &gcv);
+ clear_drawable (screen, drawable);
+ XPutImage (dpy, drawable, gc, ximage,
+ srcx, srcy, destx, desty, ximage->width, ximage->height);
+ }
+
XFreeGC (dpy, gc);
}
exit (1);
}
+ /* Make sure the Screen and the Window correspond. */
+ {
+ XWindowAttributes xgwa;
+ XGetWindowAttributes (dpy, window, &xgwa);
+ screen = xgwa.screen;
+ }
+
if (file && stat (file, &st))
{
fprintf (stderr, "%s: file \"%s\" does not exist\n", progname, file);
/* We can grab desktop images if:
- the window is the real root window;
- - the window is the virtal root window;
- the window is a toplevel window.
We cannot grab desktop images if:
- the window is a non-top-level window.
#define USAGE "usage: %s [ -options... ] window-id [pixmap-id]\n" \
"\n" \
- " This program puts an image on the given window or pixmap.\n" \
+ " %s\n" \
+ "\n" \
+ " %s puts an image on the given window or pixmap.\n" \
"\n" \
" It is used by those xscreensaver demos that operate on images.\n" \
" The image may be a file loaded from disk, a frame grabbed from\n" \
Screen *screen;
char *oprogname = progname;
char *file = 0;
+ char version[255];
Window window = (Window) 0;
Drawable drawable = (Drawable) 0;
# error Error! This file definitely needs vroot.h!
# endif
+ /* Get the version number, for error messages. */
+ {
+ char *v = (char *) strdup(strchr(screensaver_id, ' '));
+ char *s1, *s2, *s3, *s4;
+ s1 = (char *) strchr(v, ' '); s1++;
+ s2 = (char *) strchr(s1, ' ');
+ s3 = (char *) strchr(v, '('); s3++;
+ s4 = (char *) strchr(s3, ')');
+ *s2 = 0;
+ *s4 = 0;
+ sprintf (version, "Part of XScreenSaver %s -- %s.", s1, s3);
+ free(v);
+ }
+
/* We must read exactly the same resources as xscreensaver.
That means we must have both the same progclass *and* progname,
at least as far as the resource database is concerned. So,
goto LOSE;
}
window_str = argv[i];
- window = (Window) RootWindowOfScreen (screen);
+ window = VirtualRootWindowOfScreen (screen);
}
else if ((1 == sscanf (argv[i], " 0x%lx %c", &w, &dummy) ||
- 1 == sscanf (argv[i], " %ld %c", &w, &dummy)) &&
+ 1 == sscanf (argv[i], " %lu %c", &w, &dummy)) &&
w != 0)
{
if (drawable)
fprintf (stderr, "\n%s: unparsable window/pixmap ID: \"%s\"\n",
progname, argv[i]);
LOSE:
- fprintf (stderr, USAGE, progname);
+# ifdef __GNUC__
+ __extension__ /* don't warn about "string length is greater than
+ the length ISO C89 compilers are required to
+ support" in the usage string... */
+# endif
+ fprintf (stderr, USAGE, progname, version, progname);
exit (1);
}
}