1 /*
2 * Copyright (c) 2004, 2018, 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 <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <dlfcn.h>
30
31 #include <jni.h>
32 #include <sizecalc.h>
33 #include "sun_awt_UNIXToolkit.h"
34
35 #ifndef HEADLESS
36 #include "awt.h"
37 #include "gtk_interface.h"
38 #endif /* !HEADLESS */
39
40
41 static jclass this_class = NULL;
42 static jmethodID icon_upcall_method = NULL;
43
44
45 /*
46 * Class: sun_awt_UNIXToolkit
47 * Method: check_gtk
48 * Signature: (I)Z
49 */
50 JNIEXPORT jboolean JNICALL
Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv * env,jclass klass,jint version)51 Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass, jint version) {
52 #ifndef HEADLESS
53 return (jboolean)gtk_check_version(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: (I)Z
64 */
65 JNIEXPORT jboolean JNICALL
Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv * env,jclass klass,jint version,jboolean verbose)66 Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv *env, jclass klass, jint version,
67 jboolean verbose) {
68 #ifndef HEADLESS
69 return (jboolean)gtk_load(env, version, verbose);
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
Java_sun_awt_UNIXToolkit_unload_1gtk(JNIEnv * env,jclass klass)82 Java_sun_awt_UNIXToolkit_unload_1gtk(JNIEnv *env, jclass klass)
83 {
84 #ifndef HEADLESS
85 return (jboolean)gtk->unload();
86 #else
87 return JNI_FALSE;
88 #endif /* !HEADLESS */
89 }
90
init_method(JNIEnv * env,jobject this)91 jboolean init_method(JNIEnv *env, jobject this)
92 {
93 if (this_class == NULL) {
94 this_class = (*env)->NewGlobalRef(env,
95 (*env)->GetObjectClass(env, this));
96 icon_upcall_method = (*env)->GetMethodID(env, this_class,
97 "loadIconCallback", "([BIIIIIZ)V");
98 CHECK_NULL_RETURN(icon_upcall_method, JNI_FALSE);
99 }
100
101 return JNI_TRUE;
102 }
103
104 /*
105 * Class: sun_awt_UNIXToolkit
106 * Method: load_gtk_icon
107 * Signature: (Ljava/lang/String)Z
108 *
109 * This method assumes that GTK libs are present.
110 */
111 JNIEXPORT jboolean JNICALL
Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv * env,jobject this,jstring filename)112 Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv *env, jobject this,
113 jstring filename)
114 {
115 #ifndef HEADLESS
116 int len;
117 char *filename_str = NULL;
118 GError **error = NULL;
119
120 if (filename == NULL)
121 {
122 return JNI_FALSE;
123 }
124
125 len = (*env)->GetStringUTFLength(env, filename);
126 filename_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc,
127 sizeof(char), len + 1);
128 if (filename_str == NULL) {
129 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
130 return JNI_FALSE;
131 }
132 if (!init_method(env, this) ) {
133 free(filename_str);
134 return JNI_FALSE;
135 }
136 (*env)->GetStringUTFRegion(env, filename, 0, len, filename_str);
137 jboolean result = gtk->get_file_icon_data(env, filename_str, error,
138 icon_upcall_method, this);
139
140 /* Release the strings we've allocated. */
141 free(filename_str);
142
143 return result;
144 #else /* HEADLESS */
145 return JNI_FALSE;
146 #endif /* !HEADLESS */
147 }
148
149 /*
150 * Class: sun_awt_UNIXToolkit
151 * Method: load_stock_icon
152 * Signature: (ILjava/lang/String;IILjava/lang/String;)Z
153 *
154 * This method assumes that GTK libs are present.
155 */
156 JNIEXPORT jboolean JNICALL
Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv * env,jobject this,jint widget_type,jstring stock_id,jint icon_size,jint text_direction,jstring detail)157 Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this,
158 jint widget_type, jstring stock_id, jint icon_size,
159 jint text_direction, jstring detail)
160 {
161 #ifndef HEADLESS
162 int len;
163 char *stock_id_str = NULL;
164 char *detail_str = NULL;
165
166 if (stock_id == NULL)
167 {
168 return JNI_FALSE;
169 }
170
171 len = (*env)->GetStringUTFLength(env, stock_id);
172 stock_id_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc,
173 sizeof(char), len + 1);
174 if (stock_id_str == NULL) {
175 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
176 return JNI_FALSE;
177 }
178 (*env)->GetStringUTFRegion(env, stock_id, 0, len, stock_id_str);
179
180 /* Detail isn't required so check for NULL. */
181 if (detail != NULL)
182 {
183 len = (*env)->GetStringUTFLength(env, detail);
184 detail_str = (char *)SAFE_SIZE_ARRAY_ALLOC(malloc,
185 sizeof(char), len + 1);
186 if (detail_str == NULL) {
187 free(stock_id_str);
188 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
189 return JNI_FALSE;
190 }
191 (*env)->GetStringUTFRegion(env, detail, 0, len, detail_str);
192 }
193
194 if (!init_method(env, this) ) {
195 return JNI_FALSE;
196 }
197 jboolean result = gtk->get_icon_data(env, widget_type, stock_id_str,
198 icon_size, text_direction, detail_str,
199 icon_upcall_method, this);
200
201 /* Release the strings we've allocated. */
202 free(stock_id_str);
203 if (detail_str != NULL)
204 {
205 free(detail_str);
206 }
207
208 return result;
209 #else /* HEADLESS */
210 return JNI_FALSE;
211 #endif /* !HEADLESS */
212 }
213
214 /*
215 * Class: sun_awt_UNIXToolkit
216 * Method: nativeSync
217 * Signature: ()V
218 */
219 JNIEXPORT void JNICALL
Java_sun_awt_UNIXToolkit_nativeSync(JNIEnv * env,jobject this)220 Java_sun_awt_UNIXToolkit_nativeSync(JNIEnv *env, jobject this)
221 {
222 #ifndef HEADLESS
223 AWT_LOCK();
224 XSync(awt_display, False);
225 AWT_UNLOCK();
226 #endif /* !HEADLESS */
227 }
228
229 /*
230 * Class: sun_awt_SunToolkit
231 * Method: closeSplashScreen
232 * Signature: ()V
233 */
234 JNIEXPORT void JNICALL
Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv * env,jclass cls)235 Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv *env, jclass cls)
236 {
237 typedef void (*SplashClose_t)();
238 SplashClose_t splashClose;
239 void* hSplashLib = dlopen(0, RTLD_LAZY);
240 if (!hSplashLib) {
241 return;
242 }
243 splashClose = (SplashClose_t)dlsym(hSplashLib,
244 "SplashClose");
245 if (splashClose) {
246 splashClose();
247 }
248 dlclose(hSplashLib);
249 }
250
251 /*
252 * Class: sun_awt_UNIXToolkit
253 * Method: gtkCheckVersionImpl
254 * Signature: (III)Ljava/lang/String;
255 */
256 JNIEXPORT jboolean JNICALL
Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl(JNIEnv * env,jobject this,jint major,jint minor,jint micro)257 Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl(JNIEnv *env, jobject this,
258 jint major, jint minor, jint micro)
259 {
260 char *ret;
261
262 ret = gtk->gtk_check_version(major, minor, micro);
263 if (ret == NULL) {
264 return TRUE;
265 }
266
267 return FALSE;
268 }
269
270 /*
271 * Class: sun_awt_UNIXToolkit
272 * Method: get_gtk_version
273 * Signature: ()I
274 */
275 JNIEXPORT jint JNICALL
Java_sun_awt_UNIXToolkit_get_1gtk_1version(JNIEnv * env,jclass klass)276 Java_sun_awt_UNIXToolkit_get_1gtk_1version(JNIEnv *env, jclass klass)
277 {
278 #ifndef HEADLESS
279 return gtk ? gtk->version : GTK_ANY;
280 #else
281 return GTK_ANY;
282 #endif /* !HEADLESS */
283 }
284