+
+# else /* !USE_EXTERNAL_SCREEN_GRABBER */
+
+ Display *dpy = DisplayOfScreen (screen);
+ XGCValues gcv;
+ XWindowAttributes xgwa;
+ Window root;
+ int px, py;
+ unsigned int pw, ph, pbw, pd;
+ int srcx, srcy, destx, desty, w2, h2;
+
+ if (verbose_p)
+ {
+ fprintf (stderr, "%s: grabbing desktop image\n", progname);
+ grabscreen_verbose();
+ }
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+ XGetGeometry (dpy, drawable, &root, &px, &py, &pw, &ph, &pbw, &pd);
+
+ grab_screen_image_internal (screen, window);
+
+ compute_image_scaling (xgwa.width, xgwa.height,
+ pw, ph, verbose_p,
+ &srcx, &srcy, &destx, &desty, &w2, &h2);
+
+ if (pw == w2 && ph == h2) /* it fits -- just copy server-side pixmaps */
+ {
+ GC gc = XCreateGC (dpy, drawable, 0, &gcv);
+ XCopyArea (dpy, window, drawable, gc,
+ 0, 0, xgwa.width, xgwa.height, 0, 0);
+ XFreeGC (dpy, gc);
+ }
+ else /* size mismatch -- must scale client-side images to fit drawable */
+ {
+ GC gc;
+ XImage *ximage = 0;
+ XErrorHandler old_handler;
+
+ XSync (dpy, False);
+ old_handler = XSetErrorHandler (ignore_badmatch_ehandler);
+ error_handler_hit_p = False;
+
+ /* This can return BadMatch if the window is not fully on screen.
+ Trap that error and return color bars in that case.
+ (Note that this only happens with XGetImage, not with XCopyArea:
+ yet another totally gratuitous inconsistency in X, thanks.)
+ */
+ ximage = XGetImage (dpy, window, 0, 0, xgwa.width, xgwa.height,
+ ~0L, ZPixmap);
+
+ XSync (dpy, False);
+ XSetErrorHandler (old_handler);
+ XSync (dpy, False);
+
+ if (error_handler_hit_p)
+ {
+ ximage = 0;
+ if (verbose_p)
+ fprintf (stderr, "%s: BadMatch reading window 0x%x contents!\n",
+ progname, (unsigned int) window);
+ }
+
+ if (!ximage ||
+ !scale_ximage (xgwa.screen, xgwa.visual, ximage, w2, h2))
+ return False;
+
+ gc = XCreateGC (dpy, drawable, 0, &gcv);
+ clear_drawable (screen, drawable);
+ XPutImage (dpy, drawable, gc, ximage,
+ srcx, srcy, destx, desty, ximage->width, ximage->height);
+ XDestroyImage (ximage);
+ XFreeGC (dpy, gc);
+ }
+
+ if (geom_ret)
+ {
+ geom_ret->x = destx;
+ geom_ret->y = desty;
+ geom_ret->width = w2;
+ geom_ret->height = h2;
+ }
+
+ XSync (dpy, False);
+ return True;
+
+# endif /* !USE_EXTERNAL_SCREEN_GRABBER */
+}
+
+
+/* Whether the given Drawable is unreasonably small.
+ */
+static Bool
+drawable_miniscule_p (Display *dpy, Drawable drawable)
+{
+ Window root;
+ int xx, yy;
+ unsigned int bw, d, w = 0, h = 0;
+ XGetGeometry (dpy, drawable, &root, &xx, &yy, &w, &h, &bw, &d);
+ return (w < 32 || h < 32);