1 /* gtkwindowpeer.c -- Native implementation of GtkWindowPeer
2 Copyright (C) 1998, 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
40 #include "gnu_java_awt_peer_gtk_GtkWindowPeer.h"
41 #include <gdk/gdkprivate.h>
43 #include <X11/Xatom.h>
44 #include <gdk/gdkkeysyms.h>
46 #define AWT_WINDOW_OPENED 200
47 #define AWT_WINDOW_CLOSING 201
48 #define AWT_WINDOW_CLOSED 202
49 #define AWT_WINDOW_ICONIFIED 203
50 #define AWT_WINDOW_DEICONIFIED 204
51 #define AWT_WINDOW_ACTIVATED 205
52 #define AWT_WINDOW_DEACTIVATED 206
53 #define AWT_WINDOW_GAINED_FOCUS 207
54 #define AWT_WINDOW_LOST_FOCUS 208
55 #define AWT_WINDOW_STATE_CHANGED 209
58 /* This list should be kept in the same order as the VK_ field
59 declarations in KeyEvent.java. */
61 #define VK_BACK_SPACE '\b'
69 #define VK_CAPS_LOCK 20
73 #define VK_PAGE_DOWN 34
94 #define VK_SEMICOLON ';'
122 #define VK_OPEN_BRACKET '['
123 #define VK_BACK_SLASH '\\'
124 #define VK_CLOSE_BRACKET ']'
126 /* #define VK_NUMPAD0 96 */
127 /* #define VK_NUMPAD1 97 */
128 /* #define VK_NUMPAD2 98 */
129 /* #define VK_NUMPAD3 99 */
130 /* #define VK_NUMPAD4 100 */
131 /* #define VK_NUMPAD5 101 */
132 /* #define VK_NUMPAD6 102 */
133 /* #define VK_NUMPAD7 103 */
134 /* #define VK_NUMPAD8 104 */
135 /* #define VK_NUMPAD9 105 */
136 #define VK_MULTIPLY 106
138 #define VK_SEPARATER 108
139 #define VK_SEPARATOR 108
140 #define VK_SUBTRACT 109
142 /* #define VK_DECIMAL 110 */
143 #define VK_DIVIDE 111
144 #define VK_DELETE 127
145 #define VK_NUM_LOCK 144
146 #define VK_SCROLL_LOCK 145
171 #define VK_PRINTSCREEN 154
172 #define VK_INSERT 155
175 #define VK_BACK_QUOTE 192
178 #define VK_KP_DOWN 225
179 #define VK_KP_LEFT 226
180 #define VK_KP_RIGHT 227
181 #define VK_DEAD_GRAVE 128
182 #define VK_DEAD_ACUTE 129
183 #define VK_DEAD_CIRCUMFLEX 130
184 #define VK_DEAD_TILDE 131
185 #define VK_DEAD_MACRON 132
186 #define VK_DEAD_BREVE 133
187 #define VK_DEAD_ABOVEDOT 134
188 #define VK_DEAD_DIAERESIS 135
189 #define VK_DEAD_ABOVERING 136
190 #define VK_DEAD_DOUBLEACUTE 137
191 #define VK_DEAD_CARON 138
192 #define VK_DEAD_CEDILLA 139
193 #define VK_DEAD_OGONEK 140
194 #define VK_DEAD_IOTA 141
195 #define VK_DEAD_VOICED_SOUND 142
196 #define VK_DEAD_SEMIVOICED_SOUND 143
197 #define VK_AMPERSAND 150
198 #define VK_ASTERISK 151
199 #define VK_QUOTEDBL 152
201 #define VK_GREATER 160
202 #define VK_BRACELEFT 161
203 #define VK_BRACERIGHT 162
206 #define VK_CIRCUMFLEX 514
207 #define VK_DOLLAR 515
208 #define VK_EURO_SIGN 516
209 #define VK_EXCLAMATION_MARK 517
210 #define VK_INVERTED_EXCLAMATION_MARK 518
211 #define VK_LEFT_PARENTHESIS 519
212 #define VK_NUMBER_SIGN 520
214 #define VK_RIGHT_PARENTHESIS 522
215 #define VK_UNDERSCORE 523
217 #define VK_CONVERT 28
218 #define VK_NONCONVERT 29
220 #define VK_MODECHANGE 31
223 #define VK_ALPHANUMERIC 240
224 #define VK_KATAKANA 241
225 #define VK_HIRAGANA 242
226 #define VK_FULL_WIDTH 243
227 #define VK_HALF_WIDTH 244
228 #define VK_ROMAN_CHARACTERS 245
229 #define VK_ALL_CANDIDATES 256
230 #define VK_PREVIOUS_CANDIDATE 257
231 #define VK_CODE_INPUT 258
232 #define VK_JAPANESE_KATAKANA 259
233 #define VK_JAPANESE_HIRAGANA 260
234 #define VK_JAPANESE_ROMAN 261
235 #define VK_KANA_LOCK 262
236 #define VK_INPUT_METHOD_ON_OFF 263
238 #define VK_COPY 65485
239 #define VK_PASTE 65487
240 #define VK_UNDO 65483
241 #define VK_AGAIN 65481
242 #define VK_FIND 65488
243 #define VK_PROPS 65482
244 #define VK_STOP 65480
245 #define VK_COMPOSE 65312
246 #define VK_ALT_GRAPH 65406
247 #define VK_UNDEFINED 0
249 #define AWT_KEY_CHAR_UNDEFINED 0
251 #define AWT_FRAME_STATE_NORMAL 0
252 #define AWT_FRAME_STATE_ICONIFIED 1
253 #define AWT_FRAME_STATE_MAXIMIZED_HORIZ 2
254 #define AWT_FRAME_STATE_MAXIMIZED_VERT 4
255 #define AWT_FRAME_STATE_MAXIMIZED_BOTH 6
257 static jmethodID postKeyEventID
;
258 static jmethodID postWindowEventID
;
259 static jmethodID postConfigureEventID
;
260 static jmethodID postInsetsChangedEventID
;
261 static jmethodID windowGetWidthID
;
262 static jmethodID windowGetHeightID
;
265 cp_gtk_window_init_jni (void)
267 jclass gtkwindowpeer
;
269 gtkwindowpeer
= (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
270 "gnu/java/awt/peer/gtk/GtkWindowPeer");
272 postKeyEventID
= (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer
,
273 "postKeyEvent", "(IJIICI)V");
275 postWindowEventID
= (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer
,
277 "(ILjava/awt/Window;I)V");
279 postConfigureEventID
= (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer
,
280 "postConfigureEvent", "(IIII)V");
282 postInsetsChangedEventID
= (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer
,
283 "postInsetsChangedEvent",
286 windowGetWidthID
= (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer
,
289 windowGetHeightID
= (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer
,
292 gtkwindowpeer
= (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
293 "gnu/java/awt/peer/gtk/GtkWindowPeer");
296 /* Get the first keyval in the keymap for this event's keycode. The
297 first keyval corresponds roughly to Java's notion of a virtual key.
298 Returns the uppercase version of the first keyval or -1 if no
299 keyval was found for the given hardware keycode. */
301 get_first_keyval_from_keymap (GdkEventKey
*event
)
307 if (!gdk_keymap_get_entries_for_keycode (NULL
,
308 event
->hardware_keycode
,
313 /* No keyval found for hardware keycode */
319 return gdk_keyval_to_upper (keyval
);
322 /* Return the AWT key code for the given keysym or -1 if no keyval was
323 found for the given hardware keycode. */
328 keysym_to_awt_keycode (GdkEventKey
*event
)
333 ukeyval
= get_first_keyval_from_keymap (event
);
338 state
= event
->state
;
340 /* VK_A through VK_Z */
341 if (ukeyval
>= GDK_A
&& ukeyval
<= GDK_Z
)
344 /* VK_0 through VK_9 */
345 if (ukeyval
>= GDK_0
&& ukeyval
<= GDK_9
)
354 return VK_BACK_SPACE
;
379 /* For keys on the numeric keypad, the JVM produces one of two
380 virtual keys, depending on the num lock state. */
381 if (state
& GDK_MOD2_MASK
)
387 case GDK_KP_Page_Down
:
388 if (state
& GDK_MOD2_MASK
)
395 if (state
& GDK_MOD2_MASK
)
402 if (state
& GDK_MOD2_MASK
)
409 if (state
& GDK_MOD2_MASK
)
473 case GDK_bracketleft
:
474 return VK_OPEN_BRACKET
;
476 return VK_BACK_SLASH
;
477 case GDK_bracketright
:
478 return VK_CLOSE_BRACKET
;
499 case GDK_KP_Multiply
:
506 case GDK_KP_Separator
:
508 case GDK_KP_Subtract
:
515 if (state
& GDK_MOD2_MASK
)
523 case GDK_Scroll_Lock
:
524 return VK_SCROLL_LOCK
;
574 return VK_PRINTSCREEN
;
576 if (state
& GDK_MOD2_MASK
)
588 return VK_BACK_QUOTE
;
592 if (state
& GDK_MOD2_MASK
)
597 if (state
& GDK_MOD2_MASK
)
602 if (state
& GDK_MOD2_MASK
)
607 if (state
& GDK_MOD2_MASK
)
612 return VK_DEAD_GRAVE
;
614 return VK_DEAD_ACUTE
;
615 case GDK_dead_circumflex
:
616 return VK_DEAD_CIRCUMFLEX
;
618 return VK_DEAD_TILDE
;
619 case GDK_dead_macron
:
620 return VK_DEAD_MACRON
;
622 return VK_DEAD_BREVE
;
623 case GDK_dead_abovedot
:
624 return VK_DEAD_ABOVEDOT
;
625 case GDK_dead_diaeresis
:
626 return VK_DEAD_DIAERESIS
;
627 case GDK_dead_abovering
:
628 return VK_DEAD_ABOVERING
;
629 case GDK_dead_doubleacute
:
630 return VK_DEAD_DOUBLEACUTE
;
632 return VK_DEAD_CARON
;
633 case GDK_dead_cedilla
:
634 return VK_DEAD_CEDILLA
;
635 case GDK_dead_ogonek
:
636 return VK_DEAD_OGONEK
;
639 case GDK_dead_voiced_sound
:
640 return VK_DEAD_VOICED_SOUND
;
641 case GDK_dead_semivoiced_sound
:
642 return VK_DEAD_SEMIVOICED_SOUND
;
656 return VK_BRACERIGHT
;
661 case GDK_asciicircum
:
662 return VK_CIRCUMFLEX
;
668 return VK_EXCLAMATION_MARK
;
670 return VK_INVERTED_EXCLAMATION_MARK
;
672 return VK_LEFT_PARENTHESIS
;
674 return VK_NUMBER_SIGN
;
678 return VK_RIGHT_PARENTHESIS
;
680 return VK_UNDERSCORE
;
684 return VK_NONCONVERT;
687 case GDK_Mode_switch
:
688 return VK_MODECHANGE
;
695 return VK_ALPHANUMERIC;
702 return VK_FULL_WIDTH;
703 return VK_HALF_WIDTH;
704 return VK_ROMAN_CHARACTERS;
705 return VK_ALL_CANDIDATES;
707 case GDK_PreviousCandidate
:
708 return VK_PREVIOUS_CANDIDATE
;
710 return VK_CODE_INPUT
;
712 return VK_JAPANESE_KATAKANA;
713 return VK_JAPANESE_HIRAGANA;
714 return VK_JAPANESE_ROMAN;
719 return VK_INPUT_METHOD_ON_OFF;
736 /* Return the AWT key location code for the given keysym or -1 if no
737 keyval was found for the given hardware keycode. */
739 keysym_to_awt_keylocation (GdkEventKey
*event
)
743 ukeyval
= get_first_keyval_from_keymap (event
);
748 /* VK_A through VK_Z */
749 if (ukeyval
>= GDK_A
&& ukeyval
<= GDK_Z
)
750 return AWT_KEY_LOCATION_STANDARD
;
752 /* VK_0 through VK_9 */
753 if (ukeyval
>= GDK_0
&& ukeyval
<= GDK_9
)
754 return AWT_KEY_LOCATION_STANDARD
;
762 return AWT_KEY_LOCATION_LEFT
;
768 return AWT_KEY_LOCATION_RIGHT
;
793 case GDK_bracketleft
:
795 case GDK_bracketright
:
797 case GDK_Scroll_Lock
:
829 case GDK_dead_circumflex
:
831 case GDK_dead_macron
:
833 case GDK_dead_abovedot
:
834 case GDK_dead_diaeresis
:
835 case GDK_dead_abovering
:
836 case GDK_dead_doubleacute
:
838 case GDK_dead_cedilla
:
839 case GDK_dead_ogonek
:
841 case GDK_dead_voiced_sound
:
842 case GDK_dead_semivoiced_sound
:
852 case GDK_asciicircum
:
862 case GDK_Mode_switch
:
866 case GDK_PreviousCandidate
:
869 return AWT_KEY_LOCATION_STANDARD
;
873 case GDK_KP_Page_Down
:
887 case GDK_KP_Multiply
:
889 case GDK_KP_Separator
:
890 case GDK_KP_Subtract
:
900 return AWT_KEY_LOCATION_NUMPAD
;
903 return AWT_KEY_LOCATION_UNKNOWN
;
908 keyevent_to_awt_keychar (GdkEventKey
*event
)
910 if (event
->length
> 0)
912 /* Translate GDK carriage return to Java linefeed. */
913 if (event
->string
[0] == 13)
916 return event
->string
[0];
920 switch (event
->keyval
)
923 return VK_BACK_SPACE
;
930 return AWT_KEY_CHAR_UNDEFINED
;
935 /* Modifier key events need special treatment. In Sun's peer
936 implementation, when a modifier key is pressed, the KEY_PRESSED
937 event has that modifier in its modifiers list. The corresponding
938 KEY_RELEASED event's modifier list does not contain the modifier.
939 For example, pressing and releasing the shift key will produce a
940 key press event with modifiers=Shift, and a key release event with
941 no modifiers. GDK's key events behave in the exact opposite way,
942 so this translation code is needed. */
944 keyevent_state_to_awt_mods (GdkEventKey
*event
)
949 if (event
->type
== GDK_KEY_PRESS
)
951 state
= event
->state
;
953 if (event
->keyval
== GDK_Shift_L
954 || event
->keyval
== GDK_Shift_R
)
955 result
|= AWT_SHIFT_DOWN_MASK
| AWT_SHIFT_MASK
;
958 if (state
& GDK_SHIFT_MASK
)
959 result
|= AWT_SHIFT_DOWN_MASK
| AWT_SHIFT_MASK
;
962 if (event
->keyval
== GDK_Control_L
963 || event
->keyval
== GDK_Control_R
)
964 result
|= AWT_CTRL_DOWN_MASK
| AWT_CTRL_MASK
;
967 if (state
& GDK_CONTROL_MASK
)
968 result
|= AWT_CTRL_DOWN_MASK
| AWT_CTRL_MASK
;
971 if (event
->keyval
== GDK_Alt_L
972 || event
->keyval
== GDK_Alt_R
)
973 result
|= AWT_ALT_DOWN_MASK
| AWT_ALT_MASK
;
976 if (state
& GDK_MOD1_MASK
)
977 result
|= AWT_ALT_DOWN_MASK
| AWT_ALT_MASK
;
980 else if (event
->type
== GDK_KEY_RELEASE
)
982 state
= event
->state
;
984 if (event
->keyval
!= GDK_Shift_L
985 && event
->keyval
!= GDK_Shift_R
)
987 if (state
& GDK_SHIFT_MASK
)
988 result
|= AWT_SHIFT_DOWN_MASK
| AWT_SHIFT_MASK
;
990 if (event
->keyval
!= GDK_Control_L
991 && event
->keyval
!= GDK_Control_R
)
993 if (state
& GDK_CONTROL_MASK
)
994 result
|= AWT_CTRL_DOWN_MASK
| AWT_CTRL_MASK
;
997 if (event
->keyval
!= GDK_Alt_L
998 && event
->keyval
!= GDK_Alt_R
)
1000 if (state
& GDK_MOD1_MASK
)
1001 result
|= AWT_ALT_DOWN_MASK
| AWT_ALT_MASK
;
1008 static gboolean
window_configure_cb (GtkWidget
*widget
,
1009 GdkEventConfigure
*event
,
1012 /* FIXME: we're currently seeing the double-activation that occurs
1013 with metacity and GTK. See
1014 http://bugzilla.gnome.org/show_bug.cgi?id=140977 for details. */
1016 static void window_get_frame_extents (GtkWidget
*window
,
1017 int *top
, int *left
,
1018 int *bottom
, int *right
);
1020 static void request_frame_extents (GtkWidget
*window
);
1022 static Bool
property_notify_predicate (Display
*display
,
1026 static gboolean
window_delete_cb (GtkWidget
*widget
, GdkEvent
*event
,
1028 static void window_destroy_cb (GtkWidget
*widget
, GdkEvent
*event
,
1030 static void window_show_cb (GtkWidget
*widget
, jobject peer
);
1031 static void window_focus_state_change_cb (GtkWidget
*widget
,
1034 static gboolean
window_focus_in_cb (GtkWidget
* widget
,
1035 GdkEventFocus
*event
,
1037 static gboolean
window_focus_out_cb (GtkWidget
* widget
,
1038 GdkEventFocus
*event
,
1040 static gboolean
window_window_state_cb (GtkWidget
*widget
,
1043 static gboolean
window_property_changed_cb (GtkWidget
*widget
,
1044 GdkEventProperty
*event
,
1046 static void realize_cb (GtkWidget
*widget
, jobject peer
);
1049 window_configure_cb (GtkWidget
*widget
__attribute__((unused
)),
1050 GdkEventConfigure
*event
,
1053 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1054 postConfigureEventID
,
1057 (jint
) event
->width
,
1058 (jint
) event
->height
);
1064 key_press_cb (GtkWidget
*widget
__attribute__((unused
)),
1071 keycode
= keysym_to_awt_keycode (event
);
1072 keylocation
= keysym_to_awt_keylocation (event
);
1074 /* Return immediately if an error occurs translating a hardware
1075 keycode to a keyval. */
1076 if (keycode
< 0 || keylocation
< 0)
1079 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1081 (jint
) AWT_KEY_PRESSED
,
1082 (jlong
) event
->time
,
1083 keyevent_state_to_awt_mods (event
),
1085 keyevent_to_awt_keychar (event
),
1088 /* FIXME: generation of key typed events needs to be moved
1089 to GtkComponentPeer.postKeyEvent. If the key in a key
1090 press event is not an "action" key
1091 (KeyEvent.isActionKey) and is not a modifier key, then
1092 it should generate a key typed event. */
1098 key_release_cb (GtkWidget
*widget
__attribute__((unused
)),
1105 keycode
= keysym_to_awt_keycode (event
);
1106 keylocation
= keysym_to_awt_keylocation (event
);
1108 /* Return immediately if an error occurs translating a hardware
1109 keycode to a keyval. */
1110 if (keycode
< 0 || keylocation
< 0)
1113 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1115 (jint
) AWT_KEY_RELEASED
,
1116 (jlong
) event
->time
,
1117 keyevent_state_to_awt_mods (event
),
1119 keyevent_to_awt_keychar (event
),
1125 /* Union used for type punning. */
1128 guchar
**gu_extents
;
1129 unsigned long **extents
;
1132 union atom_list_union
1134 guchar
**gu_extents
;
1138 JNIEXPORT
void JNICALL
1139 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create
1140 (JNIEnv
*env
, jobject obj
, jint type
, jboolean decorated
, jobject parent
)
1142 GtkWidget
*window_widget
;
1144 void *window_parent
;
1147 gdk_threads_enter ();
1149 NSA_SET_GLOBAL_REF (env
, obj
);
1151 window_widget
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
1152 window
= GTK_WINDOW (window_widget
);
1154 /* Keep this window in front of its parent, if it has one. */
1157 window_parent
= NSA_GET_PTR (env
, parent
);
1158 gtk_window_set_transient_for (window
, GTK_WINDOW(window_parent
));
1161 gtk_window_set_decorated (window
, decorated
);
1163 gtk_window_set_type_hint (window
, type
);
1165 gtk_window_group_add_window (cp_gtk_global_window_group
, window
);
1167 fixed
= gtk_fixed_new ();
1169 gtk_container_add (GTK_CONTAINER (window_widget
), fixed
);
1171 gtk_widget_show (fixed
);
1173 NSA_SET_PTR (env
, obj
, window_widget
);
1175 gdk_threads_leave ();
1178 JNIEXPORT
void JNICALL
1179 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetTitle
1180 (JNIEnv
*env
, jobject obj
, jstring title
)
1182 const char *c_title
;
1185 gdk_threads_enter ();
1187 ptr
= NSA_GET_PTR (env
, obj
);
1189 c_title
= (*env
)->GetStringUTFChars (env
, title
, NULL
);
1191 gtk_window_set_title (GTK_WINDOW (ptr
), c_title
);
1193 (*env
)->ReleaseStringUTFChars (env
, title
, c_title
);
1195 gdk_threads_leave ();
1198 JNIEXPORT
void JNICALL
1199 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetResizable
1200 (JNIEnv
*env
, jobject obj
, jboolean resizable
)
1204 gdk_threads_enter ();
1206 ptr
= NSA_GET_PTR (env
, obj
);
1207 gtk_window_set_resizable (GTK_WINDOW (ptr
), resizable
);
1208 g_object_set (G_OBJECT (ptr
), "allow-shrink", resizable
, NULL
);
1210 gdk_threads_leave ();
1213 JNIEXPORT
void JNICALL
1214 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetModal
1215 (JNIEnv
*env
, jobject obj
, jboolean modal
)
1219 gdk_threads_enter ();
1221 ptr
= NSA_GET_PTR (env
, obj
);
1223 gtk_window_set_modal (GTK_WINDOW (ptr
), modal
);
1225 gdk_threads_leave ();
1228 JNIEXPORT
void JNICALL
1229 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setVisibleNative
1230 (JNIEnv
*env
, jobject obj
, jboolean visible
)
1232 gdk_threads_enter ();
1234 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setVisibleNativeUnlocked
1235 (env
, obj
, visible
);
1239 gdk_threads_leave ();
1242 JNIEXPORT
void JNICALL
1243 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setVisibleNativeUnlocked
1244 (JNIEnv
*env
, jobject obj
, jboolean visible
)
1248 ptr
= NSA_GET_PTR (env
, obj
);
1251 gtk_widget_show (GTK_WIDGET (ptr
));
1253 gtk_widget_hide (GTK_WIDGET (ptr
));
1256 JNIEXPORT
void JNICALL
1257 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals
1258 (JNIEnv
*env
, jobject obj
)
1263 gdk_threads_enter ();
1265 ptr
= NSA_GET_PTR (env
, obj
);
1266 gref
= NSA_GET_GLOBAL_REF (env
, obj
);
1268 g_signal_connect (G_OBJECT (ptr
), "delete-event",
1269 G_CALLBACK (window_delete_cb
), *gref
);
1271 g_signal_connect (G_OBJECT (ptr
), "destroy-event",
1272 G_CALLBACK (window_destroy_cb
), *gref
);
1274 g_signal_connect (G_OBJECT (ptr
), "show",
1275 G_CALLBACK (window_show_cb
), *gref
);
1277 g_signal_connect (G_OBJECT (ptr
), "notify::has-toplevel-focus",
1278 G_CALLBACK (window_focus_state_change_cb
), *gref
);
1280 g_signal_connect (G_OBJECT (ptr
), "focus-in-event",
1281 G_CALLBACK (window_focus_in_cb
), *gref
);
1283 g_signal_connect (G_OBJECT (ptr
), "focus-out-event",
1284 G_CALLBACK (window_focus_out_cb
), *gref
);
1286 g_signal_connect (G_OBJECT (ptr
), "window-state-event",
1287 G_CALLBACK (window_window_state_cb
), *gref
);
1289 g_signal_connect (G_OBJECT (ptr
), "property-notify-event",
1290 G_CALLBACK (window_property_changed_cb
), *gref
);
1292 g_signal_connect_after (G_OBJECT (ptr
), "realize",
1293 G_CALLBACK (realize_cb
), *gref
);
1295 g_signal_connect (G_OBJECT (ptr
), "key-press-event",
1296 G_CALLBACK (key_press_cb
), *gref
);
1298 g_signal_connect (G_OBJECT (ptr
), "key-release-event",
1299 G_CALLBACK (key_release_cb
), *gref
);
1301 g_signal_connect_after (G_OBJECT (ptr
), "window-state-event",
1302 G_CALLBACK (window_window_state_cb
), *gref
);
1304 g_signal_connect (G_OBJECT (ptr
), "configure-event",
1305 G_CALLBACK (window_configure_cb
), *gref
);
1307 cp_gtk_component_connect_expose_signals (ptr
, gref
);
1308 cp_gtk_component_connect_mouse_signals (ptr
, gref
);
1310 /* FIXME: override focus signals here to prevent child fixed repaint? */
1312 gdk_threads_leave ();
1315 /* Realize the window here so that its frame extents are known now.
1316 That way Window.pack can operate with the accurate insets returned
1317 by the window manager rather than the default estimates. */
1318 JNIEXPORT
void JNICALL
1319 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_realize (JNIEnv
*env
, jobject obj
)
1323 gdk_threads_enter ();
1325 ptr
= NSA_GET_PTR (env
, obj
);
1327 gtk_widget_realize (GTK_WIDGET (ptr
));
1329 gdk_threads_leave ();
1332 JNIEXPORT
void JNICALL
1333 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toBack (JNIEnv
*env
,
1338 gdk_threads_enter ();
1340 ptr
= NSA_GET_PTR (env
, obj
);
1342 gdk_window_lower (GTK_WIDGET (ptr
)->window
);
1345 gdk_threads_leave ();
1348 JNIEXPORT
void JNICALL
1349 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toFront (JNIEnv
*env
,
1354 gdk_threads_enter ();
1356 ptr
= NSA_GET_PTR (env
, obj
);
1358 gdk_window_raise (GTK_WIDGET (ptr
)->window
);
1361 gdk_threads_leave ();
1364 JNIEXPORT
void JNICALL
1365 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setSize
1366 (JNIEnv
*env
, jobject obj
, jint width
, jint height
)
1370 gdk_threads_enter ();
1372 ptr
= NSA_GET_PTR (env
, obj
);
1374 /* Avoid GTK runtime assertion failures. */
1375 width
= (width
< 1) ? 1 : width
;
1376 height
= (height
< 1) ? 1 : height
;
1378 gtk_widget_set_size_request (GTK_WIDGET(ptr
), width
, height
);
1380 gdk_threads_leave ();
1383 JNIEXPORT
void JNICALL
1384 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetBounds
1385 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
1387 gdk_threads_enter ();
1389 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetBoundsUnlocked
1390 (env
, obj
, x
, y
, width
, height
);
1392 gdk_threads_leave ();
1395 JNIEXPORT
void JNICALL
1396 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetBoundsUnlocked
1397 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
1401 ptr
= NSA_GET_PTR (env
, obj
);
1403 /* Avoid GTK runtime assertion failures. */
1404 width
= (width
< 1) ? 1 : width
;
1405 height
= (height
< 1) ? 1 : height
;
1407 gtk_window_move (GTK_WINDOW(ptr
), x
, y
);
1408 /* The call to gdk_window_move is needed in addition to the call to
1409 gtk_window_move. If gdk_window_move isn't called, then the
1410 following set of operations doesn't give the expected results:
1413 2. manually move it to another position on the screen
1415 4. reposition the window with Component.setLocation
1418 Instead of being at the position set by setLocation, the window
1419 is reshown at the position to which it was moved manually. */
1420 if (GTK_WIDGET (ptr
)->window
!= NULL
)
1421 gdk_window_move (GTK_WIDGET (ptr
)->window
, x
, y
);
1423 /* Need to change the widget's request size. */
1424 gtk_widget_set_size_request (GTK_WIDGET(ptr
), width
, height
);
1425 /* Also need to call gtk_window_resize. If the resize is requested
1426 by the program and the window's "resizable" property is true then
1427 the size request will not be honoured. */
1428 gtk_window_resize (GTK_WINDOW (ptr
), width
, height
);
1432 window_get_frame_extents (GtkWidget
*window
,
1433 int *top
, int *left
, int *bottom
, int *right
)
1435 unsigned long *extents
= NULL
;
1436 union extents_union gu_ex
;
1438 /* Guess frame extents in case _NET_FRAME_EXTENTS is not
1440 if (gtk_window_get_decorated (GTK_WINDOW (window
)))
1455 /* Request that the window manager set window's
1456 _NET_FRAME_EXTENTS property. */
1457 request_frame_extents (window
);
1459 /* Attempt to retrieve window's frame extents. */
1460 gu_ex
.extents
= &extents
;
1461 if (gdk_property_get (window
->window
,
1462 gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE
),
1463 gdk_atom_intern ("CARDINAL", FALSE
),
1465 sizeof (unsigned long) * 4,
1472 *left
= extents
[0];
1473 *right
= extents
[1];
1475 *bottom
= extents
[3];
1479 static Atom extents_atom
= 0;
1481 /* Requests that the window manager set window's
1482 _NET_FRAME_EXTENTS property. */
1484 request_frame_extents (GtkWidget
*window
)
1486 const char *request_str
= "_NET_REQUEST_FRAME_EXTENTS";
1487 GdkAtom request_extents
= gdk_atom_intern (request_str
, FALSE
);
1489 /* Check if the current window manager supports
1490 _NET_REQUEST_FRAME_EXTENTS. */
1491 if (gdk_net_wm_supports (request_extents
))
1493 GdkDisplay
*display
= gtk_widget_get_display (window
);
1494 Display
*xdisplay
= GDK_DISPLAY_XDISPLAY (display
);
1496 GdkWindow
*root_window
= gdk_get_default_root_window ();
1497 Window xroot_window
= GDK_WINDOW_XID (root_window
);
1499 Atom extents_request_atom
=
1500 gdk_x11_get_xatom_by_name_for_display (display
, request_str
);
1503 XEvent notify_xevent
;
1505 unsigned long window_id
= GDK_WINDOW_XID (GDK_DRAWABLE(window
->window
));
1509 const char *extents_str
= "_NET_FRAME_EXTENTS";
1511 gdk_x11_get_xatom_by_name_for_display (display
, extents_str
);
1514 xevent
.xclient
.type
= ClientMessage
;
1515 xevent
.xclient
.message_type
= extents_request_atom
;
1516 xevent
.xclient
.display
= xdisplay
;
1517 xevent
.xclient
.window
= window_id
;
1518 xevent
.xclient
.format
= 32;
1519 xevent
.xclient
.data
.l
[0] = 0;
1520 xevent
.xclient
.data
.l
[1] = 0;
1521 xevent
.xclient
.data
.l
[2] = 0;
1522 xevent
.xclient
.data
.l
[3] = 0;
1523 xevent
.xclient
.data
.l
[4] = 0;
1525 XSendEvent (xdisplay
, xroot_window
, False
,
1526 (SubstructureRedirectMask
| SubstructureNotifyMask
),
1529 XIfEvent(xdisplay
, ¬ify_xevent
,
1530 property_notify_predicate
, (XPointer
) &window_id
);
1535 property_notify_predicate (Display
*xdisplay
__attribute__((unused
)),
1539 unsigned long *window
= (unsigned long *) window_id
;
1541 if (event
->xany
.type
== PropertyNotify
1542 && event
->xany
.window
== *window
1543 && event
->xproperty
.atom
== extents_atom
)
1550 window_delete_cb (GtkWidget
*widget
__attribute__((unused
)),
1551 GdkEvent
*event
__attribute__((unused
)),
1554 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1556 (jint
) AWT_WINDOW_CLOSING
,
1557 (jobject
) NULL
, (jint
) 0);
1559 /* Prevents that the Window dissappears ("destroy"
1560 not being signalled). This is necessary because it
1561 should be up to a WindowListener implementation
1562 how the AWT Frame responds to close requests. */
1567 window_destroy_cb (GtkWidget
*widget
__attribute__((unused
)),
1568 GdkEvent
*event
__attribute__((unused
)),
1571 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1573 (jint
) AWT_WINDOW_CLOSED
,
1574 (jobject
) NULL
, (jint
) 0);
1578 window_show_cb (GtkWidget
*widget
__attribute__((unused
)),
1581 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1583 (jint
) AWT_WINDOW_OPENED
,
1584 (jobject
) NULL
, (jint
) 0);
1588 window_focus_state_change_cb (GtkWidget
*widget
,
1589 GParamSpec
*pspec
__attribute__((unused
)),
1592 if (GTK_WINDOW (widget
)->has_toplevel_focus
)
1593 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1595 (jint
) AWT_WINDOW_ACTIVATED
,
1596 (jobject
) NULL
, (jint
) 0);
1598 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1600 (jint
) AWT_WINDOW_DEACTIVATED
,
1601 (jobject
) NULL
, (jint
) 0);
1605 window_focus_in_cb (GtkWidget
* widget
__attribute__((unused
)),
1606 GdkEventFocus
*event
__attribute__((unused
)),
1609 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1611 (jint
) AWT_WINDOW_GAINED_FOCUS
,
1612 (jobject
) NULL
, (jint
) 0);
1618 window_focus_out_cb (GtkWidget
* widget
__attribute__((unused
)),
1619 GdkEventFocus
*event
__attribute__((unused
)),
1622 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1624 (jint
) AWT_WINDOW_LOST_FOCUS
,
1625 (jobject
) NULL
, (jint
) 0);
1631 window_window_state_cb (GtkWidget
*widget
__attribute__((unused
)),
1637 /* Handle WINDOW_ICONIFIED and WINDOW_DEICONIFIED events. */
1638 if (event
->window_state
.changed_mask
& GDK_WINDOW_STATE_ICONIFIED
)
1640 /* We've either been iconified or deiconified. */
1641 if (event
->window_state
.new_window_state
& GDK_WINDOW_STATE_ICONIFIED
)
1643 /* We've been iconified. */
1644 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1646 (jint
) AWT_WINDOW_ICONIFIED
,
1647 (jobject
) NULL
, (jint
) 0);
1651 /* We've been deiconified. */
1652 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1654 (jint
) AWT_WINDOW_DEICONIFIED
,
1655 (jobject
) NULL
, (jint
) 0);
1659 /* Post a WINDOW_STATE_CHANGED event, passing the new frame state to
1661 new_state
= AWT_FRAME_STATE_NORMAL
;
1663 if (event
->window_state
.new_window_state
& GDK_WINDOW_STATE_ICONIFIED
)
1664 new_state
|= AWT_FRAME_STATE_ICONIFIED
;
1666 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1668 (jint
) AWT_WINDOW_STATE_CHANGED
,
1669 (jobject
) NULL
, new_state
);
1675 window_property_changed_cb (GtkWidget
*widget
__attribute__((unused
)),
1676 GdkEventProperty
*event
,
1679 unsigned long *extents
;
1680 union extents_union gu_ex
;
1682 gu_ex
.extents
= &extents
;
1683 if (gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE
) == event
->atom
1684 && gdk_property_get (event
->window
,
1685 gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE
),
1686 gdk_atom_intern ("CARDINAL", FALSE
),
1688 sizeof (unsigned long) * 4,
1695 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1696 postInsetsChangedEventID
,
1697 (jint
) extents
[2], /* top */
1698 (jint
) extents
[0], /* left */
1699 (jint
) extents
[3], /* bottom */
1700 (jint
) extents
[1]); /* right */
1708 realize_cb (GtkWidget
*widget
, jobject peer
)
1717 width
= (*cp_gtk_gdk_env())->CallIntMethod (cp_gtk_gdk_env(), peer
, windowGetWidthID
);
1718 height
= (*cp_gtk_gdk_env())->CallIntMethod (cp_gtk_gdk_env(), peer
, windowGetHeightID
);
1720 window_get_frame_extents (widget
, &top
, &left
, &bottom
, &right
);
1722 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
1723 postInsetsChangedEventID
,
1724 top
, left
, bottom
, right
);
1726 gtk_window_set_default_size (GTK_WINDOW (widget
),
1727 MAX (1, width
- left
- right
),
1728 MAX (1, height
- top
- bottom
));
1730 /* set the size like we do in nativeSetBounds */
1731 gtk_widget_set_size_request (widget
,
1732 MAX (1, width
- left
- right
),
1733 MAX (1, height
- top
- bottom
));
1735 gtk_window_resize (GTK_WINDOW (widget
),
1736 MAX (1, width
- left
- right
),
1737 MAX (1, height
- top
- bottom
));
1741 * This method returns a GDK keyval that corresponds to one of the
1742 * keysyms in the X keymap table. The return value is only used to
1743 * determine the keyval's corresponding hardware keycode, and doesn't
1744 * reflect an accurate translation of a Java virtual key value to a
1751 cp_gtk_awt_keycode_to_keysym (jint keyCode
, jint keyLocation
)
1753 /* GDK_A through GDK_Z */
1754 if (keyCode
>= VK_A
&& keyCode
<= VK_Z
)
1755 return gdk_keyval_to_lower (keyCode
);
1757 /* GDK_0 through GDK_9 */
1758 if (keyCode
>= VK_0
&& keyCode
<= VK_9
)
1764 return keyLocation
== AWT_KEY_LOCATION_NUMPAD
? GDK_KP_Enter
: GDK_Return
;
1766 return GDK_BackSpace
;
1774 return keyLocation
== AWT_KEY_LOCATION_LEFT
? GDK_Shift_L
: GDK_Shift_R
;
1776 return keyLocation
== AWT_KEY_LOCATION_LEFT
? GDK_Control_L
: GDK_Control_R
;
1778 return keyLocation
== AWT_KEY_LOCATION_LEFT
? GDK_Alt_L
: GDK_Alt_R
;
1782 return GDK_Caps_Lock
;
1788 return keyLocation
== AWT_KEY_LOCATION_NUMPAD
? GDK_KP_Page_Up
: GDK_Page_Up
;
1790 return keyLocation
== AWT_KEY_LOCATION_NUMPAD
? GDK_KP_Page_Down
: GDK_Page_Down
;
1792 return keyLocation
== AWT_KEY_LOCATION_NUMPAD
? GDK_KP_End
: GDK_End
;
1794 return keyLocation
== AWT_KEY_LOCATION_NUMPAD
? GDK_KP_Home
: GDK_Home
;
1824 return GDK_semicolon
;
1855 case VK_OPEN_BRACKET
:
1856 return GDK_bracketleft
;
1858 return GDK_backslash
;
1859 case VK_CLOSE_BRACKET
:
1860 return GDK_bracketright
;
1882 return GDK_KP_Multiply
;
1889 return GDK_KP_Separator
;
1891 return GDK_KP_Subtract
;
1893 return GDK_KP_Decimal
;
1895 return GDK_KP_Divide
;
1897 return keyLocation
== AWT_KEY_LOCATION_NUMPAD
? GDK_KP_Delete
: GDK_Delete
;
1899 return GDK_Num_Lock
;
1900 case VK_SCROLL_LOCK
:
1901 return GDK_Scroll_Lock
;
1950 case VK_PRINTSCREEN
:
1953 return keyLocation
== AWT_KEY_LOCATION_NUMPAD
? GDK_KP_Insert
: GDK_Insert
;
1957 return keyLocation
== AWT_KEY_LOCATION_LEFT
? GDK_Meta_L
: GDK_Meta_R
;
1961 return GDK_apostrophe
;
1969 return GDK_KP_Right
;
1971 return GDK_dead_grave
;
1973 return GDK_dead_acute
;
1974 case VK_DEAD_CIRCUMFLEX
:
1975 return GDK_dead_circumflex
;
1977 return GDK_dead_tilde
;
1978 case VK_DEAD_MACRON
:
1979 return GDK_dead_macron
;
1981 return GDK_dead_breve
;
1982 case VK_DEAD_ABOVEDOT
:
1983 return GDK_dead_abovedot
;
1984 case VK_DEAD_DIAERESIS
:
1985 return GDK_dead_diaeresis
;
1986 case VK_DEAD_ABOVERING
:
1987 return GDK_dead_abovering
;
1988 case VK_DEAD_DOUBLEACUTE
:
1989 return GDK_dead_doubleacute
;
1991 return GDK_dead_caron
;
1992 case VK_DEAD_CEDILLA
:
1993 return GDK_dead_cedilla
;
1994 case VK_DEAD_OGONEK
:
1995 return GDK_dead_ogonek
;
1997 return GDK_dead_iota
;
1998 case VK_DEAD_VOICED_SOUND
:
1999 return GDK_dead_voiced_sound
;
2000 case VK_DEAD_SEMIVOICED_SOUND
:
2001 return GDK_dead_semivoiced_sound
;
2003 return GDK_ampersand
;
2005 return GDK_asterisk
;
2007 return GDK_quotedbl
;
2013 return GDK_braceleft
;
2015 return GDK_braceright
;
2021 return GDK_asciicircum
;
2025 return GDK_EuroSign
;
2026 case VK_EXCLAMATION_MARK
:
2028 case VK_INVERTED_EXCLAMATION_MARK
:
2029 return GDK_exclamdown
;
2030 case VK_LEFT_PARENTHESIS
:
2031 return GDK_parenleft
;
2032 case VK_NUMBER_SIGN
:
2033 return GDK_numbersign
;
2036 case VK_RIGHT_PARENTHESIS
:
2037 return GDK_parenright
;
2039 return GDK_underscore
;
2047 return GDK_Mode_switch
;
2054 case VK_ALPHANUMERIC:
2057 return GDK_Katakana
;
2059 return GDK_Hiragana
;
2063 case VK_ROMAN_CHARACTERS:
2064 case VK_ALL_CANDIDATES:
2066 case VK_PREVIOUS_CANDIDATE
:
2067 return GDK_PreviousCandidate
;
2069 return GDK_Codeinput
;
2071 case VK_JAPANESE_KATAKANA:
2072 case VK_JAPANESE_HIRAGANA:
2073 case VK_JAPANESE_ROMAN:
2076 return GDK_Kana_Lock
;
2078 case VK_INPUT_METHOD_ON_OFF:
2091 return GDK_VoidSymbol
;