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
flush(gpointer data)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
schedule_flush()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
cp_gtk_grab_current_drawable(GtkWidget * widget,GdkDrawable ** draw,GdkWindow ** win)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
Java_gnu_java_awt_peer_gtk_ComponentGraphics_hasXRender(JNIEnv * env,jclass cls)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
Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState(JNIEnv * env,jobject obj,jobject peer)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 cairo_t *cr;
125 void *ptr;
126
127 gdk_threads_enter();
128
129 ptr = gtkpeer_get_widget (env, peer);
130 g_assert (ptr != NULL);
131
132 widget = GTK_WIDGET (ptr);
133 g_assert (widget != NULL);
134
135 drawable = widget->window;
136 g_assert (drawable != NULL);
137
138 cr = gdk_cairo_create(drawable);
139
140 g_assert(cr != NULL);
141
142 gdk_threads_leave();
143
144 return PTR_TO_JLONG(cr);
145 }
146
147 JNIEXPORT jlong JNICALL
Java_gnu_java_awt_peer_gtk_ComponentGraphics_initFromVolatile(JNIEnv * env,jobject obj,jlong ptr)148 Java_gnu_java_awt_peer_gtk_ComponentGraphics_initFromVolatile
149 (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)),
150 jlong ptr)
151 {
152 GdkDrawable *drawable;
153 cairo_t *cr;
154
155 gdk_threads_enter();
156
157 drawable = JLONG_TO_PTR(GdkDrawable, ptr);
158 g_assert (drawable != NULL);
159
160 cr = gdk_cairo_create (drawable);
161 g_assert(cr != NULL);
162
163 gdk_threads_leave();
164
165 return PTR_TO_JLONG(cr);
166 }
167
168 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_ComponentGraphics_start_1gdk_1drawing(JNIEnv * env,jobject obj)169 Java_gnu_java_awt_peer_gtk_ComponentGraphics_start_1gdk_1drawing
170 (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)))
171 {
172 gdk_threads_enter();
173 }
174
175 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_ComponentGraphics_end_1gdk_1drawing(JNIEnv * env,jobject obj)176 Java_gnu_java_awt_peer_gtk_ComponentGraphics_end_1gdk_1drawing
177 (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)))
178 {
179 schedule_flush ();
180 gdk_threads_leave();
181 }
182
183 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative(JNIEnv * env,jobject obj,jobject peer,jint x,jint y,jint w,jint h,jint dx,jint dy)184 Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative
185 (JNIEnv *env, jobject obj __attribute__((unused)), jobject peer,
186 jint x, jint y, jint w, jint h, jint dx, jint dy)
187 {
188 GdkPixbuf *pixbuf;
189 GdkDrawable *drawable;
190 GdkWindow *win;
191 GtkWidget *widget = NULL;
192 void *ptr = NULL;
193
194 gdk_threads_enter();
195
196 ptr = gtkpeer_get_widget (env, peer);
197 g_assert (ptr != NULL);
198
199 widget = GTK_WIDGET (ptr);
200 g_assert (widget != NULL);
201
202 cp_gtk_grab_current_drawable (widget, &drawable, &win);
203 g_assert (drawable != NULL);
204
205 pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, w, h );
206 gdk_pixbuf_get_from_drawable( pixbuf, drawable, NULL, x, y, 0, 0, w, h );
207 gdk_draw_pixbuf (drawable, NULL, pixbuf,
208 0, 0, x + dx, y + dy,
209 w, h,
210 GDK_RGB_DITHER_NORMAL, 0, 0);
211 gdk_threads_leave();
212 }
213
214 JNIEXPORT jobject JNICALL
Java_gnu_java_awt_peer_gtk_ComponentGraphics_nativeGrab(JNIEnv * env,jclass cls,jobject peer)215 Java_gnu_java_awt_peer_gtk_ComponentGraphics_nativeGrab
216 (JNIEnv *env, jclass cls __attribute__((unused)), jobject peer )
217 {
218 GdkPixbuf *pixbuf;
219 GdkDrawable *drawable;
220 GdkWindow *win;
221 gint w,h;
222 GtkWidget *widget = NULL;
223 void *ptr = NULL;
224
225 gdk_threads_enter();
226
227 ptr = gtkpeer_get_widget (env, peer);
228 g_assert (ptr != NULL);
229
230 widget = GTK_WIDGET (ptr);
231 g_assert (widget != NULL);
232
233 cp_gtk_grab_current_drawable (widget, &drawable, &win);
234 g_assert (drawable != NULL);
235
236 gdk_drawable_get_size ( drawable, &w, &h );
237
238 pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, w, h );
239 gdk_pixbuf_get_from_drawable( pixbuf, drawable, NULL, 0, 0, 0, 0, w, h );
240 g_object_ref( pixbuf );
241 gdk_draw_pixbuf (drawable, NULL, pixbuf,
242 0, 0, 0, 0,
243 w, h,
244 GDK_RGB_DITHER_NORMAL, 0, 0);
245 gdk_threads_leave();
246
247 return JCL_NewRawDataObject (env, pixbuf);
248 }
249
250 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_ComponentGraphics_drawVolatile(JNIEnv * env,jobject obj,jobject peer,jlong img,jint x,jint y,jint w,jint h,jint cx,jint cy,jint cw,jint ch)251 Java_gnu_java_awt_peer_gtk_ComponentGraphics_drawVolatile
252 (JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer,
253 jlong img, jint x, jint y, jint w, jint h, jint cx, jint cy, jint cw, jint ch)
254 {
255 GdkPixmap *pixmap;
256 GtkWidget *widget = NULL;
257 GdkGC *gc;
258 GdkRectangle clip;
259 void *ptr;
260
261 gdk_threads_enter();
262
263 ptr = gtkpeer_get_widget (env, peer);
264 g_assert (ptr != NULL);
265
266 widget = GTK_WIDGET (ptr);
267 g_assert (widget != NULL);
268
269 pixmap = JLONG_TO_PTR(GdkPixmap, img);
270
271 gc = gdk_gc_new(widget->window);
272
273 clip.x = cx;
274 clip.y = cy;
275 clip.width = cw;
276 clip.height = ch;
277 gdk_gc_set_clip_rectangle(gc, &clip);
278
279 gdk_draw_drawable(widget->window,
280 gc,
281 pixmap,
282 0, 0,
283 x, y,
284 w, h);
285
286 g_object_unref( gc );
287
288 schedule_flush ();
289
290 gdk_threads_leave();
291 }
292