/***** Pixel reading *****/
/**********************************************************************/
+#ifndef XFree86Server
+/**
+ * Do clip testing prior to calling XGetImage. If any of the region lies
+ * outside the screen's bounds, XGetImage will return NULL.
+ * We use XTranslateCoordinates() to check if that's the case and
+ * adjust the x, y and length parameters accordingly.
+ * \return -1 if span is totally clipped away,
+ * else return number of pixels to skip in the destination array.
+ */
+static int
+clip_for_xgetimage(XMesaContext xmesa, GLuint *n, GLint *x, GLint *y)
+{
+ XMesaBuffer source = xmesa->xm_buffer;
+ Window rootWin = RootWindow(xmesa->display, 0);
+ Window child;
+ int screenWidth = WidthOfScreen(DefaultScreenOfDisplay(xmesa->display));
+ int dx, dy;
+ XTranslateCoordinates(xmesa->display, source->buffer, rootWin,
+ *x, *y, &dx, &dy, &child);
+ if (dx >= screenWidth) {
+ /* totally clipped on right */
+ return -1;
+ }
+ if (dx < 0) {
+ /* clipped on left */
+ int clip = -dx;
+ if (clip >= *n)
+ return -1; /* totally clipped on left */
+ *x += clip;
+ *n -= clip;
+ dx = 0;
+ return clip;
+ }
+ if (dx + *n > screenWidth) {
+ /* clipped on right */
+ int clip = dx + *n - screenWidth;
+ *n -= clip;
+ }
+ return 0;
+}
+#endif
/*
#ifndef XFree86Server
XMesaImage *span = NULL;
int error;
+ int k = clip_for_xgetimage(xmesa, &n, &x, &y);
+ if (k < 0)
+ return;
+ index += k;
+
catch_xgetimage_errors( xmesa->display );
span = XGetImage( xmesa->display, source->buffer,
x, y, n, 1, AllPlanes, ZPixmap );
x, FLIP(source, y), n, 1, ZPixmap,
~0L, (pointer)span->data);
#else
+ int k;
+ y = FLIP(source, y);
+ k = clip_for_xgetimage(xmesa, &n, &x, &y);
+ if (k < 0)
+ return;
+ rgba += k;
catch_xgetimage_errors( xmesa->display );
span = XGetImage( xmesa->display, source->buffer,
- x, FLIP(source, y), n, 1, AllPlanes, ZPixmap );
+ x, y, n, 1, AllPlanes, ZPixmap );
error = check_xgetimage_errors();
#endif
if (span && !error) {