1 /*
   2  * Copyright (c) 2005, 2019, 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 "gtk_interface.h"
  29 #include "com_sun_java_swing_plaf_gtk_GTKEngine.h"
  30 
  31 /* Static buffer for conversion from java.lang.String to UTF-8 */
  32 static char conversionBuffer[(CONV_BUFFER_SIZE - 1) * 3 + 1];
  33 
  34 const char *getStrFor(JNIEnv *env, jstring val)
  35 {
  36     int length = (*env)->GetStringLength(env, val);
  37     if (length > CONV_BUFFER_SIZE-1)
  38     {
  39         length = CONV_BUFFER_SIZE-1;
  40     }
  41 
  42     memset(conversionBuffer, 0, sizeof(conversionBuffer));
  43     (*env)->GetStringUTFRegion(env, val, 0, length, conversionBuffer);
  44     return conversionBuffer;
  45 }
  46 
  47 /*
  48  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
  49  * Method:    native_paint_arrow
  50  * Signature: (IIILjava/lang/String;IIIII)V
  51  */
  52 JNIEXPORT void JNICALL
  53 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow(
  54         JNIEnv *env, jobject this,
  55         jint widget_type, jint state, jint shadow_type, jstring detail,
  56         jint x, jint y, jint w, jint h, jint arrow_type)
  57 {
  58     gtk->gdk_threads_enter();
  59     gtk->paint_arrow(widget_type, state, shadow_type, getStrFor(env, detail),
  60             x, y, w, h, arrow_type, TRUE);
  61     gtk->gdk_threads_leave();
  62 }
  63 
  64 /*
  65  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
  66  * Method:    native_paint_box
  67  * Signature: (IIILjava/lang/String;IIIIII)V
  68  */
  69 JNIEXPORT void JNICALL
  70 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box(
  71         JNIEnv *env, jobject this,
  72         jint widget_type, jint state, jint shadow_type, jstring detail,
  73         jint x, jint y, jint w, jint h,
  74         jint synth_state, jint dir)
  75 {
  76     gtk->gdk_threads_enter();
  77     gtk->paint_box(widget_type, state, shadow_type, getStrFor(env, detail),
  78                    x, y, w, h, synth_state, dir);
  79     gtk->gdk_threads_leave();
  80 }
  81 
  82 /*
  83  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
  84  * Method:    native_paint_box_gap
  85  * Signature: (IIILjava/lang/String;IIIIIII)V
  86  */
  87 JNIEXPORT void JNICALL
  88 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box_1gap(
  89         JNIEnv *env, jobject this,
  90         jint widget_type, jint state, jint shadow_type, jstring detail,
  91         jint x, jint y, jint w, jint h,
  92         jint gap_side, jint gap_x, jint gap_w)
  93 {
  94     gtk->gdk_threads_enter();
  95     gtk->paint_box_gap(widget_type, state, shadow_type, getStrFor(env, detail),
  96             x, y, w, h, gap_side, gap_x, gap_w);
  97     gtk->gdk_threads_leave();
  98 }
  99 
 100 /*
 101  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 102  * Method:    native_paint_check
 103  * Signature: (IILjava/lang/String;IIII)V
 104  */
 105 JNIEXPORT void JNICALL
 106 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1check(
 107         JNIEnv *env, jobject this,
 108         jint widget_type, jint synth_state, jstring detail,
 109         jint x, jint y, jint w, jint h)
 110 {
 111     gtk->gdk_threads_enter();
 112     gtk->paint_check(widget_type, synth_state, getStrFor(env, detail),
 113                      x, y, w, h);
 114     gtk->gdk_threads_leave();
 115 }
 116 
 117 /*
 118  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 119  * Method:    native_paint_expander
 120  * Signature: (IILjava/lang/String;IIIII)V
 121  */
 122 JNIEXPORT void JNICALL
 123 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1expander(
 124         JNIEnv *env, jobject this,
 125         jint widget_type, jint state, jstring detail,
 126         jint x, jint y, jint w, jint h, jint expander_style)
 127 {
 128     gtk->gdk_threads_enter();
 129     gtk->paint_expander(widget_type, state, getStrFor(env, detail),
 130             x, y, w, h, expander_style);
 131     gtk->gdk_threads_leave();
 132 }
 133 
 134 /*
 135  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 136  * Method:    native_paint_extension
 137  * Signature: (IIILjava/lang/String;IIIII)V
 138  */
 139 JNIEXPORT void JNICALL
 140 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1extension(
 141         JNIEnv *env, jobject this,
 142         jint widget_type, jint state, jint shadow_type, jstring detail,
 143         jint x, jint y, jint w, jint h, jint placement)
 144 {
 145     gtk->gdk_threads_enter();
 146     gtk->paint_extension(widget_type, state, shadow_type,
 147             getStrFor(env, detail), x, y, w, h, placement);
 148     gtk->gdk_threads_leave();
 149 }
 150 
 151 /*
 152  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 153  * Method:    native_paint_flat_box
 154  * Signature: (IIILjava/lang/String;IIII)V
 155  */
 156 JNIEXPORT void JNICALL
 157 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1flat_1box(
 158         JNIEnv *env, jobject this,
 159         jint widget_type, jint state, jint shadow_type, jstring detail,
 160         jint x, jint y, jint w, jint h, jboolean has_focus)
 161 {
 162     gtk->gdk_threads_enter();
 163     gtk->paint_flat_box(widget_type, state, shadow_type,
 164             getStrFor(env, detail), x, y, w, h, has_focus);
 165     gtk->gdk_threads_leave();
 166 }
 167 
 168 /*
 169  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 170  * Method:    native_paint_focus
 171  * Signature: (IILjava/lang/String;IIII)V
 172  */
 173 JNIEXPORT void JNICALL
 174 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1focus(
 175         JNIEnv *env, jobject this,
 176         jint widget_type, jint state, jstring detail,
 177         jint x, jint y, jint w, jint h)
 178 {
 179     gtk->gdk_threads_enter();
 180     gtk->paint_focus(widget_type, state, getStrFor(env, detail),
 181             x, y, w, h);
 182     gtk->gdk_threads_leave();
 183 }
 184 
 185 /*
 186  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 187  * Method:    native_paint_handle
 188  * Signature: (IIILjava/lang/String;IIIII)V
 189  */
 190 JNIEXPORT void JNICALL
 191 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1handle(
 192         JNIEnv *env, jobject this,
 193         jint widget_type, jint state, jint shadow_type, jstring detail,
 194         jint x, jint y, jint w, jint h, jint orientation)
 195 {
 196     gtk->gdk_threads_enter();
 197     gtk->paint_handle(widget_type, state, shadow_type, getStrFor(env, detail),
 198             x, y, w, h, orientation);
 199     gtk->gdk_threads_leave();
 200 }
 201 
 202 /*
 203  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 204  * Method:    native_paint_hline
 205  * Signature: (IILjava/lang/String;IIII)V
 206  */
 207 JNIEXPORT void JNICALL
 208 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1hline(
 209         JNIEnv *env, jobject this,
 210         jint widget_type, jint state, jstring detail,
 211         jint x, jint y, jint w, jint h)
 212 {
 213     gtk->gdk_threads_enter();
 214     gtk->paint_hline(widget_type, state, getStrFor(env, detail),
 215             x, y, w, h);
 216     gtk->gdk_threads_leave();
 217 }
 218 
 219 /*
 220  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 221  * Method:    native_paint_option
 222  * Signature: (IILjava/lang/String;IIII)V
 223  */
 224 JNIEXPORT void JNICALL
 225 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1option(
 226         JNIEnv *env, jobject this,
 227         jint widget_type, jint synth_state, jstring detail,
 228         jint x, jint y, jint w, jint h)
 229 {
 230     gtk->gdk_threads_enter();
 231     gtk->paint_option(widget_type, synth_state, getStrFor(env, detail),
 232                       x, y, w, h);
 233     gtk->gdk_threads_leave();
 234 }
 235 
 236 /*
 237  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 238  * Method:    native_paint_shadow
 239  * Signature: (IIILjava/lang/String;IIIIII)V
 240  */
 241 JNIEXPORT void JNICALL
 242 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1shadow(
 243         JNIEnv *env, jobject this,
 244         jint widget_type, jint state, jint shadow_type, jstring detail,
 245         jint x, jint y, jint w, jint h,
 246         jint synth_state, jint dir)
 247 {
 248     gtk->gdk_threads_enter();
 249     gtk->paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail),
 250                       x, y, w, h, synth_state, dir);
 251     gtk->gdk_threads_leave();
 252 }
 253 
 254 /*
 255  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 256  * Method:    native_paint_slider
 257  * Signature: (IIILjava/lang/String;IIIII)V
 258  */
 259 JNIEXPORT void JNICALL
 260 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1slider(
 261         JNIEnv *env, jobject this,
 262         jint widget_type, jint state, jint shadow_type, jstring detail,
 263         jint x, jint y, jint w, jint h, jint orientation, jboolean has_focus)
 264 {
 265     gtk->gdk_threads_enter();
 266     gtk->paint_slider(widget_type, state, shadow_type, getStrFor(env, detail),
 267             x, y, w, h, orientation, has_focus);
 268     gtk->gdk_threads_leave();
 269 }
 270 
 271 /*
 272  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 273  * Method:    native_paint_vline
 274  * Signature: (IILjava/lang/String;IIII)V
 275  */
 276 JNIEXPORT void JNICALL
 277 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1vline(
 278         JNIEnv *env, jobject this,
 279         jint widget_type, jint state, jstring detail,
 280         jint x, jint y, jint w, jint h)
 281 {
 282     gtk->gdk_threads_enter();
 283     gtk->paint_vline(widget_type, state, getStrFor(env, detail),
 284             x, y, w, h);
 285     gtk->gdk_threads_leave();
 286 }
 287 
 288 /*
 289  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 290  * Method:    native_paint_background
 291  * Signature: (IIIIII)V
 292  */
 293 JNIEXPORT void JNICALL
 294 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1background(
 295         JNIEnv *env, jobject this, jint widget_type, jint state,
 296         jint x, jint y, jint w, jint h)
 297 {
 298     gtk->gdk_threads_enter();
 299     gtk->paint_background(widget_type, state, x, y, w, h);
 300     gtk->gdk_threads_leave();
 301 }
 302 
 303 /*
 304  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 305  * Method:    nativeStartPainting
 306  * Signature: (II)V
 307  */
 308 JNIEXPORT void JNICALL
 309 Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeStartPainting(
 310         JNIEnv *env, jobject this, jint w, jint h)
 311 {
 312     gtk->gdk_threads_enter();
 313     gtk->init_painting(env, w, h);
 314     gtk->gdk_threads_leave();
 315 }
 316 
 317 /*
 318  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 319  * Method:    nativeFinishPainting
 320  * Signature: ([III)I
 321  */
 322 JNIEXPORT jint JNICALL
 323 Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeFinishPainting(
 324         JNIEnv *env, jobject this, jintArray dest, jint width, jint height)
 325 {
 326     jint transparency;
 327     gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0);
 328     gtk->gdk_threads_enter();
 329     transparency = gtk->copy_image(buffer, width, height);
 330     gtk->gdk_threads_leave();
 331     (*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0);
 332     return transparency;
 333 }
 334 
 335 /*
 336  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 337  * Method:    native_switch_theme
 338  * Signature: ()V
 339  */
 340 JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch_1theme(
 341         JNIEnv *env, jobject this)
 342 {
 343     // Note that flush_gtk_event_loop takes care of locks (7053002)
 344     gtk->gdk_threads_enter();
 345     gtk->flush_event_loop();
 346     gtk->gdk_threads_leave();
 347 }
 348 
 349 /*
 350  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 351  * Method:    native_get_gtk_setting
 352  * Signature: (I)Ljava/lang/Object;
 353  */
 354 JNIEXPORT jobject JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1get_1gtk_1setting(
 355         JNIEnv *env, jobject this, jint property)
 356 {
 357     jobject obj;
 358     gtk->gdk_threads_enter();
 359     obj = gtk->get_setting(env, property);
 360     gtk->gdk_threads_leave();
 361     return obj;
 362 }
 363 
 364 /*
 365  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
 366  * Method:    nativeSetRangeValue
 367  * Signature: (IDDDD)V
 368  */
 369 JNIEXPORT void JNICALL
 370 Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeSetRangeValue(
 371         JNIEnv *env, jobject this, jint widget_type,
 372         jdouble value, jdouble min, jdouble max, jdouble visible)
 373 {
 374     gtk->gdk_threads_enter();
 375     gtk->set_range_value(widget_type, value, min, max, visible);
 376     gtk->gdk_threads_leave();
 377 }