bluecore/glfw/lib/window.c

730 lines
20 KiB
C

//========================================================================
// GLFW - An OpenGL framework
// File: window.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// 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.
//
//------------------------------------------------------------------------
// $Id: window.c,v 1.15 2007/03/15 03:20:19 elmindreda Exp $
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// Clear all open window hints
//========================================================================
void _glfwClearWindowHints( void )
{
_glfwWinHints.RefreshRate = 0;
_glfwWinHints.AccumRedBits = 0;
_glfwWinHints.AccumGreenBits = 0;
_glfwWinHints.AccumBlueBits = 0;
_glfwWinHints.AccumAlphaBits = 0;
_glfwWinHints.AuxBuffers = 0;
_glfwWinHints.Stereo = 0;
_glfwWinHints.WindowNoResize = 0;
_glfwWinHints.Samples = 0;
}
//========================================================================
// Handle the input tracking part of window deactivation
//========================================================================
void _glfwInputDeactivation( void )
{
int i;
// Release all keyboard keys
for( i = 0; i <= GLFW_KEY_LAST; i ++ )
{
if( _glfwInput.Key[ i ] == GLFW_PRESS )
{
_glfwInputKey( i, GLFW_RELEASE );
}
}
// Release all mouse buttons
for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ )
{
if( _glfwInput.MouseButton[ i ] == GLFW_PRESS )
{
_glfwInputMouseClick( i, GLFW_RELEASE );
}
}
}
//========================================================================
// _glfwClearInput() - Clear all input state
//========================================================================
void _glfwClearInput( void )
{
int i;
// Release all keyboard keys
for( i = 0; i <= GLFW_KEY_LAST; i ++ )
{
_glfwInput.Key[ i ] = GLFW_RELEASE;
}
// Clear last character
_glfwInput.LastChar = 0;
// Release all mouse buttons
for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ )
{
_glfwInput.MouseButton[ i ] = GLFW_RELEASE;
}
// Set mouse position to (0,0)
_glfwInput.MousePosX = 0;
_glfwInput.MousePosY = 0;
// Set mouse wheel position to 0
_glfwInput.WheelPos = 0;
// The default is to use non sticky keys and mouse buttons
_glfwInput.StickyKeys = GL_FALSE;
_glfwInput.StickyMouseButtons = GL_FALSE;
// The default is to disable key repeat
_glfwInput.KeyRepeat = GL_FALSE;
}
//========================================================================
// _glfwInputKey() - Register keyboard activity
//========================================================================
void _glfwInputKey( int key, int action )
{
int keyrepeat = 0;
if( key < 0 || key > GLFW_KEY_LAST )
{
return;
}
// Are we trying to release an already released key?
if( action == GLFW_RELEASE && _glfwInput.Key[ key ] != GLFW_PRESS )
{
return;
}
// Register key action
if( action == GLFW_RELEASE && _glfwInput.StickyKeys )
{
_glfwInput.Key[ key ] = GLFW_STICK;
}
else
{
keyrepeat = (_glfwInput.Key[ key ] == GLFW_PRESS) &&
(action == GLFW_PRESS);
_glfwInput.Key[ key ] = (char) action;
}
// Call user callback function
if( _glfwWin.KeyCallback && (_glfwInput.KeyRepeat || !keyrepeat) )
{
_glfwWin.KeyCallback( key, action );
}
}
//========================================================================
// _glfwInputChar() - Register (keyboard) character activity
//========================================================================
void _glfwInputChar( int character, int action )
{
int keyrepeat = 0;
// Valid Unicode (ISO 10646) character?
if( !( (character >= 32 && character <= 126) || character >= 160 ) )
{
return;
}
// Is this a key repeat?
if( action == GLFW_PRESS && _glfwInput.LastChar == character )
{
keyrepeat = 1;
}
// Store this character as last character (or clear it, if released)
if( action == GLFW_PRESS )
{
_glfwInput.LastChar = character;
}
else
{
_glfwInput.LastChar = 0;
}
// Call user callback function
if( _glfwWin.CharCallback && (_glfwInput.KeyRepeat || !keyrepeat) )
{
_glfwWin.CharCallback( character, action );
}
}
//========================================================================
// _glfwInputMouseClick() - Register mouse button clicks
//========================================================================
void _glfwInputMouseClick( int button, int action )
{
if( button >= 0 && button <= GLFW_MOUSE_BUTTON_LAST )
{
// Register mouse button action
if( action == GLFW_RELEASE && _glfwInput.StickyMouseButtons )
{
_glfwInput.MouseButton[ button ] = GLFW_STICK;
}
else
{
_glfwInput.MouseButton[ button ] = (char) action;
}
// Call user callback function
if( _glfwWin.MouseButtonCallback )
{
_glfwWin.MouseButtonCallback( button, action );
}
}
}
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwOpenWindow() - Here is where the window is created, and the OpenGL
// rendering context is created
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height,
int redbits, int greenbits, int bluebits, int alphabits,
int depthbits, int stencilbits, int mode )
{
int x;
_GLFWhints hints;
// Is GLFW initialized?
if( !_glfwInitialized || _glfwWin.Opened )
{
return GL_FALSE;
}
// Copy and clear window hints
hints = _glfwWinHints;
_glfwClearWindowHints();
// Check input arguments
if( mode != GLFW_WINDOW && mode != GLFW_FULLSCREEN )
{
return GL_FALSE;
}
// Clear GLFW window state
_glfwWin.Active = GL_TRUE;
_glfwWin.Iconified = GL_FALSE;
_glfwWin.MouseLock = GL_FALSE;
_glfwWin.AutoPollEvents = GL_TRUE;
_glfwClearInput();
// Unregister all callback functions
_glfwWin.WindowSizeCallback = NULL;
_glfwWin.WindowCloseCallback = NULL;
_glfwWin.WindowRefreshCallback = NULL;
_glfwWin.KeyCallback = NULL;
_glfwWin.CharCallback = NULL;
_glfwWin.MousePosCallback = NULL;
_glfwWin.MouseButtonCallback = NULL;
_glfwWin.MouseWheelCallback = NULL;
// Check width & height
if( width > 0 && height <= 0 )
{
// Set the window aspect ratio to 4:3
height = (width * 3) / 4;
}
else if( width <= 0 && height > 0 )
{
// Set the window aspect ratio to 4:3
width = (height * 4) / 3;
}
else if( width <= 0 && height <= 0 )
{
// Default window size
width = 640;
height = 480;
}
// Remember window settings
_glfwWin.Width = width;
_glfwWin.Height = height;
_glfwWin.Fullscreen = (mode == GLFW_FULLSCREEN ? 1 : 0);
// Platform specific window opening routine
if( !_glfwPlatformOpenWindow( width, height, redbits, greenbits,
bluebits, alphabits, depthbits, stencilbits, mode, &hints ) )
{
return GL_FALSE;
}
// Flag that window is now opened
_glfwWin.Opened = GL_TRUE;
// Get window parameters (such as color buffer bits etc)
_glfwPlatformRefreshWindowParams();
// Get OpenGL version
glfwGetGLVersion( &_glfwWin.GLVerMajor, &_glfwWin.GLVerMinor, &x );
// Do we have non-power-of-two textures?
_glfwWin.Has_GL_ARB_texture_non_power_of_two =
glfwExtensionSupported( "GL_ARB_texture_non_power_of_two" );
// Do we have automatic mipmap generation?
_glfwWin.Has_GL_SGIS_generate_mipmap =
(_glfwWin.GLVerMajor >= 2) || (_glfwWin.GLVerMinor >= 4) ||
glfwExtensionSupported( "GL_SGIS_generate_mipmap" );
// If full-screen mode was requested, disable mouse cursor
if( mode == GLFW_FULLSCREEN )
{
glfwDisable( GLFW_MOUSE_CURSOR );
}
return GL_TRUE;
}
//========================================================================
// glfwOpenWindowHint() - Set hints for opening the window
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
switch( target )
{
case GLFW_REFRESH_RATE:
_glfwWinHints.RefreshRate = hint;
break;
case GLFW_ACCUM_RED_BITS:
_glfwWinHints.AccumRedBits = hint;
break;
case GLFW_ACCUM_GREEN_BITS:
_glfwWinHints.AccumGreenBits = hint;
break;
case GLFW_ACCUM_BLUE_BITS:
_glfwWinHints.AccumBlueBits = hint;
break;
case GLFW_ACCUM_ALPHA_BITS:
_glfwWinHints.AccumAlphaBits = hint;
break;
case GLFW_AUX_BUFFERS:
_glfwWinHints.AuxBuffers = hint;
break;
case GLFW_STEREO:
_glfwWinHints.Stereo = hint;
break;
case GLFW_WINDOW_NO_RESIZE:
_glfwWinHints.WindowNoResize = hint;
break;
case GLFW_FSAA_SAMPLES:
_glfwWinHints.Samples = hint;
break;
default:
break;
}
}
//========================================================================
// glfwCloseWindow() - Properly kill the window / video display
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
// Show mouse pointer again (if hidden)
glfwEnable( GLFW_MOUSE_CURSOR );
// Close window
_glfwPlatformCloseWindow();
// Window is no longer opened
_glfwWin.Opened = GL_FALSE;
}
//========================================================================
// glfwSetWindowTitle() - Set the window title
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set window title
_glfwPlatformSetWindowTitle( title );
}
//========================================================================
// glfwGetWindowSize() - Get the window size
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height )
{
if( width != NULL )
{
*width = _glfwWin.Width;
}
if( height != NULL )
{
*height = _glfwWin.Height;
}
}
//========================================================================
// glfwSetWindowSize() - Set the window size
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Iconified )
{
return;
}
// Don't do anything if the window size did not change
if( width == _glfwWin.Width && height == _glfwWin.Height )
{
return;
}
// Change window size
_glfwPlatformSetWindowSize( width, height );
// Refresh window parameters (may have changed due to changed video
// modes)
_glfwPlatformRefreshWindowParams();
}
//========================================================================
// glfwSetWindowPos() - Set the window position
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Fullscreen ||
_glfwWin.Iconified )
{
return;
}
// Set window position
_glfwPlatformSetWindowPos( x, y );
}
//========================================================================
// glfwIconfyWindow() - Window iconification
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Iconified )
{
return;
}
// Iconify window
_glfwPlatformIconifyWindow();
}
//========================================================================
// glfwRestoreWindow() - Window un-iconification
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened || !_glfwWin.Iconified )
{
return;
}
// Restore iconified window
_glfwPlatformRestoreWindow();
// Refresh window parameters
_glfwPlatformRefreshWindowParams();
}
//========================================================================
// glfwSwapBuffers() - Swap buffers (double-buffering) and poll any new
// events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Check for window messages
if( _glfwWin.AutoPollEvents )
{
glfwPollEvents();
}
// Update display-buffer
if( _glfwWin.Opened )
{
_glfwPlatformSwapBuffers();
}
}
//========================================================================
// glfwSwapInterval() - Set double buffering swap interval (0 = vsync off)
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set double buffering swap interval
_glfwPlatformSwapInterval( interval );
}
//========================================================================
// glfwGetWindowParam() - Get window parameter
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return 0;
}
// Is the window opened?
if( !_glfwWin.Opened )
{
if( param == GLFW_OPENED )
{
return GL_FALSE;
}
return 0;
}
// Window parameters
switch( param )
{
case GLFW_OPENED:
return GL_TRUE;
case GLFW_ACTIVE:
return _glfwWin.Active;
case GLFW_ICONIFIED:
return _glfwWin.Iconified;
case GLFW_ACCELERATED:
return _glfwWin.Accelerated;
case GLFW_RED_BITS:
return _glfwWin.RedBits;
case GLFW_GREEN_BITS:
return _glfwWin.GreenBits;
case GLFW_BLUE_BITS:
return _glfwWin.BlueBits;
case GLFW_ALPHA_BITS:
return _glfwWin.AlphaBits;
case GLFW_DEPTH_BITS:
return _glfwWin.DepthBits;
case GLFW_STENCIL_BITS:
return _glfwWin.StencilBits;
case GLFW_ACCUM_RED_BITS:
return _glfwWin.AccumRedBits;
case GLFW_ACCUM_GREEN_BITS:
return _glfwWin.AccumGreenBits;
case GLFW_ACCUM_BLUE_BITS:
return _glfwWin.AccumBlueBits;
case GLFW_ACCUM_ALPHA_BITS:
return _glfwWin.AccumAlphaBits;
case GLFW_AUX_BUFFERS:
return _glfwWin.AuxBuffers;
case GLFW_STEREO:
return _glfwWin.Stereo;
case GLFW_REFRESH_RATE:
return _glfwWin.RefreshRate;
case GLFW_WINDOW_NO_RESIZE:
return _glfwWin.WindowNoResize;
case GLFW_FSAA_SAMPLES:
return _glfwWin.Samples;
default:
return 0;
}
}
//========================================================================
// glfwSetWindowSizeCallback() - Set callback function for window size
// changes
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.WindowSizeCallback = cbfun;
// Call the callback function to let the application know the current
// window size
if( cbfun )
{
cbfun( _glfwWin.Width, _glfwWin.Height );
}
}
//========================================================================
// glfwSetWindowCloseCallback() - Set callback function for window close
// events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.WindowCloseCallback = cbfun;
}
//========================================================================
// glfwSetWindowRefreshCallback() - Set callback function for window
// refresh events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.WindowRefreshCallback = cbfun;
}
//========================================================================
// glfwPollEvents() - Poll for new window and input events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwPollEvents( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Poll for new events
_glfwPlatformPollEvents();
}
//========================================================================
// glfwWaitEvents() - Wait for new window and input events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Poll for new events
_glfwPlatformWaitEvents();
}