LCOV - code coverage report
Current view: top level - desktop/source/lib - init.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 168 401 41.9 %
Date: 2015-06-13 12:38:46 Functions: 20 42 47.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <config_folders.h>
      11             : 
      12             : #include <stdio.h>
      13             : #include <string.h>
      14             : #include <stdlib.h>
      15             : 
      16             : #include <boost/shared_ptr.hpp>
      17             : #include <boost/weak_ptr.hpp>
      18             : #include <boost/property_tree/json_parser.hpp>
      19             : 
      20             : #define LOK_USE_UNSTABLE_API
      21             : #include <LibreOfficeKit/LibreOfficeKit.h>
      22             : #include <LibreOfficeKit/LibreOfficeKitEnums.h>
      23             : 
      24             : #include <sal/log.hxx>
      25             : #include <tools/errinf.hxx>
      26             : #include <osl/file.hxx>
      27             : #include <osl/process.h>
      28             : #include <osl/thread.h>
      29             : #include <rtl/strbuf.hxx>
      30             : #include <rtl/bootstrap.hxx>
      31             : #include <cppuhelper/bootstrap.hxx>
      32             : #include <comphelper/dispatchcommand.hxx>
      33             : #include <comphelper/lok.hxx>
      34             : #include <comphelper/processfactory.hxx>
      35             : 
      36             : #include <com/sun/star/beans/XPropertySet.hpp>
      37             : #include <com/sun/star/frame/Desktop.hpp>
      38             : #include <com/sun/star/frame/XStorable.hpp>
      39             : #include <com/sun/star/lang/Locale.hpp>
      40             : #include <com/sun/star/lang/XComponent.hpp>
      41             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      42             : #include <com/sun/star/ucb/XContentProvider.hpp>
      43             : #include <com/sun/star/ucb/XUniversalContentBroker.hpp>
      44             : 
      45             : #include <vcl/svapp.hxx>
      46             : #include <vcl/svpforlokit.hxx>
      47             : #include <tools/resmgr.hxx>
      48             : #include <tools/fract.hxx>
      49             : #include <vcl/graphicfilter.hxx>
      50             : #include <vcl/sysdata.hxx>
      51             : #include <vcl/virdev.hxx>
      52             : #include <vcl/ITiledRenderable.hxx>
      53             : #include <unotools/syslocaleoptions.hxx>
      54             : #include <unotools/mediadescriptor.hxx>
      55             : #include <osl/module.hxx>
      56             : #include <comphelper/sequence.hxx>
      57             : 
      58             : #include <app.hxx>
      59             : 
      60             : #include "../app/cmdlineargs.hxx"
      61             : // We also need to hackily be able to start the main libreoffice thread:
      62             : #include "../app/sofficemain.h"
      63             : #include "../app/officeipcthread.hxx"
      64             : 
      65             : using namespace css;
      66             : using namespace vcl;
      67             : using namespace desktop;
      68             : using namespace utl;
      69             : 
      70             : using namespace boost;
      71             : 
      72             : struct LibLODocument_Impl;
      73             : struct LibLibreOffice_Impl;
      74             : 
      75             : static LibLibreOffice_Impl *gImpl = NULL;
      76         116 : static weak_ptr< LibreOfficeKitClass > gOfficeClass;
      77         116 : static weak_ptr< LibreOfficeKitDocumentClass > gDocumentClass;
      78             : 
      79             : typedef struct
      80             : {
      81             :     const char *extn;
      82             :     const char *filterName;
      83             : } ExtensionMap;
      84             : 
      85             : // We need a shared_array for passing into the BitmapDevice (via
      86             : // VirtualDevice.SetOutputSizePixelScaleOffsetAndBuffer which goes via the
      87             : // SvpVirtualDevice, ending up in the basebmp BitmapDevice. However as we're
      88             : // given the array externally we can't delete it, and hence need to override
      89             : // shared_array's default of deleting its pointer.
      90             : template<typename T>
      91             : struct NoDelete
      92             : {
      93           0 :    void operator()(T* /* p */) {}
      94             : };
      95             : 
      96             : static const ExtensionMap aWriterExtensionMap[] =
      97             : {
      98             :     { "doc",   "MS Word 97" },
      99             :     { "docx",  "MS Word 2007 XML" },
     100             :     { "fodt",  "OpenDocument Text Flat XML" },
     101             :     { "html",  "HTML (StarWriter)" },
     102             :     { "odt",   "writer8" },
     103             :     { "ott",   "writer8_template" },
     104             :     { "pdf",   "writer_pdf_Export" },
     105             :     { "txt",   "Text" },
     106             :     { "xhtml", "XHTML Writer File" },
     107             :     { NULL, NULL }
     108             : };
     109             : 
     110             : static const ExtensionMap aCalcExtensionMap[] =
     111             : {
     112             :     { "csv",   "Text - txt - csv (StarCalc)" },
     113             :     { "fods",  "OpenDocument Spreadsheet Flat XML" },
     114             :     { "html",  "HTML (StarCalc)" },
     115             :     { "ods",   "calc8" },
     116             :     { "ots",   "calc8_template" },
     117             :     { "pdf",   "calc_pdf_Export" },
     118             :     { "xhtml", "XHTML Calc File" },
     119             :     { "xls",   "MS Excel 97" },
     120             :     { "xlsx",  "Calc MS Excel 2007 XML" },
     121             :     { NULL, NULL }
     122             : };
     123             : 
     124             : static const ExtensionMap aImpressExtensionMap[] =
     125             : {
     126             :     { "fodp",  "OpenDocument Presentation Flat XML" },
     127             :     { "html",  "impress_html_Export" },
     128             :     { "odg",   "impress8_draw" },
     129             :     { "odp",   "impress8" },
     130             :     { "otp",   "impress8_template" },
     131             :     { "pdf",   "impress_pdf_Export" },
     132             :     { "potm",  "Impress MS PowerPoint 2007 XML Template" },
     133             :     { "pot",   "MS PowerPoint 97 Vorlage" },
     134             :     { "pptx",  "Impress MS PowerPoint 2007 XML" },
     135             :     { "pps",   "MS PowerPoint 97 Autoplay" },
     136             :     { "ppt",   "MS PowerPoint 97" },
     137             :     { "svg",   "impress_svg_Export" },
     138             :     { "swf",   "impress_flash_Export" },
     139             :     { "xhtml", "XHTML Impress File" },
     140             :     { NULL, NULL }
     141             : };
     142             : 
     143             : static const ExtensionMap aDrawExtensionMap[] =
     144             : {
     145             :     { "fodg",  "draw_ODG_FlatXML" },
     146             :     { "html",  "draw_html_Export" },
     147             :     { "odg",   "draw8" },
     148             :     { "pdf",   "draw_pdf_Export" },
     149             :     { "svg",   "draw_svg_Export" },
     150             :     { "swf",   "draw_flash_Export" },
     151             :     { "xhtml", "XHTML Draw File" },
     152             :     { NULL, NULL }
     153             : };
     154             : 
     155           3 : static OUString getUString(const char* pString)
     156             : {
     157           3 :     if (pString == NULL)
     158           0 :         return OUString();
     159             : 
     160           3 :     OString sString(pString, strlen(pString));
     161           3 :     return OStringToOUString(sString, RTL_TEXTENCODING_UTF8);
     162             : }
     163             : 
     164             : // Try to convert a relative URL to an absolute one
     165           3 : static OUString getAbsoluteURL(const char* pURL)
     166             : {
     167           3 :     OUString aURL( getUString( pURL ) );
     168           6 :     OUString sAbsoluteDocUrl, sWorkingDir, sDocPathUrl;
     169             : 
     170             :     // FIXME: this would appear to kill non-file URLs.
     171           3 :     osl_getProcessWorkingDir(&sWorkingDir.pData);
     172           3 :     osl::FileBase::getFileURLFromSystemPath( aURL, sDocPathUrl );
     173           3 :     osl::FileBase::getAbsoluteFileURL(sWorkingDir, sDocPathUrl, sAbsoluteDocUrl);
     174             : 
     175           6 :     return sAbsoluteDocUrl;
     176             : }
     177             : 
     178             : extern "C"
     179             : {
     180             : 
     181             : static void doc_destroy(LibreOfficeKitDocument* pThis);
     182             : static int  doc_saveAs(LibreOfficeKitDocument* pThis, const char* pUrl, const char* pFormat, const char* pFilterOptions);
     183             : static int doc_getDocumentType(LibreOfficeKitDocument* pThis);
     184             : static int doc_getParts(LibreOfficeKitDocument* pThis);
     185             : static int doc_getPart(LibreOfficeKitDocument* pThis);
     186             : static void doc_setPart(LibreOfficeKitDocument* pThis, int nPart);
     187             : static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart);
     188             : static void doc_setPartMode(LibreOfficeKitDocument* pThis, int nPartMode);
     189             : void        doc_paintTile(LibreOfficeKitDocument* pThis,
     190             :                           unsigned char* pBuffer,
     191             :                           const int nCanvasWidth, const int nCanvasHeight,
     192             :                           const int nTilePosX, const int nTilePosY,
     193             :                           const int nTileWidth, const int nTileHeight);
     194             : static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
     195             :                                 long* pWidth,
     196             :                                 long* pHeight);
     197             : static void doc_initializeForRendering(LibreOfficeKitDocument* pThis);
     198             : 
     199             : static void doc_registerCallback(LibreOfficeKitDocument* pThis,
     200             :                                 LibreOfficeKitCallback pCallback,
     201             :                                 void* pData);
     202             : static void doc_postKeyEvent(LibreOfficeKitDocument* pThis,
     203             :                              int nType,
     204             :                              int nCharCode,
     205             :                              int nKeyCode);
     206             : static void doc_postMouseEvent (LibreOfficeKitDocument* pThis,
     207             :                                 int nType,
     208             :                                 int nX,
     209             :                                 int nY,
     210             :                                 int nCount);
     211             : static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
     212             :                                const char* pCommand,
     213             :                                const char* pArguments);
     214             : static void doc_setTextSelection (LibreOfficeKitDocument* pThis,
     215             :                                   int nType,
     216             :                                   int nX,
     217             :                                   int nY);
     218             : static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis,
     219             :                                   int nType,
     220             :                                   int nX,
     221             :                                   int nY);
     222             : static void doc_resetSelection (LibreOfficeKitDocument* pThis);
     223             : 
     224             : struct LibLODocument_Impl : public _LibreOfficeKitDocument
     225             : {
     226             :     uno::Reference<css::lang::XComponent> mxComponent;
     227             :     shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass;
     228             : 
     229           2 :     LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent) :
     230           2 :         mxComponent( xComponent )
     231             :     {
     232           2 :         if (!(m_pDocumentClass = gDocumentClass.lock()))
     233             :         {
     234           1 :             m_pDocumentClass.reset(new LibreOfficeKitDocumentClass);
     235             : 
     236           1 :             m_pDocumentClass->nSize = sizeof(LibreOfficeKitDocument);
     237             : 
     238           1 :             m_pDocumentClass->destroy = doc_destroy;
     239           1 :             m_pDocumentClass->saveAs = doc_saveAs;
     240           1 :             m_pDocumentClass->getDocumentType = doc_getDocumentType;
     241           1 :             m_pDocumentClass->getParts = doc_getParts;
     242           1 :             m_pDocumentClass->getPart = doc_getPart;
     243           1 :             m_pDocumentClass->setPart = doc_setPart;
     244           1 :             m_pDocumentClass->getPartName = doc_getPartName;
     245           1 :             m_pDocumentClass->setPartMode = doc_setPartMode;
     246           1 :             m_pDocumentClass->paintTile = doc_paintTile;
     247           1 :             m_pDocumentClass->getDocumentSize = doc_getDocumentSize;
     248           1 :             m_pDocumentClass->initializeForRendering = doc_initializeForRendering;
     249           1 :             m_pDocumentClass->registerCallback = doc_registerCallback;
     250           1 :             m_pDocumentClass->postKeyEvent = doc_postKeyEvent;
     251           1 :             m_pDocumentClass->postMouseEvent = doc_postMouseEvent;
     252           1 :             m_pDocumentClass->postUnoCommand = doc_postUnoCommand;
     253           1 :             m_pDocumentClass->setTextSelection = doc_setTextSelection;
     254           1 :             m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection;
     255           1 :             m_pDocumentClass->resetSelection = doc_resetSelection;
     256             : 
     257           1 :             gDocumentClass = m_pDocumentClass;
     258             :         }
     259           2 :         pClass = m_pDocumentClass.get();
     260           2 :     }
     261             : 
     262           2 :     ~LibLODocument_Impl()
     263           2 :     {
     264           2 :         mxComponent->dispose();
     265           2 :     }
     266             : };
     267             : 
     268           2 : static void doc_destroy(LibreOfficeKitDocument *pThis)
     269             : {
     270           2 :     LibLODocument_Impl *pDocument = static_cast<LibLODocument_Impl*>(pThis);
     271           2 :     delete pDocument;
     272           2 : }
     273             : 
     274             : static void                    lo_destroy       (LibreOfficeKit* pThis);
     275             : static int                     lo_initialize    (LibreOfficeKit* pThis, const char* pInstallPath, const char* pUserProfilePath);
     276             : static LibreOfficeKitDocument* lo_documentLoad  (LibreOfficeKit* pThis, const char* pURL);
     277             : static char *                  lo_getError      (LibreOfficeKit* pThis);
     278             : static LibreOfficeKitDocument* lo_documentLoadWithOptions  (LibreOfficeKit* pThis,
     279             :                                                            const char* pURL,
     280             :                                                            const char* pOptions);
     281             : static void                    lo_registerCallback (LibreOfficeKit* pThis,
     282             :                                                     LibreOfficeKitCallback pCallback,
     283             :                                                     void* pData);
     284             : 
     285           1 : struct LibLibreOffice_Impl : public _LibreOfficeKit
     286             : {
     287             :     OUString maLastExceptionMsg;
     288             :     shared_ptr< LibreOfficeKitClass > m_pOfficeClass;
     289             :     oslThread maThread;
     290             :     LibreOfficeKitCallback mpCallback;
     291             :     void *mpCallbackData;
     292             : 
     293           1 :     LibLibreOffice_Impl()
     294             :         : maThread(0)
     295             :         , mpCallback(nullptr)
     296           1 :         , mpCallbackData(nullptr)
     297             :     {
     298           1 :         if(!(m_pOfficeClass = gOfficeClass.lock())) {
     299           1 :             m_pOfficeClass.reset(new LibreOfficeKitClass);
     300           1 :             m_pOfficeClass->nSize = sizeof(LibreOfficeKitClass);
     301             : 
     302           1 :             m_pOfficeClass->destroy = lo_destroy;
     303           1 :             m_pOfficeClass->documentLoad = lo_documentLoad;
     304           1 :             m_pOfficeClass->getError = lo_getError;
     305           1 :             m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions;
     306           1 :             m_pOfficeClass->registerCallback = lo_registerCallback;
     307             : 
     308           1 :             gOfficeClass = m_pOfficeClass;
     309             :         }
     310             : 
     311           1 :         pClass = m_pOfficeClass.get();
     312           1 :     }
     313             : };
     314             : 
     315             : namespace
     316             : {
     317             : 
     318           0 : ITiledRenderable* getTiledRenderable(LibreOfficeKitDocument* pThis)
     319             : {
     320           0 :     LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
     321           0 :     return dynamic_cast<ITiledRenderable*>(pDocument->mxComponent.get());
     322             : }
     323             : 
     324             : } // anonymous namespace
     325             : 
     326             : // Wonder global state ...
     327         116 : static uno::Reference<css::uno::XComponentContext> xContext;
     328         116 : static uno::Reference<css::lang::XMultiServiceFactory> xSFactory;
     329         116 : static uno::Reference<css::lang::XMultiComponentFactory> xFactory;
     330             : 
     331           0 : static LibreOfficeKitDocument* lo_documentLoad(LibreOfficeKit* pThis, const char* pURL)
     332             : {
     333           0 :     return lo_documentLoadWithOptions(pThis, pURL, NULL);
     334             : }
     335             : 
     336           3 : static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, const char* pURL, const char* pOptions)
     337             : {
     338           3 :     LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
     339             : 
     340           3 :     SolarMutexGuard aGuard;
     341             : 
     342           6 :     OUString aURL = getAbsoluteURL(pURL);
     343             : 
     344           3 :     pLib->maLastExceptionMsg.clear();
     345             : 
     346           3 :     if (!xContext.is())
     347             :     {
     348           0 :         pLib->maLastExceptionMsg = "ComponentContext is not available";
     349             :         SAL_INFO("lok", "ComponentContext is not available");
     350           0 :         return NULL;
     351             :     }
     352             : 
     353           6 :     uno::Reference<frame::XDesktop2> xComponentLoader = frame::Desktop::create(xContext);
     354             : 
     355           3 :     if (!xComponentLoader.is())
     356             :     {
     357           0 :         pLib->maLastExceptionMsg = "ComponentLoader is not available";
     358             :         SAL_INFO("lok", "ComponentLoader is not available");
     359           0 :         return NULL;
     360             :     }
     361             : 
     362             :     try
     363             :     {
     364           3 :         uno::Sequence<css::beans::PropertyValue> aFilterOptions(1);
     365           6 :         aFilterOptions[0] = css::beans::PropertyValue( OUString("FilterOptions"),
     366             :                                                        0,
     367             :                                                        uno::makeAny(OUString::createFromAscii(pOptions)),
     368           3 :                                                        beans::PropertyState_DIRECT_VALUE);
     369           6 :         uno::Reference<lang::XComponent> xComponent;
     370           8 :         xComponent = xComponentLoader->loadComponentFromURL(
     371             :                                             aURL, OUString("_blank"), 0,
     372           5 :                                             aFilterOptions);
     373             : 
     374           2 :         if (!xComponent.is())
     375             :         {
     376           0 :             pLib->maLastExceptionMsg = "loadComponentFromURL returned an empty reference";
     377             :             SAL_INFO("lok", "Document can't be loaded - " << pLib->maLastExceptionMsg);
     378           0 :             return NULL;
     379             :         }
     380             : 
     381           5 :         return new LibLODocument_Impl(xComponent);
     382             : 
     383             :     }
     384           2 :     catch (const uno::Exception& exception)
     385             :     {
     386           1 :         pLib->maLastExceptionMsg = exception.Message;
     387             :         SAL_INFO("lok", "Document can't be loaded - exception: " << exception.Message);
     388             :     }
     389             : 
     390           4 :     return NULL;
     391             : }
     392             : 
     393           0 : static void lo_registerCallback (LibreOfficeKit* pThis,
     394             :                                  LibreOfficeKitCallback pCallback,
     395             :                                  void* pData)
     396             : {
     397           0 :     LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
     398             : 
     399           0 :     pLib->mpCallback = pCallback;
     400           0 :     pLib->mpCallbackData = pData;
     401           0 : }
     402             : 
     403           0 : static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const char* pFormat, const char* pFilterOptions)
     404             : {
     405           0 :     LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
     406             : 
     407           0 :     OUString sFormat = getUString(pFormat);
     408           0 :     OUString aURL = getAbsoluteURL(sUrl);
     409             : 
     410             :     try
     411             :     {
     412             :         const ExtensionMap* pMap;
     413             : 
     414           0 :         switch (doc_getDocumentType(pThis))
     415             :         {
     416             :         case LOK_DOCTYPE_SPREADSHEET:
     417           0 :             pMap = aCalcExtensionMap;
     418           0 :             break;
     419             :         case LOK_DOCTYPE_PRESENTATION:
     420           0 :             pMap = aImpressExtensionMap;
     421           0 :             break;
     422             :         case LOK_DOCTYPE_DRAWING:
     423           0 :             pMap = aDrawExtensionMap;
     424           0 :             break;
     425             :         case LOK_DOCTYPE_TEXT:
     426           0 :             pMap = aWriterExtensionMap;
     427           0 :             break;
     428             :         case LOK_DOCTYPE_OTHER:
     429             :         default:
     430           0 :             return false;
     431             :         }
     432             : 
     433           0 :         if (pFormat == NULL)
     434             :         {
     435             :             // sniff from the extension
     436           0 :             sal_Int32 idx = aURL.lastIndexOf(".");
     437           0 :             if( idx > 0 )
     438             :             {
     439           0 :                 sFormat = aURL.copy( idx + 1 );
     440             :             }
     441             :             else
     442             :             {
     443           0 :                 gImpl->maLastExceptionMsg = "input filename without a suffix";
     444           0 :                 return false;
     445             :             }
     446             :         }
     447             : 
     448           0 :         OUString aFilterName;
     449           0 :         for (sal_Int32 i = 0; pMap[i].extn; ++i)
     450             :         {
     451           0 :             if (sFormat.equalsIgnoreAsciiCaseAscii(pMap[i].extn))
     452             :             {
     453           0 :                 aFilterName = getUString(pMap[i].filterName);
     454           0 :                 break;
     455             :             }
     456             :         }
     457           0 :         if (aFilterName.isEmpty())
     458             :         {
     459           0 :             gImpl->maLastExceptionMsg = "no output filter found for provided suffix";
     460           0 :             return false;
     461             :         }
     462             : 
     463           0 :         OUString aFilterOptions = getUString(pFilterOptions);
     464             : 
     465           0 :         MediaDescriptor aSaveMediaDescriptor;
     466           0 :         aSaveMediaDescriptor["Overwrite"] <<= sal_True;
     467           0 :         aSaveMediaDescriptor["FilterName"] <<= aFilterName;
     468           0 :         aSaveMediaDescriptor[MediaDescriptor::PROP_FILTEROPTIONS()] <<= aFilterOptions;
     469             : 
     470           0 :         uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
     471           0 :         xStorable->storeToURL(aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
     472             : 
     473           0 :         return true;
     474             :     }
     475           0 :     catch (const uno::Exception& exception)
     476             :     {
     477           0 :         gImpl->maLastExceptionMsg = "exception: " + exception.Message;
     478             :     }
     479           0 :     return false;
     480             : }
     481             : 
     482           2 : static int doc_getDocumentType (LibreOfficeKitDocument* pThis)
     483             : {
     484           2 :     LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
     485             : 
     486             :     try
     487             :     {
     488           2 :         uno::Reference<lang::XServiceInfo> xDocument(pDocument->mxComponent, uno::UNO_QUERY_THROW);
     489             : 
     490           2 :         if (xDocument->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
     491             :         {
     492           0 :             return LOK_DOCTYPE_SPREADSHEET;
     493             :         }
     494           2 :         else if (xDocument->supportsService("com.sun.star.presentation.PresentationDocument"))
     495             :         {
     496           1 :             return LOK_DOCTYPE_PRESENTATION;
     497             :         }
     498           1 :         else if (xDocument->supportsService("com.sun.star.drawing.DrawingDocument"))
     499             :         {
     500           0 :             return LOK_DOCTYPE_DRAWING;
     501             :         }
     502           1 :         else if (xDocument->supportsService("com.sun.star.text.TextDocument"))
     503             :         {
     504           1 :             return LOK_DOCTYPE_TEXT;
     505             :         }
     506             :         else
     507             :         {
     508           0 :             gImpl->maLastExceptionMsg = "unknown document type";
     509           0 :         }
     510             :     }
     511           0 :     catch (const uno::Exception& exception)
     512             :     {
     513           0 :         gImpl->maLastExceptionMsg = "exception: " + exception.Message;
     514             :     }
     515           0 :     return LOK_DOCTYPE_OTHER;
     516             : }
     517             : 
     518           0 : static int doc_getParts (LibreOfficeKitDocument* pThis)
     519             : {
     520           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     521           0 :     if (!pDoc)
     522             :     {
     523           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     524           0 :         return 0;
     525             :     }
     526             : 
     527           0 :     return pDoc->getParts();
     528             : }
     529             : 
     530           0 : static int doc_getPart (LibreOfficeKitDocument* pThis)
     531             : {
     532           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     533           0 :     if (!pDoc)
     534             :     {
     535           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     536           0 :         return 0;
     537             :     }
     538             : 
     539           0 :     return pDoc->getPart();
     540             : }
     541             : 
     542           0 : static void doc_setPart(LibreOfficeKitDocument* pThis, int nPart)
     543             : {
     544           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     545           0 :     if (!pDoc)
     546             :     {
     547           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     548           0 :         return;
     549             :     }
     550             : 
     551           0 :     SolarMutexGuard aGuard;
     552           0 :     pDoc->setPart( nPart );
     553             : }
     554             : 
     555           0 : static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart)
     556             : {
     557           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     558           0 :     if (!pDoc)
     559             :     {
     560           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     561           0 :         return 0;
     562             :     }
     563             : 
     564           0 :     OUString sName = pDoc->getPartName( nPart );
     565           0 :     OString aString = OUStringToOString(sName, RTL_TEXTENCODING_UTF8);
     566           0 :     char* pMemory = static_cast<char*>(malloc(aString.getLength() + 1));
     567           0 :     strcpy(pMemory, aString.getStr());
     568           0 :     return pMemory;
     569             : 
     570             : }
     571             : 
     572           0 : static void doc_setPartMode(LibreOfficeKitDocument* pThis,
     573             :                             int nPartMode)
     574             : {
     575           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     576           0 :     if (!pDoc)
     577             :     {
     578           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     579           0 :         return;
     580             :     }
     581             : 
     582           0 :     SolarMutexGuard aGuard;
     583             : 
     584           0 :     int nCurrentPart = pDoc->getPart();
     585             : 
     586           0 :     pDoc->setPartMode(nPartMode);
     587             : 
     588             :     // We need to make sure the internal state is updated, just changing the mode
     589             :     // might not update the relevant shells (i.e. impress will keep rendering the
     590             :     // previous mode unless we do this).
     591             :     // TODO: we might want to do this within the relevant components rather than
     592             :     // here, but that's also dependent on how we implement embedded object
     593             :     // rendering I guess?
     594             :     // TODO: we could be clever and e.g. set to 0 when we change to/from
     595             :     // embedded object mode, and not when changing between slide/notes/combined
     596             :     // modes?
     597           0 :     if ( nCurrentPart < pDoc->getParts() )
     598             :     {
     599           0 :         pDoc->setPart( nCurrentPart );
     600             :     }
     601             :     else
     602             :     {
     603           0 :         pDoc->setPart( 0 );
     604           0 :     }
     605             : }
     606             : 
     607           0 : void doc_paintTile (LibreOfficeKitDocument* pThis,
     608             :                     unsigned char* pBuffer,
     609             :                     const int nCanvasWidth, const int nCanvasHeight,
     610             :                     const int nTilePosX, const int nTilePosY,
     611             :                     const int nTileWidth, const int nTileHeight)
     612             : {
     613             :     SAL_INFO( "lok.tiledrendering", "paintTile: painting [" << nTileWidth << "x" << nTileHeight <<
     614             :               "]@(" << nTilePosX << ", " << nTilePosY << ") to [" <<
     615             :               nCanvasWidth << "x" << nCanvasHeight << "]px" );
     616             : 
     617           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     618           0 :     if (!pDoc)
     619             :     {
     620           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     621           0 :         return;
     622             :     }
     623             : 
     624           0 :     SolarMutexGuard aGuard;
     625             : 
     626             : #if defined(UNX) && !defined(MACOSX) && !defined(ENABLE_HEADLESS)
     627             : 
     628             : #ifndef IOS
     629           0 :     InitSvpForLibreOfficeKit();
     630             : 
     631           0 :     ScopedVclPtrInstance< VirtualDevice > pDevice(nullptr, Size(1, 1), (sal_uInt16)32) ;
     632           0 :     boost::shared_array< sal_uInt8 > aBuffer( pBuffer, NoDelete< sal_uInt8 >() );
     633             :     pDevice->SetOutputSizePixelScaleOffsetAndBuffer(
     634             :                 Size(nCanvasWidth, nCanvasHeight), Fraction(1.0), Point(),
     635           0 :                 aBuffer, true );
     636             : 
     637           0 :     pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight,
     638           0 :                     nTilePosX, nTilePosY, nTileWidth, nTileHeight);
     639             : #else
     640             :     SystemGraphicsData aData;
     641             :     aData.rCGContext = reinterpret_cast<CGContextRef>(pBuffer);
     642             :     // the Size argument is irrelevant, I hope
     643             :     ScopedVclPtrInstance<VirtualDevice> pDevice(&aData, Size(1, 1), (sal_uInt16)0);
     644             : 
     645             :     pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight,
     646             :                     nTilePosX, nTilePosY, nTileWidth, nTileHeight);
     647             : #endif
     648             : 
     649           0 :     static bool bDebug = getenv("LOK_DEBUG") != 0;
     650           0 :     if (bDebug)
     651             :     {
     652             :         // Draw a small red rectangle in the top left corner so that it's easy to see where a new tile begins.
     653           0 :         Rectangle aRect(0, 0, 5, 5);
     654           0 :         aRect = pDevice->PixelToLogic(aRect);
     655           0 :         pDevice->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
     656           0 :         pDevice->SetFillColor(COL_LIGHTRED);
     657           0 :         pDevice->SetLineColor();
     658           0 :         pDevice->DrawRect(aRect);
     659           0 :         pDevice->Pop();
     660           0 :     }
     661             : 
     662             : #else
     663             :     (void) pBuffer;
     664             :     (void) nCanvasWidth;
     665             :     (void) nCanvasHeight;
     666             :     (void) nTilePosX;
     667             :     (void) nTilePosY;
     668             :     (void) nTileWidth;
     669             :     (void) nTileHeight;
     670             : #endif
     671             : }
     672             : 
     673           0 : static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
     674             :                                 long* pWidth,
     675             :                                 long* pHeight)
     676             : {
     677           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     678           0 :     if (pDoc)
     679             :     {
     680           0 :         Size aDocumentSize = pDoc->getDocumentSize();
     681           0 :         *pWidth = aDocumentSize.Width();
     682           0 :         *pHeight = aDocumentSize.Height();
     683             :     }
     684             :     else
     685             :     {
     686           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     687             :     }
     688           0 : }
     689             : 
     690           0 : static void doc_initializeForRendering(LibreOfficeKitDocument* pThis)
     691             : {
     692           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     693           0 :     if (pDoc)
     694             :     {
     695           0 :         pDoc->initializeForTiledRendering();
     696             :     }
     697           0 : }
     698             : 
     699           0 : static void doc_registerCallback(LibreOfficeKitDocument* pThis,
     700             :                                 LibreOfficeKitCallback pCallback,
     701             :                                 void* pData)
     702             : {
     703           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     704           0 :     if (!pDoc)
     705             :     {
     706           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     707           0 :         return;
     708             :     }
     709             : 
     710           0 :     pDoc->registerCallback(pCallback, pData);
     711             : }
     712             : 
     713           0 : static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nCharCode, int nKeyCode)
     714             : {
     715           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     716           0 :     if (!pDoc)
     717             :     {
     718           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     719           0 :         return;
     720             :     }
     721             : 
     722           0 :     pDoc->postKeyEvent(nType, nCharCode, nKeyCode);
     723             : }
     724             : 
     725           1 : static void jsonToPropertyValues(const char* pJSON, uno::Sequence<beans::PropertyValue>& rPropertyValues)
     726             : {
     727           1 :     std::vector<beans::PropertyValue> aArguments;
     728           1 :     if (pJSON)
     729             :     {
     730           0 :         boost::property_tree::ptree aTree;
     731           0 :         std::stringstream aStream(pJSON);
     732           0 :         boost::property_tree::read_json(aStream, aTree);
     733             : 
     734           0 :         for (const std::pair<std::string, boost::property_tree::ptree>& rPair : aTree)
     735             :         {
     736           0 :             const std::string& rType = rPair.second.get<std::string>("type");
     737           0 :             const std::string& rValue = rPair.second.get<std::string>("value");
     738             : 
     739           0 :             beans::PropertyValue aValue;
     740           0 :             aValue.Name = OUString::fromUtf8(rPair.first.c_str());
     741           0 :             if (rType == "string")
     742           0 :                 aValue.Value <<= OUString::fromUtf8(rValue.c_str());
     743           0 :             else if (rType == "boolean")
     744           0 :                 aValue.Value <<= OString(rValue.c_str()).toBoolean();
     745           0 :             else if (rType == "long")
     746           0 :                 aValue.Value <<= OString(rValue.c_str()).toInt32();
     747             :             else
     748             :                 SAL_WARN("desktop.lib", "jsonToPropertyValues: unhandled type '"<<rType<<"'");
     749           0 :             aArguments.push_back(aValue);
     750           0 :         }
     751             :     }
     752           1 :     rPropertyValues = comphelper::containerToSequence(aArguments);
     753           1 : }
     754             : 
     755           1 : static void doc_postUnoCommand(LibreOfficeKitDocument* /*pThis*/, const char* pCommand, const char* pArguments)
     756             : {
     757           1 :     OUString aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
     758             : 
     759           2 :     uno::Sequence<beans::PropertyValue> aPropertyValues;
     760           1 :     jsonToPropertyValues(pArguments, aPropertyValues);
     761           1 :     if (!comphelper::dispatchCommand(aCommand, aPropertyValues))
     762             :     {
     763           0 :         gImpl->maLastExceptionMsg = "Failed to dispatch the .uno: command";
     764           1 :     }
     765           1 : }
     766             : 
     767           0 : static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX, int nY, int nCount)
     768             : {
     769           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     770           0 :     if (!pDoc)
     771             :     {
     772           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     773           0 :         return;
     774             :     }
     775             : 
     776           0 :     pDoc->postMouseEvent(nType, nX, nY, nCount);
     777             : }
     778             : 
     779           0 : static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
     780             : {
     781           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     782           0 :     if (!pDoc)
     783             :     {
     784           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     785           0 :         return;
     786             :     }
     787             : 
     788           0 :     pDoc->setTextSelection(nType, nX, nY);
     789             : }
     790             : 
     791           0 : static void doc_setGraphicSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
     792             : {
     793           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     794           0 :     if (!pDoc)
     795             :     {
     796           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     797           0 :         return;
     798             :     }
     799             : 
     800           0 :     pDoc->setGraphicSelection(nType, nX, nY);
     801             : }
     802             : 
     803           0 : static void doc_resetSelection(LibreOfficeKitDocument* pThis)
     804             : {
     805           0 :     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     806           0 :     if (!pDoc)
     807             :     {
     808           0 :         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
     809           0 :         return;
     810             :     }
     811             : 
     812           0 :     pDoc->resetSelection();
     813             : }
     814             : 
     815           0 : static char* lo_getError (LibreOfficeKit *pThis)
     816             : {
     817           0 :     LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
     818           0 :     OString aString = OUStringToOString(pLib->maLastExceptionMsg, RTL_TEXTENCODING_UTF8);
     819           0 :     char* pMemory = static_cast<char*>(malloc(aString.getLength() + 1));
     820           0 :     strcpy(pMemory, aString.getStr());
     821           0 :     return pMemory;
     822             : }
     823             : 
     824           1 : static void force_c_locale()
     825             : {
     826             :     // force locale (and resource files loaded) to en-US
     827           1 :     OUString aLangISO("en-US");
     828           2 :     LanguageTag aLocale(aLangISO);
     829           1 :     ResMgr::SetDefaultLocale(aLocale);
     830           2 :     SvtSysLocaleOptions aLocalOptions;
     831           1 :     aLocalOptions.SetLocaleConfigString(aLangISO);
     832           2 :     aLocalOptions.SetUILocaleConfigString(aLangISO);
     833           1 : }
     834             : 
     835           0 : static void aBasicErrorFunc(const OUString& rError, const OUString& rAction)
     836             : {
     837           0 :     OStringBuffer aBuffer("Unexpected dialog: ");
     838           0 :     aBuffer.append(OUStringToOString(rAction, RTL_TEXTENCODING_ASCII_US));
     839           0 :     aBuffer.append(" Error: ");
     840           0 :     aBuffer.append(OUStringToOString(rError, RTL_TEXTENCODING_ASCII_US));
     841             : 
     842           0 :     fprintf(stderr, "Unexpected basic error dialog '%s'\n", aBuffer.getStr());
     843           0 : }
     844             : 
     845           1 : static bool initialize_uno(const OUString& aAppProgramURL)
     846             : {
     847             : #ifdef IOS
     848             :     // For iOS we already hardocde the inifile as "rc" in the .app directory.
     849             :     (void) aAppProgramURL;
     850             : #elif defined MACOSX
     851             :     rtl::Bootstrap::setIniFilename(aAppProgramURL + "/../Resources/" SAL_CONFIGFILE("soffice"));
     852             : #else
     853           1 :     rtl::Bootstrap::setIniFilename(aAppProgramURL + "/" SAL_CONFIGFILE("soffice"));
     854             : #endif
     855             : 
     856           1 :     xContext = cppu::defaultBootstrap_InitialComponentContext();
     857           1 :     if (!xContext.is())
     858             :     {
     859           0 :         gImpl->maLastExceptionMsg = "XComponentContext could not be created";
     860             :         SAL_INFO("lok", "XComponentContext could not be created");
     861           0 :         return false;
     862             :     }
     863             : 
     864           1 :     xFactory = xContext->getServiceManager();
     865           1 :     if (!xFactory.is())
     866             :     {
     867           0 :         gImpl->maLastExceptionMsg = "XMultiComponentFactory could not be created";
     868             :         SAL_INFO("lok", "XMultiComponentFactory could not be created");
     869           0 :         return false;
     870             :     }
     871             : 
     872           1 :     xSFactory = uno::Reference<lang::XMultiServiceFactory>(xFactory, uno::UNO_QUERY_THROW);
     873           1 :     if (!xSFactory.is())
     874             :     {
     875           0 :         gImpl->maLastExceptionMsg = "XMultiServiceFactory could not be created";
     876             :         SAL_INFO("lok", "XMultiServiceFactory could not be created");
     877           0 :         return false;
     878             :     }
     879           1 :     comphelper::setProcessServiceFactory(xSFactory);
     880             : 
     881             :     SAL_INFO("lok", "Uno initialized  - " <<  xContext.is());
     882             : 
     883             :     // set UserInstallation to user profile dir in test/user-template
     884             : //    rtl::Bootstrap aDefaultVars;
     885             : //    aDefaultVars.set(OUString("UserInstallation"), aAppProgramURL + "../registry" );
     886             :     // configmgr setup ?
     887             : 
     888           1 :     return true;
     889             : }
     890             : 
     891           1 : static void lo_startmain(void*)
     892             : {
     893           1 :     soffice_main();
     894           1 : }
     895             : 
     896             : static bool bInitialized = false;
     897             : 
     898          80 : static void lo_status_indicator_callback(void *data, comphelper::LibreOfficeKit::statusIndicatorCallbackType type, int percent)
     899             : {
     900          80 :     LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(data);
     901             : 
     902          80 :     if (!pLib->mpCallback)
     903         160 :         return;
     904             : 
     905           0 :     switch (type)
     906             :     {
     907             :     case comphelper::LibreOfficeKit::statusIndicatorCallbackType::Start:
     908           0 :         pLib->mpCallback(LOK_CALLBACK_STATUS_INDICATOR_START, 0, pLib->mpCallbackData);
     909           0 :         break;
     910             :     case comphelper::LibreOfficeKit::statusIndicatorCallbackType::SetValue:
     911           0 :         pLib->mpCallback(LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE, OUString::number(percent).toUtf8().getStr(), pLib->mpCallbackData);
     912           0 :         break;
     913             :     case comphelper::LibreOfficeKit::statusIndicatorCallbackType::Finish:
     914           0 :         pLib->mpCallback(LOK_CALLBACK_STATUS_INDICATOR_FINISH, 0, pLib->mpCallbackData);
     915           0 :         break;
     916             :     }
     917             : }
     918             : 
     919           1 : static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char* pUserProfilePath)
     920             : {
     921           1 :     LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
     922             : 
     923           1 :     if (bInitialized)
     924           0 :         return 1;
     925             : 
     926           1 :     comphelper::LibreOfficeKit::setActive();
     927           1 :     comphelper::LibreOfficeKit::setStatusIndicatorCallback(lo_status_indicator_callback, pLib);
     928             : 
     929           1 :     if (pUserProfilePath)
     930           0 :         rtl::Bootstrap::set(OUString("UserInstallation"), OUString(pUserProfilePath, strlen(pUserProfilePath), RTL_TEXTENCODING_UTF8));
     931             : 
     932           1 :     OUString aAppPath;
     933           1 :     if (pAppPath)
     934             :     {
     935           1 :         aAppPath = OUString(pAppPath, strlen(pAppPath), RTL_TEXTENCODING_UTF8);
     936             :     }
     937             :     else
     938             :     {
     939             :         // Fun conversion dance back and forth between URLs and system paths...
     940           0 :         OUString aAppURL;
     941             :         ::osl::Module::getUrlFromAddress( reinterpret_cast< oslGenericFunction >(lo_initialize),
     942           0 :                                           aAppURL);
     943           0 :         osl::FileBase::getSystemPathFromFileURL( aAppURL, aAppPath );
     944             :     }
     945             : 
     946           2 :     OUString aAppURL;
     947           1 :     if (osl::FileBase::getFileURLFromSystemPath(aAppPath, aAppURL) != osl::FileBase::E_None)
     948           0 :         return 0;
     949             : 
     950             :     try
     951             :     {
     952             :         SAL_INFO("lok", "Attempting to initalize UNO");
     953           1 :         if (!initialize_uno(aAppURL))
     954             :         {
     955           0 :             return false;
     956             :         }
     957           1 :         force_c_locale();
     958             : 
     959             :         // Force headless -- this is only for bitmap rendering.
     960           1 :         rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp");
     961             : 
     962             :         // We specifically need to make sure we have the "headless"
     963             :         // command arg set (various code specifically checks via
     964             :         // CommandLineArgs):
     965           1 :         desktop::Desktop::GetCommandLineArgs().setHeadless();
     966             : 
     967           1 :         Application::EnableHeadlessMode(true);
     968             : 
     969             :         // This is horrible crack. I really would want to go back to simply just call
     970             :         // InitVCL() here. The OfficeIPCThread thing is just horrible.
     971             : 
     972             :         // We could use InitVCL() here -- and used to before using soffice_main,
     973             :         // however that now deals with the initialisation for us (and it's not
     974             :         // possible to try to set up VCL twice.
     975             : 
     976             :         // Instead VCL init is done for us by soffice_main in a separate thread,
     977             :         // however we specifically can't proceed until this setup is complete
     978             :         // (or you get segfaults trying to use VCL and/or deadlocks due to other
     979             :         //  setup within soffice_main). Specifically the various Application::
     980             :         // functions depend on VCL being ready -- the deadlocks would happen
     981             :         // if you try to use loadDocument too early.
     982             : 
     983             :         // The OfficeIPCThread is specifically set to be read when all the other
     984             :         // init in Desktop::Main (run from soffice_main) is done. We can "enable"
     985             :         // the Thread from wherever (it's done again in Desktop::Main), and can
     986             :         // then use it to wait until we're definitely ready to continue.
     987             : 
     988             :         SAL_INFO("lok", "Enabling OfficeIPCThread");
     989           1 :         OfficeIPCThread::EnableOfficeIPCThread();
     990             :         SAL_INFO("lok", "Starting soffice_main");
     991           1 :         pLib->maThread = osl_createThread(lo_startmain, NULL);
     992             :         SAL_INFO("lok", "Waiting for OfficeIPCThread");
     993           1 :         OfficeIPCThread::WaitForReady();
     994             :         SAL_INFO("lok", "OfficeIPCThread ready -- continuing");
     995             : 
     996             :         // If the Thread has been disabled again that indicates that a
     997             :         // restart is required (or in any case we don't have a useable
     998             :         // process around).
     999           1 :         if (!OfficeIPCThread::IsEnabled())
    1000             :         {
    1001           0 :             fprintf(stderr, "LOK init failed -- restart required\n");
    1002           0 :             return false;
    1003             :         }
    1004             : 
    1005           1 :         ErrorHandler::RegisterDisplay(aBasicErrorFunc);
    1006             : 
    1007             :         SAL_INFO("lok", "LOK Initialized");
    1008           1 :         bInitialized = true;
    1009             :     }
    1010           0 :     catch (css::uno::Exception& exception)
    1011             :     {
    1012             :         fprintf(stderr, "Bootstrapping exception '%s'\n",
    1013           0 :                  OUStringToOString(exception.Message, RTL_TEXTENCODING_UTF8).getStr());
    1014             :     }
    1015           2 :     return bInitialized;
    1016             : }
    1017             : 
    1018             : // Undo our clever trick of having SAL_DLLPUBLIC_EXPORT actually not
    1019             : // meaning what is says in for the DISABLE_DYNLOADING case. See
    1020             : // <sal/types.h>. Normally, when building just one big dylib (Android)
    1021             : // or executable (iOS), most of our "public" symbols don't need to be
    1022             : // visible outside that resulting dylib/executable. But
    1023             : // libreofficekit_hook must be exported for dlsym() to find it,
    1024             : // though, at least on iOS.
    1025             : 
    1026             : #if defined(__GNUC__) && defined(HAVE_GCC_VISIBILITY_FEATURE) && defined(DISABLE_DYNLOADING)
    1027             : __attribute__ ((visibility("default")))
    1028             : #else
    1029             : SAL_DLLPUBLIC_EXPORT
    1030             : #endif
    1031           1 : LibreOfficeKit *libreofficekit_hook_2(const char* install_path, const char* user_profile_path)
    1032             : {
    1033           1 :     if (!gImpl)
    1034             :     {
    1035             :         SAL_INFO("lok", "Create libreoffice object");
    1036             : 
    1037           1 :         gImpl = new LibLibreOffice_Impl();
    1038           1 :         if (!lo_initialize(gImpl, install_path, user_profile_path))
    1039             :         {
    1040           0 :             lo_destroy(gImpl);
    1041             :         }
    1042             :     }
    1043           1 :     return static_cast<LibreOfficeKit*>(gImpl);
    1044             : }
    1045             : 
    1046             : #if defined(__GNUC__) && defined(HAVE_GCC_VISIBILITY_FEATURE) && defined(DISABLE_DYNLOADING)
    1047             : __attribute__ ((visibility("default")))
    1048             : #else
    1049             : SAL_DLLPUBLIC_EXPORT
    1050             : #endif
    1051           0 : LibreOfficeKit *libreofficekit_hook(const char* install_path)
    1052             : {
    1053           0 :     return libreofficekit_hook_2(install_path, NULL);
    1054             : }
    1055             : 
    1056           1 : static void lo_destroy(LibreOfficeKit* pThis)
    1057             : {
    1058           1 :     LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
    1059           1 :     gImpl = NULL;
    1060             : 
    1061             :     SAL_INFO("lok", "LO Destroy");
    1062             : 
    1063           1 :     comphelper::LibreOfficeKit::setStatusIndicatorCallback(0, 0);
    1064             : 
    1065           1 :     Application::Quit();
    1066           1 :     osl_joinWithThread(pLib->maThread);
    1067           1 :     osl_destroyThread(pLib->maThread);
    1068             : 
    1069           1 :     delete pLib;
    1070           1 :     bInitialized = false;
    1071             :     SAL_INFO("lok", "LO Destroy Done");
    1072           1 : }
    1073             : 
    1074         348 : }
    1075             : 
    1076             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11