/*******************************************************************************
* Copyright (c) 2009, 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nokia Corporation - initial implementation
*******************************************************************************/
#ifndef _JNI_UTILS_H_
#define _JNI_UTILS_H_
#include <QObject>
#include <QRect>
#include <QPoint>
#include <QStringList>
#include <QStack>
#include <QPointer>
#include <jni.h>
#include "swtexport.h"
template<class T>
class QStack;
namespace Java { namespace GFX {
class ImageDataWrapper;
class PaletteDataWrapper;
class Image;
class GfxException;
}}
namespace Java { namespace eSWT {
class ExecExceptionHandler;
typedef QPointer<QObject> QObjectPtr;
typedef QStack<QObjectPtr> PtrStack;
typedef QStack<ExecExceptionHandler*> ExecStack;
class JniUtils : public QObject {
Q_OBJECT
public:
/**
* The constructor.
* @param aEnv The JNI environment pointer of the Qt GUI thread.
*/
JniUtils(JNIEnv* aEnv);
/**
* The destructor.
*/
virtual ~JniUtils();
/**
* Calls eventProcess Java method of the Display class.
* Can only be called in the UI thread.
* @param aQObject Target QObject of the QEvent
* @param aQEventType Type of the QEvent
* @param aN Event type specific integer arguments
* @param aString Event type specific string argument
* @return True if the event should be canceled.
*/
bool eventProcess(const QObject* aQObject, const int& aQEventType,
const int& a1 = 0, const int& a2 = 0, const int& a3 = 0,
const int& a4 = 0, const int& a5 = 0,
const jstring aString = NULL);
/**
* Calls eventProcess Java instance method based on the given jobject and jmethodID.
* Can only be called in the UI thread.
* @param aObject The Java object instance for the method call.
* @param aMethodID The Java methodID for the method call.
* @param ... Parameters to pass to the Java method.
* @return True if the event should be canceled.
*/
bool eventProcess(jobject aObject, const jmethodID aMethodID,
const QObject* aQObject, const int& aQEventType, const int& a1,
const int& a2, const int& a3, const int& a4, const int& a5,
const jstring aString);
/**
* Calls static eventProcess Java method based on the given jclass and jmethodID.
* Can only be called in the UI thread.
* @param aObject The Java class for the method call.
* @param aMethodID The Java methodID for the method call.
* @param ... Parameters to pass to the Java method.
* @return True if the event should be canceled.
*/
bool eventProcess(jclass aClazz, const jmethodID aMethodID,
const QObject* aQObject, const int& aQEventType, const int& a1,
const int& a2, const int& a3, const int& a4, const int& a5,
const jstring aString);
/**
* This must be called before entering an event loop. E.g. dialogs and
* menus need to call this before calling exec(). This will handle closing
* the dialog or menu properly in case a Java exception is thrown while in
* exec(). Call to enterExec must always be paired with leaveExec.
* @param aObject the object that exec will be called on.
*/
void enterExec(QObject* aObject);
/**
* This must be called after exiting an event loop. It must be preceded by
* enterExec.
*/
void leaveExec();
/**
* Creates a Java Rectangle from the given QRect.
* @param aEnv JNI environment for the thread
* @param aRect The QRect to use.
* @return A Java Rectangle object reference. Never NULL.
* @exception std::bad_alloc
*/
jobject NewJavaRectangle(JNIEnv* aEnv, const QRect& aRect);
/**
* Creates a Java Point from the given QSize.
* @param aEnv JNI environment for the thread
* @param aSize The QSize object ot use.
* @return A Java Point object reference.
* @exception std::bad_alloc
*/
jobject NewJavaPoint(JNIEnv* aEnv, const QSize& aSize);
/**
* Creates a Java Point from the given QPoint.
* @param aEnv JNI environment for the thread
* @param aPoint The QPoint object ot use.
* @return A Java Point object reference.
* @exception std::bad_alloc
*/
jobject NewJavaPoint(JNIEnv* aEnv, const QPoint& aPoint);
/**
* Creates a QString from the given Java string.
* @param aEnv JNI environment for the thread
* @param The Java String to use.
* @return A QString object.
* @exception std::bad_alloc
*/
SWTQT_EXPORT QString JavaStringToQString(JNIEnv* aEnv, jstring aJavaString);
/**
* Creates a Java string from the given QString.
* @param aEnv JNI environment for the thread
* @param aQString The QString object to use.
* @return A Java string.
* @exception std::bad_alloc
*/
SWTQT_EXPORT jstring QStringToJavaString(JNIEnv* aEnv, const QString& aQString);
/**
* Creates a new Java integer array from the given native int array.
* @param aEnv JNI environment for the thread
* @param aArray Native primitive integer array.
* @param aItemCount Number of items to read from the array starting from the first item.
* @return A Java integer array.
* @exception std::bad_alloc
*/
jintArray NewJavaIntArray(JNIEnv* aEnv, int* aArray, const int& aItemCount);
/**
* Creates a new Java string array from the given QStringList.
* @param aEnv JNI environment for the thread
* @param aStrList QStringList.
* @return A Java object array.
* @exception std::bad_alloc or std::bad_typeid
*/
jobjectArray NewJavaStringArray(JNIEnv* aEnv, const QStringList& aStrList);
/**
* Creates a QStringList from the given Java string array .
* @param aEnv JNI environment for the thread
* @param aObjectArray jobjectArray.
* @return A QStringList
*/
QStringList JavaStringArrayToQStringList(JNIEnv* aEnv, jobjectArray aObjectArray);
/**
* Creates a new Java byte array from the given QByteArray.
* @param aEnv JNI environment for the thread
* @param aArray QByteArray.
* @return A Java byte array.
* @exception std::bad_alloc
*/
jbyteArray NewJavaByteArray(JNIEnv* aEnv, const QByteArray& aArray);
/**
* Creates a QByteArray from the given Java byte array.
* @param aEnv JNI environment for the thread
* @param Java byte array.
* @return A QByteArray object.
* @exception std::bad_alloc
*/
QByteArray JavaByteArrayToQByteArray(JNIEnv* aEnv, jbyteArray aByteArray);
/**
* Throws an SWT error exception from the current JNI call.
* Note that after this call the JVM is handling the exception and further Java execution is not
* possible until the exception has been caught by the JVM.
* @param aEnv JNI environment for the thread
* @param aError The SWT error code to throw.
*/
SWTQT_EXPORT void Throw(JNIEnv* aEnv, const int& aError);
/**
* Throws a custom Java exception from the current JNI call.
* Note that after this call the JVM is handling the exception and further Java execution is not
* possible until the exception has been caught by the JVM.
* @param aEnv JNI environment for the thread
* @param aException The GfxException containing error code and error description.
*/
void Throw(JNIEnv* aEnv, Java::GFX::GfxException& aException);
/**
* Returns a Java object instance method ID based of on the given method name and signature.
* @param aEnv JNI environment for the thread
* @param aObject The Java object instance.
* @param aMethodName The name of the Java method.
* @param aMethodSignature The JNI signature of the Java method.
* @return JNI method id of the method or NULL if unsuccessful.
*/
jmethodID FindJavaMethodID(JNIEnv* aEnv, jobject aObject, const char* aMethodName,
const char* aMethodSignature);
/**
* Returns the number of currently active (maybe nested) calls to event
* processing functions. I.e. calls to functions that might lead to
* callbacks to Java event listeners. Used to defer the desruction of
* QApplication to the point where all nested events loops have exited.
*/
int javaCallbackCount();
/**
* Copies a region of a Java integer array to a pre-allocated primitive int
* buffer.
* @param aEnv JNI environment for the thread
* @param aArray The source Java array
* @param aStart The copy operation start index in the source array
* @param aLength The number of elements to be copied
* @param aBuffer The pre-allocated destination buffer
* @exception std::bad_alloc
*/
void GetJavaIntArrayRegionToIntArray(JNIEnv* aEnv, jintArray aArray, jsize aStart, jsize aLength, int* aBuffer);
/**
* Copies contents of a primitive integer buffer to a region of a Java
* integer array.
* @param aEnv JNI environment for the thread
* @param aArray The target Java array
* @param aStart The copy operation start index in the target Java array
* @param aLength The number of elements to be copied
* @param aBuffer The native primitive type source buffer
* @exception std::bad_alloc
*/
void SetJavaIntArrayRegionFromIntArray(JNIEnv* aEnv, jintArray aArray, jsize aStart, jsize aLength, int* aBuffer);
/**
* Copies a region of a Java byte array to a pre-allocated primitive char
* buffer.
* @param aEnv JNI environment for the thread
* @param aArray The source Java array
* @param aStart The copy operation start index in the source array
* @param aLength The number of elements to be copied
* @param aBuffer The pre-allocated destination buffer
* @exception std::bad_alloc
*/
void GetJavaByteArrayRegionToCharArray(JNIEnv* aEnv, jbyteArray aArray, jsize aStart, jsize aLength, char* aBuffer);
/**
* Copies contents of a primitive integer buffer to a region of a Java
* integer array.
* @param aEnv JNI environment for the thread
* @param aArray The target Java array
* @param aStart The copy operation start index in the target Java array
* @param aLength The number of elements to be copied
* @param aBuffer The native primitive type source buffer
* @exception std::bad_alloc
*/
void SetJavaByteArrayRegionFromCharArray(JNIEnv* aEnv, jbyteArray aArray, jsize aStart, jsize aLength, char* aBuffer);
/**
* Copies a region of a Java short array to a pre-allocated primitive short
* buffer.
* @param aEnv JNI environment for the thread
* @param aArray The source Java array
* @param aStart The copy operation start index in the source array
* @param aLength The number of elements to be copied
* @param aBuffer The pre-allocated destination buffer
* @exception std::bad_alloc
*/
void GetJavaShortArrayRegionToShortArray(JNIEnv* aEnv, jshortArray aArray, jsize aStart, jsize aLength, short* aBuffer);
/**
* Copies contents of a primitive short buffer to a region of a Java
* short array.
* @param aEnv JNI environment for the thread
* @param aArray The target Java array
* @param aStart The copy operation start index in the target Java array
* @param aLength The number of elements to be copied
* @param aBuffer The native primitive type source buffer
* @exception std::bad_alloc
*/
void SetJavaShortArrayRegionFromShortArray(JNIEnv* aEnv, jshortArray aArray, jsize aStart, jsize aLength, short* aBuffer);
/**
* Creates java side image data object based on the given native side
* image data object.
* @param aEnv JNI environment for the thread
* @param aImageData The native image data object
* @return Java side image data object
*/
jobject CreateJavaImageData(JNIEnv* aEnv, Java::GFX::ImageDataWrapper& aImageData);
/**
* Creates java side palette data object based on the given native side
* palette data object.
* @param aEnv JNI environment for the thread
* @param aPaletteData The native palette data object
* @return Java side palette data object
*/
jobject CreateJavaPaletteData(JNIEnv* aEnv, Java::GFX::PaletteDataWrapper& aPaletteData);
/**
* Creates a native image object based on the given image data object.
* @param aEnv JNI environment for the thread
* @param aJavaImageData Java side image data object
* @param aType The native type of the image to be created
* @return Native image object
*/
Java::GFX::Image* CreateImage(JNIEnv* aEnv, jobject& aJavaImageData, jint aType);
/**
* Checks if in terms of event processing the object can be deleted. Used
* to prevent objects from getting deleted inside their event listeners.
* @param aPtrToDelete Pointer to the deletion candidate object.
* @return True if the object can be deleted.
*/
bool safeToDelete(QObject* aPtrToDelete);
private:
JniUtils() {};
/**
* Calls back Java eventProcess method which can be either static class
* method of the given class or an instance method of the given object.
* @param aObject Java object instance or NULL if the method is static.
* @param aClazz Java class or NULL if the method is an instance method.
* @param aMethodID The Java methodID for the method call.
* @param ... Parameters to pass to the Java method.
* @return True if the event should be canceled.
*/
bool eventProcess(jobject aObject, jclass aClazz, const jmethodID aMethodID,
const int& aQObject, const int& aQEventType, const int& a1,
const int& a2, const int& a3, const int& a4, const int& a5,
const jstring aString);
/**
* Creates a native palette data object based on the given palette data object.
* @param aEnv JNI environment
* @param aJavaPaletteData Java side image data object
* @return Native image object
*/
Java::GFX::PaletteDataWrapper* CreatePaletteData(JNIEnv* aEnv, jobject& aJavaPaletteData);
/**
* Converts GfxException error code to java exception class string.
* @param aErrorCode The Gfx error code to throw.
*/
const char* resolveException(int aErrorCode);
/**
* Checks recursively if the object is a child of the other object.
* @param aChild The child candidate.
* @param aParent The candidate parent object whose children are searched.
* @returns True if aParent equals aChild or aChild is one of the children.
*/
bool isSameOrChild(const QObject* aChild, const QObject* aParent) const;
/**
* Private helper class that can be created on stack to safely update the
* number of recursive callbacks and the list of objects currently in
* their event or signal handler.
*/
class JavaCallbackCounter
{
public:
JavaCallbackCounter(PtrStack& aStack, QObject* aObject)
: mStack(aStack)
{
QObjectPtr ptr = aObject;
mStack.push(ptr);
}
virtual ~JavaCallbackCounter()
{
mStack.pop();
}
private:
PtrStack& mStack;
};
JNIEnv* mUIThreadJniEnv;
jclass* mJclasses;
jmethodID* mJmethodIds;
ExecStack mExecStack;
PtrStack mObjectsBeingHandled;
};
}}
#endif // _JNI_UTILS_H_