From 5a55cb5cca41adad3379e87ee72532e3a7b6a61e Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Mon, 30 Sep 2013 12:22:25 +0200 Subject: [PATCH] Implemented SDL2 mouse and keyboard drivers --- Source/OpenTK/Platform/SDL2/Sdl2Factory.cs | 8 +- Source/OpenTK/Platform/SDL2/Sdl2InputBase.cs | 48 +++++++++--- Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs | 26 ++++++- Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs | 77 +++++++++++++++++-- .../OpenTK/Platform/SDL2/Sdl2NativeWindow.cs | 2 +- 5 files changed, 137 insertions(+), 24 deletions(-) diff --git a/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs b/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs index 4ac2eda3..b095796f 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs @@ -33,6 +33,8 @@ namespace OpenTK.Platform.SDL2 { class Sdl2Factory : IPlatformFactory { + readonly IInputDriver2 InputDriver = new Sdl2InputBase(); + public Sdl2Factory() { } @@ -86,17 +88,17 @@ namespace OpenTK.Platform.SDL2 public IKeyboardDriver2 CreateKeyboardDriver() { - return new Sdl2Keyboard(); + return InputDriver.KeyboardDriver; } public IMouseDriver2 CreateMouseDriver() { - return new Sdl2Mouse(); + return InputDriver.MouseDriver; } public IGamePadDriver CreateGamePadDriver() { - return new Sdl2Joystick(); + return InputDriver.GamePadDriver; } #endregion diff --git a/Source/OpenTK/Platform/SDL2/Sdl2InputBase.cs b/Source/OpenTK/Platform/SDL2/Sdl2InputBase.cs index 178b1656..22d5dbea 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2InputBase.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2InputBase.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading; using OpenTK.Input; @@ -34,26 +35,49 @@ namespace OpenTK.Platform.SDL2 { class Sdl2InputBase : IInputDriver2 { - Sdl2WindowInfo window; - readonly Thread thread; - readonly AutoResetEvent ready = new AutoResetEvent(false); + readonly Sdl2Keyboard keyboard_driver = new Sdl2Keyboard(); + readonly Sdl2Mouse mouse_driver = new Sdl2Mouse(); + readonly SDL.SDL_EventFilter EventFilterDelegate; public Sdl2InputBase() { - window = new Sdl2WindowInfo( - SDL.SDL_CreateWindow("Hidden Input Window", 0, 0, 1, 1, - SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN), - null); + EventFilterDelegate = FilterInputEvents; + SDL.SDL_AddEventWatch(EventFilterDelegate, IntPtr.Zero); } #region Private Members - void ProcessEvents() + int FilterInputEvents(IntPtr user_data, IntPtr e) { - SDL.SDL_Event e; - while (SDL.SDL_WaitEvent(out e) != 0) + SDL.SDL_Event ev; + unsafe { + ev = *(SDL.SDL_Event*)e; } + + var type = (SDL.SDL_EventType)Marshal.ReadInt32(e); + switch (type) + { + case SDL.SDL_EventType.SDL_KEYDOWN: + case SDL.SDL_EventType.SDL_KEYUP: + keyboard_driver.ProcessKeyboardEvent(ev.key); + break; + + case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN: + case SDL.SDL_EventType.SDL_MOUSEBUTTONUP: + mouse_driver.ProcessMouseEvent(ev.button); + break; + + case SDL.SDL_EventType.SDL_MOUSEMOTION: + mouse_driver.ProcessMouseEvent(ev.motion); + break; + + case SDL.SDL_EventType.SDL_MOUSEWHEEL: + mouse_driver.ProcessWheelEvent(ev.wheel); + break; + } + + return 0; } #endregion @@ -64,7 +88,7 @@ namespace OpenTK.Platform.SDL2 { get { - throw new NotImplementedException(); + return mouse_driver; } } @@ -72,7 +96,7 @@ namespace OpenTK.Platform.SDL2 { get { - throw new NotImplementedException(); + return keyboard_driver; } } diff --git a/Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs b/Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs index e81ac048..8d2919dc 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs @@ -32,25 +32,45 @@ namespace OpenTK.Platform.SDL2 { class Sdl2Keyboard : IKeyboardDriver2 { + static readonly Sdl2KeyMap KeyMap = new Sdl2KeyMap(); + KeyboardState state; + public Sdl2Keyboard() { + state.IsConnected = true; } + #region Public Members + + public void ProcessKeyboardEvent(SDL.SDL_KeyboardEvent e) + { + Key key; + if (KeyMap.TryGetValue(e.keysym.sym, out key)) + { + state.SetKeyState(key, (byte)e.keysym.scancode, e.state != 0); + } + } + + #endregion + #region IKeyboardDriver2 Members public KeyboardState GetState() { - return new KeyboardState(); + return state; } public KeyboardState GetState(int index) { - return new KeyboardState(); + if (index == 0) + return state; + else + return new KeyboardState(); } public string GetDeviceName(int index) { - return String.Empty; + return "SDL2 Default Keyboard"; } #endregion diff --git a/Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs b/Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs index 882b0e2c..b58fefa7 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs @@ -26,33 +26,100 @@ #endregion using System; +using System.Diagnostics; using OpenTK.Input; namespace OpenTK.Platform.SDL2 { class Sdl2Mouse : IMouseDriver2 { + MouseState state; + public Sdl2Mouse() { + state.IsConnected = true; } + #region Private Members + + MouseButton TranslateButton(uint button) + { + switch (button) + { + case SDL.SDL_BUTTON_LEFT: + return MouseButton.Left; + + case SDL.SDL_BUTTON_RIGHT: + return MouseButton.Right; + + case SDL.SDL_BUTTON_MIDDLE: + return MouseButton.Middle; + + case SDL.SDL_BUTTON_X1: + return MouseButton.Button1; + + case SDL.SDL_BUTTON_X2: + return MouseButton.Button2; + + default: + Debug.Print("SDL2 unknown button {0}", button); + return MouseButton.Left; + } + } + + void SetButtonState(MouseButton button, bool pressed) + { + if (pressed) + { + state.EnableBit((int)button); + } + else + { + state.DisableBit((int)button); + } + } + + #endregion + + #region Public Members + + public void ProcessWheelEvent(SDL.SDL_MouseWheelEvent wheel) + { + state.WheelPrecise += wheel.y; + } + + public void ProcessMouseEvent(SDL.SDL_MouseMotionEvent motion) + { + state.X += motion.xrel; + state.Y += motion.yrel; + } + + public void ProcessMouseEvent(SDL.SDL_MouseButtonEvent button) + { + bool pressed = button.state == SDL.SDL_PRESSED; + SetButtonState(TranslateButton(button.button), pressed); + } + + #endregion + #region IMouseDriver2 Members public MouseState GetState() { - int x, y; - uint b = SDL.SDL_GetMouseState(out x, out y); - return new MouseState(); + return state; } public MouseState GetState(int index) { - return new MouseState(); + if (index == 0) + return state; + else + return new MouseState(); } public void SetPosition(double x, double y) { - //SDL2.mouse + SDL.SDL_WarpMouseInWindow(IntPtr.Zero, (int)x, (int)y); } #endregion diff --git a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs index bcd5dd18..e58e94c8 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs @@ -65,7 +65,7 @@ namespace OpenTK.Platform.SDL2 static Sdl2NativeWindow() { // store the filter delegate to protect it from the GC - SDL.SDL_SetEventFilter(EventFilterDelegate, IntPtr.Zero); + SDL.SDL_AddEventWatch(EventFilterDelegate, IntPtr.Zero); } public Sdl2NativeWindow(int x, int y, int width, int height,