From d81bedf5f8a5f009818daa9c91b698d44036afd5 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Fri, 4 Oct 2013 10:02:19 +0200 Subject: [PATCH] Moved all input processing to Sdl2InputDriver This reduces the duplication of code between Sdl2NativeWindow and Sdl2InputDriver. Sdl2InputDriver is now solely responsible for handling input. --- .../OpenTK/Platform/SDL2/Sdl2InputDriver.cs | 63 +++++++++++++++++-- Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs | 32 +++++++++- Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs | 29 ++++++++- .../OpenTK/Platform/SDL2/Sdl2NativeWindow.cs | 58 +++++++---------- .../OpenTK/Platform/SDL2/sdl2-cs/src/SDL2.cs | 14 +++++ 5 files changed, 152 insertions(+), 44 deletions(-) diff --git a/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs b/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs index eb67e4c0..16c8c354 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs @@ -34,25 +34,33 @@ using OpenTK.Input; namespace OpenTK.Platform.SDL2 { - class Sdl2InputDriver : IInputDriver2 + class Sdl2InputDriver : IInputDriver2, IInputDriver { readonly static Dictionary DriverHandles = new Dictionary(); + readonly IntPtr driver_handle; + readonly Sdl2Keyboard keyboard_driver = new Sdl2Keyboard(); readonly Sdl2Mouse mouse_driver = new Sdl2Mouse(); + readonly Sdl2JoystickDriver joystick_driver = new Sdl2JoystickDriver(); + readonly SDL.SDL_EventFilter EventFilterDelegate = FilterInputEvents; + readonly IntPtr EventFilterPointer; static int count; bool disposed; public Sdl2InputDriver() { + EventFilterPointer = Marshal.GetFunctionPointerForDelegate( + EventFilterDelegate); + lock (SDL.Sync) { - IntPtr driver_handle = new IntPtr(count++); + driver_handle = new IntPtr(count++); DriverHandles.Add(driver_handle, this); - SDL.SDL_AddEventWatch(EventFilterDelegate, driver_handle); + SDL.SDL_AddEventWatch(EventFilterPointer, driver_handle); } } @@ -99,6 +107,51 @@ namespace OpenTK.Platform.SDL2 #endregion + #region IInputDriver Members + + public void Poll() + { + joystick_driver.Poll(); + } + + #endregion + + #region IJoystickDriver Members + + public IList Joysticks + { + get + { + return joystick_driver.Joysticks; + } + } + + #endregion + + #region IMouseDriver Members + + public IList Mouse + { + get + { + return mouse_driver.Mouse; + } + } + + #endregion + + #region IKeyboardDriver Members + + public IList Keyboard + { + get + { + return keyboard_driver.Keyboard; + } + } + + #endregion + #region IInputDriver2 Members public IMouseDriver2 MouseDriver @@ -136,10 +189,12 @@ namespace OpenTK.Platform.SDL2 if (manual) { Debug.Print("Disposing {0}", GetType()); + joystick_driver.Dispose(); lock (SDL.Sync) { - SDL.SDL_DelEventWatch(EventFilterDelegate, IntPtr.Zero); + SDL.SDL_DelEventWatch(EventFilterPointer, IntPtr.Zero); } + DriverHandles.Remove(driver_handle); } else { diff --git a/Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs b/Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs index 20693083..5bc9c7a7 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2Keyboard.cs @@ -26,18 +26,30 @@ #endregion using System; +using System.Collections.Generic; using OpenTK.Input; namespace OpenTK.Platform.SDL2 { - class Sdl2Keyboard : IKeyboardDriver2 + class Sdl2Keyboard : IKeyboardDriver2, IKeyboardDriver { static readonly Sdl2KeyMap KeyMap = new Sdl2KeyMap(); KeyboardState state; + readonly List keyboards = + new List(); + readonly IList keyboards_readonly; + public Sdl2Keyboard() { state.IsConnected = true; + + keyboards.Add(new KeyboardDevice()); + keyboards[0].Description = "Standard keyboard"; + keyboards[0].NumberOfFunctionKeys = 12; + keyboards[0].NumberOfKeys = 101; + keyboards[0].NumberOfLeds = 3; + keyboards_readonly = keyboards.AsReadOnly(); } #region Private Members @@ -74,9 +86,23 @@ namespace OpenTK.Platform.SDL2 { Key key; bool pressed = e.state != 0; - if (KeyMap.TryGetValue(e.keysym.scancode, out key)) + var scancode = e.keysym.scancode; + if (KeyMap.TryGetValue(scancode, out key)) { - state.SetKeyState(key, (byte)e.keysym.scancode, pressed); + state.SetKeyState(key, (byte)scancode, pressed); + keyboards[0].SetKey(key, (byte)scancode, pressed); + } + } + + #endregion + + #region IKeyboardDriver Members + + public IList Keyboard + { + get + { + return keyboards_readonly; } } diff --git a/Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs b/Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs index b58fefa7..31d70729 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2Mouse.cs @@ -26,18 +26,30 @@ #endregion using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Drawing; using OpenTK.Input; namespace OpenTK.Platform.SDL2 { - class Sdl2Mouse : IMouseDriver2 + class Sdl2Mouse : IMouseDriver2, IMouseDriver { MouseState state; + readonly List mice = + new List(); + readonly IList mice_readonly; + public Sdl2Mouse() { state.IsConnected = true; + + mice.Add(new MouseDevice()); + mice[0].Description = "Standard mouse"; + mice[0].NumberOfButtons = 3; + mice[0].NumberOfWheels = 1; + mice_readonly = mice.AsReadOnly(); } #region Private Members @@ -86,18 +98,33 @@ namespace OpenTK.Platform.SDL2 public void ProcessWheelEvent(SDL.SDL_MouseWheelEvent wheel) { state.WheelPrecise += wheel.y; + mice[0].WheelPrecise += wheel.y; } public void ProcessMouseEvent(SDL.SDL_MouseMotionEvent motion) { state.X += motion.xrel; state.Y += motion.yrel; + mice[0].Position = new Point(motion.x, motion.y); } public void ProcessMouseEvent(SDL.SDL_MouseButtonEvent button) { bool pressed = button.state == SDL.SDL_PRESSED; SetButtonState(TranslateButton(button.button), pressed); + mice[0][TranslateButton(button.button)] = pressed; + } + + #endregion + + #region IMouseDriver Members + + public IList Mouse + { + get + { + return mice_readonly; + } } #endregion diff --git a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs index a20a5cb6..3d5e49a7 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs @@ -53,12 +53,7 @@ namespace OpenTK.Platform.SDL2 Icon icon; string window_title; - KeyboardDevice keyboard = new KeyboardDevice(); - MouseDevice mouse = new MouseDevice(); - IList keyboards = new List(1); - IList mice = new List(1); - - readonly Sdl2JoystickDriver joystick_driver = new Sdl2JoystickDriver(); + readonly IInputDriver input_driver = new Sdl2InputDriver(); readonly SDL.SDL_EventFilter EventFilterDelegate = FilterEvents; @@ -95,18 +90,6 @@ namespace OpenTK.Platform.SDL2 windows.Add(window_id, this); window_title = title; - keyboard.Description = "Standard keyboard"; - keyboard.NumberOfFunctionKeys = 12; - keyboard.NumberOfKeys = 101; - keyboard.NumberOfLeds = 3; - - mouse.Description = "Standard mouse"; - mouse.NumberOfButtons = 3; - mouse.NumberOfWheels = 1; - - keyboards.Add(keyboard); - mice.Add(mouse); - exists = true; } } @@ -220,7 +203,8 @@ namespace OpenTK.Platform.SDL2 } switch (ev.button.button) - { + {/* + case (byte)SDL.SDL_BUTTON_LEFT: window.mouse[MouseButton.Left] = button_pressed; break; @@ -240,6 +224,7 @@ namespace OpenTK.Platform.SDL2 case (byte)SDL.SDL_BUTTON_X2: window.mouse[MouseButton.Button2] = button_pressed; break; + */ } } @@ -247,19 +232,19 @@ namespace OpenTK.Platform.SDL2 { bool key_pressed = ev.key.state == SDL.SDL_PRESSED; var key = ev.key.keysym; - window.keyboard.SetKey(TranslateKey(key.scancode), (uint)key.scancode, key_pressed); + //window.keyboard.SetKey(TranslateKey(key.scancode), (uint)key.scancode, key_pressed); } static void ProcessMotionEvent(Sdl2NativeWindow window, SDL.SDL_Event ev) { float scale = window.ClientSize.Width / (float)window.Size.Width; - window.mouse.Position = new Point( - (int)(ev.motion.x * scale), (int)(ev.motion.y * scale)); + //window.mouse.Position = new Point( + // (int)(ev.motion.x * scale), (int)(ev.motion.y * scale)); } static void ProcessWheelEvent(Sdl2NativeWindow window, SDL.SDL_Event ev) { - window.mouse.Wheel += ev.wheel.y; + //window.mouse.Wheel += ev.wheel.y; } static void ProcessWindowEvent(Sdl2NativeWindow window, SDL.SDL_WindowEvent e) @@ -835,7 +820,7 @@ namespace OpenTK.Platform.SDL2 { get { - return this; + return input_driver; } } @@ -864,7 +849,7 @@ namespace OpenTK.Platform.SDL2 public void Poll() { - joystick_driver.Poll(); + InputDriver.Poll(); } #endregion @@ -875,7 +860,7 @@ namespace OpenTK.Platform.SDL2 { get { - return joystick_driver.Joysticks; + return InputDriver.Joysticks; } } @@ -887,7 +872,7 @@ namespace OpenTK.Platform.SDL2 { get { - return mice; + return InputDriver.Mouse; } } @@ -899,7 +884,7 @@ namespace OpenTK.Platform.SDL2 { get { - return keyboards; + return InputDriver.Keyboard; } } @@ -911,22 +896,23 @@ namespace OpenTK.Platform.SDL2 { if (!disposed) { - if (manual) + lock (sync) { - Debug.Print("Disposing {0}", GetType()); - lock (sync) + if (manual) { + Debug.Print("Disposing {0}", GetType()); + InputDriver.Dispose(); if (Exists) { DestroyWindow(); } } + else + { + Debug.WriteLine("Sdl2NativeWindow leaked, did you forget to call Dispose()?"); + } + disposed = true; } - else - { - Debug.WriteLine("Sdl2NativeWindow leaked, did you forget to call Dispose()?"); - } - disposed = true; } } diff --git a/Source/OpenTK/Platform/SDL2/sdl2-cs/src/SDL2.cs b/Source/OpenTK/Platform/SDL2/sdl2-cs/src/SDL2.cs index ab744a0f..2aff6d97 100644 --- a/Source/OpenTK/Platform/SDL2/sdl2-cs/src/SDL2.cs +++ b/Source/OpenTK/Platform/SDL2/sdl2-cs/src/SDL2.cs @@ -3400,6 +3400,13 @@ namespace OpenTK.Platform.SDL2 IntPtr userdata ); + /* userdata refers to a void* */ + [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] + public static extern void SDL_AddEventWatch( + IntPtr filter, + IntPtr userdata + ); + /* userdata refers to a void* */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void SDL_DelEventWatch( @@ -3407,6 +3414,13 @@ namespace OpenTK.Platform.SDL2 IntPtr userdata ); + /* userdata refers to a void* */ + [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] + public static extern void SDL_DelEventWatch( + IntPtr filter, + IntPtr userdata + ); + /* userdata refers to a void* */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void SDL_FilterEvents(