1 /*
   2  * Copyright (c) 2011, 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 #ifndef GLASS_GENERAL_H
  26 #define        GLASS_GENERAL_H
  27 
  28 #include <jni.h>
  29 
  30 #include <stdint.h>
  31 #include <X11/Xlib.h>
  32 #include <gdk/gdk.h>
  33 #include <gtk/gtk.h>
  34 
  35 #include "glass_wrapper.h"
  36 
  37 #define JLONG_TO_PTR(value) ((void*)(intptr_t)(value))
  38 #define PTR_TO_JLONG(value) ((jlong)(intptr_t)(value))
  39 
  40 #define FILE_PREFIX "file://"
  41 #define URI_LIST_COMMENT_PREFIX "#"
  42 #define URI_LIST_LINE_BREAK "\r\n"
  43 
  44 extern JNIEnv* mainEnv; // Use only with main loop thread!!!
  45 
  46 #include <exception>
  47 
  48 struct jni_exception: public std::exception {
  49     jni_exception(jthrowable _th): throwable(_th), message() {
  50             jclass jc = mainEnv->FindClass("java/lang/Throwable");
  51             if (mainEnv->ExceptionOccurred()) {
  52                 mainEnv->ExceptionDescribe();
  53                 mainEnv->ExceptionClear();
  54             }
  55             jmethodID jmid = mainEnv->GetMethodID(jc, "getMessage", "()Ljava/lang/String;");
  56             if (mainEnv->ExceptionOccurred()) {
  57                 mainEnv->ExceptionDescribe();
  58                 mainEnv->ExceptionClear();
  59             }
  60             jmessage = (jstring)mainEnv->CallObjectMethod(throwable, jmid);
  61             message = jmessage == NULL ? "" : mainEnv->GetStringUTFChars(jmessage, NULL);
  62     }
  63     const char *what() const throw()
  64     {
  65         return message;
  66     }
  67     ~jni_exception() throw(){
  68         if (jmessage && message) {
  69             mainEnv->ReleaseStringUTFChars(jmessage, message);
  70         }
  71     }
  72 private:
  73     jthrowable throwable;
  74     const char *message;
  75     jstring jmessage;
  76 };
  77 
  78 #define EXCEPTION_OCCURED(env) (check_and_clear_exception(env))
  79 
  80 #define CHECK_JNI_EXCEPTION(env) \
  81         if (env->ExceptionCheck()) {\
  82             check_and_clear_exception(env);\
  83             return;\
  84         }
  85 
  86 #define CHECK_JNI_EXCEPTION_RET(env, ret) \
  87         if (env->ExceptionCheck()) {\
  88             check_and_clear_exception(env);\
  89             return ret;\
  90         }
  91 
  92 #define JNI_EXCEPTION_TO_CPP(env) \
  93         if (env->ExceptionCheck()) {\
  94             check_and_clear_exception(env);\
  95             throw jni_exception(env->ExceptionOccurred());\
  96         }
  97 
  98 #define HANDLE_MEM_ALLOC_ERROR(env, nativePtr, message) \
  99         ((nativePtr == NULL) && glass_throw_oom(env, message))
 100 
 101     gpointer glass_try_malloc0_n(gsize m, gsize n);
 102 
 103     gpointer glass_try_malloc_n(gsize m, gsize n);
 104 
 105     typedef struct {
 106         jobject runnable;
 107         int flag;
 108     } RunnableContext;
 109 
 110     extern char const * const GDK_WINDOW_DATA_CONTEXT;
 111 
 112     GdkCursor* get_native_cursor(int type);
 113 
 114     // JNI global references
 115     extern jclass jStringCls; // java.lang.String
 116 
 117     extern jclass jByteBufferCls; //java.nio.ByteBuffer
 118     extern jmethodID jByteBufferArray; //java.nio.ByteBuffer#array()[B
 119     extern jmethodID jByteBufferWrap; //java.nio.ByteBuffer#wrap([B)Ljava/nio/ByteBuffer;
 120 
 121     extern jclass jRunnableCls; // java.lang.Runnable
 122     extern jmethodID jRunnableRun; // java.lang.Runnable#run ()V
 123 
 124     extern jclass jArrayListCls; // java.util.ArrayList
 125     extern jmethodID jArrayListInit; // java.util.ArrayList#<init> ()V
 126     extern jmethodID jArrayListAdd; // java.util.ArrayList#add (Ljava/lang/Object;)Z
 127     extern jmethodID jArrayListGetIdx; //java.util.ArryList#get (I)Ljava/lang/Object;
 128 
 129     extern jmethodID jPixelsAttachData; // com.sun.class.ui.Pixels#attachData (J)V
 130     extern jclass jGtkPixelsCls; // com.sun.class.ui.gtk.GtkPixels
 131     extern jmethodID jGtkPixelsInit; // com.sun.class.ui.gtk.GtkPixels#<init> (IILjava/nio/ByteBuffer;)V
 132 
 133     extern jclass jScreenCls;   // com.sun.glass.ui.Screen
 134     extern jmethodID jScreenInit; // com.sun.glass.ui.Screen#<init> ()V
 135     extern jmethodID jScreenNotifySettingsChanged; // com.sun.glass.ui.Screen#notifySettingsChanged ()V
 136     extern jmethodID jScreenGetScreenForLocation; //com.sun.glass.ui.Screen#getScreenForLocation(JJ)Lcom.sun.glass.ui.Screen;
 137     extern jmethodID jScreenGetNativeScreen; //com.sun.glass.ui.Screen#getNativeScreen()J
 138 
 139     extern jmethodID jViewNotifyResize; // com.sun.glass.ui.View#notifyResize (II)V
 140     extern jmethodID jViewNotifyMouse; // com.sun.glass.ui.View#notifyMouse (IIIIIIIZZ)V
 141     extern jmethodID jViewNotifyRepaint; // com.sun.glass.ui.View#notifyRepaint (IIII)V
 142     extern jmethodID jViewNotifyKey; // com.sun.glass.ui.View#notifyKey (II[CI)V
 143     extern jmethodID jViewNotifyView; //com.sun.glass.ui.View#notifyView (I)V
 144     extern jmethodID jViewNotifyDragEnter; //com.sun.glass.ui.View#notifyDragEnter (IIIII)I
 145     extern jmethodID jViewNotifyDragOver; //com.sun.glass.ui.View#notifyDragOver (IIIII)I
 146     extern jmethodID jViewNotifyDragDrop; //com.sun.glass.ui.View#notifyDragDrop (IIIII)I
 147     extern jmethodID jViewNotifyDragLeave; //com.sun.glass.ui.View#notifyDragLeave ()V
 148     extern jmethodID jViewNotifyScroll; //com.sun.glass.ui.View#notifyScroll (IIIIDDIIIIIDD)V
 149     extern jmethodID jViewNotifyInputMethod; //com.sun.glass.ui.View#notifyInputMethod (Ljava/lang/String;[I[I[BIII)V
 150     extern jmethodID jViewNotifyInputMethodDraw; //com.sun.glass.ui.gtk.GtkView#notifyInputMethodDraw (Ljava/lang/String;III[B)V
 151     extern jmethodID jViewNotifyInputMethodCaret; //com.sun.glass.ui.gtk.GtkView#notifyInputMethodCaret (III)V
 152     extern jmethodID jViewNotifyPreeditMode; //com.sun.glass.ui.gtk.GtkView#notifyPreeditMode (Z)V
 153     extern jmethodID jViewNotifyMenu; //com.sun.glass.ui.View#notifyMenu (IIIIZ)V
 154     extern jfieldID  jViewPtr; //com.sun.glass.ui.View.ptr
 155 
 156     extern jmethodID jWindowNotifyResize; // com.sun.glass.ui.Window#notifyResize (III)V
 157     extern jmethodID jWindowNotifyMove; // com.sun.glass.ui.Window#notifyMove (II)V
 158     extern jmethodID jWindowNotifyDestroy; // com.sun.glass.ui.Window#notifyDestroy ()V
 159     extern jmethodID jWindowNotifyClose; // com.sun.glass.ui.Window#notifyClose ()V
 160     extern jmethodID jWindowNotifyFocus; // com.sun.glass.ui.Window#notifyFocus (I)V
 161     extern jmethodID jWindowNotifyFocusDisabled; // com.sun.glass.ui.Window#notifyFocusDisabled ()V
 162     extern jmethodID jWindowNotifyFocusUngrab; // com.sun.glass.ui.Window#notifyFocusUngrab ()V
 163     extern jmethodID jWindowNotifyMoveToAnotherScreen; // com.sun.glass.ui.Window#notifyMoveToAnotherScreen (Lcom/sun/glass/ui/Screen;)V
 164     extern jmethodID jWindowNotifyDelegatePtr; //com.sun.glass.ui.Window#notifyDelegatePtr (J)V
 165     extern jmethodID jWindowNotifyLevelChanged; //com.sun.glass.ui.Window#notifyLevelChanged (I)V
 166 
 167     extern jmethodID jWindowIsEnabled; // com.sun.glass.ui.Window#isEnabled ()Z
 168     extern jfieldID jWindowPtr; // com.sun.glass.ui.Window#ptr
 169     extern jfieldID jCursorPtr; // com.sun.glass.ui.Cursor#ptr
 170 
 171     extern jmethodID jGtkWindowNotifyStateChanged; // com.sun.glass.ui.GtkWindow#notifyStateChanged (I)V
 172 
 173     extern jmethodID jClipboardContentChanged; // com.sun.glass.ui.Clipboard#contentChanged ()V
 174 
 175     extern jmethodID jSizeInit; // com.sun.class.ui.Size#<init> ()V
 176 
 177     extern jmethodID jMapGet; // java.util.Map#get(Ljava/lang/Object;)Ljava/lang/Object;
 178     extern jmethodID jMapKeySet; // java.util.Map#keySet()Ljava/util/Set;
 179     extern jmethodID jMapContainsKey; // java.util.Map#containsKey(Ljava/lang/Object;)Z
 180 
 181     extern jclass jHashSetCls; // java.util.HashSet
 182     extern jmethodID jHashSetInit; // java.util.HashSet#<init> ()V
 183 
 184     extern jmethodID jSetAdd; //java.util.Set#add (Ljava/lang/Object;)Z
 185     extern jmethodID jSetSize; //java.util.Set#size ()I
 186     extern jmethodID jSetToArray; //java.util.Set#toArray ([Ljava/lang/Object;)[Ljava/lang/Object;
 187 
 188     extern jmethodID jIterableIterator; // java.lang.Iterable#iterator()Ljava/util/Iterator;
 189     extern jmethodID jIteratorHasNext; // java.util.Iterator#hasNext()Z;
 190     extern jmethodID jIteratorNext; // java.util.Iterator#next()Ljava/lang/Object;
 191 
 192     extern jclass jApplicationCls; //com.sun.glass.ui.gtk.GtkApplication
 193     extern jfieldID jApplicationDisplay; //com.sun.glass.ui.gtk.GtkApplication#display
 194     extern jfieldID jApplicationScreen; //com.sun.glass.ui.gtk.GtkApplication#screen
 195     extern jfieldID jApplicationVisualID; //com.sun.glass.ui.gtk.GtkApplication#visualID
 196     extern jmethodID jApplicationReportException; // reportException(Ljava/lang/Throwable;)V
 197     extern jmethodID jApplicationGetApplication; // GetApplication()()Lcom/sun/glass/ui/Application;
 198     extern jmethodID jApplicationGetName; // getName()Ljava/lang/String;
 199 
 200 #ifdef VERBOSE
 201 #define LOG0(msg) {printf(msg);fflush(stdout);}
 202 #define LOG1(msg, param) {printf(msg, param);fflush(stdout);}
 203 #define LOG2(msg, param1, param2) {printf(msg, param1, param2);fflush(stdout);}
 204 #define LOG3(msg, param1, param2, param3) {printf(msg, param1, param2, param3);fflush(stdout);}
 205 #define LOG4(msg, param1, param2, param3, param4) {printf(msg, param1, param2, param3, param4);fflush(stdout);}
 206 #define LOG5(msg, param1, param2, param3, param4, param5) {printf(msg, param1, param2, param3, param4, param5);fflush(stdout);}
 207 
 208 #define LOG_STRING_ARRAY(env, array) dump_jstring_array(env, array);
 209 
 210 #define ERROR0(msg) {fprintf(stderr, msg);fflush(stderr);}
 211 #define ERROR1(msg, param) {fprintf(stderr, msg, param);fflush(stderr);}
 212 #define ERROR2(msg, param1, param2) {fprintf(stderr, msg, param1, param2);fflush(stderr);}
 213 #define ERROR3(msg, param1, param2, param3) {fprintf(stderr, msg, param1, param2, param3);fflush(stderr);}
 214 #define ERROR4(msg, param1, param2, param3, param4) {fprintf(stderr, msg, param1, param2, param3, param4);fflush(stderr);}
 215 #else
 216 #define LOG0(msg)
 217 #define LOG1(msg, param)
 218 #define LOG2(msg, param1, param2)
 219 #define LOG3(msg, param1, param2, param3)
 220 #define LOG4(msg, param1, param2, param3, param4)
 221 #define LOG5(msg, param1, param2, param3, param4, param5)
 222 
 223 #define LOG_STRING_ARRAY(env, array)
 224 
 225 #define ERROR0(msg)
 226 #define ERROR1(msg, param)
 227 #define ERROR2(msg, param1, param2)
 228 #define ERROR3(msg, param1, param2, param3)
 229 #define ERROR4(msg, param1, param2, param3, param4)
 230 #endif
 231 
 232 #define LOG_EXCEPTION(env) check_and_clear_exception(env);
 233 
 234     gchar* get_application_name();
 235     void glass_throw_exception(JNIEnv * env,
 236             const char * exceptionClass,
 237             const char * exceptionMessage);
 238     int glass_throw_oom(JNIEnv * env, const char * exceptionMessage);
 239     void dump_jstring_array(JNIEnv*, jobjectArray);
 240 
 241     guint8* convert_BGRA_to_RGBA(const int* pixels, int stride, int height);
 242 
 243     gboolean check_and_clear_exception(JNIEnv *env);
 244 
 245     jboolean is_display_valid();
 246 
 247     gsize get_files_count(gchar **uris);
 248 
 249     jobject uris_to_java(JNIEnv *env, gchar **uris, gboolean files);
 250 
 251 #endif        /* GLASS_GENERAL_H */
 252