native-glass.win.Utils.h Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openjfx-78-backport-native Show documentation
Show all versions of openjfx-78-backport-native Show documentation
This contains the native files for the backport of OpenJFX 8 to run on Java 7.
The newest version!
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _GLASS_UTILS_
#define _GLASS_UTILS_
#ifndef _WIN32_WINNT
# error The header should not be included directly. Do #include "common.h" instead.
#endif
#ifndef USER_TIMER_MINIMUM
#define USER_TIMER_MINIMUM 0x0000000A
#define USER_TIMER_MAXIMUM 0x7FFFFFFF
#endif
#if defined(DEBUG) || defined(_DEBUG)
#define ASSERT(condition) \
if (!(condition)) { \
fprintf(stderr, "ERROR: %s (%s, %s, line %d)\n", \
#condition, __FUNCTION__, __FILE__, __LINE__); \
fflush(stderr); \
::DebugBreak(); \
}
#else
#define ASSERT(condition)
#endif
#ifdef _WIN64
#define jlong_to_ptr(a) ((void*)(a))
#define ptr_to_jlong(a) ((jlong)(a))
#else
#define jlong_to_ptr(a) ((void*)(int)(a))
#define ptr_to_jlong(a) ((jlong)(int)(a))
#endif
#define jbool_to_bool(a) (((a) == JNI_TRUE) ? TRUE : FALSE)
#define bool_to_jbool(a) ((a) ? JNI_TRUE : JNI_FALSE)
#define IS_WINVER_ATLEAST(maj, min) \
(LOBYTE(LOWORD(::GetVersion())) > (maj) || \
LOBYTE(LOWORD(::GetVersion())) == (maj) && \
HIBYTE(LOWORD(::GetVersion())) >= (min))
#define IS_WINXP IS_WINVER_ATLEAST(5, 1)
#define IS_WINVISTA IS_WINVER_ATLEAST(6, 0)
#define IS_WIN7 IS_WINVER_ATLEAST(6, 1)
#if defined(DEBUG) || defined(_DEBUG)
#define LOG(msg, ...) do { printf(msg, __VA_ARGS__); } while (0)
#else
#define LOG(msg, ...) do { } while (0)
#endif
///////////////////////////////////////////////////////////
// Java helper routines
///////////////////////////////////////////////////////////
JavaVM* GetJVM();
JNIEnv* GetEnv();
// Returns JNI_TRUE if there are exceptions
jboolean CheckAndClearException(JNIEnv *env);
jint GetModifiers();
class JString {
public:
JString(JNIEnv *env, jstring jString) {
init(env, jString, true);
}
JString(JNIEnv *env, jstring jString, bool autoDelete) {
init(env, jString, autoDelete);
}
~JString() {
if (m_wszStr && m_autoDelete) {
delete[] m_wszStr;
}
}
operator wchar_t*() { return m_wszStr; }
int length() { return m_len; }
private:
void init(JNIEnv *env, jstring jString, bool autoDelete) {
m_len = env->GetStringLength(jString);
m_wszStr = new wchar_t[m_len + 1];
env->GetStringRegion(jString, 0, m_len, (jchar *)m_wszStr);
m_wszStr[m_len] = L'\0';
m_autoDelete = autoDelete;
}
wchar_t *m_wszStr;
int m_len;
bool m_autoDelete;
};
// DNT == double null terminated
class DNTString {
public:
DNTString(int limit) :
m_limit(limit), m_length(0), m_substrings(NULL), m_count(0)
{
wszStr = new wchar_t[limit];
memset(wszStr, 0, limit*sizeof(wchar_t));
}
~DNTString() {
if (wszStr) {
delete[] wszStr;
}
if (m_substrings) {
delete[] m_substrings;
}
}
operator wchar_t*() { return wszStr; }
size_t length() { return m_length; }
size_t limit() { return m_limit; }
void setLimit(size_t limit, bool copy = false) {
wchar_t * const oldStr = wszStr;
const size_t oldLimit = m_limit;
m_limit = limit;
wszStr = new wchar_t[limit];
memset(wszStr, 0, limit*sizeof(wchar_t));
if (copy && oldStr) {
wmemcpy_s(wszStr, m_limit - 1, oldStr, min(oldLimit - 1, m_limit - 1));
m_length = min(m_length, m_limit - 2);
}
if (oldStr) {
delete[] oldStr;
}
}
UINT count() {
calculateSubstrings();
return m_count;
}
wchar_t* substring(UINT i) {
calculateSubstrings();
return wszStr+m_substrings[i];
}
// appends the count characters of the src string to the DNT string
void append(const wchar_t *wszSrc, const size_t count, bool allowGrow = false) {
if (allowGrow) {
if (m_length + count > m_limit - 2) {
const size_t GROWTH_RATE = 2; // consider parameterizing this const
setLimit((m_length + count + 2)*GROWTH_RATE, true);
}
}
// "-1" because this is a _double_ null terminated string
wcsncpy_s(wszStr + m_length, m_limit - m_length - 1, wszSrc, count);
m_length += count;
if (m_length > m_limit) {
m_length = m_limit;
}
}
// recalculates the length of the DNT string
// use the function when wszStr could be modified directly
void calculateLength() {
size_t i = 0;
while(wszStr[i] != L'\0' || wszStr[i+1] != L'\0') {
i++;
if (i>= m_limit-1) {
i = m_limit;
break;
}
}
m_length = i;
}
private:
void calculateSubstrings() {
if (m_substrings)
return;
wchar_t prevChar = '\0';
for (size_t i = 0; i < m_length; i++) {
if (prevChar == '\0' && wszStr[i] != '\0') { // new substring
m_count++;
}
prevChar = wszStr[i];
}
m_substrings = new size_t[m_count];
m_count = 0;
prevChar = '\0';
for (size_t i = 0; i < m_length; i++) {
if (prevChar == '\0' && wszStr[i] != '\0') { // new substring
m_substrings[m_count] = i;
m_count++;
}
prevChar = wszStr[i];
}
}
wchar_t *wszStr;
size_t m_length, m_limit;
size_t *m_substrings;
UINT m_count; // the count of the substrings
};
inline jstring CreateJString(JNIEnv *env, const wchar_t *wszStr) {
if (wszStr == NULL)
return NULL;
return env->NewString((const jchar *)wszStr, jsize(wcslen(wszStr)));
}
inline jstring CreateJString(JNIEnv *env, const char *szStr) {
if (szStr == NULL)
return NULL;
return env->NewStringUTF(szStr);
}
inline jstring ConcatJStrings(JNIEnv *env, jstring str1, jstring str2) {
if (str1 == NULL || str2 == NULL)
return NULL;
jclass cls = env->FindClass("java/lang/String");
jmethodID mid = env->GetMethodID(cls, "concat", "(Ljava/lang/String;)Ljava/lang/String;");
jstring ret = (jstring)env->CallObjectMethod(str1, mid, str2);
CheckAndClearException(env);
return ret;
}
template
class JLocalRef {
JNIEnv* m_env;
T m_localJRef;
public:
JLocalRef(JNIEnv* env, T localJRef = NULL)
: m_env(env),
m_localJRef(localJRef)
{}
T Detach() {
T ret = m_localJRef;
m_localJRef = NULL;
return ret;
}
void Attach(T newValue) {
if (m_localJRef) {
m_env->DeleteLocalRef((jobject)m_localJRef);
}
m_localJRef = newValue;
}
operator T() { return m_localJRef; }
operator bool() { return NULL!=m_localJRef; }
bool operator !() { return NULL==m_localJRef; }
~JLocalRef() {
if (m_localJRef) {
m_env->DeleteLocalRef((jobject)m_localJRef);
}
}
};
template
class JGlobalRef {
T m_globalJRef;
public:
JGlobalRef() : m_globalJRef(NULL) {}
JGlobalRef(T o) : m_globalJRef(NULL) // make sure it's NULL initially
{
Attach(GetEnv(), o);
}
void Attach(JNIEnv* env, T localJRef){
if (m_globalJRef) {
env->DeleteGlobalRef((jobject)m_globalJRef);
}
m_globalJRef = (T)(localJRef
? env->NewGlobalRef((jobject)localJRef)
: NULL);
}
JGlobalRef& operator = (T localRef)
{
Attach(GetEnv(), localRef);
return *this;
}
operator T() { return m_globalJRef; }
operator bool() { return NULL!=m_globalJRef; }
bool operator !() { return NULL==m_globalJRef; }
~JGlobalRef() {
if (m_globalJRef) {
GetEnv()->DeleteGlobalRef((jobject)m_globalJRef);
}
}
};
template
class MemHolder
{
public:
MemHolder(size_t count)
{
m_pMem = reinterpret_cast(0==count
? NULL
: malloc(count*sizeof(T)));
}
~MemHolder(){
free(m_pMem);
}
MemHolder& operator = (MemHolder &r)
{
if(this != &r){
m_pMem = r.m_pMem;
r.m_pMem = NULL;
}
return *this;
}
inline T *get() { return m_pMem; }
inline operator T *() { return m_pMem; }
inline operator bool() { return NULL!=m_pMem;}
inline bool operator !() { return NULL==m_pMem;}
private:
T *m_pMem;
};
typedef JLocalRef JLObject;
typedef JLocalRef JLString;
typedef JLocalRef JLClass;
typedef JLocalRef JLObjectArray;
template
class JArray {
public:
JArray() : data(NULL) {}
~JArray()
{
if (data) {
GetEnv()->ReleasePrimitiveArrayCritical(array, data, JNI_ABORT);
}
}
void Attach(JNIEnv *env, jarray a)
{
array.Attach(env, a);
}
T* GetPtr()
{
if (!data && array) {
data = (T*)GetEnv()->GetPrimitiveArrayCritical(array, NULL);
}
return data;
}
operator bool() { return array; }
private:
JGlobalRef array;
T * data;
};
template
class JBufferArray {
public:
JBufferArray() : data(NULL), offset(0) {}
void Attach(JNIEnv *env, jobject buf, jarray arr, jint offs)
{
if (!arr) {
data = (T*)env->GetDirectBufferAddress(buf);
} else {
array.Attach(env, arr);
offset = offs;
}
}
T* GetPtr()
{
if (!data && array) {
data = array.GetPtr();
data += offset;
}
return data;
}
operator bool() { return data || array; }
private:
T* data;
JArray array;
jint offset;
};
typedef struct _tagJavaIDs {
struct {
jmethodID notifyFocus;
jmethodID notifyFocusDisabled;
jmethodID notifyFocusUngrab;
jmethodID notifyDestroy;
jmethodID notifyDelegatePtr;
jmethodID notifyInitAccessibility;
} Window;
struct {
jmethodID notifyResize;
jmethodID notifyRepaint;
jmethodID notifyKey;
jmethodID notifyMouse;
jmethodID notifyMenu;
jmethodID notifyScroll;
jmethodID notifyInputMethod;
jmethodID notifyInputMethodCandidatePosRequest;
jmethodID notifyDragEnter;
jmethodID notifyDragOver;
jmethodID notifyDragLeave;
jmethodID notifyDragDrop;
jmethodID notifyView;
jmethodID getWidth;
jmethodID getHeight;
jfieldID ptr;
} View;
struct {
jmethodID init;
} Size;
struct {
jmethodID attachData;
} Pixels;
struct {
jmethodID getType;
jmethodID getNativeCursor;
} Cursor;
struct {
struct {
jmethodID getDescription;
jmethodID extensionsToArray;
} ExtensionFilter;
jmethodID createFileChooserResult;
} CommonDialogs;
struct {
jmethodID run;
} Runnable;
struct {
jmethodID add;
} List;
struct {
jmethodID gesturePerformedMID;
jmethodID inertiaGestureFinishedMID;
jmethodID notifyBeginTouchEventMID;
jmethodID notifyNextTouchEventMID;
jmethodID notifyEndTouchEventMID;
} Gestures;
struct {
jmethodID init;
jmethodID notifySettingsChanged;
} Screen;
struct {
jmethodID reportExceptionMID;
} Application;
} JavaIDs;
extern JavaIDs javaIDs;
#endif //_GLASS_UTILS_