Opentk/Source/OpenTK/Platform/X11/X11Keyboard.cs
the_fiddler 33527aa2c9 Added KeyDown and KeyUp events to IKeyboard and Keyboard.
Improved input logger test to hook on the aforementioned events.
Removed Debug printing of keys in OpenTK.Input.Keyboard.
Beautified X11Keyboard.cs
Added experimental code to handle X11 keyboard events (not used yet).
2007-08-20 13:45:04 +00:00

236 lines
9.2 KiB
C#

#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
* See license.txt for license info
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using OpenTK.Input;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace OpenTK.Platform.X11
{
/// <summary>
/// Drives the Keyboard devices on X11.
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
/// </summary>
internal class X11Keyboard : IKeyboardDriver
{
/// <summary>
/// The window receiving input events.
/// </summary>
WindowInfo window;
private bool[] keys = new bool[(int)OpenTK.Input.Key.MaxKeys];
private List<Keyboard> keyboards = new List<Keyboard>();
private static Dictionary<XKey, Key> keymap = new Dictionary<XKey, Key>((int)Key.MaxKeys);
/// <summary>
/// The smallest and largest KeyCode supported by the X server. Queried through API.DisplayKeycodes()
/// </summary>
int firstKeyCode, lastKeyCode;
/// <summary>
/// The number of KeySyms for each KeyCode.
/// </summary>
int keysyms_per_keycode;
IntPtr[] keysyms;
private static bool keymapExists;
#region private static void Initialize()
private static void Initialize()
{
if (!keymapExists)
{
keymap.Add(XKey.Escape, Key.Escape);
keymap.Add(XKey.Return, Key.Enter);
keymap.Add(XKey.space, Key.Space);
keymap.Add(XKey.BackSpace, Key.BackSpace);
keymap.Add(XKey.Shift_L, Key.ShiftLeft);
keymap.Add(XKey.Shift_R, Key.ShiftRight);
keymap.Add(XKey.Alt_L, Key.AltLeft);
keymap.Add(XKey.Alt_R, Key.AltRight);
keymap.Add(XKey.Control_L, Key.ControlLeft);
keymap.Add(XKey.Control_R, Key.ControlRight);
keymap.Add(XKey.Super_L, Key.WinLeft);
keymap.Add(XKey.Super_R, Key.WinRight);
keymap.Add(XKey.Meta_L, Key.WinLeft);
keymap.Add(XKey.Meta_R, Key.WinRight);
keymap.Add(XKey.Menu, Key.Menu);
keymap.Add(XKey.Tab, Key.Tab);
keymap.Add(XKey.minus, Key.Minus);
keymap.Add(XKey.plus, Key.Plus);
keymap.Add(XKey.equal, Key.Plus);
keymap.Add(XKey.Caps_Lock, Key.CapsLock);
keymap.Add(XKey.Num_Lock, Key.NumLock);
for (int i = (int)XKey.F1; i <= (int)XKey.F35; i++)
{
keymap.Add((XKey)i, (Key)((int)Key.F1 + (i - (int)XKey.F1)));
}
for (int i = (int)XKey.a; i <= (int)XKey.z; i++)
{
keymap.Add((XKey)i, (Key)((int)Key.A + (i - (int)XKey.a)));
}
for (int i = (int)XKey.A; i <= (int)XKey.Z; i++)
{
keymap.Add((XKey)i, (Key)((int)Key.A + (i - (int)XKey.A)));
}
for (int i = (int)XKey.Number0; i <= (int)XKey.Number9; i++)
{
keymap.Add((XKey)i, (Key)((int)Key.Number0 + (i - (int)XKey.Number0)));
}
for (int i = (int)XKey.KP_0; i <= (int)XKey.KP_9; i++)
{
keymap.Add((XKey)i, (Key)((int)Key.Keypad0 + (i - (int)XKey.KP_0)));
}
keymap.Add(XKey.Pause, Key.Pause);
keymap.Add(XKey.Break, Key.Pause);
keymap.Add(XKey.Scroll_Lock, Key.Pause);
keymap.Add(XKey.Insert, Key.PrintScreen);
keymap.Add(XKey.Print, Key.PrintScreen);
keymap.Add(XKey.Sys_Req, Key.PrintScreen);
keymap.Add(XKey.backslash, Key.BackSlash);
keymap.Add(XKey.bar, Key.BackSlash);
keymap.Add(XKey.braceleft, Key.BracketLeft);
keymap.Add(XKey.bracketleft, Key.BracketLeft);
keymap.Add(XKey.braceright, Key.BracketRight);
keymap.Add(XKey.bracketright, Key.BracketRight);
keymap.Add(XKey.colon, Key.Semicolon);
keymap.Add(XKey.semicolon, Key.Semicolon);
keymap.Add(XKey.quoteright, Key.Quote);
keymap.Add(XKey.quotedbl, Key.Quote);
keymap.Add(XKey.quoteleft, Key.Tilde);
keymap.Add(XKey.asciitilde, Key.Tilde);
keymap.Add(XKey.comma, Key.Comma);
keymap.Add(XKey.less, Key.Comma);
keymap.Add(XKey.period, Key.Period);
keymap.Add(XKey.greater, Key.Period);
keymap.Add(XKey.slash, Key.Slash);
keymap.Add(XKey.question, Key.Slash);
keymap.Add(XKey.Left, Key.Left);
keymap.Add(XKey.Down, Key.Down);
keymap.Add(XKey.Right, Key.Right);
keymap.Add(XKey.Up, Key.Up);
keymap.Add(XKey.Delete, Key.Delete);
keymap.Add(XKey.Home, Key.Home);
keymap.Add(XKey.End, Key.End);
//keymap.Add(XKey.Prior, Key.PageUp); // XKey.Prior == XKey.Page_Up
keymap.Add(XKey.Page_Up, Key.PageUp);
keymap.Add(XKey.Page_Down, Key.PageDown);
//keymap.Add(XKey.Next, Key.PageDown); // XKey.Next == XKey.Page_Down
keymap.Add(XKey.KP_Add, Key.KeypadAdd);
keymap.Add(XKey.KP_Subtract, Key.KeypadSubtract);
keymap.Add(XKey.KP_Multiply, Key.KeypadMultiply);
keymap.Add(XKey.KP_Divide, Key.KeypadDivide);
keymap.Add(XKey.KP_Decimal, Key.KeypadDecimal);
keymap.Add(XKey.KP_Insert, Key.Keypad0);
keymap.Add(XKey.KP_End, Key.Keypad1);
keymap.Add(XKey.KP_Down, Key.Keypad2);
keymap.Add(XKey.KP_Page_Down, Key.Keypad3);
keymap.Add(XKey.KP_Left, Key.Keypad4);
keymap.Add(XKey.KP_Right, Key.Keypad6);
keymap.Add(XKey.KP_Home, Key.Keypad7);
keymap.Add(XKey.KP_Up, Key.Keypad8);
keymap.Add(XKey.KP_Page_Up, Key.Keypad9);
keymap.Add(XKey.KP_Delete, Key.KeypadDecimal);
keymap.Add(XKey.KP_Enter, Key.Enter);
keymapExists = true;
}
}
#endregion
internal X11Keyboard(WindowInfo window)
{
this.window = window;
Initialize();
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);
//keysyms = (IntPtr[])Marshal.PtrToStructure(keysym_ptr, typeof(IntPtr[]));
API.Free(keysym_ptr);
Keyboard kb = new Keyboard();
kb.Description = "Default X11 keyboard";
kb.NumberOfKeys = lastKeyCode - firstKeyCode + 1;
keyboards.Add(kb);
Debug.Print("Keyboard added: {0}", kb.ToString());
}
#region internal bool ProcessKeyboardEvent(X11.KeyEvent e)
/// <summary>
/// Processes X11 KeyEvents.
/// </summary>
/// <param name="e">The X11.KeyEvent to process</param>
/// <returns>True if the event was processed, false otherwise.</returns>
internal bool ProcessKeyboardEvent(X11.XKeyEvent e)
{
//int keysym = keysyms[(e.keycode - firstKeyCode) * keysyms_per_keycode].ToInt32();
//int keysym2 = keysyms[(e.keycode - firstKeyCode) * keysyms_per_keycode].ToInt32();
bool pressed = e.type == XEventName.KeyPress;
IntPtr keysym = API.LookupKeysym(ref e, 0);
IntPtr keysym2 = API.LookupKeysym(ref e, 1);
switch (keysym.ToInt64())
{
default:
if (keymap.ContainsKey((XKey)keysym))
{
keyboards[0][keymap[(XKey)keysym]] = pressed;
}
else if (keymap.ContainsKey((XKey)keysym2))
{
keyboards[0][keymap[(XKey)keysym2]] = pressed;
}
else
{
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2);
return false;
}
return true;
}
}
#endregion
#region --- IKeyboardDriver Members ---
public IList<Keyboard> Keyboard
{
get { return keyboards; }
}
#endregion
}
}