1 /* 2 * Copyright (c) 2000, 2005, 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 <stdio.h> 27 #include <dlfcn.h> 28 #include <string.h> 29 #include <stdlib.h> 30 #include <jni.h> 31 #include <jni_util.h> 32 #include <jvm.h> 33 #include "gdefs.h" 34 35 #include <sys/param.h> 36 #include <sys/utsname.h> 37 38 #include "awt_Plugin.h" 39 40 #ifdef AIX 41 #include "porting_aix.h" /* For the 'dladdr' function. */ 42 #endif 43 44 #ifdef DEBUG 45 #define VERBOSE_AWT_DEBUG 46 #endif 47 48 static void *awtHandle = NULL; 49 50 typedef jint JNICALL JNI_OnLoad_type(JavaVM *vm, void *reserved); 51 52 /* Initialize the Java VM instance variable when the library is 53 first loaded */ 54 JavaVM *jvm; 55 56 JNIEXPORT jboolean JNICALL AWTIsHeadless() { 57 static JNIEnv *env = NULL; 58 static jboolean isHeadless; 59 jmethodID headlessFn; 60 jclass graphicsEnvClass; 61 62 if (env == NULL) { 63 env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 64 graphicsEnvClass = (*env)->FindClass(env, 65 "java/awt/GraphicsEnvironment"); 66 if (graphicsEnvClass == NULL) { 67 return JNI_TRUE; 68 } 69 headlessFn = (*env)->GetStaticMethodID(env, 70 graphicsEnvClass, "isHeadless", "()Z"); 71 if (headlessFn == NULL) { 72 return JNI_TRUE; 73 } 74 isHeadless = (*env)->CallStaticBooleanMethod(env, graphicsEnvClass, 75 headlessFn); 76 } 77 return isHeadless; 78 } 79 80 /* 81 * Pathnames to the various awt toolkits 82 */ 83 84 85 #ifdef MACOSX 86 #define LWAWT_PATH "/libawt_lwawt.dylib" 87 #define DEFAULT_PATH LWAWT_PATH 88 #else 89 #define XAWT_PATH "/libawt_xawt.so" 90 #define DEFAULT_PATH XAWT_PATH 91 #define HEADLESS_PATH "/libawt_headless.so" 92 #endif 93 94 jint 95 AWT_OnLoad(JavaVM *vm, void *reserved) 96 { 97 Dl_info dlinfo; 98 char buf[MAXPATHLEN]; 99 int32_t len; 100 char *p, *tk; 101 JNI_OnLoad_type *JNI_OnLoad_ptr; 102 struct utsname name; 103 JNIEnv *env = (JNIEnv *)JNU_GetEnv(vm, JNI_VERSION_1_2); 104 void *v; 105 jstring fmanager = NULL; 106 jstring fmProp = NULL; 107 108 if (awtHandle != NULL) { 109 /* Avoid several loading attempts */ 110 return JNI_VERSION_1_2; 111 } 112 113 jvm = vm; 114 115 /* Get address of this library and the directory containing it. */ 116 dladdr((void *)JNI_OnLoad, &dlinfo); 117 realpath((char *)dlinfo.dli_fname, buf); 118 len = strlen(buf); 119 p = strrchr(buf, '/'); 120 121 /* 122 * The code below is responsible for: 123 * 1. Loading appropriate awt library, i.e. libawt_xawt or libawt_headless 124 * 2. Set the "sun.font.fontmanager" system property. 125 */ 126 127 fmProp = (*env)->NewStringUTF(env, "sun.font.fontmanager"); 128 #ifdef MACOSX 129 fmanager = (*env)->NewStringUTF(env, "sun.font.CFontManager"); 130 tk = LWAWT_PATH; 131 #else 132 fmanager = (*env)->NewStringUTF(env, "sun.awt.X11FontManager"); 133 tk = XAWT_PATH; 134 #endif 135 if (fmanager && fmProp) { 136 JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "setProperty", 137 "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", 138 fmProp, fmanager); 139 } 140 141 #ifndef MACOSX 142 if (AWTIsHeadless()) { 143 tk = HEADLESS_PATH; 144 } 145 #endif 146 147 /* Calculate library name to load */ 148 strncpy(p, tk, MAXPATHLEN-len-1); 149 150 if (fmProp) { 151 (*env)->DeleteLocalRef(env, fmProp); 152 } 153 if (fmanager) { 154 (*env)->DeleteLocalRef(env, fmanager); 155 } 156 157 JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "load", 158 "(Ljava/lang/String;)V", 159 JNU_NewStringPlatform(env, buf)); 160 161 awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); 162 163 return JNI_VERSION_1_2; 164 } 165 166 JNIEXPORT jint JNICALL 167 JNI_OnLoad(JavaVM *vm, void *reserved) 168 { 169 return AWT_OnLoad(vm, reserved); 170 } 171 172 /* 173 * This entry point must remain in libawt.so as part of a contract 174 * with the CDE variant of Java Media Framework. (sdtjmplay) 175 * Reflect this call over to the correct libawt_<toolkit>.so. 176 */ 177 JNIEXPORT void JNICALL 178 Java_sun_awt_motif_XsessionWMcommand(JNIEnv *env, jobject this, 179 jobject frame, jstring jcommand) 180 { 181 /* type of the old backdoor function */ 182 typedef void JNICALL 183 XsessionWMcommand_type(JNIEnv *env, jobject this, 184 jobject frame, jstring jcommand); 185 186 static XsessionWMcommand_type *XsessionWMcommand = NULL; 187 188 if (XsessionWMcommand == NULL && awtHandle == NULL) { 189 return; 190 } 191 192 XsessionWMcommand = (XsessionWMcommand_type *) 193 dlsym(awtHandle, "Java_sun_awt_motif_XsessionWMcommand"); 194 195 if (XsessionWMcommand == NULL) 196 return; 197 198 (*XsessionWMcommand)(env, this, frame, jcommand); 199 } 200 201 202 /* 203 * This entry point must remain in libawt.so as part of a contract 204 * with the CDE variant of Java Media Framework. (sdtjmplay) 205 * Reflect this call over to the correct libawt_<toolkit>.so. 206 */ 207 JNIEXPORT void JNICALL 208 Java_sun_awt_motif_XsessionWMcommand_New(JNIEnv *env, jobjectArray jargv) 209 { 210 typedef void JNICALL 211 XsessionWMcommand_New_type(JNIEnv *env, jobjectArray jargv); 212 213 static XsessionWMcommand_New_type *XsessionWMcommand = NULL; 214 215 if (XsessionWMcommand == NULL && awtHandle == NULL) { 216 return; 217 } 218 219 XsessionWMcommand = (XsessionWMcommand_New_type *) 220 dlsym(awtHandle, "Java_sun_awt_motif_XsessionWMcommand_New"); 221 222 if (XsessionWMcommand == NULL) 223 return; 224 225 (*XsessionWMcommand)(env, jargv); 226 } 227 228 229 #define REFLECT_VOID_FUNCTION(name, arglist, paramlist) \ 230 typedef name##_type arglist; \ 231 void name arglist \ 232 { \ 233 static name##_type *name##_ptr = NULL; \ 234 if (name##_ptr == NULL && awtHandle == NULL) { \ 235 return; \ 236 } \ 237 name##_ptr = (name##_type *) \ 238 dlsym(awtHandle, #name); \ 239 if (name##_ptr == NULL) { \ 240 return; \ 241 } \ 242 (*name##_ptr)paramlist; \ 243 } 244 245 #define REFLECT_FUNCTION(return_type, name, arglist, paramlist) \ 246 typedef return_type name##_type arglist; \ 247 return_type name arglist \ 248 { \ 249 static name##_type *name##_ptr = NULL; \ 250 if (name##_ptr == NULL && awtHandle == NULL) { \ 251 return NULL; \ 252 } \ 253 name##_ptr = (name##_type *) \ 254 dlsym(awtHandle, #name); \ 255 if (name##_ptr == NULL) { \ 256 return NULL; \ 257 } \ 258 return (*name##_ptr)paramlist; \ 259 } 260 261 262 /* 263 * These entry point must remain in libawt.so ***for Java Plugin ONLY*** 264 * Reflect this call over to the correct libawt_<toolkit>.so. 265 */ 266 267 REFLECT_VOID_FUNCTION(getAwtLockFunctions, 268 (void (**AwtLock)(JNIEnv *), void (**AwtUnlock)(JNIEnv *), 269 void (**AwtNoFlushUnlock)(JNIEnv *), void *reserved), 270 (AwtLock, AwtUnlock, AwtNoFlushUnlock, reserved)) 271 272 REFLECT_VOID_FUNCTION(getAwtData, 273 (int32_t *awt_depth, Colormap *awt_cmap, Visual **awt_visual, 274 int32_t *awt_num_colors, void *pReserved), 275 (awt_depth, awt_cmap, awt_visual, 276 awt_num_colors, pReserved)) 277 278 REFLECT_FUNCTION(Display *, getAwtDisplay, (void), ())