/**************************************************************
 *
 * 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/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 },
    { "animatedimages",     WINDOW_CONTROL },
	{ "spinbutton",			WINDOW_SPINBUTTON },
	{ "spinfield",			WINDOW_SPINFIELD },
	{ "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;
}


namespace
{
    struct MessageBoxTypeInfo
    {
        css::awt::MessageBoxType eType;
        const sal_Char          *pName;
        sal_Int32                nLen;
    };

    static MessageBoxTypeInfo aMessageBoxTypeInfo[] =
    {
        { css::awt::MessageBoxType_MESSAGEBOX,      RTL_CONSTASCII_STRINGPARAM("messbox") },
        { css::awt::MessageBoxType_INFOBOX,         RTL_CONSTASCII_STRINGPARAM("infobox") },
        { css::awt::MessageBoxType_WARNINGBOX,      RTL_CONSTASCII_STRINGPARAM("warningbox") },
        { css::awt::MessageBoxType_ERRORBOX,        RTL_CONSTASCII_STRINGPARAM("errorbox") },
        { css::awt::MessageBoxType_QUERYBOX,        RTL_CONSTASCII_STRINGPARAM("querybox") },
        { css::awt::MessageBoxType_MAKE_FIXED_SIZE, 0, 0 }
    };

    static bool lcl_convertMessageBoxType(
        rtl::OUString &sType,
        css::awt::MessageBoxType eType )
    {
        const MessageBoxTypeInfo *pMap = aMessageBoxTypeInfo;
        css::awt::MessageBoxType eVal = css::awt::MessageBoxType_MAKE_FIXED_SIZE;

        while ( pMap->pName )
        {
            if ( pMap->eType == eType )
            {
                eVal = eType;
                sType = rtl::OUString( pMap->pName, pMap->nLen, RTL_TEXTENCODING_ASCII_US );
                break;
            }
            pMap++;
        }

        return ( eVal != css::awt::MessageBoxType_MAKE_FIXED_SIZE );
    }
}

//	----------------------------------------------------
//	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;
}
}

// constructor, 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)
{
#ifdef WNT
	CEnableAccessInterface e;
#endif
    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 accommodate all int types
                                // uno::Any shift operator will 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 ( 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 accommodate all int types
        // uno::Any shift operator will 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,
    ::com::sun::star::awt::MessageBoxType eType,
    ::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;

    rtl::OUString aType;
    lcl_convertMessageBoxType( aType, eType );

    aDescriptor.Type              = css::awt::WindowClass_MODALTOP;
    aDescriptor.WindowServiceName = aType;
    aDescriptor.ParentIndex       = -1;
    aDescriptor.Parent            = aParent;
    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);
}
