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