From c850d3b11189a767fa1b5a7f62c01b04b3ac6589 Mon Sep 17 00:00:00 2001
From: Laurent Gomila <laurent.gom@gmail.com>
Date: Mon, 4 Jul 2011 08:21:40 +0200
Subject: [PATCH] Implemented global inputs (sf::Keyboard, sf::Mouse,
 sf::Joystick) and removed the event-based sf::Input. Window::WaitEvent now
 works with joystick events as well. Added Event::JoystickConnected and
 Event::JoystickDisconnected. Added Window::GetCursorPosition.

---
 examples/opengl/OpenGL.cpp                    |   6 +-
 examples/pong/Pong.cpp                        |   6 +-
 examples/shader/Shader.cpp                    |  22 +-
 examples/window/Window.cpp                    |   2 +-
 include/SFML/System/Vector2.hpp               |   5 +-
 include/SFML/Window.hpp                       |   4 +-
 include/SFML/Window/Event.hpp                 | 278 ++++--------------
 include/SFML/Window/Input.hpp                 | 198 -------------
 include/SFML/Window/Joystick.hpp              | 203 +++++++++++++
 include/SFML/Window/Keyboard.hpp              | 208 +++++++++++++
 include/SFML/Window/Mouse.hpp                 | 131 +++++++++
 include/SFML/Window/Window.hpp                |  35 ++-
 src/SFML/Graphics/Shader.cpp                  |   2 +-
 src/SFML/Window/CMakeLists.txt                |  25 +-
 src/SFML/Window/Input.cpp                     | 149 ----------
 src/SFML/Window/InputImpl.hpp                 |  48 +++
 src/SFML/Window/Joystick.cpp                  |  75 +++++
 src/SFML/Window/JoystickImpl.hpp              |  95 ++++++
 src/SFML/Window/JoystickManager.cpp           | 111 +++++++
 src/SFML/Window/JoystickManager.hpp           | 118 ++++++++
 src/SFML/Window/Keyboard.cpp                  |  40 +++
 src/SFML/Window/Linux/InputImpl.cpp           | 228 ++++++++++++++
 src/SFML/Window/Linux/InputImpl.hpp           |  83 ++++++
 src/SFML/Window/Linux/Joystick.cpp            | 204 -------------
 src/SFML/Window/Linux/JoystickImpl.cpp        | 168 +++++++++++
 .../Linux/{Joystick.hpp => JoystickImpl.hpp}  | 214 +++++++-------
 src/SFML/Window/Linux/WindowImplX11.cpp       | 248 ++++++++--------
 src/SFML/Window/Linux/WindowImplX11.hpp       |  14 +-
 src/SFML/Window/Mouse.cpp                     |  58 ++++
 src/SFML/Window/OSX/InputImpl.cpp             |  60 ++++
 src/SFML/Window/OSX/InputImpl.hpp             |  83 ++++++
 .../{Joystick.hpp => OSX/JoystickImpl.cpp}    |  74 +++--
 .../Joystick.hpp => OSX/JoystickImpl.hpp}     | 196 ++++++------
 src/SFML/Window/OSX/SFApplication.h           |   4 +-
 src/SFML/Window/OSX/SFApplication.m           |  11 +-
 src/SFML/Window/OSX/SFWindowController.mm     |   4 +-
 src/SFML/Window/OSX/WindowImplCocoa.hpp       |  13 +-
 src/SFML/Window/OSX/WindowImplCocoa.mm        |  12 +-
 src/SFML/Window/Win32/InputImpl.cpp           | 179 +++++++++++
 src/SFML/Window/Win32/InputImpl.hpp           |  83 ++++++
 src/SFML/Window/Win32/Joystick.cpp            | 149 ----------
 src/SFML/Window/Win32/JoystickImpl.cpp        | 134 +++++++++
 src/SFML/Window/Win32/JoystickImpl.hpp        | 107 +++++++
 src/SFML/Window/Win32/WindowImplWin32.cpp     | 216 +++++++-------
 src/SFML/Window/Win32/WindowImplWin32.hpp     |  14 +-
 src/SFML/Window/Window.cpp                    |  35 ++-
 src/SFML/Window/WindowImpl.cpp                | 114 ++++---
 src/SFML/Window/WindowImpl.hpp                |  20 +-
 48 files changed, 2969 insertions(+), 1517 deletions(-)
 delete mode 100644 include/SFML/Window/Input.hpp
 create mode 100644 include/SFML/Window/Joystick.hpp
 create mode 100644 include/SFML/Window/Keyboard.hpp
 create mode 100644 include/SFML/Window/Mouse.hpp
 delete mode 100644 src/SFML/Window/Input.cpp
 create mode 100644 src/SFML/Window/InputImpl.hpp
 create mode 100644 src/SFML/Window/Joystick.cpp
 create mode 100644 src/SFML/Window/JoystickImpl.hpp
 create mode 100644 src/SFML/Window/JoystickManager.cpp
 create mode 100644 src/SFML/Window/JoystickManager.hpp
 create mode 100644 src/SFML/Window/Keyboard.cpp
 create mode 100644 src/SFML/Window/Linux/InputImpl.cpp
 create mode 100644 src/SFML/Window/Linux/InputImpl.hpp
 delete mode 100644 src/SFML/Window/Linux/Joystick.cpp
 create mode 100644 src/SFML/Window/Linux/JoystickImpl.cpp
 rename src/SFML/Window/Linux/{Joystick.hpp => JoystickImpl.hpp} (61%)
 create mode 100644 src/SFML/Window/Mouse.cpp
 create mode 100644 src/SFML/Window/OSX/InputImpl.cpp
 create mode 100644 src/SFML/Window/OSX/InputImpl.hpp
 rename src/SFML/Window/{Joystick.hpp => OSX/JoystickImpl.cpp} (59%)
 rename src/SFML/Window/{Win32/Joystick.hpp => OSX/JoystickImpl.hpp} (62%)
 create mode 100644 src/SFML/Window/Win32/InputImpl.cpp
 create mode 100644 src/SFML/Window/Win32/InputImpl.hpp
 delete mode 100644 src/SFML/Window/Win32/Joystick.cpp
 create mode 100644 src/SFML/Window/Win32/JoystickImpl.cpp
 create mode 100644 src/SFML/Window/Win32/JoystickImpl.hpp

diff --git a/examples/opengl/OpenGL.cpp b/examples/opengl/OpenGL.cpp
index 33cfd837..3b02e38c 100644
--- a/examples/opengl/OpenGL.cpp
+++ b/examples/opengl/OpenGL.cpp
@@ -68,7 +68,7 @@ int main()
                 window.Close();
 
             // Escape key : exit
-            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Escape))
+            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Keyboard::Escape))
                 window.Close();
 
             // Adjust the viewport when the window is resized
@@ -90,8 +90,8 @@ int main()
         glClear(GL_DEPTH_BUFFER_BIT);
 
         // We get the position of the mouse cursor, so that we can move the box accordingly
-        float x =  window.GetInput().GetMouseX() * 200.f / window.GetWidth()  - 100.f;
-        float y = -window.GetInput().GetMouseY() * 200.f / window.GetHeight() + 100.f;
+        float x =  window.GetCursorPosition().x * 200.f / window.GetWidth()  - 100.f;
+        float y = -window.GetCursorPosition().y * 200.f / window.GetHeight() + 100.f;
 
         // Apply some transformations
         glMatrixMode(GL_MODELVIEW);
diff --git a/examples/pong/Pong.cpp b/examples/pong/Pong.cpp
index 84020e2f..1d03d9ef 100644
--- a/examples/pong/Pong.cpp
+++ b/examples/pong/Pong.cpp
@@ -89,7 +89,7 @@ int main()
         {
             // Window closed or escape key pressed : exit
             if ((event.Type == sf::Event::Closed) || 
-               ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Escape)))
+               ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Keyboard::Escape)))
             {
                 window.Close();
                 break;
@@ -99,9 +99,9 @@ int main()
         if (isPlaying)
         {
             // Move the player's paddle
-            if (window.GetInput().IsKeyDown(sf::Key::Up) && (leftPaddle.GetPosition().y > 5.f))
+            if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Up) && (leftPaddle.GetPosition().y > 5.f))
                 leftPaddle.Move(0.f, -leftPaddleSpeed * window.GetFrameTime() / 1000.f);
-            if (window.GetInput().IsKeyDown(sf::Key::Down) && (leftPaddle.GetPosition().y < window.GetView().GetSize().y - leftPaddle.GetSize().y - 5.f))
+            if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Down) && (leftPaddle.GetPosition().y < window.GetView().GetSize().y - leftPaddle.GetSize().y - 5.f))
                 leftPaddle.Move(0.f, leftPaddleSpeed * window.GetFrameTime() / 1000.f);
 
             // Move the computer's paddle
diff --git a/examples/shader/Shader.cpp b/examples/shader/Shader.cpp
index ee984a97..b30257a1 100644
--- a/examples/shader/Shader.cpp
+++ b/examples/shader/Shader.cpp
@@ -179,19 +179,19 @@ int main()
             if (event.Type == sf::Event::KeyPressed)
             {
                 // Escape key : exit
-                if (event.Key.Code == sf::Key::Escape)
+                if (event.Key.Code == sf::Keyboard::Escape)
                     window.Close();
 
                 // Numpad : switch effect
                 switch (event.Key.Code)
                 {
-                    case sf::Key::Numpad1 : backgroundShader.GotoPrevious(); break;
-                    case sf::Key::Numpad4 : backgroundShader.GotoNext();     break;
-                    case sf::Key::Numpad2 : entityShader.GotoPrevious();     break;
-                    case sf::Key::Numpad5 : entityShader.GotoNext();         break;
-                    case sf::Key::Numpad3 : globalShader.GotoPrevious();     break;
-                    case sf::Key::Numpad6 : globalShader.GotoNext();         break;
-                    default :                                                break;
+                    case sf::Keyboard::Numpad1 : backgroundShader.GotoPrevious(); break;
+                    case sf::Keyboard::Numpad4 : backgroundShader.GotoNext();     break;
+                    case sf::Keyboard::Numpad2 : entityShader.GotoPrevious();     break;
+                    case sf::Keyboard::Numpad5 : entityShader.GotoNext();         break;
+                    case sf::Keyboard::Numpad3 : globalShader.GotoPrevious();     break;
+                    case sf::Keyboard::Numpad6 : globalShader.GotoNext();         break;
+                    default : break;
                 }
 
                 // Update the text
@@ -202,8 +202,8 @@ int main()
         }
 
         // Get the mouse position in the range [0, 1]
-        float mouseX = window.GetInput().GetMouseX() / static_cast<float>(window.GetWidth());
-        float mouseY = window.GetInput().GetMouseY() / static_cast<float>(window.GetHeight());
+        float mouseX = window.GetCursorPosition().x / static_cast<float>(window.GetWidth());
+        float mouseY = window.GetCursorPosition().y / static_cast<float>(window.GetHeight());
 
         // Update the shaders
         backgroundShader.Update(mouseX, mouseY);
@@ -265,7 +265,7 @@ void DisplayError()
                 window.Close();
 
             // Escape key : exit
-            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Escape))
+            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Keyboard::Escape))
                 window.Close();
         }
 
diff --git a/examples/window/Window.cpp b/examples/window/Window.cpp
index 7a0d9414..fb99a1b1 100644
--- a/examples/window/Window.cpp
+++ b/examples/window/Window.cpp
@@ -45,7 +45,7 @@ int main()
                 window.Close();
 
             // Escape key : exit
-            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Escape))
+            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Keyboard::Escape))
                 window.Close();
 
             // Resize event : adjust viewport
diff --git a/include/SFML/System/Vector2.hpp b/include/SFML/System/Vector2.hpp
index 399710e0..6b50bc49 100644
--- a/include/SFML/System/Vector2.hpp
+++ b/include/SFML/System/Vector2.hpp
@@ -250,8 +250,9 @@ bool operator !=(const Vector2<T>& left, const Vector2<T>& right);
 #include <SFML/System/Vector2.inl>
 
 // Define the most common types
-typedef Vector2<int>   Vector2i;
-typedef Vector2<float> Vector2f;
+typedef Vector2<int>          Vector2i;
+typedef Vector2<unsigned int> Vector2u;
+typedef Vector2<float>        Vector2f;
 
 } // namespace sf
 
diff --git a/include/SFML/Window.hpp b/include/SFML/Window.hpp
index db1c7b46..7035e958 100644
--- a/include/SFML/Window.hpp
+++ b/include/SFML/Window.hpp
@@ -33,7 +33,9 @@
 #include <SFML/Window/Context.hpp>
 #include <SFML/Window/ContextSettings.hpp>
 #include <SFML/Window/Event.hpp>
-#include <SFML/Window/Input.hpp>
+#include <SFML/Window/Joystick.hpp>
+#include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window/Mouse.hpp>
 #include <SFML/Window/VideoMode.hpp>
 #include <SFML/Window/Window.hpp>
 #include <SFML/Window/WindowStyle.hpp>
diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp
index 5d1b8834..e294cc0e 100644
--- a/include/SFML/Window/Event.hpp
+++ b/include/SFML/Window/Event.hpp
@@ -29,174 +29,13 @@
 // Headers
 ////////////////////////////////////////////////////////////
 #include <SFML/Config.hpp>
+#include <SFML/Window/Joystick.hpp>
+#include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window/Mouse.hpp>
 
 
 namespace sf
 {
-namespace Key
-{
-    ////////////////////////////////////////////////////////////
-    /// \ingroup window
-    /// \brief Definition of key codes for keyboard events
-    ///
-    ////////////////////////////////////////////////////////////
-    enum Code
-    {
-        A = 'a',      ///< The A key
-        B = 'b',      ///< The B key
-        C = 'c',      ///< The C key
-        D = 'd',      ///< The D key
-        E = 'e',      ///< The E key
-        F = 'f',      ///< The F key
-        G = 'g',      ///< The G key
-        H = 'h',      ///< The H key
-        I = 'i',      ///< The I key
-        J = 'j',      ///< The J key
-        K = 'k',      ///< The K key
-        L = 'l',      ///< The L key
-        M = 'm',      ///< The M key
-        N = 'n',      ///< The N key
-        O = 'o',      ///< The O key
-        P = 'p',      ///< The P key
-        Q = 'q',      ///< The Q key
-        R = 'r',      ///< The R key
-        S = 's',      ///< The S key
-        T = 't',      ///< The T key
-        U = 'u',      ///< The U key
-        V = 'v',      ///< The V key
-        W = 'w',      ///< The W key
-        X = 'x',      ///< The X key
-        Y = 'y',      ///< The Y key
-        Z = 'z',      ///< The Z key
-        Num0 = '0',   ///< The 0 key
-        Num1 = '1',   ///< The 1 key
-        Num2 = '2',   ///< The 2 key
-        Num3 = '3',   ///< The 3 key
-        Num4 = '4',   ///< The 4 key
-        Num5 = '5',   ///< The 5 key
-        Num6 = '6',   ///< The 6 key
-        Num7 = '7',   ///< The 7 key
-        Num8 = '8',   ///< The 8 key
-        Num9 = '9',   ///< The 9 key
-        Escape = 256, ///< The Escape key
-        LControl,     ///< The left Control key
-        LShift,       ///< The left Shift key
-        LAlt,         ///< The left Alt key
-        LSystem,      ///< The left OS specific key : windows (Windows and Linux), apple (MacOS X), ...
-        RControl,     ///< The right Control key
-        RShift,       ///< The right Shift key
-        RAlt,         ///< The right Alt key
-        RSystem,      ///< The right OS specific key : windows (Windows and Linux), apple (MacOS X), ...
-        Menu,         ///< The Menu key
-        LBracket,     ///< The [ key
-        RBracket,     ///< The ] key
-        SemiColon,    ///< The ; key
-        Comma,        ///< The , key
-        Period,       ///< The . key
-        Quote,        ///< The ' key
-        Slash,        ///< The / key
-        BackSlash,    ///< The \ key
-        Tilde,        ///< The ~ key
-        Equal,        ///< The = key
-        Dash,         ///< The - key
-        Space,        ///< The Space key
-        Return,       ///< The Return key
-        Back,         ///< The Backspace key
-        Tab,          ///< The Tabulation key
-        PageUp,       ///< The Page up key
-        PageDown,     ///< The Page down key
-        End,          ///< The End key
-        Home,         ///< The Home key
-        Insert,       ///< The Insert key
-        Delete,       ///< The Delete key
-        Add,          ///< +
-        Subtract,     ///< -
-        Multiply,     ///< *
-        Divide,       ///< /
-        Left,         ///< Left arrow
-        Right,        ///< Right arrow
-        Up,           ///< Up arrow
-        Down,         ///< Down arrow
-        Numpad0,      ///< The numpad 0 key
-        Numpad1,      ///< The numpad 1 key
-        Numpad2,      ///< The numpad 2 key
-        Numpad3,      ///< The numpad 3 key
-        Numpad4,      ///< The numpad 4 key
-        Numpad5,      ///< The numpad 5 key
-        Numpad6,      ///< The numpad 6 key
-        Numpad7,      ///< The numpad 7 key
-        Numpad8,      ///< The numpad 8 key
-        Numpad9,      ///< The numpad 9 key
-        F1,           ///< The F1 key
-        F2,           ///< The F2 key
-        F3,           ///< The F3 key
-        F4,           ///< The F4 key
-        F5,           ///< The F5 key
-        F6,           ///< The F6 key
-        F7,           ///< The F7 key
-        F8,           ///< The F8 key
-        F9,           ///< The F8 key
-        F10,          ///< The F10 key
-        F11,          ///< The F11 key
-        F12,          ///< The F12 key
-        F13,          ///< The F13 key
-        F14,          ///< The F14 key
-        F15,          ///< The F15 key
-        Pause,        ///< The Pause key
-
-        Count         ///< Keep last -- the total number of keyboard keys
-    };
-}
-
-
-namespace Mouse
-{
-    ////////////////////////////////////////////////////////////
-    /// \ingroup window
-    /// \brief Definition of button codes for mouse events
-    ///
-    ////////////////////////////////////////////////////////////
-    enum Button
-    {
-        Left,     ///< The left mouse button
-        Right,    ///< The right mouse button
-        Middle,   ///< The middle (wheel) mouse button
-        XButton1, ///< The first extra mouse button
-        XButton2, ///< The second extra mouse button
-
-        ButtonCount     ///< Keep last -- the total number of mouse buttons
-    };
-}
-
-
-namespace Joy
-{
-    ////////////////////////////////////////////////////////////
-    /// \ingroup window
-    /// \brief Definition of joystick axis for joystick events
-    ///
-    ////////////////////////////////////////////////////////////
-    enum Axis
-    {
-        AxisX,   ///< The X axis
-        AxisY,   ///< The Y axis
-        AxisZ,   ///< The Z axis
-        AxisR,   ///< The R axis
-        AxisU,   ///< The U axis
-        AxisV,   ///< The V axis
-        AxisPOV, ///< The Point-Of-View axis (hat)
-
-        AxisCount // Keep last -- total number of joystick axis
-    };
-
-    enum
-    {
-        Count       = 8, ///< Total number of supported joysticks
-        ButtonCount = 32 ///< Total number of supported joystick buttons
-    };
-}
-
-
 ////////////////////////////////////////////////////////////
 /// \brief Defines a system event and its parameters
 ///
@@ -205,17 +44,27 @@ class Event
 {
 public :
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Size events parameters (Resized)
+    ///
+    ////////////////////////////////////////////////////////////
+    struct SizeEvent
+    {
+        unsigned int Width;  ///< New width, in pixels
+        unsigned int Height; ///< New height, in pixels
+    };
+
     ////////////////////////////////////////////////////////////
     /// \brief Keyboard event parameters (KeyPressed, KeyReleased)
     ///
     ////////////////////////////////////////////////////////////
     struct KeyEvent
     {
-        Key::Code Code;    ///< Code of the key that has been pressed
-        bool      Alt;     ///< Is the Alt key pressed?
-        bool      Control; ///< Is the Control key pressed?
-        bool      Shift;   ///< Is the Shift key pressed?
-        bool      System;  ///< Is the System key pressed?
+        Keyboard::Key Code;    ///< Code of the key that has been pressed
+        bool          Alt;     ///< Is the Alt key pressed?
+        bool          Control; ///< Is the Control key pressed?
+        bool          Shift;   ///< Is the Shift key pressed?
+        bool          System;  ///< Is the System key pressed?
     };
 
     ////////////////////////////////////////////////////////////
@@ -261,35 +110,35 @@ public :
     };
 
     ////////////////////////////////////////////////////////////
-    /// \brief Joystick axis move event parameters (JoyMoved)
+    /// \brief Joystick connection events parameters
+    ///        (JoystickConnected, JoystickDisconnected)
     ///
     ////////////////////////////////////////////////////////////
-    struct JoyMoveEvent
+    struct JoystickConnectEvent
     {
-        unsigned int JoystickId; ///< Index of the joystick (in range [0 .. Joy::Count - 1])
-        Joy::Axis    Axis;       ///< Axis on which the joystick moved
-        float        Position;   ///< New position on the axis (in range [-100 .. 100])
+        unsigned int JoystickId; ///< Index of the joystick (in range [0 .. Joystick::Count - 1])
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Joystick axis move event parameters (JoystickMoved)
+    ///
+    ////////////////////////////////////////////////////////////
+    struct JoystickMoveEvent
+    {
+        unsigned int   JoystickId; ///< Index of the joystick (in range [0 .. Joystick::Count - 1])
+        Joystick::Axis Axis;       ///< Axis on which the joystick moved
+        float          Position;   ///< New position on the axis (in range [-100 .. 100])
     };
 
     ////////////////////////////////////////////////////////////
     /// \brief Joystick buttons events parameters
-    ///        (JoyButtonPressed, JoyButtonReleased)
+    ///        (JoystickButtonPressed, JoystickButtonReleased)
     ///
     ////////////////////////////////////////////////////////////
-    struct JoyButtonEvent
+    struct JoystickButtonEvent
     {
-        unsigned int JoystickId; ///< Index of the joystick (in range [0 .. Joy::Count - 1])
-        unsigned int Button;     ///< Index of the button that has been pressed (in range [0 .. Joy::ButtonCount - 1])
-    };
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Size events parameters (Resized)
-    ///
-    ////////////////////////////////////////////////////////////
-    struct SizeEvent
-    {
-        unsigned int Width;  ///< New width, in pixels
-        unsigned int Height; ///< New height, in pixels
+        unsigned int JoystickId; ///< Index of the joystick (in range [0 .. Joystick::Count - 1])
+        unsigned int Button;     ///< Index of the button that has been pressed (in range [0 .. Joystick::ButtonCount - 1])
     };
 
     ////////////////////////////////////////////////////////////
@@ -298,24 +147,26 @@ public :
     ////////////////////////////////////////////////////////////
     enum EventType
     {
-        Closed,              ///< The window requested to be closed
-        Resized,             ///< The window was resized
-        LostFocus,           ///< The window lost the focus
-        GainedFocus,         ///< The window gained the focus
-        TextEntered,         ///< A character was entered
-        KeyPressed,          ///< A key was pressed
-        KeyReleased,         ///< A key was released
-        MouseWheelMoved,     ///< The mouse wheel was scrolled
-        MouseButtonPressed,  ///< A mouse button was pressed
-        MouseButtonReleased, ///< A mouse button was released
-        MouseMoved,          ///< The mouse cursor moved
-        MouseEntered,        ///< The mouse cursor entered the area of the window
-        MouseLeft,           ///< The mouse cursor left the area of the window
-        JoyButtonPressed,    ///< A joystick button was pressed
-        JoyButtonReleased,   ///< A joystick button was released
-        JoyMoved,            ///< The joystick moved along an axis
+        Closed,                 ///< The window requested to be closed
+        Resized,                ///< The window was resized
+        LostFocus,              ///< The window lost the focus
+        GainedFocus,            ///< The window gained the focus
+        TextEntered,            ///< A character was entered
+        KeyPressed,             ///< A key was pressed
+        KeyReleased,            ///< A key was released
+        MouseWheelMoved,        ///< The mouse wheel was scrolled
+        MouseButtonPressed,     ///< A mouse button was pressed
+        MouseButtonReleased,    ///< A mouse button was released
+        MouseMoved,             ///< The mouse cursor moved
+        MouseEntered,           ///< The mouse cursor entered the area of the window
+        MouseLeft,              ///< The mouse cursor left the area of the window
+        JoystickButtonPressed,  ///< A joystick button was pressed
+        JoystickButtonReleased, ///< A joystick button was released
+        JoystickMoved,          ///< The joystick moved along an axis
+        JoystickConnected,      ///< A joystick was connected
+        JoystickDisconnected,   ///< A joystick was disconnected
 
-        Count                ///< Keep last -- the total number of event types
+        Count                   ///< Keep last -- the total number of event types
     };
 
     ////////////////////////////////////////////////////////////
@@ -325,14 +176,15 @@ public :
 
     union
     {
-        KeyEvent         Key;         ///< Key event parameters
-        TextEvent        Text;        ///< Text event parameters
-        MouseMoveEvent   MouseMove;   ///< Mouse move event parameters
-        MouseButtonEvent MouseButton; ///< Mouse button event parameters
-        MouseWheelEvent  MouseWheel;  ///< Mouse wheel event parameters
-        JoyMoveEvent     JoyMove;     ///< Joystick move event parameters
-        JoyButtonEvent   JoyButton;   ///< Joystick button event parameters
-        SizeEvent        Size;        ///< Size event parameters
+        SizeEvent            Size;            ///< Size event parameters
+        KeyEvent             Key;             ///< Key event parameters
+        TextEvent            Text;            ///< Text event parameters
+        MouseMoveEvent       MouseMove;       ///< Mouse move event parameters
+        MouseButtonEvent     MouseButton;     ///< Mouse button event parameters
+        MouseWheelEvent      MouseWheel;      ///< Mouse wheel event parameters
+        JoystickMoveEvent    JoystickMove;    ///< Joystick move event parameters
+        JoystickButtonEvent  JoystickButton;  ///< Joystick button event parameters
+        JoystickConnectEvent JoystickConnect; ///< Joystick (dis)connect event parameters
     };
 };
 
diff --git a/include/SFML/Window/Input.hpp b/include/SFML/Window/Input.hpp
deleted file mode 100644
index 161cb678..00000000
--- a/include/SFML/Window/Input.hpp
+++ /dev/null
@@ -1,198 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_INPUT_HPP
-#define SFML_INPUT_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
-#include <SFML/System/NonCopyable.hpp>
-#include <SFML/Window/Event.hpp>
-
-
-namespace sf
-{
-class Window;
-
-////////////////////////////////////////////////////////////
-/// \brief Give access to the real-time states of keyboard,
-///        mouse and joysticks
-///
-////////////////////////////////////////////////////////////
-class SFML_API Input : NonCopyable
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    Input();
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the current state of a key (pressed or released)
-    ///
-    /// \param key Code of the key to test
-    ///
-    /// \return True if key is down, false if key is up
-    ///
-    ////////////////////////////////////////////////////////////
-    bool IsKeyDown(Key::Code key) const;
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the current state of a mouse button (pressed or released)
-    ///
-    /// \param button Code of the mouse button to check
-    ///
-    /// \return True if button is down, false if button is up
-    ///
-    ////////////////////////////////////////////////////////////
-    bool IsMouseButtonDown(Mouse::Button button) const;
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the current state of a joystick button (pressed or released)
-    ///
-    /// \param joystick Index of the joystick to test (in range [0 .. Joy::Count - 1])
-    /// \param button   Index of the button to test (in range [0 .. Joy::ButtonCount - 1])
-    ///
-    /// \return True if button is down, false if button is up
-    ///
-    ////////////////////////////////////////////////////////////
-    bool IsJoystickButtonDown(unsigned int joystick, unsigned int button) const;
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the current mouse X position
-    ///
-    /// The returned position is relative to the left border
-    /// of the owner window.
-    ///
-    /// \return Current mouse left position
-    ///
-    ////////////////////////////////////////////////////////////
-    int GetMouseX() const;
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the current mouse Y position
-    ///
-    /// The returned position is relative to the top border
-    /// of the owner window.
-    ///
-    /// \return Current mouse top position
-    ///
-    ////////////////////////////////////////////////////////////
-    int GetMouseY() const;
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the current position of a joystick axis
-    ///
-    /// The returned position is in the range [-100 .. 100], except
-    /// the POV which is an angle and is thus defined in [0 .. 360].
-    ///
-    /// \param joystick Index of the joystick to test (in range [0 .. Joy::Count - 1])
-    /// \param axis     Axis to test
-    ///
-    /// \return Current axis position
-    ///
-    ////////////////////////////////////////////////////////////
-    float GetJoystickAxis(unsigned int joystick, Joy::Axis axis) const;
-
-private :
-
-    friend class Window;
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Notifies the input of a new event
-    ///
-    /// This function is for internal use only, it is called by
-    /// the owner window every time a new event has been triggered.
-    ///
-    /// \param event Event received
-    ///
-    ////////////////////////////////////////////////////////////
-    void OnEvent(const Event& event);
-
-    ////////////////////////////////////////////////////////////
-    /// Reset all the states
-    ///
-    ////////////////////////////////////////////////////////////
-    void ResetStates();
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    bool  myKeys[Key::Count];                              ///< Array containing the state of all keyboard keys
-    bool  myMouseButtons[Mouse::ButtonCount];              ///< Array containing the state of all mouse buttons
-    int   myMouseX;                                        ///< Mouse position on X
-    int   myMouseY;                                        ///< Mouse position on Y
-    bool  myJoystickButtons[Joy::Count][Joy::ButtonCount]; ///< Array containing the state of all joysticks buttons
-    float myJoystickAxis[Joy::Count][Joy::AxisCount];      ///< Joysticks position on each axis
-};
-
-} // namespace sf
-
-
-#endif // SFML_INPUT_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::Input
-/// \ingroup window
-///
-/// sf::Input provides a way to access the state of keys,
-/// mouse buttons, mouse position, joystick buttons and
-/// jostick axis.
-///
-/// sf::Input provides the same informations as the event
-/// system, but these informations can be accessed at any time,
-/// which is more convenient in many situations.
-///
-/// For example, to move an entity you can decide to catch the
-/// sf::Event::KeyPressed event on arrow keys. But if you do so,
-/// you will only receive one event when the key gets pressed
-/// (or repeated events if you activated this feature), thus the
-/// entity will not move smoothly. The best solution here is to
-/// use sf::Input::IsKeyDown so that you can update your entity's
-/// position at every iteration of your game loop, not only when you
-/// catch a KeyPressed event.
-///
-/// Note that instances of sf::Input cannot be created directly,
-/// they must be retrieved from a window (sf::Window) with its
-/// GetInput() function.
-///
-/// Usage example:
-/// \code
-/// // Retrieve the input object attached to our window
-/// const sf::Input& input = window.GetInput();
-///
-/// // Move an entity according to the current keys state
-/// float offset = 5.f * window.GetFrameTime(); // 5 pixels/sec
-/// if (input.IsKeyDown(sf::Key::Left))  entity.Move(-offset, 0);
-/// if (input.IsKeyDown(sf::Key::Right)) entity.Move( offset, 0);
-/// if (input.IsKeyDown(sf::Key::Up))    entity.Move(0, -offset);
-/// if (input.IsKeyDown(sf::Key::Down))  entity.Move(0,  offset);
-/// \endcode
-///
-////////////////////////////////////////////////////////////
diff --git a/include/SFML/Window/Joystick.hpp b/include/SFML/Window/Joystick.hpp
new file mode 100644
index 00000000..b059c2d8
--- /dev/null
+++ b/include/SFML/Window/Joystick.hpp
@@ -0,0 +1,203 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_JOYSTICK_HPP
+#define SFML_JOYSTICK_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Give access to the real-time state of the joysticks
+///
+////////////////////////////////////////////////////////////
+class SFML_API Joystick
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Constants related to joysticks capabilities
+    ///
+    ////////////////////////////////////////////////////////////
+    enum
+    {
+        Count       = 8,  ///< Maximum number of supported joysticks
+        ButtonCount = 32, ///< Maximum number of supported buttons
+        AxisCount   = 8   ///< Maximum number of supported axes
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Axes supported by SFML joysticks
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Axis
+    {
+        X,    ///< The X axis
+        Y,    ///< The Y axis
+        Z,    ///< The Z axis
+        R,    ///< The R axis
+        U,    ///< The U axis
+        V,    ///< The V axis
+        PovX, ///< The X axis of the point-of-view hat
+        PovY  ///< The Y axis of the point-of-view hat
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick is connected
+    ///
+    /// \param joystick Index of the joystick to check
+    ///
+    /// \return True if the joystick is connected, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsConnected(unsigned int joystick);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the number of buttons supported by a joystick
+    ///
+    /// If the joystick is not connected, this function returns 0.
+    ///
+    /// \param joystick Index of the joystick
+    ///
+    /// \return Number of buttons supported by the joystick
+    ///
+    ////////////////////////////////////////////////////////////
+    static unsigned int GetButtonCount(unsigned int joystick);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick supports a given axis
+    ///
+    /// If the joystick is not connected, this function returns false.
+    ///
+    /// \param joystick Index of the joystick
+    /// \param axis     Axis to check
+    ///
+    /// \return True if the joystick supports the axis, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool HasAxis(unsigned int joystick, Axis axis);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick button is pressed
+    ///
+    /// If the joystick is not connected, this function returns false.
+    ///
+    /// \param joystick Index of the joystick
+    /// \param button   Button to check
+    ///
+    /// \return True if the button is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsButtonPressed(unsigned int joystick, int button);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of a joystick axis
+    ///
+    /// If the joystick is not connected, this function returns 0.
+    ///
+    /// \param joystick Index of the joystick
+    /// \param axis     Axis to check
+    ///
+    /// \return Current position of the axis, in range [-100 .. 100]
+    ///
+    ////////////////////////////////////////////////////////////
+    static float GetAxisPosition(unsigned int joystick, Axis axis);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the states of all joysticks
+    ///
+    /// This function is used internally by SFML, so you normally
+    /// don't have to call it explicitely. However, you may need to
+    /// call it if you have no window yet (or no window at all):
+    /// in this case the joysticks states are not updated automatically.
+    ///
+    ////////////////////////////////////////////////////////////
+    static void Update();
+};
+
+} // namespace sf
+
+
+#endif // SFML_JOYSTICK_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Joystick
+/// \ingroup window
+///
+/// sf::Joystick provides an interface to the state of the
+/// joysticks. It only contains static functions, so it's not
+/// meant to be instanciated. Instead, each joystick is identified
+/// by an index that is passed to the functions of this class.
+///
+/// This class allows users to query the state of joysticks at any
+/// time and directly, without having to deal with a window and
+/// its events. Compared to the JoystickMoved, JoystickButtonPressed
+/// and JoystickButtonReleased events, sf::Joystick can retrieve the
+/// state of axes and buttons of joysticks at any time
+/// (you don't need to store and update a boolean on your side
+/// in order to know if a button is pressed or released), and you
+/// always get the real state of joysticks, even if they are
+/// moved, pressed or released when your window is out of focus
+/// and no event is triggered.
+///
+/// SFML supports:
+/// \li 8 joysticks (sf::Joystick::Count)
+/// \li 32 buttons per joystick (sf::Joystick::ButtonCount)
+/// \li 8 axes per joystick (sf::Joystick::AxisCount)
+///
+/// Unlike the keyboard or mouse, the state of joysticks is sometimes
+/// not directly available (depending on the OS), therefore an Update()
+/// function must be called in order to update the current state of
+/// joysticks. When you have a window with event handling, this is done
+/// automatically, you don't need to call anything. But if you have no
+/// window, or if you want to check joysticks state before creating one,
+/// you must call sf::Joystick::Update explicitely.
+///
+/// Usage example:
+/// \code
+/// // Is joystick #0 connected?
+/// bool connected = sf::Joystick::IsConnected(0);
+///
+/// // How many buttons does joystick #0 support?
+/// unsigned int buttons = sf::Joystick::GetButtonCount(0);
+///
+/// // Does joystick #0 define a X axis?
+/// bool hasX = sf::Joystick::HasAxis(0, sf::Joystick::X);
+///
+/// // Is button #2 pressed on joystick #0?
+/// bool pressed = sf::Joystick::IsButtonPressed(0, 2);
+///
+/// // What's the current position of the Y axis on joystick #0?
+/// float position = sf::Joystick::GetAxisPosition(0, sf::Joystick::Y);
+/// \endcode
+///
+/// \see sf::Keyboard, sf::Mouse
+///
+////////////////////////////////////////////////////////////
diff --git a/include/SFML/Window/Keyboard.hpp b/include/SFML/Window/Keyboard.hpp
new file mode 100644
index 00000000..abecde05
--- /dev/null
+++ b/include/SFML/Window/Keyboard.hpp
@@ -0,0 +1,208 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_KEYBOARD_HPP
+#define SFML_KEYBOARD_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Give access to the real-time state of the keyboard
+///
+////////////////////////////////////////////////////////////
+class SFML_API Keyboard
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Key codes
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Key
+    {
+        A,            ///< The A key
+        B,            ///< The B key
+        C,            ///< The C key
+        D,            ///< The D key
+        E,            ///< The E key
+        F,            ///< The F key
+        G,            ///< The G key
+        H,            ///< The H key
+        I,            ///< The I key
+        J,            ///< The J key
+        K,            ///< The K key
+        L,            ///< The L key
+        M,            ///< The M key
+        N,            ///< The N key
+        O,            ///< The O key
+        P,            ///< The P key
+        Q,            ///< The Q key
+        R,            ///< The R key
+        S,            ///< The S key
+        T,            ///< The T key
+        U,            ///< The U key
+        V,            ///< The V key
+        W,            ///< The W key
+        X,            ///< The X key
+        Y,            ///< The Y key
+        Z,            ///< The Z key
+        Num0,         ///< The 0 key
+        Num1,         ///< The 1 key
+        Num2,         ///< The 2 key
+        Num3,         ///< The 3 key
+        Num4,         ///< The 4 key
+        Num5,         ///< The 5 key
+        Num6,         ///< The 6 key
+        Num7,         ///< The 7 key
+        Num8,         ///< The 8 key
+        Num9,         ///< The 9 key
+        Escape,       ///< The Escape key
+        LControl,     ///< The left Control key
+        LShift,       ///< The left Shift key
+        LAlt,         ///< The left Alt key
+        LSystem,      ///< The left OS specific key: window (Windows and Linux), apple (MacOS X), ...
+        RControl,     ///< The right Control key
+        RShift,       ///< The right Shift key
+        RAlt,         ///< The right Alt key
+        RSystem,      ///< The right OS specific key: window (Windows and Linux), apple (MacOS X), ...
+        Menu,         ///< The Menu key
+        LBracket,     ///< The [ key
+        RBracket,     ///< The ] key
+        SemiColon,    ///< The ; key
+        Comma,        ///< The , key
+        Period,       ///< The . key
+        Quote,        ///< The ' key
+        Slash,        ///< The / key
+        BackSlash,    ///< The \ key
+        Tilde,        ///< The ~ key
+        Equal,        ///< The = key
+        Dash,         ///< The - key
+        Space,        ///< The Space key
+        Return,       ///< The Return key
+        Back,         ///< The Backspace key
+        Tab,          ///< The Tabulation key
+        PageUp,       ///< The Page up key
+        PageDown,     ///< The Page down key
+        End,          ///< The End key
+        Home,         ///< The Home key
+        Insert,       ///< The Insert key
+        Delete,       ///< The Delete key
+        Add,          ///< +
+        Subtract,     ///< -
+        Multiply,     ///< *
+        Divide,       ///< /
+        Left,         ///< Left arrow
+        Right,        ///< Right arrow
+        Up,           ///< Up arrow
+        Down,         ///< Down arrow
+        Numpad0,      ///< The numpad 0 key
+        Numpad1,      ///< The numpad 1 key
+        Numpad2,      ///< The numpad 2 key
+        Numpad3,      ///< The numpad 3 key
+        Numpad4,      ///< The numpad 4 key
+        Numpad5,      ///< The numpad 5 key
+        Numpad6,      ///< The numpad 6 key
+        Numpad7,      ///< The numpad 7 key
+        Numpad8,      ///< The numpad 8 key
+        Numpad9,      ///< The numpad 9 key
+        F1,           ///< The F1 key
+        F2,           ///< The F2 key
+        F3,           ///< The F3 key
+        F4,           ///< The F4 key
+        F5,           ///< The F5 key
+        F6,           ///< The F6 key
+        F7,           ///< The F7 key
+        F8,           ///< The F8 key
+        F9,           ///< The F8 key
+        F10,          ///< The F10 key
+        F11,          ///< The F11 key
+        F12,          ///< The F12 key
+        F13,          ///< The F13 key
+        F14,          ///< The F14 key
+        F15,          ///< The F15 key
+        Pause,        ///< The Pause key
+
+        KeyCount      ///< Keep last -- the total number of keyboard keys
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a key is pressed
+    ///
+    /// \param key Key to check
+    ///
+    /// \return True if the key is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsKeyPressed(Key key);
+};
+
+} // namespace sf
+
+
+#endif // SFML_KEYBOARD_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Keyboard
+/// \ingroup window
+///
+/// sf::Keyboard provides an interface to the state of the
+/// keyboard. It only contains static functions (a single
+/// keyboard is assumed), so it's not meant to be instanciated.
+///
+/// This class allows users to query the keyboard state at any
+/// time and directly, without having to deal with a window and
+/// its events. Compared to the KeyPressed and KeyReleased events,
+/// sf::Keyboard can retrieve the state of a key at any time
+/// (you don't need to store and update a boolean on your side
+/// in order to know if a key is pressed or released), and you
+/// always get the real state of the keyboard, even if keys are
+/// pressed or released when your window is out of focus and no
+/// event is triggered.
+///
+/// Usage example:
+/// \code
+/// if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Left))
+/// {
+///     // move left...
+/// }
+/// else if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Right))
+/// {
+///     // move right...
+/// }
+/// else if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Escape))
+/// {
+///     // quit...
+/// }
+/// \endcode
+///
+/// \see sf::Joystick, sf::Mouse
+///
+////////////////////////////////////////////////////////////
diff --git a/include/SFML/Window/Mouse.hpp b/include/SFML/Window/Mouse.hpp
new file mode 100644
index 00000000..34cc0259
--- /dev/null
+++ b/include/SFML/Window/Mouse.hpp
@@ -0,0 +1,131 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_MOUSE_HPP
+#define SFML_MOUSE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <SFML/System/Vector2.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Give access to the real-time state of the mouse
+///
+////////////////////////////////////////////////////////////
+class SFML_API Mouse
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Mouse buttons
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Button
+    {
+        Left,       ///< The left mouse button
+        Right,      ///< The right mouse button
+        Middle,     ///< The middle (wheel) mouse button
+        XButton1,   ///< The first extra mouse button
+        XButton2,   ///< The second extra mouse button
+
+        ButtonCount ///< Keep last -- the total number of mouse buttons
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a mouse button is pressed
+    ///
+    /// \param button Button to check
+    ///
+    /// \return True if the button is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsButtonPressed(Button button);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of the mouse
+    ///
+    /// This function returns the current position of the mouse
+    /// cursor.
+    /// If the cursor is over a SFML window, the returned position
+    /// is relative to this window. Otherwise, the returned position
+    /// is in desktop coordinates.
+    ///
+    /// \return Current position of the mouse
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector2i GetPosition();
+};
+
+} // namespace sf
+
+
+#endif // SFML_MOUSE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Mouse
+/// \ingroup window
+///
+/// sf::Mouse provides an interface to the state of the
+/// mouse. It only contains static functions (a single
+/// mouse is assumed), so it's not meant to be instanciated.
+///
+/// This class allows users to query the mouse state at any
+/// time and directly, without having to deal with a window and
+/// its events. Compared to the MouseMoved, MouseButtonPressed
+/// and MouseButtonReleased events, sf::Mouse can retrieve the
+/// state of the cursor and the buttons at any time
+/// (you don't need to store and update a boolean on your side
+/// in order to know if a button is pressed or released), and you
+/// always get the real state of the mouse, even if it is
+/// moved, pressed or released when your window is out of focus
+/// and no event is triggered.
+///
+/// Note that the sf::Mouse::GetPosition function has a special
+/// behaviour: it returns the cursor position relative to the
+/// window which has the mouse focus (ie. the window on which
+/// the cursor is).
+///
+/// Usage example:
+/// \code
+/// if (sf::Mouse::IsButtonPressed(sf::Mouse::Left))
+/// {
+///     // left click...
+/// }
+/// else if (sf::Mouse::IsButtonPressed(sf::Mouse::Right))
+/// {
+///     // right click...
+/// }
+///
+/// sf::Vector2i position = sf::Mouse::GetPosition();
+/// \endcode
+///
+/// \see sf::Joystick, sf::Keyboard
+///
+////////////////////////////////////////////////////////////
diff --git a/include/SFML/Window/Window.hpp b/include/SFML/Window/Window.hpp
index 18fc1189..1189d1a2 100644
--- a/include/SFML/Window/Window.hpp
+++ b/include/SFML/Window/Window.hpp
@@ -29,12 +29,12 @@
 // Headers
 ////////////////////////////////////////////////////////////
 #include <SFML/Window/ContextSettings.hpp>
-#include <SFML/Window/Input.hpp>
 #include <SFML/Window/VideoMode.hpp>
 #include <SFML/Window/WindowHandle.hpp>
 #include <SFML/Window/WindowStyle.hpp>
 #include <SFML/Window/GlResource.hpp>
 #include <SFML/System/Clock.hpp>
+#include <SFML/System/Vector2.hpp>
 #include <SFML/System/NonCopyable.hpp>
 #include <string>
 
@@ -287,6 +287,14 @@ public :
     ////////////////////////////////////////////////////////////
     void SetCursorPosition(unsigned int x, unsigned int y);
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the position of the mouse cursor
+    ///
+    /// \return Current mouse cursor position, relative to the window
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector2i GetCursorPosition() const;
+
     ////////////////////////////////////////////////////////////
     /// \brief Change the position of the window on screen
     ///
@@ -384,17 +392,6 @@ public :
     ////////////////////////////////////////////////////////////
     void Display();
 
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the input manager attached the window
-    ///
-    /// This input gives access to the real-time state of
-    /// keyboard, mouse and joysticks for this window.
-    ///
-    /// \return Read-only reference to the input manager
-    ///
-    ////////////////////////////////////////////////////////////
-    const Input& GetInput() const;
-
     ////////////////////////////////////////////////////////////
     /// \brief Limit the framerate to a maximum fixed frequency
     ///
@@ -447,6 +444,16 @@ public :
     ////////////////////////////////////////////////////////////
     WindowHandle GetSystemHandle() const;
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the window which is under the mouse cursor
+    ///
+    /// This function is for internal use.
+    ///
+    /// \return Pointer to the mouse focus window (NULL if not)
+    ///
+    ////////////////////////////////////////////////////////////
+    static const Window* GetMouseFocusWindow();
+
 private :
 
     ////////////////////////////////////////////////////////////
@@ -493,7 +500,6 @@ private :
     ////////////////////////////////////////////////////////////
     priv::WindowImpl* myWindow;         ///< Platform-specific implementation of the window
     priv::GlContext*  myContext;        ///< Platform-specific implementation of the OpenGL context
-    Input             myInput;          ///< Input manager connected to window
     Clock             myClock;          ///< Clock for measuring the elapsed time between frames
     Uint32            myLastFrameTime;  ///< Time elapsed since last frame
     unsigned int      myFramerateLimit; ///< Current framerate limit
@@ -523,8 +529,7 @@ private :
 /// The sf::Window class provides a simple interface for manipulating
 /// the window: move, resize, show/hide, control mouse cursor, etc.
 /// It also provides event handling through its PollEvent() and WaitEvent()
-/// functions, and real-time state handling with its attached sf::Input
-/// object (see GetInput()).
+/// functions.
 ///
 /// Note that OpenGL experts can pass their own parameters (antialiasing
 /// level, bits for the depth and stencil buffers, etc.) to the
diff --git a/src/SFML/Graphics/Shader.cpp b/src/SFML/Graphics/Shader.cpp
index 8e7be3fe..c078e9f3 100644
--- a/src/SFML/Graphics/Shader.cpp
+++ b/src/SFML/Graphics/Shader.cpp
@@ -257,7 +257,7 @@ void Shader::SetCurrentTexture(const std::string& name)
         EnsureGlContext();
 
         // Find the location of the variable in the shader
-        int myCurrentTexture = glGetUniformLocationARB(myShaderProgram, name.c_str());
+        myCurrentTexture = glGetUniformLocationARB(myShaderProgram, name.c_str());
         if (myCurrentTexture == -1)
             Err() << "Texture \"" << name << "\" not found in shader" << std::endl;
     }
diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt
index 007a4b78..419f044d 100644
--- a/src/SFML/Window/CMakeLists.txt
+++ b/src/SFML/Window/CMakeLists.txt
@@ -12,9 +12,16 @@ set(SRC
     ${INCROOT}/GlResource.hpp
     ${INCROOT}/ContextSettings.hpp
     ${INCROOT}/Event.hpp
-    ${SRCROOT}/Input.cpp
-    ${INCROOT}/Input.hpp
-    ${SRCROOT}/Joystick.hpp
+    ${SRCROOT}/InputImpl.hpp
+    ${INCROOT}/Joystick.hpp
+    ${SRCROOT}/Joystick.cpp
+    ${SRCROOT}/JoystickImpl.hpp
+    ${SRCROOT}/JoystickManager.cpp
+    ${SRCROOT}/JoystickManager.hpp
+    ${INCROOT}/Keyboard.hpp
+    ${SRCROOT}/Keyboard.cpp
+    ${INCROOT}/Mouse.hpp
+    ${SRCROOT}/Mouse.cpp
     ${SRCROOT}/VideoMode.cpp
     ${INCROOT}/VideoMode.hpp
     ${SRCROOT}/VideoModeImpl.hpp
@@ -32,8 +39,10 @@ if(WINDOWS)
         ${SRC}
         ${SRCROOT}/Win32/WglContext.cpp
         ${SRCROOT}/Win32/WglContext.hpp
-        ${SRCROOT}/Win32/Joystick.cpp
-        ${SRCROOT}/Win32/Joystick.hpp
+        ${SRCROOT}/Win32/InputImpl.cpp
+        ${SRCROOT}/Win32/InputImpl.hpp
+        ${SRCROOT}/Win32/JoystickImpl.cpp
+        ${SRCROOT}/Win32/JoystickImpl.hpp
         ${SRCROOT}/Win32/VideoModeImpl.cpp
         ${SRCROOT}/Win32/WindowImplWin32.cpp
         ${SRCROOT}/Win32/WindowImplWin32.hpp
@@ -43,8 +52,10 @@ elseif(LINUX)
         ${SRC}
         ${SRCROOT}/Linux/GlxContext.cpp
         ${SRCROOT}/Linux/GlxContext.hpp
-        ${SRCROOT}/Linux/Joystick.cpp
-        ${SRCROOT}/Linux/Joystick.hpp
+        ${SRCROOT}/Linux/InputImpl.cpp
+        ${SRCROOT}/Linux/InputImpl.hpp
+        ${SRCROOT}/Linux/JoystickImpl.cpp
+        ${SRCROOT}/Linux/JoystickImpl.hpp
         ${SRCROOT}/Linux/VideoModeImpl.cpp
         ${SRCROOT}/Linux/WindowImplX11.cpp
         ${SRCROOT}/Linux/WindowImplX11.hpp
diff --git a/src/SFML/Window/Input.cpp b/src/SFML/Window/Input.cpp
deleted file mode 100644
index 289ec706..00000000
--- a/src/SFML/Window/Input.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages 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.
-//
-////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Window/Input.hpp>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-Input::Input() :
-myMouseX(0),
-myMouseY(0)
-{
-    ResetStates();
-}
-
-
-////////////////////////////////////////////////////////////
-bool Input::IsKeyDown(Key::Code key) const
-{
-    return myKeys[key];
-}
-
-
-////////////////////////////////////////////////////////////
-bool Input::IsMouseButtonDown(Mouse::Button button) const
-{
-    return myMouseButtons[button];
-}
-
-
-////////////////////////////////////////////////////////////
-bool Input::IsJoystickButtonDown(unsigned int joystick, unsigned int button) const
-{
-    if ((joystick < Joy::Count) && (button < Joy::ButtonCount))
-        return myJoystickButtons[joystick][button];
-    else
-        return false;
-}
-
-
-////////////////////////////////////////////////////////////
-int Input::GetMouseX() const
-{
-    return myMouseX;
-}
-
-
-////////////////////////////////////////////////////////////
-int Input::GetMouseY() const
-{
-    return myMouseY;
-}
-
-
-////////////////////////////////////////////////////////////
-float Input::GetJoystickAxis(unsigned int joystick, Joy::Axis axis) const
-{
-    if (joystick < Joy::Count)
-        return myJoystickAxis[joystick][axis];
-    else
-        return 0.f;
-}
-
-
-////////////////////////////////////////////////////////////
-void Input::OnEvent(const Event& event)
-{
-    switch (event.Type)
-    {
-        // Key events
-        case Event::KeyPressed :  myKeys[event.Key.Code] = true;  break;
-        case Event::KeyReleased : myKeys[event.Key.Code] = false; break;
-
-        // Mouse event
-        case Event::MouseButtonPressed :  myMouseButtons[event.MouseButton.Button] = true;  break;
-        case Event::MouseButtonReleased : myMouseButtons[event.MouseButton.Button] = false; break;
-
-        // Mouse move event
-        case Event::MouseMoved :
-            myMouseX = event.MouseMove.X;
-            myMouseY = event.MouseMove.Y;
-            break;
-
-        // Joystick button events
-        case Event::JoyButtonPressed :  myJoystickButtons[event.JoyButton.JoystickId][event.JoyButton.Button] = true;  break;
-        case Event::JoyButtonReleased : myJoystickButtons[event.JoyButton.JoystickId][event.JoyButton.Button] = false; break;
-
-        // Joystick move event
-        case Event::JoyMoved :
-            myJoystickAxis[event.JoyMove.JoystickId][event.JoyMove.Axis] = event.JoyMove.Position;
-            break;
-
-        // Lost focus event : we must reset all persistent states
-        case Event::LostFocus :
-            ResetStates();
-            break;
-
-        default :
-            break;
-    }
-}
-
-
-////////////////////////////////////////////////////////////
-void Input::ResetStates()
-{
-    for (int i = 0; i < Key::Count; ++i)
-        myKeys[i] = false;
-
-    for (int i = 0; i < Mouse::ButtonCount; ++i)
-        myMouseButtons[i] = false;
-
-    for (int i = 0; i < Joy::Count; ++i)
-    {
-        for (int j = 0; j < Joy::ButtonCount; ++j)
-            myJoystickButtons[i][j] = false;
-
-        for (int j = 0; j < Joy::AxisCount; ++j)
-            myJoystickAxis[i][j] = 0.f;
-        myJoystickAxis[i][Joy::AxisPOV] = -1.f;
-    }
-}
-
-} // namespace sf
diff --git a/src/SFML/Window/InputImpl.hpp b/src/SFML/Window/InputImpl.hpp
new file mode 100644
index 00000000..7c501471
--- /dev/null
+++ b/src/SFML/Window/InputImpl.hpp
@@ -0,0 +1,48 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_INPUTIMPL_HPP
+#define SFML_INPUTIMPL_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+#if defined(SFML_SYSTEM_WINDOWS)
+
+    #include <SFML/Window/Win32/InputImpl.hpp>
+
+#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
+
+    #include <SFML/Window/Linux/InputImpl.hpp>
+
+#elif defined(SFML_SYSTEM_MACOS)
+
+	#include <SFML/Window/OSX/InputImpl.hpp>
+
+#endif
+
+
+#endif // SFML_INPUTIMPL_HPP
diff --git a/src/SFML/Window/Joystick.cpp b/src/SFML/Window/Joystick.cpp
new file mode 100644
index 00000000..95e29291
--- /dev/null
+++ b/src/SFML/Window/Joystick.cpp
@@ -0,0 +1,75 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Joystick.hpp>
+#include <SFML/Window/JoystickManager.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+bool Joystick::IsConnected(unsigned int joystick)
+{
+    return priv::JoystickManager::GetInstance().GetState(joystick).Connected;
+}
+
+
+////////////////////////////////////////////////////////////
+unsigned int Joystick::GetButtonCount(unsigned int joystick)
+{
+    return priv::JoystickManager::GetInstance().GetCapabilities(joystick).ButtonCount;
+}
+
+
+////////////////////////////////////////////////////////////
+bool Joystick::HasAxis(unsigned int joystick, Axis axis)
+{
+    return priv::JoystickManager::GetInstance().GetCapabilities(joystick).Axes[axis];
+}
+
+
+////////////////////////////////////////////////////////////
+bool Joystick::IsButtonPressed(unsigned int joystick, int button)
+{
+    return priv::JoystickManager::GetInstance().GetState(joystick).Buttons[button];
+}
+
+
+////////////////////////////////////////////////////////////
+float Joystick::GetAxisPosition(unsigned int joystick, Axis axis)
+{
+    return priv::JoystickManager::GetInstance().GetState(joystick).Axes[axis];
+}
+
+
+////////////////////////////////////////////////////////////
+void Joystick::Update()
+{
+    return priv::JoystickManager::GetInstance().Update();
+}
+
+} // namespace sf
diff --git a/src/SFML/Window/JoystickImpl.hpp b/src/SFML/Window/JoystickImpl.hpp
new file mode 100644
index 00000000..5ec45ecb
--- /dev/null
+++ b/src/SFML/Window/JoystickImpl.hpp
@@ -0,0 +1,95 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_JOYSTICKIMPL_HPP
+#define SFML_JOYSTICKIMPL_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <SFML/Window/Joystick.hpp>
+#include <algorithm>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Structure holding a joystick's capabilities
+///
+////////////////////////////////////////////////////////////
+struct JoystickCaps
+{
+    JoystickCaps()
+    {
+        ButtonCount = 0;
+        std::fill(Axes, Axes + Joystick::AxisCount, false);
+    }
+
+    unsigned int ButtonCount;               ///< Number of buttons supported by the joystick
+    bool         Axes[Joystick::AxisCount]; ///< Support for each axis
+};
+
+
+////////////////////////////////////////////////////////////
+/// \brief Structure holding a joystick's state
+///
+////////////////////////////////////////////////////////////
+struct JoystickState
+{
+    JoystickState()
+    {
+        Connected = false;
+        std::fill(Axes, Axes + Joystick::AxisCount, 0.f);
+        std::fill(Buttons, Buttons + Joystick::ButtonCount, false);
+    }
+
+    bool  Connected;                      ///< Is the joystick currently connected?
+    float Axes[Joystick::AxisCount];      ///< Position of each axis, in range [-100, 100]
+    bool  Buttons[Joystick::ButtonCount]; ///< Status of each button (true = pressed)
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#if defined(SFML_SYSTEM_WINDOWS)
+
+    #include <SFML/Window/Win32/JoystickImpl.hpp>
+
+#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
+
+    #include <SFML/Window/Linux/JoystickImpl.hpp>
+
+#elif defined(SFML_SYSTEM_MACOS)
+
+	#include <SFML/Window/OSX/JoystickImpl.hpp>
+
+#endif
+
+
+#endif // SFML_JOYSTICKIMPL_HPP
diff --git a/src/SFML/Window/JoystickManager.cpp b/src/SFML/Window/JoystickManager.cpp
new file mode 100644
index 00000000..322815f2
--- /dev/null
+++ b/src/SFML/Window/JoystickManager.cpp
@@ -0,0 +1,111 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/JoystickManager.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+JoystickManager& JoystickManager::GetInstance()
+{
+    static JoystickManager instance;
+    return instance;
+}
+
+
+////////////////////////////////////////////////////////////
+const JoystickCaps& JoystickManager::GetCapabilities(unsigned int joystick) const
+{
+    return myJoysticks[joystick].Capabilities;
+}
+
+
+////////////////////////////////////////////////////////////
+const JoystickState& JoystickManager::GetState(unsigned int joystick) const
+{
+    return myJoysticks[joystick].State;
+}
+
+
+////////////////////////////////////////////////////////////
+void JoystickManager::Update()
+{
+    for (int i = 0; i < Joystick::Count; ++i)
+    {
+        Item& item = myJoysticks[i];
+
+        if (item.State.Connected)
+        {
+            // Get the current state of the joystick
+            item.State = item.Joystick.Update();
+
+            // Check if it's still connected
+            if (!item.State.Connected)
+            {
+                item.Joystick.Close();
+                item.Capabilities = JoystickCaps();
+                item.State = JoystickState();
+            }
+        }
+        else
+        {
+            // Check if the joystick was connected since last update
+            if (JoystickImpl::IsConnected(i))
+            {
+                if (item.Joystick.Open(i))
+                {
+                    item.Capabilities = item.Joystick.GetCapabilities();
+                    item.State = item.Joystick.Update();
+                }
+            }
+        }
+    }
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickManager::JoystickManager()
+{
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickManager::~JoystickManager()
+{
+    for (int i = 0; i < Joystick::Count; ++i)
+    {
+        if (myJoysticks[i].State.Connected)
+            myJoysticks[i].Joystick.Close();
+    }
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/JoystickManager.hpp b/src/SFML/Window/JoystickManager.hpp
new file mode 100644
index 00000000..32141dd3
--- /dev/null
+++ b/src/SFML/Window/JoystickManager.hpp
@@ -0,0 +1,118 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_JOYSTICKMANAGER_HPP
+#define SFML_JOYSTICKMANAGER_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Joystick.hpp>
+#include <SFML/Window/JoystickImpl.hpp>
+#include <SFML/System/NonCopyable.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Global joystick manager
+///
+////////////////////////////////////////////////////////////
+class JoystickManager : NonCopyable
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the global unique instance of the manager
+    ///
+    /// \return Unique instance of the joystick manager
+    ///
+    ////////////////////////////////////////////////////////////
+    static JoystickManager& GetInstance();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the capabilities of an open joystick
+    ///
+    /// \param joystick Index of the joystick
+    ///
+    /// \return Capabilities of the joystick
+    ///
+    ////////////////////////////////////////////////////////////
+    const JoystickCaps& GetCapabilities(unsigned int joystick) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current state of an open joystick
+    ///
+    /// \param joystick Index of the joystick
+    ///
+    /// \return Current state of the joystick
+    ///
+    ////////////////////////////////////////////////////////////
+    const JoystickState& GetState(unsigned int joystick) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the state of all the joysticks
+    ///
+    ////////////////////////////////////////////////////////////
+    void Update();
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    JoystickManager();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    ~JoystickManager();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Joystick information and state
+    ///
+    ////////////////////////////////////////////////////////////
+    struct Item
+    {
+        JoystickImpl  Joystick;     ///< Joystick implementation
+        JoystickState State;        ///< The current joystick state
+        JoystickCaps  Capabilities; ///< The joystick capabilities
+    };
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    Item myJoysticks[Joystick::Count]; ///< Joysticks information and state
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_JOYSTICKMANAGER_HPP
diff --git a/src/SFML/Window/Keyboard.cpp b/src/SFML/Window/Keyboard.cpp
new file mode 100644
index 00000000..70d8733b
--- /dev/null
+++ b/src/SFML/Window/Keyboard.cpp
@@ -0,0 +1,40 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window/InputImpl.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+bool Keyboard::IsKeyPressed(Key key)
+{
+    return priv::InputImpl::IsKeyPressed(key);
+}
+
+} // namespace sf
diff --git a/src/SFML/Window/Linux/InputImpl.cpp b/src/SFML/Window/Linux/InputImpl.cpp
new file mode 100644
index 00000000..0c1a683f
--- /dev/null
+++ b/src/SFML/Window/Linux/InputImpl.cpp
@@ -0,0 +1,228 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Linux/InputImpl.hpp>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+
+
+namespace
+{
+    // Open, store and close a X display
+    struct GlobalDisplay
+    {
+        GlobalDisplay() 
+        {
+            display = XOpenDisplay(NULL);
+            window = DefaultRootWindow(display);
+        }
+
+        ~GlobalDisplay()
+        {
+            XCloseDisplay(display);
+        }
+
+        ::Display* display;
+        ::Window window;
+    };
+
+    // Global connection with the X server, used in global input functions
+    GlobalDisplay global;
+}
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+bool InputImpl::IsKeyPressed(Keyboard::Key key)
+{
+    // Get the corresponding X11 keysym
+    KeySym keysym = 0;
+    switch (key)
+    {
+        case Keyboard::A:          keysym = XK_A;            break;
+        case Keyboard::B:          keysym = XK_B;            break;
+        case Keyboard::C:          keysym = XK_C;            break;
+        case Keyboard::D:          keysym = XK_D;            break;
+        case Keyboard::E:          keysym = XK_E;            break;
+        case Keyboard::F:          keysym = XK_F;            break;
+        case Keyboard::G:          keysym = XK_G;            break;
+        case Keyboard::H:          keysym = XK_H;            break;
+        case Keyboard::I:          keysym = XK_I;            break;
+        case Keyboard::J:          keysym = XK_J;            break;
+        case Keyboard::K:          keysym = XK_K;            break;
+        case Keyboard::L:          keysym = XK_L;            break;
+        case Keyboard::M:          keysym = XK_M;            break;
+        case Keyboard::N:          keysym = XK_N;            break;
+        case Keyboard::O:          keysym = XK_O;            break;
+        case Keyboard::P:          keysym = XK_P;            break;
+        case Keyboard::Q:          keysym = XK_Q;            break;
+        case Keyboard::R:          keysym = XK_R;            break;
+        case Keyboard::S:          keysym = XK_S;            break;
+        case Keyboard::T:          keysym = XK_T;            break;
+        case Keyboard::U:          keysym = XK_U;            break;
+        case Keyboard::V:          keysym = XK_V;            break;
+        case Keyboard::W:          keysym = XK_W;            break;
+        case Keyboard::X:          keysym = XK_X;            break;
+        case Keyboard::Y:          keysym = XK_Y;            break;
+        case Keyboard::Z:          keysym = XK_Z;            break;
+        case Keyboard::Num0:       keysym = XK_0;            break;
+        case Keyboard::Num1:       keysym = XK_1;            break;
+        case Keyboard::Num2:       keysym = XK_2;            break;
+        case Keyboard::Num3:       keysym = XK_3;            break;
+        case Keyboard::Num4:       keysym = XK_4;            break;
+        case Keyboard::Num5:       keysym = XK_5;            break;
+        case Keyboard::Num6:       keysym = XK_6;            break;
+        case Keyboard::Num7:       keysym = XK_7;            break;
+        case Keyboard::Num8:       keysym = XK_8;            break;
+        case Keyboard::Num9:       keysym = XK_9;            break;
+        case Keyboard::Escape:     keysym = XK_Escape;       break;
+        case Keyboard::LControl:   keysym = XK_Control_L;    break;
+        case Keyboard::LShift:     keysym = XK_Shift_L;      break;
+        case Keyboard::LAlt:       keysym = XK_Alt_L;        break;
+        case Keyboard::LSystem:    keysym = XK_Super_L;      break;
+        case Keyboard::RControl:   keysym = XK_Control_R;    break;
+        case Keyboard::RShift:     keysym = XK_Shift_R;      break;
+        case Keyboard::RAlt:       keysym = XK_Alt_R;        break;
+        case Keyboard::RSystem:    keysym = XK_Super_R;      break;
+        case Keyboard::Menu:       keysym = XK_Menu;         break;
+        case Keyboard::LBracket:   keysym = XK_bracketleft;  break;
+        case Keyboard::RBracket:   keysym = XK_bracketright; break;
+        case Keyboard::SemiColon:  keysym = XK_semicolon;    break;
+        case Keyboard::Comma:      keysym = XK_comma;        break;
+        case Keyboard::Period:     keysym = XK_period;       break;
+        case Keyboard::Quote:      keysym = XK_dead_acute;   break;
+        case Keyboard::Slash:      keysym = XK_slash;        break;
+        case Keyboard::BackSlash:  keysym = XK_backslash;    break;
+        case Keyboard::Tilde:      keysym = XK_dead_grave;   break;
+        case Keyboard::Equal:      keysym = XK_equal;        break;
+        case Keyboard::Dash:       keysym = XK_minus;        break;
+        case Keyboard::Space:      keysym = XK_space;        break;
+        case Keyboard::Return:     keysym = XK_Return;       break;
+        case Keyboard::Back:       keysym = XK_BackSpace;    break;
+        case Keyboard::Tab:        keysym = XK_Tab;          break;
+        case Keyboard::PageUp:     keysym = XK_Prior;        break;
+        case Keyboard::PageDown:   keysym = XK_Next;         break;
+        case Keyboard::End:        keysym = XK_End;          break;
+        case Keyboard::Home:       keysym = XK_Home;         break;
+        case Keyboard::Insert:     keysym = XK_Insert;       break;
+        case Keyboard::Delete:     keysym = XK_Delete;       break;
+        case Keyboard::Add:        keysym = XK_KP_Add;       break;
+        case Keyboard::Subtract:   keysym = XK_KP_Subtract;  break;
+        case Keyboard::Multiply:   keysym = XK_KP_Multiply;  break;
+        case Keyboard::Divide:     keysym = XK_KP_Divide;    break;
+        case Keyboard::Left:       keysym = XK_Left;         break;
+        case Keyboard::Right:      keysym = XK_Right;        break;
+        case Keyboard::Up:         keysym = XK_Up;           break;
+        case Keyboard::Down:       keysym = XK_Down;         break;
+        case Keyboard::Numpad0:    keysym = XK_KP_0;         break;
+        case Keyboard::Numpad1:    keysym = XK_KP_1;         break;
+        case Keyboard::Numpad2:    keysym = XK_KP_2;         break;
+        case Keyboard::Numpad3:    keysym = XK_KP_3;         break;
+        case Keyboard::Numpad4:    keysym = XK_KP_4;         break;
+        case Keyboard::Numpad5:    keysym = XK_KP_5;         break;
+        case Keyboard::Numpad6:    keysym = XK_KP_6;         break;
+        case Keyboard::Numpad7:    keysym = XK_KP_7;         break;
+        case Keyboard::Numpad8:    keysym = XK_KP_8;         break;
+        case Keyboard::Numpad9:    keysym = XK_KP_9;         break;
+        case Keyboard::F1:         keysym = XK_F1;           break;
+        case Keyboard::F2:         keysym = XK_F2;           break;
+        case Keyboard::F3:         keysym = XK_F3;           break;
+        case Keyboard::F4:         keysym = XK_F4;           break;
+        case Keyboard::F5:         keysym = XK_F5;           break;
+        case Keyboard::F6:         keysym = XK_F6;           break;
+        case Keyboard::F7:         keysym = XK_F7;           break;
+        case Keyboard::F8:         keysym = XK_F8;           break;
+        case Keyboard::F9:         keysym = XK_F9;           break;
+        case Keyboard::F10:        keysym = XK_F10;          break;
+        case Keyboard::F11:        keysym = XK_F11;          break;
+        case Keyboard::F12:        keysym = XK_F12;          break;
+        case Keyboard::F13:        keysym = XK_F13;          break;
+        case Keyboard::F14:        keysym = XK_F14;          break;
+        case Keyboard::F15:        keysym = XK_F15;          break;
+        case Keyboard::Pause:      keysym = XK_Pause;        break;
+    }
+
+    // Convert to keycode
+    KeyCode keycode = XKeysymToKeycode(global.display, keysym);
+    if (keycode != 0)
+    {
+        // Get the whole keyboard state
+        char keys[32];
+        XQueryKeymap(global.display, keys);
+
+        // Check our keycode
+        return (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
+    }
+
+    return false;
+}
+
+
+////////////////////////////////////////////////////////////
+bool InputImpl::IsMouseButtonPressed(Mouse::Button button)
+{
+    // we don't care about these but they are required
+    ::Window root, child;
+    int wx, wy;
+    int gx, gy;
+
+    unsigned int buttons = 0;
+    XQueryPointer(global.display, global.window, &root, &child, &gx, &gy, &wx, &wy, &buttons);
+
+    switch (button)
+    {
+        case Mouse::Left:     return buttons & Button1Mask;
+        case Mouse::Right:    return buttons & Button3Mask;
+        case Mouse::Middle:   return buttons & Button2Mask;
+        case Mouse::XButton1: return false; // not supported by X
+        case Mouse::XButton2: return false; // not supported by X
+    }
+
+    return false;
+}
+
+
+////////////////////////////////////////////////////////////
+Vector2i InputImpl::GetMousePosition()
+{
+    // we don't care about these but they are required
+    ::Window root, child;
+    int wx, wy;
+    unsigned int buttons;
+
+    int x = 0;
+    int y = 0;
+    XQueryPointer(global.display, global.window, &root, &child, &x, &y, &wx, &wy, &buttons);
+
+    return Vector2i(x, y);
+}
+
+} // namespace priv
+
+} // namespace sf
\ No newline at end of file
diff --git a/src/SFML/Window/Linux/InputImpl.hpp b/src/SFML/Window/Linux/InputImpl.hpp
new file mode 100644
index 00000000..3f3df155
--- /dev/null
+++ b/src/SFML/Window/Linux/InputImpl.hpp
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_INPUTIMPLX11_HPP
+#define SFML_INPUTIMPLX11_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window/Mouse.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Linux (X11) implementation of inputs (keyboard + mouse)
+///
+////////////////////////////////////////////////////////////
+class InputImpl
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a key is pressed
+    ///
+    /// \param key Key to check
+    ///
+    /// \return True if the key is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsKeyPressed(Keyboard::Key key);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a mouse button is pressed
+    ///
+    /// \param button Button to check
+    ///
+    /// \return True if the button is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsMouseButtonPressed(Mouse::Button button);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of the mouse
+    ///
+    /// This function returns the mouse position in desktop coordinates.
+    ///
+    /// \return Current position of the mouse
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector2i GetMousePosition();
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_INPUTIMPLX11_HPP
\ No newline at end of file
diff --git a/src/SFML/Window/Linux/Joystick.cpp b/src/SFML/Window/Linux/Joystick.cpp
deleted file mode 100644
index 2ad46b49..00000000
--- a/src/SFML/Window/Linux/Joystick.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages 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.
-//
-////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Window/Joystick.hpp>
-#include <sstream>
-
-
-namespace sf
-{
-namespace priv
-{
-#if defined(SFML_SYSTEM_LINUX)
-
-////////////////////////////////////////////////////////////
-void Joystick::Initialize(unsigned int index)
-{
-    // Initial state
-    myNbButtons = 0;
-    myPovX = 0;
-    myPovY = 0;
-    for (int i = 0; i < Joy::ButtonCount; ++i)
-    {
-        myState.Buttons[i] = false;
-    }
-    for (int i = 0; i < Joy::AxisCount; ++i)
-    {
-        myState.Axis[i] = 0.f;
-        myAxes[i] = false;
-    }
-
-    // Open the joystick handle
-    std::ostringstream oss;
-    oss << "/dev/input/js" << index;
-    myDescriptor = open(oss.str().c_str(), O_RDONLY);
-    if (myDescriptor > 0)
-    {
-        // Use non-blocking mode
-        fcntl(myDescriptor, F_SETFL, O_NONBLOCK);
-
-        // Get number of buttons
-        char nbButtons;
-        ioctl(myDescriptor, JSIOCGBUTTONS, &nbButtons);
-        myNbButtons = nbButtons;
-        if (myNbButtons > Joy::ButtonCount)
-            myNbButtons = Joy::ButtonCount;
-
-        // Get the supported axes
-        char nbAxes;
-        ioctl(myDescriptor, JSIOCGAXES, &nbAxes);
-        ioctl(myDescriptor, JSIOCGAXMAP, myAxesMapping);
-        for (int i = 0; i < nbAxes; ++i)
-        {
-            switch (myAxesMapping[i])
-            {
-                case ABS_X :                      myAxes[Joy::AxisX]   = true; break;
-                case ABS_Y :                      myAxes[Joy::AxisY]   = true; break;
-                case ABS_Z : case ABS_THROTTLE :  myAxes[Joy::AxisZ]   = true; break;
-                case ABS_RZ: case ABS_RUDDER:     myAxes[Joy::AxisR]   = true; break;
-                case ABS_RX :                     myAxes[Joy::AxisU]   = true; break;
-                case ABS_RY :                     myAxes[Joy::AxisV]   = true; break;
-                case ABS_HAT0X : case ABS_HAT0Y : myAxes[Joy::AxisPOV] = true; break;
-                default : break;
-            }
-        }
-    }
-}
-
-
-////////////////////////////////////////////////////////////
-JoystickState Joystick::UpdateState()
-{
-    if (myDescriptor > 0)
-    {
-        js_event joyState;
-        while (read(myDescriptor, &joyState, sizeof(joyState)) > 0)
-        {
-            switch (joyState.type & ~JS_EVENT_INIT)
-            {
-                // An axis has been moved
-                case JS_EVENT_AXIS :
-                {
-                    switch (myAxesMapping[joyState.number])
-                    {
-                        case ABS_X :                      myState.Axis[Joy::AxisX] = joyState.value * 100.f / 32767.f; break;
-                        case ABS_Y :                      myState.Axis[Joy::AxisY] = joyState.value * 100.f / 32767.f; break;
-                        case ABS_Z : case ABS_THROTTLE :  myState.Axis[Joy::AxisZ] = joyState.value * 100.f / 32767.f; break;
-                        case ABS_RZ: case ABS_RUDDER:     myState.Axis[Joy::AxisR] = joyState.value * 100.f / 32767.f; break;
-                        case ABS_RX :                     myState.Axis[Joy::AxisU] = joyState.value * 100.f / 32767.f; break;
-                        case ABS_RY :                     myState.Axis[Joy::AxisV] = joyState.value * 100.f / 32767.f; break;
-                        case ABS_HAT0X :                  myPovX = joyState.value;                                     break;
-                        case ABS_HAT0Y :                  myPovY = joyState.value;                                     break;
-                        default : break;
-                    }
-
-                    // Compute the new POV angle
-                    if (myPovX > 0)
-                    {
-                        if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 135.f;
-                        else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 45.f;
-                        else                 myState.Axis[Joy::AxisPOV] = 90.f;
-                    }
-                    else if (myPovX < 0)
-                    {
-                        if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 225.f;
-                        else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 315.f;
-                        else                 myState.Axis[Joy::AxisPOV] = 270.f;
-                    }
-                    else
-                    {
-                        if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 180.f;
-                        else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 0.f;
-                        else                 myState.Axis[Joy::AxisPOV] = -1.f;
-                    }
-
-                    break;
-                }
-
-                // A button has been pressed
-                case JS_EVENT_BUTTON :
-                {
-                    if (joyState.number < GetButtonsCount())
-                        myState.Buttons[joyState.number] = (joyState.value != 0);
-                    break;
-                }
-            }
-        }
-    }
-
-    return myState;
-}
-
-
-////////////////////////////////////////////////////////////
-bool Joystick::HasAxis(Joy::Axis Axis) const
-{
-    return myAxes[Axis];
-}
-
-
-////////////////////////////////////////////////////////////
-unsigned int Joystick::GetButtonsCount() const
-{
-    return myNbButtons;
-}
-
-
-#elif defined(SFML_SYSTEM_FREEBSD)
-
-
-////////////////////////////////////////////////////////////
-void Joystick::Initialize(unsigned int index)
-{
-}
-
-
-////////////////////////////////////////////////////////////
-JoystickState Joystick::UpdateState()
-{
-    return JoystickState();
-}
-
-
-////////////////////////////////////////////////////////////
-bool Joystick::HasAxis(Joy::Axis Axis) const
-{
-    return false;
-}
-
-
-////////////////////////////////////////////////////////////
-unsigned int Joystick::GetButtonsCount() const
-{
-    return 0;
-}
-
-#endif // defined(SFML_SYSTEM_FREEBSD)
-
-} // namespace priv
-
-} // namespace sf
diff --git a/src/SFML/Window/Linux/JoystickImpl.cpp b/src/SFML/Window/Linux/JoystickImpl.cpp
new file mode 100644
index 00000000..91f22d23
--- /dev/null
+++ b/src/SFML/Window/Linux/JoystickImpl.cpp
@@ -0,0 +1,168 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/JoystickImpl.hpp>
+#include <sys/stat.h>
+#include <errno.h>
+#include <sstream>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+bool JoystickImpl::IsConnected(unsigned int index)
+{
+    std::ostringstream oss;
+    oss << "/dev/input/js" << index;
+
+    struct stat info; 
+    return stat(oss.str().c_str(), &info) == 0; 
+}
+
+
+////////////////////////////////////////////////////////////
+bool JoystickImpl::Open(unsigned int index)
+{
+    std::ostringstream oss;
+    oss << "/dev/input/js" << index;
+
+    myFile = open(oss.str().c_str(), O_RDONLY);
+    if (myFile > 0)
+    {
+        // Use non-blocking mode
+        fcntl(myFile, F_SETFL, O_NONBLOCK);
+
+        // Retrieve the axes mapping
+        ioctl(myFile, JSIOCGAXMAP, myMapping);
+
+        // Reset the joystick state
+        myState = JoystickState();
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+////////////////////////////////////////////////////////////
+void JoystickImpl::Close()
+{
+    close(myFile);
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickCaps JoystickImpl::GetCapabilities() const
+{
+    JoystickCaps caps;
+
+    // Get the number of buttons
+    char buttonCount;
+    ioctl(myFile, JSIOCGBUTTONS, &buttonCount);
+    caps.ButtonCount = buttonCount;
+    if (caps.ButtonCount > Joystick::ButtonCount)
+        caps.ButtonCount = Joystick::ButtonCount;
+
+    // Get the supported axes
+    char axesCount;
+    ioctl(myFile, JSIOCGAXES, &axesCount);
+    for (int i = 0; i < axesCount; ++i)
+    {
+        switch (myMapping[i])
+        {
+            case ABS_X :        caps.Axes[Joystick::X]    = true; break;
+            case ABS_Y :        caps.Axes[Joystick::Y]    = true; break;
+            case ABS_Z :
+            case ABS_THROTTLE : caps.Axes[Joystick::Z]    = true; break;
+            case ABS_RZ:
+            case ABS_RUDDER:    caps.Axes[Joystick::R]    = true; break;
+            case ABS_RX :       caps.Axes[Joystick::U]    = true; break;
+            case ABS_RY :       caps.Axes[Joystick::V]    = true; break;
+            case ABS_HAT0X :    caps.Axes[Joystick::PovX] = true; break;
+            case ABS_HAT0Y :    caps.Axes[Joystick::PovY] = true; break;
+            default : break;
+        }
+    }
+
+    return caps;
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickState JoystickImpl::JoystickImpl::Update()
+{
+    // pop events from the joystick file
+    js_event joyState;
+    while (read(myFile, &joyState, sizeof(joyState)) > 0)
+    {
+        switch (joyState.type & ~JS_EVENT_INIT)
+        {
+            // An axis was moved
+            case JS_EVENT_AXIS :
+            {
+                float value = joyState.value * 100.f / 32767.f;
+                switch (myMapping[joyState.number])
+                {
+                    case ABS_X :        myState.Axes[Joystick::X]    = value; break;
+                    case ABS_Y :        myState.Axes[Joystick::Y]    = value; break;
+                    case ABS_Z :
+                    case ABS_THROTTLE : myState.Axes[Joystick::Z]    = value; break;
+                    case ABS_RZ:
+                    case ABS_RUDDER:    myState.Axes[Joystick::R]    = value; break;
+                    case ABS_RX :       myState.Axes[Joystick::U]    = value; break;
+                    case ABS_RY :       myState.Axes[Joystick::V]    = value; break;
+                    case ABS_HAT0X :    myState.Axes[Joystick::PovX] = value; break;
+                    case ABS_HAT0Y :    myState.Axes[Joystick::PovY] = value; break;
+                    default : break;
+                }
+                break;
+            }
+
+            // A button was pressed
+            case JS_EVENT_BUTTON :
+            {
+                if (joyState.number < Joystick::ButtonCount)
+                    myState.Buttons[joyState.number] = (joyState.value != 0);
+                break;
+            }
+        }
+    }
+
+    // Check the connection state of the joystick (read() fails with an error != EGAIN if it's no longer connected)
+    myState.Connected = (errno == EAGAIN);
+
+    return myState;
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Linux/Joystick.hpp b/src/SFML/Window/Linux/JoystickImpl.hpp
similarity index 61%
rename from src/SFML/Window/Linux/Joystick.hpp
rename to src/SFML/Window/Linux/JoystickImpl.hpp
index fd407abe..c3d64f59 100644
--- a/src/SFML/Window/Linux/Joystick.hpp
+++ b/src/SFML/Window/Linux/JoystickImpl.hpp
@@ -1,105 +1,109 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_JOYSTICKLINUX_HPP
-#define SFML_JOYSTICKLINUX_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#if defined(SFML_SYSTEM_LINUX)
-    #include <linux/joystick.h>
-    #include <fcntl.h>
-#elif defined(SFML_SYSTEM_FREEBSD)
-    // #include <sys/joystick.h> ?
-    #define ABS_MAX 1
-#endif
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-/// \brief Linux implementation of Joystick
-///
-////////////////////////////////////////////////////////////
-class Joystick
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Initialize the instance and bind it to a physical joystick
-    ///
-    /// \param index Index of the physical joystick to bind to
-    ///
-    ////////////////////////////////////////////////////////////
-    void Initialize(unsigned int index);
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Update the current joystick and return its new state
-    ///
-    /// \return Current state of the joystick
-    ///
-    ////////////////////////////////////////////////////////////
-    JoystickState UpdateState();
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Check if the joystick supports the given axis
-    ///
-    /// \param axis Axis to check
-    ///
-    /// \return True of the axis is supported, false otherwise
-    ///
-    ////////////////////////////////////////////////////////////
-    bool HasAxis(Joy::Axis Axis) const;
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the number of buttons supported by the joystick
-    ///
-    /// \return Number of buttons
-    ///
-    ////////////////////////////////////////////////////////////
-    unsigned int GetButtonsCount() const;
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    int           myDescriptor;               ///< Linux descriptor of the joystick
-    unsigned int  myNbButtons;                ///< Number of buttons supported by the joystick
-    bool          myAxes[Joy::AxisCount];     ///< Supported axes
-    JoystickState myState;                    ///< Current state of the joystick
-    int           myPovX;                     ///< Last X position of the POV
-    int           myPovY;                     ///< Last Y position of the POV
-    char          myAxesMapping[ABS_MAX + 1]; ///< Axes mapping (index --> axis id)
-};
-
-} // namespace priv
-
-} // namespace sf
-
-
-#endif // SFML_JOYSTICKLINUX_HPP
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_JOYSTICKIMPLLINUX_HPP
+#define SFML_JOYSTICKIMPLLINUX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#if defined(SFML_SYSTEM_LINUX)
+    #include <linux/joystick.h>
+    #include <fcntl.h>
+#elif defined(SFML_SYSTEM_FREEBSD)
+    // #include <sys/joystick.h> ?
+    #define ABS_MAX 1
+#endif
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Linux implementation of joysticks
+///
+////////////////////////////////////////////////////////////
+class JoystickImpl
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick is currently connected
+    ///
+    /// \param index Index of the joystick to check
+    ///
+    /// \return True if the joystick is connected, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsConnected(unsigned int index);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Open the joystick
+    ///
+    /// \param index Index assigned to the joystick
+    ///
+    /// \return True on success, false on failure
+    ///
+    ////////////////////////////////////////////////////////////
+    bool Open(unsigned int index);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Close the joystick
+    ///
+    ////////////////////////////////////////////////////////////
+    void Close();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the joystick capabilities
+    ///
+    /// \return Joystick capabilities
+    ///
+    ////////////////////////////////////////////////////////////
+    JoystickCaps GetCapabilities() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the joystick and get its new state
+    ///
+    /// \return Joystick state
+    ///
+    ////////////////////////////////////////////////////////////
+    JoystickState Update();
+
+private :
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    int           myFile;                 ///< File descriptor of the joystick
+    char          myMapping[ABS_MAX + 1]; ///< Axes mapping (index to axis id)
+    JoystickState myState;                ///< Current state of the joystick
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_JOYSTICKIMPLLINUX_HPP
diff --git a/src/SFML/Window/Linux/WindowImplX11.cpp b/src/SFML/Window/Linux/WindowImplX11.cpp
index 3a64fbc1..942c2378 100644
--- a/src/SFML/Window/Linux/WindowImplX11.cpp
+++ b/src/SFML/Window/Linux/WindowImplX11.cpp
@@ -284,26 +284,12 @@ WindowHandle WindowImplX11::GetSystemHandle() const
 
 
 ////////////////////////////////////////////////////////////
-void WindowImplX11::ProcessEvents(bool block)
+void WindowImplX11::ProcessEvents()
 {
-    if (block)
+    XEvent event;
+    while (XCheckIfEvent(myDisplay, &event, &CheckEvent, reinterpret_cast<XPointer>(myWindow)))
     {
-        // Blocking -- wait and process events in the event queue until a valid event is found
-        XEvent event;
-        do
-        {
-            XIfEvent(myDisplay, &event, &CheckEvent, reinterpret_cast<XPointer>(myWindow));
-        }
-        while (!ProcessEvent(event));
-    }
-    else
-    {
-        // Non-blocking -- process all events in the event queue
-        XEvent event;
-        while (XCheckIfEvent(myDisplay, &event, &CheckEvent, reinterpret_cast<XPointer>(myWindow)))
-        {
-            ProcessEvent(event);
-        }
+        ProcessEvent(event);
     }
 }
 
@@ -324,6 +310,22 @@ void WindowImplX11::SetCursorPosition(unsigned int x, unsigned int y)
 }
 
 
+////////////////////////////////////////////////////////////
+Vector2i WindowImplX11::GetCursorPosition() const
+{
+    // we don't care about these but they are required
+    ::Window root, child;
+    int gx, gy;
+    unsigned int buttons;
+
+    int x = 0;
+    int y = 0;
+    XQueryPointer(myDisplay, myWindow, &root, &child, &gx, &gy, &x, &y, &buttons);
+
+    return Vector2i(x, y);
+}
+
+
 ////////////////////////////////////////////////////////////
 void WindowImplX11::SetPosition(int x, int y)
 {
@@ -590,7 +592,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
             //   and we need to properly forward the first one.
             char keys[32];
             XQueryKeymap(myDisplay, keys);
-            if (keys[windowEvent.xkey.keycode >> 3] & (1 << (windowEvent.xkey.keycode % 8)))
+            if (keys[windowEvent.xkey.keycode / 8] & (1 << (windowEvent.xkey.keycode % 8)))
             {
                 // KeyRelease event + key down = repeated event --> discard
                 if (windowEvent.type == KeyRelease)
@@ -847,7 +849,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
 
 
 ////////////////////////////////////////////////////////////
-Key::Code WindowImplX11::KeysymToSF(KeySym symbol)
+Keyboard::Key WindowImplX11::KeysymToSF(KeySym symbol)
 {
     // First convert to uppercase (to avoid dealing with two different keysyms for the same key)
     KeySym lower, key;
@@ -855,111 +857,111 @@ Key::Code WindowImplX11::KeysymToSF(KeySym symbol)
 
     switch (key)
     {
-        case XK_Shift_L :      return Key::LShift;
-        case XK_Shift_R :      return Key::RShift;
-        case XK_Control_L :    return Key::LControl;
-        case XK_Control_R :    return Key::RControl;
-        case XK_Alt_L :        return Key::LAlt;
-        case XK_Alt_R :        return Key::RAlt;
-        case XK_Super_L :      return Key::LSystem;
-        case XK_Super_R :      return Key::RSystem;
-        case XK_Menu :         return Key::Menu;
-        case XK_Escape :       return Key::Escape;
-        case XK_semicolon :    return Key::SemiColon;
-        case XK_slash :        return Key::Slash;
-        case XK_equal :        return Key::Equal;
-        case XK_minus :        return Key::Dash;
-        case XK_bracketleft :  return Key::LBracket;
-        case XK_bracketright : return Key::RBracket;
-        case XK_comma :        return Key::Comma;
-        case XK_period :       return Key::Period;
-        case XK_dead_acute :   return Key::Quote;
-        case XK_backslash :    return Key::BackSlash;
-        case XK_dead_grave :   return Key::Tilde;
-        case XK_space :        return Key::Space;
-        case XK_Return :       return Key::Return;
-        case XK_KP_Enter :     return Key::Return;
-        case XK_BackSpace :    return Key::Back;
-        case XK_Tab :          return Key::Tab;
-        case XK_Prior :        return Key::PageUp;
-        case XK_Next :         return Key::PageDown;
-        case XK_End :          return Key::End;
-        case XK_Home :         return Key::Home;
-        case XK_Insert :       return Key::Insert;
-        case XK_Delete :       return Key::Delete;
-        case XK_KP_Add :       return Key::Add;
-        case XK_KP_Subtract :  return Key::Subtract;
-        case XK_KP_Multiply :  return Key::Multiply;
-        case XK_KP_Divide :    return Key::Divide;
-        case XK_Pause :        return Key::Pause;
-        case XK_F1 :           return Key::F1;
-        case XK_F2 :           return Key::F2;
-        case XK_F3 :           return Key::F3;
-        case XK_F4 :           return Key::F4;
-        case XK_F5 :           return Key::F5;
-        case XK_F6 :           return Key::F6;
-        case XK_F7 :           return Key::F7;
-        case XK_F8 :           return Key::F8;
-        case XK_F9 :           return Key::F9;
-        case XK_F10 :          return Key::F10;
-        case XK_F11 :          return Key::F11;
-        case XK_F12 :          return Key::F12;
-        case XK_F13 :          return Key::F13;
-        case XK_F14 :          return Key::F14;
-        case XK_F15 :          return Key::F15;
-        case XK_Left :         return Key::Left;
-        case XK_Right :        return Key::Right;
-        case XK_Up :           return Key::Up;
-        case XK_Down :         return Key::Down;
-        case XK_KP_0 :         return Key::Numpad0;
-        case XK_KP_1 :         return Key::Numpad1;
-        case XK_KP_2 :         return Key::Numpad2;
-        case XK_KP_3 :         return Key::Numpad3;
-        case XK_KP_4 :         return Key::Numpad4;
-        case XK_KP_5 :         return Key::Numpad5;
-        case XK_KP_6 :         return Key::Numpad6;
-        case XK_KP_7 :         return Key::Numpad7;
-        case XK_KP_8 :         return Key::Numpad8;
-        case XK_KP_9 :         return Key::Numpad9;
-        case XK_A :            return Key::A;
-        case XK_Z :            return Key::Z;
-        case XK_E :            return Key::E;
-        case XK_R :            return Key::R;
-        case XK_T :            return Key::T;
-        case XK_Y :            return Key::Y;
-        case XK_U :            return Key::U;
-        case XK_I :            return Key::I;
-        case XK_O :            return Key::O;
-        case XK_P :            return Key::P;
-        case XK_Q :            return Key::Q;
-        case XK_S :            return Key::S;
-        case XK_D :            return Key::D;
-        case XK_F :            return Key::F;
-        case XK_G :            return Key::G;
-        case XK_H :            return Key::H;
-        case XK_J :            return Key::J;
-        case XK_K :            return Key::K;
-        case XK_L :            return Key::L;
-        case XK_M :            return Key::M;
-        case XK_W :            return Key::W;
-        case XK_X :            return Key::X;
-        case XK_C :            return Key::C;
-        case XK_V :            return Key::V;
-        case XK_B :            return Key::B;
-        case XK_N :            return Key::N;
-        case XK_0 :            return Key::Num0;
-        case XK_1 :            return Key::Num1;
-        case XK_2 :            return Key::Num2;
-        case XK_3 :            return Key::Num3;
-        case XK_4 :            return Key::Num4;
-        case XK_5 :            return Key::Num5;
-        case XK_6 :            return Key::Num6;
-        case XK_7 :            return Key::Num7;
-        case XK_8 :            return Key::Num8;
-        case XK_9 :            return Key::Num9;
+        case XK_Shift_L :      return Keyboard::LShift;
+        case XK_Shift_R :      return Keyboard::RShift;
+        case XK_Control_L :    return Keyboard::LControl;
+        case XK_Control_R :    return Keyboard::RControl;
+        case XK_Alt_L :        return Keyboard::LAlt;
+        case XK_Alt_R :        return Keyboard::RAlt;
+        case XK_Super_L :      return Keyboard::LSystem;
+        case XK_Super_R :      return Keyboard::RSystem;
+        case XK_Menu :         return Keyboard::Menu;
+        case XK_Escape :       return Keyboard::Escape;
+        case XK_semicolon :    return Keyboard::SemiColon;
+        case XK_slash :        return Keyboard::Slash;
+        case XK_equal :        return Keyboard::Equal;
+        case XK_minus :        return Keyboard::Dash;
+        case XK_bracketleft :  return Keyboard::LBracket;
+        case XK_bracketright : return Keyboard::RBracket;
+        case XK_comma :        return Keyboard::Comma;
+        case XK_period :       return Keyboard::Period;
+        case XK_dead_acute :   return Keyboard::Quote;
+        case XK_backslash :    return Keyboard::BackSlash;
+        case XK_dead_grave :   return Keyboard::Tilde;
+        case XK_space :        return Keyboard::Space;
+        case XK_Return :       return Keyboard::Return;
+        case XK_KP_Enter :     return Keyboard::Return;
+        case XK_BackSpace :    return Keyboard::Back;
+        case XK_Tab :          return Keyboard::Tab;
+        case XK_Prior :        return Keyboard::PageUp;
+        case XK_Next :         return Keyboard::PageDown;
+        case XK_End :          return Keyboard::End;
+        case XK_Home :         return Keyboard::Home;
+        case XK_Insert :       return Keyboard::Insert;
+        case XK_Delete :       return Keyboard::Delete;
+        case XK_KP_Add :       return Keyboard::Add;
+        case XK_KP_Subtract :  return Keyboard::Subtract;
+        case XK_KP_Multiply :  return Keyboard::Multiply;
+        case XK_KP_Divide :    return Keyboard::Divide;
+        case XK_Pause :        return Keyboard::Pause;
+        case XK_F1 :           return Keyboard::F1;
+        case XK_F2 :           return Keyboard::F2;
+        case XK_F3 :           return Keyboard::F3;
+        case XK_F4 :           return Keyboard::F4;
+        case XK_F5 :           return Keyboard::F5;
+        case XK_F6 :           return Keyboard::F6;
+        case XK_F7 :           return Keyboard::F7;
+        case XK_F8 :           return Keyboard::F8;
+        case XK_F9 :           return Keyboard::F9;
+        case XK_F10 :          return Keyboard::F10;
+        case XK_F11 :          return Keyboard::F11;
+        case XK_F12 :          return Keyboard::F12;
+        case XK_F13 :          return Keyboard::F13;
+        case XK_F14 :          return Keyboard::F14;
+        case XK_F15 :          return Keyboard::F15;
+        case XK_Left :         return Keyboard::Left;
+        case XK_Right :        return Keyboard::Right;
+        case XK_Up :           return Keyboard::Up;
+        case XK_Down :         return Keyboard::Down;
+        case XK_KP_0 :         return Keyboard::Numpad0;
+        case XK_KP_1 :         return Keyboard::Numpad1;
+        case XK_KP_2 :         return Keyboard::Numpad2;
+        case XK_KP_3 :         return Keyboard::Numpad3;
+        case XK_KP_4 :         return Keyboard::Numpad4;
+        case XK_KP_5 :         return Keyboard::Numpad5;
+        case XK_KP_6 :         return Keyboard::Numpad6;
+        case XK_KP_7 :         return Keyboard::Numpad7;
+        case XK_KP_8 :         return Keyboard::Numpad8;
+        case XK_KP_9 :         return Keyboard::Numpad9;
+        case XK_A :            return Keyboard::A;
+        case XK_Z :            return Keyboard::Z;
+        case XK_E :            return Keyboard::E;
+        case XK_R :            return Keyboard::R;
+        case XK_T :            return Keyboard::T;
+        case XK_Y :            return Keyboard::Y;
+        case XK_U :            return Keyboard::U;
+        case XK_I :            return Keyboard::I;
+        case XK_O :            return Keyboard::O;
+        case XK_P :            return Keyboard::P;
+        case XK_Q :            return Keyboard::Q;
+        case XK_S :            return Keyboard::S;
+        case XK_D :            return Keyboard::D;
+        case XK_F :            return Keyboard::F;
+        case XK_G :            return Keyboard::G;
+        case XK_H :            return Keyboard::H;
+        case XK_J :            return Keyboard::J;
+        case XK_K :            return Keyboard::K;
+        case XK_L :            return Keyboard::L;
+        case XK_M :            return Keyboard::M;
+        case XK_W :            return Keyboard::W;
+        case XK_X :            return Keyboard::X;
+        case XK_C :            return Keyboard::C;
+        case XK_V :            return Keyboard::V;
+        case XK_B :            return Keyboard::B;
+        case XK_N :            return Keyboard::N;
+        case XK_0 :            return Keyboard::Num0;
+        case XK_1 :            return Keyboard::Num1;
+        case XK_2 :            return Keyboard::Num2;
+        case XK_3 :            return Keyboard::Num3;
+        case XK_4 :            return Keyboard::Num4;
+        case XK_5 :            return Keyboard::Num5;
+        case XK_6 :            return Keyboard::Num6;
+        case XK_7 :            return Keyboard::Num7;
+        case XK_8 :            return Keyboard::Num8;
+        case XK_9 :            return Keyboard::Num9;
     }
 
-    return Key::Code(0);
+    return Keyboard::Key(0);
 }
 
 } // namespace priv
diff --git a/src/SFML/Window/Linux/WindowImplX11.hpp b/src/SFML/Window/Linux/WindowImplX11.hpp
index f46f87cd..14466682 100644
--- a/src/SFML/Window/Linux/WindowImplX11.hpp
+++ b/src/SFML/Window/Linux/WindowImplX11.hpp
@@ -94,10 +94,8 @@ private :
     ////////////////////////////////////////////////////////////
     /// \brief Process incoming events from the operating system
     ///
-    /// \param block Use true to block the thread until an event arrives
-    ///
     ////////////////////////////////////////////////////////////
-    virtual void ProcessEvents(bool block);
+    virtual void ProcessEvents();
 
     ////////////////////////////////////////////////////////////
     /// \brief Show or hide the mouse cursor
@@ -116,6 +114,14 @@ private :
     ////////////////////////////////////////////////////////////
     virtual void SetCursorPosition(unsigned int x, unsigned int y);
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the position of the mouse cursor
+    ///
+    /// \return Current mouse cursor position, relative to the window
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Vector2i GetCursorPosition() const;
+
     ////////////////////////////////////////////////////////////
     /// \brief Change the position of the window on screen
     ///
@@ -212,7 +218,7 @@ private :
     /// \return Corrsponding SFML key code
     ///
     ////////////////////////////////////////////////////////////
-    static Key::Code KeysymToSF(KeySym symbol);
+    static Keyboard::Key KeysymToSF(KeySym symbol);
 
     ////////////////////////////////////////////////////////////
     // Member data
diff --git a/src/SFML/Window/Mouse.cpp b/src/SFML/Window/Mouse.cpp
new file mode 100644
index 00000000..afb63b18
--- /dev/null
+++ b/src/SFML/Window/Mouse.cpp
@@ -0,0 +1,58 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Mouse.hpp>
+#include <SFML/Window/InputImpl.hpp>
+#include <SFML/Window/Window.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+bool Mouse::IsButtonPressed(Button button)
+{
+    return priv::InputImpl::IsMouseButtonPressed(button);
+}
+
+
+////////////////////////////////////////////////////////////
+Vector2i Mouse::GetPosition()
+{
+    const Window* focusWindow = Window::GetMouseFocusWindow();
+    if (focusWindow)
+    {
+        // Position relative to the focus window
+        return focusWindow->GetCursorPosition();
+    }
+    else
+    {
+        // Desktop position
+        return priv::InputImpl::GetMousePosition();
+    }
+}
+
+} // namespace sf
diff --git a/src/SFML/Window/OSX/InputImpl.cpp b/src/SFML/Window/OSX/InputImpl.cpp
new file mode 100644
index 00000000..bfd635c6
--- /dev/null
+++ b/src/SFML/Window/OSX/InputImpl.cpp
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/OSX/InputImpl.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+bool InputImpl::IsKeyPressed(Keyboard::Key key)
+{
+	// @to be implemented
+    return false;
+}
+
+
+////////////////////////////////////////////////////////////
+bool InputImpl::IsMouseButtonPressed(Mouse::Button button)
+{
+	// @to be implemented
+    return false;
+}
+
+
+////////////////////////////////////////////////////////////
+Vector2i InputImpl::GetMousePosition()
+{
+	// @to be implemented
+    return Vector2i();
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/OSX/InputImpl.hpp b/src/SFML/Window/OSX/InputImpl.hpp
new file mode 100644
index 00000000..3d52da52
--- /dev/null
+++ b/src/SFML/Window/OSX/InputImpl.hpp
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_INPUTIMPLOSX_HPP
+#define SFML_INPUTIMPLOSX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window/Mouse.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Mac OS X implementation of inputs (keyboard + mouse)
+///
+////////////////////////////////////////////////////////////
+class InputImpl
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a key is pressed
+    ///
+    /// \param key Key to check
+    ///
+    /// \return True if the key is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsKeyPressed(Keyboard::Key key);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a mouse button is pressed
+    ///
+    /// \param button Button to check
+    ///
+    /// \return True if the button is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsMouseButtonPressed(Mouse::Button button);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of the mouse
+    ///
+    /// This function returns the mouse position in desktop coordinates.
+    ///
+    /// \return Current position of the mouse
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector2i GetMousePosition();
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_INPUTIMPLOSX_HPP
diff --git a/src/SFML/Window/Joystick.hpp b/src/SFML/Window/OSX/JoystickImpl.cpp
similarity index 59%
rename from src/SFML/Window/Joystick.hpp
rename to src/SFML/Window/OSX/JoystickImpl.cpp
index c98baf8e..c45c6722 100644
--- a/src/SFML/Window/Joystick.hpp
+++ b/src/SFML/Window/OSX/JoystickImpl.cpp
@@ -22,14 +22,10 @@
 //
 ////////////////////////////////////////////////////////////
 
-#ifndef SFML_JOYSTICK_HPP
-#define SFML_JOYSTICK_HPP
-
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
-#include <SFML/Window/Event.hpp>
+#include <SFML/Window/JoystickImpl.hpp>
 
 
 namespace sf
@@ -37,45 +33,43 @@ namespace sf
 namespace priv
 {
 ////////////////////////////////////////////////////////////
-/// \brief Structure holding the joystick state's parameters
-///
-////////////////////////////////////////////////////////////
-struct JoystickState
+bool JoystickImpl::IsConnected(unsigned int index)
 {
-    JoystickState()
-    {
-        // Default value for axes
-        for (int i = 0; i < Joy::AxisCount; ++i)
-            Axis[i] = 0.f;
-        Axis[Joy::AxisPOV] = -1.f;
+	// @to be implemented
+    return false;
+}
 
-        // Default value for buttons
-        for (int i = 0; i < Joy::ButtonCount; ++i)
-            Buttons[i] = false;
-    }
 
-    float Axis[Joy::AxisCount];      ///< Position on each axis in range [-100, 100] (except POV which is [0, 360])
-    bool  Buttons[Joy::ButtonCount]; ///< Status of each button (true = pressed)
-};
+////////////////////////////////////////////////////////////
+bool JoystickImpl::Open(unsigned int index)
+{
+	// @to be implemented
+    return false;
+}
+
+
+////////////////////////////////////////////////////////////
+void JoystickImpl::Close()
+{
+	// @to be implemented
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickCaps JoystickImpl::GetCapabilities() const
+{
+	// @to be implemented
+    return JoystickCaps();
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickState JoystickImpl::Update()
+{
+	// @to be implemented
+    return JoystickState();
+}
 
 } // namespace priv
 
 } // namespace sf
-
-
-#if defined(SFML_SYSTEM_WINDOWS)
-
-    #include <SFML/Window/Win32/Joystick.hpp>
-
-#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
-
-    #include <SFML/Window/Linux/Joystick.hpp>
-
-#elif defined(SFML_SYSTEM_MACOS)
-
-	#include <SFML/Window/OSX/Joystick.hpp>
-
-#endif
-
-
-#endif // SFML_JOYSTICK_HPP
diff --git a/src/SFML/Window/Win32/Joystick.hpp b/src/SFML/Window/OSX/JoystickImpl.hpp
similarity index 62%
rename from src/SFML/Window/Win32/Joystick.hpp
rename to src/SFML/Window/OSX/JoystickImpl.hpp
index 6b3c3874..970a0dd6 100644
--- a/src/SFML/Window/Win32/Joystick.hpp
+++ b/src/SFML/Window/OSX/JoystickImpl.hpp
@@ -1,96 +1,100 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_JOYSTICKWIN32_HPP
-#define SFML_JOYSTICKWIN32_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-/// \brief Windows implementation of Joystick
-///
-////////////////////////////////////////////////////////////
-class Joystick
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Initialize the instance and bind it to a physical joystick
-    ///
-    /// \param index Index of the physical joystick to bind to
-    ///
-    ////////////////////////////////////////////////////////////
-    void Initialize(unsigned int index);
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Update the current joystick and return its new state
-    ///
-    /// \return Current state of the joystick
-    ///
-    ////////////////////////////////////////////////////////////
-    JoystickState UpdateState();
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Check if the joystick supports the given axis
-    ///
-    /// \param Axis : Axis to check
-    ///
-    /// \return True of the axis is supported, false otherwise
-    ///
-    ////////////////////////////////////////////////////////////
-    bool HasAxis(Joy::Axis Axis) const;
-
-    ////////////////////////////////////////////////////////////
-    /// \brief Get the number of buttons supported by the joystick
-    ///
-    /// \return Number of buttons
-    ///
-    ////////////////////////////////////////////////////////////
-    unsigned int GetButtonsCount() const;
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    bool         myIsConnected;          ///< Is there a joystick connected?
-    unsigned int myIndex;                ///< Windows ID of the joystick
-    unsigned int myNbButtons;            ///< Number of buttons supported by the joystick
-    bool         myAxes[Joy::AxisCount]; ///< Supported axes
-    bool         myHasContinuousPOV;     ///< True if the driver supports continuous values for the POV
-};
-
-} // namespace priv
-
-} // namespace sf
-
-
-#endif // SFML_JOYSTICKWIN32_HPP
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_JOYSTICKIMPLOSX_HPP
+#define SFML_JOYSTICKIMPLOSX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/JoystickImpl.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Mac OS X implementation of joysticks
+///
+////////////////////////////////////////////////////////////
+class JoystickImpl
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick is currently connected
+    ///
+    /// \param index Index of the joystick to check
+    ///
+    /// \return True if the joystick is connected, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsConnected(unsigned int index);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Open the joystick
+    ///
+    /// \param index Index assigned to the joystick
+    ///
+    /// \return True on success, false on failure
+    ///
+    ////////////////////////////////////////////////////////////
+    bool Open(unsigned int index);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Close the joystick
+    ///
+    ////////////////////////////////////////////////////////////
+    void Close();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the joystick capabilities
+    ///
+    /// \return Joystick capabilities
+    ///
+    ////////////////////////////////////////////////////////////
+    JoystickCaps GetCapabilities() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the joystick and get its new state
+    ///
+    /// \return Joystick state
+    ///
+    ////////////////////////////////////////////////////////////
+    JoystickState Update();
+
+private :
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_JOYSTICKIMPLOSX_HPP
diff --git a/src/SFML/Window/OSX/SFApplication.h b/src/SFML/Window/OSX/SFApplication.h
index 92338fea..d3615eb6 100644
--- a/src/SFML/Window/OSX/SFApplication.h
+++ b/src/SFML/Window/OSX/SFApplication.h
@@ -38,9 +38,7 @@
 ////////////////////////////////////////////////////////////
 /// \brief Event processing
 ///
-/// \param block blocking mode means at least one event is proccessed.
-///
 ////////////////////////////////////////////////////////////
-+(void)processEventWithBlockingMode:(BOOL)block;
++(void)processEvent
 
 @end
diff --git a/src/SFML/Window/OSX/SFApplication.m b/src/SFML/Window/OSX/SFApplication.m
index cc484062..010bcb68 100644
--- a/src/SFML/Window/OSX/SFApplication.m
+++ b/src/SFML/Window/OSX/SFApplication.m
@@ -35,20 +35,11 @@
 
 
 ////////////////////////////////////////////////////////////
-+(void)processEventWithBlockingMode:(BOOL)block
++(void)processEvent
 {
     [NSApplication sharedApplication]; // Make sure NSApp exists
     NSEvent* event = nil;
     
-    if (block) { // At least one event is read.
-        event = [NSApp nextEventMatchingMask:NSAnyEventMask 
-                                   untilDate:[NSDate distantFuture]
-                                      inMode:NSDefaultRunLoopMode
-                                     dequeue:YES]; // Remove the event from the dequeue
-        [NSApp sendEvent:event];
-    }
-    
-    // If there are some other event read them.
     while ((event = [NSApp nextEventMatchingMask:NSAnyEventMask
                                        untilDate:[NSDate distantPast]
                                           inMode:NSDefaultRunLoopMode
diff --git a/src/SFML/Window/OSX/SFWindowController.mm b/src/SFML/Window/OSX/SFWindowController.mm
index 958ac647..1f5a1fa7 100644
--- a/src/SFML/Window/OSX/SFWindowController.mm
+++ b/src/SFML/Window/OSX/SFWindowController.mm
@@ -404,7 +404,7 @@
 
 
 ////////////////////////////////////////////////////////
--(void)processEventWithBlockingMode:(BOOL)block
+-(void)processEvent
 {
     // If we are not on the main thread we stop here and advice the user.
     if ([NSThread currentThread] != [NSThread mainThread]) {
@@ -421,7 +421,7 @@
     
     // If we don't have a requester we don't fetch event.
     if (myRequester != 0) {
-        [SFApplication processEventWithBlockingMode:block];
+        [SFApplication processEvent];
     }
 }
 
diff --git a/src/SFML/Window/OSX/WindowImplCocoa.hpp b/src/SFML/Window/OSX/WindowImplCocoa.hpp
index ef2c012b..6013abfa 100644
--- a/src/SFML/Window/OSX/WindowImplCocoa.hpp
+++ b/src/SFML/Window/OSX/WindowImplCocoa.hpp
@@ -233,13 +233,12 @@ public:
     static void SetUpProcess(void);
     
 private:
+
     ////////////////////////////////////////////////////////////
     /// \brief Process incoming events from the operating system
     ///
-    /// \param block Use true to block the thread until an event arrives
-    ///
     ////////////////////////////////////////////////////////////
-    virtual void ProcessEvents(bool block);
+    virtual void ProcessEvents();
     
     ////////////////////////////////////////////////////////////
     /// \brief Get the OS-specific handle of the window
@@ -266,6 +265,14 @@ private:
     ////////////////////////////////////////////////////////////
     virtual void SetCursorPosition(unsigned int x, unsigned int y);
     
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the position of the mouse cursor
+    ///
+    /// \return Current mouse cursor position, relative to the window
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Vector2i GetCursorPosition() const;
+
     ////////////////////////////////////////////////////////////
     /// \brief Change the position of the window on screen
     ///
diff --git a/src/SFML/Window/OSX/WindowImplCocoa.mm b/src/SFML/Window/OSX/WindowImplCocoa.mm
index 162231e6..57866623 100644
--- a/src/SFML/Window/OSX/WindowImplCocoa.mm
+++ b/src/SFML/Window/OSX/WindowImplCocoa.mm
@@ -312,9 +312,9 @@ void WindowImplCocoa::TextEntered(unichar charcode)
 #pragma mark WindowImplCocoa's event-related methods
 
 ////////////////////////////////////////////////////////////
-void WindowImplCocoa::ProcessEvents(bool block)
+void WindowImplCocoa::ProcessEvents()
 {
-    [myDelegate processEventWithBlockingMode:(block ? YES : NO)];
+    [myDelegate processEvent];
 }
     
 #pragma mark
@@ -344,6 +344,14 @@ void WindowImplCocoa::SetCursorPosition(unsigned int x, unsigned int y)
     [myDelegate setCursorPositionToX:x Y:y];
 }
 
+
+////////////////////////////////////////////////////////////
+Vector2i WindowImplCocoa::GetCursorPosition() const
+{
+	// @to be implemented
+    return Vector2i();
+}
+
     
 ////////////////////////////////////////////////////////////
 void WindowImplCocoa::SetPosition(int x, int y)
diff --git a/src/SFML/Window/Win32/InputImpl.cpp b/src/SFML/Window/Win32/InputImpl.cpp
new file mode 100644
index 00000000..6845be41
--- /dev/null
+++ b/src/SFML/Window/Win32/InputImpl.cpp
@@ -0,0 +1,179 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#define _WIN32_WINDOWS 0x0501
+#define _WIN32_WINNT   0x0501
+#include <SFML/Window/Win32/InputImpl.hpp>
+#include <windows.h>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+bool InputImpl::IsKeyPressed(Keyboard::Key key)
+{
+    int vkey = 0;
+    switch (key)
+    {
+        case Keyboard::A:          vkey = 'A';           break;
+        case Keyboard::B:          vkey = 'B';           break;
+        case Keyboard::C:          vkey = 'C';           break;
+        case Keyboard::D:          vkey = 'D';           break;
+        case Keyboard::E:          vkey = 'E';           break;
+        case Keyboard::F:          vkey = 'F';           break;
+        case Keyboard::G:          vkey = 'G';           break;
+        case Keyboard::H:          vkey = 'H';           break;
+        case Keyboard::I:          vkey = 'I';           break;
+        case Keyboard::J:          vkey = 'J';           break;
+        case Keyboard::K:          vkey = 'K';           break;
+        case Keyboard::L:          vkey = 'L';           break;
+        case Keyboard::M:          vkey = 'M';           break;
+        case Keyboard::N:          vkey = 'N';           break;
+        case Keyboard::O:          vkey = 'O';           break;
+        case Keyboard::P:          vkey = 'P';           break;
+        case Keyboard::Q:          vkey = 'Q';           break;
+        case Keyboard::R:          vkey = 'R';           break;
+        case Keyboard::S:          vkey = 'S';           break;
+        case Keyboard::T:          vkey = 'T';           break;
+        case Keyboard::U:          vkey = 'U';           break;
+        case Keyboard::V:          vkey = 'V';           break;
+        case Keyboard::W:          vkey = 'W';           break;
+        case Keyboard::X:          vkey = 'X';           break;
+        case Keyboard::Y:          vkey = 'Y';           break;
+        case Keyboard::Z:          vkey = 'Z';           break;
+        case Keyboard::Num0:       vkey = '0';           break;
+        case Keyboard::Num1:       vkey = '1';           break;
+        case Keyboard::Num2:       vkey = '2';           break;
+        case Keyboard::Num3:       vkey = '3';           break;
+        case Keyboard::Num4:       vkey = '4';           break;
+        case Keyboard::Num5:       vkey = '5';           break;
+        case Keyboard::Num6:       vkey = '6';           break;
+        case Keyboard::Num7:       vkey = '7';           break;
+        case Keyboard::Num8:       vkey = '8';           break;
+        case Keyboard::Num9:       vkey = '9';           break;
+        case Keyboard::Escape:     vkey = VK_ESCAPE;     break;
+        case Keyboard::LControl:   vkey = VK_LCONTROL;   break;
+        case Keyboard::LShift:     vkey = VK_LSHIFT;     break;
+        case Keyboard::LAlt:       vkey = VK_LMENU;      break;
+        case Keyboard::LSystem:    vkey = VK_LWIN;       break;
+        case Keyboard::RControl:   vkey = VK_RCONTROL;   break;
+        case Keyboard::RShift:     vkey = VK_RSHIFT;     break;
+        case Keyboard::RAlt:       vkey = VK_RMENU;      break;
+        case Keyboard::RSystem:    vkey = VK_RWIN;       break;
+        case Keyboard::Menu:       vkey = VK_APPS;       break;
+        case Keyboard::LBracket:   vkey = VK_OEM_4;      break;
+        case Keyboard::RBracket:   vkey = VK_OEM_6;      break;
+        case Keyboard::SemiColon:  vkey = VK_OEM_1;      break;
+        case Keyboard::Comma:      vkey = VK_OEM_COMMA;  break;
+        case Keyboard::Period:     vkey = VK_OEM_PERIOD; break;
+        case Keyboard::Quote:      vkey = VK_OEM_7;      break;
+        case Keyboard::Slash:      vkey = VK_OEM_2;      break;
+        case Keyboard::BackSlash:  vkey = VK_OEM_5;      break;
+        case Keyboard::Tilde:      vkey = VK_OEM_3;      break;
+        case Keyboard::Equal:      vkey = VK_OEM_PLUS;   break;
+        case Keyboard::Dash:       vkey = VK_OEM_MINUS;  break;
+        case Keyboard::Space:      vkey = VK_SPACE;      break;
+        case Keyboard::Return:     vkey = VK_RETURN;     break;
+        case Keyboard::Back:       vkey = VK_BACK;       break;
+        case Keyboard::Tab:        vkey = VK_TAB;        break;
+        case Keyboard::PageUp:     vkey = VK_PRIOR;      break;
+        case Keyboard::PageDown:   vkey = VK_NEXT;       break;
+        case Keyboard::End:        vkey = VK_END;        break;
+        case Keyboard::Home:       vkey = VK_HOME;       break;
+        case Keyboard::Insert:     vkey = VK_INSERT;     break;
+        case Keyboard::Delete:     vkey = VK_DELETE;     break;
+        case Keyboard::Add:        vkey = VK_ADD;        break;
+        case Keyboard::Subtract:   vkey = VK_SUBTRACT;   break;
+        case Keyboard::Multiply:   vkey = VK_MULTIPLY;   break;
+        case Keyboard::Divide:     vkey = VK_DIVIDE;     break;
+        case Keyboard::Left:       vkey = VK_LEFT;       break;
+        case Keyboard::Right:      vkey = VK_RIGHT;      break;
+        case Keyboard::Up:         vkey = VK_UP;         break;
+        case Keyboard::Down:       vkey = VK_DOWN;       break;
+        case Keyboard::Numpad0:    vkey = VK_NUMPAD0;    break;
+        case Keyboard::Numpad1:    vkey = VK_NUMPAD1;    break;
+        case Keyboard::Numpad2:    vkey = VK_NUMPAD2;    break;
+        case Keyboard::Numpad3:    vkey = VK_NUMPAD3;    break;
+        case Keyboard::Numpad4:    vkey = VK_NUMPAD4;    break;
+        case Keyboard::Numpad5:    vkey = VK_NUMPAD5;    break;
+        case Keyboard::Numpad6:    vkey = VK_NUMPAD6;    break;
+        case Keyboard::Numpad7:    vkey = VK_NUMPAD7;    break;
+        case Keyboard::Numpad8:    vkey = VK_NUMPAD8;    break;
+        case Keyboard::Numpad9:    vkey = VK_NUMPAD9;    break;
+        case Keyboard::F1:         vkey = VK_F1;         break;
+        case Keyboard::F2:         vkey = VK_F2;         break;
+        case Keyboard::F3:         vkey = VK_F3;         break;
+        case Keyboard::F4:         vkey = VK_F4;         break;
+        case Keyboard::F5:         vkey = VK_F5;         break;
+        case Keyboard::F6:         vkey = VK_F6;         break;
+        case Keyboard::F7:         vkey = VK_F7;         break;
+        case Keyboard::F8:         vkey = VK_F8;         break;
+        case Keyboard::F9:         vkey = VK_F9;         break;
+        case Keyboard::F10:        vkey = VK_F10;        break;
+        case Keyboard::F11:        vkey = VK_F11;        break;
+        case Keyboard::F12:        vkey = VK_F12;        break;
+        case Keyboard::F13:        vkey = VK_F13;        break;
+        case Keyboard::F14:        vkey = VK_F14;        break;
+        case Keyboard::F15:        vkey = VK_F16;        break;
+        case Keyboard::Pause:      vkey = VK_PAUSE;      break;
+    }
+
+    return GetAsyncKeyState(vkey) != 0;
+}
+
+
+////////////////////////////////////////////////////////////
+bool InputImpl::IsMouseButtonPressed(Mouse::Button button)
+{
+    int vkey = 0;
+    switch (button)
+    {
+        case Mouse::Left:     vkey = VK_LBUTTON;  break;
+        case Mouse::Right:    vkey = VK_RBUTTON;  break;
+        case Mouse::Middle:   vkey = VK_MBUTTON;  break;
+        case Mouse::XButton1: vkey = VK_XBUTTON1; break;
+        case Mouse::XButton2: vkey = VK_XBUTTON2; break;
+    }
+
+    return GetAsyncKeyState(vkey) != 0;
+}
+
+
+////////////////////////////////////////////////////////////
+Vector2i InputImpl::GetMousePosition()
+{
+    POINT position;
+    GetCursorPos(&position);
+
+    return Vector2i(position.x, position.y);
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Win32/InputImpl.hpp b/src/SFML/Window/Win32/InputImpl.hpp
new file mode 100644
index 00000000..5870f4f1
--- /dev/null
+++ b/src/SFML/Window/Win32/InputImpl.hpp
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_INPUTIMPLWIN32_HPP
+#define SFML_INPUTIMPLWIN32_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window/Mouse.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Windows implementation of inputs (keyboard + mouse)
+///
+////////////////////////////////////////////////////////////
+class InputImpl
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a key is pressed
+    ///
+    /// \param key Key to check
+    ///
+    /// \return True if the key is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsKeyPressed(Keyboard::Key key);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a mouse button is pressed
+    ///
+    /// \param button Button to check
+    ///
+    /// \return True if the button is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsMouseButtonPressed(Mouse::Button button);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of the mouse
+    ///
+    /// This function returns the mouse position in desktop coordinates.
+    ///
+    /// \return Current position of the mouse
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector2i GetMousePosition();
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_INPUTIMPLWIN32_HPP
diff --git a/src/SFML/Window/Win32/Joystick.cpp b/src/SFML/Window/Win32/Joystick.cpp
deleted file mode 100644
index e14552f7..00000000
--- a/src/SFML/Window/Win32/Joystick.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages 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.
-//
-////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#define _WIN32_WINDOWS 0x0501
-#define _WIN32_WINNT   0x0501
-#include <SFML/Window/Joystick.hpp>
-#include <windows.h>
-#include <mmsystem.h>
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-void Joystick::Initialize(unsigned int index)
-{
-    // Reset state
-    myIndex            = JOYSTICKID1;
-    myNbButtons        = 0;
-    myIsConnected      = false;
-    myHasContinuousPOV = false;
-    for (int i = 0; i < Joy::AxisCount; ++i)
-        myAxes[i] = false;
-
-    // Get the Index-th connected joystick
-    MMRESULT error;
-    JOYINFOEX joyInfos;
-    joyInfos.dwSize = sizeof(joyInfos);
-    joyInfos.dwFlags = JOY_RETURNALL;
-    for (unsigned int found = 0; (error = joyGetPosEx(myIndex, &joyInfos)) != JOYERR_PARMS; myIndex++)
-    {
-        // Check if the current joystick is connected
-        if (error == JOYERR_NOERROR)
-        {
-            // Check if it's the required index
-            if (found == index)
-            {
-                // Ok : store its parameters and return
-                myIsConnected = true;
-                JOYCAPS caps;
-                joyGetDevCaps(myIndex, &caps, sizeof(caps));
-                myNbButtons = caps.wNumButtons;
-                if (myNbButtons > Joy::ButtonCount)
-                    myNbButtons = Joy::ButtonCount;
-
-                myAxes[Joy::AxisX]   = true;
-                myAxes[Joy::AxisY]   = true;
-                myAxes[Joy::AxisZ]   = (caps.wCaps & JOYCAPS_HASZ) != 0;
-                myAxes[Joy::AxisR]   = (caps.wCaps & JOYCAPS_HASR) != 0;
-                myAxes[Joy::AxisU]   = (caps.wCaps & JOYCAPS_HASU) != 0;
-                myAxes[Joy::AxisV]   = (caps.wCaps & JOYCAPS_HASV) != 0;
-                myAxes[Joy::AxisPOV] = (caps.wCaps & JOYCAPS_HASPOV) != 0;
-                myHasContinuousPOV   = (caps.wCaps & JOYCAPS_POVCTS) != 0;
-
-                return;
-            }
-
-            // Go to the next valid joystick
-            ++found;
-        }
-    }
-}
-
-
-////////////////////////////////////////////////////////////
-JoystickState Joystick::UpdateState()
-{
-    JoystickState state;
-
-    if (myIsConnected)
-    {
-        // Get the joystick caps (for range conversions)
-        JOYCAPS caps;
-        if (joyGetDevCaps(myIndex, &caps, sizeof(caps)) == JOYERR_NOERROR)
-        {
-            // Get the current joystick state
-            JOYINFOEX pos;
-            pos.dwFlags  = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | JOY_RETURNBUTTONS;
-            pos.dwFlags |= myHasContinuousPOV ? JOY_RETURNPOVCTS : JOY_RETURNPOV;
-            pos.dwSize   = sizeof(JOYINFOEX);
-            if (joyGetPosEx(myIndex, &pos) == JOYERR_NOERROR)
-            {
-                // Axes
-                state.Axis[Joy::AxisX] = (pos.dwXpos - (caps.wXmax + caps.wXmin) / 2.f) * 200.f / (caps.wXmax - caps.wXmin);
-                state.Axis[Joy::AxisY] = (pos.dwYpos - (caps.wYmax + caps.wYmin) / 2.f) * 200.f / (caps.wYmax - caps.wYmin);
-                state.Axis[Joy::AxisZ] = (pos.dwZpos - (caps.wZmax + caps.wZmin) / 2.f) * 200.f / (caps.wZmax - caps.wZmin);
-                state.Axis[Joy::AxisR] = (pos.dwRpos - (caps.wRmax + caps.wRmin) / 2.f) * 200.f / (caps.wRmax - caps.wRmin);
-                state.Axis[Joy::AxisU] = (pos.dwUpos - (caps.wUmax + caps.wUmin) / 2.f) * 200.f / (caps.wUmax - caps.wUmin);
-                state.Axis[Joy::AxisV] = (pos.dwVpos - (caps.wVmax + caps.wVmin) / 2.f) * 200.f / (caps.wVmax - caps.wVmin);
-
-                // POV
-                if (pos.dwPOV != 0xFFFF)
-                    state.Axis[Joy::AxisPOV] = pos.dwPOV / 100.f;
-                else
-                    state.Axis[Joy::AxisPOV] = -1.f;
-
-                // Buttons
-                for (unsigned int i = 0; i < GetButtonsCount(); ++i)
-                    state.Buttons[i] = (pos.dwButtons & (1 << i)) != 0;
-            }
-        }
-    }
-
-    return state;
-}
-
-
-////////////////////////////////////////////////////////////
-bool Joystick::HasAxis(Joy::Axis Axis) const
-{
-    return myAxes[Axis];
-}
-
-
-////////////////////////////////////////////////////////////
-unsigned int Joystick::GetButtonsCount() const
-{
-    return myNbButtons;
-}
-
-
-} // namespace priv
-
-} // namespace sf
diff --git a/src/SFML/Window/Win32/JoystickImpl.cpp b/src/SFML/Window/Win32/JoystickImpl.cpp
new file mode 100644
index 00000000..862e488f
--- /dev/null
+++ b/src/SFML/Window/Win32/JoystickImpl.cpp
@@ -0,0 +1,134 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages 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.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/JoystickImpl.hpp>
+#include <windows.h>
+#include <cmath>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+bool JoystickImpl::IsConnected(unsigned int index)
+{
+    JOYINFOEX joyInfo;
+    joyInfo.dwSize = sizeof(joyInfo);
+    joyInfo.dwFlags = 0;
+
+    return joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
+}
+
+
+////////////////////////////////////////////////////////////
+bool JoystickImpl::Open(unsigned int index)
+{
+    // No explicit "open" action is required
+    myIndex = JOYSTICKID1 + index;
+
+    // Store the joystick capabilities
+    return joyGetDevCaps(myIndex, &myCaps, sizeof(myCaps)) == JOYERR_NOERROR;
+}
+
+
+////////////////////////////////////////////////////////////
+void JoystickImpl::Close()
+{
+    // Nothing to do
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickCaps JoystickImpl::GetCapabilities() const
+{
+    JoystickCaps caps;
+
+    caps.ButtonCount = myCaps.wNumButtons;
+    if (caps.ButtonCount > Joystick::ButtonCount)
+        caps.ButtonCount = Joystick::ButtonCount;
+
+    caps.Axes[Joystick::X]    = true;
+    caps.Axes[Joystick::Y]    = true;
+    caps.Axes[Joystick::Z]    = (myCaps.wCaps & JOYCAPS_HASZ) != 0;
+    caps.Axes[Joystick::R]    = (myCaps.wCaps & JOYCAPS_HASR) != 0;
+    caps.Axes[Joystick::U]    = (myCaps.wCaps & JOYCAPS_HASU) != 0;
+    caps.Axes[Joystick::V]    = (myCaps.wCaps & JOYCAPS_HASV) != 0;
+    caps.Axes[Joystick::PovX] = (myCaps.wCaps & JOYCAPS_HASPOV) != 0;
+    caps.Axes[Joystick::PovY] = (myCaps.wCaps & JOYCAPS_HASPOV) != 0;
+
+    return caps;
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickState JoystickImpl::Update()
+{
+    JoystickState state;
+
+    // Get the current joystick state
+    JOYINFOEX pos;
+    pos.dwFlags  = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | JOY_RETURNBUTTONS;
+    pos.dwFlags |= (myCaps.wCaps & JOYCAPS_POVCTS) ? JOY_RETURNPOVCTS : JOY_RETURNPOV;
+    pos.dwSize   = sizeof(JOYINFOEX);
+    if (joyGetPosEx(myIndex, &pos) == JOYERR_NOERROR)
+    {
+        // The joystick is connected
+        state.Connected = true;
+
+        // Axes
+        state.Axes[Joystick::X] = (pos.dwXpos - (myCaps.wXmax + myCaps.wXmin) / 2.f) * 200.f / (myCaps.wXmax - myCaps.wXmin);
+        state.Axes[Joystick::Y] = (pos.dwYpos - (myCaps.wYmax + myCaps.wYmin) / 2.f) * 200.f / (myCaps.wYmax - myCaps.wYmin);
+        state.Axes[Joystick::Z] = (pos.dwZpos - (myCaps.wZmax + myCaps.wZmin) / 2.f) * 200.f / (myCaps.wZmax - myCaps.wZmin);
+        state.Axes[Joystick::R] = (pos.dwRpos - (myCaps.wRmax + myCaps.wRmin) / 2.f) * 200.f / (myCaps.wRmax - myCaps.wRmin);
+        state.Axes[Joystick::U] = (pos.dwUpos - (myCaps.wUmax + myCaps.wUmin) / 2.f) * 200.f / (myCaps.wUmax - myCaps.wUmin);
+        state.Axes[Joystick::V] = (pos.dwVpos - (myCaps.wVmax + myCaps.wVmin) / 2.f) * 200.f / (myCaps.wVmax - myCaps.wVmin);
+
+        // Special case for POV, it is given as an angle
+        if (pos.dwPOV != 0xFFFF)
+        {
+            float angle = pos.dwPOV / 36000.f * 3.141592654f;
+            state.Axes[Joystick::PovX] = std::cos(angle) * 100;
+            state.Axes[Joystick::PovY] = std::sin(angle) * 100;
+        }
+        else
+        {
+            state.Axes[Joystick::PovX] = 0;
+            state.Axes[Joystick::PovY] = 0;
+        }
+
+        // Buttons
+        for (unsigned int i = 0; i < Joystick::ButtonCount; ++i)
+            state.Buttons[i] = (pos.dwButtons & (1 << i)) != 0;
+    }
+
+    return state;
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Win32/JoystickImpl.hpp b/src/SFML/Window/Win32/JoystickImpl.hpp
new file mode 100644
index 00000000..800f0d72
--- /dev/null
+++ b/src/SFML/Window/Win32/JoystickImpl.hpp
@@ -0,0 +1,107 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_JOYSTICKIMPLWIN32_HPP
+#define SFML_JOYSTICKIMPLWIN32_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#define _WIN32_WINDOWS 0x0501
+#define _WIN32_WINNT   0x0501
+#include <SFML/Window/JoystickImpl.hpp>
+#include <windows.h>
+#include <mmsystem.h>
+#include <cmath>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Windows implementation of joysticks
+///
+////////////////////////////////////////////////////////////
+class JoystickImpl
+{
+public :
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick is currently connected
+    ///
+    /// \param index Index of the joystick to check
+    ///
+    /// \return True if the joystick is connected, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool IsConnected(unsigned int index);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Open the joystick
+    ///
+    /// \param index Index assigned to the joystick
+    ///
+    /// \return True on success, false on failure
+    ///
+    ////////////////////////////////////////////////////////////
+    bool Open(unsigned int index);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Close the joystick
+    ///
+    ////////////////////////////////////////////////////////////
+    void Close();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the joystick capabilities
+    ///
+    /// \return Joystick capabilities
+    ///
+    ////////////////////////////////////////////////////////////
+    JoystickCaps GetCapabilities() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the joystick and get its new state
+    ///
+    /// \return Joystick state
+    ///
+    ////////////////////////////////////////////////////////////
+    JoystickState Update();
+
+private :
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    unsigned int myIndex; ///< Index of the joystick
+    JOYCAPS      myCaps;  ///< Joystick capabilities
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_JOYSTICKIMPLWIN32_HPP
diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp
index 0788c5b1..d440260e 100644
--- a/src/SFML/Window/Win32/WindowImplWin32.cpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.cpp
@@ -204,14 +204,11 @@ WindowHandle WindowImplWin32::GetSystemHandle() const
 
 
 ////////////////////////////////////////////////////////////
-void WindowImplWin32::ProcessEvents(bool block)
+void WindowImplWin32::ProcessEvents()
 {
     // We process the window events only if we own it
     if (!myCallback)
     {
-        if (block)
-            WaitMessage();
-
         MSG message;
         while (PeekMessage(&message, myHandle, 0, 0, PM_REMOVE))
         {
@@ -243,6 +240,17 @@ void WindowImplWin32::SetCursorPosition(unsigned int x, unsigned int y)
 }
 
 
+////////////////////////////////////////////////////////////
+Vector2i WindowImplWin32::GetCursorPosition() const
+{
+    POINT position;
+    GetCursorPos(&position);
+    ScreenToClient(myHandle, &position);
+
+    return Vector2i(position.x, position.y);
+}
+
+
 ////////////////////////////////////////////////////////////
 void WindowImplWin32::SetPosition(int x, int y)
 {
@@ -676,7 +684,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
 
 
 ////////////////////////////////////////////////////////////
-Key::Code WindowImplWin32::VirtualKeyCodeToSF(WPARAM key, LPARAM flags)
+Keyboard::Key WindowImplWin32::VirtualKeyCodeToSF(WPARAM key, LPARAM flags)
 {
     switch (key)
     {
@@ -685,114 +693,114 @@ Key::Code WindowImplWin32::VirtualKeyCodeToSF(WPARAM key, LPARAM flags)
         {
             static UINT lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
             UINT scancode = static_cast<UINT>((flags & (0xFF << 16)) >> 16);
-            return scancode == lShift ? Key::LShift : Key::RShift;
+            return scancode == lShift ? Keyboard::LShift : Keyboard::RShift;
         }
 
         // Check the "extended" flag to distinguish between left and right alt
-        case VK_MENU : return (HIWORD(flags) & KF_EXTENDED) ? Key::RAlt : Key::LAlt;
+        case VK_MENU : return (HIWORD(flags) & KF_EXTENDED) ? Keyboard::RAlt : Keyboard::LAlt;
 
         // Check the "extended" flag to distinguish between left and right control
-        case VK_CONTROL : return (HIWORD(flags) & KF_EXTENDED) ? Key::RControl : Key::LControl;
+        case VK_CONTROL : return (HIWORD(flags) & KF_EXTENDED) ? Keyboard::RControl : Keyboard::LControl;
 
         // Other keys are reported properly
-        case VK_LWIN :       return Key::LSystem;
-        case VK_RWIN :       return Key::RSystem;
-        case VK_APPS :       return Key::Menu;
-        case VK_OEM_1 :      return Key::SemiColon;
-        case VK_OEM_2 :      return Key::Slash;
-        case VK_OEM_PLUS :   return Key::Equal;
-        case VK_OEM_MINUS :  return Key::Dash;
-        case VK_OEM_4 :      return Key::LBracket;
-        case VK_OEM_6 :      return Key::RBracket;
-        case VK_OEM_COMMA :  return Key::Comma;
-        case VK_OEM_PERIOD : return Key::Period;
-        case VK_OEM_7 :      return Key::Quote;
-        case VK_OEM_5 :      return Key::BackSlash;
-        case VK_OEM_3 :      return Key::Tilde;
-        case VK_ESCAPE :     return Key::Escape;
-        case VK_SPACE :      return Key::Space;
-        case VK_RETURN :     return Key::Return;
-        case VK_BACK :       return Key::Back;
-        case VK_TAB :        return Key::Tab;
-        case VK_PRIOR :      return Key::PageUp;
-        case VK_NEXT :       return Key::PageDown;
-        case VK_END :        return Key::End;
-        case VK_HOME :       return Key::Home;
-        case VK_INSERT :     return Key::Insert;
-        case VK_DELETE :     return Key::Delete;
-        case VK_ADD :        return Key::Add;
-        case VK_SUBTRACT :   return Key::Subtract;
-        case VK_MULTIPLY :   return Key::Multiply;
-        case VK_DIVIDE :     return Key::Divide;
-        case VK_PAUSE :      return Key::Pause;
-        case VK_F1 :         return Key::F1;
-        case VK_F2 :         return Key::F2;
-        case VK_F3 :         return Key::F3;
-        case VK_F4 :         return Key::F4;
-        case VK_F5 :         return Key::F5;
-        case VK_F6 :         return Key::F6;
-        case VK_F7 :         return Key::F7;
-        case VK_F8 :         return Key::F8;
-        case VK_F9 :         return Key::F9;
-        case VK_F10 :        return Key::F10;
-        case VK_F11 :        return Key::F11;
-        case VK_F12 :        return Key::F12;
-        case VK_F13 :        return Key::F13;
-        case VK_F14 :        return Key::F14;
-        case VK_F15 :        return Key::F15;
-        case VK_LEFT :       return Key::Left;
-        case VK_RIGHT :      return Key::Right;
-        case VK_UP :         return Key::Up;
-        case VK_DOWN :       return Key::Down;
-        case VK_NUMPAD0 :    return Key::Numpad0;
-        case VK_NUMPAD1 :    return Key::Numpad1;
-        case VK_NUMPAD2 :    return Key::Numpad2;
-        case VK_NUMPAD3 :    return Key::Numpad3;
-        case VK_NUMPAD4 :    return Key::Numpad4;
-        case VK_NUMPAD5 :    return Key::Numpad5;
-        case VK_NUMPAD6 :    return Key::Numpad6;
-        case VK_NUMPAD7 :    return Key::Numpad7;
-        case VK_NUMPAD8 :    return Key::Numpad8;
-        case VK_NUMPAD9 :    return Key::Numpad9;
-        case 'A' :           return Key::A;
-        case 'Z' :           return Key::Z;
-        case 'E' :           return Key::E;
-        case 'R' :           return Key::R;
-        case 'T' :           return Key::T;
-        case 'Y' :           return Key::Y;
-        case 'U' :           return Key::U;
-        case 'I' :           return Key::I;
-        case 'O' :           return Key::O;
-        case 'P' :           return Key::P;
-        case 'Q' :           return Key::Q;
-        case 'S' :           return Key::S;
-        case 'D' :           return Key::D;
-        case 'F' :           return Key::F;
-        case 'G' :           return Key::G;
-        case 'H' :           return Key::H;
-        case 'J' :           return Key::J;
-        case 'K' :           return Key::K;
-        case 'L' :           return Key::L;
-        case 'M' :           return Key::M;
-        case 'W' :           return Key::W;
-        case 'X' :           return Key::X;
-        case 'C' :           return Key::C;
-        case 'V' :           return Key::V;
-        case 'B' :           return Key::B;
-        case 'N' :           return Key::N;
-        case '0' :           return Key::Num0;
-        case '1' :           return Key::Num1;
-        case '2' :           return Key::Num2;
-        case '3' :           return Key::Num3;
-        case '4' :           return Key::Num4;
-        case '5' :           return Key::Num5;
-        case '6' :           return Key::Num6;
-        case '7' :           return Key::Num7;
-        case '8' :           return Key::Num8;
-        case '9' :           return Key::Num9;
+        case VK_LWIN :       return Keyboard::LSystem;
+        case VK_RWIN :       return Keyboard::RSystem;
+        case VK_APPS :       return Keyboard::Menu;
+        case VK_OEM_1 :      return Keyboard::SemiColon;
+        case VK_OEM_2 :      return Keyboard::Slash;
+        case VK_OEM_PLUS :   return Keyboard::Equal;
+        case VK_OEM_MINUS :  return Keyboard::Dash;
+        case VK_OEM_4 :      return Keyboard::LBracket;
+        case VK_OEM_6 :      return Keyboard::RBracket;
+        case VK_OEM_COMMA :  return Keyboard::Comma;
+        case VK_OEM_PERIOD : return Keyboard::Period;
+        case VK_OEM_7 :      return Keyboard::Quote;
+        case VK_OEM_5 :      return Keyboard::BackSlash;
+        case VK_OEM_3 :      return Keyboard::Tilde;
+        case VK_ESCAPE :     return Keyboard::Escape;
+        case VK_SPACE :      return Keyboard::Space;
+        case VK_RETURN :     return Keyboard::Return;
+        case VK_BACK :       return Keyboard::Back;
+        case VK_TAB :        return Keyboard::Tab;
+        case VK_PRIOR :      return Keyboard::PageUp;
+        case VK_NEXT :       return Keyboard::PageDown;
+        case VK_END :        return Keyboard::End;
+        case VK_HOME :       return Keyboard::Home;
+        case VK_INSERT :     return Keyboard::Insert;
+        case VK_DELETE :     return Keyboard::Delete;
+        case VK_ADD :        return Keyboard::Add;
+        case VK_SUBTRACT :   return Keyboard::Subtract;
+        case VK_MULTIPLY :   return Keyboard::Multiply;
+        case VK_DIVIDE :     return Keyboard::Divide;
+        case VK_PAUSE :      return Keyboard::Pause;
+        case VK_F1 :         return Keyboard::F1;
+        case VK_F2 :         return Keyboard::F2;
+        case VK_F3 :         return Keyboard::F3;
+        case VK_F4 :         return Keyboard::F4;
+        case VK_F5 :         return Keyboard::F5;
+        case VK_F6 :         return Keyboard::F6;
+        case VK_F7 :         return Keyboard::F7;
+        case VK_F8 :         return Keyboard::F8;
+        case VK_F9 :         return Keyboard::F9;
+        case VK_F10 :        return Keyboard::F10;
+        case VK_F11 :        return Keyboard::F11;
+        case VK_F12 :        return Keyboard::F12;
+        case VK_F13 :        return Keyboard::F13;
+        case VK_F14 :        return Keyboard::F14;
+        case VK_F15 :        return Keyboard::F15;
+        case VK_LEFT :       return Keyboard::Left;
+        case VK_RIGHT :      return Keyboard::Right;
+        case VK_UP :         return Keyboard::Up;
+        case VK_DOWN :       return Keyboard::Down;
+        case VK_NUMPAD0 :    return Keyboard::Numpad0;
+        case VK_NUMPAD1 :    return Keyboard::Numpad1;
+        case VK_NUMPAD2 :    return Keyboard::Numpad2;
+        case VK_NUMPAD3 :    return Keyboard::Numpad3;
+        case VK_NUMPAD4 :    return Keyboard::Numpad4;
+        case VK_NUMPAD5 :    return Keyboard::Numpad5;
+        case VK_NUMPAD6 :    return Keyboard::Numpad6;
+        case VK_NUMPAD7 :    return Keyboard::Numpad7;
+        case VK_NUMPAD8 :    return Keyboard::Numpad8;
+        case VK_NUMPAD9 :    return Keyboard::Numpad9;
+        case 'A' :           return Keyboard::A;
+        case 'Z' :           return Keyboard::Z;
+        case 'E' :           return Keyboard::E;
+        case 'R' :           return Keyboard::R;
+        case 'T' :           return Keyboard::T;
+        case 'Y' :           return Keyboard::Y;
+        case 'U' :           return Keyboard::U;
+        case 'I' :           return Keyboard::I;
+        case 'O' :           return Keyboard::O;
+        case 'P' :           return Keyboard::P;
+        case 'Q' :           return Keyboard::Q;
+        case 'S' :           return Keyboard::S;
+        case 'D' :           return Keyboard::D;
+        case 'F' :           return Keyboard::F;
+        case 'G' :           return Keyboard::G;
+        case 'H' :           return Keyboard::H;
+        case 'J' :           return Keyboard::J;
+        case 'K' :           return Keyboard::K;
+        case 'L' :           return Keyboard::L;
+        case 'M' :           return Keyboard::M;
+        case 'W' :           return Keyboard::W;
+        case 'X' :           return Keyboard::X;
+        case 'C' :           return Keyboard::C;
+        case 'V' :           return Keyboard::V;
+        case 'B' :           return Keyboard::B;
+        case 'N' :           return Keyboard::N;
+        case '0' :           return Keyboard::Num0;
+        case '1' :           return Keyboard::Num1;
+        case '2' :           return Keyboard::Num2;
+        case '3' :           return Keyboard::Num3;
+        case '4' :           return Keyboard::Num4;
+        case '5' :           return Keyboard::Num5;
+        case '6' :           return Keyboard::Num6;
+        case '7' :           return Keyboard::Num7;
+        case '8' :           return Keyboard::Num8;
+        case '9' :           return Keyboard::Num9;
     }
 
-    return Key::Code(0);
+    return Keyboard::Key(0);
 }
 
 
diff --git a/src/SFML/Window/Win32/WindowImplWin32.hpp b/src/SFML/Window/Win32/WindowImplWin32.hpp
index 923db0e4..c8120874 100644
--- a/src/SFML/Window/Win32/WindowImplWin32.hpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.hpp
@@ -83,10 +83,8 @@ private :
     ////////////////////////////////////////////////////////////
     /// \brief Process incoming events from the operating system
     ///
-    /// \param block Use true to block the thread until an event arrives
-    ///
     ////////////////////////////////////////////////////////////
-    virtual void ProcessEvents(bool block);
+    virtual void ProcessEvents();
 
     ////////////////////////////////////////////////////////////
     /// \brief Show or hide the mouse cursor
@@ -105,6 +103,14 @@ private :
     ////////////////////////////////////////////////////////////
     virtual void SetCursorPosition(unsigned int x, unsigned int y);
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the position of the mouse cursor
+    ///
+    /// \return Current mouse cursor position, relative to the window
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Vector2i GetCursorPosition() const;
+
     ////////////////////////////////////////////////////////////
     /// \brief Change the position of the window on screen
     ///
@@ -196,7 +202,7 @@ private :
     /// \return SFML key code corresponding to the key
     ///
     ////////////////////////////////////////////////////////////
-    static Key::Code VirtualKeyCodeToSF(WPARAM key, LPARAM flags);
+    static Keyboard::Key VirtualKeyCodeToSF(WPARAM key, LPARAM flags);
 
     ////////////////////////////////////////////////////////////
     /// \brief Check if the current version of the OS supports
diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp
index dd78927a..5831939a 100644
--- a/src/SFML/Window/Window.cpp
+++ b/src/SFML/Window/Window.cpp
@@ -38,6 +38,7 @@
 namespace
 {
     const sf::Window* fullscreenWindow = NULL;
+    const sf::Window* mouseFocusWindow = NULL;
 }
 
 
@@ -249,6 +250,13 @@ void Window::SetCursorPosition(unsigned int x, unsigned int y)
 }
 
 
+////////////////////////////////////////////////////////////
+Vector2i Window::GetCursorPosition() const
+{
+    return myWindow ? myWindow->GetCursorPosition() : Vector2i(0, 0);
+}
+
+
 ////////////////////////////////////////////////////////////
 void Window::SetPosition(int x, int y)
 {
@@ -340,13 +348,6 @@ void Window::Display()
 }
 
 
-////////////////////////////////////////////////////////////
-const Input& Window::GetInput() const
-{
-    return myInput;
-}
-
-
 ////////////////////////////////////////////////////////////
 void Window::SetFramerateLimit(unsigned int limit)
 {
@@ -376,6 +377,13 @@ WindowHandle Window::GetSystemHandle() const
 }
 
 
+////////////////////////////////////////////////////////////
+const Window* Window::GetMouseFocusWindow()
+{
+    return mouseFocusWindow;
+}
+
+
 ////////////////////////////////////////////////////////////
 void Window::OnCreate()
 {
@@ -393,13 +401,20 @@ void Window::OnResize()
 ////////////////////////////////////////////////////////////
 bool Window::FilterEvent(const Event& event)
 {
-    // Notify the input object
-    myInput.OnEvent(event);
-
     // Notify resize events to the derived class
     if (event.Type == Event::Resized)
         OnResize();
 
+    // Watch mouse move/left events to track the window which is under the cursor
+    if (event.Type == Event::MouseMoved)
+    {
+        mouseFocusWindow = this;
+    }
+    else if ((event.Type == Event::MouseLeft) && (mouseFocusWindow == this))
+    {
+        mouseFocusWindow = NULL;
+    }
+
     return true;
 }
 
diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp
index 6f448c5f..51f73b33 100644
--- a/src/SFML/Window/WindowImpl.cpp
+++ b/src/SFML/Window/WindowImpl.cpp
@@ -27,6 +27,7 @@
 ////////////////////////////////////////////////////////////
 #include <SFML/Window/WindowImpl.hpp>
 #include <SFML/Window/Event.hpp>
+#include <SFML/Window/JoystickManager.hpp>
 #include <algorithm>
 #include <cmath>
 
@@ -72,12 +73,10 @@ myWidth       (0),
 myHeight      (0),
 myJoyThreshold(0.1f)
 {
-    // Initialize the joysticks
-    for (unsigned int i = 0; i < Joy::Count; ++i)
-    {
-        myJoysticks[i].Initialize(i);
-        myJoyStates[i] = myJoysticks[i].UpdateState();
-    }
+    // Get the initial joystick states
+    JoystickManager::GetInstance().Update();
+    for (unsigned int i = 0; i < Joystick::Count; ++i)
+        myJoyStates[i] = JoystickManager::GetInstance().GetState(i);
 }
 
 
@@ -115,21 +114,25 @@ bool WindowImpl::PopEvent(Event& event, bool block)
     // If the event queue is empty, let's first check if new events are available from the OS
     if (myEvents.empty())
     {
-        // Special handling of joystick events (we must use polling)
-        ProcessJoystickEvents();
-
-        if (block)
+        if (!block)
         {
-            // If we are blocking, loop until we actually received a SFML event
-            // (there may be OS events that make ProcessEvents(true) return, but
-            // which don't translate to SFML events)
-            while (myEvents.empty())
-                ProcessEvents(true);
+            // Non-blocking mode: process events and continue
+            ProcessJoystickEvents();
+            ProcessEvents();
         }
         else
         {
-            // If we are not blocking, just process the pending events
-            ProcessEvents(false);
+            // Blocking mode: process events until one is triggered
+
+            // Here we use a manual wait loop instead of the optimized
+            // wait-event provided by the OS, so that we don't skip joystick
+            // events (which require polling)
+            while (myEvents.empty())
+            {
+                ProcessJoystickEvents();
+                ProcessEvents();
+                Sleep(10);
+            }
         }
     }
 
@@ -156,45 +159,62 @@ void WindowImpl::PushEvent(const Event& event)
 ////////////////////////////////////////////////////////////
 void WindowImpl::ProcessJoystickEvents()
 {
-    for (unsigned int i = 0; i < Joy::Count; ++i)
+    // First update the global joystick states
+    JoystickManager::GetInstance().Update();
+
+    for (unsigned int i = 0; i < Joystick::Count; ++i)
     {
         // Copy the previous state of the joystick and get the new one
         JoystickState previousState = myJoyStates[i];
-        myJoyStates[i] = myJoysticks[i].UpdateState();
+        myJoyStates[i] = JoystickManager::GetInstance().GetState(i);
+        JoystickCaps caps = JoystickManager::GetInstance().GetCapabilities(i);
 
-        // Axis
-        for (unsigned int j = 0; j < Joy::AxisCount; ++j)
+        // Connection state
+        bool connected = myJoyStates[i].Connected;
+        if (previousState.Connected ^ connected)
         {
-            Joy::Axis axis = static_cast<Joy::Axis>(j);
-            if (myJoysticks[i].HasAxis(axis))
-            {
-                float prevPos = previousState.Axis[axis];
-                float currPos = myJoyStates[i].Axis[axis];
-                if (fabs(currPos - prevPos) >= myJoyThreshold)
-                {
-                    Event event;
-                    event.Type               = Event::JoyMoved;
-                    event.JoyMove.JoystickId = i;
-                    event.JoyMove.Axis       = axis;
-                    event.JoyMove.Position   = currPos;
-                    PushEvent(event);
-                }
-            }
+            Event event;
+            event.Type = connected ? Event::JoystickConnected : Event::JoystickDisconnected;
+            event.JoystickButton.JoystickId = i;
+            PushEvent(event);
         }
 
-        // Buttons
-        for (unsigned int j = 0; j < myJoysticks[i].GetButtonsCount(); ++j)
+        if (connected)
         {
-            bool prevPressed = previousState.Buttons[j];
-            bool currPressed = myJoyStates[i].Buttons[j];
-
-            if ((!prevPressed && currPressed) || (prevPressed && !currPressed))
+            // Axes
+            for (unsigned int j = 0; j < Joystick::AxisCount; ++j)
             {
-                Event event;
-                event.Type                 = currPressed ? Event::JoyButtonPressed : Event::JoyButtonReleased;
-                event.JoyButton.JoystickId = i;
-                event.JoyButton.Button     = j;
-                PushEvent(event);
+                if (caps.Axes[j])
+                {
+                    Joystick::Axis axis = static_cast<Joystick::Axis>(j);
+                    float prevPos = previousState.Axes[axis];
+                    float currPos = myJoyStates[i].Axes[axis];
+                    if (fabs(currPos - prevPos) >= myJoyThreshold)
+                    {
+                        Event event;
+                        event.Type = Event::JoystickMoved;
+                        event.JoystickMove.JoystickId = i;
+                        event.JoystickMove.Axis = axis;
+                        event.JoystickMove.Position = currPos;
+                        PushEvent(event);
+                    }
+                }
+            }
+
+            // Buttons
+            for (unsigned int j = 0; j < caps.ButtonCount; ++j)
+            {
+                bool prevPressed = previousState.Buttons[j];
+                bool currPressed = myJoyStates[i].Buttons[j];
+
+                if (prevPressed ^ currPressed)
+                {
+                    Event event;
+                    event.Type = currPressed ? Event::JoystickButtonPressed : Event::JoystickButtonReleased;
+                    event.JoystickButton.JoystickId = i;
+                    event.JoystickButton.Button = j;
+                    PushEvent(event);
+                }
             }
         }
     }
diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp
index 104f671f..8323795d 100644
--- a/src/SFML/Window/WindowImpl.hpp
+++ b/src/SFML/Window/WindowImpl.hpp
@@ -32,6 +32,7 @@
 #include <SFML/System/NonCopyable.hpp>
 #include <SFML/Window/Event.hpp>
 #include <SFML/Window/Joystick.hpp>
+#include <SFML/Window/JoystickImpl.hpp>
 #include <SFML/Window/VideoMode.hpp>
 #include <SFML/Window/WindowHandle.hpp>
 #include <queue>
@@ -149,6 +150,14 @@ public :
     ////////////////////////////////////////////////////////////
     virtual void SetCursorPosition(unsigned int x, unsigned int y) = 0;
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the position of the mouse cursor
+    ///
+    /// \return Current mouse cursor position, relative to the window
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Vector2i GetCursorPosition() const = 0;
+
     ////////////////////////////////////////////////////////////
     /// \brief Change the position of the window on screen
     ///
@@ -238,18 +247,15 @@ private :
     ////////////////////////////////////////////////////////////
     /// \brief Process incoming events from the operating system
     ///
-    /// \param block Use true to block the thread until an event arrives
-    ///
     ////////////////////////////////////////////////////////////
-    virtual void ProcessEvents(bool block) = 0;
+    virtual void ProcessEvents() = 0;
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    std::queue<Event> myEvents;                ///< Queue of available events
-    Joystick          myJoysticks[Joy::Count]; ///< Joysticks to observe
-    JoystickState     myJoyStates[Joy::Count]; ///< Current states of the joysticks
-    float             myJoyThreshold;          ///< Joystick threshold (minimum motion for MOVE event to be generated)
+    std::queue<Event> myEvents;                     ///< Queue of available events
+    JoystickState     myJoyStates[Joystick::Count]; ///< Previous state of the joysticks
+    float             myJoyThreshold;               ///< Joystick threshold (minimum motion for MOVE event to be generated)
 };
 
 } // namespace priv