Win32 port work dump.
diff --git a/src/win32/platform.h b/src/win32/platform.h
index 42e4a1b..dc54c87 100644
--- a/src/win32/platform.h
+++ b/src/win32/platform.h
@@ -307,7 +307,6 @@
     HWND      handle;          // Window handle
     ATOM      classAtom;       // Window class atom
     int       modeID;          // Mode ID for fullscreen mode
-    HHOOK     keyboardHook;    // Keyboard hook handle
     DWORD     dwStyle;         // Window styles used for window creation
     DWORD     dwExStyle;       // --"--
 
@@ -326,8 +325,9 @@
 //------------------------------------------------------------------------
 typedef struct _GLFWlibraryWin32
 {
-    // Instance of the application
-    HINSTANCE instance;
+    HINSTANCE instance;        // Instance of the application
+    HHOOK     keyboardHook;    // Keyboard hook handle
+    DWORD     foregroundLockTimeout;
 
     // Timer data
     struct {
@@ -340,8 +340,6 @@
     // System information
     struct {
         int     winVer;
-        int     hasUnicode;
-        DWORD   foregroundLockTimeout;
     } sys;
 
 #if !defined(_GLFW_NO_DLOAD_WINMM) || !defined(_GLFW_NO_DLOAD_GDI32)
diff --git a/src/win32/win32_dllmain.c b/src/win32/win32_dllmain.c
index 63bdba6..19a1c3e 100644
--- a/src/win32/win32_dllmain.c
+++ b/src/win32/win32_dllmain.c
@@ -37,7 +37,7 @@
 // GLFW DLL entry point
 //========================================================================
 
-BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, LPVOID reserved )
+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)!
diff --git a/src/win32/win32_enable.c b/src/win32/win32_enable.c
index 352b0d5..f1765b3 100644
--- a/src/win32/win32_enable.c
+++ b/src/win32/win32_enable.c
@@ -78,9 +78,11 @@
     // Was it a system key combination (e.g. ALT+TAB)?
     if (syskeys)
     {
+        _GLFWwindow* window = _glfwLibrary.activeWindow;
+
         // Pass the key event to our window message loop
-        if (_glfwWin.opened)
-            PostMessage(_glfwWin.window, (UINT) wParam, p->vkCode, 0);
+        if (window)
+            PostMessage(window->Win32.handle, (UINT) wParam, p->vkCode, 0);
 
         // We've taken care of it - don't let the system know about this
         // key event
@@ -89,7 +91,7 @@
     else
     {
         // It's a harmless key press, let the system deal with it
-        return CallNextHookEx(_glfwWin.keyboardHook, nCode, wParam, lParam);
+        return CallNextHookEx(_glfwLibrary.Win32.keyboardHook, nCode, wParam, lParam);
     }
 }
 
@@ -104,19 +106,11 @@
 
 void _glfwPlatformEnableSystemKeys(void)
 {
-    BOOL dummy;
-
-    // Use different methods depending on operating system version
-    if (_glfwLibrary.Sys.winVer >= _GLFW_WIN_NT4)
+    if (_glfwLibrary.Win32.keyboardHook != NULL)
     {
-        if (_glfwWin.keyboardHook != NULL)
-        {
-            UnhookWindowsHookEx(_glfwWin.keyboardHook);
-            _glfwWin.keyboardHook = NULL;
-        }
+        UnhookWindowsHookEx(_glfwLibrary.Win32.keyboardHook);
+        _glfwLibrary.Win32.keyboardHook = NULL;
     }
-    else
-        SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, FALSE, &dummy, 0);
 }
 
 
@@ -126,22 +120,9 @@
 
 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
-        SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &dummy, 0);
-    }
+    _glfwLibrary.Win32.keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,
+                                                       keyboardHook,
+                                                       _glfwLibrary.Win32.instance,
+                                                       0);
 }
 
diff --git a/src/win32/win32_glext.c b/src/win32/win32_glext.c
index 6b0c995..4245ae8 100644
--- a/src/win32/win32_glext.c
+++ b/src/win32/win32_glext.c
@@ -43,9 +43,11 @@
 {
     const GLubyte* extensions;
 
-    if (_glfwWin.GetExtensionsStringEXT != NULL)
+    _GLFWwindow* window = _glfwLibrary.currentWindow;
+
+    if (window->WGL.GetExtensionsStringEXT != NULL)
     {
-        extensions = (GLubyte*) _glfwWin.GetExtensionsStringEXT();
+        extensions = (GLubyte*) window->WGL.GetExtensionsStringEXT();
         if (extensions != NULL)
         {
             if (_glfwStringInExtensionString(extension, extensions))
@@ -53,9 +55,9 @@
         }
     }
 
-    if (_glfwWin.GetExtensionsStringARB != NULL)
+    if (window->WGL.GetExtensionsStringARB != NULL)
     {
-        extensions = (GLubyte*) _glfwWin.GetExtensionsStringARB(_glfwWin.DC);
+        extensions = (GLubyte*) window->WGL.GetExtensionsStringARB(window->WGL.DC);
         if (extensions != NULL)
         {
             if (_glfwStringInExtensionString(extension, extensions))
diff --git a/src/win32/win32_init.c b/src/win32/win32_init.c
index 5034b00..1ddd571 100644
--- a/src/win32/win32_init.c
+++ b/src/win32/win32_init.c
@@ -44,28 +44,28 @@
 {
     // gdi32.dll (OpenGL pixel format functions & SwapBuffers)
 #ifndef _GLFW_NO_DLOAD_GDI32
-    _glfwLibrary.Libs.gdi32 = LoadLibrary("gdi32.dll");
-    if (_glfwLibrary.Libs.gdi32 != NULL)
+    _glfwLibrary.Win32.libs.gdi32 = LoadLibrary("gdi32.dll");
+    if (_glfwLibrary.Win32.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");
+        _glfwLibrary.Win32.libs.ChoosePixelFormat = (CHOOSEPIXELFORMAT_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.gdi32, "ChoosePixelFormat");
+        _glfwLibrary.Win32.libs.DescribePixelFormat = (DESCRIBEPIXELFORMAT_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.gdi32, "DescribePixelFormat");
+        _glfwLibrary.Win32.libs.GetPixelFormat = (GETPIXELFORMAT_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.gdi32, "GetPixelFormat");
+        _glfwLibrary.Win32.libs.SetPixelFormat = (SETPIXELFORMAT_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.gdi32, "SetPixelFormat");
+        _glfwLibrary.Win32.libs.SwapBuffers = (SWAPBUFFERS_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.gdi32, "SwapBuffers");
 
-        if (_glfwLibrary.Libs.ChoosePixelFormat &&
-            _glfwLibrary.Libs.DescribePixelFormat &&
-            _glfwLibrary.Libs.GetPixelFormat &&
-            _glfwLibrary.Libs.SetPixelFormat &&
-            _glfwLibrary.Libs.SwapBuffers)
+        if (_glfwLibrary.Win32.libs.ChoosePixelFormat &&
+            _glfwLibrary.Win32.libs.DescribePixelFormat &&
+            _glfwLibrary.Win32.libs.GetPixelFormat &&
+            _glfwLibrary.Win32.libs.SetPixelFormat &&
+            _glfwLibrary.Win32.libs.SwapBuffers)
         {
-            FreeLibrary(_glfwLibrary.Libs.gdi32);
-            _glfwLibrary.Libs.gdi32 = NULL;
+            FreeLibrary(_glfwLibrary.Win32.libs.gdi32);
+            _glfwLibrary.Win32.libs.gdi32 = NULL;
             return GL_FALSE;
         }
     }
@@ -75,25 +75,25 @@
 
     // winmm.dll (for joystick and timer support)
 #ifndef _GLFW_NO_DLOAD_WINMM
-    _glfwLibrary.Libs.winmm = LoadLibrary("winmm.dll");
-    if (_glfwLibrary.Libs.winmm != NULL)
+    _glfwLibrary.Win32.libs.winmm = LoadLibrary("winmm.dll");
+    if (_glfwLibrary.Win32.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");
+        _glfwLibrary.Win32.libs.joyGetDevCapsA = (JOYGETDEVCAPSA_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.winmm, "joyGetDevCapsA");
+        _glfwLibrary.Win32.libs.joyGetPos = (JOYGETPOS_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.winmm, "joyGetPos");
+        _glfwLibrary.Win32.libs.joyGetPosEx = (JOYGETPOSEX_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.winmm, "joyGetPosEx");
+        _glfwLibrary.Win32.libs.timeGetTime = (TIMEGETTIME_T)
+            GetProcAddress(_glfwLibrary.Win32.libs.winmm, "timeGetTime");
 
-        if (_glfwLibrary.Libs.joyGetDevCapsA &&
-            _glfwLibrary.Libs.joyGetPos &&
-            _glfwLibrary.Libs.joyGetPosEx &&
-            _glfwLibrary.Libs.timeGetTime)
+        if (_glfwLibrary.Win32.libs.joyGetDevCapsA &&
+            _glfwLibrary.Win32.libs.joyGetPos &&
+            _glfwLibrary.Win32.libs.joyGetPosEx &&
+            _glfwLibrary.Win32.libs.timeGetTime)
         {
-            FreeLibrary(_glfwLibrary.Libs.winmm);
-            _glfwLibrary.Libs.winmm = NULL;
+            FreeLibrary(_glfwLibrary.Win32.libs.winmm);
+            _glfwLibrary.Win32.libs.winmm = NULL;
             return GL_FALSE;
         }
     }
@@ -113,19 +113,19 @@
 {
     // gdi32.dll
 #ifndef _GLFW_NO_DLOAD_GDI32
-    if (_glfwLibrary.Libs.gdi32 != NULL)
+    if (_glfwLibrary.Win32.libs.gdi32 != NULL)
     {
-        FreeLibrary(_glfwLibrary.Libs.gdi32);
-        _glfwLibrary.Libs.gdi32 = NULL;
+        FreeLibrary(_glfwLibrary.Win32.libs.gdi32);
+        _glfwLibrary.Win32.libs.gdi32 = NULL;
     }
 #endif // _GLFW_NO_DLOAD_GDI32
 
     // winmm.dll
 #ifndef _GLFW_NO_DLOAD_WINMM
-    if (_glfwLibrary.Libs.winmm != NULL)
+    if (_glfwLibrary.Win32.libs.winmm != NULL)
     {
-        FreeLibrary(_glfwLibrary.Libs.winmm);
-        _glfwLibrary.Libs.winmm = NULL;
+        FreeLibrary(_glfwLibrary.Win32.libs.winmm);
+        _glfwLibrary.Win32.libs.winmm = NULL;
     }
 #endif // _GLFW_NO_DLOAD_WINMM
 }
@@ -157,7 +157,7 @@
     // 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);
+                         &_glfwLibrary.Win32.foregroundLockTimeout, 0);
     SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID) 0,
                          SPIF_SENDCHANGE);
 
@@ -165,43 +165,31 @@
     osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
     GetVersionEx(&osi);
 
-    _glfwLibrary.Sys.winVer = _GLFW_WIN_UNKNOWN;
+    _glfwLibrary.Win32.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;
+            _glfwLibrary.Win32.sys.winVer = _GLFW_WIN_95;
         else if (osi.dwMajorVersion == 4 && osi.dwMinorVersion < 90)
-            _glfwLibrary.Sys.winVer = _GLFW_WIN_98;
+            _glfwLibrary.Win32.sys.winVer = _GLFW_WIN_98;
         else if (osi.dwMajorVersion == 4 && osi.dwMinorVersion == 90)
-            _glfwLibrary.Sys.winVer = _GLFW_WIN_ME;
+            _glfwLibrary.Win32.sys.winVer = _GLFW_WIN_ME;
         else if (osi.dwMajorVersion >= 4)
-            _glfwLibrary.Sys.winVer = _GLFW_WIN_UNKNOWN_9x;
+            _glfwLibrary.Win32.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;
+            _glfwLibrary.Win32.sys.winVer = _GLFW_WIN_NT4;
         else if (osi.dwMajorVersion == 5 && osi.dwMinorVersion == 0)
-            _glfwLibrary.Sys.winVer = _GLFW_WIN_2K;
+            _glfwLibrary.Win32.sys.winVer = _GLFW_WIN_2K;
         else if (osi.dwMajorVersion == 5 && osi.dwMinorVersion == 1)
-            _glfwLibrary.Sys.winVer = _GLFW_WIN_XP;
+            _glfwLibrary.Win32.sys.winVer = _GLFW_WIN_XP;
         else if (osi.dwMajorVersion == 5 && osi.dwMinorVersion == 2)
-            _glfwLibrary.Sys.winVer = _GLFW_WIN_NET_SERVER;
+            _glfwLibrary.Win32.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;
+            _glfwLibrary.Win32.sys.winVer = _GLFW_WIN_UNKNOWN_NT;
     }
 
     // Load libraries (DLLs)
@@ -215,10 +203,10 @@
 #endif
 
     // Retrieve GLFW instance handle
-    _glfwLibrary.instance = GetModuleHandle(NULL);
+    _glfwLibrary.Win32.instance = GetModuleHandle(NULL);
 
     // System keys are not disabled
-    _glfwWin.keyboardHook = NULL;
+    _glfwLibrary.Win32.keyboardHook = NULL;
 
     // Install atexit() routine
     atexit(glfw_atexit);
@@ -247,7 +235,7 @@
 
     // Restore FOREGROUNDLOCKTIMEOUT system setting
     SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
-                         (LPVOID) _glfwLibrary.Sys.foregroundLockTimeout,
+                         (LPVOID) _glfwLibrary.Win32.foregroundLockTimeout,
                          SPIF_SENDCHANGE);
 
     return GL_TRUE;
diff --git a/src/win32/win32_joystick.c b/src/win32/win32_joystick.c
index 74855ca..3e966dd 100644
--- a/src/win32/win32_joystick.c
+++ b/src/win32/win32_joystick.c
@@ -43,11 +43,6 @@
 {
     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;
diff --git a/src/win32/win32_time.c b/src/win32/win32_time.c
index d11e5d4..e0ba2e3 100644
--- a/src/win32/win32_time.c
+++ b/src/win32/win32_time.c
@@ -47,24 +47,24 @@
     if (QueryPerformanceFrequency((LARGE_INTEGER*) &freq))
     {
         // Performance counter is available => use it!
-        _glfwLibrary.Timer.HasPerformanceCounter = GL_TRUE;
+        _glfwLibrary.Win32.timer.HasPerformanceCounter = GL_TRUE;
 
         // Counter resolution is 1 / counter frequency
-        _glfwLibrary.Timer.Resolution = 1.0 / (double) freq;
+        _glfwLibrary.Win32.timer.Resolution = 1.0 / (double) freq;
 
         // Set start time for timer
-        QueryPerformanceCounter((LARGE_INTEGER*) &_glfwLibrary.Timer.t0_64);
+        QueryPerformanceCounter((LARGE_INTEGER*) &_glfwLibrary.Win32.timer.t0_64);
     }
     else
     {
         // No performace counter available => use the tick counter
-        _glfwLibrary.Timer.HasPerformanceCounter = GL_FALSE;
+        _glfwLibrary.Win32.timer.HasPerformanceCounter = GL_FALSE;
 
         // Counter resolution is 1 ms
-        _glfwLibrary.Timer.Resolution = 0.001;
+        _glfwLibrary.Win32.timer.Resolution = 0.001;
 
         // Set start time for timer
-        _glfwLibrary.Timer.t0_32 = _glfw_timeGetTime();
+        _glfwLibrary.Win32.timer.t0_32 = _glfw_timeGetTime();
     }
 }
 
@@ -82,16 +82,16 @@
     double t;
     __int64 t_64;
 
-    if (_glfwLibrary.Timer.HasPerformanceCounter)
+    if (_glfwLibrary.Win32.timer.HasPerformanceCounter)
     {
         QueryPerformanceCounter((LARGE_INTEGER*) &t_64);
-        t =  (double)(t_64 - _glfwLibrary.Timer.t0_64);
+        t =  (double)(t_64 - _glfwLibrary.Win32.timer.t0_64);
     }
     else
-        t = (double)(_glfw_timeGetTime() - _glfwLibrary.Timer.t0_32);
+        t = (double)(_glfw_timeGetTime() - _glfwLibrary.Win32.timer.t0_32);
 
     // Calculate the current time in seconds
-    return t * _glfwLibrary.Timer.Resolution;
+    return t * _glfwLibrary.Win32.timer.Resolution;
 }
 
 
@@ -103,12 +103,12 @@
 {
     __int64 t_64;
 
-    if (_glfwLibrary.Timer.HasPerformanceCounter)
+    if (_glfwLibrary.Win32.timer.HasPerformanceCounter)
     {
         QueryPerformanceCounter((LARGE_INTEGER*) &t_64);
-        _glfwLibrary.Timer.t0_64 = t_64 - (__int64) (t / _glfwLibrary.Timer.Resolution);
+        _glfwLibrary.Win32.timer.t0_64 = t_64 - (__int64) (t / _glfwLibrary.Win32.timer.Resolution);
     }
     else
-        _glfwLibrary.Timer.t0_32 = _glfw_timeGetTime() - (int)(t * 1000.0);
+        _glfwLibrary.Win32.timer.t0_32 = _glfw_timeGetTime() - (int)(t * 1000.0);
 }
 
diff --git a/src/win32/win32_window.c b/src/win32/win32_window.c
index 6f5e22f..a8885fe 100644
--- a/src/win32/win32_window.c
+++ b/src/win32/win32_window.c
@@ -129,11 +129,11 @@
 // NOTE: Do not call this unless we have found WGL_ARB_pixel_format
 //========================================================================
 
-static int getPixelFormatAttrib(int pixelFormat, int attrib)
+static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib)
 {
     int value = 0;
 
-    if (!_glfwWin.GetPixelFormatAttribivARB(_glfwWin.DC, pixelFormat, 0, 1, &attrib, &value))
+    if (!window->WGL.GetPixelFormatAttribivARB(window->WGL.DC, pixelFormat, 0, 1, &attrib, &value))
     {
         // NOTE: We should probably handle this error somehow
         return 0;
@@ -147,7 +147,7 @@
 // Return a list of available and usable framebuffer configs
 //========================================================================
 
-static _GLFWfbconfig* getFBConfigs(unsigned int* found)
+static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
 {
     _GLFWfbconfig* result;
     PIXELFORMATDESCRIPTOR pfd;
@@ -155,10 +155,10 @@
 
     *found = 0;
 
-    if (_glfwWin.has_WGL_ARB_pixel_format)
+    if (window->WGL.has_WGL_ARB_pixel_format)
         count = getPixelFormatAttrib(1, WGL_NUMBER_PIXEL_FORMATS_ARB);
     else
-        count = _glfw_DescribePixelFormat(_glfwWin.DC, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
+        count = _glfw_DescribePixelFormat(window->WGL.DC, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
 
     if (!count)
     {
@@ -175,7 +175,7 @@
 
     for (i = 1;  i <= count;  i++)
     {
-        if (_glfwWin.has_WGL_ARB_pixel_format)
+        if (window->WGL.has_WGL_ARB_pixel_format)
         {
             // Get pixel format attributes through WGL_ARB_pixel_format
 
@@ -207,7 +207,7 @@
             result[*found].auxBuffers = getPixelFormatAttrib(i, WGL_AUX_BUFFERS_ARB);
             result[*found].stereo = getPixelFormatAttrib(i, WGL_STEREO_ARB);
 
-            if (_glfwWin.has_WGL_ARB_multisample)
+            if (window->WGL.has_WGL_ARB_multisample)
                 result[*found].samples = getPixelFormatAttrib(i, WGL_SAMPLES_ARB);
             else
                 result[*found].samples = 0;
@@ -216,7 +216,7 @@
         {
             // Get pixel format attributes through old-fashioned PFDs
 
-            if (!_glfw_DescribePixelFormat(_glfwWin.DC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd))
+            if (!_glfw_DescribePixelFormat(window->WGL.DC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd))
                 continue;
 
             // Only consider doublebuffered OpenGL pixel formats for windows
@@ -270,7 +270,7 @@
 // Creates an OpenGL context on the specified device context
 //========================================================================
 
-static HGLRC createContext(HDC dc, const _GLFWwndconfig* wndconfig, int pixelFormat)
+static HGLRC createContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, int pixelFormat)
 {
     PIXELFORMATDESCRIPTOR pfd;
     int flags, i = 0, attribs[7];
@@ -281,7 +281,7 @@
     if (!_glfw_SetPixelFormat(dc, pixelFormat, &pfd))
         return NULL;
 
-    if (_glfwWin.has_WGL_ARB_create_context)
+    if (window->WGL.has_WGL_ARB_create_context)
     {
         // Use the newer wglCreateContextAttribsARB
 
@@ -322,7 +322,7 @@
 
         attribs[i++] = 0;
 
-        return _glfwWin.CreateContextAttribsARB(dc, NULL, attribs);
+        return window->WGL.CreateContextAttribsARB(dc, NULL, attribs);
     }
 
     return wglCreateContext(dc);
@@ -590,28 +590,31 @@
 {
     int wheelDelta, iconified;
 
+    _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtr(hWnd, 0);
+
     switch (uMsg)
     {
         // Window activate message? (iconification?)
         case WM_ACTIVATE:
         {
-            _glfwWin.active = LOWORD(wParam) != WA_INACTIVE ? GL_TRUE : GL_FALSE;
+            if (LOWORD(wParam) != WA_INACTIVE)
+                _glfwLibrary.activeWindow = window;
 
             iconified = HIWORD(wParam) ? GL_TRUE : GL_FALSE;
 
             // Were we deactivated/iconified?
-            if ((!_glfwWin.active || iconified) && !_glfwWin.iconified)
+            if ((window != _glfwLibrary.activeWindow || iconified) && !window->iconified)
             {
                 _glfwInputDeactivation();
 
                 // If we are in fullscreen mode we need to iconify
-                if (_glfwWin.opened && _glfwWin.fullscreen)
+                if (window->mode == GLFW_FULLSCREEN)
                 {
                     // Do we need to manually iconify?
                     if (!iconified)
                     {
                         // Minimize window
-                        CloseWindow(_glfwWin.window);
+                        CloseWindow(window->Win32.handle);
                         iconified = GL_TRUE;
                     }
 
@@ -620,43 +623,43 @@
                 }
 
                 // Unlock mouse if locked
-                if (!_glfwWin.oldMouseLockValid)
+                if (!window->Win32.oldMouseLockValid)
                 {
-                    _glfwWin.oldMouseLock = _glfwWin.mouseLock;
-                    _glfwWin.oldMouseLockValid = GL_TRUE;
+                    window->Win32.oldMouseLock = window->mouseLock;
+                    window->Win32.oldMouseLockValid = GL_TRUE;
                     glfwEnable(GLFW_MOUSE_CURSOR);
                 }
             }
-            else if (_glfwWin.active || !iconified)
+            else if (window == _glfwLibrary.activeWindow || !iconified)
             {
                 // If we are in fullscreen mode we need to maximize
-                if (_glfwWin.opened && _glfwWin.fullscreen && _glfwWin.iconified)
+                if (window->mode == GLFW_FULLSCREEN && window->iconified)
                 {
                     // Change display settings to the user selected mode
-                    _glfwSetVideoModeMODE(_glfwWin.modeID);
+                    _glfwSetVideoModeMODE(window->Win32.modeID);
 
                     // Do we need to manually restore window?
                     if (iconified)
                     {
                         // Restore window
-                        OpenIcon(_glfwWin.window);
+                        OpenIcon(window->Win32.handle);
                         iconified = GL_FALSE;
 
                         // Activate window
                         ShowWindow(hWnd, SW_SHOW);
-                        setForegroundWindow(_glfwWin.window);
-                        SetFocus(_glfwWin.window);
+                        setForegroundWindow(window->Win32.handle);
+                        SetFocus(window->Win32.handle);
                     }
                 }
 
                 // Lock mouse, if necessary
-                if (_glfwWin.oldMouseLockValid && _glfwWin.oldMouseLock)
+                if (window->Win32.oldMouseLockValid && window->Win32.oldMouseLock)
                     glfwDisable(GLFW_MOUSE_CURSOR);
 
-                _glfwWin.oldMouseLockValid = GL_FALSE;
+                window->Win32.oldMouseLockValid = GL_FALSE;
             }
 
-            _glfwWin.iconified = iconified;
+            window->iconified = iconified;
             return 0;
         }
 
@@ -667,7 +670,7 @@
                 case SC_SCREENSAVE:
                 case SC_MONITORPOWER:
                 {
-                    if (_glfwWin.fullscreen)
+                    if (window->mode == GLFW_FULLSCREEN)
                     {
                         // We are running in fullscreen mode, so disallow
                         // screen saver and screen blanking
@@ -697,7 +700,7 @@
         {
             _glfwInputKey(translateKey(wParam, lParam), GLFW_PRESS);
 
-            if (_glfwWin.charCallback)
+            if (window->charCallback)
                 translateChar((DWORD) wParam, (DWORD) lParam, GLFW_PRESS);
 
             return 0;
@@ -715,7 +718,7 @@
             else
                 _glfwInputKey(translateKey(wParam, lParam), GLFW_RELEASE);
 
-            if (_glfwWin.charCallback)
+            if (window->charCallback)
                 translateChar((DWORD) wParam, (DWORD) lParam, GLFW_RELEASE);
 
             return 0;
@@ -797,36 +800,36 @@
 
         case WM_MOUSEMOVE:
         {
-            int NewMouseX, NewMouseY;
+            int newMouseX, newMouseY;
 
             // Get signed (!) mouse position
-            NewMouseX = (int)((short)LOWORD(lParam));
-            NewMouseY = (int)((short)HIWORD(lParam));
+            newMouseX = (int)((short)LOWORD(lParam));
+            newMouseY = (int)((short)HIWORD(lParam));
 
-            if (NewMouseX != _glfwInput.OldMouseX ||
-                NewMouseY != _glfwInput.OldMouseY)
+            if (newMouseX != window->oldMouseX ||
+                newMouseY != window->oldMouseY)
             {
-                if (_glfwWin.mouseLock)
+                if (window == _glfwLibrary.cursorLockWindow)
                 {
-                    _glfwInput.MousePosX += NewMouseX -
-                                            _glfwInput.OldMouseX;
-                    _glfwInput.MousePosY += NewMouseY -
-                                            _glfwInput.OldMouseY;
+                    window->mousePosX += newMouseX -
+                                         window->oldMouseX;
+                    window->mousePosY += newMouseY -
+                                         window->oldMouseY;
                 }
                 else
                 {
-                    _glfwInput.MousePosX = NewMouseX;
-                    _glfwInput.MousePosY = NewMouseY;
+                    window->mousePosX = newMouseX;
+                    window->mousePosY = newMouseY;
                 }
 
-                _glfwInput.OldMouseX = NewMouseX;
-                _glfwInput.OldMouseY = NewMouseY;
-                _glfwInput.MouseMoved = GL_TRUE;
+                window->oldMouseX = newMouseX;
+                window->oldMouseY = newMouseY;
+                window->mouseMoved = GL_TRUE;
 
-                if (_glfwWin.mousePosCallback)
+                if (window->mousePosCallback)
                 {
-                    _glfwWin.mousePosCallback(_glfwInput.MousePosX,
-                                               _glfwInput.MousePosY);
+                    window->mousePosCallback(window->mousePosX,
+                                             window->mousePosY);
                 }
             }
 
@@ -835,35 +838,30 @@
 
         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;
+            wheelDelta = (((int)wParam) >> 16) / WHEEL_DELTA;
+            window->wheelPos += wheelDelta;
 
-                if (_glfwWin.mouseWheelCallback)
-                    _glfwWin.mouseWheelCallback(_glfwInput.WheelPos);
+            if (window->mouseWheelCallback)
+                window->mouseWheelCallback(window->wheelPos);
 
-                return 0;
-            }
-            break;
+            return 0;
         }
 
         case WM_SIZE:
         {
-            _glfwWin.width  = LOWORD(lParam);
-            _glfwWin.height = HIWORD(lParam);
+            window->width  = LOWORD(lParam);
+            window->height = HIWORD(lParam);
 
             // If the mouse is locked, update the clipping rect
             if (_glfwWin.mouseLock)
             {
                 RECT ClipWindowRect;
-                if (GetWindowRect(_glfwWin.window, &ClipWindowRect))
+                if (GetWindowRect(window->Win32.handle, &ClipWindowRect))
                     ClipCursor(&ClipWindowRect);
             }
 
-            if (_glfwWin.windowSizeCallback)
-                _glfwWin.windowSizeCallback(LOWORD(lParam), HIWORD(lParam));
+            if (window->windowSizeCallback)
+                window->windowSizeCallback(LOWORD(lParam), HIWORD(lParam));
 
             return 0;
         }
@@ -874,7 +872,7 @@
             if (_glfwWin.mouseLock)
             {
                 RECT ClipWindowRect;
-                if (GetWindowRect(_glfwWin.window, &ClipWindowRect))
+                if (GetWindowRect(window->Win32.handle, &ClipWindowRect))
                     ClipCursor(&ClipWindowRect);
             }
             return 0;
@@ -883,8 +881,8 @@
         // Was the window contents damaged?
         case WM_PAINT:
         {
-            if (_glfwWin.windowRefreshCallback)
-                _glfwWin.windowRefreshCallback();
+            if (window->Win32.handleRefreshCallback)
+                window->Win32.handleRefreshCallback();
 
             break;
         }
@@ -906,7 +904,8 @@
 // Translate client window size to full window size (including window borders)
 //========================================================================
 
-static void getFullWindowSize(int clientWidth, int clientHeight,
+static void getFullWindowSize(_GLFWwindow* window,
+                              int clientWidth, int clientHeight,
                               int* fullWidth, int* fullHeight)
 {
     RECT rect;
@@ -918,7 +917,7 @@
     rect.bottom = (long) clientHeight - 1;
 
     // Adjust according to window styles
-    AdjustWindowRectEx(&rect, _glfwWin.dwStyle, FALSE, _glfwWin.dwExStyle);
+    AdjustWindowRectEx(&rect, window->Win32.dwStyle, FALSE, window->Win32.dwExStyle);
 
     // Calculate width and height of full window
     *fullWidth = rect.right - rect.left + 1;
@@ -934,54 +933,60 @@
 // decreasing the possibility of forgetting to add one without the other.
 //========================================================================
 
-static void initWGLExtensions(void)
+static void initWGLExtensions(_GLFWwindow* window)
 {
     // This needs to include every function pointer loaded below
-    _glfwWin.SwapIntervalEXT = NULL;
-    _glfwWin.GetPixelFormatAttribivARB = NULL;
-    _glfwWin.GetExtensionsStringARB = NULL;
-    _glfwWin.GetExtensionsStringEXT = NULL;
-    _glfwWin.CreateContextAttribsARB = NULL;
+    window->WGL.SwapIntervalEXT = NULL;
+    window->WGL.GetPixelFormatAttribivARB = NULL;
+    window->WGL.GetExtensionsStringARB = NULL;
+    window->WGL.GetExtensionsStringEXT = NULL;
+    window->WGL.CreateContextAttribsARB = NULL;
 
     // This needs to include every extension used below except for
     // WGL_ARB_extensions_string and WGL_EXT_extensions_string
-    _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;
+    window->WGL.has_WGL_EXT_swap_control = GL_FALSE;
+    window->WGL.has_WGL_ARB_pixel_format = GL_FALSE;
+    window->WGL.has_WGL_ARB_multisample = GL_FALSE;
+    window->WGL.has_WGL_ARB_create_context = GL_FALSE;
 
-    _glfwWin.GetExtensionsStringEXT = (WGLGETEXTENSIONSSTRINGEXT_T)
+    window->WGL.GetExtensionsStringEXT = (WGLGETEXTENSIONSSTRINGEXT_T)
         wglGetProcAddress("wglGetExtensionsStringEXT");
-    if (!_glfwWin.GetExtensionsStringEXT)
+    if (!window->WGL.GetExtensionsStringEXT)
     {
-        _glfwWin.GetExtensionsStringARB = (WGLGETEXTENSIONSSTRINGARB_T)
+        window->WGL.GetExtensionsStringARB = (WGLGETEXTENSIONSSTRINGARB_T)
             wglGetProcAddress("wglGetExtensionsStringARB");
-        if (!_glfwWin.GetExtensionsStringARB)
+        if (!window->WGL.GetExtensionsStringARB)
             return;
     }
 
     if (_glfwPlatformExtensionSupported("WGL_ARB_multisample"))
-        _glfwWin.has_WGL_ARB_multisample = GL_TRUE;
+        window->WGL.has_WGL_ARB_multisample = GL_TRUE;
 
     if (_glfwPlatformExtensionSupported("WGL_ARB_create_context"))
     {
-        _glfwWin.has_WGL_ARB_create_context = GL_TRUE;
-        _glfwWin.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
+        window->WGL.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
             wglGetProcAddress("wglCreateContextAttribsARB");
+
+        if (window->WGL.CreateContextAttribsARB)
+            window->WGL.has_WGL_ARB_create_context = GL_TRUE;
     }
 
     if (_glfwPlatformExtensionSupported("WGL_EXT_swap_control"))
     {
-        _glfwWin.has_WGL_EXT_swap_control = GL_TRUE;
-        _glfwWin.SwapIntervalEXT = (WGLSWAPINTERVALEXT_T)
+        window->WGL.SwapIntervalEXT = (WGLSWAPINTERVALEXT_T)
             wglGetProcAddress("wglSwapIntervalEXT");
+
+        if (window->WGL.SwapIntervalEXT)
+            window->WGL.has_WGL_EXT_swap_control = GL_TRUE;
     }
 
     if (_glfwPlatformExtensionSupported("WGL_ARB_pixel_format"))
     {
-        _glfwWin.has_WGL_ARB_pixel_format = GL_TRUE;
-        _glfwWin.GetPixelFormatAttribivARB = (WGLGETPIXELFORMATATTRIBIVARB_T)
+        window->WGL.GetPixelFormatAttribivARB = (WGLGETPIXELFORMATATTRIBIVARB_T)
             wglGetProcAddress("wglGetPixelFormatAttribivARB");
+
+        if (window->WGL.GetPixelFormatAttribivARB)
+            window->WGL.has_WGL_ARB_pixel_format = GL_TRUE;
     }
 }
 
@@ -996,17 +1001,17 @@
 
     // Set window class parameters
     wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on...
-    wc.lpfnWndProc   = (WNDPROC)windowProc;           // Message handler
+    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.cbWndExtra    = sizeof(void*) + sizeof(int);   // Make room for one pointer
+    wc.hInstance     = _glfwLibrary.Win32.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");
+    wc.hIcon = LoadIcon(_glfwLibrary.Win32.instance, "GLFW_ICON");
     if (!wc.hIcon)
     {
         // Load default icon
@@ -1057,7 +1062,8 @@
 // Creates the GLFW window and rendering context
 //========================================================================
 
-static int createWindow(const _GLFWwndconfig* wndconfig,
+static int createWindow(_GLFWwindow* window,
+                        const _GLFWwndconfig* wndconfig,
                         const _GLFWfbconfig* fbconfig)
 {
     DWORD dwStyle, dwExStyle;
@@ -1065,16 +1071,16 @@
     RECT wa;
     POINT pos;
 
-    _glfwWin.DC = NULL;
-    _glfwWin.context = NULL;
-    _glfwWin.window = NULL;
+    window->WGL.DC = NULL;
+    window->WGL.context = NULL;
+    window->Win32.handle = 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)
+    if (window->mode == GLFW_FULLSCREEN)
     {
         dwStyle |= WS_POPUP;
 
@@ -1102,40 +1108,40 @@
     }
 
     // Remember window styles (used by getFullWindowSize)
-    _glfwWin.dwStyle   = dwStyle;
-    _glfwWin.dwExStyle = dwExStyle;
+    window->Win32.dwStyle   = dwStyle;
+    window->Win32.dwExStyle = dwExStyle;
 
     // Adjust window size for frame and title bar
-    getFullWindowSize(_glfwWin.width, _glfwWin.height, &fullWidth, &fullHeight);
+    getFullWindowSize(window->width, window->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)
+    if (window->mode == GLFW_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
+    window->Win32.handle = CreateWindowEx(window->Win32.dwExStyle,
+                                          _GLFW_WNDCLASSNAME,
+                                          "GLFW Window",
+                                          window->Win32.dwStyle,
+                                          wa.left, wa.top,       // Window position
+                                          fullWidth,             // Decorated window width
+                                          fullHeight,            // Decorated window height
+                                          NULL,                  // No parent window
+                                          NULL,                  // No menu
+                                          _glfwLibrary.Win32.instance,
+                                          NULL);                 // No lParam to WM_CREATE
 
-    if (!_glfwWin.window)
+    if (!window->Win32.handle)
     {
         fprintf(stderr, "Unable to create Win32 window\n");
         return GL_FALSE;
     }
 
-    _glfwWin.DC = GetDC(_glfwWin.window);
-    if (!_glfwWin.DC)
+    window->WGL.DC = GetDC(window->Win32.handle);
+    if (!window->WGL.DC)
     {
         fprintf(stderr, "Unable to retrieve GLFW window DC\n");
         return GL_FALSE;
@@ -1148,14 +1154,14 @@
         return GL_FALSE;
     }
 
-    _glfwWin.context = createContext(_glfwWin.DC, wndconfig, pixelFormat);
-    if (!_glfwWin.context)
+    window->WGL.context = createContext(window->WGL.DC, wndconfig, pixelFormat);
+    if (!window->WGL.context)
     {
         fprintf(stderr, "Unable to create OpenGL context\n");
         return GL_FALSE;
     }
 
-    if (!wglMakeCurrent(_glfwWin.DC, _glfwWin.context))
+    if (!wglMakeCurrent(window->WGL.DC, window->WGL.context))
     {
         fprintf(stderr, "Unable to make OpenGL context current\n");
         return GL_FALSE;
@@ -1165,9 +1171,9 @@
 
     // Initialize mouse position data
     GetCursorPos(&pos);
-    ScreenToClient(_glfwWin.window, &pos);
-    _glfwInput.OldMouseX = _glfwInput.MousePosX = pos.x;
-    _glfwInput.OldMouseY = _glfwInput.MousePosY = pos.y;
+    ScreenToClient(window->Win32.handle, &pos);
+    window->oldMouseX = window->mousePosX = pos.x;
+    window->oldMouseY = window->mousePosY = pos.y;
 
     return GL_TRUE;
 }
@@ -1179,35 +1185,27 @@
 
 static void destroyWindow(void)
 {
-    if (_glfwWin.context)
+    if (window->WGL.context)
     {
         wglMakeCurrent(NULL, NULL);
-        wglDeleteContext(_glfwWin.context);
-        _glfwWin.context = NULL;
+        wglDeleteContext(window->WGL.context);
+        window->WGL.context = NULL;
     }
 
-    if (_glfwWin.DC)
+    if (window->WGL.DC)
     {
-        ReleaseDC(_glfwWin.window, _glfwWin.DC);
-        _glfwWin.DC = NULL;
+        ReleaseDC(window->Win32.handle, window->WGL.DC);
+        window->WGL.DC = NULL;
     }
 
-    if (_glfwWin.window)
+    if (window->Win32.handle)
     {
-        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;
+        DestroyWindow(window->Win32.handle);
+        window->Win32.handle = NULL;
     }
 }
 
 
-
 //////////////////////////////////////////////////////////////////////////
 //////                       GLFW platform API                      //////
 //////////////////////////////////////////////////////////////////////////
@@ -1217,48 +1215,35 @@
 // created
 //========================================================================
 
-int _glfwPlatformOpenWindow(int width, int height,
+int _glfwPlatformOpenWindow(_GLFWwindow* window,
                             const _GLFWwndconfig* wndconfig,
                             const _GLFWfbconfig* fbconfig)
 {
     GLboolean recreateContext = GL_FALSE;
 
-    // Clear platform specific GLFW window state
-    _glfwWin.classAtom = 0;
-    _glfwWin.oldMouseLockValid = GL_FALSE;
+    window->Win32.desiredRefreshRate = wndconfig->refreshRate;
 
-    _glfwWin.desiredRefreshRate = wndconfig->refreshRate;
-
-    _glfwWin.classAtom = registerWindowClass();
-    if (!_glfwWin.classAtom)
-    {
-        fprintf(stderr, "Failed to register GLFW window class\n");
-        _glfwPlatformCloseWindow();
+    window->Win32.classAtom = registerWindowClass();
+    if (!window->Win32.classAtom)
         return GL_FALSE;
-    }
 
-    if (_glfwWin.fullscreen)
+    if (window->mode == GLFW_FULLSCREEN)
     {
-        _glfwSetVideoMode(&_glfwWin.width, &_glfwWin.height,
-                           fbconfig->redBits, fbconfig->greenBits, fbconfig->blueBits,
-                           wndconfig->refreshRate);
+        _glfwSetVideoMode(&window->width, &window->height,
+                          fbconfig->redBits, fbconfig->greenBits, fbconfig->blueBits,
+                          wndconfig->refreshRate);
     }
 
     initWGLExtensions();
 
-    if (!createWindow(wndconfig, fbconfig))
-    {
-        fprintf(stderr, "Failed to create GLFW window\n");
-        _glfwPlatformCloseWindow();
+    if (!createWindow(window, wndconfig, fbconfig))
         return GL_FALSE;
-    }
 
     if (wndconfig->glMajor > 2)
     {
-        if (!_glfwWin.has_WGL_ARB_create_context)
+        if (!window->WGL.has_WGL_ARB_create_context)
         {
-            fprintf(stderr, "OpenGL 3.0+ is not supported\n");
-            _glfwPlatformCloseWindow();
+            _glfwSetError(GLFW_UNAVAILABLE_VERSION);
             return GL_FALSE;
         }
 
@@ -1270,7 +1255,7 @@
         // 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)
+        if (window->WGL.has_WGL_ARB_multisample && window->WGL.has_WGL_ARB_pixel_format)
         {
             // We appear to have both the FSAA extension and the means to ask for it
             recreateContext = GL_TRUE;
@@ -1296,23 +1281,19 @@
 
         destroyWindow();
 
-        if (!createWindow(wndconfig, fbconfig))
-        {
-            fprintf(stderr, "Unable to re-create GLFW window\n");
-            _glfwPlatformCloseWindow();
+        if (!createWindow(window, wndconfig, fbconfig))
             return GL_FALSE;
-        }
     }
 
-    if (_glfwWin.fullscreen)
+    if (window->mode == GLFW_FULLSCREEN)
     {
         // Place the window above all topmost windows
-        SetWindowPos(_glfwWin.window, HWND_TOPMOST, 0,0,0,0,
+        SetWindowPos(window->Win32.handle, HWND_TOPMOST, 0,0,0,0,
                      SWP_NOMOVE | SWP_NOSIZE);
     }
 
-    setForegroundWindow(_glfwWin.window);
-    SetFocus(_glfwWin.window);
+    setForegroundWindow(window->Win32.handle);
+    SetFocus(window->Win32.handle);
 
     return GL_TRUE;
 }
@@ -1322,17 +1303,17 @@
 // Properly kill the window / video display
 //========================================================================
 
-void _glfwPlatformCloseWindow(void)
+void _glfwPlatformCloseWindow(_GLFWwindow* window)
 {
     destroyWindow();
 
-    if (_glfwWin.classAtom)
+    if (window->Win32.classAtom)
     {
-        UnregisterClass(_GLFW_WNDCLASSNAME, _glfwLibrary.instance);
-        _glfwWin.classAtom = 0;
+        UnregisterClass(_GLFW_WNDCLASSNAME, _glfwLibrary.Win32.instance);
+        window->Win32.classAtom = 0;
     }
 
-    if (_glfwWin.fullscreen)
+    if (window->mode == GLFW_FULLSCREEN)
     {
         // Restore original desktop resolution
         ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
@@ -1344,9 +1325,9 @@
 // Set the window title
 //========================================================================
 
-void _glfwPlatformSetWindowTitle(const char* title)
+void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
 {
-    SetWindowText(_glfwWin.window, title);
+    SetWindowText(window->Win32.handle, title);
 }
 
 
@@ -1354,14 +1335,14 @@
 // Set the window size.
 //========================================================================
 
-void _glfwPlatformSetWindowSize(int width, int height)
+void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
 {
-    int     bpp, mode = 0, refresh;
-    int     sizechanged = GL_FALSE;
-    GLint   drawbuffer;
+    int bpp, mode = 0, refresh;
+    int sizechanged = GL_FALSE;
+    GLint drawbuffer;
     GLfloat clearcolor[4];
 
-    if (_glfwWin.fullscreen)
+    if (window->mode == GLFW_FULLSCREEN)
     {
         // Get some info about the current mode
 
@@ -1375,12 +1356,11 @@
             bpp = dm.dmBitsPerPel;
 
             // Get closest match for target video mode
-            refresh = _glfwWin.desiredRefreshRate;
-            mode = _glfwGetClosestVideoModeBPP(&width, &height, &bpp,
-                                                &refresh);
+            refresh = window->Win32.desiredRefreshRate;
+            mode = _glfwGetClosestVideoModeBPP(&width, &height, &bpp, &refresh);
         }
         else
-            mode = _glfwWin.modeID;
+            mode = window->Win32.modeID;
     }
     else
     {
@@ -1390,37 +1370,22 @@
     }
 
     // Change window size before changing fullscreen mode?
-    if (_glfwWin.fullscreen && (width > _glfwWin.width))
+    if (window->mode == GLFW_FULLSCREEN && (width > window->width))
     {
-        SetWindowPos(_glfwWin.window, HWND_TOP, 0, 0, width, height,
-                      SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
+        SetWindowPos(window->Win32.handle, 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)
-    {
+    if (window->mode == GLFW_FULLSCREEN && mode != window->Win32.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);
+        SetWindowPos(window->Win32.handle, HWND_TOP, 0, 0, width, height,
+                     SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
     }
 }
 
@@ -1429,10 +1394,10 @@
 // Set the window position
 //========================================================================
 
-void _glfwPlatformSetWindowPos(int x, int y)
+void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y)
 {
-    (void) SetWindowPos(_glfwWin.window, HWND_TOP, x, y, 0, 0,
-                         SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
+    SetWindowPos(window->Win32.handle, HWND_TOP, x, y, 0, 0,
+                 SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
 }
 
 
@@ -1440,24 +1405,24 @@
 // Window iconification
 //========================================================================
 
-void _glfwPlatformIconifyWindow(void)
+void _glfwPlatformIconifyWindow(_GLFWwindow* window)
 {
     // Iconify window
-    CloseWindow(_glfwWin.window);
-    _glfwWin.iconified = GL_TRUE;
+    CloseWindow(window->Win32.handle);
+    window->iconified = GL_TRUE;
 
     // If we are in fullscreen mode we need to change video modes
-    if (_glfwWin.fullscreen)
+    if (window->mode == GLFW_FULLSCREEN)
     {
         // Change display settings to the desktop resolution
         ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
     }
 
     // Unlock mouse
-    if (!_glfwWin.oldMouseLockValid)
+    if (!window->Win32.oldMouseLockValid)
     {
-        _glfwWin.oldMouseLock = _glfwWin.mouseLock;
-        _glfwWin.oldMouseLockValid = GL_TRUE;
+        window->Win32.oldMouseLock = _glfwWin.mouseLock;
+        window->Win32.oldMouseLockValid = GL_TRUE;
         glfwEnable(GLFW_MOUSE_CURSOR);
     }
 }
@@ -1467,31 +1432,30 @@
 // Window un-iconification
 //========================================================================
 
-void _glfwPlatformRestoreWindow(void)
+void _glfwPlatformRestoreWindow(_GLFWwindow* window)
 {
-    // If we are in fullscreen mode we need to change video modes
-    if (_glfwWin.fullscreen)
+    if (window->mode == GLFW_FULLSCREEN)
     {
         // Change display settings to the user selected mode
-        _glfwSetVideoModeMODE(_glfwWin.modeID);
+        _glfwSetVideoModeMODE(window->Win32.modeID);
     }
 
     // Un-iconify window
-    OpenIcon(_glfwWin.window);
+    OpenIcon(window->Win32.handle);
 
     // Make sure that our window ends up on top of things
-    ShowWindow(_glfwWin.window, SW_SHOW);
-    setForegroundWindow(_glfwWin.window);
-    SetFocus(_glfwWin.window);
+    ShowWindow(window->Win32.handle, SW_SHOW);
+    setForegroundWindow(window->Win32.handle);
+    SetFocus(window->Win32.handle);
 
     // Window is no longer iconified
-    _glfwWin.iconified = GL_FALSE;
+    window->iconified = GL_FALSE;
 
     // Lock mouse, if necessary
-    if (_glfwWin.oldMouseLockValid && _glfwWin.oldMouseLock)
+    if (window->Win32.oldMouseLockValid && window->Win32.oldMouseLock)
         glfwDisable(GLFW_MOUSE_CURSOR);
 
-    _glfwWin.oldMouseLockValid = GL_FALSE;
+    window->Win32.oldMouseLockValid = GL_FALSE;
 }
 
 
@@ -1501,7 +1465,9 @@
 
 void _glfwPlatformSwapBuffers(void)
 {
-    _glfw_SwapBuffers(_glfwWin.DC);
+    _GLFWwindow* window = _glfwLibrary.currentWindow;
+
+    _glfw_SwapBuffers(window->WGL.DC);
 }
 
 
@@ -1511,8 +1477,10 @@
 
 void _glfwPlatformSwapInterval(int interval)
 {
-    if (_glfwWin.has_WGL_EXT_swap_control)
-        _glfwWin.SwapIntervalEXT(interval);
+    _GLFWwindow* window = _glfwLibrary.currentWindow;
+
+    if (window->WGL.has_WGL_EXT_swap_control)
+        window->WGL.SwapIntervalEXT(interval);
 }
 
 
@@ -1526,83 +1494,85 @@
     DEVMODE dm;
     int pixelFormat, mode;
 
-    // Obtain a detailed description of current pixel format
-    pixelFormat = _glfw_GetPixelFormat(_glfwWin.DC);
+    _GLFWwindow* window = _glfwLibrary.currentWindow;
 
-    if (_glfwWin.has_WGL_ARB_pixel_format)
+    // Obtain a detailed description of current pixel format
+    pixelFormat = _glfw_GetPixelFormat(window->WGL.DC);
+
+    if (window->WGL.has_WGL_ARB_pixel_format)
     {
         if (getPixelFormatAttrib(pixelFormat, WGL_ACCELERATION_ARB) !=
             WGL_NO_ACCELERATION_ARB)
         {
-            _glfwWin.accelerated = GL_TRUE;
+            window->accelerated = GL_TRUE;
         }
         else
-            _glfwWin.accelerated = GL_FALSE;
+            window->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);
+        window->redBits = getPixelFormatAttrib(pixelFormat, WGL_RED_BITS_ARB);
+        window->greenBits = getPixelFormatAttrib(pixelFormat, WGL_GREEN_BITS_ARB);
+        window->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);
+        window->alphaBits = getPixelFormatAttrib(pixelFormat, WGL_ALPHA_BITS_ARB);
+        window->depthBits = getPixelFormatAttrib(pixelFormat, WGL_DEPTH_BITS_ARB);
+        window->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);
+        window->accumRedBits = getPixelFormatAttrib(pixelFormat, WGL_ACCUM_RED_BITS_ARB);
+        window->accumGreenBits = getPixelFormatAttrib(pixelFormat, WGL_ACCUM_GREEN_BITS_ARB);
+        window->accumBlueBits = getPixelFormatAttrib(pixelFormat, WGL_ACCUM_BLUE_BITS_ARB);
+        window->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;
+        window->auxBuffers = getPixelFormatAttrib(pixelFormat, WGL_AUX_BUFFERS_ARB);
+        window->stereo = getPixelFormatAttrib(pixelFormat, WGL_STEREO_ARB) ? GL_TRUE : GL_FALSE;
 
-        if (_glfwWin.has_WGL_ARB_multisample)
+        if (window->WGL.has_WGL_ARB_multisample)
         {
-            _glfwWin.samples = getPixelFormatAttrib(pixelFormat, WGL_SAMPLES_ARB);
+            window->samples = getPixelFormatAttrib(pixelFormat, WGL_SAMPLES_ARB);
             // Should we force 1 to 0 here for consistency, or keep 1 for transparency?
         }
         else
-            _glfwWin.samples = 0;
+            window->samples = 0;
     }
     else
     {
-        _glfw_DescribePixelFormat(_glfwWin.DC, pixelFormat,
+        _glfw_DescribePixelFormat(window->WGL.DC, pixelFormat,
                                   sizeof(PIXELFORMATDESCRIPTOR), &pfd);
 
         // Is current OpenGL context accelerated?
-        _glfwWin.accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||
-                               !(pfd.dwFlags & PFD_GENERIC_FORMAT) ? 1 : 0;
+        window->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;
+        window->redBits        = pfd.cRedBits;
+        window->greenBits      = pfd.cGreenBits;
+        window->blueBits       = pfd.cBlueBits;
+        window->alphaBits      = pfd.cAlphaBits;
+        window->depthBits      = pfd.cDepthBits;
+        window->stencilBits    = pfd.cStencilBits;
+        window->accumRedBits   = pfd.cAccumRedBits;
+        window->accumGreenBits = pfd.cAccumGreenBits;
+        window->accumBlueBits  = pfd.cAccumBlueBits;
+        window->accumAlphaBits = pfd.cAccumAlphaBits;
+        window->auxBuffers     = pfd.cAuxBuffers;
+        window->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;
+        window->samples = 0;
     }
 
     // Get refresh rate
-    mode = _glfwWin.fullscreen ? _glfwWin.modeID : ENUM_CURRENT_SETTINGS;
+    mode = (window->mode == GLFW_FULLSCREEN) ? window->Win32.modeID : ENUM_CURRENT_SETTINGS;
     dm.dmSize = sizeof(DEVMODE);
 
     if (EnumDisplaySettings(NULL, mode, &dm))
     {
-        _glfwWin.refreshRate = dm.dmDisplayFrequency;
-        if (_glfwWin.refreshRate <= 1)
-            _glfwWin.refreshRate = 0;
+        window->refreshRate = dm.dmDisplayFrequency;
+        if (window->refreshRate <= 1)
+            window->refreshRate = 0;
     }
     else
-        _glfwWin.refreshRate = 0;
+        window->refreshRate = 0;
 }
 
 
@@ -1617,16 +1587,16 @@
 
     // Flag: mouse was not moved (will be changed by _glfwGetNextEvent if
     // there was a mouse move event)
-    _glfwInput.MouseMoved = GL_FALSE;
+    window->mouseMoved = GL_FALSE;
     if (_glfwWin.mouseLock)
     {
-        _glfwInput.OldMouseX = _glfwWin.width/2;
-        _glfwInput.OldMouseY = _glfwWin.height/2;
+        window->oldMouseX = _glfwWin.width/2;
+        window->oldMouseY = _glfwWin.height/2;
     }
     else
     {
-        _glfwInput.OldMouseX = _glfwInput.MousePosX;
-        _glfwInput.OldMouseY = _glfwInput.MousePosY;
+        window->oldMouseX = window->mousePosX;
+        window->oldMouseY = window->mousePosY;
     }
 
     // Check for new window messages
@@ -1664,25 +1634,25 @@
 
         // 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)
+        if (!lshift_down && window->key[GLFW_KEY_LSHIFT] == 1)
             _glfwInputKey(GLFW_KEY_LSHIFT, GLFW_RELEASE);
 
-        if (!rshift_down && _glfwInput.Key[ GLFW_KEY_RSHIFT ] == 1)
+        if (!rshift_down && window->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)
+    if (window->mouseMoved && _glfwWin.mouseLock)
     {
-        _glfwPlatformSetMouseCursorPos(_glfwWin.width / 2,
-                                        _glfwWin.height / 2);
+        _glfwPlatformSetMouseCursorPos(window->width / 2,
+                                       window->height / 2);
     }
 
     // Was there a window close request?
-    if (winclosed && _glfwWin.windowCloseCallback)
+    if (winclosed && window->closeCallback)
     {
         // Check if the program wants us to close the window
-        winclosed = _glfwWin.windowCloseCallback();
+        winclosed = window->closeCallback();
     }
     if (winclosed)
         glfwCloseWindow();
@@ -1690,7 +1660,7 @@
 
 
 //========================================================================
-// _glfwPlatformWaitEvents() - Wait for new window and input events
+// Wait for new window and input events
 //========================================================================
 
 void _glfwPlatformWaitEvents(void)
@@ -1705,18 +1675,18 @@
 // Hide mouse cursor (lock it)
 //========================================================================
 
-void _glfwPlatformHideMouseCursor(void)
+void _glfwPlatformHideMouseCursor(_GLFWwindow* window)
 {
     RECT ClipWindowRect;
 
     ShowCursor(FALSE);
 
     // Clip cursor to the window
-    if (GetWindowRect(_glfwWin.window, &ClipWindowRect))
+    if (GetWindowRect(window->Win32.handle, &ClipWindowRect))
         ClipCursor(&ClipWindowRect);
 
     // Capture cursor to user window
-    SetCapture(_glfwWin.window);
+    SetCapture(window->Win32.handle);
 }
 
 
@@ -1724,7 +1694,7 @@
 // Show mouse cursor (unlock it)
 //========================================================================
 
-void _glfwPlatformShowMouseCursor(void)
+void _glfwPlatformShowMouseCursor(_GLFWwindow* window)
 {
     // Un-capture cursor
     ReleaseCapture();
@@ -1740,14 +1710,14 @@
 // Set physical mouse cursor position
 //========================================================================
 
-void _glfwPlatformSetMouseCursorPos(int x, int y)
+void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y)
 {
     POINT pos;
 
     // Convert client coordinates to screen coordinates
     pos.x = x;
     pos.y = y;
-    ClientToScreen(_glfwWin.window, &pos);
+    ClientToScreen(window->Win32.handle, &pos);
 
     SetCursorPos(pos.x, pos.y);
 }