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