#include #include #include #include #include "QtUtils.moc" #define SYNC_EVENT1 60001 #define SYNC_EVENT2 60002 #define ASYNC_EVENT 60003 class TQRunEvent : public TQCustomEvent { public: TQRunEvent(int type, jobject r) : TQCustomEvent(type), runnable(r), res(0), lock(0) {} jobject runnable; jobject *res; TQMutex *lock; }; QtUtils* QtUtils::gUtils = 0; QtUtils::QtUtils() { } QtUtils::~QtUtils() { } void QtUtils::postSync(JNIEnv* env, jobject runnable) { TQMutex lock; TQRunEvent *e = new TQRunEvent(SYNC_EVENT1, env->NewGlobalRef(runnable)); e->lock = &lock; lock.lock(); //post the event to the QT-UI thread //and trigger its processing TQApplication::postEvent(this, e); TQApplication::sendPostedEvents(); //the lock is gained only //after executing the runnable lock.lock(); lock.unlock(); } jobject QtUtils::postSyncRet(JNIEnv* env, jobject runnable) { TQMutex lock; jobject res; TQRunEvent *e = new TQRunEvent(SYNC_EVENT2, env->NewGlobalRef(runnable)); e->lock = &lock; e->res = &res; lock.lock(); //post the event to the QT-UI thread and //trigger its processing TQApplication::postEvent(this, e); TQApplication::sendPostedEvents(); //the lock is gained only //after executing the runnable lock.lock(); lock.unlock(); jobject lres = env->NewLocalRef(res); env->DeleteGlobalRef(res); return lres; } void QtUtils::postAsync(JNIEnv *env, jobject runnable) { TQRunEvent *e = new TQRunEvent(ASYNC_EVENT, env->NewGlobalRef(runnable)); //post the event to the QT-UI thread, //it will be processed in the next Qt-loop iterations TQApplication::postEvent(this, e); } void QtUtils::customEvent(TQCustomEvent *e) { if (e->type() >= SYNC_EVENT1 && e->type() <= ASYNC_EVENT) { TQRunEvent *re = (TQRunEvent*) e; JNIEnv *env = QtSupport::GetEnv(); jclass cls = env->GetObjectClass(re->runnable); if (re->type() == SYNC_EVENT1) { jmethodID m = env->GetMethodID(cls, "run", "()V"); if (m!=0) { env->CallObjectMethod(re->runnable, m); } re->lock->unlock(); } else if (re->type() == SYNC_EVENT2) { jmethodID m = env->GetMethodID(cls, "run", "()Ljava/lang/Object;"); if (m!=0) { jobject res = env->CallObjectMethod(re->runnable, m); *(re->res) = env->NewGlobalRef(res); } re->lock->unlock(); } else { jmethodID m = env->GetMethodID(cls, "run", "()V"); if (m!=0) { env->CallVoidMethod(re->runnable, m); } } //runnable is no longer needed env->DeleteGlobalRef(re->runnable); } } JNIEXPORT jobject JNICALL Java_org_kde_qt_QtUtils_execSyncOnGUIThread__Lorg_kde_qt_QtUtils_00024Compute_2 (JNIEnv *env, jclass, jobject runnable) { if (!runnable) return 0; if (QtUtils::gUtils==0) QtUtils::gUtils = new QtUtils(); return QtUtils::gUtils->postSyncRet(env, runnable); } JNIEXPORT void JNICALL Java_org_kde_qt_QtUtils_execSyncOnGUIThread__Ljava_lang_Runnable_2 (JNIEnv *env, jclass, jobject runnable) { if (!runnable) return; if (QtUtils::gUtils==0) QtUtils::gUtils = new QtUtils(); QtUtils::gUtils->postSync(env, runnable); } JNIEXPORT void JNICALL Java_org_kde_qt_QtUtils_execAsyncOnGUIThread (JNIEnv *env, jclass, jobject runnable) { if (!runnable) return; if (QtUtils::gUtils==0) QtUtils::gUtils = new QtUtils(); QtUtils::gUtils->postAsync(env, runnable); }