adding method ListenToEventQueue (moving EventQueue observation from appshells to appshellservice) r:hyatt@netscape.com

This commit is contained in:
danm%netscape.com 1999-10-21 21:34:57 +00:00
Родитель 7e6d27b0c2
Коммит 59ec625f46
14 изменённых файлов: 92 добавлений и 151 удалений

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

@ -26,6 +26,7 @@
native int(int);
[ptr] native nsDispatchListener(nsDispatchListener);
[ptr] native nsIEventQueue(nsIEventQueue);
[ptr] native UndefinednsIWidget(nsIWidget);
[ref] native PRBoolRef(PRBool);
[ref] native voidStarRef(void *);
@ -81,6 +82,15 @@ interface nsIAppShell : nsISupports
void Spindown();
/**
* An event queue has been created or destroyed. Hook or unhook it from
* your system, as necessary.
* @param aQueue the queue in question
* @param aListen PR_TRUE for a new queue wanting hooking up. PR_FALSE
* for a queue wanting to be unhooked.
*/
void ListenToEventQueue(in nsIEventQueue aQueue, in PRBool aListen);
/**
* After event dispatch execute app specific code
*/

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

@ -41,6 +41,8 @@ class nsAppShell : public nsIAppShell
virtual nsresult Run();
NS_IMETHOD Spinup();
NS_IMETHOD Spindown();
NS_IMETHOD ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen)
{ return NS_OK; }
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent,

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

@ -23,7 +23,6 @@
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsICmdLineService.h"
#include "nsIObserverService.h"
#include <stdlib.h>
#ifdef MOZ_GLE
@ -42,10 +41,6 @@ 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:
@ -53,13 +48,13 @@ public:
const nsIEventQueue *mQueue;
gint mToken;
EventQueueToken *next;
EventQueueToken *mNext;
};
EventQueueToken::EventQueueToken(const nsIEventQueue *aQueue, const gint aToken) {
mQueue = aQueue;
mToken = aToken;
next = 0;
mNext = 0;
}
class EventQueueTokenQueue {
public:
@ -77,8 +72,19 @@ EventQueueTokenQueue::EventQueueTokenQueue() {
}
EventQueueTokenQueue::~EventQueueTokenQueue() {
NS_ASSERTION(!mHead, "event queue token deleted when not empty");
// and leak. it's an error, anyway
// if we reach this point with an empty token queue, well, fab. however,
// we expect the first event queue to still be active. so we take
// special care to unhook that queue (not that failing to do so seems
// to hurt anything). more queues than that would be an error.
//NS_ASSERTION(!mHead || !mHead->mNext, "event queue token list deleted when not empty");
// (and skip the assertion for now. we're leaking event queues because they
// are referenced by things that leak, so this assertion goes off a lot.)
if (mHead) {
gdk_input_remove(mHead->mToken);
delete mHead;
// and leak the rest. it's an error, anyway
}
}
nsresult EventQueueTokenQueue::PushToken(nsIEventQueue *aQueue, gint aToken) {
@ -87,7 +93,7 @@ nsresult EventQueueTokenQueue::PushToken(nsIEventQueue *aQueue, gint aToken) {
if (!newToken)
return NS_ERROR_OUT_OF_MEMORY;
newToken->next = mHead;
newToken->mNext = mHead;
mHead = newToken;
return NS_OK;
}
@ -103,13 +109,13 @@ PRBool EventQueueTokenQueue::PopToken(nsIEventQueue *aQueue, gint *aToken) {
lastToken = 0;
while (token && token->mQueue != aQueue) {
lastToken = token;
token = token->next;
token = token->mNext;
}
if (token) {
if (lastToken)
lastToken->next = token->next;
lastToken->mNext = token->mNext;
else
mHead = token->next;
mHead = token->mNext;
found = PR_TRUE;
*aToken = token->mToken;
delete token;
@ -129,7 +135,6 @@ nsAppShell::nsAppShell()
mEventQueueTokens = new EventQueueTokenQueue();
// throw on error would really be civilized here
NS_ASSERTION(mEventQueueTokens, "couldn't allocate event queue token queue");
RegisterObserver(PR_TRUE);
}
//-------------------------------------------------------------------------
@ -140,7 +145,6 @@ nsAppShell::nsAppShell()
nsAppShell::~nsAppShell()
{
delete mEventQueueTokens;
RegisterObserver(PR_FALSE);
}
//-------------------------------------------------------------------------
@ -149,7 +153,7 @@ nsAppShell::~nsAppShell()
//
//-------------------------------------------------------------------------
NS_IMPL_ISUPPORTS2(nsAppShell, nsIAppShell, nsIObserver)
NS_IMPL_ISUPPORTS1(nsAppShell, nsIAppShell)
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener)
@ -326,10 +330,9 @@ done:
printf("Calling gdk_input_add with event queue\n");
#endif /* DEBUG */
gdk_input_add(EQueue->GetEventQueueSelectFD(),
GDK_INPUT_READ,
event_processor_callback,
EQueue);
// (has to be called explicitly for this, the primordial appshell, because
// of startup ordering problems.)
ListenToEventQueue(EQueue, PR_TRUE);
gtk_main();
@ -423,75 +426,23 @@ NS_IMETHODIMP nsAppShell::EventIsForModalWindow(PRBool aRealEvent,
return NS_OK;
}
//-------------------------------------------------------------------------
// nsIObserver interface
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//
// Observe
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Observe(nsISupports *aSubject,
const PRUnichar *aTopic,
const PRUnichar *)
NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue *aQueue,
PRBool aListen)
{
// 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.
// tell gdk to listen to the event queue or not
gint queueToken;
nsAutoString topic(aTopic);
if (topic.Equals(gEQActivatedNotification)) {
nsCOMPtr<nsIEventQueue> eq(do_QueryInterface(aSubject));
if (eq) {
queueToken = gdk_input_add(eq->GetEventQueueSelectFD(),
if (aListen) {
queueToken = gdk_input_add(aQueue->GetEventQueueSelectFD(),
GDK_INPUT_READ,
event_processor_callback,
eq);
mEventQueueTokens->PushToken(eq, queueToken);
}
} else if (topic.Equals(gEQDestroyedNotification)) {
nsCOMPtr<nsIEventQueue> eq(do_QueryInterface(aSubject));
if (eq) {
if (mEventQueueTokens->PopToken(eq, &queueToken))
aQueue);
mEventQueueTokens->PushToken(aQueue, queueToken);
} else {
if (mEventQueueTokens->PopToken(aQueue, &queueToken))
gdk_input_remove(queueToken);
}
}
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<nsIObserver> 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);
}
}
}

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

@ -20,42 +20,24 @@
#define nsAppShell_h__
#include "nsIAppShell.h"
#include "nsIObserver.h"
#include <gtk/gtk.h>
/**
* Native GTK+ Application shell wrapper
*/
class nsIEventQueue;
class EventQueueTokenQueue;
class nsAppShell : public nsIAppShell,
public nsIObserver
class nsAppShell : public nsIAppShell
{
public:
nsAppShell();
virtual ~nsAppShell();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
// nsIAppShellInterface
NS_IMETHOD Create(int* argc, char ** argv);
NS_IMETHOD Run();
NS_IMETHOD Spinup();
NS_IMETHOD Spindown();
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent,
nsIWidget *aWidget, PRBool *aForWindow);
NS_IMETHOD Exit();
NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener);
NS_DECL_NSIAPPSHELL
private:
void RegisterObserver(PRBool aRegister);
nsDispatchListener *mDispatchListener;
EventQueueTokenQueue *mEventQueueTokens;
};

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

@ -204,7 +204,7 @@ nsresult nsWidgetFactory::CreateInstance(nsISupports *aOuter,
inst = (nsISupports*)(nsWidget *)new nsTextWidget();
}
else if (mClassID.Equals(kCAppShell)) {
inst = (nsISupports*)(nsIAppShell*)new nsAppShell();
inst = (nsISupports*)new nsAppShell();
}
else if (mClassID.Equals(kCToolkit)) {
inst = (nsISupports*)(nsWidget *)new nsToolkit();

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

@ -84,7 +84,7 @@ NS_IMETHODIMP nsAppShell::Create(int* argc, char ** argv)
// Enter a message handler loop
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Run()
NS_IMETHODIMP nsAppShell::Run(void)
{
if (!mMacPump.get())
return NS_ERROR_NOT_INITIALIZED;
@ -110,7 +110,7 @@ NS_IMETHODIMP nsAppShell::Run()
// Exit appshell
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Exit()
NS_IMETHODIMP nsAppShell::Exit(void)
{
if (mMacPump.get())
{
@ -124,12 +124,22 @@ NS_IMETHODIMP nsAppShell::Exit()
return NS_OK;
}
//-------------------------------------------------------------------------
//
// respond to notifications that an event queue has come or gone
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue * aQueue, PRBool aListen)
{ // unnecessary; handled elsewhere
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Prepare to process events
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Spinup()
NS_IMETHODIMP nsAppShell::Spinup(void)
{
if (mMacPump.get())
{
@ -144,7 +154,7 @@ NS_IMETHODIMP nsAppShell::Spinup()
// Stop being prepared to process events.
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Spindown()
NS_IMETHODIMP nsAppShell::Spindown(void)
{
if (mMacPump.get())
mMacPump->StopRunning();

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

@ -44,26 +44,13 @@ class nsAppShell : public nsIAppShell
virtual ~nsAppShell();
NS_DECL_ISUPPORTS
// nsIAppShellInterface
NS_IMETHOD Create(int* argc, char ** argv);
NS_IMETHOD Run();
NS_IMETHOD Spinup();
NS_IMETHOD Spindown();
NS_IMETHOD Exit();
NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener);
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void *aEvent);
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent, nsIWidget *aWidget,
PRBool *aForWindow);
NS_DECL_NSIAPPSHELL
private:
nsDispatchListener *mDispatchListener; // note: we don't own this, but it can be NULL
auto_ptr<nsToolkit> mToolKit;
auto_ptr<nsMacMessagePump> mMacPump;
auto_ptr<nsMacMessageSink> mMacSink; //¥¥¥ this will be COM, so use scc's COM_auto_ptr
auto_ptr<nsMacMessageSink> mMacSink; //€€€ this will be COM, so use scc's COM_auto_ptr
PRBool mExitCalled;
static PRBool mInitializedToolbox;
};

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

@ -44,6 +44,8 @@ class nsAppShell : public nsIAppShell
NS_IMETHOD Run();
NS_IMETHOD Spinup();
NS_IMETHOD Spindown();
NS_IMETHOD ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen)
{ return NS_OK; }
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
NS_IMETHOD Exit();

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

@ -41,6 +41,8 @@ class nsAppShell : public nsIAppShell
NS_IMETHOD Spinup() { return NS_OK; }
NS_IMETHOD Run();
NS_IMETHOD Spindown() { return NS_OK; }
NS_IMETHOD ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen)
{ return NS_OK; }
NS_IMETHOD Exit();
NS_IMETHOD GetNativeEvent( PRBool &aRealEvent, void *&aEvent);

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

@ -20,7 +20,6 @@
#define nsAppShell_h__
#include "nsIAppShell.h"
#include "nsIObserver.h"
#include <Pt.h>
/**
@ -30,8 +29,7 @@
class nsIEventQueueService;
class EventQueueTokenQueue;
class nsAppShell : public nsIAppShell,
public nsIObserver
class nsAppShell : public nsIAppShell
{
public:
nsAppShell();
@ -39,8 +37,6 @@ class nsAppShell : public nsIAppShell,
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
PRBool OnPaint();
// nsIAppShellInterface
@ -49,6 +45,8 @@ class nsAppShell : public nsIAppShell,
virtual nsresult Run();
NS_IMETHOD Spinup();
NS_IMETHOD Spindown();
NS_IMETHOD ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen)
{ return NS_OK; }
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent, nsIWidget *aWidget,
@ -58,8 +56,6 @@ class nsAppShell : public nsIAppShell,
NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener);
private:
void RegisterObserver(PRBool aRegister);
nsDispatchListener *mDispatchListener;
EventQueueTokenQueue *mEventQueueTokens;
static PRBool mPtInited;

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

@ -44,6 +44,8 @@ public:
NS_IMETHOD Run();
NS_IMETHOD Spinup();
NS_IMETHOD Spindown();
NS_IMETHOD ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen)
{ return NS_OK; }
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent,

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

@ -63,7 +63,7 @@ NS_METHOD nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener)
//
//-------------------------------------------------------------------------
NS_METHOD nsAppShell::Run()
NS_METHOD nsAppShell::Run(void)
{
NS_ADDREF_THIS();
// Process messages
@ -78,6 +78,15 @@ NS_METHOD nsAppShell::Run()
return msg.wParam;
}
inline NS_METHOD nsAppShell::Spinup(void)
{ return NS_OK; }
inline NS_METHOD nsAppShell::Spindown(void)
{ return NS_OK; }
inline NS_METHOD nsAppShell::ListenToEventQueue(nsIEventQueue * aQueue, PRBool aListen)
{ return NS_OK; }
NS_METHOD
nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
{
@ -174,7 +183,7 @@ nsresult nsAppShell::DispatchNativeEvent(PRBool aRealEvent, void *aEvent)
//
//-------------------------------------------------------------------------
NS_METHOD nsAppShell::Exit()
NS_METHOD nsAppShell::Exit(void)
{
PostQuitMessage(0);
return NS_OK;

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

@ -32,25 +32,11 @@ class nsAppShell : public nsIAppShell
virtual ~nsAppShell();
NS_DECL_ISUPPORTS
PRBool OnPaint();
// nsIAppShellInterface
NS_IMETHOD Create(int* argc, char ** argv);
NS_IMETHOD Run();
NS_IMETHOD Spinup() { return NS_OK; }
NS_IMETHOD Spindown() { return NS_OK; }
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent,
nsIWidget *aWidget, PRBool *aForWindow);
NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener);
NS_IMETHOD Exit();
NS_DECL_NSIAPPSHELL
private:
nsDispatchListener* mDispatchListener;
};
#endif // nsAppShell_h__

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

@ -36,6 +36,8 @@ class nsAppShell : public nsIAppShell
virtual nsresult Run();
NS_IMETHOD Spinup() { return NS_OK; }
NS_IMETHOD Spindown() { return NS_OK; }
NS_IMETHOD ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen)
{ return NS_OK; }
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent,