Implemented SDL2 mouse and keyboard drivers

This commit is contained in:
Stefanos A. 2013-09-30 12:22:25 +02:00
parent fcc9049d18
commit 5a55cb5cca
5 changed files with 137 additions and 24 deletions

View file

@ -33,6 +33,8 @@ namespace OpenTK.Platform.SDL2
{ {
class Sdl2Factory : IPlatformFactory class Sdl2Factory : IPlatformFactory
{ {
readonly IInputDriver2 InputDriver = new Sdl2InputBase();
public Sdl2Factory() public Sdl2Factory()
{ {
} }
@ -86,17 +88,17 @@ namespace OpenTK.Platform.SDL2
public IKeyboardDriver2 CreateKeyboardDriver() public IKeyboardDriver2 CreateKeyboardDriver()
{ {
return new Sdl2Keyboard(); return InputDriver.KeyboardDriver;
} }
public IMouseDriver2 CreateMouseDriver() public IMouseDriver2 CreateMouseDriver()
{ {
return new Sdl2Mouse(); return InputDriver.MouseDriver;
} }
public IGamePadDriver CreateGamePadDriver() public IGamePadDriver CreateGamePadDriver()
{ {
return new Sdl2Joystick(); return InputDriver.GamePadDriver;
} }
#endregion #endregion

View file

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using OpenTK.Input; using OpenTK.Input;
@ -34,26 +35,49 @@ namespace OpenTK.Platform.SDL2
{ {
class Sdl2InputBase : IInputDriver2 class Sdl2InputBase : IInputDriver2
{ {
Sdl2WindowInfo window; readonly Sdl2Keyboard keyboard_driver = new Sdl2Keyboard();
readonly Thread thread; readonly Sdl2Mouse mouse_driver = new Sdl2Mouse();
readonly AutoResetEvent ready = new AutoResetEvent(false); readonly SDL.SDL_EventFilter EventFilterDelegate;
public Sdl2InputBase() public Sdl2InputBase()
{ {
window = new Sdl2WindowInfo( EventFilterDelegate = FilterInputEvents;
SDL.SDL_CreateWindow("Hidden Input Window", 0, 0, 1, 1, SDL.SDL_AddEventWatch(EventFilterDelegate, IntPtr.Zero);
SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN),
null);
} }
#region Private Members #region Private Members
void ProcessEvents() int FilterInputEvents(IntPtr user_data, IntPtr e)
{ {
SDL.SDL_Event e; SDL.SDL_Event ev;
while (SDL.SDL_WaitEvent(out e) != 0) 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 #endregion
@ -64,7 +88,7 @@ namespace OpenTK.Platform.SDL2
{ {
get get
{ {
throw new NotImplementedException(); return mouse_driver;
} }
} }
@ -72,7 +96,7 @@ namespace OpenTK.Platform.SDL2
{ {
get get
{ {
throw new NotImplementedException(); return keyboard_driver;
} }
} }

View file

@ -32,25 +32,45 @@ namespace OpenTK.Platform.SDL2
{ {
class Sdl2Keyboard : IKeyboardDriver2 class Sdl2Keyboard : IKeyboardDriver2
{ {
static readonly Sdl2KeyMap KeyMap = new Sdl2KeyMap();
KeyboardState state;
public Sdl2Keyboard() 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 #region IKeyboardDriver2 Members
public KeyboardState GetState() public KeyboardState GetState()
{ {
return new KeyboardState(); return state;
} }
public KeyboardState GetState(int index) public KeyboardState GetState(int index)
{ {
return new KeyboardState(); if (index == 0)
return state;
else
return new KeyboardState();
} }
public string GetDeviceName(int index) public string GetDeviceName(int index)
{ {
return String.Empty; return "SDL2 Default Keyboard";
} }
#endregion #endregion

View file

@ -26,33 +26,100 @@
#endregion #endregion
using System; using System;
using System.Diagnostics;
using OpenTK.Input; using OpenTK.Input;
namespace OpenTK.Platform.SDL2 namespace OpenTK.Platform.SDL2
{ {
class Sdl2Mouse : IMouseDriver2 class Sdl2Mouse : IMouseDriver2
{ {
MouseState state;
public Sdl2Mouse() 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 #region IMouseDriver2 Members
public MouseState GetState() public MouseState GetState()
{ {
int x, y; return state;
uint b = SDL.SDL_GetMouseState(out x, out y);
return new MouseState();
} }
public MouseState GetState(int index) public MouseState GetState(int index)
{ {
return new MouseState(); if (index == 0)
return state;
else
return new MouseState();
} }
public void SetPosition(double x, double y) public void SetPosition(double x, double y)
{ {
//SDL2.mouse SDL.SDL_WarpMouseInWindow(IntPtr.Zero, (int)x, (int)y);
} }
#endregion #endregion

View file

@ -65,7 +65,7 @@ namespace OpenTK.Platform.SDL2
static Sdl2NativeWindow() static Sdl2NativeWindow()
{ {
// store the filter delegate to protect it from the GC // 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, public Sdl2NativeWindow(int x, int y, int width, int height,