tbogard%aol.net c802cd626d 1.) nsIEvent now has an attribute for isExitEvent(). This allows one to test if the current event represented by nsIEvent is a signal to exit the loop.
2.)  The various Run* routines were made more general.  This allowed me to move them completely within the nsCBaseLoop code rather than have them duplicated across the different Base Loop Typed classes.  This avoids the cut and pasting of code, that will probably be tweaked in the future.

3.)  To support the new Run* routines, I have added a RetrieveNextEvent and then a PlatformRetrieveNextEvent.  The first is implemented in nsCBaseLoop.  This was added to facilitate ordering of event retrieval in the near future (ie, pulling system events before normal events, or pulling PLEvents etc.)  The second function is one that platform code must override.  This is different for each loop type.  Basically this is supposed to be whatever it takes for a given implementation to pull the next event off the queue for the given loop type.  So in the Windows world, this function calls GetMessage() for the Thread and App loop types and then PeekMessage() with PM_REMOVE set for the Breath loop type.

This code is compiled but not used by the main build.  A=chofmann


git-svn-id: svn://10.0.0.236/trunk@49214 18797224-902f-48f8-a5cc-f745e15eee43
1999-09-28 16:52:10 +00:00

396 lines
11 KiB
C++

/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* Travis Bogard <travis@netscape.com>
*/
#include "nsCOMPtr.h"
#include "nsCBaseLoop.h"
#include "nsCEvent.h"
#include "nsCEventFilter.h"
//*****************************************************************************
//*** nsCBaseLoop: Object Management
//*****************************************************************************
nsCBaseLoop::nsCBaseLoop(nsEventLoopType type) : m_Type(type)
{
NS_INIT_REFCNT();
}
nsCBaseLoop::~nsCBaseLoop()
{
}
//*****************************************************************************
// nsCBaseLoop::nsISupports
//*****************************************************************************
NS_IMPL_ISUPPORTS3(nsCBaseLoop, nsIEventLoop, nsPIEventLoop,
nsISupportsWeakReference)
//*****************************************************************************
// nsCBaseLoop::nsIEventLoop
//*****************************************************************************
NS_IMETHODIMP nsCBaseLoop::Run(nsIEventFilter* filter,
nsITranslateListener* translateListener,
nsIDispatchListener* dispatchListener, PRInt32* retCode)
{
nsCOMPtr<nsIEvent> event;
CreateNewEvent(getter_AddRefs(event));
nsresult rv;
nsCOMPtr<nsIEventFilter> localFilter(dont_QueryInterface(filter));
if(!localFilter)
NS_ENSURE_SUCCESS(CreateNewEventFilter(getter_AddRefs(localFilter)),
NS_ERROR_FAILURE);
if(translateListener)
{
if(dispatchListener)
rv = RunWithTranslateAndDispatchListener(event, localFilter,
translateListener, dispatchListener);
else
rv = RunWithTranslateListener(event, localFilter, translateListener);
}
else if(dispatchListener)
rv = RunWithDispatchListener(event, localFilter, dispatchListener);
else
rv = RunWithNoListener(event, localFilter);
if(NS_FAILED(rv))
{
if(retCode)
*retCode = PlatformGetReturnCode(nsnull);
return NS_ERROR_FAILURE;
}
if(retCode)
*retCode = PlatformGetReturnCode(event);
return NS_OK;
}
NS_IMETHODIMP nsCBaseLoop::Exit(PRInt32 exitCode)
{
return PlatformExit(exitCode);
}
NS_IMETHODIMP nsCBaseLoop::CloneEvent(nsIEvent* event, nsIEvent** newEvent)
{
NS_ENSURE_ARG(event);
NS_ENSURE_ARG_POINTER(newEvent);
void* platformEventData = nsnull;
if(event)
{
platformEventData = GetPlatformEventData(event);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
}
nsCEvent* cEvent = new nsCEvent(platformEventData);
if(!cEvent)
return NS_ERROR_OUT_OF_MEMORY;
cEvent->AddRef();
nsresult rv = cEvent->QueryInterface(NS_GET_IID(nsIEvent), (void**)newEvent);
cEvent->Release();
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
return NS_OK;
}
NS_IMETHODIMP nsCBaseLoop::CreateNewEvent(nsIEvent** newEvent)
{
NS_ENSURE_ARG_POINTER(newEvent);
nsCEvent* event = new nsCEvent();
NS_ENSURE(event, NS_ERROR_OUT_OF_MEMORY);
event->AddRef();
nsresult rv = event->QueryInterface(NS_GET_IID(nsIEvent), (void**)newEvent);
event->Release();
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
return NS_OK;
}
NS_IMETHODIMP nsCBaseLoop::CreateNewEventFilter(nsIEventFilter** newFilter)
{
NS_ENSURE_ARG_POINTER(newFilter);
nsCEventFilter* filter = new nsCEventFilter();
NS_ENSURE(filter, NS_ERROR_OUT_OF_MEMORY);
filter->AddRef();
nsresult rv = filter->QueryInterface(NS_GET_IID(nsIEventFilter), (void**)newFilter);
filter->Release();
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
return NS_OK;
}
NS_IMETHODIMP nsCBaseLoop::GetNextEvent(nsIEventFilter* filter,
nsIEvent* event)
{
NS_ENSURE_ARG(event);
nsCOMPtr<nsIEventFilter> localFilter(dont_QueryInterface(filter));
if(!localFilter)
NS_ENSURE_SUCCESS(CreateNewEventFilter(getter_AddRefs(localFilter)),
NS_ERROR_FAILURE);
void* platformEventData = GetPlatformEventData(event);
void* platformFilterData = GetPlatformFilterData(localFilter);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
return PlatformGetNextEvent(platformFilterData, platformEventData);
}
NS_IMETHODIMP nsCBaseLoop::PeekNextEvent(nsIEventFilter* filter,
nsIEvent* event, PRBool fRemoveEvent)
{
NS_ENSURE_ARG(event);
nsCOMPtr<nsIEventFilter> localFilter(dont_QueryInterface(filter));
if(!localFilter)
NS_ENSURE_SUCCESS(CreateNewEventFilter(getter_AddRefs(localFilter)),
NS_ERROR_FAILURE);
void* platformEventData = GetPlatformEventData(event);
void* platformFilterData = GetPlatformFilterData(localFilter);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
return PlatformPeekNextEvent(platformFilterData, platformEventData, fRemoveEvent);
}
NS_IMETHODIMP nsCBaseLoop::TranslateEvent(nsIEvent* event)
{
NS_ENSURE_ARG(event);
void* platformEventData = GetPlatformEventData(event);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
return PlatformTranslateEvent(platformEventData);
}
NS_IMETHODIMP nsCBaseLoop::DispatchEvent(nsIEvent* event)
{
NS_ENSURE_ARG(event);
void* platformEventData = GetPlatformEventData(event);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
return PlatformDispatchEvent(platformEventData);
}
NS_IMETHODIMP nsCBaseLoop::SendLoopEvent(nsIEvent* event, PRInt32* result)
{
NS_ENSURE_ARG(event);
void* platformEventData = GetPlatformEventData(event);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
return PlatformSendLoopEvent(platformEventData, result);
}
NS_IMETHODIMP nsCBaseLoop::PostLoopEvent(nsIEvent* event)
{
NS_ENSURE_ARG(event);
void* platformEventData = GetPlatformEventData(event);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
return PlatformPostLoopEvent(platformEventData);
}
NS_IMETHODIMP nsCBaseLoop::GetEventLoopType(nsEventLoopType* pType)
{
NS_ENSURE_ARG_POINTER(pType);
*pType = m_Type;
return NS_OK;
}
NS_IMETHODIMP nsCBaseLoop::GetEventLoopName(PRUnichar** pName)
{
NS_ENSURE_ARG_POINTER(pName);
*pName = m_LoopName.ToNewUnicode();
return *pName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
//*****************************************************************************
// nsCBaseLoop::nsPIEventLoop
//*****************************************************************************
NS_IMETHODIMP nsCBaseLoop::LoopInit(const PRUnichar* pLoopName)
{
m_LoopName.Assign(pLoopName);
return NS_OK;
}
//*****************************************************************************
// nsCBaseLoop:: Internal Helpers
//*****************************************************************************
void* nsCBaseLoop::GetPlatformEventData(nsIEvent* event)
{
void* platformEventData = nsnull;
nsNativeEventDataType platformEventType = PlatformGetEventType();
event->GetNativeData(platformEventType, &platformEventData);
return platformEventData;
}
void* nsCBaseLoop::GetPlatformFilterData(nsIEventFilter* filter)
{
void* platformFilterData = nsnull;
nsNativeFilterDataType platformFilterType = PlatformGetFilterType();
filter->GetNativeData(platformFilterType, &platformFilterData);
return platformFilterData;
}
nsresult nsCBaseLoop::RunWithNoListener(nsIEvent* event,
nsIEventFilter* filter)
{
nsresult rv;
void* platformEventData = GetPlatformEventData(event);
void* platformFilterData = GetPlatformFilterData(filter);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
while(NS_OK == (rv = RetrieveNextEvent(platformFilterData, platformEventData)))
{
if(NS_FAILED(rv = PlatformTranslateEvent(platformEventData)))
break;
if(NS_FAILED(rv = PlatformDispatchEvent(platformEventData)))
break;
}
return rv;
}
nsresult nsCBaseLoop::RunWithTranslateListener(nsIEvent* event,
nsIEventFilter* filter, nsITranslateListener* translateListener)
{
nsresult rv;
void* platformEventData = GetPlatformEventData(event);
void* platformFilterData = GetPlatformFilterData(filter);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
while(NS_OK == (rv = RetrieveNextEvent(platformFilterData, platformEventData)))
{
if(NS_FAILED(rv = translateListener->PreTranslate(event)))
break;
if(NS_OK == rv)
{
if(NS_FAILED(rv = PlatformTranslateEvent(platformEventData)))
break;
if(NS_FAILED(rv = translateListener->PostTranslate(event,
NS_OK == rv ? PR_TRUE : PR_FALSE)))
break;
}
if(NS_FAILED(rv = PlatformDispatchEvent(platformEventData)))
break;
}
return rv;
}
nsresult nsCBaseLoop::RunWithDispatchListener(nsIEvent* event,
nsIEventFilter* filter, nsIDispatchListener* dispatchListener)
{
nsresult rv;
void* platformEventData = GetPlatformEventData(event);
void* platformFilterData = GetPlatformFilterData(filter);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
while(NS_OK == (rv = RetrieveNextEvent(platformFilterData, platformEventData)))
{
if(NS_FAILED(rv = PlatformTranslateEvent(platformEventData)))
break;
if(NS_FAILED(rv = dispatchListener->PreDispatch(event)))
break;
if(NS_OK == rv)
{
if(NS_FAILED(rv = PlatformDispatchEvent(platformEventData)))
break;
if(NS_FAILED(rv = dispatchListener->PostDispatch(event,
NS_OK == rv ? PR_TRUE : PR_FALSE)))
break;
}
}
return rv;
}
nsresult nsCBaseLoop::RunWithTranslateAndDispatchListener(nsIEvent* event,
nsIEventFilter* filter, nsITranslateListener* translateListener,
nsIDispatchListener* dispatchListener)
{
nsresult rv;
void* platformEventData = GetPlatformEventData(event);
void* platformFilterData = GetPlatformFilterData(filter);
NS_ENSURE(platformEventData, NS_ERROR_FAILURE);
while(NS_OK == (rv = RetrieveNextEvent(platformFilterData, platformEventData)))
{
if(NS_FAILED(rv = translateListener->PreTranslate(event)))
break;
if(NS_OK == rv)
{
if(NS_FAILED(rv = PlatformTranslateEvent(platformEventData)))
break;
if(NS_FAILED(rv = translateListener->PostTranslate(event,
NS_OK == rv ? PR_TRUE : PR_FALSE)))
break;
}
if(NS_FAILED(rv = dispatchListener->PreDispatch(event)))
break;
if(NS_OK == rv)
{
if(NS_FAILED(rv = PlatformDispatchEvent(platformEventData)))
break;
if(NS_FAILED(rv = dispatchListener->PostDispatch(event,
NS_OK == rv ? PR_TRUE : PR_FALSE)))
break;
}
}
return rv;
}
nsresult nsCBaseLoop::RetrieveNextEvent(void* platformFilterData,
void* platformEventData)
{
return PlatformRetrieveNextEvent(platformFilterData, platformEventData);
}