1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <svpm.h>
25
26 #include <string.h>
27
28 #include <tools/debug.hxx>
29 #include <tools/svwin.h>
30
31 #include "vcl/svapp.hxx"
32
33 #include "os2/saldata.hxx"
34 #include "os2/salinst.h"
35 #include "os2/salframe.h"
36 #include "os2/salobj.h"
37
38 // =======================================================================
39
ImplIsSysWindowOrChild(HWND hWndParent,HWND hWndChild)40 static sal_Bool ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild )
41 {
42 if ( hWndParent == hWndChild )
43 return TRUE;
44
45 HWND hTempWnd = WinQueryWindow( hWndChild, QW_PARENT );
46 while ( hTempWnd )
47 {
48 if ( hTempWnd == hWndParent )
49 return TRUE;
50 hTempWnd = WinQueryWindow( hTempWnd, QW_PARENT );
51 }
52
53 return FALSE;
54 }
55
56 // -----------------------------------------------------------------------
57
ImplFindOs2SalObject(HWND hWndChild)58 static Os2SalObject* ImplFindOs2SalObject( HWND hWndChild )
59 {
60 SalData* pSalData = GetSalData();
61 Os2SalObject* pObject = pSalData->mpFirstObject;
62 while ( pObject )
63 {
64 if ( ImplIsSysWindowOrChild( pObject->mhWndChild, hWndChild ) )
65 return pObject;
66
67 pObject = pObject->mpNextObject;
68 }
69
70 return NULL;
71 }
72
73 // =======================================================================
74
SalSysMsgProc(HAB,QMSG * pMsg,ULONG)75 sal_Bool EXPENTRY SalSysMsgProc( HAB /* hAB */, QMSG* pMsg, ULONG /* fs */ )
76 {
77 if ( (pMsg->msg == WM_BUTTON1DOWN) ||
78 (pMsg->msg == WM_BUTTON2DOWN) ||
79 (pMsg->msg == WM_BUTTON3DOWN) )
80 {
81 SalData* pSalData = GetSalData();
82 Os2SalObject* pObject = ImplFindOs2SalObject( pMsg->hwnd );
83 if ( pObject )
84 WinPostMsg( pObject->mhWnd, SALOBJ_MSG_TOTOP, 0, 0 );
85 }
86
87 // Focus fangen wir hier nicht ab, da wir erstmal davon ausgehen,
88 // das unser Os2SalObject-Fenster immer eine WM_FOCUSCHANGE-Message
89 // bekommt.
90
91 return FALSE;
92 }
93
94 // -----------------------------------------------------------------------
95
SalSysObjWndProc(HWND hWnd,ULONG nMsg,MPARAM nMP1,MPARAM nMP2)96 MRESULT EXPENTRY SalSysObjWndProc( HWND hWnd, ULONG nMsg,
97 MPARAM nMP1, MPARAM nMP2 )
98 {
99 Os2SalObject* pSysObj;
100 MRESULT nRet = 0;
101 int bDef = TRUE;
102
103 #if OSL_DEBUG_LEVEL>0
104 debug_printf( "SalSysObjWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg);
105 #endif
106
107 switch( nMsg )
108 {
109 case WM_ERASEBACKGROUND:
110 nRet = (MRESULT)FALSE;
111 bDef = FALSE;
112 break;
113 case WM_PAINT:
114 {
115 HPS hPS;
116 RECTL aRect;
117 hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
118 WinEndPaint( hPS );
119 bDef = FALSE;
120 }
121 bDef = FALSE;
122 break;
123
124 case WM_BUTTON1DOWN:
125 case WM_BUTTON2DOWN:
126 case WM_BUTTON3DOWN:
127 case SALOBJ_MSG_TOTOP:
128 if ( ImplSalYieldMutexTryToAcquire() )
129 {
130 pSysObj = GetSalObjWindowPtr( hWnd );
131 pSysObj->mpProc( pSysObj->mpInst, pSysObj,
132 SALOBJ_EVENT_TOTOP, 0 );
133 ImplSalYieldMutexRelease();
134 }
135 else
136 WinPostMsg( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
137 break;
138
139 case WM_FOCUSCHANGE:
140 case SALOBJ_MSG_POSTFOCUS:
141 if ( ImplSalYieldMutexTryToAcquire() )
142 {
143 pSysObj = GetSalObjWindowPtr( hWnd );
144 if ( SHORT1FROMMP( nMP2 ) )
145 {
146 pSysObj->mhLastFocusWnd = WinQueryFocus( HWND_DESKTOP );
147 pSysObj->mpProc( pSysObj->mpInst, pSysObj,
148 SALOBJ_EVENT_GETFOCUS, 0 );
149 }
150 else
151 {
152 HWND hWndFocus = HWNDFROMMP( nMP1 );
153 if ( !hWndFocus || !ImplIsSysWindowOrChild( hWnd, hWndFocus ) )
154 {
155 pSysObj->mpProc( pSysObj->mpInst, pSysObj,
156 SALOBJ_EVENT_LOSEFOCUS, 0 );
157 }
158 }
159 ImplSalYieldMutexRelease();
160 }
161 else
162 WinPostMsg( hWnd, SALOBJ_MSG_POSTFOCUS, nMP1, nMP2 );
163 break;
164
165 case WM_SIZE:
166 {
167 pSysObj = GetSalObjWindowPtr( hWnd );
168 pSysObj->mnHeight = (short)SHORT2FROMMP( nMP2 );
169 WinSetWindowPos( pSysObj->mhWndChild, 0,
170 0, 0,
171 (short)SHORT1FROMMP( nMP2 ), (short)SHORT2FROMMP( nMP2 ),
172 SWP_SIZE | SWP_MOVE );
173 bDef = FALSE;
174 }
175 break;
176
177 case WM_CREATE:
178 {
179 // Window-Instanz am Windowhandle speichern
180 CREATESTRUCT* pStruct = (CREATESTRUCT*)nMP2;
181 pSysObj = (Os2SalObject*)pStruct->pPresParams;
182 SetSalObjWindowPtr( hWnd, pSysObj );
183 bDef = FALSE;
184 }
185 break;
186 }
187
188 if ( bDef )
189 nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
190 return nRet;
191 }
192
193 // -----------------------------------------------------------------------
194
SalSysObjChildWndProc(HWND hWnd,ULONG nMsg,MPARAM nMP1,MPARAM nMP2)195 MRESULT EXPENTRY SalSysObjChildWndProc( HWND hWnd, ULONG nMsg,
196 MPARAM nMP1, MPARAM nMP2 )
197 {
198 MRESULT nRet = 0;
199 int bDef = TRUE;
200
201 #if OSL_DEBUG_LEVEL>0
202 debug_printf( "SalSysObjChildWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg);
203 #endif
204
205 switch( nMsg )
206 {
207 case WM_ERASEBACKGROUND:
208 // Wegen PlugIn's loeschen wir erstmal den Hintergrund
209 /*
210 nRet = (MRESULT)FALSE;
211 bDef = FALSE;
212 */
213 break;
214 case WM_PAINT:
215 {
216 HPS hPS;
217 RECTL aRect;
218 hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
219 WinEndPaint( hPS );
220 bDef = FALSE;
221 }
222 break;
223 }
224
225 if ( bDef )
226 nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
227 return nRet;
228 }
229
230 // -----------------------------------------------------------------------
231
SalSysObjClipWndProc(HWND hWnd,ULONG nMsg,MPARAM nMP1,MPARAM nMP2)232 MRESULT EXPENTRY SalSysObjClipWndProc( HWND hWnd, ULONG nMsg,
233 MPARAM nMP1, MPARAM nMP2 )
234 {
235 MRESULT nRet = 0;
236 int bDef = TRUE;
237
238 #if OSL_DEBUG_LEVEL>0
239 debug_printf( "SalSysObjClipWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg);
240 #endif
241
242 switch( nMsg )
243 {
244 case WM_MOUSEMOVE:
245 case WM_BUTTON1DOWN:
246 case WM_BUTTON2DOWN:
247 case WM_BUTTON3DOWN:
248 case WM_BUTTON1DBLCLK:
249 case WM_BUTTON2DBLCLK:
250 case WM_BUTTON3DBLCLK:
251 case WM_BUTTON1UP:
252 case WM_BUTTON2UP:
253 case WM_BUTTON3UP:
254 {
255 // Alle Events an den Frame weiterreichen, da diese Bereiche
256 // dem Frame gehoeren. Dazu muessen die Mouse-Koordinaaten
257 // entsprechend umgerechnet werden
258 HWND hWndParent = WinQueryWindow( hWnd, QW_PARENT ); // ergibt SysChild-Fenster
259 hWndParent = WinQueryWindow( hWndParent, QW_PARENT );
260 short nX = (short)SHORT1FROMMP( nMP1 );
261 short nY = (short)SHORT2FROMMP( nMP1 );
262 POINTL aPos;
263 aPos.x = nX;
264 aPos.y = nY;
265 WinMapWindowPoints( hWnd, hWndParent, &aPos, 1 );
266 nMP1 = MPFROM2SHORT( (short)aPos.x, (short)aPos.y );
267 bDef = FALSE;
268 nRet = WinSendMsg( hWndParent, nMsg, nMP1, nMP2 );
269 }
270 break;
271
272 case WM_HITTEST:
273 // Damit im disablten Zustand die MouseKlicks immer noch
274 // an den Frame geschickt werden
275 // Dieser Code reicht leider nicht aus, deshalb wir unter
276 // OS2 immer das Child-Fenster disablen, im Gegensatz
277 // zu Windows, wo immer der Parent disablte wird, da
278 // sich das Fenster evtl. anders Darstellen koennte,
279 // wenn es disablte wird. Da dieser Fall uns bisher
280 // nicht bekannt ist, ignorieren wir das.
281 nRet = HT_NORMAL;
282 bDef = FALSE;
283 break;
284
285 case WM_ERASEBACKGROUND:
286 nRet = (MRESULT)FALSE;
287 bDef = FALSE;
288 break;
289 case WM_PAINT:
290 {
291 HPS hPS;
292 RECTL aRect;
293 hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
294 WinEndPaint( hPS );
295 bDef = FALSE;
296 }
297 break;
298 }
299
300 if ( bDef )
301 nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
302 return nRet;
303 }
304
305 // =======================================================================
306
ImplDestroyAllClipWindows(HWND hWndLast)307 void ImplDestroyAllClipWindows( HWND hWndLast )
308 {
309 if ( hWndLast == HWND_TOP )
310 return;
311
312 HWND hWndPrev;
313 while ( hWndLast )
314 {
315 hWndPrev = WinQueryWindow( hWndLast, QW_PREV );
316 WinDestroyWindow( hWndLast );
317 hWndLast = hWndPrev;
318 }
319 }
320
321 // =======================================================================
322
ImplSalCreateObject(Os2SalInstance * pInst,Os2SalFrame * pParent)323 SalObject* ImplSalCreateObject( Os2SalInstance* pInst, Os2SalFrame* pParent )
324 {
325 SalData* pSalData = GetSalData();
326
327 if ( !pSalData->mbObjClassInit )
328 {
329 if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CLASSNAME,
330 (PFNWP)SalSysObjWndProc, CS_MOVENOTIFY,
331 SAL_OBJECT_WNDEXTRA ) )
332 {
333 if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CLIPCLASSNAME,
334 (PFNWP)SalSysObjClipWndProc, CS_HITTEST | CS_MOVENOTIFY, 0 ) )
335 {
336 if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CHILDCLASSNAME,
337 (PFNWP)SalSysObjChildWndProc, CS_HITTEST | CS_MOVENOTIFY, 32 ) )
338 pSalData->mbObjClassInit = TRUE;
339 }
340 }
341 }
342
343 if ( pSalData->mbObjClassInit )
344 {
345 Os2SalObject* pObject = new Os2SalObject;
346 HWND hWnd = WinCreateWindow( pParent->mhWndClient, SAL_OBJECT_CLASSNAME, "",
347 0,
348 0, 0, 0, 0,
349 pParent->mhWndClient, HWND_TOP,
350 0, NULL, (void*)pObject );
351 HWND hWndChild = WinCreateWindow( hWnd, SAL_OBJECT_CHILDCLASSNAME, "",
352 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
353 0, 0, 0, 0,
354 hWnd, HWND_TOP,
355 0, NULL, NULL );
356
357 if ( !hWndChild )
358 {
359 if ( hWnd )
360 WinDestroyWindow( hWnd );
361 delete pObject;
362 return NULL;
363 }
364
365 if ( hWnd )
366 {
367 #if OSL_DEBUG_LEVEL>0
368 debug_printf("ImplSalCreateObject hWndChild %x\n", hWndChild);
369 debug_printf("ImplSalCreateObject hWnd %x\n", hWnd);
370 #endif
371 pObject->mhWnd = hWnd;
372 pObject->mhWndChild = hWndChild;
373 pObject->maSysData.hWnd = hWndChild;
374 return pObject;
375 }
376 }
377
378 return NULL;
379 }
380
381 // =======================================================================
382
ImplSalObjCallbackDummy(void *,SalObject *,USHORT,const void *)383 long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* )
384 {
385 return 0;
386 }
387
388 // =======================================================================
389
Os2SalObject()390 Os2SalObject::Os2SalObject()
391 {
392 SalData* pSalData = GetSalData();
393
394 mhLastClipWnd = HWND_TOP;
395
396 mhWnd = 0;
397 mhWndChild = 0;
398 mhLastFocusWnd = 0;
399 maSysData.nSize = sizeof( SystemEnvData );
400 mnHeight = 0;
401 mpInst = NULL;
402 mpProc = ImplSalObjCallbackDummy;
403
404 // Hook installieren, wenn es das erste Os2SalObject ist
405 if ( !pSalData->mpFirstObject )
406 {
407 WinSetHook( pSalData->mhAB, pSalData->mhMQ,
408 HK_INPUT, (PFN)SalSysMsgProc, (HMODULE)0 );
409 }
410
411 // Insert object in objectlist
412 mpNextObject = pSalData->mpFirstObject;
413 pSalData->mpFirstObject = this;
414 }
415
416 // -----------------------------------------------------------------------
417
~Os2SalObject()418 Os2SalObject::~Os2SalObject()
419 {
420 SalData* pSalData = GetSalData();
421
422 // remove frame from framelist
423 if ( this == pSalData->mpFirstObject )
424 {
425 pSalData->mpFirstObject = mpNextObject;
426
427 // Wenn letztes Os2SalObject, dann Hook wieder entfernen
428 if ( !pSalData->mpFirstObject )
429 {
430 WinReleaseHook( pSalData->mhAB, pSalData->mhMQ,
431 HK_INPUT, (PFN)SalSysMsgProc, (HMODULE)0 );
432 }
433 }
434 else
435 {
436 Os2SalObject* pTempObject = pSalData->mpFirstObject;
437 while ( pTempObject->mpNextObject != this )
438 pTempObject = pTempObject->mpNextObject;
439
440 pTempObject->mpNextObject = mpNextObject;
441 }
442
443 // Cache-Daten zerstoeren
444 ImplDestroyAllClipWindows( mhLastClipWnd );
445
446 if ( mhWndChild )
447 WinDestroyWindow( mhWndChild );
448 if ( mhWnd )
449 WinDestroyWindow( mhWnd );
450 }
451
452 // -----------------------------------------------------------------------
453
ResetClipRegion()454 void Os2SalObject::ResetClipRegion()
455 {
456 ImplDestroyAllClipWindows( mhLastClipWnd );
457 mhLastClipWnd = HWND_TOP;
458 }
459
460 // -----------------------------------------------------------------------
461
GetClipRegionType()462 USHORT Os2SalObject::GetClipRegionType()
463 {
464 return SAL_OBJECT_CLIP_EXCLUDERECTS;
465 }
466
467 // -----------------------------------------------------------------------
468
BeginSetClipRegion(ULONG nRectCount)469 void Os2SalObject::BeginSetClipRegion( ULONG nRectCount )
470 {
471 mhOldLastClipWnd = mhLastClipWnd;
472 }
473
474 // -----------------------------------------------------------------------
475
UnionClipRegion(long nX,long nY,long nWidth,long nHeight)476 void Os2SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
477 {
478 HWND hClipWnd = WinCreateWindow( mhWnd, SAL_OBJECT_CLIPCLASSNAME, "",
479 WS_VISIBLE,
480 nX, mnHeight-(nY+nHeight), nWidth, nHeight,
481 mhWnd, mhLastClipWnd,
482 0, NULL, NULL );
483 #if OSL_DEBUG_LEVEL>0
484 debug_printf("Os2SalObject::UnionClipRegion hClipWnd %x\n", hClipWnd);
485 #endif
486 mhLastClipWnd = hClipWnd;
487 }
488
489 // -----------------------------------------------------------------------
490
EndSetClipRegion()491 void Os2SalObject::EndSetClipRegion()
492 {
493 ImplDestroyAllClipWindows( mhOldLastClipWnd );
494 }
495
496 // -----------------------------------------------------------------------
497
SetPosSize(long nX,long nY,long nWidth,long nHeight)498 void Os2SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
499 {
500 ULONG nStyle = 0;
501 sal_Bool bVisible = WinIsWindowVisible( mhWnd );
502 if ( bVisible )
503 {
504 WinShowWindow( mhWnd, FALSE );
505 nStyle |= SWP_SHOW;
506 }
507 SWP aParentSWP;
508 WinQueryWindowPos( WinQueryWindow( mhWnd, QW_PARENT ), &aParentSWP );
509 WinSetWindowPos( mhWnd, 0, nX, aParentSWP.cy-(nY+nHeight), nWidth, nHeight,
510 SWP_MOVE | SWP_SIZE | nStyle );
511 }
512
513 // -----------------------------------------------------------------------
514
Show(sal_Bool bVisible)515 void Os2SalObject::Show( sal_Bool bVisible )
516 {
517 WinShowWindow( mhWnd, bVisible );
518 }
519
520 // -----------------------------------------------------------------------
521
Enable(sal_Bool bEnable)522 void Os2SalObject::Enable( sal_Bool bEnable )
523 {
524 // Im Gegensatz zu Windows disablen wir das Childfenster,
525 // da ansonsten unser Clippen nicht mehr funktioniert, da
526 // wir keine Events mehr bekommen. Dadurch kann sich evtl.
527 // das Fenster anders darstellen, was wir eigentlich nicht
528 // wollen. Aber da uns bisher kein Fall bekannt ist,
529 // ignorieren wir dies. Ansonsten muss ein Fenster dazwischen
530 // gezogen werden oder getestet werden, wie wir die
531 // Maustransparenz erreichen, wenn mhWnd
532 // disablte wird.
533 WinEnableWindow( mhWndChild, bEnable );
534 }
535
536 // -----------------------------------------------------------------------
537
GrabFocus()538 void Os2SalObject::GrabFocus()
539 {
540 if ( mhLastFocusWnd &&
541 WinIsWindow( GetSalData()->mhAB, mhLastFocusWnd ) &&
542 ImplIsSysWindowOrChild( mhWndChild, mhLastFocusWnd ) )
543 WinSetFocus( HWND_DESKTOP, mhLastFocusWnd );
544 else
545 WinSetFocus( HWND_DESKTOP, mhWndChild );
546 }
547
548 // -----------------------------------------------------------------------
549
SetBackground()550 void Os2SalObject::SetBackground()
551 {
552 }
553
554 // -----------------------------------------------------------------------
555
SetBackground(SalColor nSalColor)556 void Os2SalObject::SetBackground( SalColor nSalColor )
557 {
558 }
559
560 // -----------------------------------------------------------------------
561
GetSystemData() const562 const SystemChildData* Os2SalObject::GetSystemData() const
563 {
564 return &maSysData;
565 }
566
567 // -----------------------------------------------------------------------
568 #if 0
569 void Os2SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc )
570 {
571 mpInst = pInst;
572 if ( pProc )
573 mpProc = pProc;
574 else
575 mpProc = ImplSalObjCallbackDummy;
576 }
577 #endif
578
579 // -----------------------------------------------------------------------
580
InterceptChildWindowKeyDown(sal_Bool)581 void Os2SalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ )
582 {
583 }
584
585