From 67727d2e9ba18ed48b6288c06ecd1eff4cc1ca64 Mon Sep 17 00:00:00 2001 From: thefiddler Date: Tue, 15 Jul 2014 09:09:11 +0200 Subject: [PATCH] [Linux] Completed libinput keyboard driver implementation --- Source/OpenTK/OpenTK.csproj | 1 + Source/OpenTK/Platform/DeviceCollection.cs | 3 +- .../OpenTK/Platform/Linux/Bindings/Evdev.cs | 335 ++++++++++++++++++ .../Platform/Linux/Bindings/LibInput.cs | 39 +- Source/OpenTK/Platform/Linux/LinuxInput.cs | 104 +++--- .../OpenTK/Platform/Linux/LinuxKeyboardTTY.cs | 296 +--------------- 6 files changed, 437 insertions(+), 341 deletions(-) create mode 100644 Source/OpenTK/Platform/Linux/Bindings/Evdev.cs diff --git a/Source/OpenTK/OpenTK.csproj b/Source/OpenTK/OpenTK.csproj index b5f973ce..8a6f2608 100644 --- a/Source/OpenTK/OpenTK.csproj +++ b/Source/OpenTK/OpenTK.csproj @@ -821,6 +821,7 @@ + diff --git a/Source/OpenTK/Platform/DeviceCollection.cs b/Source/OpenTK/Platform/DeviceCollection.cs index 57306785..8229c291 100644 --- a/Source/OpenTK/Platform/DeviceCollection.cs +++ b/Source/OpenTK/Platform/DeviceCollection.cs @@ -31,7 +31,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; -namespace OpenTK +namespace OpenTK.Platform { // Holds a collection of hardware devices with an associated id. // Note: 'id' refers to a unique hardware-specific device identifier. @@ -41,7 +41,6 @@ namespace OpenTK // that is added. class DeviceCollection : IEnumerable { - readonly object Sync = new object(); readonly Dictionary Map = new Dictionary(); readonly List Devices = new List(); diff --git a/Source/OpenTK/Platform/Linux/Bindings/Evdev.cs b/Source/OpenTK/Platform/Linux/Bindings/Evdev.cs new file mode 100644 index 00000000..9b457c14 --- /dev/null +++ b/Source/OpenTK/Platform/Linux/Bindings/Evdev.cs @@ -0,0 +1,335 @@ +#region License +// +// Evdev.cs +// +// Author: +// Stefanos A. +// +// Copyright (c) 2006-2014 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +#endregion + +using System; +using OpenTK.Input; + +namespace OpenTK +{ + // Bindings for linux/input.h + class Evdev + { + #region KeyMap + + public static readonly Key[] KeyMap = new Key[] + { + // 0-7 + Key.Unknown, + Key.Escape, + Key.Number1, + Key.Number2, + Key.Number3, + Key.Number4, + Key.Number5, + Key.Number6, + // 8-15 + Key.Number7, + Key.Number8, + Key.Number9, + Key.Number0, + Key.Minus, + Key.Plus, + Key.BackSpace, + Key.Tab, + // 16-23 + Key.Q, + Key.W, + Key.E, + Key.R, + Key.T, + Key.Y, + Key.U, + Key.I, + // 24-31 + Key.O, + Key.P, + Key.BracketLeft, + Key.BracketRight, + Key.Enter, + Key.ControlLeft, + Key.A, + Key.S, + // 32-39 + Key.D, + Key.F, + Key.G, + Key.H, + Key.J, + Key.K, + Key.L, + Key.Semicolon, + // 40-47 + Key.Quote, + Key.Tilde, + Key.ShiftLeft, + Key.BackSlash, //Key.Execute, + Key.Z, + Key.X, + Key.C, + Key.V, //Key.Help, + // 48-55 + Key.B, + Key.N, + Key.M, + Key.Comma, + Key.Period, + Key.Slash, + Key.ShiftRight, + Key.KeypadMultiply, + // 56-63 + Key.AltLeft, + Key.Space, + Key.CapsLock, + Key.F1, + Key.F2, + Key.F3, + Key.F4, + Key.F5, + // 64-71 + Key.F6, + Key.F7, + Key.F8, + Key.F9, + Key.F10, + Key.NumLock, + Key.ScrollLock, + Key.Keypad7, + // 72-79 + Key.Keypad8, + Key.Keypad9, + Key.KeypadSubtract, + Key.Keypad4, + Key.Keypad5, + Key.Keypad6, + Key.KeypadPlus, + Key.Keypad1, + // 80-87 + Key.Keypad2, + Key.Keypad3, + Key.Keypad0, + Key.KeypadPeriod, + Key.Unknown, + Key.Unknown, // Zzenkakuhankaku + Key.Unknown, // 102ND + Key.F11, + // 88-95 + Key.F12, + Key.Unknown, // ro + Key.Unknown, // katakana + Key.Unknown, // hiragana + Key.Unknown, // henkan + Key.Unknown, // katakanahiragana + Key.Unknown, // muhenkan + Key.Unknown, // kpjpcomma + // 96-103 + Key.KeypadEnter, + Key.ControlRight, + Key.KeypadDivide, + Key.Unknown, // sysrq + Key.AltRight, + Key.Unknown, // linefeed + Key.Home, + Key.Up, + // 104-111 + Key.PageUp, + Key.Left, + Key.Right, + Key.End, + Key.Down, + Key.PageDown, + Key.Insert, + Key.Delete, + // 112-119 + Key.Unknown, // macro + Key.Unknown, // mute + Key.Unknown, // volumedown + Key.Unknown, // volumeup + Key.Unknown, // power + Key.Unknown, // kpequal + Key.Unknown, // kpplusminus + Key.Pause, + // 120-127 + Key.Unknown, // scale + Key.Unknown, // kpcomma + Key.Unknown, // hangeul / hanguel + Key.Unknown, // hanja + Key.Unknown, // yen + Key.WinLeft, + Key.WinRight, + Key.Unknown, // compose + // 128-135 + Key.Unknown, // stop + Key.Unknown, // again + Key.Unknown, // props + Key.Unknown, // undo + Key.Unknown, // front + Key.Unknown, // copy + Key.Unknown, // open + Key.Unknown, // paste + // 136-143 + Key.Unknown, // find + Key.Unknown, // cut + Key.Unknown, // help + Key.Unknown, // menu + Key.Unknown, // calc + Key.Unknown, // setup + Key.Unknown, // sleep + Key.Unknown, // wakeup + // 144-151 + Key.Unknown, // file + Key.Unknown, // send file + Key.Unknown, // delete file + Key.Unknown, // xfer + Key.Unknown, // prog1 + Key.Unknown, // prog2 + Key.Unknown, // www + Key.Unknown, // msdos + // 152-159 + Key.Unknown, // coffee / screenlock + Key.Unknown, // direction + Key.Unknown, // cycle windows + Key.Unknown, // mail + Key.Unknown, // bookmarks + Key.Unknown, // computer + Key.Back, + Key.Unknown, // forward + // 160-167 + Key.Unknown, // close cd + Key.Unknown, // eject cd + Key.Unknown, // eject/close cd + Key.Unknown, // next song + Key.Unknown, // play/pause + Key.Unknown, // previous song + Key.Unknown, // stop cd + Key.Unknown, // record + // 168-175 + Key.Unknown, // rewind + Key.Unknown, // phone + Key.Unknown, // iso + Key.Unknown, // config + Key.Unknown, // homepage + Key.Unknown, // refresh + Key.Unknown, // exit + Key.Unknown, // move, + // 176-183 + Key.Unknown, // edit, + Key.Unknown, // scroll up, + Key.Unknown, // scroll down, + Key.Unknown, // kp left paren, + Key.Unknown, // kp right paren, + Key.Unknown, // new, + Key.Unknown, // redo, + Key.F13, + // 184-191 + Key.F14, + Key.F15, + Key.F16, + Key.F17, + Key.F18, + Key.F19, + Key.F20, + Key.F21, + // 192-199 + Key.F22, + Key.F23, + Key.F24, + Key.Unknown, + Key.Unknown, + Key.Unknown, + Key.Unknown, + Key.Unknown, + // 200-207 + Key.Unknown, // play cd + Key.Unknown, // pause cd + Key.Unknown, // prog3 + Key.Unknown, // prog4 + Key.Unknown, // dashboard + Key.Unknown, // suspend + Key.Unknown, // close + Key.Unknown, // play + // 208-215 + Key.Unknown, // fast forward + Key.Unknown, // bass boost + Key.Unknown, // print + Key.Unknown, // hp + Key.Unknown, // camera + Key.Unknown, // sound + Key.Unknown, // question + Key.Unknown, // email + // 216-223 + Key.Unknown, // chat + Key.Unknown, // search + Key.Unknown, // connect + Key.Unknown, // finance + Key.Unknown, // sport + Key.Unknown, // shop + Key.Unknown, // alt erase + Key.Unknown, // cancel + // 224-231 + Key.Unknown, // brightness down + Key.Unknown, // brightness up + Key.Unknown, // media + Key.Unknown, // switch video mode + Key.Unknown, // dillum toggle + Key.Unknown, // dillum down + Key.Unknown, // dillum up + Key.Unknown, // send + // 232-239 + Key.Unknown, // reply + Key.Unknown, // forward email + Key.Unknown, // save + Key.Unknown, // documents + Key.Unknown, // battery + Key.Unknown, // bluetooth + Key.Unknown, // wlan + Key.Unknown, // uwb + // 240-247 + Key.Unknown, + Key.Unknown, // video next + Key.Unknown, // video prev + Key.Unknown, // brightness cycle + Key.Unknown, // brightness zero + Key.Unknown, // display off + Key.Unknown, // wwan / wimax + Key.Unknown, // rfkill + // 248-255 + Key.Unknown, // mic mute + Key.Unknown, + Key.Unknown, + Key.Unknown, + Key.Unknown, + Key.Unknown, + Key.Unknown, + Key.Unknown, // reserved + }; + + #endregion + } +} + diff --git a/Source/OpenTK/Platform/Linux/Bindings/LibInput.cs b/Source/OpenTK/Platform/Linux/Bindings/LibInput.cs index c557719d..f64353dc 100644 --- a/Source/OpenTK/Platform/Linux/Bindings/LibInput.cs +++ b/Source/OpenTK/Platform/Linux/Bindings/LibInput.cs @@ -43,7 +43,7 @@ namespace OpenTK.Platform.Linux class LibInput { - const string lib = "libinput"; + internal const string lib = "libinput"; [DllImport(lib, EntryPoint = "libinput_udev_create_for_seat", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr CreateContext(InputInterface @interface, @@ -95,6 +95,9 @@ namespace OpenTK.Platform.Linux [DllImport(lib, EntryPoint = "libinput_get_event", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr GetEvent(IntPtr libinput); + [DllImport(lib, EntryPoint = "libinput_event_get_keyboard_event", CallingConvention = CallingConvention.Cdecl)] + public static extern KeyboardEvent GetKeyboardEvent(IntPtr @event); + [DllImport(lib, EntryPoint = "libinput_event_get_type", CallingConvention = CallingConvention.Cdecl)] public static extern InputEventType GetEventType(IntPtr @event); @@ -145,6 +148,12 @@ namespace OpenTK.Platform.Linux TouchFrame } + enum KeyState + { + Released = 0, + Pressed = 1 + } + [StructLayout(LayoutKind.Sequential)] class InputInterface { @@ -162,5 +171,33 @@ namespace OpenTK.Platform.Linux close = Marshal.GetFunctionPointerForDelegate(close_restricted); } } + + [StructLayout(LayoutKind.Sequential)] + struct KeyboardEvent + { + IntPtr @event; + + public IntPtr BaseEvent { get { return GetBaseEvent(@event); } } + public IntPtr Event { get { return @event; } } + public uint Key { get { return GetKey(@event); } } + public uint KeyCount { get { return GetSeatKeyCount(@event); } } + public KeyState KeyState { get { return GetKeyState(@event); } } + public uint Time { get { return GetTime(@event); } } + + [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_time", CallingConvention = CallingConvention.Cdecl)] + static extern uint GetTime(IntPtr @event); + + [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_key", CallingConvention = CallingConvention.Cdecl)] + static extern uint GetKey(IntPtr @event); + + [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_key_state", CallingConvention = CallingConvention.Cdecl)] + static extern KeyState GetKeyState(IntPtr @event); + + [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_base_event", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr GetBaseEvent(IntPtr @event); + + [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_seat_key_count", CallingConvention = CallingConvention.Cdecl)] + static extern uint GetSeatKeyCount(IntPtr @event); + } } diff --git a/Source/OpenTK/Platform/Linux/LinuxInput.cs b/Source/OpenTK/Platform/Linux/LinuxInput.cs index d3853d82..917fb72c 100644 --- a/Source/OpenTK/Platform/Linux/LinuxInput.cs +++ b/Source/OpenTK/Platform/Linux/LinuxInput.cs @@ -90,6 +90,7 @@ namespace OpenTK.Platform.Linux public MouseState State; } + static readonly Key[] KeyMap = Evdev.KeyMap; DeviceCollection Keyboards = new DeviceCollection(); DeviceCollection Mice = new DeviceCollection(); @@ -105,7 +106,7 @@ namespace OpenTK.Platform.Linux { Debug.Print("[Linux] Initializing {0}", GetType().Name); - input_thread = new Thread(ProcessEvents); + input_thread = new Thread(InputThreadLoop); input_thread.IsBackground = true; // Todo: add static path fallback when udev is not installed. @@ -130,7 +131,9 @@ namespace OpenTK.Platform.Linux String.Format("[Input] LibInput.GetFD({0:x}) failed.", input_context)); } - input_thread.Start(); + ProcessEvents(input_context); + LibInput.Resume(input_context); + //input_thread.Start(); } #region Private Members @@ -152,55 +155,18 @@ namespace OpenTK.Platform.Linux return fd; } - void ProcessEvents() + void InputThreadLoop() { PollFD poll_fd = new PollFD(); poll_fd.fd = fd; poll_fd.events = PollFlags.In; - LibInput.Resume(input_context); - while (Interlocked.Read(ref exit) == 0) { int ret = Libc.poll(ref poll_fd, 1, -1); if (ret > 0 && (poll_fd.revents & PollFlags.In) != 0) { - // Data available - ret = LibInput.Dispatch(input_context); - if (ret != 0) - { - Debug.Print("[Input] LibInput.Dispatch({0:x}) failed. Error: {1}", - input_context, ret); - continue; - } - - IntPtr pevent = LibInput.GetEvent(input_context); - if (pevent == IntPtr.Zero) - { - Debug.Print("[Input] LibInput.GetEvent({0:x}) failed.", - input_context); - continue; - } - - IntPtr device = LibInput.GetDevice(pevent); - InputEventType type = LibInput.GetEventType(pevent); - switch (type) - { - case InputEventType.DeviceAdded: - HandleDeviceAdded(input_context, device); - break; - - case InputEventType.DeviceRemoved: - HandleDeviceRemoved(input_context, device); - break; - - case InputEventType.KeyboardKey: - HandleKeyboard(input_context, device); - break; - } - Debug.WriteLine(type.ToString()); - - LibInput.DestroyEvent(pevent); + ProcessEvents(input_context); } else if (ret < 0) { @@ -212,12 +178,55 @@ namespace OpenTK.Platform.Linux } } + void ProcessEvents(IntPtr input_context) + { + // Process all events in the event queue + while (true) + { + // Data available + int ret = LibInput.Dispatch(input_context); + if (ret != 0) + { + Debug.Print("[Input] LibInput.Dispatch({0:x}) failed. Error: {1}", + input_context, ret); + break; + } + + IntPtr pevent = LibInput.GetEvent(input_context); + if (pevent == IntPtr.Zero) + { + break; + } + + IntPtr device = LibInput.GetDevice(pevent); + InputEventType type = LibInput.GetEventType(pevent); + Debug.Print(type.ToString()); + switch (type) + { + case InputEventType.DeviceAdded: + HandleDeviceAdded(input_context, device); + break; + + case InputEventType.DeviceRemoved: + HandleDeviceRemoved(input_context, device); + break; + + case InputEventType.KeyboardKey: + HandleKeyboard(input_context, device, LibInput.GetKeyboardEvent(pevent)); + break; + } + + LibInput.DestroyEvent(pevent); + } + } + void HandleDeviceAdded(IntPtr context, IntPtr device) { if (LibInput.DeviceHasCapability(device, DeviceCapability.Keyboard)) { KeyboardDevice keyboard = new KeyboardDevice(device, Keyboards.Count); Keyboards.Add(keyboard.Id, keyboard); + Debug.Print("[Linux] libinput: added keyboard device {0}", keyboard.Id); } if (LibInput.DeviceHasCapability(device, DeviceCapability.Mouse)) @@ -240,13 +249,20 @@ namespace OpenTK.Platform.Linux } } - void HandleKeyboard(IntPtr context, IntPtr device) + void HandleKeyboard(IntPtr context, IntPtr device, KeyboardEvent e) { int id = GetId(device); KeyboardDevice keyboard = Keyboards.FromHardwareId(id); if (keyboard != null) { - // Todo: update keyboard state + Key key = Key.Unknown; + uint raw = e.Key; + if (raw >= 0 && raw < KeyMap.Length) + { + key = KeyMap[raw]; + } + + keyboard.State.SetKeyState(key, e.KeyState == KeyState.Pressed); } else { @@ -265,6 +281,7 @@ namespace OpenTK.Platform.Linux KeyboardState IKeyboardDriver2.GetState() { + ProcessEvents(input_context); KeyboardState state = new KeyboardState(); foreach (KeyboardDevice keyboard in Keyboards) { @@ -275,6 +292,7 @@ namespace OpenTK.Platform.Linux KeyboardState IKeyboardDriver2.GetState(int index) { + ProcessEvents(input_context); KeyboardDevice device = Keyboards.FromIndex(index); if (device != null) { diff --git a/Source/OpenTK/Platform/Linux/LinuxKeyboardTTY.cs b/Source/OpenTK/Platform/Linux/LinuxKeyboardTTY.cs index 63b80952..afe66bc1 100644 --- a/Source/OpenTK/Platform/Linux/LinuxKeyboardTTY.cs +++ b/Source/OpenTK/Platform/Linux/LinuxKeyboardTTY.cs @@ -199,301 +199,7 @@ namespace OpenTK.Platform.Linux return KeyMap[k]; } - #region KeyMap - - static readonly Key[] KeyMap = new Key[] - { - // 0-7 - Key.Unknown, - Key.Escape, - Key.Number1, - Key.Number2, - Key.Number3, - Key.Number4, - Key.Number5, - Key.Number6, - // 8-15 - Key.Number7, - Key.Number8, - Key.Number9, - Key.Number0, - Key.Minus, - Key.Plus, - Key.BackSpace, - Key.Tab, - // 16-23 - Key.Q, - Key.W, - Key.E, - Key.R, - Key.T, - Key.Y, - Key.U, - Key.I, - // 24-31 - Key.O, - Key.P, - Key.BracketLeft, - Key.BracketRight, - Key.Enter, - Key.ControlLeft, - Key.A, - Key.S, - // 32-39 - Key.D, - Key.F, - Key.G, - Key.H, - Key.J, - Key.K, - Key.L, - Key.Semicolon, - // 40-47 - Key.Quote, - Key.Tilde, - Key.ShiftLeft, - Key.BackSlash, //Key.Execute, - Key.Z, - Key.X, - Key.C, - Key.V, //Key.Help, - // 48-55 - Key.B, - Key.N, - Key.M, - Key.Comma, - Key.Period, - Key.Slash, - Key.ShiftRight, - Key.KeypadMultiply, - // 56-63 - Key.AltLeft, - Key.Space, - Key.CapsLock, - Key.F1, - Key.F2, - Key.F3, - Key.F4, - Key.F5, - // 64-71 - Key.F6, - Key.F7, - Key.F8, - Key.F9, - Key.F10, - Key.NumLock, - Key.ScrollLock, - Key.Keypad7, - // 72-79 - Key.Keypad8, - Key.Keypad9, - Key.KeypadSubtract, - Key.Keypad4, - Key.Keypad5, - Key.Keypad6, - Key.KeypadPlus, - Key.Keypad1, - // 80-87 - Key.Keypad2, - Key.Keypad3, - Key.Keypad0, - Key.KeypadPeriod, - Key.Unknown, - Key.Unknown, // Zzenkakuhankaku - Key.Unknown, // 102ND - Key.F11, - // 88-95 - Key.F12, - Key.Unknown, // ro - Key.Unknown, // katakana - Key.Unknown, // hiragana - Key.Unknown, // henkan - Key.Unknown, // katakanahiragana - Key.Unknown, // muhenkan - Key.Unknown, // kpjpcomma - // 96-103 - Key.KeypadEnter, - Key.ControlRight, - Key.KeypadDivide, - Key.Unknown, // sysrq - Key.AltRight, - Key.Unknown, // linefeed - Key.Home, - Key.Up, - // 104-111 - Key.PageUp, - Key.Left, - Key.Right, - Key.End, - Key.Down, - Key.PageDown, - Key.Insert, - Key.Delete, - // 112-119 - Key.Unknown, // macro - Key.Unknown, // mute - Key.Unknown, // volumedown - Key.Unknown, // volumeup - Key.Unknown, // power - Key.Unknown, // kpequal - Key.Unknown, // kpplusminus - Key.Pause, - // 120-127 - Key.Unknown, // scale - Key.Unknown, // kpcomma - Key.Unknown, // hangeul / hanguel - Key.Unknown, // hanja - Key.Unknown, // yen - Key.WinLeft, - Key.WinRight, - Key.Unknown, // compose - // 128-135 - Key.Unknown, // stop - Key.Unknown, // again - Key.Unknown, // props - Key.Unknown, // undo - Key.Unknown, // front - Key.Unknown, // copy - Key.Unknown, // open - Key.Unknown, // paste - // 136-143 - Key.Unknown, // find - Key.Unknown, // cut - Key.Unknown, // help - Key.Unknown, // menu - Key.Unknown, // calc - Key.Unknown, // setup - Key.Unknown, // sleep - Key.Unknown, // wakeup - // 144-151 - Key.Unknown, // file - Key.Unknown, // send file - Key.Unknown, // delete file - Key.Unknown, // xfer - Key.Unknown, // prog1 - Key.Unknown, // prog2 - Key.Unknown, // www - Key.Unknown, // msdos - // 152-159 - Key.Unknown, // coffee / screenlock - Key.Unknown, // direction - Key.Unknown, // cycle windows - Key.Unknown, // mail - Key.Unknown, // bookmarks - Key.Unknown, // computer - Key.Back, - Key.Unknown, // forward - // 160-167 - Key.Unknown, // close cd - Key.Unknown, // eject cd - Key.Unknown, // eject/close cd - Key.Unknown, // next song - Key.Unknown, // play/pause - Key.Unknown, // previous song - Key.Unknown, // stop cd - Key.Unknown, // record - // 168-175 - Key.Unknown, // rewind - Key.Unknown, // phone - Key.Unknown, // iso - Key.Unknown, // config - Key.Unknown, // homepage - Key.Unknown, // refresh - Key.Unknown, // exit - Key.Unknown, // move, - // 176-183 - Key.Unknown, // edit, - Key.Unknown, // scroll up, - Key.Unknown, // scroll down, - Key.Unknown, // kp left paren, - Key.Unknown, // kp right paren, - Key.Unknown, // new, - Key.Unknown, // redo, - Key.F13, - // 184-191 - Key.F14, - Key.F15, - Key.F16, - Key.F17, - Key.F18, - Key.F19, - Key.F20, - Key.F21, - // 192-199 - Key.F22, - Key.F23, - Key.F24, - Key.Unknown, - Key.Unknown, - Key.Unknown, - Key.Unknown, - Key.Unknown, - // 200-207 - Key.Unknown, // play cd - Key.Unknown, // pause cd - Key.Unknown, // prog3 - Key.Unknown, // prog4 - Key.Unknown, // dashboard - Key.Unknown, // suspend - Key.Unknown, // close - Key.Unknown, // play - // 208-215 - Key.Unknown, // fast forward - Key.Unknown, // bass boost - Key.Unknown, // print - Key.Unknown, // hp - Key.Unknown, // camera - Key.Unknown, // sound - Key.Unknown, // question - Key.Unknown, // email - // 216-223 - Key.Unknown, // chat - Key.Unknown, // search - Key.Unknown, // connect - Key.Unknown, // finance - Key.Unknown, // sport - Key.Unknown, // shop - Key.Unknown, // alt erase - Key.Unknown, // cancel - // 224-231 - Key.Unknown, // brightness down - Key.Unknown, // brightness up - Key.Unknown, // media - Key.Unknown, // switch video mode - Key.Unknown, // dillum toggle - Key.Unknown, // dillum down - Key.Unknown, // dillum up - Key.Unknown, // send - // 232-239 - Key.Unknown, // reply - Key.Unknown, // forward email - Key.Unknown, // save - Key.Unknown, // documents - Key.Unknown, // battery - Key.Unknown, // bluetooth - Key.Unknown, // wlan - Key.Unknown, // uwb - // 240-247 - Key.Unknown, - Key.Unknown, // video next - Key.Unknown, // video prev - Key.Unknown, // brightness cycle - Key.Unknown, // brightness zero - Key.Unknown, // display off - Key.Unknown, // wwan / wimax - Key.Unknown, // rfkill - // 248-255 - Key.Unknown, // mic mute - Key.Unknown, - Key.Unknown, - Key.Unknown, - Key.Unknown, - Key.Unknown, - Key.Unknown, - Key.Unknown, // reserved - }; - - #endregion + static readonly Key[] KeyMap = Evdev.KeyMap; #endregion