|
|
@@ -1,1309 +0,0 @@
|
|
|
-//========================================================================
|
|
|
-// GLFW - An OpenGL framework
|
|
|
-// Platform: Carbon/AGL/CGL
|
|
|
-// API Version: 2.7
|
|
|
-// WWW: http://www.glfw.org/
|
|
|
-//------------------------------------------------------------------------
|
|
|
-// Copyright (c) 2002-2006 Marcus Geelnard
|
|
|
-// Copyright (c) 2003 Keith Bauer
|
|
|
-// Copyright (c) 2003-2010 Camilla Berglund <[email protected]>
|
|
|
-// Copyright (c) 2006-2007 Robin Leffmann
|
|
|
-//
|
|
|
-// This software is provided 'as-is', without any express or implied
|
|
|
-// warranty. In no event will the authors be held liable for any damages
|
|
|
-// arising from the use of this software.
|
|
|
-//
|
|
|
-// Permission is granted to anyone to use this software for any purpose,
|
|
|
-// including commercial applications, and to alter it and redistribute it
|
|
|
-// freely, subject to the following restrictions:
|
|
|
-//
|
|
|
-// 1. The origin of this software must not be misrepresented; you must not
|
|
|
-// claim that you wrote the original software. If you use this software
|
|
|
-// in a product, an acknowledgment in the product documentation would
|
|
|
-// be appreciated but is not required.
|
|
|
-//
|
|
|
-// 2. Altered source versions must be plainly marked as such, and must not
|
|
|
-// be misrepresented as being the original software.
|
|
|
-//
|
|
|
-// 3. This notice may not be removed or altered from any source
|
|
|
-// distribution.
|
|
|
-//
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-#include "internal.h"
|
|
|
-
|
|
|
-#define _glfwTestModifier( modifierMask, glfwKey ) \
|
|
|
-if ( changed & modifierMask ) \
|
|
|
-{ \
|
|
|
- _glfwInputKey( glfwKey, (modifiers & modifierMask ? GLFW_PRESS : GLFW_RELEASE) ); \
|
|
|
-}
|
|
|
-
|
|
|
-//************************************************************************
|
|
|
-//**** GLFW internal functions ****
|
|
|
-//************************************************************************
|
|
|
-
|
|
|
-static void handleMacModifierChange( UInt32 modifiers )
|
|
|
-{
|
|
|
- UInt32 changed = modifiers ^ _glfwInput.Modifiers;
|
|
|
-
|
|
|
- // The right *key variants below never actually occur
|
|
|
- // There also isn't even a broken right command key constant
|
|
|
- _glfwTestModifier( shiftKey, GLFW_KEY_LSHIFT );
|
|
|
- _glfwTestModifier( rightShiftKey, GLFW_KEY_RSHIFT );
|
|
|
- _glfwTestModifier( controlKey, GLFW_KEY_LCTRL );
|
|
|
- _glfwTestModifier( rightControlKey, GLFW_KEY_RCTRL );
|
|
|
- _glfwTestModifier( optionKey, GLFW_KEY_LALT );
|
|
|
- _glfwTestModifier( rightOptionKey, GLFW_KEY_RALT );
|
|
|
- _glfwTestModifier( cmdKey, GLFW_KEY_LSUPER );
|
|
|
-
|
|
|
- _glfwInput.Modifiers = modifiers;
|
|
|
-}
|
|
|
-
|
|
|
-static void handleMacKeyChange( UInt32 keyCode, int action )
|
|
|
-{
|
|
|
- switch ( keyCode )
|
|
|
- {
|
|
|
- case MAC_KEY_ENTER: _glfwInputKey( GLFW_KEY_ENTER, action); break;
|
|
|
- case MAC_KEY_RETURN: _glfwInputKey( GLFW_KEY_KP_ENTER, action); break;
|
|
|
- case MAC_KEY_ESC: _glfwInputKey( GLFW_KEY_ESC, action); break;
|
|
|
- case MAC_KEY_F1: _glfwInputKey( GLFW_KEY_F1, action); break;
|
|
|
- case MAC_KEY_F2: _glfwInputKey( GLFW_KEY_F2, action); break;
|
|
|
- case MAC_KEY_F3: _glfwInputKey( GLFW_KEY_F3, action); break;
|
|
|
- case MAC_KEY_F4: _glfwInputKey( GLFW_KEY_F4, action); break;
|
|
|
- case MAC_KEY_F5: _glfwInputKey( GLFW_KEY_F5, action); break;
|
|
|
- case MAC_KEY_F6: _glfwInputKey( GLFW_KEY_F6, action); break;
|
|
|
- case MAC_KEY_F7: _glfwInputKey( GLFW_KEY_F7, action); break;
|
|
|
- case MAC_KEY_F8: _glfwInputKey( GLFW_KEY_F8, action); break;
|
|
|
- case MAC_KEY_F9: _glfwInputKey( GLFW_KEY_F9, action); break;
|
|
|
- case MAC_KEY_F10: _glfwInputKey( GLFW_KEY_F10, action); break;
|
|
|
- case MAC_KEY_F11: _glfwInputKey( GLFW_KEY_F11, action); break;
|
|
|
- case MAC_KEY_F12: _glfwInputKey( GLFW_KEY_F12, action); break;
|
|
|
- case MAC_KEY_F13: _glfwInputKey( GLFW_KEY_F13, action); break;
|
|
|
- case MAC_KEY_F14: _glfwInputKey( GLFW_KEY_F14, action); break;
|
|
|
- case MAC_KEY_F15: _glfwInputKey( GLFW_KEY_F15, action); break;
|
|
|
- case MAC_KEY_UP: _glfwInputKey( GLFW_KEY_UP, action); break;
|
|
|
- case MAC_KEY_DOWN: _glfwInputKey( GLFW_KEY_DOWN, action); break;
|
|
|
- case MAC_KEY_LEFT: _glfwInputKey( GLFW_KEY_LEFT, action); break;
|
|
|
- case MAC_KEY_RIGHT: _glfwInputKey( GLFW_KEY_RIGHT, action); break;
|
|
|
- case MAC_KEY_TAB: _glfwInputKey( GLFW_KEY_TAB, action); break;
|
|
|
- case MAC_KEY_BACKSPACE: _glfwInputKey( GLFW_KEY_BACKSPACE, action); break;
|
|
|
- case MAC_KEY_HELP: _glfwInputKey( GLFW_KEY_INSERT, action); break;
|
|
|
- case MAC_KEY_DEL: _glfwInputKey( GLFW_KEY_DEL, action); break;
|
|
|
- case MAC_KEY_PAGEUP: _glfwInputKey( GLFW_KEY_PAGEUP, action); break;
|
|
|
- case MAC_KEY_PAGEDOWN: _glfwInputKey( GLFW_KEY_PAGEDOWN, action); break;
|
|
|
- case MAC_KEY_HOME: _glfwInputKey( GLFW_KEY_HOME, action); break;
|
|
|
- case MAC_KEY_END: _glfwInputKey( GLFW_KEY_END, action); break;
|
|
|
- case MAC_KEY_KP_0: _glfwInputKey( GLFW_KEY_KP_0, action); break;
|
|
|
- case MAC_KEY_KP_1: _glfwInputKey( GLFW_KEY_KP_1, action); break;
|
|
|
- case MAC_KEY_KP_2: _glfwInputKey( GLFW_KEY_KP_2, action); break;
|
|
|
- case MAC_KEY_KP_3: _glfwInputKey( GLFW_KEY_KP_3, action); break;
|
|
|
- case MAC_KEY_KP_4: _glfwInputKey( GLFW_KEY_KP_4, action); break;
|
|
|
- case MAC_KEY_KP_5: _glfwInputKey( GLFW_KEY_KP_5, action); break;
|
|
|
- case MAC_KEY_KP_6: _glfwInputKey( GLFW_KEY_KP_6, action); break;
|
|
|
- case MAC_KEY_KP_7: _glfwInputKey( GLFW_KEY_KP_7, action); break;
|
|
|
- case MAC_KEY_KP_8: _glfwInputKey( GLFW_KEY_KP_8, action); break;
|
|
|
- case MAC_KEY_KP_9: _glfwInputKey( GLFW_KEY_KP_9, action); break;
|
|
|
- case MAC_KEY_KP_DIVIDE: _glfwInputKey( GLFW_KEY_KP_DIVIDE, action); break;
|
|
|
- case MAC_KEY_KP_MULTIPLY: _glfwInputKey( GLFW_KEY_KP_MULTIPLY, action); break;
|
|
|
- case MAC_KEY_KP_SUBTRACT: _glfwInputKey( GLFW_KEY_KP_SUBTRACT, action); break;
|
|
|
- case MAC_KEY_KP_ADD: _glfwInputKey( GLFW_KEY_KP_ADD, action); break;
|
|
|
- case MAC_KEY_KP_DECIMAL: _glfwInputKey( GLFW_KEY_KP_DECIMAL, action); break;
|
|
|
- case MAC_KEY_KP_EQUAL: _glfwInputKey( GLFW_KEY_KP_EQUAL, action); break;
|
|
|
- case MAC_KEY_KP_ENTER: _glfwInputKey( GLFW_KEY_KP_ENTER, action); break;
|
|
|
- case MAC_KEY_NUMLOCK: _glfwInputKey( GLFW_KEY_KP_NUM_LOCK, action); break;
|
|
|
- default:
|
|
|
- {
|
|
|
- extern void *KCHRPtr;
|
|
|
- UInt32 state = 0;
|
|
|
- char charCode = (char)KeyTranslate( KCHRPtr, keyCode, &state );
|
|
|
- UppercaseText( &charCode, 1, smSystemScript );
|
|
|
- _glfwInputKey( (unsigned char)charCode, action );
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// The set of event class/kind combinations supported by keyEventHandler
|
|
|
-// This is used by installEventHandlers below
|
|
|
-static const EventTypeSpec GLFW_KEY_EVENT_TYPES[] =
|
|
|
-{
|
|
|
- { kEventClassKeyboard, kEventRawKeyDown },
|
|
|
- { kEventClassKeyboard, kEventRawKeyUp },
|
|
|
- { kEventClassKeyboard, kEventRawKeyRepeat },
|
|
|
- { kEventClassKeyboard, kEventRawKeyModifiersChanged }
|
|
|
-};
|
|
|
-
|
|
|
-static OSStatus keyEventHandler( EventHandlerCallRef handlerCallRef,
|
|
|
- EventRef event,
|
|
|
- void *userData )
|
|
|
-{
|
|
|
- UInt32 keyCode;
|
|
|
- short int keyChar;
|
|
|
- UInt32 modifiers;
|
|
|
-
|
|
|
- switch( GetEventKind( event ) )
|
|
|
- {
|
|
|
- case kEventRawKeyRepeat:
|
|
|
- case kEventRawKeyDown:
|
|
|
- {
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamKeyCode,
|
|
|
- typeUInt32,
|
|
|
- NULL,
|
|
|
- sizeof( UInt32 ),
|
|
|
- NULL,
|
|
|
- &keyCode ) == noErr )
|
|
|
- {
|
|
|
- handleMacKeyChange( keyCode, GLFW_PRESS );
|
|
|
- }
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamKeyUnicodes,
|
|
|
- typeUnicodeText,
|
|
|
- NULL,
|
|
|
- sizeof(keyChar),
|
|
|
- NULL,
|
|
|
- &keyChar) == noErr )
|
|
|
- {
|
|
|
- _glfwInputChar( keyChar, GLFW_PRESS );
|
|
|
- }
|
|
|
- return noErr;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventRawKeyUp:
|
|
|
- {
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamKeyCode,
|
|
|
- typeUInt32,
|
|
|
- NULL,
|
|
|
- sizeof( UInt32 ),
|
|
|
- NULL,
|
|
|
- &keyCode ) == noErr )
|
|
|
- {
|
|
|
- handleMacKeyChange( keyCode, GLFW_RELEASE );
|
|
|
- }
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamKeyUnicodes,
|
|
|
- typeUnicodeText,
|
|
|
- NULL,
|
|
|
- sizeof(keyChar),
|
|
|
- NULL,
|
|
|
- &keyChar) == noErr )
|
|
|
- {
|
|
|
- _glfwInputChar( keyChar, GLFW_RELEASE );
|
|
|
- }
|
|
|
- return noErr;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventRawKeyModifiersChanged:
|
|
|
- {
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamKeyModifiers,
|
|
|
- typeUInt32,
|
|
|
- NULL,
|
|
|
- sizeof( UInt32 ),
|
|
|
- NULL,
|
|
|
- &modifiers ) == noErr )
|
|
|
- {
|
|
|
- handleMacModifierChange( modifiers );
|
|
|
- return noErr;
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- return eventNotHandledErr;
|
|
|
-}
|
|
|
-
|
|
|
-// The set of event class/kind combinations supported by mouseEventHandler
|
|
|
-// This is used by installEventHandlers below
|
|
|
-static const EventTypeSpec GLFW_MOUSE_EVENT_TYPES[] =
|
|
|
-{
|
|
|
- { kEventClassMouse, kEventMouseDown },
|
|
|
- { kEventClassMouse, kEventMouseUp },
|
|
|
- { kEventClassMouse, kEventMouseMoved },
|
|
|
- { kEventClassMouse, kEventMouseDragged },
|
|
|
- { kEventClassMouse, kEventMouseWheelMoved },
|
|
|
-};
|
|
|
-
|
|
|
-static OSStatus mouseEventHandler( EventHandlerCallRef handlerCallRef,
|
|
|
- EventRef event,
|
|
|
- void *userData )
|
|
|
-{
|
|
|
- switch( GetEventKind( event ) )
|
|
|
- {
|
|
|
- case kEventMouseDown:
|
|
|
- {
|
|
|
- WindowRef window;
|
|
|
- EventRecord oldStyleMacEvent;
|
|
|
- ConvertEventRefToEventRecord( event, &oldStyleMacEvent );
|
|
|
- if( FindWindow ( oldStyleMacEvent.where, &window ) == inMenuBar )
|
|
|
- {
|
|
|
- MenuSelect( oldStyleMacEvent.where );
|
|
|
- HiliteMenu(0);
|
|
|
- return noErr;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- EventMouseButton button;
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamMouseButton,
|
|
|
- typeMouseButton,
|
|
|
- NULL,
|
|
|
- sizeof( EventMouseButton ),
|
|
|
- NULL,
|
|
|
- &button ) == noErr )
|
|
|
- {
|
|
|
- button -= kEventMouseButtonPrimary;
|
|
|
- if( button <= GLFW_MOUSE_BUTTON_LAST )
|
|
|
- {
|
|
|
- _glfwInputMouseClick( button + GLFW_MOUSE_BUTTON_LEFT,
|
|
|
- GLFW_PRESS );
|
|
|
- }
|
|
|
- return noErr;
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventMouseUp:
|
|
|
- {
|
|
|
- EventMouseButton button;
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamMouseButton,
|
|
|
- typeMouseButton,
|
|
|
- NULL,
|
|
|
- sizeof( EventMouseButton ),
|
|
|
- NULL,
|
|
|
- &button ) == noErr )
|
|
|
- {
|
|
|
- button -= kEventMouseButtonPrimary;
|
|
|
- if( button <= GLFW_MOUSE_BUTTON_LAST )
|
|
|
- {
|
|
|
- _glfwInputMouseClick( button + GLFW_MOUSE_BUTTON_LEFT,
|
|
|
- GLFW_RELEASE );
|
|
|
- }
|
|
|
- return noErr;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventMouseMoved:
|
|
|
- case kEventMouseDragged:
|
|
|
- {
|
|
|
- HIPoint mouseLocation;
|
|
|
- if( _glfwWin.mouseLock )
|
|
|
- {
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamMouseDelta,
|
|
|
- typeHIPoint,
|
|
|
- NULL,
|
|
|
- sizeof( HIPoint ),
|
|
|
- NULL,
|
|
|
- &mouseLocation ) != noErr )
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- _glfwInput.MousePosX += mouseLocation.x;
|
|
|
- _glfwInput.MousePosY += mouseLocation.y;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamMouseLocation,
|
|
|
- typeHIPoint,
|
|
|
- NULL,
|
|
|
- sizeof( HIPoint ),
|
|
|
- NULL,
|
|
|
- &mouseLocation ) != noErr )
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- _glfwInput.MousePosX = mouseLocation.x;
|
|
|
- _glfwInput.MousePosY = mouseLocation.y;
|
|
|
-
|
|
|
- if( !_glfwWin.fullscreen )
|
|
|
- {
|
|
|
- Rect content;
|
|
|
- GetWindowBounds( _glfwWin.window,
|
|
|
- kWindowContentRgn,
|
|
|
- &content );
|
|
|
-
|
|
|
- _glfwInput.MousePosX -= content.left;
|
|
|
- _glfwInput.MousePosY -= content.top;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if( _glfwWin.mousePosCallback )
|
|
|
- {
|
|
|
- _glfwWin.mousePosCallback( _glfwInput.MousePosX,
|
|
|
- _glfwInput.MousePosY );
|
|
|
- }
|
|
|
-
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventMouseWheelMoved:
|
|
|
- {
|
|
|
- EventMouseWheelAxis axis;
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamMouseWheelAxis,
|
|
|
- typeMouseWheelAxis,
|
|
|
- NULL,
|
|
|
- sizeof( EventMouseWheelAxis ),
|
|
|
- NULL,
|
|
|
- &axis) == noErr )
|
|
|
- {
|
|
|
- long wheelDelta;
|
|
|
- if( axis == kEventMouseWheelAxisY &&
|
|
|
- GetEventParameter( event,
|
|
|
- kEventParamMouseWheelDelta,
|
|
|
- typeLongInteger,
|
|
|
- NULL,
|
|
|
- sizeof( long ),
|
|
|
- NULL,
|
|
|
- &wheelDelta ) == noErr )
|
|
|
- {
|
|
|
- _glfwInput.WheelPos += wheelDelta;
|
|
|
- if( _glfwWin.mouseWheelCallback )
|
|
|
- {
|
|
|
- _glfwWin.mouseWheelCallback( _glfwInput.WheelPos );
|
|
|
- }
|
|
|
- return noErr;
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return eventNotHandledErr;
|
|
|
-}
|
|
|
-
|
|
|
-// The set of event class/kind combinations supported by commandHandler
|
|
|
-// This is used by installEventHandlers below
|
|
|
-static const EventTypeSpec GLFW_COMMAND_EVENT_TYPES[] =
|
|
|
-{
|
|
|
- { kEventClassCommand, kEventCommandProcess }
|
|
|
-};
|
|
|
-
|
|
|
-static OSStatus commandHandler( EventHandlerCallRef handlerCallRef,
|
|
|
- EventRef event,
|
|
|
- void *userData )
|
|
|
-{
|
|
|
- if( _glfwWin.sysKeysDisabled )
|
|
|
- {
|
|
|
- // TODO: Give adequate UI feedback that this is the case
|
|
|
- return eventNotHandledErr;
|
|
|
- }
|
|
|
-
|
|
|
- HICommand command;
|
|
|
- if( GetEventParameter( event,
|
|
|
- kEventParamDirectObject,
|
|
|
- typeHICommand,
|
|
|
- NULL,
|
|
|
- sizeof( HICommand ),
|
|
|
- NULL,
|
|
|
- &command ) == noErr )
|
|
|
- {
|
|
|
- switch( command.commandID )
|
|
|
- {
|
|
|
- case kHICommandClose:
|
|
|
- case kHICommandQuit:
|
|
|
- {
|
|
|
- // Check if the program wants us to close the window
|
|
|
- if( _glfwWin.windowCloseCallback )
|
|
|
- {
|
|
|
- if( _glfwWin.windowCloseCallback() )
|
|
|
- {
|
|
|
- glfwCloseWindow();
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- glfwCloseWindow();
|
|
|
- }
|
|
|
- return noErr;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return eventNotHandledErr;
|
|
|
-}
|
|
|
-
|
|
|
-// The set of event class/kind combinations supported by windowEventHandler
|
|
|
-// This is used by installEventHandlers below
|
|
|
-static const EventTypeSpec GLFW_WINDOW_EVENT_TYPES[] =
|
|
|
-{
|
|
|
- { kEventClassWindow, kEventWindowBoundsChanged },
|
|
|
- { kEventClassWindow, kEventWindowClose },
|
|
|
- { kEventClassWindow, kEventWindowDrawContent },
|
|
|
- { kEventClassWindow, kEventWindowActivated },
|
|
|
- { kEventClassWindow, kEventWindowDeactivated },
|
|
|
-};
|
|
|
-
|
|
|
-static OSStatus windowEventHandler( EventHandlerCallRef handlerCallRef,
|
|
|
- EventRef event,
|
|
|
- void *userData )
|
|
|
-{
|
|
|
- switch( GetEventKind(event) )
|
|
|
- {
|
|
|
- case kEventWindowBoundsChanged:
|
|
|
- {
|
|
|
- WindowRef window;
|
|
|
- GetEventParameter( event,
|
|
|
- kEventParamDirectObject,
|
|
|
- typeWindowRef,
|
|
|
- NULL,
|
|
|
- sizeof(WindowRef),
|
|
|
- NULL,
|
|
|
- &window );
|
|
|
-
|
|
|
- Rect rect;
|
|
|
- GetWindowPortBounds( window, &rect );
|
|
|
-
|
|
|
- if( _glfwWin.width != rect.right ||
|
|
|
- _glfwWin.height != rect.bottom )
|
|
|
- {
|
|
|
- aglUpdateContext( _glfwWin.aglContext );
|
|
|
-
|
|
|
- _glfwWin.width = rect.right;
|
|
|
- _glfwWin.height = rect.bottom;
|
|
|
- if( _glfwWin.windowSizeCallback )
|
|
|
- {
|
|
|
- _glfwWin.windowSizeCallback( _glfwWin.width, _glfwWin.height );
|
|
|
- }
|
|
|
- // Emulate (force) content invalidation
|
|
|
- if( _glfwWin.windowRefreshCallback )
|
|
|
- {
|
|
|
- _glfwWin.windowRefreshCallback();
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventWindowClose:
|
|
|
- {
|
|
|
- // Check if the client wants us to close the window
|
|
|
- if( _glfwWin.windowCloseCallback )
|
|
|
- {
|
|
|
- if( _glfwWin.windowCloseCallback() )
|
|
|
- {
|
|
|
- glfwCloseWindow();
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- glfwCloseWindow();
|
|
|
- }
|
|
|
- return noErr;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventWindowDrawContent:
|
|
|
- {
|
|
|
- if( _glfwWin.windowRefreshCallback )
|
|
|
- {
|
|
|
- _glfwWin.windowRefreshCallback();
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventWindowActivated:
|
|
|
- {
|
|
|
- _glfwWin.active = GL_TRUE;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case kEventWindowDeactivated:
|
|
|
- {
|
|
|
- _glfwWin.active = GL_FALSE;
|
|
|
- _glfwInputDeactivation();
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return eventNotHandledErr;
|
|
|
-}
|
|
|
-
|
|
|
-static int installEventHandlers( void )
|
|
|
-{
|
|
|
- OSStatus error;
|
|
|
-
|
|
|
- _glfwWin.mouseUPP = NewEventHandlerUPP( mouseEventHandler );
|
|
|
-
|
|
|
- error = InstallEventHandler( GetApplicationEventTarget(),
|
|
|
- _glfwWin.mouseUPP,
|
|
|
- GetEventTypeCount( GLFW_MOUSE_EVENT_TYPES ),
|
|
|
- GLFW_MOUSE_EVENT_TYPES,
|
|
|
- NULL,
|
|
|
- NULL );
|
|
|
- if( error != noErr )
|
|
|
- {
|
|
|
- fprintf( stderr, "Failed to install Carbon application mouse event handler\n" );
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- _glfwWin.commandUPP = NewEventHandlerUPP( commandHandler );
|
|
|
-
|
|
|
- error = InstallEventHandler( GetApplicationEventTarget(),
|
|
|
- _glfwWin.commandUPP,
|
|
|
- GetEventTypeCount( GLFW_COMMAND_EVENT_TYPES ),
|
|
|
- GLFW_COMMAND_EVENT_TYPES,
|
|
|
- NULL,
|
|
|
- NULL );
|
|
|
- if( error != noErr )
|
|
|
- {
|
|
|
- fprintf( stderr, "Failed to install Carbon application command event handler\n" );
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- _glfwWin.keyboardUPP = NewEventHandlerUPP( keyEventHandler );
|
|
|
-
|
|
|
- error = InstallEventHandler( GetApplicationEventTarget(),
|
|
|
- _glfwWin.keyboardUPP,
|
|
|
- GetEventTypeCount( GLFW_KEY_EVENT_TYPES ),
|
|
|
- GLFW_KEY_EVENT_TYPES,
|
|
|
- NULL,
|
|
|
- NULL );
|
|
|
- if( error != noErr )
|
|
|
- {
|
|
|
- fprintf( stderr, "Failed to install Carbon application key event handler\n" );
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- return GL_TRUE;
|
|
|
-}
|
|
|
-
|
|
|
-//************************************************************************
|
|
|
-//**** Platform implementation functions ****
|
|
|
-//************************************************************************
|
|
|
-
|
|
|
-#define _setAGLAttribute( aglAttributeName, AGLparameter ) \
|
|
|
-if ( AGLparameter != 0 ) \
|
|
|
-{ \
|
|
|
- AGLpixelFormatAttributes[numAGLAttrs++] = aglAttributeName; \
|
|
|
- AGLpixelFormatAttributes[numAGLAttrs++] = AGLparameter; \
|
|
|
-}
|
|
|
-
|
|
|
-#define _setCGLAttribute( cglAttributeName, CGLparameter ) \
|
|
|
-if ( CGLparameter != 0 ) \
|
|
|
-{ \
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = cglAttributeName; \
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = CGLparameter; \
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Here is where the window is created, and
|
|
|
-// the OpenGL rendering context is created
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-int _glfwPlatformOpenWindow( int width, int height,
|
|
|
- const _GLFWwndconfig *wndconfig,
|
|
|
- const _GLFWfbconfig *fbconfig )
|
|
|
-{
|
|
|
- OSStatus error;
|
|
|
- unsigned int windowAttributes;
|
|
|
- ProcessSerialNumber psn;
|
|
|
-
|
|
|
- // TODO: Break up this function!
|
|
|
-
|
|
|
- _glfwWin.windowUPP = NULL;
|
|
|
- _glfwWin.mouseUPP = NULL;
|
|
|
- _glfwWin.keyboardUPP = NULL;
|
|
|
- _glfwWin.commandUPP = NULL;
|
|
|
- _glfwWin.window = NULL;
|
|
|
- _glfwWin.aglContext = NULL;
|
|
|
- _glfwWin.aglPixelFormat = NULL;
|
|
|
- _glfwWin.cglContext = NULL;
|
|
|
- _glfwWin.cglPixelFormat = NULL;
|
|
|
-
|
|
|
- _glfwWin.refreshRate = wndconfig->refreshRate;
|
|
|
-
|
|
|
- // Fail if OpenGL 3.0 or above was requested
|
|
|
- if( wndconfig->glMajor > 2 )
|
|
|
- {
|
|
|
- fprintf( stderr, "OpenGL 3.0+ is not yet supported on Mac OS X\n" );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- if( _glfwLibrary.Unbundled )
|
|
|
- {
|
|
|
- if( GetCurrentProcess( &psn ) != noErr )
|
|
|
- {
|
|
|
- fprintf( stderr, "Failed to get the process serial number\n" );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- if( TransformProcessType( &psn, kProcessTransformToForegroundApplication ) != noErr )
|
|
|
- {
|
|
|
- fprintf( stderr, "Failed to become a foreground application\n" );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- if( wndconfig->mode == GLFW_FULLSCREEN )
|
|
|
- {
|
|
|
- if( SetFrontProcess( &psn ) != noErr )
|
|
|
- {
|
|
|
- fprintf( stderr, "Failed to become the front process\n" );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if( !installEventHandlers() )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to install Carbon application event handlers\n" );
|
|
|
-
|
|
|
- _glfwPlatformTerminate();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // Windowed or fullscreen; AGL or CGL? Quite the mess...
|
|
|
- // AGL appears to be the only choice for attaching OpenGL contexts to
|
|
|
- // Carbon windows, but it leaves the user no control over fullscreen
|
|
|
- // mode stretching. Solution: AGL for windowed, CGL for fullscreen.
|
|
|
- if( wndconfig->mode == GLFW_WINDOW )
|
|
|
- {
|
|
|
- // create AGL pixel format attribute list
|
|
|
- GLint AGLpixelFormatAttributes[256];
|
|
|
- int numAGLAttrs = 0;
|
|
|
-
|
|
|
- AGLpixelFormatAttributes[numAGLAttrs++] = AGL_RGBA;
|
|
|
- AGLpixelFormatAttributes[numAGLAttrs++] = AGL_DOUBLEBUFFER;
|
|
|
- AGLpixelFormatAttributes[numAGLAttrs++] = AGL_CLOSEST_POLICY;
|
|
|
-
|
|
|
- if( fbconfig->stereo )
|
|
|
- {
|
|
|
- AGLpixelFormatAttributes[numAGLAttrs++] = AGL_STEREO;
|
|
|
- }
|
|
|
-
|
|
|
- _setAGLAttribute( AGL_AUX_BUFFERS, fbconfig->auxBuffers);
|
|
|
- _setAGLAttribute( AGL_RED_SIZE, fbconfig->redBits );
|
|
|
- _setAGLAttribute( AGL_GREEN_SIZE, fbconfig->greenBits );
|
|
|
- _setAGLAttribute( AGL_BLUE_SIZE, fbconfig->blueBits );
|
|
|
- _setAGLAttribute( AGL_ALPHA_SIZE, fbconfig->alphaBits );
|
|
|
- _setAGLAttribute( AGL_DEPTH_SIZE, fbconfig->depthBits );
|
|
|
- _setAGLAttribute( AGL_STENCIL_SIZE, fbconfig->stencilBits );
|
|
|
- _setAGLAttribute( AGL_ACCUM_RED_SIZE, fbconfig->accumRedBits );
|
|
|
- _setAGLAttribute( AGL_ACCUM_GREEN_SIZE, fbconfig->accumGreenBits );
|
|
|
- _setAGLAttribute( AGL_ACCUM_BLUE_SIZE, fbconfig->accumBlueBits );
|
|
|
- _setAGLAttribute( AGL_ACCUM_ALPHA_SIZE, fbconfig->accumAlphaBits );
|
|
|
-
|
|
|
- if( fbconfig->samples > 1 )
|
|
|
- {
|
|
|
- _setAGLAttribute( AGL_SAMPLE_BUFFERS_ARB, 1 );
|
|
|
- _setAGLAttribute( AGL_SAMPLES_ARB, fbconfig->samples );
|
|
|
- AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NO_RECOVERY;
|
|
|
- }
|
|
|
-
|
|
|
- AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NONE;
|
|
|
-
|
|
|
- // create pixel format descriptor
|
|
|
- AGLDevice mainMonitor = GetMainDevice();
|
|
|
- _glfwWin.aglPixelFormat = aglChoosePixelFormat( &mainMonitor,
|
|
|
- 1,
|
|
|
- AGLpixelFormatAttributes );
|
|
|
- if( _glfwWin.aglPixelFormat == NULL )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to choose AGL pixel format: %s\n",
|
|
|
- aglErrorString( aglGetError() ) );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // create AGL context
|
|
|
- _glfwWin.aglContext = aglCreateContext( _glfwWin.aglPixelFormat, NULL );
|
|
|
-
|
|
|
- if( _glfwWin.aglContext == NULL )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to create AGL context: %s\n",
|
|
|
- aglErrorString( aglGetError() ) );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // create window
|
|
|
- Rect windowContentBounds;
|
|
|
- windowContentBounds.left = 0;
|
|
|
- windowContentBounds.top = 0;
|
|
|
- windowContentBounds.right = width;
|
|
|
- windowContentBounds.bottom = height;
|
|
|
-
|
|
|
- windowAttributes = ( kWindowCloseBoxAttribute |
|
|
|
- kWindowCollapseBoxAttribute |
|
|
|
- kWindowStandardHandlerAttribute );
|
|
|
-
|
|
|
- if( wndconfig->windowNoResize )
|
|
|
- {
|
|
|
- windowAttributes |= kWindowLiveResizeAttribute;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- windowAttributes |= ( kWindowFullZoomAttribute |
|
|
|
- kWindowResizableAttribute );
|
|
|
- }
|
|
|
-
|
|
|
- error = CreateNewWindow( kDocumentWindowClass,
|
|
|
- windowAttributes,
|
|
|
- &windowContentBounds,
|
|
|
- &( _glfwWin.window ) );
|
|
|
- if( ( error != noErr ) || ( _glfwWin.window == NULL ) )
|
|
|
- {
|
|
|
- fprintf( stderr, "Failed to create Carbon window\n" );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- _glfwWin.windowUPP = NewEventHandlerUPP( windowEventHandler );
|
|
|
-
|
|
|
- error = InstallWindowEventHandler( _glfwWin.window,
|
|
|
- _glfwWin.windowUPP,
|
|
|
- GetEventTypeCount( GLFW_WINDOW_EVENT_TYPES ),
|
|
|
- GLFW_WINDOW_EVENT_TYPES,
|
|
|
- NULL,
|
|
|
- NULL );
|
|
|
- if( error != noErr )
|
|
|
- {
|
|
|
- fprintf( stderr, "Failed to install Carbon window event handler\n" );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // Don't care if we fail here
|
|
|
- (void)SetWindowTitleWithCFString( _glfwWin.window, CFSTR( "GLFW Window" ) );
|
|
|
- (void)RepositionWindow( _glfwWin.window,
|
|
|
- NULL,
|
|
|
- kWindowCenterOnMainScreen );
|
|
|
-
|
|
|
- if( !aglSetDrawable( _glfwWin.aglContext,
|
|
|
- GetWindowPort( _glfwWin.window ) ) )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to set the AGL context as the Carbon window drawable: %s\n",
|
|
|
- aglErrorString( aglGetError() ) );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // Make OpenGL context current
|
|
|
- if( !aglSetCurrentContext( _glfwWin.aglContext ) )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to make AGL context current: %s\n",
|
|
|
- aglErrorString( aglGetError() ) );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- ShowWindow( _glfwWin.window );
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CGDisplayErr cgErr;
|
|
|
- CGLError cglErr;
|
|
|
-
|
|
|
- CFDictionaryRef optimalMode;
|
|
|
-
|
|
|
- GLint numCGLvs = 0;
|
|
|
-
|
|
|
- CGLPixelFormatAttribute CGLpixelFormatAttributes[64];
|
|
|
- int numCGLAttrs = 0;
|
|
|
-
|
|
|
- // variables for enumerating color depths
|
|
|
- GLint rgbColorDepth;
|
|
|
-
|
|
|
- // CGL pixel format attributes
|
|
|
- _setCGLAttribute( kCGLPFADisplayMask,
|
|
|
- CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ) );
|
|
|
-
|
|
|
- if( fbconfig->stereo )
|
|
|
- {
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAStereo;
|
|
|
- }
|
|
|
-
|
|
|
- if( fbconfig->samples > 1 )
|
|
|
- {
|
|
|
- _setCGLAttribute( kCGLPFASamples, (CGLPixelFormatAttribute)fbconfig->samples );
|
|
|
- _setCGLAttribute( kCGLPFASampleBuffers, (CGLPixelFormatAttribute)1 );
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFANoRecovery;
|
|
|
- }
|
|
|
-
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAFullScreen;
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFADoubleBuffer;
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAAccelerated;
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFANoRecovery;
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAMinimumPolicy;
|
|
|
-
|
|
|
- _setCGLAttribute( kCGLPFAAccumSize,
|
|
|
- (CGLPixelFormatAttribute)( fbconfig->accumRedBits \
|
|
|
- + fbconfig->accumGreenBits \
|
|
|
- + fbconfig->accumBlueBits \
|
|
|
- + fbconfig->accumAlphaBits ) );
|
|
|
-
|
|
|
- _setCGLAttribute( kCGLPFAAlphaSize, (CGLPixelFormatAttribute)fbconfig->alphaBits );
|
|
|
- _setCGLAttribute( kCGLPFADepthSize, (CGLPixelFormatAttribute)fbconfig->depthBits );
|
|
|
- _setCGLAttribute( kCGLPFAStencilSize, (CGLPixelFormatAttribute)fbconfig->stencilBits );
|
|
|
- _setCGLAttribute( kCGLPFAAuxBuffers, (CGLPixelFormatAttribute)fbconfig->auxBuffers );
|
|
|
-
|
|
|
- CGLpixelFormatAttributes[ numCGLAttrs++ ] = (CGLPixelFormatAttribute)NULL;
|
|
|
-
|
|
|
- // create a suitable pixel format with above attributes..
|
|
|
- cglErr = CGLChoosePixelFormat( CGLpixelFormatAttributes,
|
|
|
- &_glfwWin.cglPixelFormat,
|
|
|
- &numCGLvs );
|
|
|
- if( cglErr != kCGLNoError )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to choose CGL pixel format: %s\n",
|
|
|
- CGLErrorString( cglErr ) );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // ..and create a rendering context using that pixel format
|
|
|
- cglErr = CGLCreateContext( _glfwWin.cglPixelFormat, NULL, &_glfwWin.cglContext );
|
|
|
- if( cglErr != kCGLNoError )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to create CGL context: %s\n",
|
|
|
- CGLErrorString( cglErr ) );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // enumerate depth of RGB channels - unlike AGL, CGL works with
|
|
|
- // a single parameter reflecting the full depth of the frame buffer
|
|
|
- (void)CGLDescribePixelFormat( _glfwWin.cglPixelFormat,
|
|
|
- 0,
|
|
|
- kCGLPFAColorSize,
|
|
|
- &rgbColorDepth );
|
|
|
-
|
|
|
- // capture the display for our application
|
|
|
- cgErr = CGCaptureAllDisplays();
|
|
|
- if( cgErr != kCGErrorSuccess )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to capture Core Graphics displays\n");
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // find closest matching NON-STRETCHED display mode..
|
|
|
- optimalMode = CGDisplayBestModeForParametersAndRefreshRateWithProperty(
|
|
|
- kCGDirectMainDisplay,
|
|
|
- rgbColorDepth,
|
|
|
- width,
|
|
|
- height,
|
|
|
- wndconfig->refreshRate,
|
|
|
- NULL,
|
|
|
- NULL );
|
|
|
- if( optimalMode == NULL )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to retrieve Core Graphics display mode\n");
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // ..and switch to that mode
|
|
|
- cgErr = CGDisplaySwitchToMode( kCGDirectMainDisplay, optimalMode );
|
|
|
- if( cgErr != kCGErrorSuccess )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to switch to Core Graphics display mode\n");
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // switch to our OpenGL context, and bring it up fullscreen
|
|
|
- cglErr = CGLSetCurrentContext( _glfwWin.cglContext );
|
|
|
- if( cglErr != kCGLNoError )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to make CGL context current: %s\n",
|
|
|
- CGLErrorString( cglErr ) );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- cglErr = CGLSetFullScreen( _glfwWin.cglContext );
|
|
|
- if( cglErr != kCGLNoError )
|
|
|
- {
|
|
|
- fprintf( stderr,
|
|
|
- "Failed to set CGL fullscreen mode: %s\n",
|
|
|
- CGLErrorString( cglErr ) );
|
|
|
-
|
|
|
- _glfwPlatformCloseWindow();
|
|
|
- return GL_FALSE;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return GL_TRUE;
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Properly kill the window/video display
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformCloseWindow( void )
|
|
|
-{
|
|
|
- if( _glfwWin.mouseUPP != NULL )
|
|
|
- {
|
|
|
- DisposeEventHandlerUPP( _glfwWin.mouseUPP );
|
|
|
- _glfwWin.mouseUPP = NULL;
|
|
|
- }
|
|
|
- if( _glfwWin.commandUPP != NULL )
|
|
|
- {
|
|
|
- DisposeEventHandlerUPP( _glfwWin.commandUPP );
|
|
|
- _glfwWin.commandUPP = NULL;
|
|
|
- }
|
|
|
- if( _glfwWin.keyboardUPP != NULL )
|
|
|
- {
|
|
|
- DisposeEventHandlerUPP( _glfwWin.keyboardUPP );
|
|
|
- _glfwWin.keyboardUPP = NULL;
|
|
|
- }
|
|
|
- if( _glfwWin.windowUPP != NULL )
|
|
|
- {
|
|
|
- DisposeEventHandlerUPP( _glfwWin.windowUPP );
|
|
|
- _glfwWin.windowUPP = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- if( _glfwWin.fullscreen )
|
|
|
- {
|
|
|
- if( _glfwWin.cglContext != NULL )
|
|
|
- {
|
|
|
- CGLSetCurrentContext( NULL );
|
|
|
- CGLClearDrawable( _glfwWin.cglContext );
|
|
|
- CGLDestroyContext( _glfwWin.cglContext );
|
|
|
- CGReleaseAllDisplays();
|
|
|
- _glfwWin.cglContext = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- if( _glfwWin.cglPixelFormat != NULL )
|
|
|
- {
|
|
|
- CGLDestroyPixelFormat( _glfwWin.cglPixelFormat );
|
|
|
- _glfwWin.cglPixelFormat = NULL;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if( _glfwWin.aglContext != NULL )
|
|
|
- {
|
|
|
- aglSetCurrentContext( NULL );
|
|
|
- aglSetDrawable( _glfwWin.aglContext, NULL );
|
|
|
- aglDestroyContext( _glfwWin.aglContext );
|
|
|
- _glfwWin.aglContext = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- if( _glfwWin.aglPixelFormat != NULL )
|
|
|
- {
|
|
|
- aglDestroyPixelFormat( _glfwWin.aglPixelFormat );
|
|
|
- _glfwWin.aglPixelFormat = NULL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if( _glfwWin.window != NULL )
|
|
|
- {
|
|
|
- ReleaseWindow( _glfwWin.window );
|
|
|
- _glfwWin.window = NULL;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Set the window title
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformSetWindowTitle( const char *title )
|
|
|
-{
|
|
|
- CFStringRef windowTitle;
|
|
|
-
|
|
|
- if( !_glfwWin.fullscreen )
|
|
|
- {
|
|
|
- windowTitle = CFStringCreateWithCString( kCFAllocatorDefault,
|
|
|
- title,
|
|
|
- kCFStringEncodingISOLatin1 );
|
|
|
-
|
|
|
- (void)SetWindowTitleWithCFString( _glfwWin.window, windowTitle );
|
|
|
-
|
|
|
- CFRelease( windowTitle );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Set the window size
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformSetWindowSize( int width, int height )
|
|
|
-{
|
|
|
- if( !_glfwWin.fullscreen )
|
|
|
- {
|
|
|
- SizeWindow( _glfwWin.window, width, height, TRUE );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Set the window position
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformSetWindowPos( int x, int y )
|
|
|
-{
|
|
|
- if( !_glfwWin.fullscreen )
|
|
|
- {
|
|
|
- MoveWindow( _glfwWin.window, x, y, FALSE );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Window iconification
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformIconifyWindow( void )
|
|
|
-{
|
|
|
- if( !_glfwWin.fullscreen )
|
|
|
- {
|
|
|
- (void)CollapseWindow( _glfwWin.window, TRUE );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Window un-iconification
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformRestoreWindow( void )
|
|
|
-{
|
|
|
- if( !_glfwWin.fullscreen )
|
|
|
- {
|
|
|
- (void)CollapseWindow( _glfwWin.window, FALSE );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Swap buffers (double-buffering) and poll any new events
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformSwapBuffers( void )
|
|
|
-{
|
|
|
- if( _glfwWin.fullscreen )
|
|
|
- {
|
|
|
- CGLFlushDrawable( _glfwWin.cglContext );
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- aglSwapBuffers( _glfwWin.aglContext );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Set double buffering swap interval
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformSwapInterval( int interval )
|
|
|
-{
|
|
|
- GLint AGLparameter = interval;
|
|
|
-
|
|
|
- // CGL doesn't seem to like intervals other than 0 (vsync off) or 1 (vsync on)
|
|
|
- long CGLparameter = ( interval ? 1 : 0 );
|
|
|
-
|
|
|
- if( _glfwWin.fullscreen )
|
|
|
- {
|
|
|
- // Don't care if we fail here..
|
|
|
- (void)CGLSetParameter( _glfwWin.cglContext,
|
|
|
- kCGLCPSwapInterval,
|
|
|
- (GLint*) &CGLparameter );
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // ..or here
|
|
|
- (void)aglSetInteger( _glfwWin.aglContext,
|
|
|
- AGL_SWAP_INTERVAL,
|
|
|
- &AGLparameter );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Read back framebuffer parameters from the context
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-#define _getAGLAttribute( aglAttributeName, variableName ) \
|
|
|
-{ \
|
|
|
- GLint aglValue; \
|
|
|
- (void)aglDescribePixelFormat( _glfwWin.aglPixelFormat, aglAttributeName, &aglValue ); \
|
|
|
- variableName = aglValue; \
|
|
|
-}
|
|
|
-
|
|
|
-#define _getCGLAttribute( cglAttributeName, variableName ) \
|
|
|
-{ \
|
|
|
- GLint cglValue; \
|
|
|
- (void)CGLDescribePixelFormat( _glfwWin.cglPixelFormat, 0, cglAttributeName, &cglValue ); \
|
|
|
- variableName = cglValue; \
|
|
|
-}
|
|
|
-
|
|
|
-void _glfwPlatformRefreshWindowParams( void )
|
|
|
-{
|
|
|
- GLint rgbColorDepth;
|
|
|
- GLint rgbaAccumDepth = 0;
|
|
|
- GLint rgbChannelDepth = 0;
|
|
|
-
|
|
|
- if( _glfwWin.fullscreen )
|
|
|
- {
|
|
|
- _getCGLAttribute( kCGLPFAAccelerated, _glfwWin.accelerated );
|
|
|
- _getCGLAttribute( kCGLPFAAlphaSize, _glfwWin.alphaBits );
|
|
|
- _getCGLAttribute( kCGLPFADepthSize, _glfwWin.depthBits );
|
|
|
- _getCGLAttribute( kCGLPFAStencilSize, _glfwWin.stencilBits );
|
|
|
- _getCGLAttribute( kCGLPFAAuxBuffers, _glfwWin.auxBuffers );
|
|
|
- _getCGLAttribute( kCGLPFAStereo, _glfwWin.stereo );
|
|
|
- _getCGLAttribute( kCGLPFASamples, _glfwWin.samples );
|
|
|
-
|
|
|
- // Enumerate depth of RGB channels - unlike AGL, CGL works with
|
|
|
- // a single parameter reflecting the full depth of the frame buffer
|
|
|
- (void)CGLDescribePixelFormat( _glfwWin.cglPixelFormat,
|
|
|
- 0,
|
|
|
- kCGLPFAColorSize,
|
|
|
- &rgbColorDepth );
|
|
|
-
|
|
|
- if( rgbColorDepth == 24 || rgbColorDepth == 32 )
|
|
|
- {
|
|
|
- rgbChannelDepth = 8;
|
|
|
- }
|
|
|
- if( rgbColorDepth == 16 )
|
|
|
- {
|
|
|
- rgbChannelDepth = 5;
|
|
|
- }
|
|
|
-
|
|
|
- _glfwWin.redBits = rgbChannelDepth;
|
|
|
- _glfwWin.greenBits = rgbChannelDepth;
|
|
|
- _glfwWin.blueBits = rgbChannelDepth;
|
|
|
-
|
|
|
- // Get pixel depth of accumulator - I haven't got the slightest idea
|
|
|
- // how this number conforms to any other channel depth than 8 bits,
|
|
|
- // so this might end up giving completely knackered results...
|
|
|
- _getCGLAttribute( kCGLPFAColorSize, rgbaAccumDepth );
|
|
|
- if( rgbaAccumDepth == 32 )
|
|
|
- {
|
|
|
- rgbaAccumDepth = 8;
|
|
|
- }
|
|
|
-
|
|
|
- _glfwWin.accumRedBits = rgbaAccumDepth;
|
|
|
- _glfwWin.accumGreenBits = rgbaAccumDepth;
|
|
|
- _glfwWin.accumBlueBits = rgbaAccumDepth;
|
|
|
- _glfwWin.accumAlphaBits = rgbaAccumDepth;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- _getAGLAttribute( AGL_ACCELERATED, _glfwWin.accelerated );
|
|
|
- _getAGLAttribute( AGL_RED_SIZE, _glfwWin.redBits );
|
|
|
- _getAGLAttribute( AGL_GREEN_SIZE, _glfwWin.greenBits );
|
|
|
- _getAGLAttribute( AGL_BLUE_SIZE, _glfwWin.blueBits );
|
|
|
- _getAGLAttribute( AGL_ALPHA_SIZE, _glfwWin.alphaBits );
|
|
|
- _getAGLAttribute( AGL_DEPTH_SIZE, _glfwWin.depthBits );
|
|
|
- _getAGLAttribute( AGL_STENCIL_SIZE, _glfwWin.stencilBits );
|
|
|
- _getAGLAttribute( AGL_ACCUM_RED_SIZE, _glfwWin.accumRedBits );
|
|
|
- _getAGLAttribute( AGL_ACCUM_GREEN_SIZE, _glfwWin.accumGreenBits );
|
|
|
- _getAGLAttribute( AGL_ACCUM_BLUE_SIZE, _glfwWin.accumBlueBits );
|
|
|
- _getAGLAttribute( AGL_ACCUM_ALPHA_SIZE, _glfwWin.accumAlphaBits );
|
|
|
- _getAGLAttribute( AGL_AUX_BUFFERS, _glfwWin.auxBuffers );
|
|
|
- _getAGLAttribute( AGL_STEREO, _glfwWin.stereo );
|
|
|
- _getAGLAttribute( AGL_SAMPLES_ARB, _glfwWin.samples );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Poll for new window and input events
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformPollEvents( void )
|
|
|
-{
|
|
|
- EventRef event;
|
|
|
- EventTargetRef eventDispatcher = GetEventDispatcherTarget();
|
|
|
-
|
|
|
- while ( ReceiveNextEvent( 0, NULL, 0.0, TRUE, &event ) == noErr )
|
|
|
- {
|
|
|
- SendEventToEventTarget( event, eventDispatcher );
|
|
|
- ReleaseEvent( event );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Wait for new window and input events
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformWaitEvents( void )
|
|
|
-{
|
|
|
- EventRef event;
|
|
|
-
|
|
|
- // Wait for new events
|
|
|
- ReceiveNextEvent( 0, NULL, kEventDurationForever, FALSE, &event );
|
|
|
-
|
|
|
- // Process the new events
|
|
|
- _glfwPlatformPollEvents();
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Hide mouse cursor (lock it)
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformHideMouseCursor( void )
|
|
|
-{
|
|
|
- CGDisplayHideCursor( kCGDirectMainDisplay );
|
|
|
- CGAssociateMouseAndMouseCursorPosition( false );
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Show mouse cursor (unlock it)
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformShowMouseCursor( void )
|
|
|
-{
|
|
|
- CGDisplayShowCursor( kCGDirectMainDisplay );
|
|
|
- CGAssociateMouseAndMouseCursorPosition( true );
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-// Set physical mouse cursor position
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-void _glfwPlatformSetMouseCursorPos( int x, int y )
|
|
|
-{
|
|
|
- Rect content;
|
|
|
-
|
|
|
- if( _glfwWin.fullscreen )
|
|
|
- {
|
|
|
- CGDisplayMoveCursorToPoint( kCGDirectMainDisplay,
|
|
|
- CGPointMake( x, y ) );
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- GetWindowBounds(_glfwWin.window, kWindowContentRgn, &content);
|
|
|
-
|
|
|
- _glfwInput.MousePosX = x + content.left;
|
|
|
- _glfwInput.MousePosY = y + content.top;
|
|
|
-
|
|
|
- CGDisplayMoveCursorToPoint( kCGDirectMainDisplay,
|
|
|
- CGPointMake( _glfwInput.MousePosX,
|
|
|
- _glfwInput.MousePosY ) );
|
|
|
- }
|
|
|
-}
|
|
|
-
|