1 /*
   2  * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 #include "glass_key.h"
  26 #include "glass_gtkcompat.h"
  27 #include <com_sun_glass_events_KeyEvent.h>
  28 #include <com_sun_glass_ui_gtk_GtkApplication.h>
  29 
  30 #include <glib.h>
  31 #include <gdk/gdk.h>
  32 #include <gtk/gtk.h>
  33 
  34 static gboolean key_initialized = FALSE;
  35 static GHashTable *keymap;
  36 
  37 static void glass_g_hash_table_insert_int(GHashTable *table, gint key, gint value)
  38 {
  39     g_hash_table_insert(table, GINT_TO_POINTER(key), GINT_TO_POINTER(value));
  40 }
  41 
  42 static void initialize_key()
  43 {
  44     keymap = g_hash_table_new(g_direct_hash, g_direct_equal);
  45     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Return), com_sun_glass_events_KeyEvent_VK_ENTER);
  46     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(BackSpace), com_sun_glass_events_KeyEvent_VK_BACKSPACE);
  47     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Tab), com_sun_glass_events_KeyEvent_VK_TAB);
  48     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Clear), com_sun_glass_events_KeyEvent_VK_CLEAR); //XXX what is this?
  49     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Pause), com_sun_glass_events_KeyEvent_VK_PAUSE);
  50     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Escape), com_sun_glass_events_KeyEvent_VK_ESCAPE);
  51     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(space), com_sun_glass_events_KeyEvent_VK_SPACE);
  52     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Delete), com_sun_glass_events_KeyEvent_VK_DELETE);
  53     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Print), com_sun_glass_events_KeyEvent_VK_PRINTSCREEN); //XXX is correct?
  54     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Insert), com_sun_glass_events_KeyEvent_VK_INSERT);
  55     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Help), com_sun_glass_events_KeyEvent_VK_HELP); //XXX what is this?
  56 
  57     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Shift_L), com_sun_glass_events_KeyEvent_VK_SHIFT);
  58     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Shift_R), com_sun_glass_events_KeyEvent_VK_SHIFT); //XXX is this correct?
  59     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Control_L), com_sun_glass_events_KeyEvent_VK_CONTROL);
  60     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Control_R), com_sun_glass_events_KeyEvent_VK_CONTROL);
  61     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Alt_L), com_sun_glass_events_KeyEvent_VK_ALT);
  62     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Alt_R), com_sun_glass_events_KeyEvent_VK_ALT_GRAPH);
  63     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Super_L), com_sun_glass_events_KeyEvent_VK_WINDOWS);
  64     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Super_R), com_sun_glass_events_KeyEvent_VK_WINDOWS);
  65     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Menu), com_sun_glass_events_KeyEvent_VK_CONTEXT_MENU);
  66     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Meta_L), com_sun_glass_events_KeyEvent_VK_WINDOWS);
  67     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Meta_R), com_sun_glass_events_KeyEvent_VK_CONTEXT_MENU);//XXX is this correct?
  68     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Caps_Lock), com_sun_glass_events_KeyEvent_VK_CAPS_LOCK);
  69     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Num_Lock), com_sun_glass_events_KeyEvent_VK_NUM_LOCK);
  70     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Scroll_Lock), com_sun_glass_events_KeyEvent_VK_SCROLL_LOCK);
  71 
  72     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Page_Up), com_sun_glass_events_KeyEvent_VK_PAGE_UP);
  73     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Prior), com_sun_glass_events_KeyEvent_VK_PAGE_UP);
  74     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Page_Down), com_sun_glass_events_KeyEvent_VK_PAGE_DOWN);
  75     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Next), com_sun_glass_events_KeyEvent_VK_PAGE_DOWN);
  76     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(End), com_sun_glass_events_KeyEvent_VK_END);
  77     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Home), com_sun_glass_events_KeyEvent_VK_HOME);
  78     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Left), com_sun_glass_events_KeyEvent_VK_LEFT);
  79     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Right), com_sun_glass_events_KeyEvent_VK_RIGHT);
  80     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Up), com_sun_glass_events_KeyEvent_VK_UP);
  81     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Down), com_sun_glass_events_KeyEvent_VK_DOWN);
  82 
  83     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(comma), com_sun_glass_events_KeyEvent_VK_COMMA);
  84     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(minus), com_sun_glass_events_KeyEvent_VK_MINUS);
  85     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(period), com_sun_glass_events_KeyEvent_VK_PERIOD);
  86     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(slash), com_sun_glass_events_KeyEvent_VK_SLASH);
  87     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(semicolon), com_sun_glass_events_KeyEvent_VK_SEMICOLON);
  88     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(equal), com_sun_glass_events_KeyEvent_VK_EQUALS);
  89     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(bracketleft), com_sun_glass_events_KeyEvent_VK_OPEN_BRACKET);
  90     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(bracketright), com_sun_glass_events_KeyEvent_VK_CLOSE_BRACKET);
  91     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(backslash), com_sun_glass_events_KeyEvent_VK_BACK_SLASH);
  92     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(bar), com_sun_glass_events_KeyEvent_VK_BACK_SLASH);
  93     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Multiply), com_sun_glass_events_KeyEvent_VK_MULTIPLY);
  94     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Add), com_sun_glass_events_KeyEvent_VK_ADD);
  95     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Separator), com_sun_glass_events_KeyEvent_VK_SEPARATOR);
  96     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Subtract), com_sun_glass_events_KeyEvent_VK_SUBTRACT);
  97     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Decimal), com_sun_glass_events_KeyEvent_VK_DECIMAL);
  98 
  99     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(apostrophe), com_sun_glass_events_KeyEvent_VK_QUOTE);
 100     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(grave), com_sun_glass_events_KeyEvent_VK_BACK_QUOTE);
 101 
 102     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(ampersand), com_sun_glass_events_KeyEvent_VK_AMPERSAND);
 103     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(asterisk), com_sun_glass_events_KeyEvent_VK_ASTERISK);
 104     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(quotedbl), com_sun_glass_events_KeyEvent_VK_DOUBLE_QUOTE);
 105     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(less), com_sun_glass_events_KeyEvent_VK_LESS);
 106     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(greater), com_sun_glass_events_KeyEvent_VK_GREATER);
 107     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(braceleft), com_sun_glass_events_KeyEvent_VK_BRACELEFT);
 108     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(braceright), com_sun_glass_events_KeyEvent_VK_BRACERIGHT);
 109     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(at), com_sun_glass_events_KeyEvent_VK_AT);
 110     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(colon), com_sun_glass_events_KeyEvent_VK_COLON);
 111     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(asciicircum), com_sun_glass_events_KeyEvent_VK_CIRCUMFLEX);
 112     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(dollar), com_sun_glass_events_KeyEvent_VK_DOLLAR);
 113     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(EuroSign), com_sun_glass_events_KeyEvent_VK_EURO_SIGN);
 114     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(exclam), com_sun_glass_events_KeyEvent_VK_EXCLAMATION);
 115     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(exclamdown), com_sun_glass_events_KeyEvent_VK_INV_EXCLAMATION);
 116     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(parenleft), com_sun_glass_events_KeyEvent_VK_LEFT_PARENTHESIS);
 117     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(numbersign), com_sun_glass_events_KeyEvent_VK_NUMBER_SIGN);
 118     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(plus), com_sun_glass_events_KeyEvent_VK_PLUS);
 119     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(parenright), com_sun_glass_events_KeyEvent_VK_RIGHT_PARENTHESIS);
 120     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(underscore), com_sun_glass_events_KeyEvent_VK_UNDERSCORE);
 121 
 122     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(0), com_sun_glass_events_KeyEvent_VK_0);
 123     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(1), com_sun_glass_events_KeyEvent_VK_1);
 124     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(2), com_sun_glass_events_KeyEvent_VK_2);
 125     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(3), com_sun_glass_events_KeyEvent_VK_3);
 126     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(4), com_sun_glass_events_KeyEvent_VK_4);
 127     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(5), com_sun_glass_events_KeyEvent_VK_5);
 128     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(6), com_sun_glass_events_KeyEvent_VK_6);
 129     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(7), com_sun_glass_events_KeyEvent_VK_7);
 130     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(8), com_sun_glass_events_KeyEvent_VK_8);
 131     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(9), com_sun_glass_events_KeyEvent_VK_9);
 132 
 133     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(a), com_sun_glass_events_KeyEvent_VK_A);
 134     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(b), com_sun_glass_events_KeyEvent_VK_B);
 135     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(c), com_sun_glass_events_KeyEvent_VK_C);
 136     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(d), com_sun_glass_events_KeyEvent_VK_D);
 137     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(e), com_sun_glass_events_KeyEvent_VK_E);
 138     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(f), com_sun_glass_events_KeyEvent_VK_F);
 139     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(g), com_sun_glass_events_KeyEvent_VK_G);
 140     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(h), com_sun_glass_events_KeyEvent_VK_H);
 141     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(i), com_sun_glass_events_KeyEvent_VK_I);
 142     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(j), com_sun_glass_events_KeyEvent_VK_J);
 143     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(k), com_sun_glass_events_KeyEvent_VK_K);
 144     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(l), com_sun_glass_events_KeyEvent_VK_L);
 145     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(m), com_sun_glass_events_KeyEvent_VK_M);
 146     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(n), com_sun_glass_events_KeyEvent_VK_N);
 147     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(o), com_sun_glass_events_KeyEvent_VK_O);
 148     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(p), com_sun_glass_events_KeyEvent_VK_P);
 149     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(q), com_sun_glass_events_KeyEvent_VK_Q);
 150     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(r), com_sun_glass_events_KeyEvent_VK_R);
 151     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(s), com_sun_glass_events_KeyEvent_VK_S);
 152     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(t), com_sun_glass_events_KeyEvent_VK_T);
 153     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(u), com_sun_glass_events_KeyEvent_VK_U);
 154     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(v), com_sun_glass_events_KeyEvent_VK_V);
 155     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(w), com_sun_glass_events_KeyEvent_VK_W);
 156     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(x), com_sun_glass_events_KeyEvent_VK_X);
 157     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(y), com_sun_glass_events_KeyEvent_VK_Y);
 158     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(z), com_sun_glass_events_KeyEvent_VK_Z);
 159 
 160     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(A), com_sun_glass_events_KeyEvent_VK_A);
 161     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(B), com_sun_glass_events_KeyEvent_VK_B);
 162     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(C), com_sun_glass_events_KeyEvent_VK_C);
 163     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(D), com_sun_glass_events_KeyEvent_VK_D);
 164     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(E), com_sun_glass_events_KeyEvent_VK_E);
 165     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F), com_sun_glass_events_KeyEvent_VK_F);
 166     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(G), com_sun_glass_events_KeyEvent_VK_G);
 167     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(H), com_sun_glass_events_KeyEvent_VK_H);
 168     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(I), com_sun_glass_events_KeyEvent_VK_I);
 169     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(J), com_sun_glass_events_KeyEvent_VK_J);
 170     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(K), com_sun_glass_events_KeyEvent_VK_K);
 171     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(L), com_sun_glass_events_KeyEvent_VK_L);
 172     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(M), com_sun_glass_events_KeyEvent_VK_M);
 173     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(N), com_sun_glass_events_KeyEvent_VK_N);
 174     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(O), com_sun_glass_events_KeyEvent_VK_O);
 175     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(P), com_sun_glass_events_KeyEvent_VK_P);
 176     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Q), com_sun_glass_events_KeyEvent_VK_Q);
 177     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(R), com_sun_glass_events_KeyEvent_VK_R);
 178     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(S), com_sun_glass_events_KeyEvent_VK_S);
 179     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(T), com_sun_glass_events_KeyEvent_VK_T);
 180     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(U), com_sun_glass_events_KeyEvent_VK_U);
 181     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(V), com_sun_glass_events_KeyEvent_VK_V);
 182     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(W), com_sun_glass_events_KeyEvent_VK_W);
 183     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(X), com_sun_glass_events_KeyEvent_VK_X);
 184     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Y), com_sun_glass_events_KeyEvent_VK_Y);
 185     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(Z), com_sun_glass_events_KeyEvent_VK_Z);
 186 
 187     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_0), com_sun_glass_events_KeyEvent_VK_NUMPAD0);
 188     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_1), com_sun_glass_events_KeyEvent_VK_NUMPAD1);
 189     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_2), com_sun_glass_events_KeyEvent_VK_NUMPAD2);
 190     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_3), com_sun_glass_events_KeyEvent_VK_NUMPAD3);
 191     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_4), com_sun_glass_events_KeyEvent_VK_NUMPAD4);
 192     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_5), com_sun_glass_events_KeyEvent_VK_NUMPAD5);
 193     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_6), com_sun_glass_events_KeyEvent_VK_NUMPAD6);
 194     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_7), com_sun_glass_events_KeyEvent_VK_NUMPAD7);
 195     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_8), com_sun_glass_events_KeyEvent_VK_NUMPAD8);
 196     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_9), com_sun_glass_events_KeyEvent_VK_NUMPAD9);
 197 
 198     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Enter), com_sun_glass_events_KeyEvent_VK_ENTER);
 199     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Home), com_sun_glass_events_KeyEvent_VK_HOME);
 200     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Left), com_sun_glass_events_KeyEvent_VK_LEFT);
 201     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Up), com_sun_glass_events_KeyEvent_VK_UP);
 202     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Right), com_sun_glass_events_KeyEvent_VK_RIGHT);
 203     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Down), com_sun_glass_events_KeyEvent_VK_DOWN);
 204     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Prior), com_sun_glass_events_KeyEvent_VK_PAGE_UP);
 205     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Page_Up), com_sun_glass_events_KeyEvent_VK_PAGE_UP);
 206     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Next), com_sun_glass_events_KeyEvent_VK_PAGE_DOWN);
 207     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Page_Down), com_sun_glass_events_KeyEvent_VK_PAGE_DOWN);
 208     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_End), com_sun_glass_events_KeyEvent_VK_END);
 209     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Insert), com_sun_glass_events_KeyEvent_VK_INSERT);
 210     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Delete), com_sun_glass_events_KeyEvent_VK_DELETE);
 211     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Divide), com_sun_glass_events_KeyEvent_VK_DIVIDE);
 212     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(KP_Begin),
 213             com_sun_glass_events_KeyEvent_VK_CLEAR); // 5 key on keypad with Num Lock turned off
 214 
 215     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F1), com_sun_glass_events_KeyEvent_VK_F1);
 216     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F2), com_sun_glass_events_KeyEvent_VK_F2);
 217     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F3), com_sun_glass_events_KeyEvent_VK_F3);
 218     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F4), com_sun_glass_events_KeyEvent_VK_F4);
 219     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F5), com_sun_glass_events_KeyEvent_VK_F5);
 220     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F6), com_sun_glass_events_KeyEvent_VK_F6);
 221     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F7), com_sun_glass_events_KeyEvent_VK_F7);
 222     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F8), com_sun_glass_events_KeyEvent_VK_F8);
 223     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F9), com_sun_glass_events_KeyEvent_VK_F9);
 224     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F10), com_sun_glass_events_KeyEvent_VK_F10);
 225     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F11), com_sun_glass_events_KeyEvent_VK_F11);
 226     glass_g_hash_table_insert_int(keymap, GLASS_GDK_KEY_CONSTANT(F12), com_sun_glass_events_KeyEvent_VK_F12);
 227 }
 228 
 229 static void init_keymap() {
 230     if (!key_initialized) {
 231         initialize_key();
 232         key_initialized = TRUE;
 233     }
 234 }
 235 
 236 jint gdk_keyval_to_glass(guint keyval)
 237 {
 238     init_keymap();
 239     return GPOINTER_TO_INT(g_hash_table_lookup(keymap, GINT_TO_POINTER(keyval)));
 240 }
 241 
 242 jint get_glass_key(GdkEventKey* e) {
 243     init_keymap();
 244 
 245     guint keyValue;
 246     guint state = e->state & GDK_MOD2_MASK; //NumLock test
 247 
 248     gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(),
 249             e->hardware_keycode, static_cast<GdkModifierType>(state), e->group,
 250             &keyValue, NULL, NULL, NULL);
 251 
 252     jint key = GPOINTER_TO_INT(g_hash_table_lookup(keymap,
 253             GINT_TO_POINTER(keyValue)));
 254 
 255     if (!key) {
 256         // We failed to find a keyval in our keymap, this may happen with
 257         // non-latin layouts(e.g. Cyrillic). So here we try to find a keyval
 258         // from a default layout(we assume that it is a US-like one).
 259         GdkKeymapKey kk;
 260         kk.keycode = e->hardware_keycode;
 261         kk.group = kk.level = 0;
 262 
 263         keyValue = gdk_keymap_lookup_key(gdk_keymap_get_default(), &kk);
 264 
 265         key = GPOINTER_TO_INT(g_hash_table_lookup(keymap,
 266                 GINT_TO_POINTER(keyValue)));
 267     }
 268 
 269     return key;
 270 }
 271 
 272 gint find_gdk_keyval_for_glass_keycode(jint code) {
 273     gint result = -1;
 274     GHashTableIter iter;
 275     gpointer key, value;
 276     init_keymap();
 277     g_hash_table_iter_init(&iter, keymap);
 278     while (g_hash_table_iter_next(&iter, &key, &value)) {
 279         if (code == GPOINTER_TO_INT(value)) {
 280             result = GPOINTER_TO_INT(key);
 281             break;
 282         }
 283     }
 284     return result;
 285 }
 286 
 287 jint gdk_modifier_mask_to_glass(guint mask)
 288 {
 289     jint glass_mask = 0;
 290     glass_mask |= (mask & GDK_SHIFT_MASK) ? com_sun_glass_events_KeyEvent_MODIFIER_SHIFT : 0;
 291     glass_mask |= (mask & GDK_CONTROL_MASK) ? com_sun_glass_events_KeyEvent_MODIFIER_CONTROL : 0;
 292     glass_mask |= (mask & GDK_MOD1_MASK) ? com_sun_glass_events_KeyEvent_MODIFIER_ALT : 0;
 293     glass_mask |= (mask & GDK_META_MASK) ? com_sun_glass_events_KeyEvent_MODIFIER_ALT : 0; // XXX: is this OK?
 294     glass_mask |= (mask & GDK_BUTTON1_MASK) ? com_sun_glass_events_KeyEvent_MODIFIER_BUTTON_PRIMARY : 0;
 295     glass_mask |= (mask & GDK_BUTTON2_MASK) ? com_sun_glass_events_KeyEvent_MODIFIER_BUTTON_MIDDLE : 0;
 296     glass_mask |= (mask & GDK_BUTTON3_MASK) ? com_sun_glass_events_KeyEvent_MODIFIER_BUTTON_SECONDARY : 0;
 297     glass_mask |= (mask & GDK_SUPER_MASK) ? com_sun_glass_events_KeyEvent_MODIFIER_WINDOWS : 0; // XXX: is this OK?
 298 
 299     return glass_mask;
 300 }
 301 
 302 jint glass_key_to_modifier(jint glassKey) {
 303     switch (glassKey) {
 304         case com_sun_glass_events_KeyEvent_VK_SHIFT:
 305             return com_sun_glass_events_KeyEvent_MODIFIER_SHIFT;
 306         case com_sun_glass_events_KeyEvent_VK_ALT:
 307         case com_sun_glass_events_KeyEvent_VK_ALT_GRAPH:
 308             return com_sun_glass_events_KeyEvent_MODIFIER_ALT;
 309         case com_sun_glass_events_KeyEvent_VK_CONTROL:
 310             return com_sun_glass_events_KeyEvent_MODIFIER_CONTROL;
 311         case com_sun_glass_events_KeyEvent_VK_WINDOWS:
 312             return com_sun_glass_events_KeyEvent_MODIFIER_WINDOWS;
 313         default:
 314             return 0;
 315     }
 316 }
 317 extern "C" {
 318 
 319 /*
 320  * Class:     com_sun_glass_ui_gtk_GtkApplication
 321  * Method:    _getKeyCodeForChar
 322  * Signature: (C)I
 323  */
 324 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_gtk_GtkApplication__1getKeyCodeForChar
 325   (JNIEnv *env, jobject jApplication, jchar character)
 326 {
 327     (void)env;
 328     (void)jApplication;
 329 
 330     gunichar *ucs_char = g_utf16_to_ucs4(&character, 1, NULL, NULL, NULL);
 331     if (ucs_char == NULL) {
 332         return com_sun_glass_events_KeyEvent_VK_UNDEFINED;
 333     }
 334 
 335     guint keyval = gdk_unicode_to_keyval(*ucs_char);
 336 
 337     if (keyval == (*ucs_char | 0x01000000)) {
 338         g_free(ucs_char);
 339         return com_sun_glass_events_KeyEvent_VK_UNDEFINED;
 340     }
 341 
 342     g_free(ucs_char);
 343 
 344     return gdk_keyval_to_glass(keyval);
 345 }
 346 
 347 } // extern "C"