diff --git a/mozilla/widget/src/photon/nsAppShell.cpp b/mozilla/widget/src/photon/nsAppShell.cpp index 2a568d51614..6728e739551 100644 --- a/mozilla/widget/src/photon/nsAppShell.cpp +++ b/mozilla/widget/src/photon/nsAppShell.cpp @@ -17,28 +17,21 @@ */ #include "prmon.h" +#include "nsCOMPtr.h" #include "nsAppShell.h" #include "nsIAppShell.h" #include "nsIServiceManager.h" #include "nsIEventQueueService.h" #include "nsICmdLineService.h" +#include "nsIObserverService.h" #include -#ifdef MOZ_GLE -#include -#endif - #include "nsIWidget.h" #include "nsIPref.h" -#include "nsIWidget.h" #include #include - -//NS_DEFINE_IID(kIAppShellIID, NS_IAPPSHELL_IID); -//NS_IMPL_ISUPPORTS(nsAppShell,kIAppShellIID); - PRBool nsAppShell::mPtInited = PR_FALSE; nsIEventQueue *kedlEQueue = nsnull; @@ -59,6 +52,10 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID); static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); +// copied from nsEventQueue.cpp +static char *gEQActivatedNotification = "nsIEventQueueActivated"; +static char *gEQDestroyedNotification = "nsIEventQueueDestroyed"; + // a linked, ordered list of event queues and their tokens class EventQueueToken { public: @@ -109,10 +106,12 @@ void EventQueueTokenQueue::PushToken(nsIEventQueue *aQueue, gint aToken) EventQueueToken *newToken = new EventQueueToken(aQueue, aToken); NS_ASSERTION(newToken, "couldn't allocate token queue element"); - if (newToken) { - newToken->next = mHead; - mHead = newToken; - } + if (!newToken) + return NS_ERROR_OUT_OF_MEMORY; + + newToken->next = mHead; + mHead = newToken; + return NS_OK; } PRBool EventQueueTokenQueue::PopToken(nsIEventQueue *aQueue, gint *aToken) @@ -155,15 +154,17 @@ nsAppShell::nsAppShell() NS_INIT_REFCNT(); mDispatchListener = nsnull; - mLock = PR_NewLock(); +// mLock = PR_NewLock(); mEventQueueTokens = new EventQueueTokenQueue(); - mEventBufferSz = sizeof( PhEvent_t ) + 1000; - mEvent = (PhEvent_t*) PR_Malloc( mEventBufferSz ); +// mEventBufferSz = sizeof( PhEvent_t ) + 1000; +// mEvent = (PhEvent_t*) PR_Malloc( mEventBufferSz ); // throw on error would really be civilized here - NS_ASSERTION(mLock, "couldn't obtain lock in appshell"); +// NS_ASSERTION(mLock, "couldn't obtain lock in appshell"); NS_ASSERTION(mEventQueueTokens, "couldn't allocate event queue token queue"); - NS_ASSERTION( mEvent, "Out of memory" ); +// NS_ASSERTION( mEvent, "Out of memory" ); + + RegisterObserver(PR_TRUE); /* Run this only once per application startup */ if( !mPtInited ) @@ -183,11 +184,13 @@ nsAppShell::~nsAppShell() { PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::~nsAppShell\n")); - PR_DestroyLock(mLock); +// PR_DestroyLock(mLock); delete mEventQueueTokens; - if (mEvent) - PR_Free(mEvent); +// if (mEvent) +// PR_Free(mEvent); + + RegisterObserver(PR_FALSE); } @@ -196,8 +199,7 @@ nsAppShell::~nsAppShell() // nsISupports implementation macro // //------------------------------------------------------------------------- -NS_IMPL_ISUPPORTS1(nsAppShell, nsIAppShell) - +NS_IMPL_ISUPPORTS2(nsAppShell, nsIAppShell, nsIObserver) //------------------------------------------------------------------------- NS_IMETHODIMP nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener) @@ -278,6 +280,8 @@ NS_METHOD nsAppShell::Spindown() return NS_OK; } + +#if 0 //------------------------------------------------------------------------- // // PushThreadEventQueue @@ -352,6 +356,7 @@ PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::PopThreadEventQueue\n")); NS_ERROR("Appshell unable to obtain eventqueue service."); return rv; } +#endif int done_damn_it = 0; @@ -422,7 +427,8 @@ done: printf("nsAppShell::Run Error calling PtAppAddFd\n"); exit(1); } - MyMainLoop(); + + MyMainLoop(); /* PtMainLoop() */ #ifdef DEBUG printf("Calling PtAppRemoveFd with event queue\n"); @@ -454,6 +460,7 @@ NS_METHOD nsAppShell::Exit() return NS_OK; } +#if 0 //------------------------------------------------------------------------- // // GetNativeData @@ -470,6 +477,7 @@ void* nsAppShell::GetNativeData(PRUint32 aDataType) } return nsnull; } +#endif NS_METHOD nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent) @@ -588,3 +596,97 @@ NS_METHOD nsAppShell::EventIsForModalWindow(PRBool aRealEvent, void *aEvent, nsI return NS_OK; #endif } + + +//------------------------------------------------------------------------- +// nsIObserver interface +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +// +// Observe +// +//------------------------------------------------------------------------- + +NS_IMETHODIMP nsAppShell::Observe(nsISupports *aSubject, + const PRUnichar *aTopic, + const PRUnichar *) +{ + // tell gdk to listen to the event queue or not. what happens + // if multiple appshells (horrors, but it happens) repeat the same + // instruction, one wonders. + + gint queueToken; + int err; + + nsAutoString topic(aTopic); + + if (topic.Equals(gEQActivatedNotification)) { + nsCOMPtr eq(do_QueryInterface(aSubject)); + if (eq) { +#if 0 + queueToken = gdk_input_add(eq->GetEventQueueSelectFD(), + GDK_INPUT_READ, + event_processor_callback, + eq); +#else + err = PtAppAddFd(NULL,eq->GetEventQueueSelectFD(),Pt_FD_READ,event_processor_callback,eq); + if (err == -1) + { + printf("nsAppShell::PushThreadEventQueue Error calling PtAppAddFd\n"); + exit(1); + } +#endif + mEventQueueTokens->PushToken(eq, queueToken); + } + } else if (topic.Equals(gEQDestroyedNotification)) { + nsCOMPtr eq(do_QueryInterface(aSubject)); + if (eq) { + if (mEventQueueTokens->PopToken(eq, &queueToken)) +#if 0 + gdk_input_remove(queueToken); +#else + err=PtAppRemoveFd(NULL,eq->GetEventQueueSelectFD()); + if ( err == -1) + { + printf("nsAppShell::PopThreadEventQueue Error calling PtAppRemoveFd\n"); + exit(1); + } +#endif + } + } + return NS_OK; +} + +//------------------------------------------------------------------------- +// +// Observe +// +//------------------------------------------------------------------------- +void nsAppShell::RegisterObserver(PRBool aRegister) +{ + nsresult rv; + nsAutoString topicA(gEQActivatedNotification); + nsAutoString topicB(gEQDestroyedNotification); + + NS_WITH_SERVICE(nsIObserverService, os, NS_OBSERVERSERVICE_PROGID, &rv); + if (NS_SUCCEEDED(rv)) { +#if 0 + nsCOMPtr us(do_QueryInterface(this)); + if (us) { +#else + nsIObserver *us; + if (NS_SUCCEEDED(QueryInterface(nsIObserver::GetIID(), (void **) &us)) && us) { +#endif + if (aRegister) { + os->AddObserver(us, topicA.GetUnicode()); + os->AddObserver(us, topicB.GetUnicode()); + } else { + os->RemoveObserver(us, topicA.GetUnicode()); + os->RemoveObserver(us, topicB.GetUnicode()); + } + NS_RELEASE(us); + } + } +} + diff --git a/mozilla/widget/src/photon/nsAppShell.h b/mozilla/widget/src/photon/nsAppShell.h index 7d68936b792..2fee940a4af 100644 --- a/mozilla/widget/src/photon/nsAppShell.h +++ b/mozilla/widget/src/photon/nsAppShell.h @@ -19,8 +19,9 @@ #ifndef nsAppShell_h__ #define nsAppShell_h__ -#include #include "nsIAppShell.h" +#include "nsIObserver.h" +#include /** * Native Photon Application shell wrapper @@ -28,17 +29,18 @@ class nsIEventQueueService; class EventQueueTokenQueue; -struct PRLock; - -class nsAppShell : public nsIAppShell +class nsAppShell : public nsIAppShell, + public nsIObserver { public: - nsAppShell(); + nsAppShell(); virtual ~nsAppShell(); NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + PRBool OnPaint(); // nsIAppShellInterface @@ -47,33 +49,26 @@ class nsAppShell : public nsIAppShell virtual nsresult Run(); NS_IMETHOD Spinup(); NS_IMETHOD Spindown(); - NS_IMETHOD PushThreadEventQueue(); - NS_IMETHOD PopThreadEventQueue(); NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent); NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent); - NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener); - NS_IMETHOD Exit(); - virtual void* GetNativeData(PRUint32 aDataType); -// NS_IMETHOD GetSelectionMgr(nsISelectionMgr** aSelectionMgr); - - // XXX temporary for Dialog investigation - -// NS_IMETHOD GetNativeEvent(void *& aEvent, nsIWidget* aWidget, PRBool &aIsInWindow, PRBool &aIsMouseEvent); -// NS_IMETHOD DispatchNativeEvent(void * aEvent); NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent, nsIWidget *aWidget, PRBool *aForWindow); - private: + NS_IMETHOD Exit(); + NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener); + +private: + void RegisterObserver(PRBool aRegister); nsDispatchListener *mDispatchListener; -//nsISelectionMgr *mSelectionMgr; - unsigned long mEventBufferSz; - PhEvent_t *mEvent; + EventQueueTokenQueue *mEventQueueTokens; static PRBool mPtInited; -//nsIEventQueueService * mEventQService; - PRLock *mLock; - EventQueueTokenQueue *mEventQueueTokens; +// unsigned long mEventBufferSz; +// PhEvent_t *mEvent; +// nsIEventQueueService * mEventQService; +// PRLock *mLock; + }; #endif // nsAppShell_h__ diff --git a/mozilla/widget/src/photon/nsWidgetFactory.cpp b/mozilla/widget/src/photon/nsWidgetFactory.cpp index c9ba9243604..0aa70e20847 100644 --- a/mozilla/widget/src/photon/nsWidgetFactory.cpp +++ b/mozilla/widget/src/photon/nsWidgetFactory.cpp @@ -244,7 +244,7 @@ nsresult nsWidgetFactory::CreateInstance( nsISupports *aOuter, else if (mClassID.Equals(kCAppShell)) { PR_LOG(PhWidLog, PR_LOG_DEBUG,( "nsWidgetFactory::CreateInstance of nsAppShell\n" )); - inst = (nsISupports*)new nsAppShell(); + inst = (nsISupports*)(nsIAppShell*)new nsAppShell(); } else if (mClassID.Equals(kCToolkit)) { PR_LOG(PhWidLog, PR_LOG_DEBUG,( "nsWidgetFactory::CreateInstance of nsToolkit\n" ));