Merge branch 'master' into tls

Conflicts:
	src/x11_window.c
This commit is contained in:
Camilla Berglund 2012-08-26 21:56:20 +02:00
commit 035a8f4a49
16 changed files with 468 additions and 509 deletions

View File

@ -1,22 +1,29 @@
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
STRING(REGEX REPLACE "\n" ";" files "${files}")
FOREACH(file ${files})
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
IF(EXISTS "$ENV{DESTDIR}${file}")
EXEC_PROGRAM(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
IF(NOT "${rm_retval}" STREQUAL 0)
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif()
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach (file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if (EXISTS "$ENV{DESTDIR}${file}")
exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval)
if (NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
ENDIF(NOT "${rm_retval}" STREQUAL 0)
ELSE(EXISTS "$ENV{DESTDIR}${file}")
MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
ENDIF(EXISTS "$ENV{DESTDIR}${file}")
ENDFOREACH(file)
endif()
elseif (IS_SYMLINK "$ENV{DESTDIR}${file}")
EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval)
if (NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"")
endif()
else()
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif()
endforeach()

View File

@ -3,7 +3,7 @@ include_directories(${GLFW_SOURCE_DIR}/src
${glfw_INCLUDE_DIRS})
set(common_HEADERS ${GLFW_SOURCE_DIR}/include/GL/glfw3.h internal.h)
set(common_SOURCES clipboard.c error.c fullscreen.c gamma.c init.c input.c
set(common_SOURCES clipboard.c fullscreen.c gamma.c init.c input.c
joystick.c opengl.c time.c window.c)
if (_GLFW_COCOA_NSGL)
@ -40,10 +40,13 @@ if (BUILD_SHARED_LIBS)
if (_GLFW_WIN32_WGL)
# The GLFW DLL needs a special compile-time macro and import library name
set_target_properties(glfw PROPERTIES
PREFIX ""
IMPORT_PREFIX ""
IMPORT_SUFFIX "dll.lib")
set_target_properties(glfw PROPERTIES PREFIX "" IMPORT_PREFIX "")
if (MINGW)
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a")
else()
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib")
endif()
elseif (_GLFW_COCOA_NSGL)
# Append -fno-common to the compile flags to work around a bug in the Apple GCC
get_target_property(glfw_CFLAGS glfw COMPILE_FLAGS)

View File

@ -40,7 +40,7 @@
//************************************************************************
//========================================================================
// Save the original gamma ramp so that we can restore it later
// Save the original gamma ramp so that it can be restored later
//========================================================================
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)

View File

@ -40,13 +40,14 @@
void _glfwPlatformEnableSystemKeys(_GLFWwindow* window)
{
// This is checked in macosx_window.m; we take no action here
// This is checked in cocoa_window.m; no action needed here
}
void _glfwPlatformDisableSystemKeys(_GLFWwindow* window)
{
// This is checked in macosx_window.m; we take no action here
// I don't think it's really possible to disable stuff like Exposé
// This is checked in cocoa_window.m; no action needed here
// Note that it may not be possible to disable things like Exposé
// except in full-screen mode.
}

View File

@ -5,6 +5,7 @@
// WWW: http://www.glfw.org/
//------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -46,7 +47,6 @@
//------------------------------------------------------------------------
// Joystick element information
//------------------------------------------------------------------------
typedef struct
{
IOHIDElementCookie cookie;
@ -65,7 +65,6 @@ typedef struct
//------------------------------------------------------------------------
// Joystick information & state
//------------------------------------------------------------------------
typedef struct
{
int present;
@ -86,7 +85,7 @@ typedef struct
static _glfwJoystick _glfwJoysticks[GLFW_JOYSTICK_LAST + 1];
void GetElementsCFArrayHandler(const void* value, void* parameter);
static void getElementsCFArrayHandler(const void* value, void* parameter);
//========================================================================
@ -112,7 +111,7 @@ static void addJoystickElement(_glfwJoystick* joystick, CFTypeRef refElement)
(elementType == kIOHIDElementTypeInput_Button) ||
(elementType == kIOHIDElementTypeInput_Misc))
{
switch (usagePage) /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */
switch (usagePage)
{
case kHIDPage_GenericDesktop:
{
@ -175,10 +174,10 @@ static void addJoystickElement(_glfwJoystick* joystick, CFTypeRef refElement)
if (refElementTop)
{
CFTypeID type = CFGetTypeID (refElementTop);
if (type == CFArrayGetTypeID()) /* if element is an array */
if (type == CFArrayGetTypeID())
{
CFRange range = {0, CFArrayGetCount (refElementTop)};
CFArrayApplyFunction(refElementTop, range, GetElementsCFArrayHandler, joystick);
CFArrayApplyFunction(refElementTop, range, getElementsCFArrayHandler, joystick);
}
}
}
@ -189,7 +188,7 @@ static void addJoystickElement(_glfwJoystick* joystick, CFTypeRef refElement)
// Adds an element to the specified joystick
//========================================================================
void GetElementsCFArrayHandler(const void* value, void* parameter)
static void getElementsCFArrayHandler(const void* value, void* parameter)
{
if (CFGetTypeID(value) == CFDictionaryGetTypeID())
addJoystickElement((_glfwJoystick*) parameter, (CFTypeRef) value);
@ -213,7 +212,7 @@ static long getElementValue(_glfwJoystick* joystick, _glfwJoystickElement* eleme
&hidEvent);
if (kIOReturnSuccess == result)
{
/* record min and max for auto calibration */
// Record min and max for auto calibration
if (hidEvent.value < element->minReport)
element->minReport = hidEvent.value;
if (hidEvent.value > element->maxReport)
@ -221,7 +220,7 @@ static long getElementValue(_glfwJoystick* joystick, _glfwJoystickElement* eleme
}
}
/* auto user scale */
// Auto user scale
return (long) hidEvent.value;
}
@ -284,7 +283,7 @@ static void removalCallback(void* target, IOReturn result, void* refcon, void* s
//========================================================================
// Polls for joystick events and updates GFLW state
// Polls for joystick events and updates GLFW state
//========================================================================
static void pollJoystickEvents(void)
@ -340,13 +339,15 @@ void _glfwInitJoysticks(void)
CFMutableDictionaryRef hidMatchDictionary = NULL;
io_object_t ioHIDDeviceObject = 0;
memset(&_glfwJoysticks, 0, sizeof(_glfwJoysticks));
result = IOMasterPort(bootstrap_port, &masterPort);
hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
if (kIOReturnSuccess != result || !hidMatchDictionary)
{
if (hidMatchDictionary)
CFRelease(hidMatchDictionary);
return;
}
@ -356,8 +357,11 @@ void _glfwInitJoysticks(void)
if (result != kIOReturnSuccess)
return;
if (!objectIterator) /* there are no joysticks */
if (!objectIterator)
{
// There are no joysticks
return;
}
while ((ioHIDDeviceObject = IOIteratorNext(objectIterator)))
{
@ -379,14 +383,14 @@ void _glfwInitJoysticks(void)
if (result != kIOReturnSuccess)
continue;
/* Check device type */
// Check device type
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey));
if (refCF)
{
CFNumberGetValue(refCF, kCFNumberLongType, &usagePage);
if (usagePage != kHIDPage_GenericDesktop)
{
/* We are not interested in this device */
// This device is not relevant to GLFW
continue;
}
}
@ -395,12 +399,12 @@ void _glfwInitJoysticks(void)
if (refCF)
{
CFNumberGetValue(refCF, kCFNumberLongType, &usage);
if ((usage != kHIDUsage_GD_Joystick &&
usage != kHIDUsage_GD_GamePad &&
usage != kHIDUsage_GD_MultiAxisController))
{
/* We are not interested in this device */
// This device is not relevant to GLFW
continue;
}
}
@ -434,7 +438,7 @@ void _glfwInitJoysticks(void)
joystick,
joystick);
/* Get product string */
// Get product string
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
if (refCF)
{
@ -459,7 +463,7 @@ void _glfwInitJoysticks(void)
CFRange range = { 0, CFArrayGetCount(refTopElement) };
CFArrayApplyFunction(refTopElement,
range,
GetElementsCFArrayHandler,
getElementsCFArrayHandler,
(void*) joystick);
}
@ -509,7 +513,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
return (int) CFArrayGetCount(_glfwJoysticks[joy].axes);
case GLFW_BUTTONS:
return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons) + ((int) CFArrayGetCount(_glfwJoysticks[joy].hats)) * 4;
return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons) +
(int) CFArrayGetCount(_glfwJoysticks[joy].hats) * 4;
default:
break;
@ -555,8 +560,6 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
else
pos[i] = (2.0f * (axes->value - axes->minReport) / readScale) - 1.0f;
//printf("%ld, %ld, %ld\n", axes->value, axes->minReport, axes->maxReport);
if (i & 1)
pos[i] = -pos[i];
}
@ -597,19 +600,28 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
// Virtual buttons - Inject data from hats
// Each hat is exposed as 4 buttons which exposes 8 directions with concurrent button presses
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; // Bit fields of button presses for each direction, including nil
// Bit fields of button presses for each direction, including nil
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
for (i = 0; i < joystick.numHats; i++)
{
_glfwJoystickElement* hat = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.hats, i);
int value = hat->value;
if (value < 0 || value > 8) value = 8;
for (j = 0; j < 4 && button < numbuttons; j++)
int value = hat->value;
if (value < 0 || value > 8)
value = 8;
for (j = 0; j < 4 && button < numbuttons; j++)
{
buttons[button++] = directions[value] & (1 << j) ? GLFW_PRESS : GLFW_RELEASE;
if (directions[value] & (1 << j))
buttons[button] = GLFW_PRESS;
else
buttons[button] = GLFW_RELEASE;
button++;
}
}
return button;
}

View File

@ -277,9 +277,6 @@ static int convertMacKeyCode(unsigned int macKeyCode)
if (macKeyCode >= 128)
return -1;
// This treats keycodes as *positional*; that is, we'll return 'a'
// for the key left of 's', even on an AZERTY keyboard. The charInput
// function should still get 'q' though.
return table[macKeyCode];
}
@ -541,7 +538,7 @@ static NSString* findAppName(void)
}
}
// If we get here, we're unbundled
// If we get here, the application is unbundled
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
@ -551,10 +548,7 @@ static NSString* findAppName(void)
char** progname = _NSGetProgname();
if (progname && *progname)
{
// TODO: UTF-8?
return [NSString stringWithUTF8String:*progname];
}
// Really shouldn't get here
return @"GLFW Application";
@ -866,8 +860,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!initializeAppKit())
return GL_FALSE;
// We can only have one application delegate, but we only allocate it the
// first time we create a window to keep all window code in this file
// There can only be one application delegate, but we allocate it the
// first time a window is created to keep all window code in this file
if (_glfwLibrary.NS.delegate == nil)
{
_glfwLibrary.NS.delegate = [[GLFWApplicationDelegate alloc] init];

View File

@ -1,149 +0,0 @@
//========================================================================
// GLFW - An OpenGL library
// Platform: All
// API version: 3.0
// WWW: http://www.glfw.org/
//------------------------------------------------------------------------
// Copyright (c) 2008-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// 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"
#include <stdio.h>
#include <stdarg.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
// The current error value and callback
// These are not in _glfwLibrary since they need to be initialized and
// accessible before glfwInit so it can report errors
//========================================================================
static int _glfwError = GLFW_NO_ERROR;
static GLFWerrorfun _glfwErrorCallback = NULL;
//========================================================================
// Sets the current error value
// This function may be called without GLFW having been initialized
//========================================================================
void _glfwSetError(int error, const char* format, ...)
{
if (_glfwErrorCallback)
{
char buffer[16384];
const char* description;
if (format)
{
int count;
va_list vl;
va_start(vl, format);
count = vsnprintf(buffer, sizeof(buffer), format, vl);
va_end(vl);
if (count < 0)
buffer[sizeof(buffer) - 1] = '\0';
description = buffer;
}
else
description = glfwErrorString(error);
_glfwErrorCallback(error, description);
}
else
_glfwError = error;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
// Returns the current error value
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI int glfwGetError(void)
{
int error = _glfwError;
_glfwError = GLFW_NO_ERROR;
return error;
}
//========================================================================
// Returns a string representation of the specified error value
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI const char* glfwErrorString(int error)
{
switch (error)
{
case GLFW_NO_ERROR:
return "No error";
case GLFW_NOT_INITIALIZED:
return "The GLFW library is not initialized";
case GLFW_NO_CURRENT_CONTEXT:
return "There is no current OpenGL context";
case GLFW_INVALID_ENUM:
return "Invalid argument for enum parameter";
case GLFW_INVALID_VALUE:
return "Invalid value for parameter";
case GLFW_OUT_OF_MEMORY:
return "Out of memory";
case GLFW_OPENGL_UNAVAILABLE:
return "OpenGL is not available on this machine";
case GLFW_VERSION_UNAVAILABLE:
return "The requested OpenGL version is unavailable";
case GLFW_PLATFORM_ERROR:
return "A platform-specific error occurred";
case GLFW_WINDOW_NOT_ACTIVE:
return "The specified window is not active";
case GLFW_FORMAT_UNAVAILABLE:
return "The requested format is unavailable";
}
return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString";
}
//========================================================================
// Sets the callback function for GLFW errors
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun)
{
_glfwErrorCallback = cbfun;
}

View File

@ -6,6 +6,7 @@
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -31,7 +32,11 @@
#include "internal.h"
#include <stdlib.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif
//========================================================================
@ -87,7 +92,7 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
{
int delta;
// We assume that by 32 they really meant 24
// We assume that by 32 the user really meant 24
if (bpp == 32)
bpp = 24;

View File

@ -28,11 +28,82 @@
//
//========================================================================
#define _init_c_
#include "internal.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
//------------------------------------------------------------------------
// Flag indicating whether GLFW has been successfully initialized
//------------------------------------------------------------------------
GLboolean _glfwInitialized = GL_FALSE;
//------------------------------------------------------------------------
// All shared and API-specific global data protected by _glfwInitialized
// This should only be touched after a call to glfwInit that has not been
// followed by a call to glfwTerminate
//------------------------------------------------------------------------
_GLFWlibrary _glfwLibrary;
//------------------------------------------------------------------------
// The current GLFW error code
// This is outside of _glfwLibrary so it can be initialized and usable
// before glfwInit is called, which lets that function report errors
// TODO: Make this thread-local
//------------------------------------------------------------------------
static int _glfwError = GLFW_NO_ERROR;
//------------------------------------------------------------------------
// The current error callback
// This is outside of _glfwLibrary so it can be initialized and usable
// before glfwInit is called, which lets that function report errors
//------------------------------------------------------------------------
static GLFWerrorfun _glfwErrorCallback = NULL;
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
// Sets the current error value
//========================================================================
void _glfwSetError(int error, const char* format, ...)
{
if (_glfwErrorCallback)
{
char buffer[16384];
const char* description;
if (format)
{
int count;
va_list vl;
va_start(vl, format);
count = vsnprintf(buffer, sizeof(buffer), format, vl);
va_end(vl);
if (count < 0)
buffer[sizeof(buffer) - 1] = '\0';
description = buffer;
}
else
description = glfwErrorString(error);
_glfwErrorCallback(error, description);
}
else
_glfwError = error;
}
//////////////////////////////////////////////////////////////////////////
@ -50,8 +121,7 @@ GLFWAPI int glfwInit(void)
memset(&_glfwLibrary, 0, sizeof(_glfwLibrary));
// Not all window hints have zero as their default value, so this
// needs to be here despite the memset above
// Not all window hints have zero as their default value
_glfwSetDefaultWindowHints();
if (!_glfwPlatformInit())
@ -93,6 +163,7 @@ GLFWAPI void glfwTerminate(void)
//========================================================================
// Get GLFW version
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
@ -110,6 +181,7 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
//========================================================================
// Get the GLFW version string
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI const char* glfwGetVersionString(void)
@ -117,3 +189,64 @@ GLFWAPI const char* glfwGetVersionString(void)
return _glfwPlatformGetVersionString();
}
//========================================================================
// Returns the current error value
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI int glfwGetError(void)
{
int error = _glfwError;
_glfwError = GLFW_NO_ERROR;
return error;
}
//========================================================================
// Returns a string representation of the specified error value
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI const char* glfwErrorString(int error)
{
switch (error)
{
case GLFW_NO_ERROR:
return "No error";
case GLFW_NOT_INITIALIZED:
return "The GLFW library is not initialized";
case GLFW_NO_CURRENT_CONTEXT:
return "There is no current OpenGL context";
case GLFW_INVALID_ENUM:
return "Invalid argument for enum parameter";
case GLFW_INVALID_VALUE:
return "Invalid value for parameter";
case GLFW_OUT_OF_MEMORY:
return "Out of memory";
case GLFW_OPENGL_UNAVAILABLE:
return "OpenGL is not available on this machine";
case GLFW_VERSION_UNAVAILABLE:
return "The requested OpenGL version is unavailable";
case GLFW_PLATFORM_ERROR:
return "A platform-specific error occurred";
case GLFW_WINDOW_NOT_ACTIVE:
return "The specified window is not active";
case GLFW_FORMAT_UNAVAILABLE:
return "The requested format is unavailable";
}
return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString";
}
//========================================================================
// Sets the callback function for GLFW errors
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun)
{
_glfwErrorCallback = cbfun;
}

View File

@ -31,17 +31,6 @@
#ifndef _internal_h_
#define _internal_h_
//========================================================================
// GLFWGLOBAL is a macro that places all global variables in the init.c
// module (all other modules reference global variables as 'extern')
//========================================================================
#if defined(_init_c_)
#define GLFWGLOBAL
#else
#define GLFWGLOBAL extern
#endif
//========================================================================
// Input handling definitions
@ -243,18 +232,12 @@ struct _GLFWlibrary
};
//========================================================================
// System independent global variables (GLFW internals)
//========================================================================
// Flag indicating if GLFW has been initialized
#if defined(_init_c_)
GLboolean _glfwInitialized = GL_FALSE;
#else
GLFWGLOBAL GLboolean _glfwInitialized;
#endif
GLFWGLOBAL _GLFWlibrary _glfwLibrary;
//------------------------------------------------------------------------
// Global state shared between compilation units of GLFW
// These are exported from and documented in init.c
//------------------------------------------------------------------------
extern GLboolean _glfwInitialized;
extern _GLFWlibrary _glfwLibrary;
//========================================================================
@ -325,7 +308,7 @@ void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long
int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second);
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
// Error handling (error.c)
// Error handling (init.c)
void _glfwSetError(int error, const char* format, ...);
// Window management (window.c)

View File

@ -47,6 +47,12 @@ GLFWAPI int glfwGetJoystickParam(int joy, int param)
return 0;
}
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
{
_glfwSetError(GLFW_INVALID_ENUM, NULL);
return 0;
}
return _glfwPlatformGetJoystickParam(joy, param);
}
@ -65,6 +71,18 @@ GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes)
return 0;
}
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
{
_glfwSetError(GLFW_INVALID_ENUM, NULL);
return 0;
}
if (pos == NULL || numaxes < 0)
{
_glfwSetError(GLFW_INVALID_VALUE, NULL);
return 0;
}
// Clear positions
for (i = 0; i < numaxes; i++)
pos[i] = 0.0f;
@ -89,6 +107,18 @@ GLFWAPI int glfwGetJoystickButtons(int joy,
return 0;
}
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
{
_glfwSetError(GLFW_INVALID_ENUM, NULL);
return 0;
}
if (buttons == NULL || numbuttons < 0)
{
_glfwSetError(GLFW_INVALID_VALUE, NULL);
return 0;
}
// Clear button states
for (i = 0; i < numbuttons; i++)
buttons[i] = GLFW_RELEASE;

View File

@ -6,6 +6,7 @@
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -32,7 +33,11 @@
#include <string.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif
//========================================================================

View File

@ -30,47 +30,128 @@
#include "internal.h"
//========================================================================
// Note: Only Linux joystick input is supported at the moment. Other
// systems will behave as if there are no joysticks connected.
//========================================================================
#ifdef _GLFW_USE_LINUX_JOYSTICKS
#include <linux/joystick.h>
//------------------------------------------------------------------------
// Here are the Linux joystick driver v1.x interface definitions that we
// use (we do not want to rely on <linux/joystick.h>):
//------------------------------------------------------------------------
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
// Joystick event types
#define JS_EVENT_BUTTON 0x01 /* button pressed/released */
#define JS_EVENT_AXIS 0x02 /* joystick moved */
#define JS_EVENT_INIT 0x80 /* initial state of device */
// Joystick event structure
struct js_event {
unsigned int time; /* (u32) event timestamp in milliseconds */
signed short value; /* (s16) value */
unsigned char type; /* (u8) event type */
unsigned char number; /* (u8) axis/button number */
};
// Joystick IOCTL commands
#define JSIOCGVERSION _IOR('j', 0x01, int) /* get driver version (u32) */
#define JSIOCGAXES _IOR('j', 0x11, char) /* get number of axes (u8) */
#define JSIOCGBUTTONS _IOR('j', 0x12, char) /* get number of buttons (u8) */
#endif // _GLFW_USE_LINUX_JOYSTICKS
//========================================================================
// Attempt to open the specified joystick device
//========================================================================
static int openJoystickDevice(int joy, const char* path)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
char numAxes, numButtons;
int fd, version;
fd = open(path, O_NONBLOCK);
if (fd == -1)
return GL_FALSE;
_glfwLibrary.X11.joystick[joy].fd = fd;
// Verify that the joystick driver version is at least 1.0
ioctl(fd, JSIOCGVERSION, &version);
if (version < 0x010000)
{
// It's an old 0.x interface (we don't support it)
close(fd);
return GL_FALSE;
}
ioctl(fd, JSIOCGAXES, &numAxes);
_glfwLibrary.X11.joystick[joy].numAxes = (int) numAxes;
ioctl(fd, JSIOCGBUTTONS, &numButtons);
_glfwLibrary.X11.joystick[joy].numButtons = (int) numButtons;
_glfwLibrary.X11.joystick[joy].axis =
(float*) malloc(sizeof(float) * numAxes);
if (_glfwLibrary.X11.joystick[joy].axis == NULL)
{
close(fd);
_glfwSetError(GLFW_OUT_OF_MEMORY, NULL);
return GL_FALSE;
}
_glfwLibrary.X11.joystick[joy].button =
(unsigned char*) malloc(sizeof(char) * numButtons);
if (_glfwLibrary.X11.joystick[joy].button == NULL)
{
free(_glfwLibrary.X11.joystick[joy].axis);
close(fd);
_glfwSetError(GLFW_OUT_OF_MEMORY, NULL);
return GL_FALSE;
}
_glfwLibrary.X11.joystick[joy].present = GL_TRUE;
#endif // _GLFW_USE_LINUX_JOYSTICKS
return GL_TRUE;
}
//========================================================================
// Polls for and processes events for all present joysticks
//========================================================================
static void pollJoystickEvents(void)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
int i;
struct js_event e;
for (i = 0; i <= GLFW_JOYSTICK_LAST; i++)
{
if (!_glfwLibrary.X11.joystick[i].present)
continue;
// Read all queued events (non-blocking)
while (read(_glfwLibrary.X11.joystick[i].fd, &e, sizeof(e)) > 0)
{
// We don't care if it's an init event or not
e.type &= ~JS_EVENT_INIT;
switch (e.type)
{
case JS_EVENT_AXIS:
_glfwLibrary.X11.joystick[i].axis[e.number] =
(float) e.value / 32767.0f;
// We need to change the sign for the Y axes, so that
// positive = up/forward, according to the GLFW spec.
if (e.number & 1)
{
_glfwLibrary.X11.joystick[i].axis[e.number] =
-_glfwLibrary.X11.joystick[i].axis[e.number];
}
break;
case JS_EVENT_BUTTON:
_glfwLibrary.X11.joystick[i].button[e.number] =
e.value ? GLFW_PRESS : GLFW_RELEASE;
break;
default:
break;
}
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
@ -82,97 +163,24 @@ struct js_event {
void _glfwInitJoysticks(void)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
int k, n, fd, joy_count;
const char* joy_base_name;
char joy_dev_name[20];
int driver_version = 0x000800;
char ret_data;
#endif // _GLFW_USE_LINUX_JOYSTICKS
int i;
// Start by saying that there are no sticks
for (i = 0; i <= GLFW_JOYSTICK_LAST; i++)
_glfwJoy[i].Present = GL_FALSE;
#ifdef _GLFW_USE_LINUX_JOYSTICKS
// Try to open joysticks (nonblocking)
joy_count = 0;
for (k = 0; k <= 1 && joy_count <= GLFW_JOYSTICK_LAST; k++)
int i, j, joy = 0;
char path[20];
const char* bases[] =
{
// Pick joystick base name
switch (k)
"/dev/input/js",
"/dev/js"
};
for (i = 0; i < sizeof(bases) / sizeof(bases[0]); i++)
{
for (j = 0; j < 50; j++)
{
case 0:
// USB joysticks
joy_base_name = "/dev/input/js";
if (joy > GLFW_JOYSTICK_LAST)
break;
case 1:
// "Legacy" joysticks
joy_base_name = "/dev/js";
break;
default:
// This should never happen
continue;
}
// Try to open a few of these sticks
for (i = 0; i <= 50 && joy_count <= GLFW_JOYSTICK_LAST; i++)
{
sprintf(joy_dev_name, "%s%d", joy_base_name, i);
fd = open(joy_dev_name, O_NONBLOCK);
if (fd != -1)
{
// Remember fd
_glfwJoy[joy_count].fd = fd;
// Check that the joystick driver version is 1.0+
ioctl(fd, JSIOCGVERSION, &driver_version);
if (driver_version < 0x010000)
{
// It's an old 0.x interface (we don't support it)
close(fd);
continue;
}
// Get number of joystick axes
ioctl(fd, JSIOCGAXES, &ret_data);
_glfwJoy[joy_count].NumAxes = (int) ret_data;
// Get number of joystick buttons
ioctl(fd, JSIOCGBUTTONS, &ret_data);
_glfwJoy[joy_count].NumButtons = (int) ret_data;
// Allocate memory for joystick state
_glfwJoy[joy_count].Axis =
(float*) malloc(sizeof(float) *
_glfwJoy[joy_count].NumAxes);
if (_glfwJoy[joy_count].Axis == NULL)
{
close(fd);
continue;
}
_glfwJoy[joy_count].Button =
(unsigned char*) malloc(sizeof(char) *
_glfwJoy[joy_count].NumButtons);
if (_glfwJoy[joy_count].Button == NULL)
{
free(_glfwJoy[joy_count].Axis);
close(fd);
continue;
}
// Clear joystick state
for (n = 0; n < _glfwJoy[joy_count].NumAxes; n++)
_glfwJoy[joy_count].Axis[n] = 0.0f;
for (n = 0; n < _glfwJoy[joy_count].NumButtons; n++)
_glfwJoy[joy_count].Button[n] = GLFW_RELEASE;
// The joystick is supported and connected
_glfwJoy[joy_count].Present = GL_TRUE;
joy_count++;
}
sprintf(path, "%s%i", bases[i], j);
if (openJoystickDevice(joy, path))
joy++;
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
@ -185,72 +193,18 @@ void _glfwInitJoysticks(void)
void _glfwTerminateJoysticks(void)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
int i;
// Close any opened joysticks
for (i = 0; i <= GLFW_JOYSTICK_LAST; i++)
{
if (_glfwJoy[i].Present)
if (_glfwLibrary.X11.joystick[i].present)
{
close(_glfwJoy[i].fd);
free(_glfwJoy[i].Axis);
free(_glfwJoy[i].Button);
close(_glfwLibrary.X11.joystick[i].fd);
free(_glfwLibrary.X11.joystick[i].axis);
free(_glfwLibrary.X11.joystick[i].button);
_glfwJoy[i].Present = GL_FALSE;
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
}
//========================================================================
// Empty joystick event queue
//========================================================================
static void pollJoystickEvents(void)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
struct js_event e;
int i;
// Get joystick events for all GLFW joysticks
for (i = 0; i <= GLFW_JOYSTICK_LAST; i++)
{
// Is the stick present?
if (_glfwJoy[i].Present)
{
// Read all queued events (non-blocking)
while (read(_glfwJoy[i].fd, &e, sizeof(struct js_event)) > 0)
{
// We don't care if it's an init event or not
e.type &= ~JS_EVENT_INIT;
// Check event type
switch (e.type)
{
case JS_EVENT_AXIS:
_glfwJoy[i].Axis[e.number] = (float) e.value / 32767.0f;
// We need to change the sign for the Y axes, so that
// positive = up/forward, according to the GLFW spec.
if (e.number & 1)
_glfwJoy[i].Axis[e.number] = -_glfwJoy[i].Axis[e.number];
break;
case JS_EVENT_BUTTON:
_glfwJoy[i].Button[e.number] =
e.value ? GLFW_PRESS : GLFW_RELEASE;
break;
default:
break;
}
}
_glfwLibrary.X11.joystick[i].present = GL_FALSE;
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
@ -267,11 +221,8 @@ static void pollJoystickEvents(void)
int _glfwPlatformGetJoystickParam(int joy, int param)
{
if (!_glfwJoy[joy].Present)
{
// TODO: Figure out if this is an error
if (!_glfwLibrary.X11.joystick[joy].present)
return 0;
}
switch (param)
{
@ -279,13 +230,13 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
return GL_TRUE;
case GLFW_AXES:
return _glfwJoy[joy].NumAxes;
return _glfwLibrary.X11.joystick[joy].numAxes;
case GLFW_BUTTONS:
return _glfwJoy[joy].NumButtons;
return _glfwLibrary.X11.joystick[joy].numButtons;
default:
break;
_glfwSetError(GLFW_INVALID_ENUM, NULL);
}
return 0;
@ -296,28 +247,22 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
// Get joystick axis positions
//========================================================================
int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
int _glfwPlatformGetJoystickPos(int joy, float* pos, int numAxes)
{
int i;
if (!_glfwJoy[joy].Present)
{
// TODO: Figure out if this is an error
if (!_glfwLibrary.X11.joystick[joy].present)
return 0;
}
// Update joystick state
pollJoystickEvents();
// Does the joystick support less axes than requested?
if (_glfwJoy[joy].NumAxes < numaxes)
numaxes = _glfwJoy[joy].NumAxes;
if (_glfwLibrary.X11.joystick[joy].numAxes < numAxes)
numAxes = _glfwLibrary.X11.joystick[joy].numAxes;
// Copy axis positions from internal state
for (i = 0; i < numaxes; i++)
pos[i] = _glfwJoy[joy].Axis[i];
for (i = 0; i < numAxes; i++)
pos[i] = _glfwLibrary.X11.joystick[joy].axis[i];
return numaxes;
return numAxes;
}
@ -326,27 +271,21 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
//========================================================================
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
int numbuttons)
int numButtons)
{
int i;
if (!_glfwJoy[joy].Present)
{
// TODO: Figure out if this is an error
if (!_glfwLibrary.X11.joystick[joy].present)
return 0;
}
// Update joystick state
pollJoystickEvents();
// Does the joystick support less buttons than requested?
if (_glfwJoy[joy].NumButtons < numbuttons)
numbuttons = _glfwJoy[joy].NumButtons;
if (_glfwLibrary.X11.joystick[joy].numButtons < numButtons)
numButtons = _glfwLibrary.X11.joystick[joy].numButtons;
// Copy button states from internal state
for (i = 0; i < numbuttons; i++)
buttons[i] = _glfwJoy[joy].Button[i];
for (i = 0; i < numButtons; i++)
buttons[i] = _glfwLibrary.X11.joystick[joy].button[i];
return numbuttons;
return numButtons;
}

View File

@ -42,20 +42,21 @@
#include <GL/glx.h>
// This path may need to be changed if you build GLFW using your own setup
// We ship and use our own copy of glxext.h since GLFW uses fairly new
// GLFW comes with its own copy of glxext.h since it uses some fairly new
// extensions and not all operating systems come with an up-to-date version
#include "../support/GL/glxext.h"
// With XFree86, we can use the XF86VidMode extension
// The XF86VidMode extension provides mode setting and gamma control
#if defined(_GLFW_HAS_XF86VIDMODE)
#include <X11/extensions/xf86vmode.h>
#endif
// The XRandR extension provides mode setting and gamma control
#if defined(_GLFW_HAS_XRANDR)
#include <X11/extensions/Xrandr.h>
#endif
// Do we have support for dlopen/dlsym?
// dlopen is used as a fallback function retrieval mechanism
#if defined(_GLFW_HAS_DLOPEN)
#include <dlfcn.h>
#endif
@ -65,7 +66,7 @@
#include <X11/XKBlib.h>
#endif
// We support four different ways for getting addresses for GL/GLX
// GLFW supports four different ways for getting addresses for GL/GLX
// extension functions: glXGetProcAddress, glXGetProcAddressARB,
// glXGetProcAddressEXT, and dlsym
#if defined(_GLFW_HAS_GLXGETPROCADDRESSARB)
@ -232,6 +233,15 @@ typedef struct _GLFWlibraryX11
int status;
} selection;
struct {
int present;
int fd;
int numAxes;
int numButtons;
float* axis;
unsigned char* button;
} joystick[GLFW_JOYSTICK_LAST + 1];
} _GLFWlibraryX11;
@ -268,19 +278,6 @@ typedef struct _GLFWlibraryGLX
} _GLFWlibraryGLX;
//------------------------------------------------------------------------
// Joystick information & state
//------------------------------------------------------------------------
GLFWGLOBAL struct {
int Present;
int fd;
int NumAxes;
int NumButtons;
float* Axis;
unsigned char* Button;
} _glfwJoy[GLFW_JOYSTICK_LAST + 1];
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================

View File

@ -45,21 +45,18 @@
#define Button6 6
#define Button7 7
//========================================================================
// Translates an X Window key to internal coding
//========================================================================
static int translateKey(int keycode)
{
// Use the pre-filled LUT (see updateKeyCodeLUT() ).
// Use the pre-filled LUT (see updateKeyCodeLUT() in x11_init.c)
if ((keycode >= 0) && (keycode < 256))
{
return _glfwLibrary.X11.keyCodeLUT[keycode];
}
else
{
return -1;
}
}
@ -92,6 +89,7 @@ static GLboolean createWindow(_GLFWwindow* window,
// Every window needs a colormap
// Create one based on the visual used by the current context
// TODO: Decouple this from context creation
window->X11.colormap = XCreateColormap(_glfwLibrary.X11.display,
_glfwLibrary.X11.root,
@ -111,30 +109,29 @@ static GLboolean createWindow(_GLFWwindow* window,
if (wndconfig->mode == GLFW_WINDOWED)
{
// The /only/ reason we are setting the background pixel here is
// that otherwise our window wont get any decorations on systems
// using Compiz on Intel hardware
// The /only/ reason for setting the background pixel here is that
// otherwise our window won't get any decorations on systems using
// certain versions of Compiz on Intel hardware
wa.background_pixel = BlackPixel(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen);
wamask |= CWBackPixel;
}
window->X11.handle = XCreateWindow(
_glfwLibrary.X11.display,
_glfwLibrary.X11.root,
0, 0, // Upper left corner of this window on root
window->width, window->height,
0, // Border width
visual->depth, // Color depth
InputOutput,
visual->visual,
wamask,
&wa
);
window->X11.handle = XCreateWindow(_glfwLibrary.X11.display,
_glfwLibrary.X11.root,
0, 0, // Position
window->width, window->height,
0, // Border width
visual->depth, // Color depth
InputOutput,
visual->visual,
wamask,
&wa);
if (!window->X11.handle)
{
// TODO: Handle all the various error codes here
// TODO: Handle all the various error codes here and translate them
// to GLFW errors
_glfwSetError(GLFW_PLATFORM_ERROR,
"X11/GLX: Failed to create window");
@ -149,8 +146,8 @@ static GLboolean createWindow(_GLFWwindow* window,
// manager ignore the window completely (ICCCM, section 4)
// The good thing is that this makes undecorated fullscreen windows
// easy to do; the bad thing is that we have to do everything manually
// and some things (like iconify/restore) won't work at all, as they're
// usually performed by the window manager
// and some things (like iconify/restore) won't work at all, as those
// are tasks usually performed by the window manager
XSetWindowAttributes attributes;
attributes.override_redirect = True;
@ -167,7 +164,7 @@ static GLboolean createWindow(_GLFWwindow* window,
"WM_DELETE_WINDOW",
False);
// Declare the WM protocols we support
// Declare the WM protocols supported by GLFW
{
int count = 0;
Atom protocols[2];
@ -178,8 +175,8 @@ static GLboolean createWindow(_GLFWwindow* window,
protocols[count++] = _glfwLibrary.X11.wmDeleteWindow;
// The _NET_WM_PING EWMH protocol
// Tells the WM to ping our window and flag us as unresponsive if we
// don't reply within a few seconds
// Tells the WM to ping the GLFW window and flag the application as
// unresponsive if the WM doesn't get a reply within a few seconds
if (_glfwLibrary.X11.wmPing != None)
protocols[count++] = _glfwLibrary.X11.wmPing;
@ -285,7 +282,7 @@ static void captureCursor(_GLFWwindow* window)
static void showCursor(_GLFWwindow* window)
{
// Un-grab cursor (only in windowed mode: in fullscreen mode we still
// Un-grab cursor (in windowed mode only; in fullscreen mode we still
// want the cursor grabbed in order to confine the cursor to the window
// area)
if (window->X11.cursorGrabbed)
@ -379,7 +376,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
}
else if (window->X11.overrideRedirect)
{
// In override-redirect mode, we have divorced ourselves from the
// In override-redirect mode we have divorced ourselves from the
// window manager, so we need to do everything manually
XRaiseWindow(_glfwLibrary.X11.display, window->X11.handle);
@ -407,7 +404,6 @@ static void leaveFullscreenMode(_GLFWwindow* window)
{
_glfwRestoreVideoMode();
// Did we change the screen saver setting?
if (_glfwLibrary.X11.saver.changed)
{
// Restore old screen saver settings
@ -647,7 +643,8 @@ static void processEvent(XEvent *event)
if (event->xmotion.x != window->X11.cursorPosX ||
event->xmotion.y != window->X11.cursorPosY)
{
// The cursor was moved and we didn't do it
// The cursor was moved by something other than GLFW
int x, y;
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
@ -715,8 +712,8 @@ static void processEvent(XEvent *event)
else if (_glfwLibrary.X11.wmPing != None &&
(Atom) event->xclient.data.l[0] == _glfwLibrary.X11.wmPing)
{
// The window manager is pinging us to make sure we are still
// responding to events
// The window manager is pinging the application to ensure it's
// still responding to events
event->xclient.window = _glfwLibrary.X11.root;
XSendEvent(_glfwLibrary.X11.display,
@ -863,7 +860,6 @@ static void processEvent(XEvent *event)
{
case RRScreenChangeNotify:
{
// Show XRandR that we really care
XRRUpdateConfiguration(event);
break;
}
@ -1070,8 +1066,8 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
if (window->X11.overrideRedirect)
{
// We can't iconify/restore override-redirect windows, as that's
// performed by the window manager
// Override-redirect windows cannot be iconified or restored, as those
// tasks are performed by the window manager
return;
}
@ -1089,8 +1085,8 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
if (window->X11.overrideRedirect)
{
// We can't iconify/restore override-redirect windows, as that's
// performed by the window manager
// Override-redirect windows cannot be iconified or restored, as those
// tasks are performed by the window manager
return;
}
@ -1204,7 +1200,7 @@ void _glfwPlatformWaitEvents(void)
void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y)
{
// Store the new position so we can recognise it later
// Store the new position so it can be recognized later
window->X11.cursorPosX = x;
window->X11.cursorPosY = y;

View File

@ -242,8 +242,11 @@ static void window_refresh_callback(GLFWwindow window)
{
printf("%08x at %0.3f: Window refresh\n", counter++, glfwGetTime());
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
if (glfwGetCurrentContext())
{
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
}
}
static void window_focus_callback(GLFWwindow window, int activated)