Mercurial > sdl-ios-xcode
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) { |