summaryrefslogtreecommitdiff
path: root/vcl/ios/source/window/salframe.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/ios/source/window/salframe.cxx')
-rw-r--r--vcl/ios/source/window/salframe.cxx1151
1 files changed, 1151 insertions, 0 deletions
diff --git a/vcl/ios/source/window/salframe.cxx b/vcl/ios/source/window/salframe.cxx
new file mode 100644
index 000000000000..e18d242c59b4
--- /dev/null
+++ b/vcl/ios/source/window/salframe.cxx
@@ -0,0 +1,1151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include <string>
+
+#include "rtl/ustrbuf.hxx"
+
+#include "osl/file.h"
+
+#include "vcl/svapp.hxx"
+#include "vcl/window.hxx"
+#include "vcl/timer.hxx"
+
+#include "ios/saldata.hxx"
+#include "ios/salgdi.h"
+#include "ios/salframe.h"
+#include "ios/salmenu.h"
+#include "ios/saltimer.h"
+#include "ios/salinst.h"
+#include "ios/salframeview.h"
+
+#include "salwtype.hxx"
+
+using namespace std;
+
+// =======================================================================
+
+IosSalFrame* IosSalFrame::s_pCaptureFrame = NULL;
+
+// =======================================================================
+
+IosSalFrame::IosSalFrame( SalFrame* pParent, sal_uLong salFrameStyle ) :
+ mpWindow(nil),
+ mpView(nil),
+ mpGraphics(NULL),
+ mpParent(NULL),
+ mnMinWidth(0),
+ mnMinHeight(0),
+ mnMaxWidth(0),
+ mnMaxHeight(0),
+ mbGraphics(false),
+ mbShown(false),
+ mbInitShow(true),
+ mbPresentation( false ),
+ mnStyle( salFrameStyle ),
+ mnStyleMask( 0 ),
+ mnLastEventTime( 0 ),
+ mnLastModifierFlags( 0 ),
+ mpMenu( NULL ),
+ mnExtStyle( 0 ),
+ mePointerStyle( POINTER_ARROW ),
+ mrClippingPath( 0 ),
+ mnICOptions( 0 )
+{
+ maSysData.nSize = sizeof( SystemEnvData );
+
+ mpParent = dynamic_cast<IosSalFrame*>(pParent);
+
+ initWindowAndView();
+
+ SalData* pSalData = GetSalData();
+ pSalData->maFrames.push_front( this );
+ pSalData->maFrameCheck.insert( this );
+}
+
+// -----------------------------------------------------------------------
+
+IosSalFrame::~IosSalFrame()
+{
+ // cleanup clipping stuff
+ ResetClipRegion();
+
+ SalData* pSalData = GetSalData();
+ pSalData->maFrames.remove( this );
+ pSalData->maFrameCheck.erase( this );
+
+ DBG_ASSERT( this != s_pCaptureFrame, "capture frame destroyed" );
+ if( this == s_pCaptureFrame )
+ s_pCaptureFrame = NULL;
+
+ if ( mpGraphics )
+ delete mpGraphics;
+
+ if ( mpView ) {
+ [mpView release];
+ }
+ if ( mpWindow )
+ [mpWindow release];
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::initWindowAndView()
+{
+ // initialize mirroring parameters
+ // FIXME: screens changing
+ UIScreen * pScreen = [mpWindow screen];
+ if( pScreen == nil )
+ pScreen = [UIScreen mainScreen];
+ maScreenRect = [pScreen applicationFrame];
+
+ // calculate some default geometry
+ CGRect aVisibleRect = [pScreen applicationFrame];
+ CocoaTouchToVCL( aVisibleRect );
+
+ maGeometry.nX = static_cast<int>(aVisibleRect.origin.x + aVisibleRect.size.width / 10);
+ maGeometry.nY = static_cast<int>(aVisibleRect.origin.y + aVisibleRect.size.height / 10);
+ maGeometry.nWidth = static_cast<unsigned int>(aVisibleRect.size.width * 0.8);
+ maGeometry.nHeight = static_cast<unsigned int>(aVisibleRect.size.height * 0.8);
+
+ // calculate style mask
+ if( (mnStyle & SAL_FRAME_STYLE_FLOAT) ||
+ (mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
+ ;
+ else if( mnStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ // make default window "maximized"
+ maGeometry.nX = static_cast<int>(aVisibleRect.origin.x);
+ maGeometry.nY = static_cast<int>(aVisibleRect.origin.y);
+ maGeometry.nWidth = static_cast<int>(aVisibleRect.size.width);
+ maGeometry.nHeight = static_cast<int>(aVisibleRect.size.height);
+ }
+ else
+ {
+ if( (mnStyle & SAL_FRAME_STYLE_MOVEABLE) )
+ {
+ }
+ }
+
+ mpWindow = [[SalFrameWindow alloc] initWithSalFrame: this];
+ mpView = [[SalFrameView alloc] initWithSalFrame: this];
+
+ maSysData.pView = mpView;
+
+ UpdateFrameGeometry();
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::CocoaTouchToVCL( CGRect& io_rRect, bool bRelativeToScreen )
+{
+ if( bRelativeToScreen )
+ io_rRect.origin.y = maScreenRect.size.height - (io_rRect.origin.y+io_rRect.size.height);
+ else
+ io_rRect.origin.y = maGeometry.nHeight - (io_rRect.origin.y+io_rRect.size.height);
+}
+
+void IosSalFrame::VCLToCocoaTouch( CGRect& io_rRect, bool bRelativeToScreen )
+{
+ if( bRelativeToScreen )
+ io_rRect.origin.y = maScreenRect.size.height - (io_rRect.origin.y+io_rRect.size.height);
+ else
+ io_rRect.origin.y = maGeometry.nHeight - (io_rRect.origin.y+io_rRect.size.height);
+}
+
+void IosSalFrame::CocoaTouchToVCL( CGPoint& io_rPoint, bool bRelativeToScreen )
+{
+ if( bRelativeToScreen )
+ io_rPoint.y = maScreenRect.size.height - io_rPoint.y;
+ else
+ io_rPoint.y = maGeometry.nHeight - io_rPoint.y;
+}
+
+void IosSalFrame::VCLToCocoaTouch( CGPoint& io_rPoint, bool bRelativeToScreen )
+{
+ if( bRelativeToScreen )
+ io_rPoint.y = maScreenRect.size.height - io_rPoint.y;
+ else
+ io_rPoint.y = maGeometry.nHeight - io_rPoint.y;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::screenParametersChanged()
+{
+ UpdateFrameGeometry();
+
+ if( mpGraphics )
+ mpGraphics->updateResolution();
+ CallCallback( SALEVENT_DISPLAYCHANGED, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* IosSalFrame::GetGraphics()
+{
+ if ( mbGraphics )
+ return NULL;
+
+ if ( !mpGraphics )
+ {
+ mpGraphics = new IosSalGraphics;
+ mpGraphics->SetWindowGraphics( this );
+ }
+
+ mbGraphics = TRUE;
+ return mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::ReleaseGraphics( SalGraphics *pGraphics )
+{
+ (void)pGraphics;
+ DBG_ASSERT( pGraphics == mpGraphics, "graphics released on wrong frame" );
+ mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool IosSalFrame::PostEvent( void *pData )
+{
+ GetSalData()->mpFirstInstance->PostUserEvent( this, SALEVENT_USEREVENT, pData );
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+void IosSalFrame::SetTitle(const XubString& /* rTitle */)
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetIcon( sal_uInt16 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetRepresentedURL( const rtl::OUString& /* i_rDocURL */ )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::initShow()
+{
+ mbInitShow = false;
+ {
+ Rectangle aScreenRect;
+ GetWorkArea( aScreenRect );
+ if( mpParent ) // center relative to parent
+ {
+ // center on parent
+ long nNewX = mpParent->maGeometry.nX + ((long)mpParent->maGeometry.nWidth - (long)maGeometry.nWidth)/2;
+ if( nNewX < aScreenRect.Left() )
+ nNewX = aScreenRect.Left();
+ if( long(nNewX + maGeometry.nWidth) > aScreenRect.Right() )
+ nNewX = aScreenRect.Right() - maGeometry.nWidth-1;
+ long nNewY = mpParent->maGeometry.nY + ((long)mpParent->maGeometry.nHeight - (long)maGeometry.nHeight)/2;
+ if( nNewY < aScreenRect.Top() )
+ nNewY = aScreenRect.Top();
+ if( nNewY > aScreenRect.Bottom() )
+ nNewY = aScreenRect.Bottom() - maGeometry.nHeight-1;
+ SetPosSize( nNewX - mpParent->maGeometry.nX,
+ nNewY - mpParent->maGeometry.nY,
+ 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y );
+ }
+ else if( ! (mnStyle & SAL_FRAME_STYLE_SIZEABLE) )
+ {
+ // center on screen
+ long nNewX = (aScreenRect.GetWidth() - maGeometry.nWidth)/2;
+ long nNewY = (aScreenRect.GetHeight() - maGeometry.nHeight)/2;
+ SetPosSize( nNewX, nNewY, 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y );
+ }
+ }
+}
+
+void IosSalFrame::SendPaintEvent( const Rectangle* pRect )
+{
+ SalPaintEvent aPaintEvt( 0, 0, maGeometry.nWidth, maGeometry.nHeight, true );
+ if( pRect )
+ {
+ aPaintEvt.mnBoundX = pRect->Left();
+ aPaintEvt.mnBoundY = pRect->Top();
+ aPaintEvt.mnBoundWidth = pRect->GetWidth();
+ aPaintEvt.mnBoundHeight = pRect->GetHeight();
+ }
+
+ CallCallback(SALEVENT_PAINT, &aPaintEvt);
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::Show(sal_Bool bVisible, sal_Bool bNoActivate)
+{
+ if ( !mpWindow )
+ return;
+
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ mbShown = bVisible;
+ if(bVisible)
+ {
+ if( mbInitShow )
+ initShow();
+
+ CallCallback(SALEVENT_RESIZE, 0);
+ // trigger filling our backbuffer
+ SendPaintEvent();
+
+ if( !bNoActivate )
+ [mpWindow makeKeyAndVisible];
+#if 0 // ???
+ if( mpParent )
+ {
+ /* #i92674# #i96433# we do not want an invisible parent to show up (which adding a visible
+ child implicitly does). However we also do not want a parentless toolbar.
+
+ HACK: try to decide when we should not insert a child to its parent
+ floaters and ownerdraw windows have not yet shown up in cases where
+ we don't want the parent to become visible
+ */
+ if( mpParent->mbShown || (mnStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_FLOAT) ) )
+ {
+ [mpParent->mpWindow addChildWindow: mpWindow];
+ }
+ }
+
+ if( mbPresentation )
+ [mpWindow makeMainWindow];
+#endif
+ }
+ else
+ {
+#if 0 // ???
+ if( mpParent && [mpWindow parentWindow] == mpParent->mpWindow )
+ [mpParent->mpWindow removeChildWindow: mpWindow];
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::Enable( sal_Bool )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetMinClientSize( long nWidth, long nHeight )
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ mnMinWidth = nWidth;
+ mnMinHeight = nHeight;
+
+ if( mpWindow )
+ {
+ // Always add the decoration as the dimension concerns only
+ // the content rectangle
+ nWidth += maGeometry.nLeftDecoration + maGeometry.nRightDecoration;
+ nHeight += maGeometry.nTopDecoration + maGeometry.nBottomDecoration;
+
+ CGSize aSize = { nWidth, nHeight };
+#if 0 // ???
+ // Size of full window (content+structure) although we only
+ // have the client size in arguments
+ [mpWindow setMinSize: aSize];
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetMaxClientSize( long nWidth, long nHeight )
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ mnMaxWidth = nWidth;
+ mnMaxHeight = nHeight;
+
+ if( mpWindow )
+ {
+ // Always add the decoration as the dimension concerns only
+ // the content rectangle
+ nWidth += maGeometry.nLeftDecoration + maGeometry.nRightDecoration;
+ nHeight += maGeometry.nTopDecoration + maGeometry.nBottomDecoration;
+
+ // Carbon windows can't have a size greater than 32767x32767
+ if (nWidth>32767) nWidth=32767;
+ if (nHeight>32767) nHeight=32767;
+
+ CGSize aSize = { nWidth, nHeight };
+#if 0 // ???
+ // Size of full window (content+structure) although we only
+ // have the client size in arguments
+ [mpWindow setMaxSize: aSize];
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetClientSize( long nWidth, long nHeight )
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ if( mpWindow )
+ {
+ CGSize aSize = { nWidth, nHeight };
+#if 0 // ???
+ [mpWindow setContentSize: aSize];
+#endif
+ UpdateFrameGeometry();
+ if( mbShown )
+ // trigger filling our backbuffer
+ SendPaintEvent();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::GetClientSize( long& rWidth, long& rHeight )
+{
+ if( mbShown || mbInitShow )
+ {
+ rWidth = maGeometry.nWidth;
+ rHeight = maGeometry.nHeight;
+ }
+ else
+ {
+ rWidth = 0;
+ rHeight = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetWindowState( const SalFrameState* pState )
+{
+ // ???
+
+ // get new geometry
+ UpdateFrameGeometry();
+
+ sal_uInt16 nEvent = 0;
+ if( pState->mnMask & (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_X) )
+ {
+ mbPositioned = true;
+ nEvent = SALEVENT_MOVE;
+ }
+
+ if( pState->mnMask & (SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT) )
+ {
+ mbSized = true;
+ nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE;
+ }
+ // send event that we were moved/sized
+ if( nEvent )
+ CallCallback( nEvent, NULL );
+
+ if( mbShown && mpWindow )
+ {
+ // trigger filling our backbuffer
+ SendPaintEvent();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool IosSalFrame::GetWindowState( SalFrameState* pState )
+{
+ if ( !mpWindow )
+ return FALSE;
+
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ pState->mnMask = SAL_FRAMESTATE_MASK_X |
+ SAL_FRAMESTATE_MASK_Y |
+ SAL_FRAMESTATE_MASK_WIDTH |
+ SAL_FRAMESTATE_MASK_HEIGHT |
+ SAL_FRAMESTATE_MASK_STATE;
+
+ CGRect aStateRect = [mpWindow frame];
+#if 0 // ???
+ aStateRect = [UIWindow contentRectForFrameRect: aStateRect styleMask: mnStyleMask];
+ CocoaTouchToVCL( aStateRect );
+ pState->mnX = long(aStateRect.origin.x);
+ pState->mnY = long(aStateRect.origin.y);
+ pState->mnWidth = long(aStateRect.size.width);
+ pState->mnHeight = long(aStateRect.size.height);
+#endif
+ pState->mnState = SAL_FRAMESTATE_MAXIMIZED;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetScreenNumber(unsigned int nScreen)
+{
+ // ???
+}
+
+void IosSalFrame::SetApplicationID( const rtl::OUString &/*rApplicationID*/ )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay )
+{
+ // ???
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::StartPresentation( sal_Bool bStart )
+{
+ if ( !mpWindow )
+ return;
+
+ // ???
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetAlwaysOnTop( sal_Bool )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::ToTop(sal_uInt16 nFlags)
+{
+ if ( !mpWindow )
+ return;
+
+ // ???
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetPointer( PointerStyle ePointerStyle )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetPointerPos( long /* nX */ , long /* nY */ )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::Flush( void )
+{
+ // ???
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::Flush( const Rectangle& rRect )
+{
+ // ???
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::Sync()
+{
+ // ???
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetInputContext( SalInputContext* pContext )
+{
+ if (!pContext)
+ {
+ mnICOptions = 0;
+ return;
+ }
+
+ mnICOptions = pContext->mnOptions;
+
+ if(!(pContext->mnOptions & SAL_INPUTCONTEXT_TEXT))
+ return;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::EndExtTextInput( sal_uInt16 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+XubString IosSalFrame::GetKeyName( sal_uInt16 nKeyCode )
+{
+ static std::map< sal_uInt16, rtl::OUString > aKeyMap;
+ if( aKeyMap.empty() )
+ {
+ sal_uInt16 i;
+ for( i = KEY_A; i <= KEY_Z; i++ )
+ aKeyMap[ i ] = rtl::OUString( sal_Unicode( 'A' + (i - KEY_A) ) );
+ for( i = KEY_0; i <= KEY_9; i++ )
+ aKeyMap[ i ] = rtl::OUString( sal_Unicode( '0' + (i - KEY_0) ) );
+ for( i = KEY_F1; i <= KEY_F26; i++ )
+ {
+ rtl::OUStringBuffer aKey( 3 );
+ aKey.append( sal_Unicode( 'F' ) );
+ aKey.append( sal_Int32( i - KEY_F1 + 1 ) );
+ aKeyMap[ i ] = aKey.makeStringAndClear();
+ }
+
+ aKeyMap[ KEY_DOWN ] = rtl::OUString( sal_Unicode( 0x21e3 ) );
+ aKeyMap[ KEY_UP ] = rtl::OUString( sal_Unicode( 0x21e1 ) );
+ aKeyMap[ KEY_LEFT ] = rtl::OUString( sal_Unicode( 0x21e0 ) );
+ aKeyMap[ KEY_RIGHT ] = rtl::OUString( sal_Unicode( 0x21e2 ) );
+ aKeyMap[ KEY_HOME ] = rtl::OUString( sal_Unicode( 0x2196 ) );
+ aKeyMap[ KEY_END ] = rtl::OUString( sal_Unicode( 0x2198 ) );
+ aKeyMap[ KEY_PAGEUP ] = rtl::OUString( sal_Unicode( 0x21de ) );
+ aKeyMap[ KEY_PAGEDOWN ] = rtl::OUString( sal_Unicode( 0x21df ) );
+ aKeyMap[ KEY_RETURN ] = rtl::OUString( sal_Unicode( 0x21a9 ) );
+ aKeyMap[ KEY_ESCAPE ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "esc" ) );
+ aKeyMap[ KEY_TAB ] = rtl::OUString( sal_Unicode( 0x21e5 ) );
+ aKeyMap[ KEY_BACKSPACE ]= rtl::OUString( sal_Unicode( 0x232b ) );
+ aKeyMap[ KEY_SPACE ] = rtl::OUString( sal_Unicode( 0x2423 ) );
+ aKeyMap[ KEY_DELETE ] = rtl::OUString( sal_Unicode( 0x2326 ) );
+ aKeyMap[ KEY_ADD ] = rtl::OUString( sal_Unicode( '+' ) );
+ aKeyMap[ KEY_SUBTRACT ] = rtl::OUString( sal_Unicode( '-' ) );
+ aKeyMap[ KEY_DIVIDE ] = rtl::OUString( sal_Unicode( '/' ) );
+ aKeyMap[ KEY_MULTIPLY ] = rtl::OUString( sal_Unicode( '*' ) );
+ aKeyMap[ KEY_POINT ] = rtl::OUString( sal_Unicode( '.' ) );
+ aKeyMap[ KEY_COMMA ] = rtl::OUString( sal_Unicode( ',' ) );
+ aKeyMap[ KEY_LESS ] = rtl::OUString( sal_Unicode( '<' ) );
+ aKeyMap[ KEY_GREATER ] = rtl::OUString( sal_Unicode( '>' ) );
+ aKeyMap[ KEY_EQUAL ] = rtl::OUString( sal_Unicode( '=' ) );
+ aKeyMap[ KEY_OPEN ] = rtl::OUString( sal_Unicode( 0x23cf ) );
+
+ /* yet unmapped KEYCODES:
+ aKeyMap[ KEY_INSERT ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_CUT ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_COPY ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_PASTE ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_UNDO ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_REPEAT ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_FIND ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_PROPERTIES ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_FRONT ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_CONTEXTMENU ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_MENU ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_HELP ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_HANGUL_HANJA ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_DECIMAL ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_TILDE ] = rtl::OUString( sal_Unicode( ) );
+ aKeyMap[ KEY_QUOTELEFT ]= rtl::OUString( sal_Unicode( ) );
+ */
+
+ }
+
+ rtl::OUStringBuffer aResult( 16 );
+
+ sal_uInt16 nUnmodifiedCode = (nKeyCode & KEY_CODE);
+ std::map< sal_uInt16, rtl::OUString >::const_iterator it = aKeyMap.find( nUnmodifiedCode );
+ if( it != aKeyMap.end() )
+ {
+ if( (nKeyCode & KEY_SHIFT) != 0 )
+ aResult.append( sal_Unicode( 0x21e7 ) );
+ if( (nKeyCode & KEY_MOD1) != 0 )
+ aResult.append( sal_Unicode( 0x2318 ) );
+ // we do not really handle Alt (see below)
+ // we map it to MOD3, whichis actually Command
+ if( (nKeyCode & (KEY_MOD2|KEY_MOD3)) != 0 )
+ aResult.append( sal_Unicode( 0x2303 ) );
+
+ aResult.append( it->second );
+ }
+
+ return aResult.makeStringAndClear();
+}
+
+// -----------------------------------------------------------------------
+
+XubString IosSalFrame::GetSymbolKeyName( const XubString&, sal_uInt16 nKeyCode )
+{
+ return GetKeyName( nKeyCode );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::getResolution( long& o_rDPIX, long& o_rDPIY )
+{
+ if( ! mpGraphics )
+ {
+ GetGraphics();
+ ReleaseGraphics( mpGraphics );
+ }
+ mpGraphics->GetResolution( o_rDPIX, o_rDPIY );
+}
+
+void IosSalFrame::UpdateSettings( AllSettings& rSettings )
+{
+ if ( !mpWindow )
+ return;
+
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ StyleSettings aStyleSettings = rSettings.GetStyleSettings();
+
+ // Background Color
+ Color aBackgroundColor = Color( 0xEC, 0xEC, 0xEC );
+ aStyleSettings.Set3DColors( aBackgroundColor );
+ aStyleSettings.SetFaceColor( aBackgroundColor );
+ Color aInactiveTabColor( aBackgroundColor );
+ aInactiveTabColor.DecreaseLuminance( 32 );
+ aStyleSettings.SetInactiveTabColor( aInactiveTabColor );
+
+ aStyleSettings.SetDialogColor( aBackgroundColor );
+ aStyleSettings.SetLightBorderColor( aBackgroundColor );
+ Color aShadowColor( aStyleSettings.GetShadowColor() );
+ aStyleSettings.SetDarkShadowColor( aShadowColor );
+ aShadowColor.IncreaseLuminance( 32 );
+ aStyleSettings.SetShadowColor( aShadowColor );
+
+ // get the system font settings
+ Font aAppFont = aStyleSettings.GetAppFont();
+ long nDPIX = 72, nDPIY = 72;
+ getResolution( nDPIX, nDPIY );
+
+ aStyleSettings.SetToolbarIconSize( nDPIY > 160 ? STYLE_TOOLBAR_ICONSIZE_LARGE : STYLE_TOOLBAR_ICONSIZE_SMALL );
+
+ aStyleSettings.SetCursorBlinkTime( 500 );
+
+ // no mnemonics on iOs
+ aStyleSettings.SetOptions( aStyleSettings.GetOptions() | STYLE_OPTION_NOMNEMONICS );
+
+ // images in menus false for iOS
+ aStyleSettings.SetPreferredUseImagesInMenus( false );
+ aStyleSettings.SetHideDisabledMenuItems( sal_True );
+ aStyleSettings.SetAcceleratorsInContextMenus( sal_False );
+
+ rSettings.SetStyleSettings( aStyleSettings );
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* IosSalFrame::GetSystemData() const
+{
+ return &maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::Beep( SoundType eSoundType )
+{
+ switch( eSoundType )
+ {
+ case SOUND_DISABLE:
+ // don't beep
+ break;
+ default:
+ // ???
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags)
+{
+ if ( !mpWindow )
+ return;
+
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ sal_uInt16 nEvent = 0;
+
+ if (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y))
+ {
+ mbPositioned = true;
+ nEvent = SALEVENT_MOVE;
+ }
+
+ if (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
+ {
+ mbSized = true;
+ nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE;
+ }
+
+ CGRect aFrameRect = [mpWindow frame];
+#if 0 // ???
+ CGRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask];
+
+ // position is always relative to parent frame
+ CGRect aParentContentRect;
+
+ if( mpParent )
+ {
+ if( Application::GetSettings().GetLayoutRTL() )
+ {
+ if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 )
+ nX = mpParent->maGeometry.nWidth - nWidth-1 - nX;
+ else
+ nX = mpParent->maGeometry.nWidth - static_cast<long int>( aContentRect.size.width-1) - nX;
+ }
+ CGRect aParentFrameRect = [mpParent->mpWindow frame];
+ aParentContentRect = [NSWindow contentRectForFrameRect: aParentFrameRect styleMask: mpParent->mnStyleMask];
+ }
+ else
+ aParentContentRect = maScreenRect; // use screen if no parent
+
+ CocoaTouchToVCL( aContentRect );
+ CocoaTouchToVCL( aParentContentRect );
+
+ bool bPaint = false;
+ if( (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) != 0 )
+ {
+ if( nWidth != aContentRect.size.width || nHeight != aContentRect.size.height )
+ bPaint = true;
+ }
+
+ // use old window pos if no new pos requested
+ if( (nFlags & SAL_FRAME_POSSIZE_X) != 0 )
+ aContentRect.origin.x = nX + aParentContentRect.origin.x;
+ if( (nFlags & SAL_FRAME_POSSIZE_Y) != 0)
+ aContentRect.origin.y = nY + aParentContentRect.origin.y;
+
+ // use old size if no new size requested
+ if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 )
+ aContentRect.size.width = nWidth;
+ if( (nFlags & SAL_FRAME_POSSIZE_HEIGHT) != 0)
+ aContentRect.size.height = nHeight;
+
+ VCLToCocoaTouch( aContentRect );
+
+ // do not display yet, we need to update our backbuffer
+ {
+ [mpWindow setFrame: [NSWindow frameRectForContentRect: aContentRect styleMask: mnStyleMask] display: NO];
+ }
+
+ UpdateFrameGeometry();
+
+ if (nEvent)
+ CallCallback(nEvent, NULL);
+
+ if( mbShown && bPaint )
+ {
+ // trigger filling our backbuffer
+ SendPaintEvent();
+
+ // now inform the system that the views need to be drawn
+ [mpWindow display];
+ }
+#endif
+}
+
+void IosSalFrame::GetWorkArea( Rectangle& rRect )
+{
+ if ( !mpWindow )
+ return;
+
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ UIScreen* pScreen = [mpWindow screen];
+ if( pScreen == nil )
+ pScreen = [UIScreen mainScreen];
+ CGRect aRect = [pScreen applicationFrame];
+ CocoaTouchToVCL( aRect );
+ rRect.nLeft = static_cast<long>(aRect.origin.x);
+ rRect.nTop = static_cast<long>(aRect.origin.y);
+ rRect.nRight = static_cast<long>(aRect.origin.x + aRect.size.width - 1);
+ rRect.nBottom = static_cast<long>(aRect.origin.y + aRect.size.height - 1);
+}
+
+SalPointerState IosSalFrame::GetPointerState()
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ SalPointerState state;
+ state.mnState = 0;
+
+ // ???
+
+ return state;
+}
+
+SalFrame::SalIndicatorState IosSalFrame::GetIndicatorState()
+{
+ SalIndicatorState aState;
+ aState.mnState = 0;
+ return aState;
+}
+
+void IosSalFrame::SimulateKeyPress( sal_uInt16 /*nKeyCode*/ )
+{
+}
+
+bool IosSalFrame::SetPluginParent( SystemParentData* )
+{
+ // plugin parent may be killed unexpectedly by
+ // plugging process;
+
+ //TODO: implement
+ return sal_False;
+}
+
+sal_Bool IosSalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , KeyCode& )
+{
+ // not supported yet
+ return FALSE;
+}
+
+LanguageType IosSalFrame::GetInputLanguage()
+{
+ //TODO: implement
+ return LANGUAGE_DONTKNOW;
+}
+
+void IosSalFrame::DrawMenuBar()
+{
+}
+
+void IosSalFrame::SetMenu( SalMenu* pSalMenu )
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ // ???
+}
+
+void IosSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle )
+{
+ // ???
+}
+
+void IosSalFrame::SetBackgroundBitmap( SalBitmap* )
+{
+ //TODO: implement
+}
+
+SalBitmap* IosSalFrame::SnapShot()
+{
+ return mpGraphics ? mpGraphics->getBitmap( 0, 0, maGeometry.nWidth, maGeometry.nHeight ) : NULL;
+}
+
+SalFrame* IosSalFrame::GetParent() const
+{
+ return mpParent;
+}
+
+void IosSalFrame::SetParent( SalFrame* pNewParent )
+{
+ bool bShown = mbShown;
+ // remove from child list
+ Show( FALSE );
+ mpParent = (IosSalFrame*)pNewParent;
+ // insert to correct parent and paint
+ Show( bShown );
+}
+
+void IosSalFrame::UpdateFrameGeometry()
+{
+ if ( !mpWindow )
+ {
+ return;
+ }
+
+ // keep in mind that view and window coordinates are lower left
+ // whereas vcl's are upper left
+
+#if 0 // ???
+ // update screen rect
+ NSScreen * pScreen = [mpWindow screen];
+ if( pScreen )
+ {
+ maScreenRect = [pScreen frame];
+ NSArray* pScreens = [NSScreen screens];
+ if( pScreens )
+ maGeometry.nScreenNumber = [pScreens indexOfObject: pScreen];
+ }
+
+ CGRect aFrameRect = [mpWindow frame];
+
+ CGRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask];
+
+ // release old track rect
+ [mpView removeTrackingRect: mnTrackingRectTag];
+ // install the new track rect
+ CGRect aTrackRect = { { 0, 0 }, aContentRect.size };
+ mnTrackingRectTag = [mpView addTrackingRect: aTrackRect owner: mpView userData: nil assumeInside: NO];
+
+ // convert to vcl convention
+ CocoaTouchToVCL( aFrameRect );
+ CocoaTouchToVCL( aContentRect );
+
+ maGeometry.nX = static_cast<int>(aContentRect.origin.x);
+ maGeometry.nY = static_cast<int>(aContentRect.origin.y);
+
+ maGeometry.nLeftDecoration = static_cast<unsigned int>(aContentRect.origin.x - aFrameRect.origin.x);
+ maGeometry.nRightDecoration = static_cast<unsigned int>((aFrameRect.origin.x + aFrameRect.size.width) -
+ (aContentRect.origin.x + aContentRect.size.width));
+
+ maGeometry.nTopDecoration = static_cast<unsigned int>(aContentRect.origin.y - aFrameRect.origin.y);
+ maGeometry.nBottomDecoration = static_cast<unsigned int>((aFrameRect.origin.y + aFrameRect.size.height) -
+ (aContentRect.origin.y + aContentRect.size.height));
+
+ maGeometry.nWidth = static_cast<unsigned int>(aContentRect.size.width);
+ maGeometry.nHeight = static_cast<unsigned int>(aContentRect.size.height);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalFrame::CaptureMouse( sal_Bool bCapture )
+{
+ /* Remark:
+ we'll try to use a pidgin version of capture mouse
+ on MacOSX (neither carbon nor cocoa) there is a
+ CaptureMouse equivalent (in Carbon there is TrackMouseLocation
+ but this is useless to use since it is blocking)
+
+ However on cocoa the active frame seems to get mouse events
+ also outside the window, so we'll try to forward mouse events
+ to the capture frame in the hope that one of our frames
+ gets a mouse event.
+
+ This will break as soon as the user activates another app, but
+ a mouse click will normally lead to a release of the mouse anyway.
+
+ Let's see how far we get this way. Alternatively we could use one
+ large overlay window like we did for the carbon implementation,
+ however that is resource intensive.
+ */
+
+ if( bCapture )
+ s_pCaptureFrame = this;
+ else if( ! bCapture && s_pCaptureFrame == this )
+ s_pCaptureFrame = NULL;
+}
+
+void IosSalFrame::ResetClipRegion()
+{
+ if ( !mpWindow )
+ {
+ return;
+ }
+
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ // release old path and indicate no clipping
+ CGPathRelease( mrClippingPath );
+ mrClippingPath = NULL;
+
+ if( mpWindow )
+ {
+ [mpWindow setOpaque: YES];
+ }
+}
+
+void IosSalFrame::BeginSetClipRegion( sal_uLong nRects )
+{
+ if ( !mpWindow )
+ {
+ return;
+ }
+
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ // release old path
+ if( mrClippingPath )
+ {
+ CGPathRelease( mrClippingPath );
+ mrClippingPath = NULL;
+ }
+
+ if( maClippingRects.size() > SAL_CLIPRECT_COUNT && nRects < maClippingRects.size() )
+ {
+ std::vector<CGRect> aEmptyVec;
+ maClippingRects.swap( aEmptyVec );
+ }
+ maClippingRects.clear();
+ maClippingRects.reserve( nRects );
+}
+
+void IosSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ if( nWidth && nHeight )
+ {
+ CGRect aRect = { { nX, nY }, { nWidth, nHeight } };
+ VCLToCocoaTouch( aRect, false );
+ maClippingRects.push_back( CGRectMake(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height) );
+ }
+}
+
+void IosSalFrame::EndSetClipRegion()
+{
+ if ( !mpWindow )
+ {
+ return;
+ }
+
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ if( ! maClippingRects.empty() )
+ {
+ mrClippingPath = CGPathCreateMutable();
+ CGPathAddRects( mrClippingPath, NULL, &maClippingRects[0], maClippingRects.size() );
+ }
+ if( mpWindow )
+ {
+ [mpWindow setOpaque: (mrClippingPath != NULL) ? NO : YES];
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */