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