comparison src/video/quartz/SDL_QuartzVideo.m @ 155:2d162219f433

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
author Sam Lantinga <slouken@libsdl.org>
date Sun, 19 Aug 2001 23:57:39 +0000
parents aac75d5f7869
children 4382c38dfbee
comparison
equal deleted inserted replaced
154:50d2b5305c2c 155:2d162219f433
25 /* Some variables to share among files, put in device structure eventually */ 25 /* Some variables to share among files, put in device structure eventually */
26 static SDL_GrabMode currentGrabMode = SDL_GRAB_OFF; 26 static SDL_GrabMode currentGrabMode = SDL_GRAB_OFF;
27 static BOOL inForeground = YES; 27 static BOOL inForeground = YES;
28 static SDLKey keymap[256]; 28 static SDLKey keymap[256];
29 static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */ 29 static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
30 static char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */
30 31
31 /* Include files into one compile unit...break apart eventually */ 32 /* Include files into one compile unit...break apart eventually */
32 #include "SDL_QuartzWM.m" 33 #include "SDL_QuartzWM.m"
33 #include "SDL_QuartzEvents.m" 34 #include "SDL_QuartzEvents.m"
34 #include "SDL_QuartzWindow.m" 35 #include "SDL_QuartzWindow.m"
35
36 char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */
37 36
38 /* Bootstrap binding, enables entry point into the driver */ 37 /* Bootstrap binding, enables entry point into the driver */
39 VideoBootStrap QZ_bootstrap = { 38 VideoBootStrap QZ_bootstrap = {
40 "Quartz", "MacOS X CoreGraphics", QZ_Available, QZ_CreateDevice 39 "Quartz", "MacOS X CoreGraphics", QZ_Available, QZ_CreateDevice
41 }; 40 };
141 CFIndex num_modes = CFArrayGetCount (mode_list); 140 CFIndex num_modes = CFArrayGetCount (mode_list);
142 CFIndex i; 141 CFIndex i;
143 142
144 static SDL_Rect **list = NULL; 143 static SDL_Rect **list = NULL;
145 int list_size = 0; 144 int list_size = 0;
146 145
147 /* Any windowed mode is acceptable */ 146 /* Any windowed mode is acceptable */
148 if ( (flags & SDL_FULLSCREEN) == 0 ) 147 if ( (flags & SDL_FULLSCREEN) == 0 )
149 return (SDL_Rect**)-1; 148 return (SDL_Rect**)-1;
150 149
151 /* Free memory from previous call, if any */ 150 /* Free memory from previous call, if any */
152 if ( list != NULL ) { 151 if ( list != NULL ) {
153 152
154 int i = 0; 153 int i;
155 154
156 for (i = 0; list[i] != NULL; i++) 155 for (i = 0; list[i] != NULL; i++)
157 free (list[i]); 156 free (list[i]);
158 157
159 free (list); 158 free (list);
160 list = NULL; 159 list = NULL;
161 } 160 }
162 161
163 /* Build list of modes with the requested bpp */ 162 /* Build list of modes with the requested bpp */
164 for (i = num_modes-1; i >= 0; i--) { 163 for (i = 0; i < num_modes; i++) {
165 164
166 CFDictionaryRef onemode = CFArrayGetValueAtIndex (mode_list, i); 165 CFDictionaryRef onemode;
167 CFNumberRef number; 166 CFNumberRef number;
168 int bpp; 167 int bpp;
169 168
169 onemode = CFArrayGetValueAtIndex (mode_list, i);
170 number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel); 170 number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel);
171 CFNumberGetValue (number, kCFNumberSInt32Type, &bpp); 171 CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);
172 172
173 if (bpp == format->BitsPerPixel) { 173 if (bpp == format->BitsPerPixel) {
174 174
175 int intvalue; 175 int intvalue;
176 SDL_Rect *rect; 176 int hasMode;
177 int lastwidth = 0, lastheight = 0, width, height; 177 int width, height;
178 178
179 number = CFDictionaryGetValue (onemode, kCGDisplayWidth); 179 number = CFDictionaryGetValue (onemode, kCGDisplayWidth);
180 CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue); 180 CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
181 width = (Uint16) intvalue; 181 width = (Uint16) intvalue;
182 182
183 number = CFDictionaryGetValue (onemode, kCGDisplayHeight); 183 number = CFDictionaryGetValue (onemode, kCGDisplayHeight);
184 CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue); 184 CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
185 height = (Uint16) intvalue; 185 height = (Uint16) intvalue;
186 186
187 /* We'll get a lot of modes with the same size, so ignore them */ 187 /* Check if mode is already in the list */
188 if ( width != lastwidth && height != lastheight ) { 188 {
189 189 int i;
190 lastwidth = width; 190 hasMode = SDL_FALSE;
191 lastheight = height; 191 for (i = 0; i < list_size; i++) {
192 if (list[i]->w == width && list[i]->h == height) {
193 hasMode = SDL_TRUE;
194 break;
195 }
196 }
197 }
198
199 /* Grow the list and add mode to the list */
200 if ( ! hasMode ) {
192 201
202 SDL_Rect *rect;
203
193 list_size++; 204 list_size++;
194 205
195 if ( list == NULL) 206 if ( list == NULL)
196 list = (SDL_Rect**) malloc (sizeof(*list) * list_size+1); 207 list = (SDL_Rect**) malloc (sizeof(*list) * list_size+1);
197 else 208 else
209 list[list_size] = NULL; 220 list[list_size] = NULL;
210 } 221 }
211 } 222 }
212 } 223 }
213 224
225 /* Sort list largest to smallest (by area) */
226 {
227 int i, j;
228 for (i = 0; i < list_size; i++) {
229 for (j = 0; j < list_size-1; j++) {
230
231 int area1, area2;
232 area1 = list[j]->w * list[j]->h;
233 area2 = list[j+1]->w * list[j+1]->h;
234
235 if (area1 < area2) {
236 SDL_Rect *tmp = list[j];
237 list[j] = list[j+1];
238 list[j+1] = tmp;
239 }
240 }
241 }
242 }
214 return list; 243 return list;
215 } 244 }
216 245
217 static void QZ_UnsetVideoMode (_THIS) { 246 static void QZ_UnsetVideoMode (_THIS) {
218
219 if ( mode_flags & SDL_OPENGL )
220 QZ_TearDownOpenGL (this);
221 247
222 /* Reset values that may change between switches */ 248 /* Reset values that may change between switches */
223 this->info.blit_fill = 0; 249 this->info.blit_fill = 0;
224 this->FillHWRect = NULL; 250 this->FillHWRect = NULL;
225 this->UpdateRects = NULL; 251 this->UpdateRects = NULL;
227 /* Restore gamma settings */ 253 /* Restore gamma settings */
228 CGDisplayRestoreColorSyncSettings (); 254 CGDisplayRestoreColorSyncSettings ();
229 255
230 /* Restore original screen resolution */ 256 /* Restore original screen resolution */
231 if ( mode_flags & SDL_FULLSCREEN ) { 257 if ( mode_flags & SDL_FULLSCREEN ) {
258 if (mode_flags & SDL_OPENGL)
259 CGLSetFullScreen(NULL);
260
232 CGDisplaySwitchToMode (display_id, save_mode); 261 CGDisplaySwitchToMode (display_id, save_mode);
233 CGDisplayRelease (display_id); 262 CGDisplayRelease (display_id);
234 this->screen->pixels = NULL;
235 } 263 }
236 /* Release window mode data structures */ 264 /* Release window mode data structures */
237 else { 265 else {
238 if ( (mode_flags & SDL_OPENGL) == 0 ) { 266 if ( (mode_flags & SDL_OPENGL) == 0 ) {
239 UnlockPortBits ( [ windowView qdPort ] ); 267 UnlockPortBits ( [ windowView qdPort ] );
240 [ windowView release ]; 268 [ windowView release ];
241 } 269 }
242 [ window setContentView:nil ]; 270 [ window setContentView:nil ];
271 [ window setDelegate:nil ];
243 [ window close ]; 272 [ window close ];
244 [ window release ]; 273 }
245 } 274
246 275 /* Set pixels to null (so other code doesn't try to free it) */
276 if (this->screen != NULL)
277 this->screen->pixels = NULL;
278
279 /* Release the OpenGL context */
280 if ( mode_flags & SDL_OPENGL )
281 QZ_TearDownOpenGL (this);
282
247 /* Ensure the cursor will be visible and working when we quit */ 283 /* Ensure the cursor will be visible and working when we quit */
248 CGDisplayShowCursor (display_id); 284 CGDisplayShowCursor (display_id);
249 CGAssociateMouseAndMouseCursorPosition (1); 285 CGAssociateMouseAndMouseCursorPosition (1);
286
287 /* Signal successful teardown */
288 video_set = SDL_FALSE;
250 } 289 }
251 290
252 static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width, 291 static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
253 int height, int bpp, Uint32 flags) { 292 int height, int bpp, Uint32 flags) {
254 int exact_match; 293 int exact_match;
261 if ( ! exact_match ) { 300 if ( ! exact_match ) {
262 sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp); 301 sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp);
263 SDL_SetError (QZ_Error); 302 SDL_SetError (QZ_Error);
264 goto ERR_NO_MATCH; 303 goto ERR_NO_MATCH;
265 } 304 }
266 305
267 /* Put up the blanking window (a window above all other windows) */ 306 /* Put up the blanking window (a window above all other windows) */
268 if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) { 307 if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) {
269 SDL_SetError ("Failed capturing display"); 308 SDL_SetError ("Failed capturing display");
270 goto ERR_NO_CAPTURE; 309 goto ERR_NO_CAPTURE;
271 } 310 }
368 style |= NSResizableWindowMask; 407 style |= NSResizableWindowMask;
369 } 408 }
370 409
371 /* Manually create a window, avoids having a nib file resource */ 410 /* Manually create a window, avoids having a nib file resource */
372 window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect 411 window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect
373 styleMask:style backing:NSBackingStoreRetained defer:NO ]; 412 styleMask:style backing:NSBackingStoreBuffered defer:NO ];
374 if (window == nil) { 413 if (window == nil) {
375 SDL_SetError ("Could not create the Cocoa window"); 414 SDL_SetError ("Could not create the Cocoa window");
376 return NULL; 415 return NULL;
377 } 416 }
378 417
429 } 468 }
430 469
431 static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width, 470 static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
432 int height, int bpp, Uint32 flags) { 471 int height, int bpp, Uint32 flags) {
433 472
434 if (SDL_VideoSurface != NULL) 473 if (video_set == SDL_TRUE)
435 QZ_UnsetVideoMode (this); 474 QZ_UnsetVideoMode (this);
436 475
437 current->flags = 0; 476 current->flags = 0;
438 477
439 /* Setup full screen video */ 478 /* Setup full screen video */
467 break; 506 break;
468 case 24: 507 case 24:
469 SDL_SetError ("24bpp is not available"); 508 SDL_SetError ("24bpp is not available");
470 return NULL; 509 return NULL;
471 case 32: /* (8)-8-8-8 ARGB */ 510 case 32: /* (8)-8-8-8 ARGB */
472 amask = 0x00000000; /* These are the correct semantics */ 511 amask = 0x00000000;
473 rmask = 0x00FF0000; 512 rmask = 0x00FF0000;
474 gmask = 0x0000FF00; 513 gmask = 0x0000FF00;
475 bmask = 0x000000FF; 514 bmask = 0x000000FF;
476 break; 515 break;
477 } 516 }
483 } 522 }
484 } 523 }
485 524
486 /* Warp mouse to origin in order to get passive mouse motion events started correctly */ 525 /* Warp mouse to origin in order to get passive mouse motion events started correctly */
487 QZ_PrivateWarpCursor (this, current->flags & SDL_FULLSCREEN, height, 0, 0); 526 QZ_PrivateWarpCursor (this, current->flags & SDL_FULLSCREEN, height, 0, 0);
527
528 /* Signal successful completion */
529 video_set = SDL_TRUE;
488 530
489 return current; 531 return current;
490 } 532 }
491 533
492 static int QZ_ToggleFullScreen (_THIS, int on) { 534 static int QZ_ToggleFullScreen (_THIS, int on) {