# HG changeset patch # User Sam Lantinga # Date 1183836028 0 # Node ID 4e29535b821b44950d3e29c4681d8c225dc7d09d # Parent f5794774970d39bd72d2b0fba26bb6181d0c0236 Fixed bug #360 Fixed fullscreen video modes and improved the mouse grab code. diff -r f5794774970d -r 4e29535b821b src/video/bwindow/SDL_BView.h --- a/src/video/bwindow/SDL_BView.h Fri Jul 06 13:39:03 2007 +0000 +++ b/src/video/bwindow/SDL_BView.h Sat Jul 07 19:20:28 2007 +0000 @@ -37,12 +37,26 @@ BView(frame, "SDL View", B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS)) { image = NULL; + xoff = yoff = 0; SetViewColor(0,0,0,0); SetHighColor(0,0,0,0); } virtual ~SDL_BView() { SetBitmap(NULL); } + /* Set drawing offsets for fullscreen mode */ + virtual void SetXYOffset(int x, int y) { + xoff = x; + yoff = y; + } + virtual void GetXYOffset(int &x, int &y) { + x = xoff; + y = yoff; + } + virtual void GetXYOffset(float &x, float &y) { + x = (float)xoff; + y = (float)yoff; + } /* The view changed size. If it means we're in fullscreen, we * draw a nice black box in the entire view to get black borders. */ @@ -52,14 +66,14 @@ bounds.right = width; bounds.bottom = height; /* Fill the entire view with black */ -// FillRect(bounds, B_SOLID_HIGH); + FillRect(bounds, B_SOLID_HIGH); /* And if there's an image, redraw it. */ if( image ) { bounds = image->Bounds(); Draw(bounds); } } - + /* Drawing portion of this complete breakfast. :) */ virtual void SetBitmap(BBitmap *bitmap) { if ( image ) { @@ -69,17 +83,34 @@ } virtual void Draw(BRect updateRect) { if ( image ) { - DrawBitmap(image, updateRect, updateRect); + if(xoff || yoff) { + BRect dest; + dest.top = updateRect.top + yoff; + dest.left = updateRect.left + xoff; + dest.bottom = updateRect.bottom + yoff; + dest.right = updateRect.right + xoff; + DrawBitmap(image, updateRect, dest); + } else { + DrawBitmap(image, updateRect, updateRect); + } } } virtual void DrawAsync(BRect updateRect) { - if ( image ) { + if(xoff || yoff) { + BRect dest; + dest.top = updateRect.top + yoff; + dest.left = updateRect.left + xoff; + dest.bottom = updateRect.bottom + yoff; + dest.right = updateRect.right + xoff;; + DrawBitmapAsync(image, updateRect, dest); + } else { DrawBitmapAsync(image, updateRect, updateRect); } } private: BBitmap *image; + int xoff, yoff; }; #endif /* _SDL_BView_h */ diff -r f5794774970d -r 4e29535b821b src/video/bwindow/SDL_BWin.h --- a/src/video/bwindow/SDL_BWin.h Fri Jul 06 13:39:03 2007 +0000 +++ b/src/video/bwindow/SDL_BWin.h Sat Jul 07 19:20:28 2007 +0000 @@ -149,6 +149,34 @@ virtual void SetBitmap(BBitmap *bitmap) { SDL_View->SetBitmap(bitmap); } + virtual void SetXYOffset(int x, int y) { +#if SDL_VIDEO_OPENGL + if ( the_view == SDL_GLView ) { + return; + } +#endif + SDL_View->SetXYOffset(x, y); + } + virtual void GetXYOffset(int &x, int &y) { +#if SDL_VIDEO_OPENGL + if ( the_view == SDL_GLView ) { + x = 0; + y = 0; + return; + } +#endif + SDL_View->GetXYOffset(x, y); + } + virtual void GetXYOffset(float &x, float &y) { +#if SDL_VIDEO_OPENGL + if ( the_view == SDL_GLView ) { + x = 0.0f; + y = 0.0f; + return; + } +#endif + SDL_View->GetXYOffset(x, y); + } virtual bool BeginDraw(void) { return(Lock()); } diff -r f5794774970d -r 4e29535b821b src/video/bwindow/SDL_sysevents.cc --- a/src/video/bwindow/SDL_sysevents.cc Fri Jul 06 13:39:03 2007 +0000 +++ b/src/video/bwindow/SDL_sysevents.cc Sat Jul 07 19:20:28 2007 +0000 @@ -166,62 +166,61 @@ BPoint where; int32 transit; if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { + int x, y; -//BeSman: I need another method for cursor catching !!! -if(view->input_grab != SDL_GRAB_OFF) -{ - BPoint center; - center.x = (SDL_VideoSurface->w/2); - center.y = (SDL_VideoSurface->h/2); - BPoint delta = where - center; -if(delta.x > center.x) -SDL_WarpMouse((int)center.x*2,(int)where.y); - -if(delta.x < -center.x) -SDL_WarpMouse(0,(int)where.y); - -if(delta.y > center.y) -SDL_WarpMouse((int)where.x,(int)center.y*2); + GetXYOffset(x, y); + x = (int)where.x - x; + y = (int)where.y - y; -if(delta.y < -center.y) -SDL_WarpMouse((int)where.x,0); - - -if((delta.x-1 < -center.x)&&(delta.y-1 < -center.y)) -SDL_WarpMouse(1,1); - -if((delta.x-1 < -center.x)&&(delta.y+1 > center.y)) -SDL_WarpMouse(1,(int)center.y*2-1); - -if((delta.x+1 > center.x)&&(delta.y-1 < -center.y)) -SDL_WarpMouse((int)center.x*2-1,1); - -if((delta.x+1 > center.x)&&(delta.y+1 > center.y)) -SDL_WarpMouse((int)center.x*2-1,(int)center.y*2-1); - -} + //BeSman: I need another method for cursor catching !!! + if (view->input_grab != SDL_GRAB_OFF) + { + bool clipped = false; + if ( x < 0 ) { + x = 0; + clipped = true; + } else if ( x >= SDL_VideoSurface->w ) { + x = (SDL_VideoSurface->w-1); + clipped = true; + } + if ( y < 0 ) { + y = 0; + clipped = true; + } else if ( y >= SDL_VideoSurface->h ) { + y = (SDL_VideoSurface->h-1); + clipped = true; + } + if ( clipped ) { + BPoint edge; + GetXYOffset(edge.x, edge.y); + edge.x += x; + edge.y += y; + ConvertToScreen(&edge); + set_mouse_position((int)edge.x, (int)edge.y); + } + transit = B_INSIDE_VIEW; + } if (transit == B_EXITED_VIEW) { if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - // be_app->SetCursor(B_HAND_CURSOR); + be_app->SetCursor(B_HAND_CURSOR); } } else { - - int x, y; - if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { + if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); SDL_SetCursor(NULL); } - x = (int)where.x; - y = (int)where.y; if ( mouse_relative ) { - BPoint center; - center.x = (SDL_VideoSurface->w/2); - center.y = (SDL_VideoSurface->h/2); - x -= (int)center.x; - y -= (int)center.y; + int half_w = (SDL_VideoSurface->w/2); + int half_h = (SDL_VideoSurface->h/2); + x -= half_w; + y -= half_h; if ( x || y ) { + BPoint center; + GetXYOffset(center.x, center.y); + center.x += half_w; + center.y += half_h; ConvertToScreen(¢er); set_mouse_position((int)center.x, (int)center.y); SDL_PrivateMouseMotion(0, 1, x, y); diff -r f5794774970d -r 4e29535b821b src/video/bwindow/SDL_sysmouse.cc --- a/src/video/bwindow/SDL_sysmouse.cc Fri Jul 06 13:39:03 2007 +0000 +++ b/src/video/bwindow/SDL_sysmouse.cc Sat Jul 07 19:20:28 2007 +0000 @@ -128,15 +128,14 @@ /* Implementation by Christian Bauer */ void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y) { - if (_this->screen && (_this->screen->flags & SDL_FULLSCREEN)) { - SDL_PrivateMouseMotion(0, 0, x, y); - } else { - BPoint pt(x, y); - SDL_Win->Lock(); - SDL_Win->ConvertToScreen(&pt); - SDL_Win->Unlock(); - set_mouse_position((int32)pt.x, (int32)pt.y); - } + BPoint pt; + SDL_Win->GetXYOffset(pt.x, pt.y); + pt.x += x; + pt.y += y; + SDL_Win->Lock(); + SDL_Win->ConvertToScreen(&pt); + SDL_Win->Unlock(); + set_mouse_position((int32)pt.x, (int32)pt.y); } /* Check to see if we need to enter or leave mouse relative mode */ diff -r f5794774970d -r 4e29535b821b src/video/bwindow/SDL_sysvideo.cc --- a/src/video/bwindow/SDL_sysvideo.cc Fri Jul 06 13:39:03 2007 +0000 +++ b/src/video/bwindow/SDL_sysvideo.cc Sat Jul 07 19:20:28 2007 +0000 @@ -366,9 +366,8 @@ --i; /* We went too far */ } -/* BeSman::We dont want to use a Desktop resolution */ -// width = modes[i]->w; -// height = modes[i]->h; + width = modes[i]->w; + height = modes[i]->h; bscreen.GetModeList(&dmodes, &nmodes); for ( i = 0; i < nmodes; ++i ) { @@ -455,6 +454,12 @@ cx = (bounds.IntegerWidth() - width)/2; cy = (bounds.IntegerHeight() - height)/2; + if ( fullscreen ) { + /* Set offset for drawing */ + SDL_Win->SetXYOffset(cx, cy); + } else { + SDL_Win->SetXYOffset(0, 0); + } if ( ! needs_unlock || was_fullscreen ) { /* Center the window the first time */ SDL_Win->MoveTo(cx, cy); diff -r f5794774970d -r 4e29535b821b src/video/bwindow/SDL_sysyuv.cc --- a/src/video/bwindow/SDL_sysyuv.cc Fri Jul 06 13:39:03 2007 +0000 +++ b/src/video/bwindow/SDL_sysyuv.cc Sat Jul 07 19:20:28 2007 +0000 @@ -274,7 +274,13 @@ return 0; } BView * bview = overlay->hwdata->bview; - bview->MoveTo(dst->x,dst->y); + if (SDL_Win->IsFullScreen()) { + int left,top; + SDL_Win->GetXYOffset(left,top); + bview->MoveTo(left+dst->x,top+dst->y); + } else { + bview->MoveTo(dst->x,dst->y); + } bview->ResizeTo(dst->w,dst->h); bview->Flush(); if (overlay->hwdata->first_display) {