Updated Keyboard and Mouse handling. Mouse now uses XQueryPointer. Keyboard relies on X11 events. Still missing mouse delta support.

This commit is contained in:
the_fiddler 2007-09-26 11:58:55 +00:00
parent d16f2ce71b
commit 78b8f274ee
4 changed files with 148 additions and 58 deletions

View file

@ -11,6 +11,7 @@ using System.Runtime.InteropServices;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection; using System.Reflection;
using OpenTK.OpenGL; using OpenTK.OpenGL;
using OpenTK.Input;
//using OpenTK.OpenGL; //using OpenTK.OpenGL;
@ -27,6 +28,7 @@ namespace OpenTK.Platform.X11
private X11GLContext glContext; private X11GLContext glContext;
private WindowInfo window = new WindowInfo(); private WindowInfo window = new WindowInfo();
private DisplayMode mode = new DisplayMode(); private DisplayMode mode = new DisplayMode();
X11Input driver;
// Number of pending events. // Number of pending events.
private int pending = 0; private int pending = 0;
@ -36,8 +38,7 @@ namespace OpenTK.Platform.X11
// C# ResizeEventArgs // C# ResizeEventArgs
private ResizeEventArgs resizeEventArgs = new ResizeEventArgs(); private ResizeEventArgs resizeEventArgs = new ResizeEventArgs();
// Low level X11 resize request // Used for event loop.
// Event used for event loop.
private XEvent e = new XEvent(); private XEvent e = new XEvent();
private bool disposed; private bool disposed;
@ -82,7 +83,7 @@ namespace OpenTK.Platform.X11
Functions.XNextEvent(window.Display, ref e); Functions.XNextEvent(window.Display, ref e);
Debug.Print("Event: {0} ({1} pending)", e.type, pending); //Debug.Print("Event: {0} ({1} pending)", e.type, pending);
// Respond to the event e // Respond to the event e
switch (e.type) switch (e.type)
@ -90,7 +91,7 @@ namespace OpenTK.Platform.X11
case XEventName.ReparentNotify: case XEventName.ReparentNotify:
// TODO: Is there a more suitable place to raise the Create event? // TODO: Is there a more suitable place to raise the Create event?
// ReparentNotify seems to be the first event raised on window creation. // ReparentNotify seems to be the first event raised on window creation.
this.OnCreate(EventArgs.Empty); //this.OnCreate(EventArgs.Empty);
break; break;
@ -134,8 +135,9 @@ namespace OpenTK.Platform.X11
case XEventName.MotionNotify: case XEventName.MotionNotify:
case XEventName.ButtonPress: case XEventName.ButtonPress:
case XEventName.ButtonRelease: case XEventName.ButtonRelease:
Functions.XPutBackEvent(window.Display, ref e); //Functions.XPutBackEvent(window.Display, ref e);
return; driver.ProcessEvent(ref e);
break;
default: default:
Debug.WriteLine(String.Format("{0} event was not handled", e.type)); Debug.WriteLine(String.Format("{0} event was not handled", e.type));
@ -215,6 +217,49 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region public string Text
public string Title
{
get
{
return String.Empty;
}
set
{
}
}
#endregion
#region public bool Visible
public bool Visible
{
get
{
return true;
}
set
{
}
}
#endregion
#region public IInputDriver InputDriver
public IInputDriver InputDriver
{
get
{
return driver;
}
}
#endregion
#region public IWindowInfo WindowInfo #region public IWindowInfo WindowInfo
public IWindowInfo WindowInfo public IWindowInfo WindowInfo
@ -273,9 +318,9 @@ namespace OpenTK.Platform.X11
API.CreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/); API.CreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/);
window.EventMask = window.EventMask =
EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask | EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeyReleaseMask | EventMask.KeyPressMask;/* |
EventMask.PointerMotionMask | EventMask.PointerMotionHintMask | EventMask.PointerMotionMask | /* Bad! EventMask.PointerMotionHintMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask; EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;*/
attributes.event_mask = (IntPtr)window.EventMask; attributes.event_mask = (IntPtr)window.EventMask;
uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask | uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
@ -317,6 +362,8 @@ namespace OpenTK.Platform.X11
API.MapRaised(window.Display, window.Handle); API.MapRaised(window.Display, window.Handle);
driver = new X11Input(window);
GL.LoadAll(); GL.LoadAll();
Glu.LoadAll(); Glu.LoadAll();

View file

@ -38,7 +38,7 @@ namespace OpenTK.Platform.X11
/// the device specific drivers (Keyboard, Mouse, Hid). /// the device specific drivers (Keyboard, Mouse, Hid).
/// </summary> /// </summary>
/// <param name="attach">The window which the InputDriver will attach itself on.</param> /// <param name="attach">The window which the InputDriver will attach itself on.</param>
public X11Input(X11.WindowInfo attach) public X11Input(IWindowInfo attach)
{ {
Debug.WriteLine("Initalizing X11 input driver."); Debug.WriteLine("Initalizing X11 input driver.");
Debug.Indent(); Debug.Indent();
@ -75,14 +75,14 @@ namespace OpenTK.Platform.X11
Functions.XMapWindow(window.Display, window.Handle); Functions.XMapWindow(window.Display, window.Handle);
*/ */
window = attach; //window = attach;
keyboardDriver = new X11Keyboard(window); keyboardDriver = new X11Keyboard(window);
mouseDriver = new X11Mouse(window); mouseDriver = new X11Mouse(window);
Thread pollingThread = new Thread(InternalPoll); //Thread pollingThread = new Thread(InternalPoll);
//pollingThread.Priority = ThreadPriority.BelowNormal; //pollingThread.Priority = ThreadPriority.BelowNormal;
pollingThread.IsBackground = true; //pollingThread.IsBackground = true;
pollingThread.Start(); //pollingThread.Start();
Debug.Unindent(); Debug.Unindent();
} }
@ -93,39 +93,39 @@ namespace OpenTK.Platform.X11
{ {
try try
{ {
while (!disposed) //while (!disposed)
{ //{
Functions.XMaskEvent(window.Display, // Functions.XMaskEvent(window.Display,
EventMask.PointerMotionMask | EventMask.PointerMotionHintMask | // EventMask.PointerMotionMask | EventMask.PointerMotionHintMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | // EventMask.ButtonPressMask | EventMask.ButtonReleaseMask |
EventMask.KeyPressMask | EventMask.KeyReleaseMask | // EventMask.KeyPressMask | EventMask.KeyReleaseMask |
EventMask.StructureNotifyMask, ref e); // EventMask.StructureNotifyMask, ref e);
if (disposed || disposing) // if (disposed || disposing)
return; // return;
switch (e.type) // switch (e.type)
{ // {
case XEventName.KeyPress: // case XEventName.KeyPress:
case XEventName.KeyRelease: // case XEventName.KeyRelease:
keyboardDriver.ProcessKeyboardEvent(ref e.KeyEvent); // keyboardDriver.ProcessKeyboardEvent(ref e.KeyEvent);
break; // break;
case XEventName.ButtonPress: // case XEventName.ButtonPress:
case XEventName.ButtonRelease: // case XEventName.ButtonRelease:
mouseDriver.ProcessButton(ref e.ButtonEvent); // mouseDriver.ProcessButton(ref e.ButtonEvent);
break; // break;
case XEventName.MotionNotify: // case XEventName.MotionNotify:
mouseDriver.ProcessMotion(ref e.MotionEvent); // mouseDriver.ProcessMotion(ref e.MotionEvent);
break; // break;
case XEventName.DestroyNotify: // case XEventName.DestroyNotify:
Functions.XPutBackEvent(window.Display, ref e); // Functions.XPutBackEvent(window.Display, ref e);
//pollingThread.Abort(); // //pollingThread.Abort();
return; // return;
} // }
} //}
} }
catch (ThreadAbortException expt) catch (ThreadAbortException expt)
{ {
@ -135,6 +135,29 @@ namespace OpenTK.Platform.X11
} }
} }
internal void ProcessEvent(ref XEvent e)
{
switch (e.type)
{
case XEventName.KeyPress:
case XEventName.KeyRelease:
//Debug.Print("Keyboard press");
keyboardDriver.ProcessKeyboardEvent(ref e.KeyEvent);
break;
case XEventName.ButtonPress:
case XEventName.ButtonRelease:
//Debug.Print("Button");
mouseDriver.ProcessButton(ref e.ButtonEvent);
break;
case XEventName.MotionNotify:
//Debug.Print("Mouse move");
mouseDriver.ProcessMotion(ref e.MotionEvent);
break;
}
}
#region --- IInputDriver Members --- #region --- IInputDriver Members ---
#region public IList<IInputDevice> InputDevices #region public IList<IInputDevice> InputDevices
@ -148,7 +171,7 @@ namespace OpenTK.Platform.X11
#region public IList<Keyboard> Keyboard #region public IList<Keyboard> Keyboard
public IList<Keyboard> Keyboard public IList<KeyboardDevice> Keyboard
{ {
get { return keyboardDriver.Keyboard; } get { return keyboardDriver.Keyboard; }
} }
@ -157,7 +180,7 @@ namespace OpenTK.Platform.X11
#region public IList<Mouse> Mouse #region public IList<Mouse> Mouse
public IList<Mouse> Mouse public IList<MouseDevice> Mouse
{ {
get { return mouseDriver.Mouse; } get { return mouseDriver.Mouse; }
} }
@ -172,6 +195,7 @@ namespace OpenTK.Platform.X11
/// </summary> /// </summary>
public void Poll() public void Poll()
{ {
mouseDriver.Poll();
} }
#endregion #endregion

View file

@ -27,7 +27,7 @@ namespace OpenTK.Platform.X11
/// </summary> /// </summary>
WindowInfo window; WindowInfo window;
List<Keyboard> keyboards = new List<Keyboard>(); List<KeyboardDevice> keyboards = new List<KeyboardDevice>();
static Dictionary<XKey, Key> keymap = new Dictionary<XKey, Key>((int)Key.MaxKeys); static Dictionary<XKey, Key> keymap = new Dictionary<XKey, Key>((int)Key.MaxKeys);
/// <summary> /// <summary>
/// The smallest and largest KeyCode supported by the X server. Queried through API.DisplayKeycodes() /// The smallest and largest KeyCode supported by the X server. Queried through API.DisplayKeycodes()
@ -186,7 +186,7 @@ namespace OpenTK.Platform.X11
API.Free(keysym_ptr); API.Free(keysym_ptr);
Keyboard kb = new Keyboard(); KeyboardDevice kb = new KeyboardDevice();
kb.Description = "Default X11 keyboard"; kb.Description = "Default X11 keyboard";
kb.NumberOfKeys = lastKeyCode - firstKeyCode + 1; kb.NumberOfKeys = lastKeyCode - firstKeyCode + 1;
kb.DeviceID = IntPtr.Zero; kb.DeviceID = IntPtr.Zero;
@ -214,7 +214,7 @@ namespace OpenTK.Platform.X11
//Debug.Print("Key down: {0}", e.ToString()); //Debug.Print("Key down: {0}", e.ToString());
int index = keyboards.FindIndex(delegate(Keyboard kb) int index = keyboards.FindIndex(delegate(KeyboardDevice kb)
{ {
return kb.DeviceID == IntPtr.Zero; return kb.DeviceID == IntPtr.Zero;
}); });
@ -243,7 +243,7 @@ namespace OpenTK.Platform.X11
#region --- IKeyboardDriver Members --- #region --- IKeyboardDriver Members ---
public IList<Keyboard> Keyboard public IList<KeyboardDevice> Keyboard
{ {
get { return keyboards; } get { return keyboards; }
} }

View file

@ -18,7 +18,7 @@ namespace OpenTK.Platform.X11
internal sealed class X11Mouse : IMouseDriver internal sealed class X11Mouse : IMouseDriver
{ {
WindowInfo window; WindowInfo window;
List<Mouse> mice = new List<Mouse>(); List<MouseDevice> mice = new List<MouseDevice>();
#region Constructor #region Constructor
@ -28,7 +28,7 @@ namespace OpenTK.Platform.X11
// Just create one mouse now. // Just create one mouse now.
// TODO: support for multiple devices through evdev. // TODO: support for multiple devices through evdev.
Mouse m = new Mouse(); MouseDevice m = new MouseDevice();
m.Description = "Default X11 mouse"; m.Description = "Default X11 mouse";
m.DeviceID = IntPtr.Zero; m.DeviceID = IntPtr.Zero;
m.NumberOfButtons = 5; m.NumberOfButtons = 5;
@ -40,7 +40,7 @@ namespace OpenTK.Platform.X11
#region --- IMouseDriver Members --- #region --- IMouseDriver Members ---
public IList<Mouse> Mouse public IList<MouseDevice> Mouse
{ {
get { return mice; } get { return mice; }
} }
@ -54,13 +54,14 @@ namespace OpenTK.Platform.X11
/// <returns>True if the event was processed, false otherwise.</returns> /// <returns>True if the event was processed, false otherwise.</returns>
internal bool ProcessButton(ref X11.XButtonEvent e) internal bool ProcessButton(ref X11.XButtonEvent e)
{ {
Mouse m = mice[0]; MouseDevice m = mice[0];
bool pressed = e.type == XEventName.ButtonPress; bool pressed = e.type == XEventName.ButtonPress;
if ((e.state & (int)X11.MouseMask.Button1Mask) != 0) m[OpenTK.Input.MouseButton.Button1] = pressed; //e.
if ((e.state & (int)X11.MouseMask.Button2Mask) != 0) m[OpenTK.Input.MouseButton.Button2] = pressed; if ((e.state & (int)X11.MouseMask.Button1Mask) != 0) m[OpenTK.Input.MouseButton.Left] = pressed;
if ((e.state & (int)X11.MouseMask.Button3Mask) != 0) m[OpenTK.Input.MouseButton.Button3] = pressed; if ((e.state & (int)X11.MouseMask.Button2Mask) != 0) m[OpenTK.Input.MouseButton.Middle] = pressed;
if ((e.state & (int)X11.MouseMask.Button4Mask) != 0) m[OpenTK.Input.MouseButton.Button4] = pressed; if ((e.state & (int)X11.MouseMask.Button3Mask) != 0) m[OpenTK.Input.MouseButton.Right] = pressed;
if ((e.state & (int)X11.MouseMask.Button5Mask) != 0) m[OpenTK.Input.MouseButton.Button5] = pressed; if ((e.state & (int)X11.MouseMask.Button4Mask) != 0) m.Wheel++;
if ((e.state & (int)X11.MouseMask.Button5Mask) != 0) m.Wheel--;
return true; return true;
} }
@ -71,10 +72,28 @@ namespace OpenTK.Platform.X11
/// <returns>True if the event was processed, false otherwise.</returns> /// <returns>True if the event was processed, false otherwise.</returns>
internal bool ProcessMotion(ref X11.XMotionEvent e) internal bool ProcessMotion(ref X11.XMotionEvent e)
{ {
Mouse m = mice[0]; MouseDevice m = mice[0];
m.X = e.x; m.X = e.x;
m.Y = e.y; m.Y = e.y;
return true; return true;
} }
/// <summary>
/// Queries the mouse pos.
/// </summary>
internal void Poll()
{
IntPtr root, child;
int state, root_x, root_y, win_x, win_y;
MouseDevice m = mice[0];
Functions.XQueryPointer(window.Display, window.Handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out state);
m[OpenTK.Input.MouseButton.Left] = (state & (int)X11.MouseMask.Button1Mask) != 0;
m[OpenTK.Input.MouseButton.Middle] = (state & (int)X11.MouseMask.Button2Mask) != 0;
m[OpenTK.Input.MouseButton.Right] = (state & (int)X11.MouseMask.Button3Mask) != 0;
m.Wheel += (state & (int)X11.MouseMask.Button4Mask);
m.Wheel -= (state & (int)X11.MouseMask.Button5Mask);
m.X = root_x;
m.Y = root_y;
}
} }
} }