Date: Thu, 16 Aug 2001 21:50:51 -0500 (EST)
authorSam Lantinga <slouken@libsdl.org>
Sun, 19 Aug 2001 23:57:39 +0000
changeset 155 2d162219f433
parent 154 50d2b5305c2c
child 156 7064032cbe77
Date: Thu, 16 Aug 2001 21:50:51 -0500 (EST) From: Darrell Walisser <dwaliss1@purdue.edu> Subject: Patch for video bugs + Max's additions I've attached a patch for today's CVS that includes Max's virtual mouse button fix as well as some other changes: -building mode list correctly now (had duplicate entries, was unsorted) -switching modes correctly now (wasn't destroying previous mode) -releasing memory correctly in event loop
src/video/maccommon/SDL_macevents.c
src/video/quartz/SDL_QuartzEvents.m
src/video/quartz/SDL_QuartzVideo.h
src/video/quartz/SDL_QuartzVideo.m
--- a/src/video/maccommon/SDL_macevents.c	Sat Aug 18 22:24:19 2001 +0000
+++ b/src/video/maccommon/SDL_macevents.c	Sun Aug 19 23:57:39 2001 +0000
@@ -107,6 +107,7 @@
 /* The main MacOS event handler */
 static int Mac_HandleEvents(_THIS, int wait4it)
 {
+	static int mouse_button = 1;
 	int i;
 	EventRecord event;
 
@@ -148,7 +149,7 @@
 	/* for some reason, event.where isn't set ? */
 	GetGlobalMouse ( &event.where );
 #endif
-    
+
 	/* Check for mouse motion */
 	if ( (event.where.h != last_where.h) ||
 	     (event.where.v != last_where.v) ) {
@@ -282,16 +283,14 @@
 			myGlobalToLocal(this, &event.where);
 			/* Treat command-click as right mouse button */
 			if ( event.modifiers & optionKey ) {
-			    SDL_PrivateMouseButton(SDL_PRESSED,
-					2,event.where.h,event.where.v);
+				mouse_button = 2;
+			} else if ( event.modifiers & cmdKey ) {
+				mouse_button = 3;
+			} else {
+				mouse_button = 1;
 			}
-			else if ( event.modifiers & cmdKey ) {
-			    SDL_PrivateMouseButton(SDL_PRESSED,
-					3,event.where.h,event.where.v);
-			} else {
-			    SDL_PrivateMouseButton(SDL_PRESSED,
-					1,event.where.h,event.where.v);
-			}
+			SDL_PrivateMouseButton(SDL_PRESSED,
+				mouse_button, event.where.h, event.where.v);
 			break;
 		  case inGrow: {
 			int newSize;
@@ -336,7 +335,7 @@
 			if ( TrackBox (win, event.where, area )) {
 				if ( IsWindowCollapsable(win) ) {
 					CollapseWindow (win, !IsWindowCollapsed(win));
-					// There should be something done like in inGrow case, but...
+					/* There should be something done like in inGrow case, but... */
 				}
 			}
 			break;
@@ -355,18 +354,14 @@
 	  break;
 	  case mouseUp: {
 		myGlobalToLocal(this, &event.where);
-		/* Treat command-click as right mouse button */
-		if ( event.modifiers & cmdKey ) {
-		    SDL_PrivateMouseButton(SDL_RELEASED,
-				3, event.where.h, event.where.v);
-		}
-		else if ( event.modifiers & optionKey ) {
-		    SDL_PrivateMouseButton(SDL_RELEASED,
-				2,event.where.h,event.where.v);
-		} else {
-		    SDL_PrivateMouseButton(SDL_RELEASED,
-				1, event.where.h, event.where.v);
-		}
+		/* Release the mouse button we simulated in the last press.
+		   The drawback of this methos is we cannot press more than
+		   one button. However, this doesn't matter, since there is
+		   only a single logical mouse button, even if you have a
+		   multi-button mouse, this doesn't matter at all.
+		 */
+		SDL_PrivateMouseButton(SDL_RELEASED,
+			mouse_button, event.where.h, event.where.v);
 	  }
 	  break;
 #if 0 /* Handled above the switch statement */
--- a/src/video/quartz/SDL_QuartzEvents.m	Sat Aug 18 22:24:19 2001 +0000
+++ b/src/video/quartz/SDL_QuartzEvents.m	Sun Aug 19 23:57:39 2001 +0000
@@ -22,6 +22,8 @@
 
 #include "SDL_QuartzKeys.h"
 
+static int last_virtual_button = 0; // Last virtual mouse button pressed
+
 static void  QZ_InitOSKeymap (_THIS) {
 	int i;
 
@@ -222,12 +224,16 @@
 
 static void QZ_PumpEvents (_THIS)
 { 
-    NSDate *distantPast = [ NSDate distantPast ];
-    
+    NSDate *distantPast;
     NSEvent *event;
     NSRect winRect;
     NSRect titleBarRect;
-            
+    NSAutoreleasePool *pool;
+    
+    distantPast = [ [ NSDate distantPast ] retain ];
+    
+    pool = [ [ NSAutoreleasePool alloc ] init ];
+    
     winRect = NSMakeRect (0, 0, SDL_VideoSurface->w + 1, SDL_VideoSurface->h + 1);
     titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
         SDL_VideoSurface->h + 22 );
@@ -266,9 +272,11 @@
             
             case NSLeftMouseDown:  
                 if ( NSCommandKeyMask & currentMods ) {
-                        DO_MOUSE_DOWN (3, 0);
+                    last_virtual_button = 3;
+                    DO_MOUSE_DOWN (3, 0);
                 } 
                 else if ( NSAlternateKeyMask & currentMods ) {
+                    last_virtual_button = 2;
                     DO_MOUSE_DOWN (2, 0);
                 } 
                 else {
@@ -278,14 +286,14 @@
             case 25:               DO_MOUSE_DOWN (2, 0); break;
             case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;   
             case NSLeftMouseUp:    
-            if ( NSCommandKeyMask & currentMods ) {
-                        DO_MOUSE_UP (3, 0);
-                } 
-                else if ( NSAlternateKeyMask & currentMods ) {
-                    DO_MOUSE_UP (2, 0);
-                } 
-                else
+            
+                if ( last_virtual_button != 0 ) {
+                    DO_MOUSE_UP (last_virtual_button, 0);
+                    last_virtual_button = 0;
+                }
+                else {
                     DO_MOUSE_UP (1, 1);
+                }
                 break;
             case 26:               DO_MOUSE_UP (2, 0);   break;
             case NSRightMouseUp:   DO_MOUSE_UP (3, 0);   break;
@@ -364,5 +372,8 @@
             }
         }
       } while (event != nil);
+      
+      [ pool release ];
+      [ distantPast release ];
 }
 
--- a/src/video/quartz/SDL_QuartzVideo.h	Sat Aug 18 22:24:19 2001 +0000
+++ b/src/video/quartz/SDL_QuartzVideo.h	Sun Aug 19 23:57:39 2001 +0000
@@ -83,8 +83,9 @@
     CFArrayRef         mode_list;
     CGDirectPaletteRef palette;
     NSOpenGLContext    *gl_context;
-    int                width, height, bpp;
+    Uint32             width, height, bpp;
     Uint32             flags;
+    SDL_bool           video_is_set; /* tell if the video mode was set */
     
     /* Window-only fields */
     NSWindow        *window;
@@ -105,6 +106,7 @@
 #define device_height (this->hidden->height)
 #define device_bpp (this->hidden->bpp)
 #define mode_flags (this->hidden->flags)
+#define video_set (this->hidden->video_is_set)
 #define window (this->hidden->window)
 #define windowView (this->hidden->view)
 
--- a/src/video/quartz/SDL_QuartzVideo.m	Sat Aug 18 22:24:19 2001 +0000
+++ b/src/video/quartz/SDL_QuartzVideo.m	Sun Aug 19 23:57:39 2001 +0000
@@ -27,14 +27,13 @@
 static BOOL   inForeground = YES;
 static SDLKey keymap[256];
 static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
+static char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */
 
 /* Include files into one compile unit...break apart eventually */
 #include "SDL_QuartzWM.m"
 #include "SDL_QuartzEvents.m"
 #include "SDL_QuartzWindow.m"
 
-char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */
-
 /* Bootstrap binding, enables entry point into the driver */
 VideoBootStrap QZ_bootstrap = {
     "Quartz", "MacOS X CoreGraphics", QZ_Available, QZ_CreateDevice
@@ -143,7 +142,7 @@
 
     static SDL_Rect **list = NULL;
     int list_size = 0;
-
+    
     /* Any windowed mode is acceptable */
     if ( (flags & SDL_FULLSCREEN) == 0 )
         return (SDL_Rect**)-1;
@@ -151,7 +150,7 @@
     /* Free memory from previous call, if any */
     if ( list != NULL ) {
 
-      int i = 0;
+      int i;
 
       for (i = 0; list[i] != NULL; i++)
 	free (list[i]);
@@ -159,23 +158,24 @@
       free (list);
       list = NULL;
     }
-
+    
     /* Build list of modes with the requested bpp */
-    for (i = num_modes-1; i >= 0; i--) {
+    for (i = 0; i < num_modes; i++) {
    
-        CFDictionaryRef onemode = CFArrayGetValueAtIndex (mode_list, i);
-	CFNumberRef     number;
+        CFDictionaryRef onemode;
+        CFNumberRef     number;
 	int bpp;
 	
+        onemode = CFArrayGetValueAtIndex (mode_list, i); 
 	number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel);
 	CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);
 
 	if (bpp == format->BitsPerPixel) {
 	  
-	  int       intvalue;
-	  SDL_Rect *rect;
-          int       lastwidth = 0, lastheight = 0, width, height;
-
+	  int intvalue;
+          int hasMode;
+          int width, height;
+          
 	  number = CFDictionaryGetValue (onemode, kCGDisplayWidth);
 	  CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
 	  width = (Uint16) intvalue;
@@ -184,12 +184,23 @@
 	  CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
 	  height = (Uint16) intvalue;
           
-          /* We'll get a lot of modes with the same size, so ignore them */
-          if ( width != lastwidth && height != lastheight ) {
-
-            lastwidth  = width;
-            lastheight = height;
+          /* Check if mode is already in the list */
+          {
+            int i;
+            hasMode = SDL_FALSE;
+            for (i = 0; i < list_size; i++) {
+                if (list[i]->w == width && list[i]->h == height) {
+                    hasMode = SDL_TRUE;
+                    break;
+                }
+            }
+          }
+          
+          /* Grow the list and add mode to the list */
+          if ( ! hasMode ) {
 	  
+            SDL_Rect *rect;
+            
             list_size++;
 
             if ( list == NULL)
@@ -211,14 +222,29 @@
       }
     }
     
+    /* Sort list largest to smallest (by area) */
+    {
+        int i, j;
+        for (i = 0; i < list_size; i++) {
+            for (j = 0; j < list_size-1; j++) {
+            
+                int area1, area2;
+                area1 = list[j]->w * list[j]->h;
+                area2 = list[j+1]->w * list[j+1]->h;
+                
+                if (area1 < area2) {
+                    SDL_Rect *tmp = list[j];
+                    list[j] = list[j+1];
+                    list[j+1] = tmp;
+                }
+            }
+        }
+    }
     return list;
 }
 
 static void QZ_UnsetVideoMode (_THIS) {
 
-    if ( mode_flags & SDL_OPENGL )
-        QZ_TearDownOpenGL (this);
-
     /* Reset values that may change between switches */
     this->info.blit_fill = 0;
     this->FillHWRect     = NULL;
@@ -229,9 +255,11 @@
    
     /* Restore original screen resolution */
     if ( mode_flags & SDL_FULLSCREEN ) {
+        if (mode_flags & SDL_OPENGL)
+            CGLSetFullScreen(NULL);
+            
         CGDisplaySwitchToMode (display_id, save_mode);
         CGDisplayRelease (display_id);
-        this->screen->pixels = NULL;
     }
     /* Release window mode data structures */
     else { 
@@ -240,13 +268,24 @@
             [ windowView release  ];
         }
         [ window setContentView:nil ];
+        [ window setDelegate:nil ];
         [ window close ];
-        [ window release ];
     }
     
+    /* Set pixels to null (so other code doesn't try to free it) */
+    if (this->screen != NULL)
+        this->screen->pixels = NULL;
+        
+    /* Release the OpenGL context */
+    if ( mode_flags & SDL_OPENGL )
+        QZ_TearDownOpenGL (this);
+        
     /* Ensure the cursor will be visible and working when we quit */
     CGDisplayShowCursor (display_id);
     CGAssociateMouseAndMouseCursorPosition (1);
+    
+    /* Signal successful teardown */
+    video_set = SDL_FALSE;
 }
 
 static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
@@ -263,7 +302,7 @@
         SDL_SetError (QZ_Error);
         goto ERR_NO_MATCH;
     }
-    
+
     /* Put up the blanking window (a window above all other windows) */
     if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) {
         SDL_SetError ("Failed capturing display");
@@ -370,7 +409,7 @@
 
     /* Manually create a window, avoids having a nib file resource */
     window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect 
-        styleMask:style backing:NSBackingStoreRetained defer:NO ];
+        styleMask:style backing:NSBackingStoreBuffered defer:NO ];
     if (window == nil) {
         SDL_SetError ("Could not create the Cocoa window");
         return NULL;
@@ -431,7 +470,7 @@
 static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width, 
 				     int height, int bpp, Uint32 flags) {
 
-    if (SDL_VideoSurface != NULL)
+    if (video_set == SDL_TRUE)
         QZ_UnsetVideoMode (this);
        
     current->flags = 0;
@@ -469,7 +508,7 @@
                 SDL_SetError ("24bpp is not available");
                 return NULL;
             case 32:   /* (8)-8-8-8 ARGB */
-                amask = 0x00000000; /* These are the correct semantics */
+                amask = 0x00000000;
                 rmask = 0x00FF0000;
                 gmask = 0x0000FF00;
                 bmask = 0x000000FF;
@@ -486,6 +525,9 @@
     /* Warp mouse to origin in order to get passive mouse motion events started correctly */
     QZ_PrivateWarpCursor (this, current->flags & SDL_FULLSCREEN, height, 0, 0);
     
+    /* Signal successful completion */
+    video_set = SDL_TRUE;
+    
     return current;
 }