| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include <svpm.h> |
| |
| #include <string.h> |
| |
| #include <tools/debug.hxx> |
| #include <tools/svwin.h> |
| |
| #include "vcl/svapp.hxx" |
| |
| #include "os2/saldata.hxx" |
| #include "os2/salinst.h" |
| #include "os2/salframe.h" |
| #include "os2/salobj.h" |
| |
| // ======================================================================= |
| |
| static sal_Bool ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild ) |
| { |
| if ( hWndParent == hWndChild ) |
| return TRUE; |
| |
| HWND hTempWnd = WinQueryWindow( hWndChild, QW_PARENT ); |
| while ( hTempWnd ) |
| { |
| if ( hTempWnd == hWndParent ) |
| return TRUE; |
| hTempWnd = WinQueryWindow( hTempWnd, QW_PARENT ); |
| } |
| |
| return FALSE; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| static Os2SalObject* ImplFindOs2SalObject( HWND hWndChild ) |
| { |
| SalData* pSalData = GetSalData(); |
| Os2SalObject* pObject = pSalData->mpFirstObject; |
| while ( pObject ) |
| { |
| if ( ImplIsSysWindowOrChild( pObject->mhWndChild, hWndChild ) ) |
| return pObject; |
| |
| pObject = pObject->mpNextObject; |
| } |
| |
| return NULL; |
| } |
| |
| // ======================================================================= |
| |
| sal_Bool EXPENTRY SalSysMsgProc( HAB /* hAB */, QMSG* pMsg, ULONG /* fs */ ) |
| { |
| if ( (pMsg->msg == WM_BUTTON1DOWN) || |
| (pMsg->msg == WM_BUTTON2DOWN) || |
| (pMsg->msg == WM_BUTTON3DOWN) ) |
| { |
| SalData* pSalData = GetSalData(); |
| Os2SalObject* pObject = ImplFindOs2SalObject( pMsg->hwnd ); |
| if ( pObject ) |
| WinPostMsg( pObject->mhWnd, SALOBJ_MSG_TOTOP, 0, 0 ); |
| } |
| |
| // Focus fangen wir hier nicht ab, da wir erstmal davon ausgehen, |
| // das unser Os2SalObject-Fenster immer eine WM_FOCUSCHANGE-Message |
| // bekommt. |
| |
| return FALSE; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| MRESULT EXPENTRY SalSysObjWndProc( HWND hWnd, ULONG nMsg, |
| MPARAM nMP1, MPARAM nMP2 ) |
| { |
| Os2SalObject* pSysObj; |
| MRESULT nRet = 0; |
| int bDef = TRUE; |
| |
| #if OSL_DEBUG_LEVEL>0 |
| debug_printf( "SalSysObjWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg); |
| #endif |
| |
| switch( nMsg ) |
| { |
| case WM_ERASEBACKGROUND: |
| nRet = (MRESULT)FALSE; |
| bDef = FALSE; |
| break; |
| case WM_PAINT: |
| { |
| HPS hPS; |
| RECTL aRect; |
| hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect ); |
| WinEndPaint( hPS ); |
| bDef = FALSE; |
| } |
| bDef = FALSE; |
| break; |
| |
| case WM_BUTTON1DOWN: |
| case WM_BUTTON2DOWN: |
| case WM_BUTTON3DOWN: |
| case SALOBJ_MSG_TOTOP: |
| if ( ImplSalYieldMutexTryToAcquire() ) |
| { |
| pSysObj = GetSalObjWindowPtr( hWnd ); |
| pSysObj->mpProc( pSysObj->mpInst, pSysObj, |
| SALOBJ_EVENT_TOTOP, 0 ); |
| ImplSalYieldMutexRelease(); |
| } |
| else |
| WinPostMsg( hWnd, SALOBJ_MSG_TOTOP, 0, 0 ); |
| break; |
| |
| case WM_FOCUSCHANGE: |
| case SALOBJ_MSG_POSTFOCUS: |
| if ( ImplSalYieldMutexTryToAcquire() ) |
| { |
| pSysObj = GetSalObjWindowPtr( hWnd ); |
| if ( SHORT1FROMMP( nMP2 ) ) |
| { |
| pSysObj->mhLastFocusWnd = WinQueryFocus( HWND_DESKTOP ); |
| pSysObj->mpProc( pSysObj->mpInst, pSysObj, |
| SALOBJ_EVENT_GETFOCUS, 0 ); |
| } |
| else |
| { |
| HWND hWndFocus = HWNDFROMMP( nMP1 ); |
| if ( !hWndFocus || !ImplIsSysWindowOrChild( hWnd, hWndFocus ) ) |
| { |
| pSysObj->mpProc( pSysObj->mpInst, pSysObj, |
| SALOBJ_EVENT_LOSEFOCUS, 0 ); |
| } |
| } |
| ImplSalYieldMutexRelease(); |
| } |
| else |
| WinPostMsg( hWnd, SALOBJ_MSG_POSTFOCUS, nMP1, nMP2 ); |
| break; |
| |
| case WM_SIZE: |
| { |
| pSysObj = GetSalObjWindowPtr( hWnd ); |
| pSysObj->mnHeight = (short)SHORT2FROMMP( nMP2 ); |
| WinSetWindowPos( pSysObj->mhWndChild, 0, |
| 0, 0, |
| (short)SHORT1FROMMP( nMP2 ), (short)SHORT2FROMMP( nMP2 ), |
| SWP_SIZE | SWP_MOVE ); |
| bDef = FALSE; |
| } |
| break; |
| |
| case WM_CREATE: |
| { |
| // Window-Instanz am Windowhandle speichern |
| CREATESTRUCT* pStruct = (CREATESTRUCT*)nMP2; |
| pSysObj = (Os2SalObject*)pStruct->pPresParams; |
| SetSalObjWindowPtr( hWnd, pSysObj ); |
| bDef = FALSE; |
| } |
| break; |
| } |
| |
| if ( bDef ) |
| nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 ); |
| return nRet; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| MRESULT EXPENTRY SalSysObjChildWndProc( HWND hWnd, ULONG nMsg, |
| MPARAM nMP1, MPARAM nMP2 ) |
| { |
| MRESULT nRet = 0; |
| int bDef = TRUE; |
| |
| #if OSL_DEBUG_LEVEL>0 |
| debug_printf( "SalSysObjChildWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg); |
| #endif |
| |
| switch( nMsg ) |
| { |
| case WM_ERASEBACKGROUND: |
| // Wegen PlugIn's loeschen wir erstmal den Hintergrund |
| /* |
| nRet = (MRESULT)FALSE; |
| bDef = FALSE; |
| */ |
| break; |
| case WM_PAINT: |
| { |
| HPS hPS; |
| RECTL aRect; |
| hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect ); |
| WinEndPaint( hPS ); |
| bDef = FALSE; |
| } |
| break; |
| } |
| |
| if ( bDef ) |
| nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 ); |
| return nRet; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| MRESULT EXPENTRY SalSysObjClipWndProc( HWND hWnd, ULONG nMsg, |
| MPARAM nMP1, MPARAM nMP2 ) |
| { |
| MRESULT nRet = 0; |
| int bDef = TRUE; |
| |
| #if OSL_DEBUG_LEVEL>0 |
| debug_printf( "SalSysObjClipWndProc hWnd 0x%x nMsg %d\n", hWnd, nMsg); |
| #endif |
| |
| switch( nMsg ) |
| { |
| case WM_MOUSEMOVE: |
| case WM_BUTTON1DOWN: |
| case WM_BUTTON2DOWN: |
| case WM_BUTTON3DOWN: |
| case WM_BUTTON1DBLCLK: |
| case WM_BUTTON2DBLCLK: |
| case WM_BUTTON3DBLCLK: |
| case WM_BUTTON1UP: |
| case WM_BUTTON2UP: |
| case WM_BUTTON3UP: |
| { |
| // Alle Events an den Frame weiterreichen, da diese Bereiche |
| // dem Frame gehoeren. Dazu muessen die Mouse-Koordinaaten |
| // entsprechend umgerechnet werden |
| HWND hWndParent = WinQueryWindow( hWnd, QW_PARENT ); // ergibt SysChild-Fenster |
| hWndParent = WinQueryWindow( hWndParent, QW_PARENT ); |
| short nX = (short)SHORT1FROMMP( nMP1 ); |
| short nY = (short)SHORT2FROMMP( nMP1 ); |
| POINTL aPos; |
| aPos.x = nX; |
| aPos.y = nY; |
| WinMapWindowPoints( hWnd, hWndParent, &aPos, 1 ); |
| nMP1 = MPFROM2SHORT( (short)aPos.x, (short)aPos.y ); |
| bDef = FALSE; |
| nRet = WinSendMsg( hWndParent, nMsg, nMP1, nMP2 ); |
| } |
| break; |
| |
| case WM_HITTEST: |
| // Damit im disablten Zustand die MouseKlicks immer noch |
| // an den Frame geschickt werden |
| // Dieser Code reicht leider nicht aus, deshalb wir unter |
| // OS2 immer das Child-Fenster disablen, im Gegensatz |
| // zu Windows, wo immer der Parent disablte wird, da |
| // sich das Fenster evtl. anders Darstellen koennte, |
| // wenn es disablte wird. Da dieser Fall uns bisher |
| // nicht bekannt ist, ignorieren wir das. |
| nRet = HT_NORMAL; |
| bDef = FALSE; |
| break; |
| |
| case WM_ERASEBACKGROUND: |
| nRet = (MRESULT)FALSE; |
| bDef = FALSE; |
| break; |
| case WM_PAINT: |
| { |
| HPS hPS; |
| RECTL aRect; |
| hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect ); |
| WinEndPaint( hPS ); |
| bDef = FALSE; |
| } |
| break; |
| } |
| |
| if ( bDef ) |
| nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 ); |
| return nRet; |
| } |
| |
| // ======================================================================= |
| |
| void ImplDestroyAllClipWindows( HWND hWndLast ) |
| { |
| if ( hWndLast == HWND_TOP ) |
| return; |
| |
| HWND hWndPrev; |
| while ( hWndLast ) |
| { |
| hWndPrev = WinQueryWindow( hWndLast, QW_PREV ); |
| WinDestroyWindow( hWndLast ); |
| hWndLast = hWndPrev; |
| } |
| } |
| |
| // ======================================================================= |
| |
| SalObject* ImplSalCreateObject( Os2SalInstance* pInst, Os2SalFrame* pParent ) |
| { |
| SalData* pSalData = GetSalData(); |
| |
| if ( !pSalData->mbObjClassInit ) |
| { |
| if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CLASSNAME, |
| (PFNWP)SalSysObjWndProc, CS_MOVENOTIFY, |
| SAL_OBJECT_WNDEXTRA ) ) |
| { |
| if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CLIPCLASSNAME, |
| (PFNWP)SalSysObjClipWndProc, CS_HITTEST | CS_MOVENOTIFY, 0 ) ) |
| { |
| if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CHILDCLASSNAME, |
| (PFNWP)SalSysObjChildWndProc, CS_HITTEST | CS_MOVENOTIFY, 32 ) ) |
| pSalData->mbObjClassInit = TRUE; |
| } |
| } |
| } |
| |
| if ( pSalData->mbObjClassInit ) |
| { |
| Os2SalObject* pObject = new Os2SalObject; |
| HWND hWnd = WinCreateWindow( pParent->mhWndClient, SAL_OBJECT_CLASSNAME, "", |
| 0, |
| 0, 0, 0, 0, |
| pParent->mhWndClient, HWND_TOP, |
| 0, NULL, (void*)pObject ); |
| HWND hWndChild = WinCreateWindow( hWnd, SAL_OBJECT_CHILDCLASSNAME, "", |
| WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE, |
| 0, 0, 0, 0, |
| hWnd, HWND_TOP, |
| 0, NULL, NULL ); |
| |
| if ( !hWndChild ) |
| { |
| if ( hWnd ) |
| WinDestroyWindow( hWnd ); |
| delete pObject; |
| return NULL; |
| } |
| |
| if ( hWnd ) |
| { |
| #if OSL_DEBUG_LEVEL>0 |
| debug_printf("ImplSalCreateObject hWndChild %x\n", hWndChild); |
| debug_printf("ImplSalCreateObject hWnd %x\n", hWnd); |
| #endif |
| pObject->mhWnd = hWnd; |
| pObject->mhWndChild = hWndChild; |
| pObject->maSysData.hWnd = hWndChild; |
| return pObject; |
| } |
| } |
| |
| return NULL; |
| } |
| |
| // ======================================================================= |
| |
| long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* ) |
| { |
| return 0; |
| } |
| |
| // ======================================================================= |
| |
| Os2SalObject::Os2SalObject() |
| { |
| SalData* pSalData = GetSalData(); |
| |
| mhLastClipWnd = HWND_TOP; |
| |
| mhWnd = 0; |
| mhWndChild = 0; |
| mhLastFocusWnd = 0; |
| maSysData.nSize = sizeof( SystemEnvData ); |
| mnHeight = 0; |
| mpInst = NULL; |
| mpProc = ImplSalObjCallbackDummy; |
| |
| // Hook installieren, wenn es das erste Os2SalObject ist |
| if ( !pSalData->mpFirstObject ) |
| { |
| WinSetHook( pSalData->mhAB, pSalData->mhMQ, |
| HK_INPUT, (PFN)SalSysMsgProc, (HMODULE)0 ); |
| } |
| |
| // Insert object in objectlist |
| mpNextObject = pSalData->mpFirstObject; |
| pSalData->mpFirstObject = this; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Os2SalObject::~Os2SalObject() |
| { |
| SalData* pSalData = GetSalData(); |
| |
| // remove frame from framelist |
| if ( this == pSalData->mpFirstObject ) |
| { |
| pSalData->mpFirstObject = mpNextObject; |
| |
| // Wenn letztes Os2SalObject, dann Hook wieder entfernen |
| if ( !pSalData->mpFirstObject ) |
| { |
| WinReleaseHook( pSalData->mhAB, pSalData->mhMQ, |
| HK_INPUT, (PFN)SalSysMsgProc, (HMODULE)0 ); |
| } |
| } |
| else |
| { |
| Os2SalObject* pTempObject = pSalData->mpFirstObject; |
| while ( pTempObject->mpNextObject != this ) |
| pTempObject = pTempObject->mpNextObject; |
| |
| pTempObject->mpNextObject = mpNextObject; |
| } |
| |
| // Cache-Daten zerstoeren |
| ImplDestroyAllClipWindows( mhLastClipWnd ); |
| |
| if ( mhWndChild ) |
| WinDestroyWindow( mhWndChild ); |
| if ( mhWnd ) |
| WinDestroyWindow( mhWnd ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::ResetClipRegion() |
| { |
| ImplDestroyAllClipWindows( mhLastClipWnd ); |
| mhLastClipWnd = HWND_TOP; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| USHORT Os2SalObject::GetClipRegionType() |
| { |
| return SAL_OBJECT_CLIP_EXCLUDERECTS; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::BeginSetClipRegion( ULONG nRectCount ) |
| { |
| mhOldLastClipWnd = mhLastClipWnd; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) |
| { |
| HWND hClipWnd = WinCreateWindow( mhWnd, SAL_OBJECT_CLIPCLASSNAME, "", |
| WS_VISIBLE, |
| nX, mnHeight-(nY+nHeight), nWidth, nHeight, |
| mhWnd, mhLastClipWnd, |
| 0, NULL, NULL ); |
| #if OSL_DEBUG_LEVEL>0 |
| debug_printf("Os2SalObject::UnionClipRegion hClipWnd %x\n", hClipWnd); |
| #endif |
| mhLastClipWnd = hClipWnd; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::EndSetClipRegion() |
| { |
| ImplDestroyAllClipWindows( mhOldLastClipWnd ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight ) |
| { |
| ULONG nStyle = 0; |
| sal_Bool bVisible = WinIsWindowVisible( mhWnd ); |
| if ( bVisible ) |
| { |
| WinShowWindow( mhWnd, FALSE ); |
| nStyle |= SWP_SHOW; |
| } |
| SWP aParentSWP; |
| WinQueryWindowPos( WinQueryWindow( mhWnd, QW_PARENT ), &aParentSWP ); |
| WinSetWindowPos( mhWnd, 0, nX, aParentSWP.cy-(nY+nHeight), nWidth, nHeight, |
| SWP_MOVE | SWP_SIZE | nStyle ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::Show( sal_Bool bVisible ) |
| { |
| WinShowWindow( mhWnd, bVisible ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::Enable( sal_Bool bEnable ) |
| { |
| // Im Gegensatz zu Windows disablen wir das Childfenster, |
| // da ansonsten unser Clippen nicht mehr funktioniert, da |
| // wir keine Events mehr bekommen. Dadurch kann sich evtl. |
| // das Fenster anders darstellen, was wir eigentlich nicht |
| // wollen. Aber da uns bisher kein Fall bekannt ist, |
| // ignorieren wir dies. Ansonsten muss ein Fenster dazwischen |
| // gezogen werden oder getestet werden, wie wir die |
| // Maustransparenz erreichen, wenn mhWnd |
| // disablte wird. |
| WinEnableWindow( mhWndChild, bEnable ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::GrabFocus() |
| { |
| if ( mhLastFocusWnd && |
| WinIsWindow( GetSalData()->mhAB, mhLastFocusWnd ) && |
| ImplIsSysWindowOrChild( mhWndChild, mhLastFocusWnd ) ) |
| WinSetFocus( HWND_DESKTOP, mhLastFocusWnd ); |
| else |
| WinSetFocus( HWND_DESKTOP, mhWndChild ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::SetBackground() |
| { |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::SetBackground( SalColor nSalColor ) |
| { |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| const SystemChildData* Os2SalObject::GetSystemData() const |
| { |
| return &maSysData; |
| } |
| |
| // ----------------------------------------------------------------------- |
| #if 0 |
| void Os2SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc ) |
| { |
| mpInst = pInst; |
| if ( pProc ) |
| mpProc = pProc; |
| else |
| mpProc = ImplSalObjCallbackDummy; |
| } |
| #endif |
| |
| // ----------------------------------------------------------------------- |
| |
| void Os2SalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) |
| { |
| } |
| |