From 64c16183ef9b499bb8009a894dec5dd033fbd8ff Mon Sep 17 00:00:00 2001 From: "ramiro%netscape.com" Date: Fri, 23 Jul 1999 12:12:08 +0000 Subject: [PATCH] Exorcise the evil global app context thing and replace it with an xpcom thing. --- allmakefiles.sh | 1 + widget/src/motif/Makefile.in | 4 + widget/src/motif/app_context/.cvsignore | 1 + widget/src/motif/app_context/Makefile.in | 52 ++++++ .../app_context/nsIMotifAppContextService.h | 69 ++++++++ .../app_context/nsMotifAppContextService.cpp | 51 ++++++ .../app_context/nsMotifAppContextService.h | 36 ++++ .../nsMotifAppContextServiceFactory.cpp | 156 ++++++++++++++++++ widget/src/motif/nsAppShell.cpp | 60 ++++++- widget/src/motif/nsAppShell.h | 9 +- widget/src/motif/nsFileWidget.cpp | 4 +- widget/src/motif/nsWindow.cpp | 2 +- widget/timer/src/unix/motif/nsTimerMotif.cpp | 76 +++++++-- widget/timer/src/unix/motif/nsTimerMotif.h | 2 + 14 files changed, 502 insertions(+), 21 deletions(-) create mode 100644 widget/src/motif/app_context/.cvsignore create mode 100644 widget/src/motif/app_context/Makefile.in create mode 100644 widget/src/motif/app_context/nsIMotifAppContextService.h create mode 100644 widget/src/motif/app_context/nsMotifAppContextService.cpp create mode 100644 widget/src/motif/app_context/nsMotifAppContextService.h create mode 100644 widget/src/motif/app_context/nsMotifAppContextServiceFactory.cpp diff --git a/allmakefiles.sh b/allmakefiles.sh index e11bd8df91bc..6a9978caf4eb 100755 --- a/allmakefiles.sh +++ b/allmakefiles.sh @@ -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 diff --git a/widget/src/motif/Makefile.in b/widget/src/motif/Makefile.in index 89b27bdd1921..5e6d057a216e 100644 --- a/widget/src/motif/Makefile.in +++ b/widget/src/motif/Makefile.in @@ -59,6 +59,10 @@ CPPSRCS = \ nsXtManageWidget.cpp \ $(NULL) +DIRS =\ + app_context \ + $(NULL) + include $(topsrcdir)/config/config.mk CXXFLAGS += $(TK_CFLAGS) diff --git a/widget/src/motif/app_context/.cvsignore b/widget/src/motif/app_context/.cvsignore new file mode 100644 index 000000000000..f3c7a7c5da68 --- /dev/null +++ b/widget/src/motif/app_context/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/widget/src/motif/app_context/Makefile.in b/widget/src/motif/app_context/Makefile.in new file mode 100644 index 000000000000..b4133696817c --- /dev/null +++ b/widget/src/motif/app_context/Makefile.in @@ -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 diff --git a/widget/src/motif/app_context/nsIMotifAppContextService.h b/widget/src/motif/app_context/nsIMotifAppContextService.h new file mode 100644 index 000000000000..4c3a11778ec1 --- /dev/null +++ b/widget/src/motif/app_context/nsIMotifAppContextService.h @@ -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 + +// 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__ */ diff --git a/widget/src/motif/app_context/nsMotifAppContextService.cpp b/widget/src/motif/app_context/nsMotifAppContextService.cpp new file mode 100644 index 000000000000..3c9552b4dd99 --- /dev/null +++ b/widget/src/motif/app_context/nsMotifAppContextService.cpp @@ -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::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; +} diff --git a/widget/src/motif/app_context/nsMotifAppContextService.h b/widget/src/motif/app_context/nsMotifAppContextService.h new file mode 100644 index 000000000000..c0f3877bdb00 --- /dev/null +++ b/widget/src/motif/app_context/nsMotifAppContextService.h @@ -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; +}; diff --git a/widget/src/motif/app_context/nsMotifAppContextServiceFactory.cpp b/widget/src/motif/app_context/nsMotifAppContextServiceFactory.cpp new file mode 100644 index 000000000000..4e014af7afe5 --- /dev/null +++ b/widget/src/motif/app_context/nsMotifAppContextServiceFactory.cpp @@ -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 + 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 + 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; +} diff --git a/widget/src/motif/nsAppShell.cpp b/widget/src/motif/nsAppShell.cpp index 94fe44100cc5..57024fc1153d 100644 --- a/widget/src/motif/nsAppShell.cpp +++ b/widget/src/motif/nsAppShell.cpp @@ -21,6 +21,9 @@ #include "nsIServiceManager.h" #include "nsIEventQueueService.h" #include "nsICmdLineService.h" + +#include "nsIMotifAppContextService.h" + #include #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); + } + } +} diff --git a/widget/src/motif/nsAppShell.h b/widget/src/motif/nsAppShell.h index d3aa70c76620..80498a8b0083 100644 --- a/widget/src/motif/nsAppShell.h +++ b/widget/src/motif/nsAppShell.h @@ -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__ diff --git a/widget/src/motif/nsFileWidget.cpp b/widget/src/motif/nsFileWidget.cpp index f86de2411dc9..23ec926664f4 100644 --- a/widget/src/motif/nsFileWidget.cpp +++ b/widget/src/motif/nsFileWidget.cpp @@ -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; diff --git a/widget/src/motif/nsWindow.cpp b/widget/src/motif/nsWindow.cpp index 2c304ba1be4e..257aec87d6f5 100644 --- a/widget/src/motif/nsWindow.cpp +++ b/widget/src/motif/nsWindow.cpp @@ -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) { diff --git a/widget/timer/src/unix/motif/nsTimerMotif.cpp b/widget/timer/src/unix/motif/nsTimerMotif.cpp index 69a49af6b6fd..59e51fc66480 100644 --- a/widget/timer/src/unix/motif/nsTimerMotif.cpp +++ b/widget/timer/src/unix/motif/nsTimerMotif.cpp @@ -25,16 +25,13 @@ // #include // #include +#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"); diff --git a/widget/timer/src/unix/motif/nsTimerMotif.h b/widget/timer/src/unix/motif/nsTimerMotif.h index 1716ba7634f6..630a921e8844 100644 --- a/widget/timer/src/unix/motif/nsTimerMotif.h +++ b/widget/timer/src/unix/motif/nsTimerMotif.h @@ -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