~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/widget/src/gtk2/nsGtkKeyUtils.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 mozilla.org code.
 
18
 *
 
19
 * The Initial Developer of the Original Code 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
#include <gdk/gdkkeysyms.h>
 
40
#include <gdk/gdkevents.h>
 
41
#include <gdk/gdkx.h>
 
42
#include "nsGUIEvent.h"
 
43
#include "keysym2ucs.h"
 
44
 
 
45
struct nsKeyConverter {
 
46
    int vkCode; // Platform independent key code
 
47
    int keysym; // GDK keysym key code
 
48
};
 
49
 
 
50
//
 
51
// Netscape keycodes are defined in widget/public/nsGUIEvent.h
 
52
// GTK keycodes are defined in <gdk/gdkkeysyms.h>
 
53
//
 
54
struct nsKeyConverter nsKeycodes[] = {
 
55
    { NS_VK_CANCEL,     GDK_Cancel },
 
56
    { NS_VK_BACK,       GDK_BackSpace },
 
57
    { NS_VK_TAB,        GDK_Tab },
 
58
    { NS_VK_TAB,        GDK_ISO_Left_Tab },
 
59
    { NS_VK_CLEAR,      GDK_Clear },
 
60
    { NS_VK_RETURN,     GDK_Return },
 
61
    { NS_VK_SHIFT,      GDK_Shift_L },
 
62
    { NS_VK_SHIFT,      GDK_Shift_R },
 
63
    { NS_VK_CONTROL,    GDK_Control_L },
 
64
    { NS_VK_CONTROL,    GDK_Control_R },
 
65
    { NS_VK_ALT,        GDK_Alt_L },
 
66
    { NS_VK_ALT,        GDK_Alt_R },
 
67
    { NS_VK_META,       GDK_Meta_L },
 
68
    { NS_VK_META,       GDK_Meta_R },
 
69
    { NS_VK_PAUSE,      GDK_Pause },
 
70
    { NS_VK_CAPS_LOCK,  GDK_Caps_Lock },
 
71
    { NS_VK_ESCAPE,     GDK_Escape },
 
72
    { NS_VK_SPACE,      GDK_space },
 
73
    { NS_VK_PAGE_UP,    GDK_Page_Up },
 
74
    { NS_VK_PAGE_DOWN,  GDK_Page_Down },
 
75
    { NS_VK_END,        GDK_End },
 
76
    { NS_VK_HOME,       GDK_Home },
 
77
    { NS_VK_LEFT,       GDK_Left },
 
78
    { NS_VK_UP,         GDK_Up },
 
79
    { NS_VK_RIGHT,      GDK_Right },
 
80
    { NS_VK_DOWN,       GDK_Down },
 
81
    { NS_VK_PRINTSCREEN, GDK_Print },
 
82
    { NS_VK_INSERT,     GDK_Insert },
 
83
    { NS_VK_DELETE,     GDK_Delete },
 
84
 
 
85
    // keypad keys
 
86
    { NS_VK_LEFT,       GDK_KP_Left },
 
87
    { NS_VK_RIGHT,      GDK_KP_Right },
 
88
    { NS_VK_UP,         GDK_KP_Up },
 
89
    { NS_VK_DOWN,       GDK_KP_Down },
 
90
    { NS_VK_PAGE_UP,    GDK_KP_Page_Up },
 
91
    // Not sure what these are
 
92
    //{ NS_VK_,       GDK_KP_Prior },
 
93
    //{ NS_VK_,        GDK_KP_Next },
 
94
    // GDK_KP_Begin is the 5 on the non-numlock keypad
 
95
    //{ NS_VK_,        GDK_KP_Begin },
 
96
    { NS_VK_PAGE_DOWN,  GDK_KP_Page_Down },
 
97
    { NS_VK_HOME,       GDK_KP_Home },
 
98
    { NS_VK_END,        GDK_KP_End },
 
99
    { NS_VK_INSERT,     GDK_KP_Insert },
 
100
    { NS_VK_DELETE,     GDK_KP_Delete },
 
101
 
 
102
    { NS_VK_MULTIPLY,   GDK_KP_Multiply },
 
103
    { NS_VK_ADD,        GDK_KP_Add },
 
104
    { NS_VK_SEPARATOR,  GDK_KP_Separator },
 
105
    { NS_VK_SUBTRACT,   GDK_KP_Subtract },
 
106
    { NS_VK_DECIMAL,    GDK_KP_Decimal },
 
107
    { NS_VK_DIVIDE,     GDK_KP_Divide },
 
108
    { NS_VK_RETURN,     GDK_KP_Enter },
 
109
 
 
110
    { NS_VK_COMMA,      GDK_comma },
 
111
    { NS_VK_PERIOD,     GDK_period },
 
112
    { NS_VK_SLASH,      GDK_slash },
 
113
    { NS_VK_BACK_SLASH, GDK_backslash },
 
114
    { NS_VK_BACK_QUOTE, GDK_grave },
 
115
    { NS_VK_OPEN_BRACKET, GDK_bracketleft },
 
116
    { NS_VK_CLOSE_BRACKET, GDK_bracketright },
 
117
    { NS_VK_SEMICOLON, GDK_colon },
 
118
    { NS_VK_QUOTE, GDK_apostrophe },
 
119
 
 
120
    // context menu key, keysym 0xff67, typically keycode 117 on 105-key (Microsoft) 
 
121
    // x86 keyboards, located between right 'Windows' key and right Ctrl key
 
122
    { NS_VK_CONTEXT_MENU, GDK_Menu },
 
123
 
 
124
    // NS doesn't have dash or equals distinct from the numeric keypad ones,
 
125
    // so we'll use those for now.  See bug 17008:
 
126
    { NS_VK_SUBTRACT, GDK_minus },
 
127
    { NS_VK_EQUALS, GDK_equal },
 
128
 
 
129
    // Some shifted keys, see bug 15463 as well as 17008.
 
130
    // These should be subject to different keyboard mappings.
 
131
    { NS_VK_QUOTE, GDK_quotedbl },
 
132
    { NS_VK_OPEN_BRACKET, GDK_braceleft },
 
133
    { NS_VK_CLOSE_BRACKET, GDK_braceright },
 
134
    { NS_VK_BACK_SLASH, GDK_bar },
 
135
    { NS_VK_SEMICOLON, GDK_semicolon },
 
136
    { NS_VK_BACK_QUOTE, GDK_asciitilde },
 
137
    { NS_VK_COMMA, GDK_less },
 
138
    { NS_VK_PERIOD, GDK_greater },
 
139
    { NS_VK_SLASH,      GDK_question },
 
140
    { NS_VK_1, GDK_exclam },
 
141
    { NS_VK_2, GDK_at },
 
142
    { NS_VK_3, GDK_numbersign },
 
143
    { NS_VK_4, GDK_dollar },
 
144
    { NS_VK_5, GDK_percent },
 
145
    { NS_VK_6, GDK_asciicircum },
 
146
    { NS_VK_7, GDK_ampersand },
 
147
    { NS_VK_8, GDK_asterisk },
 
148
    { NS_VK_9, GDK_parenleft },
 
149
    { NS_VK_0, GDK_parenright },
 
150
    { NS_VK_SUBTRACT, GDK_underscore },
 
151
    { NS_VK_EQUALS, GDK_plus }
 
152
};
 
153
 
 
154
#define IS_XSUN_XSERVER(dpy) \
 
155
    (strstr(XServerVendor(dpy), "Sun Microsystems") != NULL)
 
156
 
 
157
// map Sun Keyboard special keysyms on to NS_VK keys
 
158
struct nsKeyConverter nsSunKeycodes[] = {
 
159
    {NS_VK_ESCAPE, GDK_F11 }, //bug 57262, Sun Stop key generates F11 keysym
 
160
    {NS_VK_F1, GDK_Help }, //Mapping Help key to F1
 
161
    {NS_VK_F11, 0x1005ff10 }, //Sun F11 key generates SunF36(0x1005ff10) keysym
 
162
    {NS_VK_F12, 0x1005ff11 }, //Sun F12 key generates SunF37(0x1005ff11) keysym
 
163
    {NS_VK_PAGE_UP,    GDK_F29 }, //KP_Prior
 
164
    {NS_VK_PAGE_DOWN,  GDK_F35 }, //KP_Next
 
165
    {NS_VK_HOME,       GDK_F27 }, //KP_Home
 
166
    {NS_VK_END,        GDK_F33 }, //KP_End
 
167
};
 
168
 
 
169
int
 
170
GdkKeyCodeToDOMKeyCode(int aKeysym)
 
171
{
 
172
    int i, length = 0;
 
173
 
 
174
    // First, try to handle alphanumeric input, not listed in nsKeycodes:
 
175
    // most likely, more letters will be getting typed in than things in
 
176
    // the key list, so we will look through these first.
 
177
 
 
178
    // since X has different key symbols for upper and lowercase letters and
 
179
    // mozilla does not, convert gdk's to mozilla's
 
180
    if (aKeysym >= GDK_a && aKeysym <= GDK_z)
 
181
        return aKeysym - GDK_a + NS_VK_A;
 
182
    if (aKeysym >= GDK_A && aKeysym <= GDK_Z)
 
183
        return aKeysym - GDK_A + NS_VK_A;
 
184
 
 
185
    // numbers
 
186
    if (aKeysym >= GDK_0 && aKeysym <= GDK_9)
 
187
        return aKeysym - GDK_0 + NS_VK_0;
 
188
 
 
189
    // keypad numbers
 
190
    if (aKeysym >= GDK_KP_0 && aKeysym <= GDK_KP_9)
 
191
        return aKeysym - GDK_KP_0 + NS_VK_NUMPAD0;
 
192
 
 
193
    // map Sun Keyboard special keysyms
 
194
    if (IS_XSUN_XSERVER(GDK_DISPLAY())) {
 
195
        length = sizeof(nsSunKeycodes) / sizeof(struct nsKeyConverter);
 
196
        for (i = 0; i < length; i++) {
 
197
            if (nsSunKeycodes[i].keysym == aKeysym)
 
198
                return(nsSunKeycodes[i].vkCode);
 
199
        }
 
200
    }
 
201
 
 
202
    // misc other things
 
203
    length = sizeof(nsKeycodes) / sizeof(struct nsKeyConverter);
 
204
    for (i = 0; i < length; i++) {
 
205
        if (nsKeycodes[i].keysym == aKeysym)
 
206
            return(nsKeycodes[i].vkCode);
 
207
    }
 
208
 
 
209
    // function keys
 
210
    if (aKeysym >= GDK_F1 && aKeysym <= GDK_F24)
 
211
        return aKeysym - GDK_F1 + NS_VK_F1;
 
212
 
 
213
    return((int)0);
 
214
}
 
215
 
 
216
int
 
217
DOMKeyCodeToGdkKeyCode(PRUint32 aKeysym)
 
218
{
 
219
    int i, length = 0;
 
220
 
 
221
    // First, try to handle alphanumeric input, not listed in nsKeycodes:
 
222
    // most likely, more letters will be getting typed in than things in
 
223
    // the key list, so we will look through these first.
 
224
 
 
225
    if (aKeysym >= NS_VK_A && aKeysym <= NS_VK_Z)
 
226
      // gdk and DOM both use the ASCII codes for these keys.
 
227
      return aKeysym;
 
228
 
 
229
    // numbers
 
230
    if (aKeysym >= NS_VK_0 && aKeysym <= NS_VK_9)
 
231
      // gdk and DOM both use the ASCII codes for these keys.
 
232
      return aKeysym - GDK_0 + NS_VK_0;
 
233
 
 
234
    // keypad numbers
 
235
    if (aKeysym >= NS_VK_NUMPAD0 && aKeysym <= NS_VK_NUMPAD9)
 
236
      return aKeysym - NS_VK_NUMPAD0 + GDK_KP_0;
 
237
 
 
238
    // misc other things
 
239
    length = NS_ARRAY_LENGTH(nsKeycodes);
 
240
    for (i = 0; i < length; ++i) {
 
241
      if (nsKeycodes[i].vkCode == aKeysym) {
 
242
        return nsKeycodes[i].keysym;
 
243
      }
 
244
    }
 
245
 
 
246
    // function keys
 
247
    if (aKeysym >= NS_VK_F1 && aKeysym <= NS_VK_F9)
 
248
      return aKeysym - NS_VK_F1 + GDK_F1;
 
249
 
 
250
    return 0;
 
251
}
 
252
 
 
253
// Convert gdk key event keyvals to char codes if printable, 0 otherwise
 
254
PRUint32 nsConvertCharCodeToUnicode(GdkEventKey* aEvent)
 
255
{
 
256
    // Anything above 0xf000 is considered a non-printable
 
257
    // Exception: directly encoded UCS characters
 
258
    if (aEvent->keyval > 0xf000 && (aEvent->keyval & 0xff000000) != 0x01000000) {
 
259
 
 
260
        // Keypad keys are an exception: they return a value different
 
261
        // from their non-keypad equivalents, but mozilla doesn't distinguish.
 
262
        switch (aEvent->keyval)
 
263
            {
 
264
            case GDK_KP_Space:
 
265
                return ' ';
 
266
            case GDK_KP_Equal:
 
267
                return '=';
 
268
            case GDK_KP_Multiply:
 
269
                return '*';
 
270
            case GDK_KP_Add:
 
271
                return '+';
 
272
            case GDK_KP_Separator:
 
273
                return '|';
 
274
            case GDK_KP_Subtract:
 
275
                return '-';
 
276
            case GDK_KP_Decimal:
 
277
                return '.';
 
278
            case GDK_KP_Divide:
 
279
                return '/';
 
280
            case GDK_KP_0:
 
281
                return '0';
 
282
            case GDK_KP_1:
 
283
                return '1';
 
284
            case GDK_KP_2:
 
285
                return '2';
 
286
            case GDK_KP_3:
 
287
                return '3';
 
288
            case GDK_KP_4:
 
289
                return '4';
 
290
            case GDK_KP_5:
 
291
                return '5';
 
292
            case GDK_KP_6:
 
293
                return '6';
 
294
            case GDK_KP_7:
 
295
                return '7';
 
296
            case GDK_KP_8:
 
297
                return '8';
 
298
            case GDK_KP_9:
 
299
                return '9';
 
300
            }
 
301
 
 
302
        // non-printables
 
303
        return 0;
 
304
    }
 
305
 
 
306
    // we're supposedly printable, let's try to convert
 
307
    long ucs = keysym2ucs(aEvent->keyval);
 
308
    if ((ucs != -1) && (ucs < 0x10000))
 
309
        return ucs;
 
310
 
 
311
    // I guess we couldn't convert
 
312
    return 0;
 
313
}