packages feed

bindings-GLFW 3.1.2.4 → 3.2.1.0

raw patch · 62 files changed

+17238/−11187 lines, 62 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Bindings.GLFW: c'GL_FALSE :: (Num a) => a
- Bindings.GLFW: c'GL_TRUE :: (Num a) => a
+ Bindings.GLFW: c'GLFW_ANY_RELEASE_BEHAVIOR :: (Num a) => a
+ Bindings.GLFW: c'GLFW_AUTO_ICONIFY :: (Num a) => a
+ Bindings.GLFW: c'GLFW_CONTEXT_CREATION_API :: (Num a) => a
+ Bindings.GLFW: c'GLFW_CONTEXT_NO_ERROR :: (Num a) => a
+ Bindings.GLFW: c'GLFW_CONTEXT_RELEASE_BEHAVIOR :: (Num a) => a
+ Bindings.GLFW: c'GLFW_DONT_CARE :: (Num a) => a
+ Bindings.GLFW: c'GLFW_DOUBLEBUFFER :: (Num a) => a
+ Bindings.GLFW: c'GLFW_EGL_CONTEXT_API :: (Num a) => a
+ Bindings.GLFW: c'GLFW_FALSE :: (Num a) => a
+ Bindings.GLFW: c'GLFW_FLOATING :: (Num a) => a
+ Bindings.GLFW: c'GLFW_MAXIMIZED :: (Num a) => a
+ Bindings.GLFW: c'GLFW_NATIVE_CONTEXT_API :: (Num a) => a
+ Bindings.GLFW: c'GLFW_NO_API :: (Num a) => a
+ Bindings.GLFW: c'GLFW_RELEASE_BEHAVIOR_FLUSH :: (Num a) => a
+ Bindings.GLFW: c'GLFW_RELEASE_BEHAVIOR_NONE :: (Num a) => a
+ Bindings.GLFW: c'GLFW_TRUE :: (Num a) => a
+ Bindings.GLFW: c'glfwCreateWindowSurface :: Ptr vkInstance -> Ptr C'GLFWwindow -> Ptr vkAllocationCallbacks -> Ptr vkSurfaceKHR -> IO Int32
+ Bindings.GLFW: c'glfwFocusWindow :: Ptr C'GLFWwindow -> IO ()
+ Bindings.GLFW: c'glfwGetCocoaMonitor :: Ptr C'GLFWwindow -> IO (Ptr Word32)
+ Bindings.GLFW: c'glfwGetCocoaWindow :: Ptr C'GLFWwindow -> IO (Ptr ())
+ Bindings.GLFW: c'glfwGetEGLContext :: Ptr C'GLFWwindow -> IO (Ptr ())
+ Bindings.GLFW: c'glfwGetEGLDisplay :: IO (Ptr ())
+ Bindings.GLFW: c'glfwGetEGLSurface :: Ptr C'GLFWwindow -> IO (Ptr ())
+ Bindings.GLFW: c'glfwGetGLXContext :: Ptr C'GLFWwindow -> IO (Ptr ())
+ Bindings.GLFW: c'glfwGetGLXWindow :: Ptr C'GLFWwindow -> IO Word64
+ Bindings.GLFW: c'glfwGetInstanceProcAddress :: Ptr vkInstance -> CString -> IO (FunPtr vkProc)
+ Bindings.GLFW: c'glfwGetKeyName :: CInt -> CInt -> IO CString
+ Bindings.GLFW: c'glfwGetMirDisplay :: IO (Ptr mir_connection)
+ Bindings.GLFW: c'glfwGetMirMonitor :: Ptr C'GLFWwindow -> IO CInt
+ Bindings.GLFW: c'glfwGetMirWindow :: Ptr C'GLFWwindow -> IO (Ptr mir_surface)
+ Bindings.GLFW: c'glfwGetNSGLContext :: Ptr C'GLFWwindow -> IO (Ptr ())
+ Bindings.GLFW: c'glfwGetPhysicalDevicePresentationSupport :: Ptr vkInstance -> Ptr vkPhysicalDevice -> Word32 -> IO CInt
+ Bindings.GLFW: c'glfwGetRequiredInstanceExtensions :: Ptr Word32 -> IO (Ptr CString)
+ Bindings.GLFW: c'glfwGetTimerFrequency :: IO (CULong)
+ Bindings.GLFW: c'glfwGetTimerValue :: IO (CULong)
+ Bindings.GLFW: c'glfwGetWGLContext :: Ptr C'GLFWwindow -> IO (Ptr ())
+ Bindings.GLFW: c'glfwGetWaylandDisplay :: IO (Ptr wl_display)
+ Bindings.GLFW: c'glfwGetWaylandMonitor :: Ptr C'GLFWwindow -> IO (Ptr wl_output)
+ Bindings.GLFW: c'glfwGetWaylandWindow :: Ptr C'GLFWwindow -> IO (Ptr wl_surface)
+ Bindings.GLFW: c'glfwGetWin32Adapter :: Ptr C'GLFWwindow -> IO CString
+ Bindings.GLFW: c'glfwGetWin32Monitor :: Ptr C'GLFWwindow -> IO (Ptr ())
+ Bindings.GLFW: c'glfwGetWin32Window :: Ptr C'GLFWwindow -> IO (Ptr ())
+ Bindings.GLFW: c'glfwGetWindowFrameSize :: Ptr C'GLFWwindow -> Ptr CInt -> Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()
+ Bindings.GLFW: c'glfwGetX11Adapter :: Ptr C'GLFWwindow -> IO Word64
+ Bindings.GLFW: c'glfwGetX11Display :: Ptr C'GLFWwindow -> IO (Ptr display)
+ Bindings.GLFW: c'glfwGetX11Monitor :: Ptr C'GLFWwindow -> IO Word64
+ Bindings.GLFW: c'glfwGetX11Window :: Ptr C'GLFWwindow -> IO Word64
+ Bindings.GLFW: c'glfwMaximizeWindow :: Ptr C'GLFWwindow -> IO ()
+ Bindings.GLFW: c'glfwSetCharModsCallback :: Ptr C'GLFWwindow -> C'GLFWcharmodsfun -> IO C'GLFWcharmodsfun
+ Bindings.GLFW: c'glfwSetJoystickCallback :: C'GLFWjoystickfun -> IO C'GLFWjoystickfun
+ Bindings.GLFW: c'glfwSetWindowAspectRatio :: Ptr C'GLFWwindow -> CInt -> CInt -> IO ()
+ Bindings.GLFW: c'glfwSetWindowIcon :: Ptr C'GLFWwindow -> CInt -> Ptr C'GLFWimage -> IO ()
+ Bindings.GLFW: c'glfwSetWindowMonitor :: Ptr C'GLFWwindow -> Ptr C'GLFWmonitor -> CInt -> CInt -> CInt -> CInt -> CInt -> IO ()
+ Bindings.GLFW: c'glfwSetWindowSizeLimits :: Ptr C'GLFWwindow -> CInt -> CInt -> CInt -> CInt -> IO ()
+ Bindings.GLFW: c'glfwVulkanSupported :: IO CInt
+ Bindings.GLFW: c'glfwWaitEventsTimeout :: CDouble -> IO ()
+ Bindings.GLFW: mK'GLFWcharmodsfun :: C'GLFWcharmodsfun -> (Ptr C'GLFWwindow -> CUInt -> CInt -> IO ())
+ Bindings.GLFW: mK'GLFWjoystickfun :: C'GLFWjoystickfun -> (CInt -> CInt -> IO ())
+ Bindings.GLFW: mk'GLFWcharmodsfun :: (Ptr C'GLFWwindow -> CUInt -> CInt -> IO ()) -> IO C'GLFWcharmodsfun
+ Bindings.GLFW: mk'GLFWjoystickfun :: (CInt -> CInt -> IO ()) -> IO C'GLFWjoystickfun
+ Bindings.GLFW: p'glfwCreateWindowSurface :: FunPtr (Ptr vkInstance -> Ptr C'GLFWwindow -> Ptr vkAllocationCallbacks -> Ptr vkSurfaceKHR -> IO Int32)
+ Bindings.GLFW: p'glfwFocusWindow :: FunPtr (Ptr C'GLFWwindow -> IO ())
+ Bindings.GLFW: p'glfwGetCocoaMonitor :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr Word32))
+ Bindings.GLFW: p'glfwGetCocoaWindow :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetEGLContext :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetEGLDisplay :: FunPtr (IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetEGLSurface :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetGLXContext :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetGLXWindow :: FunPtr (Ptr C'GLFWwindow -> IO Word64)
+ Bindings.GLFW: p'glfwGetInstanceProcAddress :: FunPtr (Ptr vkInstance -> CString -> IO (FunPtr vkProc))
+ Bindings.GLFW: p'glfwGetKeyName :: FunPtr (CInt -> CInt -> IO CString)
+ Bindings.GLFW: p'glfwGetMirDisplay :: FunPtr (IO (Ptr mir_connection))
+ Bindings.GLFW: p'glfwGetMirMonitor :: FunPtr (Ptr C'GLFWwindow -> IO CInt)
+ Bindings.GLFW: p'glfwGetMirWindow :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr mir_surface))
+ Bindings.GLFW: p'glfwGetNSGLContext :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetPhysicalDevicePresentationSupport :: FunPtr (Ptr vkInstance -> Ptr vkPhysicalDevice -> Word32 -> IO CInt)
+ Bindings.GLFW: p'glfwGetRequiredInstanceExtensions :: FunPtr (Ptr Word32 -> IO (Ptr CString))
+ Bindings.GLFW: p'glfwGetTimerFrequency :: FunPtr (IO (CULong))
+ Bindings.GLFW: p'glfwGetTimerValue :: FunPtr (IO (CULong))
+ Bindings.GLFW: p'glfwGetWGLContext :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetWaylandDisplay :: FunPtr (IO (Ptr wl_display))
+ Bindings.GLFW: p'glfwGetWaylandMonitor :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr wl_output))
+ Bindings.GLFW: p'glfwGetWaylandWindow :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr wl_surface))
+ Bindings.GLFW: p'glfwGetWin32Adapter :: FunPtr (Ptr C'GLFWwindow -> IO CString)
+ Bindings.GLFW: p'glfwGetWin32Monitor :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetWin32Window :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))
+ Bindings.GLFW: p'glfwGetWindowFrameSize :: FunPtr (Ptr C'GLFWwindow -> Ptr CInt -> Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ())
+ Bindings.GLFW: p'glfwGetX11Adapter :: FunPtr (Ptr C'GLFWwindow -> IO Word64)
+ Bindings.GLFW: p'glfwGetX11Display :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr display))
+ Bindings.GLFW: p'glfwGetX11Monitor :: FunPtr (Ptr C'GLFWwindow -> IO Word64)
+ Bindings.GLFW: p'glfwGetX11Window :: FunPtr (Ptr C'GLFWwindow -> IO Word64)
+ Bindings.GLFW: p'glfwMaximizeWindow :: FunPtr (Ptr C'GLFWwindow -> IO ())
+ Bindings.GLFW: p'glfwSetCharModsCallback :: FunPtr (Ptr C'GLFWwindow -> C'GLFWcharmodsfun -> IO C'GLFWcharmodsfun)
+ Bindings.GLFW: p'glfwSetJoystickCallback :: FunPtr (C'GLFWjoystickfun -> IO C'GLFWjoystickfun)
+ Bindings.GLFW: p'glfwSetWindowAspectRatio :: FunPtr (Ptr C'GLFWwindow -> CInt -> CInt -> IO ())
+ Bindings.GLFW: p'glfwSetWindowIcon :: FunPtr (Ptr C'GLFWwindow -> CInt -> Ptr C'GLFWimage -> IO ())
+ Bindings.GLFW: p'glfwSetWindowMonitor :: FunPtr (Ptr C'GLFWwindow -> Ptr C'GLFWmonitor -> CInt -> CInt -> CInt -> CInt -> CInt -> IO ())
+ Bindings.GLFW: p'glfwSetWindowSizeLimits :: FunPtr (Ptr C'GLFWwindow -> CInt -> CInt -> CInt -> CInt -> IO ())
+ Bindings.GLFW: p'glfwVulkanSupported :: FunPtr (IO CInt)
+ Bindings.GLFW: p'glfwWaitEventsTimeout :: FunPtr (CDouble -> IO ())
+ Bindings.GLFW: type C'GLFWcharmodsfun = FunPtr (Ptr C'GLFWwindow -> CUInt -> CInt -> IO ())
+ Bindings.GLFW: type C'GLFWjoystickfun = FunPtr (CInt -> CInt -> IO ())

Files

Bindings/GLFW.hsc view
@@ -7,6 +7,7 @@  #include <bindings.dsl.h> #include <GLFW/glfw3.h>+ #ifdef ExposeNative   #warning "You are compiling glfw using the native access functions. BEWARE." @@ -22,8 +23,16 @@    #elif defined(__linux__) -    #define GLFW_EXPOSE_NATIVE_X11-    #define GLFW_EXPOSE_NATIVE_GLX+    #if defined(BINDINGS_GLFW_USE_X11)+      #define GLFW_EXPOSE_NATIVE_X11+      #define GLFW_EXPOSE_NATIVE_GLX+    #elif defined(BINDINGS_GLFW_USE_WAYLAND)+      #define GLFW_EXPOSE_NATIVE_WAYLAND+      #define GLFW_EXPOSE_NATIVE_EGL+    #elif defined(BINDINGS_GLFW_USE_MIR)+      #define GLFW_EXPOSE_NATIVE_MIR+      #define GLFW_EXPOSE_NATIVE_EGL+    #endif    #endif @@ -36,19 +45,19 @@ module Bindings.GLFW where  import Prelude (Eq, IO, Num, Show)-import Prelude (($), return)+import Prelude (($), return, error, (++))  import Data.Data        (Data)+import Data.Int         (Int32)+import Data.Word        (Word32, Word64) import Data.Typeable    (Typeable) import Foreign.C.Types  (CChar, CUChar, CUShort)-import Foreign.C.Types  (CDouble(..), CFloat(..), CInt(..), CUInt(..))-import Foreign.Ptr      (FunPtr, Ptr, plusPtr)+import Foreign.C.Types  (CDouble(..), CFloat(..), CInt(..), CUInt(..), CULong(..))+import Foreign.C.String (CString)+import Foreign.Ptr      (FunPtr, nullFunPtr, Ptr, plusPtr) import Foreign.Storable (Storable(..)) -------------------------------------------------------------------------------- -#num GL_FALSE-#num GL_TRUE- #num GLFW_VERSION_MAJOR #num GLFW_VERSION_MINOR #num GLFW_VERSION_REVISION@@ -406,6 +415,14 @@ #num GLFW_HAND_CURSOR #num GLFW_HRESIZE_CURSOR #num GLFW_VRESIZE_CURSOR+#num GLFW_DONT_CARE+#num GLFW_DOUBLEBUFFER+#num GLFW_AUTO_ICONIFY+#num GLFW_FLOATING+#num GLFW_CONTEXT_RELEASE_BEHAVIOR+#num GLFW_ANY_RELEASE_BEHAVIOR+#num GLFW_RELEASE_BEHAVIOR_FLUSH+#num GLFW_RELEASE_BEHAVIOR_NONE  #starttype GLFWimage #field width  , CInt@@ -418,9 +435,288 @@ deriving instance Data     C'GLFWcursor  #callback GLFWdropfun , Ptr <GLFWwindow> -> CInt -> Ptr (Ptr CChar) -> IO ()+#callback GLFWcharmodsfun , Ptr <GLFWwindow> -> CUInt -> CInt -> IO ()  #ccall glfwCreateCursor , Ptr <GLFWimage> -> CInt -> CInt -> IO (Ptr <GLFWcursor>) #ccall glfwCreateStandardCursor , CInt -> IO (Ptr <GLFWcursor>) #ccall glfwSetCursor , Ptr <GLFWwindow> -> Ptr <GLFWcursor> -> IO () #ccall glfwDestroyCursor , Ptr <GLFWcursor> -> IO () #ccall glfwSetDropCallback , Ptr <GLFWwindow> -> <GLFWdropfun> -> IO <GLFWdropfun>+#ccall glfwSetCharModsCallback , Ptr <GLFWwindow> -> <GLFWcharmodsfun> -> IO <GLFWcharmodsfun>+#ccall glfwGetWindowFrameSize , Ptr <GLFWwindow> -> Ptr CInt -> Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()++--------------------------------------------------------------------------------+-- GLFW 3.2 additions+--------------------------------------------------------------------------------++#num GLFW_NO_API+#num GLFW_CONTEXT_CREATION_API+#num GLFW_NATIVE_CONTEXT_API+#num GLFW_EGL_CONTEXT_API+#num GLFW_CONTEXT_NO_ERROR+#num GLFW_TRUE+#num GLFW_FALSE+#num GLFW_MAXIMIZED++#ccall glfwFocusWindow , Ptr <GLFWwindow> -> IO ()+#ccall glfwMaximizeWindow , Ptr <GLFWwindow> -> IO ()+#ccall glfwSetWindowMonitor , Ptr <GLFWwindow> -> Ptr <GLFWmonitor> -> CInt -> CInt -> CInt -> CInt -> CInt -> IO ()+#ccall glfwSetWindowIcon , Ptr <GLFWwindow> -> CInt -> Ptr <GLFWimage> -> IO ()+#ccall glfwWaitEventsTimeout , CDouble -> IO ()+#ccall glfwSetWindowSizeLimits , Ptr <GLFWwindow> -> CInt -> CInt -> CInt -> CInt -> IO ()+#ccall glfwSetWindowAspectRatio , Ptr <GLFWwindow> -> CInt -> CInt -> IO ()+#ccall glfwGetKeyName , CInt -> CInt -> IO CString+#ccall glfwGetTimerValue , IO (CULong)+#ccall glfwGetTimerFrequency , IO (CULong)++#callback GLFWjoystickfun , CInt -> CInt -> IO ()+#ccall glfwSetJoystickCallback , <GLFWjoystickfun> -> IO <GLFWjoystickfun>++#ccall glfwVulkanSupported , IO CInt+#ccall glfwGetRequiredInstanceExtensions , Ptr Word32 -> IO (Ptr CString)++-- GLFW prevents the declaration of some of the Vulkan functions in its header+-- glfw3.h if it cannot find the required Vulkan headers. As of now (4/2018),+-- these functions are still *defined* in vulkan.c, which is built regardless of+-- whether or not the Vulkan headers were found. Internally, the required types+-- are defined locally in order to make the build work, and h2c will still link+-- against them without a problem. Whether or not you have a valid Vulkan+-- implementation might not be clear though. Nothing is preventing the glfw3+-- authors from hiding the Vulkan functions without valid headers, which could+-- cause some pain in the future, so use the following functions with caution.+-- See commit @521d161af85047 for a way to deal with this more annoyingly.+#ccall glfwGetInstanceProcAddress               , Ptr vkInstance -> CString -> IO (FunPtr vkProc)+#ccall glfwGetPhysicalDevicePresentationSupport , Ptr vkInstance -> Ptr vkPhysicalDevice -> Word32 -> IO CInt+#ccall glfwCreateWindowSurface                  , Ptr vkInstance -> Ptr <GLFWwindow> -> Ptr vkAllocationCallbacks -> Ptr vkSurfaceKHR -> IO Int32+++--------------------------------------------------------------------------------+-- Native APIs+--------------------------------------------------------------------------------++#if defined(GLFW_EXPOSE_NATIVE_WIN32)+#ccall glfwGetWin32Adapter , Ptr <GLFWwindow> -> IO CString+#ccall glfwGetWin32Monitor , Ptr <GLFWwindow> -> IO (Ptr ())+#ccall glfwGetWin32Window  , Ptr <GLFWwindow> -> IO (Ptr ())+#else++p'glfwGetWin32Adapter :: FunPtr (Ptr C'GLFWwindow -> IO CString)+p'glfwGetWin32Adapter = nullFunPtr++c'glfwGetWin32Adapter :: Ptr C'GLFWwindow -> IO CString+c'glfwGetWin32Adapter =+  error $ "c'glfwGetWin32Adapter undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetWin32Monitor :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))+p'glfwGetWin32Monitor = nullFunPtr++c'glfwGetWin32Monitor :: Ptr C'GLFWwindow -> IO (Ptr ())+c'glfwGetWin32Monitor =+  error $ "c'glfwGetWin32Monitor undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetWin32Window :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))+p'glfwGetWin32Window = nullFunPtr++c'glfwGetWin32Window ::  Ptr C'GLFWwindow -> IO (Ptr ())+c'glfwGetWin32Window =+  error $ "c'glfwGetWin32Window undefined! -- "+       ++ "Did you use the wrong glfw3native API?"+#endif++#if defined(GLFW_EXPOSE_NATIVE_WGL)+#ccall glfwGetWGLContext , Ptr <GLFWwindow> -> IO (Ptr ())+#else+p'glfwGetWGLContext :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))+p'glfwGetWGLContext = nullFunPtr++c'glfwGetWGLContext :: Ptr C'GLFWwindow -> IO (Ptr ())+c'glfwGetWGLContext =+  error $ "c'glfwGetWGLContext undefined! -- "+       ++ "Did you use the wrong glfw3native API?"+#endif++#if defined(GLFW_EXPOSE_NATIVE_COCOA)+#ccall glfwGetCocoaMonitor , Ptr <GLFWwindow> -> IO (Ptr Word32)+#ccall glfwGetCocoaWindow , Ptr <GLFWwindow> -> IO (Ptr ())+#else+p'glfwGetCocoaMonitor :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr Word32))+p'glfwGetCocoaMonitor = nullFunPtr++c'glfwGetCocoaMonitor :: Ptr C'GLFWwindow -> IO (Ptr Word32)+c'glfwGetCocoaMonitor =+  error $ "c'glfwGetCocoaMonitor undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetCocoaWindow :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))+p'glfwGetCocoaWindow = nullFunPtr++c'glfwGetCocoaWindow :: Ptr C'GLFWwindow -> IO (Ptr ())+c'glfwGetCocoaWindow =+  error $ "c'glfwGetCocoaWindow undefined! -- "+       ++ "Did you use the wrong glfw3native API?"+#endif++#if defined(GLFW_EXPOSE_NATIVE_NSGL)+#ccall glfwGetNSGLContext , Ptr <GLFWwindow> -> IO (Ptr ())+#else+p'glfwGetNSGLContext :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))+p'glfwGetNSGLContext = nullFunPtr++c'glfwGetNSGLContext :: Ptr C'GLFWwindow -> IO (Ptr ())+c'glfwGetNSGLContext =+  error $ "c'glfwGetNSGLContext undefined! -- "+       ++ "Did you use the wrong glfw3native API?"+#endif++#if defined(GLFW_EXPOSE_NATIVE_X11)+#ccall glfwGetX11Display , Ptr <GLFWwindow> -> IO (Ptr display)+#ccall glfwGetX11Adapter , Ptr <GLFWwindow> -> IO Word64+#ccall glfwGetX11Monitor , Ptr <GLFWwindow> -> IO Word64+#ccall glfwGetX11Window  , Ptr <GLFWwindow> -> IO Word64+#else+p'glfwGetX11Display :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr display))+p'glfwGetX11Display = nullFunPtr++c'glfwGetX11Display :: Ptr C'GLFWwindow -> IO (Ptr display)+c'glfwGetX11Display =+  error $ "c'glfwGetX11Display undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetX11Adapter :: FunPtr (Ptr C'GLFWwindow -> IO Word64)+p'glfwGetX11Adapter = nullFunPtr++c'glfwGetX11Adapter :: Ptr C'GLFWwindow -> IO Word64+c'glfwGetX11Adapter =+  error $ "c'glfwGetX11Adapter undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetX11Monitor :: FunPtr (Ptr C'GLFWwindow -> IO Word64)+p'glfwGetX11Monitor = nullFunPtr++c'glfwGetX11Monitor :: Ptr C'GLFWwindow -> IO Word64+c'glfwGetX11Monitor =+  error $ "c'glfwGetX11Monitor undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetX11Window :: FunPtr (Ptr C'GLFWwindow -> IO Word64)+p'glfwGetX11Window = nullFunPtr++c'glfwGetX11Window ::  Ptr C'GLFWwindow -> IO Word64+c'glfwGetX11Window =+  error $ "c'glfwGetX11Window undefined! -- "+       ++ "Did you use the wrong glfw3native API?"+#endif++#if defined(GLFW_EXPOSE_NATIVE_GLX)+#ccall glfwGetGLXContext , Ptr <GLFWwindow> -> IO (Ptr ())+#ccall glfwGetGLXWindow  , Ptr <GLFWwindow> -> IO Word64+#else+p'glfwGetGLXContext :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))+p'glfwGetGLXContext = nullFunPtr++c'glfwGetGLXContext :: Ptr C'GLFWwindow -> IO (Ptr ())+c'glfwGetGLXContext =+  error $ "c'glfwGetGLXContext undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetGLXWindow :: FunPtr (Ptr C'GLFWwindow -> IO Word64)+p'glfwGetGLXWindow = nullFunPtr++c'glfwGetGLXWindow ::  Ptr C'GLFWwindow -> IO Word64+c'glfwGetGLXWindow =+  error $ "c'glfwGetGLXWindow undefined! -- "+       ++ "Did you use the wrong glfw3native API?"+#endif++#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)+#ccall glfwGetWaylandDisplay , IO (Ptr wl_display)+#ccall glfwGetWaylandMonitor , Ptr <GLFWwindow> -> IO (Ptr wl_output)+#ccall glfwGetWaylandWindow , Ptr <GLFWwindow> -> IO (Ptr wl_surface)+#else+p'glfwGetWaylandDisplay :: FunPtr (IO (Ptr wl_display))+p'glfwGetWaylandDisplay = nullFunPtr++c'glfwGetWaylandDisplay :: IO (Ptr wl_display)+c'glfwGetWaylandDisplay =+  error $ "c'glfwGetWaylandDisplay undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetWaylandMonitor :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr wl_output))+p'glfwGetWaylandMonitor = nullFunPtr++c'glfwGetWaylandMonitor :: Ptr C'GLFWwindow -> IO (Ptr wl_output)+c'glfwGetWaylandMonitor =+  error $ "c'glfwGetWaylandMonitor undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetWaylandWindow :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr wl_surface))+p'glfwGetWaylandWindow = nullFunPtr++c'glfwGetWaylandWindow :: Ptr C'GLFWwindow -> IO (Ptr wl_surface)+c'glfwGetWaylandWindow =+  error $ "c'glfwGetWaylandWindow undefined! -- "+       ++ "Did you use the wrong glfw3native API?"+#endif++#if defined(GLFW_EXPOSE_NATIVE_MIR)+#ccall glfwGetMirDisplay , IO (Ptr mir_connection)+#ccall glfwGetMirMonitor , Ptr <GLFWwindow> -> IO CInt+#ccall glfwGetMirWindow , Ptr <GLFWwindow> -> IO (Ptr mir_surface)+#else+p'glfwGetMirDisplay :: FunPtr (IO (Ptr mir_connection))+p'glfwGetMirDisplay = nullFunPtr++c'glfwGetMirDisplay :: IO (Ptr mir_connection)+c'glfwGetMirDisplay =+  error $ "c'glfwGetMirDisplay undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetMirMonitor :: FunPtr (Ptr C'GLFWwindow -> IO CInt)+p'glfwGetMirMonitor = nullFunPtr++c'glfwGetMirMonitor :: Ptr C'GLFWwindow -> IO CInt+c'glfwGetMirMonitor =+  error $ "c'glfwGetMirMonitor undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetMirWindow :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr mir_surface))+p'glfwGetMirWindow = nullFunPtr++c'glfwGetMirWindow :: Ptr C'GLFWwindow -> IO (Ptr mir_surface)+c'glfwGetMirWindow =+  error $ "c'glfwGetMirWindow undefined! -- "+       ++ "Did you use the wrong glfw3native API?"+#endif++#if defined(GLFW_EXPOSE_NATIVE_EGL)+#ccall glfwGetEGLDisplay , IO (Ptr ())+#ccall glfwGetEGLContext , Ptr <GLFWwindow> -> IO (Ptr ())+#ccall glfwGetEGLSurface , Ptr <GLFWwindow> -> IO (Ptr ())+#else+p'glfwGetEGLDisplay :: FunPtr (IO (Ptr ()))+p'glfwGetEGLDisplay = nullFunPtr++c'glfwGetEGLDisplay :: IO (Ptr ())+c'glfwGetEGLDisplay =+  error $ "c'glfwGetEGLDisplay undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetEGLContext :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))+p'glfwGetEGLContext = nullFunPtr++c'glfwGetEGLContext :: Ptr C'GLFWwindow -> IO (Ptr ())+c'glfwGetEGLContext =+  error $ "c'glfwGetEGLContext undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++p'glfwGetEGLSurface :: FunPtr (Ptr C'GLFWwindow -> IO (Ptr ()))+p'glfwGetEGLSurface = nullFunPtr++c'glfwGetEGLSurface :: Ptr C'GLFWwindow -> IO (Ptr ())+c'glfwGetEGLSurface =+  error $ "c'glfwGetEGLSurface undefined! -- "+       ++ "Did you use the wrong glfw3native API?"++#endif
README.md view
@@ -9,30 +9,20 @@ library for creating windows with OpenGL contexts and managing input and events. -The binding is to [GLFW 3.1 released 2015-01-18][3].+The binding is to [GLFW 3.2.1 released 2016-08-18][3]. -*These bindings are too low-level for normal use.* For higher-level GLFW-bindings, see [GLFW-b][4].+*These bindings are a lot lower level than intended for normal use.*+For higher-level GLFW bindings, see [GLFW-b][4].  ## Contributing -This package uses git-flow as development model, in short that means that:--1. New features should be added to "develop" branch.-2. "master" branch is reserved for stable releases.-3. Patches for bugs related with previous releases should always be done in-    "hotfixes" branch.-4. All merge commits to master from "hotfixes" should be done-    using the "--no-ff" flag and from "develop" should avoid merging commits.--Until we have a defined road-map we are going to leave out "release-"branches" and "feature branches". For more information about this development-model please refer to [this site.][5]+1. To add a new feature or fix a bug, please start a new branch with a+   meaningful name (not "feature").+2. "master" branch is reserved as the current up-to-date working tree. -Thanks you, and happy coding.+Thank you, and happy coding.  [1]: http://www.haskell.org/ [2]: http://www.glfw.org/-[3]: http://www.glfw.org/Version-3.1-released.html+[3]: http://www.glfw.org/Version-3.2.1-released.html [4]: https://github.com/bsl/GLFW-b-[5]: http://nvie.com/posts/a-successful-git-branching-model/
Test.hs view
@@ -4,13 +4,14 @@ import Data.Char             (isAscii) import Data.List             (intercalate, isPrefixOf) import Foreign.C.String      (peekCString, withCString)+import Foreign.C.Types       (CDouble(..)) import Foreign.Marshal.Alloc (alloca) import Foreign.Marshal.Array (peekArray)-import Foreign.Ptr           (Ptr, nullPtr)+import Foreign.Ptr           (Ptr, nullPtr, nullFunPtr) import Foreign.Storable      (Storable(..))  -- HUnit-import Test.HUnit ((@?=), assertBool, assertFailure)+import Test.HUnit ((@?=), (@?), assertBool, assertFailure)  -- test-framework import Test.Framework (Test, defaultMain, testGroup)@@ -39,11 +40,19 @@      p'mon <- c'glfwGetPrimaryMonitor -    c'glfwWindowHint c'GLFW_VISIBLE c'GL_FALSE+    c'glfwWindowHint c'GLFW_VISIBLE c'GLFW_FALSE     p'win <- withCString "bindings-GLFW test" $ \p'title ->       c'glfwCreateWindow 100 100 p'title nullPtr nullPtr     c'glfwMakeContextCurrent p'win +    -- Mostly check for compiling+    cmcb <- mk'GLFWcharmodsfun $ \win x y ->+        putStrLn $ "Got char mods callback! " ++ show (win, x, y)+    _ <- c'glfwSetCharModsCallback p'win cmcb+    jcb <- mk'GLFWjoystickfun $ \x y ->+        putStrLn $ "Got joystick callback! " ++ show (x, y)+    _ <- c'glfwSetJoystickCallback jcb+     defaultMain $ tests p'mon p'win      -- TODO because of how defaultMain works, this code is not reached@@ -54,7 +63,7 @@  versionMajor, versionMinor, versionRevision :: Int versionMajor    = 3-versionMinor    = 1+versionMinor    = 2 versionRevision = 1  giveItTime :: IO ()@@ -114,30 +123,43 @@       -- , testCase "gamma ramp"                 $ test_glfwGamma_ramp p'mon       ]     , testGroup "Window handling"-      [ testCase "glfwDefaultWindowHints"   test_glfwDefaultWindowHints-      , testCase "window close flag"      $ test_window_close_flag p'win-      , testCase "glfwSetWindowTitle"     $ test_glfwSetWindowTitle p'win-      , testCase "window pos"             $ test_window_pos p'win-      , testCase "window size"            $ test_window_size p'win-      , testCase "glfwGetFramebufferSize" $ test_glfwGetFramebufferSize p'win-      , testCase "iconification"          $ test_iconification p'win-      -- , testCase "show/hide"              $ test_show_hide p'win-      , testCase "glfwGetWindowMonitor"   $ test_glfwGetWindowMonitor p'win p'mon-      , testCase "cursor pos"             $ test_cursor_pos p'win-      , testCase "glfwGetWindowAttrib"    $ test_glfwGetWindowAttrib p'win-      , testCase "glfwPollEvents"           test_glfwPollEvents-      , testCase "glfwWaitEvents"           test_glfwWaitEvents+      [ testCase "glfwDefaultWindowHints"       test_glfwDefaultWindowHints+      , testCase "glfwGetWindowAttrib"        $ test_glfwGetWindowAttrib p'win+      , testCase "window close flag"          $ test_window_close_flag p'win+      , testCase "glfwSetWindowTitle"         $ test_glfwSetWindowTitle p'win+      , testCase "window pos"                 $ test_window_pos p'win+      , testCase "window size"                $ test_window_size p'win+      , testCase "glfwGetWindowFrameSize"     $ test_glfwGetWindowFrameSize p'win+      , testCase "glfwGetFramebufferSize"     $ test_glfwGetFramebufferSize p'win+      , testCase "iconification"              $ test_iconification p'win+      -- , testCase "show/hide"                  $ test_show_hide p'win+      , testCase "glfwGetWindowMonitor"       $ test_glfwGetWindowMonitor p'win p'mon+      , testCase "glfwSetWindowMonitor"       $ test_glfwSetWindowMonitor p'win p'mon+      , testCase "glfwSetWindowIcon"          $ test_glfwSetWindowIcon p'win+      , testCase "glfwMaximizeWindow"         $ test_glfwMaximizeWindow p'win+      , testCase "glfwSetWindowSizeLimits"    $ test_glfwSetWindowSizeLimits p'win+      , testCase "glfwSetWindowAspectRatio"   $ test_glfwSetWindowAspectRatio p'win+      , testCase "glfwFocusWindow"            $ test_glfwFocusWindow p'win+      , testCase "cursor pos"                 $ test_cursor_pos p'win+      , testCase "glfwPollEvents"               test_glfwPollEvents+      , testCase "glfwWaitEvents"               test_glfwWaitEvents+      , testCase "glfwWaitEventsTimeout"        test_glfwWaitEventsTimeout       ]     , testGroup "Input handling"       [ testCase "glfwJoystickPresent"    test_glfwJoystickPresent       , testCase "glfwGetJoystickAxes"    test_glfwGetJoystickAxes       , testCase "glfwGetJoystickButtons" test_glfwGetJoystickButtons       , testCase "glfwGetJoystickName"    test_glfwGetJoystickName+      , testCase "glfwGetKeyName"         test_glfwGetKeyName       ]     , testGroup "Time"       [ testCase "glfwGetTime" test_glfwGetTime       , testCase "glfwSetTime" test_glfwSetTime       ]+    , testGroup "Timers"+      [ testCase "glfwGetTimerValue"         test_glfwGetTimerValue+      , testCase "glfwSetTimerFrequency"     test_glfwGetTimerFrequency+      ]     , testGroup "Context"       [ testCase "glfwGetCurrentContext"  $ test_glfwGetCurrentContext p'win       , testCase "glfwSwapBuffers"        $ test_glfwSwapBuffers p'win@@ -147,6 +169,13 @@     , testGroup "Clipboard"       [ testCase "clipboard" $ test_clipboard p'win       ]+    , testGroup "Vulkan"+      [ testCase "glfwVulkanSupported"                          test_glfwVulkanSupported+      , testCase "glfwGetRequiredInstanceExtensions"            test_glfwGetRequiredInstanceExtensions+      , testCase "glfwGetInstanceProcAddress"                   test_glfwGetInstanceProcAddress+      , testCase "glfwGetPhysicalDevicePresentationSupport"     test_glfwGetPhysicalDevicePresentationSupport+      , testCase "glfwCreateWindowSurface"                    $ test_glfwCreateWindowSurface p'win+      ]     ]  --------------------------------------------------------------------------------@@ -275,15 +304,15 @@ test_window_close_flag :: Ptr C'GLFWwindow -> IO () test_window_close_flag p'win = do     r0 <- c'glfwWindowShouldClose p'win-    r0 @?= c'GL_FALSE+    r0 @?= c'GLFW_FALSE -    c'glfwSetWindowShouldClose p'win c'GL_TRUE+    c'glfwSetWindowShouldClose p'win c'GLFW_TRUE     r1 <- c'glfwWindowShouldClose p'win-    r1 @?= c'GL_TRUE+    r1 @?= c'GLFW_TRUE -    c'glfwSetWindowShouldClose p'win c'GL_FALSE+    c'glfwSetWindowShouldClose p'win c'GLFW_FALSE     r2 <- c'glfwWindowShouldClose p'win-    r2 @?= c'GL_FALSE+    r2 @?= c'GLFW_FALSE  test_glfwSetWindowTitle :: Ptr C'GLFWwindow -> IO () test_glfwSetWindowTitle p'win =@@ -309,6 +338,7 @@     setGet :: Int -> Int -> IO (Int, Int, Int, Int)     setGet x0 y0 = do         c'glfwSetWindowPos p'win (fromIntegral x0) (fromIntegral y0)+        c'glfwSwapBuffers p'win         giveItTime         alloca $ \p'x1 ->           alloca $ \p'y1 -> do@@ -320,8 +350,8 @@  test_window_size :: Ptr C'GLFWwindow -> IO () test_window_size p'win = do-    let w = 17-        h = 37+    let w = 177+        h = 372     c'glfwSetWindowSize p'win w h     giveItTime     alloca $ \p'w' ->@@ -332,6 +362,15 @@           w' @?= w           h' @?= h +-- Really all we can say here is that we likely have a title bar, so just check+-- that the 'frame' around the top edge is > 0.+test_glfwGetWindowFrameSize :: Ptr C'GLFWwindow -> IO ()+test_glfwGetWindowFrameSize p'win =+    alloca $ \p'win_frame_top -> do+        c'glfwGetWindowFrameSize p'win nullPtr p'win_frame_top nullPtr nullPtr+        top <- peek p'win_frame_top+        assertBool "Window has no frame width up top!" $ top > 0+ test_glfwGetFramebufferSize :: Ptr C'GLFWwindow -> IO () test_glfwGetFramebufferSize p'win =     alloca $ \p'w  ->@@ -344,88 +383,146 @@         h  <- peek p'h         fw <- peek p'fw         fh <- peek p'fh-        fw @?= w-        fh @?= h+        ((fw `mod` w) == 0) @? "Framebuffer width multiple of window's"+        ((fh `mod` h) == 0) @? "Framebuffer height multiple of window's"  test_iconification :: Ptr C'GLFWwindow -> IO () test_iconification p'win = do+    c'glfwShowWindow p'win     r0 <- c'glfwGetWindowAttrib p'win c'GLFW_ICONIFIED-    r0 @?= c'GL_FALSE+    r0 @?= c'GLFW_FALSE      c'glfwIconifyWindow p'win     giveItTime      r1 <- c'glfwGetWindowAttrib p'win c'GLFW_ICONIFIED-    r1 @?= c'GL_TRUE+    r1 @?= c'GLFW_TRUE      c'glfwRestoreWindow p'win+    c'glfwHideWindow p'win  -- test_show_hide :: Ptr C'GLFWwindow -> IO () -- test_show_hide p'win = do --     v0 <- c'glfwGetWindowAttrib p'win c'GLFW_VISIBLE---     v0 @?= c'GL_FALSE+--     v0 @?= c'GLFW_FALSE  --     c'glfwShowWindow p'win --     giveItTime --     v1 <- c'glfwGetWindowAttrib p'win c'GLFW_VISIBLE---     v1 @?= c'GL_TRUE+--     v1 @?= c'GLFW_TRUE  --     c'glfwHideWindow p'win --     giveItTime --     v2 <- c'glfwGetWindowAttrib p'win c'GLFW_VISIBLE---     v2 @?= c'GL_FALSE+--     v2 @?= c'GLFW_FALSE  test_glfwGetWindowMonitor :: Ptr C'GLFWwindow -> Ptr C'GLFWmonitor -> IO () test_glfwGetWindowMonitor p'win _ = do     p'mon <- c'glfwGetWindowMonitor p'win     p'mon @?= nullPtr +test_glfwSetWindowMonitor :: Ptr C'GLFWwindow -> Ptr C'GLFWmonitor -> IO ()+test_glfwSetWindowMonitor p'win _ = do+    c'glfwSetWindowMonitor p'win nullPtr 0 0 100 100 60++test_glfwSetWindowIcon :: Ptr C'GLFWwindow -> IO ()+test_glfwSetWindowIcon p'win = do+    c'glfwSetWindowIcon p'win 0 nullPtr++test_glfwSetWindowSizeLimits :: Ptr C'GLFWwindow -> IO ()+test_glfwSetWindowSizeLimits p'win = do+    c'glfwSetWindowSizeLimits p'win 640 480 1024 768++test_glfwSetWindowAspectRatio :: Ptr C'GLFWwindow -> IO ()+test_glfwSetWindowAspectRatio p'win = do+    c'glfwSetWindowAspectRatio p'win c'GLFW_DONT_CARE c'GLFW_DONT_CARE++test_glfwFocusWindow :: Ptr C'GLFWwindow -> IO ()+test_glfwFocusWindow = c'glfwFocusWindow++-- NOTE: This test seems to fail in X11. This might be due to the asynchronous+-- nature of focus events in X. We may be able to fix it by waiting for the focus+-- event before setting the cursor position. test_cursor_pos :: Ptr C'GLFWwindow -> IO () test_cursor_pos p'win =     alloca $ \p'w   ->     alloca $ \p'h   ->     alloca $ \p'cx' ->     alloca $ \p'cy' -> do+        c'glfwShowWindow p'win         c'glfwGetWindowSize p'win p'w p'h         w <- peek p'w         h <- peek p'h-        let cx = fromIntegral w / 2-            cy = fromIntegral h / 2++        -- Make sure we use integral coordinates here so that we don't run into+        -- platform-dependent differences.+        let cx :: CDouble+            cy :: CDouble+            (cx, cy) = (fromIntegral $ w `div` 2, fromIntegral $ h `div` 2)++        -- !HACK! Poll events seems to be necessary on OS X,+        -- before /and/ after glfwSetCursorPos, otherwise, the+        -- windowing system likely never receives the cursor update. This is+        -- reflected in the C version of GLFW as well, we just call it here in+        -- order to have a more robust test.++        c'glfwPollEvents+         c'glfwSetCursorPos p'win cx cy-        giveItTime++        c'glfwPollEvents -- !HACK! see comment above+         c'glfwGetCursorPos p'win p'cx' p'cy'         cx' <- peek p'cx'         cy' <- peek p'cy'         cx' @?= cx         cy' @?= cy+        c'glfwHideWindow p'win  test_glfwGetWindowAttrib :: Ptr C'GLFWwindow -> IO () test_glfwGetWindowAttrib p'win = do     let pairs =-          [ ( c'GLFW_FOCUSED,    c'GL_FALSE        )-          , ( c'GLFW_ICONIFIED,  c'GL_FALSE        )-          , ( c'GLFW_RESIZABLE,  c'GL_TRUE         )-          , ( c'GLFW_DECORATED,  c'GL_TRUE         )+          [ ( c'GLFW_FOCUSED,    c'GLFW_FALSE        )+          , ( c'GLFW_ICONIFIED,  c'GLFW_FALSE        )+          , ( c'GLFW_RESIZABLE,  c'GLFW_TRUE         )+          , ( c'GLFW_DECORATED,  c'GLFW_TRUE         )           , ( c'GLFW_CLIENT_API, c'GLFW_OPENGL_API )           ]     rs <- mapM (c'glfwGetWindowAttrib p'win . fst) pairs     rs @?= map snd pairs +test_glfwMaximizeWindow :: Ptr C'GLFWwindow -> IO ()+test_glfwMaximizeWindow p'win = do+    c'glfwShowWindow p'win+    startsMaximized <- c'glfwGetWindowAttrib p'win c'GLFW_MAXIMIZED+    startsMaximized @?= c'GLFW_FALSE++    c'glfwMaximizeWindow p'win+    giveItTime++    isMaximized <- c'glfwGetWindowAttrib p'win c'GLFW_MAXIMIZED+    isMaximized @?= c'GLFW_TRUE+    c'glfwHideWindow p'win+ test_glfwPollEvents :: IO () test_glfwPollEvents =     c'glfwPollEvents  test_glfwWaitEvents :: IO ()-test_glfwWaitEvents =-    c'glfwWaitEvents+test_glfwWaitEvents = c'glfwPostEmptyEvent >> c'glfwWaitEvents +test_glfwWaitEventsTimeout :: IO ()+test_glfwWaitEventsTimeout =+    -- to not slow down the test too much we set the timeout to 0.001 second :+    c'glfwWaitEventsTimeout 0.001+ --------------------------------------------------------------------------------  test_glfwJoystickPresent :: IO () test_glfwJoystickPresent = do     _ <- c'glfwJoystickPresent c'GLFW_JOYSTICK_1     r <- c'glfwJoystickPresent c'GLFW_JOYSTICK_16-    r @?= c'GL_FALSE+    r @?= c'GLFW_FALSE  test_glfwGetJoystickAxes :: IO () test_glfwGetJoystickAxes =@@ -461,6 +558,14 @@             name <- peekCString p'name             assertBool "" $ not $ null name +test_glfwGetKeyName :: IO ()+test_glfwGetKeyName =+    forM_ [c'GLFW_KEY_SLASH, c'GLFW_KEY_PERIOD] $ \k -> do+        p'name <- c'glfwGetKeyName k 0+        when (p'name /= nullPtr) $ do+            name <- peekCString p'name+            assertBool "" $ not $ null name+ --------------------------------------------------------------------------------  test_glfwGetTime :: IO ()@@ -477,6 +582,18 @@  -------------------------------------------------------------------------------- +test_glfwGetTimerValue :: IO ()+test_glfwGetTimerValue = do+    val <- c'glfwGetTimerValue+    assertBool "" $ val > 0++test_glfwGetTimerFrequency :: IO ()+test_glfwGetTimerFrequency = do+    freq <- c'glfwGetTimerFrequency+    assertBool "" $ freq > 0++--------------------------------------------------------------------------------+ test_glfwGetCurrentContext :: Ptr C'GLFWwindow -> IO () test_glfwGetCurrentContext p'win = do     p'win' <- c'glfwGetCurrentContext@@ -493,8 +610,8 @@ test_glfwExtensionSupported :: IO () test_glfwExtensionSupported = do     let pairs =-          [ ( "GL_ARB_multisample", c'GL_TRUE  )-          , ( "bogus",              c'GL_FALSE )+          [ ( "GL_ARB_multisample", c'GLFW_TRUE  )+          , ( "bogus",              c'GLFW_FALSE )           ]     rs <- forM (map fst pairs) $ \ext ->       withCString ext c'glfwExtensionSupported@@ -514,11 +631,67 @@     setGet s = do         withCString s $ \p's ->           c'glfwSetClipboardString p'win p's+        threadDelay 100000  -- Give it a little time         p's' <- c'glfwGetClipboardString p'win         if p's' == nullPtr           then return ""           else peekCString p's'  --------------------------------------------------------------------------------++test_glfwVulkanSupported :: IO ()+test_glfwVulkanSupported =+    -- Just test that it doesn't error. If it does, then we have a problem, but+    -- some platforms (like OS X) don't actually support vulkan.+    c'glfwVulkanSupported >> return ()++test_glfwGetRequiredInstanceExtensions :: IO ()+test_glfwGetRequiredInstanceExtensions = do+    support <- c'glfwVulkanSupported+    if (support == 1)+        then alloca $ \p'count ->+            c'glfwGetRequiredInstanceExtensions p'count >> return ()+        else return ()++test_glfwGetInstanceProcAddress :: IO ()+test_glfwGetInstanceProcAddress = do+    support <- c'glfwVulkanSupported+    if support == 1+    then do+        shouldBeNull <- withCString "notafunction" $+                        \s -> c'glfwGetInstanceProcAddress nullPtr s+        shouldBeNull @?= nullFunPtr+        assertBool "Function pointer is defined!" $+          p'glfwGetInstanceProcAddress /= nullFunPtr+    else return ()++test_glfwGetPhysicalDevicePresentationSupport :: IO ()+test_glfwGetPhysicalDevicePresentationSupport = do+    -- We don't really have the proper types to test this function+    support <- c'glfwVulkanSupported+    if support == 1+    then do+        shouldBeFalse <-+          c'glfwGetPhysicalDevicePresentationSupport nullPtr nullPtr 0+        shouldBeFalse @?= c'GLFW_FALSE+        assertBool "Function pointer is defined!" $+          p'glfwGetPhysicalDevicePresentationSupport /= nullFunPtr+    else return ()++test_glfwCreateWindowSurface :: Ptr C'GLFWwindow -> IO ()+test_glfwCreateWindowSurface p'win = do+    -- We don't really have the proper types to test this function+    support <- c'glfwVulkanSupported+    if support == 1+    then do+        alloca $ \p'surface -> do+          let resPtr = p'surface :: Ptr ()+          shouldNotBeSuccessful <-+            c'glfwCreateWindowSurface nullPtr p'win nullPtr resPtr+          assertBool "c'glfwCreateSurface was successful??" $+            shouldNotBeSuccessful /= 0+        assertBool "Function pointer is defined!" $+          p'glfwCreateWindowSurface /= nullFunPtr+    else return ()  {-# ANN module "HLint: ignore Use camelCase" #-}
bindings-GLFW.cabal view
@@ -1,5 +1,5 @@ name:         bindings-GLFW-version:      3.1.2.4+version:      3.2.1.0 category:     Graphics  author:       Brian Lewis <brian@lorf.org>@@ -126,6 +126,7 @@       glfw/src/input.c       glfw/src/monitor.c       glfw/src/window.c+      glfw/src/vulkan.c      cc-options: -D_GLFW_USE_CONFIG_H @@ -133,25 +134,27 @@       include-dirs:         glfw/include/os/unix-like       c-sources:+        glfw/src/glx_context.c+        glfw/src/egl_context.c         glfw/src/xkb_unicode.c         glfw/src/linux_joystick.c         glfw/src/posix_time.c         glfw/src/posix_tls.c       if flag(X)+        cc-options: -DBINDINGS_GLFW_USE_X11         c-sources:-          glfw/src/glx_context.c           glfw/src/x11_init.c           glfw/src/x11_monitor.c           glfw/src/x11_window.c       if flag(Wayland)+        cc-options: -DBINDINGS_GLFW_USE_WAYLAND         c-sources:-          glfw/src/egl_context.c           glfw/src/wl_init.c           glfw/src/wl_monitor.c           glfw/src/wl_window.c       if flag(Mir)+        cc-options: -DBINDINGS_GLFW_USE_MIR         c-sources:-          glfw/src/egl_context.c           glfw/src/mir_init.c           glfw/src/mir_monitor.c           glfw/src/mir_window.c@@ -170,10 +173,10 @@       include-dirs:          glfw/include/os/darwin       c-sources:-         glfw/src/mach_time.c+         glfw/src/cocoa_time.c          glfw/src/posix_tls.c          glfw/src/cocoa_init.m-         glfw/src/iokit_joystick.m+         glfw/src/cocoa_joystick.m          glfw/src/cocoa_monitor.m          glfw/src/cocoa_window.m          glfw/src/nsgl_context.m@@ -189,8 +192,9 @@       include-dirs:         glfw/include/os/windows       c-sources:+        glfw/src/egl_context.c         glfw/src/win32_init.c-        glfw/src/winmm_joystick.c+        glfw/src/win32_joystick.c         glfw/src/win32_monitor.c         glfw/src/win32_time.c         glfw/src/win32_window.c@@ -202,7 +206,6 @@    if flag(ExposeNative)     cc-options: -DExposeNative- --------------------------------------------------------------------------------  test-suite main
glfw/include/GLFW/glfw3.h view
@@ -1,3335 +1,4224 @@ /*************************************************************************- * GLFW 3.1 - www.glfw.org- * A library for OpenGL, window and input- *------------------------------------------------------------------------- * Copyright (c) 2002-2006 Marcus Geelnard- * Copyright (c) 2006-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.- *- *************************************************************************/--#ifndef _glfw3_h_-#define _glfw3_h_--#ifdef __cplusplus-extern "C" {-#endif---/*************************************************************************- * Doxygen documentation- *************************************************************************/--/*! @defgroup context Context handling- *- *  This is the reference documentation for context related functions.  For more- *  information, see the @ref context.- */-/*! @defgroup init Initialization, version and errors- *- *  This is the reference documentation for initialization and termination of- *  the library, version management and error handling.  For more information,- *  see the @ref intro.- */-/*! @defgroup input Input handling- *- *  This is the reference documentation for input related functions and types.- *  For more information, see the @ref input.- */-/*! @defgroup monitor Monitor handling- *- *  This is the reference documentation for monitor related functions and types.- *  For more information, see the @ref monitor.- */-/*! @defgroup window Window handling- *- *  This is the reference documentation for window related functions and types,- *  including creation, deletion and event polling.  For more information, see- *  the @ref window.- */---/*************************************************************************- * Global definitions- *************************************************************************/--/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */--/* Please report any problems that you find with your compiler, which may- * be solved in this section! There are several compilers that I have not- * been able to test this file with yet.- *- * First: If we are we on Windows, we want a single define for it (_WIN32)- * (Note: For Cygwin the compiler flag -mwin32 should be used, but to- * make sure that things run smoothly for Cygwin users, we add __CYGWIN__- * to the list of "valid Win32 identifiers", which removes the need for- * -mwin32)- */-#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__))- #define _WIN32-#endif /* _WIN32 */--/* In order for extension support to be portable, we need to define an- * OpenGL function call method. We use the keyword APIENTRY, which is- * defined for Win32. (Note: Windows also needs this for <GL/gl.h>)- */-#ifndef APIENTRY- #ifdef _WIN32-  #define APIENTRY __stdcall- #else-  #define APIENTRY- #endif-#endif /* APIENTRY */--/* The following three defines are here solely to make some Windows-based- * <GL/gl.h> files happy. Theoretically we could include <windows.h>, but- * it has the major drawback of severely polluting our namespace.- */--/* Under Windows, we need WINGDIAPI defined */-#if !defined(WINGDIAPI) && defined(_WIN32)- #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)-  /* Microsoft Visual C++, Borland C++ Builder and Pelles C */-  #define WINGDIAPI __declspec(dllimport)- #elif defined(__LCC__)-  /* LCC-Win32 */-  #define WINGDIAPI __stdcall- #else-  /* Others (e.g. MinGW, Cygwin) */-  #define WINGDIAPI extern- #endif- #define GLFW_WINGDIAPI_DEFINED-#endif /* WINGDIAPI */--/* Some <GL/glu.h> files also need CALLBACK defined */-#if !defined(CALLBACK) && defined(_WIN32)- #if defined(_MSC_VER)-  /* Microsoft Visual C++ */-  #if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)-   #define CALLBACK __stdcall-  #else-   #define CALLBACK-  #endif- #else-  /* Other Windows compilers */-  #define CALLBACK __stdcall- #endif- #define GLFW_CALLBACK_DEFINED-#endif /* CALLBACK */--/* Most GL/glu.h variants on Windows need wchar_t- * OpenGL/gl.h blocks the definition of ptrdiff_t by glext.h on OS X */-#if !defined(GLFW_INCLUDE_NONE)- #include <stddef.h>-#endif--/* Include the chosen client API headers.- */-#if defined(__APPLE_CC__)- #if defined(GLFW_INCLUDE_GLCOREARB)-  #include <OpenGL/gl3.h>-  #if defined(GLFW_INCLUDE_GLEXT)-   #include <OpenGL/gl3ext.h>-  #endif- #elif !defined(GLFW_INCLUDE_NONE)-  #if !defined(GLFW_INCLUDE_GLEXT)-   #define GL_GLEXT_LEGACY-  #endif-  #include <OpenGL/gl.h>- #endif- #if defined(GLFW_INCLUDE_GLU)-  #include <OpenGL/glu.h>- #endif-#else- #if defined(GLFW_INCLUDE_GLCOREARB)-  #include <GL/glcorearb.h>- #elif defined(GLFW_INCLUDE_ES1)-  #include <GLES/gl.h>-  #if defined(GLFW_INCLUDE_GLEXT)-   #include <GLES/glext.h>-  #endif- #elif defined(GLFW_INCLUDE_ES2)-  #include <GLES2/gl2.h>-  #if defined(GLFW_INCLUDE_GLEXT)-   #include <GLES2/gl2ext.h>-  #endif- #elif defined(GLFW_INCLUDE_ES3)-  #include <GLES3/gl3.h>-  #if defined(GLFW_INCLUDE_GLEXT)-   #include <GLES3/gl2ext.h>-  #endif- #elif defined(GLFW_INCLUDE_ES31)-  #include <GLES3/gl31.h>-  #if defined(GLFW_INCLUDE_GLEXT)-   #include <GLES3/gl2ext.h>-  #endif- #elif !defined(GLFW_INCLUDE_NONE)-  #include <GL/gl.h>-  #if defined(GLFW_INCLUDE_GLEXT)-   #include <GL/glext.h>-  #endif- #endif- #if defined(GLFW_INCLUDE_GLU)-  #include <GL/glu.h>- #endif-#endif--#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)- /* GLFW_DLL must be defined by applications that are linking against the DLL-  * version of the GLFW library.  _GLFW_BUILD_DLL is defined by the GLFW-  * configuration header when compiling the DLL version of the library.-  */- #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"-#endif--/* GLFWAPI is used to declare public API functions for export- * from the DLL / shared library / dynamic library.- */-#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)- /* We are building GLFW as a Win32 DLL */- #define GLFWAPI __declspec(dllexport)-#elif defined(_WIN32) && defined(GLFW_DLL)- /* We are calling GLFW as a Win32 DLL */- #if defined(__LCC__)-  #define GLFWAPI extern- #else-  #define GLFWAPI __declspec(dllimport)- #endif-#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)- /* We are building GLFW as a shared / dynamic library */- #define GLFWAPI __attribute__((visibility("default")))-#else- /* We are building or calling GLFW as a static library */- #define GLFWAPI-#endif--/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */---/*************************************************************************- * GLFW API tokens- *************************************************************************/--/*! @name GLFW version macros- *  @{ */-/*! @brief The major version number of the GLFW library.- *- *  This is incremented when the API is changed in non-compatible ways.- *  @ingroup init- */-#define GLFW_VERSION_MAJOR          3-/*! @brief The minor version number of the GLFW library.- *- *  This is incremented when features are added to the API but it remains- *  backward-compatible.- *  @ingroup init- */-#define GLFW_VERSION_MINOR          1-/*! @brief The revision number of the GLFW library.- *- *  This is incremented when a bug fix release is made that does not contain any- *  API changes.- *  @ingroup init- */-#define GLFW_VERSION_REVISION       1-/*! @} */--/*! @name Key and button actions- *  @{ */-/*! @brief The key or mouse button was released.- *- *  The key or mouse button was released.- *- *  @ingroup input- */-#define GLFW_RELEASE                0-/*! @brief The key or mouse button was pressed.- *- *  The key or mouse button was pressed.- *- *  @ingroup input- */-#define GLFW_PRESS                  1-/*! @brief The key was held down until it repeated.- *- *  The key was held down until it repeated.- *- *  @ingroup input- */-#define GLFW_REPEAT                 2-/*! @} */--/*! @defgroup keys Keyboard keys- *- *  See [key input](@ref input_key) for how these are used.- *- *  These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),- *  but re-arranged to map to 7-bit ASCII for printable keys (function keys are- *  put in the 256+ range).- *- *  The naming of the key codes follow these rules:- *   - The US keyboard layout is used- *   - Names of printable alpha-numeric characters are used (e.g. "A", "R",- *     "3", etc.)- *   - For non-alphanumeric characters, Unicode:ish names are used (e.g.- *     "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not- *     correspond to the Unicode standard (usually for brevity)- *   - Keys that lack a clear US mapping are named "WORLD_x"- *   - For non-printable keys, custom names are used (e.g. "F4",- *     "BACKSPACE", etc.)- *- *  @ingroup input- *  @{- */--/* The unknown key */-#define GLFW_KEY_UNKNOWN            -1--/* Printable keys */-#define GLFW_KEY_SPACE              32-#define GLFW_KEY_APOSTROPHE         39  /* ' */-#define GLFW_KEY_COMMA              44  /* , */-#define GLFW_KEY_MINUS              45  /* - */-#define GLFW_KEY_PERIOD             46  /* . */-#define GLFW_KEY_SLASH              47  /* / */-#define GLFW_KEY_0                  48-#define GLFW_KEY_1                  49-#define GLFW_KEY_2                  50-#define GLFW_KEY_3                  51-#define GLFW_KEY_4                  52-#define GLFW_KEY_5                  53-#define GLFW_KEY_6                  54-#define GLFW_KEY_7                  55-#define GLFW_KEY_8                  56-#define GLFW_KEY_9                  57-#define GLFW_KEY_SEMICOLON          59  /* ; */-#define GLFW_KEY_EQUAL              61  /* = */-#define GLFW_KEY_A                  65-#define GLFW_KEY_B                  66-#define GLFW_KEY_C                  67-#define GLFW_KEY_D                  68-#define GLFW_KEY_E                  69-#define GLFW_KEY_F                  70-#define GLFW_KEY_G                  71-#define GLFW_KEY_H                  72-#define GLFW_KEY_I                  73-#define GLFW_KEY_J                  74-#define GLFW_KEY_K                  75-#define GLFW_KEY_L                  76-#define GLFW_KEY_M                  77-#define GLFW_KEY_N                  78-#define GLFW_KEY_O                  79-#define GLFW_KEY_P                  80-#define GLFW_KEY_Q                  81-#define GLFW_KEY_R                  82-#define GLFW_KEY_S                  83-#define GLFW_KEY_T                  84-#define GLFW_KEY_U                  85-#define GLFW_KEY_V                  86-#define GLFW_KEY_W                  87-#define GLFW_KEY_X                  88-#define GLFW_KEY_Y                  89-#define GLFW_KEY_Z                  90-#define GLFW_KEY_LEFT_BRACKET       91  /* [ */-#define GLFW_KEY_BACKSLASH          92  /* \ */-#define GLFW_KEY_RIGHT_BRACKET      93  /* ] */-#define GLFW_KEY_GRAVE_ACCENT       96  /* ` */-#define GLFW_KEY_WORLD_1            161 /* non-US #1 */-#define GLFW_KEY_WORLD_2            162 /* non-US #2 */--/* Function keys */-#define GLFW_KEY_ESCAPE             256-#define GLFW_KEY_ENTER              257-#define GLFW_KEY_TAB                258-#define GLFW_KEY_BACKSPACE          259-#define GLFW_KEY_INSERT             260-#define GLFW_KEY_DELETE             261-#define GLFW_KEY_RIGHT              262-#define GLFW_KEY_LEFT               263-#define GLFW_KEY_DOWN               264-#define GLFW_KEY_UP                 265-#define GLFW_KEY_PAGE_UP            266-#define GLFW_KEY_PAGE_DOWN          267-#define GLFW_KEY_HOME               268-#define GLFW_KEY_END                269-#define GLFW_KEY_CAPS_LOCK          280-#define GLFW_KEY_SCROLL_LOCK        281-#define GLFW_KEY_NUM_LOCK           282-#define GLFW_KEY_PRINT_SCREEN       283-#define GLFW_KEY_PAUSE              284-#define GLFW_KEY_F1                 290-#define GLFW_KEY_F2                 291-#define GLFW_KEY_F3                 292-#define GLFW_KEY_F4                 293-#define GLFW_KEY_F5                 294-#define GLFW_KEY_F6                 295-#define GLFW_KEY_F7                 296-#define GLFW_KEY_F8                 297-#define GLFW_KEY_F9                 298-#define GLFW_KEY_F10                299-#define GLFW_KEY_F11                300-#define GLFW_KEY_F12                301-#define GLFW_KEY_F13                302-#define GLFW_KEY_F14                303-#define GLFW_KEY_F15                304-#define GLFW_KEY_F16                305-#define GLFW_KEY_F17                306-#define GLFW_KEY_F18                307-#define GLFW_KEY_F19                308-#define GLFW_KEY_F20                309-#define GLFW_KEY_F21                310-#define GLFW_KEY_F22                311-#define GLFW_KEY_F23                312-#define GLFW_KEY_F24                313-#define GLFW_KEY_F25                314-#define GLFW_KEY_KP_0               320-#define GLFW_KEY_KP_1               321-#define GLFW_KEY_KP_2               322-#define GLFW_KEY_KP_3               323-#define GLFW_KEY_KP_4               324-#define GLFW_KEY_KP_5               325-#define GLFW_KEY_KP_6               326-#define GLFW_KEY_KP_7               327-#define GLFW_KEY_KP_8               328-#define GLFW_KEY_KP_9               329-#define GLFW_KEY_KP_DECIMAL         330-#define GLFW_KEY_KP_DIVIDE          331-#define GLFW_KEY_KP_MULTIPLY        332-#define GLFW_KEY_KP_SUBTRACT        333-#define GLFW_KEY_KP_ADD             334-#define GLFW_KEY_KP_ENTER           335-#define GLFW_KEY_KP_EQUAL           336-#define GLFW_KEY_LEFT_SHIFT         340-#define GLFW_KEY_LEFT_CONTROL       341-#define GLFW_KEY_LEFT_ALT           342-#define GLFW_KEY_LEFT_SUPER         343-#define GLFW_KEY_RIGHT_SHIFT        344-#define GLFW_KEY_RIGHT_CONTROL      345-#define GLFW_KEY_RIGHT_ALT          346-#define GLFW_KEY_RIGHT_SUPER        347-#define GLFW_KEY_MENU               348-#define GLFW_KEY_LAST               GLFW_KEY_MENU--/*! @} */--/*! @defgroup mods Modifier key flags- *- *  See [key input](@ref input_key) for how these are used.- *- *  @ingroup input- *  @{ */--/*! @brief If this bit is set one or more Shift keys were held down.- */-#define GLFW_MOD_SHIFT           0x0001-/*! @brief If this bit is set one or more Control keys were held down.- */-#define GLFW_MOD_CONTROL         0x0002-/*! @brief If this bit is set one or more Alt keys were held down.- */-#define GLFW_MOD_ALT             0x0004-/*! @brief If this bit is set one or more Super keys were held down.- */-#define GLFW_MOD_SUPER           0x0008--/*! @} */--/*! @defgroup buttons Mouse buttons- *- *  See [mouse button input](@ref input_mouse_button) for how these are used.- *- *  @ingroup input- *  @{ */-#define GLFW_MOUSE_BUTTON_1         0-#define GLFW_MOUSE_BUTTON_2         1-#define GLFW_MOUSE_BUTTON_3         2-#define GLFW_MOUSE_BUTTON_4         3-#define GLFW_MOUSE_BUTTON_5         4-#define GLFW_MOUSE_BUTTON_6         5-#define GLFW_MOUSE_BUTTON_7         6-#define GLFW_MOUSE_BUTTON_8         7-#define GLFW_MOUSE_BUTTON_LAST      GLFW_MOUSE_BUTTON_8-#define GLFW_MOUSE_BUTTON_LEFT      GLFW_MOUSE_BUTTON_1-#define GLFW_MOUSE_BUTTON_RIGHT     GLFW_MOUSE_BUTTON_2-#define GLFW_MOUSE_BUTTON_MIDDLE    GLFW_MOUSE_BUTTON_3-/*! @} */--/*! @defgroup joysticks Joysticks- *- *  See [joystick input](@ref joystick) for how these are used.- *- *  @ingroup input- *  @{ */-#define GLFW_JOYSTICK_1             0-#define GLFW_JOYSTICK_2             1-#define GLFW_JOYSTICK_3             2-#define GLFW_JOYSTICK_4             3-#define GLFW_JOYSTICK_5             4-#define GLFW_JOYSTICK_6             5-#define GLFW_JOYSTICK_7             6-#define GLFW_JOYSTICK_8             7-#define GLFW_JOYSTICK_9             8-#define GLFW_JOYSTICK_10            9-#define GLFW_JOYSTICK_11            10-#define GLFW_JOYSTICK_12            11-#define GLFW_JOYSTICK_13            12-#define GLFW_JOYSTICK_14            13-#define GLFW_JOYSTICK_15            14-#define GLFW_JOYSTICK_16            15-#define GLFW_JOYSTICK_LAST          GLFW_JOYSTICK_16-/*! @} */--/*! @defgroup errors Error codes- *- *  See [error handling](@ref error_handling) for how these are used.- *- *  @ingroup init- *  @{ */-/*! @brief GLFW has not been initialized.- *- *  This occurs if a GLFW function was called that may not be called unless the- *  library is [initialized](@ref intro_init).- *- *  @par Analysis- *  Application programmer error.  Initialize GLFW before calling any function- *  that requires initialization.- */-#define GLFW_NOT_INITIALIZED        0x00010001-/*! @brief No context is current for this thread.- *- *  This occurs if a GLFW function was called that needs and operates on the- *  current OpenGL or OpenGL ES context but no context is current on the calling- *  thread.  One such function is @ref glfwSwapInterval.- *- *  @par Analysis- *  Application programmer error.  Ensure a context is current before calling- *  functions that require a current context.- */-#define GLFW_NO_CURRENT_CONTEXT     0x00010002-/*! @brief One of the arguments to the function was an invalid enum value.- *- *  One of the arguments to the function was an invalid enum value, for example- *  requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref- *  glfwGetWindowAttrib.- *- *  @par Analysis- *  Application programmer error.  Fix the offending call.- */-#define GLFW_INVALID_ENUM           0x00010003-/*! @brief One of the arguments to the function was an invalid value.- *- *  One of the arguments to the function was an invalid value, for example- *  requesting a non-existent OpenGL or OpenGL ES version like 2.7.- *- *  Requesting a valid but unavailable OpenGL or OpenGL ES version will instead- *  result in a @ref GLFW_VERSION_UNAVAILABLE error.- *- *  @par Analysis- *  Application programmer error.  Fix the offending call.- */-#define GLFW_INVALID_VALUE          0x00010004-/*! @brief A memory allocation failed.- *- *  A memory allocation failed.- *- *  @par Analysis- *  A bug in GLFW or the underlying operating system.  Report the bug to our- *  [issue tracker](https://github.com/glfw/glfw/issues).- */-#define GLFW_OUT_OF_MEMORY          0x00010005-/*! @brief GLFW could not find support for the requested client API on the- *  system.- *- *  GLFW could not find support for the requested client API on the system.- *- *  @par Analysis- *  The installed graphics driver does not support the requested client API, or- *  does not support it via the chosen context creation backend.  Below are- *  a few examples.- *- *  @par- *  Some pre-installed Windows graphics drivers do not support OpenGL.  AMD only- *  supports OpenGL ES via EGL, while Nvidia and Intel only supports it via- *  a WGL or GLX extension.  OS X does not provide OpenGL ES at all.  The Mesa- *  EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary- *  driver.- */-#define GLFW_API_UNAVAILABLE        0x00010006-/*! @brief The requested OpenGL or OpenGL ES version is not available.- *- *  The requested OpenGL or OpenGL ES version (including any requested profile- *  or context option) is not available on this machine.- *- *  @par Analysis- *  The machine does not support your requirements.  If your application is- *  sufficiently flexible, downgrade your requirements and try again.- *  Otherwise, inform the user that their machine does not match your- *  requirements.- *- *  @par- *  Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0- *  comes out before the 4.x series gets that far, also fail with this error and- *  not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions- *  will exist.- */-#define GLFW_VERSION_UNAVAILABLE    0x00010007-/*! @brief A platform-specific error occurred that does not match any of the- *  more specific categories.- *- *  A platform-specific error occurred that does not match any of the more- *  specific categories.- *- *  @par Analysis- *  A bug in GLFW or the underlying operating system.  Report the bug to our- *  [issue tracker](https://github.com/glfw/glfw/issues).- */-#define GLFW_PLATFORM_ERROR         0x00010008-/*! @brief The requested format is not supported or available.- *- *  If emitted during window creation, the requested pixel format is not- *  supported.- *- *  If emitted when querying the clipboard, the contents of the clipboard could- *  not be converted to the requested format.- *- *  @par Analysis- *  If emitted during window creation, one or more- *  [hard constraints](@ref window_hints_hard) did not match any of the- *  available pixel formats.  If your application is sufficiently flexible,- *  downgrade your requirements and try again.  Otherwise, inform the user that- *  their machine does not match your requirements.- *- *  @par- *  If emitted when querying the clipboard, ignore the error or report it to- *  the user, as appropriate.- */-#define GLFW_FORMAT_UNAVAILABLE     0x00010009-/*! @} */--#define GLFW_FOCUSED                0x00020001-#define GLFW_ICONIFIED              0x00020002-#define GLFW_RESIZABLE              0x00020003-#define GLFW_VISIBLE                0x00020004-#define GLFW_DECORATED              0x00020005-#define GLFW_AUTO_ICONIFY           0x00020006-#define GLFW_FLOATING               0x00020007--#define GLFW_RED_BITS               0x00021001-#define GLFW_GREEN_BITS             0x00021002-#define GLFW_BLUE_BITS              0x00021003-#define GLFW_ALPHA_BITS             0x00021004-#define GLFW_DEPTH_BITS             0x00021005-#define GLFW_STENCIL_BITS           0x00021006-#define GLFW_ACCUM_RED_BITS         0x00021007-#define GLFW_ACCUM_GREEN_BITS       0x00021008-#define GLFW_ACCUM_BLUE_BITS        0x00021009-#define GLFW_ACCUM_ALPHA_BITS       0x0002100A-#define GLFW_AUX_BUFFERS            0x0002100B-#define GLFW_STEREO                 0x0002100C-#define GLFW_SAMPLES                0x0002100D-#define GLFW_SRGB_CAPABLE           0x0002100E-#define GLFW_REFRESH_RATE           0x0002100F-#define GLFW_DOUBLEBUFFER           0x00021010--#define GLFW_CLIENT_API             0x00022001-#define GLFW_CONTEXT_VERSION_MAJOR  0x00022002-#define GLFW_CONTEXT_VERSION_MINOR  0x00022003-#define GLFW_CONTEXT_REVISION       0x00022004-#define GLFW_CONTEXT_ROBUSTNESS     0x00022005-#define GLFW_OPENGL_FORWARD_COMPAT  0x00022006-#define GLFW_OPENGL_DEBUG_CONTEXT   0x00022007-#define GLFW_OPENGL_PROFILE         0x00022008-#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009--#define GLFW_OPENGL_API             0x00030001-#define GLFW_OPENGL_ES_API          0x00030002--#define GLFW_NO_ROBUSTNESS                   0-#define GLFW_NO_RESET_NOTIFICATION  0x00031001-#define GLFW_LOSE_CONTEXT_ON_RESET  0x00031002--#define GLFW_OPENGL_ANY_PROFILE              0-#define GLFW_OPENGL_CORE_PROFILE    0x00032001-#define GLFW_OPENGL_COMPAT_PROFILE  0x00032002--#define GLFW_CURSOR                 0x00033001-#define GLFW_STICKY_KEYS            0x00033002-#define GLFW_STICKY_MOUSE_BUTTONS   0x00033003--#define GLFW_CURSOR_NORMAL          0x00034001-#define GLFW_CURSOR_HIDDEN          0x00034002-#define GLFW_CURSOR_DISABLED        0x00034003--#define GLFW_ANY_RELEASE_BEHAVIOR            0-#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001-#define GLFW_RELEASE_BEHAVIOR_NONE  0x00035002--/*! @defgroup shapes Standard cursor shapes- *- *  See [standard cursor creation](@ref cursor_standard) for how these are used.- *- *  @ingroup input- *  @{ */--/*! @brief The regular arrow cursor shape.- *- *  The regular arrow cursor.- */-#define GLFW_ARROW_CURSOR           0x00036001-/*! @brief The text input I-beam cursor shape.- *- *  The text input I-beam cursor shape.- */-#define GLFW_IBEAM_CURSOR           0x00036002-/*! @brief The crosshair shape.- *- *  The crosshair shape.- */-#define GLFW_CROSSHAIR_CURSOR       0x00036003-/*! @brief The hand shape.- *- *  The hand shape.- */-#define GLFW_HAND_CURSOR            0x00036004-/*! @brief The horizontal resize arrow shape.- *- *  The horizontal resize arrow shape.- */-#define GLFW_HRESIZE_CURSOR         0x00036005-/*! @brief The vertical resize arrow shape.- *- *  The vertical resize arrow shape.- */-#define GLFW_VRESIZE_CURSOR         0x00036006-/*! @} */--#define GLFW_CONNECTED              0x00040001-#define GLFW_DISCONNECTED           0x00040002--#define GLFW_DONT_CARE              -1---/*************************************************************************- * GLFW API types- *************************************************************************/--/*! @brief Client API function pointer type.- *- *  Generic function pointer used for returning client API function pointers- *  without forcing a cast from a regular pointer.- *- *  @ingroup context- */-typedef void (*GLFWglproc)(void);--/*! @brief Opaque monitor object.- *- *  Opaque monitor object.- *- *  @ingroup monitor- */-typedef struct GLFWmonitor GLFWmonitor;--/*! @brief Opaque window object.- *- *  Opaque window object.- *- *  @ingroup window- */-typedef struct GLFWwindow GLFWwindow;--/*! @brief Opaque cursor object.- *- *  Opaque cursor object.- *- *  @ingroup cursor- */-typedef struct GLFWcursor GLFWcursor;--/*! @brief The function signature for error callbacks.- *- *  This is the function signature for error callback functions.- *- *  @param[in] error An [error code](@ref errors).- *  @param[in] description A UTF-8 encoded string describing the error.- *- *  @sa glfwSetErrorCallback- *- *  @ingroup init- */-typedef void (* GLFWerrorfun)(int,const char*);--/*! @brief The function signature for window position callbacks.- *- *  This is the function signature for window position callback functions.- *- *  @param[in] window The window that was moved.- *  @param[in] xpos The new x-coordinate, in screen coordinates, of the- *  upper-left corner of the client area of the window.- *  @param[in] ypos The new y-coordinate, in screen coordinates, of the- *  upper-left corner of the client area of the window.- *- *  @sa glfwSetWindowPosCallback- *- *  @ingroup window- */-typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);--/*! @brief The function signature for window resize callbacks.- *- *  This is the function signature for window size callback functions.- *- *  @param[in] window The window that was resized.- *  @param[in] width The new width, in screen coordinates, of the window.- *  @param[in] height The new height, in screen coordinates, of the window.- *- *  @sa glfwSetWindowSizeCallback- *- *  @ingroup window- */-typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);--/*! @brief The function signature for window close callbacks.- *- *  This is the function signature for window close callback functions.- *- *  @param[in] window The window that the user attempted to close.- *- *  @sa glfwSetWindowCloseCallback- *- *  @ingroup window- */-typedef void (* GLFWwindowclosefun)(GLFWwindow*);--/*! @brief The function signature for window content refresh callbacks.- *- *  This is the function signature for window refresh callback functions.- *- *  @param[in] window The window whose content needs to be refreshed.- *- *  @sa glfwSetWindowRefreshCallback- *- *  @ingroup window- */-typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);--/*! @brief The function signature for window focus/defocus callbacks.- *- *  This is the function signature for window focus callback functions.- *- *  @param[in] window The window that gained or lost input focus.- *  @param[in] focused `GL_TRUE` if the window was given input focus, or- *  `GL_FALSE` if it lost it.- *- *  @sa glfwSetWindowFocusCallback- *- *  @ingroup window- */-typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);--/*! @brief The function signature for window iconify/restore callbacks.- *- *  This is the function signature for window iconify/restore callback- *  functions.- *- *  @param[in] window The window that was iconified or restored.- *  @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE`- *  if it was restored.- *- *  @sa glfwSetWindowIconifyCallback- *- *  @ingroup window- */-typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);--/*! @brief The function signature for framebuffer resize callbacks.- *- *  This is the function signature for framebuffer resize callback- *  functions.- *- *  @param[in] window The window whose framebuffer was resized.- *  @param[in] width The new width, in pixels, of the framebuffer.- *  @param[in] height The new height, in pixels, of the framebuffer.- *- *  @sa glfwSetFramebufferSizeCallback- *- *  @ingroup window- */-typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);--/*! @brief The function signature for mouse button callbacks.- *- *  This is the function signature for mouse button callback functions.- *- *  @param[in] window The window that received the event.- *  @param[in] button The [mouse button](@ref buttons) that was pressed or- *  released.- *  @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.- *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were- *  held down.- *- *  @sa glfwSetMouseButtonCallback- *- *  @ingroup input- */-typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);--/*! @brief The function signature for cursor position callbacks.- *- *  This is the function signature for cursor position callback functions.- *- *  @param[in] window The window that received the event.- *  @param[in] xpos The new x-coordinate, in screen coordinates, of the cursor.- *  @param[in] ypos The new y-coordinate, in screen coordinates, of the cursor.- *- *  @sa glfwSetCursorPosCallback- *- *  @ingroup input- */-typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);--/*! @brief The function signature for cursor enter/leave callbacks.- *- *  This is the function signature for cursor enter/leave callback functions.- *- *  @param[in] window The window that received the event.- *  @param[in] entered `GL_TRUE` if the cursor entered the window's client- *  area, or `GL_FALSE` if it left it.- *- *  @sa glfwSetCursorEnterCallback- *- *  @ingroup input- */-typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);--/*! @brief The function signature for scroll callbacks.- *- *  This is the function signature for scroll callback functions.- *- *  @param[in] window The window that received the event.- *  @param[in] xoffset The scroll offset along the x-axis.- *  @param[in] yoffset The scroll offset along the y-axis.- *- *  @sa glfwSetScrollCallback- *- *  @ingroup input- */-typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);--/*! @brief The function signature for keyboard key callbacks.- *- *  This is the function signature for keyboard key callback functions.- *- *  @param[in] window The window that received the event.- *  @param[in] key The [keyboard key](@ref keys) that was pressed or released.- *  @param[in] scancode The system-specific scancode of the key.- *  @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.- *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were- *  held down.- *- *  @sa glfwSetKeyCallback- *- *  @ingroup input- */-typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);--/*! @brief The function signature for Unicode character callbacks.- *- *  This is the function signature for Unicode character callback functions.- *- *  @param[in] window The window that received the event.- *  @param[in] codepoint The Unicode code point of the character.- *- *  @sa glfwSetCharCallback- *- *  @ingroup input- */-typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);--/*! @brief The function signature for Unicode character with modifiers- *  callbacks.- *- *  This is the function signature for Unicode character with modifiers callback- *  functions.  It is called for each input character, regardless of what- *  modifier keys are held down.- *- *  @param[in] window The window that received the event.- *  @param[in] codepoint The Unicode code point of the character.- *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were- *  held down.- *- *  @sa glfwSetCharModsCallback- *- *  @ingroup input- */-typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);--/*! @brief The function signature for file drop callbacks.- *- *  This is the function signature for file drop callbacks.- *- *  @param[in] window The window that received the event.- *  @param[in] count The number of dropped files.- *  @param[in] paths The UTF-8 encoded file and/or directory path names.- *- *  @sa glfwSetDropCallback- *- *  @ingroup input- */-typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);--/*! @brief The function signature for monitor configuration callbacks.- *- *  This is the function signature for monitor configuration callback functions.- *- *  @param[in] monitor The monitor that was connected or disconnected.- *  @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.- *- *  @sa glfwSetMonitorCallback- *- *  @ingroup monitor- */-typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);--/*! @brief Video mode type.- *- *  This describes a single video mode.- *- *  @ingroup monitor- */-typedef struct GLFWvidmode-{-    /*! The width, in screen coordinates, of the video mode.-     */-    int width;-    /*! The height, in screen coordinates, of the video mode.-     */-    int height;-    /*! The bit depth of the red channel of the video mode.-     */-    int redBits;-    /*! The bit depth of the green channel of the video mode.-     */-    int greenBits;-    /*! The bit depth of the blue channel of the video mode.-     */-    int blueBits;-    /*! The refresh rate, in Hz, of the video mode.-     */-    int refreshRate;-} GLFWvidmode;--/*! @brief Gamma ramp.- *- *  This describes the gamma ramp for a monitor.- *- *  @sa glfwGetGammaRamp glfwSetGammaRamp- *- *  @ingroup monitor- */-typedef struct GLFWgammaramp-{-    /*! An array of value describing the response of the red channel.-     */-    unsigned short* red;-    /*! An array of value describing the response of the green channel.-     */-    unsigned short* green;-    /*! An array of value describing the response of the blue channel.-     */-    unsigned short* blue;-    /*! The number of elements in each array.-     */-    unsigned int size;-} GLFWgammaramp;--/*! @brief Image data.- */-typedef struct GLFWimage-{-    /*! The width, in pixels, of this image.-     */-    int width;-    /*! The height, in pixels, of this image.-     */-    int height;-    /*! The pixel data of this image, arranged left-to-right, top-to-bottom.-     */-    unsigned char* pixels;-} GLFWimage;---/*************************************************************************- * GLFW API functions- *************************************************************************/--/*! @brief Initializes the GLFW library.- *- *  This function initializes the GLFW library.  Before most GLFW functions can- *  be used, GLFW must be initialized, and before an application terminates GLFW- *  should be terminated in order to free any resources allocated during or- *  after initialization.- *- *  If this function fails, it calls @ref glfwTerminate before returning.  If it- *  succeeds, you should call @ref glfwTerminate before the application exits.- *- *  Additional calls to this function after successful initialization but before- *  termination will return `GL_TRUE` immediately.- *- *  @return `GL_TRUE` if successful, or `GL_FALSE` if an- *  [error](@ref error_handling) occurred.- *- *  @remarks __OS X:__ This function will change the current directory of the- *  application to the `Contents/Resources` subdirectory of the application's- *  bundle, if present.  This can be disabled with a- *  [compile-time option](@ref compile_options_osx).- *- *  @remarks __X11:__ If the `LC_CTYPE` category of the current locale is set to- *  `"C"` then the environment's locale will be applied to that category.  This- *  is done because character input will not function when `LC_CTYPE` is set to- *  `"C"`.  If another locale was set before this function was called, it will- *  be left untouched.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref intro_init- *  @sa glfwTerminate- *- *  @since Added in GLFW 1.0.- *- *  @ingroup init- */-GLFWAPI int glfwInit(void);--/*! @brief Terminates the GLFW library.- *- *  This function destroys all remaining windows and cursors, restores any- *  modified gamma ramps and frees any other allocated resources.  Once this- *  function is called, you must again call @ref glfwInit successfully before- *  you will be able to use most GLFW functions.- *- *  If GLFW has been successfully initialized, this function should be called- *  before the application exits.  If initialization fails, there is no need to- *  call this function, as it is called by @ref glfwInit before it returns- *  failure.- *- *  @remarks This function may be called before @ref glfwInit.- *- *  @warning No window's context may be current on another thread when this- *  function is called.- *- *  @par Reentrancy- *  This function may not be called from a callback.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref intro_init- *  @sa glfwInit- *- *  @since Added in GLFW 1.0.- *- *  @ingroup init- */-GLFWAPI void glfwTerminate(void);--/*! @brief Retrieves the version of the GLFW library.- *- *  This function retrieves the major, minor and revision numbers of the GLFW- *  library.  It is intended for when you are using GLFW as a shared library and- *  want to ensure that you are using the minimum required version.- *- *  Any or all of the version arguments may be `NULL`.  This function always- *  succeeds.- *- *  @param[out] major Where to store the major version number, or `NULL`.- *  @param[out] minor Where to store the minor version number, or `NULL`.- *  @param[out] rev Where to store the revision number, or `NULL`.- *- *  @remarks This function may be called before @ref glfwInit.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref intro_version- *  @sa glfwGetVersionString- *- *  @since Added in GLFW 1.0.- *- *  @ingroup init- */-GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);--/*! @brief Returns a string describing the compile-time configuration.- *- *  This function returns the compile-time generated- *  [version string](@ref intro_version_string) of the GLFW library binary.  It- *  describes the version, platform, compiler and any platform-specific- *  compile-time options.- *- *  __Do not use the version string__ to parse the GLFW library version.  The- *  @ref glfwGetVersion function already provides the version of the running- *  library binary.- *- *  This function always succeeds.- *- *  @return The GLFW version string.- *- *  @remarks This function may be called before @ref glfwInit.- *- *  @par Pointer Lifetime- *  The returned string is static and compile-time generated.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref intro_version- *  @sa glfwGetVersion- *- *  @since Added in GLFW 3.0.- *- *  @ingroup init- */-GLFWAPI const char* glfwGetVersionString(void);--/*! @brief Sets the error callback.- *- *  This function sets the error callback, which is called with an error code- *  and a human-readable description each time a GLFW error occurs.- *- *  The error callback is called on the thread where the error occurred.  If you- *  are using GLFW from multiple threads, your error callback needs to be- *  written accordingly.- *- *  Because the description string may have been generated specifically for that- *  error, it is not guaranteed to be valid after the callback has returned.  If- *  you wish to use it after the callback returns, you need to make a copy.- *- *  Once set, the error callback remains set even after the library has been- *  terminated.- *- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set.- *- *  @remarks This function may be called before @ref glfwInit.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref error_handling- *- *  @since Added in GLFW 3.0.- *- *  @ingroup init- */-GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);--/*! @brief Returns the currently connected monitors.- *- *  This function returns an array of handles for all currently connected- *  monitors.- *- *  @param[out] count Where to store the number of monitors in the returned- *  array.  This is set to zero if an error occurred.- *  @return An array of monitor handles, or `NULL` if an- *  [error](@ref error_handling) occurred.- *- *  @par Pointer Lifetime- *  The returned array is allocated and freed by GLFW.  You should not free it- *  yourself.  It is guaranteed to be valid only until the monitor configuration- *  changes or the library is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_monitors- *  @sa @ref monitor_event- *  @sa glfwGetPrimaryMonitor- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);--/*! @brief Returns the primary monitor.- *- *  This function returns the primary monitor.  This is usually the monitor- *  where elements like the Windows task bar or the OS X menu bar is located.- *- *  @return The primary monitor, or `NULL` if an [error](@ref error_handling)- *  occurred.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_monitors- *  @sa glfwGetMonitors- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);--/*! @brief Returns the position of the monitor's viewport on the virtual screen.- *- *  This function returns the position, in screen coordinates, of the upper-left- *  corner of the specified monitor.- *- *  Any or all of the position arguments may be `NULL`.  If an error occurs, all- *  non-`NULL` position arguments will be set to zero.- *- *  @param[in] monitor The monitor to query.- *  @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.- *  @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_properties- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);--/*! @brief Returns the physical size of the monitor.- *- *  This function returns the size, in millimetres, of the display area of the- *  specified monitor.- *- *  Some systems do not provide accurate monitor size information, either- *  because the monitor- *  [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)- *  data is incorrect or because the driver does not report it accurately.- *- *  Any or all of the size arguments may be `NULL`.  If an error occurs, all- *  non-`NULL` size arguments will be set to zero.- *- *  @param[in] monitor The monitor to query.- *  @param[out] widthMM Where to store the width, in millimetres, of the- *  monitor's display area, or `NULL`.- *  @param[out] heightMM Where to store the height, in millimetres, of the- *  monitor's display area, or `NULL`.- *- *  @remarks __Windows:__ The OS calculates the returned physical size from the- *  current resolution and system DPI instead of querying the monitor EDID data.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_properties- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);--/*! @brief Returns the name of the specified monitor.- *- *  This function returns a human-readable name, encoded as UTF-8, of the- *  specified monitor.  The name typically reflects the make and model of the- *  monitor and is not guaranteed to be unique among the connected monitors.- *- *  @param[in] monitor The monitor to query.- *  @return The UTF-8 encoded name of the monitor, or `NULL` if an- *  [error](@ref error_handling) occurred.- *- *  @par Pointer Lifetime- *  The returned string is allocated and freed by GLFW.  You should not free it- *  yourself.  It is valid until the specified monitor is disconnected or the- *  library is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_properties- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);--/*! @brief Sets the monitor configuration callback.- *- *  This function sets the monitor configuration callback, or removes the- *  currently set callback.  This is called when a monitor is connected to or- *  disconnected from the system.- *- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @bug __X11:__ This callback is not yet called on monitor configuration- *  changes.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_event- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);--/*! @brief Returns the available video modes for the specified monitor.- *- *  This function returns an array of all video modes supported by the specified- *  monitor.  The returned array is sorted in ascending order, first by color- *  bit depth (the sum of all channel depths) and then by resolution area (the- *  product of width and height).- *- *  @param[in] monitor The monitor to query.- *  @param[out] count Where to store the number of video modes in the returned- *  array.  This is set to zero if an error occurred.- *  @return An array of video modes, or `NULL` if an- *  [error](@ref error_handling) occurred.- *- *  @par Pointer Lifetime- *  The returned array is allocated and freed by GLFW.  You should not free it- *  yourself.  It is valid until the specified monitor is disconnected, this- *  function is called again for that monitor or the library is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_modes- *  @sa glfwGetVideoMode- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Changed to return an array of modes for a specific monitor.- *- *  @ingroup monitor- */-GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);--/*! @brief Returns the current mode of the specified monitor.- *- *  This function returns the current video mode of the specified monitor.  If- *  you have created a full screen window for that monitor, the return value- *  will depend on whether that window is iconified.- *- *  @param[in] monitor The monitor to query.- *  @return The current mode of the monitor, or `NULL` if an- *  [error](@ref error_handling) occurred.- *- *  @par Pointer Lifetime- *  The returned array is allocated and freed by GLFW.  You should not free it- *  yourself.  It is valid until the specified monitor is disconnected or the- *  library is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_modes- *  @sa glfwGetVideoModes- *- *  @since Added in GLFW 3.0.  Replaces `glfwGetDesktopMode`.- *- *  @ingroup monitor- */-GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);--/*! @brief Generates a gamma ramp and sets it for the specified monitor.- *- *  This function generates a 256-element gamma ramp from the specified exponent- *  and then calls @ref glfwSetGammaRamp with it.- *- *  @param[in] monitor The monitor whose gamma ramp to set.- *  @param[in] gamma The desired exponent.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_gamma- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);--/*! @brief Returns the current gamma ramp for the specified monitor.- *- *  This function returns the current gamma ramp of the specified monitor.- *- *  @param[in] monitor The monitor to query.- *  @return The current gamma ramp, or `NULL` if an- *  [error](@ref error_handling) occurred.- *- *  @par Pointer Lifetime- *  The returned structure and its arrays are allocated and freed by GLFW.  You- *  should not free them yourself.  They are valid until the specified monitor- *  is disconnected, this function is called again for that monitor or the- *  library is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_gamma- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);--/*! @brief Sets the current gamma ramp for the specified monitor.- *- *  This function sets the current gamma ramp for the specified monitor.  The- *  original gamma ramp for that monitor is saved by GLFW the first time this- *  function is called and is restored by @ref glfwTerminate.- *- *  @param[in] monitor The monitor whose gamma ramp to set.- *  @param[in] ramp The gamma ramp to use.- *- *  @note Gamma ramp sizes other than 256 are not supported by all hardware.- *- *  @par Pointer Lifetime- *  The specified gamma ramp is copied before this function returns.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref monitor_gamma- *- *  @since Added in GLFW 3.0.- *- *  @ingroup monitor- */-GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);--/*! @brief Resets all window hints to their default values.- *- *  This function resets all window hints to their- *  [default values](@ref window_hints_values).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_hints- *  @sa glfwWindowHint- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI void glfwDefaultWindowHints(void);--/*! @brief Sets the specified window hint to the desired value.- *- *  This function sets hints for the next call to @ref glfwCreateWindow.  The- *  hints, once set, retain their values until changed by a call to @ref- *  glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is- *  terminated.- *- *  @param[in] target The [window hint](@ref window_hints) to set.- *  @param[in] hint The new value of the window hint.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_hints- *  @sa glfwDefaultWindowHints- *- *  @since Added in GLFW 3.0.  Replaces `glfwOpenWindowHint`.- *- *  @ingroup window- */-GLFWAPI void glfwWindowHint(int target, int hint);--/*! @brief Creates a window and its associated context.- *- *  This function creates a window and its associated OpenGL or OpenGL ES- *  context.  Most of the options controlling how the window and its context- *  should be created are specified with [window hints](@ref window_hints).- *- *  Successful creation does not change which context is current.  Before you- *  can use the newly created context, you need to- *  [make it current](@ref context_current).  For information about the `share`- *  parameter, see @ref context_sharing.- *- *  The created window, framebuffer and context may differ from what you- *  requested, as not all parameters and hints are- *  [hard constraints](@ref window_hints_hard).  This includes the size of the- *  window, especially for full screen windows.  To query the actual attributes- *  of the created window, framebuffer and context, use queries like @ref- *  glfwGetWindowAttrib and @ref glfwGetWindowSize.- *- *  To create a full screen window, you need to specify the monitor the window- *  will cover.  If no monitor is specified, windowed mode will be used.  Unless- *  you have a way for the user to choose a specific monitor, it is recommended- *  that you pick the primary monitor.  For more information on how to query- *  connected monitors, see @ref monitor_monitors.- *- *  For full screen windows, the specified size becomes the resolution of the- *  window's _desired video mode_.  As long as a full screen window has input- *  focus, the supported video mode most closely matching the desired video mode- *  is set for the specified monitor.  For more information about full screen- *  windows, including the creation of so called _windowed full screen_ or- *  _borderless full screen_ windows, see @ref window_windowed_full_screen.- *- *  By default, newly created windows use the placement recommended by the- *  window system.  To create the window at a specific position, make it- *  initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window- *  hint, set its [position](@ref window_pos) and then [show](@ref window_hide)- *  it.- *- *  If a full screen window has input focus, the screensaver is prohibited from- *  starting.- *- *  Window systems put limits on window sizes.  Very large or very small window- *  dimensions may be overridden by the window system on creation.  Check the- *  actual [size](@ref window_size) after creation.- *- *  The [swap interval](@ref buffer_swap) is not set during window creation and- *  the initial value may vary depending on driver settings and defaults.- *- *  @param[in] width The desired width, in screen coordinates, of the window.- *  This must be greater than zero.- *  @param[in] height The desired height, in screen coordinates, of the window.- *  This must be greater than zero.- *  @param[in] title The initial, UTF-8 encoded window title.- *  @param[in] monitor The monitor to use for full screen mode, or `NULL` to use- *  windowed mode.- *  @param[in] share The window whose context to share resources with, or `NULL`- *  to not share resources.- *  @return The handle of the created window, or `NULL` if an- *  [error](@ref error_handling) occurred.- *- *  @remarks __Windows:__ Window creation will fail if the Microsoft GDI- *  software OpenGL implementation is the only one available.- *- *  @remarks __Windows:__ If the executable has an icon resource named- *  `GLFW_ICON,` it will be set as the icon for the window.  If no such icon is- *  present, the `IDI_WINLOGO` icon will be used instead.- *- *  @remarks __Windows:__ The context to share resources with may not be current- *  on any other thread.- *- *  @remarks __OS X:__ The GLFW window has no icon, as it is not a document- *  window, but the dock icon will be the same as the application bundle's icon.- *  For more information on bundles, see the- *  [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)- *  in the Mac Developer Library.- *- *  @remarks __OS X:__ The first time a window is created the menu bar is- *  populated with common commands like Hide, Quit and About.  The About entry- *  opens a minimal about dialog with information from the application's bundle.- *  The menu bar can be disabled with a- *  [compile-time option](@ref compile_options_osx).- *- *  @remarks __X11:__ There is no mechanism for setting the window icon yet.- *- *  @remarks __X11:__ Some window managers will not respect the placement of- *  initially hidden windows.- *- *  @par Reentrancy- *  This function may not be called from a callback.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_creation- *  @sa glfwDestroyWindow- *- *  @since Added in GLFW 3.0.  Replaces `glfwOpenWindow`.- *- *  @ingroup window- */-GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);--/*! @brief Destroys the specified window and its context.- *- *  This function destroys the specified window and its context.  On calling- *  this function, no further callbacks will be called for that window.- *- *  If the context of the specified window is current on the main thread, it is- *  detached before being destroyed.- *- *  @param[in] window The window to destroy.- *- *  @note The context of the specified window must not be current on any other- *  thread when this function is called.- *- *  @par Reentrancy- *  This function may not be called from a callback.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_creation- *  @sa glfwCreateWindow- *- *  @since Added in GLFW 3.0.  Replaces `glfwCloseWindow`.- *- *  @ingroup window- */-GLFWAPI void glfwDestroyWindow(GLFWwindow* window);--/*! @brief Checks the close flag of the specified window.- *- *  This function returns the value of the close flag of the specified window.- *- *  @param[in] window The window to query.- *  @return The value of the close flag.- *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.- *- *  @sa @ref window_close- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);--/*! @brief Sets the close flag of the specified window.- *- *  This function sets the value of the close flag of the specified window.- *  This can be used to override the user's attempt to close the window, or- *  to signal that it should be closed.- *- *  @param[in] window The window whose flag to change.- *  @param[in] value The new value.- *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.- *- *  @sa @ref window_close- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);--/*! @brief Sets the title of the specified window.- *- *  This function sets the window title, encoded as UTF-8, of the specified- *  window.- *- *  @param[in] window The window whose title to change.- *  @param[in] title The UTF-8 encoded window title.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_title- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup window- */-GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);--/*! @brief Retrieves the position of the client area of the specified window.- *- *  This function retrieves the position, in screen coordinates, of the- *  upper-left corner of the client area of the specified window.- *- *  Any or all of the position arguments may be `NULL`.  If an error occurs, all- *  non-`NULL` position arguments will be set to zero.- *- *  @param[in] window The window to query.- *  @param[out] xpos Where to store the x-coordinate of the upper-left corner of- *  the client area, or `NULL`.- *  @param[out] ypos Where to store the y-coordinate of the upper-left corner of- *  the client area, or `NULL`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_pos- *  @sa glfwSetWindowPos- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);--/*! @brief Sets the position of the client area of the specified window.- *- *  This function sets the position, in screen coordinates, of the upper-left- *  corner of the client area of the specified windowed mode window.  If the- *  window is a full screen window, this function does nothing.- *- *  __Do not use this function__ to move an already visible window unless you- *  have very good reasons for doing so, as it will confuse and annoy the user.- *- *  The window manager may put limits on what positions are allowed.  GLFW- *  cannot and should not override these limits.- *- *  @param[in] window The window to query.- *  @param[in] xpos The x-coordinate of the upper-left corner of the client area.- *  @param[in] ypos The y-coordinate of the upper-left corner of the client area.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_pos- *  @sa glfwGetWindowPos- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup window- */-GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);--/*! @brief Retrieves the size of the client area of the specified window.- *- *  This function retrieves the size, in screen coordinates, of the client area- *  of the specified window.  If you wish to retrieve the size of the- *  framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.- *- *  Any or all of the size arguments may be `NULL`.  If an error occurs, all- *  non-`NULL` size arguments will be set to zero.- *- *  @param[in] window The window whose size to retrieve.- *  @param[out] width Where to store the width, in screen coordinates, of the- *  client area, or `NULL`.- *  @param[out] height Where to store the height, in screen coordinates, of the- *  client area, or `NULL`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_size- *  @sa glfwSetWindowSize- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup window- */-GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);--/*! @brief Sets the size of the client area of the specified window.- *- *  This function sets the size, in screen coordinates, of the client area of- *  the specified window.- *- *  For full screen windows, this function selects and switches to the resolution- *  closest to the specified size, without affecting the window's context.  As- *  the context is unaffected, the bit depths of the framebuffer remain- *  unchanged.- *- *  The window manager may put limits on what sizes are allowed.  GLFW cannot- *  and should not override these limits.- *- *  @param[in] window The window to resize.- *  @param[in] width The desired width of the specified window.- *  @param[in] height The desired height of the specified window.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_size- *  @sa glfwGetWindowSize- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup window- */-GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);--/*! @brief Retrieves the size of the framebuffer of the specified window.- *- *  This function retrieves the size, in pixels, of the framebuffer of the- *  specified window.  If you wish to retrieve the size of the window in screen- *  coordinates, see @ref glfwGetWindowSize.- *- *  Any or all of the size arguments may be `NULL`.  If an error occurs, all- *  non-`NULL` size arguments will be set to zero.- *- *  @param[in] window The window whose framebuffer to query.- *  @param[out] width Where to store the width, in pixels, of the framebuffer,- *  or `NULL`.- *  @param[out] height Where to store the height, in pixels, of the framebuffer,- *  or `NULL`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_fbsize- *  @sa glfwSetFramebufferSizeCallback- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);--/*! @brief Retrieves the size of the frame of the window.- *- *  This function retrieves the size, in screen coordinates, of each edge of the- *  frame of the specified window.  This size includes the title bar, if the- *  window has one.  The size of the frame may vary depending on the- *  [window-related hints](@ref window_hints_wnd) used to create it.- *- *  Because this function retrieves the size of each window frame edge and not- *  the offset along a particular coordinate axis, the retrieved values will- *  always be zero or positive.- *- *  Any or all of the size arguments may be `NULL`.  If an error occurs, all- *  non-`NULL` size arguments will be set to zero.- *- *  @param[in] window The window whose frame size to query.- *  @param[out] left Where to store the size, in screen coordinates, of the left- *  edge of the window frame, or `NULL`.- *  @param[out] top Where to store the size, in screen coordinates, of the top- *  edge of the window frame, or `NULL`.- *  @param[out] right Where to store the size, in screen coordinates, of the- *  right edge of the window frame, or `NULL`.- *  @param[out] bottom Where to store the size, in screen coordinates, of the- *  bottom edge of the window frame, or `NULL`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_size- *- *  @since Added in GLFW 3.1.- *- *  @ingroup window- */-GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);--/*! @brief Iconifies the specified window.- *- *  This function iconifies (minimizes) the specified window if it was- *  previously restored.  If the window is already iconified, this function does- *  nothing.- *- *  If the specified window is a full screen window, the original monitor- *  resolution is restored until the window is restored.- *- *  @param[in] window The window to iconify.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_iconify- *  @sa glfwRestoreWindow- *- *  @since Added in GLFW 2.1.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup window- */-GLFWAPI void glfwIconifyWindow(GLFWwindow* window);--/*! @brief Restores the specified window.- *- *  This function restores the specified window if it was previously iconified- *  (minimized).  If the window is already restored, this function does nothing.- *- *  If the specified window is a full screen window, the resolution chosen for- *  the window is restored on the selected monitor.- *- *  @param[in] window The window to restore.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_iconify- *  @sa glfwIconifyWindow- *- *  @since Added in GLFW 2.1.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup window- */-GLFWAPI void glfwRestoreWindow(GLFWwindow* window);--/*! @brief Makes the specified window visible.- *- *  This function makes the specified window visible if it was previously- *  hidden.  If the window is already visible or is in full screen mode, this- *  function does nothing.- *- *  @param[in] window The window to make visible.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_hide- *  @sa glfwHideWindow- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI void glfwShowWindow(GLFWwindow* window);--/*! @brief Hides the specified window.- *- *  This function hides the specified window if it was previously visible.  If- *  the window is already hidden or is in full screen mode, this function does- *  nothing.- *- *  @param[in] window The window to hide.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_hide- *  @sa glfwShowWindow- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI void glfwHideWindow(GLFWwindow* window);--/*! @brief Returns the monitor that the window uses for full screen mode.- *- *  This function returns the handle of the monitor that the specified window is- *  in full screen on.- *- *  @param[in] window The window to query.- *  @return The monitor, or `NULL` if the window is in windowed mode or an error- *  occurred.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_monitor- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);--/*! @brief Returns an attribute of the specified window.- *- *  This function returns the value of an attribute of the specified window or- *  its OpenGL or OpenGL ES context.- *- *  @param[in] window The window to query.- *  @param[in] attrib The [window attribute](@ref window_attribs) whose value to- *  return.- *  @return The value of the attribute, or zero if an- *  [error](@ref error_handling) occurred.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_attribs- *- *  @since Added in GLFW 3.0.  Replaces `glfwGetWindowParam` and- *  `glfwGetGLVersion`.- *- *  @ingroup window- */-GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);--/*! @brief Sets the user pointer of the specified window.- *- *  This function sets the user-defined pointer of the specified window.  The- *  current value is retained until the window is destroyed.  The initial value- *  is `NULL`.- *- *  @param[in] window The window whose pointer to set.- *  @param[in] pointer The new value.- *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.- *- *  @sa @ref window_userptr- *  @sa glfwGetWindowUserPointer- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);--/*! @brief Returns the user pointer of the specified window.- *- *  This function returns the current value of the user-defined pointer of the- *  specified window.  The initial value is `NULL`.- *- *  @param[in] window The window whose pointer to return.- *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.- *- *  @sa @ref window_userptr- *  @sa glfwSetWindowUserPointer- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);--/*! @brief Sets the position callback for the specified window.- *- *  This function sets the position callback of the specified window, which is- *  called when the window is moved.  The callback is provided with the screen- *  position of the upper-left corner of the client area of the window.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_pos- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun);--/*! @brief Sets the size callback for the specified window.- *- *  This function sets the size callback of the specified window, which is- *  called when the window is resized.  The callback is provided with the size,- *  in screen coordinates, of the client area of the window.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_size- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.  Updated callback signature.- *- *  @ingroup window- */-GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun);--/*! @brief Sets the close callback for the specified window.- *- *  This function sets the close callback of the specified window, which is- *  called when the user attempts to close the window, for example by clicking- *  the close widget in the title bar.- *- *  The close flag is set before this callback is called, but you can modify it- *  at any time with @ref glfwSetWindowShouldClose.- *- *  The close callback is not triggered by @ref glfwDestroyWindow.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @remarks __OS X:__ Selecting Quit from the application menu will- *  trigger the close callback for all windows.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_close- *- *  @since Added in GLFW 2.5.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.  Updated callback signature.- *- *  @ingroup window- */-GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);--/*! @brief Sets the refresh callback for the specified window.- *- *  This function sets the refresh callback of the specified window, which is- *  called when the client area of the window needs to be redrawn, for example- *  if the window has been exposed after having been covered by another window.- *- *  On compositing window systems such as Aero, Compiz or Aqua, where the window- *  contents are saved off-screen, this callback may be called only very- *  infrequently or never at all.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_refresh- *- *  @since Added in GLFW 2.5.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.  Updated callback signature.- *- *  @ingroup window- */-GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun);--/*! @brief Sets the focus callback for the specified window.- *- *  This function sets the focus callback of the specified window, which is- *  called when the window gains or loses input focus.- *- *  After the focus callback is called for a window that lost input focus,- *  synthetic key and mouse button release events will be generated for all such- *  that had been pressed.  For more information, see @ref glfwSetKeyCallback- *  and @ref glfwSetMouseButtonCallback.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_focus- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);--/*! @brief Sets the iconify callback for the specified window.- *- *  This function sets the iconification callback of the specified window, which- *  is called when the window is iconified or restored.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_iconify- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);--/*! @brief Sets the framebuffer resize callback for the specified window.- *- *  This function sets the framebuffer resize callback of the specified window,- *  which is called when the framebuffer of the specified window is resized.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref window_fbsize- *- *  @since Added in GLFW 3.0.- *- *  @ingroup window- */-GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);--/*! @brief Processes all pending events.- *- *  This function processes only those events that are already in the event- *  queue and then returns immediately.  Processing events will cause the window- *  and input callbacks associated with those events to be called.- *- *  On some platforms, a window move, resize or menu operation will cause event- *  processing to block.  This is due to how event processing is designed on- *  those platforms.  You can use the- *  [window refresh callback](@ref window_refresh) to redraw the contents of- *  your window when necessary during such operations.- *- *  On some platforms, certain events are sent directly to the application- *  without going through the event queue, causing callbacks to be called- *  outside of a call to one of the event processing functions.- *- *  Event processing is not required for joystick input to work.- *- *  @par Reentrancy- *  This function may not be called from a callback.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref events- *  @sa glfwWaitEvents- *- *  @since Added in GLFW 1.0.- *- *  @ingroup window- */-GLFWAPI void glfwPollEvents(void);--/*! @brief Waits until events are queued and processes them.- *- *  This function puts the calling thread to sleep until at least one event is- *  available in the event queue.  Once one or more events are available,- *  it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue- *  are processed and the function then returns immediately.  Processing events- *  will cause the window and input callbacks associated with those events to be- *  called.- *- *  Since not all events are associated with callbacks, this function may return- *  without a callback having been called even if you are monitoring all- *  callbacks.- *- *  On some platforms, a window move, resize or menu operation will cause event- *  processing to block.  This is due to how event processing is designed on- *  those platforms.  You can use the- *  [window refresh callback](@ref window_refresh) to redraw the contents of- *  your window when necessary during such operations.- *- *  On some platforms, certain callbacks may be called outside of a call to one- *  of the event processing functions.- *- *  If no windows exist, this function returns immediately.  For synchronization- *  of threads in applications that do not create windows, use your threading- *  library of choice.- *- *  Event processing is not required for joystick input to work.- *- *  @par Reentrancy- *  This function may not be called from a callback.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref events- *  @sa glfwPollEvents- *- *  @since Added in GLFW 2.5.- *- *  @ingroup window- */-GLFWAPI void glfwWaitEvents(void);--/*! @brief Posts an empty event to the event queue.- *- *  This function posts an empty event from the current thread to the event- *  queue, causing @ref glfwWaitEvents to return.- *- *  If no windows exist, this function returns immediately.  For synchronization- *  of threads in applications that do not create windows, use your threading- *  library of choice.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref events- *  @sa glfwWaitEvents- *- *  @since Added in GLFW 3.1.- *- *  @ingroup window- */-GLFWAPI void glfwPostEmptyEvent(void);--/*! @brief Returns the value of an input option for the specified window.- *- *  This function returns the value of an input option for the specified window.- *  The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or- *  `GLFW_STICKY_MOUSE_BUTTONS`.- *- *  @param[in] window The window to query.- *  @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or- *  `GLFW_STICKY_MOUSE_BUTTONS`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa glfwSetInputMode- *- *  @since Added in GLFW 3.0.- *- *  @ingroup input- */-GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);--/*! @brief Sets an input option for the specified window.- *- *  This function sets an input mode option for the specified window.  The mode- *  must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or- *  `GLFW_STICKY_MOUSE_BUTTONS`.- *- *  If the mode is `GLFW_CURSOR`, the value must be one of the following cursor- *  modes:- *  - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.- *  - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client- *    area of the window but does not restrict the cursor from leaving.- *  - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual- *    and unlimited cursor movement.  This is useful for implementing for- *    example 3D camera controls.- *- *  If the mode is `GLFW_STICKY_KEYS`, the value must be either `GL_TRUE` to- *  enable sticky keys, or `GL_FALSE` to disable it.  If sticky keys are- *  enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`- *  the next time it is called even if the key had been released before the- *  call.  This is useful when you are only interested in whether keys have been- *  pressed but not when or in which order.- *- *  If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either- *  `GL_TRUE` to enable sticky mouse buttons, or `GL_FALSE` to disable it.  If- *  sticky mouse buttons are enabled, a mouse button press will ensure that @ref- *  glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even if- *  the mouse button had been released before the call.  This is useful when you- *  are only interested in whether mouse buttons have been pressed but not when- *  or in which order.- *- *  @param[in] window The window whose input mode to set.- *  @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or- *  `GLFW_STICKY_MOUSE_BUTTONS`.- *  @param[in] value The new value of the specified input mode.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa glfwGetInputMode- *- *  @since Added in GLFW 3.0.  Replaces `glfwEnable` and `glfwDisable`.- *- *  @ingroup input- */-GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);--/*! @brief Returns the last reported state of a keyboard key for the specified- *  window.- *- *  This function returns the last state reported for the specified key to the- *  specified window.  The returned state is one of `GLFW_PRESS` or- *  `GLFW_RELEASE`.  The higher-level action `GLFW_REPEAT` is only reported to- *  the key callback.- *- *  If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns- *  `GLFW_PRESS` the first time you call it for a key that was pressed, even if- *  that key has already been released.- *- *  The key functions deal with physical keys, with [key tokens](@ref keys)- *  named after their use on the standard US keyboard layout.  If you want to- *  input text, use the Unicode character callback instead.- *- *  The [modifier key bit masks](@ref mods) are not key tokens and cannot be- *  used with this function.- *- *  @param[in] window The desired window.- *  @param[in] key The desired [keyboard key](@ref keys).  `GLFW_KEY_UNKNOWN` is- *  not a valid key for this function.- *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref input_key- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup input- */-GLFWAPI int glfwGetKey(GLFWwindow* window, int key);--/*! @brief Returns the last reported state of a mouse button for the specified- *  window.- *- *  This function returns the last state reported for the specified mouse button- *  to the specified window.  The returned state is one of `GLFW_PRESS` or- *  `GLFW_RELEASE`.- *- *  If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function- *  `GLFW_PRESS` the first time you call it for a mouse button that was pressed,- *  even if that mouse button has already been released.- *- *  @param[in] window The desired window.- *  @param[in] button The desired [mouse button](@ref buttons).- *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref input_mouse_button- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup input- */-GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);--/*! @brief Retrieves the position of the cursor relative to the client area of- *  the window.- *- *  This function returns the position of the cursor, in screen coordinates,- *  relative to the upper-left corner of the client area of the specified- *  window.- *- *  If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor- *  position is unbounded and limited only by the minimum and maximum values of- *  a `double`.- *- *  The coordinate can be converted to their integer equivalents with the- *  `floor` function.  Casting directly to an integer type works for positive- *  coordinates, but fails for negative ones.- *- *  Any or all of the position arguments may be `NULL`.  If an error occurs, all- *  non-`NULL` position arguments will be set to zero.- *- *  @param[in] window The desired window.- *  @param[out] xpos Where to store the cursor x-coordinate, relative to the- *  left edge of the client area, or `NULL`.- *  @param[out] ypos Where to store the cursor y-coordinate, relative to the to- *  top edge of the client area, or `NULL`.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref cursor_pos- *  @sa glfwSetCursorPos- *- *  @since Added in GLFW 3.0.  Replaces `glfwGetMousePos`.- *- *  @ingroup input- */-GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);--/*! @brief Sets the position of the cursor, relative to the client area of the- *  window.- *- *  This function sets the position, in screen coordinates, of the cursor- *  relative to the upper-left corner of the client area of the specified- *  window.  The window must have input focus.  If the window does not have- *  input focus when this function is called, it fails silently.- *- *  __Do not use this function__ to implement things like camera controls.  GLFW- *  already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the- *  cursor, transparently re-centers it and provides unconstrained cursor- *  motion.  See @ref glfwSetInputMode for more information.- *- *  If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is- *  unconstrained and limited only by the minimum and maximum values of- *  a `double`.- *- *  @param[in] window The desired window.- *  @param[in] xpos The desired x-coordinate, relative to the left edge of the- *  client area.- *  @param[in] ypos The desired y-coordinate, relative to the top edge of the- *  client area.- *- *  @remarks __X11:__ Due to the asynchronous nature of a modern X desktop, it- *  may take a moment for the window focus event to arrive.  This means you will- *  not be able to set the cursor position directly after window creation.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref cursor_pos- *  @sa glfwGetCursorPos- *- *  @since Added in GLFW 3.0.  Replaces `glfwSetMousePos`.- *- *  @ingroup input- */-GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);--/*! @brief Creates a custom cursor.- *- *  Creates a new custom cursor image that can be set for a window with @ref- *  glfwSetCursor.  The cursor can be destroyed with @ref glfwDestroyCursor.- *  Any remaining cursors are destroyed by @ref glfwTerminate.- *- *  The pixels are 32-bit little-endian RGBA, i.e. eight bits per channel.  They- *  are arranged canonically as packed sequential rows, starting from the- *  top-left corner.- *- *  The cursor hotspot is specified in pixels, relative to the upper-left corner- *  of the cursor image.  Like all other coordinate systems in GLFW, the X-axis- *  points to the right and the Y-axis points down.- *- *  @param[in] image The desired cursor image.- *  @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.- *  @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.- *- *  @return The handle of the created cursor, or `NULL` if an- *  [error](@ref error_handling) occurred.- *- *  @par Pointer Lifetime- *  The specified image data is copied before this function returns.- *- *  @par Reentrancy- *  This function may not be called from a callback.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref cursor_object- *  @sa glfwDestroyCursor- *  @sa glfwCreateStandardCursor- *- *  @since Added in GLFW 3.1.- *- *  @ingroup input- */-GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);--/*! @brief Creates a cursor with a standard shape.- *- *  Returns a cursor with a [standard shape](@ref shapes), that can be set for- *  a window with @ref glfwSetCursor.- *- *  @param[in] shape One of the [standard shapes](@ref shapes).- *- *  @return A new cursor ready to use or `NULL` if an- *  [error](@ref error_handling) occurred.- *- *  @par Reentrancy- *  This function may not be called from a callback.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref cursor_object- *  @sa glfwCreateCursor- *- *  @since Added in GLFW 3.1.- *- *  @ingroup input- */-GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);--/*! @brief Destroys a cursor.- *- *  This function destroys a cursor previously created with @ref- *  glfwCreateCursor.  Any remaining cursors will be destroyed by @ref- *  glfwTerminate.- *- *  @param[in] cursor The cursor object to destroy.- *- *  @par Reentrancy- *  This function may not be called from a callback.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref cursor_object- *  @sa glfwCreateCursor- *- *  @since Added in GLFW 3.1.- *- *  @ingroup input- */-GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);--/*! @brief Sets the cursor for the window.- *- *  This function sets the cursor image to be used when the cursor is over the- *  client area of the specified window.  The set cursor will only be visible- *  when the [cursor mode](@ref cursor_mode) of the window is- *  `GLFW_CURSOR_NORMAL`.- *- *  On some platforms, the set cursor may not be visible unless the window also- *  has input focus.- *- *  @param[in] window The window to set the cursor for.- *  @param[in] cursor The cursor to set, or `NULL` to switch back to the default- *  arrow cursor.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref cursor_object- *- *  @since Added in GLFW 3.1.- *- *  @ingroup input- */-GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);--/*! @brief Sets the key callback.- *- *  This function sets the key callback of the specified window, which is called- *  when a key is pressed, repeated or released.- *- *  The key functions deal with physical keys, with layout independent- *  [key tokens](@ref keys) named after their values in the standard US keyboard- *  layout.  If you want to input text, use the- *  [character callback](@ref glfwSetCharCallback) instead.- *- *  When a window loses input focus, it will generate synthetic key release- *  events for all pressed keys.  You can tell these events from user-generated- *  events by the fact that the synthetic ones are generated after the focus- *  loss event has been processed, i.e. after the- *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called.- *- *  The scancode of a key is specific to that platform or sometimes even to that- *  machine.  Scancodes are intended to allow users to bind keys that don't have- *  a GLFW key token.  Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their- *  state is not saved and so it cannot be queried with @ref glfwGetKey.- *- *  Sometimes GLFW needs to generate synthetic key events, in which case the- *  scancode may be zero.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new key callback, or `NULL` to remove the currently- *  set callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref input_key- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.  Updated callback signature.- *- *  @ingroup input- */-GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);--/*! @brief Sets the Unicode character callback.- *- *  This function sets the character callback of the specified window, which is- *  called when a Unicode character is input.- *- *  The character callback is intended for Unicode text input.  As it deals with- *  characters, it is keyboard layout dependent, whereas the- *  [key callback](@ref glfwSetKeyCallback) is not.  Characters do not map 1:1- *  to physical keys, as a key may produce zero, one or more characters.  If you- *  want to know whether a specific physical key was pressed or released, see- *  the key callback instead.- *- *  The character callback behaves as system text input normally does and will- *  not be called if modifier keys are held down that would prevent normal text- *  input on that platform, for example a Super (Command) key on OS X or Alt key- *  on Windows.  There is a- *  [character with modifiers callback](@ref glfwSetCharModsCallback) that- *  receives these events.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref input_char- *- *  @since Added in GLFW 2.4.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.  Updated callback signature.- *- *  @ingroup input- */-GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);--/*! @brief Sets the Unicode character with modifiers callback.- *- *  This function sets the character with modifiers callback of the specified- *  window, which is called when a Unicode character is input regardless of what- *  modifier keys are used.- *- *  The character with modifiers callback is intended for implementing custom- *  Unicode character input.  For regular Unicode text input, see the- *  [character callback](@ref glfwSetCharCallback).  Like the character- *  callback, the character with modifiers callback deals with characters and is- *  keyboard layout dependent.  Characters do not map 1:1 to physical keys, as- *  a key may produce zero, one or more characters.  If you want to know whether- *  a specific physical key was pressed or released, see the- *  [key callback](@ref glfwSetKeyCallback) instead.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or an- *  error occurred.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref input_char- *- *  @since Added in GLFW 3.1.- *- *  @ingroup input- */-GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);--/*! @brief Sets the mouse button callback.- *- *  This function sets the mouse button callback of the specified window, which- *  is called when a mouse button is pressed or released.- *- *  When a window loses input focus, it will generate synthetic mouse button- *  release events for all pressed mouse buttons.  You can tell these events- *  from user-generated events by the fact that the synthetic ones are generated- *  after the focus loss event has been processed, i.e. after the- *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref input_mouse_button- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.  Updated callback signature.- *- *  @ingroup input- */-GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);--/*! @brief Sets the cursor position callback.- *- *  This function sets the cursor position callback of the specified window,- *  which is called when the cursor is moved.  The callback is provided with the- *  position, in screen coordinates, relative to the upper-left corner of the- *  client area of the window.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref cursor_pos- *- *  @since Added in GLFW 3.0.  Replaces `glfwSetMousePosCallback`.- *- *  @ingroup input- */-GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun);--/*! @brief Sets the cursor enter/exit callback.- *- *  This function sets the cursor boundary crossing callback of the specified- *  window, which is called when the cursor enters or leaves the client area of- *  the window.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new callback, or `NULL` to remove the currently set- *  callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref cursor_enter- *- *  @since Added in GLFW 3.0.- *- *  @ingroup input- */-GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun);--/*! @brief Sets the scroll callback.- *- *  This function sets the scroll callback of the specified window, which is- *  called when a scrolling device is used, such as a mouse wheel or scrolling- *  area of a touchpad.- *- *  The scroll callback receives all scrolling input, like that from a mouse- *  wheel or a touchpad scrolling area.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new scroll callback, or `NULL` to remove the currently- *  set callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref scrolling- *- *  @since Added in GLFW 3.0.  Replaces `glfwSetMouseWheelCallback`.- *- *  @ingroup input- */-GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);--/*! @brief Sets the file drop callback.- *- *  This function sets the file drop callback of the specified window, which is- *  called when one or more dragged files are dropped on the window.- *- *  Because the path array and its strings may have been generated specifically- *  for that event, they are not guaranteed to be valid after the callback has- *  returned.  If you wish to use them after the callback returns, you need to- *  make a deep copy.- *- *  @param[in] window The window whose callback to set.- *  @param[in] cbfun The new file drop callback, or `NULL` to remove the- *  currently set callback.- *  @return The previously set callback, or `NULL` if no callback was set or the- *  library had not been [initialized](@ref intro_init).- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref path_drop- *- *  @since Added in GLFW 3.1.- *- *  @ingroup input- */-GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);--/*! @brief Returns whether the specified joystick is present.- *- *  This function returns whether the specified joystick is present.- *- *  @param[in] joy The [joystick](@ref joysticks) to query.- *  @return `GL_TRUE` if the joystick is present, or `GL_FALSE` otherwise.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref joystick- *- *  @since Added in GLFW 3.0.  Replaces `glfwGetJoystickParam`.- *- *  @ingroup input- */-GLFWAPI int glfwJoystickPresent(int joy);--/*! @brief Returns the values of all axes of the specified joystick.- *- *  This function returns the values of all axes of the specified joystick.- *  Each element in the array is a value between -1.0 and 1.0.- *- *  @param[in] joy The [joystick](@ref joysticks) to query.- *  @param[out] count Where to store the number of axis values in the returned- *  array.  This is set to zero if an error occurred.- *  @return An array of axis values, or `NULL` if the joystick is not present.- *- *  @par Pointer Lifetime- *  The returned array is allocated and freed by GLFW.  You should not free it- *  yourself.  It is valid until the specified joystick is disconnected, this- *  function is called again for that joystick or the library is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref joystick_axis- *- *  @since Added in GLFW 3.0.  Replaces `glfwGetJoystickPos`.- *- *  @ingroup input- */-GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);--/*! @brief Returns the state of all buttons of the specified joystick.- *- *  This function returns the state of all buttons of the specified joystick.- *  Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.- *- *  @param[in] joy The [joystick](@ref joysticks) to query.- *  @param[out] count Where to store the number of button states in the returned- *  array.  This is set to zero if an error occurred.- *  @return An array of button states, or `NULL` if the joystick is not present.- *- *  @par Pointer Lifetime- *  The returned array is allocated and freed by GLFW.  You should not free it- *  yourself.  It is valid until the specified joystick is disconnected, this- *  function is called again for that joystick or the library is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref joystick_button- *- *  @since Added in GLFW 2.2.- *- *  @par- *  __GLFW 3:__ Changed to return a dynamic array.- *- *  @ingroup input- */-GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);--/*! @brief Returns the name of the specified joystick.- *- *  This function returns the name, encoded as UTF-8, of the specified joystick.- *  The returned string is allocated and freed by GLFW.  You should not free it- *  yourself.- *- *  @param[in] joy The [joystick](@ref joysticks) to query.- *  @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick- *  is not present.- *- *  @par Pointer Lifetime- *  The returned string is allocated and freed by GLFW.  You should not free it- *  yourself.  It is valid until the specified joystick is disconnected, this- *  function is called again for that joystick or the library is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref joystick_name- *- *  @since Added in GLFW 3.0.- *- *  @ingroup input- */-GLFWAPI const char* glfwGetJoystickName(int joy);--/*! @brief Sets the clipboard to the specified string.- *- *  This function sets the system clipboard to the specified, UTF-8 encoded- *  string.- *- *  @param[in] window The window that will own the clipboard contents.- *  @param[in] string A UTF-8 encoded string.- *- *  @par Pointer Lifetime- *  The specified string is copied before this function returns.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref clipboard- *  @sa glfwGetClipboardString- *- *  @since Added in GLFW 3.0.- *- *  @ingroup input- */-GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);--/*! @brief Returns the contents of the clipboard as a string.- *- *  This function returns the contents of the system clipboard, if it contains- *  or is convertible to a UTF-8 encoded string.- *- *  @param[in] window The window that will request the clipboard contents.- *  @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`- *  if an [error](@ref error_handling) occurred.- *- *  @par Pointer Lifetime- *  The returned string is allocated and freed by GLFW.  You should not free it- *  yourself.  It is valid until the next call to @ref- *  glfwGetClipboardString or @ref glfwSetClipboardString, or until the library- *  is terminated.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref clipboard- *  @sa glfwSetClipboardString- *- *  @since Added in GLFW 3.0.- *- *  @ingroup input- */-GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);--/*! @brief Returns the value of the GLFW timer.- *- *  This function returns the value of the GLFW timer.  Unless the timer has- *  been set using @ref glfwSetTime, the timer measures time elapsed since GLFW- *  was initialized.- *- *  The resolution of the timer is system dependent, but is usually on the order- *  of a few micro- or nanoseconds.  It uses the highest-resolution monotonic- *  time source on each supported platform.- *- *  @return The current value, in seconds, or zero if an- *  [error](@ref error_handling) occurred.- *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.- *- *  @sa @ref time- *- *  @since Added in GLFW 1.0.- *- *  @ingroup input- */-GLFWAPI double glfwGetTime(void);--/*! @brief Sets the GLFW timer.- *- *  This function sets the value of the GLFW timer.  It then continues to count- *  up from that value.  The value must be a positive finite number.- *- *  @param[in] time The new value, in seconds.- *- *  @par Thread Safety- *  This function may only be called from the main thread.- *- *  @sa @ref time- *- *  @since Added in GLFW 2.2.- *- *  @ingroup input- */-GLFWAPI void glfwSetTime(double time);--/*! @brief Makes the context of the specified window current for the calling- *  thread.- *- *  This function makes the OpenGL or OpenGL ES context of the specified window- *  current on the calling thread.  A context can only be made current on- *  a single thread at a time and each thread can have only a single current- *  context at a time.- *- *  By default, making a context non-current implicitly forces a pipeline flush.- *  On machines that support `GL_KHR_context_flush_control`, you can control- *  whether a context performs this flush by setting the- *  [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.- *- *  @param[in] window The window whose context to make current, or `NULL` to- *  detach the current context.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref context_current- *  @sa glfwGetCurrentContext- *- *  @since Added in GLFW 3.0.- *- *  @ingroup context- */-GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);--/*! @brief Returns the window whose context is current on the calling thread.- *- *  This function returns the window whose OpenGL or OpenGL ES context is- *  current on the calling thread.- *- *  @return The window whose context is current, or `NULL` if no window's- *  context is current.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref context_current- *  @sa glfwMakeContextCurrent- *- *  @since Added in GLFW 3.0.- *- *  @ingroup context- */-GLFWAPI GLFWwindow* glfwGetCurrentContext(void);--/*! @brief Swaps the front and back buffers of the specified window.- *- *  This function swaps the front and back buffers of the specified window.  If- *  the swap interval is greater than zero, the GPU driver waits the specified- *  number of screen updates before swapping the buffers.- *- *  @param[in] window The window whose buffers to swap.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref buffer_swap- *  @sa glfwSwapInterval- *- *  @since Added in GLFW 1.0.- *- *  @par- *  __GLFW 3:__ Added window handle parameter.- *- *  @ingroup window- */-GLFWAPI void glfwSwapBuffers(GLFWwindow* window);--/*! @brief Sets the swap interval for the current context.- *- *  This function sets the swap interval for the current context, i.e. the- *  number of screen updates to wait from the time @ref glfwSwapBuffers was- *  called before swapping the buffers and returning.  This is sometimes called- *  _vertical synchronization_, _vertical retrace synchronization_ or just- *  _vsync_.- *- *  Contexts that support either of the `WGL_EXT_swap_control_tear` and- *  `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,- *  which allow the driver to swap even if a frame arrives a little bit late.- *  You can check for the presence of these extensions using @ref- *  glfwExtensionSupported.  For more information about swap tearing, see the- *  extension specifications.- *- *  A context must be current on the calling thread.  Calling this function- *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.- *- *  @param[in] interval The minimum number of screen updates to wait for- *  until the buffers are swapped by @ref glfwSwapBuffers.- *- *  @remarks This function is not called during context creation, leaving the- *  swap interval set to whatever is the default on that platform.  This is done- *  because some swap interval extensions used by GLFW do not allow the swap- *  interval to be reset to zero once it has been set to a non-zero value.- *- *  @remarks Some GPU drivers do not honor the requested swap interval, either- *  because of a user setting that overrides the application's request or due to- *  bugs in the driver.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref buffer_swap- *  @sa glfwSwapBuffers- *- *  @since Added in GLFW 1.0.- *- *  @ingroup context- */-GLFWAPI void glfwSwapInterval(int interval);--/*! @brief Returns whether the specified extension is available.- *- *  This function returns whether the specified- *  [client API extension](@ref context_glext) is supported by the current- *  OpenGL or OpenGL ES context.  It searches both for OpenGL and OpenGL ES- *  extension and platform-specific context creation API extensions.- *- *  A context must be current on the calling thread.  Calling this function- *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.- *- *  As this functions retrieves and searches one or more extension strings each- *  call, it is recommended that you cache its results if it is going to be used- *  frequently.  The extension strings will not change during the lifetime of- *  a context, so there is no danger in doing this.- *- *  @param[in] extension The ASCII encoded name of the extension.- *  @return `GL_TRUE` if the extension is available, or `GL_FALSE` otherwise.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref context_glext- *  @sa glfwGetProcAddress- *- *  @since Added in GLFW 1.0.- *- *  @ingroup context- */-GLFWAPI int glfwExtensionSupported(const char* extension);--/*! @brief Returns the address of the specified function for the current- *  context.- *- *  This function returns the address of the specified- *  [core or extension function](@ref context_glext), if it is supported- *  by the current context.- *- *  A context must be current on the calling thread.  Calling this function- *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.- *- *  @param[in] procname The ASCII encoded name of the function.- *  @return The address of the function, or `NULL` if the function is- *  unavailable or an [error](@ref error_handling) occurred.- *- *  @remarks The addresses of a given function is not guaranteed to be the same- *  between contexts.- *- *  @remarks This function may return a non-`NULL` address despite the- *  associated version or extension not being available.  Always check the- *  context version or extension string presence first.- *- *  @par Pointer Lifetime- *  The returned function pointer is valid until the context is destroyed or the- *  library is terminated.- *- *  @par Thread Safety- *  This function may be called from any thread.- *- *  @sa @ref context_glext- *  @sa glfwExtensionSupported- *- *  @since Added in GLFW 1.0.- *- *  @ingroup context- */-GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);+ * GLFW 3.2 - www.glfw.org+ * A library for OpenGL, window and input+ *------------------------------------------------------------------------+ * Copyright (c) 2002-2006 Marcus Geelnard+ * Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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.+ *+ *************************************************************************/++#ifndef _glfw3_h_+#define _glfw3_h_++#ifdef __cplusplus+extern "C" {+#endif+++/*************************************************************************+ * Doxygen documentation+ *************************************************************************/++/*! @file glfw3.h+ *  @brief The header of the GLFW 3 API.+ *+ *  This is the header file of the GLFW 3 API.  It defines all its types and+ *  declares all its functions.+ *+ *  For more information about how to use this file, see @ref build_include.+ */+/*! @defgroup context Context reference+ *+ *  This is the reference documentation for OpenGL and OpenGL ES context related+ *  functions.  For more task-oriented information, see the @ref context_guide.+ */+/*! @defgroup vulkan Vulkan reference+ *+ *  This is the reference documentation for Vulkan related functions and types.+ *  For more task-oriented information, see the @ref vulkan_guide.+ */+/*! @defgroup init Initialization, version and error reference+ *+ *  This is the reference documentation for initialization and termination of+ *  the library, version management and error handling.  For more task-oriented+ *  information, see the @ref intro_guide.+ */+/*! @defgroup input Input reference+ *+ *  This is the reference documentation for input related functions and types.+ *  For more task-oriented information, see the @ref input_guide.+ */+/*! @defgroup monitor Monitor reference+ *+ *  This is the reference documentation for monitor related functions and types.+ *  For more task-oriented information, see the @ref monitor_guide.+ */+/*! @defgroup window Window reference+ *+ *  This is the reference documentation for window related functions and types,+ *  including creation, deletion and event polling.  For more task-oriented+ *  information, see the @ref window_guide.+ */+++/*************************************************************************+ * Compiler- and platform-specific preprocessor work+ *************************************************************************/++/* If we are we on Windows, we want a single define for it.+ */+#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))+ #define _WIN32+#endif /* _WIN32 */++/* It is customary to use APIENTRY for OpenGL function pointer declarations on+ * all platforms.  Additionally, the Windows OpenGL header needs APIENTRY.+ */+#ifndef APIENTRY+ #ifdef _WIN32+  #define APIENTRY __stdcall+ #else+  #define APIENTRY+ #endif+#endif /* APIENTRY */++/* Some Windows OpenGL headers need this.+ */+#if !defined(WINGDIAPI) && defined(_WIN32)+ #define WINGDIAPI __declspec(dllimport)+ #define GLFW_WINGDIAPI_DEFINED+#endif /* WINGDIAPI */++/* Some Windows GLU headers need this.+ */+#if !defined(CALLBACK) && defined(_WIN32)+ #define CALLBACK __stdcall+ #define GLFW_CALLBACK_DEFINED+#endif /* CALLBACK */++/* Include because most Windows GLU headers need wchar_t and+ * the OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.+ * Include it unconditionally to avoid surprising side-effects.+ */+#include <stddef.h>++/* Include because it is needed by Vulkan and related functions.+ */+#include <stdint.h>++/* Include the chosen client API headers.+ */+#if defined(__APPLE__)+ #if defined(GLFW_INCLUDE_GLCOREARB)+  #include <OpenGL/gl3.h>+  #if defined(GLFW_INCLUDE_GLEXT)+   #include <OpenGL/gl3ext.h>+  #endif+ #elif !defined(GLFW_INCLUDE_NONE)+  #if !defined(GLFW_INCLUDE_GLEXT)+   #define GL_GLEXT_LEGACY+  #endif+  #include <OpenGL/gl.h>+ #endif+ #if defined(GLFW_INCLUDE_GLU)+  #include <OpenGL/glu.h>+ #endif+#else+ #if defined(GLFW_INCLUDE_GLCOREARB)+  #include <GL/glcorearb.h>+ #elif defined(GLFW_INCLUDE_ES1)+  #include <GLES/gl.h>+  #if defined(GLFW_INCLUDE_GLEXT)+   #include <GLES/glext.h>+  #endif+ #elif defined(GLFW_INCLUDE_ES2)+  #include <GLES2/gl2.h>+  #if defined(GLFW_INCLUDE_GLEXT)+   #include <GLES2/gl2ext.h>+  #endif+ #elif defined(GLFW_INCLUDE_ES3)+  #include <GLES3/gl3.h>+  #if defined(GLFW_INCLUDE_GLEXT)+   #include <GLES2/gl2ext.h>+  #endif+ #elif defined(GLFW_INCLUDE_ES31)+  #include <GLES3/gl31.h>+  #if defined(GLFW_INCLUDE_GLEXT)+   #include <GLES2/gl2ext.h>+  #endif+ #elif defined(GLFW_INCLUDE_VULKAN)+  #include <vulkan/vulkan.h>+ #elif !defined(GLFW_INCLUDE_NONE)+  #include <GL/gl.h>+  #if defined(GLFW_INCLUDE_GLEXT)+   #include <GL/glext.h>+  #endif+ #endif+ #if defined(GLFW_INCLUDE_GLU)+  #include <GL/glu.h>+ #endif+#endif++#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)+ /* GLFW_DLL must be defined by applications that are linking against the DLL+  * version of the GLFW library.  _GLFW_BUILD_DLL is defined by the GLFW+  * configuration header when compiling the DLL version of the library.+  */+ #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"+#endif++/* GLFWAPI is used to declare public API functions for export+ * from the DLL / shared library / dynamic library.+ */+#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)+ /* We are building GLFW as a Win32 DLL */+ #define GLFWAPI __declspec(dllexport)+#elif defined(_WIN32) && defined(GLFW_DLL)+ /* We are calling GLFW as a Win32 DLL */+ #define GLFWAPI __declspec(dllimport)+#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)+ /* We are building GLFW as a shared / dynamic library */+ #define GLFWAPI __attribute__((visibility("default")))+#else+ /* We are building or calling GLFW as a static library */+ #define GLFWAPI+#endif+++/*************************************************************************+ * GLFW API tokens+ *************************************************************************/++/*! @name GLFW version macros+ *  @{ */+/*! @brief The major version number of the GLFW library.+ *+ *  This is incremented when the API is changed in non-compatible ways.+ *  @ingroup init+ */+#define GLFW_VERSION_MAJOR          3+/*! @brief The minor version number of the GLFW library.+ *+ *  This is incremented when features are added to the API but it remains+ *  backward-compatible.+ *  @ingroup init+ */+#define GLFW_VERSION_MINOR          2+/*! @brief The revision number of the GLFW library.+ *+ *  This is incremented when a bug fix release is made that does not contain any+ *  API changes.+ *  @ingroup init+ */+#define GLFW_VERSION_REVISION       1+/*! @} */++/*! @name Boolean values+ *  @{ */+/*! @brief One.+ *+ *  One.  Seriously.  You don't _need_ to use this symbol in your code.  It's+ *  just semantic sugar for the number 1.  You can use `1` or `true` or `_True`+ *  or `GL_TRUE` or whatever you want.+ */+#define GLFW_TRUE                   1+/*! @brief Zero.+ *+ *  Zero.  Seriously.  You don't _need_ to use this symbol in your code.  It's+ *  just just semantic sugar for the number 0.  You can use `0` or `false` or+ *  `_False` or `GL_FALSE` or whatever you want.+ */+#define GLFW_FALSE                  0+/*! @} */++/*! @name Key and button actions+ *  @{ */+/*! @brief The key or mouse button was released.+ *+ *  The key or mouse button was released.+ *+ *  @ingroup input+ */+#define GLFW_RELEASE                0+/*! @brief The key or mouse button was pressed.+ *+ *  The key or mouse button was pressed.+ *+ *  @ingroup input+ */+#define GLFW_PRESS                  1+/*! @brief The key was held down until it repeated.+ *+ *  The key was held down until it repeated.+ *+ *  @ingroup input+ */+#define GLFW_REPEAT                 2+/*! @} */++/*! @defgroup keys Keyboard keys+ *+ *  See [key input](@ref input_key) for how these are used.+ *+ *  These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),+ *  but re-arranged to map to 7-bit ASCII for printable keys (function keys are+ *  put in the 256+ range).+ *+ *  The naming of the key codes follow these rules:+ *   - The US keyboard layout is used+ *   - Names of printable alpha-numeric characters are used (e.g. "A", "R",+ *     "3", etc.)+ *   - For non-alphanumeric characters, Unicode:ish names are used (e.g.+ *     "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not+ *     correspond to the Unicode standard (usually for brevity)+ *   - Keys that lack a clear US mapping are named "WORLD_x"+ *   - For non-printable keys, custom names are used (e.g. "F4",+ *     "BACKSPACE", etc.)+ *+ *  @ingroup input+ *  @{+ */++/* The unknown key */+#define GLFW_KEY_UNKNOWN            -1++/* Printable keys */+#define GLFW_KEY_SPACE              32+#define GLFW_KEY_APOSTROPHE         39  /* ' */+#define GLFW_KEY_COMMA              44  /* , */+#define GLFW_KEY_MINUS              45  /* - */+#define GLFW_KEY_PERIOD             46  /* . */+#define GLFW_KEY_SLASH              47  /* / */+#define GLFW_KEY_0                  48+#define GLFW_KEY_1                  49+#define GLFW_KEY_2                  50+#define GLFW_KEY_3                  51+#define GLFW_KEY_4                  52+#define GLFW_KEY_5                  53+#define GLFW_KEY_6                  54+#define GLFW_KEY_7                  55+#define GLFW_KEY_8                  56+#define GLFW_KEY_9                  57+#define GLFW_KEY_SEMICOLON          59  /* ; */+#define GLFW_KEY_EQUAL              61  /* = */+#define GLFW_KEY_A                  65+#define GLFW_KEY_B                  66+#define GLFW_KEY_C                  67+#define GLFW_KEY_D                  68+#define GLFW_KEY_E                  69+#define GLFW_KEY_F                  70+#define GLFW_KEY_G                  71+#define GLFW_KEY_H                  72+#define GLFW_KEY_I                  73+#define GLFW_KEY_J                  74+#define GLFW_KEY_K                  75+#define GLFW_KEY_L                  76+#define GLFW_KEY_M                  77+#define GLFW_KEY_N                  78+#define GLFW_KEY_O                  79+#define GLFW_KEY_P                  80+#define GLFW_KEY_Q                  81+#define GLFW_KEY_R                  82+#define GLFW_KEY_S                  83+#define GLFW_KEY_T                  84+#define GLFW_KEY_U                  85+#define GLFW_KEY_V                  86+#define GLFW_KEY_W                  87+#define GLFW_KEY_X                  88+#define GLFW_KEY_Y                  89+#define GLFW_KEY_Z                  90+#define GLFW_KEY_LEFT_BRACKET       91  /* [ */+#define GLFW_KEY_BACKSLASH          92  /* \ */+#define GLFW_KEY_RIGHT_BRACKET      93  /* ] */+#define GLFW_KEY_GRAVE_ACCENT       96  /* ` */+#define GLFW_KEY_WORLD_1            161 /* non-US #1 */+#define GLFW_KEY_WORLD_2            162 /* non-US #2 */++/* Function keys */+#define GLFW_KEY_ESCAPE             256+#define GLFW_KEY_ENTER              257+#define GLFW_KEY_TAB                258+#define GLFW_KEY_BACKSPACE          259+#define GLFW_KEY_INSERT             260+#define GLFW_KEY_DELETE             261+#define GLFW_KEY_RIGHT              262+#define GLFW_KEY_LEFT               263+#define GLFW_KEY_DOWN               264+#define GLFW_KEY_UP                 265+#define GLFW_KEY_PAGE_UP            266+#define GLFW_KEY_PAGE_DOWN          267+#define GLFW_KEY_HOME               268+#define GLFW_KEY_END                269+#define GLFW_KEY_CAPS_LOCK          280+#define GLFW_KEY_SCROLL_LOCK        281+#define GLFW_KEY_NUM_LOCK           282+#define GLFW_KEY_PRINT_SCREEN       283+#define GLFW_KEY_PAUSE              284+#define GLFW_KEY_F1                 290+#define GLFW_KEY_F2                 291+#define GLFW_KEY_F3                 292+#define GLFW_KEY_F4                 293+#define GLFW_KEY_F5                 294+#define GLFW_KEY_F6                 295+#define GLFW_KEY_F7                 296+#define GLFW_KEY_F8                 297+#define GLFW_KEY_F9                 298+#define GLFW_KEY_F10                299+#define GLFW_KEY_F11                300+#define GLFW_KEY_F12                301+#define GLFW_KEY_F13                302+#define GLFW_KEY_F14                303+#define GLFW_KEY_F15                304+#define GLFW_KEY_F16                305+#define GLFW_KEY_F17                306+#define GLFW_KEY_F18                307+#define GLFW_KEY_F19                308+#define GLFW_KEY_F20                309+#define GLFW_KEY_F21                310+#define GLFW_KEY_F22                311+#define GLFW_KEY_F23                312+#define GLFW_KEY_F24                313+#define GLFW_KEY_F25                314+#define GLFW_KEY_KP_0               320+#define GLFW_KEY_KP_1               321+#define GLFW_KEY_KP_2               322+#define GLFW_KEY_KP_3               323+#define GLFW_KEY_KP_4               324+#define GLFW_KEY_KP_5               325+#define GLFW_KEY_KP_6               326+#define GLFW_KEY_KP_7               327+#define GLFW_KEY_KP_8               328+#define GLFW_KEY_KP_9               329+#define GLFW_KEY_KP_DECIMAL         330+#define GLFW_KEY_KP_DIVIDE          331+#define GLFW_KEY_KP_MULTIPLY        332+#define GLFW_KEY_KP_SUBTRACT        333+#define GLFW_KEY_KP_ADD             334+#define GLFW_KEY_KP_ENTER           335+#define GLFW_KEY_KP_EQUAL           336+#define GLFW_KEY_LEFT_SHIFT         340+#define GLFW_KEY_LEFT_CONTROL       341+#define GLFW_KEY_LEFT_ALT           342+#define GLFW_KEY_LEFT_SUPER         343+#define GLFW_KEY_RIGHT_SHIFT        344+#define GLFW_KEY_RIGHT_CONTROL      345+#define GLFW_KEY_RIGHT_ALT          346+#define GLFW_KEY_RIGHT_SUPER        347+#define GLFW_KEY_MENU               348++#define GLFW_KEY_LAST               GLFW_KEY_MENU++/*! @} */++/*! @defgroup mods Modifier key flags+ *+ *  See [key input](@ref input_key) for how these are used.+ *+ *  @ingroup input+ *  @{ */++/*! @brief If this bit is set one or more Shift keys were held down.+ */+#define GLFW_MOD_SHIFT           0x0001+/*! @brief If this bit is set one or more Control keys were held down.+ */+#define GLFW_MOD_CONTROL         0x0002+/*! @brief If this bit is set one or more Alt keys were held down.+ */+#define GLFW_MOD_ALT             0x0004+/*! @brief If this bit is set one or more Super keys were held down.+ */+#define GLFW_MOD_SUPER           0x0008++/*! @} */++/*! @defgroup buttons Mouse buttons+ *+ *  See [mouse button input](@ref input_mouse_button) for how these are used.+ *+ *  @ingroup input+ *  @{ */+#define GLFW_MOUSE_BUTTON_1         0+#define GLFW_MOUSE_BUTTON_2         1+#define GLFW_MOUSE_BUTTON_3         2+#define GLFW_MOUSE_BUTTON_4         3+#define GLFW_MOUSE_BUTTON_5         4+#define GLFW_MOUSE_BUTTON_6         5+#define GLFW_MOUSE_BUTTON_7         6+#define GLFW_MOUSE_BUTTON_8         7+#define GLFW_MOUSE_BUTTON_LAST      GLFW_MOUSE_BUTTON_8+#define GLFW_MOUSE_BUTTON_LEFT      GLFW_MOUSE_BUTTON_1+#define GLFW_MOUSE_BUTTON_RIGHT     GLFW_MOUSE_BUTTON_2+#define GLFW_MOUSE_BUTTON_MIDDLE    GLFW_MOUSE_BUTTON_3+/*! @} */++/*! @defgroup joysticks Joysticks+ *+ *  See [joystick input](@ref joystick) for how these are used.+ *+ *  @ingroup input+ *  @{ */+#define GLFW_JOYSTICK_1             0+#define GLFW_JOYSTICK_2             1+#define GLFW_JOYSTICK_3             2+#define GLFW_JOYSTICK_4             3+#define GLFW_JOYSTICK_5             4+#define GLFW_JOYSTICK_6             5+#define GLFW_JOYSTICK_7             6+#define GLFW_JOYSTICK_8             7+#define GLFW_JOYSTICK_9             8+#define GLFW_JOYSTICK_10            9+#define GLFW_JOYSTICK_11            10+#define GLFW_JOYSTICK_12            11+#define GLFW_JOYSTICK_13            12+#define GLFW_JOYSTICK_14            13+#define GLFW_JOYSTICK_15            14+#define GLFW_JOYSTICK_16            15+#define GLFW_JOYSTICK_LAST          GLFW_JOYSTICK_16+/*! @} */++/*! @defgroup errors Error codes+ *+ *  See [error handling](@ref error_handling) for how these are used.+ *+ *  @ingroup init+ *  @{ */+/*! @brief GLFW has not been initialized.+ *+ *  This occurs if a GLFW function was called that must not be called unless the+ *  library is [initialized](@ref intro_init).+ *+ *  @analysis Application programmer error.  Initialize GLFW before calling any+ *  function that requires initialization.+ */+#define GLFW_NOT_INITIALIZED        0x00010001+/*! @brief No context is current for this thread.+ *+ *  This occurs if a GLFW function was called that needs and operates on the+ *  current OpenGL or OpenGL ES context but no context is current on the calling+ *  thread.  One such function is @ref glfwSwapInterval.+ *+ *  @analysis Application programmer error.  Ensure a context is current before+ *  calling functions that require a current context.+ */+#define GLFW_NO_CURRENT_CONTEXT     0x00010002+/*! @brief One of the arguments to the function was an invalid enum value.+ *+ *  One of the arguments to the function was an invalid enum value, for example+ *  requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref+ *  glfwGetWindowAttrib.+ *+ *  @analysis Application programmer error.  Fix the offending call.+ */+#define GLFW_INVALID_ENUM           0x00010003+/*! @brief One of the arguments to the function was an invalid value.+ *+ *  One of the arguments to the function was an invalid value, for example+ *  requesting a non-existent OpenGL or OpenGL ES version like 2.7.+ *+ *  Requesting a valid but unavailable OpenGL or OpenGL ES version will instead+ *  result in a @ref GLFW_VERSION_UNAVAILABLE error.+ *+ *  @analysis Application programmer error.  Fix the offending call.+ */+#define GLFW_INVALID_VALUE          0x00010004+/*! @brief A memory allocation failed.+ *+ *  A memory allocation failed.+ *+ *  @analysis A bug in GLFW or the underlying operating system.  Report the bug+ *  to our [issue tracker](https://github.com/glfw/glfw/issues).+ */+#define GLFW_OUT_OF_MEMORY          0x00010005+/*! @brief GLFW could not find support for the requested API on the system.+ *+ *  GLFW could not find support for the requested API on the system.+ *+ *  @analysis The installed graphics driver does not support the requested+ *  API, or does not support it via the chosen context creation backend.+ *  Below are a few examples.+ *+ *  @par+ *  Some pre-installed Windows graphics drivers do not support OpenGL.  AMD only+ *  supports OpenGL ES via EGL, while Nvidia and Intel only support it via+ *  a WGL or GLX extension.  OS X does not provide OpenGL ES at all.  The Mesa+ *  EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary+ *  driver.  Older graphics drivers do not support Vulkan.+ */+#define GLFW_API_UNAVAILABLE        0x00010006+/*! @brief The requested OpenGL or OpenGL ES version is not available.+ *+ *  The requested OpenGL or OpenGL ES version (including any requested context+ *  or framebuffer hints) is not available on this machine.+ *+ *  @analysis The machine does not support your requirements.  If your+ *  application is sufficiently flexible, downgrade your requirements and try+ *  again.  Otherwise, inform the user that their machine does not match your+ *  requirements.+ *+ *  @par+ *  Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0+ *  comes out before the 4.x series gets that far, also fail with this error and+ *  not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions+ *  will exist.+ */+#define GLFW_VERSION_UNAVAILABLE    0x00010007+/*! @brief A platform-specific error occurred that does not match any of the+ *  more specific categories.+ *+ *  A platform-specific error occurred that does not match any of the more+ *  specific categories.+ *+ *  @analysis A bug or configuration error in GLFW, the underlying operating+ *  system or its drivers, or a lack of required resources.  Report the issue to+ *  our [issue tracker](https://github.com/glfw/glfw/issues).+ */+#define GLFW_PLATFORM_ERROR         0x00010008+/*! @brief The requested format is not supported or available.+ *+ *  If emitted during window creation, the requested pixel format is not+ *  supported.+ *+ *  If emitted when querying the clipboard, the contents of the clipboard could+ *  not be converted to the requested format.+ *+ *  @analysis If emitted during window creation, one or more+ *  [hard constraints](@ref window_hints_hard) did not match any of the+ *  available pixel formats.  If your application is sufficiently flexible,+ *  downgrade your requirements and try again.  Otherwise, inform the user that+ *  their machine does not match your requirements.+ *+ *  @par+ *  If emitted when querying the clipboard, ignore the error or report it to+ *  the user, as appropriate.+ */+#define GLFW_FORMAT_UNAVAILABLE     0x00010009+/*! @brief The specified window does not have an OpenGL or OpenGL ES context.+ *+ *  A window that does not have an OpenGL or OpenGL ES context was passed to+ *  a function that requires it to have one.+ *+ *  @analysis Application programmer error.  Fix the offending call.+ */+#define GLFW_NO_WINDOW_CONTEXT      0x0001000A+/*! @} */++#define GLFW_FOCUSED                0x00020001+#define GLFW_ICONIFIED              0x00020002+#define GLFW_RESIZABLE              0x00020003+#define GLFW_VISIBLE                0x00020004+#define GLFW_DECORATED              0x00020005+#define GLFW_AUTO_ICONIFY           0x00020006+#define GLFW_FLOATING               0x00020007+#define GLFW_MAXIMIZED              0x00020008++#define GLFW_RED_BITS               0x00021001+#define GLFW_GREEN_BITS             0x00021002+#define GLFW_BLUE_BITS              0x00021003+#define GLFW_ALPHA_BITS             0x00021004+#define GLFW_DEPTH_BITS             0x00021005+#define GLFW_STENCIL_BITS           0x00021006+#define GLFW_ACCUM_RED_BITS         0x00021007+#define GLFW_ACCUM_GREEN_BITS       0x00021008+#define GLFW_ACCUM_BLUE_BITS        0x00021009+#define GLFW_ACCUM_ALPHA_BITS       0x0002100A+#define GLFW_AUX_BUFFERS            0x0002100B+#define GLFW_STEREO                 0x0002100C+#define GLFW_SAMPLES                0x0002100D+#define GLFW_SRGB_CAPABLE           0x0002100E+#define GLFW_REFRESH_RATE           0x0002100F+#define GLFW_DOUBLEBUFFER           0x00021010++#define GLFW_CLIENT_API             0x00022001+#define GLFW_CONTEXT_VERSION_MAJOR  0x00022002+#define GLFW_CONTEXT_VERSION_MINOR  0x00022003+#define GLFW_CONTEXT_REVISION       0x00022004+#define GLFW_CONTEXT_ROBUSTNESS     0x00022005+#define GLFW_OPENGL_FORWARD_COMPAT  0x00022006+#define GLFW_OPENGL_DEBUG_CONTEXT   0x00022007+#define GLFW_OPENGL_PROFILE         0x00022008+#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009+#define GLFW_CONTEXT_NO_ERROR       0x0002200A+#define GLFW_CONTEXT_CREATION_API   0x0002200B++#define GLFW_NO_API                          0+#define GLFW_OPENGL_API             0x00030001+#define GLFW_OPENGL_ES_API          0x00030002++#define GLFW_NO_ROBUSTNESS                   0+#define GLFW_NO_RESET_NOTIFICATION  0x00031001+#define GLFW_LOSE_CONTEXT_ON_RESET  0x00031002++#define GLFW_OPENGL_ANY_PROFILE              0+#define GLFW_OPENGL_CORE_PROFILE    0x00032001+#define GLFW_OPENGL_COMPAT_PROFILE  0x00032002++#define GLFW_CURSOR                 0x00033001+#define GLFW_STICKY_KEYS            0x00033002+#define GLFW_STICKY_MOUSE_BUTTONS   0x00033003++#define GLFW_CURSOR_NORMAL          0x00034001+#define GLFW_CURSOR_HIDDEN          0x00034002+#define GLFW_CURSOR_DISABLED        0x00034003++#define GLFW_ANY_RELEASE_BEHAVIOR            0+#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001+#define GLFW_RELEASE_BEHAVIOR_NONE  0x00035002++#define GLFW_NATIVE_CONTEXT_API     0x00036001+#define GLFW_EGL_CONTEXT_API        0x00036002++/*! @defgroup shapes Standard cursor shapes+ *+ *  See [standard cursor creation](@ref cursor_standard) for how these are used.+ *+ *  @ingroup input+ *  @{ */++/*! @brief The regular arrow cursor shape.+ *+ *  The regular arrow cursor.+ */+#define GLFW_ARROW_CURSOR           0x00036001+/*! @brief The text input I-beam cursor shape.+ *+ *  The text input I-beam cursor shape.+ */+#define GLFW_IBEAM_CURSOR           0x00036002+/*! @brief The crosshair shape.+ *+ *  The crosshair shape.+ */+#define GLFW_CROSSHAIR_CURSOR       0x00036003+/*! @brief The hand shape.+ *+ *  The hand shape.+ */+#define GLFW_HAND_CURSOR            0x00036004+/*! @brief The horizontal resize arrow shape.+ *+ *  The horizontal resize arrow shape.+ */+#define GLFW_HRESIZE_CURSOR         0x00036005+/*! @brief The vertical resize arrow shape.+ *+ *  The vertical resize arrow shape.+ */+#define GLFW_VRESIZE_CURSOR         0x00036006+/*! @} */++#define GLFW_CONNECTED              0x00040001+#define GLFW_DISCONNECTED           0x00040002++#define GLFW_DONT_CARE              -1+++/*************************************************************************+ * GLFW API types+ *************************************************************************/++/*! @brief Client API function pointer type.+ *+ *  Generic function pointer used for returning client API function pointers+ *  without forcing a cast from a regular pointer.+ *+ *  @sa @ref context_glext+ *  @sa glfwGetProcAddress+ *+ *  @since Added in version 3.0.+ + *  @ingroup context+ */+typedef void (*GLFWglproc)(void);++/*! @brief Vulkan API function pointer type.+ *+ *  Generic function pointer used for returning Vulkan API function pointers+ *  without forcing a cast from a regular pointer.+ *+ *  @sa @ref vulkan_proc+ *  @sa glfwGetInstanceProcAddress+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup vulkan+ */+typedef void (*GLFWvkproc)(void);++/*! @brief Opaque monitor object.+ *+ *  Opaque monitor object.+ *+ *  @see @ref monitor_object+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+typedef struct GLFWmonitor GLFWmonitor;++/*! @brief Opaque window object.+ *+ *  Opaque window object.+ *+ *  @see @ref window_object+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+typedef struct GLFWwindow GLFWwindow;++/*! @brief Opaque cursor object.+ *+ *  Opaque cursor object.+ *+ *  @see @ref cursor_object+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup cursor+ */+typedef struct GLFWcursor GLFWcursor;++/*! @brief The function signature for error callbacks.+ *+ *  This is the function signature for error callback functions.+ *+ *  @param[in] error An [error code](@ref errors).+ *  @param[in] description A UTF-8 encoded string describing the error.+ *+ *  @sa @ref error_handling+ *  @sa glfwSetErrorCallback+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup init+ */+typedef void (* GLFWerrorfun)(int,const char*);++/*! @brief The function signature for window position callbacks.+ *+ *  This is the function signature for window position callback functions.+ *+ *  @param[in] window The window that was moved.+ *  @param[in] xpos The new x-coordinate, in screen coordinates, of the+ *  upper-left corner of the client area of the window.+ *  @param[in] ypos The new y-coordinate, in screen coordinates, of the+ *  upper-left corner of the client area of the window.+ *+ *  @sa @ref window_pos+ *  @sa glfwSetWindowPosCallback+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);++/*! @brief The function signature for window resize callbacks.+ *+ *  This is the function signature for window size callback functions.+ *+ *  @param[in] window The window that was resized.+ *  @param[in] width The new width, in screen coordinates, of the window.+ *  @param[in] height The new height, in screen coordinates, of the window.+ *+ *  @sa @ref window_size+ *  @sa glfwSetWindowSizeCallback+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);++/*! @brief The function signature for window close callbacks.+ *+ *  This is the function signature for window close callback functions.+ *+ *  @param[in] window The window that the user attempted to close.+ *+ *  @sa @ref window_close+ *  @sa glfwSetWindowCloseCallback+ *+ *  @since Added in version 2.5.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+typedef void (* GLFWwindowclosefun)(GLFWwindow*);++/*! @brief The function signature for window content refresh callbacks.+ *+ *  This is the function signature for window refresh callback functions.+ *+ *  @param[in] window The window whose content needs to be refreshed.+ *+ *  @sa @ref window_refresh+ *  @sa glfwSetWindowRefreshCallback+ *+ *  @since Added in version 2.5.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);++/*! @brief The function signature for window focus/defocus callbacks.+ *+ *  This is the function signature for window focus callback functions.+ *+ *  @param[in] window The window that gained or lost input focus.+ *  @param[in] focused `GLFW_TRUE` if the window was given input focus, or+ *  `GLFW_FALSE` if it lost it.+ *+ *  @sa @ref window_focus+ *  @sa glfwSetWindowFocusCallback+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);++/*! @brief The function signature for window iconify/restore callbacks.+ *+ *  This is the function signature for window iconify/restore callback+ *  functions.+ *+ *  @param[in] window The window that was iconified or restored.+ *  @param[in] iconified `GLFW_TRUE` if the window was iconified, or+ *  `GLFW_FALSE` if it was restored.+ *+ *  @sa @ref window_iconify+ *  @sa glfwSetWindowIconifyCallback+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);++/*! @brief The function signature for framebuffer resize callbacks.+ *+ *  This is the function signature for framebuffer resize callback+ *  functions.+ *+ *  @param[in] window The window whose framebuffer was resized.+ *  @param[in] width The new width, in pixels, of the framebuffer.+ *  @param[in] height The new height, in pixels, of the framebuffer.+ *+ *  @sa @ref window_fbsize+ *  @sa glfwSetFramebufferSizeCallback+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);++/*! @brief The function signature for mouse button callbacks.+ *+ *  This is the function signature for mouse button callback functions.+ *+ *  @param[in] window The window that received the event.+ *  @param[in] button The [mouse button](@ref buttons) that was pressed or+ *  released.+ *  @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.+ *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were+ *  held down.+ *+ *  @sa @ref input_mouse_button+ *  @sa glfwSetMouseButtonCallback+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle and modifier mask parameters.+ *+ *  @ingroup input+ */+typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);++/*! @brief The function signature for cursor position callbacks.+ *+ *  This is the function signature for cursor position callback functions.+ *+ *  @param[in] window The window that received the event.+ *  @param[in] xpos The new cursor x-coordinate, relative to the left edge of+ *  the client area.+ *  @param[in] ypos The new cursor y-coordinate, relative to the top edge of the+ *  client area.+ *+ *  @sa @ref cursor_pos+ *  @sa glfwSetCursorPosCallback+ *+ *  @since Added in version 3.0.  Replaces `GLFWmouseposfun`.+ *+ *  @ingroup input+ */+typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);++/*! @brief The function signature for cursor enter/leave callbacks.+ *+ *  This is the function signature for cursor enter/leave callback functions.+ *+ *  @param[in] window The window that received the event.+ *  @param[in] entered `GLFW_TRUE` if the cursor entered the window's client+ *  area, or `GLFW_FALSE` if it left it.+ *+ *  @sa @ref cursor_enter+ *  @sa glfwSetCursorEnterCallback+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup input+ */+typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);++/*! @brief The function signature for scroll callbacks.+ *+ *  This is the function signature for scroll callback functions.+ *+ *  @param[in] window The window that received the event.+ *  @param[in] xoffset The scroll offset along the x-axis.+ *  @param[in] yoffset The scroll offset along the y-axis.+ *+ *  @sa @ref scrolling+ *  @sa glfwSetScrollCallback+ *+ *  @since Added in version 3.0.  Replaces `GLFWmousewheelfun`.+ *+ *  @ingroup input+ */+typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);++/*! @brief The function signature for keyboard key callbacks.+ *+ *  This is the function signature for keyboard key callback functions.+ *+ *  @param[in] window The window that received the event.+ *  @param[in] key The [keyboard key](@ref keys) that was pressed or released.+ *  @param[in] scancode The system-specific scancode of the key.+ *  @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.+ *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were+ *  held down.+ *+ *  @sa @ref input_key+ *  @sa glfwSetKeyCallback+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle, scancode and modifier mask parameters.+ *+ *  @ingroup input+ */+typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);++/*! @brief The function signature for Unicode character callbacks.+ *+ *  This is the function signature for Unicode character callback functions.+ *+ *  @param[in] window The window that received the event.+ *  @param[in] codepoint The Unicode code point of the character.+ *+ *  @sa @ref input_char+ *  @sa glfwSetCharCallback+ *+ *  @since Added in version 2.4.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup input+ */+typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);++/*! @brief The function signature for Unicode character with modifiers+ *  callbacks.+ *+ *  This is the function signature for Unicode character with modifiers callback+ *  functions.  It is called for each input character, regardless of what+ *  modifier keys are held down.+ *+ *  @param[in] window The window that received the event.+ *  @param[in] codepoint The Unicode code point of the character.+ *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were+ *  held down.+ *+ *  @sa @ref input_char+ *  @sa glfwSetCharModsCallback+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup input+ */+typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);++/*! @brief The function signature for file drop callbacks.+ *+ *  This is the function signature for file drop callbacks.+ *+ *  @param[in] window The window that received the event.+ *  @param[in] count The number of dropped files.+ *  @param[in] paths The UTF-8 encoded file and/or directory path names.+ *+ *  @sa @ref path_drop+ *  @sa glfwSetDropCallback+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup input+ */+typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);++/*! @brief The function signature for monitor configuration callbacks.+ *+ *  This is the function signature for monitor configuration callback functions.+ *+ *  @param[in] monitor The monitor that was connected or disconnected.+ *  @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.+ *+ *  @sa @ref monitor_event+ *  @sa glfwSetMonitorCallback+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);++/*! @brief The function signature for joystick configuration callbacks.+ *+ *  This is the function signature for joystick configuration callback+ *  functions.+ *+ *  @param[in] joy The joystick that was connected or disconnected.+ *  @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.+ *+ *  @sa @ref joystick_event+ *  @sa glfwSetJoystickCallback+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup input+ */+typedef void (* GLFWjoystickfun)(int,int);++/*! @brief Video mode type.+ *+ *  This describes a single video mode.+ *+ *  @sa @ref monitor_modes+ *  @sa glfwGetVideoMode glfwGetVideoModes+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added refresh rate member.+ *+ *  @ingroup monitor+ */+typedef struct GLFWvidmode+{+    /*! The width, in screen coordinates, of the video mode.+     */+    int width;+    /*! The height, in screen coordinates, of the video mode.+     */+    int height;+    /*! The bit depth of the red channel of the video mode.+     */+    int redBits;+    /*! The bit depth of the green channel of the video mode.+     */+    int greenBits;+    /*! The bit depth of the blue channel of the video mode.+     */+    int blueBits;+    /*! The refresh rate, in Hz, of the video mode.+     */+    int refreshRate;+} GLFWvidmode;++/*! @brief Gamma ramp.+ *+ *  This describes the gamma ramp for a monitor.+ *+ *  @sa @ref monitor_gamma+ *  @sa glfwGetGammaRamp glfwSetGammaRamp+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+typedef struct GLFWgammaramp+{+    /*! An array of value describing the response of the red channel.+     */+    unsigned short* red;+    /*! An array of value describing the response of the green channel.+     */+    unsigned short* green;+    /*! An array of value describing the response of the blue channel.+     */+    unsigned short* blue;+    /*! The number of elements in each array.+     */+    unsigned int size;+} GLFWgammaramp;++/*! @brief Image data.+ *+ *  @sa @ref cursor_custom+ *  @sa @ref window_icon+ *+ *  @since Added in version 2.1.+ *  @glfw3 Removed format and bytes-per-pixel members.+ */+typedef struct GLFWimage+{+    /*! The width, in pixels, of this image.+     */+    int width;+    /*! The height, in pixels, of this image.+     */+    int height;+    /*! The pixel data of this image, arranged left-to-right, top-to-bottom.+     */+    unsigned char* pixels;+} GLFWimage;+++/*************************************************************************+ * GLFW API functions+ *************************************************************************/++/*! @brief Initializes the GLFW library.+ *+ *  This function initializes the GLFW library.  Before most GLFW functions can+ *  be used, GLFW must be initialized, and before an application terminates GLFW+ *  should be terminated in order to free any resources allocated during or+ *  after initialization.+ *+ *  If this function fails, it calls @ref glfwTerminate before returning.  If it+ *  succeeds, you should call @ref glfwTerminate before the application exits.+ *+ *  Additional calls to this function after successful initialization but before+ *  termination will return `GLFW_TRUE` immediately.+ *+ *  @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_PLATFORM_ERROR.+ *+ *  @remark @osx This function will change the current directory of the+ *  application to the `Contents/Resources` subdirectory of the application's+ *  bundle, if present.  This can be disabled with a+ *  [compile-time option](@ref compile_options_osx).+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref intro_init+ *  @sa glfwTerminate+ *+ *  @since Added in version 1.0.+ *+ *  @ingroup init+ */+GLFWAPI int glfwInit(void);++/*! @brief Terminates the GLFW library.+ *+ *  This function destroys all remaining windows and cursors, restores any+ *  modified gamma ramps and frees any other allocated resources.  Once this+ *  function is called, you must again call @ref glfwInit successfully before+ *  you will be able to use most GLFW functions.+ *+ *  If GLFW has been successfully initialized, this function should be called+ *  before the application exits.  If initialization fails, there is no need to+ *  call this function, as it is called by @ref glfwInit before it returns+ *  failure.+ *+ *  @errors Possible errors include @ref GLFW_PLATFORM_ERROR.+ *+ *  @remark This function may be called before @ref glfwInit.+ *+ *  @warning The contexts of any remaining windows must not be current on any+ *  other thread when this function is called.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref intro_init+ *  @sa glfwInit+ *+ *  @since Added in version 1.0.+ *+ *  @ingroup init+ */+GLFWAPI void glfwTerminate(void);++/*! @brief Retrieves the version of the GLFW library.+ *+ *  This function retrieves the major, minor and revision numbers of the GLFW+ *  library.  It is intended for when you are using GLFW as a shared library and+ *  want to ensure that you are using the minimum required version.+ *+ *  Any or all of the version arguments may be `NULL`.+ *+ *  @param[out] major Where to store the major version number, or `NULL`.+ *  @param[out] minor Where to store the minor version number, or `NULL`.+ *  @param[out] rev Where to store the revision number, or `NULL`.+ *+ *  @errors None.+ *+ *  @remark This function may be called before @ref glfwInit.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref intro_version+ *  @sa glfwGetVersionString+ *+ *  @since Added in version 1.0.+ *+ *  @ingroup init+ */+GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);++/*! @brief Returns a string describing the compile-time configuration.+ *+ *  This function returns the compile-time generated+ *  [version string](@ref intro_version_string) of the GLFW library binary.  It+ *  describes the version, platform, compiler and any platform-specific+ *  compile-time options.  It should not be confused with the OpenGL or OpenGL+ *  ES version string, queried with `glGetString`.+ *+ *  __Do not use the version string__ to parse the GLFW library version.  The+ *  @ref glfwGetVersion function provides the version of the running library+ *  binary in numerical format.+ *+ *  @return The ASCII encoded GLFW version string.+ *+ *  @errors None.+ *+ *  @remark This function may be called before @ref glfwInit.+ *+ *  @pointer_lifetime The returned string is static and compile-time generated.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref intro_version+ *  @sa glfwGetVersion+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup init+ */+GLFWAPI const char* glfwGetVersionString(void);++/*! @brief Sets the error callback.+ *+ *  This function sets the error callback, which is called with an error code+ *  and a human-readable description each time a GLFW error occurs.+ *+ *  The error callback is called on the thread where the error occurred.  If you+ *  are using GLFW from multiple threads, your error callback needs to be+ *  written accordingly.+ *+ *  Because the description string may have been generated specifically for that+ *  error, it is not guaranteed to be valid after the callback has returned.  If+ *  you wish to use it after the callback returns, you need to make a copy.+ *+ *  Once set, the error callback remains set even after the library has been+ *  terminated.+ *+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set.+ *+ *  @errors None.+ *+ *  @remark This function may be called before @ref glfwInit.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref error_handling+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup init+ */+GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);++/*! @brief Returns the currently connected monitors.+ *+ *  This function returns an array of handles for all currently connected+ *  monitors.  The primary monitor is always first in the returned array.  If no+ *  monitors were found, this function returns `NULL`.+ *+ *  @param[out] count Where to store the number of monitors in the returned+ *  array.  This is set to zero if an error occurred.+ *  @return An array of monitor handles, or `NULL` if no monitors were found or+ *  if an [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is guaranteed to be valid only until the+ *  monitor configuration changes or the library is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_monitors+ *  @sa @ref monitor_event+ *  @sa glfwGetPrimaryMonitor+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);++/*! @brief Returns the primary monitor.+ *+ *  This function returns the primary monitor.  This is usually the monitor+ *  where elements like the task bar or global menu bar are located.+ *+ *  @return The primary monitor, or `NULL` if no monitors were found or if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @remark The primary monitor is always first in the array returned by @ref+ *  glfwGetMonitors.+ *+ *  @sa @ref monitor_monitors+ *  @sa glfwGetMonitors+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);++/*! @brief Returns the position of the monitor's viewport on the virtual screen.+ *+ *  This function returns the position, in screen coordinates, of the upper-left+ *  corner of the specified monitor.+ *+ *  Any or all of the position arguments may be `NULL`.  If an error occurs, all+ *  non-`NULL` position arguments will be set to zero.+ *+ *  @param[in] monitor The monitor to query.+ *  @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.+ *  @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_properties+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);++/*! @brief Returns the physical size of the monitor.+ *+ *  This function returns the size, in millimetres, of the display area of the+ *  specified monitor.+ *+ *  Some systems do not provide accurate monitor size information, either+ *  because the monitor+ *  [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)+ *  data is incorrect or because the driver does not report it accurately.+ *+ *  Any or all of the size arguments may be `NULL`.  If an error occurs, all+ *  non-`NULL` size arguments will be set to zero.+ *+ *  @param[in] monitor The monitor to query.+ *  @param[out] widthMM Where to store the width, in millimetres, of the+ *  monitor's display area, or `NULL`.+ *  @param[out] heightMM Where to store the height, in millimetres, of the+ *  monitor's display area, or `NULL`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @remark @win32 calculates the returned physical size from the+ *  current resolution and system DPI instead of querying the monitor EDID data.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_properties+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);++/*! @brief Returns the name of the specified monitor.+ *+ *  This function returns a human-readable name, encoded as UTF-8, of the+ *  specified monitor.  The name typically reflects the make and model of the+ *  monitor and is not guaranteed to be unique among the connected monitors.+ *+ *  @param[in] monitor The monitor to query.+ *  @return The UTF-8 encoded name of the monitor, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is valid until the specified monitor is+ *  disconnected or the library is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_properties+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);++/*! @brief Sets the monitor configuration callback.+ *+ *  This function sets the monitor configuration callback, or removes the+ *  currently set callback.  This is called when a monitor is connected to or+ *  disconnected from the system.+ *+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_event+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);++/*! @brief Returns the available video modes for the specified monitor.+ *+ *  This function returns an array of all video modes supported by the specified+ *  monitor.  The returned array is sorted in ascending order, first by color+ *  bit depth (the sum of all channel depths) and then by resolution area (the+ *  product of width and height).+ *+ *  @param[in] monitor The monitor to query.+ *  @param[out] count Where to store the number of video modes in the returned+ *  array.  This is set to zero if an error occurred.+ *  @return An array of video modes, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is valid until the specified monitor is+ *  disconnected, this function is called again for that monitor or the library+ *  is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_modes+ *  @sa glfwGetVideoMode+ *+ *  @since Added in version 1.0.+ *  @glfw3 Changed to return an array of modes for a specific monitor.+ *+ *  @ingroup monitor+ */+GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);++/*! @brief Returns the current mode of the specified monitor.+ *+ *  This function returns the current video mode of the specified monitor.  If+ *  you have created a full screen window for that monitor, the return value+ *  will depend on whether that window is iconified.+ *+ *  @param[in] monitor The monitor to query.+ *  @return The current mode of the monitor, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is valid until the specified monitor is+ *  disconnected or the library is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_modes+ *  @sa glfwGetVideoModes+ *+ *  @since Added in version 3.0.  Replaces `glfwGetDesktopMode`.+ *+ *  @ingroup monitor+ */+GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);++/*! @brief Generates a gamma ramp and sets it for the specified monitor.+ *+ *  This function generates a 256-element gamma ramp from the specified exponent+ *  and then calls @ref glfwSetGammaRamp with it.  The value must be a finite+ *  number greater than zero.+ *+ *  @param[in] monitor The monitor whose gamma ramp to set.+ *  @param[in] gamma The desired exponent.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_gamma+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);++/*! @brief Returns the current gamma ramp for the specified monitor.+ *+ *  This function returns the current gamma ramp of the specified monitor.+ *+ *  @param[in] monitor The monitor to query.+ *  @return The current gamma ramp, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The returned structure and its arrays are allocated and+ *  freed by GLFW.  You should not free them yourself.  They are valid until the+ *  specified monitor is disconnected, this function is called again for that+ *  monitor or the library is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_gamma+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);++/*! @brief Sets the current gamma ramp for the specified monitor.+ *+ *  This function sets the current gamma ramp for the specified monitor.  The+ *  original gamma ramp for that monitor is saved by GLFW the first time this+ *  function is called and is restored by @ref glfwTerminate.+ *+ *  @param[in] monitor The monitor whose gamma ramp to set.+ *  @param[in] ramp The gamma ramp to use.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @remark Gamma ramp sizes other than 256 are not supported by all platforms+ *  or graphics hardware.+ *+ *  @remark @win32 The gamma ramp size must be 256.+ *+ *  @pointer_lifetime The specified gamma ramp is copied before this function+ *  returns.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref monitor_gamma+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup monitor+ */+GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);++/*! @brief Resets all window hints to their default values.+ *+ *  This function resets all window hints to their+ *  [default values](@ref window_hints_values).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_hints+ *  @sa glfwWindowHint+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI void glfwDefaultWindowHints(void);++/*! @brief Sets the specified window hint to the desired value.+ *+ *  This function sets hints for the next call to @ref glfwCreateWindow.  The+ *  hints, once set, retain their values until changed by a call to @ref+ *  glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is+ *  terminated.+ *+ *  This function does not check whether the specified hint values are valid.+ *  If you set hints to invalid values this will instead be reported by the next+ *  call to @ref glfwCreateWindow.+ *+ *  @param[in] hint The [window hint](@ref window_hints) to set.+ *  @param[in] value The new value of the window hint.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_INVALID_ENUM.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_hints+ *  @sa glfwDefaultWindowHints+ *+ *  @since Added in version 3.0.  Replaces `glfwOpenWindowHint`.+ *+ *  @ingroup window+ */+GLFWAPI void glfwWindowHint(int hint, int value);++/*! @brief Creates a window and its associated context.+ *+ *  This function creates a window and its associated OpenGL or OpenGL ES+ *  context.  Most of the options controlling how the window and its context+ *  should be created are specified with [window hints](@ref window_hints).+ *+ *  Successful creation does not change which context is current.  Before you+ *  can use the newly created context, you need to+ *  [make it current](@ref context_current).  For information about the `share`+ *  parameter, see @ref context_sharing.+ *+ *  The created window, framebuffer and context may differ from what you+ *  requested, as not all parameters and hints are+ *  [hard constraints](@ref window_hints_hard).  This includes the size of the+ *  window, especially for full screen windows.  To query the actual attributes+ *  of the created window, framebuffer and context, see @ref+ *  glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.+ *+ *  To create a full screen window, you need to specify the monitor the window+ *  will cover.  If no monitor is specified, the window will be windowed mode.+ *  Unless you have a way for the user to choose a specific monitor, it is+ *  recommended that you pick the primary monitor.  For more information on how+ *  to query connected monitors, see @ref monitor_monitors.+ *+ *  For full screen windows, the specified size becomes the resolution of the+ *  window's _desired video mode_.  As long as a full screen window is not+ *  iconified, the supported video mode most closely matching the desired video+ *  mode is set for the specified monitor.  For more information about full+ *  screen windows, including the creation of so called _windowed full screen_+ *  or _borderless full screen_ windows, see @ref window_windowed_full_screen.+ *+ *  Once you have created the window, you can switch it between windowed and+ *  full screen mode with @ref glfwSetWindowMonitor.  If the window has an+ *  OpenGL or OpenGL ES context, it will be unaffected.+ *+ *  By default, newly created windows use the placement recommended by the+ *  window system.  To create the window at a specific position, make it+ *  initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window+ *  hint, set its [position](@ref window_pos) and then [show](@ref window_hide)+ *  it.+ *+ *  As long as at least one full screen window is not iconified, the screensaver+ *  is prohibited from starting.+ *+ *  Window systems put limits on window sizes.  Very large or very small window+ *  dimensions may be overridden by the window system on creation.  Check the+ *  actual [size](@ref window_size) after creation.+ *+ *  The [swap interval](@ref buffer_swap) is not set during window creation and+ *  the initial value may vary depending on driver settings and defaults.+ *+ *  @param[in] width The desired width, in screen coordinates, of the window.+ *  This must be greater than zero.+ *  @param[in] height The desired height, in screen coordinates, of the window.+ *  This must be greater than zero.+ *  @param[in] title The initial, UTF-8 encoded window title.+ *  @param[in] monitor The monitor to use for full screen mode, or `NULL` for+ *  windowed mode.+ *  @param[in] share The window whose context to share resources with, or `NULL`+ *  to not share resources.+ *  @return The handle of the created window, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref+ *  GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @remark @win32 Window creation will fail if the Microsoft GDI software+ *  OpenGL implementation is the only one available.+ *+ *  @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it+ *  will be set as the initial icon for the window.  If no such icon is present,+ *  the `IDI_WINLOGO` icon will be used instead.  To set a different icon, see+ *  @ref glfwSetWindowIcon.+ *+ *  @remark @win32 The context to share resources with must not be current on+ *  any other thread.+ *+ *  @remark @osx The GLFW window has no icon, as it is not a document+ *  window, but the dock icon will be the same as the application bundle's icon.+ *  For more information on bundles, see the+ *  [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)+ *  in the Mac Developer Library.+ *+ *  @remark @osx The first time a window is created the menu bar is populated+ *  with common commands like Hide, Quit and About.  The About entry opens+ *  a minimal about dialog with information from the application's bundle.  The+ *  menu bar can be disabled with a+ *  [compile-time option](@ref compile_options_osx).+ *+ *  @remark @osx On OS X 10.10 and later the window frame will not be rendered+ *  at full resolution on Retina displays unless the `NSHighResolutionCapable`+ *  key is enabled in the application bundle's `Info.plist`.  For more+ *  information, see+ *  [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)+ *  in the Mac Developer Library.  The GLFW test and example programs use+ *  a custom `Info.plist` template for this, which can be found as+ *  `CMake/MacOSXBundleInfo.plist.in` in the source tree.+ *+ *  @remark @x11 Some window managers will not respect the placement of+ *  initially hidden windows.+ *+ *  @remark @x11 Due to the asynchronous nature of X11, it may take a moment for+ *  a window to reach its requested state.  This means you may not be able to+ *  query the final size, position or other attributes directly after window+ *  creation.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_creation+ *  @sa glfwDestroyWindow+ *+ *  @since Added in version 3.0.  Replaces `glfwOpenWindow`.+ *+ *  @ingroup window+ */+GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);++/*! @brief Destroys the specified window and its context.+ *+ *  This function destroys the specified window and its context.  On calling+ *  this function, no further callbacks will be called for that window.+ *+ *  If the context of the specified window is current on the main thread, it is+ *  detached before being destroyed.+ *+ *  @param[in] window The window to destroy.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @note The context of the specified window must not be current on any other+ *  thread when this function is called.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_creation+ *  @sa glfwCreateWindow+ *+ *  @since Added in version 3.0.  Replaces `glfwCloseWindow`.+ *+ *  @ingroup window+ */+GLFWAPI void glfwDestroyWindow(GLFWwindow* window);++/*! @brief Checks the close flag of the specified window.+ *+ *  This function returns the value of the close flag of the specified window.+ *+ *  @param[in] window The window to query.+ *  @return The value of the close flag.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @sa @ref window_close+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);++/*! @brief Sets the close flag of the specified window.+ *+ *  This function sets the value of the close flag of the specified window.+ *  This can be used to override the user's attempt to close the window, or+ *  to signal that it should be closed.+ *+ *  @param[in] window The window whose flag to change.+ *  @param[in] value The new value.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @sa @ref window_close+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);++/*! @brief Sets the title of the specified window.+ *+ *  This function sets the window title, encoded as UTF-8, of the specified+ *  window.+ *+ *  @param[in] window The window whose title to change.+ *  @param[in] title The UTF-8 encoded window title.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @remark @osx The window title will not be updated until the next time you+ *  process events.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_title+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);++/*! @brief Sets the icon for the specified window.+ *+ *  This function sets the icon of the specified window.  If passed an array of+ *  candidate images, those of or closest to the sizes desired by the system are+ *  selected.  If no images are specified, the window reverts to its default+ *  icon.+ *+ *  The desired image sizes varies depending on platform and system settings.+ *  The selected images will be rescaled as needed.  Good sizes include 16x16,+ *  32x32 and 48x48.+ *+ *  @param[in] window The window whose icon to set.+ *  @param[in] count The number of images in the specified array, or zero to+ *  revert to the default window icon.+ *  @param[in] images The images to create the icon from.  This is ignored if+ *  count is zero.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The specified image data is copied before this function+ *  returns.+ *+ *  @remark @osx The GLFW window has no icon, as it is not a document+ *  window, so this function does nothing.  The dock icon will be the same as+ *  the application bundle's icon.  For more information on bundles, see the+ *  [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)+ *  in the Mac Developer Library.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_icon+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);++/*! @brief Retrieves the position of the client area of the specified window.+ *+ *  This function retrieves the position, in screen coordinates, of the+ *  upper-left corner of the client area of the specified window.+ *+ *  Any or all of the position arguments may be `NULL`.  If an error occurs, all+ *  non-`NULL` position arguments will be set to zero.+ *+ *  @param[in] window The window to query.+ *  @param[out] xpos Where to store the x-coordinate of the upper-left corner of+ *  the client area, or `NULL`.+ *  @param[out] ypos Where to store the y-coordinate of the upper-left corner of+ *  the client area, or `NULL`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_pos+ *  @sa glfwSetWindowPos+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);++/*! @brief Sets the position of the client area of the specified window.+ *+ *  This function sets the position, in screen coordinates, of the upper-left+ *  corner of the client area of the specified windowed mode window.  If the+ *  window is a full screen window, this function does nothing.+ *+ *  __Do not use this function__ to move an already visible window unless you+ *  have very good reasons for doing so, as it will confuse and annoy the user.+ *+ *  The window manager may put limits on what positions are allowed.  GLFW+ *  cannot and should not override these limits.+ *+ *  @param[in] window The window to query.+ *  @param[in] xpos The x-coordinate of the upper-left corner of the client area.+ *  @param[in] ypos The y-coordinate of the upper-left corner of the client area.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_pos+ *  @sa glfwGetWindowPos+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);++/*! @brief Retrieves the size of the client area of the specified window.+ *+ *  This function retrieves the size, in screen coordinates, of the client area+ *  of the specified window.  If you wish to retrieve the size of the+ *  framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.+ *+ *  Any or all of the size arguments may be `NULL`.  If an error occurs, all+ *  non-`NULL` size arguments will be set to zero.+ *+ *  @param[in] window The window whose size to retrieve.+ *  @param[out] width Where to store the width, in screen coordinates, of the+ *  client area, or `NULL`.+ *  @param[out] height Where to store the height, in screen coordinates, of the+ *  client area, or `NULL`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_size+ *  @sa glfwSetWindowSize+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);++/*! @brief Sets the size limits of the specified window.+ *+ *  This function sets the size limits of the client area of the specified+ *  window.  If the window is full screen, the size limits only take effect+ *  once it is made windowed.  If the window is not resizable, this function+ *  does nothing.+ *+ *  The size limits are applied immediately to a windowed mode window and may+ *  cause it to be resized.+ *+ *  The maximum dimensions must be greater than or equal to the minimum+ *  dimensions and all must be greater than or equal to zero.+ *+ *  @param[in] window The window to set limits for.+ *  @param[in] minwidth The minimum width, in screen coordinates, of the client+ *  area, or `GLFW_DONT_CARE`.+ *  @param[in] minheight The minimum height, in screen coordinates, of the+ *  client area, or `GLFW_DONT_CARE`.+ *  @param[in] maxwidth The maximum width, in screen coordinates, of the client+ *  area, or `GLFW_DONT_CARE`.+ *  @param[in] maxheight The maximum height, in screen coordinates, of the+ *  client area, or `GLFW_DONT_CARE`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.+ *+ *  @remark If you set size limits and an aspect ratio that conflict, the+ *  results are undefined.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_sizelimits+ *  @sa glfwSetWindowAspectRatio+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);++/*! @brief Sets the aspect ratio of the specified window.+ *+ *  This function sets the required aspect ratio of the client area of the+ *  specified window.  If the window is full screen, the aspect ratio only takes+ *  effect once it is made windowed.  If the window is not resizable, this+ *  function does nothing.+ *+ *  The aspect ratio is specified as a numerator and a denominator and both+ *  values must be greater than zero.  For example, the common 16:9 aspect ratio+ *  is specified as 16 and 9, respectively.+ *+ *  If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect+ *  ratio limit is disabled.+ *+ *  The aspect ratio is applied immediately to a windowed mode window and may+ *  cause it to be resized.+ *+ *  @param[in] window The window to set limits for.+ *  @param[in] numer The numerator of the desired aspect ratio, or+ *  `GLFW_DONT_CARE`.+ *  @param[in] denom The denominator of the desired aspect ratio, or+ *  `GLFW_DONT_CARE`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.+ *+ *  @remark If you set size limits and an aspect ratio that conflict, the+ *  results are undefined.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_sizelimits+ *  @sa glfwSetWindowSizeLimits+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);++/*! @brief Sets the size of the client area of the specified window.+ *+ *  This function sets the size, in screen coordinates, of the client area of+ *  the specified window.+ *+ *  For full screen windows, this function updates the resolution of its desired+ *  video mode and switches to the video mode closest to it, without affecting+ *  the window's context.  As the context is unaffected, the bit depths of the+ *  framebuffer remain unchanged.+ *+ *  If you wish to update the refresh rate of the desired video mode in addition+ *  to its resolution, see @ref glfwSetWindowMonitor.+ *+ *  The window manager may put limits on what sizes are allowed.  GLFW cannot+ *  and should not override these limits.+ *+ *  @param[in] window The window to resize.+ *  @param[in] width The desired width, in screen coordinates, of the window+ *  client area.+ *  @param[in] height The desired height, in screen coordinates, of the window+ *  client area.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_size+ *  @sa glfwGetWindowSize+ *  @sa glfwSetWindowMonitor+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);++/*! @brief Retrieves the size of the framebuffer of the specified window.+ *+ *  This function retrieves the size, in pixels, of the framebuffer of the+ *  specified window.  If you wish to retrieve the size of the window in screen+ *  coordinates, see @ref glfwGetWindowSize.+ *+ *  Any or all of the size arguments may be `NULL`.  If an error occurs, all+ *  non-`NULL` size arguments will be set to zero.+ *+ *  @param[in] window The window whose framebuffer to query.+ *  @param[out] width Where to store the width, in pixels, of the framebuffer,+ *  or `NULL`.+ *  @param[out] height Where to store the height, in pixels, of the framebuffer,+ *  or `NULL`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_fbsize+ *  @sa glfwSetFramebufferSizeCallback+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);++/*! @brief Retrieves the size of the frame of the window.+ *+ *  This function retrieves the size, in screen coordinates, of each edge of the+ *  frame of the specified window.  This size includes the title bar, if the+ *  window has one.  The size of the frame may vary depending on the+ *  [window-related hints](@ref window_hints_wnd) used to create it.+ *+ *  Because this function retrieves the size of each window frame edge and not+ *  the offset along a particular coordinate axis, the retrieved values will+ *  always be zero or positive.+ *+ *  Any or all of the size arguments may be `NULL`.  If an error occurs, all+ *  non-`NULL` size arguments will be set to zero.+ *+ *  @param[in] window The window whose frame size to query.+ *  @param[out] left Where to store the size, in screen coordinates, of the left+ *  edge of the window frame, or `NULL`.+ *  @param[out] top Where to store the size, in screen coordinates, of the top+ *  edge of the window frame, or `NULL`.+ *  @param[out] right Where to store the size, in screen coordinates, of the+ *  right edge of the window frame, or `NULL`.+ *  @param[out] bottom Where to store the size, in screen coordinates, of the+ *  bottom edge of the window frame, or `NULL`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_size+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup window+ */+GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);++/*! @brief Iconifies the specified window.+ *+ *  This function iconifies (minimizes) the specified window if it was+ *  previously restored.  If the window is already iconified, this function does+ *  nothing.+ *+ *  If the specified window is a full screen window, the original monitor+ *  resolution is restored until the window is restored.+ *+ *  @param[in] window The window to iconify.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_iconify+ *  @sa glfwRestoreWindow+ *  @sa glfwMaximizeWindow+ *+ *  @since Added in version 2.1.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+GLFWAPI void glfwIconifyWindow(GLFWwindow* window);++/*! @brief Restores the specified window.+ *+ *  This function restores the specified window if it was previously iconified+ *  (minimized) or maximized.  If the window is already restored, this function+ *  does nothing.+ *+ *  If the specified window is a full screen window, the resolution chosen for+ *  the window is restored on the selected monitor.+ *+ *  @param[in] window The window to restore.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_iconify+ *  @sa glfwIconifyWindow+ *  @sa glfwMaximizeWindow+ *+ *  @since Added in version 2.1.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+GLFWAPI void glfwRestoreWindow(GLFWwindow* window);++/*! @brief Maximizes the specified window.+ *+ *  This function maximizes the specified window if it was previously not+ *  maximized.  If the window is already maximized, this function does nothing.+ *+ *  If the specified window is a full screen window, this function does nothing.+ *+ *  @param[in] window The window to maximize.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @par Thread Safety+ *  This function may only be called from the main thread.+ *+ *  @sa @ref window_iconify+ *  @sa glfwIconifyWindow+ *  @sa glfwRestoreWindow+ *+ *  @since Added in GLFW 3.2.+ *+ *  @ingroup window+ */+GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);++/*! @brief Makes the specified window visible.+ *+ *  This function makes the specified window visible if it was previously+ *  hidden.  If the window is already visible or is in full screen mode, this+ *  function does nothing.+ *+ *  @param[in] window The window to make visible.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_hide+ *  @sa glfwHideWindow+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI void glfwShowWindow(GLFWwindow* window);++/*! @brief Hides the specified window.+ *+ *  This function hides the specified window if it was previously visible.  If+ *  the window is already hidden or is in full screen mode, this function does+ *  nothing.+ *+ *  @param[in] window The window to hide.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_hide+ *  @sa glfwShowWindow+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI void glfwHideWindow(GLFWwindow* window);++/*! @brief Brings the specified window to front and sets input focus.+ *+ *  This function brings the specified window to front and sets input focus.+ *  The window should already be visible and not iconified.+ *+ *  By default, both windowed and full screen mode windows are focused when+ *  initially created.  Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable+ *  this behavior.+ *+ *  __Do not use this function__ to steal focus from other applications unless+ *  you are certain that is what the user wants.  Focus stealing can be+ *  extremely disruptive.+ *+ *  @param[in] window The window to give input focus.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_focus+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup window+ */+GLFWAPI void glfwFocusWindow(GLFWwindow* window);++/*! @brief Returns the monitor that the window uses for full screen mode.+ *+ *  This function returns the handle of the monitor that the specified window is+ *  in full screen on.+ *+ *  @param[in] window The window to query.+ *  @return The monitor, or `NULL` if the window is in windowed mode or an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_monitor+ *  @sa glfwSetWindowMonitor+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);++/*! @brief Sets the mode, monitor, video mode and placement of a window.+ *+ *  This function sets the monitor that the window uses for full screen mode or,+ *  if the monitor is `NULL`, makes it windowed mode.+ *+ *  When setting a monitor, this function updates the width, height and refresh+ *  rate of the desired video mode and switches to the video mode closest to it.+ *  The window position is ignored when setting a monitor.+ *+ *  When the monitor is `NULL`, the position, width and height are used to+ *  place the window client area.  The refresh rate is ignored when no monitor+ *  is specified.+ *+ *  If you only wish to update the resolution of a full screen window or the+ *  size of a windowed mode window, see @ref glfwSetWindowSize.+ *+ *  When a window transitions from full screen to windowed mode, this function+ *  restores any previous window settings such as whether it is decorated,+ *  floating, resizable, has size or aspect ratio limits, etc..+ *+ *  @param[in] window The window whose monitor, size or video mode to set.+ *  @param[in] monitor The desired monitor, or `NULL` to set windowed mode.+ *  @param[in] xpos The desired x-coordinate of the upper-left corner of the+ *  client area.+ *  @param[in] ypos The desired y-coordinate of the upper-left corner of the+ *  client area.+ *  @param[in] width The desired with, in screen coordinates, of the client area+ *  or video mode.+ *  @param[in] height The desired height, in screen coordinates, of the client+ *  area or video mode.+ *  @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,+ *  or `GLFW_DONT_CARE`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_monitor+ *  @sa @ref window_full_screen+ *  @sa glfwGetWindowMonitor+ *  @sa glfwSetWindowSize+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);++/*! @brief Returns an attribute of the specified window.+ *+ *  This function returns the value of an attribute of the specified window or+ *  its OpenGL or OpenGL ES context.+ *+ *  @param[in] window The window to query.+ *  @param[in] attrib The [window attribute](@ref window_attribs) whose value to+ *  return.+ *  @return The value of the attribute, or zero if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.+ *+ *  @remark Framebuffer related hints are not window attributes.  See @ref+ *  window_attribs_fb for more information.+ *+ *  @remark Zero is a valid value for many window and context related+ *  attributes so you cannot use a return value of zero as an indication of+ *  errors.  However, this function should not fail as long as it is passed+ *  valid arguments and the library has been [initialized](@ref intro_init).+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_attribs+ *+ *  @since Added in version 3.0.  Replaces `glfwGetWindowParam` and+ *  `glfwGetGLVersion`.+ *+ *  @ingroup window+ */+GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);++/*! @brief Sets the user pointer of the specified window.+ *+ *  This function sets the user-defined pointer of the specified window.  The+ *  current value is retained until the window is destroyed.  The initial value+ *  is `NULL`.+ *+ *  @param[in] window The window whose pointer to set.+ *  @param[in] pointer The new value.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @sa @ref window_userptr+ *  @sa glfwGetWindowUserPointer+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);++/*! @brief Returns the user pointer of the specified window.+ *+ *  This function returns the current value of the user-defined pointer of the+ *  specified window.  The initial value is `NULL`.+ *+ *  @param[in] window The window whose pointer to return.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @sa @ref window_userptr+ *  @sa glfwSetWindowUserPointer+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);++/*! @brief Sets the position callback for the specified window.+ *+ *  This function sets the position callback of the specified window, which is+ *  called when the window is moved.  The callback is provided with the screen+ *  position of the upper-left corner of the client area of the window.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_pos+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun);++/*! @brief Sets the size callback for the specified window.+ *+ *  This function sets the size callback of the specified window, which is+ *  called when the window is resized.  The callback is provided with the size,+ *  in screen coordinates, of the client area of the window.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_size+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter and return value.+ *+ *  @ingroup window+ */+GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun);++/*! @brief Sets the close callback for the specified window.+ *+ *  This function sets the close callback of the specified window, which is+ *  called when the user attempts to close the window, for example by clicking+ *  the close widget in the title bar.+ *+ *  The close flag is set before this callback is called, but you can modify it+ *  at any time with @ref glfwSetWindowShouldClose.+ *+ *  The close callback is not triggered by @ref glfwDestroyWindow.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @remark @osx Selecting Quit from the application menu will trigger the close+ *  callback for all windows.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_close+ *+ *  @since Added in version 2.5.+ *  @glfw3 Added window handle parameter and return value.+ *+ *  @ingroup window+ */+GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);++/*! @brief Sets the refresh callback for the specified window.+ *+ *  This function sets the refresh callback of the specified window, which is+ *  called when the client area of the window needs to be redrawn, for example+ *  if the window has been exposed after having been covered by another window.+ *+ *  On compositing window systems such as Aero, Compiz or Aqua, where the window+ *  contents are saved off-screen, this callback may be called only very+ *  infrequently or never at all.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_refresh+ *+ *  @since Added in version 2.5.+ *  @glfw3 Added window handle parameter and return value.+ *+ *  @ingroup window+ */+GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun);++/*! @brief Sets the focus callback for the specified window.+ *+ *  This function sets the focus callback of the specified window, which is+ *  called when the window gains or loses input focus.+ *+ *  After the focus callback is called for a window that lost input focus,+ *  synthetic key and mouse button release events will be generated for all such+ *  that had been pressed.  For more information, see @ref glfwSetKeyCallback+ *  and @ref glfwSetMouseButtonCallback.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_focus+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);++/*! @brief Sets the iconify callback for the specified window.+ *+ *  This function sets the iconification callback of the specified window, which+ *  is called when the window is iconified or restored.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_iconify+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);++/*! @brief Sets the framebuffer resize callback for the specified window.+ *+ *  This function sets the framebuffer resize callback of the specified window,+ *  which is called when the framebuffer of the specified window is resized.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref window_fbsize+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup window+ */+GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);++/*! @brief Processes all pending events.+ *+ *  This function processes only those events that are already in the event+ *  queue and then returns immediately.  Processing events will cause the window+ *  and input callbacks associated with those events to be called.+ *+ *  On some platforms, a window move, resize or menu operation will cause event+ *  processing to block.  This is due to how event processing is designed on+ *  those platforms.  You can use the+ *  [window refresh callback](@ref window_refresh) to redraw the contents of+ *  your window when necessary during such operations.+ *+ *  On some platforms, certain events are sent directly to the application+ *  without going through the event queue, causing callbacks to be called+ *  outside of a call to one of the event processing functions.+ *+ *  Event processing is not required for joystick input to work.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref events+ *  @sa glfwWaitEvents+ *  @sa glfwWaitEventsTimeout+ *+ *  @since Added in version 1.0.+ *+ *  @ingroup window+ */+GLFWAPI void glfwPollEvents(void);++/*! @brief Waits until events are queued and processes them.+ *+ *  This function puts the calling thread to sleep until at least one event is+ *  available in the event queue.  Once one or more events are available,+ *  it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue+ *  are processed and the function then returns immediately.  Processing events+ *  will cause the window and input callbacks associated with those events to be+ *  called.+ *+ *  Since not all events are associated with callbacks, this function may return+ *  without a callback having been called even if you are monitoring all+ *  callbacks.+ *+ *  On some platforms, a window move, resize or menu operation will cause event+ *  processing to block.  This is due to how event processing is designed on+ *  those platforms.  You can use the+ *  [window refresh callback](@ref window_refresh) to redraw the contents of+ *  your window when necessary during such operations.+ *+ *  On some platforms, certain callbacks may be called outside of a call to one+ *  of the event processing functions.+ *+ *  If no windows exist, this function returns immediately.  For synchronization+ *  of threads in applications that do not create windows, use your threading+ *  library of choice.+ *+ *  Event processing is not required for joystick input to work.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref events+ *  @sa glfwPollEvents+ *  @sa glfwWaitEventsTimeout+ *+ *  @since Added in version 2.5.+ *+ *  @ingroup window+ */+GLFWAPI void glfwWaitEvents(void);++/*! @brief Waits with timeout until events are queued and processes them.+ *+ *  This function puts the calling thread to sleep until at least one event is+ *  available in the event queue, or until the specified timeout is reached.  If+ *  one or more events are available, it behaves exactly like @ref+ *  glfwPollEvents, i.e. the events in the queue are processed and the function+ *  then returns immediately.  Processing events will cause the window and input+ *  callbacks associated with those events to be called.+ *+ *  The timeout value must be a positive finite number.+ *+ *  Since not all events are associated with callbacks, this function may return+ *  without a callback having been called even if you are monitoring all+ *  callbacks.+ *+ *  On some platforms, a window move, resize or menu operation will cause event+ *  processing to block.  This is due to how event processing is designed on+ *  those platforms.  You can use the+ *  [window refresh callback](@ref window_refresh) to redraw the contents of+ *  your window when necessary during such operations.+ *+ *  On some platforms, certain callbacks may be called outside of a call to one+ *  of the event processing functions.+ *+ *  If no windows exist, this function returns immediately.  For synchronization+ *  of threads in applications that do not create windows, use your threading+ *  library of choice.+ *+ *  Event processing is not required for joystick input to work.+ *+ *  @param[in] timeout The maximum amount of time, in seconds, to wait.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref events+ *  @sa glfwPollEvents+ *  @sa glfwWaitEvents+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup window+ */+GLFWAPI void glfwWaitEventsTimeout(double timeout);++/*! @brief Posts an empty event to the event queue.+ *+ *  This function posts an empty event from the current thread to the event+ *  queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return.+ *+ *  If no windows exist, this function returns immediately.  For synchronization+ *  of threads in applications that do not create windows, use your threading+ *  library of choice.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref events+ *  @sa glfwWaitEvents+ *  @sa glfwWaitEventsTimeout+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup window+ */+GLFWAPI void glfwPostEmptyEvent(void);++/*! @brief Returns the value of an input option for the specified window.+ *+ *  This function returns the value of an input option for the specified window.+ *  The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or+ *  `GLFW_STICKY_MOUSE_BUTTONS`.+ *+ *  @param[in] window The window to query.+ *  @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or+ *  `GLFW_STICKY_MOUSE_BUTTONS`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_INVALID_ENUM.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa glfwSetInputMode+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup input+ */+GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);++/*! @brief Sets an input option for the specified window.+ *+ *  This function sets an input mode option for the specified window.  The mode+ *  must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or+ *  `GLFW_STICKY_MOUSE_BUTTONS`.+ *+ *  If the mode is `GLFW_CURSOR`, the value must be one of the following cursor+ *  modes:+ *  - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.+ *  - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client+ *    area of the window but does not restrict the cursor from leaving.+ *  - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual+ *    and unlimited cursor movement.  This is useful for implementing for+ *    example 3D camera controls.+ *+ *  If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to+ *  enable sticky keys, or `GLFW_FALSE` to disable it.  If sticky keys are+ *  enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`+ *  the next time it is called even if the key had been released before the+ *  call.  This is useful when you are only interested in whether keys have been+ *  pressed but not when or in which order.+ *+ *  If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either+ *  `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.+ *  If sticky mouse buttons are enabled, a mouse button press will ensure that+ *  @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even+ *  if the mouse button had been released before the call.  This is useful when+ *  you are only interested in whether mouse buttons have been pressed but not+ *  when or in which order.+ *+ *  @param[in] window The window whose input mode to set.+ *  @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or+ *  `GLFW_STICKY_MOUSE_BUTTONS`.+ *  @param[in] value The new value of the specified input mode.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa glfwGetInputMode+ *+ *  @since Added in version 3.0.  Replaces `glfwEnable` and `glfwDisable`.+ *+ *  @ingroup input+ */+GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);++/*! @brief Returns the localized name of the specified printable key.+ *+ *  This function returns the localized name of the specified printable key.+ *  This is intended for displaying key bindings to the user.+ *+ *  If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise+ *  the scancode is ignored.  If a non-printable key or (if the key is+ *  `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is+ *  specified, this function returns `NULL`.          + *+ *  This behavior allows you to pass in the arguments passed to the+ *  [key callback](@ref input_key) without modification.+ *+ *  The printable keys are:+ *  - `GLFW_KEY_APOSTROPHE`+ *  - `GLFW_KEY_COMMA`+ *  - `GLFW_KEY_MINUS`+ *  - `GLFW_KEY_PERIOD`+ *  - `GLFW_KEY_SLASH`+ *  - `GLFW_KEY_SEMICOLON`+ *  - `GLFW_KEY_EQUAL`+ *  - `GLFW_KEY_LEFT_BRACKET`+ *  - `GLFW_KEY_RIGHT_BRACKET`+ *  - `GLFW_KEY_BACKSLASH`+ *  - `GLFW_KEY_WORLD_1`+ *  - `GLFW_KEY_WORLD_2`+ *  - `GLFW_KEY_0` to `GLFW_KEY_9`+ *  - `GLFW_KEY_A` to `GLFW_KEY_Z`+ *  - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9`+ *  - `GLFW_KEY_KP_DECIMAL`+ *  - `GLFW_KEY_KP_DIVIDE`+ *  - `GLFW_KEY_KP_MULTIPLY`+ *  - `GLFW_KEY_KP_SUBTRACT`+ *  - `GLFW_KEY_KP_ADD`+ *  - `GLFW_KEY_KP_EQUAL`+ *+ *  @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.+ *  @param[in] scancode The scancode of the key to query.+ *  @return The localized name of the key, or `NULL`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is valid until the next call to @ref+ *  glfwGetKeyName, or until the library is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref input_key_name+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup input+ */+GLFWAPI const char* glfwGetKeyName(int key, int scancode);++/*! @brief Returns the last reported state of a keyboard key for the specified+ *  window.+ *+ *  This function returns the last state reported for the specified key to the+ *  specified window.  The returned state is one of `GLFW_PRESS` or+ *  `GLFW_RELEASE`.  The higher-level action `GLFW_REPEAT` is only reported to+ *  the key callback.+ *+ *  If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns+ *  `GLFW_PRESS` the first time you call it for a key that was pressed, even if+ *  that key has already been released.+ *+ *  The key functions deal with physical keys, with [key tokens](@ref keys)+ *  named after their use on the standard US keyboard layout.  If you want to+ *  input text, use the Unicode character callback instead.+ *+ *  The [modifier key bit masks](@ref mods) are not key tokens and cannot be+ *  used with this function.+ *+ *  __Do not use this function__ to implement [text input](@ref input_char).+ *+ *  @param[in] window The desired window.+ *  @param[in] key The desired [keyboard key](@ref keys).  `GLFW_KEY_UNKNOWN` is+ *  not a valid key for this function.+ *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_INVALID_ENUM.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref input_key+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup input+ */+GLFWAPI int glfwGetKey(GLFWwindow* window, int key);++/*! @brief Returns the last reported state of a mouse button for the specified+ *  window.+ *+ *  This function returns the last state reported for the specified mouse button+ *  to the specified window.  The returned state is one of `GLFW_PRESS` or+ *  `GLFW_RELEASE`.+ *+ *  If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function+ *  `GLFW_PRESS` the first time you call it for a mouse button that was pressed,+ *  even if that mouse button has already been released.+ *+ *  @param[in] window The desired window.+ *  @param[in] button The desired [mouse button](@ref buttons).+ *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_INVALID_ENUM.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref input_mouse_button+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup input+ */+GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);++/*! @brief Retrieves the position of the cursor relative to the client area of+ *  the window.+ *+ *  This function returns the position of the cursor, in screen coordinates,+ *  relative to the upper-left corner of the client area of the specified+ *  window.+ *+ *  If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor+ *  position is unbounded and limited only by the minimum and maximum values of+ *  a `double`.+ *+ *  The coordinate can be converted to their integer equivalents with the+ *  `floor` function.  Casting directly to an integer type works for positive+ *  coordinates, but fails for negative ones.+ *+ *  Any or all of the position arguments may be `NULL`.  If an error occurs, all+ *  non-`NULL` position arguments will be set to zero.+ *+ *  @param[in] window The desired window.+ *  @param[out] xpos Where to store the cursor x-coordinate, relative to the+ *  left edge of the client area, or `NULL`.+ *  @param[out] ypos Where to store the cursor y-coordinate, relative to the to+ *  top edge of the client area, or `NULL`.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref cursor_pos+ *  @sa glfwSetCursorPos+ *+ *  @since Added in version 3.0.  Replaces `glfwGetMousePos`.+ *+ *  @ingroup input+ */+GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);++/*! @brief Sets the position of the cursor, relative to the client area of the+ *  window.+ *+ *  This function sets the position, in screen coordinates, of the cursor+ *  relative to the upper-left corner of the client area of the specified+ *  window.  The window must have input focus.  If the window does not have+ *  input focus when this function is called, it fails silently.+ *+ *  __Do not use this function__ to implement things like camera controls.  GLFW+ *  already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the+ *  cursor, transparently re-centers it and provides unconstrained cursor+ *  motion.  See @ref glfwSetInputMode for more information.+ *+ *  If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is+ *  unconstrained and limited only by the minimum and maximum values of+ *  a `double`.+ *+ *  @param[in] window The desired window.+ *  @param[in] xpos The desired x-coordinate, relative to the left edge of the+ *  client area.+ *  @param[in] ypos The desired y-coordinate, relative to the top edge of the+ *  client area.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref cursor_pos+ *  @sa glfwGetCursorPos+ *+ *  @since Added in version 3.0.  Replaces `glfwSetMousePos`.+ *+ *  @ingroup input+ */+GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);++/*! @brief Creates a custom cursor.+ *+ *  Creates a new custom cursor image that can be set for a window with @ref+ *  glfwSetCursor.  The cursor can be destroyed with @ref glfwDestroyCursor.+ *  Any remaining cursors are destroyed by @ref glfwTerminate.+ *+ *  The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight+ *  bits per channel.  They are arranged canonically as packed sequential rows,+ *  starting from the top-left corner.+ *+ *  The cursor hotspot is specified in pixels, relative to the upper-left corner+ *  of the cursor image.  Like all other coordinate systems in GLFW, the X-axis+ *  points to the right and the Y-axis points down.+ *+ *  @param[in] image The desired cursor image.+ *  @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.+ *  @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.+ *  @return The handle of the created cursor, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The specified image data is copied before this function+ *  returns.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref cursor_object+ *  @sa glfwDestroyCursor+ *  @sa glfwCreateStandardCursor+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup input+ */+GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);++/*! @brief Creates a cursor with a standard shape.+ *+ *  Returns a cursor with a [standard shape](@ref shapes), that can be set for+ *  a window with @ref glfwSetCursor.+ *+ *  @param[in] shape One of the [standard shapes](@ref shapes).+ *  @return A new cursor ready to use or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref cursor_object+ *  @sa glfwCreateCursor+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup input+ */+GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);++/*! @brief Destroys a cursor.+ *+ *  This function destroys a cursor previously created with @ref+ *  glfwCreateCursor.  Any remaining cursors will be destroyed by @ref+ *  glfwTerminate.+ *+ *  @param[in] cursor The cursor object to destroy.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @reentrancy This function must not be called from a callback.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref cursor_object+ *  @sa glfwCreateCursor+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup input+ */+GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);++/*! @brief Sets the cursor for the window.+ *+ *  This function sets the cursor image to be used when the cursor is over the+ *  client area of the specified window.  The set cursor will only be visible+ *  when the [cursor mode](@ref cursor_mode) of the window is+ *  `GLFW_CURSOR_NORMAL`.+ *+ *  On some platforms, the set cursor may not be visible unless the window also+ *  has input focus.+ *+ *  @param[in] window The window to set the cursor for.+ *  @param[in] cursor The cursor to set, or `NULL` to switch back to the default+ *  arrow cursor.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref cursor_object+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup input+ */+GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);++/*! @brief Sets the key callback.+ *+ *  This function sets the key callback of the specified window, which is called+ *  when a key is pressed, repeated or released.+ *+ *  The key functions deal with physical keys, with layout independent+ *  [key tokens](@ref keys) named after their values in the standard US keyboard+ *  layout.  If you want to input text, use the+ *  [character callback](@ref glfwSetCharCallback) instead.+ *+ *  When a window loses input focus, it will generate synthetic key release+ *  events for all pressed keys.  You can tell these events from user-generated+ *  events by the fact that the synthetic ones are generated after the focus+ *  loss event has been processed, i.e. after the+ *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called.+ *+ *  The scancode of a key is specific to that platform or sometimes even to that+ *  machine.  Scancodes are intended to allow users to bind keys that don't have+ *  a GLFW key token.  Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their+ *  state is not saved and so it cannot be queried with @ref glfwGetKey.+ *+ *  Sometimes GLFW needs to generate synthetic key events, in which case the+ *  scancode may be zero.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new key callback, or `NULL` to remove the currently+ *  set callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref input_key+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter and return value.+ *+ *  @ingroup input+ */+GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);++/*! @brief Sets the Unicode character callback.+ *+ *  This function sets the character callback of the specified window, which is+ *  called when a Unicode character is input.+ *+ *  The character callback is intended for Unicode text input.  As it deals with+ *  characters, it is keyboard layout dependent, whereas the+ *  [key callback](@ref glfwSetKeyCallback) is not.  Characters do not map 1:1+ *  to physical keys, as a key may produce zero, one or more characters.  If you+ *  want to know whether a specific physical key was pressed or released, see+ *  the key callback instead.+ *+ *  The character callback behaves as system text input normally does and will+ *  not be called if modifier keys are held down that would prevent normal text+ *  input on that platform, for example a Super (Command) key on OS X or Alt key+ *  on Windows.  There is a+ *  [character with modifiers callback](@ref glfwSetCharModsCallback) that+ *  receives these events.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref input_char+ *+ *  @since Added in version 2.4.+ *  @glfw3 Added window handle parameter and return value.+ *+ *  @ingroup input+ */+GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);++/*! @brief Sets the Unicode character with modifiers callback.+ *+ *  This function sets the character with modifiers callback of the specified+ *  window, which is called when a Unicode character is input regardless of what+ *  modifier keys are used.+ *+ *  The character with modifiers callback is intended for implementing custom+ *  Unicode character input.  For regular Unicode text input, see the+ *  [character callback](@ref glfwSetCharCallback).  Like the character+ *  callback, the character with modifiers callback deals with characters and is+ *  keyboard layout dependent.  Characters do not map 1:1 to physical keys, as+ *  a key may produce zero, one or more characters.  If you want to know whether+ *  a specific physical key was pressed or released, see the+ *  [key callback](@ref glfwSetKeyCallback) instead.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref input_char+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup input+ */+GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);++/*! @brief Sets the mouse button callback.+ *+ *  This function sets the mouse button callback of the specified window, which+ *  is called when a mouse button is pressed or released.+ *+ *  When a window loses input focus, it will generate synthetic mouse button+ *  release events for all pressed mouse buttons.  You can tell these events+ *  from user-generated events by the fact that the synthetic ones are generated+ *  after the focus loss event has been processed, i.e. after the+ *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref input_mouse_button+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter and return value.+ *+ *  @ingroup input+ */+GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);++/*! @brief Sets the cursor position callback.+ *+ *  This function sets the cursor position callback of the specified window,+ *  which is called when the cursor is moved.  The callback is provided with the+ *  position, in screen coordinates, relative to the upper-left corner of the+ *  client area of the window.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref cursor_pos+ *+ *  @since Added in version 3.0.  Replaces `glfwSetMousePosCallback`.+ *+ *  @ingroup input+ */+GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun);++/*! @brief Sets the cursor enter/exit callback.+ *+ *  This function sets the cursor boundary crossing callback of the specified+ *  window, which is called when the cursor enters or leaves the client area of+ *  the window.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref cursor_enter+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup input+ */+GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun);++/*! @brief Sets the scroll callback.+ *+ *  This function sets the scroll callback of the specified window, which is+ *  called when a scrolling device is used, such as a mouse wheel or scrolling+ *  area of a touchpad.+ *+ *  The scroll callback receives all scrolling input, like that from a mouse+ *  wheel or a touchpad scrolling area.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new scroll callback, or `NULL` to remove the currently+ *  set callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref scrolling+ *+ *  @since Added in version 3.0.  Replaces `glfwSetMouseWheelCallback`.+ *+ *  @ingroup input+ */+GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);++/*! @brief Sets the file drop callback.+ *+ *  This function sets the file drop callback of the specified window, which is+ *  called when one or more dragged files are dropped on the window.+ *+ *  Because the path array and its strings may have been generated specifically+ *  for that event, they are not guaranteed to be valid after the callback has+ *  returned.  If you wish to use them after the callback returns, you need to+ *  make a deep copy.+ *+ *  @param[in] window The window whose callback to set.+ *  @param[in] cbfun The new file drop callback, or `NULL` to remove the+ *  currently set callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref path_drop+ *+ *  @since Added in version 3.1.+ *+ *  @ingroup input+ */+GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);++/*! @brief Returns whether the specified joystick is present.+ *+ *  This function returns whether the specified joystick is present.+ *+ *  @param[in] joy The [joystick](@ref joysticks) to query.+ *  @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref joystick+ *+ *  @since Added in version 3.0.  Replaces `glfwGetJoystickParam`.+ *+ *  @ingroup input+ */+GLFWAPI int glfwJoystickPresent(int joy);++/*! @brief Returns the values of all axes of the specified joystick.+ *+ *  This function returns the values of all axes of the specified joystick.+ *  Each element in the array is a value between -1.0 and 1.0.+ *+ *  Querying a joystick slot with no device present is not an error, but will+ *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to+ *  check device presence.+ *+ *  @param[in] joy The [joystick](@ref joysticks) to query.+ *  @param[out] count Where to store the number of axis values in the returned+ *  array.  This is set to zero if the joystick is not present or an error+ *  occurred.+ *  @return An array of axis values, or `NULL` if the joystick is not present or+ *  an [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is valid until the specified joystick is+ *  disconnected, this function is called again for that joystick or the library+ *  is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref joystick_axis+ *+ *  @since Added in version 3.0.  Replaces `glfwGetJoystickPos`.+ *+ *  @ingroup input+ */+GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);++/*! @brief Returns the state of all buttons of the specified joystick.+ *+ *  This function returns the state of all buttons of the specified joystick.+ *  Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.+ *+ *  Querying a joystick slot with no device present is not an error, but will+ *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to+ *  check device presence.+ *+ *  @param[in] joy The [joystick](@ref joysticks) to query.+ *  @param[out] count Where to store the number of button states in the returned+ *  array.  This is set to zero if the joystick is not present or an error+ *  occurred.+ *  @return An array of button states, or `NULL` if the joystick is not present+ *  or an [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is valid until the specified joystick is+ *  disconnected, this function is called again for that joystick or the library+ *  is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref joystick_button+ *+ *  @since Added in version 2.2.+ *  @glfw3 Changed to return a dynamic array.+ *+ *  @ingroup input+ */+GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);++/*! @brief Returns the name of the specified joystick.+ *+ *  This function returns the name, encoded as UTF-8, of the specified joystick.+ *  The returned string is allocated and freed by GLFW.  You should not free it+ *  yourself.+ *+ *  Querying a joystick slot with no device present is not an error, but will+ *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to+ *  check device presence.+ *+ *  @param[in] joy The [joystick](@ref joysticks) to query.+ *  @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick+ *  is not present or an [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is valid until the specified joystick is+ *  disconnected, this function is called again for that joystick or the library+ *  is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref joystick_name+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup input+ */+GLFWAPI const char* glfwGetJoystickName(int joy);++/*! @brief Sets the joystick configuration callback.+ *+ *  This function sets the joystick configuration callback, or removes the+ *  currently set callback.  This is called when a joystick is connected to or+ *  disconnected from the system.+ *+ *  @param[in] cbfun The new callback, or `NULL` to remove the currently set+ *  callback.+ *  @return The previously set callback, or `NULL` if no callback was set or the+ *  library had not been [initialized](@ref intro_init).+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref joystick_event+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup input+ */+GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);++/*! @brief Sets the clipboard to the specified string.+ *+ *  This function sets the system clipboard to the specified, UTF-8 encoded+ *  string.+ *+ *  @param[in] window The window that will own the clipboard contents.+ *  @param[in] string A UTF-8 encoded string.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The specified string is copied before this function+ *  returns.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref clipboard+ *  @sa glfwGetClipboardString+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup input+ */+GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);++/*! @brief Returns the contents of the clipboard as a string.+ *+ *  This function returns the contents of the system clipboard, if it contains+ *  or is convertible to a UTF-8 encoded string.  If the clipboard is empty or+ *  if its contents cannot be converted, `NULL` is returned and a @ref+ *  GLFW_FORMAT_UNAVAILABLE error is generated.+ *+ *  @param[in] window The window that will request the clipboard contents.+ *  @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`+ *  if an [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is valid until the next call to @ref+ *  glfwGetClipboardString or @ref glfwSetClipboardString, or until the library+ *  is terminated.+ *+ *  @thread_safety This function must only be called from the main thread.+ *+ *  @sa @ref clipboard+ *  @sa glfwSetClipboardString+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup input+ */+GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);++/*! @brief Returns the value of the GLFW timer.+ *+ *  This function returns the value of the GLFW timer.  Unless the timer has+ *  been set using @ref glfwSetTime, the timer measures time elapsed since GLFW+ *  was initialized.+ *+ *  The resolution of the timer is system dependent, but is usually on the order+ *  of a few micro- or nanoseconds.  It uses the highest-resolution monotonic+ *  time source on each supported platform.+ *+ *  @return The current value, in seconds, or zero if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.  Reading and+ *  writing of the internal timer offset is not atomic, so it needs to be+ *  externally synchronized with calls to @ref glfwSetTime.+ *+ *  @sa @ref time+ *+ *  @since Added in version 1.0.+ *+ *  @ingroup input+ */+GLFWAPI double glfwGetTime(void);++/*! @brief Sets the GLFW timer.+ *+ *  This function sets the value of the GLFW timer.  It then continues to count+ *  up from that value.  The value must be a positive finite number less than+ *  or equal to 18446744073.0, which is approximately 584.5 years.+ *+ *  @param[in] time The new value, in seconds.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_INVALID_VALUE.+ *+ *  @remark The upper limit of the timer is calculated as+ *  floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations+ *  storing nanoseconds in 64 bits.  The limit may be increased in the future.+ *+ *  @thread_safety This function may be called from any thread.  Reading and+ *  writing of the internal timer offset is not atomic, so it needs to be+ *  externally synchronized with calls to @ref glfwGetTime.+ *+ *  @sa @ref time+ *+ *  @since Added in version 2.2.+ *+ *  @ingroup input+ */+GLFWAPI void glfwSetTime(double time);++/*! @brief Returns the current value of the raw timer.+ *+ *  This function returns the current value of the raw timer, measured in+ *  1&nbsp;/&nbsp;frequency seconds.  To get the frequency, call @ref+ *  glfwGetTimerFrequency.+ *+ *  @return The value of the timer, or zero if an + *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref time+ *  @sa glfwGetTimerFrequency+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup input+ */+GLFWAPI uint64_t glfwGetTimerValue(void);++/*! @brief Returns the frequency, in Hz, of the raw timer.+ *+ *  This function returns the frequency, in Hz, of the raw timer.+ *+ *  @return The frequency of the timer, in Hz, or zero if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref time+ *  @sa glfwGetTimerValue+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup input+ */+GLFWAPI uint64_t glfwGetTimerFrequency(void);++/*! @brief Makes the context of the specified window current for the calling+ *  thread.+ *+ *  This function makes the OpenGL or OpenGL ES context of the specified window+ *  current on the calling thread.  A context can only be made current on+ *  a single thread at a time and each thread can have only a single current+ *  context at a time.+ *+ *  By default, making a context non-current implicitly forces a pipeline flush.+ *  On machines that support `GL_KHR_context_flush_control`, you can control+ *  whether a context performs this flush by setting the+ *  [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.+ *+ *  The specified window must have an OpenGL or OpenGL ES context.  Specifying+ *  a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT+ *  error.+ *+ *  @param[in] window The window whose context to make current, or `NULL` to+ *  detach the current context.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref context_current+ *  @sa glfwGetCurrentContext+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup context+ */+GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);++/*! @brief Returns the window whose context is current on the calling thread.+ *+ *  This function returns the window whose OpenGL or OpenGL ES context is+ *  current on the calling thread.+ *+ *  @return The window whose context is current, or `NULL` if no window's+ *  context is current.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref context_current+ *  @sa glfwMakeContextCurrent+ *+ *  @since Added in version 3.0.+ *+ *  @ingroup context+ */+GLFWAPI GLFWwindow* glfwGetCurrentContext(void);++/*! @brief Swaps the front and back buffers of the specified window.+ *+ *  This function swaps the front and back buffers of the specified window when+ *  rendering with OpenGL or OpenGL ES.  If the swap interval is greater than+ *  zero, the GPU driver waits the specified number of screen updates before+ *  swapping the buffers.+ *+ *  The specified window must have an OpenGL or OpenGL ES context.  Specifying+ *  a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT+ *  error.+ *+ *  This function does not apply to Vulkan.  If you are rendering with Vulkan,+ *  see `vkQueuePresentKHR` instead.+ *+ *  @param[in] window The window whose buffers to swap.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.+ *+ *  @remark __EGL:__ The context of the specified window must be current on the+ *  calling thread.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref buffer_swap+ *  @sa glfwSwapInterval+ *+ *  @since Added in version 1.0.+ *  @glfw3 Added window handle parameter.+ *+ *  @ingroup window+ */+GLFWAPI void glfwSwapBuffers(GLFWwindow* window);++/*! @brief Sets the swap interval for the current context.+ *+ *  This function sets the swap interval for the current OpenGL or OpenGL ES+ *  context, i.e. the number of screen updates to wait from the time @ref+ *  glfwSwapBuffers was called before swapping the buffers and returning.  This+ *  is sometimes called _vertical synchronization_, _vertical retrace+ *  synchronization_ or just _vsync_.+ *+ *  Contexts that support either of the `WGL_EXT_swap_control_tear` and+ *  `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,+ *  which allow the driver to swap even if a frame arrives a little bit late.+ *  You can check for the presence of these extensions using @ref+ *  glfwExtensionSupported.  For more information about swap tearing, see the+ *  extension specifications.+ *+ *  A context must be current on the calling thread.  Calling this function+ *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.+ *+ *  This function does not apply to Vulkan.  If you are rendering with Vulkan,+ *  see the present mode of your swapchain instead.+ *+ *  @param[in] interval The minimum number of screen updates to wait for+ *  until the buffers are swapped by @ref glfwSwapBuffers.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.+ *+ *  @remark This function is not called during context creation, leaving the+ *  swap interval set to whatever is the default on that platform.  This is done+ *  because some swap interval extensions used by GLFW do not allow the swap+ *  interval to be reset to zero once it has been set to a non-zero value.+ *+ *  @remark Some GPU drivers do not honor the requested swap interval, either+ *  because of a user setting that overrides the application's request or due to+ *  bugs in the driver.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref buffer_swap+ *  @sa glfwSwapBuffers+ *+ *  @since Added in version 1.0.+ *+ *  @ingroup context+ */+GLFWAPI void glfwSwapInterval(int interval);++/*! @brief Returns whether the specified extension is available.+ *+ *  This function returns whether the specified+ *  [API extension](@ref context_glext) is supported by the current OpenGL or+ *  OpenGL ES context.  It searches both for client API extension and context+ *  creation API extensions.+ *+ *  A context must be current on the calling thread.  Calling this function+ *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.+ *+ *  As this functions retrieves and searches one or more extension strings each+ *  call, it is recommended that you cache its results if it is going to be used+ *  frequently.  The extension strings will not change during the lifetime of+ *  a context, so there is no danger in doing this.+ *+ *  This function does not apply to Vulkan.  If you are using Vulkan, see @ref+ *  glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties`+ *  and `vkEnumerateDeviceExtensionProperties` instead.+ *+ *  @param[in] extension The ASCII encoded name of the extension.+ *  @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`+ *  otherwise.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref+ *  GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref context_glext+ *  @sa glfwGetProcAddress+ *+ *  @since Added in version 1.0.+ *+ *  @ingroup context+ */+GLFWAPI int glfwExtensionSupported(const char* extension);++/*! @brief Returns the address of the specified function for the current+ *  context.+ *+ *  This function returns the address of the specified OpenGL or OpenGL ES+ *  [core or extension function](@ref context_glext), if it is supported+ *  by the current context.+ *+ *  A context must be current on the calling thread.  Calling this function+ *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.+ *+ *  This function does not apply to Vulkan.  If you are rendering with Vulkan,+ *  see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and+ *  `vkGetDeviceProcAddr` instead.+ *+ *  @param[in] procname The ASCII encoded name of the function.+ *  @return The address of the function, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.+ *+ *  @remark The address of a given function is not guaranteed to be the same+ *  between contexts.+ *+ *  @remark This function may return a non-`NULL` address despite the+ *  associated version or extension not being available.  Always check the+ *  context version or extension string first.+ *+ *  @pointer_lifetime The returned function pointer is valid until the context+ *  is destroyed or the library is terminated.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref context_glext+ *  @sa glfwExtensionSupported+ *+ *  @since Added in version 1.0.+ *+ *  @ingroup context+ */+GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);++/*! @brief Returns whether the Vulkan loader has been found.+ *+ *  This function returns whether the Vulkan loader has been found.  This check+ *  is performed by @ref glfwInit.+ *+ *  The availability of a Vulkan loader does not by itself guarantee that window+ *  surface creation or even device creation is possible.  Call @ref+ *  glfwGetRequiredInstanceExtensions to check whether the extensions necessary+ *  for Vulkan surface creation are available and @ref+ *  glfwGetPhysicalDevicePresentationSupport to check whether a queue family of+ *  a physical device supports image presentation.+ *+ *  @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref vulkan_support+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup vulkan+ */+GLFWAPI int glfwVulkanSupported(void);++/*! @brief Returns the Vulkan instance extensions required by GLFW.+ *+ *  This function returns an array of names of Vulkan instance extensions required+ *  by GLFW for creating Vulkan surfaces for GLFW windows.  If successful, the+ *  list will always contains `VK_KHR_surface`, so if you don't require any+ *  additional extensions you can pass this list directly to the+ *  `VkInstanceCreateInfo` struct.+ *+ *  If Vulkan is not available on the machine, this function returns `NULL` and+ *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported+ *  to check whether Vulkan is available.+ *+ *  If Vulkan is available but no set of extensions allowing window surface+ *  creation was found, this function returns `NULL`.  You may still use Vulkan+ *  for off-screen rendering and compute work.+ *+ *  @param[out] count Where to store the number of extensions in the returned+ *  array.  This is set to zero if an error occurred.+ *  @return An array of ASCII encoded extension names, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_API_UNAVAILABLE.+ *+ *  @remarks Additional extensions may be required by future versions of GLFW.+ *  You should check if any extensions you wish to enable are already in the+ *  returned array, as it is an error to specify an extension more than once in+ *  the `VkInstanceCreateInfo` struct.+ *+ *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You+ *  should not free it yourself.  It is guaranteed to be valid only until the+ *  library is terminated.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref vulkan_ext+ *  @sa glfwCreateWindowSurface+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup vulkan+ */+GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);++#if defined(VK_VERSION_1_0)++/*! @brief Returns the address of the specified Vulkan instance function.+ *+ *  This function returns the address of the specified Vulkan core or extension+ *  function for the specified instance.  If instance is set to `NULL` it can+ *  return any function exported from the Vulkan loader, including at least the+ *  following functions:+ *+ *  - `vkEnumerateInstanceExtensionProperties`+ *  - `vkEnumerateInstanceLayerProperties`+ *  - `vkCreateInstance`+ *  - `vkGetInstanceProcAddr`+ *+ *  If Vulkan is not available on the machine, this function returns `NULL` and+ *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported+ *  to check whether Vulkan is available.+ *+ *  This function is equivalent to calling `vkGetInstanceProcAddr` with+ *  a platform-specific query of the Vulkan loader as a fallback.+ *+ *  @param[in] instance The Vulkan instance to query, or `NULL` to retrieve+ *  functions related to instance creation.+ *  @param[in] procname The ASCII encoded name of the function.+ *  @return The address of the function, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ *  GLFW_API_UNAVAILABLE.+ *+ *  @pointer_lifetime The returned function pointer is valid until the library+ *  is terminated.+ *+ *  @thread_safety This function may be called from any thread.+ *+ *  @sa @ref vulkan_proc+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup vulkan+ */+GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);++/*! @brief Returns whether the specified queue family can present images.+ *+ *  This function returns whether the specified queue family of the specified+ *  physical device supports presentation to the platform GLFW was built for.+ *+ *  If Vulkan or the required window surface creation instance extensions are+ *  not available on the machine, or if the specified instance was not created+ *  with the required extensions, this function returns `GLFW_FALSE` and+ *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported+ *  to check whether Vulkan is available and @ref+ *  glfwGetRequiredInstanceExtensions to check what instance extensions are+ *  required.+ *+ *  @param[in] instance The instance that the physical device belongs to.+ *  @param[in] device The physical device that the queue family belongs to.+ *  @param[in] queuefamily The index of the queue family to query.+ *  @return `GLFW_TRUE` if the queue family supports presentation, or+ *  `GLFW_FALSE` otherwise.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.+ *+ *  @thread_safety This function may be called from any thread.  For+ *  synchronization details of Vulkan objects, see the Vulkan specification.+ *+ *  @sa @ref vulkan_present+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup vulkan+ */+GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);++/*! @brief Creates a Vulkan surface for the specified window.+ *+ *  This function creates a Vulkan surface for the specified window.+ *+ *  If the Vulkan loader was not found at initialization, this function returns+ *  `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE+ *  error.  Call @ref glfwVulkanSupported to check whether the Vulkan loader was+ *  found.+ *+ *  If the required window surface creation instance extensions are not+ *  available or if the specified instance was not created with these extensions+ *  enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and+ *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref+ *  glfwGetRequiredInstanceExtensions to check what instance extensions are+ *  required.+ *+ *  The window surface must be destroyed before the specified Vulkan instance.+ *  It is the responsibility of the caller to destroy the window surface.  GLFW+ *  does not destroy it for you.  Call `vkDestroySurfaceKHR` to destroy the+ *  surface.+ *+ *  @param[in] instance The Vulkan instance to create the surface in.+ *  @param[in] window The window to create the surface for.+ *  @param[in] allocator The allocator to use, or `NULL` to use the default+ *  allocator.+ *  @param[out] surface Where to store the handle of the surface.  This is set+ *  to `VK_NULL_HANDLE` if an error occurred.+ *  @return `VK_SUCCESS` if successful, or a Vulkan error code if an+ *  [error](@ref error_handling) occurred.+ *+ *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ *  GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.+ *+ *  @remarks If an error occurs before the creation call is made, GLFW returns+ *  the Vulkan error code most appropriate for the error.  Appropriate use of+ *  @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should+ *  eliminate almost all occurrences of these errors.+ *+ *  @thread_safety This function may be called from any thread.  For+ *  synchronization details of Vulkan objects, see the Vulkan specification.+ *+ *  @sa @ref vulkan_surface+ *  @sa glfwGetRequiredInstanceExtensions+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup vulkan+ */+GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);++#endif /*VK_VERSION_1_0*/   /*************************************************************************
glfw/include/GLFW/glfw3native.h view
@@ -1,9 +1,9 @@ /*************************************************************************- * GLFW 3.1 - www.glfw.org+ * GLFW 3.2 - www.glfw.org  * A library for OpenGL, window and input  *------------------------------------------------------------------------  * Copyright (c) 2002-2006 Marcus Geelnard- * Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+ * Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -38,20 +38,30 @@  * Doxygen documentation  *************************************************************************/ +/*! @file glfw3native.h+ *  @brief The header of the native access functions.+ *+ *  This is the header file of the native access functions.  See @ref native for+ *  more information.+ */ /*! @defgroup native Native access  *  *  **By using the native access functions you assert that you know what you're  *  doing and how to fix problems caused by using them.  If you don't, you  *  shouldn't be using them.**  *- *  Before the inclusion of @ref glfw3native.h, you must define exactly one- *  window system API macro and exactly one context creation API macro.  Failure- *  to do this will cause a compile-time error.+ *  Before the inclusion of @ref glfw3native.h, you may define exactly one+ *  window system API macro and zero or more context creation API macros.  *+ *  The chosen backends must match those the library was compiled for.  Failure+ *  to do this will cause a link-time error.+ *  *  The available window API macros are:  *  * `GLFW_EXPOSE_NATIVE_WIN32`  *  * `GLFW_EXPOSE_NATIVE_COCOA`  *  * `GLFW_EXPOSE_NATIVE_X11`+ *  * `GLFW_EXPOSE_NATIVE_WAYLAND`+ *  * `GLFW_EXPOSE_NATIVE_MIR`  *  *  The available context API macros are:  *  * `GLFW_EXPOSE_NATIVE_WGL`@@ -86,20 +96,23 @@ #elif defined(GLFW_EXPOSE_NATIVE_X11)  #include <X11/Xlib.h>  #include <X11/extensions/Xrandr.h>-#else- #error "No window API selected"+#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)+ #include <wayland-client.h>+#elif defined(GLFW_EXPOSE_NATIVE_MIR)+ #include <mir_toolkit/mir_client_library.h> #endif  #if defined(GLFW_EXPOSE_NATIVE_WGL)  /* WGL is declared by windows.h */-#elif defined(GLFW_EXPOSE_NATIVE_NSGL)+#endif+#if defined(GLFW_EXPOSE_NATIVE_NSGL)  /* NSGL is declared by Cocoa.h */-#elif defined(GLFW_EXPOSE_NATIVE_GLX)+#endif+#if defined(GLFW_EXPOSE_NATIVE_GLX)  #include <GL/glx.h>-#elif defined(GLFW_EXPOSE_NATIVE_EGL)+#endif+#if defined(GLFW_EXPOSE_NATIVE_EGL)  #include <EGL/egl.h>-#else- #error "No context API selected" #endif  @@ -114,11 +127,10 @@  *  of the specified monitor, or `NULL` if an [error](@ref error_handling)  *  occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.1.+ *  @since Added in version 3.1.  *  *  @ingroup native  */@@ -130,11 +142,10 @@  *  `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.1.+ *  @since Added in version 3.1.  *  *  @ingroup native  */@@ -145,11 +156,10 @@  *  @return The `HWND` of the specified window, or `NULL` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */@@ -162,11 +172,10 @@  *  @return The `HGLRC` of the specified window, or `NULL` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */@@ -179,11 +188,10 @@  *  @return The `CGDirectDisplayID` of the specified monitor, or  *  `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.1.+ *  @since Added in version 3.1.  *  *  @ingroup native  */@@ -194,11 +202,10 @@  *  @return The `NSWindow` of the specified window, or `nil` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */@@ -211,11 +218,10 @@  *  @return The `NSOpenGLContext` of the specified window, or `nil` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */@@ -228,11 +234,10 @@  *  @return The `Display` used by GLFW, or `NULL` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */@@ -243,11 +248,10 @@  *  @return The `RRCrtc` of the specified monitor, or `None` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.1.+ *  @since Added in version 3.1.  *  *  @ingroup native  */@@ -258,11 +262,10 @@  *  @return The `RROutput` of the specified monitor, or `None` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.1.+ *  @since Added in version 3.1.  *  *  @ingroup native  */@@ -273,11 +276,10 @@  *  @return The `Window` of the specified window, or `None` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */@@ -290,28 +292,128 @@  *  @return The `GLXContext` of the specified window, or `NULL` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);++/*! @brief Returns the `GLXWindow` of the specified window.+ *+ *  @return The `GLXWindow` of the specified window, or `None` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup native+ */+GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); #endif +#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)+/*! @brief Returns the `struct wl_display*` used by GLFW.+ *+ *  @return The `struct wl_display*` used by GLFW, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup native+ */+GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);++/*! @brief Returns the `struct wl_output*` of the specified monitor.+ *+ *  @return The `struct wl_output*` of the specified monitor, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup native+ */+GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);++/*! @brief Returns the main `struct wl_surface*` of the specified window.+ *+ *  @return The main `struct wl_surface*` of the specified window, or `NULL` if+ *  an [error](@ref error_handling) occurred.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup native+ */+GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);+#endif++#if defined(GLFW_EXPOSE_NATIVE_MIR)+/*! @brief Returns the `MirConnection*` used by GLFW.+ *+ *  @return The `MirConnection*` used by GLFW, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup native+ */+GLFWAPI MirConnection* glfwGetMirDisplay(void);++/*! @brief Returns the Mir output ID of the specified monitor.+ *+ *  @return The Mir output ID of the specified monitor, or zero if an+ *  [error](@ref error_handling) occurred.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup native+ */+GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);++/*! @brief Returns the `MirSurface*` of the specified window.+ *+ *  @return The `MirSurface*` of the specified window, or `NULL` if an+ *  [error](@ref error_handling) occurred.+ *+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.+ *+ *  @since Added in version 3.2.+ *+ *  @ingroup native+ */+GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);+#endif+ #if defined(GLFW_EXPOSE_NATIVE_EGL) /*! @brief Returns the `EGLDisplay` used by GLFW.  *  *  @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */@@ -322,11 +424,10 @@  *  @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */@@ -337,11 +438,10 @@  *  @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an  *  [error](@ref error_handling) occurred.  *- *  @par Thread Safety- *  This function may be called from any thread.  Access is not synchronized.+ *  @thread_safety This function may be called from any thread.  Access is not+ *  synchronized.  *- *  @par History- *  Added in GLFW 3.0.+ *  @since Added in version 3.0.  *  *  @ingroup native  */
glfw/src/cocoa_init.m view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 OS X - www.glfw.org+// GLFW 3.2 OS X - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.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@@ -72,7 +72,10 @@ // static void createKeyTables(void) {+    int scancode;+     memset(_glfw.ns.publicKeys, -1, sizeof(_glfw.ns.publicKeys));+    memset(_glfw.ns.nativeKeys, -1, sizeof(_glfw.ns.nativeKeys));      _glfw.ns.publicKeys[0x1D] = GLFW_KEY_0;     _glfw.ns.publicKeys[0x12] = GLFW_KEY_1;@@ -188,9 +191,107 @@     _glfw.ns.publicKeys[0x51] = GLFW_KEY_KP_EQUAL;     _glfw.ns.publicKeys[0x43] = GLFW_KEY_KP_MULTIPLY;     _glfw.ns.publicKeys[0x4E] = GLFW_KEY_KP_SUBTRACT;++    for (scancode = 0;  scancode < 256;  scancode++)+    {+        // Store the reverse translation for faster key name lookup+        if (_glfw.ns.publicKeys[scancode] >= 0)+            _glfw.ns.nativeKeys[_glfw.ns.publicKeys[scancode]] = scancode;+    } } +// Retrieve Unicode data for the current keyboard layout+//+static GLFWbool updateUnicodeDataNS(void)+{+    if (_glfw.ns.inputSource)+    {+        CFRelease(_glfw.ns.inputSource);+        _glfw.ns.inputSource = NULL;+        _glfw.ns.unicodeData = nil;+    } +    _glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();+    if (!_glfw.ns.inputSource)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Cocoa: Failed to retrieve keyboard layout input source");+        return GLFW_FALSE;+    }++    _glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,+                                                     kTISPropertyUnicodeKeyLayoutData);+    if (!_glfw.ns.unicodeData)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Cocoa: Failed to retrieve keyboard layout Unicode data");+        return GLFW_FALSE;+    }++    return GLFW_TRUE;+}++// Load HIToolbox.framework and the TIS symbols we need from it+//+static GLFWbool initializeTIS(void)+{+    // This works only because Cocoa has already loaded it properly+    _glfw.ns.tis.bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));+    if (!_glfw.ns.tis.bundle)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Cocoa: Failed to load HIToolbox.framework");+        return GLFW_FALSE;+    }++    CFStringRef* kPropertyUnicodeKeyLayoutData =+        CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,+                                      CFSTR("kTISPropertyUnicodeKeyLayoutData"));+    CFStringRef* kNotifySelectedKeyboardInputSourceChanged =+        CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,+                                      CFSTR("kTISNotifySelectedKeyboardInputSourceChanged"));+    _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =+        CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,+                                          CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));+    _glfw.ns.tis.GetInputSourceProperty =+        CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,+                                          CFSTR("TISGetInputSourceProperty"));+    _glfw.ns.tis.GetKbdType =+        CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,+                                          CFSTR("LMGetKbdType"));++    if (!kPropertyUnicodeKeyLayoutData ||+        !kNotifySelectedKeyboardInputSourceChanged ||+        !TISCopyCurrentKeyboardLayoutInputSource ||+        !TISGetInputSourceProperty ||+        !LMGetKbdType)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Cocoa: Failed to load TIS API symbols");+        return GLFW_FALSE;+    }++    _glfw.ns.tis.kPropertyUnicodeKeyLayoutData =+        *kPropertyUnicodeKeyLayoutData;+    _glfw.ns.tis.kNotifySelectedKeyboardInputSourceChanged =+        *kNotifySelectedKeyboardInputSourceChanged;++    return updateUnicodeDataNS();+}++@interface GLFWLayoutListener : NSObject+@end++@implementation GLFWLayoutListener++- (void)selectedKeyboardInputSourceChanged:(NSObject* )object+{+    updateUnicodeDataNS();+}++@end++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW platform API                      ////// //////////////////////////////////////////////////////////////////////////@@ -199,6 +300,13 @@ {     _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; +    _glfw.ns.listener = [[GLFWLayoutListener alloc] init];+    [[NSDistributedNotificationCenter defaultCenter]+        addObserver:_glfw.ns.listener+           selector:@selector(selectedKeyboardInputSourceChanged:)+               name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged+             object:nil];+ #if defined(_GLFW_USE_CHDIR)     changeToResourcesDirectory(); #endif@@ -207,21 +315,31 @@      _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);     if (!_glfw.ns.eventSource)-        return GL_FALSE;+        return GLFW_FALSE;      CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0); -    if (!_glfwInitContextAPI())-        return GL_FALSE;+    if (!initializeTIS())+        return GLFW_FALSE; -    _glfwInitTimer();-    _glfwInitJoysticks();+    if (!_glfwInitThreadLocalStoragePOSIX())+        return GLFW_FALSE; -    return GL_TRUE;+    _glfwInitTimerNS();+    _glfwInitJoysticksNS();++    return GLFW_TRUE; }  void _glfwPlatformTerminate(void) {+    if (_glfw.ns.inputSource)+    {+        CFRelease(_glfw.ns.inputSource);+        _glfw.ns.inputSource = NULL;+        _glfw.ns.unicodeData = nil;+    }+     if (_glfw.ns.eventSource)     {         CFRelease(_glfw.ns.eventSource);@@ -235,24 +353,34 @@         _glfw.ns.delegate = nil;     } -    [_glfw.ns.autoreleasePool release];-    _glfw.ns.autoreleasePool = nil;+    if (_glfw.ns.listener)+    {+        [[NSDistributedNotificationCenter defaultCenter]+            removeObserver:_glfw.ns.listener+                      name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged+                    object:nil];+        [[NSDistributedNotificationCenter defaultCenter]+            removeObserver:_glfw.ns.listener];+        [_glfw.ns.listener release];+        _glfw.ns.listener = nil;+    }      [_glfw.ns.cursor release];     _glfw.ns.cursor = nil;      free(_glfw.ns.clipboardString); -    _glfwTerminateJoysticks();-    _glfwTerminateContextAPI();+    _glfwTerminateNSGL();+    _glfwTerminateJoysticksNS();+    _glfwTerminateThreadLocalStoragePOSIX();++    [_glfw.ns.autoreleasePool release];+    _glfw.ns.autoreleasePool = nil; }  const char* _glfwPlatformGetVersionString(void) {-    const char* version = _GLFW_VERSION_NUMBER " Cocoa"-#if defined(_GLFW_NSGL)-        " NSGL"-#endif+    return _GLFW_VERSION_NUMBER " Cocoa NSGL" #if defined(_GLFW_USE_CHDIR)         " chdir" #endif@@ -266,7 +394,5 @@         " dynamic" #endif         ;--    return version; } 
+ glfw/src/cocoa_joystick.h view
@@ -0,0 +1,60 @@+//========================================================================+// GLFW 3.2 Cocoa - www.glfw.org+//------------------------------------------------------------------------+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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.+//+//========================================================================++#ifndef _glfw3_cocoa_joystick_h_+#define _glfw3_cocoa_joystick_h_++#include <IOKit/IOKitLib.h>+#include <IOKit/IOCFPlugIn.h>+#include <IOKit/hid/IOHIDLib.h>+#include <IOKit/hid/IOHIDKeys.h>++#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \+    _GLFWjoystickNS ns_js[GLFW_JOYSTICK_LAST + 1]+++// Cocoa-specific per-joystick data+//+typedef struct _GLFWjoystickNS+{+    GLFWbool        present;+    char            name[256];++    IOHIDDeviceRef deviceRef;++    CFMutableArrayRef axisElements;+    CFMutableArrayRef buttonElements;+    CFMutableArrayRef hatElements;++    float*          axes;+    unsigned char*  buttons;+} _GLFWjoystickNS;+++void _glfwInitJoysticksNS(void);+void _glfwTerminateJoysticksNS(void);++#endif // _glfw3_cocoa_joystick_h_
+ glfw/src/cocoa_joystick.m view
@@ -0,0 +1,511 @@+//========================================================================+// GLFW 3.2 Cocoa - www.glfw.org+//------------------------------------------------------------------------+// Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.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+// 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 <unistd.h>+#include <ctype.h>+#include <string.h>++#include <mach/mach.h>+#include <mach/mach_error.h>++#include <CoreFoundation/CoreFoundation.h>+#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>+++// Joystick element information+//+typedef struct _GLFWjoyelementNS+{+    IOHIDElementRef elementRef;++    long min;+    long max;++    long minReport;+    long maxReport;++} _GLFWjoyelementNS;+++static void getElementsCFArrayHandler(const void* value, void* parameter);++// Adds an element to the specified joystick+//+static void addJoystickElement(_GLFWjoystickNS* js,+                               IOHIDElementRef elementRef)+{+    IOHIDElementType elementType;+    long usagePage, usage;+    CFMutableArrayRef elementsArray = NULL;++    elementType = IOHIDElementGetType(elementRef);+    usagePage = IOHIDElementGetUsagePage(elementRef);+    usage = IOHIDElementGetUsage(elementRef);++    if ((elementType != kIOHIDElementTypeInput_Axis) &&+        (elementType != kIOHIDElementTypeInput_Button) &&+        (elementType != kIOHIDElementTypeInput_Misc))+    {+        return;+    }++    switch (usagePage)+    {+        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:+                    elementsArray = js->axisElements;+                    break;+                case kHIDUsage_GD_Hatswitch:+                    elementsArray = js->hatElements;+                    break;+            }++            break;+        }++        case kHIDPage_Button:+            elementsArray = js->buttonElements;+            break;+        default:+            break;+    }++    if (elementsArray)+    {+        _GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));++        CFArrayAppendValue(elementsArray, element);++        element->elementRef = elementRef;++        element->minReport = IOHIDElementGetLogicalMin(elementRef);+        element->maxReport = IOHIDElementGetLogicalMax(elementRef);+    }+}++// Adds an element to the specified joystick+//+static void getElementsCFArrayHandler(const void* value, void* parameter)+{+    if (CFGetTypeID(value) == IOHIDElementGetTypeID())+    {+        addJoystickElement((_GLFWjoystickNS*) parameter,+                           (IOHIDElementRef) value);+    }+}++// Returns the value of the specified element of the specified joystick+//+static long getElementValue(_GLFWjoystickNS* js, _GLFWjoyelementNS* element)+{+    IOReturn result = kIOReturnSuccess;+    IOHIDValueRef valueRef;+    long value = 0;++    if (js && element && js->deviceRef)+    {+        result = IOHIDDeviceGetValue(js->deviceRef,+                                     element->elementRef,+                                     &valueRef);++        if (kIOReturnSuccess == result)+        {+            value = IOHIDValueGetIntegerValue(valueRef);++            // Record min and max for auto calibration+            if (value < element->minReport)+                element->minReport = value;+            if (value > element->maxReport)+                element->maxReport = value;+        }+    }++    // Auto user scale+    return value;+}++// Removes the specified joystick+//+static void removeJoystick(_GLFWjoystickNS* js)+{+    int i;++    if (!js->present)+        return;++    for (i = 0;  i < CFArrayGetCount(js->axisElements);  i++)+        free((void*) CFArrayGetValueAtIndex(js->axisElements, i));+    CFArrayRemoveAllValues(js->axisElements);+    CFRelease(js->axisElements);++    for (i = 0;  i < CFArrayGetCount(js->buttonElements);  i++)+        free((void*) CFArrayGetValueAtIndex(js->buttonElements, i));+    CFArrayRemoveAllValues(js->buttonElements);+    CFRelease(js->buttonElements);++    for (i = 0;  i < CFArrayGetCount(js->hatElements);  i++)+        free((void*) CFArrayGetValueAtIndex(js->hatElements, i));+    CFArrayRemoveAllValues(js->hatElements);+    CFRelease(js->hatElements);++    free(js->axes);+    free(js->buttons);++    memset(js, 0, sizeof(_GLFWjoystickNS));++    _glfwInputJoystickChange(js - _glfw.ns_js, GLFW_DISCONNECTED);+}++// Polls for joystick axis events and updates GLFW state+//+static GLFWbool pollJoystickAxisEvents(_GLFWjoystickNS* js)+{+    CFIndex i;++    if (!js->present)+        return GLFW_FALSE;++    for (i = 0;  i < CFArrayGetCount(js->axisElements);  i++)+    {+        _GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)+            CFArrayGetValueAtIndex(js->axisElements, i);++        long value = getElementValue(js, axis);+        long readScale = axis->maxReport - axis->minReport;++        if (readScale == 0)+            js->axes[i] = value;+        else+            js->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f;+    }++    return GLFW_TRUE;+}++// Polls for joystick button events and updates GLFW state+//+static GLFWbool pollJoystickButtonEvents(_GLFWjoystickNS* js)+{+    CFIndex i;+    int buttonIndex = 0;++    if (!js->present)+        return GLFW_FALSE;++    for (i = 0;  i < CFArrayGetCount(js->buttonElements);  i++)+    {+        _GLFWjoyelementNS* button = (_GLFWjoyelementNS*)+            CFArrayGetValueAtIndex(js->buttonElements, i);++        if (getElementValue(js, button))+            js->buttons[buttonIndex++] = GLFW_PRESS;+        else+            js->buttons[buttonIndex++] = GLFW_RELEASE;+    }++    for (i = 0;  i < CFArrayGetCount(js->hatElements);  i++)+    {+        _GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)+            CFArrayGetValueAtIndex(js->hatElements, i);++        // Bit fields of button presses for each direction, including nil+        const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };++        long j, value = getElementValue(js, hat);+        if (value < 0 || value > 8)+            value = 8;++        for (j = 0;  j < 4;  j++)+        {+            if (directions[value] & (1 << j))+                js->buttons[buttonIndex++] = GLFW_PRESS;+            else+                js->buttons[buttonIndex++] = GLFW_RELEASE;+        }+    }++    return GLFW_TRUE;+}++// Callback for user-initiated joystick addition+//+static void matchCallback(void* context,+                          IOReturn result,+                          void* sender,+                          IOHIDDeviceRef deviceRef)+{+    _GLFWjoystickNS* js;+    int joy;++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+    {+        if (_glfw.ns_js[joy].present && _glfw.ns_js[joy].deviceRef == deviceRef)+            return;+    }++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+    {+        if (!_glfw.ns_js[joy].present)+            break;+    }++    if (joy > GLFW_JOYSTICK_LAST)+        return;++    js = _glfw.ns_js + joy;+    js->present = GLFW_TRUE;+    js->deviceRef = deviceRef;++    CFStringRef name = IOHIDDeviceGetProperty(deviceRef,+                                              CFSTR(kIOHIDProductKey));+    if (name)+    {+        CFStringGetCString(name,+                           js->name,+                           sizeof(js->name),+                           kCFStringEncodingUTF8);+    }+    else+        strncpy(js->name, "Unknown", sizeof(js->name));++    js->axisElements = CFArrayCreateMutable(NULL, 0, NULL);+    js->buttonElements = CFArrayCreateMutable(NULL, 0, NULL);+    js->hatElements = CFArrayCreateMutable(NULL, 0, NULL);++    CFArrayRef arrayRef = IOHIDDeviceCopyMatchingElements(deviceRef,+                                                          NULL,+                                                          kIOHIDOptionsTypeNone);+    CFRange range = { 0, CFArrayGetCount(arrayRef) };+    CFArrayApplyFunction(arrayRef,+                         range,+                         getElementsCFArrayHandler,+                         (void*) js);++    CFRelease(arrayRef);++    js->axes = calloc(CFArrayGetCount(js->axisElements), sizeof(float));+    js->buttons = calloc(CFArrayGetCount(js->buttonElements) ++                         CFArrayGetCount(js->hatElements) * 4, 1);++    _glfwInputJoystickChange(joy, GLFW_CONNECTED);+}++// Callback for user-initiated joystick removal+//+static void removeCallback(void* context,+                           IOReturn result,+                           void* sender,+                           IOHIDDeviceRef deviceRef)+{+    int joy;++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+    {+        if (_glfw.ns_js[joy].deviceRef == deviceRef)+        {+            removeJoystick(_glfw.ns_js + joy);+            break;+        }+    }+}++// Creates a dictionary to match against devices with the specified usage page+// and usage+//+static CFMutableDictionaryRef createMatchingDictionary(long usagePage,+                                                       long usage)+{+    CFMutableDictionaryRef result =+        CFDictionaryCreateMutable(kCFAllocatorDefault,+                                  0,+                                  &kCFTypeDictionaryKeyCallBacks,+                                  &kCFTypeDictionaryValueCallBacks);++    if (result)+    {+        CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault,+                                             kCFNumberLongType,+                                             &usagePage);+        if (pageRef)+        {+            CFDictionarySetValue(result,+                                 CFSTR(kIOHIDDeviceUsagePageKey),+                                 pageRef);+            CFRelease(pageRef);++            CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault,+                                                  kCFNumberLongType,+                                                  &usage);+            if (usageRef)+            {+                CFDictionarySetValue(result,+                                     CFSTR(kIOHIDDeviceUsageKey),+                                     usageRef);+                CFRelease(usageRef);+            }+        }+    }++    return result;+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW internal API                      //////+//////////////////////////////////////////////////////////////////////////++// Initialize joystick interface+//+void _glfwInitJoysticksNS(void)+{+    CFMutableArrayRef matchingCFArrayRef;++    _glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,+                                             kIOHIDOptionsTypeNone);++    matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault,+                                              0,+                                              &kCFTypeArrayCallBacks);+    if (matchingCFArrayRef)+    {+        CFDictionaryRef matchingCFDictRef =+            createMatchingDictionary(kHIDPage_GenericDesktop,+                                     kHIDUsage_GD_Joystick);+        if (matchingCFDictRef)+        {+            CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef);+            CFRelease(matchingCFDictRef);+        }++        matchingCFDictRef = createMatchingDictionary(kHIDPage_GenericDesktop,+                                                     kHIDUsage_GD_GamePad);+        if (matchingCFDictRef)+        {+            CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef);+            CFRelease(matchingCFDictRef);+        }++        matchingCFDictRef =+            createMatchingDictionary(kHIDPage_GenericDesktop,+                                     kHIDUsage_GD_MultiAxisController);+        if (matchingCFDictRef)+        {+            CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef);+            CFRelease(matchingCFDictRef);+        }++        IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager,+                                              matchingCFArrayRef);+        CFRelease(matchingCFArrayRef);+    }++    IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,+                                               &matchCallback, NULL);+    IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,+                                              &removeCallback, NULL);++    IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,+                                    CFRunLoopGetMain(),+                                    kCFRunLoopDefaultMode);++    IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone);++    // Execute the run loop once in order to register any initially-attached+    // joysticks+    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);+}++// Close all opened joystick handles+//+void _glfwTerminateJoysticksNS(void)+{+    int joy;++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+    {+        _GLFWjoystickNS* js = _glfw.ns_js + joy;+        removeJoystick(js);+    }++    CFRelease(_glfw.ns.hidManager);+    _glfw.ns.hidManager = NULL;+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW platform API                      //////+//////////////////////////////////////////////////////////////////////////++int _glfwPlatformJoystickPresent(int joy)+{+    _GLFWjoystickNS* js = _glfw.ns_js + joy;+    return js->present;+}++const float* _glfwPlatformGetJoystickAxes(int joy, int* count)+{+    _GLFWjoystickNS* js = _glfw.ns_js + joy;+    if (!pollJoystickAxisEvents(js))+        return NULL;++    *count = (int) CFArrayGetCount(js->axisElements);+    return js->axes;+}++const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)+{+    _GLFWjoystickNS* js = _glfw.ns_js + joy;+    if (!pollJoystickButtonEvents(js))+        return NULL;++    *count = (int) CFArrayGetCount(js->buttonElements) ++             (int) CFArrayGetCount(js->hatElements) * 4;+    return js->buttons;+}++const char* _glfwPlatformGetJoystickName(int joy)+{+    _GLFWjoystickNS* js = _glfw.ns_js + joy;+    if (!js->present)+        return NULL;++    return js->name;+}+
glfw/src/cocoa_monitor.m view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 OS X - www.glfw.org+// GLFW 3.2 OS X - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -28,11 +28,9 @@ #include "internal.h"  #include <stdlib.h>-#include <stdlib.h> #include <limits.h>  #include <IOKit/graphics/IOGraphicsLib.h>-#include <IOKit/graphics/IOGraphicsLib.h> #include <CoreVideo/CVBase.h> #include <CoreVideo/CVDisplayLink.h> #include <ApplicationServices/ApplicationServices.h>@@ -57,7 +55,8 @@                                                  (const void**) &value))     {         // This may happen if a desktop Mac is running headless-        _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name");+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Cocoa: Failed to retrieve display name");          CFRelease(info);         return strdup("Unknown");@@ -65,7 +64,7 @@      size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),                                              kCFStringEncodingUTF8);-    name = calloc(size + 1, sizeof(char));+    name = calloc(size + 1, 1);     CFStringGetCString(value, name, size, kCFStringEncodingUTF8);      CFRelease(info);@@ -75,28 +74,28 @@  // Check whether the display mode should be included in enumeration //-static GLboolean modeIsGood(CGDisplayModeRef mode)+static GLFWbool modeIsGood(CGDisplayModeRef mode) {     uint32_t flags = CGDisplayModeGetIOFlags(mode);     if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))-        return GL_FALSE;+        return GLFW_FALSE;      if (flags & kDisplayModeInterlacedFlag)-        return GL_FALSE;+        return GLFW_FALSE;      if (flags & kDisplayModeStretchedFlag)-        return GL_FALSE;+        return GLFW_FALSE;      CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);     if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&         CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))     {         CFRelease(format);-        return GL_FALSE;+        return GLFW_FALSE;     }      CFRelease(format);-    return GL_TRUE;+    return GLFW_TRUE; }  // Convert Core Graphics display mode to GLFW video mode@@ -165,7 +164,7 @@  // Change the current video mode //-GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)+GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) {     CFArrayRef modes;     CFIndex count, i;@@ -177,7 +176,7 @@     best = _glfwChooseVideoMode(monitor, desired);     _glfwPlatformGetVideoMode(monitor, &current);     if (_glfwCompareVideoModes(&current, best) == 0)-        return GL_TRUE;+        return GLFW_TRUE;      CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); @@ -215,15 +214,15 @@     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Cocoa: Monitor mode list changed");-        return GL_FALSE;+        return GLFW_FALSE;     } -    return GL_TRUE;+    return GLFW_TRUE; }  // Restore the previously saved (original) video mode //-void _glfwRestoreVideoMode(_GLFWmonitor* monitor)+void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor) {     if (monitor->ns.previousMode)     {@@ -251,53 +250,29 @@     *count = 0;      CGGetOnlineDisplayList(0, NULL, &displayCount);-     displays = calloc(displayCount, sizeof(CGDirectDisplayID));     monitors = calloc(displayCount, sizeof(_GLFWmonitor*));      CGGetOnlineDisplayList(displayCount, displays, &displayCount); -    NSArray* screens = [NSScreen screens];-     for (i = 0;  i < displayCount;  i++)     {-        int j;+        _GLFWmonitor* monitor;          if (CGDisplayIsAsleep(displays[i]))             continue; -        CGDirectDisplayID screenDisplayID = CGDisplayMirrorsDisplay(displays[i]);-        if (screenDisplayID == kCGNullDirectDisplay)-            screenDisplayID = displays[i];-         const CGSize size = CGDisplayScreenSize(displays[i]);         char* name = getDisplayName(displays[i]); -        monitors[found] = _glfwAllocMonitor(name, size.width, size.height);-        monitors[found]->ns.displayID = displays[i];+        monitor = _glfwAllocMonitor(name, size.width, size.height);+        monitor->ns.displayID  = displays[i];+        monitor->ns.unitNumber = CGDisplayUnitNumber(displays[i]);          free(name); -        for (j = 0;  j < [screens count];  j++)-        {-            NSScreen* screen = [screens objectAtIndex:j];-            NSDictionary* dictionary = [screen deviceDescription];-            NSNumber* number = [dictionary objectForKey:@"NSScreenNumber"];--            if ([number unsignedIntegerValue] == screenDisplayID)-            {-                monitors[found]->ns.screen = screen;-                break;-            }-        }--        if (monitors[found]->ns.screen)-            found++;-        else-        {-            _glfwFreeMonitor(monitors[found]);-            monitors[found] = NULL;-        }+        found++;+        monitors[found - 1] = monitor;     }      free(displays);@@ -306,9 +281,11 @@     return monitors; } -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)+GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) {-    return first->ns.displayID == second->ns.displayID;+    // HACK: Compare unit numbers instead of display IDs to work around display+    //       replacement on machines with automatic graphics switching+    return first->ns.unitNumber == second->ns.unitNumber; }  void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)@@ -321,22 +298,22 @@         *ypos = (int) bounds.origin.y; } -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) {     CFArrayRef modes;-    CFIndex count, i, j;+    CFIndex found, i, j;     GLFWvidmode* result;     CVDisplayLinkRef link; +    *count = 0;+     CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);      modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);-    count = CFArrayGetCount(modes);--    result = calloc(count, sizeof(GLFWvidmode));-    *found = 0;+    found = CFArrayGetCount(modes);+    result = calloc(found, sizeof(GLFWvidmode)); -    for (i = 0;  i < count;  i++)+    for (i = 0;  i < found;  i++)     {         CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);         if (!modeIsGood(dm))@@ -344,24 +321,21 @@          const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); -        for (j = 0;  j < *found;  j++)+        for (j = 0;  j < *count;  j++)         {             if (_glfwCompareVideoModes(result + j, &mode) == 0)                 break;         } -        if (i < *found)-        {-            // This is a duplicate, so skip it+        // Skip duplicate modes+        if (i < *count)             continue;-        } -        result[*found] = mode;-        (*found)++;+        (*count)++;+        result[*count - 1] = mode;     }      CFRelease(modes);-     CVDisplayLinkRelease(link);     return result; }
glfw/src/cocoa_platform.h view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 OS X - www.glfw.org+// GLFW 3.2 OS X - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.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@@ -24,28 +24,28 @@ // //======================================================================== -#ifndef _cocoa_platform_h_-#define _cocoa_platform_h_-+#ifndef _glfw3_cocoa_platform_h_+#define _glfw3_cocoa_platform_h_  #include <stdint.h>+#include <dlfcn.h>  #if defined(__OBJC__)+#import <Carbon/Carbon.h> #import <Cocoa/Cocoa.h> #else+#include <Carbon/Carbon.h> #include <ApplicationServices/ApplicationServices.h> typedef void* id; #endif  #include "posix_tls.h"--#if defined(_GLFW_NSGL)- #include "nsgl_context.h"-#else- #error "No supported context creation API selected"-#endif+#include "cocoa_joystick.h"+#include "nsgl_context.h" -#include "iokit_joystick.h"+#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)+#define _glfw_dlclose(handle) dlclose(handle)+#define _glfw_dlsym(handle, name) dlsym(handle, name)  #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowNS  ns #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns@@ -53,38 +53,67 @@ #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorNS ns #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorNS  ns +#define _GLFW_EGL_CONTEXT_STATE+#define _GLFW_EGL_LIBRARY_CONTEXT_STATE +// HIToolbox.framework pointer typedefs+#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData+#define kTISNotifySelectedKeyboardInputSourceChanged _glfw.ns.tis.kNotifySelectedKeyboardInputSourceChanged+typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);+#define TISCopyCurrentKeyboardLayoutInputSource _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource+typedef void* (*PFN_TISGetInputSourceProperty)(TISInputSourceRef,CFStringRef);+#define TISGetInputSourceProperty _glfw.ns.tis.GetInputSourceProperty+typedef UInt8 (*PFN_LMGetKbdType)(void);+#define LMGetKbdType _glfw.ns.tis.GetKbdType++ // Cocoa-specific per-window data // typedef struct _GLFWwindowNS {     id              object;-    id	            delegate;+    id              delegate;     id              view;-    unsigned int    modifierFlags;      // The total sum of the distances the cursor has been warped     // since the last cursor motion event was processed     // This is kept to counteract Cocoa doing the same internally-    double          warpDeltaX, warpDeltaY;+    double          cursorWarpDeltaX, cursorWarpDeltaY;  } _GLFWwindowNS; - // Cocoa-specific global data // typedef struct _GLFWlibraryNS {-    CGEventSourceRef eventSource;-    id              delegate;-    id              autoreleasePool;-    id              cursor;+    CGEventSourceRef    eventSource;+    id                  delegate;+    id                  autoreleasePool;+    id                  cursor;+    TISInputSourceRef   inputSource;+    IOHIDManagerRef     hidManager;+    id                  unicodeData;+    id                  listener; -    short int       publicKeys[256];-    char*           clipboardString;+    char                keyName[64];+    short int           publicKeys[256];+    short int           nativeKeys[GLFW_KEY_LAST + 1];+    char*               clipboardString;+    // Where to place the cursor when re-enabled+    double              restoreCursorPosX, restoreCursorPosY;+    // The window whose disabled cursor mode is active+    _GLFWwindow*        disabledCursorWindow; -} _GLFWlibraryNS;+    struct {+        CFBundleRef     bundle;+        PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource;+        PFN_TISGetInputSourceProperty GetInputSourceProperty;+        PFN_LMGetKbdType GetKbdType;+        CFStringRef     kPropertyUnicodeKeyLayoutData;+        CFStringRef     kNotifySelectedKeyboardInputSourceChanged;+    } tis; +} _GLFWlibraryNS;  // Cocoa-specific per-monitor data //@@ -92,11 +121,10 @@ {     CGDirectDisplayID   displayID;     CGDisplayModeRef    previousMode;-    id                  screen;+    uint32_t            unitNumber;  } _GLFWmonitorNS; - // Cocoa-specific per-cursor data // typedef struct _GLFWcursorNS@@ -105,20 +133,18 @@  } _GLFWcursorNS; - // Cocoa-specific global timer data // typedef struct _GLFWtimeNS {-    double          base;-    double          resolution;+    uint64_t        frequency;  } _GLFWtimeNS;  -void _glfwInitTimer(void);+void _glfwInitTimerNS(void); -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired);-void _glfwRestoreVideoMode(_GLFWmonitor* monitor);+GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);+void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor); -#endif // _cocoa_platform_h_+#endif // _glfw3_cocoa_platform_h_
+ glfw/src/cocoa_time.c view
@@ -0,0 +1,60 @@+//========================================================================+// GLFW 3.2 OS X - www.glfw.org+//------------------------------------------------------------------------+// Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.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 <mach/mach_time.h>+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW internal API                      //////+//////////////////////////////////////////////////////////////////////////++// Initialise timer+//+void _glfwInitTimerNS(void)+{+    mach_timebase_info_data_t info;+    mach_timebase_info(&info);++    _glfw.ns_time.frequency = (info.denom * 1e9) / info.numer;+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW platform API                      //////+//////////////////////////////////////////////////////////////////////////++uint64_t _glfwPlatformGetTimerValue(void)+{+    return mach_absolute_time();+}++uint64_t _glfwPlatformGetTimerFrequency(void)+{+    return _glfw.ns_time.frequency;+}+
glfw/src/cocoa_window.m view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 OS X - www.glfw.org+// GLFW 3.2 OS X - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.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@@ -26,6 +26,7 @@  #include "internal.h" +#include <float.h> #include <string.h>  // Needed for _NSGetProgname@@ -55,6 +56,26 @@     return nil; } +// Returns the style mask corresponding to the window settings+//+static NSUInteger getStyleMask(_GLFWwindow* window)+{+    NSUInteger styleMask = 0;++    if (window->monitor || !window->decorated)+        styleMask |= NSBorderlessWindowMask;+    else+    {+        styleMask |= NSTitledWindowMask | NSClosableWindowMask |+                     NSMiniaturizableWindowMask;++        if (window->resizable)+            styleMask |= NSResizableWindowMask;+    }++    return styleMask;+}+ // Center the cursor in the view of the window // static void centerCursor(_GLFWwindow *window)@@ -64,10 +85,18 @@     _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); } -// Update the cursor to match the specified cursor mode+// Returns whether the cursor is in the client area of the specified window //-static void updateModeCursor(_GLFWwindow* window)+static GLFWbool cursorInClientArea(_GLFWwindow* window) {+    const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];+    return [window->ns.view mouse:pos inRect:[window->ns.view frame]];+}++// Updates the cursor image according to its cursor mode+//+static void updateCursorImage(_GLFWwindow* window)+{     if (window->cursorMode == GLFW_CURSOR_NORMAL)     {         if (window->cursor)@@ -79,51 +108,98 @@         [(NSCursor*) _glfw.ns.cursor set]; } -// Enter full screen mode+// Transforms the specified y-coordinate between the CG display and NS screen+// coordinate systems //-static GLboolean enterFullscreenMode(_GLFWwindow* window)+static float transformY(float y) {-    GLboolean status;+    return CGDisplayBounds(CGMainDisplayID()).size.height - y;+} -    status = _glfwSetVideoMode(window->monitor, &window->videoMode);+// Make the specified window and its video mode active on its monitor+//+static GLFWbool acquireMonitor(_GLFWwindow* window)+{+    const GLFWbool status = _glfwSetVideoModeNS(window->monitor, &window->videoMode);+    const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID);+    const NSRect frame = NSMakeRect(bounds.origin.x,+                                    transformY(bounds.origin.y + bounds.size.height),+                                    bounds.size.width,+                                    bounds.size.height); -    // NOTE: The window is resized despite mode setting failure to make-    //       glfwSetWindowSize more robust-    [window->ns.object setFrame:[window->monitor->ns.screen frame]-                        display:YES];+    [window->ns.object setFrame:frame display:YES]; +    _glfwInputMonitorWindowChange(window->monitor, window);     return status; } -// Leave full screen mode+// Remove the window and restore the original video mode //-static void leaveFullscreenMode(_GLFWwindow* window)+static void releaseMonitor(_GLFWwindow* window) {-    _glfwRestoreVideoMode(window->monitor);+    if (window->monitor->window != window)+        return;++    _glfwInputMonitorWindowChange(window->monitor, NULL);+    _glfwRestoreVideoModeNS(window->monitor); } -// Transforms the specified y-coordinate between the CG display and NS screen-// coordinate systems+// Translates OS X key modifiers into GLFW ones //-static float transformY(float y)+static int translateFlags(NSUInteger flags) {-    const float height = CGDisplayBounds(CGMainDisplayID()).size.height;-    return height - y;+    int mods = 0;++    if (flags & NSShiftKeyMask)+        mods |= GLFW_MOD_SHIFT;+    if (flags & NSControlKeyMask)+        mods |= GLFW_MOD_CONTROL;+    if (flags & NSAlternateKeyMask)+        mods |= GLFW_MOD_ALT;+    if (flags & NSCommandKeyMask)+        mods |= GLFW_MOD_SUPER;++    return mods; } -// Returns the backing rect of the specified window+// Translates a OS X keycode to a GLFW keycode //-static NSRect convertRectToBacking(_GLFWwindow* window, NSRect contentRect)+static int translateKey(unsigned int key) {-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070-    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)-        return [window->ns.view convertRectToBacking:contentRect];-    else-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/-        return contentRect;+    if (key >= sizeof(_glfw.ns.publicKeys) / sizeof(_glfw.ns.publicKeys[0]))+        return GLFW_KEY_UNKNOWN;++    return _glfw.ns.publicKeys[key]; } +// Translate a GLFW keycode to a Cocoa modifier flag+//+static NSUInteger translateKeyToModifierFlag(int key)+{+    switch (key)+    {+        case GLFW_KEY_LEFT_SHIFT:+        case GLFW_KEY_RIGHT_SHIFT:+            return NSShiftKeyMask;+        case GLFW_KEY_LEFT_CONTROL:+        case GLFW_KEY_RIGHT_CONTROL:+            return NSControlKeyMask;+        case GLFW_KEY_LEFT_ALT:+        case GLFW_KEY_RIGHT_ALT:+            return NSAlternateKeyMask;+        case GLFW_KEY_LEFT_SUPER:+        case GLFW_KEY_RIGHT_SUPER:+            return NSCommandKeyMask;+    } +    return 0;+}++// Defines a constant for empty ranges in NSTextInputClient+//+static const NSRange kEmptyRange = { NSNotFound, 0 };++ //------------------------------------------------------------------------ // Delegate for window related notifications //------------------------------------------------------------------------@@ -156,27 +232,26 @@  - (void)windowDidResize:(NSNotification *)notification {-    if (_glfw.focusedWindow == window &&-        window->cursorMode == GLFW_CURSOR_DISABLED)-    {+    if (window->context.client != GLFW_NO_API)+        [window->context.nsgl.object update];++    if (_glfw.ns.disabledCursorWindow == window)         centerCursor(window);-    }      const NSRect contentRect = [window->ns.view frame];-    const NSRect fbRect = convertRectToBacking(window, contentRect);+    const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];      _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);     _glfwInputWindowSize(window, contentRect.size.width, contentRect.size.height);-    _glfwInputWindowDamage(window); }  - (void)windowDidMove:(NSNotification *)notification {-    if (_glfw.focusedWindow == window &&-        window->cursorMode == GLFW_CURSOR_DISABLED)-    {+    if (window->context.client != GLFW_NO_API)+        [window->context.nsgl.object update];++    if (_glfw.ns.disabledCursorWindow == window)         centerCursor(window);-    }      int x, y;     _glfwPlatformGetWindowPos(window, &x, &y);@@ -185,35 +260,35 @@  - (void)windowDidMiniaturize:(NSNotification *)notification {-    _glfwInputWindowIconify(window, GL_TRUE);+    if (window->monitor)+        releaseMonitor(window);++    _glfwInputWindowIconify(window, GLFW_TRUE); }  - (void)windowDidDeminiaturize:(NSNotification *)notification {-    _glfwInputWindowIconify(window, GL_FALSE);+    if (window->monitor)+        acquireMonitor(window);++    _glfwInputWindowIconify(window, GLFW_FALSE); }  - (void)windowDidBecomeKey:(NSNotification *)notification {-    if (window->monitor)-        enterFullscreenMode(window);--    if (_glfw.focusedWindow == window &&-        window->cursorMode == GLFW_CURSOR_DISABLED)-    {+    if (_glfw.ns.disabledCursorWindow == window)         centerCursor(window);-    } -    _glfwInputWindowFocus(window, GL_TRUE);-    _glfwPlatformApplyCursorMode(window);+    _glfwInputWindowFocus(window, GLFW_TRUE);+    _glfwPlatformSetCursorMode(window, window->cursorMode); }  - (void)windowDidResignKey:(NSNotification *)notification {-    if (window->monitor)-        leaveFullscreenMode(window);+    if (window->monitor && window->autoIconify)+        _glfwPlatformIconifyWindow(window); -    _glfwInputWindowFocus(window, GL_FALSE);+    _glfwInputWindowFocus(window, GLFW_FALSE); }  @end@@ -250,45 +325,26 @@     _glfwPlatformPostEmptyEvent(); } -@end--// Translates OS X key modifiers into GLFW ones-//-static int translateFlags(NSUInteger flags)+- (void)applicationDidHide:(NSNotification *)notification {-    int mods = 0;--    if (flags & NSShiftKeyMask)-        mods |= GLFW_MOD_SHIFT;-    if (flags & NSControlKeyMask)-        mods |= GLFW_MOD_CONTROL;-    if (flags & NSAlternateKeyMask)-        mods |= GLFW_MOD_ALT;-    if (flags & NSCommandKeyMask)-        mods |= GLFW_MOD_SUPER;+    int i; -    return mods;+    for (i = 0;  i < _glfw.monitorCount;  i++)+        _glfwRestoreVideoModeNS(_glfw.monitors[i]); } -// Translates a OS X keycode to a GLFW keycode-//-static int translateKey(unsigned int key)-{-    if (key >= sizeof(_glfw.ns.publicKeys) / sizeof(_glfw.ns.publicKeys[0]))-        return GLFW_KEY_UNKNOWN;--    return _glfw.ns.publicKeys[key];-}+@end   //------------------------------------------------------------------------ // Content view class for the GLFW window //------------------------------------------------------------------------ -@interface GLFWContentView : NSOpenGLView+@interface GLFWContentView : NSView <NSTextInputClient> {     _GLFWwindow* window;     NSTrackingArea* trackingArea;+    NSMutableAttributedString* markedText; }  - (id)initWithGlfwWindow:(_GLFWwindow *)initWindow;@@ -313,12 +369,12 @@  - (id)initWithGlfwWindow:(_GLFWwindow *)initWindow {-    self = [super initWithFrame:NSMakeRect(0, 0, 1, 1)-                    pixelFormat:nil];+    self = [super init];     if (self != nil)     {         window = initWindow;         trackingArea = nil;+        markedText = [[NSMutableAttributedString alloc] init];          [self updateTrackingAreas];         [self registerForDraggedTypes:[NSArray arrayWithObjects:@@ -328,9 +384,10 @@     return self; } --(void)dealloc+- (void)dealloc {     [trackingArea release];+    [markedText release];     [super dealloc]; } @@ -351,7 +408,7 @@  - (void)cursorUpdate:(NSEvent *)event {-    updateModeCursor(window);+    updateCursorImage(window); }  - (void)mouseDown:(NSEvent *)event@@ -379,20 +436,23 @@ {     if (window->cursorMode == GLFW_CURSOR_DISABLED)     {-        _glfwInputCursorMotion(window,-                               [event deltaX] - window->ns.warpDeltaX,-                               [event deltaY] - window->ns.warpDeltaY);+        const double dx = [event deltaX] - window->ns.cursorWarpDeltaX;+        const double dy = [event deltaY] - window->ns.cursorWarpDeltaY;++        _glfwInputCursorPos(window,+                            window->virtualCursorPosX + dx,+                            window->virtualCursorPosY + dy);     }     else     {         const NSRect contentRect = [window->ns.view frame];         const NSPoint pos = [event locationInWindow]; -        _glfwInputCursorMotion(window, pos.x, contentRect.size.height - pos.y);+        _glfwInputCursorPos(window, pos.x, contentRect.size.height - pos.y);     } -    window->ns.warpDeltaX = 0;-    window->ns.warpDeltaY = 0;+    window->ns.cursorWarpDeltaX = 0;+    window->ns.cursorWarpDeltaY = 0; }  - (void)rightMouseDown:(NSEvent *)event@@ -439,20 +499,24 @@  - (void)mouseExited:(NSEvent *)event {-    _glfwInputCursorEnter(window, GL_FALSE);+    _glfwInputCursorEnter(window, GLFW_FALSE); }  - (void)mouseEntered:(NSEvent *)event {-    _glfwInputCursorEnter(window, GL_TRUE);+    _glfwInputCursorEnter(window, GLFW_TRUE); }  - (void)viewDidChangeBackingProperties {     const NSRect contentRect = [window->ns.view frame];-    const NSRect fbRect = convertRectToBacking(window, contentRect);+    const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];      _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);+}++- (void)drawRect:(NSRect)rect+{     _glfwInputWindowDamage(window); } @@ -487,18 +551,7 @@      _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods); -    NSString* characters = [event characters];-    NSUInteger i, length = [characters length];-    const int plain = !(mods & GLFW_MOD_SUPER);--    for (i = 0;  i < length;  i++)-    {-        const unichar codepoint = [characters characterAtIndex:i];-        if ((codepoint & 0xff00) == 0xf700)-            continue;--        _glfwInputChar(window, codepoint, mods, plain);-    }+    [self interpretKeyEvents:[NSArray arrayWithObject:event]]; }  - (void)flagsChanged:(NSEvent *)event@@ -508,21 +561,18 @@         [event modifierFlags] & NSDeviceIndependentModifierFlagsMask;     const int key = translateKey([event keyCode]);     const int mods = translateFlags(modifierFlags);+    const NSUInteger keyFlag = translateKeyToModifierFlag(key); -    if (modifierFlags == window->ns.modifierFlags)+    if (keyFlag & modifierFlags)     {         if (window->keys[key] == GLFW_PRESS)             action = GLFW_RELEASE;         else             action = GLFW_PRESS;     }-    else if (modifierFlags > window->ns.modifierFlags)-        action = GLFW_PRESS;     else         action = GLFW_RELEASE; -    window->ns.modifierFlags = modifierFlags;-     _glfwInputKey(window, key, [event keyCode], action, mods); } @@ -537,23 +587,13 @@ {     double deltaX, deltaY; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070-    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)-    {-        deltaX = [event scrollingDeltaX];-        deltaY = [event scrollingDeltaY];+    deltaX = [event scrollingDeltaX];+    deltaY = [event scrollingDeltaY]; -        if ([event hasPreciseScrollingDeltas])-        {-            deltaX *= 0.1;-            deltaY *= 0.1;-        }-    }-    else-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/+    if ([event hasPreciseScrollingDeltas])     {-        deltaX = [event deltaX];-        deltaY = [event deltaY];+        deltaX *= 0.1;+        deltaY *= 0.1;     }      if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0)@@ -584,9 +624,9 @@     NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];      const NSRect contentRect = [window->ns.view frame];-    _glfwInputCursorMotion(window,-                           [sender draggingLocation].x,-                           contentRect.size.height - [sender draggingLocation].y);+    _glfwInputCursorPos(window,+                        [sender draggingLocation].x,+                        contentRect.size.height - [sender draggingLocation].y);      const int count = [files count];     if (count)@@ -613,6 +653,92 @@     [self setNeedsDisplay:YES]; } +- (BOOL)hasMarkedText+{+    return [markedText length] > 0;+}++- (NSRange)markedRange+{+    if ([markedText length] > 0)+        return NSMakeRange(0, [markedText length] - 1);+    else+        return kEmptyRange;+}++- (NSRange)selectedRange+{+    return kEmptyRange;+}++- (void)setMarkedText:(id)string+        selectedRange:(NSRange)selectedRange+     replacementRange:(NSRange)replacementRange+{+    if ([string isKindOfClass:[NSAttributedString class]])+        [markedText initWithAttributedString:string];+    else+        [markedText initWithString:string];+}++- (void)unmarkText+{+    [[markedText mutableString] setString:@""];+}++- (NSArray*)validAttributesForMarkedText+{+    return [NSArray array];+}++- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range+                                               actualRange:(NSRangePointer)actualRange+{+    return nil;+}++- (NSUInteger)characterIndexForPoint:(NSPoint)point+{+    return 0;+}++- (NSRect)firstRectForCharacterRange:(NSRange)range+                         actualRange:(NSRangePointer)actualRange+{+    int xpos, ypos;+    _glfwPlatformGetWindowPos(window, &xpos, &ypos);+    const NSRect contentRect = [window->ns.view frame];+    return NSMakeRect(xpos, transformY(ypos + contentRect.size.height), 0.0, 0.0);+}++- (void)insertText:(id)string replacementRange:(NSRange)replacementRange+{+    NSString* characters;+    NSEvent* event = [NSApp currentEvent];+    const int mods = translateFlags([event modifierFlags]);+    const int plain = !(mods & GLFW_MOD_SUPER);++    if ([string isKindOfClass:[NSAttributedString class]])+        characters = [string string];+    else+        characters = (NSString*) string;++    NSUInteger i, length = [characters length];++    for (i = 0;  i < length;  i++)+    {+        const unichar codepoint = [characters characterAtIndex:i];+        if ((codepoint & 0xff00) == 0xf700)+            continue;++        _glfwInputChar(window, codepoint, mods, plain);+    }+}++- (void)doCommandBySelector:(SEL)selector+{+}+ @end  @@ -654,6 +780,12 @@         [super sendEvent:event]; } ++// No-op thread entry point+//+- (void)doNothing:(id)object+{+} @end  #if defined(_GLFW_USE_MENUBAR)@@ -719,6 +851,7 @@     [[appMenu addItemWithTitle:@"Services"                        action:NULL                 keyEquivalent:@""] setSubmenu:servicesMenu];+    [servicesMenu release];     [appMenu addItem:[NSMenuItem separatorItem]];     [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]                        action:@selector(hide:)@@ -737,6 +870,7 @@      NSMenuItem* windowMenuItem =         [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];+    [bar release];     NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];     [NSApp setWindowsMenu:windowMenu];     [windowMenuItem setSubmenu:windowMenu];@@ -752,18 +886,12 @@                           action:@selector(arrangeInFront:)                    keyEquivalent:@""]; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070-    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)-    {-        // TODO: Make this appear at the bottom of the menu (for consistency)--        [windowMenu addItem:[NSMenuItem separatorItem]];-        [[windowMenu addItemWithTitle:@"Enter Full Screen"-                               action:@selector(toggleFullScreen:)-                        keyEquivalent:@"f"]-            setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask];-    }-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/+    // TODO: Make this appear at the bottom of the menu (for consistency)+    [windowMenu addItem:[NSMenuItem separatorItem]];+    [[windowMenu addItemWithTitle:@"Enter Full Screen"+                           action:@selector(toggleFullScreen:)+                    keyEquivalent:@"f"]+     setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask];      // Prior to Snow Leopard, we need to use this oddly-named semi-private API     // to get the application menu working properly.@@ -775,14 +903,19 @@  // Initialize the Cocoa Application Kit //-static GLboolean initializeAppKit(void)+static GLFWbool initializeAppKit(void) {     if (NSApp)-        return GL_TRUE;+        return GLFW_TRUE;      // Implicitly create shared NSApplication instance     [GLFWApplication sharedApplication]; +    // Make Cocoa enter multi-threaded mode+    [NSThread detachNewThreadSelector:@selector(doNothing:)+                             toTarget:NSApp+                           withObject:nil];+     // In case we are unbundled, make us a proper UI application     [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; @@ -800,91 +933,85 @@     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Cocoa: Failed to create application delegate");-        return GL_FALSE;+        return GLFW_FALSE;     }      [NSApp setDelegate:_glfw.ns.delegate];     [NSApp run]; -    return GL_TRUE;+    return GLFW_TRUE; }  // Create the Cocoa window //-static GLboolean createWindow(_GLFWwindow* window,-                              const _GLFWwndconfig* wndconfig)+static GLFWbool createNativeWindow(_GLFWwindow* window,+                                   const _GLFWwndconfig* wndconfig) {     window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];     if (window->ns.delegate == nil)     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Cocoa: Failed to create window delegate");-        return GL_FALSE;+        return GLFW_FALSE;     } -    unsigned int styleMask = 0;+    NSRect contentRect; -    if (wndconfig->monitor || !wndconfig->decorated)-        styleMask = NSBorderlessWindowMask;-    else+    if (window->monitor)     {-        styleMask = NSTitledWindowMask | NSClosableWindowMask |-                    NSMiniaturizableWindowMask;--        if (wndconfig->resizable)-            styleMask |= NSResizableWindowMask;-    }+        GLFWvidmode mode;+        int xpos, ypos; -    NSRect contentRect;+        _glfwPlatformGetVideoMode(window->monitor, &mode);+        _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); -    if (wndconfig->monitor)-        contentRect = [wndconfig->monitor->ns.screen frame];+        contentRect = NSMakeRect(xpos, ypos, mode.width, mode.height);+    }     else         contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height);      window->ns.object = [[GLFWWindow alloc]         initWithContentRect:contentRect-                  styleMask:styleMask+                  styleMask:getStyleMask(window)                     backing:NSBackingStoreBuffered                       defer:NO];      if (window->ns.object == nil)     {         _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create window");-        return GL_FALSE;+        return GLFW_FALSE;     } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070-    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)-    {-        if (wndconfig->resizable)-            [window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];-    }-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/--    if (wndconfig->monitor)-    {+    if (window->monitor)         [window->ns.object setLevel:NSMainMenuWindowLevel + 1];-        [window->ns.object setHidesOnDeactivate:YES];-    }     else     {         [window->ns.object center]; +        if (wndconfig->resizable)+            [window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];+         if (wndconfig->floating)             [window->ns.object setLevel:NSFloatingWindowLevel];++        if (wndconfig->maximized)+            [window->ns.object zoom:nil];     } +    window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];++#if defined(_GLFW_USE_RETINA)+    [window->ns.view setWantsBestResolutionOpenGLSurface:YES];+#endif /*_GLFW_USE_RETINA*/++    [window->ns.object makeFirstResponder:window->ns.view];     [window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];     [window->ns.object setDelegate:window->ns.delegate];     [window->ns.object setAcceptsMouseMovedEvents:YES];--#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070-    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)-        [window->ns.object setRestorable:NO];-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/+    [window->ns.object setContentView:window->ns.view];+    [window->ns.object setRestorable:NO]; -    return GL_TRUE;+    return GLFW_TRUE; }  @@ -898,50 +1025,52 @@                               const _GLFWfbconfig* fbconfig) {     if (!initializeAppKit())-        return GL_FALSE;--    if (!createWindow(window, wndconfig))-        return GL_FALSE;--    if (!_glfwCreateContext(window, ctxconfig, fbconfig))-        return GL_FALSE;--    window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];+        return GLFW_FALSE; -#if defined(_GLFW_USE_RETINA)-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070-    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)-        [window->ns.view setWantsBestResolutionOpenGLSurface:YES];-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/-#endif /*_GLFW_USE_RETINA*/+    if (!createNativeWindow(window, wndconfig))+        return GLFW_FALSE; -    [window->ns.object setContentView:window->ns.view];-    // NOTE: If you set the pixel format before the context it creates another-    //       context, only to have it destroyed by the next line-    //       We cannot use the view to create the context because that interface-    //       does not support context resource sharing-    [window->ns.view setOpenGLContext:window->nsgl.context];-    [window->ns.view setPixelFormat:window->nsgl.pixelFormat];-    [window->nsgl.context setView:window->ns.view];+    if (ctxconfig->client != GLFW_NO_API)+    {+        if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)+        {+            if (!_glfwInitNSGL())+                return GLFW_FALSE;+            if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))+                return GLFW_FALSE;+        }+        else+        {+            _glfwInputError(GLFW_API_UNAVAILABLE, "Cocoa: EGL not available");+            return GLFW_FALSE;+        }+    } -    if (wndconfig->monitor)+    if (window->monitor)     {         _glfwPlatformShowWindow(window);-        if (!enterFullscreenMode(window))-            return GL_FALSE;+        _glfwPlatformFocusWindow(window);+        if (!acquireMonitor(window))+            return GLFW_FALSE;++        centerCursor(window);     } -    return GL_TRUE;+    return GLFW_TRUE; }  void _glfwPlatformDestroyWindow(_GLFWwindow* window) {+    if (_glfw.ns.disabledCursorWindow == window)+        _glfw.ns.disabledCursorWindow = NULL;+     [window->ns.object orderOut:nil];      if (window->monitor)-        leaveFullscreenMode(window);+        releaseMonitor(window); -    _glfwDestroyContext(window);+    if (window->context.destroy)+        window->context.destroy(window);      [window->ns.object setDelegate:nil];     [window->ns.delegate release];@@ -952,6 +1081,9 @@      [window->ns.object close];     window->ns.object = nil;++    [_glfw.ns.autoreleasePool drain];+    _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; }  void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)@@ -959,6 +1091,12 @@     [window->ns.object setTitle:[NSString stringWithUTF8String:title]]; } +void _glfwPlatformSetWindowIcon(_GLFWwindow* window,+                                int count, const GLFWimage* images)+{+    // Regular windows do not have icons+}+ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) {     const NSRect contentRect =@@ -991,15 +1129,41 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) {     if (window->monitor)-        enterFullscreenMode(window);+    {+        if (window->monitor->window == window)+            acquireMonitor(window);+    }     else         [window->ns.object setContentSize:NSMakeSize(width, height)]; } +void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,+                                      int minwidth, int minheight,+                                      int maxwidth, int maxheight)+{+    if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)+        [window->ns.object setContentMinSize:NSMakeSize(0, 0)];+    else+        [window->ns.object setContentMinSize:NSMakeSize(minwidth, minheight)];++    if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)+        [window->ns.object setContentMaxSize:NSMakeSize(DBL_MAX, DBL_MAX)];+    else+        [window->ns.object setContentMaxSize:NSMakeSize(maxwidth, maxheight)];+}++void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)+{+    if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)+        [window->ns.object setContentAspectRatio:NSMakeSize(0, 0)];+    else+        [window->ns.object setContentAspectRatio:NSMakeSize(numer, denom)];+}+ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) {     const NSRect contentRect = [window->ns.view frame];-    const NSRect fbRect = convertRectToBacking(window, contentRect);+    const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];      if (width)         *width = (int) fbRect.size.width;@@ -1033,11 +1197,30 @@  void _glfwPlatformRestoreWindow(_GLFWwindow* window) {-    [window->ns.object deminiaturize:nil];+    if ([window->ns.object isMiniaturized])+        [window->ns.object deminiaturize:nil];+    else if ([window->ns.object isZoomed])+        [window->ns.object zoom:nil]; } +void _glfwPlatformMaximizeWindow(_GLFWwindow* window)+{+    if (![window->ns.object isZoomed])+        [window->ns.object zoom:nil];+}+ void _glfwPlatformShowWindow(_GLFWwindow* window) {+    [window->ns.object orderFront:nil];+}++void _glfwPlatformHideWindow(_GLFWwindow* window)+{+    [window->ns.object orderOut:nil];+}++void _glfwPlatformFocusWindow(_GLFWwindow* window)+{     // Make us the active application     // HACK: This has been moved here from initializeAppKit to prevent     //       applications using only hidden windows from being activated, but@@ -1047,14 +1230,101 @@     [window->ns.object makeKeyAndOrderFront:nil]; } -void _glfwPlatformUnhideWindow(_GLFWwindow* window)+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,+                                   _GLFWmonitor* monitor,+                                   int xpos, int ypos,+                                   int width, int height,+                                   int refreshRate) {-    [window->ns.object orderFront:nil];-}+    if (window->monitor == monitor)+    {+        if (monitor)+        {+            if (monitor->window == window)+                acquireMonitor(window);+        }+        else+        {+            const NSRect contentRect =+                NSMakeRect(xpos, transformY(ypos + height), width, height);+            const NSRect frameRect =+                [window->ns.object frameRectForContentRect:contentRect+                                                 styleMask:getStyleMask(window)]; -void _glfwPlatformHideWindow(_GLFWwindow* window)-{-    [window->ns.object orderOut:nil];+            [window->ns.object setFrame:frameRect display:YES];+        }++        return;+    }++    if (window->monitor)+        releaseMonitor(window);++    _glfwInputWindowMonitorChange(window, monitor);++    const NSUInteger styleMask = getStyleMask(window);+    [window->ns.object setStyleMask:styleMask];+    [window->ns.object makeFirstResponder:window->ns.view];++    NSRect contentRect;++    if (monitor)+    {+        GLFWvidmode mode;++        _glfwPlatformGetVideoMode(window->monitor, &mode);+        _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);++        contentRect = NSMakeRect(xpos, transformY(ypos + mode.height),+                                    mode.width, mode.height);+    }+    else+    {+        contentRect = NSMakeRect(xpos, transformY(ypos + height),+                                    width, height);+    }++    NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect+                                                        styleMask:styleMask];+    [window->ns.object setFrame:frameRect display:YES];++    if (monitor)+    {+        [window->ns.object setLevel:NSMainMenuWindowLevel + 1];+        [window->ns.object setHasShadow:NO];++        acquireMonitor(window);+    }+    else+    {+        if (window->numer != GLFW_DONT_CARE &&+            window->denom != GLFW_DONT_CARE)+        {+            [window->ns.object setContentAspectRatio:NSMakeSize(window->numer,+                                                                window->denom)];+        }++        if (window->minwidth != GLFW_DONT_CARE &&+            window->minheight != GLFW_DONT_CARE)+        {+            [window->ns.object setContentMinSize:NSMakeSize(window->minwidth,+                                                            window->minheight)];+        }++        if (window->maxwidth != GLFW_DONT_CARE &&+            window->maxheight != GLFW_DONT_CARE)+        {+            [window->ns.object setContentMaxSize:NSMakeSize(window->maxwidth,+                                                            window->maxheight)];+        }++        if (window->floating)+            [window->ns.object setLevel:NSFloatingWindowLevel];+        else+            [window->ns.object setLevel:NSNormalWindowLevel];++        [window->ns.object setHasShadow:YES];+    } }  int _glfwPlatformWindowFocused(_GLFWwindow* window)@@ -1072,6 +1342,11 @@     return [window->ns.object isVisible]; } +int _glfwPlatformWindowMaximized(_GLFWwindow* window)+{+    return [window->ns.object isZoomed];+}+ void _glfwPlatformPollEvents(void) {     for (;;)@@ -1104,6 +1379,19 @@     _glfwPlatformPollEvents(); } +void _glfwPlatformWaitEventsTimeout(double timeout)+{+    NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];+    NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask+                                        untilDate:date+                                           inMode:NSDefaultRunLoopMode+                                          dequeue:YES];+    if (event)+        [NSApp sendEvent:event];++    _glfwPlatformPollEvents();+}+ void _glfwPlatformPostEmptyEvent(void) {     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];@@ -1133,13 +1421,13 @@  void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) {-    updateModeCursor(window);+    updateCursorImage(window);      const NSRect contentRect = [window->ns.view frame];     const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; -    window->ns.warpDeltaX += x - pos.x;-    window->ns.warpDeltaY += y - contentRect.size.height + pos.y;+    window->ns.cursorWarpDeltaX += x - pos.x;+    window->ns.cursorWarpDeltaY += y - contentRect.size.height + pos.y;      if (window->monitor)     {@@ -1148,24 +1436,81 @@     }     else     {-        const NSPoint localPoint = NSMakePoint(x, contentRect.size.height - y - 1);-        const NSPoint globalPoint = [window->ns.object convertBaseToScreen:localPoint];+        const NSRect localRect = NSMakeRect(x, contentRect.size.height - y - 1, 0, 0);+        const NSRect globalRect = [window->ns.object convertRectToScreen:localRect];+        const NSPoint globalPoint = globalRect.origin;          CGWarpMouseCursorPosition(CGPointMake(globalPoint.x,                                               transformY(globalPoint.y)));     } } -void _glfwPlatformApplyCursorMode(_GLFWwindow* window)+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) {-    updateModeCursor(window);--    if (window->cursorMode == GLFW_CURSOR_DISABLED)+    if (mode == GLFW_CURSOR_DISABLED)+    {+        _glfw.ns.disabledCursorWindow = window;+        _glfwPlatformGetCursorPos(window,+                                  &_glfw.ns.restoreCursorPosX,+                                  &_glfw.ns.restoreCursorPosY);+        centerCursor(window);         CGAssociateMouseAndMouseCursorPosition(false);-    else+    }+    else if (_glfw.ns.disabledCursorWindow == window)+    {+        _glfw.ns.disabledCursorWindow = NULL;         CGAssociateMouseAndMouseCursorPosition(true);+        _glfwPlatformSetCursorPos(window,+                                  _glfw.ns.restoreCursorPosX,+                                  _glfw.ns.restoreCursorPosY);+    }++    if (cursorInClientArea(window))+        updateCursorImage(window); } +const char* _glfwPlatformGetKeyName(int key, int scancode)+{+    if (key != GLFW_KEY_UNKNOWN)+        scancode = _glfw.ns.nativeKeys[key];++    if (!_glfwIsPrintable(_glfw.ns.publicKeys[scancode]))+        return NULL;++    UInt32 deadKeyState = 0;+    UniChar characters[8];+    UniCharCount characterCount = 0;++    if (UCKeyTranslate([(NSData*) _glfw.ns.unicodeData bytes],+                       scancode,+                       kUCKeyActionDisplay,+                       0,+                       LMGetKbdType(),+                       kUCKeyTranslateNoDeadKeysBit,+                       &deadKeyState,+                       sizeof(characters) / sizeof(characters[0]),+                       &characterCount,+                       characters) != noErr)+    {+        return NULL;+    }++    if (!characterCount)+        return NULL;++    CFStringRef string = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,+                                                            characters,+                                                            characterCount,+                                                            kCFAllocatorNull);+    CFStringGetCString(string,+                       _glfw.ns.keyName,+                       sizeof(_glfw.ns.keyName),+                       kCFStringEncodingUTF8);+    CFRelease(string);++    return _glfw.ns.keyName;+}+ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,                               const GLFWimage* image,                               int xhot, int yhot)@@ -1173,6 +1518,9 @@     NSImage* native;     NSBitmapImageRep* rep; +    if (!initializeAppKit())+        return GLFW_FALSE;+     rep = [[NSBitmapImageRep alloc]         initWithBitmapDataPlanes:NULL                       pixelsWide:image->width@@ -1187,12 +1535,12 @@                     bitsPerPixel:32];      if (rep == nil)-        return GL_FALSE;+        return GLFW_FALSE;      memcpy([rep bitmapData], image->pixels, image->width * image->height * 4);      native = [[NSImage alloc] initWithSize:NSMakeSize(image->width, image->height)];-    [native addRepresentation: rep];+    [native addRepresentation:rep];      cursor->ns.object = [[NSCursor alloc] initWithImage:native                                                 hotSpot:NSMakePoint(xhot, yhot)];@@ -1201,22 +1549,26 @@     [rep release];      if (cursor->ns.object == nil)-        return GL_FALSE;+        return GLFW_FALSE; -    return GL_TRUE;+    return GLFW_TRUE; }  int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) {+    if (!initializeAppKit())+        return GLFW_FALSE;+     cursor->ns.object = getStandardCursor(shape);     if (!cursor->ns.object)     {-        _glfwInputError(GLFW_INVALID_ENUM, "Cocoa: Invalid standard cursor");-        return GL_FALSE;+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Cocoa: Failed to retrieve standard cursor");+        return GLFW_FALSE;     }      [cursor->ns.object retain];-    return GL_TRUE;+    return GLFW_TRUE; }  void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)@@ -1227,16 +1579,8 @@  void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) {-    const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];--    if (window->cursorMode == GLFW_CURSOR_NORMAL &&-        [window->ns.view mouse:pos inRect:[window->ns.view frame]])-    {-        if (cursor)-            [(NSCursor*) cursor->ns.object set];-        else-            [[NSCursor arrowCursor] set];-    }+    if (cursorInClientArea(window))+        updateCursorImage(window); }  void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)@@ -1255,7 +1599,8 @@      if (![[pasteboard types] containsObject:NSStringPboardType])     {-        _glfwInputError(GLFW_FORMAT_UNAVAILABLE, NULL);+        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,+                        "Cocoa: Failed to retrieve string from pasteboard");         return NULL;     } @@ -1271,6 +1616,27 @@     _glfw.ns.clipboardString = strdup([object UTF8String]);      return _glfw.ns.clipboardString;+}++char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count)+{+    *count = 0;+    return NULL;+}++int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,+                                                      VkPhysicalDevice device,+                                                      uint32_t queuefamily)+{+    return GLFW_FALSE;+}++VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,+                                          _GLFWwindow* window,+                                          const VkAllocationCallbacks* allocator,+                                          VkSurfaceKHR* surface)+{+    return VK_ERROR_EXTENSION_NOT_PRESENT; }  
glfw/src/context.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 - www.glfw.org+// GLFW 3.2 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -27,74 +27,40 @@  #include "internal.h" +#include <assert.h> #include <stdio.h> #include <string.h> #include <limits.h> #include <stdio.h>  -// Parses the client API version string and extracts the version number-//-static GLboolean parseVersionString(int* api, int* major, int* minor, int* rev)-{-    int i;-    const char* version;-    const char* prefixes[] =-    {-        "OpenGL ES-CM ",-        "OpenGL ES-CL ",-        "OpenGL ES ",-        NULL-    };--    *api = GLFW_OPENGL_API;--    version = (const char*) glGetString(GL_VERSION);-    if (!version)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Failed to retrieve context version string");-        return GL_FALSE;-    }--    for (i = 0;  prefixes[i];  i++)-    {-        const size_t length = strlen(prefixes[i]);--        if (strncmp(version, prefixes[i], length) == 0)-        {-            version += length;-            *api = GLFW_OPENGL_ES_API;-            break;-        }-    }--    if (!sscanf(version, "%d.%d.%d", major, minor, rev))-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "No version found in context version string");-        return GL_FALSE;-    }--    return GL_TRUE;-}-- ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// ////////////////////////////////////////////////////////////////////////// -GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)+GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) {-    if (ctxconfig->api != GLFW_OPENGL_API &&-        ctxconfig->api != GLFW_OPENGL_ES_API)+    if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&+        ctxconfig->source != GLFW_EGL_CONTEXT_API)     {-        _glfwInputError(GLFW_INVALID_ENUM, "Invalid client API requested");-        return GL_FALSE;+        _glfwInputError(GLFW_INVALID_ENUM,+                        "Invalid context creation API %i",+                        ctxconfig->source);+        return GLFW_FALSE;     } -    if (ctxconfig->api == GLFW_OPENGL_API)+    if (ctxconfig->client != GLFW_NO_API &&+        ctxconfig->client != GLFW_OPENGL_API &&+        ctxconfig->client != GLFW_OPENGL_ES_API)     {+        _glfwInputError(GLFW_INVALID_ENUM,+                        "Invalid client API %i",+                        ctxconfig->client);+        return GLFW_FALSE;+    }++    if (ctxconfig->client == GLFW_OPENGL_API)+    {         if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||             (ctxconfig->major == 1 && ctxconfig->minor > 5) ||             (ctxconfig->major == 2 && ctxconfig->minor > 1) ||@@ -104,15 +70,12 @@             // OpenGL 1.x series ended with version 1.5             // OpenGL 2.x series ended with version 2.1             // OpenGL 3.x series ended with version 3.3+            // For now, let everything else through              _glfwInputError(GLFW_INVALID_VALUE,-                            "Invalid OpenGL version %i.%i requested",+                            "Invalid OpenGL version %i.%i",                             ctxconfig->major, ctxconfig->minor);-            return GL_FALSE;-        }-        else-        {-            // For now, let everything else through+            return GLFW_FALSE;         }          if (ctxconfig->profile)@@ -121,33 +84,32 @@                 ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)             {                 _glfwInputError(GLFW_INVALID_ENUM,-                                "Invalid OpenGL profile requested");-                return GL_FALSE;+                                "Invalid OpenGL profile %i",+                                ctxconfig->profile);+                return GLFW_FALSE;             } -            if (ctxconfig->major < 3 ||+            if (ctxconfig->major <= 2 ||                 (ctxconfig->major == 3 && ctxconfig->minor < 2))             {                 // Desktop OpenGL context profiles are only defined for version 3.2                 // and above                  _glfwInputError(GLFW_INVALID_VALUE,-                                "Context profiles only exist for "-                                "OpenGL version 3.2 and above");-                return GL_FALSE;+                                "Context profiles are only defined for OpenGL version 3.2 and above");+                return GLFW_FALSE;             }         } -        if (ctxconfig->forward && ctxconfig->major < 3)+        if (ctxconfig->forward && ctxconfig->major <= 2)         {             // Forward-compatible contexts are only defined for OpenGL version 3.0 and above             _glfwInputError(GLFW_INVALID_VALUE,-                            "Forward compatibility only exist for OpenGL "-                            "version 3.0 and above");-            return GL_FALSE;+                            "Forward-compatibility is only defined for OpenGL version 3.0 and above");+            return GLFW_FALSE;         }     }-    else if (ctxconfig->api == GLFW_OPENGL_ES_API)+    else if (ctxconfig->client == GLFW_OPENGL_ES_API)     {         if (ctxconfig->major < 1 || ctxconfig->minor < 0 ||             (ctxconfig->major == 1 && ctxconfig->minor > 1) ||@@ -156,31 +118,12 @@             // OpenGL ES 1.0 is the smallest valid version             // OpenGL ES 1.x series ended with version 1.1             // OpenGL ES 2.x series ended with version 2.0--            _glfwInputError(GLFW_INVALID_VALUE,-                            "Invalid OpenGL ES version %i.%i requested",-                            ctxconfig->major, ctxconfig->minor);-            return GL_FALSE;-        }-        else-        {             // For now, let everything else through-        } -        if (ctxconfig->profile)-        {-            // OpenGL ES does not support profiles             _glfwInputError(GLFW_INVALID_VALUE,-                            "Context profiles are not supported by OpenGL ES");-            return GL_FALSE;-        }--        if (ctxconfig->forward)-        {-            // OpenGL ES does not support forward-compatibility-            _glfwInputError(GLFW_INVALID_VALUE,-                            "Forward compatibility is not supported by OpenGL ES");-            return GL_FALSE;+                            "Invalid OpenGL ES version %i.%i",+                            ctxconfig->major, ctxconfig->minor);+            return GLFW_FALSE;         }     } @@ -189,9 +132,10 @@         if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION &&             ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)         {-            _glfwInputError(GLFW_INVALID_VALUE,-                            "Invalid context robustness mode requested");-            return GL_FALSE;+            _glfwInputError(GLFW_INVALID_ENUM,+                            "Invalid context robustness mode %i",+                            ctxconfig->robustness);+            return GLFW_FALSE;         }     } @@ -200,13 +144,14 @@         if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE &&             ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)         {-            _glfwInputError(GLFW_INVALID_VALUE,-                            "Invalid context release behavior requested");-            return GL_FALSE;+            _glfwInputError(GLFW_INVALID_ENUM,+                            "Invalid context release behavior %i",+                            ctxconfig->release);+            return GLFW_FALSE;         }     } -    return GL_TRUE;+    return GLFW_TRUE; }  const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,@@ -372,63 +317,159 @@     return closest; } -GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)+GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig) {-    _GLFWwindow* window = _glfwPlatformGetCurrentContext();+    int i;+    _GLFWwindow* window;+    const char* version;+    const char* prefixes[] =+    {+        "OpenGL ES-CM ",+        "OpenGL ES-CL ",+        "OpenGL ES ",+        NULL+    }; -    if (!parseVersionString(&window->context.api,-                            &window->context.major,-                            &window->context.minor,-                            &window->context.revision))+    window = _glfwPlatformGetCurrentContext();++    window->context.source = ctxconfig->source;+    window->context.client = GLFW_OPENGL_API;++    window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)+        window->context.getProcAddress("glGetIntegerv");+    window->context.GetString = (PFNGLGETSTRINGPROC)+        window->context.getProcAddress("glGetString");+    if (!window->context.GetIntegerv || !window->context.GetString)     {-        return GL_FALSE;+        _glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");+        return GLFW_FALSE;     } -#if defined(_GLFW_USE_OPENGL)-    if (window->context.major > 2)+    version = (const char*) window->context.GetString(GL_VERSION);+    if (!version)     {+        if (ctxconfig->client == GLFW_OPENGL_API)+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "OpenGL version string retrieval is broken");+        }+        else+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "OpenGL ES version string retrieval is broken");+        }++        return GLFW_FALSE;+    }++    for (i = 0;  prefixes[i];  i++)+    {+        const size_t length = strlen(prefixes[i]);++        if (strncmp(version, prefixes[i], length) == 0)+        {+            version += length;+            window->context.client = GLFW_OPENGL_ES_API;+            break;+        }+    }++    if (!sscanf(version, "%d.%d.%d",+                &window->context.major,+                &window->context.minor,+                &window->context.revision))+    {+        if (window->context.client == GLFW_OPENGL_API)+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "No version found in OpenGL version string");+        }+        else+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "No version found in OpenGL ES version string");+        }++        return GLFW_FALSE;+    }++    if (window->context.major < ctxconfig->major ||+        (window->context.major == ctxconfig->major &&+         window->context.minor < ctxconfig->minor))+    {+        // The desired OpenGL version is greater than the actual version+        // This only happens if the machine lacks {GLX|WGL}_ARB_create_context+        // /and/ the user has requested an OpenGL version greater than 1.0++        // For API consistency, we emulate the behavior of the+        // {GLX|WGL}_ARB_create_context extension and fail here++        if (window->context.client == GLFW_OPENGL_API)+        {+            _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                            "Requested OpenGL version %i.%i, got version %i.%i",+                            ctxconfig->major, ctxconfig->minor,+                            window->context.major, window->context.minor);+        }+        else+        {+            _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                            "Requested OpenGL ES version %i.%i, got version %i.%i",+                            ctxconfig->major, ctxconfig->minor,+                            window->context.major, window->context.minor);+        }++        return GLFW_FALSE;+    }++    if (window->context.major >= 3)+    {         // OpenGL 3.0+ uses a different function for extension string retrieval         // We cache it here instead of in glfwExtensionSupported mostly to alert         // users as early as possible that their build may be broken -        window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");-        if (!window->GetStringi)+        window->context.GetStringi = (PFNGLGETSTRINGIPROC)+            window->context.getProcAddress("glGetStringi");+        if (!window->context.GetStringi)         {             _glfwInputError(GLFW_PLATFORM_ERROR,                             "Entry point retrieval is broken");-            return GL_FALSE;+            return GLFW_FALSE;         }     } -    if (window->context.api == GLFW_OPENGL_API)+    if (window->context.client == GLFW_OPENGL_API)     {         // Read back context flags (OpenGL 3.0 and above)         if (window->context.major >= 3)         {             GLint flags;-            glGetIntegerv(GL_CONTEXT_FLAGS, &flags);+            window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags);              if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)-                window->context.forward = GL_TRUE;+                window->context.forward = GLFW_TRUE;              if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)-                window->context.debug = GL_TRUE;+                window->context.debug = GLFW_TRUE;             else if (glfwExtensionSupported("GL_ARB_debug_output") &&                      ctxconfig->debug)             {                 // HACK: This is a workaround for older drivers (pre KHR_debug)                 //       not setting the debug bit in the context flags for                 //       debug contexts-                window->context.debug = GL_TRUE;+                window->context.debug = GLFW_TRUE;             }++            if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR)+                window->context.noerror = GLFW_TRUE;         }          // Read back OpenGL context profile (OpenGL 3.2 and above)-        if (window->context.major > 3 ||+        if (window->context.major >= 4 ||             (window->context.major == 3 && window->context.minor >= 2))         {             GLint mask;-            glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);+            window->context.GetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);              if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)                 window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;@@ -451,7 +492,8 @@             //       only present from 3.0 while the extension applies from 1.1              GLint strategy;-            glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);+            window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,+                                        &strategy);              if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)                 window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;@@ -468,7 +510,8 @@             //       one, so we can reuse them here              GLint strategy;-            glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);+            window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,+                                        &strategy);              if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)                 window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;@@ -480,55 +523,38 @@     if (glfwExtensionSupported("GL_KHR_context_flush_control"))     {         GLint behavior;-        glGetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior);+        window->context.GetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior);          if (behavior == GL_NONE)             window->context.release = GLFW_RELEASE_BEHAVIOR_NONE;         else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH)             window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH;     }-#endif // _GLFW_USE_OPENGL -    return GL_TRUE;-}--GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig)-{-    _GLFWwindow* window = _glfwPlatformGetCurrentContext();--    if (window->context.major < ctxconfig->major ||-        (window->context.major == ctxconfig->major &&-         window->context.minor < ctxconfig->minor))+    // Clearing the front buffer to black to avoid garbage pixels left over from+    // previous uses of our bit of VRAM     {-        // The desired OpenGL version is greater than the actual version-        // This only happens if the machine lacks {GLX|WGL}_ARB_create_context-        // /and/ the user has requested an OpenGL version greater than 1.0--        // For API consistency, we emulate the behavior of the-        // {GLX|WGL}_ARB_create_context extension and fail here--        _glfwInputError(GLFW_VERSION_UNAVAILABLE, NULL);-        return GL_FALSE;+        PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)+            window->context.getProcAddress("glClear");+        glClear(GL_COLOR_BUFFER_BIT);+        window->context.swapBuffers(window);     } -    return GL_TRUE;+    return GLFW_TRUE; } -int _glfwStringInExtensionString(const char* string, const GLubyte* extensions)+GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions) {-    const GLubyte* start;-    GLubyte* where;-    GLubyte* terminator;+    const char* start = extensions; -    // It takes a bit of care to be fool-proof about parsing the-    // OpenGL extensions string. Don't be fooled by sub-strings,-    // etc.-    start = extensions;     for (;;)     {-        where = (GLubyte*) strstr((const char*) start, string);+        const char* where;+        const char* terminator;++        where = strstr(start, string);         if (!where)-            return GL_FALSE;+            return GLFW_FALSE;          terminator = where + strlen(string);         if (where == start || *(where - 1) == ' ')@@ -540,7 +566,7 @@         start = terminator;     } -    return GL_TRUE;+    return GLFW_TRUE; }  @@ -551,13 +577,24 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    _GLFWwindow* previous = _glfwPlatformGetCurrentContext();      _GLFW_REQUIRE_INIT(); -    if (_glfwPlatformGetCurrentContext() == window)+    if (window && window->context.client == GLFW_NO_API)+    {+        _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);         return;+    } -    _glfwPlatformMakeContextCurrent(window);+    if (previous)+    {+        if (!window || window->context.source != previous->context.source)+            previous->context.makeCurrent(NULL);+    }++    if (window)+        window->context.makeCurrent(window); }  GLFWAPI GLFWwindow* glfwGetCurrentContext(void)@@ -569,43 +606,56 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT();-    _glfwPlatformSwapBuffers(window);++    if (window->context.client == GLFW_NO_API)+    {+        _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);+        return;+    }++    window->context.swapBuffers(window); }  GLFWAPI void glfwSwapInterval(int interval) {+    _GLFWwindow* window;+     _GLFW_REQUIRE_INIT(); -    if (!_glfwPlatformGetCurrentContext())+    window = _glfwPlatformGetCurrentContext();+    if (!window)     {         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);         return;     } -    _glfwPlatformSwapInterval(interval);+    window->context.swapInterval(interval); }  GLFWAPI int glfwExtensionSupported(const char* extension) {     _GLFWwindow* window; -    _GLFW_REQUIRE_INIT_OR_RETURN(GL_FALSE);+    assert(extension != NULL); +    _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);+     window = _glfwPlatformGetCurrentContext();     if (!window)     {         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);-        return GL_FALSE;+        return GLFW_FALSE;     }      if (*extension == '\0')     {-        _glfwInputError(GLFW_INVALID_VALUE, NULL);-        return GL_FALSE;+        _glfwInputError(GLFW_INVALID_VALUE, "Extension name is empty string");+        return GLFW_FALSE;     } -#if defined(_GLFW_USE_OPENGL)     if (window->context.major >= 3)     {         int i;@@ -613,53 +663,58 @@          // Check if extension is in the modern OpenGL extensions string list -        glGetIntegerv(GL_NUM_EXTENSIONS, &count);+        window->context.GetIntegerv(GL_NUM_EXTENSIONS, &count);          for (i = 0;  i < count;  i++)         {-            const char* en = (const char*) window->GetStringi(GL_EXTENSIONS, i);+            const char* en = (const char*)+                window->context.GetStringi(GL_EXTENSIONS, i);             if (!en)             {                 _glfwInputError(GLFW_PLATFORM_ERROR,-                                "Failed to retrieve extension string %i", i);-                return GL_FALSE;+                                "Extension string retrieval is broken");+                return GLFW_FALSE;             }              if (strcmp(en, extension) == 0)-                return GL_TRUE;+                return GLFW_TRUE;         }     }     else-#endif // _GLFW_USE_OPENGL     {         // Check if extension is in the old style OpenGL extensions string -        const GLubyte* extensions = glGetString(GL_EXTENSIONS);+        const char* extensions = (const char*)+            window->context.GetString(GL_EXTENSIONS);         if (!extensions)         {             _glfwInputError(GLFW_PLATFORM_ERROR,-                            "Failed to retrieve extension string");-            return GL_FALSE;+                            "Extension string retrieval is broken");+            return GLFW_FALSE;         }          if (_glfwStringInExtensionString(extension, extensions))-            return GL_TRUE;+            return GLFW_TRUE;     }      // Check if extension is in the platform-specific string-    return _glfwPlatformExtensionSupported(extension);+    return window->context.extensionSupported(extension); }  GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname) {+    _GLFWwindow* window;+    assert(procname != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); -    if (!_glfwPlatformGetCurrentContext())+    window = _glfwPlatformGetCurrentContext();+    if (!window)     {         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);         return NULL;     } -    return _glfwPlatformGetProcAddress(procname);+    return window->context.getProcAddress(procname); } 
glfw/src/egl_context.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 EGL - www.glfw.org+// GLFW 3.2 EGL - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -28,13 +28,14 @@ #include "internal.h"  #include <stdio.h>+#include <string.h> #include <stdlib.h> #include <assert.h>   // Return a description of the specified EGL error //-static const char* getErrorString(EGLint error)+static const char* getEGLErrorString(EGLint error) {     switch (error)     {@@ -47,54 +48,46 @@         case EGL_BAD_ALLOC:             return "EGL failed to allocate resources for the requested operation";         case EGL_BAD_ATTRIBUTE:-            return "An unrecognized attribute or attribute value was passed "-                   "in the attribute list";+            return "An unrecognized attribute or attribute value was passed in the attribute list";         case EGL_BAD_CONTEXT:-            return "An EGLContext argument does not name a valid EGL "-                   "rendering context";+            return "An EGLContext argument does not name a valid EGL rendering context";         case EGL_BAD_CONFIG:-            return "An EGLConfig argument does not name a valid EGL frame "-                   "buffer configuration";+            return "An EGLConfig argument does not name a valid EGL frame buffer configuration";         case EGL_BAD_CURRENT_SURFACE:-            return "The current surface of the calling thread is a window, pixel "-                   "buffer or pixmap that is no longer valid";+            return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid";         case EGL_BAD_DISPLAY:-            return "An EGLDisplay argument does not name a valid EGL display "-                   "connection";+            return "An EGLDisplay argument does not name a valid EGL display connection";         case EGL_BAD_SURFACE:-            return "An EGLSurface argument does not name a valid surface "-                   "configured for GL rendering";+            return "An EGLSurface argument does not name a valid surface configured for GL rendering";         case EGL_BAD_MATCH:             return "Arguments are inconsistent";         case EGL_BAD_PARAMETER:             return "One or more argument values are invalid";         case EGL_BAD_NATIVE_PIXMAP:-            return "A NativePixmapType argument does not refer to a valid "-                   "native pixmap";+            return "A NativePixmapType argument does not refer to a valid native pixmap";         case EGL_BAD_NATIVE_WINDOW:-            return "A NativeWindowType argument does not refer to a valid "-                   "native window";+            return "A NativeWindowType argument does not refer to a valid native window";         case EGL_CONTEXT_LOST:             return "The application must destroy all contexts and reinitialise";+        default:+            return "ERROR: UNKNOWN EGL ERROR";     }--    return "UNKNOWN EGL ERROR"; }  // Returns the specified attribute of the specified EGLConfig //-static int getConfigAttrib(EGLConfig config, int attrib)+static int getEGLConfigAttrib(EGLConfig config, int attrib) {     int value;     eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);     return value; } -// Return a list of available and usable framebuffer configs+// Return the EGLConfig most closely matching the specified hints //-static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig,-                                 const _GLFWfbconfig* desired,-                                 EGLConfig* result)+static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,+                                const _GLFWfbconfig* desired,+                                EGLConfig* result) {     EGLConfig* nativeConfigs;     _GLFWfbconfig* usableConfigs;@@ -105,7 +98,7 @@     if (!nativeCount)     {         _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");-        return GL_FALSE;+        return GLFW_FALSE;     }      nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));@@ -119,114 +112,312 @@         const EGLConfig n = nativeConfigs[i];         _GLFWfbconfig* u = usableConfigs + usableCount; -#if defined(_GLFW_X11)-        if (!getConfigAttrib(n, EGL_NATIVE_VISUAL_ID))-        {-            // Only consider EGLConfigs with associated visuals+        // Only consider RGB(A) EGLConfigs+        if (!(getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER))             continue;-        }-#endif // _GLFW_X11 -        if (!(getConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER))-        {-            // Only consider RGB(A) EGLConfigs+        // Only consider window EGLConfigs+        if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))             continue;-        } -        if (!(getConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))-        {-            // Only consider window EGLConfigs+#if defined(_GLFW_X11)+        // Only consider EGLConfigs with associated Visuals+        if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))             continue;-        }+#endif // _GLFW_X11 -        if (ctxconfig->api == GLFW_OPENGL_ES_API)+        if (ctxconfig->client == GLFW_OPENGL_ES_API)         {             if (ctxconfig->major == 1)             {-                if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))+                if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))                     continue;             }             else             {-                if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))+                if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))                     continue;             }         }-        else if (ctxconfig->api == GLFW_OPENGL_API)+        else if (ctxconfig->client == GLFW_OPENGL_API)         {-            if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))+            if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))                 continue;         } -        u->redBits = getConfigAttrib(n, EGL_RED_SIZE);-        u->greenBits = getConfigAttrib(n, EGL_GREEN_SIZE);-        u->blueBits = getConfigAttrib(n, EGL_BLUE_SIZE);+        u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);+        u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE);+        u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE); -        u->alphaBits = getConfigAttrib(n, EGL_ALPHA_SIZE);-        u->depthBits = getConfigAttrib(n, EGL_DEPTH_SIZE);-        u->stencilBits = getConfigAttrib(n, EGL_STENCIL_SIZE);+        u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE);+        u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);+        u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE); -        u->samples = getConfigAttrib(n, EGL_SAMPLES);-        u->doublebuffer = GL_TRUE;+        u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);+        u->doublebuffer = GLFW_TRUE; -        u->egl = n;+        u->handle = (uintptr_t) n;         usableCount++;     }      closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);     if (closest)-        *result = closest->egl;+        *result = (EGLConfig) closest->handle;      free(nativeConfigs);     free(usableConfigs); -    return closest ? GL_TRUE : GL_FALSE;+    return closest != NULL; } +static void makeContextCurrentEGL(_GLFWwindow* window)+{+    if (window)+    {+        if (!eglMakeCurrent(_glfw.egl.display,+                            window->context.egl.surface,+                            window->context.egl.surface,+                            window->context.egl.handle))+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "EGL: Failed to make context current: %s",+                            getEGLErrorString(eglGetError()));+            return;+        }+    }+    else+    {+        if (!eglMakeCurrent(_glfw.egl.display,+                            EGL_NO_SURFACE,+                            EGL_NO_SURFACE,+                            EGL_NO_CONTEXT))+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "EGL: Failed to clear current context: %s",+                            getEGLErrorString(eglGetError()));+            return;+        }+    } +    _glfwPlatformSetCurrentContext(window);+}++static void swapBuffersEGL(_GLFWwindow* window)+{+    if (window != _glfwPlatformGetCurrentContext())+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "EGL: The context must be current on the calling thread when swapping buffers");+        return;+    }++    eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);+}++static void swapIntervalEGL(int interval)+{+    eglSwapInterval(_glfw.egl.display, interval);+}++static int extensionSupportedEGL(const char* extension)+{+    const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);+    if (extensions)+    {+        if (_glfwStringInExtensionString(extension, extensions))+            return GLFW_TRUE;+    }++    return GLFW_FALSE;+}++static GLFWglproc getProcAddressEGL(const char* procname)+{+    _GLFWwindow* window = _glfwPlatformGetCurrentContext();++    if (window->context.egl.client)+    {+        GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,+                                                   procname);+        if (proc)+            return proc;+    }++    return eglGetProcAddress(procname);+}++static void destroyContextEGL(_GLFWwindow* window)+{+#if defined(_GLFW_X11)+    // NOTE: Do not unload libGL.so.1 while the X11 display is still open,+    //       as it will make XCloseDisplay segfault+    if (window->context.client != GLFW_OPENGL_API)+#endif // _GLFW_X11+    {+        if (window->context.egl.client)+        {+            _glfw_dlclose(window->context.egl.client);+            window->context.egl.client = NULL;+        }+    }++    if (window->context.egl.surface)+    {+        eglDestroySurface(_glfw.egl.display, window->context.egl.surface);+        window->context.egl.surface = EGL_NO_SURFACE;+    }++    if (window->context.egl.handle)+    {+        eglDestroyContext(_glfw.egl.display, window->context.egl.handle);+        window->context.egl.handle = EGL_NO_CONTEXT;+    }+}++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////  // Initialize EGL //-int _glfwInitContextAPI(void)+GLFWbool _glfwInitEGL(void) {-    if (!_glfwInitTLS())-        return GL_FALSE;+    int i;+    const char* sonames[] =+    {+#if defined(_GLFW_WIN32)+        "libEGL.dll",+        "EGL.dll",+#elif defined(_GLFW_COCOA)+        "libEGL.dylib",+#else+        "libEGL.so.1",+#endif+        NULL+    }; -    _glfw.egl.display = eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY);+    if (_glfw.egl.handle)+        return GLFW_TRUE;++    for (i = 0;  sonames[i];  i++)+    {+        _glfw.egl.handle = _glfw_dlopen(sonames[i]);+        if (_glfw.egl.handle)+            break;+    }++    if (!_glfw.egl.handle)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");+        return GLFW_FALSE;+    }++    _glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);++    _glfw.egl.GetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");+    _glfw.egl.GetConfigs = (PFNEGLGETCONFIGSPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");+    _glfw.egl.GetDisplay = (PFNEGLGETDISPLAYPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");+    _glfw.egl.GetError = (PFNEGLGETERRORPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglGetError");+    _glfw.egl.Initialize = (PFNEGLINITIALIZEPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglInitialize");+    _glfw.egl.Terminate = (PFNEGLTERMINATEPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglTerminate");+    _glfw.egl.BindAPI = (PFNEGLBINDAPIPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglBindAPI");+    _glfw.egl.CreateContext = (PFNEGLCREATECONTEXTPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglCreateContext");+    _glfw.egl.DestroySurface = (PFNEGLDESTROYSURFACEPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");+    _glfw.egl.DestroyContext = (PFNEGLDESTROYCONTEXTPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");+    _glfw.egl.CreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");+    _glfw.egl.MakeCurrent = (PFNEGLMAKECURRENTPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");+    _glfw.egl.SwapBuffers = (PFNEGLSWAPBUFFERSPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");+    _glfw.egl.SwapInterval = (PFNEGLSWAPINTERVALPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");+    _glfw.egl.QueryString = (PFNEGLQUERYSTRINGPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglQueryString");+    _glfw.egl.GetProcAddress = (PFNEGLGETPROCADDRESSPROC)+        _glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");++    if (!_glfw.egl.GetConfigAttrib ||+        !_glfw.egl.GetConfigs ||+        !_glfw.egl.GetDisplay ||+        !_glfw.egl.GetError ||+        !_glfw.egl.Initialize ||+        !_glfw.egl.Terminate ||+        !_glfw.egl.BindAPI ||+        !_glfw.egl.CreateContext ||+        !_glfw.egl.DestroySurface ||+        !_glfw.egl.DestroyContext ||+        !_glfw.egl.CreateWindowSurface ||+        !_glfw.egl.MakeCurrent ||+        !_glfw.egl.SwapBuffers ||+        !_glfw.egl.SwapInterval ||+        !_glfw.egl.QueryString ||+        !_glfw.egl.GetProcAddress)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "EGL: Failed to load required entry points");++        _glfwTerminateEGL();+        return GLFW_FALSE;+    }++    _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);     if (_glfw.egl.display == EGL_NO_DISPLAY)     {         _glfwInputError(GLFW_API_UNAVAILABLE,                         "EGL: Failed to get EGL display: %s",-                        getErrorString(eglGetError()));-        return GL_FALSE;+                        getEGLErrorString(eglGetError()));++        _glfwTerminateEGL();+        return GLFW_FALSE;     } -    if (!eglInitialize(_glfw.egl.display,-                       &_glfw.egl.versionMajor,-                       &_glfw.egl.versionMinor))+    if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))     {         _glfwInputError(GLFW_API_UNAVAILABLE,                         "EGL: Failed to initialize EGL: %s",-                        getErrorString(eglGetError()));-        return GL_FALSE;+                        getEGLErrorString(eglGetError()));++        _glfwTerminateEGL();+        return GLFW_FALSE;     } -    if (_glfwPlatformExtensionSupported("EGL_KHR_create_context"))-        _glfw.egl.KHR_create_context = GL_TRUE;+    _glfw.egl.KHR_create_context =+        extensionSupportedEGL("EGL_KHR_create_context");+    _glfw.egl.KHR_create_context_no_error =+        extensionSupportedEGL("EGL_KHR_create_context_no_error");+    _glfw.egl.KHR_gl_colorspace =+        extensionSupportedEGL("EGL_KHR_gl_colorspace"); -    return GL_TRUE;+    return GLFW_TRUE; }  // Terminate EGL //-void _glfwTerminateContextAPI(void)+void _glfwTerminateEGL(void) {-    eglTerminate(_glfw.egl.display);+    if (_glfw.egl.display)+    {+        eglTerminate(_glfw.egl.display);+        _glfw.egl.display = EGL_NO_DISPLAY;+    } -    _glfwTerminateTLS();+    if (_glfw.egl.handle)+    {+        _glfw_dlclose(_glfw.egl.handle);+        _glfw.egl.handle = NULL;+    } }  #define setEGLattrib(attribName, attribValue) \@@ -238,118 +429,87 @@  // Create the OpenGL or OpenGL ES context //-int _glfwCreateContext(_GLFWwindow* window,-                       const _GLFWctxconfig* ctxconfig,-                       const _GLFWfbconfig* fbconfig)+GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,+                               const _GLFWctxconfig* ctxconfig,+                               const _GLFWfbconfig* fbconfig) {-    int attribs[40];+    EGLint attribs[40];     EGLConfig config;     EGLContext share = NULL; +    if (!_glfw.egl.display)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");+        return GLFW_FALSE;+    }+     if (ctxconfig->share)-        share = ctxconfig->share->egl.context;+        share = ctxconfig->share->context.egl.handle; -    if (!chooseFBConfigs(ctxconfig, fbconfig, &config))+    if (!chooseEGLConfig(ctxconfig, fbconfig, &config))     {-        _glfwInputError(GLFW_PLATFORM_ERROR,+        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,                         "EGL: Failed to find a suitable EGLConfig");-        return GL_FALSE;+        return GLFW_FALSE;     } -#if defined(_GLFW_X11)-    // Retrieve the visual corresponding to the chosen EGL config-    {-        EGLint count = 0;-        int mask;-        EGLint redBits, greenBits, blueBits, alphaBits, visualID = 0;-        XVisualInfo info;--        eglGetConfigAttrib(_glfw.egl.display, config,-                           EGL_NATIVE_VISUAL_ID, &visualID);--        info.screen = _glfw.x11.screen;-        mask = VisualScreenMask;--        if (visualID)-        {-            // The X window visual must match the EGL config-            info.visualid = visualID;-            mask |= VisualIDMask;-        }-        else-        {-            // some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID-            // attribute, so attempt to find the closest match.--            eglGetConfigAttrib(_glfw.egl.display, config,-                               EGL_RED_SIZE, &redBits);-            eglGetConfigAttrib(_glfw.egl.display, config,-                               EGL_GREEN_SIZE, &greenBits);-            eglGetConfigAttrib(_glfw.egl.display, config,-                               EGL_BLUE_SIZE, &blueBits);-            eglGetConfigAttrib(_glfw.egl.display, config,-                               EGL_ALPHA_SIZE, &alphaBits);--            info.depth = redBits + greenBits + blueBits + alphaBits;-            mask |= VisualDepthMask;-        }--        window->egl.visual = XGetVisualInfo(_glfw.x11.display,-                                            mask, &info, &count);-        if (!window->egl.visual)-        {-            _glfwInputError(GLFW_PLATFORM_ERROR,-                            "EGL: Failed to retrieve visual for EGLConfig");-            return GL_FALSE;-        }-    }-#endif // _GLFW_X11--    if (ctxconfig->api == GLFW_OPENGL_ES_API)+    if (ctxconfig->client == GLFW_OPENGL_ES_API)     {         if (!eglBindAPI(EGL_OPENGL_ES_API))         {-            _glfwInputError(GLFW_PLATFORM_ERROR,+            _glfwInputError(GLFW_API_UNAVAILABLE,                             "EGL: Failed to bind OpenGL ES: %s",-                            getErrorString(eglGetError()));-            return GL_FALSE;+                            getEGLErrorString(eglGetError()));+            return GLFW_FALSE;         }     }     else     {         if (!eglBindAPI(EGL_OPENGL_API))         {-            _glfwInputError(GLFW_PLATFORM_ERROR,+            _glfwInputError(GLFW_API_UNAVAILABLE,                             "EGL: Failed to bind OpenGL: %s",-                            getErrorString(eglGetError()));-            return GL_FALSE;+                            getEGLErrorString(eglGetError()));+            return GLFW_FALSE;         }     }      if (_glfw.egl.KHR_create_context)     {-        int index = 0, mask = 0, flags = 0, strategy = 0;+        int index = 0, mask = 0, flags = 0; -        if (ctxconfig->api == GLFW_OPENGL_API)+        if (ctxconfig->client == GLFW_OPENGL_API)         {+            if (ctxconfig->forward)+                flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;+             if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)                 mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;             else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)                 mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; -            if (ctxconfig->forward)-                flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;--            if (ctxconfig->debug)-                flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;+            if (_glfw.egl.KHR_create_context_no_error)+            {+                if (ctxconfig->noerror)+                    flags |= EGL_CONTEXT_OPENGL_NO_ERROR_KHR;+            }         } +        if (ctxconfig->debug)+            flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;+         if (ctxconfig->robustness)         {             if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)-                strategy = EGL_NO_RESET_NOTIFICATION_KHR;+            {+                setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,+                             EGL_NO_RESET_NOTIFICATION_KHR);+            }             else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)-                strategy = EGL_LOSE_CONTEXT_ON_RESET_KHR;+            {+                setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,+                             EGL_LOSE_CONTEXT_ON_RESET_KHR);+            }              flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;         }@@ -366,16 +526,13 @@         if (flags)             setEGLattrib(EGL_CONTEXT_FLAGS_KHR, flags); -        if (strategy)-            setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, strategy);-         setEGLattrib(EGL_NONE, EGL_NONE);     }     else     {         int index = 0; -        if (ctxconfig->api == GLFW_OPENGL_ES_API)+        if (ctxconfig->client == GLFW_OPENGL_ES_API)             setEGLattrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);          setEGLattrib(EGL_NONE, EGL_NONE);@@ -384,127 +541,169 @@     // Context release behaviors (GL_KHR_context_flush_control) are not yet     // supported on EGL but are not a hard constraint, so ignore and continue -    window->egl.context = eglCreateContext(_glfw.egl.display,-                                           config, share, attribs);+    window->context.egl.handle = eglCreateContext(_glfw.egl.display,+                                                  config, share, attribs); -    if (window->egl.context == EGL_NO_CONTEXT)+    if (window->context.egl.handle == EGL_NO_CONTEXT)     {-        _glfwInputError(GLFW_PLATFORM_ERROR,+        _glfwInputError(GLFW_VERSION_UNAVAILABLE,                         "EGL: Failed to create context: %s",-                        getErrorString(eglGetError()));-        return GL_FALSE;+                        getEGLErrorString(eglGetError()));+        return GLFW_FALSE;     } -    window->egl.config = config;--    return GL_TRUE;-}+    // Set up attributes for surface creation+    {+        int index = 0; -#undef setEGLattrib+        if (fbconfig->sRGB)+        {+            if (_glfw.egl.KHR_gl_colorspace)+            {+                setEGLattrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);+            }+        } -// Destroy the OpenGL context-//-void _glfwDestroyContext(_GLFWwindow* window)-{-#if defined(_GLFW_X11)-    if (window->egl.visual)-    {-       XFree(window->egl.visual);-       window->egl.visual = NULL;+        setEGLattrib(EGL_NONE, EGL_NONE);     }-#endif // _GLFW_X11 -    if (window->egl.surface)+    window->context.egl.surface =+        eglCreateWindowSurface(_glfw.egl.display,+                               config,+                               _GLFW_EGL_NATIVE_WINDOW,+                               attribs);+    if (window->context.egl.surface == EGL_NO_SURFACE)     {-        eglDestroySurface(_glfw.egl.display, window->egl.surface);-        window->egl.surface = EGL_NO_SURFACE;+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "EGL: Failed to create window surface: %s",+                        getEGLErrorString(eglGetError()));+        return GLFW_FALSE;     } -    if (window->egl.context)-    {-        eglDestroyContext(_glfw.egl.display, window->egl.context);-        window->egl.context = EGL_NO_CONTEXT;-    }-}+    window->context.egl.config = config; -// Analyzes the specified context for possible recreation-//-int _glfwAnalyzeContext(const _GLFWwindow* window,-                        const _GLFWctxconfig* ctxconfig,-                        const _GLFWfbconfig* fbconfig)-{+    // Load the appropriate client library+    {+        int i;+        const char** sonames;+        const char* es1sonames[] =+        { #if defined(_GLFW_WIN32)-    return _GLFW_RECREATION_NOT_NEEDED;+            "GLESv1_CM.dll",+            "libGLES_CM.dll",+#elif defined(_GLFW_COCOA)+            "libGLESv1_CM.dylib", #else-    return 0;+            "libGLESv1_CM.so.1",+            "libGLES_CM.so.1", #endif-}-+            NULL+        };+        const char* es2sonames[] =+        {+#if defined(_GLFW_WIN32)+            "GLESv2.dll",+            "libGLESv2.dll",+#elif defined(_GLFW_COCOA)+            "libGLESv2.dylib",+#else+            "libGLESv2.so.2",+#endif+            NULL+        };+        const char* glsonames[] =+        {+#if defined(_GLFW_WIN32)+#elif defined(_GLFW_COCOA)+#else+            "libGL.so.1",+#endif+            NULL+        }; -//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////+        if (ctxconfig->client == GLFW_OPENGL_ES_API)+        {+            if (ctxconfig->major == 1)+                sonames = es1sonames;+            else+                sonames = es2sonames;+        }+        else+            sonames = glsonames; -void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)-{-    if (window)-    {-        if (window->egl.surface == EGL_NO_SURFACE)+        for (i = 0;  sonames[i];  i++)         {-            window->egl.surface = eglCreateWindowSurface(_glfw.egl.display,-                                                         window->egl.config,-                                                         (EGLNativeWindowType)_GLFW_EGL_NATIVE_WINDOW,-                                                         NULL);-            if (window->egl.surface == EGL_NO_SURFACE)-            {-                _glfwInputError(GLFW_PLATFORM_ERROR,-                                "EGL: Failed to create window surface: %s",-                                getErrorString(eglGetError()));-            }+            // HACK: Match presence of lib prefix to increase chance of finding+            //       a matching pair in the jungle that is Win32 EGL/GLES+            if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))+                continue;++            window->context.egl.client = _glfw_dlopen(sonames[i]);+            if (window->context.egl.client)+                break;         } -        eglMakeCurrent(_glfw.egl.display,-                       window->egl.surface,-                       window->egl.surface,-                       window->egl.context);-    }-    else-    {-        eglMakeCurrent(_glfw.egl.display,-                       EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);+        if (!window->context.egl.client)+        {+            _glfwInputError(GLFW_API_UNAVAILABLE,+                            "EGL: Failed to load client library");+            return GLFW_FALSE;+        }     } -    _glfwSetCurrentContext(window);-}+    window->context.makeCurrent = makeContextCurrentEGL;+    window->context.swapBuffers = swapBuffersEGL;+    window->context.swapInterval = swapIntervalEGL;+    window->context.extensionSupported = extensionSupportedEGL;+    window->context.getProcAddress = getProcAddressEGL;+    window->context.destroy = destroyContextEGL; -void _glfwPlatformSwapBuffers(_GLFWwindow* window)-{-    eglSwapBuffers(_glfw.egl.display, window->egl.surface);+    return GLFW_TRUE; } -void _glfwPlatformSwapInterval(int interval)-{-    eglSwapInterval(_glfw.egl.display, interval);-}+#undef setEGLattrib -int _glfwPlatformExtensionSupported(const char* extension)+// Returns the Visual and depth of the chosen EGLConfig+//+#if defined(_GLFW_X11)+GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,+                              const _GLFWfbconfig* fbconfig,+                              Visual** visual, int* depth) {-    const char* extensions;+    XVisualInfo* result;+    XVisualInfo desired;+    EGLConfig native;+    EGLint visualID = 0, count = 0;+    const long vimask = VisualScreenMask | VisualIDMask; -    extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);-    if (extensions != NULL)+    if (!chooseEGLConfig(ctxconfig, fbconfig, &native))     {-        if (_glfwStringInExtensionString(extension, (unsigned char*) extensions))-            return GL_TRUE;+        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,+                        "EGL: Failed to find a suitable EGLConfig");+        return GLFW_FALSE;     } -    return GL_FALSE;-}+    eglGetConfigAttrib(_glfw.egl.display, native,+                       EGL_NATIVE_VISUAL_ID, &visualID); -GLFWglproc _glfwPlatformGetProcAddress(const char* procname)-{-    return eglGetProcAddress(procname);+    desired.screen = _glfw.x11.screen;+    desired.visualid = visualID;++    result = XGetVisualInfo(_glfw.x11.display, vimask, &desired, &count);+    if (!result)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "EGL: Failed to retrieve Visual for EGLConfig");+        return GLFW_FALSE;+    }++    *visual = result->visual;+    *depth = result->depth;++    XFree(result);+    return GLFW_TRUE; }+#endif // _GLFW_X11   //////////////////////////////////////////////////////////////////////////@@ -521,13 +720,27 @@ {     _GLFWwindow* window = (_GLFWwindow*) handle;     _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);-    return window->egl.context;++    if (window->context.client == GLFW_NO_API)+    {+        _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);+        return EGL_NO_CONTEXT;+    }++    return window->context.egl.handle; }  GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;     _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);-    return window->egl.surface;++    if (window->context.client == GLFW_NO_API)+    {+        _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);+        return EGL_NO_SURFACE;+    }++    return window->context.egl.surface; } 
glfw/src/egl_context.h view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 EGL - www.glfw.org+// GLFW 3.2 EGL - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -25,61 +25,189 @@ // //======================================================================== -#ifndef _egl_context_h_-#define _egl_context_h_+#ifndef _glfw3_egl_context_h_+#define _glfw3_egl_context_h_ -#include <EGL/egl.h>+#if defined(_GLFW_USE_EGLPLATFORM_H)+ #include <EGL/eglplatform.h>+#elif defined(_GLFW_WIN32)+ #define EGLAPIENTRY __stdcall+typedef HDC EGLNativeDisplayType;+typedef HWND EGLNativeWindowType;+#elif defined(_GLFW_X11)+ #define EGLAPIENTRY+typedef Display* EGLNativeDisplayType;+typedef Window EGLNativeWindowType;+#elif defined(_GLFW_WAYLAND)+ #define EGLAPIENTRY+typedef struct wl_display* EGLNativeDisplayType;+typedef struct wl_egl_window* EGLNativeWindowType;+#elif defined(_GLFW_MIR)+ #define EGLAPIENTRY+typedef MirEGLNativeDisplayType EGLNativeDisplayType;+typedef MirEGLNativeWindowType EGLNativeWindowType;+#else+ #error "No supported EGL platform selected"+#endif -// This path may need to be changed if you build GLFW using your own setup-// We ship and use our own copy of eglext.h since GLFW uses fairly new-// extensions and not all operating systems come with an up-to-date version-#include "../deps/EGL/eglext.h"+#define EGL_SUCCESS	0x3000+#define EGL_NOT_INITIALIZED	0x3001+#define EGL_BAD_ACCESS 0x3002+#define EGL_BAD_ALLOC 0x3003+#define EGL_BAD_ATTRIBUTE 0x3004+#define EGL_BAD_CONFIG 0x3005+#define EGL_BAD_CONTEXT	0x3006+#define EGL_BAD_CURRENT_SURFACE	0x3007+#define EGL_BAD_DISPLAY	0x3008+#define EGL_BAD_MATCH 0x3009+#define EGL_BAD_NATIVE_PIXMAP 0x300a+#define EGL_BAD_NATIVE_WINDOW 0x300b+#define EGL_BAD_PARAMETER 0x300c+#define EGL_BAD_SURFACE	0x300d+#define EGL_CONTEXT_LOST 0x300e+#define EGL_COLOR_BUFFER_TYPE 0x303f+#define EGL_RGB_BUFFER 0x308e+#define EGL_SURFACE_TYPE 0x3033+#define EGL_WINDOW_BIT 0x0004+#define EGL_RENDERABLE_TYPE	0x3040+#define EGL_OPENGL_ES_BIT 0x0001+#define EGL_OPENGL_ES2_BIT 0x0004+#define EGL_OPENGL_BIT 0x0008+#define EGL_ALPHA_SIZE 0x3021+#define EGL_BLUE_SIZE 0x3022+#define EGL_GREEN_SIZE 0x3023+#define EGL_RED_SIZE 0x3024+#define EGL_DEPTH_SIZE 0x3025+#define EGL_STENCIL_SIZE 0x3026+#define EGL_SAMPLES	0x3031+#define EGL_OPENGL_ES_API 0x30a0+#define EGL_OPENGL_API 0x30a2+#define EGL_NONE 0x3038+#define EGL_EXTENSIONS 0x3055+#define EGL_CONTEXT_CLIENT_VERSION 0x3098+#define EGL_NATIVE_VISUAL_ID 0x302e+#define EGL_NO_SURFACE ((EGLSurface) 0)+#define EGL_NO_DISPLAY ((EGLDisplay) 0)+#define EGL_NO_CONTEXT ((EGLContext) 0)+#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0) -// Do we have support for dlopen/dlsym?-#if defined(_GLFW_HAS_DLOPEN)- #include <dlfcn.h>-#endif+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31be+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004+#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd+#define EGL_CONTEXT_FLAGS_KHR 0x30fc+#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3+#define EGL_GL_COLORSPACE_KHR 0x309d+#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 -#define _GLFW_PLATFORM_FBCONFIG                 EGLConfig       egl-#define _GLFW_PLATFORM_CONTEXT_STATE            _GLFWcontextEGL egl-#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE    _GLFWlibraryEGL egl+typedef int EGLint;+typedef unsigned int EGLBoolean;+typedef unsigned int EGLenum;+typedef void* EGLConfig;+typedef void* EGLContext;+typedef void* EGLDisplay;+typedef void* EGLSurface; +// EGL function pointer typedefs+typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETCONFIGATTRIBPROC)(EGLDisplay,EGLConfig,EGLint,EGLint*);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETCONFIGSPROC)(EGLDisplay,EGLConfig*,EGLint,EGLint*);+typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType);+typedef EGLint (EGLAPIENTRY * PFNEGLGETERRORPROC)(void);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLINITIALIZEPROC)(EGLDisplay,EGLint*,EGLint*);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLTERMINATEPROC)(EGLDisplay);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLBINDAPIPROC)(EGLenum);+typedef EGLContext (EGLAPIENTRY * PFNEGLCREATECONTEXTPROC)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYSURFACEPROC)(EGLDisplay,EGLSurface);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYCONTEXTPROC)(EGLDisplay,EGLContext);+typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLMAKECURRENTPROC)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPBUFFERSPROC)(EGLDisplay,EGLSurface);+typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPINTERVALPROC)(EGLDisplay,EGLint);+typedef const char* (EGLAPIENTRY * PFNEGLQUERYSTRINGPROC)(EGLDisplay,EGLint);+typedef GLFWglproc (EGLAPIENTRY * PFNEGLGETPROCADDRESSPROC)(const char*);+#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib+#define eglGetConfigs _glfw.egl.GetConfigs+#define eglGetDisplay _glfw.egl.GetDisplay+#define eglGetError _glfw.egl.GetError+#define eglInitialize _glfw.egl.Initialize+#define eglTerminate _glfw.egl.Terminate+#define eglBindAPI _glfw.egl.BindAPI+#define eglCreateContext _glfw.egl.CreateContext+#define eglDestroySurface _glfw.egl.DestroySurface+#define eglDestroyContext _glfw.egl.DestroyContext+#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface+#define eglMakeCurrent _glfw.egl.MakeCurrent+#define eglSwapBuffers _glfw.egl.SwapBuffers+#define eglSwapInterval _glfw.egl.SwapInterval+#define eglQueryString _glfw.egl.QueryString+#define eglGetProcAddress _glfw.egl.GetProcAddress +#define _GLFW_EGL_CONTEXT_STATE            _GLFWcontextEGL egl+#define _GLFW_EGL_LIBRARY_CONTEXT_STATE    _GLFWlibraryEGL egl++ // EGL-specific per-context data // typedef struct _GLFWcontextEGL {-   EGLConfig      config;-   EGLContext     context;-   EGLSurface     surface;+   EGLConfig        config;+   EGLContext       handle;+   EGLSurface       surface; -#if defined(_GLFW_X11)-   XVisualInfo*   visual;-#endif+   void*            client;  } _GLFWcontextEGL; - // EGL-specific global data // typedef struct _GLFWlibraryEGL {     EGLDisplay      display;-    EGLint          versionMajor, versionMinor;+    EGLint          major, minor;+    GLFWbool        prefix; -    GLboolean       KHR_create_context;+    GLFWbool        KHR_create_context;+    GLFWbool        KHR_create_context_no_error;+    GLFWbool        KHR_gl_colorspace; +    void*           handle;++    PFNEGLGETCONFIGATTRIBPROC       GetConfigAttrib;+    PFNEGLGETCONFIGSPROC            GetConfigs;+    PFNEGLGETDISPLAYPROC            GetDisplay;+    PFNEGLGETERRORPROC              GetError;+    PFNEGLINITIALIZEPROC            Initialize;+    PFNEGLTERMINATEPROC             Terminate;+    PFNEGLBINDAPIPROC               BindAPI;+    PFNEGLCREATECONTEXTPROC         CreateContext;+    PFNEGLDESTROYSURFACEPROC        DestroySurface;+    PFNEGLDESTROYCONTEXTPROC        DestroyContext;+    PFNEGLCREATEWINDOWSURFACEPROC   CreateWindowSurface;+    PFNEGLMAKECURRENTPROC           MakeCurrent;+    PFNEGLSWAPBUFFERSPROC           SwapBuffers;+    PFNEGLSWAPINTERVALPROC          SwapInterval;+    PFNEGLQUERYSTRINGPROC           QueryString;+    PFNEGLGETPROCADDRESSPROC        GetProcAddress;+ } _GLFWlibraryEGL;  -int _glfwInitContextAPI(void);-void _glfwTerminateContextAPI(void);-int _glfwCreateContext(_GLFWwindow* window,-                       const _GLFWctxconfig* ctxconfig,-                       const _GLFWfbconfig* fbconfig);-void _glfwDestroyContext(_GLFWwindow* window);-int _glfwAnalyzeContext(const _GLFWwindow* window,-                        const _GLFWctxconfig* ctxconfig,-                        const _GLFWfbconfig* fbconfig);+GLFWbool _glfwInitEGL(void);+void _glfwTerminateEGL(void);+GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,+                               const _GLFWctxconfig* ctxconfig,+                               const _GLFWfbconfig* fbconfig);+#if defined(_GLFW_X11)+GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,+                              const _GLFWfbconfig* fbconfig,+                              Visual** visual, int* depth);+#endif /*_GLFW_X11*/ -#endif // _egl_context_h_+#endif // _glfw3_egl_context_h_
glfw/src/glx_context.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 GLX - www.glfw.org+// GLFW 3.2 GLX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -31,11 +31,6 @@ #include <stdlib.h> #include <assert.h> --// This is the only glXGetProcAddress variant not declared by glxext.h-void (*glXGetProcAddressEXT(const GLubyte* procName))();-- #ifndef GLXBadProfileARB  #define GLXBadProfileARB 13 #endif@@ -43,38 +38,36 @@  // Returns the specified attribute of the specified GLXFBConfig //-static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib)+static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib) {     int value;     glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);     return value; } -// Return a list of available and usable framebuffer configs+// Return the GLXFBConfig most closely matching the specified hints //-static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result)+static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result) {     GLXFBConfig* nativeConfigs;     _GLFWfbconfig* usableConfigs;     const _GLFWfbconfig* closest;     int i, nativeCount, usableCount;     const char* vendor;-    GLboolean trustWindowBit = GL_TRUE;+    GLFWbool trustWindowBit = GLFW_TRUE; +    // HACK: This is a (hopefully temporary) workaround for Chromium+    //       (VirtualBox GL) not setting the window bit on any GLXFBConfigs     vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);     if (strcmp(vendor, "Chromium") == 0)-    {-        // HACK: This is a (hopefully temporary) workaround for Chromium-        //       (VirtualBox GL) not setting the window bit on any GLXFBConfigs-        trustWindowBit = GL_FALSE;-    }+        trustWindowBit = GLFW_FALSE; -    nativeConfigs = glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen,-                                    &nativeCount);+    nativeConfigs =+        glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);     if (!nativeCount)     {         _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");-        return GL_FALSE;+        return GLFW_FALSE;     }      usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));@@ -85,72 +78,62 @@         const GLXFBConfig n = nativeConfigs[i];         _GLFWfbconfig* u = usableConfigs + usableCount; -        if (!getFBConfigAttrib(n, GLX_VISUAL_ID))-        {-            // Only consider GLXFBConfigs with associated visuals+        // Only consider RGBA GLXFBConfigs+        if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))             continue;-        } -        if (!(getFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))-        {-            // Only consider RGBA GLXFBConfigs-            continue;-        }--        if (!(getFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))+        // Only consider window GLXFBConfigs+        if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))         {             if (trustWindowBit)-            {-                // Only consider window GLXFBConfigs                 continue;-            }         } -        u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE);-        u->greenBits = getFBConfigAttrib(n, GLX_GREEN_SIZE);-        u->blueBits = getFBConfigAttrib(n, GLX_BLUE_SIZE);+        u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);+        u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);+        u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE); -        u->alphaBits = getFBConfigAttrib(n, GLX_ALPHA_SIZE);-        u->depthBits = getFBConfigAttrib(n, GLX_DEPTH_SIZE);-        u->stencilBits = getFBConfigAttrib(n, GLX_STENCIL_SIZE);+        u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);+        u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);+        u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE); -        u->accumRedBits = getFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);-        u->accumGreenBits = getFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);-        u->accumBlueBits = getFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);-        u->accumAlphaBits = getFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);+        u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);+        u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);+        u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);+        u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); -        u->auxBuffers = getFBConfigAttrib(n, GLX_AUX_BUFFERS);+        u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS); -        if (getFBConfigAttrib(n, GLX_STEREO))-            u->stereo = GL_TRUE;-        if (getFBConfigAttrib(n, GLX_DOUBLEBUFFER))-            u->doublebuffer = GL_TRUE;+        if (getGLXFBConfigAttrib(n, GLX_STEREO))+            u->stereo = GLFW_TRUE;+        if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))+            u->doublebuffer = GLFW_TRUE;          if (_glfw.glx.ARB_multisample)-            u->samples = getFBConfigAttrib(n, GLX_SAMPLES);+            u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES); -        if (_glfw.glx.ARB_framebuffer_sRGB)-            u->sRGB = getFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);+        if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)+            u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); -        u->glx = n;+        u->handle = (uintptr_t) n;         usableCount++;     }      closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);     if (closest)-        *result = closest->glx;+        *result = (GLXFBConfig) closest->handle;      XFree(nativeConfigs);     free(usableConfigs); -    return closest ? GL_TRUE : GL_FALSE;+    return closest != NULL; }  // Create the OpenGL context using legacy API //-static GLXContext createLegacyContext(_GLFWwindow* window,-                                      GLXFBConfig fbconfig,-                                      GLXContext share)+static GLXContext createLegacyContextGLX(_GLFWwindow* window,+                                         GLXFBConfig fbconfig,+                                         GLXContext share) {     return glXCreateNewContext(_glfw.x11.display,                                fbconfig,@@ -159,122 +142,279 @@                                True); } +static void makeContextCurrentGLX(_GLFWwindow* window)+{+    if (window)+    {+        if (!glXMakeCurrent(_glfw.x11.display,+                            window->context.glx.window,+                            window->context.glx.handle))+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "GLX: Failed to make context current");+            return;+        }+    }+    else+    {+        if (!glXMakeCurrent(_glfw.x11.display, None, NULL))+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "GLX: Failed to clear current context");+            return;+        }+    } +    _glfwPlatformSetCurrentContext(window);+}++static void swapBuffersGLX(_GLFWwindow* window)+{+    glXSwapBuffers(_glfw.x11.display, window->context.glx.window);+}++static void swapIntervalGLX(int interval)+{+    _GLFWwindow* window = _glfwPlatformGetCurrentContext();++    if (_glfw.glx.EXT_swap_control)+    {+        _glfw.glx.SwapIntervalEXT(_glfw.x11.display,+                                  window->context.glx.window,+                                  interval);+    }+    else if (_glfw.glx.MESA_swap_control)+        _glfw.glx.SwapIntervalMESA(interval);+    else if (_glfw.glx.SGI_swap_control)+    {+        if (interval > 0)+            _glfw.glx.SwapIntervalSGI(interval);+    }+}++static int extensionSupportedGLX(const char* extension)+{+    const char* extensions =+        glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);+    if (extensions)+    {+        if (_glfwStringInExtensionString(extension, extensions))+            return GLFW_TRUE;+    }++    return GLFW_FALSE;+}++static GLFWglproc getProcAddressGLX(const char* procname)+{+    if (_glfw.glx.GetProcAddress)+        return _glfw.glx.GetProcAddress((const GLubyte*) procname);+    else if (_glfw.glx.GetProcAddressARB)+        return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);+    else+        return dlsym(_glfw.glx.handle, procname);+}++// Destroy the OpenGL context+//+static void destroyContextGLX(_GLFWwindow* window)+{+    if (window->context.glx.window)+    {+        glXDestroyWindow(_glfw.x11.display, window->context.glx.window);+        window->context.glx.window = None;+    }++    if (window->context.glx.handle)+    {+        glXDestroyContext(_glfw.x11.display, window->context.glx.handle);+        window->context.glx.handle = NULL;+    }+}++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////  // Initialize GLX //-int _glfwInitContextAPI(void)+GLFWbool _glfwInitGLX(void) {-    if (!_glfwInitTLS())-        return GL_FALSE;+    int i;+    const char* sonames[] =+    {+#if defined(__CYGWIN__)+        "libGL-1.so",+#else+        "libGL.so.1",+        "libGL.so",+#endif+        NULL+    }; -#ifdef _GLFW_DLOPEN_LIBGL-    _glfw.glx.libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);-    if (!_glfw.glx.libGL)+    if (_glfw.glx.handle)+        return GLFW_TRUE;++    for (i = 0;  sonames[i];  i++)     {-        _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to find libGL");-        return GL_FALSE;+        _glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL);+        if (_glfw.glx.handle)+            break;     }-#endif +    if (!_glfw.glx.handle)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");+        return GLFW_FALSE;+    }++    _glfw.glx.GetFBConfigs =+        dlsym(_glfw.glx.handle, "glXGetFBConfigs");+    _glfw.glx.GetFBConfigAttrib =+        dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");+    _glfw.glx.GetClientString =+        dlsym(_glfw.glx.handle, "glXGetClientString");+    _glfw.glx.QueryExtension =+        dlsym(_glfw.glx.handle, "glXQueryExtension");+    _glfw.glx.QueryVersion =+        dlsym(_glfw.glx.handle, "glXQueryVersion");+    _glfw.glx.DestroyContext =+        dlsym(_glfw.glx.handle, "glXDestroyContext");+    _glfw.glx.MakeCurrent =+        dlsym(_glfw.glx.handle, "glXMakeCurrent");+    _glfw.glx.SwapBuffers =+        dlsym(_glfw.glx.handle, "glXSwapBuffers");+    _glfw.glx.QueryExtensionsString =+        dlsym(_glfw.glx.handle, "glXQueryExtensionsString");+    _glfw.glx.CreateNewContext =+        dlsym(_glfw.glx.handle, "glXCreateNewContext");+    _glfw.glx.CreateWindow =+        dlsym(_glfw.glx.handle, "glXCreateWindow");+    _glfw.glx.DestroyWindow =+        dlsym(_glfw.glx.handle, "glXDestroyWindow");+    _glfw.glx.GetProcAddress =+        dlsym(_glfw.glx.handle, "glXGetProcAddress");+    _glfw.glx.GetProcAddressARB =+        dlsym(_glfw.glx.handle, "glXGetProcAddressARB");+    _glfw.glx.GetVisualFromFBConfig =+        dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");++    if (!_glfw.glx.GetFBConfigs ||+        !_glfw.glx.GetFBConfigAttrib ||+        !_glfw.glx.GetClientString ||+        !_glfw.glx.QueryExtension ||+        !_glfw.glx.QueryVersion ||+        !_glfw.glx.DestroyContext ||+        !_glfw.glx.MakeCurrent ||+        !_glfw.glx.SwapBuffers ||+        !_glfw.glx.QueryExtensionsString ||+        !_glfw.glx.CreateNewContext ||+        !_glfw.glx.CreateWindow ||+        !_glfw.glx.DestroyWindow ||+        !_glfw.glx.GetProcAddress ||+        !_glfw.glx.GetProcAddressARB ||+        !_glfw.glx.GetVisualFromFBConfig)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "GLX: Failed to load required entry points");+        return GLFW_FALSE;+    }+     if (!glXQueryExtension(_glfw.x11.display,                            &_glfw.glx.errorBase,                            &_glfw.glx.eventBase))     {         _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");-        return GL_FALSE;+        return GLFW_FALSE;     } -    if (!glXQueryVersion(_glfw.x11.display,-                         &_glfw.glx.versionMajor,-                         &_glfw.glx.versionMinor))+    if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))     {         _glfwInputError(GLFW_API_UNAVAILABLE,                         "GLX: Failed to query GLX version");-        return GL_FALSE;+        return GLFW_FALSE;     } -    if (_glfw.glx.versionMajor == 1 && _glfw.glx.versionMinor < 3)+    if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)     {         _glfwInputError(GLFW_API_UNAVAILABLE,                         "GLX: GLX version 1.3 is required");-        return GL_FALSE;+        return GLFW_FALSE;     } -    if (_glfwPlatformExtensionSupported("GLX_EXT_swap_control"))+    if (extensionSupportedGLX("GLX_EXT_swap_control"))     {         _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)-            _glfwPlatformGetProcAddress("glXSwapIntervalEXT");+            getProcAddressGLX("glXSwapIntervalEXT");          if (_glfw.glx.SwapIntervalEXT)-            _glfw.glx.EXT_swap_control = GL_TRUE;+            _glfw.glx.EXT_swap_control = GLFW_TRUE;     } -    if (_glfwPlatformExtensionSupported("GLX_SGI_swap_control"))+    if (extensionSupportedGLX("GLX_SGI_swap_control"))     {         _glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)-            _glfwPlatformGetProcAddress("glXSwapIntervalSGI");+            getProcAddressGLX("glXSwapIntervalSGI");          if (_glfw.glx.SwapIntervalSGI)-            _glfw.glx.SGI_swap_control = GL_TRUE;+            _glfw.glx.SGI_swap_control = GLFW_TRUE;     } -    if (_glfwPlatformExtensionSupported("GLX_MESA_swap_control"))+    if (extensionSupportedGLX("GLX_MESA_swap_control"))     {         _glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)-            _glfwPlatformGetProcAddress("glXSwapIntervalMESA");+            getProcAddressGLX("glXSwapIntervalMESA");          if (_glfw.glx.SwapIntervalMESA)-            _glfw.glx.MESA_swap_control = GL_TRUE;+            _glfw.glx.MESA_swap_control = GLFW_TRUE;     } -    if (_glfwPlatformExtensionSupported("GLX_ARB_multisample"))-        _glfw.glx.ARB_multisample = GL_TRUE;+    if (extensionSupportedGLX("GLX_ARB_multisample"))+        _glfw.glx.ARB_multisample = GLFW_TRUE; -    if (_glfwPlatformExtensionSupported("GLX_ARB_framebuffer_sRGB"))-        _glfw.glx.ARB_framebuffer_sRGB = GL_TRUE;+    if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))+        _glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE; -    if (_glfwPlatformExtensionSupported("GLX_ARB_create_context"))+    if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))+        _glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;++    if (extensionSupportedGLX("GLX_ARB_create_context"))     {         _glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)-            _glfwPlatformGetProcAddress("glXCreateContextAttribsARB");+            getProcAddressGLX("glXCreateContextAttribsARB");          if (_glfw.glx.CreateContextAttribsARB)-            _glfw.glx.ARB_create_context = GL_TRUE;+            _glfw.glx.ARB_create_context = GLFW_TRUE;     } -    if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_robustness"))-        _glfw.glx.ARB_create_context_robustness = GL_TRUE;+    if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))+        _glfw.glx.ARB_create_context_robustness = GLFW_TRUE; -    if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile"))-        _glfw.glx.ARB_create_context_profile = GL_TRUE;+    if (extensionSupportedGLX("GLX_ARB_create_context_profile"))+        _glfw.glx.ARB_create_context_profile = GLFW_TRUE; -    if (_glfwPlatformExtensionSupported("GLX_EXT_create_context_es2_profile"))-        _glfw.glx.EXT_create_context_es2_profile = GL_TRUE;+    if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))+        _glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE; -    if (_glfwPlatformExtensionSupported("GLX_ARB_context_flush_control"))-        _glfw.glx.ARB_context_flush_control = GL_TRUE;+    if (extensionSupportedGLX("GLX_ARB_context_flush_control"))+        _glfw.glx.ARB_context_flush_control = GLFW_TRUE; -    return GL_TRUE;+    return GLFW_TRUE; }  // Terminate GLX //-void _glfwTerminateContextAPI(void)+void _glfwTerminateGLX(void) {-    // Unload libGL.so if necessary-#ifdef _GLFW_DLOPEN_LIBGL-    if (_glfw.glx.libGL != NULL)+    // NOTE: This function must not call any X11 functions, as it is called+    //       after XCloseDisplay (see _glfwPlatformTerminate for details)++    if (_glfw.glx.handle)     {-        dlclose(_glfw.glx.libGL);-        _glfw.glx.libGL = NULL;+        dlclose(_glfw.glx.handle);+        _glfw.glx.handle = NULL;     }-#endif--    _glfwTerminateTLS(); }  #define setGLXattrib(attribName, attribValue) \@@ -286,43 +426,33 @@  // Create the OpenGL or OpenGL ES context //-int _glfwCreateContext(_GLFWwindow* window,-                       const _GLFWctxconfig* ctxconfig,-                       const _GLFWfbconfig* fbconfig)+GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,+                               const _GLFWctxconfig* ctxconfig,+                               const _GLFWfbconfig* fbconfig) {     int attribs[40];-    GLXFBConfig native;+    GLXFBConfig native = NULL;     GLXContext share = NULL;      if (ctxconfig->share)-        share = ctxconfig->share->glx.context;+        share = ctxconfig->share->context.glx.handle; -    if (!chooseFBConfig(fbconfig, &native))+    if (!chooseGLXFBConfig(fbconfig, &native))     {-        _glfwInputError(GLFW_PLATFORM_ERROR,+        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,                         "GLX: Failed to find a suitable GLXFBConfig");-        return GL_FALSE;-    }--    // Retrieve the corresponding visual-    window->glx.visual = glXGetVisualFromFBConfig(_glfw.x11.display, native);-    if (!window->glx.visual)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "GLX: Failed to retrieve visual for GLXFBConfig");-        return GL_FALSE;+        return GLFW_FALSE;     } -    if (ctxconfig->api == GLFW_OPENGL_ES_API)+    if (ctxconfig->client == GLFW_OPENGL_ES_API)     {         if (!_glfw.glx.ARB_create_context ||             !_glfw.glx.ARB_create_context_profile ||             !_glfw.glx.EXT_create_context_es2_profile)         {             _glfwInputError(GLFW_API_UNAVAILABLE,-                            "GLX: OpenGL ES requested but "-                            "GLX_EXT_create_context_es2_profile is unavailable");-            return GL_FALSE;+                            "GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");+            return GLFW_FALSE;         }     } @@ -331,9 +461,8 @@         if (!_glfw.glx.ARB_create_context)         {             _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                            "GLX: Forward compatibility requested but "-                            "GLX_ARB_create_context_profile is unavailable");-            return GL_FALSE;+                            "GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");+            return GLFW_FALSE;         }     } @@ -343,45 +472,49 @@             !_glfw.glx.ARB_create_context_profile)         {             _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                            "GLX: An OpenGL profile requested but "-                            "GLX_ARB_create_context_profile is unavailable");-            return GL_FALSE;+                            "GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");+            return GLFW_FALSE;         }     } -    _glfwGrabXErrorHandler();+    _glfwGrabErrorHandlerX11();      if (_glfw.glx.ARB_create_context)     {-        int index = 0, mask = 0, flags = 0, strategy = 0;+        int index = 0, mask = 0, flags = 0; -        if (ctxconfig->api == GLFW_OPENGL_API)+        if (ctxconfig->client == GLFW_OPENGL_API)         {             if (ctxconfig->forward)                 flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; -            if (ctxconfig->debug)-                flags |= GLX_CONTEXT_DEBUG_BIT_ARB;--            if (ctxconfig->profile)-            {-                if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)-                    mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;-                else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)-                    mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;-            }+            if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)+                mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;+            else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)+                mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;         }         else             mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; +        if (ctxconfig->debug)+            flags |= GLX_CONTEXT_DEBUG_BIT_ARB;+        if (ctxconfig->noerror)+            flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;+         if (ctxconfig->robustness)         {             if (_glfw.glx.ARB_create_context_robustness)             {                 if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)-                    strategy = GLX_NO_RESET_NOTIFICATION_ARB;+                {+                    setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,+                                 GLX_NO_RESET_NOTIFICATION_ARB);+                }                 else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)-                    strategy = GLX_LOSE_CONTEXT_ON_RESET_ARB;+                {+                    setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,+                                 GLX_LOSE_CONTEXT_ON_RESET_ARB);+                }                  flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;             }@@ -404,12 +537,11 @@             }         } +        // NOTE: Only request an explicitly versioned context when necessary, as+        //       explicitly requesting version 1.0 does not always return the+        //       highest version supported by the driver         if (ctxconfig->major != 1 || ctxconfig->minor != 0)         {-            // NOTE: Only request an explicitly versioned context when-            //       necessary, as explicitly requesting version 1.0 does not-            //       always return the highest available version-             setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);             setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);         }@@ -420,128 +552,94 @@         if (flags)             setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags); -        if (strategy)-            setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy);-         setGLXattrib(None, None); -        window->glx.context =+        window->context.glx.handle =             _glfw.glx.CreateContextAttribsARB(_glfw.x11.display,                                               native,                                               share,                                               True,                                               attribs); -        if (!window->glx.context)+        // HACK: This is a fallback for broken versions of the Mesa+        //       implementation of GLX_ARB_create_context_profile that fail+        //       default 1.0 context creation with a GLXBadProfileARB error in+        //       violation of the extension spec+        if (!window->context.glx.handle)         {-            // 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 extension spec             if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&-                ctxconfig->api == GLFW_OPENGL_API &&+                ctxconfig->client == GLFW_OPENGL_API &&                 ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&-                ctxconfig->forward == GL_FALSE)+                ctxconfig->forward == GLFW_FALSE)             {-                window->glx.context = createLegacyContext(window, native, share);+                window->context.glx.handle =+                    createLegacyContextGLX(window, native, share);             }         }     }     else-        window->glx.context = createLegacyContext(window, native, share);--    _glfwReleaseXErrorHandler();--    if (!window->glx.context)     {-        _glfwInputXError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context");-        return GL_FALSE;+        window->context.glx.handle =+            createLegacyContextGLX(window, native, share);     } -    return GL_TRUE;-}--#undef setGLXattrib+    _glfwReleaseErrorHandlerX11(); -// Destroy the OpenGL context-//-void _glfwDestroyContext(_GLFWwindow* window)-{-    if (window->glx.visual)+    if (!window->context.glx.handle)     {-        XFree(window->glx.visual);-        window->glx.visual = NULL;+        _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");+        return GLFW_FALSE;     } -    if (window->glx.context)+    window->context.glx.window =+        glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);+    if (!window->context.glx.window)     {-        glXDestroyContext(_glfw.x11.display, window->glx.context);-        window->glx.context = NULL;+        _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");+        return GLFW_FALSE;     }-} --//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////--void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)-{-    if (window)-    {-        glXMakeCurrent(_glfw.x11.display,-                       window->x11.handle,-                       window->glx.context);-    }-    else-        glXMakeCurrent(_glfw.x11.display, None, NULL);+    window->context.makeCurrent = makeContextCurrentGLX;+    window->context.swapBuffers = swapBuffersGLX;+    window->context.swapInterval = swapIntervalGLX;+    window->context.extensionSupported = extensionSupportedGLX;+    window->context.getProcAddress = getProcAddressGLX;+    window->context.destroy = destroyContextGLX; -    _glfwSetCurrentContext(window);+    return GLFW_TRUE; } -void _glfwPlatformSwapBuffers(_GLFWwindow* window)-{-    glXSwapBuffers(_glfw.x11.display, window->x11.handle);-}+#undef setGLXattrib -void _glfwPlatformSwapInterval(int interval)+// Returns the Visual and depth of the chosen GLXFBConfig+//+GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,+                              const _GLFWfbconfig* fbconfig,+                              Visual** visual, int* depth) {-    _GLFWwindow* window = _glfwPlatformGetCurrentContext();+    GLXFBConfig native;+    XVisualInfo* result; -    if (_glfw.glx.EXT_swap_control)-    {-        _glfw.glx.SwapIntervalEXT(_glfw.x11.display,-                                  window->x11.handle,-                                  interval);-    }-    else if (_glfw.glx.MESA_swap_control)-        _glfw.glx.SwapIntervalMESA(interval);-    else if (_glfw.glx.SGI_swap_control)+    if (!chooseGLXFBConfig(fbconfig, &native))     {-        if (interval > 0)-            _glfw.glx.SwapIntervalSGI(interval);+        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,+                        "GLX: Failed to find a suitable GLXFBConfig");+        return GLFW_FALSE;     }-} -int _glfwPlatformExtensionSupported(const char* extension)-{-    const GLubyte* extensions;--    // Get list of GLX extensions-    extensions = (const GLubyte*) glXQueryExtensionsString(_glfw.x11.display,-                                                           _glfw.x11.screen);-    if (extensions != NULL)+    result = glXGetVisualFromFBConfig(_glfw.x11.display, native);+    if (!result)     {-        if (_glfwStringInExtensionString(extension, extensions))-            return GL_TRUE;+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "GLX: Failed to retrieve Visual for GLXFBConfig");+        return GLFW_FALSE;     } -    return GL_FALSE;-}+    *visual = result->visual;+    *depth = result->depth; -GLFWglproc _glfwPlatformGetProcAddress(const char* procname)-{-    return _glfw_glXGetProcAddress((const GLubyte*) procname);+    XFree(result);+    return GLFW_TRUE; }  @@ -553,6 +651,27 @@ {     _GLFWwindow* window = (_GLFWwindow*) handle;     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);-    return window->glx.context;++    if (window->context.client == GLFW_NO_API)+    {+        _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);+        return NULL;+    }++    return window->context.glx.handle;+}++GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    _GLFW_REQUIRE_INIT_OR_RETURN(None);++    if (window->context.client == GLFW_NO_API)+    {+        _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);+        return None;+    }++    return window->context.glx.window; } 
glfw/src/glx_context.h view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 GLX - www.glfw.org+// GLFW 3.2 GLX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -25,96 +25,158 @@ // //======================================================================== -#ifndef _glx_context_h_-#define _glx_context_h_+#ifndef _glfw3_glx_context_h_+#define _glfw3_glx_context_h_ -#define GLX_GLXEXT_LEGACY-#include <GL/glx.h>+#define GLX_VENDOR 1+#define GLX_RGBA_BIT 0x00000001+#define GLX_WINDOW_BIT 0x00000001+#define GLX_DRAWABLE_TYPE 0x8010+#define GLX_RENDER_TYPE	0x8011+#define GLX_RGBA_TYPE 0x8014+#define GLX_DOUBLEBUFFER 5+#define GLX_STEREO 6+#define GLX_AUX_BUFFERS	7+#define GLX_RED_SIZE 8+#define GLX_GREEN_SIZE 9+#define GLX_BLUE_SIZE 10+#define GLX_ALPHA_SIZE 11+#define GLX_DEPTH_SIZE 12+#define GLX_STENCIL_SIZE 13+#define GLX_ACCUM_RED_SIZE 14+#define GLX_ACCUM_GREEN_SIZE 15+#define GLX_ACCUM_BLUE_SIZE	16+#define GLX_ACCUM_ALPHA_SIZE 17+#define GLX_SAMPLES 0x186a1+#define GLX_VISUAL_ID 0x800b -// 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-// extensions and not all operating systems come with an up-to-date version-#include "../deps/GL/glxext.h"+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2+#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092+#define GLX_CONTEXT_FLAGS_ARB 0x2094+#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004+#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004+#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252+#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256+#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261+#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097+#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0+#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 -// Do we have support for dlopen/dlsym?-#if defined(_GLFW_HAS_DLOPEN)- #include <dlfcn.h>-#endif+typedef XID GLXWindow;+typedef XID GLXDrawable;+typedef struct __GLXFBConfig* GLXFBConfig;+typedef struct __GLXcontext* GLXContext;+typedef void (*__GLXextproc)(void); -// We support four different ways for getting addresses for GL/GLX-// extension functions: glXGetProcAddress, glXGetProcAddressARB,-// glXGetProcAddressEXT, and dlsym-#if defined(_GLFW_HAS_GLXGETPROCADDRESSARB)- #define _glfw_glXGetProcAddress(x) glXGetProcAddressARB(x)-#elif defined(_GLFW_HAS_GLXGETPROCADDRESS)- #define _glfw_glXGetProcAddress(x) glXGetProcAddress(x)-#elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT)- #define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x)-#elif defined(_GLFW_HAS_DLOPEN)- #define _glfw_glXGetProcAddress(x) dlsym(_glfw.glx.libGL, x)- #define _GLFW_DLOPEN_LIBGL-#else- #error "No OpenGL entry point retrieval mechanism was enabled"-#endif+typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);+typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);+typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);+typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);+typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext);+typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext);+typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);+typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);+typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);+typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);+typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName);+typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);+typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);+typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);+typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);+typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig);+typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*);+typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow); -#define _GLFW_PLATFORM_FBCONFIG                 GLXFBConfig     glx+// libGL.so function pointer typedefs+#define glXGetFBConfigs _glfw.glx.GetFBConfigs+#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib+#define glXGetClientString _glfw.glx.GetClientString+#define glXQueryExtension _glfw.glx.QueryExtension+#define glXQueryVersion _glfw.glx.QueryVersion+#define glXDestroyContext _glfw.glx.DestroyContext+#define glXMakeCurrent _glfw.glx.MakeCurrent+#define glXSwapBuffers _glfw.glx.SwapBuffers+#define glXQueryExtensionsString _glfw.glx.QueryExtensionsString+#define glXCreateNewContext _glfw.glx.CreateNewContext+#define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig+#define glXCreateWindow _glfw.glx.CreateWindow+#define glXDestroyWindow _glfw.glx.DestroyWindow+ #define _GLFW_PLATFORM_CONTEXT_STATE            _GLFWcontextGLX glx #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE    _GLFWlibraryGLX glx -#ifndef GLX_MESA_swap_control-typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);-#endif - // GLX-specific per-context data // typedef struct _GLFWcontextGLX {-    // Rendering context-    GLXContext      context;-    // Visual of selected GLXFBConfig-    XVisualInfo*    visual;+    GLXContext      handle;+    GLXWindow       window;  } _GLFWcontextGLX; - // GLX-specific global data // typedef struct _GLFWlibraryGLX {-    int             versionMajor, versionMinor;+    int             major, minor;     int             eventBase;     int             errorBase; -    // GLX extensions-    PFNGLXSWAPINTERVALSGIPROC             SwapIntervalSGI;-    PFNGLXSWAPINTERVALEXTPROC             SwapIntervalEXT;-    PFNGLXSWAPINTERVALMESAPROC            SwapIntervalMESA;-    PFNGLXCREATECONTEXTATTRIBSARBPROC     CreateContextAttribsARB;-    GLboolean       SGI_swap_control;-    GLboolean       EXT_swap_control;-    GLboolean       MESA_swap_control;-    GLboolean       ARB_multisample;-    GLboolean       ARB_framebuffer_sRGB;-    GLboolean       ARB_create_context;-    GLboolean       ARB_create_context_profile;-    GLboolean       ARB_create_context_robustness;-    GLboolean       EXT_create_context_es2_profile;-    GLboolean       ARB_context_flush_control;+    // dlopen handle for libGL.so.1+    void*           handle; -#if defined(_GLFW_DLOPEN_LIBGL)-    // dlopen handle for libGL.so (for glfwGetProcAddress)-    void*           libGL;-#endif+    // GLX 1.3 functions+    PFNGLXGETFBCONFIGSPROC              GetFBConfigs;+    PFNGLXGETFBCONFIGATTRIBPROC         GetFBConfigAttrib;+    PFNGLXGETCLIENTSTRINGPROC           GetClientString;+    PFNGLXQUERYEXTENSIONPROC            QueryExtension;+    PFNGLXQUERYVERSIONPROC              QueryVersion;+    PFNGLXDESTROYCONTEXTPROC            DestroyContext;+    PFNGLXMAKECURRENTPROC               MakeCurrent;+    PFNGLXSWAPBUFFERSPROC               SwapBuffers;+    PFNGLXQUERYEXTENSIONSSTRINGPROC     QueryExtensionsString;+    PFNGLXCREATENEWCONTEXTPROC          CreateNewContext;+    PFNGLXGETVISUALFROMFBCONFIGPROC     GetVisualFromFBConfig;+    PFNGLXCREATEWINDOWPROC              CreateWindow;+    PFNGLXDESTROYWINDOWPROC             DestroyWindow; +    // GLX 1.4 and extension functions+    PFNGLXGETPROCADDRESSPROC            GetProcAddress;+    PFNGLXGETPROCADDRESSPROC            GetProcAddressARB;+    PFNGLXSWAPINTERVALSGIPROC           SwapIntervalSGI;+    PFNGLXSWAPINTERVALEXTPROC           SwapIntervalEXT;+    PFNGLXSWAPINTERVALMESAPROC          SwapIntervalMESA;+    PFNGLXCREATECONTEXTATTRIBSARBPROC   CreateContextAttribsARB;+    GLFWbool        SGI_swap_control;+    GLFWbool        EXT_swap_control;+    GLFWbool        MESA_swap_control;+    GLFWbool        ARB_multisample;+    GLFWbool        ARB_framebuffer_sRGB;+    GLFWbool        EXT_framebuffer_sRGB;+    GLFWbool        ARB_create_context;+    GLFWbool        ARB_create_context_profile;+    GLFWbool        ARB_create_context_robustness;+    GLFWbool        EXT_create_context_es2_profile;+    GLFWbool        ARB_context_flush_control;+ } _GLFWlibraryGLX;  -int _glfwInitContextAPI(void);-void _glfwTerminateContextAPI(void);-int _glfwCreateContext(_GLFWwindow* window,-                       const _GLFWctxconfig* ctxconfig,-                       const _GLFWfbconfig* fbconfig);-void _glfwDestroyContext(_GLFWwindow* window);+GLFWbool _glfwInitGLX(void);+void _glfwTerminateGLX(void);+GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,+                               const _GLFWctxconfig* ctxconfig,+                               const _GLFWfbconfig* fbconfig);+void _glfwDestroyContextGLX(_GLFWwindow* window);+GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,+                              const _GLFWfbconfig* fbconfig,+                              Visual** visual, int* depth); -#endif // _glx_context_h_+#endif // _glfw3_glx_context_h_
glfw/src/init.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 - www.glfw.org+// GLFW 3.2 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -33,13 +33,13 @@ #include <stdarg.h>  -// The three global variables below comprise all global data in GLFW, except for-// various static const translation tables.  Any other global variable is a bug.+// The three global variables below comprise all global data in GLFW.+// Any other global variable is a bug.  // Global state shared between compilation units of GLFW // These are documented in internal.h //-GLboolean _glfwInitialized = GL_FALSE;+GLFWbool _glfwInitialized = GLFW_FALSE; _GLFWlibrary _glfw;  // This is outside of _glfw so it can be initialized and usable before@@ -65,16 +65,18 @@         case GLFW_OUT_OF_MEMORY:             return "Out of memory";         case GLFW_API_UNAVAILABLE:-            return "The requested client API is unavailable";+            return "The requested API is unavailable";         case GLFW_VERSION_UNAVAILABLE:-            return "The requested client API version is unavailable";+            return "The requested API version is unavailable";         case GLFW_PLATFORM_ERROR:             return "A platform-specific error occurred";         case GLFW_FORMAT_UNAVAILABLE:             return "The requested format is unavailable";+        case GLFW_NO_WINDOW_CONTEXT:+            return "The specified window has no context";+        default:+            return "ERROR: UNKNOWN GLFW ERROR";     }--    return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString"; }  @@ -86,7 +88,7 @@ {     if (_glfwErrorCallback)     {-        char buffer[16384];+        char buffer[8192];         const char* description;          if (format)@@ -118,30 +120,25 @@ GLFWAPI int glfwInit(void) {     if (_glfwInitialized)-        return GL_TRUE;+        return GLFW_TRUE;      memset(&_glfw, 0, sizeof(_glfw));      if (!_glfwPlatformInit())     {         _glfwPlatformTerminate();-        return GL_FALSE;+        return GLFW_FALSE;     }      _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);-    if (!_glfw.monitorCount)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR, "No monitors found");-        _glfwPlatformTerminate();-        return GL_FALSE;-    }+    _glfwInitialized = GLFW_TRUE; -    _glfwInitialized = GL_TRUE;+    _glfw.timerOffset = _glfwPlatformGetTimerValue();      // Not all window hints have zero as their default value     glfwDefaultWindowHints(); -    return GL_TRUE;+    return GLFW_TRUE; }  GLFWAPI void glfwTerminate(void)@@ -166,6 +163,8 @@             _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);     } +    _glfwTerminateVulkan();+     _glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);     _glfw.monitors = NULL;     _glfw.monitorCount = 0;@@ -173,7 +172,7 @@     _glfwPlatformTerminate();      memset(&_glfw, 0, sizeof(_glfw));-    _glfwInitialized = GL_FALSE;+    _glfwInitialized = GLFW_FALSE; }  GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
glfw/src/input.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 - www.glfw.org+// GLFW 3.2 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -27,107 +27,14 @@  #include "internal.h" -#include <stdlib.h>+#include <assert.h> #include <float.h>-#if defined(_MSC_VER)- #include <malloc.h>-#endif+#include <stdlib.h>  // Internal key state used for sticky keys #define _GLFW_STICK 3  -// Sets the cursor mode for the specified window-//-static void setCursorMode(_GLFWwindow* window, int newMode)-{-    const int oldMode = window->cursorMode;--    if (newMode != GLFW_CURSOR_NORMAL &&-        newMode != GLFW_CURSOR_HIDDEN &&-        newMode != GLFW_CURSOR_DISABLED)-    {-        _glfwInputError(GLFW_INVALID_ENUM, NULL);-        return;-    }--    if (oldMode == newMode)-        return;--    window->cursorMode = newMode;--    if (_glfw.focusedWindow == window)-    {-        if (oldMode == GLFW_CURSOR_DISABLED)-        {-            _glfwPlatformSetCursorPos(window,-                                      _glfw.cursorPosX,-                                      _glfw.cursorPosY);-        }-        else if (newMode == GLFW_CURSOR_DISABLED)-        {-            int width, height;--            _glfwPlatformGetCursorPos(window,-                                      &_glfw.cursorPosX,-                                      &_glfw.cursorPosY);--            window->cursorPosX = _glfw.cursorPosX;-            window->cursorPosY = _glfw.cursorPosY;--            _glfwPlatformGetWindowSize(window, &width, &height);-            _glfwPlatformSetCursorPos(window, width / 2, height / 2);-        }--        _glfwPlatformApplyCursorMode(window);-    }-}--// Set sticky keys mode for the specified window-//-static void setStickyKeys(_GLFWwindow* window, int enabled)-{-    if (window->stickyKeys == enabled)-        return;--    if (!enabled)-    {-        int i;--        // Release all sticky keys-        for (i = 0;  i <= GLFW_KEY_LAST;  i++)-        {-            if (window->keys[i] == _GLFW_STICK)-                window->keys[i] = GLFW_RELEASE;-        }-    }--    window->stickyKeys = enabled;-}--// Set sticky mouse buttons mode for the specified window-//-static void setStickyMouseButtons(_GLFWwindow* window, int enabled)-{-    if (window->stickyMouseButtons == enabled)-        return;--    if (!enabled)-    {-        int i;--        // Release all sticky mouse buttons-        for (i = 0;  i <= GLFW_MOUSE_BUTTON_LAST;  i++)-        {-            if (window->mouseButtons[i] == _GLFW_STICK)-                window->mouseButtons[i] = GLFW_RELEASE;-        }-    }--    window->stickyMouseButtons = enabled;-}-- ////////////////////////////////////////////////////////////////////////// //////                         GLFW event API                       ////// //////////////////////////////////////////////////////////////////////////@@ -136,13 +43,13 @@ {     if (key >= 0 && key <= GLFW_KEY_LAST)     {-        GLboolean repeated = GL_FALSE;+        GLFWbool repeated = GLFW_FALSE;          if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)             return;          if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)-            repeated = GL_TRUE;+            repeated = GLFW_TRUE;          if (action == GLFW_RELEASE && window->stickyKeys)             window->keys[key] = _GLFW_STICK;@@ -157,7 +64,7 @@         window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods); } -void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain)+void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain) {     if (codepoint < 32 || (codepoint > 126 && codepoint < 160))         return;@@ -193,25 +100,19 @@         window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods); } -void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y)+void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos) {-    if (window->cursorMode == GLFW_CURSOR_DISABLED)-    {-        if (x == 0.0 && y == 0.0)-            return;--        window->cursorPosX += x;-        window->cursorPosY += y;+    if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)+        return; -        x = window->cursorPosX;-        y = window->cursorPosY;-    }+    window->virtualCursorPosX = xpos;+    window->virtualCursorPosY = ypos;      if (window->callbacks.cursorPos)-        window->callbacks.cursorPos((GLFWwindow*) window, x, y);+        window->callbacks.cursorPos((GLFWwindow*) window, xpos, ypos); } -void _glfwInputCursorEnter(_GLFWwindow* window, int entered)+void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered) {     if (window->callbacks.cursorEnter)         window->callbacks.cursorEnter((GLFWwindow*) window, entered);@@ -223,14 +124,33 @@         window->callbacks.drop((GLFWwindow*) window, count, paths); } +void _glfwInputJoystickChange(int joy, int event)+{+    if (_glfw.callbacks.joystick)+        _glfw.callbacks.joystick(joy, event);+} + //////////////////////////////////////////////////////////////////////////+//////                       GLFW internal API                      //////+//////////////////////////////////////////////////////////////////////////++GLFWbool _glfwIsPrintable(int key)+{+    return (key >= GLFW_KEY_APOSTROPHE && key <= GLFW_KEY_WORLD_2) ||+           (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) ||+           key == GLFW_KEY_KP_EQUAL;+}+++////////////////////////////////////////////////////////////////////////// //////                        GLFW public API                       ////// //////////////////////////////////////////////////////////////////////////  GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT_OR_RETURN(0); @@ -243,7 +163,7 @@         case GLFW_STICKY_MOUSE_BUTTONS:             return window->stickyMouseButtons;         default:-            _glfwInputError(GLFW_INVALID_ENUM, NULL);+            _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode);             return 0;     } }@@ -251,35 +171,101 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT();      switch (mode)     {         case GLFW_CURSOR:-            setCursorMode(window, value);-            break;+        {+            if (value != GLFW_CURSOR_NORMAL &&+                value != GLFW_CURSOR_HIDDEN &&+                value != GLFW_CURSOR_DISABLED)+            {+                _glfwInputError(GLFW_INVALID_ENUM,+                                "Invalid cursor mode %i",+                                value);+                return;+            }++            if (window->cursorMode == value)+                return;++            window->cursorMode = value;++            _glfwPlatformGetCursorPos(window,+                                      &window->virtualCursorPosX,+                                      &window->virtualCursorPosY);++            if (_glfwPlatformWindowFocused(window))+                _glfwPlatformSetCursorMode(window, value);++            return;+        }+         case GLFW_STICKY_KEYS:-            setStickyKeys(window, value ? GL_TRUE : GL_FALSE);-            break;+        {+            if (window->stickyKeys == value)+                return;++            if (!value)+            {+                int i;++                // Release all sticky keys+                for (i = 0;  i <= GLFW_KEY_LAST;  i++)+                {+                    if (window->keys[i] == _GLFW_STICK)+                        window->keys[i] = GLFW_RELEASE;+                }+            }++            window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;+            return;+        }+         case GLFW_STICKY_MOUSE_BUTTONS:-            setStickyMouseButtons(window, value ? GL_TRUE : GL_FALSE);-            break;-        default:-            _glfwInputError(GLFW_INVALID_ENUM, NULL);-            break;+        {+            if (window->stickyMouseButtons == value)+                return;++            if (!value)+            {+                int i;++                // Release all sticky mouse buttons+                for (i = 0;  i <= GLFW_MOUSE_BUTTON_LAST;  i++)+                {+                    if (window->mouseButtons[i] == _GLFW_STICK)+                        window->mouseButtons[i] = GLFW_RELEASE;+                }+            }++            window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;+            return;+        }     }++    _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode); } +GLFWAPI const char* glfwGetKeyName(int key, int scancode)+{+    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);+    return _glfwPlatformGetKeyName(key, scancode);+}+ GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); -    if (key < 0 || key > GLFW_KEY_LAST)+    if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)     {-        _glfwInputError(GLFW_INVALID_ENUM, "The specified key is invalid");+        _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);         return GLFW_RELEASE;     } @@ -296,13 +282,13 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); -    if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)+    if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST)     {-        _glfwInputError(GLFW_INVALID_ENUM,-                        "The specified mouse button is invalid");+        _glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button);         return GLFW_RELEASE;     } @@ -319,6 +305,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      if (xpos)         *xpos = 0;@@ -330,9 +317,9 @@     if (window->cursorMode == GLFW_CURSOR_DISABLED)     {         if (xpos)-            *xpos = window->cursorPosX;+            *xpos = window->virtualCursorPosX;         if (ypos)-            *ypos = window->cursorPosY;+            *ypos = window->virtualCursorPosY;     }     else         _glfwPlatformGetCursorPos(window, xpos, ypos);@@ -341,17 +328,27 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT(); -    if (_glfw.focusedWindow != window)+    if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||+        ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX)+    {+        _glfwInputError(GLFW_INVALID_VALUE,+                        "Invalid cursor position %f %f",+                        xpos, ypos);         return;+    } +    if (!_glfwPlatformWindowFocused(window))+        return;+     if (window->cursorMode == GLFW_CURSOR_DISABLED)     {         // Only update the accumulated position if the cursor is disabled-        window->cursorPosX = xpos;-        window->cursorPosY = ypos;+        window->virtualCursorPosX = xpos;+        window->virtualCursorPosY = ypos;     }     else     {@@ -364,6 +361,8 @@ {     _GLFWcursor* cursor; +    assert(image != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);      cursor = calloc(1, sizeof(_GLFWcursor));@@ -385,6 +384,17 @@      _GLFW_REQUIRE_INIT_OR_RETURN(NULL); +    if (shape != GLFW_ARROW_CURSOR &&+        shape != GLFW_IBEAM_CURSOR &&+        shape != GLFW_CROSSHAIR_CURSOR &&+        shape != GLFW_HAND_CURSOR &&+        shape != GLFW_HRESIZE_CURSOR &&+        shape != GLFW_VRESIZE_CURSOR)+    {+        _glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor %i", shape);+        return NULL;+    }+     cursor = calloc(1, sizeof(_GLFWcursor));     cursor->next = _glfw.cursorListHead;     _glfw.cursorListHead = cursor;@@ -437,17 +447,20 @@ {     _GLFWwindow* window = (_GLFWwindow*) windowHandle;     _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT(); -    _glfwPlatformSetCursor(window, cursor);-     window->cursor = cursor;++    _glfwPlatformSetCursor(window, cursor); }  GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun);     return cbfun;@@ -456,6 +469,8 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun);     return cbfun;@@ -464,6 +479,8 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun);     return cbfun;@@ -473,6 +490,8 @@                                                       GLFWmousebuttonfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun);     return cbfun;@@ -482,6 +501,8 @@                                                   GLFWcursorposfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun);     return cbfun;@@ -491,6 +512,8 @@                                                       GLFWcursorenterfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun);     return cbfun;@@ -500,6 +523,8 @@                                             GLFWscrollfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun);     return cbfun;@@ -508,6 +533,8 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);     return cbfun;@@ -519,7 +546,7 @@      if (joy < 0 || joy > GLFW_JOYSTICK_LAST)     {-        _glfwInputError(GLFW_INVALID_ENUM, NULL);+        _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy);         return 0;     } @@ -528,13 +555,14 @@  GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count) {+    assert(count != NULL);     *count = 0;      _GLFW_REQUIRE_INIT_OR_RETURN(NULL);      if (joy < 0 || joy > GLFW_JOYSTICK_LAST)     {-        _glfwInputError(GLFW_INVALID_ENUM, NULL);+        _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy);         return NULL;     } @@ -543,13 +571,14 @@  GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count) {+    assert(count != NULL);     *count = 0;      _GLFW_REQUIRE_INIT_OR_RETURN(NULL);      if (joy < 0 || joy > GLFW_JOYSTICK_LAST)     {-        _glfwInputError(GLFW_INVALID_ENUM, NULL);+        _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy);         return NULL;     } @@ -562,16 +591,26 @@      if (joy < 0 || joy > GLFW_JOYSTICK_LAST)     {-        _glfwInputError(GLFW_INVALID_ENUM, NULL);+        _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy);         return NULL;     }      return _glfwPlatformGetJoystickName(joy); } +GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)+{+    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);+    _GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);+    return cbfun;+}+ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+    assert(string != NULL);+     _GLFW_REQUIRE_INIT();     _glfwPlatformSetClipboardString(window, string); }@@ -579,6 +618,8 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     return _glfwPlatformGetClipboardString(window); }@@ -586,19 +627,33 @@ GLFWAPI double glfwGetTime(void) {     _GLFW_REQUIRE_INIT_OR_RETURN(0.0);-    return _glfwPlatformGetTime();+    return (double) (_glfwPlatformGetTimerValue() - _glfw.timerOffset) /+        _glfwPlatformGetTimerFrequency(); }  GLFWAPI void glfwSetTime(double time) {     _GLFW_REQUIRE_INIT(); -    if (time != time || time - DBL_MAX == time || time < 0.0)+    if (time != time || time < 0.0 || time > 18446744073.0)     {-        _glfwInputError(GLFW_INVALID_VALUE, "Invalid time");+        _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", time);         return;     } -    _glfwPlatformSetTime(time);+    _glfw.timerOffset = _glfwPlatformGetTimerValue() -+        (uint64_t) (time * _glfwPlatformGetTimerFrequency());+}++GLFWAPI uint64_t glfwGetTimerValue(void)+{+    _GLFW_REQUIRE_INIT_OR_RETURN(0);+    return _glfwPlatformGetTimerValue();+}++GLFWAPI uint64_t glfwGetTimerFrequency(void)+{+    _GLFW_REQUIRE_INIT_OR_RETURN(0);+    return _glfwPlatformGetTimerFrequency(); } 
glfw/src/internal.h view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 - www.glfw.org+// GLFW 3.2 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -25,47 +25,142 @@ // //======================================================================== -#ifndef _internal_h_-#define _internal_h_+#ifndef _glfw3_internal_h_+#define _glfw3_internal_h_   #if defined(_GLFW_USE_CONFIG_H)  #include "glfw_config.h" #endif -#define _GLFW_VERSION_NUMBER "3.1.1"--#if defined(_GLFW_USE_OPENGL)- // This is the default for glfw3.h-#elif defined(_GLFW_USE_GLESV1)- #define GLFW_INCLUDE_ES1-#elif defined(_GLFW_USE_GLESV2)- #define GLFW_INCLUDE_ES2-#else- #error "No supported client library selected"+#if defined(GLFW_INCLUDE_GLCOREARB) || \+    defined(GLFW_INCLUDE_ES1)       || \+    defined(GLFW_INCLUDE_ES2)       || \+    defined(GLFW_INCLUDE_ES3)       || \+    defined(GLFW_INCLUDE_NONE)      || \+    defined(GLFW_INCLUDE_GLEXT)     || \+    defined(GLFW_INCLUDE_GLU)       || \+    defined(GLFW_INCLUDE_VULKAN)    || \+    defined(GLFW_DLL)+ #error "You must not define any header option macros when compiling GLFW" #endif -// Disable the inclusion of the platform glext.h by gl.h to allow proper-// inclusion of our own, newer glext.h below-#define GL_GLEXT_LEGACY-+#define GLFW_INCLUDE_NONE #include "../include/GLFW/glfw3.h" -#if defined(_GLFW_USE_OPENGL)- // This path may need to be changed if you build GLFW using your own setup- // GLFW comes with its own copy of glext.h since it uses fairly new extensions- // and not all development environments come with an up-to-date version- #include "../deps/GL/glext.h"-#endif+typedef int GLFWbool;  typedef struct _GLFWwndconfig   _GLFWwndconfig; typedef struct _GLFWctxconfig   _GLFWctxconfig; typedef struct _GLFWfbconfig    _GLFWfbconfig;+typedef struct _GLFWcontext     _GLFWcontext; typedef struct _GLFWwindow      _GLFWwindow; typedef struct _GLFWlibrary     _GLFWlibrary; typedef struct _GLFWmonitor     _GLFWmonitor; typedef struct _GLFWcursor      _GLFWcursor; +typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);+typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);+typedef void (* _GLFWswapintervalfun)(int);+typedef int (* _GLFWextensionsupportedfun)(const char*);+typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*);+typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);++#define GL_VERSION 0x1f02+#define GL_NONE	0+#define GL_COLOR_BUFFER_BIT	0x00004000+#define GL_EXTENSIONS 0x1f03+#define GL_NUM_EXTENSIONS 0x821d+#define GL_CONTEXT_FLAGS 0x821e+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002+#define GL_CONTEXT_PROFILE_MASK 0x9126+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256+#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252+#define GL_NO_RESET_NOTIFICATION_ARB 0x8261+#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82fb+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc+#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008++typedef int	GLint;+typedef unsigned int GLuint;+typedef unsigned int GLenum;+typedef unsigned int GLbitfield;+typedef unsigned char GLubyte;++typedef void (APIENTRY * PFNGLCLEARPROC)(GLbitfield);+typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);+typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);+typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);++#define VK_NULL_HANDLE 0++typedef void* VkInstance;+typedef void* VkPhysicalDevice;+typedef uint64_t VkSurfaceKHR;+typedef uint32_t VkFlags;+typedef uint32_t VkBool32;++typedef enum VkStructureType+{+    VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,+    VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,+    VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,+    VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,+    VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,+    VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF+} VkStructureType;++typedef enum VkResult+{+    VK_SUCCESS = 0,+    VK_NOT_READY = 1,+    VK_TIMEOUT = 2,+    VK_EVENT_SET = 3,+    VK_EVENT_RESET = 4,+    VK_INCOMPLETE = 5,+    VK_ERROR_OUT_OF_HOST_MEMORY = -1,+    VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,+    VK_ERROR_INITIALIZATION_FAILED = -3,+    VK_ERROR_DEVICE_LOST = -4,+    VK_ERROR_MEMORY_MAP_FAILED = -5,+    VK_ERROR_LAYER_NOT_PRESENT = -6,+    VK_ERROR_EXTENSION_NOT_PRESENT = -7,+    VK_ERROR_FEATURE_NOT_PRESENT = -8,+    VK_ERROR_INCOMPATIBLE_DRIVER = -9,+    VK_ERROR_TOO_MANY_OBJECTS = -10,+    VK_ERROR_FORMAT_NOT_SUPPORTED = -11,+    VK_ERROR_SURFACE_LOST_KHR = -1000000000,+    VK_SUBOPTIMAL_KHR = 1000001003,+    VK_ERROR_OUT_OF_DATE_KHR = -1000001004,+    VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,+    VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,+    VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,+    VK_RESULT_MAX_ENUM = 0x7FFFFFFF+} VkResult;++typedef struct VkAllocationCallbacks VkAllocationCallbacks;++typedef struct VkExtensionProperties+{+    char            extensionName[256];+    uint32_t        specVersion;+} VkExtensionProperties;++typedef void (APIENTRY * PFN_vkVoidFunction)(void);++#if defined(_GLFW_VULKAN_STATIC)+  PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*);+  VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*);+#else+  typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);+  typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);+  #define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties+  #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr+#endif+ #if defined(_GLFW_COCOA)  #include "cocoa_platform.h" #elif defined(_GLFW_WIN32)@@ -103,7 +198,7 @@  *  @brief Various utility functions for internal use.  *  *  These functions are shared code and may be used by any part of GLFW- *  Each platform may add its own utility functions, but those may only be+ *  Each platform may add its own utility functions, but those must only be  *  called by the platform-specific code  */ @@ -112,6 +207,13 @@ // Helper macros //======================================================================== +// Constructs a version number string from the public header macros+#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r+#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)+#define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \+                                                GLFW_VERSION_MINOR, \+                                                GLFW_VERSION_REVISION)+ // Checks for whether the library has been initialized #define _GLFW_REQUIRE_INIT()                         \     if (!_glfwInitialized)                           \@@ -151,16 +253,15 @@     int           width;     int           height;     const char*   title;-    GLboolean     resizable;-    GLboolean     visible;-    GLboolean     decorated;-    GLboolean     focused;-    GLboolean     autoIconify;-    GLboolean     floating;-    _GLFWmonitor* monitor;+    GLFWbool      resizable;+    GLFWbool      visible;+    GLFWbool      decorated;+    GLFWbool      focused;+    GLFWbool      autoIconify;+    GLFWbool      floating;+    GLFWbool      maximized; }; - /*! @brief Context configuration.  *  *  Parameters relating to the creation of the context but not directly related@@ -169,18 +270,19 @@  */ struct _GLFWctxconfig {-    int           api;+    int           client;+    int           source;     int           major;     int           minor;-    GLboolean     forward;-    GLboolean     debug;+    GLFWbool      forward;+    GLFWbool      debug;+    GLFWbool      noerror;     int           profile;     int           robustness;     int           release;     _GLFWwindow*  share; }; - /*! @brief Framebuffer configuration.  *  *  This describes buffers and their sizes.  It also contains@@ -202,16 +304,42 @@     int         accumBlueBits;     int         accumAlphaBits;     int         auxBuffers;-    int         stereo;+    GLFWbool    stereo;     int         samples;-    int         sRGB;-    int         doublebuffer;+    GLFWbool    sRGB;+    GLFWbool    doublebuffer;+    uintptr_t   handle;+}; +/*! @brief Context structure.+ */+struct _GLFWcontext+{+    int                 client;+    int                 source;+    int                 major, minor, revision;+    GLFWbool            forward, debug, noerror;+    int                 profile;+    int                 robustness;+    int                 release;++    PFNGLGETSTRINGIPROC GetStringi;+    PFNGLGETINTEGERVPROC GetIntegerv;+    PFNGLGETSTRINGPROC  GetString;++    _GLFWmakecontextcurrentfun  makeCurrent;+    _GLFWswapbuffersfun         swapBuffers;+    _GLFWswapintervalfun        swapInterval;+    _GLFWextensionsupportedfun  extensionSupported;+    _GLFWgetprocaddressfun      getProcAddress;+    _GLFWdestroycontextfun      destroy;+     // This is defined in the context API's context.h-    _GLFW_PLATFORM_FBCONFIG;+    _GLFW_PLATFORM_CONTEXT_STATE;+    // This is defined in egl_context.h+    _GLFW_EGL_CONTEXT_STATE; }; - /*! @brief Window and context structure.  */ struct _GLFWwindow@@ -219,37 +347,29 @@     struct _GLFWwindow* next;      // Window settings and state-    GLboolean           resizable;-    GLboolean           decorated;-    GLboolean           autoIconify;-    GLboolean           floating;-    GLboolean           closed;+    GLFWbool            resizable;+    GLFWbool            decorated;+    GLFWbool            autoIconify;+    GLFWbool            floating;+    GLFWbool            closed;     void*               userPointer;     GLFWvidmode         videoMode;     _GLFWmonitor*       monitor;     _GLFWcursor*        cursor; -    // Window input state-    GLboolean           stickyKeys;-    GLboolean           stickyMouseButtons;-    double              cursorPosX, cursorPosY;+    int                 minwidth, minheight;+    int                 maxwidth, maxheight;+    int                 numer, denom;++    GLFWbool            stickyKeys;+    GLFWbool            stickyMouseButtons;     int                 cursorMode;     char                mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];     char                keys[GLFW_KEY_LAST + 1];--    // OpenGL extensions and context attributes-    struct {-        int             api;-        int             major, minor, revision;-        GLboolean       forward, debug;-        int             profile;-        int             robustness;-        int             release;-    } context;+    // Virtual cursor position when cursor is disabled+    double              virtualCursorPosX, virtualCursorPosY; -#if defined(_GLFW_USE_OPENGL)-    PFNGLGETSTRINGIPROC GetStringi;-#endif+    _GLFWcontext        context;      struct {         GLFWwindowposfun        pos;@@ -271,11 +391,8 @@      // This is defined in the window API's platform.h     _GLFW_PLATFORM_WINDOW_STATE;-    // This is defined in the context API's context.h-    _GLFW_PLATFORM_CONTEXT_STATE; }; - /*! @brief Monitor structure.  */ struct _GLFWmonitor@@ -285,6 +402,9 @@     // Physical dimensions in millimeters.     int             widthMM, heightMM; +    // The window whose video mode is current on this monitor+    _GLFWwindow*    window;+     GLFWvidmode*    modes;     int             modeCount;     GLFWvidmode     currentMode;@@ -296,7 +416,6 @@     _GLFW_PLATFORM_MONITOR_STATE; }; - /*! @brief Cursor structure  */ struct _GLFWcursor@@ -312,50 +431,41 @@ struct _GLFWlibrary {     struct {-        int         redBits;-        int         greenBits;-        int         blueBits;-        int         alphaBits;-        int         depthBits;-        int         stencilBits;-        int         accumRedBits;-        int         accumGreenBits;-        int         accumBlueBits;-        int         accumAlphaBits;-        int         auxBuffers;-        int         stereo;-        int         resizable;-        int         visible;-        int         decorated;-        int         focused;-        int         autoIconify;-        int         floating;-        int         samples;-        int         sRGB;-        int         refreshRate;-        int         doublebuffer;-        int         api;-        int         major;-        int         minor;-        int         forward;-        int         debug;-        int         profile;-        int         robustness;-        int         release;+        _GLFWfbconfig   framebuffer;+        _GLFWwndconfig  window;+        _GLFWctxconfig  context;+        int             refreshRate;     } hints; -    double          cursorPosX, cursorPosY;+    _GLFWcursor*        cursorListHead; -    _GLFWcursor*    cursorListHead;+    _GLFWwindow*        windowListHead; -    _GLFWwindow*    windowListHead;-    _GLFWwindow*    focusedWindow;+    _GLFWmonitor**      monitors;+    int                 monitorCount; -    _GLFWmonitor**  monitors;-    int             monitorCount;+    uint64_t            timerOffset;      struct {+        GLFWbool        available;+        void*           handle;+        char**          extensions;+        uint32_t        extensionCount;+#if !defined(_GLFW_VULKAN_STATIC)+        PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;+        PFN_vkGetInstanceProcAddr GetInstanceProcAddr;+#endif+        GLFWbool        KHR_surface;+        GLFWbool        KHR_win32_surface;+        GLFWbool        KHR_xlib_surface;+        GLFWbool        KHR_xcb_surface;+        GLFWbool        KHR_wayland_surface;+        GLFWbool        KHR_mir_surface;+    } vk;++    struct {         GLFWmonitorfun  monitor;+        GLFWjoystickfun joystick;     } callbacks;      // This is defined in the window API's platform.h@@ -368,6 +478,8 @@     _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;     // This is defined in the platform's tls.h     _GLFW_PLATFORM_LIBRARY_TLS_STATE;+    // This is defined in egl_context.h+    _GLFW_EGL_LIBRARY_CONTEXT_STATE; };  @@ -377,7 +489,7 @@  /*! @brief Flag indicating whether GLFW has been successfully initialized.  */-extern GLboolean _glfwInitialized;+extern GLFWbool _glfwInitialized;  /*! @brief All global data protected by @ref _glfwInitialized.  *  This should only be touched after a call to @ref glfwInit that has not been@@ -391,7 +503,7 @@ //========================================================================  /*! @brief Initializes the platform-specific part of the library.- *  @return `GL_TRUE` if successful, or `GL_FALSE` if an error occurred.+ *  @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an error occurred.  *  @ingroup platform  */ int _glfwPlatformInit(void);@@ -420,12 +532,17 @@  */ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); -/*! @brief Applies the cursor mode of the specified window to the system.- *  @param[in] window The window whose cursor mode to apply.+/*! @brief Sets the specified cursor mode of the specified window.+ *  @param[in] window The window whose cursor mode to set.  *  @ingroup platform  */-void _glfwPlatformApplyCursorMode(_GLFWwindow* window);+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); +/*! @copydoc glfwGetKeyName+ *  @ingroup platform+ */+const char* _glfwPlatformGetKeyName(int key, int scancode);+ /*! @copydoc glfwGetMonitors  *  @ingroup platform  */@@ -435,11 +552,11 @@  *  *  @param[in] first The first monitor.  *  @param[in] second The second monitor.- *  @return @c GL_TRUE if the monitor objects represent the same monitor, or @c- *  GL_FALSE otherwise.+ *  @return @c GLFW_TRUE if the monitor objects represent the same monitor, or+ *  @c GLFW_FALSE otherwise.  *  @ingroup platform  */-GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second);+GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second);  /*! @copydoc glfwGetMonitorPos  *  @ingroup platform@@ -498,15 +615,15 @@  */ const char* _glfwPlatformGetJoystickName(int joy); -/*! @copydoc glfwGetTime+/*! @copydoc glfwGetTimerValue  *  @ingroup platform  */-double _glfwPlatformGetTime(void);+uint64_t _glfwPlatformGetTimerValue(void); -/*! @copydoc glfwSetTime+/*! @copydoc glfwGetTimerFrequency  *  @ingroup platform  */-void _glfwPlatformSetTime(double time);+uint64_t _glfwPlatformGetTimerFrequency(void);  /*! @ingroup platform  */@@ -524,6 +641,11 @@  */ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title); +/*! @copydoc glfwSetWindowIcon+ *  @ingroup platform+ */+void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, const GLFWimage* images);+ /*! @copydoc glfwGetWindowPos  *  @ingroup platform  */@@ -544,6 +666,16 @@  */ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height); +/*! @copydoc glfwSetWindowSizeLimits+ *  @ingroup platform+ */+void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);++/*! @copydoc glfwSetWindowAspectRatio+ *  @ingroup platform+ */+void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);+ /*! @copydoc glfwGetFramebufferSize  *  @ingroup platform  */@@ -564,20 +696,31 @@  */ void _glfwPlatformRestoreWindow(_GLFWwindow* window); -/*! @copydoc glfwShowWindow+/*! @copydoc glfwMaximizeWindow  *  @ingroup platform  */-void _glfwPlatformShowWindow(_GLFWwindow* window);+void _glfwPlatformMaximizeWindow(_GLFWwindow* window); -/*! @ingroup platform+/*! @copydoc glfwShowWindow+ *  @ingroup platform  */-void _glfwPlatformUnhideWindow(_GLFWwindow* window);+void _glfwPlatformShowWindow(_GLFWwindow* window);  /*! @copydoc glfwHideWindow  *  @ingroup platform  */ void _glfwPlatformHideWindow(_GLFWwindow* window); +/*! @copydoc glfwFocusWindow+ *  @ingroup platform+ */+void _glfwPlatformFocusWindow(_GLFWwindow* window);++/*! @copydoc glfwSetWindowMonitor+ *  @ingroup platform+ */+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);+ /*! @brief Returns whether the window is focused.  *  @ingroup platform  */@@ -593,6 +736,11 @@  */ int _glfwPlatformWindowVisible(_GLFWwindow* window); +/*! @brief Returns whether the window is maximized.+ *  @ingroup platform+ */+int _glfwPlatformWindowMaximized(_GLFWwindow* window);+ /*! @copydoc glfwPollEvents  *  @ingroup platform  */@@ -603,41 +751,25 @@  */ void _glfwPlatformWaitEvents(void); +/*! @copydoc glfwWaitEventsTimeout+ *  @ingroup platform+ */+void _glfwPlatformWaitEventsTimeout(double timeout);+ /*! @copydoc glfwPostEmptyEvent  *  @ingroup platform  */ void _glfwPlatformPostEmptyEvent(void); -/*! @copydoc glfwMakeContextCurrent- *  @ingroup platform+/*! @ingroup platform  */-void _glfwPlatformMakeContextCurrent(_GLFWwindow* window);+void _glfwPlatformSetCurrentContext(_GLFWwindow* context);  /*! @copydoc glfwGetCurrentContext  *  @ingroup platform  */ _GLFWwindow* _glfwPlatformGetCurrentContext(void); -/*! @copydoc glfwSwapBuffers- *  @ingroup platform- */-void _glfwPlatformSwapBuffers(_GLFWwindow* window);--/*! @copydoc glfwSwapInterval- *  @ingroup platform- */-void _glfwPlatformSwapInterval(int interval);--/*! @copydoc glfwExtensionSupported- *  @ingroup platform- */-int _glfwPlatformExtensionSupported(const char* extension);--/*! @copydoc glfwGetProcAddress- *  @ingroup platform- */-GLFWglproc _glfwPlatformGetProcAddress(const char* procname);- /*! @copydoc glfwCreateCursor  *  @ingroup platform  */@@ -658,18 +790,30 @@  */ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); +/*! @ingroup platform+ */+char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count); +/*! @ingroup platform+ */+int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);++/*! @ingroup platform+ */+VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);++ //======================================================================== // Event API functions //========================================================================  /*! @brief Notifies shared code of a window focus event.  *  @param[in] window The window that received the event.- *  @param[in] focused `GL_TRUE` if the window received focus, or `GL_FALSE`+ *  @param[in] focused `GLFW_TRUE` if the window received focus, or `GLFW_FALSE`  *  if it lost focus.  *  @ingroup event  */-void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused);+void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);  /*! @brief Notifies shared code of a window movement event.  *  @param[in] window The window that received the event.@@ -697,11 +841,11 @@  /*! @brief Notifies shared code of a window iconification event.  *  @param[in] window The window that received the event.- *  @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE`- *  if it was restored.+ *  @param[in] iconified `GLFW_TRUE` if the window was iconified, or+ *  `GLFW_FALSE` if it was restored.  *  @ingroup event  */-void _glfwInputWindowIconify(_GLFWwindow* window, int iconified);+void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);  /*! @brief Notifies shared code of a window damage event.  *  @param[in] window The window that received the event.@@ -714,6 +858,8 @@  */ void _glfwInputWindowCloseRequest(_GLFWwindow* window); +void _glfwInputWindowMonitorChange(_GLFWwindow* window, _GLFWmonitor* monitor);+ /*! @brief Notifies shared code of a physical key event.  *  @param[in] window The window that received the event.  *  @param[in] key The key that was pressed or released.@@ -728,19 +874,19 @@  *  @param[in] window The window that received the event.  *  @param[in] codepoint The Unicode code point of the input character.  *  @param[in] mods Bit field describing which modifier keys were held down.- *  @param[in] plain `GL_TRUE` if the character is regular text input, or- *  `GL_FALSE` otherwise.+ *  @param[in] plain `GLFW_TRUE` if the character is regular text input, or+ *  `GLFW_FALSE` otherwise.  *  @ingroup event  */-void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain);+void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain);  /*! @brief Notifies shared code of a scroll event.  *  @param[in] window The window that received the event.- *  @param[in] x The scroll offset along the x-axis.- *  @param[in] y The scroll offset along the y-axis.+ *  @param[in] xoffset The scroll offset along the x-axis.+ *  @param[in] yoffset The scroll offset along the y-axis.  *  @ingroup event  */-void _glfwInputScroll(_GLFWwindow* window, double x, double y);+void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);  /*! @brief Notifies shared code of a mouse button click event.  *  @param[in] window The window that received the event.@@ -752,33 +898,41 @@  /*! @brief Notifies shared code of a cursor motion event.  *  @param[in] window The window that received the event.- *  @param[in] x The new x-coordinate of the cursor, relative to the left edge- *  of the client area of the window.- *  @param[in] y The new y-coordinate of the cursor, relative to the top edge+ *  @param[in] xpos The new x-coordinate of the cursor, relative to the left+ *  edge of the client area of the window.+ *  @param[in] ypos The new y-coordinate of the cursor, relative to the top edge  *  of the client area of the window.  *  @ingroup event  */-void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y);+void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);  /*! @brief Notifies shared code of a cursor enter/leave event.  *  @param[in] window The window that received the event.- *  @param[in] entered `GL_TRUE` if the cursor entered the client area of the- *  window, or `GL_FALSE` if it left it.+ *  @param[in] entered `GLFW_TRUE` if the cursor entered the client area of the+ *  window, or `GLFW_FALSE` if it left it.  *  @ingroup event  */-void _glfwInputCursorEnter(_GLFWwindow* window, int entered);+void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);  /*! @ingroup event  */ void _glfwInputMonitorChange(void); +/*! @ingroup event+ */+void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window);+ /*! @brief Notifies shared code of an error.  *  @param[in] error The error code most suitable for the error.  *  @param[in] format The `printf` style format string of the error  *  description.  *  @ingroup event  */+#if defined(__GNUC__)+void _glfwInputError(int error, const char* format, ...) __attribute__((format(printf, 2, 3)));+#else void _glfwInputError(int error, const char* format, ...);+#endif  /*! @brief Notifies dropped object over window.  *  @param[in] window The window that received the event.@@ -788,7 +942,14 @@  */ void _glfwInputDrop(_GLFWwindow* window, int count, const char** names); +/*! @brief Notifies shared code of a joystick connection/disconnection event.+ *  @param[in] joy The joystick that was connected or disconnected.+ *  @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.+ *  @ingroup event+ */+void _glfwInputJoystickChange(int joy, int event); + //======================================================================== // Utility functions //========================================================================@@ -811,10 +972,10 @@ /*! @brief Searches an extension string for the specified extension.  *  @param[in] string The extension string to search.  *  @param[in] extensions The extension to search for.- *  @return `GL_TRUE` if the extension was found, or `GL_FALSE` otherwise.+ *  @return `GLFW_TRUE` if the extension was found, or `GLFW_FALSE` otherwise.  *  @ingroup utility  */-int _glfwStringInExtensionString(const char* string, const GLubyte* extensions);+GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);  /*! @brief Chooses the framebuffer config that best matches the desired one.  *  @param[in] desired The desired framebuffer config.@@ -830,14 +991,15 @@  /*! @brief Retrieves the attributes of the current context.  *  @param[in] ctxconfig The desired context attributes.- *  @return `GL_TRUE` if successful, or `GL_FALSE` if the context is unusable.+ *  @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if the context is+ *  unusable.  *  @ingroup utility  */-GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig);+GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig);  /*! @brief Checks whether the desired context attributes are valid.  *  @param[in] ctxconfig The context attributes to check.- *  @return `GL_TRUE` if the context attributes are valid, or `GL_FALSE`+ *  @return `GLFW_TRUE` if the context attributes are valid, or `GLFW_FALSE`  *  otherwise.  *  @ingroup utility  *@@ -845,16 +1007,7 @@  *  exists and whether all relevant options have supported and non-conflicting  *  values.  */-GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);--/*! @brief Checks whether the current context fulfils the specified hard- *  constraints.- *  @param[in] ctxconfig The desired context attributes.- *  @return `GL_TRUE` if the context fulfils the hard constraints, or `GL_FALSE`- *  otherwise.- *  @ingroup utility- */-GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig);+GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);  /*! @ingroup utility  */@@ -883,4 +1036,20 @@   */ void _glfwFreeMonitors(_GLFWmonitor** monitors, int count); -#endif // _internal_h_+/*! @ingroup utility+ */+GLFWbool _glfwIsPrintable(int key);++/*! @ingroup utility+ */+GLFWbool _glfwInitVulkan(void);++/*! @ingroup utility+ */+void _glfwTerminateVulkan(void);++/*! @ingroup utility+ */+const char* _glfwGetVulkanResultString(VkResult result);++#endif // _glfw3_internal_h_
− glfw/src/iokit_joystick.h
@@ -1,61 +0,0 @@-//========================================================================-// GLFW 3.1 IOKit - www.glfw.org-//-------------------------------------------------------------------------// Copyright (c) 2006-2014 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.-//-//========================================================================--#ifndef _iokit_joystick_h_-#define _iokit_joystick_h_--#include <IOKit/IOKitLib.h>-#include <IOKit/IOCFPlugIn.h>-#include <IOKit/hid/IOHIDLib.h>-#include <IOKit/hid/IOHIDKeys.h>--#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \-    _GLFWjoystickIOKit iokit_js[GLFW_JOYSTICK_LAST + 1]---// IOKit-specific per-joystick data-//-typedef struct _GLFWjoystickIOKit-{-    int             present;-    char            name[256];--    IOHIDDeviceInterface** interface;--    CFMutableArrayRef axisElements;-    CFMutableArrayRef buttonElements;-    CFMutableArrayRef hatElements;--    float*          axes;-    unsigned char*  buttons;--} _GLFWjoystickIOKit;---void _glfwInitJoysticks(void);-void _glfwTerminateJoysticks(void);--#endif // _iokit_joystick_h_
− glfw/src/iokit_joystick.m
@@ -1,506 +0,0 @@-//========================================================================-// GLFW 3.1 IOKit - 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-// 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 <unistd.h>-#include <ctype.h>--#include <mach/mach.h>-#include <mach/mach_error.h>--#include <CoreFoundation/CoreFoundation.h>-#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>---//-------------------------------------------------------------------------// Joystick element information-//-------------------------------------------------------------------------typedef struct-{-    IOHIDElementCookie cookie;--    long min;-    long max;--    long minReport;-    long maxReport;--} _GLFWjoyelement;---static void getElementsCFArrayHandler(const void* value, void* parameter);---// Adds an element to the specified joystick-//-static void addJoystickElement(_GLFWjoystickIOKit* joystick, CFTypeRef elementRef)-{-    long elementType, usagePage, usage;-    CFMutableArrayRef elementsArray = NULL;--    CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementTypeKey)),-                     kCFNumberLongType, &elementType);-    CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementUsagePageKey)),-                     kCFNumberLongType, &usagePage);-    CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementUsageKey)),-                     kCFNumberLongType, &usage);--    if ((elementType == kIOHIDElementTypeInput_Axis) ||-        (elementType == kIOHIDElementTypeInput_Button) ||-        (elementType == kIOHIDElementTypeInput_Misc))-    {-        switch (usagePage)-        {-            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:-                        elementsArray = joystick->axisElements;-                        break;-                    case kHIDUsage_GD_Hatswitch:-                        elementsArray = joystick->hatElements;-                        break;-                }--                break;-            }--            case kHIDPage_Button:-                elementsArray = joystick->buttonElements;-                break;-            default:-                break;-        }--        if (elementsArray)-        {-            long number;-            CFTypeRef numberRef;-            _GLFWjoyelement* element = calloc(1, sizeof(_GLFWjoyelement));--            CFArrayAppendValue(elementsArray, element);--            numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementCookieKey));-            if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number))-                element->cookie = (IOHIDElementCookie) number;--            numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementMinKey));-            if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number))-                element->minReport = element->min = number;--            numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementMaxKey));-            if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number))-                element->maxReport = element->max = number;-        }-    }-    else-    {-        CFTypeRef array = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementKey));-        if (array)-        {-            if (CFGetTypeID(array) == CFArrayGetTypeID())-            {-                CFRange range = { 0, CFArrayGetCount(array) };-                CFArrayApplyFunction(array, range, getElementsCFArrayHandler, joystick);-            }-        }-    }-}--// Adds an element to the specified joystick-//-static void getElementsCFArrayHandler(const void* value, void* parameter)-{-    if (CFGetTypeID(value) == CFDictionaryGetTypeID())-        addJoystickElement((_GLFWjoystickIOKit*) parameter, (CFTypeRef) value);-}--// Returns the value of the specified element of the specified joystick-//-static long getElementValue(_GLFWjoystickIOKit* joystick, _GLFWjoyelement* 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(_GLFWjoystickIOKit* joystick)-{-    int i;--    if (!joystick->present)-        return;--    for (i = 0;  i < CFArrayGetCount(joystick->axisElements);  i++)-        free((void*) CFArrayGetValueAtIndex(joystick->axisElements, i));-    CFArrayRemoveAllValues(joystick->axisElements);--    for (i = 0;  i < CFArrayGetCount(joystick->buttonElements);  i++)-        free((void*) CFArrayGetValueAtIndex(joystick->buttonElements, i));-    CFArrayRemoveAllValues(joystick->buttonElements);--    for (i = 0;  i < CFArrayGetCount(joystick->hatElements);  i++)-        free((void*) CFArrayGetValueAtIndex(joystick->hatElements, i));-    CFArrayRemoveAllValues(joystick->hatElements);--    free(joystick->axes);-    free(joystick->buttons);--    (*(joystick->interface))->close(joystick->interface);-    (*(joystick->interface))->Release(joystick->interface);--    memset(joystick, 0, sizeof(_GLFWjoystickIOKit));-}--// Callback for user-initiated joystick removal-//-static void removalCallback(void* target, IOReturn result, void* refcon, void* sender)-{-    removeJoystick((_GLFWjoystickIOKit*) refcon);-}--// Polls for joystick events and updates GLFW state-//-static void pollJoystickEvents(void)-{-    int joy;--    for (joy = 0;  joy <= GLFW_JOYSTICK_LAST;  joy++)-    {-        CFIndex i;-        int buttonIndex = 0;-        _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy;--        if (!joystick->present)-            continue;--        for (i = 0;  i < CFArrayGetCount(joystick->buttonElements);  i++)-        {-            _GLFWjoyelement* button =-                (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->buttonElements, i);--            if (getElementValue(joystick, button))-                joystick->buttons[buttonIndex++] = GLFW_PRESS;-            else-                joystick->buttons[buttonIndex++] = GLFW_RELEASE;-        }--        for (i = 0;  i < CFArrayGetCount(joystick->axisElements);  i++)-        {-            _GLFWjoyelement* axis =-                (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->axisElements, i);--            long value = getElementValue(joystick, axis);-            long readScale = axis->maxReport - axis->minReport;--            if (readScale == 0)-                joystick->axes[i] = value;-            else-                joystick->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f;-        }--        for (i = 0;  i < CFArrayGetCount(joystick->hatElements);  i++)-        {-            _GLFWjoyelement* hat =-                (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->hatElements, i);--            // Bit fields of button presses for each direction, including nil-            const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };--            long j, value = getElementValue(joystick, hat);-            if (value < 0 || value > 8)-                value = 8;--            for (j = 0;  j < 4;  j++)-            {-                if (directions[value] & (1 << j))-                    joystick->buttons[buttonIndex++] = GLFW_PRESS;-                else-                    joystick->buttons[buttonIndex++] = GLFW_RELEASE;-            }-        }-    }-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW internal API                      //////-//////////////////////////////////////////////////////////////////////////--// Initialize joystick interface-//-void _glfwInitJoysticks(void)-{-    int joy = 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 propsRef = NULL;-        CFTypeRef valueRef = NULL;-        kern_return_t result;--        IOCFPlugInInterface** ppPlugInInterface = NULL;-        HRESULT plugInResult = S_OK;-        SInt32 score = 0;--        long usagePage = 0;-        long usage = 0;--        valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,-                                                   CFSTR(kIOHIDPrimaryUsagePageKey),-                                                   kCFAllocatorDefault, kNilOptions);-        if (valueRef)-        {-            CFNumberGetValue(valueRef, kCFNumberLongType, &usagePage);-            CFRelease(valueRef);-        }--        valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,-                                                   CFSTR(kIOHIDPrimaryUsageKey),-                                                   kCFAllocatorDefault, kNilOptions);-        if (valueRef)-        {-            CFNumberGetValue(valueRef, kCFNumberLongType, &usage);-            CFRelease(valueRef);-        }--        if (usagePage != kHIDPage_GenericDesktop)-        {-            // This device is not relevant to GLFW-            continue;-        }--        if ((usage != kHIDUsage_GD_Joystick &&-             usage != kHIDUsage_GD_GamePad &&-             usage != kHIDUsage_GD_MultiAxisController))-        {-            // This device is not relevant to GLFW-            continue;-        }-        -        result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject,-                                                   &propsRef,-                                                   kCFAllocatorDefault,-                                                   kNilOptions);-        -        if (result != kIOReturnSuccess)-            continue;--        _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy;-        joystick->present = GL_TRUE;--        result = IOCreatePlugInInterfaceForService(ioHIDDeviceObject,-                                                   kIOHIDDeviceUserClientTypeID,-                                                   kIOCFPlugInInterfaceID,-                                                   &ppPlugInInterface,-                                                   &score);--        if (kIOReturnSuccess != result)-        {-            CFRelease(propsRef);-            return;-        }--        plugInResult = (*ppPlugInInterface)->QueryInterface(-                            ppPlugInInterface,-                            CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),-                            (void *) &(joystick->interface));--        if (plugInResult != S_OK)-        {-            CFRelease(propsRef);-            return;-        }--        (*ppPlugInInterface)->Release(ppPlugInInterface);--        (*(joystick->interface))->open(joystick->interface, 0);-        (*(joystick->interface))->setRemovalCallback(joystick->interface,-                                                     removalCallback,-                                                     joystick,-                                                     joystick);--        // Get product string-        valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDProductKey));-        if (valueRef)-        {-            CFStringGetCString(valueRef,-                               joystick->name,-                               sizeof(joystick->name),-                               kCFStringEncodingUTF8);-        }--        joystick->axisElements = CFArrayCreateMutable(NULL, 0, NULL);-        joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL);-        joystick->hatElements = CFArrayCreateMutable(NULL, 0, NULL);--        valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDElementKey));-        if (CFGetTypeID(valueRef) == CFArrayGetTypeID())-        {-            CFRange range = { 0, CFArrayGetCount(valueRef) };-            CFArrayApplyFunction(valueRef,-                                 range,-                                 getElementsCFArrayHandler,-                                 (void*) joystick);-        }--        CFRelease(propsRef);--        joystick->axes = calloc(CFArrayGetCount(joystick->axisElements),-                                         sizeof(float));-        joystick->buttons = calloc(CFArrayGetCount(joystick->buttonElements) +-                                   CFArrayGetCount(joystick->hatElements) * 4, 1);--        joy++;-        if (joy > GLFW_JOYSTICK_LAST)-            break;-    }-}--// Close all opened joystick handles-//-void _glfwTerminateJoysticks(void)-{-    int i;--    for (i = 0;  i < GLFW_JOYSTICK_LAST + 1;  i++)-    {-        _GLFWjoystickIOKit* joystick = &_glfw.iokit_js[i];-        removeJoystick(joystick);--        if (joystick->axisElements)-            CFRelease(joystick->axisElements);-        if (joystick->buttonElements)-            CFRelease(joystick->buttonElements);-        if (joystick->hatElements)-            CFRelease(joystick->hatElements);-    }-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////--int _glfwPlatformJoystickPresent(int joy)-{-    pollJoystickEvents();--    return _glfw.iokit_js[joy].present;-}--const float* _glfwPlatformGetJoystickAxes(int joy, int* count)-{-    _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy;--    pollJoystickEvents();--    if (!joystick->present)-        return NULL;--    *count = (int) CFArrayGetCount(joystick->axisElements);-    return joystick->axes;-}--const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)-{-    _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy;--    pollJoystickEvents();--    if (!joystick->present)-        return NULL;--    *count = (int) CFArrayGetCount(joystick->buttonElements) +-             (int) CFArrayGetCount(joystick->hatElements) * 4;-    return joystick->buttons;-}--const char* _glfwPlatformGetJoystickName(int joy)-{-    pollJoystickEvents();--    return _glfw.iokit_js[joy].name;-}-
glfw/src/linux_joystick.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 Linux - www.glfw.org+// GLFW 3.2 Linux - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -45,12 +45,13 @@  // Attempt to open the specified joystick device //-static void openJoystickDevice(const char* path)-{ #if defined(__linux__)+static GLFWbool openJoystickDevice(const char* path)+{     char axisCount, buttonCount;-    char name[256];+    char name[256] = "";     int joy, fd, version;+    _GLFWjoystickLinux* js;      for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)     {@@ -58,7 +59,7 @@             continue;          if (strcmp(_glfw.linux_js.js[joy].path, path) == 0)-            return;+            return GLFW_FALSE;     }      for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)@@ -68,13 +69,11 @@     }      if (joy > GLFW_JOYSTICK_LAST)-        return;+        return GLFW_FALSE;      fd = open(path, O_RDONLY | O_NONBLOCK);     if (fd == -1)-        return;--    _glfw.linux_js.js[joy].fd = fd;+        return GLFW_FALSE;      // Verify that the joystick driver version is at least 1.0     ioctl(fd, JSIOCGVERSION, &version);@@ -82,116 +81,102 @@     {         // It's an old 0.x interface (we don't support it)         close(fd);-        return;+        return GLFW_FALSE;     }      if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0)         strncpy(name, "Unknown", sizeof(name)); -    _glfw.linux_js.js[joy].name = strdup(name);-    _glfw.linux_js.js[joy].path = strdup(path);+    js = _glfw.linux_js.js + joy;+    js->present = GLFW_TRUE;+    js->name = strdup(name);+    js->path = strdup(path);+    js->fd = fd;      ioctl(fd, JSIOCGAXES, &axisCount);-    _glfw.linux_js.js[joy].axisCount = (int) axisCount;+    js->axisCount = (int) axisCount;+    js->axes = calloc(axisCount, sizeof(float));      ioctl(fd, JSIOCGBUTTONS, &buttonCount);-    _glfw.linux_js.js[joy].buttonCount = (int) buttonCount;--    _glfw.linux_js.js[joy].axes = calloc(axisCount, sizeof(float));-    _glfw.linux_js.js[joy].buttons = calloc(buttonCount, 1);+    js->buttonCount = (int) buttonCount;+    js->buttons = calloc(buttonCount, 1); -    _glfw.linux_js.js[joy].present = GL_TRUE;-#endif // __linux__+    _glfwInputJoystickChange(joy, GLFW_CONNECTED);+    return GLFW_TRUE; }+#endif // __linux__ -// Polls for and processes events for all present joysticks+// Polls for and processes events the specified joystick //-static void pollJoystickEvents(void)+static GLFWbool pollJoystickEvents(_GLFWjoystickLinux* js) { #if defined(__linux__)-    int i;-    struct js_event e;-    ssize_t offset = 0;-    char buffer[16384];--    const ssize_t size = read(_glfw.linux_js.inotify, buffer, sizeof(buffer));--    while (size > offset)-    {-        regmatch_t match;-        const struct inotify_event* e = (struct inotify_event*) (buffer + offset);--        if (regexec(&_glfw.linux_js.regex, e->name, 1, &match, 0) == 0)-        {-            char path[20];-            snprintf(path, sizeof(path), "/dev/input/%s", e->name);-            openJoystickDevice(path);-        }+    _glfwPollJoystickEvents(); -        offset += sizeof(struct inotify_event) + e->len;-    }+    if (!js->present)+        return GLFW_FALSE; -    for (i = 0;  i <= GLFW_JOYSTICK_LAST;  i++)+    // Read all queued events (non-blocking)+    for (;;)     {-        if (!_glfw.linux_js.js[i].present)-            continue;+        struct js_event e; -        // Read all queued events (non-blocking)-        for (;;)+        errno = 0;+        if (read(js->fd, &e, sizeof(e)) < 0)         {-            errno = 0;-            if (read(_glfw.linux_js.js[i].fd, &e, sizeof(e)) < 0)+            // Reset the joystick slot if the device was disconnected+            if (errno == ENODEV)             {-                if (errno == ENODEV)-                {-                    // The joystick was disconnected--                    free(_glfw.linux_js.js[i].axes);-                    free(_glfw.linux_js.js[i].buttons);-                    free(_glfw.linux_js.js[i].name);-                    free(_glfw.linux_js.js[i].path);+                free(js->axes);+                free(js->buttons);+                free(js->name);+                free(js->path); -                    memset(&_glfw.linux_js.js[i], 0, sizeof(_glfw.linux_js.js[i]));-                }+                memset(js, 0, sizeof(_GLFWjoystickLinux)); -                break;+                _glfwInputJoystickChange(js - _glfw.linux_js.js,+                                         GLFW_DISCONNECTED);             } -            // We don't care if it's an init event or not-            e.type &= ~JS_EVENT_INIT;--            switch (e.type)-            {-                case JS_EVENT_AXIS:-                    _glfw.linux_js.js[i].axes[e.number] =-                        (float) e.value / 32767.0f;-                    break;+            break;+        } -                case JS_EVENT_BUTTON:-                    _glfw.linux_js.js[i].buttons[e.number] =-                        e.value ? GLFW_PRESS : GLFW_RELEASE;-                    break;+        // Clear the initial-state bit+        e.type &= ~JS_EVENT_INIT; -                default:-                    break;-            }-        }+        if (e.type == JS_EVENT_AXIS)+            js->axes[e.number] = (float) e.value / 32767.0f;+        else if (e.type == JS_EVENT_BUTTON)+            js->buttons[e.number] = e.value ? GLFW_PRESS : GLFW_RELEASE;     } #endif // __linux__+    return js->present; } +// Lexically compare joysticks by name; used by qsort+//+#if defined(__linux__)+static int compareJoysticks(const void* fp, const void* sp)+{+    const _GLFWjoystickLinux* fj = fp;+    const _GLFWjoystickLinux* sj = sp;+    return strcmp(fj->path, sj->path);+}+#endif // __linux__ + ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////  // Initialize joystick interface //-int _glfwInitJoysticks(void)+GLFWbool _glfwInitJoysticksLinux(void) { #if defined(__linux__)-    const char* dirname = "/dev/input";     DIR* dir;+    int count = 0;+    const char* dirname = "/dev/input";      _glfw.linux_js.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);     if (_glfw.linux_js.inotify == -1)@@ -199,7 +184,7 @@         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Linux: Failed to initialize inotify: %s",                         strerror(errno));-        return GL_FALSE;+        return GLFW_FALSE;     }      // HACK: Register for IN_ATTRIB as well to get notified when udev is done@@ -220,7 +205,7 @@     if (regcomp(&_glfw.linux_js.regex, "^js[0-9]\\+$", 0) != 0)     {         _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");-        return GL_FALSE;+        return GLFW_FALSE;     }      dir = opendir(dirname);@@ -237,7 +222,8 @@                 continue;              snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);-            openJoystickDevice(path);+            if (openJoystickDevice(path))+                count++;         }          closedir(dir);@@ -251,14 +237,15 @@         // Continue with no joysticks detected     } +    qsort(_glfw.linux_js.js, count, sizeof(_GLFWjoystickLinux), compareJoysticks); #endif // __linux__ -    return GL_TRUE;+    return GLFW_TRUE; }  // Close all opened joystick handles //-void _glfwTerminateJoysticks(void)+void _glfwTerminateJoysticksLinux(void) { #if defined(__linux__)     int i;@@ -287,38 +274,68 @@ #endif // __linux__ } +void _glfwPollJoystickEvents(void)+{+#if defined(__linux__)+    ssize_t offset = 0;+    char buffer[16384]; +    const ssize_t size = read(_glfw.linux_js.inotify, buffer, sizeof(buffer));++    while (size > offset)+    {+        regmatch_t match;+        const struct inotify_event* e = (struct inotify_event*) (buffer + offset);++        if (regexec(&_glfw.linux_js.regex, e->name, 1, &match, 0) == 0)+        {+            char path[20];+            snprintf(path, sizeof(path), "/dev/input/%s", e->name);+            openJoystickDevice(path);+        }++        offset += sizeof(struct inotify_event) + e->len;+    }+#endif+}++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW platform API                      ////// //////////////////////////////////////////////////////////////////////////  int _glfwPlatformJoystickPresent(int joy) {-    pollJoystickEvents();--    return _glfw.linux_js.js[joy].present;+    _GLFWjoystickLinux* js = _glfw.linux_js.js + joy;+    return pollJoystickEvents(js); }  const float* _glfwPlatformGetJoystickAxes(int joy, int* count) {-    pollJoystickEvents();+    _GLFWjoystickLinux* js = _glfw.linux_js.js + joy;+    if (!pollJoystickEvents(js))+        return NULL; -    *count = _glfw.linux_js.js[joy].axisCount;-    return _glfw.linux_js.js[joy].axes;+    *count = js->axisCount;+    return js->axes; }  const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) {-    pollJoystickEvents();+    _GLFWjoystickLinux* js = _glfw.linux_js.js + joy;+    if (!pollJoystickEvents(js))+        return NULL; -    *count = _glfw.linux_js.js[joy].buttonCount;-    return _glfw.linux_js.js[joy].buttons;+    *count = js->buttonCount;+    return js->buttons; }  const char* _glfwPlatformGetJoystickName(int joy) {-    pollJoystickEvents();+    _GLFWjoystickLinux* js = _glfw.linux_js.js + joy;+    if (!pollJoystickEvents(js))+        return NULL; -    return _glfw.linux_js.js[joy].name;+    return js->name; } 
glfw/src/linux_joystick.h view
@@ -1,5 +1,5 @@ //========================================================================-// GLFW 3.1 Linux - www.glfw.org+// GLFW 3.2 Linux - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> //@@ -24,40 +24,45 @@ // //======================================================================== -#ifndef _linux_joystick_h_-#define _linux_joystick_h_+#ifndef _glfw3_linux_joystick_h_+#define _glfw3_linux_joystick_h_  #include <regex.h> -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \-    _GLFWjoystickLinux linux_js+#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWjoylistLinux linux_js  -// Linux-specific joystick API data+// Linux-specific joystick data // typedef struct _GLFWjoystickLinux {-    struct-    {-        int             present;-        int             fd;-        float*          axes;-        int             axisCount;-        unsigned char*  buttons;-        int             buttonCount;-        char*           name;-        char*           path;-    } js[GLFW_JOYSTICK_LAST + 1];+    GLFWbool        present;+    int             fd;+    float*          axes;+    int             axisCount;+    unsigned char*  buttons;+    int             buttonCount;+    char*           name;+    char*           path;+} _GLFWjoystickLinux; +// Linux-specific joystick API data+//+typedef struct _GLFWjoylistLinux+{+    _GLFWjoystickLinux js[GLFW_JOYSTICK_LAST + 1];+ #if defined(__linux__)     int             inotify;     int             watch;     regex_t         regex; #endif /*__linux__*/-} _GLFWjoystickLinux;+} _GLFWjoylistLinux;  -int _glfwInitJoysticks(void);-void _glfwTerminateJoysticks(void);+GLFWbool _glfwInitJoysticksLinux(void);+void _glfwTerminateJoysticksLinux(void); -#endif // _linux_joystick_h_+void _glfwPollJoystickEvents(void);++#endif // _glfw3_linux_joystick_h_
− glfw/src/mach_time.c
@@ -1,71 +0,0 @@-//========================================================================-// GLFW 3.1 OS X - www.glfw.org-//-------------------------------------------------------------------------// Copyright (c) 2009-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 <mach/mach_time.h>---// Return raw time-//-static uint64_t getRawTime(void)-{-    return mach_absolute_time();-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW internal API                      //////-//////////////////////////////////////////////////////////////////////////--// Initialise timer-//-void _glfwInitTimer(void)-{-    mach_timebase_info_data_t info;-    mach_timebase_info(&info);--    _glfw.ns_time.resolution = (double) info.numer / (info.denom * 1.0e9);-    _glfw.ns_time.base = getRawTime();-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////--double _glfwPlatformGetTime(void)-{-    return (double) (getRawTime() - _glfw.ns_time.base) *-        _glfw.ns_time.resolution;-}--void _glfwPlatformSetTime(double time)-{-    _glfw.ns_time.base = getRawTime() --        (uint64_t) (time / _glfw.ns_time.resolution);-}-
glfw/src/mir_init.c view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 Mir - www.glfw.org+// GLFW 3.2 Mir - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2014 Brandon Schaefer <brandon.schaefer@canonical.com>+// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -26,10 +26,136 @@  #include "internal.h" +#include <linux/input.h> #include <stdlib.h> #include <string.h>  +// Create key code translation tables+//+static void createKeyTables(void)+{+    memset(_glfw.mir.publicKeys, -1, sizeof(_glfw.mir.publicKeys));++    _glfw.mir.publicKeys[KEY_GRAVE]      = GLFW_KEY_GRAVE_ACCENT;+    _glfw.mir.publicKeys[KEY_1]          = GLFW_KEY_1;+    _glfw.mir.publicKeys[KEY_2]          = GLFW_KEY_2;+    _glfw.mir.publicKeys[KEY_3]          = GLFW_KEY_3;+    _glfw.mir.publicKeys[KEY_4]          = GLFW_KEY_4;+    _glfw.mir.publicKeys[KEY_5]          = GLFW_KEY_5;+    _glfw.mir.publicKeys[KEY_6]          = GLFW_KEY_6;+    _glfw.mir.publicKeys[KEY_7]          = GLFW_KEY_7;+    _glfw.mir.publicKeys[KEY_8]          = GLFW_KEY_8;+    _glfw.mir.publicKeys[KEY_9]          = GLFW_KEY_9;+    _glfw.mir.publicKeys[KEY_0]          = GLFW_KEY_0;+    _glfw.mir.publicKeys[KEY_MINUS]      = GLFW_KEY_MINUS;+    _glfw.mir.publicKeys[KEY_EQUAL]      = GLFW_KEY_EQUAL;+    _glfw.mir.publicKeys[KEY_Q]          = GLFW_KEY_Q;+    _glfw.mir.publicKeys[KEY_W]          = GLFW_KEY_W;+    _glfw.mir.publicKeys[KEY_E]          = GLFW_KEY_E;+    _glfw.mir.publicKeys[KEY_R]          = GLFW_KEY_R;+    _glfw.mir.publicKeys[KEY_T]          = GLFW_KEY_T;+    _glfw.mir.publicKeys[KEY_Y]          = GLFW_KEY_Y;+    _glfw.mir.publicKeys[KEY_U]          = GLFW_KEY_U;+    _glfw.mir.publicKeys[KEY_I]          = GLFW_KEY_I;+    _glfw.mir.publicKeys[KEY_O]          = GLFW_KEY_O;+    _glfw.mir.publicKeys[KEY_P]          = GLFW_KEY_P;+    _glfw.mir.publicKeys[KEY_LEFTBRACE]  = GLFW_KEY_LEFT_BRACKET;+    _glfw.mir.publicKeys[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;+    _glfw.mir.publicKeys[KEY_A]          = GLFW_KEY_A;+    _glfw.mir.publicKeys[KEY_S]          = GLFW_KEY_S;+    _glfw.mir.publicKeys[KEY_D]          = GLFW_KEY_D;+    _glfw.mir.publicKeys[KEY_F]          = GLFW_KEY_F;+    _glfw.mir.publicKeys[KEY_G]          = GLFW_KEY_G;+    _glfw.mir.publicKeys[KEY_H]          = GLFW_KEY_H;+    _glfw.mir.publicKeys[KEY_J]          = GLFW_KEY_J;+    _glfw.mir.publicKeys[KEY_K]          = GLFW_KEY_K;+    _glfw.mir.publicKeys[KEY_L]          = GLFW_KEY_L;+    _glfw.mir.publicKeys[KEY_SEMICOLON]  = GLFW_KEY_SEMICOLON;+    _glfw.mir.publicKeys[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;+    _glfw.mir.publicKeys[KEY_Z]          = GLFW_KEY_Z;+    _glfw.mir.publicKeys[KEY_X]          = GLFW_KEY_X;+    _glfw.mir.publicKeys[KEY_C]          = GLFW_KEY_C;+    _glfw.mir.publicKeys[KEY_V]          = GLFW_KEY_V;+    _glfw.mir.publicKeys[KEY_B]          = GLFW_KEY_B;+    _glfw.mir.publicKeys[KEY_N]          = GLFW_KEY_N;+    _glfw.mir.publicKeys[KEY_M]          = GLFW_KEY_M;+    _glfw.mir.publicKeys[KEY_COMMA]      = GLFW_KEY_COMMA;+    _glfw.mir.publicKeys[KEY_DOT]        = GLFW_KEY_PERIOD;+    _glfw.mir.publicKeys[KEY_SLASH]      = GLFW_KEY_SLASH;+    _glfw.mir.publicKeys[KEY_BACKSLASH]  = GLFW_KEY_BACKSLASH;+    _glfw.mir.publicKeys[KEY_ESC]        = GLFW_KEY_ESCAPE;+    _glfw.mir.publicKeys[KEY_TAB]        = GLFW_KEY_TAB;+    _glfw.mir.publicKeys[KEY_LEFTSHIFT]  = GLFW_KEY_LEFT_SHIFT;+    _glfw.mir.publicKeys[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;+    _glfw.mir.publicKeys[KEY_LEFTCTRL]   = GLFW_KEY_LEFT_CONTROL;+    _glfw.mir.publicKeys[KEY_RIGHTCTRL]  = GLFW_KEY_RIGHT_CONTROL;+    _glfw.mir.publicKeys[KEY_LEFTALT]    = GLFW_KEY_LEFT_ALT;+    _glfw.mir.publicKeys[KEY_RIGHTALT]   = GLFW_KEY_RIGHT_ALT;+    _glfw.mir.publicKeys[KEY_LEFTMETA]   = GLFW_KEY_LEFT_SUPER;+    _glfw.mir.publicKeys[KEY_RIGHTMETA]  = GLFW_KEY_RIGHT_SUPER;+    _glfw.mir.publicKeys[KEY_MENU]       = GLFW_KEY_MENU;+    _glfw.mir.publicKeys[KEY_NUMLOCK]    = GLFW_KEY_NUM_LOCK;+    _glfw.mir.publicKeys[KEY_CAPSLOCK]   = GLFW_KEY_CAPS_LOCK;+    _glfw.mir.publicKeys[KEY_PRINT]      = GLFW_KEY_PRINT_SCREEN;+    _glfw.mir.publicKeys[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;+    _glfw.mir.publicKeys[KEY_PAUSE]      = GLFW_KEY_PAUSE;+    _glfw.mir.publicKeys[KEY_DELETE]     = GLFW_KEY_DELETE;+    _glfw.mir.publicKeys[KEY_BACKSPACE]  = GLFW_KEY_BACKSPACE;+    _glfw.mir.publicKeys[KEY_ENTER]      = GLFW_KEY_ENTER;+    _glfw.mir.publicKeys[KEY_HOME]       = GLFW_KEY_HOME;+    _glfw.mir.publicKeys[KEY_END]        = GLFW_KEY_END;+    _glfw.mir.publicKeys[KEY_PAGEUP]     = GLFW_KEY_PAGE_UP;+    _glfw.mir.publicKeys[KEY_PAGEDOWN]   = GLFW_KEY_PAGE_DOWN;+    _glfw.mir.publicKeys[KEY_INSERT]     = GLFW_KEY_INSERT;+    _glfw.mir.publicKeys[KEY_LEFT]       = GLFW_KEY_LEFT;+    _glfw.mir.publicKeys[KEY_RIGHT]      = GLFW_KEY_RIGHT;+    _glfw.mir.publicKeys[KEY_DOWN]       = GLFW_KEY_DOWN;+    _glfw.mir.publicKeys[KEY_UP]         = GLFW_KEY_UP;+    _glfw.mir.publicKeys[KEY_F1]         = GLFW_KEY_F1;+    _glfw.mir.publicKeys[KEY_F2]         = GLFW_KEY_F2;+    _glfw.mir.publicKeys[KEY_F3]         = GLFW_KEY_F3;+    _glfw.mir.publicKeys[KEY_F4]         = GLFW_KEY_F4;+    _glfw.mir.publicKeys[KEY_F5]         = GLFW_KEY_F5;+    _glfw.mir.publicKeys[KEY_F6]         = GLFW_KEY_F6;+    _glfw.mir.publicKeys[KEY_F7]         = GLFW_KEY_F7;+    _glfw.mir.publicKeys[KEY_F8]         = GLFW_KEY_F8;+    _glfw.mir.publicKeys[KEY_F9]         = GLFW_KEY_F9;+    _glfw.mir.publicKeys[KEY_F10]        = GLFW_KEY_F10;+    _glfw.mir.publicKeys[KEY_F11]        = GLFW_KEY_F11;+    _glfw.mir.publicKeys[KEY_F12]        = GLFW_KEY_F12;+    _glfw.mir.publicKeys[KEY_F13]        = GLFW_KEY_F13;+    _glfw.mir.publicKeys[KEY_F14]        = GLFW_KEY_F14;+    _glfw.mir.publicKeys[KEY_F15]        = GLFW_KEY_F15;+    _glfw.mir.publicKeys[KEY_F16]        = GLFW_KEY_F16;+    _glfw.mir.publicKeys[KEY_F17]        = GLFW_KEY_F17;+    _glfw.mir.publicKeys[KEY_F18]        = GLFW_KEY_F18;+    _glfw.mir.publicKeys[KEY_F19]        = GLFW_KEY_F19;+    _glfw.mir.publicKeys[KEY_F20]        = GLFW_KEY_F20;+    _glfw.mir.publicKeys[KEY_F21]        = GLFW_KEY_F21;+    _glfw.mir.publicKeys[KEY_F22]        = GLFW_KEY_F22;+    _glfw.mir.publicKeys[KEY_F23]        = GLFW_KEY_F23;+    _glfw.mir.publicKeys[KEY_F24]        = GLFW_KEY_F24;+    _glfw.mir.publicKeys[KEY_KPSLASH]    = GLFW_KEY_KP_DIVIDE;+    _glfw.mir.publicKeys[KEY_KPDOT]      = GLFW_KEY_KP_MULTIPLY;+    _glfw.mir.publicKeys[KEY_KPMINUS]    = GLFW_KEY_KP_SUBTRACT;+    _glfw.mir.publicKeys[KEY_KPPLUS]     = GLFW_KEY_KP_ADD;+    _glfw.mir.publicKeys[KEY_KP0]        = GLFW_KEY_KP_0;+    _glfw.mir.publicKeys[KEY_KP1]        = GLFW_KEY_KP_1;+    _glfw.mir.publicKeys[KEY_KP2]        = GLFW_KEY_KP_2;+    _glfw.mir.publicKeys[KEY_KP3]        = GLFW_KEY_KP_3;+    _glfw.mir.publicKeys[KEY_KP4]        = GLFW_KEY_KP_4;+    _glfw.mir.publicKeys[KEY_KP5]        = GLFW_KEY_KP_5;+    _glfw.mir.publicKeys[KEY_KP6]        = GLFW_KEY_KP_6;+    _glfw.mir.publicKeys[KEY_KP7]        = GLFW_KEY_KP_7;+    _glfw.mir.publicKeys[KEY_KP8]        = GLFW_KEY_KP_8;+    _glfw.mir.publicKeys[KEY_KP9]        = GLFW_KEY_KP_9;+    _glfw.mir.publicKeys[KEY_KPCOMMA]    = GLFW_KEY_KP_DECIMAL;+    _glfw.mir.publicKeys[KEY_KPEQUAL]    = GLFW_KEY_KP_EQUAL;+    _glfw.mir.publicKeys[KEY_KPENTER]    = GLFW_KEY_KP_ENTER;+}++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////@@ -46,39 +172,47 @@                         "Mir: Unable to connect to server: %s",                         mir_connection_get_error_message(_glfw.mir.connection)); -        return GL_FALSE;+        return GLFW_FALSE;     }      _glfw.mir.display =         mir_connection_get_egl_native_display(_glfw.mir.connection); -    if (!_glfwInitContextAPI())-        return GL_FALSE;+    createKeyTables(); -    _glfwInitTimer();-    _glfwInitJoysticks();+    if (!_glfwInitThreadLocalStoragePOSIX())+        return GLFW_FALSE; +    if (!_glfwInitJoysticksLinux())+        return GLFW_FALSE;++    _glfwInitTimerPOSIX();++    // Need the default conf for when we set a NULL cursor+    _glfw.mir.default_conf = mir_cursor_configuration_from_name(mir_arrow_cursor_name);+     _glfw.mir.event_queue = calloc(1, sizeof(EventQueue));-    _glfwInitEventQueue(_glfw.mir.event_queue);+    _glfwInitEventQueueMir(_glfw.mir.event_queue);      error = pthread_mutex_init(&_glfw.mir.event_mutex, NULL);     if (error)     {         _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Mir: Failed to create event mutex: %s\n",+                        "Mir: Failed to create event mutex: %s",                         strerror(error));-        return GL_FALSE;+        return GLFW_FALSE;     } -    return GL_TRUE;+    return GLFW_TRUE; }  void _glfwPlatformTerminate(void) {-    _glfwTerminateContextAPI();-    _glfwTerminateJoysticks();+    _glfwTerminateEGL();+    _glfwTerminateJoysticksLinux();+    _glfwTerminateThreadLocalStoragePOSIX(); -    _glfwDeleteEventQueue(_glfw.mir.event_queue);+    _glfwDeleteEventQueueMir(_glfw.mir.event_queue);      pthread_mutex_destroy(&_glfw.mir.event_mutex); @@ -87,15 +221,18 @@  const char* _glfwPlatformGetVersionString(void) {-    const char* version = _GLFW_VERSION_NUMBER " Mir EGL"+    return _GLFW_VERSION_NUMBER " Mir EGL" #if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)         " clock_gettime"+#else+        " gettimeofday" #endif+#if defined(__linux__)+        " /dev/js"+#endif #if defined(_GLFW_BUILD_DLL)         " shared" #endif         ;--    return version; } 
glfw/src/mir_monitor.c view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 Mir - www.glfw.org+// GLFW 3.2 Mir - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2014 Brandon Schaefer <brandon.schaefer@canonical.com>+// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -73,7 +73,7 @@     return monitors; } -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)+GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) {     return first->mir.output_id == second->mir.output_id; }@@ -86,6 +86,39 @@         *ypos = monitor->mir.y; } +void FillInRGBBitsFromPixelFormat(GLFWvidmode* mode, const MirPixelFormat pf)+{+    switch (pf)+    {+      case mir_pixel_format_rgb_565:+          mode->redBits   = 5;+          mode->greenBits = 6;+          mode->blueBits  = 5;+          break;+      case mir_pixel_format_rgba_5551:+          mode->redBits   = 5;+          mode->greenBits = 5;+          mode->blueBits  = 5;+          break;+      case mir_pixel_format_rgba_4444:+          mode->redBits   = 4;+          mode->greenBits = 4;+          mode->blueBits  = 4;+          break;+      case mir_pixel_format_abgr_8888:+      case mir_pixel_format_xbgr_8888:+      case mir_pixel_format_argb_8888:+      case mir_pixel_format_xrgb_8888:+      case mir_pixel_format_bgr_888:+      case mir_pixel_format_rgb_888:+      default:+          mode->redBits   = 8;+          mode->greenBits = 8;+          mode->blueBits  = 8;+          break;+    }+}+ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) {     int i;@@ -106,9 +139,8 @@             modes[*found].width  = out->modes[*found].horizontal_resolution;             modes[*found].height = out->modes[*found].vertical_resolution;             modes[*found].refreshRate = out->modes[*found].refresh_rate;-            modes[*found].redBits     = 8;-            modes[*found].greenBits   = 8;-            modes[*found].blueBits    = 8;++            FillInRGBBitsFromPixelFormat(&modes[*found], out->output_formats[*found]);         }          break;@@ -127,12 +159,24 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); }  void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__);+}+++//////////////////////////////////////////////////////////////////////////+//////                        GLFW native API                       //////+//////////////////////////////////////////////////////////////////////////++GLFWAPI int glfwGetMirMonitor(GLFWmonitor* handle)+{+    _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    _GLFW_REQUIRE_INIT_OR_RETURN(0);+    return monitor->mir.output_id; } 
glfw/src/mir_platform.h view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 Mir - www.glfw.org+// GLFW 3.2 Mir - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2014 Brandon Schaefer <brandon.schaefer@canonical.com>+// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -24,33 +24,51 @@ // //======================================================================== -#ifndef _mir_platform_h_-#define _mir_platform_h_+#ifndef _glfw3_mir_platform_h_+#define _glfw3_mir_platform_h_ +#include <sys/queue.h>+#include <pthread.h>+#include <dlfcn.h>+ #include <mir_toolkit/mir_client_library.h> +typedef VkFlags VkMirSurfaceCreateFlagsKHR;++typedef struct VkMirSurfaceCreateInfoKHR+{+    VkStructureType             sType;+    const void*                 pNext;+    VkMirSurfaceCreateFlagsKHR  flags;+    MirConnection*              connection;+    MirSurface*                 mirSurface;+} VkMirSurfaceCreateInfoKHR;++typedef VkResult (APIENTRY *PFN_vkCreateMirSurfaceKHR)(VkInstance,const VkMirSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*);+ #include "posix_tls.h" #include "posix_time.h" #include "linux_joystick.h"--#include <sys/queue.h>--#include <pthread.h>+#include "xkb_unicode.h"+#include "egl_context.h" -#if defined(_GLFW_EGL)- #include "egl_context.h"-#else- #error "The Mir backend depends on EGL platform support"-#endif+#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)+#define _glfw_dlclose(handle) dlclose(handle)+#define _glfw_dlsym(handle, name) dlsym(handle, name) -#define _GLFW_EGL_NATIVE_WINDOW  window->mir.window-#define _GLFW_EGL_NATIVE_DISPLAY _glfw.mir.display+#define _GLFW_EGL_NATIVE_WINDOW  ((EGLNativeWindowType) window->mir.window)+#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)  #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowMir  mir #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorMir mir #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryMir mir #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorMir  mir +#define _GLFW_PLATFORM_CONTEXT_STATE+#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE++ // Mir-specific Event Queue // typedef struct EventQueue@@ -69,7 +87,6 @@  } _GLFWwindowMir; - // Mir-specific per-monitor data // typedef struct _GLFWmonitorMir@@ -81,30 +98,33 @@  } _GLFWmonitorMir; - // Mir-specific global data // typedef struct _GLFWlibraryMir {     MirConnection*          connection;     MirEGLNativeDisplayType display;+    MirCursorConfiguration* default_conf;     EventQueue* event_queue; +    short int       publicKeys[256];+     pthread_mutex_t event_mutex;     pthread_cond_t  event_cond;  } _GLFWlibraryMir; - // Mir-specific per-cursor data // TODO: Only system cursors are implemented in Mir atm. Need to wait for support. // typedef struct _GLFWcursorMir {+    MirCursorConfiguration* conf;+    MirBufferStream*        custom_cursor; } _GLFWcursorMir;  -extern void _glfwInitEventQueue(EventQueue* queue);-extern void _glfwDeleteEventQueue(EventQueue* queue);+extern void _glfwInitEventQueueMir(EventQueue* queue);+extern void _glfwDeleteEventQueueMir(EventQueue* queue); -#endif // _mir_platform_h_+#endif // _glfw3_mir_platform_h_
glfw/src/mir_window.c view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 Mir - www.glfw.org+// GLFW 3.2 Mir - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2014 Brandon Schaefer <brandon.schaefer@canonical.com>+// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -25,7 +25,6 @@ //========================================================================  #include "internal.h"-#include "xkb_unicode.h"  #include <linux/input.h> #include <stdlib.h>@@ -35,32 +34,34 @@ typedef struct EventNode {     TAILQ_ENTRY(EventNode) entries;-    MirEvent*              event;+    const MirEvent*        event;     _GLFWwindow*           window; } EventNode;  static void deleteNode(EventQueue* queue, EventNode* node) {-    free(node->event);+    mir_event_unref(node->event);     free(node); } -static int emptyEventQueue(EventQueue* queue)+static GLFWbool emptyEventQueue(EventQueue* queue) {-    return queue->head.tqh_first == NULL ? GL_TRUE : GL_FALSE;+    return queue->head.tqh_first == NULL; } -static EventNode* newEventNode(MirEvent const* event, _GLFWwindow* context)+// TODO The mir_event_ref is not supposed to be used but ... its needed+//      in this case. Need to wait until we can read from an FD set up by mir+//      for single threaded event handling.+static EventNode* newEventNode(const MirEvent* event, _GLFWwindow* context) {     EventNode* new_node = calloc(1, sizeof(EventNode));-    new_node->event     = calloc(1, sizeof(MirEvent));+    new_node->event     = mir_event_ref(event);     new_node->window    = context; -    memcpy(new_node->event, event, sizeof(MirEvent));     return new_node; } -static void enqueueEvent(MirEvent const* event, _GLFWwindow* context)+static void enqueueEvent(const MirEvent* event, _GLFWwindow* context) {     pthread_mutex_lock(&_glfw.mir.event_mutex); @@ -88,6 +89,9 @@     return node; } +/* FIXME Soon to be changed upstream mir! So we can use an egl config to figure out+         the best pixel format!+*/ static MirPixelFormat findValidPixelFormat(void) {     unsigned int i, validFormats, mirPixelFormats = 32;@@ -114,234 +118,119 @@ {     int publicMods = 0x0; -    if (mods & mir_key_modifier_alt)+    if (mods & mir_input_event_modifier_alt)         publicMods |= GLFW_MOD_ALT;-    else if (mods & mir_key_modifier_shift)+    else if (mods & mir_input_event_modifier_shift)         publicMods |= GLFW_MOD_SHIFT;-    else if (mods & mir_key_modifier_ctrl)+    else if (mods & mir_input_event_modifier_ctrl)         publicMods |= GLFW_MOD_CONTROL;-    else if (mods & mir_key_modifier_meta)+    else if (mods & mir_input_event_modifier_meta)         publicMods |= GLFW_MOD_SUPER;      return publicMods; } -// Taken from wl_init.c static int toGLFWKeyCode(uint32_t key) {-    switch (key)-    {-        case KEY_GRAVE:         return GLFW_KEY_GRAVE_ACCENT;-        case KEY_1:             return GLFW_KEY_1;-        case KEY_2:             return GLFW_KEY_2;-        case KEY_3:             return GLFW_KEY_3;-        case KEY_4:             return GLFW_KEY_4;-        case KEY_5:             return GLFW_KEY_5;-        case KEY_6:             return GLFW_KEY_6;-        case KEY_7:             return GLFW_KEY_7;-        case KEY_8:             return GLFW_KEY_8;-        case KEY_9:             return GLFW_KEY_9;-        case KEY_0:             return GLFW_KEY_0;-        case KEY_MINUS:         return GLFW_KEY_MINUS;-        case KEY_EQUAL:         return GLFW_KEY_EQUAL;-        case KEY_Q:             return GLFW_KEY_Q;-        case KEY_W:             return GLFW_KEY_W;-        case KEY_E:             return GLFW_KEY_E;-        case KEY_R:             return GLFW_KEY_R;-        case KEY_T:             return GLFW_KEY_T;-        case KEY_Y:             return GLFW_KEY_Y;-        case KEY_U:             return GLFW_KEY_U;-        case KEY_I:             return GLFW_KEY_I;-        case KEY_O:             return GLFW_KEY_O;-        case KEY_P:             return GLFW_KEY_P;-        case KEY_LEFTBRACE:     return GLFW_KEY_LEFT_BRACKET;-        case KEY_RIGHTBRACE:    return GLFW_KEY_RIGHT_BRACKET;-        case KEY_A:             return GLFW_KEY_A;-        case KEY_S:             return GLFW_KEY_S;-        case KEY_D:             return GLFW_KEY_D;-        case KEY_F:             return GLFW_KEY_F;-        case KEY_G:             return GLFW_KEY_G;-        case KEY_H:             return GLFW_KEY_H;-        case KEY_J:             return GLFW_KEY_J;-        case KEY_K:             return GLFW_KEY_K;-        case KEY_L:             return GLFW_KEY_L;-        case KEY_SEMICOLON:     return GLFW_KEY_SEMICOLON;-        case KEY_APOSTROPHE:    return GLFW_KEY_APOSTROPHE;-        case KEY_Z:             return GLFW_KEY_Z;-        case KEY_X:             return GLFW_KEY_X;-        case KEY_C:             return GLFW_KEY_C;-        case KEY_V:             return GLFW_KEY_V;-        case KEY_B:             return GLFW_KEY_B;-        case KEY_N:             return GLFW_KEY_N;-        case KEY_M:             return GLFW_KEY_M;-        case KEY_COMMA:         return GLFW_KEY_COMMA;-        case KEY_DOT:           return GLFW_KEY_PERIOD;-        case KEY_SLASH:         return GLFW_KEY_SLASH;-        case KEY_BACKSLASH:     return GLFW_KEY_BACKSLASH;-        case KEY_ESC:           return GLFW_KEY_ESCAPE;-        case KEY_TAB:           return GLFW_KEY_TAB;-        case KEY_LEFTSHIFT:     return GLFW_KEY_LEFT_SHIFT;-        case KEY_RIGHTSHIFT:    return GLFW_KEY_RIGHT_SHIFT;-        case KEY_LEFTCTRL:      return GLFW_KEY_LEFT_CONTROL;-        case KEY_RIGHTCTRL:     return GLFW_KEY_RIGHT_CONTROL;-        case KEY_LEFTALT:       return GLFW_KEY_LEFT_ALT;-        case KEY_RIGHTALT:      return GLFW_KEY_RIGHT_ALT;-        case KEY_LEFTMETA:      return GLFW_KEY_LEFT_SUPER;-        case KEY_RIGHTMETA:     return GLFW_KEY_RIGHT_SUPER;-        case KEY_MENU:          return GLFW_KEY_MENU;-        case KEY_NUMLOCK:       return GLFW_KEY_NUM_LOCK;-        case KEY_CAPSLOCK:      return GLFW_KEY_CAPS_LOCK;-        case KEY_PRINT:         return GLFW_KEY_PRINT_SCREEN;-        case KEY_SCROLLLOCK:    return GLFW_KEY_SCROLL_LOCK;-        case KEY_PAUSE:         return GLFW_KEY_PAUSE;-        case KEY_DELETE:        return GLFW_KEY_DELETE;-        case KEY_BACKSPACE:     return GLFW_KEY_BACKSPACE;-        case KEY_ENTER:         return GLFW_KEY_ENTER;-        case KEY_HOME:          return GLFW_KEY_HOME;-        case KEY_END:           return GLFW_KEY_END;-        case KEY_PAGEUP:        return GLFW_KEY_PAGE_UP;-        case KEY_PAGEDOWN:      return GLFW_KEY_PAGE_DOWN;-        case KEY_INSERT:        return GLFW_KEY_INSERT;-        case KEY_LEFT:          return GLFW_KEY_LEFT;-        case KEY_RIGHT:         return GLFW_KEY_RIGHT;-        case KEY_DOWN:          return GLFW_KEY_DOWN;-        case KEY_UP:            return GLFW_KEY_UP;-        case KEY_F1:            return GLFW_KEY_F1;-        case KEY_F2:            return GLFW_KEY_F2;-        case KEY_F3:            return GLFW_KEY_F3;-        case KEY_F4:            return GLFW_KEY_F4;-        case KEY_F5:            return GLFW_KEY_F5;-        case KEY_F6:            return GLFW_KEY_F6;-        case KEY_F7:            return GLFW_KEY_F7;-        case KEY_F8:            return GLFW_KEY_F8;-        case KEY_F9:            return GLFW_KEY_F9;-        case KEY_F10:           return GLFW_KEY_F10;-        case KEY_F11:           return GLFW_KEY_F11;-        case KEY_F12:           return GLFW_KEY_F12;-        case KEY_F13:           return GLFW_KEY_F13;-        case KEY_F14:           return GLFW_KEY_F14;-        case KEY_F15:           return GLFW_KEY_F15;-        case KEY_F16:           return GLFW_KEY_F16;-        case KEY_F17:           return GLFW_KEY_F17;-        case KEY_F18:           return GLFW_KEY_F18;-        case KEY_F19:           return GLFW_KEY_F19;-        case KEY_F20:           return GLFW_KEY_F20;-        case KEY_F21:           return GLFW_KEY_F21;-        case KEY_F22:           return GLFW_KEY_F22;-        case KEY_F23:           return GLFW_KEY_F23;-        case KEY_F24:           return GLFW_KEY_F24;-        case KEY_KPSLASH:       return GLFW_KEY_KP_DIVIDE;-        case KEY_KPDOT:         return GLFW_KEY_KP_MULTIPLY;-        case KEY_KPMINUS:       return GLFW_KEY_KP_SUBTRACT;-        case KEY_KPPLUS:        return GLFW_KEY_KP_ADD;-        case KEY_KP0:           return GLFW_KEY_KP_0;-        case KEY_KP1:           return GLFW_KEY_KP_1;-        case KEY_KP2:           return GLFW_KEY_KP_2;-        case KEY_KP3:           return GLFW_KEY_KP_3;-        case KEY_KP4:           return GLFW_KEY_KP_4;-        case KEY_KP5:           return GLFW_KEY_KP_5;-        case KEY_KP6:           return GLFW_KEY_KP_6;-        case KEY_KP7:           return GLFW_KEY_KP_7;-        case KEY_KP8:           return GLFW_KEY_KP_8;-        case KEY_KP9:           return GLFW_KEY_KP_9;-        case KEY_KPCOMMA:       return GLFW_KEY_KP_DECIMAL;-        case KEY_KPEQUAL:       return GLFW_KEY_KP_EQUAL;-        case KEY_KPENTER:       return GLFW_KEY_KP_ENTER;-        default:                return GLFW_KEY_UNKNOWN;-    }+    if (key < sizeof(_glfw.mir.publicKeys) / sizeof(_glfw.mir.publicKeys[0]))+        return _glfw.mir.publicKeys[key];++    return GLFW_KEY_UNKNOWN; } -static void handleKeyEvent(const MirKeyEvent key, _GLFWwindow* window)+static void handleKeyEvent(const MirKeyboardEvent* key_event, _GLFWwindow* window) {-    const int pressed = key.action == mir_key_action_up ? GLFW_RELEASE : GLFW_PRESS;-    const int mods = mirModToGLFWMod(key.modifiers);-    const long text = _glfwKeySym2Unicode(key.key_code);-    const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));+    const int action    = mir_keyboard_event_action   (key_event);+    const int scan_code = mir_keyboard_event_scan_code(key_event);+    const int key_code  = mir_keyboard_event_key_code (key_event);+    const int modifiers = mir_keyboard_event_modifiers(key_event); -    _glfwInputKey(window, toGLFWKeyCode(key.scan_code), key.scan_code, pressed, mods);+    const int  pressed = action == mir_keyboard_action_up ? GLFW_RELEASE : GLFW_PRESS;+    const int  mods    = mirModToGLFWMod(modifiers);+    const long text    = _glfwKeySym2Unicode(key_code);+    const int  plain   = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); +    _glfwInputKey(window, toGLFWKeyCode(scan_code), scan_code, pressed, mods);+     if (text != -1)         _glfwInputChar(window, text, mods, plain); } -static void handleMouseButton(_GLFWwindow* window,-                              int pressed, int mods, MirMotionButton button)+static void handlePointerButton(_GLFWwindow* window,+                              int pressed,+                              const MirPointerEvent* pointer_event) {-    static int lastButton;-    int publicButton;-    const int publicMods = mirModToGLFWMod(mods);+    int mods                = mir_pointer_event_modifiers(pointer_event);+    const int publicMods    = mirModToGLFWMod(mods);+    MirPointerButton button = mir_pointer_button_primary;+    static uint32_t oldButtonStates = 0;+    uint32_t newButtonStates        = mir_pointer_event_buttons(pointer_event);+    int publicButton                = GLFW_MOUSE_BUTTON_LEFT; +    // XOR our old button states our new states to figure out what was added or removed+    button = newButtonStates ^ oldButtonStates;+     switch (button)     {-        case mir_motion_button_primary:+        case mir_pointer_button_primary:             publicButton = GLFW_MOUSE_BUTTON_LEFT;             break;-        case mir_motion_button_secondary:+        case mir_pointer_button_secondary:             publicButton = GLFW_MOUSE_BUTTON_RIGHT;             break;-        case mir_motion_button_tertiary:+        case mir_pointer_button_tertiary:             publicButton = GLFW_MOUSE_BUTTON_MIDDLE;             break;-        case mir_motion_button_forward:+        case mir_pointer_button_forward:             // FIXME What is the forward button?             publicButton = GLFW_MOUSE_BUTTON_4;             break;-        case mir_motion_button_back:+        case mir_pointer_button_back:             // FIXME What is the back button?             publicButton = GLFW_MOUSE_BUTTON_5;             break;         default:-            publicButton = lastButton;             break;     } -    lastButton = publicButton;+    oldButtonStates = newButtonStates;      _glfwInputMouseClick(window, publicButton, pressed, publicMods); } -static void handleMouseMotion(_GLFWwindow* window, int x, int y)+static void handlePointerMotion(_GLFWwindow* window,+                                const MirPointerEvent* pointer_event) {-    _glfwInputCursorMotion(window, x, y);-}+    int current_x = window->virtualCursorPosX;+    int current_y = window->virtualCursorPosY;+    int x  = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x);+    int y  = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y);+    int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);+    int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll); -static void handleMouseScroll(_GLFWwindow* window, int dx, int dy)-{-    _glfwInputScroll(window, dx, dy);+    _glfwInputCursorPos(window, x, y);+    if (dx != 0 || dy != 0)+      _glfwInputScroll(window, dx, dy); } -static void handleMouseEvent(const MirMotionEvent motion,-                             int cord_index,+static void handlePointerEvent(const MirPointerEvent* pointer_event,                              _GLFWwindow* window) {-    switch (motion.action)+    int action = mir_pointer_event_action(pointer_event);++    switch (action)     {-          case mir_motion_action_down:-          case mir_motion_action_pointer_down:-              handleMouseButton(window, GLFW_PRESS,-                                motion.modifiers, motion.button_state);-              break;-          case mir_motion_action_up:-          case mir_motion_action_pointer_up:-              handleMouseButton(window, GLFW_RELEASE,-                                motion.modifiers, motion.button_state);-              break;-          case mir_motion_action_hover_move:-          case mir_motion_action_move:-              handleMouseMotion(window,-                                motion.pointer_coordinates[cord_index].x,-                                motion.pointer_coordinates[cord_index].y);+          case mir_pointer_action_button_down:+              handlePointerButton(window, GLFW_PRESS, pointer_event);               break;-          case mir_motion_action_outside:+          case mir_pointer_action_button_up:+              handlePointerButton(window, GLFW_RELEASE, pointer_event);               break;-          case mir_motion_action_scroll:-              handleMouseScroll(window,-                                motion.pointer_coordinates[cord_index].hscroll,-                                motion.pointer_coordinates[cord_index].vscroll);+          case mir_pointer_action_motion:+              handlePointerMotion(window, pointer_event);               break;-          case mir_motion_action_cancel:-          case mir_motion_action_hover_enter:-          case mir_motion_action_hover_exit:+          case mir_pointer_action_enter:+          case mir_pointer_action_leave:               break;           default:               break;@@ -349,85 +238,90 @@     } } -static void handleMotionEvent(const MirMotionEvent motion, _GLFWwindow* window)+static void handleInput(const MirInputEvent* input_event, _GLFWwindow* window) {-    int i;-    for (i = 0;  i < motion.pointer_count;  i++)-        handleMouseEvent(motion, i, window);+    int type = mir_input_event_get_type(input_event);++    switch (type)+    {+        case mir_input_event_type_key:+            handleKeyEvent(mir_input_event_get_keyboard_event(input_event), window);+            break;+        case mir_input_event_type_pointer:+            handlePointerEvent(mir_input_event_get_pointer_event(input_event), window);+            break;+        default:+            break;+    } } -static void handleInput(MirEvent const* event, _GLFWwindow* window)+static void handleEvent(const MirEvent* event, _GLFWwindow* window) {-    switch (event->type)+    int type = mir_event_get_type(event);++    switch (type)     {-        case mir_event_type_key:-            handleKeyEvent(event->key, window);-            break;-        case mir_event_type_motion:-            handleMotionEvent(event->motion, window);+        case mir_event_type_input:+            handleInput(mir_event_get_input_event(event), window);             break;         default:             break;     } } -static void addNewEvent(MirSurface* surface, MirEvent const* event, void* context)+static void addNewEvent(MirSurface* surface, const MirEvent* event, void* context) {     enqueueEvent(event, context); } -static int createSurface(_GLFWwindow* window)+static GLFWbool createSurface(_GLFWwindow* window) {-    MirSurfaceParameters params =-    {-        .name         = "MirSurface",-        .width        = window->mir.width,-        .height       = window->mir.height,-        .pixel_format = mir_pixel_format_invalid,-        .buffer_usage = mir_buffer_usage_hardware,-        .output_id    = mir_display_output_id_invalid-    };--    MirEventDelegate delegate =-    {-        addNewEvent,-        window-    };+    MirSurfaceSpec* spec;+    MirBufferUsage buffer_usage = mir_buffer_usage_hardware;+    MirPixelFormat pixel_format = findValidPixelFormat(); -    params.pixel_format = findValidPixelFormat();-    if (params.pixel_format == mir_pixel_format_invalid)+    if (pixel_format == mir_pixel_format_invalid)     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Mir: Unable to find a correct pixel format");-        return GL_FALSE;+        return GLFW_FALSE;     }+ +    spec = mir_connection_create_spec_for_normal_surface(_glfw.mir.connection,+                                                         window->mir.width,+                                                         window->mir.height,+                                                         pixel_format); -    window->mir.surface =-        mir_connection_create_surface_sync(_glfw.mir.connection, &params);+    mir_surface_spec_set_buffer_usage(spec, buffer_usage);+    mir_surface_spec_set_name(spec, "MirSurface");++    window->mir.surface = mir_surface_create_sync(spec);+    mir_surface_spec_release(spec);+     if (!mir_surface_is_valid(window->mir.surface))     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Mir: Unable to create surface: %s",                         mir_surface_get_error_message(window->mir.surface)); -        return GL_FALSE;+        return GLFW_FALSE;     } -    mir_surface_set_event_handler(window->mir.surface, &delegate);+    mir_surface_set_event_handler(window->mir.surface, addNewEvent, window); -    return GL_TRUE;+    return GLFW_TRUE; }  ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// ////////////////////////////////////////////////////////////////////////// -void _glfwInitEventQueue(EventQueue* queue)+void _glfwInitEventQueueMir(EventQueue* queue) {     TAILQ_INIT(&queue->head); } -void _glfwDeleteEventQueue(EventQueue* queue)+void _glfwDeleteEventQueueMir(EventQueue* queue) {     if (queue)     {@@ -457,23 +351,20 @@                               const _GLFWctxconfig* ctxconfig,                               const _GLFWfbconfig* fbconfig) {-    if (!_glfwCreateContext(window, ctxconfig, fbconfig))-        return GL_FALSE;--    if (wndconfig->monitor)+    if (window->monitor)     {         GLFWvidmode mode;-        _glfwPlatformGetVideoMode(wndconfig->monitor, &mode);+        _glfwPlatformGetVideoMode(window->monitor, &mode);          mir_surface_set_state(window->mir.surface, mir_surface_state_fullscreen);          if (wndconfig->width > mode.width || wndconfig->height > mode.height)         {             _glfwInputError(GLFW_PLATFORM_ERROR,-                            "Mir: Requested surface size is to large (%i %i)",-                             wndconfig->width, wndconfig->height);+                            "Mir: Requested surface size too large: %ix%i",+                            wndconfig->width, wndconfig->height); -            return GL_FALSE;+            return GLFW_FALSE;         }     } @@ -481,11 +372,20 @@     window->mir.height = wndconfig->height;      if (!createSurface(window))-        return GL_FALSE;+        return GLFW_FALSE; -    window->mir.window = mir_surface_get_egl_native_window(window->mir.surface);+    window->mir.window = mir_buffer_stream_get_egl_native_window(+                                   mir_surface_get_buffer_stream(window->mir.surface)); -    return GL_TRUE;+    if (ctxconfig->client != GLFW_NO_API)+    {+        if (!_glfwInitEGL())+            return GLFW_FALSE;+        if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))+            return GLFW_FALSE;+    }++    return GLFW_TRUE; }  void _glfwPlatformDestroyWindow(_GLFWwindow* window)@@ -496,19 +396,59 @@         window->mir.surface = NULL;     } -    _glfwDestroyContext(window);+    if (window->context.destroy)+        window->context.destroy(window); }  void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) {+    MirSurfaceSpec* spec;+    const char* e_title = title ? title : "";++    spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);+    mir_surface_spec_set_name(spec, e_title);++    mir_surface_apply_spec(window->mir.surface, spec);+    mir_surface_spec_release(spec);+}++void _glfwPlatformSetWindowIcon(_GLFWwindow* window,+                                int count, const GLFWimage* images)+{     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); } +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)+{+    MirSurfaceSpec* spec;++    spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);+    mir_surface_spec_set_width (spec, width);+    mir_surface_spec_set_height(spec, height);++    mir_surface_apply_spec(window->mir.surface, spec);+    mir_surface_spec_release(spec);+}++void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,+                                      int minwidth, int minheight,+                                      int maxwidth, int maxheight)+{+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__);+}++void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)+{+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__);+}+ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); }  void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,@@ -516,19 +456,13 @@                                      int* right, int* bottom) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); }  void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);-}--void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)-{-    _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); }  void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)@@ -549,43 +483,74 @@     mir_surface_set_state(window->mir.surface, mir_surface_state_restored); } -void _glfwPlatformHideWindow(_GLFWwindow* window)+void _glfwPlatformMaximizeWindow(_GLFWwindow* window) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); } +void _glfwPlatformHideWindow(_GLFWwindow* window)+{+    MirSurfaceSpec* spec;++    spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);+    mir_surface_spec_set_state(spec, mir_surface_state_hidden);++    mir_surface_apply_spec(window->mir.surface, spec);+    mir_surface_spec_release(spec);+}+ void _glfwPlatformShowWindow(_GLFWwindow* window) {+    MirSurfaceSpec* spec;++    spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);+    mir_surface_spec_set_state(spec, mir_surface_state_restored);++    mir_surface_apply_spec(window->mir.surface, spec);+    mir_surface_spec_release(spec);+}++void _glfwPlatformFocusWindow(_GLFWwindow* window)+{     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); } -void _glfwPlatformUnhideWindow(_GLFWwindow* window)+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,+                                   _GLFWmonitor* monitor,+                                   int xpos, int ypos,+                                   int width, int height,+                                   int refreshRate) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); }  int _glfwPlatformWindowFocused(_GLFWwindow* window) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);-    return GL_FALSE;+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__);+    return GLFW_FALSE; }  int _glfwPlatformWindowIconified(_GLFWwindow* window) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);-    return GL_FALSE;+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__);+    return GLFW_FALSE; }  int _glfwPlatformWindowVisible(_GLFWwindow* window) {+    return mir_surface_get_visibility(window->mir.surface) == mir_surface_visibility_exposed;+}++int _glfwPlatformWindowMaximized(_GLFWwindow* window)+{     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);-    return GL_FALSE;+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__);+    return GLFW_FALSE; }  void _glfwPlatformPollEvents(void)@@ -594,7 +559,7 @@      while ((node = dequeueEvent(_glfw.mir.event_queue)))     {-        handleInput(node->event, node->window);+        handleEvent(node->event, node->window);         deleteNode(_glfw.mir.event_queue, node);     } }@@ -611,6 +576,24 @@     _glfwPlatformPollEvents(); } +void _glfwPlatformWaitEventsTimeout(double timeout)+{+    pthread_mutex_lock(&_glfw.mir.event_mutex);++    if (emptyEventQueue(_glfw.mir.event_queue))+    {+        struct timespec time;+        clock_gettime(CLOCK_REALTIME, &time);+        time.tv_sec += (long) timeout;+        time.tv_nsec += (long) ((timeout - (long) timeout) * 1e9);+        pthread_cond_timedwait(&_glfw.mir.event_cond, &_glfw.mir.event_mutex, &time);+    }++    pthread_mutex_unlock(&_glfw.mir.event_mutex);++    _glfwPlatformPollEvents();+}+ void _glfwPlatformPostEmptyEvent(void) { }@@ -623,65 +606,243 @@         *height = window->mir.height; } +// FIXME implement int _glfwPlatformCreateCursor(_GLFWcursor* cursor,                               const GLFWimage* image,                               int xhot, int yhot) {-    _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+    MirBufferStream* stream;+    MirPixelFormat pixel_format = findValidPixelFormat(); -    return GL_FALSE;+    int i_w = image->width;+    int i_h = image->height;++    if (pixel_format == mir_pixel_format_invalid)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Mir: Unable to find a correct pixel format");+        return GLFW_FALSE;+    }++    stream = mir_connection_create_buffer_stream_sync(_glfw.mir.connection,+                                                      i_w, i_h,+                                                      pixel_format,+                                                      mir_buffer_usage_software);++    cursor->mir.conf = mir_cursor_configuration_from_buffer_stream(stream, xhot, yhot);++    char* dest;+    unsigned char *pixels;+    int i, r_stride, bytes_per_pixel, bytes_per_row;++    MirGraphicsRegion region;+    mir_buffer_stream_get_graphics_region(stream, &region);++    // FIXME Figure this out based on the current_pf+    bytes_per_pixel = 4;+    bytes_per_row   = bytes_per_pixel * i_w;++    dest   = region.vaddr;+    pixels = image->pixels;++    r_stride = region.stride;++    for (i = 0; i < i_h; i++)+    {+        memcpy(dest, pixels, bytes_per_row);+        dest   += r_stride;+        pixels += r_stride;+    }++    cursor->mir.custom_cursor = stream;++    return GLFW_TRUE; } +const char* getSystemCursorName(int shape)+{+    switch (shape)+    {+        case GLFW_ARROW_CURSOR:+            return mir_arrow_cursor_name;+        case GLFW_IBEAM_CURSOR:+            return mir_caret_cursor_name;+        case GLFW_CROSSHAIR_CURSOR:+            return mir_crosshair_cursor_name;+        case GLFW_HAND_CURSOR:+            return mir_open_hand_cursor_name;+        case GLFW_HRESIZE_CURSOR:+            return mir_horizontal_resize_cursor_name;+        case GLFW_VRESIZE_CURSOR:+            return mir_vertical_resize_cursor_name;+    }++    return NULL;+}+ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) {-    _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+    const char* cursor_name = getSystemCursorName(shape); -    return GL_FALSE;+    if (cursor_name)+    {+        cursor->mir.conf          = mir_cursor_configuration_from_name(cursor_name);+        cursor->mir.custom_cursor = NULL;++        return GLFW_TRUE;+    }++    return GLFW_FALSE; }  void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) {-    _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+    if (cursor->mir.conf)+        mir_cursor_configuration_destroy(cursor->mir.conf);+    if (cursor->mir.custom_cursor)+        mir_buffer_stream_release_sync(cursor->mir.custom_cursor); }  void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) {-    _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+    if (cursor && cursor->mir.conf)+    {+        mir_wait_for(mir_surface_configure_cursor(window->mir.surface, cursor->mir.conf));+        if (cursor->mir.custom_cursor)+        {+            mir_buffer_stream_swap_buffers_sync(cursor->mir.custom_cursor);+        }+    }+    else+    {+        mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.default_conf));+    } }  void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); }  void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); } -void _glfwPlatformApplyCursorMode(_GLFWwindow* window)+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); } +const char* _glfwPlatformGetKeyName(int key, int scancode)+{+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__);+    return NULL;+}+ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__); }  const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) {     _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Mir: Unsupported function %s!", __PRETTY_FUNCTION__);+                    "Mir: Unsupported function %s", __PRETTY_FUNCTION__);      return NULL;+}++char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count)+{+    char** extensions;++    *count = 0;++    if (!_glfw.vk.KHR_mir_surface)+        return NULL;++    extensions = calloc(2, sizeof(char*));+    extensions[0] = strdup("VK_KHR_surface");+    extensions[1] = strdup("VK_KHR_mir_surface");++    *count = 2;+    return extensions;+}++int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,+                                                      VkPhysicalDevice device,+                                                      uint32_t queuefamily)+{+    PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR =+        (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)+        vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");+    if (!vkGetPhysicalDeviceMirPresentationSupportKHR)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Mir: Vulkan instance missing VK_KHR_mir_surface extension");+        return GLFW_FALSE;+    }++    return vkGetPhysicalDeviceMirPresentationSupportKHR(device,+                                                        queuefamily,+                                                        _glfw.mir.connection);+}++VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,+                                          _GLFWwindow* window,+                                          const VkAllocationCallbacks* allocator,+                                          VkSurfaceKHR* surface)+{+    VkResult err;+    VkMirSurfaceCreateInfoKHR sci;+    PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;++    vkCreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)+        vkGetInstanceProcAddr(instance, "vkCreateMirSurfaceKHR");+    if (!vkCreateMirSurfaceKHR)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Mir: Vulkan instance missing VK_KHR_mir_surface extension");+        return VK_ERROR_EXTENSION_NOT_PRESENT;+    }++    memset(&sci, 0, sizeof(sci));+    sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;+    sci.connection = _glfw.mir.connection;+    sci.mirSurface = window->mir.surface;++    err = vkCreateMirSurfaceKHR(instance, &sci, allocator, surface);+    if (err)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Mir: Failed to create Vulkan surface: %s",+                        _glfwGetVulkanResultString(err));+    }++    return err;+}+++//////////////////////////////////////////////////////////////////////////+//////                        GLFW native API                       //////+//////////////////////////////////////////////////////////////////////////++GLFWAPI MirConnection* glfwGetMirDisplay(void)+{+    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);+    return _glfw.mir.connection;+}++GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* handle)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);+    return window->mir.surface; } 
glfw/src/monitor.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 - www.glfw.org+// GLFW 3.2 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -27,7 +27,9 @@  #include "internal.h" +#include <assert.h> #include <math.h>+#include <float.h> #include <string.h> #include <stdlib.h> #include <limits.h>@@ -37,43 +39,42 @@ #define strdup _strdup #endif -// Lexical comparison function for GLFW video modes, used by qsort+// Lexically compare video modes, used by qsort //-static int compareVideoModes(const void* firstPtr, const void* secondPtr)+static int compareVideoModes(const void* fp, const void* sp) {-    int firstBPP, secondBPP, firstSize, secondSize;-    const GLFWvidmode* first = firstPtr;-    const GLFWvidmode* second = secondPtr;+    const GLFWvidmode* fm = fp;+    const GLFWvidmode* sm = sp;+    const int fbpp = fm->redBits + fm->greenBits + fm->blueBits;+    const int sbpp = sm->redBits + sm->greenBits + sm->blueBits;+    const int farea = fm->width * fm->height;+    const int sarea = sm->width * sm->height;      // First sort on color bits per pixel-    firstBPP = first->redBits + first->greenBits + first->blueBits;-    secondBPP = second->redBits + second->greenBits + second->blueBits;-    if (firstBPP != secondBPP)-        return firstBPP - secondBPP;+    if (fbpp != sbpp)+        return fbpp - sbpp; -    // Then sort on screen area, in pixels-    firstSize = first->width * first->height;-    secondSize = second->width * second->height;-    if (firstSize != secondSize)-        return firstSize - secondSize;+    // Then sort on screen area+    if (farea != sarea)+        return farea - sarea;      // Lastly sort on refresh rate-    return first->refreshRate - second->refreshRate;+    return fm->refreshRate - sm->refreshRate; }  // Retrieves the available modes for the specified monitor //-static int refreshVideoModes(_GLFWmonitor* monitor)+static GLFWbool refreshVideoModes(_GLFWmonitor* monitor) {     int modeCount;     GLFWvidmode* modes;      if (monitor->modes)-        return GL_TRUE;+        return GLFW_TRUE;      modes = _glfwPlatformGetVideoModes(monitor, &modeCount);     if (!modes)-        return GL_FALSE;+        return GLFW_FALSE;      qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes); @@ -81,7 +82,7 @@     monitor->modes = modes;     monitor->modeCount = modeCount; -    return GL_TRUE;+    return GLFW_TRUE; }  @@ -129,7 +130,11 @@         for (window = _glfw.windowListHead;  window;  window = window->next)         {             if (window->monitor == monitors[i])-                window->monitor = NULL;+            {+                int width, height;+                _glfwPlatformGetWindowSize(window, &width, &height);+                _glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0);+            }         }          if (_glfw.callbacks.monitor)@@ -161,7 +166,12 @@     _glfwFreeMonitors(monitors, monitorCount); } +void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window)+{+    monitor->window = window;+} + ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////@@ -266,9 +276,9 @@     return closest; } -int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second)+int _glfwCompareVideoModes(const GLFWvidmode* fm, const GLFWvidmode* sm) {-    return compareVideoModes(first, second);+    return compareVideoModes(fm, sm); }  void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)@@ -297,6 +307,7 @@  GLFWAPI GLFWmonitor** glfwGetMonitors(int* count) {+    assert(count != NULL);     *count = 0;      _GLFW_REQUIRE_INIT_OR_RETURN(NULL);@@ -308,12 +319,17 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void) {     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++    if (!_glfw.monitorCount)+        return NULL;+     return (GLFWmonitor*) _glfw.monitors[0]; }  GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) {     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    assert(monitor != NULL);      if (xpos)         *xpos = 0;@@ -328,6 +344,7 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) {     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    assert(monitor != NULL);      if (widthMM)         *widthMM = 0;@@ -345,6 +362,8 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) {     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    assert(monitor != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     return monitor->name; }@@ -359,6 +378,8 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) {     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    assert(monitor != NULL);+    assert(count != NULL);      *count = 0; @@ -374,6 +395,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) {     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    assert(monitor != NULL);      _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -389,10 +411,9 @@      _GLFW_REQUIRE_INIT(); -    if (gamma <= 0.f)+    if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)     {-        _glfwInputError(GLFW_INVALID_VALUE,-                        "Gamma value must be greater than zero");+        _glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);         return;     } @@ -423,6 +444,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) {     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    assert(monitor != NULL);      _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -435,6 +457,19 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) {     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    assert(monitor != NULL);+    assert(ramp != NULL);+    assert(ramp->red != NULL);+    assert(ramp->green != NULL);+    assert(ramp->blue != NULL);++    if (ramp->size <= 0)+    {+        _glfwInputError(GLFW_INVALID_VALUE,+                        "Invalid gamma ramp size %i",+                        ramp->size);+        return;+    }      _GLFW_REQUIRE_INIT(); 
glfw/src/nsgl_context.h view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 OS X - www.glfw.org+// GLFW 3.2 OS X - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.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@@ -24,10 +24,9 @@ // //======================================================================== -#ifndef _nsgl_context_h_-#define _nsgl_context_h_+#ifndef _glfw3_nsgl_context_h_+#define _glfw3_nsgl_context_h_ -#define _GLFW_PLATFORM_FBCONFIG #define _GLFW_PLATFORM_CONTEXT_STATE            _GLFWcontextNSGL nsgl #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE    _GLFWlibraryNSGL nsgl @@ -37,26 +36,25 @@ typedef struct _GLFWcontextNSGL {     id           pixelFormat;-    id	         context;+    id	         object;  } _GLFWcontextNSGL; - // NSGL-specific global data // typedef struct _GLFWlibraryNSGL {     // dlopen handle for OpenGL.framework (for glfwGetProcAddress)-    void*           framework;+    CFBundleRef     framework;  } _GLFWlibraryNSGL;  -int _glfwInitContextAPI(void);-void _glfwTerminateContextAPI(void);-int _glfwCreateContext(_GLFWwindow* window,-                       const _GLFWctxconfig* ctxconfig,-                       const _GLFWfbconfig* fbconfig);-void _glfwDestroyContext(_GLFWwindow* window);+GLFWbool _glfwInitNSGL(void);+void _glfwTerminateNSGL(void);+GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,+                                const _GLFWctxconfig* ctxconfig,+                                const _GLFWfbconfig* fbconfig);+void _glfwDestroyContextNSGL(_GLFWwindow* window); -#endif // _nsgl_context_h_+#endif // _glfw3_nsgl_context_h_
glfw/src/nsgl_context.m view
@@ -1,7 +1,7 @@ //========================================================================-// GLFW 3.1 OS X - www.glfw.org+// GLFW 3.2 OS X - www.glfw.org //-------------------------------------------------------------------------// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.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@@ -27,58 +27,112 @@ #include "internal.h"  +static void makeContextCurrentNSGL(_GLFWwindow* window)+{+    if (window)+        [window->context.nsgl.object makeCurrentContext];+    else+        [NSOpenGLContext clearCurrentContext];++    _glfwPlatformSetCurrentContext(window);+}++static void swapBuffersNSGL(_GLFWwindow* window)+{+    // ARP appears to be unnecessary, but this is future-proof+    [window->context.nsgl.object flushBuffer];+}++static void swapIntervalNSGL(int interval)+{+    _GLFWwindow* window = _glfwPlatformGetCurrentContext();++    GLint sync = interval;+    [window->context.nsgl.object setValues:&sync+                              forParameter:NSOpenGLCPSwapInterval];+}++static int extensionSupportedNSGL(const char* extension)+{+    // There are no NSGL extensions+    return GLFW_FALSE;+}++static GLFWglproc getProcAddressNSGL(const char* procname)+{+    CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,+                                                       procname,+                                                       kCFStringEncodingASCII);++    GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,+                                                          symbolName);++    CFRelease(symbolName);++    return symbol;+}++// Destroy the OpenGL context+//+static void destroyContextNSGL(_GLFWwindow* window)+{+    [window->context.nsgl.pixelFormat release];+    window->context.nsgl.pixelFormat = nil;++    [window->context.nsgl.object release];+    window->context.nsgl.object = nil;+}++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////  // Initialize OpenGL support //-int _glfwInitContextAPI(void)+GLFWbool _glfwInitNSGL(void) {-    if (!_glfwInitTLS())-        return GL_FALSE;+    if (_glfw.nsgl.framework)+        return GLFW_TRUE;      _glfw.nsgl.framework =         CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));     if (_glfw.nsgl.framework == NULL)     {-        _glfwInputError(GLFW_PLATFORM_ERROR,+        _glfwInputError(GLFW_API_UNAVAILABLE,                         "NSGL: Failed to locate OpenGL framework");-        return GL_FALSE;+        return GLFW_FALSE;     } -    return GL_TRUE;+    return GLFW_TRUE; }  // Terminate OpenGL support //-void _glfwTerminateContextAPI(void)+void _glfwTerminateNSGL(void) {-    _glfwTerminateTLS(); }  // Create the OpenGL context //-int _glfwCreateContext(_GLFWwindow* window,-                       const _GLFWctxconfig* ctxconfig,-                       const _GLFWfbconfig* fbconfig)+GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,+                                const _GLFWctxconfig* ctxconfig,+                                const _GLFWfbconfig* fbconfig) {     unsigned int attributeCount = 0; -    if (ctxconfig->api == GLFW_OPENGL_ES_API)+    if (ctxconfig->client == GLFW_OPENGL_ES_API)     {-        _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                        "NSGL: This API does not support OpenGL ES");-        return GL_FALSE;+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "NSGL: OpenGL ES is not available on OS X");+        return GLFW_FALSE;     } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070     if (ctxconfig->major == 3 && ctxconfig->minor < 2)     {         _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                        "NSGL: The targeted version of OS X does not "-                        "support OpenGL 3.0 or 3.1");-        return GL_FALSE;+                        "NSGL: The targeted version of OS X does not support OpenGL 3.0 or 3.1");+        return GLFW_FALSE;     }      if (ctxconfig->major > 2)@@ -86,31 +140,17 @@         if (!ctxconfig->forward)         {             _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                            "NSGL: The targeted version of OS X only "-                            "supports OpenGL 3.2 and later versions if they "-                            "are forward-compatible");-            return GL_FALSE;+                            "NSGL: The targeted version of OS X only supports forward-compatible contexts for OpenGL 3.2 and above");+            return GLFW_FALSE;         }          if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)         {             _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                            "NSGL: The targeted version of OS X only "-                            "supports OpenGL 3.2 and later versions if they "-                            "use the core profile");-            return GL_FALSE;+                            "NSGL: The targeted version of OS X only supports core profile contexts for OpenGL 3.2 and above");+            return GLFW_FALSE;         }     }-#else-    // Fail if OpenGL 3.0 or above was requested-    if (ctxconfig->major > 2)-    {-        _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                        "NSGL: The targeted version of OS X does not "-                        "support OpenGL version 3.0 or above");-        return GL_FALSE;-    }-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/      // Context robustness modes (GL_KHR_robustness) are not yet supported on     // OS X but are not a hard constraint, so ignore and continue@@ -127,7 +167,6 @@     ADD_ATTR(NSOpenGLPFAAccelerated);     ADD_ATTR(NSOpenGLPFAClosestPolicy); -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000     if (ctxconfig->major >= 4)     {@@ -139,7 +178,6 @@     {         ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);     }-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/      if (ctxconfig->major <= 2)     {@@ -213,91 +251,40 @@ #undef ADD_ATTR #undef ADD_ATTR2 -    window->nsgl.pixelFormat =+    window->context.nsgl.pixelFormat =         [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];-    if (window->nsgl.pixelFormat == nil)+    if (window->context.nsgl.pixelFormat == nil)     {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "NSGL: Failed to create OpenGL pixel format");-        return GL_FALSE;+        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,+                        "NSGL: Failed to find a suitable pixel format");+        return GLFW_FALSE;     }      NSOpenGLContext* share = NULL;      if (ctxconfig->share)-        share = ctxconfig->share->nsgl.context;+        share = ctxconfig->share->context.nsgl.object; -    window->nsgl.context =-        [[NSOpenGLContext alloc] initWithFormat:window->nsgl.pixelFormat+    window->context.nsgl.object =+        [[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat                                    shareContext:share];-    if (window->nsgl.context == nil)+    if (window->context.nsgl.object == nil)     {-        _glfwInputError(GLFW_PLATFORM_ERROR,+        _glfwInputError(GLFW_VERSION_UNAVAILABLE,                         "NSGL: Failed to create OpenGL context");-        return GL_FALSE;+        return GLFW_FALSE;     } -    return GL_TRUE;-}--// Destroy the OpenGL context-//-void _glfwDestroyContext(_GLFWwindow* window)-{-    [window->nsgl.pixelFormat release];-    window->nsgl.pixelFormat = nil;--    [window->nsgl.context release];-    window->nsgl.context = nil;-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////--void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)-{-    if (window)-        [window->nsgl.context makeCurrentContext];-    else-        [NSOpenGLContext clearCurrentContext];--    _glfwSetCurrentContext(window);-}--void _glfwPlatformSwapBuffers(_GLFWwindow* window)-{-    // ARP appears to be unnecessary, but this is future-proof-    [window->nsgl.context flushBuffer];-}--void _glfwPlatformSwapInterval(int interval)-{-    _GLFWwindow* window = _glfwPlatformGetCurrentContext();--    GLint sync = interval;-    [window->nsgl.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];-}--int _glfwPlatformExtensionSupported(const char* extension)-{-    // There are no NSGL extensions-    return GL_FALSE;-}--GLFWglproc _glfwPlatformGetProcAddress(const char* procname)-{-    CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,-                                                       procname,-                                                       kCFStringEncodingASCII);--    GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,-                                                          symbolName);+    [window->context.nsgl.object setView:window->ns.view]; -    CFRelease(symbolName);+    window->context.makeCurrent = makeContextCurrentNSGL;+    window->context.swapBuffers = swapBuffersNSGL;+    window->context.swapInterval = swapIntervalNSGL;+    window->context.extensionSupported = extensionSupportedNSGL;+    window->context.getProcAddress = getProcAddressNSGL;+    window->context.destroy = destroyContextNSGL; -    return symbol;+    return GLFW_TRUE; }  @@ -309,6 +296,13 @@ {     _GLFWwindow* window = (_GLFWwindow*) handle;     _GLFW_REQUIRE_INIT_OR_RETURN(nil);-    return window->nsgl.context;++    if (window->context.client == GLFW_NO_API)+    {+        _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);+        return NULL;+    }++    return window->context.nsgl.object; } 
glfw/src/posix_time.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 POSIX - www.glfw.org+// GLFW 3.2 POSIX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -30,52 +30,29 @@ #include <sys/time.h> #include <time.h> -// Return raw time-//-static uint64_t getRawTime(void)-{-#if defined(CLOCK_MONOTONIC)-    if (_glfw.posix_time.monotonic)-    {-        struct timespec ts; -        clock_gettime(CLOCK_MONOTONIC, &ts);-        return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;-    }-    else-#endif-    {-        struct timeval tv;--        gettimeofday(&tv, NULL);-        return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;-    }-}-- ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////  // Initialise timer //-void _glfwInitTimer(void)+void _glfwInitTimerPOSIX(void) { #if defined(CLOCK_MONOTONIC)     struct timespec ts;      if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)     {-        _glfw.posix_time.monotonic = GL_TRUE;-        _glfw.posix_time.resolution = 1e-9;+        _glfw.posix_time.monotonic = GLFW_TRUE;+        _glfw.posix_time.frequency = 1000000000;     }     else #endif     {-        _glfw.posix_time.resolution = 1e-6;+        _glfw.posix_time.monotonic = GLFW_FALSE;+        _glfw.posix_time.frequency = 1000000;     }--    _glfw.posix_time.base = getRawTime(); }  @@ -83,15 +60,26 @@ //////                       GLFW platform API                      ////// ////////////////////////////////////////////////////////////////////////// -double _glfwPlatformGetTime(void)+uint64_t _glfwPlatformGetTimerValue(void) {-    return (double) (getRawTime() - _glfw.posix_time.base) *-        _glfw.posix_time.resolution;+#if defined(CLOCK_MONOTONIC)+    if (_glfw.posix_time.monotonic)+    {+        struct timespec ts;+        clock_gettime(CLOCK_MONOTONIC, &ts);+        return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;+    }+    else+#endif+    {+        struct timeval tv;+        gettimeofday(&tv, NULL);+        return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;+    } } -void _glfwPlatformSetTime(double time)+uint64_t _glfwPlatformGetTimerFrequency(void) {-    _glfw.posix_time.base = getRawTime() --        (uint64_t) (time / _glfw.posix_time.resolution);+    return _glfw.posix_time.frequency; } 
glfw/src/posix_time.h view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 POSIX - www.glfw.org+// GLFW 3.2 POSIX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -25,8 +25,8 @@ // //======================================================================== -#ifndef _posix_time_h_-#define _posix_time_h_+#ifndef _glfw3_posix_time_h_+#define _glfw3_posix_time_h_  #define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimePOSIX posix_time @@ -37,13 +37,12 @@ // typedef struct _GLFWtimePOSIX {-    GLboolean   monotonic;-    double      resolution;-    uint64_t    base;+    GLFWbool    monotonic;+    uint64_t    frequency;  } _GLFWtimePOSIX;  -void _glfwInitTimer(void);+void _glfwInitTimerPOSIX(void); -#endif // _posix_time_h_+#endif // _glfw3_posix_time_h_
glfw/src/posix_tls.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 POSIX - www.glfw.org+// GLFW 3.2 POSIX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -32,32 +32,34 @@ //////                       GLFW internal API                      ////// ////////////////////////////////////////////////////////////////////////// -int _glfwInitTLS(void)+GLFWbool _glfwInitThreadLocalStoragePOSIX(void) {     if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0)     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "POSIX: Failed to create context TLS");-        return GL_FALSE;+        return GLFW_FALSE;     } -    return GL_TRUE;-}--void _glfwTerminateTLS(void)-{-    pthread_key_delete(_glfw.posix_tls.context);+    _glfw.posix_tls.allocated = GLFW_TRUE;+    return GLFW_TRUE; } -void _glfwSetCurrentContext(_GLFWwindow* context)+void _glfwTerminateThreadLocalStoragePOSIX(void) {-    pthread_setspecific(_glfw.posix_tls.context, context);+    if (_glfw.posix_tls.allocated)+        pthread_key_delete(_glfw.posix_tls.context); }   ////////////////////////////////////////////////////////////////////////// //////                       GLFW platform API                      ////// //////////////////////////////////////////////////////////////////////////++void _glfwPlatformSetCurrentContext(_GLFWwindow* context)+{+    pthread_setspecific(_glfw.posix_tls.context, context);+}  _GLFWwindow* _glfwPlatformGetCurrentContext(void) {
glfw/src/posix_tls.h view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 POSIX - www.glfw.org+// GLFW 3.2 POSIX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -25,8 +25,8 @@ // //======================================================================== -#ifndef _posix_tls_h_-#define _posix_tls_h_+#ifndef _glfw3_posix_tls_h_+#define _glfw3_posix_tls_h_  #include <pthread.h> @@ -37,13 +37,13 @@ // typedef struct _GLFWtlsPOSIX {+    GLFWbool        allocated;     pthread_key_t   context;  } _GLFWtlsPOSIX;  -int _glfwInitTLS(void);-void _glfwTerminateTLS(void);-void _glfwSetCurrentContext(_GLFWwindow* context);+GLFWbool _glfwInitThreadLocalStoragePOSIX(void);+void _glfwTerminateThreadLocalStoragePOSIX(void); -#endif // _posix_tls_h_+#endif // _glfw3_posix_tls_h_
+ glfw/src/vulkan.c view
@@ -0,0 +1,302 @@+//========================================================================+// GLFW 3.2 - www.glfw.org+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Marcus Geelnard+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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 <assert.h>+#include <string.h>+#include <stdlib.h>+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW internal API                      //////+//////////////////////////////////////////////////////////////////////////++GLFWbool _glfwInitVulkan(void)+{+    VkResult err;+    VkExtensionProperties* ep;+    uint32_t i, count;++#if !defined(_GLFW_VULKAN_STATIC)+#if defined(_GLFW_WIN32)+    const char* name = "vulkan-1.dll";+#else+    const char* name = "libvulkan.so.1";+#endif++    if (_glfw.vk.available)+        return GLFW_TRUE;++    _glfw.vk.handle = _glfw_dlopen(name);+    if (!_glfw.vk.handle)+        return GLFW_FALSE;++    _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)+        _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");+    if (!_glfw.vk.GetInstanceProcAddr)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Vulkan: Loader does not export vkGetInstanceProcAddr");++        _glfwTerminateVulkan();+        return GLFW_FALSE;+    }++    _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)+        vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");+    if (!_glfw.vk.EnumerateInstanceExtensionProperties)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");++        _glfwTerminateVulkan();+        return GLFW_FALSE;+    }+#endif // _GLFW_VULKAN_STATIC++    err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);+    if (err)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Vulkan: Failed to query instance extension count: %s",+                        _glfwGetVulkanResultString(err));++        _glfwTerminateVulkan();+        return GLFW_FALSE;+    }++    ep = calloc(count, sizeof(VkExtensionProperties));++    err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);+    if (err)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Vulkan: Failed to query instance extensions: %s",+                        _glfwGetVulkanResultString(err));++        free(ep);+        _glfwTerminateVulkan();+        return GLFW_FALSE;+    }++    for (i = 0;  i < count;  i++)+    {+        if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)+            _glfw.vk.KHR_surface = GLFW_TRUE;+        if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)+            _glfw.vk.KHR_win32_surface = GLFW_TRUE;+        if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)+            _glfw.vk.KHR_xlib_surface = GLFW_TRUE;+        if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)+            _glfw.vk.KHR_xcb_surface = GLFW_TRUE;+        if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)+            _glfw.vk.KHR_wayland_surface = GLFW_TRUE;+        if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0)+            _glfw.vk.KHR_mir_surface = GLFW_TRUE;+    }++    free(ep);++    _glfw.vk.available = GLFW_TRUE;++    if (_glfw.vk.KHR_surface)+    {+        _glfw.vk.extensions =+            _glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount);+    }++    return GLFW_TRUE;+}++void _glfwTerminateVulkan(void)+{+    uint32_t i;++    for (i = 0;  i < _glfw.vk.extensionCount;  i++)+        free(_glfw.vk.extensions[i]);+    free(_glfw.vk.extensions);++    if (_glfw.vk.handle)+        _glfw_dlclose(_glfw.vk.handle);+}++const char* _glfwGetVulkanResultString(VkResult result)+{+    switch (result)+    {+        case VK_SUCCESS:+            return "Success";+        case VK_NOT_READY:+            return "A fence or query has not yet completed";+        case VK_TIMEOUT:+            return "A wait operation has not completed in the specified time";+        case VK_EVENT_SET:+            return "An event is signaled";+        case VK_EVENT_RESET:+            return "An event is unsignaled";+        case VK_INCOMPLETE:+            return "A return array was too small for the result";+        case VK_ERROR_OUT_OF_HOST_MEMORY:+            return "A host memory allocation has failed";+        case VK_ERROR_OUT_OF_DEVICE_MEMORY:+            return "A device memory allocation has failed";+        case VK_ERROR_INITIALIZATION_FAILED:+            return "Initialization of an object could not be completed for implementation-specific reasons";+        case VK_ERROR_DEVICE_LOST:+            return "The logical or physical device has been lost";+        case VK_ERROR_MEMORY_MAP_FAILED:+            return "Mapping of a memory object has failed";+        case VK_ERROR_LAYER_NOT_PRESENT:+            return "A requested layer is not present or could not be loaded";+        case VK_ERROR_EXTENSION_NOT_PRESENT:+            return "A requested extension is not supported";+        case VK_ERROR_FEATURE_NOT_PRESENT:+            return "A requested feature is not supported";+        case VK_ERROR_INCOMPATIBLE_DRIVER:+            return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";+        case VK_ERROR_TOO_MANY_OBJECTS:+            return "Too many objects of the type have already been created";+        case VK_ERROR_FORMAT_NOT_SUPPORTED:+            return "A requested format is not supported on this device";+        case VK_ERROR_SURFACE_LOST_KHR:+            return "A surface is no longer available";+        case VK_SUBOPTIMAL_KHR:+            return "A swapchain no longer matches the surface properties exactly, but can still be used";+        case VK_ERROR_OUT_OF_DATE_KHR:+            return "A surface has changed in such a way that it is no longer compatible with the swapchain";+        case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:+            return "The display used by a swapchain does not use the same presentable image layout";+        case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:+            return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";+        case VK_ERROR_VALIDATION_FAILED_EXT:+            return "A validation layer found an error";+        default:+            return "ERROR: UNKNOWN VULKAN ERROR";+    }+}+++//////////////////////////////////////////////////////////////////////////+//////                        GLFW public API                       //////+//////////////////////////////////////////////////////////////////////////++GLFWAPI int glfwVulkanSupported(void)+{+    _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);+    return _glfwInitVulkan();+}++GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)+{+    *count = 0;++    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++    if (!_glfwInitVulkan())+    {+        _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");+        return NULL;+    }++    *count = _glfw.vk.extensionCount;+    return (const char**) _glfw.vk.extensions;+}++GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,+                                              const char* procname)+{+    GLFWvkproc proc;++    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++    if (!_glfwInitVulkan())+    {+        _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");+        return NULL;+    }++    proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);+    if (!proc)+        proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);++    return proc;+}++GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,+                                                     VkPhysicalDevice device,+                                                     uint32_t queuefamily)+{+    _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);++    if (!_glfwInitVulkan())+    {+        _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");+        return GLFW_FALSE;+    }++    if (!_glfw.vk.extensions)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Vulkan: Window surface creation extensions not found");+        return GLFW_FALSE;+    }++    return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,+                                                             device,+                                                             queuefamily);+}++GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,+                                         GLFWwindow* handle,+                                         const VkAllocationCallbacks* allocator,+                                         VkSurfaceKHR* surface)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+    assert(surface != NULL);++    *surface = VK_NULL_HANDLE;++    _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);++    if (!_glfwInitVulkan())+    {+        _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");+        return VK_ERROR_INITIALIZATION_FAILED;+    }++    if (!_glfw.vk.extensions)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Vulkan: Window surface creation extensions not found");+        return VK_ERROR_EXTENSION_NOT_PRESENT;+    }++    return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface);+}+
glfw/src/wgl_context.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 WGL - www.glfw.org+// GLFW 3.2 WGL - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -32,111 +32,21 @@ #include <assert.h>  -// 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(_GLFWwindow* window)-{-    // This needs to include every function pointer loaded below-    window->wgl.SwapIntervalEXT = NULL;-    window->wgl.GetPixelFormatAttribivARB = NULL;-    window->wgl.GetExtensionsStringARB = NULL;-    window->wgl.GetExtensionsStringEXT = NULL;-    window->wgl.CreateContextAttribsARB = NULL;--    // This needs to include every extension used below except for-    // WGL_ARB_extensions_string and WGL_EXT_extensions_string-    window->wgl.ARB_multisample = GL_FALSE;-    window->wgl.ARB_framebuffer_sRGB = GL_FALSE;-    window->wgl.ARB_create_context = GL_FALSE;-    window->wgl.ARB_create_context_profile = GL_FALSE;-    window->wgl.EXT_create_context_es2_profile = GL_FALSE;-    window->wgl.ARB_create_context_robustness = GL_FALSE;-    window->wgl.EXT_swap_control = GL_FALSE;-    window->wgl.ARB_pixel_format = GL_FALSE;-    window->wgl.ARB_context_flush_control = GL_FALSE;--    window->wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)-        wglGetProcAddress("wglGetExtensionsStringEXT");-    if (!window->wgl.GetExtensionsStringEXT)-    {-        window->wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)-            wglGetProcAddress("wglGetExtensionsStringARB");-        if (!window->wgl.GetExtensionsStringARB)-            return;-    }--    if (_glfwPlatformExtensionSupported("WGL_ARB_multisample"))-        window->wgl.ARB_multisample = GL_TRUE;--    if (_glfwPlatformExtensionSupported("WGL_ARB_framebuffer_sRGB"))-        window->wgl.ARB_framebuffer_sRGB = GL_TRUE;--    if (_glfwPlatformExtensionSupported("WGL_ARB_create_context"))-    {-        window->wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)-            wglGetProcAddress("wglCreateContextAttribsARB");--        if (window->wgl.CreateContextAttribsARB)-            window->wgl.ARB_create_context = GL_TRUE;-    }--    if (window->wgl.ARB_create_context)-    {-        if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_profile"))-            window->wgl.ARB_create_context_profile = GL_TRUE;-    }--    if (window->wgl.ARB_create_context &&-        window->wgl.ARB_create_context_profile)-    {-        if (_glfwPlatformExtensionSupported("WGL_EXT_create_context_es2_profile"))-            window->wgl.EXT_create_context_es2_profile = GL_TRUE;-    }--    if (window->wgl.ARB_create_context)-    {-        if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_robustness"))-            window->wgl.ARB_create_context_robustness = GL_TRUE;-    }--    if (_glfwPlatformExtensionSupported("WGL_EXT_swap_control"))-    {-        window->wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)-            wglGetProcAddress("wglSwapIntervalEXT");--        if (window->wgl.SwapIntervalEXT)-            window->wgl.EXT_swap_control = GL_TRUE;-    }--    if (_glfwPlatformExtensionSupported("WGL_ARB_pixel_format"))-    {-        window->wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)-            wglGetProcAddress("wglGetPixelFormatAttribivARB");--        if (window->wgl.GetPixelFormatAttribivARB)-            window->wgl.ARB_pixel_format = GL_TRUE;-    }--    if (_glfwPlatformExtensionSupported("WGL_ARB_context_flush_control"))-        window->wgl.ARB_context_flush_control = GL_TRUE;-}- // Returns the specified attribute of the specified pixel format-// NOTE: Do not call this unless we have found WGL_ARB_pixel_format // static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) {     int value = 0; -    if (!window->wgl.GetPixelFormatAttribivARB(window->wgl.dc,-                                               pixelFormat,-                                               0, 1, &attrib, &value))+    assert(_glfw.wgl.ARB_pixel_format);++    if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,+                                             pixelFormat,+                                             0, 1, &attrib, &value))     {-        // NOTE: We should probably handle this error somehow+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "WGL: Failed to retrieve pixel format attribute %i",+                        attrib);         return 0;     } @@ -145,34 +55,26 @@  // Return a list of available and usable framebuffer configs //-static GLboolean choosePixelFormat(_GLFWwindow* window,-                                   const _GLFWfbconfig* desired,-                                   int* result)+static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired) {     _GLFWfbconfig* usableConfigs;     const _GLFWfbconfig* closest;-    int i, nativeCount, usableCount;+    int i, pixelFormat, nativeCount, usableCount; -    if (window->wgl.ARB_pixel_format)+    if (_glfw.wgl.ARB_pixel_format)     {         nativeCount = getPixelFormatAttrib(window,-                                         1,-                                         WGL_NUMBER_PIXEL_FORMATS_ARB);+                                           1,+                                           WGL_NUMBER_PIXEL_FORMATS_ARB);     }     else     {-        nativeCount = DescribePixelFormat(window->wgl.dc,+        nativeCount = DescribePixelFormat(window->context.wgl.dc,                                           1,                                           sizeof(PIXELFORMATDESCRIPTOR),                                           NULL);     } -    if (!nativeCount)-    {-        _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: No pixel formats found");-        return GL_FALSE;-    }-     usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));     usableCount = 0; @@ -181,9 +83,10 @@         const int n = i + 1;         _GLFWfbconfig* u = usableConfigs + usableCount; -        if (window->wgl.ARB_pixel_format)+        if (_glfw.wgl.ARB_pixel_format)         {-            // Get pixel format attributes through WGL_ARB_pixel_format+            // Get pixel format attributes through "modern" extension+             if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) ||                 !getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB))             {@@ -218,26 +121,27 @@             u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB);              if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB))-                u->stereo = GL_TRUE;+                u->stereo = GLFW_TRUE;             if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB))-                u->doublebuffer = GL_TRUE;+                u->doublebuffer = GLFW_TRUE; -            if (window->wgl.ARB_multisample)+            if (_glfw.wgl.ARB_multisample)                 u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB); -            if (window->wgl.ARB_framebuffer_sRGB)+            if (_glfw.wgl.ARB_framebuffer_sRGB ||+                _glfw.wgl.EXT_framebuffer_sRGB)             {                 if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))-                    u->sRGB = GL_TRUE;+                    u->sRGB = GLFW_TRUE;             }         }         else         {             PIXELFORMATDESCRIPTOR pfd; -            // Get pixel format attributes through old-fashioned PFDs+            // Get pixel format attributes through legacy PFDs -            if (!DescribePixelFormat(window->wgl.dc,+            if (!DescribePixelFormat(window->context.wgl.dc,                                      n,                                      sizeof(PIXELFORMATDESCRIPTOR),                                      &pfd))@@ -276,12 +180,12 @@             u->auxBuffers = pfd.cAuxBuffers;              if (pfd.dwFlags & PFD_STEREO)-                u->stereo = GL_TRUE;+                u->stereo = GLFW_TRUE;             if (pfd.dwFlags & PFD_DOUBLEBUFFER)-                u->doublebuffer = GL_TRUE;+                u->doublebuffer = GLFW_TRUE;         } -        u->wgl = n;+        u->handle = n;         usableCount++;     } @@ -291,55 +195,267 @@                         "WGL: The driver does not appear to support OpenGL");          free(usableConfigs);-        return GL_FALSE;+        return 0;     }      closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);     if (!closest)     {-        _glfwInputError(GLFW_PLATFORM_ERROR,+        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,                         "WGL: Failed to find a suitable pixel format");          free(usableConfigs);-        return GL_FALSE;+        return 0;     } -    *result = closest->wgl;+    pixelFormat = (int) closest->handle;     free(usableConfigs); -    return GL_TRUE;+    return pixelFormat; } +// Returns whether desktop compositing is enabled+//+static GLFWbool isCompositionEnabled(void)+{+    BOOL enabled; +    if (!_glfw_DwmIsCompositionEnabled)+        return FALSE;++    if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK)+        return FALSE;++    return enabled;+}++static void makeContextCurrentWGL(_GLFWwindow* window)+{+    if (window)+    {+        if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))+            _glfwPlatformSetCurrentContext(window);+        else+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "WGL: Failed to make context current");+            _glfwPlatformSetCurrentContext(NULL);+        }+    }+    else+    {+        if (!wglMakeCurrent(NULL, NULL))+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "WGL: Failed to clear current context");+        }++        _glfwPlatformSetCurrentContext(NULL);+    }+}++static void swapBuffersWGL(_GLFWwindow* window)+{+    // HACK: Use DwmFlush when desktop composition is enabled+    if (isCompositionEnabled() && !window->monitor)+    {+        int count = abs(window->context.wgl.interval);+        while (count--)+            _glfw_DwmFlush();+    }++    SwapBuffers(window->context.wgl.dc);+}++static void swapIntervalWGL(int interval)+{+    _GLFWwindow* window = _glfwPlatformGetCurrentContext();++    window->context.wgl.interval = interval;++    // HACK: Disable WGL swap interval when desktop composition is enabled to+    //       avoid interfering with DWM vsync+    if (isCompositionEnabled() && !window->monitor)+        interval = 0;++    if (_glfw.wgl.EXT_swap_control)+        _glfw.wgl.SwapIntervalEXT(interval);+}++static int extensionSupportedWGL(const char* extension)+{+    const char* extensions;++    if (_glfw.wgl.GetExtensionsStringEXT)+    {+        extensions = _glfw.wgl.GetExtensionsStringEXT();+        if (extensions)+        {+            if (_glfwStringInExtensionString(extension, extensions))+                return GLFW_TRUE;+        }+    }++    if (_glfw.wgl.GetExtensionsStringARB)+    {+        extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());+        if (extensions)+        {+            if (_glfwStringInExtensionString(extension, extensions))+                return GLFW_TRUE;+        }+    }++    return GLFW_FALSE;+}++static GLFWglproc getProcAddressWGL(const char* procname)+{+    const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);+    if (proc)+        return proc;++    return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);+}++// Destroy the OpenGL context+//+static void destroyContextWGL(_GLFWwindow* window)+{+    if (window->context.wgl.handle)+    {+        wglDeleteContext(window->context.wgl.handle);+        window->context.wgl.handle = NULL;+    }+}++// Initialize WGL-specific extensions+//+static void loadWGLExtensions(void)+{+    PIXELFORMATDESCRIPTOR pfd;+    HGLRC rc;+    HDC dc = GetDC(_glfw.win32.helperWindowHandle);;++    _glfw.wgl.extensionsLoaded = GLFW_TRUE;++    // NOTE: A dummy context has to be created for opengl32.dll to load the+    //       OpenGL ICD, from which we can then query WGL extensions+    // NOTE: This code will accept the Microsoft GDI ICD; accelerated context+    //       creation failure occurs during manual pixel format enumeration++    ZeroMemory(&pfd, sizeof(pfd));+    pfd.nSize = sizeof(pfd);+    pfd.nVersion = 1;+    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;+    pfd.iPixelType = PFD_TYPE_RGBA;+    pfd.cColorBits = 24;++    if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "WGL: Failed to set pixel format for dummy context");+        return;+    }++    rc = wglCreateContext(dc);+    if (!rc)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "WGL: Failed to create dummy context");+        return;+    }++    if (!wglMakeCurrent(dc, rc))+    {+        wglDeleteContext(rc);++        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "WGL: Failed to make dummy context current");+        return;+    }++    // NOTE: Functions must be loaded first as they're needed to retrieve the+    //       extension string that tells us whether the functions are supported+    _glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)+        wglGetProcAddress("wglGetExtensionsStringEXT");+    _glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)+        wglGetProcAddress("wglGetExtensionsStringARB");+    _glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)+        wglGetProcAddress("wglCreateContextAttribsARB");+    _glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)+        wglGetProcAddress("wglSwapIntervalEXT");+    _glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)+        wglGetProcAddress("wglGetPixelFormatAttribivARB");++    // NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not+    //       checked below as we are already using them+    _glfw.wgl.ARB_multisample =+        extensionSupportedWGL("WGL_ARB_multisample");+    _glfw.wgl.ARB_framebuffer_sRGB =+        extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");+    _glfw.wgl.EXT_framebuffer_sRGB =+        extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");+    _glfw.wgl.ARB_create_context =+        extensionSupportedWGL("WGL_ARB_create_context");+    _glfw.wgl.ARB_create_context_profile =+        extensionSupportedWGL("WGL_ARB_create_context_profile");+    _glfw.wgl.EXT_create_context_es2_profile =+        extensionSupportedWGL("WGL_EXT_create_context_es2_profile");+    _glfw.wgl.ARB_create_context_robustness =+        extensionSupportedWGL("WGL_ARB_create_context_robustness");+    _glfw.wgl.EXT_swap_control =+        extensionSupportedWGL("WGL_EXT_swap_control");+    _glfw.wgl.ARB_pixel_format =+        extensionSupportedWGL("WGL_ARB_pixel_format");+    _glfw.wgl.ARB_context_flush_control =+        extensionSupportedWGL("WGL_ARB_context_flush_control");++    wglMakeCurrent(dc, NULL);+    wglDeleteContext(rc);+}++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////  // Initialize WGL //-int _glfwInitContextAPI(void)+GLFWbool _glfwInitWGL(void) {-    if (!_glfwInitTLS())-        return GL_FALSE;+    if (_glfw.wgl.instance)+        return GLFW_TRUE; -    _glfw.wgl.opengl32.instance = LoadLibraryW(L"opengl32.dll");-    if (!_glfw.wgl.opengl32.instance)+    _glfw.wgl.instance = LoadLibraryA("opengl32.dll");+    if (!_glfw.wgl.instance)     {-        _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to load opengl32.dll");-        return GL_FALSE;+        _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to load opengl32.dll");+        return GLFW_FALSE;     } -    return GL_TRUE;+    _glfw.wgl.CreateContext = (WGLCREATECONTEXT_T)+        GetProcAddress(_glfw.wgl.instance, "wglCreateContext");+    _glfw.wgl.DeleteContext = (WGLDELETECONTEXT_T)+        GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");+    _glfw.wgl.GetProcAddress = (WGLGETPROCADDRESS_T)+        GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");+    _glfw.wgl.GetCurrentDC = (WGLGETCURRENTDC_T)+        GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");+    _glfw.wgl.MakeCurrent = (WGLMAKECURRENT_T)+        GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");+    _glfw.wgl.ShareLists = (WGLSHARELISTS_T)+        GetProcAddress(_glfw.wgl.instance, "wglShareLists");++    return GLFW_TRUE; }  // Terminate WGL //-void _glfwTerminateContextAPI(void)+void _glfwTerminateWGL(void) {-    if (_glfw.wgl.opengl32.instance)-        FreeLibrary(_glfw.wgl.opengl32.instance);--    _glfwTerminateTLS();+    if (_glfw.wgl.instance)+        FreeLibrary(_glfw.wgl.instance); }  #define setWGLattrib(attribName, attribValue) \@@ -351,75 +467,118 @@  // Create the OpenGL or OpenGL ES context //-int _glfwCreateContext(_GLFWwindow* window,-                       const _GLFWctxconfig* ctxconfig,-                       const _GLFWfbconfig* fbconfig)+GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,+                               const _GLFWctxconfig* ctxconfig,+                               const _GLFWfbconfig* fbconfig) {     int attribs[40];-    int pixelFormat = 0;+    int pixelFormat;     PIXELFORMATDESCRIPTOR pfd;     HGLRC share = NULL; +    if (!_glfw.wgl.extensionsLoaded)+        loadWGLExtensions();+     if (ctxconfig->share)-        share = ctxconfig->share->wgl.context;+        share = ctxconfig->share->context.wgl.handle; -    window->wgl.dc = GetDC(window->win32.handle);-    if (!window->wgl.dc)+    window->context.wgl.dc = GetDC(window->win32.handle);+    if (!window->context.wgl.dc)     {         _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to retrieve DC for window");-        return GL_FALSE;+                        "WGL: Failed to retrieve DC for window");+        return GLFW_FALSE;     } -    if (!choosePixelFormat(window, fbconfig, &pixelFormat))-        return GL_FALSE;+    pixelFormat = choosePixelFormat(window, fbconfig);+    if (!pixelFormat)+        return GLFW_FALSE; -    if (!DescribePixelFormat(window->wgl.dc, pixelFormat, sizeof(pfd), &pfd))+    if (!DescribePixelFormat(window->context.wgl.dc,+                             pixelFormat, sizeof(pfd), &pfd))     {         _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to retrieve PFD for selected pixel "-                        "format");-        return GL_FALSE;+                        "WGL: Failed to retrieve PFD for selected pixel format");+        return GLFW_FALSE;     } -    if (!SetPixelFormat(window->wgl.dc, pixelFormat, &pfd))+    if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))     {         _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to set selected pixel format");-        return GL_FALSE;+                        "WGL: Failed to set selected pixel format");+        return GLFW_FALSE;     } -    if (window->wgl.ARB_create_context)+    if (ctxconfig->client == GLFW_OPENGL_API)     {-        int index = 0, mask = 0, flags = 0, strategy = 0;+        if (ctxconfig->forward)+        {+            if (!_glfw.wgl.ARB_create_context)+            {+                _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                                "WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");+                return GLFW_FALSE;+            }+        } -        if (ctxconfig->api == GLFW_OPENGL_API)+        if (ctxconfig->profile)         {+            if (!_glfw.wgl.ARB_create_context_profile)+            {+                _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                                "WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");+                return GLFW_FALSE;+            }+        }+    }+    else+    {+        if (!_glfw.wgl.ARB_create_context ||+            !_glfw.wgl.ARB_create_context_profile ||+            !_glfw.wgl.EXT_create_context_es2_profile)+        {+            _glfwInputError(GLFW_API_UNAVAILABLE,+                            "WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");+            return GLFW_FALSE;+        }+    }++    if (_glfw.wgl.ARB_create_context)+    {+        int index = 0, mask = 0, flags = 0;++        if (ctxconfig->client == GLFW_OPENGL_API)+        {             if (ctxconfig->forward)                 flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; -            if (ctxconfig->debug)-                flags |= WGL_CONTEXT_DEBUG_BIT_ARB;--            if (ctxconfig->profile)-            {-                if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)-                    mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;-                else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)-                    mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;-            }+            if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)+                mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;+            else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)+                mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;         }         else             mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT; +        if (ctxconfig->debug)+            flags |= WGL_CONTEXT_DEBUG_BIT_ARB;+        if (ctxconfig->noerror)+            flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;+         if (ctxconfig->robustness)         {-            if (window->wgl.ARB_create_context_robustness)+            if (_glfw.wgl.ARB_create_context_robustness)             {                 if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)-                    strategy = WGL_NO_RESET_NOTIFICATION_ARB;+                {+                    setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,+                                 WGL_NO_RESET_NOTIFICATION_ARB);+                }                 else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)-                    strategy = WGL_LOSE_CONTEXT_ON_RESET_ARB;+                {+                    setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,+                                 WGL_LOSE_CONTEXT_ON_RESET_ARB);+                }                  flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;             }@@ -427,7 +586,7 @@          if (ctxconfig->release)         {-            if (window->wgl.ARB_context_flush_control)+            if (_glfw.wgl.ARB_context_flush_control)             {                 if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)                 {@@ -442,12 +601,11 @@             }         } +        // NOTE: Only request an explicitly versioned context when necessary, as+        //       explicitly requesting version 1.0 does not always return the+        //       highest version supported by the driver         if (ctxconfig->major != 1 || ctxconfig->minor != 0)         {-            // NOTE: Only request an explicitly versioned context when-            //       necessary, as explicitly requesting version 1.0 does not-            //       always return the highest available version-             setWGLattrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);             setWGLattrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);         }@@ -458,242 +616,86 @@         if (mask)             setWGLattrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); -        if (strategy)-            setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy);-         setWGLattrib(0, 0); -        window->wgl.context = window->wgl.CreateContextAttribsARB(window->wgl.dc,-                                                                  share,-                                                                  attribs);-        if (!window->wgl.context)-        {-            _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                            "WGL: Failed to create OpenGL context");-            return GL_FALSE;-        }-    }-    else-    {-        window->wgl.context = wglCreateContext(window->wgl.dc);-        if (!window->wgl.context)+        window->context.wgl.handle =+            _glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,+                                              share, attribs);+        if (!window->context.wgl.handle)         {-            _glfwInputError(GLFW_PLATFORM_ERROR,-                            "WGL: Failed to create OpenGL context");-            return GL_FALSE;-        }+            const DWORD error = GetLastError(); -        if (share)-        {-            if (!wglShareLists(share, window->wgl.context))+            if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))             {-                _glfwInputError(GLFW_PLATFORM_ERROR,-                                "WGL: Failed to enable sharing with specified "-                                "OpenGL context");-                return GL_FALSE;+                if (ctxconfig->client == GLFW_OPENGL_API)+                {+                    _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                                    "WGL: Driver does not support OpenGL version %i.%i",+                                    ctxconfig->major,+                                    ctxconfig->minor);+                }+                else+                {+                    _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                                    "WGL: Driver does not support OpenGL ES version %i.%i",+                                    ctxconfig->major,+                                    ctxconfig->minor);+                }             }-        }-    }--    _glfwPlatformMakeContextCurrent(window);-    initWGLExtensions(window);--    return GL_TRUE;-}--#undef setWGLattrib--// Destroy the OpenGL context-//-void _glfwDestroyContext(_GLFWwindow* window)-{-    if (window->wgl.context)-    {-        wglDeleteContext(window->wgl.context);-        window->wgl.context = NULL;-    }--    if (window->wgl.dc)-    {-        ReleaseDC(window->win32.handle, window->wgl.dc);-        window->wgl.dc = NULL;-    }-}--// Analyzes the specified context for possible recreation-//-int _glfwAnalyzeContext(const _GLFWwindow* window,-                        const _GLFWctxconfig* ctxconfig,-                        const _GLFWfbconfig* fbconfig)-{-    GLboolean required = GL_FALSE;--    if (ctxconfig->api == GLFW_OPENGL_API)-    {-        if (ctxconfig->forward)-        {-            if (!window->wgl.ARB_create_context)+            else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))             {                 _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                                "WGL: A forward compatible OpenGL context "-                                "requested but WGL_ARB_create_context is "-                                "unavailable");-                return _GLFW_RECREATION_IMPOSSIBLE;+                                "WGL: Driver does not support the requested OpenGL profile");             }--            required = GL_TRUE;-        }--        if (ctxconfig->profile)-        {-            if (!window->wgl.ARB_create_context_profile)+            else             {-                _glfwInputError(GLFW_VERSION_UNAVAILABLE,-                                "WGL: OpenGL profile requested but "-                                "WGL_ARB_create_context_profile is unavailable");-                return _GLFW_RECREATION_IMPOSSIBLE;+                if (ctxconfig->client == GLFW_OPENGL_API)+                {+                    _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                                    "WGL: Failed to create OpenGL context");+                }+                else+                {+                    _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                                    "WGL: Failed to create OpenGL ES context");+                }             } -            required = GL_TRUE;-        }--        if (ctxconfig->release)-        {-            if (window->wgl.ARB_context_flush_control)-                required = GL_TRUE;+            return GLFW_FALSE;         }     }     else     {-        if (!window->wgl.ARB_create_context ||-            !window->wgl.ARB_create_context_profile ||-            !window->wgl.EXT_create_context_es2_profile)+        window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);+        if (!window->context.wgl.handle)         {-            _glfwInputError(GLFW_API_UNAVAILABLE,-                            "WGL: OpenGL ES requested but "-                            "WGL_ARB_create_context_es2_profile is unavailable");-            return _GLFW_RECREATION_IMPOSSIBLE;+            _glfwInputError(GLFW_VERSION_UNAVAILABLE,+                            "WGL: Failed to create OpenGL context");+            return GLFW_FALSE;         } -        required = GL_TRUE;-    }--    if (ctxconfig->major != 1 || ctxconfig->minor != 0)-    {-        if (window->wgl.ARB_create_context)-            required = GL_TRUE;-    }--    if (ctxconfig->debug)-    {-        if (window->wgl.ARB_create_context)-            required = GL_TRUE;-    }--    if (fbconfig->samples > 0)-    {-        // We want FSAA, but can we get it?-        // FSAA is not a hard constraint, so otherwise we just don't care--        if (window->wgl.ARB_multisample && window->wgl.ARB_pixel_format)-        {-            // We appear to have both the extension and the means to ask for it-            required = GL_TRUE;-        }-    }--    if (fbconfig->sRGB)-    {-        // We want sRGB, but can we get it?-        // sRGB is not a hard constraint, so otherwise we just don't care--        if (window->wgl.ARB_framebuffer_sRGB && window->wgl.ARB_pixel_format)-        {-            // We appear to have both the extension and the means to ask for it-            required = GL_TRUE;-        }-    }--    if (required)-        return _GLFW_RECREATION_REQUIRED;--    return _GLFW_RECREATION_NOT_NEEDED;-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////--void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)-{-    if (window)-        wglMakeCurrent(window->wgl.dc, window->wgl.context);-    else-        wglMakeCurrent(NULL, NULL);--    _glfwSetCurrentContext(window);-}--void _glfwPlatformSwapBuffers(_GLFWwindow* window)-{-    SwapBuffers(window->wgl.dc);-}--void _glfwPlatformSwapInterval(int interval)-{-    _GLFWwindow* window = _glfwPlatformGetCurrentContext();--#if !defined(_GLFW_USE_DWM_SWAP_INTERVAL)-    if (_glfwIsCompositionEnabled() && interval)-    {-        // Don't enabled vsync when desktop compositing is enabled, as it leads-        // to frame jitter-        return;-    }-#endif--    if (window->wgl.EXT_swap_control)-        window->wgl.SwapIntervalEXT(interval);-}--int _glfwPlatformExtensionSupported(const char* extension)-{-    const GLubyte* extensions;--    _GLFWwindow* window = _glfwPlatformGetCurrentContext();--    if (window->wgl.GetExtensionsStringEXT != NULL)-    {-        extensions = (GLubyte*) window->wgl.GetExtensionsStringEXT();-        if (extensions != NULL)+        if (share)         {-            if (_glfwStringInExtensionString(extension, extensions))-                return GL_TRUE;+            if (!wglShareLists(share, window->context.wgl.handle))+            {+                _glfwInputError(GLFW_PLATFORM_ERROR,+                                "WGL: Failed to enable sharing with specified OpenGL context");+                return GLFW_FALSE;+            }         }     } -    if (window->wgl.GetExtensionsStringARB != NULL)-    {-        extensions = (GLubyte*) window->wgl.GetExtensionsStringARB(window->wgl.dc);-        if (extensions != NULL)-        {-            if (_glfwStringInExtensionString(extension, extensions))-                return GL_TRUE;-        }-    }+    window->context.makeCurrent = makeContextCurrentWGL;+    window->context.swapBuffers = swapBuffersWGL;+    window->context.swapInterval = swapIntervalWGL;+    window->context.extensionSupported = extensionSupportedWGL;+    window->context.getProcAddress = getProcAddressWGL;+    window->context.destroy = destroyContextWGL; -    return GL_FALSE;+    return GLFW_TRUE; } -GLFWglproc _glfwPlatformGetProcAddress(const char* procname)-{-    const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);-    if (proc)-        return proc;--    return (GLFWglproc) GetProcAddress(_glfw.wgl.opengl32.instance, procname);-}+#undef setWGLattrib   //////////////////////////////////////////////////////////////////////////@@ -704,6 +706,13 @@ {     _GLFWwindow* window = (_GLFWwindow*) handle;     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);-    return window->wgl.context;++    if (window->context.client == GLFW_NO_API)+    {+        _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);+        return NULL;+    }++    return window->context.wgl.handle; } 
glfw/src/wgl_context.h view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 WGL - www.glfw.org+// GLFW 3.2 WGL - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -25,15 +25,82 @@ // //======================================================================== -#ifndef _wgl_context_h_-#define _wgl_context_h_+#ifndef _glfw3_wgl_context_h_+#define _glfw3_wgl_context_h_ -// This path may need to be changed if you build GLFW using your own setup-// We ship and use our own copy of wglext.h since GLFW uses fairly new-// extensions and not all operating systems come with an up-to-date version-#include "../deps/GL/wglext.h" -#define _GLFW_PLATFORM_FBCONFIG                 int             wgl+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000+#define WGL_SUPPORT_OPENGL_ARB 0x2010+#define WGL_DRAW_TO_WINDOW_ARB 0x2001+#define WGL_PIXEL_TYPE_ARB 0x2013+#define WGL_TYPE_RGBA_ARB 0x202b+#define WGL_ACCELERATION_ARB 0x2003+#define WGL_NO_ACCELERATION_ARB 0x2025+#define WGL_RED_BITS_ARB 0x2015+#define WGL_RED_SHIFT_ARB 0x2016+#define WGL_GREEN_BITS_ARB 0x2017+#define WGL_GREEN_SHIFT_ARB 0x2018+#define WGL_BLUE_BITS_ARB 0x2019+#define WGL_BLUE_SHIFT_ARB 0x201a+#define WGL_ALPHA_BITS_ARB 0x201b+#define WGL_ALPHA_SHIFT_ARB 0x201c+#define WGL_ACCUM_BITS_ARB 0x201d+#define WGL_ACCUM_RED_BITS_ARB 0x201e+#define WGL_ACCUM_GREEN_BITS_ARB 0x201f+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021+#define WGL_DEPTH_BITS_ARB 0x2022+#define WGL_STENCIL_BITS_ARB 0x2023+#define WGL_AUX_BUFFERS_ARB 0x2024+#define WGL_STEREO_ARB 0x2012+#define WGL_DOUBLE_BUFFER_ARB 0x2011+#define WGL_SAMPLES_ARB 0x2042+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092+#define WGL_CONTEXT_FLAGS_ARB 0x2094+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261+#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097+#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0+#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098++#define ERROR_INVALID_VERSION_ARB 0x2095+#define ERROR_INVALID_PROFILE_ARB 0x2096++typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);+typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);+typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);++typedef HGLRC (WINAPI * WGLCREATECONTEXT_T)(HDC);+typedef BOOL (WINAPI * WGLDELETECONTEXT_T)(HGLRC);+typedef PROC (WINAPI * WGLGETPROCADDRESS_T)(LPCSTR);+typedef HDC (WINAPI * WGLGETCURRENTDC_T)(void);+typedef BOOL (WINAPI * WGLMAKECURRENT_T)(HDC,HGLRC);+typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,HGLRC);++// opengl32.dll function pointer typedefs+#define wglCreateContext _glfw.wgl.CreateContext+#define wglDeleteContext _glfw.wgl.DeleteContext+#define wglGetProcAddress _glfw.wgl.GetProcAddress+#define wglGetCurrentDC _glfw.wgl.GetCurrentDC+#define wglMakeCurrent _glfw.wgl.MakeCurrent+#define wglShareLists _glfw.wgl.ShareLists++#define _GLFW_RECREATION_NOT_NEEDED 0+#define _GLFW_RECREATION_REQUIRED   1+#define _GLFW_RECREATION_IMPOSSIBLE 2+ #define _GLFW_PLATFORM_CONTEXT_STATE            _GLFWcontextWGL wgl #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE    _GLFWlibraryWGL wgl @@ -42,48 +109,49 @@ // typedef struct _GLFWcontextWGL {-    HDC       dc;              // Private GDI device context-    HGLRC     context;         // Permanent rendering context--    // WGL extensions (context specific)-    PFNWGLSWAPINTERVALEXTPROC           SwapIntervalEXT;-    PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;-    PFNWGLGETEXTENSIONSSTRINGEXTPROC    GetExtensionsStringEXT;-    PFNWGLGETEXTENSIONSSTRINGARBPROC    GetExtensionsStringARB;-    PFNWGLCREATECONTEXTATTRIBSARBPROC   CreateContextAttribsARB;-    GLboolean                           EXT_swap_control;-    GLboolean                           ARB_multisample;-    GLboolean                           ARB_framebuffer_sRGB;-    GLboolean                           ARB_pixel_format;-    GLboolean                           ARB_create_context;-    GLboolean                           ARB_create_context_profile;-    GLboolean                           EXT_create_context_es2_profile;-    GLboolean                           ARB_create_context_robustness;-    GLboolean                           ARB_context_flush_control;+    HDC       dc;+    HGLRC     handle;+    int       interval;  } _GLFWcontextWGL; - // WGL-specific global data // typedef struct _GLFWlibraryWGL {-    // opengl32.dll (for glfwGetProcAddress)-    struct {-        HINSTANCE   instance;-    } opengl32;+    HINSTANCE                           instance;+    WGLCREATECONTEXT_T                  CreateContext;+    WGLDELETECONTEXT_T                  DeleteContext;+    WGLGETPROCADDRESS_T                 GetProcAddress;+    WGLGETCURRENTDC_T                   GetCurrentDC;+    WGLMAKECURRENT_T                    MakeCurrent;+    WGLSHARELISTS_T                     ShareLists; +    GLFWbool                            extensionsLoaded;++    PFNWGLSWAPINTERVALEXTPROC           SwapIntervalEXT;+    PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;+    PFNWGLGETEXTENSIONSSTRINGEXTPROC    GetExtensionsStringEXT;+    PFNWGLGETEXTENSIONSSTRINGARBPROC    GetExtensionsStringARB;+    PFNWGLCREATECONTEXTATTRIBSARBPROC   CreateContextAttribsARB;+    GLFWbool                            EXT_swap_control;+    GLFWbool                            ARB_multisample;+    GLFWbool                            ARB_framebuffer_sRGB;+    GLFWbool                            EXT_framebuffer_sRGB;+    GLFWbool                            ARB_pixel_format;+    GLFWbool                            ARB_create_context;+    GLFWbool                            ARB_create_context_profile;+    GLFWbool                            EXT_create_context_es2_profile;+    GLFWbool                            ARB_create_context_robustness;+    GLFWbool                            ARB_context_flush_control;+ } _GLFWlibraryWGL;  -int _glfwInitContextAPI(void);-void _glfwTerminateContextAPI(void);-int _glfwCreateContext(_GLFWwindow* window,-                       const _GLFWctxconfig* ctxconfig,-                       const _GLFWfbconfig* fbconfig);-void _glfwDestroyContext(_GLFWwindow* window);-int _glfwAnalyzeContext(const _GLFWwindow* window,-                        const _GLFWctxconfig* ctxconfig,-                        const _GLFWfbconfig* fbconfig);+GLFWbool _glfwInitWGL(void);+void _glfwTerminateWGL(void);+GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,+                               const _GLFWctxconfig* ctxconfig,+                               const _GLFWfbconfig* fbconfig); -#endif // _wgl_context_h_+#endif // _glfw3_wgl_context_h_
glfw/src/win32_init.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 Win32 - www.glfw.org+// GLFW 3.2 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -30,20 +30,24 @@ #include <stdlib.h> #include <malloc.h> -#ifdef __BORLANDC__-// With the Borland C++ compiler, we want to disable FPU exceptions-#include <float.h>-#endif // __BORLANDC__+#include <initguid.h>+DEFINE_GUID(GUID_DEVINTERFACE_HID,0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30); +#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) -#if defined(_GLFW_USE_OPTIMUS_HPG)+// Applications exporting this symbol with this value will be automatically+// directed to the high-performance GPU on Nvidia Optimus systems with+// up-to-date drivers+//+__declspec(dllexport) DWORD NvOptimusEnablement = 1;  // Applications exporting this symbol with this value will be automatically-// directed to the high-performance GPU on Nvidia Optimus systems+// directed to the high-performance GPU on AMD PowerXpress systems with+// up-to-date drivers //-__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;+__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; -#endif // _GLFW_USE_OPTIMUS_HPG+#endif // _GLFW_USE_HYBRID_HPG  #if defined(_GLFW_BUILD_DLL) @@ -58,58 +62,93 @@  // Load necessary libraries (DLLs) //-static GLboolean initLibraries(void)+static GLFWbool loadLibraries(void) {-    _glfw.win32.winmm.instance = LoadLibraryW(L"winmm.dll");+    _glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");     if (!_glfw.win32.winmm.instance)     {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to load winmm.dll");-        return GL_FALSE;+        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to load winmm.dll");+        return GLFW_FALSE;     } -    _glfw.win32.winmm.joyGetDevCaps = (JOYGETDEVCAPS_T)-        GetProcAddress(_glfw.win32.winmm.instance, "joyGetDevCapsW");-    _glfw.win32.winmm.joyGetPos = (JOYGETPOS_T)-        GetProcAddress(_glfw.win32.winmm.instance, "joyGetPos");-    _glfw.win32.winmm.joyGetPosEx = (JOYGETPOSEX_T)-        GetProcAddress(_glfw.win32.winmm.instance, "joyGetPosEx");     _glfw.win32.winmm.timeGetTime = (TIMEGETTIME_T)         GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime"); -    if (!_glfw.win32.winmm.joyGetDevCaps ||-        !_glfw.win32.winmm.joyGetPos ||-        !_glfw.win32.winmm.joyGetPosEx ||-        !_glfw.win32.winmm.timeGetTime)+    _glfw.win32.user32.instance = LoadLibraryA("user32.dll");+    if (!_glfw.win32.user32.instance)     {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to load winmm functions");-        return GL_FALSE;+        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to load user32.dll");+        return GLFW_FALSE;     } -    _glfw.win32.user32.instance = LoadLibraryW(L"user32.dll");-    if (_glfw.win32.user32.instance)+    _glfw.win32.user32.SetProcessDPIAware = (SETPROCESSDPIAWARE_T)+        GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");+    _glfw.win32.user32.ChangeWindowMessageFilterEx = (CHANGEWINDOWMESSAGEFILTEREX_T)+        GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");++    _glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");+    if (_glfw.win32.dinput8.instance)     {-        _glfw.win32.user32.SetProcessDPIAware = (SETPROCESSDPIAWARE_T)-            GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");-        _glfw.win32.user32.ChangeWindowMessageFilterEx = (CHANGEWINDOWMESSAGEFILTEREX_T)-            GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");+        _glfw.win32.dinput8.DirectInput8Create = (DIRECTINPUT8CREATE_T)+            GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");     } -    _glfw.win32.dwmapi.instance = LoadLibraryW(L"dwmapi.dll");+    {+        int i;+        const char* names[] =+        {+            "xinput1_4.dll",+            "xinput1_3.dll",+            "xinput9_1_0.dll",+            "xinput1_2.dll",+            "xinput1_1.dll",+            NULL+        };++        for (i = 0;  names[i];  i++)+        {+            _glfw.win32.xinput.instance = LoadLibraryA(names[i]);+            if (_glfw.win32.xinput.instance)+            {+                _glfw.win32.xinput.XInputGetCapabilities = (XINPUTGETCAPABILITIES_T)+                    GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");+                _glfw.win32.xinput.XInputGetState = (XINPUTGETSTATE_T)+                    GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");++                break;+            }+        }+    }++    _glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");     if (_glfw.win32.dwmapi.instance)     {         _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T)             GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");+        _glfw.win32.dwmapi.DwmFlush = (DWMFLUSH_T)+            GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");     } -    return GL_TRUE;+    _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");+    if (_glfw.win32.shcore.instance)+    {+        _glfw.win32.shcore.SetProcessDpiAwareness = (SETPROCESSDPIAWARENESS_T)+            GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");+    }++    return GLFW_TRUE; }  // Unload used libraries (DLLs) //-static void terminateLibraries(void)+static void freeLibraries(void) {+    if (_glfw.win32.xinput.instance)+        FreeLibrary(_glfw.win32.xinput.instance);++    if (_glfw.win32.dinput8.instance)+        FreeLibrary(_glfw.win32.dinput8.instance);+     if (_glfw.win32.winmm.instance)         FreeLibrary(_glfw.win32.winmm.instance); @@ -118,13 +157,19 @@      if (_glfw.win32.dwmapi.instance)         FreeLibrary(_glfw.win32.dwmapi.instance);++    if (_glfw.win32.shcore.instance)+        FreeLibrary(_glfw.win32.shcore.instance); }  // Create key code translation tables // static void createKeyTables(void) {+    int scancode;+     memset(_glfw.win32.publicKeys, -1, sizeof(_glfw.win32.publicKeys));+    memset(_glfw.win32.nativeKeys, -1, sizeof(_glfw.win32.nativeKeys));      _glfw.win32.publicKeys[0x00B] = GLFW_KEY_0;     _glfw.win32.publicKeys[0x002] = GLFW_KEY_1;@@ -187,6 +232,7 @@     _glfw.win32.publicKeys[0x151] = GLFW_KEY_PAGE_DOWN;     _glfw.win32.publicKeys[0x149] = GLFW_KEY_PAGE_UP;     _glfw.win32.publicKeys[0x045] = GLFW_KEY_PAUSE;+    _glfw.win32.publicKeys[0x146] = GLFW_KEY_PAUSE;     _glfw.win32.publicKeys[0x039] = GLFW_KEY_SPACE;     _glfw.win32.publicKeys[0x00F] = GLFW_KEY_TAB;     _glfw.win32.publicKeys[0x03A] = GLFW_KEY_CAPS_LOCK;@@ -246,31 +292,61 @@     _glfw.win32.publicKeys[0x11C] = GLFW_KEY_KP_ENTER;     _glfw.win32.publicKeys[0x037] = GLFW_KEY_KP_MULTIPLY;     _glfw.win32.publicKeys[0x04A] = GLFW_KEY_KP_SUBTRACT;-} --//////////////////////////////////////////////////////////////////////////-//////                       GLFW internal API                      //////-//////////////////////////////////////////////////////////////////////////+    for (scancode = 0;  scancode < 512;  scancode++)+    {+        if (_glfw.win32.publicKeys[scancode] > 0)+            _glfw.win32.nativeKeys[_glfw.win32.publicKeys[scancode]] = scancode;+    }+} -// Returns whether desktop compositing is enabled+// Creates a dummy window for behind-the-scenes work //-BOOL _glfwIsCompositionEnabled(void)+static HWND createHelperWindow(void) {-    BOOL enabled;+    HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,+                                  _GLFW_WNDCLASSNAME,+                                  L"GLFW helper window",+                                  WS_CLIPSIBLINGS | WS_CLIPCHILDREN,+                                  0, 0, 1, 1,+                                  HWND_MESSAGE, NULL,+                                  GetModuleHandleW(NULL),+                                  NULL);+    if (!window)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to create helper window");+        return NULL;+    } -    if (!_glfw_DwmIsCompositionEnabled)-        return FALSE;+    // HACK: The first call to ShowWindow is ignored if the parent process+    //       passed along a STARTUPINFO, so clear that flag with a no-op call+    ShowWindow(window, SW_HIDE); -    if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK)-        return FALSE;+    // Register for HID device notifications+    {+        DEV_BROADCAST_DEVICEINTERFACE_W dbi;+        ZeroMemory(&dbi, sizeof(dbi));+        dbi.dbcc_size = sizeof(dbi);+        dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;+        dbi.dbcc_classguid = GUID_DEVINTERFACE_HID; -    return enabled;+        RegisterDeviceNotificationW(window,+                                    (DEV_BROADCAST_HDR*) &dbi,+                                    DEVICE_NOTIFY_WINDOW_HANDLE);+    }++   return window; } ++//////////////////////////////////////////////////////////////////////////+//////                       GLFW internal API                      //////+//////////////////////////////////////////////////////////////////////////+ // Returns a wide string version of the specified UTF-8 string //-WCHAR* _glfwCreateWideStringFromUTF8(const char* source)+WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source) {     WCHAR* target;     int length;@@ -292,7 +368,7 @@  // Returns a UTF-8 string version of the specified wide string //-char* _glfwCreateUTF8FromWideString(const WCHAR* source)+char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source) {     char* target;     int length;@@ -301,7 +377,7 @@     if (!length)         return NULL; -    target = calloc(length, sizeof(char));+    target = calloc(length, 1);      if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL))     {@@ -319,6 +395,9 @@  int _glfwPlatformInit(void) {+    if (!_glfwInitThreadLocalStorageWin32())+        return GLFW_FALSE;+     // To make SetForegroundWindow work as we want, we need to fiddle     // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early     // as possible in the hope of still being the foreground process)@@ -327,36 +406,38 @@     SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),                           SPIF_SENDCHANGE); -    if (!initLibraries())-        return GL_FALSE;+    if (!loadLibraries())+        return GLFW_FALSE;      createKeyTables(); -    if (_glfw_SetProcessDPIAware)+    if (_glfw_SetProcessDpiAwareness)+        _glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);+    else if (_glfw_SetProcessDPIAware)         _glfw_SetProcessDPIAware(); -#ifdef __BORLANDC__-    // With the Borland C++ compiler, we want to disable FPU exceptions-    // (this is recommended for OpenGL applications under Windows)-    _control87(MCW_EM, MCW_EM);-#endif+    if (!_glfwRegisterWindowClassWin32())+        return GLFW_FALSE; -    if (!_glfwRegisterWindowClass())-        return GL_FALSE;+    _glfw.win32.helperWindowHandle = createHelperWindow();+    if (!_glfw.win32.helperWindowHandle)+        return GLFW_FALSE; -    if (!_glfwInitContextAPI())-        return GL_FALSE;+    _glfwPlatformPollEvents(); -    _glfwInitTimer();-    _glfwInitJoysticks();+    _glfwInitTimerWin32();+    _glfwInitJoysticksWin32(); -    return GL_TRUE;+    return GLFW_TRUE; }  void _glfwPlatformTerminate(void) {-    _glfwUnregisterWindowClass();+    if (_glfw.win32.helperWindowHandle)+        DestroyWindow(_glfw.win32.helperWindowHandle); +    _glfwUnregisterWindowClassWin32();+     // Restore previous foreground lock timeout system setting     SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,                           UIntToPtr(_glfw.win32.foregroundLockTimeout),@@ -364,31 +445,29 @@      free(_glfw.win32.clipboardString); -    _glfwTerminateJoysticks();-    _glfwTerminateContextAPI();-    terminateLibraries();+    _glfwTerminateWGL();+    _glfwTerminateEGL();++    _glfwTerminateJoysticksWin32();+    _glfwTerminateThreadLocalStorageWin32();++    freeLibraries(); }  const char* _glfwPlatformGetVersionString(void) {-    const char* version = _GLFW_VERSION_NUMBER " Win32"-#if defined(_GLFW_WGL)-        " WGL"-#elif defined(_GLFW_EGL)-        " EGL"-#endif+    return _GLFW_VERSION_NUMBER " Win32 WGL EGL" #if defined(__MINGW32__)         " MinGW" #elif defined(_MSC_VER)         " VisualC"-#elif defined(__BORLANDC__)-        " BorlandC" #endif+#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)+        " hybrid-GPU"+#endif #if defined(_GLFW_BUILD_DLL)         " DLL" #endif         ;--    return version; } 
+ glfw/src/win32_joystick.c view
@@ -0,0 +1,763 @@+//========================================================================+// GLFW 3.1 Win32 - www.glfw.org+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Marcus Geelnard+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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 <math.h>++#include <initguid.h>++#define _GLFW_PRESENCE_ONLY 1+#define _GLFW_UPDATE_STATE  2++#define _GLFW_TYPE_AXIS     0+#define _GLFW_TYPE_SLIDER   1+#define _GLFW_TYPE_BUTTON   2+#define _GLFW_TYPE_POV      3++// Data produced with DirectInput device object enumeration+//+typedef struct _GLFWobjenumWin32+{+    IDirectInputDevice8W*   device;+    _GLFWjoyobjectWin32*    objects;+    int                     objectCount;+    int                     axisCount;+    int                     sliderCount;+    int                     buttonCount;+    int                     povCount;+} _GLFWobjenumWin32;++// Define only the necessary GUIDs (it's bad enough that we're exporting these)+//+DEFINE_GUID(IID_IDirectInput8W,0xbf798031,0x483a,0x4da2,0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00);+DEFINE_GUID(GUID_XAxis,0xa36d02e0,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);+DEFINE_GUID(GUID_YAxis,0xa36d02e1,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);+DEFINE_GUID(GUID_ZAxis,0xa36d02e2,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);+DEFINE_GUID(GUID_RxAxis,0xa36d02f4,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);+DEFINE_GUID(GUID_RyAxis,0xa36d02f5,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);+DEFINE_GUID(GUID_RzAxis,0xa36d02e3,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);+DEFINE_GUID(GUID_Slider,0xa36d02e4,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);+DEFINE_GUID(GUID_Button,0xa36d02f0,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);+DEFINE_GUID(GUID_POV,0xa36d02f2,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);++// Object data array for our clone of c_dfDIJoystick+// Generated with https://github.com/elmindreda/c_dfDIJoystick2+//+static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] =+{+    { &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },+    { &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },+    { &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },+    { &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },+    { &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },+    { &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },+    { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },+    { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },+    { &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+    { NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },+};++// Our clone of c_dfDIJoystick+//+static const DIDATAFORMAT _glfwDataFormat =+{+    sizeof(DIDATAFORMAT),+    sizeof(DIOBJECTDATAFORMAT),+    DIDFT_ABSAXIS,+    sizeof(DIJOYSTATE),+    sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),+    _glfwObjectDataFormats+};++// Returns a description fitting the specified XInput capabilities+//+static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)+{+    switch (xic->SubType)+    {+        case XINPUT_DEVSUBTYPE_WHEEL:+            return "XInput Wheel";+        case XINPUT_DEVSUBTYPE_ARCADE_STICK:+            return "XInput Arcade Stick";+        case XINPUT_DEVSUBTYPE_FLIGHT_STICK:+            return "XInput Flight Stick";+        case XINPUT_DEVSUBTYPE_DANCE_PAD:+            return "XInput Dance Pad";+        case XINPUT_DEVSUBTYPE_GUITAR:+            return "XInput Guitar";+        case XINPUT_DEVSUBTYPE_DRUM_KIT:+            return "XInput Drum Kit";+        case XINPUT_DEVSUBTYPE_GAMEPAD:+        {+            if (xic->Flags & XINPUT_CAPS_WIRELESS)+                return "Wireless Xbox 360 Controller";+            else+                return "Xbox 360 Controller";+        }+    }++    return "Unknown XInput Device";+}++// Lexically compare device objects+//+static int compareJoystickObjects(const void* first, const void* second)+{+    const _GLFWjoyobjectWin32* fo = first;+    const _GLFWjoyobjectWin32* so = second;++    if (fo->type != so->type)+        return fo->type - so->type;++    return fo->offset - so->offset;+}++// Checks whether the specified device supports XInput+// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom+//+static GLFWbool supportsXInput(const GUID* guid)+{+    UINT i, count = 0;+    RAWINPUTDEVICELIST* ridl;+    GLFWbool result = GLFW_FALSE;++    if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)+        return GLFW_FALSE;++    ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));++    if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)+    {+        free(ridl);+        return GLFW_FALSE;+    }++    for (i = 0;  i < count;  i++)+    {+        RID_DEVICE_INFO rdi;+        char name[256];+        UINT size;++        if (ridl[i].dwType != RIM_TYPEHID)+            continue;++        ZeroMemory(&rdi, sizeof(rdi));+        rdi.cbSize = sizeof(rdi);+        size = sizeof(rdi);++        if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,+                                         RIDI_DEVICEINFO,+                                         &rdi, &size) == -1)+        {+            continue;+        }++        if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)+            continue;++        memset(name, 0, sizeof(name));+        size = sizeof(name);++        if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,+                                         RIDI_DEVICENAME,+                                         name, &size) == -1)+        {+            break;+        }++        name[sizeof(name) - 1] = '\0';+        if (strstr(name, "IG_"))+        {+            result = GLFW_TRUE;+            break;+        }+    }++    free(ridl);+    return result;+}++// Frees all resources associated with the specified joystick+//+static void closeJoystick(_GLFWjoystickWin32* js)+{+    if (js->device)+    {+        IDirectInputDevice8_Unacquire(js->device);+        IDirectInputDevice8_Release(js->device);+    }++    free(js->name);+    free(js->axes);+    free(js->buttons);+    free(js->objects);+    memset(js, 0, sizeof(_GLFWjoystickWin32));++    _glfwInputJoystickChange((int) (js - _glfw.win32_js), GLFW_DISCONNECTED);+}++// DirectInput device object enumeration callback+// Insights gleaned from SDL2+//+static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,+                                          void* user)+{+    _GLFWobjenumWin32* data = user;+    _GLFWjoyobjectWin32* object = data->objects + data->objectCount;++    if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)+    {+        DIPROPRANGE dipr;++        if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)+            object->offset = DIJOFS_SLIDER(data->sliderCount);+        else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)+            object->offset = DIJOFS_X;+        else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)+            object->offset = DIJOFS_Y;+        else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)+            object->offset = DIJOFS_Z;+        else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)+            object->offset = DIJOFS_RX;+        else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)+            object->offset = DIJOFS_RY;+        else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)+            object->offset = DIJOFS_RZ;+        else+            return DIENUM_CONTINUE;++        ZeroMemory(&dipr, sizeof(dipr));+        dipr.diph.dwSize = sizeof(dipr);+        dipr.diph.dwHeaderSize = sizeof(dipr.diph);+        dipr.diph.dwObj = doi->dwType;+        dipr.diph.dwHow = DIPH_BYID;+        dipr.lMin = -32768;+        dipr.lMax =  32767;++        if (FAILED(IDirectInputDevice8_SetProperty(data->device,+                                                   DIPROP_RANGE,+                                                   &dipr.diph)))+        {+            return DIENUM_CONTINUE;+        }++        if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)+        {+            object->type = _GLFW_TYPE_SLIDER;+            data->sliderCount++;+        }+        else+        {+            object->type = _GLFW_TYPE_AXIS;+            data->axisCount++;+        }+    }+    else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)+    {+        object->offset = DIJOFS_BUTTON(data->buttonCount);+        object->type = _GLFW_TYPE_BUTTON;+        data->buttonCount++;+    }+    else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)+    {+        object->offset = DIJOFS_POV(data->povCount);+        object->type = _GLFW_TYPE_POV;+        data->povCount++;+    }++    data->objectCount++;+    return DIENUM_CONTINUE;+}++// DirectInput device enumeration callback+//+static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)+{+    int joy = 0;+    DIDEVCAPS dc;+    DIPROPDWORD dipd;+    IDirectInputDevice8* device;+    _GLFWobjenumWin32 data;+    _GLFWjoystickWin32* js;++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+    {+        if (memcmp(&_glfw.win32_js[joy].guid, &di->guidInstance, sizeof(GUID)) == 0)+            return DIENUM_CONTINUE;+    }++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+    {+        if (!_glfw.win32_js[joy].present)+            break;+    }++    if (joy > GLFW_JOYSTICK_LAST)+        return DIENUM_STOP;++    if (supportsXInput(&di->guidProduct))+        return DIENUM_CONTINUE;++    if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api,+                                          &di->guidInstance,+                                          &device,+                                          NULL)))+    {+        _glfwInputError(GLFW_PLATFORM_ERROR, "DI: Failed to create device");+        return DIENUM_CONTINUE;+    }++    if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat)))+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "DI: Failed to set device data format");++        IDirectInputDevice8_Release(device);+        return DIENUM_CONTINUE;+    }++    ZeroMemory(&dc, sizeof(dc));+    dc.dwSize = sizeof(dc);++    if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "DI: Failed to query device capabilities");++        IDirectInputDevice8_Release(device);+        return DIENUM_CONTINUE;+    }++    ZeroMemory(&dipd, sizeof(dipd));+    dipd.diph.dwSize = sizeof(dipd);+    dipd.diph.dwHeaderSize = sizeof(dipd.diph);+    dipd.diph.dwHow = DIPH_DEVICE;+    dipd.dwData = DIPROPAXISMODE_ABS;++    if (FAILED(IDirectInputDevice8_SetProperty(device,+                                               DIPROP_AXISMODE,+                                               &dipd.diph)))+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "DI: Failed to set device axis mode");++        IDirectInputDevice8_Release(device);+        return DIENUM_CONTINUE;+    }++    memset(&data, 0, sizeof(data));+    data.device = device;+    data.objects = calloc(dc.dwAxes + dc.dwButtons + dc.dwPOVs,+                          sizeof(_GLFWjoyobjectWin32));++    if (FAILED(IDirectInputDevice8_EnumObjects(device,+                                               deviceObjectCallback,+                                               &data,+                                               DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "DI: Failed to enumerate device objects");++        IDirectInputDevice8_Release(device);+        free(data.objects);+        return DIENUM_CONTINUE;+    }++    qsort(data.objects, data.objectCount,+          sizeof(_GLFWjoyobjectWin32),+          compareJoystickObjects);++    js = _glfw.win32_js + joy;+    js->device = device;+    js->guid = di->guidInstance;+    js->axisCount = data.axisCount + data.sliderCount;+    js->axes = calloc(js->axisCount, sizeof(float));+    js->buttonCount += data.buttonCount + data.povCount * 4;+    js->buttons = calloc(js->buttonCount, 1);+    js->objects = data.objects;+    js->objectCount = data.objectCount;+    js->name = _glfwCreateUTF8FromWideStringWin32(di->tszInstanceName);+    js->present = GLFW_TRUE;++    _glfwInputJoystickChange(joy, GLFW_CONNECTED);+    return DIENUM_CONTINUE;+}++// Attempt to open the specified joystick device+// TODO: Pack state arrays for non-gamepad devices+//+static GLFWbool openXinputDevice(DWORD index)+{+    int joy;+    XINPUT_CAPABILITIES xic;+    _GLFWjoystickWin32* js;++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+    {+        if (_glfw.win32_js[joy].present &&+            _glfw.win32_js[joy].device == NULL &&+            _glfw.win32_js[joy].index == index)+        {+            return GLFW_FALSE;+        }+    }++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+    {+        if (!_glfw.win32_js[joy].present)+            break;+    }++    if (joy > GLFW_JOYSTICK_LAST)+        return GLFW_FALSE;++    if (_glfw_XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)+        return GLFW_FALSE;++    js = _glfw.win32_js + joy;+    js->axisCount = 6;+    js->axes = calloc(js->axisCount, sizeof(float));+    js->buttonCount = 14;+    js->buttons = calloc(js->buttonCount, 1);+    js->present = GLFW_TRUE;+    js->name = strdup(getDeviceDescription(&xic));+    js->index = index;++    _glfwInputJoystickChange(joy, GLFW_CONNECTED);++    return GLFW_TRUE;+}++// Polls for and processes events the specified joystick+//+static GLFWbool pollJoystickState(_GLFWjoystickWin32* js, int mode)+{+    if (!js->present)+        return GLFW_FALSE;++    if (js->device)+    {+        int i, j, ai = 0, bi = 0;+        HRESULT result;+        DIJOYSTATE state;++        IDirectInputDevice8_Poll(js->device);+        result = IDirectInputDevice8_GetDeviceState(js->device,+                                                    sizeof(state),+                                                    &state);+        if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)+        {+            IDirectInputDevice8_Acquire(js->device);+            IDirectInputDevice8_Poll(js->device);+            result = IDirectInputDevice8_GetDeviceState(js->device,+                                                        sizeof(state),+                                                        &state);+        }++        if (FAILED(result))+        {+            closeJoystick(js);+            return GLFW_FALSE;+        }++        if (mode == _GLFW_PRESENCE_ONLY)+            return GLFW_TRUE;++        for (i = 0;  i < js->objectCount;  i++)+        {+            const void* data = (char*) &state + js->objects[i].offset;++            switch (js->objects[i].type)+            {+                case _GLFW_TYPE_AXIS:+                case _GLFW_TYPE_SLIDER:+                {+                    js->axes[ai++] = (*((LONG*) data) + 0.5f) / 32767.5f;+                    break;+                }++                case _GLFW_TYPE_BUTTON:+                {+                    if (*((BYTE*) data) & 0x80)+                        js->buttons[bi++] = GLFW_PRESS;+                    else+                        js->buttons[bi++] = GLFW_RELEASE;++                    break;+                }++                case _GLFW_TYPE_POV:+                {+                    const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };+                    // Screams of horror are appropriate at this point+                    int value = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);+                    if (value < 0 || value > 8)+                        value = 8;++                    for (j = 0;  j < 4;  j++)+                    {+                        if (directions[value] & (1 << j))+                            js->buttons[bi++] = GLFW_PRESS;+                        else+                            js->buttons[bi++] = GLFW_RELEASE;+                    }++                    break;+                }+            }+        }++        return GLFW_TRUE;+    }+    else+    {+        int i;+        DWORD result;+        XINPUT_STATE xis;+        const WORD buttons[14] =+        {+            XINPUT_GAMEPAD_A,+            XINPUT_GAMEPAD_B,+            XINPUT_GAMEPAD_X,+            XINPUT_GAMEPAD_Y,+            XINPUT_GAMEPAD_LEFT_SHOULDER,+            XINPUT_GAMEPAD_RIGHT_SHOULDER,+            XINPUT_GAMEPAD_BACK,+            XINPUT_GAMEPAD_START,+            XINPUT_GAMEPAD_LEFT_THUMB,+            XINPUT_GAMEPAD_RIGHT_THUMB,+            XINPUT_GAMEPAD_DPAD_UP,+            XINPUT_GAMEPAD_DPAD_RIGHT,+            XINPUT_GAMEPAD_DPAD_DOWN,+            XINPUT_GAMEPAD_DPAD_LEFT+        };++        result = _glfw_XInputGetState(js->index, &xis);+        if (result != ERROR_SUCCESS)+        {+            if (result == ERROR_DEVICE_NOT_CONNECTED)+                closeJoystick(js);++            return GLFW_FALSE;+        }++        if (mode == _GLFW_PRESENCE_ONLY)+            return GLFW_TRUE;++        if (sqrt((double) (xis.Gamepad.sThumbLX * xis.Gamepad.sThumbLX ++                           xis.Gamepad.sThumbLY * xis.Gamepad.sThumbLY)) >+            (double) XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)+        {+            js->axes[0] = (xis.Gamepad.sThumbLX + 0.5f) / 32767.f;+            js->axes[1] = (xis.Gamepad.sThumbLY + 0.5f) / 32767.f;+        }+        else+        {+            js->axes[0] = 0.f;+            js->axes[1] = 0.f;+        }++        if (sqrt((double) (xis.Gamepad.sThumbRX * xis.Gamepad.sThumbRX ++                           xis.Gamepad.sThumbRY * xis.Gamepad.sThumbRY)) >+            (double) XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)+        {+            js->axes[2] = (xis.Gamepad.sThumbRX + 0.5f) / 32767.f;+            js->axes[3] = (xis.Gamepad.sThumbRY + 0.5f) / 32767.f;+        }+        else+        {+            js->axes[2] = 0.f;+            js->axes[3] = 0.f;+        }++        if (xis.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)+            js->axes[4] = xis.Gamepad.bLeftTrigger / 127.5f - 1.f;+        else+            js->axes[4] = -1.f;++        if (xis.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)+            js->axes[5] = xis.Gamepad.bRightTrigger / 127.5f - 1.f;+        else+            js->axes[5] = -1.f;++        for (i = 0;  i < 14;  i++)+            js->buttons[i] = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;++        return GLFW_TRUE;+    }+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW internal API                      //////+//////////////////////////////////////////////////////////////////////////++// Initialize joystick interface+//+void _glfwInitJoysticksWin32(void)+{+    if (_glfw.win32.dinput8.instance)+    {+        if (FAILED(_glfw_DirectInput8Create(GetModuleHandle(NULL),+                                            DIRECTINPUT_VERSION,+                                            &IID_IDirectInput8W,+                                            (void**) &_glfw.win32.dinput8.api,+                                            NULL)))+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "DI: Failed to create interface");+        }+    }++    _glfwDetectJoystickConnectionWin32();+}++// Close all opened joystick handles+//+void _glfwTerminateJoysticksWin32(void)+{+    int joy;++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+        closeJoystick(_glfw.win32_js + joy);++    if (_glfw.win32.dinput8.api)+        IDirectInput8_Release(_glfw.win32.dinput8.api);+}++// Checks for new joysticks after DBT_DEVICEARRIVAL+//+void _glfwDetectJoystickConnectionWin32(void)+{+    if (_glfw.win32.xinput.instance)+    {+        DWORD i;++        for (i = 0;  i < XUSER_MAX_COUNT;  i++)+            openXinputDevice(i);+    }++    if (_glfw.win32.dinput8.api)+    {+        if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api,+                                             DI8DEVCLASS_GAMECTRL,+                                             deviceCallback,+                                             NULL,+                                             DIEDFL_ALLDEVICES)))+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "Failed to enumerate DirectInput8 devices");+            return;+        }+    }+}++// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE+//+void _glfwDetectJoystickDisconnectionWin32(void)+{+    int joy;++    for (joy = GLFW_JOYSTICK_1;  joy <= GLFW_JOYSTICK_LAST;  joy++)+        pollJoystickState(_glfw.win32_js + joy, _GLFW_PRESENCE_ONLY);+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW platform API                      //////+//////////////////////////////////////////////////////////////////////////++int _glfwPlatformJoystickPresent(int joy)+{+    _GLFWjoystickWin32* js = _glfw.win32_js + joy;+    return pollJoystickState(js, _GLFW_PRESENCE_ONLY);+}++const float* _glfwPlatformGetJoystickAxes(int joy, int* count)+{+    _GLFWjoystickWin32* js = _glfw.win32_js + joy;+    if (!pollJoystickState(js, _GLFW_UPDATE_STATE))+        return NULL;++    *count = js->axisCount;+    return js->axes;+}++const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)+{+    _GLFWjoystickWin32* js = _glfw.win32_js + joy;+    if (!pollJoystickState(js, _GLFW_UPDATE_STATE))+        return NULL;++    *count = js->buttonCount;+    return js->buttons;+}++const char* _glfwPlatformGetJoystickName(int joy)+{+    _GLFWjoystickWin32* js = _glfw.win32_js + joy;+    if (!pollJoystickState(js, _GLFW_PRESENCE_ONLY))+        return NULL;++    return js->name;+}+
+ glfw/src/win32_joystick.h view
@@ -0,0 +1,64 @@+//========================================================================+// GLFW 3.2 Win32 - www.glfw.org+//------------------------------------------------------------------------+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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.+//+//========================================================================++#ifndef _glfw3_win32_joystick_h_+#define _glfw3_win32_joystick_h_++#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \+    _GLFWjoystickWin32 win32_js[GLFW_JOYSTICK_LAST + 1]++// Joystick element (axis, button or slider)+//+typedef struct _GLFWjoyobjectWin32+{+    int                     offset;+    int                     type;+} _GLFWjoyobjectWin32;++// Win32-specific per-joystick data+//+typedef struct _GLFWjoystickWin32+{+    GLFWbool                present;+    float*                  axes;+    int                     axisCount;+    unsigned char*          buttons;+    int                     buttonCount;+    _GLFWjoyobjectWin32*    objects;+    int                     objectCount;+    char*                   name;+    IDirectInputDevice8W*   device;+    DWORD                   index;+    GUID                    guid;+} _GLFWjoystickWin32;+++void _glfwInitJoysticksWin32(void);+void _glfwTerminateJoysticksWin32(void);+void _glfwDetectJoystickConnectionWin32(void);+void _glfwDetectJoystickDisconnectionWin32(void);++#endif // _glfw3_win32_joystick_h_
glfw/src/win32_monitor.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 Win32 - www.glfw.org+// GLFW 3.2 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -32,22 +32,67 @@ #include <limits.h> #include <malloc.h> -// These constants are missing on MinGW-#ifndef EDS_ROTATEDMODE- #define EDS_ROTATEDMODE 0x00000004-#endif-#ifndef DISPLAY_DEVICE_ACTIVE- #define DISPLAY_DEVICE_ACTIVE 0x00000001-#endif +// Create monitor from an adapter and (optionally) a display+//+static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,+                                   DISPLAY_DEVICEW* display)+{+    _GLFWmonitor* monitor;+    char* name;+    HDC dc; +    if (display)+        name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);+    else+        name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);+    if (!name)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to convert string to UTF-8");+        return NULL;+    }++    dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);++    monitor = _glfwAllocMonitor(name,+                                GetDeviceCaps(dc, HORZSIZE),+                                GetDeviceCaps(dc, VERTSIZE));++    DeleteDC(dc);+    free(name);++    if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)+        monitor->win32.modesPruned = GLFW_TRUE;++    wcscpy(monitor->win32.adapterName, adapter->DeviceName);+    WideCharToMultiByte(CP_UTF8, 0,+                        adapter->DeviceName, -1,+                        monitor->win32.publicAdapterName,+                        sizeof(monitor->win32.publicAdapterName),+                        NULL, NULL);++    if (display)+    {+        wcscpy(monitor->win32.displayName, display->DeviceName);+        WideCharToMultiByte(CP_UTF8, 0,+                            display->DeviceName, -1,+                            monitor->win32.publicDisplayName,+                            sizeof(monitor->win32.publicDisplayName),+                            NULL, NULL);+    }++    return monitor;+}++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////  // Change the current video mode //-GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)+GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired) {     GLFWvidmode current;     const GLFWvidmode* best;@@ -56,7 +101,7 @@     best = _glfwChooseVideoMode(monitor, desired);     _glfwPlatformGetVideoMode(monitor, &current);     if (_glfwCompareVideoModes(&current, best) == 0)-        return GL_TRUE;+        return GLFW_TRUE;      ZeroMemory(&dm, sizeof(dm));     dm.dmSize = sizeof(DEVMODEW);@@ -77,22 +122,22 @@                                  NULL) != DISP_CHANGE_SUCCESSFUL)     {         _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to set video mode");-        return GL_FALSE;+        return GLFW_FALSE;     } -    monitor->win32.modeChanged = GL_TRUE;-    return GL_TRUE;+    monitor->win32.modeChanged = GLFW_TRUE;+    return GLFW_TRUE; }  // Restore the previously saved (original) video mode //-void _glfwRestoreVideoMode(_GLFWmonitor* monitor)+void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor) {     if (monitor->win32.modeChanged)     {         ChangeDisplaySettingsExW(monitor->win32.adapterName,                                  NULL, NULL, CDS_FULLSCREEN, NULL);-        monitor->win32.modeChanged = GL_FALSE;+        monitor->win32.modeChanged = GLFW_FALSE;     } } @@ -103,16 +148,19 @@  _GLFWmonitor** _glfwPlatformGetMonitors(int* count) {-    int size = 0, found = 0;+    int found = 0;+    DWORD adapterIndex, displayIndex, primaryIndex = 0;+    DISPLAY_DEVICEW adapter, display;+    GLFWbool hasDisplays = GLFW_FALSE;     _GLFWmonitor** monitors = NULL;-    DWORD adapterIndex, displayIndex;      *count = 0; +    // HACK: Check if any active adapters have connected displays+    //       If not, this is a headless system or a VMware guest+     for (adapterIndex = 0;  ;  adapterIndex++)     {-        DISPLAY_DEVICEW adapter;-         ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));         adapter.cb = sizeof(DISPLAY_DEVICEW); @@ -122,73 +170,65 @@         if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))             continue; -        for (displayIndex = 0;  ;  displayIndex++)-        {-            DISPLAY_DEVICEW display;-            char* name;-            HDC dc;--            ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));-            display.cb = sizeof(DISPLAY_DEVICEW);--            if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))-                break;--            if (found == size)-            {-                size += 4;-                monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size);-            }+        ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));+        display.cb = sizeof(DISPLAY_DEVICEW); -            name = _glfwCreateUTF8FromWideString(display.DeviceString);-            if (!name)-            {-                _glfwInputError(GLFW_PLATFORM_ERROR,-                                "Failed to convert string to UTF-8");-                continue;-            }+        if (EnumDisplayDevicesW(adapter.DeviceName, 0, &display, 0))+        {+            hasDisplays = GLFW_TRUE;+            break;+        }+    } -            dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL);+    for (adapterIndex = 0;  ;  adapterIndex++)+    {+        ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));+        adapter.cb = sizeof(DISPLAY_DEVICEW); -            monitors[found] = _glfwAllocMonitor(name,-                                                GetDeviceCaps(dc, HORZSIZE),-                                                GetDeviceCaps(dc, VERTSIZE));+        if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))+            break; -            DeleteDC(dc);-            free(name);+        if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))+            continue; -            wcscpy(monitors[found]->win32.adapterName, adapter.DeviceName);-            wcscpy(monitors[found]->win32.displayName, display.DeviceName);+        if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)+            primaryIndex = found; -            WideCharToMultiByte(CP_UTF8, 0,-                                adapter.DeviceName, -1,-                                monitors[found]->win32.publicAdapterName,-                                sizeof(monitors[found]->win32.publicAdapterName),-                                NULL, NULL);+        if (hasDisplays)+        {+            for (displayIndex = 0;  ;  displayIndex++)+            {+                ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));+                display.cb = sizeof(DISPLAY_DEVICEW); -            WideCharToMultiByte(CP_UTF8, 0,-                                display.DeviceName, -1,-                                monitors[found]->win32.publicDisplayName,-                                sizeof(monitors[found]->win32.publicDisplayName),-                                NULL, NULL);+                if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))+                    break; -            if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE &&-                displayIndex == 0)-            {-                _GLFW_SWAP_POINTERS(monitors[0], monitors[found]);+                found++;+                monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);+                monitors[found - 1] = createMonitor(&adapter, &display);             }-+        }+        else+        {             found++;+            monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);+            monitors[found - 1] = createMonitor(&adapter, NULL);         }     } +    _GLFW_SWAP_POINTERS(monitors[0], monitors[primaryIndex]);+     *count = found;     return monitors; } -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)+GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) {-    return wcscmp(first->win32.displayName, second->win32.displayName) == 0;+    if (wcslen(first->win32.displayName))+        return wcscmp(first->win32.displayName, second->win32.displayName) == 0;+    else+        return wcscmp(first->win32.adapterName, second->win32.adapterName) == 0; }  void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)@@ -208,12 +248,12 @@         *ypos = settings.dmPosition.y; } -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) {-    int modeIndex = 0, count = 0;+    int modeIndex = 0, size = 0;     GLFWvidmode* result = NULL; -    *found = 0;+    *count = 0;      for (;;)     {@@ -229,11 +269,9 @@          modeIndex++; +        // Skip modes with less than 15 BPP         if (dm.dmBitsPerPel < 15)-        {-            // Skip modes with less than 15 BPP             continue;-        }          mode.width  = dm.dmPelsWidth;         mode.height = dm.dmPelsHeight;@@ -243,30 +281,45 @@                       &mode.greenBits,                       &mode.blueBits); -        for (i = 0;  i < *found;  i++)+        for (i = 0;  i < *count;  i++)         {             if (_glfwCompareVideoModes(result + i, &mode) == 0)                 break;         } -        if (i < *found)-        {-            // This is a duplicate, so skip it+        // Skip duplicate modes+        if (i < *count)             continue;-        } -        if (*found == count)+        if (monitor->win32.modesPruned)         {-            if (count)-                count *= 2;-            else-                count = 128;+            // Skip modes not supported by the connected displays+            if (ChangeDisplaySettingsExW(monitor->win32.adapterName,+                                         &dm,+                                         NULL,+                                         CDS_TEST,+                                         NULL) != DISP_CHANGE_SUCCESSFUL)+            {+                continue;+            }+        } -            result = (GLFWvidmode*) realloc(result, count * sizeof(GLFWvidmode));+        if (*count == size)+        {+            size += 128;+            result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));         } -        result[*found] = mode;-        (*found)++;+        (*count)++;+        result[*count - 1] = mode;+    }++    if (!*count)+    {+        // HACK: Report the current mode if no valid modes were found+        result = calloc(1, sizeof(GLFWvidmode));+        _glfwPlatformGetVideoMode(monitor, result);+        *count = 1;     }      return result;
glfw/src/win32_platform.h view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 Win32 - www.glfw.org+// GLFW 3.2 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -25,9 +25,8 @@ // //======================================================================== -#ifndef _win32_platform_h_-#define _win32_platform_h_-+#ifndef _glfw3_win32_platform_h_+#define _glfw3_win32_platform_h_  // We don't need all the fancy stuff #ifndef NOMINMAX@@ -62,8 +61,14 @@  #define _WIN32_WINNT 0x0501 #endif +// GLFW uses DirectInput8 interfaces+#define DIRECTINPUT_VERSION 0x0800++#include <wctype.h> #include <windows.h> #include <mmsystem.h>+#include <dinput.h>+#include <xinput.h> #include <dbt.h>  #if defined(_MSC_VER)@@ -71,9 +76,7 @@  #define strdup _strdup #endif --// HACK: Define macros that some older windows.h variants don't-+// HACK: Define macros that some windows.h variants don't #ifndef WM_MOUSEHWHEEL  #define WM_MOUSEHWHEEL 0x020E #endif@@ -89,6 +92,18 @@ #ifndef UNICODE_NOCHAR  #define UNICODE_NOCHAR 0xFFFF #endif+#ifndef WM_DPICHANGED+ #define WM_DPICHANGED 0x02E0+#endif+#ifndef GET_XBUTTON_WPARAM+ #define GET_XBUTTON_WPARAM(w) (HIWORD(w))+#endif+#ifndef EDS_ROTATEDMODE+ #define EDS_ROTATEDMODE 0x00000004+#endif+#ifndef DISPLAY_DEVICE_ACTIVE+ #define DISPLAY_DEVICE_ACTIVE 0x00000001+#endif  #if WINVER < 0x0601 typedef struct tagCHANGEFILTERSTRUCT@@ -102,17 +117,63 @@ #endif #endif /*Windows 7*/ +#ifndef DPI_ENUMS_DECLARED+typedef enum PROCESS_DPI_AWARENESS+{+    PROCESS_DPI_UNAWARE = 0,+    PROCESS_SYSTEM_DPI_AWARE = 1,+    PROCESS_PER_MONITOR_DPI_AWARE = 2+} PROCESS_DPI_AWARENESS;+#endif /*DPI_ENUMS_DECLARED*/ +// HACK: Define macros that some xinput.h variants don't+#ifndef XINPUT_CAPS_WIRELESS+ #define XINPUT_CAPS_WIRELESS 0x0002+#endif+#ifndef XINPUT_DEVSUBTYPE_WHEEL+ #define XINPUT_DEVSUBTYPE_WHEEL 0x02+#endif+#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK+ #define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03+#endif+#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK+ #define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04+#endif+#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD+ #define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05+#endif+#ifndef XINPUT_DEVSUBTYPE_GUITAR+ #define XINPUT_DEVSUBTYPE_GUITAR 0x06+#endif+#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT+ #define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08+#endif+#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD+ #define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13+#endif+#ifndef XUSER_MAX_COUNT+ #define XUSER_MAX_COUNT 4+#endif++// HACK: Define macros that some dinput.h variants don't+#ifndef DIDFT_OPTIONAL+ #define DIDFT_OPTIONAL	0x80000000+#endif+ // winmm.dll function pointer typedefs-typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT);-typedef MMRESULT (WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO);-typedef MMRESULT (WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX); typedef DWORD (WINAPI * TIMEGETTIME_T)(void);-#define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps-#define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos-#define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx #define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime +// xinput.dll function pointer typedefs+typedef DWORD (WINAPI * XINPUTGETCAPABILITIES_T)(DWORD,DWORD,XINPUT_CAPABILITIES*);+typedef DWORD (WINAPI * XINPUTGETSTATE_T)(DWORD,XINPUT_STATE*);+#define _glfw_XInputGetCapabilities _glfw.win32.xinput.XInputGetCapabilities+#define _glfw_XInputGetState _glfw.win32.xinput.XInputGetState++// dinput8.dll function pointer typedefs+typedef HRESULT (WINAPI * DIRECTINPUT8CREATE_T)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);+#define _glfw_DirectInput8Create _glfw.win32.dinput8.DirectInput8Create+ // user32.dll function pointer typedefs typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT);@@ -121,31 +182,45 @@  // dwmapi.dll function pointer typedefs typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*);+typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID); #define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled+#define _glfw_DwmFlush _glfw.win32.dwmapi.DwmFlush +// shcore.dll function pointer typedefs+typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);+#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness -#define _GLFW_RECREATION_NOT_NEEDED 0-#define _GLFW_RECREATION_REQUIRED   1-#define _GLFW_RECREATION_IMPOSSIBLE 2+typedef VkFlags VkWin32SurfaceCreateFlagsKHR; +typedef struct VkWin32SurfaceCreateInfoKHR+{+    VkStructureType                 sType;+    const void*                     pNext;+    VkWin32SurfaceCreateFlagsKHR    flags;+    HINSTANCE                       hinstance;+    HWND                            hwnd;+} VkWin32SurfaceCreateInfoKHR; -#include "win32_tls.h"+typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t); -#if defined(_GLFW_WGL)- #include "wgl_context.h"-#elif defined(_GLFW_EGL)- #define _GLFW_EGL_NATIVE_WINDOW  window->win32.handle- #define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY- #include "egl_context.h"-#else- #error "No supported context creation API selected"-#endif+#include "win32_joystick.h"+#include "wgl_context.h"+#include "egl_context.h" -#include "winmm_joystick.h"+#define _GLFW_WNDCLASSNAME L"GLFW30" +#define _glfw_dlopen(name) LoadLibraryA(name)+#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)+#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)++#define _GLFW_EGL_NATIVE_WINDOW  ((EGLNativeWindowType) window->win32.handle)+#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY+ #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowWin32  win32 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 #define _GLFW_PLATFORM_LIBRARY_TIME_STATE   _GLFWtimeWin32    win32_time+#define _GLFW_PLATFORM_LIBRARY_TLS_STATE    _GLFWtlsWin32     win32_tls #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorWin32 win32 #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorWin32  win32 @@ -155,50 +230,67 @@ typedef struct _GLFWwindowWin32 {     HWND                handle;-    DWORD               dwStyle;-    DWORD               dwExStyle;+    HICON               bigIcon;+    HICON               smallIcon; -    GLboolean           cursorInside;-    GLboolean           iconified;+    GLFWbool            cursorTracked;+    GLFWbool            iconified;      // The last received cursor position, regardless of source-    int                 cursorPosX, cursorPosY;+    int                 lastCursorPosX, lastCursorPosY;  } _GLFWwindowWin32; - // Win32-specific global data // typedef struct _GLFWlibraryWin32 {+    HWND                helperWindowHandle;     DWORD               foregroundLockTimeout;     char*               clipboardString;+    char                keyName[64];     short int           publicKeys[512];+    short int           nativeKeys[GLFW_KEY_LAST + 1];+    // Where to place the cursor when re-enabled+    double              restoreCursorPosX, restoreCursorPosY;+    // The window whose disabled cursor mode is active+    _GLFWwindow*        disabledCursorWindow; -    // winmm.dll     struct {         HINSTANCE       instance;-        JOYGETDEVCAPS_T joyGetDevCaps;-        JOYGETPOS_T     joyGetPos;-        JOYGETPOSEX_T   joyGetPosEx;         TIMEGETTIME_T   timeGetTime;     } winmm; -    // user32.dll     struct {-        HINSTANCE       instance;-        SETPROCESSDPIAWARE_T SetProcessDPIAware;+        HINSTANCE            instance;+        DIRECTINPUT8CREATE_T DirectInput8Create;+        IDirectInput8W*      api;+    } dinput8;++    struct {+        HINSTANCE               instance;+        XINPUTGETCAPABILITIES_T XInputGetCapabilities;+        XINPUTGETSTATE_T        XInputGetState;+    } xinput;++    struct {+        HINSTANCE                     instance;+        SETPROCESSDPIAWARE_T          SetProcessDPIAware;         CHANGEWINDOWMESSAGEFILTEREX_T ChangeWindowMessageFilterEx;     } user32; -    // dwmapi.dll     struct {         HINSTANCE       instance;         DWMISCOMPOSITIONENABLED_T DwmIsCompositionEnabled;+        DWMFLUSH_T      DwmFlush;     } dwmapi; -} _GLFWlibraryWin32;+    struct {+        HINSTANCE       instance;+        SETPROCESSDPIAWARENESS_T SetProcessDpiAwareness;+    } shcore; +} _GLFWlibraryWin32;  // Win32-specific per-monitor data //@@ -209,11 +301,11 @@     WCHAR               displayName[32];     char                publicAdapterName[64];     char                publicDisplayName[64];-    GLboolean           modeChanged;+    GLFWbool            modesPruned;+    GLFWbool            modeChanged;  } _GLFWmonitorWin32; - // Win32-specific per-cursor data // typedef struct _GLFWcursorWin32@@ -222,29 +314,37 @@  } _GLFWcursorWin32; - // Win32-specific global timer data // typedef struct _GLFWtimeWin32 {-    GLboolean           hasPC;-    double              resolution;-    unsigned __int64    base;+    GLFWbool            hasPC;+    uint64_t            frequency;  } _GLFWtimeWin32; +// Win32-specific global TLS data+//+typedef struct _GLFWtlsWin32+{+    GLFWbool        allocated;+    DWORD           context; -GLboolean _glfwRegisterWindowClass(void);-void _glfwUnregisterWindowClass(void);+} _GLFWtlsWin32; -BOOL _glfwIsCompositionEnabled(void); -WCHAR* _glfwCreateWideStringFromUTF8(const char* source);-char* _glfwCreateUTF8FromWideString(const WCHAR* source);+GLFWbool _glfwRegisterWindowClassWin32(void);+void _glfwUnregisterWindowClassWin32(void); -void _glfwInitTimer(void);+GLFWbool _glfwInitThreadLocalStorageWin32(void);+void _glfwTerminateThreadLocalStorageWin32(void); -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired);-void _glfwRestoreVideoMode(_GLFWmonitor* monitor);+WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);+char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source); -#endif // _win32_platform_h_+void _glfwInitTimerWin32(void);++GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);+void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);++#endif // _glfw3_win32_platform_h_
glfw/src/win32_time.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 Win32 - www.glfw.org+// GLFW 3.2 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -28,43 +28,26 @@ #include "internal.h"  -// Return raw time-//-static unsigned __int64 getRawTime(void)-{-    if (_glfw.win32_time.hasPC)-    {-        unsigned __int64 time;-        QueryPerformanceCounter((LARGE_INTEGER*) &time);-        return time;-    }-    else-        return (unsigned __int64) _glfw_timeGetTime();-}-- ////////////////////////////////////////////////////////////////////////// //////                       GLFW internal API                      ////// //////////////////////////////////////////////////////////////////////////  // Initialise timer //-void _glfwInitTimer(void)+void _glfwInitTimerWin32(void) {-    unsigned __int64 frequency;+    uint64_t frequency;      if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))     {-        _glfw.win32_time.hasPC = GL_TRUE;-        _glfw.win32_time.resolution = 1.0 / (double) frequency;+        _glfw.win32_time.hasPC = GLFW_TRUE;+        _glfw.win32_time.frequency = frequency;     }     else     {-        _glfw.win32_time.hasPC = GL_FALSE;-        _glfw.win32_time.resolution = 0.001; // winmm resolution is 1 ms+        _glfw.win32_time.hasPC = GLFW_FALSE;+        _glfw.win32_time.frequency = 1000;     }--    _glfw.win32_time.base = getRawTime(); }  @@ -72,15 +55,20 @@ //////                       GLFW platform API                      ////// ////////////////////////////////////////////////////////////////////////// -double _glfwPlatformGetTime(void)+uint64_t _glfwPlatformGetTimerValue(void) {-    return (double) (getRawTime() - _glfw.win32_time.base) *-        _glfw.win32_time.resolution;+    if (_glfw.win32_time.hasPC)+    {+        uint64_t value;+        QueryPerformanceCounter((LARGE_INTEGER*) &value);+        return value;+    }+    else+        return (uint64_t) _glfw_timeGetTime(); } -void _glfwPlatformSetTime(double time)+uint64_t _glfwPlatformGetTimerFrequency(void) {-    _glfw.win32_time.base = getRawTime() --        (unsigned __int64) (time / _glfw.win32_time.resolution);+    return _glfw.win32_time.frequency; } 
glfw/src/win32_tls.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 Win32 - www.glfw.org+// GLFW 3.2 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -32,35 +32,35 @@ //////                       GLFW internal API                      ////// ////////////////////////////////////////////////////////////////////////// -int _glfwInitTLS(void)+GLFWbool _glfwInitThreadLocalStorageWin32(void) {     _glfw.win32_tls.context = TlsAlloc();     if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES)     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Win32: Failed to allocate TLS index");-        return GL_FALSE;+        return GLFW_FALSE;     } -    _glfw.win32_tls.allocated = GL_TRUE;-    return GL_TRUE;+    _glfw.win32_tls.allocated = GLFW_TRUE;+    return GLFW_TRUE; } -void _glfwTerminateTLS(void)+void _glfwTerminateThreadLocalStorageWin32(void) {     if (_glfw.win32_tls.allocated)         TlsFree(_glfw.win32_tls.context); } -void _glfwSetCurrentContext(_GLFWwindow* context)-{-    TlsSetValue(_glfw.win32_tls.context, context);-} - ////////////////////////////////////////////////////////////////////////// //////                       GLFW platform API                      ////// //////////////////////////////////////////////////////////////////////////++void _glfwPlatformSetCurrentContext(_GLFWwindow* context)+{+    TlsSetValue(_glfw.win32_tls.context, context);+}  _GLFWwindow* _glfwPlatformGetCurrentContext(void) {
− glfw/src/win32_tls.h
@@ -1,48 +0,0 @@-//========================================================================-// GLFW 3.1 Win32 - www.glfw.org-//-------------------------------------------------------------------------// Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-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.-//-//========================================================================--#ifndef _win32_tls_h_-#define _win32_tls_h_--#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsWin32 win32_tls---// Win32-specific global TLS data-//-typedef struct _GLFWtlsWin32-{-    GLboolean       allocated;-    DWORD           context;--} _GLFWtlsWin32;---int _glfwInitTLS(void);-void _glfwTerminateTLS(void);-void _glfwSetCurrentContext(_GLFWwindow* context);--#endif // _win32_tls_h_
glfw/src/win32_window.c view
@@ -1,1301 +1,1713 @@ //========================================================================-// GLFW 3.1 Win32 - www.glfw.org-//-------------------------------------------------------------------------// Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-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 <stdlib.h>-#include <malloc.h>-#include <string.h>-#include <windowsx.h>-#include <shellapi.h>--#define _GLFW_KEY_INVALID -2--#define _GLFW_WNDCLASSNAME L"GLFW30"---// Updates the cursor clip rect-//-static void updateClipRect(_GLFWwindow* window)-{-    RECT clipRect;-    GetClientRect(window->win32.handle, &clipRect);-    ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);-    ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);-    ClipCursor(&clipRect);-}--// Hide the mouse cursor-//-static void hideCursor(_GLFWwindow* window)-{-    POINT pos;--    ClipCursor(NULL);--    if (GetCursorPos(&pos))-    {-        if (WindowFromPoint(pos) == window->win32.handle)-            SetCursor(NULL);-    }-}--// Disable the mouse cursor-//-static void disableCursor(_GLFWwindow* window)-{-    POINT pos;--    updateClipRect(window);--    if (GetCursorPos(&pos))-    {-        if (WindowFromPoint(pos) == window->win32.handle)-            SetCursor(NULL);-    }-}--// Restores the mouse cursor-//-static void restoreCursor(_GLFWwindow* window)-{-    POINT pos;--    ClipCursor(NULL);--    if (GetCursorPos(&pos))-    {-        if (WindowFromPoint(pos) == window->win32.handle)-        {-            if (window->cursor)-                SetCursor(window->cursor->win32.handle);-            else-                SetCursor(LoadCursorW(NULL, IDC_ARROW));-        }-    }-}--// Translates a GLFW standard cursor to a resource ID-//-static LPWSTR translateCursorShape(int shape)-{-    switch (shape)-    {-        case GLFW_ARROW_CURSOR:-            return IDC_ARROW;-        case GLFW_IBEAM_CURSOR:-            return IDC_IBEAM;-        case GLFW_CROSSHAIR_CURSOR:-            return IDC_CROSS;-        case GLFW_HAND_CURSOR:-            return IDC_HAND;-        case GLFW_HRESIZE_CURSOR:-            return IDC_SIZEWE;-        case GLFW_VRESIZE_CURSOR:-            return IDC_SIZENS;-    }--    return NULL;-}--// Retrieves and translates modifier keys-//-static int getKeyMods(void)-{-    int mods = 0;--    if (GetKeyState(VK_SHIFT) & (1 << 31))-        mods |= GLFW_MOD_SHIFT;-    if (GetKeyState(VK_CONTROL) & (1 << 31))-        mods |= GLFW_MOD_CONTROL;-    if (GetKeyState(VK_MENU) & (1 << 31))-        mods |= GLFW_MOD_ALT;-    if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & (1 << 31))-        mods |= GLFW_MOD_SUPER;--    return mods;-}--// Retrieves and translates modifier keys-//-static int getAsyncKeyMods(void)-{-    int mods = 0;--    if (GetAsyncKeyState(VK_SHIFT) & (1 << 31))-        mods |= GLFW_MOD_SHIFT;-    if (GetAsyncKeyState(VK_CONTROL) & (1 << 31))-        mods |= GLFW_MOD_CONTROL;-    if (GetAsyncKeyState(VK_MENU) & (1 << 31))-        mods |= GLFW_MOD_ALT;-    if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & (1 << 31))-        mods |= GLFW_MOD_SUPER;--    return mods;-}--// Translates a Windows key to the corresponding GLFW key-//-static int translateKey(WPARAM wParam, LPARAM lParam)-{-    if (wParam == VK_CONTROL)-    {-        // The CTRL keys require special handling--        MSG next;-        DWORD time;--        // Is this an extended key (i.e. right key)?-        if (lParam & 0x01000000)-            return GLFW_KEY_RIGHT_CONTROL;--        // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only-        // want the RALT message, so we try to see if the next message-        // is a RALT message. In that case, this is a false LCTRL!-        time = GetMessageTime();--        if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))-        {-            if (next.message == WM_KEYDOWN ||-                next.message == WM_SYSKEYDOWN ||-                next.message == WM_KEYUP ||-                next.message == WM_SYSKEYUP)-            {-                if (next.wParam == VK_MENU &&-                    (next.lParam & 0x01000000) &&-                    next.time == time)-                {-                    // Next message is a RALT down message, which-                    // means that this is not a proper LCTRL message-                    return _GLFW_KEY_INVALID;-                }-            }-        }--        return GLFW_KEY_LEFT_CONTROL;-    }--    return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF];-}--// Enter full screen mode-//-static GLboolean enterFullscreenMode(_GLFWwindow* window)-{-    GLFWvidmode mode;-    GLboolean status;-    int xpos, ypos;--    status = _glfwSetVideoMode(window->monitor, &window->videoMode);--    _glfwPlatformGetVideoMode(window->monitor, &mode);-    _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);--    SetWindowPos(window->win32.handle, HWND_TOPMOST,-                 xpos, ypos, mode.width, mode.height, SWP_NOCOPYBITS);--    return status;-}--// Leave full screen mode-//-static void leaveFullscreenMode(_GLFWwindow* window)-{-    _glfwRestoreVideoMode(window->monitor);-}--// Window callback function (handles window events)-//-static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,-                                   WPARAM wParam, LPARAM lParam)-{-    _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtrW(hWnd, 0);--    switch (uMsg)-    {-        case WM_NCCREATE:-        {-            CREATESTRUCTW* cs = (CREATESTRUCTW*) lParam;-            SetWindowLongPtrW(hWnd, 0, (LONG_PTR) cs->lpCreateParams);-            break;-        }--        case WM_SETFOCUS:-        {-            if (window->cursorMode != GLFW_CURSOR_NORMAL)-                _glfwPlatformApplyCursorMode(window);--            if (window->monitor && window->autoIconify)-                enterFullscreenMode(window);--            _glfwInputWindowFocus(window, GL_TRUE);-            return 0;-        }--        case WM_KILLFOCUS:-        {-            if (window->cursorMode != GLFW_CURSOR_NORMAL)-                restoreCursor(window);--            if (window->monitor && window->autoIconify)-            {-                _glfwPlatformIconifyWindow(window);-                leaveFullscreenMode(window);-            }--            _glfwInputWindowFocus(window, GL_FALSE);-            return 0;-        }--        case WM_SYSCOMMAND:-        {-            switch (wParam & 0xfff0)-            {-                case SC_SCREENSAVE:-                case SC_MONITORPOWER:-                {-                    if (window->monitor)-                    {-                        // We are running in full screen mode, so disallow-                        // screen saver and screen blanking-                        return 0;-                    }-                    else-                        break;-                }--                // User trying to access application menu using ALT?-                case SC_KEYMENU:-                    return 0;-            }-            break;-        }--        case WM_CLOSE:-        {-            _glfwInputWindowCloseRequest(window);-            return 0;-        }--        case WM_KEYDOWN:-        case WM_SYSKEYDOWN:-        {-            const int scancode = (lParam >> 16) & 0x1ff;-            const int key = translateKey(wParam, lParam);-            if (key == _GLFW_KEY_INVALID)-                break;--            _glfwInputKey(window, key, scancode, GLFW_PRESS, getKeyMods());-            break;-        }--        case WM_CHAR:-        {-            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE);-            return 0;-        }--        case WM_SYSCHAR:-        {-            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_FALSE);-            return 0;-        }--        case WM_UNICHAR:-        {-            // This message is not sent by Windows, but is sent by some-            // third-party input method engines--            if (wParam == UNICODE_NOCHAR)-            {-                // Returning TRUE here announces support for this message-                return TRUE;-            }--            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE);-            return FALSE;-        }--        case WM_KEYUP:-        case WM_SYSKEYUP:-        {-            const int mods = getKeyMods();-            const int scancode = (lParam >> 16) & 0x1ff;-            const int key = translateKey(wParam, lParam);-            if (key == _GLFW_KEY_INVALID)-                break;--            if (wParam == VK_SHIFT)-            {-                // Release both Shift keys on Shift up event, as only one event-                // is sent even if both keys are released-                _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);-                _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);-            }-            else if (wParam == VK_SNAPSHOT)-            {-                // Key down is not reported for the print screen key-                _glfwInputKey(window, key, scancode, GLFW_PRESS, mods);-                _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);-            }-            else-                _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);--            break;-        }--        case WM_LBUTTONDOWN:-        case WM_RBUTTONDOWN:-        case WM_MBUTTONDOWN:-        case WM_XBUTTONDOWN:-        {-            const int mods = getKeyMods();--            SetCapture(hWnd);--            if (uMsg == WM_LBUTTONDOWN)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);-            else if (uMsg == WM_RBUTTONDOWN)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);-            else if (uMsg == WM_MBUTTONDOWN)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);-            else-            {-                if (HIWORD(wParam) == XBUTTON1)-                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS, mods);-                else if (HIWORD(wParam) == XBUTTON2)-                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS, mods);--                return TRUE;-            }--            return 0;-        }--        case WM_LBUTTONUP:-        case WM_RBUTTONUP:-        case WM_MBUTTONUP:-        case WM_XBUTTONUP:-        {-            const int mods = getKeyMods();--            ReleaseCapture();--            if (uMsg == WM_LBUTTONUP)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods);-            else if (uMsg == WM_RBUTTONUP)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods);-            else if (uMsg == WM_MBUTTONUP)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods);-            else-            {-                if (HIWORD(wParam) == XBUTTON1)-                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE, mods);-                else if (HIWORD(wParam) == XBUTTON2)-                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE, mods);--                return TRUE;-            }--            return 0;-        }--        case WM_MOUSEMOVE:-        {-            const int x = GET_X_LPARAM(lParam);-            const int y = GET_Y_LPARAM(lParam);--            if (window->cursorMode == GLFW_CURSOR_DISABLED)-            {-                if (_glfw.focusedWindow != window)-                    break;--                _glfwInputCursorMotion(window,-                                        x - window->win32.cursorPosX,-                                        y - window->win32.cursorPosY);-            }-            else-                _glfwInputCursorMotion(window, x, y);--            window->win32.cursorPosX = x;-            window->win32.cursorPosY = y;--            if (!window->win32.cursorInside)-            {-                TRACKMOUSEEVENT tme;-                ZeroMemory(&tme, sizeof(tme));-                tme.cbSize = sizeof(tme);-                tme.dwFlags = TME_LEAVE;-                tme.hwndTrack = window->win32.handle;-                TrackMouseEvent(&tme);--                window->win32.cursorInside = GL_TRUE;-                _glfwInputCursorEnter(window, GL_TRUE);-            }--            return 0;-        }--        case WM_MOUSELEAVE:-        {-            window->win32.cursorInside = GL_FALSE;-            _glfwInputCursorEnter(window, GL_FALSE);-            return 0;-        }--        case WM_MOUSEWHEEL:-        {-            _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);-            return 0;-        }--        case WM_MOUSEHWHEEL:-        {-            // This message is only sent on Windows Vista and later-            // NOTE: The X-axis is inverted for consistency with OS X and X11.-            _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);-            return 0;-        }--        case WM_SIZE:-        {-            if (_glfw.focusedWindow == window)-            {-                if (window->cursorMode == GLFW_CURSOR_DISABLED)-                    updateClipRect(window);-            }--            if (!window->win32.iconified && wParam == SIZE_MINIMIZED)-            {-                window->win32.iconified = GL_TRUE;-                _glfwInputWindowIconify(window, GL_TRUE);-            }-            else if (window->win32.iconified &&-                     (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED))-            {-                window->win32.iconified = GL_FALSE;-                _glfwInputWindowIconify(window, GL_FALSE);-            }--            _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam));-            _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam));-            return 0;-        }--        case WM_MOVE:-        {-            if (_glfw.focusedWindow == window)-            {-                if (window->cursorMode == GLFW_CURSOR_DISABLED)-                    updateClipRect(window);-            }--            // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as-            // those macros do not handle negative window positions correctly-            _glfwInputWindowPos(window,-                                GET_X_LPARAM(lParam),-                                GET_Y_LPARAM(lParam));-            return 0;-        }--        case WM_PAINT:-        {-            _glfwInputWindowDamage(window);-            break;-        }--        case WM_ERASEBKGND:-        {-            return TRUE;-        }--        case WM_SETCURSOR:-        {-            if (_glfw.focusedWindow == window && LOWORD(lParam) == HTCLIENT)-            {-                if (window->cursorMode == GLFW_CURSOR_HIDDEN ||-                    window->cursorMode == GLFW_CURSOR_DISABLED)-                {-                    SetCursor(NULL);-                    return TRUE;-                }-                else if (window->cursor)-                {-                    SetCursor(window->cursor->win32.handle);-                    return TRUE;-                }-            }--            break;-        }--        case WM_DEVICECHANGE:-        {-            if (DBT_DEVNODES_CHANGED == wParam)-            {-                _glfwInputMonitorChange();-                return TRUE;-            }-            break;-        }--        case WM_DWMCOMPOSITIONCHANGED:-        {-            if (_glfwIsCompositionEnabled())-            {-                _GLFWwindow* previous = _glfwPlatformGetCurrentContext();-                _glfwPlatformMakeContextCurrent(window);-                _glfwPlatformSwapInterval(0);-                _glfwPlatformMakeContextCurrent(previous);-            }--            // TODO: Restore vsync if compositing was disabled-            break;-        }--        case WM_DROPFILES:-        {-            HDROP hDrop = (HDROP) wParam;-            POINT pt;-            int i;--            const int count = DragQueryFileW(hDrop, 0xffffffff, NULL, 0);-            char** paths = calloc(count, sizeof(char*));--            // Move the mouse to the position of the drop-            DragQueryPoint(hDrop, &pt);-            _glfwInputCursorMotion(window, pt.x, pt.y);--            for (i = 0;  i < count;  i++)-            {-                const UINT length = DragQueryFileW(hDrop, i, NULL, 0);-                WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));--                DragQueryFileW(hDrop, i, buffer, length + 1);-                paths[i] = _glfwCreateUTF8FromWideString(buffer);--                free(buffer);-            }--            _glfwInputDrop(window, count, (const char**) paths);--            for (i = 0;  i < count;  i++)-                free(paths[i]);-            free(paths);--            DragFinish(hDrop);-            return 0;-        }-    }--    return DefWindowProc(hWnd, uMsg, wParam, lParam);-}--// Translate client window size to full window size (including window borders)-//-static void getFullWindowSize(_GLFWwindow* window,-                              int clientWidth, int clientHeight,-                              int* fullWidth, int* fullHeight)-{-    RECT rect = { 0, 0, clientWidth, clientHeight };-    AdjustWindowRectEx(&rect, window->win32.dwStyle,-                       FALSE, window->win32.dwExStyle);-    *fullWidth = rect.right - rect.left;-    *fullHeight = rect.bottom - rect.top;-}--// Creates the GLFW window and rendering context-//-static int createWindow(_GLFWwindow* window,-                        const _GLFWwndconfig* wndconfig,-                        const _GLFWctxconfig* ctxconfig,-                        const _GLFWfbconfig* fbconfig)-{-    int xpos, ypos, fullWidth, fullHeight;-    WCHAR* wideTitle;--    window->win32.dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;-    window->win32.dwExStyle = WS_EX_APPWINDOW;--    if (window->monitor)-    {-        window->win32.dwStyle |= WS_POPUP;--        // NOTE: This window placement is temporary and approximate, as the-        //       correct position and size cannot be known until the monitor-        //       video mode has been set-        _glfwPlatformGetMonitorPos(wndconfig->monitor, &xpos, &ypos);-        fullWidth  = wndconfig->width;-        fullHeight = wndconfig->height;-    }-    else-    {-        if (wndconfig->decorated)-        {-            window->win32.dwStyle |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;--            if (wndconfig->resizable)-            {-                window->win32.dwStyle |= WS_MAXIMIZEBOX | WS_SIZEBOX;-                window->win32.dwExStyle |= WS_EX_WINDOWEDGE;-            }-        }-        else-            window->win32.dwStyle |= WS_POPUP;--        xpos = CW_USEDEFAULT;-        ypos = CW_USEDEFAULT;--        getFullWindowSize(window,-                          wndconfig->width, wndconfig->height,-                          &fullWidth, &fullHeight);-    }--    wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title);-    if (!wideTitle)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to convert title to wide string");-        return GL_FALSE;-    }--    window->win32.handle = CreateWindowExW(window->win32.dwExStyle,-                                           _GLFW_WNDCLASSNAME,-                                           wideTitle,-                                           window->win32.dwStyle,-                                           xpos, ypos,-                                           fullWidth, fullHeight,-                                           NULL, // No parent window-                                           NULL, // No window menu-                                           GetModuleHandleW(NULL),-                                           window); // Pass object to WM_CREATE--    free(wideTitle);--    if (!window->win32.handle)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window");-        return GL_FALSE;-    }--    if (_glfw_ChangeWindowMessageFilterEx)-    {-        _glfw_ChangeWindowMessageFilterEx(window->win32.handle,-                                          WM_DROPFILES, MSGFLT_ALLOW, NULL);-        _glfw_ChangeWindowMessageFilterEx(window->win32.handle,-                                          WM_COPYDATA, MSGFLT_ALLOW, NULL);-        _glfw_ChangeWindowMessageFilterEx(window->win32.handle,-                                          WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);-    }--    if (wndconfig->floating && !wndconfig->monitor)-    {-        SetWindowPos(window->win32.handle,-                        HWND_TOPMOST,-                        0, 0, 0, 0,-                        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);-    }--    DragAcceptFiles(window->win32.handle, TRUE);--    if (!_glfwCreateContext(window, ctxconfig, fbconfig))-        return GL_FALSE;--    return GL_TRUE;-}--// Destroys the GLFW window and rendering context-//-static void destroyWindow(_GLFWwindow* window)-{-    _glfwDestroyContext(window);--    if (window->win32.handle)-    {-        DestroyWindow(window->win32.handle);-        window->win32.handle = NULL;-    }-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW internal API                      //////-//////////////////////////////////////////////////////////////////////////--// Registers the GLFW window class-//-GLboolean _glfwRegisterWindowClass(void)-{-    WNDCLASSW wc;--    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;-    wc.lpfnWndProc   = (WNDPROC) windowProc;-    wc.cbClsExtra    = 0;                           // No extra class data-    wc.cbWndExtra    = sizeof(void*) + sizeof(int); // Make room for one pointer-    wc.hInstance     = GetModuleHandleW(NULL);-    wc.hCursor       = LoadCursorW(NULL, IDC_ARROW);-    wc.hbrBackground = NULL;                        // No background-    wc.lpszMenuName  = NULL;                        // No menu-    wc.lpszClassName = _GLFW_WNDCLASSNAME;--    // Load user-provided icon if available-    wc.hIcon = LoadIconW(GetModuleHandleW(NULL), L"GLFW_ICON");-    if (!wc.hIcon)-    {-        // No user-provided icon found, load default icon-        wc.hIcon = LoadIconW(NULL, IDI_WINLOGO);-    }--    if (!RegisterClassW(&wc))-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to register window class");-        return GL_FALSE;-    }--    return GL_TRUE;-}--// Unregisters the GLFW window class-//-void _glfwUnregisterWindowClass(void)-{-    UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////--int _glfwPlatformCreateWindow(_GLFWwindow* window,-                              const _GLFWwndconfig* wndconfig,-                              const _GLFWctxconfig* ctxconfig,-                              const _GLFWfbconfig* fbconfig)-{-    int status;--    if (!createWindow(window, wndconfig, ctxconfig, fbconfig))-        return GL_FALSE;--    status = _glfwAnalyzeContext(window, ctxconfig, fbconfig);--    if (status == _GLFW_RECREATION_IMPOSSIBLE)-        return GL_FALSE;--    if (status == _GLFW_RECREATION_REQUIRED)-    {-        // Some window hints require us to re-create the context using WGL-        // extensions retrieved through the current context, as we cannot check-        // for WGL extensions or retrieve WGL entry points before we have a-        // current context (actually until we have implicitly loaded the ICD)--        // Yes, this is strange, and yes, this is the proper way on Win32--        // As Windows only allows you to set the pixel format once for a-        // window, we need to destroy the current window and create a new one-        // to be able to use the new pixel format--        // Technically, it may be possible to keep the old window around if-        // we're just creating an OpenGL 3.0+ context with the same pixel-        // format, but it's not worth the added code complexity--        // First we clear the current context (the one we just created)-        // This is usually done by glfwDestroyWindow, but as we're not doing-        // full GLFW window destruction, it's duplicated here-        _glfwPlatformMakeContextCurrent(NULL);--        // Next destroy the Win32 window and WGL context (without resetting or-        // destroying the GLFW window object)-        destroyWindow(window);--        // ...and then create them again, this time with better APIs-        if (!createWindow(window, wndconfig, ctxconfig, fbconfig))-            return GL_FALSE;-    }--    if (window->monitor)-    {-        _glfwPlatformShowWindow(window);-        if (!enterFullscreenMode(window))-            return GL_FALSE;-    }--    return GL_TRUE;-}--void _glfwPlatformDestroyWindow(_GLFWwindow* window)-{-    if (window->monitor)-        leaveFullscreenMode(window);--    destroyWindow(window);-}--void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)-{-    WCHAR* wideTitle = _glfwCreateWideStringFromUTF8(title);-    if (!wideTitle)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to convert title to wide string");-        return;-    }--    SetWindowTextW(window->win32.handle, wideTitle);-    free(wideTitle);-}--void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)-{-    POINT pos = { 0, 0 };-    ClientToScreen(window->win32.handle, &pos);--    if (xpos)-        *xpos = pos.x;-    if (ypos)-        *ypos = pos.y;-}--void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)-{-    RECT rect = { xpos, ypos, xpos, ypos };-    AdjustWindowRectEx(&rect, window->win32.dwStyle,-                       FALSE, window->win32.dwExStyle);-    SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0,-                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);-}--void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)-{-    RECT area;-    GetClientRect(window->win32.handle, &area);--    if (width)-        *width = area.right;-    if (height)-        *height = area.bottom;-}--void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)-{-    if (window->monitor)-        enterFullscreenMode(window);-    else-    {-        int fullWidth, fullHeight;-        getFullWindowSize(window, width, height, &fullWidth, &fullHeight);--        SetWindowPos(window->win32.handle, HWND_TOP,-                     0, 0, fullWidth, fullHeight,-                     SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);-    }-}--void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)-{-    _glfwPlatformGetWindowSize(window, width, height);-}--void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,-                                     int* left, int* top,-                                     int* right, int* bottom)-{-    RECT rect;-    int width, height;--    _glfwPlatformGetWindowSize(window, &width, &height);-    SetRect(&rect, 0, 0, width, height);-    AdjustWindowRectEx(&rect, window->win32.dwStyle,-                       FALSE, window->win32.dwExStyle);--    if (left)-        *left = -rect.left;-    if (top)-        *top = -rect.top;-    if (right)-        *right = rect.right - width;-    if (bottom)-        *bottom = rect.bottom - height;-}--void _glfwPlatformIconifyWindow(_GLFWwindow* window)-{-    ShowWindow(window->win32.handle, SW_MINIMIZE);-}--void _glfwPlatformRestoreWindow(_GLFWwindow* window)-{-    ShowWindow(window->win32.handle, SW_RESTORE);-}--void _glfwPlatformShowWindow(_GLFWwindow* window)-{-    ShowWindow(window->win32.handle, SW_SHOW);-    BringWindowToTop(window->win32.handle);-    SetForegroundWindow(window->win32.handle);-    SetFocus(window->win32.handle);-}--void _glfwPlatformUnhideWindow(_GLFWwindow* window)-{-    ShowWindow(window->win32.handle, SW_SHOW);-}--void _glfwPlatformHideWindow(_GLFWwindow* window)-{-    ShowWindow(window->win32.handle, SW_HIDE);-}--int _glfwPlatformWindowFocused(_GLFWwindow* window)-{-    return window->win32.handle == GetActiveWindow();-}--int _glfwPlatformWindowIconified(_GLFWwindow* window)-{-    return IsIconic(window->win32.handle);-}--int _glfwPlatformWindowVisible(_GLFWwindow* window)-{-    return IsWindowVisible(window->win32.handle);-}--void _glfwPlatformPollEvents(void)-{-    MSG msg;-    _GLFWwindow* window;--    while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))-    {-        if (msg.message == WM_QUIT)-        {-            // Treat WM_QUIT as a close on all windows-            // While GLFW does not itself post WM_QUIT, other processes may post-            // it to this one, for example Task Manager--            window = _glfw.windowListHead;-            while (window)-            {-                _glfwInputWindowCloseRequest(window);-                window = window->next;-            }-        }-        else-        {-            TranslateMessage(&msg);-            DispatchMessageW(&msg);-        }-    }--    window = _glfw.focusedWindow;-    if (window)-    {-        // LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)-        // This is the only async event handling in GLFW, but it solves some-        // nasty problems-        {-            const int mods = getAsyncKeyMods();--            // Get current state of left and right shift keys-            const int lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;-            const int rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;--            // See if this differs from our belief of what has happened-            // (we only have to check for lost key up events)-            if (!lshiftDown && window->keys[GLFW_KEY_LEFT_SHIFT] == 1)-                _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, 0, GLFW_RELEASE, mods);--            if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1)-                _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, GLFW_RELEASE, mods);-        }--        // Did the cursor move in an focused window that has disabled the cursor-        if (window->cursorMode == GLFW_CURSOR_DISABLED)-        {-            int width, height;-            _glfwPlatformGetWindowSize(window, &width, &height);-            _glfwPlatformSetCursorPos(window, width / 2, height / 2);-        }-    }-}--void _glfwPlatformWaitEvents(void)-{-    WaitMessage();--    _glfwPlatformPollEvents();-}--void _glfwPlatformPostEmptyEvent(void)-{-    _GLFWwindow* window = _glfw.windowListHead;-    PostMessage(window->win32.handle, WM_NULL, 0, 0);-}--void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)-{-    POINT pos;--    if (GetCursorPos(&pos))-    {-        ScreenToClient(window->win32.handle, &pos);--        if (xpos)-            *xpos = pos.x;-        if (ypos)-            *ypos = pos.y;-    }-}--void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)-{-    POINT pos = { (int) xpos, (int) ypos };--    // Store the new position so it can be recognized later-    window->win32.cursorPosX = pos.x;-    window->win32.cursorPosY = pos.y;--    ClientToScreen(window->win32.handle, &pos);-    SetCursorPos(pos.x, pos.y);-}--void _glfwPlatformApplyCursorMode(_GLFWwindow* window)-{-    switch (window->cursorMode)-    {-        case GLFW_CURSOR_NORMAL:-            restoreCursor(window);-            break;-        case GLFW_CURSOR_HIDDEN:-            hideCursor(window);-            break;-        case GLFW_CURSOR_DISABLED:-            disableCursor(window);-            break;-    }-}--int _glfwPlatformCreateCursor(_GLFWcursor* cursor,-                              const GLFWimage* image,-                              int xhot, int yhot)-{-    HDC dc;-    HBITMAP bitmap, mask;-    BITMAPV5HEADER bi;-    ICONINFO ii;-    DWORD* target = 0;-    BYTE* source = (BYTE*) image->pixels;-    int i;--    ZeroMemory(&bi, sizeof(bi));-    bi.bV5Size        = sizeof(BITMAPV5HEADER);-    bi.bV5Width       = image->width;-    bi.bV5Height      = -image->height;-    bi.bV5Planes      = 1;-    bi.bV5BitCount    = 32;-    bi.bV5Compression = BI_BITFIELDS;-    bi.bV5RedMask     = 0x00ff0000;-    bi.bV5GreenMask   = 0x0000ff00;-    bi.bV5BlueMask    = 0x000000ff;-    bi.bV5AlphaMask   = 0xff000000;--    dc = GetDC(NULL);-    bitmap = CreateDIBSection(dc, (BITMAPINFO*) &bi, DIB_RGB_COLORS,-                              (void**) &target, NULL, (DWORD) 0);-    ReleaseDC(NULL, dc);--    if (!bitmap)-        return GL_FALSE;--    mask = CreateBitmap(image->width, image->height, 1, 1, NULL);-    if (!mask)-    {-        DeleteObject(bitmap);-        return GL_FALSE;-    }--    for (i = 0;  i < image->width * image->height;  i++, target++, source += 4)-    {-        *target = (source[3] << 24) |-                  (source[0] << 16) |-                  (source[1] <<  8) |-                   source[2];-    }--    ZeroMemory(&ii, sizeof(ii));-    ii.fIcon    = FALSE;-    ii.xHotspot = xhot;-    ii.yHotspot = yhot;-    ii.hbmMask  = mask;-    ii.hbmColor = bitmap;--    cursor->win32.handle = (HCURSOR) CreateIconIndirect(&ii);--    DeleteObject(bitmap);-    DeleteObject(mask);--    if (!cursor->win32.handle)-        return GL_FALSE;--    return GL_TRUE;-}--int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)-{-    LPCWSTR native = translateCursorShape(shape);-    if (!native)-    {-        _glfwInputError(GLFW_INVALID_ENUM, "Win32: Invalid standard cursor");-        return GL_FALSE;-    }--    cursor->win32.handle = CopyCursor(LoadCursorW(NULL, native));-    if (!cursor->win32.handle)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to retrieve shared cursor");-        return GL_FALSE;-    }--    return GL_TRUE;-}--void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)-{-    if (cursor->win32.handle)-        DestroyIcon((HICON) cursor->win32.handle);-}--void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)-{-    // It should be guaranteed that the cursor is not being used by this window if-    // the following condition is not met. That way it should be safe to destroy the-    // cursor after calling glfwSetCursor(window, NULL) on all windows using the cursor.--    if (_glfw.focusedWindow == window &&-        window->cursorMode == GLFW_CURSOR_NORMAL &&-        window->win32.cursorInside)-    {-        if (cursor)-            SetCursor(cursor->win32.handle);-        else-            SetCursor(LoadCursorW(NULL, IDC_ARROW));-    }-}--void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)-{-    WCHAR* wideString;-    HANDLE stringHandle;-    size_t wideSize;--    wideString = _glfwCreateWideStringFromUTF8(string);-    if (!wideString)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to convert clipboard string to "-                        "wide string");-        return;-    }--    wideSize = (wcslen(wideString) + 1) * sizeof(WCHAR);--    stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideSize);-    if (!stringHandle)-    {-        free(wideString);--        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to allocate global handle for clipboard");-        return;-    }--    memcpy(GlobalLock(stringHandle), wideString, wideSize);-    GlobalUnlock(stringHandle);--    if (!OpenClipboard(window->win32.handle))-    {-        GlobalFree(stringHandle);-        free(wideString);--        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");-        return;-    }--    EmptyClipboard();-    SetClipboardData(CF_UNICODETEXT, stringHandle);-    CloseClipboard();--    free(wideString);-}--const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)-{-    HANDLE stringHandle;--    if (!IsClipboardFormatAvailable(CF_UNICODETEXT))-    {-        _glfwInputError(GLFW_FORMAT_UNAVAILABLE, NULL);-        return NULL;-    }--    if (!OpenClipboard(window->win32.handle))-    {-        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");-        return NULL;-    }--    stringHandle = GetClipboardData(CF_UNICODETEXT);-    if (!stringHandle)-    {-        CloseClipboard();--        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to retrieve clipboard data");-        return NULL;-    }--    free(_glfw.win32.clipboardString);-    _glfw.win32.clipboardString =-        _glfwCreateUTF8FromWideString(GlobalLock(stringHandle));--    GlobalUnlock(stringHandle);-    CloseClipboard();--    if (!_glfw.win32.clipboardString)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Win32: Failed to convert wide string to UTF-8");-        return NULL;-    }--    return _glfw.win32.clipboardString;+// GLFW 3.2 Win32 - www.glfw.org+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Marcus Geelnard+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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 <limits.h>+#include <stdlib.h>+#include <malloc.h>+#include <string.h>+#include <windowsx.h>+#include <shellapi.h>++#define _GLFW_KEY_INVALID -2++// Returns the window style for the specified window+//+static DWORD getWindowStyle(const _GLFWwindow* window)+{+    DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;++    if (window->monitor)+        style |= WS_POPUP;+    else+    {+        if (window->decorated)+        {+            style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;++            if (window->resizable)+                style |= WS_MAXIMIZEBOX | WS_THICKFRAME;+        }+        else+            style |= WS_POPUP;+    }++    return style;+}++// Returns the extended window style for the specified window+//+static DWORD getWindowExStyle(const _GLFWwindow* window)+{+    DWORD style = WS_EX_APPWINDOW;++    if (window->monitor || window->floating)+        style |= WS_EX_TOPMOST;++    return style;+}++// Returns the image whose area most closely matches the desired one+//+static const GLFWimage* chooseImage(int count, const GLFWimage* images,+                                    int width, int height)+{+    int i, leastDiff = INT_MAX;+    const GLFWimage* closest = NULL;++    for (i = 0;  i < count;  i++)+    {+        const int currDiff = abs(images[i].width * images[i].height -+                                 width * height);+        if (currDiff < leastDiff)+        {+            closest = images + i;+            leastDiff = currDiff;+        }+    }++    return closest;+}++// Creates an RGBA icon or cursor+//+static HICON createIcon(const GLFWimage* image,+                        int xhot, int yhot, GLFWbool icon)+{+    int i;+    HDC dc;+    HICON handle;+    HBITMAP color, mask;+    BITMAPV5HEADER bi;+    ICONINFO ii;+    unsigned char* target = NULL;+    unsigned char* source = image->pixels;++    ZeroMemory(&bi, sizeof(bi));+    bi.bV5Size        = sizeof(BITMAPV5HEADER);+    bi.bV5Width       = image->width;+    bi.bV5Height      = -image->height;+    bi.bV5Planes      = 1;+    bi.bV5BitCount    = 32;+    bi.bV5Compression = BI_BITFIELDS;+    bi.bV5RedMask     = 0x00ff0000;+    bi.bV5GreenMask   = 0x0000ff00;+    bi.bV5BlueMask    = 0x000000ff;+    bi.bV5AlphaMask   = 0xff000000;++    dc = GetDC(NULL);+    color = CreateDIBSection(dc,+                             (BITMAPINFO*) &bi,+                             DIB_RGB_COLORS,+                             (void**) &target,+                             NULL,+                             (DWORD) 0);+    ReleaseDC(NULL, dc);++    if (!color)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to create RGBA bitmap");+        return NULL;+    }++    mask = CreateBitmap(image->width, image->height, 1, 1, NULL);+    if (!mask)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to create mask bitmap");+        DeleteObject(color);+        return NULL;+    }++    for (i = 0;  i < image->width * image->height;  i++)+    {+        target[0] = source[2];+        target[1] = source[1];+        target[2] = source[0];+        target[3] = source[3];+        target += 4;+        source += 4;+    }++    ZeroMemory(&ii, sizeof(ii));+    ii.fIcon    = icon;+    ii.xHotspot = xhot;+    ii.yHotspot = yhot;+    ii.hbmMask  = mask;+    ii.hbmColor = color;++    handle = CreateIconIndirect(&ii);++    DeleteObject(color);+    DeleteObject(mask);++    if (!handle)+    {+        if (icon)+            _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create icon");+        else+            _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create cursor");+    }++    return handle;+}++// Translate client window size to full window size according to styles+//+static void getFullWindowSize(DWORD style, DWORD exStyle,+                              int clientWidth, int clientHeight,+                              int* fullWidth, int* fullHeight)+{+    RECT rect = { 0, 0, clientWidth, clientHeight };+    AdjustWindowRectEx(&rect, style, FALSE, exStyle);+    *fullWidth = rect.right - rect.left;+    *fullHeight = rect.bottom - rect.top;+}++// Enforce the client rect aspect ratio based on which edge is being dragged+//+static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)+{+    int xoff, yoff;+    const float ratio = (float) window->numer / (float) window->denom;++    getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),+                      0, 0, &xoff, &yoff);++    if (edge == WMSZ_LEFT  || edge == WMSZ_BOTTOMLEFT ||+        edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT)+    {+        area->bottom = area->top + yoff ++            (int) ((area->right - area->left - xoff) / ratio);+    }+    else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT)+    {+        area->top = area->bottom - yoff -+            (int) ((area->right - area->left - xoff) / ratio);+    }+    else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM)+    {+        area->right = area->left + xoff ++            (int) ((area->bottom - area->top - yoff) * ratio);+    }+}++// Centers the cursor over the window client area+//+static void centerCursor(_GLFWwindow* window)+{+    int width, height;+    _glfwPlatformGetWindowSize(window, &width, &height);+    _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);+}++// Returns whether the cursor is in the client area of the specified window+//+static GLFWbool cursorInClientArea(_GLFWwindow* window)+{+    RECT area;+    POINT pos;++    if (!GetCursorPos(&pos))+        return GLFW_FALSE;++    if (WindowFromPoint(pos) != window->win32.handle)+        return GLFW_FALSE;++    GetClientRect(window->win32.handle, &area);+    ClientToScreen(window->win32.handle, (POINT*) &area.left);+    ClientToScreen(window->win32.handle, (POINT*) &area.right);++    return PtInRect(&area, pos);+}++// Updates the cursor image according to its cursor mode+//+static void updateCursorImage(_GLFWwindow* window)+{+    if (window->cursorMode == GLFW_CURSOR_NORMAL)+    {+        if (window->cursor)+            SetCursor(window->cursor->win32.handle);+        else+            SetCursor(LoadCursorW(NULL, IDC_ARROW));+    }+    else+        SetCursor(NULL);+}++// Updates the cursor clip rect+//+static void updateClipRect(_GLFWwindow* window)+{+    if (window)+    {+        RECT clipRect;+        GetClientRect(window->win32.handle, &clipRect);+        ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);+        ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);+        ClipCursor(&clipRect);+    }+    else+        ClipCursor(NULL);+}++// Translates a GLFW standard cursor to a resource ID+//+static LPWSTR translateCursorShape(int shape)+{+    switch (shape)+    {+        case GLFW_ARROW_CURSOR:+            return IDC_ARROW;+        case GLFW_IBEAM_CURSOR:+            return IDC_IBEAM;+        case GLFW_CROSSHAIR_CURSOR:+            return IDC_CROSS;+        case GLFW_HAND_CURSOR:+            return IDC_HAND;+        case GLFW_HRESIZE_CURSOR:+            return IDC_SIZEWE;+        case GLFW_VRESIZE_CURSOR:+            return IDC_SIZENS;+    }++    return NULL;+}++// Retrieves and translates modifier keys+//+static int getKeyMods(void)+{+    int mods = 0;++    if (GetKeyState(VK_SHIFT) & (1 << 31))+        mods |= GLFW_MOD_SHIFT;+    if (GetKeyState(VK_CONTROL) & (1 << 31))+        mods |= GLFW_MOD_CONTROL;+    if (GetKeyState(VK_MENU) & (1 << 31))+        mods |= GLFW_MOD_ALT;+    if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & (1 << 31))+        mods |= GLFW_MOD_SUPER;++    return mods;+}++// Retrieves and translates modifier keys+//+static int getAsyncKeyMods(void)+{+    int mods = 0;++    if (GetAsyncKeyState(VK_SHIFT) & (1 << 31))+        mods |= GLFW_MOD_SHIFT;+    if (GetAsyncKeyState(VK_CONTROL) & (1 << 31))+        mods |= GLFW_MOD_CONTROL;+    if (GetAsyncKeyState(VK_MENU) & (1 << 31))+        mods |= GLFW_MOD_ALT;+    if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & (1 << 31))+        mods |= GLFW_MOD_SUPER;++    return mods;+}++// Translates a Windows key to the corresponding GLFW key+//+static int translateKey(WPARAM wParam, LPARAM lParam)+{+    if (wParam == VK_CONTROL)+    {+        // The CTRL keys require special handling++        MSG next;+        DWORD time;++        // Is this an extended key (i.e. right key)?+        if (lParam & 0x01000000)+            return GLFW_KEY_RIGHT_CONTROL;++        // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only+        // want the RALT message, so we try to see if the next message+        // is a RALT message. In that case, this is a false LCTRL!+        time = GetMessageTime();++        if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))+        {+            if (next.message == WM_KEYDOWN ||+                next.message == WM_SYSKEYDOWN ||+                next.message == WM_KEYUP ||+                next.message == WM_SYSKEYUP)+            {+                if (next.wParam == VK_MENU &&+                    (next.lParam & 0x01000000) &&+                    next.time == time)+                {+                    // Next message is a RALT down message, which+                    // means that this is not a proper LCTRL message+                    return _GLFW_KEY_INVALID;+                }+            }+        }++        return GLFW_KEY_LEFT_CONTROL;+    }++    if (wParam == VK_PROCESSKEY)+    {+        // IME notifies that keys have been filtered by setting the virtual+        // key-code to VK_PROCESSKEY+        return _GLFW_KEY_INVALID;+    }++    return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF];+}++// Make the specified window and its video mode active on its monitor+//+static GLFWbool acquireMonitor(_GLFWwindow* window)+{+    GLFWvidmode mode;+    GLFWbool status;+    int xpos, ypos;++    status = _glfwSetVideoModeWin32(window->monitor, &window->videoMode);++    _glfwPlatformGetVideoMode(window->monitor, &mode);+    _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);++    SetWindowPos(window->win32.handle, HWND_TOPMOST,+                 xpos, ypos, mode.width, mode.height,+                 SWP_NOACTIVATE | SWP_NOCOPYBITS);++    _glfwInputMonitorWindowChange(window->monitor, window);+    return status;+}++// Remove the window and restore the original video mode+//+static void releaseMonitor(_GLFWwindow* window)+{+    if (window->monitor->window != window)+        return;++    _glfwInputMonitorWindowChange(window->monitor, NULL);+    _glfwRestoreVideoModeWin32(window->monitor);+}++// Window callback function (handles window messages)+//+static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,+                                   WPARAM wParam, LPARAM lParam)+{+    _GLFWwindow* window = GetPropW(hWnd, L"GLFW");+    if (!window)+    {+        // This is the message handling for the hidden helper window++        switch (uMsg)+        {+            case WM_DEVICECHANGE:+            {+                if (wParam == DBT_DEVNODES_CHANGED)+                {+                    _glfwInputMonitorChange();+                    return TRUE;+                }+                else if (wParam == DBT_DEVICEARRIVAL)+                {+                    DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;+                    if (dbh)+                    {+                        if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)+                            _glfwDetectJoystickConnectionWin32();+                    }+                }+                else if (wParam == DBT_DEVICEREMOVECOMPLETE)+                {+                    DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;+                    if (dbh)+                    {+                        if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)+                            _glfwDetectJoystickDisconnectionWin32();+                    }+                }++                break;+            }+        }++        return DefWindowProcW(hWnd, uMsg, wParam, lParam);+    }++    switch (uMsg)+    {+        case WM_SETFOCUS:+        {+            _glfwInputWindowFocus(window, GLFW_TRUE);++            if (window->cursorMode == GLFW_CURSOR_DISABLED)+                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);++            return 0;+        }++        case WM_KILLFOCUS:+        {+            if (window->cursorMode == GLFW_CURSOR_DISABLED)+                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);++            if (window->monitor && window->autoIconify)+                _glfwPlatformIconifyWindow(window);++            _glfwInputWindowFocus(window, GLFW_FALSE);+            return 0;+        }++        case WM_SYSCOMMAND:+        {+            switch (wParam & 0xfff0)+            {+                case SC_SCREENSAVE:+                case SC_MONITORPOWER:+                {+                    if (window->monitor)+                    {+                        // We are running in full screen mode, so disallow+                        // screen saver and screen blanking+                        return 0;+                    }+                    else+                        break;+                }++                // User trying to access application menu using ALT?+                case SC_KEYMENU:+                    return 0;+            }+            break;+        }++        case WM_CLOSE:+        {+            _glfwInputWindowCloseRequest(window);+            return 0;+        }++        case WM_CHAR:+        case WM_SYSCHAR:+        case WM_UNICHAR:+        {+            const GLFWbool plain = (uMsg != WM_SYSCHAR);++            if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR)+            {+                // WM_UNICHAR is not sent by Windows, but is sent by some+                // third-party input method engine+                // Returning TRUE here announces support for this message+                return TRUE;+            }++            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain);+            return 0;+        }++        case WM_KEYDOWN:+        case WM_SYSKEYDOWN:+        case WM_KEYUP:+        case WM_SYSKEYUP:+        {+            const int key = translateKey(wParam, lParam);+            const int scancode = (lParam >> 16) & 0x1ff;+            const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS;+            const int mods = getKeyMods();++            if (key == _GLFW_KEY_INVALID)+                break;++            if (action == GLFW_RELEASE && wParam == VK_SHIFT)+            {+                // Release both Shift keys on Shift up event, as only one event+                // is sent even if both keys are released+                _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods);+                _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods);+            }+            else if (wParam == VK_SNAPSHOT)+            {+                // Key down is not reported for the Print Screen key+                _glfwInputKey(window, key, scancode, GLFW_PRESS, mods);+                _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);+            }+            else+                _glfwInputKey(window, key, scancode, action, mods);++            break;+        }++        case WM_LBUTTONDOWN:+        case WM_RBUTTONDOWN:+        case WM_MBUTTONDOWN:+        case WM_XBUTTONDOWN:+        case WM_LBUTTONUP:+        case WM_RBUTTONUP:+        case WM_MBUTTONUP:+        case WM_XBUTTONUP:+        {+            int button, action;++            if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)+                button = GLFW_MOUSE_BUTTON_LEFT;+            else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP)+                button = GLFW_MOUSE_BUTTON_RIGHT;+            else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)+                button = GLFW_MOUSE_BUTTON_MIDDLE;+            else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)+                button = GLFW_MOUSE_BUTTON_4;+            else+                button = GLFW_MOUSE_BUTTON_5;++            if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN ||+                uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN)+            {+                action = GLFW_PRESS;+                SetCapture(hWnd);+            }+            else+            {+                action = GLFW_RELEASE;+                ReleaseCapture();+            }++            _glfwInputMouseClick(window, button, action, getKeyMods());++            if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)+                return TRUE;++            return 0;+        }++        case WM_MOUSEMOVE:+        {+            const int x = GET_X_LPARAM(lParam);+            const int y = GET_Y_LPARAM(lParam);++            if (window->cursorMode == GLFW_CURSOR_DISABLED)+            {+                const int dx = x - window->win32.lastCursorPosX;+                const int dy = y - window->win32.lastCursorPosY;++                if (_glfw.win32.disabledCursorWindow != window)+                    break;++                _glfwInputCursorPos(window,+                                    window->virtualCursorPosX + dx,+                                    window->virtualCursorPosY + dy);+            }+            else+                _glfwInputCursorPos(window, x, y);++            window->win32.lastCursorPosX = x;+            window->win32.lastCursorPosY = y;++            if (!window->win32.cursorTracked)+            {+                TRACKMOUSEEVENT tme;+                ZeroMemory(&tme, sizeof(tme));+                tme.cbSize = sizeof(tme);+                tme.dwFlags = TME_LEAVE;+                tme.hwndTrack = window->win32.handle;+                TrackMouseEvent(&tme);++                window->win32.cursorTracked = GLFW_TRUE;+                _glfwInputCursorEnter(window, GLFW_TRUE);+            }++            return 0;+        }++        case WM_MOUSELEAVE:+        {+            window->win32.cursorTracked = GLFW_FALSE;+            _glfwInputCursorEnter(window, GLFW_FALSE);+            return 0;+        }++        case WM_MOUSEWHEEL:+        {+            _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);+            return 0;+        }++        case WM_MOUSEHWHEEL:+        {+            // This message is only sent on Windows Vista and later+            // NOTE: The X-axis is inverted for consistency with OS X and X11.+            _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);+            return 0;+        }++        case WM_ENTERSIZEMOVE:+        case WM_ENTERMENULOOP:+        {+            if (window->cursorMode == GLFW_CURSOR_DISABLED)+                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);++            break;+        }++        case WM_EXITSIZEMOVE:+        case WM_EXITMENULOOP:+        {+            if (window->cursorMode == GLFW_CURSOR_DISABLED)+                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);++            break;+        }++        case WM_SIZE:+        {+            const GLFWbool iconified =+                !window->win32.iconified && wParam == SIZE_MINIMIZED;+            const GLFWbool restored =+                window->win32.iconified &&+                (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED);++            if (_glfw.win32.disabledCursorWindow == window)+                updateClipRect(window);++            if (iconified)+                _glfwInputWindowIconify(window, GLFW_TRUE);+            else if (restored)+                _glfwInputWindowIconify(window, GLFW_FALSE);++            _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam));+            _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam));++            if (iconified)+            {+                window->win32.iconified = GLFW_TRUE;+                if (window->monitor)+                    releaseMonitor(window);+            }+            else if (restored)+            {+                window->win32.iconified = GLFW_FALSE;+                if (window->monitor)+                    acquireMonitor(window);+            }++            return 0;+        }++        case WM_MOVE:+        {+            if (_glfw.win32.disabledCursorWindow == window)+                updateClipRect(window);++            // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as+            // those macros do not handle negative window positions correctly+            _glfwInputWindowPos(window,+                                GET_X_LPARAM(lParam),+                                GET_Y_LPARAM(lParam));+            return 0;+        }++        case WM_SIZING:+        {+            if (window->numer == GLFW_DONT_CARE ||+                window->denom == GLFW_DONT_CARE)+            {+                break;+            }++            applyAspectRatio(window, (int) wParam, (RECT*) lParam);+            return TRUE;+        }++        case WM_GETMINMAXINFO:+        {+            int xoff, yoff;+            MINMAXINFO* mmi = (MINMAXINFO*) lParam;++            if (window->monitor)+                break;++            getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),+                              0, 0, &xoff, &yoff);++            if (window->minwidth != GLFW_DONT_CARE &&+                window->minheight != GLFW_DONT_CARE)+            {+                mmi->ptMinTrackSize.x = window->minwidth + xoff;+                mmi->ptMinTrackSize.y = window->minheight + yoff;+            }++            if (window->maxwidth != GLFW_DONT_CARE &&+                window->maxheight != GLFW_DONT_CARE)+            {+                mmi->ptMaxTrackSize.x = window->maxwidth + xoff;+                mmi->ptMaxTrackSize.y = window->maxheight + yoff;+            }++            return 0;+        }++        case WM_PAINT:+        {+            _glfwInputWindowDamage(window);+            break;+        }++        case WM_ERASEBKGND:+        {+            return TRUE;+        }++        case WM_SETCURSOR:+        {+            if (LOWORD(lParam) == HTCLIENT)+            {+                updateCursorImage(window);+                return TRUE;+            }++            break;+        }++        case WM_DPICHANGED:+        {+            RECT* rect = (RECT*) lParam;+            SetWindowPos(window->win32.handle,+                         HWND_TOP,+                         rect->left,+                         rect->top,+                         rect->right - rect->left,+                         rect->bottom - rect->top,+                         SWP_NOACTIVATE | SWP_NOZORDER);+            break;+        }++        case WM_DROPFILES:+        {+            HDROP drop = (HDROP) wParam;+            POINT pt;+            int i;++            const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0);+            char** paths = calloc(count, sizeof(char*));++            // Move the mouse to the position of the drop+            DragQueryPoint(drop, &pt);+            _glfwInputCursorPos(window, pt.x, pt.y);++            for (i = 0;  i < count;  i++)+            {+                const UINT length = DragQueryFileW(drop, i, NULL, 0);+                WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));++                DragQueryFileW(drop, i, buffer, length + 1);+                paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);++                free(buffer);+            }++            _glfwInputDrop(window, count, (const char**) paths);++            for (i = 0;  i < count;  i++)+                free(paths[i]);+            free(paths);++            DragFinish(drop);+            return 0;+        }+    }++    return DefWindowProcW(hWnd, uMsg, wParam, lParam);+}++// Creates the GLFW window+//+static int createNativeWindow(_GLFWwindow* window,+                              const _GLFWwndconfig* wndconfig)+{+    int xpos, ypos, fullWidth, fullHeight;+    WCHAR* wideTitle;+    DWORD style = getWindowStyle(window);+    DWORD exStyle = getWindowExStyle(window);++    if (window->monitor)+    {+        GLFWvidmode mode;++        // NOTE: This window placement is temporary and approximate, as the+        //       correct position and size cannot be known until the monitor+        //       video mode has been set+        _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);+        _glfwPlatformGetVideoMode(window->monitor, &mode);+        fullWidth  = mode.width;+        fullHeight = mode.height;+    }+    else+    {+        xpos = CW_USEDEFAULT;+        ypos = CW_USEDEFAULT;++        if (wndconfig->maximized)+            style |= WS_MAXIMIZE;++        getFullWindowSize(style, exStyle,+                          wndconfig->width, wndconfig->height,+                          &fullWidth, &fullHeight);+    }++    wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);+    if (!wideTitle)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to convert window title to UTF-16");+        return GLFW_FALSE;+    }++    window->win32.handle = CreateWindowExW(exStyle,+                                           _GLFW_WNDCLASSNAME,+                                           wideTitle,+                                           style,+                                           xpos, ypos,+                                           fullWidth, fullHeight,+                                           NULL, // No parent window+                                           NULL, // No window menu+                                           GetModuleHandleW(NULL),+                                           NULL);++    free(wideTitle);++    if (!window->win32.handle)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window");+        return GLFW_FALSE;+    }++    SetPropW(window->win32.handle, L"GLFW", window);++    if (_glfw_ChangeWindowMessageFilterEx)+    {+        _glfw_ChangeWindowMessageFilterEx(window->win32.handle,+                                          WM_DROPFILES, MSGFLT_ALLOW, NULL);+        _glfw_ChangeWindowMessageFilterEx(window->win32.handle,+                                          WM_COPYDATA, MSGFLT_ALLOW, NULL);+        _glfw_ChangeWindowMessageFilterEx(window->win32.handle,+                                          WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);+    }++    DragAcceptFiles(window->win32.handle, TRUE);++    return GLFW_TRUE;+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW internal API                      //////+//////////////////////////////////////////////////////////////////////////++// Registers the GLFW window class+//+GLFWbool _glfwRegisterWindowClassWin32(void)+{+    WNDCLASSEXW wc;++    ZeroMemory(&wc, sizeof(wc));+    wc.cbSize        = sizeof(wc);+    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;+    wc.lpfnWndProc   = (WNDPROC) windowProc;+    wc.hInstance     = GetModuleHandleW(NULL);+    wc.hCursor       = LoadCursorW(NULL, IDC_ARROW);+    wc.lpszClassName = _GLFW_WNDCLASSNAME;++    // Load user-provided icon if available+    wc.hIcon = LoadImageW(GetModuleHandleW(NULL),+                          L"GLFW_ICON", IMAGE_ICON,+                          0, 0, LR_DEFAULTSIZE | LR_SHARED);+    if (!wc.hIcon)+    {+        // No user-provided icon found, load default icon+        wc.hIcon = LoadImageW(NULL,+                              IDI_APPLICATION, IMAGE_ICON,+                              0, 0, LR_DEFAULTSIZE | LR_SHARED);+    }++    if (!RegisterClassExW(&wc))+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to register window class");+        return GLFW_FALSE;+    }++    return GLFW_TRUE;+}++// Unregisters the GLFW window class+//+void _glfwUnregisterWindowClassWin32(void)+{+    UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW platform API                      //////+//////////////////////////////////////////////////////////////////////////++int _glfwPlatformCreateWindow(_GLFWwindow* window,+                              const _GLFWwndconfig* wndconfig,+                              const _GLFWctxconfig* ctxconfig,+                              const _GLFWfbconfig* fbconfig)+{+    if (!createNativeWindow(window, wndconfig))+        return GLFW_FALSE;++    if (ctxconfig->client != GLFW_NO_API)+    {+        if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)+        {+            if (!_glfwInitWGL())+                return GLFW_FALSE;+            if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))+                return GLFW_FALSE;+        }+        else+        {+            if (!_glfwInitEGL())+                return GLFW_FALSE;+            if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))+                return GLFW_FALSE;+        }+    }++    if (window->monitor)+    {+        _glfwPlatformShowWindow(window);+        _glfwPlatformFocusWindow(window);+        if (!acquireMonitor(window))+            return GLFW_FALSE;++        centerCursor(window);+    }++    return GLFW_TRUE;+}++void _glfwPlatformDestroyWindow(_GLFWwindow* window)+{+    if (window->monitor)+        releaseMonitor(window);++    if (window->context.destroy)+        window->context.destroy(window);++    if (_glfw.win32.disabledCursorWindow == window)+        _glfw.win32.disabledCursorWindow = NULL;++    if (window->win32.handle)+    {+        RemovePropW(window->win32.handle, L"GLFW");+        DestroyWindow(window->win32.handle);+        window->win32.handle = NULL;+    }++    if (window->win32.bigIcon)+        DestroyIcon(window->win32.bigIcon);++    if (window->win32.smallIcon)+        DestroyIcon(window->win32.smallIcon);+}++void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)+{+    WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);+    if (!wideTitle)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to convert window title to UTF-16");+        return;+    }++    SetWindowTextW(window->win32.handle, wideTitle);+    free(wideTitle);+}++void _glfwPlatformSetWindowIcon(_GLFWwindow* window,+                                int count, const GLFWimage* images)+{+    HICON bigIcon = NULL, smallIcon = NULL;++    if (count)+    {+        const GLFWimage* bigImage = chooseImage(count, images,+                                                GetSystemMetrics(SM_CXICON),+                                                GetSystemMetrics(SM_CYICON));+        const GLFWimage* smallImage = chooseImage(count, images,+                                                  GetSystemMetrics(SM_CXSMICON),+                                                  GetSystemMetrics(SM_CYSMICON));++        bigIcon = createIcon(bigImage, 0, 0, GLFW_TRUE);+        smallIcon = createIcon(smallImage, 0, 0, GLFW_TRUE);+    }+    else+    {+        bigIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICON);+        smallIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICONSM);+    }++    SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon);+    SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon);++    if (window->win32.bigIcon)+        DestroyIcon(window->win32.bigIcon);++    if (window->win32.smallIcon)+        DestroyIcon(window->win32.smallIcon);++    if (count)+    {+        window->win32.bigIcon = bigIcon;+        window->win32.smallIcon = smallIcon;+    }+}++void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)+{+    POINT pos = { 0, 0 };+    ClientToScreen(window->win32.handle, &pos);++    if (xpos)+        *xpos = pos.x;+    if (ypos)+        *ypos = pos.y;+}++void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)+{+    RECT rect = { xpos, ypos, xpos, ypos };+    AdjustWindowRectEx(&rect, getWindowStyle(window),+                       FALSE, getWindowExStyle(window));+    SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0,+                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);+}++void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)+{+    RECT area;+    GetClientRect(window->win32.handle, &area);++    if (width)+        *width = area.right;+    if (height)+        *height = area.bottom;+}++void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)+{+    if (window->monitor)+    {+        if (window->monitor->window == window)+            acquireMonitor(window);+    }+    else+    {+        RECT rect = { 0, 0, width, height };+        AdjustWindowRectEx(&rect, getWindowStyle(window),+                           FALSE, getWindowExStyle(window));+        SetWindowPos(window->win32.handle, HWND_TOP,+                     0, 0, rect.right - rect.left, rect.bottom - rect.top,+                     SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);+    }+}++void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,+                                      int minwidth, int minheight,+                                      int maxwidth, int maxheight)+{+    RECT area;++    if ((minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) &&+        (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE))+    {+        return;+    }++    GetWindowRect(window->win32.handle, &area);+    MoveWindow(window->win32.handle,+               area.left, area.top,+               area.right - area.left,+               area.bottom - area.top, TRUE);+}++void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)+{+    RECT area;++    if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)+        return;++    GetWindowRect(window->win32.handle, &area);+    applyAspectRatio(window, WMSZ_BOTTOMRIGHT, &area);+    MoveWindow(window->win32.handle,+               area.left, area.top,+               area.right - area.left,+               area.bottom - area.top, TRUE);+}++void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)+{+    _glfwPlatformGetWindowSize(window, width, height);+}++void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,+                                     int* left, int* top,+                                     int* right, int* bottom)+{+    RECT rect;+    int width, height;++    _glfwPlatformGetWindowSize(window, &width, &height);+    SetRect(&rect, 0, 0, width, height);+    AdjustWindowRectEx(&rect, getWindowStyle(window),+                       FALSE, getWindowExStyle(window));++    if (left)+        *left = -rect.left;+    if (top)+        *top = -rect.top;+    if (right)+        *right = rect.right - width;+    if (bottom)+        *bottom = rect.bottom - height;+}++void _glfwPlatformIconifyWindow(_GLFWwindow* window)+{+    ShowWindow(window->win32.handle, SW_MINIMIZE);+}++void _glfwPlatformRestoreWindow(_GLFWwindow* window)+{+    ShowWindow(window->win32.handle, SW_RESTORE);+}++void _glfwPlatformMaximizeWindow(_GLFWwindow* window)+{+    ShowWindow(window->win32.handle, SW_MAXIMIZE);+}++void _glfwPlatformShowWindow(_GLFWwindow* window)+{+    ShowWindow(window->win32.handle, SW_SHOW);+}++void _glfwPlatformHideWindow(_GLFWwindow* window)+{+    ShowWindow(window->win32.handle, SW_HIDE);+}++void _glfwPlatformFocusWindow(_GLFWwindow* window)+{+    BringWindowToTop(window->win32.handle);+    SetForegroundWindow(window->win32.handle);+    SetFocus(window->win32.handle);+}++void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,+                                   _GLFWmonitor* monitor,+                                   int xpos, int ypos,+                                   int width, int height,+                                   int refreshRate)+{+    if (window->monitor == monitor)+    {+        if (monitor)+        {+            if (monitor->window == window)+                acquireMonitor(window);+        }+        else+        {+            RECT rect = { xpos, ypos, xpos + width, ypos + height };+            AdjustWindowRectEx(&rect, getWindowStyle(window),+                               FALSE, getWindowExStyle(window));+            SetWindowPos(window->win32.handle, HWND_TOP,+                         rect.left, rect.top,+                         rect.right - rect.left, rect.bottom - rect.top,+                         SWP_NOCOPYBITS | SWP_NOACTIVATE | SWP_NOZORDER);+        }++        return;+    }++    if (window->monitor)+        releaseMonitor(window);++    _glfwInputWindowMonitorChange(window, monitor);++    if (monitor)+    {+        GLFWvidmode mode;+        DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);+        UINT flags = SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOCOPYBITS;++        if (window->decorated)+        {+            style &= ~WS_OVERLAPPEDWINDOW;+            style |= getWindowStyle(window);+            SetWindowLongW(window->win32.handle, GWL_STYLE, style);++            flags |= SWP_FRAMECHANGED;+        }++        _glfwPlatformGetVideoMode(monitor, &mode);+        _glfwPlatformGetMonitorPos(monitor, &xpos, &ypos);++        SetWindowPos(window->win32.handle, HWND_TOPMOST,+                     xpos, ypos, mode.width, mode.height,+                     flags);++        acquireMonitor(window);+    }+    else+    {+        HWND after;+        RECT rect = { xpos, ypos, xpos + width, ypos + height };+        DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);+        UINT flags = SWP_NOACTIVATE | SWP_NOCOPYBITS;++        if (window->decorated)+        {+            style &= ~WS_POPUP;+            style |= getWindowStyle(window);+            SetWindowLongW(window->win32.handle, GWL_STYLE, style);++            flags |= SWP_FRAMECHANGED;+        }++        if (window->floating)+            after = HWND_TOPMOST;+        else+            after = HWND_NOTOPMOST;++        AdjustWindowRectEx(&rect, getWindowStyle(window),+                           FALSE, getWindowExStyle(window));+        SetWindowPos(window->win32.handle, after,+                     rect.left, rect.top,+                     rect.right - rect.left, rect.bottom - rect.top,+                     flags);+    }+}++int _glfwPlatformWindowFocused(_GLFWwindow* window)+{+    return window->win32.handle == GetActiveWindow();+}++int _glfwPlatformWindowIconified(_GLFWwindow* window)+{+    return IsIconic(window->win32.handle);+}++int _glfwPlatformWindowVisible(_GLFWwindow* window)+{+    return IsWindowVisible(window->win32.handle);+}++int _glfwPlatformWindowMaximized(_GLFWwindow* window)+{+    return IsZoomed(window->win32.handle);+}++void _glfwPlatformPollEvents(void)+{+    MSG msg;+    HWND handle;+    _GLFWwindow* window;++    while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))+    {+        if (msg.message == WM_QUIT)+        {+            // Treat WM_QUIT as a close on all windows+            // While GLFW does not itself post WM_QUIT, other processes may post+            // it to this one, for example Task Manager++            window = _glfw.windowListHead;+            while (window)+            {+                _glfwInputWindowCloseRequest(window);+                window = window->next;+            }+        }+        else+        {+            TranslateMessage(&msg);+            DispatchMessageW(&msg);+        }+    }++    handle = GetActiveWindow();+    if (handle)+    {+        // LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)+        // This is the only async event handling in GLFW, but it solves some+        // nasty problems+        window = GetPropW(handle, L"GLFW");+        if (window)+        {+            const int mods = getAsyncKeyMods();++            // Get current state of left and right shift keys+            const int lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;+            const int rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;++            // See if this differs from our belief of what has happened+            // (we only have to check for lost key up events)+            if (!lshiftDown && window->keys[GLFW_KEY_LEFT_SHIFT] == 1)+                _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, 0, GLFW_RELEASE, mods);++            if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1)+                _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, GLFW_RELEASE, mods);+        }+    }++    window = _glfw.win32.disabledCursorWindow;+    if (window)+    {+        int width, height;+        _glfwPlatformGetWindowSize(window, &width, &height);++        // NOTE: Re-center the cursor only if it has moved since the last call,+        //       to avoid breaking glfwWaitEvents with WM_MOUSEMOVE+        if (window->win32.lastCursorPosX != width / 2 ||+            window->win32.lastCursorPosY != height / 2)+        {+            _glfwPlatformSetCursorPos(window, width / 2, height / 2);+        }+    }+}++void _glfwPlatformWaitEvents(void)+{+    WaitMessage();++    _glfwPlatformPollEvents();+}++void _glfwPlatformWaitEventsTimeout(double timeout)+{+    MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);++    _glfwPlatformPollEvents();+}++void _glfwPlatformPostEmptyEvent(void)+{+    _GLFWwindow* window = _glfw.windowListHead;+    PostMessage(window->win32.handle, WM_NULL, 0, 0);+}++void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)+{+    POINT pos;++    if (GetCursorPos(&pos))+    {+        ScreenToClient(window->win32.handle, &pos);++        if (xpos)+            *xpos = pos.x;+        if (ypos)+            *ypos = pos.y;+    }+}++void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)+{+    POINT pos = { (int) xpos, (int) ypos };++    // Store the new position so it can be recognized later+    window->win32.lastCursorPosX = pos.x;+    window->win32.lastCursorPosY = pos.y;++    ClientToScreen(window->win32.handle, &pos);+    SetCursorPos(pos.x, pos.y);+}++void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)+{+    if (mode == GLFW_CURSOR_DISABLED)+    {+        _glfw.win32.disabledCursorWindow = window;+        _glfwPlatformGetCursorPos(window,+                                  &_glfw.win32.restoreCursorPosX,+                                  &_glfw.win32.restoreCursorPosY);+        centerCursor(window);+        updateClipRect(window);+    }+    else if (_glfw.win32.disabledCursorWindow == window)+    {+        _glfw.win32.disabledCursorWindow = NULL;+        updateClipRect(NULL);+        _glfwPlatformSetCursorPos(window,+                                  _glfw.win32.restoreCursorPosX,+                                  _glfw.win32.restoreCursorPosY);+    }++    if (cursorInClientArea(window))+        updateCursorImage(window);+}++const char* _glfwPlatformGetKeyName(int key, int scancode)+{+    WCHAR name[16];++    if (key != GLFW_KEY_UNKNOWN)+        scancode = _glfw.win32.nativeKeys[key];++    if (!_glfwIsPrintable(_glfw.win32.publicKeys[scancode]))+        return NULL;++    if (!GetKeyNameTextW(scancode << 16, name, sizeof(name) / sizeof(WCHAR)))+        return NULL;++    if (!WideCharToMultiByte(CP_UTF8, 0, name, -1,+                             _glfw.win32.keyName,+                             sizeof(_glfw.win32.keyName),+                             NULL, NULL))+    {+        return NULL;+    }++    return _glfw.win32.keyName;+}++int _glfwPlatformCreateCursor(_GLFWcursor* cursor,+                              const GLFWimage* image,+                              int xhot, int yhot)+{+    cursor->win32.handle = (HCURSOR) createIcon(image, xhot, yhot, GLFW_FALSE);+    if (!cursor->win32.handle)+        return GLFW_FALSE;++    return GLFW_TRUE;+}++int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)+{+    cursor->win32.handle =+        CopyCursor(LoadCursorW(NULL, translateCursorShape(shape)));+    if (!cursor->win32.handle)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to create standard cursor");+        return GLFW_FALSE;+    }++    return GLFW_TRUE;+}++void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)+{+    if (cursor->win32.handle)+        DestroyIcon((HICON) cursor->win32.handle);+}++void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)+{+    if (cursorInClientArea(window))+        updateCursorImage(window);+}++void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)+{+    int characterCount;+    HANDLE object;+    WCHAR* buffer;++    characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);+    if (!characterCount)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to convert clipboard string to UTF-16");+        return;+    }++    object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));+    if (!object)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to allocate global handle for clipboard");+        return;+    }++    buffer = GlobalLock(object);+    if (!buffer)+    {+        GlobalFree(object);++        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");+        return;+    }++    MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount);+    GlobalUnlock(object);++    if (!OpenClipboard(_glfw.win32.helperWindowHandle))+    {+        GlobalFree(object);++        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");+        return;+    }++    EmptyClipboard();+    SetClipboardData(CF_UNICODETEXT, object);+    CloseClipboard();+}++const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)+{+    HANDLE object;+    WCHAR* buffer;++    if (!OpenClipboard(_glfw.win32.helperWindowHandle))+    {+        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");+        return NULL;+    }++    object = GetClipboardData(CF_UNICODETEXT);+    if (!object)+    {+        CloseClipboard();++        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,+                        "Win32: Failed to convert clipboard to string");+        return NULL;+    }++    buffer = GlobalLock(object);+    if (!buffer)+    {+        CloseClipboard();++        _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");+        return NULL;+    }++    free(_glfw.win32.clipboardString);+    _glfw.win32.clipboardString =+        _glfwCreateUTF8FromWideStringWin32(buffer);++    GlobalUnlock(object);+    CloseClipboard();++    if (!_glfw.win32.clipboardString)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to convert wide string to UTF-8");+        return NULL;+    }++    return _glfw.win32.clipboardString;+}++char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count)+{+    char** extensions;++    *count = 0;++    if (!_glfw.vk.KHR_win32_surface)+        return NULL;++    extensions = calloc(2, sizeof(char*));+    extensions[0] = strdup("VK_KHR_surface");+    extensions[1] = strdup("VK_KHR_win32_surface");++    *count = 2;+    return extensions;+}++int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,+                                                      VkPhysicalDevice device,+                                                      uint32_t queuefamily)+{+    PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =+        (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)+        vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");+    if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Win32: Vulkan instance missing VK_KHR_win32_surface extension");+        return GLFW_FALSE;+    }++    return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily);+}++VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,+                                          _GLFWwindow* window,+                                          const VkAllocationCallbacks* allocator,+                                          VkSurfaceKHR* surface)+{+    VkResult err;+    VkWin32SurfaceCreateInfoKHR sci;+    PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;++    vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)+        vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");+    if (!vkCreateWin32SurfaceKHR)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Win32: Vulkan instance missing VK_KHR_win32_surface extension");+        return VK_ERROR_EXTENSION_NOT_PRESENT;+    }++    memset(&sci, 0, sizeof(sci));+    sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;+    sci.hinstance = GetModuleHandle(NULL);+    sci.hwnd = window->win32.handle;++    err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);+    if (err)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Win32: Failed to create Vulkan surface: %s",+                        _glfwGetVulkanResultString(err));+    }++    return err; }  
glfw/src/window.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 - www.glfw.org+// GLFW 3.2 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org> // Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net> // // This software is provided 'as-is', without any express or implied@@ -28,20 +28,20 @@  #include "internal.h" +#include <assert.h> #include <string.h> #include <stdlib.h>+#include <float.h>   ////////////////////////////////////////////////////////////////////////// //////                         GLFW event API                       ////// ////////////////////////////////////////////////////////////////////////// -void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused)+void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused) {     if (focused)     {-        _glfw.focusedWindow = window;-         if (window->callbacks.focus)             window->callbacks.focus((GLFWwindow*) window, focused);     }@@ -49,8 +49,6 @@     {         int i; -        _glfw.focusedWindow = NULL;-         if (window->callbacks.focus)             window->callbacks.focus((GLFWwindow*) window, focused); @@ -82,7 +80,7 @@         window->callbacks.size((GLFWwindow*) window, width, height); } -void _glfwInputWindowIconify(_GLFWwindow* window, int iconified)+void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified) {     if (window->callbacks.iconify)         window->callbacks.iconify((GLFWwindow*) window, iconified);@@ -102,13 +100,18 @@  void _glfwInputWindowCloseRequest(_GLFWwindow* window) {-    window->closed = GL_TRUE;+    window->closed = GLFW_TRUE;      if (window->callbacks.close)         window->callbacks.close((GLFWwindow*) window); } +void _glfwInputWindowMonitorChange(_GLFWwindow* window, _GLFWmonitor* monitor)+{+    window->monitor = monitor;+} + ////////////////////////////////////////////////////////////////////////// //////                        GLFW public API                       ////// //////////////////////////////////////////////////////////////////////////@@ -124,55 +127,38 @@     _GLFWwindow* window;     _GLFWwindow* previous; +    assert(title != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);      if (width <= 0 || height <= 0)     {-        _glfwInputError(GLFW_INVALID_VALUE, "Invalid window size");+        _glfwInputError(GLFW_INVALID_VALUE,+                        "Invalid window size %ix%i",+                        width, height);+         return NULL;     } -    // Set up desired framebuffer config-    fbconfig.redBits        = _glfw.hints.redBits;-    fbconfig.greenBits      = _glfw.hints.greenBits;-    fbconfig.blueBits       = _glfw.hints.blueBits;-    fbconfig.alphaBits      = _glfw.hints.alphaBits;-    fbconfig.depthBits      = _glfw.hints.depthBits;-    fbconfig.stencilBits    = _glfw.hints.stencilBits;-    fbconfig.accumRedBits   = _glfw.hints.accumRedBits;-    fbconfig.accumGreenBits = _glfw.hints.accumGreenBits;-    fbconfig.accumBlueBits  = _glfw.hints.accumBlueBits;-    fbconfig.accumAlphaBits = _glfw.hints.accumAlphaBits;-    fbconfig.auxBuffers     = _glfw.hints.auxBuffers;-    fbconfig.stereo         = _glfw.hints.stereo ? GL_TRUE : GL_FALSE;-    fbconfig.samples        = _glfw.hints.samples;-    fbconfig.sRGB           = _glfw.hints.sRGB;-    fbconfig.doublebuffer   = _glfw.hints.doublebuffer ? GL_TRUE : GL_FALSE;+    fbconfig  = _glfw.hints.framebuffer;+    ctxconfig = _glfw.hints.context;+    wndconfig = _glfw.hints.window; -    // Set up desired window config-    wndconfig.width         = width;-    wndconfig.height        = height;-    wndconfig.title         = title;-    wndconfig.resizable     = _glfw.hints.resizable ? GL_TRUE : GL_FALSE;-    wndconfig.visible       = _glfw.hints.visible ? GL_TRUE : GL_FALSE;-    wndconfig.decorated     = _glfw.hints.decorated ? GL_TRUE : GL_FALSE;-    wndconfig.focused       = _glfw.hints.focused ? GL_TRUE : GL_FALSE;-    wndconfig.autoIconify   = _glfw.hints.autoIconify ? GL_TRUE : GL_FALSE;-    wndconfig.floating      = _glfw.hints.floating ? GL_TRUE : GL_FALSE;-    wndconfig.monitor       = (_GLFWmonitor*) monitor;+    wndconfig.width   = width;+    wndconfig.height  = height;+    wndconfig.title   = title;+    ctxconfig.share   = (_GLFWwindow*) share; -    // Set up desired context config-    ctxconfig.api           = _glfw.hints.api;-    ctxconfig.major         = _glfw.hints.major;-    ctxconfig.minor         = _glfw.hints.minor;-    ctxconfig.forward       = _glfw.hints.forward ? GL_TRUE : GL_FALSE;-    ctxconfig.debug         = _glfw.hints.debug ? GL_TRUE : GL_FALSE;-    ctxconfig.profile       = _glfw.hints.profile;-    ctxconfig.robustness    = _glfw.hints.robustness;-    ctxconfig.release       = _glfw.hints.release;-    ctxconfig.share         = (_GLFWwindow*) share;+    if (ctxconfig.share)+    {+        if (ctxconfig.client == GLFW_NO_API ||+            ctxconfig.share->context.client == GLFW_NO_API)+        {+            _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);+            return NULL;+        }+    } -    // Check the OpenGL bits of the window config     if (!_glfwIsValidContextConfig(&ctxconfig))         return NULL; @@ -180,85 +166,63 @@     window->next = _glfw.windowListHead;     _glfw.windowListHead = window; -    if (wndconfig.monitor)-    {-        wndconfig.resizable = GL_TRUE;-        wndconfig.visible   = GL_TRUE;-        wndconfig.focused   = GL_TRUE;--        // Set up desired video mode-        window->videoMode.width       = width;-        window->videoMode.height      = height;-        window->videoMode.redBits     = _glfw.hints.redBits;-        window->videoMode.greenBits   = _glfw.hints.greenBits;-        window->videoMode.blueBits    = _glfw.hints.blueBits;-        window->videoMode.refreshRate = _glfw.hints.refreshRate;-    }+    window->videoMode.width       = width;+    window->videoMode.height      = height;+    window->videoMode.redBits     = fbconfig.redBits;+    window->videoMode.greenBits   = fbconfig.greenBits;+    window->videoMode.blueBits    = fbconfig.blueBits;+    window->videoMode.refreshRate = _glfw.hints.refreshRate; -    // Transfer window hints that are persistent settings and not-    // just initial states-    window->monitor     = wndconfig.monitor;+    window->monitor     = (_GLFWmonitor*) monitor;     window->resizable   = wndconfig.resizable;     window->decorated   = wndconfig.decorated;     window->autoIconify = wndconfig.autoIconify;     window->floating    = wndconfig.floating;     window->cursorMode  = GLFW_CURSOR_NORMAL; +    window->minwidth    = GLFW_DONT_CARE;+    window->minheight   = GLFW_DONT_CARE;+    window->maxwidth    = GLFW_DONT_CARE;+    window->maxheight   = GLFW_DONT_CARE;+    window->numer       = GLFW_DONT_CARE;+    window->denom       = GLFW_DONT_CARE;+     // Save the currently current context so it can be restored later     previous = _glfwPlatformGetCurrentContext();+    if (ctxconfig.client != GLFW_NO_API)+        glfwMakeContextCurrent(NULL);      // Open the actual window and create its context     if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))     {+        glfwMakeContextCurrent((GLFWwindow*) previous);         glfwDestroyWindow((GLFWwindow*) window);-        _glfwPlatformMakeContextCurrent(previous);         return NULL;     } -    _glfwPlatformMakeContextCurrent(window);--    // Retrieve the actual (as opposed to requested) context attributes-    if (!_glfwRefreshContextAttribs(&ctxconfig))-    {-        glfwDestroyWindow((GLFWwindow*) window);-        _glfwPlatformMakeContextCurrent(previous);-        return NULL;-    }--    // Verify the context against the requested parameters-    if (!_glfwIsValidContext(&ctxconfig))-    {-        glfwDestroyWindow((GLFWwindow*) window);-        _glfwPlatformMakeContextCurrent(previous);-        return NULL;-    }--    // Clearing the front buffer to black to avoid garbage pixels left over-    // from previous uses of our bit of VRAM-    glClear(GL_COLOR_BUFFER_BIT);-    _glfwPlatformSwapBuffers(window);--    // Restore the previously current context (or NULL)-    _glfwPlatformMakeContextCurrent(previous);--    if (wndconfig.monitor)+    if (ctxconfig.client != GLFW_NO_API)     {-        int width, height;-        _glfwPlatformGetWindowSize(window, &width, &height);+        window->context.makeCurrent(window); -        window->cursorPosX = width / 2;-        window->cursorPosY = height / 2;+        // Retrieve the actual (as opposed to requested) context attributes+        if (!_glfwRefreshContextAttribs(&ctxconfig))+        {+            glfwMakeContextCurrent((GLFWwindow*) previous);+            glfwDestroyWindow((GLFWwindow*) window);+            return NULL;+        } -        _glfwPlatformSetCursorPos(window, window->cursorPosX, window->cursorPosY);+        // Restore the previously current context (or NULL)+        glfwMakeContextCurrent((GLFWwindow*) previous);     }-    else++    if (!window->monitor)     {         if (wndconfig.visible)         {+            _glfwPlatformShowWindow(window);             if (wndconfig.focused)-                _glfwPlatformShowWindow(window);-            else-                _glfwPlatformUnhideWindow(window);+                _glfwPlatformFocusWindow(window);         }     } @@ -272,129 +236,139 @@     memset(&_glfw.hints, 0, sizeof(_glfw.hints));      // The default is OpenGL with minimum version 1.0-    _glfw.hints.api   = GLFW_OPENGL_API;-    _glfw.hints.major = 1;-    _glfw.hints.minor = 0;+    _glfw.hints.context.client = GLFW_OPENGL_API;+    _glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;+    _glfw.hints.context.major  = 1;+    _glfw.hints.context.minor  = 0;      // The default is a focused, visible, resizable window with decorations-    _glfw.hints.resizable   = GL_TRUE;-    _glfw.hints.visible     = GL_TRUE;-    _glfw.hints.decorated   = GL_TRUE;-    _glfw.hints.focused     = GL_TRUE;-    _glfw.hints.autoIconify = GL_TRUE;--    // The default is to select the highest available refresh rate-    _glfw.hints.refreshRate = GLFW_DONT_CARE;+    _glfw.hints.window.resizable   = GLFW_TRUE;+    _glfw.hints.window.visible     = GLFW_TRUE;+    _glfw.hints.window.decorated   = GLFW_TRUE;+    _glfw.hints.window.focused     = GLFW_TRUE;+    _glfw.hints.window.autoIconify = GLFW_TRUE;      // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,     // double buffered-    _glfw.hints.redBits      = 8;-    _glfw.hints.greenBits    = 8;-    _glfw.hints.blueBits     = 8;-    _glfw.hints.alphaBits    = 8;-    _glfw.hints.depthBits    = 24;-    _glfw.hints.stencilBits  = 8;-    _glfw.hints.doublebuffer = GL_TRUE;+    _glfw.hints.framebuffer.redBits      = 8;+    _glfw.hints.framebuffer.greenBits    = 8;+    _glfw.hints.framebuffer.blueBits     = 8;+    _glfw.hints.framebuffer.alphaBits    = 8;+    _glfw.hints.framebuffer.depthBits    = 24;+    _glfw.hints.framebuffer.stencilBits  = 8;+    _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;++    // The default is to select the highest available refresh rate+    _glfw.hints.refreshRate = GLFW_DONT_CARE; } -GLFWAPI void glfwWindowHint(int target, int hint)+GLFWAPI void glfwWindowHint(int hint, int value) {     _GLFW_REQUIRE_INIT(); -    switch (target)+    switch (hint)     {         case GLFW_RED_BITS:-            _glfw.hints.redBits = hint;+            _glfw.hints.framebuffer.redBits = value;             break;         case GLFW_GREEN_BITS:-            _glfw.hints.greenBits = hint;+            _glfw.hints.framebuffer.greenBits = value;             break;         case GLFW_BLUE_BITS:-            _glfw.hints.blueBits = hint;+            _glfw.hints.framebuffer.blueBits = value;             break;         case GLFW_ALPHA_BITS:-            _glfw.hints.alphaBits = hint;+            _glfw.hints.framebuffer.alphaBits = value;             break;         case GLFW_DEPTH_BITS:-            _glfw.hints.depthBits = hint;+            _glfw.hints.framebuffer.depthBits = value;             break;         case GLFW_STENCIL_BITS:-            _glfw.hints.stencilBits = hint;+            _glfw.hints.framebuffer.stencilBits = value;             break;         case GLFW_ACCUM_RED_BITS:-            _glfw.hints.accumRedBits = hint;+            _glfw.hints.framebuffer.accumRedBits = value;             break;         case GLFW_ACCUM_GREEN_BITS:-            _glfw.hints.accumGreenBits = hint;+            _glfw.hints.framebuffer.accumGreenBits = value;             break;         case GLFW_ACCUM_BLUE_BITS:-            _glfw.hints.accumBlueBits = hint;+            _glfw.hints.framebuffer.accumBlueBits = value;             break;         case GLFW_ACCUM_ALPHA_BITS:-            _glfw.hints.accumAlphaBits = hint;+            _glfw.hints.framebuffer.accumAlphaBits = value;             break;         case GLFW_AUX_BUFFERS:-            _glfw.hints.auxBuffers = hint;+            _glfw.hints.framebuffer.auxBuffers = value;             break;         case GLFW_STEREO:-            _glfw.hints.stereo = hint;-            break;-        case GLFW_REFRESH_RATE:-            _glfw.hints.refreshRate = hint;+            _glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;             break;         case GLFW_DOUBLEBUFFER:-            _glfw.hints.doublebuffer = hint;+            _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;             break;+        case GLFW_SAMPLES:+            _glfw.hints.framebuffer.samples = value;+            break;+        case GLFW_SRGB_CAPABLE:+            _glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;+            break;         case GLFW_RESIZABLE:-            _glfw.hints.resizable = hint;+            _glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;             break;         case GLFW_DECORATED:-            _glfw.hints.decorated = hint;+            _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;             break;         case GLFW_FOCUSED:-            _glfw.hints.focused = hint;+            _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;             break;         case GLFW_AUTO_ICONIFY:-            _glfw.hints.autoIconify = hint;+            _glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;             break;         case GLFW_FLOATING:-            _glfw.hints.floating = hint;-            break;-        case GLFW_VISIBLE:-            _glfw.hints.visible = hint;+            _glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;             break;-        case GLFW_SAMPLES:-            _glfw.hints.samples = hint;+        case GLFW_MAXIMIZED:+            _glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;             break;-        case GLFW_SRGB_CAPABLE:-            _glfw.hints.sRGB = hint;+        case GLFW_VISIBLE:+            _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;             break;         case GLFW_CLIENT_API:-            _glfw.hints.api = hint;+            _glfw.hints.context.client = value;             break;+        case GLFW_CONTEXT_CREATION_API:+            _glfw.hints.context.source = value;+            break;         case GLFW_CONTEXT_VERSION_MAJOR:-            _glfw.hints.major = hint;+            _glfw.hints.context.major = value;             break;         case GLFW_CONTEXT_VERSION_MINOR:-            _glfw.hints.minor = hint;+            _glfw.hints.context.minor = value;             break;         case GLFW_CONTEXT_ROBUSTNESS:-            _glfw.hints.robustness = hint;+            _glfw.hints.context.robustness = value;             break;         case GLFW_OPENGL_FORWARD_COMPAT:-            _glfw.hints.forward = hint;+            _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;             break;         case GLFW_OPENGL_DEBUG_CONTEXT:-            _glfw.hints.debug = hint;+            _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;             break;+        case GLFW_CONTEXT_NO_ERROR:+            _glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;+            break;         case GLFW_OPENGL_PROFILE:-            _glfw.hints.profile = hint;+            _glfw.hints.context.profile = value;             break;         case GLFW_CONTEXT_RELEASE_BEHAVIOR:-            _glfw.hints.release = hint;+            _glfw.hints.context.release = value;             break;+        case GLFW_REFRESH_RATE:+            _glfw.hints.refreshRate = value;+            break;         default:-            _glfwInputError(GLFW_INVALID_ENUM, NULL);+            _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint %i", hint);             break;     } }@@ -415,11 +389,7 @@     // The window's context must not be current on another thread when the     // window is destroyed     if (window == _glfwPlatformGetCurrentContext())-        _glfwPlatformMakeContextCurrent(NULL);--    // Clear the focused window pointer if this is the focused window-    if (_glfw.focusedWindow == window)-        _glfw.focusedWindow = NULL;+        glfwMakeContextCurrent(NULL);      _glfwPlatformDestroyWindow(window); @@ -439,6 +409,8 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(0);     return window->closed; }@@ -446,6 +418,8 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT();     window->closed = value; }@@ -453,13 +427,30 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);++    assert(title != NULL);+     _GLFW_REQUIRE_INIT();     _glfwPlatformSetWindowTitle(window, title); } +GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,+                               int count, const GLFWimage* images)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+    assert(count >= 0);+    assert(count == 0 || images != NULL);++    _GLFW_REQUIRE_INIT();+    _glfwPlatformSetWindowIcon(window, count, images);+}+ GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      if (xpos)         *xpos = 0;@@ -473,15 +464,12 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT();      if (window->monitor)-    {-        _glfwInputError(GLFW_INVALID_VALUE,-                        "Full screen windows cannot be positioned");         return;-    }      _glfwPlatformSetWindowPos(window, xpos, ypos); }@@ -489,6 +477,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      if (width)         *width = 0;@@ -502,21 +491,92 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT(); -    if (window->monitor)+    window->videoMode.width  = width;+    window->videoMode.height = height;++    _glfwPlatformSetWindowSize(window, width, height);+}++GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,+                                     int minwidth, int minheight,+                                     int maxwidth, int maxheight)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);++    _GLFW_REQUIRE_INIT();++    if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE)     {-        window->videoMode.width  = width;-        window->videoMode.height = height;+        if (minwidth < 0 || minheight < 0)+        {+            _glfwInputError(GLFW_INVALID_VALUE,+                            "Invalid window minimum size %ix%i",+                            minwidth, minheight);+            return;+        }     } -    _glfwPlatformSetWindowSize(window, width, height);+    if (maxwidth != GLFW_DONT_CARE && maxheight != GLFW_DONT_CARE)+    {+        if (maxwidth < 0 || maxheight < 0 ||+            maxwidth < minwidth || maxheight < minheight)+        {+            _glfwInputError(GLFW_INVALID_VALUE,+                            "Invalid window maximum size %ix%i",+                            maxwidth, maxheight);+            return;+        }+    }++    window->minwidth  = minwidth;+    window->minheight = minheight;+    window->maxwidth  = maxwidth;+    window->maxheight = maxheight;++    if (window->monitor || !window->resizable)+        return;++    _glfwPlatformSetWindowSizeLimits(window,+                                     minwidth, minheight,+                                     maxwidth, maxheight); } +GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);++    _GLFW_REQUIRE_INIT();++    if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)+    {+        if (numer <= 0 || denom <= 0)+        {+            _glfwInputError(GLFW_INVALID_VALUE,+                            "Invalid window aspect ratio %i:%i",+                            numer, denom);+            return;+        }+    }++    window->numer = numer;+    window->denom = denom;++    if (window->monitor || !window->resizable)+        return;++    _glfwPlatformSetWindowAspectRatio(window, numer, denom);+}+ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      if (width)         *width = 0;@@ -532,6 +592,7 @@                                     int* right, int* bottom) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      if (left)         *left = 0;@@ -549,6 +610,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT();     _glfwPlatformIconifyWindow(window); }@@ -556,13 +619,25 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT();     _glfwPlatformRestoreWindow(window); } +GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);++    _GLFW_REQUIRE_INIT();+    _glfwPlatformMaximizeWindow(window);+}+ GLFWAPI void glfwShowWindow(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT(); @@ -570,11 +645,13 @@         return;      _glfwPlatformShowWindow(window);+    _glfwPlatformFocusWindow(window); }  GLFWAPI void glfwHideWindow(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT(); @@ -584,9 +661,20 @@     _glfwPlatformHideWindow(window); } +GLFWAPI void glfwFocusWindow(GLFWwindow* handle)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);++    _GLFW_REQUIRE_INIT();++    _glfwPlatformFocusWindow(window);+}+ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);      _GLFW_REQUIRE_INIT_OR_RETURN(0); @@ -598,6 +686,8 @@             return _glfwPlatformWindowIconified(window);         case GLFW_VISIBLE:             return _glfwPlatformWindowVisible(window);+        case GLFW_MAXIMIZED:+            return _glfwPlatformWindowMaximized(window);         case GLFW_RESIZABLE:             return window->resizable;         case GLFW_DECORATED:@@ -605,7 +695,9 @@         case GLFW_FLOATING:             return window->floating;         case GLFW_CLIENT_API:-            return window->context.api;+            return window->context.client;+        case GLFW_CONTEXT_CREATION_API:+            return window->context.source;         case GLFW_CONTEXT_VERSION_MAJOR:             return window->context.major;         case GLFW_CONTEXT_VERSION_MINOR:@@ -622,22 +714,65 @@             return window->context.profile;         case GLFW_CONTEXT_RELEASE_BEHAVIOR:             return window->context.release;+        case GLFW_CONTEXT_NO_ERROR:+            return window->context.noerror;     } -    _glfwInputError(GLFW_INVALID_ENUM, NULL);+    _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute %i", attrib);     return 0; }  GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     return (GLFWmonitor*) window->monitor; } +GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,+                                  GLFWmonitor* mh,+                                  int xpos, int ypos,+                                  int width, int height,+                                  int refreshRate)+{+    _GLFWwindow* window = (_GLFWwindow*) wh;+    _GLFWmonitor* monitor = (_GLFWmonitor*) mh;+    assert(window != NULL);++    _GLFW_REQUIRE_INIT();++    if (width <= 0 || height <= 0)+    {+        _glfwInputError(GLFW_INVALID_VALUE,+                        "Invalid window size %ix%i",+                        width, height);+        return;+    }++    if (refreshRate < 0 && refreshRate != GLFW_DONT_CARE)+    {+        _glfwInputError(GLFW_INVALID_VALUE,+                        "Invalid refresh rate %i",+                        refreshRate);+        return;+    }++    window->videoMode.width       = width;+    window->videoMode.height      = height;+    window->videoMode.refreshRate = refreshRate;++    _glfwPlatformSetWindowMonitor(window, monitor,+                                  xpos, ypos, width, height,+                                  refreshRate);+}+ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT();     window->userPointer = pointer; }@@ -645,6 +780,8 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     return window->userPointer; }@@ -653,6 +790,8 @@                                                   GLFWwindowposfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun);     return cbfun;@@ -662,6 +801,8 @@                                                     GLFWwindowsizefun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun);     return cbfun;@@ -671,6 +812,8 @@                                                       GLFWwindowclosefun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun);     return cbfun;@@ -680,6 +823,8 @@                                                           GLFWwindowrefreshfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun);     return cbfun;@@ -689,6 +834,8 @@                                                       GLFWwindowfocusfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun);     return cbfun;@@ -698,6 +845,8 @@                                                           GLFWwindowiconifyfun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun);     return cbfun;@@ -707,6 +856,8 @@                                                               GLFWframebuffersizefun cbfun) {     _GLFWwindow* window = (_GLFWwindow*) handle;+    assert(window != NULL);+     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);     _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun);     return cbfun;@@ -726,6 +877,19 @@         return;      _glfwPlatformWaitEvents();+}++GLFWAPI void glfwWaitEventsTimeout(double timeout)+{+    _GLFW_REQUIRE_INIT();++    if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)+    {+        _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout);+        return;+    }++    _glfwPlatformWaitEventsTimeout(timeout); }  GLFWAPI void glfwPostEmptyEvent(void)
− glfw/src/winmm_joystick.c
@@ -1,177 +0,0 @@-//========================================================================-// GLFW 3.1 WinMM - www.glfw.org-//-------------------------------------------------------------------------// Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-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 <stdlib.h>---//////////////////////////////////////////////////////////////////////////-//////                       GLFW internal API                      //////-//////////////////////////////////////////////////////////////////////////--// Convert axis value to the [-1,1] range-//-static float normalizeAxis(DWORD pos, DWORD min, DWORD max)-{-    float fpos = (float) pos;-    float fmin = (float) min;-    float fmax = (float) max;--    return (2.f * (fpos - fmin) / (fmax - fmin)) - 1.f;-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW internal API                      //////-//////////////////////////////////////////////////////////////////////////--// Initialize joystick interface-//-void _glfwInitJoysticks(void)-{-}--// Close all opened joystick handles-//-void _glfwTerminateJoysticks(void)-{-    int i;--    for (i = 0;  i < GLFW_JOYSTICK_LAST;  i++)-        free(_glfw.winmm_js[i].name);-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////--int _glfwPlatformJoystickPresent(int joy)-{-    JOYINFO ji;--    if (_glfw_joyGetPos(joy, &ji) != JOYERR_NOERROR)-        return GL_FALSE;--    return GL_TRUE;-}--const float* _glfwPlatformGetJoystickAxes(int joy, int* count)-{-    JOYCAPS jc;-    JOYINFOEX ji;-    float* axes = _glfw.winmm_js[joy].axes;--    if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)-        return NULL;--    ji.dwSize = sizeof(JOYINFOEX);-    ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ |-                 JOY_RETURNR | JOY_RETURNU | JOY_RETURNV;-    if (_glfw_joyGetPosEx(joy, &ji) != JOYERR_NOERROR)-        return NULL;--    axes[(*count)++] = normalizeAxis(ji.dwXpos, jc.wXmin, jc.wXmax);-    axes[(*count)++] = normalizeAxis(ji.dwYpos, jc.wYmin, jc.wYmax);--    if (jc.wCaps & JOYCAPS_HASZ)-        axes[(*count)++] = normalizeAxis(ji.dwZpos, jc.wZmin, jc.wZmax);--    if (jc.wCaps & JOYCAPS_HASR)-        axes[(*count)++] = normalizeAxis(ji.dwRpos, jc.wRmin, jc.wRmax);--    if (jc.wCaps & JOYCAPS_HASU)-        axes[(*count)++] = normalizeAxis(ji.dwUpos, jc.wUmin, jc.wUmax);--    if (jc.wCaps & JOYCAPS_HASV)-        axes[(*count)++] = normalizeAxis(ji.dwVpos, jc.wVmin, jc.wVmax);--    return axes;-}--const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)-{-    JOYCAPS jc;-    JOYINFOEX ji;-    unsigned char* buttons = _glfw.winmm_js[joy].buttons;--    if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)-        return NULL;--    ji.dwSize = sizeof(JOYINFOEX);-    ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV;-    if (_glfw_joyGetPosEx(joy, &ji) != JOYERR_NOERROR)-        return NULL;--    while (*count < (int) jc.wNumButtons)-    {-        buttons[*count] = (unsigned char)-            (ji.dwButtons & (1UL << *count) ? GLFW_PRESS : GLFW_RELEASE);-        (*count)++;-    }--    // Virtual buttons - Inject data from hats-    // Each hat is exposed as 4 buttons which exposes 8 directions with-    // concurrent button presses-    // NOTE: this API exposes only one hat--    if ((jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR))-    {-        int i, value = ji.dwPOV / 100 / 45;--        // Bit fields of button presses for each direction, including nil-        const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };--        if (value < 0 || value > 8)-            value = 8;--        for (i = 0;  i < 4;  i++)-        {-            if (directions[value] & (1 << i))-                buttons[(*count)++] = GLFW_PRESS;-            else-                buttons[(*count)++] = GLFW_RELEASE;-        }-    }--    return buttons;-}--const char* _glfwPlatformGetJoystickName(int joy)-{-    JOYCAPS jc;--    if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)-        return NULL;--    free(_glfw.winmm_js[joy].name);-    _glfw.winmm_js[joy].name = _glfwCreateUTF8FromWideString(jc.szPname);--    return _glfw.winmm_js[joy].name;-}-
− glfw/src/winmm_joystick.h
@@ -1,47 +0,0 @@-//========================================================================-// GLFW 3.1 WinMM - www.glfw.org-//-------------------------------------------------------------------------// Copyright (c) 2006-2014 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.-//-//========================================================================--#ifndef _winmm_joystick_h_-#define _winmm_joystick_h_--#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \-    _GLFWjoystickWinMM winmm_js[GLFW_JOYSTICK_LAST + 1]---// WinMM-specific per-joystick data-//-typedef struct _GLFWjoystickWinMM-{-    float           axes[6];-    unsigned char   buttons[36]; // 32 buttons plus one hat-    char*           name;-} _GLFWjoystickWinMM;---void _glfwInitJoysticks(void);-void _glfwTerminateJoysticks(void);--#endif // _winmm_joystick_h_
glfw/src/wl_init.c view
@@ -1,5 +1,5 @@ //========================================================================-// GLFW 3.1 Wayland - www.glfw.org+// GLFW 3.2 Wayland - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> //@@ -35,8 +35,12 @@ #include <wayland-client.h> #include <wayland-cursor.h> -#include "xkb_unicode.h" +static inline int min(int n1, int n2)+{+    return n1 < n2 ? n1 : n2;+}+ static void pointerHandleEnter(void* data,                                struct wl_pointer* pointer,                                uint32_t serial,@@ -50,7 +54,7 @@     _glfw.wl.pointerFocus = window;      _glfwPlatformSetCursor(window, window->wl.currentCursor);-    _glfwInputCursorEnter(window, GL_TRUE);+    _glfwInputCursorEnter(window, GLFW_TRUE); }  static void pointerHandleLeave(void* data,@@ -65,7 +69,7 @@      _glfw.wl.pointerSerial = serial;     _glfw.wl.pointerFocus = NULL;-    _glfwInputCursorEnter(window, GL_FALSE);+    _glfwInputCursorEnter(window, GLFW_FALSE); }  static void pointerHandleMotion(void* data,@@ -80,16 +84,16 @@         return;      if (window->cursorMode == GLFW_CURSOR_DISABLED)-    {-        /* TODO */-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Wayland: GLFW_CURSOR_DISABLED not supported");         return;+    else+    {+        window->wl.cursorPosX = wl_fixed_to_double(sx);+        window->wl.cursorPosY = wl_fixed_to_double(sy);     } -    _glfwInputCursorMotion(window,-                           wl_fixed_to_double(sx),-                           wl_fixed_to_double(sy));+    _glfwInputCursorPos(window,+                        wl_fixed_to_double(sx),+                        wl_fixed_to_double(sy)); }  static void pointerHandleButton(void* data,@@ -229,7 +233,7 @@     _GLFWwindow* window = wl_surface_get_user_data(surface);      _glfw.wl.keyboardFocus = window;-    _glfwInputWindowFocus(window, GL_TRUE);+    _glfwInputWindowFocus(window, GLFW_TRUE); }  static void keyboardHandleLeave(void* data,@@ -243,131 +247,15 @@         return;      _glfw.wl.keyboardFocus = NULL;-    _glfwInputWindowFocus(window, GL_FALSE);+    _glfwInputWindowFocus(window, GLFW_FALSE); }  static int toGLFWKeyCode(uint32_t key) {-    switch (key)-    {-        case KEY_GRAVE:         return GLFW_KEY_GRAVE_ACCENT;-        case KEY_1:             return GLFW_KEY_1;-        case KEY_2:             return GLFW_KEY_2;-        case KEY_3:             return GLFW_KEY_3;-        case KEY_4:             return GLFW_KEY_4;-        case KEY_5:             return GLFW_KEY_5;-        case KEY_6:             return GLFW_KEY_6;-        case KEY_7:             return GLFW_KEY_7;-        case KEY_8:             return GLFW_KEY_8;-        case KEY_9:             return GLFW_KEY_9;-        case KEY_0:             return GLFW_KEY_0;-        case KEY_MINUS:         return GLFW_KEY_MINUS;-        case KEY_EQUAL:         return GLFW_KEY_EQUAL;-        case KEY_Q:             return GLFW_KEY_Q;-        case KEY_W:             return GLFW_KEY_W;-        case KEY_E:             return GLFW_KEY_E;-        case KEY_R:             return GLFW_KEY_R;-        case KEY_T:             return GLFW_KEY_T;-        case KEY_Y:             return GLFW_KEY_Y;-        case KEY_U:             return GLFW_KEY_U;-        case KEY_I:             return GLFW_KEY_I;-        case KEY_O:             return GLFW_KEY_O;-        case KEY_P:             return GLFW_KEY_P;-        case KEY_LEFTBRACE:     return GLFW_KEY_LEFT_BRACKET;-        case KEY_RIGHTBRACE:    return GLFW_KEY_RIGHT_BRACKET;-        case KEY_A:             return GLFW_KEY_A;-        case KEY_S:             return GLFW_KEY_S;-        case KEY_D:             return GLFW_KEY_D;-        case KEY_F:             return GLFW_KEY_F;-        case KEY_G:             return GLFW_KEY_G;-        case KEY_H:             return GLFW_KEY_H;-        case KEY_J:             return GLFW_KEY_J;-        case KEY_K:             return GLFW_KEY_K;-        case KEY_L:             return GLFW_KEY_L;-        case KEY_SEMICOLON:     return GLFW_KEY_SEMICOLON;-        case KEY_APOSTROPHE:    return GLFW_KEY_APOSTROPHE;-        case KEY_Z:             return GLFW_KEY_Z;-        case KEY_X:             return GLFW_KEY_X;-        case KEY_C:             return GLFW_KEY_C;-        case KEY_V:             return GLFW_KEY_V;-        case KEY_B:             return GLFW_KEY_B;-        case KEY_N:             return GLFW_KEY_N;-        case KEY_M:             return GLFW_KEY_M;-        case KEY_COMMA:         return GLFW_KEY_COMMA;-        case KEY_DOT:           return GLFW_KEY_PERIOD;-        case KEY_SLASH:         return GLFW_KEY_SLASH;-        case KEY_BACKSLASH:     return GLFW_KEY_BACKSLASH;-        case KEY_ESC:           return GLFW_KEY_ESCAPE;-        case KEY_TAB:           return GLFW_KEY_TAB;-        case KEY_LEFTSHIFT:     return GLFW_KEY_LEFT_SHIFT;-        case KEY_RIGHTSHIFT:    return GLFW_KEY_RIGHT_SHIFT;-        case KEY_LEFTCTRL:      return GLFW_KEY_LEFT_CONTROL;-        case KEY_RIGHTCTRL:     return GLFW_KEY_RIGHT_CONTROL;-        case KEY_LEFTALT:       return GLFW_KEY_LEFT_ALT;-        case KEY_RIGHTALT:      return GLFW_KEY_RIGHT_ALT;-        case KEY_LEFTMETA:      return GLFW_KEY_LEFT_SUPER;-        case KEY_RIGHTMETA:     return GLFW_KEY_RIGHT_SUPER;-        case KEY_MENU:          return GLFW_KEY_MENU;-        case KEY_NUMLOCK:       return GLFW_KEY_NUM_LOCK;-        case KEY_CAPSLOCK:      return GLFW_KEY_CAPS_LOCK;-        case KEY_PRINT:         return GLFW_KEY_PRINT_SCREEN;-        case KEY_SCROLLLOCK:    return GLFW_KEY_SCROLL_LOCK;-        case KEY_PAUSE:         return GLFW_KEY_PAUSE;-        case KEY_DELETE:        return GLFW_KEY_DELETE;-        case KEY_BACKSPACE:     return GLFW_KEY_BACKSPACE;-        case KEY_ENTER:         return GLFW_KEY_ENTER;-        case KEY_HOME:          return GLFW_KEY_HOME;-        case KEY_END:           return GLFW_KEY_END;-        case KEY_PAGEUP:        return GLFW_KEY_PAGE_UP;-        case KEY_PAGEDOWN:      return GLFW_KEY_PAGE_DOWN;-        case KEY_INSERT:        return GLFW_KEY_INSERT;-        case KEY_LEFT:          return GLFW_KEY_LEFT;-        case KEY_RIGHT:         return GLFW_KEY_RIGHT;-        case KEY_DOWN:          return GLFW_KEY_DOWN;-        case KEY_UP:            return GLFW_KEY_UP;-        case KEY_F1:            return GLFW_KEY_F1;-        case KEY_F2:            return GLFW_KEY_F2;-        case KEY_F3:            return GLFW_KEY_F3;-        case KEY_F4:            return GLFW_KEY_F4;-        case KEY_F5:            return GLFW_KEY_F5;-        case KEY_F6:            return GLFW_KEY_F6;-        case KEY_F7:            return GLFW_KEY_F7;-        case KEY_F8:            return GLFW_KEY_F8;-        case KEY_F9:            return GLFW_KEY_F9;-        case KEY_F10:           return GLFW_KEY_F10;-        case KEY_F11:           return GLFW_KEY_F11;-        case KEY_F12:           return GLFW_KEY_F12;-        case KEY_F13:           return GLFW_KEY_F13;-        case KEY_F14:           return GLFW_KEY_F14;-        case KEY_F15:           return GLFW_KEY_F15;-        case KEY_F16:           return GLFW_KEY_F16;-        case KEY_F17:           return GLFW_KEY_F17;-        case KEY_F18:           return GLFW_KEY_F18;-        case KEY_F19:           return GLFW_KEY_F19;-        case KEY_F20:           return GLFW_KEY_F20;-        case KEY_F21:           return GLFW_KEY_F21;-        case KEY_F22:           return GLFW_KEY_F22;-        case KEY_F23:           return GLFW_KEY_F23;-        case KEY_F24:           return GLFW_KEY_F24;-        case KEY_KPSLASH:       return GLFW_KEY_KP_DIVIDE;-        case KEY_KPDOT:         return GLFW_KEY_KP_MULTIPLY;-        case KEY_KPMINUS:       return GLFW_KEY_KP_SUBTRACT;-        case KEY_KPPLUS:        return GLFW_KEY_KP_ADD;-        case KEY_KP0:           return GLFW_KEY_KP_0;-        case KEY_KP1:           return GLFW_KEY_KP_1;-        case KEY_KP2:           return GLFW_KEY_KP_2;-        case KEY_KP3:           return GLFW_KEY_KP_3;-        case KEY_KP4:           return GLFW_KEY_KP_4;-        case KEY_KP5:           return GLFW_KEY_KP_5;-        case KEY_KP6:           return GLFW_KEY_KP_6;-        case KEY_KP7:           return GLFW_KEY_KP_7;-        case KEY_KP8:           return GLFW_KEY_KP_8;-        case KEY_KP9:           return GLFW_KEY_KP_9;-        case KEY_KPCOMMA:       return GLFW_KEY_KP_DECIMAL;-        case KEY_KPEQUAL:       return GLFW_KEY_KP_EQUAL;-        case KEY_KPENTER:       return GLFW_KEY_KP_ENTER;-        default:                return GLFW_KEY_UNKNOWN;-    }+    if (key < sizeof(_glfw.wl.publicKeys) / sizeof(_glfw.wl.publicKeys[0]))+        return _glfw.wl.publicKeys[key];++    return GLFW_KEY_UNKNOWN; }  static void keyboardHandleKey(void* data,@@ -492,8 +380,10 @@ {     if (strcmp(interface, "wl_compositor") == 0)     {+        _glfw.wl.wl_compositor_version = min(3, version);         _glfw.wl.compositor =-            wl_registry_bind(registry, name, &wl_compositor_interface, 1);+            wl_registry_bind(registry, name, &wl_compositor_interface,+                             _glfw.wl.wl_compositor_version);     }     else if (strcmp(interface, "wl_shm") == 0)     {@@ -507,7 +397,7 @@     }     else if (strcmp(interface, "wl_output") == 0)     {-        _glfwAddOutput(name, version);+        _glfwAddOutputWayland(name, version);     }     else if (strcmp(interface, "wl_seat") == 0)     {@@ -518,6 +408,20 @@             wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL);         }     }+    else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0)+    {+        _glfw.wl.relativePointerManager =+            wl_registry_bind(registry, name,+                             &zwp_relative_pointer_manager_v1_interface,+                             1);+    }+    else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0)+    {+        _glfw.wl.pointerConstraints =+            wl_registry_bind(registry, name,+                             &zwp_pointer_constraints_v1_interface,+                             1);+    } }  static void registryHandleGlobalRemove(void *data,@@ -532,7 +436,131 @@     registryHandleGlobalRemove }; +// Create key code translation tables+//+static void createKeyTables(void)+{+    memset(_glfw.wl.publicKeys, -1, sizeof(_glfw.wl.publicKeys)); +    _glfw.wl.publicKeys[KEY_GRAVE]      = GLFW_KEY_GRAVE_ACCENT;+    _glfw.wl.publicKeys[KEY_1]          = GLFW_KEY_1;+    _glfw.wl.publicKeys[KEY_2]          = GLFW_KEY_2;+    _glfw.wl.publicKeys[KEY_3]          = GLFW_KEY_3;+    _glfw.wl.publicKeys[KEY_4]          = GLFW_KEY_4;+    _glfw.wl.publicKeys[KEY_5]          = GLFW_KEY_5;+    _glfw.wl.publicKeys[KEY_6]          = GLFW_KEY_6;+    _glfw.wl.publicKeys[KEY_7]          = GLFW_KEY_7;+    _glfw.wl.publicKeys[KEY_8]          = GLFW_KEY_8;+    _glfw.wl.publicKeys[KEY_9]          = GLFW_KEY_9;+    _glfw.wl.publicKeys[KEY_0]          = GLFW_KEY_0;+    _glfw.wl.publicKeys[KEY_MINUS]      = GLFW_KEY_MINUS;+    _glfw.wl.publicKeys[KEY_EQUAL]      = GLFW_KEY_EQUAL;+    _glfw.wl.publicKeys[KEY_Q]          = GLFW_KEY_Q;+    _glfw.wl.publicKeys[KEY_W]          = GLFW_KEY_W;+    _glfw.wl.publicKeys[KEY_E]          = GLFW_KEY_E;+    _glfw.wl.publicKeys[KEY_R]          = GLFW_KEY_R;+    _glfw.wl.publicKeys[KEY_T]          = GLFW_KEY_T;+    _glfw.wl.publicKeys[KEY_Y]          = GLFW_KEY_Y;+    _glfw.wl.publicKeys[KEY_U]          = GLFW_KEY_U;+    _glfw.wl.publicKeys[KEY_I]          = GLFW_KEY_I;+    _glfw.wl.publicKeys[KEY_O]          = GLFW_KEY_O;+    _glfw.wl.publicKeys[KEY_P]          = GLFW_KEY_P;+    _glfw.wl.publicKeys[KEY_LEFTBRACE]  = GLFW_KEY_LEFT_BRACKET;+    _glfw.wl.publicKeys[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;+    _glfw.wl.publicKeys[KEY_A]          = GLFW_KEY_A;+    _glfw.wl.publicKeys[KEY_S]          = GLFW_KEY_S;+    _glfw.wl.publicKeys[KEY_D]          = GLFW_KEY_D;+    _glfw.wl.publicKeys[KEY_F]          = GLFW_KEY_F;+    _glfw.wl.publicKeys[KEY_G]          = GLFW_KEY_G;+    _glfw.wl.publicKeys[KEY_H]          = GLFW_KEY_H;+    _glfw.wl.publicKeys[KEY_J]          = GLFW_KEY_J;+    _glfw.wl.publicKeys[KEY_K]          = GLFW_KEY_K;+    _glfw.wl.publicKeys[KEY_L]          = GLFW_KEY_L;+    _glfw.wl.publicKeys[KEY_SEMICOLON]  = GLFW_KEY_SEMICOLON;+    _glfw.wl.publicKeys[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;+    _glfw.wl.publicKeys[KEY_Z]          = GLFW_KEY_Z;+    _glfw.wl.publicKeys[KEY_X]          = GLFW_KEY_X;+    _glfw.wl.publicKeys[KEY_C]          = GLFW_KEY_C;+    _glfw.wl.publicKeys[KEY_V]          = GLFW_KEY_V;+    _glfw.wl.publicKeys[KEY_B]          = GLFW_KEY_B;+    _glfw.wl.publicKeys[KEY_N]          = GLFW_KEY_N;+    _glfw.wl.publicKeys[KEY_M]          = GLFW_KEY_M;+    _glfw.wl.publicKeys[KEY_COMMA]      = GLFW_KEY_COMMA;+    _glfw.wl.publicKeys[KEY_DOT]        = GLFW_KEY_PERIOD;+    _glfw.wl.publicKeys[KEY_SLASH]      = GLFW_KEY_SLASH;+    _glfw.wl.publicKeys[KEY_BACKSLASH]  = GLFW_KEY_BACKSLASH;+    _glfw.wl.publicKeys[KEY_ESC]        = GLFW_KEY_ESCAPE;+    _glfw.wl.publicKeys[KEY_TAB]        = GLFW_KEY_TAB;+    _glfw.wl.publicKeys[KEY_LEFTSHIFT]  = GLFW_KEY_LEFT_SHIFT;+    _glfw.wl.publicKeys[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;+    _glfw.wl.publicKeys[KEY_LEFTCTRL]   = GLFW_KEY_LEFT_CONTROL;+    _glfw.wl.publicKeys[KEY_RIGHTCTRL]  = GLFW_KEY_RIGHT_CONTROL;+    _glfw.wl.publicKeys[KEY_LEFTALT]    = GLFW_KEY_LEFT_ALT;+    _glfw.wl.publicKeys[KEY_RIGHTALT]   = GLFW_KEY_RIGHT_ALT;+    _glfw.wl.publicKeys[KEY_LEFTMETA]   = GLFW_KEY_LEFT_SUPER;+    _glfw.wl.publicKeys[KEY_RIGHTMETA]  = GLFW_KEY_RIGHT_SUPER;+    _glfw.wl.publicKeys[KEY_MENU]       = GLFW_KEY_MENU;+    _glfw.wl.publicKeys[KEY_NUMLOCK]    = GLFW_KEY_NUM_LOCK;+    _glfw.wl.publicKeys[KEY_CAPSLOCK]   = GLFW_KEY_CAPS_LOCK;+    _glfw.wl.publicKeys[KEY_PRINT]      = GLFW_KEY_PRINT_SCREEN;+    _glfw.wl.publicKeys[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;+    _glfw.wl.publicKeys[KEY_PAUSE]      = GLFW_KEY_PAUSE;+    _glfw.wl.publicKeys[KEY_DELETE]     = GLFW_KEY_DELETE;+    _glfw.wl.publicKeys[KEY_BACKSPACE]  = GLFW_KEY_BACKSPACE;+    _glfw.wl.publicKeys[KEY_ENTER]      = GLFW_KEY_ENTER;+    _glfw.wl.publicKeys[KEY_HOME]       = GLFW_KEY_HOME;+    _glfw.wl.publicKeys[KEY_END]        = GLFW_KEY_END;+    _glfw.wl.publicKeys[KEY_PAGEUP]     = GLFW_KEY_PAGE_UP;+    _glfw.wl.publicKeys[KEY_PAGEDOWN]   = GLFW_KEY_PAGE_DOWN;+    _glfw.wl.publicKeys[KEY_INSERT]     = GLFW_KEY_INSERT;+    _glfw.wl.publicKeys[KEY_LEFT]       = GLFW_KEY_LEFT;+    _glfw.wl.publicKeys[KEY_RIGHT]      = GLFW_KEY_RIGHT;+    _glfw.wl.publicKeys[KEY_DOWN]       = GLFW_KEY_DOWN;+    _glfw.wl.publicKeys[KEY_UP]         = GLFW_KEY_UP;+    _glfw.wl.publicKeys[KEY_F1]         = GLFW_KEY_F1;+    _glfw.wl.publicKeys[KEY_F2]         = GLFW_KEY_F2;+    _glfw.wl.publicKeys[KEY_F3]         = GLFW_KEY_F3;+    _glfw.wl.publicKeys[KEY_F4]         = GLFW_KEY_F4;+    _glfw.wl.publicKeys[KEY_F5]         = GLFW_KEY_F5;+    _glfw.wl.publicKeys[KEY_F6]         = GLFW_KEY_F6;+    _glfw.wl.publicKeys[KEY_F7]         = GLFW_KEY_F7;+    _glfw.wl.publicKeys[KEY_F8]         = GLFW_KEY_F8;+    _glfw.wl.publicKeys[KEY_F9]         = GLFW_KEY_F9;+    _glfw.wl.publicKeys[KEY_F10]        = GLFW_KEY_F10;+    _glfw.wl.publicKeys[KEY_F11]        = GLFW_KEY_F11;+    _glfw.wl.publicKeys[KEY_F12]        = GLFW_KEY_F12;+    _glfw.wl.publicKeys[KEY_F13]        = GLFW_KEY_F13;+    _glfw.wl.publicKeys[KEY_F14]        = GLFW_KEY_F14;+    _glfw.wl.publicKeys[KEY_F15]        = GLFW_KEY_F15;+    _glfw.wl.publicKeys[KEY_F16]        = GLFW_KEY_F16;+    _glfw.wl.publicKeys[KEY_F17]        = GLFW_KEY_F17;+    _glfw.wl.publicKeys[KEY_F18]        = GLFW_KEY_F18;+    _glfw.wl.publicKeys[KEY_F19]        = GLFW_KEY_F19;+    _glfw.wl.publicKeys[KEY_F20]        = GLFW_KEY_F20;+    _glfw.wl.publicKeys[KEY_F21]        = GLFW_KEY_F21;+    _glfw.wl.publicKeys[KEY_F22]        = GLFW_KEY_F22;+    _glfw.wl.publicKeys[KEY_F23]        = GLFW_KEY_F23;+    _glfw.wl.publicKeys[KEY_F24]        = GLFW_KEY_F24;+    _glfw.wl.publicKeys[KEY_KPSLASH]    = GLFW_KEY_KP_DIVIDE;+    _glfw.wl.publicKeys[KEY_KPDOT]      = GLFW_KEY_KP_MULTIPLY;+    _glfw.wl.publicKeys[KEY_KPMINUS]    = GLFW_KEY_KP_SUBTRACT;+    _glfw.wl.publicKeys[KEY_KPPLUS]     = GLFW_KEY_KP_ADD;+    _glfw.wl.publicKeys[KEY_KP0]        = GLFW_KEY_KP_0;+    _glfw.wl.publicKeys[KEY_KP1]        = GLFW_KEY_KP_1;+    _glfw.wl.publicKeys[KEY_KP2]        = GLFW_KEY_KP_2;+    _glfw.wl.publicKeys[KEY_KP3]        = GLFW_KEY_KP_3;+    _glfw.wl.publicKeys[KEY_KP4]        = GLFW_KEY_KP_4;+    _glfw.wl.publicKeys[KEY_KP5]        = GLFW_KEY_KP_5;+    _glfw.wl.publicKeys[KEY_KP6]        = GLFW_KEY_KP_6;+    _glfw.wl.publicKeys[KEY_KP7]        = GLFW_KEY_KP_7;+    _glfw.wl.publicKeys[KEY_KP8]        = GLFW_KEY_KP_8;+    _glfw.wl.publicKeys[KEY_KP9]        = GLFW_KEY_KP_9;+    _glfw.wl.publicKeys[KEY_KPCOMMA]    = GLFW_KEY_KP_DECIMAL;+    _glfw.wl.publicKeys[KEY_KPEQUAL]    = GLFW_KEY_KP_EQUAL;+    _glfw.wl.publicKeys[KEY_KPENTER]    = GLFW_KEY_KP_ENTER;+}++ ////////////////////////////////////////////////////////////////////////// //////                       GLFW platform API                      ////// //////////////////////////////////////////////////////////////////////////@@ -544,7 +572,7 @@     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Wayland: Failed to connect to display");-        return GL_FALSE;+        return GLFW_FALSE;     }      _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);@@ -553,12 +581,14 @@     _glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*));     _glfw.wl.monitorsSize = 4; +    createKeyTables();+     _glfw.wl.xkb.context = xkb_context_new(0);     if (!_glfw.wl.xkb.context)     {         _glfwInputError(GLFW_PLATFORM_ERROR,                         "Wayland: Failed to initialize xkb context");-        return GL_FALSE;+        return GLFW_FALSE;     }      // Sync so we got all registry objects@@ -567,12 +597,14 @@     // Sync so we got all initial output events     wl_display_roundtrip(_glfw.wl.display); -    if (!_glfwInitContextAPI())-        return GL_FALSE;+    if (!_glfwInitThreadLocalStoragePOSIX())+        return GLFW_FALSE; -    _glfwInitTimer();-    _glfwInitJoysticks();+    if (!_glfwInitJoysticksLinux())+        return GLFW_FALSE; +    _glfwInitTimerPOSIX();+     if (_glfw.wl.pointer && _glfw.wl.shm)     {         _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm);@@ -580,27 +612,20 @@         {             _glfwInputError(GLFW_PLATFORM_ERROR,                             "Wayland: Unable to load default cursor theme\n");-            return GL_FALSE;-        }-        _glfw.wl.defaultCursor =-            wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr");-        if (!_glfw.wl.defaultCursor)-        {-            _glfwInputError(GLFW_PLATFORM_ERROR,-                            "Wayland: Unable to load default left pointer\n");-            return GL_FALSE;+            return GLFW_FALSE;         }         _glfw.wl.cursorSurface =             wl_compositor_create_surface(_glfw.wl.compositor);     } -    return GL_TRUE;+    return GLFW_TRUE; }  void _glfwPlatformTerminate(void) {-    _glfwTerminateContextAPI();-    _glfwTerminateJoysticks();+    _glfwTerminateEGL();+    _glfwTerminateJoysticksLinux();+    _glfwTerminateThreadLocalStoragePOSIX();      if (_glfw.wl.cursorTheme)         wl_cursor_theme_destroy(_glfw.wl.cursorTheme);@@ -616,15 +641,18 @@  const char* _glfwPlatformGetVersionString(void) {-    const char* version = _GLFW_VERSION_NUMBER " Wayland EGL "+    return _GLFW_VERSION_NUMBER " Wayland EGL" #if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)         " clock_gettime"+#else+        " gettimeofday" #endif+#if defined(__linux__)+        " /dev/js"+#endif #if defined(_GLFW_BUILD_DLL)         " shared" #endif         ;--    return version; } 
glfw/src/wl_monitor.c view
@@ -1,5 +1,5 @@ //========================================================================-// GLFW 3.1 Wayland - www.glfw.org+// GLFW 3.2 Wayland - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> //@@ -69,7 +69,7 @@      mode.base.width = width;     mode.base.height = height;-    mode.base.refreshRate = refresh;+    mode.base.refreshRate = refresh / 1000;     mode.flags = flags;      if (monitor->wl.modesCount + 1 >= monitor->wl.modesSize)@@ -90,13 +90,16 @@ {     struct _GLFWmonitor *monitor = data; -    monitor->wl.done = GL_TRUE;+    monitor->wl.done = GLFW_TRUE; }  static void scale(void* data,                   struct wl_output* output,                   int32_t factor) {+    struct _GLFWmonitor *monitor = data;++    monitor->wl.scale = factor; }  static const struct wl_output_listener output_listener = {@@ -111,13 +114,13 @@ //////                       GLFW internal API                      ////// ////////////////////////////////////////////////////////////////////////// -void _glfwAddOutput(uint32_t name, uint32_t version)+void _glfwAddOutputWayland(uint32_t name, uint32_t version) {     _GLFWmonitor *monitor;     struct wl_output *output;     char name_str[80]; -    memset(name_str, 0, 80 * sizeof(char));+    memset(name_str, 0, sizeof(name_str));     snprintf(name_str, 79, "wl_output@%u", name);      if (version < 2)@@ -142,6 +145,8 @@     monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland));     monitor->wl.modesSize = 4; +    monitor->wl.scale = 1;+     monitor->wl.output = output;     wl_output_add_listener(output, &output_listener, monitor); @@ -195,7 +200,7 @@     return NULL; } -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)+GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) {     return first->wl.output == second->wl.output; }@@ -239,12 +244,26 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) {     // TODO-    fprintf(stderr, "_glfwPlatformGetGammaRamp not implemented yet\n");+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Wayland: Gamma ramp getting not supported yet"); }  void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) {     // TODO-    fprintf(stderr, "_glfwPlatformSetGammaRamp not implemented yet\n");+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Wayland: Gamma ramp setting not supported yet");+}+++//////////////////////////////////////////////////////////////////////////+//////                        GLFW native API                       //////+//////////////////////////////////////////////////////////////////////////++GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)+{+    _GLFWmonitor* monitor = (_GLFWmonitor*) handle;+    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);+    return monitor->wl.output; } 
glfw/src/wl_platform.h view
@@ -1,5 +1,5 @@ //========================================================================-// GLFW 3.1 Wayland - www.glfw.org+// GLFW 3.2 Wayland - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> //@@ -24,51 +24,86 @@ // //======================================================================== -#ifndef _wayland_platform_h_-#define _wayland_platform_h_-+#ifndef _glfw3_wayland_platform_h_+#define _glfw3_wayland_platform_h_  #include <wayland-client.h> #include <xkbcommon/xkbcommon.h>+#include <dlfcn.h> -#if defined(_GLFW_EGL)- #include "egl_context.h"-#else- #error "The Wayland backend depends on EGL platform support"-#endif+typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; +typedef struct VkWaylandSurfaceCreateInfoKHR+{+    VkStructureType                 sType;+    const void*                     pNext;+    VkWaylandSurfaceCreateFlagsKHR  flags;+    struct wl_display*              display;+    struct wl_surface*              surface;+} VkWaylandSurfaceCreateInfoKHR;++typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);+ #include "posix_tls.h" #include "posix_time.h" #include "linux_joystick.h"+#include "xkb_unicode.h"+#include "egl_context.h" -#define _GLFW_EGL_NATIVE_WINDOW         window->wl.native-#define _GLFW_EGL_NATIVE_DISPLAY        _glfw.wl.display+#include "wayland-relative-pointer-unstable-v1-client-protocol.h"+#include "wayland-pointer-constraints-unstable-v1-client-protocol.h" +#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)+#define _glfw_dlclose(handle) dlclose(handle)+#define _glfw_dlsym(handle, name) dlsym(handle, name)++#define _GLFW_EGL_NATIVE_WINDOW         ((EGLNativeWindowType) window->wl.native)+#define _GLFW_EGL_NATIVE_DISPLAY        ((EGLNativeDisplayType) _glfw.wl.display)+ #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowWayland  wl #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorWayland wl #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorWayland  wl +#define _GLFW_PLATFORM_CONTEXT_STATE+#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE + // Wayland-specific video mode data // typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland; - // Wayland-specific per-window data // typedef struct _GLFWwindowWayland {     int                         width, height;-    GLboolean                   visible;+    GLFWbool                    visible;+    GLFWbool                    maximized;     struct wl_surface*          surface;     struct wl_egl_window*       native;     struct wl_shell_surface*    shell_surface;     struct wl_callback*         callback;+     _GLFWcursor*                currentCursor;-} _GLFWwindowWayland;+    double                      cursorPosX, cursorPosY; +    char*                       title; +    // We need to track the monitors the window spans on to calculate the+    // optimal scaling factor.+    int                         scale;+    _GLFWmonitor**              monitors;+    int                         monitorsCount;+    int                         monitorsSize;++    struct {+        struct zwp_relative_pointer_v1*    relativePointer;+        struct zwp_locked_pointer_v1*      lockedPointer;+    } pointerLock;+} _GLFWwindowWayland;+ // Wayland-specific global data // typedef struct _GLFWlibraryWayland@@ -81,9 +116,12 @@     struct wl_seat*             seat;     struct wl_pointer*          pointer;     struct wl_keyboard*         keyboard;+    struct zwp_relative_pointer_manager_v1* relativePointerManager;+    struct zwp_pointer_constraints_v1*      pointerConstraints; +    int                         wl_compositor_version;+     struct wl_cursor_theme*     cursorTheme;-    struct wl_cursor*           defaultCursor;     struct wl_surface*          cursorSurface;     uint32_t                    pointerSerial; @@ -91,6 +129,8 @@     int                         monitorsCount;     int                         monitorsSize; +    short int                   publicKeys[256];+     struct {         struct xkb_context*     context;         struct xkb_keymap*      keymap;@@ -107,7 +147,6 @@  } _GLFWlibraryWayland; - // Wayland-specific per-monitor data // typedef struct _GLFWmonitorWayland@@ -117,24 +156,24 @@     _GLFWvidmodeWayland*        modes;     int                         modesCount;     int                         modesSize;-    GLboolean                   done;+    GLFWbool                    done;      int                         x;     int                         y;-+    int                         scale; } _GLFWmonitorWayland; - // Wayland-specific per-cursor data // typedef struct _GLFWcursorWayland {+    struct wl_cursor_image*     image;     struct wl_buffer*           buffer;     int                         width, height;     int                         xhot, yhot; } _GLFWcursorWayland;  -void _glfwAddOutput(uint32_t name, uint32_t version);+void _glfwAddOutputWayland(uint32_t name, uint32_t version); -#endif // _wayland_platform_h_+#endif // _glfw3_wayland_platform_h_
glfw/src/wl_window.c view
@@ -1,5 +1,5 @@ //========================================================================-// GLFW 3.1 Wayland - www.glfw.org+// GLFW 3.2 Wayland - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> //@@ -55,7 +55,32 @@                             int32_t height) {     _GLFWwindow* window = data;-    _glfwInputFramebufferSize(window, width, height);+    float aspectRatio;+    float targetRatio;++    if (!window->monitor)+    {+        if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)+        {+            aspectRatio = (float)width / (float)height;+            targetRatio = (float)window->numer / (float)window->denom;+            if (aspectRatio < targetRatio)+                height = width / targetRatio;+            else if (aspectRatio > targetRatio)+                width = height * targetRatio;+        }++        if (window->minwidth != GLFW_DONT_CARE && width < window->minwidth)+            width = window->minwidth;+        else if (window->maxwidth != GLFW_DONT_CARE && width > window->maxwidth)+            width = window->maxwidth;++        if (window->minheight != GLFW_DONT_CARE && height < window->minheight)+            height = window->minheight;+        else if (window->maxheight != GLFW_DONT_CARE && height > window->maxheight)+            height = window->maxheight;+    }+     _glfwInputWindowSize(window, width, height);     _glfwPlatformSetWindowSize(window, width, height);     _glfwInputWindowDamage(window);@@ -72,34 +97,159 @@     handlePopupDone }; -static GLboolean createSurface(_GLFWwindow* window,-                               const _GLFWwndconfig* wndconfig)+static void checkScaleChange(_GLFWwindow* window) {+    int scaledWidth, scaledHeight;+    int scale = 1;+    int i;+    int monitorScale;++    // Check if we will be able to set the buffer scale or not.+    if (_glfw.wl.wl_compositor_version < 3)+        return;++    // Get the scale factor from the highest scale monitor.+    for (i = 0; i < window->wl.monitorsCount; ++i)+    {+        monitorScale = window->wl.monitors[i]->wl.scale;+        if (scale < monitorScale)+            scale = monitorScale;+    }++    // Only change the framebuffer size if the scale changed.+    if (scale != window->wl.scale)+    {+        window->wl.scale = scale;+        scaledWidth = window->wl.width * scale;+        scaledHeight = window->wl.height * scale;+        wl_surface_set_buffer_scale(window->wl.surface, scale);+        wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);+        _glfwInputFramebufferSize(window, scaledWidth, scaledHeight);+    }+}++static void handleEnter(void *data,+                        struct wl_surface *surface,+                        struct wl_output *output)+{+    _GLFWwindow* window = data;+    _GLFWmonitor* monitor = wl_output_get_user_data(output);++    if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)+    {+        ++window->wl.monitorsSize;+        window->wl.monitors =+            realloc(window->wl.monitors,+                    window->wl.monitorsSize * sizeof(_GLFWmonitor*));+    }++    window->wl.monitors[window->wl.monitorsCount++] = monitor;++    checkScaleChange(window);+}++static void handleLeave(void *data,+                        struct wl_surface *surface,+                        struct wl_output *output)+{+    _GLFWwindow* window = data;+    _GLFWmonitor* monitor = wl_output_get_user_data(output);+    GLFWbool found;+    int i;++    for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)+    {+        if (monitor == window->wl.monitors[i])+            found = GLFW_TRUE;+        if (found)+            window->wl.monitors[i] = window->wl.monitors[i + 1];+    }+    window->wl.monitors[--window->wl.monitorsCount] = NULL;++    checkScaleChange(window);+}++static const struct wl_surface_listener surfaceListener = {+    handleEnter,+    handleLeave+};++// Makes the surface considered as XRGB instead of ARGB.+static void setOpaqueRegion(_GLFWwindow* window)+{+    struct wl_region* region;++    region = wl_compositor_create_region(_glfw.wl.compositor);+    if (!region)+        return;++    wl_region_add(region, 0, 0, window->wl.width, window->wl.height);+    wl_surface_set_opaque_region(window->wl.surface, region);+    wl_surface_commit(window->wl.surface);+    wl_region_destroy(region);+}++static GLFWbool createSurface(_GLFWwindow* window,+                              const _GLFWwndconfig* wndconfig)+{     window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);     if (!window->wl.surface)-        return GL_FALSE;+        return GLFW_FALSE; +    wl_surface_add_listener(window->wl.surface,+                            &surfaceListener,+                            window);+     wl_surface_set_user_data(window->wl.surface, window);      window->wl.native = wl_egl_window_create(window->wl.surface,                                              wndconfig->width,                                              wndconfig->height);     if (!window->wl.native)-        return GL_FALSE;+        return GLFW_FALSE; +    window->wl.width = wndconfig->width;+    window->wl.height = wndconfig->height;+    window->wl.scale = 1;++    // TODO: make this optional once issue #197 is fixed.+    setOpaqueRegion(window);++    return GLFW_TRUE;+}++static GLFWbool createShellSurface(_GLFWwindow* window)+{     window->wl.shell_surface = wl_shell_get_shell_surface(_glfw.wl.shell,                                                           window->wl.surface);     if (!window->wl.shell_surface)-        return GL_FALSE;+        return GLFW_FALSE;      wl_shell_surface_add_listener(window->wl.shell_surface,                                   &shellSurfaceListener,                                   window); -    window->wl.width = wndconfig->width;-    window->wl.height = wndconfig->height;+    if (window->wl.title)+        wl_shell_surface_set_title(window->wl.shell_surface, window->wl.title); -    return GL_TRUE;+    if (window->monitor)+    {+        wl_shell_surface_set_fullscreen(+            window->wl.shell_surface,+            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,+            0,+            window->monitor->wl.output);+    }+    else if (window->wl.maximized)+    {+        wl_shell_surface_set_maximized(window->wl.shell_surface, NULL);+    }+    else+    {+        wl_shell_surface_set_toplevel(window->wl.shell_surface);+    }++    return GLFW_TRUE; }  static int@@ -114,6 +264,43 @@     return fd; } +static void+handleEvents(int timeout)+{+    struct wl_display* display = _glfw.wl.display;+    struct pollfd fds[] = {+        { wl_display_get_fd(display), POLLIN },+    };++    while (wl_display_prepare_read(display) != 0)+        wl_display_dispatch_pending(display);++    // If an error different from EAGAIN happens, we have likely been+    // disconnected from the Wayland session, try to handle that the best we+    // can.+    if (wl_display_flush(display) < 0 && errno != EAGAIN)+    {+        _GLFWwindow* window = _glfw.windowListHead;+        while (window)+        {+            _glfwInputWindowCloseRequest(window);+            window = window->next;+        }+        wl_display_cancel_read(display);+        return;+    }++    if (poll(fds, 1, timeout) > 0)+    {+        wl_display_read_events(display);+        wl_display_dispatch_pending(display);+    }+    else+    {+        wl_display_cancel_read(display);+    }+}+ /*  * Create a new, unique, anonymous file of the given size, and  * return the file descriptor for it. The file descriptor is set@@ -150,7 +337,7 @@         return -1;     } -    name = malloc(strlen(path) + sizeof(template));+    name = calloc(strlen(path) + sizeof(template), 1);     strcpy(name, path);     strcat(name, template); @@ -170,6 +357,28 @@     return fd; } +// Translates a GLFW standard cursor to a theme cursor name+//+static char *translateCursorShape(int shape)+{+    switch (shape)+    {+        case GLFW_ARROW_CURSOR:+            return "left_ptr";+        case GLFW_IBEAM_CURSOR:+            return "xterm";+        case GLFW_CROSSHAIR_CURSOR:+            return "crosshair";+        case GLFW_HAND_CURSOR:+            return "grabbing";+        case GLFW_HRESIZE_CURSOR:+            return "sb_h_double_arrow";+        case GLFW_VRESIZE_CURSOR:+            return "sb_v_double_arrow";+    }+    return NULL;+}+ ////////////////////////////////////////////////////////////////////////// //////                       GLFW platform API                      ////// //////////////////////////////////////////////////////////////////////////@@ -179,28 +388,40 @@                               const _GLFWctxconfig* ctxconfig,                               const _GLFWfbconfig* fbconfig) {-    if (!_glfwCreateContext(window, ctxconfig, fbconfig))-        return GL_FALSE;-     if (!createSurface(window, wndconfig))-        return GL_FALSE;+        return GLFW_FALSE; -    if (wndconfig->monitor)+    if (ctxconfig->client != GLFW_NO_API)     {-        wl_shell_surface_set_fullscreen(-            window->wl.shell_surface,-            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,-            0,-            wndconfig->monitor->wl.output);+        if (!_glfwInitEGL())+            return GLFW_FALSE;+        if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))+            return GLFW_FALSE;     }++    if (wndconfig->title)+        window->wl.title = strdup(wndconfig->title);++    if (wndconfig->visible)+    {+        if (!createShellSurface(window))+            return GLFW_FALSE;++        window->wl.visible = GLFW_TRUE;+    }     else     {-        wl_shell_surface_set_toplevel(window->wl.shell_surface);+        window->wl.shell_surface = NULL;+        window->wl.visible = GLFW_FALSE;     }      window->wl.currentCursor = NULL; -    return GL_TRUE;+    window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));+    window->wl.monitorsCount = 0;+    window->wl.monitorsSize = 1;++    return GLFW_TRUE; }  void _glfwPlatformDestroyWindow(_GLFWwindow* window)@@ -208,15 +429,16 @@     if (window == _glfw.wl.pointerFocus)     {         _glfw.wl.pointerFocus = NULL;-        _glfwInputCursorEnter(window, GL_FALSE);+        _glfwInputCursorEnter(window, GLFW_FALSE);     }     if (window == _glfw.wl.keyboardFocus)     {         _glfw.wl.keyboardFocus = NULL;-        _glfwInputWindowFocus(window, GL_FALSE);+        _glfwInputWindowFocus(window, GLFW_FALSE);     } -    _glfwDestroyContext(window);+    if (window->context.destroy)+        window->context.destroy(window);      if (window->wl.native)         wl_egl_window_destroy(window->wl.native);@@ -226,13 +448,27 @@      if (window->wl.surface)         wl_surface_destroy(window->wl.surface);++    free(window->wl.title);+    free(window->wl.monitors); }  void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) {-    wl_shell_surface_set_title(window->wl.shell_surface, title);+    if (window->wl.title)+        free(window->wl.title);+    window->wl.title = strdup(title);+    if (window->wl.shell_surface)+        wl_shell_surface_set_title(window->wl.shell_surface, title); } +void _glfwPlatformSetWindowIcon(_GLFWwindow* window,+                                int count, const GLFWimage* images)+{+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Wayland: Setting window icon not supported");+}+ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) {     // A Wayland client is not aware of its position, so just warn and leave it@@ -260,111 +496,157 @@  void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) {-    wl_egl_window_resize(window->wl.native, width, height, 0, 0);+    int scaledWidth = width * window->wl.scale;+    int scaledHeight = height * window->wl.scale;     window->wl.width = width;     window->wl.height = height;+    wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);+    setOpaqueRegion(window);+    _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); } +void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,+                                      int minwidth, int minheight,+                                      int maxwidth, int maxheight)+{+    // TODO: find out how to trigger a resize.+    // The actual limits are checked in the wl_shell_surface::configure handler.+}++void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)+{+    // TODO: find out how to trigger a resize.+    // The actual limits are checked in the wl_shell_surface::configure handler.+}+ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) {     _glfwPlatformGetWindowSize(window, width, height);+    *width *= window->wl.scale;+    *height *= window->wl.scale; }  void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,                                      int* left, int* top,                                      int* right, int* bottom) {-    // TODO-    fprintf(stderr, "_glfwPlatformGetWindowFrameSize not implemented yet\n");+    // TODO: will need a proper implementation once decorations are+    // implemented, but for now just leave everything as 0. }  void _glfwPlatformIconifyWindow(_GLFWwindow* window) {-    // TODO-    fprintf(stderr, "_glfwPlatformIconifyWindow not implemented yet\n");+    // TODO: move to xdg_shell instead of wl_shell.+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Wayland: Iconify window not supported"); }  void _glfwPlatformRestoreWindow(_GLFWwindow* window) {-    // TODO-    fprintf(stderr, "_glfwPlatformRestoreWindow not implemented yet\n");+    // TODO: also do the same for iconified.+    if (window->monitor || window->wl.maximized)+    {+        if (window->wl.shell_surface)+            wl_shell_surface_set_toplevel(window->wl.shell_surface);++        window->wl.maximized = GLFW_FALSE;+    } } -void _glfwPlatformShowWindow(_GLFWwindow* window)+void _glfwPlatformMaximizeWindow(_GLFWwindow* window) {-    wl_shell_surface_set_toplevel(window->wl.shell_surface);+    if (!window->monitor && !window->wl.maximized)+    {+        if (window->wl.shell_surface)+        {+            // Let the compositor select the best output.+            wl_shell_surface_set_maximized(window->wl.shell_surface, NULL);+        }+        window->wl.maximized = GLFW_TRUE;+    } } -void _glfwPlatformUnhideWindow(_GLFWwindow* window)+void _glfwPlatformShowWindow(_GLFWwindow* window) {-    // TODO-    fprintf(stderr, "_glfwPlatformUnhideWindow not implemented yet\n");+    if (!window->monitor)+    {+        if (!window->wl.shell_surface)+            createShellSurface(window);+        window->wl.visible = GLFW_TRUE;+    } }  void _glfwPlatformHideWindow(_GLFWwindow* window) {-    wl_surface_attach(window->wl.surface, NULL, 0, 0);-    wl_surface_commit(window->wl.surface);+    if (!window->monitor)+    {+        if (window->wl.shell_surface)+            wl_shell_surface_destroy(window->wl.shell_surface);+        window->wl.visible = GLFW_FALSE;+    } } +void _glfwPlatformFocusWindow(_GLFWwindow* window)+{+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Wayland: Focusing a window requires user interaction");+}++void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,+                                   _GLFWmonitor* monitor,+                                   int xpos, int ypos,+                                   int width, int height,+                                   int refreshRate)+{+    if (monitor)+    {+        wl_shell_surface_set_fullscreen(+            window->wl.shell_surface,+            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,+            refreshRate * 1000, // Convert Hz to mHz.+            monitor->wl.output);+    }+    else+    {+        wl_shell_surface_set_toplevel(window->wl.shell_surface);+    }+    _glfwInputWindowMonitorChange(window, monitor);+}+ int _glfwPlatformWindowFocused(_GLFWwindow* window) {-    // TODO-    return GL_FALSE;+    return _glfw.wl.keyboardFocus == window; }  int _glfwPlatformWindowIconified(_GLFWwindow* window) {-    // TODO-    return GL_FALSE;+    // TODO: move to xdg_shell, wl_shell doesn't have any iconified concept.+    return GLFW_FALSE; }  int _glfwPlatformWindowVisible(_GLFWwindow* window) {-    // TODO-    return GL_FALSE;+    return window->wl.visible; } -void _glfwPlatformPollEvents(void)+int _glfwPlatformWindowMaximized(_GLFWwindow* window) {-    struct wl_display* display = _glfw.wl.display;-    struct pollfd fds[] = {-        { wl_display_get_fd(display), POLLIN },-    };+    return window->wl.maximized;+} -    while (wl_display_prepare_read(display) != 0)-        wl_display_dispatch_pending(display);-    wl_display_flush(display);-    if (poll(fds, 1, 0) > 0)-    {-        wl_display_read_events(display);-        wl_display_dispatch_pending(display);-    }-    else-    {-        wl_display_cancel_read(display);-    }+void _glfwPlatformPollEvents(void)+{+    handleEvents(0); }  void _glfwPlatformWaitEvents(void) {-    struct wl_display* display = _glfw.wl.display;-    struct pollfd fds[] = {-        { wl_display_get_fd(display), POLLIN },-    };+    handleEvents(-1);+} -    while (wl_display_prepare_read(display) != 0)-        wl_display_dispatch_pending(display);-    wl_display_flush(display);-    if (poll(fds, 1, -1) > 0)-    {-        wl_display_read_events(display);-        wl_display_dispatch_pending(display);-    }-    else-    {-        wl_display_cancel_read(display);-    }+void _glfwPlatformWaitEventsTimeout(double timeout)+{+    handleEvents((int) (timeout * 1e3)); }  void _glfwPlatformPostEmptyEvent(void)@@ -374,22 +656,36 @@  void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) {-    // TODO-    fprintf(stderr, "_glfwPlatformGetCursorPos not implemented yet\n");+    if (xpos)+        *xpos = window->wl.cursorPosX;+    if (ypos)+        *ypos = window->wl.cursorPosY; } +static GLFWbool isPointerLocked(_GLFWwindow* window);+ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) {-    // A Wayland client can not set the cursor position-    _glfwInputError(GLFW_PLATFORM_ERROR,-                    "Wayland: Cursor position setting not supported");+    if (isPointerLocked(window))+    {+        zwp_locked_pointer_v1_set_cursor_position_hint(+            window->wl.pointerLock.lockedPointer,+            wl_fixed_from_double(x), wl_fixed_from_double(y));+        wl_surface_commit(window->wl.surface);+    } } -void _glfwPlatformApplyCursorMode(_GLFWwindow* window)+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) {     _glfwPlatformSetCursor(window, window->wl.currentCursor); } +const char* _glfwPlatformGetKeyName(int key, int scancode)+{+    // TODO+    return NULL;+}+ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,                               const GLFWimage* image,                               int xhot, int yhot)@@ -404,18 +700,18 @@     if (fd < 0)     {         _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Wayland: Creating a buffer file for %d B failed: %m\n",+                        "Wayland: Creating a buffer file for %d B failed: %m",                         length);-        return GL_FALSE;+        return GLFW_FALSE;     }      data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);     if (data == MAP_FAILED)     {         _glfwInputError(GLFW_PLATFORM_ERROR,-                        "Wayland: Cursor mmap failed: %m\n");+                        "Wayland: Cursor mmap failed: %m");         close(fd);-        return GL_FALSE;+        return GLFW_FALSE;     }      pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);@@ -425,10 +721,12 @@     unsigned char* target = data;     for (i = 0;  i < image->width * image->height;  i++, source += 4)     {-        *target++ = source[2];-        *target++ = source[1];-        *target++ = source[0];-        *target++ = source[3];+        unsigned int alpha = source[3];++        *target++ = (unsigned char) ((source[2] * alpha) / 255);+        *target++ = (unsigned char) ((source[1] * alpha) / 255);+        *target++ = (unsigned char) ((source[0] * alpha) / 255);+        *target++ = (unsigned char) alpha;     }      cursor->wl.buffer =@@ -443,24 +741,138 @@     cursor->wl.height = image->height;     cursor->wl.xhot = xhot;     cursor->wl.yhot = yhot;-    return GL_TRUE;+    return GLFW_TRUE; }  int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) {-    // TODO-    fprintf(stderr, "_glfwPlatformCreateStandardCursor not implemented yet\n");-    return GL_FALSE;+    struct wl_cursor* standardCursor;++    standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,+                                                translateCursorShape(shape));+    if (!standardCursor)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Wayland: Standard cursor \"%s\" not found",+                        translateCursorShape(shape));+        return GLFW_FALSE;+    }++    cursor->wl.image = standardCursor->images[0];+    return GLFW_TRUE; }  void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) {-    wl_buffer_destroy(cursor->wl.buffer);+    // If it's a standard cursor we don't need to do anything here+    if (cursor->wl.image)+        return;++    if (cursor->wl.buffer)+        wl_buffer_destroy(cursor->wl.buffer); } +static void handleRelativeMotion(void* data,+                                 struct zwp_relative_pointer_v1* pointer,+                                 uint32_t timeHi,+                                 uint32_t timeLo,+                                 wl_fixed_t dx,+                                 wl_fixed_t dy,+                                 wl_fixed_t dxUnaccel,+                                 wl_fixed_t dyUnaccel)+{+    _GLFWwindow* window = data;++    if (window->cursorMode != GLFW_CURSOR_DISABLED)+        return;++    _glfwInputCursorPos(window,+                        window->virtualCursorPosX + wl_fixed_to_double(dxUnaccel),+                        window->virtualCursorPosY + wl_fixed_to_double(dyUnaccel));+}++static const struct zwp_relative_pointer_v1_listener relativePointerListener = {+    handleRelativeMotion+};++static void handleLocked(void* data,+                         struct zwp_locked_pointer_v1* lockedPointer)+{+}++static void unlockPointer(_GLFWwindow* window)+{+    struct zwp_relative_pointer_v1* relativePointer =+        window->wl.pointerLock.relativePointer;+    struct zwp_locked_pointer_v1* lockedPointer =+        window->wl.pointerLock.lockedPointer;++    zwp_relative_pointer_v1_destroy(relativePointer);+    zwp_locked_pointer_v1_destroy(lockedPointer);++    window->wl.pointerLock.relativePointer = NULL;+    window->wl.pointerLock.lockedPointer = NULL;+}++static void lockPointer(_GLFWwindow* window);++static void handleUnlocked(void* data,+                           struct zwp_locked_pointer_v1* lockedPointer)+{+}++static const struct zwp_locked_pointer_v1_listener lockedPointerListener = {+    handleLocked,+    handleUnlocked+};++static void lockPointer(_GLFWwindow* window)+{+    struct zwp_relative_pointer_v1* relativePointer;+    struct zwp_locked_pointer_v1* lockedPointer;++    if (!_glfw.wl.relativePointerManager)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Wayland: no relative pointer manager");+        return;+    }++    relativePointer =+        zwp_relative_pointer_manager_v1_get_relative_pointer(+            _glfw.wl.relativePointerManager,+            _glfw.wl.pointer);+    zwp_relative_pointer_v1_add_listener(relativePointer,+                                         &relativePointerListener,+                                         window);++    lockedPointer =+        zwp_pointer_constraints_v1_lock_pointer(+            _glfw.wl.pointerConstraints,+            window->wl.surface,+            _glfw.wl.pointer,+            NULL,+            ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);+    zwp_locked_pointer_v1_add_listener(lockedPointer,+                                       &lockedPointerListener,+                                       window);++    window->wl.pointerLock.relativePointer = relativePointer;+    window->wl.pointerLock.lockedPointer = lockedPointer;++    wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,+                          NULL, 0, 0);+}++static GLFWbool isPointerLocked(_GLFWwindow* window)+{+    return window->wl.pointerLock.lockedPointer != NULL;+}+ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) {     struct wl_buffer* buffer;+    struct wl_cursor* defaultCursor;     struct wl_cursor_image* image;     struct wl_surface* surface = _glfw.wl.cursorSurface; @@ -474,11 +886,29 @@     if (window != _glfw.wl.pointerFocus)         return; +    // Unlock possible pointer lock if no longer disabled.+    if (window->cursorMode != GLFW_CURSOR_DISABLED && isPointerLocked(window))+        unlockPointer(window);+     if (window->cursorMode == GLFW_CURSOR_NORMAL)     {-        if (cursor == NULL)+        if (cursor)+            image = cursor->wl.image;+        else         {-            image = _glfw.wl.defaultCursor->images[0];+            defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,+                                                       "left_ptr");+            if (!defaultCursor)+            {+                _glfwInputError(GLFW_PLATFORM_ERROR,+                                "Wayland: Standard cursor not found");+                return;+            }+            image = defaultCursor->images[0];+        }++        if (image)+        {             buffer = wl_cursor_image_get_buffer(image);             if (!buffer)                 return;@@ -503,22 +933,118 @@             wl_surface_commit(surface);         }     }-    else /* Cursor is hidden set cursor surface to NULL */+    else if (window->cursorMode == GLFW_CURSOR_DISABLED)     {-        wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, NULL, 0, 0);+        if (!isPointerLocked(window))+            lockPointer(window);     }+    else if (window->cursorMode == GLFW_CURSOR_HIDDEN)+    {+        wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,+                              NULL, 0, 0);+    } }  void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) {     // TODO-    fprintf(stderr, "_glfwPlatformSetClipboardString not implemented yet\n");+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Wayland: Clipboard setting not implemented yet"); }  const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) {     // TODO-    fprintf(stderr, "_glfwPlatformGetClipboardString not implemented yet\n");+    _glfwInputError(GLFW_PLATFORM_ERROR,+                    "Wayland: Clipboard getting not implemented yet");     return NULL;+}++char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count)+{+    char** extensions;++    *count = 0;++    if (!_glfw.vk.KHR_wayland_surface)+        return NULL;++    extensions = calloc(2, sizeof(char*));+    extensions[0] = strdup("VK_KHR_surface");+    extensions[1] = strdup("VK_KHR_wayland_surface");++    *count = 2;+    return extensions;+}++int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,+                                                      VkPhysicalDevice device,+                                                      uint32_t queuefamily)+{+    PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =+        (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)+        vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");+    if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");+        return VK_NULL_HANDLE;+    }++    return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device,+                                                            queuefamily,+                                                            _glfw.wl.display);+}++VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,+                                          _GLFWwindow* window,+                                          const VkAllocationCallbacks* allocator,+                                          VkSurfaceKHR* surface)+{+    VkResult err;+    VkWaylandSurfaceCreateInfoKHR sci;+    PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;++    vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)+        vkGetInstanceProcAddr(instance, "vkCreateWaylandSurfaceKHR");+    if (!vkCreateWaylandSurfaceKHR)+    {+        _glfwInputError(GLFW_API_UNAVAILABLE,+                        "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");+        return VK_ERROR_EXTENSION_NOT_PRESENT;+    }++    memset(&sci, 0, sizeof(sci));+    sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;+    sci.display = _glfw.wl.display;+    sci.surface = window->wl.surface;++    err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface);+    if (err)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "Wayland: Failed to create Vulkan surface: %s",+                        _glfwGetVulkanResultString(err));+    }++    return err;+}+++//////////////////////////////////////////////////////////////////////////+//////                        GLFW native API                       //////+//////////////////////////////////////////////////////////////////////////++GLFWAPI struct wl_display* glfwGetWaylandDisplay(void)+{+    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);+    return _glfw.wl.display;+}++GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)+{+    _GLFWwindow* window = (_GLFWwindow*) handle;+    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);+    return window->wl.surface; } 
glfw/src/x11_init.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 X11 - www.glfw.org+// GLFW 3.2 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -38,7 +38,7 @@  // Translate an X11 key code to a GLFW key code. //-static int translateKey(int scancode)+static int translateKeyCode(int scancode) {     int keySym; @@ -72,9 +72,8 @@             default:                break;         } -        // Now try primary keysym for function keys (non-printable keys). These-        // should not be layout dependent (i.e. US layout and international-        // layouts should give the same result).+        // Now try primary keysym for function keys (non-printable keys)+        // These should not depend on the current keyboard layout         keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);     }     else@@ -234,6 +233,7 @@     int scancode, key;      memset(_glfw.x11.publicKeys, -1, sizeof(_glfw.x11.publicKeys));+    memset(_glfw.x11.nativeKeys, -1, sizeof(_glfw.x11.nativeKeys));      if (_glfw.x11.xkb.available)     {@@ -241,15 +241,14 @@         // keyboard layout          char name[XkbKeyNameLength + 1];-        XkbDescPtr descr = XkbGetKeyboard(_glfw.x11.display,-                                          XkbAllComponentsMask,-                                          XkbUseCoreKbd);+        XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);+        XkbGetNames(_glfw.x11.display, XkbKeyNamesMask, desc);          // Find the X11 key code -> GLFW key code mapping-        for (scancode = descr->min_key_code;  scancode <= descr->max_key_code;  scancode++)+        for (scancode = desc->min_key_code;  scancode <= desc->max_key_code;  scancode++)         {-            memcpy(name, descr->names->keys[scancode].name, XkbKeyNameLength);-            name[XkbKeyNameLength] = 0;+            memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength);+            name[XkbKeyNameLength] = '\0';              // Map the key name to a GLFW key code. Note: We only map printable             // keys here, and we use the US keyboard layout. The rest of the@@ -309,34 +308,39 @@                 _glfw.x11.publicKeys[scancode] = key;         } -        XkbFreeKeyboard(descr, 0, True);+        XkbFreeNames(desc, XkbKeyNamesMask, True);+        XkbFreeKeyboard(desc, 0, True);     } -    // Translate the un-translated key codes using traditional X11 KeySym-    // lookups     for (scancode = 0;  scancode < 256;  scancode++)     {+        // Translate the un-translated key codes using traditional X11 KeySym+        // lookups         if (_glfw.x11.publicKeys[scancode] < 0)-            _glfw.x11.publicKeys[scancode] = translateKey(scancode);+            _glfw.x11.publicKeys[scancode] = translateKeyCode(scancode);++        // Store the reverse translation for faster key name lookup+        if (_glfw.x11.publicKeys[scancode] > 0)+            _glfw.x11.nativeKeys[_glfw.x11.publicKeys[scancode]] = scancode;     } }  // Check whether the IM has a usable style //-static GLboolean hasUsableInputMethodStyle(void)+static GLFWbool hasUsableInputMethodStyle(void) {     unsigned int i;-    GLboolean found = GL_FALSE;+    GLFWbool found = GLFW_FALSE;     XIMStyles* styles = NULL;      if (XGetIMValues(_glfw.x11.im, XNQueryInputStyle, &styles, NULL) != NULL)-        return GL_FALSE;+        return GLFW_FALSE;      for (i = 0;  i < styles->count_styles;  i++)     {         if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))         {-            found = GL_TRUE;+            found = GLFW_TRUE;             break;         }     }@@ -351,16 +355,13 @@                              unsigned long atomCount,                              const char* atomName) {-    Atom atom = XInternAtom(_glfw.x11.display, atomName, True);-    if (atom != None)-    {-        unsigned long i;+    unsigned long i;+    const Atom atom = XInternAtom(_glfw.x11.display, atomName, False); -        for (i = 0;  i < atomCount;  i++)-        {-            if (supportedAtoms[i] == atom)-                return atom;-        }+    for (i = 0;  i < atomCount;  i++)+    {+        if (supportedAtoms[i] == atom)+            return atom;     }      return None;@@ -373,33 +374,31 @@     Window* windowFromRoot = NULL;     Window* windowFromChild = NULL; -    // First we need a couple of atoms, which should already be there-    Atom supportingWmCheck =-        XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", True);-    Atom wmSupported =-        XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", True);-    if (supportingWmCheck == None || wmSupported == None)-        return;+    // First we need a couple of atoms+    const Atom supportingWmCheck =+        XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);+    const Atom wmSupported =+        XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);      // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window-    if (_glfwGetWindowProperty(_glfw.x11.root,-                               supportingWmCheck,-                               XA_WINDOW,-                               (unsigned char**) &windowFromRoot) != 1)+    if (_glfwGetWindowPropertyX11(_glfw.x11.root,+                                  supportingWmCheck,+                                  XA_WINDOW,+                                  (unsigned char**) &windowFromRoot) != 1)     {         if (windowFromRoot)             XFree(windowFromRoot);         return;     } -    _glfwGrabXErrorHandler();+    _glfwGrabErrorHandlerX11();      // It should be the ID of a child window (of the root)     // Then we look for the same property on the child window-    if (_glfwGetWindowProperty(*windowFromRoot,-                               supportingWmCheck,-                               XA_WINDOW,-                               (unsigned char**) &windowFromChild) != 1)+    if (_glfwGetWindowPropertyX11(*windowFromRoot,+                                  supportingWmCheck,+                                  XA_WINDOW,+                                  (unsigned char**) &windowFromChild) != 1)     {         XFree(windowFromRoot);         if (windowFromChild)@@ -407,7 +406,7 @@         return;     } -    _glfwReleaseXErrorHandler();+    _glfwReleaseErrorHandlerX11();      // It should be the ID of that same child window     if (*windowFromRoot != *windowFromChild)@@ -427,10 +426,10 @@      // Now we need to check the _NET_SUPPORTED property of the root window     // It should be a list of supported WM protocol and state atoms-    atomCount = _glfwGetWindowProperty(_glfw.x11.root,-                                       wmSupported,-                                       XA_ATOM,-                                       (unsigned char**) &supportedAtoms);+    atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,+                                          wmSupported,+                                          XA_ATOM,+                                          (unsigned char**) &supportedAtoms);      // See which of the atoms we support that are supported by the WM     _glfw.x11.NET_WM_STATE =@@ -439,46 +438,30 @@         getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");     _glfw.x11.NET_WM_STATE_FULLSCREEN =         getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");+    _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =+        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");+    _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =+        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");     _glfw.x11.NET_WM_FULLSCREEN_MONITORS =         getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");-    _glfw.x11.NET_WM_NAME =-        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");-    _glfw.x11.NET_WM_ICON_NAME =-        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME");-    _glfw.x11.NET_WM_PID =-        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PID");-    _glfw.x11.NET_WM_PING =-        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING");+    _glfw.x11.NET_WM_WINDOW_TYPE =+        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");+    _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =+        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");     _glfw.x11.NET_ACTIVE_WINDOW =         getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");     _glfw.x11.NET_FRAME_EXTENTS =         getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");     _glfw.x11.NET_REQUEST_FRAME_EXTENTS =         getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");-    _glfw.x11.NET_WM_BYPASS_COMPOSITOR =-        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_BYPASS_COMPOSITOR");      XFree(supportedAtoms);--    _glfw.x11.hasEWMH = GL_TRUE; }  // Initialize X11 display and look for supported X11 extensions //-static GLboolean initExtensions(void)+static GLFWbool initExtensions(void) {-    // Find or create window manager atoms-    _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display,-                                         "WM_PROTOCOLS",-                                         False);-    _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False);-    _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display,-                                             "WM_DELETE_WINDOW",-                                             False);-    _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display,-                                           "_MOTIF_WM_HINTS",-                                           False);- #if defined(_GLFW_HAS_XF86VM)     // Check for XF86VidMode extension     _glfw.x11.vidmode.available =@@ -488,32 +471,29 @@ #endif /*_GLFW_HAS_XF86VM*/      // Check for RandR extension-    _glfw.x11.randr.available =-        XRRQueryExtension(_glfw.x11.display,+    if (XRRQueryExtension(_glfw.x11.display,                           &_glfw.x11.randr.eventBase,-                          &_glfw.x11.randr.errorBase);--    if (_glfw.x11.randr.available)+                          &_glfw.x11.randr.errorBase))     {-        XRRScreenResources* sr;--        if (!XRRQueryVersion(_glfw.x11.display,-                             &_glfw.x11.randr.versionMajor,-                             &_glfw.x11.randr.versionMinor))+        if (XRRQueryVersion(_glfw.x11.display,+                            &_glfw.x11.randr.major,+                            &_glfw.x11.randr.minor))         {-            _glfwInputError(GLFW_PLATFORM_ERROR,-                            "X11: Failed to query RandR version");-            return GL_FALSE;+            // The GLFW RandR path requires at least version 1.3+            if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)+                _glfw.x11.randr.available = GLFW_TRUE;         }--        // The GLFW RandR path requires at least version 1.3-        if (_glfw.x11.randr.versionMajor == 1 &&-            _glfw.x11.randr.versionMinor < 3)+        else         {-            _glfw.x11.randr.available = GL_FALSE;+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "X11: Failed to query RandR version");         }+    } -        sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root);+    if (_glfw.x11.randr.available)+    {+        XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,+                                                       _glfw.x11.root);          if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))         {@@ -523,49 +503,33 @@             // available             _glfwInputError(GLFW_PLATFORM_ERROR,                             "X11: RandR gamma ramp support seems broken");-            _glfw.x11.randr.gammaBroken = GL_TRUE;+            _glfw.x11.randr.gammaBroken = GLFW_TRUE;         }          XRRFreeScreenResources(sr);++        XRRSelectInput(_glfw.x11.display, _glfw.x11.root,+                       RROutputChangeNotifyMask);     }      if (XineramaQueryExtension(_glfw.x11.display,-                               &_glfw.x11.xinerama.versionMajor,-                               &_glfw.x11.xinerama.versionMinor))+                               &_glfw.x11.xinerama.major,+                               &_glfw.x11.xinerama.minor))     {         if (XineramaIsActive(_glfw.x11.display))-            _glfw.x11.xinerama.available = GL_TRUE;+            _glfw.x11.xinerama.available = GLFW_TRUE;     } -#if defined(_GLFW_HAS_XINPUT)-    if (XQueryExtension(_glfw.x11.display,-                        "XInputExtension",-                        &_glfw.x11.xi.majorOpcode,-                        &_glfw.x11.xi.eventBase,-                        &_glfw.x11.xi.errorBase))-    {-        _glfw.x11.xi.versionMajor = 2;-        _glfw.x11.xi.versionMinor = 0;--        if (XIQueryVersion(_glfw.x11.display,-                           &_glfw.x11.xi.versionMajor,-                           &_glfw.x11.xi.versionMinor) != BadRequest)-        {-            _glfw.x11.xi.available = GL_TRUE;-        }-    }-#endif /*_GLFW_HAS_XINPUT*/-     // Check if Xkb is supported on this display-    _glfw.x11.xkb.versionMajor = 1;-    _glfw.x11.xkb.versionMinor = 0;+    _glfw.x11.xkb.major = 1;+    _glfw.x11.xkb.minor = 0;     _glfw.x11.xkb.available =         XkbQueryExtension(_glfw.x11.display,                           &_glfw.x11.xkb.majorOpcode,                           &_glfw.x11.xkb.eventBase,                           &_glfw.x11.xkb.errorBase,-                          &_glfw.x11.xkb.versionMajor,-                          &_glfw.x11.xkb.versionMinor);+                          &_glfw.x11.xkb.major,+                          &_glfw.x11.xkb.minor);      if (_glfw.x11.xkb.available)     {@@ -574,10 +538,17 @@         if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))         {             if (supported)-                _glfw.x11.xkb.detectable = GL_TRUE;+                _glfw.x11.xkb.detectable = GLFW_TRUE;         }     } +    _glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so", RTLD_LAZY | RTLD_GLOBAL);+    if (_glfw.x11.x11xcb.handle)+    {+        _glfw.x11.x11xcb.XGetXCBConnection = (XGETXCBCONNECTION_T)+            dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");+    }+     // Update the key code LUT     // FIXME: We should listen to XkbMapNotify events to track changes to     // the keyboard mapping.@@ -586,7 +557,7 @@     // Detect whether an EWMH-conformant window manager is running     detectEWMH(); -    // Find or create string format atoms+    // String format atoms     _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);     _glfw.x11.UTF8_STRING =         XInternAtom(_glfw.x11.display, "UTF8_STRING", False);@@ -594,45 +565,69 @@         XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);     _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); -    // Find or create selection property atom+    // Custom selection property atom     _glfw.x11.GLFW_SELECTION =         XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); -    // Find or create standard clipboard atoms+    // ICCCM standard clipboard atoms     _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);     _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);     _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); -    // Find or create clipboard manager atoms+    // Clipboard manager atoms     _glfw.x11.CLIPBOARD_MANAGER =         XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False);     _glfw.x11.SAVE_TARGETS =         XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); -    // Find Xdnd (drag and drop) atoms, if available-    _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True);-    _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True);-    _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True);-    _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", True);-    _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", True);-    _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", True);-    _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", True);-    _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True);-    _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True);+    // Xdnd (drag and drop) atoms+    _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False);+    _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False);+    _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False);+    _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False);+    _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False);+    _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False);+    _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", False);+    _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False);+    _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); -    return GL_TRUE;+    // ICCCM, EWMH and Motif window property atoms+    // These can be set safely even without WM support+    // The EWMH atoms that require WM support are handled in detectEWMH+    _glfw.x11.WM_PROTOCOLS =+        XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False);+    _glfw.x11.WM_STATE =+        XInternAtom(_glfw.x11.display, "WM_STATE", False);+    _glfw.x11.WM_DELETE_WINDOW =+        XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);+    _glfw.x11.NET_WM_ICON =+        XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);+    _glfw.x11.NET_WM_PING =+        XInternAtom(_glfw.x11.display, "_NET_WM_PING", False);+    _glfw.x11.NET_WM_PID =+        XInternAtom(_glfw.x11.display, "_NET_WM_PID", False);+    _glfw.x11.NET_WM_NAME =+        XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False);+    _glfw.x11.NET_WM_ICON_NAME =+        XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False);+    _glfw.x11.NET_WM_BYPASS_COMPOSITOR =+        XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False);+    _glfw.x11.MOTIF_WM_HINTS =+        XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);++    return GLFW_TRUE; }  // Create a blank cursor for hidden and disabled cursor modes //-static Cursor createNULLCursor(void)+static Cursor createHiddenCursor(void) {     unsigned char pixels[16 * 16 * 4];     GLFWimage image = { 16, 16, pixels };      memset(pixels, 0, sizeof(pixels)); -    return _glfwCreateCursor(&image, 0, 0);+    return _glfwCreateCursorX11(&image, 0, 0); }  // X error handler@@ -650,7 +645,7 @@  // Sets the X error handler callback //-void _glfwGrabXErrorHandler(void)+void _glfwGrabErrorHandlerX11(void) {     _glfw.x11.errorCode = Success;     XSetErrorHandler(errorHandler);@@ -658,7 +653,7 @@  // Clears the X error handler callback //-void _glfwReleaseXErrorHandler(void)+void _glfwReleaseErrorHandlerX11(void) {     // Synchronize to make sure all commands are processed     XSync(_glfw.x11.display, False);@@ -667,7 +662,7 @@  // Reports the specified error, appending information about the last X error //-void _glfwInputXError(int error, const char* message)+void _glfwInputErrorX11(int error, const char* message) {     char buffer[8192];     XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode,@@ -678,7 +673,7 @@  // Creates a native cursor object from the specified image and hotspot //-Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)+Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot) {     int i;     Cursor cursor;@@ -695,10 +690,12 @@      for (i = 0;  i < image->width * image->height;  i++, target++, source += 4)     {-        *target = (source[3] << 24) |-                  (source[0] << 16) |-                  (source[1] <<  8) |-                   source[2];+        unsigned int alpha = source[3];++        *target = (alpha << 24) |+                  ((unsigned char) ((source[0] * alpha) / 255) << 16) |+                  ((unsigned char) ((source[1] * alpha) / 255) <<  8) |+                  ((unsigned char) ((source[2] * alpha) / 255) <<  0);     }      cursor = XcursorImageLoadCursor(_glfw.x11.display, native);@@ -714,16 +711,31 @@  int _glfwPlatformInit(void) {+#if !defined(X_HAVE_UTF8_STRING)+    // HACK: If the current locale is C, apply the environment's locale+    //       This is done because the C locale breaks wide character input     if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)         setlocale(LC_CTYPE, "");+#endif      XInitThreads();      _glfw.x11.display = XOpenDisplay(NULL);     if (!_glfw.x11.display)     {-        _glfwInputError(GLFW_API_UNAVAILABLE, "X11: Failed to open X display");-        return GL_FALSE;+        const char* display = getenv("DISPLAY");+        if (display)+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "X11: Failed to open display %s", display);+        }+        else+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "X11: The DISPLAY environment variable is missing");+        }++        return GLFW_FALSE;     }      _glfw.x11.screen = DefaultScreen(_glfw.x11.display);@@ -731,15 +743,15 @@     _glfw.x11.context = XUniqueContext();      if (!initExtensions())-        return GL_FALSE;+        return GLFW_FALSE; -    _glfw.x11.cursor = createNULLCursor();+    _glfw.x11.cursor = createHiddenCursor();      if (XSupportsLocale())     {         XSetLocaleModifiers(""); -        _glfw.x11.im = XOpenIM(_glfw.x11.display, 0, 0, 0);+        _glfw.x11.im = XOpenIM(_glfw.x11.display, 0, NULL, NULL);         if (_glfw.x11.im)         {             if (!hasUsableInputMethodStyle())@@ -750,19 +762,25 @@         }     } -    if (!_glfwInitContextAPI())-        return GL_FALSE;+    if (!_glfwInitThreadLocalStoragePOSIX())+        return GLFW_FALSE; -    if (!_glfwInitJoysticks())-        return GL_FALSE;+    if (!_glfwInitJoysticksLinux())+        return GLFW_FALSE; -    _glfwInitTimer();+    _glfwInitTimerPOSIX(); -    return GL_TRUE;+    return GLFW_TRUE; }  void _glfwPlatformTerminate(void) {+    if (_glfw.x11.x11xcb.handle)+    {+        dlclose(_glfw.x11.x11xcb.handle);+        _glfw.x11.x11xcb.handle = NULL;+    }+     if (_glfw.x11.cursor)     {         XFreeCursor(_glfw.x11.display, _glfw.x11.cursor);@@ -777,44 +795,39 @@         _glfw.x11.im = NULL;     } -    _glfwTerminateJoysticks();-    _glfwTerminateContextAPI();+    _glfwTerminateEGL();      if (_glfw.x11.display)     {         XCloseDisplay(_glfw.x11.display);         _glfw.x11.display = NULL;     }++    // NOTE: This needs to be done after XCloseDisplay, as libGL registers+    //       cleanup callbacks that get called by it+    _glfwTerminateGLX();++    _glfwTerminateJoysticksLinux();+    _glfwTerminateThreadLocalStoragePOSIX(); }  const char* _glfwPlatformGetVersionString(void) {-    const char* version = _GLFW_VERSION_NUMBER " X11"-#if defined(_GLFW_GLX)-        " GLX"-#elif defined(_GLFW_EGL)-        " EGL"-#endif-#if defined(_GLFW_HAS_GLXGETPROCADDRESS)-        " glXGetProcAddress"-#elif defined(_GLFW_HAS_GLXGETPROCADDRESSARB)-        " glXGetProcAddressARB"-#elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT)-        " glXGetProcAddressEXT"-#elif defined(_GLFW_DLOPEN_LIBGL)-        " dlsym(libGL)"-#endif+    return _GLFW_VERSION_NUMBER " X11 GLX EGL" #if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)         " clock_gettime"+#else+        " gettimeofday" #endif #if defined(__linux__)         " /dev/js" #endif+#if defined(_GLFW_HAS_XF86VM)+        " Xf86vm"+#endif #if defined(_GLFW_BUILD_DLL)         " shared" #endif         ;--    return version; } 
glfw/src/x11_monitor.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 X11 - www.glfw.org+// GLFW 3.2 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -34,7 +34,7 @@  // Check whether the display mode should be included in enumeration //-static GLboolean modeIsGood(const XRRModeInfo* mi)+static GLFWbool modeIsGood(const XRRModeInfo* mi) {     return (mi->modeFlags & RR_Interlace) == 0; }@@ -97,7 +97,7 @@  // Set the current video mode for the specified monitor //-GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)+GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired) {     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)     {@@ -112,7 +112,7 @@         best = _glfwChooseVideoMode(monitor, desired);         _glfwPlatformGetVideoMode(monitor, &current);         if (_glfwCompareVideoModes(&current, best) == 0)-            return GL_TRUE;+            return GLFW_TRUE;          sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root);         ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);@@ -155,16 +155,16 @@         {             _glfwInputError(GLFW_PLATFORM_ERROR,                             "X11: Monitor mode list changed");-            return GL_FALSE;+            return GLFW_FALSE;         }     } -    return GL_TRUE;+    return GLFW_TRUE; }  // Restore the saved (original) video mode for the specified monitor //-void _glfwRestoreVideoMode(_GLFWmonitor* monitor)+void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor) {     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)     {@@ -200,7 +200,7 @@  _GLFWmonitor** _glfwPlatformGetMonitors(int* count) {-    int i, j, k, size = 0, found = 0;+    int i, j, k, found = 0;     _GLFWmonitor** monitors = NULL;      *count = 0;@@ -214,6 +214,8 @@         RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,                                                _glfw.x11.root); +        monitors = calloc(sr->noutput, sizeof(_GLFWmonitor*));+         if (_glfw.x11.xinerama.available)             screens = XineramaQueryScreens(_glfw.x11.display, &screenCount); @@ -225,6 +227,7 @@             for (j = 0;  j < ci->noutput;  j++)             {                 int widthMM, heightMM;+                _GLFWmonitor* monitor;                 XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display,                                                      sr, ci->outputs[j]);                 if (oi->connection != RR_Connected)@@ -233,12 +236,6 @@                     continue;                 } -                if (found == size)-                {-                    size += 4;-                    monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size);-                }-                 if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)                 {                     widthMM  = oi->mm_height;@@ -250,9 +247,9 @@                     heightMM = oi->mm_height;                 } -                monitors[found] = _glfwAllocMonitor(oi->name, widthMM, heightMM);-                monitors[found]->x11.output = ci->outputs[j];-                monitors[found]->x11.crtc   = oi->crtc;+                monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);+                monitor->x11.output = ci->outputs[j];+                monitor->x11.crtc   = oi->crtc;                  for (k = 0;  k < screenCount;  k++)                 {@@ -261,17 +258,18 @@                         screens[k].width == ci->width &&                         screens[k].height == ci->height)                     {-                        monitors[found]->x11.index = k;+                        monitor->x11.index = k;                         break;                     }                 }                  XRRFreeOutputInfo(oi); -                if (ci->outputs[j] == primary)-                    _GLFW_SWAP_POINTERS(monitors[0], monitors[found]);-                 found++;+                monitors[found - 1] = monitor;++                if (ci->outputs[j] == primary)+                    _GLFW_SWAP_POINTERS(monitors[0], monitors[found - 1]);             }              XRRFreeCrtcInfo(ci);@@ -286,7 +284,10 @@         {             _glfwInputError(GLFW_PLATFORM_ERROR,                             "X11: RandR monitor support seems broken");-            _glfw.x11.randr.monitorBroken = GL_TRUE;++            _glfw.x11.randr.monitorBroken = GLFW_TRUE;+            free(monitors);+            monitors = NULL;         }     } @@ -305,7 +306,7 @@     return monitors; } -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)+GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) {     return first->x11.crtc == second->x11.crtc; }@@ -330,13 +331,11 @@     } } -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) {     GLFWvidmode* result; -    *found = 0;--    // Build array of available resolutions+    *count = 0;      if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)     {@@ -359,20 +358,18 @@              const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); -            for (j = 0;  j < *found;  j++)+            for (j = 0;  j < *count;  j++)             {                 if (_glfwCompareVideoModes(result + j, &mode) == 0)                     break;             } -            if (j < *found)-            {-                // This is a duplicate, so skip it+            // Skip duplicate modes+            if (j < *count)                 continue;-            } -            result[*found] = mode;-            (*found)++;+            (*count)++;+            result[*count - 1] = mode;         }          XRRFreeOutputInfo(oi);@@ -381,7 +378,7 @@     }     else     {-        *found = 1;+        *count = 1;         result = calloc(1, sizeof(GLFWvidmode));         _glfwPlatformGetVideoMode(monitor, result);     }
glfw/src/x11_platform.h view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 X11 - www.glfw.org+// GLFW 3.2 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -25,12 +25,13 @@ // //======================================================================== -#ifndef _x11_platform_h_-#define _x11_platform_h_+#ifndef _glfw3_x11_platform_h_+#define _glfw3_x11_platform_h_  #include <unistd.h> #include <signal.h> #include <stdint.h>+#include <dlfcn.h>  #include <X11/Xlib.h> #include <X11/keysym.h>@@ -46,34 +47,56 @@ // The Xinerama extension provides legacy monitor indices #include <X11/extensions/Xinerama.h> -#if defined(_GLFW_HAS_XINPUT)- // The XInput2 extension provides improved input events- #include <X11/extensions/XInput2.h>-#endif- #if defined(_GLFW_HAS_XF86VM)  // The Xf86VidMode extension provides fallback gamma control  #include <X11/extensions/xf86vmode.h> #endif -#include "posix_tls.h"+typedef XID xcb_window_t;+typedef XID xcb_visualid_t;+typedef struct xcb_connection_t xcb_connection_t;+typedef xcb_connection_t* (* XGETXCBCONNECTION_T)(Display*); -#if defined(_GLFW_GLX)- #define _GLFW_X11_CONTEXT_VISUAL window->glx.visual- #include "glx_context.h"-#elif defined(_GLFW_EGL)- #define _GLFW_X11_CONTEXT_VISUAL window->egl.visual- #define _GLFW_EGL_NATIVE_WINDOW  window->x11.handle- #define _GLFW_EGL_NATIVE_DISPLAY _glfw.x11.display- #include "egl_context.h"-#else- #error "No supported context creation API selected"-#endif+typedef VkFlags VkXlibSurfaceCreateFlagsKHR;+typedef VkFlags VkXcbSurfaceCreateFlagsKHR; +typedef struct VkXlibSurfaceCreateInfoKHR+{+    VkStructureType             sType;+    const void*                 pNext;+    VkXlibSurfaceCreateFlagsKHR flags;+    Display*                    dpy;+    Window                      window;+} VkXlibSurfaceCreateInfoKHR;++typedef struct VkXcbSurfaceCreateInfoKHR+{+    VkStructureType             sType;+    const void*                 pNext;+    VkXcbSurfaceCreateFlagsKHR  flags;+    xcb_connection_t*           connection;+    xcb_window_t                window;+} VkXcbSurfaceCreateInfoKHR;++typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID);+typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);++#include "posix_tls.h" #include "posix_time.h" #include "linux_joystick.h" #include "xkb_unicode.h"+#include "glx_context.h"+#include "egl_context.h" +#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)+#define _glfw_dlclose(handle) dlclose(handle)+#define _glfw_dlsym(handle, name) dlsym(handle, name)++#define _GLFW_EGL_NATIVE_WINDOW  ((EGLNativeWindowType) window->x11.handle)+#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)+ #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowX11  x11 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorX11 x11@@ -88,19 +111,22 @@     Window          handle;     XIC             ic; -    GLboolean       overrideRedirect;+    GLFWbool        overrideRedirect;      // Cached position and size used to filter out duplicate events     int             width, height;     int             xpos, ypos;      // The last received cursor position, regardless of source-    double          cursorPosX, cursorPosY;+    int             lastCursorPosX, lastCursorPosY;     // The last position the cursor was warped to by GLFW-    int             warpPosX, warpPosY;+    int             warpCursorPosX, warpCursorPosY; -} _GLFWwindowX11;+    // The information from the last KeyPress event+    unsigned int    lastKeyCode;+    Time            lastKeyTime; +} _GLFWwindowX11;  // X11-specific global data //@@ -116,14 +142,20 @@     XContext        context;     // XIM input method     XIM             im;-    // True if window manager supports EWMH-    GLboolean       hasEWMH;     // Most recent error code received by X error handler     int             errorCode;     // Clipboard string (while the selection is owned)     char*           clipboardString;+    // Key name string+    char            keyName[64];     // X11 keycode to GLFW key LUT     short int       publicKeys[256];+    // GLFW key to X11 keycode LUT+    short int       nativeKeys[GLFW_KEY_LAST + 1];+    // Where to place the cursor when re-enabled+    double          restoreCursorPosX, restoreCursorPosY;+    // The window whose disabled cursor mode is active+    _GLFWwindow*    disabledCursorWindow;      // Window manager atoms     Atom            WM_PROTOCOLS;@@ -131,11 +163,16 @@     Atom            WM_DELETE_WINDOW;     Atom            NET_WM_NAME;     Atom            NET_WM_ICON_NAME;+    Atom            NET_WM_ICON;     Atom            NET_WM_PID;     Atom            NET_WM_PING;+    Atom            NET_WM_WINDOW_TYPE;+    Atom            NET_WM_WINDOW_TYPE_NORMAL;     Atom            NET_WM_STATE;     Atom            NET_WM_STATE_ABOVE;     Atom            NET_WM_STATE_FULLSCREEN;+    Atom            NET_WM_STATE_MAXIMIZED_VERT;+    Atom            NET_WM_STATE_MAXIMIZED_HORZ;     Atom            NET_WM_BYPASS_COMPOSITOR;     Atom            NET_WM_FULLSCREEN_MONITORS;     Atom            NET_ACTIVE_WINDOW;@@ -167,23 +204,23 @@     Atom            GLFW_SELECTION;      struct {-        GLboolean   available;+        GLFWbool    available;         int         eventBase;         int         errorBase;-        int         versionMajor;-        int         versionMinor;-        GLboolean   gammaBroken;-        GLboolean   monitorBroken;+        int         major;+        int         minor;+        GLFWbool    gammaBroken;+        GLFWbool    monitorBroken;     } randr;      struct {-        GLboolean   available;-        GLboolean   detectable;+        GLFWbool    available;+        GLFWbool    detectable;         int         majorOpcode;         int         eventBase;         int         errorBase;-        int         versionMajor;-        int         versionMinor;+        int         major;+        int         minor;     } xkb;      struct {@@ -199,25 +236,19 @@     } xdnd;      struct {-        GLboolean   available;-        int         versionMajor;-        int         versionMinor;+        GLFWbool    available;+        int         major;+        int         minor;     } xinerama; -#if defined(_GLFW_HAS_XINPUT)     struct {-        GLboolean   available;-        int         majorOpcode;-        int         eventBase;-        int         errorBase;-        int         versionMajor;-        int         versionMinor;-    } xi;-#endif /*_GLFW_HAS_XINPUT*/+        void*       handle;+        XGETXCBCONNECTION_T XGetXCBConnection;+    } x11xcb;  #if defined(_GLFW_HAS_XF86VM)     struct {-        GLboolean   available;+        GLFWbool    available;         int         eventBase;         int         errorBase;     } vidmode;@@ -225,7 +256,6 @@  } _GLFWlibraryX11; - // X11-specific per-monitor data // typedef struct _GLFWmonitorX11@@ -240,7 +270,6 @@  } _GLFWmonitorX11; - // X11-specific per-cursor data // typedef struct _GLFWcursorX11@@ -250,18 +279,18 @@ } _GLFWcursorX11;  -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired);-void _glfwRestoreVideoMode(_GLFWmonitor* monitor);+GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);+void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor); -Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);+Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot); -unsigned long _glfwGetWindowProperty(Window window,-                                     Atom property,-                                     Atom type,-                                     unsigned char** value);+unsigned long _glfwGetWindowPropertyX11(Window window,+                                        Atom property,+                                        Atom type,+                                        unsigned char** value); -void _glfwGrabXErrorHandler(void);-void _glfwReleaseXErrorHandler(void);-void _glfwInputXError(int error, const char* message);+void _glfwGrabErrorHandlerX11(void);+void _glfwReleaseErrorHandlerX11(void);+void _glfwInputErrorX11(int error, const char* message); -#endif // _x11_platform_h_+#endif // _glfw3_x11_platform_h_
glfw/src/x11_window.c view
@@ -1,1924 +1,2458 @@ //========================================================================-// GLFW 3.1 X11 - www.glfw.org-//-------------------------------------------------------------------------// Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-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 <X11/cursorfont.h>-#include <X11/Xmd.h>--#include <sys/select.h>--#include <string.h>-#include <stdio.h>-#include <stdlib.h>-#include <limits.h>--// Action for EWMH client messages-#define _NET_WM_STATE_REMOVE        0-#define _NET_WM_STATE_ADD           1-#define _NET_WM_STATE_TOGGLE        2--// Additional mouse button names for XButtonEvent-#define Button6            6-#define Button7            7--typedef struct-{-    unsigned long flags;-    unsigned long functions;-    unsigned long decorations;-    long input_mode;-    unsigned long status;-} MotifWmHints;--#define MWM_HINTS_DECORATIONS (1L << 1)---// Returns whether the window is iconified-//-static int getWindowState(_GLFWwindow* window)-{-    int result = WithdrawnState;-    struct {-        CARD32 state;-        Window icon;-    } *state = NULL;--    if (_glfwGetWindowProperty(window->x11.handle,-                               _glfw.x11.WM_STATE,-                               _glfw.x11.WM_STATE,-                               (unsigned char**) &state) >= 2)-    {-        result = state->state;-    }--    XFree(state);-    return result;-}--// Returns whether the event is a selection event-//-static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)-{-    _GLFWwindow* window = (_GLFWwindow*) pointer;-    return event->type == PropertyNotify &&-           event->xproperty.state == PropertyNewValue &&-           event->xproperty.window == window->x11.handle &&-           event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS;-}--// Translates a GLFW standard cursor to a font cursor shape-//-static int translateCursorShape(int shape)-{-    switch (shape)-    {-        case GLFW_ARROW_CURSOR:-            return XC_arrow;-        case GLFW_IBEAM_CURSOR:-            return XC_xterm;-        case GLFW_CROSSHAIR_CURSOR:-            return XC_crosshair;-        case GLFW_HAND_CURSOR:-            return XC_hand1;-        case GLFW_HRESIZE_CURSOR:-            return XC_sb_h_double_arrow;-        case GLFW_VRESIZE_CURSOR:-            return XC_sb_v_double_arrow;-    }--    return 0;-}--// Translates an X event modifier state mask-//-static int translateState(int state)-{-    int mods = 0;--    if (state & ShiftMask)-        mods |= GLFW_MOD_SHIFT;-    if (state & ControlMask)-        mods |= GLFW_MOD_CONTROL;-    if (state & Mod1Mask)-        mods |= GLFW_MOD_ALT;-    if (state & Mod4Mask)-        mods |= GLFW_MOD_SUPER;--    return mods;-}--// Translates an X Window key to internal coding-//-static int translateKey(int scancode)-{-    // Use the pre-filled LUT (see createKeyTables() in x11_init.c)-    if (scancode < 0 || scancode > 255)-        return GLFW_KEY_UNKNOWN;--    return _glfw.x11.publicKeys[scancode];-}--// Return the GLFW window corresponding to the specified X11 window-//-static _GLFWwindow* findWindowByHandle(Window handle)-{-    _GLFWwindow* window;--    if (XFindContext(_glfw.x11.display,-                     handle,-                     _glfw.x11.context,-                     (XPointer*) &window) != 0)-    {-        return NULL;-    }--    return window;-}--// Adds or removes an EWMH state to a window-//-static void changeWindowState(_GLFWwindow* window, Atom state, int action)-{-    XEvent event;-    memset(&event, 0, sizeof(event));--    event.type = ClientMessage;-    event.xclient.window = window->x11.handle;-    event.xclient.format = 32; // Data is 32-bit longs-    event.xclient.message_type = _glfw.x11.NET_WM_STATE;-    event.xclient.data.l[0] = action;-    event.xclient.data.l[1] = state;-    event.xclient.data.l[2] = 0; // No secondary property-    event.xclient.data.l[3] = 1; // Sender is a normal application--    XSendEvent(_glfw.x11.display,-               _glfw.x11.root,-               False,-               SubstructureNotifyMask | SubstructureRedirectMask,-               &event);-}--// Splits and translates a text/uri-list into separate file paths-// NOTE: This function destroys the provided string-//-static char** parseUriList(char* text, int* count)-{-    const char* prefix = "file://";-    char** paths = NULL;-    char* line;--    *count = 0;--    while ((line = strtok(text, "\r\n")))-    {-        text = NULL;--        if (line[0] == '#')-            continue;--        if (strncmp(line, prefix, strlen(prefix)) == 0)-            line += strlen(prefix);--        (*count)++;--        char* path = calloc(strlen(line) + 1, 1);-        paths = realloc(paths, *count * sizeof(char*));-        paths[*count - 1] = path;--        while (*line)-        {-            if (line[0] == '%' && line[1] && line[2])-            {-                const char digits[3] = { line[1], line[2], '\0' };-                *path = strtol(digits, NULL, 16);-                line += 2;-            }-            else-                *path = *line;--            path++;-            line++;-        }-    }--    return paths;-}--// Create the X11 window (and its colormap)-//-static GLboolean createWindow(_GLFWwindow* window,-                              const _GLFWwndconfig* wndconfig)-{-    unsigned long wamask;-    XSetWindowAttributes wa;-    XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL;--    // 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(_glfw.x11.display,-                                           _glfw.x11.root,-                                           visual->visual,-                                           AllocNone);--    // Create the actual window-    {-        wamask = CWBorderPixel | CWColormap | CWEventMask;--        wa.colormap = window->x11.colormap;-        wa.border_pixel = 0;-        wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |-                        PointerMotionMask | ButtonPressMask | ButtonReleaseMask |-                        ExposureMask | FocusChangeMask | VisibilityChangeMask |-                        EnterWindowMask | LeaveWindowMask | PropertyChangeMask;--        _glfwGrabXErrorHandler();--        window->x11.handle = XCreateWindow(_glfw.x11.display,-                                           _glfw.x11.root,-                                           0, 0,-                                           wndconfig->width, wndconfig->height,-                                           0,              // Border width-                                           visual->depth,  // Color depth-                                           InputOutput,-                                           visual->visual,-                                           wamask,-                                           &wa);--        _glfwReleaseXErrorHandler();--        if (!window->x11.handle)-        {-            _glfwInputXError(GLFW_PLATFORM_ERROR,-                             "X11: Failed to create window");-            return GL_FALSE;-        }--        if (!wndconfig->decorated)-        {-            MotifWmHints hints;-            hints.flags = MWM_HINTS_DECORATIONS;-            hints.decorations = 0;--            XChangeProperty(_glfw.x11.display, window->x11.handle,-                            _glfw.x11.MOTIF_WM_HINTS,-                            _glfw.x11.MOTIF_WM_HINTS, 32,-                            PropModeReplace,-                            (unsigned char*) &hints,-                            sizeof(MotifWmHints) / sizeof(long));-        }--        XSaveContext(_glfw.x11.display,-                     window->x11.handle,-                     _glfw.x11.context,-                     (XPointer) window);-    }--    if (window->monitor && !_glfw.x11.hasEWMH)-    {-        // This is the butcher's way of removing window decorations-        // Setting the override-redirect attribute on a window makes the window-        // manager ignore the window completely (ICCCM, section 4)-        // The good thing is that this makes undecorated full screen 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 those-        // are tasks usually performed by the window manager--        XSetWindowAttributes attributes;-        attributes.override_redirect = True;-        XChangeWindowAttributes(_glfw.x11.display,-                                window->x11.handle,-                                CWOverrideRedirect,-                                &attributes);--        window->x11.overrideRedirect = GL_TRUE;-    }--    // Declare the WM protocols supported by GLFW-    {-        int count = 0;-        Atom protocols[2];--        // The WM_DELETE_WINDOW ICCCM protocol-        // Basic window close notification protocol-        if (_glfw.x11.WM_DELETE_WINDOW)-            protocols[count++] = _glfw.x11.WM_DELETE_WINDOW;--        // The _NET_WM_PING EWMH protocol-        // 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 (_glfw.x11.NET_WM_PING)-            protocols[count++] = _glfw.x11.NET_WM_PING;--        if (count > 0)-        {-            XSetWMProtocols(_glfw.x11.display, window->x11.handle,-                            protocols, count);-        }-    }--    if (_glfw.x11.NET_WM_PID)-    {-        const pid_t pid = getpid();--        XChangeProperty(_glfw.x11.display,  window->x11.handle,-                        _glfw.x11.NET_WM_PID, XA_CARDINAL, 32,-                        PropModeReplace,-                        (unsigned char*) &pid, 1);-    }--    // Set ICCCM WM_HINTS property-    {-        XWMHints* hints = XAllocWMHints();-        if (!hints)-        {-            _glfwInputError(GLFW_OUT_OF_MEMORY,-                            "X11: Failed to allocate WM hints");-            return GL_FALSE;-        }--        hints->flags = StateHint;-        hints->initial_state = NormalState;--        XSetWMHints(_glfw.x11.display, window->x11.handle, hints);-        XFree(hints);-    }--    // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set)-    {-        XSizeHints* hints = XAllocSizeHints();-        hints->flags = 0;--        if (wndconfig->monitor)-        {-            hints->flags |= PPosition;-            _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y);-        }-        else-        {-            // HACK: Explicitly setting PPosition to any value causes some WMs,-            //       notably Compiz and Metacity, to honor the position of-            //       unmapped windows set by XMoveWindow-            hints->flags |= PPosition;-            hints->x = hints->y = 0;-        }--        if (!wndconfig->resizable)-        {-            hints->flags |= (PMinSize | PMaxSize);-            hints->min_width  = hints->max_width  = wndconfig->width;-            hints->min_height = hints->max_height = wndconfig->height;-        }--        XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);-        XFree(hints);-    }--    // Set ICCCM WM_CLASS property-    // HACK: Until a mechanism for specifying the application name is added, the-    //       initial window title is used as the window class name-    if (strlen(wndconfig->title))-    {-        XClassHint* hint = XAllocClassHint();-        hint->res_name = (char*) wndconfig->title;-        hint->res_class = (char*) wndconfig->title;--        XSetClassHint(_glfw.x11.display, window->x11.handle, hint);-        XFree(hint);-    }--#if defined(_GLFW_HAS_XINPUT)-    if (_glfw.x11.xi.available)-    {-        // Select for XInput2 events--        XIEventMask eventmask;-        unsigned char mask[] = { 0 };--        eventmask.deviceid = 2;-        eventmask.mask_len = sizeof(mask);-        eventmask.mask = mask;-        XISetMask(mask, XI_Motion);--        XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1);-    }-#endif /*_GLFW_HAS_XINPUT*/--    if (_glfw.x11.XdndAware)-    {-        // Announce support for Xdnd (drag and drop)-        const Atom version = 5;-        XChangeProperty(_glfw.x11.display, window->x11.handle,-                        _glfw.x11.XdndAware, XA_ATOM, 32,-                        PropModeReplace, (unsigned char*) &version, 1);-    }--    if (_glfw.x11.NET_REQUEST_FRAME_EXTENTS)-    {-        // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to-        // function before the window is mapped--        XEvent event;-        memset(&event, 0, sizeof(event));--        event.type = ClientMessage;-        event.xclient.window = window->x11.handle;-        event.xclient.format = 32; // Data is 32-bit longs-        event.xclient.message_type = _glfw.x11.NET_REQUEST_FRAME_EXTENTS;--        XSendEvent(_glfw.x11.display,-                   _glfw.x11.root,-                   False,-                   SubstructureNotifyMask | SubstructureRedirectMask,-                   &event);-        XIfEvent(_glfw.x11.display, &event, isFrameExtentsEvent, (XPointer) window);-    }--    if (wndconfig->floating && !wndconfig->monitor)-    {-        if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE)-        {-            changeWindowState(window,-                              _glfw.x11.NET_WM_STATE_ABOVE,-                              _NET_WM_STATE_ADD);-        }-    }--    _glfwPlatformSetWindowTitle(window, wndconfig->title);--    XRRSelectInput(_glfw.x11.display, window->x11.handle,-                   RRScreenChangeNotifyMask);--    if (_glfw.x11.im)-    {-        window->x11.ic = XCreateIC(_glfw.x11.im,-                                   XNInputStyle,-                                   XIMPreeditNothing | XIMStatusNothing,-                                   XNClientWindow,-                                   window->x11.handle,-                                   XNFocusWindow,-                                   window->x11.handle,-                                   NULL);-    }--    _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);-    _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);--    return GL_TRUE;-}--// Hide the mouse cursor-//-static void hideCursor(_GLFWwindow* window)-{-    XUngrabPointer(_glfw.x11.display, CurrentTime);-    XDefineCursor(_glfw.x11.display, window->x11.handle, _glfw.x11.cursor);-}--// Disable the mouse cursor-//-static void disableCursor(_GLFWwindow* window)-{-    XGrabPointer(_glfw.x11.display, window->x11.handle, True,-                 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,-                 GrabModeAsync, GrabModeAsync,-                 window->x11.handle, _glfw.x11.cursor, CurrentTime);-}--// Restores the mouse cursor-//-static void restoreCursor(_GLFWwindow* window)-{-    XUngrabPointer(_glfw.x11.display, CurrentTime);--    if (window->cursor)-    {-        XDefineCursor(_glfw.x11.display, window->x11.handle,-                      window->cursor->x11.handle);-    }-    else-        XUndefineCursor(_glfw.x11.display, window->x11.handle);-}--// Returns whether the event is a selection event-//-static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)-{-    return event->type == SelectionRequest ||-           event->type == SelectionNotify ||-           event->type == SelectionClear;-}--// Set the specified property to the selection converted to the requested target-//-static Atom writeTargetToProperty(const XSelectionRequestEvent* request)-{-    int i;-    const Atom formats[] = { _glfw.x11.UTF8_STRING,-                             _glfw.x11.COMPOUND_STRING,-                             XA_STRING };-    const int formatCount = sizeof(formats) / sizeof(formats[0]);--    if (request->property == None)-    {-        // The requester is a legacy client (ICCCM section 2.2)-        // We don't support legacy clients, so fail here-        return None;-    }--    if (request->target == _glfw.x11.TARGETS)-    {-        // The list of supported targets was requested--        const Atom targets[] = { _glfw.x11.TARGETS,-                                 _glfw.x11.MULTIPLE,-                                 _glfw.x11.UTF8_STRING,-                                 _glfw.x11.COMPOUND_STRING,-                                 XA_STRING };--        XChangeProperty(_glfw.x11.display,-                        request->requestor,-                        request->property,-                        XA_ATOM,-                        32,-                        PropModeReplace,-                        (unsigned char*) targets,-                        sizeof(targets) / sizeof(targets[0]));--        return request->property;-    }--    if (request->target == _glfw.x11.MULTIPLE)-    {-        // Multiple conversions were requested--        Atom* targets;-        unsigned long i, count;--        count = _glfwGetWindowProperty(request->requestor,-                                       request->property,-                                       _glfw.x11.ATOM_PAIR,-                                       (unsigned char**) &targets);--        for (i = 0;  i < count;  i += 2)-        {-            int j;--            for (j = 0;  j < formatCount;  j++)-            {-                if (targets[i] == formats[j])-                    break;-            }--            if (j < formatCount)-            {-                XChangeProperty(_glfw.x11.display,-                                request->requestor,-                                targets[i + 1],-                                targets[i],-                                8,-                                PropModeReplace,-                                (unsigned char*) _glfw.x11.clipboardString,-                                strlen(_glfw.x11.clipboardString));-            }-            else-                targets[i + 1] = None;-        }--        XChangeProperty(_glfw.x11.display,-                        request->requestor,-                        request->property,-                        _glfw.x11.ATOM_PAIR,-                        32,-                        PropModeReplace,-                        (unsigned char*) targets,-                        count);--        XFree(targets);--        return request->property;-    }--    if (request->target == _glfw.x11.SAVE_TARGETS)-    {-        // The request is a check whether we support SAVE_TARGETS-        // It should be handled as a no-op side effect target--        XChangeProperty(_glfw.x11.display,-                        request->requestor,-                        request->property,-                        _glfw.x11.NULL_,-                        32,-                        PropModeReplace,-                        NULL,-                        0);--        return request->property;-    }--    // Conversion to a data target was requested--    for (i = 0;  i < formatCount;  i++)-    {-        if (request->target == formats[i])-        {-            // The requested target is one we support--            XChangeProperty(_glfw.x11.display,-                            request->requestor,-                            request->property,-                            request->target,-                            8,-                            PropModeReplace,-                            (unsigned char*) _glfw.x11.clipboardString,-                            strlen(_glfw.x11.clipboardString));--            return request->property;-        }-    }--    // The requested target is not supported--    return None;-}--static void handleSelectionClear(XEvent* event)-{-    free(_glfw.x11.clipboardString);-    _glfw.x11.clipboardString = NULL;-}--static void handleSelectionRequest(XEvent* event)-{-    const XSelectionRequestEvent* request = &event->xselectionrequest;--    XEvent response;-    memset(&response, 0, sizeof(response));--    response.xselection.property = writeTargetToProperty(request);-    response.xselection.type = SelectionNotify;-    response.xselection.display = request->display;-    response.xselection.requestor = request->requestor;-    response.xselection.selection = request->selection;-    response.xselection.target = request->target;-    response.xselection.time = request->time;--    XSendEvent(_glfw.x11.display, request->requestor, False, 0, &response);-}--static void pushSelectionToManager(_GLFWwindow* window)-{-    XConvertSelection(_glfw.x11.display,-                      _glfw.x11.CLIPBOARD_MANAGER,-                      _glfw.x11.SAVE_TARGETS,-                      None,-                      window->x11.handle,-                      CurrentTime);--    for (;;)-    {-        XEvent event;--        if (!XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL))-            continue;--        switch (event.type)-        {-            case SelectionRequest:-                handleSelectionRequest(&event);-                break;--            case SelectionClear:-                handleSelectionClear(&event);-                break;--            case SelectionNotify:-            {-                if (event.xselection.target == _glfw.x11.SAVE_TARGETS)-                {-                    // This means one of two things; either the selection was-                    // not owned, which means there is no clipboard manager, or-                    // the transfer to the clipboard manager has completed-                    // In either case, it means we are done here-                    return;-                }--                break;-            }-        }-    }-}--// Enter full screen mode-//-static void enterFullscreenMode(_GLFWwindow* window)-{-    if (_glfw.x11.saver.count == 0)-    {-        // Remember old screen saver settings-        XGetScreenSaver(_glfw.x11.display,-                        &_glfw.x11.saver.timeout,-                        &_glfw.x11.saver.interval,-                        &_glfw.x11.saver.blanking,-                        &_glfw.x11.saver.exposure);--        // Disable screen saver-        XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking,-                        DefaultExposures);-    }--    _glfw.x11.saver.count++;--    _glfwSetVideoMode(window->monitor, &window->videoMode);--    if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR)-    {-        const unsigned long value = 1;--        XChangeProperty(_glfw.x11.display,  window->x11.handle,-                        _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,-                        PropModeReplace, (unsigned char*) &value, 1);-    }--    if (_glfw.x11.xinerama.available && _glfw.x11.NET_WM_FULLSCREEN_MONITORS)-    {-        XEvent event;-        memset(&event, 0, sizeof(event));--        event.type = ClientMessage;-        event.xclient.window = window->x11.handle;-        event.xclient.format = 32; // Data is 32-bit longs-        event.xclient.message_type = _glfw.x11.NET_WM_FULLSCREEN_MONITORS;-        event.xclient.data.l[0] = window->monitor->x11.index;-        event.xclient.data.l[1] = window->monitor->x11.index;-        event.xclient.data.l[2] = window->monitor->x11.index;-        event.xclient.data.l[3] = window->monitor->x11.index;--        XSendEvent(_glfw.x11.display,-                   _glfw.x11.root,-                   False,-                   SubstructureNotifyMask | SubstructureRedirectMask,-                   &event);-    }--    if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)-    {-        int x, y;-        _glfwPlatformGetMonitorPos(window->monitor, &x, &y);-        _glfwPlatformSetWindowPos(window, x, y);--        if (_glfw.x11.NET_ACTIVE_WINDOW)-        {-            // Ask the window manager to raise and focus the GLFW window-            // Only focused windows with the _NET_WM_STATE_FULLSCREEN state end-            // up on top of all other windows ("Stacking order" in EWMH spec)--            XEvent event;-            memset(&event, 0, sizeof(event));--            event.type = ClientMessage;-            event.xclient.window = window->x11.handle;-            event.xclient.format = 32; // Data is 32-bit longs-            event.xclient.message_type = _glfw.x11.NET_ACTIVE_WINDOW;-            event.xclient.data.l[0] = 1; // Sender is a normal application-            event.xclient.data.l[1] = 0; // We don't really know the timestamp--            XSendEvent(_glfw.x11.display,-                       _glfw.x11.root,-                       False,-                       SubstructureNotifyMask | SubstructureRedirectMask,-                       &event);-        }--        // Ask the window manager to make the GLFW window a full screen window-        // Full screen windows are undecorated and, when focused, are kept-        // on top of all other windows--        changeWindowState(window,-                          _glfw.x11.NET_WM_STATE_FULLSCREEN,-                          _NET_WM_STATE_ADD);-    }-    else if (window->x11.overrideRedirect)-    {-        // In override-redirect mode we have divorced ourselves from the-        // window manager, so we need to do everything manually-        int xpos, ypos;-        GLFWvidmode mode;--        _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);-        _glfwPlatformGetVideoMode(window->monitor, &mode);--        XRaiseWindow(_glfw.x11.display, window->x11.handle);-        XSetInputFocus(_glfw.x11.display, window->x11.handle,-                       RevertToParent, CurrentTime);-        XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos);-        XResizeWindow(_glfw.x11.display, window->x11.handle,-                      mode.width, mode.height);-    }-}--// Leave full screen mode-//-static void leaveFullscreenMode(_GLFWwindow* window)-{-    _glfwRestoreVideoMode(window->monitor);--    _glfw.x11.saver.count--;--    if (_glfw.x11.saver.count == 0)-    {-        // Restore old screen saver settings-        XSetScreenSaver(_glfw.x11.display,-                        _glfw.x11.saver.timeout,-                        _glfw.x11.saver.interval,-                        _glfw.x11.saver.blanking,-                        _glfw.x11.saver.exposure);-    }--    if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR)-    {-        const unsigned long value = 0;--        XChangeProperty(_glfw.x11.display,  window->x11.handle,-                        _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,-                        PropModeReplace, (unsigned char*) &value, 1);-    }--    if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)-    {-        // Ask the window manager to make the GLFW window a normal window-        // Normal windows usually have frames and other decorations--        changeWindowState(window,-                          _glfw.x11.NET_WM_STATE_FULLSCREEN,-                          _NET_WM_STATE_REMOVE);-    }-}--// Process the specified X event-//-static void processEvent(XEvent *event)-{-    _GLFWwindow* window = NULL;--    if (event->type != GenericEvent)-    {-        window = findWindowByHandle(event->xany.window);-        if (window == NULL)-        {-            // This is an event for a window that has already been destroyed-            return;-        }-    }--    switch (event->type)-    {-        case KeyPress:-        {-            const int key = translateKey(event->xkey.keycode);-            const int mods = translateState(event->xkey.state);-            const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));--            if (event->xkey.keycode)-                _glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods);--            if (window->x11.ic)-            {-                // Translate keys to characters with XIM input context--                int i;-                Status status;-                wchar_t buffer[16];--                if (XFilterEvent(event, None))-                {-                    // Discard intermediary (dead key) events for character input-                    break;-                }--                const int count = XwcLookupString(window->x11.ic,-                                                  &event->xkey,-                                                  buffer, sizeof(buffer),-                                                  NULL, &status);--                for (i = 0;  i < count;  i++)-                    _glfwInputChar(window, buffer[i], mods, plain);-            }-            else-            {-                // Translate keys to characters with fallback lookup table--                KeySym keysym;-                XLookupString(&event->xkey, NULL, 0, &keysym, NULL);--                const long character = _glfwKeySym2Unicode(keysym);-                if (character != -1)-                    _glfwInputChar(window, character, mods, plain);-            }--            break;-        }--        case KeyRelease:-        {-            const int key = translateKey(event->xkey.keycode);-            const int mods = translateState(event->xkey.state);--            if (!_glfw.x11.xkb.detectable)-            {-                // HACK: Key repeat events will arrive as KeyRelease/KeyPress-                //       pairs with similar or identical time stamps-                //       The key repeat logic in _glfwInputKey expects only key-                //       presses to repeat, so detect and discard release events-                if (XEventsQueued(_glfw.x11.display, QueuedAfterReading))-                {-                    XEvent nextEvent;-                    XPeekEvent(_glfw.x11.display, &nextEvent);--                    if (nextEvent.type == KeyPress &&-                        nextEvent.xkey.window == event->xkey.window &&-                        nextEvent.xkey.keycode == event->xkey.keycode)-                    {-                        // HACK: Repeat events sometimes leak through due to-                        //       some sort of time drift, so add an epsilon-                        //       Toshiyuki Takahashi can press a button 16 times-                        //       per second so it's fairly safe to assume that-                        //       no human is pressing the key 50 times per-                        //       second (value is ms)-                        if ((nextEvent.xkey.time - event->xkey.time) < 20)-                        {-                            // This is very likely a server-generated key repeat-                            // event, so ignore it-                            break;-                        }-                    }-                }-            }--            _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods);-            break;-        }--        case ButtonPress:-        {-            const int mods = translateState(event->xbutton.state);--            if (event->xbutton.button == Button1)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);-            else if (event->xbutton.button == Button2)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);-            else if (event->xbutton.button == Button3)-                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);--            // Modern X provides scroll events as mouse button presses-            else if (event->xbutton.button == Button4)-                _glfwInputScroll(window, 0.0, 1.0);-            else if (event->xbutton.button == Button5)-                _glfwInputScroll(window, 0.0, -1.0);-            else if (event->xbutton.button == Button6)-                _glfwInputScroll(window, 1.0, 0.0);-            else if (event->xbutton.button == Button7)-                _glfwInputScroll(window, -1.0, 0.0);--            else-            {-                // Additional buttons after 7 are treated as regular buttons-                // We subtract 4 to fill the gap left by scroll input above-                _glfwInputMouseClick(window,-                                     event->xbutton.button - 4,-                                     GLFW_PRESS,-                                     mods);-            }--            break;-        }--        case ButtonRelease:-        {-            const int mods = translateState(event->xbutton.state);--            if (event->xbutton.button == Button1)-            {-                _glfwInputMouseClick(window,-                                     GLFW_MOUSE_BUTTON_LEFT,-                                     GLFW_RELEASE,-                                     mods);-            }-            else if (event->xbutton.button == Button2)-            {-                _glfwInputMouseClick(window,-                                     GLFW_MOUSE_BUTTON_MIDDLE,-                                     GLFW_RELEASE,-                                     mods);-            }-            else if (event->xbutton.button == Button3)-            {-                _glfwInputMouseClick(window,-                                     GLFW_MOUSE_BUTTON_RIGHT,-                                     GLFW_RELEASE,-                                     mods);-            }-            else if (event->xbutton.button > Button7)-            {-                // Additional buttons after 7 are treated as regular buttons-                // We subtract 4 to fill the gap left by scroll input above-                _glfwInputMouseClick(window,-                                     event->xbutton.button - 4,-                                     GLFW_RELEASE,-                                     mods);-            }-            break;-        }--        case EnterNotify:-        {-            _glfwInputCursorEnter(window, GL_TRUE);-            break;-        }--        case LeaveNotify:-        {-            _glfwInputCursorEnter(window, GL_FALSE);-            break;-        }--        case MotionNotify:-        {-            const int x = event->xmotion.x;-            const int y = event->xmotion.y;--            if (x != window->x11.warpPosX || y != window->x11.warpPosY)-            {-                // The cursor was moved by something other than GLFW--                if (window->cursorMode == GLFW_CURSOR_DISABLED)-                {-                    if (_glfw.focusedWindow != window)-                        break;--                    _glfwInputCursorMotion(window,-                                           x - window->x11.cursorPosX,-                                           y - window->x11.cursorPosY);-                }-                else-                    _glfwInputCursorMotion(window, x, y);-            }--            window->x11.cursorPosX = x;-            window->x11.cursorPosY = y;-            break;-        }--        case ConfigureNotify:-        {-            if (event->xconfigure.width != window->x11.width ||-                event->xconfigure.height != window->x11.height)-            {-                _glfwInputFramebufferSize(window,-                                          event->xconfigure.width,-                                          event->xconfigure.height);--                _glfwInputWindowSize(window,-                                     event->xconfigure.width,-                                     event->xconfigure.height);--                window->x11.width = event->xconfigure.width;-                window->x11.height = event->xconfigure.height;-            }--            if (event->xconfigure.x != window->x11.xpos ||-                event->xconfigure.y != window->x11.ypos)-            {-                _glfwInputWindowPos(window,-                                    event->xconfigure.x,-                                    event->xconfigure.y);--                window->x11.xpos = event->xconfigure.x;-                window->x11.ypos = event->xconfigure.y;-            }--            break;-        }--        case ClientMessage:-        {-            // Custom client message, probably from the window manager--            if (event->xclient.message_type == None)-                break;--            if (event->xclient.message_type == _glfw.x11.WM_PROTOCOLS)-            {-                if (_glfw.x11.WM_DELETE_WINDOW &&-                    (Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW)-                {-                    // The window manager was asked to close the window, for example by-                    // the user pressing a 'close' window decoration button--                    _glfwInputWindowCloseRequest(window);-                }-                else if (_glfw.x11.NET_WM_PING &&-                        (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING)-                {-                    // The window manager is pinging the application to ensure it's-                    // still responding to events--                    event->xclient.window = _glfw.x11.root;-                    XSendEvent(_glfw.x11.display,-                            event->xclient.window,-                            False,-                            SubstructureNotifyMask | SubstructureRedirectMask,-                            event);-                }-            }-            else if (event->xclient.message_type == _glfw.x11.XdndEnter)-            {-                // A drag operation has entered the window-                // TODO: Check if UTF-8 string is supported by the source-            }-            else if (event->xclient.message_type == _glfw.x11.XdndDrop)-            {-                // The drag operation has finished dropping on-                // the window, ask to convert it to a UTF-8 string-                _glfw.x11.xdnd.source = event->xclient.data.l[0];-                XConvertSelection(_glfw.x11.display,-                                  _glfw.x11.XdndSelection,-                                  _glfw.x11.UTF8_STRING,-                                  _glfw.x11.XdndSelection,-                                  window->x11.handle, CurrentTime);-            }-            else if (event->xclient.message_type == _glfw.x11.XdndPosition)-            {-                // The drag operation has moved over the window-                const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF;-                const int absY = (event->xclient.data.l[2]) & 0xFFFF;-                int x, y;--                _glfwPlatformGetWindowPos(window, &x, &y);-                _glfwInputCursorMotion(window, absX - x, absY - y);--                // Reply that we are ready to copy the dragged data-                XEvent reply;-                memset(&reply, 0, sizeof(reply));--                reply.type = ClientMessage;-                reply.xclient.window = event->xclient.data.l[0];-                reply.xclient.message_type = _glfw.x11.XdndStatus;-                reply.xclient.format = 32;-                reply.xclient.data.l[0] = window->x11.handle;-                reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle-                reply.xclient.data.l[2] = 0; // Specify an empty rectangle-                reply.xclient.data.l[3] = 0;-                reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy;--                XSendEvent(_glfw.x11.display, event->xclient.data.l[0],-                           False, NoEventMask, &reply);-                XFlush(_glfw.x11.display);-            }--            break;-        }--        case SelectionNotify:-        {-            if (event->xselection.property)-            {-                // The converted data from the drag operation has arrived-                char* data;-                const int result =-                    _glfwGetWindowProperty(event->xselection.requestor,-                                           event->xselection.property,-                                           event->xselection.target,-                                           (unsigned char**) &data);--                if (result)-                {-                    int i, count;-                    char** paths = parseUriList(data, &count);--                    _glfwInputDrop(window, count, (const char**) paths);--                    for (i = 0;  i < count;  i++)-                        free(paths[i]);-                    free(paths);-                }--                XFree(data);--                XEvent reply;-                memset(&reply, 0, sizeof(reply));--                reply.type = ClientMessage;-                reply.xclient.window = _glfw.x11.xdnd.source;-                reply.xclient.message_type = _glfw.x11.XdndFinished;-                reply.xclient.format = 32;-                reply.xclient.data.l[0] = window->x11.handle;-                reply.xclient.data.l[1] = result;-                reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy;--                // Reply that all is well-                XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,-                           False, NoEventMask, &reply);-                XFlush(_glfw.x11.display);-            }--            break;-        }--        case FocusIn:-        {-            if (event->xfocus.mode == NotifyNormal)-            {-                _glfwInputWindowFocus(window, GL_TRUE);--                if (window->cursorMode == GLFW_CURSOR_DISABLED)-                    disableCursor(window);-            }--            break;-        }--        case FocusOut:-        {-            if (event->xfocus.mode == NotifyNormal)-            {-                _glfwInputWindowFocus(window, GL_FALSE);--                if (window->cursorMode == GLFW_CURSOR_DISABLED)-                    restoreCursor(window);-            }--            break;-        }--        case Expose:-        {-            _glfwInputWindowDamage(window);-            break;-        }--        case PropertyNotify:-        {-            if (event->xproperty.atom == _glfw.x11.WM_STATE &&-                event->xproperty.state == PropertyNewValue)-            {-                const int state = getWindowState(window);-                if (state == IconicState)-                    _glfwInputWindowIconify(window, GL_TRUE);-                else if (state == NormalState)-                    _glfwInputWindowIconify(window, GL_FALSE);-            }--            break;-        }--        case SelectionClear:-        {-            handleSelectionClear(event);-            break;-        }--        case SelectionRequest:-        {-            handleSelectionRequest(event);-            break;-        }--        case DestroyNotify:-            return;--#if defined(_GLFW_HAS_XINPUT)-        case GenericEvent:-        {-            if (event->xcookie.extension == _glfw.x11.xi.majorOpcode &&-                XGetEventData(_glfw.x11.display, &event->xcookie))-            {-                if (event->xcookie.evtype == XI_Motion)-                {-                    XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data;--                    window = findWindowByHandle(data->event);-                    if (window)-                    {-                        if (data->event_x != window->x11.warpPosX ||-                            data->event_y != window->x11.warpPosY)-                        {-                            // The cursor was moved by something other than GLFW--                            double x, y;--                            if (window->cursorMode == GLFW_CURSOR_DISABLED)-                            {-                                if (_glfw.focusedWindow != window)-                                    break;--                                x = data->event_x - window->x11.cursorPosX;-                                y = data->event_y - window->x11.cursorPosY;-                            }-                            else-                            {-                                x = data->event_x;-                                y = data->event_y;-                            }--                            _glfwInputCursorMotion(window, x, y);-                        }--                        window->x11.cursorPosX = data->event_x;-                        window->x11.cursorPosY = data->event_y;-                    }-                }-            }--            XFreeEventData(_glfw.x11.display, &event->xcookie);-            break;-        }-#endif /*_GLFW_HAS_XINPUT*/--        default:-        {-            switch (event->type - _glfw.x11.randr.eventBase)-            {-                case RRScreenChangeNotify:-                {-                    XRRUpdateConfiguration(event);-                    break;-                }-            }--            break;-        }-    }-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW internal API                      //////-//////////////////////////////////////////////////////////////////////////--// Retrieve a single window property of the specified type-// Inspired by fghGetWindowProperty from freeglut-//-unsigned long _glfwGetWindowProperty(Window window,-                                     Atom property,-                                     Atom type,-                                     unsigned char** value)-{-    Atom actualType;-    int actualFormat;-    unsigned long itemCount, bytesAfter;--    XGetWindowProperty(_glfw.x11.display,-                       window,-                       property,-                       0,-                       LONG_MAX,-                       False,-                       type,-                       &actualType,-                       &actualFormat,-                       &itemCount,-                       &bytesAfter,-                       value);--    if (type != AnyPropertyType && actualType != type)-        return 0;--    return itemCount;-}---//////////////////////////////////////////////////////////////////////////-//////                       GLFW platform API                      //////-//////////////////////////////////////////////////////////////////////////--int _glfwPlatformCreateWindow(_GLFWwindow* window,-                              const _GLFWwndconfig* wndconfig,-                              const _GLFWctxconfig* ctxconfig,-                              const _GLFWfbconfig* fbconfig)-{-    if (!_glfwCreateContext(window, ctxconfig, fbconfig))-        return GL_FALSE;--    if (!createWindow(window, wndconfig))-        return GL_FALSE;--    if (wndconfig->monitor)-    {-        _glfwPlatformShowWindow(window);-        enterFullscreenMode(window);-    }--    return GL_TRUE;-}--void _glfwPlatformDestroyWindow(_GLFWwindow* window)-{-    if (window->monitor)-        leaveFullscreenMode(window);--    if (window->x11.ic)-    {-        XDestroyIC(window->x11.ic);-        window->x11.ic = NULL;-    }--    _glfwDestroyContext(window);--    if (window->x11.handle)-    {-        if (window->x11.handle ==-            XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD))-        {-            pushSelectionToManager(window);-        }--        XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context);-        XUnmapWindow(_glfw.x11.display, window->x11.handle);-        XDestroyWindow(_glfw.x11.display, window->x11.handle);-        window->x11.handle = (Window) 0;-    }--    if (window->x11.colormap)-    {-        XFreeColormap(_glfw.x11.display, window->x11.colormap);-        window->x11.colormap = (Colormap) 0;-    }--    XFlush(_glfw.x11.display);-}--void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)-{-#if defined(X_HAVE_UTF8_STRING)-    Xutf8SetWMProperties(_glfw.x11.display,-                         window->x11.handle,-                         title, title,-                         NULL, 0,-                         NULL, NULL, NULL);-#else-    // This may be a slightly better fallback than using XStoreName and-    // XSetIconName, which always store their arguments using STRING-    XmbSetWMProperties(_glfw.x11.display,-                       window->x11.handle,-                       title, title,-                       NULL, 0,-                       NULL, NULL, NULL);-#endif--    if (_glfw.x11.NET_WM_NAME)-    {-        XChangeProperty(_glfw.x11.display,  window->x11.handle,-                        _glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8,-                        PropModeReplace,-                        (unsigned char*) title, strlen(title));-    }--    if (_glfw.x11.NET_WM_ICON_NAME)-    {-        XChangeProperty(_glfw.x11.display,  window->x11.handle,-                        _glfw.x11.NET_WM_ICON_NAME, _glfw.x11.UTF8_STRING, 8,-                        PropModeReplace,-                        (unsigned char*) title, strlen(title));-    }--    XFlush(_glfw.x11.display);-}--void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)-{-    Window child;-    int x, y;--    XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root,-                          0, 0, &x, &y, &child);--    if (child)-    {-        int left, top;-        XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child,-                              0, 0, &left, &top, &child);--        x -= left;-        y -= top;-    }--    if (xpos)-        *xpos = x;-    if (ypos)-        *ypos = y;-}--void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)-{-    XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos);-    XFlush(_glfw.x11.display);-}--void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)-{-    XWindowAttributes attribs;-    XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs);--    if (width)-        *width = attribs.width;-    if (height)-        *height = attribs.height;-}--void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)-{-    if (window->monitor)-    {-        _glfwSetVideoMode(window->monitor, &window->videoMode);--        if (window->x11.overrideRedirect)-        {-            GLFWvidmode mode;-            _glfwPlatformGetVideoMode(window->monitor, &mode);-            XResizeWindow(_glfw.x11.display, window->x11.handle,-                          mode.width, mode.height);-        }-    }-    else-    {-        if (!window->resizable)-        {-            // Update window size restrictions to match new window size--            XSizeHints* hints = XAllocSizeHints();--            hints->flags |= (PMinSize | PMaxSize);-            hints->min_width  = hints->max_width  = width;-            hints->min_height = hints->max_height = height;--            XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);-            XFree(hints);-        }--        XResizeWindow(_glfw.x11.display, window->x11.handle, width, height);-    }--    XFlush(_glfw.x11.display);-}--void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)-{-    _glfwPlatformGetWindowSize(window, width, height);-}--void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,-                                     int* left, int* top,-                                     int* right, int* bottom)-{-    long* extents = NULL;--    if (_glfw.x11.NET_FRAME_EXTENTS == None)-        return;--    if (_glfwGetWindowProperty(window->x11.handle,-                               _glfw.x11.NET_FRAME_EXTENTS,-                               XA_CARDINAL,-                               (unsigned char**) &extents) == 4)-    {-        if (left)-            *left = extents[0];-        if (top)-            *top = extents[2];-        if (right)-            *right = extents[1];-        if (bottom)-            *bottom = extents[3];-    }--    if (extents)-        XFree(extents);-}--void _glfwPlatformIconifyWindow(_GLFWwindow* window)-{-    if (window->x11.overrideRedirect)-    {-        // Override-redirect windows cannot be iconified or restored, as those-        // tasks are performed by the window manager-        _glfwInputError(GLFW_API_UNAVAILABLE,-                        "X11: Iconification of full screen windows requires "-                        "a WM that supports EWMH");-        return;-    }--    XIconifyWindow(_glfw.x11.display, window->x11.handle, _glfw.x11.screen);-    XFlush(_glfw.x11.display);-}--void _glfwPlatformRestoreWindow(_GLFWwindow* window)-{-    if (window->x11.overrideRedirect)-    {-        // Override-redirect windows cannot be iconified or restored, as those-        // tasks are performed by the window manager-        _glfwInputError(GLFW_API_UNAVAILABLE,-                        "X11: Iconification of full screen windows requires "-                        "a WM that supports EWMH");-        return;-    }--    XMapWindow(_glfw.x11.display, window->x11.handle);-    XFlush(_glfw.x11.display);-}--void _glfwPlatformShowWindow(_GLFWwindow* window)-{-    XMapRaised(_glfw.x11.display, window->x11.handle);-    XFlush(_glfw.x11.display);-}--void _glfwPlatformUnhideWindow(_GLFWwindow* window)-{-    XMapWindow(_glfw.x11.display, window->x11.handle);-    XFlush(_glfw.x11.display);-}--void _glfwPlatformHideWindow(_GLFWwindow* window)-{-    XUnmapWindow(_glfw.x11.display, window->x11.handle);-    XFlush(_glfw.x11.display);-}--int _glfwPlatformWindowFocused(_GLFWwindow* window)-{-    Window focused;-    int state;--    XGetInputFocus(_glfw.x11.display, &focused, &state);-    return window->x11.handle == focused;-}--int _glfwPlatformWindowIconified(_GLFWwindow* window)-{-    return getWindowState(window) == IconicState;-}--int _glfwPlatformWindowVisible(_GLFWwindow* window)-{-    XWindowAttributes wa;-    XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &wa);-    return wa.map_state == IsViewable;-}--void _glfwPlatformPollEvents(void)-{-    int count = XPending(_glfw.x11.display);-    while (count--)-    {-        XEvent event;-        XNextEvent(_glfw.x11.display, &event);-        processEvent(&event);-    }--    _GLFWwindow* window = _glfw.focusedWindow;-    if (window && window->cursorMode == GLFW_CURSOR_DISABLED)-    {-        int width, height;-        _glfwPlatformGetWindowSize(window, &width, &height);-        _glfwPlatformSetCursorPos(window, width / 2, height / 2);-    }-}--void _glfwPlatformWaitEvents(void)-{-    if (!XPending(_glfw.x11.display))-    {-        fd_set fds;-        const int fd = ConnectionNumber(_glfw.x11.display);--        FD_ZERO(&fds);-        FD_SET(fd, &fds);--        // select(1) is used instead of an X function like XNextEvent, as the-        // wait inside those are guarded by the mutex protecting the display-        // struct, locking out other threads from using X (including GLX)-        if (select(fd + 1, &fds, NULL, NULL, NULL) < 0)-            return;-    }--    _glfwPlatformPollEvents();-}--void _glfwPlatformPostEmptyEvent(void)-{-    XEvent event;-    _GLFWwindow* window = _glfw.windowListHead;--    memset(&event, 0, sizeof(event));-    event.type = ClientMessage;-    event.xclient.window = window->x11.handle;-    event.xclient.format = 32; // Data is 32-bit longs-    event.xclient.message_type = _glfw.x11.NULL_;--    XSendEvent(_glfw.x11.display, window->x11.handle, False, 0, &event);-    XFlush(_glfw.x11.display);-}--void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)-{-    Window root, child;-    int rootX, rootY, childX, childY;-    unsigned int mask;--    XQueryPointer(_glfw.x11.display, window->x11.handle,-                  &root, &child,-                  &rootX, &rootY, &childX, &childY,-                  &mask);--    if (xpos)-        *xpos = childX;-    if (ypos)-        *ypos = childY;-}--void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)-{-    // Store the new position so it can be recognized later-    window->x11.warpPosX = (int) x;-    window->x11.warpPosY = (int) y;--    XWarpPointer(_glfw.x11.display, None, window->x11.handle,-                 0,0,0,0, (int) x, (int) y);-}--void _glfwPlatformApplyCursorMode(_GLFWwindow* window)-{-    switch (window->cursorMode)-    {-        case GLFW_CURSOR_NORMAL:-            restoreCursor(window);-            break;-        case GLFW_CURSOR_HIDDEN:-            hideCursor(window);-            break;-        case GLFW_CURSOR_DISABLED:-            disableCursor(window);-            break;-    }-}--int _glfwPlatformCreateCursor(_GLFWcursor* cursor,-                              const GLFWimage* image,-                              int xhot, int yhot)-{-    cursor->x11.handle = _glfwCreateCursor(image, xhot, yhot);-    if (!cursor->x11.handle)-        return GL_FALSE;--    return GL_TRUE;-}--int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)-{-    const unsigned int native = translateCursorShape(shape);-    if (!native)-    {-        _glfwInputError(GLFW_INVALID_ENUM, "X11: Invalid standard cursor");-        return GL_FALSE;-    }--    cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);-    if (!cursor->x11.handle)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "X11: Failed to create standard cursor");-        return GL_FALSE;-    }--    return GL_TRUE;-}--void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)-{-    if (cursor->x11.handle)-        XFreeCursor(_glfw.x11.display, cursor->x11.handle);-}--void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)-{-    if (window->cursorMode == GLFW_CURSOR_NORMAL)-    {-        if (cursor)-            XDefineCursor(_glfw.x11.display, window->x11.handle, cursor->x11.handle);-        else-            XUndefineCursor(_glfw.x11.display, window->x11.handle);--        XFlush(_glfw.x11.display);-    }-}--void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)-{-    free(_glfw.x11.clipboardString);-    _glfw.x11.clipboardString = strdup(string);--    XSetSelectionOwner(_glfw.x11.display,-                       _glfw.x11.CLIPBOARD,-                       window->x11.handle, CurrentTime);--    if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=-        window->x11.handle)-    {-        _glfwInputError(GLFW_PLATFORM_ERROR,-                        "X11: Failed to become owner of the clipboard selection");-    }-}--const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)-{-    size_t i;-    const Atom formats[] = { _glfw.x11.UTF8_STRING,-                             _glfw.x11.COMPOUND_STRING,-                             XA_STRING };-    const size_t formatCount = sizeof(formats) / sizeof(formats[0]);--    if (findWindowByHandle(XGetSelectionOwner(_glfw.x11.display,-                                              _glfw.x11.CLIPBOARD)))-    {-        // Instead of doing a large number of X round-trips just to put this-        // string into a window property and then read it back, just return it-        return _glfw.x11.clipboardString;-    }--    free(_glfw.x11.clipboardString);-    _glfw.x11.clipboardString = NULL;--    for (i = 0;  i < formatCount;  i++)-    {-        char* data;-        XEvent event;--        XConvertSelection(_glfw.x11.display,-                          _glfw.x11.CLIPBOARD,-                          formats[i],-                          _glfw.x11.GLFW_SELECTION,-                          window->x11.handle, CurrentTime);--        // XCheckTypedEvent is used instead of XIfEvent in order not to lock-        // other threads out from the display during the entire wait period-        while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))-            ;--        if (event.xselection.property == None)-            continue;--        if (_glfwGetWindowProperty(event.xselection.requestor,-                                   event.xselection.property,-                                   event.xselection.target,-                                   (unsigned char**) &data))-        {-            _glfw.x11.clipboardString = strdup(data);-        }--        XFree(data);--        XDeleteProperty(_glfw.x11.display,-                        event.xselection.requestor,-                        event.xselection.property);--        if (_glfw.x11.clipboardString)-            break;-    }--    if (_glfw.x11.clipboardString == NULL)-    {-        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,-                        "X11: Failed to convert selection to string");-    }--    return _glfw.x11.clipboardString;+// GLFW 3.2 X11 - www.glfw.org+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Marcus Geelnard+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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 <X11/cursorfont.h>+#include <X11/Xmd.h>++#include <sys/select.h>++#include <string.h>+#include <stdio.h>+#include <stdlib.h>+#include <limits.h>+#include <errno.h>+#include <assert.h>++// Action for EWMH client messages+#define _NET_WM_STATE_REMOVE        0+#define _NET_WM_STATE_ADD           1+#define _NET_WM_STATE_TOGGLE        2++// Additional mouse button names for XButtonEvent+#define Button6            6+#define Button7            7+++// Wait for data to arrive using select+// This avoids blocking other threads via the per-display Xlib lock that also+// covers GLX functions+//+static GLFWbool waitForEvent(double* timeout)+{+    fd_set fds;+    const int fd = ConnectionNumber(_glfw.x11.display);+    int count = fd + 1;++    FD_ZERO(&fds);+    FD_SET(fd, &fds);+#if defined(__linux__)+    FD_SET(_glfw.linux_js.inotify, &fds);++    if (fd < _glfw.linux_js.inotify)+        count = _glfw.linux_js.inotify + 1;+#endif+    for (;;)+    {+        if (timeout)+        {+            const long seconds = (long) *timeout;+            const long microseconds = (long) ((*timeout - seconds) * 1e6);+            struct timeval tv = { seconds, microseconds };+            const uint64_t base = _glfwPlatformGetTimerValue();++            const int result = select(count, &fds, NULL, NULL, &tv);+            const int error = errno;++            *timeout -= (_glfwPlatformGetTimerValue() - base) /+                (double) _glfwPlatformGetTimerFrequency();++            if (result > 0)+                return GLFW_TRUE;+            if ((result == -1 && error == EINTR) || *timeout <= 0.0)+                return GLFW_FALSE;+        }+        else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR)+            return GLFW_TRUE;+    }+}++// Waits until a VisibilityNotify event arrives for the specified window or the+// timeout period elapses (ICCCM section 4.2.2)+//+static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)+{+    XEvent dummy;+    double timeout = 0.1;++    while (!XCheckTypedWindowEvent(_glfw.x11.display,+                                   window->x11.handle,+                                   VisibilityNotify,+                                   &dummy))+    {+        if (!waitForEvent(&timeout))+            return GLFW_FALSE;+    }++    return GLFW_TRUE;+}++// Returns whether the window is iconified+//+static int getWindowState(_GLFWwindow* window)+{+    int result = WithdrawnState;+    struct {+        CARD32 state;+        Window icon;+    } *state = NULL;++    if (_glfwGetWindowPropertyX11(window->x11.handle,+                                  _glfw.x11.WM_STATE,+                                  _glfw.x11.WM_STATE,+                                  (unsigned char**) &state) >= 2)+    {+        result = state->state;+    }++    XFree(state);+    return result;+}++// Returns whether the event is a selection event+//+static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)+{+    return event->type == SelectionRequest ||+           event->type == SelectionNotify ||+           event->type == SelectionClear;+}++// Returns whether it is a _NET_FRAME_EXTENTS event for the specified window+//+static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)+{+    _GLFWwindow* window = (_GLFWwindow*) pointer;+    return event->type == PropertyNotify &&+           event->xproperty.state == PropertyNewValue &&+           event->xproperty.window == window->x11.handle &&+           event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS;+}++// Translates a GLFW standard cursor to a font cursor shape+//+static int translateCursorShape(int shape)+{+    switch (shape)+    {+        case GLFW_ARROW_CURSOR:+            return XC_left_ptr;+        case GLFW_IBEAM_CURSOR:+            return XC_xterm;+        case GLFW_CROSSHAIR_CURSOR:+            return XC_crosshair;+        case GLFW_HAND_CURSOR:+            return XC_hand1;+        case GLFW_HRESIZE_CURSOR:+            return XC_sb_h_double_arrow;+        case GLFW_VRESIZE_CURSOR:+            return XC_sb_v_double_arrow;+    }++    return 0;+}++// Translates an X event modifier state mask+//+static int translateState(int state)+{+    int mods = 0;++    if (state & ShiftMask)+        mods |= GLFW_MOD_SHIFT;+    if (state & ControlMask)+        mods |= GLFW_MOD_CONTROL;+    if (state & Mod1Mask)+        mods |= GLFW_MOD_ALT;+    if (state & Mod4Mask)+        mods |= GLFW_MOD_SUPER;++    return mods;+}++// Translates an X11 key code to a GLFW key token+//+static int translateKey(int scancode)+{+    // Use the pre-filled LUT (see createKeyTables() in x11_init.c)+    if (scancode < 0 || scancode > 255)+        return GLFW_KEY_UNKNOWN;++    return _glfw.x11.publicKeys[scancode];+}++// Return the GLFW window corresponding to the specified X11 window+//+static _GLFWwindow* findWindowByHandle(Window handle)+{+    _GLFWwindow* window;++    if (XFindContext(_glfw.x11.display,+                     handle,+                     _glfw.x11.context,+                     (XPointer*) &window) != 0)+    {+        return NULL;+    }++    return window;+}++// Sends an EWMH or ICCCM event to the window manager+//+static void sendEventToWM(_GLFWwindow* window, Atom type,+                          long a, long b, long c, long d, long e)+{+    XEvent event;+    memset(&event, 0, sizeof(event));++    event.type = ClientMessage;+    event.xclient.window = window->x11.handle;+    event.xclient.format = 32; // Data is 32-bit longs+    event.xclient.message_type = type;+    event.xclient.data.l[0] = a;+    event.xclient.data.l[1] = b;+    event.xclient.data.l[2] = c;+    event.xclient.data.l[3] = d;+    event.xclient.data.l[4] = e;++    XSendEvent(_glfw.x11.display, _glfw.x11.root,+               False,+               SubstructureNotifyMask | SubstructureRedirectMask,+               &event);+}++// Updates the normal hints according to the window settings+//+static void updateNormalHints(_GLFWwindow* window, int width, int height)+{+    XSizeHints* hints = XAllocSizeHints();++    if (!window->monitor)+    {+        if (window->resizable)+        {+            if (window->minwidth != GLFW_DONT_CARE &&+                window->minheight != GLFW_DONT_CARE)+            {+                hints->flags |= PMinSize;+                hints->min_width = window->minwidth;+                hints->min_height = window->minheight;+            }++            if (window->maxwidth != GLFW_DONT_CARE &&+                window->maxheight != GLFW_DONT_CARE)+            {+                hints->flags |= PMaxSize;+                hints->max_width = window->maxwidth;+                hints->max_height = window->maxheight;+            }++            if (window->numer != GLFW_DONT_CARE &&+                window->denom != GLFW_DONT_CARE)+            {+                hints->flags |= PAspect;+                hints->min_aspect.x = hints->max_aspect.x = window->numer;+                hints->min_aspect.y = hints->max_aspect.y = window->denom;+            }+        }+        else+        {+            hints->flags |= (PMinSize | PMaxSize);+            hints->min_width  = hints->max_width  = width;+            hints->min_height = hints->max_height = height;+        }+    }++    hints->flags |= PWinGravity;+    hints->win_gravity = StaticGravity;++    XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);+    XFree(hints);+}++// Updates the full screen status of the window+//+static void updateWindowMode(_GLFWwindow* window)+{+    if (window->monitor)+    {+        if (_glfw.x11.xinerama.available &&+            _glfw.x11.NET_WM_FULLSCREEN_MONITORS)+        {+            sendEventToWM(window,+                          _glfw.x11.NET_WM_FULLSCREEN_MONITORS,+                          window->monitor->x11.index,+                          window->monitor->x11.index,+                          window->monitor->x11.index,+                          window->monitor->x11.index,+                          0);+        }++        if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)+        {+            sendEventToWM(window,+                          _glfw.x11.NET_WM_STATE,+                          _NET_WM_STATE_ADD,+                          _glfw.x11.NET_WM_STATE_FULLSCREEN,+                          0, 1, 0);+        }+        else+        {+            // This is the butcher's way of removing window decorations+            // Setting the override-redirect attribute on a window makes the+            // window manager ignore the window completely (ICCCM, section 4)+            // The good thing is that this makes undecorated full screen 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 those are tasks usually performed by the window manager++            XSetWindowAttributes attributes;+            attributes.override_redirect = True;+            XChangeWindowAttributes(_glfw.x11.display,+                                    window->x11.handle,+                                    CWOverrideRedirect,+                                    &attributes);++            window->x11.overrideRedirect = GLFW_TRUE;+        }++        // Enable compositor bypass+        {+            const unsigned long value = 1;++            XChangeProperty(_glfw.x11.display,  window->x11.handle,+                            _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,+                            PropModeReplace, (unsigned char*) &value, 1);+        }+    }+    else+    {+        if (_glfw.x11.xinerama.available &&+            _glfw.x11.NET_WM_FULLSCREEN_MONITORS)+        {+            XDeleteProperty(_glfw.x11.display, window->x11.handle,+                            _glfw.x11.NET_WM_FULLSCREEN_MONITORS);+        }++        if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)+        {+            sendEventToWM(window,+                          _glfw.x11.NET_WM_STATE,+                          _NET_WM_STATE_REMOVE,+                          _glfw.x11.NET_WM_STATE_FULLSCREEN,+                          0, 1, 0);+        }+        else+        {+            XSetWindowAttributes attributes;+            attributes.override_redirect = False;+            XChangeWindowAttributes(_glfw.x11.display,+                                    window->x11.handle,+                                    CWOverrideRedirect,+                                    &attributes);++            window->x11.overrideRedirect = GLFW_FALSE;+        }++        // Disable compositor bypass+        {+            XDeleteProperty(_glfw.x11.display, window->x11.handle,+                            _glfw.x11.NET_WM_BYPASS_COMPOSITOR);+        }+    }+}++// Splits and translates a text/uri-list into separate file paths+// NOTE: This function destroys the provided string+//+static char** parseUriList(char* text, int* count)+{+    const char* prefix = "file://";+    char** paths = NULL;+    char* line;++    *count = 0;++    while ((line = strtok(text, "\r\n")))+    {+        text = NULL;++        if (line[0] == '#')+            continue;++        if (strncmp(line, prefix, strlen(prefix)) == 0)+            line += strlen(prefix);++        (*count)++;++        char* path = calloc(strlen(line) + 1, 1);+        paths = realloc(paths, *count * sizeof(char*));+        paths[*count - 1] = path;++        while (*line)+        {+            if (line[0] == '%' && line[1] && line[2])+            {+                const char digits[3] = { line[1], line[2], '\0' };+                *path = strtol(digits, NULL, 16);+                line += 2;+            }+            else+                *path = *line;++            path++;+            line++;+        }+    }++    return paths;+}++// Centers the cursor over the window client area+//+static void centerCursor(_GLFWwindow* window)+{+    int width, height;+    _glfwPlatformGetWindowSize(window, &width, &height);+    _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);+}++// Updates the cursor image according to its cursor mode+//+static void updateCursorImage(_GLFWwindow* window)+{+    if (window->cursorMode == GLFW_CURSOR_NORMAL)+    {+        if (window->cursor)+        {+            XDefineCursor(_glfw.x11.display, window->x11.handle,+                          window->cursor->x11.handle);+        }+        else+            XUndefineCursor(_glfw.x11.display, window->x11.handle);+    }+    else+        XDefineCursor(_glfw.x11.display, window->x11.handle, _glfw.x11.cursor);+}++// Create the X11 window (and its colormap)+//+static GLFWbool createNativeWindow(_GLFWwindow* window,+                                   const _GLFWwndconfig* wndconfig,+                                   Visual* visual, int depth)+{+    // Create a colormap based on the visual used by the current context+    window->x11.colormap = XCreateColormap(_glfw.x11.display,+                                           _glfw.x11.root,+                                           visual,+                                           AllocNone);++    // Create the actual window+    {+        XSetWindowAttributes wa;+        const unsigned long wamask = CWBorderPixel | CWColormap | CWEventMask;++        wa.colormap = window->x11.colormap;+        wa.border_pixel = 0;+        wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |+                        PointerMotionMask | ButtonPressMask | ButtonReleaseMask |+                        ExposureMask | FocusChangeMask | VisibilityChangeMask |+                        EnterWindowMask | LeaveWindowMask | PropertyChangeMask;++        _glfwGrabErrorHandlerX11();++        window->x11.handle = XCreateWindow(_glfw.x11.display,+                                           _glfw.x11.root,+                                           0, 0,+                                           wndconfig->width, wndconfig->height,+                                           0,      // Border width+                                           depth,  // Color depth+                                           InputOutput,+                                           visual,+                                           wamask,+                                           &wa);++        _glfwReleaseErrorHandlerX11();++        if (!window->x11.handle)+        {+            _glfwInputErrorX11(GLFW_PLATFORM_ERROR,+                               "X11: Failed to create window");+            return GLFW_FALSE;+        }++        XSaveContext(_glfw.x11.display,+                     window->x11.handle,+                     _glfw.x11.context,+                     (XPointer) window);+    }++    if (!wndconfig->decorated)+    {+        struct+        {+            unsigned long flags;+            unsigned long functions;+            unsigned long decorations;+            long input_mode;+            unsigned long status;+        } hints;++        hints.flags = 2;       // Set decorations+        hints.decorations = 0; // No decorations++        XChangeProperty(_glfw.x11.display, window->x11.handle,+                        _glfw.x11.MOTIF_WM_HINTS,+                        _glfw.x11.MOTIF_WM_HINTS, 32,+                        PropModeReplace,+                        (unsigned char*) &hints,+                        sizeof(hints) / sizeof(long));+    }++    if (_glfw.x11.NET_WM_STATE && !window->monitor)+    {+        Atom states[3];+        int count = 0;++        if (wndconfig->floating)+        {+            if (_glfw.x11.NET_WM_STATE_ABOVE)+                states[count++] = _glfw.x11.NET_WM_STATE_ABOVE;+        }++        if (wndconfig->maximized)+        {+            if (_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&+                _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)+            {+                states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;+                states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;+            }+        }++        if (count)+        {+            XChangeProperty(_glfw.x11.display, window->x11.handle,+                            _glfw.x11.NET_WM_STATE, XA_ATOM, 32,+                            PropModeReplace, (unsigned char*) &states, count);+        }+    }++    // Declare the WM protocols supported by GLFW+    {+        Atom protocols[] =+        {+            _glfw.x11.WM_DELETE_WINDOW,+            _glfw.x11.NET_WM_PING+        };++        XSetWMProtocols(_glfw.x11.display, window->x11.handle,+                        protocols, sizeof(protocols) / sizeof(Atom));+    }++    // Declare our PID+    {+        const pid_t pid = getpid();++        XChangeProperty(_glfw.x11.display,  window->x11.handle,+                        _glfw.x11.NET_WM_PID, XA_CARDINAL, 32,+                        PropModeReplace,+                        (unsigned char*) &pid, 1);+    }++    if (_glfw.x11.NET_WM_WINDOW_TYPE && _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL)+    {+        Atom type = _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL;+        XChangeProperty(_glfw.x11.display,  window->x11.handle,+                        _glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,+                        PropModeReplace, (unsigned char*) &type, 1);+    }++    // Set ICCCM WM_HINTS property+    {+        XWMHints* hints = XAllocWMHints();+        if (!hints)+        {+            _glfwInputError(GLFW_OUT_OF_MEMORY,+                            "X11: Failed to allocate WM hints");+            return GLFW_FALSE;+        }++        hints->flags = StateHint;+        hints->initial_state = NormalState;++        XSetWMHints(_glfw.x11.display, window->x11.handle, hints);+        XFree(hints);+    }++    updateNormalHints(window, wndconfig->width, wndconfig->height);++    // Set ICCCM WM_CLASS property+    // HACK: Until a mechanism for specifying the application name is added, the+    //       initial window title is used as the window class name+    if (strlen(wndconfig->title))+    {+        XClassHint* hint = XAllocClassHint();+        hint->res_name = (char*) wndconfig->title;+        hint->res_class = (char*) wndconfig->title;++        XSetClassHint(_glfw.x11.display, window->x11.handle, hint);+        XFree(hint);+    }++    if (_glfw.x11.XdndAware)+    {+        // Announce support for Xdnd (drag and drop)+        const Atom version = 5;+        XChangeProperty(_glfw.x11.display, window->x11.handle,+                        _glfw.x11.XdndAware, XA_ATOM, 32,+                        PropModeReplace, (unsigned char*) &version, 1);+    }++    _glfwPlatformSetWindowTitle(window, wndconfig->title);++    if (_glfw.x11.im)+    {+        window->x11.ic = XCreateIC(_glfw.x11.im,+                                   XNInputStyle,+                                   XIMPreeditNothing | XIMStatusNothing,+                                   XNClientWindow,+                                   window->x11.handle,+                                   XNFocusWindow,+                                   window->x11.handle,+                                   NULL);+    }++    _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);+    _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);++    return GLFW_TRUE;+}++// Set the specified property to the selection converted to the requested target+//+static Atom writeTargetToProperty(const XSelectionRequestEvent* request)+{+    int i;+    const Atom formats[] = { _glfw.x11.UTF8_STRING,+                             _glfw.x11.COMPOUND_STRING,+                             XA_STRING };+    const int formatCount = sizeof(formats) / sizeof(formats[0]);++    if (request->property == None)+    {+        // The requester is a legacy client (ICCCM section 2.2)+        // We don't support legacy clients, so fail here+        return None;+    }++    if (request->target == _glfw.x11.TARGETS)+    {+        // The list of supported targets was requested++        const Atom targets[] = { _glfw.x11.TARGETS,+                                 _glfw.x11.MULTIPLE,+                                 _glfw.x11.UTF8_STRING,+                                 _glfw.x11.COMPOUND_STRING,+                                 XA_STRING };++        XChangeProperty(_glfw.x11.display,+                        request->requestor,+                        request->property,+                        XA_ATOM,+                        32,+                        PropModeReplace,+                        (unsigned char*) targets,+                        sizeof(targets) / sizeof(targets[0]));++        return request->property;+    }++    if (request->target == _glfw.x11.MULTIPLE)+    {+        // Multiple conversions were requested++        Atom* targets;+        unsigned long i, count;++        count = _glfwGetWindowPropertyX11(request->requestor,+                                          request->property,+                                          _glfw.x11.ATOM_PAIR,+                                          (unsigned char**) &targets);++        for (i = 0;  i < count;  i += 2)+        {+            int j;++            for (j = 0;  j < formatCount;  j++)+            {+                if (targets[i] == formats[j])+                    break;+            }++            if (j < formatCount)+            {+                XChangeProperty(_glfw.x11.display,+                                request->requestor,+                                targets[i + 1],+                                targets[i],+                                8,+                                PropModeReplace,+                                (unsigned char*) _glfw.x11.clipboardString,+                                strlen(_glfw.x11.clipboardString));+            }+            else+                targets[i + 1] = None;+        }++        XChangeProperty(_glfw.x11.display,+                        request->requestor,+                        request->property,+                        _glfw.x11.ATOM_PAIR,+                        32,+                        PropModeReplace,+                        (unsigned char*) targets,+                        count);++        XFree(targets);++        return request->property;+    }++    if (request->target == _glfw.x11.SAVE_TARGETS)+    {+        // The request is a check whether we support SAVE_TARGETS+        // It should be handled as a no-op side effect target++        XChangeProperty(_glfw.x11.display,+                        request->requestor,+                        request->property,+                        _glfw.x11.NULL_,+                        32,+                        PropModeReplace,+                        NULL,+                        0);++        return request->property;+    }++    // Conversion to a data target was requested++    for (i = 0;  i < formatCount;  i++)+    {+        if (request->target == formats[i])+        {+            // The requested target is one we support++            XChangeProperty(_glfw.x11.display,+                            request->requestor,+                            request->property,+                            request->target,+                            8,+                            PropModeReplace,+                            (unsigned char*) _glfw.x11.clipboardString,+                            strlen(_glfw.x11.clipboardString));++            return request->property;+        }+    }++    // The requested target is not supported++    return None;+}++static void handleSelectionClear(XEvent* event)+{+    free(_glfw.x11.clipboardString);+    _glfw.x11.clipboardString = NULL;+}++static void handleSelectionRequest(XEvent* event)+{+    const XSelectionRequestEvent* request = &event->xselectionrequest;++    XEvent reply;+    memset(&reply, 0, sizeof(reply));++    reply.xselection.property = writeTargetToProperty(request);+    reply.xselection.type = SelectionNotify;+    reply.xselection.display = request->display;+    reply.xselection.requestor = request->requestor;+    reply.xselection.selection = request->selection;+    reply.xselection.target = request->target;+    reply.xselection.time = request->time;++    XSendEvent(_glfw.x11.display, request->requestor, False, 0, &reply);+}++static void pushSelectionToManager(_GLFWwindow* window)+{+    XConvertSelection(_glfw.x11.display,+                      _glfw.x11.CLIPBOARD_MANAGER,+                      _glfw.x11.SAVE_TARGETS,+                      None,+                      window->x11.handle,+                      CurrentTime);++    for (;;)+    {+        XEvent event;++        while (XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL))+        {+            switch (event.type)+            {+                case SelectionRequest:+                    handleSelectionRequest(&event);+                    break;++                case SelectionClear:+                    handleSelectionClear(&event);+                    break;++                case SelectionNotify:+                {+                    if (event.xselection.target == _glfw.x11.SAVE_TARGETS)+                    {+                        // This means one of two things; either the selection was+                        // not owned, which means there is no clipboard manager, or+                        // the transfer to the clipboard manager has completed+                        // In either case, it means we are done here+                        return;+                    }++                    break;+                }+            }+        }++        waitForEvent(NULL);+    }+}++// Make the specified window and its video mode active on its monitor+//+static GLFWbool acquireMonitor(_GLFWwindow* window)+{+    GLFWbool status;++    if (_glfw.x11.saver.count == 0)+    {+        // Remember old screen saver settings+        XGetScreenSaver(_glfw.x11.display,+                        &_glfw.x11.saver.timeout,+                        &_glfw.x11.saver.interval,+                        &_glfw.x11.saver.blanking,+                        &_glfw.x11.saver.exposure);++        // Disable screen saver+        XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking,+                        DefaultExposures);+    }++    if (!window->monitor->window)+        _glfw.x11.saver.count++;++    status = _glfwSetVideoModeX11(window->monitor, &window->videoMode);++    if (window->x11.overrideRedirect)+    {+        int xpos, ypos;+        GLFWvidmode mode;++        // Manually position the window over its monitor+        _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);+        _glfwPlatformGetVideoMode(window->monitor, &mode);++        XMoveResizeWindow(_glfw.x11.display, window->x11.handle,+                          xpos, ypos, mode.width, mode.height);+    }++    _glfwInputMonitorWindowChange(window->monitor, window);+    return status;+}++// Remove the window and restore the original video mode+//+static void releaseMonitor(_GLFWwindow* window)+{+    if (window->monitor->window != window)+        return;++    _glfwInputMonitorWindowChange(window->monitor, NULL);+    _glfwRestoreVideoModeX11(window->monitor);++    _glfw.x11.saver.count--;++    if (_glfw.x11.saver.count == 0)+    {+        // Restore old screen saver settings+        XSetScreenSaver(_glfw.x11.display,+                        _glfw.x11.saver.timeout,+                        _glfw.x11.saver.interval,+                        _glfw.x11.saver.blanking,+                        _glfw.x11.saver.exposure);+    }+}++// Decode a Unicode code point from a UTF-8 stream+// Based on cutef8 by Jeff Bezanson (Public Domain)+//+#if defined(X_HAVE_UTF8_STRING)+static unsigned int decodeUTF8(const char** s)+{+    unsigned int ch = 0, count = 0;+    static const unsigned int offsets[] =+    {+        0x00000000u, 0x00003080u, 0x000e2080u,+        0x03c82080u, 0xfa082080u, 0x82082080u+    };++    do+    {+        ch = (ch << 6) + (unsigned char) **s;+        (*s)++;+        count++;+    } while ((**s & 0xc0) == 0x80);++    assert(count <= 6);+    return ch - offsets[count - 1];+}+#endif /*X_HAVE_UTF8_STRING*/++// Process the specified X event+//+static void processEvent(XEvent *event)+{+    _GLFWwindow* window = NULL;+    int keycode = 0;+    Bool filtered = False;++    // HACK: Save scancode as some IMs clear the field in XFilterEvent+    if (event->type == KeyPress || event->type == KeyRelease)+        keycode = event->xkey.keycode;++    if (_glfw.x11.im)+        filtered = XFilterEvent(event, None);++    if (_glfw.x11.randr.available)+    {+        if (event->type == _glfw.x11.randr.eventBase + RRNotify)+        {+            XRRUpdateConfiguration(event);+            _glfwInputMonitorChange();+            return;+        }+    }++    if (event->type != GenericEvent)+    {+        window = findWindowByHandle(event->xany.window);+        if (window == NULL)+        {+            // This is an event for a window that has already been destroyed+            return;+        }+    }++    switch (event->type)+    {+        case KeyPress:+        {+            const int key = translateKey(keycode);+            const int mods = translateState(event->xkey.state);+            const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));++            if (window->x11.ic)+            {+                // HACK: Ignore duplicate key press events generated by ibus+                //       Corresponding release events are filtered out by the+                //       GLFW key repeat logic+                if (window->x11.lastKeyCode != keycode ||+                    window->x11.lastKeyTime != event->xkey.time)+                {+                    if (keycode)+                        _glfwInputKey(window, key, keycode, GLFW_PRESS, mods);+                }++                window->x11.lastKeyCode = keycode;+                window->x11.lastKeyTime = event->xkey.time;++                if (!filtered)+                {+                    int count;+                    Status status;+#if defined(X_HAVE_UTF8_STRING)+                    char buffer[100];+                    char* chars = buffer;++                    count = Xutf8LookupString(window->x11.ic,+                                              &event->xkey,+                                              buffer, sizeof(buffer) - 1,+                                              NULL, &status);++                    if (status == XBufferOverflow)+                    {+                        chars = calloc(count + 1, 1);+                        count = Xutf8LookupString(window->x11.ic,+                                                  &event->xkey,+                                                  chars, count,+                                                  NULL, &status);+                    }++                    if (status == XLookupChars || status == XLookupBoth)+                    {+                        const char* c = chars;+                        chars[count] = '\0';+                        while (c - chars < count)+                            _glfwInputChar(window, decodeUTF8(&c), mods, plain);+                    }+#else /*X_HAVE_UTF8_STRING*/+                    wchar_t buffer[16];+                    wchar_t* chars = buffer;++                    count = XwcLookupString(window->x11.ic,+                                            &event->xkey,+                                            buffer, sizeof(buffer) / sizeof(wchar_t),+                                            NULL, &status);++                    if (status == XBufferOverflow)+                    {+                        chars = calloc(count, sizeof(wchar_t));+                        count = XwcLookupString(window->x11.ic,+                                                &event->xkey,+                                                chars, count,+                                                NULL, &status);+                    }++                    if (status == XLookupChars || status == XLookupBoth)+                    {+                        int i;+                        for (i = 0;  i < count;  i++)+                            _glfwInputChar(window, chars[i], mods, plain);+                    }+#endif /*X_HAVE_UTF8_STRING*/++                    if (chars != buffer)+                        free(chars);+                }+            }+            else+            {+                KeySym keysym;+                XLookupString(&event->xkey, NULL, 0, &keysym, NULL);++                _glfwInputKey(window, key, keycode, GLFW_PRESS, mods);++                const long character = _glfwKeySym2Unicode(keysym);+                if (character != -1)+                    _glfwInputChar(window, character, mods, plain);+            }++            return;+        }++        case KeyRelease:+        {+            const int key = translateKey(keycode);+            const int mods = translateState(event->xkey.state);++            if (!_glfw.x11.xkb.detectable)+            {+                // HACK: Key repeat events will arrive as KeyRelease/KeyPress+                //       pairs with similar or identical time stamps+                //       The key repeat logic in _glfwInputKey expects only key+                //       presses to repeat, so detect and discard release events+                if (XEventsQueued(_glfw.x11.display, QueuedAfterReading))+                {+                    XEvent next;+                    XPeekEvent(_glfw.x11.display, &next);++                    if (next.type == KeyPress &&+                        next.xkey.window == event->xkey.window &&+                        next.xkey.keycode == keycode)+                    {+                        // HACK: The time of repeat events sometimes doesn't+                        //       match that of the press event, so add an+                        //       epsilon+                        //       Toshiyuki Takahashi can press a button+                        //       16 times per second so it's fairly safe to+                        //       assume that no human is pressing the key 50+                        //       times per second (value is ms)+                        if ((next.xkey.time - event->xkey.time) < 20)+                        {+                            // This is very likely a server-generated key repeat+                            // event, so ignore it+                            return;+                        }+                    }+                }+            }++            _glfwInputKey(window, key, keycode, GLFW_RELEASE, mods);+            return;+        }++        case ButtonPress:+        {+            const int mods = translateState(event->xbutton.state);++            if (event->xbutton.button == Button1)+                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);+            else if (event->xbutton.button == Button2)+                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);+            else if (event->xbutton.button == Button3)+                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);++            // Modern X provides scroll events as mouse button presses+            else if (event->xbutton.button == Button4)+                _glfwInputScroll(window, 0.0, 1.0);+            else if (event->xbutton.button == Button5)+                _glfwInputScroll(window, 0.0, -1.0);+            else if (event->xbutton.button == Button6)+                _glfwInputScroll(window, 1.0, 0.0);+            else if (event->xbutton.button == Button7)+                _glfwInputScroll(window, -1.0, 0.0);++            else+            {+                // Additional buttons after 7 are treated as regular buttons+                // We subtract 4 to fill the gap left by scroll input above+                _glfwInputMouseClick(window,+                                     event->xbutton.button - Button1 - 4,+                                     GLFW_PRESS,+                                     mods);+            }++            return;+        }++        case ButtonRelease:+        {+            const int mods = translateState(event->xbutton.state);++            if (event->xbutton.button == Button1)+            {+                _glfwInputMouseClick(window,+                                     GLFW_MOUSE_BUTTON_LEFT,+                                     GLFW_RELEASE,+                                     mods);+            }+            else if (event->xbutton.button == Button2)+            {+                _glfwInputMouseClick(window,+                                     GLFW_MOUSE_BUTTON_MIDDLE,+                                     GLFW_RELEASE,+                                     mods);+            }+            else if (event->xbutton.button == Button3)+            {+                _glfwInputMouseClick(window,+                                     GLFW_MOUSE_BUTTON_RIGHT,+                                     GLFW_RELEASE,+                                     mods);+            }+            else if (event->xbutton.button > Button7)+            {+                // Additional buttons after 7 are treated as regular buttons+                // We subtract 4 to fill the gap left by scroll input above+                _glfwInputMouseClick(window,+                                     event->xbutton.button - Button1 - 4,+                                     GLFW_RELEASE,+                                     mods);+            }++            return;+        }++        case EnterNotify:+        {+            // HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise+            //       ignore the defined cursor for hidden cursor mode+            if (window->cursorMode == GLFW_CURSOR_HIDDEN)+                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_HIDDEN);++            _glfwInputCursorEnter(window, GLFW_TRUE);+            return;+        }++        case LeaveNotify:+        {+            _glfwInputCursorEnter(window, GLFW_FALSE);+            return;+        }++        case MotionNotify:+        {+            const int x = event->xmotion.x;+            const int y = event->xmotion.y;++            if (x != window->x11.warpCursorPosX || y != window->x11.warpCursorPosY)+            {+                // The cursor was moved by something other than GLFW++                if (window->cursorMode == GLFW_CURSOR_DISABLED)+                {+                    if (_glfw.x11.disabledCursorWindow != window)+                        return;++                    const int dx = x - window->x11.lastCursorPosX;+                    const int dy = y - window->x11.lastCursorPosY;++                    _glfwInputCursorPos(window,+                                        window->virtualCursorPosX + dx,+                                        window->virtualCursorPosY + dy);+                }+                else+                    _glfwInputCursorPos(window, x, y);+            }++            window->x11.lastCursorPosX = x;+            window->x11.lastCursorPosY = y;+            return;+        }++        case ConfigureNotify:+        {+            if (event->xconfigure.width != window->x11.width ||+                event->xconfigure.height != window->x11.height)+            {+                _glfwInputFramebufferSize(window,+                                          event->xconfigure.width,+                                          event->xconfigure.height);++                _glfwInputWindowSize(window,+                                     event->xconfigure.width,+                                     event->xconfigure.height);++                window->x11.width = event->xconfigure.width;+                window->x11.height = event->xconfigure.height;+            }++            if (event->xconfigure.x != window->x11.xpos ||+                event->xconfigure.y != window->x11.ypos)+            {+                if (window->x11.overrideRedirect || event->xany.send_event)+                {+                    _glfwInputWindowPos(window,+                                        event->xconfigure.x,+                                        event->xconfigure.y);++                    window->x11.xpos = event->xconfigure.x;+                    window->x11.ypos = event->xconfigure.y;+                }+            }++            return;+        }++        case ClientMessage:+        {+            // Custom client message, probably from the window manager++            if (filtered)+                return;++            if (event->xclient.message_type == None)+                return;++            if (event->xclient.message_type == _glfw.x11.WM_PROTOCOLS)+            {+                const Atom protocol = event->xclient.data.l[0];+                if (protocol == None)+                    return;++                if (protocol == _glfw.x11.WM_DELETE_WINDOW)+                {+                    // The window manager was asked to close the window, for example by+                    // the user pressing a 'close' window decoration button+                    _glfwInputWindowCloseRequest(window);+                }+                else if (protocol == _glfw.x11.NET_WM_PING)+                {+                    // The window manager is pinging the application to ensure it's+                    // still responding to events++                    XEvent reply = *event;+                    reply.xclient.window = _glfw.x11.root;++                    XSendEvent(_glfw.x11.display, _glfw.x11.root,+                               False,+                               SubstructureNotifyMask | SubstructureRedirectMask,+                               &reply);+                }+            }+            else if (event->xclient.message_type == _glfw.x11.XdndEnter)+            {+                // A drag operation has entered the window+                // TODO: Check if UTF-8 string is supported by the source+            }+            else if (event->xclient.message_type == _glfw.x11.XdndDrop)+            {+                // The drag operation has finished dropping on+                // the window, ask to convert it to a UTF-8 string+                _glfw.x11.xdnd.source = event->xclient.data.l[0];+                XConvertSelection(_glfw.x11.display,+                                  _glfw.x11.XdndSelection,+                                  _glfw.x11.UTF8_STRING,+                                  _glfw.x11.XdndSelection,+                                  window->x11.handle, CurrentTime);+            }+            else if (event->xclient.message_type == _glfw.x11.XdndPosition)+            {+                // The drag operation has moved over the window+                const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF;+                const int absY = (event->xclient.data.l[2]) & 0xFFFF;+                int x, y;++                _glfwPlatformGetWindowPos(window, &x, &y);+                _glfwInputCursorPos(window, absX - x, absY - y);++                // Reply that we are ready to copy the dragged data+                XEvent reply;+                memset(&reply, 0, sizeof(reply));++                reply.type = ClientMessage;+                reply.xclient.window = event->xclient.data.l[0];+                reply.xclient.message_type = _glfw.x11.XdndStatus;+                reply.xclient.format = 32;+                reply.xclient.data.l[0] = window->x11.handle;+                reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle+                reply.xclient.data.l[2] = 0; // Specify an empty rectangle+                reply.xclient.data.l[3] = 0;+                reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy;++                XSendEvent(_glfw.x11.display, event->xclient.data.l[0],+                           False, NoEventMask, &reply);+                XFlush(_glfw.x11.display);+            }++            return;+        }++        case SelectionNotify:+        {+            if (event->xselection.property)+            {+                // The converted data from the drag operation has arrived+                char* data;+                const int result =+                    _glfwGetWindowPropertyX11(event->xselection.requestor,+                                              event->xselection.property,+                                              event->xselection.target,+                                              (unsigned char**) &data);++                if (result)+                {+                    int i, count;+                    char** paths = parseUriList(data, &count);++                    _glfwInputDrop(window, count, (const char**) paths);++                    for (i = 0;  i < count;  i++)+                        free(paths[i]);+                    free(paths);+                }++                XFree(data);++                XEvent reply;+                memset(&reply, 0, sizeof(reply));++                reply.type = ClientMessage;+                reply.xclient.window = _glfw.x11.xdnd.source;+                reply.xclient.message_type = _glfw.x11.XdndFinished;+                reply.xclient.format = 32;+                reply.xclient.data.l[0] = window->x11.handle;+                reply.xclient.data.l[1] = result;+                reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy;++                // Reply that all is well+                XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,+                           False, NoEventMask, &reply);+                XFlush(_glfw.x11.display);+            }++            return;+        }++        case FocusIn:+        {+            if (window->cursorMode == GLFW_CURSOR_DISABLED)+                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);++            if (event->xfocus.mode == NotifyGrab ||+                event->xfocus.mode == NotifyUngrab)+            {+                // Ignore focus events from popup indicator windows, window menu+                // key chords and window dragging+                return;+            }++            if (window->x11.ic)+                XSetICFocus(window->x11.ic);++            _glfwInputWindowFocus(window, GLFW_TRUE);+            return;+        }++        case FocusOut:+        {+            if (window->cursorMode == GLFW_CURSOR_DISABLED)+                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);++            if (event->xfocus.mode == NotifyGrab ||+                event->xfocus.mode == NotifyUngrab)+            {+                // Ignore focus events from popup indicator windows, window menu+                // key chords and window dragging+                return;+            }++            if (window->x11.ic)+                XUnsetICFocus(window->x11.ic);++            if (window->monitor && window->autoIconify)+                _glfwPlatformIconifyWindow(window);++            _glfwInputWindowFocus(window, GLFW_FALSE);+            return;+        }++        case Expose:+        {+            _glfwInputWindowDamage(window);+            return;+        }++        case PropertyNotify:+        {+            if (event->xproperty.atom == _glfw.x11.WM_STATE &&+                event->xproperty.state == PropertyNewValue)+            {+                const int state = getWindowState(window);+                if (state == IconicState)+                {+                    if (window->monitor)+                        releaseMonitor(window);++                    _glfwInputWindowIconify(window, GLFW_TRUE);+                }+                else if (state == NormalState)+                {+                    if (window->monitor)+                        acquireMonitor(window);++                    _glfwInputWindowIconify(window, GLFW_FALSE);+                }+            }++            return;+        }++        case SelectionClear:+        {+            handleSelectionClear(event);+            return;+        }++        case SelectionRequest:+        {+            handleSelectionRequest(event);+            return;+        }++        case DestroyNotify:+            return;+    }+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW internal API                      //////+//////////////////////////////////////////////////////////////////////////++// Retrieve a single window property of the specified type+// Inspired by fghGetWindowProperty from freeglut+//+unsigned long _glfwGetWindowPropertyX11(Window window,+                                        Atom property,+                                        Atom type,+                                        unsigned char** value)+{+    Atom actualType;+    int actualFormat;+    unsigned long itemCount, bytesAfter;++    XGetWindowProperty(_glfw.x11.display,+                       window,+                       property,+                       0,+                       LONG_MAX,+                       False,+                       type,+                       &actualType,+                       &actualFormat,+                       &itemCount,+                       &bytesAfter,+                       value);++    if (type != AnyPropertyType && actualType != type)+        return 0;++    return itemCount;+}+++//////////////////////////////////////////////////////////////////////////+//////                       GLFW platform API                      //////+//////////////////////////////////////////////////////////////////////////++int _glfwPlatformCreateWindow(_GLFWwindow* window,+                              const _GLFWwndconfig* wndconfig,+                              const _GLFWctxconfig* ctxconfig,+                              const _GLFWfbconfig* fbconfig)+{+    Visual* visual;+    int depth;++    if (ctxconfig->client == GLFW_NO_API)+    {+        visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);+        depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);+    }+    else+    {+        if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)+        {+            if (!_glfwInitGLX())+                return GLFW_FALSE;+            if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))+                return GLFW_FALSE;+        }+        else+        {+            if (!_glfwInitEGL())+                return GLFW_FALSE;+            if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))+                return GLFW_FALSE;+        }+    }++    if (!createNativeWindow(window, wndconfig, visual, depth))+        return GLFW_FALSE;++    if (ctxconfig->client != GLFW_NO_API)+    {+        if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)+        {+            if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))+                return GLFW_FALSE;+        }+        else+        {+            if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))+                return GLFW_FALSE;+        }+    }++    if (window->monitor)+    {+        _glfwPlatformShowWindow(window);+        updateWindowMode(window);+        if (!acquireMonitor(window))+            return GLFW_FALSE;++        centerCursor(window);+    }++    XFlush(_glfw.x11.display);+    return GLFW_TRUE;+}++void _glfwPlatformDestroyWindow(_GLFWwindow* window)+{+    if (_glfw.x11.disabledCursorWindow == window)+        _glfw.x11.disabledCursorWindow = NULL;++    if (window->monitor)+        releaseMonitor(window);++    if (window->x11.ic)+    {+        XDestroyIC(window->x11.ic);+        window->x11.ic = NULL;+    }++    if (window->context.destroy)+        window->context.destroy(window);++    if (window->x11.handle)+    {+        if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==+            window->x11.handle)+        {+            pushSelectionToManager(window);+        }++        XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context);+        XUnmapWindow(_glfw.x11.display, window->x11.handle);+        XDestroyWindow(_glfw.x11.display, window->x11.handle);+        window->x11.handle = (Window) 0;+    }++    if (window->x11.colormap)+    {+        XFreeColormap(_glfw.x11.display, window->x11.colormap);+        window->x11.colormap = (Colormap) 0;+    }++    XFlush(_glfw.x11.display);+}++void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)+{+#if defined(X_HAVE_UTF8_STRING)+    Xutf8SetWMProperties(_glfw.x11.display,+                         window->x11.handle,+                         title, title,+                         NULL, 0,+                         NULL, NULL, NULL);+#else+    // This may be a slightly better fallback than using XStoreName and+    // XSetIconName, which always store their arguments using STRING+    XmbSetWMProperties(_glfw.x11.display,+                       window->x11.handle,+                       title, title,+                       NULL, 0,+                       NULL, NULL, NULL);+#endif++    XChangeProperty(_glfw.x11.display,  window->x11.handle,+                    _glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8,+                    PropModeReplace,+                    (unsigned char*) title, strlen(title));++    XChangeProperty(_glfw.x11.display,  window->x11.handle,+                    _glfw.x11.NET_WM_ICON_NAME, _glfw.x11.UTF8_STRING, 8,+                    PropModeReplace,+                    (unsigned char*) title, strlen(title));++    XFlush(_glfw.x11.display);+}++void _glfwPlatformSetWindowIcon(_GLFWwindow* window,+                                int count, const GLFWimage* images)+{+    if (count)+    {+        int i, j, longCount = 0;++        for (i = 0;  i < count;  i++)+            longCount += 2 + images[i].width * images[i].height;++        long* icon = calloc(longCount, sizeof(long));+        long* target = icon;++        for (i = 0;  i < count;  i++)+        {+            *target++ = images[i].width;+            *target++ = images[i].height;++            for (j = 0;  j < images[i].width * images[i].height;  j++)+            {+                *target++ = (images[i].pixels[j * 4 + 0] << 16) |+                            (images[i].pixels[j * 4 + 1] <<  8) |+                            (images[i].pixels[j * 4 + 2] <<  0) |+                            (images[i].pixels[j * 4 + 3] << 24);+            }+        }++        XChangeProperty(_glfw.x11.display, window->x11.handle,+                        _glfw.x11.NET_WM_ICON,+                        XA_CARDINAL, 32,+                        PropModeReplace,+                        (unsigned char*) icon,+                        longCount);++        free(icon);+    }+    else+    {+        XDeleteProperty(_glfw.x11.display, window->x11.handle,+                        _glfw.x11.NET_WM_ICON);+    }++    XFlush(_glfw.x11.display);+}++void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)+{+    Window dummy;+    int x, y;++    XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root,+                          0, 0, &x, &y, &dummy);++    if (xpos)+        *xpos = x;+    if (ypos)+        *ypos = y;+}++void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)+{+    // HACK: Explicitly setting PPosition to any value causes some WMs, notably+    //       Compiz and Metacity, to honor the position of unmapped windows+    if (!_glfwPlatformWindowVisible(window))+    {+        long supplied;+        XSizeHints* hints = XAllocSizeHints();++        if (XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied))+        {+            hints->flags |= PPosition;+            hints->x = hints->y = 0;++            XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);+        }++        XFree(hints);+    }++    XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos);+    XFlush(_glfw.x11.display);+}++void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)+{+    XWindowAttributes attribs;+    XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs);++    if (width)+        *width = attribs.width;+    if (height)+        *height = attribs.height;+}++void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)+{+    if (window->monitor)+    {+        if (window->monitor->window == window)+            acquireMonitor(window);+    }+    else+    {+        if (!window->resizable)+            updateNormalHints(window, width, height);++        XResizeWindow(_glfw.x11.display, window->x11.handle, width, height);+    }++    XFlush(_glfw.x11.display);+}++void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,+                                      int minwidth, int minheight,+                                      int maxwidth, int maxheight)+{+    int width, height;+    _glfwPlatformGetWindowSize(window, &width, &height);+    updateNormalHints(window, width, height);+    XFlush(_glfw.x11.display);+}++void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)+{+    int width, height;+    _glfwPlatformGetWindowSize(window, &width, &height);+    updateNormalHints(window, width, height);+    XFlush(_glfw.x11.display);+}++void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)+{+    _glfwPlatformGetWindowSize(window, width, height);+}++void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,+                                     int* left, int* top,+                                     int* right, int* bottom)+{+    long* extents = NULL;++    if (window->monitor || !window->decorated)+        return;++    if (_glfw.x11.NET_FRAME_EXTENTS == None)+        return;++    if (!_glfwPlatformWindowVisible(window) &&+        _glfw.x11.NET_REQUEST_FRAME_EXTENTS)+    {+        XEvent event;+        double timeout = 0.5;++        // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to+        // function before the window is mapped+        sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS,+                      0, 0, 0, 0, 0);++        // HACK: Use a timeout because earlier versions of some window managers+        //       (at least Unity, Fluxbox and Xfwm) failed to send the reply+        //       They have been fixed but broken versions are still in the wild+        //       If you are affected by this and your window manager is NOT+        //       listed above, PLEASE report it to their and our issue trackers+        while (!XCheckIfEvent(_glfw.x11.display,+                              &event,+                              isFrameExtentsEvent,+                              (XPointer) window))+        {+            if (!waitForEvent(&timeout))+            {+                _glfwInputError(GLFW_PLATFORM_ERROR,+                                "X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");+                return;+            }+        }+    }++    if (_glfwGetWindowPropertyX11(window->x11.handle,+                                  _glfw.x11.NET_FRAME_EXTENTS,+                                  XA_CARDINAL,+                                  (unsigned char**) &extents) == 4)+    {+        if (left)+            *left = extents[0];+        if (top)+            *top = extents[2];+        if (right)+            *right = extents[1];+        if (bottom)+            *bottom = extents[3];+    }++    if (extents)+        XFree(extents);+}++void _glfwPlatformIconifyWindow(_GLFWwindow* window)+{+    if (window->x11.overrideRedirect)+    {+        // Override-redirect windows cannot be iconified or restored, as those+        // tasks are performed by the window manager+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "X11: Iconification of full screen windows requires a WM that supports EWMH full screen");+        return;+    }++    XIconifyWindow(_glfw.x11.display, window->x11.handle, _glfw.x11.screen);+    XFlush(_glfw.x11.display);+}++void _glfwPlatformRestoreWindow(_GLFWwindow* window)+{+    if (window->x11.overrideRedirect)+    {+        // Override-redirect windows cannot be iconified or restored, as those+        // tasks are performed by the window manager+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "X11: Iconification of full screen windows requires a WM that supports EWMH full screen");+        return;+    }++    if (_glfwPlatformWindowIconified(window))+    {+        XMapWindow(_glfw.x11.display, window->x11.handle);+        waitForVisibilityNotify(window);+    }+    else if (_glfwPlatformWindowVisible(window))+    {+        if (_glfw.x11.NET_WM_STATE &&+            _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&+            _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)+        {+            sendEventToWM(window,+                          _glfw.x11.NET_WM_STATE,+                          _NET_WM_STATE_REMOVE,+                          _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,+                          _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,+                          1, 0);+        }+    }++    XFlush(_glfw.x11.display);+}++void _glfwPlatformMaximizeWindow(_GLFWwindow* window)+{+    if (_glfw.x11.NET_WM_STATE &&+        _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&+        _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)+    {+        sendEventToWM(window,+                      _glfw.x11.NET_WM_STATE,+                      _NET_WM_STATE_ADD,+                      _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,+                      _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,+                      1, 0);+        XFlush(_glfw.x11.display);+    }+}++void _glfwPlatformShowWindow(_GLFWwindow* window)+{+    if (_glfwPlatformWindowVisible(window))+        return;++    XMapWindow(_glfw.x11.display, window->x11.handle);+    waitForVisibilityNotify(window);+}++void _glfwPlatformHideWindow(_GLFWwindow* window)+{+    XUnmapWindow(_glfw.x11.display, window->x11.handle);+    XFlush(_glfw.x11.display);+}++void _glfwPlatformFocusWindow(_GLFWwindow* window)+{+    if (_glfw.x11.NET_ACTIVE_WINDOW)+        sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);+    else+    {+        XRaiseWindow(_glfw.x11.display, window->x11.handle);+        XSetInputFocus(_glfw.x11.display, window->x11.handle,+                       RevertToParent, CurrentTime);+    }++    XFlush(_glfw.x11.display);+}++void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,+                                   _GLFWmonitor* monitor,+                                   int xpos, int ypos,+                                   int width, int height,+                                   int refreshRate)+{+    if (window->monitor == monitor)+    {+        if (monitor)+        {+            if (monitor->window == window)+                acquireMonitor(window);+        }+        else+        {+            XMoveResizeWindow(_glfw.x11.display, window->x11.handle,+                              xpos, ypos, width, height);+        }++        return;+    }++    if (window->monitor)+        releaseMonitor(window);++    _glfwInputWindowMonitorChange(window, monitor);+    updateNormalHints(window, width, height);+    updateWindowMode(window);++    if (window->monitor)+    {+        XMapRaised(_glfw.x11.display, window->x11.handle);+        if (waitForVisibilityNotify(window))+            acquireMonitor(window);+    }+    else+    {+        XMoveResizeWindow(_glfw.x11.display, window->x11.handle,+                          xpos, ypos, width, height);+    }++    XFlush(_glfw.x11.display);+}++int _glfwPlatformWindowFocused(_GLFWwindow* window)+{+    Window focused;+    int state;++    XGetInputFocus(_glfw.x11.display, &focused, &state);+    return window->x11.handle == focused;+}++int _glfwPlatformWindowIconified(_GLFWwindow* window)+{+    return getWindowState(window) == IconicState;+}++int _glfwPlatformWindowVisible(_GLFWwindow* window)+{+    XWindowAttributes wa;+    XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &wa);+    return wa.map_state == IsViewable;+}++int _glfwPlatformWindowMaximized(_GLFWwindow* window)+{+    Atom* states;+    unsigned long i;+    GLFWbool maximized = GLFW_FALSE;+    const unsigned long count =+        _glfwGetWindowPropertyX11(window->x11.handle,+                                  _glfw.x11.NET_WM_STATE,+                                  XA_ATOM,+                                  (unsigned char**) &states);++    for (i = 0;  i < count;  i++)+    {+        if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||+            states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)+        {+            maximized = GLFW_TRUE;+            break;+        }+    }++    XFree(states);+    return maximized;+}++void _glfwPlatformPollEvents(void)+{+    _glfwPollJoystickEvents();++    int count = XPending(_glfw.x11.display);+    while (count--)+    {+        XEvent event;+        XNextEvent(_glfw.x11.display, &event);+        processEvent(&event);+    }++    if (_glfw.x11.disabledCursorWindow)+        centerCursor(_glfw.x11.disabledCursorWindow);++    XFlush(_glfw.x11.display);+}++void _glfwPlatformWaitEvents(void)+{+    while (!XPending(_glfw.x11.display))+        waitForEvent(NULL);++    _glfwPlatformPollEvents();+}++void _glfwPlatformWaitEventsTimeout(double timeout)+{+    while (!XPending(_glfw.x11.display))+    {+        if (!waitForEvent(&timeout))+            break;+    }++    _glfwPlatformPollEvents();+}++void _glfwPlatformPostEmptyEvent(void)+{+    XEvent event;+    _GLFWwindow* window = _glfw.windowListHead;++    memset(&event, 0, sizeof(event));+    event.type = ClientMessage;+    event.xclient.window = window->x11.handle;+    event.xclient.format = 32; // Data is 32-bit longs+    event.xclient.message_type = _glfw.x11.NULL_;++    XSendEvent(_glfw.x11.display, window->x11.handle, False, 0, &event);+    XFlush(_glfw.x11.display);+}++void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)+{+    Window root, child;+    int rootX, rootY, childX, childY;+    unsigned int mask;++    XQueryPointer(_glfw.x11.display, window->x11.handle,+                  &root, &child,+                  &rootX, &rootY, &childX, &childY,+                  &mask);++    if (xpos)+        *xpos = childX;+    if (ypos)+        *ypos = childY;+}++void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)+{+    // Store the new position so it can be recognized later+    window->x11.warpCursorPosX = (int) x;+    window->x11.warpCursorPosY = (int) y;++    XWarpPointer(_glfw.x11.display, None, window->x11.handle,+                 0,0,0,0, (int) x, (int) y);+    XFlush(_glfw.x11.display);+}++void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)+{+    if (mode == GLFW_CURSOR_DISABLED)+    {+        _glfw.x11.disabledCursorWindow = window;+        _glfwPlatformGetCursorPos(window,+                                  &_glfw.x11.restoreCursorPosX,+                                  &_glfw.x11.restoreCursorPosY);+        centerCursor(window);+        XGrabPointer(_glfw.x11.display, window->x11.handle, True,+                     ButtonPressMask | ButtonReleaseMask | PointerMotionMask,+                     GrabModeAsync, GrabModeAsync,+                     window->x11.handle, _glfw.x11.cursor, CurrentTime);+    }+    else if (_glfw.x11.disabledCursorWindow == window)+    {+        _glfw.x11.disabledCursorWindow = NULL;+        XUngrabPointer(_glfw.x11.display, CurrentTime);+        _glfwPlatformSetCursorPos(window,+                                  _glfw.x11.restoreCursorPosX,+                                  _glfw.x11.restoreCursorPosY);+    }++    updateCursorImage(window);+    XFlush(_glfw.x11.display);+}++const char* _glfwPlatformGetKeyName(int key, int scancode)+{+    KeySym keysym;+    int extra;++    if (!_glfw.x11.xkb.available)+        return NULL;++    if (key != GLFW_KEY_UNKNOWN)+        scancode = _glfw.x11.nativeKeys[key];++    if (!_glfwIsPrintable(_glfw.x11.publicKeys[scancode]))+        return NULL;++    keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);+    if (keysym == NoSymbol)+      return NULL;++    XkbTranslateKeySym(_glfw.x11.display, &keysym, 0,+                       _glfw.x11.keyName, sizeof(_glfw.x11.keyName),+                       &extra);++    if (!strlen(_glfw.x11.keyName))+        return NULL;++    return _glfw.x11.keyName;+}++int _glfwPlatformCreateCursor(_GLFWcursor* cursor,+                              const GLFWimage* image,+                              int xhot, int yhot)+{+    cursor->x11.handle = _glfwCreateCursorX11(image, xhot, yhot);+    if (!cursor->x11.handle)+        return GLFW_FALSE;++    return GLFW_TRUE;+}++int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)+{+    cursor->x11.handle = XCreateFontCursor(_glfw.x11.display,+                                           translateCursorShape(shape));+    if (!cursor->x11.handle)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "X11: Failed to create standard cursor");+        return GLFW_FALSE;+    }++    return GLFW_TRUE;+}++void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)+{+    if (cursor->x11.handle)+        XFreeCursor(_glfw.x11.display, cursor->x11.handle);+}++void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)+{+    if (window->cursorMode == GLFW_CURSOR_NORMAL)+    {+        updateCursorImage(window);+        XFlush(_glfw.x11.display);+    }+}++void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)+{+    free(_glfw.x11.clipboardString);+    _glfw.x11.clipboardString = strdup(string);++    XSetSelectionOwner(_glfw.x11.display,+                       _glfw.x11.CLIPBOARD,+                       window->x11.handle, CurrentTime);++    if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=+        window->x11.handle)+    {+        _glfwInputError(GLFW_PLATFORM_ERROR,+                        "X11: Failed to become owner of clipboard selection");+    }+}++const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)+{+    size_t i;+    const Atom formats[] = { _glfw.x11.UTF8_STRING,+                             _glfw.x11.COMPOUND_STRING,+                             XA_STRING };+    const size_t formatCount = sizeof(formats) / sizeof(formats[0]);++    if (findWindowByHandle(XGetSelectionOwner(_glfw.x11.display,+                                              _glfw.x11.CLIPBOARD)))+    {+        // Instead of doing a large number of X round-trips just to put this+        // string into a window property and then read it back, just return it+        return _glfw.x11.clipboardString;+    }++    free(_glfw.x11.clipboardString);+    _glfw.x11.clipboardString = NULL;++    for (i = 0;  i < formatCount;  i++)+    {+        char* data;+        XEvent event;++        XConvertSelection(_glfw.x11.display,+                          _glfw.x11.CLIPBOARD,+                          formats[i],+                          _glfw.x11.GLFW_SELECTION,+                          window->x11.handle, CurrentTime);++        while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))+            waitForEvent(NULL);++        if (event.xselection.property == None)+            continue;++        if (_glfwGetWindowPropertyX11(event.xselection.requestor,+                                      event.xselection.property,+                                      event.xselection.target,+                                      (unsigned char**) &data))+        {+            _glfw.x11.clipboardString = strdup(data);+        }++        XFree(data);++        XDeleteProperty(_glfw.x11.display,+                        event.xselection.requestor,+                        event.xselection.property);++        if (_glfw.x11.clipboardString)+            break;+    }++    if (_glfw.x11.clipboardString == NULL)+    {+        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,+                        "X11: Failed to convert clipboard to string");+    }++    return _glfw.x11.clipboardString;+}++char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count)+{+    char** extensions;++    *count = 0;++    if (!_glfw.vk.KHR_xcb_surface || !_glfw.x11.x11xcb.handle)+    {+        if (!_glfw.vk.KHR_xlib_surface)+            return NULL;+    }++    extensions = calloc(2, sizeof(char*));+    extensions[0] = strdup("VK_KHR_surface");++    if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)+        extensions[1] = strdup("VK_KHR_xcb_surface");+    else+        extensions[1] = strdup("VK_KHR_xlib_surface");++    *count = 2;+    return extensions;+}++int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,+                                                      VkPhysicalDevice device,+                                                      uint32_t queuefamily)+{+    VisualID visualID = XVisualIDFromVisual(DefaultVisual(_glfw.x11.display,+                                                          _glfw.x11.screen));++    if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)+    {+        PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR =+            (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)+            vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");+        if (!vkGetPhysicalDeviceXcbPresentationSupportKHR)+        {+            _glfwInputError(GLFW_API_UNAVAILABLE,+                            "X11: Vulkan instance missing VK_KHR_xcb_surface extension");+            return GLFW_FALSE;+        }++        xcb_connection_t* connection =+            _glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display);+        if (!connection)+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "X11: Failed to retrieve XCB connection");+            return GLFW_FALSE;+        }++        return vkGetPhysicalDeviceXcbPresentationSupportKHR(device,+                                                            queuefamily,+                                                            connection,+                                                            visualID);+    }+    else+    {+        PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR =+            (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)+            vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");+        if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)+        {+            _glfwInputError(GLFW_API_UNAVAILABLE,+                            "X11: Vulkan instance missing VK_KHR_xlib_surface extension");+            return GLFW_FALSE;+        }++        return vkGetPhysicalDeviceXlibPresentationSupportKHR(device,+                                                             queuefamily,+                                                             _glfw.x11.display,+                                                             visualID);+    }+}++VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,+                                          _GLFWwindow* window,+                                          const VkAllocationCallbacks* allocator,+                                          VkSurfaceKHR* surface)+{+    if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)+    {+        VkResult err;+        VkXcbSurfaceCreateInfoKHR sci;+        PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;++        xcb_connection_t* connection =+            _glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display);+        if (!connection)+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "X11: Failed to retrieve XCB connection");+            return VK_ERROR_EXTENSION_NOT_PRESENT;+        }++        vkCreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)+            vkGetInstanceProcAddr(instance, "vkCreateXcbSurfaceKHR");+        if (!vkCreateXcbSurfaceKHR)+        {+            _glfwInputError(GLFW_API_UNAVAILABLE,+                            "X11: Vulkan instance missing VK_KHR_xcb_surface extension");+            return VK_ERROR_EXTENSION_NOT_PRESENT;+        }++        memset(&sci, 0, sizeof(sci));+        sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;+        sci.connection = connection;+        sci.window = window->x11.handle;++        err = vkCreateXcbSurfaceKHR(instance, &sci, allocator, surface);+        if (err)+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "X11: Failed to create Vulkan XCB surface: %s",+                            _glfwGetVulkanResultString(err));+        }++        return err;+    }+    else+    {+        VkResult err;+        VkXlibSurfaceCreateInfoKHR sci;+        PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;++        vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)+            vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR");+        if (!vkCreateXlibSurfaceKHR)+        {+            _glfwInputError(GLFW_API_UNAVAILABLE,+                            "X11: Vulkan instance missing VK_KHR_xlib_surface extension");+            return VK_ERROR_EXTENSION_NOT_PRESENT;+        }++        memset(&sci, 0, sizeof(sci));+        sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;+        sci.dpy = _glfw.x11.display;+        sci.window = window->x11.handle;++        err = vkCreateXlibSurfaceKHR(instance, &sci, allocator, surface);+        if (err)+        {+            _glfwInputError(GLFW_PLATFORM_ERROR,+                            "X11: Failed to create Vulkan X11 surface: %s",+                            _glfwGetVulkanResultString(err));+        }++        return err;+    } }  
glfw/src/xkb_unicode.c view
@@ -1,8 +1,8 @@ //========================================================================-// GLFW 3.1 X11 - www.glfw.org+// GLFW 3.2 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>+// Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.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@@ -827,24 +827,24 @@   { 0x13be, 0x0178 },   { 0x20ac, 0x20ac },   // Numeric keypad with numlock on-  { XK_KP_Space, ' ' },-  { XK_KP_Equal, '=' },-  { XK_KP_Multiply, '*' },-  { XK_KP_Add, '+' },-  { XK_KP_Separator, ',' },-  { XK_KP_Subtract, '-' },-  { XK_KP_Decimal, '.' },-  { XK_KP_Divide, '/' },-  { XK_KP_0, 0x0030 },-  { XK_KP_1, 0x0031 },-  { XK_KP_2, 0x0032 },-  { XK_KP_3, 0x0033 },-  { XK_KP_4, 0x0034 },-  { XK_KP_5, 0x0035 },-  { XK_KP_6, 0x0036 },-  { XK_KP_7, 0x0037 },-  { XK_KP_8, 0x0038 },-  { XK_KP_9, 0x0039 }+  { 0xff80 /*XKB_KEY_KP_Space*/,     ' ' },+  { 0xffbd /*XKB_KEY_KP_Equal*/,     '=' },+  { 0xffaa /*XKB_KEY_KP_Multiply*/,  '*' },+  { 0xffab /*XKB_KEY_KP_Add*/,       '+' },+  { 0xffac /*XKB_KEY_KP_Separator*/, ',' },+  { 0xffad /*XKB_KEY_KP_Subtract*/,  '-' },+  { 0xffae /*XKB_KEY_KP_Decimal*/,   '.' },+  { 0xffaf /*XKB_KEY_KP_Divide*/,    '/' },+  { 0xffb0 /*XKB_KEY_KP_0*/, 0x0030 },+  { 0xffb1 /*XKB_KEY_KP_1*/, 0x0031 },+  { 0xffb2 /*XKB_KEY_KP_2*/, 0x0032 },+  { 0xffb3 /*XKB_KEY_KP_3*/, 0x0033 },+  { 0xffb4 /*XKB_KEY_KP_4*/, 0x0034 },+  { 0xffb5 /*XKB_KEY_KP_5*/, 0x0035 },+  { 0xffb6 /*XKB_KEY_KP_6*/, 0x0036 },+  { 0xffb7 /*XKB_KEY_KP_7*/, 0x0037 },+  { 0xffb8 /*XKB_KEY_KP_8*/, 0x0038 },+  { 0xffb9 /*XKB_KEY_KP_9*/, 0x0039 } };  
glfw/src/xkb_unicode.h view
@@ -1,5 +1,5 @@ //========================================================================-// GLFW 3.1 Linux - www.glfw.org+// GLFW 3.2 Linux - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> //@@ -24,10 +24,10 @@ // //======================================================================== -#ifndef _xkb_unicode_h_-#define _xkb_unicode_h_+#ifndef _glfw3_xkb_unicode_h_+#define _glfw3_xkb_unicode_h_   long _glfwKeySym2Unicode(unsigned int keysym); -#endif // _xkb_unicode_h_+#endif // _glfw3_xkb_unicode_h_