xref: /aoo41x/main/vcl/os2/source/app/salinst.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #define INCL_DOSMISC
29 #define INCL_DOSMODULEMGR
30 #define INCL_DOSPROCESS
31 
32 #include <string.h>
33 #include <svpm.h>
34 #include <process.h>
35 
36 #define _SV_SALINST_CXX
37 
38 #ifndef _VOS_MUTEX_HXX
39 #include <vos/mutex.hxx>
40 #endif
41 #include <tools/debug.hxx>
42 
43 #ifndef _SV_SALIDS_HRC
44 #include <salids.hrc>
45 #endif
46 #include <vcl/apptypes.hxx>
47 #include <saldata.hxx>
48 #include <salinst.h>
49 #include <salframe.h>
50 #include <salobj.h>
51 #include <saltimer.h>
52 #include <salbmp.h>
53 #include <vcl/salimestatus.hxx>
54 #include <vcl/timer.hxx>
55 #include <tools/solarmutex.hxx>
56 
57 // =======================================================================
58 
59 void SalAbort( const XubString& rErrorText )
60 {
61 	ImplFreeSalGDI();
62 
63 	if( !rErrorText.Len() )
64 		fprintf( stderr, "Application Error " );
65 	else
66 		fprintf( stderr, "%s ",
67 			ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
68 	abort();
69 }
70 
71 // =======================================================================
72 
73 ULONG GetCurrentThreadId()
74 {
75 	PTIB pptib = NULL;
76 	PPIB pppib = NULL;
77 
78 	DosGetInfoBlocks( &pptib, &pppib );
79 	return pptib->tib_ptib2->tib2_ultid;
80 }
81 
82 // =======================================================================
83 
84 MRESULT EXPENTRY SalComWndProc( HWND hWnd, ULONG nMsg, MPARAM nMP1, MPARAM nMP2 );
85 
86 // =======================================================================
87 
88 class SalYieldMutex : public vos::OMutex
89 {
90 public:
91 	Os2SalInstance*			mpInstData;
92 	ULONG					mnCount;
93 	ULONG					mnThreadId;
94 
95 public:
96 							SalYieldMutex( Os2SalInstance* pInstData );
97 
98 	virtual void SAL_CALL       acquire();
99 	virtual void SAL_CALL       release();
100 	virtual sal_Bool SAL_CALL   tryToAcquire();
101 
102 	ULONG					GetAcquireCount( ULONG nThreadId );
103 };
104 
105 // -----------------------------------------------------------------------
106 
107 SalYieldMutex::SalYieldMutex( Os2SalInstance* pInstData )
108 {
109 	mpInstData	= pInstData;
110 	mnCount 	= 0;
111 	mnThreadId	= 0;
112 }
113 
114 // -----------------------------------------------------------------------
115 
116 void SalYieldMutex::acquire()
117 {
118 	OMutex::acquire();
119 	mnCount++;
120 	mnThreadId = GetCurrentThreadId();
121 }
122 
123 // -----------------------------------------------------------------------
124 
125 void SalYieldMutex::release()
126 {
127 	ULONG nThreadId = GetCurrentThreadId();
128 	if ( mnThreadId != nThreadId )
129 		OMutex::release();
130 	else
131 	{
132 		SalData* pSalData = GetSalData();
133 		if ( pSalData->mnAppThreadId != nThreadId )
134 		{
135 			if ( mnCount == 1 )
136 			{
137                 mpInstData->mpSalWaitMutex->acquire();
138 				if ( mpInstData->mnYieldWaitCount )
139 					WinPostMsg( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
140 				mnThreadId = 0;
141                 mnCount--;
142                 OMutex::release();
143                 mpInstData->mpSalWaitMutex->release();
144             }
145             else
146             {
147                 mnCount--;
148                 OMutex::release();
149             }
150 		}
151 		else
152 		{
153 			if ( mnCount == 1 )
154 				mnThreadId = 0;
155 			mnCount--;
156 			OMutex::release();
157 		}
158 	}
159 }
160 
161 // -----------------------------------------------------------------------
162 
163 sal_Bool SalYieldMutex::tryToAcquire()
164 {
165 	if ( OMutex::tryToAcquire() )
166 	{
167 		mnCount++;
168 		mnThreadId = GetCurrentThreadId();
169 		return sal_True;
170 	}
171 	else
172 		return sal_False;
173 }
174 
175 // -----------------------------------------------------------------------
176 
177 ULONG SalYieldMutex::GetAcquireCount( ULONG nThreadId )
178 {
179 	if ( nThreadId == mnThreadId )
180 		return mnCount;
181 	else
182 		return 0;
183 }
184 
185 // -----------------------------------------------------------------------
186 
187 void ImplSalYieldMutexAcquireWithWait()
188 {
189     Os2SalInstance* pInst = GetSalData()->mpFirstInstance;
190     if ( !pInst )
191         return;
192 
193     // If we are the main thread, then we must wait with wait, because
194     // in if we don't reschedule, then we create deadlocks if a Windows
195     // Function is called from another thread. If we arn't the main thread,
196     // than we call qcquire directly.
197     ULONG nThreadId = GetCurrentThreadId();
198     SalData* pSalData = GetSalData();
199     if ( pSalData->mnAppThreadId == nThreadId )
200     {
201         // Wenn wir den Mutex nicht bekommen, muessen wir solange
202         // warten, bis wir Ihn bekommen
203         BOOL bAcquire = FALSE;
204         do
205         {
206             if ( pInst->mpSalYieldMutex->tryToAcquire() )
207                 bAcquire = TRUE;
208             else
209             {
210                 pInst->mpSalWaitMutex->acquire();
211                 if ( pInst->mpSalYieldMutex->tryToAcquire() )
212                 {
213                     bAcquire = TRUE;
214                     pInst->mpSalWaitMutex->release();
215                 }
216                 else
217                 {
218                     pInst->mnYieldWaitCount++;
219                     pInst->mpSalWaitMutex->release();
220 					QMSG aTmpMsg;
221 					WinGetMsg( pSalData->mhAB, &aTmpMsg, pInst->mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
222                     pInst->mnYieldWaitCount--;
223                     if ( pInst->mnYieldWaitCount )
224 						WinPostMsg( pInst->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0 , 0 );
225                 }
226             }
227         }
228         while ( !bAcquire );
229     }
230     else
231         pInst->mpSalYieldMutex->acquire();
232 }
233 
234 // -----------------------------------------------------------------------
235 
236 BOOL ImplSalYieldMutexTryToAcquire()
237 {
238     Os2SalInstance* pInst = GetSalData()->mpFirstInstance;
239     if ( pInst )
240         return pInst->mpSalYieldMutex->tryToAcquire();
241     else
242         return FALSE;
243 }
244 
245 // -----------------------------------------------------------------------
246 
247 void ImplSalYieldMutexAcquire()
248 {
249     Os2SalInstance* pInst = GetSalData()->mpFirstInstance;
250     if ( pInst )
251         pInst->mpSalYieldMutex->acquire();
252 }
253 
254 // -----------------------------------------------------------------------
255 
256 void ImplSalYieldMutexRelease()
257 {
258     Os2SalInstance* pInst = GetSalData()->mpFirstInstance;
259     if ( pInst )
260         pInst->mpSalYieldMutex->release();
261 }
262 
263 // -----------------------------------------------------------------------
264 
265 ULONG ImplSalReleaseYieldMutex()
266 {
267     Os2SalInstance* pInst = GetSalData()->mpFirstInstance;
268     if ( !pInst )
269         return 0;
270 
271     SalYieldMutex*  pYieldMutex = pInst->mpSalYieldMutex;
272     ULONG           nCount = pYieldMutex->GetAcquireCount( GetCurrentThreadId() );
273     ULONG           n = nCount;
274     while ( n )
275     {
276         pYieldMutex->release();
277         n--;
278     }
279 
280     return nCount;
281 }
282 
283 // -----------------------------------------------------------------------
284 
285 void ImplSalAcquireYieldMutex( ULONG nCount )
286 {
287     Os2SalInstance* pInst = GetSalData()->mpFirstInstance;
288     if ( !pInst )
289         return;
290 
291     SalYieldMutex*  pYieldMutex = pInst->mpSalYieldMutex;
292     while ( nCount )
293     {
294         pYieldMutex->acquire();
295         nCount--;
296     }
297 }
298 
299 // -----------------------------------------------------------------------
300 
301 bool Os2SalInstance::CheckYieldMutex()
302 {
303     bool bRet = true;
304 	SalData*	pSalData = GetSalData();
305 	ULONG		nCurThreadId = GetCurrentThreadId();
306 	if ( pSalData->mnAppThreadId != nCurThreadId )
307 	{
308 		if ( pSalData->mpFirstInstance )
309 		{
310             SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex;
311 			if ( pYieldMutex->mnThreadId != nCurThreadId )
312 			{
313 				bRet = false;
314 			}
315 		}
316 	}
317 	else
318 	{
319 		if ( pSalData->mpFirstInstance )
320 		{
321             SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex;
322 			if ( pYieldMutex->mnThreadId != nCurThreadId )
323 			{
324 				bRet = false;
325 			}
326 		}
327 	}
328 	return bRet;
329 }
330 
331 // =======================================================================
332 
333 void InitSalData()
334 {
335 	SalData* pSalData = new SalData;
336 	memset( pSalData, 0, sizeof( SalData ) );
337 	SetSalData( pSalData );
338 }
339 
340 // -----------------------------------------------------------------------
341 
342 void DeInitSalData()
343 {
344 	SalData* pSalData = GetSalData();
345 	if ( pSalData->mpFontMetrics )
346 		delete pSalData->mpFontMetrics;
347 	delete pSalData;
348 	SetSalData( NULL );
349 }
350 
351 // -----------------------------------------------------------------------
352 
353 void InitSalMain()
354 {
355 	PPIB pib;
356 	PTIB tib;
357 	HAB hAB;
358 	HMQ hMQ;
359 	SalData* pData = GetAppSalData();
360 #if OSL_DEBUG_LEVEL>0
361 printf("InitSalMain\n");
362 #endif
363 
364 	// morph application to PM
365 	DosGetInfoBlocks(&tib, &pib);
366 	// Change flag from VIO to PM:
367 	if (pib->pib_ultype==2) pib->pib_ultype = 3;
368 
369 	// create anchor block
370 	hAB = WinInitialize( 0 );
371 	if ( !hAB )
372 		return;
373 
374 	// create message queue
375 	hMQ = WinCreateMsgQueue( hAB, 60 );
376 	if ( !hMQ )
377 	{
378 		WinTerminate( hAB );
379 		return;
380 	}
381 
382 	if ( pData ) // Im AppServer NULL
383 	{
384 		// Ankerblock und Messagequeue merken
385 		pData->mhAB = hAB;
386 		pData->mhMQ = hMQ;
387 	}
388 
389 }
390 
391 void DeInitSalMain()
392 {
393 #if OSL_DEBUG_LEVEL>0
394 printf("DeInitSalMain\n");
395 #endif
396 
397 	SalData* pData = GetAppSalData();
398 	// destroy message queue and anchor block
399 	WinDestroyMsgQueue( pData->mhMQ );
400 	WinTerminate( pData->mhAB );
401 
402 }
403 
404 // -----------------------------------------------------------------------
405 
406 SalInstance* CreateSalInstance()
407 {
408 	SalData*		pSalData = GetSalData();
409 
410 	// determine the os2 version
411 	ULONG nMayor;
412 	ULONG nMinor;
413 	DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MAJOR, &nMayor, sizeof( nMayor ) );
414 	DosQuerySysInfo( QSV_VERSION_MINOR, QSV_VERSION_MINOR, &nMinor, sizeof( nMinor ) );
415 	aSalShlData.mnVersion = (USHORT)(nMayor*10 + nMinor);
416 
417 	pSalData->mnAppThreadId = GetCurrentThreadId();
418 
419 	// register frame class
420 	if ( !WinRegisterClass( pSalData->mhAB, (PSZ)SAL_FRAME_CLASSNAME,
421 							(PFNWP)SalFrameWndProc, CS_MOVENOTIFY /* 17/08 CS_HITTEST | CS_MOVENOTIFY */,
422 							SAL_FRAME_WNDEXTRA ) )
423 	{
424 		return NULL;
425 	}
426 	// register subframe class
427 	if ( !WinRegisterClass( pSalData->mhAB, (PSZ)SAL_SUBFRAME_CLASSNAME,
428 							(PFNWP)SalFrameWndProc, CS_SAVEBITS| CS_MOVENOTIFY,
429 							SAL_FRAME_WNDEXTRA ) )
430 	{
431 		return NULL;
432 	}
433 	// register object class
434 	if ( !WinRegisterClass( pSalData->mhAB, (PSZ)SAL_COM_CLASSNAME,
435 							(PFNWP)SalComWndProc, 0, 0 ))
436 	{
437 		return NULL;
438 	}
439 
440 	HWND hComWnd = WinCreateWindow( HWND_OBJECT, (PCSZ)SAL_COM_CLASSNAME,
441 									(PCSZ)"", 0, 0, 0, 0, 0,
442 									HWND_OBJECT, HWND_TOP,
443 									222, NULL, NULL);
444     if ( !hComWnd )
445         return NULL;
446 
447 #if OSL_DEBUG_LEVEL>0
448 	debug_printf("CreateSalInstance hComWnd %x\n", hComWnd);
449 #endif
450     Os2SalInstance* pInst = new Os2SalInstance;
451 
452 	// init instance (only one instance in this version !!!)
453 	pSalData->mpFirstInstance	= pInst;
454 	pInst->mhAB		= pSalData->mhAB;
455 	pInst->mhMQ		= pSalData->mhMQ;
456 	pInst->mnArgc	= pSalData->mnArgc;
457 	pInst->mpArgv	= pSalData->mpArgv;
458 	pInst->mhComWnd	= hComWnd;
459 
460 	// AppIcon ermitteln
461 	ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, pInst->mhAppIcon);
462 
463 	// init static GDI Data
464 	ImplInitSalGDI();
465 
466 	return pInst;
467 }
468 
469 // -----------------------------------------------------------------------
470 
471 void DestroySalInstance( SalInstance* pInst )
472 {
473 	SalData* pSalData = GetSalData();
474 
475 	//	(only one instance in this version !!!)
476 	ImplFreeSalGDI();
477 
478 #ifdef ENABLE_IME
479 	// IME-Daten freigeben
480 	if ( pSalData->mpIMEData )
481 		ImplReleaseSALIMEData();
482 #endif
483 
484 	// reset instance
485 	if ( pSalData->mpFirstInstance == pInst )
486 		pSalData->mpFirstInstance = NULL;
487 
488 	delete pInst;
489 }
490 
491 // -----------------------------------------------------------------------
492 
493 Os2SalInstance::Os2SalInstance()
494 {
495 	mhComWnd				= 0;
496 	mpSalYieldMutex			= new SalYieldMutex( this );
497 	mpSalWaitMutex			= new vos::OMutex;
498     mnYieldWaitCount         = 0;
499 	mpSalYieldMutex->acquire();
500 	::tools::SolarMutex::SetSolarMutex( mpSalYieldMutex );
501 }
502 
503 // -----------------------------------------------------------------------
504 
505 Os2SalInstance::~Os2SalInstance()
506 {
507 	::tools::SolarMutex::SetSolarMutex( 0 );
508 	mpSalYieldMutex->release();
509 	delete mpSalYieldMutex;
510 	delete mpSalWaitMutex;
511 	WinDestroyWindow( mhComWnd);
512 }
513 
514 // -----------------------------------------------------------------------
515 
516 vos::IMutex* Os2SalInstance::GetYieldMutex()
517 {
518     return mpSalYieldMutex;
519 }
520 // -----------------------------------------------------------------------
521 
522 ULONG Os2SalInstance::ReleaseYieldMutex()
523 {
524     return ImplSalReleaseYieldMutex();
525 }
526 
527 // -----------------------------------------------------------------------
528 
529 void Os2SalInstance::AcquireYieldMutex( ULONG nCount )
530 {
531     ImplSalAcquireYieldMutex( nCount );
532 }
533 
534 // -----------------------------------------------------------------------
535 
536 static void ImplSalYield( BOOL bWait, BOOL bHandleAllCurrentEvents )
537 {
538 	QMSG			aMsg;
539 	bool bWasMsg = false, bOneEvent = false;
540 	bool bQuit = false;
541 
542     Os2SalInstance* pInst = GetSalData()->mpFirstInstance;
543     int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1;
544     do
545     {
546         if ( WinPeekMsg( pInst->mhAB, &aMsg, 0, 0, 0, PM_REMOVE ) )
547         {
548 			WinDispatchMsg( pInst->mhAB, &aMsg );
549 			bOneEvent = bWasMsg = true;
550 			if (aMsg.msg == WM_QUIT)
551 				bQuit = true;
552         }
553         else
554             bOneEvent = false;
555     } while( --nMaxEvents && bOneEvent );
556 
557 	if ( bWait && ! bWasMsg )
558 	{
559 		if ( WinGetMsg( pInst->mhAB, &aMsg, 0, 0, 0 ) )
560 			WinDispatchMsg( pInst->mhAB, &aMsg );
561 		else
562 			bQuit = true;
563 	}
564 
565 	if (bQuit)
566 	{
567 		ImplSalYieldMutexAcquireWithWait();
568 		Os2SalFrame*   pFrame = GetSalData()->mpFirstFrame;
569 		if ( pFrame )
570 		{
571 			if (pFrame->CallCallback( SALEVENT_SHUTDOWN, 0 ))
572 				WinCancelShutdown( pFrame->mhAB, FALSE );
573 		}
574 		ImplSalYieldMutexRelease();
575 	}
576 
577 }
578 
579 // -----------------------------------------------------------------------
580 
581 void Os2SalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
582 {
583 	SalYieldMutex*	pYieldMutex = mpSalYieldMutex;
584 	SalData*		pSalData = GetSalData();
585 	ULONG			nCurThreadId = GetCurrentThreadId();
586 	ULONG			nCount = pYieldMutex->GetAcquireCount( nCurThreadId );
587 	ULONG			n = nCount;
588 	while ( n )
589 	{
590 		pYieldMutex->release();
591 		n--;
592 	}
593 	if ( pSalData->mnAppThreadId != nCurThreadId )
594 	{
595 		// #97739# A SendMessage call blocks until the called thread (here: the main thread)
596 		// returns. During a yield however, messages are processed in the main thread that might
597 		// result in a new message loop due to opening a dialog. Thus, SendMessage would not
598 		// return which will block this thread!
599 		// Solution: just give up the time slice and hope that messages are processed
600 		// by the main thread anyway (where all windows are created)
601 		// If the mainthread is not currently handling messages, then our SendMessage would
602 		// also do nothing, so this seems to be reasonable.
603 
604         // #i18883# only sleep if potential deadlock scenario, ie, when a dialog is open
605         if( ImplGetSVData()->maAppData.mnModalMode )
606             DosSleep(1);
607         else
608 			WinSendMsg( mhComWnd, SAL_MSG_THREADYIELD, (MPARAM)bWait, (MPARAM)bHandleAllCurrentEvents );
609 
610 		n = nCount;
611 		while ( n )
612 		{
613 			pYieldMutex->acquire();
614 			n--;
615 		}
616 	}
617 	else
618 	{
619 		ImplSalYield( bWait, bHandleAllCurrentEvents );
620 
621 		n = nCount;
622 		while ( n )
623 		{
624             ImplSalYieldMutexAcquireWithWait();
625             n--;
626 		}
627 	}
628 }
629 
630 // -----------------------------------------------------------------------
631 
632 MRESULT EXPENTRY SalComWndProc( HWND hWnd, ULONG nMsg,
633 								MPARAM nMP1, MPARAM nMP2 )
634 {
635 	//debug_printf( "SalComWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg);
636 
637 	switch ( nMsg )
638 	{
639         case SAL_MSG_PRINTABORTJOB:
640             //ImplSalPrinterAbortJobAsync( (HDC)wParam );
641             break;
642 		case SAL_MSG_THREADYIELD:
643 			ImplSalYield( (bool)nMP1, (bool) nMP2);
644 			return 0;
645         // If we get this message, because another GetMessage() call
646         // has recieved this message, we must post this message to
647         // us again, because in the other case we wait forever.
648         case SAL_MSG_RELEASEWAITYIELD:
649             {
650             Os2SalInstance* pInst = GetSalData()->mpFirstInstance;
651             if ( pInst && pInst->mnYieldWaitCount )
652                 WinPostMsg( hWnd, SAL_MSG_RELEASEWAITYIELD, nMP1, nMP2 );
653             }
654             return 0;
655 		case SAL_MSG_STARTTIMER:
656 			ImplSalStartTimer( (ULONG)nMP2, FALSE);
657 			return 0;
658 		case SAL_MSG_CREATEFRAME:
659 			return (MRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (HWND)nMP2, (ULONG)nMP1 );
660         case SAL_MSG_DESTROYFRAME:
661             delete (SalFrame*)nMP2;
662             return 0;
663         case SAL_MSG_DESTROYHWND:
664             //We only destroy the native window here. We do NOT destroy the SalFrame contained
665 			//in the structure (GetWindowPtr()).
666 			if (WinDestroyWindow((HWND)nMP2) == 0)
667 			{
668 				OSL_ENSURE(0, "DestroyWindow failed!");
669 				//Failure: We remove the SalFrame from the window structure. So we avoid that
670 				// the window structure may contain an invalid pointer, once the SalFrame is deleted.
671 	           SetWindowPtr((HWND)nMP2, 0);
672 			}
673 			return 0;
674 		case SAL_MSG_CREATEOBJECT:
675 			return (MRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (Os2SalFrame*)(ULONG)nMP2 );
676         case SAL_MSG_DESTROYOBJECT:
677             delete (SalObject*)nMP2;
678 			return 0;
679         case SAL_MSG_CREATESOUND:
680             //return (MRESULT)((Os2SalSound*)nMP2)->ImplCreate();
681 			return 0;
682         case SAL_MSG_DESTROYSOUND:
683             //((Os2SalSound*)nMP2)->ImplDestroy();
684 			return 0;
685         case SAL_MSG_POSTTIMER:
686 			SalTimerProc( 0, 0, SALTIMERPROC_RECURSIVE, (ULONG)nMP2 );
687 			break;
688         case WM_TIMER:
689 			SalTimerProc( hWnd, 0, 0, 0 );
690             break;
691 	}
692 
693 	return WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
694 }
695 
696 // -----------------------------------------------------------------------
697 
698 bool Os2SalInstance::AnyInput( USHORT nType )
699 {
700 	SalData* pSalData = GetSalData();
701 	QMSG	aQMSG;
702 
703 	if ( (nType & (INPUT_ANY)) == INPUT_ANY )
704 	{
705 		// Any Input
706 		if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0, 0, 0, PM_NOREMOVE ) )
707 			return TRUE;
708 	}
709 	else
710 	{
711 		if ( nType & INPUT_MOUSE )
712 		{
713 			// Test auf Mouseinput
714 			if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
715 							 WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE ) )
716 				return TRUE;
717 		}
718 
719 		if ( nType & INPUT_KEYBOARD )
720 		{
721 			// Test auf Keyinput
722 			if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
723 							 WM_CHAR, WM_CHAR, PM_NOREMOVE ) )
724 				return !(SHORT1FROMMP( aQMSG.mp1 ) & KC_KEYUP);
725 		}
726 
727 		if ( nType & INPUT_PAINT )
728 		{
729 			// Test auf Paintinput
730 			if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
731 							 WM_PAINT, WM_PAINT, PM_NOREMOVE ) )
732 				return TRUE;
733 		}
734 
735 		if ( nType & INPUT_TIMER )
736 		{
737 			// Test auf Timerinput
738 			if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
739 							 WM_TIMER, WM_TIMER, PM_NOREMOVE ) )
740 				return TRUE;
741 		}
742 
743 		if ( nType & INPUT_OTHER )
744 		{
745 			// Test auf sonstigen Input
746 			if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0, 0, 0, PM_NOREMOVE ) )
747 				return TRUE;
748 		}
749 	}
750 
751 	return FALSE;
752 }
753 
754 // -----------------------------------------------------------------------
755 
756 SalFrame* Os2SalInstance::CreateChildFrame( SystemParentData* pSystemParentData, ULONG nSalFrameStyle )
757 {
758     // Um auf Main-Thread umzuschalten
759     return (SalFrame*)WinSendMsg( mhComWnd, SAL_MSG_CREATEFRAME, (MPARAM)nSalFrameStyle, (MPARAM)pSystemParentData->hWnd );
760 }
761 
762 // -----------------------------------------------------------------------
763 
764 SalFrame* Os2SalInstance::CreateFrame( SalFrame* pParent, ULONG nSalFrameStyle )
765 {
766     // Um auf Main-Thread umzuschalten
767     HWND mhWndClient;
768 //31/05/06 YD use client as owner(parent) so positioning will not need to
769 // take care of borders and captions
770     if ( pParent )
771         mhWndClient = static_cast<Os2SalFrame*>(pParent)->mhWndClient;
772     else
773         mhWndClient = 0;
774     return (SalFrame*)WinSendMsg( mhComWnd, SAL_MSG_CREATEFRAME, (MPARAM)nSalFrameStyle, (MPARAM)mhWndClient );
775 }
776 
777 
778 // -----------------------------------------------------------------------
779 
780 void Os2SalInstance::DestroyFrame( SalFrame* pFrame )
781 {
782     WinSendMsg( mhComWnd, SAL_MSG_DESTROYFRAME, 0, (MPARAM)pFrame );
783 }
784 
785 // -----------------------------------------------------------------------
786 
787 SalObject* Os2SalInstance::CreateObject( SalFrame* pParent,
788                                          SystemWindowData* /*pWindowData*/, // SystemWindowData meaningless on Windows
789                                          BOOL /*bShow*/ )
790 {
791 	// Um auf Main-Thread umzuschalten
792 	return (SalObject*)WinSendMsg( mhComWnd, SAL_MSG_CREATEOBJECT, 0, (MPARAM)pParent );
793 }
794 
795 
796 // -----------------------------------------------------------------------
797 
798 void Os2SalInstance::DestroyObject( SalObject* pObject )
799 {
800     WinSendMsg( mhComWnd, SAL_MSG_DESTROYOBJECT, 0, (MPARAM)pObject );
801 }
802 
803 // -----------------------------------------------------------------------
804 
805 void* Os2SalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
806 {
807 	rReturnedBytes	= 1;
808 	rReturnedType	= AsciiCString;
809 	return (void*) "";
810 }
811 
812 void Os2SalInstance::AddToRecentDocumentList(const rtl::OUString& /*rFileUrl*/, const rtl::OUString& /*rMimeType*/)
813 {
814 }
815 
816 // -----------------------------------------------------------------------
817 
818 SalTimer* Os2SalInstance::CreateSalTimer()
819 {
820     return new Os2SalTimer();
821 }
822 
823 // -----------------------------------------------------------------------
824 
825 SalBitmap* Os2SalInstance::CreateSalBitmap()
826 {
827     return new Os2SalBitmap();
828 }
829 
830 // -----------------------------------------------------------------------
831 
832 class Os2ImeStatus : public SalI18NImeStatus
833 {
834   public:
835     Os2ImeStatus() {}
836     virtual ~Os2ImeStatus() {}
837 
838     // asks whether there is a status window available
839     // to toggle into menubar
840     virtual bool canToggle() { return false; }
841     virtual void toggle() {}
842 };
843 
844 SalI18NImeStatus* Os2SalInstance::CreateI18NImeStatus()
845 {
846     return new Os2ImeStatus();
847 }
848 
849 // -----------------------------------------------------------------------
850 
851 const ::rtl::OUString& SalGetDesktopEnvironment()
852 {
853     static ::rtl::OUString aDesktopEnvironment( RTL_CONSTASCII_USTRINGPARAM( "OS/2" ) );
854     return aDesktopEnvironment;
855 }
856 
857 SalSession* Os2SalInstance::CreateSalSession()
858 {
859     return NULL;
860 }
861 
862