]> git.ipfire.org Git - thirdparty/gcc.git/blame - libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c, [...]: New files.
[thirdparty/gcc.git] / libjava / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkComponentPeer.c
CommitLineData
5aac1dac 1/* gtkcomponentpeer.c -- Native implementation of GtkComponentPeer
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 "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
41#include <gtk/gtkprivate.h>
42
009ed5cc
TF
43static GtkWidget *find_fg_color_widget (GtkWidget *widget);
44static GtkWidget *find_bg_color_widget (GtkWidget *widget);
45
5aac1dac
TT
46
47JNIEXPORT void JNICALL
48Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursor
49 (JNIEnv *env, jobject obj, jint type)
50{
51 void *ptr;
52 GtkWidget *widget;
53 GdkCursorType gdk_cursor_type;
54 GdkCursor *gdk_cursor;
55
56 ptr = NSA_GET_PTR (env, obj);
57
58 switch (type)
59 {
60 case AWT_CROSSHAIR_CURSOR:
61 gdk_cursor_type = GDK_CROSSHAIR;
62 break;
63 case AWT_TEXT_CURSOR:
64 gdk_cursor_type = GDK_XTERM;
65 break;
66 case AWT_WAIT_CURSOR:
67 gdk_cursor_type = GDK_WATCH;
68 break;
69 case AWT_SW_RESIZE_CURSOR:
70 gdk_cursor_type = GDK_BOTTOM_LEFT_CORNER;
71 break;
72 case AWT_SE_RESIZE_CURSOR:
73 gdk_cursor_type = GDK_BOTTOM_RIGHT_CORNER;
74 break;
75 case AWT_NW_RESIZE_CURSOR:
76 gdk_cursor_type = GDK_TOP_LEFT_CORNER;
77 break;
78 case AWT_NE_RESIZE_CURSOR:
79 gdk_cursor_type = GDK_TOP_RIGHT_CORNER;
80 break;
81 case AWT_N_RESIZE_CURSOR:
82 gdk_cursor_type = GDK_TOP_SIDE;
83 break;
84 case AWT_S_RESIZE_CURSOR:
85 gdk_cursor_type = GDK_BOTTOM_SIDE;
86 break;
87 case AWT_W_RESIZE_CURSOR:
88 gdk_cursor_type = GDK_LEFT_SIDE;
89 break;
90 case AWT_E_RESIZE_CURSOR:
91 gdk_cursor_type = GDK_RIGHT_SIDE;
92 break;
93 case AWT_HAND_CURSOR:
94 gdk_cursor_type = GDK_HAND2;
95 break;
96 case AWT_MOVE_CURSOR:
97 gdk_cursor_type = GDK_FLEUR;
98 break;
99 default:
100 gdk_cursor_type = GDK_LEFT_PTR;
101 }
102
103 gdk_threads_enter ();
104
105 widget = GTK_WIDGET(ptr);
106
107 gdk_cursor = gdk_cursor_new (gdk_cursor_type);
108 gdk_window_set_cursor (widget->window, gdk_cursor);
109 gdk_cursor_destroy (gdk_cursor);
110
111 gdk_threads_leave ();
112}
113
5aac1dac
TT
114/*
115 * Find the origin of a widget's window.
116 */
117JNIEXPORT void JNICALL
118Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetLocationOnScreen
119 (JNIEnv * env, jobject obj, jintArray jpoint)
120{
121 void *ptr;
122 jint *point;
123
124 ptr = NSA_GET_PTR (env, obj);
125 point = (*env)->GetIntArrayElements (env, jpoint, 0);
126
127 gdk_threads_enter ();
b59b5081 128
5aac1dac 129 gdk_window_get_origin (GTK_WIDGET (ptr)->window, point, point+1);
b59b5081
TF
130
131 if (!GTK_IS_CONTAINER (ptr))
132 {
133 *point += GTK_WIDGET(ptr)->allocation.x;
134 *(point+1) += GTK_WIDGET(ptr)->allocation.y;
135 }
136
5aac1dac
TT
137 gdk_threads_leave ();
138
139 (*env)->ReleaseIntArrayElements(env, jpoint, point, 0);
140}
141
142/*
b17fc9eb 143 * Find this widget's current size.
5aac1dac
TT
144 */
145JNIEXPORT void JNICALL
146Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetDimensions
b17fc9eb 147 (JNIEnv *env, jobject obj, jintArray jdims)
5aac1dac 148{
b17fc9eb
TF
149 void *ptr;
150 jint *dims;
151 GtkRequisition requisition;
152
153 ptr = NSA_GET_PTR (env, obj);
154
155 dims = (*env)->GetIntArrayElements (env, jdims, 0);
156 dims[0] = dims[1] = 0;
157
158 gdk_threads_enter ();
159
160 gtk_widget_size_request (GTK_WIDGET (ptr), &requisition);
161
162 dims[0] = requisition.width;
163 dims[1] = requisition.height;
164
165 gdk_threads_leave ();
166
167 (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
168}
5aac1dac 169
b17fc9eb
TF
170/*
171 * Find this widget's preferred size.
172 */
173JNIEXPORT void JNICALL
174Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetPreferredDimensions
175 (JNIEnv *env, jobject obj, jintArray jdims)
176{
177 void *ptr;
178 jint *dims;
179 GtkRequisition current_req;
180 GtkRequisition natural_req;
181
182 ptr = NSA_GET_PTR (env, obj);
183
184 dims = (*env)->GetIntArrayElements (env, jdims, 0);
185 dims[0] = dims[1] = 0;
186
187 gdk_threads_enter ();
188
189 /* Save the widget's current size request. */
190 gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
5aac1dac 191
b17fc9eb
TF
192 /* Get the widget's "natural" size request. */
193 gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
194 gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
5aac1dac 195
b17fc9eb
TF
196 /* Reset the widget's size request. */
197 gtk_widget_set_size_request (GTK_WIDGET (ptr),
198 current_req.width, current_req.height);
5aac1dac 199
b17fc9eb
TF
200 dims[0] = natural_req.width;
201 dims[1] = natural_req.height;
5aac1dac 202
b17fc9eb 203 gdk_threads_leave ();
5aac1dac 204
b17fc9eb 205 (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
5aac1dac
TT
206}
207
5aac1dac
TT
208JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeBounds
209 (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
210{
211 GtkWidget *widget;
212 void *ptr;
213
214 ptr = NSA_GET_PTR (env, obj);
215
216 gdk_threads_enter ();
217
218 widget = GTK_WIDGET (ptr);
219 if (GTK_IS_VIEWPORT (widget->parent))
220 {
86881a7b 221 gtk_widget_set_size_request (widget, width, height);
5aac1dac
TT
222 }
223 else
224 {
86881a7b 225 gtk_widget_set_size_request (widget, width, height);
5aac1dac
TT
226 gtk_layout_move (GTK_LAYOUT (widget->parent), widget, x, y);
227 }
228
229 gdk_threads_leave ();
230}
231
232JNIEXPORT jintArray JNICALL
233Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetBackground
234 (JNIEnv *env, jobject obj)
235{
236 void *ptr;
237 jintArray array;
238 int *rgb;
239 GdkColor bg;
240
241 ptr = NSA_GET_PTR (env, obj);
242
243 gdk_threads_enter ();
244 bg = GTK_WIDGET (ptr)->style->bg[GTK_STATE_NORMAL];
245 gdk_threads_leave ();
246
247 array = (*env)->NewIntArray (env, 3);
248 rgb = (*env)->GetIntArrayElements (env, array, NULL);
249 /* convert color data from 16 bit values down to 8 bit values */
250 rgb[0] = bg.red >> 8;
251 rgb[1] = bg.green >> 8;
252 rgb[2] = bg.blue >> 8;
253 (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
254
255 return array;
256}
257
258JNIEXPORT jintArray JNICALL
259Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetForeground
260 (JNIEnv *env, jobject obj)
261{
262 void *ptr;
263 jintArray array;
264 jint *rgb;
265 GdkColor fg;
266
267 ptr = NSA_GET_PTR (env, obj);
268
269 gdk_threads_enter ();
270 fg = GTK_WIDGET (ptr)->style->fg[GTK_STATE_NORMAL];
271 gdk_threads_leave ();
272
273 array = (*env)->NewIntArray (env, 3);
274 rgb = (*env)->GetIntArrayElements (env, array, NULL);
275 /* convert color data from 16 bit values down to 8 bit values */
276 rgb[0] = fg.red >> 8;
277 rgb[1] = fg.green >> 8;
278 rgb[2] = fg.blue >> 8;
279 (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
280
281 return array;
282}
283
a5586c38
TF
284JNIEXPORT void JNICALL
285Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetBackground
286 (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
287{
288 GdkColor normal_color;
289 GdkColor active_color;
290 GtkWidget *widget;
291 void *ptr;
292
293 ptr = NSA_GET_PTR (env, obj);
294
295 normal_color.red = (red / 255.0) * 65535;
296 normal_color.green = (green / 255.0) * 65535;
297 normal_color.blue = (blue / 255.0) * 65535;
298
299 /* This calculation only approximates the active colors produced by
300 Sun's AWT. */
301 active_color.red = 0.85 * (red / 255.0) * 65535;
302 active_color.green = 0.85 * (green / 255.0) * 65535;
303 active_color.blue = 0.85 * (blue / 255.0) * 65535;
304
305 gdk_threads_enter ();
306
009ed5cc 307 widget = find_bg_color_widget (GTK_WIDGET (ptr));
a5586c38
TF
308
309 gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &normal_color);
310 gtk_widget_modify_bg (widget, GTK_STATE_ACTIVE, &active_color);
311 gtk_widget_modify_bg (widget, GTK_STATE_PRELIGHT, &normal_color);
312
313 gdk_threads_leave ();
314}
315
316JNIEXPORT void JNICALL
317Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetForeground
318 (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
319{
320 GdkColor color;
321 GtkWidget *widget;
322 void *ptr;
323
324 ptr = NSA_GET_PTR (env, obj);
325
326 color.red = (red / 255.0) * 65535;
327 color.green = (green / 255.0) * 65535;
328 color.blue = (blue / 255.0) * 65535;
329
330 gdk_threads_enter ();
331
009ed5cc 332 widget = find_fg_color_widget (GTK_WIDGET (ptr));
a5586c38
TF
333
334 gtk_widget_modify_fg (widget, GTK_STATE_NORMAL, &color);
009ed5cc
TF
335 gtk_widget_modify_fg (widget, GTK_STATE_ACTIVE, &color);
336 gtk_widget_modify_fg (widget, GTK_STATE_PRELIGHT, &color);
a5586c38
TF
337
338 gdk_threads_leave ();
339}
340
86881a7b
GH
341JNIEXPORT void JNICALL
342Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkSetFont
343 (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
344{
345 const char *font_name;
346 void *ptr;
86881a7b
GH
347 PangoFontDescription *font_desc;
348
349 ptr = NSA_GET_PTR (env, obj);
350
351 font_name = (*env)->GetStringUTFChars (env, name, NULL);
352
353 gdk_threads_enter();
354
355 font_desc = pango_font_description_from_string (font_name);
356 pango_font_description_set_size (font_desc, size * PANGO_SCALE);
357
358 if (style & AWT_STYLE_BOLD)
359 pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
360
361 if (style & AWT_STYLE_ITALIC)
362 pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
363
364 gtk_widget_modify_font (GTK_WIDGET(ptr), font_desc);
365
366 pango_font_description_free (font_desc);
367
368 gdk_threads_leave();
369
370 (*env)->ReleaseStringUTFChars (env, name, font_name);
371}
372
5aac1dac
TT
373void
374set_visible (GtkWidget *widget, jboolean visible)
375{
376 if (visible)
377 gtk_widget_show (widget);
378 else
379 gtk_widget_hide (widget);
380}
381
382GtkLayout *
383find_gtk_layout (GtkWidget *parent)
384{
385 if (GTK_IS_WINDOW (parent))
386 {
387 GList *children = gtk_container_children
388 (GTK_CONTAINER (GTK_BIN (parent)->child));
389
390 if (GTK_IS_MENU_BAR (children->data))
391 return GTK_LAYOUT (children->next->data);
392 else /* GTK_IS_LAYOUT (children->data) */
393 return GTK_LAYOUT (children->data);
394 }
395
396 return NULL;
397}
398
399#define WIDGET_CLASS(w) GTK_WIDGET_CLASS (GTK_OBJECT (w)->klass)
400
401void
402set_parent (GtkWidget *widget, GtkContainer *parent)
403{
404 if (GTK_IS_WINDOW (parent))
405 {
406 GList *children = gtk_container_children
407 (GTK_CONTAINER (GTK_BIN (parent)->child));
408
409 if (GTK_IS_MENU_BAR (children->data))
410 gtk_layout_put (GTK_LAYOUT (children->next->data), widget, 0, 0);
411 else /* GTK_IS_LAYOUT (children->data) */
412 gtk_layout_put (GTK_LAYOUT (children->data), widget, 0, 0);
413 }
414 else
415 if (GTK_IS_SCROLLED_WINDOW (parent))
416 {
417/* if (WIDGET_CLASS (widget)->set_scroll_adjustments_signal) */
418/* gtk_container_add (GTK_CONTAINER (parent), widget); */
419/* else */
420/* { */
421 gtk_scrolled_window_add_with_viewport
422 (GTK_SCROLLED_WINDOW (parent), widget);
423 gtk_viewport_set_shadow_type (GTK_VIEWPORT (widget->parent),
424 GTK_SHADOW_NONE);
425/* } */
426
427 }
428/* gtk_layout_put */
429/* (GTK_LAYOUT (GTK_BIN (parent)->child), widget, 0, 0); */
430
431/* if (GTK_IS_SCROLLED_WINDOW (parent)) */
432/* gtk_layout_put */
433/* (GTK_LAYOUT (GTK_BIN (GTK_BIN (parent)->child)->child), widget, 0, 0); */
434 else
435 gtk_layout_put (GTK_LAYOUT (parent), widget, 0, 0);
436}
437
438JNIEXPORT jboolean JNICALL
439Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isEnabled
440 (JNIEnv *env, jobject obj)
441{
442 void *ptr;
443 jboolean ret_val;
444
445 ptr = NSA_GET_PTR (env, obj);
446
447 gdk_threads_enter ();
448 ret_val = GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (ptr));
449 gdk_threads_leave ();
450
451 return ret_val;
452}
453
454JNIEXPORT jboolean JNICALL
455Java_gnu_java_awt_peer_gtk_GtkComponentPeer_modalHasGrab
ce7a72c8 456 (JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)))
5aac1dac
TT
457{
458 GtkWidget *widget;
459 jboolean retval;
460
461 gdk_threads_enter ();
462 widget = gtk_grab_get_current ();
463 retval = (widget && GTK_IS_WINDOW (widget) && GTK_WINDOW (widget)->modal);
464 gdk_threads_leave ();
465
466 return retval;
467}
468
469JNIEXPORT void JNICALL
470Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Ljava_lang_String_2
471 (JNIEnv *env, jobject obj, jstring jname, jstring jvalue)
472{
473 const char *name;
474 const char *value;
475 void *ptr;
5aac1dac
TT
476
477 ptr = NSA_GET_PTR (env, obj);
478 name = (*env)->GetStringUTFChars (env, jname, NULL);
479 value = (*env)->GetStringUTFChars (env, jvalue, NULL);
480
d0b8b6fb 481 gdk_threads_enter();
29e531ff
TF
482 g_object_set(ptr, name, value, NULL);
483 gdk_threads_leave();
5aac1dac
TT
484
485 (*env)->ReleaseStringUTFChars (env, jname, name);
486 (*env)->ReleaseStringUTFChars (env, jvalue, value);
487}
488
489JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Z
b59b5081 490 (JNIEnv *env, jobject obj, jstring jname, jboolean value)
5aac1dac
TT
491{
492 const char *name;
493 void *ptr;
5aac1dac
TT
494
495 ptr = NSA_GET_PTR (env, obj);
5aac1dac 496
5ec47f60 497 name = (*env)->GetStringUTFChars (env, jname, NULL);
5aac1dac 498
5ec47f60 499 gdk_threads_enter();
29e531ff
TF
500 g_object_set(ptr, name, value, NULL);
501 gdk_threads_leave();
5aac1dac
TT
502
503 (*env)->ReleaseStringUTFChars (env, jname, name);
504}
505
506JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2I
507 (JNIEnv *env, jobject obj, jstring jname, jint value)
508{
509 const char *name;
510 void *ptr;
5aac1dac
TT
511
512 ptr = NSA_GET_PTR (env, obj);
513 name = (*env)->GetStringUTFChars (env, jname, NULL);
514
29e531ff
TF
515 gdk_threads_enter();
516 g_object_set(ptr, name, value, NULL);
517 gdk_threads_leave();
5aac1dac
TT
518
519 (*env)->ReleaseStringUTFChars (env, jname, name);
520}
521
522JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2F
523 (JNIEnv *env, jobject obj, jstring jname, jfloat value)
524{
525 const char *name;
526 void *ptr;
5aac1dac
TT
527
528 ptr = NSA_GET_PTR (env, obj);
529 name = (*env)->GetStringUTFChars (env, jname, NULL);
530
29e531ff
TF
531 gdk_threads_enter();
532 g_object_set(ptr, name, value, NULL);
533 gdk_threads_leave();
5aac1dac
TT
534
535 (*env)->ReleaseStringUTFChars (env, jname, name);
536}
537
538JNIEXPORT void JNICALL
539Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Ljava_lang_Object_2
540 (JNIEnv *env, jobject obj1, jstring jname, jobject obj2)
541{
542 const char *name;
543 void *ptr1, *ptr2;
5aac1dac
TT
544
545 ptr1 = NSA_GET_PTR (env, obj1);
546 ptr2 = NSA_GET_PTR (env, obj2);
547
548 name = (*env)->GetStringUTFChars (env, jname, NULL);
549
550 /* special case to catch where we need to set the parent */
551 if (!strcmp (name, "parent"))
552 {
553 gdk_threads_enter ();
554 set_parent (GTK_WIDGET (ptr1), GTK_CONTAINER (ptr2));
555 gdk_threads_leave ();
556
557 (*env)->ReleaseStringUTFChars (env, jname, name);
558 return;
559 }
560
29e531ff
TF
561 gdk_threads_enter();
562 g_object_set(ptr1, name, ptr2, NULL);
563 gdk_threads_leave();
5aac1dac
TT
564
565 (*env)->ReleaseStringUTFChars (env, jname, name);
566}
567
7edbd87e
DJ
568gboolean
569filter_expose_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
570{
2635995a
MW
571 /*
572 * Prevent the default event handler from getting this signal if applicable
573 * FIXME: I came up with these filters by looking for patterns in the unwanted
574 * expose events that are fed back to us from gtk/X. Perhaps there is
575 * a way to prevent them from occuring in the first place.
576 */
7edbd87e
DJ
577 if (event->type == GDK_EXPOSE && (!GTK_IS_LAYOUT(widget)
578 || event->any.window != widget->window))
579 {
580 g_signal_stop_emission_by_name(GTK_OBJECT(widget), "event");
581 return FALSE;
582 }
583 else
584 {
2635995a
MW
585 /* There may be non-expose events that are triggered while we're
586 painting a heavyweight peer. */
7edbd87e
DJ
587 return pre_event_handler(widget, event, peer);
588 }
589}
590
591JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_addExposeFilter
592 (JNIEnv *env, jobject obj)
593{
f2919ef3
DJ
594 GtkObject *filterobj;
595 GtkWidget *vbox, *layout;
596 GList *children;
31e632d3
GH
597 void *ptr = NSA_GET_PTR (env, obj);
598 jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
599
600 g_assert (gref);
7edbd87e
DJ
601
602 gdk_threads_enter ();
603
2635995a
MW
604 /* GtkFramePeer is built as a GtkLayout inside a GtkVBox inside a GtkWindow.
605 Events go to the GtkLayout layer, so we filter them there. */
f2919ef3
DJ
606 if (GTK_IS_WINDOW(ptr))
607 {
608 children = gtk_container_get_children(GTK_CONTAINER(ptr));
609 vbox = children->data;
610 g_assert (GTK_IS_VBOX(vbox));
611
612 children = gtk_container_get_children(GTK_CONTAINER(vbox));
613 do
614 {
615 layout = children->data;
616 children = children->next;
617 }
618 while (!GTK_IS_LAYOUT (layout) && children != NULL);
619 g_assert (GTK_IS_LAYOUT(layout));
620
621 filterobj = GTK_OBJECT(layout);
622 }
623 else
624 {
625 filterobj = GTK_OBJECT(ptr);
626 }
627
628 g_signal_handlers_block_by_func (filterobj, *pre_event_handler, *gref);
629 g_signal_connect( filterobj, "event",
7edbd87e
DJ
630 G_CALLBACK(filter_expose_event_handler), *gref);
631
632 gdk_threads_leave ();
633}
634
635JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_removeExposeFilter
636 (JNIEnv *env, jobject obj)
637{
f2919ef3
DJ
638 GtkObject *filterobj;
639 GtkWidget *vbox, *layout;
640 GList *children;
31e632d3
GH
641 void *ptr = NSA_GET_PTR (env, obj);
642 jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
643
644 g_assert (gref);
7edbd87e
DJ
645
646 gdk_threads_enter ();
647
2635995a
MW
648 /* GtkFramePeer is built as a GtkLayout inside a GtkVBox inside a GtkWindow.
649 Events go to the GtkLayout layer, so we filter them there. */
f2919ef3
DJ
650 if (GTK_IS_WINDOW(ptr))
651 {
652 children = gtk_container_get_children(GTK_CONTAINER(ptr));
653 vbox = children->data;
654 g_assert (GTK_IS_VBOX(vbox));
655
656 children = gtk_container_get_children(GTK_CONTAINER(vbox));
657 do
658 {
659 layout = children->data;
660 children = children->next;
661 }
662 while (!GTK_IS_LAYOUT (layout) && children != NULL);
663 g_assert (GTK_IS_LAYOUT(layout));
664
665 filterobj = GTK_OBJECT(layout);
666 }
667 else
668 {
669 filterobj = GTK_OBJECT(ptr);
670 }
671
672 g_signal_handlers_disconnect_by_func (filterobj,
7edbd87e 673 *filter_expose_event_handler, *gref);
f2919ef3 674 g_signal_handlers_unblock_by_func (filterobj, *pre_event_handler, *gref);
7edbd87e
DJ
675
676 gdk_threads_leave ();
677}
678
679JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetQueueDrawArea
680 (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
681{
682 GdkRectangle rect;
683 void *ptr;
684
685 ptr = NSA_GET_PTR (env, obj);
686
687 rect.x = x + GTK_WIDGET(ptr)->allocation.x;
688 rect.y = y + GTK_WIDGET(ptr)->allocation.y;
689 rect.width = width;
690 rect.height = height;
691
692 gdk_threads_enter ();
693
694 gdk_window_invalidate_rect (GTK_WIDGET (ptr)->window, &rect, 0);
695 gdk_window_process_all_updates();
696
697 gdk_threads_leave ();
698}
699
834b1209 700JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectJObject
5aac1dac
TT
701 (JNIEnv *env, jobject obj)
702{
703 void *ptr;
704
705 ptr = NSA_GET_PTR (env, obj);
706
707 gdk_threads_enter ();
834b1209 708
5aac1dac 709 gtk_widget_realize (GTK_WIDGET (ptr));
d0b8b6fb 710
834b1209
FN
711 connect_awt_hook (env, obj, 1, GTK_WIDGET (ptr)->window);
712
713 gdk_threads_leave ();
714}
715
716JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals
7ecd4576 717 (JNIEnv *env, jobject obj)
834b1209 718{
7ecd4576
FN
719 void *ptr = NSA_GET_PTR (env, obj);
720 jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
721 g_assert (gref);
834b1209
FN
722
723 gdk_threads_enter ();
724
725 gtk_widget_realize (GTK_WIDGET (ptr));
726
727 /* FIXME: We could check here if this is a scrolled window with a
728 single child that does not have an associated jobject. This
729 means that it is one of our wrapped widgets like List or TextArea
730 and thus we could connect the signal to the child without having
731 to specialize this method. */
732
733 /* Connect EVENT signal, which happens _before_ any specific signal. */
734
735 g_signal_connect (GTK_OBJECT (ptr), "event",
7ecd4576 736 G_CALLBACK (pre_event_handler), *gref);
834b1209 737
5aac1dac
TT
738 gdk_threads_leave ();
739}
009ed5cc
TF
740
741static GtkWidget *
742find_fg_color_widget (GtkWidget *widget)
743{
744 GtkWidget *fg_color_widget;
745
81a88a61 746 if (GTK_IS_EVENT_BOX (widget) || GTK_IS_BUTTON (widget))
009ed5cc
TF
747 fg_color_widget = gtk_bin_get_child (GTK_BIN(widget));
748 else
749 fg_color_widget = widget;
750
751 return fg_color_widget;
752}
753
754static GtkWidget *
755find_bg_color_widget (GtkWidget *widget)
756{
757 GtkWidget *bg_color_widget;
758
759 if (GTK_IS_WINDOW (widget))
760 {
761 GtkWidget *vbox;
762 GList* children;
763
764 children = gtk_container_get_children(GTK_CONTAINER(widget));
765 vbox = children->data;
766
767 children = gtk_container_get_children(GTK_CONTAINER(vbox));
768 bg_color_widget = children->data;
769 }
770 else
771 bg_color_widget = widget;
772
773 return bg_color_widget;
774}
775