1 /* 2 * Copyright (c) 2005, 2016, 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 #include <dlfcn.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include "jvm_md.h" 29 #include "gtk_interface.h" 30 31 GtkApi* gtk2_load(JNIEnv *env, const char* lib_name); 32 GtkApi* gtk3_load(JNIEnv *env, const char* lib_name); 33 34 gboolean gtk2_check(const char* lib_name); 35 gboolean gtk3_check(const char* lib_name); 36 37 GtkApi *gtk; 38 39 typedef struct { 40 GtkVersion version; 41 const char* name; 42 const char* vname; 43 GtkApi* (*load)(JNIEnv *env, const char* lib_name); 44 gboolean (*check)(const char* lib_name); 45 } GtkLib; 46 47 static GtkLib libs[] = { 48 { 49 GTK_2, 50 JNI_LIB_NAME("gtk-x11-2.0"), 51 VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"), 52 >k2_load, 53 >k2_check 54 }, 55 { 56 GTK_3, 57 JNI_LIB_NAME("gtk-3"), 58 VERSIONED_JNI_LIB_NAME("gtk-3", "0"), 59 >k3_load, 60 >k3_check 61 }, 62 { 63 0, 64 NULL, 65 NULL, 66 NULL, 67 NULL 68 } 69 }; 70 71 static gboolean isLoadedLib(const char *lib_name) { 72 FILE* fp = fopen("/proc/self/maps", "r"); 73 if (!fp) { 74 return FALSE; 75 } 76 char line[512]; 77 while (fgets(line, 512, fp) != NULL) 78 { 79 if (strstr(line, lib_name)) { 80 fclose(fp); 81 return TRUE; 82 } 83 } 84 fclose(fp); 85 return FALSE; 86 } 87 88 static GtkLib* get_loaded() { 89 GtkLib* lib = libs; 90 while(!gtk && lib->version) { 91 if (isLoadedLib(lib->vname)) { 92 return lib; 93 } 94 if (isLoadedLib(lib->name)) { 95 return lib; 96 } 97 lib++; 98 } 99 return NULL; 100 } 101 102 gboolean gtk_load(JNIEnv *env, GtkVersion version, gboolean verbose) { 103 if (gtk == NULL) { 104 GtkLib* lib = get_loaded(); 105 if (lib) { 106 if (verbose) { 107 fprintf(stderr,"%s is already loaded\n",lib->name); 108 } 109 if (version != GTK_ANY && lib->version != version) { 110 if (verbose) { 111 fprintf(stderr, "WARNING: Cannot load GTK%d library: \ 112 GTK%d has already been loaded\n", version, lib->version); 113 } 114 return FALSE; 115 } 116 if (verbose) { 117 fprintf(stderr, "Looking for GTK%d library...\n", lib->version); 118 } 119 gtk = lib->load(env, lib->vname); 120 if (!gtk) { 121 gtk = lib->load(env, lib->name); 122 } 123 } else { 124 lib = libs; 125 while (!gtk && lib->version) { 126 if (version == GTK_ANY || lib->version == version) { 127 if (verbose) { 128 fprintf(stderr, "Looking for GTK%d library...\n", 129 lib->version); 130 } 131 gtk = lib->load(env, lib->vname); 132 if (!gtk) { 133 gtk = lib->load(env, lib->name); 134 } 135 if (verbose && !gtk) { 136 fprintf(stderr, "Not found.\n"); 137 } 138 } 139 lib++; 140 } 141 lib--; 142 } 143 if (verbose) { 144 if (gtk) { 145 fprintf(stderr, "GTK%d library loaded.\n", lib->version); 146 } else { 147 fprintf(stderr, "Failed to load GTK library.\n"); 148 } 149 } 150 } 151 return gtk != NULL; 152 } 153 154 static gboolean check_version(GtkVersion version) { 155 GtkLib* lib = libs; 156 while (lib->version) { 157 if (version == GTK_ANY || lib->version == version) { 158 if (lib->check(lib->vname)) { 159 return TRUE; 160 } 161 if (lib->check(lib->name)) { 162 return TRUE; 163 } 164 } 165 lib++; 166 } 167 return FALSE; 168 } 169 170 gboolean gtk_check_version(GtkVersion version) { 171 if (gtk) { 172 return TRUE; 173 } 174 GtkLib* lib; 175 if (lib = get_loaded()) { 176 return lib->check(lib->vname) || lib->check(lib->name); 177 } 178 return check_version(version); 179 }