[X11] Optimized XKey translation

This commit is contained in:
thefiddler 2014-04-25 21:55:00 +02:00
parent 6257858d54
commit 9605940661
3 changed files with 377 additions and 143 deletions

View file

@ -29,7 +29,6 @@ namespace OpenTK.Platform.X11
List<KeyboardDevice> dummy_keyboard_list = new List<KeyboardDevice>(1); List<KeyboardDevice> dummy_keyboard_list = new List<KeyboardDevice>(1);
List<MouseDevice> dummy_mice_list = new List<MouseDevice>(1); List<MouseDevice> dummy_mice_list = new List<MouseDevice>(1);
X11KeyMap keymap = new X11KeyMap();
int firstKeyCode, lastKeyCode; // The smallest and largest KeyCode supported by the X server. int firstKeyCode, lastKeyCode; // The smallest and largest KeyCode supported by the X server.
int keysyms_per_keycode; // The number of KeySyms for each KeyCode. int keysyms_per_keycode; // The number of KeySyms for each KeyCode.
IntPtr[] keysyms; IntPtr[] keysyms;
@ -100,17 +99,12 @@ namespace OpenTK.Platform.X11
{ {
XKey keysym = (XKey)API.LookupKeysym(ref e, 0); XKey keysym = (XKey)API.LookupKeysym(ref e, 0);
XKey keysym2 = (XKey)API.LookupKeysym(ref e, 1); XKey keysym2 = (XKey)API.LookupKeysym(ref e, 1);
key = Key.Unknown; key = X11KeyMap.GetKey(keysym);
if (key == Key.Unknown)
if (keymap.ContainsKey(keysym))
{ {
key = keymap[keysym]; key = X11KeyMap.GetKey(keysym2);
} }
else if (keymap.ContainsKey(keysym2)) if (key == Key.Unknown)
{
key = keymap[keysym2];
}
else
{ {
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2); Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2);
} }

View file

@ -10,129 +10,364 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Diagnostics; using System.Diagnostics;
using OpenTK.Input; using OpenTK.Input;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
internal class X11KeyMap : Dictionary<XKey, Key> static class X11KeyMap
{ {
internal X11KeyMap() public static Key GetKey(XKey key)
{ {
try switch (key)
{ {
this.Add(XKey.Escape, Key.Escape); case XKey.Escape:
this.Add(XKey.Return, Key.Enter); return Key.Escape;
this.Add(XKey.space, Key.Space); case XKey.Return:
this.Add(XKey.BackSpace, Key.BackSpace); return Key.Enter;
case XKey.space:
return Key.Space;
case XKey.BackSpace:
return Key.BackSpace;
this.Add(XKey.Shift_L, Key.ShiftLeft); case XKey.Shift_L:
this.Add(XKey.Shift_R, Key.ShiftRight); return Key.ShiftLeft;
this.Add(XKey.Alt_L, Key.AltLeft); case XKey.Shift_R:
this.Add(XKey.Alt_R, Key.AltRight); return Key.ShiftRight;
this.Add(XKey.Control_L, Key.ControlLeft); case XKey.Alt_L:
this.Add(XKey.Control_R, Key.ControlRight); return Key.AltLeft;
this.Add(XKey.Super_L, Key.WinLeft); case XKey.Alt_R:
this.Add(XKey.Super_R, Key.WinRight); return Key.AltRight;
this.Add(XKey.Meta_L, Key.WinLeft); case XKey.Control_L:
this.Add(XKey.Meta_R, Key.WinRight); return Key.ControlLeft;
this.Add(XKey.ISO_Level3_Shift, Key.AltRight); // Normally AltGr case XKey.Control_R:
return Key.ControlRight;
case XKey.Super_L:
return Key.WinLeft;
case XKey.Super_R:
return Key.WinRight;
case XKey.Meta_L:
return Key.WinLeft;
case XKey.Meta_R:
return Key.WinRight;
case XKey.ISO_Level3_Shift:
return Key.AltRight; // Normally AltGr
this.Add(XKey.Menu, Key.Menu); case XKey.Menu:
this.Add(XKey.Tab, Key.Tab); return Key.Menu;
this.Add(XKey.minus, Key.Minus); case XKey.Tab:
this.Add(XKey.plus, Key.Plus); return Key.Tab;
this.Add(XKey.equal, Key.Plus); case XKey.minus:
return Key.Minus;
case XKey.plus:
return Key.Plus;
case XKey.equal:
return Key.Plus;
this.Add(XKey.Caps_Lock, Key.CapsLock); case XKey.Caps_Lock:
this.Add(XKey.Num_Lock, Key.NumLock); return Key.CapsLock;
case XKey.Num_Lock:
return Key.NumLock;
for (int i = (int)XKey.F1; i <= (int)XKey.F35; i++) case XKey.F1:
{ return Key.F1;
this.Add((XKey)i, (Key)((int)Key.F1 + (i - (int)XKey.F1))); case XKey.F2:
} return Key.F2;
case XKey.F3:
return Key.F3;
case XKey.F4:
return Key.F4;
case XKey.F5:
return Key.F5;
case XKey.F6:
return Key.F6;
case XKey.F7:
return Key.F7;
case XKey.F8:
return Key.F8;
case XKey.F9:
return Key.F9;
case XKey.F10:
return Key.F10;
case XKey.F11:
return Key.F11;
case XKey.F12:
return Key.F12;
case XKey.F13:
return Key.F13;
case XKey.F14:
return Key.F14;
case XKey.F15:
return Key.F15;
case XKey.F16:
return Key.F16;
case XKey.F17:
return Key.F17;
case XKey.F18:
return Key.F18;
case XKey.F19:
return Key.F19;
case XKey.F20:
return Key.F20;
case XKey.F21:
return Key.F21;
case XKey.F22:
return Key.F22;
case XKey.F23:
return Key.F23;
case XKey.F24:
return Key.F24;
case XKey.F25:
return Key.F25;
case XKey.F26:
return Key.F26;
case XKey.F27:
return Key.F27;
case XKey.F28:
return Key.F28;
case XKey.F29:
return Key.F29;
case XKey.F30:
return Key.F30;
case XKey.F31:
return Key.F31;
case XKey.F32:
return Key.F32;
case XKey.F33:
return Key.F33;
case XKey.F34:
return Key.F34;
case XKey.F35:
return Key.F35;
for (int i = (int)XKey.a; i <= (int)XKey.z; i++) case XKey.a:
{ case XKey.A:
this.Add((XKey)i, (Key)((int)Key.A + (i - (int)XKey.a))); return Key.A;
} case XKey.b:
case XKey.B:
return Key.B;
case XKey.c:
case XKey.C:
return Key.C;
case XKey.d:
case XKey.D:
return Key.D;
case XKey.e:
case XKey.E:
return Key.E;
case XKey.f:
case XKey.F:
return Key.F;
case XKey.g:
case XKey.G:
return Key.G;
case XKey.h:
case XKey.H:
return Key.H;
case XKey.i:
case XKey.I:
return Key.I;
case XKey.j:
case XKey.J:
return Key.J;
case XKey.k:
case XKey.K:
return Key.K;
case XKey.l:
case XKey.L:
return Key.L;
case XKey.m:
case XKey.M:
return Key.M;
case XKey.n:
case XKey.N:
return Key.N;
case XKey.o:
case XKey.O:
return Key.O;
case XKey.p:
case XKey.P:
return Key.P;
case XKey.q:
case XKey.Q:
return Key.Q;
case XKey.r:
case XKey.R:
return Key.R;
case XKey.s:
case XKey.S:
return Key.S;
case XKey.t:
case XKey.T:
return Key.T;
case XKey.u:
case XKey.U:
return Key.U;
case XKey.v:
case XKey.V:
return Key.V;
case XKey.w:
case XKey.W:
return Key.W;
case XKey.x:
case XKey.X:
return Key.X;
case XKey.y:
case XKey.Y:
return Key.Y;
case XKey.z:
case XKey.Z:
return Key.Z;
for (int i = (int)XKey.A; i <= (int)XKey.Z; i++) case XKey.Number0:
{ return Key.Number0;
this.Add((XKey)i, (Key)((int)Key.A + (i - (int)XKey.A))); case XKey.Number1:
} return Key.Number1;
case XKey.Number2:
return Key.Number2;
case XKey.Number3:
return Key.Number3;
case XKey.Number4:
return Key.Number4;
case XKey.Number5:
return Key.Number5;
case XKey.Number6:
return Key.Number6;
case XKey.Number7:
return Key.Number7;
case XKey.Number8:
return Key.Number8;
case XKey.Number9:
return Key.Number9;
for (int i = (int)XKey.Number0; i <= (int)XKey.Number9; i++) case XKey.KP_0:
{ return Key.Keypad0;
this.Add((XKey)i, (Key)((int)Key.Number0 + (i - (int)XKey.Number0))); case XKey.KP_1:
} return Key.Keypad1;
case XKey.KP_2:
return Key.Keypad2;
case XKey.KP_3:
return Key.Keypad3;
case XKey.KP_4:
return Key.Keypad4;
case XKey.KP_5:
return Key.Keypad5;
case XKey.KP_6:
return Key.Keypad6;
case XKey.KP_7:
return Key.Keypad7;
case XKey.KP_8:
return Key.Keypad8;
case XKey.KP_9:
return Key.Keypad9;
for (int i = (int)XKey.KP_0; i <= (int)XKey.KP_9; i++) case XKey.Pause:
{ return Key.Pause;
this.Add((XKey)i, (Key)((int)Key.Keypad0 + (i - (int)XKey.KP_0))); case XKey.Break:
} return Key.Pause;
case XKey.Scroll_Lock:
return Key.Pause;
case XKey.Insert:
return Key.PrintScreen;
case XKey.Print:
return Key.PrintScreen;
case XKey.Sys_Req:
return Key.PrintScreen;
this.Add(XKey.Pause, Key.Pause); case XKey.backslash:
this.Add(XKey.Break, Key.Pause); return Key.BackSlash;
this.Add(XKey.Scroll_Lock, Key.Pause); case XKey.bar:
this.Add(XKey.Insert, Key.PrintScreen); return Key.BackSlash;
this.Add(XKey.Print, Key.PrintScreen); case XKey.braceleft:
this.Add(XKey.Sys_Req, Key.PrintScreen); return Key.BracketLeft;
case XKey.bracketleft:
return Key.BracketLeft;
case XKey.braceright:
return Key.BracketRight;
case XKey.bracketright:
return Key.BracketRight;
case XKey.colon:
return Key.Semicolon;
case XKey.semicolon:
return Key.Semicolon;
case XKey.quoteright:
return Key.Quote;
case XKey.quotedbl:
return Key.Quote;
case XKey.quoteleft:
return Key.Tilde;
case XKey.asciitilde:
return Key.Tilde;
this.Add(XKey.backslash, Key.BackSlash); case XKey.comma:
this.Add(XKey.bar, Key.BackSlash); return Key.Comma;
this.Add(XKey.braceleft, Key.BracketLeft); case XKey.less:
this.Add(XKey.bracketleft, Key.BracketLeft); return Key.Comma;
this.Add(XKey.braceright, Key.BracketRight); case XKey.period:
this.Add(XKey.bracketright, Key.BracketRight); return Key.Period;
this.Add(XKey.colon, Key.Semicolon); case XKey.greater:
this.Add(XKey.semicolon, Key.Semicolon); return Key.Period;
this.Add(XKey.quoteright, Key.Quote); case XKey.slash:
this.Add(XKey.quotedbl, Key.Quote); return Key.Slash;
this.Add(XKey.quoteleft, Key.Tilde); case XKey.question:
this.Add(XKey.asciitilde, Key.Tilde); return Key.Slash;
this.Add(XKey.comma, Key.Comma); case XKey.Left:
this.Add(XKey.less, Key.Comma); return Key.Left;
this.Add(XKey.period, Key.Period); case XKey.Down:
this.Add(XKey.greater, Key.Period); return Key.Down;
this.Add(XKey.slash, Key.Slash); case XKey.Right:
this.Add(XKey.question, Key.Slash); return Key.Right;
case XKey.Up:
return Key.Up;
this.Add(XKey.Left, Key.Left); case XKey.Delete:
this.Add(XKey.Down, Key.Down); return Key.Delete;
this.Add(XKey.Right, Key.Right); case XKey.Home:
this.Add(XKey.Up, Key.Up); return Key.Home;
case XKey.End:
return Key.End;
//case XKey.Prior: return Key.PageUp; // XKey.Prior == XKey.Page_Up
case XKey.Page_Up:
return Key.PageUp;
case XKey.Page_Down:
return Key.PageDown;
//case XKey.Next: return Key.PageDown; // XKey.Next == XKey.Page_Down
this.Add(XKey.Delete, Key.Delete); case XKey.KP_Add:
this.Add(XKey.Home, Key.Home); return Key.KeypadAdd;
this.Add(XKey.End, Key.End); case XKey.KP_Subtract:
//this.Add(XKey.Prior, Key.PageUp); // XKey.Prior == XKey.Page_Up return Key.KeypadSubtract;
this.Add(XKey.Page_Up, Key.PageUp); case XKey.KP_Multiply:
this.Add(XKey.Page_Down, Key.PageDown); return Key.KeypadMultiply;
//this.Add(XKey.Next, Key.PageDown); // XKey.Next == XKey.Page_Down case XKey.KP_Divide:
return Key.KeypadDivide;
case XKey.KP_Decimal:
return Key.KeypadDecimal;
case XKey.KP_Insert:
return Key.Keypad0;
case XKey.KP_End:
return Key.Keypad1;
case XKey.KP_Down:
return Key.Keypad2;
case XKey.KP_Page_Down:
return Key.Keypad3;
case XKey.KP_Left:
return Key.Keypad4;
case XKey.KP_Right:
return Key.Keypad6;
case XKey.KP_Home:
return Key.Keypad7;
case XKey.KP_Up:
return Key.Keypad8;
case XKey.KP_Page_Up:
return Key.Keypad9;
case XKey.KP_Delete:
return Key.KeypadDecimal;
case XKey.KP_Enter:
return Key.KeypadEnter;
this.Add(XKey.KP_Add, Key.KeypadAdd); default:
this.Add(XKey.KP_Subtract, Key.KeypadSubtract); return Key.Unknown;
this.Add(XKey.KP_Multiply, Key.KeypadMultiply);
this.Add(XKey.KP_Divide, Key.KeypadDivide);
this.Add(XKey.KP_Decimal, Key.KeypadDecimal);
this.Add(XKey.KP_Insert, Key.Keypad0);
this.Add(XKey.KP_End, Key.Keypad1);
this.Add(XKey.KP_Down, Key.Keypad2);
this.Add(XKey.KP_Page_Down, Key.Keypad3);
this.Add(XKey.KP_Left, Key.Keypad4);
this.Add(XKey.KP_Right, Key.Keypad6);
this.Add(XKey.KP_Home, Key.Keypad7);
this.Add(XKey.KP_Up, Key.Keypad8);
this.Add(XKey.KP_Page_Up, Key.Keypad9);
this.Add(XKey.KP_Delete, Key.KeypadDecimal);
this.Add(XKey.KP_Enter, Key.KeypadEnter);
}
catch (ArgumentException e)
{
Debug.Print("Exception while creating keymap: '{0}'.", e.ToString());
} }
} }
} }

View file

@ -36,7 +36,6 @@ namespace OpenTK.Platform.X11
// Only one keyboard supported. // Only one keyboard supported.
sealed class X11Keyboard : IKeyboardDriver2 sealed class X11Keyboard : IKeyboardDriver2
{ {
readonly static X11KeyMap keymap = new X11KeyMap();
readonly static string name = "Core X11 keyboard"; readonly static string name = "Core X11 keyboard";
readonly byte[] keys = new byte[32]; readonly byte[] keys = new byte[32];
readonly int KeysymsPerKeycode; readonly int KeysymsPerKeycode;
@ -53,7 +52,10 @@ namespace OpenTK.Platform.X11
// Find the number of keysyms per keycode. // Find the number of keysyms per keycode.
int first = 0, last = 0; int first = 0, last = 0;
API.DisplayKeycodes(display, ref first, ref last); API.DisplayKeycodes(display, ref first, ref last);
IntPtr keysym_ptr = API.GetKeyboardMapping(display, (byte)first, last - first + 1, IntPtr keysym_ptr =
API.GetKeyboardMapping(display,
(byte)first,
last - first + 1,
ref KeysymsPerKeycode); ref KeysymsPerKeycode);
Functions.XFree(keysym_ptr); Functions.XFree(keysym_ptr);
@ -66,7 +68,9 @@ namespace OpenTK.Platform.X11
bool supported; bool supported;
Functions.XkbSetDetectableAutoRepeat(display, true, out supported); Functions.XkbSetDetectableAutoRepeat(display, true, out supported);
} }
catch { } catch
{
}
} }
} }
@ -108,8 +112,9 @@ namespace OpenTK.Platform.X11
for (int mod = 0; mod < KeysymsPerKeycode; mod++) for (int mod = 0; mod < KeysymsPerKeycode; mod++)
{ {
IntPtr keysym = Functions.XKeycodeToKeysym(display, (byte)keycode, mod); IntPtr keysym = Functions.XKeycodeToKeysym(display, (byte)keycode, mod);
if (keysym != IntPtr.Zero && keymap.TryGetValue((XKey)keysym, out key)) if (keysym != IntPtr.Zero)
{ {
key = X11KeyMap.GetKey((XKey)keysym);
if (pressed) if (pressed)
state.EnableBit((int)key); state.EnableBit((int)key);
else else