1 /* gdkgraphics.c
2    Copyright (C) 1999 Free Software Foundation, Inc.
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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 #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>
43 
44 static jmethodID initComponentGraphicsUnlockedID;
45 
46 void
cp_gtk_graphics_init_jni(void)47 cp_gtk_graphics_init_jni (void)
48 {
49   jclass gdkgraphics;
50 
51   gdkgraphics = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
52                                          "gnu/java/awt/peer/gtk/GdkGraphics");
53 
54   initComponentGraphicsUnlockedID =
55     (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics,
56                                       "initComponentGraphicsUnlocked",
57                                       "()V");
58 }
59 
60 struct state_table *cp_gtk_native_graphics_state_table;
61 
62 static struct state_table *native_graphics_global_ref_table;
63 
64 #define NSA_GLOBAL_G_INIT(env, clazz) \
65   native_graphics_global_ref_table = cp_gtk_init_state_table (env, clazz)
66 
67 #define NSA_GET_GLOBAL_G_REF(env, obj) \
68   cp_gtk_get_state (env, obj, native_graphics_global_ref_table)
69 
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)
75 
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)
81 
82 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_initStaticState(JNIEnv * env,jclass clazz)83 Java_gnu_java_awt_peer_gtk_GdkGraphics_initStaticState
84   (JNIEnv *env, jclass clazz)
85 {
86    gdk_threads_enter();
87 
88    NSA_G_INIT (env, clazz);
89    NSA_GLOBAL_G_INIT (env, clazz);
90 
91    gdk_threads_leave();
92 }
93 
94 #define GDK_STABLE_IS_PIXMAP(d) (GDK_IS_PIXMAP(d))
95 
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);
100 
101 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_copyState(JNIEnv * env,jobject obj,jobject old)102 Java_gnu_java_awt_peer_gtk_GdkGraphics_copyState
103   (JNIEnv *env, jobject obj, jobject old)
104 {
105   struct graphics *g = NULL;
106   struct graphics *g_old = NULL;
107 
108   gdk_threads_enter ();
109 
110   g = (struct graphics *) g_malloc (sizeof (struct graphics));
111   g_old = (struct graphics *) NSA_GET_G_PTR (env, old);
112 
113   *g = *g_old;
114 
115   g->gc = gdk_gc_new (g->drawable);
116   gdk_gc_copy (g->gc, g_old->gc);
117 
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);
122 
123   g_object_ref (g->cm);
124 
125   NSA_SET_G_PTR (env, obj, g);
126 
127   gdk_threads_leave ();
128 }
129 
130 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II(JNIEnv * env,jobject obj,jint width,jint height)131 Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II
132   (JNIEnv *env, jobject obj, jint width, jint height)
133 {
134   struct graphics *g = NULL;
135 
136   gdk_threads_enter ();
137 
138   g = (struct graphics *) g_malloc (sizeof (struct graphics));
139   g->x_offset = g->y_offset = 0;
140 
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);
146 
147   NSA_SET_G_PTR (env, obj, g);
148 
149   gdk_threads_leave ();
150 }
151 
152 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_initFromImage(JNIEnv * env,jobject obj,jobject source)153 Java_gnu_java_awt_peer_gtk_GdkGraphics_initFromImage
154    (JNIEnv *env, jobject obj, jobject source)
155 {
156   struct graphics *g = NULL;
157   GdkPixmap *pixmap = NULL;
158 
159   gdk_threads_enter ();
160 
161   pixmap = cp_gtk_image_get_pixmap (env, source);
162   g_assert(pixmap != NULL);
163   g_object_ref (pixmap);
164 
165   g = (struct graphics *) g_malloc (sizeof (struct graphics));
166   g->x_offset = g->y_offset = 0;
167 
168   g->drawable = (GdkDrawable *)pixmap;
169 
170   g->cm = gdk_drawable_get_colormap (g->drawable);
171   g_object_ref (g->cm);
172   g->gc = gdk_gc_new (g->drawable);
173 
174   NSA_SET_G_PTR (env, obj, g);
175 
176   gdk_threads_leave ();
177 }
178 
179 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked(JNIEnv * env,jobject obj,jobject peer)180 Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked
181   (JNIEnv *env, jobject obj, jobject peer)
182 {
183   struct graphics *g = NULL;
184   void *ptr = NULL;
185   GtkWidget *widget = NULL;
186   GdkColor color;
187 
188   g = (struct graphics *) g_malloc (sizeof (struct graphics));
189   ptr = NSA_GET_PTR (env, peer);
190   g->x_offset = 0;
191   g->y_offset = 0;
192 
193   widget = GTK_WIDGET (ptr);
194   g->drawable = (GdkDrawable *) widget->window;
195 
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];
202 
203   NSA_SET_G_PTR (env, obj, g);
204 }
205 
206 /* copy the native state of the peer (GtkWidget *) to the native state
207    of the graphics object */
208 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2(JNIEnv * env,jobject obj,jobject peer)209 Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
210   (JNIEnv *env, jobject obj, jobject peer)
211 {
212   gdk_threads_enter ();
213   Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked
214     (env, obj, peer);
215   gdk_threads_leave ();
216 }
217 
218 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals(JNIEnv * env,jobject obj,jobject peer)219 Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals
220   (JNIEnv *env, jobject obj, jobject peer)
221 {
222   void *ptr = NULL;
223   jobject *gref = NULL;
224 
225   gdk_threads_enter ();
226 
227   NSA_SET_GLOBAL_G_REF (env, obj);
228   gref = NSA_GET_GLOBAL_G_REF (env, obj);
229 
230   ptr = NSA_GET_PTR (env, peer);
231 
232   g_signal_connect_after (G_OBJECT (ptr), "realize",
233                           G_CALLBACK (realize_cb), *gref);
234 
235   gdk_threads_leave ();
236 }
237 
238 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_dispose(JNIEnv * env,jobject obj)239 Java_gnu_java_awt_peer_gtk_GdkGraphics_dispose
240   (JNIEnv *env, jobject obj)
241 {
242   struct graphics *g = NULL;
243 
244   gdk_threads_enter ();
245 
246   g = (struct graphics *) NSA_DEL_G_PTR (env, obj);
247 
248   /* check if dispose has been called already */
249   if (!g)
250     {
251       gdk_threads_leave ();
252       return;
253     }
254 
255   XFlush (GDK_DISPLAY ());
256 
257   g_object_unref (g->gc);
258 
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);
263 
264   g_object_unref (g->cm);
265 
266   g_free (g);
267 
268   gdk_threads_leave ();
269 }
270 
271 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative(JNIEnv * env,jobject obj,jint x,jint y)272 Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative
273   (JNIEnv *env, jobject obj, jint x, jint y)
274 {
275   struct graphics *g = NULL;
276 
277   gdk_threads_enter ();
278 
279   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
280 
281   g->x_offset += x;
282   g->y_offset += y;
283 
284   gdk_threads_leave ();
285 }
286 
287 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString(JNIEnv * env,jobject obj,jobject font,jstring str,jint x,jint y)288 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString
289   (JNIEnv *env, jobject obj, jobject font, jstring str, jint x, jint y)
290 {
291   struct peerfont *pfont = NULL;
292   struct graphics *g = NULL;
293   const char *cstr = NULL;
294   int baseline_y = 0;
295   PangoLayoutIter *iter = NULL;
296 
297   gdk_threads_enter ();
298 
299   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
300   g_assert (g != NULL);
301 
302   pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
303   g_assert (pfont != NULL);
304 
305   cstr = (*env)->GetStringUTFChars (env, str, NULL);
306 
307   pango_layout_set_font_description (pfont->layout, pfont->desc);
308   pango_layout_set_text (pfont->layout, cstr, -1);
309   iter = pango_layout_get_iter (pfont->layout);
310 
311   baseline_y = pango_layout_iter_get_baseline (iter);
312 
313   gdk_draw_layout (g->drawable, g->gc,
314                    x + g->x_offset,
315                    y + g->y_offset - PANGO_PIXELS (baseline_y),
316                    pfont->layout);
317 
318   pango_layout_iter_free (iter);
319   pango_layout_set_text (pfont->layout, "", -1);
320 
321   gdk_flush ();
322 
323   (*env)->ReleaseStringUTFChars (env, str, cstr);
324 
325   gdk_threads_leave ();
326 }
327 
328 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine(JNIEnv * env,jobject obj,jint x,jint y,jint x2,jint y2)329 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine
330   (JNIEnv *env, jobject obj, jint x, jint y, jint x2, jint y2)
331 {
332   struct graphics *g = NULL;
333 
334   gdk_threads_enter ();
335 
336   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
337 
338   gdk_draw_line (g->drawable, g->gc,
339 		 x + g->x_offset, y + g->y_offset,
340 		 x2 + g->x_offset, y2 + g->y_offset);
341   gdk_flush ();
342 
343   gdk_threads_leave ();
344 }
345 
346 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height)347 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect
348   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
349 {
350   struct graphics *g = NULL;
351 
352   gdk_threads_enter ();
353 
354   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
355 
356   gdk_draw_rectangle (g->drawable, g->gc, TRUE,
357 		      x + g->x_offset, y + g->y_offset, width, height);
358   gdk_flush ();
359 
360   gdk_threads_leave ();
361 }
362 
363 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height)364 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect
365   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
366 {
367   struct graphics *g = NULL;
368 
369   gdk_threads_enter ();
370 
371   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
372 
373   gdk_draw_rectangle (g->drawable, g->gc, FALSE,
374 		      x + g->x_offset, y + g->y_offset, width, height);
375   gdk_flush ();
376 
377   gdk_threads_leave ();
378 }
379 
380 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height,jint dx,jint dy)381 Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea
382   (JNIEnv *env, jobject obj, jint x, jint y,
383    jint width, jint height, jint dx, jint dy)
384 {
385   struct graphics *g = NULL;
386 
387   gdk_threads_enter ();
388 
389   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
390 
391   gdk_draw_drawable ((GdkWindow *)g->drawable,
392 		     g->gc,
393 		     (GdkWindow *)g->drawable,
394 		     x + g->x_offset, y + g->y_offset,
395 		     x + g->x_offset + dx, y + g->y_offset + dy,
396 		     width, height);
397   gdk_flush ();
398 
399   gdk_threads_leave ();
400 }
401 
402 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height)403 Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect
404   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
405 {
406   struct graphics *g = NULL;
407   GdkGCValues saved;
408   GtkWidget *widget = NULL;
409   union widget_union w;
410 
411   gdk_threads_enter ();
412 
413   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
414 
415   if (!g)
416     {
417       gdk_threads_leave ();
418       return;
419     }
420 
421   if (GDK_IS_WINDOW (g->drawable))
422     {
423       w.widget = &widget;
424       gdk_window_get_user_data (GDK_WINDOW (g->drawable), w.void_widget);
425       if (widget == NULL || !GTK_IS_EVENT_BOX (widget))
426         gdk_window_clear_area ((GdkWindow *) g->drawable,
427                                x + g->x_offset, y + g->y_offset,
428                                width, height);
429     }
430   else
431     {
432       gdk_gc_get_values (g->gc, &saved);
433       gdk_gc_set_foreground (g->gc, &(saved.background));
434       gdk_draw_rectangle (g->drawable, g->gc, TRUE,
435 			  x + g->x_offset, y + g->y_offset, width, height);
436       gdk_gc_set_foreground (g->gc, &(saved.foreground));
437     }
438 
439   gdk_flush ();
440 
441   gdk_threads_leave ();
442 }
443 
444 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction(JNIEnv * env,jobject obj,jint func)445 Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction
446   (JNIEnv *env, jobject obj, jint func)
447 {
448   struct graphics *g = NULL;
449 
450   gdk_threads_enter ();
451 
452   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
453 
454   gdk_gc_set_function (g->gc, func);
455 
456   gdk_threads_leave ();
457 }
458 
459 
460 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor(JNIEnv * env,jobject obj,jint red,jint green,jint blue)461 Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor
462   (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
463 {
464   GdkColor color;
465   struct graphics *g = NULL;
466 
467   gdk_threads_enter ();
468 
469   color.red = red << 8;
470   color.green = green << 8;
471   color.blue = blue << 8;
472 
473   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
474 
475   gdk_colormap_alloc_color (g->cm, &color, TRUE, TRUE);
476   gdk_gc_set_foreground (g->gc, &color);
477 
478   gdk_threads_leave ();
479 }
480 
481 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height,jint angle1,jint angle2)482 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc
483   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height,
484    jint angle1, jint angle2)
485 {
486   struct graphics *g = NULL;
487 
488   gdk_threads_enter ();
489 
490   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
491 
492   gdk_draw_arc (g->drawable, g->gc, FALSE,
493 		x + g->x_offset, y + g->y_offset,
494 		width, height, angle1 << 6, angle2 << 6);
495   gdk_flush ();
496 
497   gdk_threads_leave ();
498 }
499 
500 static GdkPoint *
translate_points(JNIEnv * env,jintArray xpoints,jintArray ypoints,jint npoints,jint x_offset,jint y_offset)501 translate_points (JNIEnv *env, jintArray xpoints, jintArray ypoints,
502 		  jint npoints, jint x_offset, jint y_offset)
503 {
504   GdkPoint *points;
505   jint *x, *y;
506   int i;
507 
508   /* allocate one more point than necessary, in case we need to tack
509      on an extra due to the semantics of Java polygons. */
510   points = g_malloc (sizeof (GdkPoint) * (npoints + 1));
511 
512   x = (*env)->GetIntArrayElements (env, xpoints, NULL);
513   y = (*env)->GetIntArrayElements (env, ypoints, NULL);
514 
515   for (i = 0; i < npoints; i++)
516     {
517       points[i].x = x[i] + x_offset;
518       points[i].y = y[i] + y_offset;
519     }
520 
521   (*env)->ReleaseIntArrayElements (env, xpoints, x, JNI_ABORT);
522   (*env)->ReleaseIntArrayElements (env, ypoints, y, JNI_ABORT);
523 
524   return points;
525 }
526 
527 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline(JNIEnv * env,jobject obj,jintArray xpoints,jintArray ypoints,jint npoints)528 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline
529   (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
530    jint npoints)
531 {
532   struct graphics *g = NULL;
533   GdkPoint *points = NULL;
534 
535   gdk_threads_enter ();
536 
537   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
538   points = translate_points (env, xpoints, ypoints, npoints,
539 			     g->x_offset, g->y_offset);
540 
541   gdk_draw_lines (g->drawable, g->gc, points, npoints);
542   gdk_flush ();
543 
544   g_free (points);
545 
546   gdk_threads_leave ();
547 }
548 
549 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon(JNIEnv * env,jobject obj,jintArray xpoints,jintArray ypoints,jint npoints)550 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon
551   (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
552    jint npoints)
553 {
554   struct graphics *g = NULL;
555   GdkPoint *points = NULL;
556 
557   gdk_threads_enter ();
558 
559   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
560   points = translate_points (env, xpoints, ypoints, npoints,
561 			     g->x_offset, g->y_offset);
562 
563   /* make sure the polygon is closed, per Java semantics.
564      if it's not, we close it. */
565   if (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y)
566     points[npoints++] = points[0];
567 
568   gdk_draw_lines (g->drawable, g->gc, points, npoints);
569   gdk_flush ();
570 
571   g_free (points);
572 
573   gdk_threads_leave ();
574 }
575 
576 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon(JNIEnv * env,jobject obj,jintArray xpoints,jintArray ypoints,jint npoints)577 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon
578   (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
579    jint npoints)
580 {
581   struct graphics *g = NULL;
582   GdkPoint *points = NULL;
583 
584   gdk_threads_enter ();
585 
586   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
587   points = translate_points (env, xpoints, ypoints, npoints,
588 			     g->x_offset, g->y_offset);
589   gdk_draw_polygon (g->drawable, g->gc, TRUE, points, npoints);
590   gdk_flush ();
591 
592   g_free (points);
593 
594   gdk_threads_leave ();
595 }
596 
597 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height,jint angle1,jint angle2)598 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc
599   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height,
600    jint angle1, jint angle2)
601 {
602   struct graphics *g = NULL;
603 
604   gdk_threads_enter ();
605 
606   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
607 
608   gdk_draw_arc (g->drawable, g->gc, TRUE,
609 		x + g->x_offset, y + g->y_offset,
610 		width, height, angle1 << 6, angle2 << 6);
611   gdk_flush ();
612 
613   gdk_threads_leave ();
614 }
615 
616 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height)617 Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval
618   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
619 {
620   struct graphics *g = NULL;
621 
622   gdk_threads_enter ();
623 
624   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
625 
626   gdk_draw_arc (g->drawable, g->gc, FALSE,
627 		x + g->x_offset, y + g->y_offset,
628 		width, height, 0, 23040);
629   gdk_flush ();
630 
631   gdk_threads_leave ();
632 }
633 
634 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height)635 Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval
636   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
637 {
638   struct graphics *g = NULL;
639 
640   gdk_threads_enter ();
641 
642   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
643 
644   gdk_draw_arc (g->drawable, g->gc, TRUE,
645 		x + g->x_offset, y + g->y_offset,
646 		width, height, 0, 23040);
647   gdk_flush ();
648 
649   gdk_threads_leave ();
650 }
651 
652 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle(JNIEnv * env,jobject obj,jint x,jint y,jint width,jint height)653 Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle
654   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
655 {
656   struct graphics *g = NULL;
657   GdkRectangle rectangle;
658 
659   gdk_threads_enter ();
660 
661   g = (struct graphics *) NSA_GET_G_PTR (env, obj);
662 
663   rectangle.x = x + g->x_offset;
664   rectangle.y = y + g->y_offset;
665   rectangle.width = width;
666   rectangle.height = height;
667 
668   gdk_gc_set_clip_rectangle (g->gc, &rectangle);
669 
670   gdk_threads_leave ();
671 }
672 
673 static void
realize_cb(GtkWidget * widget,jobject jgraphics)674 realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject jgraphics)
675 {
676   (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(),
677                                        jgraphics,
678                                        initComponentGraphicsUnlockedID);
679 
680   NSA_DEL_GLOBAL_G_REF (cp_gtk_gdk_env(), jgraphics);
681 }
682