1 /* 2 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 29 #include <dlfcn.h> 30 31 #include <jni.h> 32 #include <sizecalc.h> 33 #include "sun_awt_UNIXToolkit.h" 34 35 #ifndef HEADLESS 36 #include "awt.h" 37 #include "gtk2_interface.h" 38 #endif /* !HEADLESS */ 39 40 41 static jclass this_class = NULL; 42 static jmethodID icon_upcall_method = NULL; 43 44 45 /* 46 * Class: sun_awt_UNIXToolkit 47 * Method: check_gtk 48 * Signature: ()Z 49 */ 50 JNIEXPORT jboolean JNICALL 51 Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass) 52 { 53 #ifndef HEADLESS 54 return (jboolean)gtk2_check_version(); 55 #else 56 return JNI_FALSE; 57 #endif /* !HEADLESS */ 58 } 59 60 61 /* 62 * Class: sun_awt_UNIXToolkit 63 * Method: load_gtk 64 * Signature: ()Z 65 */ 66 JNIEXPORT jboolean JNICALL 67 Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv *env, jclass klass) 68 { 69 #ifndef HEADLESS 70 return (jboolean)gtk2_load(); 71 #else 72 return JNI_FALSE; 73 #endif /* !HEADLESS */ 74 } 75 76 77 /* 78 * Class: sun_awt_UNIXToolkit 79 * Method: unload_gtk 80 * Signature: ()Z 81 */ 82 JNIEXPORT jboolean JNICALL 83 Java_sun_awt_UNIXToolkit_unload_1gtk(JNIEnv *env, jclass klass) 84 { 85 #ifndef HEADLESS 86 return (jboolean)gtk2_unload(); 87 #else 88 return JNI_FALSE; 89 #endif /* !HEADLESS */ 90 } 91 92 jboolean _icon_upcall(JNIEnv *env, jobject this, GdkPixbuf *pixbuf) 93 { 94 jboolean result = JNI_FALSE; 95 96 if (this_class == NULL) { 97 this_class = (*env)->NewGlobalRef(env, 98 (*env)->GetObjectClass(env, this)); 99 icon_upcall_method = (*env)->GetMethodID(env, this_class, 100 "loadIconCallback", "([BIIIIIZ)V"); 101 } 102 103 if (pixbuf != NULL) 104 { 105 guchar *pixbuf_data = (*fp_gdk_pixbuf_get_pixels)(pixbuf); 106 int row_stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf); 107 int width = (*fp_gdk_pixbuf_get_width)(pixbuf); 108 int height = (*fp_gdk_pixbuf_get_height)(pixbuf); 109 int bps = (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf); 110 int channels = (*fp_gdk_pixbuf_get_n_channels)(pixbuf); 111 gboolean alpha = (*fp_gdk_pixbuf_get_has_alpha)(pixbuf); 112 113 /* Copy the data array into a Java structure so we can pass it back. */ 114 jbyteArray data = (*env)->NewByteArray(env, (row_stride * height)); 115 (*env)->SetByteArrayRegion(env, data, 0, (row_stride * height), 116 (jbyte *)pixbuf_data); 117 118 /* Release the pixbuf. */ 119 (*fp_g_object_unref)(pixbuf); 120 121 /* Call the callback method to create the image on the Java side. */ 122 (*env)->CallVoidMethod(env, this, icon_upcall_method, data, 123 width, height, row_stride, bps, channels, alpha); 124 result = JNI_TRUE; 125 } 126 return result; 127 } 128 129 /* 130 * Class: sun_awt_UNIXToolkit 131 * Method: load_gtk_icon 132 * Signature: (Ljava/lang/String)Z 133 * 134 * This method assumes that GTK libs are present. 135 */ 136 JNIEXPORT jboolean JNICALL 137 Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv *env, jobject this, 138 jstring filename) 139 { 140 #ifndef HEADLESS 141 int len; 142 char *filename_str = NULL; 143 GError **error = NULL; 144 GdkPixbuf *pixbuf; 145 146 if (filename == NULL) 147 { 148 return JNI_FALSE; 149 } 150 151 len = (*env)->GetStringUTFLength(env, filename); 152 filename_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc, 153 sizeof(char), len + 1); 154 if (filename_str == NULL) { 155 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); 156 return JNI_FALSE; 157 } 158 (*env)->GetStringUTFRegion(env, filename, 0, len, filename_str); 159 pixbuf = (*fp_gdk_pixbuf_new_from_file)(filename_str, error); 160 161 /* Release the strings we've allocated. */ 162 free(filename_str); 163 164 return _icon_upcall(env, this, pixbuf); 165 #else /* HEADLESS */ 166 return JNI_FALSE; 167 #endif /* !HEADLESS */ 168 } 169 170 /* 171 * Class: sun_awt_UNIXToolkit 172 * Method: load_stock_icon 173 * Signature: (ILjava/lang/String;IILjava/lang/String;)Z 174 * 175 * This method assumes that GTK libs are present. 176 */ 177 JNIEXPORT jboolean JNICALL 178 Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this, 179 jint widget_type, jstring stock_id, jint icon_size, 180 jint text_direction, jstring detail) 181 { 182 #ifndef HEADLESS 183 int len; 184 char *stock_id_str = NULL; 185 char *detail_str = NULL; 186 GdkPixbuf *pixbuf; 187 188 if (stock_id == NULL) 189 { 190 return JNI_FALSE; 191 } 192 193 len = (*env)->GetStringUTFLength(env, stock_id); 194 stock_id_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc, 195 sizeof(char), len + 1); 196 if (stock_id_str == NULL) { 197 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); 198 return JNI_FALSE; 199 } 200 (*env)->GetStringUTFRegion(env, stock_id, 0, len, stock_id_str); 201 202 /* Detail isn't required so check for NULL. */ 203 if (detail != NULL) 204 { 205 len = (*env)->GetStringUTFLength(env, detail); 206 detail_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc, 207 sizeof(char), len + 1); 208 if (detail_str == NULL) { 209 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); 210 return JNI_FALSE; 211 } 212 (*env)->GetStringUTFRegion(env, detail, 0, len, detail_str); 213 } 214 215 pixbuf = gtk2_get_stock_icon(widget_type, stock_id_str, icon_size, 216 text_direction, detail_str); 217 218 /* Release the strings we've allocated. */ 219 free(stock_id_str); 220 if (detail_str != NULL) 221 { 222 free(detail_str); 223 } 224 225 return _icon_upcall(env, this, pixbuf); 226 #else /* HEADLESS */ 227 return JNI_FALSE; 228 #endif /* !HEADLESS */ 229 } 230 231 /* 232 * Class: sun_awt_UNIXToolkit 233 * Method: nativeSync 234 * Signature: ()V 235 */ 236 JNIEXPORT void JNICALL 237 Java_sun_awt_UNIXToolkit_nativeSync(JNIEnv *env, jobject this) 238 { 239 #ifndef HEADLESS 240 AWT_LOCK(); 241 XSync(awt_display, False); 242 AWT_UNLOCK(); 243 #endif /* !HEADLESS */ 244 } 245 246 /* 247 * Class: sun_awt_SunToolkit 248 * Method: closeSplashScreen 249 * Signature: ()V 250 */ 251 JNIEXPORT void JNICALL 252 Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv *env, jclass cls) 253 { 254 typedef void (*SplashClose_t)(); 255 SplashClose_t splashClose; 256 void* hSplashLib = dlopen(0, RTLD_LAZY); 257 if (!hSplashLib) { 258 return; 259 } 260 splashClose = (SplashClose_t)dlsym(hSplashLib, 261 "SplashClose"); 262 if (splashClose) { 263 splashClose(); 264 } 265 dlclose(hSplashLib); 266 } 267 268 /* 269 * Class: sun_awt_UNIXToolkit 270 * Method: gtkCheckVersionImpl 271 * Signature: (III)Ljava/lang/String; 272 */ 273 JNIEXPORT jboolean JNICALL 274 Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl(JNIEnv *env, jobject this, 275 jint major, jint minor, jint micro) 276 { 277 char *ret; 278 279 ret = fp_gtk_check_version(major, minor, micro); 280 if (ret == NULL) { 281 return TRUE; 282 } 283 284 free(ret); 285 return FALSE; 286 }