1 /* gtkpeer.c -- Some GTK peer specific helper functions
2 Copyright (C) 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 "gtkpeer.h"
39 #include "jni.h"
40
41 /**
42 * The Pointer class.
43 */
44 static jclass pointerClass;
45
46 /**
47 * The Pointer constructor.
48 */
49 static jmethodID pointerConstructorMID;
50
51 /**
52 * The field ID of the data field in the Pointer class.
53 */
54 static jfieldID pointerDataFID;
55
56 /**
57 * The field ID of the widget field in the GtkGenericPeer class.
58 */
59 static jfieldID widgetFID;
60
61 /**
62 * The field ID of the globalRef field in the GtkGenericPeer class.
63 */
64 static jfieldID globalRefFID;
65
66 /**
67 * The field ID of the display field in the GdkGraphicsEnvironment class.
68 */
69 static jfieldID displayFID;
70
71 /**
72 * The field ID of the screen field in the GdkScreenGraphicsDevice class.
73 */
74 static jfieldID screenFID;
75
76 /**
77 * The field ID of the nativeFont field in GdkFontPeer.
78 */
79 static jfieldID fontFID;
80
81 /**
82 * The field ID of the nativeDecoder field in GdkPixbufDecoder.
83 */
84 static jfieldID pixbufLoaderFID;
85
86 /**
87 * Initializes the IDs of the Pointer* classes.
88 *
89 * @param env the JNI environment
90 */
gtkpeer_init_pointer_IDs(JNIEnv * env)91 void gtkpeer_init_pointer_IDs(JNIEnv* env)
92 {
93 #if SIZEOF_VOID_P == 8
94 pointerClass = (*env)->FindClass (env, "gnu/classpath/Pointer64");
95 if (pointerClass != NULL)
96 {
97 pointerClass = (*env)->NewGlobalRef (env, pointerClass);
98 pointerDataFID = (*env)->GetFieldID (env, pointerClass, "data", "J");
99 pointerConstructorMID = (*env)->GetMethodID (env, pointerClass, "<init>",
100 "(J)V");
101 }
102 #else
103 #if SIZEOF_VOID_P == 4
104 pointerClass = (*env)->FindClass(env, "gnu/classpath/Pointer32");
105 if (pointerClass != NULL)
106 {
107 pointerClass = (*env)->NewGlobalRef (env, pointerClass);
108 pointerDataFID = (*env)->GetFieldID (env, pointerClass, "data", "I");
109 pointerConstructorMID = (*env)->GetMethodID (env, pointerClass, "<init>",
110 "(I)V");
111 }
112 #else
113 #error "Pointer size is not supported."
114 #endif /* SIZEOF_VOID_P == 4 */
115 #endif /* SIZEOF_VOID_P == 8 */
116 }
117
118 /**
119 * Initializes the field IDs for the widget reference.
120 *
121 * @param env the JNI environment
122 */
gtkpeer_init_widget_IDs(JNIEnv * env)123 void gtkpeer_init_widget_IDs(JNIEnv *env)
124 {
125 jclass cls;
126
127 /* Find the widget field ID in GtkGenericPeer. */
128 cls = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GtkGenericPeer");
129 widgetFID = (*env)->GetFieldID(env, cls, "widget",
130 "Lgnu/classpath/Pointer;");
131
132 /* Find the globalRef field in GtkGenericPeer. */
133 globalRefFID = (*env)->GetFieldID(env, cls, "globalRef",
134 "Lgnu/classpath/Pointer;");
135 }
136
137 /**
138 * Stores the GTK widget reference in the GtkGenericPeer object.
139 *
140 * @param env the JNI environment
141 * @param peer the actual peer object
142 * @param widget the widget reference to store
143 */
gtkpeer_set_widget(JNIEnv * env,jobject peer,void * widget)144 void gtkpeer_set_widget(JNIEnv *env, jobject peer, void *widget)
145 {
146 jobject obj;
147
148 /* Fetch the widget field object. */
149 obj = (*env)->GetObjectField(env, peer, widgetFID);
150 if (obj == NULL)
151 {
152 /* Create if necessary. */
153 #if SIZEOF_VOID_P == 8
154 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
155 (jlong) widget);
156 #else
157 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
158 (jint) widget);
159 #endif
160 (*env)->SetObjectField(env, peer, widgetFID, obj);
161 }
162 else
163 {
164 #if SIZEOF_VOID_P == 8
165 (*env)->SetLongField(env, obj, pointerDataFID, (jlong) widget);
166 #else
167 (*env)->SetIntField(env, obj, pointerDataFID, (jint) widget);
168 #endif
169 }
170 }
171
172 /**
173 * Retrieves the GTK widget reference from a GtkGenericPeer object.
174 *
175 * @param env the JNI environment
176 * @param peer the actual peer object
177 *
178 * @return the widget reference
179 */
gtkpeer_get_widget(JNIEnv * env,jobject peer)180 void* gtkpeer_get_widget(JNIEnv *env, jobject peer)
181 {
182 jobject obj;
183 void *widget;
184
185 /* Fetch the widget field from the peer object. */
186 obj = (*env)->GetObjectField(env, peer, widgetFID);
187
188 /* Fetch actual widget pointer. */
189 #if SIZEOF_VOID_P == 8
190 widget = (void*) (*env)->GetLongField(env, obj, pointerDataFID);
191 #else
192 widget = (void*) (*env)->GetIntField(env, obj, pointerDataFID);
193 #endif
194 return widget;
195 }
196
197
198 /**
199 * Stores the global JNI reference of a peer inside the peer.
200 *
201 * @param env the JNI environment
202 * @param peer the peer object
203 */
gtkpeer_set_global_ref(JNIEnv * env,jobject peer)204 void gtkpeer_set_global_ref(JNIEnv *env, jobject peer)
205 {
206 jobject obj;
207 void* globalRef;
208
209 /* Create global reference. */
210 globalRef = (*env)->NewGlobalRef(env, peer);
211
212 /* Fetch the globalRef field object. */
213 obj = (*env)->GetObjectField(env, peer, globalRefFID);
214 if (obj == NULL)
215 {
216 /* Create if necessary. */
217 #if SIZEOF_VOID_P == 8
218 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
219 (jlong) globalRef);
220 #else
221 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
222 (jint) globalRef);
223 #endif
224 (*env)->SetObjectField(env, peer, globalRefFID, obj);
225 }
226 else
227 {
228 #if SIZEOF_VOID_P == 8
229 (*env)->SetLongField(env, obj, pointerDataFID, (jlong) globalRef);
230 #else
231 (*env)->SetIntField(env, obj, pointerDataFID, (jint) globalRef);
232 #endif
233 }
234 }
235
236 /**
237 * Retrieves the global reference from a peer.
238 *
239 * @param env the JNI environment
240 * @param peer the peer object
241 *
242 * @return the global reference
243 */
gtkpeer_get_global_ref(JNIEnv * env,jobject peer)244 void* gtkpeer_get_global_ref(JNIEnv *env, jobject peer)
245 {
246 jobject obj;
247 void *globalRef;
248
249 /* Fetch the globalRef field from the peer object. */
250 obj = (*env)->GetObjectField(env, peer, globalRefFID);
251
252 /* Fetch actual globalRef pointer. */
253 #if SIZEOF_VOID_P == 8
254 globalRef = (void*) (*env)->GetLongField(env, obj, pointerDataFID);
255 #else
256 globalRef = (void*) (*env)->GetIntField(env, obj, pointerDataFID);
257 #endif
258 return globalRef;
259 }
260
261 /**
262 * Deletes the global reference of a peer. This is necessary in order to
263 * allow the peer to be garbage collected.
264 *
265 * @param env the JNI environment
266 * @param peer the peer object.
267 */
gtkpeer_del_global_ref(JNIEnv * env,jobject peer)268 void gtkpeer_del_global_ref(JNIEnv* env, jobject peer)
269 {
270 jobject obj;
271 void *globalRef;
272
273 /* Fetch the globalRef field from the peer object. */
274 obj = (*env)->GetObjectField(env, peer, globalRefFID);
275
276 /* Fetch actual globalRef pointer. */
277 #if SIZEOF_VOID_P == 8
278 globalRef = (void*) (*env)->GetLongField(env, obj, pointerDataFID);
279 #else
280 globalRef = (void*) (*env)->GetIntField(env, obj, pointerDataFID);
281 #endif
282 (*env)->DeleteGlobalRef(env, globalRef);
283 }
284
285 /**
286 * Initializes the fieldIDs for the display and screen fields.
287 *
288 * @param env the JNI environment
289 */
gtkpeer_init_display_IDs(JNIEnv * env)290 void gtkpeer_init_display_IDs(JNIEnv* env)
291 {
292 jclass cls;
293
294 /* Find the display field ID in GdkGraphicsEnvironment. */
295 cls = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GdkGraphicsEnvironment");
296 displayFID = (*env)->GetFieldID(env, cls, "display",
297 "Lgnu/classpath/Pointer;");
298 }
299
300 /**
301 * Sets the native display pointer in the GdkGraphicsEnvironment object.
302 *
303 * @param env the JNI environment
304 * @param graphicsenv the GdkGraphicsEnvironment object
305 * @param display the native display pointer
306 */
gtkpeer_set_display(JNIEnv * env,jobject graphicsenv,void * display)307 void gtkpeer_set_display(JNIEnv* env, jobject graphicsenv, void* display)
308 {
309 jobject obj;
310
311 /* Fetch the display field object. */
312 obj = (*env)->GetObjectField(env, graphicsenv, displayFID);
313 if (obj == NULL)
314 {
315 /* Create if necessary. */
316 #if SIZEOF_VOID_P == 8
317 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
318 (jlong) display);
319 #else
320 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
321 (jint) display);
322 #endif
323 (*env)->SetObjectField(env, graphicsenv, displayFID, obj);
324 }
325 else
326 {
327 #if SIZEOF_VOID_P == 8
328 (*env)->SetLongField(env, obj, pointerDataFID, (jlong) display);
329 #else
330 (*env)->SetIntField(env, obj, pointerDataFID, (jint) display);
331 #endif
332 }
333 }
334
335 /**
336 * Fetches the native display pointer from the GdkGraphicsEnvironment object.
337 *
338 * @param env the JNI environment
339 * @param graphicsenv the GdkGraphicsEnvironment object
340 *
341 * @return the native display pointer
342 */
gtkpeer_get_display(JNIEnv * env,jobject graphicsenv)343 void* gtkpeer_get_display(JNIEnv* env, jobject graphicsenv)
344 {
345 jobject obj;
346 void *display;
347
348 /* Fetch the display field from the peer object. */
349 obj = (*env)->GetObjectField(env, graphicsenv, displayFID);
350
351 /* Fetch actual display pointer. */
352 #if SIZEOF_VOID_P == 8
353 display = (void*) (*env)->GetLongField(env, obj, pointerDataFID);
354 #else
355 display = (void*) (*env)->GetIntField(env, obj, pointerDataFID);
356 #endif
357 return display;
358 }
359
360 /**
361 * Initializes the fieldIDs for the screen field.
362 *
363 * @param env the JNI environment
364 */
gtkpeer_init_screen_IDs(JNIEnv * env)365 void gtkpeer_init_screen_IDs(JNIEnv* env)
366 {
367 jclass cls;
368
369 /* Find the display field ID in GdkScreenGraphicsDevice. */
370 cls = (*env)->FindClass(env,
371 "gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice");
372 screenFID = (*env)->GetFieldID(env, cls, "screen",
373 "Lgnu/classpath/Pointer;");
374 }
375
376 /**
377 * Sets the native screen in the GdkScreenGraphicsDevice object.
378 *
379 * @param env the JNI environment
380 * @param screen_graphics_device the GdkScreenGraphicsDevice object
381 * @param ptr the native screen pointer
382 */
gtkpeer_set_screen(JNIEnv * env,jobject screen_graphics_device,void * ptr)383 void gtkpeer_set_screen(JNIEnv* env, jobject screen_graphics_device,
384 void* ptr)
385 {
386 jobject obj;
387
388 /* Fetch the screen field object. */
389 obj = (*env)->GetObjectField(env, screen_graphics_device, screenFID);
390 if (obj == NULL)
391 {
392 /* Create if necessary. */
393 #if SIZEOF_VOID_P == 8
394 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
395 (jlong) ptr);
396 #else
397 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
398 (jint) ptr);
399 #endif
400 (*env)->SetObjectField(env, screen_graphics_device, screenFID, obj);
401 }
402 else
403 {
404 #if SIZEOF_VOID_P == 8
405 (*env)->SetLongField(env, obj, pointerDataFID, (jlong) ptr);
406 #else
407 (*env)->SetIntField(env, obj, pointerDataFID, (jint) ptr);
408 #endif
409 }
410 }
411
412 /**
413 * Fetches the native screen pointer from the GdkScreenGraphicsDevice object.
414 *
415 * @param env the JNI environment
416 * @param screen_graphics_device the GdkScreenGraphicsDevice object
417 *
418 * @return the native screen pointer
419 */
gtkpeer_get_screen(JNIEnv * env,jobject screen_graphics_device)420 void* gtkpeer_get_screen(JNIEnv* env, jobject screen_graphics_device)
421 {
422 jobject obj;
423 void *screen;
424
425 /* Fetch the display field from the peer object. */
426 obj = (*env)->GetObjectField(env, screen_graphics_device, screenFID);
427
428 /* Fetch actual display pointer. */
429 #if SIZEOF_VOID_P == 8
430 screen = (void*) (*env)->GetLongField(env, obj, pointerDataFID);
431 #else
432 screen = (void*) (*env)->GetIntField(env, obj, pointerDataFID);
433 #endif
434 return screen;
435 }
436
437 /**
438 * Initializes the field IDs for fonts.
439 *
440 * @param env the JNI environment
441 */
gtkpeer_init_font_IDs(JNIEnv * env)442 void gtkpeer_init_font_IDs(JNIEnv* env)
443 {
444 jclass cls;
445
446 /* Find the nativeFont field ID in GdkFontPeer. */
447 cls = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GdkFontPeer");
448 fontFID = (*env)->GetFieldID(env, cls, "nativeFont",
449 "Lgnu/classpath/Pointer;");
450 }
451
452 /**
453 * Sets the native font in the nativeFont field in GdkFontPeer.
454 *
455 * @param env the JNI environment
456 * @param font_peer the font peer object
457 * @param font the actual native font reference
458 */
gtkpeer_set_font(JNIEnv * env,jobject font_peer,void * font)459 void gtkpeer_set_font(JNIEnv* env, jobject font_peer, void* font)
460 {
461 jobject obj;
462
463 /* Fetch the nativeFont field object. */
464 obj = (*env)->GetObjectField(env, font_peer, fontFID);
465 if (obj == NULL)
466 {
467 /* Create if necessary. */
468 #if SIZEOF_VOID_P == 8
469 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
470 (jlong) font);
471 #else
472 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
473 (jint) font);
474 #endif
475 (*env)->SetObjectField(env, font_peer, fontFID, obj);
476 }
477 else
478 {
479 #if SIZEOF_VOID_P == 8
480 (*env)->SetLongField(env, obj, pointerDataFID, (jlong) font);
481 #else
482 (*env)->SetIntField(env, obj, pointerDataFID, (jint) font);
483 #endif
484 }
485 }
486
487 /**
488 * Fetches the native font reference from the GdkFontPeer object.
489 *
490 * @param env the JNI environment
491 * @param font_peer the font peer object
492 *
493 * @return the native font structure
494 */
gtkpeer_get_font(JNIEnv * env,jobject font_peer)495 void* gtkpeer_get_font(JNIEnv* env, jobject font_peer)
496 {
497 jobject obj;
498 void *font;
499
500 /* Fetch the nativeFont field from the peer object. */
501 obj = (*env)->GetObjectField(env, font_peer, fontFID);
502
503 /* Fetch actual font pointer. */
504 #if SIZEOF_VOID_P == 8
505 font = (void*) (*env)->GetLongField(env, obj, pointerDataFID);
506 #else
507 font = (void*) (*env)->GetIntField(env, obj, pointerDataFID);
508 #endif
509 return font;
510 }
511
512 /**
513 * Initializes the field IDs for pixbuf decoder.
514 *
515 * @param env the JNI environment
516 */
gtkpeer_init_pixbuf_IDs(JNIEnv * env)517 void gtkpeer_init_pixbuf_IDs(JNIEnv* env)
518 {
519 jclass cls;
520
521 /* Find the nativeFont field ID in GdkFontPeer. */
522 cls = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GdkPixbufDecoder");
523 pixbufLoaderFID = (*env)->GetFieldID(env, cls, "nativeDecoder",
524 "Lgnu/classpath/Pointer;");
525 }
526
527 /**
528 * Sets the native font in the nativeFont field in GdkFontPeer.
529 *
530 * @param env the JNI environment
531 * @param pixbuf_dec the pixbuf decoder object
532 * @param pixbuf_loader the native pixbuf loader
533 */
gtkpeer_set_pixbuf_loader(JNIEnv * env,jobject pixbuf_dec,void * pixbuf_loader)534 void gtkpeer_set_pixbuf_loader(JNIEnv* env, jobject pixbuf_dec,
535 void* pixbuf_loader)
536 {
537 jobject obj;
538
539 /* Fetch the nativeDecoder field object. */
540 obj = (*env)->GetObjectField(env, pixbuf_dec, pixbufLoaderFID);
541 if (obj == NULL)
542 {
543 /* Create if necessary. */
544 #if SIZEOF_VOID_P == 8
545 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
546 (jlong) pixbuf_loader);
547 #else
548 obj = (*env)->NewObject(env, pointerClass, pointerConstructorMID,
549 (jint) pixbuf_loader);
550 #endif
551 (*env)->SetObjectField(env, pixbuf_dec, pixbufLoaderFID, obj);
552 }
553 else
554 {
555 #if SIZEOF_VOID_P == 8
556 (*env)->SetLongField(env, obj, pointerDataFID, (jlong) pixbuf_loader);
557 #else
558 (*env)->SetIntField(env, obj, pointerDataFID, (jint) pixbuf_loader);
559 #endif
560 }
561 }
562
563 /**
564 * Fetches the native pixbuf loader reference from the GdkPixbufDecoder object.
565 *
566 * @param env the JNI environment
567 * @param pixbuf_dec the pixbuf decoder object
568 *
569 * @return the native pixbuf loader
570 */
gtkpeer_get_pixbuf_loader(JNIEnv * env,jobject pixbuf_dec)571 void* gtkpeer_get_pixbuf_loader(JNIEnv* env, jobject pixbuf_dec)
572 {
573 jobject obj;
574 void *loader;
575
576 /* Fetch the nativeFont field from the peer object. */
577 obj = (*env)->GetObjectField(env, pixbuf_dec, pixbufLoaderFID);
578
579 /* Fetch actual font pointer. */
580 #if SIZEOF_VOID_P == 8
581 loader = (void*) (*env)->GetLongField(env, obj, pointerDataFID);
582 #else
583 loader = (void*) (*env)->GetIntField(env, obj, pointerDataFID);
584 #endif
585 return loader;
586 }
587