/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (Β“Wolf ET Source CodeΒ”).
Wolf ET Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Wolf ET Source Code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wolf ET Source Code. If not, see .
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include
Q3DEF_BEGIN
#include "../renderer/tr_local.h"
#include "../client/client.h"
#include "mac_local.h"
Q3DEF_END
#define MacWarning Sys_Warning
#define MacFatalError Sys_Error
#ifndef AGL_SAMPLES_ARB
#define AGL_SAMPLE_BUFFERS_ARB 55 /* number of multi sample buffers */
#define AGL_SAMPLES_ARB 56 /* number of samples per multi sample buffer */
#endif
#define USE_AGL_FULLSCREEN 0
//=====================================================================
// Includes
#include "AGLUtils.h"
#include "CDrawSprocket.h"
//=====================================================================
// Global Variables
Fixed aglFrequency; // Monitor frequency, set in main() from the prefs
AGLContext gAGLContext; // The currently active drawing context, either primary or secondary
AGLContext gAGLContext_Primary; // Primary context, used in non-SMP situations or in the main thread
AGLContext gAGLContext_Secondary; // Secondary context, used mainly for an SMP thread
AGLPixelFormat gPixelFormat;
//=====================================================================
// Local Variables
static WindowRef sBlankingWindow; // Used only for AGL_FULLSCREEN cases, to blank out the desktop
static WindowRef sGLWindow; // In non-AGL_FULLSCREEN cases, contains the GL drawable window
static Rect sGLWindowRect;
static RGBColor sRGBWhite = { 0xFFFF, 0xFFFF, 0xFFFF };
static RGBColor sRGBBlack = { 0x0000, 0x0000, 0x0000 };
static Boolean sAGLActive = false; // True if a drawable is active
static long sSystemVersion;
static CGrafPtr sCurrentAGLPort;
static DisplayIDType glMonitor;
/*static*/ short glWidth, glHeight;
static int glFrequency; // Same as aglFrequency, only in int form
static EventHandlerUPP sWindowEventHandlerUPP; // carbon window constrain event handler
static EventHandlerRef sEventHandlerRef; // event handler reference
//=====================================================================
// Implementation
OSStatus MySetWindowContentColor( WindowRef inWindow, RGBColor const *inRGB ) {
OSStatus status = noErr;
// LBO - the following routine requires 8.5 in non-Carbon builds (8.1 in Carbon)
status = SetWindowContentColor( inWindow, inRGB );
return status;
}
//===============================================================================
// appWindowEventHandler
//
// This event handler is installed by InitCarbonEvents (below) to prevent
// Carbon from moving our windows when they're offscreen. This is most noticable
// when we've set up a blanking window that covers the entire gray region.
//===============================================================================
static pascal OSStatus appWindowEventHandler( EventHandlerCallRef myHandler, EventRef event, void* userData ) {
#pragma unused (myHandler, userData)
OSStatus result = eventNotHandledErr;
UInt32 eventKind;
eventKind = GetEventKind( event );
switch ( eventKind )
{
case kEventWindowConstrain:
{
// We handled the event, eat it
result = noErr;
break;
}
}
return result;
}
void InstallCarbonWindowEvents( WindowRef inWindow ) {
OSStatus status;
EventTypeSpec list[] = { {kEventClassWindow, kEventWindowConstrain } };
// If we don't support Carbon events, bail
if ( (Ptr) InstallEventHandler == (Ptr) kUnresolvedCFragSymbolAddress ) {
return;
}
// Install an application event handler
if ( sWindowEventHandlerUPP == NULL ) {
sWindowEventHandlerUPP = NewEventHandlerUPP( appWindowEventHandler );
if ( !sWindowEventHandlerUPP ) {
SysBeep( 0 ); return;
}
}
status = InstallWindowEventHandler( inWindow, sWindowEventHandlerUPP, 1, list, 0, &sEventHandlerRef );
if ( status != noErr ) {
SysBeep( 0 );
}
}
void DisposeCarbonWindowEvents( void ) {
if ( sEventHandlerRef == NULL ) {
return;
}
(void)RemoveEventHandler( sEventHandlerRef );
sEventHandlerRef = NULL;
if ( sWindowEventHandlerUPP != NULL ) {
DisposeEventHandlerUPP( sWindowEventHandlerUPP );
}
sWindowEventHandlerUPP = NULL;
}
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
// _aglSetGameContext
//
// Given an already chosen AGL context and monitor, this routine will take care of the bs
// involved with choosing a properly-sized window (on non-fullscreen devices) and it
// will activate a fullscreen context if desired for those devices that support that option.
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
GLboolean _aglSetGameContext( short inWidth, short inHeight, short inDepth, short inAGLDepth, short inStencilDepth,
Fixed inFreq, DisplayIDType inDevice, Boolean inWindow, int inFSAASamples ) {
GLint result;
GLboolean ok;
GDHandle device;
GLint attrib[] = { AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_NO_RECOVERY,
AGL_FULLSCREEN,
AGL_ACCELERATED,
AGL_RED_SIZE, 8,
AGL_GREEN_SIZE, 8,
AGL_BLUE_SIZE, 8,
AGL_ALPHA_SIZE, 0,
AGL_DEPTH_SIZE, 16,
AGL_STENCIL_SIZE, 0,
#if TEST_SMP
AGL_MP_SAFE,
#endif
#if TEST_FSAA
AGL_SAMPLES_ARB, 4,
AGL_SAMPLE_BUFFERS_ARB, 1,
#endif
AGL_NONE };
short depth, pageCount;
Fixed frequency;
OSErr err;
WindowAttributes winAttrib;
GLenum glErr;
// Are we on 10?
err = Gestalt( gestaltSystemVersion, &sSystemVersion );
#if MAC_DEBUG && SINGLE_BUFFER
attrib[1] = AGL_NONE;
#endif
if ( !gDrawSprocket ) {
return GL_FALSE;
}
glFrequency = Fix2X( inFreq );
glMonitor = inDevice;
glWidth = inWidth;
glHeight = inHeight;
sCurrentAGLPort = NULL;
#if !USE_AGL_FULLSCREEN
attrib[3] = AGL_ACCELERATED;
#endif
// AGL_RED/GREEN/BLUE_SIZE
if ( inDepth <= 16 ) {
// 15/16 default to 555 RGB
attrib[6] = attrib[8] = attrib[10] = 5;
}
// AGL_DEPTH_SIZE
if ( inAGLDepth ) {
attrib[14] = inAGLDepth;
} else {
attrib[14] = inDepth;
}
// AGL_STENCIL_SIZE
if ( inStencilDepth ) {
attrib[16] = inStencilDepth;
}
DMGetGDeviceByDisplayID( inDevice, &device, false );
if ( device == NULL ) {
device = GetMainDevice();
}
if ( gAGLContext ) {
_aglDisposeGameContext();
}
#if TEST_SMP
// There is no AGL_MP_SAFE renderer on MacOS 8/9
if ( sSystemVersion < 0x01000 ) {
attrib[17] = AGL_NONE;
}
#endif
// If our monitor is set to 8-bit under MacOS 8 or 9, we have to change that for OpenGL to
// find a valid context.
if ( sSystemVersion < 0x01000 ) {
int curDepth = ( **( ( **device ).gdPMap ) ).pixelSize;
if ( curDepth == 8 ) {
if ( err = HasDepth( device, 8, 1, 1 ) ) {
if ( inDepth == 16 ) {
err = SetDepth( device, 16, 1, 1 );
} else {
err = SetDepth( device, 32, 1, 1 );
}
}
if ( err ) {
MacWarning( "This game requires a color monitor that supports thousands or millions of colors" );
}
}
}
#if TEST_FSAA
// If < 10.2 or no samples, don't ask for them
if ( ( sSystemVersion < 0x01020 ) || ( inFSAASamples == 0 ) ) {
attrib[18] = AGL_NONE;
attrib[19] = AGL_NONE;
attrib[20] = AGL_NONE;
attrib[21] = AGL_NONE;
} else
{
attrib[19] = inFSAASamples;
}
#endif
#if 1 // !USE_AGL_FULLSCREEN
// attrib[5] = AGL_ACCELERATED;
gPixelFormat = aglChoosePixelFormat( &device, 1, attrib );
#else
if ( sSystemVersion < 0x01000 ) {
// Under MacOS 8/9, the 3dfx driver is the only card to support agl
// fullscreen. It's deprecated and buggy, so we must set it up the "wrong" way
// to get agl fullscreen to work, otherwise the system will freak out and crash
// badly in the aglChoosePixelFormat call below.
attrib[3] = AGL_ACCELERATED;
gPixelFormat = aglChoosePixelFormat( &device, 1, attrib );
} else
{
// Since we're trying for AGL_FULLSCREEN, we must set the first 2 params to 0
gPixelFormat = aglChoosePixelFormat( NULL, 0, attrib );
// If it failed, try again without AGL_FULLSCREEN
if ( gPixelFormat == NULL ) {
attrib[3] = AGL_ACCELERATED;
gPixelFormat = aglChoosePixelFormat( &device, 1, attrib );
}
}
#endif
if ( gPixelFormat == NULL ) {
MacWarning( "aglChoosePixelFormat failed" );
return GL_FALSE;
}
// Create an AGL context
gAGLContext_Primary = aglCreateContext( gPixelFormat, NULL );
if ( !gAGLContext_Primary ) {
MacWarning( "aglCreateContext failed" );
return GL_FALSE;
}
#if TEST_SMP
gAGLContext_Secondary = aglCreateContext( gPixelFormat, gAGLContext_Primary );
if ( !gAGLContext_Secondary ) {
MacWarning( "aglCreateContext (alt) failed" );
}
#endif
// Make the primary context the current context
_aglUsePrimaryContext();
// If we found a fullscreen device, see if the renderer supports it.
// This is pretty dumb, but on OSX it can be mutually exclusive due to a bug in OpenGL
if ( attrib[3] == AGL_FULLSCREEN ) {
AGLRendererInfo info;
info = aglQueryRendererInfo( &device, 1 );
if ( !info ) {
MacWarning( "aglQueryRendererInfo failed" );
return GL_FALSE;
}
// is this a fullscreen device?
ok = aglDescribeRenderer( info, AGL_FULLSCREEN, &result );
aglDestroyRendererInfo( info );
} else {
result = 0;
}
if ( gUseCarbonEvents ) {
winAttrib = kWindowStandardHandlerAttribute;
} else {
winAttrib = kWindowNoAttributes;
}
// Burp the agl error handler. We could have encountered errors above and worked around them
// so we need to toss any errors currently pending.
glErr = aglGetError();
// If it is a fullscreen renderer and we want to run fullscreen, set up a fullscreen context.
// We don't use DrawSprocket for fullscreen contexts (e.g. 3dfx) because
// a) it's not strictly necessary and b) the aglSetFullScreen call can
// confuse DrawSprocket and cause the Finder to mangle the desktop icons
// The downside of this is that there are no gamma fades around the res switch
// when we're running on 3dfx hardware - yet.
if ( result && !inWindow ) {
OSStatus status;
Rect desktopRect;
CGrafPtr oldPort;
// Get a rect that covers the entire desktop
GetRegionBounds( GetGrayRgn(), &desktopRect );
// Create a blanking window to hide everything
#if TARGET_API_MAC_CARBON
{
status = CreateNewWindow( kDocumentWindowClass, winAttrib, &desktopRect, &sBlankingWindow );
if ( status ) {
MacWarning( "CreateNewWindow failed" );
return GL_FALSE;
}
glMonitor = 0;
}
#else
sBlankingWindow = NewCWindow( NULL, &desktopRect, "\p", false, noGrowDocProc, ( WindowRef ) - 1, false, 0 );
if ( !sBlankingWindow ) {
return GL_FALSE;
}
#endif
GetPort( &oldPort );
// Clear the window to black, then show it
SetPortWindowPort( sBlankingWindow );
RGBForeColor( &sRGBBlack );
RGBBackColor( &sRGBWhite );
status = MySetWindowContentColor( sBlankingWindow, &sRGBBlack );
ShowWindow( sBlankingWindow );
SetPort( oldPort );
sCurrentAGLPort = ( CGrafPtr ) - 1;
ok = aglSetFullScreen( gAGLContext, glWidth, glHeight, glFrequency, glMonitor );
// That tanked, try a different frequency
if ( !ok ) {
ok = aglSetFullScreen( gAGLContext, glWidth, glHeight, 60.0, glMonitor );
}
if ( !ok ) {
ok = aglSetFullScreen( gAGLContext, glWidth, glHeight, 75.0, glMonitor );
}
#if 0
// If that stuff failed, let's try leaving out the monitor
if ( !ok ) {
ok = aglSetFullScreen( gAGLContext, glWidth, glHeight, 60.0, 0 );
}
if ( !ok ) {
ok = aglSetFullScreen( gAGLContext, glWidth, glHeight, 75.0, 0 );
}
#endif
if ( !ok ) {
MacFatalError( "aglSetFullScreen failed. Try specifying a different refresh rate." );
return GL_FALSE;
}
#if MAC_Q3
#if MAC_JKJA
VID_Printf( PRINT_ALL, "...AGL_FULLSCREEN, %dx%d at %dHz\n", glWidth, glHeight, glFrequency );
#else
ri.Printf( PRINT_ALL, "...AGL_FULLSCREEN, %dx%d at %dHz\n", glWidth, glHeight, glFrequency );
#endif
#endif
sAGLActive = true;
sGLWindowRect.top = sGLWindowRect.left = 0;
sGLWindowRect.right = glWidth;
sGLWindowRect.bottom = glHeight;
} else
{
short windowType;
Str32 winTitle;
OSStatus status;
if ( !inWindow ) {
GDHandle newDevice;
short outWidth, outHeight, outDepth, outPageCount;
Fixed outFreq;
// if (!gDrawSprocket->SwitchToResolution (inWidth, inHeight, inDepth, inFreq, 1, true)) return GL_FALSE;
gDrawSprocket->ConfigureGameContext( inWidth, inHeight, inDepth, inFreq, 1 );
gDrawSprocket->SwitchToGameContext( true );
newDevice = gDrawSprocket->GetGDevice();
if ( newDevice ) {
sGLWindowRect.top = ( *newDevice )->gdRect.top;
sGLWindowRect.left = ( *newDevice )->gdRect.left;
} else
{
#if MAC_Q3
#if MAC_JKJA
Cvar_Set( "r_mode", "3" );
#else
ri.Cvar_Set( "r_mode", "3" );
#endif
GLimp_Shutdown();
GLimp_Init();
#endif
}
gDrawSprocket->GetGameResolution( &outWidth, &outHeight, &outDepth, &outFreq, &outPageCount );
#if MAC_Q3
#if MAC_JKJA
VID_Printf( PRINT_ALL, "...DSp context, %dx%d, %d bit, %d pages\n", outWidth, outHeight, outDepth, outPageCount );
#else
ri.Printf( PRINT_ALL, "...DSp context, %dx%d, %d bit, %d pages\n", outWidth, outHeight, outDepth, outPageCount );
#endif
#endif
windowType = plainDBox;
} else
{
// Center the window
sGLWindowRect.left = ( ( ( *device )->gdRect.right - ( *device )->gdRect.left ) - glWidth ) / 2;
sGLWindowRect.top = ( ( ( *device )->gdRect.bottom - ( *device )->gdRect.top ) - glHeight ) / 2;
windowType = noGrowDocProc;
}
// create a window to draw into
if ( !inWindow ) {
DSpContextReference gameContext;
gameContext = gDrawSprocket->GetCurrentContext();
// DSpContext_LocalToGlobal (gameContext, (Point *)&sGLWindowRect);
gDrawSprocket->FadeGammaUp( true );
} else
{
sGLWindowRect.left += ( **device ).gdRect.left;
sGLWindowRect.top += ( **device ).gdRect.top;
}
sGLWindowRect.right = sGLWindowRect.left + glWidth;
sGLWindowRect.bottom = sGLWindowRect.top + glHeight;
sprintf( (char *)winTitle, "%s", kGameName );
c2pstrcpy( winTitle, (const char *)winTitle );
#if TARGET_API_MAC_CARBON
{
// On 10, we can attach a drawable directly to a DSp CGrafPtr
// On < 10, we have to use a blanking window instead.
if ( inWindow ) {
CreateNewWindow( kDocumentWindowClass, winAttrib, &sGLWindowRect, &sGLWindow );
} else if ( sSystemVersion < 0x01000 ) {
// CreateNewWindow (kPlainWindowClass, winAttrib, &sGLWindowRect, &sGLWindow);
// CreateNewWindow (kDocumentWindowClass, winAttrib, &sGLWindowRect, &sGLWindow);
// Always create a window on classic
sGLWindow = NewCWindow( NULL, &sGLWindowRect, winTitle, 0, windowType, ( WindowRef ) - 1, 0, 0 );
if ( sGLWindow == NULL ) {
return GL_FALSE;
}
// InstallCarbonWindowEvents (sGLWindow);
} else {
sGLWindow = NULL;
}
}
#else
// Always create a window on classic
sGLWindow = NewCWindow( NULL, &sGLWindowRect, winTitle, 0, windowType, ( WindowRef ) - 1, 0, 0 );
if ( sGLWindow == NULL ) {
return GL_FALSE;
}
#endif
// Attach the agl context
if ( sGLWindow ) {
CGrafPtr oldPort;
GetPort( &oldPort );
SetPortWindowPort( sGLWindow );
RGBForeColor( &sRGBBlack );
RGBBackColor( &sRGBWhite );
SetPort( oldPort );
SetWTitle( sGLWindow, kGameNameP );
// status = MySetWindowContentColor (sGLWindow, &sRGBBlack);
ShowWindow( sGLWindow );
BringToFront( sGLWindow );
sCurrentAGLPort = GetWindowPort( sGLWindow );
ok = aglSetDrawable( gAGLContext, sCurrentAGLPort );
#if 0 //TEST_SMP
ok = aglSetDrawable( gAltAGLContext, sCurrentAGLPort );
#endif
} else
{
// use DSp's front buffer on Mac OS X
sCurrentAGLPort = gDrawSprocket->GetFrontBuffer();
if ( sCurrentAGLPort == NULL ) {
// ReportError ("DSpContext_GetFrontBuffer() had an error.");
return NULL;
}
// there is a problem in Mac OS X GM CoreGraphics that may not size the port pixmap correctly
// this will check the vertical sizes and offset if required to fix the problem
// this will not center ports that are smaller then a particular resolution
{
long deltaV, deltaH;
Rect portBounds;
PixMapHandle hPix = GetPortPixMap( sCurrentAGLPort );
Rect pixBounds = ( **hPix ).bounds;
GetPortBounds( sCurrentAGLPort, &portBounds );
deltaV = ( portBounds.bottom - portBounds.top ) - ( pixBounds.bottom - pixBounds.top ) +
( portBounds.bottom - portBounds.top - glHeight ) / 2;
deltaH = -( portBounds.right - portBounds.left - glWidth ) / 2;
if ( deltaV || deltaH ) {
GrafPtr pPortSave;
GetPort( &pPortSave );
SetPort( (GrafPtr)sCurrentAGLPort );
// set origin to account for CG offset and if requested drawable smaller than screen rez
SetOrigin( deltaH, deltaV );
SetPort( pPortSave );
}
}
ok = aglSetDrawable( gAGLContext, sCurrentAGLPort );
#if 0 //TEST_SMP
ok = aglSetDrawable( gAltAGLContext, sCurrentAGLPort );
#endif
}
if ( !ok ) {
MacWarning( "aglSetDrawable failed" );
return GL_FALSE;
}
sAGLActive = true;
}
return GL_TRUE;
}
void _aglDisposeGameContext( void ) {
if ( gAGLContext_Primary ) {
aglSetCurrentContext( NULL );
aglSetDrawable( gAGLContext_Primary, NULL );
aglDestroyContext( gAGLContext_Primary );
gAGLContext_Primary = NULL;
}
#if TEST_SMP
if ( gAGLContext_Secondary ) {
aglSetDrawable( gAGLContext_Secondary, NULL );
aglDestroyContext( gAGLContext_Secondary );
gAGLContext_Secondary = NULL;
}
#endif
gAGLContext = NULL;
sAGLActive = false;
if ( sGLWindow ) {
DisposeWindow( sGLWindow );
sGLWindow = NULL;
}
if ( sBlankingWindow ) {
DisposeWindow( sBlankingWindow );
sBlankingWindow = NULL;
}
if ( gPixelFormat ) {
// Pixel format is no longer needed
aglDestroyPixelFormat( gPixelFormat );
gPixelFormat = NULL;
}
}
GLboolean _aglSuspendGameContext( void ) {
GLboolean result;
if ( sAGLActive == false ) {
return GL_TRUE;
}
if ( !gAGLContext ) {
return GL_TRUE;
}
// gDrawSprocket->FadeGammaDownImmediate (true);
result = aglSetDrawable( gAGLContext, NULL );
#if TEST_SMP
// (void)aglSetDrawable (gAltAGLContext, NULL);
#endif
#if 0
if ( r_fullscreen->integer ) {
// If we're using DSp on OSX, we need to pause the context so we can see dialogs
if ( ( sSystemVersion >= 0x01000 ) && !sGLWindow && !sBlankingWindow ) {
if ( gDrawSprocket->GetState() == kDSpContextState_Active ) {
gDrawSprocket->SetState( kDSpContextState_Paused );
}
}
gDrawSprocket->FadeGammaUpImmediate( true );
}
#endif
#if 0
// Are we using AGL_FULLSCREEN?
if ( sBlankingWindow ) {
// Yes, give some time for the monitor to adjust to the new res.
UInt32 tickCount;
Delay( 60, &tickCount );
}
#endif
// InitCursor ();
sAGLActive = false;
return result;
}
CGrafPtr _aglGetCurrentPort( void ) {
if ( sGLWindow ) {
// Running in a window
return GetWindowPort( sGLWindow );
} else if ( sBlankingWindow ) {
// Using aglSetFullscreen
return ( CGrafPtr ) - 1;
} else
{
// Using DrawSprocket fullscreen
return gDrawSprocket->GetFrontBuffer();
}
}
GLboolean _aglResumeGameContext( void ) {
GLboolean result = GL_FALSE;
if ( !gAGLContext ) {
return GL_TRUE;
}
if ( r_fullscreen->integer ) {
/*
CGDirectDisplayID displayID;
displayID = (CGDirectDisplayID)sys_gl.displayID;
if ( displayID == 0 ) {
displayID = kCGDirectMainDisplay;
}
CGDisplayHideCursor( displayID );
// HideCursor();
*/
gDrawSprocket->FadeGammaDownImmediate( true );
}
if ( sGLWindow ) {
// the blanking window can get shoved offscreen when the movie context
// becomes active, put it back where it belongs - jb, 3/25/01
#undef MoveWindow
MoveWindow( sGLWindow, sGLWindowRect.left, sGLWindowRect.top, false );
// The blanking window can get moved in priority, bump it to the front
BringToFront( sGLWindow );
result = aglSetDrawable( gAGLContext, GetWindowPort( sGLWindow ) );
} else if ( sBlankingWindow ) {
// The blanking window can get moved in priority, bump it to the front
BringToFront( sBlankingWindow );
// Set the agl context for fullscreen instead of a window
result = aglSetFullScreen( gAGLContext, glWidth, glHeight, glFrequency, glMonitor );
// That tanked, try a different frequency
if ( !result ) {
result = aglSetFullScreen( gAGLContext, glWidth, glHeight, 60.0, glMonitor );
}
if ( !result ) {
result = aglSetFullScreen( gAGLContext, glWidth, glHeight, 75.0, glMonitor );
}
}
#if TARGET_API_MAC_CARBON
else
{
#if 0
// If we're using DSp on OSX, we need to reactivate the context
if ( ( sSystemVersion >= 0x01000 ) && ( r_fullscreen->integer ) ) {
if ( gDrawSprocket->GetState() == kDSpContextState_Paused ) {
gDrawSprocket->SetState( kDSpContextState_Active );
}
}
#endif
{
CGrafPtr pPort;
// use DSp's front buffer on Mac OS X
pPort = gDrawSprocket->GetFrontBuffer();
if ( pPort == NULL ) {
// ReportError ("DSpContext_GetFrontBuffer() had an error.");
return result;
}
// there is a problem in Mac OS X GM CoreGraphics that may not size the port pixmap correctly
// this will check the vertical sizes and offset if required to fix the problem
// this will not center ports that are smaller then a particular resolution
{
long deltaV, deltaH;
Rect portBounds;
PixMapHandle hPix = GetPortPixMap( pPort );
Rect pixBounds = ( **hPix ).bounds;
GetPortBounds( pPort, &portBounds );
deltaV = ( portBounds.bottom - portBounds.top ) - ( pixBounds.bottom - pixBounds.top ) +
( portBounds.bottom - portBounds.top - glHeight ) / 2;
deltaH = -( portBounds.right - portBounds.left - glWidth ) / 2;
if ( deltaV || deltaH ) {
GrafPtr pPortSave;
GetPort( &pPortSave );
SetPort( (GrafPtr)pPort );
// set origin to account for CG offset and if requested drawable smaller than screen rez
SetOrigin( deltaH, deltaV );
SetPort( pPortSave );
}
}
result = aglSetDrawable( gAGLContext, pPort );
}
}
#endif
if ( r_fullscreen->integer ) {
gDrawSprocket->FadeGammaUpImmediate( true );
}
sAGLActive = true;
return result;
}
void _aglUsePrimaryContext( void ) {
GLboolean ok;
if ( gAGLContext_Primary == NULL ) {
#if MAC_DEBUG && TEST_SMP
Debugger();
#endif
return;
}
gAGLContext = gAGLContext_Primary;
ok = aglSetDrawable( gAGLContext_Secondary, NULL );
ok = aglSetCurrentContext( gAGLContext );
if ( !ok ) {
MacWarning( "aglSetCurrentContext failed" );
}
}
void _aglUseSecondaryContext( void ) {
GLboolean ok;
if ( gAGLContext_Secondary == NULL ) {
#if MAC_DEBUG && TEST_SMP
Debugger();
#endif
return;
}
gAGLContext = gAGLContext_Secondary;
ok = aglSetDrawable( gAGLContext_Primary, NULL );
ok = aglSetCurrentContext( gAGLContext );
if ( !ok ) {
MacWarning( "aglSetCurrentContext failed" );
}
ok = aglSetDrawable( gAGLContext, _aglGetCurrentPort() );
}
void _aglSwapBuffers( void ) {
if ( sAGLActive ) {
aglSwapBuffers( gAGLContext );
} else {
gDrawSprocket->SwapBuffers();
}
}
WindowRef _aglGetGLWindow( void ) {
return sGLWindow;
}
AGLDrawable _aglGetDrawable( void ) {
return aglGetDrawable( gAGLContext );
}
Boolean _aglUsingFullscreen( void ) {
if ( sBlankingWindow ) {
return true;
} else {
return false;
}
}