]>
Commit | Line | Data |
---|---|---|
5aac1dac | 1 | /* gtkcomponentpeer.c -- Native implementation of GtkComponentPeer |
2635995a | 2 | Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc. |
5aac1dac TT |
3 | |
4 | This file is part of GNU Classpath. | |
5 | ||
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. | |
10 | ||
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. | |
15 | ||
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. | |
20 | ||
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. | |
25 | ||
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. */ | |
37 | ||
38 | ||
39 | #include "gtkpeer.h" | |
40 | #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h" | |
41 | #include <gtk/gtkprivate.h> | |
42 | ||
009ed5cc TF |
43 | static GtkWidget *find_fg_color_widget (GtkWidget *widget); |
44 | static GtkWidget *find_bg_color_widget (GtkWidget *widget); | |
45 | ||
5aac1dac TT |
46 | |
47 | JNIEXPORT void JNICALL | |
48 | Java_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 | */ | |
117 | JNIEXPORT void JNICALL | |
118 | Java_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 | */ |
145 | JNIEXPORT void JNICALL | |
146 | Java_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 | */ | |
173 | JNIEXPORT void JNICALL | |
174 | Java_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), ¤t_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 |
208 | JNIEXPORT 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 | ||
232 | JNIEXPORT jintArray JNICALL | |
233 | Java_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 | ||
258 | JNIEXPORT jintArray JNICALL | |
259 | Java_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 |
284 | JNIEXPORT void JNICALL |
285 | Java_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 | ||
316 | JNIEXPORT void JNICALL | |
317 | Java_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 |
341 | JNIEXPORT void JNICALL |
342 | Java_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 |
373 | void |
374 | set_visible (GtkWidget *widget, jboolean visible) | |
375 | { | |
376 | if (visible) | |
377 | gtk_widget_show (widget); | |
378 | else | |
379 | gtk_widget_hide (widget); | |
380 | } | |
381 | ||
382 | GtkLayout * | |
383 | find_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 | ||
401 | void | |
402 | set_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 | ||
438 | JNIEXPORT jboolean JNICALL | |
439 | Java_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 | ||
454 | JNIEXPORT jboolean JNICALL | |
455 | Java_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 | ||
469 | JNIEXPORT void JNICALL | |
470 | Java_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 | ||
489 | JNIEXPORT 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 | ||
506 | JNIEXPORT 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 | ||
522 | JNIEXPORT 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 | ||
538 | JNIEXPORT void JNICALL | |
539 | Java_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 |
568 | gboolean |
569 | filter_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 | ||
591 | JNIEXPORT 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 | ||
635 | JNIEXPORT 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 | ||
679 | JNIEXPORT 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 | 700 | JNIEXPORT 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 | ||
716 | JNIEXPORT 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 | |
741 | static GtkWidget * | |
742 | find_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 | ||
754 | static GtkWidget * | |
755 | find_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 |