1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
17 * The Original Code is mozilla.org code.
19 * The Initial Developer of the Original Code is
20 * Christopher Blizzard <blizzard@mozilla.org>.
21 * Portions created by the Initial Developer are Copyright (C) 2001
22 * the Initial Developer. All Rights Reserved.
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include <gdk/gdkkeysyms.h>
42 #define GDK_Sleep 0x1008ff2f
49 #include "nsGUIEvent.h"
50 #include "keysym2ucs.h"
52 #define MAX_UNICODE 0x10FFFF
54 struct nsKeyConverter
{
55 int vkCode
; // Platform independent key code
56 int keysym
; // GDK keysym key code
60 // Netscape keycodes are defined in widget/public/nsGUIEvent.h
61 // GTK keycodes are defined in <gdk/gdkkeysyms.h>
63 struct nsKeyConverter nsKeycodes
[] = {
64 { NS_VK_CANCEL
, GDK_Cancel
},
65 { NS_VK_BACK
, GDK_BackSpace
},
66 { NS_VK_TAB
, GDK_Tab
},
67 { NS_VK_TAB
, GDK_ISO_Left_Tab
},
68 { NS_VK_CLEAR
, GDK_Clear
},
69 { NS_VK_RETURN
, GDK_Return
},
70 { NS_VK_SHIFT
, GDK_Shift_L
},
71 { NS_VK_SHIFT
, GDK_Shift_R
},
72 { NS_VK_CONTROL
, GDK_Control_L
},
73 { NS_VK_CONTROL
, GDK_Control_R
},
74 { NS_VK_ALT
, GDK_Alt_L
},
75 { NS_VK_ALT
, GDK_Alt_R
},
76 { NS_VK_META
, GDK_Meta_L
},
77 { NS_VK_META
, GDK_Meta_R
},
78 { NS_VK_PAUSE
, GDK_Pause
},
79 { NS_VK_CAPS_LOCK
, GDK_Caps_Lock
},
80 { NS_VK_KANA
, GDK_Kana_Lock
},
81 { NS_VK_KANA
, GDK_Kana_Shift
},
82 { NS_VK_HANGUL
, GDK_Hangul
},
83 // { NS_VK_JUNJA, GDK_XXX },
84 // { NS_VK_FINAL, GDK_XXX },
85 { NS_VK_HANJA
, GDK_Hangul_Hanja
},
86 { NS_VK_KANJI
, GDK_Kanji
},
87 { NS_VK_ESCAPE
, GDK_Escape
},
88 { NS_VK_CONVERT
, GDK_Henkan
},
89 { NS_VK_NONCONVERT
, GDK_Muhenkan
},
90 // { NS_VK_ACCEPT, GDK_XXX },
91 { NS_VK_MODECHANGE
, GDK_Mode_switch
},
92 { NS_VK_SPACE
, GDK_space
},
93 { NS_VK_PAGE_UP
, GDK_Page_Up
},
94 { NS_VK_PAGE_DOWN
, GDK_Page_Down
},
95 { NS_VK_END
, GDK_End
},
96 { NS_VK_HOME
, GDK_Home
},
97 { NS_VK_LEFT
, GDK_Left
},
99 { NS_VK_RIGHT
, GDK_Right
},
100 { NS_VK_DOWN
, GDK_Down
},
101 { NS_VK_SELECT
, GDK_Select
},
102 { NS_VK_PRINT
, GDK_Print
},
103 { NS_VK_EXECUTE
, GDK_Execute
},
104 { NS_VK_PRINTSCREEN
, GDK_Print
},
105 { NS_VK_INSERT
, GDK_Insert
},
106 { NS_VK_DELETE
, GDK_Delete
},
107 { NS_VK_HELP
, GDK_Help
},
110 { NS_VK_LEFT
, GDK_KP_Left
},
111 { NS_VK_RIGHT
, GDK_KP_Right
},
112 { NS_VK_UP
, GDK_KP_Up
},
113 { NS_VK_DOWN
, GDK_KP_Down
},
114 { NS_VK_PAGE_UP
, GDK_KP_Page_Up
},
115 // Not sure what these are
116 //{ NS_VK_, GDK_KP_Prior },
117 //{ NS_VK_, GDK_KP_Next },
118 // GDK_KP_Begin is the 5 on the non-numlock keypad
119 //{ NS_VK_, GDK_KP_Begin },
120 { NS_VK_PAGE_DOWN
, GDK_KP_Page_Down
},
121 { NS_VK_HOME
, GDK_KP_Home
},
122 { NS_VK_END
, GDK_KP_End
},
123 { NS_VK_INSERT
, GDK_KP_Insert
},
124 { NS_VK_DELETE
, GDK_KP_Delete
},
126 { NS_VK_MULTIPLY
, GDK_KP_Multiply
},
127 { NS_VK_ADD
, GDK_KP_Add
},
128 { NS_VK_SEPARATOR
, GDK_KP_Separator
},
129 { NS_VK_SUBTRACT
, GDK_KP_Subtract
},
130 { NS_VK_DECIMAL
, GDK_KP_Decimal
},
131 { NS_VK_DIVIDE
, GDK_KP_Divide
},
132 { NS_VK_RETURN
, GDK_KP_Enter
},
133 { NS_VK_NUM_LOCK
, GDK_Num_Lock
},
134 { NS_VK_SCROLL_LOCK
,GDK_Scroll_Lock
},
136 { NS_VK_COMMA
, GDK_comma
},
137 { NS_VK_PERIOD
, GDK_period
},
138 { NS_VK_SLASH
, GDK_slash
},
139 { NS_VK_BACK_SLASH
, GDK_backslash
},
140 { NS_VK_BACK_QUOTE
, GDK_grave
},
141 { NS_VK_OPEN_BRACKET
, GDK_bracketleft
},
142 { NS_VK_CLOSE_BRACKET
, GDK_bracketright
},
143 { NS_VK_SEMICOLON
, GDK_colon
},
144 { NS_VK_QUOTE
, GDK_apostrophe
},
146 // context menu key, keysym 0xff67, typically keycode 117 on 105-key (Microsoft)
147 // x86 keyboards, located between right 'Windows' key and right Ctrl key
148 { NS_VK_CONTEXT_MENU
, GDK_Menu
},
149 { NS_VK_SLEEP
, GDK_Sleep
},
151 // NS doesn't have dash or equals distinct from the numeric keypad ones,
152 // so we'll use those for now. See bug 17008:
153 { NS_VK_SUBTRACT
, GDK_minus
},
154 { NS_VK_EQUALS
, GDK_equal
},
156 // Some shifted keys, see bug 15463 as well as 17008.
157 // These should be subject to different keyboard mappings.
158 { NS_VK_QUOTE
, GDK_quotedbl
},
159 { NS_VK_OPEN_BRACKET
, GDK_braceleft
},
160 { NS_VK_CLOSE_BRACKET
, GDK_braceright
},
161 { NS_VK_BACK_SLASH
, GDK_bar
},
162 { NS_VK_SEMICOLON
, GDK_semicolon
},
163 { NS_VK_BACK_QUOTE
, GDK_asciitilde
},
164 { NS_VK_COMMA
, GDK_less
},
165 { NS_VK_PERIOD
, GDK_greater
},
166 { NS_VK_SLASH
, GDK_question
},
167 { NS_VK_1
, GDK_exclam
},
169 { NS_VK_3
, GDK_numbersign
},
170 { NS_VK_4
, GDK_dollar
},
171 { NS_VK_5
, GDK_percent
},
172 { NS_VK_6
, GDK_asciicircum
},
173 { NS_VK_7
, GDK_ampersand
},
174 { NS_VK_8
, GDK_asterisk
},
175 { NS_VK_9
, GDK_parenleft
},
176 { NS_VK_0
, GDK_parenright
},
177 { NS_VK_SUBTRACT
, GDK_underscore
},
178 { NS_VK_EQUALS
, GDK_plus
}
182 #define IS_XSUN_XSERVER(dpy) \
183 (strstr(XServerVendor(dpy), "Sun Microsystems") != NULL)
186 // map Sun Keyboard special keysyms on to NS_VK keys
187 struct nsKeyConverter nsSunKeycodes
[] = {
188 {NS_VK_ESCAPE
, GDK_F11
}, //bug 57262, Sun Stop key generates F11 keysym
189 {NS_VK_F1
, GDK_Help
}, //Mapping Help key to F1
190 {NS_VK_F11
, 0x1005ff10 }, //Sun F11 key generates SunF36(0x1005ff10) keysym
191 {NS_VK_F12
, 0x1005ff11 }, //Sun F12 key generates SunF37(0x1005ff11) keysym
192 {NS_VK_PAGE_UP
, GDK_F29
}, //KP_Prior
193 {NS_VK_PAGE_DOWN
, GDK_F35
}, //KP_Next
194 {NS_VK_HOME
, GDK_F27
}, //KP_Home
195 {NS_VK_END
, GDK_F33
}, //KP_End
199 GdkKeyCodeToDOMKeyCode(int aKeysym
)
203 // First, try to handle alphanumeric input, not listed in nsKeycodes:
204 // most likely, more letters will be getting typed in than things in
205 // the key list, so we will look through these first.
207 // since X has different key symbols for upper and lowercase letters and
208 // mozilla does not, convert gdk's to mozilla's
209 if (aKeysym
>= GDK_a
&& aKeysym
<= GDK_z
)
210 return aKeysym
- GDK_a
+ NS_VK_A
;
211 if (aKeysym
>= GDK_A
&& aKeysym
<= GDK_Z
)
212 return aKeysym
- GDK_A
+ NS_VK_A
;
215 if (aKeysym
>= GDK_0
&& aKeysym
<= GDK_9
)
216 return aKeysym
- GDK_0
+ NS_VK_0
;
219 if (aKeysym
>= GDK_KP_0
&& aKeysym
<= GDK_KP_9
)
220 return aKeysym
- GDK_KP_0
+ NS_VK_NUMPAD0
;
223 // map Sun Keyboard special keysyms
224 if (IS_XSUN_XSERVER(GDK_DISPLAY())) {
225 length
= sizeof(nsSunKeycodes
) / sizeof(struct nsKeyConverter
);
226 for (i
= 0; i
< length
; i
++) {
227 if (nsSunKeycodes
[i
].keysym
== aKeysym
)
228 return(nsSunKeycodes
[i
].vkCode
);
234 length
= sizeof(nsKeycodes
) / sizeof(struct nsKeyConverter
);
235 for (i
= 0; i
< length
; i
++) {
236 if (nsKeycodes
[i
].keysym
== aKeysym
)
237 return(nsKeycodes
[i
].vkCode
);
241 if (aKeysym
>= GDK_F1
&& aKeysym
<= GDK_F24
)
242 return aKeysym
- GDK_F1
+ NS_VK_F1
;
248 DOMKeyCodeToGdkKeyCode(int aKeysym
)
252 // First, try to handle alphanumeric input, not listed in nsKeycodes:
253 // most likely, more letters will be getting typed in than things in
254 // the key list, so we will look through these first.
256 if (aKeysym
>= NS_VK_A
&& aKeysym
<= NS_VK_Z
)
257 // gdk and DOM both use the ASCII codes for these keys.
261 if (aKeysym
>= NS_VK_0
&& aKeysym
<= NS_VK_9
)
262 // gdk and DOM both use the ASCII codes for these keys.
263 return aKeysym
- GDK_0
+ NS_VK_0
;
266 if (aKeysym
>= NS_VK_NUMPAD0
&& aKeysym
<= NS_VK_NUMPAD9
)
267 return aKeysym
- NS_VK_NUMPAD0
+ GDK_KP_0
;
270 length
= NS_ARRAY_LENGTH(nsKeycodes
);
271 for (i
= 0; i
< length
; ++i
) {
272 if (nsKeycodes
[i
].vkCode
== aKeysym
) {
273 return nsKeycodes
[i
].keysym
;
278 if (aKeysym
>= NS_VK_F1
&& aKeysym
<= NS_VK_F9
)
279 return aKeysym
- NS_VK_F1
+ GDK_F1
;
284 // Convert gdk key event keyvals to char codes if printable, 0 otherwise
285 PRUint32
nsConvertCharCodeToUnicode(GdkEventKey
* aEvent
)
287 // Anything above 0xf000 is considered a non-printable
288 // Exception: directly encoded UCS characters
289 if (aEvent
->keyval
> 0xf000 && (aEvent
->keyval
& 0xff000000) != 0x01000000) {
291 // Keypad keys are an exception: they return a value different
292 // from their non-keypad equivalents, but mozilla doesn't distinguish.
293 switch (aEvent
->keyval
)
299 case GDK_KP_Multiply
:
303 case GDK_KP_Separator
:
305 case GDK_KP_Subtract
:
337 // we're supposedly printable, let's try to convert
338 long ucs
= keysym2ucs(aEvent
->keyval
);
339 if ((ucs
!= -1) && (ucs
< MAX_UNICODE
))
342 // I guess we couldn't convert