OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_ComponentGraphics.c
1 /* gnu_java_awt_peer_gtk_ComponentGraphics.c
2    Copyright (C) 2006, 2007 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 "jcl.h"
39 #include "gtkpeer.h"
40 #include <gdk/gdktypes.h>
41 #include <gdk/gdkprivate.h>
42
43 #include <gdk-pixbuf/gdk-pixbuf.h>
44 #include <gdk-pixbuf/gdk-pixdata.h>
45
46 #include <cairo-ft.h>
47
48 #include <stdio.h>
49 #include <stdlib.h>
50
51 #if HAVE_XRENDER
52 #include <gdk/gdkx.h>
53 #include <X11/extensions/Xrender.h>
54 #endif
55
56 #include "gnu_java_awt_peer_gtk_ComponentGraphics.h"
57
58 #include "cairographics2d.h"
59
60 static short flush_scheduled = 0;
61
62 static gboolean flush (gpointer data __attribute__((unused)))
63 {
64   gdk_threads_enter ();
65
66   gdk_display_flush (gdk_display_get_default ());
67   flush_scheduled = 0;
68
69   gdk_threads_leave ();
70
71   return FALSE;
72 }
73
74 /* The minimum time period between calls to XFlush, in
75    milliseconds. */
76 #define MINIMUM_FLUSH_PERIOD 20
77
78 /* schedule_flush must be called with the GDK lock held. */
79 static void
80 schedule_flush ()
81 {
82   if (!flush_scheduled)
83     {
84       g_timeout_add (MINIMUM_FLUSH_PERIOD, flush, NULL);
85       flush_scheduled = 1;
86     }
87 }
88
89 void cp_gtk_grab_current_drawable(GtkWidget *widget, GdkDrawable **draw,
90                                   GdkWindow **win)
91 {
92   g_assert (widget != NULL);
93   g_assert (draw != NULL);
94   g_assert (win != NULL);
95
96   *win = widget->window;
97
98   *draw = *win;
99   gdk_window_get_internal_paint_info (*win, draw, 0, 0); 
100 }
101
102 /**
103  * Returns whether the XRender extension is supported
104  */
105 JNIEXPORT jboolean JNICALL 
106 Java_gnu_java_awt_peer_gtk_ComponentGraphics_hasXRender
107   (JNIEnv *env __attribute__ ((unused)), jclass cls __attribute__ ((unused)))
108 {
109 #if HAVE_XRENDER
110   int ev = 0, err = 0; 
111   if( XRenderQueryExtension (GDK_DISPLAY(), &ev, &err) )
112     return JNI_TRUE;
113 #endif
114   return JNI_FALSE;
115 }
116
117
118 JNIEXPORT jlong JNICALL 
119 Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState
120   (JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer)
121 {
122   GdkDrawable *drawable;
123   GtkWidget *widget;
124   int width, height;
125   cairo_t *cr;
126   void *ptr;
127
128   gdk_threads_enter();
129
130   ptr = gtkpeer_get_widget (env, peer);
131   g_assert (ptr != NULL);
132
133   widget = GTK_WIDGET (ptr);
134   g_assert (widget != NULL);
135
136   drawable = widget->window;
137   g_assert (drawable != NULL);
138
139   width = widget->allocation.width;
140   height = widget->allocation.height;
141
142   cr = gdk_cairo_create(drawable);
143
144   g_assert(cr != NULL);
145
146   gdk_threads_leave();
147
148   return PTR_TO_JLONG(cr);
149 }
150
151 JNIEXPORT jlong JNICALL 
152 Java_gnu_java_awt_peer_gtk_ComponentGraphics_initFromVolatile
153   (JNIEnv *env  __attribute__ ((unused)), jobject obj __attribute__ ((unused)),
154    jlong ptr)
155 {
156   GdkDrawable *drawable;
157   cairo_t *cr;
158
159   gdk_threads_enter();
160
161   drawable = JLONG_TO_PTR(GdkDrawable, ptr);
162   g_assert (drawable != NULL);
163
164   cr = gdk_cairo_create (drawable);
165   g_assert(cr != NULL);
166
167   gdk_threads_leave();
168
169   return PTR_TO_JLONG(cr);
170 }
171
172 JNIEXPORT void JNICALL 
173 Java_gnu_java_awt_peer_gtk_ComponentGraphics_start_1gdk_1drawing
174   (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)))
175 {
176   gdk_threads_enter();
177 }
178
179 JNIEXPORT void JNICALL 
180 Java_gnu_java_awt_peer_gtk_ComponentGraphics_end_1gdk_1drawing
181   (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)))
182 {
183   schedule_flush ();
184   gdk_threads_leave();
185 }
186
187 JNIEXPORT void JNICALL 
188 Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative
189   (JNIEnv *env, jobject obj __attribute__((unused)), jobject peer,
190    jint x, jint y, jint w, jint h, jint dx, jint dy)
191 {
192   GdkPixbuf *pixbuf;
193   GdkDrawable *drawable;
194   GdkWindow *win;
195   GtkWidget *widget = NULL;
196   void *ptr = NULL;
197
198   gdk_threads_enter();
199
200   ptr = gtkpeer_get_widget (env, peer);
201   g_assert (ptr != NULL);
202
203   widget = GTK_WIDGET (ptr);
204   g_assert (widget != NULL);
205
206   cp_gtk_grab_current_drawable (widget, &drawable, &win);
207   g_assert (drawable != NULL);
208
209   pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, w, h );
210   gdk_pixbuf_get_from_drawable( pixbuf, drawable, NULL, x, y, 0, 0, w, h );
211   gdk_draw_pixbuf (drawable, NULL, pixbuf,
212                    0, 0, x + dx, y + dy, 
213                    w, h, 
214                    GDK_RGB_DITHER_NORMAL, 0, 0);
215   gdk_threads_leave();
216 }
217
218 JNIEXPORT jobject JNICALL 
219 Java_gnu_java_awt_peer_gtk_ComponentGraphics_nativeGrab
220 (JNIEnv *env, jclass cls __attribute__((unused)), jobject peer )
221 {
222   GdkPixbuf *pixbuf;
223   GdkDrawable *drawable;
224   GdkWindow *win;
225   gint w,h;
226   GtkWidget *widget = NULL;
227   void *ptr = NULL;
228
229   gdk_threads_enter();
230
231   ptr = gtkpeer_get_widget (env, peer);
232   g_assert (ptr != NULL);
233
234   widget = GTK_WIDGET (ptr);
235   g_assert (widget != NULL);
236
237   cp_gtk_grab_current_drawable (widget, &drawable, &win);
238   g_assert (drawable != NULL);
239
240   gdk_drawable_get_size ( drawable, &w, &h );
241
242   pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, w, h );
243   gdk_pixbuf_get_from_drawable( pixbuf, drawable, NULL, 0, 0, 0, 0, w, h );
244   g_object_ref( pixbuf );
245   gdk_draw_pixbuf (drawable, NULL, pixbuf,
246                    0, 0, 0, 0, 
247                    w, h, 
248                    GDK_RGB_DITHER_NORMAL, 0, 0);
249   gdk_threads_leave();
250
251   return JCL_NewRawDataObject (env, pixbuf);
252 }
253
254 JNIEXPORT void JNICALL 
255 Java_gnu_java_awt_peer_gtk_ComponentGraphics_drawVolatile
256 (JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer, 
257  jlong img, jint x, jint y, jint w, jint h, jint cx, jint cy, jint cw, jint ch)
258 {
259   GdkPixmap *pixmap;
260   GtkWidget *widget = NULL;
261   GdkGC *gc;
262   GdkRectangle clip;
263   void *ptr;
264
265   gdk_threads_enter();
266
267   ptr = gtkpeer_get_widget (env, peer);
268   g_assert (ptr != NULL);
269
270   widget = GTK_WIDGET (ptr);
271   g_assert (widget != NULL);
272
273   pixmap = JLONG_TO_PTR(GdkPixmap, img);
274  
275   gc = gdk_gc_new(widget->window);
276
277   clip.x = cx;
278   clip.y = cy;
279   clip.width = cw;
280   clip.height = ch;
281   gdk_gc_set_clip_rectangle(gc, &clip);
282
283   gdk_draw_drawable(widget->window,
284                     gc,
285                     pixmap,
286                     0, 0,
287                     x, y,
288                     w, h);
289
290   g_object_unref( gc );
291
292   schedule_flush ();
293
294   gdk_threads_leave();
295 }