/* -*- 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 */ // XXX Milind: #include #include #include #include #include #include #include #include "EmbedMozilla.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" //----------------------------------------------------------------------------- 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_CID(kCUnixToolkitServiceCID, NS_UNIX_TOOLKIT_SERVICE_CID); //----------------------------------------------------------------------------- extern "C" void NS_SetupRegistry(); static void resize_callback( Widget w, XtPointer data, XEvent *xevent, Boolean *toContinue ); static void window_event_handler( Widget w, XtPointer data, XEvent *xevent, Boolean *toContinue ); static void event_processor_callback( XtPointer client_data, int *fd, XtInputId *id ); //----------------------------------------------------------------------------- static nsXlibEventDispatcher gsEventDispatcher = nsnull; static nsIXlibWindowService * gsWindowService = nsnull; static nsIWebShell * sgWebShell = nsnull; static nsIPref * sgPrefs = nsnull; // XXX Milind: the Qt socket notifier which processes pending events static Widget gTopLevelWidget = 0; static Window gWebShellWindow = 0; static Widget gWebShellWidget = 0; static const long lEVENT_MASK = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | ExposureMask;// | ResizeRedirectMask; // XXX Milind: Display *gDisplay = NULL; int gScreenNumber = 0; Window gTopLevelWindow = 0; //----------------------------------------------------------------------------- static void WindowCreateCallback( PRUint32 aID ) { // XXX Milind: printf( "window created: %u\n", aID ); Widget parentwidget = gTopLevelWidget; Widget widget = XtCreateEmbedMozilla( parentwidget, ( Window )aID, "XtEmbedMozilla", NULL, 0 ); XtRealizeWidget( widget ); printf( "widget(%p) of window(%ld)\n\n", widget, (Window)aID ); XtAddEventHandler( widget, ( ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask ), False, window_event_handler, gsEventDispatcher ); } static void WindowDestroyCallback(PRUint32 aID) { printf("window destroyed\n"); } // XXX MAIN int main(int argc, char **argv) { XtAppContext app; gTopLevelWidget = XtAppInitialize( &app, // app context "embed_xlib_into_qt", // app class name 0, // option list 0, // number of options &argc, // argc argv, // argv 0, // fallback resrces 0, // arg list 0 ); // number of args gDisplay = XtDisplay( gTopLevelWidget ); gScreenNumber = DefaultScreen( gDisplay ); printf("TOP LEVEL WIDGET: %p\n", gTopLevelWidget); // init xlibrgb xlib_rgb_init( gDisplay, DefaultScreenOfDisplay( gDisplay ) ); XtVaSetValues( gTopLevelWidget, XtNwidth, 500, XtNheight, 500, NULL); printf("realizing TOP LEVEL WIDGET...\n"); XtRealizeWidget( gTopLevelWidget ); printf("done.\n"); gTopLevelWindow = XtWindow( gTopLevelWidget ); printf("Top Level Window = %ld\n", gTopLevelWindow); ////////////////////////////////////////////////////////////////////// // // 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 **)&gsWindowService); NS_ASSERTION(NS_SUCCEEDED(rv),"Couldn't obtain window service\n"); if (!NS_SUCCEEDED(rv)) return 1; gsWindowService->SetWindowCreateCallback(WindowCreateCallback); gsWindowService->SetWindowDestroyCallback(WindowDestroyCallback); // XXX Milind: XtAppAddInput( app, eventQueue->GetEventQueueSelectFD(), ( XtInputId* )XtInputReadMask, event_processor_callback, eventQueue ); rv = nsRepository::CreateInstance(kWebShellCID, nsnull, kIWebShellIID, (void**)&sgWebShell); NS_ASSERTION(NS_SUCCEEDED(rv),"Cannot create WebShell.\n"); if (!NS_SUCCEEDED(rv)) return 1; sgWebShell->Init( ( nsNativeWidget )gTopLevelWindow, 0, 0, 500, 500); gsWindowService->GetEventDispatcher(&gsEventDispatcher); rv = nsComponentManager::CreateInstance(kPrefCID, NULL, kIPrefIID, (void **) &sgPrefs); if (NS_OK != rv) { printf("failed to get prefs instance\n"); return rv; } sgPrefs->StartUp(); sgPrefs->ReadUserPrefs(); sgWebShell->SetPrefs(sgPrefs); printf("showing webshell...\n"); sgWebShell->Show(); char *url = "http://www.mozilla.org/unix/xlib.html"; nsString URL(url); PRUnichar *u_url = URL.ToNewUnicode(); sgWebShell->LoadURL(u_url); XtPopup( gTopLevelWidget, XtGrabNone ); XtAddEventHandler( gTopLevelWidget, StructureNotifyMask, False, resize_callback, sgWebShell ); XtAppMainLoop( app ); } static void resize_callback( Widget w, XtPointer data, XEvent *xevent, Boolean *toContinue ) { static int x = 0, y = 0, width = 0, height = 0, changed = 0; if ( xevent->type == ConfigureNotify ) { 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; width = width != xconfigure.width ? changed = 1, xconfigure.width : width; height = height != xconfigure.height ? changed = 1, xconfigure.height : height; } else { //x = x != xresize.x ? changed = 1, xresize.x : x; //y = y != xresize.y ? changed = 1, xresize.y : y; width = width != xresize.width ? changed = 1, xresize.width : width; height = height != xresize.height ? changed = 1, xresize.height : height; } if ( changed ) { printf("RESIZE...%p(%d, %d)\n", w, width, height); webshell->SetBounds( 0, 0, width, height ); changed = 0; } } //*toContinue = False; } // this will pick up size changes in the main window and resize // the web shell window accordingly static void window_event_handler( Widget w, XtPointer data, XEvent *xevent, Boolean *toContinue ) { //printf("window_event_handler...\n"); (*gsEventDispatcher)((nsXlibNativeEvent) xevent); //*toContinue = True; } static void event_processor_callback( XtPointer client_data, int *fd, XtInputId *id ) { printf("event_processor_callback...\n"); nsIEventQueue *eq = ( nsIEventQueue *)client_data; eq->ProcessPendingEvents(); }