From e088fc522b9a528a038a9e24c89d3298fba6b06e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 17 Apr 2006 05:38:33 +0000 Subject: [PATCH] Fixed bug #189 Clip the overlay destination rectangle to the screen area on X11 --- src/video/x11/SDL_x11yuv.c | 47 ++++++++++++++++++++++++++++++++++---- test/testoverlay2.c | 4 ++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/video/x11/SDL_x11yuv.c b/src/video/x11/SDL_x11yuv.c index 22bbda115..30953874b 100644 --- a/src/video/x11/SDL_x11yuv.c +++ b/src/video/x11/SDL_x11yuv.c @@ -357,20 +357,59 @@ void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) { struct private_yuvhwdata *hwdata; + int srcx, srcy, srcw, srch; + int dstx, dsty, dstw, dsth; hwdata = overlay->hwdata; + + /* Clip the rectangle to the screen area */ + srcx = 0; + srcy = 0; + srcw = overlay->w; + srch = overlay->h; + dstx = dstrect->x; + dsty = dstrect->y; + dstw = dstrect->w; + dsth = dstrect->h; + if ( dstx < 0 ) { + srcw += (dstx * overlay->w) / dstrect->w; + dstw += dstx; + srcx -= (dstx * overlay->w) / dstrect->w; + dstx = 0; + } + if ( (dstx+dstw) > this->screen->w ) { + int extra = (dstx+dstw - this->screen->w); + srcw -= (extra * overlay->w) / dstrect->w; + dstw -= extra; + } + if ( dsty < 0 ) { + srch += (dsty * overlay->h) / dstrect->h; + dsth += dsty; + srcy -= (dsty * overlay->h) / dstrect->h; + dsty = 0; + } + if ( (dsty+dsth) > this->screen->h ) { + int extra = (dsty+dsth - this->screen->h); + srch -= (extra * overlay->h) / dstrect->h; + dsth -= extra; + } + if ( srcw <= 0 || srch <= 0 || + srch <= 0 || dsth <= 0 ) { + return; + } + #ifndef NO_SHARED_MEMORY if ( hwdata->yuv_use_mitshm ) { SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC, - hwdata->image, 0, 0, overlay->w, overlay->h, - dstrect->x, dstrect->y, dstrect->w, dstrect->h, False); + hwdata->image, + srcx, srcy, srcw, srch, dstx, dsty, dstw, dsth, False); } else #endif { SDL_NAME(XvPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC, - hwdata->image, 0, 0, overlay->w, overlay->h, - dstrect->x, dstrect->y, dstrect->w, dstrect->h); + hwdata->image, + srcx, srcy, srcw, srch, dstx, dsty, dstw, dsth); } XSync(GFX_Display, False); return(0); diff --git a/test/testoverlay2.c b/test/testoverlay2.c index 28cd3dd70..5f491f22d 100644 --- a/test/testoverlay2.c +++ b/test/testoverlay2.c @@ -526,6 +526,10 @@ int main(int argc, char **argv) resized=1; } break; + case SDL_MOUSEBUTTONDOWN: + overlayrect.x = event.button.x - overlayrect.w/2; + overlayrect.y = event.button.y - overlayrect.h/2; + break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_SPACE) {