GLFW-b (empty) → 0.0.1
raw patch · 44 files changed
+15937/−0 lines, 44 filesdep +basesetup-changed
Dependencies added: base
Files
- GLFW-b.cabal +141/−0
- LICENSE +26/−0
- README.md +28/−0
- Setup.hs +6/−0
- glfw/include/GL/glfw.h +509/−0
- glfw/lib/cocoa/cocoa_enable.m +52/−0
- glfw/lib/cocoa/cocoa_fullscreen.m +103/−0
- glfw/lib/cocoa/cocoa_glext.m +64/−0
- glfw/lib/cocoa/cocoa_init.m +241/−0
- glfw/lib/cocoa/cocoa_joystick.m +66/−0
- glfw/lib/cocoa/cocoa_thread.c +416/−0
- glfw/lib/cocoa/cocoa_time.m +106/−0
- glfw/lib/cocoa/cocoa_window.m +880/−0
- glfw/lib/enable.c +310/−0
- glfw/lib/fullscreen.c +95/−0
- glfw/lib/glext.c +211/−0
- glfw/lib/image.c +631/−0
- glfw/lib/init.c +111/−0
- glfw/lib/input.c +280/−0
- glfw/lib/joystick.c +102/−0
- glfw/lib/stream.c +194/−0
- glfw/lib/tga.c +405/−0
- glfw/lib/thread.c +340/−0
- glfw/lib/time.c +83/−0
- glfw/lib/win32/win32_dllmain.c +60/−0
- glfw/lib/win32/win32_enable.c +155/−0
- glfw/lib/win32/win32_fullscreen.c +320/−0
- glfw/lib/win32/win32_glext.c +82/−0
- glfw/lib/win32/win32_init.c +356/−0
- glfw/lib/win32/win32_joystick.c +234/−0
- glfw/lib/win32/win32_thread.c +511/−0
- glfw/lib/win32/win32_time.c +146/−0
- glfw/lib/win32/win32_window.c +1822/−0
- glfw/lib/window.c +981/−0
- glfw/lib/x11/x11_enable.c +55/−0
- glfw/lib/x11/x11_fullscreen.c +528/−0
- glfw/lib/x11/x11_glext.c +90/−0
- glfw/lib/x11/x11_init.c +286/−0
- glfw/lib/x11/x11_joystick.c +367/−0
- glfw/lib/x11/x11_keysym2unicode.c +901/−0
- glfw/lib/x11/x11_thread.c +508/−0
- glfw/lib/x11/x11_time.c +154/−0
- glfw/lib/x11/x11_window.c +1993/−0
- src/Graphics/UI/GLFW.hsc +988/−0
+ GLFW-b.cabal view
@@ -0,0 +1,141 @@+name: GLFW-b+version: 0.0.1++category: Graphics++synopsis: GLFW bindings+description: Bindings to GLFW, a free, open source, multi-platform library for+ creating OpenGL contexts and managing input, including keyboard,+ mouse, joystick and time.+ .+ /GLFW-b does not currently work on Mac OS X./ Sorry.+ .+ Please see README.md+ (<http://github.com/bsl/GLFW-b/blob/master/README.md>) for+ information about how these bindings differ from the ones in the+ GLFW package (<http://hackage.haskell.org/package/GLFW>).+ .+ For more information about the library on which these bindings+ are based, please see <http://glfw.sourceforge.net>.++author: Brian Lewis <brian@lorf.org>+maintainer: Brian Lewis <brian@lorf.org>++license: BSD3+license-file: LICENSE++-- -- -- -- -- -- -- -- -- --++cabal-version: >= 1.6+build-type: Simple++-- -- -- -- -- -- -- -- -- --++extra-source-files:+ README.md+ glfw/include/GL/glfw.h++-- -- -- -- -- -- -- -- -- --++library+ exposed-modules:+ Graphics.UI.GLFW++ build-depends:+ base == 4.*++ hs-source-dirs:+ src++ include-dirs:+ glfw/include+ glfw/lib+ c-sources:+ glfw/lib/enable.c+ glfw/lib/fullscreen.c+ glfw/lib/glext.c+ glfw/lib/image.c+ glfw/lib/init.c+ glfw/lib/input.c+ glfw/lib/joystick.c+ glfw/lib/stream.c+ glfw/lib/tga.c+ glfw/lib/thread.c+ glfw/lib/time.c+ glfw/lib/window.c++ if os(linux)+ include-dirs:+ glfw/lib/x11+ c-sources:+ glfw/lib/x11/x11_enable.c+ glfw/lib/x11/x11_fullscreen.c+ glfw/lib/x11/x11_glext.c+ glfw/lib/x11/x11_init.c+ glfw/lib/x11/x11_joystick.c+ glfw/lib/x11/x11_keysym2unicode.c+ glfw/lib/x11/x11_thread.c+ glfw/lib/x11/x11_time.c+ glfw/lib/x11/x11_window.c+ cc-options:+ -D_GLFW_USE_LINUX_JOYSTICKS+ -D_GLFW_HAS_XRANDR+-- -D_GLFW_HAS_PTHREAD+-- -D_GLFW_HAS_SCHED_YIELD+ -D_GLFW_HAS_GLXGETPROCADDRESS+-- -D_GLFW_HAS_DLOPEN+-- -D_GLFW_HAS_SYSCONF+-- -pthread+ -O2+ extra-libraries:+ GL+ GLU+ X11+ Xrandr+ else+ if os(darwin)+ include-dirs:+ glfw/lib/cocoa+ c-sources:+ glfw/lib/cocoa/cocoa_enable.m+ glfw/lib/cocoa/cocoa_fullscreen.m+ glfw/lib/cocoa/cocoa_glext.m+ glfw/lib/cocoa/cocoa_init.m+ glfw/lib/cocoa/cocoa_joystick.m+ glfw/lib/cocoa/cocoa_thread.c+ glfw/lib/cocoa/cocoa_time.m+ glfw/lib/cocoa/cocoa_window.m+ cc-options:+ -O2+ frameworks:+ AGL+ Cocoa+ OpenGL+ else+ if os(mingw32)+ include-dirs:+ glfw/lib/win32+ c-sources:+ glfw/lib/win32/win32_dllmain.c+ glfw/lib/win32/win32_enable.c+ glfw/lib/win32/win32_fullscreen.c+ glfw/lib/win32/win32_glext.c+ glfw/lib/win32/win32_init.c+ glfw/lib/win32/win32_joystick.c+ glfw/lib/win32/win32_thread.c+ glfw/lib/win32/win32_time.c+ glfw/lib/win32/win32_window.c+ cc-options:+ -O2+ extra-libraries:+ opengl32++ ghc-options: -Wall -O2+ if impl(ghc >= 6.8)+ ghc-options: -fwarn-tabs++-- -- -- -- -- -- -- -- -- --++source-repository head+ type: git+ location: git://github.com/bsl/GLFW-b.git
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright Brian Lewis <brian@lorf.org> 2009++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,28 @@+Differences between GLFW and GLFW-b 2010.01+===========================================++* GLFW binds to version 2.6 of the GLFW C library. GLFW-b binds to 2.7. GLFW+ 2.7 is partially written in Objective C. This is a problem for Cabal, so+ _GLFW-b does not currently work on Mac OS X._++* Some GLFW functions return OpenGL {Gettable,Settable}StateVars. I don't like+ this because it adds an extra step to extract a value and causes GLFW to be+ dependent on OpenGL. GLFW-b doesn't depend on OpenGL.++* GLFW sometimes depends on GLFW C library internally defined values. GLFW-b+ doesn't. For example, GLFW-b doesn't assume that GL\_FALSE = 0. I don't think+ this makes a difference in practice, but it makes me feel better.++* GLFW sometimes assumes that certain Haskell types are equivalent to certain C+ types, e.g. Int and int. GLFW-b doesn't. GLFW-b always uses the appropriate+ type from Foreign.C.Types. I don't think this makes a difference in practice,+ but it makes me feel better.++* GLFW contains workarounds for a bugs in GHC < 6.10 FFI. GLFW-b doesn't.++* GLFW's API is pretty faithful to the C API. GLFW-b prefers to use full words+ and self-explanatory function names.++* In GLFW-b, registering hints and opening a window are combined into one step.++* GLFW has support for loading textures and rendering strings. GLFW-b doesn't.
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Distribution.Simple (defaultMain)++main :: IO ()+main = defaultMain
+ glfw/include/GL/glfw.h view
@@ -0,0 +1,509 @@+/************************************************************************+ * GLFW - An OpenGL framework+ * File: glfw.h+ * API version: 2.7+ * WWW: http://glfw.sourceforge.net+ *------------------------------------------------------------------------+ * Copyright (c) 2002-2006 Camilla Berglund+ *+ * This software is provided 'as-is', without any express or implied+ * warranty. In no event will the authors be held liable for any damages+ * arising from the use of this software.+ *+ * Permission is granted to anyone to use this software for any purpose,+ * including commercial applications, and to alter it and redistribute it+ * freely, subject to the following restrictions:+ *+ * 1. The origin of this software must not be misrepresented; you must not+ * claim that you wrote the original software. If you use this software+ * in a product, an acknowledgment in the product documentation would+ * be appreciated but is not required.+ *+ * 2. Altered source versions must be plainly marked as such, and must not+ * be misrepresented as being the original software.+ *+ * 3. This notice may not be removed or altered from any source+ * distribution.+ *+ *************************************************************************/++#ifndef __glfw_h_+#define __glfw_h_++#ifdef __cplusplus+extern "C" {+#endif+++/*************************************************************************+ * Global definitions+ *************************************************************************/++/* We need a NULL pointer from time to time */+#ifndef NULL+ #ifdef __cplusplus+ #define NULL 0+ #else+ #define NULL ((void *)0)+ #endif+#endif /* NULL */+++/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */++/* Please report any probles 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+ #define GL_APIENTRY_DEFINED+#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 GL_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 GLU_CALLBACK_DEFINED+#endif /* CALLBACK */++/* Microsoft Visual C++, Borland C++ and Pelles C <GL*glu.h> needs wchar_t */+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)) && !defined(_WCHAR_T_DEFINED)+ typedef unsigned short wchar_t;+ #define _WCHAR_T_DEFINED+#endif /* _WCHAR_T_DEFINED */+++/* ---------------- GLFW related system specific defines ----------------- */++#if defined(_WIN32) && defined(GLFW_BUILD_DLL)++ /* We are building a Win32 DLL */+ #define GLFWAPI __declspec(dllexport)+ #define GLFWAPIENTRY __stdcall+ #define GLFWCALL __stdcall++#elif defined(_WIN32) && defined(GLFW_DLL)++ /* We are calling a Win32 DLL */+ #if defined(__LCC__)+ #define GLFWAPI extern+ #else+ #define GLFWAPI __declspec(dllimport)+ #endif+ #define GLFWAPIENTRY __stdcall+ #define GLFWCALL __stdcall++#else++ /* We are either building/calling a static lib or we are non-win32 */+ #define GLFWAPIENTRY+ #define GLFWAPI+ #define GLFWCALL++#endif++/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */++/* Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is+ * convenient for the user to only have to include <GL/glfw.h>. This also+ * solves the problem with Windows <GL/gl.h> and <GL/glu.h> needing some+ * special defines which normally requires the user to include <windows.h>+ * (which is not a nice solution for portable programs).+ */+#if defined(__APPLE_CC__)+ #include <OpenGL/gl.h>+ #ifndef GLFW_NO_GLU+ #include <OpenGL/glu.h>+ #endif+#else+ #include <GL/gl.h>+ #ifndef GLFW_NO_GLU+ #include <GL/glu.h>+ #endif+#endif+++/*************************************************************************+ * GLFW version+ *************************************************************************/++#define GLFW_VERSION_MAJOR 2+#define GLFW_VERSION_MINOR 7+#define GLFW_VERSION_REVISION 0+++/*************************************************************************+ * Input handling definitions+ *************************************************************************/++/* Key and button state/action definitions */+#define GLFW_RELEASE 0+#define GLFW_PRESS 1++/* Keyboard key definitions: 8-bit ISO-8859-1 (Latin 1) encoding is used+ * for printable keys (such as A-Z, 0-9 etc), and values above 256+ * represent special (non-printable) keys (e.g. F1, Page Up etc).+ */+#define GLFW_KEY_UNKNOWN -1+#define GLFW_KEY_SPACE 32+#define GLFW_KEY_SPECIAL 256+#define GLFW_KEY_ESC (GLFW_KEY_SPECIAL+1)+#define GLFW_KEY_F1 (GLFW_KEY_SPECIAL+2)+#define GLFW_KEY_F2 (GLFW_KEY_SPECIAL+3)+#define GLFW_KEY_F3 (GLFW_KEY_SPECIAL+4)+#define GLFW_KEY_F4 (GLFW_KEY_SPECIAL+5)+#define GLFW_KEY_F5 (GLFW_KEY_SPECIAL+6)+#define GLFW_KEY_F6 (GLFW_KEY_SPECIAL+7)+#define GLFW_KEY_F7 (GLFW_KEY_SPECIAL+8)+#define GLFW_KEY_F8 (GLFW_KEY_SPECIAL+9)+#define GLFW_KEY_F9 (GLFW_KEY_SPECIAL+10)+#define GLFW_KEY_F10 (GLFW_KEY_SPECIAL+11)+#define GLFW_KEY_F11 (GLFW_KEY_SPECIAL+12)+#define GLFW_KEY_F12 (GLFW_KEY_SPECIAL+13)+#define GLFW_KEY_F13 (GLFW_KEY_SPECIAL+14)+#define GLFW_KEY_F14 (GLFW_KEY_SPECIAL+15)+#define GLFW_KEY_F15 (GLFW_KEY_SPECIAL+16)+#define GLFW_KEY_F16 (GLFW_KEY_SPECIAL+17)+#define GLFW_KEY_F17 (GLFW_KEY_SPECIAL+18)+#define GLFW_KEY_F18 (GLFW_KEY_SPECIAL+19)+#define GLFW_KEY_F19 (GLFW_KEY_SPECIAL+20)+#define GLFW_KEY_F20 (GLFW_KEY_SPECIAL+21)+#define GLFW_KEY_F21 (GLFW_KEY_SPECIAL+22)+#define GLFW_KEY_F22 (GLFW_KEY_SPECIAL+23)+#define GLFW_KEY_F23 (GLFW_KEY_SPECIAL+24)+#define GLFW_KEY_F24 (GLFW_KEY_SPECIAL+25)+#define GLFW_KEY_F25 (GLFW_KEY_SPECIAL+26)+#define GLFW_KEY_UP (GLFW_KEY_SPECIAL+27)+#define GLFW_KEY_DOWN (GLFW_KEY_SPECIAL+28)+#define GLFW_KEY_LEFT (GLFW_KEY_SPECIAL+29)+#define GLFW_KEY_RIGHT (GLFW_KEY_SPECIAL+30)+#define GLFW_KEY_LSHIFT (GLFW_KEY_SPECIAL+31)+#define GLFW_KEY_RSHIFT (GLFW_KEY_SPECIAL+32)+#define GLFW_KEY_LCTRL (GLFW_KEY_SPECIAL+33)+#define GLFW_KEY_RCTRL (GLFW_KEY_SPECIAL+34)+#define GLFW_KEY_LALT (GLFW_KEY_SPECIAL+35)+#define GLFW_KEY_RALT (GLFW_KEY_SPECIAL+36)+#define GLFW_KEY_TAB (GLFW_KEY_SPECIAL+37)+#define GLFW_KEY_ENTER (GLFW_KEY_SPECIAL+38)+#define GLFW_KEY_BACKSPACE (GLFW_KEY_SPECIAL+39)+#define GLFW_KEY_INSERT (GLFW_KEY_SPECIAL+40)+#define GLFW_KEY_DEL (GLFW_KEY_SPECIAL+41)+#define GLFW_KEY_PAGEUP (GLFW_KEY_SPECIAL+42)+#define GLFW_KEY_PAGEDOWN (GLFW_KEY_SPECIAL+43)+#define GLFW_KEY_HOME (GLFW_KEY_SPECIAL+44)+#define GLFW_KEY_END (GLFW_KEY_SPECIAL+45)+#define GLFW_KEY_KP_0 (GLFW_KEY_SPECIAL+46)+#define GLFW_KEY_KP_1 (GLFW_KEY_SPECIAL+47)+#define GLFW_KEY_KP_2 (GLFW_KEY_SPECIAL+48)+#define GLFW_KEY_KP_3 (GLFW_KEY_SPECIAL+49)+#define GLFW_KEY_KP_4 (GLFW_KEY_SPECIAL+50)+#define GLFW_KEY_KP_5 (GLFW_KEY_SPECIAL+51)+#define GLFW_KEY_KP_6 (GLFW_KEY_SPECIAL+52)+#define GLFW_KEY_KP_7 (GLFW_KEY_SPECIAL+53)+#define GLFW_KEY_KP_8 (GLFW_KEY_SPECIAL+54)+#define GLFW_KEY_KP_9 (GLFW_KEY_SPECIAL+55)+#define GLFW_KEY_KP_DIVIDE (GLFW_KEY_SPECIAL+56)+#define GLFW_KEY_KP_MULTIPLY (GLFW_KEY_SPECIAL+57)+#define GLFW_KEY_KP_SUBTRACT (GLFW_KEY_SPECIAL+58)+#define GLFW_KEY_KP_ADD (GLFW_KEY_SPECIAL+59)+#define GLFW_KEY_KP_DECIMAL (GLFW_KEY_SPECIAL+60)+#define GLFW_KEY_KP_EQUAL (GLFW_KEY_SPECIAL+61)+#define GLFW_KEY_KP_ENTER (GLFW_KEY_SPECIAL+62)+#define GLFW_KEY_KP_NUM_LOCK (GLFW_KEY_SPECIAL+63)+#define GLFW_KEY_CAPS_LOCK (GLFW_KEY_SPECIAL+64)+#define GLFW_KEY_SCROLL_LOCK (GLFW_KEY_SPECIAL+65)+#define GLFW_KEY_PAUSE (GLFW_KEY_SPECIAL+66)+#define GLFW_KEY_LSUPER (GLFW_KEY_SPECIAL+67)+#define GLFW_KEY_RSUPER (GLFW_KEY_SPECIAL+68)+#define GLFW_KEY_MENU (GLFW_KEY_SPECIAL+69)+#define GLFW_KEY_LAST GLFW_KEY_MENU++/* Mouse button definitions */+#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++/* Mouse button aliases */+#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+++/* Joystick identifiers */+#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+++/*************************************************************************+ * Other definitions+ *************************************************************************/++/* glfwOpenWindow modes */+#define GLFW_WINDOW 0x00010001+#define GLFW_FULLSCREEN 0x00010002++/* glfwGetWindowParam tokens */+#define GLFW_OPENED 0x00020001+#define GLFW_ACTIVE 0x00020002+#define GLFW_ICONIFIED 0x00020003+#define GLFW_ACCELERATED 0x00020004+#define GLFW_RED_BITS 0x00020005+#define GLFW_GREEN_BITS 0x00020006+#define GLFW_BLUE_BITS 0x00020007+#define GLFW_ALPHA_BITS 0x00020008+#define GLFW_DEPTH_BITS 0x00020009+#define GLFW_STENCIL_BITS 0x0002000A++/* The following constants are used for both glfwGetWindowParam+ * and glfwOpenWindowHint+ */+#define GLFW_REFRESH_RATE 0x0002000B+#define GLFW_ACCUM_RED_BITS 0x0002000C+#define GLFW_ACCUM_GREEN_BITS 0x0002000D+#define GLFW_ACCUM_BLUE_BITS 0x0002000E+#define GLFW_ACCUM_ALPHA_BITS 0x0002000F+#define GLFW_AUX_BUFFERS 0x00020010+#define GLFW_STEREO 0x00020011+#define GLFW_WINDOW_NO_RESIZE 0x00020012+#define GLFW_FSAA_SAMPLES 0x00020013+#define GLFW_OPENGL_VERSION_MAJOR 0x00020014+#define GLFW_OPENGL_VERSION_MINOR 0x00020015+#define GLFW_OPENGL_FORWARD_COMPAT 0x00020016+#define GLFW_OPENGL_DEBUG_CONTEXT 0x00020017+#define GLFW_OPENGL_PROFILE 0x00020018++/* GLFW_OPENGL_PROFILE tokens */+#define GLFW_OPENGL_CORE_PROFILE 0x00050001+#define GLFW_OPENGL_COMPAT_PROFILE 0x00050002++/* glfwEnable/glfwDisable tokens */+#define GLFW_MOUSE_CURSOR 0x00030001+#define GLFW_STICKY_KEYS 0x00030002+#define GLFW_STICKY_MOUSE_BUTTONS 0x00030003+#define GLFW_SYSTEM_KEYS 0x00030004+#define GLFW_KEY_REPEAT 0x00030005+#define GLFW_AUTO_POLL_EVENTS 0x00030006++/* glfwWaitThread wait modes */+#define GLFW_WAIT 0x00040001+#define GLFW_NOWAIT 0x00040002++/* glfwGetJoystickParam tokens */+#define GLFW_PRESENT 0x00050001+#define GLFW_AXES 0x00050002+#define GLFW_BUTTONS 0x00050003++/* glfwReadImage/glfwLoadTexture2D flags */+#define GLFW_NO_RESCALE_BIT 0x00000001 /* Only for glfwReadImage */+#define GLFW_ORIGIN_UL_BIT 0x00000002+#define GLFW_BUILD_MIPMAPS_BIT 0x00000004 /* Only for glfwLoadTexture2D */+#define GLFW_ALPHA_MAP_BIT 0x00000008++/* Time spans longer than this (seconds) are considered to be infinity */+#define GLFW_INFINITY 100000.0+++/*************************************************************************+ * Typedefs+ *************************************************************************/++/* The video mode structure used by glfwGetVideoModes() */+typedef struct {+ int Width, Height;+ int RedBits, BlueBits, GreenBits;+} GLFWvidmode;++/* Image/texture information */+typedef struct {+ int Width, Height;+ int Format;+ int BytesPerPixel;+ unsigned char *Data;+} GLFWimage;++/* Thread ID */+typedef int GLFWthread;++/* Mutex object */+typedef void * GLFWmutex;++/* Condition variable object */+typedef void * GLFWcond;++/* Function pointer types */+typedef void (GLFWCALL * GLFWwindowsizefun)(int,int);+typedef int (GLFWCALL * GLFWwindowclosefun)(void);+typedef void (GLFWCALL * GLFWwindowrefreshfun)(void);+typedef void (GLFWCALL * GLFWmousebuttonfun)(int,int);+typedef void (GLFWCALL * GLFWmouseposfun)(int,int);+typedef void (GLFWCALL * GLFWmousewheelfun)(int);+typedef void (GLFWCALL * GLFWkeyfun)(int,int);+typedef void (GLFWCALL * GLFWcharfun)(int,int);+typedef void (GLFWCALL * GLFWthreadfun)(void *);+++/*************************************************************************+ * Prototypes+ *************************************************************************/++/* GLFW initialization, termination and version querying */+GLFWAPI int GLFWAPIENTRY glfwInit( void );+GLFWAPI void GLFWAPIENTRY glfwTerminate( void );+GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor, int *rev );++/* Window handling */+GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode );+GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint );+GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void );+GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title );+GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height );+GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height );+GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y );+GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void );+GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void );+GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void );+GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval );+GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param );+GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun );++/* Video mode functions */+GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list, int maxcount );+GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode );++/* Input handling */+GLFWAPI void GLFWAPIENTRY glfwPollEvents( void );+GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void );+GLFWAPI int GLFWAPIENTRY glfwGetKey( int key );+GLFWAPI int GLFWAPIENTRY glfwGetMouseButton( int button );+GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos );+GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos );+GLFWAPI int GLFWAPIENTRY glfwGetMouseWheel( void );+GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos );+GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun );++/* Joystick input */+GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param );+GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos, int numaxes );+GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons );++/* Time */+GLFWAPI double GLFWAPIENTRY glfwGetTime( void );+GLFWAPI void GLFWAPIENTRY glfwSetTime( double time );+GLFWAPI void GLFWAPIENTRY glfwSleep( double time );++/* Extension support */+GLFWAPI int GLFWAPIENTRY glfwExtensionSupported( const char *extension );+GLFWAPI void* GLFWAPIENTRY glfwGetProcAddress( const char *procname );+GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, int *rev );++/* Threading support */+GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun, void *arg );+GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID );+GLFWAPI int GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode );+GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void );+GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void );+GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex );+GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex );+GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex );+GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void );+GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond );+GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout );+GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond );+GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond );+GLFWAPI int GLFWAPIENTRY glfwGetNumberOfProcessors( void );++/* Enable/disable functions */+GLFWAPI void GLFWAPIENTRY glfwEnable( int token );+GLFWAPI void GLFWAPIENTRY glfwDisable( int token );++/* Image/texture I/O support */+GLFWAPI int GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img, int flags );+GLFWAPI int GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags );+GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img );+GLFWAPI int GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags );+GLFWAPI int GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags );+GLFWAPI int GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags );+++#ifdef __cplusplus+}+#endif++#endif /* __glfw_h_ */+
+ glfw/lib/cocoa/cocoa_enable.m view
@@ -0,0 +1,52 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_enable.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Enable and disable system keys+//========================================================================++void _glfwPlatformEnableSystemKeys( void )+{+ // This is checked in macosx_window.m; we take no action here+}++void _glfwPlatformDisableSystemKeys( void )+{+ // This is checked in macosx_window.m; we take no action here+ // I don't think it's really possible to disable stuff like Exposé+ // except in full-screen mode.+}+
+ glfw/lib/cocoa/cocoa_fullscreen.m view
@@ -0,0 +1,103 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_fullscreen.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//========================================================================+// Check whether the display mode should be included in enumeration+//========================================================================++static BOOL modeIsGood( NSDictionary *mode )+{+ // This is a bit controversial, if you've got something other than an+ // LCD computer monitor as an output device you might not want these+ // checks. You might also want to reject modes which are interlaced,+ // or TV out. There is no one-size-fits-all policy that can work here.+ // This seems like a decent compromise, but certain applications may+ // wish to patch this...+ return [[mode objectForKey:(id)kCGDisplayBitsPerPixel] intValue] >= 15 &&+ [mode objectForKey:(id)kCGDisplayModeIsSafeForHardware] != nil &&+ [mode objectForKey:(id)kCGDisplayModeIsStretched] == nil;+}++//========================================================================+// Convert Core Graphics display mode to GLFW video mode+//========================================================================++static GLFWvidmode vidmodeFromCGDisplayMode( NSDictionary *mode )+{+ unsigned int width = [[mode objectForKey:(id)kCGDisplayWidth] unsignedIntValue];+ unsigned int height = [[mode objectForKey:(id)kCGDisplayHeight] unsignedIntValue];+ unsigned int bps = [[mode objectForKey:(id)kCGDisplayBitsPerSample] unsignedIntValue];++ GLFWvidmode result;+ result.Width = width;+ result.Height = height;+ result.RedBits = bps;+ result.GreenBits = bps;+ result.BlueBits = bps;+ return result;+}+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Get a list of available video modes+//========================================================================++int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )+{+ NSArray *modes = (NSArray *)CGDisplayAvailableModes( CGMainDisplayID() );++ unsigned int i, j = 0, n = [modes count];+ for( i = 0; i < n && i < (unsigned)maxcount; i++ )+ {+ NSDictionary *mode = [modes objectAtIndex:i];+ if( modeIsGood( mode ) )+ {+ list[j++] = vidmodeFromCGDisplayMode( mode );+ }+ }++ return j;+}++//========================================================================+// Get the desktop video mode+//========================================================================++void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )+{+ *mode = vidmodeFromCGDisplayMode( _glfwLibrary.DesktopMode );+}+
+ glfw/lib/cocoa/cocoa_glext.m view
@@ -0,0 +1,64 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_glext.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Check if an OpenGL extension is available at runtime+//========================================================================++int _glfwPlatformExtensionSupported( const char *extension )+{+ // There are no AGL, CGL or NSGL extensions.+ return GL_FALSE;+}++//========================================================================+// Get the function pointer to an OpenGL function+//========================================================================++void * _glfwPlatformGetProcAddress( const char *procname )+{+ CFStringRef symbolName = CFStringCreateWithCString( kCFAllocatorDefault,+ procname,+ kCFStringEncodingASCII );++ void *symbol = CFBundleGetFunctionPointerForName( _glfwLibrary.OpenGLFramework,+ symbolName );++ CFRelease( symbolName );++ return symbol;+}+
+ glfw/lib/cocoa/cocoa_init.m view
@@ -0,0 +1,241 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_init.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++// Needed for _NSGetProgname+#include <crt_externs.h>++#include "internal.h"++// Prior to Snow Leopard, we need to use this oddly-named semi-private API+// to get the application menu working properly. Need to be careful in+// case it goes away in a future OS update.+@interface NSApplication (NSAppleMenu)+- (void)setAppleMenu:(NSMenu *)m;+@end++// Keys to search for as potential application names+NSString *GLFWNameKeys[] =+{+ @"CFBundleDisplayName",+ @"CFBundleName",+ @"CFBundleExecutable",+};++//========================================================================+// Try to figure out what the calling application is called+//========================================================================+static NSString *findAppName( void )+{+ NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];++ unsigned int i;+ for( i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++ )+ {+ id name = [infoDictionary objectForKey:GLFWNameKeys[i]];+ if (name &&+ [name isKindOfClass:[NSString class]] &&+ ![@"" isEqualToString:name])+ {+ return name;+ }+ }++ // If we get here, we're unbundled+ if( !_glfwLibrary.Unbundled )+ {+ // Could do this only if we discover we're unbundled, but it should+ // do no harm...+ ProcessSerialNumber psn = { 0, kCurrentProcess };+ TransformProcessType( &psn, kProcessTransformToForegroundApplication );++ // Having the app in front of the terminal window is also generally+ // handy. There is an NSApplication API to do this, but...+ SetFrontProcess( &psn );++ _glfwLibrary.Unbundled = GL_TRUE;+ }++ char **progname = _NSGetProgname();+ if( progname && *progname )+ {+ // TODO: UTF8?+ return [NSString stringWithUTF8String:*progname];+ }++ // Really shouldn't get here+ return @"GLFW Application";+}++//========================================================================+// Set up the menu bar (manually)+// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that+// could go away at any moment, lots of stuff that really should be+// localize(d|able), etc. Loading a nib would save us this horror, but that+// doesn't seem like a good thing to require of GLFW's clients.+//========================================================================+static void setUpMenuBar( void )+{+ NSString *appName = findAppName();++ NSMenu *bar = [[NSMenu alloc] init];+ [NSApp setMainMenu:bar];++ NSMenuItem *appMenuItem =+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];+ NSMenu *appMenu = [[NSMenu alloc] init];+ [appMenuItem setSubmenu:appMenu];++ [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]+ action:@selector(orderFrontStandardAboutPanel:)+ keyEquivalent:@""];+ [appMenu addItem:[NSMenuItem separatorItem]];+ NSMenu *servicesMenu = [[NSMenu alloc] init];+ [NSApp setServicesMenu:servicesMenu];+ [[appMenu addItemWithTitle:@"Services"+ action:NULL+ keyEquivalent:@""] setSubmenu:servicesMenu];+ [appMenu addItem:[NSMenuItem separatorItem]];+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]+ action:@selector(hide:)+ keyEquivalent:@"h"];+ [[appMenu addItemWithTitle:@"Hide Others"+ action:@selector(hideOtherApplications:)+ keyEquivalent:@"h"]+ setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];+ [appMenu addItemWithTitle:@"Show All"+ action:@selector(unhideAllApplications:)+ keyEquivalent:@""];+ [appMenu addItem:[NSMenuItem separatorItem]];+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]+ action:@selector(terminate:)+ keyEquivalent:@"q"];++ NSMenuItem *windowMenuItem =+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];+ NSMenu *windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];+ [NSApp setWindowsMenu:windowMenu];+ [windowMenuItem setSubmenu:windowMenu];++ [windowMenu addItemWithTitle:@"Miniaturize"+ action:@selector(performMiniaturize:)+ keyEquivalent:@"m"];+ [windowMenu addItemWithTitle:@"Zoom"+ action:@selector(performZoom:)+ keyEquivalent:@""];+ [windowMenu addItem:[NSMenuItem separatorItem]];+ [windowMenu addItemWithTitle:@"Bring All to Front"+ action:@selector(arrangeInFront:)+ keyEquivalent:@""];++ // At least guard the call to private API to avoid an exception if it+ // goes away. Hopefully that means the worst we'll break in future is to+ // look ugly...+ if( [NSApp respondsToSelector:@selector(setAppleMenu:)] )+ {+ [NSApp setAppleMenu:appMenu];+ }+}++//========================================================================+// Initialize GLFW thread package+//========================================================================++static void initThreads( void )+{+ // Initialize critical section handle+ (void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL );++ // The first thread (the main thread) has ID 0+ _glfwThrd.NextID = 0;++ // Fill out information about the main thread (this thread)+ _glfwThrd.First.ID = _glfwThrd.NextID ++;+ _glfwThrd.First.Function = NULL;+ _glfwThrd.First.PosixID = pthread_self();+ _glfwThrd.First.Previous = NULL;+ _glfwThrd.First.Next = NULL;+}++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Initialize the GLFW library+//========================================================================++int _glfwPlatformInit( void )+{+ _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init];++ // Implicitly create shared NSApplication instance+ [NSApplication sharedApplication];++ NSString* resourcePath = [[NSBundle mainBundle] resourcePath];++ if( access( [resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK ) == 0 )+ {+ chdir( [resourcePath cStringUsingEncoding:NSUTF8StringEncoding] );+ }++ // Setting up menu bar must go exactly here else weirdness ensues+ setUpMenuBar();++ [NSApp finishLaunching];++ initThreads();++ _glfwPlatformSetTime( 0.0 );++ _glfwLibrary.DesktopMode =+ (NSDictionary *)CGDisplayCurrentMode( CGMainDisplayID() );++ return GL_TRUE;+}++//========================================================================+// Close window, if open, and shut down GLFW+//========================================================================++int _glfwPlatformTerminate( void )+{+ // TODO: Fail unless this is the main thread++ glfwCloseWindow();++ // TODO: Kill all non-main threads?+ // TODO: Probably other cleanup++ [_glfwLibrary.AutoreleasePool release];+ _glfwLibrary.AutoreleasePool = nil;++ return GL_TRUE;+}+
+ glfw/lib/cocoa/cocoa_joystick.m view
@@ -0,0 +1,66 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_joystick.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Determine joystick capabilities+//========================================================================++int _glfwPlatformGetJoystickParam( int joy, int param )+{+ // TODO: Implement this.+ return 0;+}++//========================================================================+// Get joystick axis positions+//========================================================================++int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )+{+ // TODO: Implement this.+ return 0;+}++//========================================================================+// Get joystick button states+//========================================================================++int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons )+{+ // TODO: Implement this.+ return 0;+}+
+ glfw/lib/cocoa/cocoa_thread.c view
@@ -0,0 +1,416 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_thread.c+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++#include <sys/time.h>+#include <sys/sysctl.h>+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// _glfwNewThread() - This is simply a "wrapper" for calling the user+// thread function.+//========================================================================++void * _glfwNewThread( void * arg )+{+ GLFWthreadfun threadfun;+ _GLFWthread *t;++ // Get pointer to thread information for current thread+ t = _glfwGetThreadPointer( glfwGetThreadID() );+ if( t == NULL )+ {+ return 0;+ }++ // Get user thread function pointer+ threadfun = t->Function;++ // Call the user thread function+ threadfun( arg );++ // Remove thread from thread list+ ENTER_THREAD_CRITICAL_SECTION+ _glfwRemoveThread( t );+ LEAVE_THREAD_CRITICAL_SECTION++ // When the thread function returns, the thread will die...+ return NULL;+}++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// _glfwPlatformCreateThread() - Create a new thread+//========================================================================++GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )+{+ GLFWthread ID;+ _GLFWthread *t;+ int result;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Create a new thread information memory area+ t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );+ if( t == NULL )+ {+ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION+ return -1;+ }++ // Get a new unique thread id+ ID = _glfwThrd.NextID ++;++ // Store thread information in the thread list+ t->Function = fun;+ t->ID = ID;++ // Create thread+ result = pthread_create(+ &t->PosixID, // Thread handle+ NULL, // Default thread attributes+ _glfwNewThread, // Thread function (a wrapper function)+ (void *)arg // Argument to thread is user argument+ );++ // Did the thread creation fail?+ if( result != 0 )+ {+ free( (void *) t );+ LEAVE_THREAD_CRITICAL_SECTION+ return -1;+ }++ // Append thread to thread list+ _glfwAppendThread( t );++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Return the GLFW thread ID+ return ID;+}+++//========================================================================+// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY+// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME+// SITUATIONS!+//========================================================================++void _glfwPlatformDestroyThread( GLFWthread ID )+{+ _GLFWthread *t;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Get thread information pointer+ t = _glfwGetThreadPointer( ID );+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return;+ }++ // Simply murder the process, no mercy!+ pthread_kill( t->PosixID, SIGKILL );++ // Remove thread from thread list+ _glfwRemoveThread( t );++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION+}+++//========================================================================+// _glfwPlatformWaitThread() - Wait for a thread to die+//========================================================================++int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )+{+ pthread_t thread;+ _GLFWthread *t;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Get thread information pointer+ t = _glfwGetThreadPointer( ID );++ // Is the thread already dead?+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return GL_TRUE;+ }++ // If got this far, the thread is alive => polling returns FALSE+ if( waitmode == GLFW_NOWAIT )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return GL_FALSE;+ }++ // Get thread handle+ thread = t->PosixID;++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Wait for thread to die+ (void) pthread_join( thread, NULL );++ return GL_TRUE;+}+++//========================================================================+// _glfwPlatformGetThreadID() - Return the thread ID for the current+// thread+//========================================================================++GLFWthread _glfwPlatformGetThreadID( void )+{+ _GLFWthread *t;+ GLFWthread ID = -1;+ pthread_t posixID;++ // Get current thread ID+ posixID = pthread_self();++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Loop through entire list of threads to find the matching POSIX+ // thread ID+ for( t = &_glfwThrd.First; t != NULL; t = t->Next )+ {+ if( t->PosixID == posixID )+ {+ ID = t->ID;+ break;+ }+ }++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Return the found GLFW thread identifier+ return ID;+}+++//========================================================================+// _glfwPlatformCreateMutex() - Create a mutual exclusion object+//========================================================================++GLFWmutex _glfwPlatformCreateMutex( void )+{+ pthread_mutex_t *mutex;++ // Allocate memory for mutex+ mutex = (pthread_mutex_t *) malloc( sizeof( pthread_mutex_t ) );+ if( !mutex )+ {+ return NULL;+ }++ // Initialise a mutex object+ (void) pthread_mutex_init( mutex, NULL );++ // Cast to GLFWmutex and return+ return (GLFWmutex) mutex;+}+++//========================================================================+// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object+//========================================================================++void _glfwPlatformDestroyMutex( GLFWmutex mutex )+{+ // Destroy the mutex object+ pthread_mutex_destroy( (pthread_mutex_t *) mutex );++ // Free memory for mutex object+ free( (void *) mutex );+}+++//========================================================================+// _glfwPlatformLockMutex() - Request access to a mutex+//========================================================================++void _glfwPlatformLockMutex( GLFWmutex mutex )+{+ // Wait for mutex to be released+ (void) pthread_mutex_lock( (pthread_mutex_t *) mutex );+}+++//========================================================================+// _glfwPlatformUnlockMutex() - Release a mutex+//========================================================================++void _glfwPlatformUnlockMutex( GLFWmutex mutex )+{+ // Release mutex+ pthread_mutex_unlock( (pthread_mutex_t *) mutex );+}+++//========================================================================+// _glfwPlatformCreateCond() - Create a new condition variable object+//========================================================================++GLFWcond _glfwPlatformCreateCond( void )+{+ pthread_cond_t *cond;++ // Allocate memory for condition variable+ cond = (pthread_cond_t *) malloc( sizeof(pthread_cond_t) );+ if( !cond )+ {+ return NULL;+ }++ // Initialise condition variable+ (void) pthread_cond_init( cond, NULL );++ // Cast to GLFWcond and return+ return (GLFWcond) cond;+}+++//========================================================================+// _glfwPlatformDestroyCond() - Destroy a condition variable object+//========================================================================++void _glfwPlatformDestroyCond( GLFWcond cond )+{+ // Destroy the condition variable object+ (void) pthread_cond_destroy( (pthread_cond_t *) cond );++ // Free memory for condition variable object+ free( (void *) cond );+}+++//========================================================================+// _glfwPlatformWaitCond() - Wait for a condition to be raised+//========================================================================++void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,+ double timeout )+{+ struct timeval currenttime;+ struct timespec wait;+ long dt_sec, dt_usec;++ // Select infinite or timed wait+ if( timeout >= GLFW_INFINITY )+ {+ // Wait for condition (infinite wait)+ (void) pthread_cond_wait( (pthread_cond_t *) cond,+ (pthread_mutex_t *) mutex );+ }+ else+ {+ // Set timeout time, relatvie to current time+ gettimeofday( ¤ttime, NULL );+ dt_sec = (long) timeout;+ dt_usec = (long) ((timeout - (double)dt_sec) * 1000000.0);+ wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;+ if( wait.tv_nsec > 1000000000L )+ {+ wait.tv_nsec -= 1000000000L;+ dt_sec ++;+ }+ wait.tv_sec = currenttime.tv_sec + dt_sec;++ // Wait for condition (timed wait)+ (void) pthread_cond_timedwait( (pthread_cond_t *) cond,+ (pthread_mutex_t *) mutex, &wait );+ }+}+++//========================================================================+// _glfwPlatformSignalCond() - Signal a condition to one waiting thread+//========================================================================++void _glfwPlatformSignalCond( GLFWcond cond )+{+ // Signal condition+ (void) pthread_cond_signal( (pthread_cond_t *) cond );+}+++//========================================================================+// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting+// threads+//========================================================================++void _glfwPlatformBroadcastCond( GLFWcond cond )+{+ // Broadcast condition+ (void) pthread_cond_broadcast( (pthread_cond_t *) cond );+}+++//========================================================================+// _glfwPlatformGetNumberOfProcessors() - Return the number of processors+// in the system.+//========================================================================++int _glfwPlatformGetNumberOfProcessors( void )+{+ int n;++ // Get number of processors online+ _glfw_numprocessors( n );+ return n;+}+
+ glfw/lib/cocoa/cocoa_time.m view
@@ -0,0 +1,106 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_time.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++#include <sys/time.h>++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Return timer value in seconds+//========================================================================++double _glfwPlatformGetTime( void )+{+ return [NSDate timeIntervalSinceReferenceDate] - _glfwLibrary.Timer.t0;+}++//========================================================================+// Set timer value in seconds+//========================================================================++void _glfwPlatformSetTime( double time )+{+ _glfwLibrary.Timer.t0 = [NSDate timeIntervalSinceReferenceDate] - time;+}++//========================================================================+// Put a thread to sleep for a specified amount of time+//========================================================================++void _glfwPlatformSleep( double time )+{+ if( time == 0.0 )+ {+ sched_yield();+ return;+ }++ struct timeval currenttime;+ struct timespec wait;+ pthread_mutex_t mutex;+ pthread_cond_t cond;+ long dt_sec, dt_usec;++ // Not all pthread implementations have a pthread_sleep() function. We+ // do it the portable way, using a timed wait for a condition that we+ // will never signal. NOTE: The unistd functions sleep/usleep suspends+ // the entire PROCESS, not a signle thread, which is why we can not+ // use them to implement glfwSleep.++ // Set timeout time, relatvie to current time+ gettimeofday( ¤ttime, NULL );+ dt_sec = (long) time;+ dt_usec = (long) ((time - (double)dt_sec) * 1000000.0);+ wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;+ if( wait.tv_nsec > 1000000000L )+ {+ wait.tv_nsec -= 1000000000L;+ dt_sec ++;+ }+ wait.tv_sec = currenttime.tv_sec + dt_sec;++ // Initialize condition and mutex objects+ pthread_mutex_init( &mutex, NULL );+ pthread_cond_init( &cond, NULL );++ // Do a timed wait+ pthread_mutex_lock( &mutex );+ pthread_cond_timedwait( &cond, &mutex, &wait );+ pthread_mutex_unlock( &mutex );++ // Destroy condition and mutex objects+ pthread_mutex_destroy( &mutex );+ pthread_cond_destroy( &cond );+}+
+ glfw/lib/cocoa/cocoa_window.m view
@@ -0,0 +1,880 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_window.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//========================================================================+// Delegate for window related notifications+// (but also used as an application delegate)+//========================================================================++@interface GLFWWindowDelegate : NSObject+@end++@implementation GLFWWindowDelegate++- (BOOL)windowShouldClose:(id)window+{+ if( _glfwWin.windowCloseCallback )+ {+ if( !_glfwWin.windowCloseCallback() )+ {+ return NO;+ }+ }++ // This is horribly ugly, but it works+ glfwCloseWindow();+ return NO;+}++- (void)windowDidResize:(NSNotification *)notification+{+ [_glfwWin.context update];++ NSRect contentRect =+ [_glfwWin.window contentRectForFrameRect:[_glfwWin.window frame]];+ _glfwWin.width = contentRect.size.width;+ _glfwWin.height = contentRect.size.height;++ if( _glfwWin.windowSizeCallback )+ {+ _glfwWin.windowSizeCallback( _glfwWin.width, _glfwWin.height );+ }+}++- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender+{+ if( _glfwWin.windowCloseCallback )+ {+ if( !_glfwWin.windowCloseCallback() )+ {+ return NSTerminateCancel;+ }+ }++ // This is horribly ugly, but it works+ glfwCloseWindow();+ return NSTerminateCancel;+}++@end++// TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject.+static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] =+{+ /* 00 */ 'A',+ /* 01 */ 'S',+ /* 02 */ 'D',+ /* 03 */ 'F',+ /* 04 */ 'H',+ /* 05 */ 'G',+ /* 06 */ 'Z',+ /* 07 */ 'X',+ /* 08 */ 'C',+ /* 09 */ 'V',+ /* 0a */ -1,+ /* 0b */ 'B',+ /* 0c */ 'Q',+ /* 0d */ 'W',+ /* 0e */ 'E',+ /* 0f */ 'R',+ /* 10 */ 'Y',+ /* 11 */ 'T',+ /* 12 */ '1',+ /* 13 */ '2',+ /* 14 */ '3',+ /* 15 */ '4',+ /* 16 */ '6',+ /* 17 */ '5',+ /* 18 */ GLFW_KEY_KP_EQUAL,+ /* 19 */ '9',+ /* 1a */ '7',+ /* 1b */ '-',+ /* 1c */ '8',+ /* 1d */ '0',+ /* 1e */ ']',+ /* 1f */ 'O',+ /* 20 */ 'U',+ /* 21 */ '[',+ /* 22 */ 'I',+ /* 23 */ 'P',+ /* 24 */ GLFW_KEY_ENTER,+ /* 25 */ 'L',+ /* 26 */ 'J',+ /* 27 */ '\'',+ /* 28 */ 'K',+ /* 29 */ ';',+ /* 2a */ '\\',+ /* 2b */ ',',+ /* 2c */ '/',+ /* 2d */ 'N',+ /* 2e */ 'M',+ /* 2f */ '.',+ /* 30 */ GLFW_KEY_TAB,+ /* 31 */ GLFW_KEY_SPACE,+ /* 32 */ '`',+ /* 33 */ GLFW_KEY_BACKSPACE,+ /* 34 */ -1,+ /* 35 */ GLFW_KEY_ESC,+ /* 36 */ GLFW_KEY_RSUPER,+ /* 37 */ GLFW_KEY_LSUPER,+ /* 38 */ GLFW_KEY_LSHIFT,+ /* 39 */ GLFW_KEY_CAPS_LOCK,+ /* 3a */ GLFW_KEY_LALT,+ /* 3b */ GLFW_KEY_LCTRL,+ /* 3c */ GLFW_KEY_RSHIFT,+ /* 3d */ GLFW_KEY_RALT,+ /* 3e */ GLFW_KEY_RCTRL,+ /* 3f */ -1,+ /* 40 */ -1,+ /* 41 */ GLFW_KEY_KP_DECIMAL,+ /* 42 */ -1,+ /* 43 */ GLFW_KEY_KP_MULTIPLY,+ /* 44 */ -1,+ /* 45 */ GLFW_KEY_KP_ADD,+ /* 46 */ -1,+ /* 47 */ -1,+ /* 48 */ -1,+ /* 49 */ -1,+ /* 4a */ -1,+ /* 4b */ GLFW_KEY_KP_DIVIDE,+ /* 4c */ GLFW_KEY_KP_ENTER,+ /* 4d */ -1,+ /* 4e */ GLFW_KEY_KP_SUBTRACT,+ /* 4f */ -1,+ /* 50 */ -1,+ /* 51 */ -1,+ /* 52 */ GLFW_KEY_KP_0,+ /* 53 */ GLFW_KEY_KP_1,+ /* 54 */ GLFW_KEY_KP_2,+ /* 55 */ GLFW_KEY_KP_3,+ /* 56 */ GLFW_KEY_KP_4,+ /* 57 */ GLFW_KEY_KP_5,+ /* 58 */ GLFW_KEY_KP_6,+ /* 59 */ GLFW_KEY_KP_7,+ /* 5a */ -1,+ /* 5b */ GLFW_KEY_KP_8,+ /* 5c */ GLFW_KEY_KP_9,+ /* 5d */ -1,+ /* 5e */ -1,+ /* 5f */ -1,+ /* 60 */ GLFW_KEY_F5,+ /* 61 */ GLFW_KEY_F6,+ /* 62 */ GLFW_KEY_F7,+ /* 63 */ GLFW_KEY_F3,+ /* 64 */ GLFW_KEY_F8,+ /* 65 */ -1,+ /* 66 */ -1,+ /* 67 */ -1,+ /* 68 */ -1,+ /* 69 */ GLFW_KEY_F13,+ /* 6a */ GLFW_KEY_F16,+ /* 6b */ -1,+ /* 6c */ -1,+ /* 6d */ -1,+ /* 6e */ -1,+ /* 6f */ -1,+ /* 70 */ -1,+ /* 71 */ -1,+ /* 72 */ GLFW_KEY_INSERT,+ /* 73 */ GLFW_KEY_HOME,+ /* 74 */ GLFW_KEY_PAGEUP,+ /* 75 */ GLFW_KEY_DEL,+ /* 76 */ GLFW_KEY_F4,+ /* 77 */ GLFW_KEY_END,+ /* 78 */ GLFW_KEY_F2,+ /* 79 */ GLFW_KEY_PAGEDOWN,+ /* 7a */ GLFW_KEY_F1,+ /* 7b */ GLFW_KEY_LEFT,+ /* 7c */ GLFW_KEY_RIGHT,+ /* 7d */ GLFW_KEY_DOWN,+ /* 7e */ GLFW_KEY_UP,+ /* 7f */ -1,+};++//========================================================================+// Converts a Mac OS X keycode to a GLFW keycode+//========================================================================++static int convertMacKeyCode( unsigned int macKeyCode )+{+ if( macKeyCode >= 128 )+ {+ return -1;+ }++ // This treats keycodes as *positional*; that is, we'll return 'a'+ // for the key left of 's', even on an AZERTY keyboard. The charInput+ // function should still get 'q' though.+ return MAC_TO_GLFW_KEYCODE_MAPPING[macKeyCode];+}++//========================================================================+// Content view class for the GLFW window+//========================================================================++@interface GLFWContentView : NSView+@end++@implementation GLFWContentView++- (BOOL)isOpaque+{+ return YES;+}++- (BOOL)canBecomeKeyView+{+ return YES;+}++- (BOOL)acceptsFirstResponder+{+ return YES;+}++- (void)mouseDown:(NSEvent *)event+{+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );+}++- (void)mouseDragged:(NSEvent *)event+{+ [self mouseMoved:event];+}++- (void)mouseUp:(NSEvent *)event+{+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE );+}++- (void)mouseMoved:(NSEvent *)event+{+ if( _glfwWin.mouseLock )+ {+ _glfwInput.MousePosX += [event deltaX];+ _glfwInput.MousePosY -= [event deltaY];+ }+ else+ {+ NSPoint p = [event locationInWindow];++ // Cocoa coordinate system has origin at lower left+ _glfwInput.MousePosX = p.x;+ _glfwInput.MousePosY = [[_glfwWin.window contentView] bounds].size.height - p.y;+ }++ if( _glfwWin.mousePosCallback )+ {+ _glfwWin.mousePosCallback( _glfwInput.MousePosX, _glfwInput.MousePosY );+ }+}++- (void)rightMouseDown:(NSEvent *)event+{+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );+}++- (void)rightMouseDragged:(NSEvent *)event+{+ [self mouseMoved:event];+}++- (void)rightMouseUp:(NSEvent *)event+{+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE );+}++- (void)otherMouseDown:(NSEvent *)event+{+ _glfwInputMouseClick( [event buttonNumber], GLFW_PRESS );+}++- (void)otherMouseDragged:(NSEvent *)event+{+ [self mouseMoved:event];+}++- (void)otherMouseUp:(NSEvent *)event+{+ _glfwInputMouseClick( [event buttonNumber], GLFW_RELEASE );+}++- (void)keyDown:(NSEvent *)event+{+ NSUInteger length;+ NSString* characters;+ int i, code = convertMacKeyCode( [event keyCode] );++ if( code != -1 )+ {+ _glfwInputKey( code, GLFW_PRESS );++ if( [event modifierFlags] & NSCommandKeyMask )+ {+ if( !_glfwWin.sysKeysDisabled )+ {+ [super keyDown:event];+ }+ }+ else+ {+ characters = [event characters];+ length = [characters length];++ for( i = 0; i < length; i++ )+ {+ _glfwInputChar( [characters characterAtIndex:i], GLFW_PRESS );+ }+ }+ }+}++- (void)flagsChanged:(NSEvent *)event+{+ unsigned int newModifierFlags = [event modifierFlags];+ int mode;++ if( newModifierFlags > _glfwWin.modifierFlags )+ {+ mode = GLFW_PRESS;+ }+ else+ {+ mode = GLFW_RELEASE;+ }++ _glfwWin.modifierFlags = newModifierFlags;+ _glfwInputKey( MAC_TO_GLFW_KEYCODE_MAPPING[[event keyCode]], mode );+}++- (void)keyUp:(NSEvent *)event+{+ NSUInteger length;+ NSString* characters;+ int i, code = convertMacKeyCode( [event keyCode] );++ if( code != -1 )+ {+ _glfwInputKey( code, GLFW_RELEASE );++ characters = [event characters];+ length = [characters length];++ for( i = 0; i < length; i++ )+ {+ _glfwInputChar( [characters characterAtIndex:i], GLFW_RELEASE );+ }+ }+}++- (void)scrollWheel:(NSEvent *)event+{+ _glfwInput.WheelPosFloating += [event deltaY];+ _glfwInput.WheelPos = lrint(_glfwInput.WheelPosFloating);++ if( _glfwWin.mouseWheelCallback )+ {+ _glfwWin.mouseWheelCallback( _glfwInput.WheelPos );+ }+}++@end++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Here is where the window is created, and the OpenGL rendering context is+// created+//========================================================================++int _glfwPlatformOpenWindow( int width, int height,+ const _GLFWwndconfig *wndconfig,+ const _GLFWfbconfig *fbconfig )+{+ int colorBits;++ _glfwWin.pixelFormat = nil;+ _glfwWin.window = nil;+ _glfwWin.context = nil;+ _glfwWin.delegate = nil;++ _glfwWin.delegate = [[GLFWWindowDelegate alloc] init];+ if( _glfwWin.delegate == nil )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ [NSApp setDelegate:_glfwWin.delegate];++ // Mac OS X needs non-zero color size, so set resonable values+ colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits;+ if( colorBits == 0 )+ {+ colorBits = 24;+ }+ else if( colorBits < 15 )+ {+ colorBits = 15;+ }++ // Ignored hints:+ // OpenGLMajor, OpenGLMinor, OpenGLForward:+ // pending Mac OS X support for OpenGL 3.x+ // OpenGLDebug+ // pending it meaning anything on Mac OS X++ // Don't use accumulation buffer support; it's not accelerated+ // Aux buffers probably aren't accelerated either++ CFDictionaryRef fullscreenMode = NULL;+ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ fullscreenMode =+ // I think it's safe to pass 0 to the refresh rate for this function+ // rather than conditionalizing the code to call the version which+ // doesn't specify refresh...+ CGDisplayBestModeForParametersAndRefreshRateWithProperty(+ CGMainDisplayID(),+ colorBits + fbconfig->alphaBits,+ width,+ height,+ wndconfig->refreshRate,+ // Controversial, see macosx_fullscreen.m for discussion+ kCGDisplayModeIsSafeForHardware,+ NULL);++ width = [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue];+ height = [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue];+ }++ unsigned int styleMask = 0;+ if( wndconfig->mode == GLFW_WINDOW )+ {+ styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;++ if( !wndconfig->windowNoResize )+ {+ styleMask |= NSResizableWindowMask;+ }+ }+ else+ {+ styleMask = NSBorderlessWindowMask;+ }++ _glfwWin.window = [[NSWindow alloc]+ initWithContentRect:NSMakeRect(0, 0, width, height)+ styleMask:styleMask+ backing:NSBackingStoreBuffered+ defer:NO];+ [_glfwWin.window setContentView:[[GLFWContentView alloc] init]];+ [_glfwWin.window setDelegate:_glfwWin.delegate];+ [_glfwWin.window setAcceptsMouseMovedEvents:YES];+ [_glfwWin.window center];++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ CGCaptureAllDisplays();+ CGDisplaySwitchToMode( CGMainDisplayID(), fullscreenMode );+ }++ unsigned int attribute_count = 0;+#define ADD_ATTR(x) attributes[attribute_count++] = x+#define ADD_ATTR2(x, y) (void)({ ADD_ATTR(x); ADD_ATTR(y); })+#define MAX_ATTRS 24 // urgh+ NSOpenGLPixelFormatAttribute attributes[MAX_ATTRS];++ ADD_ATTR( NSOpenGLPFADoubleBuffer );++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ ADD_ATTR( NSOpenGLPFAFullScreen );+ ADD_ATTR( NSOpenGLPFANoRecovery );+ ADD_ATTR2( NSOpenGLPFAScreenMask,+ CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() ) );+ }++ ADD_ATTR2( NSOpenGLPFAColorSize, colorBits );++ if( fbconfig->alphaBits > 0)+ {+ ADD_ATTR2( NSOpenGLPFAAlphaSize, fbconfig->alphaBits );+ }++ if( fbconfig->depthBits > 0)+ {+ ADD_ATTR2( NSOpenGLPFADepthSize, fbconfig->depthBits );+ }++ if( fbconfig->stencilBits > 0)+ {+ ADD_ATTR2( NSOpenGLPFAStencilSize, fbconfig->stencilBits );+ }++ int accumBits = fbconfig->accumRedBits + fbconfig->accumGreenBits ++ fbconfig->accumBlueBits + fbconfig->accumAlphaBits;++ if( accumBits > 0)+ {+ ADD_ATTR2( NSOpenGLPFAAccumSize, accumBits );+ }++ if( fbconfig->auxBuffers > 0)+ {+ ADD_ATTR2( NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers );+ }++ if( fbconfig->stereo)+ {+ ADD_ATTR( NSOpenGLPFAStereo );+ }++ if( fbconfig->samples > 0)+ {+ ADD_ATTR2( NSOpenGLPFASampleBuffers, 1 );+ ADD_ATTR2( NSOpenGLPFASamples, fbconfig->samples );+ }++ ADD_ATTR(0);++ _glfwWin.pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];+ if( _glfwWin.pixelFormat == nil )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ _glfwWin.context = [[NSOpenGLContext alloc] initWithFormat:_glfwWin.pixelFormat+ shareContext:nil];+ if( _glfwWin.context == nil )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ [_glfwWin.window makeKeyAndOrderFront:nil];+ [_glfwWin.context setView:[_glfwWin.window contentView]];++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ // TODO: Make this work on pre-Leopard systems+ [[_glfwWin.window contentView] enterFullScreenMode:[NSScreen mainScreen]+ withOptions:nil];+ }++ [_glfwWin.context makeCurrentContext];++ NSPoint point = [[NSCursor currentCursor] hotSpot];+ _glfwInput.MousePosX = point.x;+ _glfwInput.MousePosY = point.y;++ return GL_TRUE;+}++//========================================================================+// Properly kill the window / video display+//========================================================================++void _glfwPlatformCloseWindow( void )+{+ [_glfwWin.window orderOut:nil];++ if( _glfwWin.fullscreen )+ {+ [[_glfwWin.window contentView] exitFullScreenModeWithOptions:nil];+ CGDisplaySwitchToMode( CGMainDisplayID(),+ (CFDictionaryRef)_glfwLibrary.DesktopMode );+ CGReleaseAllDisplays();+ }++ [_glfwWin.pixelFormat release];+ _glfwWin.pixelFormat = nil;++ [NSOpenGLContext clearCurrentContext];+ [_glfwWin.context release];+ _glfwWin.context = nil;++ [_glfwWin.window setDelegate:nil];+ [NSApp setDelegate:nil];+ [_glfwWin.delegate release];+ _glfwWin.delegate = nil;++ [_glfwWin.window close];+ _glfwWin.window = nil;++ // TODO: Probably more cleanup+}++//========================================================================+// Set the window title+//========================================================================++void _glfwPlatformSetWindowTitle( const char *title )+{+ [_glfwWin.window setTitle:[NSString stringWithCString:title+ encoding:NSISOLatin1StringEncoding]];+}++//========================================================================+// Set the window size+//========================================================================++void _glfwPlatformSetWindowSize( int width, int height )+{+ [_glfwWin.window setContentSize:NSMakeSize(width, height)];+}++//========================================================================+// Set the window position+//========================================================================++void _glfwPlatformSetWindowPos( int x, int y )+{+ NSRect contentRect = [_glfwWin.window contentRectForFrameRect:[_glfwWin.window frame]];++ // We assume here that the client code wants to position the window within the+ // screen the window currently occupies+ NSRect screenRect = [[_glfwWin.window screen] visibleFrame];+ contentRect.origin = NSMakePoint(screenRect.origin.x + x,+ screenRect.origin.y + screenRect.size.height -+ y - contentRect.size.height);++ [_glfwWin.window setFrame:[_glfwWin.window frameRectForContentRect:contentRect]+ display:YES];+}++//========================================================================+// Iconify the window+//========================================================================++void _glfwPlatformIconifyWindow( void )+{+ [_glfwWin.window miniaturize:nil];+}++//========================================================================+// Restore (un-iconify) the window+//========================================================================++void _glfwPlatformRestoreWindow( void )+{+ [_glfwWin.window deminiaturize:nil];+}++//========================================================================+// Swap buffers+//========================================================================++void _glfwPlatformSwapBuffers( void )+{+ // ARP appears to be unnecessary, but this is future-proof+ [_glfwWin.context flushBuffer];+}++//========================================================================+// Set double buffering swap interval+//========================================================================++void _glfwPlatformSwapInterval( int interval )+{+ GLint sync = interval;+ [_glfwWin.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];+}++//========================================================================+// Write back window parameters into GLFW window structure+//========================================================================++void _glfwPlatformRefreshWindowParams( void )+{+ GLint value;++ // Since GLFW 2.x doesn't understand screens, we use virtual screen zero++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAAccelerated+ forVirtualScreen:0];+ _glfwWin.accelerated = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAAlphaSize+ forVirtualScreen:0];+ _glfwWin.alphaBits = value;++ // It seems that the color size includes the size of the alpha channel+ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAColorSize+ forVirtualScreen:0];+ value -= _glfwWin.alphaBits;+ _glfwWin.redBits = value / 3;+ _glfwWin.greenBits = value / 3;+ _glfwWin.blueBits = value / 3;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFADepthSize+ forVirtualScreen:0];+ _glfwWin.depthBits = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAStencilSize+ forVirtualScreen:0];+ _glfwWin.stencilBits = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAAccumSize+ forVirtualScreen:0];+ _glfwWin.accumRedBits = value / 3;+ _glfwWin.accumGreenBits = value / 3;+ _glfwWin.accumBlueBits = value / 3;++ // TODO: Figure out what to set this value to+ _glfwWin.accumAlphaBits = 0;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAAuxBuffers+ forVirtualScreen:0];+ _glfwWin.auxBuffers = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAStereo+ forVirtualScreen:0];+ _glfwWin.stereo = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFASamples+ forVirtualScreen:0];+ _glfwWin.samples = value;++ // These are forced to false as long as Mac OS X lacks support for OpenGL 3.0++ _glfwWin.glForward = GL_FALSE;+ _glfwWin.glDebug = GL_FALSE;+ _glfwWin.glProfile = 0;+}++//========================================================================+// Poll for new window and input events+//========================================================================++void _glfwPlatformPollEvents( void )+{+ NSEvent *event;++ do+ {+ event = [NSApp nextEventMatchingMask:NSAnyEventMask+ untilDate:[NSDate distantPast]+ inMode:NSDefaultRunLoopMode+ dequeue:YES];++ if (event)+ {+ [NSApp sendEvent:event];+ }+ }+ while (event);++ [_glfwLibrary.AutoreleasePool drain];+ _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init];+}++//========================================================================+// Wait for new window and input events+//========================================================================++void _glfwPlatformWaitEvents( void )+{+ // I wanted to pass NO to dequeue:, and rely on PollEvents to+ // dequeue and send. For reasons not at all clear to me, passing+ // NO to dequeue: causes this method never to return.+ NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask+ untilDate:[NSDate distantFuture]+ inMode:NSDefaultRunLoopMode+ dequeue:YES];+ [NSApp sendEvent:event];++ _glfwPlatformPollEvents();+}++//========================================================================+// Hide mouse cursor (lock it)+//========================================================================++void _glfwPlatformHideMouseCursor( void )+{+ [NSCursor hide];+ CGAssociateMouseAndMouseCursorPosition( false );+}++//========================================================================+// Show mouse cursor (unlock it)+//========================================================================++void _glfwPlatformShowMouseCursor( void )+{+ [NSCursor unhide];+ CGAssociateMouseAndMouseCursorPosition( true );+}++//========================================================================+// Set physical mouse cursor position+//========================================================================++void _glfwPlatformSetMouseCursorPos( int x, int y )+{+ // The library seems to assume that after calling this the mouse won't move,+ // but obviously it will, and escape the app's window, and activate other apps,+ // and other badness in pain. I think the API's just silly, but maybe I'm+ // misunderstanding it...++ // Also, (x, y) are window coords...++ // Also, it doesn't seem possible to write this robustly without+ // calculating the maximum y coordinate of all screens, since Cocoa's+ // "global coordinates" are upside down from CG's...++ // Without this (once per app run, but it's convenient to do it here)+ // events will be suppressed for a default of 0.25 seconds after we+ // move the cursor.+ CGSetLocalEventsSuppressionInterval( 0.0 );++ NSPoint localPoint = NSMakePoint( x, y );+ NSPoint globalPoint = [_glfwWin.window convertBaseToScreen:localPoint];+ CGPoint mainScreenOrigin = CGDisplayBounds( CGMainDisplayID() ).origin;+ double mainScreenHeight = CGDisplayBounds( CGMainDisplayID() ).size.height;+ CGPoint targetPoint = CGPointMake( globalPoint.x - mainScreenOrigin.x,+ mainScreenHeight - globalPoint.y - mainScreenOrigin.y );+ CGDisplayMoveCursorToPoint( CGMainDisplayID(), targetPoint );+}+
+ glfw/lib/enable.c view
@@ -0,0 +1,310 @@+//========================================================================+// GLFW - An OpenGL framework+// File: enable.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// Enable (show) mouse cursor+//========================================================================++static void enableMouseCursor( void )+{+ int centerPosX, centerPosY;++ if( !_glfwWin.opened || !_glfwWin.mouseLock )+ {+ return;+ }++ // Show mouse cursor+ _glfwPlatformShowMouseCursor();++ centerPosX = _glfwWin.width / 2;+ centerPosY = _glfwWin.height / 2;++ if( centerPosX != _glfwInput.MousePosX || centerPosY != _glfwInput.MousePosY )+ {+ _glfwPlatformSetMouseCursorPos( centerPosX, centerPosY );++ _glfwInput.MousePosX = centerPosX;+ _glfwInput.MousePosY = centerPosY;++ if( _glfwWin.mousePosCallback )+ {+ _glfwWin.mousePosCallback( _glfwInput.MousePosX,+ _glfwInput.MousePosY );+ }+ }++ // From now on the mouse is unlocked+ _glfwWin.mouseLock = GL_FALSE;+}++//========================================================================+// Disable (hide) mouse cursor+//========================================================================++static void disableMouseCursor( void )+{+ if( !_glfwWin.opened || _glfwWin.mouseLock )+ {+ return;+ }++ // Hide mouse cursor+ _glfwPlatformHideMouseCursor();++ // Move cursor to the middle of the window+ _glfwPlatformSetMouseCursorPos( _glfwWin.width >> 1,+ _glfwWin.height >> 1 );++ // From now on the mouse is locked+ _glfwWin.mouseLock = GL_TRUE;+}+++//========================================================================+// Enable sticky keys+//========================================================================++static void enableStickyKeys( void )+{+ _glfwInput.StickyKeys = 1;+}++//========================================================================+// Disable sticky keys+//========================================================================++static void disableStickyKeys( void )+{+ int i;++ _glfwInput.StickyKeys = 0;++ // Release all sticky keys+ for( i = 0; i <= GLFW_KEY_LAST; i++ )+ {+ if( _glfwInput.Key[ i ] == 2 )+ {+ _glfwInput.Key[ i ] = 0;+ }+ }+}+++//========================================================================+// Enable sticky mouse buttons+//========================================================================++static void enableStickyMouseButtons( void )+{+ _glfwInput.StickyMouseButtons = 1;+}++//========================================================================+// Disable sticky mouse buttons+//========================================================================++static void disableStickyMouseButtons( void )+{+ int i;++ _glfwInput.StickyMouseButtons = 0;++ // Release all sticky mouse buttons+ for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++ )+ {+ if( _glfwInput.MouseButton[ i ] == 2 )+ {+ _glfwInput.MouseButton[ i ] = 0;+ }+ }+}+++//========================================================================+// Enable system keys+//========================================================================++static void enableSystemKeys( void )+{+ if( !_glfwWin.sysKeysDisabled )+ {+ return;+ }++ _glfwPlatformEnableSystemKeys();++ // Indicate that system keys are no longer disabled+ _glfwWin.sysKeysDisabled = GL_FALSE;+}++//========================================================================+// Disable system keys+//========================================================================++static void disableSystemKeys( void )+{+ if( _glfwWin.sysKeysDisabled )+ {+ return;+ }++ _glfwPlatformDisableSystemKeys();++ // Indicate that system keys are now disabled+ _glfwWin.sysKeysDisabled = GL_TRUE;+}+++//========================================================================+// Enable key repeat+//========================================================================++static void enableKeyRepeat( void )+{+ _glfwInput.KeyRepeat = 1;+}++//========================================================================+// Disable key repeat+//========================================================================++static void disableKeyRepeat( void )+{+ _glfwInput.KeyRepeat = 0;+}+++//========================================================================+// Enable automatic event polling+//========================================================================++static void enableAutoPollEvents( void )+{+ _glfwWin.autoPollEvents = 1;+}++//========================================================================+// Disable automatic event polling+//========================================================================++static void disableAutoPollEvents( void )+{+ _glfwWin.autoPollEvents = 0;+}++++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// Enable certain GLFW/window/system functions.+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwEnable( int token )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return;+ }++ switch( token )+ {+ case GLFW_MOUSE_CURSOR:+ enableMouseCursor();+ break;+ case GLFW_STICKY_KEYS:+ enableStickyKeys();+ break;+ case GLFW_STICKY_MOUSE_BUTTONS:+ enableStickyMouseButtons();+ break;+ case GLFW_SYSTEM_KEYS:+ enableSystemKeys();+ break;+ case GLFW_KEY_REPEAT:+ enableKeyRepeat();+ break;+ case GLFW_AUTO_POLL_EVENTS:+ enableAutoPollEvents();+ break;+ default:+ break;+ }+}+++//========================================================================+// Disable certain GLFW/window/system functions.+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwDisable( int token )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return;+ }++ switch( token )+ {+ case GLFW_MOUSE_CURSOR:+ disableMouseCursor();+ break;+ case GLFW_STICKY_KEYS:+ disableStickyKeys();+ break;+ case GLFW_STICKY_MOUSE_BUTTONS:+ disableStickyMouseButtons();+ break;+ case GLFW_SYSTEM_KEYS:+ disableSystemKeys();+ break;+ case GLFW_KEY_REPEAT:+ disableKeyRepeat();+ break;+ case GLFW_AUTO_POLL_EVENTS:+ disableAutoPollEvents();+ break;+ default:+ break;+ }+}+
+ glfw/lib/fullscreen.c view
@@ -0,0 +1,95 @@+//========================================================================+// GLFW - An OpenGL framework+// File: fullscreen.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// glfwGetVideoModes() - Get a list of available video modes+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list,+ int maxcount )+{+ int count, i, swap, res1, res2, depth1, depth2;+ GLFWvidmode vm;++ if( !_glfwInitialized || maxcount <= 0 || list == (GLFWvidmode*) 0 )+ {+ return 0;+ }++ // Get list of video modes+ count = _glfwPlatformGetVideoModes( list, maxcount );++ // Sort list (bubble sort)+ do+ {+ swap = 0;+ for( i = 0; i < count-1; ++ i )+ {+ res1 = list[i].Width*list[i].Height;+ depth1 = list[i].RedBits+list[i].GreenBits+list[i].BlueBits;+ res2 = list[i+1].Width*list[i+1].Height;+ depth2 = list[i+1].RedBits+list[i+1].GreenBits++ list[i+1].BlueBits;+ if( (depth2<depth1) || ((depth2==depth1) && (res2<res1)) )+ {+ vm = list[i];+ list[i] = list[i+1];+ list[i+1] = vm;+ swap = 1;+ }+ }+ }+ while( swap );++ return count;+}+++//========================================================================+// glfwGetDesktopMode() - Get the desktop video mode+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode )+{+ if( !_glfwInitialized || mode == (GLFWvidmode*) 0 )+ {+ return;+ }++ _glfwPlatformGetDesktopMode( mode );+}+
+ glfw/lib/glext.c view
@@ -0,0 +1,211 @@+//========================================================================+// GLFW - An OpenGL framework+// File: glext.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// Parses the OpenGL version string and extracts the version number+//========================================================================++void _glfwParseGLVersion( int *major, int *minor, int *rev )+{+ GLuint _major, _minor = 0, _rev = 0;+ const GLubyte *version;+ const GLubyte *ptr;++ // Get OpenGL version string+ version = glGetString( GL_VERSION );+ if( !version )+ {+ return;+ }++ // Parse string+ ptr = version;+ for( _major = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )+ {+ _major = 10*_major + (*ptr - '0');+ }+ if( *ptr == '.' )+ {+ ptr ++;+ for( _minor = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )+ {+ _minor = 10*_minor + (*ptr - '0');+ }+ if( *ptr == '.' )+ {+ ptr ++;+ for( _rev = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )+ {+ _rev = 10*_rev + (*ptr - '0');+ }+ }+ }++ // Return parsed values+ *major = _major;+ *minor = _minor;+ *rev = _rev;+}++//========================================================================+// _glfwStringInExtensionString() - Check if a string can be found in an+// OpenGL extension string+//========================================================================++int _glfwStringInExtensionString( const char *string,+ const GLubyte *extensions )+{+ const GLubyte *start;+ GLubyte *where, *terminator;++ // 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;+ while( 1 )+ {+ where = (GLubyte *) strstr( (const char *) start, string );+ if( !where )+ {+ return GL_FALSE;+ }+ terminator = where + strlen( string );+ if( where == start || *(where - 1) == ' ' )+ {+ if( *terminator == ' ' || *terminator == '\0' )+ {+ break;+ }+ }+ start = terminator;+ }++ return GL_TRUE;+}++++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// glfwExtensionSupported() - Check if an OpenGL extension is available+// at runtime+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwExtensionSupported( const char *extension )+{+ const GLubyte *extensions;+ GLubyte *where;++ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return GL_FALSE;+ }++ // Extension names should not have spaces+ where = (GLubyte *) strchr( extension, ' ' );+ if( where || *extension == '\0' )+ {+ return GL_FALSE;+ }++ // Check if extension is in the standard OpenGL extensions string+ extensions = glGetString( GL_EXTENSIONS );+ if( extensions != NULL )+ {+ if( _glfwStringInExtensionString( extension, extensions ) )+ {+ return GL_TRUE;+ }+ }++ // Additional platform specific extension checking (e.g. WGL)+ if( _glfwPlatformExtensionSupported( extension ) )+ {+ return GL_TRUE;+ }++ return GL_FALSE;+}+++//========================================================================+// glfwGetProcAddress() - Get the function pointer to an OpenGL function.+// This function can be used to get access to extended OpenGL functions.+//========================================================================++GLFWAPI void * GLFWAPIENTRY glfwGetProcAddress( const char *procname )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return NULL;+ }++ return _glfwPlatformGetProcAddress( procname );+}+++//========================================================================+// Returns the OpenGL version+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, int *rev )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ if( major != NULL )+ {+ *major = _glfwWin.glMajor;+ }+ if( minor != NULL )+ {+ *minor = _glfwWin.glMinor;+ }+ if( rev != NULL )+ {+ *rev = _glfwWin.glRevision;+ }+}+
+ glfw/lib/image.c view
@@ -0,0 +1,631 @@+//========================================================================+// GLFW - An OpenGL framework+// File: image.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++//========================================================================+// Description:+//+// This module acts as an interface for different image file formats (the+// image file format is detected automatically).+//+// By default the loaded image is rescaled (using bilinear interpolation)+// to the next higher 2^N x 2^M resolution, unless it has a valid+// 2^N x 2^M resolution. The interpolation is quite slow, even if the+// routine has been optimized for speed (a 200x200 RGB image is scaled to+// 256x256 in ~30 ms on a P3-500).+//+// Paletted images are converted to RGB/RGBA images.+//+// A convenience function is also included (glfwLoadTexture2D), which+// loads a texture image from a file directly to OpenGL texture memory,+// with an option to generate all mipmap levels. GL_SGIS_generate_mipmap+// is used whenever available, which should give an optimal mipmap+// generation speed (possibly performed in hardware). A software fallback+// method is included when GL_SGIS_generate_mipmap is not supported (it+// generates all mipmaps of a 256x256 RGB texture in ~3 ms on a P3-500).+//+//========================================================================+++#include "internal.h"+++// We want to support automatic mipmap generation+#ifndef GL_SGIS_generate_mipmap+ #define GL_GENERATE_MIPMAP_SGIS 0x8191+ #define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192+ #define GL_SGIS_generate_mipmap 1+#endif // GL_SGIS_generate_mipmap+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// Upsample image, from size w1 x h1 to w2 x h2+//========================================================================++static void UpsampleImage( unsigned char *src, unsigned char *dst,+ int w1, int h1, int w2, int h2, int bpp )+{+ int m, n, k, x, y, col8;+ float dx, dy, xstep, ystep, col, col1, col2;+ unsigned char *src1, *src2, *src3, *src4;++ // Calculate scaling factor+ xstep = (float)(w1-1) / (float)(w2-1);+ ystep = (float)(h1-1) / (float)(h2-1);++ // Copy source data to destination data with bilinear interpolation+ // Note: The rather strange look of this routine is a direct result of+ // my attempts at optimizing it. Improvements are welcome!+ dy = 0.0f;+ y = 0;+ for( n = 0; n < h2; n ++ )+ {+ dx = 0.0f;+ src1 = &src[ y*w1*bpp ];+ src3 = y < (h1-1) ? src1 + w1*bpp : src1;+ src2 = src1 + bpp;+ src4 = src3 + bpp;+ x = 0;+ for( m = 0; m < w2; m ++ )+ {+ for( k = 0; k < bpp; k ++ )+ {+ col1 = *src1 ++;+ col2 = *src2 ++;+ col = col1 + (col2 - col1) * dx;+ col1 = *src3 ++;+ col2 = *src4 ++;+ col2 = col1 + (col2 - col1) * dx;+ col += (col2 - col) * dy;+ col8 = (int) (col + 0.5);+ if( col8 >= 256 ) col8 = 255;+ *dst++ = (unsigned char) col8;+ }+ dx += xstep;+ if( dx >= 1.0f )+ {+ x ++;+ dx -= 1.0f;+ if( x >= (w1-1) )+ {+ src2 = src1;+ src4 = src3;+ }+ }+ else+ {+ src1 -= bpp;+ src2 -= bpp;+ src3 -= bpp;+ src4 -= bpp;+ }+ }+ dy += ystep;+ if( dy >= 1.0f )+ {+ y ++;+ dy -= 1.0f;+ }+ }+}+++//========================================================================+// Build the next mip-map level+//========================================================================++static int HalveImage( GLubyte *src, int *width, int *height,+ int components )+{+ int halfwidth, halfheight, m, n, k, idx1, idx2;+ GLubyte *dst;++ // Last level?+ if( *width <= 1 && *height <= 1 )+ {+ return GL_FALSE;+ }++ // Calculate new width and height (handle 1D case)+ halfwidth = *width > 1 ? *width / 2 : 1;+ halfheight = *height > 1 ? *height / 2 : 1;++ // Downsample image with a simple box-filter+ dst = src;+ if( *width == 1 || *height == 1 )+ {+ // 1D case+ for( m = 0; m < halfwidth+halfheight-1; m ++ )+ {+ for( k = 0; k < components; k ++ )+ {+ *dst ++ = (GLubyte) (((int)*src ++ (int)src[components] + 1) >> 1);+ src ++;+ }+ src += components;+ }+ }+ else+ {+ // 2D case+ idx1 = *width*components;+ idx2 = (*width+1)*components;+ for( m = 0; m < halfheight; m ++ )+ {+ for( n = 0; n < halfwidth; n ++ )+ {+ for( k = 0; k < components; k ++ )+ {+ *dst ++ = (GLubyte) (((int)*src ++ (int)src[components] ++ (int)src[idx1] ++ (int)src[idx2] + 2) >> 2);+ src ++;+ }+ src += components;+ }+ src += components * (*width);+ }+ }++ // Return new width and height+ *width = halfwidth;+ *height = halfheight;++ return GL_TRUE;+}+++//========================================================================+// Rescales an image into power-of-two dimensions+//========================================================================++static int RescaleImage( GLFWimage* image )+{+ int width, height, log2, newsize;+ unsigned char *data;++ // Calculate next larger 2^N width+ for( log2 = 0, width = image->Width; width > 1; width >>= 1, log2 ++ )+ ;++ width = (int) 1 << log2;+ if( width < image->Width )+ {+ width <<= 1;+ }++ // Calculate next larger 2^M height+ for( log2 = 0, height = image->Height; height > 1; height >>= 1, log2 ++ )+ ;++ height = (int) 1 << log2;+ if( height < image->Height )+ {+ height <<= 1;+ }++ // Do we really need to rescale?+ if( width != image->Width || height != image->Height )+ {+ // Allocate memory for new (upsampled) image data+ newsize = width * height * image->BytesPerPixel;+ data = (unsigned char *) malloc( newsize );+ if( data == NULL )+ {+ free( image->Data );+ return GL_FALSE;+ }++ // Copy old image data to new image data with interpolation+ UpsampleImage( image->Data, data, image->Width, image->Height,+ width, height, image->BytesPerPixel );++ // Free memory for old image data (not needed anymore)+ free( image->Data );++ // Set pointer to new image data, and set new image dimensions+ image->Data = data;+ image->Width = width;+ image->Height = height;+ }++ return GL_TRUE;+}+++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// glfwReadImage() - Read an image from a named file+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img,+ int flags )+{+ _GLFWstream stream;++ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return GL_FALSE;+ }++ // Start with an empty image descriptor+ img->Width = 0;+ img->Height = 0;+ img->BytesPerPixel = 0;+ img->Data = NULL;++ // Open file+ if( !_glfwOpenFileStream( &stream, name, "rb" ) )+ {+ return GL_FALSE;+ }++ // We only support TGA files at the moment+ if( !_glfwReadTGA( &stream, img, flags ) )+ {+ _glfwCloseStream( &stream );+ return GL_FALSE;+ }++ // Close stream+ _glfwCloseStream( &stream );++ // Should we rescale the image to closest 2^N x 2^M resolution?+ if( !(flags & GLFW_NO_RESCALE_BIT) )+ {+ if( !RescaleImage( img ) )+ {+ return GL_FALSE;+ }+ }++ // Interpret BytesPerPixel as an OpenGL format+ switch( img->BytesPerPixel )+ {+ default:+ case 1:+ if( flags & GLFW_ALPHA_MAP_BIT )+ {+ img->Format = GL_ALPHA;+ }+ else+ {+ img->Format = GL_LUMINANCE;+ }+ break;+ case 3:+ img->Format = GL_RGB;+ break;+ case 4:+ img->Format = GL_RGBA;+ break;+ }++ return GL_TRUE;+}+++//========================================================================+// glfwReadMemoryImage() - Read an image file from a memory buffer+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags )+{+ _GLFWstream stream;++ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return GL_FALSE;+ }++ // Start with an empty image descriptor+ img->Width = 0;+ img->Height = 0;+ img->BytesPerPixel = 0;+ img->Data = NULL;++ // Open buffer+ if( !_glfwOpenBufferStream( &stream, (void*) data, size ) )+ {+ return GL_FALSE;+ }++ // We only support TGA files at the moment+ if( !_glfwReadTGA( &stream, img, flags ) )+ {+ _glfwCloseStream( &stream );+ return GL_FALSE;+ }++ // Close stream+ _glfwCloseStream( &stream );++ // Should we rescale the image to closest 2^N x 2^M resolution?+ if( !(flags & GLFW_NO_RESCALE_BIT) )+ {+ if( !RescaleImage( img ) )+ {+ return GL_FALSE;+ }+ }++ // Interpret BytesPerPixel as an OpenGL format+ switch( img->BytesPerPixel )+ {+ default:+ case 1:+ if( flags & GLFW_ALPHA_MAP_BIT )+ {+ img->Format = GL_ALPHA;+ }+ else+ {+ img->Format = GL_LUMINANCE;+ }+ break;+ case 3:+ img->Format = GL_RGB;+ break;+ case 4:+ img->Format = GL_RGBA;+ break;+ }++ return GL_TRUE;+}+++//========================================================================+// glfwFreeImage() - Free allocated memory for an image+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return;+ }++ // Free memory+ if( img->Data != NULL )+ {+ free( img->Data );+ img->Data = NULL;+ }++ // Clear all fields+ img->Width = 0;+ img->Height = 0;+ img->Format = 0;+ img->BytesPerPixel = 0;+}+++//========================================================================+// glfwLoadTexture2D() - Read an image from a file, and upload it to+// texture memory+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags )+{+ GLFWimage img;++ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return GL_FALSE;+ }++ // Force rescaling if necessary+ if( !_glfwWin.has_GL_ARB_texture_non_power_of_two )+ {+ flags &= (~GLFW_NO_RESCALE_BIT);+ }++ // Read image from file+ if( !glfwReadImage( name, &img, flags ) )+ {+ return GL_FALSE;+ }++ if( !glfwLoadTextureImage2D( &img, flags ) )+ {+ return GL_FALSE;+ }++ // Data buffer is not needed anymore+ glfwFreeImage( &img );++ return GL_TRUE;+}+++//========================================================================+// glfwLoadMemoryTexture2D() - Read an image from a buffer, and upload it to+// texture memory+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags )+{+ GLFWimage img;++ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return GL_FALSE;+ }++ // Force rescaling if necessary+ if( !_glfwWin.has_GL_ARB_texture_non_power_of_two )+ {+ flags &= (~GLFW_NO_RESCALE_BIT);+ }++ // Read image from file+ if( !glfwReadMemoryImage( data, size, &img, flags ) )+ {+ return GL_FALSE;+ }++ if( !glfwLoadTextureImage2D( &img, flags ) )+ {+ return GL_FALSE;+ }++ // Data buffer is not needed anymore+ glfwFreeImage( &img );++ return GL_TRUE;+}+++//========================================================================+// glfwLoadTextureImage2D() - Upload an image object to texture memory+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags )+{+ GLint UnpackAlignment, GenMipMap;+ int level, format, AutoGen, newsize, n;+ unsigned char *data, *dataptr;++ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return GL_FALSE;+ }++ // TODO: Use GL_MAX_TEXTURE_SIZE or GL_PROXY_TEXTURE_2D to determine+ // whether the image size is valid.+ // NOTE: May require box filter downsampling routine.++ // Do we need to convert the alpha map to RGBA format (OpenGL 1.0)?+ if( (_glfwWin.glMajor == 1) && (_glfwWin.glMinor == 0) &&+ (img->Format == GL_ALPHA) )+ {+ // We go to RGBA representation instead+ img->BytesPerPixel = 4;++ // Allocate memory for new RGBA image data+ newsize = img->Width * img->Height * img->BytesPerPixel;+ data = (unsigned char *) malloc( newsize );+ if( data == NULL )+ {+ free( img->Data );+ return GL_FALSE;+ }++ // Convert Alpha map to RGBA+ dataptr = data;+ for( n = 0; n < (img->Width*img->Height); ++ n )+ {+ *dataptr ++ = 255;+ *dataptr ++ = 255;+ *dataptr ++ = 255;+ *dataptr ++ = img->Data[n];+ }++ // Free memory for old image data (not needed anymore)+ free( img->Data );++ // Set pointer to new image data+ img->Data = data;+ }++ // Set unpack alignment to one byte+ glGetIntegerv( GL_UNPACK_ALIGNMENT, &UnpackAlignment );+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );++ // Should we use automatic mipmap generation?+ AutoGen = ( flags & GLFW_BUILD_MIPMAPS_BIT ) &&+ _glfwWin.has_GL_SGIS_generate_mipmap;++ // Enable automatic mipmap generation+ if( AutoGen )+ {+ glGetTexParameteriv( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,+ &GenMipMap );+ glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,+ GL_TRUE );+ }++ // Format specification is different for OpenGL 1.0+ if( _glfwWin.glMajor == 1 && _glfwWin.glMinor == 0 )+ {+ format = img->BytesPerPixel;+ }+ else+ {+ format = img->Format;+ }++ // Upload to texture memeory+ level = 0;+ do+ {+ // Upload this mipmap level+ glTexImage2D( GL_TEXTURE_2D, level, format,+ img->Width, img->Height, 0, format,+ GL_UNSIGNED_BYTE, (void*) img->Data );++ // Build next mipmap level manually, if required+ if( ( flags & GLFW_BUILD_MIPMAPS_BIT ) && !AutoGen )+ {+ level = HalveImage( img->Data, &img->Width,+ &img->Height, img->BytesPerPixel ) ?+ level + 1 : 0;+ }+ }+ while( level != 0 );++ // Restore old automatic mipmap generation state+ if( AutoGen )+ {+ glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,+ GenMipMap );+ }++ // Restore old unpack alignment+ glPixelStorei( GL_UNPACK_ALIGNMENT, UnpackAlignment );++ return GL_TRUE;+}+
+ glfw/lib/init.c view
@@ -0,0 +1,111 @@+//========================================================================+// GLFW - An OpenGL framework+// File: init.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#define _init_c_+#include "internal.h"+++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// glfwInit() - Initialize various GLFW state+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwInit( void )+{+ // Is GLFW already initialized?+ if( _glfwInitialized )+ {+ return GL_TRUE;+ }++ memset( &_glfwLibrary, 0, sizeof( _glfwLibrary ) );+ memset( &_glfwWin, 0, sizeof( _glfwWin ) );++ // Window is not yet opened+ _glfwWin.opened = GL_FALSE;++ // Default enable/disable settings+ _glfwWin.sysKeysDisabled = GL_FALSE;++ // Clear window hints+ _glfwClearWindowHints();++ // Platform specific initialization+ if( !_glfwPlatformInit() )+ {+ return GL_FALSE;+ }++ // Form now on, GLFW state is valid+ _glfwInitialized = GL_TRUE;++ return GL_TRUE;+}++++//========================================================================+// glfwTerminate() - Close window and kill all threads.+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwTerminate( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return;+ }++ // Platform specific termination+ if( !_glfwPlatformTerminate() )+ {+ return;+ }++ // GLFW is no longer initialized+ _glfwInitialized = GL_FALSE;+}+++//========================================================================+// glfwGetVersion() - Get GLFW version+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor,+ int *rev )+{+ if( major != NULL ) *major = GLFW_VERSION_MAJOR;+ if( minor != NULL ) *minor = GLFW_VERSION_MINOR;+ if( rev != NULL ) *rev = GLFW_VERSION_REVISION;+}+
+ glfw/lib/input.c view
@@ -0,0 +1,280 @@+//========================================================================+// GLFW - An OpenGL framework+// File: input.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//========================================================================+// glfwGetKey()+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetKey( int key )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return GLFW_RELEASE;+ }++ // Is it a valid key?+ if( key < 0 || key > GLFW_KEY_LAST )+ {+ return GLFW_RELEASE;+ }++ if( _glfwInput.Key[ key ] == GLFW_STICK )+ {+ // Sticky mode: release key now+ _glfwInput.Key[ key ] = GLFW_RELEASE;+ return GLFW_PRESS;+ }++ return (int) _glfwInput.Key[ key ];+}+++//========================================================================+// glfwGetMouseButton()+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetMouseButton( int button )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return GLFW_RELEASE;+ }++ // Is it a valid mouse button?+ if( button < 0 || button > GLFW_MOUSE_BUTTON_LAST )+ {+ return GLFW_RELEASE;+ }++ if( _glfwInput.MouseButton[ button ] == GLFW_STICK )+ {+ // Sticky mode: release mouse button now+ _glfwInput.MouseButton[ button ] = GLFW_RELEASE;+ return GLFW_PRESS;+ }++ return (int) _glfwInput.MouseButton[ button ];+}+++//========================================================================+// glfwGetMousePos()+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Return mouse position+ if( xpos != NULL )+ {+ *xpos = _glfwInput.MousePosX;+ }+ if( ypos != NULL )+ {+ *ypos = _glfwInput.MousePosY;+ }+}+++//========================================================================+// glfwSetMousePos()+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Don't do anything if the mouse position did not change+ if( xpos == _glfwInput.MousePosX && ypos == _glfwInput.MousePosY )+ {+ return;+ }++ // Set GLFW mouse position+ _glfwInput.MousePosX = xpos;+ _glfwInput.MousePosY = ypos;++ // If we have a locked mouse, do not change cursor position+ if( _glfwWin.mouseLock )+ {+ return;+ }++ // Update physical cursor position+ _glfwPlatformSetMouseCursorPos( xpos, ypos );+}+++//========================================================================+// glfwGetMouseWheel()+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetMouseWheel( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return 0;+ }++ // Return mouse wheel position+ return _glfwInput.WheelPos;+}+++//========================================================================+// glfwSetMouseWheel()+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set mouse wheel position+ _glfwInput.WheelPos = pos;+}+++//========================================================================+// glfwSetKeyCallback() - Set callback function for keyboard input+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set callback function+ _glfwWin.keyCallback = cbfun;+}+++//========================================================================+// glfwSetCharCallback() - Set callback function for character input+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set callback function+ _glfwWin.charCallback = cbfun;+}+++//========================================================================+// glfwSetMouseButtonCallback() - Set callback function for mouse clicks+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set callback function+ _glfwWin.mouseButtonCallback = cbfun;+}+++//========================================================================+// glfwSetMousePosCallback() - Set callback function for mouse moves+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set callback function+ _glfwWin.mousePosCallback = cbfun;++ // Call the callback function to let the application know the current+ // mouse position+ if( cbfun )+ {+ cbfun( _glfwInput.MousePosX, _glfwInput.MousePosY );+ }+}+++//========================================================================+// glfwSetMouseWheelCallback() - Set callback function for mouse wheel+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set callback function+ _glfwWin.mouseWheelCallback = cbfun;++ // Call the callback function to let the application know the current+ // mouse wheel position+ if( cbfun )+ {+ cbfun( _glfwInput.WheelPos );+ }+}+
+ glfw/lib/joystick.c view
@@ -0,0 +1,102 @@+//========================================================================+// GLFW - An OpenGL framework+// File: joystick.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// glfwGetJoystickParam() - Determine joystick capabilities+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return 0;+ }++ return _glfwPlatformGetJoystickParam( joy, param );+}+++//========================================================================+// glfwGetJoystickPos() - Get joystick axis positions+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos, int numaxes )+{+ int i;++ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return 0;+ }++ // Clear positions+ for( i = 0; i < numaxes; i++ )+ {+ pos[ i ] = 0.0f;+ }++ return _glfwPlatformGetJoystickPos( joy, pos, numaxes );+}+++//========================================================================+// glfwGetJoystickButtons() - Get joystick button states+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy,+ unsigned char *buttons,+ int numbuttons )+{+ int i;++ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return 0;+ }++ // Clear button states+ for( i = 0; i < numbuttons; i++ )+ {+ buttons[ i ] = GLFW_RELEASE;+ }++ return _glfwPlatformGetJoystickButtons( joy, buttons, numbuttons );+}+
+ glfw/lib/stream.c view
@@ -0,0 +1,194 @@+//========================================================================+// GLFW - An OpenGL framework+// File: stream.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================+++#include "internal.h"+++//========================================================================+// Opens a GLFW stream with a file+//========================================================================++int _glfwOpenFileStream( _GLFWstream *stream, const char* name, const char* mode )+{+ memset( stream, 0, sizeof(_GLFWstream) );++ stream->file = fopen( name, mode );+ if( stream->file == NULL )+ {+ return GL_FALSE;+ }++ return GL_TRUE;+}+++//========================================================================+// Opens a GLFW stream with a memory block+//========================================================================++int _glfwOpenBufferStream( _GLFWstream *stream, void *data, long size )+{+ memset( stream, 0, sizeof(_GLFWstream) );++ stream->data = data;+ stream->size = size;+ return GL_TRUE;+}+++//========================================================================+// Reads data from a GLFW stream+//========================================================================++long _glfwReadStream( _GLFWstream *stream, void *data, long size )+{+ if( stream->file != NULL )+ {+ return fread( data, 1, size, stream->file );+ }++ if( stream->data != NULL )+ {+ // Check for EOF+ if( stream->position == stream->size )+ {+ return 0;+ }++ // Clamp read size to available data+ if( stream->position + size > stream->size )+ {+ size = stream->size - stream->position;+ }++ // Perform data read+ memcpy( data, (unsigned char*) stream->data + stream->position, size );+ stream->position += size;+ return size;+ }++ return 0;+}+++//========================================================================+// Returns the current position of a GLFW stream+//========================================================================++long _glfwTellStream( _GLFWstream *stream )+{+ if( stream->file != NULL )+ {+ return ftell( stream->file );+ }++ if( stream->data != NULL )+ {+ return stream->position;+ }++ return 0;+}+++//========================================================================+// Sets the current position of a GLFW stream+//========================================================================++int _glfwSeekStream( _GLFWstream *stream, long offset, int whence )+{+ long position;++ if( stream->file != NULL )+ {+ if( fseek( stream->file, offset, whence ) != 0 )+ {+ return GL_FALSE;+ }++ return GL_TRUE;+ }++ if( stream->data != NULL )+ {+ position = offset;++ // Handle whence parameter+ if( whence == SEEK_CUR )+ {+ position += stream->position;+ }+ else if( whence == SEEK_END )+ {+ position += stream->size;+ }+ else if( whence != SEEK_SET )+ {+ return GL_FALSE;+ }++ // Clamp offset to buffer bounds and apply it+ if( position > stream->size )+ {+ stream->position = stream->size;+ }+ else if( position < 0 )+ {+ stream->position = 0;+ }+ else+ {+ stream->position = position;+ }++ return GL_TRUE;+ }++ return GL_FALSE;+}+++//========================================================================+// Closes a GLFW stream+//========================================================================++void _glfwCloseStream( _GLFWstream *stream )+{+ if( stream->file != NULL )+ {+ fclose( stream->file );+ }++ // Nothing to be done about (user allocated) memory blocks++ memset( stream, 0, sizeof(_GLFWstream) );+}+
+ glfw/lib/tga.c view
@@ -0,0 +1,405 @@+//========================================================================+// GLFW - An OpenGL framework+// File: tga.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++//========================================================================+// Description:+//+// TGA format image file loader. This module supports version 1 Targa+// images, with these restrictions:+// - Pixel format may only be 8, 24 or 32 bits+// - Colormaps must be no longer than 256 entries+//+//========================================================================+++#include "internal.h"+++//************************************************************************+//**** GLFW internal functions & declarations ****+//************************************************************************++//========================================================================+// TGA file header information+//========================================================================++typedef struct {+ int idlen; // 1 byte+ int cmaptype; // 1 byte+ int imagetype; // 1 byte+ int cmapfirstidx; // 2 bytes+ int cmaplen; // 2 bytes+ int cmapentrysize; // 1 byte+ int xorigin; // 2 bytes+ int yorigin; // 2 bytes+ int width; // 2 bytes+ int height; // 2 bytes+ int bitsperpixel; // 1 byte+ int imageinfo; // 1 byte+ int _alphabits; // (derived from imageinfo)+ int _origin; // (derived from imageinfo)+} _tga_header_t;++#define _TGA_CMAPTYPE_NONE 0+#define _TGA_CMAPTYPE_PRESENT 1++#define _TGA_IMAGETYPE_NONE 0+#define _TGA_IMAGETYPE_CMAP 1+#define _TGA_IMAGETYPE_TC 2+#define _TGA_IMAGETYPE_GRAY 3+#define _TGA_IMAGETYPE_CMAP_RLE 9+#define _TGA_IMAGETYPE_TC_RLE 10+#define _TGA_IMAGETYPE_GRAY_RLE 11++#define _TGA_IMAGEINFO_ALPHA_MASK 0x0f+#define _TGA_IMAGEINFO_ALPHA_SHIFT 0+#define _TGA_IMAGEINFO_ORIGIN_MASK 0x30+#define _TGA_IMAGEINFO_ORIGIN_SHIFT 4++#define _TGA_ORIGIN_BL 0+#define _TGA_ORIGIN_BR 1+#define _TGA_ORIGIN_UL 2+#define _TGA_ORIGIN_UR 3+++//========================================================================+// _glfwReadTGAHeader() - Read TGA file header (and check that it is+// valid)+//========================================================================++static int ReadTGAHeader( _GLFWstream *s, _tga_header_t *h )+{+ unsigned char buf[ 18 ];+ int pos;++ // Read TGA file header from file+ pos = _glfwTellStream( s );+ _glfwReadStream( s, buf, 18 );++ // Interpret header (endian independent parsing)+ h->idlen = (int) buf[0];+ h->cmaptype = (int) buf[1];+ h->imagetype = (int) buf[2];+ h->cmapfirstidx = (int) buf[3] | (((int) buf[4]) << 8);+ h->cmaplen = (int) buf[5] | (((int) buf[6]) << 8);+ h->cmapentrysize = (int) buf[7];+ h->xorigin = (int) buf[8] | (((int) buf[9]) << 8);+ h->yorigin = (int) buf[10] | (((int) buf[11]) << 8);+ h->width = (int) buf[12] | (((int) buf[13]) << 8);+ h->height = (int) buf[14] | (((int) buf[15]) << 8);+ h->bitsperpixel = (int) buf[16];+ h->imageinfo = (int) buf[17];++ // Extract alphabits and origin information+ h->_alphabits = (int) (h->imageinfo & _TGA_IMAGEINFO_ALPHA_MASK) >>+ _TGA_IMAGEINFO_ALPHA_SHIFT;+ h->_origin = (int) (h->imageinfo & _TGA_IMAGEINFO_ORIGIN_MASK) >>+ _TGA_IMAGEINFO_ORIGIN_SHIFT;++ // Validate TGA header (is this a TGA file?)+ if( (h->cmaptype == 0 || h->cmaptype == 1) &&+ ((h->imagetype >= 1 && h->imagetype <= 3) ||+ (h->imagetype >= 9 && h->imagetype <= 11)) &&+ (h->bitsperpixel == 8 || h->bitsperpixel == 24 ||+ h->bitsperpixel == 32) )+ {+ // Skip the ID field+ _glfwSeekStream( s, h->idlen, SEEK_CUR );++ // Indicate that the TGA header was valid+ return GL_TRUE;+ }+ else+ {+ // Restore file position+ _glfwSeekStream( s, pos, SEEK_SET );++ // Indicate that the TGA header was invalid+ return GL_FALSE;+ }+}++//========================================================================+// Read Run-Length Encoded data+//========================================================================++static void ReadTGA_RLE( unsigned char *buf, int size, int bpp,+ _GLFWstream *s )+{+ int repcount, bytes, k, n;+ unsigned char pixel[ 4 ];+ char c;++ // Dummy check+ if( bpp > 4 )+ {+ return;+ }++ while( size > 0 )+ {+ // Get repetition count+ _glfwReadStream( s, &c, 1 );+ repcount = (unsigned int) c;+ bytes = ((repcount & 127) + 1) * bpp;+ if( size < bytes )+ {+ bytes = size;+ }++ // Run-Length packet?+ if( repcount & 128 )+ {+ _glfwReadStream( s, pixel, bpp );+ for( n = 0; n < (repcount & 127) + 1; n ++ )+ {+ for( k = 0; k < bpp; k ++ )+ {+ *buf ++ = pixel[ k ];+ }+ }+ }+ else+ {+ // It's a Raw packet+ _glfwReadStream( s, buf, bytes );+ buf += bytes;+ }++ size -= bytes;+ }+}+++//========================================================================+// _glfwReadTGA() - Read a TGA image from a file+//========================================================================++int _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags )+{+ _tga_header_t h;+ unsigned char *cmap, *pix, tmp, *src, *dst;+ int cmapsize, pixsize, pixsize2;+ int bpp, bpp2, k, m, n, swapx, swapy;++ // Read TGA header+ if( !ReadTGAHeader( s, &h ) )+ {+ return 0;+ }++ // Is there a colormap?+ cmapsize = (h.cmaptype == _TGA_CMAPTYPE_PRESENT ? 1 : 0) * h.cmaplen *+ ((h.cmapentrysize+7) / 8);+ if( cmapsize > 0 )+ {+ // Is it a colormap that we can handle?+ if( (h.cmapentrysize != 24 && h.cmapentrysize != 32) ||+ h.cmaplen == 0 || h.cmaplen > 256 )+ {+ return 0;+ }++ // Allocate memory for colormap+ cmap = (unsigned char *) malloc( cmapsize );+ if( cmap == NULL )+ {+ return 0;+ }++ // Read colormap from file+ _glfwReadStream( s, cmap, cmapsize );+ }+ else+ {+ cmap = NULL;+ }++ // Size of pixel data+ pixsize = h.width * h.height * ((h.bitsperpixel + 7) / 8);++ // Bytes per pixel (pixel data - unexpanded)+ bpp = (h.bitsperpixel + 7) / 8;++ // Bytes per pixel (expanded pixels - not colormap indeces)+ if( cmap )+ {+ bpp2 = (h.cmapentrysize + 7) / 8;+ }+ else+ {+ bpp2 = bpp;+ }++ // For colormaped images, the RGB/RGBA image data may use more memory+ // than the stored pixel data+ pixsize2 = h.width * h.height * bpp2;++ // Allocate memory for pixel data+ pix = (unsigned char *) malloc( pixsize2 );+ if( pix == NULL )+ {+ if( cmap )+ {+ free( cmap );+ }+ return 0;+ }++ // Read pixel data from file+ if( h.imagetype >= _TGA_IMAGETYPE_CMAP_RLE )+ {+ ReadTGA_RLE( pix, pixsize, bpp, s );+ }+ else+ {+ _glfwReadStream( s, pix, pixsize );+ }++ // If the image origin is not what we want, re-arrange the pixels+ switch( h._origin )+ {+ default:+ case _TGA_ORIGIN_UL:+ swapx = 0;+ swapy = 1;+ break;++ case _TGA_ORIGIN_BL:+ swapx = 0;+ swapy = 0;+ break;++ case _TGA_ORIGIN_UR:+ swapx = 1;+ swapy = 1;+ break;++ case _TGA_ORIGIN_BR:+ swapx = 1;+ swapy = 0;+ break;+ }+ if( (swapy && !(flags & GLFW_ORIGIN_UL_BIT)) ||+ (!swapy && (flags & GLFW_ORIGIN_UL_BIT)) )+ {+ src = pix;+ dst = &pix[ (h.height-1)*h.width*bpp ];+ for( n = 0; n < h.height/2; n ++ )+ {+ for( m = 0; m < h.width ; m ++ )+ {+ for( k = 0; k < bpp; k ++ )+ {+ tmp = *src;+ *src ++ = *dst;+ *dst ++ = tmp;+ }+ }+ dst -= 2*h.width*bpp;+ }+ }+ if( swapx )+ {+ src = pix;+ dst = &pix[ (h.width-1)*bpp ];+ for( n = 0; n < h.height; n ++ )+ {+ for( m = 0; m < h.width/2 ; m ++ )+ {+ for( k = 0; k < bpp; k ++ )+ {+ tmp = *src;+ *src ++ = *dst;+ *dst ++ = tmp;+ }+ dst -= 2*bpp;+ }+ src += ((h.width+1)/2)*bpp;+ dst += ((3*h.width+1)/2)*bpp;+ }+ }++ // Convert BGR/BGRA to RGB/RGBA, and optionally colormap indeces to+ // RGB/RGBA values+ if( cmap )+ {+ // Convert colormap pixel format (BGR -> RGB or BGRA -> RGBA)+ if( bpp2 == 3 || bpp2 == 4 )+ {+ for( n = 0; n < h.cmaplen; n ++ )+ {+ tmp = cmap[ n*bpp2 ];+ cmap[ n*bpp2 ] = cmap[ n*bpp2 + 2 ];+ cmap[ n*bpp2 + 2 ] = tmp;+ }+ }++ // Convert pixel data to RGB/RGBA data+ for( m = h.width * h.height - 1; m >= 0; m -- )+ {+ n = pix[ m ];+ for( k = 0; k < bpp2; k ++ )+ {+ pix[ m*bpp2 + k ] = cmap[ n*bpp2 + k ];+ }+ }++ // Free memory for colormap (it's not needed anymore)+ free( cmap );+ }+ else+ {+ // Convert image pixel format (BGR -> RGB or BGRA -> RGBA)+ if( bpp2 == 3 || bpp2 == 4 )+ {+ src = pix;+ dst = &pix[ 2 ];+ for( n = 0; n < h.height * h.width; n ++ )+ {+ tmp = *src;+ *src = *dst;+ *dst = tmp;+ src += bpp2;+ dst += bpp2;+ }+ }+ }++ // Fill out GLFWimage struct (the Format field will be set by+ // glfwReadImage)+ img->Width = h.width;+ img->Height = h.height;+ img->BytesPerPixel = bpp2;+ img->Data = pix;++ return 1;+}+
+ glfw/lib/thread.c view
@@ -0,0 +1,340 @@+//========================================================================+// GLFW - An OpenGL framework+// File: thread.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// _glfwGetThreadPointer() - Find pointer to thread with a matching ID+//========================================================================++_GLFWthread * _glfwGetThreadPointer( int ID )+{+ _GLFWthread *t;++ for( t = &_glfwThrd.First; t != NULL; t = t->Next )+ {+ if( t->ID == ID )+ {+ break;+ }+ }++ return t;+}+++//========================================================================+// _glfwAppendThread() - Append thread to thread list+//========================================================================++void _glfwAppendThread( _GLFWthread * t )+{+ _GLFWthread *t_tmp;++ t_tmp = &_glfwThrd.First;+ while( t_tmp->Next != NULL )+ {+ t_tmp = t_tmp->Next;+ }+ t_tmp->Next = t;+ t->Previous = t_tmp;+ t->Next = NULL;+}+++//========================================================================+// _glfwRemoveThread() - Remove thread from thread list+//========================================================================++void _glfwRemoveThread( _GLFWthread * t )+{+ if( t->Previous != NULL )+ {+ t->Previous->Next = t->Next;+ }+ if( t->Next != NULL )+ {+ t->Next->Previous = t->Previous;+ }+ free( (void *) t );+}++++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// glfwCreateThread() - Create a new thread+//========================================================================++GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun,+ void *arg )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return -1;+ }++ // Return the GLFW thread ID+ return _glfwPlatformCreateThread( fun, arg );+}+++//========================================================================+// glfwDestroyThread() - Kill a thread. NOTE: THIS IS A VERY DANGEROUS+// OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME SITUATIONS!+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return;+ }++ // Is it a valid thread? (killing the main thread is not allowed)+ if( ID < 1 )+ {+ return;+ }++ _glfwPlatformDestroyThread( ID );+}+++//========================================================================+// glfwWaitThread() - Wait for a thread to die+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return GL_TRUE;+ }++ // Is it a valid thread? (waiting for the main thread is not allowed)+ if( ID < 1 )+ {+ return GL_TRUE;+ }++ return _glfwPlatformWaitThread( ID, waitmode );+}+++//========================================================================+// glfwGetThreadID() - Return the thread ID for the current thread+//========================================================================++GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return 0;+ }++ return _glfwPlatformGetThreadID();+}+++//========================================================================+// glfwCreateMutex() - Create a mutual exclusion object+//========================================================================++GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return (GLFWmutex) 0;+ }++ return _glfwPlatformCreateMutex();+}+++//========================================================================+// glfwDestroyMutex() - Destroy a mutual exclusion object+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex )+{+ // Initialized & valid mutex (no real way of assuring this)?+ if( !_glfwInitialized || !mutex )+ {+ return;+ }++ _glfwPlatformDestroyMutex( mutex );+}+++//========================================================================+// glfwLockMutex() - Request access to a mutex+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex )+{+ // Initialized & valid mutex (no real way of assuring this)?+ if( !_glfwInitialized && !mutex )+ {+ return;+ }++ _glfwPlatformLockMutex( mutex );+}+++//========================================================================+// glfwUnlockMutex() - Release a mutex+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex )+{+ // Initialized & valid mutex (no real way of assuring this)?+ if( !_glfwInitialized && !mutex )+ {+ return;+ }++ _glfwPlatformUnlockMutex( mutex );+}+++//========================================================================+// glfwCreateCond() - Create a new condition variable object+//========================================================================++GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return (GLFWcond) 0;+ }++ return _glfwPlatformCreateCond();+}+++//========================================================================+// glfwDestroyCond() - Destroy a condition variable object+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond )+{+ // Initialized & valid condition variable?+ if( !_glfwInitialized || !cond )+ {+ return;+ }++ _glfwPlatformDestroyCond( cond );+}+++//========================================================================+// glfwWaitCond() - Wait for a condition to be raised+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex,+ double timeout )+{+ // Initialized & valid condition variable and mutex?+ if( !_glfwInitialized || !cond || !mutex )+ {+ return;+ }++ _glfwPlatformWaitCond( cond, mutex, timeout );+}+++//========================================================================+// glfwSignalCond() - Signal a condition to one waiting thread+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond )+{+ // Initialized & valid condition variable?+ if( !_glfwInitialized || !cond )+ {+ return;+ }++ _glfwPlatformSignalCond( cond );+}+++//========================================================================+// glfwBroadcastCond() - Broadcast a condition to all waiting threads+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond )+{+ // Initialized & valid condition variable?+ if( !_glfwInitialized || !cond )+ {+ return;+ }++ _glfwPlatformBroadcastCond( cond );+}+++//========================================================================+// glfwGetNumberOfProcessors() - Return the number of processors in the+// system. This information can be useful for determining the optimal+// number of threads to use for performing a certain task.+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetNumberOfProcessors( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return 0;+ }++ return _glfwPlatformGetNumberOfProcessors();+}
+ glfw/lib/time.c view
@@ -0,0 +1,83 @@+//========================================================================+// GLFW - An OpenGL framework+// File: time.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// glfwGetTime() - Return timer value in seconds+//========================================================================++GLFWAPI double GLFWAPIENTRY glfwGetTime( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return 0.0;+ }++ return _glfwPlatformGetTime();+}+++//========================================================================+// glfwSetTime() - Set timer value in seconds+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetTime( double time )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return;+ }++ _glfwPlatformSetTime( time );+}+++//========================================================================+// glfwSleep() - Put a thread to sleep for a specified amount of time+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSleep( double time )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return;+ }++ _glfwPlatformSleep( time );+}
+ glfw/lib/win32/win32_dllmain.c view
@@ -0,0 +1,60 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_dllmain.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++#if defined(GLFW_BUILD_DLL)++//========================================================================+// GLFW DLL entry point+//========================================================================++BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, LPVOID reserved )+{+ // NOTE: Some compilers complains about instance and x never being used -+ // never mind that (we don't want to use them)!++ switch( reason )+ {+ case DLL_PROCESS_ATTACH:+ // Initializations+ break;+ case DLL_PROCESS_DETACH:+ // Do some cleanup+ glfwTerminate();+ break;+ };++ return TRUE;+}++#endif // GLFW_BUILD_DLL+
+ glfw/lib/win32/win32_enable.c view
@@ -0,0 +1,155 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_enable.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// Low level keyboard hook (system callback) function+// Used to disable system keys under Windows NT+//========================================================================++static LRESULT CALLBACK keyboardHook( int nCode, WPARAM wParam, LPARAM lParam )+{+ BOOL syskeys = FALSE;+ PKBDLLHOOKSTRUCT p;++ // We are only looking for keyboard events - interpret lParam as a+ // pointer to a KBDLLHOOKSTRUCT+ p = (PKBDLLHOOKSTRUCT) lParam;++ if( nCode == HC_ACTION )+ {+ // We have a keyboard event++ switch( wParam )+ {+ case WM_KEYDOWN:+ case WM_SYSKEYDOWN:+ case WM_KEYUP:+ case WM_SYSKEYUP:+ // Detect: ALT+TAB, ALT+ESC, ALT+F4, CTRL+ESC,+ // LWIN, RWIN, APPS (mysterious menu key)+ syskeys = ( p->vkCode == VK_TAB &&+ p->flags & LLKHF_ALTDOWN ) ||+ ( p->vkCode == VK_ESCAPE &&+ p->flags & LLKHF_ALTDOWN ) ||+ ( p->vkCode == VK_F4 &&+ p->flags & LLKHF_ALTDOWN ) ||+ ( p->vkCode == VK_ESCAPE &&+ (GetKeyState(VK_CONTROL) & 0x8000)) ||+ p->vkCode == VK_LWIN ||+ p->vkCode == VK_RWIN ||+ p->vkCode == VK_APPS;+ break;++ default:+ break;+ }+ }++ // Was it a system key combination (e.g. ALT+TAB)?+ if( syskeys )+ {+ // Pass the key event to our window message loop+ if( _glfwWin.opened )+ {+ PostMessage( _glfwWin.window, (UINT) wParam, p->vkCode, 0 );+ }++ // We've taken care of it - don't let the system know about this+ // key event+ return 1;+ }+ else+ {+ // It's a harmless key press, let the system deal with it+ return CallNextHookEx( _glfwWin.keyboardHook, nCode, wParam, lParam );+ }+}++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Enable system keys+//========================================================================++void _glfwPlatformEnableSystemKeys( void )+{+ BOOL dummy;++ // Use different methods depending on operating system version+ if( _glfwLibrary.Sys.winVer >= _GLFW_WIN_NT4 )+ {+ if( _glfwWin.keyboardHook != NULL )+ {+ UnhookWindowsHookEx( _glfwWin.keyboardHook );+ _glfwWin.keyboardHook = NULL;+ }+ }+ else+ {+ (void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, FALSE, &dummy, 0 );+ }+}++//========================================================================+// Disable system keys+//========================================================================++void _glfwPlatformDisableSystemKeys( void )+{+ BOOL dummy;++ // Use different methods depending on operating system version+ if( _glfwLibrary.Sys.winVer >= _GLFW_WIN_NT4 )+ {+ // Under Windows NT, install a low level keyboard hook+ _glfwWin.keyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,+ keyboardHook,+ _glfwLibrary.instance,+ 0 );+ }+ else+ {+ // Under Windows 95/98/ME, fool Windows that a screensaver+ // is running => prevents ALT+TAB, CTRL+ESC and CTRL+ALT+DEL+ (void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, TRUE, &dummy, 0 );+ }+}+
+ glfw/lib/win32/win32_fullscreen.c view
@@ -0,0 +1,320 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_fullscreen.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// Convert BPP to RGB bits based on "best guess"+//========================================================================++static void bpp2rgb( int bpp, int *r, int *g, int *b )+{+ int delta;++ // We assume that by 32 they really meant 24+ if( bpp == 32 )+ {+ bpp = 24;+ }++ // Convert "bits per pixel" to red, green & blue sizes++ *r = *g = *b = bpp / 3;+ delta = bpp - (*r * 3);+ if( delta >= 1 )+ {+ *g = *g + 1;+ }+ if( delta == 2 )+ {+ *r = *r + 1;+ }+}+++//========================================================================+// Return closest video mode by dimensions, refresh rate and bits per pixel+//========================================================================++int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh )+{+ int mode, bestmode, match, bestmatch, rr, bestrr, success;+ DEVMODE dm;++ // Find best match+ bestmatch = 0x7fffffff;+ bestrr = 0x7fffffff;+ mode = bestmode = 0;+ do+ {+ dm.dmSize = sizeof( DEVMODE );+ success = EnumDisplaySettings( NULL, mode, &dm );+ if( success )+ {+ match = dm.dmBitsPerPel - *bpp;+ if( match < 0 ) match = -match;+ match = ( match << 25 ) |+ ( (dm.dmPelsWidth - *w) *+ (dm.dmPelsWidth - *w) ++ (dm.dmPelsHeight - *h) *+ (dm.dmPelsHeight - *h) );+ if( match < bestmatch )+ {+ bestmatch = match;+ bestmode = mode;+ bestrr = (dm.dmDisplayFrequency - *refresh) *+ (dm.dmDisplayFrequency - *refresh);+ }+ else if( match == bestmatch && *refresh > 0 )+ {+ rr = (dm.dmDisplayFrequency - *refresh) *+ (dm.dmDisplayFrequency - *refresh);+ if( rr < bestrr )+ {+ bestmatch = match;+ bestmode = mode;+ bestrr = rr;+ }+ }+ }+ mode ++;+ }+ while( success );++ // Get the parameters for the best matching display mode+ dm.dmSize = sizeof( DEVMODE );+ (void) EnumDisplaySettings( NULL, bestmode, &dm );++ // Fill out actual width and height+ *w = dm.dmPelsWidth;+ *h = dm.dmPelsHeight;++ // Return bits per pixel+ *bpp = dm.dmBitsPerPel;++ // Return vertical refresh rate+ *refresh = dm.dmDisplayFrequency;++ return bestmode;+}+++//========================================================================+// Return closest video mode by dimensions, refresh rate and channel sizes+//========================================================================++static int getClosestVideoMode( int *w, int *h,+ int *r, int *g, int *b,+ int *refresh )+{+ int bpp, bestmode;++ // Colorbits = sum of red/green/blue bits+ bpp = *r + *g + *b;++ // If colorbits < 15 (e.g. 0) or >= 24, default to 32 bpp+ if( bpp < 15 || bpp >= 24 )+ {+ bpp = 32;+ }++ // Find best match+ bestmode = _glfwGetClosestVideoModeBPP( w, h, &bpp, refresh );++ // Convert "bits per pixel" to red, green & blue sizes+ bpp2rgb( bpp, r, g, b );++ return bestmode;+}+++//========================================================================+// Change the current video mode+//========================================================================++void _glfwSetVideoModeMODE( int mode )+{+ DEVMODE dm;+ int success;++ // Get the parameters for the best matching display mode+ dm.dmSize = sizeof( DEVMODE );+ (void) EnumDisplaySettings( NULL, mode, &dm );++ // Set which fields we want to specify+ dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;++ // Do we have a prefered refresh rate?+ if( _glfwWin.desiredRefreshRate > 0 )+ {+ dm.dmFields = dm.dmFields | DM_DISPLAYFREQUENCY;+ dm.dmDisplayFrequency = _glfwWin.desiredRefreshRate;+ }++ // Change display setting+ dm.dmSize = sizeof( DEVMODE );+ success = ChangeDisplaySettings( &dm, CDS_FULLSCREEN );++ // If the mode change was not possible, query the current display+ // settings (we'll use the desktop resolution for fullscreen mode)+ if( success == DISP_CHANGE_SUCCESSFUL )+ {+ _glfwWin.modeID = mode;+ }+ else+ {+ _glfwWin.modeID = ENUM_REGISTRY_SETTINGS;+ EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm );+ }++ // Set the window size to that of the display mode+ _glfwWin.width = dm.dmPelsWidth;+ _glfwWin.height = dm.dmPelsHeight;+}+++//========================================================================+// _glfwSetVideoMode() - Change the current video mode+//========================================================================++void _glfwSetVideoMode( int *w, int *h, int r, int g, int b, int refresh )+{+ int bestmode;++ // Find a best match mode+ bestmode = getClosestVideoMode( w, h, &r, &g, &b, &refresh );++ // Change mode+ _glfwSetVideoModeMODE( bestmode );+}+++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// _glfwPlatformGetVideoModes() - Get a list of available video modes+//========================================================================++int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )+{+ int count, success, mode, i, j;+ int m1, m2, bpp, r, g, b;+ DEVMODE dm;++ // Loop through all video modes and extract all the UNIQUE modes+ count = 0;+ mode = 0;+ do+ {+ // Get video mode properties+ dm.dmSize = sizeof( DEVMODE );+ success = EnumDisplaySettings( NULL, mode, &dm );++ // Is it a valid mode? (only list depths >= 15 bpp)+ if( success && dm.dmBitsPerPel >= 15 )+ {+ // Convert to RGB, and back to bpp ("mask out" alpha bits etc)+ bpp2rgb( dm.dmBitsPerPel, &r, &g, &b );+ bpp = r + g + b;++ // Mode "code" for this mode+ m1 = (bpp << 25) | (dm.dmPelsWidth * dm.dmPelsHeight);++ // Insert mode in list (sorted), and avoid duplicates+ for( i = 0; i < count; i ++ )+ {+ // Mode "code" for already listed mode+ bpp = list[i].RedBits + list[i].GreenBits ++ list[i].BlueBits;+ m2 = (bpp << 25) | (list[i].Width * list[i].Height);+ if( m1 <= m2 )+ {+ break;+ }+ }++ // New entry at the end of the list?+ if( i >= count )+ {+ list[count].Width = dm.dmPelsWidth;+ list[count].Height = dm.dmPelsHeight;+ list[count].RedBits = r;+ list[count].GreenBits = g;+ list[count].BlueBits = b;+ count ++;+ }+ // Insert new entry in the list?+ else if( m1 < m2 )+ {+ for( j = count; j > i; j -- )+ {+ list[j] = list[j-1];+ }+ list[i].Width = dm.dmPelsWidth;+ list[i].Height = dm.dmPelsHeight;+ list[i].RedBits = r;+ list[i].GreenBits = g;+ list[i].BlueBits = b;+ count ++;+ }+ }+ mode ++;+ }+ while( success && (count < maxcount) );++ return count;+}+++//========================================================================+// Get the desktop video mode+//========================================================================++void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )+{+ DEVMODE dm;++ // Get desktop display mode+ dm.dmSize = sizeof( DEVMODE );+ (void) EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm );++ // Return desktop mode parameters+ mode->Width = dm.dmPelsWidth;+ mode->Height = dm.dmPelsHeight;+ bpp2rgb( dm.dmBitsPerPel, &mode->RedBits, &mode->GreenBits, &mode->BlueBits );+}+
+ glfw/lib/win32/win32_glext.c view
@@ -0,0 +1,82 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_glext.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Check if the current context supports the specified WGL extension+//========================================================================++int _glfwPlatformExtensionSupported( const char *extension )+{+ const GLubyte *extensions;++ if( _glfwWin.GetExtensionsStringEXT != NULL )+ {+ extensions = (GLubyte *) _glfwWin.GetExtensionsStringEXT();+ if( extensions != NULL )+ {+ if( _glfwStringInExtensionString( extension, extensions ) )+ {+ return GL_TRUE;+ }+ }+ }++ if( _glfwWin.GetExtensionsStringARB != NULL )+ {+ extensions = (GLubyte *) _glfwWin.GetExtensionsStringARB( _glfwWin.DC );+ if( extensions != NULL )+ {+ if( _glfwStringInExtensionString( extension, extensions ) )+ {+ return GL_TRUE;+ }+ }+ }++ return GL_FALSE;+}+++//========================================================================+// Get the function pointer to an OpenGL function+//========================================================================++void *_glfwPlatformGetProcAddress( const char *procname )+{+ return (void *) wglGetProcAddress( procname );+}+
+ glfw/lib/win32/win32_init.c view
@@ -0,0 +1,356 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_init.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++// With the Borland C++ compiler, we want to disable FPU exceptions+#ifdef __BORLANDC__+#include <float.h>+#endif // __BORLANDC__++++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// _glfwInitLibraries() - Load necessary libraries (DLLs)+//========================================================================++static int _glfwInitLibraries( void )+{+ // gdi32.dll (OpenGL pixel format functions & SwapBuffers)+#ifndef _GLFW_NO_DLOAD_GDI32+ _glfwLibrary.Libs.gdi32 = LoadLibrary( "gdi32.dll" );+ if( _glfwLibrary.Libs.gdi32 != NULL )+ {+ _glfwLibrary.Libs.ChoosePixelFormat = (CHOOSEPIXELFORMAT_T)+ GetProcAddress( _glfwLibrary.Libs.gdi32, "ChoosePixelFormat" );+ _glfwLibrary.Libs.DescribePixelFormat = (DESCRIBEPIXELFORMAT_T)+ GetProcAddress( _glfwLibrary.Libs.gdi32, "DescribePixelFormat" );+ _glfwLibrary.Libs.GetPixelFormat = (GETPIXELFORMAT_T)+ GetProcAddress( _glfwLibrary.Libs.gdi32, "GetPixelFormat" );+ _glfwLibrary.Libs.SetPixelFormat = (SETPIXELFORMAT_T)+ GetProcAddress( _glfwLibrary.Libs.gdi32, "SetPixelFormat" );+ _glfwLibrary.Libs.SwapBuffers = (SWAPBUFFERS_T)+ GetProcAddress( _glfwLibrary.Libs.gdi32, "SwapBuffers" );+ if( _glfwLibrary.Libs.ChoosePixelFormat == NULL ||+ _glfwLibrary.Libs.DescribePixelFormat == NULL ||+ _glfwLibrary.Libs.GetPixelFormat == NULL ||+ _glfwLibrary.Libs.SetPixelFormat == NULL ||+ _glfwLibrary.Libs.SwapBuffers == NULL )+ {+ FreeLibrary( _glfwLibrary.Libs.gdi32 );+ _glfwLibrary.Libs.gdi32 = NULL;+ return GL_FALSE;+ }+ }+ else+ {+ return GL_FALSE;+ }+#endif // _GLFW_NO_DLOAD_GDI32++ // winmm.dll (for joystick and timer support)+#ifndef _GLFW_NO_DLOAD_WINMM+ _glfwLibrary.Libs.winmm = LoadLibrary( "winmm.dll" );+ if( _glfwLibrary.Libs.winmm != NULL )+ {+ _glfwLibrary.Libs.joyGetDevCapsA = (JOYGETDEVCAPSA_T)+ GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetDevCapsA" );+ _glfwLibrary.Libs.joyGetPos = (JOYGETPOS_T)+ GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetPos" );+ _glfwLibrary.Libs.joyGetPosEx = (JOYGETPOSEX_T)+ GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetPosEx" );+ _glfwLibrary.Libs.timeGetTime = (TIMEGETTIME_T)+ GetProcAddress( _glfwLibrary.Libs.winmm, "timeGetTime" );+ if( _glfwLibrary.Libs.joyGetDevCapsA == NULL ||+ _glfwLibrary.Libs.joyGetPos == NULL ||+ _glfwLibrary.Libs.joyGetPosEx == NULL ||+ _glfwLibrary.Libs.timeGetTime == NULL )+ {+ FreeLibrary( _glfwLibrary.Libs.winmm );+ _glfwLibrary.Libs.winmm = NULL;+ return GL_FALSE;+ }+ }+ else+ {+ return GL_FALSE;+ }+#endif // _GLFW_NO_DLOAD_WINMM++ return GL_TRUE;+}+++//========================================================================+// _glfwFreeLibraries() - Unload used libraries (DLLs)+//========================================================================++static void _glfwFreeLibraries( void )+{+ // gdi32.dll+#ifndef _GLFW_NO_DLOAD_GDI32+ if( _glfwLibrary.Libs.gdi32 != NULL )+ {+ FreeLibrary( _glfwLibrary.Libs.gdi32 );+ _glfwLibrary.Libs.gdi32 = NULL;+ }+#endif // _GLFW_NO_DLOAD_GDI32++ // winmm.dll+#ifndef _GLFW_NO_DLOAD_WINMM+ if( _glfwLibrary.Libs.winmm != NULL )+ {+ FreeLibrary( _glfwLibrary.Libs.winmm );+ _glfwLibrary.Libs.winmm = NULL;+ }+#endif // _GLFW_NO_DLOAD_WINMM+}+++//========================================================================+// _glfwInitThreads() - Initialize GLFW thread package+//========================================================================++static void _glfwInitThreads( void )+{+ // Initialize critical section handle+ InitializeCriticalSection( &_glfwThrd.CriticalSection );++ // The first thread (the main thread) has ID 0+ _glfwThrd.NextID = 0;++ // Fill out information about the main thread (this thread)+ _glfwThrd.First.ID = _glfwThrd.NextID ++;+ _glfwThrd.First.Function = NULL;+ _glfwThrd.First.Handle = GetCurrentThread();+ _glfwThrd.First.WinID = GetCurrentThreadId();+ _glfwThrd.First.Previous = NULL;+ _glfwThrd.First.Next = NULL;+}+++//========================================================================+// _glfwTerminateThreads() - Terminate GLFW thread package+//========================================================================++static void _glfwTerminateThreads( void )+{+ _GLFWthread *t, *t_next;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO+ // DIE, _BEFORE_ CALLING glfwTerminate()!!!)+ t = _glfwThrd.First.Next;+ while( t != NULL )+ {+ // Get pointer to next thread+ t_next = t->Next;++ // Simply murder the process, no mercy!+ if( TerminateThread( t->Handle, 0 ) )+ {+ // Close thread handle+ CloseHandle( t->Handle );++ // Free memory allocated for this thread+ free( (void *) t );+ }++ // Select next thread in list+ t = t_next;+ }++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Delete critical section handle+ DeleteCriticalSection( &_glfwThrd.CriticalSection );+}+++//========================================================================+// _glfwTerminate_atexit() - Terminate GLFW when exiting application+//========================================================================++void _glfwTerminate_atexit( void )+{+ glfwTerminate();+}++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// _glfwPlatformInit() - Initialize various GLFW state+//========================================================================++int _glfwPlatformInit( void )+{+ OSVERSIONINFO osi;++ // 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)+ SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT, 0,+ &_glfwLibrary.Sys.foregroundLockTimeout, 0 );+ SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0,+ SPIF_SENDCHANGE );++ // Check which OS version we are running+ osi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );+ GetVersionEx( &osi );+ _glfwLibrary.Sys.winVer = _GLFW_WIN_UNKNOWN;+ if( osi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )+ {+ if( osi.dwMajorVersion == 4 && osi.dwMinorVersion < 10 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_95;+ }+ else if( osi.dwMajorVersion == 4 && osi.dwMinorVersion < 90 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_98;+ }+ else if( osi.dwMajorVersion == 4 && osi.dwMinorVersion == 90 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_ME;+ }+ else if( osi.dwMajorVersion >= 4 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_UNKNOWN_9x;+ }+ }+ else if( osi.dwPlatformId == VER_PLATFORM_WIN32_NT )+ {+ if( osi.dwMajorVersion == 4 && osi.dwMinorVersion == 0 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_NT4;+ }+ else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 0 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_2K;+ }+ else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 1 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_XP;+ }+ else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 2 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_NET_SERVER;+ }+ else if( osi.dwMajorVersion >= 5 )+ {+ _glfwLibrary.Sys.winVer = _GLFW_WIN_UNKNOWN_NT;+ }+ }++ // Do we have Unicode support?+ if( _glfwLibrary.Sys.winVer >= _GLFW_WIN_NT4 )+ {+ // Windows NT/2000/XP/.NET has Unicode support+ _glfwLibrary.Sys.hasUnicode = GL_TRUE;+ }+ else+ {+ // Windows 9x/ME does not have Unicode support+ _glfwLibrary.Sys.hasUnicode = GL_FALSE;+ }++ // Load libraries (DLLs)+ if( !_glfwInitLibraries() )+ {+ return GL_FALSE;+ }++ // With the Borland C++ compiler, we want to disable FPU exceptions+ // (this is recommended for OpenGL applications under Windows)+#ifdef __BORLANDC__+ _control87( MCW_EM, MCW_EM );+#endif++ // Retrieve GLFW instance handle+ _glfwLibrary.instance = GetModuleHandle( NULL );++ // System keys are not disabled+ _glfwWin.keyboardHook = NULL;++ // Initialise thread package+ _glfwInitThreads();++ // Install atexit() routine+ atexit( _glfwTerminate_atexit );++ // Start the timer+ _glfwInitTimer();++ return GL_TRUE;+}+++//========================================================================+// _glfwPlatformTerminate() - Close window and kill all threads+//========================================================================++int _glfwPlatformTerminate( void )+{+ // Only the main thread is allowed to do this...+ if( GetCurrentThreadId() != _glfwThrd.First.WinID )+ {+ return GL_FALSE;+ }++ // Close OpenGL window+ glfwCloseWindow();++ // Kill thread package+ _glfwTerminateThreads();++ // Enable system keys again (if they were disabled)+ glfwEnable( GLFW_SYSTEM_KEYS );++ // Unload libraries (DLLs)+ _glfwFreeLibraries();++ // Restore FOREGROUNDLOCKTIMEOUT system setting+ SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0,+ (LPVOID)_glfwLibrary.Sys.foregroundLockTimeout,+ SPIF_SENDCHANGE );++ return GL_TRUE;+}+
+ glfw/lib/win32/win32_joystick.c view
@@ -0,0 +1,234 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_joystick.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// _glfwJoystickPresent() - Return GL_TRUE if joystick is present,+// else return GL_FALSE.+//========================================================================++static int _glfwJoystickPresent( int joy )+{+ JOYINFO ji;++ // Windows NT 4.0 MMSYSTEM only supports 2 sticks (other Windows+ // versions support 16 sticks)+ if( _glfwLibrary.Sys.winVer == _GLFW_WIN_NT4 && joy > GLFW_JOYSTICK_2 )+ {+ return GL_FALSE;+ }++ // Is it a valid stick ID (Windows don't support more than 16 sticks)?+ if( joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_16 )+ {+ return GL_FALSE;+ }++ // Is the joystick present?+ if( _glfw_joyGetPos( joy - GLFW_JOYSTICK_1, &ji ) != JOYERR_NOERROR )+ {+ return GL_FALSE;+ }++ return GL_TRUE;+}+++//========================================================================+// _glfwCalcJoystickPos() - Calculate joystick position+//========================================================================++static float _glfwCalcJoystickPos( DWORD pos, DWORD min, DWORD max )+{+ float fpos = (float) pos;+ float fmin = (float) min;+ float fmax = (float) max;+ return (2.0f*(fpos - fmin) / (fmax - fmin)) - 1.0f;+}++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// _glfwPlatformGetJoystickParam() - Determine joystick capabilities+//========================================================================++int _glfwPlatformGetJoystickParam( int joy, int param )+{+ JOYCAPS jc;++// return 0;++ // Is joystick present?+ if( !_glfwJoystickPresent( joy ) )+ {+ return 0;+ }++ // We got this far, the joystick is present+ if( param == GLFW_PRESENT )+ {+ return GL_TRUE;+ }++ // Get joystick capabilities+ _glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) );++ switch( param )+ {+ case GLFW_AXES:+ // Return number of joystick axes+ return jc.wNumAxes;++ case GLFW_BUTTONS:+ // Return number of joystick axes+ return jc.wNumButtons;++ default:+ break;+ }++ return 0;+}+++//========================================================================+// _glfwPlatformGetJoystickPos() - Get joystick axis positions+//========================================================================++int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )+{+ JOYCAPS jc;+ JOYINFOEX ji;+ int axis;++// return 0;++ // Is joystick present?+ if( !_glfwJoystickPresent( joy ) )+ {+ return 0;+ }++ // Get joystick capabilities+ _glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) );++ // Get joystick state+ ji.dwSize = sizeof( JOYINFOEX );+ ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ |+ JOY_RETURNR | JOY_RETURNU | JOY_RETURNV;+ _glfw_joyGetPosEx( joy - GLFW_JOYSTICK_1, &ji );++ // Get position values for all axes+ axis = 0;+ if( axis < numaxes )+ {+ pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwXpos, jc.wXmin,+ jc.wXmax );+ }+ if( axis < numaxes )+ {+ pos[ axis++ ] = -_glfwCalcJoystickPos( ji.dwYpos, jc.wYmin,+ jc.wYmax );+ }+ if( axis < numaxes && jc.wCaps & JOYCAPS_HASZ )+ {+ pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwZpos, jc.wZmin,+ jc.wZmax );+ }+ if( axis < numaxes && jc.wCaps & JOYCAPS_HASR )+ {+ pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwRpos, jc.wRmin,+ jc.wRmax );+ }+ if( axis < numaxes && jc.wCaps & JOYCAPS_HASU )+ {+ pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwUpos, jc.wUmin,+ jc.wUmax );+ }+ if( axis < numaxes && jc.wCaps & JOYCAPS_HASV )+ {+ pos[ axis++ ] = -_glfwCalcJoystickPos( ji.dwVpos, jc.wVmin,+ jc.wVmax );+ }++ // Return number of returned axes+ return axis;+}+++//========================================================================+// _glfwPlatformGetJoystickButtons() - Get joystick button states+//========================================================================++int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,+ int numbuttons )+{+ JOYCAPS jc;+ JOYINFOEX ji;+ int button;++// return 0;++ // Is joystick present?+ if( !_glfwJoystickPresent( joy ) )+ {+ return 0;+ }++ // Get joystick capabilities+ _glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) );++ // Get joystick state+ ji.dwSize = sizeof( JOYINFOEX );+ ji.dwFlags = JOY_RETURNBUTTONS;+ _glfw_joyGetPosEx( joy - GLFW_JOYSTICK_1, &ji );++ // Get states of all requested buttons+ button = 0;+ while( button < numbuttons && button < (int) jc.wNumButtons )+ {+ buttons[ button ] = (unsigned char)+ (ji.dwButtons & (1UL << button) ? GLFW_PRESS : GLFW_RELEASE);+ button ++;+ }++ return button;+}+
+ glfw/lib/win32/win32_thread.c view
@@ -0,0 +1,511 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_thread.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+// This is an implementation of POSIX "compatible" condition variables for+// Win32, as described by Douglas C. Schmidt and Irfan Pyarali:+// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html+//************************************************************************++enum {+ _GLFW_COND_SIGNAL = 0,+ _GLFW_COND_BROADCAST = 1+};++typedef struct {+ // Signal and broadcast event HANDLEs+ HANDLE events[ 2 ];++ // Count of the number of waiters+ unsigned int waiters_count;++ // Serialize access to <waiters_count>+ CRITICAL_SECTION waiters_count_lock;+} _GLFWcond;++++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// _glfwNewThread() - This is simply a "wrapper" for calling the user+// thread function.+//========================================================================++DWORD WINAPI _glfwNewThread( LPVOID lpParam )+{+ GLFWthreadfun threadfun;+ _GLFWthread *t;++ // Get pointer to thread information for current thread+ t = _glfwGetThreadPointer( _glfwPlatformGetThreadID() );+ if( t == NULL )+ {+ return 0;+ }++ // Get user thread function pointer+ threadfun = t->Function;++ // Call the user thread function+ threadfun( (void *) lpParam );++ // Remove thread from thread list+ ENTER_THREAD_CRITICAL_SECTION+ _glfwRemoveThread( t );+ LEAVE_THREAD_CRITICAL_SECTION++ // When the thread function returns, the thread will die...+ return 0;+}++++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// _glfwPlatformCreateThread() - Create a new thread+//========================================================================++GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )+{+ GLFWthread ID;+ _GLFWthread *t, *t_tmp;+ HANDLE hThread;+ DWORD dwThreadId;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Create a new thread information memory area+ t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );+ if( t == NULL )+ {+ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION+ return -1;+ }++ // Get a new unique thread id+ ID = _glfwThrd.NextID ++;++ // Store thread information in the thread list+ t->Function = fun;+ t->ID = ID;++ // Create thread+ hThread = CreateThread(+ NULL, // Default security attributes+ 0, // Default stack size (1 MB)+ _glfwNewThread, // Thread function (a wrapper function)+ (LPVOID)arg, // Argument to thread is the user argument+ 0, // Default creation flags+ &dwThreadId // Returned thread identifier+ );++ // Did the thread creation fail?+ if( hThread == NULL )+ {+ free( (void *) t );+ LEAVE_THREAD_CRITICAL_SECTION+ return -1;+ }++ // Store more thread information in the thread list+ t->Handle = hThread;+ t->WinID = dwThreadId;++ // Append thread to thread list+ t_tmp = &_glfwThrd.First;+ while( t_tmp->Next != NULL )+ {+ t_tmp = t_tmp->Next;+ }+ t_tmp->Next = t;+ t->Previous = t_tmp;+ t->Next = NULL;++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Return the GLFW thread ID+ return ID;+}+++//========================================================================+// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY+// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME+// SITUATIONS!+//========================================================================++void _glfwPlatformDestroyThread( GLFWthread ID )+{+ _GLFWthread *t;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Get thread information pointer+ t = _glfwGetThreadPointer( ID );+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return;+ }++ // Simply murder the process, no mercy!+ if( TerminateThread( t->Handle, 0 ) )+ {+ // Close thread handle+ CloseHandle( t->Handle );++ // Remove thread from thread list+ _glfwRemoveThread( t );+ }++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION+}+++//========================================================================+// _glfwPlatformWaitThread() - Wait for a thread to die+//========================================================================++int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )+{+ DWORD result;+ HANDLE hThread;+ _GLFWthread *t;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Get thread information pointer+ t = _glfwGetThreadPointer( ID );++ // Is the thread already dead?+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return GL_TRUE;+ }++ // Get thread handle+ hThread = t->Handle;++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Wait for thread to die+ if( waitmode == GLFW_WAIT )+ {+ result = WaitForSingleObject( hThread, INFINITE );+ }+ else if( waitmode == GLFW_NOWAIT )+ {+ result = WaitForSingleObject( hThread, 0 );+ }+ else+ {+ return GL_FALSE;+ }++ // Did we have a time-out?+ if( result == WAIT_TIMEOUT )+ {+ return GL_FALSE;+ }+ return GL_TRUE;+}+++//========================================================================+// _glfwPlatformGetThreadID() - Return the thread ID for the current+// thread+//========================================================================++GLFWthread _glfwPlatformGetThreadID( void )+{+ _GLFWthread *t;+ GLFWthread ID = -1;+ DWORD WinID;++ // Get Windows thread ID+ WinID = GetCurrentThreadId();++ // Enter critical section (to avoid an inconsistent thread list)+ ENTER_THREAD_CRITICAL_SECTION++ // Loop through entire list of threads to find the matching Windows+ // thread ID+ for( t = &_glfwThrd.First; t != NULL; t = t->Next )+ {+ if( t->WinID == WinID )+ {+ ID = t->ID;+ break;+ }+ }++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Return the found GLFW thread identifier+ return ID;+}+++//========================================================================+// _glfwPlatformCreateMutex() - Create a mutual exclusion object+//========================================================================++GLFWmutex _glfwPlatformCreateMutex( void )+{+ CRITICAL_SECTION *mutex;++ // Allocate memory for mutex+ mutex = (CRITICAL_SECTION *) malloc( sizeof(CRITICAL_SECTION) );+ if( !mutex )+ {+ return NULL;+ }++ // Initialize mutex+ InitializeCriticalSection( mutex );++ // Cast to GLFWmutex and return+ return (GLFWmutex) mutex;+}+++//========================================================================+// glfwDestroyMutex() - Destroy a mutual exclusion object+//========================================================================++void _glfwPlatformDestroyMutex( GLFWmutex mutex )+{+ // Destroy mutex+ DeleteCriticalSection( (CRITICAL_SECTION *) mutex );+ free( mutex );+}+++//========================================================================+// _glfwPlatformLockMutex() - Request access to a mutex+//========================================================================++void _glfwPlatformLockMutex( GLFWmutex mutex )+{+ // Wait for mutex to be released+ EnterCriticalSection( (CRITICAL_SECTION *) mutex );+}+++//========================================================================+// _glfwPlatformUnlockMutex() - Release a mutex+//========================================================================++void _glfwPlatformUnlockMutex( GLFWmutex mutex )+{+ // Release mutex+ LeaveCriticalSection( (CRITICAL_SECTION *) mutex );+}+++//========================================================================+// _glfwPlatformCreateCond() - Create a new condition variable object+//========================================================================++GLFWcond _glfwPlatformCreateCond( void )+{+ _GLFWcond *cond;++ // Allocate memory for condition variable+ cond = (_GLFWcond *) malloc( sizeof(_GLFWcond) );+ if( !cond )+ {+ return NULL;+ }++ // Initialize condition variable+ cond->waiters_count = 0;+ cond->events[ _GLFW_COND_SIGNAL ] = CreateEvent( NULL, FALSE,+ FALSE, NULL );+ cond->events[ _GLFW_COND_BROADCAST ] = CreateEvent( NULL, TRUE,+ FALSE, NULL );+ InitializeCriticalSection( &cond->waiters_count_lock );++ // Cast to GLFWcond and return+ return (GLFWcond) cond;+}+++//========================================================================+// _glfwPlatformDestroyCond() - Destroy a condition variable object+//========================================================================++void _glfwPlatformDestroyCond( GLFWcond cond )+{+ // Close the condition variable handles+ CloseHandle( ((_GLFWcond *)cond)->events[ _GLFW_COND_SIGNAL ] );+ CloseHandle( ((_GLFWcond *)cond)->events[ _GLFW_COND_BROADCAST ] );++ // Delete critical section+ DeleteCriticalSection( &((_GLFWcond *)cond)->waiters_count_lock );++ // Free memory for condition variable+ free( (void *) cond );+}+++//========================================================================+// _glfwPlatformWaitCond() - Wait for a condition to be raised+//========================================================================++void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,+ double timeout )+{+ _GLFWcond *cv = (_GLFWcond *) cond;+ int result, last_waiter;+ DWORD timeout_ms;++ // Avoid race conditions+ EnterCriticalSection( &cv->waiters_count_lock );+ cv->waiters_count ++;+ LeaveCriticalSection( &cv->waiters_count_lock );++ // It's ok to release the mutex here since Win32 manual-reset events+ // maintain state when used with SetEvent()+ LeaveCriticalSection( (CRITICAL_SECTION *) mutex );++ // Translate timeout into milliseconds+ if( timeout >= GLFW_INFINITY )+ {+ timeout_ms = INFINITE;+ }+ else+ {+ timeout_ms = (DWORD) (1000.0 * timeout + 0.5);+ if( timeout_ms <= 0 )+ {+ timeout_ms = 1;+ }+ }++ // Wait for either event to become signaled due to glfwSignalCond or+ // glfwBroadcastCond being called+ result = WaitForMultipleObjects( 2, cv->events, FALSE, timeout_ms );++ // Check if we are the last waiter+ EnterCriticalSection( &cv->waiters_count_lock );+ cv->waiters_count --;+ last_waiter = (result == WAIT_OBJECT_0 + _GLFW_COND_BROADCAST) &&+ (cv->waiters_count == 0);+ LeaveCriticalSection( &cv->waiters_count_lock );++ // Some thread called glfwBroadcastCond+ if( last_waiter )+ {+ // We're the last waiter to be notified or to stop waiting, so+ // reset the manual event+ ResetEvent( cv->events[ _GLFW_COND_BROADCAST ] );+ }++ // Reacquire the mutex+ EnterCriticalSection( (CRITICAL_SECTION *) mutex );+}+++//========================================================================+// _glfwPlatformSignalCond() - Signal a condition to one waiting thread+//========================================================================++void _glfwPlatformSignalCond( GLFWcond cond )+{+ _GLFWcond *cv = (_GLFWcond *) cond;+ int have_waiters;++ // Avoid race conditions+ EnterCriticalSection( &cv->waiters_count_lock );+ have_waiters = cv->waiters_count > 0;+ LeaveCriticalSection( &cv->waiters_count_lock );++ if( have_waiters )+ {+ SetEvent( cv->events[ _GLFW_COND_SIGNAL ] );+ }+}+++//========================================================================+// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting+// threads+//========================================================================++void _glfwPlatformBroadcastCond( GLFWcond cond )+{+ _GLFWcond *cv = (_GLFWcond *) cond;+ int have_waiters;++ // Avoid race conditions+ EnterCriticalSection( &cv->waiters_count_lock );+ have_waiters = cv->waiters_count > 0;+ LeaveCriticalSection( &cv->waiters_count_lock );++ if( have_waiters )+ {+ SetEvent( cv->events[ _GLFW_COND_BROADCAST ] );+ }+}+++//========================================================================+// _glfwPlatformGetNumberOfProcessors() - Return the number of processors+// in the system.+//========================================================================++int _glfwPlatformGetNumberOfProcessors( void )+{+ SYSTEM_INFO si;++ // Get hardware system information+ GetSystemInfo( &si );++ return (int) si.dwNumberOfProcessors;+}
+ glfw/lib/win32/win32_time.c view
@@ -0,0 +1,146 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_time.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// _glfwInitTimer() - Initialise timer+//========================================================================++void _glfwInitTimer( void )+{+ __int64 freq;++ // Check if we have a performance counter+ if( QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ) )+ {+ // Performance counter is available => use it!+ _glfwLibrary.Timer.HasPerformanceCounter = GL_TRUE;++ // Counter resolution is 1 / counter frequency+ _glfwLibrary.Timer.Resolution = 1.0 / (double)freq;++ // Set start time for timer+ QueryPerformanceCounter( (LARGE_INTEGER *)&_glfwLibrary.Timer.t0_64 );+ }+ else+ {+ // No performace counter available => use the tick counter+ _glfwLibrary.Timer.HasPerformanceCounter = GL_FALSE;++ // Counter resolution is 1 ms+ _glfwLibrary.Timer.Resolution = 0.001;++ // Set start time for timer+ _glfwLibrary.Timer.t0_32 = _glfw_timeGetTime();+ }+}+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Return timer value in seconds+//========================================================================++double _glfwPlatformGetTime( void )+{+ double t;+ __int64 t_64;++ if( _glfwLibrary.Timer.HasPerformanceCounter )+ {+ QueryPerformanceCounter( (LARGE_INTEGER *)&t_64 );+ t = (double)(t_64 - _glfwLibrary.Timer.t0_64);+ }+ else+ {+ t = (double)(_glfw_timeGetTime() - _glfwLibrary.Timer.t0_32);+ }++ // Calculate the current time in seconds+ return t * _glfwLibrary.Timer.Resolution;+}+++//========================================================================+// Set timer value in seconds+//========================================================================++void _glfwPlatformSetTime( double t )+{+ __int64 t_64;++ if( _glfwLibrary.Timer.HasPerformanceCounter )+ {+ QueryPerformanceCounter( (LARGE_INTEGER *)&t_64 );+ _glfwLibrary.Timer.t0_64 = t_64 - (__int64)(t/_glfwLibrary.Timer.Resolution);+ }+ else+ {+ _glfwLibrary.Timer.t0_32 = _glfw_timeGetTime() - (int)(t*1000.0);+ }+}+++//========================================================================+// Put a thread to sleep for a specified amount of time+//========================================================================++void _glfwPlatformSleep( double time )+{+ DWORD t;++ if( time == 0.0 )+ {+ t = 0;+ }+ else if( time < 0.001 )+ {+ t = 1;+ }+ else if( time > 2147483647.0 )+ {+ t = 2147483647;+ }+ else+ {+ t = (DWORD)(time*1000.0 + 0.5);+ }+ Sleep( t );+}+
+ glfw/lib/win32/win32_window.c view
@@ -0,0 +1,1822 @@+//========================================================================+// GLFW - An OpenGL framework+// File: win32_window.c+// Platform: Windows+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++// We use versioned window class names in order not to cause conflicts+// between applications using different versions of GLFW+#define _GLFW_WNDCLASSNAME "GLFW27"+++//========================================================================+// Enable/disable minimize/restore animations+//========================================================================++static int setMinMaxAnimations( int enable )+{+ ANIMATIONINFO AI;+ int old_enable;++ // Get old animation setting+ AI.cbSize = sizeof( ANIMATIONINFO );+ SystemParametersInfo( SPI_GETANIMATION, AI.cbSize, &AI, 0 );+ old_enable = AI.iMinAnimate;++ // If requested, change setting+ if( old_enable != enable )+ {+ AI.iMinAnimate = enable;+ SystemParametersInfo( SPI_SETANIMATION, AI.cbSize, &AI,+ SPIF_SENDCHANGE );+ }++ return old_enable;+}+++//========================================================================+// Focus the window and bring it to the top of the stack+// Due to some nastiness with how Win98/ME/2k/XP handles SetForegroundWindow,+// we have to go through some really bizarre measures to achieve this+//========================================================================++static void setForegroundWindow( HWND hWnd )+{+ int try_count = 0;+ int old_animate;++ // Try the standard approach first...+ BringWindowToTop( hWnd );+ SetForegroundWindow( hWnd );++ // If it worked, return now+ if( hWnd == GetForegroundWindow() )+ {+ // Try to modify the system settings (since this is the foreground+ // process, we are allowed to do this)+ SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0,+ SPIF_SENDCHANGE );+ return;+ }++ // For other Windows versions than 95 & NT4.0, the standard approach+ // may not work, so if we failed we have to "trick" Windows into+ // making our window the foureground window: Iconify and restore+ // again. It is ugly, but it seems to work (we turn off those annoying+ // zoom animations to make it look a bit better at least).++ // Turn off minimize/restore animations+ old_animate = setMinMaxAnimations( 0 );++ // We try this a few times, just to be on the safe side of things...+ do+ {+ // Iconify & restore+ ShowWindow( hWnd, SW_HIDE );+ ShowWindow( hWnd, SW_SHOWMINIMIZED );+ ShowWindow( hWnd, SW_SHOWNORMAL );++ // Try to get focus+ BringWindowToTop( hWnd );+ SetForegroundWindow( hWnd );++ // We do not want to keep going on forever, so we keep track of+ // how many times we tried+ try_count ++;+ }+ while( hWnd != GetForegroundWindow() && try_count <= 3 );++ // Restore the system minimize/restore animation setting+ (void) setMinMaxAnimations( old_animate );++ // Try to modify the system settings (since this is now hopefully the+ // foreground process, we are probably allowed to do this)+ SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0,+ SPIF_SENDCHANGE );+}+++//========================================================================+// 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(int pixelFormat, int attrib)+{+ int value = 0;++ if( !_glfwWin.GetPixelFormatAttribivARB( _glfwWin.DC, pixelFormat, 0, 1, &attrib, &value) )+ {+ // NOTE: We should probably handle this error somehow+ return 0;+ }++ return value;+}+++//========================================================================+// Return a list of available and usable framebuffer configs+//========================================================================++static _GLFWfbconfig *getFBConfigs( unsigned int *found )+{+ _GLFWfbconfig *result;+ PIXELFORMATDESCRIPTOR pfd;+ int i, count;++ *found = 0;++ if( _glfwWin.has_WGL_ARB_pixel_format )+ {+ count = getPixelFormatAttrib( 1, WGL_NUMBER_PIXEL_FORMATS_ARB );+ }+ else+ {+ count = _glfw_DescribePixelFormat( _glfwWin.DC, 1, sizeof( PIXELFORMATDESCRIPTOR ), NULL );+ }++ if( !count )+ {+ fprintf( stderr, "No Win32 pixel formats available\n" );+ return NULL;+ }++ result = (_GLFWfbconfig*) malloc( sizeof( _GLFWfbconfig ) * count );+ if( !result )+ {+ fprintf(stderr, "Out of memory");+ return NULL;+ }++ for( i = 1; i <= count; i++ )+ {+ if( _glfwWin.has_WGL_ARB_pixel_format )+ {+ // Get pixel format attributes through WGL_ARB_pixel_format++ if( !getPixelFormatAttrib( i, WGL_SUPPORT_OPENGL_ARB ) ||+ !getPixelFormatAttrib( i, WGL_DRAW_TO_WINDOW_ARB ) ||+ !getPixelFormatAttrib( i, WGL_DOUBLE_BUFFER_ARB ) )+ {+ // Only consider doublebuffered OpenGL pixel formats for windows+ continue;+ }++ if( getPixelFormatAttrib( i, WGL_PIXEL_TYPE_ARB ) != WGL_TYPE_RGBA_ARB )+ {+ // Only consider RGBA pixel formats+ continue;+ }++ result[*found].redBits = getPixelFormatAttrib( i, WGL_RED_BITS_ARB );+ result[*found].greenBits = getPixelFormatAttrib( i, WGL_GREEN_BITS_ARB );+ result[*found].blueBits = getPixelFormatAttrib( i, WGL_BLUE_BITS_ARB );+ result[*found].alphaBits = getPixelFormatAttrib( i, WGL_ALPHA_BITS_ARB );++ result[*found].depthBits = getPixelFormatAttrib( i, WGL_DEPTH_BITS_ARB );+ result[*found].stencilBits = getPixelFormatAttrib( i, WGL_STENCIL_BITS_ARB );++ result[*found].accumRedBits = getPixelFormatAttrib( i, WGL_ACCUM_RED_BITS_ARB );+ result[*found].accumGreenBits = getPixelFormatAttrib( i, WGL_ACCUM_GREEN_BITS_ARB );+ result[*found].accumBlueBits = getPixelFormatAttrib( i, WGL_ACCUM_BLUE_BITS_ARB );+ result[*found].accumAlphaBits = getPixelFormatAttrib( i, WGL_ACCUM_ALPHA_BITS_ARB );++ result[*found].auxBuffers = getPixelFormatAttrib( i, WGL_AUX_BUFFERS_ARB );+ result[*found].stereo = getPixelFormatAttrib( i, WGL_STEREO_ARB );++ if( _glfwWin.has_WGL_ARB_multisample )+ {+ result[*found].samples = getPixelFormatAttrib( i, WGL_SAMPLES_ARB );+ }+ else+ {+ result[*found].samples = 0;+ }+ }+ else+ {+ // Get pixel format attributes through old-fashioned PFDs++ if( !_glfw_DescribePixelFormat( _glfwWin.DC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfd ) )+ {+ continue;+ }++ if( !( pfd.dwFlags & PFD_DRAW_TO_WINDOW ) ||+ !( pfd.dwFlags & PFD_SUPPORT_OPENGL ) ||+ !( pfd.dwFlags & PFD_DOUBLEBUFFER ) )+ {+ // Only consider doublebuffered OpenGL pixel formats for windows+ continue;+ }++ if( !( pfd.dwFlags & PFD_GENERIC_ACCELERATED ) &&+ ( pfd.dwFlags & PFD_GENERIC_FORMAT ) )+ {+ continue;+ }++ if( pfd.iPixelType != PFD_TYPE_RGBA )+ {+ // Only RGBA pixel formats considered+ continue;+ }++ result[*found].redBits = pfd.cRedBits;+ result[*found].greenBits = pfd.cGreenBits;+ result[*found].blueBits = pfd.cBlueBits;+ result[*found].alphaBits = pfd.cAlphaBits;++ result[*found].depthBits = pfd.cDepthBits;+ result[*found].stencilBits = pfd.cStencilBits;++ result[*found].accumRedBits = pfd.cAccumRedBits;+ result[*found].accumGreenBits = pfd.cAccumGreenBits;+ result[*found].accumBlueBits = pfd.cAccumBlueBits;+ result[*found].accumAlphaBits = pfd.cAccumAlphaBits;++ result[*found].auxBuffers = pfd.cAuxBuffers;+ result[*found].stereo = ( pfd.dwFlags & PFD_STEREO ) ? GL_TRUE : GL_FALSE;++ // PFD pixel formats do not support FSAA+ result[*found].samples = 0;+ }++ result[*found].platformID = i;++ (*found)++;+ }++ return result;+}+++//========================================================================+// Creates an OpenGL context on the specified device context+//========================================================================++static HGLRC createContext( HDC dc, const _GLFWwndconfig* wndconfig, int pixelFormat )+{+ PIXELFORMATDESCRIPTOR pfd;+ int flags, i = 0, attribs[7];++ if( !_glfw_DescribePixelFormat( dc, pixelFormat, sizeof(pfd), &pfd ) )+ {+ return NULL;+ }++ if( !_glfw_SetPixelFormat( dc, pixelFormat, &pfd ) )+ {+ return NULL;+ }++ if( _glfwWin.has_WGL_ARB_create_context )+ {+ // Use the newer wglCreateContextAttribsARB++ if( wndconfig->glMajor != 0 || wndconfig->glMinor != 0 )+ {+ // Request an explicitly versioned context++ attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB;+ attribs[i++] = wndconfig->glMajor;+ attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB;+ attribs[i++] = wndconfig->glMinor;+ }++ if( wndconfig->glForward || wndconfig->glDebug )+ {+ flags = 0;++ if( wndconfig->glForward )+ {+ flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;+ }++ if( wndconfig->glDebug )+ {+ flags |= WGL_CONTEXT_DEBUG_BIT_ARB;+ }++ attribs[i++] = WGL_CONTEXT_FLAGS_ARB;+ attribs[i++] = flags;+ }++ if( wndconfig->glProfile )+ {+ if( wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE )+ {+ flags = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;+ }+ else+ {+ flags = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;+ }++ attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB;+ attribs[i++] = flags;+ }++ attribs[i++] = 0;++ return _glfwWin.CreateContextAttribsARB( dc, NULL, attribs );+ }++ return wglCreateContext( dc );+}+++//========================================================================+// Translates a Windows key to the corresponding GLFW key+//========================================================================++static int translateKey( WPARAM wParam, LPARAM lParam )+{+ MSG next_msg;+ DWORD msg_time;+ DWORD scan_code;++ // Check for numeric keypad keys+ // Note: This way we always force "NumLock = ON", which at least+ // enables GLFW users to detect numeric keypad keys+ int hiFlags = HIWORD( lParam );++ if ( !( hiFlags & 0x100 ) )+ {+ switch( MapVirtualKey( hiFlags & 0xFF, 1 ) )+ {+ case VK_INSERT: return GLFW_KEY_KP_0;+ case VK_END: return GLFW_KEY_KP_1;+ case VK_DOWN: return GLFW_KEY_KP_2;+ case VK_NEXT: return GLFW_KEY_KP_3;+ case VK_LEFT: return GLFW_KEY_KP_4;+ case VK_CLEAR: return GLFW_KEY_KP_5;+ case VK_RIGHT: return GLFW_KEY_KP_6;+ case VK_HOME: return GLFW_KEY_KP_7;+ case VK_UP: return GLFW_KEY_KP_8;+ case VK_PRIOR: return GLFW_KEY_KP_9;+ case VK_DIVIDE: return GLFW_KEY_KP_DIVIDE;+ case VK_MULTIPLY: return GLFW_KEY_KP_MULTIPLY;+ case VK_SUBTRACT: return GLFW_KEY_KP_SUBTRACT;+ case VK_ADD: return GLFW_KEY_KP_ADD;+ case VK_DELETE: return GLFW_KEY_KP_DECIMAL;+ }+ }++ // Check which key was pressed or released+ switch( wParam )+ {+ // The SHIFT keys require special handling+ case VK_SHIFT:+ {+ // Compare scan code for this key with that of VK_RSHIFT in+ // order to determine which shift key was pressed (left or+ // right)+ scan_code = MapVirtualKey( VK_RSHIFT, 0 );+ if( ((lParam & 0x01ff0000) >> 16) == scan_code )+ {+ return GLFW_KEY_RSHIFT;+ }++ return GLFW_KEY_LSHIFT;+ }++ // The CTRL keys require special handling+ case VK_CONTROL:+ {+ // Is this an extended key (i.e. right key)?+ if( lParam & 0x01000000 )+ {+ return GLFW_KEY_RCTRL;+ }++ // 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!+ msg_time = GetMessageTime();+ if( PeekMessage( &next_msg, NULL, 0, 0, PM_NOREMOVE ) )+ {+ if( next_msg.message == WM_KEYDOWN ||+ next_msg.message == WM_SYSKEYDOWN )+ {+ if( next_msg.wParam == VK_MENU &&+ (next_msg.lParam & 0x01000000) &&+ next_msg.time == msg_time )+ {+ // Next message is a RALT down message, which+ // means that this is NOT a proper LCTRL message!+ return GLFW_KEY_UNKNOWN;+ }+ }+ }++ return GLFW_KEY_LCTRL;+ }++ // The ALT keys require special handling+ case VK_MENU:+ {+ // Is this an extended key (i.e. right key)?+ if( lParam & 0x01000000 )+ {+ return GLFW_KEY_RALT;+ }++ return GLFW_KEY_LALT;+ }++ // The ENTER keys require special handling+ case VK_RETURN:+ {+ // Is this an extended key (i.e. right key)?+ if( lParam & 0x01000000 )+ {+ return GLFW_KEY_KP_ENTER;+ }++ return GLFW_KEY_ENTER;+ }++ // Special keys (non character keys)+ case VK_ESCAPE: return GLFW_KEY_ESC;+ case VK_TAB: return GLFW_KEY_TAB;+ case VK_BACK: return GLFW_KEY_BACKSPACE;+ case VK_HOME: return GLFW_KEY_HOME;+ case VK_END: return GLFW_KEY_END;+ case VK_PRIOR: return GLFW_KEY_PAGEUP;+ case VK_NEXT: return GLFW_KEY_PAGEDOWN;+ case VK_INSERT: return GLFW_KEY_INSERT;+ case VK_DELETE: return GLFW_KEY_DEL;+ case VK_LEFT: return GLFW_KEY_LEFT;+ case VK_UP: return GLFW_KEY_UP;+ case VK_RIGHT: return GLFW_KEY_RIGHT;+ case VK_DOWN: return GLFW_KEY_DOWN;+ case VK_F1: return GLFW_KEY_F1;+ case VK_F2: return GLFW_KEY_F2;+ case VK_F3: return GLFW_KEY_F3;+ case VK_F4: return GLFW_KEY_F4;+ case VK_F5: return GLFW_KEY_F5;+ case VK_F6: return GLFW_KEY_F6;+ case VK_F7: return GLFW_KEY_F7;+ case VK_F8: return GLFW_KEY_F8;+ case VK_F9: return GLFW_KEY_F9;+ case VK_F10: return GLFW_KEY_F10;+ case VK_F11: return GLFW_KEY_F11;+ case VK_F12: return GLFW_KEY_F12;+ case VK_F13: return GLFW_KEY_F13;+ case VK_F14: return GLFW_KEY_F14;+ case VK_F15: return GLFW_KEY_F15;+ case VK_F16: return GLFW_KEY_F16;+ case VK_F17: return GLFW_KEY_F17;+ case VK_F18: return GLFW_KEY_F18;+ case VK_F19: return GLFW_KEY_F19;+ case VK_F20: return GLFW_KEY_F20;+ case VK_F21: return GLFW_KEY_F21;+ case VK_F22: return GLFW_KEY_F22;+ case VK_F23: return GLFW_KEY_F23;+ case VK_F24: return GLFW_KEY_F24;+ case VK_SPACE: return GLFW_KEY_SPACE;++ // Numeric keypad+ case VK_NUMPAD0: return GLFW_KEY_KP_0;+ case VK_NUMPAD1: return GLFW_KEY_KP_1;+ case VK_NUMPAD2: return GLFW_KEY_KP_2;+ case VK_NUMPAD3: return GLFW_KEY_KP_3;+ case VK_NUMPAD4: return GLFW_KEY_KP_4;+ case VK_NUMPAD5: return GLFW_KEY_KP_5;+ case VK_NUMPAD6: return GLFW_KEY_KP_6;+ case VK_NUMPAD7: return GLFW_KEY_KP_7;+ case VK_NUMPAD8: return GLFW_KEY_KP_8;+ case VK_NUMPAD9: return GLFW_KEY_KP_9;+ case VK_DIVIDE: return GLFW_KEY_KP_DIVIDE;+ case VK_MULTIPLY: return GLFW_KEY_KP_MULTIPLY;+ case VK_SUBTRACT: return GLFW_KEY_KP_SUBTRACT;+ case VK_ADD: return GLFW_KEY_KP_ADD;+ case VK_DECIMAL: return GLFW_KEY_KP_DECIMAL;+ case VK_NUMLOCK: return GLFW_KEY_KP_NUM_LOCK;++ case VK_CAPITAL: return GLFW_KEY_CAPS_LOCK;+ case VK_SCROLL: return GLFW_KEY_SCROLL_LOCK;+ case VK_PAUSE: return GLFW_KEY_PAUSE;++ case VK_LWIN: return GLFW_KEY_LSUPER;+ case VK_RWIN: return GLFW_KEY_RSUPER;+ case VK_APPS: return GLFW_KEY_MENU;++ // The rest (should be printable keys)+ default:+ {+ // Convert to printable character (ISO-8859-1 or Unicode)+ wParam = MapVirtualKey( (UINT) wParam, 2 ) & 0x0000FFFF;++ // Make sure that the character is uppercase+ if( _glfwLibrary.Sys.hasUnicode )+ {+ wParam = (WPARAM) CharUpperW( (LPWSTR) wParam );+ }+ else+ {+ wParam = (WPARAM) CharUpperA( (LPSTR) wParam );+ }++ // Valid ISO-8859-1 character?+ if( (wParam >= 32 && wParam <= 126) ||+ (wParam >= 160 && wParam <= 255) )+ {+ return (int) wParam;+ }++ return GLFW_KEY_UNKNOWN;+ }+ }+}+++//========================================================================+// Translates a Windows key to Unicode+//========================================================================++static void translateChar( DWORD wParam, DWORD lParam, int action )+{+ BYTE keyboard_state[ 256 ];+ UCHAR char_buf[ 10 ];+ WCHAR unicode_buf[ 10 ];+ UINT scan_code;+ int i, num_chars, unicode;++ GetKeyboardState( keyboard_state );++ // Derive scan code from lParam and action+ scan_code = (lParam & 0x01ff0000) >> 16;+ if( action == GLFW_RELEASE )+ {+ scan_code |= 0x8000000;+ }++ if( _glfwLibrary.Sys.hasUnicode )+ {+ num_chars = ToUnicode(+ wParam, // virtual-key code+ scan_code, // scan code+ keyboard_state, // key-state array+ unicode_buf, // buffer for translated key+ 10, // size of translated key buffer+ 0 // active-menu flag+ );+ unicode = 1;+ }+ else+ {+ // Convert to ISO-8859-1+ num_chars = ToAscii(+ wParam, // virtual-key code+ scan_code, // scan code+ keyboard_state, // key-state array+ (LPWORD) char_buf, // buffer for translated key+ 0 // active-menu flag+ );+ unicode = 0;+ }++ // Report characters+ for( i = 0; i < num_chars; i++ )+ {+ // Get next character from buffer+ if( unicode )+ {+ _glfwInputChar( (int) unicode_buf[ i ], action );+ }+ else+ {+ _glfwInputChar( (int) char_buf[ i ], action );+ }+ }+}+++//========================================================================+// Window callback function (handles window events)+//========================================================================++static LRESULT CALLBACK windowProc( HWND hWnd, UINT uMsg,+ WPARAM wParam, LPARAM lParam )+{+ int wheelDelta, iconified;++ switch( uMsg )+ {+ // Window activate message? (iconification?)+ case WM_ACTIVATE:+ {+ _glfwWin.active = LOWORD(wParam) != WA_INACTIVE ? GL_TRUE : GL_FALSE;++ iconified = HIWORD(wParam) ? GL_TRUE : GL_FALSE;++ // Were we deactivated/iconified?+ if( (!_glfwWin.active || iconified) && !_glfwWin.iconified )+ {+ _glfwInputDeactivation();++ // If we are in fullscreen mode we need to iconify+ if( _glfwWin.opened && _glfwWin.fullscreen )+ {+ // Do we need to manually iconify?+ if( !iconified )+ {+ // Minimize window+ CloseWindow( _glfwWin.window );+ iconified = GL_TRUE;+ }++ // Restore the original desktop resolution+ ChangeDisplaySettings( NULL, CDS_FULLSCREEN );+ }++ // Unlock mouse if locked+ if( !_glfwWin.oldMouseLockValid )+ {+ _glfwWin.oldMouseLock = _glfwWin.mouseLock;+ _glfwWin.oldMouseLockValid = GL_TRUE;+ glfwEnable( GLFW_MOUSE_CURSOR );+ }+ }+ else if( _glfwWin.active || !iconified )+ {+ // If we are in fullscreen mode we need to maximize+ if( _glfwWin.opened && _glfwWin.fullscreen && _glfwWin.iconified )+ {+ // Change display settings to the user selected mode+ _glfwSetVideoModeMODE( _glfwWin.modeID );++ // Do we need to manually restore window?+ if( iconified )+ {+ // Restore window+ OpenIcon( _glfwWin.window );+ iconified = GL_FALSE;++ // Activate window+ ShowWindow( hWnd, SW_SHOW );+ setForegroundWindow( _glfwWin.window );+ SetFocus( _glfwWin.window );+ }+ }++ // Lock mouse, if necessary+ if( _glfwWin.oldMouseLockValid && _glfwWin.oldMouseLock )+ {+ glfwDisable( GLFW_MOUSE_CURSOR );+ }+ _glfwWin.oldMouseLockValid = GL_FALSE;+ }++ _glfwWin.iconified = iconified;+ return 0;+ }++ case WM_SYSCOMMAND:+ {+ switch( wParam & 0xfff0 )+ {+ case SC_SCREENSAVE:+ case SC_MONITORPOWER:+ {+ if( _glfwWin.fullscreen )+ {+ // Disallow screen saver and screen blanking if we are+ // running in fullscreen mode+ return 0;+ }+ else+ {+ break;+ }+ }++ // User trying to access application menu using ALT?+ case SC_KEYMENU:+ return 0;+ }+ break;+ }++ case WM_CLOSE:+ {+ // Translate this to WM_QUIT so that we can handle all cases in the+ // same place+ PostQuitMessage( 0 );+ return 0;+ }++ case WM_KEYDOWN:+ case WM_SYSKEYDOWN:+ {+ _glfwInputKey( translateKey( wParam, lParam ), GLFW_PRESS );++ if( _glfwWin.charCallback )+ {+ translateChar( (DWORD) wParam, (DWORD) lParam, GLFW_PRESS );+ }+ return 0;+ }++ case WM_KEYUP:+ case WM_SYSKEYUP:+ {+ // Special trick: release both shift keys on SHIFT up event+ if( wParam == VK_SHIFT )+ {+ _glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE );+ _glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE );+ }+ else+ {+ _glfwInputKey( translateKey( wParam, lParam ), GLFW_RELEASE );+ }++ if( _glfwWin.charCallback )+ {+ translateChar( (DWORD) wParam, (DWORD) lParam, GLFW_RELEASE );+ }++ return 0;+ }++ case WM_LBUTTONDOWN:+ SetCapture(hWnd);+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );+ return 0;+ case WM_RBUTTONDOWN:+ SetCapture(hWnd);+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );+ return 0;+ case WM_MBUTTONDOWN:+ SetCapture(hWnd);+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS );+ return 0;+ case WM_XBUTTONDOWN:+ {+ if( HIWORD(wParam) == XBUTTON1 )+ {+ SetCapture(hWnd);+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_PRESS );+ }+ else if( HIWORD(wParam) == XBUTTON2 )+ {+ SetCapture(hWnd);+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_PRESS );+ }+ return 1;+ }++ case WM_LBUTTONUP:+ ReleaseCapture();+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE );+ return 0;+ case WM_RBUTTONUP:+ ReleaseCapture();+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE );+ return 0;+ case WM_MBUTTONUP:+ ReleaseCapture();+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE );+ return 0;+ case WM_XBUTTONUP:+ {+ if( HIWORD(wParam) == XBUTTON1 )+ {+ ReleaseCapture();+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_RELEASE );+ }+ else if( HIWORD(wParam) == XBUTTON2 )+ {+ ReleaseCapture();+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_RELEASE );+ }+ return 1;+ }++ case WM_MOUSEMOVE:+ {+ int NewMouseX, NewMouseY;++ // Get signed (!) mouse position+ NewMouseX = (int)((short)LOWORD(lParam));+ NewMouseY = (int)((short)HIWORD(lParam));++ if( NewMouseX != _glfwInput.OldMouseX ||+ NewMouseY != _glfwInput.OldMouseY )+ {+ if( _glfwWin.mouseLock )+ {+ _glfwInput.MousePosX += NewMouseX -+ _glfwInput.OldMouseX;+ _glfwInput.MousePosY += NewMouseY -+ _glfwInput.OldMouseY;+ }+ else+ {+ _glfwInput.MousePosX = NewMouseX;+ _glfwInput.MousePosY = NewMouseY;+ }+ _glfwInput.OldMouseX = NewMouseX;+ _glfwInput.OldMouseY = NewMouseY;+ _glfwInput.MouseMoved = GL_TRUE;++ if( _glfwWin.mousePosCallback )+ {+ _glfwWin.mousePosCallback( _glfwInput.MousePosX,+ _glfwInput.MousePosY );+ }+ }+ return 0;+ }++ case WM_MOUSEWHEEL:+ {+ // WM_MOUSEWHEEL is not supported under Windows 95+ if( _glfwLibrary.Sys.winVer != _GLFW_WIN_95 )+ {+ wheelDelta = (((int)wParam) >> 16) / WHEEL_DELTA;+ _glfwInput.WheelPos += wheelDelta;+ if( _glfwWin.mouseWheelCallback )+ {+ _glfwWin.mouseWheelCallback( _glfwInput.WheelPos );+ }+ return 0;+ }+ break;+ }++ case WM_SIZE:+ {+ _glfwWin.width = LOWORD(lParam);+ _glfwWin.height = HIWORD(lParam);++ // If the mouse is locked, update the clipping rect+ if( _glfwWin.mouseLock )+ {+ RECT ClipWindowRect;+ if( GetWindowRect( _glfwWin.window, &ClipWindowRect ) )+ {+ ClipCursor( &ClipWindowRect );+ }+ }++ if( _glfwWin.windowSizeCallback )+ {+ _glfwWin.windowSizeCallback( LOWORD(lParam), HIWORD(lParam) );+ }+ return 0;+ }++ case WM_MOVE:+ {+ // If the mouse is locked, update the clipping rect+ if( _glfwWin.mouseLock )+ {+ RECT ClipWindowRect;+ if( GetWindowRect( _glfwWin.window, &ClipWindowRect ) )+ {+ ClipCursor( &ClipWindowRect );+ }+ }+ return 0;+ }++ // Was the window contents damaged?+ case WM_PAINT:+ {+ if( _glfwWin.windowRefreshCallback )+ {+ _glfwWin.windowRefreshCallback();+ }+ break;+ }++ case WM_DISPLAYCHANGE:+ {+ // TODO: Do stuff here.++ break;+ }+ }++ // Pass all unhandled messages to DefWindowProc+ return DefWindowProc( hWnd, uMsg, wParam, lParam );+}+++//========================================================================+// Translate client window size to full window size (including window borders)+//========================================================================++static void getFullWindowSize( int clientWidth, int clientHeight,+ int *fullWidth, int *fullHeight )+{+ RECT rect;++ // Create a window rectangle+ rect.left = (long)0;+ rect.right = (long)clientWidth - 1;+ rect.top = (long)0;+ rect.bottom = (long)clientHeight - 1;++ // Adjust according to window styles+ AdjustWindowRectEx( &rect, _glfwWin.dwStyle, FALSE, _glfwWin.dwExStyle );++ // Calculate width and height of full window+ *fullWidth = rect.right - rect.left + 1;+ *fullHeight = rect.bottom - rect.top + 1;+}+++//========================================================================+// Initialize WGL-specific extensions+// This function is called once before initial context creation, i.e. before+// any WGL extensions could be present. This is done in order to have both+// extension variable clearing and loading in the same place, hopefully+// decreasing the possibility of forgetting to add one without the other.+//========================================================================++static void initWGLExtensions( void )+{+ // This needs to include every function pointer loaded below+ _glfwWin.SwapIntervalEXT = NULL;+ _glfwWin.GetPixelFormatAttribivARB = NULL;+ _glfwWin.GetExtensionsStringARB = NULL;+ _glfwWin.GetExtensionsStringEXT = NULL;+ _glfwWin.CreateContextAttribsARB = NULL;++ // This needs to include every extension used below except for+ // WGL_ARB_extensions_string and WGL_EXT_extensions_string+ _glfwWin.has_WGL_EXT_swap_control = GL_FALSE;+ _glfwWin.has_WGL_ARB_pixel_format = GL_FALSE;+ _glfwWin.has_WGL_ARB_multisample = GL_FALSE;+ _glfwWin.has_WGL_ARB_create_context = GL_FALSE;++ _glfwWin.GetExtensionsStringEXT = (WGLGETEXTENSIONSSTRINGEXT_T)+ wglGetProcAddress( "wglGetExtensionsStringEXT" );+ if( !_glfwWin.GetExtensionsStringEXT )+ {+ _glfwWin.GetExtensionsStringARB = (WGLGETEXTENSIONSSTRINGARB_T)+ wglGetProcAddress( "wglGetExtensionsStringARB" );+ if( !_glfwWin.GetExtensionsStringARB )+ {+ return;+ }+ }++ if( _glfwPlatformExtensionSupported( "WGL_ARB_multisample" ) )+ {+ _glfwWin.has_WGL_ARB_multisample = GL_TRUE;+ }++ if( _glfwPlatformExtensionSupported( "WGL_ARB_create_context" ) )+ {+ _glfwWin.has_WGL_ARB_create_context = GL_TRUE;+ _glfwWin.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)+ wglGetProcAddress( "wglCreateContextAttribsARB" );+ }++ if( _glfwPlatformExtensionSupported( "WGL_EXT_swap_control" ) )+ {+ _glfwWin.has_WGL_EXT_swap_control = GL_TRUE;+ _glfwWin.SwapIntervalEXT = (WGLSWAPINTERVALEXT_T)+ wglGetProcAddress( "wglSwapIntervalEXT" );+ }++ if( _glfwPlatformExtensionSupported( "WGL_ARB_pixel_format" ) )+ {+ _glfwWin.has_WGL_ARB_pixel_format = GL_TRUE;+ _glfwWin.GetPixelFormatAttribivARB = (WGLGETPIXELFORMATATTRIBIVARB_T)+ wglGetProcAddress( "wglGetPixelFormatAttribivARB" );+ }+}+++//========================================================================+// Registers the GLFW window class+//========================================================================++static ATOM registerWindowClass( void )+{+ WNDCLASS wc;++ // Set window class parameters+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on...+ wc.lpfnWndProc = (WNDPROC)windowProc; // Message handler+ wc.cbClsExtra = 0; // No extra class data+ wc.cbWndExtra = 0; // No extra window data+ wc.hInstance = _glfwLibrary.instance; // Set instance+ wc.hCursor = LoadCursor( NULL, IDC_ARROW ); // Load arrow pointer+ wc.hbrBackground = NULL; // No background+ wc.lpszMenuName = NULL; // No menu+ wc.lpszClassName = _GLFW_WNDCLASSNAME; // Set class name++ // Load user-provided icon if available+ wc.hIcon = LoadIcon( _glfwLibrary.instance, "GLFW_ICON" );+ if( !wc.hIcon )+ {+ // Load default icon+ wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );+ }++ return RegisterClass( &wc );+}+++//========================================================================+// Returns the closest matching pixel format, or zero on error+//========================================================================++static int choosePixelFormat( const _GLFWfbconfig *fbconfig )+{+ unsigned int fbcount;+ int pixelFormat;+ _GLFWfbconfig *fbconfigs;+ const _GLFWfbconfig *closest;++ fbconfigs = getFBConfigs( &fbcount );+ if( !fbconfigs )+ {+ fprintf( stderr, "Failed to find any usable GLFWFBConfigs\n" );+ return 0;+ }++ closest = _glfwChooseFBConfig( fbconfig, fbconfigs, fbcount );+ if( !closest )+ {+ fprintf( stderr, "Failed to select a GLFWFBConfig from the alternatives\n" );+ free( fbconfigs );+ return 0;+ }++ pixelFormat = (int) closest->platformID;++ free( fbconfigs );+ fbconfigs = NULL;+ closest = NULL;++ return pixelFormat;+}+++//========================================================================+// Creates the GLFW window and rendering context+//========================================================================++static int createWindow( const _GLFWwndconfig *wndconfig,+ const _GLFWfbconfig *fbconfig )+{+ DWORD dwStyle, dwExStyle;+ int pixelFormat, fullWidth, fullHeight;+ RECT wa;+ POINT pos;++ _glfwWin.DC = NULL;+ _glfwWin.context = NULL;+ _glfwWin.window = NULL;++ // Set common window styles+ dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;+ dwExStyle = WS_EX_APPWINDOW;++ // Set window style, depending on fullscreen mode+ if( _glfwWin.fullscreen )+ {+ dwStyle |= WS_POPUP;++ // Here's a trick for helping us getting window focus+ // (SetForegroundWindow doesn't work properly under+ // Win98/ME/2K/.NET/+)+ /*+ if( _glfwLibrary.Sys.WinVer != _GLFW_WIN_95 &&+ _glfwLibrary.Sys.WinVer != _GLFW_WIN_NT4 &&+ _glfwLibrary.Sys.WinVer != _GLFW_WIN_XP )+ {+ dwStyle |= WS_MINIMIZE;+ }+ */+ }+ else+ {+ dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;++ if( !wndconfig->windowNoResize )+ {+ dwStyle |= ( WS_MAXIMIZEBOX | WS_SIZEBOX );+ dwExStyle |= WS_EX_WINDOWEDGE;+ }+ }++ // Remember window styles (used by getFullWindowSize)+ _glfwWin.dwStyle = dwStyle;+ _glfwWin.dwExStyle = dwExStyle;++ // Adjust window size for frame and title bar+ getFullWindowSize( _glfwWin.width, _glfwWin.height, &fullWidth, &fullHeight );++ // Adjust window position to working area (e.g. if the task bar is at+ // the top of the display). Fullscreen windows are always opened in+ // the upper left corner regardless of the desktop working area.+ if( _glfwWin.fullscreen )+ {+ wa.left = wa.top = 0;+ }+ else+ {+ SystemParametersInfo( SPI_GETWORKAREA, 0, &wa, 0 );+ }++ _glfwWin.window = CreateWindowEx( _glfwWin.dwExStyle, // Extended style+ _GLFW_WNDCLASSNAME, // Class name+ "GLFW Window", // Window title+ _glfwWin.dwStyle, // Defined window style+ wa.left, wa.top, // Window position+ fullWidth, // Decorated window width+ fullHeight, // Decorated window height+ NULL, // No parent window+ NULL, // No menu+ _glfwLibrary.instance, // Instance+ NULL ); // Nothing to WM_CREATE++ if( !_glfwWin.window )+ {+ fprintf( stderr, "Unable to create Win32 window\n" );+ return GL_FALSE;+ }++ _glfwWin.DC = GetDC( _glfwWin.window );+ if( !_glfwWin.DC )+ {+ fprintf( stderr, "Unable to retrieve GLFW window DC\n" );+ return GL_FALSE;+ }++ pixelFormat = choosePixelFormat( fbconfig );+ if( !pixelFormat )+ {+ fprintf( stderr, "Unable to find a usable pixel format\n" );+ return GL_FALSE;+ }++ _glfwWin.context = createContext( _glfwWin.DC, wndconfig, pixelFormat );+ if( !_glfwWin.context )+ {+ fprintf( stderr, "Unable to create OpenGL context\n" );+ return GL_FALSE;+ }++ if( !wglMakeCurrent( _glfwWin.DC, _glfwWin.context ) )+ {+ fprintf( stderr, "Unable to make OpenGL context current\n" );+ return GL_FALSE;+ }++ initWGLExtensions();++ // Initialize mouse position data+ GetCursorPos( &pos );+ ScreenToClient( _glfwWin.window, &pos );+ _glfwInput.OldMouseX = _glfwInput.MousePosX = pos.x;+ _glfwInput.OldMouseY = _glfwInput.MousePosY = pos.y;++ return GL_TRUE;+}+++//========================================================================+// Destroys the GLFW window and rendering context+//========================================================================++static void destroyWindow( void )+{+ if( _glfwWin.context )+ {+ wglMakeCurrent( NULL, NULL );+ wglDeleteContext( _glfwWin.context );+ _glfwWin.context = NULL;+ }++ if( _glfwWin.DC )+ {+ ReleaseDC( _glfwWin.window, _glfwWin.DC );+ _glfwWin.DC = NULL;+ }++ if( _glfwWin.window )+ {+ if( _glfwLibrary.Sys.winVer <= _GLFW_WIN_NT4 )+ {+ // Note: Hiding the window first fixes an annoying W98/NT4+ // remaining icon bug for fullscreen displays+ ShowWindow( _glfwWin.window, SW_HIDE );+ }++ DestroyWindow( _glfwWin.window );+ _glfwWin.window = NULL;+ }+}++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Here is where the window is created, and the OpenGL rendering context is+// created+//========================================================================++int _glfwPlatformOpenWindow( int width, int height,+ const _GLFWwndconfig *wndconfig,+ const _GLFWfbconfig *fbconfig )+{+ GLboolean recreateContext = GL_FALSE;++ // Clear platform specific GLFW window state+ _glfwWin.classAtom = 0;+ _glfwWin.oldMouseLockValid = GL_FALSE;++ _glfwWin.desiredRefreshRate = wndconfig->refreshRate;++ _glfwWin.classAtom = registerWindowClass();+ if( !_glfwWin.classAtom )+ {+ fprintf( stderr, "Failed to register GLFW window class\n" );+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ if( _glfwWin.fullscreen )+ {+ _glfwSetVideoMode( &_glfwWin.width, &_glfwWin.height,+ fbconfig->redBits, fbconfig->greenBits, fbconfig->blueBits,+ wndconfig->refreshRate );+ }++ initWGLExtensions();++ if( !createWindow( wndconfig, fbconfig ) )+ {+ fprintf( stderr, "Failed to create GLFW window\n" );+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ if( wndconfig->glMajor > 2 )+ {+ if( !_glfwWin.has_WGL_ARB_create_context )+ {+ fprintf( stderr, "OpenGL 3.0+ is not supported\n" );+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ recreateContext = 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( _glfwWin.has_WGL_ARB_multisample && _glfwWin.has_WGL_ARB_pixel_format )+ {+ // We appear to have both the FSAA extension and the means to ask for it+ recreateContext = GL_TRUE;+ }+ }++ if( recreateContext )+ {+ // 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 potential compatibility problems++ destroyWindow();++ if( !createWindow( wndconfig, fbconfig ) )+ {+ fprintf( stderr, "Unable to re-create GLFW window\n" );+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }+ }++ if( _glfwWin.fullscreen )+ {+ // Place the window above all topmost windows+ SetWindowPos( _glfwWin.window, HWND_TOPMOST, 0,0,0,0,+ SWP_NOMOVE | SWP_NOSIZE );+ }++ setForegroundWindow( _glfwWin.window );+ SetFocus( _glfwWin.window );++ // Start by clearing the front buffer to black (avoid ugly desktop+ // remains in our OpenGL window)+ glClear( GL_COLOR_BUFFER_BIT );+ _glfw_SwapBuffers( _glfwWin.DC );++ return GL_TRUE;+}+++//========================================================================+// Properly kill the window / video display+//========================================================================++void _glfwPlatformCloseWindow( void )+{+ destroyWindow();++ if( _glfwWin.classAtom )+ {+ UnregisterClass( _GLFW_WNDCLASSNAME, _glfwLibrary.instance );+ _glfwWin.classAtom = 0;+ }++ if( _glfwWin.fullscreen )+ {+ // Restore original desktop resolution+ ChangeDisplaySettings( NULL, CDS_FULLSCREEN );+ }+}+++//========================================================================+// Set the window title+//========================================================================++void _glfwPlatformSetWindowTitle( const char *title )+{+ (void) SetWindowText( _glfwWin.window, title );+}+++//========================================================================+// Set the window size.+//========================================================================++void _glfwPlatformSetWindowSize( int width, int height )+{+ int bpp, mode = 0, refresh;+ int sizechanged = GL_FALSE;+ GLint drawbuffer;+ GLfloat clearcolor[4];++ if( _glfwWin.fullscreen )+ {+ // Get some info about the current mode++ DEVMODE dm;++ // Get current BPP settings+ dm.dmSize = sizeof( DEVMODE );+ if( EnumDisplaySettings( NULL, _glfwWin.modeID, &dm ) )+ {+ // Get bpp+ bpp = dm.dmBitsPerPel;++ // Get closest match for target video mode+ refresh = _glfwWin.desiredRefreshRate;+ mode = _glfwGetClosestVideoModeBPP( &width, &height, &bpp,+ &refresh );+ }+ else+ {+ mode = _glfwWin.modeID;+ }+ }+ else+ {+ // If we are in windowed mode, adjust the window size to+ // compensate for window decorations+ getFullWindowSize( width, height, &width, &height );+ }++ // Change window size before changing fullscreen mode?+ if( _glfwWin.fullscreen && (width > _glfwWin.width) )+ {+ SetWindowPos( _glfwWin.window, HWND_TOP, 0, 0, width, height,+ SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER );+ sizechanged = GL_TRUE;+ }++ // Change fullscreen video mode?+ if( _glfwWin.fullscreen && mode != _glfwWin.modeID )+ {+ _glfwSetVideoModeMODE( mode );++ // Clear the front buffer to black (avoid ugly desktop remains in+ // our OpenGL window)+ glGetIntegerv( GL_DRAW_BUFFER, &drawbuffer );+ glGetFloatv( GL_COLOR_CLEAR_VALUE, clearcolor );+ glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );+ glClear( GL_COLOR_BUFFER_BIT );+ if( drawbuffer == GL_BACK )+ {+ _glfw_SwapBuffers( _glfwWin.DC );+ }+ glClearColor( clearcolor[0], clearcolor[1], clearcolor[2],+ clearcolor[3] );+ }++ // Set window size (if not already changed)+ if( !sizechanged )+ {+ SetWindowPos( _glfwWin.window, HWND_TOP, 0, 0, width, height,+ SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER );+ }+}+++//========================================================================+// Set the window position+//========================================================================++void _glfwPlatformSetWindowPos( int x, int y )+{+ (void) SetWindowPos( _glfwWin.window, HWND_TOP, x, y, 0, 0,+ SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER );+}+++//========================================================================+// Window iconification+//========================================================================++void _glfwPlatformIconifyWindow( void )+{+ // Iconify window+ CloseWindow( _glfwWin.window );+ _glfwWin.iconified = GL_TRUE;++ // If we are in fullscreen mode we need to change video modes+ if( _glfwWin.fullscreen )+ {+ // Change display settings to the desktop resolution+ ChangeDisplaySettings( NULL, CDS_FULLSCREEN );+ }++ // Unlock mouse+ if( !_glfwWin.oldMouseLockValid )+ {+ _glfwWin.oldMouseLock = _glfwWin.mouseLock;+ _glfwWin.oldMouseLockValid = GL_TRUE;+ glfwEnable( GLFW_MOUSE_CURSOR );+ }+}+++//========================================================================+// Window un-iconification+//========================================================================++void _glfwPlatformRestoreWindow( void )+{+ // If we are in fullscreen mode we need to change video modes+ if( _glfwWin.fullscreen )+ {+ // Change display settings to the user selected mode+ _glfwSetVideoModeMODE( _glfwWin.modeID );+ }++ // Un-iconify window+ OpenIcon( _glfwWin.window );++ // Make sure that our window ends up on top of things+ ShowWindow( _glfwWin.window, SW_SHOW );+ setForegroundWindow( _glfwWin.window );+ SetFocus( _glfwWin.window );++ // Window is no longer iconified+ _glfwWin.iconified = GL_FALSE;++ // Lock mouse, if necessary+ if( _glfwWin.oldMouseLockValid && _glfwWin.oldMouseLock )+ {+ glfwDisable( GLFW_MOUSE_CURSOR );+ }+ _glfwWin.oldMouseLockValid = GL_FALSE;+}+++//========================================================================+// Swap buffers (double-buffering)+//========================================================================++void _glfwPlatformSwapBuffers( void )+{+ _glfw_SwapBuffers( _glfwWin.DC );+}+++//========================================================================+// Set double buffering swap interval+//========================================================================++void _glfwPlatformSwapInterval( int interval )+{+ if( _glfwWin.has_WGL_EXT_swap_control )+ {+ _glfwWin.SwapIntervalEXT( interval );+ }+}+++//========================================================================+// Write back window parameters into GLFW window structure+//========================================================================++void _glfwPlatformRefreshWindowParams( void )+{+ PIXELFORMATDESCRIPTOR pfd;+ DEVMODE dm;+ int pixelFormat, mode;++ // Obtain a detailed description of current pixel format+ pixelFormat = _glfw_GetPixelFormat( _glfwWin.DC );++ if( _glfwWin.has_WGL_ARB_pixel_format )+ {+ if( getPixelFormatAttrib( pixelFormat, WGL_ACCELERATION_ARB ) !=+ WGL_NO_ACCELERATION_ARB )+ {+ _glfwWin.accelerated = GL_TRUE;+ }+ else+ {+ _glfwWin.accelerated = GL_FALSE;+ }++ _glfwWin.redBits = getPixelFormatAttrib( pixelFormat, WGL_RED_BITS_ARB );+ _glfwWin.greenBits = getPixelFormatAttrib( pixelFormat, WGL_GREEN_BITS_ARB );+ _glfwWin.blueBits = getPixelFormatAttrib( pixelFormat, WGL_BLUE_BITS_ARB );++ _glfwWin.alphaBits = getPixelFormatAttrib( pixelFormat, WGL_ALPHA_BITS_ARB );+ _glfwWin.depthBits = getPixelFormatAttrib( pixelFormat, WGL_DEPTH_BITS_ARB );+ _glfwWin.stencilBits = getPixelFormatAttrib( pixelFormat, WGL_STENCIL_BITS_ARB );++ _glfwWin.accumRedBits = getPixelFormatAttrib( pixelFormat, WGL_ACCUM_RED_BITS_ARB );+ _glfwWin.accumGreenBits = getPixelFormatAttrib( pixelFormat, WGL_ACCUM_GREEN_BITS_ARB );+ _glfwWin.accumBlueBits = getPixelFormatAttrib( pixelFormat, WGL_ACCUM_BLUE_BITS_ARB );+ _glfwWin.accumAlphaBits = getPixelFormatAttrib( pixelFormat, WGL_ACCUM_ALPHA_BITS_ARB );++ _glfwWin.auxBuffers = getPixelFormatAttrib( pixelFormat, WGL_AUX_BUFFERS_ARB );+ _glfwWin.stereo = getPixelFormatAttrib( pixelFormat, WGL_STEREO_ARB ) ? GL_TRUE : GL_FALSE;++ if( _glfwWin.has_WGL_ARB_multisample )+ {+ _glfwWin.samples = getPixelFormatAttrib( pixelFormat, WGL_SAMPLES_ARB );+ // Should we force 1 to 0 here for consistency, or keep 1 for transparency?+ }+ else+ {+ _glfwWin.samples = 0;+ }+ }+ else+ {+ _glfw_DescribePixelFormat( _glfwWin.DC, pixelFormat,+ sizeof(PIXELFORMATDESCRIPTOR), &pfd );++ // Is current OpenGL context accelerated?+ _glfwWin.accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||+ !(pfd.dwFlags & PFD_GENERIC_FORMAT) ? 1 : 0;++ // "Standard" window parameters+ _glfwWin.redBits = pfd.cRedBits;+ _glfwWin.greenBits = pfd.cGreenBits;+ _glfwWin.blueBits = pfd.cBlueBits;+ _glfwWin.alphaBits = pfd.cAlphaBits;+ _glfwWin.depthBits = pfd.cDepthBits;+ _glfwWin.stencilBits = pfd.cStencilBits;+ _glfwWin.accumRedBits = pfd.cAccumRedBits;+ _glfwWin.accumGreenBits = pfd.cAccumGreenBits;+ _glfwWin.accumBlueBits = pfd.cAccumBlueBits;+ _glfwWin.accumAlphaBits = pfd.cAccumAlphaBits;+ _glfwWin.auxBuffers = pfd.cAuxBuffers;+ _glfwWin.stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE;++ // If we don't have WGL_ARB_pixel_format then we can't have created a+ // multisampling context, so it's safe to hardcode zero here+ _glfwWin.samples = 0;+ }++ // Get refresh rate+ mode = _glfwWin.fullscreen ? _glfwWin.modeID : ENUM_CURRENT_SETTINGS;+ dm.dmSize = sizeof( DEVMODE );++ if( EnumDisplaySettings( NULL, mode, &dm ) )+ {+ _glfwWin.refreshRate = dm.dmDisplayFrequency;+ if( _glfwWin.refreshRate <= 1 )+ {+ _glfwWin.refreshRate = 0;+ }+ }+ else+ {+ _glfwWin.refreshRate = 0;+ }+}+++//========================================================================+// Poll for new window and input events+//========================================================================++void _glfwPlatformPollEvents( void )+{+ MSG msg;+ int winclosed = GL_FALSE;++ // Flag: mouse was not moved (will be changed by _glfwGetNextEvent if+ // there was a mouse move event)+ _glfwInput.MouseMoved = GL_FALSE;+ if( _glfwWin.mouseLock )+ {+ _glfwInput.OldMouseX = _glfwWin.width/2;+ _glfwInput.OldMouseY = _glfwWin.height/2;+ }+ else+ {+ _glfwInput.OldMouseX = _glfwInput.MousePosX;+ _glfwInput.OldMouseY = _glfwInput.MousePosY;+ }++ // Check for new window messages+ while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )+ {+ switch( msg.message )+ {+ // QUIT-message (from close window)?+ case WM_QUIT:+ winclosed = GL_TRUE;+ break;++ // Ok, send it to the window message handler+ default:+ DispatchMessage( &msg );+ break;+ }+ }++ // 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.+ // Caveat: Does not work under Win 9x/ME.+ if( _glfwLibrary.Sys.winVer >= _GLFW_WIN_NT4 )+ {+ int lshift_down, rshift_down;++ // Get current state of left and right shift keys+ lshift_down = (GetAsyncKeyState( VK_LSHIFT ) >> 15) & 1;+ rshift_down = (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( !lshift_down && _glfwInput.Key[ GLFW_KEY_LSHIFT ] == 1 )+ {+ _glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE );+ }+ if( !rshift_down && _glfwInput.Key[ GLFW_KEY_RSHIFT ] == 1 )+ {+ _glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE );+ }+ }++ // Did we have mouse movement in locked cursor mode?+ if( _glfwInput.MouseMoved && _glfwWin.mouseLock )+ {+ _glfwPlatformSetMouseCursorPos( _glfwWin.width / 2,+ _glfwWin.height / 2 );+ }++ // Was there a window close request?+ if( winclosed && _glfwWin.windowCloseCallback )+ {+ // Check if the program wants us to close the window+ winclosed = _glfwWin.windowCloseCallback();+ }+ if( winclosed )+ {+ glfwCloseWindow();+ }+}+++//========================================================================+// _glfwPlatformWaitEvents() - Wait for new window and input events+//========================================================================++void _glfwPlatformWaitEvents( void )+{+ WaitMessage();++ _glfwPlatformPollEvents();+}+++//========================================================================+// Hide mouse cursor (lock it)+//========================================================================++void _glfwPlatformHideMouseCursor( void )+{+ RECT ClipWindowRect;++ ShowCursor( FALSE );++ // Clip cursor to the window+ if( GetWindowRect( _glfwWin.window, &ClipWindowRect ) )+ {+ ClipCursor( &ClipWindowRect );+ }++ // Capture cursor to user window+ SetCapture( _glfwWin.window );+}+++//========================================================================+// Show mouse cursor (unlock it)+//========================================================================++void _glfwPlatformShowMouseCursor( void )+{+ // Un-capture cursor+ ReleaseCapture();++ // Release the cursor from the window+ ClipCursor( NULL );++ ShowCursor( TRUE );+}+++//========================================================================+// Set physical mouse cursor position+//========================================================================++void _glfwPlatformSetMouseCursorPos( int x, int y )+{+ POINT pos;++ // Convert client coordinates to screen coordinates+ pos.x = x;+ pos.y = y;+ ClientToScreen( _glfwWin.window, &pos );++ SetCursorPos( pos.x, pos.y );+}+
+ glfw/lib/window.c view
@@ -0,0 +1,981 @@+//========================================================================+// GLFW - An OpenGL framework+// File: window.c+// Platform: Any+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++#include <limits.h>++++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++static int Max(int a, int b)+{+ return (a > b) ? a : b;+}++//========================================================================+// Clear all open window hints+//========================================================================++void _glfwClearWindowHints( void )+{+ memset( &_glfwLibrary.hints, 0, sizeof( _glfwLibrary.hints ) );+}+++//========================================================================+// Handle the input tracking part of window deactivation+//========================================================================++void _glfwInputDeactivation( void )+{+ int i;++ // Release all keyboard keys+ for( i = 0; i <= GLFW_KEY_LAST; i ++ )+ {+ if( _glfwInput.Key[ i ] == GLFW_PRESS )+ {+ _glfwInputKey( i, GLFW_RELEASE );+ }+ }++ // Release all mouse buttons+ for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ )+ {+ if( _glfwInput.MouseButton[ i ] == GLFW_PRESS )+ {+ _glfwInputMouseClick( i, GLFW_RELEASE );+ }+ }+}+++//========================================================================+// _glfwClearInput() - Clear all input state+//========================================================================++void _glfwClearInput( void )+{+ int i;++ // Release all keyboard keys+ for( i = 0; i <= GLFW_KEY_LAST; i ++ )+ {+ _glfwInput.Key[ i ] = GLFW_RELEASE;+ }++ // Clear last character+ _glfwInput.LastChar = 0;++ // Release all mouse buttons+ for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ )+ {+ _glfwInput.MouseButton[ i ] = GLFW_RELEASE;+ }++ // Set mouse position to (0,0)+ _glfwInput.MousePosX = 0;+ _glfwInput.MousePosY = 0;++ // Set mouse wheel position to 0+ _glfwInput.WheelPos = 0;++ // The default is to use non sticky keys and mouse buttons+ _glfwInput.StickyKeys = GL_FALSE;+ _glfwInput.StickyMouseButtons = GL_FALSE;++ // The default is to disable key repeat+ _glfwInput.KeyRepeat = GL_FALSE;+}+++//========================================================================+// _glfwInputKey() - Register keyboard activity+//========================================================================++void _glfwInputKey( int key, int action )+{+ int keyrepeat = 0;++ if( key < 0 || key > GLFW_KEY_LAST )+ {+ return;+ }++ // Are we trying to release an already released key?+ if( action == GLFW_RELEASE && _glfwInput.Key[ key ] != GLFW_PRESS )+ {+ return;+ }++ // Register key action+ if( action == GLFW_RELEASE && _glfwInput.StickyKeys )+ {+ _glfwInput.Key[ key ] = GLFW_STICK;+ }+ else+ {+ keyrepeat = (_glfwInput.Key[ key ] == GLFW_PRESS) &&+ (action == GLFW_PRESS);+ _glfwInput.Key[ key ] = (char) action;+ }++ // Call user callback function+ if( _glfwWin.keyCallback && (_glfwInput.KeyRepeat || !keyrepeat) )+ {+ _glfwWin.keyCallback( key, action );+ }+}+++//========================================================================+// Register (keyboard) character activity+//========================================================================++void _glfwInputChar( int character, int action )+{+ int keyrepeat = 0;++ // Valid Unicode (ISO 10646) character?+ if( !( (character >= 32 && character <= 126) || character >= 160 ) )+ {+ return;+ }++ // Is this a key repeat?+ if( action == GLFW_PRESS && _glfwInput.LastChar == character )+ {+ keyrepeat = 1;+ }++ // Store this character as last character (or clear it, if released)+ if( action == GLFW_PRESS )+ {+ _glfwInput.LastChar = character;+ }+ else+ {+ _glfwInput.LastChar = 0;+ }++ if( action != GLFW_PRESS )+ {+ // This intentionally breaks release notifications for Unicode+ // characters, partly to see if anyone cares but mostly because it's+ // a nonsensical concept to begin with+ //+ // It will remain broken either until its removal in the 3.0 API or+ // until someone explains, in a way that makes sense to people outside+ // the US and Scandinavia, what "Unicode character up" actually means+ //+ // If what you want is "physical key up" then you should be using the+ // key functions and/or the key callback, NOT the Unicode input+ //+ // However, if your particular application uses this misfeature for...+ // something, you can re-enable it by removing this if-statement+ return;+ }++ if( _glfwWin.charCallback && (_glfwInput.KeyRepeat || !keyrepeat) )+ {+ _glfwWin.charCallback( character, action );+ }+}+++//========================================================================+// _glfwInputMouseClick() - Register mouse button clicks+//========================================================================++void _glfwInputMouseClick( int button, int action )+{+ if( button >= 0 && button <= GLFW_MOUSE_BUTTON_LAST )+ {+ // Register mouse button action+ if( action == GLFW_RELEASE && _glfwInput.StickyMouseButtons )+ {+ _glfwInput.MouseButton[ button ] = GLFW_STICK;+ }+ else+ {+ _glfwInput.MouseButton[ button ] = (char) action;+ }++ // Call user callback function+ if( _glfwWin.mouseButtonCallback )+ {+ _glfwWin.mouseButtonCallback( button, action );+ }+ }+}+++//========================================================================+// Return the available framebuffer config closest to the desired values+// This is based on the manual GLX Visual selection from 2.6+//========================================================================++const _GLFWfbconfig *_glfwChooseFBConfig( const _GLFWfbconfig *desired,+ const _GLFWfbconfig *alternatives,+ unsigned int count )+{+ unsigned int i;+ unsigned int missing, leastMissing = UINT_MAX;+ unsigned int colorDiff, leastColorDiff = UINT_MAX;+ unsigned int extraDiff, leastExtraDiff = UINT_MAX;+ GLboolean desiresColor = GL_FALSE;+ const _GLFWfbconfig *current;+ const _GLFWfbconfig *closest = NULL;++ // Cache some long-winded preferences++ if( desired->redBits || desired->greenBits || desired->blueBits ||+ desired->alphaBits )+ {+ desiresColor = GL_TRUE;+ }++ for( i = 0; i < count; i++ )+ {+ current = alternatives + i;++ if( desired->stereo > 0 && current->stereo == 0 )+ {+ // Stereo is a hard constraint+ continue;+ }++ // Count number of missing buffers+ {+ missing = 0;++ if( desired->alphaBits > 0 && current->alphaBits == 0 )+ {+ missing++;+ }++ if( desired->depthBits > 0 && current->depthBits == 0 )+ {+ missing++;+ }++ if( desired->stencilBits > 0 && current->stencilBits == 0 )+ {+ missing++;+ }++ if( desired->auxBuffers > 0 && current->auxBuffers < desired->auxBuffers )+ {+ missing += desired->auxBuffers - current->auxBuffers;+ }++ if( desired->samples > 0 && current->samples == 0 )+ {+ // Technically, several multisampling buffers could be+ // involved, but that's a lower level implementation detail and+ // not important to us here, so we count them as one+ missing++;+ }+ }++ // These polynomials make many small channel size differences matter+ // less than one large channel size difference++ // Calculate color channel size difference value+ {+ colorDiff = 0;++ if ( desired->redBits > 0 )+ {+ colorDiff += ( desired->redBits - current->redBits ) *+ ( desired->redBits - current->redBits );+ }++ if ( desired->greenBits > 0 )+ {+ colorDiff += ( desired->greenBits - current->greenBits ) *+ ( desired->greenBits - current->greenBits );+ }++ if ( desired->blueBits > 0 )+ {+ colorDiff += ( desired->blueBits - current->blueBits ) *+ ( desired->blueBits - current->blueBits );+ }+ }++ // Calculate non-color channel size difference value+ {+ extraDiff = 0;++ if( desired->alphaBits > 0 )+ {+ extraDiff += ( desired->alphaBits - current->alphaBits ) *+ ( desired->alphaBits - current->alphaBits );+ }++ if( desired->depthBits > 0 )+ {+ extraDiff += ( desired->depthBits - current->depthBits ) *+ ( desired->depthBits - current->depthBits );+ }++ if( desired->stencilBits > 0 )+ {+ extraDiff += ( desired->stencilBits - current->stencilBits ) *+ ( desired->stencilBits - current->stencilBits );+ }++ if( desired->accumRedBits > 0 )+ {+ extraDiff += ( desired->accumRedBits - current->accumRedBits ) *+ ( desired->accumRedBits - current->accumRedBits );+ }++ if( desired->accumGreenBits > 0 )+ {+ extraDiff += ( desired->accumGreenBits - current->accumGreenBits ) *+ ( desired->accumGreenBits - current->accumGreenBits );+ }++ if( desired->accumBlueBits > 0 )+ {+ extraDiff += ( desired->accumBlueBits - current->accumBlueBits ) *+ ( desired->accumBlueBits - current->accumBlueBits );+ }++ if( desired->accumAlphaBits > 0 )+ {+ extraDiff += ( desired->accumAlphaBits - current->accumAlphaBits ) *+ ( desired->accumAlphaBits - current->accumAlphaBits );+ }++ if( desired->samples > 0 )+ {+ extraDiff += ( desired->samples - current->samples ) *+ ( desired->samples - current->samples );+ }+ }++ // Figure out if the current one is better than the best one found so far++ if( missing < leastMissing )+ {+ closest = current;+ }+ else if( missing == leastMissing )+ {+ if( desiresColor )+ {+ if( ( colorDiff < leastColorDiff ) ||+ ( colorDiff == leastColorDiff && extraDiff < leastExtraDiff ) )+ {+ closest = current;+ }+ }+ else+ {+ if( ( extraDiff < leastExtraDiff ) ||+ ( extraDiff == leastExtraDiff && colorDiff < leastColorDiff ) )+ {+ closest = current;+ }+ }+ }++ if( current == closest )+ {+ leastMissing = missing;+ leastColorDiff = colorDiff;+ leastExtraDiff = extraDiff;+ }+ }++ return closest;+}+++//************************************************************************+//**** GLFW user functions ****+//************************************************************************++//========================================================================+// Create the GLFW window and its associated context+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height,+ int redbits, int greenbits, int bluebits, int alphabits,+ int depthbits, int stencilbits, int mode )+{+ _GLFWfbconfig fbconfig;+ _GLFWwndconfig wndconfig;++ // Is GLFW initialized?+ if( !_glfwInitialized || _glfwWin.opened )+ {+ return GL_FALSE;+ }++ // Set up desired framebuffer config+ fbconfig.redBits = redbits;+ fbconfig.greenBits = greenbits;+ fbconfig.blueBits = bluebits;+ fbconfig.alphaBits = alphabits;+ fbconfig.depthBits = depthbits;+ fbconfig.stencilBits = stencilbits;+ fbconfig.accumRedBits = _glfwLibrary.hints.accumRedBits;+ fbconfig.accumGreenBits = _glfwLibrary.hints.accumGreenBits;+ fbconfig.accumBlueBits = _glfwLibrary.hints.accumBlueBits;+ fbconfig.accumAlphaBits = _glfwLibrary.hints.accumAlphaBits;+ fbconfig.auxBuffers = _glfwLibrary.hints.auxBuffers;+ fbconfig.stereo = _glfwLibrary.hints.stereo;+ fbconfig.samples = _glfwLibrary.hints.samples;++ // Set up desired window config+ wndconfig.mode = mode;+ wndconfig.refreshRate = _glfwLibrary.hints.refreshRate;+ wndconfig.windowNoResize = _glfwLibrary.hints.windowNoResize;+ wndconfig.glMajor = _glfwLibrary.hints.glMajor;+ wndconfig.glMinor = _glfwLibrary.hints.glMinor;+ wndconfig.glForward = _glfwLibrary.hints.glForward;+ wndconfig.glDebug = _glfwLibrary.hints.glDebug;+ wndconfig.glProfile = _glfwLibrary.hints.glProfile;++ // Clear for next open call+ _glfwClearWindowHints();++ // Check input arguments+ if( mode != GLFW_WINDOW && mode != GLFW_FULLSCREEN )+ {+ return GL_FALSE;+ }++ // Clear GLFW window state+ _glfwWin.active = GL_TRUE;+ _glfwWin.iconified = GL_FALSE;+ _glfwWin.mouseLock = GL_FALSE;+ _glfwWin.autoPollEvents = GL_TRUE;+ _glfwClearInput();++ // Unregister all callback functions+ _glfwWin.windowSizeCallback = NULL;+ _glfwWin.windowCloseCallback = NULL;+ _glfwWin.windowRefreshCallback = NULL;+ _glfwWin.keyCallback = NULL;+ _glfwWin.charCallback = NULL;+ _glfwWin.mousePosCallback = NULL;+ _glfwWin.mouseButtonCallback = NULL;+ _glfwWin.mouseWheelCallback = NULL;++ // Check width & height+ if( width > 0 && height <= 0 )+ {+ // Set the window aspect ratio to 4:3+ height = (width * 3) / 4;+ }+ else if( width <= 0 && height > 0 )+ {+ // Set the window aspect ratio to 4:3+ width = (height * 4) / 3;+ }+ else if( width <= 0 && height <= 0 )+ {+ // Default window size+ width = 640;+ height = 480;+ }++ // Remember window settings+ _glfwWin.width = width;+ _glfwWin.height = height;+ _glfwWin.fullscreen = (mode == GLFW_FULLSCREEN ? GL_TRUE : GL_FALSE);++ // Platform specific window opening routine+ if( !_glfwPlatformOpenWindow( width, height, &wndconfig, &fbconfig ) )+ {+ return GL_FALSE;+ }++ // Flag that window is now opened+ _glfwWin.opened = GL_TRUE;++ // Get window parameters (such as color buffer bits etc)+ _glfwPlatformRefreshWindowParams();++ // Get OpenGL version+ _glfwParseGLVersion( &_glfwWin.glMajor, &_glfwWin.glMinor,+ &_glfwWin.glRevision );++ // Do we have non-power-of-two textures?+ _glfwWin.has_GL_ARB_texture_non_power_of_two =+ ( _glfwWin.glMajor >= 2 ) ||+ glfwExtensionSupported( "GL_ARB_texture_non_power_of_two" );++ // Do we have automatic mipmap generation?+ _glfwWin.has_GL_SGIS_generate_mipmap =+ ( _glfwWin.glMajor >= 2 ) || ( _glfwWin.glMinor >= 4 ) ||+ glfwExtensionSupported( "GL_SGIS_generate_mipmap" );++ // If full-screen mode was requested, disable mouse cursor+ if( mode == GLFW_FULLSCREEN )+ {+ glfwDisable( GLFW_MOUSE_CURSOR );+ }++ return GL_TRUE;+}+++//========================================================================+// Set hints for opening the window+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return;+ }++ switch( target )+ {+ case GLFW_REFRESH_RATE:+ _glfwLibrary.hints.refreshRate = Max(hint, 0);+ break;+ case GLFW_ACCUM_RED_BITS:+ _glfwLibrary.hints.accumRedBits = Max(hint, 0);+ break;+ case GLFW_ACCUM_GREEN_BITS:+ _glfwLibrary.hints.accumGreenBits = Max(hint, 0);+ break;+ case GLFW_ACCUM_BLUE_BITS:+ _glfwLibrary.hints.accumBlueBits = Max(hint, 0);+ break;+ case GLFW_ACCUM_ALPHA_BITS:+ _glfwLibrary.hints.accumAlphaBits = Max(hint, 0);+ break;+ case GLFW_AUX_BUFFERS:+ _glfwLibrary.hints.auxBuffers = Max(hint, 0);+ break;+ case GLFW_STEREO:+ _glfwLibrary.hints.stereo = hint ? GL_TRUE : GL_FALSE;+ break;+ case GLFW_WINDOW_NO_RESIZE:+ _glfwLibrary.hints.windowNoResize = hint ? GL_TRUE : GL_FALSE;+ break;+ case GLFW_FSAA_SAMPLES:+ _glfwLibrary.hints.samples = Max(hint, 0);+ break;+ case GLFW_OPENGL_VERSION_MAJOR:+ _glfwLibrary.hints.glMajor = Max(hint, 0);+ break;+ case GLFW_OPENGL_VERSION_MINOR:+ _glfwLibrary.hints.glMinor = Max(hint, 0);+ break;+ case GLFW_OPENGL_FORWARD_COMPAT:+ _glfwLibrary.hints.glForward = hint ? GL_TRUE : GL_FALSE;+ break;+ case GLFW_OPENGL_DEBUG_CONTEXT:+ _glfwLibrary.hints.glDebug = hint ? GL_TRUE : GL_FALSE;+ break;+ case GLFW_OPENGL_PROFILE:+ if( hint == GLFW_OPENGL_CORE_PROFILE ||+ hint == GLFW_OPENGL_COMPAT_PROFILE )+ {+ _glfwLibrary.hints.glProfile = hint;+ }+ else+ {+ _glfwLibrary.hints.glProfile = 0;+ }+ default:+ break;+ }+}+++//========================================================================+// Properly kill the window / video display+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void )+{+ if( !_glfwInitialized )+ {+ return;+ }++ // Show mouse pointer again (if hidden)+ glfwEnable( GLFW_MOUSE_CURSOR );++ _glfwPlatformCloseWindow();++ memset( &_glfwWin, 0, sizeof(_glfwWin) );+ _glfwWin.opened = GL_FALSE;+}+++//========================================================================+// glfwSetWindowTitle() - Set the window title+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set window title+ _glfwPlatformSetWindowTitle( title );+}+++//========================================================================+// glfwGetWindowSize() - Get the window size+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height )+{+ if( width != NULL )+ {+ *width = _glfwWin.width;+ }+ if( height != NULL )+ {+ *height = _glfwWin.height;+ }+}+++//========================================================================+// glfwSetWindowSize() - Set the window size+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened || _glfwWin.iconified )+ {+ return;+ }++ // Don't do anything if the window size did not change+ if( width == _glfwWin.width && height == _glfwWin.height )+ {+ return;+ }++ // Change window size+ _glfwPlatformSetWindowSize( width, height );++ // Refresh window parameters (may have changed due to changed video+ // modes)+ _glfwPlatformRefreshWindowParams();+}+++//========================================================================+// glfwSetWindowPos() - Set the window position+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened || _glfwWin.fullscreen ||+ _glfwWin.iconified )+ {+ return;+ }++ // Set window position+ _glfwPlatformSetWindowPos( x, y );+}+++//========================================================================+// glfwIconfyWindow() - Window iconification+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened || _glfwWin.iconified )+ {+ return;+ }++ // Iconify window+ _glfwPlatformIconifyWindow();+}+++//========================================================================+// glfwRestoreWindow() - Window un-iconification+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened || !_glfwWin.iconified )+ {+ return;+ }++ // Restore iconified window+ _glfwPlatformRestoreWindow();++ // Refresh window parameters+ _glfwPlatformRefreshWindowParams();+}+++//========================================================================+// glfwSwapBuffers() - Swap buffers (double-buffering) and poll any new+// events+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Check for window messages+ if( _glfwWin.autoPollEvents )+ {+ glfwPollEvents();+ }++ // Update display-buffer+ if( _glfwWin.opened )+ {+ _glfwPlatformSwapBuffers();+ }+}+++//========================================================================+// glfwSwapInterval() - Set double buffering swap interval (0 = vsync off)+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set double buffering swap interval+ _glfwPlatformSwapInterval( interval );+}+++//========================================================================+// glfwGetWindowParam() - Get window parameter+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param )+{+ // Is GLFW initialized?+ if( !_glfwInitialized )+ {+ return 0;+ }++ // Is the window opened?+ if( !_glfwWin.opened )+ {+ if( param == GLFW_OPENED )+ {+ return GL_FALSE;+ }+ return 0;+ }++ // Window parameters+ switch( param )+ {+ case GLFW_OPENED:+ return GL_TRUE;+ case GLFW_ACTIVE:+ return _glfwWin.active;+ case GLFW_ICONIFIED:+ return _glfwWin.iconified;+ case GLFW_ACCELERATED:+ return _glfwWin.accelerated;+ case GLFW_RED_BITS:+ return _glfwWin.redBits;+ case GLFW_GREEN_BITS:+ return _glfwWin.greenBits;+ case GLFW_BLUE_BITS:+ return _glfwWin.blueBits;+ case GLFW_ALPHA_BITS:+ return _glfwWin.alphaBits;+ case GLFW_DEPTH_BITS:+ return _glfwWin.depthBits;+ case GLFW_STENCIL_BITS:+ return _glfwWin.stencilBits;+ case GLFW_ACCUM_RED_BITS:+ return _glfwWin.accumRedBits;+ case GLFW_ACCUM_GREEN_BITS:+ return _glfwWin.accumGreenBits;+ case GLFW_ACCUM_BLUE_BITS:+ return _glfwWin.accumBlueBits;+ case GLFW_ACCUM_ALPHA_BITS:+ return _glfwWin.accumAlphaBits;+ case GLFW_AUX_BUFFERS:+ return _glfwWin.auxBuffers;+ case GLFW_STEREO:+ return _glfwWin.stereo;+ case GLFW_REFRESH_RATE:+ return _glfwWin.refreshRate;+ case GLFW_WINDOW_NO_RESIZE:+ return _glfwWin.windowNoResize;+ case GLFW_FSAA_SAMPLES:+ return _glfwWin.samples;+ case GLFW_OPENGL_VERSION_MAJOR:+ return _glfwWin.glMajor;+ case GLFW_OPENGL_VERSION_MINOR:+ return _glfwWin.glMinor;+ case GLFW_OPENGL_FORWARD_COMPAT:+ return _glfwWin.glForward;+ case GLFW_OPENGL_DEBUG_CONTEXT:+ return _glfwWin.glDebug;+ case GLFW_OPENGL_PROFILE:+ return _glfwWin.glProfile;+ default:+ return 0;+ }+}+++//========================================================================+// glfwSetWindowSizeCallback() - Set callback function for window size+// changes+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set callback function+ _glfwWin.windowSizeCallback = cbfun;++ // Call the callback function to let the application know the current+ // window size+ if( cbfun )+ {+ cbfun( _glfwWin.width, _glfwWin.height );+ }+}++//========================================================================+// glfwSetWindowCloseCallback() - Set callback function for window close+// events+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set callback function+ _glfwWin.windowCloseCallback = cbfun;+}+++//========================================================================+// glfwSetWindowRefreshCallback() - Set callback function for window+// refresh events+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Set callback function+ _glfwWin.windowRefreshCallback = cbfun;+}+++//========================================================================+// glfwPollEvents() - Poll for new window and input events+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwPollEvents( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Poll for new events+ _glfwPlatformPollEvents();+}+++//========================================================================+// glfwWaitEvents() - Wait for new window and input events+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void )+{+ // Is GLFW initialized?+ if( !_glfwInitialized || !_glfwWin.opened )+ {+ return;+ }++ // Poll for new events+ _glfwPlatformWaitEvents();+}+
+ glfw/lib/x11/x11_enable.c view
@@ -0,0 +1,55 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_enable.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Enable system keys+//========================================================================++void _glfwPlatformEnableSystemKeys( void )+{+ // Not supported under X11 (yet)+}++//========================================================================+// Disable system keys+//========================================================================++void _glfwPlatformDisableSystemKeys( void )+{+ // Not supported under X11 (yet)+}+
+ glfw/lib/x11/x11_fullscreen.c view
@@ -0,0 +1,528 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_fullscreen.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++#include <limits.h>+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// Convert BPP to RGB bits (based on "best guess")+//========================================================================++static void BPP2RGB( int bpp, int *r, int *g, int *b )+{+ int delta;++ // Special case: BPP = 32 (I don't think this is necessary for X11??)+ if( bpp == 32 )+ bpp = 24;++ // Convert "bits per pixel" to red, green & blue sizes+ *r = *g = *b = bpp / 3;+ delta = bpp - (*r * 3);+ if( delta >= 1 )+ {+ *g = *g + 1;+ }+ if( delta == 2 )+ {+ *r = *r + 1;+ }+}+++//========================================================================+// Finds the video mode closest in size to the specified desired size+//========================================================================++int _glfwGetClosestVideoMode( int screen, int *width, int *height, int *rate )+{+#if defined( _GLFW_HAS_XRANDR )+ int i, match, bestmatch;+ int sizecount, bestsize;+ int ratecount, bestrate;+ short *ratelist;+ XRRScreenConfiguration *sc;+ XRRScreenSize *sizelist;++ if( _glfwLibrary.XRandR.available )+ {+ sc = XRRGetScreenInfo( _glfwLibrary.display,+ RootWindow( _glfwLibrary.display, screen ) );++ sizelist = XRRConfigSizes( sc, &sizecount );++ // Find the best matching mode+ bestsize = -1;+ bestmatch = INT_MAX;+ for( i = 0; i < sizecount; i++ )+ {+ match = (*width - sizelist[i].width) *+ (*width - sizelist[i].width) ++ (*height - sizelist[i].height) *+ (*height - sizelist[i].height);+ if( match < bestmatch )+ {+ bestmatch = match;+ bestsize = i;+ }+ }++ if( bestsize != -1 )+ {+ // Report width & height of best matching mode+ *width = sizelist[bestsize].width;+ *height = sizelist[bestsize].height;++ if( *rate > 0 )+ {+ ratelist = XRRConfigRates( sc, bestsize, &ratecount );++ bestrate = -1;+ bestmatch = INT_MAX;+ for( i = 0; i < ratecount; i++ )+ {+ match = abs( ratelist[i] - *rate );+ if( match < bestmatch )+ {+ bestmatch = match;+ bestrate = ratelist[i];+ }+ }++ if( bestrate != -1 )+ {+ *rate = bestrate;+ }+ }+ }++ // Free modelist+ XRRFreeScreenConfigInfo( sc );++ if( bestsize != -1 )+ {+ return bestsize;+ }+ }+#elif defined( _GLFW_HAS_XF86VIDMODE )+ XF86VidModeModeInfo **modelist;+ int modecount, i, bestmode, bestmatch, match;++ // Use the XF86VidMode extension to control video resolution+ if( _glfwLibrary.XF86VidMode.available )+ {+ // Get a list of all available display modes+ XF86VidModeGetAllModeLines( _glfwLibrary.display, screen,+ &modecount, &modelist );++ // Find the best matching mode+ bestmode = -1;+ bestmatch = INT_MAX;+ for( i = 0; i < modecount; i++ )+ {+ match = (*width - modelist[i]->hdisplay) *+ (*width - modelist[i]->hdisplay) ++ (*height - modelist[i]->vdisplay) *+ (*height - modelist[i]->vdisplay);+ if( match < bestmatch )+ {+ bestmatch = match;+ bestmode = i;+ }+ }++ if( bestmode != -1 )+ {+ // Report width & height of best matching mode+ *width = modelist[ bestmode ]->hdisplay;+ *height = modelist[ bestmode ]->vdisplay;+ }++ // Free modelist+ XFree( modelist );++ if( bestmode != -1 )+ {+ return bestmode;+ }+ }+#endif++ // Default: Simply use the screen resolution+ *width = DisplayWidth( _glfwLibrary.display, screen );+ *height = DisplayHeight( _glfwLibrary.display, screen );++ return 0;+}+++//========================================================================+// Change the current video mode+//========================================================================++void _glfwSetVideoModeMODE( int screen, int mode, int rate )+{+#if defined( _GLFW_HAS_XRANDR )+ XRRScreenConfiguration *sc;+ Window root;++ if( _glfwLibrary.XRandR.available )+ {+ root = RootWindow( _glfwLibrary.display, screen );+ sc = XRRGetScreenInfo( _glfwLibrary.display, root );++ // Remember old size and flag that we have changed the mode+ if( !_glfwWin.FS.modeChanged )+ {+ _glfwWin.FS.oldSizeID = XRRConfigCurrentConfiguration( sc, &_glfwWin.FS.oldRotation );+ _glfwWin.FS.oldWidth = DisplayWidth( _glfwLibrary.display, screen );+ _glfwWin.FS.oldHeight = DisplayHeight( _glfwLibrary.display, screen );++ _glfwWin.FS.modeChanged = GL_TRUE;+ }++ if( rate > 0 )+ {+ // Set desired configuration+ XRRSetScreenConfigAndRate( _glfwLibrary.display,+ sc,+ root,+ mode,+ RR_Rotate_0,+ (short) rate,+ CurrentTime );+ }+ else+ {+ // Set desired configuration+ XRRSetScreenConfig( _glfwLibrary.display,+ sc,+ root,+ mode,+ RR_Rotate_0,+ CurrentTime );+ }++ XRRFreeScreenConfigInfo( sc );+ }+#elif defined( _GLFW_HAS_XF86VIDMODE )+ XF86VidModeModeInfo **modelist;+ int modecount;++ // Use the XF86VidMode extension to control video resolution+ if( _glfwLibrary.XF86VidMode.available )+ {+ // Get a list of all available display modes+ XF86VidModeGetAllModeLines( _glfwLibrary.display, screen,+ &modecount, &modelist );++ // Unlock mode switch if necessary+ if( _glfwWin.FS.modeChanged )+ {+ XF86VidModeLockModeSwitch( _glfwLibrary.display, screen, 0 );+ }++ // Change the video mode to the desired mode+ XF86VidModeSwitchToMode( _glfwLibrary.display, screen,+ modelist[ mode ] );++ // Set viewport to upper left corner (where our window will be)+ XF86VidModeSetViewPort( _glfwLibrary.display, screen, 0, 0 );++ // Lock mode switch+ XF86VidModeLockModeSwitch( _glfwLibrary.display, screen, 1 );++ // Remember old mode and flag that we have changed the mode+ if( !_glfwWin.FS.modeChanged )+ {+ _glfwWin.FS.oldMode = *modelist[ 0 ];+ _glfwWin.FS.modeChanged = GL_TRUE;+ }++ // Free mode list+ XFree( modelist );+ }+#endif+}+++//========================================================================+// Change the current video mode+//========================================================================++void _glfwSetVideoMode( int screen, int *width, int *height, int *rate )+{+ int bestmode;++ // Find a best match mode+ bestmode = _glfwGetClosestVideoMode( screen, width, height, rate );++ // Change mode+ _glfwSetVideoModeMODE( screen, bestmode, *rate );+}++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++struct _glfwResolution+{+ int width;+ int height;+};++//========================================================================+// List available video modes+//========================================================================++int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )+{+ int count, k, l, r, g, b, rgba, gl;+ int depth, screen;+ Display *dpy;+ XVisualInfo *vislist, dummy;+ int viscount, rgbcount, rescount;+ int *rgbarray;+ struct _glfwResolution *resarray;+#if defined( _GLFW_HAS_XRANDR )+ XRRScreenConfiguration *sc;+ XRRScreenSize *sizelist;+ int sizecount;+#elif defined( _GLFW_HAS_XF86VIDMODE )+ XF86VidModeModeInfo **modelist;+ int modecount, width, height;+#endif++ // Get display and screen+ dpy = _glfwLibrary.display;+ screen = DefaultScreen( dpy );++ // Get list of visuals+ vislist = XGetVisualInfo( dpy, 0, &dummy, &viscount );+ if( vislist == NULL )+ {+ return 0;+ }++ rgbarray = (int*) malloc( sizeof(int) * viscount );+ rgbcount = 0;++ // Build RGB array+ for( k = 0; k < viscount; k++ )+ {+ // Does the visual support OpenGL & true color?+ glXGetConfig( dpy, &vislist[k], GLX_USE_GL, &gl );+ glXGetConfig( dpy, &vislist[k], GLX_RGBA, &rgba );+ if( gl && rgba )+ {+ // Get color depth for this visual+ depth = vislist[k].depth;++ // Convert to RGB+ BPP2RGB( depth, &r, &g, &b );+ depth = (r<<16) | (g<<8) | b;++ // Is this mode unique?+ for( l = 0; l < rgbcount; l++ )+ {+ if( depth == rgbarray[ l ] )+ {+ break;+ }+ }+ if( l >= rgbcount )+ {+ rgbarray[ rgbcount ] = depth;+ rgbcount++;+ }+ }+ }++ rescount = 0;+ resarray = NULL;++ // Build resolution array+#if defined( _GLFW_HAS_XRANDR )+ if( _glfwLibrary.XRandR.available )+ {+ sc = XRRGetScreenInfo( dpy, RootWindow( dpy, screen ) );+ sizelist = XRRConfigSizes( sc, &sizecount );++ resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * sizecount );++ for( k = 0; k < sizecount; k++ )+ {+ resarray[ rescount ].width = sizelist[ k ].width;+ resarray[ rescount ].height = sizelist[ k ].height;+ rescount++;+ }++ XRRFreeScreenConfigInfo( sc );+ }+#elif defined( _GLFW_HAS_XF86VIDMODE )+ if( _glfwLibrary.XF86VidMode.available )+ {+ XF86VidModeGetAllModeLines( dpy, screen, &modecount, &modelist );++ resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * modecount );++ for( k = 0; k < modecount; k++ )+ {+ width = modelist[ k ]->hdisplay;+ height = modelist[ k ]->vdisplay;++ // Is this mode unique?+ for( l = 0; l < rescount; l++ )+ {+ if( width == resarray[ l ].width && height == resarray[ l ].height )+ {+ break;+ }+ }++ if( l >= rescount )+ {+ resarray[ rescount ].width = width;+ resarray[ rescount ].height = height;+ rescount++;+ }+ }++ XFree( modelist );+ }+#endif++ if( !resarray )+ {+ rescount = 1;+ resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * rescount );++ resarray[ 0 ].width = DisplayWidth( dpy, screen );+ resarray[ 0 ].height = DisplayHeight( dpy, screen );+ }++ // Build permutations of colors and resolutions+ count = 0;+ for( k = 0; k < rgbcount && count < maxcount; k++ )+ {+ for( l = 0; l < rescount && count < maxcount; l++ )+ {+ list[count].Width = resarray[ l ].width;+ list[count].Height = resarray[ l ].height;+ list[count].RedBits = (rgbarray[ k ] >> 16) & 255;+ list[count].GreenBits = (rgbarray[ k ] >> 8) & 255;+ list[count].BlueBits = rgbarray[ k ] & 255;+ count++;+ }+ }++ // Free visuals list+ XFree( vislist );++ free( resarray );+ free( rgbarray );++ return count;+}+++//========================================================================+// Get the desktop video mode+//========================================================================++void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )+{+ Display *dpy;+ int bpp, screen;+#if defined( _GLFW_HAS_XF86VIDMODE )+ XF86VidModeModeInfo **modelist;+ int modecount;+#endif++ // Get display and screen+ dpy = _glfwLibrary.display;+ screen = DefaultScreen( dpy );++ // Get display depth+ bpp = DefaultDepth( dpy, screen );++ // Convert BPP to RGB bits+ BPP2RGB( bpp, &mode->RedBits, &mode->GreenBits, &mode->BlueBits );++#if defined( _GLFW_HAS_XRANDR )+ if( _glfwLibrary.XRandR.available )+ {+ if( _glfwWin.FS.modeChanged )+ {+ mode->Width = _glfwWin.FS.oldWidth;+ mode->Height = _glfwWin.FS.oldHeight;+ return;+ }+ }+#elif defined( _GLFW_HAS_XF86VIDMODE )+ if( _glfwLibrary.XF86VidMode.available )+ {+ if( _glfwWin.FS.modeChanged )+ {+ // The old (desktop) mode is stored in _glfwWin.FS.oldMode+ mode->Width = _glfwWin.FS.oldMode.hdisplay;+ mode->Height = _glfwWin.FS.oldMode.vdisplay;+ }+ else+ {+ // Use the XF86VidMode extension to get list of video modes+ XF86VidModeGetAllModeLines( dpy, screen, &modecount,+ &modelist );++ // The first mode in the list is the current (desktio) mode+ mode->Width = modelist[ 0 ]->hdisplay;+ mode->Height = modelist[ 0 ]->vdisplay;++ // Free list+ XFree( modelist );+ }++ return;+ }+#endif++ // Get current display width and height+ mode->Width = DisplayWidth( dpy, screen );+ mode->Height = DisplayHeight( dpy, screen );+}+
+ glfw/lib/x11/x11_glext.c view
@@ -0,0 +1,90 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_glext.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++void (*glXGetProcAddress(const GLubyte *procName))();+void (*glXGetProcAddressARB(const GLubyte *procName))();+void (*glXGetProcAddressEXT(const GLubyte *procName))();++// 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(_glfwLibs.libGL,x)+ #define _GLFW_DLOPEN_LIBGL+#else+#define _glfw_glXGetProcAddress(x) NULL+#endif+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Check if an OpenGL extension is available at runtime+//========================================================================++int _glfwPlatformExtensionSupported( const char *extension )+{+ const GLubyte *extensions;++ // Get list of GLX extensions+ extensions = (const GLubyte*) glXQueryExtensionsString( _glfwLibrary.display,+ _glfwWin.screen );+ if( extensions != NULL )+ {+ if( _glfwStringInExtensionString( extension, extensions ) )+ {+ return GL_TRUE;+ }+ }++ return GL_FALSE;+}+++//========================================================================+// Get the function pointer to an OpenGL function+//========================================================================++void * _glfwPlatformGetProcAddress( const char *procname )+{+ return (void *) _glfw_glXGetProcAddress( (const GLubyte *) procname );+}+
+ glfw/lib/x11/x11_init.c view
@@ -0,0 +1,286 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_init.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// Initialize GLFW thread package+//========================================================================++static void initThreads( void )+{+ // Initialize critical section handle+#ifdef _GLFW_HAS_PTHREAD+ (void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL );+#endif++ // The first thread (the main thread) has ID 0+ _glfwThrd.NextID = 0;++ // Fill out information about the main thread (this thread)+ _glfwThrd.First.ID = _glfwThrd.NextID++;+ _glfwThrd.First.Function = NULL;+ _glfwThrd.First.Previous = NULL;+ _glfwThrd.First.Next = NULL;+#ifdef _GLFW_HAS_PTHREAD+ _glfwThrd.First.PosixID = pthread_self();+#endif+}+++//========================================================================+// Terminate GLFW thread package+//========================================================================++static void terminateThreads( void )+{+#ifdef _GLFW_HAS_PTHREAD++ _GLFWthread *t, *t_next;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO+ // DIE, _BEFORE_ CALLING glfwTerminate()!!!)+ t = _glfwThrd.First.Next;+ while( t != NULL )+ {+ // Get pointer to next thread+ t_next = t->Next;++ // Simply murder the process, no mercy!+ pthread_kill( t->PosixID, SIGKILL );++ // Free memory allocated for this thread+ free( (void *) t );++ // Select next thread in list+ t = t_next;+ }++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Delete critical section handle+ pthread_mutex_destroy( &_glfwThrd.CriticalSection );++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// Dynamically load libraries+//========================================================================++static void initLibraries( void )+{+#ifdef _GLFW_DLOPEN_LIBGL+ int i;+ char *libGL_names[ ] =+ {+ "libGL.so",+ "libGL.so.1",+ "/usr/lib/libGL.so",+ "/usr/lib/libGL.so.1",+ NULL+ };++ _glfwLibrary.Libs.libGL = NULL;+ for( i = 0; !libGL_names[ i ] != NULL; i ++ )+ {+ _glfwLibrary.Libs.libGL = dlopen( libGL_names[ i ],+ RTLD_LAZY | RTLD_GLOBAL );+ if( _glfwLibrary.Libs.libGL )+ break;+ }+#endif+}+++//========================================================================+// Terminate GLFW when exiting application+//========================================================================++static void glfw_atexit( void )+{+ glfwTerminate();+}+++//========================================================================+// Initialize X11 display+//========================================================================++static int initDisplay( void )+{+ // Open display+ _glfwLibrary.display = XOpenDisplay( 0 );+ if( !_glfwLibrary.display )+ {+ fprintf(stderr, "Failed to open X display\n");+ return GL_FALSE;+ }++ // Check for XF86VidMode extension+#ifdef _GLFW_HAS_XF86VIDMODE+ _glfwLibrary.XF86VidMode.available =+ XF86VidModeQueryExtension( _glfwLibrary.display,+ &_glfwLibrary.XF86VidMode.eventBase,+ &_glfwLibrary.XF86VidMode.errorBase);+#else+ _glfwLibrary.XF86VidMode.available = 0;+#endif++ // Check for XRandR extension+#ifdef _GLFW_HAS_XRANDR+ _glfwLibrary.XRandR.available =+ XRRQueryExtension( _glfwLibrary.display,+ &_glfwLibrary.XRandR.eventBase,+ &_glfwLibrary.XRandR.errorBase );+#else+ _glfwLibrary.XRandR.available = 0;+#endif++ // Fullscreen & screen saver settings+ // Check if GLX is supported on this display+ if( !glXQueryExtension( _glfwLibrary.display, NULL, NULL ) )+ {+ fprintf(stderr, "GLX not supported\n");+ return GL_FALSE;+ }++ // Retrieve GLX version+ if( !glXQueryVersion( _glfwLibrary.display,+ &_glfwLibrary.glxMajor,+ &_glfwLibrary.glxMinor ) )+ {+ fprintf(stderr, "Unable to query GLX version\n");+ return GL_FALSE;+ }++ return GL_TRUE;+}+++//========================================================================+// Terminate X11 display+//========================================================================++static void terminateDisplay( void )+{+ // Open display+ if( _glfwLibrary.display )+ {+ XCloseDisplay( _glfwLibrary.display );+ _glfwLibrary.display = NULL;+ }+}+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Initialize various GLFW state+//========================================================================++int _glfwPlatformInit( void )+{+ // Initialize display+ if( !initDisplay() )+ {+ return GL_FALSE;+ }++ // Initialize thread package+ initThreads();++ // Try to load libGL.so if necessary+ initLibraries();++ // Install atexit() routine+ // atexit( glfw_atexit );++ // Initialize joysticks+ _glfwInitJoysticks();++ // Start the timer+ _glfwInitTimer();++ return GL_TRUE;+}+++//========================================================================+// Close window and kill all threads+//========================================================================++int _glfwPlatformTerminate( void )+{+#ifdef _GLFW_HAS_PTHREAD+ // Only the main thread is allowed to do this...+ if( pthread_self() != _glfwThrd.First.PosixID )+ {+ return GL_FALSE;+ }+#endif // _GLFW_HAS_PTHREAD++ // Close OpenGL window+ glfwCloseWindow();++ // Kill thread package+ terminateThreads();++ // Terminate display+ terminateDisplay();++ // Terminate joysticks+ _glfwTerminateJoysticks();++ // Unload libGL.so if necessary+#ifdef _GLFW_DLOPEN_LIBGL+ if( _glfwLibrary.Libs.libGL != NULL )+ {+ dlclose( _glfwLibrary.Libs.libGL );+ _glfwLibrary.Libs.libGL = NULL;+ }+#endif++ return GL_TRUE;+}+
+ glfw/lib/x11/x11_joystick.c view
@@ -0,0 +1,367 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_joystick.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//========================================================================+// Note: Only Linux joystick input is supported at the moment. Other+// systems will behave as if there are no joysticks connected.+//========================================================================+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++#ifdef _GLFW_USE_LINUX_JOYSTICKS++//------------------------------------------------------------------------+// Here are the Linux joystick driver v1.x interface definitions that we+// use (we do not want to rely on <linux/joystick.h>):+//------------------------------------------------------------------------++#include <sys/ioctl.h>+#include <fcntl.h>+#include <errno.h>++// Joystick event types+#define JS_EVENT_BUTTON 0x01 /* button pressed/released */+#define JS_EVENT_AXIS 0x02 /* joystick moved */+#define JS_EVENT_INIT 0x80 /* initial state of device */++// Joystick event structure+struct js_event {+ unsigned int time; /* (u32) event timestamp in milliseconds */+ signed short value; /* (s16) value */+ unsigned char type; /* (u8) event type */+ unsigned char number; /* (u8) axis/button number */+};++// Joystick IOCTL commands+#define JSIOCGVERSION _IOR('j', 0x01, int) /* get driver version (u32) */+#define JSIOCGAXES _IOR('j', 0x11, char) /* get number of axes (u8) */+#define JSIOCGBUTTONS _IOR('j', 0x12, char) /* get number of buttons (u8) */++#endif // _GLFW_USE_LINUX_JOYSTICKS+++//========================================================================+// _glfwInitJoysticks() - Initialize joystick interface+//========================================================================++void _glfwInitJoysticks( void )+{+#ifdef _GLFW_USE_LINUX_JOYSTICKS+ int k, n, fd, joy_count;+ char *joy_base_name, joy_dev_name[ 20 ];+ int driver_version = 0x000800;+ char ret_data;+#endif // _GLFW_USE_LINUX_JOYSTICKS+ int i;++ // Start by saying that there are no sticks+ for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i )+ {+ _glfwJoy[ i ].Present = GL_FALSE;+ }++#ifdef _GLFW_USE_LINUX_JOYSTICKS++ // Try to open joysticks (nonblocking)+ joy_count = 0;+ for( k = 0; k <= 1 && joy_count <= GLFW_JOYSTICK_LAST; ++ k )+ {+ // Pick joystick base name+ switch( k )+ {+ case 0:+ joy_base_name = "/dev/input/js"; // USB sticks+ break;+ case 1:+ joy_base_name = "/dev/js"; // "Legacy" sticks+ break;+ default:+ continue; // (should never happen)+ }++ // Try to open a few of these sticks+ for( i = 0; i <= 50 && joy_count <= GLFW_JOYSTICK_LAST; ++ i )+ {+ sprintf( joy_dev_name, "%s%d", joy_base_name, i );+ fd = open( joy_dev_name, O_NONBLOCK );+ if( fd != -1 )+ {+ // Remember fd+ _glfwJoy[ joy_count ].fd = fd;++ // Check that the joystick driver version is 1.0++ ioctl( fd, JSIOCGVERSION, &driver_version );+ if( driver_version < 0x010000 )+ {+ // It's an old 0.x interface (we don't support it)+ close( fd );+ continue;+ }++ // Get number of joystick axes+ ioctl( fd, JSIOCGAXES, &ret_data );+ _glfwJoy[ joy_count ].NumAxes = (int) ret_data;++ // Get number of joystick buttons+ ioctl( fd, JSIOCGBUTTONS, &ret_data );+ _glfwJoy[ joy_count ].NumButtons = (int) ret_data;++ // Allocate memory for joystick state+ _glfwJoy[ joy_count ].Axis =+ (float *) malloc( sizeof(float) *+ _glfwJoy[ joy_count ].NumAxes );+ if( _glfwJoy[ joy_count ].Axis == NULL )+ {+ close( fd );+ continue;+ }+ _glfwJoy[ joy_count ].Button =+ (unsigned char *) malloc( sizeof(char) *+ _glfwJoy[ joy_count ].NumButtons );+ if( _glfwJoy[ joy_count ].Button == NULL )+ {+ free( _glfwJoy[ joy_count ].Axis );+ close( fd );+ continue;+ }++ // Clear joystick state+ for( n = 0; n < _glfwJoy[ joy_count ].NumAxes; ++ n )+ {+ _glfwJoy[ joy_count ].Axis[ n ] = 0.0f;+ }+ for( n = 0; n < _glfwJoy[ joy_count ].NumButtons; ++ n )+ {+ _glfwJoy[ joy_count ].Button[ n ] = GLFW_RELEASE;+ }++ // The joystick is supported and connected+ _glfwJoy[ joy_count ].Present = GL_TRUE;+ joy_count ++;+ }+ }+ }++#endif // _GLFW_USE_LINUX_JOYSTICKS++}+++//========================================================================+// _glfwTerminateJoysticks() - Close all opened joystick handles+//========================================================================++void _glfwTerminateJoysticks( void )+{++#ifdef _GLFW_USE_LINUX_JOYSTICKS++ int i;++ // Close any opened joysticks+ for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i )+ {+ if( _glfwJoy[ i ].Present )+ {+ close( _glfwJoy[ i ].fd );+ free( _glfwJoy[ i ].Axis );+ free( _glfwJoy[ i ].Button );+ _glfwJoy[ i ].Present = GL_FALSE;+ }+ }++#endif // _GLFW_USE_LINUX_JOYSTICKS++}+++//========================================================================+// Empty joystick event queue+//========================================================================++static void pollJoystickEvents( void )+{++#ifdef _GLFW_USE_LINUX_JOYSTICKS++ struct js_event e;+ int i;++ // Get joystick events for all GLFW joysticks+ for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i )+ {+ // Is the stick present?+ if( _glfwJoy[ i ].Present )+ {+ // Read all queued events (non-blocking)+ while( read(_glfwJoy[i].fd, &e, sizeof(struct js_event)) > 0 )+ {+ // We don't care if it's an init event or not+ e.type &= ~JS_EVENT_INIT;++ // Check event type+ switch( e.type )+ {+ case JS_EVENT_AXIS:+ _glfwJoy[ i ].Axis[ e.number ] = (float) e.value /+ 32767.0f;+ // We need to change the sign for the Y axes, so that+ // positive = up/forward, according to the GLFW spec.+ if( e.number & 1 )+ {+ _glfwJoy[ i ].Axis[ e.number ] =+ -_glfwJoy[ i ].Axis[ e.number ];+ }+ break;++ case JS_EVENT_BUTTON:+ _glfwJoy[ i ].Button[ e.number ] =+ e.value ? GLFW_PRESS : GLFW_RELEASE;+ break;++ default:+ break;+ }+ }+ }+ }++#endif // _GLFW_USE_LINUX_JOYSTICKS++}+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// _glfwPlatformGetJoystickParam() - Determine joystick capabilities+//========================================================================++int _glfwPlatformGetJoystickParam( int joy, int param )+{+ // Is joystick present?+ if( !_glfwJoy[ joy ].Present )+ {+ return 0;+ }++ switch( param )+ {+ case GLFW_PRESENT:+ return GL_TRUE;++ case GLFW_AXES:+ return _glfwJoy[ joy ].NumAxes;++ case GLFW_BUTTONS:+ return _glfwJoy[ joy ].NumButtons;++ default:+ break;+ }++ return 0;+}+++//========================================================================+// _glfwPlatformGetJoystickPos() - Get joystick axis positions+//========================================================================++int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )+{+ int i;++ // Is joystick present?+ if( !_glfwJoy[ joy ].Present )+ {+ return 0;+ }++ // Update joystick state+ pollJoystickEvents();++ // Does the joystick support less axes than requested?+ if( _glfwJoy[ joy ].NumAxes < numaxes )+ {+ numaxes = _glfwJoy[ joy ].NumAxes;+ }++ // Copy axis positions from internal state+ for( i = 0; i < numaxes; ++ i )+ {+ pos[ i ] = _glfwJoy[ joy ].Axis[ i ];+ }++ return numaxes;+}+++//========================================================================+// _glfwPlatformGetJoystickButtons() - Get joystick button states+//========================================================================++int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,+ int numbuttons )+{+ int i;++ // Is joystick present?+ if( !_glfwJoy[ joy ].Present )+ {+ return 0;+ }++ // Update joystick state+ pollJoystickEvents();++ // Does the joystick support less buttons than requested?+ if( _glfwJoy[ joy ].NumButtons < numbuttons )+ {+ numbuttons = _glfwJoy[ joy ].NumButtons;+ }++ // Copy button states from internal state+ for( i = 0; i < numbuttons; ++ i )+ {+ buttons[ i ] = _glfwJoy[ joy ].Button[ i ];+ }++ return numbuttons;+}+
+ glfw/lib/x11/x11_keysym2unicode.c view
@@ -0,0 +1,901 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_keysym2unicode.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++/*+ * Marcus: This code was originally written by Markus G. Kuhn.+ * I have made some slight changes (trimmed it down a bit from >60 KB to+ * 20 KB), but the functionality is the same.+ */++/*+ * This module converts keysym values into the corresponding ISO 10646+ * (UCS, Unicode) values.+ *+ * The array keysymtab[] contains pairs of X11 keysym values for graphical+ * characters and the corresponding Unicode value. The function+ * _glfwKeySym2Unicode() maps a keysym onto a Unicode value using a binary+ * search, therefore keysymtab[] must remain SORTED by keysym value.+ *+ * We allow to represent any UCS character in the range U-00000000 to+ * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.+ * This admittedly does not cover the entire 31-bit space of UCS, but+ * it does cover all of the characters up to U-10FFFF, which can be+ * represented by UTF-16, and more, and it is very unlikely that higher+ * UCS codes will ever be assigned by ISO. So to get Unicode character+ * U+ABCD you can directly use keysym 0x0100abcd.+ *+ * Original author: Markus G. Kuhn <mkuhn@acm.org>, University of+ * Cambridge, April 2001+ *+ * Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing+ * an initial draft of the mapping table.+ *+ */+++//************************************************************************+//**** KeySym to Unicode mapping table ****+//************************************************************************++static struct codepair {+ unsigned short keysym;+ unsigned short ucs;+} keysymtab[] = {+ { 0x01a1, 0x0104 },+ { 0x01a2, 0x02d8 },+ { 0x01a3, 0x0141 },+ { 0x01a5, 0x013d },+ { 0x01a6, 0x015a },+ { 0x01a9, 0x0160 },+ { 0x01aa, 0x015e },+ { 0x01ab, 0x0164 },+ { 0x01ac, 0x0179 },+ { 0x01ae, 0x017d },+ { 0x01af, 0x017b },+ { 0x01b1, 0x0105 },+ { 0x01b2, 0x02db },+ { 0x01b3, 0x0142 },+ { 0x01b5, 0x013e },+ { 0x01b6, 0x015b },+ { 0x01b7, 0x02c7 },+ { 0x01b9, 0x0161 },+ { 0x01ba, 0x015f },+ { 0x01bb, 0x0165 },+ { 0x01bc, 0x017a },+ { 0x01bd, 0x02dd },+ { 0x01be, 0x017e },+ { 0x01bf, 0x017c },+ { 0x01c0, 0x0154 },+ { 0x01c3, 0x0102 },+ { 0x01c5, 0x0139 },+ { 0x01c6, 0x0106 },+ { 0x01c8, 0x010c },+ { 0x01ca, 0x0118 },+ { 0x01cc, 0x011a },+ { 0x01cf, 0x010e },+ { 0x01d0, 0x0110 },+ { 0x01d1, 0x0143 },+ { 0x01d2, 0x0147 },+ { 0x01d5, 0x0150 },+ { 0x01d8, 0x0158 },+ { 0x01d9, 0x016e },+ { 0x01db, 0x0170 },+ { 0x01de, 0x0162 },+ { 0x01e0, 0x0155 },+ { 0x01e3, 0x0103 },+ { 0x01e5, 0x013a },+ { 0x01e6, 0x0107 },+ { 0x01e8, 0x010d },+ { 0x01ea, 0x0119 },+ { 0x01ec, 0x011b },+ { 0x01ef, 0x010f },+ { 0x01f0, 0x0111 },+ { 0x01f1, 0x0144 },+ { 0x01f2, 0x0148 },+ { 0x01f5, 0x0151 },+ { 0x01f8, 0x0159 },+ { 0x01f9, 0x016f },+ { 0x01fb, 0x0171 },+ { 0x01fe, 0x0163 },+ { 0x01ff, 0x02d9 },+ { 0x02a1, 0x0126 },+ { 0x02a6, 0x0124 },+ { 0x02a9, 0x0130 },+ { 0x02ab, 0x011e },+ { 0x02ac, 0x0134 },+ { 0x02b1, 0x0127 },+ { 0x02b6, 0x0125 },+ { 0x02b9, 0x0131 },+ { 0x02bb, 0x011f },+ { 0x02bc, 0x0135 },+ { 0x02c5, 0x010a },+ { 0x02c6, 0x0108 },+ { 0x02d5, 0x0120 },+ { 0x02d8, 0x011c },+ { 0x02dd, 0x016c },+ { 0x02de, 0x015c },+ { 0x02e5, 0x010b },+ { 0x02e6, 0x0109 },+ { 0x02f5, 0x0121 },+ { 0x02f8, 0x011d },+ { 0x02fd, 0x016d },+ { 0x02fe, 0x015d },+ { 0x03a2, 0x0138 },+ { 0x03a3, 0x0156 },+ { 0x03a5, 0x0128 },+ { 0x03a6, 0x013b },+ { 0x03aa, 0x0112 },+ { 0x03ab, 0x0122 },+ { 0x03ac, 0x0166 },+ { 0x03b3, 0x0157 },+ { 0x03b5, 0x0129 },+ { 0x03b6, 0x013c },+ { 0x03ba, 0x0113 },+ { 0x03bb, 0x0123 },+ { 0x03bc, 0x0167 },+ { 0x03bd, 0x014a },+ { 0x03bf, 0x014b },+ { 0x03c0, 0x0100 },+ { 0x03c7, 0x012e },+ { 0x03cc, 0x0116 },+ { 0x03cf, 0x012a },+ { 0x03d1, 0x0145 },+ { 0x03d2, 0x014c },+ { 0x03d3, 0x0136 },+ { 0x03d9, 0x0172 },+ { 0x03dd, 0x0168 },+ { 0x03de, 0x016a },+ { 0x03e0, 0x0101 },+ { 0x03e7, 0x012f },+ { 0x03ec, 0x0117 },+ { 0x03ef, 0x012b },+ { 0x03f1, 0x0146 },+ { 0x03f2, 0x014d },+ { 0x03f3, 0x0137 },+ { 0x03f9, 0x0173 },+ { 0x03fd, 0x0169 },+ { 0x03fe, 0x016b },+ { 0x047e, 0x203e },+ { 0x04a1, 0x3002 },+ { 0x04a2, 0x300c },+ { 0x04a3, 0x300d },+ { 0x04a4, 0x3001 },+ { 0x04a5, 0x30fb },+ { 0x04a6, 0x30f2 },+ { 0x04a7, 0x30a1 },+ { 0x04a8, 0x30a3 },+ { 0x04a9, 0x30a5 },+ { 0x04aa, 0x30a7 },+ { 0x04ab, 0x30a9 },+ { 0x04ac, 0x30e3 },+ { 0x04ad, 0x30e5 },+ { 0x04ae, 0x30e7 },+ { 0x04af, 0x30c3 },+ { 0x04b0, 0x30fc },+ { 0x04b1, 0x30a2 },+ { 0x04b2, 0x30a4 },+ { 0x04b3, 0x30a6 },+ { 0x04b4, 0x30a8 },+ { 0x04b5, 0x30aa },+ { 0x04b6, 0x30ab },+ { 0x04b7, 0x30ad },+ { 0x04b8, 0x30af },+ { 0x04b9, 0x30b1 },+ { 0x04ba, 0x30b3 },+ { 0x04bb, 0x30b5 },+ { 0x04bc, 0x30b7 },+ { 0x04bd, 0x30b9 },+ { 0x04be, 0x30bb },+ { 0x04bf, 0x30bd },+ { 0x04c0, 0x30bf },+ { 0x04c1, 0x30c1 },+ { 0x04c2, 0x30c4 },+ { 0x04c3, 0x30c6 },+ { 0x04c4, 0x30c8 },+ { 0x04c5, 0x30ca },+ { 0x04c6, 0x30cb },+ { 0x04c7, 0x30cc },+ { 0x04c8, 0x30cd },+ { 0x04c9, 0x30ce },+ { 0x04ca, 0x30cf },+ { 0x04cb, 0x30d2 },+ { 0x04cc, 0x30d5 },+ { 0x04cd, 0x30d8 },+ { 0x04ce, 0x30db },+ { 0x04cf, 0x30de },+ { 0x04d0, 0x30df },+ { 0x04d1, 0x30e0 },+ { 0x04d2, 0x30e1 },+ { 0x04d3, 0x30e2 },+ { 0x04d4, 0x30e4 },+ { 0x04d5, 0x30e6 },+ { 0x04d6, 0x30e8 },+ { 0x04d7, 0x30e9 },+ { 0x04d8, 0x30ea },+ { 0x04d9, 0x30eb },+ { 0x04da, 0x30ec },+ { 0x04db, 0x30ed },+ { 0x04dc, 0x30ef },+ { 0x04dd, 0x30f3 },+ { 0x04de, 0x309b },+ { 0x04df, 0x309c },+ { 0x05ac, 0x060c },+ { 0x05bb, 0x061b },+ { 0x05bf, 0x061f },+ { 0x05c1, 0x0621 },+ { 0x05c2, 0x0622 },+ { 0x05c3, 0x0623 },+ { 0x05c4, 0x0624 },+ { 0x05c5, 0x0625 },+ { 0x05c6, 0x0626 },+ { 0x05c7, 0x0627 },+ { 0x05c8, 0x0628 },+ { 0x05c9, 0x0629 },+ { 0x05ca, 0x062a },+ { 0x05cb, 0x062b },+ { 0x05cc, 0x062c },+ { 0x05cd, 0x062d },+ { 0x05ce, 0x062e },+ { 0x05cf, 0x062f },+ { 0x05d0, 0x0630 },+ { 0x05d1, 0x0631 },+ { 0x05d2, 0x0632 },+ { 0x05d3, 0x0633 },+ { 0x05d4, 0x0634 },+ { 0x05d5, 0x0635 },+ { 0x05d6, 0x0636 },+ { 0x05d7, 0x0637 },+ { 0x05d8, 0x0638 },+ { 0x05d9, 0x0639 },+ { 0x05da, 0x063a },+ { 0x05e0, 0x0640 },+ { 0x05e1, 0x0641 },+ { 0x05e2, 0x0642 },+ { 0x05e3, 0x0643 },+ { 0x05e4, 0x0644 },+ { 0x05e5, 0x0645 },+ { 0x05e6, 0x0646 },+ { 0x05e7, 0x0647 },+ { 0x05e8, 0x0648 },+ { 0x05e9, 0x0649 },+ { 0x05ea, 0x064a },+ { 0x05eb, 0x064b },+ { 0x05ec, 0x064c },+ { 0x05ed, 0x064d },+ { 0x05ee, 0x064e },+ { 0x05ef, 0x064f },+ { 0x05f0, 0x0650 },+ { 0x05f1, 0x0651 },+ { 0x05f2, 0x0652 },+ { 0x06a1, 0x0452 },+ { 0x06a2, 0x0453 },+ { 0x06a3, 0x0451 },+ { 0x06a4, 0x0454 },+ { 0x06a5, 0x0455 },+ { 0x06a6, 0x0456 },+ { 0x06a7, 0x0457 },+ { 0x06a8, 0x0458 },+ { 0x06a9, 0x0459 },+ { 0x06aa, 0x045a },+ { 0x06ab, 0x045b },+ { 0x06ac, 0x045c },+ { 0x06ae, 0x045e },+ { 0x06af, 0x045f },+ { 0x06b0, 0x2116 },+ { 0x06b1, 0x0402 },+ { 0x06b2, 0x0403 },+ { 0x06b3, 0x0401 },+ { 0x06b4, 0x0404 },+ { 0x06b5, 0x0405 },+ { 0x06b6, 0x0406 },+ { 0x06b7, 0x0407 },+ { 0x06b8, 0x0408 },+ { 0x06b9, 0x0409 },+ { 0x06ba, 0x040a },+ { 0x06bb, 0x040b },+ { 0x06bc, 0x040c },+ { 0x06be, 0x040e },+ { 0x06bf, 0x040f },+ { 0x06c0, 0x044e },+ { 0x06c1, 0x0430 },+ { 0x06c2, 0x0431 },+ { 0x06c3, 0x0446 },+ { 0x06c4, 0x0434 },+ { 0x06c5, 0x0435 },+ { 0x06c6, 0x0444 },+ { 0x06c7, 0x0433 },+ { 0x06c8, 0x0445 },+ { 0x06c9, 0x0438 },+ { 0x06ca, 0x0439 },+ { 0x06cb, 0x043a },+ { 0x06cc, 0x043b },+ { 0x06cd, 0x043c },+ { 0x06ce, 0x043d },+ { 0x06cf, 0x043e },+ { 0x06d0, 0x043f },+ { 0x06d1, 0x044f },+ { 0x06d2, 0x0440 },+ { 0x06d3, 0x0441 },+ { 0x06d4, 0x0442 },+ { 0x06d5, 0x0443 },+ { 0x06d6, 0x0436 },+ { 0x06d7, 0x0432 },+ { 0x06d8, 0x044c },+ { 0x06d9, 0x044b },+ { 0x06da, 0x0437 },+ { 0x06db, 0x0448 },+ { 0x06dc, 0x044d },+ { 0x06dd, 0x0449 },+ { 0x06de, 0x0447 },+ { 0x06df, 0x044a },+ { 0x06e0, 0x042e },+ { 0x06e1, 0x0410 },+ { 0x06e2, 0x0411 },+ { 0x06e3, 0x0426 },+ { 0x06e4, 0x0414 },+ { 0x06e5, 0x0415 },+ { 0x06e6, 0x0424 },+ { 0x06e7, 0x0413 },+ { 0x06e8, 0x0425 },+ { 0x06e9, 0x0418 },+ { 0x06ea, 0x0419 },+ { 0x06eb, 0x041a },+ { 0x06ec, 0x041b },+ { 0x06ed, 0x041c },+ { 0x06ee, 0x041d },+ { 0x06ef, 0x041e },+ { 0x06f0, 0x041f },+ { 0x06f1, 0x042f },+ { 0x06f2, 0x0420 },+ { 0x06f3, 0x0421 },+ { 0x06f4, 0x0422 },+ { 0x06f5, 0x0423 },+ { 0x06f6, 0x0416 },+ { 0x06f7, 0x0412 },+ { 0x06f8, 0x042c },+ { 0x06f9, 0x042b },+ { 0x06fa, 0x0417 },+ { 0x06fb, 0x0428 },+ { 0x06fc, 0x042d },+ { 0x06fd, 0x0429 },+ { 0x06fe, 0x0427 },+ { 0x06ff, 0x042a },+ { 0x07a1, 0x0386 },+ { 0x07a2, 0x0388 },+ { 0x07a3, 0x0389 },+ { 0x07a4, 0x038a },+ { 0x07a5, 0x03aa },+ { 0x07a7, 0x038c },+ { 0x07a8, 0x038e },+ { 0x07a9, 0x03ab },+ { 0x07ab, 0x038f },+ { 0x07ae, 0x0385 },+ { 0x07af, 0x2015 },+ { 0x07b1, 0x03ac },+ { 0x07b2, 0x03ad },+ { 0x07b3, 0x03ae },+ { 0x07b4, 0x03af },+ { 0x07b5, 0x03ca },+ { 0x07b6, 0x0390 },+ { 0x07b7, 0x03cc },+ { 0x07b8, 0x03cd },+ { 0x07b9, 0x03cb },+ { 0x07ba, 0x03b0 },+ { 0x07bb, 0x03ce },+ { 0x07c1, 0x0391 },+ { 0x07c2, 0x0392 },+ { 0x07c3, 0x0393 },+ { 0x07c4, 0x0394 },+ { 0x07c5, 0x0395 },+ { 0x07c6, 0x0396 },+ { 0x07c7, 0x0397 },+ { 0x07c8, 0x0398 },+ { 0x07c9, 0x0399 },+ { 0x07ca, 0x039a },+ { 0x07cb, 0x039b },+ { 0x07cc, 0x039c },+ { 0x07cd, 0x039d },+ { 0x07ce, 0x039e },+ { 0x07cf, 0x039f },+ { 0x07d0, 0x03a0 },+ { 0x07d1, 0x03a1 },+ { 0x07d2, 0x03a3 },+ { 0x07d4, 0x03a4 },+ { 0x07d5, 0x03a5 },+ { 0x07d6, 0x03a6 },+ { 0x07d7, 0x03a7 },+ { 0x07d8, 0x03a8 },+ { 0x07d9, 0x03a9 },+ { 0x07e1, 0x03b1 },+ { 0x07e2, 0x03b2 },+ { 0x07e3, 0x03b3 },+ { 0x07e4, 0x03b4 },+ { 0x07e5, 0x03b5 },+ { 0x07e6, 0x03b6 },+ { 0x07e7, 0x03b7 },+ { 0x07e8, 0x03b8 },+ { 0x07e9, 0x03b9 },+ { 0x07ea, 0x03ba },+ { 0x07eb, 0x03bb },+ { 0x07ec, 0x03bc },+ { 0x07ed, 0x03bd },+ { 0x07ee, 0x03be },+ { 0x07ef, 0x03bf },+ { 0x07f0, 0x03c0 },+ { 0x07f1, 0x03c1 },+ { 0x07f2, 0x03c3 },+ { 0x07f3, 0x03c2 },+ { 0x07f4, 0x03c4 },+ { 0x07f5, 0x03c5 },+ { 0x07f6, 0x03c6 },+ { 0x07f7, 0x03c7 },+ { 0x07f8, 0x03c8 },+ { 0x07f9, 0x03c9 },+ { 0x08a1, 0x23b7 },+ { 0x08a2, 0x250c },+ { 0x08a3, 0x2500 },+ { 0x08a4, 0x2320 },+ { 0x08a5, 0x2321 },+ { 0x08a6, 0x2502 },+ { 0x08a7, 0x23a1 },+ { 0x08a8, 0x23a3 },+ { 0x08a9, 0x23a4 },+ { 0x08aa, 0x23a6 },+ { 0x08ab, 0x239b },+ { 0x08ac, 0x239d },+ { 0x08ad, 0x239e },+ { 0x08ae, 0x23a0 },+ { 0x08af, 0x23a8 },+ { 0x08b0, 0x23ac },+ { 0x08bc, 0x2264 },+ { 0x08bd, 0x2260 },+ { 0x08be, 0x2265 },+ { 0x08bf, 0x222b },+ { 0x08c0, 0x2234 },+ { 0x08c1, 0x221d },+ { 0x08c2, 0x221e },+ { 0x08c5, 0x2207 },+ { 0x08c8, 0x223c },+ { 0x08c9, 0x2243 },+ { 0x08cd, 0x21d4 },+ { 0x08ce, 0x21d2 },+ { 0x08cf, 0x2261 },+ { 0x08d6, 0x221a },+ { 0x08da, 0x2282 },+ { 0x08db, 0x2283 },+ { 0x08dc, 0x2229 },+ { 0x08dd, 0x222a },+ { 0x08de, 0x2227 },+ { 0x08df, 0x2228 },+ { 0x08ef, 0x2202 },+ { 0x08f6, 0x0192 },+ { 0x08fb, 0x2190 },+ { 0x08fc, 0x2191 },+ { 0x08fd, 0x2192 },+ { 0x08fe, 0x2193 },+ { 0x09e0, 0x25c6 },+ { 0x09e1, 0x2592 },+ { 0x09e2, 0x2409 },+ { 0x09e3, 0x240c },+ { 0x09e4, 0x240d },+ { 0x09e5, 0x240a },+ { 0x09e8, 0x2424 },+ { 0x09e9, 0x240b },+ { 0x09ea, 0x2518 },+ { 0x09eb, 0x2510 },+ { 0x09ec, 0x250c },+ { 0x09ed, 0x2514 },+ { 0x09ee, 0x253c },+ { 0x09ef, 0x23ba },+ { 0x09f0, 0x23bb },+ { 0x09f1, 0x2500 },+ { 0x09f2, 0x23bc },+ { 0x09f3, 0x23bd },+ { 0x09f4, 0x251c },+ { 0x09f5, 0x2524 },+ { 0x09f6, 0x2534 },+ { 0x09f7, 0x252c },+ { 0x09f8, 0x2502 },+ { 0x0aa1, 0x2003 },+ { 0x0aa2, 0x2002 },+ { 0x0aa3, 0x2004 },+ { 0x0aa4, 0x2005 },+ { 0x0aa5, 0x2007 },+ { 0x0aa6, 0x2008 },+ { 0x0aa7, 0x2009 },+ { 0x0aa8, 0x200a },+ { 0x0aa9, 0x2014 },+ { 0x0aaa, 0x2013 },+ { 0x0aae, 0x2026 },+ { 0x0aaf, 0x2025 },+ { 0x0ab0, 0x2153 },+ { 0x0ab1, 0x2154 },+ { 0x0ab2, 0x2155 },+ { 0x0ab3, 0x2156 },+ { 0x0ab4, 0x2157 },+ { 0x0ab5, 0x2158 },+ { 0x0ab6, 0x2159 },+ { 0x0ab7, 0x215a },+ { 0x0ab8, 0x2105 },+ { 0x0abb, 0x2012 },+ { 0x0abc, 0x2329 },+ { 0x0abe, 0x232a },+ { 0x0ac3, 0x215b },+ { 0x0ac4, 0x215c },+ { 0x0ac5, 0x215d },+ { 0x0ac6, 0x215e },+ { 0x0ac9, 0x2122 },+ { 0x0aca, 0x2613 },+ { 0x0acc, 0x25c1 },+ { 0x0acd, 0x25b7 },+ { 0x0ace, 0x25cb },+ { 0x0acf, 0x25af },+ { 0x0ad0, 0x2018 },+ { 0x0ad1, 0x2019 },+ { 0x0ad2, 0x201c },+ { 0x0ad3, 0x201d },+ { 0x0ad4, 0x211e },+ { 0x0ad6, 0x2032 },+ { 0x0ad7, 0x2033 },+ { 0x0ad9, 0x271d },+ { 0x0adb, 0x25ac },+ { 0x0adc, 0x25c0 },+ { 0x0add, 0x25b6 },+ { 0x0ade, 0x25cf },+ { 0x0adf, 0x25ae },+ { 0x0ae0, 0x25e6 },+ { 0x0ae1, 0x25ab },+ { 0x0ae2, 0x25ad },+ { 0x0ae3, 0x25b3 },+ { 0x0ae4, 0x25bd },+ { 0x0ae5, 0x2606 },+ { 0x0ae6, 0x2022 },+ { 0x0ae7, 0x25aa },+ { 0x0ae8, 0x25b2 },+ { 0x0ae9, 0x25bc },+ { 0x0aea, 0x261c },+ { 0x0aeb, 0x261e },+ { 0x0aec, 0x2663 },+ { 0x0aed, 0x2666 },+ { 0x0aee, 0x2665 },+ { 0x0af0, 0x2720 },+ { 0x0af1, 0x2020 },+ { 0x0af2, 0x2021 },+ { 0x0af3, 0x2713 },+ { 0x0af4, 0x2717 },+ { 0x0af5, 0x266f },+ { 0x0af6, 0x266d },+ { 0x0af7, 0x2642 },+ { 0x0af8, 0x2640 },+ { 0x0af9, 0x260e },+ { 0x0afa, 0x2315 },+ { 0x0afb, 0x2117 },+ { 0x0afc, 0x2038 },+ { 0x0afd, 0x201a },+ { 0x0afe, 0x201e },+ { 0x0ba3, 0x003c },+ { 0x0ba6, 0x003e },+ { 0x0ba8, 0x2228 },+ { 0x0ba9, 0x2227 },+ { 0x0bc0, 0x00af },+ { 0x0bc2, 0x22a5 },+ { 0x0bc3, 0x2229 },+ { 0x0bc4, 0x230a },+ { 0x0bc6, 0x005f },+ { 0x0bca, 0x2218 },+ { 0x0bcc, 0x2395 },+ { 0x0bce, 0x22a4 },+ { 0x0bcf, 0x25cb },+ { 0x0bd3, 0x2308 },+ { 0x0bd6, 0x222a },+ { 0x0bd8, 0x2283 },+ { 0x0bda, 0x2282 },+ { 0x0bdc, 0x22a2 },+ { 0x0bfc, 0x22a3 },+ { 0x0cdf, 0x2017 },+ { 0x0ce0, 0x05d0 },+ { 0x0ce1, 0x05d1 },+ { 0x0ce2, 0x05d2 },+ { 0x0ce3, 0x05d3 },+ { 0x0ce4, 0x05d4 },+ { 0x0ce5, 0x05d5 },+ { 0x0ce6, 0x05d6 },+ { 0x0ce7, 0x05d7 },+ { 0x0ce8, 0x05d8 },+ { 0x0ce9, 0x05d9 },+ { 0x0cea, 0x05da },+ { 0x0ceb, 0x05db },+ { 0x0cec, 0x05dc },+ { 0x0ced, 0x05dd },+ { 0x0cee, 0x05de },+ { 0x0cef, 0x05df },+ { 0x0cf0, 0x05e0 },+ { 0x0cf1, 0x05e1 },+ { 0x0cf2, 0x05e2 },+ { 0x0cf3, 0x05e3 },+ { 0x0cf4, 0x05e4 },+ { 0x0cf5, 0x05e5 },+ { 0x0cf6, 0x05e6 },+ { 0x0cf7, 0x05e7 },+ { 0x0cf8, 0x05e8 },+ { 0x0cf9, 0x05e9 },+ { 0x0cfa, 0x05ea },+ { 0x0da1, 0x0e01 },+ { 0x0da2, 0x0e02 },+ { 0x0da3, 0x0e03 },+ { 0x0da4, 0x0e04 },+ { 0x0da5, 0x0e05 },+ { 0x0da6, 0x0e06 },+ { 0x0da7, 0x0e07 },+ { 0x0da8, 0x0e08 },+ { 0x0da9, 0x0e09 },+ { 0x0daa, 0x0e0a },+ { 0x0dab, 0x0e0b },+ { 0x0dac, 0x0e0c },+ { 0x0dad, 0x0e0d },+ { 0x0dae, 0x0e0e },+ { 0x0daf, 0x0e0f },+ { 0x0db0, 0x0e10 },+ { 0x0db1, 0x0e11 },+ { 0x0db2, 0x0e12 },+ { 0x0db3, 0x0e13 },+ { 0x0db4, 0x0e14 },+ { 0x0db5, 0x0e15 },+ { 0x0db6, 0x0e16 },+ { 0x0db7, 0x0e17 },+ { 0x0db8, 0x0e18 },+ { 0x0db9, 0x0e19 },+ { 0x0dba, 0x0e1a },+ { 0x0dbb, 0x0e1b },+ { 0x0dbc, 0x0e1c },+ { 0x0dbd, 0x0e1d },+ { 0x0dbe, 0x0e1e },+ { 0x0dbf, 0x0e1f },+ { 0x0dc0, 0x0e20 },+ { 0x0dc1, 0x0e21 },+ { 0x0dc2, 0x0e22 },+ { 0x0dc3, 0x0e23 },+ { 0x0dc4, 0x0e24 },+ { 0x0dc5, 0x0e25 },+ { 0x0dc6, 0x0e26 },+ { 0x0dc7, 0x0e27 },+ { 0x0dc8, 0x0e28 },+ { 0x0dc9, 0x0e29 },+ { 0x0dca, 0x0e2a },+ { 0x0dcb, 0x0e2b },+ { 0x0dcc, 0x0e2c },+ { 0x0dcd, 0x0e2d },+ { 0x0dce, 0x0e2e },+ { 0x0dcf, 0x0e2f },+ { 0x0dd0, 0x0e30 },+ { 0x0dd1, 0x0e31 },+ { 0x0dd2, 0x0e32 },+ { 0x0dd3, 0x0e33 },+ { 0x0dd4, 0x0e34 },+ { 0x0dd5, 0x0e35 },+ { 0x0dd6, 0x0e36 },+ { 0x0dd7, 0x0e37 },+ { 0x0dd8, 0x0e38 },+ { 0x0dd9, 0x0e39 },+ { 0x0dda, 0x0e3a },+ { 0x0ddf, 0x0e3f },+ { 0x0de0, 0x0e40 },+ { 0x0de1, 0x0e41 },+ { 0x0de2, 0x0e42 },+ { 0x0de3, 0x0e43 },+ { 0x0de4, 0x0e44 },+ { 0x0de5, 0x0e45 },+ { 0x0de6, 0x0e46 },+ { 0x0de7, 0x0e47 },+ { 0x0de8, 0x0e48 },+ { 0x0de9, 0x0e49 },+ { 0x0dea, 0x0e4a },+ { 0x0deb, 0x0e4b },+ { 0x0dec, 0x0e4c },+ { 0x0ded, 0x0e4d },+ { 0x0df0, 0x0e50 },+ { 0x0df1, 0x0e51 },+ { 0x0df2, 0x0e52 },+ { 0x0df3, 0x0e53 },+ { 0x0df4, 0x0e54 },+ { 0x0df5, 0x0e55 },+ { 0x0df6, 0x0e56 },+ { 0x0df7, 0x0e57 },+ { 0x0df8, 0x0e58 },+ { 0x0df9, 0x0e59 },+ { 0x0ea1, 0x3131 },+ { 0x0ea2, 0x3132 },+ { 0x0ea3, 0x3133 },+ { 0x0ea4, 0x3134 },+ { 0x0ea5, 0x3135 },+ { 0x0ea6, 0x3136 },+ { 0x0ea7, 0x3137 },+ { 0x0ea8, 0x3138 },+ { 0x0ea9, 0x3139 },+ { 0x0eaa, 0x313a },+ { 0x0eab, 0x313b },+ { 0x0eac, 0x313c },+ { 0x0ead, 0x313d },+ { 0x0eae, 0x313e },+ { 0x0eaf, 0x313f },+ { 0x0eb0, 0x3140 },+ { 0x0eb1, 0x3141 },+ { 0x0eb2, 0x3142 },+ { 0x0eb3, 0x3143 },+ { 0x0eb4, 0x3144 },+ { 0x0eb5, 0x3145 },+ { 0x0eb6, 0x3146 },+ { 0x0eb7, 0x3147 },+ { 0x0eb8, 0x3148 },+ { 0x0eb9, 0x3149 },+ { 0x0eba, 0x314a },+ { 0x0ebb, 0x314b },+ { 0x0ebc, 0x314c },+ { 0x0ebd, 0x314d },+ { 0x0ebe, 0x314e },+ { 0x0ebf, 0x314f },+ { 0x0ec0, 0x3150 },+ { 0x0ec1, 0x3151 },+ { 0x0ec2, 0x3152 },+ { 0x0ec3, 0x3153 },+ { 0x0ec4, 0x3154 },+ { 0x0ec5, 0x3155 },+ { 0x0ec6, 0x3156 },+ { 0x0ec7, 0x3157 },+ { 0x0ec8, 0x3158 },+ { 0x0ec9, 0x3159 },+ { 0x0eca, 0x315a },+ { 0x0ecb, 0x315b },+ { 0x0ecc, 0x315c },+ { 0x0ecd, 0x315d },+ { 0x0ece, 0x315e },+ { 0x0ecf, 0x315f },+ { 0x0ed0, 0x3160 },+ { 0x0ed1, 0x3161 },+ { 0x0ed2, 0x3162 },+ { 0x0ed3, 0x3163 },+ { 0x0ed4, 0x11a8 },+ { 0x0ed5, 0x11a9 },+ { 0x0ed6, 0x11aa },+ { 0x0ed7, 0x11ab },+ { 0x0ed8, 0x11ac },+ { 0x0ed9, 0x11ad },+ { 0x0eda, 0x11ae },+ { 0x0edb, 0x11af },+ { 0x0edc, 0x11b0 },+ { 0x0edd, 0x11b1 },+ { 0x0ede, 0x11b2 },+ { 0x0edf, 0x11b3 },+ { 0x0ee0, 0x11b4 },+ { 0x0ee1, 0x11b5 },+ { 0x0ee2, 0x11b6 },+ { 0x0ee3, 0x11b7 },+ { 0x0ee4, 0x11b8 },+ { 0x0ee5, 0x11b9 },+ { 0x0ee6, 0x11ba },+ { 0x0ee7, 0x11bb },+ { 0x0ee8, 0x11bc },+ { 0x0ee9, 0x11bd },+ { 0x0eea, 0x11be },+ { 0x0eeb, 0x11bf },+ { 0x0eec, 0x11c0 },+ { 0x0eed, 0x11c1 },+ { 0x0eee, 0x11c2 },+ { 0x0eef, 0x316d },+ { 0x0ef0, 0x3171 },+ { 0x0ef1, 0x3178 },+ { 0x0ef2, 0x317f },+ { 0x0ef3, 0x3181 },+ { 0x0ef4, 0x3184 },+ { 0x0ef5, 0x3186 },+ { 0x0ef6, 0x318d },+ { 0x0ef7, 0x318e },+ { 0x0ef8, 0x11eb },+ { 0x0ef9, 0x11f0 },+ { 0x0efa, 0x11f9 },+ { 0x0eff, 0x20a9 },+ { 0x13a4, 0x20ac },+ { 0x13bc, 0x0152 },+ { 0x13bd, 0x0153 },+ { 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 }+};+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// _glfwKeySym2Unicode() - Convert X11 KeySym to Unicode+//========================================================================++long _glfwKeySym2Unicode( KeySym keysym )+{+ int min = 0;+ int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;+ int mid;++ /* First check for Latin-1 characters (1:1 mapping) */+ if( (keysym >= 0x0020 && keysym <= 0x007e) ||+ (keysym >= 0x00a0 && keysym <= 0x00ff) )+ { return keysym;+ }++ /* Also check for directly encoded 24-bit UCS characters */+ if( (keysym & 0xff000000) == 0x01000000 )+ {+ return keysym & 0x00ffffff;+ }++ /* Binary search in table */+ while( max >= min )+ {+ mid = (min + max) / 2;+ if( keysymtab[mid].keysym < keysym )+ {+ min = mid + 1;+ }+ else if( keysymtab[mid].keysym > keysym )+ {+ max = mid - 1;+ }+ else+ {+ /* Found it! */+ return keysymtab[mid].ucs;+ }+ }++ /* No matching Unicode value found */+ return -1;+}
+ glfw/lib/x11/x11_thread.c view
@@ -0,0 +1,508 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_thread.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++#ifdef _GLFW_HAS_PTHREAD++//========================================================================+// _glfwNewThread() - This is simply a "wrapper" for calling the user+// thread function.+//========================================================================++void * _glfwNewThread( void * arg )+{+ GLFWthreadfun threadfun;+ _GLFWthread *t;+ pthread_t posixID;++ // Get current thread ID+ posixID = pthread_self();++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Loop through entire list of threads to find the matching POSIX+ // thread ID+ for( t = &_glfwThrd.First; t != NULL; t = t->Next )+ {+ if( t->PosixID == posixID )+ {+ break;+ }+ }+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return NULL;+ }++ // Get user thread function pointer+ threadfun = t->Function;++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Call the user thread function+ threadfun( arg );++ // Remove thread from thread list+ ENTER_THREAD_CRITICAL_SECTION+ _glfwRemoveThread( t );+ LEAVE_THREAD_CRITICAL_SECTION++ // When the thread function returns, the thread will die...+ return NULL;+}++#endif // _GLFW_HAS_PTHREAD++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// _glfwPlatformCreateThread() - Create a new thread+//========================================================================++GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )+{+#ifdef _GLFW_HAS_PTHREAD++ GLFWthread ID;+ _GLFWthread *t;+ int result;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Create a new thread information memory area+ t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );+ if( t == NULL )+ {+ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION+ return -1;+ }++ // Get a new unique thread id+ ID = _glfwThrd.NextID ++;++ // Store thread information in the thread list+ t->Function = fun;+ t->ID = ID;++ // Create thread+ result = pthread_create(+ &t->PosixID, // Thread handle+ NULL, // Default thread attributes+ _glfwNewThread, // Thread function (a wrapper function)+ (void *)arg // Argument to thread is user argument+ );++ // Did the thread creation fail?+ if( result != 0 )+ {+ free( (void *) t );+ LEAVE_THREAD_CRITICAL_SECTION+ return -1;+ }++ // Append thread to thread list+ _glfwAppendThread( t );++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Return the GLFW thread ID+ return ID;++#else++ return -1;++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY+// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME+// SITUATIONS!+//========================================================================++void _glfwPlatformDestroyThread( GLFWthread ID )+{+#ifdef _GLFW_HAS_PTHREAD++ _GLFWthread *t;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Get thread information pointer+ t = _glfwGetThreadPointer( ID );+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return;+ }++ // Simply murder the process, no mercy!+ pthread_kill( t->PosixID, SIGKILL );++ // Remove thread from thread list+ _glfwRemoveThread( t );++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformWaitThread() - Wait for a thread to die+//========================================================================++int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )+{+#ifdef _GLFW_HAS_PTHREAD++ pthread_t thread;+ _GLFWthread *t;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Get thread information pointer+ t = _glfwGetThreadPointer( ID );++ // Is the thread already dead?+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return GL_TRUE;+ }++ // If got this far, the thread is alive => polling returns FALSE+ if( waitmode == GLFW_NOWAIT )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return GL_FALSE;+ }++ // Get thread handle+ thread = t->PosixID;++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Wait for thread to die+ (void) pthread_join( thread, NULL );++ return GL_TRUE;++#else++ return GL_TRUE;++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformGetThreadID() - Return the thread ID for the current+// thread+//========================================================================++GLFWthread _glfwPlatformGetThreadID( void )+{+#ifdef _GLFW_HAS_PTHREAD++ _GLFWthread *t;+ GLFWthread ID = -1;+ pthread_t posixID;++ // Get current thread ID+ posixID = pthread_self();++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Loop through entire list of threads to find the matching POSIX+ // thread ID+ for( t = &_glfwThrd.First; t != NULL; t = t->Next )+ {+ if( t->PosixID == posixID )+ {+ ID = t->ID;+ break;+ }+ }++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Return the found GLFW thread identifier+ return ID;++#else++ return 0;++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformCreateMutex() - Create a mutual exclusion object+//========================================================================++GLFWmutex _glfwPlatformCreateMutex( void )+{+#ifdef _GLFW_HAS_PTHREAD++ pthread_mutex_t *mutex;++ // Allocate memory for mutex+ mutex = (pthread_mutex_t *) malloc( sizeof( pthread_mutex_t ) );+ if( !mutex )+ {+ return NULL;+ }++ // Initialise a mutex object+ (void) pthread_mutex_init( mutex, NULL );++ // Cast to GLFWmutex and return+ return (GLFWmutex) mutex;++#else++ return (GLFWmutex) 0;++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object+//========================================================================++void _glfwPlatformDestroyMutex( GLFWmutex mutex )+{+#ifdef _GLFW_HAS_PTHREAD++ // Destroy the mutex object+ pthread_mutex_destroy( (pthread_mutex_t *) mutex );++ // Free memory for mutex object+ free( (void *) mutex );++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformLockMutex() - Request access to a mutex+//========================================================================++void _glfwPlatformLockMutex( GLFWmutex mutex )+{+#ifdef _GLFW_HAS_PTHREAD++ // Wait for mutex to be released+ (void) pthread_mutex_lock( (pthread_mutex_t *) mutex );++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformUnlockMutex() - Release a mutex+//========================================================================++void _glfwPlatformUnlockMutex( GLFWmutex mutex )+{+#ifdef _GLFW_HAS_PTHREAD++ // Release mutex+ pthread_mutex_unlock( (pthread_mutex_t *) mutex );++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformCreateCond() - Create a new condition variable object+//========================================================================++GLFWcond _glfwPlatformCreateCond( void )+{+#ifdef _GLFW_HAS_PTHREAD++ pthread_cond_t *cond;++ // Allocate memory for condition variable+ cond = (pthread_cond_t *) malloc( sizeof(pthread_cond_t) );+ if( !cond )+ {+ return NULL;+ }++ // Initialise condition variable+ (void) pthread_cond_init( cond, NULL );++ // Cast to GLFWcond and return+ return (GLFWcond) cond;++#else++ return (GLFWcond) 0;++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformDestroyCond() - Destroy a condition variable object+//========================================================================++void _glfwPlatformDestroyCond( GLFWcond cond )+{+#ifdef _GLFW_HAS_PTHREAD++ // Destroy the condition variable object+ (void) pthread_cond_destroy( (pthread_cond_t *) cond );++ // Free memory for condition variable object+ free( (void *) cond );++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformWaitCond() - Wait for a condition to be raised+//========================================================================++void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,+ double timeout )+{+#ifdef _GLFW_HAS_PTHREAD++ struct timeval currenttime;+ struct timespec wait;+ long dt_sec, dt_usec;++ // Select infinite or timed wait+ if( timeout >= GLFW_INFINITY )+ {+ // Wait for condition (infinite wait)+ (void) pthread_cond_wait( (pthread_cond_t *) cond,+ (pthread_mutex_t *) mutex );+ }+ else+ {+ // Set timeout time, relatvie to current time+ gettimeofday( ¤ttime, NULL );+ dt_sec = (long) timeout;+ dt_usec = (long) ((timeout - (double)dt_sec) * 1000000.0);+ wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;+ if( wait.tv_nsec > 1000000000L )+ {+ wait.tv_nsec -= 1000000000L;+ dt_sec ++;+ }+ wait.tv_sec = currenttime.tv_sec + dt_sec;++ // Wait for condition (timed wait)+ (void) pthread_cond_timedwait( (pthread_cond_t *) cond,+ (pthread_mutex_t *) mutex, &wait );+ }++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformSignalCond() - Signal a condition to one waiting thread+//========================================================================++void _glfwPlatformSignalCond( GLFWcond cond )+{+#ifdef _GLFW_HAS_PTHREAD++ // Signal condition+ (void) pthread_cond_signal( (pthread_cond_t *) cond );++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting+// threads+//========================================================================++void _glfwPlatformBroadcastCond( GLFWcond cond )+{+#ifdef _GLFW_HAS_PTHREAD++ // Broadcast condition+ (void) pthread_cond_broadcast( (pthread_cond_t *) cond );++#endif // _GLFW_HAS_PTHREAD+}+++//========================================================================+// _glfwPlatformGetNumberOfProcessors() - Return the number of processors+// in the system.+//========================================================================++int _glfwPlatformGetNumberOfProcessors( void )+{+ int n;++ // Get number of processors online+ _glfw_numprocessors( n );+ return n;+}+
+ glfw/lib/x11/x11_time.c view
@@ -0,0 +1,154 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_time.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++//========================================================================+// Initialise timer+//========================================================================++void _glfwInitTimer( void )+{+ struct timeval tv;++ // "Resolution" is 1 us+ _glfwLibrary.Timer.resolution = 1e-6;++ // Set start-time for timer+ gettimeofday( &tv, NULL );+ _glfwLibrary.Timer.t0 = (long long) tv.tv_sec * (long long) 1000000 ++ (long long) tv.tv_usec;+}+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Return timer value in seconds+//========================================================================++double _glfwPlatformGetTime( void )+{+ long long t;+ struct timeval tv;++ gettimeofday( &tv, NULL );+ t = (long long) tv.tv_sec * (long long) 1000000 ++ (long long) tv.tv_usec;++ return (double)(t - _glfwLibrary.Timer.t0) * _glfwLibrary.Timer.resolution;+}+++//========================================================================+// Set timer value in seconds+//========================================================================++void _glfwPlatformSetTime( double t )+{+ long long t0;+ struct timeval tv;++ gettimeofday( &tv, NULL );+ t0 = (long long) tv.tv_sec * (long long) 1000000 ++ (long long) tv.tv_usec;++ // Calulate new starting time+ _glfwLibrary.Timer.t0 = t0 - (long long)(t/_glfwLibrary.Timer.resolution);+}+++//========================================================================+// Put a thread to sleep for a specified amount of time+//========================================================================++void _glfwPlatformSleep( double time )+{+#ifdef _GLFW_HAS_PTHREAD++ if( time == 0.0 )+ {+#ifdef _GLFW_HAS_SCHED_YIELD+ sched_yield();+#endif+ return;+ }++ struct timeval currenttime;+ struct timespec wait;+ pthread_mutex_t mutex;+ pthread_cond_t cond;+ long dt_sec, dt_usec;++ // Not all pthread implementations have a pthread_sleep() function. We+ // do it the portable way, using a timed wait for a condition that we+ // will never signal. NOTE: The unistd functions sleep/usleep suspends+ // the entire PROCESS, not a signle thread, which is why we can not+ // use them to implement glfwSleep.++ // Set timeout time, relatvie to current time+ gettimeofday( ¤ttime, NULL );+ dt_sec = (long) time;+ dt_usec = (long) ((time - (double)dt_sec) * 1000000.0);+ wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;+ if( wait.tv_nsec > 1000000000L )+ {+ wait.tv_nsec -= 1000000000L;+ dt_sec++;+ }+ wait.tv_sec = currenttime.tv_sec + dt_sec;++ // Initialize condition and mutex objects+ pthread_mutex_init( &mutex, NULL );+ pthread_cond_init( &cond, NULL );++ // Do a timed wait+ pthread_mutex_lock( &mutex );+ pthread_cond_timedwait( &cond, &mutex, &wait );+ pthread_mutex_unlock( &mutex );++ // Destroy condition and mutex objects+ pthread_mutex_destroy( &mutex );+ pthread_cond_destroy( &cond );++#else++ // For systems without PTHREAD, use unistd usleep+ if( time > 0 )+ {+ usleep( (unsigned int) (time*1000000) );+ }++#endif // _GLFW_HAS_PTHREAD+}+
+ glfw/lib/x11/x11_window.c view
@@ -0,0 +1,1993 @@+//========================================================================+// GLFW - An OpenGL framework+// File: x11_window.c+// Platform: X11 (Unix)+// API version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"+++/* KDE decoration values */+enum {+ KDE_noDecoration = 0,+ KDE_normalDecoration = 1,+ KDE_tinyDecoration = 2,+ KDE_noFocus = 256,+ KDE_standaloneMenuBar = 512,+ KDE_desktopIcon = 1024 ,+ KDE_staysOnTop = 2048+};+++/* Define GLX 1.4 FSAA tokens if not already defined */+#ifndef GLX_VERSION_1_4++#define GLX_SAMPLE_BUFFERS 100000+#define GLX_SAMPLES 100001++#endif /*GLX_VERSION_1_4*/++++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// Checks whether the event is a MapNotify for the specified window+//========================================================================++static Bool isMapNotify( Display *d, XEvent *e, char *arg )+{+ return (e->type == MapNotify) && (e->xmap.window == (Window)arg);+}+++//========================================================================+// Turn off window decorations+// Based on xawdecode: src/wmhooks.c+//========================================================================++#define MWM_HINTS_DECORATIONS (1L << 1)++static void disableDecorations( void )+{+ GLboolean removedDecorations;+ Atom hintAtom;+ XSetWindowAttributes attributes;++ removedDecorations = GL_FALSE;++ // First try to set MWM hints+ hintAtom = XInternAtom( _glfwLibrary.display, "_MOTIF_WM_HINTS", True );+ if ( hintAtom != None )+ {+ struct {+ unsigned long flags;+ unsigned long functions;+ unsigned long decorations;+ long input_mode;+ unsigned long status;+ } MWMHints = { MWM_HINTS_DECORATIONS, 0, 0, 0, 0 };++ XChangeProperty( _glfwLibrary.display, _glfwWin.window, hintAtom, hintAtom,+ 32, PropModeReplace, (unsigned char *)&MWMHints,+ sizeof(MWMHints) / 4 );+ removedDecorations = GL_TRUE;+ }++ // Now try to set KWM hints+ hintAtom = XInternAtom( _glfwLibrary.display, "KWM_WIN_DECORATION", True );+ if ( hintAtom != None )+ {+ long KWMHints = KDE_tinyDecoration;++ XChangeProperty( _glfwLibrary.display, _glfwWin.window, hintAtom, hintAtom,+ 32, PropModeReplace, (unsigned char *)&KWMHints,+ sizeof(KWMHints) / 4 );+ removedDecorations = GL_TRUE;+ }++ // Now try to set GNOME hints+ hintAtom = XInternAtom( _glfwLibrary.display, "_WIN_HINTS", True );+ if ( hintAtom != None )+ {+ long GNOMEHints = 0;++ XChangeProperty( _glfwLibrary.display, _glfwWin.window, hintAtom, hintAtom,+ 32, PropModeReplace, (unsigned char *)&GNOMEHints,+ sizeof(GNOMEHints) / 4 );+ removedDecorations = GL_TRUE;+ }++ // Now try to set KDE NET_WM hints+ hintAtom = XInternAtom( _glfwLibrary.display, "_NET_WM_WINDOW_TYPE", True );+ if ( hintAtom != None )+ {+ Atom NET_WMHints[2];++ NET_WMHints[0] = XInternAtom( _glfwLibrary.display,+ "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE",+ True );+ /* define a fallback... */+ NET_WMHints[1] = XInternAtom( _glfwLibrary.display,+ "_NET_WM_WINDOW_TYPE_NORMAL",+ True );++ XChangeProperty( _glfwLibrary.display, _glfwWin.window, hintAtom, XA_ATOM,+ 32, PropModeReplace, (unsigned char *)&NET_WMHints,+ 2 );+ removedDecorations = GL_TRUE;+ }++ // Set ICCCM fullscreen WM hint+ hintAtom = XInternAtom( _glfwLibrary.display, "_NET_WM_STATE", True );+ if ( hintAtom != None )+ {+ Atom NET_WMHints[1];++ NET_WMHints[0] = XInternAtom( _glfwLibrary.display,+ "_NET_WM_STATE_FULLSCREEN",+ True );++ XChangeProperty( _glfwLibrary.display, _glfwWin.window, hintAtom, XA_ATOM,+ 32, PropModeReplace, (unsigned char *)&NET_WMHints, 1 );+ }++ // Did we sucessfully remove the window decorations?+ if( removedDecorations )+ {+ // Finally set the transient hints+ XSetTransientForHint( _glfwLibrary.display,+ _glfwWin.window,+ RootWindow( _glfwLibrary.display, _glfwWin.screen) );+ XUnmapWindow( _glfwLibrary.display, _glfwWin.window );+ XMapWindow( _glfwLibrary.display, _glfwWin.window );+ }+ else+ {+ // The Butcher way of removing window decorations+ attributes.override_redirect = True;+ XChangeWindowAttributes( _glfwLibrary.display,+ _glfwWin.window,+ CWOverrideRedirect,+ &attributes );+ _glfwWin.overrideRedirect = GL_TRUE;+ }+}+++//========================================================================+// Turn on window decorations+//========================================================================++static void enableDecorations( void )+{+ GLboolean activatedDecorations;+ Atom hintAtom;++ // If this is an override redirect window, skip it...+ if( _glfwWin.overrideRedirect )+ {+ return;+ }++ activatedDecorations = 0;++ // First try to unset MWM hints+ hintAtom = XInternAtom( _glfwLibrary.display, "_MOTIF_WM_HINTS", True );+ if ( hintAtom != None )+ {+ XDeleteProperty( _glfwLibrary.display, _glfwWin.window, hintAtom );+ activatedDecorations = GL_TRUE;+ }++ // Now try to unset KWM hints+ hintAtom = XInternAtom( _glfwLibrary.display, "KWM_WIN_DECORATION", True );+ if ( hintAtom != None )+ {+ XDeleteProperty( _glfwLibrary.display, _glfwWin.window, hintAtom );+ activatedDecorations = GL_TRUE;+ }++ // Now try to unset GNOME hints+ hintAtom = XInternAtom( _glfwLibrary.display, "_WIN_HINTS", True );+ if ( hintAtom != None )+ {+ XDeleteProperty( _glfwLibrary.display, _glfwWin.window, hintAtom );+ activatedDecorations = GL_TRUE;+ }++ // Now try to unset NET_WM hints+ hintAtom = XInternAtom( _glfwLibrary.display, "_NET_WM_WINDOW_TYPE", True );+ if ( hintAtom != None )+ {+ Atom NET_WMHints = XInternAtom( _glfwLibrary.display,+ "_NET_WM_WINDOW_TYPE_NORMAL",+ True);+ if( NET_WMHints != None )+ {+ XChangeProperty( _glfwLibrary.display, _glfwWin.window,+ hintAtom, XA_ATOM, 32, PropModeReplace,+ (unsigned char *)&NET_WMHints, 1 );+ activatedDecorations = GL_TRUE;+ }+ }++ // Finally unset the transient hints if necessary+ if( activatedDecorations )+ {+ // NOTE: Does this work?+ XSetTransientForHint( _glfwLibrary.display, _glfwWin.window, None );+ XUnmapWindow( _glfwLibrary.display, _glfwWin.window );+ XMapWindow( _glfwLibrary.display, _glfwWin.window );+ }+}+++//========================================================================+// Translates an X Window key to internal coding+//========================================================================++static int translateKey( int keycode )+{+ KeySym key, key_lc, key_uc;++ // Try secondary keysym, for numeric keypad keys+ // Note: This way we always force "NumLock = ON", which at least+ // enables GLFW users to detect numeric keypad keys+ key = XKeycodeToKeysym( _glfwLibrary.display, keycode, 1 );+ switch( key )+ {+ // Numeric keypad+ case XK_KP_0: return GLFW_KEY_KP_0;+ case XK_KP_1: return GLFW_KEY_KP_1;+ case XK_KP_2: return GLFW_KEY_KP_2;+ case XK_KP_3: return GLFW_KEY_KP_3;+ case XK_KP_4: return GLFW_KEY_KP_4;+ case XK_KP_5: return GLFW_KEY_KP_5;+ case XK_KP_6: return GLFW_KEY_KP_6;+ case XK_KP_7: return GLFW_KEY_KP_7;+ case XK_KP_8: return GLFW_KEY_KP_8;+ case XK_KP_9: return GLFW_KEY_KP_9;+ case XK_KP_Separator:+ case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL;+ case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;+ case XK_KP_Enter: return GLFW_KEY_KP_ENTER;+ default: break;+ }++ // Now try pimary keysym+ key = XKeycodeToKeysym( _glfwLibrary.display, keycode, 0 );+ switch( key )+ {+ // Special keys (non character keys)+ case XK_Escape: return GLFW_KEY_ESC;+ case XK_Tab: return GLFW_KEY_TAB;+ case XK_Shift_L: return GLFW_KEY_LSHIFT;+ case XK_Shift_R: return GLFW_KEY_RSHIFT;+ case XK_Control_L: return GLFW_KEY_LCTRL;+ case XK_Control_R: return GLFW_KEY_RCTRL;+ case XK_Meta_L:+ case XK_Alt_L: return GLFW_KEY_LALT;+ case XK_Mode_switch: // Mapped to Alt_R on many keyboards+ case XK_Meta_R:+ case XK_ISO_Level3_Shift: // AltGr on at least some machines+ case XK_Alt_R: return GLFW_KEY_RALT;+ case XK_Super_L: return GLFW_KEY_LSUPER;+ case XK_Super_R: return GLFW_KEY_RSUPER;+ case XK_Menu: return GLFW_KEY_MENU;+ case XK_Num_Lock: return GLFW_KEY_KP_NUM_LOCK;+ case XK_Caps_Lock: return GLFW_KEY_CAPS_LOCK;+ case XK_Scroll_Lock: return GLFW_KEY_SCROLL_LOCK;+ case XK_Pause: return GLFW_KEY_PAUSE;+ case XK_KP_Delete:+ case XK_Delete: return GLFW_KEY_DEL;+ case XK_BackSpace: return GLFW_KEY_BACKSPACE;+ case XK_Return: return GLFW_KEY_ENTER;+ case XK_KP_Home:+ case XK_Home: return GLFW_KEY_HOME;+ case XK_KP_End:+ case XK_End: return GLFW_KEY_END;+ case XK_KP_Page_Up:+ case XK_Page_Up: return GLFW_KEY_PAGEUP;+ case XK_KP_Page_Down:+ case XK_Page_Down: return GLFW_KEY_PAGEDOWN;+ case XK_KP_Insert:+ case XK_Insert: return GLFW_KEY_INSERT;+ case XK_KP_Left:+ case XK_Left: return GLFW_KEY_LEFT;+ case XK_KP_Right:+ case XK_Right: return GLFW_KEY_RIGHT;+ case XK_KP_Down:+ case XK_Down: return GLFW_KEY_DOWN;+ case XK_KP_Up:+ case XK_Up: return GLFW_KEY_UP;+ case XK_F1: return GLFW_KEY_F1;+ case XK_F2: return GLFW_KEY_F2;+ case XK_F3: return GLFW_KEY_F3;+ case XK_F4: return GLFW_KEY_F4;+ case XK_F5: return GLFW_KEY_F5;+ case XK_F6: return GLFW_KEY_F6;+ case XK_F7: return GLFW_KEY_F7;+ case XK_F8: return GLFW_KEY_F8;+ case XK_F9: return GLFW_KEY_F9;+ case XK_F10: return GLFW_KEY_F10;+ case XK_F11: return GLFW_KEY_F11;+ case XK_F12: return GLFW_KEY_F12;+ case XK_F13: return GLFW_KEY_F13;+ case XK_F14: return GLFW_KEY_F14;+ case XK_F15: return GLFW_KEY_F15;+ case XK_F16: return GLFW_KEY_F16;+ case XK_F17: return GLFW_KEY_F17;+ case XK_F18: return GLFW_KEY_F18;+ case XK_F19: return GLFW_KEY_F19;+ case XK_F20: return GLFW_KEY_F20;+ case XK_F21: return GLFW_KEY_F21;+ case XK_F22: return GLFW_KEY_F22;+ case XK_F23: return GLFW_KEY_F23;+ case XK_F24: return GLFW_KEY_F24;+ case XK_F25: return GLFW_KEY_F25;++ // Numeric keypad (should have been detected in secondary keysym!)+ case XK_KP_Divide: return GLFW_KEY_KP_DIVIDE;+ case XK_KP_Multiply: return GLFW_KEY_KP_MULTIPLY;+ case XK_KP_Subtract: return GLFW_KEY_KP_SUBTRACT;+ case XK_KP_Add: return GLFW_KEY_KP_ADD;+ case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;+ case XK_KP_Enter: return GLFW_KEY_KP_ENTER;++ // The rest (should be printable keys)+ default:+ // Make uppercase+ XConvertCase( key, &key_lc, &key_uc );+ key = key_uc;++ // Valid ISO 8859-1 character?+ if( (key >= 32 && key <= 126) ||+ (key >= 160 && key <= 255) )+ {+ return (int) key;+ }+ return GLFW_KEY_UNKNOWN;+ }+}+++//========================================================================+// Translates an X Window event to Unicode+//========================================================================++static int translateChar( XKeyEvent *event )+{+ KeySym keysym;++ // Get X11 keysym+ XLookupString( event, NULL, 0, &keysym, NULL );++ // Convert to Unicode (see x11_keysym2unicode.c)+ return (int) _glfwKeySym2Unicode( keysym );+}++++//========================================================================+// Get next X event (called by glfwPollEvents)+//========================================================================++static int getNextEvent( void )+{+ XEvent event, next_event;++ // Pull next event from event queue+ XNextEvent( _glfwLibrary.display, &event );++ // Handle certain window messages+ switch( event.type )+ {+ // Is a key being pressed?+ case KeyPress:+ {+ // Translate and report key press+ _glfwInputKey( translateKey( event.xkey.keycode ), GLFW_PRESS );++ // Translate and report character input+ if( _glfwWin.charCallback )+ {+ _glfwInputChar( translateChar( &event.xkey ), GLFW_PRESS );+ }+ break;+ }++ // Is a key being released?+ case KeyRelease:+ {+ // Do not report key releases for key repeats. For key repeats+ // we will get KeyRelease/KeyPress pairs with identical time+ // stamps. User selected key repeat filtering is handled in+ // _glfwInputKey()/_glfwInputChar().+ if( XEventsQueued( _glfwLibrary.display, QueuedAfterReading ) )+ {+ XPeekEvent( _glfwLibrary.display, &next_event );+ if( next_event.type == KeyPress &&+ next_event.xkey.window == event.xkey.window &&+ next_event.xkey.keycode == event.xkey.keycode )+ {+ // This last check is a hack to work around key repeats+ // leaking through due to some sort of time drift+ // 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_event.xkey.time - event.xkey.time ) < 20 )+ {+ // Do not report anything for this event+ break;+ }+ }+ }++ // Translate and report key release+ _glfwInputKey( translateKey( event.xkey.keycode ), GLFW_RELEASE );++ // Translate and report character input+ if( _glfwWin.charCallback )+ {+ _glfwInputChar( translateChar( &event.xkey ), GLFW_RELEASE );+ }+ break;+ }++ // Were any of the mouse-buttons pressed?+ case ButtonPress:+ {+ if( event.xbutton.button == Button1 )+ {+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );+ }+ else if( event.xbutton.button == Button2 )+ {+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS );+ }+ else if( event.xbutton.button == Button3 )+ {+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );+ }++ // XFree86 3.3.2 and later translates mouse wheel up/down into+ // mouse button 4 & 5 presses+ else if( event.xbutton.button == Button4 )+ {+ _glfwInput.WheelPos++; // To verify: is this up or down?+ if( _glfwWin.mouseWheelCallback )+ {+ _glfwWin.mouseWheelCallback( _glfwInput.WheelPos );+ }+ }+ else if( event.xbutton.button == Button5 )+ {+ _glfwInput.WheelPos--;+ if( _glfwWin.mouseWheelCallback )+ {+ _glfwWin.mouseWheelCallback( _glfwInput.WheelPos );+ }+ }+ break;+ }++ // Were any of the mouse-buttons released?+ case ButtonRelease:+ {+ if( event.xbutton.button == Button1 )+ {+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT,+ GLFW_RELEASE );+ }+ else if( event.xbutton.button == Button2 )+ {+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE,+ GLFW_RELEASE );+ }+ else if( event.xbutton.button == Button3 )+ {+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT,+ GLFW_RELEASE );+ }+ break;+ }++ // Was the mouse moved?+ case MotionNotify:+ {+ if( event.xmotion.x != _glfwInput.CursorPosX ||+ event.xmotion.y != _glfwInput.CursorPosY )+ {+ if( _glfwWin.mouseLock )+ {+ _glfwInput.MousePosX += event.xmotion.x -+ _glfwInput.CursorPosX;+ _glfwInput.MousePosY += event.xmotion.y -+ _glfwInput.CursorPosY;+ }+ else+ {+ _glfwInput.MousePosX = event.xmotion.x;+ _glfwInput.MousePosY = event.xmotion.y;+ }+ _glfwInput.CursorPosX = event.xmotion.x;+ _glfwInput.CursorPosY = event.xmotion.y;+ _glfwInput.MouseMoved = GL_TRUE;++ // Call user callback function+ if( _glfwWin.mousePosCallback )+ {+ _glfwWin.mousePosCallback( _glfwInput.MousePosX,+ _glfwInput.MousePosY );+ }+ }+ break;+ }++ // Was the window resized?+ case ConfigureNotify:+ {+ if( event.xconfigure.width != _glfwWin.width ||+ event.xconfigure.height != _glfwWin.height )+ {+ _glfwWin.width = event.xconfigure.width;+ _glfwWin.height = event.xconfigure.height;+ if( _glfwWin.windowSizeCallback )+ {+ _glfwWin.windowSizeCallback( _glfwWin.width,+ _glfwWin.height );+ }+ }+ break;+ }++ // Was the window closed by the window manager?+ case ClientMessage:+ {+ if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.WMDeleteWindow )+ {+ return GL_TRUE;+ }++ if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.WMPing )+ {+ XSendEvent( _glfwLibrary.display,+ RootWindow( _glfwLibrary.display, _glfwWin.screen ),+ False, SubstructureNotifyMask | SubstructureRedirectMask, &event );+ }+ break;+ }++ // Was the window mapped (un-iconified)?+ case MapNotify:+ _glfwWin.mapNotifyCount++;+ break;++ // Was the window unmapped (iconified)?+ case UnmapNotify:+ _glfwWin.mapNotifyCount--;+ break;++ // Was the window activated?+ case FocusIn:+ _glfwWin.focusInCount++;+ break;++ // Was the window de-activated?+ case FocusOut:+ _glfwWin.focusInCount--;+ break;++ // Was the window contents damaged?+ case Expose:+ {+ // Call user callback function+ if( _glfwWin.windowRefreshCallback )+ {+ _glfwWin.windowRefreshCallback();+ }+ break;+ }++ // Was the window destroyed?+ case DestroyNotify:+ return GL_FALSE;++ default:+ {+#if defined( _GLFW_HAS_XRANDR )+ switch( event.type - _glfwLibrary.XRandR.eventBase )+ {+ case RRScreenChangeNotify:+ {+ // Show XRandR that we really care+ XRRUpdateConfiguration( &event );+ break;+ }+ }+#endif+ break;+ }+ }++ // The window was not destroyed+ return GL_FALSE;+}+++//========================================================================+// Create a blank cursor (for locked mouse mode)+//========================================================================++static Cursor createNULLCursor( Display *display, Window root )+{+ Pixmap cursormask;+ XGCValues xgc;+ GC gc;+ XColor col;+ Cursor cursor;++ cursormask = XCreatePixmap( display, root, 1, 1, 1 );+ xgc.function = GXclear;+ gc = XCreateGC( display, cursormask, GCFunction, &xgc );+ XFillRectangle( display, cursormask, gc, 0, 0, 1, 1 );+ col.pixel = 0;+ col.red = 0;+ col.flags = 4;+ cursor = XCreatePixmapCursor( display, cursormask, cursormask,+ &col,&col, 0,0 );+ XFreePixmap( display, cursormask );+ XFreeGC( display, gc );++ return cursor;+}+++//========================================================================+// Returns the specified attribute of the specified GLXFBConfig+// NOTE: Do not call this unless we have found GLX 1.3 or GLX_SGIX_fbconfig+//========================================================================++static int getFBConfigAttrib( GLXFBConfig fbconfig, int attrib )+{+ int value;++ if( _glfwWin.has_GLX_SGIX_fbconfig )+ {+ _glfwWin.GetFBConfigAttribSGIX( _glfwLibrary.display, fbconfig, attrib, &value );+ }+ else+ {+ glXGetFBConfigAttrib( _glfwLibrary.display, fbconfig, attrib, &value );+ }++ return value;+}+++//========================================================================+// Return a list of available and usable framebuffer configs+//========================================================================++static _GLFWfbconfig *getFBConfigs( unsigned int *found )+{+ GLXFBConfig *fbconfigs;+ _GLFWfbconfig *result;+ int i, count = 0;++ *found = 0;++ if( _glfwLibrary.glxMajor == 1 && _glfwLibrary.glxMinor < 3 )+ {+ if( !_glfwWin.has_GLX_SGIX_fbconfig )+ {+ fprintf(stderr, "GLXFBConfigs are not supported by the X server\n");+ return NULL;+ }+ }++ if( _glfwWin.has_GLX_SGIX_fbconfig )+ {+ fbconfigs = _glfwWin.ChooseFBConfigSGIX( _glfwLibrary.display,+ _glfwWin.screen,+ NULL,+ &count );+ if( !count )+ {+ fprintf(stderr, "No GLXFBConfigs returned");+ return NULL;+ }+ }+ else+ {+ fbconfigs = glXGetFBConfigs( _glfwLibrary.display, _glfwWin.screen, &count );+ if( !count )+ {+ fprintf(stderr, "No GLXFBConfigs returned");+ return NULL;+ }+ }++ result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);+ if( !result )+ {+ fprintf(stderr, "Out of memory");+ return NULL;+ }++ for( i = 0; i < count; i++ )+ {+ if( !getFBConfigAttrib( fbconfigs[i], GLX_DOUBLEBUFFER ) ||+ !getFBConfigAttrib( fbconfigs[i], GLX_VISUAL_ID ) )+ {+ // Only consider doublebuffered GLXFBConfigs with associated visuals+ continue;+ }++ if( !( getFBConfigAttrib( fbconfigs[i], GLX_RENDER_TYPE ) & GLX_RGBA_BIT ) )+ {+ // Only consider RGBA GLXFBConfigs+ continue;+ }++ if( !( getFBConfigAttrib( fbconfigs[i], GLX_DRAWABLE_TYPE ) & GLX_WINDOW_BIT ) )+ {+ // Only consider window GLXFBConfigs+ continue;+ }++ result[*found].redBits = getFBConfigAttrib( fbconfigs[i], GLX_RED_SIZE );+ result[*found].greenBits = getFBConfigAttrib( fbconfigs[i], GLX_GREEN_SIZE );+ result[*found].blueBits = getFBConfigAttrib( fbconfigs[i], GLX_BLUE_SIZE );++ result[*found].alphaBits = getFBConfigAttrib( fbconfigs[i], GLX_ALPHA_SIZE );+ result[*found].depthBits = getFBConfigAttrib( fbconfigs[i], GLX_DEPTH_SIZE );+ result[*found].stencilBits = getFBConfigAttrib( fbconfigs[i], GLX_STENCIL_SIZE );++ result[*found].accumRedBits = getFBConfigAttrib( fbconfigs[i], GLX_ACCUM_RED_SIZE );+ result[*found].accumGreenBits = getFBConfigAttrib( fbconfigs[i], GLX_ACCUM_GREEN_SIZE );+ result[*found].accumBlueBits = getFBConfigAttrib( fbconfigs[i], GLX_ACCUM_BLUE_SIZE );+ result[*found].accumAlphaBits = getFBConfigAttrib( fbconfigs[i], GLX_ACCUM_ALPHA_SIZE );++ result[*found].auxBuffers = getFBConfigAttrib( fbconfigs[i], GLX_AUX_BUFFERS );+ result[*found].stereo = getFBConfigAttrib( fbconfigs[i], GLX_STEREO );++ if( _glfwWin.has_GLX_ARB_multisample )+ {+ result[*found].samples = getFBConfigAttrib( fbconfigs[i], GLX_SAMPLES );+ }+ else+ {+ result[*found].samples = 0;+ }++ result[*found].platformID = (GLFWintptr) getFBConfigAttrib( fbconfigs[i], GLX_FBCONFIG_ID );++ (*found)++;+ }++ XFree( fbconfigs );++ return result;+}+++//========================================================================+// Create the OpenGL context+//========================================================================++#define setGLXattrib( attribs, index, attribName, attribValue ) \+ attribs[index++] = attribName; \+ attribs[index++] = attribValue;++static int createContext( const _GLFWwndconfig *wndconfig, GLXFBConfigID fbconfigID )+{+ int attribs[40];+ int flags, dummy, index;+ GLXFBConfig *fbconfig;++ if( wndconfig->glMajor > 2 )+ {+ if( !_glfwWin.has_GLX_ARB_create_context )+ {+ fprintf(stderr, "GLX_ARB_create_context extension not found\n");+ return GL_FALSE;+ }+ }++ // Retrieve the previously selected GLXFBConfig+ {+ index = 0;++ setGLXattrib( attribs, index, GLX_FBCONFIG_ID, (int) fbconfigID );+ setGLXattrib( attribs, index, None, None );++ if( _glfwWin.has_GLX_SGIX_fbconfig )+ {+ fbconfig = _glfwWin.ChooseFBConfigSGIX( _glfwLibrary.display,+ _glfwWin.screen,+ attribs,+ &dummy );+ }+ else+ {+ fbconfig = glXChooseFBConfig( _glfwLibrary.display,+ _glfwWin.screen,+ attribs,+ &dummy );+ }++ if( fbconfig == NULL )+ {+ fprintf(stderr, "Unable to retrieve the selected GLXFBConfig\n");+ return GL_FALSE;+ }+ }++ // Retrieve the corresponding visual+ if( _glfwWin.has_GLX_SGIX_fbconfig )+ {+ _glfwWin.visual = _glfwWin.GetVisualFromFBConfigSGIX( _glfwLibrary.display,+ *fbconfig );+ }+ else+ {+ _glfwWin.visual = glXGetVisualFromFBConfig( _glfwLibrary.display, *fbconfig );+ }++ if( _glfwWin.visual == NULL )+ {+ XFree( fbconfig );++ fprintf(stderr, "Unable to retrieve visual for GLXFBconfig\n");+ return GL_FALSE;+ }++ if( _glfwWin.has_GLX_ARB_create_context )+ {+ index = 0;++ if( wndconfig->glMajor != 0 || wndconfig->glMinor != 0 )+ {+ // Request an explicitly versioned context++ setGLXattrib( attribs, index, GLX_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor );+ setGLXattrib( attribs, index, GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor );+ }++ if( wndconfig->glForward || wndconfig->glDebug )+ {+ flags = 0;++ if( wndconfig->glForward )+ {+ flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;+ }++ if( wndconfig->glDebug )+ {+ flags |= GLX_CONTEXT_DEBUG_BIT_ARB;+ }++ setGLXattrib( attribs, index, GLX_CONTEXT_FLAGS_ARB, flags );+ }++ if( wndconfig->glProfile )+ {+ if( !_glfwWin.has_GLX_ARB_create_context_profile )+ {+ fprintf( stderr, "OpenGL profile requested but GLX_ARB_create_context_profile "+ "is unavailable\n" );+ return GL_FALSE;+ }++ if( wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE )+ {+ flags = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;+ }+ else+ {+ flags = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;+ }++ setGLXattrib( attribs, index, GLX_CONTEXT_PROFILE_MASK_ARB, flags );+ }++ setGLXattrib( attribs, index, None, None );++ _glfwWin.context = _glfwWin.CreateContextAttribsARB( _glfwLibrary.display,+ *fbconfig,+ NULL,+ True,+ attribs );+ }+ else+ {+ if( _glfwWin.has_GLX_SGIX_fbconfig )+ {+ _glfwWin.context = _glfwWin.CreateContextWithConfigSGIX( _glfwLibrary.display,+ *fbconfig,+ GLX_RGBA_TYPE,+ NULL,+ True );+ }+ else+ {+ _glfwWin.context = glXCreateNewContext( _glfwLibrary.display,+ *fbconfig,+ GLX_RGBA_TYPE,+ NULL,+ True );+ }+ }++ XFree( fbconfig );++ if( _glfwWin.context == NULL )+ {+ fprintf(stderr, "Unable to create OpenGL context\n");+ return GL_FALSE;+ }++ _glfwWin.fbconfigID = fbconfigID;++ return GL_TRUE;+}+++//========================================================================+// Initialize GLX-specific extensions+//========================================================================++static void initGLXExtensions( void )+{+ // This needs to include every function pointer loaded below+ _glfwWin.SwapIntervalSGI = NULL;+ _glfwWin.GetFBConfigAttribSGIX = NULL;+ _glfwWin.ChooseFBConfigSGIX = NULL;+ _glfwWin.CreateContextWithConfigSGIX = NULL;+ _glfwWin.GetVisualFromFBConfigSGIX = NULL;+ _glfwWin.CreateContextAttribsARB = NULL;++ // This needs to include every extension used below+ _glfwWin.has_GLX_SGIX_fbconfig = GL_FALSE;+ _glfwWin.has_GLX_SGI_swap_control = GL_FALSE;+ _glfwWin.has_GLX_ARB_multisample = GL_FALSE;+ _glfwWin.has_GLX_ARB_create_context = GL_FALSE;+ _glfwWin.has_GLX_ARB_create_context_profile = GL_FALSE;++ if( _glfwPlatformExtensionSupported( "GLX_SGI_swap_control" ) )+ {+ _glfwWin.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)+ _glfwPlatformGetProcAddress( "glXSwapIntervalSGI" );++ if( _glfwWin.SwapIntervalSGI )+ {+ _glfwWin.has_GLX_SGI_swap_control = GL_TRUE;+ }+ }++ if( _glfwPlatformExtensionSupported( "GLX_SGIX_fbconfig" ) )+ {+ _glfwWin.GetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)+ _glfwPlatformGetProcAddress( "glXGetFBConfigAttribSGIX" );+ _glfwWin.ChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)+ _glfwPlatformGetProcAddress( "glXChooseFBConfigSGIX" );+ _glfwWin.CreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)+ _glfwPlatformGetProcAddress( "glXCreateContextWithConfigSGIX" );+ _glfwWin.GetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)+ _glfwPlatformGetProcAddress( "glXGetVisualFromFBConfigSGIX" );++ if( _glfwWin.GetFBConfigAttribSGIX &&+ _glfwWin.ChooseFBConfigSGIX &&+ _glfwWin.CreateContextWithConfigSGIX &&+ _glfwWin.GetVisualFromFBConfigSGIX )+ {+ _glfwWin.has_GLX_SGIX_fbconfig = GL_TRUE;+ }+ }++ if( _glfwPlatformExtensionSupported( "GLX_ARB_multisample" ) )+ {+ _glfwWin.has_GLX_ARB_multisample = GL_TRUE;+ }++ if( _glfwPlatformExtensionSupported( "GLX_ARB_create_context" ) )+ {+ _glfwWin.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)+ _glfwPlatformGetProcAddress( "glXCreateContextAttribsARB" );++ if( _glfwWin.CreateContextAttribsARB )+ {+ _glfwWin.has_GLX_ARB_create_context = GL_TRUE;+ }+ }++ if( _glfwPlatformExtensionSupported( "GLX_ARB_create_context_profile" ) )+ {+ _glfwWin.has_GLX_ARB_create_context_profile = GL_TRUE;+ }+}+++//========================================================================+// Create the X11 window (and its colormap)+//========================================================================++static GLboolean createWindow( int width, int height,+ const _GLFWwndconfig *wndconfig )+{+ XEvent event;+ Atom protocols[2];+ XSizeHints *sizehints;+ unsigned long wamask;+ XSetWindowAttributes wa;++ // Every window needs a colormap+ // We create one based on the visual used by the current context++ _glfwWin.colormap = XCreateColormap( _glfwLibrary.display,+ RootWindow( _glfwLibrary.display,+ _glfwWin.screen ),+ _glfwWin.visual->visual,+ AllocNone );++ // Create the actual window+ {+ wamask = CWBorderPixel | CWColormap | CWEventMask;++ wa.colormap = _glfwWin.colormap;+ wa.border_pixel = 0;+ wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask |+ ExposureMask | FocusChangeMask | VisibilityChangeMask;++ if( wndconfig->mode == GLFW_WINDOW )+ {+ // The /only/ reason we are setting the background pixel here is+ // because otherwise our window wont get any decorations on systems+ // using Compiz on Intel hardware+ wa.background_pixel = BlackPixel( _glfwLibrary.display, _glfwWin.screen );+ wamask |= CWBackPixel;+ }++ _glfwWin.window = XCreateWindow(+ _glfwLibrary.display,+ RootWindow( _glfwLibrary.display, _glfwWin.screen ),+ 0, 0, // Upper left corner of this window on root+ _glfwWin.width, _glfwWin.height,+ 0, // Border width+ _glfwWin.visual->depth, // Color depth+ InputOutput,+ _glfwWin.visual->visual,+ wamask,+ &wa+ );+ if( !_glfwWin.window )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }+ }++ // Declare which WM protocols we support+ {+ // Basic window close notification protocol+ _glfwWin.WMDeleteWindow = XInternAtom( _glfwLibrary.display,+ "WM_DELETE_WINDOW",+ False );++ // Tells the WM to ping our window and flag us as unresponsive if we+ // don't reply within a few seconds+ _glfwWin.WMPing = XInternAtom( _glfwLibrary.display, "_NET_WM_PING", False );++ protocols[0] = _glfwWin.WMDeleteWindow;+ protocols[1] = _glfwWin.WMPing;++ XSetWMProtocols( _glfwLibrary.display, _glfwWin.window, protocols,+ sizeof(protocols) / sizeof(Atom) );+ }++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ disableDecorations();+ }++ // Set window position and size WM hints+ {+ sizehints = XAllocSizeHints();+ sizehints->flags = 0;++ if( wndconfig->windowNoResize )+ {+ sizehints->flags |= (PMinSize | PMaxSize);+ sizehints->min_width = sizehints->max_width = _glfwWin.width;+ sizehints->min_height = sizehints->max_height = _glfwWin.height;+ }++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ sizehints->flags |= PPosition;+ sizehints->x = 0;+ sizehints->y = 0;+ }++ XSetWMNormalHints( _glfwLibrary.display, _glfwWin.window, sizehints );+ XFree( sizehints );+ }++ _glfwPlatformSetWindowTitle( "GLFW Window" );++ XMapWindow( _glfwLibrary.display, _glfwWin.window );++ // Wait for map notification+ XIfEvent( _glfwLibrary.display, &event, isMapNotify,+ (char*)_glfwWin.window );++ // Make sure that our window ends up on top of things+ XRaiseWindow( _glfwLibrary.display, _glfwWin.window );++ return GL_TRUE;+}++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Here is where the window is created, and+// the OpenGL rendering context is created+//========================================================================++int _glfwPlatformOpenWindow( int width, int height,+ const _GLFWwndconfig* wndconfig,+ const _GLFWfbconfig* fbconfig )+{+ unsigned int mask, fbcount;+ _GLFWfbconfig *fbconfigs;+ _GLFWfbconfig closest;+ const _GLFWfbconfig *result;+ Window window, root;+ int windowX, windowY, rootX, rootY;++ // Clear platform specific GLFW window state+ _glfwWin.visual = (XVisualInfo*)NULL;+ _glfwWin.colormap = (Colormap)0;+ _glfwWin.context = (GLXContext)NULL;+ _glfwWin.window = (Window)0;+ _glfwWin.pointerGrabbed = GL_FALSE;+ _glfwWin.pointerHidden = GL_FALSE;+ _glfwWin.keyboardGrabbed = GL_FALSE;+ _glfwWin.overrideRedirect = GL_FALSE;+ _glfwWin.FS.modeChanged = GL_FALSE;+ _glfwWin.Saver.changed = GL_FALSE;+ _glfwWin.refreshRate = wndconfig->refreshRate;+ _glfwWin.windowNoResize = wndconfig->windowNoResize;++ // As the 2.x API doesn't understand screens, we hardcode this choice and+ // hope for the best+ _glfwWin.screen = DefaultScreen( _glfwLibrary.display );++ initGLXExtensions();++ // Choose the best available fbconfig+ {+ fbconfigs = getFBConfigs( &fbcount );+ if( !fbconfigs )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ result = _glfwChooseFBConfig( fbconfig, fbconfigs, fbcount );+ if( !result )+ {+ free( fbconfigs );+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ closest = *result;+ free( fbconfigs );+ fbconfigs = NULL;+ result = NULL;+ }++ if( !createContext( wndconfig, (GLXFBConfigID) closest.platformID ) )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ // Change video mode+ _glfwSetVideoMode( _glfwWin.screen, &_glfwWin.width,+ &_glfwWin.height, &_glfwWin.refreshRate );++ // Remember old screen saver settings+ XGetScreenSaver( _glfwLibrary.display, &_glfwWin.Saver.timeout,+ &_glfwWin.Saver.interval, &_glfwWin.Saver.blanking,+ &_glfwWin.Saver.exposure );++ // Disable screen saver+ XSetScreenSaver( _glfwLibrary.display, 0, 0, DontPreferBlanking,+ DefaultExposures );+ }++ if( !createWindow( width, height, wndconfig ) )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ // Fullscreen mode post-window-creation work++#if defined( _GLFW_HAS_XRANDR )+ // Request screen change notifications+ if( _glfwLibrary.XRandR.available )+ {+ XRRSelectInput( _glfwLibrary.display,+ _glfwWin.window,+ RRScreenChangeNotifyMask );+ }+#endif++ // Force window position/size (some WMs do their own window+ // geometry, which we want to override)+ XMoveWindow( _glfwLibrary.display, _glfwWin.window, 0, 0 );+ XResizeWindow( _glfwLibrary.display, _glfwWin.window, _glfwWin.width,+ _glfwWin.height );++ if( XGrabKeyboard( _glfwLibrary.display, _glfwWin.window, True,+ GrabModeAsync, GrabModeAsync, CurrentTime ) ==+ GrabSuccess )+ {+ _glfwWin.keyboardGrabbed = GL_TRUE;+ }++ if( XGrabPointer( _glfwLibrary.display, _glfwWin.window, True,+ ButtonPressMask | ButtonReleaseMask |+ PointerMotionMask, GrabModeAsync, GrabModeAsync,+ _glfwWin.window, None, CurrentTime ) ==+ GrabSuccess )+ {+ _glfwWin.pointerGrabbed = GL_TRUE;+ }++ // Try to get window inside viewport (for virtual displays) by+ // moving the mouse cursor to the upper left corner (and then to+ // the center) - this works for XFree86+ XWarpPointer( _glfwLibrary.display, None, _glfwWin.window, 0,0,0,0, 0,0 );+ XWarpPointer( _glfwLibrary.display, None, _glfwWin.window, 0,0,0,0,+ _glfwWin.width/2, _glfwWin.height/2 );+ }++ // Retrieve and set initial cursor position+ {+ XQueryPointer( _glfwLibrary.display,+ _glfwWin.window,+ &root,+ &window,+ &rootX, &rootY,+ &windowX, &windowY,+ &mask );++ // TODO: Probably check for some corner cases here.++ _glfwInput.MousePosX = windowX;+ _glfwInput.MousePosY = windowY;+ }++ // Connect the context to the window+ glXMakeCurrent( _glfwLibrary.display, _glfwWin.window, _glfwWin.context );++ // Start by clearing the front buffer to black (avoid ugly desktop+ // remains in our OpenGL window)+ glClear( GL_COLOR_BUFFER_BIT );+ glXSwapBuffers( _glfwLibrary.display, _glfwWin.window );++ return GL_TRUE;+}+++//========================================================================+// Properly kill the window/video display+//========================================================================++void _glfwPlatformCloseWindow( void )+{+#if defined( _GLFW_HAS_XRANDR )+ XRRScreenConfiguration *sc;+ Window root;+#endif++ // Do we have a rendering context?+ if( _glfwWin.context )+ {+ // Release the context+ glXMakeCurrent( _glfwLibrary.display, None, NULL );++ // Delete the context+ glXDestroyContext( _glfwLibrary.display, _glfwWin.context );+ _glfwWin.context = NULL;+ }++ // Do we have a visual?+ if( _glfwWin.visual )+ {+ XFree( _glfwWin.visual );+ _glfwWin.visual = NULL;+ }++ // Ungrab pointer and/or keyboard?+ if( _glfwWin.keyboardGrabbed )+ {+ XUngrabKeyboard( _glfwLibrary.display, CurrentTime );+ _glfwWin.keyboardGrabbed = GL_FALSE;+ }+ if( _glfwWin.pointerGrabbed )+ {+ XUngrabPointer( _glfwLibrary.display, CurrentTime );+ _glfwWin.pointerGrabbed = GL_FALSE;+ }++ // Do we have a window?+ if( _glfwWin.window )+ {+ // Unmap the window+ XUnmapWindow( _glfwLibrary.display, _glfwWin.window );++ // Destroy the window+ XDestroyWindow( _glfwLibrary.display, _glfwWin.window );+ _glfwWin.window = (Window) 0;+ }++ if( _glfwWin.colormap )+ {+ XFreeColormap( _glfwLibrary.display, _glfwWin.colormap );+ _glfwWin.colormap = (Colormap) 0;+ }++ // Did we change the fullscreen resolution?+ if( _glfwWin.FS.modeChanged )+ {+#if defined( _GLFW_HAS_XRANDR )+ if( _glfwLibrary.XRandR.available )+ {+ root = RootWindow( _glfwLibrary.display, _glfwWin.screen );+ sc = XRRGetScreenInfo( _glfwLibrary.display, root );++ XRRSetScreenConfig( _glfwLibrary.display,+ sc,+ root,+ _glfwWin.FS.oldSizeID,+ _glfwWin.FS.oldRotation,+ CurrentTime );++ XRRFreeScreenConfigInfo( sc );+ }+#elif defined( _GLFW_HAS_XF86VIDMODE )+ if( _glfwLibrary.XF86VidMode.available )+ {+ // Unlock mode switch+ XF86VidModeLockModeSwitch( _glfwLibrary.display,+ _glfwWin.screen,+ 0 );++ // Change the video mode back to the old mode+ XF86VidModeSwitchToMode( _glfwLibrary.display,+ _glfwWin.screen,+ &_glfwWin.FS.oldMode );+ }+#endif+ _glfwWin.FS.modeChanged = GL_FALSE;+ }++ // Did we change the screen saver setting?+ if( _glfwWin.Saver.changed )+ {+ // Restore old screen saver settings+ XSetScreenSaver( _glfwLibrary.display,+ _glfwWin.Saver.timeout,+ _glfwWin.Saver.interval,+ _glfwWin.Saver.blanking,+ _glfwWin.Saver.exposure );+ _glfwWin.Saver.changed = GL_FALSE;+ }+}+++//========================================================================+// _glfwPlatformSetWindowTitle() - Set the window title.+//========================================================================++void _glfwPlatformSetWindowTitle( const char *title )+{+ // Set window & icon title+ XStoreName( _glfwLibrary.display, _glfwWin.window, title );+ XSetIconName( _glfwLibrary.display, _glfwWin.window, title );+}+++//========================================================================+// _glfwPlatformSetWindowSize() - Set the window size.+//========================================================================++void _glfwPlatformSetWindowSize( int width, int height )+{+ int mode = 0, rate, sizeChanged = GL_FALSE;+ XSizeHints *sizehints;++ rate = _glfwWin.refreshRate;++ // If we are in fullscreen mode, get some info about the current mode+ if( _glfwWin.fullscreen )+ {+ // Get closest match for target video mode+ mode = _glfwGetClosestVideoMode( _glfwWin.screen, &width, &height, &rate );+ }++ if( _glfwWin.windowNoResize )+ {+ sizehints = XAllocSizeHints();+ sizehints->flags = 0;++ sizehints->min_width = sizehints->max_width = width;+ sizehints->min_height = sizehints->max_height = height;++ XSetWMNormalHints( _glfwLibrary.display, _glfwWin.window, sizehints );+ XFree( sizehints );+ }++ // Change window size before changing fullscreen mode?+ if( _glfwWin.fullscreen && (width > _glfwWin.width) )+ {+ XResizeWindow( _glfwLibrary.display, _glfwWin.window, width, height );+ sizeChanged = GL_TRUE;+ }++ // Change fullscreen video mode?+ if( _glfwWin.fullscreen )+ {+ // Change video mode (keeping current rate)+ _glfwSetVideoModeMODE( _glfwWin.screen, mode, _glfwWin.refreshRate );+ }++ // Set window size (if not already changed)+ if( !sizeChanged )+ {+ XResizeWindow( _glfwLibrary.display, _glfwWin.window, width, height );+ }+}+++//========================================================================+// _glfwPlatformSetWindowPos() - Set the window position.+//========================================================================++void _glfwPlatformSetWindowPos( int x, int y )+{+ // Set window position+ XMoveWindow( _glfwLibrary.display, _glfwWin.window, x, y );+}+++//========================================================================+// _glfwPlatformIconfyWindow() - Window iconification+//========================================================================++void _glfwPlatformIconifyWindow( void )+{+ // We can't do this for override redirect windows+ if( _glfwWin.overrideRedirect )+ {+ return;+ }++ // In fullscreen mode, we need to restore the desktop video mode+ if( _glfwWin.fullscreen )+ {+#if defined( _GLFW_HAS_XRANDR )+ if( _glfwLibrary.XRandR.available )+ {+ // TODO: The code.+ }+#elif defined( _GLFW_HAS_XF86VIDMODE )+ if( _glfwLibrary.XF86VidMode.available )+ {+ // Unlock mode switch+ XF86VidModeLockModeSwitch( _glfwLibrary.display,+ _glfwWin.screen,+ 0 );++ // Change the video mode back to the old mode+ XF86VidModeSwitchToMode( _glfwLibrary.display,+ _glfwWin.screen, &_glfwWin.FS.oldMode );+ }+#endif+ _glfwWin.FS.modeChanged = GL_FALSE;+ }++ // Show mouse pointer+ if( _glfwWin.pointerHidden )+ {+ XUndefineCursor( _glfwLibrary.display, _glfwWin.window );+ _glfwWin.pointerHidden = GL_FALSE;+ }++ // Un-grab mouse pointer+ if( _glfwWin.pointerGrabbed )+ {+ XUngrabPointer( _glfwLibrary.display, CurrentTime );+ _glfwWin.pointerGrabbed = GL_FALSE;+ }++ // Iconify window+ XIconifyWindow( _glfwLibrary.display, _glfwWin.window,+ _glfwWin.screen );++ // Window is now iconified+ _glfwWin.iconified = GL_TRUE;+}+++//========================================================================+// Window un-iconification+//========================================================================++void _glfwPlatformRestoreWindow( void )+{+ // We can't do this for override redirect windows+ if( _glfwWin.overrideRedirect )+ {+ return;+ }++ // In fullscreen mode, change back video mode to user selected mode+ if( _glfwWin.fullscreen )+ {+ _glfwSetVideoMode( _glfwWin.screen,+ &_glfwWin.width, &_glfwWin.height, &_glfwWin.refreshRate );+ }++ // Un-iconify window+ XMapWindow( _glfwLibrary.display, _glfwWin.window );++ // In fullscreen mode...+ if( _glfwWin.fullscreen )+ {+ // Make sure window is in upper left corner+ XMoveWindow( _glfwLibrary.display, _glfwWin.window, 0, 0 );++ // Get input focus+ XSetInputFocus( _glfwLibrary.display, _glfwWin.window, RevertToParent,+ CurrentTime );+ }++ // Lock mouse, if necessary+ if( _glfwWin.mouseLock )+ {+ // Hide cursor+ if( !_glfwWin.pointerHidden )+ {+ XDefineCursor( _glfwLibrary.display, _glfwWin.window,+ createNULLCursor( _glfwLibrary.display,+ _glfwWin.window ) );++ _glfwWin.pointerHidden = GL_TRUE;+ }++ // Grab cursor+ if( !_glfwWin.pointerGrabbed )+ {+ if( XGrabPointer( _glfwLibrary.display, _glfwWin.window, True,+ ButtonPressMask | ButtonReleaseMask |+ PointerMotionMask, GrabModeAsync,+ GrabModeAsync, _glfwWin.window, None,+ CurrentTime ) == GrabSuccess )+ {+ _glfwWin.pointerGrabbed = GL_TRUE;+ }+ }+ }++ // Window is no longer iconified+ _glfwWin.iconified = GL_FALSE;+}+++//========================================================================+// _glfwPlatformSwapBuffers() - Swap buffers (double-buffering) and poll+// any new events.+//========================================================================++void _glfwPlatformSwapBuffers( void )+{+ // Update display-buffer+ glXSwapBuffers( _glfwLibrary.display, _glfwWin.window );+}+++//========================================================================+// _glfwPlatformSwapInterval() - Set double buffering swap interval+//========================================================================++void _glfwPlatformSwapInterval( int interval )+{+ if( _glfwWin.has_GLX_SGI_swap_control )+ {+ _glfwWin.SwapIntervalSGI( interval );+ }+}+++//========================================================================+// Read back framebuffer parameters from the context+//========================================================================++void _glfwPlatformRefreshWindowParams( void )+{+ int dummy;+ GLXFBConfig *fbconfig;+#if defined( _GLFW_HAS_XRANDR )+ XRRScreenConfiguration *sc;+#elif defined( _GLFW_HAS_XF86VIDMODE )+ XF86VidModeModeLine modeline;+ int dotclock;+ float pixels_per_second, pixels_per_frame;+#endif+ int attribs[] = { GLX_FBCONFIG_ID, _glfwWin.fbconfigID, None };++ if( _glfwWin.has_GLX_SGIX_fbconfig )+ {+ fbconfig = _glfwWin.ChooseFBConfigSGIX( _glfwLibrary.display,+ _glfwWin.screen,+ attribs,+ &dummy );+ }+ else+ {+ fbconfig = glXChooseFBConfig( _glfwLibrary.display,+ _glfwWin.screen,+ attribs,+ &dummy );+ }++ if( fbconfig == NULL )+ {+ // This should never ever happen+ // TODO: Figure out what to do when this happens+ fprintf( stderr, "Cannot find known GLXFBConfig by ID. "+ "This cannot happen. Have a nice day.\n");+ abort();+ }++ // There is no clear definition of an "accelerated" context on X11/GLX, and+ // true sounds better than false, so we hardcode true here+ _glfwWin.accelerated = GL_TRUE;++ // "Standard" window parameters+ _glfwWin.redBits = getFBConfigAttrib( *fbconfig, GLX_RED_SIZE );+ _glfwWin.greenBits = getFBConfigAttrib( *fbconfig, GLX_GREEN_SIZE );+ _glfwWin.blueBits = getFBConfigAttrib( *fbconfig, GLX_BLUE_SIZE );++ _glfwWin.alphaBits = getFBConfigAttrib( *fbconfig, GLX_ALPHA_SIZE );+ _glfwWin.depthBits = getFBConfigAttrib( *fbconfig, GLX_DEPTH_SIZE );+ _glfwWin.stencilBits = getFBConfigAttrib( *fbconfig, GLX_STENCIL_SIZE );++ _glfwWin.accumRedBits = getFBConfigAttrib( *fbconfig, GLX_ACCUM_RED_SIZE );+ _glfwWin.accumGreenBits = getFBConfigAttrib( *fbconfig, GLX_ACCUM_GREEN_SIZE );+ _glfwWin.accumBlueBits = getFBConfigAttrib( *fbconfig, GLX_ACCUM_BLUE_SIZE );+ _glfwWin.accumAlphaBits = getFBConfigAttrib( *fbconfig, GLX_ACCUM_ALPHA_SIZE );++ _glfwWin.auxBuffers = getFBConfigAttrib( *fbconfig, GLX_AUX_BUFFERS );++ // Get stereo rendering setting+ _glfwWin.stereo = getFBConfigAttrib( *fbconfig, GLX_STEREO ) ? 1 : 0;++ // Get multisample buffer samples+ if( _glfwWin.has_GLX_ARB_multisample )+ {+ _glfwWin.samples = getFBConfigAttrib( *fbconfig, GLX_SAMPLES );+ }+ else+ {+ _glfwWin.samples = 0;+ }++ // Default to refresh rate unknown (=0 according to GLFW spec)+ _glfwWin.refreshRate = 0;++ // Retrieve refresh rate if possible+#if defined( _GLFW_HAS_XRANDR )+ if( _glfwLibrary.XRandR.available )+ {+ sc = XRRGetScreenInfo( _glfwLibrary.display,+ RootWindow( _glfwLibrary.display, _glfwWin.screen ) );+ _glfwWin.refreshRate = XRRConfigCurrentRate( sc );+ XRRFreeScreenConfigInfo( sc );+ }+#elif defined( _GLFW_HAS_XF86VIDMODE )+ if( _glfwLibrary.XF86VidMode.available )+ {+ // Use the XF86VidMode extension to get current video mode+ XF86VidModeGetModeLine( _glfwLibrary.display, _glfwWin.screen,+ &dotclock, &modeline );+ pixels_per_second = 1000.0f * (float) dotclock;+ pixels_per_frame = (float) modeline.htotal * modeline.vtotal;+ _glfwWin.refreshRate = (int)(pixels_per_second/pixels_per_frame+0.5);+ }+#endif++ XFree( fbconfig );+}+++//========================================================================+// _glfwPlatformPollEvents() - Poll for new window and input events+//========================================================================++void _glfwPlatformPollEvents( void )+{+ int winclosed = GL_FALSE;++ // Flag that the cursor has not moved+ _glfwInput.MouseMoved = GL_FALSE;++ // Clear MapNotify and FocusIn counts+ _glfwWin.mapNotifyCount = 0;+ _glfwWin.focusInCount = 0;++ // Empty the window event queue+ while( XPending( _glfwLibrary.display ) )+ {+ if( getNextEvent() )+ {+ winclosed = GL_TRUE;+ }+ }++ // Did we get mouse movement in locked cursor mode?+ if( _glfwInput.MouseMoved && _glfwWin.mouseLock )+ {+ int maxx, minx, maxy, miny;++ // Calculate movement threshold+ minx = _glfwWin.width / 4;+ maxx = (_glfwWin.width * 3) / 4;+ miny = _glfwWin.height / 4;+ maxy = (_glfwWin.height * 3) / 4;++ // Did the mouse cursor move beyond our movement threshold+ if(_glfwInput.CursorPosX < minx || _glfwInput.CursorPosX > maxx ||+ _glfwInput.CursorPosY < miny || _glfwInput.CursorPosY > maxy)+ {+ // Move the mouse pointer back to the window center so that it+ // does not wander off...+ _glfwPlatformSetMouseCursorPos( _glfwWin.width/2,+ _glfwWin.height/2 );+ }+ }++ // Was the window (un)iconified?+ if( _glfwWin.mapNotifyCount < 0 && !_glfwWin.iconified )+ {+ // Show mouse pointer+ if( _glfwWin.pointerHidden )+ {+ XUndefineCursor( _glfwLibrary.display, _glfwWin.window );+ _glfwWin.pointerHidden = GL_FALSE;+ }++ // Un-grab mouse pointer+ if( _glfwWin.pointerGrabbed )+ {+ XUngrabPointer( _glfwLibrary.display, CurrentTime );+ _glfwWin.pointerGrabbed = GL_FALSE;+ }++ _glfwWin.iconified = GL_TRUE;+ }+ else if( _glfwWin.mapNotifyCount > 0 && _glfwWin.iconified )+ {+ // Restore fullscreen mode properties+ if( _glfwWin.fullscreen )+ {+ // Change back video mode to user selected mode+ _glfwSetVideoMode( _glfwWin.screen, &_glfwWin.width,+ &_glfwWin.height, &_glfwWin.refreshRate );+ // Disable window manager decorations+ enableDecorations();++ // Make sure window is in upper left corner+ XMoveWindow( _glfwLibrary.display, _glfwWin.window, 0, 0 );++ // Get input focus+ XSetInputFocus( _glfwLibrary.display, _glfwWin.window,+ RevertToParent, CurrentTime );+ }++ // Hide cursor if necessary+ if( _glfwWin.mouseLock && !_glfwWin.pointerHidden )+ {+ if( !_glfwWin.pointerHidden )+ {+ XDefineCursor( _glfwLibrary.display, _glfwWin.window,+ createNULLCursor( _glfwLibrary.display,+ _glfwWin.window ) );++ _glfwWin.pointerHidden = GL_TRUE;+ }+ }++ // Grab cursor if necessary+ if( (_glfwWin.mouseLock || _glfwWin.fullscreen) &&+ !_glfwWin.pointerGrabbed )+ {+ if( XGrabPointer( _glfwLibrary.display, _glfwWin.window, True,+ ButtonPressMask | ButtonReleaseMask |+ PointerMotionMask, GrabModeAsync,+ GrabModeAsync, _glfwWin.window, None,+ CurrentTime ) == GrabSuccess )+ {+ _glfwWin.pointerGrabbed = GL_TRUE;+ }+ }++ _glfwWin.iconified = GL_FALSE;+ }++ // Did the window get/lose focus+ if( _glfwWin.focusInCount > 0 && !_glfwWin.active )+ {+ // If we are in fullscreen mode, restore window+ if( _glfwWin.fullscreen && _glfwWin.iconified )+ {+ _glfwPlatformRestoreWindow();+ }++ // Window is now active+ _glfwWin.active = GL_TRUE;+ }+ else if( _glfwWin.focusInCount < 0 && _glfwWin.active )+ {+ // If we are in fullscreen mode, iconfify window+ if( _glfwWin.fullscreen )+ {+ _glfwPlatformIconifyWindow();+ }++ // Window is not active+ _glfwWin.active = GL_FALSE;+ _glfwInputDeactivation();+ }++ // Was there a window close request?+ if( winclosed && _glfwWin.windowCloseCallback )+ {+ // Check if the program wants us to close the window+ winclosed = _glfwWin.windowCloseCallback();+ }+ if( winclosed )+ {+ glfwCloseWindow();+ }+}+++//========================================================================+// _glfwPlatformWaitEvents() - Wait for new window and input events+//========================================================================++void _glfwPlatformWaitEvents( void )+{+ XEvent event;++ // Wait for new events (blocking)+ XNextEvent( _glfwLibrary.display, &event );+ XPutBackEvent( _glfwLibrary.display, &event );++ // Poll events from queue+ _glfwPlatformPollEvents();+}+++//========================================================================+// _glfwPlatformHideMouseCursor() - Hide mouse cursor (lock it)+//========================================================================++void _glfwPlatformHideMouseCursor( void )+{+ // Hide cursor+ if( !_glfwWin.pointerHidden )+ {+ XDefineCursor( _glfwLibrary.display, _glfwWin.window,+ createNULLCursor( _glfwLibrary.display,+ _glfwWin.window ) );++ _glfwWin.pointerHidden = GL_TRUE;+ }++ // Grab cursor to user window+ if( !_glfwWin.pointerGrabbed )+ {+ if( XGrabPointer( _glfwLibrary.display, _glfwWin.window, True,+ ButtonPressMask | ButtonReleaseMask |+ PointerMotionMask, GrabModeAsync, GrabModeAsync,+ _glfwWin.window, None, CurrentTime ) ==+ GrabSuccess )+ {+ _glfwWin.pointerGrabbed = GL_TRUE;+ }+ }+}+++//========================================================================+// _glfwPlatformShowMouseCursor() - Show mouse cursor (unlock it)+//========================================================================++void _glfwPlatformShowMouseCursor( void )+{+ // Un-grab cursor (only in windowed mode: in fullscreen mode we still+ // want the mouse grabbed in order to confine the cursor to the window+ // area)+ if( _glfwWin.pointerGrabbed && !_glfwWin.fullscreen )+ {+ XUngrabPointer( _glfwLibrary.display, CurrentTime );+ _glfwWin.pointerGrabbed = GL_FALSE;+ }++ // Show cursor+ if( _glfwWin.pointerHidden )+ {+ XUndefineCursor( _glfwLibrary.display, _glfwWin.window );+ _glfwWin.pointerHidden = GL_FALSE;+ }+}+++//========================================================================+// _glfwPlatformSetMouseCursorPos() - Set physical mouse cursor position+//========================================================================++void _glfwPlatformSetMouseCursorPos( int x, int y )+{+ // Change cursor position+ _glfwInput.CursorPosX = x;+ _glfwInput.CursorPosY = y;+ XWarpPointer( _glfwLibrary.display, None, _glfwWin.window, 0,0,0,0, x, y );+}+
+ src/Graphics/UI/GLFW.hsc view
@@ -0,0 +1,988 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module Graphics.UI.GLFW+ ( -- * Initialization and termination+ initialize+ , terminate++ -- * Video mode information+ , getVideoMode+ , getVideoModes+ --+ , VideoMode(..)++ -- * Windows+ -- ** Management+ , openWindow+ , closeWindow+ , setWindowTitle+ , setWindowDimensions+ , setWindowPosition+ , iconifyWindow+ , restoreWindow+ , swapBuffers+ , setWindowBufferSwapInterval+ --+ , DisplayMode(..)+ , DisplayOptions(..)+ , defaultDisplayOptions+ -- ** Information+ , windowIsOpen+ , windowIsActive+ , windowIsIconified+ , windowIsResizable+ , windowIsHardwareAccelerated+ , windowSupportsStereoRendering+ , getWindowRefreshRate+ , getWindowDimensions+ , getWindowValue+ , setWindowCloseCallback+ , setWindowSizeCallback+ , setWindowRefreshCallback+ --+ , WindowValue(..)+ , WindowCloseCallback+ , WindowSizeCallback+ , WindowRefreshCallback++ -- * Input+ , pollEvents+ , waitEvents+ -- ** Keyboard+ , keyIsPressed+ , setCharCallback+ , setKeyCallback+ --+ , Key(..)+ , CharCallback+ , KeyCallback+ -- ** Mouse+ , mouseButtonIsPressed+ , getMousePosition+ , getMouseWheel+ , setMousePosition+ , setMouseWheel+ , setMouseButtonCallback+ , setMousePositionCallback+ , setMouseWheelCallback+ --+ , MouseButton(..)+ , MouseButtonCallback+ , MousePositionCallback+ , MouseWheelCallback+ -- ** Joystick+ , joystickIsPresent+ , getJoystickPosition+ , getNumJoystickAxes+ , getNumJoystickButtons+ , joystickButtonsArePressed+ --+ , Joystick(..)++ -- * Time+ , getTime+ , setTime+ , resetTime+ , sleep++ -- * Version information+ , getGlfwVersion+ , getGlVersion+ ) where++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++import Control.Monad (when)+import Data.Char (chr, ord)+import Data.IORef (IORef, atomicModifyIORef, newIORef)+import Data.Maybe (fromJust, isJust)+import Data.Version (Version(..))+import Foreign.C.String (CString, withCString)+import Foreign.C.Types (CDouble, CFloat, CInt, CUChar)+import Foreign.Marshal.Alloc (alloca)+import Foreign.Marshal.Array (allocaArray, peekArray)+import Foreign.Ptr (FunPtr, Ptr, freeHaskellFunPtr)+import Foreign.Storable (Storable(..))+import System.IO.Unsafe (unsafePerformIO)++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++#include <GL/glfw.h>++foreign import ccall unsafe glfwInit :: IO CInt+foreign import ccall unsafe glfwTerminate :: IO ()+foreign import ccall unsafe glfwGetVersion :: Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()++foreign import ccall unsafe glfwOpenWindow :: CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> IO CInt+foreign import ccall unsafe glfwOpenWindowHint :: CInt -> CInt -> IO ()+foreign import ccall unsafe glfwCloseWindow :: IO ()+foreign import ccall unsafe glfwSetWindowCloseCallback :: FunPtr GlfwWindowCloseCallback -> IO ()+foreign import ccall unsafe glfwSetWindowTitle :: CString -> IO ()+foreign import ccall unsafe glfwSetWindowSize :: CInt -> CInt -> IO ()+foreign import ccall unsafe glfwSetWindowPos :: CInt -> CInt -> IO ()+foreign import ccall unsafe glfwGetWindowSize :: Ptr CInt -> Ptr CInt -> IO ()+foreign import ccall glfwSetWindowSizeCallback :: FunPtr GlfwWindowSizeCallback -> IO ()+foreign import ccall unsafe glfwIconifyWindow :: IO ()+foreign import ccall unsafe glfwRestoreWindow :: IO ()+foreign import ccall unsafe glfwGetWindowParam :: CInt -> IO CInt+foreign import ccall glfwSwapBuffers :: IO ()+foreign import ccall unsafe glfwSwapInterval :: CInt -> IO ()+foreign import ccall unsafe glfwSetWindowRefreshCallback :: FunPtr GlfwWindowRefreshCallback -> IO ()++foreign import ccall unsafe glfwGetVideoModes :: Ptr VideoMode -> CInt -> IO CInt+foreign import ccall unsafe glfwGetDesktopMode :: Ptr VideoMode -> IO ()++foreign import ccall unsafe glfwPollEvents :: IO ()+foreign import ccall unsafe glfwWaitEvents :: IO ()+foreign import ccall unsafe glfwGetKey :: CInt -> IO CInt+foreign import ccall unsafe glfwGetMouseButton :: CInt -> IO CInt+foreign import ccall unsafe glfwGetMousePos :: Ptr CInt -> Ptr CInt -> IO ()+foreign import ccall unsafe glfwSetMousePos :: CInt -> CInt -> IO ()+foreign import ccall unsafe glfwGetMouseWheel :: IO CInt+foreign import ccall unsafe glfwSetMouseWheel :: CInt -> IO ()+foreign import ccall glfwSetKeyCallback :: FunPtr GlfwKeyCallback -> IO ()+foreign import ccall glfwSetCharCallback :: FunPtr GlfwCharCallback -> IO ()+foreign import ccall glfwSetMouseButtonCallback :: FunPtr GlfwMouseButtonCallback -> IO ()+foreign import ccall glfwSetMousePosCallback :: FunPtr GlfwMousePositionCallback -> IO ()+foreign import ccall glfwSetMouseWheelCallback :: FunPtr GlfwMouseWheelCallback -> IO ()+foreign import ccall unsafe glfwGetJoystickParam :: CInt -> CInt -> IO CInt+foreign import ccall unsafe glfwGetJoystickPos :: CInt -> Ptr CFloat -> CInt -> IO CInt+foreign import ccall unsafe glfwGetJoystickButtons :: CInt -> Ptr CUChar -> CInt -> IO CInt++foreign import ccall unsafe glfwGetTime :: IO CDouble+foreign import ccall unsafe glfwSetTime :: CDouble -> IO ()+foreign import ccall unsafe glfwSleep :: CDouble -> IO ()++foreign import ccall unsafe glfwGetGLVersion :: Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()++type GlfwCharCallback = CInt -> CInt -> IO ()+type GlfwKeyCallback = CInt -> CInt -> IO ()+type GlfwMouseButtonCallback = CInt -> CInt -> IO ()+type GlfwMousePositionCallback = CInt -> CInt -> IO ()+type GlfwMouseWheelCallback = CInt -> IO ()+type GlfwWindowCloseCallback = IO CInt+type GlfwWindowRefreshCallback = IO ()+type GlfwWindowSizeCallback = CInt -> CInt -> IO ()++type CharCallback = Char -> Bool -> IO ()+type KeyCallback = Key -> Bool -> IO ()+type MouseButtonCallback = MouseButton -> Bool -> IO ()+type MousePositionCallback = Int -> Int -> IO ()+type MouseWheelCallback = Int -> IO ()+type WindowCloseCallback = IO Bool+type WindowRefreshCallback = IO ()+type WindowSizeCallback = Int -> Int -> IO ()++foreign import ccall unsafe "wrapper" wrapCharCallback :: GlfwCharCallback -> IO (FunPtr GlfwCharCallback)+foreign import ccall unsafe "wrapper" wrapKeyCallback :: GlfwKeyCallback -> IO (FunPtr GlfwKeyCallback)+foreign import ccall unsafe "wrapper" wrapMouseButtonCallback :: GlfwMouseButtonCallback -> IO (FunPtr GlfwMouseButtonCallback)+foreign import ccall unsafe "wrapper" wrapMousePositionCallback :: GlfwMousePositionCallback -> IO (FunPtr GlfwMousePositionCallback)+foreign import ccall unsafe "wrapper" wrapMouseWheelCallback :: GlfwMouseWheelCallback -> IO (FunPtr GlfwMouseWheelCallback)+foreign import ccall unsafe "wrapper" wrapWindowCloseCallback :: GlfwWindowCloseCallback -> IO (FunPtr GlfwWindowCloseCallback)+foreign import ccall unsafe "wrapper" wrapWindowRefreshCallback :: GlfwWindowRefreshCallback -> IO (FunPtr GlfwWindowRefreshCallback)+foreign import ccall unsafe "wrapper" wrapWindowSizeCallback :: GlfwWindowSizeCallback -> IO (FunPtr GlfwWindowSizeCallback)++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Initialization and termination++initialize :: IO Bool+initialize =+ fromC `fmap` glfwInit++terminate :: IO ()+terminate =+ glfwTerminate++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Video mode information++getVideoMode :: IO VideoMode+getVideoMode =+ alloca $ \ptr -> do+ glfwGetDesktopMode ptr+ peek ptr++getVideoModes :: IO [VideoMode]+getVideoModes =+ allocaArray m $ \ptr -> do+ n <- glfwGetVideoModes ptr (toC m)+ peekArray (fromC n) ptr+ where+ m = 256++-- -- -- -- -- -- -- -- -- --++data VideoMode = VideoMode+ { videoMode_width :: Int+ , videoMode_height :: Int+ , videoMode_numRedBits :: Int+ , videoMode_numGreenBits :: Int+ , videoMode_numBlueBits :: Int+ } deriving Show++instance Storable VideoMode where+ sizeOf _ = (#const sizeof(GLFWvidmode))+ alignment _ = alignment (undefined :: CInt)++ peek ptr = do+ w <- (#peek GLFWvidmode, Width) ptr :: IO CInt+ h <- (#peek GLFWvidmode, Height) ptr :: IO CInt+ r <- (#peek GLFWvidmode, RedBits) ptr :: IO CInt+ g <- (#peek GLFWvidmode, GreenBits) ptr :: IO CInt+ b <- (#peek GLFWvidmode, BlueBits) ptr :: IO CInt+ return VideoMode+ { videoMode_width = fromC w+ , videoMode_height = fromC h+ , videoMode_numRedBits = fromC r+ , videoMode_numGreenBits = fromC g+ , videoMode_numBlueBits = fromC b+ }++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Window management++openWindow :: DisplayOptions -> IO Bool+openWindow displayOptions = do+ let DisplayOptions+ { displayOptions_width = _displayOptions_width+ , displayOptions_height = _displayOptions_height+ , displayOptions_numRedBits = _displayOptions_numRedBits+ , displayOptions_numGreenBits = _displayOptions_numGreenBits+ , displayOptions_numBlueBits = _displayOptions_numBlueBits+ , displayOptions_numAlphaBits = _displayOptions_numAlphaBits+ , displayOptions_numDepthBits = _displayOptions_numDepthBits+ , displayOptions_numStencilBits = _displayOptions_numStencilBits+ , displayOptions_displayMode = _displayOptions_displayMode+ , displayOptions_refreshRate = _displayOptions_refreshRate+ , displayOptions_accumNumRedBits = _displayOptions_accumNumRedBits+ , displayOptions_accumNumGreenBits = _displayOptions_accumNumGreenBits+ , displayOptions_accumNumBlueBits = _displayOptions_accumNumBlueBits+ , displayOptions_accumNumAlphaBits = _displayOptions_accumNumAlphaBits+ , displayOptions_numAuxiliaryBuffers = _displayOptions_numAuxiliaryBuffers+ , displayOptions_numFsaaSamples = _displayOptions_numFsaaSamples+ , displayOptions_windowIsResizable = _displayOptions_windowIsResizable+ , displayOptions_stereoRendering = _displayOptions_stereoRendering+ } = displayOptions++ -- Add hints.+ when (isJust _displayOptions_refreshRate) $ glfwOpenWindowHint (#const GLFW_REFRESH_RATE) (toC (fromJust _displayOptions_refreshRate))+ when (isJust _displayOptions_accumNumRedBits) $ glfwOpenWindowHint (#const GLFW_ACCUM_RED_BITS) (toC (fromJust _displayOptions_accumNumRedBits))+ when (isJust _displayOptions_accumNumGreenBits) $ glfwOpenWindowHint (#const GLFW_ACCUM_GREEN_BITS) (toC (fromJust _displayOptions_accumNumGreenBits))+ when (isJust _displayOptions_accumNumBlueBits) $ glfwOpenWindowHint (#const GLFW_ACCUM_BLUE_BITS) (toC (fromJust _displayOptions_accumNumBlueBits))+ when (isJust _displayOptions_accumNumAlphaBits) $ glfwOpenWindowHint (#const GLFW_ACCUM_ALPHA_BITS) (toC (fromJust _displayOptions_accumNumAlphaBits))+ when (isJust _displayOptions_numAuxiliaryBuffers) $ glfwOpenWindowHint (#const GLFW_AUX_BUFFERS) (toC (fromJust _displayOptions_numAuxiliaryBuffers))+ when (isJust _displayOptions_numFsaaSamples) $ glfwOpenWindowHint (#const GLFW_FSAA_SAMPLES) (toC (fromJust _displayOptions_numFsaaSamples))++ glfwOpenWindowHint (#const GLFW_WINDOW_NO_RESIZE) (toC (not _displayOptions_windowIsResizable))+ glfwOpenWindowHint (#const GLFW_STEREO) (toC _displayOptions_stereoRendering)++ -- Open the window.+ fromC `fmap` glfwOpenWindow+ (toC _displayOptions_width)+ (toC _displayOptions_height)+ (toC _displayOptions_numRedBits)+ (toC _displayOptions_numGreenBits)+ (toC _displayOptions_numBlueBits)+ (toC _displayOptions_numAlphaBits)+ (toC _displayOptions_numDepthBits)+ (toC _displayOptions_numStencilBits)+ (toC _displayOptions_displayMode)++closeWindow :: IO ()+closeWindow =+ glfwCloseWindow++setWindowTitle :: String -> IO ()+setWindowTitle t =+ withCString t glfwSetWindowTitle++setWindowDimensions :: Int -> Int -> IO ()+setWindowDimensions w h =+ glfwSetWindowSize (toC w) (toC h)++setWindowPosition :: Int -> Int -> IO ()+setWindowPosition w h =+ glfwSetWindowPos (toC w) (toC h)++iconifyWindow :: IO ()+iconifyWindow =+ glfwIconifyWindow++restoreWindow :: IO ()+restoreWindow =+ glfwRestoreWindow++swapBuffers :: IO ()+swapBuffers =+ glfwSwapBuffers++setWindowBufferSwapInterval :: Int -> IO ()+setWindowBufferSwapInterval =+ glfwSwapInterval . toC++-- -- -- -- -- -- -- -- -- --++data DisplayMode+ = Window+ | Fullscreen+ deriving (Show)++instance C DisplayMode CInt where+ toC dm = case dm of+ Window -> #const GLFW_WINDOW+ Fullscreen -> #const GLFW_FULLSCREEN++ fromC i = case i of+ (#const GLFW_WINDOW ) -> Window+ (#const GLFW_FULLSCREEN) -> Fullscreen+ _ -> makeFromCError "DisplayMode" i++-- -- -- -- -- -- -- -- -- --++data DisplayOptions = DisplayOptions+ { displayOptions_width :: Int+ , displayOptions_height :: Int+ , displayOptions_numRedBits :: Int+ , displayOptions_numGreenBits :: Int+ , displayOptions_numBlueBits :: Int+ , displayOptions_numAlphaBits :: Int+ , displayOptions_numDepthBits :: Int+ , displayOptions_numStencilBits :: Int+ , displayOptions_displayMode :: DisplayMode+ , displayOptions_refreshRate :: Maybe Int+ , displayOptions_accumNumRedBits :: Maybe Int+ , displayOptions_accumNumGreenBits :: Maybe Int+ , displayOptions_accumNumBlueBits :: Maybe Int+ , displayOptions_accumNumAlphaBits :: Maybe Int+ , displayOptions_numAuxiliaryBuffers :: Maybe Int+ , displayOptions_numFsaaSamples :: Maybe Int+ , displayOptions_windowIsResizable :: Bool+ , displayOptions_stereoRendering :: Bool+ } deriving (Show)++defaultDisplayOptions :: DisplayOptions+defaultDisplayOptions =+ DisplayOptions+ { displayOptions_width = 0+ , displayOptions_height = 0+ , displayOptions_numRedBits = 0+ , displayOptions_numGreenBits = 0+ , displayOptions_numBlueBits = 0+ , displayOptions_numAlphaBits = 0+ , displayOptions_numDepthBits = 0+ , displayOptions_numStencilBits = 0+ , displayOptions_displayMode = Window+ , displayOptions_refreshRate = Nothing+ , displayOptions_accumNumRedBits = Nothing+ , displayOptions_accumNumGreenBits = Nothing+ , displayOptions_accumNumBlueBits = Nothing+ , displayOptions_accumNumAlphaBits = Nothing+ , displayOptions_numAuxiliaryBuffers = Nothing+ , displayOptions_numFsaaSamples = Nothing+ , displayOptions_windowIsResizable = True+ , displayOptions_stereoRendering = False+ }++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Window information++windowIsOpen :: IO Bool+windowIsOpen =+ fromC `fmap` glfwGetWindowParam (#const GLFW_OPENED)++windowIsActive :: IO Bool+windowIsActive =+ fromC `fmap` glfwGetWindowParam (#const GLFW_ACTIVE)++windowIsIconified :: IO Bool+windowIsIconified =+ fromC `fmap` glfwGetWindowParam (#const GLFW_ICONIFIED)++windowIsResizable :: IO Bool+windowIsResizable =+ (not . fromC) `fmap` glfwGetWindowParam (#const GLFW_WINDOW_NO_RESIZE)++windowIsHardwareAccelerated :: IO Bool+windowIsHardwareAccelerated =+ fromC `fmap` glfwGetWindowParam (#const GLFW_ACCELERATED)++windowSupportsStereoRendering :: IO Bool+windowSupportsStereoRendering =+ fromC `fmap` glfwGetWindowParam (#const GLFW_STEREO)++getWindowRefreshRate :: IO Int+getWindowRefreshRate =+ fromC `fmap` glfwGetWindowParam (#const GLFW_REFRESH_RATE)++getWindowDimensions :: IO (Int, Int)+getWindowDimensions =+ alloca $ \wp ->+ alloca $ \hp -> do+ glfwGetWindowSize wp hp+ w <- peek wp+ h <- peek hp+ return (fromC w, fromC h)++getWindowValue :: WindowValue -> IO Int+getWindowValue wn =+ fromC `fmap` glfwGetWindowParam (toC wn)++setWindowCloseCallback :: WindowCloseCallback -> IO ()+setWindowCloseCallback cb = do+ ccb <- wrapWindowCloseCallback (toC `fmap` cb)+ glfwSetWindowCloseCallback ccb+ storeCallback windowCloseCallback ccb++setWindowSizeCallback :: WindowSizeCallback -> IO ()+setWindowSizeCallback cb = do+ ccb <- wrapWindowSizeCallback (\w h -> cb (fromC w) (fromC h))+ glfwSetWindowSizeCallback ccb+ storeCallback windowSizeCallback ccb++setWindowRefreshCallback :: WindowRefreshCallback -> IO ()+setWindowRefreshCallback cb = do+ ccb <- wrapWindowRefreshCallback cb+ glfwSetWindowRefreshCallback ccb+ storeCallback windowRefreshCallback ccb++-- -- -- -- -- -- -- -- -- --++data WindowValue+ = NumRedBits+ | NumGreenBits+ | NumBlueBits+ | NumAlphaBits+ | NumDepthBits+ | NumStencilBits+ | NumAccumRedBits+ | NumAccumGreenBits+ | NumAccumBlueBits+ | NumAccumAlphaBits+ | NumAuxBuffers+ | NumFsaaSamples+ deriving (Bounded, Enum, Eq, Show)++instance C WindowValue CInt where+ toC wn = case wn of+ NumRedBits -> #const GLFW_RED_BITS+ NumGreenBits -> #const GLFW_GREEN_BITS+ NumBlueBits -> #const GLFW_BLUE_BITS+ NumAlphaBits -> #const GLFW_ALPHA_BITS+ NumDepthBits -> #const GLFW_DEPTH_BITS+ NumStencilBits -> #const GLFW_STENCIL_BITS+ NumAccumRedBits -> #const GLFW_ACCUM_RED_BITS+ NumAccumGreenBits -> #const GLFW_ACCUM_GREEN_BITS+ NumAccumBlueBits -> #const GLFW_ACCUM_BLUE_BITS+ NumAccumAlphaBits -> #const GLFW_ACCUM_ALPHA_BITS+ NumAuxBuffers -> #const GLFW_AUX_BUFFERS+ NumFsaaSamples -> #const GLFW_FSAA_SAMPLES++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Input++pollEvents :: IO ()+pollEvents =+ glfwPollEvents++waitEvents :: IO ()+waitEvents =+ glfwWaitEvents++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Keyboard++keyIsPressed :: Key -> IO Bool+keyIsPressed k =+ fromC `fmap` glfwGetKey (toC k)++setCharCallback :: CharCallback -> IO ()+setCharCallback cb = do+ ccb <- wrapCharCallback (\c b -> cb (fromC c) (fromC b))+ glfwSetCharCallback ccb+ storeCallback charCallback ccb++setKeyCallback :: KeyCallback -> IO ()+setKeyCallback cb = do+ ccb <- wrapKeyCallback (\k b -> cb (fromC k) (fromC b))+ glfwSetKeyCallback ccb+ storeCallback keyCallback ccb++-- -- -- -- -- -- -- -- -- --++data Key+ = CharKey Char+ | KeyUnknown+ | KeySpace+ | KeySpecial+ | KeyEsc+ | KeyF1+ | KeyF2+ | KeyF3+ | KeyF4+ | KeyF5+ | KeyF6+ | KeyF7+ | KeyF8+ | KeyF9+ | KeyF10+ | KeyF11+ | KeyF12+ | KeyF13+ | KeyF14+ | KeyF15+ | KeyF16+ | KeyF17+ | KeyF18+ | KeyF19+ | KeyF20+ | KeyF21+ | KeyF22+ | KeyF23+ | KeyF24+ | KeyF25+ | KeyUp+ | KeyDown+ | KeyLeft+ | KeyRight+ | KeyLeftShift+ | KeyRightShift+ | KeyLeftCtrl+ | KeyRightCtrl+ | KeyLeftAlt+ | KeyRightAlt+ | KeyTab+ | KeyEnter+ | KeyBackspace+ | KeyInsert+ | KeyDel+ | KeyPageup+ | KeyPagedown+ | KeyHome+ | KeyEnd+ | KeyPad0+ | KeyPad1+ | KeyPad2+ | KeyPad3+ | KeyPad4+ | KeyPad5+ | KeyPad6+ | KeyPad7+ | KeyPad8+ | KeyPad9+ | KeyPadDivide+ | KeyPadMultiply+ | KeyPadSubtract+ | KeyPadAdd+ | KeyPadDecimal+ | KeyPadEqual+ | KeyPadEnter+ deriving (Eq, Show)++instance C Key CInt where+ toC k = case k of+ CharKey c -> fromIntegral (ord c)+ KeyUnknown -> #const GLFW_KEY_UNKNOWN+ KeySpace -> #const GLFW_KEY_SPACE+ KeySpecial -> #const GLFW_KEY_SPECIAL+ KeyEsc -> #const GLFW_KEY_ESC+ KeyF1 -> #const GLFW_KEY_F1+ KeyF2 -> #const GLFW_KEY_F2+ KeyF3 -> #const GLFW_KEY_F3+ KeyF4 -> #const GLFW_KEY_F4+ KeyF5 -> #const GLFW_KEY_F5+ KeyF6 -> #const GLFW_KEY_F6+ KeyF7 -> #const GLFW_KEY_F7+ KeyF8 -> #const GLFW_KEY_F8+ KeyF9 -> #const GLFW_KEY_F9+ KeyF10 -> #const GLFW_KEY_F10+ KeyF11 -> #const GLFW_KEY_F11+ KeyF12 -> #const GLFW_KEY_F12+ KeyF13 -> #const GLFW_KEY_F13+ KeyF14 -> #const GLFW_KEY_F14+ KeyF15 -> #const GLFW_KEY_F15+ KeyF16 -> #const GLFW_KEY_F16+ KeyF17 -> #const GLFW_KEY_F17+ KeyF18 -> #const GLFW_KEY_F18+ KeyF19 -> #const GLFW_KEY_F19+ KeyF20 -> #const GLFW_KEY_F20+ KeyF21 -> #const GLFW_KEY_F21+ KeyF22 -> #const GLFW_KEY_F22+ KeyF23 -> #const GLFW_KEY_F23+ KeyF24 -> #const GLFW_KEY_F24+ KeyF25 -> #const GLFW_KEY_F25+ KeyUp -> #const GLFW_KEY_UP+ KeyDown -> #const GLFW_KEY_DOWN+ KeyLeft -> #const GLFW_KEY_LEFT+ KeyRight -> #const GLFW_KEY_RIGHT+ KeyLeftShift -> #const GLFW_KEY_LSHIFT+ KeyRightShift -> #const GLFW_KEY_RSHIFT+ KeyLeftCtrl -> #const GLFW_KEY_LCTRL+ KeyRightCtrl -> #const GLFW_KEY_RCTRL+ KeyLeftAlt -> #const GLFW_KEY_LALT+ KeyRightAlt -> #const GLFW_KEY_RALT+ KeyTab -> #const GLFW_KEY_TAB+ KeyEnter -> #const GLFW_KEY_ENTER+ KeyBackspace -> #const GLFW_KEY_BACKSPACE+ KeyInsert -> #const GLFW_KEY_INSERT+ KeyDel -> #const GLFW_KEY_DEL+ KeyPageup -> #const GLFW_KEY_PAGEUP+ KeyPagedown -> #const GLFW_KEY_PAGEDOWN+ KeyHome -> #const GLFW_KEY_HOME+ KeyEnd -> #const GLFW_KEY_END+ KeyPad0 -> #const GLFW_KEY_KP_0+ KeyPad1 -> #const GLFW_KEY_KP_1+ KeyPad2 -> #const GLFW_KEY_KP_2+ KeyPad3 -> #const GLFW_KEY_KP_3+ KeyPad4 -> #const GLFW_KEY_KP_4+ KeyPad5 -> #const GLFW_KEY_KP_5+ KeyPad6 -> #const GLFW_KEY_KP_6+ KeyPad7 -> #const GLFW_KEY_KP_7+ KeyPad8 -> #const GLFW_KEY_KP_8+ KeyPad9 -> #const GLFW_KEY_KP_9+ KeyPadDivide -> #const GLFW_KEY_KP_DIVIDE+ KeyPadMultiply -> #const GLFW_KEY_KP_MULTIPLY+ KeyPadSubtract -> #const GLFW_KEY_KP_SUBTRACT+ KeyPadAdd -> #const GLFW_KEY_KP_ADD+ KeyPadDecimal -> #const GLFW_KEY_KP_DECIMAL+ KeyPadEqual -> #const GLFW_KEY_KP_EQUAL+ KeyPadEnter -> #const GLFW_KEY_KP_ENTER++ fromC i =+ if i < #const GLFW_KEY_SPECIAL+ then CharKey (chr (fromIntegral i))+ else case i of+ (#const GLFW_KEY_UNKNOWN ) -> KeyUnknown+ (#const GLFW_KEY_SPACE ) -> KeySpace+ (#const GLFW_KEY_SPECIAL ) -> KeySpecial+ (#const GLFW_KEY_ESC ) -> KeyEsc+ (#const GLFW_KEY_F1 ) -> KeyF1+ (#const GLFW_KEY_F2 ) -> KeyF2+ (#const GLFW_KEY_F3 ) -> KeyF3+ (#const GLFW_KEY_F4 ) -> KeyF4+ (#const GLFW_KEY_F5 ) -> KeyF5+ (#const GLFW_KEY_F6 ) -> KeyF6+ (#const GLFW_KEY_F7 ) -> KeyF7+ (#const GLFW_KEY_F8 ) -> KeyF8+ (#const GLFW_KEY_F9 ) -> KeyF9+ (#const GLFW_KEY_F10 ) -> KeyF10+ (#const GLFW_KEY_F11 ) -> KeyF11+ (#const GLFW_KEY_F12 ) -> KeyF12+ (#const GLFW_KEY_F13 ) -> KeyF13+ (#const GLFW_KEY_F14 ) -> KeyF14+ (#const GLFW_KEY_F15 ) -> KeyF15+ (#const GLFW_KEY_F16 ) -> KeyF16+ (#const GLFW_KEY_F17 ) -> KeyF17+ (#const GLFW_KEY_F18 ) -> KeyF18+ (#const GLFW_KEY_F19 ) -> KeyF19+ (#const GLFW_KEY_F20 ) -> KeyF20+ (#const GLFW_KEY_F21 ) -> KeyF21+ (#const GLFW_KEY_F22 ) -> KeyF22+ (#const GLFW_KEY_F23 ) -> KeyF23+ (#const GLFW_KEY_F24 ) -> KeyF24+ (#const GLFW_KEY_F25 ) -> KeyF25+ (#const GLFW_KEY_UP ) -> KeyUp+ (#const GLFW_KEY_DOWN ) -> KeyDown+ (#const GLFW_KEY_LEFT ) -> KeyLeft+ (#const GLFW_KEY_RIGHT ) -> KeyRight+ (#const GLFW_KEY_LSHIFT ) -> KeyLeftShift+ (#const GLFW_KEY_RSHIFT ) -> KeyRightShift+ (#const GLFW_KEY_LCTRL ) -> KeyLeftCtrl+ (#const GLFW_KEY_RCTRL ) -> KeyRightCtrl+ (#const GLFW_KEY_LALT ) -> KeyLeftAlt+ (#const GLFW_KEY_RALT ) -> KeyRightAlt+ (#const GLFW_KEY_TAB ) -> KeyTab+ (#const GLFW_KEY_ENTER ) -> KeyEnter+ (#const GLFW_KEY_BACKSPACE ) -> KeyBackspace+ (#const GLFW_KEY_INSERT ) -> KeyInsert+ (#const GLFW_KEY_DEL ) -> KeyDel+ (#const GLFW_KEY_PAGEUP ) -> KeyPageup+ (#const GLFW_KEY_PAGEDOWN ) -> KeyPagedown+ (#const GLFW_KEY_HOME ) -> KeyHome+ (#const GLFW_KEY_END ) -> KeyEnd+ (#const GLFW_KEY_KP_0 ) -> KeyPad0+ (#const GLFW_KEY_KP_1 ) -> KeyPad1+ (#const GLFW_KEY_KP_2 ) -> KeyPad2+ (#const GLFW_KEY_KP_3 ) -> KeyPad3+ (#const GLFW_KEY_KP_4 ) -> KeyPad4+ (#const GLFW_KEY_KP_5 ) -> KeyPad5+ (#const GLFW_KEY_KP_6 ) -> KeyPad6+ (#const GLFW_KEY_KP_7 ) -> KeyPad7+ (#const GLFW_KEY_KP_8 ) -> KeyPad8+ (#const GLFW_KEY_KP_9 ) -> KeyPad9+ (#const GLFW_KEY_KP_DIVIDE ) -> KeyPadDivide+ (#const GLFW_KEY_KP_MULTIPLY) -> KeyPadMultiply+ (#const GLFW_KEY_KP_SUBTRACT) -> KeyPadSubtract+ (#const GLFW_KEY_KP_ADD ) -> KeyPadAdd+ (#const GLFW_KEY_KP_DECIMAL ) -> KeyPadDecimal+ (#const GLFW_KEY_KP_EQUAL ) -> KeyPadEqual+ (#const GLFW_KEY_KP_ENTER ) -> KeyPadEnter+ _ -> KeyUnknown++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Mouse++mouseButtonIsPressed :: MouseButton -> IO Bool+mouseButtonIsPressed mb =+ fromC `fmap` glfwGetMouseButton (toC mb)++getMousePosition :: IO (Int, Int)+getMousePosition =+ alloca $ \px ->+ alloca $ \py -> do+ glfwGetMousePos px py+ x <- peek px+ y <- peek py+ return (fromC x, fromC y)++getMouseWheel :: IO Int+getMouseWheel =+ fromC `fmap` glfwGetMouseWheel++setMousePosition :: Int -> Int -> IO ()+setMousePosition x y =+ glfwSetMousePos (toC x) (toC y)++setMouseWheel :: Int -> IO ()+setMouseWheel =+ glfwSetMouseWheel . toC++setMouseButtonCallback :: MouseButtonCallback -> IO ()+setMouseButtonCallback cb = do+ ccb <- wrapMouseButtonCallback (\b p -> cb (fromC b) (fromC p))+ glfwSetMouseButtonCallback ccb+ storeCallback mouseButtonCallback ccb++setMousePositionCallback :: MousePositionCallback -> IO ()+setMousePositionCallback cb = do+ ccb <- wrapMousePositionCallback (\x y -> cb (fromC x) (fromC y))+ glfwSetMousePosCallback ccb+ storeCallback mousePositionCallback ccb++setMouseWheelCallback :: MouseWheelCallback -> IO ()+setMouseWheelCallback cb = do+ ccb <- wrapMouseWheelCallback (cb . fromC)+ glfwSetMouseWheelCallback ccb+ storeCallback mouseWheelCallback ccb++-- -- -- -- -- -- -- -- -- --++data MouseButton+ = MouseButton0 | MouseButton1 | MouseButton2 | MouseButton3+ | MouseButton4 | MouseButton5 | MouseButton6 | MouseButton7+ deriving (Bounded, Enum, Eq, Show)++instance C MouseButton CInt where+ toC mb = case mb of+ MouseButton0 -> #const GLFW_MOUSE_BUTTON_1+ MouseButton1 -> #const GLFW_MOUSE_BUTTON_2+ MouseButton2 -> #const GLFW_MOUSE_BUTTON_3+ MouseButton3 -> #const GLFW_MOUSE_BUTTON_4+ MouseButton4 -> #const GLFW_MOUSE_BUTTON_5+ MouseButton5 -> #const GLFW_MOUSE_BUTTON_6+ MouseButton6 -> #const GLFW_MOUSE_BUTTON_7+ MouseButton7 -> #const GLFW_MOUSE_BUTTON_8++ fromC i = case i of+ (#const GLFW_MOUSE_BUTTON_1) -> MouseButton0+ (#const GLFW_MOUSE_BUTTON_2) -> MouseButton1+ (#const GLFW_MOUSE_BUTTON_3) -> MouseButton2+ (#const GLFW_MOUSE_BUTTON_4) -> MouseButton3+ (#const GLFW_MOUSE_BUTTON_5) -> MouseButton4+ (#const GLFW_MOUSE_BUTTON_6) -> MouseButton5+ (#const GLFW_MOUSE_BUTTON_7) -> MouseButton6+ (#const GLFW_MOUSE_BUTTON_8) -> MouseButton7+ _ -> makeFromCError "MouseButton" i++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Joystick++joystickIsPresent :: Joystick -> IO Bool+joystickIsPresent j =+ fromC `fmap` glfwGetJoystickParam (toC j) (#const GLFW_PRESENT)++getNumJoystickAxes :: Joystick -> IO Int+getNumJoystickAxes j =+ fromC `fmap` glfwGetJoystickParam (toC j) (#const GLFW_AXES)++getNumJoystickButtons :: Joystick -> IO Int+getNumJoystickButtons j =+ fromC `fmap` glfwGetJoystickParam (toC j) (#const GLFW_BUTTONS)++getJoystickPosition :: Joystick -> Int -> IO [Float]+getJoystickPosition j m =+ if m < 1+ then return []+ else allocaArray m $ \ptr -> do+ n <- fromC `fmap` glfwGetJoystickPos (toC j) ptr (toC m)+ a <- peekArray n ptr+ return $ map fromC a++joystickButtonsArePressed :: Joystick -> Int -> IO [Bool]+joystickButtonsArePressed j m =+ if m < 1+ then return []+ else allocaArray m $ \ptr -> do+ n <- fromC `fmap` glfwGetJoystickButtons (toC j) ptr (toC m)+ a <- peekArray n ptr :: IO [CUChar]+ return $ map ((glfwPress ==) . fromIntegral) a++-- -- -- -- -- -- -- -- -- --++data Joystick+ = Joystick0 | Joystick1 | Joystick2 | Joystick3+ | Joystick4 | Joystick5 | Joystick6 | Joystick7+ | Joystick8 | Joystick9 | Joystick10 | Joystick11+ | Joystick12 | Joystick13 | Joystick14 | Joystick15+ deriving (Bounded, Enum, Eq, Show)++instance C Joystick CInt where+ toC j = case j of+ Joystick0 -> #const GLFW_JOYSTICK_1+ Joystick1 -> #const GLFW_JOYSTICK_2+ Joystick2 -> #const GLFW_JOYSTICK_3+ Joystick3 -> #const GLFW_JOYSTICK_4+ Joystick4 -> #const GLFW_JOYSTICK_5+ Joystick5 -> #const GLFW_JOYSTICK_6+ Joystick6 -> #const GLFW_JOYSTICK_7+ Joystick7 -> #const GLFW_JOYSTICK_8+ Joystick8 -> #const GLFW_JOYSTICK_9+ Joystick9 -> #const GLFW_JOYSTICK_10+ Joystick10 -> #const GLFW_JOYSTICK_11+ Joystick11 -> #const GLFW_JOYSTICK_12+ Joystick12 -> #const GLFW_JOYSTICK_13+ Joystick13 -> #const GLFW_JOYSTICK_14+ Joystick14 -> #const GLFW_JOYSTICK_15+ Joystick15 -> #const GLFW_JOYSTICK_16++ fromC i = case i of+ (#const GLFW_JOYSTICK_1 ) -> Joystick0+ (#const GLFW_JOYSTICK_2 ) -> Joystick1+ (#const GLFW_JOYSTICK_3 ) -> Joystick2+ (#const GLFW_JOYSTICK_4 ) -> Joystick3+ (#const GLFW_JOYSTICK_5 ) -> Joystick4+ (#const GLFW_JOYSTICK_6 ) -> Joystick5+ (#const GLFW_JOYSTICK_7 ) -> Joystick6+ (#const GLFW_JOYSTICK_8 ) -> Joystick7+ (#const GLFW_JOYSTICK_9 ) -> Joystick8+ (#const GLFW_JOYSTICK_10) -> Joystick9+ (#const GLFW_JOYSTICK_11) -> Joystick10+ (#const GLFW_JOYSTICK_12) -> Joystick11+ (#const GLFW_JOYSTICK_13) -> Joystick12+ (#const GLFW_JOYSTICK_14) -> Joystick13+ (#const GLFW_JOYSTICK_15) -> Joystick14+ (#const GLFW_JOYSTICK_16) -> Joystick15+ _ -> makeFromCError "Joystick" i++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Time++getTime :: IO Double+getTime =+ realToFrac `fmap` glfwGetTime++setTime :: Double -> IO ()+setTime =+ glfwSetTime . realToFrac++resetTime :: IO ()+resetTime =+ setTime (0 :: Double)++sleep :: Double -> IO ()+sleep =+ glfwSleep . realToFrac++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Version information++getGlfwVersion :: IO Version+getGlfwVersion =+ alloca $ \p0 ->+ alloca $ \p1 ->+ alloca $ \p2 -> do+ glfwGetVersion p0 p1 p2+ v0 <- fromC `fmap` peek p0+ v1 <- fromC `fmap` peek p1+ v2 <- fromC `fmap` peek p2+ return $ Version [v0, v1, v2] []++getGlVersion :: IO Version+getGlVersion =+ alloca $ \p0 ->+ alloca $ \p1 ->+ alloca $ \p2 -> do+ glfwGetGLVersion p0 p1 p2+ v0 <- fromC `fmap` peek p0+ v1 <- fromC `fmap` peek p1+ v2 <- fromC `fmap` peek p2+ return $ Version [v0, v1, v2] []++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++glfwPress :: CInt+glfwPress = #const GLFW_PRESS++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++class C h c where+ toC :: h -> c+ fromC :: c -> h++ toC = undefined+ fromC = undefined++makeFromCError :: (Show c) => String -> c -> a+makeFromCError s c = error (s ++ " fromC: no match for " ++ show c)++-- -- -- -- -- -- -- -- -- --++instance C Bool CInt where+ toC False = #const GL_FALSE+ toC True = #const GL_TRUE++ fromC (#const GL_FALSE) = False+ fromC (#const GL_TRUE) = True+ fromC i = makeFromCError "Bool" i++-- -- -- -- -- -- -- -- -- --++instance C Char CInt where+ toC = fromIntegral . ord+ fromC = chr . fromIntegral++-- -- -- -- -- -- -- -- -- --++instance C Float CFloat where+ toC = realToFrac+ fromC = realToFrac++-- -- -- -- -- -- -- -- -- --++instance C Int CInt where+ toC = fromIntegral+ fromC = fromIntegral++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++charCallback :: IORef (Maybe (FunPtr GlfwCharCallback))+keyCallback :: IORef (Maybe (FunPtr GlfwKeyCallback))+mouseButtonCallback :: IORef (Maybe (FunPtr GlfwMouseButtonCallback))+mousePositionCallback :: IORef (Maybe (FunPtr GlfwMousePositionCallback))+mouseWheelCallback :: IORef (Maybe (FunPtr GlfwMouseWheelCallback))+windowCloseCallback :: IORef (Maybe (FunPtr GlfwWindowCloseCallback))+windowRefreshCallback :: IORef (Maybe (FunPtr GlfwWindowRefreshCallback))+windowSizeCallback :: IORef (Maybe (FunPtr GlfwWindowSizeCallback))++charCallback = unsafePerformIO (newIORef Nothing)+keyCallback = unsafePerformIO (newIORef Nothing)+mouseButtonCallback = unsafePerformIO (newIORef Nothing)+mousePositionCallback = unsafePerformIO (newIORef Nothing)+mouseWheelCallback = unsafePerformIO (newIORef Nothing)+windowCloseCallback = unsafePerformIO (newIORef Nothing)+windowRefreshCallback = unsafePerformIO (newIORef Nothing)+windowSizeCallback = unsafePerformIO (newIORef Nothing)++storeCallback :: IORef (Maybe (FunPtr a)) -> FunPtr a -> IO ()+storeCallback ior cb =+ atomicModifyIORef ior (\mcb -> (Just cb, mcb)) >>= maybe (return ()) freeHaskellFunPtr