Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkWindowPeer.c
blobac8f6a8ff1eaf4084494e007a649c0272dbd5d21
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)
9 any later version.
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
19 02110-1301 USA.
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
24 combination.
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. */
39 #include "gtkpeer.h"
40 #include "gnu_java_awt_peer_gtk_GtkWindowPeer.h"
41 #include <gdk/gdkprivate.h>
42 #include <gdk/gdkx.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
57 /* Virtual Keys */
58 /* This list should be kept in the same order as the VK_ field
59 declarations in KeyEvent.java. */
60 #define VK_ENTER '\n'
61 #define VK_BACK_SPACE '\b'
62 #define VK_TAB '\t'
63 #define VK_CANCEL 3
64 #define VK_CLEAR 12
65 #define VK_SHIFT 16
66 #define VK_CONTROL 17
67 #define VK_ALT 18
68 #define VK_PAUSE 19
69 #define VK_CAPS_LOCK 20
70 #define VK_ESCAPE 27
71 #define VK_SPACE ' '
72 #define VK_PAGE_UP 33
73 #define VK_PAGE_DOWN 34
74 #define VK_END 35
75 #define VK_HOME 36
76 #define VK_LEFT 37
77 #define VK_UP 38
78 #define VK_RIGHT 39
79 #define VK_DOWN 40
80 #define VK_COMMA ','
81 #define VK_MINUS '-'
82 #define VK_PERIOD '.'
83 #define VK_SLASH '/'
84 #define VK_0 '0'
85 #define VK_1 '1'
86 #define VK_2 '2'
87 #define VK_3 '3'
88 #define VK_4 '4'
89 #define VK_5 '5'
90 #define VK_6 '6'
91 #define VK_7 '7'
92 #define VK_8 '8'
93 #define VK_9 '9'
94 #define VK_SEMICOLON ';'
95 #define VK_EQUALS '='
96 #define VK_A 'A'
97 #define VK_B 'B'
98 #define VK_C 'C'
99 #define VK_D 'D'
100 #define VK_E 'E'
101 #define VK_F 'F'
102 #define VK_G 'G'
103 #define VK_H 'H'
104 #define VK_I 'I'
105 #define VK_J 'J'
106 #define VK_K 'K'
107 #define VK_L 'L'
108 #define VK_M 'M'
109 #define VK_N 'N'
110 #define VK_O 'O'
111 #define VK_P 'P'
112 #define VK_Q 'Q'
113 #define VK_R 'R'
114 #define VK_S 'S'
115 #define VK_T 'T'
116 #define VK_U 'U'
117 #define VK_V 'V'
118 #define VK_W 'W'
119 #define VK_X 'X'
120 #define VK_Y 'Y'
121 #define VK_Z 'Z'
122 #define VK_OPEN_BRACKET '['
123 #define VK_BACK_SLASH '\\'
124 #define VK_CLOSE_BRACKET ']'
125 /* See gtkpeer.h */
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
137 #define VK_ADD 107
138 #define VK_SEPARATER 108
139 #define VK_SEPARATOR 108
140 #define VK_SUBTRACT 109
141 /* See gtkpeer.h */
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
147 #define VK_F1 112
148 #define VK_F2 113
149 #define VK_F3 114
150 #define VK_F4 115
151 #define VK_F5 116
152 #define VK_F6 117
153 #define VK_F7 118
154 #define VK_F8 119
155 #define VK_F9 120
156 #define VK_F10 121
157 #define VK_F11 122
158 #define VK_F12 123
159 #define VK_F13 61440
160 #define VK_F14 61441
161 #define VK_F15 61442
162 #define VK_F16 61443
163 #define VK_F17 61444
164 #define VK_F18 61445
165 #define VK_F19 61446
166 #define VK_F20 61447
167 #define VK_F21 61448
168 #define VK_F22 61449
169 #define VK_F23 61450
170 #define VK_F24 61451
171 #define VK_PRINTSCREEN 154
172 #define VK_INSERT 155
173 #define VK_HELP 156
174 #define VK_META 157
175 #define VK_BACK_QUOTE 192
176 #define VK_QUOTE 222
177 #define VK_KP_UP 224
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
200 #define VK_LESS 153
201 #define VK_GREATER 160
202 #define VK_BRACELEFT 161
203 #define VK_BRACERIGHT 162
204 #define VK_AT 512
205 #define VK_COLON 513
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
213 #define VK_PLUS 521
214 #define VK_RIGHT_PARENTHESIS 522
215 #define VK_UNDERSCORE 523
216 #define VK_FINAL 24
217 #define VK_CONVERT 28
218 #define VK_NONCONVERT 29
219 #define VK_ACCEPT 30
220 #define VK_MODECHANGE 31
221 #define VK_KANA 21
222 #define VK_KANJI 25
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
237 #define VK_CUT 65489
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;
264 void
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,
276 "postWindowEvent",
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",
284 "(IIII)V");
286 windowGetWidthID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer,
287 "getWidth", "()I");
289 windowGetHeightID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer,
290 "getHeight", "()I");
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. */
300 static gint
301 get_first_keyval_from_keymap (GdkEventKey *event)
303 guint keyval;
304 guint *keyvals;
305 gint n_entries;
307 if (!gdk_keymap_get_entries_for_keycode (NULL,
308 event->hardware_keycode,
309 NULL,
310 &keyvals,
311 &n_entries))
313 /* No keyval found for hardware keycode */
314 return -1;
316 keyval = keyvals[0];
317 g_free (keyvals);
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. */
324 #ifdef __GNUC__
325 __inline
326 #endif
327 static jint
328 keysym_to_awt_keycode (GdkEventKey *event)
330 gint ukeyval;
331 guint state;
333 ukeyval = get_first_keyval_from_keymap (event);
335 if (ukeyval < 0)
336 return -1;
338 state = event->state;
340 /* VK_A through VK_Z */
341 if (ukeyval >= GDK_A && ukeyval <= GDK_Z)
342 return ukeyval;
344 /* VK_0 through VK_9 */
345 if (ukeyval >= GDK_0 && ukeyval <= GDK_9)
346 return ukeyval;
348 switch (ukeyval)
350 case GDK_Return:
351 case GDK_KP_Enter:
352 return VK_ENTER;
353 case GDK_BackSpace:
354 return VK_BACK_SPACE;
355 case GDK_Tab:
356 return VK_TAB;
357 case GDK_Cancel:
358 return VK_CANCEL;
359 case GDK_Clear:
360 return VK_CLEAR;
361 case GDK_Shift_L:
362 case GDK_Shift_R:
363 return VK_SHIFT;
364 case GDK_Control_L:
365 case GDK_Control_R:
366 return VK_CONTROL;
367 case GDK_Alt_L:
368 case GDK_Alt_R:
369 return VK_ALT;
370 case GDK_Pause:
371 return VK_PAUSE;
372 case GDK_Caps_Lock:
373 return VK_CAPS_LOCK;
374 case GDK_Escape:
375 return VK_ESCAPE;
376 case GDK_space:
377 return VK_SPACE;
378 case GDK_KP_Page_Up:
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)
382 return VK_NUMPAD9;
383 else
384 return VK_PAGE_UP;
385 case GDK_Page_Up:
386 return VK_PAGE_UP;
387 case GDK_KP_Page_Down:
388 if (state & GDK_MOD2_MASK)
389 return VK_NUMPAD3;
390 else
391 return VK_PAGE_DOWN;
392 case GDK_Page_Down:
393 return VK_PAGE_DOWN;
394 case GDK_KP_End:
395 if (state & GDK_MOD2_MASK)
396 return VK_NUMPAD1;
397 else
398 return VK_END;
399 case GDK_End:
400 return VK_END;
401 case GDK_KP_Home:
402 if (state & GDK_MOD2_MASK)
403 return VK_NUMPAD7;
404 else
405 return VK_HOME;
406 case GDK_Home:
407 return VK_HOME;
408 case GDK_KP_Begin:
409 if (state & GDK_MOD2_MASK)
410 return VK_NUMPAD5;
411 else
412 return VK_UNDEFINED;
413 case GDK_Left:
414 return VK_LEFT;
415 case GDK_Up:
416 return VK_UP;
417 case GDK_Right:
418 return VK_RIGHT;
419 case GDK_Down:
420 return VK_DOWN;
421 case GDK_comma:
422 return VK_COMMA;
423 case GDK_minus:
424 return VK_MINUS;
425 case GDK_period:
426 return VK_PERIOD;
427 case GDK_slash:
428 return VK_SLASH;
430 return VK_0;
431 return VK_1;
432 return VK_2;
433 return VK_3;
434 return VK_4;
435 return VK_5;
436 return VK_6;
437 return VK_7;
438 return VK_8;
439 return VK_9;
441 case GDK_semicolon:
442 return VK_SEMICOLON;
443 case GDK_equal:
444 return VK_EQUALS;
446 return VK_A;
447 return VK_B;
448 return VK_C;
449 return VK_D;
450 return VK_E;
451 return VK_F;
452 return VK_G;
453 return VK_H;
454 return VK_I;
455 return VK_J;
456 return VK_K;
457 return VK_L;
458 return VK_M;
459 return VK_N;
460 return VK_O;
461 return VK_P;
462 return VK_Q;
463 return VK_R;
464 return VK_S;
465 return VK_T;
466 return VK_U;
467 return VK_V;
468 return VK_W;
469 return VK_X;
470 return VK_Y;
471 return VK_Z;
473 case GDK_bracketleft:
474 return VK_OPEN_BRACKET;
475 case GDK_backslash:
476 return VK_BACK_SLASH;
477 case GDK_bracketright:
478 return VK_CLOSE_BRACKET;
479 case GDK_KP_0:
480 return VK_NUMPAD0;
481 case GDK_KP_1:
482 return VK_NUMPAD1;
483 case GDK_KP_2:
484 return VK_NUMPAD2;
485 case GDK_KP_3:
486 return VK_NUMPAD3;
487 case GDK_KP_4:
488 return VK_NUMPAD4;
489 case GDK_KP_5:
490 return VK_NUMPAD5;
491 case GDK_KP_6:
492 return VK_NUMPAD6;
493 case GDK_KP_7:
494 return VK_NUMPAD7;
495 case GDK_KP_8:
496 return VK_NUMPAD8;
497 case GDK_KP_9:
498 return VK_NUMPAD9;
499 case GDK_KP_Multiply:
500 return VK_MULTIPLY;
501 case GDK_KP_Add:
502 return VK_ADD;
504 return VK_SEPARATER;
506 case GDK_KP_Separator:
507 return VK_SEPARATOR;
508 case GDK_KP_Subtract:
509 return VK_SUBTRACT;
510 case GDK_KP_Decimal:
511 return VK_DECIMAL;
512 case GDK_KP_Divide:
513 return VK_DIVIDE;
514 case GDK_KP_Delete:
515 if (state & GDK_MOD2_MASK)
516 return VK_DECIMAL;
517 else
518 return VK_DELETE;
519 case GDK_Delete:
520 return VK_DELETE;
521 case GDK_Num_Lock:
522 return VK_NUM_LOCK;
523 case GDK_Scroll_Lock:
524 return VK_SCROLL_LOCK;
525 case GDK_F1:
526 return VK_F1;
527 case GDK_F2:
528 return VK_F2;
529 case GDK_F3:
530 return VK_F3;
531 case GDK_F4:
532 return VK_F4;
533 case GDK_F5:
534 return VK_F5;
535 case GDK_F6:
536 return VK_F6;
537 case GDK_F7:
538 return VK_F7;
539 case GDK_F8:
540 return VK_F8;
541 case GDK_F9:
542 return VK_F9;
543 case GDK_F10:
544 return VK_F10;
545 case GDK_F11:
546 return VK_F11;
547 case GDK_F12:
548 return VK_F12;
549 case GDK_F13:
550 return VK_F13;
551 case GDK_F14:
552 return VK_F14;
553 case GDK_F15:
554 return VK_F15;
555 case GDK_F16:
556 return VK_F16;
557 case GDK_F17:
558 return VK_F17;
559 case GDK_F18:
560 return VK_F18;
561 case GDK_F19:
562 return VK_F19;
563 case GDK_F20:
564 return VK_F20;
565 case GDK_F21:
566 return VK_F21;
567 case GDK_F22:
568 return VK_F22;
569 case GDK_F23:
570 return VK_F23;
571 case GDK_F24:
572 return VK_F24;
573 case GDK_Print:
574 return VK_PRINTSCREEN;
575 case GDK_KP_Insert:
576 if (state & GDK_MOD2_MASK)
577 return VK_NUMPAD0;
578 else
579 return VK_INSERT;
580 case GDK_Insert:
581 return VK_INSERT;
582 case GDK_Help:
583 return VK_HELP;
584 case GDK_Meta_L:
585 case GDK_Meta_R:
586 return VK_META;
587 case GDK_grave:
588 return VK_BACK_QUOTE;
589 case GDK_apostrophe:
590 return VK_QUOTE;
591 case GDK_KP_Up:
592 if (state & GDK_MOD2_MASK)
593 return VK_NUMPAD8;
594 else
595 return VK_KP_UP;
596 case GDK_KP_Down:
597 if (state & GDK_MOD2_MASK)
598 return VK_NUMPAD2;
599 else
600 return VK_KP_DOWN;
601 case GDK_KP_Left:
602 if (state & GDK_MOD2_MASK)
603 return VK_NUMPAD4;
604 else
605 return VK_KP_LEFT;
606 case GDK_KP_Right:
607 if (state & GDK_MOD2_MASK)
608 return VK_NUMPAD6;
609 else
610 return VK_KP_RIGHT;
611 case GDK_dead_grave:
612 return VK_DEAD_GRAVE;
613 case GDK_dead_acute:
614 return VK_DEAD_ACUTE;
615 case GDK_dead_circumflex:
616 return VK_DEAD_CIRCUMFLEX;
617 case GDK_dead_tilde:
618 return VK_DEAD_TILDE;
619 case GDK_dead_macron:
620 return VK_DEAD_MACRON;
621 case GDK_dead_breve:
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;
631 case GDK_dead_caron:
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;
637 case GDK_dead_iota:
638 return VK_DEAD_IOTA;
639 case GDK_dead_voiced_sound:
640 return VK_DEAD_VOICED_SOUND;
641 case GDK_dead_semivoiced_sound:
642 return VK_DEAD_SEMIVOICED_SOUND;
643 case GDK_ampersand:
644 return VK_AMPERSAND;
645 case GDK_asterisk:
646 return VK_ASTERISK;
647 case GDK_quotedbl:
648 return VK_QUOTEDBL;
649 case GDK_less:
650 return VK_LESS;
651 case GDK_greater:
652 return VK_GREATER;
653 case GDK_braceleft:
654 return VK_BRACELEFT;
655 case GDK_braceright:
656 return VK_BRACERIGHT;
657 case GDK_at:
658 return VK_AT;
659 case GDK_colon:
660 return VK_COLON;
661 case GDK_asciicircum:
662 return VK_CIRCUMFLEX;
663 case GDK_dollar:
664 return VK_DOLLAR;
665 case GDK_EuroSign:
666 return VK_EURO_SIGN;
667 case GDK_exclam:
668 return VK_EXCLAMATION_MARK;
669 case GDK_exclamdown:
670 return VK_INVERTED_EXCLAMATION_MARK;
671 case GDK_parenleft:
672 return VK_LEFT_PARENTHESIS;
673 case GDK_numbersign:
674 return VK_NUMBER_SIGN;
675 case GDK_plus:
676 return VK_PLUS;
677 case GDK_parenright:
678 return VK_RIGHT_PARENTHESIS;
679 case GDK_underscore:
680 return VK_UNDERSCORE;
682 return VK_FINAL;
683 return VK_CONVERT;
684 return VK_NONCONVERT;
685 return VK_ACCEPT;
687 case GDK_Mode_switch:
688 return VK_MODECHANGE;
690 return VK_KANA;
692 case GDK_Kanji:
693 return VK_KANJI;
695 return VK_ALPHANUMERIC;
697 case GDK_Katakana:
698 return VK_KATAKANA;
699 case GDK_Hiragana:
700 return VK_HIRAGANA;
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;
709 case GDK_Codeinput:
710 return VK_CODE_INPUT;
712 return VK_JAPANESE_KATAKANA;
713 return VK_JAPANESE_HIRAGANA;
714 return VK_JAPANESE_ROMAN;
716 case GDK_Kana_Lock:
717 return VK_KANA_LOCK;
719 return VK_INPUT_METHOD_ON_OFF;
720 return VK_CUT;
721 return VK_COPY;
722 return VK_PASTE;
723 return VK_UNDO;
724 return VK_AGAIN;
725 return VK_FIND;
726 return VK_PROPS;
727 return VK_STOP;
728 return VK_COMPOSE;
729 return VK_ALT_GRAPH;
731 default:
732 return VK_UNDEFINED;
736 /* Return the AWT key location code for the given keysym or -1 if no
737 keyval was found for the given hardware keycode. */
738 static jint
739 keysym_to_awt_keylocation (GdkEventKey *event)
741 gint ukeyval;
743 ukeyval = get_first_keyval_from_keymap (event);
745 if (ukeyval < 0)
746 return -1;
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;
756 switch (ukeyval)
758 case GDK_Shift_L:
759 case GDK_Control_L:
760 case GDK_Alt_L:
761 case GDK_Meta_L:
762 return AWT_KEY_LOCATION_LEFT;
764 case GDK_Shift_R:
765 case GDK_Control_R:
766 case GDK_Alt_R:
767 case GDK_Meta_R:
768 return AWT_KEY_LOCATION_RIGHT;
770 case GDK_Return:
771 case GDK_BackSpace:
772 case GDK_Tab:
773 case GDK_Cancel:
774 case GDK_Clear:
775 case GDK_Pause:
776 case GDK_Caps_Lock:
777 case GDK_Escape:
778 case GDK_space:
779 case GDK_Page_Up:
780 case GDK_Page_Down:
781 case GDK_End:
782 case GDK_Home:
783 case GDK_Left:
784 case GDK_Up:
785 case GDK_Right:
786 case GDK_Down:
787 case GDK_comma:
788 case GDK_minus:
789 case GDK_period:
790 case GDK_slash:
791 case GDK_semicolon:
792 case GDK_equal:
793 case GDK_bracketleft:
794 case GDK_backslash:
795 case GDK_bracketright:
796 case GDK_Delete:
797 case GDK_Scroll_Lock:
798 case GDK_F1:
799 case GDK_F2:
800 case GDK_F3:
801 case GDK_F4:
802 case GDK_F5:
803 case GDK_F6:
804 case GDK_F7:
805 case GDK_F8:
806 case GDK_F9:
807 case GDK_F10:
808 case GDK_F11:
809 case GDK_F12:
810 case GDK_F13:
811 case GDK_F14:
812 case GDK_F15:
813 case GDK_F16:
814 case GDK_F17:
815 case GDK_F18:
816 case GDK_F19:
817 case GDK_F20:
818 case GDK_F21:
819 case GDK_F22:
820 case GDK_F23:
821 case GDK_F24:
822 case GDK_Print:
823 case GDK_Insert:
824 case GDK_Help:
825 case GDK_grave:
826 case GDK_apostrophe:
827 case GDK_dead_grave:
828 case GDK_dead_acute:
829 case GDK_dead_circumflex:
830 case GDK_dead_tilde:
831 case GDK_dead_macron:
832 case GDK_dead_breve:
833 case GDK_dead_abovedot:
834 case GDK_dead_diaeresis:
835 case GDK_dead_abovering:
836 case GDK_dead_doubleacute:
837 case GDK_dead_caron:
838 case GDK_dead_cedilla:
839 case GDK_dead_ogonek:
840 case GDK_dead_iota:
841 case GDK_dead_voiced_sound:
842 case GDK_dead_semivoiced_sound:
843 case GDK_ampersand:
844 case GDK_asterisk:
845 case GDK_quotedbl:
846 case GDK_less:
847 case GDK_greater:
848 case GDK_braceleft:
849 case GDK_braceright:
850 case GDK_at:
851 case GDK_colon:
852 case GDK_asciicircum:
853 case GDK_dollar:
854 case GDK_EuroSign:
855 case GDK_exclam:
856 case GDK_exclamdown:
857 case GDK_parenleft:
858 case GDK_numbersign:
859 case GDK_plus:
860 case GDK_parenright:
861 case GDK_underscore:
862 case GDK_Mode_switch:
863 case GDK_Kanji:
864 case GDK_Katakana:
865 case GDK_Hiragana:
866 case GDK_PreviousCandidate:
867 case GDK_Codeinput:
868 case GDK_Kana_Lock:
869 return AWT_KEY_LOCATION_STANDARD;
871 case GDK_KP_Enter:
872 case GDK_KP_Page_Up:
873 case GDK_KP_Page_Down:
874 case GDK_KP_End:
875 case GDK_KP_Home:
876 case GDK_KP_Begin:
877 case GDK_KP_0:
878 case GDK_KP_1:
879 case GDK_KP_2:
880 case GDK_KP_3:
881 case GDK_KP_4:
882 case GDK_KP_5:
883 case GDK_KP_6:
884 case GDK_KP_7:
885 case GDK_KP_8:
886 case GDK_KP_9:
887 case GDK_KP_Multiply:
888 case GDK_KP_Add:
889 case GDK_KP_Separator:
890 case GDK_KP_Subtract:
891 case GDK_KP_Decimal:
892 case GDK_KP_Divide:
893 case GDK_KP_Delete:
894 case GDK_Num_Lock:
895 case GDK_KP_Insert:
896 case GDK_KP_Up:
897 case GDK_KP_Down:
898 case GDK_KP_Left:
899 case GDK_KP_Right:
900 return AWT_KEY_LOCATION_NUMPAD;
902 default:
903 return AWT_KEY_LOCATION_UNKNOWN;
907 static jchar
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)
914 return VK_ENTER;
915 else
916 return event->string[0];
918 else
920 switch (event->keyval)
922 case GDK_BackSpace:
923 return VK_BACK_SPACE;
924 case GDK_Tab:
925 return VK_TAB;
926 case GDK_Delete:
927 case GDK_KP_Delete:
928 return VK_DELETE;
929 default:
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. */
943 static jint
944 keyevent_state_to_awt_mods (GdkEventKey *event)
946 jint result = 0;
947 guint state;
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;
956 else
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;
965 else
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;
974 else
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;
1005 return result;
1008 static gboolean window_configure_cb (GtkWidget *widget,
1009 GdkEventConfigure *event,
1010 jobject peer);
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,
1023 XEvent *xevent,
1024 XPointer arg);
1026 static gboolean window_delete_cb (GtkWidget *widget, GdkEvent *event,
1027 jobject peer);
1028 static void window_destroy_cb (GtkWidget *widget, GdkEvent *event,
1029 jobject peer);
1030 static void window_show_cb (GtkWidget *widget, jobject peer);
1031 static void window_focus_state_change_cb (GtkWidget *widget,
1032 GParamSpec *pspec,
1033 jobject peer);
1034 static gboolean window_focus_in_cb (GtkWidget * widget,
1035 GdkEventFocus *event,
1036 jobject peer);
1037 static gboolean window_focus_out_cb (GtkWidget * widget,
1038 GdkEventFocus *event,
1039 jobject peer);
1040 static gboolean window_window_state_cb (GtkWidget *widget,
1041 GdkEvent *event,
1042 jobject peer);
1043 static gboolean window_property_changed_cb (GtkWidget *widget,
1044 GdkEventProperty *event,
1045 jobject peer);
1046 static void realize_cb (GtkWidget *widget, jobject peer);
1048 static gboolean
1049 window_configure_cb (GtkWidget *widget __attribute__((unused)),
1050 GdkEventConfigure *event,
1051 jobject peer)
1053 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1054 postConfigureEventID,
1055 (jint) event->x,
1056 (jint) event->y,
1057 (jint) event->width,
1058 (jint) event->height);
1060 return FALSE;
1063 static gboolean
1064 key_press_cb (GtkWidget *widget __attribute__((unused)),
1065 GdkEventKey *event,
1066 jobject peer)
1068 jint keycode;
1069 jint keylocation;
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)
1077 return TRUE;
1079 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1080 postKeyEventID,
1081 (jint) AWT_KEY_PRESSED,
1082 (jlong) event->time,
1083 keyevent_state_to_awt_mods (event),
1084 keycode,
1085 keyevent_to_awt_keychar (event),
1086 keylocation);
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. */
1093 return TRUE;
1097 static gboolean
1098 key_release_cb (GtkWidget *widget __attribute__((unused)),
1099 GdkEventKey *event,
1100 jobject peer)
1102 jint keycode;
1103 jint keylocation;
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)
1111 return TRUE;
1113 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1114 postKeyEventID,
1115 (jint) AWT_KEY_RELEASED,
1116 (jlong) event->time,
1117 keyevent_state_to_awt_mods (event),
1118 keycode,
1119 keyevent_to_awt_keychar (event),
1120 keylocation);
1122 return TRUE;
1125 /* Union used for type punning. */
1126 union extents_union
1128 guchar **gu_extents;
1129 unsigned long **extents;
1132 union atom_list_union
1134 guchar **gu_extents;
1135 Atom **atom_list;
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;
1143 GtkWindow *window;
1144 void *window_parent;
1145 GtkWidget *fixed;
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. */
1155 if (parent)
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;
1183 void *ptr;
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)
1202 void *ptr;
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)
1217 void *ptr;
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);
1237 gdk_flush ();
1239 gdk_threads_leave ();
1242 JNIEXPORT void JNICALL
1243 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setVisibleNativeUnlocked
1244 (JNIEnv *env, jobject obj, jboolean visible)
1246 void *ptr;
1248 ptr = NSA_GET_PTR (env, obj);
1250 if (visible)
1251 gtk_widget_show (GTK_WIDGET (ptr));
1252 else
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)
1260 void *ptr;
1261 jobject *gref;
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)
1321 void *ptr;
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,
1334 jobject obj)
1336 void *ptr;
1338 gdk_threads_enter ();
1340 ptr = NSA_GET_PTR (env, obj);
1342 gdk_window_lower (GTK_WIDGET (ptr)->window);
1343 gdk_flush ();
1345 gdk_threads_leave ();
1348 JNIEXPORT void JNICALL
1349 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toFront (JNIEnv *env,
1350 jobject obj)
1352 void *ptr;
1354 gdk_threads_enter ();
1356 ptr = NSA_GET_PTR (env, obj);
1358 gdk_window_raise (GTK_WIDGET (ptr)->window);
1359 gdk_flush ();
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)
1368 void *ptr;
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)
1399 void *ptr;
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:
1412 1. show a window
1413 2. manually move it to another position on the screen
1414 3. hide the window
1415 4. reposition the window with Component.setLocation
1416 5. show the window
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);
1431 static void
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
1439 supported. */
1440 if (gtk_window_get_decorated (GTK_WINDOW (window)))
1442 *top = 23;
1443 *left = 6;
1444 *bottom = 6;
1445 *right = 6;
1447 else
1449 *top = 0;
1450 *left = 0;
1451 *bottom = 0;
1452 *right = 0;
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,
1466 FALSE,
1467 NULL,
1468 NULL,
1469 NULL,
1470 gu_ex.gu_extents))
1472 *left = extents [0];
1473 *right = extents [1];
1474 *top = extents [2];
1475 *bottom = extents [3];
1479 static Atom extents_atom = 0;
1481 /* Requests that the window manager set window's
1482 _NET_FRAME_EXTENTS property. */
1483 static void
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);
1502 XEvent xevent;
1503 XEvent notify_xevent;
1505 unsigned long window_id = GDK_WINDOW_XID (GDK_DRAWABLE(window->window));
1507 if (!extents_atom)
1509 const char *extents_str = "_NET_FRAME_EXTENTS";
1510 extents_atom =
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),
1527 &xevent);
1529 XIfEvent(xdisplay, &notify_xevent,
1530 property_notify_predicate, (XPointer) &window_id);
1534 static Bool
1535 property_notify_predicate (Display *xdisplay __attribute__((unused)),
1536 XEvent *event,
1537 XPointer window_id)
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)
1544 return True;
1545 else
1546 return False;
1549 static gboolean
1550 window_delete_cb (GtkWidget *widget __attribute__((unused)),
1551 GdkEvent *event __attribute__((unused)),
1552 jobject peer)
1554 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1555 postWindowEventID,
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. */
1563 return TRUE;
1566 static void
1567 window_destroy_cb (GtkWidget *widget __attribute__((unused)),
1568 GdkEvent *event __attribute__((unused)),
1569 jobject peer)
1571 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1572 postWindowEventID,
1573 (jint) AWT_WINDOW_CLOSED,
1574 (jobject) NULL, (jint) 0);
1577 static void
1578 window_show_cb (GtkWidget *widget __attribute__((unused)),
1579 jobject peer)
1581 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1582 postWindowEventID,
1583 (jint) AWT_WINDOW_OPENED,
1584 (jobject) NULL, (jint) 0);
1587 static void
1588 window_focus_state_change_cb (GtkWidget *widget,
1589 GParamSpec *pspec __attribute__((unused)),
1590 jobject peer)
1592 if (GTK_WINDOW (widget)->has_toplevel_focus)
1593 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1594 postWindowEventID,
1595 (jint) AWT_WINDOW_ACTIVATED,
1596 (jobject) NULL, (jint) 0);
1597 else
1598 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1599 postWindowEventID,
1600 (jint) AWT_WINDOW_DEACTIVATED,
1601 (jobject) NULL, (jint) 0);
1604 static gboolean
1605 window_focus_in_cb (GtkWidget * widget __attribute__((unused)),
1606 GdkEventFocus *event __attribute__((unused)),
1607 jobject peer)
1609 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1610 postWindowEventID,
1611 (jint) AWT_WINDOW_GAINED_FOCUS,
1612 (jobject) NULL, (jint) 0);
1614 return FALSE;
1617 static gboolean
1618 window_focus_out_cb (GtkWidget * widget __attribute__((unused)),
1619 GdkEventFocus *event __attribute__((unused)),
1620 jobject peer)
1622 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1623 postWindowEventID,
1624 (jint) AWT_WINDOW_LOST_FOCUS,
1625 (jobject) NULL, (jint) 0);
1627 return FALSE;
1630 static gboolean
1631 window_window_state_cb (GtkWidget *widget __attribute__((unused)),
1632 GdkEvent *event,
1633 jobject peer)
1635 jint new_state;
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,
1645 postWindowEventID,
1646 (jint) AWT_WINDOW_ICONIFIED,
1647 (jobject) NULL, (jint) 0);
1649 else
1651 /* We've been deiconified. */
1652 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
1653 postWindowEventID,
1654 (jint) AWT_WINDOW_DEICONIFIED,
1655 (jobject) NULL, (jint) 0);
1659 /* Post a WINDOW_STATE_CHANGED event, passing the new frame state to
1660 GtkWindowPeer. */
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,
1667 postWindowEventID,
1668 (jint) AWT_WINDOW_STATE_CHANGED,
1669 (jobject) NULL, new_state);
1671 return TRUE;
1674 static gboolean
1675 window_property_changed_cb (GtkWidget *widget __attribute__((unused)),
1676 GdkEventProperty *event,
1677 jobject peer)
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,
1689 FALSE,
1690 NULL,
1691 NULL,
1692 NULL,
1693 gu_ex.gu_extents))
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 */
1704 return FALSE;
1707 static void
1708 realize_cb (GtkWidget *widget, jobject peer)
1710 jint top = 0;
1711 jint left = 0;
1712 jint bottom = 0;
1713 jint right = 0;
1714 jint width = 0;
1715 jint height = 0;
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
1745 * GDK keyval.
1747 #ifdef __GNUC__
1748 __inline
1749 #endif
1750 guint
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)
1759 return keyCode;
1761 switch (keyCode)
1763 case VK_ENTER:
1764 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Enter : GDK_Return;
1765 case VK_BACK_SPACE:
1766 return GDK_BackSpace;
1767 case VK_TAB:
1768 return GDK_Tab;
1769 case VK_CANCEL:
1770 return GDK_Cancel;
1771 case VK_CLEAR:
1772 return GDK_Clear;
1773 case VK_SHIFT:
1774 return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Shift_L : GDK_Shift_R;
1775 case VK_CONTROL:
1776 return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Control_L : GDK_Control_R;
1777 case VK_ALT:
1778 return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Alt_L : GDK_Alt_R;
1779 case VK_PAUSE:
1780 return GDK_Pause;
1781 case VK_CAPS_LOCK:
1782 return GDK_Caps_Lock;
1783 case VK_ESCAPE:
1784 return GDK_Escape;
1785 case VK_SPACE:
1786 return GDK_space;
1787 case VK_PAGE_UP:
1788 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Page_Up : GDK_Page_Up;
1789 case VK_PAGE_DOWN:
1790 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Page_Down : GDK_Page_Down;
1791 case VK_END:
1792 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_End : GDK_End;
1793 case VK_HOME:
1794 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Home : GDK_Home;
1795 case VK_LEFT:
1796 return GDK_Left;
1797 case VK_UP:
1798 return GDK_Up;
1799 case VK_RIGHT:
1800 return GDK_Right;
1801 case VK_DOWN:
1802 return GDK_Down;
1803 case VK_COMMA:
1804 return GDK_comma;
1805 case VK_MINUS:
1806 return GDK_minus;
1807 case VK_PERIOD:
1808 return GDK_period;
1809 case VK_SLASH:
1810 return GDK_slash;
1812 case VK_0:
1813 case VK_1:
1814 case VK_2:
1815 case VK_3:
1816 case VK_4:
1817 case VK_5:
1818 case VK_6:
1819 case VK_7:
1820 case VK_8:
1821 case VK_9:
1823 case VK_SEMICOLON:
1824 return GDK_semicolon;
1825 case VK_EQUALS:
1826 return GDK_equal;
1828 case VK_A:
1829 case VK_B:
1830 case VK_C:
1831 case VK_D:
1832 case VK_E:
1833 case VK_F:
1834 case VK_G:
1835 case VK_H:
1836 case VK_I:
1837 case VK_J:
1838 case VK_K:
1839 case VK_L:
1840 case VK_M:
1841 case VK_N:
1842 case VK_O:
1843 case VK_P:
1844 case VK_Q:
1845 case VK_R:
1846 case VK_S:
1847 case VK_T:
1848 case VK_U:
1849 case VK_V:
1850 case VK_W:
1851 case VK_X:
1852 case VK_Y:
1853 case VK_Z:
1855 case VK_OPEN_BRACKET:
1856 return GDK_bracketleft;
1857 case VK_BACK_SLASH:
1858 return GDK_backslash;
1859 case VK_CLOSE_BRACKET:
1860 return GDK_bracketright;
1861 case VK_NUMPAD0:
1862 return GDK_KP_0;
1863 case VK_NUMPAD1:
1864 return GDK_KP_1;
1865 case VK_NUMPAD2:
1866 return GDK_KP_2;
1867 case VK_NUMPAD3:
1868 return GDK_KP_3;
1869 case VK_NUMPAD4:
1870 return GDK_KP_4;
1871 case VK_NUMPAD5:
1872 return GDK_KP_5;
1873 case VK_NUMPAD6:
1874 return GDK_KP_6;
1875 case VK_NUMPAD7:
1876 return GDK_KP_7;
1877 case VK_NUMPAD8:
1878 return GDK_KP_8;
1879 case VK_NUMPAD9:
1880 return GDK_KP_9;
1881 case VK_MULTIPLY:
1882 return GDK_KP_Multiply;
1883 case VK_ADD:
1884 return GDK_KP_Add;
1886 case VK_SEPARATER:
1888 case VK_SEPARATOR:
1889 return GDK_KP_Separator;
1890 case VK_SUBTRACT:
1891 return GDK_KP_Subtract;
1892 case VK_DECIMAL:
1893 return GDK_KP_Decimal;
1894 case VK_DIVIDE:
1895 return GDK_KP_Divide;
1896 case VK_DELETE:
1897 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Delete : GDK_Delete;
1898 case VK_NUM_LOCK:
1899 return GDK_Num_Lock;
1900 case VK_SCROLL_LOCK:
1901 return GDK_Scroll_Lock;
1902 case VK_F1:
1903 return GDK_F1;
1904 case VK_F2:
1905 return GDK_F2;
1906 case VK_F3:
1907 return GDK_F3;
1908 case VK_F4:
1909 return GDK_F4;
1910 case VK_F5:
1911 return GDK_F5;
1912 case VK_F6:
1913 return GDK_F6;
1914 case VK_F7:
1915 return GDK_F7;
1916 case VK_F8:
1917 return GDK_F8;
1918 case VK_F9:
1919 return GDK_F9;
1920 case VK_F10:
1921 return GDK_F10;
1922 case VK_F11:
1923 return GDK_F11;
1924 case VK_F12:
1925 return GDK_F12;
1926 case VK_F13:
1927 return GDK_F13;
1928 case VK_F14:
1929 return GDK_F14;
1930 case VK_F15:
1931 return GDK_F15;
1932 case VK_F16:
1933 return GDK_F16;
1934 case VK_F17:
1935 return GDK_F17;
1936 case VK_F18:
1937 return GDK_F18;
1938 case VK_F19:
1939 return GDK_F19;
1940 case VK_F20:
1941 return GDK_F20;
1942 case VK_F21:
1943 return GDK_F21;
1944 case VK_F22:
1945 return GDK_F22;
1946 case VK_F23:
1947 return GDK_F23;
1948 case VK_F24:
1949 return GDK_F24;
1950 case VK_PRINTSCREEN:
1951 return GDK_Print;
1952 case VK_INSERT:
1953 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Insert : GDK_Insert;
1954 case VK_HELP:
1955 return GDK_Help;
1956 case VK_META:
1957 return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Meta_L : GDK_Meta_R;
1958 case VK_BACK_QUOTE:
1959 return GDK_grave;
1960 case VK_QUOTE:
1961 return GDK_apostrophe;
1962 case VK_KP_UP:
1963 return GDK_KP_Up;
1964 case VK_KP_DOWN:
1965 return GDK_KP_Down;
1966 case VK_KP_LEFT:
1967 return GDK_KP_Left;
1968 case VK_KP_RIGHT:
1969 return GDK_KP_Right;
1970 case VK_DEAD_GRAVE:
1971 return GDK_dead_grave;
1972 case VK_DEAD_ACUTE:
1973 return GDK_dead_acute;
1974 case VK_DEAD_CIRCUMFLEX:
1975 return GDK_dead_circumflex;
1976 case VK_DEAD_TILDE:
1977 return GDK_dead_tilde;
1978 case VK_DEAD_MACRON:
1979 return GDK_dead_macron;
1980 case VK_DEAD_BREVE:
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;
1990 case VK_DEAD_CARON:
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;
1996 case VK_DEAD_IOTA:
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;
2002 case VK_AMPERSAND:
2003 return GDK_ampersand;
2004 case VK_ASTERISK:
2005 return GDK_asterisk;
2006 case VK_QUOTEDBL:
2007 return GDK_quotedbl;
2008 case VK_LESS:
2009 return GDK_less;
2010 case VK_GREATER:
2011 return GDK_greater;
2012 case VK_BRACELEFT:
2013 return GDK_braceleft;
2014 case VK_BRACERIGHT:
2015 return GDK_braceright;
2016 case VK_AT:
2017 return GDK_at;
2018 case VK_COLON:
2019 return GDK_colon;
2020 case VK_CIRCUMFLEX:
2021 return GDK_asciicircum;
2022 case VK_DOLLAR:
2023 return GDK_dollar;
2024 case VK_EURO_SIGN:
2025 return GDK_EuroSign;
2026 case VK_EXCLAMATION_MARK:
2027 return GDK_exclam;
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;
2034 case VK_PLUS:
2035 return GDK_plus;
2036 case VK_RIGHT_PARENTHESIS:
2037 return GDK_parenright;
2038 case VK_UNDERSCORE:
2039 return GDK_underscore;
2041 case VK_FINAL:
2042 case VK_CONVERT:
2043 case VK_NONCONVERT:
2044 case VK_ACCEPT:
2046 case VK_MODECHANGE:
2047 return GDK_Mode_switch;
2049 case VK_KANA:
2051 case VK_KANJI:
2052 return GDK_Kanji;
2054 case VK_ALPHANUMERIC:
2056 case VK_KATAKANA:
2057 return GDK_Katakana;
2058 case VK_HIRAGANA:
2059 return GDK_Hiragana;
2061 case VK_FULL_WIDTH:
2062 case VK_HALF_WIDTH:
2063 case VK_ROMAN_CHARACTERS:
2064 case VK_ALL_CANDIDATES:
2066 case VK_PREVIOUS_CANDIDATE:
2067 return GDK_PreviousCandidate;
2068 case VK_CODE_INPUT:
2069 return GDK_Codeinput;
2071 case VK_JAPANESE_KATAKANA:
2072 case VK_JAPANESE_HIRAGANA:
2073 case VK_JAPANESE_ROMAN:
2075 case VK_KANA_LOCK:
2076 return GDK_Kana_Lock;
2078 case VK_INPUT_METHOD_ON_OFF:
2079 case VK_CUT:
2080 case VK_COPY:
2081 case VK_PASTE:
2082 case VK_UNDO:
2083 case VK_AGAIN:
2084 case VK_FIND:
2085 case VK_PROPS:
2086 case VK_STOP:
2087 case VK_COMPOSE:
2088 case VK_ALT_GRAPH:
2090 default:
2091 return GDK_VoidSymbol;