/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"
#include <com/sun/star/beans/PropertyAttribute.hpp>

#ifndef _SVWIN_HXX
#include <tools/svwin.h>
#endif
#include <stdio.h>
#include <com/sun/star/awt/ImageScaleMode.hpp>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
#include <com/sun/star/awt/WindowClass.hpp>
#include <com/sun/star/awt/MessageBoxButtons.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/SystemDependent.hpp>
#include <com/sun/star/awt/FocusEvent.hpp>
#include <com/sun/star/awt/KeyEvent.hpp>
#include <com/sun/star/awt/KeyModifier.hpp>
#include <com/sun/star/lang/EventObject.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <cppuhelper/typeprovider.hxx>
#include <osl/conditn.hxx>
#include <rtl/memory.h>
#include <rtl/uuid.h>
#include <rtl/process.h>

#ifdef WNT
#include <tools/prewin.h>
#include <windows.h>
#include <tools/postwin.h>
#elif defined ( OS2 )
#include <svpm.h>
#elif (defined QUARTZ)
#include "premac.h"
#include <Cocoa/Cocoa.h>
#include "postmac.h"
#endif
#include <vcl/sysdata.hxx>

#include <toolkit/awt/vclxwindows.hxx>
#include <toolkit/awt/vclxsystemdependentwindow.hxx>
#include <toolkit/awt/vclxregion.hxx>
#include <toolkit/awt/vclxtoolkit.hxx>
#include <toolkit/awt/vclxtabpagecontainer.hxx>
#include <toolkit/awt/vclxtabpagemodel.hxx>

#include <toolkit/awt/xsimpleanimation.hxx>
#include <toolkit/awt/xthrobber.hxx>
#include <toolkit/awt/animatedimagespeer.hxx>
#include <toolkit/awt/vclxtopwindow.hxx>
#include <toolkit/awt/vclxwindow.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/unowrapper.hxx>
#include <toolkit/helper/servicenames.hxx>


#include <toolkit/helper/macros.hxx>
#include <toolkit/helper/convert.hxx>
#include <vcl/unohelp.hxx>
#include <vcl/btndlg.hxx>
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#include <vcl/combobox.hxx>
#include <vcl/ctrl.hxx>
#include <vcl/dialog.hxx>
#include <vcl/dockingarea.hxx>
#include <vcl/dockwin.hxx>
#include <vcl/edit.hxx>
#include <vcl/field.hxx>
#include <vcl/fixed.hxx>
#include <vcl/floatwin.hxx>
#include <vcl/group.hxx>
#include <vcl/imgctrl.hxx>
#include <vcl/longcurr.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/menubtn.hxx>
#include <vcl/morebtn.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/spin.hxx>
#include <vcl/split.hxx>
#include <vcl/splitwin.hxx>
#include <vcl/status.hxx>
#include <vcl/svapp.hxx>
#include <vcl/syschild.hxx>
#include <vcl/tabctrl.hxx>
#include <vcl/tabdlg.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/virdev.hxx>
#include <vcl/window.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/throbber.hxx>
#include "toolkit/awt/vclxspinbutton.hxx"

#include <tools/debug.hxx>
#include <comphelper/processfactory.hxx>

namespace css = ::com::sun::star;

#define VCLWINDOW_FRAMEWINDOW				0x1000
#define VCLWINDOW_SYSTEMCHILDWINDOW			0x1001

#if (defined WNT)
#define SYSTEM_DEPENDENT_TYPE ::com::sun::star::lang::SystemDependent::SYSTEM_WIN32
#elif (defined OS2)
#define SYSTEM_DEPENDENT_TYPE ::com::sun::star::lang::SystemDependent::SYSTEM_OS2
#elif (defined QUARTZ)
#define SYSTEM_DEPENDENT_TYPE ::com::sun::star::lang::SystemDependent::SYSTEM_MAC
#elif (defined UNX)
#define SYSTEM_DEPENDENT_TYPE ::com::sun::star::lang::SystemDependent::SYSTEM_XWINDOW
#endif

TOOLKIT_DLLPUBLIC WinBits ImplGetWinBits( sal_uInt32 nComponentAttribs, sal_uInt16 nCompType )
{
	WinBits nWinBits = 0;

	sal_Bool bMessBox = sal_False;
	if ( ( nCompType == WINDOW_INFOBOX ) ||
		 ( nCompType == WINDOW_MESSBOX ) ||
		 ( nCompType == WINDOW_QUERYBOX ) ||
		 ( nCompType == WINDOW_WARNINGBOX ) ||
		 ( nCompType == WINDOW_ERRORBOX ) )
	{
		bMessBox = sal_True;
	}

    bool bDecoratedWindow = false;
    if  (   bMessBox
        ||  ( nCompType == WINDOW_DIALOG )
        ||  ( nCompType == WINDOW_MODELESSDIALOG )
        ||  ( nCompType == WINDOW_MODALDIALOG )
        ||  ( nCompType == WINDOW_SYSTEMDIALOG )
        ||  ( nCompType == WINDOW_PATHDIALOG )
        ||  ( nCompType == WINDOW_FILEDIALOG )
        ||  ( nCompType == WINDOW_PRINTERSETUPDIALOG )
        ||  ( nCompType == WINDOW_PRINTDIALOG )
        ||  ( nCompType == WINDOW_COLORDIALOG )
        ||  ( nCompType == WINDOW_FONTDIALOG )
        ||  ( nCompType == WINDOW_DOCKINGWINDOW )
        ||  ( nCompType == WINDOW_TABDIALOG )
        ||  ( nCompType == WINDOW_BUTTONDIALOG )
        ||  ( nCompType == WINDOW_SYSTEMCHILDWINDOW )
        )
    {
        bDecoratedWindow = true;
    }

    if( nComponentAttribs & ::com::sun::star::awt::WindowAttribute::BORDER )
		nWinBits |= WB_BORDER;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::NOBORDER )
		nWinBits |= WB_NOBORDER;
	if( nComponentAttribs & ::com::sun::star::awt::WindowAttribute::SIZEABLE )
		nWinBits |= WB_SIZEABLE;
	if( nComponentAttribs & ::com::sun::star::awt::WindowAttribute::MOVEABLE )
		nWinBits |= WB_MOVEABLE;
	if( nComponentAttribs & ::com::sun::star::awt::WindowAttribute::CLOSEABLE )
		nWinBits |= WB_CLOSEABLE;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::HSCROLL )
		nWinBits |= WB_HSCROLL;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::VSCROLL )
		nWinBits |= WB_VSCROLL;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::LEFT )
		nWinBits |= WB_LEFT;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::CENTER )
		nWinBits |= WB_CENTER;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::RIGHT )
		nWinBits |= WB_RIGHT;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::SPIN )
		nWinBits |= WB_SPIN;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::SORT )
		nWinBits |= WB_SORT;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::DROPDOWN )
		nWinBits |= WB_DROPDOWN;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::DEFBUTTON )
		nWinBits |= WB_DEFBUTTON;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::READONLY )
		nWinBits |= WB_READONLY;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::CLIPCHILDREN )
		nWinBits |= WB_CLIPCHILDREN;
	if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::GROUP )
		nWinBits |= WB_GROUP;
    if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::NOLABEL ) //added for issue79712
		nWinBits |= WB_NOLABEL;

	// These bits are not uniqe
	if ( bMessBox )
	{
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::OK )
			nWinBits |= WB_OK;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::OK_CANCEL )
			nWinBits |= WB_OK_CANCEL;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::YES_NO )
			nWinBits |= WB_YES_NO;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::YES_NO_CANCEL )
			nWinBits |= WB_YES_NO_CANCEL;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::RETRY_CANCEL )
			nWinBits |= WB_RETRY_CANCEL;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::DEF_OK )
			nWinBits |= WB_DEF_OK;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::DEF_CANCEL )
			nWinBits |= WB_DEF_CANCEL;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::DEF_RETRY )
			nWinBits |= WB_DEF_RETRY;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::DEF_YES )
			nWinBits |= WB_DEF_YES;
		if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::DEF_NO )
			nWinBits |= WB_DEF_NO;
	}
    if ( nCompType == WINDOW_MULTILINEEDIT )
    {
        if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::AUTOHSCROLL )
            nWinBits |= WB_AUTOHSCROLL;
        if( nComponentAttribs & ::com::sun::star::awt::VclWindowPeerAttribute::AUTOVSCROLL )
            nWinBits |= WB_AUTOVSCROLL;
    }


    if ( bDecoratedWindow )
    {
        if( nComponentAttribs & ::com::sun::star::awt::WindowAttribute::NODECORATION )
        {
            // No decoration removes several window attributes and must
            // set WB_NOBORDER!
            nWinBits &= ~WB_BORDER;
	        nWinBits &= ~WB_SIZEABLE;
	        nWinBits &= ~WB_MOVEABLE;
	        nWinBits &= ~WB_CLOSEABLE;
            nWinBits |= WB_NOBORDER;
        }
    }

	return nWinBits;
}

struct ComponentInfo
{
	const char*		pName;
	WindowType		nWinType;
};

static ComponentInfo __FAR_DATA aComponentInfos [] =
{
	{ "buttondialog", 		WINDOW_BUTTONDIALOG },
	{ "cancelbutton",		WINDOW_CANCELBUTTON },
	{ "checkbox",			WINDOW_CHECKBOX },
	{ "combobox",			WINDOW_COMBOBOX },
	{ "control",			WINDOW_CONTROL },
	{ "currencybox",		WINDOW_CURRENCYBOX },
	{ "currencyfield",		WINDOW_CURRENCYFIELD },
	{ "datebox",			WINDOW_DATEBOX },
	{ "datefield",			WINDOW_DATEFIELD },
	{ "dialog",				WINDOW_DIALOG },
	{ "dockingarea",		WINDOW_DOCKINGAREA },
	{ "dockingwindow",		WINDOW_DOCKINGWINDOW },
	{ "edit",				WINDOW_EDIT },
	{ "errorbox",			WINDOW_ERRORBOX },
	{ "fixedbitmap",		WINDOW_FIXEDBITMAP },
	{ "fixedimage",			WINDOW_FIXEDIMAGE },
	{ "fixedline",			WINDOW_FIXEDLINE },
	{ "fixedtext",			WINDOW_FIXEDTEXT },
	{ "floatingwindow",		WINDOW_FLOATINGWINDOW },
	{ "framewindow",		VCLWINDOW_FRAMEWINDOW },
	{ "groupbox",			WINDOW_GROUPBOX },
	{ "helpbutton",			WINDOW_HELPBUTTON },
	{ "imagebutton",		WINDOW_IMAGEBUTTON },
	{ "imageradiobutton",	WINDOW_IMAGERADIOBUTTON },
	{ "infobox",			WINDOW_INFOBOX },
	{ "listbox",			WINDOW_LISTBOX },
	{ "longcurrencybox",	WINDOW_LONGCURRENCYBOX },
	{ "longcurrencyfield",	WINDOW_LONGCURRENCYFIELD },
	{ "menubutton",			WINDOW_MENUBUTTON },
	{ "messbox",			WINDOW_MESSBOX },
	{ "metricbox",			WINDOW_METRICBOX },
	{ "metricfield",		WINDOW_METRICFIELD },
	{ "modaldialog",		WINDOW_MODALDIALOG },
	{ "modelessdialog",		WINDOW_MODELESSDIALOG },
	{ "morebutton",			WINDOW_MOREBUTTON },
    { "multilineedit",		WINDOW_MULTILINEEDIT },
	{ "multilistbox",		WINDOW_MULTILISTBOX },
	{ "numericbox",			WINDOW_NUMERICBOX },
	{ "numericfield",		WINDOW_NUMERICFIELD },
	{ "okbutton",			WINDOW_OKBUTTON },
	{ "patternbox",			WINDOW_PATTERNBOX },
	{ "patternfield",		WINDOW_PATTERNFIELD },
	{ "pushbutton",			WINDOW_PUSHBUTTON },
	{ "querybox",			WINDOW_QUERYBOX },
	{ "radiobutton",		WINDOW_RADIOBUTTON },
	{ "scrollbar",			WINDOW_SCROLLBAR },
	{ "scrollbarbox",		WINDOW_SCROLLBARBOX },
    { "simpleanimation",	WINDOW_CONTROL },
    { "animatedimages",     WINDOW_CONTROL },
	{ "spinbutton",			WINDOW_SPINBUTTON },
	{ "spinfield",			WINDOW_SPINFIELD },
    { "throbber",        	WINDOW_CONTROL },
	{ "splitter",			WINDOW_SPLITTER },
	{ "splitwindow",		WINDOW_SPLITWINDOW },
	{ "statusbar",			WINDOW_STATUSBAR },
	{ "systemchildwindow",	VCLWINDOW_SYSTEMCHILDWINDOW },
	{ "tabcontrol",			WINDOW_TABCONTROL },
	{ "tabdialog",			WINDOW_TABDIALOG },
	{ "tabpage",			WINDOW_TABPAGE },
	{ "timebox",			WINDOW_TIMEBOX },
	{ "timefield",			WINDOW_TIMEFIELD },
	{ "toolbox",			WINDOW_TOOLBOX },
	{ "tristatebox",		WINDOW_TRISTATEBOX },
	{ "warningbox",			WINDOW_WARNINGBOX },
	{ "window",				WINDOW_WINDOW },
	{ "workwindow",			WINDOW_WORKWINDOW },
	{ "tabpagecontainer",	WINDOW_CONTROL },
	{ "tabpagemodel",		WINDOW_TABPAGE }
};

extern "C"
{
static int
#if defined( WNT )
 __cdecl
#endif
#if defined( ICC ) && defined( OS2 )
_Optlink
#endif
 	ComponentInfoCompare( const void* pFirst, const void* pSecond)
{
	return( strcmp( ((ComponentInfo*)pFirst)->pName,
		    		((ComponentInfo*)pSecond)->pName ) );
}
}

sal_uInt16 ImplGetComponentType( const String& rServiceName )
{
	static sal_Bool bSorted = sal_False;
	if( !bSorted )
	{
		qsort( 	(void*) aComponentInfos,
				sizeof( aComponentInfos ) / sizeof( ComponentInfo ),
				sizeof( ComponentInfo ),
				ComponentInfoCompare );
		bSorted = sal_True;
	}


	ComponentInfo aSearch;
	ByteString aServiceName( rServiceName, gsl_getSystemTextEncoding() );
	aServiceName.ToLowerAscii();
	if ( aServiceName.Len() )
		aSearch.pName = aServiceName.GetBuffer();
	else
		aSearch.pName = "window";

	ComponentInfo* pInf = (ComponentInfo*) bsearch( &aSearch,
						(void*) aComponentInfos,
						sizeof( aComponentInfos ) / sizeof( ComponentInfo ),
						sizeof( ComponentInfo ),
						ComponentInfoCompare );

	return pInf ? pInf->nWinType : 0;
}


//	----------------------------------------------------
//	class VCLXToolkit
//	----------------------------------------------------

static sal_Int32							nVCLToolkitInstanceCount = 0;
static sal_Bool									bInitedByVCLToolkit = sal_False;
//static cppu::OInterfaceContainerHelper *	pToolkits = 0;

static osl::Mutex & getInitMutex()
{
	static osl::Mutex * pM;
	if( !pM )
	{
		osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
		if( !pM )
		{
			static osl::Mutex aMutex;
			pM = &aMutex;
		}
	}
	return *pM;
}

static osl::Condition & getInitCondition()
{
	static osl::Condition * pC = 0;
	if( !pC )
	{
		osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
		if( !pC )
		{
			static osl::Condition aCondition;
			pC = &aCondition;
		}
	}
	return *pC;
}

struct ToolkitThreadData
{
	VCLXToolkit * pTk;
	::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr;

	ToolkitThreadData( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr, VCLXToolkit * pTk_ )
		: pTk( pTk_ )
		, xSMgr( rSMgr )
	{
	}
};

extern "C"
{
static void SAL_CALL ToolkitWorkerFunction( void* pArgs )
{
	ToolkitThreadData * pTTD = (ToolkitThreadData *)pArgs;
	bInitedByVCLToolkit = InitVCL( pTTD->xSMgr );
	if( bInitedByVCLToolkit )
	{
		UnoWrapper* pUnoWrapper = new UnoWrapper( pTTD->pTk );
		Application::SetUnoWrapper( pUnoWrapper );
	}
	getInitCondition().set();
	if( bInitedByVCLToolkit )
	{
		{
		osl::Guard< vos::IMutex > aGuard( Application::GetSolarMutex() );
		Application::Execute();
		}
		try
		{
			pTTD->pTk->dispose();
		}
		catch( com::sun::star::uno::Exception & )
		{
		}
		/*
		if( pToolkits )
		{
			cppu::OInterfaceIteratorHelper aIt( *pToolkits );
			::com::sun::star::uno::XInterface *	pI;
			while( pI = aIt.next() )
				((::com::sun::star::lang::XComponent *)pI)->dispose();

			// delete toolkit container
			osl::Guard< osl::Mutex > aGuard( getInitMutex() );
			delete pToolkits;
			pToolkits = 0;
		}
		*/
		DeInitVCL();
	}
    else
    {
        JoinMainLoopThread();
    }
	delete pTTD;
}
}

// contructor, which might initialize VCL
VCLXToolkit::VCLXToolkit( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr ):
    cppu::WeakComponentImplHelper7<
    ::com::sun::star::awt::XToolkit,
    ::com::sun::star::lang::XServiceInfo,
    ::com::sun::star::awt::XSystemChildFactory,
    ::com::sun::star::awt::XMessageBoxFactory,
    ::com::sun::star::awt::XDataTransferProviderAccess,
    ::com::sun::star::awt::XExtendedToolkit,
    ::com::sun::star::awt::XReschedule>( GetMutex() ),
    m_aTopWindowListeners(rBHelper.rMutex),
    m_aKeyHandlers(rBHelper.rMutex),
    m_aFocusListeners(rBHelper.rMutex),
    m_aEventListenerLink(LINK(this, VCLXToolkit, eventListenerHandler)),
    m_aKeyListenerLink(LINK(this, VCLXToolkit, keyListenerHandler)),
    m_bEventListener(false),
    m_bKeyListener(false)
{
	hSvToolsLib = NULL;
	fnSvtCreateWindow = NULL;

	osl::Guard< osl::Mutex > aGuard( getInitMutex() );
    nVCLToolkitInstanceCount++;
    if( ( nVCLToolkitInstanceCount == 1 ) && ( !Application::IsInMain() ) )
	{
		// setup execute thread
		CreateMainLoopThread( ToolkitWorkerFunction, new ToolkitThreadData( rSMgr, this ) );
		getInitCondition().wait();
		/*
		if( bInitedByVCLToolkit )
		{
			// insert in disposing list
			if( !pToolkits )
				pToolkits = new cppu::OInterfaceContainerHelper( getInitMutex() );
			pToolkits->addInterface( (::com::sun::star::lang::XComponent *)this );
		}
		*/
	}
}

VCLXToolkit::~VCLXToolkit()
{
}


void SAL_CALL VCLXToolkit::disposing()
{
	if ( hSvToolsLib )
	{
		osl_unloadModule( hSvToolsLib );
		hSvToolsLib = NULL;
		fnSvtCreateWindow = NULL;
	}

    {
        osl::Guard< osl::Mutex > aGuard( getInitMutex() );
        if( --nVCLToolkitInstanceCount == 0 )
        {
            if( bInitedByVCLToolkit )
            {
                Application::Quit();
                JoinMainLoopThread();
                bInitedByVCLToolkit = sal_False;
            }
        }
    }

    if (m_bEventListener)
    {
        ::Application::RemoveEventListener(m_aEventListenerLink);
        m_bEventListener = false;
    }
    if (m_bKeyListener)
    {
        ::Application::RemoveKeyListener(m_aKeyListenerLink);
        m_bKeyListener = false;
    }
    ::css::lang::EventObject aEvent(
        static_cast< ::cppu::OWeakObject * >(this));
    m_aTopWindowListeners.disposeAndClear(aEvent);
    m_aKeyHandlers.disposeAndClear(aEvent);
    m_aFocusListeners.disposeAndClear(aEvent);

/*
	osl::Guard< osl::Mutex > aGuard( getInitMutex() );
	// insert in disposing list
	if( pToolkits )
	{
		// remove from the disposing list
		pToolkits->removeInterface( (::com::sun::star::lang::XComponent *)this );
	}
*/
}


::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > VCLXToolkit::getDesktopWindow(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xRef;
	// 07/00: AppWindow doesn't exist anymore...
	return xRef;
}

::com::sun::star::awt::Rectangle VCLXToolkit::getWorkArea(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::awt::Rectangle aRect;
	// 07/00: AppWindow doesn't exist anymore...
	return aRect;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > VCLXToolkit::createWindow( const ::com::sun::star::awt::WindowDescriptor& rDescriptor ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
    return ImplCreateWindow( rDescriptor, WinBits(0) );
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > VCLXToolkit::createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > xRef;
	VCLXVirtualDevice* pVDev = new VCLXVirtualDevice;

	osl::Guard< vos::IMutex > aSolarGuard( Application::GetSolarMutex() );

	VirtualDevice* pV = new VirtualDevice;
	pV->SetOutputSizePixel( Size( Width, Height ) );
	pVDev->SetVirtualDevice( pV );

	xRef = pVDev;
	return xRef;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XRegion > VCLXToolkit::createRegion(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XRegion >  xRef = new VCLXRegion;
	return xRef;
}

Window*	VCLXToolkit::ImplCreateWindow( VCLXWindow** ppNewComp,
	const ::com::sun::star::awt::WindowDescriptor& rDescriptor,
    Window* pParent, WinBits nWinBits )
{
	String aServiceName( rDescriptor.WindowServiceName );
	aServiceName.ToLowerAscii();

	Window* pNewWindow = NULL;
	sal_uInt16 nType = ImplGetComponentType( aServiceName );

	if ( !pParent )
	{
		// Wenn die Component einen Parent braucht, dann NULL zurueckgeben,
		// spaeter mal ::com::sun::star::uno::Exception...
		sal_Bool bException = sal_True;
		if  (   ( nType == WINDOW_DIALOG )
            ||  ( nType == WINDOW_MODALDIALOG )
            ||  ( nType == WINDOW_MODELESSDIALOG )
            ||  ( nType == WINDOW_MESSBOX )
            ||  ( nType == WINDOW_INFOBOX )
            ||  ( nType == WINDOW_WARNINGBOX )
            ||  ( nType == WINDOW_ERRORBOX )
            ||  ( nType == WINDOW_QUERYBOX )
            )
			bException = sal_False;
		else if ( ( nType == WINDOW_WINDOW ) ||
				  ( nType == WINDOW_WORKWINDOW ) ||
				  ( nType == VCLWINDOW_FRAMEWINDOW ) )
		{
			if ( rDescriptor.Type == ::com::sun::star::awt::WindowClass_TOP )
				bException = sal_False;
		}

		if ( bException )
		{
			*ppNewComp = NULL;
			return NULL;
		}
	}

	if ( nType )
	{
		vos::OGuard aVclGuard( Application::GetSolarMutex()  );
		switch ( (WindowType)nType )
		{
			case WINDOW_CANCELBUTTON:
				pNewWindow = new CancelButton( pParent, nWinBits );
				*ppNewComp = new VCLXButton;
			break;
			case WINDOW_CHECKBOX:
		 		pNewWindow = new CheckBox( pParent, nWinBits );
				*ppNewComp = new VCLXCheckBox;
			break;
			case WINDOW_COMBOBOX:
				pNewWindow = new ComboBox( pParent, nWinBits|WB_AUTOHSCROLL );
				((ComboBox*)pNewWindow)->EnableAutoSize( sal_False );
				*ppNewComp = new VCLXComboBox;
			break;
			case WINDOW_CURRENCYBOX:
				pNewWindow = new CurrencyBox( pParent, nWinBits );
			break;
			case WINDOW_CURRENCYFIELD:
				pNewWindow = new CurrencyField( pParent, nWinBits );
				static_cast<CurrencyField*>(pNewWindow)->EnableEmptyFieldValue( sal_True );
				*ppNewComp = new VCLXNumericField;
				((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(CurrencyField*)pNewWindow );
			break;
			case WINDOW_DATEBOX:
				pNewWindow = new DateBox( pParent, nWinBits );
			break;
			case WINDOW_DATEFIELD:
				pNewWindow = new DateField( pParent, nWinBits );
				static_cast<DateField*>(pNewWindow)->EnableEmptyFieldValue( sal_True );
				*ppNewComp = new VCLXDateField;
				((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(DateField*)pNewWindow );
			break;
			case WINDOW_DOCKINGAREA:
				pNewWindow = new DockingAreaWindow( pParent );
			break;
			case WINDOW_MULTILINEEDIT:
			case WINDOW_EDIT:
				pNewWindow = new Edit( pParent, nWinBits );
				*ppNewComp = new VCLXEdit;
			break;
			case WINDOW_ERRORBOX:
				pNewWindow = new ErrorBox( pParent, nWinBits, String() );
				*ppNewComp = new VCLXMessageBox;
			break;
			case WINDOW_FIXEDBITMAP:
				pNewWindow = new FixedBitmap( pParent, nWinBits );
			break;
			case WINDOW_FIXEDIMAGE:
				pNewWindow = new ImageControl( pParent, nWinBits );
				*ppNewComp = new VCLXImageControl;
			break;
			case WINDOW_FIXEDLINE:
				pNewWindow = new FixedLine( pParent, nWinBits );
			break;
			case WINDOW_FIXEDTEXT:
				pNewWindow = new FixedText( pParent, nWinBits );
				*ppNewComp = new VCLXFixedText;
			break;
			case WINDOW_FLOATINGWINDOW:
				pNewWindow = new FloatingWindow( pParent, nWinBits );
			break;
			case WINDOW_GROUPBOX:
				pNewWindow = new GroupBox( pParent, nWinBits );
			break;
			case WINDOW_HELPBUTTON:
				pNewWindow = new HelpButton( pParent, nWinBits );
				*ppNewComp = new VCLXButton;
			break;
			case WINDOW_IMAGEBUTTON:
 				pNewWindow = new ImageButton( pParent, nWinBits );
				*ppNewComp = new VCLXButton;
			break;
			case WINDOW_IMAGERADIOBUTTON:
				pNewWindow = new ImageRadioButton( pParent, nWinBits );
				*ppNewComp = new VCLXButton;
			break;
			case WINDOW_INFOBOX:
				pNewWindow = new InfoBox( pParent, String() );
				*ppNewComp = new VCLXMessageBox;
			break;
			case WINDOW_LISTBOX:
				pNewWindow = new ListBox( pParent, nWinBits|WB_SIMPLEMODE|WB_AUTOHSCROLL );
				((ListBox*)pNewWindow)->EnableAutoSize( sal_False );
				*ppNewComp = new VCLXListBox;
			break;
			case WINDOW_LONGCURRENCYBOX:
				pNewWindow = new LongCurrencyBox( pParent, nWinBits );
			break;
			case WINDOW_LONGCURRENCYFIELD:
				pNewWindow = new LongCurrencyField( pParent, nWinBits );
				*ppNewComp = new VCLXCurrencyField;
				((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(LongCurrencyField*)pNewWindow );
			break;
			case WINDOW_MENUBUTTON:
				pNewWindow = new MenuButton( pParent, nWinBits );
				*ppNewComp = new VCLXButton;
			break;
			case WINDOW_MESSBOX:
				pNewWindow = new MessBox( pParent, nWinBits, String(), String() );
				*ppNewComp = new VCLXMessageBox;
			break;
			case WINDOW_METRICBOX:
				pNewWindow = new MetricBox( pParent, nWinBits );
			break;
			case WINDOW_METRICFIELD:
				pNewWindow = new MetricField( pParent, nWinBits );
				*ppNewComp = new VCLXMetricField;
				((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(MetricField*)pNewWindow );
			break;
			case WINDOW_DIALOG:
			case WINDOW_MODALDIALOG:
			case WINDOW_MODELESSDIALOG:
            {
				// Modal/Modeless nur durch Show/Execute
				if ( (pParent == NULL ) && ( rDescriptor.ParentIndex == -1 ) )
					pParent = DIALOG_NO_PARENT;
				pNewWindow = new Dialog( pParent, nWinBits );
				// #i70217# Don't always create a new component object. It's possible that VCL has called
				// GetComponentInterface( sal_True ) in the Dialog ctor itself (see Window::IsTopWindow() ) 
				// which creates a component object.
				css::uno::Reference< css::awt::XWindowPeer > xWinPeer = pNewWindow->GetComponentInterface( sal_False );
				if ( xWinPeer.is() )
					*ppNewComp = dynamic_cast< VCLXDialog* >( xWinPeer.get() );
				else
				    *ppNewComp = new VCLXDialog;
            }
			break;
			case WINDOW_MOREBUTTON:
				pNewWindow = new MoreButton( pParent, nWinBits );
				*ppNewComp = new VCLXButton;
			break;
			case WINDOW_MULTILISTBOX:
				pNewWindow = new MultiListBox( pParent, nWinBits );
				*ppNewComp = new VCLXListBox;
			break;
			case WINDOW_NUMERICBOX:
				pNewWindow = new NumericBox( pParent, nWinBits );
			break;
			case WINDOW_NUMERICFIELD:
				pNewWindow = new NumericField( pParent, nWinBits );
				static_cast<NumericField*>(pNewWindow)->EnableEmptyFieldValue( sal_True );
				*ppNewComp = new VCLXNumericField;
				((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(NumericField*)pNewWindow );
			break;
			case WINDOW_OKBUTTON:
				pNewWindow = new OKButton( pParent, nWinBits );
				*ppNewComp = new VCLXButton;
			break;
			case WINDOW_PATTERNBOX:
				pNewWindow = new PatternBox( pParent, nWinBits );
			break;
			case WINDOW_PATTERNFIELD:
				pNewWindow = new PatternField( pParent, nWinBits );
				*ppNewComp = new VCLXPatternField;
				((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(PatternField*)pNewWindow );
			break;
			case WINDOW_PUSHBUTTON:
				pNewWindow = new PushButton( pParent, nWinBits );
				*ppNewComp = new VCLXButton;
			break;
			case WINDOW_QUERYBOX:
				pNewWindow = new QueryBox( pParent, nWinBits, String() );
				*ppNewComp = new VCLXMessageBox;
			break;
			case WINDOW_RADIOBUTTON:
				pNewWindow = new RadioButton( pParent, nWinBits );
				*ppNewComp = new VCLXRadioButton;

				// by default, disable RadioCheck
				// Since the VCLXRadioButton really cares for it's RadioCheck settings, this is important:
				// if we enable it, the VCLXRadioButton will use RadioButton::Check instead of RadioButton::SetState
				// This leads to a strange behaviour if the control is newly created: when settings the initial
				// state to "checked", the RadioButton::Check (called because RadioCheck=sal_True) will uncheck
				// _all_other_ radio buttons in the same group. However, at this moment the grouping of the controls
				// is not really valid: the controls are grouped after they have been created, but we're still in
				// the creation process, so the RadioButton::Check relies on invalid grouping information.
				// 07.08.2001 - #87254# - frank.schoenheit@sun.com
				static_cast<RadioButton*>(pNewWindow)->EnableRadioCheck( sal_False );
			break;
			case WINDOW_SCROLLBAR:
				pNewWindow = new ScrollBar( pParent, nWinBits );
				*ppNewComp = new VCLXScrollBar;
			break;
			case WINDOW_SCROLLBARBOX:
				pNewWindow = new ScrollBarBox( pParent, nWinBits );
			break;
			case WINDOW_SPINBUTTON:
				pNewWindow = new SpinButton( pParent, nWinBits );
                *ppNewComp = new ::toolkit::VCLXSpinButton;
			break;
			case WINDOW_SPINFIELD:
				pNewWindow = new SpinField( pParent, nWinBits );
				*ppNewComp = new VCLXNumericField;
			break;
			case WINDOW_SPLITTER:
				pNewWindow = new Splitter( pParent, nWinBits );
			break;
			case WINDOW_SPLITWINDOW:
				pNewWindow = new SplitWindow( pParent, nWinBits );
			break;
			case WINDOW_STATUSBAR:
				pNewWindow = new StatusBar( pParent, nWinBits );
			break;
			case VCLWINDOW_SYSTEMCHILDWINDOW:
				pNewWindow = new SystemChildWindow( pParent, nWinBits );
				*ppNewComp = new VCLXSystemDependentWindow();
			break;
			case WINDOW_TABCONTROL:
				pNewWindow = new TabControl( pParent, nWinBits );
                *ppNewComp = new VCLXTabPageContainer;
			break;
			case WINDOW_TABDIALOG:
				pNewWindow = new TabDialog( pParent, nWinBits );
			break;
			case WINDOW_TABPAGE:
                /*
				if ( rDescriptor.WindowServiceName.equalsIgnoreAsciiCase(
                        ::rtl::OUString::createFromAscii("tabpagemodel") ) )
                {
                    pNewWindow = new TabControl( pParent, nWinBits );
                    *ppNewComp = new VCLXTabPageContainer;
                }
				else
                */
				{
					pNewWindow = new TabPage( pParent, nWinBits );
					*ppNewComp = new VCLXTabPage;
				}
			break;
			case WINDOW_TIMEBOX:
				pNewWindow = new TimeBox( pParent, nWinBits );
			break;
			case WINDOW_TIMEFIELD:
				pNewWindow = new TimeField( pParent, nWinBits );
				static_cast<TimeField*>(pNewWindow)->EnableEmptyFieldValue( sal_True );
				*ppNewComp = new VCLXTimeField;
				((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(TimeField*)pNewWindow );
			break;
			case WINDOW_TOOLBOX:
				pNewWindow = new ToolBox( pParent, nWinBits );
				*ppNewComp = new VCLXToolBox;
			break;
			case WINDOW_TRISTATEBOX:
				pNewWindow = new TriStateBox( pParent, nWinBits );
			break;
			case WINDOW_WARNINGBOX:
				pNewWindow = new WarningBox( pParent, nWinBits, String() );
				*ppNewComp = new VCLXMessageBox;
			break;
			case WINDOW_WORKWINDOW:
			case WINDOW_WINDOW:
			case VCLWINDOW_FRAMEWINDOW:
			case WINDOW_DOCKINGWINDOW:
				if ( rDescriptor.Type == ::com::sun::star::awt::WindowClass_TOP )
				{
					if (nType == WINDOW_DOCKINGWINDOW )
						pNewWindow = new DockingWindow( pParent, nWinBits );
					else
					{
						if ((pParent == NULL) && rDescriptor.Parent.is())
						{
							// try to get a system dependent window handle
							::com::sun::star::uno::Reference< ::com::sun::star::awt::XSystemDependentWindowPeer > xSystemDepParent(rDescriptor.Parent, ::com::sun::star::uno::UNO_QUERY);

							if (xSystemDepParent.is())
							{
								sal_Int8 processID[16];

								rtl_getGlobalProcessId( (sal_uInt8*)processID );

								::com::sun::star::uno::Sequence<sal_Int8> processIdSeq(processID, 16);

								::com::sun::star::uno::Any anyHandle = xSystemDepParent->getWindowHandle(processIdSeq, SYSTEM_DEPENDENT_TYPE);

                                // use sal_Int64 here to accomodate all int types
                                // uno::Any shift operator whill upcast if necessary
                                sal_Int64 nWindowHandle = 0;
                                sal_Bool bXEmbed = sal_False;

                                bool bUseParentData = true;
                                if( ! (anyHandle >>= nWindowHandle) )
                                {
                                    css::uno::Sequence< css::beans::NamedValue > aProps;
                                    if( anyHandle >>= aProps )
                                    {
                                        const int nProps = aProps.getLength();
                                        const css::beans::NamedValue* pProps = aProps.getConstArray();
                                        for( int i = 0; i < nProps; i++ )
                                        {
                                            if( pProps[i].Name.equalsAscii( "WINDOW" ) )
                                                pProps[i].Value >>= nWindowHandle;
                                            else if( pProps[i].Name.equalsAscii( "XEMBED" ) )
                                                pProps[i].Value >>= bXEmbed;
                                        }
                                    }
                                    else
                                        bUseParentData = false;
                                }

                                if( bUseParentData )
                                {
                                    SystemParentData aParentData;
                                    aParentData.nSize	= sizeof( aParentData );
                                    #if defined QUARTZ
                                    aParentData.pView	= reinterpret_cast<NSView*>(nWindowHandle);
                                    #elif defined UNX
                                    aParentData.aWindow = nWindowHandle;
                                    aParentData.bXEmbedSupport = bXEmbed;
                                    #elif defined WNT
                                    aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
                                    #elif defined OS2
                                    aParentData.hWnd = (HWND)nWindowHandle;
                                    #endif
                                    pNewWindow = new WorkWindow( &aParentData );
                                }
							}
						}

						if (!pNewWindow)
							pNewWindow = new WorkWindow( pParent, nWinBits );
					}

                    *ppNewComp = new VCLXTopWindow( pNewWindow->GetType() == WINDOW_WORKWINDOW );
				}
				else if ( rDescriptor.Type == ::com::sun::star::awt::WindowClass_CONTAINER )
				{
					if (nType == WINDOW_DOCKINGWINDOW )
						pNewWindow = new DockingWindow( pParent, nWinBits );
					else
						pNewWindow = new Window( pParent, nWinBits );
					*ppNewComp = new VCLXContainer;
				}
				else
				{
					if (nType == WINDOW_DOCKINGWINDOW )
						pNewWindow = new DockingWindow( pParent, nWinBits );
					else
						pNewWindow = new Window( pParent, nWinBits );
					*ppNewComp = new VCLXWindow;
				}
			break;
			case WINDOW_CONTROL:
                if  ( aServiceName.EqualsAscii( "simpleanimation" ) )
                {
                    pNewWindow = new Throbber( pParent, nWinBits, Throbber::IMAGES_NONE );
                    ((Throbber*)pNewWindow)->SetScaleMode( css::awt::ImageScaleMode::Anisotropic );
                        // (compatibility)
                    *ppNewComp = new ::toolkit::XSimpleAnimation;
                }
                else if ( aServiceName.EqualsAscii( "throbber" ) )
                {
                    pNewWindow = new Throbber( pParent, nWinBits, Throbber::IMAGES_NONE );
                    ((Throbber*)pNewWindow)->SetScaleMode( css::awt::ImageScaleMode::Anisotropic );
                        // (compatibility)
                    *ppNewComp = new ::toolkit::XThrobber;
                }
				else if ( rDescriptor.WindowServiceName.equalsIgnoreAsciiCase(
                        ::rtl::OUString::createFromAscii("tabpagecontainer") ) )
                {
                    pNewWindow = new TabControl( pParent, nWinBits );
                    *ppNewComp = new VCLXTabPageContainer;
                }
                else if ( aServiceName.EqualsAscii( "animatedimages" ) )
                {
                    pNewWindow = new Throbber( pParent, nWinBits );
                    *ppNewComp = new ::toolkit::AnimatedImagesPeer;
                }
			break;
            default:
                OSL_ENSURE( false, "VCLXToolkit::ImplCreateWindow: unknown window type!" );
                break;
		}
	}

	return pNewWindow;
}

extern "C" { static void SAL_CALL thisModule() {} }

css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::ImplCreateWindow(
    const css::awt::WindowDescriptor& rDescriptor,
    WinBits nForceWinBits )
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	osl::Guard< vos::IMutex > aSolarGuard( Application::GetSolarMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xRef;

	Window* pParent = NULL;
	if ( rDescriptor.Parent.is() )
	{
		VCLXWindow* pParentComponent = VCLXWindow::GetImplementation( rDescriptor.Parent );

        // #103939# Don't through assertion, may be it's a system dependend window, used in ImplCreateWindow.
        // DBG_ASSERT( pParentComponent, "ParentComponent not valid" );

		if ( pParentComponent )
			pParent = pParentComponent->GetWindow();
	}

	WinBits nWinBits = ImplGetWinBits( rDescriptor.WindowAttributes,
		ImplGetComponentType( rDescriptor.WindowServiceName ) );
    nWinBits |= nForceWinBits;

	VCLXWindow* pNewComp = NULL;

	Window* pNewWindow = NULL;
	// Try to create the window with SvTools
	// (do this _before_ creating it on our own: The old mechanism (extended toolkit in SvTools) did it this way,
	// and we need to stay compatible)
	// try to load the lib
	if ( !fnSvtCreateWindow && !hSvToolsLib )
	{
		::rtl::OUString aLibName = ::vcl::unohelper::CreateLibraryName( "svt", sal_True );
        hSvToolsLib = osl_loadModuleRelative(
            &thisModule, aLibName.pData, SAL_LOADMODULE_DEFAULT );
		if ( hSvToolsLib )
		{
			::rtl::OUString aFunctionName( RTL_CONSTASCII_USTRINGPARAM( "CreateWindow" ) );
			fnSvtCreateWindow = (FN_SvtCreateWindow)osl_getFunctionSymbol( hSvToolsLib, aFunctionName.pData );
		}
	}
	// ask the SvTool creation function
	if ( fnSvtCreateWindow )
		pNewWindow = fnSvtCreateWindow( &pNewComp, &rDescriptor, pParent, nWinBits );

	// if SvTools could not provide a window, create it ourself
	if ( !pNewWindow )
		pNewWindow = ImplCreateWindow( &pNewComp, rDescriptor, pParent, nWinBits );

	DBG_ASSERT( pNewWindow, "createWindow: Unknown Component!" );
	DBG_ASSERTWARNING( pNewComp, "createWindow: No special Interface!" );

	if ( pNewWindow )
	{
		pNewWindow->SetCreatedWithToolkit( sal_True );
		//pNewWindow->SetPosPixel( Point() ); // do not force (0,0) position, keep default pos instead

        if ( rDescriptor.WindowAttributes & ::com::sun::star::awt::WindowAttribute::MINSIZE )
		{
			pNewWindow->SetSizePixel( Size() );
		}
		else if ( rDescriptor.WindowAttributes & ::com::sun::star::awt::WindowAttribute::FULLSIZE )
		{
			if ( pParent )
				pNewWindow->SetSizePixel( pParent->GetOutputSizePixel() );
		}
		else if ( !VCLUnoHelper::IsZero( rDescriptor.Bounds ) )
		{
			Rectangle aRect = VCLRectangle( rDescriptor.Bounds );
			pNewWindow->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
		}

		if ( !pNewComp )
		{
			// Default-Interface
			xRef = pNewWindow->GetComponentInterface( sal_True );
		}
		else
		{
			pNewComp->SetCreatedWithToolkit( sal_True );
			xRef = pNewComp;
			pNewWindow->SetComponentInterface( xRef );
		}
        DBG_ASSERT( pNewWindow->GetComponentInterface( sal_False ) == xRef,
            "VCLXToolkit::createWindow: did #133706# resurge?" );

		if ( rDescriptor.WindowAttributes & ::com::sun::star::awt::WindowAttribute::SHOW )
			pNewWindow->Show();
	}

	return xRef;
}

::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > > VCLXToolkit::createWindows( const ::com::sun::star::uno::Sequence< ::com::sun::star::awt::WindowDescriptor >& rDescriptors ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_uInt32 nComponents = rDescriptors.getLength();
	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > > aSeq( nComponents );
	for ( sal_uInt32 n = 0; n < nComponents; n++ )
	{
		::com::sun::star::awt::WindowDescriptor aDescr = rDescriptors.getConstArray()[n];

		if ( aDescr.ParentIndex == (-1) )
			aDescr.Parent = NULL;
		else if ( ( aDescr.ParentIndex >= 0 ) && ( aDescr.ParentIndex < (short)n ) )
			aDescr.Parent = aSeq.getConstArray()[aDescr.ParentIndex];
		aSeq.getArray()[n] = createWindow( aDescr );
	}
	return aSeq;
}

// ::com::sun::star::awt::XSystemChildFactory
::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > VCLXToolkit::createSystemChild( const ::com::sun::star::uno::Any& Parent, const ::com::sun::star::uno::Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 nSystemType ) throw(::com::sun::star::uno::RuntimeException)
{
	Window* pChildWindow = NULL;
	if ( nSystemType == SYSTEM_DEPENDENT_TYPE )
	{
        // use sal_Int64 here to accomodate all int types
        // uno::Any shift operator whill upcast if necessary
        sal_Int64 nWindowHandle = 0;
        sal_Bool bXEmbed = sal_False;

        bool bUseParentData = true;
        if( ! (Parent >>= nWindowHandle) )
        {
            css::uno::Sequence< css::beans::NamedValue > aProps;
            if( Parent >>= aProps )
            {
                const int nProps = aProps.getLength();
                const css::beans::NamedValue* pProps = aProps.getConstArray();
                for( int i = 0; i < nProps; i++ )
                {
                    if( pProps[i].Name.equalsAscii( "WINDOW" ) )
                        pProps[i].Value >>= nWindowHandle;
                    else if( pProps[i].Name.equalsAscii( "XEMBED" ) )
                        pProps[i].Value >>= bXEmbed;
                }
            }
            else
                bUseParentData = false;
        }

        if( bUseParentData )
        {
            SystemParentData aParentData;
            aParentData.nSize	= sizeof( aParentData );
            #if defined QUARTZ
            aParentData.pView	= reinterpret_cast<NSView*>(nWindowHandle);
            #elif defined UNX
            aParentData.aWindow = nWindowHandle;
            aParentData.bXEmbedSupport = bXEmbed;
            #elif defined WNT
            aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
            #elif defined OS2
            aParentData.hWnd = (HWND)nWindowHandle;
            #endif
            osl::Guard< vos::IMutex > aGuard( Application::GetSolarMutex() );
            try
            {
                pChildWindow = new WorkWindow( &aParentData );
            }
            catch ( ::com::sun::star::uno::RuntimeException & rEx )
            {
                // system child window could not be created
                OSL_TRACE(
                    "VCLXToolkit::createSystemChild: caught %s\n",
                    ::rtl::OUStringToOString(
                        rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
                pChildWindow = NULL;
            }
        }
	}
    else if (nSystemType == com::sun::star::lang::SystemDependent::SYSTEM_JAVA)
    {
        osl::Guard< vos::IMutex > aGuard(Application::GetSolarMutex());
        pChildWindow = new WorkWindow(0, Parent);
    }

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer;
	if ( pChildWindow )
	{
        VCLXTopWindow* pPeer = new VCLXTopWindow(true);
        osl::Guard< vos::IMutex > aGuard( Application::GetSolarMutex() );
		pPeer->SetWindow( pChildWindow );
		xPeer = pPeer;
	}

	return xPeer;
}

// ::com::sun::star::awt::XMessageBoxFactory
::com::sun::star::uno::Reference< ::com::sun::star::awt::XMessageBox > SAL_CALL VCLXToolkit::createMessageBox( 
    const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& aParent, 
    const ::com::sun::star::awt::Rectangle& aPosSize, 
    const ::rtl::OUString& aType, 
    ::sal_Int32 aButtons, 
    const ::rtl::OUString& aTitle, 
    const ::rtl::OUString& aMessage ) throw (::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::awt::WindowDescriptor aDescriptor;

    sal_Int32 nWindowAttributes = css::awt::WindowAttribute::BORDER|css::awt::WindowAttribute::MOVEABLE|css::awt::WindowAttribute::CLOSEABLE;

    // Map button definitions to window attributes
    if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK;
    else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK_CANCEL )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK_CANCEL;
    else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO;
    else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO_CANCEL )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO_CANCEL;
    else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_RETRY_CANCEL )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::RETRY_CANCEL;

    // Map default button definitions to window attributes
    if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_OK )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_OK;
    else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_CANCEL )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_CANCEL;
    else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_YES )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_YES;
    else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_NO )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_NO;
    else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_RETRY )
        nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_RETRY;

    // No more bits for VclWindowPeerAttribute possible. Mapping must be
    // done explicitly using VCL methods
    WinBits nAddWinBits( 0 );
    if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_ABORT_IGNORE_RETRY )
        nAddWinBits |= WB_ABORT_RETRY_IGNORE;
    if ( sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_IGNORE )
        nAddWinBits |= WB_DEF_IGNORE;
    
    aDescriptor.Type              = css::awt::WindowClass_MODALTOP;
    aDescriptor.WindowServiceName = aType;
    aDescriptor.ParentIndex       = -1;
    aDescriptor.Parent            = aParent;
    aDescriptor.Bounds            = aPosSize;
    aDescriptor.WindowAttributes  = nWindowAttributes;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMessageBox > xMsgBox(
        ImplCreateWindow( aDescriptor, nAddWinBits ), css::uno::UNO_QUERY );
    css::uno::Reference< css::awt::XWindow > xWindow( xMsgBox, css::uno::UNO_QUERY );
    if ( xMsgBox.is() && xWindow.is() )
    {
	    Window * pWindow = VCLUnoHelper::GetWindow( xWindow );
        if ( pWindow )
        {
            osl::Guard< vos::IMutex > aGuard(Application::GetSolarMutex());
            xMsgBox->setCaptionText( aTitle );
            xMsgBox->setMessageText( aMessage );
        }
    }

    return xMsgBox;
}

::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > SAL_CALL VCLXToolkit::getDragGestureRecognizer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& window ) throw(::com::sun::star::uno::RuntimeException)
{
	Window * pWindow = VCLUnoHelper::GetWindow( window );

	if( pWindow )
		return pWindow->GetDragGestureRecognizer();

	return ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer >();
}

::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource > SAL_CALL VCLXToolkit::getDragSource( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& window ) throw(::com::sun::star::uno::RuntimeException)
{
	Window * pWindow = VCLUnoHelper::GetWindow( window );

	if( pWindow )
		return pWindow->GetDragSource();

	return ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource >();
}

::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTarget > SAL_CALL VCLXToolkit::getDropTarget( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& window ) throw(::com::sun::star::uno::RuntimeException)
{
	Window * pWindow = VCLUnoHelper::GetWindow( window );

	if( pWindow )
		return pWindow->GetDropTarget();

	return ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTarget >();
}

::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard > SAL_CALL VCLXToolkit::getClipboard( const ::rtl::OUString& clipboardName ) throw(::com::sun::star::uno::RuntimeException)
{
	if( clipboardName.getLength() == 0 )
	{
		if( !mxClipboard.is() )
		{
			::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
			if ( xFactory.is() )
			{
				// remember clipboard here
				mxClipboard = ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard > (
					xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ) ), ::com::sun::star::uno::UNO_QUERY );
			}
		}

		return mxClipboard;
	}

	else if( clipboardName.equals( ::rtl::OUString::createFromAscii("Selection") ) )
	{
		return mxSelection;
	}

	return ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >();
}

// XServiceInfo
::rtl::OUString VCLXToolkit::getImplementationName() throw(::com::sun::star::uno::RuntimeException)
{
	return rtl::OUString::createFromAscii( "stardiv.Toolkit.VCLXToolkit" );
}

sal_Bool VCLXToolkit::supportsService( const ::rtl::OUString& rServiceName ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::MutexGuard aGuard( GetMutex() );

    ::com::sun::star::uno::Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames();
	const ::rtl::OUString* pArray = aSNL.getConstArray();
	const ::rtl::OUString* pArrayEnd = aSNL.getConstArray();
	for (; pArray != pArrayEnd; ++pArray )
		if( *pArray == rServiceName )
			break;

	return pArray != pArrayEnd;
}

::com::sun::star::uno::Sequence< ::rtl::OUString > VCLXToolkit::getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException)
{
    ::rtl::OUString aServiceName( ::rtl::OUString::createFromAscii( szServiceName2_Toolkit ) );
    return ::com::sun::star::uno::Sequence< ::rtl::OUString >( &aServiceName, 1);
}

// css::awt::XExtendedToolkit:

// virtual
::sal_Int32 SAL_CALL VCLXToolkit::getTopWindowCount()
    throw (::css::uno::RuntimeException)
{
    return static_cast< ::sal_Int32 >(::Application::GetTopWindowCount());
        // XXX  numeric overflow
}

// virtual
::css::uno::Reference< ::css::awt::XTopWindow > SAL_CALL
VCLXToolkit::getTopWindow(::sal_Int32 nIndex)
    throw (::css::uno::RuntimeException)
{
    ::Window * p = ::Application::GetTopWindow(static_cast< long >(nIndex));
        // XXX  numeric overflow
    return ::css::uno::Reference< ::css::awt::XTopWindow >(
        p == 0 ? 0 : static_cast< ::css::awt::XWindow * >(p->GetWindowPeer()),
        ::css::uno::UNO_QUERY);
}

// virtual
::css::uno::Reference< ::css::awt::XTopWindow > SAL_CALL
VCLXToolkit::getActiveTopWindow() throw (::css::uno::RuntimeException)
{
    ::Window * p = ::Application::GetActiveTopWindow();
    return ::css::uno::Reference< ::css::awt::XTopWindow >(
        p == 0 ? 0 : static_cast< ::css::awt::XWindow * >(p->GetWindowPeer()),
        ::css::uno::UNO_QUERY);
}

// virtual
void SAL_CALL VCLXToolkit::addTopWindowListener(
    ::css::uno::Reference< ::css::awt::XTopWindowListener > const & rListener)
    throw (::css::uno::RuntimeException)
{
    OSL_ENSURE(rListener.is(), "Null rListener");
    ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
    if (rBHelper.bDisposed || rBHelper.bInDispose)
    {
        aGuard.clear();
        rListener->disposing(
            ::css::lang::EventObject(
                static_cast< ::cppu::OWeakObject * >(this)));
    }
    else if (m_aTopWindowListeners.addInterface(rListener) == 1
             && !m_bEventListener)
    {
        m_bEventListener = true;
        ::Application::AddEventListener(m_aEventListenerLink);
    }
}

// virtual
void SAL_CALL VCLXToolkit::removeTopWindowListener(
    ::css::uno::Reference< ::css::awt::XTopWindowListener > const & rListener)
    throw (::css::uno::RuntimeException)
{
    ::osl::MutexGuard aGuard(rBHelper.rMutex);
    if (!(rBHelper.bDisposed || rBHelper.bInDispose)
        && m_aTopWindowListeners.removeInterface(rListener) == 0
        && m_aFocusListeners.getLength() == 0 && m_bEventListener)
    {
        ::Application::RemoveEventListener(m_aEventListenerLink);
        m_bEventListener = false;
    }
}

// virtual
void SAL_CALL VCLXToolkit::addKeyHandler(
    ::css::uno::Reference< ::css::awt::XKeyHandler > const & rHandler)
    throw (::css::uno::RuntimeException)
{
    OSL_ENSURE(rHandler.is(), "Null rHandler");
    ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
    if (rBHelper.bDisposed || rBHelper.bInDispose)
    {
        aGuard.clear();
        rHandler->disposing(
            ::css::lang::EventObject(
                static_cast< ::cppu::OWeakObject * >(this)));
    }
    else if (m_aKeyHandlers.addInterface(rHandler) == 1 && !m_bKeyListener)
    {
        m_bKeyListener = true;
        ::Application::AddKeyListener(m_aKeyListenerLink);
    }
}

// virtual
void SAL_CALL VCLXToolkit::removeKeyHandler(
    ::css::uno::Reference< ::css::awt::XKeyHandler > const & rHandler)
    throw (::css::uno::RuntimeException)
{
    ::osl::MutexGuard aGuard(rBHelper.rMutex);
    if (!(rBHelper.bDisposed || rBHelper.bInDispose)
        && m_aKeyHandlers.removeInterface(rHandler) == 0 && m_bKeyListener)
    {
        ::Application::RemoveKeyListener(m_aKeyListenerLink);
        m_bKeyListener = false;
    }
}

// virtual
void SAL_CALL VCLXToolkit::addFocusListener(
    ::css::uno::Reference< ::css::awt::XFocusListener > const & rListener)
    throw (::css::uno::RuntimeException)
{
    OSL_ENSURE(rListener.is(), "Null rListener");
    ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
    if (rBHelper.bDisposed || rBHelper.bInDispose)
    {
        aGuard.clear();
        rListener->disposing(
            ::css::lang::EventObject(
                static_cast< ::cppu::OWeakObject * >(this)));
    }
    else if (m_aFocusListeners.addInterface(rListener) == 1
             && !m_bEventListener)
    {
        m_bEventListener = true;
        ::Application::AddEventListener(m_aEventListenerLink);
    }
}

// virtual
void SAL_CALL VCLXToolkit::removeFocusListener(
    ::css::uno::Reference< ::css::awt::XFocusListener > const & rListener)
    throw (::css::uno::RuntimeException)
{
    ::osl::MutexGuard aGuard(rBHelper.rMutex);
    if (!(rBHelper.bDisposed || rBHelper.bInDispose)
        && m_aFocusListeners.removeInterface(rListener) == 0
        && m_aTopWindowListeners.getLength() == 0 && m_bEventListener)
    {
        ::Application::RemoveEventListener(m_aEventListenerLink);
        m_bEventListener = false;
    }
}

// virtual
void SAL_CALL VCLXToolkit::fireFocusGained( 
    ::com::sun::star::uno::Reference< 
    ::com::sun::star::uno::XInterface > const &) 
    throw (::com::sun::star::uno::RuntimeException)
{
}
        
// virtual 
void SAL_CALL VCLXToolkit::fireFocusLost( 
    ::com::sun::star::uno::Reference< 
    ::com::sun::star::uno::XInterface > const &) 
    throw (::com::sun::star::uno::RuntimeException)
{
}


IMPL_LINK(VCLXToolkit, eventListenerHandler, ::VclSimpleEvent const *, pEvent)
{
    switch (pEvent->GetId())
    {
    case VCLEVENT_WINDOW_SHOW:
        callTopWindowListeners(
            pEvent, &::css::awt::XTopWindowListener::windowOpened);
        break;
    case VCLEVENT_WINDOW_HIDE:
        callTopWindowListeners(
            pEvent, &::css::awt::XTopWindowListener::windowClosed);
        break;
    case VCLEVENT_WINDOW_ACTIVATE:
        callTopWindowListeners(
            pEvent, &::css::awt::XTopWindowListener::windowActivated);
        break;
    case VCLEVENT_WINDOW_DEACTIVATE:
        callTopWindowListeners(
            pEvent, &::css::awt::XTopWindowListener::windowDeactivated);
        break;
    case VCLEVENT_WINDOW_CLOSE:
        callTopWindowListeners(
            pEvent, &::css::awt::XTopWindowListener::windowClosing);
        break;
    case VCLEVENT_WINDOW_GETFOCUS:
        callFocusListeners(pEvent, true);
        break;
    case VCLEVENT_WINDOW_LOSEFOCUS:
        callFocusListeners(pEvent, false);
        break;
    case VCLEVENT_WINDOW_MINIMIZE:
        callTopWindowListeners(
            pEvent, &::css::awt::XTopWindowListener::windowMinimized);
        break;
    case VCLEVENT_WINDOW_NORMALIZE:
        callTopWindowListeners(
            pEvent, &::css::awt::XTopWindowListener::windowNormalized);
        break;
    }
    return 0;
}

IMPL_LINK(VCLXToolkit, keyListenerHandler, ::VclSimpleEvent const *, pEvent)
{
    switch (pEvent->GetId())
    {
    case VCLEVENT_WINDOW_KEYINPUT:
        return callKeyHandlers(pEvent, true);
    case VCLEVENT_WINDOW_KEYUP:
        return callKeyHandlers(pEvent, false);
    }
    return 0;
}

void VCLXToolkit::callTopWindowListeners(
    ::VclSimpleEvent const * pEvent,
    void (SAL_CALL ::css::awt::XTopWindowListener::* pFn)(
        ::css::lang::EventObject const &))
{
    ::Window * pWindow
          = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
    if (pWindow->IsTopWindow())
    {
        ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > >
              aListeners(m_aTopWindowListeners.getElements());
        if (aListeners.hasElements())
        {
            ::css::lang::EventObject aAwtEvent(
                static_cast< ::css::awt::XWindow * >(pWindow->GetWindowPeer()));
            for (::sal_Int32 i = 0; i < aListeners.getLength(); ++i)
            {
                ::css::uno::Reference< ::css::awt::XTopWindowListener >
                      xListener(aListeners[i], ::css::uno::UNO_QUERY);
                try
                {
                    (xListener.get()->*pFn)(aAwtEvent);
                }
                catch (::css::uno::RuntimeException & rEx)
                {
                    OSL_TRACE(
                        "VCLXToolkit::callTopWindowListeners: caught %s\n",
                        ::rtl::OUStringToOString(
                            rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
                }
            }
        }
    }
}

long VCLXToolkit::callKeyHandlers(::VclSimpleEvent const * pEvent,
                                  bool bPressed)
{
    ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > >
          aHandlers(m_aKeyHandlers.getElements());
    
    if (aHandlers.hasElements())
    {
        ::Window * pWindow = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
        
        // See implementation in vclxwindow.cxx for mapping between VCL and UNO AWT event
        ::KeyEvent * pKeyEvent = static_cast< ::KeyEvent * >(
            static_cast< ::VclWindowEvent const * >(pEvent)->GetData());
        ::css::awt::KeyEvent aAwtEvent(
            static_cast< ::css::awt::XWindow * >(pWindow->GetWindowPeer()),
            (pKeyEvent->GetKeyCode().IsShift()
             ? ::css::awt::KeyModifier::SHIFT : 0)
            | (pKeyEvent->GetKeyCode().IsMod1()
               ? ::css::awt::KeyModifier::MOD1 : 0)
            | (pKeyEvent->GetKeyCode().IsMod2()
               ? ::css::awt::KeyModifier::MOD2 : 0)
            | (pKeyEvent->GetKeyCode().IsMod3()
               ? ::css::awt::KeyModifier::MOD3 : 0),
            pKeyEvent->GetKeyCode().GetCode(), pKeyEvent->GetCharCode(),
            sal::static_int_cast< sal_Int16 >(
                pKeyEvent->GetKeyCode().GetFunction()));
        for (::sal_Int32 i = 0; i < aHandlers.getLength(); ++i)
        {
            ::css::uno::Reference< ::css::awt::XKeyHandler > xHandler(
                aHandlers[i], ::css::uno::UNO_QUERY);
            try
            {
                if ((bPressed ? xHandler->keyPressed(aAwtEvent)
                      : xHandler->keyReleased(aAwtEvent)))
                    return 1;
            }
            catch (::css::uno::RuntimeException & rEx)
            {
                OSL_TRACE(
                    "VCLXToolkit::callKeyHandlers: caught %s\n",
                    ::rtl::OUStringToOString(
                       rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
            }
        }
    }
    return 0;
}

void VCLXToolkit::callFocusListeners(::VclSimpleEvent const * pEvent,
                                     bool bGained)
{
    ::Window * pWindow
          = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
    if (pWindow->IsTopWindow())
    {
        ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > >
              aListeners(m_aFocusListeners.getElements());
        if (aListeners.hasElements())
        {
            // Ignore the interior of compound controls when determining the
            // window that gets the focus next (see implementation in
            // vclxwindow.cxx for mapping between VCL and UNO AWT event):
            ::css::uno::Reference< css::uno::XInterface > xNext;
            ::Window * pFocus = ::Application::GetFocusWindow();
            for (::Window * p = pFocus; p != 0; p = p->GetParent())
                if (!p->IsCompoundControl())
                {
                    pFocus = p;
                    break;
                }
            if (pFocus != 0)
                xNext = pFocus->GetComponentInterface(true);
            ::css::awt::FocusEvent aAwtEvent(
                static_cast< ::css::awt::XWindow * >(pWindow->GetWindowPeer()),
                pWindow->GetGetFocusFlags(), xNext, false);
            for (::sal_Int32 i = 0; i < aListeners.getLength(); ++i)
            {
                ::css::uno::Reference< ::css::awt::XFocusListener > xListener(
                    aListeners[i], ::css::uno::UNO_QUERY);
                try
                {
                    bGained ? xListener->focusGained(aAwtEvent)
                        : xListener->focusLost(aAwtEvent);
                }
                catch (::css::uno::RuntimeException & rEx)
                {
                    OSL_TRACE(
                        "VCLXToolkit::callFocusListeners: caught %s\n",
                        ::rtl::OUStringToOString(
                            rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
                }
            }
        }
    }
}

// css::awt::XReschedule:

void SAL_CALL VCLXToolkit::reschedule()
    throw (::com::sun::star::uno::RuntimeException)
{
    Application::Reschedule(true);
}

