aboutsummaryrefslogtreecommitdiff
path: root/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c')
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c826
1 files changed, 700 insertions, 126 deletions
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
index 3c400114e4b..cdcd72e187c 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
@@ -48,7 +48,8 @@ struct event_hook_info
{
jobject *peer_obj;
int nwindows;
- GdkWindow ***windows; /* array of pointers to (GdkWindow *) */
+ /* array of pointers to (GdkWindow *) */
+ GdkWindow ***windows;
};
static jint
@@ -68,68 +69,317 @@ button_to_awt_mods (int button)
}
static jint
-state_to_awt_mods (int mods)
+state_to_awt_mods (guint state)
{
jint result = 0;
- if (mods & (GDK_SHIFT_MASK | GDK_LOCK_MASK))
+ if (state & GDK_SHIFT_MASK)
result |= AWT_SHIFT_MASK;
- if (mods & GDK_CONTROL_MASK)
+ if (state & GDK_CONTROL_MASK)
result |= AWT_CTRL_MASK;
-
+ if (state & GDK_MOD1_MASK)
+ result |= AWT_ALT_MASK;
+
+ return result;
+}
+
+/* Modifier key events need special treatment. In Sun's peer
+ implementation, when a modifier key is pressed, the KEY_PRESSED
+ event has that modifier in its modifiers list. The corresponding
+ KEY_RELEASED event's modifier list does not contain the modifier.
+ For example, pressing and releasing the shift key will produce a
+ key press event with modifiers=Shift, and a key release event with
+ no modifiers. GDK's key events behave in the exact opposite way,
+ so this translation code is needed. */
+static jint
+keyevent_state_to_awt_mods (GdkEvent *event)
+{
+ jint result = 0;
+ guint state;
+
+ if (event->type == GDK_KEY_PRESS)
+ {
+ state = event->key.state;
+
+ if (event->key.keyval == GDK_Shift_L
+ || event->key.keyval == GDK_Shift_R)
+ result |= AWT_SHIFT_MASK;
+ else
+ {
+ if (state & GDK_SHIFT_MASK)
+ result |= AWT_SHIFT_MASK;
+ }
+
+ if (event->key.keyval == GDK_Control_L
+ || event->key.keyval == GDK_Control_R)
+ result |= AWT_CTRL_MASK;
+ else
+ {
+ if (state & GDK_CONTROL_MASK)
+ result |= AWT_CTRL_MASK;
+ }
+
+ if (event->key.keyval == GDK_Alt_L
+ || event->key.keyval == GDK_Alt_R)
+ result |= AWT_ALT_MASK;
+ else
+ {
+ if (state & GDK_MOD1_MASK)
+ result |= AWT_ALT_MASK;
+ }
+ }
+ else if (event->type == GDK_KEY_RELEASE)
+ {
+ state = event->key.state;
+
+ if (event->key.keyval != GDK_Shift_L
+ && event->key.keyval != GDK_Shift_R)
+ {
+ if (state & GDK_SHIFT_MASK)
+ result |= AWT_SHIFT_MASK;
+ }
+ if (event->key.keyval != GDK_Control_L
+ && event->key.keyval != GDK_Control_R)
+ {
+ if (state & GDK_CONTROL_MASK)
+ result |= AWT_CTRL_MASK;
+ }
+
+ if (event->key.keyval != GDK_Alt_L
+ && event->key.keyval != GDK_Alt_R)
+ {
+ if (state & GDK_MOD1_MASK)
+ result |= AWT_ALT_MASK;
+ }
+ }
+
return result;
}
+/* Get the first keyval in the keymap for this event's keycode. The
+ first keyval corresponds roughly to Java's notion of a virtual
+ key. Returns the uppercase version of the first keyval. */
+static guint
+get_first_keyval_from_keymap (GdkEvent *event)
+{
+ guint keyval;
+ guint *keyvals;
+ gint n_entries;
+
+ if (!gdk_keymap_get_entries_for_keycode (NULL,
+ event->key.hardware_keycode,
+ NULL,
+ &keyvals,
+ &n_entries))
+ {
+ g_warning ("No keyval found for hardware keycode %d\n",
+ event->key.hardware_keycode);
+ /* Try to recover by using the keyval in the event structure. */
+ keyvals = &(event->key.keyval);
+ }
+ keyval = keyvals[0];
+ g_free (keyvals);
+
+ return gdk_keyval_to_upper (keyval);
+}
+
#ifdef __GNUC__
__inline
#endif
static jint
-keysym_to_awt_keycode (guint keyval)
+keysym_to_awt_keycode (GdkEvent *event)
{
- guint vk;
+ guint ukeyval;
+ guint state;
- vk = gdk_keyval_to_upper (keyval);
+ ukeyval = get_first_keyval_from_keymap (event);
+ state = event->key.state;
- if (vk >= 0x41 && vk <= 0x5A) /* VK_A through VK_Z */
- return vk;
+ /* VK_A through VK_Z */
+ if (ukeyval >= GDK_A && ukeyval <= GDK_Z)
+ return ukeyval;
- if (vk >= 0x30 && vk <= 0x39) /* VK_0 through VK_9 */
- return vk;
+ /* VK_0 through VK_9 */
+ if (ukeyval >= GDK_0 && ukeyval <= GDK_9)
+ return ukeyval;
- switch (vk)
+ switch (ukeyval)
{
- case GDK_Alt_L:
- case GDK_Alt_R:
- return VK_ALT;
+ case GDK_Return:
+ case GDK_KP_Enter:
+ return VK_ENTER;
case GDK_BackSpace:
return VK_BACK_SPACE;
+ case GDK_Tab:
+ return VK_TAB;
case GDK_Cancel:
return VK_CANCEL;
- case GDK_Caps_Lock:
- return VK_CAPS_LOCK;
case GDK_Clear:
return VK_CLEAR;
- case GDK_bracketright:
- return VK_CLOSE_BRACKET;
- case GDK_comma:
- return VK_COMMA;
+ case GDK_Shift_L:
+ case GDK_Shift_R:
+ return VK_SHIFT;
case GDK_Control_L:
case GDK_Control_R:
return VK_CONTROL;
+ case GDK_Alt_L:
+ case GDK_Alt_R:
+ return VK_ALT;
+ case GDK_Pause:
+ return VK_PAUSE;
+ case GDK_Caps_Lock:
+ return VK_CAPS_LOCK;
+ case GDK_Escape:
+ return VK_ESCAPE;
+ case GDK_space:
+ return VK_SPACE;
+ case GDK_KP_Page_Up:
+ /* For keys on the numeric keypad, the JVM produces one of two
+ virtual keys, depending on the num lock state. */
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD9;
+ else
+ return VK_PAGE_UP;
+ case GDK_Page_Up:
+ return VK_PAGE_UP;
+ case GDK_KP_Page_Down:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD3;
+ else
+ return VK_PAGE_DOWN;
+ case GDK_Page_Down:
+ return VK_PAGE_DOWN;
+ case GDK_KP_End:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD1;
+ else
+ return VK_END;
+ case GDK_End:
+ return VK_END;
+ case GDK_KP_Home:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD7;
+ else
+ return VK_HOME;
+ case GDK_Home:
+ return VK_HOME;
+ case GDK_KP_Begin:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD5;
+ else
+ return VK_UNDEFINED;
+ case GDK_Left:
+ return VK_LEFT;
+ case GDK_Up:
+ return VK_UP;
+ case GDK_Right:
+ return VK_RIGHT;
+ case GDK_Down:
+ return VK_DOWN;
+ case GDK_comma:
+ return VK_COMMA;
+ case GDK_minus:
+ return VK_MINUS;
+ case GDK_period:
+ return VK_PERIOD;
+ case GDK_slash:
+ return VK_SLASH;
+ /*
+ return VK_0;
+ return VK_1;
+ return VK_2;
+ return VK_3;
+ return VK_4;
+ return VK_5;
+ return VK_6;
+ return VK_7;
+ return VK_8;
+ return VK_9;
+ */
+ case GDK_semicolon:
+ return VK_SEMICOLON;
+ case GDK_equal:
+ return VK_EQUALS;
+ /*
+ return VK_A;
+ return VK_B;
+ return VK_C;
+ return VK_D;
+ return VK_E;
+ return VK_F;
+ return VK_G;
+ return VK_H;
+ return VK_I;
+ return VK_J;
+ return VK_K;
+ return VK_L;
+ return VK_M;
+ return VK_N;
+ return VK_O;
+ return VK_P;
+ return VK_Q;
+ return VK_R;
+ return VK_S;
+ return VK_T;
+ return VK_U;
+ return VK_V;
+ return VK_W;
+ return VK_X;
+ return VK_Y;
+ return VK_Z;
+ */
+ case GDK_bracketleft:
+ return VK_OPEN_BRACKET;
+ case GDK_backslash:
+ return VK_BACK_SLASH;
+ case GDK_bracketright:
+ return VK_CLOSE_BRACKET;
+ case GDK_KP_0:
+ return VK_NUMPAD0;
+ case GDK_KP_1:
+ return VK_NUMPAD1;
+ case GDK_KP_2:
+ return VK_NUMPAD2;
+ case GDK_KP_3:
+ return VK_NUMPAD3;
+ case GDK_KP_4:
+ return VK_NUMPAD4;
+ case GDK_KP_5:
+ return VK_NUMPAD5;
+ case GDK_KP_6:
+ return VK_NUMPAD6;
+ case GDK_KP_7:
+ return VK_NUMPAD7;
+ case GDK_KP_8:
+ return VK_NUMPAD8;
+ case GDK_KP_9:
+ return VK_NUMPAD9;
+ case GDK_KP_Multiply:
+ return VK_MULTIPLY;
+ case GDK_KP_Add:
+ return VK_ADD;
+ /*
+ return VK_SEPARATER;
+ */
+ case GDK_KP_Separator:
+ return VK_SEPARATOR;
+ case GDK_KP_Subtract:
+ return VK_SUBTRACT;
case GDK_KP_Decimal:
return VK_DECIMAL;
- case GDK_Delete:
- return VK_DELETE;
case GDK_KP_Divide:
return VK_DIVIDE;
- case GDK_Down:
- return VK_DOWN;
- case GDK_End:
- return VK_END;
- case GDK_Return:
- return VK_ENTER;
- case GDK_Escape:
- return VK_ESCAPE;
+ case GDK_KP_Delete:
+ if (state & GDK_MOD2_MASK)
+ return VK_DECIMAL;
+ else
+ return VK_DELETE;
+ case GDK_Delete:
+ return VK_DELETE;
+ case GDK_Num_Lock:
+ return VK_NUM_LOCK;
+ case GDK_Scroll_Lock:
+ return VK_SCROLL_LOCK;
case GDK_F1:
return VK_F1;
case GDK_F2:
@@ -154,100 +404,410 @@ keysym_to_awt_keycode (guint keyval)
return VK_F11;
case GDK_F12:
return VK_F12;
- case GDK_Help:
- return VK_HELP;
- case GDK_Home:
- return VK_HOME;
+ case GDK_F13:
+ return VK_F13;
+ case GDK_F14:
+ return VK_F14;
+ case GDK_F15:
+ return VK_F15;
+ case GDK_F16:
+ return VK_F16;
+ case GDK_F17:
+ return VK_F17;
+ case GDK_F18:
+ return VK_F18;
+ case GDK_F19:
+ return VK_F19;
+ case GDK_F20:
+ return VK_F20;
+ case GDK_F21:
+ return VK_F21;
+ case GDK_F22:
+ return VK_F22;
+ case GDK_F23:
+ return VK_F23;
+ case GDK_F24:
+ return VK_F24;
+ case GDK_Print:
+ return VK_PRINTSCREEN;
+ case GDK_KP_Insert:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD0;
+ else
+ return VK_INSERT;
case GDK_Insert:
return VK_INSERT;
+ case GDK_Help:
+ return VK_HELP;
+ case GDK_Meta_L:
+ case GDK_Meta_R:
+ return VK_META;
+ case GDK_grave:
+ return VK_BACK_QUOTE;
+ case GDK_apostrophe:
+ return VK_QUOTE;
+ case GDK_KP_Up:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD8;
+ else
+ return VK_KP_UP;
+ case GDK_KP_Down:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD2;
+ else
+ return VK_KP_DOWN;
+ case GDK_KP_Left:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD4;
+ else
+ return VK_KP_LEFT;
+ case GDK_KP_Right:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD6;
+ else
+ return VK_KP_RIGHT;
+ case GDK_dead_grave:
+ return VK_DEAD_GRAVE;
+ case GDK_dead_acute:
+ return VK_DEAD_ACUTE;
+ case GDK_dead_circumflex:
+ return VK_DEAD_CIRCUMFLEX;
+ case GDK_dead_tilde:
+ return VK_DEAD_TILDE;
+ case GDK_dead_macron:
+ return VK_DEAD_MACRON;
+ case GDK_dead_breve:
+ return VK_DEAD_BREVE;
+ case GDK_dead_abovedot:
+ return VK_DEAD_ABOVEDOT;
+ case GDK_dead_diaeresis:
+ return VK_DEAD_DIAERESIS;
+ case GDK_dead_abovering:
+ return VK_DEAD_ABOVERING;
+ case GDK_dead_doubleacute:
+ return VK_DEAD_DOUBLEACUTE;
+ case GDK_dead_caron:
+ return VK_DEAD_CARON;
+ case GDK_dead_cedilla:
+ return VK_DEAD_CEDILLA;
+ case GDK_dead_ogonek:
+ return VK_DEAD_OGONEK;
+ case GDK_dead_iota:
+ return VK_DEAD_IOTA;
+ case GDK_dead_voiced_sound:
+ return VK_DEAD_VOICED_SOUND;
+ case GDK_dead_semivoiced_sound:
+ return VK_DEAD_SEMIVOICED_SOUND;
+ case GDK_ampersand:
+ return VK_AMPERSAND;
+ case GDK_asterisk:
+ return VK_ASTERISK;
+ case GDK_quotedbl:
+ return VK_QUOTEDBL;
+ case GDK_less:
+ return VK_LESS;
+ case GDK_greater:
+ return VK_GREATER;
+ case GDK_braceleft:
+ return VK_BRACELEFT;
+ case GDK_braceright:
+ return VK_BRACERIGHT;
+ case GDK_at:
+ return VK_AT;
+ case GDK_colon:
+ return VK_COLON;
+ case GDK_asciicircum:
+ return VK_CIRCUMFLEX;
+ case GDK_dollar:
+ return VK_DOLLAR;
+ case GDK_EuroSign:
+ return VK_EURO_SIGN;
+ case GDK_exclam:
+ return VK_EXCLAMATION_MARK;
+ case GDK_exclamdown:
+ return VK_INVERTED_EXCLAMATION_MARK;
+ case GDK_parenleft:
+ return VK_LEFT_PARENTHESIS;
+ case GDK_numbersign:
+ return VK_NUMBER_SIGN;
+ case GDK_plus:
+ return VK_PLUS;
+ case GDK_parenright:
+ return VK_RIGHT_PARENTHESIS;
+ case GDK_underscore:
+ return VK_UNDERSCORE;
+ /*
+ return VK_FINAL;
+ return VK_CONVERT;
+ return VK_NONCONVERT;
+ return VK_ACCEPT;
+ */
+ case GDK_Mode_switch:
+ return VK_MODECHANGE;
+ /*
+ return VK_KANA;
+ */
case GDK_Kanji:
return VK_KANJI;
- case GDK_Left:
- return VK_LEFT;
+ /*
+ return VK_ALPHANUMERIC;
+ */
+ case GDK_Katakana:
+ return VK_KATAKANA;
+ case GDK_Hiragana:
+ return VK_HIRAGANA;
+ /*
+ return VK_FULL_WIDTH;
+ return VK_HALF_WIDTH;
+ return VK_ROMAN_CHARACTERS;
+ return VK_ALL_CANDIDATES;
+ */
+ case GDK_PreviousCandidate:
+ return VK_PREVIOUS_CANDIDATE;
+ case GDK_Codeinput:
+ return VK_CODE_INPUT;
+ /*
+ return VK_JAPANESE_KATAKANA;
+ return VK_JAPANESE_HIRAGANA;
+ return VK_JAPANESE_ROMAN;
+ */
+ case GDK_Kana_Lock:
+ return VK_KANA_LOCK;
+ /*
+ return VK_INPUT_METHOD_ON_OFF;
+ return VK_CUT;
+ return VK_COPY;
+ return VK_PASTE;
+ return VK_UNDO;
+ return VK_AGAIN;
+ return VK_FIND;
+ return VK_PROPS;
+ return VK_STOP;
+ return VK_COMPOSE;
+ return VK_ALT_GRAPH;
+ */
+ default:
+ return VK_UNDEFINED;
+ }
+}
+
+static jint
+keysym_to_awt_keylocation (GdkEvent *event)
+{
+ guint ukeyval;
+
+ ukeyval = get_first_keyval_from_keymap (event);
+
+ /* VK_A through VK_Z */
+ if (ukeyval >= GDK_A && ukeyval <= GDK_Z)
+ return AWT_KEY_LOCATION_STANDARD;
+
+ /* VK_0 through VK_9 */
+ if (ukeyval >= GDK_0 && ukeyval <= GDK_9)
+ return AWT_KEY_LOCATION_STANDARD;
+
+ switch (ukeyval)
+ {
+ case GDK_Shift_L:
+ case GDK_Control_L:
+ case GDK_Alt_L:
case GDK_Meta_L:
+ return AWT_KEY_LOCATION_LEFT;
+
+ case GDK_Shift_R:
+ case GDK_Control_R:
+ case GDK_Alt_R:
case GDK_Meta_R:
- return VK_META;
- case GDK_KP_Multiply:
- return VK_MULTIPLY;
- case GDK_Num_Lock:
- return VK_NUM_LOCK;
+ return AWT_KEY_LOCATION_RIGHT;
+
+ case GDK_Return:
+ case GDK_BackSpace:
+ case GDK_Tab:
+ case GDK_Cancel:
+ case GDK_Clear:
+ case GDK_Pause:
+ case GDK_Caps_Lock:
+ case GDK_Escape:
+ case GDK_space:
+ case GDK_Page_Up:
+ case GDK_Page_Down:
+ case GDK_End:
+ case GDK_Home:
+ case GDK_Left:
+ case GDK_Up:
+ case GDK_Right:
+ case GDK_Down:
+ case GDK_comma:
+ case GDK_minus:
+ case GDK_period:
+ case GDK_slash:
+ case GDK_semicolon:
+ case GDK_equal:
+ case GDK_bracketleft:
+ case GDK_backslash:
+ case GDK_bracketright:
+ case GDK_Delete:
+ case GDK_Scroll_Lock:
+ case GDK_F1:
+ case GDK_F2:
+ case GDK_F3:
+ case GDK_F4:
+ case GDK_F5:
+ case GDK_F6:
+ case GDK_F7:
+ case GDK_F8:
+ case GDK_F9:
+ case GDK_F10:
+ case GDK_F11:
+ case GDK_F12:
+ case GDK_F13:
+ case GDK_F14:
+ case GDK_F15:
+ case GDK_F16:
+ case GDK_F17:
+ case GDK_F18:
+ case GDK_F19:
+ case GDK_F20:
+ case GDK_F21:
+ case GDK_F22:
+ case GDK_F23:
+ case GDK_F24:
+ case GDK_Print:
+ case GDK_Insert:
+ case GDK_Help:
+ case GDK_grave:
+ case GDK_apostrophe:
+ case GDK_dead_grave:
+ case GDK_dead_acute:
+ case GDK_dead_circumflex:
+ case GDK_dead_tilde:
+ case GDK_dead_macron:
+ case GDK_dead_breve:
+ case GDK_dead_abovedot:
+ case GDK_dead_diaeresis:
+ case GDK_dead_abovering:
+ case GDK_dead_doubleacute:
+ case GDK_dead_caron:
+ case GDK_dead_cedilla:
+ case GDK_dead_ogonek:
+ case GDK_dead_iota:
+ case GDK_dead_voiced_sound:
+ case GDK_dead_semivoiced_sound:
+ case GDK_ampersand:
+ case GDK_asterisk:
+ case GDK_quotedbl:
+ case GDK_less:
+ case GDK_greater:
+ case GDK_braceleft:
+ case GDK_braceright:
+ case GDK_at:
+ case GDK_colon:
+ case GDK_asciicircum:
+ case GDK_dollar:
+ case GDK_EuroSign:
+ case GDK_exclam:
+ case GDK_exclamdown:
+ case GDK_parenleft:
+ case GDK_numbersign:
+ case GDK_plus:
+ case GDK_parenright:
+ case GDK_underscore:
+ case GDK_Mode_switch:
+ case GDK_Kanji:
+ case GDK_Katakana:
+ case GDK_Hiragana:
+ case GDK_PreviousCandidate:
+ case GDK_Codeinput:
+ case GDK_Kana_Lock:
+ return AWT_KEY_LOCATION_STANDARD;
+
+ case GDK_KP_Enter:
+ case GDK_KP_Page_Up:
+ case GDK_KP_Page_Down:
+ case GDK_KP_End:
+ case GDK_KP_Home:
+ case GDK_KP_Begin:
case GDK_KP_0:
- return VK_NUMPAD0;
case GDK_KP_1:
- return VK_NUMPAD1;
case GDK_KP_2:
- return VK_NUMPAD2;
case GDK_KP_3:
- return VK_NUMPAD3;
case GDK_KP_4:
- return VK_NUMPAD4;
case GDK_KP_5:
- return VK_NUMPAD5;
case GDK_KP_6:
- return VK_NUMPAD6;
case GDK_KP_7:
- return VK_NUMPAD7;
case GDK_KP_8:
- return VK_NUMPAD8;
case GDK_KP_9:
- return VK_NUMPAD9;
- case GDK_bracketleft:
- return VK_OPEN_BRACKET;
- case GDK_Page_Down:
- return VK_PAGE_DOWN;
- case GDK_Page_Up:
- return VK_PAGE_UP;
- case GDK_Pause:
- return VK_PAUSE;
- case GDK_period:
- return VK_PERIOD;
- case GDK_Print:
- return VK_PRINTSCREEN;
- case GDK_quoteright:
- return VK_QUOTE;
- case GDK_Right:
- return VK_RIGHT;
- case GDK_Scroll_Lock:
- return VK_SCROLL_LOCK;
- case GDK_semicolon:
- return VK_SEMICOLON;
+ case GDK_KP_Multiply:
+ case GDK_KP_Add:
case GDK_KP_Separator:
- return VK_SEPARATOR;
- case GDK_Shift_L:
- case GDK_Shift_R:
- return VK_SHIFT;
- case GDK_slash:
- return VK_SLASH;
- case GDK_space:
- return VK_SPACE;
case GDK_KP_Subtract:
- return VK_SUBTRACT;
- case GDK_Tab:
- return VK_TAB;
- case GDK_Up:
- return VK_UP;
+ case GDK_KP_Decimal:
+ case GDK_KP_Divide:
+ case GDK_KP_Delete:
+ case GDK_Num_Lock:
+ case GDK_KP_Insert:
+ case GDK_KP_Up:
+ case GDK_KP_Down:
+ case GDK_KP_Left:
+ case GDK_KP_Right:
+ return AWT_KEY_LOCATION_NUMPAD;
default:
- return VK_UNDEFINED;
+ return AWT_KEY_LOCATION_UNKNOWN;
}
}
+static jchar
+keyevent_to_awt_keychar (GdkEvent *event)
+{
+ if (event->key.length > 0)
+ {
+ /* Translate GDK carriage return to Java linefeed. */
+ if (event->key.string[0] == 13)
+ return VK_ENTER;
+ else
+ return event->key.string[0];
+ }
+ else
+ {
+ switch (event->key.keyval)
+ {
+ case GDK_BackSpace:
+ return VK_BACK_SPACE;
+ case GDK_Tab:
+ return VK_TAB;
+ case GDK_Delete:
+ case GDK_KP_Delete:
+ return VK_DELETE;
+ default:
+ return AWT_KEY_CHAR_UNDEFINED;
+ }
+ }
+}
+
+/* Checks if keyval triggers a KEY_TYPED event on the source widget.
+ This function identifies special keyvals that don't trigger
+ GtkIMContext "commit" signals, but that do trigger Java KEY_TYPED
+ events. */
static int
-generates_key_typed_event (guint keyval)
+generates_key_typed_event (GdkEvent *event, GtkWidget *source)
{
- guint vk;
+ guint keyval;
- vk = gdk_keyval_to_upper (keyval);
+ if (!GTK_IS_ENTRY (source)
+ && !GTK_IS_TEXT_VIEW (source))
+ return event->key.length ? 1 : 0;
- if ((vk >= 0x20 && vk <= 0x7e) /* Most printable keysyms on a
- standard US keyboard. */
- || (vk >= 0xFF9F && vk <= 0xFFB9) /* Numeric Keypad keysyms. */
- || vk == GDK_BackSpace
- || vk == GDK_Delete
- || vk == GDK_Return)
- return 1;
- else
- return 0;
+ keyval = event->key.keyval;
+
+ return (keyval == GDK_Escape
+ || keyval == GDK_BackSpace
+ || keyval == GDK_Delete
+ || keyval == GDK_KP_Delete
+ || keyval == GDK_Return
+ || keyval == GDK_KP_Enter
+ || (keyval == GDK_Tab
+ && GTK_IS_TEXT_VIEW(source))) ? 1 : 0;
}
void
@@ -465,19 +1025,30 @@ awt_event_handler (GdkEvent *event)
{
GtkWidget *widget;
GtkWindow *window;
+ /* The window to which the Java peer is attached. */
+ GdkWindow *obj_window;
gdk_window_get_user_data (event->any.window, (void **) &widget);
window = GTK_WINDOW (gtk_widget_get_ancestor (widget,
GTK_TYPE_WINDOW));
if (window
- && GTK_WIDGET_IS_SENSITIVE (window)
+ && GTK_WIDGET_IS_SENSITIVE (window)
&& window->focus_widget
&& GTK_WIDGET_IS_SENSITIVE (window->focus_widget)
&& window->focus_widget->window)
{
gtk_widget_activate (window->focus_widget);
- gdk_property_get (window->focus_widget->window,
+
+ /* TextArea peers are attached to the scrolled window
+ that contains the GtkTextView, not to the text view
+ itself. */
+ if (GTK_IS_TEXT_VIEW (window->focus_widget))
+ obj_window = gtk_widget_get_parent (window->focus_widget)->window;
+ else
+ obj_window = window->focus_widget->window;
+
+ gdk_property_get (obj_window,
gdk_atom_intern ("_GNU_GTKAWT_ADDR", FALSE),
gdk_atom_intern ("CARDINAL", FALSE),
0,
@@ -488,27 +1059,24 @@ awt_event_handler (GdkEvent *event)
NULL,
(guchar **)&obj_ptr);
- /* if (grab && GTK_WIDGET_HAS_DEFAULT (widget) ) */
- /* { */
(*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
postKeyEventID,
(jint) AWT_KEY_PRESSED,
(jlong) event->key.time,
- state_to_awt_mods (event->key.state),
- keysym_to_awt_keycode (event->key.keyval),
- (jchar) (event->key.length) ?
- event->key.string[0] :
- AWT_KEY_CHAR_UNDEFINED);
-
- if (event->key.length
- && generates_key_typed_event(event->key.keyval))
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
- postKeyEventID,
- (jint) AWT_KEY_TYPED,
- (jlong) event->key.time,
+ keyevent_state_to_awt_mods (event),
+ keysym_to_awt_keycode (event),
+ keyevent_to_awt_keychar (event),
+ keysym_to_awt_keylocation (event));
+
+ if (generates_key_typed_event (event, window->focus_widget))
+ (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
+ postKeyEventID,
+ (jint) AWT_KEY_TYPED,
+ (jlong) event->key.time,
state_to_awt_mods (event->key.state),
- VK_UNDEFINED,
- (jchar) event->key.string[0]);
+ VK_UNDEFINED,
+ keyevent_to_awt_keychar (event),
+ AWT_KEY_LOCATION_UNKNOWN);
}
}
break;
@@ -516,6 +1084,7 @@ awt_event_handler (GdkEvent *event)
{
GtkWidget *widget;
GtkWindow *window;
+ GdkWindow *obj_window;
gdk_window_get_user_data (event->any.window, (void **) &widget);
@@ -528,7 +1097,13 @@ awt_event_handler (GdkEvent *event)
&& window->focus_widget->window)
{
gtk_widget_activate (window->focus_widget);
- gdk_property_get (window->focus_widget->window,
+
+ if (GTK_IS_TEXT_VIEW (window->focus_widget))
+ obj_window = gtk_widget_get_parent (window->focus_widget)->window;
+ else
+ obj_window = window->focus_widget->window;
+
+ gdk_property_get (obj_window,
gdk_atom_intern ("_GNU_GTKAWT_ADDR", FALSE),
gdk_atom_intern ("CARDINAL", FALSE),
0,
@@ -543,11 +1118,10 @@ awt_event_handler (GdkEvent *event)
postKeyEventID,
(jint) AWT_KEY_RELEASED,
(jlong) event->key.time,
- state_to_awt_mods (event->key.state),
- keysym_to_awt_keycode (event->key.keyval),
- (jchar) (event->key.length) ?
- event->key.string[0] :
- AWT_KEY_CHAR_UNDEFINED);
+ keyevent_state_to_awt_mods (event),
+ keysym_to_awt_keycode (event),
+ keyevent_to_awt_keychar (event),
+ keysym_to_awt_keylocation (event));
}
}
break;
@@ -558,11 +1132,11 @@ awt_event_handler (GdkEvent *event)
AWT_FOCUS_GAINED : AWT_FOCUS_LOST,
JNI_FALSE);
break;
- default:
+ default:
}
g_free (obj_ptr);
- }
-
+ }
+
gtk_main_do_event (event);
}