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