View | Details | Raw Unified | Return to issue 60696
Collapse All | Expand All

(-)scp2/source/ooo/file_ooo.scp (+9 lines)
Lines 338-343 File gid_File_Bin_Soffice_Bin Link Here
338
    Name = "soffice.bin";
338
    Name = "soffice.bin";
339
End
339
End
340
340
341
#if defined(UNX) && defined(ENABLE_GTK)
342
File gid_File_Bin_QStart_Bin
343
    BIN_FILE_BODY;
344
    Dir = gid_Dir_Program;
345
    Styles = (PACKED, PATCH);
346
    Name = "ooqstart";
347
End
348
#endif
349
341
#ifdef UNX
350
#ifdef UNX
342
351
343
File gid_File_Bin_Open_Url
352
File gid_File_Bin_Open_Url
(-)desktop/prj/build.lst (-1 / +2 lines)
Lines 14-19 dt desktop\win32\source\setup nmake - Link Here
14
dt	desktop\win32\source\officeloader		nmake	-	w	dt_officeloader NULL
14
dt	desktop\win32\source\officeloader		nmake	-	w	dt_officeloader NULL
15
dt	desktop\win32\source\applauncher		nmake	-	w	dt_applauncher NULL
15
dt	desktop\win32\source\applauncher		nmake	-	w	dt_applauncher NULL
16
dt	desktop\win32\source\applauncher\ooo	nmake	-	w	dt_applauncher_ooo dt_applauncher.w NULL
16
dt	desktop\win32\source\applauncher\ooo	nmake	-	w	dt_applauncher_ooo dt_applauncher.w NULL
17
dt	desktop\unx\source					nmake	-	u	dt_uwrapper NULL
17
dt	desktop\source\pagein					nmake	-	u	dt_pagein NULL
18
dt	desktop\source\pagein					nmake	-	u	dt_pagein NULL
18
dt	desktop\source\pkgchk					nmake	-	all	dt_pkgchk dt_dp_misc dt_app NULL
19
dt	desktop\source\pkgchk					nmake	-	all	dt_pkgchk dt_dp_misc dt_app NULL
19
dt	desktop\source\pkgchk\msi				nmake	-	w	dt_pkgchk_msi dt_pkgchk NULL
20
dt	desktop\source\pkgchk\msi				nmake	-	w	dt_pkgchk_msi dt_pkgchk NULL
Lines 31-34 dt desktop\source\deployment\registry\co Link Here
31
dt	desktop\scripts 						nmake	-	u	dt_scripts NULL
32
dt	desktop\scripts 						nmake	-	u	dt_scripts NULL
32
dt	desktop\macosx\source					nmake	-	u	dt_macosx_bundle	NULL
33
dt	desktop\macosx\source					nmake	-	u	dt_macosx_bundle	NULL
33
dt	desktop\macosx\source\misc				nmake	-	u	dt_misc_macosxrc	NULL
34
dt	desktop\macosx\source\misc				nmake	-	u	dt_misc_macosxrc	NULL
34
dt	desktop\util							nmake	-	all	dt_util dt_app dt_so_comp dt_spl dt_wrapper.w dt_officeloader.w dt_migr dt_macosx_bundle.u NULL
35
dt	desktop\util							nmake	-	all	dt_util dt_app dt_so_comp dt_spl dt_uwrapper.u dt_wrapper.w dt_officeloader.w dt_migr dt_macosx_bundle.u NULL
(-)desktop/prj/d.lst (+1 lines)
Lines 7-12 mkdir: %_DEST%\bin%_EXT%\remote2 Link Here
7
..\%__SRC%\bin\soffice.bin %_DEST%\bin%_EXT%\soffice.bin
7
..\%__SRC%\bin\soffice.bin %_DEST%\bin%_EXT%\soffice.bin
8
..\%__SRC%\bin\officeloader.exe %_DEST%\bin%_EXT%\soffice.exe
8
..\%__SRC%\bin\officeloader.exe %_DEST%\bin%_EXT%\soffice.exe
9
..\%__SRC%\bin\soffice %_DEST%\bin%_EXT%\soffice.bin
9
..\%__SRC%\bin\soffice %_DEST%\bin%_EXT%\soffice.bin
10
..\%__SRC%\bin\ooqstart %_DEST%\bin%_EXT%\ooqstart
10
11
11
..\%__SRC%\bin\soffice_oo.exe %_DEST%\bin%_EXT%\soffice_oo.exe
12
..\%__SRC%\bin\soffice_oo.exe %_DEST%\bin%_EXT%\soffice_oo.exe
12
..\%__SRC%\bin\soffice_so.exe %_DEST%\bin%_EXT%\soffice_so.exe
13
..\%__SRC%\bin\soffice_so.exe %_DEST%\bin%_EXT%\soffice_so.exe
(-)desktop/source/app/cmdlineargs.cxx (-1 / +8 lines)
Lines 412-417 sal_Bool CommandLineArgs::InterpretComma Link Here
412
		SetBoolParam_Impl( CMD_BOOLPARAM_HELPMATH, sal_True );
412
		SetBoolParam_Impl( CMD_BOOLPARAM_HELPMATH, sal_True );
413
		return sal_True;
413
		return sal_True;
414
	}
414
	}
415
    else if ( aArgStr.Copy(0, 13).EqualsIgnoreCaseAscii( "-splash-pipe=" ))
416
    {
417
		AddStringListParam_Impl( CMD_STRINGPARAM_SPLASHPIPE, aArgStr.Copy( 13 ) );
418
		return sal_True;
419
    }
415
    else if ( aArgStr.Copy(0, 8).EqualsIgnoreCaseAscii( "-accept=" ))
420
    else if ( aArgStr.Copy(0, 8).EqualsIgnoreCaseAscii( "-accept=" ))
416
    {
421
    {
417
		AddStringListParam_Impl( CMD_STRINGPARAM_ACCEPT, aArgStr.Copy( 8 ) );
422
		AddStringListParam_Impl( CMD_STRINGPARAM_ACCEPT, aArgStr.Copy( 8 ) );
Lines 861-867 sal_Bool CommandLineArgs::IsEmptyOrAccep Link Here
861
{
866
{
862
    osl::MutexGuard  aMutexGuard( m_aMutex );
867
    osl::MutexGuard  aMutexGuard( m_aMutex );
863
868
864
    return m_bEmpty || ( ( m_nArgumentCount == 1 ) && ( m_aStrParams[ CMD_STRINGPARAM_ACCEPT ].getLength() ) );
869
    return m_bEmpty ||
870
        ( ( m_nArgumentCount == 1 ) && ( m_aStrParams[ CMD_STRINGPARAM_SPLASHPIPE ].getLength() ) ) ||
871
        ( ( m_nArgumentCount == 1 ) && ( m_aStrParams[ CMD_STRINGPARAM_ACCEPT ].getLength() ) );
865
}
872
}
866
873
867
} // namespace desktop
874
} // namespace desktop
(-)desktop/source/app/cmdlineargs.hxx (+1 lines)
Lines 89-94 class CommandLineArgs Link Here
89
		enum StringParam // must be zero based!
89
		enum StringParam // must be zero based!
90
		{
90
		{
91
			CMD_STRINGPARAM_PORTAL,
91
			CMD_STRINGPARAM_PORTAL,
92
			CMD_STRINGPARAM_SPLASHPIPE,
92
			CMD_STRINGPARAM_ACCEPT,
93
			CMD_STRINGPARAM_ACCEPT,
93
			CMD_STRINGPARAM_UNACCEPT,
94
			CMD_STRINGPARAM_UNACCEPT,
94
			CMD_STRINGPARAM_USERDIR,
95
			CMD_STRINGPARAM_USERDIR,
(-)desktop/source/splash/splash.cxx (-3 / +51 lines)
Lines 82-92 SplashScreen::SplashScreen(const Referen Link Here
82
	, _yoffset(18)
82
	, _yoffset(18)
83
    , _barheight(-1)
83
    , _barheight(-1)
84
    , _barspace(2)
84
    , _barspace(2)
85
    , _bVisible( FALSE )
86
    , _outFd(NULL)
85
{
87
{
86
	_rFactory = rSMgr;
88
	_rFactory = rSMgr;
87
89
88
    loadConfig();
90
#ifdef UNX
91
	::vos::OStartupInfo aInfo;
92
#define PIPE_ARG "-splash-pipe="
93
	for (sal_uInt32 i = 0; i < aInfo.getCommandArgCount(); i++)
94
	{
95
		rtl::OUString aArg;
96
		if (aInfo.getCommandArg (i, aArg))
97
		    break;
98
		if (aArg.matchIgnoreAsciiCaseAsciiL (PIPE_ARG, sizeof (PIPE_ARG) - 1, 0))
99
		{
100
			OUString aNum = aArg.copy (sizeof (PIPE_ARG) - 1);
101
			int fd = aNum.toInt32();
102
			_outFd = fdopen (fd, "w");
103
/*			fprintf (stderr, "Got argument '-splash-pipe=%d ('%s') (%p)\n",
104
					 fd, (const sal_Char *)rtl::OUStringToOString (aNum, RTL_TEXTENCODING_UTF8),
105
					 _outFd); */
106
		}
107
	}
108
#endif
109
110
	if (!doRender())
111
		return;
112
113
	loadConfig();
89
	initBitmap();
114
	initBitmap();
115
90
	Size aSize = _aIntroBmp.GetSizePixel();
116
	Size aSize = _aIntroBmp.GetSizePixel();
91
	SetOutputSizePixel( aSize );
117
	SetOutputSizePixel( aSize );
92
    _vdev.SetOutputSizePixel( aSize );
118
    _vdev.SetOutputSizePixel( aSize );
Lines 139-148 SplashScreen::SplashScreen(const Referen Link Here
139
165
140
SplashScreen::~SplashScreen()
166
SplashScreen::~SplashScreen()
141
{
167
{
168
	if (!doRender())
169
		return;
142
	Application::RemoveEventListener(
170
	Application::RemoveEventListener(
143
		LINK( this, SplashScreen, AppEventListenerHdl ) );
171
		LINK( this, SplashScreen, AppEventListenerHdl ) );
144
	Hide();
172
	if (_bVisible) Hide();
145
173
174
#ifdef UNX
175
	if (!doRender()) {
176
		fclose (_outFd);
177
		_outFd = NULL;
178
	}
179
#endif
146
}
180
}
147
181
148
void SAL_CALL SplashScreen::start(const OUString& aText, sal_Int32 nRange)
182
void SAL_CALL SplashScreen::start(const OUString& aText, sal_Int32 nRange)
Lines 161-166 void SAL_CALL SplashScreen::end() Link Here
161
	_iProgress = _iMax;
195
	_iProgress = _iMax;
162
	updateStatus();
196
	updateStatus();
163
	if (_bVisible) Hide();
197
	if (_bVisible) Hide();
198
#ifdef UNX
199
	if (!doRender()) {
200
/*		fprintf (stderr, "SplashScreen::end()\n"); */
201
		fprintf (_outFd, "end\n");
202
		fflush (_outFd);
203
	}
204
#endif
164
}
205
}
165
void SAL_CALL SplashScreen::reset()
206
void SAL_CALL SplashScreen::reset()
166
	throw (RuntimeException)
207
	throw (RuntimeException)
Lines 185-190 void SAL_CALL SplashScreen::setValue(sal Link Here
185
    RTL_LOGFILE_CONTEXT_TRACE1( aLog, "value=%d", nValue );
226
    RTL_LOGFILE_CONTEXT_TRACE1( aLog, "value=%d", nValue );
186
227
187
    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
228
    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
229
#ifdef UNX
230
	if (!doRender())
231
	{
232
		fprintf (_outFd, "%d%%\n", nValue);
233
		fflush (_outFd);
234
	}
235
#endif
188
    if (_bVisible) {
236
    if (_bVisible) {
189
        Show();
237
        Show();
190
	    if (nValue >= _iMax) _iProgress = _iMax;
238
	    if (nValue >= _iMax) _iProgress = _iMax;
Lines 199-205 SplashScreen::initialize( const ::com::s Link Here
199
	throw (RuntimeException)
247
	throw (RuntimeException)
200
{
248
{
201
	::osl::ClearableMutexGuard	aGuard(	_aMutex );
249
	::osl::ClearableMutexGuard	aGuard(	_aMutex );
202
	if (aArguments.getLength() > 0)
250
	if (aArguments.getLength() > 0 && doRender())
203
		aArguments[0] >>= _bVisible;
251
		aArguments[0] >>= _bVisible;
204
}
252
}
205
253
(-)desktop/source/splash/splash.hxx (+5 lines)
Lines 33-38 Link Here
33
 *
33
 *
34
 ************************************************************************/
34
 ************************************************************************/
35
35
36
#include <stdio.h>
37
36
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
38
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
37
#include <com/sun/star/lang/XServiceInfo.hpp>
39
#include <com/sun/star/lang/XServiceInfo.hpp>
38
#endif
40
#endif
Lines 113-122 private: Link Here
113
	sal_Bool _bPaintBitmap;
115
	sal_Bool _bPaintBitmap;
114
	sal_Bool _bPaintProgress;
116
	sal_Bool _bPaintProgress;
115
	sal_Bool _bVisible;
117
	sal_Bool _bVisible;
118
	FILE *_outFd;
116
	long _height, _width, _tlx, _tly, _barwidth;
119
	long _height, _width, _tlx, _tly, _barwidth;
117
    long _barheight, _barspace;
120
    long _barheight, _barspace;
118
    const long _xoffset, _yoffset;
121
    const long _xoffset, _yoffset;
119
122
123
	bool doRender() { return _outFd == NULL; };
124
120
public:
125
public:
121
    static const char* interfaces[];
126
    static const char* interfaces[];
122
	static const sal_Char *serviceName;
127
	static const sal_Char *serviceName;
(-)desktop/unx/source/makefile.mk (+32 lines)
Added Link Here
1
PRJ=..$/..
2
PRJNAME=desktop
3
TARGET=ooqstart
4
5
NO_DEFAULT_STL=TRUE
6
7
.INCLUDE :  settings.mk
8
9
.IF "$(ENABLE_GTK)" != "TRUE"
10
dummy:
11
	@echo "Nothing to build. GUIBASE == $(GUIBASE), WITH_WIDGETSET == $(WITH_WIDGETSET)"
12
13
.ELSE # we need glib...
14
15
PKGCONFIG_MODULES=glib-2.0
16
.INCLUDE: pkg_config.mk
17
18
CFLAGS+= $(PKGCONFIG_CFLAGS)
19
STDLIB=
20
21
APP1TARGET = $(TARGET)
22
APP1OBJS   = $(OBJ)$/splashx.obj $(OBJ)$/start.obj
23
APP1NOSAL  = TRUE
24
APP1LIBSALCPPRT=
25
APP1CODETYPE = C
26
APP1STDLIBS = $(PKGCONFIG_LIBS) -lX11
27
28
.ENDIF
29
30
# --- Targets ------------------------------------------------------
31
32
.INCLUDE :	target.mk
(-)desktop/unx/source/splashx.c (+528 lines)
Added Link Here
1
/*************************************************************************
2
 *
3
 *  OpenOffice.org - a multi-platform office productivity suite
4
 *
5
 *  $RCSfile$
6
 *
7
 *  $Revision$
8
 *
9
 *  last change: $Author$ $Date$
10
 *
11
 *  The Contents of this file are made available subject to
12
 *  the terms of GNU Lesser General Public License Version 2.1.
13
 *
14
 *
15
 *    GNU Lesser General Public License Version 2.1
16
 *    =============================================
17
 *    Copyright 2005 by Sun Microsystems, Inc.
18
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
19
 *
20
 *    This library is free software; you can redistribute it and/or
21
 *    modify it under the terms of the GNU Lesser General Public
22
 *    License version 2.1, as published by the Free Software Foundation.
23
 *
24
 *    This library is distributed in the hope that it will be useful,
25
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
26
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
 *    Lesser General Public License for more details.
28
 *
29
 *    You should have received a copy of the GNU Lesser General Public
30
 *    License along with this library; if not, write to the Free Software
31
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32
 *    MA  02111-1307  USA
33
 *
34
 ************************************************************************/
35
36
#include <X11/Xlib.h>
37
#include <X11/Xatom.h>
38
#include <X11/Xutil.h>
39
40
#include <endian.h>
41
#include <fcntl.h>
42
#include <stdint.h>
43
#include <stdio.h>
44
#include <stdlib.h>
45
#include <string.h>
46
#include <unistd.h>
47
48
#include "splashx.h"
49
50
#define WINDOW_WIDTH  440
51
#define WINDOW_HEIGHT 299
52
53
#define PROGRESS_XOFFSET 12
54
#define PROGRESS_YOFFSET 18
55
#define PROGRESS_BARSPACE 2
56
57
static Display *display = NULL;
58
static int screen;
59
static int depth;
60
static Visual *visual = NULL;
61
62
static int width = WINDOW_WIDTH;
63
static int height = WINDOW_HEIGHT;
64
65
static Colormap color_map;
66
static Window win;
67
static GC gc;
68
69
typedef struct {
70
	unsigned char b, g, r;
71
} color_t;
72
static color_t *bitmap = NULL;
73
74
#define BMP_HEADER_LEN 14
75
#define WIN_INFO_LEN 40
76
77
#define UINT8( x )      ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) )
78
79
#define UINT16( x ) (   ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) ) + \
80
                      ( ( (unsigned int)( ( (uint8_t *)( x ) )[1] ) ) << 8 ) )
81
82
#define UINT32( x ) (   ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) ) + \
83
                      ( ( (unsigned int)( ( (uint8_t *)( x ) )[1] ) ) << 8  ) + \
84
                      ( ( (unsigned int)( ( (uint8_t *)( x ) )[2] ) ) << 16 ) + \
85
                      ( ( (unsigned int)( ( (uint8_t *)( x ) )[3] ) ) << 24 ) )
86
87
#define MAX( x, y ) ( ( (x) > (y) )? (x): (y) )
88
89
#define LOAD_FAILURE( msg ) \
90
	{ \
91
		fprintf( stderr, "%s: " msg, filename ); \
92
		close( fd ); \
93
		return 0; \
94
	}
95
96
// Load the specified Windows 24bit BMP to 'bitmap'
97
// Return: 1 - success, 0 - failure
98
int splash_load_bmp( char *filename )
99
{
100
	int fd = open( filename, O_RDONLY );
101
	if ( fd < 0 )
102
		return 0;
103
104
	char file_header[ BMP_HEADER_LEN ];
105
	
106
	if ( read( fd, file_header, BMP_HEADER_LEN ) != BMP_HEADER_LEN || file_header[0] != 'B' || file_header[1] != 'M' )
107
		LOAD_FAILURE( "Not a bitmap.\n" );
108
109
	int file_size = UINT32( file_header + 2 );
110
	
111
	char info_header[ WIN_INFO_LEN ];
112
	if ( read( fd, info_header, 4 ) != 4 )
113
		LOAD_FAILURE( "Unable to read the header.\n" );
114
115
	int header_size = UINT32( info_header );
116
	if ( header_size != WIN_INFO_LEN )
117
		LOAD_FAILURE( "Not a Windows bitmap.\n" );
118
119
	if ( read( fd, info_header + 4, WIN_INFO_LEN - 4 ) != WIN_INFO_LEN - 4 )
120
		LOAD_FAILURE( "The header ended too early.\n" );
121
122
	width = UINT32( info_header + 4 );
123
	height = UINT32( info_header + 8 );
124
125
	int bits = UINT16( info_header + 14 );
126
	int compression = UINT16( info_header + 16 );
127
128
	if ( bits != 24 )
129
		LOAD_FAILURE( "Just 24 bpp bitmaps are supported.\n" );
130
131
	if ( compression != 0 )
132
		LOAD_FAILURE( "Just uncompressed bitmaps are supported.\n" );
133
134
	size_t bitmap_size = width * height * 3;
135
	bitmap = malloc( bitmap_size );
136
	if ( bitmap == NULL )
137
		LOAD_FAILURE( "Cannot allocate memory for the data.\n" );
138
139
	int y;
140
	size_t line_size = width * 3;
141
	color_t *line = bitmap + ( height - 1 ) * width;
142
	for ( y = height; y > 0; --y, line -= width )
143
	{
144
		if ( read( fd, line, line_size ) != line_size )
145
			LOAD_FAILURE( "Cannot read the bitmap data.\n" );
146
	}
147
148
	close( fd );
149
	return 1;
150
}
151
152
// Universal shift: bits >= 0 - left, otherwise right
153
#define SHIFT( x, bits ) ( ( (bits) >= 0 )? ( (x) << (bits) ): ( (x) >> -(bits) ) )
154
155
// Position of the highest bit (more or less integer log2)
156
inline int HIGHEST_BIT( unsigned long x )
157
{
158
	int i = 0;
159
	for ( ; x; ++i )
160
		x >>= 1;
161
162
	return i;
163
}
164
165
// Number of bits set to 1
166
inline int BITS( unsigned long x )
167
{
168
	int i = 0;
169
	for ( ; x; x >>= 1 )
170
		if ( x & 1UL )
171
			++i;
172
173
	return i;
174
}
175
176
// Set 'bitmap' as the background of our 'win' window
177
static void create_pixmap()
178
{
179
	if ( !bitmap )
180
		return;
181
182
	Pixmap pixmap = XCreatePixmap( display, win, width, height, depth );
183
184
	unsigned long value_mask = 0;
185
	XGCValues values;
186
	GC pixmap_gc = XCreateGC( display, pixmap, value_mask, &values );
187
188
	if ( visual->class == TrueColor )
189
	{
190
		unsigned long red_mask   = visual->red_mask;
191
		unsigned long green_mask = visual->green_mask;
192
		unsigned long blue_mask  = visual->blue_mask;
193
194
		unsigned long red_delta_mask   = ( 1UL << ( 8 - BITS( red_mask ) ) ) - 1;
195
		unsigned long green_delta_mask = ( 1UL << ( 8 - BITS( green_mask ) ) ) - 1;
196
		unsigned long blue_delta_mask  = ( 1UL << ( 8 - BITS( blue_mask ) ) ) - 1;
197
198
		int red_shift   = HIGHEST_BIT( red_mask ) - 8;
199
		int green_shift = HIGHEST_BIT( green_mask ) - 8;
200
		int blue_shift  = HIGHEST_BIT( blue_mask ) - 8;
201
202
		XImage *image = XCreateImage( display, visual, depth, ZPixmap,
203
				0, NULL, width, height, 32, 0 );
204
205
		int bytes_per_line = image->bytes_per_line;
206
		int bpp = image->bits_per_pixel;
207
		int byte_order = image->byte_order; 
208
		int machine_byte_order = ( __BYTE_ORDER == __LITTLE_ENDIAN )? LSBFirst: MSBFirst;
209
210
		if ( __BYTE_ORDER != __LITTLE_ENDIAN && __BYTE_ORDER != __BIG_ENDIAN )
211
		{
212
			fprintf( stderr, "Unsupported machine endianity.\n" );
213
			XFreeGC( display, pixmap_gc );
214
			XFreePixmap( display, pixmap );
215
			XDestroyImage( image );
216
			return;
217
		}
218
219
		char *data = malloc( height * bytes_per_line );
220
		image->data = data;
221
222
		// The following dithers & converts the color_t color to one
223
		// acceptable for the visual
224
#define COPY_IN_OUT( code ) \
225
		{ \
226
			int x, y; \
227
			for ( y = 0; y < height; ++y ) \
228
			{ \
229
				unsigned long red_delta = 0, green_delta = 0, blue_delta = 0; \
230
				for ( x = 0; x < width; ++x, ++in  ) \
231
				{ \
232
					unsigned long red   = in->r + red_delta; \
233
					unsigned long green = in->g + green_delta; \
234
					unsigned long blue  = in->b + blue_delta; \
235
					red_delta = red & red_delta_mask; \
236
					green_delta = green & green_delta_mask; \
237
					blue_delta = blue & blue_delta_mask; \
238
					if ( red > 255 ) \
239
						red = 255; \
240
					if ( green > 255 ) \
241
						green = 255; \
242
					if ( blue > 255 ) \
243
						blue = 255; \
244
					unsigned long pixel = \
245
						( SHIFT( red, red_shift ) & red_mask ) | \
246
						( SHIFT( green, green_shift ) & green_mask ) | \
247
						( SHIFT( blue, blue_shift ) & blue_mask ); \
248
					code \
249
				} \
250
			} \
251
		}
252
253
		color_t *in = bitmap;
254
		char *out = data;
255
256
		if ( bpp == 32 )
257
		{
258
			if ( machine_byte_order == byte_order )
259
				COPY_IN_OUT( *( (uint32_t *)out ) = (uint32_t)pixel; out += 4; )
260
			else
261
				COPY_IN_OUT( uint32_t tmp = pixel;
262
							 *( (uint8_t *)out     ) = *( (uint8_t *)(&tmp) + 3 );
263
							 *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
264
							 *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 1 );
265
							 *( (uint8_t *)out + 3 ) = *( (uint8_t *)(&tmp)     );
266
							 out += 4; )
267
		}
268
		else if ( bpp == 24 )
269
		{
270
			if ( machine_byte_order == byte_order && byte_order == LSBFirst )
271
				COPY_IN_OUT( *( (color_t *)out ) = *( (color_t *)( &pixel ) ); out += 3; )
272
			if ( machine_byte_order == byte_order && byte_order == MSBFirst )
273
				COPY_IN_OUT( uint32_t tmp = pixel;
274
							 *( (uint8_t *)out     ) = *( (uint8_t *)(&tmp) + 1 );
275
							 *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
276
							 *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 3 );
277
							 out += 3; )
278
			else
279
				COPY_IN_OUT( uint32_t tmp = pixel;
280
							 *( (uint8_t *)out     ) = *( (uint8_t *)(&tmp) + 3 );
281
							 *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
282
							 *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 1 );
283
							 out += 3; )
284
		}
285
		else if ( bpp == 16 )
286
		{
287
			if ( machine_byte_order == byte_order )
288
				COPY_IN_OUT( *( (uint16_t *)out ) = (uint16_t)pixel; out += 2; )
289
			else
290
				COPY_IN_OUT( uint16_t tmp = pixel;
291
							 *( (uint8_t *)out     ) = *( (uint8_t *)(&tmp) + 1 );
292
							 *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp)     );
293
							 out += 2; );
294
		}
295
		else if ( bpp == 8 )
296
		{
297
			COPY_IN_OUT( *( (uint8_t *)out ) = (uint8_t)pixel; ++out; )
298
		}
299
		else
300
		{
301
			fprintf( stderr, "Unsupported depth: %d bits per pixel.\n", bpp );
302
			XFreeGC( display, pixmap_gc );
303
			XFreePixmap( display, pixmap );
304
			XDestroyImage( image );
305
			return;
306
		}
307
308
#undef COPY_IN_OUT
309
310
		XPutImage( display, pixmap, pixmap_gc, image, 0, 0, 0, 0, width, height );
311
		XDestroyImage( image );
312
	}
313
	else //if ( depth == 1 || visual->class == DirectColor )
314
	{
315
		// FIXME Something like the following, but faster ;-) - XDrawPoint is not
316
		// a good idea...
317
		int x, y;
318
		for ( y = 0; y < height; ++y )
319
		{
320
			color_t *color = bitmap + y * width;
321
322
			int delta = 0;
323
			for ( x = 0; x < width; ++x, ++color )
324
			{
325
				int rnd = (int)( ( (long)( random() - RAND_MAX/2 ) * 32000 )/RAND_MAX );
326
				int luminance = delta + rnd + 299 * (int)color->r + 587 * (int)color->g + 114 * (int)color->b;
327
328
				if ( luminance < 128000 )
329
				{
330
					XSetForeground( display, pixmap_gc, BlackPixel( display, screen ) );
331
					delta = luminance;
332
				}
333
				else
334
				{
335
					XSetForeground( display, pixmap_gc, WhitePixel( display, screen ) );
336
					delta = luminance - 255000;
337
				}
338
339
				XDrawPoint( display, pixmap, pixmap_gc, x, y );
340
			}
341
		}
342
	}
343
344
	XSetWindowBackgroundPixmap( display, win, pixmap );
345
346
	XFreeGC( display, pixmap_gc );
347
	XFreePixmap( display, pixmap );
348
}
349
350
// The old method of hiding the window decorations
351
static void suppress_decorations_motif()
352
{
353
	struct {
354
		unsigned long flags, functions, decorations;
355
		long input_mode;
356
		unsigned long status;
357
	} mwmhints;
358
359
	Atom a = XInternAtom( display, "_MOTIF_WM_HINTS", False );
360
361
	mwmhints.flags = 15; // functions, decorations, input_mode, status
362
	mwmhints.functions = 2; // ?
363
	mwmhints.decorations = 0;
364
	mwmhints.input_mode = 0;
365
366
	XChangeProperty( display, win, a, a, 32,
367
			PropModeReplace, (unsigned char*)&mwmhints, 5 );
368
}
369
370
// This is a splash, set it as such.
371
// If it fails, just hide the decorations...
372
static void suppress_decorations()
373
{
374
	Atom atom_type = XInternAtom( display, "_NET_WM_WINDOW_TYPE", True );
375
	Atom atom_splash = XInternAtom( display, "_NET_WM_WINDOW_TYPE_SPLASH", True );
376
377
	if ( atom_type != None && atom_splash != None )
378
		XChangeProperty( display, win, atom_type, XA_ATOM, 32,
379
				PropModeReplace, (unsigned char*)&atom_splash, 1 );
380
	//else
381
		suppress_decorations_motif(); // FIXME: Unconditional until Metacity/compiz's SPLASH handling is fixed
382
}
383
384
// Create the window
385
// Return: 1 - success, 0 - failure
386
int splash_create_window( int argc, char** argv )
387
{
388
	char *display_name = NULL;
389
	int i;
390
	for ( i = 0; i < argc; i++ )
391
	{
392
		if ( !strcmp( argv[i], "-display" )  || !strcmp( argv[i], "--display" ) )
393
			display_name = ( i + 1 < argc )? argv[i+1]: NULL;
394
	}
395
396
	if ( !display_name )
397
		display_name = getenv( "DISPLAY" );
398
399
	// init display
400
	display = XOpenDisplay( display_name );
401
	if ( !display )
402
	{
403
		fprintf( stderr, "Failed to open display\n" );
404
		return 0;
405
	}
406
407
	// create the window
408
	screen = DefaultScreen( display );
409
	depth = DefaultDepth( display, screen );
410
	color_map = DefaultColormap( display, screen );
411
	visual = DefaultVisual( display, screen );
412
413
	Window root_win = RootWindow( display, screen );
414
	int display_width = DisplayWidth( display, screen );
415
	int display_height = DisplayHeight( display, screen );
416
417
	win = XCreateSimpleWindow( display, root_win,
418
			( display_width - width ) / 2, ( display_height - height ) / 2,
419
			width, height, 0,
420
			BlackPixel( display, screen ), BlackPixel( display, screen ) );
421
422
	XSetWindowColormap( display, win, color_map );
423
424
	// FIXME Do we want an own colormap for 8bpp displays?
425
426
	// not resizable, no decorations, etc.
427
	unsigned long value_mask = 0;
428
	XGCValues values;
429
	gc = XCreateGC( display, win, value_mask, &values );
430
431
	XSizeHints size_hints;
432
	size_hints.flags = PPosition | PSize | PMinSize | PMaxSize;
433
	size_hints.min_width = width;
434
	size_hints.max_width = width;
435
	size_hints.min_height = height;
436
	size_hints.max_height = height;
437
438
	char *name = "OpenOffice.org";
439
	char *icon = "icon"; // FIXME
440
441
	XSetStandardProperties( display, win, name, icon, None,
442
			0, 0, &size_hints ); 
443
444
	// the actual work
445
	suppress_decorations();
446
	create_pixmap();
447
448
	// show it
449
	XSelectInput( display, win, 0 );
450
	XMapWindow( display, win );
451
452
	return 1;
453
}
454
455
// Re-draw & rocess the events
456
// Just throwing them away - we do not need anything more...
457
static void process_events()
458
{
459
	XEvent xev;
460
	int num_events;
461
462
	XFlush( display );
463
	num_events = XPending( display );
464
	while ( num_events > 0 )
465
	{
466
		num_events--;
467
		XNextEvent( display, &xev );
468
		//process_event(xev);
469
	}
470
}
471
472
// Draw the progress
473
void splash_draw_progress( int progress )
474
{
475
	// values taken from desktop/source/splash/splash.cxx
476
	static int tlx = 212;
477
	static int tly = 216;
478
	static int barwidth = 263;
479
	static int barheight = 8;
480
	static int barspace = PROGRESS_BARSPACE;
481
	static int initialized = 0;
482
	if ( !initialized )
483
	{
484
		if ( width <= 500)
485
		{
486
			barwidth  = width - (2 * PROGRESS_XOFFSET);
487
			barheight = 6;
488
			tlx = PROGRESS_XOFFSET;
489
			tly = height - PROGRESS_YOFFSET;
490
		}
491
		initialized = 1;
492
	}
493
494
	// sanity
495
	if ( progress < 0 )
496
		progress = 0;
497
	if ( progress > 100 )
498
		progress = 100;
499
	
500
	// draw progress...
501
	int length = ( progress * barwidth / 100 ) - ( 2 * barspace );
502
	if (length < 0)
503
		length = 0;
504
505
	// border
506
	XSetForeground( display, gc, WhitePixel( display, screen ) );
507
	XDrawRectangle( display, win, gc,
508
			tlx, tly,
509
			barwidth, barheight );
510
511
	// progress bar
512
	XSetForeground( display, gc, WhitePixel( display, screen ) );
513
	XFillRectangle( display, win, gc,
514
			tlx + barspace, tly + barspace,
515
			length + 1, barheight - 2*barspace + 1 );
516
517
	// pending events
518
	process_events();
519
}
520
521
// Close the window & cleanup
522
void splash_close_window()
523
{
524
	XCloseDisplay( display );
525
526
	free( bitmap );
527
	bitmap = NULL;
528
}
(-)desktop/unx/source/splashx.h (+58 lines)
Added Link Here
1
/*************************************************************************
2
 *
3
 *  OpenOffice.org - a multi-platform office productivity suite
4
 *
5
 *  $RCSfile$
6
 *
7
 *  $Revision$
8
 *
9
 *  last change: $Author$ $Date$
10
 *
11
 *  The Contents of this file are made available subject to
12
 *  the terms of GNU Lesser General Public License Version 2.1.
13
 *
14
 *
15
 *    GNU Lesser General Public License Version 2.1
16
 *    =============================================
17
 *    Copyright 2005 by Sun Microsystems, Inc.
18
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
19
 *
20
 *    This library is free software; you can redistribute it and/or
21
 *    modify it under the terms of the GNU Lesser General Public
22
 *    License version 2.1, as published by the Free Software Foundation.
23
 *
24
 *    This library is distributed in the hope that it will be useful,
25
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
26
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
 *    Lesser General Public License for more details.
28
 *
29
 *    You should have received a copy of the GNU Lesser General Public
30
 *    License along with this library; if not, write to the Free Software
31
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32
 *    MA  02111-1307  USA
33
 *
34
 ************************************************************************/
35
36
#ifndef _SPLASHX_H
37
#define _SPLASHX_H
38
39
// Load the specified Windows 24bit BMP we can have as a background of the
40
// splash.
41
// 
42
// Note: Must be called before the create_window(), otherwise there will be no
43
// image in the splash, just black rectangle.
44
// 
45
// Return: 1 - success, 0 - failure (non-existing, etc.)
46
int splash_load_bmp( char *filename );
47
48
// Create the splash window
49
// Return: 1 - success, 0 - failure
50
int splash_create_window( int argc, char** argv );
51
52
// Destroy the splash window
53
void splash_close_window();
54
55
// Update the progress bar
56
void splash_draw_progress( int progress );
57
58
#endif // _SPLASHX_H
(-)desktop/unx/source/start.c (+496 lines)
Added Link Here
1
/*************************************************************************
2
 *
3
 *  OpenOffice.org - a multi-platform office productivity suite
4
 *
5
 *  $RCSfile$
6
 *
7
 *  $Revision$
8
 *
9
 *  last change: $Author$ $Date$
10
 *
11
 *  The Contents of this file are made available subject to
12
 *  the terms of GNU Lesser General Public License Version 2.1.
13
 *
14
 *
15
 *    GNU Lesser General Public License Version 2.1
16
 *    =============================================
17
 *    Copyright 2005 by Sun Microsystems, Inc.
18
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
19
 *
20
 *    This library is free software; you can redistribute it and/or
21
 *    modify it under the terms of the GNU Lesser General Public
22
 *    License version 2.1, as published by the Free Software Foundation.
23
 *
24
 *    This library is distributed in the hope that it will be useful,
25
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
26
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
 *    Lesser General Public License for more details.
28
 *
29
 *    You should have received a copy of the GNU Lesser General Public
30
 *    License along with this library; if not, write to the Free Software
31
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32
 *    MA  02111-1307  USA
33
 *
34
 ************************************************************************/
35
36
#include <signal.h>
37
#include <unistd.h>
38
#include <glib.h>
39
#include <limits.h>
40
#include <stdlib.h>
41
#include <sys/types.h>
42
#include <sys/stat.h>
43
#include <sys/socket.h>
44
#include <arpa/inet.h>
45
#include <sys/un.h>
46
#include <fcntl.h>
47
#include <stdio.h>
48
49
#define PIPEDEFAULTPATH		"/tmp"
50
#define PIPEALTERNATEPATH	"/var/tmp"
51
52
static char *
53
read_path_and_chomp (const char *app)
54
{
55
	int len;
56
	char buffer[PATH_MAX];
57
58
	/* Readlink on argv[0] to point to the install path */
59
	if ((len = readlink (app, buffer, sizeof(buffer))) < 0)
60
		return NULL;
61
	buffer[MIN(len, 4095)] = '\0';
62
63
	return g_path_get_dirname (buffer);
64
}
65
66
static char *
67
get_app_path (const char *app_exec)
68
{
69
	if (app_exec[0] != '/')
70
		g_error ("%s must be called with an absolute path\n", app_exec);
71
72
	return g_path_get_dirname (app_exec);
73
}
74
75
/* OO.o likes to find real paths, unwinding symlinks etc. */
76
static char *
77
get_real_app_path (const char *app_path)
78
{
79
	char *path, *bin_path;
80
81
	path = g_strdup (app_path);
82
83
	/* Hack for use with linkoo: follow soffice.bin
84
	   if it is a symlink */
85
	bin_path = g_strconcat (app_path, "/soffice.bin", NULL);
86
	if (g_file_test (bin_path, G_FILE_TEST_IS_SYMLINK)) 
87
	{
88
		g_free (path);
89
		path = read_path_and_chomp (bin_path);
90
	}
91
	g_free (bin_path);
92
93
	/* Nasty - but OO.o likes to call realpath too ... */
94
	char *real_path = (char *)g_malloc (PATH_MAX + 1);
95
	realpath (path, real_path);
96
	real_path[PATH_MAX] = '\0';
97
	g_free (path);
98
99
	return real_path;
100
}
101
102
static char *
103
get_pipe_path (const char *app_path)
104
{
105
	char *pipe_path;
106
	char *real_app_path;
107
	char *terminated_path;
108
	const char *base_path;
109
110
	real_app_path = get_real_app_path (app_path);
111
	terminated_path = g_strconcat (real_app_path, "/", NULL);
112
113
	if (access(PIPEDEFAULTPATH, R_OK|W_OK) == 0)
114
		base_path = PIPEDEFAULTPATH;
115
	else
116
		base_path = PIPEALTERNATEPATH;
117
118
	pipe_path = g_strdup_printf (
119
			"%s/OSL_PIPE_%u_SingleOfficeIPC_%d-%x", base_path, (int)getuid(),
120
			SUPD, g_str_hash (terminated_path));
121
122
/*	fprintf (stderr, "pipe path is '%s' from '%s'\n", pipe_path, real_app_path); */
123
124
	g_free (terminated_path);
125
	g_free (real_app_path);
126
127
	return pipe_path;
128
}
129
130
static int
131
connect_pipe (const char *pipe_path)
132
{
133
	int fd;
134
	size_t len;
135
	struct sockaddr_un addr;
136
137
	memset(&addr, 0, sizeof(addr));
138
139
	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
140
		return fd;
141
142
	fcntl (fd, F_SETFD, FD_CLOEXEC);
143
144
	addr.sun_family = AF_UNIX;
145
	strncpy(addr.sun_path, pipe_path, sizeof(addr.sun_path));
146
147
/* cut / paste from osl's pipe.c */
148
#if defined(FREEBSD)
149
	len = SUN_LEN(&addr);
150
#else
151
	len = sizeof(addr);
152
#endif
153
154
	if (connect (fd, (struct sockaddr *)&addr, len) < 0)
155
		return -1;
156
157
	return fd;
158
}
159
160
static gboolean
161
send_args (int fd, GPtrArray *args, const char *cwd)
162
{
163
	int i, len;
164
	GString *arg_str = g_string_new ("");
165
166
	for (i = 1; i < args->len; i++)
167
	{
168
		g_string_append (arg_str, (char *)args->pdata[i]);
169
		g_string_append_c (arg_str, '|');
170
	}
171
172
#ifdef DEBUG		
173
	fprintf (stderr, "Pass args: '%s'\n", arg_str->str); 
174
#endif
175
	len = arg_str->len + 1;
176
177
	return write (fd, arg_str->str, len) == len;
178
}
179
180
typedef struct {
181
	gboolean finish;
182
	gboolean error;
183
	int percent;
184
}  StatusClosure;
185
186
static gboolean
187
status_pipe_update (GIOChannel * source,
188
                    GIOCondition condition, 
189
                    StatusClosure *cl)
190
{
191
	gboolean retval = TRUE;
192
193
#ifdef DEBUG
194
	fprintf (stderr, "Status pipe update (0x%x)\n", (int) condition);
195
#endif
196
197
	if ((int)condition & (G_IO_IN | G_IO_PRI))
198
	{
199
		int percent;
200
		GString *str = g_string_new ("");
201
		switch (g_io_channel_read_line_string (source, str, NULL, NULL)) {
202
			case G_IO_STATUS_ERROR:
203
				cl->error = TRUE;
204
				/* drop through */
205
			case G_IO_STATUS_EOF:
206
				retval = FALSE;
207
				break;
208
			default:
209
				/* pipe lifecycle is odd - HUP only for remote process death */
210
				if (!g_ascii_strncasecmp (str->str, "end", 3))
211
					retval = FALSE;
212
				if (sscanf (str->str, "%d%%", &percent))
213
					cl->percent = percent;
214
				break;
215
		}
216
		g_string_free (str, TRUE);
217
	}
218
219
	if ((int)condition & (G_IO_HUP | G_IO_NVAL | G_IO_ERR))
220
	{
221
		cl->error = TRUE;
222
		retval = FALSE;
223
	}
224
225
	if (!retval)
226
		cl->finish = TRUE;
227
228
	return retval;
229
}
230
231
static void
232
load_splash_image (const char *image_path)
233
{
234
	char *path;
235
	int success;
236
237
//	path = g_strconcat (image_path, "/intro-nld.bmp", NULL);
238
//	success = splash_load_bmp (path);
239
//	g_free (path);
240
//	if (success)
241
//		return;
242
243
	path = g_strconcat (image_path, "/intro.bmp", NULL);
244
	success = splash_load_bmp (path);
245
	g_free (path);
246
}
247
248
static void
249
show_splash (GIOChannel *status_channel)
250
{
251
	StatusClosure cl;
252
253
	/* setup closure */
254
	cl.finish = FALSE;
255
	cl.error = FALSE;
256
	cl.percent = 0;
257
258
	/* setup status listener ... */
259
	g_io_add_watch (status_channel, 
260
			(GIOCondition)(G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_NVAL | G_IO_ERR),
261
			(GIOFunc) status_pipe_update, (gpointer) &cl);
262
263
#ifdef DEBUG
264
	g_warning ("Start main loop...\n");
265
#endif
266
	while (!cl.finish)
267
	{
268
		splash_draw_progress (cl.percent);
269
		if ( g_main_context_pending (g_main_context_default ()) )
270
			g_main_context_iteration (g_main_context_default (), TRUE);
271
		else
272
			usleep (20000);
273
	}
274
275
	if (cl.error)
276
		g_warning ("Unknown error forking main binary / abnormal early exit ...");
277
278
	g_io_channel_shutdown (status_channel, FALSE, NULL);
279
	g_io_channel_unref (status_channel);
280
}
281
282
typedef struct {
283
	int pipe_fd;
284
	int clone_fd;
285
} ChildClosure;
286
287
static void
288
child_setup (gpointer user_data)
289
{
290
	ChildClosure *cl = (ChildClosure *)user_data;
291
	if (cl->pipe_fd >= 0)
292
		close (cl->pipe_fd);
293
	close (cl->clone_fd);
294
}
295
296
static void
297
system_checks (void)
298
{
299
#ifdef LINUX
300
	/* check proc is mounted - lots of things fail otherwise */
301
	if (!g_file_test ("/proc/version", G_FILE_TEST_EXISTS))
302
		g_warning ("/proc not mounted - OO.o is unlikely to work well if at all");
303
#endif
304
}
305
306
static gboolean
307
fork_app (const char *app_path, GPtrArray *args, int pipe_fd,
308
          GIOChannel **status_channel)
309
{
310
	int status_pipe[2];
311
	gboolean spawn_success;
312
	GError *error = NULL;
313
	char *splash_pipe_arg;
314
	ChildClosure *cl = g_new (ChildClosure, 1);
315
	GIOChannel *status;
316
317
	system_checks ();
318
319
	args->pdata[0] = (gpointer)g_strconcat (app_path, "/soffice", NULL);
320
321
	/* create pipe */
322
	if (pipe (status_pipe) < 0)
323
		g_error ("no file handles\n");
324
325
	status = g_io_channel_unix_new (status_pipe[0]);
326
	g_io_channel_set_encoding (status, NULL, NULL);
327
328
	splash_pipe_arg = g_strdup_printf ("-splash-pipe=%d", status_pipe[1]);
329
#ifdef DEBUG
330
	fprintf ( stderr, "Pass splash pipe arg: '%s'\n", splash_pipe_arg);
331
#endif
332
	g_ptr_array_add (args, splash_pipe_arg);
333
334
#ifdef DEBUG
335
	fprintf (stderr, "Fork app '%s' in '%s'\n", (char *)args->pdata[0], app_path);
336
#endif
337
	cl->pipe_fd = pipe_fd;
338
	cl->clone_fd = status_pipe[0];
339
	spawn_success = g_spawn_async
340
		(app_path, (char **)args->pdata, NULL,
341
		 G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
342
		 (GSpawnChildSetupFunc) child_setup,
343
		 (gpointer) cl,
344
		 NULL, /* child_pid */
345
		 &error);
346
	close (status_pipe[1]);
347
348
	if (!spawn_success)
349
		fprintf (stderr, "Error forking '%s/%s': '%s'\n",
350
				app_path, "/soffice",
351
				error ? error->message : "<no message>");
352
353
	*status_channel = status;
354
355
	return spawn_success;
356
}
357
358
static char *
359
convert_path (const char *arg, const char *cwd_str, gboolean not_filename)
360
{
361
	if (arg[0] == '-' || not_filename)
362
		return g_strdup (arg);
363
364
	if (strstr (arg, "://")) /* is URI */
365
		return g_strdup (arg);
366
367
	if (arg[0] == '/') /* absolute path */
368
		return g_strdup (arg);
369
370
	if (!strncmp (arg, "slot:", 5)) /* a slot */
371
		return g_strdup (arg);
372
373
	/* prepend cwd ... */
374
	return g_strconcat (cwd_str, "/", arg, NULL);
375
}
376
377
static gboolean
378
arg_check (const char *arg, const char *cmp_with)
379
{
380
	if (arg[0] == '-')
381
		arg++;
382
	else
383
		return FALSE;
384
	if (arg[0] == '-') /* tolerate -- prefixes etc. */
385
		arg++;
386
	return !g_ascii_strcasecmp (arg, cmp_with);
387
}
388
389
static GPtrArray *
390
setup_args (int argc, char **argv, const char *cwd_str,
391
            gboolean *inhibit_splash)
392
{
393
	int i;
394
	gboolean have_non_option = FALSE;
395
	gboolean next_arg_not_filename = FALSE;
396
	GPtrArray *args = g_ptr_array_sized_new (argc + 8);
397
398
	*inhibit_splash = FALSE;
399
400
	for (i = 0; i < argc; i++)
401
	{
402
		char *converted;
403
404
		if (i)
405
			converted = convert_path (argv[i], cwd_str, next_arg_not_filename);
406
		else
407
			converted = g_strdup (argv[i]);
408
		g_ptr_array_add (args, converted);
409
410
		if (!i)
411
			continue;
412
413
		if (argv[i][0] != '-')
414
			have_non_option = TRUE;
415
416
		else if (arg_check (argv[i], "nologo") ||
417
				 arg_check (argv[i], "headless") ||
418
				 arg_check (argv[i], "invisible"))
419
			*inhibit_splash = TRUE;
420
421
		else if (arg_check (argv[i], "-pt"))
422
			next_arg_not_filename = TRUE;
423
	}
424
425
	/* It's necessary to append eg. -writer for writer. */
426
	if (!have_non_option)
427
	{
428
		const char *extra_arg = g_getenv ("OOO_EXTRA_ARG");
429
		if (!extra_arg)
430
			g_error ("Missing default argument in OOO_EXTRA_ARG");
431
		if (extra_arg[0] != '\0')
432
			g_ptr_array_add (args, g_strdup (extra_arg));
433
	}
434
435
	return args;
436
}
437
438
int main (int argc, char **argv)
439
{
440
	int fd;
441
	gboolean inhibit_splash;
442
	GIOChannel *status_channel = NULL;
443
	gboolean sent_args = FALSE;
444
	char *app_path, *pipe_path;
445
	GPtrArray *args;
446
	char cwd_str[PATH_MAX];
447
448
	/* turn SIGPIPE into an error */
449
	signal (SIGPIPE, SIG_IGN);
450
	if (!getcwd (cwd_str, sizeof (cwd_str)))
451
		g_error ("can't get cwd");
452
	cwd_str[sizeof(cwd_str)-1] = '\0';
453
454
	args = setup_args (argc, argv, cwd_str, &inhibit_splash);
455
456
	app_path = get_app_path (argv[0]);
457
	if (!app_path)
458
		g_error ("Pathalogical failure: can't read app link\n");
459
460
	load_splash_image (app_path);
461
462
	pipe_path = get_pipe_path (app_path);
463
464
	if ((fd = connect_pipe (pipe_path)) >= 0)
465
		sent_args = send_args (fd, args, cwd_str);
466
#ifdef DEBUG
467
	else
468
		fprintf (stderr, "Failed to connect to pipe '%s'\n", pipe_path);
469
#endif
470
471
	if (!sent_args)
472
	{
473
		if (!inhibit_splash)
474
		{
475
			if (splash_create_window (argc, argv))
476
				splash_draw_progress (0);
477
			else
478
				inhibit_splash = TRUE;
479
		}
480
481
		if (! fork_app (app_path, args, fd, &status_channel))
482
			return 1;
483
484
		if (!inhibit_splash)
485
		{
486
			show_splash (status_channel);
487
			splash_close_window ();
488
		}
489
	}
490
491
	g_ptr_array_foreach (args, (GFunc)g_free, NULL);
492
	g_ptr_array_free (args, TRUE);
493
	g_free (app_path);
494
495
	return 0;
496
}

Return to issue 60696