merge the formfield patch from ooo-build
[ooovba.git] / vcl / os2 / source / window / salobj.cxx
blobcbcbf7701c197cb141953e24fa82f95fa41226d7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salobj.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <svpm.h>
33 #define _SV_SALOBJ_CXX
34 #include <saldata.hxx>
35 #include <salinst.h>
36 #include <salframe.h>
37 #include <salobj.h>
39 // =======================================================================
41 static BOOL ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild )
43 if ( hWndParent == hWndChild )
44 return TRUE;
46 HWND hTempWnd = WinQueryWindow( hWndChild, QW_PARENT );
47 while ( hTempWnd )
49 if ( hTempWnd == hWndParent )
50 return TRUE;
51 hTempWnd = WinQueryWindow( hTempWnd, QW_PARENT );
54 return FALSE;
57 // -----------------------------------------------------------------------
59 static Os2SalObject* ImplFindOs2SalObject( HWND hWndChild )
61 SalData* pSalData = GetSalData();
62 Os2SalObject* pObject = pSalData->mpFirstObject;
63 while ( pObject )
65 if ( ImplIsSysWindowOrChild( pObject->mhWndChild, hWndChild ) )
66 return pObject;
68 pObject = pObject->mpNextObject;
71 return NULL;
74 // =======================================================================
76 BOOL EXPENTRY SalSysMsgProc( HAB /* hAB */, QMSG* pMsg, ULONG /* fs */ )
78 if ( (pMsg->msg == WM_BUTTON1DOWN) ||
79 (pMsg->msg == WM_BUTTON2DOWN) ||
80 (pMsg->msg == WM_BUTTON3DOWN) )
82 SalData* pSalData = GetSalData();
83 Os2SalObject* pObject = ImplFindOs2SalObject( pMsg->hwnd );
84 if ( pObject )
85 WinPostMsg( pObject->mhWnd, SALOBJ_MSG_TOTOP, 0, 0 );
88 // Focus fangen wir hier nicht ab, da wir erstmal davon ausgehen,
89 // das unser Os2SalObject-Fenster immer eine WM_FOCUSCHANGE-Message
90 // bekommt.
92 return FALSE;
95 // -----------------------------------------------------------------------
97 MRESULT EXPENTRY SalSysObjWndProc( HWND hWnd, ULONG nMsg,
98 MPARAM nMP1, MPARAM nMP2 )
100 Os2SalObject* pSysObj;
101 MRESULT nRet = 0;
102 int bDef = TRUE;
104 #if OSL_DEBUG_LEVEL>0
105 debug_printf( "SalSysObjWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg);
106 #endif
108 switch( nMsg )
110 case WM_ERASEBACKGROUND:
111 nRet = (MRESULT)FALSE;
112 bDef = FALSE;
113 break;
114 case WM_PAINT:
116 HPS hPS;
117 RECTL aRect;
118 hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
119 WinEndPaint( hPS );
120 bDef = FALSE;
122 bDef = FALSE;
123 break;
125 case WM_BUTTON1DOWN:
126 case WM_BUTTON2DOWN:
127 case WM_BUTTON3DOWN:
128 case SALOBJ_MSG_TOTOP:
129 if ( ImplSalYieldMutexTryToAcquire() )
131 pSysObj = GetSalObjWindowPtr( hWnd );
132 pSysObj->mpProc( pSysObj->mpInst, pSysObj,
133 SALOBJ_EVENT_TOTOP, 0 );
134 ImplSalYieldMutexRelease();
136 else
137 WinPostMsg( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
138 break;
140 case WM_FOCUSCHANGE:
141 case SALOBJ_MSG_POSTFOCUS:
142 if ( ImplSalYieldMutexTryToAcquire() )
144 pSysObj = GetSalObjWindowPtr( hWnd );
145 if ( SHORT1FROMMP( nMP2 ) )
147 pSysObj->mhLastFocusWnd = WinQueryFocus( HWND_DESKTOP );
148 pSysObj->mpProc( pSysObj->mpInst, pSysObj,
149 SALOBJ_EVENT_GETFOCUS, 0 );
151 else
153 HWND hWndFocus = HWNDFROMMP( nMP1 );
154 if ( !hWndFocus || !ImplIsSysWindowOrChild( hWnd, hWndFocus ) )
156 pSysObj->mpProc( pSysObj->mpInst, pSysObj,
157 SALOBJ_EVENT_LOSEFOCUS, 0 );
160 ImplSalYieldMutexRelease();
162 else
163 WinPostMsg( hWnd, SALOBJ_MSG_POSTFOCUS, nMP1, nMP2 );
164 break;
166 case WM_SIZE:
168 pSysObj = GetSalObjWindowPtr( hWnd );
169 pSysObj->mnHeight = (short)SHORT2FROMMP( nMP2 );
170 WinSetWindowPos( pSysObj->mhWndChild, 0,
171 0, 0,
172 (short)SHORT1FROMMP( nMP2 ), (short)SHORT2FROMMP( nMP2 ),
173 SWP_SIZE | SWP_MOVE );
174 bDef = FALSE;
176 break;
178 case WM_CREATE:
180 // Window-Instanz am Windowhandle speichern
181 CREATESTRUCT* pStruct = (CREATESTRUCT*)nMP2;
182 pSysObj = (Os2SalObject*)pStruct->pPresParams;
183 SetSalObjWindowPtr( hWnd, pSysObj );
184 bDef = FALSE;
186 break;
189 if ( bDef )
190 nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
191 return nRet;
194 // -----------------------------------------------------------------------
196 MRESULT EXPENTRY SalSysObjChildWndProc( HWND hWnd, ULONG nMsg,
197 MPARAM nMP1, MPARAM nMP2 )
199 MRESULT nRet = 0;
200 int bDef = TRUE;
202 debug_printf( "SalSysObjChildWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg);
204 switch( nMsg )
206 case WM_ERASEBACKGROUND:
207 // Wegen PlugIn's loeschen wir erstmal den Hintergrund
209 nRet = (MRESULT)FALSE;
210 bDef = FALSE;
212 break;
213 case WM_PAINT:
215 HPS hPS;
216 RECTL aRect;
217 hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
218 WinEndPaint( hPS );
219 bDef = FALSE;
221 break;
224 if ( bDef )
225 nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
226 return nRet;
229 // -----------------------------------------------------------------------
231 MRESULT EXPENTRY SalSysObjClipWndProc( HWND hWnd, ULONG nMsg,
232 MPARAM nMP1, MPARAM nMP2 )
234 MRESULT nRet = 0;
235 int bDef = TRUE;
237 debug_printf( "SalSysObjClipWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg);
239 switch( nMsg )
241 case WM_MOUSEMOVE:
242 case WM_BUTTON1DOWN:
243 case WM_BUTTON2DOWN:
244 case WM_BUTTON3DOWN:
245 case WM_BUTTON1DBLCLK:
246 case WM_BUTTON2DBLCLK:
247 case WM_BUTTON3DBLCLK:
248 case WM_BUTTON1UP:
249 case WM_BUTTON2UP:
250 case WM_BUTTON3UP:
252 // Alle Events an den Frame weiterreichen, da diese Bereiche
253 // dem Frame gehoeren. Dazu muessen die Mouse-Koordinaaten
254 // entsprechend umgerechnet werden
255 HWND hWndParent = WinQueryWindow( hWnd, QW_PARENT ); // ergibt SysChild-Fenster
256 hWndParent = WinQueryWindow( hWndParent, QW_PARENT );
257 short nX = (short)SHORT1FROMMP( nMP1 );
258 short nY = (short)SHORT2FROMMP( nMP1 );
259 POINTL aPos;
260 aPos.x = nX;
261 aPos.y = nY;
262 WinMapWindowPoints( hWnd, hWndParent, &aPos, 1 );
263 nMP1 = MPFROM2SHORT( (short)aPos.x, (short)aPos.y );
264 bDef = FALSE;
265 nRet = WinSendMsg( hWndParent, nMsg, nMP1, nMP2 );
267 break;
269 case WM_HITTEST:
270 // Damit im disablten Zustand die MouseKlicks immer noch
271 // an den Frame geschickt werden
272 // Dieser Code reicht leider nicht aus, deshalb wir unter
273 // OS2 immer das Child-Fenster disablen, im Gegensatz
274 // zu Windows, wo immer der Parent disablte wird, da
275 // sich das Fenster evtl. anders Darstellen koennte,
276 // wenn es disablte wird. Da dieser Fall uns bisher
277 // nicht bekannt ist, ignorieren wir das.
278 nRet = HT_NORMAL;
279 bDef = FALSE;
280 break;
282 case WM_ERASEBACKGROUND:
283 nRet = (MRESULT)FALSE;
284 bDef = FALSE;
285 break;
286 case WM_PAINT:
288 HPS hPS;
289 RECTL aRect;
290 hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
291 WinEndPaint( hPS );
292 bDef = FALSE;
294 break;
297 if ( bDef )
298 nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
299 return nRet;
302 // =======================================================================
304 void ImplDestroyAllClipWindows( HWND hWndLast )
306 if ( hWndLast == HWND_TOP )
307 return;
309 HWND hWndPrev;
310 while ( hWndLast )
312 hWndPrev = WinQueryWindow( hWndLast, QW_PREV );
313 WinDestroyWindow( hWndLast );
314 hWndLast = hWndPrev;
318 // =======================================================================
320 SalObject* ImplSalCreateObject( Os2SalInstance* pInst, Os2SalFrame* pParent )
322 SalData* pSalData = GetSalData();
324 if ( !pSalData->mbObjClassInit )
326 if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CLASSNAME,
327 (PFNWP)SalSysObjWndProc, CS_MOVENOTIFY,
328 SAL_OBJECT_WNDEXTRA ) )
330 if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CLIPCLASSNAME,
331 (PFNWP)SalSysObjClipWndProc, CS_HITTEST | CS_MOVENOTIFY, 0 ) )
333 if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CHILDCLASSNAME,
334 (PFNWP)SalSysObjChildWndProc, CS_HITTEST | CS_MOVENOTIFY, 32 ) )
335 pSalData->mbObjClassInit = TRUE;
340 if ( pSalData->mbObjClassInit )
342 Os2SalObject* pObject = new Os2SalObject;
343 HWND hWnd = WinCreateWindow( pParent->mhWndClient, SAL_OBJECT_CLASSNAME, "",
345 0, 0, 0, 0,
346 pParent->mhWndClient, HWND_TOP,
347 0, NULL, (void*)pObject );
348 HWND hWndChild = WinCreateWindow( hWnd, SAL_OBJECT_CHILDCLASSNAME, "",
349 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
350 0, 0, 0, 0,
351 hWnd, HWND_TOP,
352 0, NULL, NULL );
354 if ( !hWndChild )
356 if ( hWnd )
357 WinDestroyWindow( hWnd );
358 delete pObject;
359 return NULL;
362 if ( hWnd )
364 debug_printf("ImplSalCreateObject hWndChild %x\n", hWndChild);
365 debug_printf("ImplSalCreateObject hWnd %x\n", hWnd);
366 pObject->mhWnd = hWnd;
367 pObject->mhWndChild = hWndChild;
368 pObject->maSysData.hWnd = hWndChild;
369 return pObject;
373 return NULL;
376 // =======================================================================
378 long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* )
380 return 0;
383 // =======================================================================
385 Os2SalObject::Os2SalObject()
387 SalData* pSalData = GetSalData();
389 mhLastClipWnd = HWND_TOP;
391 mhWnd = 0;
392 mhWndChild = 0;
393 mhLastFocusWnd = 0;
394 maSysData.nSize = sizeof( SystemEnvData );
395 mnHeight = 0;
396 mpInst = NULL;
397 mpProc = ImplSalObjCallbackDummy;
399 // Hook installieren, wenn es das erste Os2SalObject ist
400 if ( !pSalData->mpFirstObject )
402 WinSetHook( pSalData->mhAB, pSalData->mhMQ,
403 HK_INPUT, (PFN)SalSysMsgProc, (HMODULE)0 );
406 // Insert object in objectlist
407 mpNextObject = pSalData->mpFirstObject;
408 pSalData->mpFirstObject = this;
411 // -----------------------------------------------------------------------
413 Os2SalObject::~Os2SalObject()
415 SalData* pSalData = GetSalData();
417 // remove frame from framelist
418 if ( this == pSalData->mpFirstObject )
420 pSalData->mpFirstObject = mpNextObject;
422 // Wenn letztes Os2SalObject, dann Hook wieder entfernen
423 if ( !pSalData->mpFirstObject )
425 WinReleaseHook( pSalData->mhAB, pSalData->mhMQ,
426 HK_INPUT, (PFN)SalSysMsgProc, (HMODULE)0 );
429 else
431 Os2SalObject* pTempObject = pSalData->mpFirstObject;
432 while ( pTempObject->mpNextObject != this )
433 pTempObject = pTempObject->mpNextObject;
435 pTempObject->mpNextObject = mpNextObject;
438 // Cache-Daten zerstoeren
439 ImplDestroyAllClipWindows( mhLastClipWnd );
441 if ( mhWndChild )
442 WinDestroyWindow( mhWndChild );
443 if ( mhWnd )
444 WinDestroyWindow( mhWnd );
447 // -----------------------------------------------------------------------
449 void Os2SalObject::ResetClipRegion()
451 ImplDestroyAllClipWindows( mhLastClipWnd );
452 mhLastClipWnd = HWND_TOP;
455 // -----------------------------------------------------------------------
457 USHORT Os2SalObject::GetClipRegionType()
459 return SAL_OBJECT_CLIP_EXCLUDERECTS;
462 // -----------------------------------------------------------------------
464 void Os2SalObject::BeginSetClipRegion( ULONG nRectCount )
466 mhOldLastClipWnd = mhLastClipWnd;
469 // -----------------------------------------------------------------------
471 void Os2SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
473 HWND hClipWnd = WinCreateWindow( mhWnd, SAL_OBJECT_CLIPCLASSNAME, "",
474 WS_VISIBLE,
475 nX, mnHeight-(nY+nHeight), nWidth, nHeight,
476 mhWnd, mhLastClipWnd,
477 0, NULL, NULL );
478 debug_printf("Os2SalObject::UnionClipRegion hClipWnd %x\n", hClipWnd);
479 mhLastClipWnd = hClipWnd;
482 // -----------------------------------------------------------------------
484 void Os2SalObject::EndSetClipRegion()
486 ImplDestroyAllClipWindows( mhOldLastClipWnd );
489 // -----------------------------------------------------------------------
491 void Os2SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
493 ULONG nStyle = 0;
494 BOOL bVisible = WinIsWindowVisible( mhWnd );
495 if ( bVisible )
497 WinShowWindow( mhWnd, FALSE );
498 nStyle |= SWP_SHOW;
500 SWP aParentSWP;
501 WinQueryWindowPos( WinQueryWindow( mhWnd, QW_PARENT ), &aParentSWP );
502 WinSetWindowPos( mhWnd, 0, nX, aParentSWP.cy-(nY+nHeight), nWidth, nHeight,
503 SWP_MOVE | SWP_SIZE | nStyle );
506 // -----------------------------------------------------------------------
508 void Os2SalObject::Show( BOOL bVisible )
510 WinShowWindow( mhWnd, bVisible );
513 // -----------------------------------------------------------------------
515 void Os2SalObject::Enable( BOOL bEnable )
517 // Im Gegensatz zu Windows disablen wir das Childfenster,
518 // da ansonsten unser Clippen nicht mehr funktioniert, da
519 // wir keine Events mehr bekommen. Dadurch kann sich evtl.
520 // das Fenster anders darstellen, was wir eigentlich nicht
521 // wollen. Aber da uns bisher kein Fall bekannt ist,
522 // ignorieren wir dies. Ansonsten muss ein Fenster dazwischen
523 // gezogen werden oder getestet werden, wie wir die
524 // Maustransparenz erreichen, wenn mhWnd
525 // disablte wird.
526 WinEnableWindow( mhWndChild, bEnable );
529 // -----------------------------------------------------------------------
531 void Os2SalObject::GrabFocus()
533 if ( mhLastFocusWnd &&
534 WinIsWindow( GetSalData()->mhAB, mhLastFocusWnd ) &&
535 ImplIsSysWindowOrChild( mhWndChild, mhLastFocusWnd ) )
536 WinSetFocus( HWND_DESKTOP, mhLastFocusWnd );
537 else
538 WinSetFocus( HWND_DESKTOP, mhWndChild );
541 // -----------------------------------------------------------------------
543 void Os2SalObject::SetBackground()
547 // -----------------------------------------------------------------------
549 void Os2SalObject::SetBackground( SalColor nSalColor )
553 // -----------------------------------------------------------------------
555 const SystemChildData* Os2SalObject::GetSystemData() const
557 return &maSysData;
560 // -----------------------------------------------------------------------
561 #if 0
562 void Os2SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc )
564 mpInst = pInst;
565 if ( pProc )
566 mpProc = pProc;
567 else
568 mpProc = ImplSalObjCallbackDummy;
570 #endif