Fixes for event handling.
This commit is contained in:
briane%qnx.com 2000-10-17 15:37:29 +00:00
Родитель ec1258a408
Коммит 004469e627
1 изменённых файлов: 80 добавлений и 53 удалений

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

@ -40,6 +40,10 @@
/* Global Definitions */ /* Global Definitions */
PRBool nsAppShell::gExitMainLoop = PR_FALSE; PRBool nsAppShell::gExitMainLoop = PR_FALSE;
static PRBool sInitialized = PR_FALSE;
static PLHashTable *sQueueHashTable = nsnull;
static PLHashTable *sCountHashTable = nsnull;
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// XPCOM CIDs // XPCOM CIDs
@ -54,16 +58,14 @@ our_photon_input_add (int fd,
PtFdProc_t event_processor_callback, PtFdProc_t event_processor_callback,
void *data) void *data)
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::our_photon_input_add fd=<%d>\n", fd));
int err = PtAppAddFd(NULL, fd, (Pt_FD_READ | Pt_FD_NOPOLL), int err = PtAppAddFd(NULL, fd, (Pt_FD_READ | Pt_FD_NOPOLL),
event_processor_callback,data); event_processor_callback,data);
if (err != 0) if (err != 0)
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::our_photon_input_add Error calling PtAppAddFD errno=<%d>\n", errno));
NS_ASSERTION(0,"nsAppShell::our_photon_input_add Error calling PtAppAddFD\n"); NS_ASSERTION(0,"nsAppShell::our_photon_input_add Error calling PtAppAddFD\n");
abort();
} }
return (err);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -73,8 +75,6 @@ our_photon_input_add (int fd,
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
nsAppShell::nsAppShell() nsAppShell::nsAppShell()
{ {
// PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::nsAppShell Constructor this=<%p>\n", this));
mEventQueue = nsnull; mEventQueue = nsnull;
mFD = -1; mFD = -1;
NS_INIT_REFCNT(); NS_INIT_REFCNT();
@ -87,18 +87,13 @@ nsAppShell::nsAppShell()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
nsAppShell::~nsAppShell() nsAppShell::~nsAppShell()
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::~nsAppShell this=<%p> mFD=<%d>\n", this, mFD));
if (mFD != -1) if (mFD != -1)
{ {
int err=PtAppRemoveFd(NULL,mFD); int err=PtAppRemoveFd(NULL,mFD);
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::~nsAppShell Calling PtAppRemoveFd for mFD=<%d> err=<%d>\n", mFD, err));
if (err==-1) if (err==-1)
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG,("nsAppShell::~nsAppShell Error calling PtAppRemoveFd mFD=<%d> errno=<%d>\n", mFD, errno));
printf("nsAppShell::~EventQueueTokenQueue Run Error calling PtAppRemoveFd mFD=<%d> errno=<%d>\n", mFD, errno); printf("nsAppShell::~EventQueueTokenQueue Run Error calling PtAppRemoveFd mFD=<%d> errno=<%d>\n", mFD, errno);
//abort();
} }
mFD = -1; mFD = -1;
} }
@ -115,7 +110,6 @@ NS_IMPL_ISUPPORTS1(nsAppShell, nsIAppShell)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener) NS_IMETHODIMP nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener)
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::SetDispatchListener. this=<%p>\n", this));
return NS_OK; return NS_OK;
} }
@ -131,8 +125,6 @@ static int event_processor_callback(int fd, void *data, unsigned mode)
nsIEventQueue *eventQueue = (nsIEventQueue*)data; nsIEventQueue *eventQueue = (nsIEventQueue*)data;
if (eventQueue) if (eventQueue)
eventQueue->ProcessPendingEvents(); eventQueue->ProcessPendingEvents();
else
NS_WARNING("nsAppShell::event_processor_callback eventQueue is NULL\n");
return Pt_CONTINUE; return Pt_CONTINUE;
} }
@ -183,34 +175,39 @@ NS_IMETHODIMP nsAppShell::Create(int *bac, char **bav)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsAppShell::Spinup() NS_METHOD nsAppShell::Spinup()
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::Spinup this=<%p>\n", this));
nsresult rv = NS_OK; nsresult rv = NS_OK;
// Get the event queue service // Get the event queue service
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv); nsCOMPtr<nsIEventQueueService> eventQService = do_GetService(kEventQueueServiceCID, &rv);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_ASSERTION("Could not obtain event queue service", PR_FALSE); NS_ASSERTION("Could not obtain event queue service", PR_FALSE);
return rv; return rv;
} }
//Get the event queue for the thread. //Get the event queue for the thread.
//rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &mEventQueue); rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &mEventQueue);
// If a queue already present use it.
if (mEventQueue)
return rv;
// Create the event queue for the thread // If we got an event queue, use it.
if (mEventQueue)
goto done;
// otherwise create a new event queue for the thread
rv = eventQService->CreateThreadEventQueue(); rv = eventQService->CreateThreadEventQueue();
if (NS_OK != rv) { if (NS_FAILED(rv)) {
NS_ASSERTION("Could not create the thread event queue", PR_FALSE); NS_ASSERTION("Could not create the thread event queue", PR_FALSE);
return rv; return rv;
} }
//Get the event queue for the thread // Ask again nicely for the event queue now that we have created one.
//rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &mEventQueue); rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &mEventQueue);
// XXX shouldn't this be automatic?
done:
ListenToEventQueue(mEventQueue, PR_TRUE);
return rv; return rv;
} }
@ -221,12 +218,10 @@ NS_METHOD nsAppShell::Spinup()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsAppShell::Spindown() NS_METHOD nsAppShell::Spindown()
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::Spindown this=<%p>\n", this)); if (mEventQueue) {
ListenToEventQueue(mEventQueue, PR_FALSE);
if (mEventQueue)
{
mEventQueue->ProcessPendingEvents(); mEventQueue->ProcessPendingEvents();
NS_RELEASE(mEventQueue); mEventQueue = nsnull;
} }
return NS_OK; return NS_OK;
@ -254,26 +249,13 @@ void MyMainLoop( void )
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Run() NS_IMETHODIMP nsAppShell::Run()
{ {
int temp_fd;
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::Run this=<%p>\n", this));
if (!mEventQueue) if (!mEventQueue)
Spinup(); Spinup();
if (!mEventQueue) if (!mEventQueue)
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
temp_fd = mEventQueue->GetEventQueueSelectFD(); // kick up gtk_main. this won't return until gtk_main_quit is called
/* Don't re-add the fd if its already been added */
/* this occurs when the user creates a new profile. */
if (mFD != temp_fd)
{
mFD = temp_fd;
our_photon_input_add(mFD, event_processor_callback, mEventQueue);
}
MyMainLoop(); MyMainLoop();
Spindown(); Spindown();
@ -289,8 +271,6 @@ NS_IMETHODIMP nsAppShell::Run()
NS_METHOD nsAppShell::Exit() NS_METHOD nsAppShell::Exit()
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::Exit.\n"));
NS_WARNING("nsAppShell::Exit Called...\n");
gExitMainLoop = PR_TRUE; gExitMainLoop = PR_TRUE;
return NS_OK; return NS_OK;
@ -299,10 +279,8 @@ NS_METHOD nsAppShell::Exit()
NS_METHOD nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent) NS_METHOD nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::GetNativeEvent this=<%p>\n", this));
aEvent = NULL;
aRealEvent = PR_FALSE; aRealEvent = PR_FALSE;
aEvent = 0;
return NS_OK; return NS_OK;
} }
@ -318,12 +296,61 @@ NS_METHOD nsAppShell::DispatchNativeEvent(PRBool aRealEvent, void * aEvent)
PtProcessEvent(); PtProcessEvent();
return mEventQueue->ProcessPendingEvents(); return NS_OK;
}
#define NUMBER_HASH_KEY(_num) ((PLHashNumber) _num)
static PLHashNumber
IntHashKey(PRInt32 key)
{
return NUMBER_HASH_KEY(key);
} }
NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue *aQueue, NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue *aQueue,
PRBool aListen) PRBool aListen)
{ {
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::ListenToEventQueue aQueue=<%p> aListen=<%d>\n", aQueue, aListen)); if (!sQueueHashTable) {
sQueueHashTable = PL_NewHashTable(3, (PLHashFunction)IntHashKey,
PL_CompareValues, PL_CompareValues, 0, 0);
}
if (!sCountHashTable) {
sCountHashTable = PL_NewHashTable(3, (PLHashFunction)IntHashKey,
PL_CompareValues, PL_CompareValues, 0, 0);
}
if (aListen) {
/* add listener */
PRInt32 key = aQueue->GetEventQueueSelectFD();
/* only add if we arn't already in the table */
if (!PL_HashTableLookup(sQueueHashTable, (void *)(key))) {
int tag;
tag = our_photon_input_add(aQueue->GetEventQueueSelectFD(),
event_processor_callback,
aQueue);
if (tag >= 0) {
PL_HashTableAdd(sQueueHashTable, (void *)(key), (void *)(tag));
}
}
/* bump up the count */
int count = (int)(PL_HashTableLookup(sCountHashTable, (void *)(key)));
PL_HashTableAdd(sCountHashTable, (void *)(key), (void *)(count+1));
} else {
/* remove listener */
PRInt32 key = aQueue->GetEventQueueSelectFD();
int count = (int)(PL_HashTableLookup(sCountHashTable, (void *)(key)));
if (count - 1 == 0) {
int tag = (int)(PL_HashTableLookup(sQueueHashTable, (void *)(key)));
if (tag > 0) {
PtAppRemoveFd(NULL, key);
PL_HashTableRemove(sQueueHashTable, (void *)(key));
}
}
PL_HashTableAdd(sCountHashTable, (void *)(key), (void *)(count-1));
}
return NS_OK; return NS_OK;
} }