Example #1
0
        public X11Keyboard()
        {
            Debug.WriteLine("Using X11Keyboard.");
            state.IsConnected = true;

            IntPtr display = API.DefaultDisplay;

            using (new XLock(display))
            {
                // Find the number of keysyms per keycode.
                int first = 0, last = 0;
                API.DisplayKeycodes(display, ref first, ref last);
                IntPtr keysym_ptr =
                    API.GetKeyboardMapping(display,
                                           (byte)first,
                                           last - first + 1,
                                           ref KeysymsPerKeycode);
                Functions.XFree(keysym_ptr);

                if (Xkb.IsSupported(display))
                {
                    // Request that auto-repeat is only set on devices that support it physically.
                    // This typically means that it's turned off for keyboards what we want).
                    // We prefer this method over XAutoRepeatOff/On, because the latter needs to
                    // be reset before the program exits.
                    bool supported;
                    Xkb.SetDetectableAutoRepeat(display, true, out supported);
                    KeyMap = new X11KeyMap(display);
                }
            }
        }
Example #2
0
 internal X11KeyMap(IntPtr display)
 {
     xkb_supported = Xkb.IsSupported(display);
     if (xkb_supported)
     {
         RefreshKeycodes(display);
     }
 }
Example #3
0
        private bool TranslateKeyXkb(IntPtr display, int keycode, out Key key)
        {
            if (keycode < 8 || keycode > 255)
            {
                key = Key.Unknown;
                return(false);
            }

            // Translate the numeric keypad using the secondary group
            // (equivalent to NumLock = on)
            XKey keysym = Xkb.KeycodeToKeysym(display, keycode, 0, 1);

            switch (keysym)
            {
            case XKey.KP_0: key = Key.Keypad0; return(true);

            case XKey.KP_1: key = Key.Keypad1; return(true);

            case XKey.KP_2: key = Key.Keypad2; return(true);

            case XKey.KP_3: key = Key.Keypad3; return(true);

            case XKey.KP_4: key = Key.Keypad4; return(true);

            case XKey.KP_5: key = Key.Keypad5; return(true);

            case XKey.KP_6: key = Key.Keypad6; return(true);

            case XKey.KP_7: key = Key.Keypad7; return(true);

            case XKey.KP_8: key = Key.Keypad8; return(true);

            case XKey.KP_9: key = Key.Keypad9; return(true);

            case XKey.KP_Separator:
            case XKey.KP_Decimal: key = Key.KeypadDecimal; return(true);

            case XKey.KP_Equal: key = Key.Unknown; return(false);    // Todo: fixme

            case XKey.KP_Enter: key = Key.KeypadEnter; return(true);
            }

            // Translate non-alphanumeric keys using the primary group
            keysym = Xkb.KeycodeToKeysym(display, keycode, 0, 0);
            key    = TranslateXKey(keysym);
            return(key != Key.Unknown);
        }
Example #4
0
        // Refreshes the keycodes lookup table based
        // on the current keyboard layout.
        internal void RefreshKeycodes(IntPtr display)
        {
            // Approach inspired by GLFW: http://www.glfw.org/
            // Huge props to the GLFW team!
            if (xkb_supported)
            {
                unsafe
                {
                    // Xkb.GetKeyboard appears to be broken (multiple bug reports across distros)
                    // so use Xkb.AllocKeyboard with Xkb.GetNames instead.
                    XkbDesc *keyboard = Xkb.AllocKeyboard(display);
                    if (keyboard != null)
                    {
                        Xkb.GetNames(display, XkbNamesMask.All, keyboard);

                        for (int i = 0; i < keycodes.Length; i++)
                        {
                            keycodes[i] = Key.Unknown;
                        }

                        // Map all alphanumeric keys of this layout
                        // Symbols are handled in GetKey() instead.
                        for (int i = keyboard->min_key_code; i <= keyboard->max_key_code; ++i)
                        {
                            string name = new string((sbyte *)keyboard->names->keys[i].name, 0, Xkb.KeyNameLength);

                            Key key = Key.Unknown;
                            switch (name)
                            {
                            case "TLDE":
                                key = Key.Tilde;
                                break;

                            case "AE01":
                                key = Key.Number1;
                                break;

                            case "AE02":
                                key = Key.Number2;
                                break;

                            case "AE03":
                                key = Key.Number3;
                                break;

                            case "AE04":
                                key = Key.Number4;
                                break;

                            case "AE05":
                                key = Key.Number5;
                                break;

                            case "AE06":
                                key = Key.Number6;
                                break;

                            case "AE07":
                                key = Key.Number7;
                                break;

                            case "AE08":
                                key = Key.Number8;
                                break;

                            case "AE09":
                                key = Key.Number9;
                                break;

                            case "AE10":
                                key = Key.Number0;
                                break;

                            case "AE11":
                                key = Key.Minus;
                                break;

                            case "AE12":
                                key = Key.Plus;
                                break;

                            case "AD01":
                                key = Key.Q;
                                break;

                            case "AD02":
                                key = Key.W;
                                break;

                            case "AD03":
                                key = Key.E;
                                break;

                            case "AD04":
                                key = Key.R;
                                break;

                            case "AD05":
                                key = Key.T;
                                break;

                            case "AD06":
                                key = Key.Y;
                                break;

                            case "AD07":
                                key = Key.U;
                                break;

                            case "AD08":
                                key = Key.I;
                                break;

                            case "AD09":
                                key = Key.O;
                                break;

                            case "AD10":
                                key = Key.P;
                                break;

                            case "AD11":
                                key = Key.BracketLeft;
                                break;

                            case "AD12":
                                key = Key.BracketRight;
                                break;

                            case "AC01":
                                key = Key.A;
                                break;

                            case "AC02":
                                key = Key.S;
                                break;

                            case "AC03":
                                key = Key.D;
                                break;

                            case "AC04":
                                key = Key.F;
                                break;

                            case "AC05":
                                key = Key.G;
                                break;

                            case "AC06":
                                key = Key.H;
                                break;

                            case "AC07":
                                key = Key.J;
                                break;

                            case "AC08":
                                key = Key.K;
                                break;

                            case "AC09":
                                key = Key.L;
                                break;

                            case "AC10":
                                key = Key.Semicolon;
                                break;

                            case "AC11":
                                key = Key.Quote;
                                break;

                            case "AB01":
                                key = Key.Z;
                                break;

                            case "AB02":
                                key = Key.X;
                                break;

                            case "AB03":
                                key = Key.C;
                                break;

                            case "AB04":
                                key = Key.V;
                                break;

                            case "AB05":
                                key = Key.B;
                                break;

                            case "AB06":
                                key = Key.N;
                                break;

                            case "AB07":
                                key = Key.M;
                                break;

                            case "AB08":
                                key = Key.Comma;
                                break;

                            case "AB09":
                                key = Key.Period;
                                break;

                            case "AB10":
                                key = Key.Slash;
                                break;

                            case "BKSL":
                                key = Key.BackSlash;
                                break;

                            case "LSGT":
                                key = Key.Unknown;
                                break;

                            default:
                                key = Key.Unknown;
                                break;
                            }

                            keycodes[i] = key;
                        }

                        Xkb.FreeKeyboard(keyboard, 0, true);
                    }
                }
            }

            // Translate unknown keys (and symbols) using
            // regular layout-dependent GetKey()
            for (int i = 0; i < 256; i++)
            {
                if (keycodes[i] == Key.Unknown)
                {
                    // TranslateKeyCode expects a XKeyEvent structure
                    // Make one up
                    XKeyEvent e = new XKeyEvent();
                    e.display = display;
                    e.keycode = i;
                    Key key = Key.Unknown;
                    if (TranslateKeyEvent(ref e, out key))
                    {
                        keycodes[i] = key;
                    }
                }
            }
        }