changeset 4012:4e29535b821b SDL-1.2

Fixed bug #360 Fixed fullscreen video modes and improved the mouse grab code.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 07 Jul 2007 19:20:28 +0000
parents f5794774970d
children 5804139bdf0b
files src/video/bwindow/SDL_BView.h src/video/bwindow/SDL_BWin.h src/video/bwindow/SDL_sysevents.cc src/video/bwindow/SDL_sysmouse.cc src/video/bwindow/SDL_sysvideo.cc src/video/bwindow/SDL_sysyuv.cc
diffstat 6 files changed, 128 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- 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 */
--- 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());
 	}
--- 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(&center);
 							set_mouse_position((int)center.x, (int)center.y);
 							SDL_PrivateMouseMotion(0, 1, x, y);
--- 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 <cbauer@student.physik.uni-mainz.de> */
 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 */
--- 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);
--- 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) {