[Libreoffice-commits] .: 3 commits - desktop/prj desktop/scripts desktop/source desktop/unx

Michael Meeks michael at kemper.freedesktop.org
Mon Mar 21 14:20:05 PDT 2011


 desktop/prj/build.lst                     |    2 
 desktop/prj/d.lst                         |    1 
 desktop/scripts/soffice.sh                |  123 -------
 desktop/source/pagein/makefile.mk         |    5 
 desktop/source/pagein/pagein-main.c       |   12 
 desktop/source/pagein/pagein.c            |    5 
 desktop/unx/source/args.c                 |  154 ++++++++
 desktop/unx/source/args.h                 |   50 ++
 desktop/unx/source/makefile.mk            |   23 -
 desktop/unx/source/splashx.c              |   31 +
 desktop/unx/source/start.c                |  526 +++++++++++++++++-------------
 desktop/unx/splash/exports.map            |    1 
 desktop/unx/splash/makefile.mk            |   20 -
 desktop/unx/splash/services_unxsplash.cxx |  160 ---------
 desktop/unx/splash/unxsplash.cxx          |   68 ++-
 desktop/unx/splash/unxsplash.hxx          |   12 
 16 files changed, 654 insertions(+), 539 deletions(-)

New commits:
commit 75fa680b43011ddbb53a7e416703616fc918c432
Author: Michael Meeks <michael.meeks at novell.com>
Date:   Mon Mar 21 17:42:51 2011 +0000

    misc fixes, and un-conditionally enable the splash reporting component
    
    Lots of re-work here; un-conditionally use the splash component to do
    more intelligent fast starting. Throw up the splash screen before we
    start doing 'pagein' work (to get better progress / launch feedback),
    and hide javaldx too.

diff --git a/desktop/prj/d.lst b/desktop/prj/d.lst
index 6c9f538..bb18fe3 100755
--- a/desktop/prj/d.lst
+++ b/desktop/prj/d.lst
@@ -144,3 +144,4 @@ mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office\Jobs
 ..\%__SRC%\misc\productregistration.jar.component %_DEST%\xml%_EXT%\productregistration.jar.component
 ..\%__SRC%\misc\socomp.component %_DEST%\xml%_EXT%\socomp.component
 ..\%__SRC%\misc\spl.component %_DEST%\xml%_EXT%\spl.component
+..\%__SRC%\misc\splash.component %_DEST%\xml%_EXT%\splash.component
diff --git a/desktop/unx/source/args.c b/desktop/unx/source/args.c
index ff08cac..a438f76 100644
--- a/desktop/unx/source/args.c
+++ b/desktop/unx/source/args.c
@@ -48,7 +48,7 @@ static struct {
     unsigned int  bInhibitSplash : 1;
     unsigned int  bInhibitPagein : 1;
     unsigned int  bInhibitJavaLdx : 1;
-    const char   *pagein_type;
+    const char   *pPageinType;
 } pArgDescr[] = {
     /* have a trailing argument */
     { "pt",         1, 0, 0, 0, NULL },
@@ -73,14 +73,16 @@ static struct {
     { "?",          0, 1, 1, 1, NULL },
 };
 
-Args *parse_args (void)
+Args *args_parse (void)
 {
     Args *args;
     sal_uInt32 nArgs, i, j;
     sal_Bool skipNextArg;
 
     nArgs = osl_getCommandArgCount();
-    args = malloc (sizeof (Args) + sizeof (rtl_uString *) * nArgs);
+    i = sizeof (Args) + sizeof (rtl_uString *) * nArgs;
+    args = malloc (i);
+    memset (args, 0, i);
     args->nArgsTotal = nArgs;
 
     /* sort the -env: args to the front */
@@ -130,8 +132,8 @@ Args *parse_args (void)
                 args->bInhibitSplash  |= pArgDescr[j].bInhibitSplash;
                 args->bInhibitPagein  |= pArgDescr[j].bInhibitPagein;
                 args->bInhibitJavaLdx |= pArgDescr[j].bInhibitJavaLdx;
-                if (pArgDescr[j].pagein_type)
-                    args->pagein_type = pArgDescr[j].pagein_type;
+                if (pArgDescr[j].pPageinType)
+                    args->pPageinType = pArgDescr[j].pPageinType;
 
                 skipNextArg = pArgDescr[j].bTwoArgs;
             }
@@ -141,4 +143,12 @@ Args *parse_args (void)
     return args;
 }
 
+void
+args_free (Args *args)
+{
+    /* FIXME: free ppArgs */
+    rtl_uString_release( args->pAppPath );
+    free (args);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/args.h b/desktop/unx/source/args.h
index 9dd0c3b..9816c8a 100644
--- a/desktop/unx/source/args.h
+++ b/desktop/unx/source/args.h
@@ -33,7 +33,8 @@
 #include <rtl/ustring.h>
 
 typedef struct {
-  const char  *pagein_type;     // @pagein-writer for - writer etc. else NULL
+  rtl_uString *pAppPath;
+  const char  *pPageinType;     // @pagein-writer for - writer etc. else NULL
   sal_Bool     bInhibitSplash;  // should we show a splash screen
   sal_Bool     bInhibitPagein;  // should we run pagein ?
   sal_Bool     bInhibitJavaLdx; // should we run javaldx ?
@@ -43,6 +44,7 @@ typedef struct {
   rtl_uString *ppArgs[1];       // sorted argument array
 } Args;
 
-Args *parse_args (void);
+Args *args_parse (void);
+void  args_free  (Args *args);
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/makefile.mk b/desktop/unx/source/makefile.mk
index e406ce4..f740086 100755
--- a/desktop/unx/source/makefile.mk
+++ b/desktop/unx/source/makefile.mk
@@ -32,7 +32,7 @@ NO_DEFAULT_STL=TRUE
 
 .INCLUDE :  settings.mk
 
-.IF "$(ENABLE_QUICKSTART_LIBPNG)"!="TRUE"
+.IF "$(ENABLE_QUICKSTART_LIBPNG)"=="TRUE"
 CFLAGS+=-DENABLE_QUICKSTART_LIBPNG
 .ENDIF
 
@@ -53,7 +53,7 @@ APP1RPATH  = BRAND
 APP1OBJS   = $(OBJFILES) $(PAGEIN_OBJS)
 APP1LIBSALCPPRT=
 APP1CODETYPE = C
-APP1STDLIBS = $(STDLIBGUIMT) $(SALLIB) $(LIBPNG_LIBS)
+APP1STDLIBS = $(PTHREAD_LIBS) $(X11LINK_DYNAMIC) $(SALLIB) $(LIBPNG_LIBS)
 .IF "$(OS)"=="SOLARIS"
 APP1STDLIBS+= -lsocket
 .ENDIF
diff --git a/desktop/unx/source/splashx.c b/desktop/unx/source/splashx.c
index 9cc6832..9e0d237 100755
--- a/desktop/unx/source/splashx.c
+++ b/desktop/unx/source/splashx.c
@@ -629,13 +629,16 @@ void splash_close_window()
 
 int splash_load_bmp( const char *filename )
 {
+    (void)filename;
     return 1;
 }
 void splash_setup( int barc[3], int framec[3], int posx, int posy, int w, int h )
 {
+    (void)barc; (void)framec; (void)posx; (void)posy; (void)w; (void)h;
 }
 int splash_create_window( int argc, char** argv )
 {
+    (void)argc; (void)argv;
     return 1;
 }
 void splash_close_window()
@@ -643,6 +646,7 @@ void splash_close_window()
 }
 void splash_draw_progress( int progress )
 {
+    (void)progress;
 }
 
 #endif // ENABLE_QUICKSTART_LIBPNG
diff --git a/desktop/unx/source/start.c b/desktop/unx/source/start.c
index 3528111..3b5f480 100755
--- a/desktop/unx/source/start.c
+++ b/desktop/unx/source/start.c
@@ -54,8 +54,6 @@
 #define PIPEDEFAULTPATH      "/tmp"
 #define PIPEALTERNATEPATH    "/var/tmp"
 
-typedef enum { ProgressContinue, ProgressRestart, ProgressExit } ProgressStatus;
-
 /* Easier conversions: rtl_uString to rtl_String */
 static rtl_String *
 ustr_to_str( rtl_uString *pStr )
@@ -95,6 +93,115 @@ ustr_debug( const char *pMessage, rtl_uString *pStr )
 #define ustr_debug( a, b ) {}
 #endif
 
+typedef struct {
+    int        status_fd;
+    oslProcess child;
+} ChildInfo;
+
+static int
+child_info_get_status_fd (ChildInfo *info)
+{
+    return info->status_fd;
+}
+
+static void
+child_info_destroy (ChildInfo *info)
+{
+    close (info->status_fd);
+    osl_freeProcessHandle (info->child);
+    free (info);
+}
+
+static ChildInfo *
+child_spawn ( Args *args, sal_Bool bAllArgs, sal_Bool bWithStatus )
+{
+    rtl_uString *pApp = NULL, *pTmp = NULL;
+    rtl_uString **ppArgs;
+    sal_uInt32 nArgs, i;
+    char buffer[64];
+    ChildInfo *info;
+    int status_pipe[2];
+    oslProcessError nError;
+
+    info = calloc (1, sizeof (ChildInfo));
+
+    /* create pipe */
+    if ( pipe( status_pipe ) < 0 )
+    {
+        fprintf( stderr, "ERROR: no file handles\n");
+        exit( 1 );
+    }
+    info->status_fd = status_pipe[0];
+
+    /* application name */
+    rtl_uString_newFromAscii( &pApp, "file://" );
+    rtl_uString_newConcat( &pApp, pApp, args->pAppPath );
+    rtl_uString_newFromAscii( &pTmp, "/soffice.bin" );
+    rtl_uString_newConcat( &pApp, pApp, pTmp );
+
+    rtl_uString_new( &pTmp );
+
+    /* copy args */
+    nArgs = bAllArgs ? args->nArgsTotal : args->nArgsEnv;
+    ppArgs = (rtl_uString **)calloc( nArgs + 1, sizeof( rtl_uString* ) );
+    for ( i = 0; i < nArgs; ++i )
+        ppArgs[i] = args->ppArgs[i];
+
+    if( bWithStatus )
+    {
+        /* add the pipe arg */
+        snprintf (buffer, 63, "--splash-pipe=%d", status_pipe[1]);
+        ppArgs[nArgs] = NULL;
+        rtl_uString_newFromAscii( &ppArgs[nArgs], buffer );
+        ++nArgs;
+    }
+
+    /* start the main process */
+    nError = osl_executeProcess( pApp, ppArgs, nArgs,
+                                 osl_Process_NORMAL,
+                                 NULL,
+                                 NULL,
+                                 NULL, 0,
+                                 &info->child );
+
+    if ( nError != osl_Process_E_None )
+    {
+        fprintf( stderr, "ERROR %d forking process", nError );
+        ustr_debug( "", pApp );
+        _exit (1);
+    }
+
+    close( status_pipe[1] );
+
+    return info;
+}
+
+static sal_Bool
+child_exited_wait (ChildInfo *info, sal_Bool bShortWait)
+{
+    TimeValue t = { 0, 250 /* ms */ * 1000 * 1000 };
+    if (!bShortWait)
+        t.Seconds = 1024;
+    return osl_joinProcessWithTimeout (info->child, &t) != osl_Process_E_TimedOut;
+}
+
+static int
+child_get_exit_code (ChildInfo *info)
+{
+    oslProcessInfo inf;
+
+    inf.Code = -1;
+    inf.Size = sizeof (inf);
+    if (osl_getProcessInfo (info->child, osl_Process_EXITCODE, &inf) != osl_Process_E_None)
+    {
+        fprintf (stderr, "Warning: failed to fetch libreoffice exit status\n");
+        return -1;
+    }
+    return inf.Code;
+}
+
+typedef enum { ProgressContinue, ProgressRestart, ProgressExit } ProgressStatus;
+
 /* Path of the application. */
 static rtl_uString *
 get_app_path( const char *pAppExec )
@@ -495,7 +602,7 @@ get_bootstrap_value( int *array, int size, rtlBootstrapHandle handle, const char
 
 /* Load the colors and size of the splash. */
 static void
-load_splash_defaults( rtl_uString *pAppPath, sal_Bool *pInhibitSplash )
+load_splash_defaults( rtl_uString *pAppPath, sal_Bool *bNoDefaults )
 {
     rtl_uString *pSettings = NULL, *pTmp = NULL;
     rtlBootstrapHandle handle;
@@ -525,7 +632,7 @@ load_splash_defaults( rtl_uString *pAppPath, sal_Bool *pInhibitSplash )
     get_bootstrap_value( size,  2, handle, "ProgressSize" );
 
     if ( logo[0] == 0 )
-        *pInhibitSplash = sal_True;
+        *bNoDefaults = sal_True;
 
     splash_setup( bar, frame, pos[0], pos[1], size[0], size[1] );
 
@@ -539,7 +646,7 @@ load_splash_defaults( rtl_uString *pAppPath, sal_Bool *pInhibitSplash )
 
 /* Read the percent to show in splash. */
 static ProgressStatus
-read_percent( int status_fd, int *pPercent )
+read_percent( ChildInfo *info, int *pPercent )
 {
     static char pBuffer[BUFFER_LEN + 1];
     static char *pNext = pBuffer;
@@ -556,7 +663,8 @@ read_percent( int status_fd, int *pPercent )
     memmove( pBuffer, pNext, nNotProcessed );
 
     /* read data */
-    nRead = read( status_fd, pBuffer + nNotProcessed, BUFFER_LEN - nNotProcessed );
+    nRead = read( child_info_get_status_fd (info),
+                  pBuffer + nNotProcessed, BUFFER_LEN - nNotProcessed );
     if ( nRead < 0 )
         return sal_False;
 
@@ -567,11 +675,13 @@ read_percent( int status_fd, int *pPercent )
     pBegin = pBuffer;
     pNext = pBuffer;
     for ( pIter = pBuffer; *pIter; ++pIter )
+    {
         if ( *pIter == '\n' )
         {
             pBegin = pNext;
             pNext = pIter + 1;
         }
+    }
 
 #if OSL_DEBUG_LEVEL > 0
     fprintf( stderr, "Got status: %s\n", pBegin );
@@ -587,50 +697,6 @@ read_percent( int status_fd, int *pPercent )
     return ProgressExit;
 }
 
-/* Periodically update the splash & the percent acconding to what
-   status_fd says */
-static ProgressStatus
-show_splash( int status_fd )
-{
-    int nRetval;
-    struct pollfd aPfd;
-
-    int nPercent = 0;
-    sal_Bool bFinish = sal_False;
-    ProgressStatus eResult = ProgressExit;
-
-    /* we want to watch status_fd */
-    aPfd.fd = status_fd;
-    aPfd.events = POLLIN;
-
-#if OSL_DEBUG_LEVEL > 0
-    fprintf( stderr, "Starting main loop, status fd: %d\n", status_fd );
-#endif
-
-    /* main loop */
-    do {
-        splash_draw_progress( nPercent );
-
-        /* read from pipe if data available */
-        nRetval = poll( &aPfd, 1, 50 );
-        if ( aPfd.revents & ( POLLERR | POLLHUP | POLLNVAL ) )
-            bFinish = sal_True;
-        else if ( nRetval > 0 )
-        {
-            eResult = read_percent( status_fd, &nPercent );
-            bFinish = ( eResult != ProgressContinue );
-        }
-        else if ( nRetval < 0 )
-            bFinish = sal_True;
-    } while ( !bFinish );
-
-#if OSL_DEBUG_LEVEL > 0
-    fprintf( stderr, "Finishing, result is %s\n",
-            ( eResult == ProgressContinue )? "continue" : ( ( eResult == ProgressRestart )? "restart" : "exit" ) );
-#endif
-    return eResult;
-}
-
 /* Simple system check. */
 static void
 system_checks( void )
@@ -650,11 +716,6 @@ system_checks( void )
 /* re-use the pagein code */
 extern int pagein_execute (int argc, char **argv);
 
-/* parameters from the main thread */
-int status_fd = 0;
-int status_pipe[2];
-rtl_uString *pAppPath = NULL;
-
 void
 exec_pagein (Args *args)
 {
@@ -663,10 +724,10 @@ exec_pagein (Args *args)
     argv[0] = "dummy-pagein";
     argv[1] = "-L../basis-link/program";
     argv[2] = "@pagein-common";
-    argv[3] = (char *)args->pagein_type;
+    argv[3] = (char *)args->pPageinType;
     argv[4] = NULL;
 
-    pagein_execute (args->pagein_type ? 4 : 3, argv);
+    pagein_execute (args->pPageinType ? 4 : 3, argv);
 }
 
 static void extend_library_path (const char *new_element)
@@ -698,11 +759,11 @@ static void extend_library_path (const char *new_element)
 static void
 exec_javaldx (Args *args)
 {
-    char *newpath;
-    sal_Sequence *line;
+    char newpath[4096];
     sal_uInt32 nArgs;
-    rtl_uString *pApp = NULL;
+    rtl_uString *pApp;
     rtl_uString **ppArgs;
+    rtl_uString *pTmp, *pTmp2;
     rtl_uString *pEnvironment[1] = { NULL };
 
     ppArgs = (rtl_uString **)calloc( args->nArgsEnv + 2, sizeof( rtl_uString* ) );
@@ -710,22 +771,38 @@ exec_javaldx (Args *args)
     for ( nArgs = 0; nArgs < args->nArgsEnv; ++nArgs )
         ppArgs[nArgs] = args->ppArgs[nArgs];
 
-    /* FIXME: do we need to check / turn program/redirectrc into an absolute path ? */
-    rtl_uString_newFromAscii( &ppArgs[nArgs++], "-env:INIFILENAME=vnd.sun.star.pathname:./redirectrc" );
+    /* Use absolute path to redirectrc */
+    pTmp = NULL;
+    rtl_uString_newFromAscii( &pTmp, "-env:INIFILENAME=vnd.sun.star.pathname:" );
+    rtl_uString_newConcat( &pTmp, pTmp, args->pAppPath );
+    pTmp2 = NULL;
+    rtl_uString_newFromAscii( &pTmp2, "/redirectrc" );
+    rtl_uString_newConcat( &pTmp, pTmp, pTmp2 );
+    ppArgs[nArgs] = pTmp;
+    rtl_uString_release (pTmp2);
+    nArgs++;
 
     oslProcess javaldx = NULL;
     oslFileHandle fileOut= 0;
     oslProcessError err;
 
-    rtl_uString_newFromAscii( &pApp, "../ure/bin/javaldx" );
-    /* unset to avoid bogus output */
+    /* And also to javaldx */
+    pApp = NULL;
+    rtl_uString_newFromAscii( &pApp, "file://" );
+    rtl_uString_newConcat( &pApp, pApp, args->pAppPath );
+    pTmp = NULL;
+    rtl_uString_newFromAscii( &pTmp, "/../ure/bin/javaldx" );
+    rtl_uString_newConcat( &pApp, pApp, pTmp );
+
+    /* unset to avoid bogus console output */
     rtl_uString_newFromAscii( &pEnvironment[0], "G_SLICE" );
+
     err = osl_executeProcess_WithRedirectedIO( pApp, ppArgs, nArgs,
-                                               osl_Process_HIDDEN,
+                                               osl_Process_NORMAL,
                                                NULL, // security
                                                NULL, // work dir
                                                pEnvironment, 1,
-                                               &javaldx, // handle
+                                               &javaldx, // process handle
                                                NULL,
                                                &fileOut,
                                                NULL);
@@ -734,120 +811,29 @@ exec_javaldx (Args *args)
     {
         fprintf (stderr, "Warning: failed to launch javaldx - java may not fuction correctly\n");
         return;
-    }
+    } else {
+        char *chomp;
+        sal_uInt64 bytes_read;
 
-    line = NULL;
-    if (!osl_readLine (fileOut, &line) || !line) {
-        fprintf (stderr, "Warning: failed to read path from javaldx\n");
-        return;
-    }
+        /* Magically osl_readLine doesn't work with pipes with E_SPIPE - so be this lame instead: */
+        while (osl_readFile (fileOut, newpath, SAL_N_ELEMENTS (newpath), &bytes_read) == osl_File_E_INTR);
 
-    if (!line->nElements)
-        fprintf (stderr, "curious - javaldx returns zero length path\n");
-    else {
-        newpath = malloc (line->nElements + 1);
-        strncpy (newpath, line->elements, line->nElements);
-        newpath[line->nElements] = '\0';
-
-        fprintf (stderr, "Adding javaldx path of '%s'\n", newpath);
-        extend_library_path (newpath);
-    }
-
-    /* FIXME: should we join it first ? */
-    osl_freeProcessHandle(javaldx);
-}
-
-static void SAL_CALL
-fork_app_thread( Args *args )
-{
-    rtl_uString *pApp = NULL, *pTmp = NULL, *pArg = NULL;
-    rtl_uString **ppArgs;
-    sal_uInt32 nArgs, i;
-    sal_Bool restart;
-
-    oslProcess child;
-    oslProcessError nError;
-
-    if (!args->bInhibitJavaLdx)
-        exec_pagein (args);
-
-    if (!args->bInhibitJavaLdx)
-        exec_javaldx (args);
-
-    /* application name */
-    rtl_uString_newFromAscii( &pApp, "file://" );
-    rtl_uString_newConcat( &pApp, pApp, pAppPath );
-    rtl_uString_newFromAscii( &pTmp, "/soffice.bin" );
-    rtl_uString_newConcat( &pApp, pApp, pTmp );
-
-    rtl_uString_new( &pTmp );
-
-    /* copy args */
-    nArgs = osl_getCommandArgCount();
-    ppArgs = (rtl_uString **)calloc( nArgs + 1, sizeof( rtl_uString* ) );
-    for ( i = 0; i < nArgs; ++i )
-    {
-        ppArgs[i] = NULL;
-        osl_getCommandArg( i, &pTmp );
-        rtl_uString_newFromString( &(ppArgs[i]), pTmp );
-    }
-
-    /* add the pipe arg */
-    sal_Unicode pUnicode[RTL_USTR_MAX_VALUEOFINT32];
-    rtl_ustr_valueOfInt32( pUnicode, status_pipe[1], 10 );
-
-    rtl_uString_newFromAscii( &pArg, "--splash-pipe=" );
-    rtl_uString_newFromStr( &pTmp, pUnicode );
-    rtl_uString_newConcat( &pArg, pArg, pTmp );
-
-    ppArgs[nArgs] = NULL;
-    rtl_uString_newFromString( &(ppArgs[nArgs]), pArg );
-    ++nArgs;
-
-    restart = sal_False;
-    do
-    {
-        oslProcessInfo info;
-
-        /* start the main process */
-        nError = osl_executeProcess( pApp, ppArgs, nArgs,
-                                     osl_Process_NORMAL,
-                                     NULL,
-                                     NULL,
-                                     NULL, 0,
-                                     &child );
-
-        if ( nError != osl_Process_E_None )
-        {
-            fprintf( stderr, "ERROR %d forking process", nError );
-            ustr_debug( "", pApp );
-            _exit (1);
+        if (bytes_read <= 0) {
+            fprintf (stderr, "Warning: failed to read path from javaldx\n");
+            return;
         }
+        newpath[bytes_read] = '\0';
 
-        /* wait for it to complete */
-        osl_joinProcess (child);
-
-        info.Size = sizeof (info);
-        info.Code = 0;
-        if (osl_getProcessInfo (child, osl_Process_EXITCODE, &info) != osl_Process_E_None)
-            fprintf (stderr, "Warning: failed to fetch libreoffice exit status\n");
-
-        switch (info.Code) {
-        case 79: // re-start with just -env: parameters
-            fprintf (stderr, "FIXME: re-start with just -env: params !\n");
-            restart = sal_True;
-            break;
-        case 81: // re-start with all arguments
-            fprintf (stderr, "FIXME: re-start with all params !\n");
-            restart = sal_True;
-            break;
-        default:
-            break;
-        }
+        if ((chomp = strstr (newpath, "\n")))
+            *chomp = '\0';
     }
-    while (restart);
 
-    close( status_pipe[1] );
+#if OSL_DEBUG_LEVEL > 0
+    fprintf (stderr, "Adding javaldx path of '%s'\n", newpath);
+#endif
+    extend_library_path (newpath);
+
+    osl_freeProcessHandle(javaldx);
 }
 
 SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
@@ -855,88 +841,126 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
     int fd = 0;
     sal_Bool bSentArgs = sal_False;
     rtl_uString *pPipePath = NULL;
-    ProgressStatus eResult = ProgressExit;
     Args *args;
 
-    fprintf (stderr, "start !\n");
-
     /* turn SIGPIPE into an error */
     signal( SIGPIPE, SIG_IGN );
 
-    args = parse_args();
-
-#ifndef ENABLE_QUICKSTART_LIBPNG
-    /* we can't load and render it anyway */
-    args->bInhibitSplash = sal_True;
-#endif
-
-    pAppPath = get_app_path( argv[0] );
-    if ( !pAppPath )
+    args = args_parse ();
+    args->pAppPath = get_app_path( argv[0] );
+    if ( !args->pAppPath )
     {
         fprintf( stderr, "ERROR: Can't read app link\n" );
         exit( 1 );
     }
-    ustr_debug( "App path", pAppPath );
+    ustr_debug( "App path", args->pAppPath );
 
-    pPipePath = get_pipe_path( pAppPath );
+#ifndef ENABLE_QUICKSTART_LIBPNG
+    /* we can't load and render it anyway */
+    args->bInhibitSplash = sal_True;
+#endif
 
-    fprintf (stderr, "try pipe !\n");
+    pPipePath = get_pipe_path( args->pAppPath );
 
     if ( ( fd = connect_pipe( pPipePath ) ) >= 0 )
     {
         rtl_uString *pCwdPath = NULL;
         osl_getProcessWorkingDir( &pCwdPath );
 
-        fprintf (stderr, "send args !\n");
-
         bSentArgs = send_args( fd, pCwdPath );
     }
 #if OSL_DEBUG_LEVEL > 0
     else
         ustr_debug( "Failed to connect to pipe", pPipePath );
 #endif
+    close( fd );
 
     if ( !bSentArgs )
     {
         /* we have to prepare for, and exec the binary */
+        int nPercent = 0;
+        ChildInfo *info;
+        sal_Bool bAllArgs = sal_True;
+        sal_Bool bHaveWindow = sal_False;
+        sal_Bool bShortWait, bRestart;
+
+        /* sanity check pieces */
+        system_checks();
+
+        /* load splash image and create window */
+        if ( !args->bInhibitSplash )
+        {
+            sal_Bool bNoDefaults = sal_False;
+            load_splash_image( args->pAppPath );
+            load_splash_defaults( args->pAppPath, &bNoDefaults );
+
+            if (!bNoDefaults &&
+                ( bHaveWindow = splash_create_window( argc, argv ) ) )
+                splash_draw_progress( 0 );
+        }
+
+        /* pagein */
+        if (!args->bInhibitJavaLdx)
+            exec_pagein (args);
+
+        /* javaldx */
+        if (!args->bInhibitJavaLdx)
+            exec_javaldx (args);
+
         do {
-            /* sanity check pieces */
-            system_checks();
+            bRestart = sal_False;
 
-            /* create pipe */
-            if ( pipe( status_pipe ) < 0 )
-            {
-                fprintf( stderr, "ERROR: no file handles\n");
-                exit( 1 );
-            }
-            int status_fd = status_pipe[0];
-            osl_createThread( fork_app_thread, args );
+            /* fast updates if we have somewhere to update it to */
+            bShortWait = bHaveWindow;
 
-            if ( !args->bInhibitSplash )
+            /* Periodically update the splash & the percent according
+               to what status_fd says, poll quickly only while starting */
+            info = child_spawn (args, bAllArgs, bShortWait);
+            while (!child_exited_wait (info, bShortWait))
             {
-                load_splash_image( pAppPath );
-                load_splash_defaults( pAppPath, &args->bInhibitSplash );
-            }
+                ProgressStatus eResult;
 
-            if ( !args->bInhibitSplash && splash_create_window( argc, argv ) )
-            {
-                splash_draw_progress( 0 );
-                eResult = show_splash( status_fd );
-                splash_close_window();
+                splash_draw_progress( nPercent );
+                eResult = read_percent( info, &nPercent );
+                if (eResult != ProgressContinue)
+                {
+                    splash_close_window ();
+                    bShortWait = sal_False;
+                }
+
+#if OSL_DEBUG_LEVEL > 0
+                fprintf( stderr, "Polling, result is %s\n",
+                         ( eResult == ProgressContinue )? "continue" :
+                         ( ( eResult == ProgressRestart )? "restart" : "exit" ) );
+#endif
             }
 
-            close( status_fd );
+#if OSL_DEBUG_LEVEL > 0
+            fprintf (stderr, "Exited with code '%d'\n", child_get_exit_code (info));
+#endif
+
+            switch (child_get_exit_code (info)) {
+            case 79: // re-start with just -env: parameters
+                fprintf (stderr, "FIXME: re-start with just -env: params !\n");
+                bRestart = sal_True;
+                bAllArgs = sal_False;
+                break;
+            case 81: // re-start with all arguments
+                fprintf (stderr, "FIXME: re-start with all params !\n");
+                bRestart = sal_True;
+                bAllArgs = sal_True;
+                break;
+            default:
+                break;
+            }
 
-            fprintf (stderr, "sleep!\n");
-            sleep (100);
-        } while ( eResult == ProgressRestart );
+            child_info_destroy (info);
+        } while (bRestart);
     }
 
     /* cleanup */
-    rtl_uString_release( pAppPath );
     rtl_uString_release( pPipePath );
-
-    close( fd );
+    args_free (args);
 
     return 0;
 }
diff --git a/desktop/unx/splash/exports.map b/desktop/unx/splash/exports.map
index ba501f9..218f053 100755
--- a/desktop/unx/splash/exports.map
+++ b/desktop/unx/splash/exports.map
@@ -3,7 +3,6 @@ UDK_3_0_0 {
         GetVersionInfo;
         component_getImplementationEnvironment;
         component_getFactory;
-        component_writeInfo;
 
     local:
         *;
diff --git a/desktop/unx/splash/makefile.mk b/desktop/unx/splash/makefile.mk
index d182173..23a9d98 100755
--- a/desktop/unx/splash/makefile.mk
+++ b/desktop/unx/splash/makefile.mk
@@ -36,17 +36,9 @@ ENABLE_EXCEPTIONS=TRUE
 
 .INCLUDE :  settings.mk
 
-.IF "$(ENABLE_UNIX_QUICKSTARTER)"!="TRUE"
-
-dummy:
-    @echo "Unix quickstarter disabled"
-
-.ELSE
-
 # --- Files --------------------------------------------------------
 
-SLOFILES =  $(SLO)$/unxsplash.obj \
-            $(SLO)$/services_unxsplash.obj
+SLOFILES =  $(SLO)$/unxsplash.obj
 
 SHL1DEPN=   makefile.mk
 SHL1OBJS=   $(SLOFILES)
@@ -64,8 +56,14 @@ SHL1STDLIBS= \
     $(CPPULIB)			\
     $(SALLIB)
 
-.ENDIF # ENABLE_UNIX_QUICKSTARTER
-
 # --- Targets ------------------------------------------------------
 
 .INCLUDE :  target.mk
+
+ALLTAR : $(MISC)/splash.component
+
+$(MISC)/splash.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+        splash.component
+    $(XSLTPROC) --nonet --stringparam uri \
+        '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+        $(SOLARENV)/bin/createcomponent.xslt splash.component
diff --git a/desktop/unx/splash/services_unxsplash.cxx b/desktop/unx/splash/services_unxsplash.cxx
deleted file mode 100755
index d370b45..0000000
--- a/desktop/unx/splash/services_unxsplash.cxx
+++ /dev/null
@@ -1,160 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * Copyright 2010, Novell Inc.
- * 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.
- *
- * Contributor(s): Jan Holesovsky <kendy at novell.com>
- *
- ************************************************************************/
-#include <com/sun/star/beans/NamedValue.hpp>
-#include <com/sun/star/registry/XRegistryKey.hpp>
-#include <com/sun/star/util/Date.hpp>
-#include <uno/environment.h>
-#include <cppuhelper/factory.hxx>
-#include <unotools/configmgr.hxx>
-
-#include <string.h>
-
-#include "unxsplash.hxx"
-
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::lang;
-using namespace ::com::sun::star::beans;
-using namespace ::com::sun::star::registry;
-using namespace ::desktop;
-
-using ::rtl::OUString;
-
-static const char* pServices[] =
-{
-    UnxSplashScreen::serviceName,
-    NULL
-};
-
-static const char* pImplementations[] =
-{
-    UnxSplashScreen::implementationName,
-    NULL
-};
-
-typedef Reference<XInterface>(* fProvider)( const Reference<XMultiServiceFactory>& );
-
-static const fProvider pInstanceProviders[] =
-{
-    UnxSplashScreen::getInstance,
-    NULL
-};
-
-
-static const char** pSupportedServices[] =
-{
-    UnxSplashScreen::interfaces,
-    NULL
-};
-
-static Sequence<OUString>
-getSupportedServiceNames( int p ) {
-    const char **names = pSupportedServices[p];
-    Sequence<OUString> aSeq;
-    for ( int i = 0; names[i] != NULL; i++ )
-    {
-        aSeq.realloc( i+1 );
-        aSeq[i] = OUString::createFromAscii( names[i] );
-    }
-    return aSeq;
-}
-
-extern "C"
-{
-void SAL_CALL
-component_getImplementationEnvironment(
-    const sal_Char** ppEnvironmentTypeName,
-    uno_Environment** /*ppEnvironment*/ )
-{
-    *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
-}
-
-sal_Bool SAL_CALL
-component_writeInfo(
-    void* pServiceManager,
-    void* pRegistryKey )
-{
-    Reference<XMultiServiceFactory> xMan(
-        reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
-    Reference<XRegistryKey> xKey(
-        reinterpret_cast< XRegistryKey* >( pRegistryKey ) ) ;
-
-    // iterate over service names and register them...
-    OUString aImpl;
-    const char* pServiceName = NULL;
-    const char* pImplName = NULL;
-    for ( int i = 0; ( pServices[i] != NULL ) && ( pImplementations[i] != NULL ); i++ )
-    {
-        pServiceName= pServices[i];
-        pImplName = pImplementations[i];
-        aImpl = OUString(RTL_CONSTASCII_USTRINGPARAM( "/" ))
-              + OUString::createFromAscii( pImplName )
-              + OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES" ));
-        Reference<XRegistryKey> xNewKey = xKey->createKey( aImpl );
-        xNewKey->createKey( OUString::createFromAscii( pServiceName ) );
-    }
-    return sal_True;
-}
-
-void* SAL_CALL
-component_getFactory(
-    const sal_Char* pImplementationName,
-    void* pServiceManager,
-    void* /*pRegistryKey*/ )
-{
-    // Set default return value for this operation - if it failed.
-    if ( pImplementationName && pServiceManager )
-    {
-        Reference< XSingleServiceFactory > xFactory;
-        Reference< XMultiServiceFactory > xServiceManager(
-            reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
-
-        // search implementation
-        for ( int i = 0; ( pImplementations[i] != NULL ); i++ )
-        {
-            if ( strcmp( pImplementations[i], pImplementationName ) == 0 )
-            {
-                // found implementation
-                xFactory = Reference<XSingleServiceFactory>( cppu::createSingleFactory(
-                    xServiceManager, OUString::createFromAscii( pImplementationName ),
-                    pInstanceProviders[i], getSupportedServiceNames( i ) ) );
-                if ( xFactory.is() )
-                {
-                    // Factory is valid - service was found.
-                    xFactory->acquire();
-                    return xFactory.get();
-                }
-            }
-        }
-    }
-
-    return NULL;
-}
-} // extern "C"
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/splash/unxsplash.cxx b/desktop/unx/splash/unxsplash.cxx
index f51e22a..de703ba 100755
--- a/desktop/unx/splash/unxsplash.cxx
+++ b/desktop/unx/splash/unxsplash.cxx
@@ -34,6 +34,7 @@
 #include <tools/stream.hxx>
 #include <sfx2/sfx.hrc>
 #include <com/sun/star/registry/XRegistryKey.hpp>
+#include <cppuhelper/implementationentry.hxx>
 #include <rtl/logfile.hxx>
 #include <rtl/ustrbuf.hxx>
 #include <rtl/math.hxx>
@@ -41,13 +42,13 @@
 #define PIPE_ARG "--splash-pipe="
 
 using namespace ::rtl;
+using namespace ::com::sun::star;
 using namespace ::com::sun::star::registry;
 
 namespace desktop
 {
-
-UnxSplashScreen::UnxSplashScreen( const Reference< XMultiServiceFactory >& rSMgr )
-    : m_rFactory( rSMgr ),
+    UnxSplashScreen::UnxSplashScreen( const Reference< uno::XComponentContext >& xCtx )
+    : m_xCtx( xCtx ),
       m_pOutFd( NULL )
 {
 }
@@ -131,34 +132,65 @@ UnxSplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::
         }
     }
 }
+}
+
+using namespace desktop;
 
 // get service instance...
-UnxSplashScreen *UnxSplashScreen::m_pINSTANCE = NULL;
-osl::Mutex UnxSplashScreen::m_aMutex;
+static uno::Reference< uno::XInterface > m_xINSTANCE;
 
-Reference< XInterface > UnxSplashScreen::getInstance( const Reference< XMultiServiceFactory >& rSMgr )
+uno::Reference< uno::XInterface > SAL_CALL UnxSplash_createInstance(const uno::Reference< uno::XComponentContext > & xCtx ) throw( uno::Exception )
 {
-    if ( m_pINSTANCE == NULL )
+    static osl::Mutex m_aMutex;
+    if ( !m_xINSTANCE.is() )
     {
         osl::MutexGuard guard( m_aMutex );
-        if ( m_pINSTANCE == NULL )
-            return (XComponent*) new UnxSplashScreen( rSMgr );
+        if ( !m_xINSTANCE.is() )
+            m_xINSTANCE = (cppu::OWeakObject*) new UnxSplashScreen( xCtx );
     }
 
-    return (XComponent*)NULL;
+    return m_xINSTANCE;
+}
+
+OUString UnxSplash_getImplementationName()
+{
+    return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.comp.PipeSplashScreen" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL UnxSplash_getSupportedServiceNames() throw()
+{
+    const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.PipeSplashScreen" ) );
+    const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+    return aSeq;
 }
 
-// static service info...
-const char* UnxSplashScreen::interfaces[] =
+::cppu::ImplementationEntry aEntries[] =
 {
-    "com.sun.star.task.XStartusIndicator",
-    "com.sun.star.lang.XInitialization",
-    NULL,
+    {
+        UnxSplash_createInstance, UnxSplash_getImplementationName,
+        UnxSplash_getSupportedServiceNames,
+        ::cppu::createSingleComponentFactory,
+        0, 0
+    },
+    { 0, 0, 0, 0, 0, 0 }
 };
-const sal_Char *UnxSplashScreen::serviceName = "com.sun.star.office.PipeSplashScreen";
-const sal_Char *UnxSplashScreen::implementationName = "com.sun.star.office.comp.PipeSplashScreen";
-const sal_Char *UnxSplashScreen::supportedServiceNames[] = { "com.sun.star.office.PipeSplashScreen", NULL };
 
+extern "C"
+{
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL
+component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName,
+                                        uno_Environment ** )
+{ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; }
+
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL
+component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* pRegistryKey )
+{
+    return ::cppu::component_getFactoryHelper( pImplName, pServiceManager,
+                                               pRegistryKey, aEntries );
 }
 
+} // extern "C"
+
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/splash/unxsplash.hxx b/desktop/unx/splash/unxsplash.hxx
index abe5a8c..b25e858 100755
--- a/desktop/unx/splash/unxsplash.hxx
+++ b/desktop/unx/splash/unxsplash.hxx
@@ -31,6 +31,7 @@
 #include <com/sun/star/uno/Exception.hpp>
 #include <com/sun/star/uno/Reference.h>
 #include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/task/XStatusIndicator.hpp>
 #include <com/sun/star/lang/XInitialization.hpp>
 #include <cppuhelper/implbase2.hxx>
@@ -54,24 +55,17 @@ private:
     UnxSplashScreen( void );
     UnxSplashScreen operator =( const UnxSplashScreen& );
 
-    UnxSplashScreen( const Reference< XMultiServiceFactory >& xFactory );
-
     virtual ~UnxSplashScreen();
 
     static  UnxSplashScreen *m_pINSTANCE;
 
     static osl::Mutex m_aMutex;
-    Reference< XMultiServiceFactory > m_rFactory;
+    Reference< XComponentContext > m_xCtx;
 
     FILE *m_pOutFd;
 
 public:
-    static const char* interfaces[];
-    static const sal_Char *serviceName;
-    static const sal_Char *implementationName;
-    static const sal_Char *supportedServiceNames[];
-
-    static Reference< XInterface > getInstance( const Reference < XMultiServiceFactory >& xFactory );
+    UnxSplashScreen( const Reference< XComponentContext >& xCtx );
 
     // XStatusIndicator
     virtual void SAL_CALL start( const OUString& aText, sal_Int32 nRange ) throw ( RuntimeException );
commit e08dcb189d2560fd761bbbd955652e930551e12d
Author: Michael Meeks <michael.meeks at novell.com>
Date:   Mon Mar 21 16:15:22 2011 +0000

    split out argument parsing to clean it up

diff --git a/desktop/unx/source/args.c b/desktop/unx/source/args.c
new file mode 100644
index 0000000..ff08cac
--- /dev/null
+++ b/desktop/unx/source/args.c
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ *       Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Major Contributor(s):
+ *  Michael Meeks <michael.meeks at novell.com>
+ * Portions created by the Ted are Copyright (C) 2010 Ted. All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include <malloc.h>
+#include <string.h>
+#include <osl/process.h>
+
+#include "args.h"
+
+/* do we start -env: */
+static int
+is_env_arg (rtl_uString *str)
+{
+    return !rtl_ustr_ascii_compare_WithLength (str->buffer, 5, "-env:");
+}
+
+static struct {
+    const char   *name;
+    unsigned int  bTwoArgs : 1;
+    unsigned int  bInhibitSplash : 1;
+    unsigned int  bInhibitPagein : 1;
+    unsigned int  bInhibitJavaLdx : 1;
+    const char   *pagein_type;
+} pArgDescr[] = {
+    /* have a trailing argument */
+    { "pt",         1, 0, 0, 0, NULL },
+    { "display",    1, 0, 0, 0, NULL },
+
+    /* no splash */
+    { "nologo",     0, 1, 0, 0, NULL },
+    { "headless",   0, 1, 0, 0, NULL },
+    { "invisible",  0, 1, 0, 0, NULL },
+    { "minimized",  0, 1, 0, 0, NULL },
+
+    /* pagein bits */
+    { "writer",     0, 0, 0, 0, "@pagein-writer"  },
+    { "calc",       0, 0, 0, 0, "@pagein-calc"    },
+    { "draw",       0, 0, 0, 0, "@pagein-draw"    },
+    { "impress",    0, 0, 0, 0, "@pagein-impress" },
+
+    /* nothing much */
+    { "version",    0, 1, 1, 1, NULL },
+    { "help",       0, 1, 1, 1, NULL },
+    { "h",          0, 1, 1, 1, NULL },
+    { "?",          0, 1, 1, 1, NULL },
+};
+
+Args *parse_args (void)
+{
+    Args *args;
+    sal_uInt32 nArgs, i, j;
+    sal_Bool skipNextArg;
+
+    nArgs = osl_getCommandArgCount();
+    args = malloc (sizeof (Args) + sizeof (rtl_uString *) * nArgs);
+    args->nArgsTotal = nArgs;
+
+    /* sort the -env: args to the front */
+    for ( j = i = 0; i < nArgs; ++i )
+    {
+        rtl_uString *pTmp = NULL;
+        osl_getCommandArg( i, &pTmp );
+        if (is_env_arg (pTmp))
+            args->ppArgs[j++] = pTmp;
+        else
+            rtl_uString_release (pTmp);
+    }
+    args->nArgsEnv = j;
+
+    /* Then the other args */
+    for ( j = i = 0; i < nArgs; ++i )
+    {
+        rtl_uString *pTmp = NULL;
+
+        osl_getCommandArg( i, &pTmp );
+        if (!is_env_arg (pTmp))
+            args->ppArgs[j++] = pTmp;
+        else
+            rtl_uString_release (pTmp);
+    }
+
+    skipNextArg = sal_False;
+    for ( i = args->nArgsEnv; i < args->nArgsTotal; i++ )
+    {
+        sal_uInt32 j;
+        const sal_Unicode *arg = args->ppArgs[i]->buffer;
+        sal_Int32 length = args->ppArgs[i]->length;
+
+        /* grok only parameters */
+        if (arg[0] != '-')
+            continue;
+
+        while (length > 2 && arg[0] == '-') {
+            arg++;
+            length--;
+        }
+
+        for ( j = 0; j < SAL_N_ELEMENTS (pArgDescr); ++j ) {
+            if (!rtl_ustr_indexOfAscii_WithLength
+                    (arg, length, pArgDescr[j].name, strlen (pArgDescr[j].name))) {
+
+                args->bInhibitSplash  |= pArgDescr[j].bInhibitSplash;
+                args->bInhibitPagein  |= pArgDescr[j].bInhibitPagein;
+                args->bInhibitJavaLdx |= pArgDescr[j].bInhibitJavaLdx;
+                if (pArgDescr[j].pagein_type)
+                    args->pagein_type = pArgDescr[j].pagein_type;
+
+                skipNextArg = pArgDescr[j].bTwoArgs;
+            }
+        }
+    }
+
+    return args;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/args.h b/desktop/unx/source/args.h
new file mode 100644
index 0000000..9dd0c3b
--- /dev/null
+++ b/desktop/unx/source/args.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ *       Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Major Contributor(s):
+ *	Michael Meeks <michael.meeks at novell.com>
+ * Portions created by the Ted are Copyright (C) 2010 Ted. All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include <sal/types.h>
+#include <rtl/ustring.h>
+
+typedef struct {
+  const char  *pagein_type;     // @pagein-writer for - writer etc. else NULL
+  sal_Bool     bInhibitSplash;  // should we show a splash screen
+  sal_Bool     bInhibitPagein;  // should we run pagein ?
+  sal_Bool     bInhibitJavaLdx; // should we run javaldx ?
+
+  sal_uInt32   nArgsEnv;        // number of -env: style args
+  sal_uInt32   nArgsTotal;      // number of -env: as well as -writer style args
+  rtl_uString *ppArgs[1];       // sorted argument array
+} Args;
+
+Args *parse_args (void);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/makefile.mk b/desktop/unx/source/makefile.mk
index 8205201..e406ce4 100755
--- a/desktop/unx/source/makefile.mk
+++ b/desktop/unx/source/makefile.mk
@@ -41,7 +41,8 @@ CFLAGS+=$(LIBPNG_CFLAGS)
 
 OBJFILES= \
     $(OBJ)$/splashx.obj \
-    $(OBJ)$/start.obj
+    $(OBJ)$/start.obj \
+    $(OBJ)$/args.obj
 
 PAGEIN_OBJS= \
     $(OBJ)$/pagein.obj \
diff --git a/desktop/unx/source/start.c b/desktop/unx/source/start.c
index 7e550b3..3528111 100755
--- a/desktop/unx/source/start.c
+++ b/desktop/unx/source/start.c
@@ -47,6 +47,7 @@
 #include <rtl/ustrbuf.h>
 #include <sal/main.h>
 
+#include "args.h"
 #include "splashx.h"
 
 #define IMG_SUFFIX	         ".png"
@@ -655,42 +656,17 @@ int status_pipe[2];
 rtl_uString *pAppPath = NULL;
 
 void
-exec_pagein (void)
+exec_pagein (Args *args)
 {
-    char buffer[64] = "";
     char *argv[5];
-    sal_uInt32 nArgs, i, j;
-    static const char *cmd_names[] = { "writer", "impress", "draw", "calc" };
 
     argv[0] = "dummy-pagein";
     argv[1] = "-L../basis-link/program";
     argv[2] = "@pagein-common";
-    argv[3] = buffer;
+    argv[3] = (char *)args->pagein_type;
     argv[4] = NULL;
 
-    nArgs = osl_getCommandArgCount();
-    for ( i = 0; i < nArgs; ++i )
-    {
-        rtl_uString *pArg = NULL;
-        osl_getCommandArg( i, &pArg );
-
-        sal_Int32 length = pArg->length;
-        const sal_Unicode *arg = pArg->buffer;
-        while (length > 2 && arg[0] == '-') {
-            arg++; length--;
-        }
-
-        for ( j = 0; j < SAL_N_ELEMENTS (cmd_names); ++j ) {
-            if (!rtl_ustr_indexOfAscii_WithLength(
-                   arg, length, cmd_names[j], strlen (cmd_names[j]))) {
-                strcpy (buffer, "@pagein-");
-                strcat (buffer, cmd_names[j]);
-                goto found_app;
-            }
-        }
-    }
- found_app:
-    pagein_execute (buffer[0] != '\0' ? 4 : 3, argv);
+    pagein_execute (args->pagein_type ? 4 : 3, argv);
 }
 
 static void extend_library_path (const char *new_element)
@@ -720,34 +696,22 @@ static void extend_library_path (const char *new_element)
 }
 
 static void
-exec_javaldx (void)
+exec_javaldx (Args *args)
 {
     char *newpath;
     sal_Sequence *line;
-    sal_uInt32 i, j, nArgs;
+    sal_uInt32 nArgs;
     rtl_uString *pApp = NULL;
     rtl_uString **ppArgs;
     rtl_uString *pEnvironment[1] = { NULL };
 
-    nArgs = osl_getCommandArgCount();
-    ppArgs = (rtl_uString **)calloc( nArgs + 2, sizeof( rtl_uString* ) );
-
-#warning FIXME - copy this and just sort the arguments globally first ...
+    ppArgs = (rtl_uString **)calloc( args->nArgsEnv + 2, sizeof( rtl_uString* ) );
 
-    for ( j = i = 0; i < nArgs; ++i )
-    {
-        rtl_uString *pTmp = NULL;
-        osl_getCommandArg( i, &pTmp );
-        if (rtl_ustr_ascii_compare_WithLength (pTmp->buffer, 5, "-env:"))
-        {
-            rtl_uString_acquire (pTmp);
-            ppArgs[j++] = pTmp;
-        }
-        rtl_uString_release (pTmp);
-    }
+    for ( nArgs = 0; nArgs < args->nArgsEnv; ++nArgs )
+        ppArgs[nArgs] = args->ppArgs[nArgs];
 
     /* FIXME: do we need to check / turn program/redirectrc into an absolute path ? */
-    rtl_uString_newFromAscii( &ppArgs[j++], "-env:INIFILENAME=vnd.sun.star.pathname:./redirectrc" );
+    rtl_uString_newFromAscii( &ppArgs[nArgs++], "-env:INIFILENAME=vnd.sun.star.pathname:./redirectrc" );
 
     oslProcess javaldx = NULL;
     oslFileHandle fileOut= 0;
@@ -756,7 +720,7 @@ exec_javaldx (void)
     rtl_uString_newFromAscii( &pApp, "../ure/bin/javaldx" );
     /* unset to avoid bogus output */
     rtl_uString_newFromAscii( &pEnvironment[0], "G_SLICE" );
-    err = osl_executeProcess_WithRedirectedIO( pApp, ppArgs, j,
+    err = osl_executeProcess_WithRedirectedIO( pApp, ppArgs, nArgs,
                                                osl_Process_HIDDEN,
                                                NULL, // security
                                                NULL, // work dir
@@ -794,9 +758,8 @@ exec_javaldx (void)
 }
 
 static void SAL_CALL
-fork_app_thread( void *dummy )
+fork_app_thread( Args *args )
 {
-    (void)dummy;
     rtl_uString *pApp = NULL, *pTmp = NULL, *pArg = NULL;
     rtl_uString **ppArgs;
     sal_uInt32 nArgs, i;
@@ -805,9 +768,11 @@ fork_app_thread( void *dummy )
     oslProcess child;
     oslProcessError nError;
 
-    exec_pagein ();
+    if (!args->bInhibitJavaLdx)
+        exec_pagein (args);
 
-    exec_javaldx ();
+    if (!args->bInhibitJavaLdx)
+        exec_javaldx (args);
 
     /* application name */
     rtl_uString_newFromAscii( &pApp, "file://" );
@@ -885,98 +850,24 @@ fork_app_thread( void *dummy )
     close( status_pipe[1] );
 }
 
-/* Check if 'pArg' is -pCmpWith or --pCmpWith */
-static sal_Bool
-arg_check( rtl_uString *pArg, const char *pCmpWith )
-{
-    sal_Unicode *pUnicode = rtl_uString_getStr( pArg );
-
-    if ( pUnicode[0] == (sal_Unicode)'-' )
-        pUnicode++;
-    else
-        return sal_False;
-
-    /* tolerate -- prefixes etc. */
-    if ( pUnicode[0] == (sal_Unicode)'-' )
-        pUnicode++;
-
-    return !rtl_ustr_ascii_compare( pUnicode, pCmpWith );
-}
-
-static const char *ppInhibit[] = {
-    "nologo", "headless", "invisible", "help", "h", "?",
-    "minimized", "version", NULL
-};
-static const char *ppTwoArgs[] = {
-    "pt", "display", NULL
-};
-
-/* Read command line parameters and return whether we display the splash. */
-static sal_Bool
-get_inhibit_splash()
-{
-    rtl_uString *pTmp = NULL;
-    sal_Bool bSkipNextArg = sal_False;
-    const char **ppIter;
-
-    rtl_uString_new( &pTmp );
-
-    sal_uInt32 nArg;
-    sal_uInt32 nArgCount = osl_getCommandArgCount();
-    for ( nArg = 0; nArg < nArgCount; ++nArg )
-    {
-        if ( bSkipNextArg )
-        {
-            bSkipNextArg = sal_False;
-            continue;
-        }
-
-        osl_getCommandArg( nArg, &pTmp );
-
-        /* check for inhibit splash params */
-        for ( ppIter = ppInhibit; *ppIter; ++ppIter )
-        {
-            if ( arg_check( pTmp, *ppIter ) )
-            {
-                rtl_uString_release( pTmp );
-                return sal_True;
-            }
-        }
-        /* check for 2 arguments params */
-        for ( ppIter = ppTwoArgs; *ppIter; ++ppIter )
-        {
-            if ( arg_check( pTmp, *ppIter ) )
-            {
-                bSkipNextArg = sal_True;
-                break;
-            }
-        }
-    }
-
-    /* cleanup */
-    rtl_uString_release( pTmp );
-
-    return sal_False;
-}
-
 SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
 {
     int fd = 0;
-    sal_Bool bInhibitSplash;
     sal_Bool bSentArgs = sal_False;
     rtl_uString *pPipePath = NULL;
     ProgressStatus eResult = ProgressExit;
+    Args *args;
 
     fprintf (stderr, "start !\n");
 
     /* turn SIGPIPE into an error */
     signal( SIGPIPE, SIG_IGN );
 
-    bInhibitSplash = get_inhibit_splash();
+    args = parse_args();
 
 #ifndef ENABLE_QUICKSTART_LIBPNG
     /* we can't load and render it anyway */
-    bInhibitSplash = sal_True;
+    args->bInhibitSplash = sal_True;
 #endif
 
     pAppPath = get_app_path( argv[0] );
@@ -1019,15 +910,15 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
                 exit( 1 );
             }
             int status_fd = status_pipe[0];
-            osl_createThread( fork_app_thread, NULL );
+            osl_createThread( fork_app_thread, args );
 
-            if ( !bInhibitSplash )
+            if ( !args->bInhibitSplash )
             {
                 load_splash_image( pAppPath );
-                load_splash_defaults( pAppPath, &bInhibitSplash );
+                load_splash_defaults( pAppPath, &args->bInhibitSplash );
             }
 
-            if ( !bInhibitSplash && splash_create_window( argc, argv ) )
+            if ( !args->bInhibitSplash && splash_create_window( argc, argv ) )
             {
                 splash_draw_progress( 0 );
                 eResult = show_splash( status_fd );
commit 1df79912a5503f3f5f3c87bac3258e1c5eff93dc
Author: Michael Meeks <michael.meeks at novell.com>
Date:   Mon Mar 21 15:00:18 2011 +0000

    re-work start process to enable earlier splash and faster start

diff --git a/desktop/prj/build.lst b/desktop/prj/build.lst
index bef0960..26e9e04 100755
--- a/desktop/prj/build.lst
+++ b/desktop/prj/build.lst
@@ -20,9 +20,9 @@ dt	desktop\win32\source\rebase				nmake	-	w	dt_rebase dt_inc NULL
 dt	desktop\os2\source\applauncher			nmake	-	p	dt_applauncher dt_inc NULL
 dt	desktop\unx\source\officeloader		nmake	-	u	dt_officeloader_unx dt_inc NULL
 dt     desktop\unx\source                      nmake   -       u       dt_uwrapper     dt_inc NULL
-dt     desktop\unx\splash                      nmake   -       u       dt_usplash      dt_inc NULL
 dt	desktop\source\pagein					nmake	-	u	dt_pagein dt_inc NULL
 dt	desktop\source\pkgchk\unopkg			nmake	-	all	dt_unopkg dt_dp_misc dt_app dt_inc dt_guiloader.w NULL
+dt     desktop\unx\splash                      nmake   -       u       dt_usplash      dt_pagein.u dt_inc NULL
 dt	desktop\source\deployment				nmake	-	all	dt_deployment dt_dp_manager dt_dp_registry dt_dp_registry_package dt_dp_registry_executable dt_dp_registry_help dt_dp_registry_script dt_dp_registry_sfwk dt_dp_registry_component dt_dp_registry_configuration dt_dp_unopkg dt_inc dt_dp_misc NULL
 dt	desktop\source\deployment\misc				nmake	-	all	dt_dp_misc dt_inc NULL
 dt	desktop\source\deployment\unopkg			nmake	-	all	dt_dp_unopkg dt_inc NULL
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh
index 8e16ed1..76af9bc 100755
--- a/desktop/scripts/soffice.sh
+++ b/desktop/scripts/soffice.sh
@@ -39,6 +39,19 @@ export SAL_ENABLE_FILE_LOCKING
 # working on your system.
 # SAL_NOOPENGL=true; export SAL_NOOPENGL
 
+unset XENVIRONMENT
+
+# uncomment line below to disable anti aliasing of fonts
+# SAL_ANTIALIAS_DISABLE=true; export SAL_ANTIALIAS_DISABLE
+
+# uncomment line below if you encounter problems starting soffice on your system
+# SAL_NO_XINITTHREADS=true; export SAL_NO_XINITTHREADS
+
+# read database entries for Adabas D
+if [ -f /etc/adabasrc ]; then
+  . /etc/adabasrc
+fi
+
 # The following is needed on Linux PPC with IBM j2sdk142:
 #@# export JITC_PROCESSOR_TYPE=6
 
@@ -66,8 +79,6 @@ if [ "$VALGRIND" != "" ]; then
     export G_SLICE
 fi
 
-sd_binary=`basename "$0" | sed 's/libreoffice/soffice/g'`.bin
-
 case "`uname -s`" in
 NetBSD|OpenBSD|FreeBSD|DragonFly)
 # this is a temporary hack until we can live with the default search paths
@@ -86,109 +97,5 @@ AIX)
     ;;
 esac
 
-#collect all bootstrap variables specified on the command line
-#so that they can be passed as arguments to javaldx later on
-for arg in $@
-do
-  case "$arg" in
-       -env:*) BOOTSTRAPVARS=$BOOTSTRAPVARS" ""$arg";;
-  esac
-done
-
-# test for availability of the fast external splash
-for arg in $@; do
-    case "$arg" in
-    --nologo|-nologo|--no-oosplash|-no-oosplash|--version|-version|--help|-help|-h|-\?)
-        no_oosplash=y
-        ;;
-    esac
-done
-
-# Setup our app as oosplash, but try to avoid executing pagein,
-# and other expensive environment setup pieces wherever possible
-# for a second started office
-if [ "$sd_binary" = "soffice.bin" -a -x "$sd_prog/oosplash.bin" ] && [ "$no_oosplash" != "y" ] ; then
-    sd_binary="oosplash.bin"
-
-    # try to connect to a running instance early
-    if $VALGRINDCHECK "$sd_prog/$sd_binary" -qsend-and-report "$@" ; then
-        exit 0
-    fi
-fi
-
-# pagein
-sd_pagein_args=@pagein-common
-for sd_arg in "$@"; do
-    case ${sd_arg} in
-    --calc|-calc)
-        sd_pagein_args="${sd_pagein_args} @pagein-calc"
-        break;
-        ;;
-    --draw|-draw)
-        sd_pagein_args="${sd_pagein_args} @pagein-draw"
-        break;
-        ;;
-    --impress|-impress)
-        sd_pagein_args="${sd_pagein_args} @pagein-impress"
-        break;
-        ;;
-    --writer|-writer)
-        sd_pagein_args="${sd_pagein_args} @pagein-writer"
-        break;
-        ;;
-    esac
-done
-"$sd_prog/../basis-link/program/pagein" -L"$sd_prog/../basis-link/program" \
-    ${sd_pagein_args}
-
-# extend the ld_library_path for java: javaldx checks the sofficerc for us
-if [ -x "$sd_prog/../basis-link/ure-link/bin/javaldx" ] ; then
-    my_path=`"$sd_prog/../basis-link/ure-link/bin/javaldx" $BOOTSTRAPVARS \
-        "-env:INIFILENAME=vnd.sun.star.pathname:$sd_prog/redirectrc"`
-    if [ -n "$my_path" ] ; then
-        sd_platform=`uname -s`
-        case $sd_platform in
-          AIX)
-            LIBPATH=$my_path${LIBPATH:+:$LIBPATH}
-            export LIBPATH
-            ;;
-          *)
-            LD_LIBRARY_PATH=$my_path${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
-            export LD_LIBRARY_PATH
-            ;;
-        esac
-    fi
-fi
-
-unset XENVIRONMENT
-
-# uncomment line below to disable anti aliasing of fonts
-# SAL_ANTIALIAS_DISABLE=true; export SAL_ANTIALIAS_DISABLE
-
-# uncomment line below if you encounter problems starting soffice on your system
-# SAL_NO_XINITTHREADS=true; export SAL_NO_XINITTHREADS
-
-# read database entries for Adabas D
-if [ -f /etc/adabasrc ]; then
-  . /etc/adabasrc
-fi
-
-# execute soffice binary
-$VALGRINDCHECK "$sd_prog/$sd_binary" "$@" &
-trap 'kill -9 $!' TERM
-wait $!
-sd_ret=$?
-
-while [ $sd_ret -eq 79 -o $sd_ret -eq 81 ]
-do
-    if [ $sd_ret -eq 79 ]; then
-        $VALGRINDCHECK "$sd_prog/$sd_binary" ""$BOOTSTRAPVARS"" &
-    elif [ $sd_ret -eq 81 ]; then
-        $VALGRINDCHECK "$sd_prog/$sd_binary" "$@" &
-    fi
-
-    wait $!
-    sd_ret=$?
-done
-
-exit $sd_ret
+# oosplash does the rest: forcing pages in, javaldx etc. are
+exec $VALGRINDCHECK "$sd_prog/oosplash.bin" "$@"
diff --git a/desktop/source/pagein/makefile.mk b/desktop/source/pagein/makefile.mk
index 09248d4..205e03c 100755
--- a/desktop/source/pagein/makefile.mk
+++ b/desktop/source/pagein/makefile.mk
@@ -45,6 +45,7 @@ LIBSALCPPRT=$(0)
 
 OBJFILES= \
     $(OBJ)$/pagein.obj \
+    $(OBJ)$/pagein-main.obj \
     $(OBJ)$/file_image_unx.obj
 
 APP1TARGET=$(TARGET)
@@ -77,24 +78,28 @@ UREMISCPATH=..$/ure-link$/share$/misc
 $(MISC)$/$(TARGET)-calc : makefile.mk
     @echo Making: $@
     @-echo $(DLLPRE)sc$(DFTDLLPOST)  >  $@
+    @-echo $(DLLPRE)scui$(DFTDLLPOST) >>  $@
     @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
     @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
 
 $(MISC)$/$(TARGET)-draw : makefile.mk
     @echo Making: $@
     @-echo $(DLLPRE)sd$(DFTDLLPOST)  >  $@
+    @-echo $(DLLPRE)sdui$(DFTDLLPOST) >>  $@
     @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
     @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
 
 $(MISC)$/$(TARGET)-impress : makefile.mk
     @echo Making: $@
     @-echo $(DLLPRE)sd$(DFTDLLPOST)  >  $@
+    @-echo $(DLLPRE)sdui$(DFTDLLPOST) >>  $@
     @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
     @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
 
 $(MISC)$/$(TARGET)-writer : makefile.mk
     @echo Making: $@
     @-echo $(DLLPRE)sw$(DFTDLLPOST)  >  $@
+    @-echo $(DLLPRE)swui$(DFTDLLPOST) >>  $@
     @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
     @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
 
diff --git a/desktop/source/pagein/pagein-main.c b/desktop/source/pagein/pagein-main.c
new file mode 100644
index 0000000..f8fe82a
--- /dev/null
+++ b/desktop/source/pagein/pagein-main.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+/*
+ * De-coupled to allow pagein to be re-used in the unx
+ * splash / quick-starter
+ */
+extern int pagein_execute (int argc, char **argv);
+
+int main (int argc, char **argv)
+{
+    return pagein_execute (argc, argv);
+}
+
diff --git a/desktop/source/pagein/pagein.c b/desktop/source/pagein/pagein.c
index 15623bf..9e3b610 100755
--- a/desktop/source/pagein/pagein.c
+++ b/desktop/source/pagein/pagein.c
@@ -58,8 +58,10 @@ cleanup_and_leave:
     return (result);
 }
 
+extern int pagein_execute (int argc, char **argv);
+
 /* main */
-int  main (int argc, char **argv)
+int pagein_execute (int argc, char **argv)
 {
     int    i, v = 0;
     size_t nfiles = 0, nbytes = 0;
@@ -102,7 +104,6 @@ int  main (int argc, char **argv)
             /* next argv */
             continue;
         }
-        
 
         if ((argv[i][0] == '@') && ((fp = fopen (argv[i], "r")) == 0))
         {
diff --git a/desktop/unx/source/makefile.mk b/desktop/unx/source/makefile.mk
index 494477a..8205201 100755
--- a/desktop/unx/source/makefile.mk
+++ b/desktop/unx/source/makefile.mk
@@ -32,33 +32,31 @@ NO_DEFAULT_STL=TRUE
 
 .INCLUDE :  settings.mk
 
-.IF "$(ENABLE_UNIX_QUICKSTARTER)"!="TRUE"
-
-dummy:
-    @echo "Unix quickstarter disabled"
-
-.ELSE
+.IF "$(ENABLE_QUICKSTART_LIBPNG)"!="TRUE"
+CFLAGS+=-DENABLE_QUICKSTART_LIBPNG
+.ENDIF
 
 STDLIB=
-
 CFLAGS+=$(LIBPNG_CFLAGS)
 
 OBJFILES= \
     $(OBJ)$/splashx.obj \
     $(OBJ)$/start.obj
 
+PAGEIN_OBJS= \
+    $(OBJ)$/pagein.obj \
+    $(OBJ)$/file_image_unx.obj
+
 APP1TARGET = $(TARGET)
 APP1RPATH  = BRAND
-APP1OBJS   = $(OBJFILES)
+APP1OBJS   = $(OBJFILES) $(PAGEIN_OBJS)
 APP1LIBSALCPPRT=
 APP1CODETYPE = C
-APP1STDLIBS = $(SALLIB) -lX11 $(LIBPNG_LIBS)
+APP1STDLIBS = $(STDLIBGUIMT) $(SALLIB) $(LIBPNG_LIBS)
 .IF "$(OS)"=="SOLARIS"
 APP1STDLIBS+= -lsocket
 .ENDIF
 
-.ENDIF # ENABLE_UNIX_QUICKSTARTER
-
 # --- Targets ------------------------------------------------------
 
 .INCLUDE :	target.mk
diff --git a/desktop/unx/source/splashx.c b/desktop/unx/source/splashx.c
index 4aa5622..9cc6832 100755
--- a/desktop/unx/source/splashx.c
+++ b/desktop/unx/source/splashx.c
@@ -25,6 +25,9 @@
  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
  * instead of those above.
  */
+
+#ifdef ENABLE_QUICKSTART_LIBPNG
+
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 #include <X11/Xutil.h>
@@ -620,4 +623,28 @@ void splash_close_window()
     bitmap_rows = NULL;
 }
 
+#else /* not ENABLE_QUICKSTART_LIBPNG */
+
+/* Stubs that will never be called in this case */
+
+int splash_load_bmp( const char *filename )
+{
+    return 1;
+}
+void splash_setup( int barc[3], int framec[3], int posx, int posy, int w, int h )
+{
+}
+int splash_create_window( int argc, char** argv )
+{
+    return 1;
+}
+void splash_close_window()
+{
+}
+void splash_draw_progress( int progress )
+{
+}
+
+#endif // ENABLE_QUICKSTART_LIBPNG
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/start.c b/desktop/unx/source/start.c
index d782033..7e550b3 100755
--- a/desktop/unx/source/start.c
+++ b/desktop/unx/source/start.c
@@ -49,14 +49,7 @@
 
 #include "splashx.h"
 
-/*
- * magic argument - if passed, not passed onto soffice.bin but we exit
- * immediately if we fail to control the process. Used to avoid doing
- * an un-conditional pagein
- */
-#define QSEND_AND_REPORT "-qsend-and-report"
-
-#define IMG_SUFFIX	     ".png"
+#define IMG_SUFFIX	         ".png"
 #define PIPEDEFAULTPATH      "/tmp"
 #define PIPEALTERNATEPATH    "/var/tmp"
 
@@ -353,10 +346,6 @@ send_args( int fd, rtl_uString *pCwdPath )
 
         osl_getCommandArg( nArg, &pTmp );
 
-        if ( rtl_uString_getLength( pTmp ) == 0 ||
-             !rtl_ustr_ascii_compare( pTmp->buffer, QSEND_AND_REPORT ) )
-            continue;
-
         // this is not a param, we have to prepend filenames with file://
         // FIXME: improve the check
         if ( ( pTmp->buffer[0] != (sal_Unicode)'-' ) )
@@ -651,25 +640,174 @@ system_checks( void )
     /* check proc is mounted - lots of things fail otherwise */
     if ( stat( "/proc/version", &buf ) != 0 )
     {
-        fprintf( stderr, "ERROR: /proc not mounted - OO.o is unlikely to work well if at all" );
+        fprintf( stderr, "ERROR: /proc not mounted - LibreOffice is unlikely to work well if at all" );
         exit( 1 );
     }
 #endif
 }
 
-/* Start the OOo application */
-static sal_Bool
-fork_app( rtl_uString *pAppPath, int *status_fd )
+/* re-use the pagein code */
+extern int pagein_execute (int argc, char **argv);
+
+/* parameters from the main thread */
+int status_fd = 0;
+int status_pipe[2];
+rtl_uString *pAppPath = NULL;
+
+void
+exec_pagein (void)
+{
+    char buffer[64] = "";
+    char *argv[5];
+    sal_uInt32 nArgs, i, j;
+    static const char *cmd_names[] = { "writer", "impress", "draw", "calc" };
+
+    argv[0] = "dummy-pagein";
+    argv[1] = "-L../basis-link/program";
+    argv[2] = "@pagein-common";
+    argv[3] = buffer;
+    argv[4] = NULL;
+
+    nArgs = osl_getCommandArgCount();
+    for ( i = 0; i < nArgs; ++i )
+    {
+        rtl_uString *pArg = NULL;
+        osl_getCommandArg( i, &pArg );
+
+        sal_Int32 length = pArg->length;
+        const sal_Unicode *arg = pArg->buffer;
+        while (length > 2 && arg[0] == '-') {
+            arg++; length--;
+        }
+
+        for ( j = 0; j < SAL_N_ELEMENTS (cmd_names); ++j ) {
+            if (!rtl_ustr_indexOfAscii_WithLength(
+                   arg, length, cmd_names[j], strlen (cmd_names[j]))) {
+                strcpy (buffer, "@pagein-");
+                strcat (buffer, cmd_names[j]);
+                goto found_app;
+            }
+        }
+    }
+ found_app:
+    pagein_execute (buffer[0] != '\0' ? 4 : 3, argv);
+}
+
+static void extend_library_path (const char *new_element)
+{
+    const char *pathname;
+#ifdef AIX
+    pathname = "LIBPATH";
+#else
+    pathname = "LD_LIBRARY_PATH";
+#endif
+    char *buffer;
+    char *oldpath;
+
+    oldpath = getenv (pathname);
+    buffer = malloc (strlen (new_element) + strlen (pathname) +
+                     (oldpath ? strlen (oldpath) : 0)+ 4);
+    strcpy (buffer, pathname);
+    strcpy (buffer, "=");
+    strcpy (buffer, new_element);
+    if (oldpath) {
+        strcat (buffer, ":");
+        strcat (buffer, oldpath);
+    }
+
+    /* deliberately leak buffer - many OS' don't dup at this point */
+    putenv (buffer);
+}
+
+static void
+exec_javaldx (void)
+{
+    char *newpath;
+    sal_Sequence *line;
+    sal_uInt32 i, j, nArgs;
+    rtl_uString *pApp = NULL;
+    rtl_uString **ppArgs;
+    rtl_uString *pEnvironment[1] = { NULL };
+
+    nArgs = osl_getCommandArgCount();
+    ppArgs = (rtl_uString **)calloc( nArgs + 2, sizeof( rtl_uString* ) );
+
+#warning FIXME - copy this and just sort the arguments globally first ...
+
+    for ( j = i = 0; i < nArgs; ++i )
+    {
+        rtl_uString *pTmp = NULL;
+        osl_getCommandArg( i, &pTmp );
+        if (rtl_ustr_ascii_compare_WithLength (pTmp->buffer, 5, "-env:"))
+        {
+            rtl_uString_acquire (pTmp);
+            ppArgs[j++] = pTmp;
+        }
+        rtl_uString_release (pTmp);
+    }
+
+    /* FIXME: do we need to check / turn program/redirectrc into an absolute path ? */
+    rtl_uString_newFromAscii( &ppArgs[j++], "-env:INIFILENAME=vnd.sun.star.pathname:./redirectrc" );
+
+    oslProcess javaldx = NULL;
+    oslFileHandle fileOut= 0;
+    oslProcessError err;
+
+    rtl_uString_newFromAscii( &pApp, "../ure/bin/javaldx" );
+    /* unset to avoid bogus output */
+    rtl_uString_newFromAscii( &pEnvironment[0], "G_SLICE" );
+    err = osl_executeProcess_WithRedirectedIO( pApp, ppArgs, j,
+                                               osl_Process_HIDDEN,
+                                               NULL, // security
+                                               NULL, // work dir
+                                               pEnvironment, 1,
+                                               &javaldx, // handle
+                                               NULL,
+                                               &fileOut,
+                                               NULL);
+
+    if( err != osl_Process_E_None)
+    {
+        fprintf (stderr, "Warning: failed to launch javaldx - java may not fuction correctly\n");
+        return;
+    }
+
+    line = NULL;
+    if (!osl_readLine (fileOut, &line) || !line) {
+        fprintf (stderr, "Warning: failed to read path from javaldx\n");
+        return;
+    }
+
+    if (!line->nElements)
+        fprintf (stderr, "curious - javaldx returns zero length path\n");
+    else {
+        newpath = malloc (line->nElements + 1);
+        strncpy (newpath, line->elements, line->nElements);
+        newpath[line->nElements] = '\0';
+
+        fprintf (stderr, "Adding javaldx path of '%s'\n", newpath);
+        extend_library_path (newpath);
+    }
+
+    /* FIXME: should we join it first ? */
+    osl_freeProcessHandle(javaldx);
+}
+
+static void SAL_CALL
+fork_app_thread( void *dummy )
 {
+    (void)dummy;
     rtl_uString *pApp = NULL, *pTmp = NULL, *pArg = NULL;
     rtl_uString **ppArgs;
     sal_uInt32 nArgs, i;
+    sal_Bool restart;
 
-    oslProcess aProcess;
+    oslProcess child;
     oslProcessError nError;
-    int status_pipe[2];
 
-    system_checks();
+    exec_pagein ();
+
+    exec_javaldx ();
 
     /* application name */
     rtl_uString_newFromAscii( &pApp, "file://" );
@@ -689,13 +827,6 @@ fork_app( rtl_uString *pAppPath, int *status_fd )
         rtl_uString_newFromString( &(ppArgs[i]), pTmp );
     }
 
-    /* create pipe */
-    if ( pipe( status_pipe ) < 0 )
-    {
-        fprintf( stderr, "ERROR: no file handles\n");
-        exit( 1 );
-    }
-
     /* add the pipe arg */
     sal_Unicode pUnicode[RTL_USTR_MAX_VALUEOFINT32];
     rtl_ustr_valueOfInt32( pUnicode, status_pipe[1], 10 );
@@ -708,25 +839,50 @@ fork_app( rtl_uString *pAppPath, int *status_fd )
     rtl_uString_newFromString( &(ppArgs[nArgs]), pArg );
     ++nArgs;
 
-    /* start the OOo process */
-    nError = osl_executeProcess( pApp, ppArgs, nArgs,
-            osl_Process_DETACHED | osl_Process_NORMAL,
-            NULL,
-            NULL,
-            NULL, 0,
-            &aProcess );
+    restart = sal_False;
+    do
+    {
+        oslProcessInfo info;
 
-    *status_fd = status_pipe[0];
-    close( status_pipe[1] );
+        /* start the main process */
+        nError = osl_executeProcess( pApp, ppArgs, nArgs,
+                                     osl_Process_NORMAL,
+                                     NULL,
+                                     NULL,
+                                     NULL, 0,
+                                     &child );
 
-    if ( nError != osl_Process_E_None )
-    {
-        fprintf( stderr, "ERROR %d forking process", nError );
-        ustr_debug( "", pApp );
-        return sal_False;
+        if ( nError != osl_Process_E_None )
+        {
+            fprintf( stderr, "ERROR %d forking process", nError );
+            ustr_debug( "", pApp );
+            _exit (1);
+        }
+
+        /* wait for it to complete */
+        osl_joinProcess (child);
+
+        info.Size = sizeof (info);
+        info.Code = 0;
+        if (osl_getProcessInfo (child, osl_Process_EXITCODE, &info) != osl_Process_E_None)
+            fprintf (stderr, "Warning: failed to fetch libreoffice exit status\n");
+
+        switch (info.Code) {
+        case 79: // re-start with just -env: parameters
+            fprintf (stderr, "FIXME: re-start with just -env: params !\n");
+            restart = sal_True;
+            break;
+        case 81: // re-start with all arguments
+            fprintf (stderr, "FIXME: re-start with all params !\n");
+            restart = sal_True;
+            break;
+        default:
+            break;
+        }
     }
+    while (restart);
 
-    return sal_True;
+    close( status_pipe[1] );
 }
 
 /* Check if 'pArg' is -pCmpWith or --pCmpWith */
@@ -748,11 +904,12 @@ arg_check( rtl_uString *pArg, const char *pCmpWith )
 }
 
 static const char *ppInhibit[] = {
-    "nologo", "headless", "invisible", "help", "h", "?", "minimized",
-    NULL };
+    "nologo", "headless", "invisible", "help", "h", "?",
+    "minimized", "version", NULL
+};
 static const char *ppTwoArgs[] = {
-    "pt", "display",
-    NULL };
+    "pt", "display", NULL
+};
 
 /* Read command line parameters and return whether we display the splash. */
 static sal_Bool
@@ -804,18 +961,24 @@ get_inhibit_splash()
 
 SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
 {
-    int fd = 0, status_fd = 0;
-    sal_Bool bInhibitSplash, bSendAndReport;
+    int fd = 0;
+    sal_Bool bInhibitSplash;
     sal_Bool bSentArgs = sal_False;
-    rtl_uString *pAppPath = NULL;
     rtl_uString *pPipePath = NULL;
     ProgressStatus eResult = ProgressExit;
 
+    fprintf (stderr, "start !\n");
+
     /* turn SIGPIPE into an error */
     signal( SIGPIPE, SIG_IGN );
 
     bInhibitSplash = get_inhibit_splash();
 
+#ifndef ENABLE_QUICKSTART_LIBPNG
+    /* we can't load and render it anyway */
+    bInhibitSplash = sal_True;
+#endif
+
     pAppPath = get_app_path( argv[0] );
     if ( !pAppPath )
     {
@@ -824,15 +987,17 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
     }
     ustr_debug( "App path", pAppPath );
 
-    bSendAndReport = argc > 1 && !strcmp (argv[1], QSEND_AND_REPORT);
-
     pPipePath = get_pipe_path( pAppPath );
 
+    fprintf (stderr, "try pipe !\n");
+
     if ( ( fd = connect_pipe( pPipePath ) ) >= 0 )
     {
         rtl_uString *pCwdPath = NULL;
         osl_getProcessWorkingDir( &pCwdPath );
 
+        fprintf (stderr, "send args !\n");
+
         bSentArgs = send_args( fd, pCwdPath );
     }
 #if OSL_DEBUG_LEVEL > 0
@@ -840,12 +1005,21 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
         ustr_debug( "Failed to connect to pipe", pPipePath );
 #endif
 
-    if ( !bSendAndReport && !bSentArgs )
+    if ( !bSentArgs )
     {
-        /* we have to exec the binary */
+        /* we have to prepare for, and exec the binary */
         do {
-            if ( !fork_app( pAppPath, &status_fd ) )
-                return 1;
+            /* sanity check pieces */
+            system_checks();
+
+            /* create pipe */
+            if ( pipe( status_pipe ) < 0 )
+            {
+                fprintf( stderr, "ERROR: no file handles\n");
+                exit( 1 );
+            }
+            int status_fd = status_pipe[0];
+            osl_createThread( fork_app_thread, NULL );
 
             if ( !bInhibitSplash )
             {
@@ -861,6 +1035,9 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
             }
 
             close( status_fd );
+
+            fprintf (stderr, "sleep!\n");
+            sleep (100);
         } while ( eResult == ProgressRestart );
     }
 
@@ -870,7 +1047,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
 
     close( fd );
 
-    return bSendAndReport? !bSentArgs : 0;
+    return 0;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list