xref: /AOO41X/main/vcl/os2/source/window/salobj.cxx (revision dcefce6ce885c17ab06b686ebe819428fa9ddffe)
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