[Libreoffice-commits] .: vcl/inc vcl/ios vcl/Library_vcl.mk

Tor Lillqvist tml at kemper.freedesktop.org
Sat Jul 30 15:55:34 PDT 2011


 vcl/Library_vcl.mk                        |    7 
 vcl/inc/ios/salbmp.h                      |    1 
 vcl/inc/ios/salframe.h                    |   11 
 vcl/inc/ios/salmenu.h                     |   69 -
 vcl/ios/source/app/salinst.cxx            |   79 ++
 vcl/ios/source/app/vcluiapp.mm            |    4 
 vcl/ios/source/dtrans/iOSTransferable.cxx |  193 +++++
 vcl/ios/source/dtrans/iOSTransferable.hxx |   95 ++
 vcl/ios/source/dtrans/ios_clipboard.cxx   |  397 ++++++++++
 vcl/ios/source/dtrans/ios_clipboard.hxx   |  182 ++++
 vcl/ios/source/dtrans/service_entry.cxx   |   73 +
 vcl/ios/source/gdi/salbmp.cxx             |  915 +++++++++++++++++++++++
 vcl/ios/source/window/salframe.cxx        | 1151 ++++++++++++++++++++++++++++++
 vcl/ios/source/window/salmenu.cxx         |   72 +
 vcl/ios/source/window/salobj.cxx          |  242 ++++++
 15 files changed, 3420 insertions(+), 71 deletions(-)

New commits:
commit 8badced9e0ff5cc8c8d94cfab106b842f8e24126
Author: Tor Lillqvist <tml at iki.fi>
Date:   Sun Jul 31 01:52:37 2011 +0300

    More iOS hacking, intermediate commit, certainly not working

diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index e10dda0..625a51b 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 2e6684c..50b5405 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 04aef84..24b69ca 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 3f143ac..8a07d94 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 2f55aa8..2d4e13c 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 e40d8a7..d1aa842 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 0000000..68e534e
--- /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 0000000..8744ef1
--- /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 0000000..69f9473
--- /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;
+
+ at 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;
+}
+
+ at 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 0000000..3bd3a89
--- /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;
+
+ at 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;
+ at 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 0000000..c919dd1
--- /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 0000000..212fa0e
--- /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 0000000..3bb987e
--- /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;
+    }
+

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list