Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / jni / gtk-peer / gnu_java_awt_peer_gtk_GdkGraphics.c
blob99b1511264c8d7ae7f009d2605ab51f1a29ff531
1 /* gdkgraphics.c
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)
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. */
38 #include "gtkpeer.h"
39 #include "gdkfont.h"
40 #include "gnu_java_awt_peer_gtk_GdkGraphics.h"
41 #include <gdk/gdkprivate.h>
42 #include <gdk/gdkx.h>
44 #define GDK_STABLE_IS_PIXMAP(d) (GDK_IS_PIXMAP(d))
46 GdkPoint *
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);
60 *g = *g_old;
62 gdk_threads_enter ();
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);
74 gdk_threads_leave ();
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)
83 struct graphics *g;
85 g = (struct graphics *) malloc (sizeof (struct graphics));
86 g->x_offset = g->y_offset = 0;
88 gdk_threads_enter ();
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);
95 gdk_threads_leave ();
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));
107 void *ptr;
108 GtkWidget *widget;
109 GdkColor color;
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)
135 void *ptr;
136 jobject *gref;
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)
155 struct graphics *g;
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 ();
177 free (g);
180 JNIEXPORT void JNICALL
181 Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative
182 (JNIEnv *env, jobject obj, jint x, jint y)
184 struct graphics *g;
186 g = (struct graphics *) NSA_GET_PTR (env, obj);
188 gdk_threads_enter ();
190 g->x_offset += x;
191 g->y_offset += y;
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;
201 struct graphics *g;
202 const char *cstr;
203 int baseline_y;
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,
223 x + g->x_offset,
224 y + g->y_offset - PANGO_PIXELS (baseline_y),
225 pfont->layout);
227 pango_layout_iter_free (iter);
228 pango_layout_set_text (pfont->layout, "", -1);
230 gdk_flush ();
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)
240 struct graphics *g;
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);
248 gdk_flush ();
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)
256 struct graphics *g;
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);
264 gdk_flush ();
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)
272 struct graphics *g;
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);
279 gdk_flush ();
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)
288 struct graphics *g;
290 g = (struct graphics *) NSA_GET_PTR (env, obj);
292 gdk_threads_enter ();
293 gdk_window_copy_area ((GdkWindow *)g->drawable,
294 g->gc,
295 x + g->x_offset + dx, y + g->y_offset + dy,
296 (GdkWindow *)g->drawable,
297 x + g->x_offset, y + g->y_offset,
298 width, height);
299 gdk_flush ();
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,
315 g1->gc,
316 x + g1->x_offset, y + g1->y_offset,
317 (GdkWindow *)g2->drawable,
318 0 + g2->x_offset, 0 + g2->y_offset,
319 width, height);
320 gdk_flush ();
321 gdk_threads_leave ();
324 static void flip_pixbuf (GdkPixbuf *pixbuf,
325 jboolean flip_x,
326 jboolean flip_y,
327 jint width,
328 jint height)
330 gint src_rs;
331 guchar *src_pix;
333 src_rs = gdk_pixbuf_get_rowstride (pixbuf);
334 src_pix = gdk_pixbuf_get_pixels (pixbuf);
336 if (flip_x)
338 gint i, channels;
339 guchar buf[4];
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);
347 while (left < right)
349 g_memmove (buf, left, channels);
350 g_memmove (left, right, channels);
351 g_memmove (right, buf, channels);
352 left += channels;
353 right -= channels;
358 if (flip_y)
360 guchar *top = src_pix;
361 guchar *bottom = top + (height - 1) * src_rs;
362 gpointer buf = g_malloc (src_rs);
364 while (top < bottom)
366 g_memmove (buf, top, src_rs);
367 g_memmove (top, bottom, src_rs);
368 g_memmove (bottom, buf, src_rs);
369 top += src_rs;
370 bottom -= src_rs;
373 g_free (buf);
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,
392 g2->drawable,
393 g2->cm,
394 src_x,
395 src_y,
398 src_width,
399 src_height);
401 buf_dest = gdk_pixbuf_scale_simple (buf_src,
402 dest_width,
403 dest_height,
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,
412 g1->drawable,
413 g1->gc,
416 dest_x,
417 dest_y,
418 dest_width,
419 dest_height,
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)
437 struct graphics *g;
438 GdkGCValues saved;
439 GtkWidget *widget;
440 union widget_union w;
442 g = (struct graphics *) NSA_GET_PTR (env, obj);
444 gdk_threads_enter ();
446 if (!g)
448 gdk_threads_leave ();
449 return;
451 if (GDK_IS_WINDOW (g->drawable))
453 w.widget = &widget;
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,
458 width, height);
460 else
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));
469 gdk_flush ();
470 gdk_threads_leave ();
473 JNIEXPORT void JNICALL
474 Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction
475 (JNIEnv *env, jobject obj, jint func)
477 struct graphics *g;
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)
490 GdkColor color;
491 struct graphics *g;
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)
511 struct graphics *g;
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);
519 gdk_flush ();
520 gdk_threads_leave ();
523 GdkPoint *
524 translate_points (JNIEnv *env, jintArray xpoints, jintArray ypoints,
525 jint npoints, jint x_offset, jint y_offset)
527 GdkPoint *points;
528 jint *x, *y;
529 int i;
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);
547 return points;
550 JNIEXPORT void JNICALL
551 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline
552 (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
553 jint npoints)
555 struct graphics *g;
556 GdkPoint *points;
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);
564 gdk_flush ();
565 gdk_threads_leave ();
567 g_free (points);
570 JNIEXPORT void JNICALL
571 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon
572 (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
573 jint npoints)
575 struct graphics *g;
576 GdkPoint *points;
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);
589 gdk_flush ();
590 gdk_threads_leave ();
592 g_free (points);
595 JNIEXPORT void JNICALL
596 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon
597 (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
598 jint npoints)
600 struct graphics *g;
601 GdkPoint *points;
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);
608 gdk_flush ();
609 gdk_threads_leave ();
611 g_free (points);
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)
619 struct graphics *g;
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);
627 gdk_flush ();
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)
635 struct graphics *g;
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);
643 gdk_flush ();
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)
651 struct graphics *g;
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);
659 gdk_flush ();
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)
667 struct graphics *g;
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)),
683 jobject peer)
685 gdk_threads_leave ();
687 (*gdk_env())->CallVoidMethod (gdk_env(), peer, initComponentGraphicsID);
689 NSA_DEL_GLOBAL_REF (gdk_env(), peer);
691 gdk_threads_enter ();