1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:expandtab:shiftwidth=4:tabstop=4:
3 : */
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is mozilla.org code.
18 : *
19 : * The Initial Developer of the Original Code is Christopher Blizzard
20 : * <blizzard@mozilla.org>. Portions created by the Initial Developer
21 : * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef __nsGdkKeyUtils_h__
40 : #define __nsGdkKeyUtils_h__
41 :
42 : #include "nsEvent.h"
43 : #include "nsTArray.h"
44 :
45 : #include <gdk/gdk.h>
46 :
47 : namespace mozilla {
48 : namespace widget {
49 :
50 : /**
51 : * KeymapWrapper is a wrapper class of GdkKeymap. GdkKeymap doesn't support
52 : * all our needs, therefore, we need to access lower level APIs.
53 : * But such code is usually complex and might be slow. Against such issues,
54 : * we should cache some information.
55 : *
56 : * This class provides only static methods. The methods is using internal
57 : * singleton instance which is initialized by default GdkKeymap. When the
58 : * GdkKeymap is destroyed, the singleton instance will be destroyed.
59 : */
60 :
61 : class KeymapWrapper
62 : {
63 : public:
64 : /**
65 : * Compute an our DOM keycode from a GDK keyval.
66 : */
67 : static PRUint32 ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent);
68 :
69 : /**
70 : * Returns a GDK keyval which is related to the aDOMKeyCode. However,
71 : * it may not be same as original value since there are some lost
72 : * information.
73 : */
74 : static guint GuessGDKKeyval(PRUint32 aDOMKeyCode);
75 :
76 : /**
77 : * Modifier is list of modifiers which we support in widget level.
78 : */
79 : enum Modifier {
80 : NOT_MODIFIER = 0x0000,
81 : CAPS_LOCK = 0x0001,
82 : NUM_LOCK = 0x0002,
83 : SCROLL_LOCK = 0x0004,
84 : SHIFT = 0x0008,
85 : CTRL = 0x0010,
86 : ALT = 0x0020,
87 : SUPER = 0x0040,
88 : HYPER = 0x0080,
89 : META = 0x0100,
90 : ALTGR = 0x0200
91 : };
92 :
93 : /**
94 : * Modifiers is used for combination of Modifier.
95 : * E.g., |Modifiers modifiers = (SHIFT | CTRL);| means Shift and Ctrl.
96 : */
97 : typedef PRUint32 Modifiers;
98 :
99 : /**
100 : * GetCurrentModifierState() returns current modifier key state.
101 : * The "current" means actual state of hardware keyboard when this is
102 : * called. I.e., if some key events are not still dispatched by GDK,
103 : * the state may mismatch with GdkEventKey::state.
104 : *
105 : * @return Current modifier key state.
106 : */
107 : static guint GetCurrentModifierState();
108 :
109 : /**
110 : * AreModifiersCurrentlyActive() checks the "current" modifier state
111 : * on aGdkWindow with the keymap of the singleton instance.
112 : *
113 : * @param aModifiers One or more of Modifier values except
114 : * NOT_MODIFIER.
115 : * @return TRUE if all of modifieres in aModifiers are
116 : * active. Otherwise, FALSE.
117 : */
118 : static bool AreModifiersCurrentlyActive(Modifiers aModifiers);
119 :
120 : /**
121 : * AreModifiersActive() just checks whether aModifierState indicates
122 : * all modifiers in aModifiers are active or not.
123 : *
124 : * @param aModifiers One or more of Modifier values except
125 : * NOT_MODIFIER.
126 : * @param aModifierState GDK's modifier states.
127 : * @return TRUE if aGdkModifierType indecates all of
128 : * modifiers in aModifier are active.
129 : * Otherwise, FALSE.
130 : */
131 : static bool AreModifiersActive(Modifiers aModifiers,
132 : guint aModifierState);
133 :
134 : /**
135 : * InitInputEvent() initializes the aInputEvent with aModifierState.
136 : */
137 : static void InitInputEvent(nsInputEvent& aInputEvent,
138 : guint aModifierState);
139 :
140 : /**
141 : * InitKeyEvent() intializes aKeyEvent's modifier key related members
142 : * and keycode related values.
143 : *
144 : * @param aKeyEvent It's an nsKeyEvent which needs to be
145 : * initialized.
146 : * @param aGdkKeyEvent A native GDK key event.
147 : */
148 : static void InitKeyEvent(nsKeyEvent& aKeyEvent, GdkEventKey* aGdkKeyEvent);
149 :
150 : /**
151 : * IsKeyPressEventNecessary() returns TRUE when aGdkKeyEvent should cause
152 : * a DOM keypress event. Otherwise, FALSE.
153 : */
154 : static bool IsKeyPressEventNecessary(GdkEventKey* aGdkKeyEvent);
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 InitBySystemSettings();
175 :
176 : /**
177 : * mModifierKeys stores each hardware key information.
178 : */
179 0 : struct ModifierKey {
180 : guint mHardwareKeycode;
181 : guint mMask;
182 :
183 0 : ModifierKey(guint aHardwareKeycode) :
184 0 : mHardwareKeycode(aHardwareKeycode), mMask(0)
185 : {
186 0 : }
187 : };
188 : nsTArray<ModifierKey> mModifierKeys;
189 :
190 : /**
191 : * GetModifierKey() returns modifier key information of the hardware
192 : * keycode. If the key isn't a modifier key, returns NULL.
193 : */
194 : ModifierKey* GetModifierKey(guint aHardwareKeycode);
195 :
196 : /**
197 : * mModifierMasks is bit masks for each modifier. The index should be one
198 : * of ModifierIndex values.
199 : */
200 : enum ModifierIndex {
201 : INDEX_NUM_LOCK,
202 : INDEX_SCROLL_LOCK,
203 : INDEX_ALT,
204 : INDEX_SUPER,
205 : INDEX_HYPER,
206 : INDEX_META,
207 : INDEX_ALTGR,
208 : COUNT_OF_MODIFIER_INDEX
209 : };
210 : guint mModifierMasks[COUNT_OF_MODIFIER_INDEX];
211 :
212 : guint GetModifierMask(Modifier aModifier) const;
213 :
214 : /**
215 : * @param aGdkKeyval A GDK defined modifier key value such as
216 : * GDK_Shift_L.
217 : * @return Returns Modifier values for aGdkKeyval.
218 : * If the given key code isn't a modifier key,
219 : * returns NOT_MODIFIER.
220 : */
221 : static Modifier GetModifierForGDKKeyval(guint aGdkKeyval);
222 :
223 : #ifdef PR_LOGGING
224 : static const char* GetModifierName(Modifier aModifier);
225 : #endif // PR_LOGGING
226 :
227 : /**
228 : * mGdkKeymap is a wrapped instance by this class.
229 : */
230 : GdkKeymap* mGdkKeymap;
231 :
232 : /**
233 : * Pointer of the singleton instance.
234 : */
235 : static KeymapWrapper* sInstance;
236 :
237 : /**
238 : * Signal handlers.
239 : */
240 : static void OnKeysChanged(GdkKeymap* aKeymap, KeymapWrapper* aKeymapWrapper);
241 : static void OnDestroyKeymap(KeymapWrapper* aKeymapWrapper,
242 : GdkKeymap *aGdkKeymap);
243 :
244 : /**
245 : * GetCharCodeFor() Computes what character is inputted by the key event
246 : * with aModifierState and aGroup.
247 : *
248 : * @param aGdkKeyEvent Native key event, must not be NULL.
249 : * @param aModifierState Combination of GdkModifierType which you
250 : * want to test with aGdkKeyEvent.
251 : * @param aGroup Set group in the mGdkKeymap.
252 : * @return charCode which is inputted by aGdkKeyEvent.
253 : * If failed, this returns 0.
254 : */
255 : static PRUint32 GetCharCodeFor(const GdkEventKey *aGdkKeyEvent);
256 : PRUint32 GetCharCodeFor(const GdkEventKey *aGdkKeyEvent,
257 : guint aModifierState,
258 : gint aGroup);
259 :
260 : /**
261 : * GetKeyLevel() returns level of the aGdkKeyEvent in mGdkKeymap.
262 : *
263 : * @param aGdkKeyEvent Native key event, must not be NULL.
264 : * @return Using level. Typically, this is 0 or 1.
265 : * If failed, this returns -1.
266 : */
267 : gint GetKeyLevel(GdkEventKey *aGdkKeyEvent);
268 :
269 : /**
270 : * IsBasicLatinLetterOrNumeral() Checks whether the aCharCode is an
271 : * alphabet or a numeric character in ASCII.
272 : *
273 : * @param aCharCode Charcode which you want to test.
274 : * @return TRUE if aCharCode is an alphabet or a numeric
275 : * in ASCII range. Otherwise, FALSE.
276 : */
277 : static PRBool IsBasicLatinLetterOrNumeral(PRUint32 aCharCode);
278 :
279 : /**
280 : * InitKeypressEvent() intializes keyCode, charCode and
281 : * alternativeCharCodes of keypress event.
282 : *
283 : * @param aKeyEvent An NS_KEY_PRESS event, must not be NULL.
284 : * The modifier related members and keyCode must
285 : * be initialized already.
286 : * @param aGdkKeyEvent A native key event which causes dispatching
287 : * aKeyEvent.
288 : */
289 : void InitKeypressEvent(nsKeyEvent& aKeyEvent, GdkEventKey* aGdkKeyEvent);
290 : };
291 :
292 : } // namespace widget
293 : } // namespace mozilla
294 :
295 : #endif /* __nsGdkKeyUtils_h__ */
|