Rearchitected the way the Mozilla event thread is run. I'm using
a Java Thread now instead to control Mozilla/GTK events.
This commit is contained in:
Родитель
944678da9d
Коммит
7c7f47fff4
|
@ -54,6 +54,7 @@ nsMacMessageSink gMessageSink;
|
||||||
|
|
||||||
#ifdef XP_UNIX
|
#ifdef XP_UNIX
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include "motif/MozillaEventThread.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nsActions.h"
|
#include "nsActions.h"
|
||||||
|
@ -234,7 +235,7 @@ EmbeddedEventHandler (void * arg) {
|
||||||
#ifndef NECKO
|
#ifndef NECKO
|
||||||
NS_InitINetService();
|
NS_InitINetService();
|
||||||
#endif
|
#endif
|
||||||
// HACK(mark): EmbeddedThread isn't set until after this method returns!!
|
// HACK(mark): On Unix, embeddedThread isn't set until after this method returns!!
|
||||||
initContext->embeddedThread = PR_GetCurrentThread();
|
initContext->embeddedThread = PR_GetCurrentThread();
|
||||||
|
|
||||||
// Create the action queue
|
// Create the action queue
|
||||||
|
@ -303,13 +304,18 @@ EmbeddedEventHandler (void * arg) {
|
||||||
printf("EmbeddedEventHandler(%lx): enter event loop\n", initContext);
|
printf("EmbeddedEventHandler(%lx): enter event loop\n", initContext);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Don't loop here. The looping will be handled by a Java Thread
|
||||||
|
// (see org.mozilla.webclient.motif.MozillaEventThread).
|
||||||
|
#ifndef XP_UNIX
|
||||||
do {
|
do {
|
||||||
if (!processEventLoop(initContext)) {
|
if (!processEventLoop(initContext)) {
|
||||||
#ifndef XP_UNIX
|
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} while (PR_TRUE);
|
} while (PR_TRUE);
|
||||||
|
#else
|
||||||
|
// Just need to loop once for Unix
|
||||||
|
processEventLoop(initContext);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// It appears the current thread (belonging to Java) is assumed to be
|
// It appears the current thread (belonging to Java) is assumed to be
|
||||||
|
@ -333,6 +339,9 @@ InitEmbeddedEventHandler (WebShellInitContext* initContext)
|
||||||
#if DEBUG_RAPTOR_CANVAS
|
#if DEBUG_RAPTOR_CANVAS
|
||||||
printf("InitEmbeddedEventHandler(%lx): Creating embedded thread...\n", initContext);
|
printf("InitEmbeddedEventHandler(%lx): Creating embedded thread...\n", initContext);
|
||||||
#endif
|
#endif
|
||||||
|
// Don't create a NSPR Thread on Unix, because we will use a Java Thread instead.
|
||||||
|
// (see org.mozilla.webclient.motif.MozillaEventThread).
|
||||||
|
#ifndef XP_UNIX
|
||||||
initContext->embeddedThread = ::PR_CreateThread(PR_SYSTEM_THREAD,
|
initContext->embeddedThread = ::PR_CreateThread(PR_SYSTEM_THREAD,
|
||||||
EmbeddedEventHandler,
|
EmbeddedEventHandler,
|
||||||
(void*)initContext,
|
(void*)initContext,
|
||||||
|
@ -340,6 +349,9 @@ InitEmbeddedEventHandler (WebShellInitContext* initContext)
|
||||||
PR_GLOBAL_THREAD,
|
PR_GLOBAL_THREAD,
|
||||||
PR_UNJOINABLE_THREAD,
|
PR_UNJOINABLE_THREAD,
|
||||||
0);
|
0);
|
||||||
|
#else
|
||||||
|
EmbeddedEventHandler((void *) initContext);
|
||||||
|
#endif
|
||||||
#if DEBUG_RAPTOR_CANVAS
|
#if DEBUG_RAPTOR_CANVAS
|
||||||
printf("InitEmbeddedEventHandler(%lx): Embedded Thread created...\n", initContext);
|
printf("InitEmbeddedEventHandler(%lx): Embedded Thread created...\n", initContext);
|
||||||
#endif
|
#endif
|
||||||
|
@ -352,15 +364,8 @@ InitEmbeddedEventHandler (WebShellInitContext* initContext)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef XP_UNIX
|
|
||||||
// PENDING(mark): HACK! Sleep for 3 seconds just to make sure everything
|
|
||||||
// starts up correctly. Not sure why this helps yet.
|
|
||||||
::PR_Sleep(PR_SecondsToInterval(3));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static nsEventStatus PR_CALLBACK
|
static nsEventStatus PR_CALLBACK
|
||||||
HandleRaptorEvent (nsGUIEvent *)
|
HandleRaptorEvent (nsGUIEvent *)
|
||||||
{
|
{
|
||||||
|
@ -1089,7 +1094,50 @@ Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeWebShellCreate (
|
||||||
initContext->w = width;
|
initContext->w = width;
|
||||||
initContext->h = height;
|
initContext->h = height;
|
||||||
|
|
||||||
|
#ifdef XP_UNIX
|
||||||
|
// This probably needs some explaining...
|
||||||
|
// On Unix, instead of using a NSPR thread to manage our Mozilla event loop, we
|
||||||
|
// use a Java Thread (for reasons I won't go into now, see
|
||||||
|
// org.mozilla.webclient.motif.MozillaEventThread for more details). This java thread will
|
||||||
|
// process any pending native events in
|
||||||
|
// org.mozilla.webclient.motif.MozillaEventThread.processNativeEventQueue()
|
||||||
|
// (see below). However, when processNativeEventQueue() gets called, it needs access to it's associated
|
||||||
|
// WebShellInitContext structure in order to process any GTK / Mozilla related events. So what we
|
||||||
|
// do is we keep a static Hashtable inside the class MozillaEventThread to store mappings of
|
||||||
|
// gtkWindowID's to WebShellInitContext's (since there is one WebShellInitContext to one GTK Window).
|
||||||
|
// This is what this part of the code does:
|
||||||
|
//
|
||||||
|
// 1) It first accesses the class org.mozilla.webclient.motif.MozillaEventThread
|
||||||
|
// 2) It then accesses a static method in this class called "storeContext()" which takes as
|
||||||
|
// arguments, a GTK window pointer and a WebShellInitContext pointer
|
||||||
|
// 3) Then it invokes the method
|
||||||
|
// 4) Inside MozillaEventThread.run(), you can see the code which fetches the appropriate
|
||||||
|
// WebShellInitContext and then calls processNativeEventQueue() with it below.
|
||||||
|
|
||||||
|
// PENDING(mark): Should we cache this? Probably....
|
||||||
|
jclass mozillaEventThreadClass = env->FindClass("org/mozilla/webclient/motif/MozillaEventThread");
|
||||||
|
|
||||||
|
if (mozillaEventThreadClass == NULL) {
|
||||||
|
printf("Error: Cannot find class org.mozilla.webclient.motif.MozillaEventThread!\n");
|
||||||
|
|
||||||
|
ThrowExceptionToJava(env, "Error: Cannot find class org.mozilla.webclient.motif.MozillaEventThread!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID storeMethodID = env->GetStaticMethodID(mozillaEventThreadClass, "storeContext", "(II)V");
|
||||||
|
|
||||||
|
if (storeMethodID == NULL) {
|
||||||
|
printf("Error: Cannot get static method storeContext(int, int) from MozillaEventThread!\n");
|
||||||
|
|
||||||
|
ThrowExceptionToJava(env, "Error: Cannot get static method storeContext(int, int) from MozillaEventThread!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PENDING(mark): How do I catch this if there's an exception?
|
||||||
|
env->CallStaticVoidMethod(mozillaEventThreadClass, storeMethodID, windowPtr, (int) initContext);
|
||||||
|
#else
|
||||||
InitEmbeddedEventHandler(initContext);
|
InitEmbeddedEventHandler(initContext);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (jint) initContext;
|
return (jint) initContext;
|
||||||
} // Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeWebShellCreate()
|
} // Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeWebShellCreate()
|
||||||
|
@ -1740,6 +1788,29 @@ Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeWebShellGetURL (
|
||||||
return urlString;
|
return urlString;
|
||||||
} // Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeWebShellGetURL()
|
} // Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeWebShellGetURL()
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XP_UNIX
|
||||||
|
/*
|
||||||
|
* Class: org_mozilla_webclient_motif_MotifMozillaEventQueue
|
||||||
|
* Method: processNativeEventQueue
|
||||||
|
* Signature: ()V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_org_mozilla_webclient_motif_MozillaEventThread_processNativeEventQueue
|
||||||
|
(JNIEnv * env, jobject obj, jint webShellInitContextPtr) {
|
||||||
|
// Given a WebShellInitContext pointer, process any pending Mozilla / GTK events
|
||||||
|
WebShellInitContext * initContext = (WebShellInitContext *) webShellInitContextPtr;
|
||||||
|
|
||||||
|
// Initialize the WebShellInitContext if it's hasn't been already
|
||||||
|
if (initContext->initComplete == FALSE) {
|
||||||
|
InitEmbeddedEventHandler(initContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process any pending events...
|
||||||
|
processEventLoop(initContext);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef XP_UNIX
|
#ifdef XP_UNIX
|
||||||
}// End extern "C"
|
}// End extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,11 +20,20 @@
|
||||||
* BrowserControlMozillaShimStub.cpp
|
* BrowserControlMozillaShimStub.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dlfcn.h>
|
// PENDING(mark): I suppose this is where I need to go into my explaination of why
|
||||||
#include <jni.h>
|
// this file is needed...
|
||||||
#include "../BrowserControlMozillaShim.h"
|
|
||||||
|
|
||||||
void * mozWebShellDll;
|
// For loading DLL
|
||||||
|
#include <dlfcn.h>
|
||||||
|
// JNI...yada, yada, yada
|
||||||
|
#include <jni.h>
|
||||||
|
// JNI Header
|
||||||
|
#include "../BrowserControlMozillaShim.h"
|
||||||
|
// JNI Header
|
||||||
|
#include "MozillaEventThread.h"
|
||||||
|
|
||||||
|
// Global reference to webclient dll
|
||||||
|
void * webClientDll;
|
||||||
|
|
||||||
extern void locateMotifBrowserControlStubFunctions(void *);
|
extern void locateMotifBrowserControlStubFunctions(void *);
|
||||||
|
|
||||||
|
@ -62,6 +71,8 @@ jboolean (* nativeWebShellGoTo) (JNIEnv *, jobject, jint, jint);
|
||||||
jint (* nativeWebShellGetHistoryLength) (JNIEnv *, jobject, jint);
|
jint (* nativeWebShellGetHistoryLength) (JNIEnv *, jobject, jint);
|
||||||
jint (* nativeWebShellGetHistoryIndex) (JNIEnv *, jobject, jint);
|
jint (* nativeWebShellGetHistoryIndex) (JNIEnv *, jobject, jint);
|
||||||
jstring (* nativeWebShellGetURL) (JNIEnv *, jobject, jint, jint);
|
jstring (* nativeWebShellGetURL) (JNIEnv *, jobject, jint, jint);
|
||||||
|
void (* processNativeEventQueue) (JNIEnv *, jobject, jint);
|
||||||
|
|
||||||
|
|
||||||
void locateBrowserControlStubFunctions(void * dll) {
|
void locateBrowserControlStubFunctions(void * dll) {
|
||||||
nativeInitialize = (void (*) (JNIEnv *, jobject)) dlsym(dll, "Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeInitialize");
|
nativeInitialize = (void (*) (JNIEnv *, jobject)) dlsym(dll, "Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeInitialize");
|
||||||
|
@ -200,6 +211,20 @@ void locateBrowserControlStubFunctions(void * dll) {
|
||||||
if (!nativeWebShellGetURL) {
|
if (!nativeWebShellGetURL) {
|
||||||
printf("got dlsym error %s\n", dlerror());
|
printf("got dlsym error %s\n", dlerror());
|
||||||
}
|
}
|
||||||
|
processNativeEventQueue = (void (*) (JNIEnv *, jobject, jint)) dlsym(dll, "Java_org_mozilla_webclient_motif_MozillaEventThread_processNativeEventQueue");
|
||||||
|
if (!processNativeEventQueue) {
|
||||||
|
printf("got dlsym error %s\n", dlerror());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_mozilla_webclient_motif_MotifMozillaEventQueue
|
||||||
|
* Method: processNativeEventQueue
|
||||||
|
* Signature: ()V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_org_mozilla_webclient_motif_MozillaEventThread_processNativeEventQueue
|
||||||
|
(JNIEnv * env, jobject obj, jint gtkWinPtr) {
|
||||||
|
(* processNativeEventQueue) (env, obj, gtkWinPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,11 +238,11 @@ Java_org_mozilla_webclient_BrowserControlMozillaShim_nativeInitialize (
|
||||||
JNIEnv * env,
|
JNIEnv * env,
|
||||||
jobject obj)
|
jobject obj)
|
||||||
{
|
{
|
||||||
mozWebShellDll = dlopen("libwebclient.so", RTLD_LAZY | RTLD_GLOBAL);
|
webClientDll = dlopen("libwebclient.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
|
||||||
if (mozWebShellDll) {
|
if (webClientDll) {
|
||||||
locateBrowserControlStubFunctions(mozWebShellDll);
|
locateBrowserControlStubFunctions(webClientDll);
|
||||||
locateMotifBrowserControlStubFunctions(mozWebShellDll);
|
locateMotifBrowserControlStubFunctions(webClientDll);
|
||||||
|
|
||||||
(* nativeInitialize) (env, obj);
|
(* nativeInitialize) (env, obj);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
* MotifBrowserControlCanvasStub.cpp
|
* MotifBrowserControlCanvasStub.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// PENDING(mark): I suppose this is where I need to go into my explaination of why
|
||||||
|
// this file is needed...
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include "MotifBrowserControlCanvas.h"
|
#include "MotifBrowserControlCanvas.h"
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче