diff options
Diffstat (limited to 'vcl/os2/source/window/salframe.cxx')
-rw-r--r-- | vcl/os2/source/window/salframe.cxx | 3774 |
1 files changed, 3774 insertions, 0 deletions
diff --git a/vcl/os2/source/window/salframe.cxx b/vcl/os2/source/window/salframe.cxx new file mode 100644 index 000000000000..f3314c725255 --- /dev/null +++ b/vcl/os2/source/window/salframe.cxx @@ -0,0 +1,3774 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <string.h> + +#define INCL_DOS +#define INCL_PM +#define INCL_WIN +#include <svpm.h> + +// ======================================================================= + +#define _SV_SALFRAME_CXX + +#ifndef DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#define private public + +#ifndef _SV_SALLANG_HXX +#include <sallang.hxx> +#endif +#ifndef _SV_SALIDS_HRC +#include <salids.hrc> +#endif +#include <saldata.hxx> +#include <salinst.h> +#include <salgdi.h> +#include <salframe.h> +#include <vcl/timer.hxx> +#include <vcl/settings.hxx> +#ifndef _SV_KEYCOES_HXX +#include <vcl/keycodes.hxx> +#endif +#include <saltimer.h> + +#if OSL_DEBUG_LEVEL>10 +extern "C" int debug_printf(const char *f, ...); + +static BOOL _bCapture; + +#else +#define debug_printf( ...) { 1; } +#endif + +// ======================================================================= + +HPOINTER ImplLoadPointer( ULONG nId ); + +static void SetMaximizedFrameGeometry( HWND hWnd, Os2SalFrame* pFrame ); +static void UpdateFrameGeometry( HWND hWnd, Os2SalFrame* pFrame ); +static void ImplSalCalcFrameSize( HWND hWnd, + LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY ); +static void ImplSalCalcFrameSize( const Os2SalFrame* pFrame, + LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY ); +MRESULT EXPENTRY SalFrameSubClassWndProc( HWND hWnd, ULONG nMsg, + MPARAM nMP1, MPARAM nMP2 ); + +// ======================================================================= + +static LanguageType eImplKeyboardLanguage = LANGUAGE_DONTKNOW; +BOOL Os2SalFrame::mbInReparent = FALSE; +ULONG Os2SalFrame::mnInputLang = 0; + +// ======================================================================= + +// define a new flag +#define SWP_CENTER (SWP_NOAUTOCLOSE<<4) +#define SWP_SHOWMAXIMIZED (SWP_ACTIVATE | SWP_SHOW | SWP_MAXIMIZE) +#define SWP_SHOWMINIMIZED (SWP_ACTIVATE | SWP_SHOW | SWP_MINIMIZE) +#define SWP_SHOWNORMAL (SWP_ACTIVATE | SWP_SHOW | SWP_RESTORE) + +static LONG nScreenHeight = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN); +static LONG nScreenWidth = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); + +BOOL APIENTRY _WinQueryWindowRect( HWND hwnd, PRECTL prclDest) +{ + BOOL rc = WinQueryWindowRect( hwnd, prclDest); + ULONG tmp = prclDest->yBottom; + prclDest->yBottom = prclDest->yTop; + prclDest->yTop = tmp; + return rc; +} + +BOOL APIENTRY _WinQueryPointerPos (HWND hwndDesktop, PPOINTL pptl) +{ + BOOL rc = WinQueryPointerPos( hwndDesktop, pptl); + pptl->y = nScreenHeight - pptl->y; + return rc; +} + +BOOL APIENTRY _WinQueryWindowPos( Os2SalFrame* pFrame, PSWP pswp) +{ + SWP swpOwner; + BOOL rc = WinQueryWindowPos( pFrame->mhWndFrame, pswp); + +#if OSL_DEBUG_LEVEL>1 + debug_printf( "> WinQueryWindowPos hwnd %x at %d,%d (%dx%d)\n", + pFrame->mhWndFrame, pswp->x, pswp->y, pswp->cx, pswp->cy); +#endif + + Os2SalFrame* pParentFrame = pFrame->mpParentFrame; + + //YD adjust to owner coordinates + if ( pParentFrame ) + { + POINTL ptlOwner = {0}; + + // coords are relative to screen, map to parent frame client area + ptlOwner.x = pswp->x; + ptlOwner.y = pswp->y; + WinMapWindowPoints( HWND_DESKTOP, pParentFrame->mhWndClient, &ptlOwner, 1); + pswp->x = ptlOwner.x; + pswp->y = ptlOwner.y; + // get parent client area size + WinQueryWindowPos( pParentFrame->mhWndClient, &swpOwner); + } else + { + // no owner info, use DESKTOP???? + swpOwner.cx = nScreenWidth; + swpOwner.cy = nScreenHeight; + } + + // invert Y coordinate + pswp->y = swpOwner.cy - (pswp->y + pswp->cy); + +#if OSL_DEBUG_LEVEL>1 + debug_printf( "< WinQueryWindowPos hwnd %x at %d,%d (%dx%d)\n", + pFrame->mhWndFrame, pswp->x, pswp->y, pswp->cx, pswp->cy); +#endif + return rc; +} + +BOOL APIENTRY _WinSetWindowPos( Os2SalFrame* pFrame, HWND hwndInsertBehind, LONG x, LONG y, + LONG cx, LONG cy, ULONG fl) +{ + SWP swpOwner = {0}; + POINTL ptlOwner = {0}; + HWND hParent = NULL; + +#if OSL_DEBUG_LEVEL>1 + debug_printf( ">WinSetWindowPos hwnd %x at %d,%d (%dx%d) fl 0x%08x\n", + pFrame->mhWndFrame, x, y, cx, cy, fl); +#endif + + // first resize window if requested + if ( (fl & SWP_SIZE) ) { + ULONG flag = SWP_SIZE; + LONG nX = 0, nY = 0; + LONG frameFrameX, frameFrameY, frameCaptionY; + + ImplSalCalcFrameSize( pFrame, frameFrameX, frameFrameY, frameCaptionY ); + // if we change y size, we need to move the window down + // because os2 window origin is lower left corner + if (pFrame->maGeometry.nHeight != cy) { + SWP aSWP; + WinQueryWindowPos( pFrame->mhWndFrame, &aSWP); + nX = aSWP.x; + nY = aSWP.y - (cy + 2*frameFrameY + frameCaptionY - aSWP.cy); + flag |= SWP_MOVE; + } + WinSetWindowPos( pFrame->mhWndFrame, NULL, nX, nY, + cx+2*frameFrameX, cy+2*frameFrameY+frameCaptionY, flag); + fl = fl & ~SWP_SIZE; + } + else // otherwise get current size + { + SWP swp = {0}; + WinQueryWindowPos( pFrame->mhWndClient, &swp); + cx = swp.cx; + cy = swp.cy; + } + + // get parent window handle + Os2SalFrame* pParentFrame = pFrame->mpParentFrame; + + // use desktop if parent is not defined + hParent = pParentFrame ? pParentFrame->mhWndClient : HWND_DESKTOP; + // if parent is not visible, use desktop as reference + hParent = WinIsWindowVisible( hParent) ? hParent : HWND_DESKTOP; + + WinQueryWindowPos( hParent, &swpOwner); + + //YD adjust to owner coordinates only when moving and not centering + //if (!(fl & SWP_CENTER) && (fl & SWP_MOVE)) + if ((fl & SWP_MOVE)) + { + + // if SWP_CENTER is specified, change position to parent center + if (fl & SWP_CENTER) { + ptlOwner.x = (swpOwner.cx - cx) / 2; + ptlOwner.y = (swpOwner.cy - cy) / 2; +#if OSL_DEBUG_LEVEL>0 + debug_printf( "_WinSetWindowPos SWP_CENTER\n"); +#endif + fl = fl & ~SWP_CENTER; + } else { + // coords are relative to parent frame client area, map to screen + // map Y to OS/2 system coordinates + ptlOwner.x = x; + ptlOwner.y = swpOwner.cy - (y + cy); + +#if OSL_DEBUG_LEVEL>0 + debug_printf( "_WinSetWindowPos owner 0x%x at %d,%d (%dx%d) OS2\n", + hParent, ptlOwner.x, ptlOwner.y, swpOwner.cx, swpOwner.cy); +#endif + } + // map from client area to screen + WinMapWindowPoints( hParent, HWND_DESKTOP, &ptlOwner, 1); + x = ptlOwner.x; + y = ptlOwner.y; + +#if OSL_DEBUG_LEVEL>0 + debug_printf( "_WinSetWindowPos owner 0x%x at %d,%d (%dx%d) MAPPED OS2\n", + hParent, ptlOwner.x, ptlOwner.y, swpOwner.cx, swpOwner.cy); +#endif + } + +#if OSL_DEBUG_LEVEL>0 + debug_printf( "<WinSetWindowPos hwnd %x at %d,%d (%dx%d) fl=%x\n", + pFrame->mhWndFrame, x, y, cx, cy, fl); +#endif + return WinSetWindowPos( pFrame->mhWndFrame, hwndInsertBehind, x, y, 0, 0, fl); +} + +// ======================================================================= + +#if OSL_DEBUG_LEVEL > 0 +static void dumpWindowInfo( char* fnc, HWND hwnd) +{ + SWP aSWP; + HWND hwnd2; + char szTitle[256]; + +#if 0 + _WinQueryWindowPos( hwnd, &aSWP ); + strcpy(szTitle,""); + WinQueryWindowText(hwnd, sizeof(szTitle), szTitle); + debug_printf( "%s: window %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd, + aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle); + hwnd2 = WinQueryWindow(hwnd, QW_PARENT); + _WinQueryWindowPos( hwnd2, &aSWP ); + strcpy(szTitle,""); + WinQueryWindowText(hwnd2, sizeof(szTitle), szTitle); + debug_printf( "%s: parent %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd2, + aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle); + hwnd2 = WinQueryWindow(hwnd, QW_OWNER); + _WinQueryWindowPos( hwnd2, &aSWP ); + strcpy(szTitle,""); + WinQueryWindowText(hwnd2, sizeof(szTitle), szTitle); + debug_printf( "%s: owner %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd2, + aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle); +#endif +} +#endif + +// ======================================================================= + +#ifdef ENABLE_IME + +struct ImplSalIMEProc +{ + ULONG nOrd; + PFN* pProc; +}; + +#define SAL_IME_PROC_COUNT 12 + +// ----------------------------------------------------------------------- + +static SalIMEData* GetSalIMEData() +{ + SalData* pSalData = GetSalData(); + + if ( !pSalData->mbIMEInit ) + { + pSalData->mbIMEInit = TRUE; + + HMODULE hMod = 0; + if ( 0 == DosLoadModule( NULL, 0, "OS2IM", &hMod ) ) + { + SalIMEData* pIMEData = new SalIMEData; + BOOL bError = FALSE; + ImplSalIMEProc aProcAry[SAL_IME_PROC_COUNT] = + { + { 101, (PFN*)&(pIMEData->mpAssocIME) }, + { 104, (PFN*)&(pIMEData->mpGetIME) }, + { 106, (PFN*)&(pIMEData->mpReleaseIME) }, + { 117, (PFN*)&(pIMEData->mpSetConversionFont) }, + { 144, (PFN*)&(pIMEData->mpSetConversionFontSize) }, + { 118, (PFN*)&(pIMEData->mpGetConversionString) }, + { 122, (PFN*)&(pIMEData->mpGetResultString) }, + { 115, (PFN*)&(pIMEData->mpSetCandidateWin) }, + { 130, (PFN*)&(pIMEData->mpQueryIMEProperty) }, + { 131, (PFN*)&(pIMEData->mpRequestIME) }, + { 128, (PFN*)&(pIMEData->mpSetIMEMode) }, + { 127, (PFN*)&(pIMEData->mpQueryIMEMode) } + }; + + pIMEData->mhModIME = hMod; + for ( USHORT i = 0; i < SAL_IME_PROC_COUNT; i++ ) + { + if ( 0 != DosQueryProcAddr( pIMEData->mhModIME, aProcAry[i].nOrd, 0, aProcAry[i].pProc ) ) + { + bError = TRUE; + break; + } + } + + if ( bError ) + { + DosFreeModule( pIMEData->mhModIME ); + delete pIMEData; + } + else + pSalData->mpIMEData = pIMEData; + } + } + + return pSalData->mpIMEData; +} + +// ----------------------------------------------------------------------- + +void ImplReleaseSALIMEData() +{ + SalData* pSalData = GetSalData(); + + if ( pSalData->mpIMEData ) + { + DosFreeModule( pSalData->mpIMEData->mhModIME ); + delete pSalData->mpIMEData; + } +} + +#endif + +// ======================================================================= + +static void ImplSaveFrameState( Os2SalFrame* pFrame ) +{ + // Position, Groesse und Status fuer GetWindowState() merken + if ( !pFrame->mbFullScreen ) + { + SWP aSWP; + BOOL bVisible = WinIsWindowVisible( pFrame->mhWndFrame); + + // Query actual state (maState uses screen coords) + WinQueryWindowPos( pFrame->mhWndFrame, &aSWP ); + + if ( aSWP.fl & SWP_MINIMIZE ) + { +#if OSL_DEBUG_LEVEL>0 + debug_printf("Os2SalFrame::GetWindowState %08x SAL_FRAMESTATE_MINIMIZED\n", + pFrame->mhWndFrame); +#endif + pFrame->maState.mnState |= SAL_FRAMESTATE_MINIMIZED; + if ( bVisible ) + pFrame->mnShowState = SWP_SHOWMAXIMIZED; + } + else if ( aSWP.fl & SWP_MAXIMIZE ) + { +#if OSL_DEBUG_LEVEL>0 + debug_printf("Os2SalFrame::GetWindowState %08x SAL_FRAMESTATE_MAXIMIZED\n", + pFrame->mhWndFrame); +#endif + pFrame->maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED; + pFrame->maState.mnState |= SAL_FRAMESTATE_MAXIMIZED; + if ( bVisible ) + pFrame->mnShowState = SWP_SHOWMINIMIZED; + pFrame->mbRestoreMaximize = TRUE; + } + else + { + LONG nFrameX, nFrameY, nCaptionY; + ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY ); + // to be consistent with Unix, the frame state is without(!) decoration + long nTopDeco = nFrameY + nCaptionY; + long nLeftDeco = nFrameX; + long nBottomDeco = nFrameY; + long nRightDeco = nFrameX; + + pFrame->maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED); + // subtract decoration, store screen coords + pFrame->maState.mnX = aSWP.x+nLeftDeco; + pFrame->maState.mnY = nScreenHeight - (aSWP.y+aSWP.cy)+nTopDeco; + pFrame->maState.mnWidth = aSWP.cx-nLeftDeco-nRightDeco; + pFrame->maState.mnHeight = aSWP.cy-nTopDeco-nBottomDeco; +#if OSL_DEBUG_LEVEL>0 + debug_printf("Os2SalFrame::GetWindowState %08x (%dx%d) at %d,%d VCL\n", + pFrame->mhWndFrame, + pFrame->maState.mnWidth,pFrame->maState.mnHeight,pFrame->maState.mnX,pFrame->maState.mnY); +#endif + if ( bVisible ) + pFrame->mnShowState = SWP_SHOWNORMAL; + pFrame->mbRestoreMaximize = FALSE; + //debug_printf( "ImplSaveFrameState: window %08x at %d,%d (size %dx%d)\n", + // pFrame->mhWndFrame, + // pFrame->maState.mnX, pFrame->maState.mnY, pFrame->maState.mnWidth, pFrame->maState.mnHeight); + } + } +} + +// ----------------------------------------------------------------------- + +long ImplSalCallbackDummy( void*, SalFrame*, USHORT, const void* ) +{ + return 0; +} + +// ----------------------------------------------------------------------- + +static void ImplSalCalcFrameSize( HWND hWnd, + LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY ) +{ + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( !pFrame ) + return; + return ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY ); +} + +static void ImplSalCalcFrameSize( const Os2SalFrame* pFrame, + LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY ) +{ + if ( pFrame->mbSizeBorder ) + { + nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER ); + nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER ); + } + else if ( pFrame->mbFixBorder ) + { + nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXDLGFRAME ); + nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME ); + } + else if ( pFrame->mbBorder ) + { + nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXBORDER ); + nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER ); + } + else + { + nFrameX = 0; + nFrameY = 0; + } + if ( pFrame->mbCaption ) + nCaptionY = WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ); + else + nCaptionY = 0; + +#if OSL_DEBUG_LEVEL>0 + //if (_bCapture) + debug_printf("ImplSalCalcFrameSize 0x%08x x=%d y=%d t=%d\n", pFrame->mhWndFrame, nFrameX, nFrameY, nCaptionY); +#endif +} + +// ----------------------------------------------------------------------- + +static void ImplSalCalcFullScreenSize( const Os2SalFrame* pFrame, + LONG& rX, LONG& rY, LONG& rDX, LONG& rDY ) +{ + // set window to screen size + LONG nFrameX, nFrameY, nCaptionY; + LONG rScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); + LONG rScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); + + // Framegroessen berechnen + ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY ); + + rX = -nFrameX; + rY = -(nFrameY+nCaptionY); + rDX = rScreenDX+(nFrameX*2); + rDY = rScreenDY+(nFrameY*2)+nCaptionY; +} + +// ----------------------------------------------------------------------- + +static void ImplSalFrameFullScreenPos( Os2SalFrame* pFrame, BOOL bAlways = FALSE ) +{ + SWP aSWP; + _WinQueryWindowPos( pFrame, &aSWP ); + if ( bAlways || !(aSWP.fl & SWP_MINIMIZE) ) + { + // set window to screen size + LONG nX; + LONG nY; + LONG nWidth; + LONG nHeight; + ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight ); + _WinSetWindowPos( pFrame, 0, + nX, nY, nWidth, nHeight, + SWP_MOVE | SWP_SIZE ); + } +} + +// ----------------------------------------------------------------------- + +// Uebersetzungstabelle von System-Keycodes in StarView-Keycodes +#define KEY_TAB_SIZE (VK_ENDDRAG+1) + +static USHORT aImplTranslateKeyTab[KEY_TAB_SIZE] = +{ + // StarView-Code System-Code Index + 0, // 0x00 + 0, // VK_BUTTON1 0x01 + 0, // VK_BUTTON2 0x02 + 0, // VK_BUTTON3 0x03 + 0, // VK_BREAK 0x04 + KEY_BACKSPACE, // VK_BACKSPACE 0x05 + KEY_TAB, // VK_TAB 0x06 + KEY_TAB, // VK_BACKTAB 0x07 + KEY_RETURN, // VK_NEWLINE 0x08 + 0, // VK_SHIFT 0x09 + 0, // VK_CTRL 0x0A + 0, // VK_ALT 0x0B + 0, // VK_ALTGRAF 0x0C + 0, // VK_PAUSE 0x0D + 0, // VK_CAPSLOCK 0x0E + KEY_ESCAPE, // VK_ESC 0x0F + KEY_SPACE, // VK_SPACE 0x10 + KEY_PAGEUP, // VK_PAGEUP 0x11 + KEY_PAGEDOWN, // VK_PAGEDOWN 0x12 + KEY_END, // VK_END 0x13 + KEY_HOME, // VK_HOME 0x14 + KEY_LEFT, // VK_LEFT 0x15 + KEY_UP, // VK_UP 0x16 + KEY_RIGHT, // VK_RIGHT 0x17 + KEY_DOWN, // VK_DOWN 0x18 + 0, // VK_PRINTSCRN 0x19 + KEY_INSERT, // VK_INSERT 0x1A + KEY_DELETE, // VK_DELETE 0x1B + 0, // VK_SCRLLOCK 0x1C + 0, // VK_NUMLOCK 0x1D + KEY_RETURN, // VK_ENTER 0x1E + 0, // VK_SYSRQ 0x1F + KEY_F1, // VK_F1 0x20 + KEY_F2, // VK_F2 0x21 + KEY_F3, // VK_F3 0x22 + KEY_F4, // VK_F4 0x23 + KEY_F5, // VK_F5 0x24 + KEY_F6, // VK_F6 0x25 + KEY_F7, // VK_F7 0x26 + KEY_F8, // VK_F8 0x27 + KEY_F9, // VK_F9 0x28 + KEY_F10, // VK_F10 0x29 + KEY_F11, // VK_F11 0x2A + KEY_F12, // VK_F12 0x2B + KEY_F13, // VK_F13 0x2C + KEY_F14, // VK_F14 0x2D + KEY_F15, // VK_F15 0x2E + KEY_F16, // VK_F16 0x2F + KEY_F17, // VK_F17 0x30 + KEY_F18, // VK_F18 0x31 + KEY_F19, // VK_F19 0x32 + KEY_F20, // VK_F20 0x33 + KEY_F21, // VK_F21 0x34 + KEY_F22, // VK_F22 0x35 + KEY_F23, // VK_F23 0x36 + KEY_F24, // VK_F24 0x37 + 0 // VK_ENDDRAG 0x38 +}; + +// ======================================================================= + +SalFrame* ImplSalCreateFrame( Os2SalInstance* pInst, HWND hWndParent, ULONG nSalFrameStyle ) +{ + SalData* pSalData = GetSalData(); + Os2SalFrame* pFrame = new Os2SalFrame; + HWND hWndFrame; + HWND hWndClient; + ULONG nFrameFlags = FCF_NOBYTEALIGN | FCF_SCREENALIGN; + ULONG nFrameStyle = 0; + ULONG nClientStyle = WS_CLIPSIBLINGS; + BOOL bSubFrame = FALSE; + +#if OSL_DEBUG_LEVEL>0 + debug_printf(">ImplSalCreateFrame hWndParent 0x%x, nSalFrameStyle 0x%x\n", hWndParent, nSalFrameStyle); +#endif + + if ( hWndParent ) + { + bSubFrame = TRUE; + pFrame->mbNoIcon = TRUE; + } + + // determine creation data (bei Moveable nehmen wir DLG-Border, damit + // es besser aussieht) + if ( nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE ) + nFrameFlags |= FCF_CLOSEBUTTON; + + if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE ) { + pFrame->mbCaption = TRUE; + nFrameStyle = WS_ANIMATE; + nFrameFlags |= FCF_SYSMENU | FCF_TITLEBAR | FCF_DLGBORDER; + if ( !hWndParent ) + nFrameFlags |= FCF_MINBUTTON; + + if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE ) + { + pFrame->mbSizeBorder = TRUE; + nFrameFlags |= FCF_SIZEBORDER; + if ( !hWndParent ) + nFrameFlags |= FCF_MAXBUTTON; + } + else + pFrame->mbFixBorder = TRUE; + + // add task list style if not a tool window + if ( !(nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) { + nFrameFlags |= FCF_TASKLIST; + } + } + + if( nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW ) + { + pFrame->mbNoIcon = TRUE; + // YD gives small caption -> nExSysStyle |= WS_EX_TOOLWINDOW; + } + + if ( nSalFrameStyle & SAL_FRAME_STYLE_FLOAT ) + { + //nExSysStyle |= WS_EX_TOOLWINDOW; + pFrame->mbFloatWin = TRUE; + } + //if( nSalFrameStyle & SAL_FRAME_STYLE_TOOLTIP ) + // nExSysStyle |= WS_EX_TOPMOST; + + // init frame data + pFrame->mnStyle = nSalFrameStyle; + + // determine show style + pFrame->mnShowState = SWP_SHOWNORMAL; + + // create frame + //YD FIXME this is a potential bug with multiple threads and cuncurrent + //window creation, because this field is accessed in + //WM_CREATE to get window data, + pSalData->mpCreateFrame = pFrame; + + //YD FIXME if SAL_FRAME_CHILD is specified, use hWndParent as parent handle... + hWndFrame = WinCreateStdWindow( HWND_DESKTOP, nFrameStyle, &nFrameFlags, + (PSZ)(bSubFrame ? SAL_SUBFRAME_CLASSNAME : SAL_FRAME_CLASSNAME), + NULL, + nClientStyle, 0, 0, &hWndClient ); + debug_printf("ImplSalCreateFrame hWndParent 0x%x, hWndFrame 0x%x, hWndClient 0x%x\n", hWndParent, hWndFrame, hWndClient); + if ( !hWndFrame ) + { + delete pFrame; + return NULL; + } + + // Parent setzen (Owner) + if ( hWndParent != 0 && hWndParent != HWND_DESKTOP ) + WinSetOwner( hWndFrame, hWndParent ); + + Os2SalFrame* pParentFrame = GetWindowPtr( hWndParent ); + if ( pParentFrame ) + pFrame->mpParentFrame = pParentFrame; + + // Icon setzen (YD win32 does it in the class registration) + if ( nFrameFlags & FCF_MINBUTTON ) + WinSendMsg( hWndFrame, WM_SETICON, (MPARAM)pInst->mhAppIcon, (MPARAM)0 ); + + // If we have an Window with an Caption Bar and without + // an MaximizeBox, we change the SystemMenu + if ( (nFrameFlags & (FCF_TITLEBAR | FCF_MAXBUTTON)) == (FCF_TITLEBAR) ) + { + HWND hSysMenu = WinWindowFromID( hWndFrame, FID_SYSMENU ); + if ( hSysMenu ) + { + if ( !(nFrameFlags & (FCF_MINBUTTON | FCF_MAXBUTTON)) ) + WinEnableMenuItem(hSysMenu, SC_RESTORE, FALSE); + if ( !(nFrameFlags & FCF_MINBUTTON) ) + WinEnableMenuItem(hSysMenu, SC_MINIMIZE, FALSE); + if ( !(nFrameFlags & FCF_MAXBUTTON) ) + WinEnableMenuItem(hSysMenu, SC_MAXIMIZE, FALSE); + if ( !(nFrameFlags & FCF_SIZEBORDER) ) + WinEnableMenuItem(hSysMenu, SC_SIZE, FALSE); + } + } + if ( (nFrameFlags & FCF_SYSMENU) && !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) ) + { + HWND hSysMenu = WinWindowFromID( hWndFrame, FID_SYSMENU ); + if ( hSysMenu ) + { + WinEnableMenuItem(hSysMenu, SC_CLOSE, FALSE); + } + } + + // ticket#124 subclass frame window: we need to intercept TRACK message + aSalShlData.mpFrameProc = WinSubclassWindow( hWndFrame, SalFrameSubClassWndProc); + + // init OS/2 frame data + pFrame->mhAB = pInst->mhAB; + + // YD 18/08 under OS/2, invisible frames have size 0,0 at 0,0, so + // we need to set an initial size/position manually + SWP aSWP; + memset( &aSWP, 0, sizeof( aSWP ) ); + WinQueryTaskSizePos( pInst->mhAB, 0, &aSWP ); + WinSetWindowPos( hWndFrame, NULL, aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, + SWP_MOVE | SWP_SIZE); + +#ifdef ENABLE_IME + // Input-Context einstellen + SalIMEData* pIMEData = GetSalIMEData(); + if ( pIMEData ) + { + pFrame->mhIMEContext = 0; + if ( 0 != pIMEData->mpAssocIME( hWndClient, pFrame->mhIMEContext, &pFrame->mhDefIMEContext ) ) + pFrame->mhDefIMEContext = 0; + } + else + { + pFrame->mhIMEContext = 0; + pFrame->mhDefIMEContext = 0; + } +#endif + + RECTL rectl; + _WinQueryWindowRect( hWndClient, &rectl ); + pFrame->mnWidth = rectl.xRight; + pFrame->mnHeight = rectl.yBottom; + debug_printf( "ImplSalCreateFrame %dx%d\n", pFrame->mnWidth, pFrame->mnHeight); + ImplSaveFrameState( pFrame ); + pFrame->mbDefPos = TRUE; + + UpdateFrameGeometry( hWndFrame, pFrame ); + + if( pFrame->mnShowState == SWP_SHOWMAXIMIZED ) + { + // #96084 set a useful internal window size because + // the window will not be maximized (and the size updated) before show() + SetMaximizedFrameGeometry( hWndFrame, pFrame ); + } + +#if OSL_DEBUG_LEVEL > 1 + dumpWindowInfo( "<ImplSalCreateFrame (exit)", hWndFrame); +#endif + + return pFrame; +} + +// ======================================================================= + +Os2SalFrame::Os2SalFrame() +{ + SalData* pSalData = GetSalData(); + + mbGraphics = NULL; + mhPointer = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE ); + mpGraphics = NULL; + mpInst = NULL; + mbFullScreen = FALSE; + mbAllwayOnTop = FALSE; + mbVisible = FALSE; + mbMinHide = FALSE; + mbInShow = FALSE; + mbRestoreMaximize = FALSE; + mbInMoveMsg = FALSE; + mbInSizeMsg = FALSE; + mbDefPos = TRUE; + mbOverwriteState = TRUE; + mbHandleIME = FALSE; + mbConversionMode = FALSE; + mbCandidateMode = FALSE; + mbCaption = FALSE; + //mhDefIMEContext = 0; + mpGraphics = NULL; + mnShowState = SWP_SHOWNORMAL; + mnWidth = 0; + mnHeight = 0; + mnMinWidth = 0; + mnMinHeight = 0; + mnMaxWidth = SHRT_MAX; + mnMaxHeight = SHRT_MAX; + mnInputLang = 0; + mnKeyboardHandle = 0; + mbGraphics = FALSE; + mbCaption = FALSE; + mbBorder = FALSE; + mbFixBorder = FALSE; + mbSizeBorder = FALSE; + mbFullScreen = FALSE; + //mbPresentation = FALSE; + mbInShow = FALSE; + mbRestoreMaximize = FALSE; + mbInMoveMsg = FALSE; + mbInSizeMsg = FALSE; + //mbFullScreenToolWin = FALSE; + mbDefPos = TRUE; + mbOverwriteState = TRUE; + //mbIME = FALSE; + mbHandleIME = FALSE; + //mbSpezIME = FALSE; + //mbAtCursorIME = FALSE; + mbCandidateMode = FALSE; + mbFloatWin = FALSE; + mbNoIcon = FALSE; + //mSelectedhMenu = 0; + //mLastActivatedhMenu = 0; + mpParentFrame = NULL; + + memset( &maState, 0, sizeof( SalFrameState ) ); + maSysData.nSize = sizeof( SystemEnvData ); + memset( &maGeometry, 0, sizeof( maGeometry ) ); + + // insert frame in framelist + mpNextFrame = pSalData->mpFirstFrame; + pSalData->mpFirstFrame = this; +} + +// ----------------------------------------------------------------------- + +Os2SalFrame::~Os2SalFrame() +{ + SalData* pSalData = GetSalData(); + + // destroy DC + if ( mpGraphics ) + { + ImplSalDeInitGraphics( mpGraphics ); + WinReleasePS( mpGraphics->mhPS ); + delete mpGraphics; + } + + // destroy system frame + WinDestroyWindow( mhWndFrame ); + + // remove frame from framelist + if ( this == pSalData->mpFirstFrame ) + pSalData->mpFirstFrame = mpNextFrame; + else + { + Os2SalFrame* pTempFrame = pSalData->mpFirstFrame; + while ( pTempFrame->mpNextFrame != this ) + pTempFrame = pTempFrame->mpNextFrame; + + pTempFrame->mpNextFrame = mpNextFrame; + } +} + +// ----------------------------------------------------------------------- + +static HDC ImplWinGetDC( HWND hWnd ) +{ + HDC hDC = WinQueryWindowDC( hWnd ); + if ( !hDC ) + hDC = WinOpenWindowDC( hWnd ); + return hDC; +} + +// ----------------------------------------------------------------------- + +SalGraphics* Os2SalFrame::GetGraphics() +{ + if ( mbGraphics ) + return NULL; + + if ( !mpGraphics ) + { + SalData* pSalData = GetSalData(); + mpGraphics = new Os2SalGraphics; + mpGraphics->mhPS = WinGetPS( mhWndClient ); + mpGraphics->mhDC = ImplWinGetDC( mhWndClient ); + mpGraphics->mhWnd = mhWndClient; + mpGraphics->mnHeight = mnHeight; + mpGraphics->mbPrinter = FALSE; + mpGraphics->mbVirDev = FALSE; + mpGraphics->mbWindow = TRUE; + mpGraphics->mbScreen = TRUE; + ImplSalInitGraphics( mpGraphics ); + mbGraphics = TRUE; + } + else + mbGraphics = TRUE; + + return mpGraphics; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::ReleaseGraphics( SalGraphics* ) +{ + mbGraphics = FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Os2SalFrame::PostEvent( void* pData ) +{ + return (BOOL)WinPostMsg( mhWndClient, SAL_MSG_USEREVENT, 0, (MPARAM)pData ); +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetTitle( const XubString& rTitle ) +{ + // set window title + ByteString title( rTitle, gsl_getSystemTextEncoding() ); + debug_printf("Os2SalFrame::SetTitle %x '%s'\n", mhWndFrame, title.GetBuffer() ); + WinSetWindowText( mhWndFrame, title.GetBuffer() ); +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetIcon( USHORT nIcon ) +{ + debug_printf("Os2SalFrame::SetIcon\n"); + + // If we have a window without an Icon (for example a dialog), ignore this call + if ( mbNoIcon ) + return; + + // 0 means default (class) icon + HPOINTER hIcon = NULL; + if ( !nIcon ) + nIcon = 1; + + ImplLoadSalIcon( nIcon, hIcon ); + + DBG_ASSERT( hIcon , "Os2SalFrame::SetIcon(): Could not load icon !" ); + + // Icon setzen + WinSendMsg( mhWndFrame, WM_SETICON, (MPARAM)hIcon, (MPARAM)0 ); +} + +// ----------------------------------------------------------------------- + +SalFrame* Os2SalFrame::GetParent() const +{ + //debug_printf("Os2SalFrame::GetParent\n"); + return GetWindowPtr( WinQueryWindow(mhWndFrame, QW_OWNER) ); +} + +// ----------------------------------------------------------------------- + +static void ImplSalShow( HWND hWnd, ULONG bVisible, ULONG bNoActivate ) +{ + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( !pFrame ) + return; + + if ( bVisible ) + { + pFrame->mbDefPos = FALSE; + pFrame->mbOverwriteState = TRUE; + pFrame->mbInShow = TRUE; + +#if OSL_DEBUG_LEVEL > 0 + debug_printf( "ImplSalShow hwnd %x visible flag %d, no activate: flag %d\n", hWnd, bVisible, bNoActivate); +#endif + + if( bNoActivate ) + WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_SHOW); + else + WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, pFrame->mnShowState); + + pFrame->mbInShow = FALSE; + + // Direct Paint only, if we get the SolarMutx + if ( ImplSalYieldMutexTryToAcquire() ) + { + WinUpdateWindow( hWnd ); + ImplSalYieldMutexRelease(); + } + } + else + { +#if OSL_DEBUG_LEVEL > 0 + debug_printf( "ImplSalShow hwnd %x HIDE\n"); +#endif + WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_HIDE); + } +} + + +// ----------------------------------------------------------------------- + + +void Os2SalFrame::SetExtendedFrameStyle( SalExtStyle nExtStyle ) +{ +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::Show( BOOL bVisible, BOOL bNoActivate ) +{ + // Post this Message to the window, because this only works + // in the thread of the window, which has create this window. + // We post this message to avoid deadlocks + if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() ) + WinPostMsg( mhWndFrame, SAL_MSG_SHOW, (MPARAM)bVisible, (MPARAM)bNoActivate ); + else + ImplSalShow( mhWndFrame, bVisible, bNoActivate ); +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::Enable( BOOL bEnable ) +{ + WinEnableWindow( mhWndFrame, bEnable ); +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetMinClientSize( long nWidth, long nHeight ) +{ + debug_printf("Os2SalFrame::SetMinClientSize\n"); + mnMinWidth = nWidth; + mnMinHeight = nHeight; +} + +void Os2SalFrame::SetMaxClientSize( long nWidth, long nHeight ) +{ + debug_printf("Os2SalFrame::SetMaxClientSize\n"); + mnMaxWidth = nWidth; + mnMaxHeight = nHeight; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, + USHORT nFlags ) +{ + // calculation frame size + USHORT nEvent = 0; + ULONG nPosFlags = 0; + +#if OSL_DEBUG_LEVEL > 0 + //dumpWindowInfo( "-Os2SalFrame::SetPosSize", mhWndFrame); + debug_printf( ">Os2SalFrame::SetPosSize go to %d,%d (%dx%d) VCL\n",nX,nY,nWidth,nHeight); +#endif + + SWP aSWP; + _WinQueryWindowPos( this, &aSWP ); + BOOL bVisible = WinIsWindowVisible( mhWndFrame ); + if ( !bVisible ) + { + if ( mbFloatWin ) + mnShowState = SWP_SHOW; + else + mnShowState = SWP_SHOWNORMAL; + } + else + { + if ( (aSWP.fl & SWP_MINIMIZE) || (aSWP.fl & SWP_MAXIMIZE) ) + WinSetWindowPos(mhWndFrame, NULL, 0, 0, 0, 0, SWP_RESTORE ); + } + + if ( (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)) ) { + nPosFlags |= SWP_MOVE; +#if OSL_DEBUG_LEVEL > 0 + debug_printf( "-Os2SalFrame::SetPosSize MOVE to %d,%d\n", nX, nY); +#endif + //DBG_ASSERT( nX && nY, " Windowposition of (0,0) requested!" ); + nEvent = SALEVENT_MOVE; + } + + if ( (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) ) { + nPosFlags |= SWP_SIZE; +#if OSL_DEBUG_LEVEL > 0 + debug_printf( "-Os2SalFrame::SetPosSize SIZE to %d,%d\n", nWidth,nHeight); +#endif + nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE; + } + + // Default-Position, dann zentrieren, ansonsten Position beibehalten + if ( mbDefPos && !(nPosFlags & SWP_MOVE)) + { + // calculate bottom left corner of frame + mbDefPos = FALSE; + nPosFlags |= SWP_MOVE | SWP_CENTER; + nEvent = SALEVENT_MOVERESIZE; +#if OSL_DEBUG_LEVEL > 10 + debug_printf( "-Os2SalFrame::SetPosSize CENTER\n"); + debug_printf( "-Os2SalFrame::SetPosSize default position to %d,%d\n", nX, nY); +#endif + } + + // Adjust Window in the screen + BOOL bCheckOffScreen = TRUE; + + // but don't do this for floaters or ownerdraw windows that are currently moved interactively + if( (mnStyle & SAL_FRAME_STYLE_FLOAT) && !(mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) + bCheckOffScreen = FALSE; + + if( mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) + { + // may be the window is currently being moved (mouse is captured), then no check is required + if( mhWndClient == WinQueryCapture( HWND_DESKTOP) ) + bCheckOffScreen = FALSE; + else + bCheckOffScreen = TRUE; + } + + if( bCheckOffScreen ) + { + if ( nX+nWidth > nScreenWidth ) + nX = nScreenWidth - nWidth; + if ( nY+nHeight > nScreenHeight ) + nY = nScreenHeight - nHeight; + if ( nX < 0 ) + nX = 0; + if ( nY < 0 ) + nY = 0; + } + + // bring floating windows always to top + // do not change zorder, otherwise tooltips will bring main window to top (ticket:14) + //if( (mnStyle & SAL_FRAME_STYLE_FLOAT) ) + // nPosFlags |= SWP_ZORDER; // do not change z-order + + // set new position + _WinSetWindowPos( this, HWND_TOP, nX, nY, nWidth, nHeight, nPosFlags); // | SWP_RESTORE + + UpdateFrameGeometry( mhWndFrame, this ); + + // Notification -- really ??? + if( nEvent ) + CallCallback( nEvent, NULL ); + +#if OSL_DEBUG_LEVEL > 0 + dumpWindowInfo( "<Os2SalFrame::SetPosSize (exit)", mhWndFrame); +#endif + +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetParent( SalFrame* pNewParent ) +{ + APIRET rc; +#if OSL_DEBUG_LEVEL>0 + debug_printf("Os2SalFrame::SetParent mhWndFrame 0x%08x to 0x%08x\n", + static_cast<Os2SalFrame*>(this)->mhWndFrame, + static_cast<Os2SalFrame*>(pNewParent)->mhWndClient); +#endif + Os2SalFrame::mbInReparent = TRUE; + //rc = WinSetParent(static_cast<Os2SalFrame*>(this)->mhWndFrame, + // static_cast<Os2SalFrame*>(pNewParent)->mhWndClient, TRUE); + rc = WinSetOwner(static_cast<Os2SalFrame*>(this)->mhWndFrame, + static_cast<Os2SalFrame*>(pNewParent)->mhWndClient); + mpParentFrame = static_cast<Os2SalFrame*>(pNewParent); + Os2SalFrame::mbInReparent = FALSE; +} + +bool Os2SalFrame::SetPluginParent( SystemParentData* pNewParent ) +{ + APIRET rc; + if ( pNewParent->hWnd == 0 ) + { + pNewParent->hWnd = HWND_DESKTOP; + } + + Os2SalFrame::mbInReparent = TRUE; + rc = WinSetOwner(static_cast<Os2SalFrame*>(this)->mhWndFrame, + pNewParent->hWnd); + Os2SalFrame::mbInReparent = FALSE; + return true; +} + + +// ----------------------------------------------------------------------- + +void Os2SalFrame::GetWorkArea( RECTL &rRect ) +{ + rRect.xLeft = rRect.yTop = 0; + rRect.xRight = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN )-1; + rRect.yBottom = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN )-1; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::GetWorkArea( Rectangle &rRect ) +{ + RECTL aRect; + GetWorkArea( aRect); + rRect.nLeft = aRect.xLeft; + rRect.nRight = aRect.xRight; // win -1; + rRect.nTop = aRect.yTop; + rRect.nBottom = aRect.yBottom; // win -1; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::GetClientSize( long& rWidth, long& rHeight ) +{ + rWidth = maGeometry.nWidth; + rHeight = maGeometry.nHeight; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetWindowState( const SalFrameState* pState ) +{ + LONG nX; + LONG nY; + LONG nWidth; + LONG nHeight; + ULONG nPosSize = 0; + +#if OSL_DEBUG_LEVEL>0 + debug_printf("Os2SalFrame::SetWindowState\n"); + debug_printf("Os2SalFrame::SetWindowState %08x (%dx%d) at %d,%d VCL\n", + mhWndFrame, + pState->mnWidth,pState->mnHeight,pState->mnX,pState->mnY); +#endif + + BOOL bVisible = WinIsWindowVisible( mhWndFrame ); + + // get screen coordinates + SWP aSWP; + WinQueryWindowPos( mhWndFrame, &aSWP ); + LONG nFrameX, nFrameY, nCaptionY; + ImplSalCalcFrameSize( this, nFrameX, nFrameY, nCaptionY ); + + long nTopDeco = nFrameY + nCaptionY; + long nLeftDeco = nFrameX; + long nBottomDeco = nFrameY; + long nRightDeco = nFrameX; + + // Fenster-Position/Groesse in den Bildschirm einpassen + if ((pState->mnMask & (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y)) ) + nPosSize |= SWP_MOVE; + if ((pState->mnMask & (SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)) ) + nPosSize |= SWP_SIZE; + + if ( pState->mnMask & SAL_FRAMESTATE_MASK_X ) + nX = (int)pState->mnX - nLeftDeco; + else + nX = aSWP.x; + + // keep Y inverted since height is still unknown, will invert later + if ( pState->mnMask & SAL_FRAMESTATE_MASK_Y ) + nY = (int)pState->mnY - nTopDeco; + else + nY = nScreenHeight - (aSWP.y+aSWP.cy); + + if ( pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH ) + nWidth = (int)pState->mnWidth + nLeftDeco + nRightDeco; + else + nWidth = aSWP.cx; + if ( pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT ) + nHeight = (int)pState->mnHeight + nTopDeco + nBottomDeco; + else + nHeight = aSWP.cy; + +#if OSL_DEBUG_LEVEL>0 + debug_printf("Os2SalFrame::SetWindowState (%dx%d) at %d,%d\n", nWidth,nHeight,nX,nY); +#endif + + // Adjust Window in the screen: + // if it does not fit into the screen do nothing, ie default pos/size will be used + // if there is an overlap with the screen border move the window while keeping its size + + //if( nWidth > nScreenWidth || nHeight > nScreenHeight ) + // nPosSize |= (SWP_NOMOVE | SWP_NOSIZE); + + if ( nX+nWidth > nScreenWidth ) + nX = (nScreenWidth) - nWidth; + if ( nY+nHeight > nScreenHeight ) + nY = (nScreenHeight) - nHeight; + if ( nX < 0 ) + nX = 0; + if ( nY < 0 ) + nY = 0; + + // Restore-Position setzen + SWP aPlacement; + WinQueryWindowPos( mhWndFrame, &aPlacement ); + + // Status setzen + bVisible = WinIsWindowVisible( mhWndFrame); + BOOL bUpdateHiddenFramePos = FALSE; + if ( !bVisible ) + { + aPlacement.fl = SWP_HIDE; + + if ( mbOverwriteState ) + { + if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE ) + { + if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED ) + mnShowState = SWP_SHOWMINIMIZED; + else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) + { + mnShowState = SWP_SHOWMAXIMIZED; + bUpdateHiddenFramePos = TRUE; + } + else if ( pState->mnState & SAL_FRAMESTATE_NORMAL ) + mnShowState = SWP_SHOWNORMAL; + } + } + } + else + { + if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE ) + { + if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED ) + { + //if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) + // aPlacement.flags |= WPF_RESTORETOMAXIMIZED; + aPlacement.fl = SWP_SHOWMINIMIZED; + } + else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) + aPlacement.fl = SWP_SHOWMAXIMIZED; + else if ( pState->mnState & SAL_FRAMESTATE_NORMAL ) + aPlacement.fl = SWP_RESTORE; + } + } + + // Wenn Fenster nicht minimiert/maximiert ist oder nicht optisch + // umgesetzt werden muss, dann SetWindowPos() benutzen, da + // SetWindowPlacement() die TaskBar mit einrechnet + if ( !(aPlacement.fl & SWP_MINIMIZE) + && !( aPlacement.fl & SWP_MAXIMIZE ) + && (!bVisible || (aPlacement.fl == SWP_RESTORE)) ) + { + if( bUpdateHiddenFramePos ) + { + // #96084 set a useful internal window size because + // the window will not be maximized (and the size updated) before show() + SetMaximizedFrameGeometry( mhWndFrame, this ); + } + else + WinSetWindowPos( mhWndFrame, 0, nX, + nScreenHeight - (nY+nHeight), nWidth, nHeight, nPosSize); + } + else + { + if( (nPosSize & (SWP_MOVE|SWP_SIZE)) ) + { + aPlacement.x = nX; + aPlacement.y = nScreenHeight-(nY+nHeight); + aPlacement.cx = nWidth; + aPlacement.cy = nHeight; + } + WinSetWindowPos( mhWndFrame, 0, aPlacement.x, aPlacement.y, + aPlacement.cx, aPlacement.cy, aPlacement.fl ); + } + +#if OSL_DEBUG_LEVEL>0 + debug_printf("Os2SalFrame::SetWindowState DONE\n"); +#endif +} + +// ----------------------------------------------------------------------- + +BOOL Os2SalFrame::GetWindowState( SalFrameState* pState ) +{ + if ( maState.mnWidth && maState.mnHeight ) + { + *pState = maState; + // #94144# allow Minimize again, should be masked out when read from configuration + // 91625 - Don't save minimize + //if ( !(pState->mnState & SAL_FRAMESTATE_MAXIMIZED) ) + if ( !(pState->mnState & (SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED)) ) + pState->mnState |= SAL_FRAMESTATE_NORMAL; + return TRUE; + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetScreenNumber( unsigned int nNewScreen ) +{ +#if 0 + WinSalSystem* pSys = static_cast<WinSalSystem*>(ImplGetSalSystem()); + if( pSys ) + { + const std::vector<WinSalSystem::DisplayMonitor>& rMonitors = + pSys->getMonitors(); + size_t nMon = rMonitors.size(); + if( nNewScreen < nMon ) + { + Point aOldMonPos, aNewMonPos( rMonitors[nNewScreen].m_aArea.TopLeft() ); + Point aCurPos( maGeometry.nX, maGeometry.nY ); + for( size_t i = 0; i < nMon; i++ ) + { + if( rMonitors[i].m_aArea.IsInside( aCurPos ) ) + { + aOldMonPos = rMonitors[i].m_aArea.TopLeft(); + break; + } + } + mnDisplay = nNewScreen; + maGeometry.nScreenNumber = nNewScreen; + SetPosSize( aNewMonPos.X() + (maGeometry.nX - aOldMonPos.X()), + aNewMonPos.Y() + (maGeometry.nY - aOldMonPos.Y()), + 0, 0, + SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); + } + } +#endif +} + +// ----------------------------------------------------------------------- + +// native menu implementation - currently empty +void Os2SalFrame::DrawMenuBar() +{ +} + +void Os2SalFrame::SetMenu( SalMenu* pSalMenu ) +{ +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nDisplay ) +{ + if ( mbFullScreen == bFullScreen ) + return; + + mbFullScreen = bFullScreen; + if ( bFullScreen ) + { + // save old position + memset( &maFullScreenRect, 0, sizeof( SWP ) ); + _WinQueryWindowPos( this, &maFullScreenRect ); + + // set window to screen size + ImplSalFrameFullScreenPos( this, TRUE ); + } + else + { + _WinSetWindowPos( this, + 0, + maFullScreenRect.x, maFullScreenRect.y, + maFullScreenRect.cx, maFullScreenRect.cy, + SWP_MOVE | SWP_SIZE ); + } +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::StartPresentation( BOOL bStart ) +{ + // SysSetObjectData("<WP_DESKTOP>","Autolockup=no"); oder OS2.INI: PM_Lockup +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetAlwaysOnTop( BOOL bOnTop ) +{ + mbAllwayOnTop = bOnTop; +#if 0 + HWND hWnd; + if ( bOnTop ) + hWnd = HWND_TOPMOST; + else + hWnd = HWND_NOTOPMOST; + SetWindowPos( mhWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ); +#endif +} + + +// ----------------------------------------------------------------------- + +static void ImplSalToTop( HWND hWnd, ULONG nFlags ) +{ + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); +#if OSL_DEBUG_LEVEL>0 + debug_printf("ImplSalToTop hWnd %08x, nFlags %x\n", hWnd, nFlags); +#endif + + // if window is minimized, first restore it + SWP aSWP; + WinQueryWindowPos( hWnd, &aSWP ); + if ( aSWP.fl & SWP_MINIMIZE ) + WinSetWindowPos( hWnd, NULL, 0, 0, 0, 0, SWP_RESTORE ); + + if ( nFlags & SAL_FRAME_TOTOP_FOREGROUNDTASK ) + WinSetWindowPos( pFrame->mhWndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER); + + if ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN ) + { + ULONG nStyle; + if ( pFrame->mbRestoreMaximize ) + nStyle = SWP_MAXIMIZE; + else + nStyle = SWP_RESTORE; + + WinSetWindowPos( pFrame->mhWndFrame, NULL, 0, 0, 0, 0, nStyle ); + } + WinSetFocus( HWND_DESKTOP, pFrame->mhWndClient ); +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::ToTop( USHORT nFlags ) +{ + nFlags &= ~SAL_FRAME_TOTOP_GRABFOCUS; // this flag is not needed on win32 + // Post this Message to the window, because this only works + // in the thread of the window, which has create this window. + // We post this message to avoid deadlocks + if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() ) + WinPostMsg( mhWndFrame, SAL_MSG_TOTOP, (MPARAM)nFlags, 0 ); + else + ImplSalToTop( mhWndFrame, nFlags ); +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetPointer( PointerStyle ePointerStyle ) +{ + struct ImplPtrData + { + HPOINTER mhPointer; + ULONG mnSysId; + ULONG mnOwnId; + }; + + static ImplPtrData aImplPtrTab[POINTER_COUNT] = + { + { 0, SPTR_ARROW, 0 }, // POINTER_ARROW + { 0, 0, SAL_RESID_POINTER_NULL }, // POINTER_NULL + { 0, SPTR_WAIT, 0 }, // POINTER_WAIT + { 0, SPTR_TEXT, 0 }, // POINTER_BEAM + { 0, 0, SAL_RESID_POINTER_HELP }, // POINTER_HELP + { 0, 0, SAL_RESID_POINTER_CROSS }, // POINTER_CROSS + { 0, 0, SAL_RESID_POINTER_MOVE }, // POINTER_MOVE + { 0, SPTR_SIZENS, 0 }, // POINTER_NSIZE + { 0, SPTR_SIZENS, 0 }, // POINTER_SSIZE + { 0, SPTR_SIZEWE, 0 }, // POINTER_WSIZE + { 0, SPTR_SIZEWE, 0 }, // POINTER_ESIZE + { 0, SPTR_SIZENWSE, 0 }, // POINTER_NWSIZE + { 0, SPTR_SIZENESW, 0 }, // POINTER_NESIZE + { 0, SPTR_SIZENESW, 0 }, // POINTER_SWSIZE + { 0, SPTR_SIZENWSE, 0 }, // POINTER_SESIZE + { 0, SPTR_SIZENS, 0 }, // POINTER_WINDOW_NSIZE + { 0, SPTR_SIZENS, 0 }, // POINTER_WINDOW_SSIZE + { 0, SPTR_SIZEWE, 0 }, // POINTER_WINDOW_WSIZE + { 0, SPTR_SIZEWE, 0 }, // POINTER_WINDOW_ESIZE + { 0, SPTR_SIZENWSE, 0 }, // POINTER_WINDOW_NWSIZE + { 0, SPTR_SIZENESW, 0 }, // POINTER_WINDOW_NESIZE + { 0, SPTR_SIZENESW, 0 }, // POINTER_WINDOW_SWSIZE + { 0, SPTR_SIZENWSE, 0 }, // POINTER_WINDOW_SESIZE + { 0, 0, SAL_RESID_POINTER_HSPLIT }, // POINTER_HSPLIT + { 0, 0, SAL_RESID_POINTER_VSPLIT }, // POINTER_VSPLIT + { 0, 0, SAL_RESID_POINTER_HSIZEBAR }, // POINTER_HSIZEBAR + { 0, 0, SAL_RESID_POINTER_VSIZEBAR }, // POINTER_VSIZEBAR + { 0, 0, SAL_RESID_POINTER_HAND }, // POINTER_HAND + { 0, 0, SAL_RESID_POINTER_REFHAND }, // POINTER_REFHAND + { 0, 0, SAL_RESID_POINTER_PEN }, // POINTER_PEN + { 0, 0, SAL_RESID_POINTER_MAGNIFY }, // POINTER_MAGNIFY + { 0, 0, SAL_RESID_POINTER_FILL }, // POINTER_FILL + { 0, 0, SAL_RESID_POINTER_ROTATE }, // POINTER_ROTATE + { 0, 0, SAL_RESID_POINTER_HSHEAR }, // POINTER_HSHEAR + { 0, 0, SAL_RESID_POINTER_VSHEAR }, // POINTER_VSHEAR + { 0, 0, SAL_RESID_POINTER_MIRROR }, // POINTER_MIRROR + { 0, 0, SAL_RESID_POINTER_CROOK }, // POINTER_CROOK + { 0, 0, SAL_RESID_POINTER_CROP }, // POINTER_CROP + { 0, 0, SAL_RESID_POINTER_MOVEPOINT }, // POINTER_MOVEPOINT + { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT }, // POINTER_MOVEBEZIERWEIGHT + { 0, 0, SAL_RESID_POINTER_MOVEDATA }, // POINTER_MOVEDATA + { 0, 0, SAL_RESID_POINTER_COPYDATA }, // POINTER_COPYDATA + { 0, 0, SAL_RESID_POINTER_LINKDATA }, // POINTER_LINKDATA + { 0, 0, SAL_RESID_POINTER_MOVEDATALINK }, // POINTER_MOVEDATALINK + { 0, 0, SAL_RESID_POINTER_COPYDATALINK }, // POINTER_COPYDATALINK + { 0, 0, SAL_RESID_POINTER_MOVEFILE }, // POINTER_MOVEFILE + { 0, 0, SAL_RESID_POINTER_COPYFILE }, // POINTER_COPYFILE + { 0, 0, SAL_RESID_POINTER_LINKFILE }, // POINTER_LINKFILE + { 0, 0, SAL_RESID_POINTER_MOVEFILELINK }, // POINTER_MOVEFILELINK + { 0, 0, SAL_RESID_POINTER_COPYFILELINK }, // POINTER_COPYFILELINK + { 0, 0, SAL_RESID_POINTER_MOVEFILES }, // POINTER_MOVEFILES + { 0, 0, SAL_RESID_POINTER_COPYFILES }, // POINTER_COPYFILES + { 0, SPTR_ILLEGAL, 0 }, // POINTER_NOTALLOWED + { 0, 0, SAL_RESID_POINTER_DRAW_LINE }, // POINTER_DRAW_LINE + { 0, 0, SAL_RESID_POINTER_DRAW_RECT }, // POINTER_DRAW_RECT + { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON }, // POINTER_DRAW_POLYGON + { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER }, // POINTER_DRAW_BEZIER + { 0, 0, SAL_RESID_POINTER_DRAW_ARC }, // POINTER_DRAW_ARC + { 0, 0, SAL_RESID_POINTER_DRAW_PIE }, // POINTER_DRAW_PIE + { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT }, // POINTER_DRAW_CIRCLECUT + { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE }, // POINTER_DRAW_ELLIPSE + { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND }, // POINTER_DRAW_FREEHAND + { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT }, // POINTER_DRAW_CONNECT + { 0, 0, SAL_RESID_POINTER_DRAW_TEXT }, // POINTER_DRAW_TEXT + { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION }, // POINTER_DRAW_CAPTION + { 0, 0, SAL_RESID_POINTER_CHART }, // POINTER_CHART + { 0, 0, SAL_RESID_POINTER_DETECTIVE }, // POINTER_DETECTIVE + { 0, 0, SAL_RESID_POINTER_PIVOT_COL }, // POINTER_PIVOT_COL + { 0, 0, SAL_RESID_POINTER_PIVOT_ROW }, // POINTER_PIVOT_ROW + { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD }, // POINTER_PIVOT_FIELD + { 0, 0, SAL_RESID_POINTER_CHAIN }, // POINTER_CHAIN + { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED }, // POINTER_CHAIN_NOTALLOWED + { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE }, // POINTER_TIMEEVENT_MOVE + { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE }, // POINTER_TIMEEVENT_SIZE + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N }, // POINTER_AUTOSCROLL_N + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S }, // POINTER_AUTOSCROLL_S + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W }, // POINTER_AUTOSCROLL_W + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E }, // POINTER_AUTOSCROLL_E + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW }, // POINTER_AUTOSCROLL_NW + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE }, // POINTER_AUTOSCROLL_NE + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW }, // POINTER_AUTOSCROLL_SW + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE }, // POINTER_AUTOSCROLL_SE + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS }, // POINTER_AUTOSCROLL_NS + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE }, // POINTER_AUTOSCROLL_WE + { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE }, // POINTER_AUTOSCROLL_NSWE + { 0, 0, SAL_RESID_POINTER_AIRBRUSH }, // POINTER_AIRBRUSH + { 0, 0, SAL_RESID_POINTER_TEXT_VERTICAL }, // POINTER_TEXT_VERTICAL + { 0, 0, SAL_RESID_POINTER_PIVOT_DELETE }, // POINTER_PIVOT_DELETE + + // --> FME 2004-07-30 #i32329# Enhanced table selection + { 0, 0, SAL_RESID_POINTER_TAB_SELECT_S }, // POINTER_TAB_SELECT_S + { 0, 0, SAL_RESID_POINTER_TAB_SELECT_E }, // POINTER_TAB_SELECT_E + { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SE }, // POINTER_TAB_SELECT_SE + { 0, 0, SAL_RESID_POINTER_TAB_SELECT_W }, // POINTER_TAB_SELECT_W + { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SW }, // POINTER_TAB_SELECT_SW + // <-- + + // --> FME 2004-08-16 #i20119# Paintbrush tool + { 0, 0, SAL_RESID_POINTER_PAINTBRUSH } // POINTER_PAINTBRUSH + // <-- + }; + +#if POINTER_COUNT != 94 +#error New Pointer must be defined! +#endif + + //debug_printf("Os2SalFrame::SetPointer\n"); + + // Mousepointer loaded ? + if ( !aImplPtrTab[ePointerStyle].mhPointer ) + { + if ( aImplPtrTab[ePointerStyle].mnOwnId ) + aImplPtrTab[ePointerStyle].mhPointer = ImplLoadSalCursor( (ULONG)aImplPtrTab[ePointerStyle].mnOwnId ); + else + aImplPtrTab[ePointerStyle].mhPointer = WinQuerySysPointer( HWND_DESKTOP, aImplPtrTab[ePointerStyle].mnSysId, FALSE ); + } + if (aImplPtrTab[ePointerStyle].mhPointer == 0) { + debug_printf( "SetPointer ePointerStyle %d unknown\n", ePointerStyle); + aImplPtrTab[ePointerStyle].mhPointer = SPTR_ICONERROR; + } + + // Unterscheidet sich der Mauspointer, dann den neuen setzen + if ( mhPointer != aImplPtrTab[ePointerStyle].mhPointer ) + { + mhPointer = aImplPtrTab[ePointerStyle].mhPointer; + WinSetPointer( HWND_DESKTOP, mhPointer ); + } +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::CaptureMouse( BOOL bCapture ) +{ +#if OSL_DEBUG_LEVEL>10 + _bCapture=bCapture; + debug_printf("Os2SalFrame::CaptureMouse bCapture %d\n", bCapture); +#endif + if ( bCapture ) + WinSetCapture( HWND_DESKTOP, mhWndClient ); + else + WinSetCapture( HWND_DESKTOP, 0 ); +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetPointerPos( long nX, long nY ) +{ + POINTL aPt; + aPt.x = nX; + aPt.y = mnHeight - nY - 1; // convert sal coords to sys + WinMapWindowPoints( mhWndClient, HWND_DESKTOP, &aPt, 1 ); + WinSetPointerPos( HWND_DESKTOP, aPt.x, aPt.y ); +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::Flush() +{ +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::Sync() +{ +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetInputContext( SalInputContext* pContext ) +{ +#ifdef ENABLE_IME + SalIMEData* pIMEData = GetSalIMEData(); + if ( pIMEData ) + { + HWND hWnd = mhWndClient; + HIMI hIMI = 0; + pIMEData->mpGetIME( hWnd, &hIMI ); + if ( hIMI ) + { + ULONG nInputMode; + ULONG nConversionMode; + if ( 0 == pIMEData->mpQueryIMEMode( hIMI, &nInputMode, &nConversionMode ) ) + { + if ( pContext->mnOptions & SAL_INPUTCONTEXT_TEXT ) + { + nInputMode &= ~IMI_IM_IME_DISABLE; + if ( pContext->mnOptions & SAL_INPUTCONTEXT_EXTTEXTINPUT_OFF ) + nInputMode &= ~IMI_IM_IME_ON; +// !!! Da derzeit ueber das OS2-IME-UI der IME-Mode nicht einschaltbar ist !!! +// if ( SAL_INPUTCONTEXT_EXTTEXTINPUT_ON ) + nInputMode |= IMI_IM_IME_ON; + } + else + nInputMode |= IMI_IM_IME_DISABLE; + pIMEData->mpSetIMEMode( hIMI, nInputMode, nConversionMode ); + } + + pIMEData->mpReleaseIME( hWnd, hIMI ); + } + } +#endif +} + +// ----------------------------------------------------------------------- +#if 0 +void Os2SalFrame::UpdateExtTextInputArea() +{ +#ifdef ENABLE_IME +#endif +} +#endif + +// ----------------------------------------------------------------------- + +void Os2SalFrame::EndExtTextInput( USHORT nFlags ) +{ +#ifdef ENABLE_IME + SalIMEData* pIMEData = GetSalIMEData(); + if ( pIMEData ) + { + HWND hWnd = mhWndClient; + HIMI hIMI = 0; + pIMEData->mpGetIME( hWnd, &hIMI ); + if ( hIMI ) + { + ULONG nIndex; + if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE ) + nIndex = CNV_COMPLETE; + else + nIndex = CNV_CANCEL; + + pIMEData->mpRequestIME( hIMI, REQ_CONVERSIONSTRING, nIndex, 0 ); + pIMEData->mpReleaseIME( hWnd, hIMI ); + } + } +#endif +} + +// ----------------------------------------------------------------------- + +XubString Os2SalFrame::GetKeyName( USHORT nCode ) +{ + if ( eImplKeyboardLanguage == LANGUAGE_DONTKNOW ) + eImplKeyboardLanguage = MsLangId::getSystemLanguage(); + + XubString aKeyCode; + XubString aCode; + const sal_Unicode** pLangTab = ImplGetLangTab( eImplKeyboardLanguage ); + + if ( nCode & KEY_SHIFT ) + aKeyCode = pLangTab[LSTR_KEY_SHIFT]; + + if ( nCode & KEY_MOD1 ) + { + if ( aKeyCode.Len() == 0 ) + aKeyCode = pLangTab[LSTR_KEY_CTRL]; + else + { + aKeyCode += '+'; + aKeyCode += pLangTab[LSTR_KEY_CTRL]; + } + } + + if ( nCode & KEY_MOD2 ) + { + if ( aKeyCode.Len() == 0 ) + aKeyCode = pLangTab[LSTR_KEY_ALT]; + else + { + aKeyCode += '+'; + aKeyCode += pLangTab[LSTR_KEY_ALT]; + } + } + + USHORT nKeyCode = nCode & 0x0FFF; + if ( (nKeyCode >= KEY_0) && (nKeyCode <= KEY_9) ) + aCode = sal::static_int_cast<sal_Char>('0' + (nKeyCode - KEY_0)); + else if ( (nKeyCode >= KEY_A) && (nKeyCode <= KEY_Z) ) + aCode = sal::static_int_cast<sal_Char>('A' + (nKeyCode - KEY_A)); + else if ( (nKeyCode >= KEY_F1) && (nKeyCode <= KEY_F26) ) + { + aCode += 'F'; + if ( (nKeyCode >= KEY_F1) && (nKeyCode <= KEY_F9) ) + { + aCode += sal::static_int_cast<sal_Char>('1' + (nKeyCode - KEY_F1)); + } + else if ( (nKeyCode >= KEY_F10) && (nKeyCode <= KEY_F19) ) + { + aCode += '1'; + aCode += sal::static_int_cast<sal_Char>('0' + (nKeyCode - KEY_F10)); + } + else + { + aCode += '2'; + aCode += sal::static_int_cast<sal_Char>('0' + (nKeyCode - KEY_F20)); + } + } + else + { + switch ( nKeyCode ) + { + case KEY_DOWN: + aCode = pLangTab[LSTR_KEY_DOWN]; + break; + case KEY_UP: + aCode = pLangTab[LSTR_KEY_UP]; + break; + case KEY_LEFT: + aCode = pLangTab[LSTR_KEY_LEFT]; + break; + case KEY_RIGHT: + aCode = pLangTab[LSTR_KEY_RIGHT]; + break; + case KEY_HOME: + aCode = pLangTab[LSTR_KEY_HOME]; + break; + case KEY_END: + aCode = pLangTab[LSTR_KEY_END]; + break; + case KEY_PAGEUP: + aCode = pLangTab[LSTR_KEY_PAGEUP]; + break; + case KEY_PAGEDOWN: + aCode = pLangTab[LSTR_KEY_PAGEDOWN]; + break; + case KEY_RETURN: + aCode = pLangTab[LSTR_KEY_RETURN]; + break; + case KEY_ESCAPE: + aCode = pLangTab[LSTR_KEY_ESC]; + break; + case KEY_TAB: + aCode = pLangTab[LSTR_KEY_TAB]; + break; + case KEY_BACKSPACE: + aCode = pLangTab[LSTR_KEY_BACKSPACE]; + break; + case KEY_SPACE: + aCode = pLangTab[LSTR_KEY_SPACE]; + break; + case KEY_INSERT: + aCode = pLangTab[LSTR_KEY_INSERT]; + break; + case KEY_DELETE: + aCode = pLangTab[LSTR_KEY_DELETE]; + break; + + case KEY_ADD: + aCode += '+'; + break; + case KEY_SUBTRACT: + aCode += '-'; + break; + case KEY_MULTIPLY: + aCode += '*'; + break; + case KEY_DIVIDE: + aCode += '/'; + break; + case KEY_POINT: + aCode += '.'; + break; + case KEY_COMMA: + aCode += ','; + break; + case KEY_LESS: + aCode += '<'; + break; + case KEY_GREATER: + aCode += '>'; + break; + case KEY_EQUAL: + aCode += '='; + break; + } + } + + if ( aCode.Len() ) + { + if ( aKeyCode.Len() == 0 ) + aKeyCode = aCode; + else + { + aKeyCode += '+'; + aKeyCode += aCode; + } + } + + return aKeyCode; +} + +// ----------------------------------------------------------------------- + +XubString Os2SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode ) +{ + return GetKeyName( nKeyCode ); +} + +// ----------------------------------------------------------------------- + +inline long ImplOS2ColorToSal( long nOS2Color ) +{ + return MAKE_SALCOLOR( (BYTE)( nOS2Color>>16), (BYTE)(nOS2Color>>8), (BYTE)nOS2Color ); +} + +// ----------------------------------------------------------------------- + +static USHORT ImplMouseSysValueToSAL( int iSysValue, USHORT& rCode, USHORT& rClicks, BOOL& rDown ) +{ + LONG lValue = WinQuerySysValue( HWND_DESKTOP, iSysValue ); + + rCode = 0; + rClicks = 1; + rDown = TRUE; + + switch ( lValue & 0xFFFF ) + { + case WM_BUTTON1UP: + case WM_BUTTON1CLICK: + rCode = MOUSE_LEFT; + rDown = FALSE; + break; + case WM_BUTTON1DOWN: + case WM_BUTTON1MOTIONSTART: + rCode = MOUSE_LEFT; + break; + case WM_BUTTON1DBLCLK: + rCode = MOUSE_LEFT; + rClicks = 2; + break; + + case WM_BUTTON2UP: + case WM_BUTTON2CLICK: + rCode = MOUSE_RIGHT; + rDown = FALSE; + break; + case WM_BUTTON2DOWN: + case WM_BUTTON2MOTIONSTART: + rCode = MOUSE_RIGHT; + break; + case WM_BUTTON2DBLCLK: + rCode = MOUSE_RIGHT; + rClicks = 2; + break; + + case WM_BUTTON3UP: + case WM_BUTTON3CLICK: + rCode = MOUSE_MIDDLE; + rDown = FALSE; + break; + case WM_BUTTON3DOWN: + case WM_BUTTON3MOTIONSTART: + rCode = MOUSE_MIDDLE; + break; + case WM_BUTTON3DBLCLK: + rCode = MOUSE_MIDDLE; + rClicks = 2; + break; + } + + if ( !rCode ) + return FALSE; + + lValue = (lValue & 0xFFFF0000) >> 16; + if ( lValue != 0xFFFF ) + { + if ( lValue & KC_SHIFT ) + rCode |= KEY_SHIFT; + if ( lValue & KC_CTRL ) + rCode |= KEY_MOD1; + if ( lValue & KC_ALT ) + rCode |= KEY_MOD2; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- + +static BOOL ImplSalIsSameColor( const Color& rColor1, const Color& rColor2 ) +{ + ULONG nWrong = 0; + nWrong += Abs( (short)rColor1.GetRed()-(short)rColor2.GetRed() ); + nWrong += Abs( (short)rColor1.GetGreen()-(short)rColor2.GetGreen() ); + nWrong += Abs( (short)rColor1.GetBlue()-(short)rColor2.GetBlue() ); + return (nWrong < 30); +} + +// ----------------------------------------------------------------------- + +static BOOL ImplOS2NameFontToVCLFont( const char* pFontName, Font& rFont ) +{ + char aNumBuf[10]; + int nNumBufLen = 0; + + while ( *pFontName && (*pFontName != '.') && + (nNumBufLen < sizeof(aNumBuf)-1) ) + { + aNumBuf[nNumBufLen] = *pFontName; + nNumBufLen++; + pFontName++; + } + aNumBuf[nNumBufLen] = '\0'; + + pFontName++; + while ( *pFontName == ' ' ) + pFontName++; + + int nFontHeight = atoi( aNumBuf ); + int nFontNameLen = strlen( pFontName ); + if ( nFontHeight && nFontNameLen ) + { + rFont.SetFamily( FAMILY_DONTKNOW ); + rFont.SetWeight( WEIGHT_NORMAL ); + rFont.SetItalic( ITALIC_NONE ); + // search for a style embedded in the name, e.g. 'WarpSans Bold' + // because we need to split the style from the family name + if (strstr( pFontName, " Bold") + || strstr( pFontName, " Italic") + || strstr( pFontName, "-Normal")) + { + char* fontName = strdup( pFontName); + char* style = strstr( fontName, " Bold"); + if (style) + rFont.SetWeight( WEIGHT_BOLD ); + + if (!style) + style = strstr( fontName, " Italic"); + if (style) + rFont.SetItalic( ITALIC_NORMAL ); + + if (!style) + style = strstr( fontName, "-Normal"); + // store style, skip whitespace char + rFont.SetStyleName( ::rtl::OStringToOUString ( style+1, gsl_getSystemTextEncoding()) ); + // truncate name + *style = 0; + // store family name + rFont.SetName( ::rtl::OStringToOUString ( fontName, gsl_getSystemTextEncoding()) ); + free( fontName); + } + else + { + rFont.SetName( ::rtl::OStringToOUString (pFontName, gsl_getSystemTextEncoding()) ); + rFont.SetStyleName( ::rtl::OStringToOUString ("", gsl_getSystemTextEncoding()) ); + } + + rFont.SetSize( Size( 0, nFontHeight ) ); + return TRUE; + } + else + return FALSE; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::UpdateSettings( AllSettings& rSettings ) +{ + static char aControlPanel[] = "PM_ControlPanel"; + static char aSystemFonts[] = "PM_SystemFonts"; + char aDummyStr[] = ""; + + // --- Mouse setting --- + USHORT nCode; + USHORT nClicks; + BOOL bDown; + MouseSettings aMouseSettings = rSettings.GetMouseSettings(); + aMouseSettings.SetDoubleClickTime( WinQuerySysValue( HWND_DESKTOP, SV_DBLCLKTIME ) ); + if ( ImplMouseSysValueToSAL( SV_BEGINDRAG, nCode, nClicks, bDown ) ) + aMouseSettings.SetStartDragCode( nCode ); + if ( ImplMouseSysValueToSAL( SV_CONTEXTMENU, nCode, nClicks, bDown ) ) + { + aMouseSettings.SetContextMenuCode( nCode ); + aMouseSettings.SetContextMenuClicks( nClicks ); + aMouseSettings.SetContextMenuDown( bDown ); + } + aMouseSettings.SetButtonStartRepeat( WinQuerySysValue( HWND_DESKTOP, SV_FIRSTSCROLLRATE ) ); + aMouseSettings.SetButtonRepeat( WinQuerySysValue( HWND_DESKTOP, SV_SCROLLRATE ) ); + rSettings.SetMouseSettings( aMouseSettings ); + + // --- Style settings --- + StyleSettings aStyleSettings = rSettings.GetStyleSettings(); + BOOL bCompBorder = (aStyleSettings.GetOptions() & (STYLE_OPTION_MACSTYLE | STYLE_OPTION_UNIXSTYLE)) == 0; + + // General settings + LONG nDisplayTime = PrfQueryProfileInt( HINI_PROFILE, (PSZ)aControlPanel, (PSZ)"LogoDisplayTime", -1 ); + ULONG nSalDisplayTime; + if ( nDisplayTime < 0 ) + nSalDisplayTime = LOGO_DISPLAYTIME_STARTTIME; + else if ( !nDisplayTime ) + nSalDisplayTime = LOGO_DISPLAYTIME_NOLOGO; + else + nSalDisplayTime = (ULONG)nDisplayTime; + aStyleSettings.SetLogoDisplayTime( nSalDisplayTime ); + + aStyleSettings.SetCursorBlinkTime( WinQuerySysValue( HWND_DESKTOP, SV_CURSORRATE ) ); + ULONG nDragFullOptions = aStyleSettings.GetDragFullOptions(); + if ( WinQuerySysValue( HWND_DESKTOP, SV_DYNAMICDRAG ) ) + nDragFullOptions |= DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT; + else + nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT); + aStyleSettings.SetDragFullOptions( nDragFullOptions ); + + // Size settings + aStyleSettings.SetScrollBarSize( WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL ) ); + if ( bCompBorder ) + { + aStyleSettings.SetTitleHeight( WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) ); + } + + // Color settings + if ( bCompBorder ) + { + aStyleSettings.SetFaceColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) ); + aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() ); + aStyleSettings.SetLightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONLIGHT, 0 ) ) ); + aStyleSettings.SetLightBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) ); + aStyleSettings.SetShadowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONDARK, 0 ) ) ); + aStyleSettings.SetDarkShadowColor( Color( COL_BLACK ) ); + aStyleSettings.SetDialogColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0 ) ) ); + aStyleSettings.SetButtonTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); + aStyleSettings.SetActiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLE, 0 ) ) ); + aStyleSettings.SetActiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLETEXT, 0 ) ) ); + aStyleSettings.SetActiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVEBORDER, 0 ) ) ); + aStyleSettings.SetDeactiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLE, 0 ) ) ); + aStyleSettings.SetDeactiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLETEXT, 0 ) ) ); + aStyleSettings.SetDeactiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVEBORDER, 0 ) ) ); + aStyleSettings.SetMenuColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENU, 0 ) ) ); + aStyleSettings.SetMenuTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); + aStyleSettings.SetMenuBarTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); + } + aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() ); + aStyleSettings.SetRadioCheckTextColor( aStyleSettings.GetButtonTextColor() ); + aStyleSettings.SetGroupTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWSTATICTEXT, 0 ) ) ); + aStyleSettings.SetLabelTextColor( aStyleSettings.GetGroupTextColor() ); + aStyleSettings.SetInfoTextColor( aStyleSettings.GetGroupTextColor() ); + aStyleSettings.SetWindowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOW, 0 ) ) ); + aStyleSettings.SetActiveTabColor( aStyleSettings.GetWindowColor() ); + aStyleSettings.SetWindowTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWTEXT, 0 ) ) ); + aStyleSettings.SetFieldColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ENTRYFIELD, 0 ) ) ); + aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() ); + aStyleSettings.SetDisableColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUDISABLEDTEXT, 0 ) ) ); + aStyleSettings.SetHighlightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_HILITEBACKGROUND, 0 ) ) ); + aStyleSettings.SetHighlightTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_HILITEFOREGROUND, 0 ) ) ); + Color aMenuHighColor = ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITEBGND, 0 ) ); + if ( ImplSalIsSameColor( aMenuHighColor, aStyleSettings.GetMenuColor() ) ) + { + if ( bCompBorder ) + { + aStyleSettings.SetMenuHighlightColor( Color( COL_BLUE ) ); + aStyleSettings.SetMenuHighlightTextColor( Color( COL_WHITE ) ); + } + } + else + { + aStyleSettings.SetMenuHighlightColor( aMenuHighColor ); + aStyleSettings.SetMenuHighlightTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITE, 0 ) ) ); + } + // Checked-Color berechnen + Color aColor1 = aStyleSettings.GetFaceColor(); + Color aColor2 = aStyleSettings.GetLightColor(); + BYTE nRed = (BYTE)(((USHORT)aColor1.GetRed() + (USHORT)aColor2.GetRed())/2); + BYTE nGreen = (BYTE)(((USHORT)aColor1.GetGreen() + (USHORT)aColor2.GetGreen())/2); + BYTE nBlue = (BYTE)(((USHORT)aColor1.GetBlue() + (USHORT)aColor2.GetBlue())/2); + aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) ); + + // Fonts updaten + Font aFont; + char aFontNameBuf[255]; + aFont = aStyleSettings.GetMenuFont(); + if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"Menus", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 ) + { + if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) { +#if 0 + // Add Workplace Sans if not already listed + if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND ) + { + XubString aFontName = aFont.GetName(); + aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 ); + aFont.SetName( aFontName ); + aFont.SetSize( Size( 0, 9 ) ); + } +#endif + aStyleSettings.SetMenuFont( aFont ); + } + } + aFont = aStyleSettings.GetIconFont(); + if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"IconText", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 ) + { + if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) + aStyleSettings.SetIconFont( aFont ); + } + aFont = aStyleSettings.GetTitleFont(); + if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"WindowTitles", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 ) + { + if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) + { + // Add Workplace Sans if not already listed + if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND ) + { + XubString aFontName = aFont.GetName(); + aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 ); + aFont.SetName( aFontName ); + aFont.SetSize( Size( 0, 9 ) ); + aFont.SetWeight( WEIGHT_BOLD ); + aFont.SetItalic( ITALIC_NONE ); + } + aStyleSettings.SetTitleFont( aFont ); + aStyleSettings.SetFloatTitleFont( aFont ); + } + } + aFont = aStyleSettings.GetAppFont(); + if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"WindowText", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 ) + { + if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) + { + Font aHelpFont = aFont; + aHelpFont.SetName( (sal_Unicode*)L"Helv;WarpSans" ); + aHelpFont.SetSize( Size( 0, 8 ) ); + aHelpFont.SetWeight( WEIGHT_NORMAL ); + aHelpFont.SetItalic( ITALIC_NONE ); + aStyleSettings.SetHelpFont( aHelpFont ); + + // Add Workplace Sans if not already listed + if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND ) + { + XubString aFontName = aFont.GetName(); + aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 ); + aFont.SetName( aFontName ); + aFont.SetSize( Size( 0, 9 ) ); + } + aStyleSettings.SetAppFont( aFont ); + aStyleSettings.SetToolFont( aFont ); + aStyleSettings.SetLabelFont( aFont ); + aStyleSettings.SetInfoFont( aFont ); + aStyleSettings.SetRadioCheckFont( aFont ); + aStyleSettings.SetPushButtonFont( aFont ); + aStyleSettings.SetFieldFont( aFont ); + aStyleSettings.SetGroupFont( aFont ); + } + } + + rSettings.SetStyleSettings( aStyleSettings ); +} + +// ----------------------------------------------------------------------- + +SalBitmap* Os2SalFrame::SnapShot() +{ +debug_printf("Os2SalFrame::SnapShot\n"); +return NULL; +} + +// ----------------------------------------------------------------------- + +const SystemEnvData* Os2SalFrame::GetSystemData() const +{ + return &maSysData; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::Beep( SoundType eSoundType ) +{ + static ULONG aImplSoundTab[5] = + { + WA_NOTE, // SOUND_DEFAULT + WA_NOTE, // SOUND_INFO + WA_WARNING, // SOUND_WARNING + WA_ERROR, // SOUND_ERROR + WA_NOTE // SOUND_QUERY + }; + +#if 0 +#if SOUND_COUNT != 5 +#error New Sound must be defined! +#endif +#endif + + debug_printf("Os2SalFrame::Beep %d\n", eSoundType); + WinAlarm( HWND_DESKTOP, aImplSoundTab[eSoundType] ); +} + +// ----------------------------------------------------------------------- + +SalFrame::SalPointerState Os2SalFrame::GetPointerState() +{ + SalPointerState aState; + aState.mnState = 0; + + // MausModus feststellen und setzen + if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000 ) + aState.mnState |= MOUSE_LEFT; + if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 ) + aState.mnState |= MOUSE_RIGHT; + if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 ) + aState.mnState |= MOUSE_MIDDLE; + // Modifier-Tasten setzen + if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 ) + aState.mnState |= KEY_SHIFT; + if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) + aState.mnState |= KEY_MOD1; + if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 ) + aState.mnState |= KEY_MOD2; + + POINTL pt; + _WinQueryPointerPos( HWND_DESKTOP, &pt ); + + aState.maPos = Point( pt.x - maGeometry.nX, pt.y - maGeometry.nY ); + return aState; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::SetBackgroundBitmap( SalBitmap* ) +{ +} + +// ----------------------------------------------------------------------- + +void SalTestMouseLeave() +{ + SalData* pSalData = GetSalData(); + + if ( pSalData->mhWantLeaveMsg && !::WinQueryCapture( HWND_DESKTOP ) ) + { + POINTL aPt; + WinQueryPointerPos( HWND_DESKTOP, &aPt ); + if ( pSalData->mhWantLeaveMsg != WinWindowFromPoint( HWND_DESKTOP, &aPt, TRUE ) ) + WinSendMsg( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MPFROM2SHORT( aPt.x, aPt.y ) ); + } +} + +// ----------------------------------------------------------------------- + +static long ImplHandleMouseMsg( HWND hWnd, + UINT nMsg, MPARAM nMP1, MPARAM nMP2 ) +{ + SalMouseEvent aMouseEvt; + long nRet; + USHORT nEvent; + BOOL bCall = TRUE; + USHORT nFlags = SHORT2FROMMP( nMP2 ); + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( !pFrame ) + return 0; + + aMouseEvt.mnX = (short)SHORT1FROMMP( nMP1 ); + aMouseEvt.mnY = pFrame->mnHeight - (short)SHORT2FROMMP( nMP1 ) - 1; + aMouseEvt.mnCode = 0; + aMouseEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); + + // MausModus feststellen und setzen + if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000 ) + aMouseEvt.mnCode |= MOUSE_LEFT; + if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 ) + aMouseEvt.mnCode |= MOUSE_RIGHT; + if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 ) + aMouseEvt.mnCode |= MOUSE_MIDDLE; + // Modifier-Tasten setzen + if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 ) + aMouseEvt.mnCode |= KEY_SHIFT; + if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) + aMouseEvt.mnCode |= KEY_MOD1; + if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 ) + aMouseEvt.mnCode |= KEY_MOD2; + + switch ( nMsg ) + { + case WM_MOUSEMOVE: + { + SalData* pSalData = GetSalData(); + + // Da bei Druecken von Modifier-Tasten die MouseEvents + // nicht zusammengefast werden (da diese durch KeyEvents + // unterbrochen werden), machen wir dieses hier selber + if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) ) + { + QMSG aTempMsg; + if ( WinPeekMsg( pSalData->mhAB, &aTempMsg, + pFrame->mhWndClient, + WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE ) ) + { + if ( (aTempMsg.msg == WM_MOUSEMOVE) && + (aTempMsg.mp2 == nMP2) ) + return 1; + } + } + + // Test for MouseLeave + if ( pSalData->mhWantLeaveMsg && + (pSalData->mhWantLeaveMsg != pFrame->mhWndClient) ) + { + POINTL aMousePoint; + WinQueryMsgPos( pFrame->mhAB, &aMousePoint ); + WinSendMsg( pSalData->mhWantLeaveMsg, + SAL_MSG_MOUSELEAVE, + 0, MPFROM2SHORT( aMousePoint.x, aMousePoint.y ) ); + } + pSalData->mhWantLeaveMsg = pFrame->mhWndClient; + // Start MouseLeave-Timer + if ( !pSalData->mpMouseLeaveTimer ) + { + pSalData->mpMouseLeaveTimer = new AutoTimer; + pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT ); + pSalData->mpMouseLeaveTimer->Start(); + // We dont need to set a timeout handler, because we test + // for mouseleave in the timeout callback + } + aMouseEvt.mnButton = 0; + nEvent = SALEVENT_MOUSEMOVE; + } + break; + + case SAL_MSG_MOUSELEAVE: + { + SalData* pSalData = GetSalData(); + if ( pSalData->mhWantLeaveMsg == pFrame->mhWndClient ) + { + pSalData->mhWantLeaveMsg = 0; + if ( pSalData->mpMouseLeaveTimer ) + { + delete pSalData->mpMouseLeaveTimer; + pSalData->mpMouseLeaveTimer = NULL; + } + + // Mouse-Coordinaates are relativ to the screen + POINTL aPt; + aPt.x = (short)SHORT1FROMMP( nMP2 ); + aPt.y = (short)SHORT2FROMMP( nMP2 ); + WinMapWindowPoints( HWND_DESKTOP, pFrame->mhWndClient, &aPt, 1 ); + aPt.y = pFrame->mnHeight - aPt.y - 1; + aMouseEvt.mnX = aPt.x; + aMouseEvt.mnY = aPt.y; + aMouseEvt.mnButton = 0; + nEvent = SALEVENT_MOUSELEAVE; + } + else + bCall = FALSE; + } + break; + + case WM_BUTTON1DBLCLK: + case WM_BUTTON1DOWN: + aMouseEvt.mnButton = MOUSE_LEFT; + nEvent = SALEVENT_MOUSEBUTTONDOWN; + break; + + case WM_BUTTON2DBLCLK: + case WM_BUTTON2DOWN: + aMouseEvt.mnButton = MOUSE_RIGHT; + nEvent = SALEVENT_MOUSEBUTTONDOWN; + break; + + case WM_BUTTON3DBLCLK: + case WM_BUTTON3DOWN: + aMouseEvt.mnButton = MOUSE_MIDDLE; + nEvent = SALEVENT_MOUSEBUTTONDOWN; + break; + + case WM_BUTTON1UP: + aMouseEvt.mnButton = MOUSE_LEFT; + nEvent = SALEVENT_MOUSEBUTTONUP; + break; + + case WM_BUTTON2UP: + aMouseEvt.mnButton = MOUSE_RIGHT; + nEvent = SALEVENT_MOUSEBUTTONUP; + break; + + case WM_BUTTON3UP: + aMouseEvt.mnButton = MOUSE_MIDDLE; + nEvent = SALEVENT_MOUSEBUTTONUP; + break; + } + + // check if this window was destroyed - this might happen if we are the help window + // and sent a mouse leave message to the application which killed the help window, ie ourself + if( !WinIsWindow( pFrame->mhAB, hWnd ) ) + return 0; + +#if OSL_DEBUG_LEVEL>10 + //if (_bCapture) + debug_printf("ImplHandleMouseMsg mouse %d,%d\n",aMouseEvt.mnX,aMouseEvt.mnY); +#endif + + if ( bCall ) + { + if ( nEvent == SALEVENT_MOUSEBUTTONDOWN ) + WinUpdateWindow( pFrame->mhWndClient ); + + // --- RTL --- (mirror mouse pos) + //if( Application::GetSettings().GetLayoutRTL() ) + // aMouseEvt.mnX = pFrame->maGeometry.nWidth-1-aMouseEvt.mnX; + + nRet = pFrame->CallCallback( nEvent, &aMouseEvt ); + if ( nMsg == WM_MOUSEMOVE ) + { + WinSetPointer( HWND_DESKTOP, pFrame->mhPointer ); + nRet = TRUE; + } + } + else + nRet = 0; + + return nRet; +} + +// ----------------------------------------------------------------------- + +static long ImplHandleWheelMsg( HWND hWnd, UINT nMsg, MPARAM nMP1, MPARAM nMP2 ) +{ + + ImplSalYieldMutexAcquireWithWait(); + + long nRet = 0; + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( pFrame ) + { + + // Mouse-Coordinaates are relativ to the screen + POINTL aPt; + WinQueryMsgPos( pFrame->mhAB, &aPt ); + WinMapWindowPoints( HWND_DESKTOP, pFrame->mhWndClient, &aPt, 1 ); + aPt.y = pFrame->mnHeight - aPt.y - 1; + + SalWheelMouseEvent aWheelEvt; + aWheelEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); + aWheelEvt.mnX = aPt.x; + aWheelEvt.mnY = aPt.y; + aWheelEvt.mnCode = 0; + bool bNeg = (SHORT2FROMMP(nMP2) == SB_LINEDOWN || SHORT2FROMMP(nMP2) == SB_PAGEDOWN ); + aWheelEvt.mnDelta = bNeg ? -120 : 120; + aWheelEvt.mnNotchDelta = bNeg ? -1 : 1; + if (SHORT2FROMMP(nMP2) == SB_PAGEUP || SHORT2FROMMP(nMP2) == SB_PAGEDOWN) + aWheelEvt.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; + else + aWheelEvt.mnScrollLines = 1; + + if( nMsg == WM_HSCROLL ) + aWheelEvt.mbHorz = TRUE; + + // Modifier-Tasten setzen + if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 ) + aWheelEvt.mnCode |= KEY_SHIFT; + if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) + aWheelEvt.mnCode |= KEY_MOD1; + if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 ) + aWheelEvt.mnCode |= KEY_MOD2; + + nRet = pFrame->CallCallback( SALEVENT_WHEELMOUSE, &aWheelEvt ); + } + + ImplSalYieldMutexRelease(); + + return nRet; +} + + +// ----------------------------------------------------------------------- + +static USHORT ImplSalGetKeyCode( Os2SalFrame* pFrame, MPARAM aMP1, MPARAM aMP2 ) +{ + USHORT nKeyFlags = SHORT1FROMMP( aMP1 ); + UCHAR nCharCode = (UCHAR)SHORT1FROMMP( aMP2 ); + USHORT nKeyCode = (UCHAR)SHORT2FROMMP( aMP2 ); + UCHAR nScanCode = (UCHAR)CHAR4FROMMP( aMP1 ); + USHORT rSVCode = 0; + + // Ist virtueller KeyCode gesetzt und befindet sich der KeyCode in der + // Tabelle, dann mappen + if ( (nKeyFlags & KC_VIRTUALKEY) && (nKeyCode < KEY_TAB_SIZE) ) + rSVCode = aImplTranslateKeyTab[nKeyCode]; + + // Wenn kein KeyCode ermittelt werden konnte, versuchen wir aus dem + // CharCode einen zu erzeugen + if ( !rSVCode && nCharCode ) + { + // Bei 0-9, a-z und A-Z auch KeyCode setzen + if ( (nCharCode >= '0') && (nCharCode <= '9') && (!rSVCode || !(nKeyFlags & KC_SHIFT)) ) + rSVCode = KEYGROUP_NUM + (nCharCode-'0'); + else if ( (nCharCode >= 'a') && (nCharCode <= 'z') ) + rSVCode = KEYGROUP_ALPHA + (nCharCode-'a'); + else if ( (nCharCode >= 'A') && (nCharCode <= 'Z') ) + rSVCode = KEYGROUP_ALPHA + (nCharCode-'A'); + else + { + switch ( nCharCode ) + { + case '+': + rSVCode = KEY_ADD; + break; + case '-': + rSVCode = KEY_SUBTRACT; + break; + case '*': + rSVCode = KEY_MULTIPLY; + break; + case '/': + rSVCode = KEY_DIVIDE; + break; + case '.': + rSVCode = KEY_POINT; + break; + case ',': + rSVCode = KEY_COMMA; + break; + case '<': + rSVCode = KEY_LESS; + break; + case '>': + rSVCode = KEY_GREATER; + break; + case '=': + rSVCode = KEY_EQUAL; + break; + } + } + } + + // "Numlock-Hack": we want to get correct keycodes from the numpad + if ( (nCharCode >= '0') && (nCharCode <= '9') && !(nKeyFlags & KC_SHIFT) ) + rSVCode = KEYGROUP_NUM + (nCharCode-'0'); + if ( nCharCode == ',' ) + rSVCode = KEY_COMMA; + if ( nCharCode == '.' ) + rSVCode = KEY_POINT; + + return rSVCode; +} + +// ----------------------------------------------------------------------- + +static void ImplUpdateInputLang( Os2SalFrame* pFrame ) +{ + BOOL bLanguageChange = FALSE; + ULONG nLang = 0; + APIRET rc; + UconvObject uconv_object = NULL; + LocaleObject locale_object = NULL; + UniChar *pinfo_item; + + // we do not support change of input language while working, + // so exit if already defined (mnInputLang is a static class field) + if (pFrame->mnInputLang) + return; + + // get current locale + rc = UniCreateLocaleObject(UNI_UCS_STRING_POINTER, (UniChar *)L"", &locale_object); + // get Win32 locale id and sublanguage (hex uni string) + rc = UniQueryLocaleItem(locale_object, LOCI_xWinLocale, &pinfo_item); + // convert uni string to integer + rc = UniStrtoul(locale_object, pinfo_item, &pinfo_item, 16, &nLang); + rc = UniFreeMem(pinfo_item); +#if OSL_DEBUG_LEVEL>10 + debug_printf("ImplUpdateInputLang nLang %04x\n", nLang); + char char_buffer[256]; + rc = UniCreateUconvObject((UniChar *)L"", &uconv_object); + rc = UniQueryLocaleItem(locale_object, LOCI_sKeyboard, &pinfo_item); + rc = UniStrFromUcs(uconv_object, char_buffer, pinfo_item, sizeof(char_buffer)); + debug_printf("Keyboard name is: %s\n", char_buffer ); + rc = UniFreeMem(pinfo_item); +#endif + rc = UniFreeLocaleObject(locale_object); + + // keep input lang up-to-date +#if OSL_DEBUG_LEVEL>10 + debug_printf("ImplUpdateInputLang pFrame %08x lang changed from %d to %d\n", + pFrame, pFrame->mnInputLang, nLang); +#endif + pFrame->mnInputLang = nLang; +} + + +static sal_Unicode ImplGetCharCode( Os2SalFrame* pFrame, USHORT nKeyFlags, + sal_Char nCharCode, UCHAR nScanCode ) +{ + ImplUpdateInputLang( pFrame ); +#if OSL_DEBUG_LEVEL>10 + debug_printf("ImplGetCharCode nCharCode %c, %04x\n", nCharCode, nCharCode); +#endif + return OUString( &nCharCode, 1, gsl_getSystemTextEncoding()).toChar(); +} + +// ----------------------------------------------------------------------- + +LanguageType Os2SalFrame::GetInputLanguage() +{ + if( !mnInputLang ) + ImplUpdateInputLang( this ); + + if( !mnInputLang ) + return LANGUAGE_DONTKNOW; + else + return (LanguageType) mnInputLang; +} + +// ----------------------------------------------------------------------- + +BOOL Os2SalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , KeyCode& ) +{ + // not supported yet + return FALSE; +} + +// ----------------------------------------------------------------------- + +static sal_Unicode ImplConvertKey( Os2SalFrame* pFrame, MPARAM aMP1, MPARAM aMP2 ) +{ + USHORT nKeyFlags = SHORT1FROMMP( aMP1 ); + UCHAR nCharCode = (UCHAR)SHORT1FROMMP( aMP2 ); + USHORT nKeyCode = (UCHAR)SHORT2FROMMP( aMP2 ); + UCHAR nScanCode = (UCHAR)CHAR4FROMMP( aMP1 ); + sal_Unicode rSVCharCode = 0; + + // Ist Character-Code gesetzt + // !!! Bei CTRL/ALT ist KC_CHAR nicht gesetzt, jedoch moechten wir + // !!! dann auch einen CharCode und machen die Behandlung deshalb + // !!! selber + if ( (nKeyFlags & KC_CHAR) || (nKeyFlags & KC_CTRL) || (nKeyFlags & KC_ALT) ) + rSVCharCode = ImplGetCharCode( pFrame, nKeyFlags, nCharCode, nScanCode); + + // ret unicode + return rSVCharCode; +} + +// ----------------------------------------------------------------------- + +static long ImplHandleKeyMsg( HWND hWnd, + UINT nMsg, MPARAM nMP1, MPARAM nMP2 ) +{ + static USHORT nLastOS2KeyChar = 0; + static sal_Unicode nLastChar = 0; + USHORT nRepeat = CHAR3FROMMP( nMP1 ) - 1; + SHORT nFlags = SHORT1FROMMP( nMP1 ); + USHORT nModCode = 0; + USHORT nSVCode = 0; + USHORT nOS2KeyCode = (UCHAR)SHORT2FROMMP( nMP2 ); + sal_Unicode nSVCharCode = 0; + long nRet = 0; + + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( !pFrame ) + return 0; + + // determine modifiers + if ( nFlags & KC_SHIFT ) + nModCode |= KEY_SHIFT; + if ( nFlags & KC_CTRL ) + nModCode |= KEY_MOD1; + if ( nFlags & KC_ALT ) + nModCode |= KEY_MOD2; + + // Bei Shift, Control und Alt schicken wir einen KeyModChange-Event + if ( (nOS2KeyCode == VK_SHIFT) || (nOS2KeyCode == VK_CTRL) || + (nOS2KeyCode == VK_ALT) || (nOS2KeyCode == VK_ALTGRAF) ) + { + SalKeyModEvent aModEvt; + aModEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); + aModEvt.mnCode = nModCode; +#if OSL_DEBUG_LEVEL>10 + debug_printf("SALEVENT_KEYMODCHANGE\n"); +#endif + nRet = pFrame->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt ); + } + else + { + nSVCode = ImplSalGetKeyCode( pFrame, nMP1, nMP2 ); + nSVCharCode = ImplConvertKey( pFrame, nMP1, nMP2 ); +#if OSL_DEBUG_LEVEL>10 + debug_printf("nSVCode %04x nSVCharCode %04x\n",nSVCode,nSVCharCode ); +#endif + + // Fuer Java muessen wir bei KeyUp einen CharCode liefern + if ( nFlags & KC_KEYUP ) + { + if ( !nSVCharCode ) + { + if ( nLastOS2KeyChar == nOS2KeyCode ) + { + nSVCharCode = nLastChar; + nLastOS2KeyChar = 0; + nLastChar = 0; + } + } + else + { + nLastOS2KeyChar = 0; + nLastChar = 0; + } + } + else + { + nLastOS2KeyChar = nOS2KeyCode; + nLastChar = nSVCharCode; + } + + if ( nSVCode || nSVCharCode ) + { + SalKeyEvent aKeyEvt; + aKeyEvt.mnCode = nSVCode; + aKeyEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); + aKeyEvt.mnCode |= nModCode; + aKeyEvt.mnCharCode = nSVCharCode; + aKeyEvt.mnRepeat = nRepeat; + +#if OSL_DEBUG_LEVEL>10 + debug_printf( (nFlags & KC_KEYUP) ? "SALEVENT_KEYUP\n" : "SALEVENT_KEYINPUT\n"); +#endif + nRet = pFrame->CallCallback( (nFlags & KC_KEYUP) ? SALEVENT_KEYUP : SALEVENT_KEYINPUT, + &aKeyEvt ); + } + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +static bool ImplHandlePaintMsg( HWND hWnd ) +{ + BOOL bMutex = FALSE; + + if ( ImplSalYieldMutexTryToAcquire() ) + bMutex = TRUE; + + // if we don't get the mutex, we can also change the clip region, + // because other threads doesn't use the mutex from the main + // thread --> see GetGraphics() + + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( pFrame ) + { + // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine + // Paint-Region anliegt + if ( WinQueryUpdateRect( hWnd, NULL ) ) + { + // Call BeginPaint/EndPaint to query the rect and send + // this Notofication to rect + HPS hPS; + RECTL aUpdateRect; + hPS = WinBeginPaint( hWnd, NULLHANDLE, &aUpdateRect ); + WinEndPaint( hPS ); + + // Paint + if ( bMutex ) + { + SalPaintEvent aPEvt( aUpdateRect.xLeft, pFrame->mnHeight - aUpdateRect.yTop, aUpdateRect.xRight- aUpdateRect.xLeft, aUpdateRect.yTop - aUpdateRect.yBottom ); + + pFrame->CallCallback( SALEVENT_PAINT, &aPEvt ); + } + else + { + RECTL* pRect = new RECTL; + WinCopyRect( pFrame->mhAB, pRect, &aUpdateRect ); + WinPostMsg( hWnd, SAL_MSG_POSTPAINT, (MPARAM)pRect, 0 ); + } + } + } + + if ( bMutex ) + ImplSalYieldMutexRelease(); + + return bMutex ? true : false; +} + +// ----------------------------------------------------------------------- + +static void ImplHandlePaintMsg2( HWND hWnd, RECTL* pRect ) +{ + // Paint + if ( ImplSalYieldMutexTryToAcquire() ) + { + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( pFrame ) + { + SalPaintEvent aPEvt( pRect->xLeft, pFrame->mnHeight - pRect->yTop, pRect->xRight - pRect->xLeft, pRect->yTop - pRect->yBottom ); + pFrame->CallCallback( SALEVENT_PAINT, &aPEvt ); + } + ImplSalYieldMutexRelease(); + delete pRect; + } + else + WinPostMsg( hWnd, SAL_MSG_POSTPAINT, (MPARAM)pRect, 0 ); +} + +// ----------------------------------------------------------------------- + +static void SetMaximizedFrameGeometry( HWND hWnd, Os2SalFrame* pFrame ) +{ + // calculate and set frame geometry of a maximized window - useful if the window is still hidden + + RECTL aRect; + pFrame->GetWorkArea( aRect); + + // a maximized window has no other borders than the caption + pFrame->maGeometry.nLeftDecoration = pFrame->maGeometry.nRightDecoration = pFrame->maGeometry.nBottomDecoration = 0; + pFrame->maGeometry.nTopDecoration = pFrame->mbCaption ? WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) : 0; + + aRect.yTop += pFrame->maGeometry.nTopDecoration; + pFrame->maGeometry.nX = aRect.xLeft; + pFrame->maGeometry.nY = aRect.yBottom; + pFrame->maGeometry.nWidth = aRect.xRight - aRect.xLeft + 1; + pFrame->maGeometry.nHeight = aRect.yBottom - aRect.yTop + 1; +} + +static void UpdateFrameGeometry( HWND hWnd, Os2SalFrame* pFrame ) +{ + if( !pFrame ) + return; + + //SalFrame has a + //maGeometry member that holds absolute screen positions (and needs to be + //updated if the window is moved by the way). + + // reset data + memset(&pFrame->maGeometry, 0, sizeof(SalFrameGeometry) ); + + SWP swp; + LONG nFrameX, nFrameY, nCaptionY; + + // get frame size + WinQueryWindowPos(pFrame->mhWndFrame, &swp); + if (swp.fl & SWP_MINIMIZE) + return; + + // map from client area to screen + ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY); + pFrame->maGeometry.nTopDecoration = nFrameY + nCaptionY; + pFrame->maGeometry.nLeftDecoration = nFrameX; + pFrame->maGeometry.nRightDecoration = nFrameX; + pFrame->maGeometry.nBottomDecoration = nFrameY; + + // position of client area, not of frame corner! + pFrame->maGeometry.nX = swp.x + nFrameX; + pFrame->maGeometry.nY = nScreenHeight - (swp.y + swp.cy) + nFrameY + nCaptionY; + + int nWidth = swp.cx - pFrame->maGeometry.nRightDecoration - pFrame->maGeometry.nLeftDecoration; + int nHeight = swp.cy - pFrame->maGeometry.nBottomDecoration - pFrame->maGeometry.nTopDecoration; + + // clamp to zero + pFrame->maGeometry.nHeight = nHeight < 0 ? 0 : nHeight; + pFrame->maGeometry.nWidth = nWidth < 0 ? 0 : nWidth; +#if OSL_DEBUG_LEVEL>0 + debug_printf( "UpdateFrameGeometry: hwnd %x, frame %x at %d,%d (%dx%d)\n", + hWnd, pFrame->mhWndFrame, + pFrame->maGeometry.nX, pFrame->maGeometry.nY, + pFrame->maGeometry.nWidth,pFrame->maGeometry.nHeight); +#endif +} + +// ----------------------------------------------------------------------- + +static void ImplHandleMoveMsg( HWND hWnd) +{ + if ( ImplSalYieldMutexTryToAcquire() ) + { + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( pFrame ) + { + UpdateFrameGeometry( hWnd, pFrame ); + + if ( WinIsWindowVisible( hWnd )) + pFrame->mbDefPos = FALSE; + + // Gegen moegliche Rekursionen sichern + if ( !pFrame->mbInMoveMsg ) + { + // Fenster im FullScreenModus wieder einpassen + pFrame->mbInMoveMsg = TRUE; + if ( pFrame->mbFullScreen ) + ImplSalFrameFullScreenPos( pFrame ); + pFrame->mbInMoveMsg = FALSE; + } + + // Status merken + ImplSaveFrameState( pFrame ); + + // Call Hdl + //#93851 if we call this handler, VCL floating windows are not updated correctly + //ImplCallMoveHdl( hWnd ); + + } + + ImplSalYieldMutexRelease(); + } + else + WinPostMsg( hWnd, SAL_MSG_POSTMOVE, 0, 0 ); +} + +// ----------------------------------------------------------------------- + +static void ImplHandleSizeMsg( HWND hWnd, MPARAM nMP2 ) +{ + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( pFrame ) + { + UpdateFrameGeometry( hWnd, pFrame ); + pFrame->mbDefPos = FALSE; + pFrame->mnWidth = (short)SHORT1FROMMP( nMP2 ); + pFrame->mnHeight = (short)SHORT2FROMMP( nMP2 ); + if ( pFrame->mpGraphics ) + pFrame->mpGraphics->mnHeight = (int)SHORT2FROMMP(nMP2); + // Status merken + ImplSaveFrameState( pFrame ); + pFrame->CallCallback( SALEVENT_RESIZE, 0 ); + if ( WinIsWindowVisible( pFrame->mhWndFrame ) && !pFrame->mbInShow ) + WinUpdateWindow( pFrame->mhWndClient ); + } +} + +// ----------------------------------------------------------------------- + +static long ImplHandleFocusMsg( Os2SalFrame* pFrame, MPARAM nMP2 ) +{ +if ( pFrame && !Os2SalFrame::mbInReparent ) +{ + if ( SHORT1FROMMP( nMP2 ) ) + { + if ( WinIsWindowVisible( pFrame->mhWndFrame ) && !pFrame->mbInShow ) + WinUpdateWindow( pFrame->mhWndClient ); + return pFrame->CallCallback( SALEVENT_GETFOCUS, 0 ); + } + else + { + return pFrame->CallCallback( SALEVENT_LOSEFOCUS, 0 ); + } +} +} + +// ----------------------------------------------------------------------- + +static void ImplHandleCloseMsg( HWND hWnd ) +{ + if ( ImplSalYieldMutexTryToAcquire() ) + { + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( pFrame ) + { + pFrame->CallCallback( SALEVENT_CLOSE, 0 ); + } + + ImplSalYieldMutexRelease(); + } + else + WinPostMsg( hWnd, WM_CLOSE, 0, 0 ); +} + +// ----------------------------------------------------------------------- + +inline void ImplHandleUserEvent( HWND hWnd, MPARAM nMP2 ) +{ + ImplSalYieldMutexAcquireWithWait(); + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); + if ( pFrame ) + { + pFrame->CallCallback( SALEVENT_USEREVENT, (void*)nMP2 ); + } + ImplSalYieldMutexRelease(); +} + +// ----------------------------------------------------------------------- + +static int SalImplHandleProcessMenu( Os2SalFrame* pFrame, ULONG nMsg, MPARAM nMP1, MPARAM nMP2) +{ + long nRet = 0; +debug_printf("SalImplHandleProcessMenu\n"); +#if 0 + DWORD err=0; + if( !HIWORD(wParam) ) + { + // Menu command + WORD nId = LOWORD(wParam); + if( nId ) // zero for separators + { + SalMenuEvent aMenuEvt; + aMenuEvt.mnId = nId; + WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( pFrame->mSelectedhMenu, nId, FALSE ); + if( pSalMenuItem ) + aMenuEvt.mpMenu = pSalMenuItem->mpMenu; + else + aMenuEvt.mpMenu = NULL; + + nRet = pFrame->CallCallback( SALEVENT_MENUCOMMAND, &aMenuEvt ); + } + } +#endif + //return (nRet != 0); + return (nRet == 0); +} + +// ----------------------------------------------------------------------- + +static void ImplHandleInputLangChange( HWND hWnd ) +{ + ImplSalYieldMutexAcquireWithWait(); + + // Feststellen, ob wir IME unterstuetzen + Os2SalFrame* pFrame = GetWindowPtr( hWnd ); +#if 0 + if ( pFrame && pFrame->mbIME && pFrame->mhDefIMEContext ) + { + HWND hWnd = pFrame->mhWnd; + HKL hKL = (HKL)lParam; + UINT nImeProps = ImmGetProperty( hKL, IGP_PROPERTY ); + + pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0; + pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0; + pFrame->mbHandleIME = !pFrame->mbSpezIME; + } +#endif + + // trigger input language and codepage update + UINT nLang = pFrame->mnInputLang; + ImplUpdateInputLang( pFrame ); + debug_printf("ImplHandleInputLangChange new language 0x%04x\n",pFrame->mnInputLang); + + // notify change + if( nLang != pFrame->mnInputLang ) + pFrame->CallCallback( SALEVENT_INPUTLANGUAGECHANGE, 0 ); + + ImplSalYieldMutexRelease(); +} + +// ----------------------------------------------------------------------- + +#ifdef ENABLE_IME + +static long ImplHandleIMEStartConversion( Os2SalFrame* pFrame ) +{ + long nRet = FALSE; + SalIMEData* pIMEData = GetSalIMEData(); + if ( pIMEData ) + { + HWND hWnd = pFrame->mhWndClient; + HIMI hIMI = 0; + pIMEData->mpGetIME( hWnd, &hIMI ); + if ( hIMI ) + { + ULONG nProp; + if ( 0 != pIMEData->mpQueryIMEProperty( hIMI, QIP_PROPERTY, &nProp ) ) + pFrame->mbHandleIME = FALSE; + else + { + pFrame->mbHandleIME = !(nProp & PRP_SPECIALUI); + + } + if ( pFrame->mbHandleIME ) + { +/* Windows-Code, der noch nicht angepasst wurde !!! + // Cursor-Position ermitteln und aus der die Default-Position fuer + // das Composition-Fenster berechnen + SalCursorPosEvent aCursorPosEvt; + pFrame->CallCallback( pFrame->mpInst, pFrame, + SALEVENT_CURSORPOS, (void*)&aCursorPosEvt ); + COMPOSITIONFORM aForm; + memset( &aForm, 0, sizeof( aForm ) ); + if ( !aCursorPosEvt.mnWidth || !aCursorPosEvt.mnHeight ) + aForm.dwStyle |= CFS_DEFAULT; + else + { + aForm.dwStyle |= CFS_POINT; + aForm.ptCurrentPos.x = aCursorPosEvt.mnX; + aForm.ptCurrentPos.y = aCursorPosEvt.mnY; + } + ImmSetCompositionWindow( hIMC, &aForm ); + + // Den InputContect-Font ermitteln und diesem dem Composition-Fenster + // bekannt machen +*/ + + pFrame->mbConversionMode = TRUE; + pFrame->CallCallback( SALEVENT_STARTEXTTEXTINPUT, (void*)NULL ); + nRet = TRUE; + } + + pIMEData->mpReleaseIME( hWnd, hIMI ); + } + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +static long ImplHandleIMEConversion( Os2SalFrame* pFrame, MPARAM nMP2Param ) +{ + long nRet = FALSE; + SalIMEData* pIMEData = GetSalIMEData(); + if ( pIMEData ) + { + HWND hWnd = pFrame->mhWndClient; + HIMI hIMI = 0; + ULONG nMP2 = (ULONG)nMP2Param; + pIMEData->mpGetIME( hWnd, &hIMI ); + if ( hIMI ) + { + if ( nMP2 & (IMR_RESULT_RESULTSTRING | + IMR_CONV_CONVERSIONSTRING | IMR_CONV_CONVERSIONATTR | + IMR_CONV_CURSORPOS | IMR_CONV_CURSORATTR) ) + { + SalExtTextInputEvent aEvt; + aEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); + aEvt.mpTextAttr = NULL; + aEvt.mnCursorPos = 0; + aEvt.mnDeltaStart = 0; + aEvt.mbOnlyCursor = FALSE; + aEvt.mbCursorVisible = TRUE; + + ULONG nBufLen = 0; + xub_Unicode* pBuf = NULL; + ULONG nAttrBufLen = 0; + PM_BYTE* pAttrBuf = NULL; + BOOL bLastCursor = FALSE; + if ( nMP2 & IMR_RESULT_RESULTSTRING ) + { + pIMEData->mpGetResultString( hIMI, IMR_RESULT_RESULTSTRING, 0, &nBufLen ); + if ( nBufLen > 0 ) + { + pBuf = new xub_Unicode[nBufLen]; + pIMEData->mpGetResultString( hIMI, IMR_RESULT_RESULTSTRING, pBuf, &nBufLen ); + } + + bLastCursor = TRUE; + aEvt.mbCursorVisible = TRUE; + } + else if ( nMP2 & (IMR_CONV_CONVERSIONSTRING | IMR_CONV_CONVERSIONATTR | + IMR_CONV_CURSORPOS | IMR_CONV_CURSORATTR) ) + { + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, 0, &nBufLen ); + if ( nBufLen > 0 ) + { + pBuf = new xub_Unicode[nBufLen]; + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, pBuf, &nBufLen ); + } + + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONATTR, 0, &nAttrBufLen ); + if ( nAttrBufLen > 0 ) + { + pAttrBuf = new PM_BYTE[nAttrBufLen]; + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONATTR, pAttrBuf, &nAttrBufLen ); + } + +/* !!! Wir bekommen derzeit nur falsche Daten, deshalb zeigen wir derzeit + !!! auch keine Cursor an + ULONG nTempBufLen; + ULONG nCursorPos = 0; + ULONG nCursorAttr = 0; + ULONG nChangePos = 0; + nTempBufLen = sizeof( ULONG ); + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORPOS, &nCursorPos, &nTempBufLen ); + nTempBufLen = sizeof( ULONG ); + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORATTR, &nCursorAttr, &nTempBufLen ); + nTempBufLen = sizeof( ULONG ); + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CHANGESTART, &nChangePos, &nTempBufLen ); + + aEvt.mnCursorPos = nCursorPos; + aEvt.mnDeltaStart = nChangePos; + if ( nCursorAttr & CP_CURSORATTR_INVISIBLE ) + aEvt.mbCursorVisible = FALSE; +*/ + aEvt.mnCursorPos = 0; + aEvt.mnDeltaStart = 0; + aEvt.mbCursorVisible = FALSE; + + if ( (nMP2 == IMR_CONV_CURSORPOS) || + (nMP2 == IMR_CONV_CURSORATTR) ) + aEvt.mbOnlyCursor = TRUE; + } + + USHORT* pSalAttrAry = NULL; + if ( pBuf ) + { + aEvt.maText = XubString( pBuf, (USHORT)nBufLen ); + delete [] pBuf; + if ( pAttrBuf ) + { + USHORT nTextLen = aEvt.maText.Len(); + if ( nTextLen ) + { + pSalAttrAry = new USHORT[nTextLen]; + memset( pSalAttrAry, 0, nTextLen*sizeof( USHORT ) ); + for ( USHORT i = 0; (i < nTextLen) && (i < nAttrBufLen); i++ ) + { + PM_BYTE nOS2Attr = pAttrBuf[i]; + USHORT nSalAttr; + if ( nOS2Attr == CP_ATTR_TARGET_CONVERTED ) + nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETCONVERTED | SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; + else if ( nOS2Attr == CP_ATTR_CONVERTED ) + nSalAttr = SAL_EXTTEXTINPUT_ATTR_CONVERTED | SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE; + else if ( nOS2Attr == CP_ATTR_TARGET_NOTCONVERTED ) + nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETNOTCONVERTED | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE; + else if ( nOS2Attr == CP_ATTR_INPUT_ERROR ) + nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUTERROR | SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE; + else /* ( nOS2Attr == CP_ATTR_INPUT ) */ + nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE; + pSalAttrAry[i] = nSalAttr; + } + aEvt.mpTextAttr = pSalAttrAry; + } + delete [] pAttrBuf; + } + if ( bLastCursor ) + aEvt.mnCursorPos = aEvt.maText.Len(); + } + + pIMEData->mpReleaseIME( hWnd, hIMI ); + + // Handler rufen und wenn wir ein Attribute-Array haben, danach + // wieder zerstoeren + pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt ); + if ( pSalAttrAry ) + delete [] pSalAttrAry; + } + else + pIMEData->mpReleaseIME( hWnd, hIMI ); + } + + nRet = TRUE; + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +inline long ImplHandleIMEEndConversion( Os2SalFrame* pFrame ) +{ + pFrame->mbConversionMode = FALSE; + pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL ); + return TRUE; +} + +// ----------------------------------------------------------------------- + +static void ImplHandleIMEOpenCandidate( Os2SalFrame* pFrame ) +{ + pFrame->mbCandidateMode = TRUE; + + long nRet = FALSE; + SalIMEData* pIMEData = GetSalIMEData(); + if ( pIMEData ) + { + HWND hWnd = pFrame->mhWndClient; + HIMI hIMI = 0; + pIMEData->mpGetIME( hWnd, &hIMI ); + if ( hIMI ) + { + ULONG nBufLen = 0; + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, 0, &nBufLen ); + if ( nBufLen > 0 ) + { +/* !!! Wir bekommen derzeit nur falsche Daten steht der Cursor immer bei 0 + ULONG nTempBufLen = sizeof( ULONG ); + ULONG nCursorPos = 0; + pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORPOS, &nCursorPos, &nTempBufLen ); +*/ + ULONG nCursorPos = 0; + + SalExtTextInputPosEvent aEvt; + aEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); + aEvt.mnFirstPos = nCursorPos; + aEvt.mnChars = nBufLen-nCursorPos; + aEvt.mpPosAry = new SalExtCharPos[aEvt.mnChars]; + memset( aEvt.mpPosAry, 0, aEvt.mnChars*sizeof(SalExtCharPos) ); + + pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aEvt ); + + long nMinLeft = aEvt.mpPosAry[0].mnX; + long nMinTop = aEvt.mpPosAry[0].mnY; + long nMaxBottom = aEvt.mpPosAry[0].mnY+aEvt.mpPosAry[0].mnHeight; + long nMaxRight = nMinLeft; + USHORT i = 0; + while ( i < aEvt.mnChars ) + { + // Solange wir uns auf der gleichen Zeile bewegen, + // ermitteln wir die Rechteck-Grenzen + if ( !aEvt.mpPosAry[i].mnHeight || + (aEvt.mpPosAry[i].mnY < nMaxBottom-1) ) + { + if ( aEvt.mpPosAry[i].mnX < nMinLeft ) + nMinLeft = aEvt.mpPosAry[i].mnX; + if ( aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth > nMaxRight ) + nMaxRight = aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth; + if ( aEvt.mpPosAry[i].mnY < nMinTop ) + nMinTop = aEvt.mpPosAry[i].mnY; + i++; + } + else + break; + } + + CANDIDATEPOS aForm; + aForm.ulIndex = 0; + aForm.ulStyle = CPS_EXCLUDE; + aForm.ptCurrentPos.x = aEvt.mpPosAry[0].mnX; + aForm.ptCurrentPos.y = pFrame->mnHeight - (nMaxBottom+1) - 1; + aForm.rcArea.xLeft = nMinLeft; + aForm.rcArea.yBottom = pFrame->mnHeight - nMaxBottom - 1; + aForm.rcArea.xRight = nMaxRight+1; + aForm.rcArea.yTop = pFrame->mnHeight - nMinTop - 1; + pIMEData->mpSetCandidateWin( hIMI, &aForm ); + + delete aEvt.mpPosAry; + } + + pIMEData->mpReleaseIME( hWnd, hIMI ); + } + } +} + +// ----------------------------------------------------------------------- + +inline void ImplHandleIMECloseCandidate( Os2SalFrame* pFrame ) +{ + pFrame->mbCandidateMode = FALSE; +} + +#endif + +// ----------------------------------------------------------------------- + +MRESULT EXPENTRY SalFrameWndProc( HWND hWnd, ULONG nMsg, + MPARAM nMP1, MPARAM nMP2 ) +{ + Os2SalFrame* pFrame = (Os2SalFrame*)GetWindowPtr( hWnd ); + MRESULT nRet = (MRESULT)0; + BOOL bDef = TRUE; + bool bCheckTimers= false; + +#if OSL_DEBUG_LEVEL>10 + if (nMsg!=WM_TIMER && nMsg!=WM_MOUSEMOVE) + debug_printf( "SalFrameWndProc hWnd 0x%x nMsg 0x%x\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: + case SAL_MSG_MOUSELEAVE: + // ButtonUp/Down nie an die WinDefWindowProc weiterleiten, weil sonst + // die Message an den Owner weitergeleitet wird + ImplSalYieldMutexAcquireWithWait(); + bDef = !ImplHandleMouseMsg( hWnd, nMsg, nMP1, nMP2 ); + ImplSalYieldMutexRelease(); + break; + + case WM_CHAR: + if ( pFrame->mbConversionMode ) + bDef = FALSE; + else + bDef = !ImplHandleKeyMsg( hWnd, nMsg, nMP1, nMP2 ); + break; + + case WM_ERASEBACKGROUND: + nRet = (MRESULT)FALSE; + bDef = FALSE; + break; + + case WM_PAINT: + bCheckTimers = ImplHandlePaintMsg( hWnd ); + bDef = FALSE; + break; + case SAL_MSG_POSTPAINT: + ImplHandlePaintMsg2( hWnd, (RECTL*)nMP1 ); + bCheckTimers = true; + bDef = FALSE; + break; + + case WM_MOVE: + case SAL_MSG_POSTMOVE: + ImplHandleMoveMsg( hWnd ); + bDef = FALSE; + break; + + case WM_SIZE: + if ( ImplSalYieldMutexTryToAcquire() ) + { + ImplHandleSizeMsg( hWnd, nMP2 ); + ImplSalYieldMutexRelease(); + } + else + WinPostMsg( hWnd, SAL_MSG_POSTSIZE, nMP1, nMP2 ); + break; + case SAL_MSG_POSTSIZE: + ImplHandleSizeMsg( hWnd, nMP2 ); + break; + case WM_MINMAXFRAME: + if ( ImplSalYieldMutexTryToAcquire() ) + { + PSWP pswp = (PSWP) nMP1; + ImplHandleSizeMsg( hWnd, MPFROM2SHORT( pswp->cx, pswp->cy) ); + ImplSalYieldMutexRelease(); + } + else + WinPostMsg( hWnd, SAL_MSG_POSTSIZE, 0, nMP2 ); + break; + + case WM_CALCVALIDRECTS: + return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP); + + case WM_SETFOCUS: + if ( ImplSalYieldMutexTryToAcquire() ) + { + ImplHandleFocusMsg( pFrame, nMP2 ); + ImplSalYieldMutexRelease(); + } + else + WinPostMsg( hWnd, SAL_MSG_POSTFOCUS, 0, nMP2 ); + break; + case SAL_MSG_POSTFOCUS: + ImplHandleFocusMsg( pFrame, nMP2 ); + break; + + case WM_TRANSLATEACCEL: + { + // Da uns OS/2 zu viele Tasten abfaegnt, unternehmen wir etwas, + // damit wir Shift+F1, Shift+F10 und Shift+Enter bekommen + PQMSG pMsg = (PQMSG)nMP1; + USHORT nKeyFlags = SHORT1FROMMP( pMsg->mp1 ); + USHORT nKeyCode = (UCHAR)SHORT2FROMMP( pMsg->mp2 ); + + if ( !(nKeyFlags & KC_KEYUP) && (nKeyFlags & KC_VIRTUALKEY) && + (nKeyFlags & KC_SHIFT) && (nKeyCode != VK_ESC) ) + return (MRESULT)FALSE; + + if ( nKeyCode == VK_F1 ) + return (MRESULT)FALSE; + } + break; + + case WM_CREATE: + { + HWND hWndFrame = WinQueryWindow(hWnd, QW_PARENT); + if (hWndFrame == 0) + debug_printf(" WARNING NULL FRAME!!\n"); + SalData* pSalData = GetSalData(); + // Window-Instanz am Windowhandle speichern + pFrame = pSalData->mpCreateFrame; + pSalData->mpCreateFrame = NULL; + SetWindowPtr( hWnd, pFrame ); + SetWindowPtr( hWndFrame, pFrame); + // HWND schon hier setzen, da schon auf den Instanzdaten + // gearbeitet werden kann, wenn Messages waehrend + // CreateWindow() gesendet werden + pFrame->mhWndClient = hWnd; + pFrame->mhWndFrame = hWndFrame; + pFrame->maSysData.hWnd = hWnd; + } + break; + + case WM_CLOSE: + ImplHandleCloseMsg( hWnd ); + bDef = FALSE; + break; + + case WM_SYSVALUECHANGED: + if ( pFrame->mbFullScreen ) + ImplSalFrameFullScreenPos( pFrame ); + // kein break, da der Rest auch noch verarbeitet werden soll + case PL_ALTERED: + case WM_SYSCOLORCHANGE: + ImplSalYieldMutexAcquire(); + pFrame->CallCallback( SALEVENT_SETTINGSCHANGED, 0 ); + ImplSalYieldMutexRelease(); + break; + + case SAL_MSG_USEREVENT: + ImplHandleUserEvent( hWnd, nMP2 ); + bDef = FALSE; + break; + case SAL_MSG_TOTOP: + ImplSalToTop( hWnd, (ULONG)nMP1 ); + bDef = FALSE; + break; + case SAL_MSG_SHOW: + ImplSalShow( hWnd, (ULONG)nMP1, (ULONG)nMP2 ); + bDef = FALSE; + break; + + case WM_KBDLAYERCHANGED: + debug_printf("hWnd 0x%08x WM_KBDLAYERCHANGED\n", hWnd); + ImplHandleInputLangChange( hWnd ); + break; + + case WM_HSCROLL: + case WM_VSCROLL: + ImplHandleWheelMsg( hWnd, nMsg, nMP1, nMP2 ); + bDef = FALSE; + break; + + case WM_COMMAND: + case SAL_MSG_SYSPROCESSMENU: + if ( SalImplHandleProcessMenu( pFrame, nMsg, nMP1, nMP2 ) ) + { + bDef = FALSE; + nRet = (MRESULT)1; + } + break; + +#ifdef ENABLE_IME + case WM_IMEREQUEST: + if ( (ULONG)nMP1 == IMR_CONVRESULT ) + { + if ( pFrame->mbHandleIME ) + { + // Nur im Conversionmodus akzeptieren wir den IME-Input + if ( pFrame->mbConversionMode ) + { + ImplSalYieldMutexAcquire(); + if ( ImplHandleIMEConversion( pFrame, nMP2 ) ) + { + bDef = FALSE; + nRet = (MRESULT)TRUE; + } + ImplSalYieldMutexRelease(); + } + } + } + else if ( (ULONG)nMP1 == IMR_CANDIDATE ) + { + if ( pFrame->mbHandleIME ) + { + ImplSalYieldMutexAcquire(); + if ( (ULONG)nMP2 & IMR_CANDIDATE_SHOW ) + ImplHandleIMEOpenCandidate( pFrame ); + else if ( (ULONG)nMP2 & IMR_CANDIDATE_HIDE ) + ImplHandleIMECloseCandidate( pFrame ); + ImplSalYieldMutexRelease(); + } + } + break; + + case WM_IMENOTIFY: + if ( (ULONG)nMP1 == IMN_STARTCONVERSION ) + { + ImplSalYieldMutexAcquire(); + if ( ImplHandleIMEStartConversion( pFrame ) ) + { + bDef = FALSE; + nRet = (MRESULT)TRUE; + } + ImplSalYieldMutexRelease(); + } + else if ( (ULONG)nMP1 == IMN_ENDCONVERSION ) + { + if ( pFrame->mbHandleIME ) + { + ImplSalYieldMutexAcquire(); + if ( ImplHandleIMEEndConversion( pFrame ) ) + { + bDef = FALSE; + nRet = (MRESULT)TRUE; + } + ImplSalYieldMutexRelease(); + } + } + break; +#endif + } + + if( bCheckTimers ) + { + SalData* pSalData = GetSalData(); + if( pSalData->mnNextTimerTime ) + { + ULONG nCurTime; + DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, (PVOID)&nCurTime, sizeof(ULONG)); + if( pSalData->mnNextTimerTime < nCurTime ) + { + QMSG aMsg; + if (!WinPeekMsg( pFrame->mhAB, &aMsg, 0, WM_PAINT, WM_PAINT, PM_NOREMOVE ) ) + WinPostMsg( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_POSTTIMER, 0, (MPARAM)nCurTime ); + } + } + } + + if ( bDef ) + nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 ); + + return nRet; +} + +// ----------------------------------------------------------------------- + +void Os2SalFrame::ResetClipRegion() +{ +} + +void Os2SalFrame::BeginSetClipRegion( ULONG ) +{ +} + +void Os2SalFrame::UnionClipRegion( long, long, long, long ) +{ +} + +void Os2SalFrame::EndSetClipRegion() +{ +} + +// ----------------------------------------------------------------------- + +MRESULT EXPENTRY SalFrameSubClassWndProc( HWND hWnd, ULONG nMsg, + MPARAM nMP1, MPARAM nMP2 ) +{ + MRESULT mReturn = 0L; + + // ticket#124 min size of 132 px is too much + if (nMsg == WM_QUERYTRACKINFO) { + PTRACKINFO pti; + // first, let PM initialize TRACKINFO + mReturn = aSalShlData.mpFrameProc( hWnd, nMsg, nMP1, nMP2 ); + // now change default min size + pti = (PTRACKINFO) nMP2; + pti->ptlMinTrackSize.x = 64L; + // now return to PM + return mReturn; + } + + return aSalShlData.mpFrameProc( hWnd, nMsg, nMP1, nMP2 ); +} + +// ----------------------------------------------------------------------- |