Mercurial > sdl-ios-xcode
comparison src/video/quartz/SDL_QuartzVideo.m @ 272:d1447a846d80
Date: Sat, 19 Jan 2002 17:24:32 -0500 (EST)
From: Darrell Walisser <dwaliss1@purdue.edu>
Subject: SDL Quartz video update
-better mouse motion events
-fixed minification bugs (except OpenGL)
-fixed QZ_SetGamma for correct semantics
-fade/unfade display before/after rez switch
-experimental obscured-check/blind-copy code
The obscured code, while it speeds up window drawing substantially, isn't
ready yet. The reason is that there doesn't (yet) seem to be a way to know
when the window is dragged or when the window suddenly comes to the
foreground. Since Carbon windows seem to allow detection of such things, I
suspect it is possible through some window server API. Cocoa(NSWindow) has no
functions for such things, AFAIK.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 22 Jan 2002 18:46:28 +0000 |
parents | e8157fcb3114 |
children | f6ffac90895c |
comparison
equal
deleted
inserted
replaced
271:9631db4d9ee1 | 272:d1447a846d80 |
---|---|
30 /* Include files into one compile unit...break apart eventually */ | 30 /* Include files into one compile unit...break apart eventually */ |
31 #include "SDL_QuartzWM.m" | 31 #include "SDL_QuartzWM.m" |
32 #include "SDL_QuartzEvents.m" | 32 #include "SDL_QuartzEvents.m" |
33 #include "SDL_QuartzWindow.m" | 33 #include "SDL_QuartzWindow.m" |
34 | 34 |
35 | |
35 /* Bootstrap binding, enables entry point into the driver */ | 36 /* Bootstrap binding, enables entry point into the driver */ |
36 VideoBootStrap QZ_bootstrap = { | 37 VideoBootStrap QZ_bootstrap = { |
37 "Quartz", "MacOS X CoreGraphics", QZ_Available, QZ_CreateDevice | 38 "Quartz", "Mac OS X CoreGraphics", QZ_Available, QZ_CreateDevice |
38 }; | 39 }; |
39 | 40 |
40 /* Bootstrap functions */ | 41 /* Bootstrap functions */ |
41 static int QZ_Available () { | 42 static int QZ_Available () { |
42 return 1; | 43 return 1; |
43 } | 44 } |
44 | 45 |
45 static SDL_VideoDevice* QZ_CreateDevice (int device_index) { | 46 static SDL_VideoDevice* QZ_CreateDevice (int device_index) { |
46 | 47 |
47 #pragma unused (device_index) | 48 #pragma unused (device_index) |
48 | 49 |
49 SDL_VideoDevice *device; | 50 SDL_VideoDevice *device; |
50 SDL_PrivateVideoData *hidden; | 51 SDL_PrivateVideoData *hidden; |
51 | 52 |
52 device = (SDL_VideoDevice*) malloc (sizeof (*device) ); | 53 device = (SDL_VideoDevice*) malloc (sizeof (*device) ); |
55 if (device == NULL || hidden == NULL) | 56 if (device == NULL || hidden == NULL) |
56 SDL_OutOfMemory (); | 57 SDL_OutOfMemory (); |
57 | 58 |
58 memset (device, 0, sizeof (*device) ); | 59 memset (device, 0, sizeof (*device) ); |
59 memset (hidden, 0, sizeof (*hidden) ); | 60 memset (hidden, 0, sizeof (*hidden) ); |
60 | 61 |
61 device->hidden = hidden; | 62 device->hidden = hidden; |
62 | 63 |
63 device->VideoInit = QZ_VideoInit; | 64 device->VideoInit = QZ_VideoInit; |
64 device->ListModes = QZ_ListModes; | 65 device->ListModes = QZ_ListModes; |
65 device->SetVideoMode = QZ_SetVideoMode; | 66 device->SetVideoMode = QZ_SetVideoMode; |
66 device->ToggleFullScreen = QZ_ToggleFullScreen; | 67 device->ToggleFullScreen = QZ_ToggleFullScreen; |
67 device->SetColors = QZ_SetColors; | 68 device->SetColors = QZ_SetColors; |
68 /* device->UpdateRects = QZ_UpdateRects; this is determined by SetVideoMode() */ | 69 /* device->UpdateRects = QZ_UpdateRects; this is determined by SetVideoMode() */ |
69 device->VideoQuit = QZ_VideoQuit; | 70 device->VideoQuit = QZ_VideoQuit; |
70 | 71 |
71 device->LockHWSurface = QZ_LockHWSurface; | 72 device->LockHWSurface = QZ_LockHWSurface; |
72 device->UnlockHWSurface = QZ_UnlockHWSurface; | 73 device->UnlockHWSurface = QZ_UnlockHWSurface; |
73 device->FreeHWSurface = QZ_FreeHWSurface; | 74 device->FreeHWSurface = QZ_FreeHWSurface; |
74 /* device->FlipHWSurface = QZ_FlipHWSurface */; | 75 /* device->FlipHWSurface = QZ_FlipHWSurface */; |
75 | 76 |
81 device->GL_GetProcAddress = QZ_GL_GetProcAddress; | 82 device->GL_GetProcAddress = QZ_GL_GetProcAddress; |
82 device->GL_GetAttribute = QZ_GL_GetAttribute; | 83 device->GL_GetAttribute = QZ_GL_GetAttribute; |
83 device->GL_MakeCurrent = QZ_GL_MakeCurrent; | 84 device->GL_MakeCurrent = QZ_GL_MakeCurrent; |
84 device->GL_SwapBuffers = QZ_GL_SwapBuffers; | 85 device->GL_SwapBuffers = QZ_GL_SwapBuffers; |
85 device->GL_LoadLibrary = QZ_GL_LoadLibrary; | 86 device->GL_LoadLibrary = QZ_GL_LoadLibrary; |
86 | 87 |
87 device->FreeWMCursor = QZ_FreeWMCursor; | 88 device->FreeWMCursor = QZ_FreeWMCursor; |
88 device->CreateWMCursor = QZ_CreateWMCursor; | 89 device->CreateWMCursor = QZ_CreateWMCursor; |
89 device->ShowWMCursor = QZ_ShowWMCursor; | 90 device->ShowWMCursor = QZ_ShowWMCursor; |
90 device->WarpWMCursor = QZ_WarpWMCursor; | 91 device->WarpWMCursor = QZ_WarpWMCursor; |
91 device->MoveWMCursor = QZ_MoveWMCursor; | 92 device->MoveWMCursor = QZ_MoveWMCursor; |
96 device->SetCaption = QZ_SetCaption; | 97 device->SetCaption = QZ_SetCaption; |
97 device->SetIcon = QZ_SetIcon; | 98 device->SetIcon = QZ_SetIcon; |
98 device->IconifyWindow = QZ_IconifyWindow; | 99 device->IconifyWindow = QZ_IconifyWindow; |
99 /*device->GetWMInfo = QZ_GetWMInfo;*/ | 100 /*device->GetWMInfo = QZ_GetWMInfo;*/ |
100 device->GrabInput = QZ_GrabInput; | 101 device->GrabInput = QZ_GrabInput; |
101 | 102 |
102 device->free = QZ_DeleteDevice; | 103 device->free = QZ_DeleteDevice; |
103 | 104 |
104 return device; | 105 return device; |
105 } | 106 } |
106 | 107 |
107 static void QZ_DeleteDevice (SDL_VideoDevice *device) { | 108 static void QZ_DeleteDevice (SDL_VideoDevice *device) { |
108 | 109 |
110 free (device); | 111 free (device); |
111 } | 112 } |
112 | 113 |
113 static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) { | 114 static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) { |
114 | 115 |
115 /* Initialize the video settings; this data persists between mode switches */ | 116 /* Initialize the video settings; this data persists between mode switches */ |
116 display_id = kCGDirectMainDisplay; | 117 display_id = kCGDirectMainDisplay; |
117 save_mode = CGDisplayCurrentMode (display_id); | 118 save_mode = CGDisplayCurrentMode (display_id); |
118 mode_list = CGDisplayAvailableModes (display_id); | 119 mode_list = CGDisplayAvailableModes (display_id); |
119 palette = CGPaletteCreateDefaultColorPalette (); | 120 palette = CGPaletteCreateDefaultColorPalette (); |
120 | 121 |
121 /* Gather some information that is useful to know about the display */ | 122 /* Gather some information that is useful to know about the display */ |
122 CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayBitsPerPixel), | 123 CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayBitsPerPixel), |
123 kCFNumberSInt32Type, &device_bpp); | 124 kCFNumberSInt32Type, &device_bpp); |
124 | 125 |
125 CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayWidth), | 126 CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayWidth), |
126 kCFNumberSInt32Type, &device_width); | 127 kCFNumberSInt32Type, &device_width); |
127 | 128 |
128 CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayHeight), | 129 CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayHeight), |
129 kCFNumberSInt32Type, &device_height); | 130 kCFNumberSInt32Type, &device_height); |
130 | 131 |
131 video_format->BitsPerPixel = device_bpp; | 132 video_format->BitsPerPixel = device_bpp; |
132 | 133 |
133 return 0; | 134 return 0; |
134 } | 135 } |
135 | 136 |
136 static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { | 137 static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { |
137 | 138 |
138 CFIndex num_modes = CFArrayGetCount (mode_list); | 139 CFIndex num_modes; |
139 CFIndex i; | 140 CFIndex i; |
140 | 141 |
141 static SDL_Rect **list = NULL; | 142 static SDL_Rect **list = NULL; |
142 int list_size = 0; | 143 int list_size = 0; |
143 | 144 |
155 | 156 |
156 free (list); | 157 free (list); |
157 list = NULL; | 158 list = NULL; |
158 } | 159 } |
159 | 160 |
161 num_modes = CFArrayGetCount (mode_list); | |
162 | |
160 /* Build list of modes with the requested bpp */ | 163 /* Build list of modes with the requested bpp */ |
161 for (i = 0; i < num_modes; i++) { | 164 for (i = 0; i < num_modes; i++) { |
162 | 165 |
163 CFDictionaryRef onemode; | 166 CFDictionaryRef onemode; |
164 CFNumberRef number; | 167 CFNumberRef number; |
199 | 202 |
200 SDL_Rect *rect; | 203 SDL_Rect *rect; |
201 | 204 |
202 list_size++; | 205 list_size++; |
203 | 206 |
204 if ( list == NULL) | 207 if (list == NULL) |
205 list = (SDL_Rect**) malloc (sizeof(*list) * list_size+1); | 208 list = (SDL_Rect**) malloc (sizeof(*list) * (list_size+1) ); |
206 else | 209 else |
207 list = (SDL_Rect**) realloc (list, sizeof(*list) * list_size+1); | 210 list = (SDL_Rect**) realloc (list, sizeof(*list) * (list_size+1)); |
208 | 211 |
209 rect = (SDL_Rect*) malloc (sizeof(**list)); | 212 rect = (SDL_Rect*) malloc (sizeof(**list)); |
210 | 213 |
211 if (list == NULL || rect == NULL) | 214 if (list == NULL || rect == NULL) { |
212 SDL_OutOfMemory (); | 215 SDL_OutOfMemory (); |
213 | 216 return NULL; |
217 } | |
218 | |
214 rect->w = width; | 219 rect->w = width; |
215 rect->h = height; | 220 rect->h = height; |
216 | 221 |
217 list[list_size-1] = rect; | 222 list[list_size-1] = rect; |
218 list[list_size] = NULL; | 223 list[list_size] = NULL; |
239 } | 244 } |
240 } | 245 } |
241 return list; | 246 return list; |
242 } | 247 } |
243 | 248 |
249 /* Gamma functions to try to hide the flash from a rez switch */ | |
250 /* Fade the display from normal to black */ | |
251 /* Save gamma tables for fade back to normal */ | |
252 static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) { | |
253 | |
254 CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE], | |
255 greenTable[QZ_GAMMA_TABLE_SIZE], | |
256 blueTable[QZ_GAMMA_TABLE_SIZE]; | |
257 | |
258 float percent; | |
259 int j; | |
260 int actual; | |
261 | |
262 if ( (CGDisplayNoErr != CGGetDisplayTransferByTable | |
263 (display_id, QZ_GAMMA_TABLE_SIZE, | |
264 table->red, table->green, table->blue, &actual)) || | |
265 actual != QZ_GAMMA_TABLE_SIZE) { | |
266 | |
267 return 1; | |
268 } | |
269 | |
270 memcpy (redTable, table->red, sizeof(redTable)); | |
271 memcpy (greenTable, table->green, sizeof(greenTable)); | |
272 memcpy (blueTable, table->blue, sizeof(greenTable)); | |
273 | |
274 for (percent = 1.0; percent >= 0.0; percent -= 0.01) { | |
275 | |
276 for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) { | |
277 | |
278 redTable[j] = redTable[j] * percent; | |
279 greenTable[j] = greenTable[j] * percent; | |
280 blueTable[j] = blueTable[j] * percent; | |
281 } | |
282 | |
283 if (CGDisplayNoErr != CGSetDisplayTransferByTable | |
284 (display_id, QZ_GAMMA_TABLE_SIZE, | |
285 redTable, greenTable, blueTable)) { | |
286 | |
287 CGDisplayRestoreColorSyncSettings(); | |
288 return 1; | |
289 } | |
290 | |
291 SDL_Delay (10); | |
292 } | |
293 | |
294 return 0; | |
295 } | |
296 | |
297 /* Fade the display from black to normal */ | |
298 /* Restore previously saved gamma values */ | |
299 static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) { | |
300 | |
301 CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE], | |
302 greenTable[QZ_GAMMA_TABLE_SIZE], | |
303 blueTable[QZ_GAMMA_TABLE_SIZE]; | |
304 | |
305 float percent; | |
306 int j; | |
307 | |
308 memset (redTable, 0, sizeof(redTable)); | |
309 memset (greenTable, 0, sizeof(greenTable)); | |
310 memset (blueTable, 0, sizeof(greenTable)); | |
311 | |
312 for (percent = 0.0; percent <= 1.0; percent += 0.01) { | |
313 | |
314 for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) { | |
315 | |
316 redTable[j] = table->red[j] * percent; | |
317 greenTable[j] = table->green[j] * percent; | |
318 blueTable[j] = table->blue[j] * percent; | |
319 } | |
320 | |
321 if (CGDisplayNoErr != CGSetDisplayTransferByTable | |
322 (display_id, QZ_GAMMA_TABLE_SIZE, | |
323 redTable, greenTable, blueTable)) { | |
324 | |
325 CGDisplayRestoreColorSyncSettings(); | |
326 return 1; | |
327 } | |
328 | |
329 SDL_Delay (10); | |
330 } | |
331 | |
332 return 0; | |
333 } | |
334 | |
244 static void QZ_UnsetVideoMode (_THIS) { | 335 static void QZ_UnsetVideoMode (_THIS) { |
245 | 336 |
246 /* Reset values that may change between switches */ | 337 /* Reset values that may change between switches */ |
247 this->info.blit_fill = 0; | 338 this->info.blit_fill = 0; |
248 this->FillHWRect = NULL; | 339 this->FillHWRect = NULL; |
249 this->UpdateRects = NULL; | 340 this->UpdateRects = NULL; |
250 | |
251 /* Restore gamma settings */ | |
252 CGDisplayRestoreColorSyncSettings (); | |
253 | 341 |
254 /* Restore original screen resolution */ | 342 /* Release fullscreen resources */ |
255 if ( mode_flags & SDL_FULLSCREEN ) { | 343 if ( mode_flags & SDL_FULLSCREEN ) { |
344 | |
345 SDL_QuartzGammaTable gamma_table; | |
346 int gamma_error; | |
347 | |
348 gamma_error = QZ_FadeGammaOut (this, &gamma_table); | |
349 | |
350 /* Release the OpenGL context */ | |
351 /* Do this first to avoid trash on the display before fade */ | |
352 if ( mode_flags & SDL_OPENGL ) | |
353 QZ_TearDownOpenGL (this); | |
354 | |
256 if (mode_flags & SDL_OPENGL) | 355 if (mode_flags & SDL_OPENGL) |
257 CGLSetFullScreen(NULL); | 356 CGLSetFullScreen(NULL); |
258 | 357 |
358 /* Restore original screen resolution/bpp */ | |
259 CGDisplaySwitchToMode (display_id, save_mode); | 359 CGDisplaySwitchToMode (display_id, save_mode); |
260 CGDisplayRelease (display_id); | 360 CGDisplayRelease (display_id); |
261 } | 361 ShowMenuBar (); |
262 /* Release window mode data structures */ | 362 |
363 if (! gamma_error) | |
364 QZ_FadeGammaIn (this, &gamma_table); | |
365 } | |
366 /* Release window mode resources */ | |
263 else { | 367 else { |
264 if ( (mode_flags & SDL_OPENGL) == 0 ) { | 368 if ( (mode_flags & SDL_OPENGL) == 0 ) { |
265 UnlockPortBits ( [ windowView qdPort ] ); | 369 UnlockPortBits ( [ window_view qdPort ] ); |
266 [ windowView release ]; | 370 [ window_view release ]; |
267 } | 371 } |
268 [ qz_window setContentView:nil ]; | 372 [ qz_window setContentView:nil ]; |
269 [ qz_window setDelegate:nil ]; | 373 [ qz_window setDelegate:nil ]; |
270 [ qz_window close ]; | 374 [ qz_window close ]; |
271 } | 375 [ qz_window release ]; |
376 | |
377 /* Release the OpenGL context */ | |
378 if ( mode_flags & SDL_OPENGL ) | |
379 QZ_TearDownOpenGL (this); | |
380 } | |
381 | |
382 /* Restore gamma settings */ | |
383 CGDisplayRestoreColorSyncSettings (); | |
272 | 384 |
273 /* Set pixels to null (so other code doesn't try to free it) */ | 385 /* Set pixels to null (so other code doesn't try to free it) */ |
274 if (this->screen != NULL) | 386 if (this->screen != NULL) |
275 this->screen->pixels = NULL; | 387 this->screen->pixels = NULL; |
276 | 388 |
277 /* Release the OpenGL context */ | |
278 if ( mode_flags & SDL_OPENGL ) | |
279 QZ_TearDownOpenGL (this); | |
280 | |
281 /* Ensure the cursor will be visible and working when we quit */ | 389 /* Ensure the cursor will be visible and working when we quit */ |
282 CGDisplayShowCursor (display_id); | 390 CGDisplayShowCursor (display_id); |
283 CGAssociateMouseAndMouseCursorPosition (1); | 391 CGAssociateMouseAndMouseCursorPosition (1); |
284 | 392 |
285 /* Signal successful teardown */ | 393 /* Signal successful teardown */ |
287 } | 395 } |
288 | 396 |
289 static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width, | 397 static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width, |
290 int height, int bpp, Uint32 flags) { | 398 int height, int bpp, Uint32 flags) { |
291 int exact_match; | 399 int exact_match; |
292 | 400 int gamma_error; |
401 SDL_QuartzGammaTable gamma_table; | |
402 | |
293 /* See if requested mode exists */ | 403 /* See if requested mode exists */ |
294 mode = CGDisplayBestModeForParameters (display_id, bpp, width, | 404 mode = CGDisplayBestModeForParameters (display_id, bpp, width, |
295 height, &exact_match); | 405 height, &exact_match); |
296 | 406 |
297 /* Require an exact match to the requested mode */ | 407 /* Require an exact match to the requested mode */ |
299 sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp); | 409 sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp); |
300 SDL_SetError (QZ_Error); | 410 SDL_SetError (QZ_Error); |
301 goto ERR_NO_MATCH; | 411 goto ERR_NO_MATCH; |
302 } | 412 } |
303 | 413 |
414 /* Fade display to zero gamma */ | |
415 gamma_error = QZ_FadeGammaOut (this, &gamma_table); | |
416 | |
304 /* Put up the blanking window (a window above all other windows) */ | 417 /* Put up the blanking window (a window above all other windows) */ |
305 if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) { | 418 if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) { |
306 SDL_SetError ("Failed capturing display"); | 419 SDL_SetError ("Failed capturing display"); |
307 goto ERR_NO_CAPTURE; | 420 goto ERR_NO_CAPTURE; |
308 } | 421 } |
422 | |
309 | 423 |
310 /* Do the physical switch */ | 424 /* Do the physical switch */ |
311 if ( CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode) ) { | 425 if ( CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode) ) { |
312 SDL_SetError ("Failed switching display resolution"); | 426 SDL_SetError ("Failed switching display resolution"); |
313 goto ERR_NO_SWITCH; | 427 goto ERR_NO_SWITCH; |
314 } | 428 } |
315 | 429 |
316 /* None of these methods seem to fix the fullscreen artifacts bug(s) */ | |
317 #if USE_GDHANDLE | |
318 SetGDevice(GetMainDevice()); | |
319 current->pitch = (**(** GetMainDevice() ).gdPMap).rowBytes & 0x3FFF; | |
320 current->pixels = (**(** GetMainDevice() ).gdPMap).baseAddr; | |
321 #elif USE_CREATEPORT | |
322 device_port = CreateNewPortForCGDisplayID((Uint32*)display_id); | |
323 SetPort (device_port); | |
324 LockPortBits ( device_port ); | |
325 current->pixels = GetPixBaseAddr ( GetPortPixMap ( device_port ) ); | |
326 current->pitch = GetPixRowBytes ( GetPortPixMap ( device_port ) ); | |
327 UnlockPortBits ( device_port ); | |
328 #else | |
329 current->pixels = (Uint32*) CGDisplayBaseAddress (display_id); | 430 current->pixels = (Uint32*) CGDisplayBaseAddress (display_id); |
330 current->pitch = CGDisplayBytesPerRow (display_id); | 431 current->pitch = CGDisplayBytesPerRow (display_id); |
331 #endif | |
332 | 432 |
333 current->flags = 0; | 433 current->flags = 0; |
334 current->w = width; | 434 current->w = width; |
335 current->h = height; | 435 current->h = height; |
336 current->flags |= SDL_FULLSCREEN; | 436 current->flags |= SDL_FULLSCREEN; |
352 | 452 |
353 CGLError err; | 453 CGLError err; |
354 CGLContextObj ctx; | 454 CGLContextObj ctx; |
355 | 455 |
356 if ( ! QZ_SetupOpenGL (this, bpp, flags) ) { | 456 if ( ! QZ_SetupOpenGL (this, bpp, flags) ) { |
357 return NULL; | 457 goto ERR_NO_GL; |
358 } | 458 } |
359 | 459 |
360 ctx = [ gl_context cglContext ]; | 460 ctx = [ gl_context cglContext ]; |
361 err = CGLSetFullScreen (ctx); | 461 err = CGLSetFullScreen (ctx); |
362 | 462 |
365 SDL_SetError (QZ_Error); | 465 SDL_SetError (QZ_Error); |
366 goto ERR_NO_GL; | 466 goto ERR_NO_GL; |
367 } | 467 } |
368 | 468 |
369 [ gl_context makeCurrentContext]; | 469 [ gl_context makeCurrentContext]; |
470 | |
471 glClear (GL_COLOR_BUFFER_BIT); | |
472 | |
473 [ gl_context flushBuffer ]; | |
370 | 474 |
371 current->flags |= SDL_OPENGL; | 475 current->flags |= SDL_OPENGL; |
372 } | 476 } |
373 | 477 |
374 /* If we don't hide menu bar, it will get events and interrupt the program */ | 478 /* If we don't hide menu bar, it will get events and interrupt the program */ |
375 HideMenuBar (); | 479 HideMenuBar (); |
480 | |
481 /* Fade the display to original gamma */ | |
482 if (! gamma_error ) | |
483 QZ_FadeGammaIn (this, &gamma_table); | |
376 | 484 |
377 /* Save the flags to ensure correct tear-down */ | 485 /* Save the flags to ensure correct tear-down */ |
378 mode_flags = current->flags; | 486 mode_flags = current->flags; |
379 | 487 |
380 return current; | 488 return current; |
381 | 489 |
382 /* Since the blanking window covers *all* windows (even force quit) correct recovery is crutial */ | 490 /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */ |
383 ERR_NO_GL: CGDisplaySwitchToMode (display_id, save_mode); | 491 ERR_NO_GL: CGDisplaySwitchToMode (display_id, save_mode); |
384 ERR_NO_SWITCH: CGDisplayRelease (display_id); | 492 ERR_NO_SWITCH: CGDisplayRelease (display_id); |
385 ERR_NO_CAPTURE: | 493 ERR_NO_CAPTURE: if (!gamma_error) { QZ_FadeGammaIn (this, &gamma_table); } |
386 ERR_NO_MATCH: return NULL; | 494 ERR_NO_MATCH: return NULL; |
387 } | 495 } |
388 | 496 |
389 static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width, | 497 static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width, |
390 int height, int bpp, Uint32 flags) { | 498 int height, int bpp, Uint32 flags) { |
438 current->flags |= SDL_OPENGL; | 546 current->flags |= SDL_OPENGL; |
439 } | 547 } |
440 /* For 2D, we set the content view to a NSQuickDrawView */ | 548 /* For 2D, we set the content view to a NSQuickDrawView */ |
441 else { | 549 else { |
442 | 550 |
443 windowView = [ [ NSQuickDrawView alloc ] init ]; | 551 window_view = [ [ SDL_QuartzWindowView alloc ] init ]; |
444 [ qz_window setContentView:windowView ]; | 552 [ qz_window setContentView:window_view ]; |
445 [ qz_window makeKeyAndOrderFront:nil ]; | 553 [ qz_window makeKeyAndOrderFront:nil ]; |
446 | 554 |
447 LockPortBits ( [ windowView qdPort ] ); | 555 LockPortBits ( [ window_view qdPort ] ); |
448 current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ windowView qdPort ] ) ); | 556 current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) ); |
449 current->pitch = GetPixRowBytes ( GetPortPixMap ( [ windowView qdPort ] ) ); | 557 current->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) ); |
450 | 558 |
451 current->flags |= SDL_SWSURFACE; | 559 current->flags |= SDL_SWSURFACE; |
452 current->flags |= SDL_PREALLOC; | 560 current->flags |= SDL_PREALLOC; |
561 | |
453 if ( flags & SDL_NOFRAME ) | 562 if ( flags & SDL_NOFRAME ) |
454 current->flags |= SDL_NOFRAME; | 563 current->flags |= SDL_NOFRAME; |
455 if ( flags & SDL_RESIZABLE ) | 564 if ( flags & SDL_RESIZABLE ) |
456 current->flags |= SDL_RESIZABLE; | 565 current->flags |= SDL_RESIZABLE; |
457 | 566 |
460 current->pixels += 22 * current->pitch; | 569 current->pixels += 22 * current->pitch; |
461 } | 570 } |
462 | 571 |
463 this->UpdateRects = QZ_UpdateRects; | 572 this->UpdateRects = QZ_UpdateRects; |
464 } | 573 } |
574 | |
575 /* Save flags to ensure correct teardown */ | |
576 mode_flags = current->flags; | |
577 | |
465 return current; | 578 return current; |
466 } | 579 } |
467 | 580 |
468 static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width, | 581 static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width, |
469 int height, int bpp, Uint32 flags) { | 582 int height, int bpp, Uint32 flags) { |
480 return NULL; | 593 return NULL; |
481 } | 594 } |
482 /* Setup windowed video */ | 595 /* Setup windowed video */ |
483 else { | 596 else { |
484 /* Force bpp to the device's bpp */ | 597 /* Force bpp to the device's bpp */ |
485 bpp = current->format->BitsPerPixel; | 598 bpp = device_bpp; |
486 current = QZ_SetVideoWindowed (this, current, width, height, bpp, flags); | 599 current = QZ_SetVideoWindowed (this, current, width, height, bpp, flags); |
487 if (current == NULL) | 600 if (current == NULL) |
488 return NULL; | 601 return NULL; |
489 } | 602 } |
490 | 603 |
518 SDL_SetError ("Couldn't reallocate pixel format"); | 631 SDL_SetError ("Couldn't reallocate pixel format"); |
519 return NULL; | 632 return NULL; |
520 } | 633 } |
521 } | 634 } |
522 | 635 |
523 /* Warp mouse to origin in order to get passive mouse motion events started correctly */ | 636 /* Signal successful completion (used internally) */ |
524 QZ_PrivateWarpCursor (this, current->flags & SDL_FULLSCREEN, height, 0, 0); | |
525 | |
526 /* Signal successful completion */ | |
527 video_set = SDL_TRUE; | 637 video_set = SDL_TRUE; |
528 | 638 |
529 return current; | 639 return current; |
530 } | 640 } |
531 | 641 |
559 | 669 |
560 static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) { | 670 static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) { |
561 #pragma unused(this,num_rects,rects) | 671 #pragma unused(this,num_rects,rects) |
562 } | 672 } |
563 | 673 |
674 /** | |
675 * The obscured code is based on work by Matt Slot fprefect@ambrosiasw.com, | |
676 * who supplied sample code for Carbon. | |
677 **/ | |
678 static int QZ_IsWindowObscured (NSWindow *window) { | |
679 | |
680 //#define TEST_OBSCURED 1 | |
681 | |
682 #if TEST_OBSCURED | |
683 | |
684 /* In order to determine if a direct copy to the screen is possible, | |
685 we must figure out if there are any windows covering ours (including shadows). | |
686 This can be done by querying the window server about the on screen | |
687 windows for their screen rectangle and window level. | |
688 The procedure used below is puts accuracy before speed; however, it aims to call | |
689 the window server the fewest number of times possible to keep things reasonable. | |
690 In my testing on a 300mhz G3, this routine typically takes < 2 ms. -DW | |
691 | |
692 Notes: | |
693 -Calls into the Window Server involve IPC which is slow. | |
694 -Getting a rectangle seems slower than getting the window level | |
695 -The window list we get back is in sorted order, top to bottom | |
696 -On average, I suspect, most windows above ours are dock icon windows (hence optimization) | |
697 -Some windows above ours are always there, and cannot move or obscure us (menu bar) | |
698 | |
699 Bugs: | |
700 -no way (yet) to deactivate direct drawing when a window is dragged, | |
701 or suddenly obscured, so drawing continues and can produce garbage | |
702 We need some kind of locking mechanism on window movement to prevent this | |
703 | |
704 -deactivated normal windows use activated normal | |
705 window shadows (slight inaccuraccy) | |
706 */ | |
707 | |
708 /* Cache the connection to the window server */ | |
709 static CGSConnectionID cgsConnection = (CGSConnectionID) -1; | |
710 | |
711 /* Cache the dock icon windows */ | |
712 static CGSWindowID dockIcons[kMaxWindows]; | |
713 static int numCachedDockIcons = 0; | |
714 | |
715 CGSWindowID windows[kMaxWindows]; | |
716 CGSWindowCount i, count; | |
717 CGSWindowLevel winLevel; | |
718 CGSRect winRect; | |
719 | |
720 CGSRect contentRect; | |
721 int windowNumber; | |
722 //int isMainWindow; | |
723 int firstDockIcon; | |
724 int dockIconCacheMiss; | |
725 int windowContentOffset; | |
726 | |
727 int obscured = SDL_TRUE; | |
728 | |
729 if ( [ window isVisible ] ) { | |
730 | |
731 /* walk the window list looking for windows over top of | |
732 (or casting a shadow on) ours */ | |
733 | |
734 /* Get a connection to the window server */ | |
735 /* Should probably be moved out into SetVideoMode() or InitVideo() */ | |
736 if (cgsConnection == (CGSConnectionID) -1) { | |
737 cgsConnection = (CGSConnectionID) 0; | |
738 cgsConnection = _CGSDefaultConnection (); | |
739 } | |
740 | |
741 if (cgsConnection) { | |
742 | |
743 if ( ! [ window styleMask ] & NSBorderlessWindowMask ) | |
744 windowContentOffset = 22; | |
745 else | |
746 windowContentOffset = 0; | |
747 | |
748 windowNumber = [ window windowNumber ]; | |
749 //isMainWindow = [ window isMainWindow ]; | |
750 | |
751 /* The window list is sorted according to order on the screen */ | |
752 count = 0; | |
753 CGSGetOnScreenWindowList (cgsConnection, 0, kMaxWindows, windows, &count); | |
754 CGSGetScreenRectForWindow (cgsConnection, windowNumber, &contentRect); | |
755 | |
756 /* adjust rect for window title bar (if present) */ | |
757 contentRect.origin.y += windowContentOffset; | |
758 contentRect.size.height -= windowContentOffset; | |
759 | |
760 firstDockIcon = -1; | |
761 dockIconCacheMiss = SDL_FALSE; | |
762 | |
763 /* The first window is always an empty window with level kCGSWindowLevelTop | |
764 so start at index 1 */ | |
765 for (i = 1; i < count; i++) { | |
766 | |
767 /* If we reach our window in the list, it cannot be obscured */ | |
768 if (windows[i] == windowNumber) { | |
769 | |
770 obscured = SDL_FALSE; | |
771 break; | |
772 } | |
773 else { | |
774 | |
775 float shadowSide; | |
776 float shadowTop; | |
777 float shadowBottom; | |
778 | |
779 CGSGetWindowLevel (cgsConnection, windows[i], &winLevel); | |
780 | |
781 if (winLevel == kCGSWindowLevelDockIcon) { | |
782 | |
783 int j; | |
784 | |
785 if (firstDockIcon < 0) { | |
786 | |
787 firstDockIcon = i; | |
788 | |
789 if (numCachedDockIcons > 0) { | |
790 | |
791 for (j = 0; j < numCachedDockIcons; j++) { | |
792 | |
793 if (windows[i] == dockIcons[j]) | |
794 i++; | |
795 else | |
796 break; | |
797 } | |
798 | |
799 if (j != 0) { | |
800 | |
801 i--; | |
802 | |
803 if (j < numCachedDockIcons) { | |
804 | |
805 dockIconCacheMiss = SDL_TRUE; | |
806 } | |
807 } | |
808 | |
809 } | |
810 } | |
811 | |
812 continue; | |
813 } | |
814 else if (winLevel == kCGSWindowLevelMenuIgnore | |
815 /* winLevel == kCGSWindowLevelTop */) { | |
816 | |
817 continue; /* cannot obscure window */ | |
818 } | |
819 else if (winLevel == kCGSWindowLevelDockMenu || | |
820 winLevel == kCGSWindowLevelMenu) { | |
821 | |
822 shadowSide = 18; | |
823 shadowTop = 4; | |
824 shadowBottom = 22; | |
825 } | |
826 else if (winLevel == kCGSWindowLevelUtility) { | |
827 | |
828 shadowSide = 8; | |
829 shadowTop = 4; | |
830 shadowBottom = 12; | |
831 } | |
832 else if (winLevel == kCGSWindowLevelNormal) { | |
833 | |
834 /* These numbers are for foreground windows, | |
835 they are too big (but will work) for background windows */ | |
836 shadowSide = 20; | |
837 shadowTop = 10; | |
838 shadowBottom = 24; | |
839 } | |
840 else if (winLevel == kCGSWindowLevelDock) { | |
841 | |
842 /* Create dock icon cache */ | |
843 if (numCachedDockIcons != (i-firstDockIcon) || | |
844 dockIconCacheMiss) { | |
845 | |
846 numCachedDockIcons = i - firstDockIcon; | |
847 memcpy (dockIcons, &(windows[firstDockIcon]), | |
848 numCachedDockIcons * sizeof(*windows)); | |
849 } | |
850 | |
851 /* no shadow */ | |
852 shadowSide = 0; | |
853 shadowTop = 0; | |
854 shadowBottom = 0; | |
855 } | |
856 else { | |
857 | |
858 /* kCGSWindowLevelDockLabel, | |
859 kCGSWindowLevelDock, | |
860 kOther??? */ | |
861 | |
862 /* no shadow */ | |
863 shadowSide = 0; | |
864 shadowTop = 0; | |
865 shadowBottom = 0; | |
866 } | |
867 | |
868 CGSGetScreenRectForWindow (cgsConnection, windows[i], &winRect); | |
869 | |
870 winRect.origin.x -= shadowSide; | |
871 winRect.origin.y -= shadowTop; | |
872 winRect.size.width += shadowSide; | |
873 winRect.size.height += shadowBottom; | |
874 | |
875 if (NSIntersectsRect (contentRect, winRect)) { | |
876 | |
877 obscured = SDL_TRUE; | |
878 break; | |
879 } | |
880 | |
881 } /* window was not our window */ | |
882 | |
883 } /* iterate over windows */ | |
884 | |
885 } /* get cgsConnection */ | |
886 | |
887 } /* window is visible */ | |
888 | |
889 return obscured; | |
890 #else | |
891 return SDL_TRUE; | |
892 #endif | |
893 } | |
894 | |
564 static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) { | 895 static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) { |
565 | 896 |
566 if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) { | 897 if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) { |
567 QZ_GL_SwapBuffers (this); | 898 QZ_GL_SwapBuffers (this); |
568 } | 899 } |
900 else if ( [ qz_window isMiniaturized ] && | |
901 ! (SDL_VideoSurface->flags & SDL_OPENGL)) { | |
902 | |
903 /** | |
904 * Set port alpha opaque so deminiaturize looks right | |
905 * This isn't so nice, but there is no | |
906 * initial deminatureize notification (before demini starts) | |
907 **/ | |
908 QZ_SetPortAlphaOpaque ([ [ qz_window contentView ] qdPort], | |
909 [ qz_window styleMask ] & NSBorderlessWindowMask); | |
910 } | |
911 else if ( ! QZ_IsWindowObscured (qz_window) ) { | |
912 | |
913 /* Use direct copy to flush contents to the display */ | |
914 CGrafPtr savePort; | |
915 CGrafPtr dstPort, srcPort; | |
916 const BitMap *dstBits, *srcBits; | |
917 Rect dstRect, srcRect; | |
918 Point offset; | |
919 int i; | |
920 | |
921 GetPort (&savePort); | |
922 | |
923 dstPort = CreateNewPortForCGDisplayID ((UInt32)display_id); | |
924 srcPort = [ window_view qdPort ]; | |
925 | |
926 offset.h = 0; | |
927 offset.v = 0; | |
928 SetPort (srcPort); | |
929 LocalToGlobal (&offset); | |
930 | |
931 SetPort (dstPort); | |
932 | |
933 LockPortBits (dstPort); | |
934 LockPortBits (srcPort); | |
935 | |
936 dstBits = GetPortBitMapForCopyBits (dstPort); | |
937 srcBits = GetPortBitMapForCopyBits (srcPort); | |
938 | |
939 for (i = 0; i < numRects; i++) { | |
940 | |
941 SetRect (&srcRect, rects[i].x, rects[i].y, | |
942 rects[i].x + rects[i].w, | |
943 rects[i].y + rects[i].h); | |
944 | |
945 SetRect (&dstRect, | |
946 rects[i].x + offset.h, | |
947 rects[i].y + offset.v, | |
948 rects[i].x + rects[i].w + offset.h, | |
949 rects[i].y + rects[i].h + offset.v); | |
950 | |
951 CopyBits (srcBits, dstBits, | |
952 &srcRect, &dstRect, srcCopy, NULL); | |
953 | |
954 } | |
955 | |
956 SetPort (savePort); | |
957 } | |
569 else { | 958 else { |
959 | |
960 /* Use QDFlushPortBuffer() to flush content to display */ | |
570 int i; | 961 int i; |
571 RgnHandle dirty = NewRgn (); | 962 RgnHandle dirty = NewRgn (); |
572 RgnHandle temp = NewRgn (); | 963 RgnHandle temp = NewRgn (); |
573 | 964 |
574 SetEmptyRgn (dirty); | 965 SetEmptyRgn (dirty); |
580 rects[i].x + rects[i].w, rects[i].y + rects[i].h); | 971 rects[i].x + rects[i].w, rects[i].y + rects[i].h); |
581 MacUnionRgn (dirty, temp, dirty); | 972 MacUnionRgn (dirty, temp, dirty); |
582 } | 973 } |
583 | 974 |
584 /* Flush the dirty region */ | 975 /* Flush the dirty region */ |
585 QDFlushPortBuffer ( [ windowView qdPort ], dirty ); | 976 QDFlushPortBuffer ( [ window_view qdPort ], dirty ); |
586 DisposeRgn (dirty); | 977 DisposeRgn (dirty); |
587 DisposeRgn (temp); | 978 DisposeRgn (temp); |
588 } | 979 } |
589 } | 980 } |
590 | 981 |
595 } | 986 } |
596 | 987 |
597 static int QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) { | 988 static int QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) { |
598 | 989 |
599 CGSDisplayHWFill (display_id, rect->x, rect->y, rect->w, rect->h, color); | 990 CGSDisplayHWFill (display_id, rect->x, rect->y, rect->w, rect->h, color); |
991 | |
600 return 0; | 992 return 0; |
601 } | 993 } |
602 | 994 |
603 static int QZ_LockHWSurface(_THIS, SDL_Surface *surface) { | 995 static int QZ_LockHWSurface(_THIS, SDL_Surface *surface) { |
604 | 996 |
605 return 1; | 997 return 1; |
606 } | 998 } |
607 | 999 |
608 static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface) { | 1000 static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface) { |
1001 | |
609 } | 1002 } |
610 | 1003 |
611 static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) { | 1004 static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) { |
612 } | 1005 } |
613 | 1006 |
619 | 1012 |
620 /* Gamma functions */ | 1013 /* Gamma functions */ |
621 static int QZ_SetGamma (_THIS, float red, float green, float blue) { | 1014 static int QZ_SetGamma (_THIS, float red, float green, float blue) { |
622 | 1015 |
623 const CGGammaValue min = 0.0, max = 1.0; | 1016 const CGGammaValue min = 0.0, max = 1.0; |
624 | 1017 |
625 if ( CGDisplayNoErr != CGSetDisplayTransferByFormula | 1018 if (red == 0.0) |
626 (display_id, min, max, red, min, max, green, min, max, blue) ) | 1019 red = FLT_MAX; |
1020 else | |
1021 red = 1.0 / red; | |
1022 | |
1023 if (green == 0.0) | |
1024 green = FLT_MAX; | |
1025 else | |
1026 green = 1.0 / green; | |
1027 | |
1028 if (blue == 0.0) | |
1029 blue = FLT_MAX; | |
1030 else | |
1031 blue = 1.0 / blue; | |
1032 | |
1033 if ( CGDisplayNoErr == CGSetDisplayTransferByFormula | |
1034 (display_id, min, max, red, min, max, green, min, max, blue) ) { | |
1035 | |
1036 return 0; | |
1037 } | |
1038 else { | |
1039 | |
627 return -1; | 1040 return -1; |
628 | 1041 } |
629 return 0; | |
630 } | 1042 } |
631 | 1043 |
632 static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) { | 1044 static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) { |
633 | 1045 |
634 CGGammaValue dummy; | 1046 CGGammaValue dummy; |
635 if ( CGDisplayNoErr != CGGetDisplayTransferByFormula | 1047 if ( CGDisplayNoErr == CGGetDisplayTransferByFormula |
636 (display_id, &dummy, &dummy, red, | 1048 (display_id, &dummy, &dummy, red, |
637 &dummy, &dummy, green, &dummy, &dummy, blue) ) | 1049 &dummy, &dummy, green, &dummy, &dummy, blue) ) |
638 | 1050 |
1051 return 0; | |
1052 else | |
639 return -1; | 1053 return -1; |
640 | |
641 return 0; | |
642 } | 1054 } |
643 | 1055 |
644 static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) { | 1056 static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) { |
645 | 1057 |
646 const CGTableCount tableSize = 255; | 1058 const CGTableCount tableSize = 255; |
658 greenTable[i % 256] = ramp[i] / 65535.0; | 1070 greenTable[i % 256] = ramp[i] / 65535.0; |
659 | 1071 |
660 for (i=512; i < 768; i++) | 1072 for (i=512; i < 768; i++) |
661 blueTable[i % 256] = ramp[i] / 65535.0; | 1073 blueTable[i % 256] = ramp[i] / 65535.0; |
662 | 1074 |
663 if ( CGDisplayNoErr != CGSetDisplayTransferByTable | 1075 if ( CGDisplayNoErr == CGSetDisplayTransferByTable |
664 (display_id, tableSize, redTable, greenTable, blueTable) ) | 1076 (display_id, tableSize, redTable, greenTable, blueTable) ) |
1077 return 0; | |
1078 else | |
665 return -1; | 1079 return -1; |
666 | |
667 return 0; | |
668 } | 1080 } |
669 | 1081 |
670 static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) { | 1082 static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) { |
671 | 1083 |
672 const CGTableCount tableSize = 255; | 1084 const CGTableCount tableSize = 255; |
693 ramp[i] = blueTable[i % 256] * 65535.0; | 1105 ramp[i] = blueTable[i % 256] * 65535.0; |
694 | 1106 |
695 return 0; | 1107 return 0; |
696 } | 1108 } |
697 | 1109 |
698 /* OpenGL helper functions */ | 1110 /* OpenGL helper functions (used internally) */ |
1111 | |
699 static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) { | 1112 static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) { |
700 | 1113 |
701 NSOpenGLPixelFormatAttribute attr[32]; | 1114 NSOpenGLPixelFormatAttribute attr[32]; |
702 NSOpenGLPixelFormat *fmt; | 1115 NSOpenGLPixelFormat *fmt; |
703 int i = 0; | 1116 int i = 0; |
759 [ NSOpenGLContext clearCurrentContext ]; | 1172 [ NSOpenGLContext clearCurrentContext ]; |
760 [ gl_context clearDrawable ]; | 1173 [ gl_context clearDrawable ]; |
761 [ gl_context release ]; | 1174 [ gl_context release ]; |
762 } | 1175 } |
763 | 1176 |
1177 | |
764 /* SDL OpenGL functions */ | 1178 /* SDL OpenGL functions */ |
765 | 1179 |
766 static int QZ_GL_LoadLibrary (_THIS, const char *location) { | 1180 static int QZ_GL_LoadLibrary (_THIS, const char *location) { |
767 this->gl_config.driver_loaded = 1; | 1181 this->gl_config.driver_loaded = 1; |
768 return 1; | 1182 return 1; |
803 | 1217 |
804 } | 1218 } |
805 | 1219 |
806 CGLGetParameter (ctx, param, (long*)value); | 1220 CGLGetParameter (ctx, param, (long*)value); |
807 */ | 1221 */ |
1222 | |
808 *value = -1; | 1223 *value = -1; |
809 return -1; | 1224 return -1; |
810 } | 1225 } |
811 | 1226 |
812 static int QZ_GL_MakeCurrent (_THIS) { | 1227 static int QZ_GL_MakeCurrent (_THIS) { |
815 } | 1230 } |
816 | 1231 |
817 static void QZ_GL_SwapBuffers (_THIS) { | 1232 static void QZ_GL_SwapBuffers (_THIS) { |
818 [ gl_context flushBuffer ]; | 1233 [ gl_context flushBuffer ]; |
819 } | 1234 } |
1235 | |
1236 |