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