/* -*- 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.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 Mozilla Communicator client code. * * The Initial Developer of the Original Code is Netscape Communications * Corporation. Portions created by Netscape are Copyright (C) 1998 * Netscape Communications Corporation. All Rights Reserved. * * Contributor(s): * Pierre Phaneuf */ #include "QMozillaContainer.h" #include "nsQtEventProcessor.h" #include "nsIServiceManager.h" #include "nsIEventQueueService.h" #include "nsIXlibWindowService.h" #include "nsIUnixToolkitService.h" #include "nsIWebShell.h" #include "nsRepository.h" #include "nsIPref.h" #include "xlibrgb.h" #include //----------------------------------------------------------------------------- static NS_DEFINE_CID(kCUnixToolkitServiceCID, NS_UNIX_TOOLKIT_SERVICE_CID); static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID); static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_IID(kWindowServiceCID, NS_XLIB_WINDOW_SERVICE_CID); static NS_DEFINE_IID(kWindowServiceIID, NS_XLIB_WINDOW_SERVICE_IID); static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID); static NS_DEFINE_IID(kIPrefIID, NS_IPREF_IID); static NS_DEFINE_CID(kPrefCID, NS_PREF_CID); static NS_DEFINE_IID(kIWebShellContainerIID, NS_IWEB_SHELL_CONTAINER_IID); //----------------------------------------------------------------------------- extern "C" void NS_SetupRegistry(); // XXX ---------------------------------------------------------------- // XXX // XXX QMozillaWidget is used to bind the windows created by Mozilla // XXX with the Qt library. // XXX Please refer to the Qt sources QXtWidget and QXtApplication // XXX for further details // XXX class QMozillaWidget : public QWidget { public: QMozillaWidget( WId wid, QWidget* parent = NULL ) : QWidget( parent, "QMozillaContainer" ) { create( wid, FALSE, FALSE ); } virtual ~QMozillaWidget() { } virtual bool x11Event( XEvent* e ) { (*gsEventDispatcher)((nsXlibNativeEvent) e ); return TRUE; } static nsXlibEventDispatcher gsEventDispatcher; }; nsXlibEventDispatcher QMozillaWidget::gsEventDispatcher = nsnull; //---------------------------------------------------------------- // XXX // XXX QMozillaContainer methods // XXX QMozillaContainer::QMozillaContainer( QWidget* parent ) : QWidget( parent, "Container" ) { NS_INIT_ISUPPORTS(); printf("calling init()\n"); if ( init() != 0 ) printf("MOZILLA CONTAINER WIDGET: !!! ERROR !!! in init()\n"); printf("done\n"); } QMozillaContainer::~QMozillaContainer() { delete m_MozillaEventProcessor; m_WebShell->SetContainer(nsnull); NS_RELEASE(m_WebShell); } /* virtual */ void QMozillaContainer::focusInEvent ( QFocusEvent * ) { m_WebShell->SetFocus(); } /* virtual */ void QMozillaContainer::focusOutEvent ( QFocusEvent * ) { m_WebShell->RemoveFocus(); } /* virtual */ bool QMozillaContainer::x11Event( XEvent* xevent ) { if ( xevent->type == ConfigureNotify ) //if ( xevent->type == ResizeRequest ) { int changed = 0; XConfigureEvent &xconfigure = xevent->xconfigure; XResizeRequestEvent &xresize = xevent->xresizerequest; //nsIWebShell *webshell = ( nsIWebShell* )data; if ( xevent->type == ConfigureNotify ) { //x = x != xconfigure.x ? changed = 1, xconfigure.x : x; //y = y != xconfigure.y ? changed = 1, xconfigure.y : y; m_width = m_width != xconfigure.width ? changed = 1, xconfigure.width : m_width; m_height = m_height != xconfigure.height ? changed = 1, xconfigure.height : m_height; } else { //x = x != xresize.x ? changed = 1, xresize.x : x; //y = y != xresize.y ? changed = 1, xresize.y : y; m_width = m_width != xresize.width ? changed = 1, xresize.width : m_width; m_height = m_height != xresize.height ? changed = 1, xresize.height : m_height; } if ( changed ) { //printf("RESIZE...%p(%d, %d)\n", w, width, height); m_WebShell->SetBounds( 0, 0, width(), height() ); changed = 0; } } return TRUE; } /* public slot */ void QMozillaContainer::loadURL( const char *url ) { if ( m_WebShell ) { nsString URL(url); PRUnichar *u_url = URL.ToNewUnicode(); m_WebShell->LoadURL(u_url); } } /* public slot */ void QMozillaContainer::reload( QMozillaReloadType type = ReloadFromCache ) { if ( m_WebShell ) m_WebShell->Reload( type ); } /* public slot */ void QMozillaContainer::forward() { if ( m_WebShell && m_WebShell->CanForward() ) m_WebShell->Forward(); } /* public slot */ void QMozillaContainer::back() { if ( m_WebShell && m_WebShell->CanBack() ) m_WebShell->Back(); } /* public slot */ void QMozillaContainer::stop() { if ( m_WebShell ) m_WebShell->Stop(); } //----------------------------------------------------------------------------- static void WindowCreateCallback( PRUint32 aID ) { // XXX Milind: printf( "window created: %u\n", aID ); QWidget* qwidget = new QMozillaWidget( ( WId )aID ); qwidget->setMouseTracking( TRUE ); XSelectInput( qt_xdisplay(), ( Window )aID, ( ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask ) ); } static void WindowDestroyCallback(PRUint32 aID) { printf("window destroyed\n"); } int QMozillaContainer::init() { // init xlibrgb xlib_rgb_init( qt_xdisplay(), DefaultScreenOfDisplay( qt_xdisplay() ) ); ////////////////////////////////////////////////////////////////////// // // Toolkit Service setup // // Note: This must happend before NS_SetupRegistry() is called so // that the toolkit specific xpcom components can be registered // as needed. // ////////////////////////////////////////////////////////////////////// nsresult rv; nsIUnixToolkitService * unixToolkitService = nsnull; rv = nsComponentManager::CreateInstance(kCUnixToolkitServiceCID, nsnull, NS_GET_IID(nsIUnixToolkitService), (void **) &unixToolkitService); NS_ASSERTION(NS_SUCCEEDED(rv),"Cannot obtain unix toolkit service."); if (!NS_SUCCEEDED(rv)) return 1; // Force the toolkit into "xlib" mode regardless of MOZ_TOOLKIT unixToolkitService->SetToolkitName("xlib"); NS_RELEASE(unixToolkitService); ////////////////////////////////////////////////////////////////////// // End toolkit service setup ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // // Setup the registry // ////////////////////////////////////////////////////////////////////// NS_SetupRegistry(); printf("Creating event queue.\n"); nsIEventQueueService * eventQueueService = nsnull; nsIEventQueue * eventQueue = nsnull; // Create the Event Queue for the UI thread... rv = nsServiceManager::GetService(kEventQueueServiceCID, kIEventQueueServiceIID, (nsISupports **)&eventQueueService); NS_ASSERTION(NS_SUCCEEDED(rv),"Could not obtain the event queue service."); if (!NS_SUCCEEDED(rv)) return 1; rv = eventQueueService->CreateThreadEventQueue(); NS_ASSERTION(NS_SUCCEEDED(rv),"Could not create the event queue for the the thread."); if (!NS_SUCCEEDED(rv)) return 1; rv = eventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQueue); NS_ASSERTION(NS_SUCCEEDED(rv),"Could not get the newly created thread event queue.\n"); if (!NS_SUCCEEDED(rv)) return 1; NS_RELEASE(eventQueueService); rv = nsServiceManager::GetService(kWindowServiceCID, kWindowServiceIID, (nsISupports **)&m_WindowService); NS_ASSERTION(NS_SUCCEEDED(rv),"Couldn't obtain window service\n"); if (!NS_SUCCEEDED(rv)) return 1; m_WindowService->SetWindowCreateCallback(WindowCreateCallback); m_WindowService->SetWindowDestroyCallback(WindowDestroyCallback); printf("adding xlib event queue callback...\n"); m_MozillaEventProcessor = new nsQtEventProcessor( eventQueue, this ); printf("creating webshell...\n"); rv = nsRepository::CreateInstance(kWebShellCID, nsnull, kIWebShellIID, (void**)&m_WebShell); NS_ASSERTION(NS_SUCCEEDED(rv),"Cannot create WebShell.\n"); if (!NS_SUCCEEDED(rv)) return 1; printf("initializing webshell...\n"); m_WebShell->Init( ( nsNativeWidget )winId(), 0, 0, 500, 500); m_WebShell->SetContainer( this ); m_WindowService->GetEventDispatcher(&QMozillaWidget::gsEventDispatcher); rv = nsComponentManager::CreateInstance(kPrefCID, NULL, kIPrefIID, (void **) &m_Prefs); if (NS_OK != rv) { printf("failed to get prefs instance\n"); return rv; } m_Prefs->StartUp(); m_Prefs->ReadUserPrefs(); m_WebShell->SetPrefs(m_Prefs); printf("showing webshell...\n"); m_WebShell->Show(); return 0; } // helper fuction for BeginLoadURL, ProgressLoadURL, EndLoadURL // XXX Dont forget to delete this 'C' String since we create it here static char* makeCString( const PRUnichar* aString ) { int len = 0; const PRUnichar* ptr = aString; while ( *ptr ) len++, ptr++; char *cstring = new char[ ++len ]; // just cast down to a character while ( len >= 0 ) { cstring[len] = ( char )aString[len]; len--; } } // nsIWebShellContainer methods NS_IMPL_ISUPPORTS(QMozillaContainer, kIWebShellContainerIID); // XXX DO NOTHING: STUB METHOD FOR COMPLIANCE WITH nsIWebShellContainer NS_METHOD QMozillaContainer::WillLoadURL(nsIWebShell* aShell, const PRUnichar* aURL, nsLoadType aReason) { char *url = makeCString( aURL ); printf("MOZILLA CONTAINER WIDGET: will load %s...\n", url); delete url; return NS_OK; } NS_METHOD QMozillaContainer::BeginLoadURL(nsIWebShell* aShell, const PRUnichar* aURL) { char *url = makeCString( aURL ); printf("MOXILLA CONTAINER WIDGET: loading %s...\n", url); delete url; emit urlLoadStarted(); return NS_OK; } NS_METHOD QMozillaContainer::ProgressLoadURL( nsIWebShell* aShell, const PRUnichar* aURL, PRInt32 aProgress, PRInt32 aProgressMax) { char *url = makeCString( aURL ); emit urlLoadProgressed( (const char *)url, (int)aProgress, (int)aProgressMax ); delete url; return NS_OK; } NS_METHOD QMozillaContainer::EndLoadURL(nsIWebShell* aShell, const PRUnichar* aURL, nsresult aStatus) { char *url = makeCString( aURL ); if ( aStatus != NS_OK ) printf("MOZILLA CONTAINER WIDGET: error loading %s...\n", url); else printf("MOXILLA CONTAINER WIDGET: done loading %s...\n", url); delete url; emit urlLoadEnded(); return NS_OK; } // XXX DO NOTHING: STUB METHOD FOR COMPLIANCE WITH nsIWebShellContainer NS_METHOD QMozillaContainer::NewWebShell( PRUint32 aChromeMask, PRBool aVisible, nsIWebShell *&aNewWebShell) { return NS_OK; } // XXX DO NOTHING: STUB METHOD FOR COMPLIANCE WITH nsIWebShellContainer NS_METHOD QMozillaContainer::ContentShellAdded(nsIWebShell* aChildShell, nsIContent* frameNode) { return NS_OK; } // XXX DO NOTHING: STUB METHOD FOR COMPLIANCE WITH nsIWebShellContainer NS_METHOD QMozillaContainer::CreatePopup( nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& anAnchorAlignment, const nsString& aPopupAlignment, nsIDOMWindow* aWindow, nsIDOMWindow** outPopup) { return NS_OK; } // XXX DO NOTHING: STUB METHOD FOR COMPLIANCE WITH nsIWebShellContainer NS_METHOD QMozillaContainer::FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult) { return NS_OK; } // XXX DO NOTHING: STUB METHOD FOR COMPLIANCE WITH nsIWebShellContainer NS_METHOD QMozillaContainer::FocusAvailable(nsIWebShell* aFocusedWebShell, PRBool& aFocusTaken) { return NS_OK; }