LCOV - code coverage report
Current view: top level - widget/gtk - nsGtkKeyUtils.h (source / functions) Hit Total Coverage
Test: output.info Lines: 3 3 100.0 %
Date: 2017-07-14 16:53:18 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* vim:expandtab:shiftwidth=4:tabstop=4:
       3             :  */
       4             : /* This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : #ifndef __nsGdkKeyUtils_h__
       9             : #define __nsGdkKeyUtils_h__
      10             : 
      11             : #include "nsTArray.h"
      12             : #include "mozilla/EventForwards.h"
      13             : 
      14             : #include <gdk/gdk.h>
      15             : #include <X11/XKBlib.h>
      16             : 
      17             : namespace mozilla {
      18             : namespace widget {
      19             : 
      20             : /**
      21             :  *  KeymapWrapper is a wrapper class of GdkKeymap.  GdkKeymap doesn't support
      22             :  *  all our needs, therefore, we need to access lower level APIs.
      23             :  *  But such code is usually complex and might be slow.  Against such issues,
      24             :  *  we should cache some information.
      25             :  *
      26             :  *  This class provides only static methods.  The methods is using internal
      27             :  *  singleton instance which is initialized by default GdkKeymap.  When the
      28             :  *  GdkKeymap is destroyed, the singleton instance will be destroyed.
      29             :  */
      30             : 
      31             : class KeymapWrapper
      32             : {
      33             : public:
      34             :     /**
      35             :      * Compute an our DOM keycode from a GDK keyval.
      36             :      */
      37             :     static uint32_t ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent);
      38             : 
      39             :     /**
      40             :      * Compute a DOM key name index from aGdkKeyEvent.
      41             :      */
      42             :     static KeyNameIndex ComputeDOMKeyNameIndex(const GdkEventKey* aGdkKeyEvent);
      43             : 
      44             :     /**
      45             :      * Compute a DOM code name index from aGdkKeyEvent.
      46             :      */
      47             :     static CodeNameIndex ComputeDOMCodeNameIndex(
      48             :                            const GdkEventKey* aGdkKeyEvent);
      49             : 
      50             :     /**
      51             :      * Modifier is list of modifiers which we support in widget level.
      52             :      */
      53             :     enum Modifier {
      54             :         NOT_MODIFIER       = 0x0000,
      55             :         CAPS_LOCK          = 0x0001,
      56             :         NUM_LOCK           = 0x0002,
      57             :         SCROLL_LOCK        = 0x0004,
      58             :         SHIFT              = 0x0008,
      59             :         CTRL               = 0x0010,
      60             :         ALT                = 0x0020,
      61             :         META               = 0x0040,
      62             :         SUPER              = 0x0080,
      63             :         HYPER              = 0x0100,
      64             :         LEVEL3             = 0x0200,
      65             :         LEVEL5             = 0x0400
      66             :     };
      67             : 
      68             :     /**
      69             :      * Modifiers is used for combination of Modifier.
      70             :      * E.g., |Modifiers modifiers = (SHIFT | CTRL);| means Shift and Ctrl.
      71             :      */
      72             :     typedef uint32_t Modifiers;
      73             : 
      74             :     /**
      75             :      * GetCurrentModifierState() returns current modifier key state.
      76             :      * The "current" means actual state of hardware keyboard when this is
      77             :      * called.  I.e., if some key events are not still dispatched by GDK,
      78             :      * the state may mismatch with GdkEventKey::state.
      79             :      *
      80             :      * @return                  Current modifier key state.
      81             :      */
      82             :     static guint GetCurrentModifierState();
      83             : 
      84             :     /**
      85             :      * AreModifiersCurrentlyActive() checks the "current" modifier state
      86             :      * on aGdkWindow with the keymap of the singleton instance.
      87             :      *
      88             :      * @param aModifiers        One or more of Modifier values except
      89             :      *                          NOT_MODIFIER.
      90             :      * @return                  TRUE if all of modifieres in aModifiers are
      91             :      *                          active.  Otherwise, FALSE.
      92             :      */
      93             :     static bool AreModifiersCurrentlyActive(Modifiers aModifiers);
      94             : 
      95             :     /**
      96             :      * AreModifiersActive() just checks whether aModifierState indicates
      97             :      * all modifiers in aModifiers are active or not.
      98             :      *
      99             :      * @param aModifiers        One or more of Modifier values except
     100             :      *                          NOT_MODIFIER.
     101             :      * @param aModifierState    GDK's modifier states.
     102             :      * @return                  TRUE if aGdkModifierType indecates all of
     103             :      *                          modifiers in aModifier are active.
     104             :      *                          Otherwise, FALSE.
     105             :      */
     106             :     static bool AreModifiersActive(Modifiers aModifiers,
     107             :                                    guint aModifierState);
     108             : 
     109             :     /**
     110             :      * Utility function to compute current keyboard modifiers for
     111             :      * WidgetInputEvent
     112             :      */
     113             :     static uint32_t ComputeCurrentKeyModifiers();
     114             : 
     115             :     /**
     116             :      * Utility function to covert platform modifier state to keyboard modifiers
     117             :      * of WidgetInputEvent
     118             :      */
     119             :     static uint32_t ComputeKeyModifiers(guint aModifierState);
     120             : 
     121             :     /**
     122             :      * InitInputEvent() initializes the aInputEvent with aModifierState.
     123             :      */
     124             :     static void InitInputEvent(WidgetInputEvent& aInputEvent,
     125             :                                guint aModifierState);
     126             : 
     127             :     /**
     128             :      * InitKeyEvent() intializes aKeyEvent's modifier key related members
     129             :      * and keycode related values.
     130             :      *
     131             :      * @param aKeyEvent         It's an WidgetKeyboardEvent which needs to be
     132             :      *                          initialized.
     133             :      * @param aGdkKeyEvent      A native GDK key event.
     134             :      */
     135             :     static void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent,
     136             :                              GdkEventKey* aGdkKeyEvent);
     137             : 
     138             :     /**
     139             :      * WillDispatchKeyboardEvent() is called via
     140             :      * TextEventDispatcherListener::WillDispatchKeyboardEvent().
     141             :      *
     142             :      * @param aKeyEvent         An instance of KeyboardEvent which will be
     143             :      *                          dispatched.  This method should set charCode
     144             :      *                          and alternative char codes if it's necessary.
     145             :      * @param aGdkKeyEvent      A GdkEventKey instance which caused the
     146             :      *                          aKeyEvent.
     147             :      */
     148             :     static void WillDispatchKeyboardEvent(WidgetKeyboardEvent& aKeyEvent,
     149             :                                           GdkEventKey* aGdkKeyEvent);
     150             : 
     151             :     /**
     152             :      * Destroys the singleton KeymapWrapper instance, if it exists.
     153             :      */
     154             :     static void Shutdown();
     155             : 
     156             : protected:
     157             : 
     158             :     /**
     159             :      * GetInstance() returns a KeymapWrapper instance.
     160             :      *
     161             :      * @return                  A singleton instance of KeymapWrapper.
     162             :      */
     163             :     static KeymapWrapper* GetInstance();
     164             : 
     165             :     KeymapWrapper();
     166             :     ~KeymapWrapper();
     167             : 
     168             :     bool mInitialized;
     169             : 
     170             :     /**
     171             :      * Initializing methods.
     172             :      */
     173             :     void Init();
     174             :     void InitXKBExtension();
     175             :     void InitBySystemSettings();
     176             : 
     177             :     /**
     178             :      * mModifierKeys stores each hardware key information.
     179             :      */
     180             :     struct ModifierKey {
     181             :         guint mHardwareKeycode;
     182             :         guint mMask;
     183             : 
     184          14 :         explicit ModifierKey(guint aHardwareKeycode) :
     185          14 :           mHardwareKeycode(aHardwareKeycode), mMask(0)
     186             :         {
     187          14 :         }
     188             :     };
     189             :     nsTArray<ModifierKey> mModifierKeys;
     190             : 
     191             :     /**
     192             :      * GetModifierKey() returns modifier key information of the hardware
     193             :      * keycode.  If the key isn't a modifier key, returns nullptr.
     194             :      */
     195             :     ModifierKey* GetModifierKey(guint aHardwareKeycode);
     196             : 
     197             :     /**
     198             :      * mModifierMasks is bit masks for each modifier.  The index should be one
     199             :      * of ModifierIndex values.
     200             :      */
     201             :     enum ModifierIndex {
     202             :         INDEX_NUM_LOCK,
     203             :         INDEX_SCROLL_LOCK,
     204             :         INDEX_ALT,
     205             :         INDEX_META,
     206             :         INDEX_SUPER,
     207             :         INDEX_HYPER,
     208             :         INDEX_LEVEL3,
     209             :         INDEX_LEVEL5,
     210             :         COUNT_OF_MODIFIER_INDEX
     211             :     };
     212             :     guint mModifierMasks[COUNT_OF_MODIFIER_INDEX];
     213             : 
     214             :     guint GetModifierMask(Modifier aModifier) const;
     215             : 
     216             :     /**
     217             :      * @param aGdkKeyval        A GDK defined modifier key value such as
     218             :      *                          GDK_Shift_L.
     219             :      * @return                  Returns Modifier values for aGdkKeyval.
     220             :      *                          If the given key code isn't a modifier key,
     221             :      *                          returns NOT_MODIFIER.
     222             :      */
     223             :     static Modifier GetModifierForGDKKeyval(guint aGdkKeyval);
     224             : 
     225             :     static const char* GetModifierName(Modifier aModifier);
     226             : 
     227             :     /**
     228             :      * mGdkKeymap is a wrapped instance by this class.
     229             :      */
     230             :     GdkKeymap* mGdkKeymap;
     231             : 
     232             :     /**
     233             :      * The base event code of XKB extension.
     234             :      */
     235             :     int mXKBBaseEventCode;
     236             : 
     237             :     /**
     238             :      * Only auto_repeats[] stores valid value.  If you need to use other
     239             :      * members, you need to listen notification events for them.
     240             :      * See a call of XkbSelectEventDetails() with XkbControlsNotify in
     241             :      * InitXKBExtension().
     242             :      */
     243             :     XKeyboardState mKeyboardState;
     244             : 
     245             :     /**
     246             :      * Pointer of the singleton instance.
     247             :      */
     248             :     static KeymapWrapper* sInstance;
     249             : 
     250             :     /**
     251             :      * Auto key repeat management.
     252             :      */
     253             :     static guint sLastRepeatableHardwareKeyCode;
     254             :     enum RepeatState
     255             :     {
     256             :         NOT_PRESSED,
     257             :         FIRST_PRESS,
     258             :         REPEATING
     259             :     };
     260             :     static RepeatState sRepeatState;
     261             : 
     262             :     /**
     263             :      * IsAutoRepeatableKey() returns true if the key supports auto repeat.
     264             :      * Otherwise, false.
     265             :      */
     266             :     bool IsAutoRepeatableKey(guint aHardwareKeyCode);
     267             : 
     268             :     /**
     269             :      * Signal handlers.
     270             :      */
     271             :     static void OnKeysChanged(GdkKeymap* aKeymap, KeymapWrapper* aKeymapWrapper);
     272             :     static void OnDirectionChanged(GdkKeymap *aGdkKeymap,
     273             :                                    KeymapWrapper* aKeymapWrapper);
     274             : 
     275             :     /**
     276             :      * GetCharCodeFor() Computes what character is inputted by the key event
     277             :      * with aModifierState and aGroup.
     278             :      *
     279             :      * @param aGdkKeyEvent      Native key event, must not be nullptr.
     280             :      * @param aModifierState    Combination of GdkModifierType which you
     281             :      *                          want to test with aGdkKeyEvent.
     282             :      * @param aGroup            Set group in the mGdkKeymap.
     283             :      * @return                  charCode which is inputted by aGdkKeyEvent.
     284             :      *                          If failed, this returns 0.
     285             :      */
     286             :     static uint32_t GetCharCodeFor(const GdkEventKey *aGdkKeyEvent);
     287             :     uint32_t GetCharCodeFor(const GdkEventKey *aGdkKeyEvent,
     288             :                             guint aModifierState,
     289             :                             gint aGroup);
     290             : 
     291             :     /**
     292             :      * GetUnmodifiedCharCodeFor() computes what character is inputted by the
     293             :      * key event without Ctrl/Alt/Meta/Super/Hyper modifiers.
     294             :      * If Level3 or Level5 Shift causes no character input, this also ignores
     295             :      * them.
     296             :      *
     297             :      * @param aGdkKeyEvent      Native key event, must not be nullptr.
     298             :      * @return                  charCode which is computed without modifiers
     299             :      *                          which prevent text input.
     300             :      */
     301             :     uint32_t GetUnmodifiedCharCodeFor(const GdkEventKey* aGdkKeyEvent);
     302             : 
     303             :     /**
     304             :      * GetKeyLevel() returns level of the aGdkKeyEvent in mGdkKeymap.
     305             :      *
     306             :      * @param aGdkKeyEvent      Native key event, must not be nullptr.
     307             :      * @return                  Using level.  Typically, this is 0 or 1.
     308             :      *                          If failed, this returns -1.
     309             :      */
     310             :     gint GetKeyLevel(GdkEventKey *aGdkKeyEvent);
     311             : 
     312             :     /**
     313             :      * GetFirstLatinGroup() returns group of mGdkKeymap which can input an
     314             :      * ASCII character by GDK_A.
     315             :      *
     316             :      * @return                  group value of GdkEventKey.
     317             :      */
     318             :     gint GetFirstLatinGroup();
     319             : 
     320             :     /**
     321             :      * IsLatinGroup() checkes whether the keyboard layout of aGroup is
     322             :      * ASCII alphabet inputtable or not.
     323             :      *
     324             :      * @param aGroup            The group value of GdkEventKey.
     325             :      * @return                  TRUE if the keyboard layout can input
     326             :      *                          ASCII alphabet.  Otherwise, FALSE.
     327             :      */
     328             :     bool IsLatinGroup(guint8 aGroup);
     329             : 
     330             :     /**
     331             :      * IsBasicLatinLetterOrNumeral() Checks whether the aCharCode is an
     332             :      * alphabet or a numeric character in ASCII.
     333             :      *
     334             :      * @param aCharCode         Charcode which you want to test.
     335             :      * @return                  TRUE if aCharCode is an alphabet or a numeric
     336             :      *                          in ASCII range.  Otherwise, FALSE.
     337             :      */
     338             :     static bool IsBasicLatinLetterOrNumeral(uint32_t aCharCode);
     339             : 
     340             :     /**
     341             :      * GetGDKKeyvalWithoutModifier() returns the keyval for aGdkKeyEvent when
     342             :      * ignoring the modifier state except NumLock. (NumLock is a key to change
     343             :      * some key's meaning.)
     344             :      */
     345             :     static guint GetGDKKeyvalWithoutModifier(const GdkEventKey *aGdkKeyEvent);
     346             : 
     347             :     /**
     348             :      * GetDOMKeyCodeFromKeyPairs() returns DOM keycode for aGdkKeyval if
     349             :      * it's in KeyPair table.
     350             :      */
     351             :     static uint32_t GetDOMKeyCodeFromKeyPairs(guint aGdkKeyval);
     352             : 
     353             :     /**
     354             :      * FilterEvents() listens all events on all our windows.
     355             :      * Be careful, this may make damage to performance if you add expensive
     356             :      * code in this method.
     357             :      */
     358             :     static GdkFilterReturn FilterEvents(GdkXEvent* aXEvent,
     359             :                                         GdkEvent* aGdkEvent,
     360             :                                         gpointer aData);
     361             : 
     362             :     /**
     363             :      * See the document of WillDispatchKeyboardEvent().
     364             :      */
     365             :     void WillDispatchKeyboardEventInternal(WidgetKeyboardEvent& aKeyEvent,
     366             :                                            GdkEventKey* aGdkKeyEvent);
     367             : };
     368             : 
     369             : } // namespace widget
     370             : } // namespace mozilla
     371             : 
     372             : #endif /* __nsGdkKeyUtils_h__ */

Generated by: LCOV version 1.13