2 Copyright (C) 1999 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)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
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
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. */
40 #include "gnu_java_awt_peer_gtk_GdkGraphics.h"
41 #include <gdk/gdkprivate.h>
44 static jmethodID initComponentGraphicsUnlockedID
;
47 cp_gtk_graphics_init_jni (void)
51 gdkgraphics
= (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
52 "gnu/java/awt/peer/gtk/GdkGraphics");
54 initComponentGraphicsUnlockedID
=
55 (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics
,
56 "initComponentGraphicsUnlocked",
60 struct state_table
*cp_gtk_native_graphics_state_table
;
62 static struct state_table
*native_graphics_global_ref_table
;
64 #define NSA_GLOBAL_G_INIT(env, clazz) \
65 native_graphics_global_ref_table = cp_gtk_init_state_table (env, clazz)
67 #define NSA_GET_GLOBAL_G_REF(env, obj) \
68 cp_gtk_get_state (env, obj, native_graphics_global_ref_table)
70 #define NSA_SET_GLOBAL_G_REF(env, obj) \
71 do {jobject *globRefPtr; \
72 globRefPtr = (jobject *) malloc (sizeof (jobject)); \
73 *globRefPtr = (*env)->NewGlobalRef (env, obj); \
74 cp_gtk_set_state (env, obj, native_graphics_global_ref_table, (void *)globRefPtr);} while (0)
76 #define NSA_DEL_GLOBAL_G_REF(env, obj) \
77 do {jobject *globRefPtr = cp_gtk_get_state (env, obj, native_graphics_global_ref_table); \
78 cp_gtk_remove_state_slot (env, obj, native_graphics_global_ref_table); \
79 (*env)->DeleteGlobalRef (env, *globRefPtr); \
80 free (globRefPtr);} while (0)
82 JNIEXPORT
void JNICALL
83 Java_gnu_java_awt_peer_gtk_GdkGraphics_initStaticState
84 (JNIEnv
*env
, jclass clazz
)
88 NSA_G_INIT (env
, clazz
);
89 NSA_GLOBAL_G_INIT (env
, clazz
);
94 #define GDK_STABLE_IS_PIXMAP(d) (GDK_IS_PIXMAP(d))
96 static GdkPoint
*translate_points (JNIEnv
*env
, jintArray xpoints
,
97 jintArray ypoints
, jint npoints
,
98 jint x_offset
, jint y_offset
);
99 static void realize_cb (GtkWidget
*widget
, jobject jgraphics
);
101 JNIEXPORT
void JNICALL
102 Java_gnu_java_awt_peer_gtk_GdkGraphics_nativeCopyState
103 (JNIEnv
*env
, jobject obj
, jobject old
)
105 struct graphics
*g
= NULL
;
106 struct graphics
*g_old
= NULL
;
108 gdk_threads_enter ();
110 g
= (struct graphics
*) g_malloc (sizeof (struct graphics
));
111 g_old
= (struct graphics
*) NSA_GET_G_PTR (env
, old
);
115 g
->gc
= gdk_gc_new (g
->drawable
);
116 gdk_gc_copy (g
->gc
, g_old
->gc
);
118 if (GDK_STABLE_IS_PIXMAP (g
->drawable
))
119 g_object_ref (g
->drawable
);
120 else /* GDK_IS_WINDOW (g->drawable) */
121 g_object_ref (g
->drawable
);
123 g_object_ref (g
->cm
);
125 NSA_SET_G_PTR (env
, obj
, g
);
127 gdk_threads_leave ();
130 JNIEXPORT
void JNICALL
131 Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II
132 (JNIEnv
*env
, jobject obj
, jint width
, jint height
)
134 struct graphics
*g
= NULL
;
136 gdk_threads_enter ();
138 g
= (struct graphics
*) g_malloc (sizeof (struct graphics
));
139 g
->x_offset
= g
->y_offset
= 0;
141 g
->drawable
= (GdkDrawable
*) gdk_pixmap_new (NULL
, width
, height
,
142 gdk_rgb_get_visual ()->depth
);
143 g
->cm
= gdk_rgb_get_colormap ();
144 g_object_ref (g
->cm
);
145 g
->gc
= gdk_gc_new (g
->drawable
);
147 NSA_SET_G_PTR (env
, obj
, g
);
149 gdk_threads_leave ();
152 JNIEXPORT
void JNICALL
153 Java_gnu_java_awt_peer_gtk_GdkGraphics_initFromImage
154 (JNIEnv
*env
, jobject obj
, jobject source
)
156 struct graphics
*g
= NULL
;
157 GdkPixmap
*pixmap
= NULL
;
159 gdk_threads_enter ();
161 pixmap
= cp_gtk_image_get_pixmap (env
, source
);
162 g_assert(pixmap
!= NULL
);
163 g_object_ref (pixmap
);
165 g
= (struct graphics
*) g_malloc (sizeof (struct graphics
));
166 g
->x_offset
= g
->y_offset
= 0;
168 g
->drawable
= (GdkDrawable
*)pixmap
;
170 g
->cm
= gdk_drawable_get_colormap (g
->drawable
);
171 g_object_ref (g
->cm
);
172 g
->gc
= gdk_gc_new (g
->drawable
);
174 NSA_SET_G_PTR (env
, obj
, g
);
176 gdk_threads_leave ();
179 JNIEXPORT
void JNICALL
180 Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked
181 (JNIEnv
*env
, jobject obj
, jobject peer
)
183 struct graphics
*g
= NULL
;
185 GtkWidget
*widget
= NULL
;
188 g
= (struct graphics
*) g_malloc (sizeof (struct graphics
));
189 ptr
= NSA_GET_PTR (env
, peer
);
193 widget
= GTK_WIDGET (ptr
);
194 g
->drawable
= (GdkDrawable
*) widget
->window
;
196 g_object_ref (g
->drawable
);
197 g
->cm
= gtk_widget_get_colormap (widget
);
198 g_object_ref (g
->cm
);
199 g
->gc
= gdk_gc_new (g
->drawable
);
200 gdk_gc_copy (g
->gc
, widget
->style
->fg_gc
[GTK_STATE_NORMAL
]);
201 color
= widget
->style
->fg
[GTK_STATE_NORMAL
];
203 NSA_SET_G_PTR (env
, obj
, g
);
206 /* copy the native state of the peer (GtkWidget *) to the native state
207 of the graphics object */
208 JNIEXPORT
void JNICALL
209 Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
210 (JNIEnv
*env
, jobject obj
, jobject peer
)
212 gdk_threads_enter ();
213 Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked
215 gdk_threads_leave ();
218 JNIEXPORT
void JNICALL
219 Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals
220 (JNIEnv
*env
, jobject obj
, jobject peer
)
223 jobject
*gref
= NULL
;
225 gdk_threads_enter ();
227 NSA_SET_GLOBAL_G_REF (env
, obj
);
228 gref
= NSA_GET_GLOBAL_G_REF (env
, obj
);
230 ptr
= NSA_GET_PTR (env
, peer
);
232 g_signal_connect_after (G_OBJECT (ptr
), "realize",
233 G_CALLBACK (realize_cb
), *gref
);
235 gdk_threads_leave ();
238 JNIEXPORT
void JNICALL
239 Java_gnu_java_awt_peer_gtk_GdkGraphics_nativeDispose
240 (JNIEnv
*env
, jobject obj
)
242 struct graphics
*g
= NULL
;
244 gdk_threads_enter ();
246 g
= (struct graphics
*) NSA_DEL_G_PTR (env
, obj
);
248 /* check if dispose has been called already */
251 gdk_threads_leave ();
255 XFlush (GDK_DISPLAY ());
257 g_object_unref (g
->gc
);
259 if (GDK_STABLE_IS_PIXMAP (g
->drawable
))
260 g_object_unref (g
->drawable
);
261 else /* GDK_IS_WINDOW (g->drawable) */
262 g_object_unref (g
->drawable
);
264 g_object_unref (g
->cm
);
268 gdk_threads_leave ();
271 JNIEXPORT
void JNICALL
272 Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative
273 (JNIEnv
*env
, jobject obj
, jint x
, jint y
)
275 struct graphics
*g
= NULL
;
277 gdk_threads_enter ();
279 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
284 gdk_threads_leave ();
287 JNIEXPORT
void JNICALL
288 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString
289 (JNIEnv
*env
, jobject obj
, jobject font
, jstring str
, jint x
, jint y
)
291 struct peerfont
*pfont
= NULL
;
292 struct graphics
*g
= NULL
;
293 const char *cstr
= NULL
;
294 const char *sTmp
= NULL
;
300 PangoLayoutIter
*iter
= NULL
;
302 gdk_threads_enter ();
304 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
305 g_assert (g
!= NULL
);
307 pfont
= (struct peerfont
*)NSA_GET_FONT_PTR (env
, font
);
308 g_assert (pfont
!= NULL
);
310 cstr
= (*env
)->GetStringUTFChars (env
, str
, NULL
);
311 g_assert (cstr
!= NULL
);
313 charSize
= sizeof(char);
314 p
= malloc((strlen(cstr
) + 1) * charSize
);
315 g_assert (p
!= NULL
);
319 for (; *sTmp
!= '\0'; sTmp
++)
320 if (((unsigned char) *sTmp
) >= ' ')
328 p
= realloc(tmp
, (count
+ 1) * charSize
);
329 g_assert (p
!= NULL
);
330 pango_layout_set_text (pfont
->layout
, p
, -1);
333 pango_layout_set_font_description (pfont
->layout
, pfont
->desc
);
334 iter
= pango_layout_get_iter (pfont
->layout
);
336 baseline_y
= pango_layout_iter_get_baseline (iter
);
338 gdk_draw_layout (g
->drawable
, g
->gc
,
340 y
+ g
->y_offset
- PANGO_PIXELS (baseline_y
),
343 pango_layout_iter_free (iter
);
344 pango_layout_set_text (pfont
->layout
, "", -1);
348 (*env
)->ReleaseStringUTFChars (env
, str
, cstr
);
350 gdk_threads_leave ();
353 JNIEXPORT
void JNICALL
354 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine
355 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint x2
, jint y2
)
357 struct graphics
*g
= NULL
;
359 gdk_threads_enter ();
361 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
363 gdk_draw_line (g
->drawable
, g
->gc
,
364 x
+ g
->x_offset
, y
+ g
->y_offset
,
365 x2
+ g
->x_offset
, y2
+ g
->y_offset
);
368 gdk_threads_leave ();
371 JNIEXPORT
void JNICALL
372 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect
373 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
375 struct graphics
*g
= NULL
;
377 gdk_threads_enter ();
379 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
381 gdk_draw_rectangle (g
->drawable
, g
->gc
, TRUE
,
382 x
+ g
->x_offset
, y
+ g
->y_offset
, width
, height
);
385 gdk_threads_leave ();
388 JNIEXPORT
void JNICALL
389 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect
390 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
392 struct graphics
*g
= NULL
;
394 gdk_threads_enter ();
396 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
398 gdk_draw_rectangle (g
->drawable
, g
->gc
, FALSE
,
399 x
+ g
->x_offset
, y
+ g
->y_offset
, width
, height
);
402 gdk_threads_leave ();
405 JNIEXPORT
void JNICALL
406 Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea
407 (JNIEnv
*env
, jobject obj
, jint x
, jint y
,
408 jint width
, jint height
, jint dx
, jint dy
)
410 struct graphics
*g
= NULL
;
412 gdk_threads_enter ();
414 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
416 gdk_draw_drawable ((GdkWindow
*)g
->drawable
,
418 (GdkWindow
*)g
->drawable
,
419 x
+ g
->x_offset
, y
+ g
->y_offset
,
420 x
+ g
->x_offset
+ dx
, y
+ g
->y_offset
+ dy
,
424 gdk_threads_leave ();
427 JNIEXPORT
void JNICALL
428 Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect
429 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
431 struct graphics
*g
= NULL
;
433 GtkWidget
*widget
= NULL
;
434 union widget_union w
;
436 gdk_threads_enter ();
438 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
442 gdk_threads_leave ();
446 if (GDK_IS_WINDOW (g
->drawable
))
449 gdk_window_get_user_data (GDK_WINDOW (g
->drawable
), w
.void_widget
);
450 if (widget
== NULL
|| !GTK_IS_EVENT_BOX (widget
))
451 gdk_window_clear_area ((GdkWindow
*) g
->drawable
,
452 x
+ g
->x_offset
, y
+ g
->y_offset
,
457 gdk_gc_get_values (g
->gc
, &saved
);
458 gdk_gc_set_foreground (g
->gc
, &(saved
.background
));
459 gdk_draw_rectangle (g
->drawable
, g
->gc
, TRUE
,
460 x
+ g
->x_offset
, y
+ g
->y_offset
, width
, height
);
461 gdk_gc_set_foreground (g
->gc
, &(saved
.foreground
));
466 gdk_threads_leave ();
469 JNIEXPORT
void JNICALL
470 Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction
471 (JNIEnv
*env
, jobject obj
, jint func
)
473 struct graphics
*g
= NULL
;
475 gdk_threads_enter ();
477 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
479 gdk_gc_set_function (g
->gc
, func
);
481 gdk_threads_leave ();
485 JNIEXPORT
void JNICALL
486 Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor
487 (JNIEnv
*env
, jobject obj
, jint red
, jint green
, jint blue
)
490 struct graphics
*g
= NULL
;
492 gdk_threads_enter ();
494 color
.red
= red
<< 8;
495 color
.green
= green
<< 8;
496 color
.blue
= blue
<< 8;
498 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
500 gdk_colormap_alloc_color (g
->cm
, &color
, TRUE
, TRUE
);
501 gdk_gc_set_foreground (g
->gc
, &color
);
503 gdk_threads_leave ();
506 JNIEXPORT
void JNICALL
507 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc
508 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
,
509 jint angle1
, jint angle2
)
511 struct graphics
*g
= NULL
;
513 gdk_threads_enter ();
515 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
517 gdk_draw_arc (g
->drawable
, g
->gc
, FALSE
,
518 x
+ g
->x_offset
, y
+ g
->y_offset
,
519 width
, height
, angle1
<< 6, angle2
<< 6);
522 gdk_threads_leave ();
526 translate_points (JNIEnv
*env
, jintArray xpoints
, jintArray ypoints
,
527 jint npoints
, jint x_offset
, jint y_offset
)
533 /* allocate one more point than necessary, in case we need to tack
534 on an extra due to the semantics of Java polygons. */
535 points
= g_malloc (sizeof (GdkPoint
) * (npoints
+ 1));
537 x
= (*env
)->GetIntArrayElements (env
, xpoints
, NULL
);
538 y
= (*env
)->GetIntArrayElements (env
, ypoints
, NULL
);
540 for (i
= 0; i
< npoints
; i
++)
542 points
[i
].x
= x
[i
] + x_offset
;
543 points
[i
].y
= y
[i
] + y_offset
;
546 (*env
)->ReleaseIntArrayElements (env
, xpoints
, x
, JNI_ABORT
);
547 (*env
)->ReleaseIntArrayElements (env
, ypoints
, y
, JNI_ABORT
);
552 JNIEXPORT
void JNICALL
553 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline
554 (JNIEnv
*env
, jobject obj
, jintArray xpoints
, jintArray ypoints
,
557 struct graphics
*g
= NULL
;
558 GdkPoint
*points
= NULL
;
560 gdk_threads_enter ();
562 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
563 points
= translate_points (env
, xpoints
, ypoints
, npoints
,
564 g
->x_offset
, g
->y_offset
);
566 gdk_draw_lines (g
->drawable
, g
->gc
, points
, npoints
);
571 gdk_threads_leave ();
574 JNIEXPORT
void JNICALL
575 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon
576 (JNIEnv
*env
, jobject obj
, jintArray xpoints
, jintArray ypoints
,
579 struct graphics
*g
= NULL
;
580 GdkPoint
*points
= NULL
;
582 gdk_threads_enter ();
584 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
585 points
= translate_points (env
, xpoints
, ypoints
, npoints
,
586 g
->x_offset
, g
->y_offset
);
588 /* make sure the polygon is closed, per Java semantics.
589 if it's not, we close it. */
590 if (points
[0].x
!= points
[npoints
-1].x
|| points
[0].y
!= points
[npoints
-1].y
)
591 points
[npoints
++] = points
[0];
593 gdk_draw_lines (g
->drawable
, g
->gc
, points
, npoints
);
598 gdk_threads_leave ();
601 JNIEXPORT
void JNICALL
602 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon
603 (JNIEnv
*env
, jobject obj
, jintArray xpoints
, jintArray ypoints
,
606 struct graphics
*g
= NULL
;
607 GdkPoint
*points
= NULL
;
609 gdk_threads_enter ();
611 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
612 points
= translate_points (env
, xpoints
, ypoints
, npoints
,
613 g
->x_offset
, g
->y_offset
);
614 gdk_draw_polygon (g
->drawable
, g
->gc
, TRUE
, points
, npoints
);
619 gdk_threads_leave ();
622 JNIEXPORT
void JNICALL
623 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc
624 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
,
625 jint angle1
, jint angle2
)
627 struct graphics
*g
= NULL
;
629 gdk_threads_enter ();
631 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
633 gdk_draw_arc (g
->drawable
, g
->gc
, TRUE
,
634 x
+ g
->x_offset
, y
+ g
->y_offset
,
635 width
, height
, angle1
<< 6, angle2
<< 6);
638 gdk_threads_leave ();
641 JNIEXPORT
void JNICALL
642 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval
643 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
645 struct graphics
*g
= NULL
;
647 gdk_threads_enter ();
649 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
651 gdk_draw_arc (g
->drawable
, g
->gc
, FALSE
,
652 x
+ g
->x_offset
, y
+ g
->y_offset
,
653 width
, height
, 0, 23040);
656 gdk_threads_leave ();
659 JNIEXPORT
void JNICALL
660 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval
661 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
663 struct graphics
*g
= NULL
;
665 gdk_threads_enter ();
667 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
669 gdk_draw_arc (g
->drawable
, g
->gc
, TRUE
,
670 x
+ g
->x_offset
, y
+ g
->y_offset
,
671 width
, height
, 0, 23040);
674 gdk_threads_leave ();
677 JNIEXPORT
void JNICALL
678 Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle
679 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
681 struct graphics
*g
= NULL
;
682 GdkRectangle rectangle
;
684 gdk_threads_enter ();
686 g
= (struct graphics
*) NSA_GET_G_PTR (env
, obj
);
688 rectangle
.x
= x
+ g
->x_offset
;
689 rectangle
.y
= y
+ g
->y_offset
;
690 rectangle
.width
= width
;
691 rectangle
.height
= height
;
693 gdk_gc_set_clip_rectangle (g
->gc
, &rectangle
);
695 gdk_threads_leave ();
699 realize_cb (GtkWidget
*widget
__attribute__ ((unused
)), jobject jgraphics
)
701 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(),
703 initComponentGraphicsUnlockedID
);
705 NSA_DEL_GLOBAL_G_REF (cp_gtk_gdk_env(), jgraphics
);