Commit 1ed61fec authored by Sam Lantinga's avatar Sam Lantinga

Fixed bug #360

Fixed fullscreen video modes and improved the mouse grab code.

--HG--
branch : SDL-1.2
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402433
parent e2d89e30
...@@ -37,12 +37,26 @@ public: ...@@ -37,12 +37,26 @@ public:
BView(frame, "SDL View", B_FOLLOW_ALL_SIDES, BView(frame, "SDL View", B_FOLLOW_ALL_SIDES,
(B_WILL_DRAW|B_FRAME_EVENTS)) { (B_WILL_DRAW|B_FRAME_EVENTS)) {
image = NULL; image = NULL;
xoff = yoff = 0;
SetViewColor(0,0,0,0); SetViewColor(0,0,0,0);
SetHighColor(0,0,0,0); SetHighColor(0,0,0,0);
} }
virtual ~SDL_BView() { virtual ~SDL_BView() {
SetBitmap(NULL); 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 /* 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. * draw a nice black box in the entire view to get black borders.
*/ */
...@@ -52,7 +66,7 @@ public: ...@@ -52,7 +66,7 @@ public:
bounds.right = width; bounds.right = width;
bounds.bottom = height; bounds.bottom = height;
/* Fill the entire view with black */ /* Fill the entire view with black */
// FillRect(bounds, B_SOLID_HIGH); FillRect(bounds, B_SOLID_HIGH);
/* And if there's an image, redraw it. */ /* And if there's an image, redraw it. */
if( image ) { if( image ) {
bounds = image->Bounds(); bounds = image->Bounds();
...@@ -69,17 +83,34 @@ public: ...@@ -69,17 +83,34 @@ public:
} }
virtual void Draw(BRect updateRect) { virtual void Draw(BRect updateRect) {
if ( image ) { 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;
DrawBitmap(image, updateRect, dest);
} else {
DrawBitmap(image, updateRect, updateRect); DrawBitmap(image, updateRect, updateRect);
} }
} }
}
virtual void DrawAsync(BRect 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); DrawBitmapAsync(image, updateRect, updateRect);
} }
} }
private: private:
BBitmap *image; BBitmap *image;
int xoff, yoff;
}; };
#endif /* _SDL_BView_h */ #endif /* _SDL_BView_h */
...@@ -149,6 +149,34 @@ public: ...@@ -149,6 +149,34 @@ public:
virtual void SetBitmap(BBitmap *bitmap) { virtual void SetBitmap(BBitmap *bitmap) {
SDL_View->SetBitmap(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) { virtual bool BeginDraw(void) {
return(Lock()); return(Lock());
} }
......
...@@ -166,62 +166,61 @@ void SDL_BWin::DispatchMessage(BMessage *msg, BHandler *target) ...@@ -166,62 +166,61 @@ void SDL_BWin::DispatchMessage(BMessage *msg, BHandler *target)
BPoint where; BPoint where;
int32 transit; int32 transit;
if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { 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 !!! GetXYOffset(x, y);
if(view->input_grab != SDL_GRAB_OFF) x = (int)where.x - x;
{ y = (int)where.y - y;
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);
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 (transit == B_EXITED_VIEW) {
if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
// be_app->SetCursor(B_HAND_CURSOR); be_app->SetCursor(B_HAND_CURSOR);
} }
} else { } else {
if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
int x, y;
if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
SDL_SetCursor(NULL); SDL_SetCursor(NULL);
} }
x = (int)where.x;
y = (int)where.y;
if ( mouse_relative ) { if ( mouse_relative ) {
BPoint center; int half_w = (SDL_VideoSurface->w/2);
center.x = (SDL_VideoSurface->w/2); int half_h = (SDL_VideoSurface->h/2);
center.y = (SDL_VideoSurface->h/2); x -= half_w;
x -= (int)center.x; y -= half_h;
y -= (int)center.y;
if ( x || y ) { if ( x || y ) {
BPoint center;
GetXYOffset(center.x, center.y);
center.x += half_w;
center.y += half_h;
ConvertToScreen(&center); ConvertToScreen(&center);
set_mouse_position((int)center.x, (int)center.y); set_mouse_position((int)center.x, (int)center.y);
SDL_PrivateMouseMotion(0, 1, x, y); SDL_PrivateMouseMotion(0, 1, x, y);
......
...@@ -128,15 +128,14 @@ void BE_FreeWMCursor(_THIS, WMcursor *cursor) ...@@ -128,15 +128,14 @@ void BE_FreeWMCursor(_THIS, WMcursor *cursor)
/* Implementation by Christian Bauer <cbauer@student.physik.uni-mainz.de> */ /* Implementation by Christian Bauer <cbauer@student.physik.uni-mainz.de> */
void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y) void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
{ {
if (_this->screen && (_this->screen->flags & SDL_FULLSCREEN)) { BPoint pt;
SDL_PrivateMouseMotion(0, 0, x, y); SDL_Win->GetXYOffset(pt.x, pt.y);
} else { pt.x += x;
BPoint pt(x, y); pt.y += y;
SDL_Win->Lock(); SDL_Win->Lock();
SDL_Win->ConvertToScreen(&pt); SDL_Win->ConvertToScreen(&pt);
SDL_Win->Unlock(); SDL_Win->Unlock();
set_mouse_position((int32)pt.x, (int32)pt.y); set_mouse_position((int32)pt.x, (int32)pt.y);
}
} }
/* Check to see if we need to enter or leave mouse relative mode */ /* Check to see if we need to enter or leave mouse relative mode */
......
...@@ -366,9 +366,8 @@ static bool BE_FindClosestFSMode(_THIS, int width, int height, int bpp, ...@@ -366,9 +366,8 @@ static bool BE_FindClosestFSMode(_THIS, int width, int height, int bpp,
--i; /* We went too far */ --i; /* We went too far */
} }
/* BeSman::We dont want to use a Desktop resolution */ width = modes[i]->w;
// width = modes[i]->w; height = modes[i]->h;
// height = modes[i]->h;
bscreen.GetModeList(&dmodes, &nmodes); bscreen.GetModeList(&dmodes, &nmodes);
for ( i = 0; i < nmodes; ++i ) { for ( i = 0; i < nmodes; ++i ) {
...@@ -455,6 +454,12 @@ static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen) ...@@ -455,6 +454,12 @@ static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen)
cx = (bounds.IntegerWidth() - width)/2; cx = (bounds.IntegerWidth() - width)/2;
cy = (bounds.IntegerHeight() - height)/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 ) { if ( ! needs_unlock || was_fullscreen ) {
/* Center the window the first time */ /* Center the window the first time */
SDL_Win->MoveTo(cx, cy); SDL_Win->MoveTo(cx, cy);
......
...@@ -274,7 +274,13 @@ int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *d ...@@ -274,7 +274,13 @@ int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *d
return 0; return 0;
} }
BView * bview = overlay->hwdata->bview; BView * bview = overlay->hwdata->bview;
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->MoveTo(dst->x,dst->y);
}
bview->ResizeTo(dst->w,dst->h); bview->ResizeTo(dst->w,dst->h);
bview->Flush(); bview->Flush();
if (overlay->hwdata->first_display) { if (overlay->hwdata->first_display) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment