+
+ 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;
+}
+
+
+void
+destroy_xshm_image (Display *dpy, XImage *image, XShmSegmentInfo *shm_info)
+{
+#ifdef HAVE_XSHM_EXTENSION
+ if (shm_info->shmid == -1) {
+#endif /* HAVE_XSHM_EXTENSION */
+
+ /* Don't let XDestroyImage free image->data. */
+ thread_free (image->data);
+ image->data = NULL;
+ XDestroyImage (image);
+ return;
+
+#ifdef HAVE_XSHM_EXTENSION
+ }
+
+ Status status;
+
+ CATCH_X_ERROR(dpy);
+ status = XShmDetach (dpy, shm_info);
+ UNCATCH_X_ERROR(dpy);
+ if (shm_got_x_error)
+ status = False;
+ if (!status)
+ fprintf (stderr, "%s: XShmDetach failed!\n", progname);
+#ifdef DEBUG
+ else
+ fprintf (stderr, "%s: XShmDetach(dpy, shm_info) ==> True\n", progname);
+#endif
+
+ XDestroyImage (image);
+ XSync(dpy, False);
+
+ status = shmdt (shm_info->shmaddr);
+
+ if (status != 0)
+ {
+ char buf[1024];
+ sprintf (buf, "%s: shmdt(0x%lx) failed", progname,
+ (unsigned long) shm_info->shmaddr);
+ perror(buf);
+ }
+#ifdef DEBUG
+ else
+ fprintf (stderr, "%s: shmdt(shm_info->shmaddr) ==> 0\n", progname);
+#endif
+
+ XSync(dpy, False);
+
+#endif /* HAVE_XSHM_EXTENSION */
+}