1 /* 2 * Copyright 2004-2006 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any 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 "sun_awt_UNIXToolkit.h" 33 34 #ifndef HEADLESS 35 #include "awt.h" 36 #include "gtk2_interface.h" 37 #endif /* !HEADLESS */ 38 39 40 static jclass this_class = NULL; 41 static jmethodID icon_upcall_method = NULL; 42 43 44 /* 45 * Class: sun_awt_UNIXToolkit 46 * Method: check_gtk 47 * Signature: ()Z 48 */ 49 JNIEXPORT jboolean JNICALL 50 Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass) 51 { 52 #ifndef HEADLESS 53 return (jboolean)gtk2_check_version(); 54 #else 55 return JNI_FALSE; 56 #endif /* !HEADLESS */ 57 } 58 59 60 /* 61 * Class: sun_awt_UNIXToolkit 62 * Method: load_gtk 63 * Signature: ()Z 64 */ 65 JNIEXPORT jboolean JNICALL 66 Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv *env, jclass klass) 67 { 68 #ifndef HEADLESS 69 return (jboolean)gtk2_load(); 70 #else 71 return JNI_FALSE; 72 #endif /* !HEADLESS */ 73 } 74 75 76 /* 77 * Class: sun_awt_UNIXToolkit 78 * Method: unload_gtk 79 * Signature: ()Z 80 */ 81 JNIEXPORT jboolean JNICALL 82 Java_sun_awt_UNIXToolkit_unload_1gtk(JNIEnv *env, jclass klass) 83 { 84 #ifndef HEADLESS 85 return (jboolean)gtk2_unload(); 86 #else 87 return JNI_FALSE; 88 #endif /* !HEADLESS */ 89 } 90 91 jboolean _icon_upcall(JNIEnv *env, jobject this, GdkPixbuf *pixbuf) 92 { 93 jboolean result = JNI_FALSE; 94 95 if (this_class == NULL) { 96 this_class = (*env)->NewGlobalRef(env, 97 (*env)->GetObjectClass(env, this)); 98 icon_upcall_method = (*env)->GetMethodID(env, this_class, 99 "loadIconCallback", "([BIIIIIZ)V"); 100 } 101 102 if (pixbuf != NULL) 103 { 104 guchar *pixbuf_data = (*fp_gdk_pixbuf_get_pixels)(pixbuf); 105 int row_stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf); 106 int width = (*fp_gdk_pixbuf_get_width)(pixbuf); 107 int height = (*fp_gdk_pixbuf_get_height)(pixbuf); 108 int bps = (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf); 109 int channels = (*fp_gdk_pixbuf_get_n_channels)(pixbuf); 110 gboolean alpha = (*fp_gdk_pixbuf_get_has_alpha)(pixbuf); 111 112 /* Copy the data array into a Java structure so we can pass it back. */ 113 jbyteArray data = (*env)->NewByteArray(env, (row_stride * height)); 114 (*env)->SetByteArrayRegion(env, data, 0, (row_stride * height), 115 pixbuf_data); 116 117 /* Release the pixbuf. */ 118 (*fp_g_object_unref)(pixbuf); 119 120 /* Call the callback method to create the image on the Java side. */ 121 (*env)->CallVoidMethod(env, this, icon_upcall_method, data, 122 width, height, row_stride, bps, channels, alpha); 123 result = JNI_TRUE; 124 } 125 return result; 126 } 127 128 /* 129 * Class: sun_awt_UNIXToolkit 130 * Method: load_gtk_icon 131 * Signature: (Ljava/lang/String)Z 132 * 133 * This method assumes that GTK libs are present. 134 */ 135 JNIEXPORT jboolean JNICALL 136 Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv *env, jobject this, 137 jstring filename) 138 { 139 #ifndef HEADLESS 140 int len; 141 char *filename_str = NULL; 142 GError **error = NULL; 143 GdkPixbuf *pixbuf; 144 145 if (filename == NULL) 146 { 147 return JNI_FALSE; 148 } 149 150 len = (*env)->GetStringUTFLength(env, filename); 151 filename_str = (char *)malloc(sizeof(char) * (len + 1)); 152 if (filename_str == NULL) { 153 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); 154 return JNI_FALSE; 155 } 156 (*env)->GetStringUTFRegion(env, filename, 0, len, filename_str); 157 pixbuf = (*fp_gdk_pixbuf_new_from_file)(filename_str, error); 158 159 /* Release the strings we've allocated. */ 160 free(filename_str); 161 162 return _icon_upcall(env, this, pixbuf); 163 #else /* HEADLESS */ 164 return JNI_FALSE; 165 #endif /* !HEADLESS */ 166 } 167 168 /* 169 * Class: sun_awt_UNIXToolkit 170 * Method: load_stock_icon 171 * Signature: (ILjava/lang/String;IILjava/lang/String;)Z 172 * 173 * This method assumes that GTK libs are present. 174 */ 175 JNIEXPORT jboolean JNICALL 176 Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this, 177 jint widget_type, jstring stock_id, jint icon_size, 178 jint text_direction, jstring detail) 179 { 180 #ifndef HEADLESS 181 int len; 182 char *stock_id_str = NULL; 183 char *detail_str = NULL; 184 GdkPixbuf *pixbuf; 185 186 if (stock_id == NULL) 187 { 188 return JNI_FALSE; 189 } 190 191 len = (*env)->GetStringUTFLength(env, stock_id); 192 stock_id_str = (char *)malloc(sizeof(char) * (len + 1)); 193 if (stock_id_str == NULL) { 194 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); 195 return JNI_FALSE; 196 } 197 (*env)->GetStringUTFRegion(env, stock_id, 0, len, stock_id_str); 198 199 /* Detail isn't required so check for NULL. */ 200 if (detail != NULL) 201 { 202 len = (*env)->GetStringUTFLength(env, detail); 203 detail_str = (char *)malloc(sizeof(char) * (len + 1)); 204 if (detail_str == NULL) { 205 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); 206 return JNI_FALSE; 207 } 208 (*env)->GetStringUTFRegion(env, detail, 0, len, detail_str); 209 } 210 211 pixbuf = gtk2_get_stock_icon(widget_type, stock_id_str, icon_size, 212 text_direction, detail_str); 213 214 /* Release the strings we've allocated. */ 215 free(stock_id_str); 216 if (detail_str != NULL) 217 { 218 free(detail_str); 219 } 220 221 return _icon_upcall(env, this, pixbuf); 222 #else /* HEADLESS */ 223 return JNI_FALSE; 224 #endif /* !HEADLESS */ 225 } 226 227 /* 228 * Class: sun_awt_UNIXToolkit 229 * Method: nativeSync 230 * Signature: ()V 231 */ 232 JNIEXPORT void JNICALL 233 Java_sun_awt_UNIXToolkit_nativeSync(JNIEnv *env, jobject this) 234 { 235 #ifndef HEADLESS 236 AWT_LOCK(); 237 XSync(awt_display, False); 238 AWT_UNLOCK(); 239 #endif /* !HEADLESS */ 240 } 241 242 /* 243 * Class: sun_awt_SunToolkit 244 * Method: closeSplashScreen 245 * Signature: ()V 246 */ 247 JNIEXPORT void JNICALL 248 Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv *env, jclass cls) 249 { 250 typedef void (*SplashClose_t)(); 251 SplashClose_t splashClose; 252 void* hSplashLib = dlopen(0, RTLD_LAZY); 253 if (!hSplashLib) { 254 return; 255 } 256 splashClose = (SplashClose_t)dlsym(hSplashLib, 257 "SplashClose"); 258 if (splashClose) { 259 splashClose(); 260 } 261 dlclose(hSplashLib); 262 } 263 264 /* 265 * Class: sun_awt_UNIXToolkit 266 * Method: gtkCheckVersionImpl 267 * Signature: (III)Ljava/lang/String; 268 */ 269 JNIEXPORT jboolean JNICALL 270 Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl(JNIEnv *env, jobject this, 271 jint major, jint minor, jint micro) 272 { 273 char *ret; 274 275 ret = fp_gtk_check_version(major, minor, micro); 276 if (ret == NULL) { 277 return TRUE; 278 } 279 280 free(ret); 281 return FALSE; 282 }