]> gcc.gnu.org Git - gcc.git/blame - libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
[multiple changes]
[gcc.git] / libjava / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkEvents.c
CommitLineData
5aac1dac 1/* gtkevents.c -- GDK/GTK event handlers
2635995a 2 Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
5aac1dac
TT
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39#include "gtkpeer.h"
40#include <X11/Xlib.h>
41#include <gdk/gdkkeysyms.h>
42#include <stdarg.h>
43#include <assert.h>
44
45/* A widget can be composed of multipled windows, so we need to hook
46 events on all of them. */
47struct event_hook_info
48{
49 jobject *peer_obj;
50 int nwindows;
d0b8b6fb
TF
51 /* array of pointers to (GdkWindow *) */
52 GdkWindow ***windows;
5aac1dac
TT
53};
54
55static jint
56button_to_awt_mods (int button)
57{
58 switch (button)
59 {
60 case 1:
61 return AWT_BUTTON1_MASK;
62 case 2:
63 return AWT_BUTTON2_MASK;
64 case 3:
65 return AWT_BUTTON3_MASK;
66 }
67
68 return 0;
69}
70
71static jint
d0b8b6fb 72state_to_awt_mods (guint state)
5aac1dac
TT
73{
74 jint result = 0;
75
d0b8b6fb 76 if (state & GDK_SHIFT_MASK)
5aac1dac 77 result |= AWT_SHIFT_MASK;
d0b8b6fb 78 if (state & GDK_CONTROL_MASK)
5aac1dac 79 result |= AWT_CTRL_MASK;
d0b8b6fb
TF
80 if (state & GDK_MOD1_MASK)
81 result |= AWT_ALT_MASK;
82
5aac1dac
TT
83 return result;
84}
85
86881a7b
GH
86static jint
87state_to_awt_mods_with_button_states (guint state)
88{
89 jint result = 0;
90
91 if (state & GDK_SHIFT_MASK)
92 result |= AWT_SHIFT_MASK;
93 if (state & GDK_CONTROL_MASK)
94 result |= AWT_CTRL_MASK;
95 if (state & GDK_MOD1_MASK)
96 result |= AWT_ALT_MASK;
97 if (state & GDK_BUTTON1_MASK)
98 result |= AWT_BUTTON1_MASK;
99 if (state & GDK_BUTTON2_MASK)
100 result |= AWT_BUTTON2_MASK;
101 if (state & GDK_BUTTON3_MASK)
102 result |= AWT_BUTTON3_MASK;
103
104 return result;
105}
106
d0b8b6fb
TF
107/* Modifier key events need special treatment. In Sun's peer
108 implementation, when a modifier key is pressed, the KEY_PRESSED
109 event has that modifier in its modifiers list. The corresponding
110 KEY_RELEASED event's modifier list does not contain the modifier.
111 For example, pressing and releasing the shift key will produce a
112 key press event with modifiers=Shift, and a key release event with
113 no modifiers. GDK's key events behave in the exact opposite way,
114 so this translation code is needed. */
ff4cc28b 115jint
d0b8b6fb
TF
116keyevent_state_to_awt_mods (GdkEvent *event)
117{
118 jint result = 0;
119 guint state;
120
121 if (event->type == GDK_KEY_PRESS)
122 {
123 state = event->key.state;
124
125 if (event->key.keyval == GDK_Shift_L
126 || event->key.keyval == GDK_Shift_R)
127 result |= AWT_SHIFT_MASK;
128 else
129 {
130 if (state & GDK_SHIFT_MASK)
131 result |= AWT_SHIFT_MASK;
132 }
133
134 if (event->key.keyval == GDK_Control_L
135 || event->key.keyval == GDK_Control_R)
136 result |= AWT_CTRL_MASK;
137 else
138 {
139 if (state & GDK_CONTROL_MASK)
140 result |= AWT_CTRL_MASK;
141 }
142
143 if (event->key.keyval == GDK_Alt_L
144 || event->key.keyval == GDK_Alt_R)
145 result |= AWT_ALT_MASK;
146 else
147 {
148 if (state & GDK_MOD1_MASK)
149 result |= AWT_ALT_MASK;
150 }
151 }
152 else if (event->type == GDK_KEY_RELEASE)
153 {
154 state = event->key.state;
155
156 if (event->key.keyval != GDK_Shift_L
157 && event->key.keyval != GDK_Shift_R)
158 {
159 if (state & GDK_SHIFT_MASK)
160 result |= AWT_SHIFT_MASK;
161 }
162 if (event->key.keyval != GDK_Control_L
163 && event->key.keyval != GDK_Control_R)
164 {
165 if (state & GDK_CONTROL_MASK)
166 result |= AWT_CTRL_MASK;
167 }
168
169 if (event->key.keyval != GDK_Alt_L
170 && event->key.keyval != GDK_Alt_R)
171 {
172 if (state & GDK_MOD1_MASK)
173 result |= AWT_ALT_MASK;
174 }
175 }
176
177 return result;
178}
179
180/* Get the first keyval in the keymap for this event's keycode. The
181 first keyval corresponds roughly to Java's notion of a virtual
182 key. Returns the uppercase version of the first keyval. */
183static guint
184get_first_keyval_from_keymap (GdkEvent *event)
185{
186 guint keyval;
187 guint *keyvals;
188 gint n_entries;
189
190 if (!gdk_keymap_get_entries_for_keycode (NULL,
191 event->key.hardware_keycode,
192 NULL,
193 &keyvals,
194 &n_entries))
195 {
196 g_warning ("No keyval found for hardware keycode %d\n",
197 event->key.hardware_keycode);
198 /* Try to recover by using the keyval in the event structure. */
199 keyvals = &(event->key.keyval);
200 }
201 keyval = keyvals[0];
202 g_free (keyvals);
203
204 return gdk_keyval_to_upper (keyval);
205}
206
5aac1dac
TT
207#ifdef __GNUC__
208__inline
209#endif
210static jint
d0b8b6fb 211keysym_to_awt_keycode (GdkEvent *event)
5aac1dac 212{
d0b8b6fb
TF
213 guint ukeyval;
214 guint state;
5aac1dac 215
d0b8b6fb
TF
216 ukeyval = get_first_keyval_from_keymap (event);
217 state = event->key.state;
5aac1dac 218
d0b8b6fb
TF
219 /* VK_A through VK_Z */
220 if (ukeyval >= GDK_A && ukeyval <= GDK_Z)
221 return ukeyval;
5aac1dac 222
d0b8b6fb
TF
223 /* VK_0 through VK_9 */
224 if (ukeyval >= GDK_0 && ukeyval <= GDK_9)
225 return ukeyval;
5aac1dac 226
d0b8b6fb 227 switch (ukeyval)
5aac1dac 228 {
d0b8b6fb
TF
229 case GDK_Return:
230 case GDK_KP_Enter:
231 return VK_ENTER;
5aac1dac
TT
232 case GDK_BackSpace:
233 return VK_BACK_SPACE;
d0b8b6fb
TF
234 case GDK_Tab:
235 return VK_TAB;
5aac1dac
TT
236 case GDK_Cancel:
237 return VK_CANCEL;
5aac1dac
TT
238 case GDK_Clear:
239 return VK_CLEAR;
d0b8b6fb
TF
240 case GDK_Shift_L:
241 case GDK_Shift_R:
242 return VK_SHIFT;
5aac1dac
TT
243 case GDK_Control_L:
244 case GDK_Control_R:
245 return VK_CONTROL;
d0b8b6fb
TF
246 case GDK_Alt_L:
247 case GDK_Alt_R:
248 return VK_ALT;
249 case GDK_Pause:
250 return VK_PAUSE;
251 case GDK_Caps_Lock:
252 return VK_CAPS_LOCK;
253 case GDK_Escape:
254 return VK_ESCAPE;
255 case GDK_space:
256 return VK_SPACE;
257 case GDK_KP_Page_Up:
258 /* For keys on the numeric keypad, the JVM produces one of two
259 virtual keys, depending on the num lock state. */
260 if (state & GDK_MOD2_MASK)
261 return VK_NUMPAD9;
262 else
263 return VK_PAGE_UP;
264 case GDK_Page_Up:
265 return VK_PAGE_UP;
266 case GDK_KP_Page_Down:
267 if (state & GDK_MOD2_MASK)
268 return VK_NUMPAD3;
269 else
270 return VK_PAGE_DOWN;
271 case GDK_Page_Down:
272 return VK_PAGE_DOWN;
273 case GDK_KP_End:
274 if (state & GDK_MOD2_MASK)
275 return VK_NUMPAD1;
276 else
277 return VK_END;
278 case GDK_End:
279 return VK_END;
280 case GDK_KP_Home:
281 if (state & GDK_MOD2_MASK)
282 return VK_NUMPAD7;
283 else
284 return VK_HOME;
285 case GDK_Home:
286 return VK_HOME;
287 case GDK_KP_Begin:
288 if (state & GDK_MOD2_MASK)
289 return VK_NUMPAD5;
290 else
291 return VK_UNDEFINED;
292 case GDK_Left:
293 return VK_LEFT;
294 case GDK_Up:
295 return VK_UP;
296 case GDK_Right:
297 return VK_RIGHT;
298 case GDK_Down:
299 return VK_DOWN;
300 case GDK_comma:
301 return VK_COMMA;
302 case GDK_minus:
303 return VK_MINUS;
304 case GDK_period:
305 return VK_PERIOD;
306 case GDK_slash:
307 return VK_SLASH;
308 /*
309 return VK_0;
310 return VK_1;
311 return VK_2;
312 return VK_3;
313 return VK_4;
314 return VK_5;
315 return VK_6;
316 return VK_7;
317 return VK_8;
318 return VK_9;
319 */
320 case GDK_semicolon:
321 return VK_SEMICOLON;
322 case GDK_equal:
323 return VK_EQUALS;
324 /*
325 return VK_A;
326 return VK_B;
327 return VK_C;
328 return VK_D;
329 return VK_E;
330 return VK_F;
331 return VK_G;
332 return VK_H;
333 return VK_I;
334 return VK_J;
335 return VK_K;
336 return VK_L;
337 return VK_M;
338 return VK_N;
339 return VK_O;
340 return VK_P;
341 return VK_Q;
342 return VK_R;
343 return VK_S;
344 return VK_T;
345 return VK_U;
346 return VK_V;
347 return VK_W;
348 return VK_X;
349 return VK_Y;
350 return VK_Z;
351 */
352 case GDK_bracketleft:
353 return VK_OPEN_BRACKET;
354 case GDK_backslash:
355 return VK_BACK_SLASH;
356 case GDK_bracketright:
357 return VK_CLOSE_BRACKET;
358 case GDK_KP_0:
359 return VK_NUMPAD0;
360 case GDK_KP_1:
361 return VK_NUMPAD1;
362 case GDK_KP_2:
363 return VK_NUMPAD2;
364 case GDK_KP_3:
365 return VK_NUMPAD3;
366 case GDK_KP_4:
367 return VK_NUMPAD4;
368 case GDK_KP_5:
369 return VK_NUMPAD5;
370 case GDK_KP_6:
371 return VK_NUMPAD6;
372 case GDK_KP_7:
373 return VK_NUMPAD7;
374 case GDK_KP_8:
375 return VK_NUMPAD8;
376 case GDK_KP_9:
377 return VK_NUMPAD9;
378 case GDK_KP_Multiply:
379 return VK_MULTIPLY;
380 case GDK_KP_Add:
381 return VK_ADD;
382 /*
383 return VK_SEPARATER;
384 */
385 case GDK_KP_Separator:
386 return VK_SEPARATOR;
387 case GDK_KP_Subtract:
388 return VK_SUBTRACT;
5aac1dac
TT
389 case GDK_KP_Decimal:
390 return VK_DECIMAL;
5aac1dac
TT
391 case GDK_KP_Divide:
392 return VK_DIVIDE;
d0b8b6fb
TF
393 case GDK_KP_Delete:
394 if (state & GDK_MOD2_MASK)
395 return VK_DECIMAL;
396 else
397 return VK_DELETE;
398 case GDK_Delete:
399 return VK_DELETE;
400 case GDK_Num_Lock:
401 return VK_NUM_LOCK;
402 case GDK_Scroll_Lock:
403 return VK_SCROLL_LOCK;
5aac1dac
TT
404 case GDK_F1:
405 return VK_F1;
406 case GDK_F2:
407 return VK_F2;
408 case GDK_F3:
409 return VK_F3;
410 case GDK_F4:
411 return VK_F4;
412 case GDK_F5:
413 return VK_F5;
414 case GDK_F6:
415 return VK_F6;
416 case GDK_F7:
417 return VK_F7;
418 case GDK_F8:
419 return VK_F8;
420 case GDK_F9:
421 return VK_F9;
422 case GDK_F10:
423 return VK_F10;
424 case GDK_F11:
425 return VK_F11;
426 case GDK_F12:
427 return VK_F12;
d0b8b6fb
TF
428 case GDK_F13:
429 return VK_F13;
430 case GDK_F14:
431 return VK_F14;
432 case GDK_F15:
433 return VK_F15;
434 case GDK_F16:
435 return VK_F16;
436 case GDK_F17:
437 return VK_F17;
438 case GDK_F18:
439 return VK_F18;
440 case GDK_F19:
441 return VK_F19;
442 case GDK_F20:
443 return VK_F20;
444 case GDK_F21:
445 return VK_F21;
446 case GDK_F22:
447 return VK_F22;
448 case GDK_F23:
449 return VK_F23;
450 case GDK_F24:
451 return VK_F24;
452 case GDK_Print:
453 return VK_PRINTSCREEN;
454 case GDK_KP_Insert:
455 if (state & GDK_MOD2_MASK)
456 return VK_NUMPAD0;
457 else
458 return VK_INSERT;
5aac1dac
TT
459 case GDK_Insert:
460 return VK_INSERT;
d0b8b6fb
TF
461 case GDK_Help:
462 return VK_HELP;
463 case GDK_Meta_L:
464 case GDK_Meta_R:
465 return VK_META;
466 case GDK_grave:
467 return VK_BACK_QUOTE;
468 case GDK_apostrophe:
469 return VK_QUOTE;
470 case GDK_KP_Up:
471 if (state & GDK_MOD2_MASK)
472 return VK_NUMPAD8;
473 else
474 return VK_KP_UP;
475 case GDK_KP_Down:
476 if (state & GDK_MOD2_MASK)
477 return VK_NUMPAD2;
478 else
479 return VK_KP_DOWN;
480 case GDK_KP_Left:
481 if (state & GDK_MOD2_MASK)
482 return VK_NUMPAD4;
483 else
484 return VK_KP_LEFT;
485 case GDK_KP_Right:
486 if (state & GDK_MOD2_MASK)
487 return VK_NUMPAD6;
488 else
489 return VK_KP_RIGHT;
490 case GDK_dead_grave:
491 return VK_DEAD_GRAVE;
492 case GDK_dead_acute:
493 return VK_DEAD_ACUTE;
494 case GDK_dead_circumflex:
495 return VK_DEAD_CIRCUMFLEX;
496 case GDK_dead_tilde:
497 return VK_DEAD_TILDE;
498 case GDK_dead_macron:
499 return VK_DEAD_MACRON;
500 case GDK_dead_breve:
501 return VK_DEAD_BREVE;
502 case GDK_dead_abovedot:
503 return VK_DEAD_ABOVEDOT;
504 case GDK_dead_diaeresis:
505 return VK_DEAD_DIAERESIS;
506 case GDK_dead_abovering:
507 return VK_DEAD_ABOVERING;
508 case GDK_dead_doubleacute:
509 return VK_DEAD_DOUBLEACUTE;
510 case GDK_dead_caron:
511 return VK_DEAD_CARON;
512 case GDK_dead_cedilla:
513 return VK_DEAD_CEDILLA;
514 case GDK_dead_ogonek:
515 return VK_DEAD_OGONEK;
516 case GDK_dead_iota:
517 return VK_DEAD_IOTA;
518 case GDK_dead_voiced_sound:
519 return VK_DEAD_VOICED_SOUND;
520 case GDK_dead_semivoiced_sound:
521 return VK_DEAD_SEMIVOICED_SOUND;
522 case GDK_ampersand:
523 return VK_AMPERSAND;
524 case GDK_asterisk:
525 return VK_ASTERISK;
526 case GDK_quotedbl:
527 return VK_QUOTEDBL;
528 case GDK_less:
529 return VK_LESS;
530 case GDK_greater:
531 return VK_GREATER;
532 case GDK_braceleft:
533 return VK_BRACELEFT;
534 case GDK_braceright:
535 return VK_BRACERIGHT;
536 case GDK_at:
537 return VK_AT;
538 case GDK_colon:
539 return VK_COLON;
540 case GDK_asciicircum:
541 return VK_CIRCUMFLEX;
542 case GDK_dollar:
543 return VK_DOLLAR;
544 case GDK_EuroSign:
545 return VK_EURO_SIGN;
546 case GDK_exclam:
547 return VK_EXCLAMATION_MARK;
548 case GDK_exclamdown:
549 return VK_INVERTED_EXCLAMATION_MARK;
550 case GDK_parenleft:
551 return VK_LEFT_PARENTHESIS;
552 case GDK_numbersign:
553 return VK_NUMBER_SIGN;
554 case GDK_plus:
555 return VK_PLUS;
556 case GDK_parenright:
557 return VK_RIGHT_PARENTHESIS;
558 case GDK_underscore:
559 return VK_UNDERSCORE;
560 /*
561 return VK_FINAL;
562 return VK_CONVERT;
563 return VK_NONCONVERT;
564 return VK_ACCEPT;
565 */
566 case GDK_Mode_switch:
567 return VK_MODECHANGE;
568 /*
569 return VK_KANA;
570 */
5aac1dac
TT
571 case GDK_Kanji:
572 return VK_KANJI;
d0b8b6fb
TF
573 /*
574 return VK_ALPHANUMERIC;
575 */
576 case GDK_Katakana:
577 return VK_KATAKANA;
578 case GDK_Hiragana:
579 return VK_HIRAGANA;
580 /*
581 return VK_FULL_WIDTH;
582 return VK_HALF_WIDTH;
583 return VK_ROMAN_CHARACTERS;
584 return VK_ALL_CANDIDATES;
585 */
586 case GDK_PreviousCandidate:
587 return VK_PREVIOUS_CANDIDATE;
588 case GDK_Codeinput:
589 return VK_CODE_INPUT;
590 /*
591 return VK_JAPANESE_KATAKANA;
592 return VK_JAPANESE_HIRAGANA;
593 return VK_JAPANESE_ROMAN;
594 */
595 case GDK_Kana_Lock:
596 return VK_KANA_LOCK;
597 /*
598 return VK_INPUT_METHOD_ON_OFF;
599 return VK_CUT;
600 return VK_COPY;
601 return VK_PASTE;
602 return VK_UNDO;
603 return VK_AGAIN;
604 return VK_FIND;
605 return VK_PROPS;
606 return VK_STOP;
607 return VK_COMPOSE;
608 return VK_ALT_GRAPH;
609 */
610 default:
611 return VK_UNDEFINED;
612 }
613}
614
615static jint
616keysym_to_awt_keylocation (GdkEvent *event)
617{
618 guint ukeyval;
619
620 ukeyval = get_first_keyval_from_keymap (event);
621
622 /* VK_A through VK_Z */
623 if (ukeyval >= GDK_A && ukeyval <= GDK_Z)
624 return AWT_KEY_LOCATION_STANDARD;
625
626 /* VK_0 through VK_9 */
627 if (ukeyval >= GDK_0 && ukeyval <= GDK_9)
628 return AWT_KEY_LOCATION_STANDARD;
629
630 switch (ukeyval)
631 {
632 case GDK_Shift_L:
633 case GDK_Control_L:
634 case GDK_Alt_L:
5aac1dac 635 case GDK_Meta_L:
d0b8b6fb
TF
636 return AWT_KEY_LOCATION_LEFT;
637
638 case GDK_Shift_R:
639 case GDK_Control_R:
640 case GDK_Alt_R:
5aac1dac 641 case GDK_Meta_R:
d0b8b6fb
TF
642 return AWT_KEY_LOCATION_RIGHT;
643
644 case GDK_Return:
645 case GDK_BackSpace:
646 case GDK_Tab:
647 case GDK_Cancel:
648 case GDK_Clear:
649 case GDK_Pause:
650 case GDK_Caps_Lock:
651 case GDK_Escape:
652 case GDK_space:
653 case GDK_Page_Up:
654 case GDK_Page_Down:
655 case GDK_End:
656 case GDK_Home:
657 case GDK_Left:
658 case GDK_Up:
659 case GDK_Right:
660 case GDK_Down:
661 case GDK_comma:
662 case GDK_minus:
663 case GDK_period:
664 case GDK_slash:
665 case GDK_semicolon:
666 case GDK_equal:
667 case GDK_bracketleft:
668 case GDK_backslash:
669 case GDK_bracketright:
670 case GDK_Delete:
671 case GDK_Scroll_Lock:
672 case GDK_F1:
673 case GDK_F2:
674 case GDK_F3:
675 case GDK_F4:
676 case GDK_F5:
677 case GDK_F6:
678 case GDK_F7:
679 case GDK_F8:
680 case GDK_F9:
681 case GDK_F10:
682 case GDK_F11:
683 case GDK_F12:
684 case GDK_F13:
685 case GDK_F14:
686 case GDK_F15:
687 case GDK_F16:
688 case GDK_F17:
689 case GDK_F18:
690 case GDK_F19:
691 case GDK_F20:
692 case GDK_F21:
693 case GDK_F22:
694 case GDK_F23:
695 case GDK_F24:
696 case GDK_Print:
697 case GDK_Insert:
698 case GDK_Help:
699 case GDK_grave:
700 case GDK_apostrophe:
701 case GDK_dead_grave:
702 case GDK_dead_acute:
703 case GDK_dead_circumflex:
704 case GDK_dead_tilde:
705 case GDK_dead_macron:
706 case GDK_dead_breve:
707 case GDK_dead_abovedot:
708 case GDK_dead_diaeresis:
709 case GDK_dead_abovering:
710 case GDK_dead_doubleacute:
711 case GDK_dead_caron:
712 case GDK_dead_cedilla:
713 case GDK_dead_ogonek:
714 case GDK_dead_iota:
715 case GDK_dead_voiced_sound:
716 case GDK_dead_semivoiced_sound:
717 case GDK_ampersand:
718 case GDK_asterisk:
719 case GDK_quotedbl:
720 case GDK_less:
721 case GDK_greater:
722 case GDK_braceleft:
723 case GDK_braceright:
724 case GDK_at:
725 case GDK_colon:
726 case GDK_asciicircum:
727 case GDK_dollar:
728 case GDK_EuroSign:
729 case GDK_exclam:
730 case GDK_exclamdown:
731 case GDK_parenleft:
732 case GDK_numbersign:
733 case GDK_plus:
734 case GDK_parenright:
735 case GDK_underscore:
736 case GDK_Mode_switch:
737 case GDK_Kanji:
738 case GDK_Katakana:
739 case GDK_Hiragana:
740 case GDK_PreviousCandidate:
741 case GDK_Codeinput:
742 case GDK_Kana_Lock:
743 return AWT_KEY_LOCATION_STANDARD;
744
745 case GDK_KP_Enter:
746 case GDK_KP_Page_Up:
747 case GDK_KP_Page_Down:
748 case GDK_KP_End:
749 case GDK_KP_Home:
750 case GDK_KP_Begin:
5aac1dac 751 case GDK_KP_0:
5aac1dac 752 case GDK_KP_1:
5aac1dac 753 case GDK_KP_2:
5aac1dac 754 case GDK_KP_3:
5aac1dac 755 case GDK_KP_4:
5aac1dac 756 case GDK_KP_5:
5aac1dac 757 case GDK_KP_6:
5aac1dac 758 case GDK_KP_7:
5aac1dac 759 case GDK_KP_8:
5aac1dac 760 case GDK_KP_9:
d0b8b6fb
TF
761 case GDK_KP_Multiply:
762 case GDK_KP_Add:
5aac1dac 763 case GDK_KP_Separator:
5aac1dac 764 case GDK_KP_Subtract:
d0b8b6fb
TF
765 case GDK_KP_Decimal:
766 case GDK_KP_Divide:
767 case GDK_KP_Delete:
768 case GDK_Num_Lock:
769 case GDK_KP_Insert:
770 case GDK_KP_Up:
771 case GDK_KP_Down:
772 case GDK_KP_Left:
773 case GDK_KP_Right:
774 return AWT_KEY_LOCATION_NUMPAD;
5aac1dac
TT
775
776 default:
d0b8b6fb
TF
777 return AWT_KEY_LOCATION_UNKNOWN;
778 }
779}
780
781static jchar
782keyevent_to_awt_keychar (GdkEvent *event)
783{
784 if (event->key.length > 0)
785 {
786 /* Translate GDK carriage return to Java linefeed. */
787 if (event->key.string[0] == 13)
788 return VK_ENTER;
789 else
790 return event->key.string[0];
791 }
792 else
793 {
794 switch (event->key.keyval)
795 {
796 case GDK_BackSpace:
797 return VK_BACK_SPACE;
798 case GDK_Tab:
799 return VK_TAB;
800 case GDK_Delete:
801 case GDK_KP_Delete:
802 return VK_DELETE;
803 default:
804 return AWT_KEY_CHAR_UNDEFINED;
805 }
5aac1dac
TT
806 }
807}
808
809void
810awt_event_handler (GdkEvent *event)
811{
5aac1dac
TT
812 /* keep synthetic AWT events from being processed recursively */
813 if (event->type & SYNTHETIC_EVENT_MASK && event->type != GDK_NOTHING)
814 {
815 event->type ^= SYNTHETIC_EVENT_MASK;
5aac1dac
TT
816 }
817
834b1209
FN
818 gtk_main_do_event (event);
819}
820
821gboolean
822pre_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
823{
824 GtkWidget *event_widget;
825 static guint32 button_click_time = 0;
826 static GdkWindow *button_window = NULL;
827 static guint button_number = -1;
828 static jint click_count = 1;
86881a7b 829 static int hasBeenDragged;
834b1209
FN
830
831 /* If it is not a focus change event, the widget must be realized already.
832 If not, ignore the event (Gtk+ will do the same). */
833 if (!(event->type == GDK_FOCUS_CHANGE || GTK_WIDGET_REALIZED(widget)))
834 return FALSE;
835
836 /* Do not handle propagated events. AWT has its own propagation rules */
837 gdk_window_get_user_data (event->any.window, (void **) &event_widget);
838 if (event_widget != widget)
839 return FALSE;
840
841 /* We only care about input events */
a1045386
FN
842 if (!(event->type == GDK_BUTTON_PRESS
843 || event->type == GDK_BUTTON_RELEASE
844 || event->type == GDK_ENTER_NOTIFY
845 || event->type == GDK_LEAVE_NOTIFY
846 || event->type == GDK_CONFIGURE
847 || event->type == GDK_EXPOSE
848 || event->type == GDK_KEY_PRESS
849 || event->type == GDK_KEY_RELEASE
850 || event->type == GDK_FOCUS_CHANGE
851 || event->type == GDK_MOTION_NOTIFY))
852 {
834b1209 853 return FALSE;
a1045386 854 }
834b1209
FN
855 /* g_print("event %u widget %s peer %p\n",
856 event->type, gtk_widget_get_name (widget), peer); */
857
858 /* If it has no jobject associated we can send no AWT event */
859 if (!peer)
860 return FALSE;
861
862 /* for all input events, which have a window with a jobject attached,
863 send the AWT input event corresponding to the Gtk event off to Java */
a1045386 864
5aac1dac
TT
865 /* keep track of clickCount ourselves, since the AWT allows more
866 than a triple click to occur */
867 if (event->type == GDK_BUTTON_PRESS)
868 {
869 if ((event->button.time < (button_click_time + MULTI_CLICK_TIME))
870 && (event->button.window == button_window)
871 && (event->button.button == button_number))
872 click_count++;
873 else
874 click_count = 1;
875
876 button_click_time = event->button.time;
877 button_window = event->button.window;
878 button_number = event->button.button;
879 }
880
834b1209 881 switch (event->type)
a1045386 882 {
834b1209
FN
883 case GDK_BUTTON_PRESS:
884 (*gdk_env)->CallVoidMethod (gdk_env, peer,
885 postMouseEventID,
886 AWT_MOUSE_PRESSED,
887 (jlong)event->button.time,
888 state_to_awt_mods (event->button.state) |
889 button_to_awt_mods (event->button.button),
890 (jint)event->button.x,
891 (jint)event->button.y,
892 click_count,
893 (event->button.button == 3) ? JNI_TRUE :
894 JNI_FALSE);
86881a7b 895 hasBeenDragged = FALSE;
834b1209
FN
896 break;
897 case GDK_BUTTON_RELEASE:
898 {
899 int width, height;
900
901 (*gdk_env)->CallVoidMethod (gdk_env, peer,
902 postMouseEventID,
903 AWT_MOUSE_RELEASED,
904 (jlong)event->button.time,
5aac1dac
TT
905 state_to_awt_mods (event->button.state) |
906 button_to_awt_mods (event->button.button),
834b1209
FN
907 (jint)event->button.x,
908 (jint)event->button.y,
909 click_count,
910 JNI_FALSE);
911
2635995a
MW
912 /* Generate an AWT click event only if the release occured in the
913 window it was pressed in, and the mouse has not been dragged since
914 the last time it was pressed. */
834b1209 915 gdk_window_get_size (event->any.window, &width, &height);
86881a7b
GH
916 if (! hasBeenDragged
917 && event->button.x >= 0
834b1209
FN
918 && event->button.y >= 0
919 && event->button.x <= width
920 && event->button.y <= height)
921 {
922 (*gdk_env)->CallVoidMethod (gdk_env, peer,
923 postMouseEventID,
924 AWT_MOUSE_CLICKED,
925 (jlong)event->button.time,
926 state_to_awt_mods (event->button.state) |
927 button_to_awt_mods (event->button.button),
928 (jint)event->button.x,
929 (jint)event->button.y,
930 click_count,
931 JNI_FALSE);
932 }
933 }
934 break;
935 case GDK_MOTION_NOTIFY:
834b1209
FN
936 if (event->motion.state & (GDK_BUTTON1_MASK
937 | GDK_BUTTON2_MASK
938 | GDK_BUTTON3_MASK
939 | GDK_BUTTON4_MASK
940 | GDK_BUTTON5_MASK))
941 {
942 (*gdk_env)->CallVoidMethod (gdk_env, peer,
943 postMouseEventID,
944 AWT_MOUSE_DRAGGED,
5aac1dac 945 (jlong)event->motion.time,
86881a7b 946 state_to_awt_mods_with_button_states (event->motion.state),
5aac1dac
TT
947 (jint)event->motion.x,
948 (jint)event->motion.y,
834b1209
FN
949 0,
950 JNI_FALSE);
86881a7b 951 hasBeenDragged = TRUE;
834b1209 952 }
86881a7b
GH
953 else
954 (*gdk_env)->CallVoidMethod (gdk_env, peer, postMouseEventID,
955 AWT_MOUSE_MOVED,
956 (jlong)event->motion.time,
957 state_to_awt_mods (event->motion.state),
958 (jint)event->motion.x,
959 (jint)event->motion.y,
960 0,
961 JNI_FALSE);
834b1209
FN
962 break;
963 case GDK_ENTER_NOTIFY:
2f9c39f8
FN
964 /* We are not interested in enter events that are due to
965 grab/ungrab and not to actually crossing boundaries */
966 if (event->crossing.mode == GDK_CROSSING_NORMAL)
967 (*gdk_env)->CallVoidMethod (gdk_env, peer, postMouseEventID,
968 AWT_MOUSE_ENTERED,
969 (jlong)event->crossing.time,
86881a7b 970 state_to_awt_mods_with_button_states (event->crossing.state),
2f9c39f8
FN
971 (jint)event->crossing.x,
972 (jint)event->crossing.y,
973 0,
974 JNI_FALSE);
834b1209
FN
975 break;
976 case GDK_LEAVE_NOTIFY:
2f9c39f8
FN
977 /* We are not interested in leave events that are due to
978 grab/ungrab and not to actually crossing boundaries */
834b1209
FN
979 if (event->crossing.mode == GDK_CROSSING_NORMAL)
980 (*gdk_env)->CallVoidMethod (gdk_env, peer,
981 postMouseEventID,
982 AWT_MOUSE_EXITED,
983 (jlong)event->crossing.time,
86881a7b 984 state_to_awt_mods_with_button_states (event->crossing.state),
834b1209
FN
985 (jint)event->crossing.x,
986 (jint)event->crossing.y,
987 0,
988 JNI_FALSE);
989 break;
990 case GDK_CONFIGURE:
991 {
992 /* GtkWidget *widget;
993
994 gdk_window_get_user_data (event->any.window, (void **) &widget); */
5aac1dac 995
834b1209 996 if (widget && GTK_WIDGET_TOPLEVEL (widget))
5aac1dac 997 {
834b1209
FN
998 /* Configure events are not posted to the AWT event
999 queue, and as such, the gdk/gtk peer functions will
1000 be called back before postConfigureEvent
1001 returns. */
1002 gdk_threads_leave ();
1003
834b1209
FN
1004 (*gdk_env)->CallVoidMethod (gdk_env, peer,
1005 postConfigureEventID,
1006 (jint) event->configure.x,
1007 (jint) event->configure.y,
1008 (jint) event->configure.width,
db19e39b 1009 (jint) event->configure.height);
834b1209 1010 gdk_threads_enter ();
5aac1dac 1011 }
834b1209
FN
1012 }
1013 break;
1014 case GDK_EXPOSE:
1015 {
2635995a
MW
1016 /* This filters out unwanted feedback expose events from gtk/X
1017 when we explictly invalidate and update heavyweight components,
1018 thus avoiding an infinite loop.
1019 FIXME: I'm not quite sure why we're getting these expose events.
1020 Maybe there is a way to avoid them? */
7edbd87e
DJ
1021 if((event->any.window == widget->window && event->any.send_event)
1022 || GTK_IS_LAYOUT(widget))
1023 {
1024 (*gdk_env)->CallVoidMethod (gdk_env, peer,
1025 postExposeEventID,
1026 (jint)event->expose.area.x,
1027 (jint)event->expose.area.y,
1028 (jint)event->expose.area.width,
1029 (jint)event->expose.area.height);
1030 }
834b1209
FN
1031 }
1032 break;
c5d2de6b 1033
834b1209
FN
1034 case GDK_FOCUS_CHANGE:
1035 (*gdk_env)->CallVoidMethod (gdk_env, peer,
1036 postFocusEventID,
c5d2de6b 1037 (jint) (event->focus_change.in) ?
834b1209
FN
1038 AWT_FOCUS_GAINED : AWT_FOCUS_LOST,
1039 JNI_FALSE);
1040 break;
1041 case GDK_KEY_PRESS:
c5d2de6b
GH
1042 if (GTK_IS_WINDOW (widget))
1043 {
1044 /* GdkEventKey *keyevent = (GdkEventKey *) event; */
1045 /* g_printerr ("key press event: sent: %d time: %d state: %d keyval: %d length: %d string: %s hardware_keycode: %d group: %d\n", keyevent->send_event, keyevent->time, keyevent->state, keyevent->keyval, keyevent->length, keyevent->string, keyevent->hardware_keycode, keyevent->group); */
834b1209 1046
c5d2de6b
GH
1047 (*gdk_env)->CallVoidMethod (gdk_env, peer,
1048 postKeyEventID,
1049 (jint) AWT_KEY_PRESSED,
1050 (jlong) event->key.time,
834b1209
FN
1051 keyevent_state_to_awt_mods (event),
1052 keysym_to_awt_keycode (event),
1053 keyevent_to_awt_keychar (event),
1054 keysym_to_awt_keylocation (event));
c5d2de6b
GH
1055 /* FIXME: generation of key typed events needs to be moved
1056 to GtkComponentPeer.postKeyEvent. If the key in a key
1057 press event is not an "action" key
1058 (KeyEvent.isActionKey) and is not a modifier key, then
1059 it should generate a key typed event. */
1060 return TRUE;
b6fa901b 1061 }
c5d2de6b
GH
1062 else
1063 return FALSE;
1064 break;
1065 case GDK_KEY_RELEASE:
1066 if (GTK_IS_WINDOW (widget))
1067 {
1068 (*gdk_env)->CallVoidMethod (gdk_env, peer,
1069 postKeyEventID,
1070 (jint) AWT_KEY_RELEASED,
1071 (jlong) event->key.time,
1072 keyevent_state_to_awt_mods (event),
1073 keysym_to_awt_keycode (event),
834b1209
FN
1074 keyevent_to_awt_keychar (event),
1075 keysym_to_awt_keylocation (event));
c5d2de6b
GH
1076 return TRUE;
1077 }
1078 else
1079 return FALSE;
834b1209
FN
1080 break;
1081 default:
1082 break;
d0b8b6fb 1083 }
834b1209
FN
1084
1085 return FALSE;
5aac1dac
TT
1086}
1087
1088static void
1089attach_jobject (GdkWindow *window, jobject *obj)
1090{
1091 GdkAtom addr_atom = gdk_atom_intern ("_GNU_GTKAWT_ADDR", FALSE);
1092 GdkAtom type_atom = gdk_atom_intern ("CARDINAL", FALSE);
1093
1094 gdk_window_set_events (window,
1095 gdk_window_get_events (window)
1096 | GDK_POINTER_MOTION_MASK
1097 | GDK_BUTTON_MOTION_MASK
1098 | GDK_BUTTON_PRESS_MASK
1099 | GDK_BUTTON_RELEASE_MASK
1100 | GDK_KEY_PRESS_MASK
1101 | GDK_KEY_RELEASE_MASK
1102 | GDK_ENTER_NOTIFY_MASK
1103 | GDK_LEAVE_NOTIFY_MASK
1104 | GDK_STRUCTURE_MASK
1105 | GDK_KEY_PRESS_MASK
1106 | GDK_FOCUS_CHANGE_MASK);
1107
1108 gdk_property_change (window,
1109 addr_atom,
1110 type_atom,
1111 8,
1112 GDK_PROP_MODE_REPLACE,
1113 (guchar *)obj,
1114 sizeof (jobject));
1115}
1116
1117void
1118connect_awt_hook (JNIEnv *env, jobject peer_obj, int nwindows, ...)
1119{
5aac1dac
TT
1120 va_list ap;
1121 jobject *obj;
1122
7ecd4576 1123 obj = NSA_GET_GLOBAL_REF (env, peer_obj);
7ecd4576 1124 g_assert (obj);
5aac1dac
TT
1125
1126 va_start (ap, nwindows);
29e531ff
TF
1127 {
1128 int i;
5aac1dac 1129 for (i = 0; i < nwindows; i++)
29e531ff
TF
1130 {
1131 GdkWindow* attach = (va_arg (ap, GdkWindow *));
29e531ff
TF
1132 attach_jobject(attach, obj);
1133 }
1134 }
5aac1dac
TT
1135 va_end (ap);
1136}
834b1209 1137
This page took 0.269729 seconds and 5 git commands to generate.