Exorcise the evil global app context thing and replace it with an xpcom thing.

This commit is contained in:
ramiro%netscape.com 1999-07-23 12:12:08 +00:00
parent 748490d8a2
commit 64c16183ef
14 changed files with 502 additions and 21 deletions

View File

@ -350,6 +350,7 @@ widget/src/beos/Makefile
widget/src/build/Makefile
widget/src/gtk/Makefile
widget/src/motif/Makefile
widget/src/motif/app_context/Makefile
widget/src/photon/Makefile
widget/src/rhapsody/Makefile
widget/src/xlib/Makefile

View File

@ -59,6 +59,10 @@ CPPSRCS = \
nsXtManageWidget.cpp \
$(NULL)
DIRS =\
app_context \
$(NULL)
include $(topsrcdir)/config/config.mk
CXXFLAGS += $(TK_CFLAGS)

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1,52 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
LIBRARY_NAME = motif_app_context
IS_COMPONENT=1
REQUIRES=xpcom
CXXFLAGS += $(TK_CFLAGS)
INCLUDES += $(TK_CFLAGS) -I$(srcdir)/.. -I$(srcdir)/../../xpwidgets
CPPSRCS = \
nsMotifAppContextService.cpp \
nsMotifAppContextServiceFactory.cpp \
$(NULL)
CXXFLAGS += $(TK_CFLAGS)
EXPORTS =\
nsIMotifAppContextService.h \
$(NULL)
EXTRA_DSO_LDOPTS += $(TOOLKIT_TK_LIBS)
#MKSHLIB =
#override NO_SHARED_LIB=1
#override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (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 Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C) 1999
* Christopher Blizzard. All Rights Reserved.
*/
#ifndef nsIMotifAppContextService_h__
#define nsIMotifAppContextService_h__
#include "nsISupports.h"
#include <X11/Intrinsic.h>
// Interface id for the MotifAppContext service
// { 90F55E51-40EB-11d3-B219-000064657374 }
#define NS_MOTIF_APP_CONTEXT_SERVICE_IID \
{ 0x90f55e51, 0x40eb, 0x11d3, \
{ 0xb2, 0x19, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
// Class ID for our implementation
// { 90F55E52-40EB-11d3-B219-000064657374 }
#define NS_MOTIF_APP_CONTEXT_SERVICE_CID \
{ 0x90f55e52, 0x40eb, 0x11d3, \
{ 0xb2, 0x19, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
#define NS_MOTIF_APP_CONTEXT_SERVICE_PROGID "component://netscape/widget/motif/app_context"
class nsIMotifAppContextService : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_MOTIF_APP_CONTEXT_SERVICE_IID);
/**
* Register your function for window creation and destruction.
* This function will get called whenever a new native X window
* is created. or destroyed.
*
* @param [IN] the function that you would like to register
* @return NS_OK if ok, NS_ERROR_FAILURE if you pass in 0
*/
NS_IMETHOD SetAppContext(XtAppContext aAppContext) = 0;
/**
* This function will dispatch a native X event ( cast to a void *
* here ) to the event handler on the inside of the widget
* toolkit
* @param [IN] a pointer to an XEvent, cast to a void *
* @return NS_OK if ok, NS_ERROR_FAILURE if you pass in an
* invalid window id
*/
NS_IMETHOD GetAppContext(XtAppContext * aAppContextOut) = 0;
};
#endif /* nsIMotifAppContextService_h__ */

View File

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (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 Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C) 1999
* Christopher Blizzard. All Rights Reserved.
*/
#include "nsMotifAppContextService.h"
XtAppContext nsMotifAppContextService::sAppContext = nsnull;
nsMotifAppContextService::nsMotifAppContextService()
{
}
nsMotifAppContextService::~nsMotifAppContextService()
{
}
NS_IMPL_ADDREF(nsMotifAppContextService)
NS_IMPL_RELEASE(nsMotifAppContextService)
NS_IMPL_QUERY_INTERFACE(nsMotifAppContextService, nsCOMTypeInfo<nsIMotifAppContextService>::GetIID())
NS_IMETHODIMP
nsMotifAppContextService::SetAppContext(XtAppContext aAppContext)
{
NS_ASSERTION(sAppContext == nsnull,"App context can only be set once.");
sAppContext = aAppContext;
return NS_OK;
}
NS_IMETHODIMP
nsMotifAppContextService::GetAppContext(XtAppContext * aAppContextOut)
{
*aAppContextOut = sAppContext;
return NS_OK;
}

View File

@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (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 Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C) 1999
* Christopher Blizzard. All Rights Reserved.
*/
#include "nsIMotifAppContextService.h"
class nsMotifAppContextService : public nsIMotifAppContextService
{
public:
nsMotifAppContextService();
virtual ~nsMotifAppContextService();
NS_DECL_ISUPPORTS
NS_IMETHOD SetAppContext(XtAppContext aAppContext);
NS_IMETHOD GetAppContext(XtAppContext * aAppContextOut);
private:
static XtAppContext sAppContext;
};

View File

@ -0,0 +1,156 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (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 Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C) 1999
* Christopher Blizzard. All Rights Reserved.
*/
#include "nsIMotifAppContextService.h"
#include "nsIFactory.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
#include "nsMotifAppContextService.h"
static NS_DEFINE_CID(kCMotifAppContextServiceCID, NS_MOTIF_APP_CONTEXT_SERVICE_CID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
class nsMotifAppContextServiceFactory : public nsIFactory
{
public:
NS_DECL_ISUPPORTS
NS_IMETHOD CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
nsMotifAppContextServiceFactory(const nsCID &aClass);
virtual ~nsMotifAppContextServiceFactory();
private:
nsCID mClassID;
};
nsMotifAppContextServiceFactory::nsMotifAppContextServiceFactory(const nsCID &aClass) :
mRefCnt(0),
mClassID(aClass)
{
}
nsMotifAppContextServiceFactory::~nsMotifAppContextServiceFactory()
{
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
}
NS_IMPL_ISUPPORTS(nsMotifAppContextServiceFactory, nsIFactory::GetIID())
NS_IMETHODIMP
nsMotifAppContextServiceFactory::CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult)
{
if (aResult == nsnull)
return NS_ERROR_NULL_POINTER;
*aResult = nsnull;
nsISupports *inst = nsnull;
if (mClassID.Equals(kCMotifAppContextServiceCID)) {
inst = (nsISupports *)(nsMotifAppContextService *) new nsMotifAppContextService();
}
if (inst == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = inst->QueryInterface(aIID, aResult);
if (rv != NS_OK)
delete inst;
return rv;
}
nsresult nsMotifAppContextServiceFactory::LockFactory(PRBool aLock)
{
// Not implemented in simplest case.
return NS_OK;
}
extern "C" NS_EXPORT nsresult
NSGetFactory(nsISupports *servMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
{
printf("NSGetFactory for motif app context service\n");
if (nsnull == aFactory) {
return NS_ERROR_NULL_POINTER;
}
*aFactory = new nsMotifAppContextServiceFactory(aClass);
if (nsnull == aFactory) {
return NS_ERROR_OUT_OF_MEMORY;
}
return (*aFactory)->QueryInterface(nsIFactory::GetIID(),
(void **)aFactory);
}
extern "C" NS_EXPORT PRBool
NSCanUnload(nsISupports *aServMgr)
{
return PR_FALSE;
}
extern "C" NS_EXPORT nsresult
NSRegisterSelf(nsISupports* aServMgr, const char *fullpath)
{
nsresult rv;
printf("*** Registering MotifAppContextService\n");
nsCOMPtr<nsIServiceManager>
serviceManager(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIComponentManager, compMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterComponent(kCMotifAppContextServiceCID,
"Motif App Context Service",
NS_MOTIF_APP_CONTEXT_SERVICE_PROGID,
fullpath,
PR_TRUE,
PR_TRUE);
return rv;
}
extern "C" NS_EXPORT nsresult
NSUnregisterSelf(nsISupports *aServMgr, const char *fullpath)
{
nsresult rv;
nsCOMPtr<nsIServiceManager>
serviceManager(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIComponentManager, compMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
compMgr->UnregisterComponent(kCMotifAppContextServiceCID, fullpath);
return NS_OK;
}

View File

@ -21,6 +21,9 @@
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsICmdLineService.h"
#include "nsIMotifAppContextService.h"
#include <stdlib.h>
#ifdef LINUX
@ -59,6 +62,7 @@ NS_METHOD nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener)
return NS_OK;
}
XtAppContext nsAppShell::sAppContext = nsnull;
//-------------------------------------------------------------------------
//
@ -87,7 +91,7 @@ NS_METHOD nsAppShell::Create(int* bac, char ** bav)
XtSetLanguageProc(NULL, NULL, NULL);
mTopLevel = XtAppInitialize(&mAppContext, // app_context_return
mTopLevel = XtAppInitialize(&sAppContext, // app_context_return
"nsAppShell", // application_class
NULL, // options
0, // num_options
@ -97,7 +101,9 @@ NS_METHOD nsAppShell::Create(int* bac, char ** bav)
NULL, // args
0); // num_args
xlib_set_xt_app_context(mAppContext);
xlib_set_xt_app_context(sAppContext);
printf("nsAppShell::Create() app_context = %p\n",sAppContext);
xlib_rgb_init(XtDisplay(mTopLevel), XtScreen(mTopLevel));
@ -105,6 +111,8 @@ NS_METHOD nsAppShell::Create(int* bac, char ** bav)
XtDisplay(mTopLevel),
XtScreen(mTopLevel));
SetAppContext(sAppContext);
return NS_OK;
}
@ -164,7 +172,7 @@ done:
printf("Calling XtAppAddInput() with event queue\n");
XtAppAddInput(mAppContext,
XtAppAddInput(nsAppShell::GetAppContext(),
EQueue->GetEventQueueSelectFD(),
(XtPointer) XtInputReadMask,
event_processor_callback,
@ -184,7 +192,7 @@ done:
for (;;)
{
XtAppNextEvent(mAppContext, &event);
XtAppNextEvent(sAppContext, &event);
XtDispatchEvent(&event);
@ -264,9 +272,53 @@ void* nsAppShell::GetNativeData(PRUint32 aDataType)
return nsnull;
}
NS_METHOD nsAppShell::EventIsForModalWindow(PRBool aRealEvent, void *aEvent, nsIWidget *aWidget,
PRBool *aForWindow)
{
//XXX:Implement this.
return NS_OK;
}
static NS_DEFINE_CID(kCMotifAppContextServiceCID, NS_MOTIF_APP_CONTEXT_SERVICE_CID);
//-------------------------------------------------------------------------
//
// SetAppContext
//
//-------------------------------------------------------------------------
/* static */ void
nsAppShell::SetAppContext(XtAppContext aAppContext)
{
NS_ASSERTION(aAppContext != nsnull,"App context cant be null.");
static PRBool once = PR_TRUE;
if (once)
{
once = PR_FALSE;
nsresult rv;
nsIMotifAppContextService * ac_service = nsnull;
rv = nsComponentManager::CreateInstance(kCMotifAppContextServiceCID,
nsnull,
nsIMotifAppContextService::GetIID(),
(void **)& ac_service);
NS_ASSERTION(rv == NS_OK,"Cannot obtain app context service.");
if (ac_service)
{
printf("nsAppShell::SetAppContext() ac_service = %p\n",ac_service);
nsresult rv2 = ac_service->SetAppContext(aAppContext);
NS_ASSERTION(rv2 == NS_OK,"Cannot set the app context.");
printf("nsAppShell::SetAppContext() All is ok.\n");
NS_RELEASE(ac_service);
}
}
}

View File

@ -31,7 +31,6 @@ class nsAppShell : public nsIAppShell
{
private:
Widget mTopLevel;
XtAppContext mAppContext;
nsDispatchListener* mDispatchListener;
public:
@ -54,7 +53,13 @@ class nsAppShell : public nsIAppShell
PRBool *aForWindow);
XtAppContext GetAppContext() { return mAppContext; }
static XtAppContext GetAppContext() { return sAppContext; }
private:
static void SetAppContext(XtAppContext aAppContext);
static XtAppContext sAppContext;
};
#endif // nsAppShell_h__

View File

@ -22,6 +22,8 @@
#include "nsStringUtil.h"
#include "nsAppShell.h"
#include "xlibrgb.h"
NS_IMPL_ADDREF(nsFileWidget)
NS_IMPL_RELEASE(nsFileWidget)
@ -64,7 +66,7 @@ NS_METHOD nsFileWidget:: Create(nsIWidget *aParent,
mTitle.Append(aTitle);
mMode = aMode;
mAppContext = ((nsAppShell *) aAppShell)->GetAppContext();
mAppContext = nsAppShell::GetAppContext();
Widget parentWidget = nsnull;

View File

@ -379,7 +379,7 @@ void nsWindow::CreateWindow(nsNativeWidget aNativeParent,
nsIToolkit *aToolkit,
nsWidgetInitData *aInitData)
{
mAppContext = ((nsAppShell *) aAppShell)->GetAppContext();
mAppContext = nsAppShell::GetAppContext();
// keep a reference to the device context
if (aContext) {

View File

@ -25,16 +25,13 @@
// #include <limits.h>
// #include <X11/Intrinsic.h>
#include "nsIComponentManager.h"
#include "nsIMotifAppContextService.h"
static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
// Hack for now. This is Bad because it creates a dependency between the widget
// library and this library. This needs to be replaced with having code
// to pass an interface which can be queried for the app context.
XtAppContext gAppContext;
extern void nsTimerExpired(XtPointer aCallData);
void nsTimerMotif::FireTimeout()
{
if (mFunc != NULL) {
@ -50,7 +47,6 @@ void nsTimerMotif::FireTimeout()
// mTimerId = XtAppAddTimeOut(gAppContext, GetDelay(),(XtTimerCallbackProc)nsTimerExpired, this);
}
nsTimerMotif::nsTimerMotif()
{
NS_INIT_REFCNT();
@ -60,12 +56,15 @@ nsTimerMotif::nsTimerMotif()
mTimerId = 0;
mDelay = 0;
mClosure = NULL;
mAppContext = nsnull;
}
nsTimerMotif::~nsTimerMotif()
{
}
static NS_DEFINE_CID(kCMotifAppContextServiceCID, NS_MOTIF_APP_CONTEXT_SERVICE_CID);
nsresult
nsTimerMotif::Init(nsTimerCallbackFunc aFunc,
void *aClosure,
@ -76,7 +75,11 @@ nsTimerMotif::Init(nsTimerCallbackFunc aFunc,
mClosure = aClosure;
// mRepeat = aRepeat;
mTimerId = XtAppAddTimeOut(gAppContext, aDelay,(XtTimerCallbackProc)nsTimerExpired, this);
InitAppContext();
mTimerId = XtAppAddTimeOut(mAppContext,
aDelay,
(XtTimerCallbackProc)nsTimerExpired, this);
return Init(aDelay);
}
@ -89,7 +92,12 @@ nsTimerMotif::Init(nsITimerCallback *aCallback,
mCallback = aCallback;
// mRepeat = aRepeat;
mTimerId = XtAppAddTimeOut(gAppContext, aDelay, (XtTimerCallbackProc)nsTimerExpired, this);
InitAppContext();
mTimerId = XtAppAddTimeOut(mAppContext,
aDelay,
(XtTimerCallbackProc)nsTimerExpired,
this);
return Init(aDelay);
}
@ -97,10 +105,12 @@ nsTimerMotif::Init(nsITimerCallback *aCallback,
nsresult
nsTimerMotif::Init(PRUint32 aDelay)
{
mDelay = aDelay;
NS_ADDREF(this);
return NS_OK;
InitAppContext();
mDelay = aDelay;
NS_ADDREF(this);
return NS_OK;
}
NS_IMPL_ISUPPORTS(nsTimerMotif, kITimerIID)
@ -118,6 +128,46 @@ void nsTimerExpired(XtPointer aCallData)
timer->FireTimeout();
}
nsresult
nsTimerMotif::InitAppContext()
{
static XtAppContext gsAppContext = nsnull;
mAppContext = nsnull;
if (nsnull == gsAppContext)
{
nsresult rv;
nsIMotifAppContextService * ac_service = nsnull;
rv = nsComponentManager::CreateInstance(kCMotifAppContextServiceCID,
nsnull,
nsIMotifAppContextService::GetIID(),
(void **)& ac_service);
NS_ASSERTION(rv == NS_OK,"Cannot obtain app context service.");
if (ac_service)
{
printf("nsTimerMotif::InitAppContext() ac_service = %p\n",ac_service);
nsresult rv2 = ac_service->GetAppContext(&gsAppContext);
NS_ASSERTION(rv2 == NS_OK,"Cannot get the app context.");
NS_ASSERTION(nsnull != gsAppContext,"Global app context is null.");
NS_RELEASE(ac_service);
printf("nsTimerMotif::InitAppContext() gsAppContext = %p\n",gsAppContext);
}
}
mAppContext = gsAppContext;
return NS_OK;
}
nsresult NS_NewTimer(nsITimer** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");

View File

@ -53,6 +53,7 @@ public:
private:
nsresult Init(PRUint32 aDelay);
nsresult InitAppContext();
PRUint32 mDelay;
nsTimerCallbackFunc mFunc;
@ -61,6 +62,7 @@ private:
// PRBool mRepeat;
nsTimerMotif * mNext;
XtIntervalId mTimerId;
XtAppContext mAppContext;
};
#endif // __nsTimerMotif_h