Date: Thu, 16 Aug 2001 21:50:51 -0500 (EST)
authorSam Lantinga
Sun, 19 Aug 2001 23:57:39 +0000
changeset 1552d162219f433
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
     1.1 --- a/src/video/maccommon/SDL_macevents.c	Sat Aug 18 22:24:19 2001 +0000
     1.2 +++ b/src/video/maccommon/SDL_macevents.c	Sun Aug 19 23:57:39 2001 +0000
     1.3 @@ -107,6 +107,7 @@
     1.4  /* The main MacOS event handler */
     1.5  static int Mac_HandleEvents(_THIS, int wait4it)
     1.6  {
     1.7 +	static int mouse_button = 1;
     1.8  	int i;
     1.9  	EventRecord event;
    1.10  
    1.11 @@ -148,7 +149,7 @@
    1.12  	/* for some reason, event.where isn't set ? */
    1.13  	GetGlobalMouse ( &event.where );
    1.14  #endif
    1.15 -    
    1.16 +
    1.17  	/* Check for mouse motion */
    1.18  	if ( (event.where.h != last_where.h) ||
    1.19  	     (event.where.v != last_where.v) ) {
    1.20 @@ -282,16 +283,14 @@
    1.21  			myGlobalToLocal(this, &event.where);
    1.22  			/* Treat command-click as right mouse button */
    1.23  			if ( event.modifiers & optionKey ) {
    1.24 -			    SDL_PrivateMouseButton(SDL_PRESSED,
    1.25 -					2,event.where.h,event.where.v);
    1.26 +				mouse_button = 2;
    1.27 +			} else if ( event.modifiers & cmdKey ) {
    1.28 +				mouse_button = 3;
    1.29 +			} else {
    1.30 +				mouse_button = 1;
    1.31  			}
    1.32 -			else if ( event.modifiers & cmdKey ) {
    1.33 -			    SDL_PrivateMouseButton(SDL_PRESSED,
    1.34 -					3,event.where.h,event.where.v);
    1.35 -			} else {
    1.36 -			    SDL_PrivateMouseButton(SDL_PRESSED,
    1.37 -					1,event.where.h,event.where.v);
    1.38 -			}
    1.39 +			SDL_PrivateMouseButton(SDL_PRESSED,
    1.40 +				mouse_button, event.where.h, event.where.v);
    1.41  			break;
    1.42  		  case inGrow: {
    1.43  			int newSize;
    1.44 @@ -336,7 +335,7 @@
    1.45  			if ( TrackBox (win, event.where, area )) {
    1.46  				if ( IsWindowCollapsable(win) ) {
    1.47  					CollapseWindow (win, !IsWindowCollapsed(win));
    1.48 -					// There should be something done like in inGrow case, but...
    1.49 +					/* There should be something done like in inGrow case, but... */
    1.50  				}
    1.51  			}
    1.52  			break;
    1.53 @@ -355,18 +354,14 @@
    1.54  	  break;
    1.55  	  case mouseUp: {
    1.56  		myGlobalToLocal(this, &event.where);
    1.57 -		/* Treat command-click as right mouse button */
    1.58 -		if ( event.modifiers & cmdKey ) {
    1.59 -		    SDL_PrivateMouseButton(SDL_RELEASED,
    1.60 -				3, event.where.h, event.where.v);
    1.61 -		}
    1.62 -		else if ( event.modifiers & optionKey ) {
    1.63 -		    SDL_PrivateMouseButton(SDL_RELEASED,
    1.64 -				2,event.where.h,event.where.v);
    1.65 -		} else {
    1.66 -		    SDL_PrivateMouseButton(SDL_RELEASED,
    1.67 -				1, event.where.h, event.where.v);
    1.68 -		}
    1.69 +		/* Release the mouse button we simulated in the last press.
    1.70 +		   The drawback of this methos is we cannot press more than
    1.71 +		   one button. However, this doesn't matter, since there is
    1.72 +		   only a single logical mouse button, even if you have a
    1.73 +		   multi-button mouse, this doesn't matter at all.
    1.74 +		 */
    1.75 +		SDL_PrivateMouseButton(SDL_RELEASED,
    1.76 +			mouse_button, event.where.h, event.where.v);
    1.77  	  }
    1.78  	  break;
    1.79  #if 0 /* Handled above the switch statement */
     2.1 --- a/src/video/quartz/SDL_QuartzEvents.m	Sat Aug 18 22:24:19 2001 +0000
     2.2 +++ b/src/video/quartz/SDL_QuartzEvents.m	Sun Aug 19 23:57:39 2001 +0000
     2.3 @@ -22,6 +22,8 @@
     2.4  
     2.5  #include "SDL_QuartzKeys.h"
     2.6  
     2.7 +static int last_virtual_button = 0; // Last virtual mouse button pressed
     2.8 +
     2.9  static void  QZ_InitOSKeymap (_THIS) {
    2.10  	int i;
    2.11  
    2.12 @@ -222,12 +224,16 @@
    2.13  
    2.14  static void QZ_PumpEvents (_THIS)
    2.15  { 
    2.16 -    NSDate *distantPast = [ NSDate distantPast ];
    2.17 -    
    2.18 +    NSDate *distantPast;
    2.19      NSEvent *event;
    2.20      NSRect winRect;
    2.21      NSRect titleBarRect;
    2.22 -            
    2.23 +    NSAutoreleasePool *pool;
    2.24 +    
    2.25 +    distantPast = [ [ NSDate distantPast ] retain ];
    2.26 +    
    2.27 +    pool = [ [ NSAutoreleasePool alloc ] init ];
    2.28 +    
    2.29      winRect = NSMakeRect (0, 0, SDL_VideoSurface->w + 1, SDL_VideoSurface->h + 1);
    2.30      titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
    2.31          SDL_VideoSurface->h + 22 );
    2.32 @@ -266,9 +272,11 @@
    2.33              
    2.34              case NSLeftMouseDown:  
    2.35                  if ( NSCommandKeyMask & currentMods ) {
    2.36 -                        DO_MOUSE_DOWN (3, 0);
    2.37 +                    last_virtual_button = 3;
    2.38 +                    DO_MOUSE_DOWN (3, 0);
    2.39                  } 
    2.40                  else if ( NSAlternateKeyMask & currentMods ) {
    2.41 +                    last_virtual_button = 2;
    2.42                      DO_MOUSE_DOWN (2, 0);
    2.43                  } 
    2.44                  else {
    2.45 @@ -278,14 +286,14 @@
    2.46              case 25:               DO_MOUSE_DOWN (2, 0); break;
    2.47              case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;   
    2.48              case NSLeftMouseUp:    
    2.49 -            if ( NSCommandKeyMask & currentMods ) {
    2.50 -                        DO_MOUSE_UP (3, 0);
    2.51 -                } 
    2.52 -                else if ( NSAlternateKeyMask & currentMods ) {
    2.53 -                    DO_MOUSE_UP (2, 0);
    2.54 -                } 
    2.55 -                else
    2.56 +            
    2.57 +                if ( last_virtual_button != 0 ) {
    2.58 +                    DO_MOUSE_UP (last_virtual_button, 0);
    2.59 +                    last_virtual_button = 0;
    2.60 +                }
    2.61 +                else {
    2.62                      DO_MOUSE_UP (1, 1);
    2.63 +                }
    2.64                  break;
    2.65              case 26:               DO_MOUSE_UP (2, 0);   break;
    2.66              case NSRightMouseUp:   DO_MOUSE_UP (3, 0);   break;
    2.67 @@ -364,5 +372,8 @@
    2.68              }
    2.69          }
    2.70        } while (event != nil);
    2.71 +      
    2.72 +      [ pool release ];
    2.73 +      [ distantPast release ];
    2.74  }
    2.75  
     3.1 --- a/src/video/quartz/SDL_QuartzVideo.h	Sat Aug 18 22:24:19 2001 +0000
     3.2 +++ b/src/video/quartz/SDL_QuartzVideo.h	Sun Aug 19 23:57:39 2001 +0000
     3.3 @@ -83,8 +83,9 @@
     3.4      CFArrayRef         mode_list;
     3.5      CGDirectPaletteRef palette;
     3.6      NSOpenGLContext    *gl_context;
     3.7 -    int                width, height, bpp;
     3.8 +    Uint32             width, height, bpp;
     3.9      Uint32             flags;
    3.10 +    SDL_bool           video_is_set; /* tell if the video mode was set */
    3.11      
    3.12      /* Window-only fields */
    3.13      NSWindow        *window;
    3.14 @@ -105,6 +106,7 @@
    3.15  #define device_height (this->hidden->height)
    3.16  #define device_bpp (this->hidden->bpp)
    3.17  #define mode_flags (this->hidden->flags)
    3.18 +#define video_set (this->hidden->video_is_set)
    3.19  #define window (this->hidden->window)
    3.20  #define windowView (this->hidden->view)
    3.21  
     4.1 --- a/src/video/quartz/SDL_QuartzVideo.m	Sat Aug 18 22:24:19 2001 +0000
     4.2 +++ b/src/video/quartz/SDL_QuartzVideo.m	Sun Aug 19 23:57:39 2001 +0000
     4.3 @@ -27,14 +27,13 @@
     4.4  static BOOL   inForeground = YES;
     4.5  static SDLKey keymap[256];
     4.6  static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
     4.7 +static char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */
     4.8  
     4.9  /* Include files into one compile unit...break apart eventually */
    4.10  #include "SDL_QuartzWM.m"
    4.11  #include "SDL_QuartzEvents.m"
    4.12  #include "SDL_QuartzWindow.m"
    4.13  
    4.14 -char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */
    4.15 -
    4.16  /* Bootstrap binding, enables entry point into the driver */
    4.17  VideoBootStrap QZ_bootstrap = {
    4.18      "Quartz", "MacOS X CoreGraphics", QZ_Available, QZ_CreateDevice
    4.19 @@ -143,7 +142,7 @@
    4.20  
    4.21      static SDL_Rect **list = NULL;
    4.22      int list_size = 0;
    4.23 -
    4.24 +    
    4.25      /* Any windowed mode is acceptable */
    4.26      if ( (flags & SDL_FULLSCREEN) == 0 )
    4.27          return (SDL_Rect**)-1;
    4.28 @@ -151,7 +150,7 @@
    4.29      /* Free memory from previous call, if any */
    4.30      if ( list != NULL ) {
    4.31  
    4.32 -      int i = 0;
    4.33 +      int i;
    4.34  
    4.35        for (i = 0; list[i] != NULL; i++)
    4.36  	free (list[i]);
    4.37 @@ -159,23 +158,24 @@
    4.38        free (list);
    4.39        list = NULL;
    4.40      }
    4.41 -
    4.42 +    
    4.43      /* Build list of modes with the requested bpp */
    4.44 -    for (i = num_modes-1; i >= 0; i--) {
    4.45 +    for (i = 0; i < num_modes; i++) {
    4.46     
    4.47 -        CFDictionaryRef onemode = CFArrayGetValueAtIndex (mode_list, i);
    4.48 -	CFNumberRef     number;
    4.49 +        CFDictionaryRef onemode;
    4.50 +        CFNumberRef     number;
    4.51  	int bpp;
    4.52  	
    4.53 +        onemode = CFArrayGetValueAtIndex (mode_list, i); 
    4.54  	number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel);
    4.55  	CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);
    4.56  
    4.57  	if (bpp == format->BitsPerPixel) {
    4.58  	  
    4.59 -	  int       intvalue;
    4.60 -	  SDL_Rect *rect;
    4.61 -          int       lastwidth = 0, lastheight = 0, width, height;
    4.62 -
    4.63 +	  int intvalue;
    4.64 +          int hasMode;
    4.65 +          int width, height;
    4.66 +          
    4.67  	  number = CFDictionaryGetValue (onemode, kCGDisplayWidth);
    4.68  	  CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
    4.69  	  width = (Uint16) intvalue;
    4.70 @@ -184,12 +184,23 @@
    4.71  	  CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
    4.72  	  height = (Uint16) intvalue;
    4.73            
    4.74 -          /* We'll get a lot of modes with the same size, so ignore them */
    4.75 -          if ( width != lastwidth && height != lastheight ) {
    4.76 -
    4.77 -            lastwidth  = width;
    4.78 -            lastheight = height;
    4.79 +          /* Check if mode is already in the list */
    4.80 +          {
    4.81 +            int i;
    4.82 +            hasMode = SDL_FALSE;
    4.83 +            for (i = 0; i < list_size; i++) {
    4.84 +                if (list[i]->w == width && list[i]->h == height) {
    4.85 +                    hasMode = SDL_TRUE;
    4.86 +                    break;
    4.87 +                }
    4.88 +            }
    4.89 +          }
    4.90 +          
    4.91 +          /* Grow the list and add mode to the list */
    4.92 +          if ( ! hasMode ) {
    4.93  	  
    4.94 +            SDL_Rect *rect;
    4.95 +            
    4.96              list_size++;
    4.97  
    4.98              if ( list == NULL)
    4.99 @@ -211,14 +222,29 @@
   4.100        }
   4.101      }
   4.102      
   4.103 +    /* Sort list largest to smallest (by area) */
   4.104 +    {
   4.105 +        int i, j;
   4.106 +        for (i = 0; i < list_size; i++) {
   4.107 +            for (j = 0; j < list_size-1; j++) {
   4.108 +            
   4.109 +                int area1, area2;
   4.110 +                area1 = list[j]->w * list[j]->h;
   4.111 +                area2 = list[j+1]->w * list[j+1]->h;
   4.112 +                
   4.113 +                if (area1 < area2) {
   4.114 +                    SDL_Rect *tmp = list[j];
   4.115 +                    list[j] = list[j+1];
   4.116 +                    list[j+1] = tmp;
   4.117 +                }
   4.118 +            }
   4.119 +        }
   4.120 +    }
   4.121      return list;
   4.122  }
   4.123  
   4.124  static void QZ_UnsetVideoMode (_THIS) {
   4.125  
   4.126 -    if ( mode_flags & SDL_OPENGL )
   4.127 -        QZ_TearDownOpenGL (this);
   4.128 -
   4.129      /* Reset values that may change between switches */
   4.130      this->info.blit_fill = 0;
   4.131      this->FillHWRect     = NULL;
   4.132 @@ -229,9 +255,11 @@
   4.133     
   4.134      /* Restore original screen resolution */
   4.135      if ( mode_flags & SDL_FULLSCREEN ) {
   4.136 +        if (mode_flags & SDL_OPENGL)
   4.137 +            CGLSetFullScreen(NULL);
   4.138 +            
   4.139          CGDisplaySwitchToMode (display_id, save_mode);
   4.140          CGDisplayRelease (display_id);
   4.141 -        this->screen->pixels = NULL;
   4.142      }
   4.143      /* Release window mode data structures */
   4.144      else { 
   4.145 @@ -240,13 +268,24 @@
   4.146              [ windowView release  ];
   4.147          }
   4.148          [ window setContentView:nil ];
   4.149 +        [ window setDelegate:nil ];
   4.150          [ window close ];
   4.151 -        [ window release ];
   4.152      }
   4.153      
   4.154 +    /* Set pixels to null (so other code doesn't try to free it) */
   4.155 +    if (this->screen != NULL)
   4.156 +        this->screen->pixels = NULL;
   4.157 +        
   4.158 +    /* Release the OpenGL context */
   4.159 +    if ( mode_flags & SDL_OPENGL )
   4.160 +        QZ_TearDownOpenGL (this);
   4.161 +        
   4.162      /* Ensure the cursor will be visible and working when we quit */
   4.163      CGDisplayShowCursor (display_id);
   4.164      CGAssociateMouseAndMouseCursorPosition (1);
   4.165 +    
   4.166 +    /* Signal successful teardown */
   4.167 +    video_set = SDL_FALSE;
   4.168  }
   4.169  
   4.170  static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
   4.171 @@ -263,7 +302,7 @@
   4.172          SDL_SetError (QZ_Error);
   4.173          goto ERR_NO_MATCH;
   4.174      }
   4.175 -    
   4.176 +
   4.177      /* Put up the blanking window (a window above all other windows) */
   4.178      if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) {
   4.179          SDL_SetError ("Failed capturing display");
   4.180 @@ -370,7 +409,7 @@
   4.181  
   4.182      /* Manually create a window, avoids having a nib file resource */
   4.183      window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect 
   4.184 -        styleMask:style backing:NSBackingStoreRetained defer:NO ];
   4.185 +        styleMask:style backing:NSBackingStoreBuffered defer:NO ];
   4.186      if (window == nil) {
   4.187          SDL_SetError ("Could not create the Cocoa window");
   4.188          return NULL;
   4.189 @@ -431,7 +470,7 @@
   4.190  static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width, 
   4.191  				     int height, int bpp, Uint32 flags) {
   4.192  
   4.193 -    if (SDL_VideoSurface != NULL)
   4.194 +    if (video_set == SDL_TRUE)
   4.195          QZ_UnsetVideoMode (this);
   4.196         
   4.197      current->flags = 0;
   4.198 @@ -469,7 +508,7 @@
   4.199                  SDL_SetError ("24bpp is not available");
   4.200                  return NULL;
   4.201              case 32:   /* (8)-8-8-8 ARGB */
   4.202 -                amask = 0x00000000; /* These are the correct semantics */
   4.203 +                amask = 0x00000000;
   4.204                  rmask = 0x00FF0000;
   4.205                  gmask = 0x0000FF00;
   4.206                  bmask = 0x000000FF;
   4.207 @@ -486,6 +525,9 @@
   4.208      /* Warp mouse to origin in order to get passive mouse motion events started correctly */
   4.209      QZ_PrivateWarpCursor (this, current->flags & SDL_FULLSCREEN, height, 0, 0);
   4.210      
   4.211 +    /* Signal successful completion */
   4.212 +    video_set = SDL_TRUE;
   4.213 +    
   4.214      return current;
   4.215  }
   4.216