/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:expandtab:shiftwidth=4:tabstop=4:
*/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <gdk/gdk.h> #ifdef MOZ_X11 # include <X11/XKBlib.h> #endif #ifdef MOZ_WAYLAND # include <gdk/gdkwayland.h> # include <xkbcommon/xkbcommon.h> #endif #include"X11UndefineNone.h"
class nsWindow;
namespace mozilla { namespace widget {
/** * KeymapWrapper is a wrapper class of GdkKeymap. GdkKeymap doesn't support * all our needs, therefore, we need to access lower level APIs. * But such code is usually complex and might be slow. Against such issues, * we should cache some information. * * This class provides only static methods. The methods is using internal * singleton instance which is initialized by default GdkKeymap. When the * GdkKeymap is destroyed, the singleton instance will be destroyed.
*/
class KeymapWrapper { public: /** * Compute an our DOM keycode from a GDK keyval.
*/ static uint32_t ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent);
/** * Compute a DOM key name index from aGdkKeyEvent.
*/ static KeyNameIndex ComputeDOMKeyNameIndex(const GdkEventKey* aGdkKeyEvent);
/** * Compute a DOM code name index from aGdkKeyEvent.
*/ static CodeNameIndex ComputeDOMCodeNameIndex(const GdkEventKey* aGdkKeyEvent);
/** * We need to translate modifiers masks from Gdk to Gecko. * MappedModifier is a table of mapped modifiers, we ignore other * Gdk ones.
*/ enum MappedModifier {
NOT_MODIFIER = 0x0000,
CAPS_LOCK = 0x0001,
NUM_LOCK = 0x0002,
SCROLL_LOCK = 0x0004,
SHIFT = 0x0008,
CTRL = 0x0010,
ALT = 0x0020,
META = 0x0040,
SUPER = 0x0080,
HYPER = 0x0100,
LEVEL3 = 0x0200,
LEVEL5 = 0x0400
};
/** * MappedModifiers is used for combination of MappedModifier. * E.g., |MappedModifiers modifiers = (SHIFT | CTRL);| means Shift and Ctrl.
*/ typedef uint32_t MappedModifiers;
/** * GetCurrentModifierState() returns current modifier key state. * The "current" means actual state of hardware keyboard when this is * called. I.e., if some key events are not still dispatched by GDK, * the state may mismatch with GdkEventKey::state. * * @return Current modifier key state.
*/ static guint GetCurrentModifierState();
/** * Utility function to compute current keyboard modifiers for * WidgetInputEvent
*/ static uint32_t ComputeCurrentKeyModifiers();
/** * Utility function to covert platform modifier state to keyboard modifiers * of WidgetInputEvent
*/ static uint32_t ComputeKeyModifiers(guint aGdkModifierState);
/** * Convert native modifiers for `nsIWidget::SynthesizeNative*()` to * GDK's state.
*/ static guint ConvertWidgetModifierToGdkState(
nsIWidget::Modifiers aNativeModifiers);
/** * InitInputEvent() initializes the aInputEvent with aModifierState.
*/ staticvoid InitInputEvent(WidgetInputEvent& aInputEvent,
guint aGdkModifierState);
/** * InitKeyEvent() intializes aKeyEvent's modifier key related members * and keycode related values. * * @param aKeyEvent It's an WidgetKeyboardEvent which needs to be * initialized. * @param aGdkKeyEvent A native GDK key event. * @param aIsProcessedByIME true if aGdkKeyEvent is handled by IME.
*/ staticvoid InitKeyEvent(WidgetKeyboardEvent& aKeyEvent,
GdkEventKey* aGdkKeyEvent, bool aIsProcessedByIME);
/** * DispatchKeyDownOrKeyUpEvent() dispatches eKeyDown or eKeyUp event. * * @param aWindow The window to dispatch a keyboard event. * @param aGdkKeyEvent A native GDK_KEY_PRESS or GDK_KEY_RELEASE * event. * @param aIsProcessedByIME true if the event is handled by IME. * @param aIsCancelled [Out] true if the default is prevented. * @return true if eKeyDown event is actually dispatched. * Otherwise, false.
*/ staticbool DispatchKeyDownOrKeyUpEvent(nsWindow* aWindow,
GdkEventKey* aGdkKeyEvent, bool aIsProcessedByIME, bool* aIsCancelled);
/** * DispatchKeyDownOrKeyUpEvent() dispatches eKeyDown or eKeyUp event. * * @param aWindow The window to dispatch aKeyboardEvent. * @param aKeyboardEvent An eKeyDown or eKeyUp event. This will be * dispatched as is. * @param aIsCancelled [Out] true if the default is prevented. * @return true if eKeyDown event is actually dispatched. * Otherwise, false.
*/ staticbool DispatchKeyDownOrKeyUpEvent(nsWindow* aWindow,
WidgetKeyboardEvent& aKeyboardEvent, bool* aIsCancelled);
/** * GDK_KEY_RELEASE event handler. * * @param aWindow The window to dispatch eKeyUp event. * @param aGdkKeyEvent Receivied GDK_KEY_RELEASE event. * @return true if an event is dispatched. Otherwise, false.
*/ staticbool HandleKeyReleaseEvent(nsWindow* aWindow,
GdkEventKey* aGdkKeyEvent);
/** * WillDispatchKeyboardEvent() is called via * TextEventDispatcherListener::WillDispatchKeyboardEvent(). * * @param aKeyEvent An instance of KeyboardEvent which will be * dispatched. This method should set charCode * and alternative char codes if it's necessary. * @param aGdkKeyEvent A GdkEventKey instance which caused the * aKeyEvent.
*/ staticvoid WillDispatchKeyboardEvent(WidgetKeyboardEvent& aKeyEvent,
GdkEventKey* aGdkKeyEvent);
#ifdef MOZ_WAYLAND /** * Utility function to set all supported modifier masks * from xkb_keymap. We call that from Wayland backend routines.
*/ staticvoid SetModifierMasks(xkb_keymap* aKeymap); staticvoid HandleKeymap(uint32_t format, int fd, uint32_t size);
/** * EnsureInstance() is provided on Wayland to register Wayland callbacks * early.
*/ staticvoid EnsureInstance(); #endif
/** * ResetKeyboard is called on keymap changes from OnKeysChanged and * keyboard_handle_keymap to prepare for keymap changes.
*/ staticvoid ResetKeyboard();
/** * Destroys the singleton KeymapWrapper instance, if it exists.
*/ staticvoid Shutdown();
private: /** * GetInstance() returns a KeymapWrapper instance. * * @return A singleton instance of KeymapWrapper.
*/ static KeymapWrapper* GetInstance();
/** * GetModifierKey() returns modifier key information of the hardware * keycode. If the key isn't a modifier key, returns nullptr.
*/
ModifierKey* GetModifierKey(guint aHardwareKeycode);
/** * mModifierMasks is bit masks for each modifier. The index should be one * of ModifierIndex values.
*/ enum ModifierIndex {
INDEX_NUM_LOCK,
INDEX_SCROLL_LOCK,
INDEX_ALT,
INDEX_META,
INDEX_HYPER,
INDEX_LEVEL3,
INDEX_LEVEL5,
COUNT_OF_MODIFIER_INDEX
};
guint mModifierMasks[COUNT_OF_MODIFIER_INDEX];
/** * @param aGdkKeyval A GDK defined modifier key value such as * GDK_Shift_L. * @return Returns MappedModifier values for aGdkKeyval. * If the given key code isn't a modifier key, * returns NOT_MODIFIER.
*/ static MappedModifier GetModifierForGDKKeyval(guint aGdkKeyval);
/** * AreModifiersActive() just checks whether aGdkModifierState indicates * all modifiers in aModifiers are active or not. * * @param aModifiers One or more of MappedModifier values except * NOT_MODIFIER. * @param aGdkModifierState GDK's modifier states. * @return TRUE if aGdkModifierType indicates all of * modifiers in aModifier are active. * Otherwise, FALSE.
*/ staticbool AreModifiersActive(MappedModifiers aModifiers,
guint aGdkModifierState);
/** * mGdkKeymap is a wrapped instance by this class.
*/
GdkKeymap* mGdkKeymap;
/** * The base event code of XKB extension.
*/ int mXKBBaseEventCode;
#ifdef MOZ_X11 /** * Only auto_repeats[] stores valid value. If you need to use other * members, you need to listen notification events for them. * See a call of XkbSelectEventDetails() with XkbControlsNotify in * InitXKBExtension().
*/
XKeyboardState mKeyboardState; #endif
/** * Pointer of the singleton instance.
*/ static KeymapWrapper* sInstance;
/** * GetCharCodeFor() Computes what character is inputted by the key event * with aModifierState and aGroup. * * @param aGdkKeyEvent Native key event, must not be nullptr. * @param aModifierState Combination of GdkModifierType which you * want to test with aGdkKeyEvent. * @param aGroup Set group in the mGdkKeymap. * @return charCode which is inputted by aGdkKeyEvent. * If failed, this returns 0.
*/ static uint32_t GetCharCodeFor(const GdkEventKey* aGdkKeyEvent);
uint32_t GetCharCodeFor(const GdkEventKey* aGdkKeyEvent,
guint aGdkModifierState, gint aGroup);
/** * GetUnmodifiedCharCodeFor() computes what character is inputted by the * key event without Ctrl/Alt/Meta/Super/Hyper modifiers. * If Level3 or Level5 Shift causes no character input, this also ignores * them. * * @param aGdkKeyEvent Native key event, must not be nullptr. * @return charCode which is computed without modifiers * which prevent text input.
*/
uint32_t GetUnmodifiedCharCodeFor(const GdkEventKey* aGdkKeyEvent);
/** * GetKeyLevel() returns level of the aGdkKeyEvent in mGdkKeymap. * * @param aGdkKeyEvent Native key event, must not be nullptr. * @return Using level. Typically, this is 0 or 1. * If failed, this returns -1.
*/
gint GetKeyLevel(GdkEventKey* aGdkKeyEvent);
/** * GetFirstLatinGroup() returns group of mGdkKeymap which can input an * ASCII character by GDK_A. * * @return group value of GdkEventKey.
*/
gint GetFirstLatinGroup();
/** * IsLatinGroup() checkes whether the keyboard layout of aGroup is * ASCII alphabet inputtable or not. * * @param aGroup The group value of GdkEventKey. * @return TRUE if the keyboard layout can input * ASCII alphabet. Otherwise, FALSE.
*/ bool IsLatinGroup(guint8 aGroup);
/** * IsBasicLatinLetterOrNumeral() Checks whether the aCharCode is an * alphabet or a numeric character in ASCII. * * @param aCharCode Charcode which you want to test. * @return TRUE if aCharCode is an alphabet or a numeric * in ASCII range. Otherwise, FALSE.
*/ staticbool IsBasicLatinLetterOrNumeral(uint32_t aCharCode);
/** * IsPrintableASCIICharacter() checks whether the aCharCode is a printable * ASCII character. I.e., returns false if aCharCode is a control * character even in an ASCII character.
*/ staticbool IsPrintableASCIICharacter(uint32_t aCharCode) { return aCharCode >= 0x20 && aCharCode <= 0x7E;
}
/** * GetGDKKeyvalWithoutModifier() returns the keyval for aGdkKeyEvent when * ignoring the modifier state except NumLock. (NumLock is a key to change * some key's meaning.)
*/ static guint GetGDKKeyvalWithoutModifier(const GdkEventKey* aGdkKeyEvent);
/** * GetDOMKeyCodeFromKeyPairs() returns DOM keycode for aGdkKeyval if * it's in KeyPair table.
*/ static uint32_t GetDOMKeyCodeFromKeyPairs(guint aGdkKeyval);
#ifdef MOZ_X11 /** * FilterEvents() listens all events on all our windows. * Be careful, this may make damage to performance if you add expensive * code in this method.
*/ static GdkFilterReturn FilterEvents(GdkXEvent* aXEvent, GdkEvent* aGdkEvent,
gpointer aData); #endif
/** * MaybeDispatchContextMenuEvent() may dispatch eContextMenu event if * the given key combination should cause opening context menu. * * @param aWindow The window to dispatch a contextmenu event. * @param aEvent The native key event. * @return true if this method dispatched eContextMenu * event. Otherwise, false. * Be aware, when this returns true, the * widget may have been destroyed.
*/ staticbool MaybeDispatchContextMenuEvent(nsWindow* aWindow, const GdkEventKey* aEvent);
/** * See the document of WillDispatchKeyboardEvent().
*/ void WillDispatchKeyboardEventInternal(WidgetKeyboardEvent& aKeyEvent,
GdkEventKey* aGdkKeyEvent);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.