2007-08-10 09:27:13 +00:00
|
|
|
|
#region --- License ---
|
|
|
|
|
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
|
|
|
|
* See license.txt for license info
|
|
|
|
|
*/
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
using System;
|
2007-08-05 09:03:22 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
2008-02-01 23:28:23 +00:00
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Runtime.InteropServices;
|
2007-08-05 09:03:22 +00:00
|
|
|
|
|
|
|
|
|
using OpenTK.Input;
|
|
|
|
|
|
|
|
|
|
namespace OpenTK.Platform.X11
|
|
|
|
|
{
|
2007-08-05 13:42:31 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Drives the InputDriver on X11.
|
|
|
|
|
/// This class supports OpenTK, and is not intended for users of OpenTK.
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal sealed class X11Input : IInputDriver
|
2007-08-05 09:03:22 +00:00
|
|
|
|
{
|
2008-03-01 13:15:31 +00:00
|
|
|
|
//X11WindowInfo window;
|
2008-02-01 23:28:23 +00:00
|
|
|
|
KeyboardDevice keyboard = new KeyboardDevice();
|
|
|
|
|
MouseDevice mouse = new MouseDevice();
|
|
|
|
|
List<KeyboardDevice> dummy_keyboard_list = new List<KeyboardDevice>(1);
|
|
|
|
|
List<MouseDevice> dummy_mice_list = new List<MouseDevice>(1);
|
2007-08-05 18:26:14 +00:00
|
|
|
|
|
2008-02-01 23:28:23 +00:00
|
|
|
|
X11KeyMap keymap = new X11KeyMap();
|
|
|
|
|
int firstKeyCode, lastKeyCode; // The smallest and largest KeyCode supported by the X server.
|
|
|
|
|
int keysyms_per_keycode; // The number of KeySyms for each KeyCode.
|
|
|
|
|
IntPtr[] keysyms;
|
2007-09-25 16:45:12 +00:00
|
|
|
|
|
2008-02-02 13:39:23 +00:00
|
|
|
|
//bool disposed;
|
2007-09-25 16:45:12 +00:00
|
|
|
|
|
2007-08-05 13:42:31 +00:00
|
|
|
|
#region --- Constructors ---
|
|
|
|
|
|
2007-08-05 17:21:46 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructs a new X11Input driver. Creates a hidden InputOnly window, child to
|
|
|
|
|
/// the main application window, which selects input events and routes them to
|
|
|
|
|
/// the device specific drivers (Keyboard, Mouse, Hid).
|
|
|
|
|
/// </summary>
|
2007-09-21 20:34:07 +00:00
|
|
|
|
/// <param name="attach">The window which the InputDriver will attach itself on.</param>
|
2007-09-26 11:58:55 +00:00
|
|
|
|
public X11Input(IWindowInfo attach)
|
2007-08-05 09:03:22 +00:00
|
|
|
|
{
|
2007-08-05 13:42:31 +00:00
|
|
|
|
Debug.WriteLine("Initalizing X11 input driver.");
|
|
|
|
|
Debug.Indent();
|
|
|
|
|
|
2007-09-21 20:34:07 +00:00
|
|
|
|
if (attach == null)
|
2007-08-05 17:45:59 +00:00
|
|
|
|
throw new ArgumentException("A valid parent window must be defined, in order to create an X11Input driver.");
|
2007-08-05 13:42:31 +00:00
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
//window = new X11WindowInfo(attach);
|
2008-03-01 13:15:31 +00:00
|
|
|
|
X11WindowInfo window = (X11WindowInfo)attach;
|
2008-02-01 23:28:23 +00:00
|
|
|
|
|
|
|
|
|
// Init mouse
|
|
|
|
|
mouse.Description = "Default X11 mouse";
|
|
|
|
|
mouse.DeviceID = IntPtr.Zero;
|
|
|
|
|
mouse.NumberOfButtons = 5;
|
|
|
|
|
mouse.NumberOfWheels = 1;
|
|
|
|
|
dummy_mice_list.Add(mouse);
|
|
|
|
|
|
|
|
|
|
// Init keyboard
|
|
|
|
|
API.DisplayKeycodes(window.Display, ref firstKeyCode, ref lastKeyCode);
|
|
|
|
|
Debug.Print("First keycode: {0}, last {1}", firstKeyCode, lastKeyCode);
|
|
|
|
|
|
|
|
|
|
IntPtr keysym_ptr = API.GetKeyboardMapping(window.Display, (byte)firstKeyCode,
|
|
|
|
|
lastKeyCode - firstKeyCode + 1, ref keysyms_per_keycode);
|
|
|
|
|
Debug.Print("{0} keysyms per keycode.", keysyms_per_keycode);
|
|
|
|
|
|
|
|
|
|
keysyms = new IntPtr[(lastKeyCode - firstKeyCode + 1) * keysyms_per_keycode];
|
|
|
|
|
Marshal.PtrToStructure(keysym_ptr, keysyms);
|
|
|
|
|
API.Free(keysym_ptr);
|
|
|
|
|
|
|
|
|
|
KeyboardDevice kb = new KeyboardDevice();
|
|
|
|
|
keyboard.Description = "Default X11 keyboard";
|
|
|
|
|
keyboard.NumberOfKeys = lastKeyCode - firstKeyCode + 1;
|
|
|
|
|
keyboard.DeviceID = IntPtr.Zero;
|
|
|
|
|
dummy_keyboard_list.Add(keyboard);
|
|
|
|
|
|
2007-08-05 13:42:31 +00:00
|
|
|
|
Debug.Unindent();
|
2007-08-05 09:03:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-05 13:42:31 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2007-11-10 18:24:56 +00:00
|
|
|
|
#region private void InternalPoll()
|
|
|
|
|
#if false
|
2007-09-25 16:45:12 +00:00
|
|
|
|
private void InternalPoll()
|
|
|
|
|
{
|
2007-11-10 18:24:56 +00:00
|
|
|
|
X11.XEvent e = new XEvent();
|
2007-09-25 16:45:12 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
2007-11-10 18:24:56 +00:00
|
|
|
|
while (!disposed)
|
|
|
|
|
{
|
|
|
|
|
Functions.XMaskEvent(window.Display,
|
|
|
|
|
EventMask.PointerMotionMask | EventMask.PointerMotionHintMask |
|
|
|
|
|
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask |
|
|
|
|
|
EventMask.KeyPressMask | EventMask.KeyReleaseMask |
|
|
|
|
|
EventMask.StructureNotifyMask, ref e);
|
|
|
|
|
|
|
|
|
|
if (disposed)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
switch (e.type)
|
|
|
|
|
{
|
|
|
|
|
case XEventName.KeyPress:
|
|
|
|
|
case XEventName.KeyRelease:
|
|
|
|
|
keyboardDriver.ProcessKeyboardEvent(ref e.KeyEvent);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case XEventName.ButtonPress:
|
|
|
|
|
case XEventName.ButtonRelease:
|
|
|
|
|
mouseDriver.ProcessButton(ref e.ButtonEvent);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case XEventName.MotionNotify:
|
|
|
|
|
mouseDriver.ProcessMotion(ref e.MotionEvent);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case XEventName.DestroyNotify:
|
|
|
|
|
Functions.XPutBackEvent(window.Display, ref e);
|
|
|
|
|
//pollingThread.Abort();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-09-25 16:45:12 +00:00
|
|
|
|
}
|
|
|
|
|
catch (ThreadAbortException expt)
|
|
|
|
|
{
|
|
|
|
|
Functions.XUnmapWindow(window.Display, window.Handle);
|
|
|
|
|
Functions.XDestroyWindow(window.Display, window.Handle);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-11-10 18:24:56 +00:00
|
|
|
|
#endif
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region internal void ProcessEvent(ref XEvent e)
|
2007-09-25 16:45:12 +00:00
|
|
|
|
|
2007-09-26 11:58:55 +00:00
|
|
|
|
internal void ProcessEvent(ref XEvent e)
|
|
|
|
|
{
|
|
|
|
|
switch (e.type)
|
|
|
|
|
{
|
|
|
|
|
case XEventName.KeyPress:
|
|
|
|
|
case XEventName.KeyRelease:
|
2008-02-01 23:28:23 +00:00
|
|
|
|
bool pressed = e.type == XEventName.KeyPress;
|
|
|
|
|
|
|
|
|
|
IntPtr keysym = API.LookupKeysym(ref e.KeyEvent, 0);
|
|
|
|
|
IntPtr keysym2 = API.LookupKeysym(ref e.KeyEvent, 1);
|
|
|
|
|
|
|
|
|
|
if (keymap.ContainsKey((XKey)keysym))
|
|
|
|
|
keyboard[keymap[(XKey)keysym]] = pressed;
|
|
|
|
|
else if (keymap.ContainsKey((XKey)keysym2))
|
|
|
|
|
keyboard[keymap[(XKey)keysym2]] = pressed;
|
|
|
|
|
else
|
|
|
|
|
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.KeyEvent.keycode, (XKey)keysym, (XKey)keysym2);
|
2007-09-26 11:58:55 +00:00
|
|
|
|
break;
|
2008-02-01 23:28:23 +00:00
|
|
|
|
|
2007-09-26 11:58:55 +00:00
|
|
|
|
case XEventName.ButtonPress:
|
2008-02-01 23:28:23 +00:00
|
|
|
|
if (e.ButtonEvent.button == (int)MouseButton.Button1) mouse[OpenTK.Input.MouseButton.Left] = true;
|
|
|
|
|
else if (e.ButtonEvent.button == (int)MouseButton.Button2) mouse[OpenTK.Input.MouseButton.Middle] = true;
|
|
|
|
|
else if (e.ButtonEvent.button == (int)MouseButton.Button3) mouse[OpenTK.Input.MouseButton.Right] = true;
|
|
|
|
|
else if (e.ButtonEvent.button == (int)MouseButton.Button4) mouse.Wheel++;
|
|
|
|
|
else if (e.ButtonEvent.button == (int)MouseButton.Button5) mouse.Wheel--;
|
|
|
|
|
//if ((e.state & (int)X11.MouseMask.Button4Mask) != 0) m.Wheel++;
|
|
|
|
|
//if ((e.state & (int)X11.MouseMask.Button5Mask) != 0) m.Wheel--;
|
|
|
|
|
break;
|
|
|
|
|
|
2007-09-26 11:58:55 +00:00
|
|
|
|
case XEventName.ButtonRelease:
|
2008-02-01 23:28:23 +00:00
|
|
|
|
if (e.ButtonEvent.button == (int)MouseButton.Button1) mouse[OpenTK.Input.MouseButton.Left] = false;
|
|
|
|
|
else if (e.ButtonEvent.button == (int)MouseButton.Button2) mouse[OpenTK.Input.MouseButton.Middle] = false;
|
|
|
|
|
else if (e.ButtonEvent.button == (int)MouseButton.Button3) mouse[OpenTK.Input.MouseButton.Right] = false;
|
2007-09-26 11:58:55 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case XEventName.MotionNotify:
|
2008-02-01 23:28:23 +00:00
|
|
|
|
mouse.X = e.MotionEvent.x;
|
|
|
|
|
mouse.Y = e.MotionEvent.y;
|
2007-09-26 11:58:55 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-10 18:24:56 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-05 09:03:22 +00:00
|
|
|
|
#region --- IInputDriver Members ---
|
|
|
|
|
|
|
|
|
|
#region public IList<IInputDevice> InputDevices
|
|
|
|
|
|
|
|
|
|
public IList<IInputDevice> InputDevices
|
|
|
|
|
{
|
|
|
|
|
get { throw new Exception("The method or operation is not implemented."); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public IList<Keyboard> Keyboard
|
|
|
|
|
|
2007-09-26 11:58:55 +00:00
|
|
|
|
public IList<KeyboardDevice> Keyboard
|
2007-08-05 09:03:22 +00:00
|
|
|
|
{
|
2008-02-01 23:28:23 +00:00
|
|
|
|
get { return dummy_keyboard_list; }//return keyboardDriver.Keyboard;
|
2007-08-05 09:03:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public IList<Mouse> Mouse
|
|
|
|
|
|
2007-09-26 11:58:55 +00:00
|
|
|
|
public IList<MouseDevice> Mouse
|
2007-08-05 09:03:22 +00:00
|
|
|
|
{
|
2008-02-01 23:28:23 +00:00
|
|
|
|
get { return (IList<MouseDevice>)dummy_mice_list; } //return mouseDriver.Mouse;
|
2007-08-05 09:03:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-09-24 21:10:52 +00:00
|
|
|
|
#region public void Poll()
|
|
|
|
|
|
2007-08-05 18:33:38 +00:00
|
|
|
|
/// <summary>
|
2007-09-26 15:41:14 +00:00
|
|
|
|
/// Polls and updates state of all keyboard, mouse and joystick devices.
|
2007-08-05 18:33:38 +00:00
|
|
|
|
/// </summary>
|
2007-09-22 13:13:17 +00:00
|
|
|
|
public void Poll()
|
2007-08-05 18:26:14 +00:00
|
|
|
|
{
|
2008-01-15 13:04:35 +00:00
|
|
|
|
//mouseDriver.Poll();
|
2007-08-05 18:26:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-05 09:03:22 +00:00
|
|
|
|
#endregion
|
2007-08-22 00:30:16 +00:00
|
|
|
|
|
2007-09-24 21:10:52 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-22 00:30:16 +00:00
|
|
|
|
#region --- IDisposable Members ---
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2008-02-01 23:28:23 +00:00
|
|
|
|
//this.Dispose(true);
|
|
|
|
|
//GC.SuppressFinalize(this);
|
2007-09-25 16:45:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-02-01 23:28:23 +00:00
|
|
|
|
//private void Dispose(bool manual)
|
|
|
|
|
//{
|
|
|
|
|
// if (!disposed)
|
|
|
|
|
// {
|
|
|
|
|
// //disposing = true;
|
|
|
|
|
// if (pollingThread != null && pollingThread.IsAlive)
|
|
|
|
|
// pollingThread.Abort();
|
|
|
|
|
|
|
|
|
|
// if (manual)
|
|
|
|
|
// {
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// disposed = true;
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//~X11Input()
|
|
|
|
|
//{
|
|
|
|
|
// this.Dispose(false);
|
|
|
|
|
//}
|
2007-08-22 00:30:16 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
2007-08-05 09:03:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|