xref: /trunk/main/vcl/os2/source/window/salframe.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 #include <string.h>
29 
30 #define INCL_DOS
31 #define INCL_PM
32 #define INCL_WIN
33 #include <svpm.h>
34 
35 // =======================================================================
36 
37 #define _SV_SALFRAME_CXX
38 
39 #ifndef DEBUG_HXX
40 #include <tools/debug.hxx>
41 #endif
42 
43 #define private public
44 
45 #ifndef _SV_SALLANG_HXX
46 #include <sallang.hxx>
47 #endif
48 #ifndef _SV_SALIDS_HRC
49 #include <salids.hrc>
50 #endif
51 #include <saldata.hxx>
52 #include <salinst.h>
53 #include <salgdi.h>
54 #include <salframe.h>
55 #include <vcl/timer.hxx>
56 #include <vcl/settings.hxx>
57 #ifndef _SV_KEYCOES_HXX
58 #include <vcl/keycodes.hxx>
59 #endif
60 #include <saltimer.h>
61 
62 #if OSL_DEBUG_LEVEL>10
63 extern "C" int debug_printf(const char *f, ...);
64 
65 static BOOL _bCapture;
66 
67 #else
68 #define debug_printf( ...) { 1; }
69 #endif
70 
71 // =======================================================================
72 
73 HPOINTER ImplLoadPointer( ULONG nId );
74 
75 static void SetMaximizedFrameGeometry( HWND hWnd, Os2SalFrame* pFrame );
76 static void UpdateFrameGeometry( HWND hWnd, Os2SalFrame* pFrame );
77 static void ImplSalCalcFrameSize( HWND hWnd,
78                                   LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY );
79 static void ImplSalCalcFrameSize( const Os2SalFrame* pFrame,
80                                   LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY );
81 MRESULT EXPENTRY SalFrameSubClassWndProc( HWND hWnd, ULONG nMsg,
82                                   MPARAM nMP1, MPARAM nMP2 );
83 
84 // =======================================================================
85 
86 static LanguageType eImplKeyboardLanguage = LANGUAGE_DONTKNOW;
87 BOOL Os2SalFrame::mbInReparent = FALSE;
88 ULONG Os2SalFrame::mnInputLang = 0;
89 
90 // =======================================================================
91 
92 // define a new flag
93 #define SWP_CENTER			(SWP_NOAUTOCLOSE<<4)
94 #define SWP_SHOWMAXIMIZED	(SWP_ACTIVATE | SWP_SHOW | SWP_MAXIMIZE)
95 #define SWP_SHOWMINIMIZED	(SWP_ACTIVATE | SWP_SHOW | SWP_MINIMIZE)
96 #define SWP_SHOWNORMAL		(SWP_ACTIVATE | SWP_SHOW | SWP_RESTORE)
97 
98 static LONG nScreenHeight  = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN);
99 static LONG nScreenWidth   = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
100 
101 BOOL APIENTRY _WinQueryWindowRect( HWND hwnd, PRECTL prclDest)
102 {
103 	BOOL rc = WinQueryWindowRect( hwnd, prclDest);
104 	ULONG tmp = prclDest->yBottom;
105 	prclDest->yBottom = prclDest->yTop;
106 	prclDest->yTop = tmp;
107 	return rc;
108 }
109 
110 BOOL APIENTRY _WinQueryPointerPos (HWND hwndDesktop, PPOINTL pptl)
111 {
112 	BOOL rc = WinQueryPointerPos( hwndDesktop, pptl);
113 	pptl->y = nScreenHeight - pptl->y;
114 	return rc;
115 }
116 
117 BOOL APIENTRY _WinQueryWindowPos( Os2SalFrame* pFrame, PSWP pswp)
118 {
119 	SWP swpOwner;
120 	BOOL rc = WinQueryWindowPos( pFrame->mhWndFrame, pswp);
121 
122 #if OSL_DEBUG_LEVEL>1
123 	debug_printf( "> WinQueryWindowPos hwnd %x at %d,%d (%dx%d)\n",
124 					pFrame->mhWndFrame, pswp->x, pswp->y, pswp->cx, pswp->cy);
125 #endif
126 
127 	Os2SalFrame* pParentFrame = pFrame->mpParentFrame;
128 
129 	//YD adjust to owner coordinates
130 	if ( pParentFrame )
131 	{
132 		POINTL ptlOwner = {0};
133 
134 		// coords are relative to screen, map to parent frame client area
135 		ptlOwner.x = pswp->x;
136 		ptlOwner.y = pswp->y;
137 		WinMapWindowPoints( HWND_DESKTOP, pParentFrame->mhWndClient, &ptlOwner, 1);
138 		pswp->x = ptlOwner.x;
139 		pswp->y = ptlOwner.y;
140 		// get parent client area size
141 		WinQueryWindowPos( pParentFrame->mhWndClient, &swpOwner);
142 	} else
143 	{
144 		// no owner info, use DESKTOP????
145 		swpOwner.cx = nScreenWidth;
146 		swpOwner.cy = nScreenHeight;
147 	}
148 
149 	// invert Y coordinate
150 	pswp->y = swpOwner.cy - (pswp->y + pswp->cy);
151 
152 #if OSL_DEBUG_LEVEL>1
153 	debug_printf( "< WinQueryWindowPos hwnd %x at %d,%d (%dx%d)\n",
154 					pFrame->mhWndFrame, pswp->x, pswp->y, pswp->cx, pswp->cy);
155 #endif
156 	return rc;
157 }
158 
159 BOOL APIENTRY _WinSetWindowPos( Os2SalFrame* pFrame, HWND hwndInsertBehind, LONG x, LONG y,
160     LONG cx, LONG cy, ULONG fl)
161 {
162 	SWP 	swpOwner = {0};
163 	POINTL 	ptlOwner = {0};
164 	HWND	hParent = NULL;
165 
166 #if OSL_DEBUG_LEVEL>1
167 	debug_printf( ">WinSetWindowPos hwnd %x at %d,%d (%dx%d) fl 0x%08x\n",
168 					pFrame->mhWndFrame, x, y, cx, cy, fl);
169 #endif
170 
171 	// first resize window if requested
172 	if ( (fl & SWP_SIZE) ) {
173 		ULONG	flag = SWP_SIZE;
174 		LONG	nX = 0, nY = 0;
175 		LONG	frameFrameX, frameFrameY, frameCaptionY;
176 
177 		ImplSalCalcFrameSize( pFrame, frameFrameX, frameFrameY, frameCaptionY );
178 		// if we change y size, we need to move the window down
179 		// because os2 window origin is lower left corner
180 		if (pFrame->maGeometry.nHeight != cy) {
181 			SWP		aSWP;
182 			WinQueryWindowPos( pFrame->mhWndFrame, &aSWP);
183 			nX = aSWP.x;
184 			nY = aSWP.y - (cy + 2*frameFrameY + frameCaptionY - aSWP.cy);
185 			flag |= SWP_MOVE;
186 		}
187 		WinSetWindowPos( pFrame->mhWndFrame, NULL, nX, nY,
188 			cx+2*frameFrameX, cy+2*frameFrameY+frameCaptionY, flag);
189 		fl = fl & ~SWP_SIZE;
190 	}
191 	else // otherwise get current size
192 	{
193 		SWP swp = {0};
194 		WinQueryWindowPos( pFrame->mhWndClient, &swp);
195 		cx = swp.cx;
196 		cy = swp.cy;
197 	}
198 
199 	// get parent window handle
200 	Os2SalFrame* pParentFrame = pFrame->mpParentFrame;
201 
202 	// use desktop if parent is not defined
203 	hParent = pParentFrame ? pParentFrame->mhWndClient : HWND_DESKTOP;
204 	// if parent is not visible, use desktop as reference
205 	hParent = WinIsWindowVisible( hParent) ? hParent : HWND_DESKTOP;
206 
207 	WinQueryWindowPos( hParent, &swpOwner);
208 
209 	//YD adjust to owner coordinates only when moving and not centering
210 	//if (!(fl & SWP_CENTER) && (fl & SWP_MOVE))
211 	if ((fl & SWP_MOVE))
212 	{
213 
214 		// if SWP_CENTER is specified, change position to parent center
215 		if (fl & SWP_CENTER) {
216 			ptlOwner.x = (swpOwner.cx - cx) / 2;
217 			ptlOwner.y = (swpOwner.cy - cy) / 2;
218 #if OSL_DEBUG_LEVEL>0
219 			debug_printf( "_WinSetWindowPos SWP_CENTER\n");
220 #endif
221 			fl = fl & ~SWP_CENTER;
222 		} else {
223 			// coords are relative to parent frame client area, map to screen
224 			// map Y to OS/2 system coordinates
225 			ptlOwner.x = x;
226 			ptlOwner.y = swpOwner.cy - (y + cy);
227 
228 #if OSL_DEBUG_LEVEL>0
229 			debug_printf( "_WinSetWindowPos owner 0x%x at %d,%d (%dx%d) OS2\n",
230 				hParent, ptlOwner.x, ptlOwner.y, swpOwner.cx, swpOwner.cy);
231 #endif
232 		}
233 		// map from client area to screen
234 		WinMapWindowPoints( hParent, HWND_DESKTOP, &ptlOwner, 1);
235 		x = ptlOwner.x;
236 		y = ptlOwner.y;
237 
238 #if OSL_DEBUG_LEVEL>0
239 		debug_printf( "_WinSetWindowPos owner 0x%x at %d,%d (%dx%d) MAPPED OS2\n",
240 			hParent, ptlOwner.x, ptlOwner.y, swpOwner.cx, swpOwner.cy);
241 #endif
242 	}
243 
244 #if OSL_DEBUG_LEVEL>0
245 	debug_printf( "<WinSetWindowPos hwnd %x at %d,%d (%dx%d) fl=%x\n",
246 					pFrame->mhWndFrame, x, y, cx, cy, fl);
247 #endif
248 	return WinSetWindowPos( pFrame->mhWndFrame, hwndInsertBehind, x, y, 0, 0, fl);
249 }
250 
251 // =======================================================================
252 
253 #if OSL_DEBUG_LEVEL > 0
254 static void dumpWindowInfo( char* fnc, HWND hwnd)
255 {
256 	SWP aSWP;
257 	HWND	hwnd2;
258 	char	szTitle[256];
259 
260 #if 0
261 	_WinQueryWindowPos( hwnd, &aSWP );
262 	strcpy(szTitle,"");
263 	WinQueryWindowText(hwnd, sizeof(szTitle), szTitle);
264 	debug_printf( "%s: window %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd,
265 				aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle);
266 	hwnd2 = WinQueryWindow(hwnd, QW_PARENT);
267 	_WinQueryWindowPos( hwnd2, &aSWP );
268 	strcpy(szTitle,"");
269 	WinQueryWindowText(hwnd2, sizeof(szTitle), szTitle);
270 	debug_printf( "%s: parent %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd2,
271 				aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle);
272 	hwnd2 = WinQueryWindow(hwnd, QW_OWNER);
273 	_WinQueryWindowPos( hwnd2, &aSWP );
274 	strcpy(szTitle,"");
275 	WinQueryWindowText(hwnd2, sizeof(szTitle), szTitle);
276 	debug_printf( "%s: owner %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd2,
277 				aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle);
278 #endif
279 }
280 #endif
281 
282 // =======================================================================
283 
284 #ifdef ENABLE_IME
285 
286 struct ImplSalIMEProc
287 {
288     ULONG       nOrd;
289     PFN*        pProc;
290 };
291 
292 #define SAL_IME_PROC_COUNT          12
293 
294 // -----------------------------------------------------------------------
295 
296 static SalIMEData* GetSalIMEData()
297 {
298     SalData* pSalData = GetSalData();
299 
300     if ( !pSalData->mbIMEInit )
301     {
302         pSalData->mbIMEInit = TRUE;
303 
304         HMODULE hMod = 0;
305         if ( 0 == DosLoadModule( NULL, 0, "OS2IM", &hMod ) )
306         {
307             SalIMEData*     pIMEData = new SalIMEData;
308             BOOL            bError = FALSE;
309             ImplSalIMEProc  aProcAry[SAL_IME_PROC_COUNT] =
310             {
311             { 101, (PFN*)&(pIMEData->mpAssocIME) },
312             { 104, (PFN*)&(pIMEData->mpGetIME) },
313             { 106, (PFN*)&(pIMEData->mpReleaseIME) },
314             { 117, (PFN*)&(pIMEData->mpSetConversionFont) },
315             { 144, (PFN*)&(pIMEData->mpSetConversionFontSize) },
316             { 118, (PFN*)&(pIMEData->mpGetConversionString) },
317             { 122, (PFN*)&(pIMEData->mpGetResultString) },
318             { 115, (PFN*)&(pIMEData->mpSetCandidateWin) },
319             { 130, (PFN*)&(pIMEData->mpQueryIMEProperty) },
320             { 131, (PFN*)&(pIMEData->mpRequestIME) },
321             { 128, (PFN*)&(pIMEData->mpSetIMEMode) },
322             { 127, (PFN*)&(pIMEData->mpQueryIMEMode) }
323             };
324 
325             pIMEData->mhModIME = hMod;
326             for ( USHORT i = 0; i < SAL_IME_PROC_COUNT; i++ )
327             {
328                 if ( 0 != DosQueryProcAddr( pIMEData->mhModIME, aProcAry[i].nOrd, 0, aProcAry[i].pProc ) )
329                 {
330                     bError = TRUE;
331                     break;
332                 }
333             }
334 
335             if ( bError )
336             {
337                 DosFreeModule( pIMEData->mhModIME );
338                 delete pIMEData;
339             }
340             else
341                 pSalData->mpIMEData = pIMEData;
342         }
343     }
344 
345     return pSalData->mpIMEData;
346 }
347 
348 // -----------------------------------------------------------------------
349 
350 void ImplReleaseSALIMEData()
351 {
352     SalData* pSalData = GetSalData();
353 
354     if ( pSalData->mpIMEData )
355     {
356         DosFreeModule( pSalData->mpIMEData->mhModIME );
357         delete pSalData->mpIMEData;
358     }
359 }
360 
361 #endif
362 
363 // =======================================================================
364 
365 static void ImplSaveFrameState( Os2SalFrame* pFrame )
366 {
367     // Position, Groesse und Status fuer GetWindowState() merken
368     if ( !pFrame->mbFullScreen )
369     {
370         SWP aSWP;
371         BOOL bVisible = WinIsWindowVisible( pFrame->mhWndFrame);
372 
373         // Query actual state (maState uses screen coords)
374         WinQueryWindowPos( pFrame->mhWndFrame, &aSWP );
375 
376         if ( aSWP.fl & SWP_MINIMIZE )
377         {
378 #if OSL_DEBUG_LEVEL>0
379 			debug_printf("Os2SalFrame::GetWindowState %08x SAL_FRAMESTATE_MINIMIZED\n",
380 					pFrame->mhWndFrame);
381 #endif
382             pFrame->maState.mnState |= SAL_FRAMESTATE_MINIMIZED;
383             if ( bVisible )
384                 pFrame->mnShowState = SWP_SHOWMAXIMIZED;
385         }
386         else if ( aSWP.fl & SWP_MAXIMIZE )
387         {
388 #if OSL_DEBUG_LEVEL>0
389 			debug_printf("Os2SalFrame::GetWindowState %08x SAL_FRAMESTATE_MAXIMIZED\n",
390 					pFrame->mhWndFrame);
391 #endif
392             pFrame->maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED;
393             pFrame->maState.mnState |= SAL_FRAMESTATE_MAXIMIZED;
394             if ( bVisible )
395                 pFrame->mnShowState = SWP_SHOWMINIMIZED;
396             pFrame->mbRestoreMaximize = TRUE;
397         }
398         else
399         {
400 			LONG nFrameX, nFrameY, nCaptionY;
401 			ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY );
402 			// to be consistent with Unix, the frame state is without(!) decoration
403 			long nTopDeco = nFrameY + nCaptionY;
404 			long nLeftDeco = nFrameX;
405 			long nBottomDeco = nFrameY;
406 			long nRightDeco = nFrameX;
407 
408             pFrame->maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED);
409             // subtract decoration, store screen coords
410             pFrame->maState.mnX      = aSWP.x+nLeftDeco;
411             pFrame->maState.mnY      = nScreenHeight - (aSWP.y+aSWP.cy)+nTopDeco;
412             pFrame->maState.mnWidth  = aSWP.cx-nLeftDeco-nRightDeco;
413             pFrame->maState.mnHeight = aSWP.cy-nTopDeco-nBottomDeco;
414 #if OSL_DEBUG_LEVEL>0
415 			debug_printf("Os2SalFrame::GetWindowState %08x (%dx%d) at %d,%d VCL\n",
416 					pFrame->mhWndFrame,
417 					pFrame->maState.mnWidth,pFrame->maState.mnHeight,pFrame->maState.mnX,pFrame->maState.mnY);
418 #endif
419             if ( bVisible )
420                 pFrame->mnShowState = SWP_SHOWNORMAL;
421             pFrame->mbRestoreMaximize = FALSE;
422 			//debug_printf( "ImplSaveFrameState: window %08x at %d,%d (size %dx%d)\n",
423 			//	pFrame->mhWndFrame,
424 			//	pFrame->maState.mnX, pFrame->maState.mnY, pFrame->maState.mnWidth, pFrame->maState.mnHeight);
425         }
426     }
427 }
428 
429 // -----------------------------------------------------------------------
430 
431 long ImplSalCallbackDummy( void*, SalFrame*, USHORT, const void* )
432 {
433     return 0;
434 }
435 
436 // -----------------------------------------------------------------------
437 
438 static void ImplSalCalcFrameSize( HWND hWnd,
439                                   LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY )
440 {
441     Os2SalFrame* pFrame = GetWindowPtr( hWnd );
442     if ( !pFrame )
443         return;
444 	return ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY );
445 }
446 
447 static void ImplSalCalcFrameSize( const Os2SalFrame* pFrame,
448                                   LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY )
449 {
450     if ( pFrame->mbSizeBorder )
451     {
452         nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER );
453         nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER );
454     }
455     else if ( pFrame->mbFixBorder )
456     {
457         nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXDLGFRAME );
458         nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME );
459     }
460     else if ( pFrame->mbBorder )
461     {
462         nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXBORDER );
463         nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER );
464     }
465     else
466     {
467         nFrameX = 0;
468         nFrameY = 0;
469     }
470     if ( pFrame->mbCaption )
471         nCaptionY = WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR );
472     else
473         nCaptionY = 0;
474 
475 #if OSL_DEBUG_LEVEL>0
476 	//if (_bCapture)
477 		debug_printf("ImplSalCalcFrameSize 0x%08x x=%d y=%d t=%d\n", pFrame->mhWndFrame, nFrameX, nFrameY, nCaptionY);
478 #endif
479 }
480 
481 // -----------------------------------------------------------------------
482 
483 static void ImplSalCalcFullScreenSize( const Os2SalFrame* pFrame,
484                                        LONG& rX, LONG& rY, LONG& rDX, LONG& rDY )
485 {
486     // set window to screen size
487     LONG nFrameX, nFrameY, nCaptionY;
488     LONG rScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
489     LONG rScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
490 
491     // Framegroessen berechnen
492     ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY );
493 
494     rX  = -nFrameX;
495     rY  = -(nFrameY+nCaptionY);
496     rDX = rScreenDX+(nFrameX*2);
497     rDY = rScreenDY+(nFrameY*2)+nCaptionY;
498 }
499 
500 // -----------------------------------------------------------------------
501 
502 static void ImplSalFrameFullScreenPos( Os2SalFrame* pFrame, BOOL bAlways = FALSE )
503 {
504     SWP aSWP;
505     _WinQueryWindowPos( pFrame, &aSWP );
506     if ( bAlways || !(aSWP.fl & SWP_MINIMIZE) )
507     {
508         // set window to screen size
509         LONG nX;
510         LONG nY;
511         LONG nWidth;
512         LONG nHeight;
513         ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight );
514         _WinSetWindowPos( pFrame, 0,
515                          nX, nY, nWidth, nHeight,
516                          SWP_MOVE | SWP_SIZE );
517     }
518 }
519 
520 // -----------------------------------------------------------------------
521 
522 // Uebersetzungstabelle von System-Keycodes in StarView-Keycodes
523 #define KEY_TAB_SIZE     (VK_ENDDRAG+1)
524 
525 static USHORT aImplTranslateKeyTab[KEY_TAB_SIZE] =
526 {
527     // StarView-Code      System-Code                         Index
528     0,                    //                                  0x00
529     0,                    // VK_BUTTON1                       0x01
530     0,                    // VK_BUTTON2                       0x02
531     0,                    // VK_BUTTON3                       0x03
532     0,                    // VK_BREAK                         0x04
533     KEY_BACKSPACE,        // VK_BACKSPACE                     0x05
534     KEY_TAB,              // VK_TAB                           0x06
535     KEY_TAB,              // VK_BACKTAB                       0x07
536     KEY_RETURN,           // VK_NEWLINE                       0x08
537     0,                    // VK_SHIFT                         0x09
538     0,                    // VK_CTRL                          0x0A
539     0,                    // VK_ALT                           0x0B
540     0,                    // VK_ALTGRAF                       0x0C
541     0,                    // VK_PAUSE                         0x0D
542     0,                    // VK_CAPSLOCK                      0x0E
543     KEY_ESCAPE,           // VK_ESC                           0x0F
544     KEY_SPACE,            // VK_SPACE                         0x10
545     KEY_PAGEUP,           // VK_PAGEUP                        0x11
546     KEY_PAGEDOWN,         // VK_PAGEDOWN                      0x12
547     KEY_END,              // VK_END                           0x13
548     KEY_HOME,             // VK_HOME                          0x14
549     KEY_LEFT,             // VK_LEFT                          0x15
550     KEY_UP,               // VK_UP                            0x16
551     KEY_RIGHT,            // VK_RIGHT                         0x17
552     KEY_DOWN,             // VK_DOWN                          0x18
553     0,                    // VK_PRINTSCRN                     0x19
554     KEY_INSERT,           // VK_INSERT                        0x1A
555     KEY_DELETE,           // VK_DELETE                        0x1B
556     0,                    // VK_SCRLLOCK                      0x1C
557     0,                    // VK_NUMLOCK                       0x1D
558     KEY_RETURN,           // VK_ENTER                         0x1E
559     0,                    // VK_SYSRQ                         0x1F
560     KEY_F1,               // VK_F1                            0x20
561     KEY_F2,               // VK_F2                            0x21
562     KEY_F3,               // VK_F3                            0x22
563     KEY_F4,               // VK_F4                            0x23
564     KEY_F5,               // VK_F5                            0x24
565     KEY_F6,               // VK_F6                            0x25
566     KEY_F7,               // VK_F7                            0x26
567     KEY_F8,               // VK_F8                            0x27
568     KEY_F9,               // VK_F9                            0x28
569     KEY_F10,              // VK_F10                           0x29
570     KEY_F11,              // VK_F11                           0x2A
571     KEY_F12,              // VK_F12                           0x2B
572     KEY_F13,              // VK_F13                           0x2C
573     KEY_F14,              // VK_F14                           0x2D
574     KEY_F15,              // VK_F15                           0x2E
575     KEY_F16,              // VK_F16                           0x2F
576     KEY_F17,              // VK_F17                           0x30
577     KEY_F18,              // VK_F18                           0x31
578     KEY_F19,              // VK_F19                           0x32
579     KEY_F20,              // VK_F20                           0x33
580     KEY_F21,              // VK_F21                           0x34
581     KEY_F22,              // VK_F22                           0x35
582     KEY_F23,              // VK_F23                           0x36
583     KEY_F24,              // VK_F24                           0x37
584     0                     // VK_ENDDRAG                       0x38
585 };
586 
587 // =======================================================================
588 
589 SalFrame* ImplSalCreateFrame( Os2SalInstance* pInst, HWND hWndParent, ULONG nSalFrameStyle )
590 {
591     SalData*    	pSalData = GetSalData();
592     Os2SalFrame*   	pFrame = new Os2SalFrame;
593     HWND        	hWndFrame;
594     HWND        	hWndClient;
595     ULONG    		nFrameFlags = FCF_NOBYTEALIGN | FCF_SCREENALIGN;
596     ULONG    		nFrameStyle = 0;
597     ULONG    		nClientStyle = WS_CLIPSIBLINGS;
598     BOOL        	bSubFrame = FALSE;
599 
600 #if OSL_DEBUG_LEVEL>0
601     debug_printf(">ImplSalCreateFrame hWndParent 0x%x, nSalFrameStyle 0x%x\n", hWndParent, nSalFrameStyle);
602 #endif
603 
604 	if ( hWndParent )
605 	{
606 		bSubFrame = TRUE;
607 		pFrame->mbNoIcon = TRUE;
608 	}
609 
610     // determine creation data (bei Moveable nehmen wir DLG-Border, damit
611     // es besser aussieht)
612     if ( nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE )
613         nFrameFlags |= FCF_CLOSEBUTTON;
614 
615 	if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE ) {
616 		pFrame->mbCaption = TRUE;
617 		nFrameStyle = WS_ANIMATE;
618 		nFrameFlags |= FCF_SYSMENU | FCF_TITLEBAR | FCF_DLGBORDER;
619 		if ( !hWndParent )
620 			nFrameFlags |= FCF_MINBUTTON;
621 
622 		if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE )
623 		{
624 			pFrame->mbSizeBorder = TRUE;
625 			nFrameFlags |= FCF_SIZEBORDER;
626 			if ( !hWndParent )
627 				nFrameFlags |= FCF_MAXBUTTON;
628 		}
629 		else
630 			pFrame->mbFixBorder = TRUE;
631 
632 		// add task list style if not a tool window
633 		if ( !(nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) {
634 			nFrameFlags |= FCF_TASKLIST;
635 		}
636 	}
637 
638 	if( nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW )
639 	{
640 		pFrame->mbNoIcon = TRUE;
641 		// YD gives small caption -> nExSysStyle |= WS_EX_TOOLWINDOW;
642 	}
643 
644     if ( nSalFrameStyle & SAL_FRAME_STYLE_FLOAT )
645     {
646         //nExSysStyle |= WS_EX_TOOLWINDOW;
647         pFrame->mbFloatWin = TRUE;
648     }
649     //if( nSalFrameStyle & SAL_FRAME_STYLE_TOOLTIP )
650     //    nExSysStyle |= WS_EX_TOPMOST;
651 
652     // init frame data
653     pFrame->mnStyle = nSalFrameStyle;
654 
655     // determine show style
656     pFrame->mnShowState = SWP_SHOWNORMAL;
657 
658     // create frame
659 	//YD FIXME this is a potential bug with multiple threads and cuncurrent
660 	//window creation, because this field is accessed in
661 	//WM_CREATE to get window data,
662     pSalData->mpCreateFrame = pFrame;
663 
664 	//YD FIXME if SAL_FRAME_CHILD is specified, use hWndParent as parent handle...
665     hWndFrame = WinCreateStdWindow( HWND_DESKTOP, nFrameStyle, &nFrameFlags,
666 					(PSZ)(bSubFrame ? SAL_SUBFRAME_CLASSNAME : SAL_FRAME_CLASSNAME),
667 					NULL,
668 					nClientStyle, 0, 0, &hWndClient );
669     debug_printf("ImplSalCreateFrame hWndParent 0x%x, hWndFrame 0x%x, hWndClient 0x%x\n", hWndParent, hWndFrame, hWndClient);
670     if ( !hWndFrame )
671     {
672         delete pFrame;
673         return NULL;
674     }
675 
676     // Parent setzen (Owner)
677     if ( hWndParent != 0 && hWndParent != HWND_DESKTOP )
678         WinSetOwner( hWndFrame, hWndParent );
679 
680     Os2SalFrame* pParentFrame = GetWindowPtr( hWndParent );
681     if ( pParentFrame )
682 		pFrame->mpParentFrame = pParentFrame;
683 
684     // Icon setzen (YD win32 does it in the class registration)
685     if ( nFrameFlags & FCF_MINBUTTON )
686         WinSendMsg( hWndFrame, WM_SETICON, (MPARAM)pInst->mhAppIcon, (MPARAM)0 );
687 
688     // If we have an Window with an Caption Bar and without
689     // an MaximizeBox, we change the SystemMenu
690     if ( (nFrameFlags & (FCF_TITLEBAR | FCF_MAXBUTTON)) == (FCF_TITLEBAR) )
691     {
692         HWND hSysMenu = WinWindowFromID( hWndFrame, FID_SYSMENU );
693         if ( hSysMenu )
694         {
695             if ( !(nFrameFlags & (FCF_MINBUTTON | FCF_MAXBUTTON)) )
696 				WinEnableMenuItem(hSysMenu, SC_RESTORE, FALSE);
697             if ( !(nFrameFlags & FCF_MINBUTTON) )
698 				WinEnableMenuItem(hSysMenu, SC_MINIMIZE, FALSE);
699             if ( !(nFrameFlags & FCF_MAXBUTTON) )
700 				WinEnableMenuItem(hSysMenu, SC_MAXIMIZE, FALSE);
701             if ( !(nFrameFlags & FCF_SIZEBORDER) )
702 				WinEnableMenuItem(hSysMenu, SC_SIZE, FALSE);
703         }
704     }
705     if ( (nFrameFlags & FCF_SYSMENU) && !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) )
706     {
707         HWND hSysMenu = WinWindowFromID( hWndFrame, FID_SYSMENU );
708         if ( hSysMenu )
709         {
710             WinEnableMenuItem(hSysMenu, SC_CLOSE, FALSE);
711         }
712     }
713 
714     // ticket#124 subclass frame window: we need to intercept TRACK message
715     aSalShlData.mpFrameProc = WinSubclassWindow( hWndFrame, SalFrameSubClassWndProc);
716 
717     // init OS/2 frame data
718     pFrame->mhAB            = pInst->mhAB;
719 
720     // YD 18/08 under OS/2, invisible frames have size 0,0 at 0,0, so
721     // we need to set an initial size/position manually
722     SWP aSWP;
723     memset( &aSWP, 0, sizeof( aSWP ) );
724     WinQueryTaskSizePos( pInst->mhAB, 0, &aSWP );
725     WinSetWindowPos( hWndFrame, NULL, aSWP.x, aSWP.y, aSWP.cx, aSWP.cy,
726                      SWP_MOVE | SWP_SIZE);
727 
728 #ifdef ENABLE_IME
729     // Input-Context einstellen
730     SalIMEData* pIMEData = GetSalIMEData();
731     if ( pIMEData )
732     {
733         pFrame->mhIMEContext = 0;
734         if ( 0 != pIMEData->mpAssocIME( hWndClient, pFrame->mhIMEContext, &pFrame->mhDefIMEContext ) )
735             pFrame->mhDefIMEContext = 0;
736     }
737     else
738     {
739         pFrame->mhIMEContext = 0;
740         pFrame->mhDefIMEContext = 0;
741     }
742 #endif
743 
744     RECTL rectl;
745     _WinQueryWindowRect( hWndClient, &rectl );
746     pFrame->mnWidth  = rectl.xRight;
747     pFrame->mnHeight = rectl.yBottom;
748     debug_printf( "ImplSalCreateFrame %dx%d\n", pFrame->mnWidth, pFrame->mnHeight);
749     ImplSaveFrameState( pFrame );
750     pFrame->mbDefPos = TRUE;
751 
752 	UpdateFrameGeometry( hWndFrame, pFrame );
753 
754     if( pFrame->mnShowState == SWP_SHOWMAXIMIZED )
755 	{
756 		// #96084 set a useful internal window size because
757 		// the window will not be maximized (and the size updated) before show()
758         SetMaximizedFrameGeometry( hWndFrame, pFrame );
759 	}
760 
761 #if OSL_DEBUG_LEVEL > 1
762 	dumpWindowInfo( "<ImplSalCreateFrame (exit)", hWndFrame);
763 #endif
764 
765     return pFrame;
766 }
767 
768 // =======================================================================
769 
770 Os2SalFrame::Os2SalFrame()
771 {
772     SalData* pSalData = GetSalData();
773 
774     mbGraphics          = NULL;
775     mhPointer           = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE );
776     mpGraphics          = NULL;
777     mpInst              = NULL;
778     mbFullScreen        = FALSE;
779     mbAllwayOnTop       = FALSE;
780     mbVisible           = FALSE;
781     mbMinHide           = FALSE;
782     mbInShow            = FALSE;
783     mbRestoreMaximize   = FALSE;
784     mbInMoveMsg         = FALSE;
785     mbInSizeMsg         = FALSE;
786     mbDefPos            = TRUE;
787     mbOverwriteState    = TRUE;
788     mbHandleIME         = FALSE;
789     mbConversionMode    = FALSE;
790     mbCandidateMode     = FALSE;
791     mbCaption           = FALSE;
792     //mhDefIMEContext     = 0;
793     mpGraphics          = NULL;
794     mnShowState         = SWP_SHOWNORMAL;
795     mnWidth             = 0;
796     mnHeight            = 0;
797     mnMinWidth          = 0;
798     mnMinHeight         = 0;
799     mnMaxWidth          = SHRT_MAX;
800     mnMaxHeight         = SHRT_MAX;
801     mnInputLang         = 0;
802     mnKeyboardHandle    = 0;
803     mbGraphics          = FALSE;
804     mbCaption           = FALSE;
805     mbBorder            = FALSE;
806     mbFixBorder         = FALSE;
807     mbSizeBorder        = FALSE;
808     mbFullScreen        = FALSE;
809     //mbPresentation      = FALSE;
810     mbInShow            = FALSE;
811     mbRestoreMaximize   = FALSE;
812     mbInMoveMsg         = FALSE;
813     mbInSizeMsg         = FALSE;
814     //mbFullScreenToolWin = FALSE;
815     mbDefPos            = TRUE;
816     mbOverwriteState    = TRUE;
817     //mbIME               = FALSE;
818     mbHandleIME         = FALSE;
819     //mbSpezIME           = FALSE;
820     //mbAtCursorIME       = FALSE;
821     mbCandidateMode     = FALSE;
822     mbFloatWin          = FALSE;
823     mbNoIcon            = FALSE;
824     //mSelectedhMenu      = 0;
825     //mLastActivatedhMenu = 0;
826 	mpParentFrame		= NULL;
827 
828     memset( &maState, 0, sizeof( SalFrameState ) );
829     maSysData.nSize     = sizeof( SystemEnvData );
830     memset( &maGeometry, 0, sizeof( maGeometry ) );
831 
832     // insert frame in framelist
833     mpNextFrame = pSalData->mpFirstFrame;
834     pSalData->mpFirstFrame = this;
835 }
836 
837 // -----------------------------------------------------------------------
838 
839 Os2SalFrame::~Os2SalFrame()
840 {
841     SalData* pSalData = GetSalData();
842 
843     // destroy DC
844     if ( mpGraphics )
845     {
846         ImplSalDeInitGraphics( mpGraphics );
847         WinReleasePS( mpGraphics->mhPS );
848         delete mpGraphics;
849     }
850 
851     // destroy system frame
852     WinDestroyWindow( mhWndFrame );
853 
854     // remove frame from framelist
855     if ( this == pSalData->mpFirstFrame )
856         pSalData->mpFirstFrame = mpNextFrame;
857     else
858     {
859         Os2SalFrame* pTempFrame = pSalData->mpFirstFrame;
860         while ( pTempFrame->mpNextFrame != this )
861             pTempFrame = pTempFrame->mpNextFrame;
862 
863         pTempFrame->mpNextFrame = mpNextFrame;
864     }
865 }
866 
867 // -----------------------------------------------------------------------
868 
869 static HDC ImplWinGetDC( HWND hWnd )
870 {
871     HDC hDC = WinQueryWindowDC( hWnd );
872     if ( !hDC )
873         hDC = WinOpenWindowDC( hWnd );
874     return hDC;
875 }
876 
877 // -----------------------------------------------------------------------
878 
879 SalGraphics* Os2SalFrame::GetGraphics()
880 {
881     if ( mbGraphics )
882         return NULL;
883 
884     if ( !mpGraphics )
885     {
886         SalData* pSalData = GetSalData();
887         mpGraphics = new Os2SalGraphics;
888         mpGraphics->mhPS      = WinGetPS( mhWndClient );
889         mpGraphics->mhDC      = ImplWinGetDC( mhWndClient );
890         mpGraphics->mhWnd     = mhWndClient;
891         mpGraphics->mnHeight  = mnHeight;
892         mpGraphics->mbPrinter = FALSE;
893         mpGraphics->mbVirDev  = FALSE;
894         mpGraphics->mbWindow  = TRUE;
895         mpGraphics->mbScreen  = TRUE;
896         ImplSalInitGraphics( mpGraphics );
897         mbGraphics = TRUE;
898     }
899     else
900         mbGraphics = TRUE;
901 
902     return mpGraphics;
903 }
904 
905 // -----------------------------------------------------------------------
906 
907 void Os2SalFrame::ReleaseGraphics( SalGraphics* )
908 {
909     mbGraphics = FALSE;
910 }
911 
912 // -----------------------------------------------------------------------
913 
914 BOOL Os2SalFrame::PostEvent( void* pData )
915 {
916     return (BOOL)WinPostMsg( mhWndClient, SAL_MSG_USEREVENT, 0, (MPARAM)pData );
917 }
918 
919 // -----------------------------------------------------------------------
920 
921 void Os2SalFrame::SetTitle( const XubString& rTitle )
922 {
923     // set window title
924 	ByteString title( rTitle, gsl_getSystemTextEncoding() );
925 	debug_printf("Os2SalFrame::SetTitle %x '%s'\n", mhWndFrame, title.GetBuffer() );
926     WinSetWindowText( mhWndFrame, title.GetBuffer() );
927 }
928 
929 // -----------------------------------------------------------------------
930 
931 void Os2SalFrame::SetIcon( USHORT nIcon )
932 {
933 	debug_printf("Os2SalFrame::SetIcon\n");
934 
935     // If we have a window without an Icon (for example a dialog), ignore this call
936     if ( mbNoIcon )
937         return;
938 
939     // 0 means default (class) icon
940     HPOINTER hIcon = NULL;
941     if ( !nIcon )
942         nIcon = 1;
943 
944     ImplLoadSalIcon( nIcon, hIcon );
945 
946     DBG_ASSERT( hIcon , "Os2SalFrame::SetIcon(): Could not load icon !" );
947 
948     // Icon setzen
949 	WinSendMsg( mhWndFrame, WM_SETICON, (MPARAM)hIcon, (MPARAM)0 );
950 }
951 
952 // -----------------------------------------------------------------------
953 
954 SalFrame* Os2SalFrame::GetParent() const
955 {
956 	//debug_printf("Os2SalFrame::GetParent\n");
957     return GetWindowPtr( WinQueryWindow(mhWndFrame, QW_OWNER) );
958 }
959 
960 // -----------------------------------------------------------------------
961 
962 static void ImplSalShow( HWND hWnd, ULONG bVisible, ULONG bNoActivate )
963 {
964     Os2SalFrame* pFrame = GetWindowPtr( hWnd );
965     if ( !pFrame )
966         return;
967 
968     if ( bVisible )
969     {
970         pFrame->mbDefPos = FALSE;
971         pFrame->mbOverwriteState = TRUE;
972         pFrame->mbInShow = TRUE;
973 
974 #if OSL_DEBUG_LEVEL > 0
975 		debug_printf( "ImplSalShow hwnd %x visible flag %d, no activate: flag %d\n", hWnd, bVisible, bNoActivate);
976 #endif
977 
978         if( bNoActivate )
979 			WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_SHOW);
980         else
981             WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, pFrame->mnShowState);
982 
983         pFrame->mbInShow = FALSE;
984 
985         // Direct Paint only, if we get the SolarMutx
986         if ( ImplSalYieldMutexTryToAcquire() )
987         {
988             WinUpdateWindow( hWnd );
989             ImplSalYieldMutexRelease();
990         }
991     }
992     else
993     {
994 #if OSL_DEBUG_LEVEL > 0
995 		debug_printf( "ImplSalShow hwnd %x HIDE\n");
996 #endif
997 		WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_HIDE);
998     }
999 }
1000 
1001 
1002 // -----------------------------------------------------------------------
1003 
1004 
1005 void Os2SalFrame::SetExtendedFrameStyle( SalExtStyle nExtStyle )
1006 {
1007 }
1008 
1009 // -----------------------------------------------------------------------
1010 
1011 void Os2SalFrame::Show( BOOL bVisible, BOOL bNoActivate )
1012 {
1013     // Post this Message to the window, because this only works
1014     // in the thread of the window, which has create this window.
1015     // We post this message to avoid deadlocks
1016     if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() )
1017         WinPostMsg( mhWndFrame, SAL_MSG_SHOW, (MPARAM)bVisible, (MPARAM)bNoActivate );
1018     else
1019         ImplSalShow( mhWndFrame, bVisible, bNoActivate );
1020 }
1021 
1022 // -----------------------------------------------------------------------
1023 
1024 void Os2SalFrame::Enable( BOOL bEnable )
1025 {
1026     WinEnableWindow( mhWndFrame, bEnable );
1027 }
1028 
1029 // -----------------------------------------------------------------------
1030 
1031 void Os2SalFrame::SetMinClientSize( long nWidth, long nHeight )
1032 {
1033     debug_printf("Os2SalFrame::SetMinClientSize\n");
1034     mnMinWidth  = nWidth;
1035     mnMinHeight = nHeight;
1036 }
1037 
1038 void Os2SalFrame::SetMaxClientSize( long nWidth, long nHeight )
1039 {
1040     debug_printf("Os2SalFrame::SetMaxClientSize\n");
1041     mnMaxWidth  = nWidth;
1042     mnMaxHeight = nHeight;
1043 }
1044 
1045 // -----------------------------------------------------------------------
1046 
1047 void Os2SalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight,
1048                                                    USHORT nFlags )
1049 {
1050     // calculation frame size
1051     USHORT 	nEvent = 0;
1052 	ULONG	nPosFlags = 0;
1053 
1054 #if OSL_DEBUG_LEVEL > 0
1055 	//dumpWindowInfo( "-Os2SalFrame::SetPosSize", mhWndFrame);
1056 	debug_printf( ">Os2SalFrame::SetPosSize go to %d,%d (%dx%d) VCL\n",nX,nY,nWidth,nHeight);
1057 #endif
1058 
1059 	SWP aSWP;
1060 	_WinQueryWindowPos( this, &aSWP );
1061     BOOL bVisible = WinIsWindowVisible( mhWndFrame );
1062     if ( !bVisible )
1063     {
1064         if ( mbFloatWin )
1065 			mnShowState = SWP_SHOW;
1066         else
1067 			mnShowState = SWP_SHOWNORMAL;
1068     }
1069     else
1070     {
1071         if ( (aSWP.fl & SWP_MINIMIZE) || (aSWP.fl & SWP_MAXIMIZE) )
1072 			WinSetWindowPos(mhWndFrame, NULL, 0, 0, 0, 0, SWP_RESTORE );
1073     }
1074 
1075     if ( (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)) ) {
1076         nPosFlags |= SWP_MOVE;
1077 #if OSL_DEBUG_LEVEL > 0
1078 		debug_printf( "-Os2SalFrame::SetPosSize MOVE to %d,%d\n", nX, nY);
1079 #endif
1080         //DBG_ASSERT( nX && nY, " Windowposition of (0,0) requested!" );
1081         nEvent = SALEVENT_MOVE;
1082 	}
1083 
1084     if ( (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) ) {
1085         nPosFlags |= SWP_SIZE;
1086 #if OSL_DEBUG_LEVEL > 0
1087 		debug_printf( "-Os2SalFrame::SetPosSize SIZE to %d,%d\n", nWidth,nHeight);
1088 #endif
1089         nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE;
1090 	}
1091 
1092     // Default-Position, dann zentrieren, ansonsten Position beibehalten
1093     if ( mbDefPos  && !(nPosFlags & SWP_MOVE))
1094     {
1095         // calculate bottom left corner of frame
1096         mbDefPos = FALSE;
1097 		nPosFlags |= SWP_MOVE | SWP_CENTER;
1098         nEvent = SALEVENT_MOVERESIZE;
1099 #if OSL_DEBUG_LEVEL > 10
1100 		debug_printf( "-Os2SalFrame::SetPosSize CENTER\n");
1101 		debug_printf( "-Os2SalFrame::SetPosSize default position to %d,%d\n", nX, nY);
1102 #endif
1103     }
1104 
1105     // Adjust Window in the screen
1106     BOOL bCheckOffScreen = TRUE;
1107 
1108     // but don't do this for floaters or ownerdraw windows that are currently moved interactively
1109     if( (mnStyle & SAL_FRAME_STYLE_FLOAT) && !(mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
1110         bCheckOffScreen = FALSE;
1111 
1112     if( mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION )
1113     {
1114         // may be the window is currently being moved (mouse is captured), then no check is required
1115         if( mhWndClient == WinQueryCapture( HWND_DESKTOP) )
1116             bCheckOffScreen = FALSE;
1117         else
1118             bCheckOffScreen = TRUE;
1119     }
1120 
1121     if( bCheckOffScreen )
1122     {
1123         if ( nX+nWidth > nScreenWidth )
1124             nX = nScreenWidth - nWidth;
1125         if ( nY+nHeight > nScreenHeight )
1126             nY = nScreenHeight - nHeight;
1127         if ( nX < 0 )
1128             nX = 0;
1129         if ( nY < 0 )
1130             nY = 0;
1131     }
1132 
1133     // bring floating windows always to top
1134     // do not change zorder, otherwise tooltips will bring main window to top (ticket:14)
1135     //if( (mnStyle & SAL_FRAME_STYLE_FLOAT) )
1136     //    nPosFlags |= SWP_ZORDER; // do not change z-order
1137 
1138     // set new position
1139     _WinSetWindowPos( this, HWND_TOP, nX, nY, nWidth, nHeight, nPosFlags); // | SWP_RESTORE
1140 
1141     UpdateFrameGeometry( mhWndFrame, this );
1142 
1143     // Notification -- really ???
1144     if( nEvent )
1145         CallCallback( nEvent, NULL );
1146 
1147 #if OSL_DEBUG_LEVEL > 0
1148 	dumpWindowInfo( "<Os2SalFrame::SetPosSize (exit)", mhWndFrame);
1149 #endif
1150 
1151 }
1152 
1153 // -----------------------------------------------------------------------
1154 
1155 void Os2SalFrame::SetParent( SalFrame* pNewParent )
1156 {
1157     APIRET rc;
1158 #if OSL_DEBUG_LEVEL>0
1159     debug_printf("Os2SalFrame::SetParent mhWndFrame 0x%08x to 0x%08x\n",
1160 			static_cast<Os2SalFrame*>(this)->mhWndFrame,
1161 			static_cast<Os2SalFrame*>(pNewParent)->mhWndClient);
1162 #endif
1163     Os2SalFrame::mbInReparent = TRUE;
1164     //rc = WinSetParent(static_cast<Os2SalFrame*>(this)->mhWndFrame,
1165     //                  static_cast<Os2SalFrame*>(pNewParent)->mhWndClient, TRUE);
1166     rc = WinSetOwner(static_cast<Os2SalFrame*>(this)->mhWndFrame,
1167                       static_cast<Os2SalFrame*>(pNewParent)->mhWndClient);
1168 	mpParentFrame = static_cast<Os2SalFrame*>(pNewParent);
1169     Os2SalFrame::mbInReparent = FALSE;
1170 }
1171 
1172 bool Os2SalFrame::SetPluginParent( SystemParentData* pNewParent )
1173 {
1174     APIRET rc;
1175     if ( pNewParent->hWnd == 0 )
1176     {
1177         pNewParent->hWnd = HWND_DESKTOP;
1178     }
1179 
1180     Os2SalFrame::mbInReparent = TRUE;
1181     rc = WinSetOwner(static_cast<Os2SalFrame*>(this)->mhWndFrame,
1182                       pNewParent->hWnd);
1183     Os2SalFrame::mbInReparent = FALSE;
1184     return true;
1185 }
1186 
1187 
1188 // -----------------------------------------------------------------------
1189 
1190 void Os2SalFrame::GetWorkArea( RECTL &rRect )
1191 {
1192     rRect.xLeft     = rRect.yTop = 0;
1193     rRect.xRight    = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN )-1;
1194     rRect.yBottom   = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN )-1;
1195 }
1196 
1197 // -----------------------------------------------------------------------
1198 
1199 void Os2SalFrame::GetWorkArea( Rectangle &rRect )
1200 {
1201     RECTL aRect;
1202 	GetWorkArea( aRect);
1203     rRect.nLeft     = aRect.xLeft;
1204     rRect.nRight    = aRect.xRight; // win -1;
1205     rRect.nTop      = aRect.yTop;
1206     rRect.nBottom   = aRect.yBottom; // win -1;
1207 }
1208 
1209 // -----------------------------------------------------------------------
1210 
1211 void Os2SalFrame::GetClientSize( long& rWidth, long& rHeight )
1212 {
1213     rWidth  = maGeometry.nWidth;
1214     rHeight = maGeometry.nHeight;
1215 }
1216 
1217 // -----------------------------------------------------------------------
1218 
1219 void Os2SalFrame::SetWindowState( const SalFrameState* pState )
1220 {
1221 	LONG	nX;
1222 	LONG 	nY;
1223 	LONG 	nWidth;
1224 	LONG 	nHeight;
1225 	ULONG	nPosSize = 0;
1226 
1227 #if OSL_DEBUG_LEVEL>0
1228 	debug_printf("Os2SalFrame::SetWindowState\n");
1229 	debug_printf("Os2SalFrame::SetWindowState %08x (%dx%d) at %d,%d VCL\n",
1230 		mhWndFrame,
1231 		pState->mnWidth,pState->mnHeight,pState->mnX,pState->mnY);
1232 #endif
1233 
1234     BOOL bVisible = WinIsWindowVisible( mhWndFrame );
1235 
1236     // get screen coordinates
1237     SWP	aSWP;
1238     WinQueryWindowPos( mhWndFrame, &aSWP );
1239 	LONG nFrameX, nFrameY, nCaptionY;
1240 	ImplSalCalcFrameSize( this, nFrameX, nFrameY, nCaptionY );
1241 
1242     long nTopDeco = nFrameY + nCaptionY;
1243     long nLeftDeco = nFrameX;
1244     long nBottomDeco = nFrameY;
1245     long nRightDeco = nFrameX;
1246 
1247     // Fenster-Position/Groesse in den Bildschirm einpassen
1248     if ((pState->mnMask & (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y)) )
1249         nPosSize |= SWP_MOVE;
1250     if ((pState->mnMask & (SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)) )
1251         nPosSize |= SWP_SIZE;
1252 
1253     if ( pState->mnMask & SAL_FRAMESTATE_MASK_X )
1254         nX = (int)pState->mnX - nLeftDeco;
1255     else
1256         nX = aSWP.x;
1257 
1258 	// keep Y inverted since height is still unknown, will invert later
1259     if ( pState->mnMask & SAL_FRAMESTATE_MASK_Y )
1260         nY = (int)pState->mnY - nTopDeco;
1261     else
1262         nY = nScreenHeight - (aSWP.y+aSWP.cy);
1263 
1264     if ( pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH )
1265         nWidth = (int)pState->mnWidth + nLeftDeco + nRightDeco;
1266     else
1267         nWidth = aSWP.cx;
1268     if ( pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT )
1269         nHeight = (int)pState->mnHeight + nTopDeco + nBottomDeco;
1270     else
1271         nHeight = aSWP.cy;
1272 
1273 #if OSL_DEBUG_LEVEL>0
1274 	debug_printf("Os2SalFrame::SetWindowState (%dx%d) at %d,%d\n", nWidth,nHeight,nX,nY);
1275 #endif
1276 
1277     // Adjust Window in the screen:
1278     // if it does not fit into the screen do nothing, ie default pos/size will be used
1279     // if there is an overlap with the screen border move the window while keeping its size
1280 
1281     //if( nWidth > nScreenWidth || nHeight > nScreenHeight )
1282     //    nPosSize |= (SWP_NOMOVE | SWP_NOSIZE);
1283 
1284     if ( nX+nWidth > nScreenWidth )
1285         nX = (nScreenWidth) - nWidth;
1286     if ( nY+nHeight > nScreenHeight )
1287         nY = (nScreenHeight) - nHeight;
1288     if ( nX < 0 )
1289         nX = 0;
1290     if ( nY < 0 )
1291         nY = 0;
1292 
1293     // Restore-Position setzen
1294 	SWP aPlacement;
1295 	WinQueryWindowPos( mhWndFrame, &aPlacement );
1296 
1297     // Status setzen
1298 	bVisible = WinIsWindowVisible( mhWndFrame);
1299 	BOOL bUpdateHiddenFramePos = FALSE;
1300     if ( !bVisible )
1301     {
1302         aPlacement.fl = SWP_HIDE;
1303 
1304         if ( mbOverwriteState )
1305         {
1306             if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE )
1307             {
1308                 if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
1309                     mnShowState = SWP_SHOWMINIMIZED;
1310                 else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
1311 				{
1312                     mnShowState = SWP_SHOWMAXIMIZED;
1313 					bUpdateHiddenFramePos = TRUE;
1314 				}
1315                 else if ( pState->mnState & SAL_FRAMESTATE_NORMAL )
1316                     mnShowState = SWP_SHOWNORMAL;
1317             }
1318         }
1319     }
1320     else
1321     {
1322         if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE )
1323         {
1324             if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
1325             {
1326                 //if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
1327                 //    aPlacement.flags |= WPF_RESTORETOMAXIMIZED;
1328                 aPlacement.fl = SWP_SHOWMINIMIZED;
1329             }
1330             else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
1331                 aPlacement.fl = SWP_SHOWMAXIMIZED;
1332             else if ( pState->mnState & SAL_FRAMESTATE_NORMAL )
1333                 aPlacement.fl = SWP_RESTORE;
1334         }
1335     }
1336 
1337     // Wenn Fenster nicht minimiert/maximiert ist oder nicht optisch
1338     // umgesetzt werden muss, dann SetWindowPos() benutzen, da
1339     // SetWindowPlacement() die TaskBar mit einrechnet
1340     if ( !(aPlacement.fl & SWP_MINIMIZE)
1341 		 && !( aPlacement.fl & SWP_MAXIMIZE )
1342 	 	 && (!bVisible || (aPlacement.fl == SWP_RESTORE)) )
1343     {
1344 		if( bUpdateHiddenFramePos )
1345 		{
1346 			// #96084 set a useful internal window size because
1347 			// the window will not be maximized (and the size updated) before show()
1348             SetMaximizedFrameGeometry( mhWndFrame, this );
1349 		}
1350 		else
1351 			WinSetWindowPos( mhWndFrame, 0, nX,
1352 				nScreenHeight - (nY+nHeight), nWidth, nHeight, nPosSize);
1353     }
1354     else
1355     {
1356         if( (nPosSize & (SWP_MOVE|SWP_SIZE)) )
1357         {
1358 			aPlacement.x = nX;
1359 			aPlacement.y = nScreenHeight-(nY+nHeight);
1360 			aPlacement.cx = nWidth;
1361 			aPlacement.cy = nHeight;
1362         }
1363 		WinSetWindowPos( mhWndFrame, 0, aPlacement.x, aPlacement.y,
1364 						 aPlacement.cx, aPlacement.cy, aPlacement.fl );
1365     }
1366 
1367 #if OSL_DEBUG_LEVEL>0
1368 	debug_printf("Os2SalFrame::SetWindowState DONE\n");
1369 #endif
1370 }
1371 
1372 // -----------------------------------------------------------------------
1373 
1374 BOOL Os2SalFrame::GetWindowState( SalFrameState* pState )
1375 {
1376     if ( maState.mnWidth && maState.mnHeight )
1377     {
1378         *pState = maState;
1379         // #94144# allow Minimize again, should be masked out when read from configuration
1380         // 91625 - Don't save minimize
1381         //if ( !(pState->mnState & SAL_FRAMESTATE_MAXIMIZED) )
1382         if ( !(pState->mnState & (SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED)) )
1383             pState->mnState |= SAL_FRAMESTATE_NORMAL;
1384         return TRUE;
1385     }
1386 
1387     return FALSE;
1388 }
1389 
1390 // -----------------------------------------------------------------------
1391 
1392 void Os2SalFrame::SetScreenNumber( unsigned int nNewScreen )
1393 {
1394 #if 0
1395     WinSalSystem* pSys = static_cast<WinSalSystem*>(ImplGetSalSystem());
1396     if( pSys )
1397     {
1398         const std::vector<WinSalSystem::DisplayMonitor>& rMonitors =
1399             pSys->getMonitors();
1400         size_t nMon = rMonitors.size();
1401         if( nNewScreen < nMon )
1402         {
1403             Point aOldMonPos, aNewMonPos( rMonitors[nNewScreen].m_aArea.TopLeft() );
1404             Point aCurPos( maGeometry.nX, maGeometry.nY );
1405             for( size_t i = 0; i < nMon; i++ )
1406             {
1407                 if( rMonitors[i].m_aArea.IsInside( aCurPos ) )
1408                 {
1409                     aOldMonPos = rMonitors[i].m_aArea.TopLeft();
1410                     break;
1411                 }
1412             }
1413             mnDisplay = nNewScreen;
1414             maGeometry.nScreenNumber = nNewScreen;
1415             SetPosSize( aNewMonPos.X() + (maGeometry.nX - aOldMonPos.X()),
1416                         aNewMonPos.Y() + (maGeometry.nY - aOldMonPos.Y()),
1417                         0, 0,
1418                         SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y );
1419         }
1420     }
1421 #endif
1422 }
1423 
1424 // -----------------------------------------------------------------------
1425 
1426 // native menu implementation - currently empty
1427 void Os2SalFrame::DrawMenuBar()
1428 {
1429 }
1430 
1431 void Os2SalFrame::SetMenu( SalMenu* pSalMenu )
1432 {
1433 }
1434 
1435 // -----------------------------------------------------------------------
1436 
1437 void Os2SalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nDisplay )
1438 {
1439     if ( mbFullScreen == bFullScreen )
1440         return;
1441 
1442     mbFullScreen = bFullScreen;
1443     if ( bFullScreen )
1444     {
1445         // save old position
1446         memset( &maFullScreenRect, 0, sizeof( SWP ) );
1447         _WinQueryWindowPos( this, &maFullScreenRect );
1448 
1449         // set window to screen size
1450         ImplSalFrameFullScreenPos( this, TRUE );
1451     }
1452     else
1453     {
1454         _WinSetWindowPos( this,
1455                          0,
1456                          maFullScreenRect.x, maFullScreenRect.y,
1457                          maFullScreenRect.cx, maFullScreenRect.cy,
1458                          SWP_MOVE | SWP_SIZE );
1459     }
1460 }
1461 
1462 // -----------------------------------------------------------------------
1463 
1464 void Os2SalFrame::StartPresentation( BOOL bStart )
1465 {
1466     // SysSetObjectData("<WP_DESKTOP>","Autolockup=no"); oder OS2.INI: PM_Lockup
1467 }
1468 
1469 // -----------------------------------------------------------------------
1470 
1471 void Os2SalFrame::SetAlwaysOnTop( BOOL bOnTop )
1472 {
1473     mbAllwayOnTop = bOnTop;
1474 #if 0
1475     HWND hWnd;
1476     if ( bOnTop )
1477         hWnd = HWND_TOPMOST;
1478     else
1479         hWnd = HWND_NOTOPMOST;
1480     SetWindowPos( mhWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
1481 #endif
1482 }
1483 
1484 
1485 // -----------------------------------------------------------------------
1486 
1487 static void ImplSalToTop( HWND hWnd, ULONG nFlags )
1488 {
1489     Os2SalFrame* pFrame = GetWindowPtr( hWnd );
1490 #if OSL_DEBUG_LEVEL>0
1491 	debug_printf("ImplSalToTop hWnd %08x, nFlags %x\n", hWnd, nFlags);
1492 #endif
1493 
1494 	// if window is minimized, first restore it
1495 	SWP aSWP;
1496 	WinQueryWindowPos( hWnd, &aSWP );
1497 	if ( aSWP.fl & SWP_MINIMIZE )
1498 		WinSetWindowPos( hWnd, NULL, 0, 0, 0, 0, SWP_RESTORE );
1499 
1500     if ( nFlags & SAL_FRAME_TOTOP_FOREGROUNDTASK )
1501 		WinSetWindowPos( pFrame->mhWndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
1502 
1503     if ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN )
1504     {
1505 		ULONG	nStyle;
1506         if ( pFrame->mbRestoreMaximize )
1507             nStyle = SWP_MAXIMIZE;
1508         else
1509             nStyle = SWP_RESTORE;
1510 
1511 		WinSetWindowPos( pFrame->mhWndFrame, NULL, 0, 0, 0, 0, nStyle );
1512 	}
1513     WinSetFocus( HWND_DESKTOP, pFrame->mhWndClient );
1514 }
1515 
1516 // -----------------------------------------------------------------------
1517 
1518 void Os2SalFrame::ToTop( USHORT nFlags )
1519 {
1520 	nFlags &= ~SAL_FRAME_TOTOP_GRABFOCUS;	// this flag is not needed on win32
1521     // Post this Message to the window, because this only works
1522     // in the thread of the window, which has create this window.
1523     // We post this message to avoid deadlocks
1524     if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() )
1525         WinPostMsg( mhWndFrame, SAL_MSG_TOTOP, (MPARAM)nFlags, 0 );
1526     else
1527         ImplSalToTop( mhWndFrame, nFlags );
1528 }
1529 
1530 // -----------------------------------------------------------------------
1531 
1532 void Os2SalFrame::SetPointer( PointerStyle ePointerStyle )
1533 {
1534     struct ImplPtrData
1535     {
1536         HPOINTER	mhPointer;
1537         ULONG       mnSysId;
1538         ULONG       mnOwnId;
1539     };
1540 
1541     static ImplPtrData aImplPtrTab[POINTER_COUNT] =
1542     {
1543     { 0, SPTR_ARROW, 0 },                           // POINTER_ARROW
1544     { 0, 0, SAL_RESID_POINTER_NULL },               // POINTER_NULL
1545     { 0, SPTR_WAIT, 0 },                            // POINTER_WAIT
1546     { 0, SPTR_TEXT, 0 },                            // POINTER_BEAM
1547     { 0, 0, SAL_RESID_POINTER_HELP },               // POINTER_HELP
1548     { 0, 0, SAL_RESID_POINTER_CROSS },              // POINTER_CROSS
1549     { 0, 0, SAL_RESID_POINTER_MOVE },               // POINTER_MOVE
1550     { 0, SPTR_SIZENS, 0 },                          // POINTER_NSIZE
1551     { 0, SPTR_SIZENS, 0 },                          // POINTER_SSIZE
1552     { 0, SPTR_SIZEWE, 0 },                          // POINTER_WSIZE
1553     { 0, SPTR_SIZEWE, 0 },                          // POINTER_ESIZE
1554     { 0, SPTR_SIZENWSE, 0 },                        // POINTER_NWSIZE
1555     { 0, SPTR_SIZENESW, 0 },                        // POINTER_NESIZE
1556     { 0, SPTR_SIZENESW, 0 },                        // POINTER_SWSIZE
1557     { 0, SPTR_SIZENWSE, 0 },                        // POINTER_SESIZE
1558     { 0, SPTR_SIZENS, 0 },                          // POINTER_WINDOW_NSIZE
1559     { 0, SPTR_SIZENS, 0 },                          // POINTER_WINDOW_SSIZE
1560     { 0, SPTR_SIZEWE, 0 },                          // POINTER_WINDOW_WSIZE
1561     { 0, SPTR_SIZEWE, 0 },                          // POINTER_WINDOW_ESIZE
1562     { 0, SPTR_SIZENWSE, 0 },                        // POINTER_WINDOW_NWSIZE
1563     { 0, SPTR_SIZENESW, 0 },                        // POINTER_WINDOW_NESIZE
1564     { 0, SPTR_SIZENESW, 0 },                        // POINTER_WINDOW_SWSIZE
1565     { 0, SPTR_SIZENWSE, 0 },                        // POINTER_WINDOW_SESIZE
1566     { 0, 0, SAL_RESID_POINTER_HSPLIT },             // POINTER_HSPLIT
1567     { 0, 0, SAL_RESID_POINTER_VSPLIT },             // POINTER_VSPLIT
1568     { 0, 0, SAL_RESID_POINTER_HSIZEBAR },           // POINTER_HSIZEBAR
1569     { 0, 0, SAL_RESID_POINTER_VSIZEBAR },           // POINTER_VSIZEBAR
1570     { 0, 0, SAL_RESID_POINTER_HAND },               // POINTER_HAND
1571     { 0, 0, SAL_RESID_POINTER_REFHAND },            // POINTER_REFHAND
1572     { 0, 0, SAL_RESID_POINTER_PEN },                // POINTER_PEN
1573     { 0, 0, SAL_RESID_POINTER_MAGNIFY },            // POINTER_MAGNIFY
1574     { 0, 0, SAL_RESID_POINTER_FILL },               // POINTER_FILL
1575     { 0, 0, SAL_RESID_POINTER_ROTATE },             // POINTER_ROTATE
1576     { 0, 0, SAL_RESID_POINTER_HSHEAR },             // POINTER_HSHEAR
1577     { 0, 0, SAL_RESID_POINTER_VSHEAR },             // POINTER_VSHEAR
1578     { 0, 0, SAL_RESID_POINTER_MIRROR },             // POINTER_MIRROR
1579     { 0, 0, SAL_RESID_POINTER_CROOK },              // POINTER_CROOK
1580     { 0, 0, SAL_RESID_POINTER_CROP },               // POINTER_CROP
1581     { 0, 0, SAL_RESID_POINTER_MOVEPOINT },          // POINTER_MOVEPOINT
1582     { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT },   // POINTER_MOVEBEZIERWEIGHT
1583     { 0, 0, SAL_RESID_POINTER_MOVEDATA },           // POINTER_MOVEDATA
1584     { 0, 0, SAL_RESID_POINTER_COPYDATA },           // POINTER_COPYDATA
1585     { 0, 0, SAL_RESID_POINTER_LINKDATA },           // POINTER_LINKDATA
1586     { 0, 0, SAL_RESID_POINTER_MOVEDATALINK },       // POINTER_MOVEDATALINK
1587     { 0, 0, SAL_RESID_POINTER_COPYDATALINK },       // POINTER_COPYDATALINK
1588     { 0, 0, SAL_RESID_POINTER_MOVEFILE },           // POINTER_MOVEFILE
1589     { 0, 0, SAL_RESID_POINTER_COPYFILE },           // POINTER_COPYFILE
1590     { 0, 0, SAL_RESID_POINTER_LINKFILE },           // POINTER_LINKFILE
1591     { 0, 0, SAL_RESID_POINTER_MOVEFILELINK },       // POINTER_MOVEFILELINK
1592     { 0, 0, SAL_RESID_POINTER_COPYFILELINK },       // POINTER_COPYFILELINK
1593     { 0, 0, SAL_RESID_POINTER_MOVEFILES },          // POINTER_MOVEFILES
1594     { 0, 0, SAL_RESID_POINTER_COPYFILES },          // POINTER_COPYFILES
1595     { 0, SPTR_ILLEGAL, 0 },                         // POINTER_NOTALLOWED
1596     { 0, 0, SAL_RESID_POINTER_DRAW_LINE },          // POINTER_DRAW_LINE
1597     { 0, 0, SAL_RESID_POINTER_DRAW_RECT },          // POINTER_DRAW_RECT
1598     { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON },       // POINTER_DRAW_POLYGON
1599     { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER },        // POINTER_DRAW_BEZIER
1600     { 0, 0, SAL_RESID_POINTER_DRAW_ARC },           // POINTER_DRAW_ARC
1601     { 0, 0, SAL_RESID_POINTER_DRAW_PIE },           // POINTER_DRAW_PIE
1602     { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT },     // POINTER_DRAW_CIRCLECUT
1603     { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE },       // POINTER_DRAW_ELLIPSE
1604     { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND },      // POINTER_DRAW_FREEHAND
1605     { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT },       // POINTER_DRAW_CONNECT
1606     { 0, 0, SAL_RESID_POINTER_DRAW_TEXT },          // POINTER_DRAW_TEXT
1607     { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION },       // POINTER_DRAW_CAPTION
1608     { 0, 0, SAL_RESID_POINTER_CHART },              // POINTER_CHART
1609     { 0, 0, SAL_RESID_POINTER_DETECTIVE },          // POINTER_DETECTIVE
1610     { 0, 0, SAL_RESID_POINTER_PIVOT_COL },          // POINTER_PIVOT_COL
1611     { 0, 0, SAL_RESID_POINTER_PIVOT_ROW },          // POINTER_PIVOT_ROW
1612     { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD },        // POINTER_PIVOT_FIELD
1613     { 0, 0, SAL_RESID_POINTER_CHAIN },              // POINTER_CHAIN
1614     { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED },   // POINTER_CHAIN_NOTALLOWED
1615     { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE },     // POINTER_TIMEEVENT_MOVE
1616     { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE },     // POINTER_TIMEEVENT_SIZE
1617     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N },       // POINTER_AUTOSCROLL_N
1618     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S },       // POINTER_AUTOSCROLL_S
1619     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W },       // POINTER_AUTOSCROLL_W
1620     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E },       // POINTER_AUTOSCROLL_E
1621     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW },      // POINTER_AUTOSCROLL_NW
1622     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE },      // POINTER_AUTOSCROLL_NE
1623     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW },      // POINTER_AUTOSCROLL_SW
1624     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE },      // POINTER_AUTOSCROLL_SE
1625     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS },      // POINTER_AUTOSCROLL_NS
1626     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE },      // POINTER_AUTOSCROLL_WE
1627     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE },     // POINTER_AUTOSCROLL_NSWE
1628     { 0, 0, SAL_RESID_POINTER_AIRBRUSH },           // POINTER_AIRBRUSH
1629     { 0, 0, SAL_RESID_POINTER_TEXT_VERTICAL },      // POINTER_TEXT_VERTICAL
1630     { 0, 0, SAL_RESID_POINTER_PIVOT_DELETE },       // POINTER_PIVOT_DELETE
1631 
1632     // --> FME 2004-07-30 #i32329# Enhanced table selection
1633     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_S },       // POINTER_TAB_SELECT_S
1634     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_E },       // POINTER_TAB_SELECT_E
1635     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SE },      // POINTER_TAB_SELECT_SE
1636     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_W },       // POINTER_TAB_SELECT_W
1637     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SW },      // POINTER_TAB_SELECT_SW
1638     // <--
1639 
1640     // --> FME 2004-08-16 #i20119# Paintbrush tool
1641     { 0, 0, SAL_RESID_POINTER_PAINTBRUSH }          // POINTER_PAINTBRUSH
1642     // <--
1643     };
1644 
1645 #if POINTER_COUNT != 94
1646 #error New Pointer must be defined!
1647 #endif
1648 
1649 	//debug_printf("Os2SalFrame::SetPointer\n");
1650 
1651     // Mousepointer loaded ?
1652     if ( !aImplPtrTab[ePointerStyle].mhPointer )
1653     {
1654         if ( aImplPtrTab[ePointerStyle].mnOwnId )
1655             aImplPtrTab[ePointerStyle].mhPointer = ImplLoadSalCursor( (ULONG)aImplPtrTab[ePointerStyle].mnOwnId );
1656         else
1657             aImplPtrTab[ePointerStyle].mhPointer = WinQuerySysPointer( HWND_DESKTOP, aImplPtrTab[ePointerStyle].mnSysId, FALSE );
1658     }
1659 	if (aImplPtrTab[ePointerStyle].mhPointer == 0) {
1660 		debug_printf( "SetPointer ePointerStyle %d unknown\n", ePointerStyle);
1661 		aImplPtrTab[ePointerStyle].mhPointer = SPTR_ICONERROR;
1662 	}
1663 
1664     // Unterscheidet sich der Mauspointer, dann den neuen setzen
1665     if ( mhPointer != aImplPtrTab[ePointerStyle].mhPointer )
1666     {
1667         mhPointer = aImplPtrTab[ePointerStyle].mhPointer;
1668         WinSetPointer( HWND_DESKTOP, mhPointer );
1669     }
1670 }
1671 
1672 // -----------------------------------------------------------------------
1673 
1674 void Os2SalFrame::CaptureMouse( BOOL bCapture )
1675 {
1676 #if OSL_DEBUG_LEVEL>10
1677 	_bCapture=bCapture;
1678 	debug_printf("Os2SalFrame::CaptureMouse bCapture %d\n", bCapture);
1679 #endif
1680     if ( bCapture )
1681         WinSetCapture( HWND_DESKTOP, mhWndClient );
1682     else
1683         WinSetCapture( HWND_DESKTOP, 0 );
1684 }
1685 
1686 // -----------------------------------------------------------------------
1687 
1688 void Os2SalFrame::SetPointerPos( long nX, long nY )
1689 {
1690     POINTL aPt;
1691     aPt.x = nX;
1692     aPt.y = mnHeight - nY - 1;  // convert sal coords to sys
1693     WinMapWindowPoints( mhWndClient, HWND_DESKTOP, &aPt, 1 );
1694     WinSetPointerPos( HWND_DESKTOP, aPt.x, aPt.y );
1695 }
1696 
1697 // -----------------------------------------------------------------------
1698 
1699 void Os2SalFrame::Flush()
1700 {
1701 }
1702 
1703 // -----------------------------------------------------------------------
1704 
1705 void Os2SalFrame::Sync()
1706 {
1707 }
1708 
1709 // -----------------------------------------------------------------------
1710 
1711 void Os2SalFrame::SetInputContext( SalInputContext* pContext )
1712 {
1713 #ifdef ENABLE_IME
1714     SalIMEData* pIMEData = GetSalIMEData();
1715     if ( pIMEData )
1716     {
1717         HWND hWnd = mhWndClient;
1718         HIMI hIMI = 0;
1719         pIMEData->mpGetIME( hWnd, &hIMI );
1720         if ( hIMI )
1721         {
1722             ULONG nInputMode;
1723             ULONG nConversionMode;
1724             if ( 0 == pIMEData->mpQueryIMEMode( hIMI, &nInputMode, &nConversionMode ) )
1725             {
1726                 if ( pContext->mnOptions & SAL_INPUTCONTEXT_TEXT )
1727                 {
1728                     nInputMode &= ~IMI_IM_IME_DISABLE;
1729                     if ( pContext->mnOptions & SAL_INPUTCONTEXT_EXTTEXTINPUT_OFF )
1730                         nInputMode &= ~IMI_IM_IME_ON;
1731 // !!! Da derzeit ueber das OS2-IME-UI der IME-Mode nicht einschaltbar ist !!!
1732 //                    if ( SAL_INPUTCONTEXT_EXTTEXTINPUT_ON )
1733                         nInputMode |= IMI_IM_IME_ON;
1734                 }
1735                 else
1736                     nInputMode |= IMI_IM_IME_DISABLE;
1737                 pIMEData->mpSetIMEMode( hIMI, nInputMode, nConversionMode );
1738             }
1739 
1740             pIMEData->mpReleaseIME( hWnd, hIMI );
1741         }
1742     }
1743 #endif
1744 }
1745 
1746 // -----------------------------------------------------------------------
1747 #if 0
1748 void Os2SalFrame::UpdateExtTextInputArea()
1749 {
1750 #ifdef ENABLE_IME
1751 #endif
1752 }
1753 #endif
1754 
1755 // -----------------------------------------------------------------------
1756 
1757 void Os2SalFrame::EndExtTextInput( USHORT nFlags )
1758 {
1759 #ifdef ENABLE_IME
1760     SalIMEData* pIMEData = GetSalIMEData();
1761     if ( pIMEData )
1762     {
1763         HWND hWnd = mhWndClient;
1764         HIMI hIMI = 0;
1765         pIMEData->mpGetIME( hWnd, &hIMI );
1766         if ( hIMI )
1767         {
1768             ULONG nIndex;
1769             if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE )
1770                 nIndex = CNV_COMPLETE;
1771             else
1772                 nIndex = CNV_CANCEL;
1773 
1774             pIMEData->mpRequestIME( hIMI, REQ_CONVERSIONSTRING, nIndex, 0 );
1775             pIMEData->mpReleaseIME( hWnd, hIMI );
1776         }
1777     }
1778 #endif
1779 }
1780 
1781 // -----------------------------------------------------------------------
1782 
1783 XubString Os2SalFrame::GetKeyName( USHORT nCode )
1784 {
1785     if ( eImplKeyboardLanguage == LANGUAGE_DONTKNOW )
1786         eImplKeyboardLanguage = MsLangId::getSystemLanguage();
1787 
1788     XubString        aKeyCode;
1789     XubString        aCode;
1790     const sal_Unicode**    pLangTab = ImplGetLangTab( eImplKeyboardLanguage );
1791 
1792     if ( nCode & KEY_SHIFT )
1793         aKeyCode = pLangTab[LSTR_KEY_SHIFT];
1794 
1795     if ( nCode & KEY_MOD1 )
1796     {
1797         if ( aKeyCode.Len() == 0 )
1798             aKeyCode = pLangTab[LSTR_KEY_CTRL];
1799         else
1800         {
1801             aKeyCode += '+';
1802             aKeyCode += pLangTab[LSTR_KEY_CTRL];
1803         }
1804     }
1805 
1806     if ( nCode & KEY_MOD2 )
1807     {
1808         if ( aKeyCode.Len() == 0 )
1809             aKeyCode = pLangTab[LSTR_KEY_ALT];
1810         else
1811         {
1812             aKeyCode += '+';
1813             aKeyCode += pLangTab[LSTR_KEY_ALT];
1814         }
1815     }
1816 
1817     USHORT nKeyCode = nCode & 0x0FFF;
1818     if ( (nKeyCode >= KEY_0) && (nKeyCode <= KEY_9) )
1819         aCode = sal::static_int_cast<sal_Char>('0' + (nKeyCode - KEY_0));
1820     else if ( (nKeyCode >= KEY_A) && (nKeyCode <= KEY_Z) )
1821         aCode = sal::static_int_cast<sal_Char>('A' + (nKeyCode - KEY_A));
1822     else if ( (nKeyCode >= KEY_F1) && (nKeyCode <= KEY_F26) )
1823     {
1824 		aCode += 'F';
1825         if ( (nKeyCode >= KEY_F1) && (nKeyCode <= KEY_F9) )
1826         {
1827             aCode += sal::static_int_cast<sal_Char>('1' + (nKeyCode - KEY_F1));
1828         }
1829         else if ( (nKeyCode >= KEY_F10) && (nKeyCode <= KEY_F19) )
1830         {
1831             aCode += '1';
1832             aCode += sal::static_int_cast<sal_Char>('0' + (nKeyCode - KEY_F10));
1833         }
1834         else
1835         {
1836             aCode += '2';
1837             aCode += sal::static_int_cast<sal_Char>('0' + (nKeyCode - KEY_F20));
1838         }
1839     }
1840     else
1841     {
1842 		switch ( nKeyCode )
1843 		{
1844 			case KEY_DOWN:
1845 				aCode = pLangTab[LSTR_KEY_DOWN];
1846 				break;
1847 			case KEY_UP:
1848 				aCode = pLangTab[LSTR_KEY_UP];
1849 				break;
1850 			case KEY_LEFT:
1851 				aCode = pLangTab[LSTR_KEY_LEFT];
1852 				break;
1853 			case KEY_RIGHT:
1854 				aCode = pLangTab[LSTR_KEY_RIGHT];
1855 				break;
1856 			case KEY_HOME:
1857 				aCode = pLangTab[LSTR_KEY_HOME];
1858 				break;
1859 			case KEY_END:
1860 				aCode = pLangTab[LSTR_KEY_END];
1861 				break;
1862 			case KEY_PAGEUP:
1863 				aCode = pLangTab[LSTR_KEY_PAGEUP];
1864 				break;
1865 			case KEY_PAGEDOWN:
1866 				aCode = pLangTab[LSTR_KEY_PAGEDOWN];
1867 				break;
1868 			case KEY_RETURN:
1869 				aCode = pLangTab[LSTR_KEY_RETURN];
1870 				break;
1871 			case KEY_ESCAPE:
1872 				aCode = pLangTab[LSTR_KEY_ESC];
1873 				break;
1874 			case KEY_TAB:
1875 				aCode = pLangTab[LSTR_KEY_TAB];
1876 				break;
1877 			case KEY_BACKSPACE:
1878 				aCode = pLangTab[LSTR_KEY_BACKSPACE];
1879 				break;
1880 			case KEY_SPACE:
1881 				aCode = pLangTab[LSTR_KEY_SPACE];
1882 				break;
1883 			case KEY_INSERT:
1884 				aCode = pLangTab[LSTR_KEY_INSERT];
1885 				break;
1886 			case KEY_DELETE:
1887 				aCode = pLangTab[LSTR_KEY_DELETE];
1888 				break;
1889 
1890 			case KEY_ADD:
1891 				aCode += '+';
1892 				break;
1893 			case KEY_SUBTRACT:
1894 				aCode += '-';
1895 				break;
1896 			case KEY_MULTIPLY:
1897 				aCode += '*';
1898 				break;
1899 			case KEY_DIVIDE:
1900 				aCode += '/';
1901 				break;
1902 			case KEY_POINT:
1903 				aCode += '.';
1904 				break;
1905 			case KEY_COMMA:
1906 				aCode += ',';
1907 				break;
1908 			case KEY_LESS:
1909 				aCode += '<';
1910 				break;
1911 			case KEY_GREATER:
1912 				aCode += '>';
1913 				break;
1914 			case KEY_EQUAL:
1915 				aCode += '=';
1916 				break;
1917 		}
1918 	}
1919 
1920     if ( aCode.Len() )
1921     {
1922         if ( aKeyCode.Len() == 0 )
1923             aKeyCode = aCode;
1924         else
1925         {
1926             aKeyCode += '+';
1927             aKeyCode += aCode;
1928         }
1929     }
1930 
1931     return aKeyCode;
1932 }
1933 
1934 // -----------------------------------------------------------------------
1935 
1936 XubString Os2SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode )
1937 {
1938     return GetKeyName( nKeyCode );
1939 }
1940 
1941 // -----------------------------------------------------------------------
1942 
1943 inline long ImplOS2ColorToSal( long nOS2Color )
1944 {
1945     return MAKE_SALCOLOR( (BYTE)( nOS2Color>>16), (BYTE)(nOS2Color>>8), (BYTE)nOS2Color );
1946 }
1947 
1948 // -----------------------------------------------------------------------
1949 
1950 static USHORT ImplMouseSysValueToSAL( int iSysValue, USHORT& rCode, USHORT& rClicks, BOOL& rDown )
1951 {
1952     LONG lValue = WinQuerySysValue( HWND_DESKTOP, iSysValue );
1953 
1954     rCode   = 0;
1955     rClicks = 1;
1956     rDown   = TRUE;
1957 
1958     switch ( lValue & 0xFFFF )
1959     {
1960         case WM_BUTTON1UP:
1961         case WM_BUTTON1CLICK:
1962             rCode = MOUSE_LEFT;
1963             rDown = FALSE;
1964             break;
1965         case WM_BUTTON1DOWN:
1966         case WM_BUTTON1MOTIONSTART:
1967             rCode = MOUSE_LEFT;
1968             break;
1969         case WM_BUTTON1DBLCLK:
1970             rCode = MOUSE_LEFT;
1971             rClicks = 2;
1972             break;
1973 
1974         case WM_BUTTON2UP:
1975         case WM_BUTTON2CLICK:
1976             rCode = MOUSE_RIGHT;
1977             rDown = FALSE;
1978             break;
1979         case WM_BUTTON2DOWN:
1980         case WM_BUTTON2MOTIONSTART:
1981             rCode = MOUSE_RIGHT;
1982             break;
1983         case WM_BUTTON2DBLCLK:
1984             rCode = MOUSE_RIGHT;
1985             rClicks = 2;
1986             break;
1987 
1988         case WM_BUTTON3UP:
1989         case WM_BUTTON3CLICK:
1990             rCode = MOUSE_MIDDLE;
1991             rDown = FALSE;
1992             break;
1993         case WM_BUTTON3DOWN:
1994         case WM_BUTTON3MOTIONSTART:
1995             rCode = MOUSE_MIDDLE;
1996             break;
1997         case WM_BUTTON3DBLCLK:
1998             rCode = MOUSE_MIDDLE;
1999             rClicks = 2;
2000             break;
2001     }
2002 
2003     if ( !rCode )
2004         return FALSE;
2005 
2006     lValue = (lValue & 0xFFFF0000) >> 16;
2007     if ( lValue != 0xFFFF )
2008     {
2009         if ( lValue & KC_SHIFT )
2010             rCode |= KEY_SHIFT;
2011         if ( lValue & KC_CTRL )
2012             rCode |= KEY_MOD1;
2013         if ( lValue & KC_ALT )
2014             rCode |= KEY_MOD2;
2015     }
2016 
2017     return TRUE;
2018 }
2019 
2020 // -----------------------------------------------------------------------
2021 
2022 static BOOL ImplSalIsSameColor( const Color& rColor1, const Color& rColor2 )
2023 {
2024     ULONG nWrong = 0;
2025     nWrong += Abs( (short)rColor1.GetRed()-(short)rColor2.GetRed() );
2026     nWrong += Abs( (short)rColor1.GetGreen()-(short)rColor2.GetGreen() );
2027     nWrong += Abs( (short)rColor1.GetBlue()-(short)rColor2.GetBlue() );
2028     return (nWrong < 30);
2029 }
2030 
2031 // -----------------------------------------------------------------------
2032 
2033 static BOOL ImplOS2NameFontToVCLFont( const char* pFontName, Font& rFont )
2034 {
2035     char aNumBuf[10];
2036     int  nNumBufLen = 0;
2037 
2038     while ( *pFontName && (*pFontName != '.') &&
2039             (nNumBufLen < sizeof(aNumBuf)-1) )
2040     {
2041         aNumBuf[nNumBufLen] = *pFontName;
2042         nNumBufLen++;
2043         pFontName++;
2044     }
2045     aNumBuf[nNumBufLen] = '\0';
2046 
2047     pFontName++;
2048     while ( *pFontName == ' ' )
2049         pFontName++;
2050 
2051     int nFontHeight = atoi( aNumBuf );
2052     int nFontNameLen = strlen( pFontName );
2053     if ( nFontHeight && nFontNameLen )
2054     {
2055         rFont.SetFamily( FAMILY_DONTKNOW );
2056         rFont.SetWeight( WEIGHT_NORMAL );
2057         rFont.SetItalic( ITALIC_NONE );
2058 		// search for a style embedded in the name, e.g. 'WarpSans Bold'
2059 		// because we need to split the style from the family name
2060 		if (strstr( pFontName, " Bold")
2061 			|| strstr( pFontName, " Italic")
2062 			|| strstr( pFontName, "-Normal"))
2063 		{
2064 			char* fontName = strdup( pFontName);
2065 			char* style = strstr( fontName, " Bold");
2066 			if (style)
2067 				rFont.SetWeight( WEIGHT_BOLD );
2068 
2069 			if (!style)
2070 				style = strstr( fontName, " Italic");
2071 			if (style)
2072 				rFont.SetItalic( ITALIC_NORMAL );
2073 
2074 			if (!style)
2075 				style = strstr( fontName, "-Normal");
2076 			// store style, skip whitespace char
2077 			rFont.SetStyleName( ::rtl::OStringToOUString ( style+1, gsl_getSystemTextEncoding()) );
2078 			// truncate name
2079 			*style = 0;
2080 			// store family name
2081 			rFont.SetName( ::rtl::OStringToOUString ( fontName, gsl_getSystemTextEncoding()) );
2082 			free( fontName);
2083 		}
2084 		else
2085 		{
2086 			rFont.SetName( ::rtl::OStringToOUString (pFontName, gsl_getSystemTextEncoding()) );
2087 			rFont.SetStyleName( ::rtl::OStringToOUString ("", gsl_getSystemTextEncoding()) );
2088 		}
2089 
2090         rFont.SetSize( Size( 0, nFontHeight ) );
2091         return TRUE;
2092     }
2093     else
2094         return FALSE;
2095 }
2096 
2097 // -----------------------------------------------------------------------
2098 
2099 void Os2SalFrame::UpdateSettings( AllSettings& rSettings )
2100 {
2101     static char aControlPanel[] = "PM_ControlPanel";
2102     static char aSystemFonts[]  = "PM_SystemFonts";
2103     char aDummyStr[] = "";
2104 
2105     // --- Mouse setting ---
2106     USHORT  nCode;
2107     USHORT  nClicks;
2108     BOOL    bDown;
2109     MouseSettings aMouseSettings = rSettings.GetMouseSettings();
2110     aMouseSettings.SetDoubleClickTime( WinQuerySysValue( HWND_DESKTOP, SV_DBLCLKTIME ) );
2111     if ( ImplMouseSysValueToSAL( SV_BEGINDRAG, nCode, nClicks, bDown ) )
2112         aMouseSettings.SetStartDragCode( nCode );
2113     if ( ImplMouseSysValueToSAL( SV_CONTEXTMENU, nCode, nClicks, bDown ) )
2114     {
2115         aMouseSettings.SetContextMenuCode( nCode );
2116         aMouseSettings.SetContextMenuClicks( nClicks );
2117         aMouseSettings.SetContextMenuDown( bDown );
2118     }
2119     aMouseSettings.SetButtonStartRepeat( WinQuerySysValue( HWND_DESKTOP, SV_FIRSTSCROLLRATE ) );
2120     aMouseSettings.SetButtonRepeat( WinQuerySysValue( HWND_DESKTOP, SV_SCROLLRATE ) );
2121     rSettings.SetMouseSettings( aMouseSettings );
2122 
2123     // --- Style settings ---
2124     StyleSettings aStyleSettings = rSettings.GetStyleSettings();
2125     // General settings
2126     LONG    nDisplayTime = PrfQueryProfileInt( HINI_PROFILE, (PSZ)aControlPanel, (PSZ)"LogoDisplayTime", -1 );
2127     ULONG   nSalDisplayTime;
2128     if ( nDisplayTime < 0 )
2129         nSalDisplayTime = LOGO_DISPLAYTIME_STARTTIME;
2130     else if ( !nDisplayTime )
2131         nSalDisplayTime = LOGO_DISPLAYTIME_NOLOGO;
2132     else
2133         nSalDisplayTime = (ULONG)nDisplayTime;
2134     aStyleSettings.SetLogoDisplayTime( nSalDisplayTime );
2135 
2136     aStyleSettings.SetCursorBlinkTime( WinQuerySysValue( HWND_DESKTOP, SV_CURSORRATE ) );
2137     ULONG nDragFullOptions = aStyleSettings.GetDragFullOptions();
2138     if ( WinQuerySysValue( HWND_DESKTOP, SV_DYNAMICDRAG ) )
2139         nDragFullOptions |= DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT;
2140     else
2141         nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT);
2142     aStyleSettings.SetDragFullOptions( nDragFullOptions );
2143 
2144     // Size settings
2145     aStyleSettings.SetScrollBarSize( WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL ) );
2146     aStyleSettings.SetTitleHeight( WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) );
2147 
2148     // Color settings
2149     aStyleSettings.SetFaceColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) );
2150     aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() );
2151     aStyleSettings.SetLightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONLIGHT, 0 ) ) );
2152     aStyleSettings.SetLightBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) );
2153     aStyleSettings.SetShadowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONDARK, 0 ) ) );
2154     aStyleSettings.SetDarkShadowColor( Color( COL_BLACK ) );
2155     aStyleSettings.SetDialogColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0 ) ) );
2156     aStyleSettings.SetButtonTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) );
2157     aStyleSettings.SetActiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLE, 0 ) ) );
2158     aStyleSettings.SetActiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLETEXT, 0 ) ) );
2159     aStyleSettings.SetActiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVEBORDER, 0 ) ) );
2160     aStyleSettings.SetDeactiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLE, 0 ) ) );
2161     aStyleSettings.SetDeactiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLETEXT, 0 ) ) );
2162     aStyleSettings.SetDeactiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVEBORDER, 0 ) ) );
2163     aStyleSettings.SetMenuColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENU, 0 ) ) );
2164     aStyleSettings.SetMenuTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) );
2165     aStyleSettings.SetMenuBarTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) );
2166     aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() );
2167     aStyleSettings.SetRadioCheckTextColor( aStyleSettings.GetButtonTextColor() );
2168     aStyleSettings.SetGroupTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWSTATICTEXT, 0 ) ) );
2169     aStyleSettings.SetLabelTextColor( aStyleSettings.GetGroupTextColor() );
2170     aStyleSettings.SetInfoTextColor( aStyleSettings.GetGroupTextColor() );
2171     aStyleSettings.SetWindowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOW, 0 ) ) );
2172     aStyleSettings.SetActiveTabColor( aStyleSettings.GetWindowColor() );
2173     aStyleSettings.SetWindowTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWTEXT, 0 ) ) );
2174     aStyleSettings.SetFieldColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ENTRYFIELD, 0 ) ) );
2175     aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() );
2176     aStyleSettings.SetDisableColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUDISABLEDTEXT, 0 ) ) );
2177     aStyleSettings.SetHighlightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_HILITEBACKGROUND, 0 ) ) );
2178     aStyleSettings.SetHighlightTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_HILITEFOREGROUND, 0 ) ) );
2179     Color aMenuHighColor = ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITEBGND, 0 ) );
2180     if ( ImplSalIsSameColor( aMenuHighColor, aStyleSettings.GetMenuColor() ) )
2181     {
2182         aStyleSettings.SetMenuHighlightColor( Color( COL_BLUE ) );
2183         aStyleSettings.SetMenuHighlightTextColor( Color( COL_WHITE ) );
2184     }
2185     else
2186     {
2187         aStyleSettings.SetMenuHighlightColor( aMenuHighColor );
2188         aStyleSettings.SetMenuHighlightTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITE, 0 ) ) );
2189     }
2190     // Checked-Color berechnen
2191     Color   aColor1 = aStyleSettings.GetFaceColor();
2192     Color   aColor2 = aStyleSettings.GetLightColor();
2193     BYTE    nRed    = (BYTE)(((USHORT)aColor1.GetRed()   + (USHORT)aColor2.GetRed())/2);
2194     BYTE    nGreen  = (BYTE)(((USHORT)aColor1.GetGreen() + (USHORT)aColor2.GetGreen())/2);
2195     BYTE    nBlue   = (BYTE)(((USHORT)aColor1.GetBlue()  + (USHORT)aColor2.GetBlue())/2);
2196     aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) );
2197 
2198     // Fonts updaten
2199     Font    aFont;
2200     char    aFontNameBuf[255];
2201     aFont = aStyleSettings.GetMenuFont();
2202     if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"Menus", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 )
2203     {
2204         if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) {
2205 #if 0
2206 			// Add Workplace Sans if not already listed
2207             if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND )
2208             {
2209                 XubString aFontName = aFont.GetName();
2210                 aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 );
2211                 aFont.SetName( aFontName );
2212                 aFont.SetSize( Size( 0, 9 ) );
2213             }
2214 #endif
2215             aStyleSettings.SetMenuFont( aFont );
2216 		}
2217     }
2218     aFont = aStyleSettings.GetIconFont();
2219     if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"IconText", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 )
2220     {
2221         if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) )
2222             aStyleSettings.SetIconFont( aFont );
2223     }
2224     aFont = aStyleSettings.GetTitleFont();
2225     if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"WindowTitles", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 )
2226     {
2227         if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) )
2228         {
2229             // Add Workplace Sans if not already listed
2230             if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND )
2231             {
2232                 XubString aFontName = aFont.GetName();
2233                 aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 );
2234                 aFont.SetName( aFontName );
2235                 aFont.SetSize( Size( 0, 9 ) );
2236 				aFont.SetWeight( WEIGHT_BOLD );
2237 				aFont.SetItalic( ITALIC_NONE );
2238             }
2239             aStyleSettings.SetTitleFont( aFont );
2240             aStyleSettings.SetFloatTitleFont( aFont );
2241         }
2242     }
2243     aFont = aStyleSettings.GetAppFont();
2244     if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"WindowText", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 )
2245     {
2246         if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) )
2247         {
2248             Font aHelpFont = aFont;
2249             aHelpFont.SetName( (sal_Unicode*)L"Helv;WarpSans" );
2250             aHelpFont.SetSize( Size( 0, 8 ) );
2251             aHelpFont.SetWeight( WEIGHT_NORMAL );
2252             aHelpFont.SetItalic( ITALIC_NONE );
2253             aStyleSettings.SetHelpFont( aHelpFont );
2254 
2255             // Add Workplace Sans if not already listed
2256             if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND )
2257             {
2258                 XubString aFontName = aFont.GetName();
2259                 aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 );
2260                 aFont.SetName( aFontName );
2261                 aFont.SetSize( Size( 0, 9 ) );
2262             }
2263             aStyleSettings.SetAppFont( aFont );
2264             aStyleSettings.SetToolFont( aFont );
2265             aStyleSettings.SetLabelFont( aFont );
2266             aStyleSettings.SetInfoFont( aFont );
2267             aStyleSettings.SetRadioCheckFont( aFont );
2268             aStyleSettings.SetPushButtonFont( aFont );
2269             aStyleSettings.SetFieldFont( aFont );
2270             aStyleSettings.SetGroupFont( aFont );
2271         }
2272     }
2273 
2274     rSettings.SetStyleSettings( aStyleSettings );
2275 }
2276 
2277 // -----------------------------------------------------------------------
2278 
2279 SalBitmap* Os2SalFrame::SnapShot()
2280 {
2281 debug_printf("Os2SalFrame::SnapShot\n");
2282 return NULL;
2283 }
2284 
2285 // -----------------------------------------------------------------------
2286 
2287 const SystemEnvData* Os2SalFrame::GetSystemData() const
2288 {
2289     return &maSysData;
2290 }
2291 
2292 // -----------------------------------------------------------------------
2293 
2294 void Os2SalFrame::Beep( SoundType eSoundType )
2295 {
2296     static ULONG aImplSoundTab[5] =
2297     {
2298         WA_NOTE,                        // SOUND_DEFAULT
2299         WA_NOTE,                        // SOUND_INFO
2300         WA_WARNING,                     // SOUND_WARNING
2301         WA_ERROR,                       // SOUND_ERROR
2302         WA_NOTE                         // SOUND_QUERY
2303     };
2304 
2305 #if 0
2306 #if SOUND_COUNT != 5
2307 #error New Sound must be defined!
2308 #endif
2309 #endif
2310 
2311 	debug_printf("Os2SalFrame::Beep %d\n", eSoundType);
2312     WinAlarm( HWND_DESKTOP, aImplSoundTab[eSoundType] );
2313 }
2314 
2315 // -----------------------------------------------------------------------
2316 
2317 SalFrame::SalPointerState Os2SalFrame::GetPointerState()
2318 {
2319     SalPointerState aState;
2320     aState.mnState = 0;
2321 
2322     // MausModus feststellen und setzen
2323     if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000 )
2324         aState.mnState |= MOUSE_LEFT;
2325     if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 )
2326         aState.mnState |= MOUSE_RIGHT;
2327     if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 )
2328         aState.mnState |= MOUSE_MIDDLE;
2329     // Modifier-Tasten setzen
2330     if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 )
2331         aState.mnState |= KEY_SHIFT;
2332     if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 )
2333         aState.mnState |= KEY_MOD1;
2334     if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 )
2335         aState.mnState |= KEY_MOD2;
2336 
2337     POINTL pt;
2338     _WinQueryPointerPos( HWND_DESKTOP, &pt );
2339 
2340     aState.maPos = Point( pt.x - maGeometry.nX, pt.y - maGeometry.nY );
2341     return aState;
2342 }
2343 
2344 // -----------------------------------------------------------------------
2345 
2346 void Os2SalFrame::SetBackgroundBitmap( SalBitmap* )
2347 {
2348 }
2349 
2350 // -----------------------------------------------------------------------
2351 
2352 void SalTestMouseLeave()
2353 {
2354     SalData* pSalData = GetSalData();
2355 
2356     if ( pSalData->mhWantLeaveMsg && !::WinQueryCapture( HWND_DESKTOP ) )
2357     {
2358         POINTL aPt;
2359         WinQueryPointerPos( HWND_DESKTOP, &aPt );
2360         if ( pSalData->mhWantLeaveMsg != WinWindowFromPoint( HWND_DESKTOP, &aPt, TRUE ) )
2361             WinSendMsg( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MPFROM2SHORT( aPt.x, aPt.y ) );
2362     }
2363 }
2364 
2365 // -----------------------------------------------------------------------
2366 
2367 static long ImplHandleMouseMsg( HWND hWnd,
2368                                 UINT nMsg, MPARAM nMP1, MPARAM nMP2 )
2369 {
2370     SalMouseEvent   aMouseEvt;
2371     long            nRet;
2372     USHORT          nEvent;
2373     BOOL            bCall = TRUE;
2374     USHORT          nFlags = SHORT2FROMMP( nMP2 );
2375     Os2SalFrame* pFrame = GetWindowPtr( hWnd );
2376     if ( !pFrame )
2377         return 0;
2378 
2379     aMouseEvt.mnX       = (short)SHORT1FROMMP( nMP1 );
2380     aMouseEvt.mnY       = pFrame->mnHeight - (short)SHORT2FROMMP( nMP1 ) - 1;
2381     aMouseEvt.mnCode    = 0;
2382     aMouseEvt.mnTime    = WinQueryMsgTime( pFrame->mhAB );
2383 
2384     // MausModus feststellen und setzen
2385     if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000 )
2386         aMouseEvt.mnCode |= MOUSE_LEFT;
2387     if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 )
2388         aMouseEvt.mnCode |= MOUSE_RIGHT;
2389     if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 )
2390         aMouseEvt.mnCode |= MOUSE_MIDDLE;
2391     // Modifier-Tasten setzen
2392     if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 )
2393         aMouseEvt.mnCode |= KEY_SHIFT;
2394     if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 )
2395         aMouseEvt.mnCode |= KEY_MOD1;
2396     if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 )
2397         aMouseEvt.mnCode |= KEY_MOD2;
2398 
2399     switch ( nMsg )
2400     {
2401         case WM_MOUSEMOVE:
2402             {
2403             SalData* pSalData = GetSalData();
2404 
2405             // Da bei Druecken von Modifier-Tasten die MouseEvents
2406             // nicht zusammengefast werden (da diese durch KeyEvents
2407             // unterbrochen werden), machen wir dieses hier selber
2408             if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) )
2409             {
2410                 QMSG aTempMsg;
2411                 if ( WinPeekMsg( pSalData->mhAB, &aTempMsg,
2412                                  pFrame->mhWndClient,
2413                                  WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE ) )
2414                 {
2415                     if ( (aTempMsg.msg == WM_MOUSEMOVE) &&
2416                          (aTempMsg.mp2 == nMP2) )
2417                         return 1;
2418                 }
2419             }
2420 
2421             // Test for MouseLeave
2422             if ( pSalData->mhWantLeaveMsg &&
2423                 (pSalData->mhWantLeaveMsg != pFrame->mhWndClient) )
2424             {
2425                 POINTL aMousePoint;
2426                 WinQueryMsgPos( pFrame->mhAB, &aMousePoint );
2427                 WinSendMsg( pSalData->mhWantLeaveMsg,
2428                             SAL_MSG_MOUSELEAVE,
2429                             0, MPFROM2SHORT( aMousePoint.x, aMousePoint.y ) );
2430             }
2431             pSalData->mhWantLeaveMsg = pFrame->mhWndClient;
2432             // Start MouseLeave-Timer
2433             if ( !pSalData->mpMouseLeaveTimer )
2434             {
2435                 pSalData->mpMouseLeaveTimer = new AutoTimer;
2436                 pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT );
2437                 pSalData->mpMouseLeaveTimer->Start();
2438                 // We dont need to set a timeout handler, because we test
2439                 // for mouseleave in the timeout callback
2440             }
2441             aMouseEvt.mnButton = 0;
2442             nEvent = SALEVENT_MOUSEMOVE;
2443             }
2444             break;
2445 
2446         case SAL_MSG_MOUSELEAVE:
2447             {
2448             SalData* pSalData = GetSalData();
2449             if ( pSalData->mhWantLeaveMsg == pFrame->mhWndClient )
2450             {
2451                 pSalData->mhWantLeaveMsg = 0;
2452                 if ( pSalData->mpMouseLeaveTimer )
2453                 {
2454                     delete pSalData->mpMouseLeaveTimer;
2455                     pSalData->mpMouseLeaveTimer = NULL;
2456                 }
2457 
2458                 // Mouse-Coordinaates are relativ to the screen
2459                 POINTL aPt;
2460                 aPt.x = (short)SHORT1FROMMP( nMP2 );
2461                 aPt.y = (short)SHORT2FROMMP( nMP2 );
2462                 WinMapWindowPoints( HWND_DESKTOP, pFrame->mhWndClient, &aPt, 1 );
2463                 aPt.y = pFrame->mnHeight - aPt.y - 1;
2464                 aMouseEvt.mnX = aPt.x;
2465                 aMouseEvt.mnY = aPt.y;
2466                 aMouseEvt.mnButton = 0;
2467                 nEvent = SALEVENT_MOUSELEAVE;
2468             }
2469             else
2470                 bCall = FALSE;
2471             }
2472             break;
2473 
2474         case WM_BUTTON1DBLCLK:
2475         case WM_BUTTON1DOWN:
2476             aMouseEvt.mnButton = MOUSE_LEFT;
2477             nEvent = SALEVENT_MOUSEBUTTONDOWN;
2478             break;
2479 
2480         case WM_BUTTON2DBLCLK:
2481         case WM_BUTTON2DOWN:
2482             aMouseEvt.mnButton = MOUSE_RIGHT;
2483             nEvent = SALEVENT_MOUSEBUTTONDOWN;
2484             break;
2485 
2486         case WM_BUTTON3DBLCLK:
2487         case WM_BUTTON3DOWN:
2488             aMouseEvt.mnButton = MOUSE_MIDDLE;
2489             nEvent = SALEVENT_MOUSEBUTTONDOWN;
2490             break;
2491 
2492         case WM_BUTTON1UP:
2493             aMouseEvt.mnButton = MOUSE_LEFT;
2494             nEvent = SALEVENT_MOUSEBUTTONUP;
2495             break;
2496 
2497         case WM_BUTTON2UP:
2498             aMouseEvt.mnButton = MOUSE_RIGHT;
2499             nEvent = SALEVENT_MOUSEBUTTONUP;
2500             break;
2501 
2502         case WM_BUTTON3UP:
2503             aMouseEvt.mnButton = MOUSE_MIDDLE;
2504             nEvent = SALEVENT_MOUSEBUTTONUP;
2505             break;
2506     }
2507 
2508 	// check if this window was destroyed - this might happen if we are the help window
2509 	// and sent a mouse leave message to the application which killed the help window, ie ourself
2510 	if( !WinIsWindow( pFrame->mhAB, hWnd ) )
2511 		return 0;
2512 
2513 #if OSL_DEBUG_LEVEL>10
2514 	//if (_bCapture)
2515 		debug_printf("ImplHandleMouseMsg mouse %d,%d\n",aMouseEvt.mnX,aMouseEvt.mnY);
2516 #endif
2517 
2518     if ( bCall )
2519     {
2520         if ( nEvent == SALEVENT_MOUSEBUTTONDOWN )
2521             WinUpdateWindow( pFrame->mhWndClient );
2522 
2523         // --- RTL --- (mirror mouse pos)
2524         //if( Application::GetSettings().GetLayoutRTL() )
2525         //    aMouseEvt.mnX = pFrame->maGeometry.nWidth-1-aMouseEvt.mnX;
2526 
2527         nRet = pFrame->CallCallback( nEvent, &aMouseEvt );
2528         if ( nMsg == WM_MOUSEMOVE )
2529         {
2530             WinSetPointer( HWND_DESKTOP, pFrame->mhPointer );
2531             nRet = TRUE;
2532         }
2533     }
2534     else
2535         nRet = 0;
2536 
2537     return nRet;
2538 }
2539 
2540 // -----------------------------------------------------------------------
2541 
2542 static long ImplHandleWheelMsg( HWND hWnd, UINT nMsg, MPARAM nMP1, MPARAM nMP2 )
2543 {
2544 
2545     ImplSalYieldMutexAcquireWithWait();
2546 
2547     long        nRet = 0;
2548     Os2SalFrame*   pFrame = GetWindowPtr( hWnd );
2549     if ( pFrame )
2550     {
2551 
2552 		// Mouse-Coordinaates are relativ to the screen
2553 		POINTL aPt;
2554 		WinQueryMsgPos( pFrame->mhAB, &aPt );
2555 		WinMapWindowPoints( HWND_DESKTOP, pFrame->mhWndClient, &aPt, 1 );
2556 		aPt.y = pFrame->mnHeight - aPt.y - 1;
2557 
2558         SalWheelMouseEvent aWheelEvt;
2559 		aWheelEvt.mnTime    		= WinQueryMsgTime( pFrame->mhAB );
2560         aWheelEvt.mnX           	= aPt.x;
2561         aWheelEvt.mnY           	= aPt.y;
2562         aWheelEvt.mnCode       	 	= 0;
2563 		bool bNeg = (SHORT2FROMMP(nMP2) == SB_LINEDOWN || SHORT2FROMMP(nMP2) == SB_PAGEDOWN );
2564 		aWheelEvt.mnDelta			= bNeg ? -120 : 120;
2565 		aWheelEvt.mnNotchDelta		= bNeg ? -1 : 1;
2566 		if (SHORT2FROMMP(nMP2) == SB_PAGEUP || SHORT2FROMMP(nMP2) == SB_PAGEDOWN)
2567 			aWheelEvt.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
2568 		else
2569 			aWheelEvt.mnScrollLines = 1;
2570 
2571         if( nMsg == WM_HSCROLL )
2572             aWheelEvt.mbHorz        = TRUE;
2573 
2574 		// Modifier-Tasten setzen
2575 		if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 )
2576 			aWheelEvt.mnCode |= KEY_SHIFT;
2577 		if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 )
2578 			aWheelEvt.mnCode |= KEY_MOD1;
2579 		if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 )
2580 			aWheelEvt.mnCode |= KEY_MOD2;
2581 
2582         nRet = pFrame->CallCallback( SALEVENT_WHEELMOUSE, &aWheelEvt );
2583     }
2584 
2585     ImplSalYieldMutexRelease();
2586 
2587     return nRet;
2588 }
2589 
2590 
2591 // -----------------------------------------------------------------------
2592 
2593 static USHORT ImplSalGetKeyCode( Os2SalFrame* pFrame, MPARAM aMP1, MPARAM aMP2 )
2594 {
2595     USHORT  nKeyFlags   = SHORT1FROMMP( aMP1 );
2596     UCHAR   nCharCode   = (UCHAR)SHORT1FROMMP( aMP2 );
2597     USHORT  nKeyCode    = (UCHAR)SHORT2FROMMP( aMP2 );
2598     UCHAR   nScanCode   = (UCHAR)CHAR4FROMMP( aMP1 );
2599 	USHORT	rSVCode = 0;
2600 
2601     // Ist virtueller KeyCode gesetzt und befindet sich der KeyCode in der
2602     // Tabelle, dann mappen
2603     if ( (nKeyFlags & KC_VIRTUALKEY) && (nKeyCode < KEY_TAB_SIZE) )
2604         rSVCode = aImplTranslateKeyTab[nKeyCode];
2605 
2606     // Wenn kein KeyCode ermittelt werden konnte, versuchen wir aus dem
2607     // CharCode einen zu erzeugen
2608     if ( !rSVCode && nCharCode )
2609     {
2610         // Bei 0-9, a-z und A-Z auch KeyCode setzen
2611         if ( (nCharCode >= '0') && (nCharCode <= '9') && (!rSVCode || !(nKeyFlags & KC_SHIFT)) )
2612             rSVCode = KEYGROUP_NUM + (nCharCode-'0');
2613         else if ( (nCharCode >= 'a') && (nCharCode <= 'z') )
2614             rSVCode = KEYGROUP_ALPHA + (nCharCode-'a');
2615         else if ( (nCharCode >= 'A') && (nCharCode <= 'Z') )
2616             rSVCode = KEYGROUP_ALPHA + (nCharCode-'A');
2617         else
2618         {
2619             switch ( nCharCode )
2620             {
2621                 case '+':
2622                     rSVCode = KEY_ADD;
2623                     break;
2624                 case '-':
2625                     rSVCode = KEY_SUBTRACT;
2626                     break;
2627                 case '*':
2628                     rSVCode = KEY_MULTIPLY;
2629                     break;
2630                 case '/':
2631                     rSVCode = KEY_DIVIDE;
2632                     break;
2633                 case '.':
2634                     rSVCode = KEY_POINT;
2635                     break;
2636                 case ',':
2637                     rSVCode = KEY_COMMA;
2638                     break;
2639                 case '<':
2640                     rSVCode = KEY_LESS;
2641                     break;
2642                 case '>':
2643                     rSVCode = KEY_GREATER;
2644                     break;
2645                 case '=':
2646                     rSVCode = KEY_EQUAL;
2647                     break;
2648             }
2649         }
2650     }
2651 
2652     // "Numlock-Hack": we want to get correct keycodes from the numpad
2653     if ( (nCharCode >= '0') && (nCharCode <= '9') && !(nKeyFlags & KC_SHIFT) )
2654         rSVCode = KEYGROUP_NUM + (nCharCode-'0');
2655     if ( nCharCode == ',' )
2656         rSVCode = KEY_COMMA;
2657     if ( nCharCode == '.' )
2658         rSVCode = KEY_POINT;
2659 
2660     return rSVCode;
2661 }
2662 
2663 // -----------------------------------------------------------------------
2664 
2665 static void ImplUpdateInputLang( Os2SalFrame* pFrame )
2666 {
2667     BOOL 	bLanguageChange = FALSE;
2668     ULONG 	nLang = 0;
2669 	APIRET	rc;
2670 	UconvObject  uconv_object = NULL;
2671 	LocaleObject locale_object = NULL;
2672 	UniChar		*pinfo_item;
2673 
2674 	// we do not support change of input language while working,
2675 	// so exit if already defined (mnInputLang is a static class field)
2676 	if (pFrame->mnInputLang)
2677 		return;
2678 
2679 	// get current locale
2680 	rc = UniCreateLocaleObject(UNI_UCS_STRING_POINTER, (UniChar *)L"", &locale_object);
2681 	// get Win32 locale id and sublanguage (hex uni string)
2682 	rc = UniQueryLocaleItem(locale_object, LOCI_xWinLocale, &pinfo_item);
2683 	// convert uni string to integer
2684 	rc = UniStrtoul(locale_object, pinfo_item, &pinfo_item, 16, &nLang);
2685 	rc = UniFreeMem(pinfo_item);
2686 #if OSL_DEBUG_LEVEL>10
2687 	debug_printf("ImplUpdateInputLang nLang %04x\n", nLang);
2688 	char         char_buffer[256];
2689 	rc = UniCreateUconvObject((UniChar *)L"", &uconv_object);
2690 	rc = UniQueryLocaleItem(locale_object, LOCI_sKeyboard, &pinfo_item);
2691 	rc = UniStrFromUcs(uconv_object, char_buffer, pinfo_item, sizeof(char_buffer));
2692 	debug_printf("Keyboard name is: %s\n", char_buffer );
2693 	rc = UniFreeMem(pinfo_item);
2694 #endif
2695 	rc = UniFreeLocaleObject(locale_object);
2696 
2697 	// keep input lang up-to-date
2698 #if OSL_DEBUG_LEVEL>10
2699 	debug_printf("ImplUpdateInputLang pFrame %08x lang changed from %d to %d\n",
2700 		pFrame, pFrame->mnInputLang, nLang);
2701 #endif
2702 	pFrame->mnInputLang = nLang;
2703 }
2704 
2705 
2706 static sal_Unicode ImplGetCharCode( Os2SalFrame* pFrame, USHORT nKeyFlags,
2707 									sal_Char nCharCode, UCHAR nScanCode )
2708 {
2709     ImplUpdateInputLang( pFrame );
2710 #if OSL_DEBUG_LEVEL>10
2711     debug_printf("ImplGetCharCode nCharCode %c, %04x\n", nCharCode, nCharCode);
2712 #endif
2713     return OUString( &nCharCode, 1, gsl_getSystemTextEncoding()).toChar();
2714 }
2715 
2716 // -----------------------------------------------------------------------
2717 
2718 LanguageType Os2SalFrame::GetInputLanguage()
2719 {
2720     if( !mnInputLang )
2721         ImplUpdateInputLang( this );
2722 
2723     if( !mnInputLang )
2724         return LANGUAGE_DONTKNOW;
2725     else
2726         return (LanguageType) mnInputLang;
2727 }
2728 
2729 // -----------------------------------------------------------------------
2730 
2731 BOOL Os2SalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , KeyCode& )
2732 {
2733     // not supported yet
2734     return FALSE;
2735 }
2736 
2737 // -----------------------------------------------------------------------
2738 
2739 static sal_Unicode ImplConvertKey( Os2SalFrame* pFrame, MPARAM aMP1, MPARAM aMP2 )
2740 {
2741     USHORT  nKeyFlags   = SHORT1FROMMP( aMP1 );
2742     UCHAR   nCharCode   = (UCHAR)SHORT1FROMMP( aMP2 );
2743     USHORT  nKeyCode    = (UCHAR)SHORT2FROMMP( aMP2 );
2744     UCHAR   nScanCode   = (UCHAR)CHAR4FROMMP( aMP1 );
2745 	sal_Unicode	rSVCharCode = 0;
2746 
2747     // Ist Character-Code gesetzt
2748     // !!! Bei CTRL/ALT ist KC_CHAR nicht gesetzt, jedoch moechten wir
2749     // !!! dann auch einen CharCode und machen die Behandlung deshalb
2750     // !!! selber
2751     if ( (nKeyFlags & KC_CHAR) || (nKeyFlags & KC_CTRL) || (nKeyFlags & KC_ALT) )
2752         rSVCharCode = ImplGetCharCode( pFrame, nKeyFlags, nCharCode, nScanCode);
2753 
2754 	// ret unicode
2755 	return rSVCharCode;
2756 }
2757 
2758 // -----------------------------------------------------------------------
2759 
2760 static long ImplHandleKeyMsg( HWND hWnd,
2761                               UINT nMsg, MPARAM nMP1, MPARAM nMP2 )
2762 {
2763     static USHORT   nLastOS2KeyChar = 0;
2764     static sal_Unicode   nLastChar       = 0;
2765     USHORT          nRepeat         = CHAR3FROMMP( nMP1 ) - 1;
2766     SHORT           nFlags          = SHORT1FROMMP( nMP1 );
2767     USHORT          nModCode        = 0;
2768     USHORT          nSVCode         = 0;
2769     USHORT          nOS2KeyCode     = (UCHAR)SHORT2FROMMP( nMP2 );
2770     sal_Unicode		nSVCharCode     = 0;
2771     long            nRet            = 0;
2772 
2773     Os2SalFrame* pFrame = GetWindowPtr( hWnd );
2774     if ( !pFrame )
2775         return 0;
2776 
2777     // determine modifiers
2778     if ( nFlags & KC_SHIFT )
2779         nModCode |= KEY_SHIFT;
2780     if ( nFlags & KC_CTRL )
2781         nModCode |= KEY_MOD1;
2782     if ( nFlags & KC_ALT )
2783         nModCode |= KEY_MOD2;
2784 
2785     // Bei Shift, Control und Alt schicken wir einen KeyModChange-Event
2786     if ( (nOS2KeyCode == VK_SHIFT) || (nOS2KeyCode == VK_CTRL) ||
2787          (nOS2KeyCode == VK_ALT) || (nOS2KeyCode == VK_ALTGRAF) )
2788     {
2789         SalKeyModEvent aModEvt;
2790         aModEvt.mnTime = WinQueryMsgTime( pFrame->mhAB );
2791         aModEvt.mnCode = nModCode;
2792 #if OSL_DEBUG_LEVEL>10
2793 		debug_printf("SALEVENT_KEYMODCHANGE\n");
2794 #endif
2795         nRet = pFrame->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt );
2796     }
2797     else
2798     {
2799 		nSVCode = ImplSalGetKeyCode( pFrame, nMP1, nMP2 );
2800         nSVCharCode = ImplConvertKey( pFrame, nMP1, nMP2 );
2801 #if OSL_DEBUG_LEVEL>10
2802 		debug_printf("nSVCode %04x nSVCharCode %04x\n",nSVCode,nSVCharCode );
2803 #endif
2804 
2805         // Fuer Java muessen wir bei KeyUp einen CharCode liefern
2806         if ( nFlags & KC_KEYUP )
2807         {
2808             if ( !nSVCharCode )
2809             {
2810                 if ( nLastOS2KeyChar == nOS2KeyCode )
2811                 {
2812                     nSVCharCode     = nLastChar;
2813                     nLastOS2KeyChar = 0;
2814                     nLastChar       = 0;
2815                 }
2816             }
2817             else
2818             {
2819                 nLastOS2KeyChar = 0;
2820                 nLastChar       = 0;
2821             }
2822         }
2823         else
2824         {
2825             nLastOS2KeyChar = nOS2KeyCode;
2826             nLastChar       = nSVCharCode;
2827         }
2828 
2829         if ( nSVCode || nSVCharCode )
2830         {
2831             SalKeyEvent aKeyEvt;
2832             aKeyEvt.mnCode      = nSVCode;
2833             aKeyEvt.mnTime      = WinQueryMsgTime( pFrame->mhAB );
2834             aKeyEvt.mnCode     |= nModCode;
2835             aKeyEvt.mnCharCode  = nSVCharCode;
2836             aKeyEvt.mnRepeat    = nRepeat;
2837 
2838 #if OSL_DEBUG_LEVEL>10
2839 			debug_printf( (nFlags & KC_KEYUP) ? "SALEVENT_KEYUP\n" : "SALEVENT_KEYINPUT\n");
2840 #endif
2841             nRet = pFrame->CallCallback( (nFlags & KC_KEYUP) ? SALEVENT_KEYUP : SALEVENT_KEYINPUT,
2842                                                &aKeyEvt );
2843         }
2844     }
2845 
2846     return nRet;
2847 }
2848 
2849 // -----------------------------------------------------------------------
2850 
2851 static bool ImplHandlePaintMsg( HWND hWnd )
2852 {
2853     BOOL bMutex = FALSE;
2854 
2855     if ( ImplSalYieldMutexTryToAcquire() )
2856         bMutex = TRUE;
2857 
2858     // if we don't get the mutex, we can also change the clip region,
2859     // because other threads doesn't use the mutex from the main
2860     // thread --> see GetGraphics()
2861 
2862     Os2SalFrame* pFrame = GetWindowPtr( hWnd );
2863     if ( pFrame )
2864     {
2865         // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine
2866         // Paint-Region anliegt
2867         if ( WinQueryUpdateRect( hWnd, NULL ) )
2868         {
2869             // Call BeginPaint/EndPaint to query the rect and send
2870             // this Notofication to rect
2871 			HPS     hPS;
2872 			RECTL   aUpdateRect;
2873 			hPS = WinBeginPaint( hWnd, NULLHANDLE, &aUpdateRect );
2874 			WinEndPaint( hPS );
2875 
2876             // Paint
2877             if ( bMutex )
2878             {
2879 		SalPaintEvent aPEvt( aUpdateRect.xLeft, pFrame->mnHeight - aUpdateRect.yTop, aUpdateRect.xRight- aUpdateRect.xLeft, aUpdateRect.yTop - aUpdateRect.yBottom );
2880 
2881                 pFrame->CallCallback( SALEVENT_PAINT, &aPEvt );
2882             }
2883             else
2884             {
2885                 RECTL* pRect = new RECTL;
2886                 WinCopyRect( pFrame->mhAB, pRect, &aUpdateRect );
2887                 WinPostMsg( hWnd, SAL_MSG_POSTPAINT, (MPARAM)pRect, 0 );
2888             }
2889 		}
2890 	}
2891 
2892     if ( bMutex )
2893         ImplSalYieldMutexRelease();
2894 
2895 	return bMutex ? true : false;
2896 }
2897 
2898 // -----------------------------------------------------------------------
2899 
2900 static void ImplHandlePaintMsg2( HWND hWnd, RECTL* pRect )
2901 {
2902     // Paint
2903     if ( ImplSalYieldMutexTryToAcquire() )
2904     {
2905         Os2SalFrame* pFrame = GetWindowPtr( hWnd );
2906         if ( pFrame )
2907         {
2908             SalPaintEvent aPEvt( pRect->xLeft, pFrame->mnHeight - pRect->yTop, pRect->xRight - pRect->xLeft, pRect->yTop - pRect->yBottom );
2909             pFrame->CallCallback( SALEVENT_PAINT, &aPEvt );
2910         }
2911         ImplSalYieldMutexRelease();
2912         delete pRect;
2913     }
2914     else
2915         WinPostMsg( hWnd, SAL_MSG_POSTPAINT, (MPARAM)pRect, 0 );
2916 }
2917 
2918 // -----------------------------------------------------------------------
2919 
2920 static void SetMaximizedFrameGeometry( HWND hWnd, Os2SalFrame* pFrame )
2921 {
2922     // calculate and set frame geometry of a maximized window - useful if the window is still hidden
2923 
2924     RECTL aRect;
2925     pFrame->GetWorkArea( aRect);
2926 
2927     // a maximized window has no other borders than the caption
2928     pFrame->maGeometry.nLeftDecoration = pFrame->maGeometry.nRightDecoration = pFrame->maGeometry.nBottomDecoration = 0;
2929     pFrame->maGeometry.nTopDecoration = pFrame->mbCaption ? WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) : 0;
2930 
2931     aRect.yTop += pFrame->maGeometry.nTopDecoration;
2932     pFrame->maGeometry.nX = aRect.xLeft;
2933     pFrame->maGeometry.nY = aRect.yBottom;
2934     pFrame->maGeometry.nWidth = aRect.xRight - aRect.xLeft + 1;
2935     pFrame->maGeometry.nHeight = aRect.yBottom - aRect.yTop + 1;
2936 }
2937 
2938 static void UpdateFrameGeometry( HWND hWnd, Os2SalFrame* pFrame )
2939 {
2940     if( !pFrame )
2941         return;
2942 
2943 	//SalFrame has a
2944 	//maGeometry member that holds absolute screen positions (and needs to be
2945 	//updated if the window is moved by the way).
2946 
2947 	// reset data
2948     memset(&pFrame->maGeometry, 0, sizeof(SalFrameGeometry) );
2949 
2950 	SWP	swp;
2951 	LONG nFrameX, nFrameY, nCaptionY;
2952 
2953 	// get frame size
2954 	WinQueryWindowPos(pFrame->mhWndFrame, &swp);
2955 	if (swp.fl & SWP_MINIMIZE)
2956       return;
2957 
2958 	// map from client area to screen
2959     ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY);
2960     pFrame->maGeometry.nTopDecoration = nFrameY + nCaptionY;
2961     pFrame->maGeometry.nLeftDecoration = nFrameX;
2962     pFrame->maGeometry.nRightDecoration = nFrameX;
2963 	pFrame->maGeometry.nBottomDecoration = nFrameY;
2964 
2965 	// position of client area, not of frame corner!
2966     pFrame->maGeometry.nX = swp.x + nFrameX;
2967     pFrame->maGeometry.nY = nScreenHeight - (swp.y + swp.cy) + nFrameY + nCaptionY;
2968 
2969     int nWidth  = swp.cx - pFrame->maGeometry.nRightDecoration - pFrame->maGeometry.nLeftDecoration;
2970     int nHeight = swp.cy - pFrame->maGeometry.nBottomDecoration - pFrame->maGeometry.nTopDecoration;
2971 
2972     // clamp to zero
2973     pFrame->maGeometry.nHeight = nHeight < 0 ? 0 : nHeight;
2974     pFrame->maGeometry.nWidth = nWidth < 0 ? 0 : nWidth;
2975 #if OSL_DEBUG_LEVEL>0
2976 	debug_printf( "UpdateFrameGeometry: hwnd %x, frame %x at %d,%d (%dx%d)\n",
2977 		hWnd, pFrame->mhWndFrame,
2978 		pFrame->maGeometry.nX, pFrame->maGeometry.nY,
2979 		pFrame->maGeometry.nWidth,pFrame->maGeometry.nHeight);
2980 #endif
2981 }
2982 
2983 // -----------------------------------------------------------------------
2984 
2985 static void ImplHandleMoveMsg( HWND hWnd)
2986 {
2987     if ( ImplSalYieldMutexTryToAcquire() )
2988     {
2989         Os2SalFrame* pFrame = GetWindowPtr( hWnd );
2990         if ( pFrame )
2991         {
2992             UpdateFrameGeometry( hWnd, pFrame );
2993 
2994             if ( WinIsWindowVisible( hWnd ))
2995 				pFrame->mbDefPos = FALSE;
2996 
2997 			// Gegen moegliche Rekursionen sichern
2998 			if ( !pFrame->mbInMoveMsg )
2999 			{
3000 				// Fenster im FullScreenModus wieder einpassen
3001 				pFrame->mbInMoveMsg = TRUE;
3002 				if ( pFrame->mbFullScreen )
3003 					ImplSalFrameFullScreenPos( pFrame );
3004 				pFrame->mbInMoveMsg = FALSE;
3005 			}
3006 
3007 			// Status merken
3008 			ImplSaveFrameState( pFrame );
3009 
3010             // Call Hdl
3011             //#93851 if we call this handler, VCL floating windows are not updated correctly
3012             //ImplCallMoveHdl( hWnd );
3013 
3014         }
3015 
3016         ImplSalYieldMutexRelease();
3017     }
3018     else
3019 		WinPostMsg( hWnd, SAL_MSG_POSTMOVE, 0, 0 );
3020 }
3021 
3022 // -----------------------------------------------------------------------
3023 
3024 static void ImplHandleSizeMsg( HWND hWnd, MPARAM nMP2 )
3025 {
3026         Os2SalFrame* pFrame = GetWindowPtr( hWnd );
3027         if ( pFrame )
3028         {
3029             UpdateFrameGeometry( hWnd, pFrame );
3030 			pFrame->mbDefPos = FALSE;
3031 			pFrame->mnWidth  = (short)SHORT1FROMMP( nMP2 );
3032 			pFrame->mnHeight = (short)SHORT2FROMMP( nMP2 );
3033 			if ( pFrame->mpGraphics )
3034 				pFrame->mpGraphics->mnHeight = (int)SHORT2FROMMP(nMP2);
3035 			// Status merken
3036 			ImplSaveFrameState( pFrame );
3037 			pFrame->CallCallback( SALEVENT_RESIZE, 0 );
3038 			if ( WinIsWindowVisible( pFrame->mhWndFrame ) && !pFrame->mbInShow )
3039 				WinUpdateWindow( pFrame->mhWndClient );
3040 		}
3041 }
3042 
3043 // -----------------------------------------------------------------------
3044 
3045 static long ImplHandleFocusMsg( Os2SalFrame* pFrame, MPARAM nMP2 )
3046 {
3047 if ( pFrame && !Os2SalFrame::mbInReparent )
3048 {
3049     if ( SHORT1FROMMP( nMP2 ) )
3050     {
3051         if ( WinIsWindowVisible( pFrame->mhWndFrame ) && !pFrame->mbInShow )
3052             WinUpdateWindow( pFrame->mhWndClient );
3053         return pFrame->CallCallback( SALEVENT_GETFOCUS, 0 );
3054     }
3055     else
3056     {
3057         return pFrame->CallCallback( SALEVENT_LOSEFOCUS, 0 );
3058     }
3059 }
3060 }
3061 
3062 // -----------------------------------------------------------------------
3063 
3064 static void ImplHandleCloseMsg( HWND hWnd )
3065 {
3066     if ( ImplSalYieldMutexTryToAcquire() )
3067     {
3068         Os2SalFrame* pFrame = GetWindowPtr( hWnd );
3069         if ( pFrame )
3070         {
3071             pFrame->CallCallback( SALEVENT_CLOSE, 0 );
3072         }
3073 
3074         ImplSalYieldMutexRelease();
3075     }
3076     else
3077         WinPostMsg( hWnd, WM_CLOSE, 0, 0 );
3078 }
3079 
3080 // -----------------------------------------------------------------------
3081 
3082 inline void ImplHandleUserEvent( HWND hWnd, MPARAM nMP2 )
3083 {
3084     ImplSalYieldMutexAcquireWithWait();
3085     Os2SalFrame* pFrame = GetWindowPtr( hWnd );
3086     if ( pFrame )
3087     {
3088         pFrame->CallCallback( SALEVENT_USEREVENT, (void*)nMP2 );
3089     }
3090     ImplSalYieldMutexRelease();
3091 }
3092 
3093 // -----------------------------------------------------------------------
3094 
3095 static int SalImplHandleProcessMenu( Os2SalFrame* pFrame, ULONG nMsg, MPARAM nMP1, MPARAM nMP2)
3096 {
3097     long nRet = 0;
3098 debug_printf("SalImplHandleProcessMenu\n");
3099 #if 0
3100     DWORD err=0;
3101     if( !HIWORD(wParam) )
3102     {
3103         // Menu command
3104         WORD nId = LOWORD(wParam);
3105         if( nId )   // zero for separators
3106         {
3107             SalMenuEvent aMenuEvt;
3108             aMenuEvt.mnId   = nId;
3109             WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( pFrame->mSelectedhMenu, nId, FALSE );
3110             if( pSalMenuItem )
3111                 aMenuEvt.mpMenu = pSalMenuItem->mpMenu;
3112             else
3113                 aMenuEvt.mpMenu = NULL;
3114 
3115             nRet = pFrame->CallCallback( SALEVENT_MENUCOMMAND, &aMenuEvt );
3116         }
3117     }
3118 #endif
3119     //return (nRet != 0);
3120     return (nRet == 0);
3121 }
3122 
3123 // -----------------------------------------------------------------------
3124 
3125 static void ImplHandleInputLangChange( HWND hWnd )
3126 {
3127     ImplSalYieldMutexAcquireWithWait();
3128 
3129     // Feststellen, ob wir IME unterstuetzen
3130     Os2SalFrame* pFrame = GetWindowPtr( hWnd );
3131 #if 0
3132     if ( pFrame && pFrame->mbIME && pFrame->mhDefIMEContext )
3133     {
3134         HWND    hWnd = pFrame->mhWnd;
3135         HKL     hKL = (HKL)lParam;
3136         UINT    nImeProps = ImmGetProperty( hKL, IGP_PROPERTY );
3137 
3138         pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
3139         pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
3140         pFrame->mbHandleIME = !pFrame->mbSpezIME;
3141     }
3142 #endif
3143 
3144     // trigger input language and codepage update
3145     UINT nLang = pFrame->mnInputLang;
3146     ImplUpdateInputLang( pFrame );
3147 	debug_printf("ImplHandleInputLangChange new language 0x%04x\n",pFrame->mnInputLang);
3148 
3149     // notify change
3150     if( nLang != pFrame->mnInputLang )
3151         pFrame->CallCallback( SALEVENT_INPUTLANGUAGECHANGE, 0 );
3152 
3153     ImplSalYieldMutexRelease();
3154 }
3155 
3156 // -----------------------------------------------------------------------
3157 
3158 #ifdef ENABLE_IME
3159 
3160 static long ImplHandleIMEStartConversion( Os2SalFrame* pFrame )
3161 {
3162     long        nRet = FALSE;
3163     SalIMEData* pIMEData = GetSalIMEData();
3164     if ( pIMEData )
3165     {
3166         HWND hWnd = pFrame->mhWndClient;
3167         HIMI hIMI = 0;
3168         pIMEData->mpGetIME( hWnd, &hIMI );
3169         if ( hIMI )
3170         {
3171             ULONG nProp;
3172             if ( 0 != pIMEData->mpQueryIMEProperty( hIMI, QIP_PROPERTY, &nProp ) )
3173                 pFrame->mbHandleIME = FALSE;
3174             else
3175             {
3176                 pFrame->mbHandleIME = !(nProp & PRP_SPECIALUI);
3177 
3178             }
3179             if ( pFrame->mbHandleIME )
3180             {
3181 /* Windows-Code, der noch nicht angepasst wurde !!!
3182                 // Cursor-Position ermitteln und aus der die Default-Position fuer
3183                 // das Composition-Fenster berechnen
3184                 SalCursorPosEvent aCursorPosEvt;
3185                 pFrame->CallCallback( pFrame->mpInst, pFrame,
3186                                             SALEVENT_CURSORPOS, (void*)&aCursorPosEvt );
3187                 COMPOSITIONFORM aForm;
3188                 memset( &aForm, 0, sizeof( aForm ) );
3189                 if ( !aCursorPosEvt.mnWidth || !aCursorPosEvt.mnHeight )
3190                     aForm.dwStyle |= CFS_DEFAULT;
3191                 else
3192                 {
3193                     aForm.dwStyle          |= CFS_POINT;
3194                     aForm.ptCurrentPos.x    = aCursorPosEvt.mnX;
3195                     aForm.ptCurrentPos.y    = aCursorPosEvt.mnY;
3196                 }
3197                 ImmSetCompositionWindow( hIMC, &aForm );
3198 
3199                 // Den InputContect-Font ermitteln und diesem dem Composition-Fenster
3200                 // bekannt machen
3201 */
3202 
3203                 pFrame->mbConversionMode = TRUE;
3204                 pFrame->CallCallback( SALEVENT_STARTEXTTEXTINPUT, (void*)NULL );
3205                 nRet = TRUE;
3206             }
3207 
3208             pIMEData->mpReleaseIME( hWnd, hIMI );
3209         }
3210     }
3211 
3212     return nRet;
3213 }
3214 
3215 // -----------------------------------------------------------------------
3216 
3217 static long ImplHandleIMEConversion( Os2SalFrame* pFrame, MPARAM nMP2Param )
3218 {
3219     long        nRet = FALSE;
3220     SalIMEData* pIMEData = GetSalIMEData();
3221     if ( pIMEData )
3222     {
3223         HWND        hWnd = pFrame->mhWndClient;
3224         HIMI        hIMI = 0;
3225         ULONG    nMP2 = (ULONG)nMP2Param;
3226         pIMEData->mpGetIME( hWnd, &hIMI );
3227         if ( hIMI )
3228         {
3229             if ( nMP2 & (IMR_RESULT_RESULTSTRING |
3230                          IMR_CONV_CONVERSIONSTRING | IMR_CONV_CONVERSIONATTR |
3231                          IMR_CONV_CURSORPOS | IMR_CONV_CURSORATTR) )
3232             {
3233                 SalExtTextInputEvent aEvt;
3234                 aEvt.mnTime             = WinQueryMsgTime( pFrame->mhAB );
3235                 aEvt.mpTextAttr         = NULL;
3236                 aEvt.mnCursorPos        = 0;
3237                 aEvt.mnDeltaStart       = 0;
3238                 aEvt.mbOnlyCursor       = FALSE;
3239                 aEvt.mbCursorVisible    = TRUE;
3240 
3241                 ULONG    nBufLen = 0;
3242                 xub_Unicode*     pBuf = NULL;
3243                 ULONG    nAttrBufLen = 0;
3244                 PM_BYTE*    pAttrBuf = NULL;
3245                 BOOL        bLastCursor = FALSE;
3246                 if ( nMP2 & IMR_RESULT_RESULTSTRING )
3247                 {
3248                     pIMEData->mpGetResultString( hIMI, IMR_RESULT_RESULTSTRING, 0, &nBufLen );
3249                     if ( nBufLen > 0 )
3250                     {
3251                         pBuf = new xub_Unicode[nBufLen];
3252                         pIMEData->mpGetResultString( hIMI, IMR_RESULT_RESULTSTRING, pBuf, &nBufLen );
3253                     }
3254 
3255                     bLastCursor = TRUE;
3256                     aEvt.mbCursorVisible = TRUE;
3257                 }
3258                 else if ( nMP2 & (IMR_CONV_CONVERSIONSTRING | IMR_CONV_CONVERSIONATTR |
3259                                   IMR_CONV_CURSORPOS | IMR_CONV_CURSORATTR) )
3260                 {
3261                     pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, 0, &nBufLen );
3262                     if ( nBufLen > 0 )
3263                     {
3264                         pBuf = new xub_Unicode[nBufLen];
3265                         pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, pBuf, &nBufLen );
3266                     }
3267 
3268                     pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONATTR, 0, &nAttrBufLen );
3269                     if ( nAttrBufLen > 0 )
3270                     {
3271                         pAttrBuf = new PM_BYTE[nAttrBufLen];
3272                         pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONATTR, pAttrBuf, &nAttrBufLen );
3273                     }
3274 
3275 /* !!! Wir bekommen derzeit nur falsche Daten, deshalb zeigen wir derzeit
3276    !!! auch keine Cursor an
3277                     ULONG nTempBufLen;
3278                     ULONG nCursorPos = 0;
3279                     ULONG nCursorAttr = 0;
3280                     ULONG nChangePos = 0;
3281                     nTempBufLen = sizeof( ULONG );
3282                     pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORPOS, &nCursorPos, &nTempBufLen );
3283                     nTempBufLen = sizeof( ULONG );
3284                     pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORATTR, &nCursorAttr, &nTempBufLen );
3285                     nTempBufLen = sizeof( ULONG );
3286                     pIMEData->mpGetConversionString( hIMI, IMR_CONV_CHANGESTART, &nChangePos, &nTempBufLen );
3287 
3288                     aEvt.mnCursorPos = nCursorPos;
3289                     aEvt.mnDeltaStart = nChangePos;
3290                     if ( nCursorAttr & CP_CURSORATTR_INVISIBLE )
3291                         aEvt.mbCursorVisible = FALSE;
3292 */
3293                     aEvt.mnCursorPos = 0;
3294                     aEvt.mnDeltaStart = 0;
3295                     aEvt.mbCursorVisible = FALSE;
3296 
3297                     if ( (nMP2 == IMR_CONV_CURSORPOS) ||
3298                          (nMP2 == IMR_CONV_CURSORATTR) )
3299                         aEvt.mbOnlyCursor = TRUE;
3300                 }
3301 
3302                 USHORT* pSalAttrAry = NULL;
3303                 if ( pBuf )
3304                 {
3305                     aEvt.maText = XubString( pBuf, (USHORT)nBufLen );
3306                     delete [] pBuf;
3307                     if ( pAttrBuf )
3308                     {
3309                         USHORT nTextLen = aEvt.maText.Len();
3310                         if ( nTextLen )
3311                         {
3312                             pSalAttrAry = new USHORT[nTextLen];
3313                             memset( pSalAttrAry, 0, nTextLen*sizeof( USHORT ) );
3314                             for ( USHORT i = 0; (i < nTextLen) && (i < nAttrBufLen); i++ )
3315                             {
3316                                 PM_BYTE nOS2Attr = pAttrBuf[i];
3317                                 USHORT  nSalAttr;
3318                                 if ( nOS2Attr == CP_ATTR_TARGET_CONVERTED )
3319                                     nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETCONVERTED | SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
3320                                 else if ( nOS2Attr == CP_ATTR_CONVERTED )
3321                                     nSalAttr = SAL_EXTTEXTINPUT_ATTR_CONVERTED | SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE;
3322                                 else if ( nOS2Attr == CP_ATTR_TARGET_NOTCONVERTED )
3323                                     nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETNOTCONVERTED | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
3324                                 else if ( nOS2Attr == CP_ATTR_INPUT_ERROR )
3325                                     nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUTERROR | SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
3326                                 else /* ( nOS2Attr == CP_ATTR_INPUT ) */
3327                                     nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
3328                                 pSalAttrAry[i] = nSalAttr;
3329                             }
3330                             aEvt.mpTextAttr = pSalAttrAry;
3331                         }
3332                         delete [] pAttrBuf;
3333                     }
3334                     if ( bLastCursor )
3335                         aEvt.mnCursorPos = aEvt.maText.Len();
3336                 }
3337 
3338                 pIMEData->mpReleaseIME( hWnd, hIMI );
3339 
3340                 // Handler rufen und wenn wir ein Attribute-Array haben, danach
3341                 // wieder zerstoeren
3342                 pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
3343                 if ( pSalAttrAry )
3344                     delete [] pSalAttrAry;
3345             }
3346             else
3347                 pIMEData->mpReleaseIME( hWnd, hIMI );
3348         }
3349 
3350         nRet = TRUE;
3351     }
3352 
3353     return nRet;
3354 }
3355 
3356 // -----------------------------------------------------------------------
3357 
3358 inline long ImplHandleIMEEndConversion( Os2SalFrame* pFrame )
3359 {
3360     pFrame->mbConversionMode = FALSE;
3361     pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
3362     return TRUE;
3363 }
3364 
3365 // -----------------------------------------------------------------------
3366 
3367 static void ImplHandleIMEOpenCandidate( Os2SalFrame* pFrame )
3368 {
3369     pFrame->mbCandidateMode = TRUE;
3370 
3371     long        nRet = FALSE;
3372     SalIMEData* pIMEData = GetSalIMEData();
3373     if ( pIMEData )
3374     {
3375         HWND        hWnd = pFrame->mhWndClient;
3376         HIMI        hIMI = 0;
3377         pIMEData->mpGetIME( hWnd, &hIMI );
3378         if ( hIMI )
3379         {
3380             ULONG nBufLen = 0;
3381             pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, 0, &nBufLen );
3382             if ( nBufLen > 0 )
3383             {
3384 /* !!! Wir bekommen derzeit nur falsche Daten steht der Cursor immer bei 0
3385                 ULONG nTempBufLen = sizeof( ULONG );
3386                 ULONG nCursorPos = 0;
3387                 pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORPOS, &nCursorPos, &nTempBufLen );
3388 */
3389                 ULONG nCursorPos = 0;
3390 
3391                 SalExtTextInputPosEvent aEvt;
3392                 aEvt.mnTime         = WinQueryMsgTime( pFrame->mhAB );
3393                 aEvt.mnFirstPos     = nCursorPos;
3394                 aEvt.mnChars        = nBufLen-nCursorPos;
3395                 aEvt.mpPosAry       = new SalExtCharPos[aEvt.mnChars];
3396                 memset( aEvt.mpPosAry, 0, aEvt.mnChars*sizeof(SalExtCharPos) );
3397 
3398                 pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aEvt );
3399 
3400                 long nMinLeft   = aEvt.mpPosAry[0].mnX;
3401                 long nMinTop    = aEvt.mpPosAry[0].mnY;
3402                 long nMaxBottom = aEvt.mpPosAry[0].mnY+aEvt.mpPosAry[0].mnHeight;
3403                 long nMaxRight  = nMinLeft;
3404                 USHORT i = 0;
3405                 while ( i < aEvt.mnChars )
3406                 {
3407                     // Solange wir uns auf der gleichen Zeile bewegen,
3408                     // ermitteln wir die Rechteck-Grenzen
3409                     if ( !aEvt.mpPosAry[i].mnHeight ||
3410                          (aEvt.mpPosAry[i].mnY < nMaxBottom-1) )
3411                     {
3412                         if ( aEvt.mpPosAry[i].mnX < nMinLeft )
3413                             nMinLeft = aEvt.mpPosAry[i].mnX;
3414                         if ( aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth > nMaxRight )
3415                             nMaxRight = aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth;
3416                         if ( aEvt.mpPosAry[i].mnY < nMinTop )
3417                             nMinTop = aEvt.mpPosAry[i].mnY;
3418                         i++;
3419                     }
3420                     else
3421                         break;
3422                 }
3423 
3424                 CANDIDATEPOS aForm;
3425                 aForm.ulIndex           = 0;
3426                 aForm.ulStyle           = CPS_EXCLUDE;
3427                 aForm.ptCurrentPos.x    = aEvt.mpPosAry[0].mnX;
3428                 aForm.ptCurrentPos.y    = pFrame->mnHeight - (nMaxBottom+1) - 1;
3429                 aForm.rcArea.xLeft      = nMinLeft;
3430                 aForm.rcArea.yBottom    = pFrame->mnHeight - nMaxBottom - 1;
3431                 aForm.rcArea.xRight     = nMaxRight+1;
3432                 aForm.rcArea.yTop       = pFrame->mnHeight - nMinTop - 1;
3433                 pIMEData->mpSetCandidateWin( hIMI, &aForm );
3434 
3435                 delete aEvt.mpPosAry;
3436             }
3437 
3438             pIMEData->mpReleaseIME( hWnd, hIMI );
3439         }
3440     }
3441 }
3442 
3443 // -----------------------------------------------------------------------
3444 
3445 inline void ImplHandleIMECloseCandidate( Os2SalFrame* pFrame )
3446 {
3447     pFrame->mbCandidateMode = FALSE;
3448 }
3449 
3450 #endif
3451 
3452 // -----------------------------------------------------------------------
3453 
3454 MRESULT EXPENTRY SalFrameWndProc( HWND hWnd, ULONG nMsg,
3455                                   MPARAM nMP1, MPARAM nMP2 )
3456 {
3457     Os2SalFrame*   	pFrame      = (Os2SalFrame*)GetWindowPtr( hWnd );
3458     MRESULT     	nRet        = (MRESULT)0;
3459     BOOL        	bDef     	= TRUE;
3460 	bool 			bCheckTimers= false;
3461 
3462 #if OSL_DEBUG_LEVEL>10
3463     if (nMsg!=WM_TIMER && nMsg!=WM_MOUSEMOVE)
3464         debug_printf( "SalFrameWndProc hWnd 0x%x nMsg 0x%x\n", hWnd, nMsg);
3465 #endif
3466 
3467     switch( nMsg )
3468     {
3469         case WM_MOUSEMOVE:
3470         case WM_BUTTON1DOWN:
3471         case WM_BUTTON2DOWN:
3472         case WM_BUTTON3DOWN:
3473         case WM_BUTTON1DBLCLK:
3474         case WM_BUTTON2DBLCLK:
3475         case WM_BUTTON3DBLCLK:
3476         case WM_BUTTON1UP:
3477         case WM_BUTTON2UP:
3478         case WM_BUTTON3UP:
3479         case SAL_MSG_MOUSELEAVE:
3480             // ButtonUp/Down nie an die WinDefWindowProc weiterleiten, weil sonst
3481             // die Message an den Owner weitergeleitet wird
3482             ImplSalYieldMutexAcquireWithWait();
3483             bDef = !ImplHandleMouseMsg( hWnd, nMsg, nMP1, nMP2 );
3484             ImplSalYieldMutexRelease();
3485             break;
3486 
3487         case WM_CHAR:
3488             if ( pFrame->mbConversionMode )
3489                 bDef = FALSE;
3490             else
3491                 bDef = !ImplHandleKeyMsg( hWnd, nMsg, nMP1, nMP2 );
3492             break;
3493 
3494         case WM_ERASEBACKGROUND:
3495             nRet = (MRESULT)FALSE;
3496             bDef = FALSE;
3497             break;
3498 
3499         case WM_PAINT:
3500             bCheckTimers = ImplHandlePaintMsg( hWnd );
3501             bDef = FALSE;
3502             break;
3503         case SAL_MSG_POSTPAINT:
3504         	ImplHandlePaintMsg2( hWnd, (RECTL*)nMP1 );
3505 			bCheckTimers = true;
3506         	bDef = FALSE;
3507 			break;
3508 
3509         case WM_MOVE:
3510         case SAL_MSG_POSTMOVE:
3511             ImplHandleMoveMsg( hWnd );
3512             bDef = FALSE;
3513             break;
3514 
3515         case WM_SIZE:
3516             if ( ImplSalYieldMutexTryToAcquire() )
3517             {
3518                 ImplHandleSizeMsg( hWnd, nMP2 );
3519                 ImplSalYieldMutexRelease();
3520             }
3521             else
3522                 WinPostMsg( hWnd, SAL_MSG_POSTSIZE, nMP1, nMP2 );
3523             break;
3524         case SAL_MSG_POSTSIZE:
3525             ImplHandleSizeMsg( hWnd, nMP2 );
3526             break;
3527 		case WM_MINMAXFRAME:
3528             if ( ImplSalYieldMutexTryToAcquire() )
3529             {
3530 				PSWP pswp = (PSWP) nMP1;
3531                 ImplHandleSizeMsg( hWnd, MPFROM2SHORT( pswp->cx, pswp->cy) );
3532                 ImplSalYieldMutexRelease();
3533             }
3534             else
3535                 WinPostMsg( hWnd, SAL_MSG_POSTSIZE, 0, nMP2 );
3536 			break;
3537 
3538         case WM_CALCVALIDRECTS:
3539             return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
3540 
3541         case WM_SETFOCUS:
3542             if ( ImplSalYieldMutexTryToAcquire() )
3543             {
3544                 ImplHandleFocusMsg( pFrame, nMP2 );
3545                 ImplSalYieldMutexRelease();
3546             }
3547             else
3548                 WinPostMsg( hWnd, SAL_MSG_POSTFOCUS, 0, nMP2 );
3549             break;
3550         case SAL_MSG_POSTFOCUS:
3551             ImplHandleFocusMsg( pFrame, nMP2 );
3552             break;
3553 
3554         case WM_TRANSLATEACCEL:
3555             {
3556             // Da uns OS/2 zu viele Tasten abfaegnt, unternehmen wir etwas,
3557             // damit wir Shift+F1, Shift+F10 und Shift+Enter bekommen
3558             PQMSG   pMsg        = (PQMSG)nMP1;
3559             USHORT  nKeyFlags   = SHORT1FROMMP( pMsg->mp1 );
3560             USHORT  nKeyCode    = (UCHAR)SHORT2FROMMP( pMsg->mp2 );
3561 
3562             if ( !(nKeyFlags & KC_KEYUP) && (nKeyFlags & KC_VIRTUALKEY) &&
3563                  (nKeyFlags & KC_SHIFT) && (nKeyCode != VK_ESC) )
3564                 return (MRESULT)FALSE;
3565 
3566             if ( nKeyCode == VK_F1 )
3567                 return (MRESULT)FALSE;
3568             }
3569             break;
3570 
3571         case WM_CREATE:
3572             {
3573 				HWND hWndFrame = WinQueryWindow(hWnd, QW_PARENT);
3574 				if (hWndFrame == 0)
3575 					debug_printf(" WARNING NULL FRAME!!\n");
3576 				SalData* pSalData = GetSalData();
3577 				// Window-Instanz am Windowhandle speichern
3578 				pFrame = pSalData->mpCreateFrame;
3579 				pSalData->mpCreateFrame = NULL;
3580 				SetWindowPtr( hWnd, pFrame );
3581 				SetWindowPtr( hWndFrame, pFrame);
3582 				// HWND schon hier setzen, da schon auf den Instanzdaten
3583 				// gearbeitet werden kann, wenn Messages waehrend
3584 				// CreateWindow() gesendet werden
3585 				pFrame->mhWndClient = hWnd;
3586 				pFrame->mhWndFrame = hWndFrame;
3587 				pFrame->maSysData.hWnd = hWnd;
3588             }
3589             break;
3590 
3591         case WM_CLOSE:
3592             ImplHandleCloseMsg( hWnd );
3593             bDef = FALSE;
3594             break;
3595 
3596         case WM_SYSVALUECHANGED:
3597             if ( pFrame->mbFullScreen )
3598                 ImplSalFrameFullScreenPos( pFrame );
3599             // kein break, da der Rest auch noch verarbeitet werden soll
3600         case PL_ALTERED:
3601         case WM_SYSCOLORCHANGE:
3602             ImplSalYieldMutexAcquire();
3603             pFrame->CallCallback( SALEVENT_SETTINGSCHANGED, 0 );
3604             ImplSalYieldMutexRelease();
3605             break;
3606 
3607         case SAL_MSG_USEREVENT:
3608             ImplHandleUserEvent( hWnd, nMP2 );
3609             bDef = FALSE;
3610             break;
3611         case SAL_MSG_TOTOP:
3612             ImplSalToTop( hWnd, (ULONG)nMP1 );
3613             bDef = FALSE;
3614             break;
3615         case SAL_MSG_SHOW:
3616             ImplSalShow( hWnd, (ULONG)nMP1, (ULONG)nMP2 );
3617             bDef = FALSE;
3618             break;
3619 
3620 		case WM_KBDLAYERCHANGED:
3621 			debug_printf("hWnd 0x%08x WM_KBDLAYERCHANGED\n", hWnd);
3622             ImplHandleInputLangChange( hWnd );
3623             break;
3624 
3625 		case WM_HSCROLL:
3626 		case WM_VSCROLL:
3627 			ImplHandleWheelMsg( hWnd, nMsg, nMP1, nMP2 );
3628             bDef = FALSE;
3629 			break;
3630 
3631         case WM_COMMAND:
3632         case SAL_MSG_SYSPROCESSMENU:
3633             if ( SalImplHandleProcessMenu( pFrame, nMsg, nMP1, nMP2 ) )
3634             {
3635                 bDef = FALSE;
3636                 nRet = (MRESULT)1;
3637             }
3638             break;
3639 
3640 #ifdef ENABLE_IME
3641         case WM_IMEREQUEST:
3642             if ( (ULONG)nMP1 == IMR_CONVRESULT )
3643             {
3644                 if ( pFrame->mbHandleIME )
3645                 {
3646                     // Nur im Conversionmodus akzeptieren wir den IME-Input
3647                     if ( pFrame->mbConversionMode )
3648                     {
3649                         ImplSalYieldMutexAcquire();
3650                         if ( ImplHandleIMEConversion( pFrame, nMP2 ) )
3651                         {
3652                             bDef = FALSE;
3653                             nRet = (MRESULT)TRUE;
3654                         }
3655                         ImplSalYieldMutexRelease();
3656                     }
3657                 }
3658             }
3659             else if ( (ULONG)nMP1 == IMR_CANDIDATE )
3660             {
3661                 if ( pFrame->mbHandleIME )
3662                 {
3663                     ImplSalYieldMutexAcquire();
3664                     if ( (ULONG)nMP2 & IMR_CANDIDATE_SHOW )
3665                         ImplHandleIMEOpenCandidate( pFrame );
3666                     else if ( (ULONG)nMP2 & IMR_CANDIDATE_HIDE )
3667                         ImplHandleIMECloseCandidate( pFrame );
3668                     ImplSalYieldMutexRelease();
3669                 }
3670             }
3671             break;
3672 
3673         case WM_IMENOTIFY:
3674             if ( (ULONG)nMP1 == IMN_STARTCONVERSION )
3675             {
3676                 ImplSalYieldMutexAcquire();
3677                 if ( ImplHandleIMEStartConversion( pFrame ) )
3678                 {
3679                     bDef = FALSE;
3680                     nRet = (MRESULT)TRUE;
3681                 }
3682                 ImplSalYieldMutexRelease();
3683             }
3684             else if ( (ULONG)nMP1 == IMN_ENDCONVERSION )
3685             {
3686                 if ( pFrame->mbHandleIME )
3687                 {
3688                     ImplSalYieldMutexAcquire();
3689                     if ( ImplHandleIMEEndConversion( pFrame ) )
3690                     {
3691                         bDef = FALSE;
3692                         nRet = (MRESULT)TRUE;
3693                     }
3694                     ImplSalYieldMutexRelease();
3695                 }
3696             }
3697             break;
3698 #endif
3699     }
3700 
3701 	if( bCheckTimers )
3702 	{
3703 		SalData* pSalData = GetSalData();
3704 		if( pSalData->mnNextTimerTime )
3705 		{
3706 			ULONG nCurTime;
3707 			DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, (PVOID)&nCurTime, sizeof(ULONG));
3708 			if( pSalData->mnNextTimerTime < nCurTime )
3709 			{
3710 				QMSG aMsg;
3711 				if (!WinPeekMsg( pFrame->mhAB, &aMsg, 0, WM_PAINT, WM_PAINT, PM_NOREMOVE ) )
3712 					WinPostMsg( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_POSTTIMER, 0, (MPARAM)nCurTime );
3713 			}
3714 		}
3715 	}
3716 
3717     if ( bDef )
3718         nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
3719 
3720     return nRet;
3721 }
3722 
3723 // -----------------------------------------------------------------------
3724 
3725 void Os2SalFrame::ResetClipRegion()
3726 {
3727 }
3728 
3729 void Os2SalFrame::BeginSetClipRegion( ULONG )
3730 {
3731 }
3732 
3733 void Os2SalFrame::UnionClipRegion( long, long, long, long )
3734 {
3735 }
3736 
3737 void Os2SalFrame::EndSetClipRegion()
3738 {
3739 }
3740 
3741 // -----------------------------------------------------------------------
3742 
3743 MRESULT EXPENTRY SalFrameSubClassWndProc( HWND hWnd, ULONG nMsg,
3744                                   MPARAM nMP1, MPARAM nMP2 )
3745 {
3746     MRESULT mReturn = 0L;
3747 
3748     // ticket#124 min size of 132 px is too much
3749     if (nMsg == WM_QUERYTRACKINFO) {
3750 	PTRACKINFO pti;
3751 	// first, let PM initialize TRACKINFO
3752 	mReturn = aSalShlData.mpFrameProc( hWnd, nMsg, nMP1, nMP2 );
3753 	// now change default min size
3754 	pti = (PTRACKINFO) nMP2;
3755 	pti->ptlMinTrackSize.x = 64L;
3756 	// now return to PM
3757 	return mReturn;
3758     }
3759 
3760     return aSalShlData.mpFrameProc( hWnd, nMsg, nMP1, nMP2 );
3761 }
3762 
3763 // -----------------------------------------------------------------------
3764