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:
mark.lin%eng.sun.com 1999-08-13 23:01:49 +00:00
Родитель 944678da9d
Коммит 7c7f47fff4
3 изменённых файлов: 118 добавлений и 19 удалений

Просмотреть файл

@ -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
@ -302,14 +303,19 @@ EmbeddedEventHandler (void * arg) {
#if DEBUG_RAPTOR_CANVAS #if DEBUG_RAPTOR_CANVAS
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"