/**************************************************************
 * 
 * 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_vcl.hxx"

#include <string.h>
#include <tools/svwin.h>
#ifdef WNT
#include <process.h>
#endif
#ifdef __MINGW32__
#include <excpt.h>
#endif

#include <osl/file.hxx>

#include <vos/mutex.hxx>

#include <tools/solarmutex.hxx>
#include <tools/debug.hxx>

#include <vcl/timer.hxx>
#include <vcl/apptypes.hxx>

#include <win/wincomp.hxx>
#include <win/salids.hrc>
#include <win/saldata.hxx>
#include <win/salinst.h>
#include <win/salframe.h>
#include <win/salobj.h>
#include <win/saltimer.h>
#include <win/salbmp.h>

#include <salimestatus.hxx>
#include <salsys.hxx>

#ifndef min
#define min(a,b)	(((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a,b)	(((a) > (b)) ? (a) : (b))
#endif

#if defined _MSC_VER
#pragma warning(push, 1)
#pragma warning( disable: 4917 )
#endif

#include <GdiPlus.h>
#include <GdiPlusEnums.h>
#include <GdiPlusColor.h>
#include <Shlobj.h>

#if defined _MSC_VER
#pragma warning(pop)
#endif

// =======================================================================

void SalAbort( const XubString& rErrorText )
{
	ImplFreeSalGDI();

	if ( !rErrorText.Len() )
	{
		// #112255# make sure crash reporter is triggered
		RaiseException( 0, EXCEPTION_NONCONTINUABLE, 0, NULL );
		FatalAppExit( 0, "Application Error" );
	}
	else
	{
		// #112255# make sure crash reporter is triggered
		RaiseException( 0, EXCEPTION_NONCONTINUABLE, 0, NULL );
		ByteString aErrorText( ImplSalGetWinAnsiString( rErrorText ) );
		FatalAppExit( 0, aErrorText.GetBuffer() );
	}
}

// =======================================================================

LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );

// =======================================================================

class SalYieldMutex : public vos::OMutex
{
public: // for ImplSalYield()
	WinSalInstance*             mpInstData;
	sal_uLong                       mnCount;
	DWORD                       mnThreadId;

public:
								SalYieldMutex( WinSalInstance* pInstData );

	virtual void SAL_CALL       acquire();
	virtual void SAL_CALL       release();
	virtual sal_Bool SAL_CALL   tryToAcquire();

	sal_uLong                       GetAcquireCount( sal_uLong nThreadId );
};

// -----------------------------------------------------------------------

SalYieldMutex::SalYieldMutex( WinSalInstance* pInstData )
{
	mpInstData  = pInstData;
	mnCount     = 0;
	mnThreadId  = 0;
}

// -----------------------------------------------------------------------

void SAL_CALL SalYieldMutex::acquire()
{
	OMutex::acquire();
	mnCount++;
	mnThreadId = GetCurrentThreadId();
}

// -----------------------------------------------------------------------

void SAL_CALL SalYieldMutex::release()
{
	DWORD nThreadId = GetCurrentThreadId();
	if ( mnThreadId != nThreadId )
		OMutex::release();
	else
	{
		SalData* pSalData = GetSalData();
		if ( pSalData->mnAppThreadId != nThreadId )
		{
			if ( mnCount == 1 )
			{
				// If we don't call these message, the Output from the
				// Java clients doesn't come in the right order
				GdiFlush();

				mpInstData->mpSalWaitMutex->acquire();
				if ( mpInstData->mnYieldWaitCount )
					ImplPostMessage( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
				mnThreadId = 0;
				mnCount--;
				OMutex::release();
				mpInstData->mpSalWaitMutex->release();
			}
			else
			{
				mnCount--;
				OMutex::release();
			}
		}
		else
		{
			if ( mnCount == 1 )
				mnThreadId = 0;
			mnCount--;
			OMutex::release();
		}
	}
}

// -----------------------------------------------------------------------

sal_Bool SAL_CALL SalYieldMutex::tryToAcquire()
{
	if( OMutex::tryToAcquire() )
	{
		mnCount++;
		mnThreadId = GetCurrentThreadId();
		return sal_True;
	}
	else
		return sal_False;
}

// -----------------------------------------------------------------------

sal_uLong SalYieldMutex::GetAcquireCount( sal_uLong nThreadId )
{
	if ( nThreadId == mnThreadId )
		return mnCount;
	else
		return 0;
}

// -----------------------------------------------------------------------

void ImplSalYieldMutexAcquireWithWait()
{
	WinSalInstance* pInst = GetSalData()->mpFirstInstance;
	if ( !pInst )
		return;

	// If we are the main thread, then we must wait with wait, because
	// in if we don't reschedule, then we create deadlocks if a Windows
	// Function is called from another thread. If we arn't the main thread,
	// than we call qcquire directly.
	DWORD nThreadId = GetCurrentThreadId();
	SalData* pSalData = GetSalData();
	if ( pSalData->mnAppThreadId == nThreadId )
	{
		// Wenn wir den Mutex nicht bekommen, muessen wir solange
		// warten, bis wir Ihn bekommen
		sal_Bool bAcquire = FALSE;
		do
		{
			if ( pInst->mpSalYieldMutex->tryToAcquire() )
				bAcquire = TRUE;
			else
			{
				pInst->mpSalWaitMutex->acquire();
				if ( pInst->mpSalYieldMutex->tryToAcquire() )
				{
					bAcquire = TRUE;
					pInst->mpSalWaitMutex->release();
				}
				else
				{
					pInst->mnYieldWaitCount++;
					pInst->mpSalWaitMutex->release();
					MSG aTmpMsg;
					ImplGetMessage( &aTmpMsg, pInst->mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
					pInst->mnYieldWaitCount--;
					if ( pInst->mnYieldWaitCount )
						ImplPostMessage( pInst->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
				}
			}
		}
		while ( !bAcquire );
	}
	else
		pInst->mpSalYieldMutex->acquire();
}

// -----------------------------------------------------------------------

sal_Bool ImplSalYieldMutexTryToAcquire()
{
	WinSalInstance* pInst = GetSalData()->mpFirstInstance;
	if ( pInst )
		return pInst->mpSalYieldMutex->tryToAcquire();
	else
		return FALSE;
}

// -----------------------------------------------------------------------

void ImplSalYieldMutexAcquire()
{
	WinSalInstance* pInst = GetSalData()->mpFirstInstance;
	if ( pInst )
		pInst->mpSalYieldMutex->acquire();
}

// -----------------------------------------------------------------------

void ImplSalYieldMutexRelease()
{
	WinSalInstance* pInst = GetSalData()->mpFirstInstance;
	if ( pInst )
	{
		GdiFlush();
		pInst->mpSalYieldMutex->release();
	}
}

// -----------------------------------------------------------------------

sal_uLong ImplSalReleaseYieldMutex()
{
	WinSalInstance* pInst = GetSalData()->mpFirstInstance;
	if ( !pInst )
		return 0;

	SalYieldMutex*  pYieldMutex = pInst->mpSalYieldMutex;
	sal_uLong           nCount = pYieldMutex->GetAcquireCount( GetCurrentThreadId() );
	sal_uLong           n = nCount;
	while ( n )
	{
		pYieldMutex->release();
		n--;
	}

	return nCount;
}

// -----------------------------------------------------------------------

void ImplSalAcquireYieldMutex( sal_uLong nCount )
{
	WinSalInstance* pInst = GetSalData()->mpFirstInstance;
	if ( !pInst )
		return;

	SalYieldMutex*  pYieldMutex = pInst->mpSalYieldMutex;
	while ( nCount )
	{
		pYieldMutex->acquire();
		nCount--;
	}
}

// -----------------------------------------------------------------------

bool WinSalInstance::CheckYieldMutex()
{
    bool bRet = true;
	SalData*    pSalData = GetSalData();
	DWORD       nCurThreadId = GetCurrentThreadId();
	if ( pSalData->mnAppThreadId != nCurThreadId )
	{
		if ( pSalData->mpFirstInstance )
		{
			SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex;
			if ( pYieldMutex->mnThreadId != nCurThreadId )
			{
			    bRet = false;
			}
		}
	}
	else
	{
		if ( pSalData->mpFirstInstance )
		{
			SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex;
			if ( pYieldMutex->mnThreadId != nCurThreadId )
			{
			    bRet = false;
			}
		}
	}
	return bRet;
}

// =======================================================================

void SalData::initKeyCodeMap()
{
	UINT nKey = 0xffffffff;
	#define initKey( a, b )\
		nKey = LOWORD( VkKeyScan( a ) );\
		if( nKey < 0xffff )\
			maVKMap[ nKey ] = b;

	initKey( '+', KEY_ADD );
	initKey( '-', KEY_SUBTRACT );
	initKey( '*', KEY_MULTIPLY );
	initKey( '/', KEY_DIVIDE );                                             
	initKey( '.', KEY_POINT );
	initKey( ',', KEY_COMMA );
	initKey( '<', KEY_LESS );
	initKey( '>', KEY_GREATER );
	initKey( '=', KEY_EQUAL );
	initKey( '~', KEY_TILDE );
	initKey( '`', KEY_QUOTELEFT );
}

// =======================================================================
// -------
// SalData
// -------

SalData::SalData()
{
	mhInst = 0;                 // default instance handle
	mhPrevInst = 0;             // previous instance handle
	mnCmdShow = 0;              // default frame show style
	mhDitherPal = 0;            // dither palette
	mhDitherDIB = 0;            // dither memory handle
	mpDitherDIB = 0;            // dither memory
	mpDitherDIBData = 0;        // beginning of DIB data
	mpDitherDiff = 0;           // Dither mapping table
	mpDitherLow = 0;            // Dither mapping table
	mpDitherHigh = 0;           // Dither mapping table
	mnTimerMS = 0;              // Current Time (in MS) of the Timer
	mnTimerOrgMS = 0;           // Current Original Time (in MS)
	mnNextTimerTime = 0;
	mnLastEventTime = 0;
	mnTimerId = 0;              // windows timer id
	mbInTimerProc = FALSE;      // timer event is currently being dispatched
	mhSalObjMsgHook = 0;        // hook to get interesting msg for SalObject
	mhWantLeaveMsg = 0;         // window handle, that want a MOUSELEAVE message
	mpMouseLeaveTimer = 0;      // Timer for MouseLeave Test
	mpFirstInstance = 0;        // pointer of first instance
	mpFirstFrame = 0;           // pointer of first frame
	mpFirstObject = 0;          // pointer of first object window
	mpFirstVD = 0;              // first VirDev
	mpFirstPrinter = 0;         // first printing printer
	mpHDCCache = 0;             // Cache for three DC's
	mh50Bmp = 0;                // 50% Bitmap
	mh50Brush = 0;              // 50% Brush
	int i;
	for(i=0; i<MAX_STOCKPEN; i++)
	{
		maStockPenColorAry[i] = 0;
		mhStockPenAry[i] = 0;
	}
	for(i=0; i<MAX_STOCKBRUSH; i++)
	{
		maStockBrushColorAry[i] = 0;
		mhStockBrushAry[i] = 0;
	}
	mnStockPenCount = 0;        // count of static pens
	mnStockBrushCount = 0;      // count of static brushes
	mnSalObjWantKeyEvt = 0;     // KeyEvent, welcher vom SalObj-Hook verarbeitet werden soll
	mnCacheDCInUse = 0;         // count of CacheDC in use
	mbObjClassInit = FALSE;     // is SALOBJECTCLASS initialised
	mbInPalChange = FALSE;      // is in WM_QUERYNEWPALETTE
	mnAppThreadId = 0;          // Id from Applikation-Thread
	mbScrSvrEnabled = FALSE;    // ScreenSaver enabled
	mnSageStatus = 0;           // status of Sage-DLL (DISABLE_AGENT == nicht vorhanden)
	mpSageEnableProc = 0;       // funktion to deactivate the system agent
	mpFirstIcon = 0;            // icon cache, points to first icon, NULL if none
	mpTempFontItem = 0;
	mbThemeChanged = FALSE;     // true if visual theme was changed: throw away theme handles
	mbThemeMenuSupport = FALSE;

    // init with NULL
    gdiplusToken = 0;
    maDwmLib     = 0;
    mpDwmIsCompositionEnabled = 0;
	
	initKeyCodeMap();

	SetSalData( this );
	initNWF();
}

SalData::~SalData()
{
	deInitNWF();
	SetSalData( NULL );
}

void InitSalData()
{
	SalData* pSalData = new SalData;
	CoInitialize(0);

    // init GDIPlus
    static Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Gdiplus::GdiplusStartup(&pSalData->gdiplusToken, &gdiplusStartupInput, NULL);
}


void DeInitSalData()
{
	CoUninitialize();
	SalData* pSalData = GetSalData();

    // deinit GDIPlus
    if(pSalData)
    {
        Gdiplus::GdiplusShutdown(pSalData->gdiplusToken);
    }

    delete pSalData;
}

// -----------------------------------------------------------------------

void InitSalMain()
{
	// remember data, copied from WinMain
	SalData* pData = GetAppSalData();
	if ( pData )    // Im AppServer NULL
	{
		STARTUPINFO aSI;
		aSI.cb = sizeof( aSI );
		GetStartupInfo( &aSI );
		pData->mhInst                   = GetModuleHandle( NULL );
		pData->mhPrevInst               = NULL;
		pData->mnCmdShow                = aSI.wShowWindow;
	}
}

void DeInitSalMain()
{
}

// -----------------------------------------------------------------------

SalInstance* CreateSalInstance()
{
	SalData* pSalData = GetSalData();

	// determine the windows version
	aSalShlData.mbWXP        = 0;
    aSalShlData.mbWPrinter   = 0;
	WORD nVer = (WORD)GetVersion();
	aSalShlData.mnVersion = (((WORD)LOBYTE(nVer)) * 100) + HIBYTE(nVer);
	if ( aSalShlData.mnVersion >= 400 )
		aSalShlData.mbW40 = 1;
    rtl_zeroMemory( &aSalShlData.maVersionInfo, sizeof(aSalShlData.maVersionInfo) );
	aSalShlData.maVersionInfo.dwOSVersionInfoSize = sizeof( aSalShlData.maVersionInfo );
	if ( GetVersionEx( &aSalShlData.maVersionInfo ) )
	{
		if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
		{
			// Windows XP ?
			if ( aSalShlData.maVersionInfo.dwMajorVersion > 5 ||
			   ( aSalShlData.maVersionInfo.dwMajorVersion == 5 && aSalShlData.maVersionInfo.dwMinorVersion >= 1 ) )
				aSalShlData.mbWXP = 1;
            if( aSalShlData.maVersionInfo.dwMajorVersion >= 5 )
                aSalShlData.mbWPrinter = 1;
		}
	}

	pSalData->mnAppThreadId = GetCurrentThreadId();

	// register frame class
	if ( !pSalData->mhPrevInst )
	{
			WNDCLASSEXW aWndClassEx;
			aWndClassEx.cbSize          = sizeof( aWndClassEx );
			aWndClassEx.style           = CS_OWNDC;
			aWndClassEx.lpfnWndProc     = SalFrameWndProcW;
			aWndClassEx.cbClsExtra      = 0;
			aWndClassEx.cbWndExtra      = SAL_FRAME_WNDEXTRA;
			aWndClassEx.hInstance       = pSalData->mhInst;
			aWndClassEx.hCursor         = 0;
			aWndClassEx.hbrBackground   = 0;
			aWndClassEx.lpszMenuName    = 0;
			aWndClassEx.lpszClassName   = SAL_FRAME_CLASSNAMEW;
			ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm );
			if ( !RegisterClassExW( &aWndClassEx ) )
				return NULL;

			aWndClassEx.hIcon           = 0;
			aWndClassEx.hIconSm         = 0;
			aWndClassEx.style          |= CS_SAVEBITS;
			aWndClassEx.lpszClassName   = SAL_SUBFRAME_CLASSNAMEW;
			if ( !RegisterClassExW( &aWndClassEx ) )
				return NULL;

			// shadow effect for popups on XP
			if( aSalShlData.mbWXP )
				aWndClassEx.style       |= CS_DROPSHADOW;
			aWndClassEx.lpszClassName   = SAL_TMPSUBFRAME_CLASSNAMEW;
			if ( !RegisterClassExW( &aWndClassEx ) )
				return NULL;

			aWndClassEx.style           = 0;
			aWndClassEx.lpfnWndProc     = SalComWndProcW;
			aWndClassEx.cbWndExtra      = 0;
			aWndClassEx.lpszClassName   = SAL_COM_CLASSNAMEW;
			if ( !RegisterClassExW( &aWndClassEx ) )
				return NULL;
	}

	HWND hComWnd = CreateWindowExW( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEW,
								   L"", WS_POPUP, 0, 0, 0, 0, 0, 0,
								   pSalData->mhInst, NULL );
	if ( !hComWnd )
		return NULL;

	WinSalInstance* pInst = new WinSalInstance;

	// init instance (only one instance in this version !!!)
	pSalData->mpFirstInstance   = pInst;
	pInst->mhInst    = pSalData->mhInst;
	pInst->mhComWnd  = hComWnd;

	// init static GDI Data
	ImplInitSalGDI();

	return pInst;
}

// -----------------------------------------------------------------------

void DestroySalInstance( SalInstance* pInst )
{
	SalData* pSalData = GetSalData();

	//  (only one instance in this version !!!)

	ImplFreeSalGDI();

	// reset instance
	if ( pSalData->mpFirstInstance == pInst )
		pSalData->mpFirstInstance = NULL;

	delete pInst;
}

// -----------------------------------------------------------------------

WinSalInstance::WinSalInstance()
{
	mhComWnd                 = 0;
	mpSalYieldMutex          = new SalYieldMutex( this );
	mpSalWaitMutex           = new vos::OMutex;
	mnYieldWaitCount         = 0;
	mpSalYieldMutex->acquire();
	::tools::SolarMutex::SetSolarMutex( mpSalYieldMutex );
}

// -----------------------------------------------------------------------

WinSalInstance::~WinSalInstance()
{
	::tools::SolarMutex::SetSolarMutex( 0 );
	mpSalYieldMutex->release();
	delete mpSalYieldMutex;
	delete mpSalWaitMutex;
	DestroyWindow( mhComWnd );
}

// -----------------------------------------------------------------------

vos::IMutex* WinSalInstance::GetYieldMutex()
{
	return mpSalYieldMutex;
}

// -----------------------------------------------------------------------

sal_uLong WinSalInstance::ReleaseYieldMutex()
{
	return ImplSalReleaseYieldMutex();
}

// -----------------------------------------------------------------------

void WinSalInstance::AcquireYieldMutex( sal_uLong nCount )
{
	ImplSalAcquireYieldMutex( nCount );
}

// -----------------------------------------------------------------------

static void ImplSalDispatchMessage( MSG* pMsg )
{
	SalData* pSalData = GetSalData();
	if ( pSalData->mpFirstObject )
	{
		if ( ImplSalPreDispatchMsg( pMsg ) )
			return;
	}
	LRESULT lResult = ImplDispatchMessage( pMsg );
	if ( pSalData->mpFirstObject )
		ImplSalPostDispatchMsg( pMsg, lResult );
}

// -----------------------------------------------------------------------

void ImplSalYield( sal_Bool bWait, sal_Bool bHandleAllCurrentEvents )
{
	MSG aMsg;
	bool bWasMsg = false, bOneEvent = false;
    
    int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1;
    do
    {
		if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
		{
            if ( !ImplInterceptChildWindowKeyDown( aMsg ) )
            {
                TranslateMessage( &aMsg );
                ImplSalDispatchMessage( &aMsg );
            }

			bOneEvent = bWasMsg = true;
		}
        else
            bOneEvent = false;
    } while( --nMaxEvents && bOneEvent );

	if ( bWait && ! bWasMsg )
	{
		if ( ImplGetMessage( &aMsg, 0, 0, 0 ) )
		{
            if ( !ImplInterceptChildWindowKeyDown( aMsg ) )
            {
                TranslateMessage( &aMsg );
                ImplSalDispatchMessage( &aMsg );
            }
		}
	}
}

// -----------------------------------------------------------------------

void WinSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
{
	SalYieldMutex*  pYieldMutex = mpSalYieldMutex;
	SalData*        pSalData = GetSalData();
	DWORD           nCurThreadId = GetCurrentThreadId();
	sal_uLong           nCount = pYieldMutex->GetAcquireCount( nCurThreadId );
	sal_uLong           n = nCount;
	while ( n )
	{
		pYieldMutex->release();
		n--;
	}
	if ( pSalData->mnAppThreadId != nCurThreadId )
	{
		// #97739# A SendMessage call blocks until the called thread (here: the main thread) 
		// returns. During a yield however, messages are processed in the main thread that might
		// result in a new message loop due to opening a dialog. Thus, SendMessage would not
		// return which will block this thread!
		// Solution: just give up the time slice and hope that messages are processed
		// by the main thread anyway (where all windows are created)
		// If the mainthread is not currently handling messages, then our SendMessage would
		// also do nothing, so this seems to be reasonable.

		// #i18883# only sleep if potential deadlock scenario, ie, when a dialog is open
		if( ImplGetSVData()->maAppData.mnModalMode )
			Sleep(1);
		else
			ImplSendMessage( mhComWnd, SAL_MSG_THREADYIELD, (WPARAM)bWait, (LPARAM)bHandleAllCurrentEvents );

		n = nCount;
		while ( n )
		{
			pYieldMutex->acquire();
			n--;
		}
	}
	else
	{
		ImplSalYield( bWait, bHandleAllCurrentEvents );

		n = nCount;
		while ( n )
		{
			ImplSalYieldMutexAcquireWithWait();
			n--;
		}
	}
}

// -----------------------------------------------------------------------

LRESULT CALLBACK SalComWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
{
	LRESULT nRet = 0;


	switch ( nMsg )
	{
		case SAL_MSG_PRINTABORTJOB:
			ImplSalPrinterAbortJobAsync( (HDC)wParam );
			rDef = FALSE;
			break;
		case SAL_MSG_THREADYIELD:
			ImplSalYield( (sal_Bool)wParam, (sal_Bool)lParam );
			rDef = FALSE;
			break;
		// If we get this message, because another GetMessage() call
		// has recieved this message, we must post this message to
		// us again, because in the other case we wait forever.
		case SAL_MSG_RELEASEWAITYIELD:
			{
			WinSalInstance* pInst = GetSalData()->mpFirstInstance;
			if ( pInst && pInst->mnYieldWaitCount )
				ImplPostMessage( hWnd, SAL_MSG_RELEASEWAITYIELD, wParam, lParam );
			}
			rDef = FALSE;
			break;
		case SAL_MSG_STARTTIMER:
			ImplSalStartTimer( (sal_uLong) lParam, FALSE );
			rDef = FALSE;
			break;
		case SAL_MSG_CREATEFRAME:
			nRet = (LRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (HWND)lParam, (sal_uLong)wParam );
			rDef = FALSE;
			break;
		case SAL_MSG_RECREATEHWND:
			nRet = (LRESULT)ImplSalReCreateHWND( (HWND)wParam, (HWND)lParam, FALSE );
			rDef = FALSE;
			break;
		case SAL_MSG_RECREATECHILDHWND:
			nRet = (LRESULT)ImplSalReCreateHWND( (HWND)wParam, (HWND)lParam, TRUE );
			rDef = FALSE;
			break;
		case SAL_MSG_DESTROYFRAME:
			delete (SalFrame*)lParam;
			rDef = FALSE;
			break;
		case SAL_MSG_DESTROYHWND:
			//We only destroy the native window here. We do NOT destroy the SalFrame contained
			//in the structure (GetWindowPtr()). 
			if (DestroyWindow((HWND)lParam) == 0)
			{
				OSL_ENSURE(0, "DestroyWindow failed!");
				//Failure: We remove the SalFrame from the window structure. So we avoid that
				// the window structure may contain an invalid pointer, once the SalFrame is deleted.
			   SetWindowPtr((HWND)lParam, 0);
			}
			rDef = FALSE;
			break;
		case SAL_MSG_CREATEOBJECT:
			nRet = (LRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (WinSalFrame*)lParam );
			rDef = FALSE;
			break;
		case SAL_MSG_DESTROYOBJECT:
			delete (SalObject*)lParam;
			rDef = FALSE;
			break;
		case SAL_MSG_GETDC:
			nRet = (LRESULT)GetDCEx( (HWND)wParam, 0, DCX_CACHE );
			rDef = FALSE;
			break;
		case SAL_MSG_RELEASEDC:
			ReleaseDC( (HWND)wParam, (HDC)lParam );
			rDef = FALSE;
			break;
        case SAL_MSG_POSTTIMER:
			SalTimerProc( 0, 0, SALTIMERPROC_RECURSIVE, lParam );
			break;
	}

	return nRet;
}

LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
{
	int bDef = TRUE;
	LRESULT nRet = 0;
#ifdef __MINGW32__
	jmp_buf jmpbuf;
	__SEHandler han;
	if (__builtin_setjmp(jmpbuf) == 0)
	{
		han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
#else
	__try
	{
#endif
		nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
	}
#ifdef __MINGW32__
	han.Reset();
#else
    __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
	{
	}
#endif
	if ( bDef )
	{
		if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
			nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
	}
	return nRet;
}

LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
{
	int bDef = TRUE;
	LRESULT nRet = 0;
#ifdef __MINGW32__
	jmp_buf jmpbuf;
	__SEHandler han;
	if (__builtin_setjmp(jmpbuf) == 0)
	{
		han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
#else
	__try
	{
#endif
		nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
	}
#ifdef __MINGW32__
	han.Reset();
#else
    __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
	{
	}
#endif
	if ( bDef )
	{
		if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
			nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
	}
	return nRet;
}

// -----------------------------------------------------------------------

bool WinSalInstance::AnyInput( sal_uInt16 nType )
{
	MSG aMsg;

	if ( (nType & (INPUT_ANY)) == (INPUT_ANY) )
	{
		// revert bugfix for #108919# which never reported timeouts when called from the timer handler
		// which made the application completely unresponsive during background formatting
		if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
			return true;
	}
	else
	{
		if ( nType & INPUT_MOUSE )
		{
			// Test for mouse input
			if ( ImplPeekMessage( &aMsg, 0, WM_MOUSEFIRST, WM_MOUSELAST,
								  PM_NOREMOVE | PM_NOYIELD ) )
				return true;
		}

		if ( nType & INPUT_KEYBOARD )
		{
			// Test for key input
			if ( ImplPeekMessage( &aMsg, 0, WM_KEYDOWN, WM_KEYDOWN,
								  PM_NOREMOVE | PM_NOYIELD ) )
			{
				if ( (aMsg.wParam == VK_SHIFT)   ||
					 (aMsg.wParam == VK_CONTROL) ||
					 (aMsg.wParam == VK_MENU) )
					return false;
				else
					return true;
			}
		}

		if ( nType & INPUT_PAINT )
		{
			// Test for paint input
			if ( ImplPeekMessage( &aMsg, 0, WM_PAINT, WM_PAINT,
								  PM_NOREMOVE | PM_NOYIELD ) )
				return true;
			
			if ( ImplPeekMessage( &aMsg, 0, WM_SIZE, WM_SIZE,
								  PM_NOREMOVE | PM_NOYIELD ) )
				return true;

			if ( ImplPeekMessage( &aMsg, 0, SAL_MSG_POSTCALLSIZE, SAL_MSG_POSTCALLSIZE,
								  PM_NOREMOVE | PM_NOYIELD ) )
				return true;

			if ( ImplPeekMessage( &aMsg, 0, WM_MOVE, WM_MOVE,
								  PM_NOREMOVE | PM_NOYIELD ) )
				return true;

			if ( ImplPeekMessage( &aMsg, 0, SAL_MSG_POSTMOVE, SAL_MSG_POSTMOVE,
								  PM_NOREMOVE | PM_NOYIELD ) )
				return true;
		}

		if ( nType & INPUT_TIMER )
		{
			// Test for timer input
			if ( ImplPeekMessage( &aMsg, 0, WM_TIMER, WM_TIMER,
								  PM_NOREMOVE | PM_NOYIELD ) )
				return true;

		}

		if ( nType & INPUT_OTHER )
		{
			// Test for any input
			if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
				return true;
		}
	}

	return FALSE;
}

// -----------------------------------------------------------------------

void SalTimer::Start( sal_uLong nMS )
{
	// Um auf Main-Thread umzuschalten
	SalData* pSalData = GetSalData();
	if ( pSalData->mpFirstInstance )
	{
		if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
			ImplPostMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
		else
			ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
	}
	else
		ImplSalStartTimer( nMS, FALSE );
}

// -----------------------------------------------------------------------

SalFrame* WinSalInstance::CreateChildFrame( SystemParentData* pSystemParentData, sal_uLong nSalFrameStyle )
{
	// Um auf Main-Thread umzuschalten
	return (SalFrame*)ImplSendMessage( mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)pSystemParentData->hWnd );
}

// -----------------------------------------------------------------------

SalFrame* WinSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nSalFrameStyle )
{
	// Um auf Main-Thread umzuschalten
	HWND hWndParent;
	if ( pParent )
		hWndParent = static_cast<WinSalFrame*>(pParent)->mhWnd;
	else
		hWndParent = 0;
	return (SalFrame*)ImplSendMessage( mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)hWndParent );
}

// -----------------------------------------------------------------------

void WinSalInstance::DestroyFrame( SalFrame* pFrame )
{
	ImplSendMessage( mhComWnd, SAL_MSG_DESTROYFRAME, 0, (LPARAM)pFrame );
}

// -----------------------------------------------------------------------

SalObject* WinSalInstance::CreateObject( SalFrame* pParent,
                                         SystemWindowData* /*pWindowData*/, // SystemWindowData meaningless on Windows
                                         sal_Bool /*bShow*/ ) 
{
	// Um auf Main-Thread umzuschalten
	return (SalObject*)ImplSendMessage( mhComWnd, SAL_MSG_CREATEOBJECT, 0, (LPARAM)static_cast<WinSalFrame*>(pParent) );
}

// -----------------------------------------------------------------------

void WinSalInstance::DestroyObject( SalObject* pObject )
{
	ImplSendMessage( mhComWnd, SAL_MSG_DESTROYOBJECT, 0, (LPARAM)pObject );
}

// -----------------------------------------------------------------------

void* WinSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
{
	rReturnedBytes  = 1;
	rReturnedType   = AsciiCString;
	return const_cast<char *>("");
}

// -----------------------------------------------------------------------

/** Add a file to the system shells recent document list if there is any.
      This function may have no effect under Unix because there is no 
      standard API among the different desktop managers.
      
      @param aFileUrl
                The file url of the document.
*/
void WinSalInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& /*rMimeType*/)
{
    rtl::OUString system_path;
    osl::FileBase::RC rc = osl::FileBase::getSystemPathFromFileURL(rFileUrl, system_path);
    
    OSL_ENSURE(osl::FileBase::E_None == rc, "Invalid file url");
    
    if (osl::FileBase::E_None == rc)
        SHAddToRecentDocs(SHARD_PATHW, system_path.getStr());        
}

// -----------------------------------------------------------------------

SalTimer* WinSalInstance::CreateSalTimer()
{
	return new WinSalTimer();
}

// -----------------------------------------------------------------------

SalBitmap* WinSalInstance::CreateSalBitmap()
{
	return new WinSalBitmap();
}

class WinImeStatus : public SalI18NImeStatus
{
  public:
	WinImeStatus() {}
	virtual ~WinImeStatus() {}
	
	// asks whether there is a status window available
	// to toggle into menubar
	virtual bool canToggle() { return false; }
	virtual void toggle() {}
};

SalI18NImeStatus* WinSalInstance::CreateI18NImeStatus()
{
	return new WinImeStatus();
}

// -----------------------------------------------------------------------

const ::rtl::OUString& SalGetDesktopEnvironment()
{
	static ::rtl::OUString aDesktopEnvironment( RTL_CONSTASCII_USTRINGPARAM( "Windows" ) );
	return aDesktopEnvironment;
}

SalSession* WinSalInstance::CreateSalSession()
{
	return NULL;
}

#ifndef __MINGW32__
// -----------------------------------------------------------------------
int WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(int, LPEXCEPTION_POINTERS pExceptionInfo)
{
    // Decide if an exception is a c++ (mostly UNO) exception or a process violation.
    // Depending on this information we pass process violations directly to our signal handler ...
    // and c++ (UNO) exceptions are sended to the following code on the current stack.
    // Problem behind: user32.dll sometime consumes exceptions/process violations .-)
    // see also #112221#

    static DWORD EXCEPTION_MSC_CPP_EXCEPTION = 0xE06D7363;

    if (pExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_MSC_CPP_EXCEPTION)
        return EXCEPTION_CONTINUE_SEARCH;

    return UnhandledExceptionFilter( pExceptionInfo );
}
#endif
