summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2011-07-31 01:52:37 +0300
committerTor Lillqvist <tml@iki.fi>2011-07-31 01:52:37 +0300
commit59a5b4dfb819bdd47394107c0de1ebd8c0573538 (patch)
tree357c13c2cd2f92d9634e0fb88f543a82a99141de /vcl
parent704bc46ae43d0386e5762b6a6158c7cef831dd1d (diff)
More iOS hacking, intermediate commit, certainly not working
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vcl.mk7
-rw-r--r--vcl/inc/ios/salbmp.h1
-rw-r--r--vcl/inc/ios/salframe.h11
-rw-r--r--vcl/inc/ios/salmenu.h69
-rw-r--r--vcl/ios/source/app/salinst.cxx79
-rw-r--r--vcl/ios/source/app/vcluiapp.mm4
-rw-r--r--vcl/ios/source/dtrans/iOSTransferable.cxx193
-rw-r--r--vcl/ios/source/dtrans/iOSTransferable.hxx95
-rw-r--r--vcl/ios/source/dtrans/ios_clipboard.cxx397
-rw-r--r--vcl/ios/source/dtrans/ios_clipboard.hxx182
-rw-r--r--vcl/ios/source/dtrans/service_entry.cxx73
-rw-r--r--vcl/ios/source/gdi/salbmp.cxx915
-rw-r--r--vcl/ios/source/window/salframe.cxx1151
-rw-r--r--vcl/ios/source/window/salmenu.cxx72
-rw-r--r--vcl/ios/source/window/salobj.cxx242
15 files changed, 3420 insertions, 71 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index e10dda06407c..625a51b6f8ac 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -449,8 +449,15 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/ios/source/app/salinst \
vcl/ios/source/app/salsys \
vcl/ios/source/app/saltimer \
+ vcl/ios/source/dtrans/iOSTransferable \
+ vcl/ios/source/dtrans/ios_clipboard \
+ vcl/ios/source/dtrans/service_entry \
+ vcl/ios/source/gdi/salbmp \
vcl/ios/source/gdi/salgdi \
vcl/ios/source/gdi/salvd \
+ vcl/ios/source/window/salframe \
+ vcl/ios/source/window/salmenu \
+ vcl/ios/source/window/salobj \
))
$(eval $(call gb_Library_use_externals,vcl,\
uikit \
diff --git a/vcl/inc/ios/salbmp.h b/vcl/inc/ios/salbmp.h
index 0c3e1468b154..abba132ee29d 100644
--- a/vcl/inc/ios/salbmp.h
+++ b/vcl/inc/ios/salbmp.h
@@ -35,6 +35,7 @@
#include "vcl/salbtype.hxx"
+#include "ios/salconst.h"
#include "ios/salgdi.h"
#include "saldata.hxx"
diff --git a/vcl/inc/ios/salframe.h b/vcl/inc/ios/salframe.h
index 14761fe36ebd..c6dc691d6302 100644
--- a/vcl/inc/ios/salframe.h
+++ b/vcl/inc/ios/salframe.h
@@ -73,6 +73,8 @@ public:
bool mbGraphics:1; // is Graphics used?
bool mbShown:1;
bool mbInitShow:1;
+ bool mbPositioned:1;
+ bool mbSized:1;
bool mbPresentation:1;
sal_uLong mnStyle;
@@ -183,6 +185,15 @@ public:
void getResolution( long& o_rDPIX, long& o_rDPIY );
+ // actually the follwing methods do the same thing: flipping y coordinates
+ // but having two of them makes clearer what the coordinate system
+ // is supposed to be before and after
+ void VCLToCocoaTouch( CGRect& io_rRect, bool bRelativeToScreen = true );
+ void CocoaTouchToVCL( CGRect& io_rRect, bool bRelativeToScreen = true );
+
+ void VCLToCocoaTouch( CGPoint& io_rPoint, bool bRelativeToScreen = true );
+ void CocoaTouchToVCL( CGPoint& io_Point, bool bRelativeToScreen = true );
+
CGMutablePathRef getClipPath() const { return mrClippingPath; }
// called by VCL_UIApplication to indicate screen settings have changed
diff --git a/vcl/inc/ios/salmenu.h b/vcl/inc/ios/salmenu.h
index 3f143ac1d976..8a07d94d4f38 100644
--- a/vcl/inc/ios/salmenu.h
+++ b/vcl/inc/ios/salmenu.h
@@ -42,79 +42,10 @@ class IosSalMenuItem;
class IosSalMenu : public SalMenu
{
- std::vector< IosSalMenuItem* > maItems;
-
-public: // for OOStatusView
- struct MenuBarButtonEntry
- {
- SalMenuButtonItem maButton;
- UIImage* mpUIImage; // cached image
- NSString* mpToolTipString;
-
- MenuBarButtonEntry() : mpUIImage( nil ), mpToolTipString( nil ) {}
- MenuBarButtonEntry( const SalMenuButtonItem& i_rItem )
- : maButton( i_rItem), mpUIImage( nil ), mpToolTipString( nil ) {}
- };
-private:
- std::vector< MenuBarButtonEntry > maButtons;
-
- MenuBarButtonEntry* findButtonItem( sal_uInt16 i_nItemId );
- void releaseButtonEntry( MenuBarButtonEntry& i_rEntry );
- static void statusLayout();
-public:
- IosSalMenu( bool bMenuBar );
- virtual ~IosSalMenu();
-
- virtual sal_Bool VisibleMenuBar(); // must return TRUE to actually DISPLAY native menu bars
- // otherwise only menu messages are processed (eg, OLE on Windows)
-
- virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos );
- virtual void RemoveItem( unsigned nPos );
- virtual void SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos );
- virtual void SetFrame( const SalFrame* pFrame );
- virtual void CheckItem( unsigned nPos, sal_Bool bCheck );
- virtual void EnableItem( unsigned nPos, sal_Bool bEnable );
- virtual void SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const XubString& rText );
- virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage);
- virtual void GetSystemMenuData( SystemMenuData* pData );
- virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, sal_uLong nFlags);
- virtual bool AddMenuBarButton( const SalMenuButtonItem& );
- virtual void RemoveMenuBarButton( sal_uInt16 nId );
- virtual Rectangle GetMenuBarButtonRectPixel( sal_uInt16 i_nItemId, SalFrame* i_pReferenceFrame );
-
- int getItemIndexByPos( sal_uInt16 nPos ) const;
- const IosSalFrame* getFrame() const;
-
- void setMainMenu();
- static void unsetMainMenu();
- static void setDefaultMenu();
- static void enableMainMenu( bool bEnable );
- static void addFallbackMenuItem( UIMenuItem* NewItem );
- static void removeFallbackMenuItem( UIMenuItem* pOldItem );
-
- const std::vector< MenuBarButtonEntry >& getButtons() const { return maButtons; }
-
- bool mbMenuBar; // true - Menubar, false - Menu
- UIMenuController* mpMenu;
- Menu* mpVCLMenu; // the corresponding vcl Menu object
- const IosSalFrame* mpFrame; // the frame to dispatch the menu events to
- IosSalMenu* mpParentSalMenu; // the parent menu that contains us (and perhaps has a frame)
-
- static const IosSalMenu* pCurrentMenuBar;
-
};
class IosSalMenuItem : public SalMenuItem
{
-public:
- IosSalMenuItem( const SalItemParams* );
- virtual ~IosSalMenuItem();
-
- sal_uInt16 mnId; // Item ID
- Menu* mpVCLMenu; // VCL Menu into which this MenuItem is inserted
- IosSalMenu* mpParentMenu; // The menu in which this menu item is inserted
- IosSalMenu* mpSubMenu; // Sub menu of this item (if defined)
- UIMenuItem* mpMenuItem; // The UIMenuItem
};
#endif // _SV_SALMENU_H
diff --git a/vcl/ios/source/app/salinst.cxx b/vcl/ios/source/app/salinst.cxx
index b4c944cd31a4..f95930ba0045 100644
--- a/vcl/ios/source/app/salinst.cxx
+++ b/vcl/ios/source/app/salinst.cxx
@@ -584,6 +584,77 @@ void IosSalInstance::DestroyObject( SalObject* pObject )
delete ( pObject );
}
+// -----------------------------------------------------------------------
+
+SalPrinter* IosSalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
+{
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalInstance::DestroyPrinter( SalPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
+{
+ // ???
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalInstance::GetPrinterQueueState( SalPrinterQueueInfo* )
+{
+ // ???
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
+{
+ delete pInfo;
+}
+
+// -----------------------------------------------------------------------
+
+XubString IosSalInstance::GetDefaultPrinter()
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ // ???
+ return maDefaultPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+SalInfoPrinter* IosSalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
+ ImplJobSetup* pSetupData )
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ SalInfoPrinter* pNewInfoPrinter = NULL;
+ // ???
+ return pNewInfoPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
+{
+ // #i113170# may not be the main thread if called from UNO API
+ SalData::ensureThreadAutoreleasePool();
+
+ delete pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
SalSystem* IosSalInstance::CreateSystem()
{
return new IosSalSystem();
@@ -705,6 +776,14 @@ SalSession* IosSalInstance::CreateSalSession()
// -----------------------------------------------------------------------
+SalI18NImeStatus* IosSalInstance::CreateI18NImeStatus()
+{
+ // ???
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
// YieldMutexReleaser
YieldMutexReleaser::YieldMutexReleaser() : mnCount( 0 )
{
diff --git a/vcl/ios/source/app/vcluiapp.mm b/vcl/ios/source/app/vcluiapp.mm
index e40d8a7eb792..d1aa842f6723 100644
--- a/vcl/ios/source/app/vcluiapp.mm
+++ b/vcl/ios/source/app/vcluiapp.mm
@@ -88,12 +88,12 @@
-(void)addFallbackMenuItem: (UIMenuItem*)pNewItem
{
- IosSalMenu::addFallbackMenuItem( pNewItem );
+ // ???
}
-(void)removeFallbackMenuItem: (UIMenuItem*)pItem
{
- IosSalMenu::removeFallbackMenuItem( pItem );
+ // ???
}
@end
diff --git a/vcl/ios/source/dtrans/iOSTransferable.cxx b/vcl/ios/source/dtrans/iOSTransferable.cxx
new file mode 100644
index 000000000000..68e534e676d3
--- /dev/null
+++ b/vcl/ios/source/dtrans/iOSTransferable.cxx
@@ -0,0 +1,193 @@
+/* -*- 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 <sal/types.h>
+
+#include "iOSTransferable.hxx"
+
+using namespace std;
+using namespace osl;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::io;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+
+using ::rtl::OUString;
+
+const Type CPPUTYPE_SEQINT8 = getCppuType((Sequence<sal_Int8>*)0);
+const Type CPPUTYPE_OUSTRING = getCppuType((OUString*)0);
+
+namespace // private
+{
+ bool isValidFlavor( const DataFlavor& aFlavor )
+ {
+ size_t len = aFlavor.MimeType.getLength();
+ Type dtype = aFlavor.DataType;
+ return ((len > 0) && ((dtype == CPPUTYPE_SEQINT8) || (dtype == CPPUTYPE_OUSTRING)));
+ }
+
+} // namespace private
+
+
+iOSTransferable::iOSTransferable(const Reference<XMimeContentTypeFactory> rXMimeCntFactory,
+ UIPasteboard* pasteboard) :
+ mrXMimeCntFactory(rXMimeCntFactory),
+ mPasteboard(pasteboard)
+{
+ [mPasteboard retain];
+
+ initClipboardItemList();
+}
+
+
+iOSTransferable::~iOSTransferable()
+{
+ [mPasteboard release];
+}
+
+
+Any SAL_CALL iOSTransferable::getTransferData( const DataFlavor& aFlavor )
+ throw( UnsupportedFlavorException, IOException, RuntimeException )
+{
+ if (!isValidFlavor(aFlavor) || !isDataFlavorSupported(aFlavor))
+ {
+ throw UnsupportedFlavorException(OUString(RTL_CONSTASCII_USTRINGPARAM("IosClipboard: Unsupported data flavor")),
+ static_cast<XTransferable*>(this));
+ }
+
+ throw UnsupportedFlavorException(OUString(RTL_CONSTASCII_USTRINGPARAM("IosClipboard: Unsupported data flavor")),
+ static_cast<XTransferable*>(this));
+ // ???
+ return Any();
+}
+
+
+bool iOSTransferable::isUnicodeText(const DataFlavor& flavor)
+{
+ return (flavor.DataType == CPPUTYPE_OUSTRING);
+}
+
+
+Sequence< DataFlavor > SAL_CALL iOSTransferable::getTransferDataFlavors( )
+ throw( RuntimeException )
+{
+ return mFlavorList;
+}
+
+
+sal_Bool SAL_CALL iOSTransferable::isDataFlavorSupported(const DataFlavor& aFlavor)
+ throw( RuntimeException )
+{
+ for (sal_Int32 i = 0; i < mFlavorList.getLength(); i++)
+ if (compareDataFlavors(aFlavor, mFlavorList[i]))
+ return sal_True;
+
+ return sal_False;
+}
+
+
+void iOSTransferable::initClipboardItemList()
+{
+ NSArray* pboardFormats = [mPasteboard pasteboardTypes];
+
+ if (pboardFormats == NULL)
+ {
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("IosClipboard: Cannot get clipboard data")),
+ static_cast<XTransferable*>(this));
+ }
+
+ // ???
+}
+
+
+/* Compares two DataFlavors. Returns true if both DataFlavor have the same media type
+ and the number of parameter and all parameter values do match otherwise false
+ is returned.
+ */
+bool iOSTransferable::compareDataFlavors(const DataFlavor& lhs, const DataFlavor& rhs )
+{
+ try
+ {
+ Reference<XMimeContentType> xLhs(mrXMimeCntFactory->createMimeContentType(lhs.MimeType));
+ Reference<XMimeContentType> xRhs(mrXMimeCntFactory->createMimeContentType(rhs.MimeType));
+
+ if (!xLhs->getFullMediaType().equalsIgnoreAsciiCase(xRhs->getFullMediaType()) ||
+ !cmpAllContentTypeParameter(xLhs, xRhs))
+ {
+ return false;
+ }
+ }
+ catch( IllegalArgumentException& )
+ {
+ OSL_FAIL( "Invalid content type detected" );
+ return false;
+ }
+
+ return true;
+}
+
+
+bool iOSTransferable::cmpAllContentTypeParameter(const Reference<XMimeContentType> xLhs,
+ const Reference<XMimeContentType> xRhs) const
+{
+ Sequence<OUString> xLhsFlavors = xLhs->getParameters();
+ Sequence<OUString> xRhsFlavors = xRhs->getParameters();
+
+ // Stop here if the number of parameters is different already
+ if (xLhsFlavors.getLength() != xRhsFlavors.getLength())
+ return false;
+
+ try
+ {
+ OUString pLhs;
+ OUString pRhs;
+
+ for (sal_Int32 i = 0; i < xLhsFlavors.getLength(); i++)
+ {
+ pLhs = xLhs->getParameterValue(xLhsFlavors[i]);
+ pRhs = xRhs->getParameterValue(xLhsFlavors[i]);
+
+ if (!pLhs.equalsIgnoreAsciiCase(pRhs))
+ {
+ return false;
+ }
+ }
+ }
+ catch(IllegalArgumentException&)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/ios/source/dtrans/iOSTransferable.hxx b/vcl/ios/source/dtrans/iOSTransferable.hxx
new file mode 100644
index 000000000000..8744ef1f92bd
--- /dev/null
+++ b/vcl/ios/source/dtrans/iOSTransferable.hxx
@@ -0,0 +1,95 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+#ifndef _TRANSFERABLE_HXX_
+#define _TRANSFERABLE_HXX_
+
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp>
+#include <com/sun/star/datatransfer/XMimeContentType.hpp>
+
+#include <premac.h>
+#import <UIKit/UIKit.h>
+#include <postmac.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <vector>
+
+
+class iOSTransferable : public ::cppu::WeakImplHelper1<com::sun::star::datatransfer::XTransferable>,
+ private ::boost::noncopyable
+{
+public:
+ typedef com::sun::star::uno::Sequence< sal_Int8 > ByteSequence_t;
+
+ explicit iOSTransferable(com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XMimeContentTypeFactory> rXMimeCntFactory,
+ UIPasteboard* pasteboard);
+
+ virtual ~iOSTransferable();
+
+ //------------------------------------------------------------------------
+ // XTransferable
+ //------------------------------------------------------------------------
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor )
+ throw( ::com::sun::star::datatransfer::UnsupportedFlavorException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------
+ // Helper functions not part of the XTransferable interface
+ //------------------------------------------------------------------------
+
+ void initClipboardItemList();
+
+ //com::sun::star::uno::Any getClipboardItemData(ClipboardItemPtr_t clipboardItem);
+
+ bool isUnicodeText(const com::sun::star::datatransfer::DataFlavor& flavor);
+
+ bool compareDataFlavors( const com::sun::star::datatransfer::DataFlavor& lhs,
+ const com::sun::star::datatransfer::DataFlavor& rhs );
+
+ bool cmpAllContentTypeParameter( const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType > xLhs,
+ const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType > xRhs ) const;
+
+private:
+ com::sun::star::uno::Sequence< com::sun::star::datatransfer::DataFlavor > mFlavorList;
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XMimeContentTypeFactory> mrXMimeCntFactory;
+ UIPasteboard* mPasteboard;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/ios/source/dtrans/ios_clipboard.cxx b/vcl/ios/source/dtrans/ios_clipboard.cxx
new file mode 100644
index 000000000000..69f9473737fb
--- /dev/null
+++ b/vcl/ios/source/dtrans/ios_clipboard.cxx
@@ -0,0 +1,397 @@
+/* -*- 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 "ios_clipboard.hxx"
+
+#include "iOSTransferable.hxx"
+
+#include "vcl/unohelp.hxx"
+
+#include "comphelper/makesequence.hxx"
+
+#include <boost/assert.hpp>
+
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::datatransfer::clipboard;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace cppu;
+using namespace osl;
+using namespace std;
+using namespace comphelper;
+
+using ::rtl::OUString;
+
+@implementation EventListener;
+
+-(EventListener*)initWithIosClipboard: (IosClipboard*) pcb
+{
+ self = [super init];
+
+ if (self)
+ pIosClipboard = pcb;
+
+ return self;
+}
+
+-(void)pasteboard:(UIPasteboard*)sender provideDataForType:(NSString*)type
+{
+ if( pIosClipboard )
+ pIosClipboard->provideDataForType(sender, type);
+}
+
+-(void)applicationDidBecomeActive:(NSNotification*)aNotification
+{
+ if( pIosClipboard )
+ pIosClipboard->applicationDidBecomeActive(aNotification);
+}
+
+-(void)disposing
+{
+ pIosClipboard = NULL;
+}
+
+@end
+
+
+OUString clipboard_getImplementationName()
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.clipboard.IosClipboard"));
+}
+
+Sequence<OUString> clipboard_getSupportedServiceNames()
+{
+ return makeSequence(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.clipboard.SystemClipboard")));
+}
+
+
+IosClipboard::IosClipboard(UIPasteboard* pasteboard, bool bUseSystemPasteboard) :
+ WeakComponentImplHelper4<XClipboardEx, XClipboardNotifier, XFlushableClipboard, XServiceInfo>(m_aMutex),
+ mIsSystemPasteboard(bUseSystemPasteboard)
+{
+ Reference<XMultiServiceFactory> mrServiceMgr = vcl::unohelper::GetMultiServiceFactory();
+
+ mrXMimeCntFactory = Reference<XMimeContentTypeFactory>(mrServiceMgr->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.MimeContentTypeFactory"))), UNO_QUERY);
+
+ if (!mrXMimeCntFactory.is())
+ {
+ throw RuntimeException(OUString(
+ RTL_CONSTASCII_USTRINGPARAM("IosClipboard: Cannot create com.sun.star.datatransfer.MimeContentTypeFactory")),
+ static_cast<XClipboardEx*>(this));
+ }
+#if 0 // ???
+ mpDataFlavorMapper = DataFlavorMapperPtr_t(new DataFlavorMapper());
+#endif
+ if (pasteboard != NULL)
+ {
+ mPasteboard = pasteboard;
+ mIsSystemPasteboard = false;
+ }
+ else
+ {
+ mPasteboard = bUseSystemPasteboard ? [UIPasteboard generalPasteboard] :
+ [UIPasteboard pasteboardWithName: @"org.libreoffice.pboard" create: YES];
+
+ if (mPasteboard == nil)
+ {
+ throw RuntimeException(OUString(
+ RTL_CONSTASCII_USTRINGPARAM("IosClipboard: Cannot create pasteboard")),
+ static_cast<XClipboardEx*>(this));
+ }
+ }
+
+ [mPasteboard retain];
+
+ mEventListener = [[EventListener alloc] initWithIosClipboard: this];
+
+ if (mEventListener == nil)
+ {
+ [mPasteboard release];
+
+ throw RuntimeException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("IosClipboard: Cannot create pasteboard change listener")),
+ static_cast<XClipboardEx*>(this));
+ }
+
+ if (mIsSystemPasteboard)
+ {
+ NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
+
+ [notificationCenter addObserver: mEventListener
+ selector: @selector(applicationDidBecomeActive:)
+ name: @"UIApplicationDidBecomeActiveNotification"
+ object: [UIApplication sharedApplication]];
+ }
+
+ mPasteboardChangeCount = [mPasteboard changeCount];
+}
+
+
+IosClipboard::~IosClipboard()
+{
+ if (mIsSystemPasteboard)
+ {
+ [[NSNotificationCenter defaultCenter] removeObserver: mEventListener];
+ }
+
+ [mEventListener disposing];
+ [mEventListener release];
+ [mPasteboard release];
+}
+
+
+Reference<XTransferable> SAL_CALL IosClipboard::getContents() throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ // Shortcut: If we are clipboard owner already we don't need
+ // to drag the data through the system clipboard
+ if (mXClipboardContent.is())
+ {
+ return mXClipboardContent;
+ }
+
+ return Reference<XTransferable>(new iOSTransferable(mrXMimeCntFactory,
+ mPasteboard));
+}
+
+
+void SAL_CALL IosClipboard::setContents(const Reference<XTransferable>& xTransferable,
+ const Reference<XClipboardOwner>& xClipboardOwner)
+ throw( RuntimeException )
+{
+#if 0 // ???
+ NSArray* types = xTransferable.is() ?
+ mpDataFlavorMapper->flavorSequenceToTypesArray(xTransferable->getTransferDataFlavors()) :
+ [NSArray array];
+
+ ClearableMutexGuard aGuard(m_aMutex);
+
+ Reference<XClipboardOwner> oldOwner(mXClipboardOwner);
+ mXClipboardOwner = xClipboardOwner;
+
+ Reference<XTransferable> oldContent(mXClipboardContent);
+ mXClipboardContent = xTransferable;
+
+ mPasteboardChangeCount = [mPasteboard declareTypes: types owner: mEventListener];
+
+ aGuard.clear();
+
+ // if we are already the owner of the clipboard
+ // then fire lost ownership event
+ if (oldOwner.is())
+ {
+ fireLostClipboardOwnershipEvent(oldOwner, oldContent);
+ }
+
+ fireClipboardChangedEvent();
+#endif
+}
+
+
+OUString SAL_CALL IosClipboard::getName() throw( RuntimeException )
+{
+ return OUString();
+}
+
+
+sal_Int8 SAL_CALL IosClipboard::getRenderingCapabilities() throw( RuntimeException )
+{
+ return 0;
+}
+
+
+void SAL_CALL IosClipboard::addClipboardListener(const Reference< XClipboardListener >& listener)
+ throw( RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+
+ if (!listener.is())
+ throw IllegalArgumentException(OUString(RTL_CONSTASCII_USTRINGPARAM("empty reference")),
+ static_cast<XClipboardEx*>(this), 1);
+
+ mClipboardListeners.push_back(listener);
+}
+
+
+void SAL_CALL IosClipboard::removeClipboardListener(const Reference< XClipboardListener >& listener)
+ throw( RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+
+ if (!listener.is())
+ throw IllegalArgumentException(OUString(RTL_CONSTASCII_USTRINGPARAM("empty reference")),
+ static_cast<XClipboardEx*>(this), 1);
+
+ mClipboardListeners.remove(listener);
+}
+
+
+void IosClipboard::applicationDidBecomeActive(NSNotification*)
+{
+ ClearableMutexGuard aGuard(m_aMutex);
+
+ int currentPboardChgCount = [mPasteboard changeCount];
+
+ if (currentPboardChgCount != mPasteboardChangeCount)
+ {
+ mPasteboardChangeCount = currentPboardChgCount;
+
+ // Clear clipboard content and owner and send lostOwnership
+ // notification to the old clipboard owner as well as
+ // ClipboardChanged notification to any clipboard listener
+ Reference<XClipboardOwner> oldOwner(mXClipboardOwner);
+ mXClipboardOwner = Reference<XClipboardOwner>();
+
+ Reference<XTransferable> oldContent(mXClipboardContent);
+ mXClipboardContent = Reference<XTransferable>();
+
+ aGuard.clear();
+
+ if (oldOwner.is())
+ {
+ fireLostClipboardOwnershipEvent(oldOwner, oldContent);
+ }
+
+ fireClipboardChangedEvent();
+ }
+}
+
+
+void IosClipboard::fireClipboardChangedEvent()
+{
+ ClearableMutexGuard aGuard(m_aMutex);
+
+ list<Reference< XClipboardListener > > listeners(mClipboardListeners);
+ ClipboardEvent aEvent;
+
+ if (listeners.begin() != listeners.end())
+ {
+ aEvent = ClipboardEvent(static_cast<OWeakObject*>(this), getContents());
+ }
+
+ aGuard.clear();
+
+ while (listeners.begin() != listeners.end())
+ {
+ if (listeners.front().is())
+ {
+ try { listeners.front()->changedContents(aEvent); }
+ catch (RuntimeException&) { }
+ }
+ listeners.pop_front();
+ }
+}
+
+
+void IosClipboard::fireLostClipboardOwnershipEvent(Reference<XClipboardOwner> oldOwner, Reference<XTransferable> oldContent)
+{
+ BOOST_ASSERT(oldOwner.is());
+
+ try { oldOwner->lostOwnership(static_cast<XClipboardEx*>(this), oldContent); }
+ catch(RuntimeException&) { }
+}
+
+
+void IosClipboard::provideDataForType(UIPasteboard* sender, NSString* type)
+{
+#if 0 // ???
+ if( mXClipboardContent.is() )
+ {
+ DataProviderPtr_t dp = mpDataFlavorMapper->getDataProvider(type, mXClipboardContent);
+ NSData* pBoardData = NULL;
+
+ if (dp.get() != NULL)
+ {
+ pBoardData = (NSData*)dp->getSystemData();
+ [sender setData: pBoardData forType: type];
+ }
+ }
+#endif
+}
+
+
+//------------------------------------------------
+// XFlushableClipboard
+//------------------------------------------------
+
+void SAL_CALL IosClipboard::flushClipboard()
+ throw(RuntimeException)
+{
+#if 0 // ???
+ if (mXClipboardContent.is())
+ {
+ Sequence<DataFlavor> flavorList = mXClipboardContent->getTransferDataFlavors();
+ sal_uInt32 nFlavors = flavorList.getLength();
+
+ for (sal_uInt32 i = 0; i < nFlavors; i++)
+ {
+ NSString* sysType = mpDataFlavorMapper->openOfficeToSystemFlavor(flavorList[i]);
+
+ if (sysType != NULL)
+ {
+ provideDataForType(mPasteboard, sysType);
+ }
+ }
+ mXClipboardContent.clear();
+ }
+#endif
+}
+
+
+UIPasteboard* IosClipboard::getPasteboard() const
+{
+ return mPasteboard;
+}
+
+
+//-------------------------------------------------
+// XServiceInfo
+//-------------------------------------------------
+
+OUString SAL_CALL IosClipboard::getImplementationName() throw( RuntimeException )
+{
+ return clipboard_getImplementationName();
+}
+
+
+sal_Bool SAL_CALL IosClipboard::supportsService( const OUString& /*ServiceName*/ ) throw( RuntimeException )
+{
+ return sal_False;
+}
+
+
+Sequence< OUString > SAL_CALL IosClipboard::getSupportedServiceNames() throw( RuntimeException )
+{
+ return clipboard_getSupportedServiceNames();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/ios/source/dtrans/ios_clipboard.hxx b/vcl/ios/source/dtrans/ios_clipboard.hxx
new file mode 100644
index 000000000000..3bd3a8923186
--- /dev/null
+++ b/vcl/ios/source/dtrans/ios_clipboard.hxx
@@ -0,0 +1,182 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef _IOS_CLIPBOARD_HXX_
+#define _IOS_CLIPBOARD_HXX_
+
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <cppuhelper/compbase4.hxx>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
+#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp>
+#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+
+#include <boost/utility.hpp>
+#include <list>
+
+#include <premac.h>
+#import <UIKit/UIKit.h>
+#include <postmac.h>
+
+class IosClipboard;
+
+@interface EventListener : NSObject
+{
+ IosClipboard* pIosClipboard;
+}
+
+// Init the pasteboard change listener with a reference to the OfficeClipboard
+// instance
+- (EventListener*)initWithIosClipboard: (IosClipboard*) pcb;
+
+// Promiss resolver function
+- (void)pasteboard:(UIPasteboard*)sender provideDataForType:(NSString *)type;
+
+-(void)applicationDidBecomeActive:(NSNotification*)aNotification;
+
+-(void)disposing;
+@end
+
+
+class IosClipboard : public ::cppu::BaseMutex,
+ public ::cppu::WeakComponentImplHelper4< com::sun::star::datatransfer::clipboard::XClipboardEx,
+ com::sun::star::datatransfer::clipboard::XClipboardNotifier,
+ com::sun::star::datatransfer::clipboard::XFlushableClipboard,
+ com::sun::star::lang::XServiceInfo >,
+ private ::boost::noncopyable
+{
+public:
+ /* Create a clipboard instance.
+
+ @param pasteboard
+ If not equal NULL the instance will be instantiated with the provided
+ pasteboard reference and 'bUseSystemClipboard' will be ignored
+
+ @param bUseSystemClipboard
+ If 'pasteboard' is NULL 'bUseSystemClipboard' determines whether the
+ system clipboard will be created (bUseSystemClipboard == true) or if
+ the DragPasteboard if bUseSystemClipboard == false
+ */
+ IosClipboard(UIPasteboard* pasteboard = NULL,
+ bool bUseSystemClipboard = true);
+
+ ~IosClipboard();
+
+ //------------------------------------------------
+ // XClipboard
+ //------------------------------------------------
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > SAL_CALL getContents()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setContents( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& xTransferable,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::rtl::OUString SAL_CALL getName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XClipboardEx
+ //------------------------------------------------
+
+ virtual sal_Int8 SAL_CALL getRenderingCapabilities()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XClipboardNotifier
+ //------------------------------------------------
+
+ virtual void SAL_CALL addClipboardListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener >& listener )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL removeClipboardListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener >& listener )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XFlushableClipboard
+ //------------------------------------------------
+
+ virtual void SAL_CALL flushClipboard( ) throw( com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XServiceInfo
+ //------------------------------------------------
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ /* Get a reference to the used pasteboard.
+ */
+ UIPasteboard* getPasteboard() const;
+
+ /* Notify the current clipboard owner that he is no longer the clipboard owner.
+ */
+ void fireLostClipboardOwnershipEvent(::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner> oldOwner,
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > oldContent);
+
+ void pasteboardChangedOwner();
+
+ void provideDataForType(UIPasteboard* sender, NSString* type);
+
+ void applicationDidBecomeActive(NSNotification* aNotification);
+
+private:
+
+ /* Notify all registered XClipboardListener that the clipboard content
+ has changed.
+ */
+ void fireClipboardChangedEvent();
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XMimeContentTypeFactory > mrXMimeCntFactory;
+ ::std::list< ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener > > mClipboardListeners;
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > mXClipboardContent;
+ com::sun::star::uno::Reference< com::sun::star::datatransfer::clipboard::XClipboardOwner > mXClipboardOwner;
+ bool mIsSystemPasteboard;
+ UIPasteboard* mPasteboard;
+ int mPasteboardChangeCount;
+ EventListener* mEventListener;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/ios/source/dtrans/service_entry.cxx b/vcl/ios/source/dtrans/service_entry.cxx
new file mode 100644
index 000000000000..c919dd13aba4
--- /dev/null
+++ b/vcl/ios/source/dtrans/service_entry.cxx
@@ -0,0 +1,73 @@
+/* -*- 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 "osl/diagnose.h"
+
+#include "vcl/svapp.hxx"
+
+#include "ios/saldata.hxx"
+#include "ios/salinst.h"
+
+#include "ios_clipboard.hxx"
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::cppu;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::datatransfer::clipboard;
+
+
+uno::Reference< XInterface > IosSalInstance::CreateClipboard( const Sequence< Any >& i_rArguments )
+{
+ if ( Application::IsHeadlessModeEnabled() )
+ return SalInstance::CreateClipboard( i_rArguments );
+
+ SalData* pSalData = GetSalData();
+ if( ! pSalData->mxClipboard.is() )
+ pSalData->mxClipboard = uno::Reference<XInterface>(static_cast< XClipboard* >(new IosClipboard()), UNO_QUERY);
+ return pSalData->mxClipboard;
+}
+
+uno::Reference<XInterface> IosSalInstance::CreateDragSource()
+{
+ // ???
+ return SalInstance::CreateDragSource();
+}
+
+uno::Reference<XInterface> IosSalInstance::CreateDropTarget()
+{
+ // ???
+ return SalInstance::CreateDropTarget();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/ios/source/gdi/salbmp.cxx b/vcl/ios/source/gdi/salbmp.cxx
new file mode 100644
index 000000000000..ea4bdecc811a
--- /dev/null
+++ b/vcl/ios/source/gdi/salbmp.cxx
@@ -0,0 +1,915 @@
+/* -*- 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 <boost/bind.hpp>
+
+#include "basebmp/scanlineformats.hxx"
+#include "basebmp/color.hxx"
+
+#include "basegfx/vector/b2ivector.hxx"
+
+#include "tools/color.hxx"
+
+#include "vcl/bitmap.hxx" // for BitmapSystemData
+#include "vcl/salbtype.hxx"
+
+#include "ios/salbmp.h"
+#include "ios/salinst.h"
+
+#include "bmpfast.hxx"
+
+// =======================================================================
+
+static bool isValidBitCount( sal_uInt16 nBitCount )
+{
+ return (nBitCount == 1) || (nBitCount == 4) || (nBitCount == 8) || (nBitCount == 16) || (nBitCount == 24) || (nBitCount == 32);
+}
+
+// =======================================================================
+
+IosSalBitmap::IosSalBitmap()
+: mxGraphicContext( NULL )
+, mxCachedImage( NULL )
+, mnBits(0)
+, mnWidth(0)
+, mnHeight(0)
+, mnBytesPerRow(0)
+{
+}
+
+// ------------------------------------------------------------------
+
+IosSalBitmap::~IosSalBitmap()
+{
+ Destroy();
+}
+
+// ------------------------------------------------------------------
+
+bool IosSalBitmap::Create( CGLayerRef xLayer, int nBitmapBits,
+ int nX, int nY, int nWidth, int nHeight, bool /*bMirrorVert*/ )
+{
+ DBG_ASSERT( xLayer, "IosSalBitmap::Create() from non-layered context" );
+
+ // sanitize input parameters
+ if( nX < 0 )
+ nWidth += nX, nX = 0;
+ if( nY < 0 )
+ nHeight += nY, nY = 0;
+ const CGSize aLayerSize = CGLayerGetSize( xLayer );
+ if( nWidth >= (int)aLayerSize.width - nX )
+ nWidth = (int)aLayerSize.width - nX;
+ if( nHeight >= (int)aLayerSize.height - nY )
+ nHeight = (int)aLayerSize.height - nY;
+ if( (nWidth < 0) || (nHeight < 0) )
+ nWidth = nHeight = 0;
+
+ // initialize properties
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+ mnBits = nBitmapBits ? nBitmapBits : 32;
+
+ // initialize drawing context
+ CreateContext();
+
+ // copy layer content into the bitmap buffer
+ const CGPoint aSrcPoint = { -nX, -nY };
+ ::CGContextDrawLayerAtPoint( mxGraphicContext, aSrcPoint, xLayer );
+ return true;
+}
+
+// ------------------------------------------------------------------
+
+bool IosSalBitmap::Create( const Size& rSize, sal_uInt16 nBits, const BitmapPalette& rBitmapPalette )
+{
+ if( !isValidBitCount( nBits ) )
+ return false;
+ maPalette = rBitmapPalette;
+ mnBits = nBits;
+ mnWidth = rSize.Width();
+ mnHeight = rSize.Height();
+ return AllocateUserData();
+}
+
+// ------------------------------------------------------------------
+
+bool IosSalBitmap::Create( const SalBitmap& rSalBmp )
+{
+ return Create( rSalBmp, rSalBmp.GetBitCount() );
+}
+
+// ------------------------------------------------------------------
+
+bool IosSalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+ return Create( rSalBmp, pGraphics ? pGraphics->GetBitCount() : rSalBmp.GetBitCount() );
+}
+
+// ------------------------------------------------------------------
+
+bool IosSalBitmap::Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount )
+{
+ const IosSalBitmap& rSourceBitmap = static_cast<const IosSalBitmap&>(rSalBmp);
+
+ if( isValidBitCount( nNewBitCount ) && rSourceBitmap.maUserBuffer.get() )
+ {
+ mnBits = nNewBitCount;
+ mnWidth = rSourceBitmap.mnWidth;
+ mnHeight = rSourceBitmap.mnHeight;
+ maPalette = rSourceBitmap.maPalette;
+
+ if( AllocateUserData() )
+ {
+ ConvertBitmapData( mnWidth, mnHeight, mnBits, mnBytesPerRow, maPalette, maUserBuffer.get(), rSourceBitmap.mnBits, rSourceBitmap.mnBytesPerRow, rSourceBitmap.maPalette, rSourceBitmap.maUserBuffer.get() );
+ return true;
+ }
+ }
+ return false;
+}
+
+// ------------------------------------------------------------------
+
+bool IosSalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
+{
+ return false;
+}
+
+// ------------------------------------------------------------------
+
+void IosSalBitmap::Destroy()
+{
+ DestroyContext();
+ maUserBuffer.reset();
+}
+
+// ------------------------------------------------------------------
+
+void IosSalBitmap::DestroyContext()
+{
+ CGImageRelease( mxCachedImage );
+ mxCachedImage = NULL;
+
+ if( mxGraphicContext )
+ {
+ CGContextRelease( mxGraphicContext );
+ mxGraphicContext = NULL;
+ maContextBuffer.reset();
+ }
+}
+
+// ------------------------------------------------------------------
+
+bool IosSalBitmap::CreateContext()
+{
+ DestroyContext();
+
+ // prepare graphics context
+ // convert image from user input if available
+ const bool bSkipConversion = !maUserBuffer;
+ if( bSkipConversion )
+ AllocateUserData();
+
+ // default to RGBA color space
+ CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
+ CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst;
+
+ // convert data into something accepted by CGBitmapContextCreate()
+ size_t bitsPerComponent = (mnBits == 16) ? 5 : 8;
+ sal_uInt32 nContextBytesPerRow = mnBytesPerRow;
+ if( (mnBits == 16) || (mnBits == 32) )
+ {
+ // no conversion needed for truecolor
+ maContextBuffer = maUserBuffer;
+ }
+ else if( (mnBits == 8) && maPalette.IsGreyPalette() )
+ {
+ // no conversion needed for grayscale
+ maContextBuffer = maUserBuffer;
+ aCGColorSpace = GetSalData()->mxGraySpace;
+ aCGBmpInfo = kCGImageAlphaNone;
+ bitsPerComponent = mnBits;
+ }
+ // TODO: is special handling for 1bit input buffers worth it?
+ else
+ {
+ // convert user data to 32 bit
+ nContextBytesPerRow = mnWidth << 2;
+ try
+ {
+ maContextBuffer.reset( new sal_uInt8[ mnHeight * nContextBytesPerRow ] );
+
+ if( !bSkipConversion )
+ ConvertBitmapData( mnWidth, mnHeight,
+ 32, nContextBytesPerRow, maPalette, maContextBuffer.get(),
+ mnBits, mnBytesPerRow, maPalette, maUserBuffer.get() );
+ }
+ catch( std::bad_alloc )
+ {
+ mxGraphicContext = 0;
+ }
+ }
+
+ if( maContextBuffer.get() )
+ {
+ mxGraphicContext = ::CGBitmapContextCreate( maContextBuffer.get(), mnWidth, mnHeight,
+ bitsPerComponent, nContextBytesPerRow, aCGColorSpace, aCGBmpInfo );
+ }
+
+ if( !mxGraphicContext )
+ maContextBuffer.reset();
+
+ return mxGraphicContext != NULL;
+}
+
+// ------------------------------------------------------------------
+
+bool IosSalBitmap::AllocateUserData()
+{
+ Destroy();
+
+ if( mnWidth && mnHeight )
+ {
+ mnBytesPerRow = 0;
+
+ switch( mnBits )
+ {
+ case 1: mnBytesPerRow = (mnWidth + 7) >> 3; break;
+ case 4: mnBytesPerRow = (mnWidth + 1) >> 1; break;
+ case 8: mnBytesPerRow = mnWidth; break;
+ case 16: mnBytesPerRow = mnWidth << 1; break;
+ case 24: mnBytesPerRow = (mnWidth << 1) + mnWidth; break;
+ case 32: mnBytesPerRow = mnWidth << 2; break;
+ default:
+ OSL_FAIL("vcl::IosSalBitmap::AllocateUserData(), illegal bitcount!");
+ }
+ }
+
+ try
+ {
+ if( mnBytesPerRow )
+ maUserBuffer.reset( new sal_uInt8[mnBytesPerRow * mnHeight] );
+ }
+ catch( const std::bad_alloc& )
+ {
+ OSL_FAIL( "vcl::IosSalBitmap::AllocateUserData: bad alloc" );
+ maUserBuffer.reset( NULL );
+ mnBytesPerRow = 0;
+ }
+
+ return maUserBuffer.get() != 0;
+}
+
+// ------------------------------------------------------------------
+
+class ImplPixelFormat
+{
+protected:
+ sal_uInt8* pData;
+public:
+ static ImplPixelFormat* GetFormat( sal_uInt16 nBits, const BitmapPalette& rPalette );
+
+ virtual void StartLine( sal_uInt8* pLine ) { pData = pLine; }
+ virtual void SkipPixel( sal_uInt32 nPixel ) = 0;
+ virtual ColorData ReadPixel() = 0;
+ virtual void WritePixel( ColorData nColor ) = 0;
+};
+
+class ImplPixelFormat32 : public ImplPixelFormat
+// currently ARGB-format for 32bit depth
+{
+public:
+ virtual void SkipPixel( sal_uInt32 nPixel )
+ {
+ pData += nPixel << 2;
+ }
+ virtual ColorData ReadPixel()
+ {
+ const ColorData c = RGB_COLORDATA( pData[1], pData[2], pData[3] );
+ pData += 4;
+ return c;
+ }
+ virtual void WritePixel( ColorData nColor )
+ {
+ *pData++ = 0;
+ *pData++ = COLORDATA_RED( nColor );
+ *pData++ = COLORDATA_GREEN( nColor );
+ *pData++ = COLORDATA_BLUE( nColor );
+ }
+};
+
+class ImplPixelFormat24 : public ImplPixelFormat
+// currently BGR-format for 24bit depth
+{
+public:
+ virtual void SkipPixel( sal_uInt32 nPixel )
+ {
+ pData += (nPixel << 1) + nPixel;
+ }
+ virtual ColorData ReadPixel()
+ {
+ const ColorData c = RGB_COLORDATA( pData[2], pData[1], pData[0] );
+ pData += 3;
+ return c;
+ }
+ virtual void WritePixel( ColorData nColor )
+ {
+ *pData++ = COLORDATA_BLUE( nColor );
+ *pData++ = COLORDATA_GREEN( nColor );
+ *pData++ = COLORDATA_RED( nColor );
+ }
+};
+
+class ImplPixelFormat16 : public ImplPixelFormat
+// currently R5G6B5-format for 16bit depth
+{
+protected:
+ sal_uInt16* pData16;
+public:
+
+ virtual void StartLine( sal_uInt8* pLine )
+ {
+ pData16 = (sal_uInt16*)pLine;
+ }
+ virtual void SkipPixel( sal_uInt32 nPixel )
+ {
+ pData += nPixel;
+ }
+ virtual ColorData ReadPixel()
+ {
+ const ColorData c = RGB_COLORDATA( (*pData & 0x7c00) >> 7, (*pData & 0x03e0) >> 2 , (*pData & 0x001f) << 3 );
+ pData++;
+ return c;
+ }
+ virtual void WritePixel( ColorData nColor )
+ {
+ *pData++ = ((COLORDATA_RED( nColor ) & 0xf8 ) << 7 ) ||
+ ((COLORDATA_GREEN( nColor ) & 0xf8 ) << 2 ) ||
+ ((COLORDATA_BLUE( nColor ) & 0xf8 ) >> 3 );
+ }
+};
+
+class ImplPixelFormat8 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+
+public:
+ ImplPixelFormat8( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual void SkipPixel( sal_uInt32 nPixel )
+ {
+ pData += nPixel;
+ }
+ virtual ColorData ReadPixel()
+ {
+ return mrPalette[ *pData++ ].operator Color().GetColor();
+ }
+ virtual void WritePixel( ColorData nColor )
+ {
+ const BitmapColor aColor( COLORDATA_RED( nColor ), COLORDATA_GREEN( nColor ), COLORDATA_BLUE( nColor ) );
+ *pData++ = static_cast< sal_uInt8 >( mrPalette.GetBestIndex( aColor ) );
+ }
+};
+
+class ImplPixelFormat4 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+ sal_uInt32 mnX;
+ sal_uInt32 mnShift;
+
+public:
+ ImplPixelFormat4( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual void SkipPixel( sal_uInt32 nPixel )
+ {
+ mnX += nPixel;
+ if( (nPixel & 1) )
+ mnShift ^= 4;
+ }
+ virtual void StartLine( sal_uInt8* pLine )
+ {
+ pData = pLine;
+ mnX = 0;
+ mnShift = 4;
+ }
+ virtual ColorData ReadPixel()
+ {
+ const BitmapColor& rColor = mrPalette[( pData[mnX >> 1] >> mnShift) & 0x0f];
+ mnX++;
+ mnShift ^= 4;
+ return rColor.operator Color().GetColor();
+ }
+ virtual void WritePixel( ColorData nColor )
+ {
+ const BitmapColor aColor( COLORDATA_RED( nColor ), COLORDATA_GREEN( nColor ), COLORDATA_BLUE( nColor ) );
+ pData[mnX>>1] &= (0xf0 >> mnShift);
+ pData[mnX>>1] |= (static_cast< sal_uInt8 >( mrPalette.GetBestIndex( aColor ) ) & 0x0f);
+ mnX++;
+ mnShift ^= 4;
+ }
+};
+
+class ImplPixelFormat1 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+ sal_uInt32 mnX;
+
+public:
+ ImplPixelFormat1( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual void SkipPixel( sal_uInt32 nPixel )
+ {
+ mnX += nPixel;
+ }
+ virtual void StartLine( sal_uInt8* pLine )
+ {
+ pData = pLine;
+ mnX = 0;
+ }
+ virtual ColorData ReadPixel()
+ {
+ const BitmapColor& rColor = mrPalette[ (pData[mnX >> 3 ] >> ( 7 - ( mnX & 7 ) )) & 1];
+ mnX++;
+ return rColor.operator Color().GetColor();
+ }
+ virtual void WritePixel( ColorData nColor )
+ {
+ const BitmapColor aColor( COLORDATA_RED( nColor ), COLORDATA_GREEN( nColor ), COLORDATA_BLUE( nColor ) );
+ if( mrPalette.GetBestIndex( aColor ) & 1 )
+ pData[ mnX >> 3 ] |= 1 << ( 7 - ( mnX & 7 ) );
+ else
+ pData[ mnX >> 3 ] &= ~( 1 << ( 7 - ( mnX & 7 ) ) );
+ mnX++;
+ }
+};
+
+ImplPixelFormat* ImplPixelFormat::GetFormat( sal_uInt16 nBits, const BitmapPalette& rPalette )
+{
+ switch( nBits )
+ {
+ case 1: return new ImplPixelFormat1( rPalette );
+ case 4: return new ImplPixelFormat4( rPalette );
+ case 8: return new ImplPixelFormat8( rPalette );
+ case 16: return new ImplPixelFormat16;
+ case 24: return new ImplPixelFormat24;
+ case 32: return new ImplPixelFormat32;
+ }
+
+ return 0;
+}
+
+void IosSalBitmap::ConvertBitmapData( sal_uInt32 nWidth, sal_uInt32 nHeight,
+ sal_uInt16 nDestBits, sal_uInt32 nDestBytesPerRow, const BitmapPalette& rDestPalette, sal_uInt8* pDestData,
+ sal_uInt16 nSrcBits, sal_uInt32 nSrcBytesPerRow, const BitmapPalette& rSrcPalette, sal_uInt8* pSrcData )
+
+{
+ if( (nDestBytesPerRow == nSrcBytesPerRow) && (nDestBits == nSrcBits) && ((nSrcBits != 8) || (rDestPalette.operator==( rSrcPalette ))) )
+ {
+ // simple case, same format, so just copy
+ memcpy( pDestData, pSrcData, nHeight * nDestBytesPerRow );
+ return;
+ }
+
+ // try accelerated conversion if possible
+ // TODO: are other truecolor conversions except BGR->ARGB worth it?
+ bool bConverted = false;
+ if( (nSrcBits == 24) && (nDestBits == 32) )
+ {
+ // TODO: extend bmpfast.cxx with a method that can be directly used here
+ BitmapBuffer aSrcBuf;
+ aSrcBuf.mnFormat = BMP_FORMAT_24BIT_TC_BGR;
+ aSrcBuf.mpBits = pSrcData;
+ aSrcBuf.mnBitCount = nSrcBits;
+ aSrcBuf.mnScanlineSize = nSrcBytesPerRow;
+ BitmapBuffer aDstBuf;
+ aDstBuf.mnFormat = BMP_FORMAT_32BIT_TC_ARGB;
+ aDstBuf.mpBits = pDestData;
+ aSrcBuf.mnBitCount = nDestBits;
+ aDstBuf.mnScanlineSize = nDestBytesPerRow;
+
+ aSrcBuf.mnWidth = aDstBuf.mnWidth = nWidth;
+ aSrcBuf.mnHeight = aDstBuf.mnHeight = nHeight;
+
+ SalTwoRect aTwoRects;
+ aTwoRects.mnSrcX = aTwoRects.mnDestX = 0;
+ aTwoRects.mnSrcY = aTwoRects.mnDestY = 0;
+ aTwoRects.mnSrcWidth = aTwoRects.mnDestWidth = mnWidth;
+ aTwoRects.mnSrcHeight = aTwoRects.mnDestHeight = mnHeight;
+ bConverted = ::ImplFastBitmapConversion( aDstBuf, aSrcBuf, aTwoRects );
+ }
+
+ if( !bConverted )
+ {
+ // TODO: this implementation is for clarety, not for speed
+
+ ImplPixelFormat* pD = ImplPixelFormat::GetFormat( nDestBits, rDestPalette );
+ ImplPixelFormat* pS = ImplPixelFormat::GetFormat( nSrcBits, rSrcPalette );
+
+ if( pD && pS )
+ {
+ sal_uInt32 nY = nHeight;
+ while( nY-- )
+ {
+ pD->StartLine( pDestData );
+ pS->StartLine( pSrcData );
+
+ sal_uInt32 nX = nWidth;
+ while( nX-- )
+ pD->WritePixel( pS->ReadPixel() );
+
+ pSrcData += nSrcBytesPerRow;
+ pDestData += nDestBytesPerRow;
+ }
+ }
+ delete pS;
+ delete pD;
+ }
+}
+
+// ------------------------------------------------------------------
+
+Size IosSalBitmap::GetSize() const
+{
+ return Size( mnWidth, mnHeight );
+}
+
+// ------------------------------------------------------------------
+
+sal_uInt16 IosSalBitmap::GetBitCount() const
+{
+ return mnBits;
+}
+
+// ------------------------------------------------------------------
+
+static struct pal_entry
+{
+ sal_uInt8 mnRed;
+ sal_uInt8 mnGreen;
+ sal_uInt8 mnBlue;
+}
+const aImplSalSysPalEntryAry[ 16 ] =
+{
+{ 0, 0, 0 },
+{ 0, 0, 0x80 },
+{ 0, 0x80, 0 },
+{ 0, 0x80, 0x80 },
+{ 0x80, 0, 0 },
+{ 0x80, 0, 0x80 },
+{ 0x80, 0x80, 0 },
+{ 0x80, 0x80, 0x80 },
+{ 0xC0, 0xC0, 0xC0 },
+{ 0, 0, 0xFF },
+{ 0, 0xFF, 0 },
+{ 0, 0xFF, 0xFF },
+{ 0xFF, 0, 0 },
+{ 0xFF, 0, 0xFF },
+{ 0xFF, 0xFF, 0 },
+{ 0xFF, 0xFF, 0xFF }
+};
+
+const BitmapPalette& GetDefaultPalette( int mnBits, bool bMonochrome )
+{
+ if( bMonochrome )
+ return Bitmap::GetGreyPalette( 1U << mnBits );
+
+ // at this point we should provide some kind of default palette
+ // since all other platforms do so, too.
+ static bool bDefPalInit = false;
+ static BitmapPalette aDefPalette256;
+ static BitmapPalette aDefPalette16;
+ static BitmapPalette aDefPalette2;
+ if( ! bDefPalInit )
+ {
+ bDefPalInit = true;
+ aDefPalette256.SetEntryCount( 256 );
+ aDefPalette16.SetEntryCount( 16 );
+ aDefPalette2.SetEntryCount( 2 );
+
+ // Standard colors
+ unsigned int i;
+ for( i = 0; i < 16; i++ )
+ {
+ aDefPalette16[i] =
+ aDefPalette256[i] = BitmapColor( aImplSalSysPalEntryAry[i].mnRed,
+ aImplSalSysPalEntryAry[i].mnGreen,
+ aImplSalSysPalEntryAry[i].mnBlue );
+ }
+
+ aDefPalette2[0] = BitmapColor( 0, 0, 0 );
+ aDefPalette2[1] = BitmapColor( 0xff, 0xff, 0xff );
+
+ // own palette (6/6/6)
+ const int DITHER_PAL_STEPS = 6;
+ const sal_uInt8 DITHER_PAL_DELTA = 51;
+ int nB, nG, nR;
+ sal_uInt8 nRed, nGreen, nBlue;
+ for( nB=0, nBlue=0; nB < DITHER_PAL_STEPS; nB++, nBlue += DITHER_PAL_DELTA )
+ {
+ for( nG=0, nGreen=0; nG < DITHER_PAL_STEPS; nG++, nGreen += DITHER_PAL_DELTA )
+ {
+ for( nR=0, nRed=0; nR < DITHER_PAL_STEPS; nR++, nRed += DITHER_PAL_DELTA )
+ {
+ aDefPalette256[ i ] = BitmapColor( nRed, nGreen, nBlue );
+ i++;
+ }
+ }
+ }
+ }
+
+ // now fill in appropriate palette
+ switch( mnBits )
+ {
+ case 1: return aDefPalette2;
+ case 4: return aDefPalette16;
+ case 8: return aDefPalette256;
+ default: break;
+ }
+
+ const static BitmapPalette aEmptyPalette;
+ return aEmptyPalette;
+}
+
+BitmapBuffer* IosSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
+{
+ if( !maUserBuffer.get() )
+// || maContextBuffer.get() && (maUserBuffer.get() != maContextBuffer.get()) )
+ {
+ fprintf(stderr,"ASB::Acq(%dx%d,d=%d)\n",mnWidth,mnHeight,mnBits);
+ // TODO: AllocateUserData();
+ return NULL;
+ }
+
+ BitmapBuffer* pBuffer = new BitmapBuffer;
+ pBuffer->mnWidth = mnWidth;
+ pBuffer->mnHeight = mnHeight;
+ pBuffer->maPalette = maPalette;
+ pBuffer->mnScanlineSize = mnBytesPerRow;
+ pBuffer->mpBits = maUserBuffer.get();
+ pBuffer->mnBitCount = mnBits;
+ switch( mnBits )
+ {
+ case 1: pBuffer->mnFormat = BMP_FORMAT_1BIT_MSB_PAL; break;
+ case 4: pBuffer->mnFormat = BMP_FORMAT_4BIT_MSN_PAL; break;
+ case 8: pBuffer->mnFormat = BMP_FORMAT_8BIT_PAL; break;
+ case 16: pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
+ pBuffer->maColorMask = ColorMask( k16BitRedColorMask, k16BitGreenColorMask, k16BitBlueColorMask );
+ break;
+ case 24: pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_BGR; break;
+ case 32: pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_ARGB;
+ pBuffer->maColorMask = ColorMask( k32BitRedColorMask, k32BitGreenColorMask, k32BitBlueColorMask );
+ break;
+ }
+ pBuffer->mnFormat |= BMP_FORMAT_BOTTOM_UP;
+
+ // some BitmapBuffer users depend on a complete palette
+ if( (mnBits <= 8) && !maPalette )
+ pBuffer->maPalette = GetDefaultPalette( mnBits, true );
+
+ return pBuffer;
+}
+
+// ------------------------------------------------------------------
+
+void IosSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
+{
+ // invalidate graphic context if we have different data
+ if( !bReadOnly )
+ {
+ maPalette = pBuffer->maPalette;
+ if( mxGraphicContext )
+ DestroyContext();
+ }
+
+ delete pBuffer;
+}
+
+// ------------------------------------------------------------------
+
+CGImageRef IosSalBitmap::CreateCroppedImage( int nX, int nY, int nNewWidth, int nNewHeight ) const
+{
+ if( !mxCachedImage )
+ {
+ if( !mxGraphicContext )
+ if( !const_cast<IosSalBitmap*>(this)->CreateContext() )
+ return NULL;
+
+ mxCachedImage = CGBitmapContextCreateImage( mxGraphicContext );
+ }
+
+ CGImageRef xCroppedImage = NULL;
+ // short circuit if there is nothing to crop
+ if( !nX && !nY && (mnWidth == nNewWidth) && (mnHeight == nNewHeight) )
+ {
+ xCroppedImage = mxCachedImage;
+ CFRetain( xCroppedImage );
+ }
+ else
+ {
+ nY = mnHeight - (nY + nNewHeight); // adjust for y-mirrored context
+ const CGRect aCropRect = {{nX, nY}, {nNewWidth, nNewHeight}};
+ xCroppedImage = CGImageCreateWithImageInRect( mxCachedImage, aCropRect );
+ }
+
+ return xCroppedImage;
+}
+
+// ------------------------------------------------------------------
+
+static void CFRTLFree(void* /*info*/, const void* data, size_t /*size*/)
+{
+ rtl_freeMemory( const_cast<void*>(data) );
+}
+
+CGImageRef IosSalBitmap::CreateWithMask( const IosSalBitmap& rMask,
+ int nX, int nY, int nWidth, int nHeight ) const
+{
+ CGImageRef xImage( CreateCroppedImage( nX, nY, nWidth, nHeight ) );
+ if( !xImage )
+ return NULL;
+
+ CGImageRef xMask = rMask.CreateCroppedImage( nX, nY, nWidth, nHeight );
+ if( !xMask )
+ return xImage;
+
+ // CGImageCreateWithMask() only likes masks or greyscale images => convert if needed
+ // TODO: isolate in an extra method?
+ if( !CGImageIsMask(xMask) || (CGImageGetColorSpace(xMask) != GetSalData()->mxGraySpace) )
+ {
+ const CGRect xImageRect=CGRectMake( 0, 0, nWidth, nHeight );//the rect has no offset
+
+ // create the alpha mask image fitting our image
+ // TODO: is caching the full mask or the subimage mask worth it?
+ int nMaskBytesPerRow = ((nWidth + 3) & ~3);
+ void* pMaskMem = rtl_allocateMemory( nMaskBytesPerRow * nHeight );
+ CGContextRef xMaskContext = CGBitmapContextCreate( pMaskMem,
+ nWidth, nHeight, 8, nMaskBytesPerRow, GetSalData()->mxGraySpace, kCGImageAlphaNone );
+ CGContextDrawImage( xMaskContext, xImageRect, xMask );
+ CFRelease( xMask );
+ CGDataProviderRef xDataProvider( CGDataProviderCreateWithData( NULL,
+ pMaskMem, nHeight * nMaskBytesPerRow, &CFRTLFree ) );
+ static const float* pDecode = NULL;
+ xMask = CGImageMaskCreate( nWidth, nHeight, 8, 8, nMaskBytesPerRow, xDataProvider, pDecode, false );
+ CFRelease( xDataProvider );
+ CFRelease( xMaskContext );
+ }
+
+ if( !xMask )
+ return xImage;
+
+ // combine image and alpha mask
+ CGImageRef xMaskedImage = CGImageCreateWithMask( xImage, xMask );
+ CFRelease( xMask );
+ CFRelease( xImage );
+ return xMaskedImage;
+}
+
+// ------------------------------------------------------------------
+
+/** creates an image from the given rectangle, replacing all black pixels with nMaskColor and make all other full transparent */
+CGImageRef IosSalBitmap::CreateColorMask( int nX, int nY, int nWidth, int nHeight, SalColor nMaskColor ) const
+{
+ CGImageRef xMask = 0;
+ if( maUserBuffer.get() && (nX + nWidth <= mnWidth) && (nY + nHeight <= mnHeight) )
+ {
+ const sal_uInt32 nDestBytesPerRow = nWidth << 2;
+ sal_uInt32* pMaskBuffer = static_cast<sal_uInt32*>( rtl_allocateMemory( nHeight * nDestBytesPerRow ) );
+ sal_uInt32* pDest = pMaskBuffer;
+
+ ImplPixelFormat* pSourcePixels = ImplPixelFormat::GetFormat( mnBits, maPalette );
+
+ if( pMaskBuffer && pSourcePixels )
+ {
+ sal_uInt32 nColor;
+ reinterpret_cast<sal_uInt8*>(&nColor)[0] = 0xff;
+ reinterpret_cast<sal_uInt8*>(&nColor)[1] = SALCOLOR_RED( nMaskColor );
+ reinterpret_cast<sal_uInt8*>(&nColor)[2] = SALCOLOR_GREEN( nMaskColor );
+ reinterpret_cast<sal_uInt8*>(&nColor)[3] = SALCOLOR_BLUE( nMaskColor );
+
+ sal_uInt8* pSource = maUserBuffer.get();
+ if( nY )
+ pSource += nY * mnBytesPerRow;
+
+ int y = nHeight;
+ while( y-- )
+ {
+ pSourcePixels->StartLine( pSource );
+ pSourcePixels->SkipPixel(nX);
+ sal_uInt32 x = nWidth;
+ while( x-- )
+ {
+ *pDest++ = ( pSourcePixels->ReadPixel() == 0 ) ? nColor : 0;
+ }
+ pSource += mnBytesPerRow;
+ }
+
+ CGDataProviderRef xDataProvider( CGDataProviderCreateWithData(NULL, pMaskBuffer, nHeight * nDestBytesPerRow, &CFRTLFree) );
+ xMask = CGImageCreate(nWidth, nHeight, 8, 32, nDestBytesPerRow, GetSalData()->mxRGBSpace, kCGImageAlphaPremultipliedFirst, xDataProvider, NULL, true, kCGRenderingIntentDefault);
+ CFRelease(xDataProvider);
+ }
+ else
+ {
+ free(pMaskBuffer);
+ }
+
+ delete pSourcePixels;
+ }
+ return xMask;
+}
+
+// =======================================================================
+
+/** IosSalBitmap::GetSystemData Get platform native image data from existing image
+ *
+ * @param rData struct BitmapSystemData, defined in vcl/inc/bitmap.hxx
+ * @return true if successful
+**/
+bool IosSalBitmap::GetSystemData( BitmapSystemData& rData )
+{
+ bool bRet = false;
+
+ if( !mxGraphicContext )
+ CreateContext();
+
+ if ( mxGraphicContext )
+ {
+ bRet = true;
+
+ if ((CGBitmapContextGetBitsPerPixel(mxGraphicContext) == 32) &&
+ (CGBitmapContextGetBitmapInfo(mxGraphicContext) & kCGBitmapByteOrderMask) != kCGBitmapByteOrder32Host) {
+ /**
+ * We need to hack things because VCL does not use kCGBitmapByteOrder32Host, while Cairo requires it.
+ */
+ OSL_TRACE("IosSalBitmap::%s(): kCGBitmapByteOrder32Host not found => inserting it.",__func__);
+
+ CGImageRef xImage = CGBitmapContextCreateImage (mxGraphicContext);
+
+ // re-create the context with single change: include kCGBitmapByteOrder32Host flag.
+ CGContextRef mxGraphicContextNew = CGBitmapContextCreate( CGBitmapContextGetData(mxGraphicContext),
+ CGBitmapContextGetWidth(mxGraphicContext),
+ CGBitmapContextGetHeight(mxGraphicContext),
+ CGBitmapContextGetBitsPerComponent(mxGraphicContext),
+ CGBitmapContextGetBytesPerRow(mxGraphicContext),
+ CGBitmapContextGetColorSpace(mxGraphicContext),
+ CGBitmapContextGetBitmapInfo(mxGraphicContext) | kCGBitmapByteOrder32Host);
+ CFRelease(mxGraphicContext);
+
+ // Needs to be flipped
+ CGContextSaveGState( mxGraphicContextNew );
+ CGContextTranslateCTM (mxGraphicContextNew, 0, CGBitmapContextGetHeight(mxGraphicContextNew));
+ CGContextScaleCTM (mxGraphicContextNew, 1.0, -1.0);
+
+ CGContextDrawImage(mxGraphicContextNew, CGRectMake( 0, 0, CGImageGetWidth(xImage), CGImageGetHeight(xImage)), xImage);
+
+ // Flip back
+ CGContextRestoreGState( mxGraphicContextNew );
+
+ CGImageRelease( xImage );
+ mxGraphicContext = mxGraphicContextNew;
+ }
+
+ rData.rImageContext = (void *) mxGraphicContext;
+ rData.mnWidth = mnWidth;
+ rData.mnHeight = mnHeight;
+ }
+
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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: */
diff --git a/vcl/ios/source/window/salmenu.cxx b/vcl/ios/source/window/salmenu.cxx
new file mode 100644
index 000000000000..0cda8229b1d4
--- /dev/null
+++ b/vcl/ios/source/window/salmenu.cxx
@@ -0,0 +1,72 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#include "rtl/ustrbuf.hxx"
+
+#include "vcl/cmdevt.hxx"
+#include "vcl/floatwin.hxx"
+#include "vcl/window.hxx"
+#include "vcl/svapp.hxx"
+
+#include "ios/saldata.hxx"
+#include "ios/salinst.h"
+#include "ios/salmenu.h"
+#include "ios/salframe.h"
+#include "ios/salbmp.h"
+
+#include "svids.hrc"
+#include "window.h"
+
+// =======================================================================
+
+SalMenu* IosSalInstance::CreateMenu( sal_Bool bMenuBar, Menu* pVCLMenu )
+{
+ // ???
+ return NULL;
+}
+
+void IosSalInstance::DestroyMenu( SalMenu* pSalMenu )
+{
+ delete pSalMenu;
+}
+
+SalMenuItem* IosSalInstance::CreateMenuItem( const SalItemParams* pItemData )
+{
+ // ???
+ return NULL;
+}
+
+void IosSalInstance::DestroyMenuItem( SalMenuItem* pSalMenuItem )
+{
+ delete pSalMenuItem;
+}
+
+
+// =======================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/ios/source/window/salobj.cxx b/vcl/ios/source/window/salobj.cxx
new file mode 100644
index 000000000000..e55b0874685d
--- /dev/null
+++ b/vcl/ios/source/window/salobj.cxx
@@ -0,0 +1,242 @@
+/* -*- 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.h>
+
+#include "ios/saldata.hxx"
+#include "ios/salobj.h"
+#include "ios/salframe.h"
+
+// =======================================================================
+
+IosSalObject::IosSalObject( IosSalFrame* pFrame ) :
+ mpFrame( pFrame ),
+ mnClipX( -1 ),
+ mnClipY( -1 ),
+ mnClipWidth( -1 ),
+ mnClipHeight( -1 ),
+ mbClip( false ),
+ mnX( 0 ),
+ mnY( 0 ),
+ mnWidth( 20 ),
+ mnHeight( 20 )
+{
+ maSysData.nSize = sizeof( maSysData );
+ maSysData.pView = NULL;
+
+ CGRect aInitFrame = { { 0, 0 }, { 20, 20 } };
+ maSysData.pView = [[UIView alloc] initWithFrame: aInitFrame];
+}
+
+// -----------------------------------------------------------------------
+
+IosSalObject::~IosSalObject()
+{
+ if( maSysData.pView )
+ {
+ UIView *pView = maSysData.pView;
+ [pView removeFromSuperview];
+ [pView release];
+ }
+#if 0 // ???
+ if( mpClipView )
+ {
+ [mpClipView removeFromSuperview];
+ [mpClipView release];
+ }
+#endif
+}
+
+/*
+ sadly there seems to be no way to impose clipping on a child view,
+ especially a QTMovieView which seems to ignore the current context
+ completely. Also there is no real way to shape a window; on Ios a
+ similar effect to non-rectangular windows is achieved by using a
+ non-opaque window and not painting where one wants the background
+ to shine through.
+
+ With respect to SalObject this leaves us to having an NSClipView
+ containing the child view. Even a QTMovieView respects the boundaries of
+ that, which gives us a clip "region" consisting of one rectangle.
+ This is gives us an 80% solution only, though.
+*/
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::ResetClipRegion()
+{
+ mbClip = false;
+ setClippedPosSize();
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 IosSalObject::GetClipRegionType()
+{
+ return SAL_OBJECT_CLIP_INCLUDERECTS;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::BeginSetClipRegion( sal_uLong )
+{
+ mbClip = false;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ if( mbClip )
+ {
+ if( nX < mnClipX )
+ {
+ mnClipWidth += mnClipX - nX;
+ mnClipX = nX;
+ }
+ if( nX + nWidth > mnClipX + mnClipWidth )
+ mnClipWidth = nX + nWidth - mnClipX;
+ if( nY < mnClipY )
+ {
+ mnClipHeight += mnClipY - nY;
+ mnClipY = nY;
+ }
+ if( nY + nHeight > mnClipY + mnClipHeight )
+ mnClipHeight = nY + nHeight - mnClipY;
+ }
+ else
+ {
+ mnClipX = nX;
+ mnClipY = nY;
+ mnClipWidth = nWidth;
+ mnClipHeight = nHeight;
+ mbClip = true;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::EndSetClipRegion()
+{
+ setClippedPosSize();
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
+{
+ mnX = nX;
+ mnY = nY;
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+ setClippedPosSize();
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::setClippedPosSize()
+{
+ CGRect aViewRect = { { 0, 0 }, { mnWidth, mnHeight } };
+ if( maSysData.pView )
+ {
+ UIView *pView = maSysData.pView;
+ [pView setFrame: aViewRect];
+ }
+
+ CGRect aClipViewRect = { { mnX, mnY }, { mnWidth, mnHeight } };
+ CGPoint aClipPt = { 0, 0 };
+ if( mbClip )
+ {
+ aClipViewRect.origin.x += mnClipX;
+ aClipViewRect.origin.y += mnClipY;
+ aClipViewRect.size.width = mnClipWidth;
+ aClipViewRect.size.height = mnClipHeight;
+ aClipPt.x = mnClipX;
+ if( mnClipY == 0 )
+ aClipPt.y = mnHeight - mnClipHeight;;
+ }
+
+ mpFrame->VCLToCocoaTouch( aClipViewRect, false );
+#if 0 // ???
+ [mpClipView setFrame: aClipViewRect];
+
+ [mpClipView scrollToPoint: aClipPt];
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::Show( sal_Bool bVisible )
+{
+#if 0 // ???
+ if( mpClipView )
+ [mpClipView setHidden: (bVisible ? NO : YES)];
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::Enable( sal_Bool )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::GrabFocus()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::SetBackground()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::SetBackground( SalColor )
+{
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* IosSalObject::GetSystemData() const
+{
+ return &maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ )
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */