Merge from the pain train
[official-gcc.git] / libjava / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkComponentPeer.c
blob4cd3f16574fb4e7a6651cf9b11cfe500b681a0fc
1 /* gtkcomponentpeer.c -- Native implementation of GtkComponentPeer
2 Copyright (C) 1998, 1999, 2002, 2004 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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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_GtkComponentPeer.h"
41 #include <gtk/gtkprivate.h>
42 #include <gdk/gdkkeysyms.h>
44 static GtkWidget *find_fg_color_widget (GtkWidget *widget);
45 static GtkWidget *find_bg_color_widget (GtkWidget *widget);
46 static gboolean focus_in_cb (GtkWidget *widget,
47 GdkEventFocus *event,
48 jobject peer);
49 static gboolean focus_out_cb (GtkWidget *widget,
50 GdkEventFocus *event,
51 jobject peer);
54 * This method returns a GDK keyval that corresponds to one of the
55 * keysyms in the X keymap table. The return value is only used to
56 * determine the keyval's corresponding hardware keycode, and doesn't
57 * reflect an accurate translation of a Java virtual key value to a
58 * GDK keyval.
60 #ifdef __GNUC__
61 __inline
62 #endif
63 guint
64 awt_keycode_to_keysym (jint keyCode, jint keyLocation)
66 /* GDK_A through GDK_Z */
67 if (keyCode >= VK_A && keyCode <= VK_Z)
68 return gdk_keyval_to_lower (keyCode);
70 /* GDK_0 through GDK_9 */
71 if (keyCode >= VK_0 && keyCode <= VK_9)
72 return keyCode;
74 switch (keyCode)
76 case VK_ENTER:
77 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Enter : GDK_Return;
78 case VK_BACK_SPACE:
79 return GDK_BackSpace;
80 case VK_TAB:
81 return GDK_Tab;
82 case VK_CANCEL:
83 return GDK_Cancel;
84 case VK_CLEAR:
85 return GDK_Clear;
86 case VK_SHIFT:
87 return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Shift_L : GDK_Shift_R;
88 case VK_CONTROL:
89 return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Control_L : GDK_Control_R;
90 case VK_ALT:
91 return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Alt_L : GDK_Alt_R;
92 case VK_PAUSE:
93 return GDK_Pause;
94 case VK_CAPS_LOCK:
95 return GDK_Caps_Lock;
96 case VK_ESCAPE:
97 return GDK_Escape;
98 case VK_SPACE:
99 return GDK_space;
100 case VK_PAGE_UP:
101 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Page_Up : GDK_Page_Up;
102 case VK_PAGE_DOWN:
103 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Page_Down : GDK_Page_Down;
104 case VK_END:
105 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_End : GDK_End;
106 case VK_HOME:
107 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Home : GDK_Home;
108 case VK_LEFT:
109 return GDK_Left;
110 case VK_UP:
111 return GDK_Up;
112 case VK_RIGHT:
113 return GDK_Right;
114 case VK_DOWN:
115 return GDK_Down;
116 case VK_COMMA:
117 return GDK_comma;
118 case VK_MINUS:
119 return GDK_minus;
120 case VK_PERIOD:
121 return GDK_period;
122 case VK_SLASH:
123 return GDK_slash;
125 case VK_0:
126 case VK_1:
127 case VK_2:
128 case VK_3:
129 case VK_4:
130 case VK_5:
131 case VK_6:
132 case VK_7:
133 case VK_8:
134 case VK_9:
136 case VK_SEMICOLON:
137 return GDK_semicolon;
138 case VK_EQUALS:
139 return GDK_equal;
141 case VK_A:
142 case VK_B:
143 case VK_C:
144 case VK_D:
145 case VK_E:
146 case VK_F:
147 case VK_G:
148 case VK_H:
149 case VK_I:
150 case VK_J:
151 case VK_K:
152 case VK_L:
153 case VK_M:
154 case VK_N:
155 case VK_O:
156 case VK_P:
157 case VK_Q:
158 case VK_R:
159 case VK_S:
160 case VK_T:
161 case VK_U:
162 case VK_V:
163 case VK_W:
164 case VK_X:
165 case VK_Y:
166 case VK_Z:
168 case VK_OPEN_BRACKET:
169 return GDK_bracketleft;
170 case VK_BACK_SLASH:
171 return GDK_backslash;
172 case VK_CLOSE_BRACKET:
173 return GDK_bracketright;
174 case VK_NUMPAD0:
175 return GDK_KP_0;
176 case VK_NUMPAD1:
177 return GDK_KP_1;
178 case VK_NUMPAD2:
179 return GDK_KP_2;
180 case VK_NUMPAD3:
181 return GDK_KP_3;
182 case VK_NUMPAD4:
183 return GDK_KP_4;
184 case VK_NUMPAD5:
185 return GDK_KP_5;
186 case VK_NUMPAD6:
187 return GDK_KP_6;
188 case VK_NUMPAD7:
189 return GDK_KP_7;
190 case VK_NUMPAD8:
191 return GDK_KP_8;
192 case VK_NUMPAD9:
193 return GDK_KP_9;
194 case VK_MULTIPLY:
195 return GDK_KP_Multiply;
196 case VK_ADD:
197 return GDK_KP_Add;
199 case VK_SEPARATER:
201 case VK_SEPARATOR:
202 return GDK_KP_Separator;
203 case VK_SUBTRACT:
204 return GDK_KP_Subtract;
205 case VK_DECIMAL:
206 return GDK_KP_Decimal;
207 case VK_DIVIDE:
208 return GDK_KP_Divide;
209 case VK_DELETE:
210 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Delete : GDK_Delete;
211 case VK_NUM_LOCK:
212 return GDK_Num_Lock;
213 case VK_SCROLL_LOCK:
214 return GDK_Scroll_Lock;
215 case VK_F1:
216 return GDK_F1;
217 case VK_F2:
218 return GDK_F2;
219 case VK_F3:
220 return GDK_F3;
221 case VK_F4:
222 return GDK_F4;
223 case VK_F5:
224 return GDK_F5;
225 case VK_F6:
226 return GDK_F6;
227 case VK_F7:
228 return GDK_F7;
229 case VK_F8:
230 return GDK_F8;
231 case VK_F9:
232 return GDK_F9;
233 case VK_F10:
234 return GDK_F10;
235 case VK_F11:
236 return GDK_F11;
237 case VK_F12:
238 return GDK_F12;
239 case VK_F13:
240 return GDK_F13;
241 case VK_F14:
242 return GDK_F14;
243 case VK_F15:
244 return GDK_F15;
245 case VK_F16:
246 return GDK_F16;
247 case VK_F17:
248 return GDK_F17;
249 case VK_F18:
250 return GDK_F18;
251 case VK_F19:
252 return GDK_F19;
253 case VK_F20:
254 return GDK_F20;
255 case VK_F21:
256 return GDK_F21;
257 case VK_F22:
258 return GDK_F22;
259 case VK_F23:
260 return GDK_F23;
261 case VK_F24:
262 return GDK_F24;
263 case VK_PRINTSCREEN:
264 return GDK_Print;
265 case VK_INSERT:
266 return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Insert : GDK_Insert;
267 case VK_HELP:
268 return GDK_Help;
269 case VK_META:
270 return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Meta_L : GDK_Meta_R;
271 case VK_BACK_QUOTE:
272 return GDK_grave;
273 case VK_QUOTE:
274 return GDK_apostrophe;
275 case VK_KP_UP:
276 return GDK_KP_Up;
277 case VK_KP_DOWN:
278 return GDK_KP_Down;
279 case VK_KP_LEFT:
280 return GDK_KP_Left;
281 case VK_KP_RIGHT:
282 return GDK_KP_Right;
283 case VK_DEAD_GRAVE:
284 return GDK_dead_grave;
285 case VK_DEAD_ACUTE:
286 return GDK_dead_acute;
287 case VK_DEAD_CIRCUMFLEX:
288 return GDK_dead_circumflex;
289 case VK_DEAD_TILDE:
290 return GDK_dead_tilde;
291 case VK_DEAD_MACRON:
292 return GDK_dead_macron;
293 case VK_DEAD_BREVE:
294 return GDK_dead_breve;
295 case VK_DEAD_ABOVEDOT:
296 return GDK_dead_abovedot;
297 case VK_DEAD_DIAERESIS:
298 return GDK_dead_diaeresis;
299 case VK_DEAD_ABOVERING:
300 return GDK_dead_abovering;
301 case VK_DEAD_DOUBLEACUTE:
302 return GDK_dead_doubleacute;
303 case VK_DEAD_CARON:
304 return GDK_dead_caron;
305 case VK_DEAD_CEDILLA:
306 return GDK_dead_cedilla;
307 case VK_DEAD_OGONEK:
308 return GDK_dead_ogonek;
309 case VK_DEAD_IOTA:
310 return GDK_dead_iota;
311 case VK_DEAD_VOICED_SOUND:
312 return GDK_dead_voiced_sound;
313 case VK_DEAD_SEMIVOICED_SOUND:
314 return GDK_dead_semivoiced_sound;
315 case VK_AMPERSAND:
316 return GDK_ampersand;
317 case VK_ASTERISK:
318 return GDK_asterisk;
319 case VK_QUOTEDBL:
320 return GDK_quotedbl;
321 case VK_LESS:
322 return GDK_less;
323 case VK_GREATER:
324 return GDK_greater;
325 case VK_BRACELEFT:
326 return GDK_braceleft;
327 case VK_BRACERIGHT:
328 return GDK_braceright;
329 case VK_AT:
330 return GDK_at;
331 case VK_COLON:
332 return GDK_colon;
333 case VK_CIRCUMFLEX:
334 return GDK_asciicircum;
335 case VK_DOLLAR:
336 return GDK_dollar;
337 case VK_EURO_SIGN:
338 return GDK_EuroSign;
339 case VK_EXCLAMATION_MARK:
340 return GDK_exclam;
341 case VK_INVERTED_EXCLAMATION_MARK:
342 return GDK_exclamdown;
343 case VK_LEFT_PARENTHESIS:
344 return GDK_parenleft;
345 case VK_NUMBER_SIGN:
346 return GDK_numbersign;
347 case VK_PLUS:
348 return GDK_plus;
349 case VK_RIGHT_PARENTHESIS:
350 return GDK_parenright;
351 case VK_UNDERSCORE:
352 return GDK_underscore;
354 case VK_FINAL:
355 case VK_CONVERT:
356 case VK_NONCONVERT:
357 case VK_ACCEPT:
359 case VK_MODECHANGE:
360 return GDK_Mode_switch;
362 case VK_KANA:
364 case VK_KANJI:
365 return GDK_Kanji;
367 case VK_ALPHANUMERIC:
369 case VK_KATAKANA:
370 return GDK_Katakana;
371 case VK_HIRAGANA:
372 return GDK_Hiragana;
374 case VK_FULL_WIDTH:
375 case VK_HALF_WIDTH:
376 case VK_ROMAN_CHARACTERS:
377 case VK_ALL_CANDIDATES:
379 case VK_PREVIOUS_CANDIDATE:
380 return GDK_PreviousCandidate;
381 case VK_CODE_INPUT:
382 return GDK_Codeinput;
384 case VK_JAPANESE_KATAKANA:
385 case VK_JAPANESE_HIRAGANA:
386 case VK_JAPANESE_ROMAN:
388 case VK_KANA_LOCK:
389 return GDK_Kana_Lock;
391 case VK_INPUT_METHOD_ON_OFF:
392 case VK_CUT:
393 case VK_COPY:
394 case VK_PASTE:
395 case VK_UNDO:
396 case VK_AGAIN:
397 case VK_FIND:
398 case VK_PROPS:
399 case VK_STOP:
400 case VK_COMPOSE:
401 case VK_ALT_GRAPH:
403 default:
404 return GDK_VoidSymbol;
409 JNIEXPORT void JNICALL
410 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursor
411 (JNIEnv *env, jobject obj, jint type)
413 void *ptr;
414 GtkWidget *widget;
415 GdkCursorType gdk_cursor_type;
416 GdkCursor *gdk_cursor;
418 ptr = NSA_GET_PTR (env, obj);
420 switch (type)
422 case AWT_CROSSHAIR_CURSOR:
423 gdk_cursor_type = GDK_CROSSHAIR;
424 break;
425 case AWT_TEXT_CURSOR:
426 gdk_cursor_type = GDK_XTERM;
427 break;
428 case AWT_WAIT_CURSOR:
429 gdk_cursor_type = GDK_WATCH;
430 break;
431 case AWT_SW_RESIZE_CURSOR:
432 gdk_cursor_type = GDK_BOTTOM_LEFT_CORNER;
433 break;
434 case AWT_SE_RESIZE_CURSOR:
435 gdk_cursor_type = GDK_BOTTOM_RIGHT_CORNER;
436 break;
437 case AWT_NW_RESIZE_CURSOR:
438 gdk_cursor_type = GDK_TOP_LEFT_CORNER;
439 break;
440 case AWT_NE_RESIZE_CURSOR:
441 gdk_cursor_type = GDK_TOP_RIGHT_CORNER;
442 break;
443 case AWT_N_RESIZE_CURSOR:
444 gdk_cursor_type = GDK_TOP_SIDE;
445 break;
446 case AWT_S_RESIZE_CURSOR:
447 gdk_cursor_type = GDK_BOTTOM_SIDE;
448 break;
449 case AWT_W_RESIZE_CURSOR:
450 gdk_cursor_type = GDK_LEFT_SIDE;
451 break;
452 case AWT_E_RESIZE_CURSOR:
453 gdk_cursor_type = GDK_RIGHT_SIDE;
454 break;
455 case AWT_HAND_CURSOR:
456 gdk_cursor_type = GDK_HAND2;
457 break;
458 case AWT_MOVE_CURSOR:
459 gdk_cursor_type = GDK_FLEUR;
460 break;
461 default:
462 gdk_cursor_type = GDK_LEFT_PTR;
465 gdk_threads_enter ();
467 widget = GTK_WIDGET(ptr);
469 gdk_cursor = gdk_cursor_new (gdk_cursor_type);
470 gdk_window_set_cursor (widget->window, gdk_cursor);
471 gdk_cursor_destroy (gdk_cursor);
473 gdk_threads_leave ();
476 JNIEXPORT void JNICALL
477 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetParent
478 (JNIEnv *env, jobject obj, jobject parent)
480 void *ptr;
481 void *parent_ptr;
482 GtkWidget *widget;
483 GtkWidget *parent_widget;
485 ptr = NSA_GET_PTR (env, obj);
486 parent_ptr = NSA_GET_PTR (env, parent);
488 gdk_threads_enter ();
490 widget = GTK_WIDGET (ptr);
491 parent_widget = GTK_WIDGET (parent_ptr);
493 if (widget->parent == NULL)
495 if (GTK_IS_WINDOW (parent_widget))
497 GList *children = gtk_container_children
498 (GTK_CONTAINER (parent_widget));
500 if (GTK_IS_MENU_BAR (children->data))
501 gtk_fixed_put (GTK_FIXED (children->next->data), widget, 0, 0);
502 else
503 gtk_fixed_put (GTK_FIXED (children->data), widget, 0, 0);
505 else
506 if (GTK_IS_SCROLLED_WINDOW (parent_widget))
508 gtk_scrolled_window_add_with_viewport
509 (GTK_SCROLLED_WINDOW (parent_widget), widget);
510 gtk_viewport_set_shadow_type (GTK_VIEWPORT (widget->parent),
511 GTK_SHADOW_NONE);
514 else
516 if (widget->parent == NULL)
517 gtk_fixed_put (GTK_FIXED (parent_widget), widget, 0, 0);
521 gdk_threads_leave ();
524 JNIEXPORT void JNICALL
525 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetSensitive
526 (JNIEnv *env, jobject obj, jboolean sensitive)
528 void *ptr;
530 ptr = NSA_GET_PTR (env, obj);
532 gdk_threads_enter ();
534 gtk_widget_set_sensitive (GTK_WIDGET (ptr), sensitive);
536 gdk_threads_leave ();
539 JNIEXPORT void JNICALL
540 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetRequestFocus
541 (JNIEnv *env, jobject obj)
543 void *ptr;
545 ptr = NSA_GET_PTR (env, obj);
547 gdk_threads_enter ();
548 gtk_widget_grab_focus (GTK_WIDGET (ptr));
549 gdk_threads_leave ();
553 * Translate a Java KeyEvent object into a GdkEventKey event, then
554 * pass it to the GTK main loop for processing.
556 JNIEXPORT void JNICALL
557 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetDispatchKeyEvent
558 (JNIEnv *env, jobject obj, jint id, jlong when, jint mods,
559 jint keyCode, jint keyLocation)
561 void *ptr;
562 GdkEvent *event = NULL;
563 GdkKeymapKey *keymap_keys = NULL;
564 gint n_keys = 0;
565 guint lookup_keyval = 0;
567 ptr = NSA_GET_PTR (env, obj);
569 gdk_threads_enter ();
571 if (id == AWT_KEY_PRESSED)
572 event = gdk_event_new (GDK_KEY_PRESS);
573 else if (id == AWT_KEY_RELEASED)
574 event = gdk_event_new (GDK_KEY_RELEASE);
575 else
577 gdk_threads_leave ();
578 /* Don't send AWT KEY_TYPED events to GTK. */
579 return;
582 if (GTK_IS_BUTTON (ptr))
583 event->key.window = GTK_BUTTON (ptr)->event_window;
584 else if (GTK_IS_SCROLLED_WINDOW (ptr))
585 event->key.window = GTK_WIDGET (GTK_SCROLLED_WINDOW (ptr)->container.child)->window;
586 else
587 event->key.window = GTK_WIDGET (ptr)->window;
589 event->key.send_event = 0;
590 event->key.time = (guint32) when;
592 if (mods & AWT_SHIFT_DOWN_MASK)
593 event->key.state |= GDK_SHIFT_MASK;
594 if (mods & AWT_CTRL_DOWN_MASK)
595 event->key.state |= GDK_CONTROL_MASK;
596 if (mods & AWT_ALT_DOWN_MASK)
597 event->key.state |= GDK_MOD1_MASK;
599 /* This hack is needed because the AWT has no notion of num lock.
600 It infers numlock state from the only Java virtual keys that are
601 affected by it. */
602 if (keyCode == VK_NUMPAD9
603 || keyCode == VK_NUMPAD8
604 || keyCode == VK_NUMPAD7
605 || keyCode == VK_NUMPAD6
606 || keyCode == VK_NUMPAD5
607 || keyCode == VK_NUMPAD4
608 || keyCode == VK_NUMPAD3
609 || keyCode == VK_NUMPAD2
610 || keyCode == VK_NUMPAD1
611 || keyCode == VK_NUMPAD0
612 || keyCode == VK_DECIMAL)
613 event->key.state |= GDK_MOD2_MASK;
615 /* These values don't need to be filled in since GTK doesn't use
616 them. */
617 event->key.length = 0;
618 event->key.string = NULL;
620 lookup_keyval = awt_keycode_to_keysym (keyCode, keyLocation);
622 if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
623 lookup_keyval,
624 &keymap_keys,
625 &n_keys))
627 /* No matching keymap entry was found. */
628 g_printerr ("No matching keymap entries were found\n");
629 gdk_threads_leave ();
630 return;
633 /* Note: if n_keys > 1 then there are multiple hardware keycodes
634 that translate to lookup_keyval. We arbitrarily choose the first
635 hardware keycode from the list returned by
636 gdk_keymap_get_entries_for_keyval. */
638 event->key.hardware_keycode = keymap_keys[0].keycode;
639 event->key.group = keymap_keys[0].group;
641 g_free (keymap_keys);
643 if (!gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
644 event->key.hardware_keycode,
645 event->key.state,
646 event->key.group,
647 &event->key.keyval,
648 NULL, NULL, NULL))
650 /* No matching keyval was found. */
651 g_printerr ("No matching keyval was found\n");
652 gdk_threads_leave ();
653 return;
656 /* keyevent = (GdkEventKey *) event; */
657 /* g_printerr ("generated 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); */
659 /* We already received the original key event on the window itself,
660 so we don't want to resend it. */
661 if (!GTK_IS_WINDOW (ptr))
663 if (GTK_IS_SCROLLED_WINDOW (ptr))
664 gtk_widget_event (GTK_WIDGET (GTK_SCROLLED_WINDOW (ptr)->container.child), event);
665 else
666 gtk_widget_event (GTK_WIDGET (ptr), event);
669 gdk_threads_leave ();
673 * Find the origin of a widget's window.
675 JNIEXPORT void JNICALL
676 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetLocationOnScreen
677 (JNIEnv * env, jobject obj, jintArray jpoint)
679 void *ptr;
680 jint *point;
682 ptr = NSA_GET_PTR (env, obj);
683 point = (*env)->GetIntArrayElements (env, jpoint, 0);
685 gdk_threads_enter ();
687 gdk_window_get_origin (GTK_WIDGET (ptr)->window, point, point+1);
689 if (!GTK_IS_CONTAINER (ptr))
691 *point += GTK_WIDGET(ptr)->allocation.x;
692 *(point+1) += GTK_WIDGET(ptr)->allocation.y;
695 gdk_threads_leave ();
697 (*env)->ReleaseIntArrayElements(env, jpoint, point, 0);
701 * Find this widget's current size.
703 JNIEXPORT void JNICALL
704 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetDimensions
705 (JNIEnv *env, jobject obj, jintArray jdims)
707 void *ptr;
708 jint *dims;
709 GtkRequisition requisition;
711 ptr = NSA_GET_PTR (env, obj);
713 dims = (*env)->GetIntArrayElements (env, jdims, 0);
714 dims[0] = dims[1] = 0;
716 gdk_threads_enter ();
718 gtk_widget_size_request (GTK_WIDGET (ptr), &requisition);
720 dims[0] = requisition.width;
721 dims[1] = requisition.height;
723 gdk_threads_leave ();
725 (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
729 * Find this widget's preferred size.
731 JNIEXPORT void JNICALL
732 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetPreferredDimensions
733 (JNIEnv *env, jobject obj, jintArray jdims)
735 void *ptr;
736 jint *dims;
737 GtkRequisition current_req;
738 GtkRequisition natural_req;
740 ptr = NSA_GET_PTR (env, obj);
742 dims = (*env)->GetIntArrayElements (env, jdims, 0);
743 dims[0] = dims[1] = 0;
745 gdk_threads_enter ();
747 /* Widgets that extend GtkWindow such as GtkFileChooserDialog may have
748 a default size. These values seem more useful then the natural
749 requisition values, particularly for GtkFileChooserDialog. */
750 if (GTK_IS_WINDOW (ptr))
752 gint width, height;
753 gtk_window_get_default_size (GTK_WINDOW (ptr), &width, &height);
755 dims[0] = width;
756 dims[1] = height;
758 else
760 /* Save the widget's current size request. */
761 gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
763 /* Get the widget's "natural" size request. */
764 gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
765 gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
767 /* Reset the widget's size request. */
768 gtk_widget_set_size_request (GTK_WIDGET (ptr),
769 current_req.width, current_req.height);
771 dims[0] = natural_req.width;
772 dims[1] = natural_req.height;
775 gdk_threads_leave ();
777 (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
780 JNIEXPORT void JNICALL
781 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeBounds
782 (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
784 GtkWidget *widget;
785 void *ptr;
787 ptr = NSA_GET_PTR (env, obj);
789 gdk_threads_enter ();
791 widget = GTK_WIDGET (ptr);
793 /* We assume that -1 is a width or height and not a request for the
794 widget's natural size. */
795 width = width < 0 ? 0 : width;
796 height = height < 0 ? 0 : height;
798 if (GTK_IS_VIEWPORT (widget->parent))
799 gtk_widget_set_size_request (widget, width, height);
800 else
802 if (!(width == 0 && height == 0))
804 gtk_widget_set_size_request (widget, width, height);
805 if (widget->parent != NULL)
806 gtk_fixed_move (GTK_FIXED (widget->parent), widget, x, y);
810 gdk_threads_leave ();
813 JNIEXPORT jintArray JNICALL
814 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetBackground
815 (JNIEnv *env, jobject obj)
817 void *ptr;
818 jintArray array;
819 int *rgb;
820 GdkColor bg;
822 ptr = NSA_GET_PTR (env, obj);
824 gdk_threads_enter ();
825 bg = GTK_WIDGET (ptr)->style->bg[GTK_STATE_NORMAL];
826 gdk_threads_leave ();
828 array = (*env)->NewIntArray (env, 3);
829 rgb = (*env)->GetIntArrayElements (env, array, NULL);
830 /* convert color data from 16 bit values down to 8 bit values */
831 rgb[0] = bg.red >> 8;
832 rgb[1] = bg.green >> 8;
833 rgb[2] = bg.blue >> 8;
834 (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
836 return array;
839 JNIEXPORT jintArray JNICALL
840 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetForeground
841 (JNIEnv *env, jobject obj)
843 void *ptr;
844 jintArray array;
845 jint *rgb;
846 GdkColor fg;
848 ptr = NSA_GET_PTR (env, obj);
850 gdk_threads_enter ();
851 fg = GTK_WIDGET (ptr)->style->fg[GTK_STATE_NORMAL];
852 gdk_threads_leave ();
854 array = (*env)->NewIntArray (env, 3);
855 rgb = (*env)->GetIntArrayElements (env, array, NULL);
856 /* convert color data from 16 bit values down to 8 bit values */
857 rgb[0] = fg.red >> 8;
858 rgb[1] = fg.green >> 8;
859 rgb[2] = fg.blue >> 8;
860 (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
862 return array;
865 JNIEXPORT void JNICALL
866 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetBackground
867 (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
869 GdkColor normal_color;
870 GdkColor active_color;
871 GtkWidget *widget;
872 void *ptr;
874 ptr = NSA_GET_PTR (env, obj);
876 normal_color.red = (red / 255.0) * 65535;
877 normal_color.green = (green / 255.0) * 65535;
878 normal_color.blue = (blue / 255.0) * 65535;
880 /* This calculation only approximates the active colors produced by
881 Sun's AWT. */
882 active_color.red = 0.85 * (red / 255.0) * 65535;
883 active_color.green = 0.85 * (green / 255.0) * 65535;
884 active_color.blue = 0.85 * (blue / 255.0) * 65535;
886 gdk_threads_enter ();
888 widget = find_bg_color_widget (GTK_WIDGET (ptr));
890 gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &normal_color);
891 gtk_widget_modify_bg (widget, GTK_STATE_ACTIVE, &active_color);
892 gtk_widget_modify_bg (widget, GTK_STATE_PRELIGHT, &normal_color);
894 gdk_threads_leave ();
897 JNIEXPORT void JNICALL
898 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetForeground
899 (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
901 GdkColor color;
902 GtkWidget *widget;
903 void *ptr;
905 ptr = NSA_GET_PTR (env, obj);
907 color.red = (red / 255.0) * 65535;
908 color.green = (green / 255.0) * 65535;
909 color.blue = (blue / 255.0) * 65535;
911 gdk_threads_enter ();
913 widget = find_fg_color_widget (GTK_WIDGET (ptr));
915 gtk_widget_modify_fg (widget, GTK_STATE_NORMAL, &color);
916 gtk_widget_modify_fg (widget, GTK_STATE_ACTIVE, &color);
917 gtk_widget_modify_fg (widget, GTK_STATE_PRELIGHT, &color);
919 gdk_threads_leave ();
922 JNIEXPORT void JNICALL
923 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_show
924 (JNIEnv *env, jobject obj)
926 void *ptr;
928 ptr = NSA_GET_PTR (env, obj);
930 gdk_threads_enter();
931 gtk_widget_show (GTK_WIDGET (ptr));
932 gdk_threads_leave();
935 JNIEXPORT void JNICALL
936 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_hide
937 (JNIEnv *env, jobject obj)
939 void *ptr;
941 ptr = NSA_GET_PTR (env, obj);
943 gdk_threads_enter();
944 gtk_widget_hide (GTK_WIDGET (ptr));
945 gdk_threads_leave();
948 JNIEXPORT jboolean JNICALL
949 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isEnabled
950 (JNIEnv *env, jobject obj)
952 void *ptr;
953 jboolean ret_val;
955 ptr = NSA_GET_PTR (env, obj);
957 gdk_threads_enter ();
958 ret_val = GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (ptr));
959 gdk_threads_leave ();
961 return ret_val;
964 JNIEXPORT jboolean JNICALL
965 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isRealized
966 (JNIEnv *env, jobject obj)
968 void *ptr;
969 jboolean ret_val;
971 ptr = NSA_GET_PTR (env, obj);
973 if (ptr == NULL)
974 return FALSE;
976 gdk_threads_enter ();
977 ret_val = GTK_WIDGET_REALIZED (GTK_WIDGET (ptr));
978 gdk_threads_leave ();
980 return ret_val;
983 JNIEXPORT jboolean JNICALL
984 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_modalHasGrab
985 (JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)))
987 GtkWidget *widget;
988 jboolean retval;
990 gdk_threads_enter ();
991 widget = gtk_grab_get_current ();
992 retval = (widget && GTK_IS_WINDOW (widget) && GTK_WINDOW (widget)->modal);
993 gdk_threads_leave ();
995 return retval;
998 JNIEXPORT void JNICALL
999 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals
1000 (JNIEnv *env, jobject obj)
1002 void *ptr;
1003 jobject *gref;
1005 ptr = NSA_GET_PTR (env, obj);
1006 gref = NSA_GET_GLOBAL_REF (env, obj);
1008 gdk_threads_enter ();
1010 /* Connect EVENT signal, which happens _before_ any specific signal. */
1012 g_signal_connect (GTK_OBJECT (ptr), "event",
1013 G_CALLBACK (pre_event_handler), *gref);
1015 g_signal_connect (G_OBJECT (ptr), "focus-in-event",
1016 G_CALLBACK (focus_in_cb), *gref);
1018 g_signal_connect (G_OBJECT (ptr), "focus-out-event",
1019 G_CALLBACK (focus_out_cb), *gref);
1021 g_signal_connect_after (G_OBJECT (ptr), "realize",
1022 G_CALLBACK (connect_awt_hook_cb), *gref);
1024 gdk_threads_leave ();
1027 static GtkWidget *
1028 find_fg_color_widget (GtkWidget *widget)
1030 GtkWidget *fg_color_widget;
1032 if (GTK_IS_EVENT_BOX (widget)
1033 || (GTK_IS_BUTTON (widget)
1034 && !GTK_IS_OPTION_MENU (widget)))
1035 fg_color_widget = gtk_bin_get_child (GTK_BIN(widget));
1036 else
1037 fg_color_widget = widget;
1039 return fg_color_widget;
1042 static GtkWidget *
1043 find_bg_color_widget (GtkWidget *widget)
1045 GtkWidget *bg_color_widget;
1047 bg_color_widget = widget;
1049 return bg_color_widget;
1052 static gboolean
1053 focus_in_cb (GtkWidget *widget __attribute((unused)),
1054 GdkEventFocus *event __attribute((unused)),
1055 jobject peer)
1057 gdk_threads_leave ();
1058 (*gdk_env())->CallVoidMethod (gdk_env(), peer,
1059 postFocusEventID,
1060 AWT_FOCUS_GAINED,
1061 JNI_FALSE);
1062 gdk_threads_enter ();
1063 return FALSE;
1066 static gboolean
1067 focus_out_cb (GtkWidget *widget __attribute((unused)),
1068 GdkEventFocus *event __attribute((unused)),
1069 jobject peer)
1071 gdk_threads_leave ();
1072 (*gdk_env())->CallVoidMethod (gdk_env(), peer,
1073 postFocusEventID,
1074 AWT_FOCUS_LOST,
1075 JNI_FALSE);
1076 gdk_threads_enter ();
1077 return FALSE;