Merge branch 'master' into EGL

Conflicts:
	CMakeLists.txt
	include/GL/glfw3.h
	readme.html
	src/CMakeLists.txt
	src/internal.h
	src/window.c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8d68b4c..c35ccc2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,6 +12,7 @@
 
 option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON)
 option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
+option(GLFW_NATIVE_API "Build the GLFW native API" OFF)
 option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
 option(GLFW_USE_EGL "Build for EGL and OpenGL ES platform (Currently only X11)" OFF)
 
@@ -22,7 +23,10 @@
     find_package(OpenGL REQUIRED)
 endif()
 
-set(CMAKE_THREAD_PREFER_PTHREADS YES)
+if (NOT WIN32)
+    set(CMAKE_THREAD_PREFER_PTHREADS YES)
+endif()
+
 find_package(Threads)
 if (CMAKE_THREAD_LIBS_INIT)
     list(APPEND glfw_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
@@ -214,6 +218,10 @@
         endif()
     endif()
 
+    if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+        set(_GLFW_HAS_LINUX_JOYSTICKS 1)
+    endif()
+
 endif()
 
 #--------------------------------------------------------------------
@@ -258,6 +266,10 @@
         endif()
     endif()
 
+    if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+        set(_GLFW_HAS_LINUX_JOYSTICKS 1)
+    endif()
+
 endif()
 
 #--------------------------------------------------------------------
@@ -332,7 +344,12 @@
 # The src directory's CMakeLists.txt file installs the library
 #--------------------------------------------------------------------
 install(DIRECTORY include/GL DESTINATION include 
-        FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
+        FILES_MATCHING PATTERN glfw3.h)
+
+if (GLFW_NATIVE_API)
+    install(DIRECTORY include/GL DESTINATION include 
+            FILES_MATCHING PATTERN glfw3native.h)
+endif()
 
 install(FILES COPYING.txt readme.html 
         DESTINATION share/doc/glfw-${GLFW_VERSION_FULL})
diff --git a/examples/heightmap.c b/examples/heightmap.c
index fce8b8d..5139a49 100644
--- a/examples/heightmap.c
+++ b/examples/heightmap.c
@@ -581,7 +581,7 @@
         exit(EXIT_FAILURE);
     }
 
-    glfwWindowHint(GLFW_WINDOW_RESIZABLE, GL_FALSE);
+    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
     glfwWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
     glfwWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index c0d638b..31d7676 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -401,19 +401,20 @@
 #define GLFW_ACCUM_ALPHA_BITS     0x0002100A
 #define GLFW_AUX_BUFFERS          0x0002100B
 #define GLFW_STEREO               0x0002100C
-#define GLFW_WINDOW_RESIZABLE     0x0002100D
 #define GLFW_FSAA_SAMPLES         0x0002100E
 
 /* The following constants are used with both glfwGetWindowParam
  * and glfwWindowHint
  */
-#define GLFW_CLIENT_API           0x0002100F
-#define GLFW_OPENGL_VERSION_MAJOR 0x00021010
-#define GLFW_OPENGL_VERSION_MINOR 0x00021011
-#define GLFW_OPENGL_FORWARD_COMPAT 0x00021012
-#define GLFW_OPENGL_DEBUG_CONTEXT 0x00021013
-#define GLFW_OPENGL_PROFILE       0x00021014
-#define GLFW_OPENGL_ROBUSTNESS    0x00021015
+#define GLFW_CLIENT_API           0x00022000
+#define GLFW_OPENGL_VERSION_MAJOR 0x00022001
+#define GLFW_OPENGL_VERSION_MINOR 0x00022002
+#define GLFW_OPENGL_FORWARD_COMPAT 0x00022003
+#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022004
+#define GLFW_OPENGL_PROFILE       0x00022005
+#define GLFW_OPENGL_ROBUSTNESS    0x00022006
+#define GLFW_RESIZABLE            0x00022007
+#define GLFW_VISIBLE              0x00022008
 
 /* GLFW_CLIENT_API tokens */
 #define GLFW_OPENGL_API           0x00000001
@@ -540,6 +541,8 @@
 GLFWAPI void glfwSetWindowPos(GLFWwindow window, int xpos, int ypos);
 GLFWAPI void glfwIconifyWindow(GLFWwindow window);
 GLFWAPI void glfwRestoreWindow(GLFWwindow window);
+GLFWAPI void glfwShowWindow(GLFWwindow window);
+GLFWAPI void glfwHideWindow(GLFWwindow window);
 GLFWAPI int  glfwGetWindowParam(GLFWwindow window, int param);
 GLFWAPI void glfwSetWindowUserPointer(GLFWwindow window, void* pointer);
 GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow window);
diff --git a/readme.html b/readme.html
index 0de14bd..404c515 100644
--- a/readme.html
+++ b/readme.html
@@ -284,6 +284,7 @@
   <li>Added <code>GLFW_OPENGL_REVISION</code> window parameter to make up for removal of <code>glfwGetGLVersion</code></li>
   <li>Added <code>GLFW_INCLUDE_GL3</code> macro for telling the GLFW header to include <code>gl3.h</code> header instead of <code>gl.h</code></li>
   <li>Added <code>GLFW_INCLUDE_ES2</code> macro for telling the GLFW header to include the OpenGL ES 2.0 header instead of <code>gl.h</code></li>
+  <li>Added <code>GLFW_VISIBLE</code> window hint and parameter for controlling and polling window visibility</li>
   <li>Added <code>windows</code> simple multi-window test program</li>
   <li>Added <code>sharing</code> simple OpenGL object sharing test program</li>
   <li>Added <code>modes</code> video mode enumeration and setting test program</li>
@@ -298,7 +299,7 @@
   <li>Renamed <code>glfw.h</code> to <code>glfw3.h</code> to avoid conflicts with 2.x series</li>
   <li>Renamed <code>glfwOpenWindowHint</code> to <code>glfwWindowHint</code></li>
   <li>Renamed <code>GLFW_WINDOW</code> token to <code>GLFW_WINDOWED</code></li>
-  <li>Renamed <code>GLFW_WINDOW_NO_RESIZE</code> to <code>GLFW_WINDOW_RESIZABLE</code></li>
+  <li>Renamed <code>GLFW_WINDOW_NO_RESIZE</code> to <code>GLFW_RESIZABLE</code></li>
   <li>Renamed <code>GLFW_BUILD_DLL</code> to <code>_GLFW_BUILD_DLL</code></li>
   <li>Renamed <code>version</code> test to <code>glfwinfo</code></li>
   <li>Renamed <code>GLFW_NO_GLU</code> to <code>GLFW_INCLUDE_GLU</code> and made it disabled by default</li>
@@ -931,8 +932,9 @@
   <li>Arturo J. Pérez, for a bug fix for cursor tracking on Mac OS X 10.6 Snow
   Leopard</li>
 
-  <li>Riku Salminen, for making the X11 event processing able to support
-  multi-threaded rendering</li>
+  <li>Riku Salminen, for the initial implementation of
+  <code>glfwShowWindow</code> and <code>glfwHideWindow</code>, and for making
+  the X11 event processing able to support multi-threaded rendering</li>
 
   <li>Douglas C. Schmidt and Irfan Pyarali, for their excellent article
   <a href="http://www.cs.wustl.edu/~schmidt/win32-cv-1.html">Strategies for Implementing POSIX Condition Variables on Win32</a></li>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 044ebbd..b9bd0c7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,7 +10,11 @@
     set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
     set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m
                      cocoa_gamma.c cocoa_init.m cocoa_input.m cocoa_joystick.m
-                     cocoa_native.m cocoa_opengl.m cocoa_time.c cocoa_window.m)
+                     cocoa_opengl.m cocoa_time.c cocoa_window.m)
+
+    if (GLFW_NATIVE_API)
+        list(APPEND glfw_SOURCES cocoa_native.m)
+    endif()
 
     # For some reason, CMake doesn't know about .m
     set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
@@ -18,14 +22,21 @@
     set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
     set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c
                      win32_gamma.c win32_init.c win32_input.c win32_joystick.c
-                     win32_native.c win32_opengl.c win32_time.c win32_window.c
-                     win32_dllmain.c)
+                     win32_opengl.c win32_time.c win32_window.c)
+
+    if (GLFW_NATIVE_API)
+        list(APPEND glfw_SOURCES win32_native.c)
+    endif()
 elseif (_GLFW_X11_GLX)
     set(glfw_HEADERS ${common_HEADERS} x11_platform.h glx_platform.h)
     set(glfw_SOURCES ${common_SOURCES} glx_opengl.c x11_clipboard.c
                      x11_fullscreen.c x11_gamma.c x11_init.c x11_input.c
-                     x11_joystick.c x11_keysym2unicode.c x11_native.c x11_time.c
+                     x11_joystick.c x11_keysym2unicode.c x11_time.c
                      x11_window.c)
+
+    if (GLFW_NATIVE_API)
+        list(APPEND glfw_SOURCES x11_native.c)
+    endif()
 elseif (_GLFW_X11_EGL)
     set(glfw_HEADERS ${common_HEADERS} x11_platform.h egl_platform.h)
     set(glfw_SOURCES ${common_SOURCES} egl_opengl.c x11_clipboard.c
diff --git a/src/cocoa_window.m b/src/cocoa_window.m
index 337dace..ed10d38 100644
--- a/src/cocoa_window.m
+++ b/src/cocoa_window.m
@@ -131,6 +131,25 @@
     return NSTerminateCancel;
 }
 
+- (void)applicationDidHide:(NSNotification *)notification
+{
+    _GLFWwindow* window;
+
+    for (window = _glfwLibrary.windowListHead;  window;  window = window->next)
+        _glfwInputWindowVisibility(window, GL_FALSE);
+}
+
+- (void)applicationDidUnhide:(NSNotification *)notification
+{
+    _GLFWwindow* window;
+
+    for (window = _glfwLibrary.windowListHead;  window;  window = window->next)
+    {
+        if ([window->NS.object isVisible])
+            _glfwInputWindowVisibility(window, GL_TRUE);
+    }
+}
+
 @end
 
 
@@ -905,7 +924,6 @@
     if (!createContext(window, wndconfig, fbconfig))
         return GL_FALSE;
 
-    [window->NS.object makeKeyAndOrderFront:nil];
     [window->NSGL.context setView:[window->NS.object contentView]];
 
     if (wndconfig->mode == GLFW_FULLSCREEN)
@@ -920,6 +938,7 @@
             return GL_FALSE;
         }
 
+        _glfwPlatformShowWindow(window);
         [[window->NS.object contentView] enterFullScreenMode:[NSScreen mainScreen]
                                                  withOptions:nil];
     }
@@ -1030,6 +1049,27 @@
 
 
 //========================================================================
+// Show window
+//========================================================================
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+    [window->NS.object makeKeyAndOrderFront:nil];
+    _glfwInputWindowVisibility(window, GL_TRUE);
+}
+
+
+//========================================================================
+// Hide window
+//========================================================================
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+    [window->NS.object orderOut:nil];
+    _glfwInputWindowVisibility(window, GL_FALSE);
+}
+
+//========================================================================
 // Write back window parameters into GLFW window structure
 //========================================================================
 
diff --git a/src/config.h.in b/src/config.h.in
index ceb7e5a..6d8811c 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -69,7 +69,7 @@
 #cmakedefine _GLFW_HAS_EGLGETPROCADDRESS 1
 
 // Define this to 1 if the Linux joystick API is available
-#cmakedefine _GLFW_USE_LINUX_JOYSTICKS
+#cmakedefine _GLFW_HAS_LINUX_JOYSTICKS
 
 // The GLFW version as used by glfwGetVersionString
 #define _GLFW_VERSION_FULL "@GLFW_VERSION_FULL@"
diff --git a/src/fullscreen.c b/src/fullscreen.c
index 4372d15..f59046d 100644
--- a/src/fullscreen.c
+++ b/src/fullscreen.c
@@ -32,7 +32,7 @@
 #include "internal.h"
 
 #include <stdlib.h>
-#if _WIN32
+#if defined(_MSC_VER)
  #include <malloc.h>
 #endif
 
diff --git a/src/gamma.c b/src/gamma.c
index 21940b0..eed0b66 100644
--- a/src/gamma.c
+++ b/src/gamma.c
@@ -61,18 +61,15 @@
 
     for (i = 0;  i < size;  i++)
     {
-        float value = (float) i / ((float) (size - 1));
+        float value;
 
-        // Apply gamma
+        // Calculate intensity
+        value = (float) i / (float) (size - 1);
+        // Apply gamma curve
         value = (float) pow(value, 1.f / gamma) * 65535.f + 0.5f;
+        // Clamp to value range
+        value = (float) fmax(fmin(value, 65535.f), 0.f);
 
-        // Clamp values
-        if (value < 0.f)
-            value = 0.f;
-        else if (value > 65535.f)
-            value = 65535.f;
-
-        // Set the gamma ramp values
         ramp.red[i]   = (unsigned short) value;
         ramp.green[i] = (unsigned short) value;
         ramp.blue[i]  = (unsigned short) value;
diff --git a/src/internal.h b/src/internal.h
index 75aa4eb..5499d4f 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -98,6 +98,7 @@
     int         auxBuffers;
     GLboolean   stereo;
     GLboolean   resizable;
+    GLboolean   visible;
     int         samples;
     int         clientAPI;
     int         glMajor;
@@ -121,6 +122,7 @@
     const char*   title;
     int           refreshRate;
     GLboolean     resizable;
+    GLboolean     visible;
     int           clientAPI;
     int           glMajor;
     int           glMinor;
@@ -172,6 +174,7 @@
     int       positionX, positionY;
     int       mode;            // GLFW_WINDOW or GLFW_FULLSCREEN
     GLboolean resizable;       // GL_TRUE if user may resize this window
+    GLboolean visible;         // GL_TRUE if this window is visible
     int       refreshRate;     // monitor refresh rate
     void*     userPointer;
 
@@ -290,6 +293,8 @@
 void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y);
 void _glfwPlatformIconifyWindow(_GLFWwindow* window);
 void _glfwPlatformRestoreWindow(_GLFWwindow* window);
+void _glfwPlatformShowWindow(_GLFWwindow* window);
+void _glfwPlatformHideWindow(_GLFWwindow* window);
 
 // Event processing
 void _glfwPlatformPollEvents(void);
@@ -318,6 +323,7 @@
 void _glfwInputWindowPos(_GLFWwindow* window, int x, int y);
 void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
 void _glfwInputWindowIconify(_GLFWwindow* window, int iconified);
+void _glfwInputWindowVisibility(_GLFWwindow* window, int visible);
 void _glfwInputWindowDamage(_GLFWwindow* window);
 void _glfwInputWindowCloseRequest(_GLFWwindow* window);
 
diff --git a/src/win32_dllmain.c b/src/win32_dllmain.c
deleted file mode 100644
index 98f9ab2..0000000
--- a/src/win32_dllmain.c
+++ /dev/null
@@ -1,49 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL library
-// Platform:    Win32
-// API version: 3.0
-// WWW:         http://www.glfw.org/
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Marcus Geelnard
-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-
-#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)!
-
-    return TRUE;
-}
-
-#endif // _GLFW_BUILD_DLL
-
diff --git a/src/win32_init.c b/src/win32_init.c
index 41444b9..21de415 100644
--- a/src/win32_init.c
+++ b/src/win32_init.c
@@ -40,6 +40,18 @@
 
 
 //========================================================================
+// GLFW DLL entry point
+//========================================================================
+
+#if defined(_GLFW_BUILD_DLL)
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+    return TRUE;
+}
+#endif // _GLFW_BUILD_DLL
+
+
+//========================================================================
 // Load necessary libraries (DLLs)
 //========================================================================
 
diff --git a/src/win32_window.c b/src/win32_window.c
index feccb83..6b27547 100644
--- a/src/win32_window.c
+++ b/src/win32_window.c
@@ -33,95 +33,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <malloc.h>
-
-
-//========================================================================
-// 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 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
-    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);
-}
-
+#include <windowsx.h>
 
 //========================================================================
 // Hide mouse cursor
@@ -394,37 +306,6 @@
 
 
 //========================================================================
-// Translates a Windows key to Unicode
-//========================================================================
-
-static void translateChar(_GLFWwindow* window, DWORD wParam, DWORD lParam)
-{
-    BYTE keyboard_state[256];
-    WCHAR unicode_buf[10];
-    UINT scan_code;
-    int i, num_chars;
-
-    GetKeyboardState(keyboard_state);
-
-    // Derive scan code from lParam and action
-    scan_code = (lParam & 0x01ff0000) >> 16;
-
-    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
-    );
-
-    // Report characters
-    for (i = 0;  i < num_chars;  i++)
-        _glfwInputChar(window, (int) unicode_buf[i]);
-}
-
-
-//========================================================================
 // Window callback function (handles window events)
 //========================================================================
 
@@ -507,6 +388,12 @@
             return 0;
         }
 
+        case WM_SHOWWINDOW:
+        {
+            _glfwInputWindowVisibility(window, wParam ? GL_TRUE : GL_FALSE);
+            break;
+        }
+
         case WM_SYSCOMMAND:
         {
             switch (wParam & 0xfff0)
@@ -541,13 +428,15 @@
         case WM_SYSKEYDOWN:
         {
             _glfwInputKey(window, translateKey(wParam, lParam), GLFW_PRESS);
-
-            if (_glfwLibrary.charCallback)
-                translateChar(window, (DWORD) wParam, (DWORD) lParam);
-
             break;
         }
 
+        case WM_CHAR:
+        {
+            _glfwInputChar(window, wParam);
+            return 0;
+        }
+
         case WM_KEYUP:
         case WM_SYSKEYUP:
         {
@@ -642,8 +531,8 @@
             int newCursorX, newCursorY;
 
             // Get signed (!) cursor position
-            newCursorX = (int)((short)LOWORD(lParam));
-            newCursorY = (int)((short)HIWORD(lParam));
+            newCursorX = GET_X_LPARAM(lParam);
+            newCursorY = GET_Y_LPARAM(lParam);
 
             if (newCursorX != window->Win32.oldCursorX ||
                 newCursorY != window->Win32.oldCursorY)
@@ -836,7 +725,7 @@
     WCHAR* wideTitle;
 
     // Set common window styles
-    dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
+    dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
     dwExStyle = WS_EX_APPWINDOW;
 
     // Set window style, depending on fullscreen mode
@@ -1067,13 +956,11 @@
     if (window->mode == GLFW_FULLSCREEN)
     {
         // Place the window above all topmost windows
+        _glfwPlatformShowWindow(window);
         SetWindowPos(window->Win32.handle, HWND_TOPMOST, 0,0,0,0,
                      SWP_NOMOVE | SWP_NOSIZE);
     }
 
-    setForegroundWindow(window->Win32.handle);
-    SetFocus(window->Win32.handle);
-
     return GL_TRUE;
 }
 
@@ -1194,6 +1081,29 @@
 
 
 //========================================================================
+// Show or hide window
+//========================================================================
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+    ShowWindow(window->Win32.handle, SW_SHOWNORMAL);
+    BringWindowToTop(window->Win32.handle);
+    SetForegroundWindow(window->Win32.handle);
+    SetFocus(window->Win32.handle);
+}
+
+
+//========================================================================
+// Show or hide window
+//========================================================================
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+    ShowWindow(window->Win32.handle, SW_HIDE);
+}
+
+
+//========================================================================
 // Write back window parameters into GLFW window structure
 //========================================================================
 
@@ -1239,27 +1149,21 @@
 
     while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
     {
-        switch (msg.message)
+        if (msg.message == WM_QUIT)
         {
-            case WM_QUIT:
+            // Treat WM_QUIT as a close on all windows
+
+            window = _glfwLibrary.windowListHead;
+            while (window)
             {
-                // Treat WM_QUIT as a close on all windows
-
-                window = _glfwLibrary.windowListHead;
-                while (window)
-                {
-                    _glfwInputWindowCloseRequest(window);
-                    window = window->next;
-                }
-
-                break;
+                _glfwInputWindowCloseRequest(window);
+                window = window->next;
             }
-
-            default:
-            {
-                DispatchMessage(&msg);
-                break;
-            }
+        }
+        else
+        {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
         }
     }
 
diff --git a/src/window.c b/src/window.c
index ba592fc..c3bde9b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -33,7 +33,7 @@
 
 #include <string.h>
 #include <stdlib.h>
-#if _WIN32
+#if defined(_MSC_VER)
  #include <malloc.h>
 #endif
 
@@ -81,8 +81,9 @@
     _glfwLibrary.hints.glMajor = 1;
     _glfwLibrary.hints.glMinor = 0;
 
-    // The default is to allow window resizing
+    // The default is to show the window and allow window resizing
     _glfwLibrary.hints.resizable = GL_TRUE;
+    _glfwLibrary.hints.visible   = GL_TRUE;
 
     // The default is 24 bits of depth, 8 bits of color
     _glfwLibrary.hints.depthBits = 24;
@@ -182,6 +183,16 @@
 
 
 //========================================================================
+// Register window visibility events
+//========================================================================
+
+void _glfwInputWindowVisibility(_GLFWwindow* window, int visible)
+{
+    window->visible = visible;
+}
+
+
+//========================================================================
 // Register window damage events
 //========================================================================
 
@@ -251,6 +262,7 @@
     wndconfig.title          = title;
     wndconfig.refreshRate    = Max(_glfwLibrary.hints.refreshRate, 0);
     wndconfig.resizable      = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE;
+    wndconfig.visible        = _glfwLibrary.hints.visible ? GL_TRUE : GL_FALSE;
     wndconfig.clientAPI      = _glfwLibrary.hints.clientAPI;
     wndconfig.glMajor        = _glfwLibrary.hints.glMajor;
     wndconfig.glMinor        = _glfwLibrary.hints.glMinor;
@@ -326,8 +338,9 @@
     // Cache the actual (as opposed to requested) window parameters
     _glfwPlatformRefreshWindowParams(window);
 
-    // Cache the actual (as opposed to requested) context parameters
     glfwMakeContextCurrent(window);
+
+    // Cache the actual (as opposed to requested) context parameters
     if (!_glfwRefreshContextParams())
     {
         glfwDestroyWindow(window);
@@ -343,6 +356,11 @@
         return GL_FALSE;
     }
 
+    // Clearing the front buffer to black to avoid garbage pixels left over
+    // from previous uses of our bit of VRAM
+    glClear(GL_COLOR_BUFFER_BIT);
+    _glfwPlatformSwapBuffers(window);
+
     // Restore the previously current context (or NULL)
     glfwMakeContextCurrent(previous);
 
@@ -351,10 +369,8 @@
     if (mode == GLFW_FULLSCREEN)
         glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_CAPTURED);
 
-    // Clearing the front buffer to black to avoid garbage pixels left over
-    // from previous uses of our bit of VRAM
-    glClear(GL_COLOR_BUFFER_BIT);
-    _glfwPlatformSwapBuffers(window);
+    if (mode == GLFW_WINDOWED && wndconfig.visible)
+        glfwShowWindow(window);
 
     return window;
 }
@@ -413,9 +429,12 @@
         case GLFW_STEREO:
             _glfwLibrary.hints.stereo = hint;
             break;
-        case GLFW_WINDOW_RESIZABLE:
+        case GLFW_RESIZABLE:
             _glfwLibrary.hints.resizable = hint;
             break;
+        case GLFW_VISIBLE:
+            _glfwLibrary.hints.visible = hint;
+            break;
         case GLFW_FSAA_SAMPLES:
             _glfwLibrary.hints.samples = hint;
             break;
@@ -657,6 +676,48 @@
 
 
 //========================================================================
+// Window show
+//========================================================================
+
+GLFWAPI void glfwShowWindow(GLFWwindow handle)
+{
+    _GLFWwindow* window = (_GLFWwindow*) handle;
+
+    if (!_glfwInitialized)
+    {
+        _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
+        return;
+    }
+
+    if (window->mode == GLFW_FULLSCREEN)
+        return;
+
+    _glfwPlatformShowWindow(window);
+}
+
+
+//========================================================================
+// Window hide
+//========================================================================
+
+GLFWAPI void glfwHideWindow(GLFWwindow handle)
+{
+    _GLFWwindow* window = (_GLFWwindow*) handle;
+
+    if (!_glfwInitialized)
+    {
+        _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
+        return;
+    }
+
+    if (window->mode == GLFW_FULLSCREEN)
+        return;
+
+    _glfwPlatformHideWindow(window);
+}
+
+
+//========================================================================
 // Get window parameter
 //========================================================================
 
@@ -680,8 +741,10 @@
             return window->closeRequested;
         case GLFW_REFRESH_RATE:
             return window->refreshRate;
-        case GLFW_WINDOW_RESIZABLE:
+        case GLFW_RESIZABLE:
             return window->resizable;
+        case GLFW_VISIBLE:
+            return window->visible;
         case GLFW_CLIENT_API:
             return window->clientAPI;
         case GLFW_OPENGL_VERSION_MAJOR:
@@ -822,7 +885,7 @@
 
 
 //========================================================================
-// Poll for new window and input events and close any flagged windows
+// Poll for new window and input events
 //========================================================================
 
 GLFWAPI void glfwPollEvents(void)
diff --git a/src/x11_init.c b/src/x11_init.c
index 8399a81..a4cfacf 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -672,12 +672,12 @@
 
     _glfwTerminateGammaRamp();
 
-    terminateDisplay();
-
     _glfwTerminateJoysticks();
 
     _glfwTerminateOpenGL();
 
+    terminateDisplay();
+
     // Free clipboard memory
     if (_glfwLibrary.X11.selection.string)
         free(_glfwLibrary.X11.selection.string);
@@ -728,7 +728,7 @@
 #if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
         " clock_gettime"
 #endif
-#if defined(_GLFW_USE_LINUX_JOYSTICKS)
+#if defined(_GLFW_HAS_LINUX_JOYSTICKS)
         " Linux-joystick-API"
 #else
         " no-joystick-support"
diff --git a/src/x11_joystick.c b/src/x11_joystick.c
index c1fb62b..3d2f597 100644
--- a/src/x11_joystick.c
+++ b/src/x11_joystick.c
@@ -30,7 +30,7 @@
 
 #include "internal.h"
 
-#ifdef _GLFW_USE_LINUX_JOYSTICKS
+#ifdef _GLFW_HAS_LINUX_JOYSTICKS
 #include <linux/joystick.h>
 
 #include <sys/types.h>
@@ -41,7 +41,7 @@
 #include <dirent.h>
 #include <stdio.h>
 #include <stdlib.h>
-#endif // _GLFW_USE_LINUX_JOYSTICKS
+#endif // _GLFW_HAS_LINUX_JOYSTICKS
 
 
 //========================================================================
@@ -50,7 +50,7 @@
 
 static int openJoystickDevice(int joy, const char* path)
 {
-#ifdef _GLFW_USE_LINUX_JOYSTICKS
+#ifdef _GLFW_HAS_LINUX_JOYSTICKS
     char numAxes, numButtons;
     int fd, version;
 
@@ -97,7 +97,7 @@
     }
 
     _glfwLibrary.X11.joystick[joy].present = GL_TRUE;
-#endif // _GLFW_USE_LINUX_JOYSTICKS
+#endif // _GLFW_HAS_LINUX_JOYSTICKS
 
     return GL_TRUE;
 }
@@ -109,7 +109,7 @@
 
 static void pollJoystickEvents(void)
 {
-#ifdef _GLFW_USE_LINUX_JOYSTICKS
+#ifdef _GLFW_HAS_LINUX_JOYSTICKS
     int i;
     ssize_t result;
     struct js_event e;
@@ -160,7 +160,7 @@
             }
         }
     }
-#endif // _GLFW_USE_LINUX_JOYSTICKS
+#endif // _GLFW_HAS_LINUX_JOYSTICKS
 }
 
 
@@ -174,7 +174,7 @@
 
 int _glfwInitJoysticks(void)
 {
-#ifdef _GLFW_USE_LINUX_JOYSTICKS
+#ifdef _GLFW_HAS_LINUX_JOYSTICKS
     int i, joy = 0;
     regex_t regex;
     DIR* dir;
@@ -215,7 +215,7 @@
     }
 
     regfree(&regex);
-#endif // _GLFW_USE_LINUX_JOYSTICKS
+#endif // _GLFW_HAS_LINUX_JOYSTICKS
 
     return GL_TRUE;
 }
@@ -227,7 +227,7 @@
 
 void _glfwTerminateJoysticks(void)
 {
-#ifdef _GLFW_USE_LINUX_JOYSTICKS
+#ifdef _GLFW_HAS_LINUX_JOYSTICKS
     int i;
 
     for (i = 0;  i <= GLFW_JOYSTICK_LAST;  i++)
@@ -241,7 +241,7 @@
             _glfwLibrary.X11.joystick[i].present = GL_FALSE;
         }
     }
-#endif // _GLFW_USE_LINUX_JOYSTICKS
+#endif // _GLFW_HAS_LINUX_JOYSTICKS
 }
 
 
diff --git a/src/x11_window.c b/src/x11_window.c
index 7b66b00..5cf1e61 100644
--- a/src/x11_window.c
+++ b/src/x11_window.c
@@ -228,10 +228,6 @@
 
     _glfwPlatformSetWindowTitle(window, wndconfig->title);
 
-    // Make sure the window is mapped before proceeding
-    XMapWindow(_glfwLibrary.X11.display, window->X11.handle);
-    XFlush(_glfwLibrary.X11.display);
-
     return GL_TRUE;
 }
 
@@ -699,6 +695,7 @@
             if (window == NULL)
                 return;
 
+            _glfwInputWindowVisibility(window, GL_TRUE);
             _glfwInputWindowIconify(window, GL_FALSE);
             break;
         }
@@ -710,6 +707,7 @@
             if (window == NULL)
                 return;
 
+            _glfwInputWindowVisibility(window, GL_FALSE);
             _glfwInputWindowIconify(window, GL_TRUE);
             break;
         }
@@ -854,6 +852,7 @@
         }
 #endif /*_GLFW_HAS_XRANDR*/
 
+        _glfwPlatformShowWindow(window);
         enterFullscreenMode(window);
     }
 
@@ -1045,6 +1044,28 @@
 
 
 //========================================================================
+// Show window
+//========================================================================
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+    XMapRaised(_glfwLibrary.X11.display, window->X11.handle);
+    XFlush(_glfwLibrary.X11.display);
+}
+
+
+//========================================================================
+// Hide window
+//========================================================================
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+    XUnmapWindow(_glfwLibrary.X11.display, window->X11.handle);
+    XFlush(_glfwLibrary.X11.display);
+}
+
+
+//========================================================================
 // Read back framebuffer parameters from the context
 //========================================================================
 
diff --git a/tests/clipboard.c b/tests/clipboard.c
index fcd1c30..f83bbfe 100644
--- a/tests/clipboard.c
+++ b/tests/clipboard.c
@@ -34,6 +34,8 @@
 
 #include "getopt.h"
 
+static GLboolean closed = GL_FALSE;
+
 static void usage(void)
 {
     printf("Usage: clipboard [-h]\n");
@@ -45,6 +47,12 @@
            glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL);
 }
 
+static int window_close_callback(GLFWwindow window)
+{
+    closed = GL_TRUE;
+    return GL_FALSE;
+}
+
 static void key_callback(GLFWwindow window, int key, int action)
 {
     if (action != GLFW_PRESS)
@@ -53,7 +61,7 @@
     switch (key)
     {
         case GLFW_KEY_ESCAPE:
-            glfwDestroyWindow(window);
+            closed = GL_TRUE;
             break;
 
         case GLFW_KEY_V:
@@ -80,7 +88,7 @@
     }
 }
 
-static void size_callback(GLFWwindow window, int width, int height)
+static void window_size_callback(GLFWwindow window, int width, int height)
 {
     glViewport(0, 0, width, height);
 }
@@ -130,7 +138,8 @@
     glfwSwapInterval(1);
 
     glfwSetKeyCallback(key_callback);
-    glfwSetWindowSizeCallback(size_callback);
+    glfwSetWindowSizeCallback(window_size_callback);
+    glfwSetWindowCloseCallback(window_close_callback);
 
     glMatrixMode(GL_PROJECTION);
     glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
@@ -138,7 +147,7 @@
 
     glClearColor(0.5f, 0.5f, 0.5f, 0);
 
-    while (!glfwGetWindowParam(window, GLFW_CLOSE_REQUESTED))
+    while (!closed)
     {
         glClear(GL_COLOR_BUFFER_BIT);
 
diff --git a/tests/defaults.c b/tests/defaults.c
index 391b498..2877cfd 100644
--- a/tests/defaults.c
+++ b/tests/defaults.c
@@ -83,6 +83,8 @@
         exit(EXIT_FAILURE);
     }
 
+    glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
+
     window = glfwCreateWindow(0, 0, GLFW_WINDOWED, "Defaults", NULL);
     if (!window)
     {
diff --git a/tests/gamma.c b/tests/gamma.c
index e74d5b4..c30dd53 100644
--- a/tests/gamma.c
+++ b/tests/gamma.c
@@ -37,6 +37,7 @@
 
 #define STEP_SIZE 0.1f
 
+static GLboolean closed = GL_FALSE;
 static GLfloat gamma_value = 1.0f;
 
 static void usage(void)
@@ -51,6 +52,12 @@
     glfwSetGamma(gamma_value);
 }
 
+static int window_close_callback(GLFWwindow window)
+{
+    closed = GL_TRUE;
+    return GL_FALSE;
+}
+
 static void key_callback(GLFWwindow window, int key, int action)
 {
     if (action != GLFW_PRESS)
@@ -60,7 +67,7 @@
     {
         case GLFW_KEY_ESCAPE:
         {
-            glfwDestroyWindow(window);
+            closed = GL_TRUE;
             break;
         }
 
@@ -145,6 +152,7 @@
     glfwSwapInterval(1);
 
     glfwSetKeyCallback(key_callback);
+    glfwSetWindowCloseCallback(window_close_callback);
     glfwSetWindowSizeCallback(size_callback);
 
     glMatrixMode(GL_PROJECTION);
@@ -153,7 +161,7 @@
 
     glClearColor(0.5f, 0.5f, 0.5f, 0);
 
-    while (!glfwGetWindowParam(window, GLFW_CLOSE_REQUESTED))
+    while (!closed)
     {
         glClear(GL_COLOR_BUFFER_BIT);
 
diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c
index b549715..dea207c 100644
--- a/tests/glfwinfo.c
+++ b/tests/glfwinfo.c
@@ -250,6 +250,8 @@
     if (strategy)
         glfwWindowHint(GLFW_OPENGL_ROBUSTNESS, strategy);
 
+    glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
+
     // We assume here that we stand a better chance of success by leaving all
     // possible details of pixel format selection to GLFW
 
diff --git a/tests/iconify.c b/tests/iconify.c
index 33b6f05..7781535 100644
--- a/tests/iconify.c
+++ b/tests/iconify.c
@@ -35,11 +35,19 @@
 
 #include "getopt.h"
 
+static GLboolean closed = GL_FALSE;
+
 static void usage(void)
 {
     printf("Usage: iconify [-h] [-f]\n");
 }
 
+static int window_close_callback(GLFWwindow window)
+{
+    closed = GL_TRUE;
+    return GL_FALSE;
+}
+
 static void key_callback(GLFWwindow window, int key, int action)
 {
     printf("%0.2f Key %s\n",
@@ -55,12 +63,12 @@
             glfwIconifyWindow(window);
             break;
         case GLFW_KEY_ESCAPE:
-            glfwDestroyWindow(window);
+            closed = GL_TRUE;
             break;
     }
 }
 
-static void size_callback(GLFWwindow window, int width, int height)
+static void window_size_callback(GLFWwindow window, int width, int height)
 {
     printf("%0.2f Size %ix%i\n", glfwGetTime(), width, height);
 
@@ -124,11 +132,12 @@
     glfwSwapInterval(1);
 
     glfwSetKeyCallback(key_callback);
-    glfwSetWindowSizeCallback(size_callback);
+    glfwSetWindowSizeCallback(window_size_callback);
+    glfwSetWindowCloseCallback(window_close_callback);
 
     glEnable(GL_SCISSOR_TEST);
 
-    while (!glfwGetWindowParam(window, GLFW_CLOSE_REQUESTED))
+    while (!closed)
     {
         if (iconified != glfwGetWindowParam(window, GLFW_ICONIFIED) ||
             active != glfwGetWindowParam(window, GLFW_ACTIVE))
diff --git a/tests/modes.c b/tests/modes.c
index 5ce65ab..ef1db71 100644
--- a/tests/modes.c
+++ b/tests/modes.c
@@ -35,7 +35,7 @@
 
 #include "getopt.h"
 
-static GLFWwindow window = NULL;
+static GLFWwindow window_handle = NULL;
 
 enum Mode
 {
@@ -68,25 +68,25 @@
     fprintf(stderr, "Error: %s\n", description);
 }
 
-static void window_size_callback(GLFWwindow in_window, int width, int height)
+static void window_size_callback(GLFWwindow window, int width, int height)
 {
     printf("Window resized to %ix%i\n", width, height);
 
     glViewport(0, 0, width, height);
 }
 
-static int window_close_callback(GLFWwindow dummy)
+static int window_close_callback(GLFWwindow window)
 {
-    window = NULL;
+    window_handle = NULL;
     return GL_TRUE;
 }
 
-static void key_callback(GLFWwindow dummy, int key, int action)
+static void key_callback(GLFWwindow window, int key, int action)
 {
     if (key == GLFW_KEY_ESCAPE)
     {
         glfwDestroyWindow(window);
-        window = NULL;
+        window_handle = NULL;
     }
 }
 
@@ -132,10 +132,10 @@
 
         printf("Testing mode %u: %s", (unsigned int) i, format_mode(mode));
 
-        window = glfwCreateWindow(mode->width, mode->height,
-                                  GLFW_FULLSCREEN, "Video Mode Test",
-                                  NULL);
-        if (!window)
+        window_handle = glfwCreateWindow(mode->width, mode->height,
+                                         GLFW_FULLSCREEN, "Video Mode Test",
+                                         NULL);
+        if (!window_handle)
         {
             printf("Failed to enter mode %u: %s\n",
                    (unsigned int) i,
@@ -143,7 +143,7 @@
             continue;
         }
 
-        glfwMakeContextCurrent(window);
+        glfwMakeContextCurrent(window_handle);
         glfwSwapInterval(1);
 
         glfwSetTime(0.0);
@@ -151,10 +151,10 @@
         while (glfwGetTime() < 5.0)
         {
             glClear(GL_COLOR_BUFFER_BIT);
-            glfwSwapBuffers(window);
+            glfwSwapBuffers(window_handle);
             glfwPollEvents();
 
-            if (!window)
+            if (!window_handle)
             {
                 printf("User terminated program\n");
                 exit(EXIT_SUCCESS);
@@ -165,7 +165,7 @@
         glGetIntegerv(GL_GREEN_BITS, &current.greenBits);
         glGetIntegerv(GL_BLUE_BITS, &current.blueBits);
 
-        glfwGetWindowSize(window, &current.width, &current.height);
+        glfwGetWindowSize(window_handle, &current.width, &current.height);
 
         if (current.redBits != mode->redBits ||
             current.greenBits != mode->greenBits ||
@@ -185,9 +185,9 @@
 
         printf("Closing window\n");
 
-        glfwDestroyWindow(window);
+        glfwDestroyWindow(window_handle);
+        window_handle = NULL;
         glfwPollEvents();
-        window = NULL;
     }
 }
 
diff --git a/tests/peter.c b/tests/peter.c
index ae6e4b7..59c917e 100644
--- a/tests/peter.c
+++ b/tests/peter.c
@@ -35,6 +35,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+static GLboolean reopen = GL_FALSE;
 static GLFWwindow window_handle = NULL;
 static int cursor_x;
 static int cursor_y;
@@ -77,10 +78,7 @@
         case GLFW_KEY_R:
         {
             if (action == GLFW_PRESS)
-            {
-                glfwDestroyWindow(window);
-                open_window();
-            }
+                reopen = GL_TRUE;
 
             break;
         }
@@ -121,8 +119,6 @@
 
     if (!open_window())
     {
-        glfwTerminate();
-
         fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError()));
         exit(EXIT_FAILURE);
     }
@@ -135,6 +131,18 @@
 
         glfwSwapBuffers(window_handle);
         glfwWaitEvents();
+
+        if (reopen)
+        {
+            glfwDestroyWindow(window_handle);
+            if (!open_window())
+            {
+                fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError()));
+                exit(EXIT_FAILURE);
+            }
+
+            reopen = GL_FALSE;
+        }
     }
 
     glfwTerminate();
diff --git a/tests/sharing.c b/tests/sharing.c
index 95f2134..64e6174 100644
--- a/tests/sharing.c
+++ b/tests/sharing.c
@@ -37,27 +37,18 @@
 #define HEIGHT 400
 
 static GLFWwindow windows[2];
+static GLboolean closed = GL_FALSE;
 
 static void key_callback(GLFWwindow window, int key, int action)
 {
     if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE)
-        glfwDestroyWindow(window);
+        closed = GL_TRUE;
 }
 
 static int window_close_callback(GLFWwindow window)
 {
-    int i;
-
-    for (i = 0;  i < 2;  i++)
-    {
-        if (windows[i] == window)
-        {
-            windows[i] = NULL;
-            break;
-        }
-    }
-
-    return GL_TRUE;
+    closed = GL_TRUE;
+    return GL_FALSE;
 }
 
 static GLFWwindow open_window(const char* title, GLFWwindow share)
@@ -170,7 +161,7 @@
     glfwGetWindowPos(windows[0], &x, &y);
     glfwSetWindowPos(windows[1], x + WIDTH + 50, y);
 
-    while (windows[0] && windows[1])
+    while (!closed)
     {
         glfwMakeContextCurrent(windows[0]);
         draw_quad(texture);