Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
1721 lines (1364 loc) · 52.5 KB

SDL_QuartzVideo.m

File metadata and controls

1721 lines (1364 loc) · 52.5 KB
 
1
2
/*
SDL - Simple DirectMedia Layer
Jan 4, 2004
Jan 4, 2004
3
Copyright (C) 1997-2003 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
Dec 14, 2001
Dec 14, 2001
20
slouken@libsdl.org
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
23
24
#include "SDL_QuartzVideo.h"
Jan 4, 2004
Jan 4, 2004
25
#include "SDL_QuartzWindow.h"
Jan 4, 2004
Jan 4, 2004
27
28
29
30
31
32
33
/*
Add methods to get at private members of NSScreen.
Since there is a bug in Apple's screen switching code
that does not update this variable when switching
to fullscreen, we'll set it manually (but only for the
main screen).
*/
May 28, 2006
May 28, 2006
34
35
36
@ interface NSScreen (NSScreenAccess) - (void) setFrame:(NSRect) frame;
@end @ implementation NSScreen (NSScreenAccess) - (void) setFrame:(NSRect)
frame;
Jan 4, 2004
Jan 4, 2004
37
38
39
40
{
_frame = frame;
}
May 28, 2006
May 28, 2006
41
@end
Jan 4, 2004
Jan 4, 2004
42
43
44
45
46
/*
Structure for rez switch gamma fades
We can hide the monitor flicker by setting the gamma tables to 0
*/
#define QZ_GAMMA_TABLE_SIZE 256
May 28, 2006
May 28, 2006
47
48
typedef struct
{
Jan 4, 2004
Jan 4, 2004
49
50
51
52
53
54
55
56
57
CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
} SDL_QuartzGammaTable;
/* Bootstrap functions */
May 28, 2006
May 28, 2006
58
59
60
static int QZ_Available ();
static SDL_VideoDevice *QZ_CreateDevice (int device_index);
static void QZ_DeleteDevice (SDL_VideoDevice * device);
Jan 4, 2004
Jan 4, 2004
61
62
/* Initialization, Query, Setup, and Redrawing functions */
May 28, 2006
May 28, 2006
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
static int QZ_VideoInit (_THIS, SDL_PixelFormat * video_format);
static SDL_Rect **QZ_ListModes (_THIS, SDL_PixelFormat * format,
Uint32 flags);
static void QZ_UnsetVideoMode (_THIS, BOOL to_desktop);
static SDL_Surface *QZ_SetVideoMode (_THIS, SDL_Surface * current,
int width, int height, int bpp,
Uint32 flags);
static int QZ_ToggleFullScreen (_THIS, int on);
static int QZ_SetColors (_THIS, int first_color,
int num_colors, SDL_Color * colors);
static int QZ_LockDoubleBuffer (_THIS, SDL_Surface * surface);
static void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface * surface);
static int QZ_ThreadFlip (_THIS);
static int QZ_FlipDoubleBuffer (_THIS, SDL_Surface * surface);
static void QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect * rects);
static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect * rects);
static int QZ_LockWindow (_THIS, SDL_Surface * surface);
static void QZ_UnlockWindow (_THIS, SDL_Surface * surface);
static void QZ_UpdateRects (_THIS, int num_rects, SDL_Rect * rects);
static void QZ_VideoQuit (_THIS);
Jan 4, 2004
Jan 4, 2004
87
88
/* Hardware surface functions (for fullscreen mode only) */
May 28, 2006
May 28, 2006
89
90
91
#if 0 /* Not used (apparently, it's really slow) */
static int QZ_FillHWRect (_THIS, SDL_Surface * dst, SDL_Rect * rect,
Uint32 color);
Jan 4, 2004
Jan 4, 2004
92
#endif
May 28, 2006
May 28, 2006
93
94
95
96
static int QZ_LockHWSurface (_THIS, SDL_Surface * surface);
static void QZ_UnlockHWSurface (_THIS, SDL_Surface * surface);
static int QZ_AllocHWSurface (_THIS, SDL_Surface * surface);
static void QZ_FreeHWSurface (_THIS, SDL_Surface * surface);
Jan 4, 2004
Jan 4, 2004
97
/* static int QZ_FlipHWSurface (_THIS, SDL_Surface *surface); */
98
99
100
/* Bootstrap binding, enables entry point into the driver */
VideoBootStrap QZ_bootstrap = {
Jan 22, 2002
Jan 22, 2002
101
"Quartz", "Mac OS X CoreGraphics", QZ_Available, QZ_CreateDevice
Feb 1, 2003
Feb 1, 2003
104
105
/* Bootstrap functions */
May 28, 2006
May 28, 2006
106
107
108
static int
QZ_Available ()
{
109
110
111
return 1;
}
May 28, 2006
May 28, 2006
112
113
114
static SDL_VideoDevice *
QZ_CreateDevice (int device_index)
{
Jan 22, 2002
Jan 22, 2002
116
#pragma unused (device_index)
117
118
119
120
SDL_VideoDevice *device;
SDL_PrivateVideoData *hidden;
May 28, 2006
May 28, 2006
121
122
device = (SDL_VideoDevice *) SDL_malloc (sizeof (*device));
hidden = (SDL_PrivateVideoData *) SDL_malloc (sizeof (*hidden));
123
124
125
126
if (device == NULL || hidden == NULL)
SDL_OutOfMemory ();
May 28, 2006
May 28, 2006
127
128
SDL_memset (device, 0, sizeof (*device));
SDL_memset (hidden, 0, sizeof (*hidden));
Jan 22, 2002
Jan 22, 2002
129
130
131
device->hidden = hidden;
May 28, 2006
May 28, 2006
132
133
134
device->VideoInit = QZ_VideoInit;
device->ListModes = QZ_ListModes;
device->SetVideoMode = QZ_SetVideoMode;
135
device->ToggleFullScreen = QZ_ToggleFullScreen;
May 28, 2006
May 28, 2006
136
137
device->UpdateMouse = QZ_UpdateMouse;
device->SetColors = QZ_SetColors;
138
/* device->UpdateRects = QZ_UpdateRects; this is determined by SetVideoMode() */
May 28, 2006
May 28, 2006
139
device->VideoQuit = QZ_VideoQuit;
Jan 22, 2002
Jan 22, 2002
140
May 28, 2006
May 28, 2006
141
device->LockHWSurface = QZ_LockHWSurface;
142
device->UnlockHWSurface = QZ_UnlockHWSurface;
May 28, 2006
May 28, 2006
143
144
145
device->AllocHWSurface = QZ_AllocHWSurface;
device->FreeHWSurface = QZ_FreeHWSurface;
/* device->FlipHWSurface = QZ_FlipHWSurface */ ;
May 28, 2006
May 28, 2006
147
148
device->SetGamma = QZ_SetGamma;
device->GetGamma = QZ_GetGamma;
149
150
151
152
device->SetGammaRamp = QZ_SetGammaRamp;
device->GetGammaRamp = QZ_GetGammaRamp;
device->GL_GetProcAddress = QZ_GL_GetProcAddress;
May 28, 2006
May 28, 2006
153
154
155
156
device->GL_GetAttribute = QZ_GL_GetAttribute;
device->GL_MakeCurrent = QZ_GL_MakeCurrent;
device->GL_SwapBuffers = QZ_GL_SwapBuffers;
device->GL_LoadLibrary = QZ_GL_LoadLibrary;
Jan 22, 2002
Jan 22, 2002
157
May 28, 2006
May 28, 2006
158
device->FreeWMCursor = QZ_FreeWMCursor;
159
device->CreateWMCursor = QZ_CreateWMCursor;
May 28, 2006
May 28, 2006
160
161
162
device->ShowWMCursor = QZ_ShowWMCursor;
device->WarpWMCursor = QZ_WarpWMCursor;
device->MoveWMCursor = QZ_MoveWMCursor;
163
device->CheckMouseMode = QZ_CheckMouseMode;
May 28, 2006
May 28, 2006
164
165
device->InitOSKeymap = QZ_InitOSKeymap;
device->PumpEvents = QZ_PumpEvents;
May 28, 2006
May 28, 2006
167
168
device->SetCaption = QZ_SetCaption;
device->SetIcon = QZ_SetIcon;
169
device->IconifyWindow = QZ_IconifyWindow;
May 28, 2006
May 28, 2006
170
171
/*device->GetWMInfo = QZ_GetWMInfo; */
device->GrabInput = QZ_GrabInput;
Jan 22, 2002
Jan 22, 2002
172
May 28, 2006
May 28, 2006
173
device->CreateYUVOverlay = QZ_CreateYUVOverlay;
Jun 1, 2002
Jun 1, 2002
174
May 28, 2006
May 28, 2006
175
device->free = QZ_DeleteDevice;
Jan 22, 2002
Jan 22, 2002
176
177
178
179
return device;
}
May 28, 2006
May 28, 2006
180
181
182
static void
QZ_DeleteDevice (SDL_VideoDevice * device)
{
May 17, 2006
May 17, 2006
184
185
SDL_free (device->hidden);
SDL_free (device);
May 28, 2006
May 28, 2006
188
189
190
static int
QZ_VideoInit (_THIS, SDL_PixelFormat * video_format)
{
Jan 22, 2002
Jan 22, 2002
192
193
/* Initialize the video settings; this data persists between mode switches */
display_id = kCGDirectMainDisplay;
May 28, 2006
May 28, 2006
194
195
196
save_mode = CGDisplayCurrentMode (display_id);
mode_list = CGDisplayAvailableModes (display_id);
palette = CGPaletteCreateDefaultColorPalette ();
Jan 22, 2002
Jan 22, 2002
198
/* Gather some information that is useful to know about the display */
May 28, 2006
May 28, 2006
199
200
CFNumberGetValue (CFDictionaryGetValue
(save_mode, kCGDisplayBitsPerPixel),
Jan 22, 2002
Jan 22, 2002
201
kCFNumberSInt32Type, &device_bpp);
Jan 22, 2002
Jan 22, 2002
203
204
205
206
207
208
CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayWidth),
kCFNumberSInt32Type, &device_width);
CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayHeight),
kCFNumberSInt32Type, &device_height);
Mar 15, 2006
Mar 15, 2006
209
210
211
212
213
/* Determine the current screen size */
this->info.current_w = device_width;
this->info.current_h = device_height;
/* Determine the default screen depth */
Jan 22, 2002
Jan 22, 2002
214
215
video_format->BitsPerPixel = device_bpp;
Oct 5, 2002
Oct 5, 2002
216
217
/* Set misc globals */
current_grab_mode = SDL_GRAB_OFF;
May 28, 2006
May 28, 2006
218
219
cursor_should_be_visible = YES;
cursor_visible = YES;
Feb 15, 2004
Feb 15, 2004
220
current_mods = 0;
May 28, 2006
May 28, 2006
221
222
if (Gestalt (gestaltSystemVersion, &system_version) != noErr)
Mar 22, 2004
Mar 22, 2004
223
system_version = 0;
May 28, 2006
May 28, 2006
224
Dec 7, 2002
Dec 7, 2002
225
226
/* register for sleep notifications so wake from sleep generates SDL_VIDEOEXPOSE */
QZ_RegisterForSleepNotifications (this);
May 28, 2006
May 28, 2006
227
Jan 26, 2006
Jan 26, 2006
228
229
230
/* Fill in some window manager capabilities */
this->info.wm_available = 1;
Jan 22, 2002
Jan 22, 2002
231
return 0;
May 28, 2006
May 28, 2006
234
235
236
static SDL_Rect **
QZ_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags)
{
Jun 1, 2002
Jun 1, 2002
237
Jan 22, 2002
Jan 22, 2002
238
CFIndex num_modes;
239
240
241
CFIndex i;
int list_size = 0;
Jun 1, 2002
Jun 1, 2002
242
243
/* Any windowed mode is acceptable */
May 28, 2006
May 28, 2006
244
245
if ((flags & SDL_FULLSCREEN) == 0)
return (SDL_Rect **) - 1;
Jun 1, 2002
Jun 1, 2002
246
247
/* Free memory from previous call, if any */
May 28, 2006
May 28, 2006
248
if (client_mode_list != NULL) {
Jun 1, 2002
Jun 1, 2002
250
int i;
Oct 5, 2002
Oct 5, 2002
252
for (i = 0; client_mode_list[i] != NULL; i++)
May 17, 2006
May 17, 2006
253
SDL_free (client_mode_list[i]);
May 17, 2006
May 17, 2006
255
SDL_free (client_mode_list);
Oct 5, 2002
Oct 5, 2002
256
client_mode_list = NULL;
Jun 1, 2002
Jun 1, 2002
258
Jan 22, 2002
Jan 22, 2002
259
260
num_modes = CFArrayGetCount (mode_list);
261
/* Build list of modes with the requested bpp */
Aug 19, 2001
Aug 19, 2001
262
for (i = 0; i < num_modes; i++) {
Jun 1, 2002
Jun 1, 2002
263
Aug 19, 2001
Aug 19, 2001
264
CFDictionaryRef onemode;
May 28, 2006
May 28, 2006
265
CFNumberRef number;
Jun 1, 2002
Jun 1, 2002
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
int bpp;
onemode = CFArrayGetValueAtIndex (mode_list, i);
number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel);
CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);
if (bpp == format->BitsPerPixel) {
int intvalue;
int hasMode;
int width, height;
number = CFDictionaryGetValue (onemode, kCGDisplayWidth);
CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
width = (Uint16) intvalue;
number = CFDictionaryGetValue (onemode, kCGDisplayHeight);
CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
height = (Uint16) intvalue;
/* Check if mode is already in the list */
{
int i;
hasMode = SDL_FALSE;
for (i = 0; i < list_size; i++) {
May 28, 2006
May 28, 2006
291
if (client_mode_list[i]->w == width &&
Oct 5, 2002
Oct 5, 2002
292
client_mode_list[i]->h == height) {
Jun 1, 2002
Jun 1, 2002
293
294
295
hasMode = SDL_TRUE;
break;
}
Aug 19, 2001
Aug 19, 2001
296
297
}
}
Jun 1, 2002
Jun 1, 2002
298
299
/* Grow the list and add mode to the list */
May 28, 2006
May 28, 2006
300
if (!hasMode) {
Jun 1, 2002
Jun 1, 2002
301
302
303
304
305
SDL_Rect *rect;
list_size++;
Oct 5, 2002
Oct 5, 2002
306
if (client_mode_list == NULL)
May 28, 2006
May 28, 2006
307
308
309
client_mode_list = (SDL_Rect **)
SDL_malloc (sizeof (*client_mode_list) *
(list_size + 1));
Jun 1, 2002
Jun 1, 2002
310
else
May 28, 2006
May 28, 2006
311
312
313
314
client_mode_list = (SDL_Rect **)
SDL_realloc (client_mode_list,
sizeof (*client_mode_list) *
(list_size + 1));
Jun 1, 2002
Jun 1, 2002
315
May 28, 2006
May 28, 2006
316
317
rect = (SDL_Rect *)
SDL_malloc (sizeof (**client_mode_list));
Jun 1, 2002
Jun 1, 2002
318
Oct 5, 2002
Oct 5, 2002
319
if (client_mode_list == NULL || rect == NULL) {
Jun 1, 2002
Jun 1, 2002
320
321
322
323
SDL_OutOfMemory ();
return NULL;
}
Jan 2, 2006
Jan 2, 2006
324
rect->x = rect->y = 0;
Jun 1, 2002
Jun 1, 2002
325
326
327
rect->w = width;
rect->h = height;
May 28, 2006
May 28, 2006
328
329
client_mode_list[list_size - 1] = rect;
client_mode_list[list_size] = NULL;
Jan 22, 2002
Jan 22, 2002
330
}
Jun 1, 2002
Jun 1, 2002
333
Aug 19, 2001
Aug 19, 2001
334
335
336
337
/* Sort list largest to smallest (by area) */
{
int i, j;
for (i = 0; i < list_size; i++) {
May 28, 2006
May 28, 2006
338
for (j = 0; j < list_size - 1; j++) {
Jun 1, 2002
Jun 1, 2002
339
Aug 19, 2001
Aug 19, 2001
340
int area1, area2;
Oct 5, 2002
Oct 5, 2002
341
area1 = client_mode_list[j]->w * client_mode_list[j]->h;
May 28, 2006
May 28, 2006
342
343
area2 =
client_mode_list[j + 1]->w * client_mode_list[j + 1]->h;
Jun 1, 2002
Jun 1, 2002
344
Aug 19, 2001
Aug 19, 2001
345
if (area1 < area2) {
Oct 5, 2002
Oct 5, 2002
346
SDL_Rect *tmp = client_mode_list[j];
May 28, 2006
May 28, 2006
347
348
client_mode_list[j] = client_mode_list[j + 1];
client_mode_list[j + 1] = tmp;
Aug 19, 2001
Aug 19, 2001
349
350
351
352
}
}
}
}
Oct 5, 2002
Oct 5, 2002
353
return client_mode_list;
May 28, 2006
May 28, 2006
356
357
static SDL_bool
QZ_WindowPosition (_THIS, int *x, int *y)
Jul 23, 2003
Jul 23, 2003
358
{
May 28, 2006
May 28, 2006
359
360
361
const char *window = getenv ("SDL_VIDEO_WINDOW_POS");
if (window) {
if (sscanf (window, "%d,%d", x, y) == 2) {
Jul 23, 2003
Jul 23, 2003
362
363
364
365
366
367
return SDL_TRUE;
}
}
return SDL_FALSE;
}
May 28, 2006
May 28, 2006
368
369
370
static void
QZ_UnsetVideoMode (_THIS, BOOL to_desktop)
{
371
372
/* Reset values that may change between switches */
May 28, 2006
May 28, 2006
373
374
375
376
this->info.blit_fill = 0;
this->FillHWRect = NULL;
this->UpdateRects = NULL;
this->LockHWSurface = NULL;
Oct 5, 2002
Oct 5, 2002
377
this->UnlockHWSurface = NULL;
May 28, 2006
May 28, 2006
378
Jan 22, 2002
Jan 22, 2002
379
/* Release fullscreen resources */
May 28, 2006
May 28, 2006
380
if (mode_flags & SDL_FULLSCREEN) {
Jan 22, 2002
Jan 22, 2002
381
Aug 12, 2002
Aug 12, 2002
382
NSRect screen_rect;
May 28, 2006
May 28, 2006
383
Feb 1, 2003
Feb 1, 2003
384
/* Release double buffer stuff */
May 28, 2006
May 28, 2006
385
if (mode_flags & SDL_DOUBLEBUF) {
Feb 1, 2003
Feb 1, 2003
386
387
388
389
390
quit_thread = YES;
SDL_SemPost (sem1);
SDL_WaitThread (thread, NULL);
SDL_DestroySemaphore (sem1);
SDL_DestroySemaphore (sem2);
May 17, 2006
May 17, 2006
391
SDL_free (sw_buffers[0]);
Feb 1, 2003
Feb 1, 2003
392
}
May 28, 2006
May 28, 2006
393
Oct 5, 2002
Oct 5, 2002
394
/*
May 28, 2006
May 28, 2006
395
396
397
398
399
Release the OpenGL context
Do this first to avoid trash on the display before fade
*/
if (mode_flags & SDL_INTERNALOPENGL) {
Jan 22, 2002
Jan 22, 2002
400
QZ_TearDownOpenGL (this);
Oct 5, 2002
Oct 5, 2002
401
402
CGLSetFullScreen (NULL);
}
Feb 7, 2006
Feb 7, 2006
403
404
405
406
407
408
if (to_desktop) {
/* Restore original screen resolution/bpp */
CGDisplaySwitchToMode (display_id, save_mode);
CGReleaseAllDisplays ();
ShowMenuBar ();
/*
May 28, 2006
May 28, 2006
409
410
411
412
413
Reset the main screen's rectangle
See comment in QZ_SetVideoFullscreen for why we do this
*/
screen_rect = NSMakeRect (0, 0, device_width, device_height);
[[NSScreen mainScreen] setFrame:screen_rect];
Feb 7, 2006
Feb 7, 2006
414
}
Jan 22, 2002
Jan 22, 2002
416
/* Release window mode resources */
Jun 1, 2002
Jun 1, 2002
417
else {
May 28, 2006
May 28, 2006
418
419
420
[qz_window close];
[qz_window release];
Jun 1, 2002
Jun 1, 2002
421
qz_window = nil;
Oct 5, 2002
Oct 5, 2002
422
window_view = nil;
Oct 13, 2005
Oct 13, 2005
423
Jan 22, 2002
Jan 22, 2002
424
/* Release the OpenGL context */
May 28, 2006
May 28, 2006
425
if (mode_flags & SDL_INTERNALOPENGL)
Jan 22, 2002
Jan 22, 2002
426
QZ_TearDownOpenGL (this);
Jan 22, 2002
Jan 22, 2002
428
Aug 19, 2001
Aug 19, 2001
429
430
/* Signal successful teardown */
video_set = SDL_FALSE;
May 28, 2006
May 28, 2006
433
434
435
436
static SDL_Surface *
QZ_SetVideoFullScreen (_THIS, SDL_Surface * current, int width,
int height, int bpp, Uint32 flags)
{
Jan 2, 2006
Jan 2, 2006
437
boolean_t exact_match = 0;
Aug 12, 2002
Aug 12, 2002
438
NSRect screen_rect;
Feb 1, 2003
Feb 1, 2003
439
CGError error;
May 28, 2006
May 28, 2006
440
441
442
CGDisplayFadeReservationToken fade_token =
kCGDisplayFadeReservationInvalidToken;
Feb 7, 2006
Feb 7, 2006
443
444
/* Fade to black to hide resolution-switching flicker (and garbage
that is displayed by a destroyed OpenGL context, if applicable) */
May 28, 2006
May 28, 2006
445
446
447
if (CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess) {
CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
Feb 7, 2006
Feb 7, 2006
448
}
May 28, 2006
May 28, 2006
449
Oct 5, 2002
Oct 5, 2002
450
451
/* Destroy any previous mode */
if (video_set == SDL_TRUE)
Feb 7, 2006
Feb 7, 2006
452
QZ_UnsetVideoMode (this, FALSE);
Oct 5, 2002
Oct 5, 2002
453
454
/* See if requested mode exists */
Jun 1, 2002
Jun 1, 2002
455
456
457
mode = CGDisplayBestModeForParameters (display_id, bpp, width,
height, &exact_match);
458
/* Require an exact match to the requested mode */
May 28, 2006
May 28, 2006
459
460
461
if (!exact_match) {
SDL_SetError ("Failed to find display resolution: %dx%dx%d", width,
height, bpp);
462
463
goto ERR_NO_MATCH;
}
Aug 19, 2001
Aug 19, 2001
464
465
/* Put up the blanking window (a window above all other windows) */
Feb 1, 2003
Feb 1, 2003
466
467
468
469
if (getenv ("SDL_SINGLEDISPLAY"))
error = CGDisplayCapture (display_id);
else
error = CGCaptureAllDisplays ();
May 28, 2006
May 28, 2006
470
471
if (CGDisplayNoErr != error) {
472
473
474
SDL_SetError ("Failed capturing display");
goto ERR_NO_CAPTURE;
}
Jan 22, 2002
Jan 22, 2002
475
476
/* Do the physical switch */
May 28, 2006
May 28, 2006
477
if (CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode)) {
478
479
480
SDL_SetError ("Failed switching display resolution");
goto ERR_NO_SWITCH;
}
Jan 22, 2002
Jan 22, 2002
481
May 28, 2006
May 28, 2006
482
483
current->pixels = (Uint32 *) CGDisplayBaseAddress (display_id);
current->pitch = CGDisplayBytesPerRow (display_id);
Jun 11, 2001
Jun 11, 2001
485
current->flags = 0;
486
487
current->w = width;
current->h = height;
Jun 1, 2002
Jun 1, 2002
488
current->flags |= SDL_FULLSCREEN;
489
current->flags |= SDL_HWSURFACE;
Oct 5, 2002
Oct 5, 2002
490
current->flags |= SDL_PREALLOC;
May 28, 2006
May 28, 2006
491
492
493
this->UpdateRects = QZ_DirectUpdate;
this->LockHWSurface = QZ_LockHWSurface;
Oct 5, 2002
Oct 5, 2002
494
this->UnlockHWSurface = QZ_UnlockHWSurface;
Feb 1, 2003
Feb 1, 2003
495
496
/* Setup double-buffer emulation */
May 28, 2006
May 28, 2006
497
498
if (flags & SDL_DOUBLEBUF) {
Feb 1, 2003
Feb 1, 2003
499
/*
May 28, 2006
May 28, 2006
500
501
502
503
504
505
506
Setup a software backing store for reasonable results when
double buffering is requested (since a single-buffered hardware
surface looks hideous).
The actual screen blit occurs in a separate thread to allow
other blitting while waiting on the VBL (and hence results in higher framerates).
*/
Feb 1, 2003
Feb 1, 2003
507
508
509
this->LockHWSurface = NULL;
this->UnlockHWSurface = NULL;
this->UpdateRects = NULL;
May 28, 2006
May 28, 2006
510
511
current->flags |= (SDL_HWSURFACE | SDL_DOUBLEBUF);
Feb 1, 2003
Feb 1, 2003
512
513
514
515
516
this->UpdateRects = QZ_DoubleBufferUpdate;
this->LockHWSurface = QZ_LockDoubleBuffer;
this->UnlockHWSurface = QZ_UnlockDoubleBuffer;
this->FlipHWSurface = QZ_FlipDoubleBuffer;
May 17, 2006
May 17, 2006
517
current->pixels = SDL_malloc (current->pitch * current->h * 2);
Feb 1, 2003
Feb 1, 2003
518
519
520
521
if (current->pixels == NULL) {
SDL_OutOfMemory ();
goto ERR_DOUBLEBUF;
}
May 28, 2006
May 28, 2006
522
Feb 1, 2003
Feb 1, 2003
523
sw_buffers[0] = current->pixels;
May 28, 2006
May 28, 2006
524
525
526
sw_buffers[1] =
(Uint8 *) current->pixels + current->pitch * current->h;
Feb 1, 2003
Feb 1, 2003
527
528
529
quit_thread = NO;
sem1 = SDL_CreateSemaphore (0);
sem2 = SDL_CreateSemaphore (1);
May 28, 2006
May 28, 2006
530
thread = SDL_CreateThread ((int (*)(void *)) QZ_ThreadFlip, this);
Jun 1, 2002
Jun 1, 2002
532
May 28, 2006
May 28, 2006
533
if (CGDisplayCanSetPalette (display_id))
534
current->flags |= SDL_HWPALETTE;
Jun 1, 2002
Jun 1, 2002
535
536
/* Setup OpenGL for a fullscreen context */
May 1, 2006
May 1, 2006
537
if (flags & SDL_INTERNALOPENGL) {
538
539
540
CGLError err;
CGLContextObj ctx;
Jun 1, 2002
Jun 1, 2002
541
May 28, 2006
May 28, 2006
542
if (!QZ_SetupOpenGL (this, bpp, flags)) {
Jan 22, 2002
Jan 22, 2002
543
goto ERR_NO_GL;
Jun 1, 2002
Jun 1, 2002
545
May 28, 2006
May 28, 2006
546
ctx =[gl_context cglContext];
547
err = CGLSetFullScreen (ctx);
Jun 1, 2002
Jun 1, 2002
548
May 28, 2006
May 28, 2006
550
551
SDL_SetError ("Error setting OpenGL fullscreen: %s",
CGLErrorString (err));
552
553
goto ERR_NO_GL;
}
Jun 1, 2002
Jun 1, 2002
554
May 28, 2006
May 28, 2006
555
[gl_context makeCurrentContext];
Jan 22, 2002
Jan 22, 2002
556
557
558
glClear (GL_COLOR_BUFFER_BIT);
May 28, 2006
May 28, 2006
559
[gl_context flushBuffer];
Jun 1, 2002
Jun 1, 2002
560
May 1, 2006
May 1, 2006
561
current->flags |= SDL_INTERNALOPENGL;
562
563
564
565
}
/* If we don't hide menu bar, it will get events and interrupt the program */
HideMenuBar ();
Jan 22, 2002
Jan 22, 2002
566
Feb 7, 2006
Feb 7, 2006
567
/* Fade in again (asynchronously) */
May 28, 2006
May 28, 2006
568
569
570
571
if (fade_token != kCGDisplayFadeReservationInvalidToken) {
CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
CGReleaseDisplayFadeReservation (fade_token);
Feb 7, 2006
Feb 7, 2006
572
}
Jun 1, 2002
Jun 1, 2002
573
Aug 12, 2002
Aug 12, 2002
574
/*
May 28, 2006
May 28, 2006
575
576
577
578
579
580
581
582
There is a bug in Cocoa where NSScreen doesn't synchronize
with CGDirectDisplay, so the main screen's frame is wrong.
As a result, coordinate translation produces incorrect results.
We can hack around this bug by setting the screen rect
ourselves. This hack should be removed if/when the bug is fixed.
*/
screen_rect = NSMakeRect (0, 0, width, height);
[[NSScreen mainScreen] setFrame:screen_rect];
Aug 12, 2002
Aug 12, 2002
583
584
585
/* Save the flags to ensure correct tear-down */
mode_flags = current->flags;
Jun 1, 2002
Jun 1, 2002
586
Apr 13, 2006
Apr 13, 2006
587
/* Set app state, hide cursor if necessary, ... */
May 28, 2006
May 28, 2006
588
QZ_DoActivate (this);
Aug 18, 2005
Aug 18, 2005
589
590
591
return current;
Jun 1, 2002
Jun 1, 2002
592
/* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
May 28, 2006
May 28, 2006
593
594
595
596
597
598
599
600
601
602
ERR_NO_GL:
ERR_DOUBLEBUF:CGDisplaySwitchToMode (display_id, save_mode);
ERR_NO_SWITCH:CGReleaseAllDisplays ();
ERR_NO_CAPTURE:
ERR_NO_MATCH:if (fade_token != kCGDisplayFadeReservationInvalidToken) {
CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
CGReleaseDisplayFadeReservation (fade_token);
}
return NULL;
May 28, 2006
May 28, 2006
605
606
607
608
static SDL_Surface *
QZ_SetVideoWindowed (_THIS, SDL_Surface * current, int width,
int height, int *bpp, Uint32 flags)
{
Jun 11, 2001
Jun 11, 2001
609
unsigned int style;
Oct 5, 2002
Oct 5, 2002
610
NSRect contentRect;
Aug 10, 2003
Aug 10, 2003
611
BOOL isCustom = NO;
Jul 23, 2003
Jul 23, 2003
612
613
int center_window = 1;
int origin_x, origin_y;
May 28, 2006
May 28, 2006
614
615
CGDisplayFadeReservationToken fade_token =
kCGDisplayFadeReservationInvalidToken;
Jun 1, 2002
Jun 1, 2002
616
Jun 11, 2001
Jun 11, 2001
617
618
current->flags = 0;
current->w = width;
619
current->h = height;
May 28, 2006
May 28, 2006
620
Oct 5, 2002
Oct 5, 2002
621
contentRect = NSMakeRect (0, 0, width, height);
May 28, 2006
May 28, 2006
622
Oct 5, 2002
Oct 5, 2002
623
/*
May 28, 2006
May 28, 2006
624
625
626
627
628
629
Check if we should completely destroy the previous mode
- If it is fullscreen
- If it has different noframe or resizable attribute
- If it is OpenGL (since gl attributes could be different)
- If new mode is OpenGL, but previous mode wasn't
*/
Feb 7, 2006
Feb 7, 2006
630
631
632
633
if (video_set == SDL_TRUE) {
if (mode_flags & SDL_FULLSCREEN) {
/* Fade to black to hide resolution-switching flicker (and garbage
that is displayed by a destroyed OpenGL context, if applicable) */
May 28, 2006
May 28, 2006
634
635
636
637
638
if (CGAcquireDisplayFadeReservation (5, &fade_token) ==
kCGErrorSuccess) {
CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0,
TRUE);
Feb 7, 2006
Feb 7, 2006
639
640
}
QZ_UnsetVideoMode (this, TRUE);
May 28, 2006
May 28, 2006
641
642
643
} else if (((mode_flags ^ flags) & (SDL_NOFRAME | SDL_RESIZABLE)) ||
(mode_flags & SDL_INTERNALOPENGL) ||
(flags & SDL_INTERNALOPENGL)) {
Feb 7, 2006
Feb 7, 2006
644
645
646
QZ_UnsetVideoMode (this, TRUE);
}
}
May 28, 2006
May 28, 2006
647
Aug 10, 2003
Aug 10, 2003
648
649
650
651
/* Check for user-specified window and view */
{
char *windowPtrString = getenv ("SDL_NSWindowPointer");
char *viewPtrString = getenv ("SDL_NSQuickDrawViewPointer");
May 28, 2006
May 28, 2006
652
Aug 10, 2003
Aug 10, 2003
653
if (windowPtrString && viewPtrString) {
May 28, 2006
May 28, 2006
654
Aug 10, 2003
Aug 10, 2003
655
/* Release any previous window */
May 28, 2006
May 28, 2006
656
657
if (qz_window) {
[qz_window release];
Aug 10, 2003
Aug 10, 2003
658
659
qz_window = nil;
}
May 28, 2006
May 28, 2006
660
661
662
qz_window = (NSWindow *) atoi (windowPtrString);
window_view = (NSQuickDrawView *) atoi (viewPtrString);
Aug 10, 2003
Aug 10, 2003
663
isCustom = YES;
May 28, 2006
May 28, 2006
664
Aug 10, 2003
Aug 10, 2003
665
/*
May 28, 2006
May 28, 2006
666
667
668
669
670
671
Retain reference to window because we
might release it in QZ_UnsetVideoMode
*/
[qz_window retain];
style =[qz_window styleMask];
Aug 10, 2003
Aug 10, 2003
672
/* Check resizability */
May 28, 2006
May 28, 2006
673
if (style & NSResizableWindowMask)
Aug 10, 2003
Aug 10, 2003
674
current->flags |= SDL_RESIZABLE;
May 28, 2006
May 28, 2006
675
Aug 10, 2003
Aug 10, 2003
676
/* Check frame */
May 28, 2006
May 28, 2006
677
if (style & NSBorderlessWindowMask)
Aug 10, 2003
Aug 10, 2003
678
679
680
current->flags |= SDL_NOFRAME;
}
}
May 28, 2006
May 28, 2006
681
Oct 5, 2002
Oct 5, 2002
682
683
/* Check if we should recreate the window */
if (qz_window == nil) {
May 28, 2006
May 28, 2006
684
Oct 5, 2002
Oct 5, 2002
685
/* Set the window style based on input flags */
May 28, 2006
May 28, 2006
686
if (flags & SDL_NOFRAME) {
Oct 5, 2002
Oct 5, 2002
687
688
689
690
691
style = NSBorderlessWindowMask;
current->flags |= SDL_NOFRAME;
} else {
style = NSTitledWindowMask;
style |= (NSMiniaturizableWindowMask | NSClosableWindowMask);
May 28, 2006
May 28, 2006
692
if (flags & SDL_RESIZABLE) {
Oct 5, 2002
Oct 5, 2002
693
694
695
696
style |= NSResizableWindowMask;
current->flags |= SDL_RESIZABLE;
}
}
May 28, 2006
May 28, 2006
697
698
if (QZ_WindowPosition (this, &origin_x, &origin_y)) {
Jul 23, 2003
Jul 23, 2003
699
center_window = 0;
May 28, 2006
May 28, 2006
700
701
contentRect.origin.x = (float) origin_x;
contentRect.origin.y = (float) origin_y;
Jul 23, 2003
Jul 23, 2003
702
}
May 28, 2006
May 28, 2006
703
Oct 5, 2002
Oct 5, 2002
704
/* Manually create a window, avoids having a nib file resource */
May 28, 2006
May 28, 2006
705
706
qz_window =[[SDL_QuartzWindow alloc] initWithContentRect: contentRect styleMask: style backing: NSBackingStoreBuffered defer:NO];
Oct 5, 2002
Oct 5, 2002
707
708
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
Feb 7, 2006
Feb 7, 2006
709
if (fade_token != kCGDisplayFadeReservationInvalidToken) {
May 28, 2006
May 28, 2006
710
711
712
CGDisplayFade (fade_token, 0.5,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
Feb 7, 2006
Feb 7, 2006
713
714
CGReleaseDisplayFadeReservation (fade_token);
}
Oct 5, 2002
Oct 5, 2002
715
716
return NULL;
}
May 28, 2006
May 28, 2006
717
718
719
720
721
722
723
/*[ qz_window setReleasedWhenClosed:YES ]; */
QZ_SetCaption (this, this->wm_title, this->wm_icon);
[qz_window setAcceptsMouseMovedEvents:YES];
[qz_window setViewsNeedDisplay:NO];
if (center_window) {
[qz_window center];
Jul 23, 2003
Jul 23, 2003
724
}
May 28, 2006
May 28, 2006
725
726
[qz_window setDelegate:
[[[SDL_QuartzWindowDelegate alloc] init] autorelease]];
Oct 5, 2002
Oct 5, 2002
727
728
729
}
/* We already have a window, just change its size */
else {
May 28, 2006
May 28, 2006
730
Aug 10, 2003
Aug 10, 2003
731
if (!isCustom) {
May 28, 2006
May 28, 2006
732
733
734
[qz_window setContentSize:contentRect.size];
current->flags |= (SDL_NOFRAME | SDL_RESIZABLE) & mode_flags;
[window_view setFrameSize:contentRect.size];
Aug 10, 2003
Aug 10, 2003
735
}
Oct 5, 2002
Oct 5, 2002
736
}
Jun 1, 2002
Jun 1, 2002
737
Oct 5, 2002
Oct 5, 2002
738
/* For OpenGL, we bind the context to a subview */
May 28, 2006
May 28, 2006
739
if (flags & SDL_INTERNALOPENGL) {
Jun 1, 2002
Jun 1, 2002
740
May 28, 2006
May 28, 2006
741
if (!QZ_SetupOpenGL (this, *bpp, flags)) {
Feb 7, 2006
Feb 7, 2006
742
if (fade_token != kCGDisplayFadeReservationInvalidToken) {
May 28, 2006
May 28, 2006
743
744
745
CGDisplayFade (fade_token, 0.5,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
Feb 7, 2006
Feb 7, 2006
746
747
CGReleaseDisplayFadeReservation (fade_token);
}
748
749
return NULL;
}
Jun 1, 2002
Jun 1, 2002
750
May 28, 2006
May 28, 2006
751
752
753
754
755
756
757
758
window_view =[[NSView alloc] initWithFrame:contentRect];
[window_view setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
[[qz_window contentView] addSubview:window_view];
[gl_context setView:window_view];
[window_view release];
[gl_context makeCurrentContext];
[qz_window makeKeyAndOrderFront:nil];
May 1, 2006
May 1, 2006
759
current->flags |= SDL_INTERNALOPENGL;
Oct 5, 2002
Oct 5, 2002
761
/* For 2D, we set the subview to an NSQuickDrawView */
Nov 22, 2005
Nov 22, 2005
763
short qdbpp = 0;
Jun 1, 2002
Jun 1, 2002
764
Oct 5, 2002
Oct 5, 2002
765
766
/* Only recreate the view if it doesn't already exist */
if (window_view == nil) {
May 28, 2006
May 28, 2006
767
768
769
770
771
772
773
window_view =[[NSQuickDrawView alloc] initWithFrame:contentRect];
[window_view setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
[[qz_window contentView] addSubview:window_view];
[window_view release];
[qz_window makeKeyAndOrderFront:nil];
Oct 5, 2002
Oct 5, 2002
774
}
May 28, 2006
May 28, 2006
775
776
777
778
779
780
781
782
LockPortBits ([window_view qdPort]);
current->pixels =
GetPixBaseAddr (GetPortPixMap ([window_view qdPort]));
current->pitch =
GetPixRowBytes (GetPortPixMap ([window_view qdPort]));
qdbpp = GetPixDepth (GetPortPixMap ([window_view qdPort]));
UnlockPortBits ([window_view qdPort]);
Oct 5, 2002
Oct 5, 2002
783
Nov 22, 2005
Nov 22, 2005
784
785
786
/* QuickDraw may give a 16-bit shadow surface on 8-bit displays! */
*bpp = qdbpp;
787
788
current->flags |= SDL_SWSURFACE;
current->flags |= SDL_PREALLOC;
Sep 16, 2002
Sep 16, 2002
789
current->flags |= SDL_ASYNCBLIT;
May 28, 2006
May 28, 2006
790
Aug 10, 2003
Aug 10, 2003
791
/*
May 28, 2006
May 28, 2006
792
793
794
795
796
797
798
799
800
801
802
803
current->pixels now points to the window's pixels
We want it to point to the *view's* pixels
*/
{
int vOffset =[qz_window frame].size.height -
[window_view frame].size.height -[window_view frame].origin.y;
int hOffset =[window_view frame].origin.x;
current->pixels =
(Uint8 *) current->pixels + (vOffset * current->pitch) +
hOffset * (qdbpp / 8);
Aug 10, 2003
Aug 10, 2003
804
}
May 28, 2006
May 28, 2006
805
806
this->UpdateRects = QZ_UpdateRects;
this->LockHWSurface = QZ_LockWindow;
Sep 16, 2002
Sep 16, 2002
807
this->UnlockHWSurface = QZ_UnlockWindow;
Jun 1, 2002
Jun 1, 2002
809
Jan 22, 2002
Jan 22, 2002
810
811
/* Save flags to ensure correct teardown */
mode_flags = current->flags;
Jun 1, 2002
Jun 1, 2002
812
Feb 7, 2006
Feb 7, 2006
813
814
/* Fade in again (asynchronously) if we came from a fullscreen mode and faded to black */
if (fade_token != kCGDisplayFadeReservationInvalidToken) {
May 28, 2006
May 28, 2006
815
816
CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
Feb 7, 2006
Feb 7, 2006
817
818
819
CGReleaseDisplayFadeReservation (fade_token);
}
820
821
822
return current;
}
May 28, 2006
May 28, 2006
823
824
825
826
static SDL_Surface *
QZ_SetVideoMode (_THIS, SDL_Surface * current, int width,
int height, int bpp, Uint32 flags)
{
827
828
current->flags = 0;
Feb 24, 2004
Feb 24, 2004
829
current->pixels = NULL;
Jun 1, 2002
Jun 1, 2002
830
831
/* Setup full screen video */
May 28, 2006
May 28, 2006
832
833
834
if (flags & SDL_FULLSCREEN) {
current =
QZ_SetVideoFullScreen (this, current, width, height, bpp, flags);
835
836
837
838
839
840
if (current == NULL)
return NULL;
}
/* Setup windowed video */
else {
/* Force bpp to the device's bpp */
Jan 22, 2002
Jan 22, 2002
841
bpp = device_bpp;
May 28, 2006
May 28, 2006
842
843
current =
QZ_SetVideoWindowed (this, current, width, height, &bpp, flags);
844
845
846
if (current == NULL)
return NULL;
}
Jun 1, 2002
Jun 1, 2002
847
848
849
/* Setup the new pixel format */
{
May 28, 2006
May 28, 2006
850
int amask = 0, rmask = 0, gmask = 0, bmask = 0;
Jun 1, 2002
Jun 1, 2002
851
852
switch (bpp) {
May 28, 2006
May 28, 2006
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
case 16: /* (1)-5-5-5 RGB */
amask = 0;
rmask = 0x7C00;
gmask = 0x03E0;
bmask = 0x001F;
break;
case 24:
SDL_SetError ("24bpp is not available");
return NULL;
case 32: /* (8)-8-8-8 ARGB */
amask = 0x00000000;
rmask = 0x00FF0000;
gmask = 0x0000FF00;
bmask = 0x000000FF;
break;
Jun 1, 2002
Jun 1, 2002
869
May 28, 2006
May 28, 2006
870
if (!SDL_ReallocFormat (current, bpp, rmask, gmask, bmask, amask)) {
Jun 1, 2002
Jun 1, 2002
871
872
SDL_SetError ("Couldn't reallocate pixel format");
return NULL;
May 28, 2006
May 28, 2006
873
}
Jun 1, 2002
Jun 1, 2002
875
Jan 22, 2002
Jan 22, 2002
876
/* Signal successful completion (used internally) */
Aug 19, 2001
Aug 19, 2001
877
video_set = SDL_TRUE;
Jun 1, 2002
Jun 1, 2002
878
879
880
881
return current;
}
May 28, 2006
May 28, 2006
882
883
884
static int
QZ_ToggleFullScreen (_THIS, int on)
{
Jan 21, 2003
Jan 21, 2003
885
return 0;
May 28, 2006
May 28, 2006
888
889
890
static int
QZ_SetColors (_THIS, int first_color, int num_colors, SDL_Color * colors)
{
May 28, 2006
May 28, 2006
892
CGTableCount index;
893
CGDeviceColor color;
Jun 1, 2002
Jun 1, 2002
894
May 28, 2006
May 28, 2006
895
for (index = first_color; index < first_color + num_colors; index++) {
Jun 1, 2002
Jun 1, 2002
896
897
/* Clamp colors between 0.0 and 1.0 */
May 28, 2006
May 28, 2006
898
899
color.red = colors->r / 255.0;
color.blue = colors->b / 255.0;
900
color.green = colors->g / 255.0;
Jun 1, 2002
Jun 1, 2002
901
Jun 1, 2002
Jun 1, 2002
903
904
905
CGPaletteSetColorAtIndex (palette, color, index);
}
Jun 1, 2002
Jun 1, 2002
906
May 28, 2006
May 28, 2006
907
if (CGDisplayNoErr != CGDisplaySetPalette (display_id, palette))
Jun 1, 2002
Jun 1, 2002
909
910
911
912
return 1;
}
May 28, 2006
May 28, 2006
913
914
915
static int
QZ_LockDoubleBuffer (_THIS, SDL_Surface * surface)
{
Feb 1, 2003
Feb 1, 2003
916
917
918
919
return 1;
}
May 28, 2006
May 28, 2006
920
921
922
static void
QZ_UnlockDoubleBuffer (_THIS, SDL_Surface * surface)
{
Feb 1, 2003
Feb 1, 2003
923
924
925
926
}
/* The VBL delay is based on code by Ian R Ollmann's RezLib <iano@cco.caltech.edu> */
May 28, 2006
May 28, 2006
927
928
929
930
static AbsoluteTime
QZ_SecondsToAbsolute (double seconds)
{
Feb 1, 2003
Feb 1, 2003
931
932
union
{
Jan 4, 2004
Jan 4, 2004
933
UInt64 i;
Feb 1, 2003
Feb 1, 2003
934
935
Nanoseconds ns;
} temp;
May 28, 2006
May 28, 2006
936
Feb 1, 2003
Feb 1, 2003
937
temp.i = seconds * 1000000000.0;
May 28, 2006
May 28, 2006
938
939
return NanosecondsToAbsolute (temp.ns);
Feb 1, 2003
Feb 1, 2003
940
941
}
May 28, 2006
May 28, 2006
942
943
944
static int
QZ_ThreadFlip (_THIS)
{
Feb 1, 2003
Feb 1, 2003
945
946
947
Uint8 *src, *dst;
int skip, len, h;
May 28, 2006
May 28, 2006
948
Feb 1, 2003
Feb 1, 2003
949
/*
May 28, 2006
May 28, 2006
950
951
952
Give this thread the highest scheduling priority possible,
in the hopes that it will immediately run after the VBL delay
*/
Feb 1, 2003
Feb 1, 2003
953
954
955
956
{
pthread_t current_thread;
int policy;
struct sched_param param;
May 28, 2006
May 28, 2006
957
Feb 1, 2003
Feb 1, 2003
958
959
960
961
962
963
current_thread = pthread_self ();
pthread_getschedparam (current_thread, &policy, &param);
policy = SCHED_RR;
param.sched_priority = sched_get_priority_max (policy);
pthread_setschedparam (current_thread, policy, &param);
}
May 28, 2006
May 28, 2006
964
Feb 1, 2003
Feb 1, 2003
965
while (1) {
May 28, 2006
May 28, 2006
966
Feb 1, 2003
Feb 1, 2003
967
968
969
SDL_SemWait (sem1);
if (quit_thread)
return 0;
May 28, 2006
May 28, 2006
970
Jan 2, 2006
Jan 2, 2006
971
972
973
974
975
976
/*
* We have to add SDL_VideoSurface->offset here, since we might be a
* smaller surface in the center of the framebuffer (you asked for
* a fullscreen resolution smaller than the hardware could supply
* so SDL is centering it in a bigger resolution)...
*/
May 28, 2006
May 28, 2006
977
978
979
dst =
(Uint8 *) CGDisplayBaseAddress (display_id) +
SDL_VideoSurface->offset;
Jan 2, 2006
Jan 2, 2006
980
src = current_buffer + SDL_VideoSurface->offset;
Feb 1, 2003
Feb 1, 2003
981
982
983
len = SDL_VideoSurface->w * SDL_VideoSurface->format->BytesPerPixel;
h = SDL_VideoSurface->h;
skip = SDL_VideoSurface->pitch;
May 28, 2006
May 28, 2006
984
Feb 1, 2003
Feb 1, 2003
985
986
/* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */
{
May 28, 2006
May 28, 2006
987
Feb 1, 2003
Feb 1, 2003
988
989
990
991
992
993
/* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */
double refreshRate;
double linesPerSecond;
double target;
double position;
double adjustment;
May 28, 2006
May 28, 2006
994
AbsoluteTime nextTime;
Feb 1, 2003
Feb 1, 2003
995
CFNumberRef refreshRateCFNumber;
May 28, 2006
May 28, 2006
996
997
998
999
refreshRateCFNumber =
CFDictionaryGetValue (mode, kCGDisplayRefreshRate);
if (NULL == refreshRateCFNumber) {
Feb 1, 2003
Feb 1, 2003
1000
SDL_SetError ("Mode has no refresh rate");