From b12594d2a0bbe22da092b6b08917259b9f5871b7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 9 Nov 2004 01:20:57 +0000 Subject: do clipping prior to XGetImage, just in case the image would extend beyond the screen's bounds --- src/mesa/drivers/x11/xm_span.c | 54 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/x11/xm_span.c b/src/mesa/drivers/x11/xm_span.c index 71a4c80082..6e4bcb18a0 100644 --- a/src/mesa/drivers/x11/xm_span.c +++ b/src/mesa/drivers/x11/xm_span.c @@ -3456,6 +3456,47 @@ static void write_pixels_index_ximage( INDEX_PIXELS_ARGS ) /***** 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 /* @@ -3474,6 +3515,11 @@ static void read_index_span( const GLcontext *ctx, #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 ); @@ -3530,9 +3576,15 @@ static void read_color_span( const GLcontext *ctx, 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) { -- cgit v1.2.3