widget/gtk/nsGtkKeyUtils.h

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     8 #ifndef __nsGdkKeyUtils_h__
     9 #define __nsGdkKeyUtils_h__
    11 #include "nsTArray.h"
    12 #include "mozilla/EventForwards.h"
    14 #include <gdk/gdk.h>
    15 #include <X11/XKBlib.h>
    17 namespace mozilla {
    18 namespace widget {
    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  */
    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);
    39     /**
    40      * Compute a DOM key name index from aGdkKeyEvent.
    41      */
    42     KeyNameIndex ComputeDOMKeyNameIndex(const GdkEventKey* aGdkKeyEvent);
    44     /**
    45      * Modifier is list of modifiers which we support in widget level.
    46      */
    47     enum Modifier {
    48         NOT_MODIFIER       = 0x0000,
    49         CAPS_LOCK          = 0x0001,
    50         NUM_LOCK           = 0x0002,
    51         SCROLL_LOCK        = 0x0004,
    52         SHIFT              = 0x0008,
    53         CTRL               = 0x0010,
    54         ALT                = 0x0020,
    55         META               = 0x0040,
    56         SUPER              = 0x0080,
    57         HYPER              = 0x0100,
    58         LEVEL3             = 0x0200,
    59         LEVEL5             = 0x0400
    60     };
    62     /**
    63      * Modifiers is used for combination of Modifier.
    64      * E.g., |Modifiers modifiers = (SHIFT | CTRL);| means Shift and Ctrl.
    65      */
    66     typedef uint32_t Modifiers;
    68     /**
    69      * GetCurrentModifierState() returns current modifier key state.
    70      * The "current" means actual state of hardware keyboard when this is
    71      * called.  I.e., if some key events are not still dispatched by GDK,
    72      * the state may mismatch with GdkEventKey::state.
    73      *
    74      * @return                  Current modifier key state.
    75      */
    76     static guint GetCurrentModifierState();
    78     /**
    79      * AreModifiersCurrentlyActive() checks the "current" modifier state
    80      * on aGdkWindow with the keymap of the singleton instance.
    81      *
    82      * @param aModifiers        One or more of Modifier values except
    83      *                          NOT_MODIFIER.
    84      * @return                  TRUE if all of modifieres in aModifiers are
    85      *                          active.  Otherwise, FALSE.
    86      */
    87     static bool AreModifiersCurrentlyActive(Modifiers aModifiers);
    89     /**
    90      * AreModifiersActive() just checks whether aModifierState indicates
    91      * all modifiers in aModifiers are active or not.
    92      *
    93      * @param aModifiers        One or more of Modifier values except
    94      *                          NOT_MODIFIER.
    95      * @param aModifierState    GDK's modifier states.
    96      * @return                  TRUE if aGdkModifierType indecates all of
    97      *                          modifiers in aModifier are active.
    98      *                          Otherwise, FALSE.
    99      */
   100     static bool AreModifiersActive(Modifiers aModifiers,
   101                                    guint aModifierState);
   103     /**
   104      * InitInputEvent() initializes the aInputEvent with aModifierState.
   105      */
   106     static void InitInputEvent(WidgetInputEvent& aInputEvent,
   107                                guint aModifierState);
   109     /**
   110      * InitKeyEvent() intializes aKeyEvent's modifier key related members
   111      * and keycode related values.
   112      *
   113      * @param aKeyEvent         It's an WidgetKeyboardEvent which needs to be
   114      *                          initialized.
   115      * @param aGdkKeyEvent      A native GDK key event.
   116      */
   117     static void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent,
   118                              GdkEventKey* aGdkKeyEvent);
   120     /**
   121      * IsKeyPressEventNecessary() returns TRUE when aGdkKeyEvent should cause
   122      * a DOM keypress event.  Otherwise, FALSE.
   123      */
   124     static bool IsKeyPressEventNecessary(GdkEventKey* aGdkKeyEvent);
   126 protected:
   128     /**
   129      * GetInstance() returns a KeymapWrapper instance.
   130      *
   131      * @return                  A singleton instance of KeymapWrapper.
   132      */
   133     static KeymapWrapper* GetInstance();
   135     KeymapWrapper();
   136     ~KeymapWrapper();
   138     bool mInitialized;
   140     /**
   141      * Initializing methods.
   142      */
   143     void Init();
   144     void InitXKBExtension();
   145     void InitBySystemSettings();
   147     /**
   148      * mModifierKeys stores each hardware key information.
   149      */
   150     struct ModifierKey {
   151         guint mHardwareKeycode;
   152         guint mMask;
   154         ModifierKey(guint aHardwareKeycode) :
   155           mHardwareKeycode(aHardwareKeycode), mMask(0)
   156         {
   157         }
   158     };
   159     nsTArray<ModifierKey> mModifierKeys;
   161     /**
   162      * GetModifierKey() returns modifier key information of the hardware
   163      * keycode.  If the key isn't a modifier key, returns nullptr.
   164      */
   165     ModifierKey* GetModifierKey(guint aHardwareKeycode);
   167     /**
   168      * mModifierMasks is bit masks for each modifier.  The index should be one
   169      * of ModifierIndex values.
   170      */
   171     enum ModifierIndex {
   172         INDEX_NUM_LOCK,
   173         INDEX_SCROLL_LOCK,
   174         INDEX_ALT,
   175         INDEX_META,
   176         INDEX_SUPER,
   177         INDEX_HYPER,
   178         INDEX_LEVEL3,
   179         INDEX_LEVEL5,
   180         COUNT_OF_MODIFIER_INDEX
   181     };
   182     guint mModifierMasks[COUNT_OF_MODIFIER_INDEX];
   184     guint GetModifierMask(Modifier aModifier) const;
   186     /**
   187      * @param aGdkKeyval        A GDK defined modifier key value such as
   188      *                          GDK_Shift_L.
   189      * @return                  Returns Modifier values for aGdkKeyval.
   190      *                          If the given key code isn't a modifier key,
   191      *                          returns NOT_MODIFIER.
   192      */
   193     static Modifier GetModifierForGDKKeyval(guint aGdkKeyval);
   195 #ifdef PR_LOGGING
   196     static const char* GetModifierName(Modifier aModifier);
   197 #endif // PR_LOGGING
   199     /**
   200      * mGdkKeymap is a wrapped instance by this class.
   201      */
   202     GdkKeymap* mGdkKeymap;
   204     /**
   205      * The base event code of XKB extension.
   206      */
   207     int mXKBBaseEventCode;
   209     /**
   210      * Only auto_repeats[] stores valid value.  If you need to use other
   211      * members, you need to listen notification events for them.
   212      * See a call of XkbSelectEventDetails() with XkbControlsNotify in
   213      * InitXKBExtension().
   214      */
   215     XKeyboardState mKeyboardState;
   217     /**
   218      * Pointer of the singleton instance.
   219      */
   220     static KeymapWrapper* sInstance;
   222     /**
   223      * Auto key repeat management.
   224      */
   225     static guint sLastRepeatableHardwareKeyCode;
   226     enum RepeatState
   227     {
   228         NOT_PRESSED,
   229         FIRST_PRESS,
   230         REPEATING
   231     };
   232     static RepeatState sRepeatState;
   234     /**
   235      * IsAutoRepeatableKey() returns true if the key supports auto repeat.
   236      * Otherwise, false.
   237      */
   238     bool IsAutoRepeatableKey(guint aHardwareKeyCode);
   240     /**
   241      * Signal handlers.
   242      */
   243     static void OnKeysChanged(GdkKeymap* aKeymap, KeymapWrapper* aKeymapWrapper);
   244     static void OnDestroyKeymap(KeymapWrapper* aKeymapWrapper,
   245                                 GdkKeymap *aGdkKeymap);
   247     /**
   248      * GetCharCodeFor() Computes what character is inputted by the key event
   249      * with aModifierState and aGroup.
   250      *
   251      * @param aGdkKeyEvent      Native key event, must not be nullptr.
   252      * @param aModifierState    Combination of GdkModifierType which you
   253      *                          want to test with aGdkKeyEvent.
   254      * @param aGroup            Set group in the mGdkKeymap.
   255      * @return                  charCode which is inputted by aGdkKeyEvent.
   256      *                          If failed, this returns 0.
   257      */
   258     static uint32_t GetCharCodeFor(const GdkEventKey *aGdkKeyEvent);
   259     uint32_t GetCharCodeFor(const GdkEventKey *aGdkKeyEvent,
   260                             guint aModifierState,
   261                             gint aGroup);
   263     /**
   264      * GetUnmodifiedCharCodeFor() computes what character is inputted by the
   265      * key event without Ctrl/Alt/Meta/Super/Hyper modifiers.
   266      * If Level3 or Level5 Shift causes no character input, this also ignores
   267      * them.
   268      *
   269      * @param aGdkKeyEvent      Native key event, must not be nullptr.
   270      * @return                  charCode which is computed without modifiers
   271      *                          which prevent text input.
   272      */
   273     uint32_t GetUnmodifiedCharCodeFor(const GdkEventKey* aGdkKeyEvent);
   275     /**
   276      * GetKeyLevel() returns level of the aGdkKeyEvent in mGdkKeymap.
   277      *
   278      * @param aGdkKeyEvent      Native key event, must not be nullptr.
   279      * @return                  Using level.  Typically, this is 0 or 1.
   280      *                          If failed, this returns -1.
   281      */
   282     gint GetKeyLevel(GdkEventKey *aGdkKeyEvent);
   284     /**
   285      * GetFirstLatinGroup() returns group of mGdkKeymap which can input an
   286      * ASCII character by GDK_A.
   287      *
   288      * @return                  group value of GdkEventKey.
   289      */
   290     gint GetFirstLatinGroup();
   292     /**
   293      * IsLatinGroup() checkes whether the keyboard layout of aGroup is
   294      * ASCII alphabet inputtable or not.
   295      *
   296      * @param aGroup            The group value of GdkEventKey.
   297      * @return                  TRUE if the keyboard layout can input
   298      *                          ASCII alphabet.  Otherwise, FALSE.
   299      */
   300     bool IsLatinGroup(guint8 aGroup);
   302     /**
   303      * IsBasicLatinLetterOrNumeral() Checks whether the aCharCode is an
   304      * alphabet or a numeric character in ASCII.
   305      *
   306      * @param aCharCode         Charcode which you want to test.
   307      * @return                  TRUE if aCharCode is an alphabet or a numeric
   308      *                          in ASCII range.  Otherwise, FALSE.
   309      */
   310     static bool IsBasicLatinLetterOrNumeral(uint32_t aCharCode);
   312     /**
   313      * GetGDKKeyvalWithoutModifier() returns the keyval for aGdkKeyEvent when
   314      * ignoring the modifier state except NumLock. (NumLock is a key to change
   315      * some key's meaning.)
   316      */
   317     static guint GetGDKKeyvalWithoutModifier(const GdkEventKey *aGdkKeyEvent);
   319     /**
   320      * GetDOMKeyCodeFromKeyPairs() returns DOM keycode for aGdkKeyval if
   321      * it's in KeyPair table.
   322      */
   323     static uint32_t GetDOMKeyCodeFromKeyPairs(guint aGdkKeyval);
   325     /**
   326      * InitKeypressEvent() intializes keyCode, charCode and
   327      * alternativeCharCodes of keypress event.
   328      *
   329      * @param aKeyEvent         An NS_KEY_PRESS event, must not be nullptr.
   330      *                          The modifier related members and keyCode must
   331      *                          be initialized already.
   332      * @param aGdkKeyEvent      A native key event which causes dispatching
   333      *                          aKeyEvent.
   334      */
   335     void InitKeypressEvent(WidgetKeyboardEvent& aKeyEvent,
   336                            GdkEventKey* aGdkKeyEvent);
   338     /**
   339      * FilterEvents() listens all events on all our windows.
   340      * Be careful, this may make damage to performance if you add expensive
   341      * code in this method.
   342      */
   343     static GdkFilterReturn FilterEvents(GdkXEvent* aXEvent,
   344                                         GdkEvent* aGdkEvent,
   345                                         gpointer aData);
   346 };
   348 } // namespace widget
   349 } // namespace mozilla
   351 #endif /* __nsGdkKeyUtils_h__ */

mercurial