+
+#endif /* HAVE_XSHM_EXTENSION */
+}
+
+
+Bool
+put_xshm_image (Display *dpy, Drawable d, GC gc, XImage *image,
+ int src_x, int src_y, int dest_x, int dest_y,
+ unsigned int width, unsigned int height,
+ XShmSegmentInfo *shm_info)
+{
+#ifdef HAVE_XSHM_EXTENSION
+ assert (shm_info); /* Don't just s/XShmPutImage/put_xshm_image/. */
+ if (shm_info->shmid != -1) {
+ /* XShmPutImage is asynchronous; the contents of the XImage must not be
+ modified until the server has placed the pixels on the screen and the
+ client has received an XShmCompletionEvent. Breaking this rule can cause
+ tearing. That said, put_xshm_image doesn't provide a send_event
+ parameter, so we're always breaking this rule. Not that it seems to
+ matter; everything (so far) looks fine without it.
+
+ ####: Add a send_event parameter. And fake it for XPutImage.
+ */
+ return XShmPutImage (dpy, d, gc, image, src_x, src_y, dest_x, dest_y,
+ width, height, False);
+ }
+#endif /* HAVE_XSHM_EXTENSION */
+
+ return XPutImage (dpy, d, gc, image, src_x, src_y, dest_x, dest_y,
+ width, height);
+}
+
+
+Bool
+get_xshm_image (Display *dpy, Drawable d, XImage *image, int x, int y,
+ unsigned long plane_mask, XShmSegmentInfo *shm_info)
+{
+#ifdef HAVE_XSHM_EXTENSION
+ if (shm_info->shmid != -1) {
+ return XShmGetImage (dpy, d, image, x, y, plane_mask);
+ }
+#endif /* HAVE_XSHM_EXTENSION */
+ return XGetSubImage (dpy, d, x, y, image->width, image->height, plane_mask,
+ image->format, image, 0, 0) != NULL;