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