diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
index 1672175..9e931db 100644
--- desktop/inc/app.hxx
+++ desktop/inc/app.hxx
@@ -114,6 +114,7 @@ class Desktop : public Application
 								~Desktop();
 		virtual void			Main( );
 		virtual void			Init();
+		virtual void			InitFinished();
 		virtual void			DeInit();
 		virtual BOOL			QueryExit();
 		virtual USHORT			Exception(USHORT nError);
diff --git a/desktop/prj/build.lst b/desktop/prj/build.lst
index 3b3f0c8..012a82c 100644
--- desktop/prj/build.lst
+++ desktop/prj/build.lst
@@ -14,6 +14,8 @@ dt	desktop\win32\source\setup				nmake	-	w	dt_setup dt_inc NULL
 dt	desktop\win32\source\officeloader		nmake	-	w	dt_officeloader dt_inc NULL
 dt	desktop\win32\source\applauncher		nmake	-	w	dt_applauncher dt_inc NULL
 dt	desktop\win32\source\applauncher\ooo	nmake	-	w	dt_applauncher_ooo dt_applauncher.w 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 NULL
 dt	desktop\source\pkgchk					nmake	-	all	dt_pkgchk NULL
@@ -32,5 +34,5 @@ dt	desktop\source\deployment\registry\component		nmake	-	all	dt_dp_registry_comp
 dt	desktop\source\deployment\registry\configuration	nmake	-	all	dt_dp_registry_configuration dt_inc NULL
 dt	desktop\scripts 						nmake	-	u	dt_scripts dt_inc NULL
 dt	desktop\macosx\source					nmake	-	u	dt_macosx_icons         dt_inc NULL
-dt	desktop\util							nmake	-	all	dt_util dt_app dt_so_comp dt_spl dt_wrapper.w dt_officeloader.w dt_migr dt_macosx_icons.u NULL
+dt	desktop\util							nmake	-	all	dt_util dt_app dt_so_comp dt_spl dt_uwrapper.u dt_usplash.u dt_wrapper.w dt_officeloader.w dt_migr dt_macosx_icons.u NULL
 dt	desktop\zipintro							nmake	-	all	dt_zipintro NULL
diff --git a/desktop/prj/d.lst b/desktop/prj/d.lst
index ebfc739..b550b26 100644
--- desktop/prj/d.lst
+++ desktop/prj/d.lst
@@ -7,6 +7,7 @@ mkdir: %_DEST%\bin%_EXT%\remote2
 ..\%__SRC%\bin\soffice.bin %_DEST%\bin%_EXT%\soffice.bin
 ..\%__SRC%\bin\officeloader.exe %_DEST%\bin%_EXT%\soffice.exe
 ..\%__SRC%\bin\soffice %_DEST%\bin%_EXT%\soffice.bin
+..\%__SRC%\bin\oosplash %_DEST%\bin%_EXT%\oosplash.bin
 
 ..\%__SRC%\bin\soffice_oo.exe %_DEST%\bin%_EXT%\soffice_oo.exe
 ..\%__SRC%\bin\soffice_so.exe %_DEST%\bin%_EXT%\soffice_so.exe
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh
index 7fd1393..20936bd 100644
--- desktop/scripts/soffice.sh
+++ desktop/scripts/soffice.sh
@@ -262,6 +262,10 @@ else
 fi
 export PATH
 
+# test for availability of the fast external splash
+if [ "$sd_binary" = "soffice.bin" -a -x "$sd_prog/oosplash.bin" ] ; then
+    sd_binary="oosplash.bin"
+fi
 
 # execute soffice binary
 "$sd_prog/$sd_binary" "$@" &
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index faeafe5..681b6c6 100644
--- desktop/source/app/app.cxx
+++ desktop/source/app/app.cxx
@@ -660,6 +660,13 @@ void Desktop::Init()
     }
 }
 
+void Desktop::InitFinished()
+{
+    RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::InitFinished" );
+
+    CloseSplashScreen();
+}
+
 void Desktop::DeInit()
 {
     RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::DeInit" );
@@ -1337,6 +1344,7 @@ void Desktop::Main()
     OpenSplashScreen();
     RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main } OpenSplashScreen" );
 
+    SetSplashScreenProgress(10);
     {
         UserInstall::UserInstallError instErr_fin = UserInstall::finalize();
         if ( instErr_fin != UserInstall::E_None)
@@ -1352,7 +1360,7 @@ void Desktop::Main()
         }
         // refresh path information
         utl::Bootstrap::reloadData();
-        SetSplashScreenProgress(25);
+        SetSplashScreenProgress(20);
     }
 
     Reference< XMultiServiceFactory > xSMgr =
@@ -1365,7 +1373,7 @@ void Desktop::Main()
     {
         RegisterServices( xSMgr );
 
-        //SetSplashScreenProgress(15);
+        SetSplashScreenProgress(25);
 
 #ifndef UNX
         if ( pCmdLineArgs->IsHelp() ) {
@@ -1403,7 +1411,7 @@ void Desktop::Main()
         //  Read the common configuration items for optimization purpose
         if ( !InitializeConfiguration() ) return;
 
-        //SetSplashScreenProgress(20);
+        SetSplashScreenProgress(30);
 
         // set static variable to enabled/disable crash reporter
         retrieveCrashReporterState();
@@ -1464,10 +1472,10 @@ void Desktop::Main()
 #endif
 
         SetDisplayName( aTitle );
-//        SetSplashScreenProgress(30);
+        SetSplashScreenProgress(35);
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create SvtPathOptions and SvtLanguageOptions" );
         pPathOptions = new SvtPathOptions;
-//        SetSplashScreenProgress(40);
+        SetSplashScreenProgress(40);
 //        pLanguageOptions = new SvtLanguageOptions(sal_True);
 //        SetSplashScreenProgress(45);
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create SvtPathOptions and SvtLanguageOptions" );
@@ -1548,7 +1556,7 @@ void Desktop::Main()
                 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
             if (xDesktopFrame.is())
             {
-//                SetSplashScreenProgress(60);
+                SetSplashScreenProgress(60);
                 Reference< XFrame > xBackingFrame;
                 Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
 
@@ -1564,7 +1572,7 @@ void Desktop::Main()
                     Reference< XController > xBackingComp(
                         xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs),
                         UNO_QUERY);
-//                    SetSplashScreenProgress(80);
+                    SetSplashScreenProgress(80);
                     if (xBackingComp.is())
                     {
                         Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
@@ -1607,7 +1615,7 @@ void Desktop::Main()
         return;
     }
     */
-//    SetSplashScreenProgress(55);
+    SetSplashScreenProgress(55);
 
     SvtFontSubstConfig().Apply();
 
@@ -1616,7 +1624,7 @@ void Desktop::Main()
 	aAppearanceCfg.SetApplicationDefaults( this );
 	SvtAccessibilityOptions aOptions;
 	aOptions.SetVCLSettings();
-//    SetSplashScreenProgress(60);
+    SetSplashScreenProgress(60);
 
 	Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
 
@@ -1639,7 +1647,7 @@ void Desktop::Main()
     // use system window dialogs
     Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG );
 
-//    SetSplashScreenProgress(80);
+    SetSplashScreenProgress(80);
 
     if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() )
         InitializeQuickstartMode( xSMgr );
@@ -2908,14 +2916,18 @@ void Desktop::OpenSplashScreen()
         else if ( pCmdLine->IsWeb() )
             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "web" ));
 
+        // Which splash to use
+        OUString aSplashService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.SplashScreen" ));
+        if ( pCmdLine->GetStringParam( CommandLineArgs::CMD_STRINGPARAM_SPLASHPIPE ).getLength() )
+            aSplashService = OUString::createFromAscii("com.sun.star.office.PipeSplashScreen");
+
         bVisible = sal_True;
         Sequence< Any > aSeq( 2 );
         aSeq[0] <<= bVisible;
         aSeq[1] <<= aAppName;
         m_rSplashScreen = Reference<XStatusIndicator>(
             comphelper::getProcessServiceFactory()->createInstanceWithArguments(
-            OUString::createFromAscii("com.sun.star.office.SplashScreen"),
-            aSeq), UNO_QUERY);
+            aSplashService, aSeq), UNO_QUERY);
 
         if(m_rSplashScreen.is())
                 m_rSplashScreen->start(OUString::createFromAscii("SplashScreen"), 100);
diff --git a/desktop/source/app/cmdlineargs.cxx b/desktop/source/app/cmdlineargs.cxx
index ab02af5..5658050 100644
--- desktop/source/app/cmdlineargs.cxx
+++ desktop/source/app/cmdlineargs.cxx
@@ -420,6 +420,11 @@ sal_Bool CommandLineArgs::InterpretCommandLineParameter( const ::rtl::OUString&
 		SetBoolParam_Impl( CMD_BOOLPARAM_HELPMATH, sal_True );
 		return sal_True;
 	}
+    else if ( aArgStr.Copy(0, 13).EqualsIgnoreCaseAscii( "-splash-pipe=" ))
+    {
+		AddStringListParam_Impl( CMD_STRINGPARAM_SPLASHPIPE, aArgStr.Copy( 13 ) );
+		return sal_True;
+    }
     else if ( aArgStr.Copy(0, 8).EqualsIgnoreCaseAscii( "-accept=" ))
     {
 		AddStringListParam_Impl( CMD_STRINGPARAM_ACCEPT, aArgStr.Copy( 8 ) );
@@ -875,7 +880,9 @@ sal_Bool CommandLineArgs::IsEmptyOrAcceptOnly() const
 {
     osl::MutexGuard  aMutexGuard( m_aMutex );
 
-    return m_bEmpty || ( ( m_nArgumentCount == 1 ) && ( m_aStrParams[ CMD_STRINGPARAM_ACCEPT ].getLength() ) );
+    return m_bEmpty ||
+        ( ( m_nArgumentCount == 1 ) && ( m_aStrParams[ CMD_STRINGPARAM_SPLASHPIPE ].getLength() ) ) ||
+        ( ( m_nArgumentCount == 1 ) && ( m_aStrParams[ CMD_STRINGPARAM_ACCEPT ].getLength() ) );
 }
 
 } // namespace desktop
diff --git a/desktop/source/app/cmdlineargs.hxx b/desktop/source/app/cmdlineargs.hxx
index 877a909..83f1c67 100644
--- desktop/source/app/cmdlineargs.hxx
+++ desktop/source/app/cmdlineargs.hxx
@@ -90,6 +90,7 @@ class CommandLineArgs
 		enum StringParam // must be zero based!
 		{
 			CMD_STRINGPARAM_PORTAL,
+			CMD_STRINGPARAM_SPLASHPIPE,
 			CMD_STRINGPARAM_ACCEPT,
 			CMD_STRINGPARAM_UNACCEPT,
 			CMD_STRINGPARAM_USERDIR,
diff --git a/desktop/source/splash/makefile.mk b/desktop/source/splash/makefile.mk
index 36b7638..5be3d9d 100644
--- desktop/source/splash/makefile.mk
+++ desktop/source/splash/makefile.mk
@@ -86,7 +86,7 @@ $(SLO)$/splash.obj : $(INCCOM)$/introbmpnames.hxx
 
 .INCLUDE .IGNORE : $(MISC)$/intro_bmp_names.mk
 
-.IF "$(INTO_BITMAPS:f)"!="$(LASTTIME_INTRO_BITMAPS)"
+.IF "$(INTRO_BITMAPS:f)"!="$(LASTTIME_INTRO_BITMAPS)"
 DO_PHONY=.PHONY
 .ENDIF			# "$(INTRO_BITMAPS:f)"!="$(LASTTIME_INTRO_BITMAPS)"
 
diff --git a/desktop/unx/source/makefile.mk b/desktop/unx/source/makefile.mk
new file mode 100644
index 0000000..e609303
--- /dev/null
+++ desktop/unx/source/makefile.mk
@@ -0,0 +1,38 @@
+PRJ=..$/..
+PRJNAME=desktop
+TARGET=oosplash
+
+NO_DEFAULT_STL=TRUE
+
+.INCLUDE :  settings.mk
+
+STDLIB=
+
+OBJFILES= \
+	$(OBJ)$/splashx.obj \
+	$(OBJ)$/start.obj
+
+APP1TARGET = $(TARGET)
+APP1OBJS   = $(OBJFILES)
+APP1LIBSALCPPRT=
+APP1CODETYPE = C
+APP1STDLIBS = $(SALLIB) -lX11
+.IF "$(OS)"=="SOLARIS"
+APP1STDLIBS+= -lsocket
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE :	target.mk
+
+$(OBJ)$/start.obj : $(INCCOM)$/introbmpnames.hxx
+
+.INCLUDE .IGNORE : $(MISC)$/intro_bmp_names.mk
+
+.IF "$(INTRO_BITMAPS:f)"!="$(LASTTIME_INTRO_BITMAPS)"
+DO_PHONY=.PHONY
+.ENDIF			# "$(INTRO_BITMAPS:f)"!="$(LASTTIME_INTRO_BITMAPS)"
+
+$(INCCOM)$/introbmpnames.hxx $(DO_PHONY):
+	echo const char INTRO_BITMAP_STRINGLIST[]=$(EMQ)"$(INTRO_BITMAPS:f:t",")$(EMQ)"$(EMQ); > $@
+	echo LASTTIME_INTRO_BITMAPS=$(INTRO_BITMAPS:f) > $(MISC)$/intro_bmp_names.mk
diff --git a/desktop/unx/source/splashx.c b/desktop/unx/source/splashx.c
new file mode 100644
index 0000000..b3b6da0
--- /dev/null
+++ desktop/unx/source/splashx.c
@@ -0,0 +1,570 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile$
+ *
+ *  $Revision: 9695 $
+ *
+ *  last change: $Author: jholesovsky $ $Date: 2007-07-03 16:36:09 +0200 (Út, 03 čec 2007) $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library 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 for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+
+#include "osl/endian.h"
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "splashx.h"
+
+typedef struct {
+    unsigned char b, g, r;
+} color_t;
+
+#define WINDOW_WIDTH  440
+#define WINDOW_HEIGHT 299
+
+#define PROGRESS_XOFFSET 12
+#define PROGRESS_YOFFSET 18
+#define PROGRESS_BARSPACE 2
+
+static Display *display = NULL;
+static int screen;
+static int depth;
+static Visual *visual = NULL;
+
+static int width = WINDOW_WIDTH;
+static int height = WINDOW_HEIGHT;
+
+static Colormap color_map;
+static Window win;
+static GC gc;
+
+// Progress bar values
+// taken from desktop/source/splash/splash.cxx
+static int tlx = 212;
+static int tly = 216;
+static int barwidth = 263;
+static int barheight = 8;
+static int barspace = PROGRESS_BARSPACE;
+static color_t barcol = { 18, 202, 157 };
+static color_t framecol = { 0xD3, 0xD3, 0xD3 };
+
+static XColor barcolor;
+static XColor framecolor;
+
+static color_t *bitmap = NULL;
+
+#define BMP_HEADER_LEN 14
+#define WIN_INFO_LEN 40
+
+#define UINT8( x )      ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) )
+
+#define UINT16( x ) (   ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) ) + \
+                      ( ( (unsigned int)( ( (uint8_t *)( x ) )[1] ) ) << 8 ) )
+
+#define UINT32( x ) (   ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) ) + \
+                      ( ( (unsigned int)( ( (uint8_t *)( x ) )[1] ) ) << 8  ) + \
+                      ( ( (unsigned int)( ( (uint8_t *)( x ) )[2] ) ) << 16 ) + \
+                      ( ( (unsigned int)( ( (uint8_t *)( x ) )[3] ) ) << 24 ) )
+
+#define MAX( x, y ) ( ( (x) > (y) )? (x): (y) )
+
+#define LOAD_FAILURE( msg ) \
+    { \
+        fprintf( stderr, "%s: " msg, filename ); \
+        close( fd ); \
+        return 0; \
+    }
+
+// Load the specified Windows 24bit BMP to 'bitmap'
+// Return: 1 - success, 0 - failure
+int splash_load_bmp( char *filename )
+{
+    int fd = open( filename, O_RDONLY );
+    if ( fd < 0 )
+        return 0;
+
+    char file_header[ BMP_HEADER_LEN ];
+
+    if ( read( fd, file_header, BMP_HEADER_LEN ) != BMP_HEADER_LEN || file_header[0] != 'B' || file_header[1] != 'M' )
+        LOAD_FAILURE( "Not a bitmap.\n" );
+
+    int file_size = UINT32( file_header + 2 );
+
+    char info_header[ WIN_INFO_LEN ];
+    if ( read( fd, info_header, 4 ) != 4 )
+        LOAD_FAILURE( "Unable to read the header.\n" );
+
+    int header_size = UINT32( info_header );
+    if ( header_size != WIN_INFO_LEN )
+        LOAD_FAILURE( "Not a Windows bitmap.\n" );
+
+    if ( read( fd, info_header + 4, WIN_INFO_LEN - 4 ) != WIN_INFO_LEN - 4 )
+        LOAD_FAILURE( "The header ended too early.\n" );
+
+    width = UINT32( info_header + 4 );
+    height = UINT32( info_header + 8 );
+
+    int bits = UINT16( info_header + 14 );
+    int compression = UINT16( info_header + 16 );
+
+    if ( bits != 24 )
+        LOAD_FAILURE( "Just 24 bpp bitmaps are supported.\n" );
+
+    if ( compression != 0 )
+        LOAD_FAILURE( "Just uncompressed bitmaps are supported.\n" );
+
+    size_t bitmap_size = width * height * 3;
+    bitmap = malloc( bitmap_size );
+    if ( bitmap == NULL )
+        LOAD_FAILURE( "Cannot allocate memory for the data.\n" );
+
+    if ( read( fd, bitmap, bitmap_size ) != bitmap_size )
+        LOAD_FAILURE( "Cannot read the bitmap data.\n" );
+
+    close( fd );
+    return 1;
+}
+
+static void setup_color( int val[3], color_t *col )
+{
+    if ( val[0] < 0 || val[1] < 0 || val[2] < 0 )
+        return;
+
+#define CONVERT_COLOR( from,to ) if ( from < 0 ) to = 0; else if ( from > 255 ) to = 255; else to = from;
+    CONVERT_COLOR( val[0], col->r );
+    CONVERT_COLOR( val[1], col->g );
+    CONVERT_COLOR( val[2], col->b );
+#undef CONVERT_COLOR
+}
+
+// setup
+void splash_setup( int barc[3], int framec[3], int posx, int posy, int w, int h )
+{
+    if ( width <= 500 )
+    {
+        barwidth  = width - ( 2 * PROGRESS_XOFFSET );
+        barheight = 6;
+        tlx = PROGRESS_XOFFSET;
+        tly = height - PROGRESS_YOFFSET;
+
+        barcol.r = 0;
+        barcol.g = 0;
+        barcol.b = 128;
+    }
+
+    if ( posx >= 0 )
+        tlx = posx;
+    if ( posy >= 0 )
+        tly = posy;
+    if ( w >= 0 )
+        barwidth = w;
+    if ( h >= 0 )
+        barheight = h;
+
+    setup_color( barc, &barcol );
+    setup_color( framec, &framecol );
+}
+
+// Universal shift: bits >= 0 - left, otherwise right
+#define SHIFT( x, bits ) ( ( (bits) >= 0 )? ( (x) << (bits) ): ( (x) >> -(bits) ) )
+
+// Position of the highest bit (more or less integer log2)
+inline int HIGHEST_BIT( unsigned long x )
+{
+    int i = 0;
+    for ( ; x; ++i )
+        x >>= 1;
+
+    return i;
+}
+
+// Number of bits set to 1
+inline int BITS( unsigned long x )
+{
+    int i = 0;
+    for ( ; x; x >>= 1 )
+        if ( x & 1UL )
+            ++i;
+
+    return i;
+}
+
+// Set 'bitmap' as the background of our 'win' window
+static void create_pixmap()
+{
+    if ( !bitmap )
+        return;
+
+    Pixmap pixmap = XCreatePixmap( display, win, width, height, depth );
+
+    unsigned long value_mask = 0;
+    XGCValues values;
+    GC pixmap_gc = XCreateGC( display, pixmap, value_mask, &values );
+
+    if ( visual->class == TrueColor )
+    {
+        unsigned long red_mask   = visual->red_mask;
+        unsigned long green_mask = visual->green_mask;
+        unsigned long blue_mask  = visual->blue_mask;
+
+        unsigned long red_delta_mask   = ( 1UL << ( 8 - BITS( red_mask ) ) ) - 1;
+        unsigned long green_delta_mask = ( 1UL << ( 8 - BITS( green_mask ) ) ) - 1;
+        unsigned long blue_delta_mask  = ( 1UL << ( 8 - BITS( blue_mask ) ) ) - 1;
+
+        int red_shift   = HIGHEST_BIT( red_mask ) - 8;
+        int green_shift = HIGHEST_BIT( green_mask ) - 8;
+        int blue_shift  = HIGHEST_BIT( blue_mask ) - 8;
+
+        XImage *image = XCreateImage( display, visual, depth, ZPixmap,
+                0, NULL, width, height, 32, 0 );
+
+        int bytes_per_line = image->bytes_per_line;
+        int bpp = image->bits_per_pixel;
+        int byte_order = image->byte_order;
+        int machine_byte_order;
+#if defined( _LITTLE_ENDIAN )
+        machine_byte_order = LSBFirst;
+#elif defined( _BIG_ENDIAN )
+        machine_byte_order = MSBFirst;
+#else
+        {
+            fprintf( stderr, "Unsupported machine endianity.\n" );
+            XFreeGC( display, pixmap_gc );
+            XFreePixmap( display, pixmap );
+            XDestroyImage( image );
+            return;
+        }
+#endif
+
+        char *data = malloc( height * bytes_per_line );
+        image->data = data;
+
+        // The following dithers & converts the color_t color to one
+        // acceptable for the visual
+#define COPY_IN_OUT( pix_size, code ) \
+        { \
+            out += pix_size * width * ( height - 1 ); \
+            int x, y; \
+            for ( y = 0; y < height; ++y ) \
+            { \
+                unsigned long red_delta = 0, green_delta = 0, blue_delta = 0; \
+                for ( x = 0; x < width; ++x, ++in  ) \
+                { \
+                    unsigned long red   = in->r + red_delta; \
+                    unsigned long green = in->g + green_delta; \
+                    unsigned long blue  = in->b + blue_delta; \
+                    red_delta = red & red_delta_mask; \
+                    green_delta = green & green_delta_mask; \
+                    blue_delta = blue & blue_delta_mask; \
+                    if ( red > 255 ) \
+                        red = 255; \
+                    if ( green > 255 ) \
+                        green = 255; \
+                    if ( blue > 255 ) \
+                        blue = 255; \
+                    unsigned long pixel = \
+                        ( SHIFT( red, red_shift ) & red_mask ) | \
+                        ( SHIFT( green, green_shift ) & green_mask ) | \
+                        ( SHIFT( blue, blue_shift ) & blue_mask ); \
+                    code \
+                } \
+                out -= 2 * pix_size * width; \
+            } \
+        }
+
+        color_t *in = bitmap;
+        char *out = data;
+
+        if ( bpp == 32 )
+        {
+            if ( machine_byte_order == byte_order )
+                COPY_IN_OUT( 4, *( (uint32_t *)out ) = (uint32_t)pixel; out += 4; )
+            else
+                COPY_IN_OUT( 4, uint32_t tmp = pixel;
+                             *( (uint8_t *)out     ) = *( (uint8_t *)(&tmp) + 3 );
+                             *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
+                             *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 1 );
+                             *( (uint8_t *)out + 3 ) = *( (uint8_t *)(&tmp)     );
+                             out += 4; )
+        }
+        else if ( bpp == 24 )
+        {
+            if ( machine_byte_order == byte_order && byte_order == LSBFirst )
+                COPY_IN_OUT( 3, *( (color_t *)out ) = *( (color_t *)( &pixel ) ); out += 3; )
+            if ( machine_byte_order == byte_order && byte_order == MSBFirst )
+                COPY_IN_OUT( 3, uint32_t tmp = pixel;
+                             *( (uint8_t *)out     ) = *( (uint8_t *)(&tmp) + 1 );
+                             *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
+                             *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 3 );
+                             out += 3; )
+            else
+                COPY_IN_OUT( 3, uint32_t tmp = pixel;
+                             *( (uint8_t *)out     ) = *( (uint8_t *)(&tmp) + 3 );
+                             *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
+                             *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 1 );
+                             out += 3; )
+        }
+        else if ( bpp == 16 )
+        {
+            if ( machine_byte_order == byte_order )
+                COPY_IN_OUT( 2, *( (uint16_t *)out ) = (uint16_t)pixel; out += 2; )
+            else
+                COPY_IN_OUT( 2, uint16_t tmp = pixel;
+                             *( (uint8_t *)out     ) = *( (uint8_t *)(&tmp) + 1 );
+                             *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp)     );
+                             out += 2; );
+        }
+        else if ( bpp == 8 )
+        {
+            COPY_IN_OUT( 1, *( (uint8_t *)out ) = (uint8_t)pixel; ++out; )
+        }
+        else
+        {
+            fprintf( stderr, "Unsupported depth: %d bits per pixel.\n", bpp );
+            XFreeGC( display, pixmap_gc );
+            XFreePixmap( display, pixmap );
+            XDestroyImage( image );
+            return;
+        }
+
+#undef COPY_IN_OUT
+
+        XPutImage( display, pixmap, pixmap_gc, image, 0, 0, 0, 0, width, height );
+        XDestroyImage( image );
+    }
+    else //if ( depth == 1 || visual->class == DirectColor )
+    {
+        // FIXME Something like the following, but faster ;-) - XDrawPoint is not
+        // a good idea...
+        int x, y;
+        for ( y = 0; y < height; ++y )
+        {
+            color_t *color = bitmap + y * width;
+
+            int delta = 0;
+            for ( x = 0; x < width; ++x, ++color )
+            {
+                int rnd = (int)( ( (long)( random() - RAND_MAX/2 ) * 32000 )/RAND_MAX );
+                int luminance = delta + rnd + 299 * (int)color->r + 587 * (int)color->g + 114 * (int)color->b;
+
+                if ( luminance < 128000 )
+                {
+                    XSetForeground( display, pixmap_gc, BlackPixel( display, screen ) );
+                    delta = luminance;
+                }
+                else
+                {
+                    XSetForeground( display, pixmap_gc, WhitePixel( display, screen ) );
+                    delta = luminance - 255000;
+                }
+
+                XDrawPoint( display, pixmap, pixmap_gc, x, y );
+            }
+        }
+    }
+
+    XSetWindowBackgroundPixmap( display, win, pixmap );
+
+    XFreeGC( display, pixmap_gc );
+    XFreePixmap( display, pixmap );
+}
+
+// The old method of hiding the window decorations
+static void suppress_decorations_motif()
+{
+    struct {
+        unsigned long flags, functions, decorations;
+        long input_mode;
+        unsigned long status;
+    } mwmhints;
+
+    Atom a = XInternAtom( display, "_MOTIF_WM_HINTS", False );
+
+    mwmhints.flags = 15; // functions, decorations, input_mode, status
+    mwmhints.functions = 2; // ?
+    mwmhints.decorations = 0;
+    mwmhints.input_mode = 0;
+
+    XChangeProperty( display, win, a, a, 32,
+            PropModeReplace, (unsigned char*)&mwmhints, 5 );
+}
+
+// This is a splash, set it as such.
+// If it fails, just hide the decorations...
+static void suppress_decorations()
+{
+    Atom atom_type = XInternAtom( display, "_NET_WM_WINDOW_TYPE", True );
+    Atom atom_splash = XInternAtom( display, "_NET_WM_WINDOW_TYPE_SPLASH", True );
+
+    if ( atom_type != None && atom_splash != None )
+        XChangeProperty( display, win, atom_type, XA_ATOM, 32,
+                PropModeReplace, (unsigned char*)&atom_splash, 1 );
+    //else
+        suppress_decorations_motif(); // FIXME: Unconditional until Metacity/compiz's SPLASH handling is fixed
+}
+
+// Create the window
+// Return: 1 - success, 0 - failure
+int splash_create_window( int argc, char** argv )
+{
+    char *display_name = NULL;
+    int i;
+    for ( i = 0; i < argc; i++ )
+    {
+        if ( !strcmp( argv[i], "-display" )  || !strcmp( argv[i], "--display" ) )
+            display_name = ( i + 1 < argc )? argv[i+1]: NULL;
+    }
+
+    if ( !display_name )
+        display_name = getenv( "DISPLAY" );
+
+    // init display
+    display = XOpenDisplay( display_name );
+    if ( !display )
+    {
+        fprintf( stderr, "Failed to open display\n" );
+        return 0;
+    }
+
+    // create the window
+    screen = DefaultScreen( display );
+    depth = DefaultDepth( display, screen );
+    color_map = DefaultColormap( display, screen );
+    visual = DefaultVisual( display, screen );
+
+    Window root_win = RootWindow( display, screen );
+    int display_width = DisplayWidth( display, screen );
+    int display_height = DisplayHeight( display, screen );
+
+    win = XCreateSimpleWindow( display, root_win,
+            ( display_width - width ) / 2, ( display_height - height ) / 2,
+            width, height, 0,
+            BlackPixel( display, screen ), BlackPixel( display, screen ) );
+
+    XSetWindowColormap( display, win, color_map );
+
+    // setup colors
+#define FILL_COLOR( xcol,col ) xcol.red = 256*col.r; xcol.green = 256*col.g; xcol.blue = 256*col.b;
+    FILL_COLOR( barcolor, barcol );
+    FILL_COLOR( framecolor, framecol );
+#undef FILL_COLOR
+
+    XAllocColor( display, color_map, &barcolor );
+    XAllocColor( display, color_map, &framecolor );
+
+    // not resizable, no decorations, etc.
+    unsigned long value_mask = 0;
+    XGCValues values;
+    gc = XCreateGC( display, win, value_mask, &values );
+
+    XSizeHints size_hints;
+    size_hints.flags = PPosition | PSize | PMinSize | PMaxSize;
+    size_hints.min_width = width;
+    size_hints.max_width = width;
+    size_hints.min_height = height;
+    size_hints.max_height = height;
+
+    char *name = "OpenOffice.org";
+    char *icon = "icon"; // FIXME
+
+    XSetStandardProperties( display, win, name, icon, None,
+            0, 0, &size_hints );
+
+    // the actual work
+    suppress_decorations();
+    create_pixmap();
+
+    // show it
+    XSelectInput( display, win, 0 );
+    XMapWindow( display, win );
+
+    return 1;
+}
+
+// Re-draw & process the events
+// Just throwing them away - we do not need anything more...
+static void process_events()
+{
+    XEvent xev;
+    int num_events;
+
+    XFlush( display );
+    num_events = XPending( display );
+    while ( num_events > 0 )
+    {
+        num_events--;
+        XNextEvent( display, &xev );
+        //process_event(xev);
+    }
+}
+
+// Draw the progress
+void splash_draw_progress( int progress )
+{
+    // sanity
+    if ( progress < 0 )
+        progress = 0;
+    if ( progress > 100 )
+        progress = 100;
+
+    // draw progress...
+    int length = ( progress * barwidth / 100 ) - ( 2 * barspace );
+    if ( length < 0 )
+        length = 0;
+
+    // border
+    XSetForeground( display, gc, framecolor.pixel );
+    XDrawRectangle( display, win, gc,
+            tlx, tly,
+            barwidth, barheight );
+
+    // progress bar
+    XSetForeground( display, gc, barcolor.pixel );
+    XFillRectangle( display, win, gc,
+            tlx + barspace, tly + barspace,
+            length + 1, barheight - 2*barspace + 1 );
+
+    // pending events
+    process_events();
+}
+
+// Close the window & cleanup
+void splash_close_window()
+{
+    XCloseDisplay( display );
+
+    free( bitmap );
+    bitmap = NULL;
+}
diff --git a/desktop/unx/source/splashx.h b/desktop/unx/source/splashx.h
new file mode 100644
index 0000000..6d84d4b
--- /dev/null
+++ desktop/unx/source/splashx.h
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile$
+ *
+ *  $Revision: 9695 $
+ *
+ *  last change: $Author: jholesovsky $ $Date: 2007-07-03 16:36:09 +0200 (Út, 03 čec 2007) $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library 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 for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#ifndef _SPLASHX_H
+#define _SPLASHX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Load the specified Windows 24bit BMP we can have as a background of the
+// splash.
+//
+// Note: Must be called before the create_window(), otherwise there will be no
+// image in the splash, just black rectangle.
+//
+// Return: 1 - success, 0 - failure (non-existing, etc.)
+int splash_load_bmp( char *filename );
+
+// Init some of the values
+// If not called, the defaults are used
+// barc, framec - colors, posx, posy - position, w, h - size
+void splash_setup( int barc[3], int framec[3], int posx, int posy, int w, int h );
+
+// Create the splash window
+// Return: 1 - success, 0 - failure
+int splash_create_window( int argc, char** argv );
+
+// Destroy the splash window
+void splash_close_window();
+
+// Update the progress bar
+void splash_draw_progress( int progress );
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _SPLASHX_H
diff --git a/desktop/unx/source/start.c b/desktop/unx/source/start.c
new file mode 100644
index 0000000..2317efe
--- /dev/null
+++ desktop/unx/source/start.c
@@ -0,0 +1,717 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile$
+ *
+ *  $Revision: 9695 $
+ *
+ *  last change: $Author: jholesovsky $ $Date: 2007-07-03 16:36:09 +0200 (Út, 03 čec 2007) $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library 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 for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#include <signal.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <sys/poll.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <libgen.h>
+
+#include <osl/nlsupport.h>
+#include <osl/process.h>
+#include <rtl/bootstrap.h>
+#include <rtl/digest.h>
+#include <sal/main.h>
+
+#include "splashx.h"
+#include <introbmpnames.hxx>
+
+#define PIPEDEFAULTPATH      "/tmp"
+#define PIPEALTERNATEPATH    "/var/tmp"
+
+/* Easier conversions: rtl_uString to rtl_String */
+static rtl_String *
+ustr_to_str( rtl_uString *pStr )
+{
+    rtl_String *pOut = NULL;
+
+    rtl_uString2String( &pOut, rtl_uString_getStr( pStr ),
+            rtl_uString_getLength( pStr ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
+
+    return pOut;
+}
+
+/* Easier conversions: char * to rtl_uString */
+static rtl_uString *
+charp_to_ustr( const char *pStr )
+{
+    rtl_uString *pOut = NULL;
+
+    rtl_string2UString( &pOut, pStr, strlen( pStr ), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
+
+    return pOut;
+}
+
+/* Easier debugging of rtl_uString values. */
+#if OSL_DEBUG_LEVEL > 0
+static void
+ustr_debug( const char *pMessage, rtl_uString *pStr )
+{
+    rtl_String *pOut = ustr_to_str( pStr );
+
+    fprintf( stderr, "%s: %s\n", pMessage, rtl_string_getStr( pOut ) );
+
+    rtl_string_release( pOut );
+    return;
+}
+#else
+#define ustr_debug( a, b ) {}
+#endif
+
+/* Path of the application. */
+static rtl_uString *
+get_app_path( const char *pAppExec )
+{
+    char pRealPath[PATH_MAX];
+    rtl_uString *pResult;
+
+    char *pPath = strdup( pAppExec );
+    pPath = dirname( pPath );
+
+    realpath( pPath, pRealPath );
+    pResult = charp_to_ustr( pRealPath );
+    free( pPath );
+
+    return pResult;
+}
+
+/* Compute the OOo md5 hash from 'pText' */
+static rtl_uString *
+get_md5hash( rtl_uString *pText )
+{
+    rtl_uString *pResult = NULL;
+    sal_Int32 nCapacity = 100;
+
+    if ( !pText )
+        return NULL;
+
+    unsigned char *pData = (unsigned char *)rtl_uString_getStr( pText );
+    sal_uInt32   nSize = rtl_uString_getLength( pText ) * sizeof( sal_Unicode );
+    if ( !pData )
+        return NULL;
+
+    rtlDigest digest = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+    if ( digest <= 0 )
+        return NULL;
+
+    sal_uInt32 md5_key_len = rtl_digest_queryLength( digest );
+    sal_uInt8 *md5_buf = (sal_uInt8 *)calloc( md5_key_len, sizeof( sal_uInt8 ) );
+
+    rtl_digest_init( digest, pData , nSize );
+    rtl_digest_update( digest, pData, nSize );
+    rtl_digest_get( digest, md5_buf, md5_key_len );
+    rtl_digest_destroy( digest );
+
+    /* create hex-value string from the MD5 value to keep
+       the string size minimal */
+    rtl_uString_new_WithLength( &pResult, nCapacity );
+    sal_uInt32 i = 0;
+    for ( ; i < md5_key_len; ++i )
+    {
+        char val[3];
+        snprintf( val, 3, "%x", md5_buf[i] ); /* sic! we ignore some of the 0's */
+
+        rtl_uStringbuffer_insert_ascii( &pResult, &nCapacity, rtl_uString_getLength( pResult ),
+                val, strlen( val ) );
+    }
+
+    /* cleanup */
+    free( md5_buf );
+
+    return pResult;
+}
+
+/* Construct the pipe name */
+static rtl_uString *
+get_pipe_path( rtl_uString *pAppPath )
+{
+    rtl_uString *pPath = NULL, *pTmp = NULL, *pUserInstallation = NULL;
+    rtl_uString *pResult = NULL;
+
+    /* setup bootstrap filename */
+    rtl_uString_newFromAscii( &pPath, "file://" );
+    rtl_uString_newConcat( &pPath, pPath, pAppPath );
+    rtl_uString_newFromAscii( &pTmp, "/" );
+    rtl_uString_newConcat( &pPath, pPath, pTmp );
+    rtl_uString_newFromAscii( &pTmp, SAL_CONFIGFILE( "bootstrap" ) );
+    rtl_uString_newConcat( &pPath, pPath, pTmp );
+
+    ustr_debug( "bootstap", pPath );
+
+    /* read userinstallation value */
+    rtlBootstrapHandle handle = rtl_bootstrap_args_open( pPath );
+
+    rtl_uString_newFromAscii( &pTmp, "UserInstallation" );
+    rtl_bootstrap_get_from_handle( handle, pTmp, &pUserInstallation, NULL );
+
+    rtl_bootstrap_args_close( handle );
+
+    /* create the pipe name */
+    ustr_debug( "user installation", pUserInstallation );
+    rtl_uString *pMd5hash = get_md5hash( pUserInstallation );
+    if ( !pMd5hash )
+        rtl_uString_new( &pMd5hash );
+
+    if ( access( PIPEDEFAULTPATH, R_OK|W_OK ) == 0 )
+        rtl_uString_newFromAscii( &pResult, PIPEDEFAULTPATH );
+    else
+        rtl_uString_newFromAscii( &pResult, PIPEALTERNATEPATH );
+
+    rtl_uString_newFromAscii( &pTmp, "/OSL_PIPE_" );
+    rtl_uString_newConcat( &pResult, pResult, pTmp );
+
+    sal_Unicode pUnicode[RTL_USTR_MAX_VALUEOFINT32];
+    rtl_ustr_valueOfInt32( pUnicode, (int)getuid(), 10 );
+    rtl_uString_newFromStr( &pTmp, pUnicode );
+    rtl_uString_newConcat( &pResult, pResult, pTmp );
+
+    rtl_uString_newFromAscii( &pTmp, "_SingleOfficeIPC_" );
+    rtl_uString_newConcat( &pResult, pResult, pTmp );
+
+    rtl_uString_newConcat( &pResult, pResult, pMd5hash );
+
+    ustr_debug( "result", pResult );
+
+    /* cleanup */
+    rtl_uString_release( pPath );
+    rtl_uString_release( pTmp );
+    rtl_uString_release( pUserInstallation );
+
+    return pResult;
+}
+
+/* Get fd of the pipe of the already running OOo. */
+static int
+connect_pipe( rtl_uString *pPipePath )
+{
+    int fd;
+    size_t len;
+    struct sockaddr_un addr;
+
+    rtl_String *pPipeStr = ustr_to_str( pPipePath );
+
+    memset( &addr, 0, sizeof( addr ) );
+
+    if ( ( fd = socket( AF_UNIX, SOCK_STREAM, 0 ) ) < 0 )
+        return fd;
+
+    fcntl( fd, F_SETFD, FD_CLOEXEC );
+
+    addr.sun_family = AF_UNIX;
+    strncpy( addr.sun_path, rtl_string_getStr( pPipeStr ), sizeof( addr.sun_path ) );
+    rtl_string_release( pPipeStr );
+
+/* cut / paste from osl's pipe.c */
+#if defined(FREEBSD)
+    len = SUN_LEN( &addr );
+#else
+    len = sizeof( addr );
+#endif
+
+    if ( connect( fd, (struct sockaddr *)&addr, len ) < 0 )
+        return -1;
+
+    return fd;
+}
+
+/* Send args to the OOo instance (using the 'fd' file descriptor) */
+static sal_Bool
+send_args( int fd )
+{
+    rtl_uString *pBuffer = NULL, *pTmp = NULL;
+    sal_Int32 nCapacity = 100;
+    rtl_String *pOut = NULL;
+    sal_Bool bResult;
+    size_t nLen;
+
+    rtl_uString_new_WithLength( &pBuffer, nCapacity );
+    rtl_uString_new( &pTmp );
+
+    sal_uInt32 nArg;
+    sal_uInt32 nArgCount = osl_getCommandArgCount();
+    for ( nArg = 0; nArg < nArgCount; ++nArg )
+    {
+        osl_getCommandArg( nArg, &pTmp );
+
+        rtl_uStringbuffer_insert( &pBuffer, &nCapacity,
+                rtl_uString_getLength( pBuffer ),
+                rtl_uString_getStr( pTmp ),
+                rtl_uString_getLength( pTmp ) );
+
+        rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity,
+                rtl_uString_getLength( pBuffer ),
+                "|", 1 );
+    }
+
+    ustr_debug( "Pass args", pBuffer );
+
+    pOut = ustr_to_str( pBuffer );
+
+    nLen = rtl_string_getLength( pOut ) + 1;
+    bResult = ( write( fd, rtl_string_getStr( pOut ), nLen ) == nLen );
+
+    /* cleanup */
+    rtl_uString_release( pBuffer );
+    rtl_uString_release( pTmp );
+    rtl_string_release( pOut );
+
+    return bResult;
+}
+
+/* Load the splash bitmap. */
+static void
+load_splash_image( rtl_uString *pImagePath )
+{
+    rtl_uString *pPath = NULL, *pBitmaps = NULL, *pTmp = NULL;
+    rtl_uString *pToken = NULL, *pFilename = NULL;
+
+    sal_Int32 nIndex = 0;
+
+    /* setup values */
+    rtl_uString_newFromString( &pPath, pImagePath );
+    rtl_uString_newFromAscii( &pTmp, "/" );
+    rtl_uString_newConcat( &pPath, pPath, pTmp );
+
+    rtl_uString_newFromAscii( &pBitmaps, INTRO_BITMAP_STRINGLIST );
+    rtl_uString_newFromAscii( &pTmp, ",intro.bmp" );
+    rtl_uString_newConcat( &pBitmaps, pBitmaps, pTmp );
+
+    /* try all the bitmaps from INTRO_BITMAP_STRINGLIST
+       (and the intro.bmp fallback) */
+    while ( nIndex >= 0 )
+    {
+        nIndex = rtl_uString_getToken( &pToken, pBitmaps, 0, ',', nIndex );
+        rtl_uString_newConcat( &pFilename, pPath, pToken );
+
+        if ( rtl_uString_getLength( pToken ) > 0 )
+        {
+            rtl_String *pFilenameStr = ustr_to_str( pFilename );
+            sal_Bool bLoaded = splash_load_bmp( rtl_string_getStr( pFilenameStr ) );
+            rtl_string_release( pFilenameStr );
+
+            if ( bLoaded )
+                break;
+        }
+    }
+
+    /* cleanup */
+    rtl_uString_release( pPath );
+    rtl_uString_release( pBitmaps );
+    rtl_uString_release( pTmp );
+    rtl_uString_release( pToken );
+    rtl_uString_release( pFilename );
+}
+
+/* Fill 'array' with values of the key 'name'.
+   Its value is a comma delimited list of integers */
+static void
+get_bootstrap_value( int *array, int size, rtlBootstrapHandle handle, const char *name )
+{
+    rtl_uString *pKey = NULL, *pValue = NULL;
+    sal_Int32 nIndex = 0;
+    int i = 0;
+
+    /* get the value from the ini file */
+    rtl_uString_newFromAscii( &pKey, name );
+    rtl_bootstrap_get_from_handle( handle, pKey, &pValue, NULL );
+
+    /* the value is several numbers delimited by ',' - parse it */
+    if ( rtl_uString_getLength( pValue ) > 0 )
+    {
+        rtl_uString *pToken = NULL;
+
+        for ( ; ( nIndex >= 0 ) && ( i < size ); ++i )
+        {
+            nIndex = rtl_uString_getToken( &pToken, pValue, 0, ',', nIndex );
+            array[i] = rtl_ustr_toInt32( rtl_uString_getStr( pToken ), 10 );
+        }
+
+        rtl_uString_release( pToken );
+    }
+
+    /* cleanup */
+    rtl_uString_release( pKey );
+    rtl_uString_release( pValue );
+}
+
+/* Load the colors and size of the splash. */
+static void
+load_splash_defaults( rtl_uString *pAppPath, sal_Bool *pInhibitSplash )
+{
+    rtl_uString *pSettings = NULL, *pTmp = NULL;
+    rtlBootstrapHandle handle;
+
+    /* costruct the sofficerc file location */
+    rtl_uString_newFromAscii( &pSettings, "file://" );
+    rtl_uString_newConcat( &pSettings, pSettings, pAppPath );
+    rtl_uString_newFromAscii( &pTmp, SAL_CONFIGFILE( "soffice" ) );
+    rtl_uString_newConcat( &pSettings, pSettings, pTmp );
+
+    /* use it as the bootstrap file */
+    handle = rtl_bootstrap_args_open( pSettings );
+
+    int logo[1] =  { -1 },
+        bar[3] =   { -1, -1, -1 },
+        frame[3] = { -1, -1, -1 },
+        pos[2] =   { -1, -1 },
+        size[2] =  { -1, -1 };
+
+    /* get the values */
+    get_bootstrap_value( logo,  1, handle, "Logo" );
+    get_bootstrap_value( bar,   3, handle, "ProgressBarColor" );
+    get_bootstrap_value( frame, 3, handle, "ProgressFrameColor" );
+    get_bootstrap_value( pos,   2, handle, "ProgressPosition" );
+    get_bootstrap_value( size,  2, handle, "ProgressSize" );
+
+    if ( logo[0] == 0 )
+        *pInhibitSplash = sal_True;
+
+    splash_setup( bar, frame, pos[0], pos[1], size[0], size[1] );
+
+    /* cleanup */
+    rtl_bootstrap_args_close( handle );
+    rtl_uString_release( pSettings );
+    rtl_uString_release( pTmp );
+}
+
+#define BUFFER_LEN 255
+
+/* Read the percent to show in splash. */
+static sal_Bool
+read_percent( int status_fd, int *pPercent )
+{
+    static char pBuffer[BUFFER_LEN + 1];
+    static char *pNext = pBuffer;
+    static size_t nRead = 0;
+
+    char *pBegin;
+    char *pIter;
+
+    /* from the last call */
+    int nNotProcessed = nRead - ( pNext - pBuffer );
+    if ( nNotProcessed >= BUFFER_LEN )
+        return sal_False;
+
+    memmove( pBuffer, pNext, nNotProcessed );
+
+    /* read data */
+    nRead = read( status_fd, pBuffer + nNotProcessed, BUFFER_LEN - nNotProcessed );
+    if ( nRead < 0 )
+        return sal_False;
+
+    nRead += nNotProcessed;
+    pBuffer[nRead] = '\0';
+
+    /* skip old data */
+    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 );
+#endif
+    if ( !strncasecmp( pBegin, "end", 3 ) )
+        return sal_False;
+    else if ( sscanf( pBegin, "%d%%", pPercent ) )
+        return sal_True;
+
+    return sal_False;
+}
+
+/* Periodically update the splash & the percent acconding to what
+   status_fd says */
+static void
+show_splash( int status_fd )
+{
+    int nRetval;
+    struct pollfd aPfd;
+
+    int nPercent = 0;
+    sal_Bool bFinish = sal_False;
+
+    /* 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 ( nRetval > 0 )
+            bFinish = !read_percent( status_fd, &nPercent );
+        else if ( nRetval < 0 )
+            bFinish = sal_True;
+    } while ( !bFinish );
+}
+
+/* Simple system check. */
+static void
+system_checks( void )
+{
+#ifdef LINUX
+    struct stat buf;
+
+    /* 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" );
+        exit( 1 );
+    }
+#endif
+}
+
+/* Start the OOo application */
+static sal_Bool
+fork_app( rtl_uString *pAppPath, int *status_fd )
+{
+    rtl_uString *pApp = NULL, *pTmp = NULL, *pArg = NULL;
+    rtl_uString **ppArgs;
+    sal_uInt32 nArgs, i;
+
+    oslProcess aProcess;
+    oslProcessError nError;
+    int status_pipe[2];
+
+    system_checks();
+
+    /* 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 );
+    }
+
+    /* 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 );
+
+    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;
+
+    /* start the OOo process */
+    nError = osl_executeProcess( pApp, ppArgs, nArgs,
+            osl_Process_DETACHED | osl_Process_NORMAL,
+            NULL,
+            NULL,
+            NULL, 0,
+            &aProcess );
+
+    *status_fd = status_pipe[0];
+    close( status_pipe[1] );
+
+    if ( nError != osl_Process_E_None )
+    {
+        fprintf( stderr, "ERROR %d forking process", nError );
+        ustr_debug( "", pApp );
+        return sal_False;
+    }
+
+    return sal_True;
+}
+
+/* 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",
+    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, status_fd = 0;
+    sal_Bool bInhibitSplash;
+    sal_Bool bSentArgs = sal_False;
+    rtl_uString *pAppPath = NULL;
+    rtl_uString *pPipePath = NULL;
+
+    /* turn SIGPIPE into an error */
+    signal( SIGPIPE, SIG_IGN );
+
+    bInhibitSplash = get_inhibit_splash();
+
+    pAppPath = get_app_path( argv[0] );
+    if ( !pAppPath )
+    {
+        fprintf( stderr, "ERROR: Can't read app link\n" );
+        exit( 1 );
+    }
+    ustr_debug( "App path", pAppPath );
+
+    pPipePath = get_pipe_path( pAppPath );
+
+    if ( ( fd = connect_pipe( pPipePath ) ) >= 0 )
+        bSentArgs = send_args( fd );
+#if OSL_DEBUG_LEVEL > 0
+    else
+        ustr_debug( "Failed to connect to pipe", pPipePath );
+#endif
+
+    if ( !bSentArgs )
+    {
+        if ( !fork_app( pAppPath, &status_fd ) )
+            return 1;
+
+        if ( !bInhibitSplash )
+        {
+            load_splash_image( pAppPath );
+            load_splash_defaults( pAppPath, &bInhibitSplash );
+        }
+
+        if ( !bInhibitSplash && splash_create_window( argc, argv ) )
+        {
+            splash_draw_progress( 0 );
+            show_splash( status_fd );
+            splash_close_window();
+        }
+    }
+
+    /* cleanup */
+    rtl_uString_release( pAppPath );
+    rtl_uString_release( pPipePath );
+
+    close( fd );
+    close( status_fd );
+
+    return 0;
+}
diff --git a/desktop/unx/splash/exports.map b/desktop/unx/splash/exports.map
new file mode 100644
index 0000000..c235082
--- /dev/null
+++ desktop/unx/splash/exports.map
@@ -0,0 +1,10 @@
+UDK_3_0_0 {
+    global:
+        GetVersionInfo;
+        component_getImplementationEnvironment;
+        component_getFactory;
+        component_writeInfo;
+
+    local:
+        *;
+};
diff --git a/desktop/unx/splash/makefile.mk b/desktop/unx/splash/makefile.mk
new file mode 100644
index 0000000..4bbe6dd
--- /dev/null
+++ desktop/unx/splash/makefile.mk
@@ -0,0 +1,73 @@
+#*************************************************************************
+#
+#   OpenOffice.org - a multi-platform office productivity suite
+#
+#   $RCSfile$
+#
+#   $Revision: 7305 $
+#
+#   last change: $Author: jholesovsky $ $Date: 2006-08-04 16:35:41 +0200 (Pá, 04 srp 2006) $
+#
+#   The Contents of this file are made available subject to
+#   the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+#     GNU Lesser General Public License Version 2.1
+#     =============================================
+#     Copyright 2005 by Sun Microsystems, Inc.
+#     901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#     This library is free software; you can redistribute it and/or
+#     modify it under the terms of the GNU Lesser General Public
+#     License version 2.1, as published by the Free Software Foundation.
+#
+#     This library 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 for more details.
+#
+#     You should have received a copy of the GNU Lesser General Public
+#     License along with this library; if not, write to the Free Software
+#     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#     MA  02111-1307  USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=spl_unx
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES =  $(SLO)$/unxsplash.obj \
+            $(SLO)$/services_unxsplash.obj
+
+SHL1DEPN=   makefile.mk
+SHL1OBJS=   $(SLOFILES)
+
+
+SHL1TARGET=$(TARGET)$(UPD)$(DLLPOSTFIX)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=exports.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS= \
+	$(VOSLIB)			\
+	$(CPPUHELPERLIB)	\
+	$(CPPULIB)			\
+	$(SALLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/desktop/unx/splash/services_unxsplash.cxx b/desktop/unx/splash/services_unxsplash.cxx
new file mode 100644
index 0000000..c1ee124
--- /dev/null
+++ desktop/unx/splash/services_unxsplash.cxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile$
+ *
+ *  $Revision: 7305 $
+ *
+ *  last change: $Author: jholesovsky $ $Date: 2006-08-04 16:35:41 +0200 (Pá, 04 srp 2006) $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library 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 for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_
+#include <com/sun/star/beans/NamedValue.hpp>
+#endif
+#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATE_HPP_
+#include <com/sun/star/util/Date.hpp>
+#endif
+
+#ifndef _UNO_ENVIRONMENT_H_
+#include <uno/environment.h>
+#endif
+#ifndef _CPPUHELPER_FACTORY_HXX_
+#include <cppuhelper/factory.hxx>
+#endif
+#ifndef _UTL_CONFIGMGR_HXX_
+#include <unotools/configmgr.hxx>
+#endif
+
+#include "unxsplash.hxx"
+
+using namespace rtl;
+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;
+
+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::createFromAscii( "/" )
+              + OUString::createFromAscii( pImplName )
+              + OUString::createFromAscii( "/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"
diff --git a/desktop/unx/splash/unxsplash.cxx b/desktop/unx/splash/unxsplash.cxx
new file mode 100644
index 0000000..ca20334
--- /dev/null
+++ desktop/unx/splash/unxsplash.cxx
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile$
+ *
+ *  $Revision: 7305 $
+ *
+ *  last change: $Author: jholesovsky $ $Date: 2006-08-04 16:35:41 +0200 (Pá, 04 srp 2006) $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library 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 for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#include "unxsplash.hxx"
+#include <stdio.h>
+#ifndef _UTL_BOOTSTRAP_HXX
+#include <unotools/bootstrap.hxx>
+#endif
+#ifndef _VOS_PROCESS_HXX_
+#include <vos/process.hxx>
+#endif
+#ifndef _URLOBJ_HXX
+#include <tools/urlobj.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _SFX_HRC
+#include <sfx2/sfx.hrc>
+#endif
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <rtl/logfile.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/math.hxx>
+
+#define PIPE_ARG "-splash-pipe="
+
+using namespace ::rtl;
+using namespace ::com::sun::star::registry;
+
+namespace desktop
+{
+
+UnxSplashScreen::UnxSplashScreen( const Reference< XMultiServiceFactory >& rSMgr )
+    : m_rFactory( rSMgr ),
+      m_pOutFd( NULL )
+{
+}
+
+UnxSplashScreen::~UnxSplashScreen()
+{
+#if OSL_DEBUG_LEVEL > 1
+    fprintf( stderr, "UnxSplashScreen::~UnxSplashScreen()\n" );
+#endif
+
+    if ( m_pOutFd )
+    {
+        fclose( m_pOutFd );
+        m_pOutFd = NULL;
+    }
+}
+
+void SAL_CALL UnxSplashScreen::start( const OUString& /*aText*/, sal_Int32 /*nRange*/ )
+    throw ( RuntimeException )
+{
+}
+
+void SAL_CALL UnxSplashScreen::end()
+    throw ( RuntimeException )
+{
+#if OSL_DEBUG_LEVEL > 1
+    fprintf( stderr, "UnxSplashScreen::end()\n" );
+#endif
+
+    fprintf( m_pOutFd, "end\n" );
+    fflush( m_pOutFd );
+}
+
+void SAL_CALL UnxSplashScreen::reset()
+    throw ( RuntimeException )
+{
+    // TODO?
+}
+
+void SAL_CALL UnxSplashScreen::setText( const OUString& /*aText*/ )
+    throw ( RuntimeException )
+{
+    // TODO?
+}
+
+void SAL_CALL UnxSplashScreen::setValue( sal_Int32 nValue )
+    throw ( RuntimeException )
+{
+    if ( m_pOutFd )
+    {
+        fprintf( m_pOutFd, "%d%%\n", nValue );
+        fflush( m_pOutFd );
+    }
+}
+
+// XInitialize
+void SAL_CALL
+UnxSplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
+    throw ( RuntimeException )
+{
+    ::vos::OStartupInfo aInfo;
+    for ( sal_uInt32 i = 0; i < aInfo.getCommandArgCount(); i++ )
+    {
+        rtl::OUString aArg;
+        if ( aInfo.getCommandArg( i, aArg ) )
+            break;
+        if ( aArg.matchIgnoreAsciiCaseAsciiL( PIPE_ARG, sizeof( PIPE_ARG ) - 1, 0 ) )
+        {
+            OUString aNum = aArg.copy( sizeof( PIPE_ARG ) - 1 );
+            int fd = aNum.toInt32();
+            m_pOutFd = fdopen( fd, "w" );
+#if OSL_DEBUG_LEVEL > 1
+            fprintf( stderr, "Got argument '-splash-pipe=%d ('%s') (%p)\n",
+                     fd, (const sal_Char *)rtl::OUStringToOString( aNum, RTL_TEXTENCODING_UTF8 ),
+                     m_pOutFd );
+#endif
+        }
+    }
+}
+
+// get service instance...
+UnxSplashScreen *UnxSplashScreen::m_pINSTANCE = NULL;
+osl::Mutex UnxSplashScreen::m_aMutex;
+
+Reference< XInterface > UnxSplashScreen::getInstance( const Reference< XMultiServiceFactory >& rSMgr )
+{
+    if ( m_pINSTANCE == NULL )
+    {
+        osl::MutexGuard guard( m_aMutex );
+        if ( m_pINSTANCE == NULL )
+            return (XComponent*) new UnxSplashScreen( rSMgr );
+    }
+
+    return (XComponent*)NULL;
+}
+
+// static service info...
+const char* UnxSplashScreen::interfaces[] =
+{
+    "com.sun.star.task.XStartusIndicator",
+    "com.sun.star.lang.XInitialization",
+    NULL,
+};
+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 };
+
+OUString UnxSplashScreen::impl_getImplementationName()
+{
+    return OUString::createFromAscii( implementationName );
+}
+
+Sequence<OUString> UnxSplashScreen::impl_getSupportedServiceNames()
+{
+    Sequence<OUString> aSequence;
+    for ( int i = 0; supportedServiceNames[i] != NULL; i++ )
+    {
+        aSequence.realloc( i+1 );
+        aSequence[i] = OUString::createFromAscii( supportedServiceNames[i] );
+    }
+    return aSequence;
+}
+
+}
diff --git a/desktop/unx/splash/unxsplash.hxx b/desktop/unx/splash/unxsplash.hxx
new file mode 100644
index 0000000..5419324
--- /dev/null
+++ desktop/unx/splash/unxsplash.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile$
+ *
+ *  $Revision: 7305 $
+ *
+ *  last change: $Author: jholesovsky $ $Date: 2006-08-04 16:35:41 +0200 (Pá, 04 srp 2006) $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library 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 for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+
+#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP_
+#include <com/sun/star/uno/Exception.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
+#include <com/sun/star/uno/Reference.h>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
+#include <com/sun/star/lang/XComponent.hpp>
+#endif
+#ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATOR_HPP_
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
+#include <com/sun/star/lang/XInitialization.hpp>
+#endif
+#ifndef _CPPUHELPER_IMPLBASE2_HXX_
+#include <cppuhelper/implbase2.hxx>
+#endif
+#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
+#include <cppuhelper/interfacecontainer.h>
+#endif
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+#ifndef _RTL_BOOTSTRAP_HXX_
+#include <rtl/bootstrap.hxx>
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::task;
+
+namespace desktop {
+
+class  UnxSplashScreen : public ::cppu::WeakImplHelper2< XStatusIndicator, XInitialization >
+{
+private:
+    // don't allow anybody but ourselves to create instances of this class
+    UnxSplashScreen( const UnxSplashScreen& );
+    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;
+
+    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 );
+
+    // static service info
+    static OUString  impl_getImplementationName();
+    static Sequence<OUString> impl_getSupportedServiceNames();
+
+    // XStatusIndicator
+    virtual void SAL_CALL start( const OUString& aText, sal_Int32 nRange ) throw ( RuntimeException );
+    virtual void SAL_CALL end() throw ( RuntimeException );
+    virtual void SAL_CALL reset() throw ( RuntimeException );
+    virtual void SAL_CALL setText( const OUString& aText ) throw ( RuntimeException );
+    virtual void SAL_CALL setValue( sal_Int32 nValue ) throw ( RuntimeException );
+
+    // XInitialize
+    virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments ) throw ( RuntimeException );
+};
+
+}
diff --git a/scp2/source/ooo/file_library_ooo.scp b/scp2/source/ooo/file_library_ooo.scp
index 1fc287e..3d3460d 100644
--- scp2/source/ooo/file_library_ooo.scp
+++ scp2/source/ooo/file_library_ooo.scp
@@ -2116,6 +2116,9 @@ File gid_File_Lib_Spell
 End
 
 STD_UNO_LIB_FILE_PATCH( gid_File_Lib_Spl, spl)
+#ifdef UNX
+STD_UNO_LIB_FILE_PATCH( gid_File_Lib_Spl_Unx, spl_unx)
+#endif
 
 SPECIAL_UNO_LIB_FILE_PATCH(gid_File_Lib_Srtrs1,srtrs1)
 
diff --git a/scp2/source/ooo/file_ooo.scp b/scp2/source/ooo/file_ooo.scp
index 8e113d3..2f49288 100644
--- scp2/source/ooo/file_ooo.scp
+++ scp2/source/ooo/file_ooo.scp
@@ -341,6 +341,15 @@ File gid_File_Bin_Soffice_Bin
     Name = "soffice.bin";
 End
 
+#if defined(UNX)
+File gid_File_Bin_QStart_Bin
+    BIN_FILE_BODY;
+    Dir = gid_Dir_Program;
+    Styles = (PACKED, PATCH);
+    Name = "oosplash.bin";
+End
+#endif
+
 // use this for high detail file open dialog >= 5.1 windows
 // #ifdef WNT
 //
diff --git a/vcl/inc/vcl/svapp.hxx b/vcl/inc/vcl/svapp.hxx
index 1576807..9492703 100644
--- vcl/inc/vcl/svapp.hxx
+++ vcl/inc/vcl/svapp.hxx
@@ -292,6 +292,7 @@ public:
     virtual void                DataChanged( const DataChangedEvent& rDCEvt );
 
     virtual void                Init();
+    virtual void                InitFinished();
     virtual void                DeInit();
 
     static void                 InitAppRes( const ResId& rResId );
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 76bb447..8aefaf8 100644
--- vcl/source/app/svapp.cxx
+++ vcl/source/app/svapp.cxx
@@ -381,6 +381,11 @@ void Application::Init()
 }
 
 // -----------------------------------------------------------------------
+void Application::InitFinished()
+{
+}
+
+// -----------------------------------------------------------------------
 
 void Application::DeInit()
 {
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 6a1a0c0..db4c9f0 100644
--- vcl/source/window/window.cxx
+++ vcl/source/window/window.cxx
@@ -6518,10 +6518,19 @@ void Window::Show( BOOL bVisible, USHORT nFlags )
             mpWindowImpl->mpBorderWindow->Show( TRUE, nFlags );
         else if ( mpWindowImpl->mbFrame )
         {
-            ImplSVData* pSVData = ImplGetSVData();
             // #106431#, hide SplashScreen
-            if( pSVData->mpIntroWindow && !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
+            ImplSVData* pSVData = ImplGetSVData();
+            if ( !pSVData->mpIntroWindow )
+            {
+                // The right way would be just to call this (not even in the 'if')
+                GetpApp()->InitFinished();
+            }
+            else if ( !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
+            {
+                // ... but the VCL splash is broken, and it needs this
+                // (for ./soffice slot:5500)
                 pSVData->mpIntroWindow->Hide();
+            }
 
             //DBG_ASSERT( !mpWindowImpl->mbSuppressAccessibilityEvents, "Window::Show() - Frame reactivated");
             mpWindowImpl->mbSuppressAccessibilityEvents = FALSE;
