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