packages feed

GLFW 0.5.1.0 → 0.5.2.0

raw patch · 16 files changed

+969/−202 lines, 16 filessetup-changed

Files

Changelog.txt view
@@ -1,3 +1,12 @@+Thu Oct  3 23:59:17 PDT 2013  paul@thev.net+  * Bump version to 0.5.2.0++Thu Oct  3 23:26:34 PDT 2013  paul@thev.net+  * Upgrade to glfw C version 2.7.9++Thu Oct  3 23:25:39 PDT 2013  paul@thev.net+  * Compatibility fix to work with Cabal 1.18+ Sat Nov  3 21:41:09 PDT 2012  paul@thev.net   * Bump version to 0.5.1.0 for release 
GLFW.cabal view
@@ -1,15 +1,19 @@ name:          GLFW-version:       0.5.1.0+version:       0.5.2.0 homepage:      http://haskell.org/haskellwiki/GLFW maintainer:    Paul H. Liu <paul@thev.net>, Marc Sunet <jeannekamikaze@gmail.com>-cabal-version: >= 1.10+cabal-version: >= 1.12 build-type:    Custom category:      Graphics synopsis:      A Haskell binding for GLFW description:   A Haskell binding for GLFW, a window system independent toolkit                for writing OpenGL programs. For more information about the C                library on which this binding is based, please see-               <http://www.glfw.org>.+               <http://www.glfw.org>. Note that this binding comes with an +               older GLFW C version 2.7.9 due to incompatible API changes +               GLFW since 3.0 (for example, the removal of texture functions).+               If you want to use newer GLFW C versions, install Haskell package+               GLFW-b instead. license:       BSD3 license-file:  LICENSE 
README.txt view
@@ -19,7 +19,7 @@ ============
 
 The package comes together with a (partial) source distribution 
-of GLFW v2.7.2, which is compiled and installed together with
+of GLFW v2.7.9, which is compiled and installed together with
 the Haskell package.
 
 If you already have the Haskell package cabal-install, you can
@@ -62,7 +62,7 @@ ====
 
 For Windows users, you may have to include GHC's gcc-lib directory 
-in your PATH environment, e.g., c:\ghc\ghc-6.8.3\gcc-lib, before 
+in your PATH environment, e.g., c:\ghc\ghc-7.6.3\gcc-lib, before 
 configuring the GLFW module, otherwise it'll complain about missing
 program for ld.
 
@@ -72,15 +72,15 @@ command. 
 
 For Mac users, unfortunately interactively running GLFW programs
-from GHCi would result in a crash. The only sensible way is to 
-compile and run the program. On the other hand, it no longer 
-requires the enableGUI trick.
+from GHCi would result in a crash if you use GHC 7.6.3 or older. 
+The only sensible way is to compile and run the program, or use
+GHC 7.8 or newer. 
 
 =============
 Package Usage
 =============
 
-The package is tested with GHC 6.10.2 and GHC 7.0.2 on all
+The package is tested with GHC 7.4.2 and GHC 7.6.3 on all
 three platforms (Linux, Win32/MinGW, and Mac OS X). Though it may
 work with older versions of GHC or even Hugs, they are not tested.
 
@@ -127,4 +127,4 @@   http://projects.haskell.org/cgi-bin/mailman/listinfo/glfw
 
 --
-Last Updated: Fri Jan 20 PST 2012
+Last Updated: Thu Oct 3 PST 2013
Setup.hs view
@@ -7,6 +7,7 @@ import Distribution.Simple.Utils (rawSystemStdInOut, withTempFile) import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program+import Distribution.Simple.Program.Types import Distribution.Verbosity import Distribution.PackageDescription import Distribution.System@@ -14,9 +15,9 @@ import System.FilePath import System.Directory import System.IO (hClose, hPutStr)-import System.Cmd (rawSystem)+import System.IO.Error (catchIOError) import Data.Maybe (fromJust)-import Foreign (bitSize)+import Foreign (sizeOf) import Control.Monad (when) --import Control.Monad.State  --import Control.Monad.Trans.Class (lift)@@ -51,14 +52,12 @@       Just cpp_name -> do         let cpp_name  = fromJust (lookup "x-cc-name" custom_bi)             c_srcs    = cSources lib_bi-            mbits     = bitSize (undefined :: Int)+            mbits     = 8 * sizeOf (undefined :: Int)             cc_opts   = ("-m" ++ show mbits) : "-S" : ccOptions lib_bi             inc_dirs  = includeDirs lib_bi             lib_dirs  = extraLibDirs lib_bi             bld_dir   = buildDir local_bld_info-            prog      = ConfiguredProgram { programId = cpp_name, programVersion = Nothing,-                                            programDefaultArgs = [], programOverrideArgs = [],-                                            programLocation = FoundOnSystem { locationPath = cpp_name } }+            prog      = simpleConfiguredProgram cpp_name (FoundOnSystem { locationPath = cpp_name })         -- Compile C/C++ sources         putStrLn $ "invoking my compile phase " ++ cpp_name         objs <- mapM (compileCxx prog cc_opts inc_dirs bld_dir) c_srcs@@ -164,8 +163,9 @@         hClose outHandle         hPutStr inHandle contents         hClose inHandle-        (out, err, exitCode) <- rawSystemStdInOut verbosity "cc" (["-c", path, "-o", objPath] ++ flags) Nothing False-        return (exitCode == ExitSuccess)     +        let cc = simpleProgramInvocation "cc" (["-c", path, "-o", objPath] ++ flags)+        -- (out, err, exitCode) <- rawSystemStdInOut verbosity "cc"  Nothing Nothing Nothing False+        catchIOError (getProgramInvocationOutput verbosity cc >> return True) (\_ -> return False)  progXrandr = unlines             ["#include <X11/Xlib.h>"@@ -250,6 +250,5 @@         a <- m         return (a, s) instance (Monad m) => MonadState s (StateT s m) where-    get   = StateT $ \s -> return (s, s)                                                                               +    get   = StateT $ \s -> return (s, s)      put s = StateT $ \_ -> return ((), s)-
glfw/include/GL/glfw.h view
@@ -187,7 +187,7 @@  #define GLFW_VERSION_MAJOR    2 #define GLFW_VERSION_MINOR    7-#define GLFW_VERSION_REVISION 5+#define GLFW_VERSION_REVISION 9   /*************************************************************************
glfw/lib/cocoa/cocoa_init.m view
@@ -146,6 +146,8 @@      _glfwInitTimer(); +    _glfwInitJoysticks();+     _glfwLibrary.eventSource = CGEventSourceCreate( kCGEventSourceStateHIDSystemState );     if( !_glfwLibrary.eventSource )     {@@ -167,7 +169,10 @@  int _glfwPlatformTerminate( void ) {-    // TODO: Fail unless this is the main thread+    if( pthread_self() != _glfwThrd.First.PosixID )+    {+        return GL_FALSE;+    }      glfwCloseWindow(); @@ -179,6 +184,8 @@         CFRelease( _glfwLibrary.eventSource );         _glfwLibrary.eventSource = NULL;     }++    _glfwTerminateJoysticks();      [_glfwLibrary.autoreleasePool release];     _glfwLibrary.autoreleasePool = nil;
glfw/lib/cocoa/cocoa_joystick.m view
@@ -29,7 +29,481 @@  #include "internal.h" +#include <unistd.h>+#include <ctype.h>++#include <mach/mach.h>+#include <mach/mach_error.h>++#include <CoreFoundation/CoreFoundation.h>+#include <IOKit/IOKitLib.h>+#include <IOKit/IOCFPlugIn.h>+#include <IOKit/hid/IOHIDLib.h>+#include <IOKit/hid/IOHIDKeys.h>+#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>+++//------------------------------------------------------------------------+// Joystick state+//------------------------------------------------------------------------++typedef struct+{+    int present;+    char product[256];++    IOHIDDeviceInterface** interface;++    int numAxes;+    int numButtons;+    int numHats;++    CFMutableArrayRef axes;+    CFMutableArrayRef buttons;+    CFMutableArrayRef hats;++} _glfwJoystick;++static _glfwJoystick _glfwJoysticks[GLFW_JOYSTICK_LAST + 1];+++typedef struct+{+    IOHIDElementCookie cookie;++    long value;++    long min;+    long max;++    long minReport;+    long maxReport;++} _glfwJoystickElement;+++void GetElementsCFArrayHandler( const void* value, void* parameter );+++//========================================================================+// Adds an element to the specified joystick+//========================================================================++static void addJoystickElement( _glfwJoystick* joystick, CFTypeRef refElement )+{+    long elementType, usagePage, usage;+    CFTypeRef refElementType, refUsagePage, refUsage;++    refElementType = CFDictionaryGetValue( refElement, CFSTR( kIOHIDElementTypeKey ) );+    refUsagePage = CFDictionaryGetValue( refElement, CFSTR( kIOHIDElementUsagePageKey ) );+    refUsage = CFDictionaryGetValue( refElement, CFSTR( kIOHIDElementUsageKey ) );++    CFMutableArrayRef elementsArray = NULL;++    CFNumberGetValue( refElementType, kCFNumberLongType, &elementType );+    CFNumberGetValue( refUsagePage, kCFNumberLongType, &usagePage );+    CFNumberGetValue( refUsage, kCFNumberLongType, &usage );++    if( elementType == kIOHIDElementTypeInput_Axis ||+        elementType == kIOHIDElementTypeInput_Button ||+        elementType == kIOHIDElementTypeInput_Misc )+    {+        switch( usagePage ) /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */+        {+            case kHIDPage_GenericDesktop:+            {+                switch( usage )+                {+                    case kHIDUsage_GD_X:+                    case kHIDUsage_GD_Y:+                    case kHIDUsage_GD_Z:+                    case kHIDUsage_GD_Rx:+                    case kHIDUsage_GD_Ry:+                    case kHIDUsage_GD_Rz:+                    case kHIDUsage_GD_Slider:+                    case kHIDUsage_GD_Dial:+                    case kHIDUsage_GD_Wheel:+                        joystick->numAxes++;+                        elementsArray = joystick->axes;+                        break;+                    case kHIDUsage_GD_Hatswitch:+                        joystick->numHats++;+                        elementsArray = joystick->hats;+                        break;+                }++                break;+            }++            case kHIDPage_Button:+                joystick->numButtons++;+                elementsArray = joystick->buttons;+                break;+            default:+                break;+        }++        if( elementsArray )+        {+            long number;+            CFTypeRef refType;++            _glfwJoystickElement* element = (_glfwJoystickElement*) malloc( sizeof( _glfwJoystickElement ) );++            CFArrayAppendValue( elementsArray, element );++            refType = CFDictionaryGetValue( refElement, CFSTR( kIOHIDElementCookieKey ) );+            if( refType && CFNumberGetValue( refType, kCFNumberLongType, &number ) )+            {+                element->cookie = (IOHIDElementCookie) number;+            }++            refType = CFDictionaryGetValue( refElement, CFSTR( kIOHIDElementMinKey ) );+            if( refType && CFNumberGetValue( refType, kCFNumberLongType, &number ) )+            {+                element->minReport = element->min = number;+            }++            refType = CFDictionaryGetValue( refElement, CFSTR( kIOHIDElementMaxKey ) );+            if( refType && CFNumberGetValue( refType, kCFNumberLongType, &number ) )+            {+                element->maxReport = element->max = number;+            }+        }+    }+    else+    {+        CFTypeRef refElementTop = CFDictionaryGetValue( refElement, CFSTR( kIOHIDElementKey ) );+        if( refElementTop )+        {+            CFTypeID type = CFGetTypeID( refElementTop );+            if( type == CFArrayGetTypeID() ) /* if element is an array */+            {+                CFRange range = { 0, CFArrayGetCount( refElementTop ) };+                CFArrayApplyFunction( refElementTop, range, GetElementsCFArrayHandler, joystick );+            }+        }+    }+}+++//========================================================================+// Adds an element to the specified joystick+//========================================================================++void GetElementsCFArrayHandler( const void* value, void* parameter )+{+    if( CFGetTypeID( value ) == CFDictionaryGetTypeID() )+    {+        addJoystickElement( (_glfwJoystick*) parameter, (CFTypeRef) value );+    }+}+++//========================================================================+// Returns the value of the specified element of the specified joystick+//========================================================================++static long getElementValue( _glfwJoystick* joystick, _glfwJoystickElement* element )+{+    IOReturn result = kIOReturnSuccess;+    IOHIDEventStruct hidEvent;+    hidEvent.value = 0;++    if( joystick && element && joystick->interface )+    {+        result = (*(joystick->interface))->getElementValue( joystick->interface,+                                                            element->cookie,+                                                            &hidEvent );+        if( kIOReturnSuccess == result )+        {+            /* record min and max for auto calibration */+            if( hidEvent.value < element->minReport )+            {+                element->minReport = hidEvent.value;+            }+            if( hidEvent.value > element->maxReport )+            {+                element->maxReport = hidEvent.value;+            }+        }+    }++    /* auto user scale */+    return (long) hidEvent.value;+}+++//========================================================================+// Removes the specified joystick+//========================================================================++static void removeJoystick( _glfwJoystick* joystick )+{+    int i;++    if( joystick->present )+    {+        joystick->present = GL_FALSE;++        for( i = 0;  i < joystick->numAxes;  i++ )+        {+            _glfwJoystickElement* axes =+                (_glfwJoystickElement*) CFArrayGetValueAtIndex( joystick->axes, i );+            free( axes );+        }+        CFArrayRemoveAllValues( joystick->axes );+        joystick->numAxes = 0;++        for( i = 0;  i < joystick->numButtons;  i++ )+        {+            _glfwJoystickElement* button =+                (_glfwJoystickElement*) CFArrayGetValueAtIndex( joystick->buttons, i );+            free( button );+        }+        CFArrayRemoveAllValues( joystick->buttons );+        joystick->numButtons = 0;++        for( i = 0;  i < joystick->numHats;  i++ )+        {+            _glfwJoystickElement* hat =+                (_glfwJoystickElement*) CFArrayGetValueAtIndex( joystick->hats, i );+            free( hat );+        }+        CFArrayRemoveAllValues( joystick->hats );+        joystick->hats = 0;++        (*(joystick->interface))->close( joystick->interface );+        (*(joystick->interface))->Release( joystick->interface );++        joystick->interface = NULL;+    }+}+++//========================================================================+// Callback for user-initiated joystick removal+//========================================================================++static void removalCallback( void* target, IOReturn result, void* refcon, void* sender )+{+    removeJoystick( (_glfwJoystick*) refcon );+}+++//========================================================================+// Polls for joystick events and updates GFLW state+//========================================================================++static void pollJoystickEvents( void )+{+    int i;+    CFIndex j;++    for( i = 0;  i < GLFW_JOYSTICK_LAST + 1;  i++ )+    {+        _glfwJoystick* joystick = &_glfwJoysticks[i];++        if( joystick->present )+        {+            for( j = 0;  j < joystick->numButtons;  j++ )+            {+                _glfwJoystickElement* button =+                    (_glfwJoystickElement*) CFArrayGetValueAtIndex( joystick->buttons, j );+                button->value = getElementValue( joystick, button );+            }++            for( j = 0;  j < joystick->numAxes;  j++ )+            {+                _glfwJoystickElement* axes =+                    (_glfwJoystickElement*) CFArrayGetValueAtIndex( joystick->axes, j );+                axes->value = getElementValue( joystick, axes );+            }++            for( j = 0;  j < joystick->numHats;  j++ )+            {+                _glfwJoystickElement* hat =+                    (_glfwJoystickElement*) CFArrayGetValueAtIndex( joystick->hats, j );+                hat->value = getElementValue( joystick, hat );+            }+        }+    }+}++ //************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// Initialize joystick interface+//========================================================================++void _glfwInitJoysticks( void )+{+    int deviceCounter = 0;+    IOReturn result = kIOReturnSuccess;+    mach_port_t masterPort = 0;+    io_iterator_t objectIterator = 0;+    CFMutableDictionaryRef hidMatchDictionary = NULL;+    io_object_t ioHIDDeviceObject = 0;++    result = IOMasterPort( bootstrap_port, &masterPort );+    hidMatchDictionary = IOServiceMatching( kIOHIDDeviceKey );+    if( kIOReturnSuccess != result || !hidMatchDictionary )+    {+        if( hidMatchDictionary )+        {+            CFRelease( hidMatchDictionary );+        }++        return;+    }++    result = IOServiceGetMatchingServices( masterPort,+                                           hidMatchDictionary,+                                           &objectIterator );+    if( result != kIOReturnSuccess )+    {+        return;+    }++    if( !objectIterator ) /* there are no joysticks */+    {+        return;+    }++    while( ( ioHIDDeviceObject = IOIteratorNext( objectIterator ) ) )+    {+        CFMutableDictionaryRef hidProperties = 0;+        kern_return_t result;+        CFTypeRef refCF = 0;++        IOCFPlugInInterface** ppPlugInInterface = NULL;+        HRESULT plugInResult = S_OK;+        SInt32 score = 0;++        long usagePage, usage;++        result = IORegistryEntryCreateCFProperties( ioHIDDeviceObject,+                                                    &hidProperties,+                                                    kCFAllocatorDefault,+                                                    kNilOptions );++        if( result != kIOReturnSuccess )+        {+            continue;+        }++        /* 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 */+                continue;+            }+        }++        refCF = CFDictionaryGetValue( hidProperties, CFSTR( kIOHIDPrimaryUsageKey ) );+        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 */+                continue;+            }+        }++        _glfwJoystick* joystick = &_glfwJoysticks[deviceCounter];++        joystick->present = GL_TRUE;++        result = IOCreatePlugInInterfaceForService( ioHIDDeviceObject,+                                                    kIOHIDDeviceUserClientTypeID,+                                                    kIOCFPlugInInterfaceID,+                                                    &ppPlugInInterface,+                                                    &score );++        if( kIOReturnSuccess != result )+        {+            return;+        }++        plugInResult = (*ppPlugInInterface)->QueryInterface( ppPlugInInterface,+                                                             CFUUIDGetUUIDBytes( kIOHIDDeviceInterfaceID ),+                                                             (void *) &(joystick->interface) );++        if( plugInResult != S_OK )+        {+            return;+        }++        (*ppPlugInInterface)->Release( ppPlugInInterface );++        (*(joystick->interface))->open( joystick->interface, 0 );+        (*(joystick->interface))->setRemovalCallback( joystick->interface,+                                                      removalCallback,+                                                      joystick,+                                                      joystick );++        /* Get product string */+        refCF = CFDictionaryGetValue( hidProperties, CFSTR( kIOHIDProductKey ) );+        if( refCF )+        {+            CFStringGetCString( refCF,+                                (char*) &(joystick->product),+                                256,+                                CFStringGetSystemEncoding() );+        }++        joystick->numAxes = 0;+        joystick->numButtons = 0;+        joystick->numHats = 0;+        joystick->axes = CFArrayCreateMutable( NULL, 0, NULL );+        joystick->buttons = CFArrayCreateMutable( NULL, 0, NULL );+        joystick->hats = CFArrayCreateMutable( NULL, 0, NULL );++        CFTypeRef refTopElement = CFDictionaryGetValue( hidProperties,+                                                        CFSTR( kIOHIDElementKey ) );+        CFTypeID type = CFGetTypeID( refTopElement );+        if( type == CFArrayGetTypeID() )+        {+            CFRange range = { 0, CFArrayGetCount( refTopElement ) };+            CFArrayApplyFunction( refTopElement,+                                  range,+                                  GetElementsCFArrayHandler,+                                  (void*) joystick);+        }++        deviceCounter++;+    }+}+++//========================================================================+// Close all opened joystick handles+//========================================================================++void _glfwTerminateJoysticks( void )+{+    int i;++    for( i = 0;  i < GLFW_JOYSTICK_LAST + 1;  i++ )+    {+        _glfwJoystick* joystick = &_glfwJoysticks[i];+        removeJoystick( joystick );+    }+}+++//************************************************************************ //****               Platform implementation functions                **** //************************************************************************ @@ -39,8 +513,29 @@  int _glfwPlatformGetJoystickParam( int joy, int param ) {-    // TODO: Implement this.-    return 0;+    if( !_glfwJoysticks[joy].present )+    {+        // TODO: Figure out if this is an error+        return GL_FALSE;+    }++    switch( param )+    {+        case GLFW_PRESENT:+            return GL_TRUE;++        case GLFW_AXES:+            return (int) CFArrayGetCount( _glfwJoysticks[joy].axes );++        case GLFW_BUTTONS:+            return (int) CFArrayGetCount( _glfwJoysticks[joy].buttons ) ++                   ((int) CFArrayGetCount( _glfwJoysticks[joy].hats )) * 4;++        default:+            break;+    }++    return GL_FALSE; }  @@ -50,8 +545,51 @@  int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes ) {-    // TODO: Implement this.-    return 0;+    int i;++    if( joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST )+    {+        return 0;+    }++    _glfwJoystick joystick = _glfwJoysticks[joy];++    if( !joystick.present )+    {+        // TODO: Figure out if this is an error+        return 0;+    }++    numaxes = numaxes < joystick.numAxes ? numaxes : joystick.numAxes;++    // Update joystick state+    pollJoystickEvents();++    for( i = 0;  i < numaxes;  i++ )+    {+        _glfwJoystickElement* axes =+            (_glfwJoystickElement*) CFArrayGetValueAtIndex( joystick.axes, i );++        long readScale = axes->maxReport - axes->minReport;++        if( readScale == 0 )+        {+            pos[i] = axes->value;+        }+        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];+        }+    }++    return numaxes; }  @@ -61,7 +599,50 @@  int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons ) {-    // TODO: Implement this.-    return 0;+    int i, j, button;++    if( joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST )+    {+        return 0;+    }++    _glfwJoystick joystick = _glfwJoysticks[joy];++    if( !joystick.present )+    {+        // TODO: Figure out if this is an error+        return 0;+    }++    // Update joystick state+    pollJoystickEvents();++    for( button = 0;  button < numbuttons && button < joystick.numButtons;  button++ )+    {+        _glfwJoystickElement* element = (_glfwJoystickElement*) CFArrayGetValueAtIndex( joystick.buttons, button );+        buttons[button] = element->value ? GLFW_PRESS : GLFW_RELEASE;+    }++    // 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++    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++ )+        {+            buttons[button++] = directions[value] & (1 << j) ? GLFW_PRESS : GLFW_RELEASE;+        }+    }++    return button; } 
glfw/lib/cocoa/cocoa_window.m view
@@ -253,6 +253,18 @@     } } +- (void)windowDidMove:(NSNotification *)notification+{+    NSPoint point = [_glfwWin.window mouseLocationOutsideOfEventStream];+    _glfwInput.MousePosX = lround(floor(point.x));+    _glfwInput.MousePosY = _glfwWin.height - lround(ceil(point.y));++    if( _glfwWin.mousePosCallback )+    {+        _glfwWin.mousePosCallback( _glfwInput.MousePosX, _glfwInput.MousePosY );+    }+}+ - (void)windowDidMiniaturize:(NSNotification *)notification {     _glfwWin.iconified = GL_TRUE;@@ -494,7 +506,7 @@          // Cocoa coordinate system has origin at lower left         _glfwInput.MousePosX = p.x;-        _glfwInput.MousePosY = [[_glfwWin.window contentView] bounds].size.height - p.y;+        _glfwInput.MousePosY = _glfwWin.height - p.y;     }      if( _glfwWin.mousePosCallback )@@ -733,6 +745,11 @@     [_glfwWin.window setAcceptsMouseMovedEvents:YES];     [_glfwWin.window center]; +    if( [_glfwWin.window respondsToSelector:@selector(setRestorable:)] )+    {+        [_glfwWin.window setRestorable:NO];+    }+     if( wndconfig->mode == GLFW_FULLSCREEN )     {         _glfwLibrary.originalMode = (NSDictionary*)@@ -752,7 +769,10 @@      if( wndconfig->mode == GLFW_FULLSCREEN )     {+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070         ADD_ATTR( NSOpenGLPFAFullScreen );+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/+         ADD_ATTR( NSOpenGLPFANoRecovery );         ADD_ATTR2( NSOpenGLPFAScreenMask,                    CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() ) );@@ -833,9 +853,9 @@      [_glfwWin.context makeCurrentContext]; -    NSPoint point = [[NSCursor currentCursor] hotSpot];+    NSPoint point = [_glfwWin.window mouseLocationOutsideOfEventStream];     _glfwInput.MousePosX = point.x;-    _glfwInput.MousePosY = point.y;+    _glfwInput.MousePosY = _glfwWin.height - point.y;      return GL_TRUE; }@@ -1022,8 +1042,6 @@                        forAttribute:NSOpenGLPFASamples                    forVirtualScreen:0];     _glfwWin.samples = value;--    _glfwWin.glDebug = GL_FALSE; }  @@ -1101,23 +1119,21 @@  void _glfwPlatformSetMouseCursorPos( int x, int y ) {-    // The library seems to assume that after calling this the mouse won't move,-    // but obviously it will, and escape the app's window, and activate other apps,-    // and other badness in pain.  I think the API's just silly, but maybe I'm-    // misunderstanding it...--    // Also, (x, y) are window coords...--    // Also, it doesn't seem possible to write this robustly without-    // calculating the maximum y coordinate of all screens, since Cocoa's-    // "global coordinates" are upside down from CG's...--    NSPoint localPoint = NSMakePoint( x, y );-    NSPoint globalPoint = [_glfwWin.window convertBaseToScreen:localPoint];-    CGPoint mainScreenOrigin = CGDisplayBounds( CGMainDisplayID() ).origin;-    double mainScreenHeight = CGDisplayBounds( CGMainDisplayID() ).size.height;-    CGPoint targetPoint = CGPointMake( globalPoint.x - mainScreenOrigin.x,-                                       mainScreenHeight - globalPoint.y - mainScreenOrigin.y );-    CGDisplayMoveCursorToPoint( CGMainDisplayID(), targetPoint );+    if( _glfwWin.fullscreen )+    {+        CGPoint globalPoint = CGPointMake( x, y );+        CGDisplayMoveCursorToPoint( CGMainDisplayID(), globalPoint );+    }+    else+    {+        NSPoint localPoint = NSMakePoint( x, _glfwWin.height - y - 1 );+        NSPoint globalPoint = [_glfwWin.window convertBaseToScreen:localPoint];+        CGPoint mainScreenOrigin = CGDisplayBounds( CGMainDisplayID() ).origin;+        double mainScreenHeight = CGDisplayBounds( CGMainDisplayID() ).size.height;+        CGPoint targetPoint = CGPointMake( globalPoint.x - mainScreenOrigin.x,+                                          mainScreenHeight - globalPoint.y -+                                              mainScreenOrigin.y );+        CGDisplayMoveCursorToPoint( CGMainDisplayID(), targetPoint );+    } } 
glfw/lib/cocoa/platform.h view
@@ -261,5 +261,8 @@ // Time void _glfwInitTimer( void ); +// Joystick+void _glfwInitJoysticks( void );+void _glfwTerminateJoysticks( void );  #endif // _platform_h_
glfw/lib/enable.c view
@@ -48,23 +48,26 @@         return;     } -    // Show mouse cursor-    _glfwPlatformShowMouseCursor();--    centerPosX = _glfwWin.width / 2;-    centerPosY = _glfwWin.height / 2;--    if( centerPosX != _glfwInput.MousePosX || centerPosY != _glfwInput.MousePosY )+    if( _glfwWin.active )     {-        _glfwPlatformSetMouseCursorPos( centerPosX, centerPosY );+        // Show mouse cursor+        _glfwPlatformShowMouseCursor(); -        _glfwInput.MousePosX = centerPosX;-        _glfwInput.MousePosY = centerPosY;+        centerPosX = _glfwWin.width / 2;+        centerPosY = _glfwWin.height / 2; -        if( _glfwWin.mousePosCallback )+        if( centerPosX != _glfwInput.MousePosX || centerPosY != _glfwInput.MousePosY )         {-            _glfwWin.mousePosCallback( _glfwInput.MousePosX,-                                       _glfwInput.MousePosY );+            _glfwPlatformSetMouseCursorPos( centerPosX, centerPosY );++            _glfwInput.MousePosX = centerPosX;+            _glfwInput.MousePosY = centerPosY;++            if( _glfwWin.mousePosCallback )+            {+                _glfwWin.mousePosCallback( _glfwInput.MousePosX,+                                        _glfwInput.MousePosY );+            }         }     } @@ -84,11 +87,10 @@     }      // Hide mouse cursor-    _glfwPlatformHideMouseCursor();--    // Move cursor to the middle of the window-    _glfwPlatformSetMouseCursorPos( _glfwWin.width >> 1,-                                    _glfwWin.height >> 1 );+    if( _glfwWin.active )+    {+        _glfwPlatformHideMouseCursor();+    }      // From now on the mouse is locked     _glfwWin.mouseLock = GL_TRUE;
glfw/lib/win32/platform.h view
@@ -369,9 +369,8 @@     GLboolean                      has_WGL_ARB_create_context_profile;      // Various platform specific internal variables-    int       oldMouseLock;    // Old mouse-lock flag (used for remembering-                               // mouse-lock state when iconifying)-    int       oldMouseLockValid;+    int       mouseLockActive;    // Whether the mouse cursor enable is applied+                                  // to the actual system cursor     int       desiredRefreshRate; // Desired vertical monitor refresh rate  };
glfw/lib/win32/win32_init.c view
@@ -350,7 +350,7 @@      // Restore FOREGROUNDLOCKTIMEOUT system setting     SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0,-                          (LPVOID) _glfwLibrary.Sys.foregroundLockTimeout,+                          (LPVOID) (INT_PTR) _glfwLibrary.Sys.foregroundLockTimeout,                           SPIF_SENDCHANGE );      return GL_TRUE;
glfw/lib/win32/win32_window.c view
@@ -42,6 +42,20 @@   //========================================================================+// Updates the cursor clip rect+//========================================================================++static void updateClipRect( void )+{+    RECT clipRect;+    GetClientRect( _glfwWin.window, &clipRect );+    ClientToScreen( _glfwWin.window, (POINT*) &clipRect.left );+    ClientToScreen( _glfwWin.window, (POINT*) &clipRect.right );+    ClipCursor( &clipRect );+}+++//======================================================================== // Enable/disable minimize/restore animations //======================================================================== @@ -154,7 +168,7 @@  static _GLFWfbconfig *getFBConfigs( unsigned int *found ) {-    _GLFWfbconfig *result;+    _GLFWfbconfig *fbconfigs;     PIXELFORMATDESCRIPTOR pfd;     int i, count; @@ -175,8 +189,8 @@         return NULL;     } -    result = (_GLFWfbconfig*) malloc( sizeof( _GLFWfbconfig ) * count );-    if( !result )+    fbconfigs = (_GLFWfbconfig*) malloc( sizeof( _GLFWfbconfig ) * count );+    if( !fbconfigs )     {         fprintf(stderr, "Out of memory");         return NULL;@@ -184,6 +198,8 @@      for( i = 1;  i <= count;  i++ )     {+        _GLFWfbconfig *fbconfig = fbconfigs + *found;+         if( _glfwWin.has_WGL_ARB_pixel_format )         {             // Get pixel format attributes through WGL_ARB_pixel_format@@ -209,29 +225,29 @@                 continue;             } -            result[*found].redBits = getPixelFormatAttrib( i, WGL_RED_BITS_ARB );-            result[*found].greenBits = getPixelFormatAttrib( i, WGL_GREEN_BITS_ARB );-            result[*found].blueBits = getPixelFormatAttrib( i, WGL_BLUE_BITS_ARB );-            result[*found].alphaBits = getPixelFormatAttrib( i, WGL_ALPHA_BITS_ARB );+            fbconfig->redBits = getPixelFormatAttrib( i, WGL_RED_BITS_ARB );+            fbconfig->greenBits = getPixelFormatAttrib( i, WGL_GREEN_BITS_ARB );+            fbconfig->blueBits = getPixelFormatAttrib( i, WGL_BLUE_BITS_ARB );+            fbconfig->alphaBits = getPixelFormatAttrib( i, WGL_ALPHA_BITS_ARB ); -            result[*found].depthBits = getPixelFormatAttrib( i, WGL_DEPTH_BITS_ARB );-            result[*found].stencilBits = getPixelFormatAttrib( i, WGL_STENCIL_BITS_ARB );+            fbconfig->depthBits = getPixelFormatAttrib( i, WGL_DEPTH_BITS_ARB );+            fbconfig->stencilBits = getPixelFormatAttrib( i, WGL_STENCIL_BITS_ARB ); -            result[*found].accumRedBits = getPixelFormatAttrib( i, WGL_ACCUM_RED_BITS_ARB );-            result[*found].accumGreenBits = getPixelFormatAttrib( i, WGL_ACCUM_GREEN_BITS_ARB );-            result[*found].accumBlueBits = getPixelFormatAttrib( i, WGL_ACCUM_BLUE_BITS_ARB );-            result[*found].accumAlphaBits = getPixelFormatAttrib( i, WGL_ACCUM_ALPHA_BITS_ARB );+            fbconfig->accumRedBits = getPixelFormatAttrib( i, WGL_ACCUM_RED_BITS_ARB );+            fbconfig->accumGreenBits = getPixelFormatAttrib( i, WGL_ACCUM_GREEN_BITS_ARB );+            fbconfig->accumBlueBits = getPixelFormatAttrib( i, WGL_ACCUM_BLUE_BITS_ARB );+            fbconfig->accumAlphaBits = getPixelFormatAttrib( i, WGL_ACCUM_ALPHA_BITS_ARB ); -            result[*found].auxBuffers = getPixelFormatAttrib( i, WGL_AUX_BUFFERS_ARB );-            result[*found].stereo = getPixelFormatAttrib( i, WGL_STEREO_ARB );+            fbconfig->auxBuffers = getPixelFormatAttrib( i, WGL_AUX_BUFFERS_ARB );+            fbconfig->stereo = getPixelFormatAttrib( i, WGL_STEREO_ARB );              if( _glfwWin.has_WGL_ARB_multisample )             {-                result[*found].samples = getPixelFormatAttrib( i, WGL_SAMPLES_ARB );+                fbconfig->samples = getPixelFormatAttrib( i, WGL_SAMPLES_ARB );             }             else             {-                result[*found].samples = 0;+                fbconfig->samples = 0;             }         }         else@@ -254,6 +270,8 @@             if( !( pfd.dwFlags & PFD_GENERIC_ACCELERATED ) &&                 ( pfd.dwFlags & PFD_GENERIC_FORMAT ) )             {+                // If this is true, this pixel format is only supported by the+                // generic software implementation                 continue;             } @@ -263,32 +281,38 @@                 continue;             } -            result[*found].redBits = pfd.cRedBits;-            result[*found].greenBits = pfd.cGreenBits;-            result[*found].blueBits = pfd.cBlueBits;-            result[*found].alphaBits = pfd.cAlphaBits;+            fbconfig->redBits = pfd.cRedBits;+            fbconfig->greenBits = pfd.cGreenBits;+            fbconfig->blueBits = pfd.cBlueBits;+            fbconfig->alphaBits = pfd.cAlphaBits; -            result[*found].depthBits = pfd.cDepthBits;-            result[*found].stencilBits = pfd.cStencilBits;+            fbconfig->depthBits = pfd.cDepthBits;+            fbconfig->stencilBits = pfd.cStencilBits; -            result[*found].accumRedBits = pfd.cAccumRedBits;-            result[*found].accumGreenBits = pfd.cAccumGreenBits;-            result[*found].accumBlueBits = pfd.cAccumBlueBits;-            result[*found].accumAlphaBits = pfd.cAccumAlphaBits;+            fbconfig->accumRedBits = pfd.cAccumRedBits;+            fbconfig->accumGreenBits = pfd.cAccumGreenBits;+            fbconfig->accumBlueBits = pfd.cAccumBlueBits;+            fbconfig->accumAlphaBits = pfd.cAccumAlphaBits; -            result[*found].auxBuffers = pfd.cAuxBuffers;-            result[*found].stereo = ( pfd.dwFlags & PFD_STEREO ) ? GL_TRUE : GL_FALSE;+            fbconfig->auxBuffers = pfd.cAuxBuffers;+            fbconfig->stereo = ( pfd.dwFlags & PFD_STEREO ) ? GL_TRUE : GL_FALSE;              // PFD pixel formats do not support FSAA-            result[*found].samples = 0;+            fbconfig->samples = 0;         } -        result[*found].platformID = i;+        fbconfig->platformID = i;          (*found)++;     } -    return result;+    if( *found == 0 )+    {+        free( fbconfigs );+        return NULL;+    }++    return fbconfigs; }  @@ -370,6 +394,11 @@         {             return GL_FALSE;         }++        // Copy the debug context hint as there's no way of verifying it+        // This is the only code path capable of creating a debug context,+        // so leave it as false (from the earlier memset) otherwise+        _glfwWin.glDebug = wndconfig->glDebug;     }     else     {@@ -659,19 +688,26 @@ static LRESULT CALLBACK windowProc( HWND hWnd, UINT uMsg,                                     WPARAM wParam, LPARAM lParam ) {-    int wheelDelta, iconified;+    int wheelDelta;      switch( uMsg )     {         // Window activate message? (iconification?)         case WM_ACTIVATE:         {-            _glfwWin.active = LOWORD(wParam) != WA_INACTIVE ? GL_TRUE : GL_FALSE;+            int activated = (LOWORD(wParam) != WA_INACTIVE) ? GL_TRUE : GL_FALSE;+            int iconified = HIWORD(wParam) ? GL_TRUE : GL_FALSE; -            iconified = HIWORD(wParam) ? GL_TRUE : GL_FALSE;+            if( activated && iconified )+            {+                // This is a workaround for window iconification using the+                // taskbar leading to windows being told they're focused and+                // iconified and then never told they're defocused+                activated = GL_FALSE;+            }              // Were we deactivated/iconified?-            if( (!_glfwWin.active || iconified) && !_glfwWin.iconified )+            if( !activated && _glfwWin.active )             {                 _glfwInputDeactivation(); @@ -691,14 +727,12 @@                 }                  // Unlock mouse if locked-                if( !_glfwWin.oldMouseLockValid )+                if( _glfwWin.mouseLock )                 {-                    _glfwWin.oldMouseLock = _glfwWin.mouseLock;-                    _glfwWin.oldMouseLockValid = GL_TRUE;-                    glfwEnable( GLFW_MOUSE_CURSOR );+                    _glfwPlatformShowMouseCursor();                 }             }-            else if( _glfwWin.active || !iconified )+            else if( activated && !_glfwWin.active )             {                 // If we are in fullscreen mode we need to maximize                 if( _glfwWin.opened && _glfwWin.fullscreen && _glfwWin.iconified )@@ -721,13 +755,13 @@                 }                  // Lock mouse, if necessary-                if( _glfwWin.oldMouseLockValid && _glfwWin.oldMouseLock )+                if( _glfwWin.mouseLock )                 {-                    glfwDisable( GLFW_MOUSE_CURSOR );+                    _glfwPlatformHideMouseCursor();                 }-                _glfwWin.oldMouseLockValid = GL_FALSE;             } +            _glfwWin.active = activated;             _glfwWin.iconified = iconified;             return 0;         }@@ -865,8 +899,15 @@             if( NewMouseX != _glfwInput.OldMouseX ||                 NewMouseY != _glfwInput.OldMouseY )             {+                _glfwInput.MouseMoved = GL_TRUE;+                 if( _glfwWin.mouseLock )                 {+                    if( !_glfwWin.active )+                    {+                        return 0;+                    }+                     _glfwInput.MousePosX += NewMouseX -                                             _glfwInput.OldMouseX;                     _glfwInput.MousePosY += NewMouseY -@@ -879,7 +920,6 @@                 }                 _glfwInput.OldMouseX = NewMouseX;                 _glfwInput.OldMouseY = NewMouseY;-                _glfwInput.MouseMoved = GL_TRUE;                  if( _glfwWin.mousePosCallback )                 {@@ -914,11 +954,7 @@             // If the mouse is locked, update the clipping rect             if( _glfwWin.mouseLock )             {-                RECT ClipWindowRect;-                if( GetWindowRect( _glfwWin.window, &ClipWindowRect ) )-                {-                    ClipCursor( &ClipWindowRect );-                }+                updateClipRect();             }              if( _glfwWin.windowSizeCallback )@@ -933,11 +969,7 @@             // If the mouse is locked, update the clipping rect             if( _glfwWin.mouseLock )             {-                RECT ClipWindowRect;-                if( GetWindowRect( _glfwWin.window, &ClipWindowRect ) )-                {-                    ClipCursor( &ClipWindowRect );-                }+                updateClipRect();             }             return 0;         }@@ -991,23 +1023,20 @@  //======================================================================== // Initialize WGL-specific extensions-// This function is called once before initial context creation, i.e. before-// any WGL extensions could be present.  This is done in order to have both-// extension variable clearing and loading in the same place, hopefully-// decreasing the possibility of forgetting to add one without the other. //========================================================================  static void initWGLExtensions( void ) {-    // This needs to include every function pointer loaded below+    // This needs to include every function pointer loaded below, because+    // context re-creation means we cannot assume the struct has been cleared     _glfwWin.SwapIntervalEXT = NULL;     _glfwWin.GetPixelFormatAttribivARB = NULL;     _glfwWin.GetExtensionsStringARB = NULL;     _glfwWin.GetExtensionsStringEXT = NULL;     _glfwWin.CreateContextAttribsARB = NULL; -    // This needs to include every extension used below except for-    // WGL_ARB_extensions_string and WGL_EXT_extensions_string+    // This needs to include every extension boolean used below, because context+    // re-creation means we cannot assume the struct has been cleared     _glfwWin.has_WGL_EXT_swap_control = GL_FALSE;     _glfwWin.has_WGL_ARB_pixel_format = GL_FALSE;     _glfwWin.has_WGL_ARB_multisample = GL_FALSE;@@ -1143,7 +1172,7 @@     _glfwWin.window = NULL;      // Set common window styles-    dwStyle   = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;+    dwStyle   = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;     dwExStyle = WS_EX_APPWINDOW;      // Set window style, depending on fullscreen mode@@ -1316,8 +1345,6 @@                            wndconfig->refreshRate );     } -    initWGLExtensions();-     if( !createWindow( wndconfig, fbconfig ) )     {         fprintf( stderr, "Failed to create GLFW window\n" );@@ -1338,6 +1365,17 @@         }     } +    if( wndconfig->glDebug )+    {+        // Debug contexts are not a hard constraint, so we don't fail here if+        // the extension isn't available++        if( _glfwWin.has_WGL_ARB_create_context )+        {+            recreateContext = GL_TRUE;+        }+    }+     if( wndconfig->glMajor > 2 )     {         if ( wndconfig->glMajor != _glfwWin.glMajor ||@@ -1410,6 +1448,7 @@                       SWP_NOMOVE | SWP_NOSIZE );     } +    ShowWindow( _glfwWin.window, SW_SHOWNORMAL );     setForegroundWindow( _glfwWin.window );     SetFocus( _glfwWin.window ); @@ -1553,14 +1592,6 @@         // Change display settings to the desktop resolution         ChangeDisplaySettings( NULL, CDS_FULLSCREEN );     }--    // Unlock mouse-    if( !_glfwWin.oldMouseLockValid )-    {-        _glfwWin.oldMouseLock = _glfwWin.mouseLock;-        _glfwWin.oldMouseLockValid = GL_TRUE;-        glfwEnable( GLFW_MOUSE_CURSOR );-    } }  @@ -1587,13 +1618,6 @@      // Window is no longer iconified     _glfwWin.iconified = GL_FALSE;--    // Lock mouse, if necessary-    if( _glfwWin.oldMouseLockValid && _glfwWin.oldMouseLock )-    {-        glfwDisable( GLFW_MOUSE_CURSOR );-    }-    _glfwWin.oldMouseLockValid = GL_FALSE; }  @@ -1730,16 +1754,6 @@     // Flag: mouse was not moved (will be changed by _glfwGetNextEvent if     // there was a mouse move event)     _glfwInput.MouseMoved = GL_FALSE;-    if( _glfwWin.mouseLock )-    {-        _glfwInput.OldMouseX = _glfwWin.width/2;-        _glfwInput.OldMouseY = _glfwWin.height/2;-    }-    else-    {-        _glfwInput.OldMouseX = _glfwInput.MousePosX;-        _glfwInput.OldMouseY = _glfwInput.MousePosY;-    }      // Check for new window messages     while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )@@ -1783,7 +1797,7 @@     }      // Did we have mouse movement in locked cursor mode?-    if( _glfwInput.MouseMoved && _glfwWin.mouseLock )+    if( _glfwInput.MouseMoved && _glfwWin.active && _glfwWin.mouseLock )     {         _glfwPlatformSetMouseCursorPos( _glfwWin.width / 2,                                         _glfwWin.height / 2 );@@ -1820,18 +1834,23 @@  void _glfwPlatformHideMouseCursor( void ) {-    RECT ClipWindowRect;+    if( _glfwWin.mouseLockActive )+    {+        return;+    } +    // Move cursor to the middle of the window+    _glfwPlatformSetMouseCursorPos( _glfwWin.width / 2, _glfwWin.height / 2 );+     ShowCursor( FALSE );      // Clip cursor to the window-    if( GetWindowRect( _glfwWin.window, &ClipWindowRect ) )-    {-        ClipCursor( &ClipWindowRect );-    }+    updateClipRect();      // Capture cursor to user window     SetCapture( _glfwWin.window );++    _glfwWin.mouseLockActive = GL_TRUE; }  @@ -1841,6 +1860,11 @@  void _glfwPlatformShowMouseCursor( void ) {+    if( !_glfwWin.mouseLockActive )+    {+        return;+    }+     // Un-capture cursor     ReleaseCapture(); @@ -1848,6 +1872,8 @@     ClipCursor( NULL );      ShowCursor( TRUE );++    _glfwWin.mouseLockActive = GL_FALSE; }  @@ -1863,6 +1889,9 @@     pos.x = x;     pos.y = y;     ClientToScreen( _glfwWin.window, &pos );++    _glfwInput.OldMouseX = x;+    _glfwInput.OldMouseY = y;      SetCursorPos( pos.x, pos.y ); }
glfw/lib/x11/platform.h view
@@ -129,6 +129,20 @@ typedef intptr_t GLFWintptr;  +#ifndef GLX_EXT_swap_control++typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);++#endif /*GLX_MESA_swap_control*/+++#ifndef GLX_MESA_swap_control++typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);++#endif /*GLX_MESA_swap_control*/++ #ifndef GLX_SGI_swap_control  // Function signature for GLX_SGI_swap_control@@ -282,6 +296,8 @@     Cursor        cursor;            // Invisible cursor for hidden cursor      // GLX extensions+    PFNGLXSWAPINTERVALEXTPROC             SwapIntervalEXT;+    PFNGLXSWAPINTERVALMESAPROC            SwapIntervalMESA;     PFNGLXSWAPINTERVALSGIPROC             SwapIntervalSGI;     PFNGLXGETFBCONFIGATTRIBSGIXPROC       GetFBConfigAttribSGIX;     PFNGLXCHOOSEFBCONFIGSGIXPROC          ChooseFBConfigSGIX;@@ -289,6 +305,8 @@     PFNGLXGETVISUALFROMFBCONFIGSGIXPROC   GetVisualFromFBConfigSGIX;     PFNGLXCREATECONTEXTATTRIBSARBPROC     CreateContextAttribsARB;     GLboolean   has_GLX_SGIX_fbconfig;+    GLboolean   has_GLX_EXT_swap_control;+    GLboolean   has_GLX_MESA_swap_control;     GLboolean   has_GLX_SGI_swap_control;     GLboolean   has_GLX_ARB_multisample;     GLboolean   has_GLX_ARB_create_context;@@ -375,8 +393,11 @@      Display        *display; -    // Server-side GLX version-    int             glxMajor, glxMinor;+    struct {+        int         versionMajor, versionMinor;+        int         eventBase;+        int         errorBase;+    } GLX;      struct {         int         available;
glfw/lib/x11/x11_init.c view
@@ -177,7 +177,9 @@      // Fullscreen & screen saver settings     // Check if GLX is supported on this display-    if( !glXQueryExtension( _glfwLibrary.display, NULL, NULL ) )+    if( !glXQueryExtension( _glfwLibrary.display,+                            &_glfwLibrary.GLX.errorBase,+                            &_glfwLibrary.GLX.eventBase))     {         fprintf(stderr, "GLX not supported\n");         return GL_FALSE;@@ -185,8 +187,8 @@      // Retrieve GLX version     if( !glXQueryVersion( _glfwLibrary.display,-                          &_glfwLibrary.glxMajor,-                          &_glfwLibrary.glxMinor ) )+                          &_glfwLibrary.GLX.versionMajor,+                          &_glfwLibrary.GLX.versionMinor ) )     {         fprintf(stderr, "Unable to query GLX version\n");         return GL_FALSE;
glfw/lib/x11/x11_window.c view
@@ -46,7 +46,18 @@ #define _NET_WM_STATE_ADD           1 #define _NET_WM_STATE_TOGGLE        2 +#ifndef GLXBadProfileARB+ #define GLXBadProfileARB 13+#endif ++//========================================================================+// The X error code as provided to the X error handler+//========================================================================++static unsigned long _glfwErrorCode = Success;++ //************************************************************************ //****                  GLFW internal functions                       **** //************************************************************************@@ -58,6 +69,7 @@  static int errorHandler( Display *display, XErrorEvent *event ) {+    _glfwErrorCode = event->error_code;     return 0; } @@ -428,10 +440,11 @@     GLXFBConfig *fbconfigs;     _GLFWfbconfig *result;     int i, count = 0;+    GLboolean trustWindowBit = GL_TRUE;      *found = 0; -    if( _glfwLibrary.glxMajor == 1 && _glfwLibrary.glxMinor < 3 )+    if( _glfwLibrary.GLX.versionMajor == 1 && _glfwLibrary.GLX.versionMinor < 3 )     {         if( !_glfwWin.has_GLX_SGIX_fbconfig )         {@@ -440,6 +453,14 @@         }     } +    if( strcmp( glXGetClientString( _glfwLibrary.display, GLX_VENDOR ),+                "Chromium" ) == 0 )+    {+        // This is a (hopefully temporary) workaround for Chromium (VirtualBox+        // GL) not setting the window bit on any GLXFBConfigs+        trustWindowBit = GL_FALSE;+    }+     if( _glfwWin.has_GLX_SGIX_fbconfig )     {         fbconfigs = _glfwWin.ChooseFBConfigSGIX( _glfwLibrary.display,@@ -486,8 +507,11 @@          if( !( getFBConfigAttrib( fbconfigs[i], GLX_DRAWABLE_TYPE ) & GLX_WINDOW_BIT ) )         {-            // Only consider window GLXFBConfigs-            continue;+            if( trustWindowBit )+            {+                // Only consider window GLXFBConfigs+                continue;+            }         }          result[*found].redBits = getFBConfigAttrib( fbconfigs[i], GLX_RED_SIZE );@@ -527,6 +551,31 @@   //========================================================================+// Create the OpenGL context using the legacy interface+//========================================================================++static GLXContext createLegacyContext( GLXFBConfig fbconfig )+{+    if( _glfwWin.has_GLX_SGIX_fbconfig )+    {+        return _glfwWin.CreateContextWithConfigSGIX( _glfwLibrary.display,+                                                     fbconfig,+                                                     GLX_RGBA_TYPE,+                                                     NULL,+                                                     True );+    }+    else+    {+        return glXCreateNewContext( _glfwLibrary.display,+                                    fbconfig,+                                    GLX_RGBA_TYPE,+                                    NULL,+                                    True );+    }+}+++//======================================================================== // Create the OpenGL context //======================================================================== @@ -654,25 +703,28 @@          // We are done, so unset the error handler again (see above)         XSetErrorHandler( NULL );++        if( _glfwWin.context == NULL )+        {+            // HACK: This is a fallback for the broken Mesa implementation of+            // GLX_ARB_create_context_profile, which fails default 1.0 context+            // creation with a GLXBadProfileARB error in violation of the spec+            if( _glfwErrorCode == _glfwLibrary.GLX.errorBase + GLXBadProfileARB &&+                wndconfig->glProfile == 0 &&+                wndconfig->glForward == GL_FALSE )+            {+                _glfwWin.context = createLegacyContext( *fbconfig );+            }+        }++        // Copy the debug context hint as there's no way of verifying it+        // This is the only code path capable of creating a debug context,+        // so leave it as false (from the earlier memset) otherwise+        _glfwWin.glDebug = wndconfig->glDebug;     }     else     {-        if( _glfwWin.has_GLX_SGIX_fbconfig )-        {-            _glfwWin.context = _glfwWin.CreateContextWithConfigSGIX( _glfwLibrary.display,-                                                                     *fbconfig,-                                                                     GLX_RGBA_TYPE,-                                                                     NULL,-                                                                     True );-        }-        else-        {-            _glfwWin.context = glXCreateNewContext( _glfwLibrary.display,-                                                    *fbconfig,-                                                    GLX_RGBA_TYPE,-                                                    NULL,-                                                    True );-        }+        _glfwWin.context = createLegacyContext( *fbconfig );     }      XFree( fbconfig );@@ -698,6 +750,8 @@ static void initGLXExtensions( void ) {     // This needs to include every function pointer loaded below+    _glfwWin.SwapIntervalEXT             = NULL;+    _glfwWin.SwapIntervalMESA            = NULL;     _glfwWin.SwapIntervalSGI             = NULL;     _glfwWin.GetFBConfigAttribSGIX       = NULL;     _glfwWin.ChooseFBConfigSGIX          = NULL;@@ -707,11 +761,35 @@      // This needs to include every extension used below     _glfwWin.has_GLX_SGIX_fbconfig              = GL_FALSE;+    _glfwWin.has_GLX_EXT_swap_control           = GL_FALSE;+    _glfwWin.has_GLX_MESA_swap_control          = GL_FALSE;     _glfwWin.has_GLX_SGI_swap_control           = GL_FALSE;     _glfwWin.has_GLX_ARB_multisample            = GL_FALSE;     _glfwWin.has_GLX_ARB_create_context         = GL_FALSE;     _glfwWin.has_GLX_ARB_create_context_profile = GL_FALSE; +    if( _glfwPlatformExtensionSupported( "GLX_EXT_swap_control" ) )+    {+        _glfwWin.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)+            _glfwPlatformGetProcAddress( "glXSwapIntervalEXT" );++        if( _glfwWin.SwapIntervalEXT )+        {+            _glfwWin.has_GLX_EXT_swap_control = GL_TRUE;+        }+    }++    if( _glfwPlatformExtensionSupported( "GLX_MESA_swap_control" ) )+    {+        _glfwWin.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)+            _glfwPlatformGetProcAddress( "glXSwapIntervalMESA" );++        if( _glfwWin.SwapIntervalMESA )+        {+            _glfwWin.has_GLX_MESA_swap_control = GL_TRUE;+        }+    }+     if( _glfwPlatformExtensionSupported( "GLX_SGI_swap_control" ) )     {         _glfwWin.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)@@ -1521,6 +1599,8 @@         XFreeCursor( _glfwLibrary.display, _glfwWin.cursor );         _glfwWin.cursor = (Cursor) 0;     }++    XFlush( _glfwLibrary.display ); }  @@ -1543,7 +1623,6 @@ void _glfwPlatformSetWindowSize( int width, int height ) {     int     mode = 0, rate, sizeChanged = GL_FALSE;-    XSizeHints *sizehints;      rate = _glfwWin.refreshRate; @@ -1557,14 +1636,14 @@     {         // Update window size restrictions to match new window size -        sizehints = XAllocSizeHints();-        sizehints->flags = 0;+        XSizeHints *hints = XAllocSizeHints(); -        sizehints->min_width  = sizehints->max_width  = width;-        sizehints->min_height = sizehints->max_height = height;+        hints->flags |= (PMinSize | PMaxSize);+        hints->min_width  = hints->max_width  = width;+        hints->min_height = hints->max_height = height; -        XSetWMNormalHints( _glfwLibrary.display, _glfwWin.window, sizehints );-        XFree( sizehints );+        XSetWMNormalHints( _glfwLibrary.display, _glfwWin.window, hints );+        XFree( hints );     }      // Change window size before changing fullscreen mode?@@ -1649,10 +1728,23 @@  void _glfwPlatformSwapInterval( int interval ) {-    if( _glfwWin.has_GLX_SGI_swap_control )+    if( _glfwWin.has_GLX_EXT_swap_control )     {-        _glfwWin.SwapIntervalSGI( interval );+        _glfwWin.SwapIntervalEXT( _glfwLibrary.display,+                                  _glfwWin.window,+                                  interval );     }+    else if( _glfwWin.has_GLX_MESA_swap_control )+    {+        _glfwWin.SwapIntervalMESA( interval );+    }+    else if( _glfwWin.has_GLX_SGI_swap_control )+    {+        if( interval > 0 )+        {+            _glfwWin.SwapIntervalSGI( interval );+        }+    } }  @@ -1838,6 +1930,9 @@             _glfwWin.pointerGrabbed = GL_TRUE;         }     }++    // Move cursor to the middle of the window+    _glfwPlatformSetMouseCursorPos( _glfwWin.width / 2, _glfwWin.height / 2 ); }