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., 59 Temple Place, Suite 330, 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 #define GDK_STABLE_IS_PIXMAP(d) (GDK_IS_PIXMAP(d))
47 translate_points (JNIEnv
*env
, jintArray xpoints
, jintArray ypoints
,
48 jint npoints
, jint x_offset
, jint y_offset
);
49 static void realize_cb (GtkWidget
*widget
, jobject peer
);
51 JNIEXPORT
void JNICALL
52 Java_gnu_java_awt_peer_gtk_GdkGraphics_copyState
53 (JNIEnv
*env
, jobject obj
, jobject old
)
55 struct graphics
*g
, *g_old
;
57 g
= (struct graphics
*) malloc (sizeof (struct graphics
));
58 g_old
= (struct graphics
*) NSA_GET_PTR (env
, old
);
64 g
->gc
= gdk_gc_new (g
->drawable
);
65 gdk_gc_copy (g
->gc
, g_old
->gc
);
67 if (GDK_STABLE_IS_PIXMAP (g
->drawable
))
68 gdk_pixmap_ref (g
->drawable
);
69 else /* GDK_IS_WINDOW (g->drawable) */
70 gdk_window_ref (g
->drawable
);
72 gdk_colormap_ref (g
->cm
);
76 NSA_SET_PTR (env
, obj
, g
);
79 JNIEXPORT
void JNICALL
80 Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II
81 (JNIEnv
*env
, jobject obj
, jint width
, jint height
)
85 g
= (struct graphics
*) malloc (sizeof (struct graphics
));
86 g
->x_offset
= g
->y_offset
= 0;
89 g
->drawable
= (GdkDrawable
*) gdk_pixmap_new (NULL
, width
, height
,
90 gdk_rgb_get_visual ()->depth
);
91 g
->cm
= gdk_rgb_get_cmap ();
92 gdk_colormap_ref (g
->cm
);
93 g
->gc
= gdk_gc_new (g
->drawable
);
97 NSA_SET_PTR (env
, obj
, g
);
100 /* copy the native state of the peer (GtkWidget *) to the native state
101 of the graphics object */
102 JNIEXPORT
void JNICALL
103 Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
104 (JNIEnv
*env
, jobject obj
, jobject peer
)
106 struct graphics
*g
= (struct graphics
*) malloc (sizeof (struct graphics
));
111 ptr
= NSA_GET_PTR (env
, peer
);
112 g
->x_offset
= g
->y_offset
= 0;
114 gdk_threads_enter ();
116 widget
= GTK_WIDGET (ptr
);
117 g
->drawable
= (GdkDrawable
*) widget
->window
;
119 gdk_window_ref (g
->drawable
);
120 g
->cm
= gtk_widget_get_colormap (widget
);
121 gdk_colormap_ref (g
->cm
);
122 g
->gc
= gdk_gc_new (g
->drawable
);
123 gdk_gc_copy (g
->gc
, widget
->style
->fg_gc
[GTK_STATE_NORMAL
]);
124 color
= widget
->style
->fg
[GTK_STATE_NORMAL
];
126 gdk_threads_leave ();
128 NSA_SET_PTR (env
, obj
, g
);
131 JNIEXPORT
void JNICALL
132 Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals
133 (JNIEnv
*env
, jobject obj
, jobject peer
)
138 NSA_SET_GLOBAL_REF (env
, obj
);
139 gref
= NSA_GET_GLOBAL_REF (env
, obj
);
141 ptr
= NSA_GET_PTR (env
, peer
);
143 gdk_threads_enter ();
145 g_signal_connect_after (G_OBJECT (ptr
), "realize",
146 G_CALLBACK (realize_cb
), *gref
);
148 gdk_threads_leave ();
151 JNIEXPORT
void JNICALL
152 Java_gnu_java_awt_peer_gtk_GdkGraphics_dispose
153 (JNIEnv
*env
, jobject obj
)
158 g
= (struct graphics
*) NSA_DEL_PTR (env
, obj
);
160 if (!g
) return; /* dispose has been called more than once */
162 gdk_threads_enter ();
163 XFlush (GDK_DISPLAY ());
165 gdk_gc_destroy (g
->gc
);
167 if (GDK_STABLE_IS_PIXMAP (g
->drawable
))
168 gdk_pixmap_unref (g
->drawable
);
169 else /* GDK_IS_WINDOW (g->drawable) */
170 gdk_window_unref (g
->drawable
);
172 gdk_colormap_unref (g
->cm
);
174 gdk_threads_leave ();
180 JNIEXPORT
void JNICALL
181 Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative
182 (JNIEnv
*env
, jobject obj
, jint x
, jint y
)
186 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
188 gdk_threads_enter ();
193 gdk_threads_leave ();
196 JNIEXPORT
void JNICALL
197 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString
198 (JNIEnv
*env
, jobject obj
, jobject font
, jstring str
, jint x
, jint y
)
200 struct peerfont
*pfont
= NULL
;
204 PangoLayoutIter
*iter
;
206 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
207 g_assert (g
!= NULL
);
209 pfont
= (struct peerfont
*)NSA_GET_FONT_PTR (env
, font
);
210 g_assert (pfont
!= NULL
);
212 cstr
= (*env
)->GetStringUTFChars (env
, str
, NULL
);
214 gdk_threads_enter ();
216 pango_layout_set_font_description (pfont
->layout
, pfont
->desc
);
217 pango_layout_set_text (pfont
->layout
, cstr
, -1);
218 iter
= pango_layout_get_iter (pfont
->layout
);
220 baseline_y
= pango_layout_iter_get_baseline (iter
);
222 gdk_draw_layout (g
->drawable
, g
->gc
,
224 y
+ g
->y_offset
- PANGO_PIXELS (baseline_y
),
227 pango_layout_iter_free (iter
);
228 pango_layout_set_text (pfont
->layout
, "", -1);
231 gdk_threads_leave ();
233 (*env
)->ReleaseStringUTFChars (env
, str
, cstr
);
236 JNIEXPORT
void JNICALL
237 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine
238 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint x2
, jint y2
)
242 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
244 gdk_threads_enter ();
245 gdk_draw_line (g
->drawable
, g
->gc
,
246 x
+ g
->x_offset
, y
+ g
->y_offset
,
247 x2
+ g
->x_offset
, y2
+ g
->y_offset
);
249 gdk_threads_leave ();
252 JNIEXPORT
void JNICALL
253 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect
254 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
258 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
260 gdk_threads_enter ();
262 gdk_draw_rectangle (g
->drawable
, g
->gc
, TRUE
,
263 x
+ g
->x_offset
, y
+ g
->y_offset
, width
, height
);
265 gdk_threads_leave ();
268 JNIEXPORT
void JNICALL
269 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect
270 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
274 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
276 gdk_threads_enter ();
277 gdk_draw_rectangle (g
->drawable
, g
->gc
, FALSE
,
278 x
+ g
->x_offset
, y
+ g
->y_offset
, width
, height
);
280 gdk_threads_leave ();
283 JNIEXPORT
void JNICALL
284 Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea
285 (JNIEnv
*env
, jobject obj
, jint x
, jint y
,
286 jint width
, jint height
, jint dx
, jint dy
)
290 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
292 gdk_threads_enter ();
293 gdk_window_copy_area ((GdkWindow
*)g
->drawable
,
295 x
+ g
->x_offset
+ dx
, y
+ g
->y_offset
+ dy
,
296 (GdkWindow
*)g
->drawable
,
297 x
+ g
->x_offset
, y
+ g
->y_offset
,
300 gdk_threads_leave ();
303 JNIEXPORT
void JNICALL
304 Java_gnu_java_awt_peer_gtk_GdkGraphics_copyPixmap
305 (JNIEnv
*env
, jobject obj
, jobject offscreen
,
306 jint x
, jint y
, jint width
, jint height
)
308 struct graphics
*g1
, *g2
;
310 g1
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
311 g2
= (struct graphics
*) NSA_GET_PTR (env
, offscreen
);
313 gdk_threads_enter ();
314 gdk_window_copy_area ((GdkWindow
*)g1
->drawable
,
316 x
+ g1
->x_offset
, y
+ g1
->y_offset
,
317 (GdkWindow
*)g2
->drawable
,
318 0 + g2
->x_offset
, 0 + g2
->y_offset
,
321 gdk_threads_leave ();
324 static void flip_pixbuf (GdkPixbuf
*pixbuf
,
333 src_rs
= gdk_pixbuf_get_rowstride (pixbuf
);
334 src_pix
= gdk_pixbuf_get_pixels (pixbuf
);
341 channels
= gdk_pixbuf_get_has_alpha (pixbuf
) ? 4 : 3;
343 for (i
= 0; i
< height
; i
++)
345 guchar
*left
= src_pix
+ i
* src_rs
;
346 guchar
*right
= left
+ channels
* (width
- 1);
349 g_memmove (buf
, left
, channels
);
350 g_memmove (left
, right
, channels
);
351 g_memmove (right
, buf
, channels
);
360 guchar
*top
= src_pix
;
361 guchar
*bottom
= top
+ (height
- 1) * src_rs
;
362 gpointer buf
= g_malloc (src_rs
);
366 g_memmove (buf
, top
, src_rs
);
367 g_memmove (top
, bottom
, src_rs
);
368 g_memmove (bottom
, buf
, src_rs
);
377 JNIEXPORT
void JNICALL
378 Java_gnu_java_awt_peer_gtk_GdkGraphics_copyAndScalePixmap
379 (JNIEnv
*env
, jobject obj
, jobject offscreen
, jboolean flip_x
, jboolean flip_y
,
380 jint src_x
, jint src_y
, jint src_width
, jint src_height
,
381 jint dest_x
, jint dest_y
, jint dest_width
, jint dest_height
)
383 struct graphics
*g1
, *g2
;
384 GdkPixbuf
*buf_src
, *buf_dest
;
386 g1
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
387 g2
= (struct graphics
*) NSA_GET_PTR (env
, offscreen
);
389 gdk_threads_enter ();
391 buf_src
= gdk_pixbuf_get_from_drawable (NULL
,
401 buf_dest
= gdk_pixbuf_scale_simple (buf_src
,
404 GDK_INTERP_BILINEAR
);
406 if (flip_x
|| flip_y
)
408 flip_pixbuf (buf_dest
, flip_x
, flip_y
, dest_width
, dest_height
);
411 gdk_pixbuf_render_to_drawable (buf_dest
,
420 GDK_RGB_DITHER_NORMAL
,
424 g_object_unref (G_OBJECT (buf_src
));
425 g_object_unref (G_OBJECT (buf_dest
));
427 gdk_threads_leave ();
433 JNIEXPORT
void JNICALL
434 Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect
435 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
440 union widget_union w
;
442 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
444 gdk_threads_enter ();
448 gdk_threads_leave ();
451 if (GDK_IS_WINDOW (g
->drawable
))
454 gdk_window_get_user_data (GDK_WINDOW (g
->drawable
), w
.void_widget
);
455 if (widget
== NULL
|| !GTK_IS_EVENT_BOX (widget
))
456 gdk_window_clear_area ((GdkWindow
*) g
->drawable
,
457 x
+ g
->x_offset
, y
+ g
->y_offset
,
462 gdk_gc_get_values (g
->gc
, &saved
);
463 gdk_gc_set_foreground (g
->gc
, &(saved
.background
));
464 gdk_draw_rectangle (g
->drawable
, g
->gc
, TRUE
,
465 x
+ g
->x_offset
, y
+ g
->y_offset
, width
, height
);
466 gdk_gc_set_foreground (g
->gc
, &(saved
.foreground
));
470 gdk_threads_leave ();
473 JNIEXPORT
void JNICALL
474 Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction
475 (JNIEnv
*env
, jobject obj
, jint func
)
478 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
480 gdk_threads_enter ();
481 gdk_gc_set_function (g
->gc
, func
);
482 gdk_threads_leave ();
486 JNIEXPORT
void JNICALL
487 Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor
488 (JNIEnv
*env
, jobject obj
, jint red
, jint green
, jint blue
)
493 color
.red
= red
<< 8;
494 color
.green
= green
<< 8;
495 color
.blue
= blue
<< 8;
497 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
499 gdk_threads_enter ();
500 gdk_color_alloc (g
->cm
, &color
);
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
)
513 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
515 gdk_threads_enter ();
516 gdk_draw_arc (g
->drawable
, g
->gc
, FALSE
,
517 x
+ g
->x_offset
, y
+ g
->y_offset
,
518 width
, height
, angle1
<< 6, angle2
<< 6);
520 gdk_threads_leave ();
524 translate_points (JNIEnv
*env
, jintArray xpoints
, jintArray ypoints
,
525 jint npoints
, jint x_offset
, jint y_offset
)
531 /* allocate one more point than necessary, in case we need to tack
532 on an extra due to the semantics of Java polygons. */
533 points
= g_malloc (sizeof (GdkPoint
) * (npoints
+ 1));
535 x
= (*env
)->GetIntArrayElements (env
, xpoints
, NULL
);
536 y
= (*env
)->GetIntArrayElements (env
, ypoints
, NULL
);
538 for (i
= 0; i
< npoints
; i
++)
540 points
[i
].x
= x
[i
] + x_offset
;
541 points
[i
].y
= y
[i
] + y_offset
;
544 (*env
)->ReleaseIntArrayElements (env
, xpoints
, x
, JNI_ABORT
);
545 (*env
)->ReleaseIntArrayElements (env
, ypoints
, y
, JNI_ABORT
);
550 JNIEXPORT
void JNICALL
551 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline
552 (JNIEnv
*env
, jobject obj
, jintArray xpoints
, jintArray ypoints
,
558 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
559 points
= translate_points (env
, xpoints
, ypoints
, npoints
,
560 g
->x_offset
, g
->y_offset
);
562 gdk_threads_enter ();
563 gdk_draw_lines (g
->drawable
, g
->gc
, points
, npoints
);
565 gdk_threads_leave ();
570 JNIEXPORT
void JNICALL
571 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon
572 (JNIEnv
*env
, jobject obj
, jintArray xpoints
, jintArray ypoints
,
578 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
579 points
= translate_points (env
, xpoints
, ypoints
, npoints
,
580 g
->x_offset
, g
->y_offset
);
582 /* make sure the polygon is closed, per Java semantics.
583 if it's not, we close it. */
584 if (points
[0].x
!= points
[npoints
-1].x
|| points
[0].y
!= points
[npoints
-1].y
)
585 points
[npoints
++] = points
[0];
587 gdk_threads_enter ();
588 gdk_draw_lines (g
->drawable
, g
->gc
, points
, npoints
);
590 gdk_threads_leave ();
595 JNIEXPORT
void JNICALL
596 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon
597 (JNIEnv
*env
, jobject obj
, jintArray xpoints
, jintArray ypoints
,
603 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
604 points
= translate_points (env
, xpoints
, ypoints
, npoints
,
605 g
->x_offset
, g
->y_offset
);
606 gdk_threads_enter ();
607 gdk_draw_polygon (g
->drawable
, g
->gc
, TRUE
, points
, npoints
);
609 gdk_threads_leave ();
614 JNIEXPORT
void JNICALL
615 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc
616 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
,
617 jint angle1
, jint angle2
)
621 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
623 gdk_threads_enter ();
624 gdk_draw_arc (g
->drawable
, g
->gc
, TRUE
,
625 x
+ g
->x_offset
, y
+ g
->y_offset
,
626 width
, height
, angle1
<< 6, angle2
<< 6);
628 gdk_threads_leave ();
631 JNIEXPORT
void JNICALL
632 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval
633 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
637 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
639 gdk_threads_enter ();
640 gdk_draw_arc (g
->drawable
, g
->gc
, FALSE
,
641 x
+ g
->x_offset
, y
+ g
->y_offset
,
642 width
, height
, 0, 23040);
644 gdk_threads_leave ();
647 JNIEXPORT
void JNICALL
648 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval
649 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
653 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
655 gdk_threads_enter ();
656 gdk_draw_arc (g
->drawable
, g
->gc
, TRUE
,
657 x
+ g
->x_offset
, y
+ g
->y_offset
,
658 width
, height
, 0, 23040);
660 gdk_threads_leave ();
663 JNIEXPORT
void JNICALL
664 Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle
665 (JNIEnv
*env
, jobject obj
, jint x
, jint y
, jint width
, jint height
)
668 GdkRectangle rectangle
;
670 g
= (struct graphics
*) NSA_GET_PTR (env
, obj
);
672 rectangle
.x
= x
+ g
->x_offset
;
673 rectangle
.y
= y
+ g
->y_offset
;
674 rectangle
.width
= width
;
675 rectangle
.height
= height
;
677 gdk_threads_enter ();
678 gdk_gc_set_clip_rectangle (g
->gc
, &rectangle
);
679 gdk_threads_leave ();
682 static void realize_cb (GtkWidget
*widget
__attribute__ ((unused
)),
685 gdk_threads_leave ();
687 (*gdk_env())->CallVoidMethod (gdk_env(), peer
, initComponentGraphicsID
);
689 NSA_DEL_GLOBAL_REF (gdk_env(), peer
);
691 gdk_threads_enter ();