1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <config_features.h>
13 #if defined(ENABLE_QUICKSTART_LIBPNG) && HAVE_FEATURE_UI
16 #include <X11/Xatom.h>
17 #include <X11/Xutil.h>
20 #include <X11/extensions/Xinerama.h>
23 #include <osl/endian.h>
33 #include <osl/process.h>
34 #include <osl/thread.h>
35 #include <rtl/bootstrap.h>
36 #include <rtl/ustrbuf.h>
39 unsigned char b
, g
, r
;
59 //true when intro-highres loaded successfully
60 sal_Bool bHasHiDpiImage
;
62 // Progress bar values
63 // taken from desktop/source/splash/splash.cxx
75 unsigned char** bitmap_rows
;
81 #define WINDOW_WIDTH 440
82 #define WINDOW_HEIGHT 299
84 #define PROGRESS_XOFFSET 12
85 #define PROGRESS_YOFFSET 18
86 #define PROGRESS_BARSPACE 2
89 #ifndef PNG_TRANSFORM_GRAY_TO_RGB
90 # define PNG_TRANSFORM_GRAY_TO_RGB 0x2000
93 static int splash_load_bmp( struct splash
* splash
, const char *filename
)
97 if ( !(file
= fopen( filename
, "r" ) ) )
100 splash
->png_ptr
= png_create_read_struct( PNG_LIBPNG_VER_STRING
, NULL
, NULL
, NULL
);
101 splash
->info_ptr
= png_create_info_struct(splash
->png_ptr
);
102 png_init_io( splash
->png_ptr
, file
);
104 if( setjmp( png_jmpbuf( splash
->png_ptr
) ) )
106 png_destroy_read_struct( &(splash
->png_ptr
), &(splash
->info_ptr
), NULL
);
111 png_read_png( splash
->png_ptr
, splash
->info_ptr
,
112 PNG_TRANSFORM_EXPAND
| PNG_TRANSFORM_STRIP_ALPHA
|
113 PNG_TRANSFORM_GRAY_TO_RGB
| PNG_TRANSFORM_BGR
, NULL
);
115 splash
->bitmap_rows
= png_get_rows( splash
->png_ptr
, splash
->info_ptr
);
116 splash
->width
= png_get_image_width( splash
->png_ptr
, splash
->info_ptr
);
117 splash
->height
= png_get_image_height( splash
->png_ptr
, splash
->info_ptr
);
123 static void setup_color( int const val
[3], color_t
*col
)
125 if ( val
[0] < 0 || val
[1] < 0 || val
[2] < 0 )
128 #define CONVERT_COLOR( from,to ) if ( from < 0 ) to = 0; else if ( from > 255 ) to = 255; else to = from;
129 CONVERT_COLOR( val
[0], col
->r
);
130 CONVERT_COLOR( val
[1], col
->g
);
131 CONVERT_COLOR( val
[2], col
->b
);
135 /* Fill 'array' with values of the key 'name'.
136 Its value is a comma delimited list of integers */
137 static void get_bootstrap_value( int *array
, int size
, rtlBootstrapHandle handle
, const char *name
)
139 rtl_uString
*pKey
= NULL
, *pValue
= NULL
;
141 /* get the value from the ini file */
142 rtl_uString_newFromAscii( &pKey
, name
);
143 rtl_bootstrap_get_from_handle( handle
, pKey
, &pValue
, NULL
);
145 /* the value is several numbers delimited by ',' - parse it */
146 if ( rtl_uString_getLength( pValue
) > 0 )
148 rtl_uString
*pToken
= NULL
;
150 sal_Int32 nIndex
= 0;
151 for ( ; ( nIndex
>= 0 ) && ( i
< size
); ++i
)
153 nIndex
= rtl_uString_getToken( &pToken
, pValue
, 0, ',', nIndex
);
154 array
[i
] = rtl_ustr_toInt32( rtl_uString_getStr( pToken
), 10 );
157 rtl_uString_release( pToken
);
161 rtl_uString_release( pKey
);
162 rtl_uString_release( pValue
);
166 static void splash_setup( struct splash
* splash
, int const barc
[3], int const framec
[3], int posx
, int posy
, int w
, int h
)
168 if ( splash
->width
<= 500 )
170 splash
->barwidth
= splash
->width
- ( 2 * PROGRESS_XOFFSET
);
171 splash
->barheight
= 6;
172 splash
->tlx
= PROGRESS_XOFFSET
;
173 splash
->tly
= splash
->height
- PROGRESS_YOFFSET
;
175 splash
->barcol
.r
= 0;
176 splash
->barcol
.g
= 0;
177 splash
->barcol
.b
= 128;
185 splash
->barwidth
= w
;
187 splash
->barheight
= h
;
189 setup_color( barc
, &(splash
->barcol
) );
190 setup_color( framec
, &(splash
->framecol
) );
193 // Universal shift: bits >= 0 - left, otherwise right
194 #define SHIFT( x, bits ) ( ( (bits) >= 0 )? ( (x) << (bits) ): ( (x) >> -(bits) ) )
196 // Position of the highest bit (more or less integer log2)
197 static int HIGHEST_BIT( unsigned long x
)
206 // Number of bits set to 1
207 static int BITS( unsigned long x
)
217 // Set 'bitmap' as the background of our 'win' window
218 static void create_pixmap(struct splash
* splash
)
224 if ( !splash
->bitmap_rows
)
228 pixmap
= XCreatePixmap( splash
->display
, splash
->win
, splash
->width
, splash
->height
, splash
->depth
);
230 pixmap_gc
= XCreateGC( splash
->display
, pixmap
, 0/*value_mask*/, &values
);
232 if ( splash
->visual
->class == TrueColor
)
234 const unsigned long red_mask
= splash
->visual
->red_mask
;
235 const unsigned long green_mask
= splash
->visual
->green_mask
;
236 const unsigned long blue_mask
= splash
->visual
->blue_mask
;
238 const unsigned long red_delta_mask
= ( 1UL << ( 8 - BITS( red_mask
) ) ) - 1;
239 const unsigned long green_delta_mask
= ( 1UL << ( 8 - BITS( green_mask
) ) ) - 1;
240 const unsigned long blue_delta_mask
= ( 1UL << ( 8 - BITS( blue_mask
) ) ) - 1;
242 const int red_shift
= HIGHEST_BIT( red_mask
) - 8;
243 const int green_shift
= HIGHEST_BIT( green_mask
) - 8;
244 const int blue_shift
= HIGHEST_BIT( blue_mask
) - 8;
246 XImage
* image
= XCreateImage( splash
->display
, splash
->visual
, splash
->depth
, ZPixmap
,
247 0, NULL
, splash
->width
, splash
->height
, 32, 0 );
249 const int bytes_per_line
= image
->bytes_per_line
;
250 const int bpp
= image
->bits_per_pixel
;
251 const int byte_order
= image
->byte_order
;
252 #if defined OSL_LITENDIAN
253 const int machine_byte_order
= LSBFirst
;
254 #else /* OSL_BIGENDIAN */
255 const int machine_byte_order
= MSBFirst
;
258 char *data
= malloc( splash
->height
* bytes_per_line
);
262 // The following dithers & converts the color_t color to one
263 // acceptable for the visual
264 #define COPY_IN_OUT( pix_size, code ) \
267 for ( y = 0; y < splash->height; ++y ) \
269 unsigned long red_delta = 0, green_delta = 0, blue_delta = 0; \
270 color_t *in = (color_t *)(splash->bitmap_rows[y]); \
271 out = data + y * bytes_per_line; \
272 for ( x = 0; x < splash->width; ++x, ++in ) \
274 unsigned long red = in->r + red_delta; \
275 unsigned long green = in->g + green_delta; \
276 unsigned long blue = in->b + blue_delta; \
277 unsigned long pixel = 0; \
280 red_delta = red & red_delta_mask; \
281 green_delta = green & green_delta_mask; \
282 blue_delta = blue & blue_delta_mask; \
290 ( SHIFT( red, red_shift ) & red_mask ) | \
291 ( SHIFT( green, green_shift ) & green_mask ) | \
292 ( SHIFT( blue, blue_shift ) & blue_mask ); \
300 if ( machine_byte_order
== byte_order
)
301 COPY_IN_OUT( 4, *( (uint32_t *)out
) = (uint32_t)pixel
; out
+= 4; )
303 COPY_IN_OUT( 4, tmp
= pixel
;
304 *( (uint8_t *)out
) = *( (uint8_t *)(&tmp
) + 3 );
305 *( (uint8_t *)out
+ 1 ) = *( (uint8_t *)(&tmp
) + 2 );
306 *( (uint8_t *)out
+ 2 ) = *( (uint8_t *)(&tmp
) + 1 );
307 *( (uint8_t *)out
+ 3 ) = *( (uint8_t *)(&tmp
) );
310 else if ( bpp
== 24 )
312 if (machine_byte_order
== byte_order
)
314 #if defined OSL_LITENDIAN
315 COPY_IN_OUT( 3, memcpy(out
, &pixel
, sizeof (color_t
)); out
+= 3; )
316 #else /* OSL_BIGENDIAN */
317 COPY_IN_OUT( 3, tmp
= pixel
;
318 *( (uint8_t *)out
) = *( (uint8_t *)(&tmp
) + 1 );
319 *( (uint8_t *)out
+ 1 ) = *( (uint8_t *)(&tmp
) + 2 );
320 *( (uint8_t *)out
+ 2 ) = *( (uint8_t *)(&tmp
) + 3 );
325 COPY_IN_OUT( 3, tmp
= pixel
;
326 *( (uint8_t *)out
) = *( (uint8_t *)(&tmp
) + 3 );
327 *( (uint8_t *)out
+ 1 ) = *( (uint8_t *)(&tmp
) + 2 );
328 *( (uint8_t *)out
+ 2 ) = *( (uint8_t *)(&tmp
) + 1 );
331 else if ( bpp
== 16 )
333 if ( machine_byte_order
== byte_order
)
334 COPY_IN_OUT( 2, *( (uint16_t *)out
) = (uint16_t)pixel
; out
+= 2; )
336 COPY_IN_OUT( 2, tmp
= pixel
;
337 *( (uint8_t *)out
) = *( (uint8_t *)(&tmp
) + 1 );
338 *( (uint8_t *)out
+ 1 ) = *( (uint8_t *)(&tmp
) );
343 COPY_IN_OUT( 1, *( (uint8_t *)out
) = (uint8_t)pixel
; ++out
; )
347 fprintf( stderr
, "Unsupported depth: %d bits per pixel.\n", bpp
);
348 XFreeGC( splash
->display
, pixmap_gc
);
349 XFreePixmap( splash
->display
, pixmap
);
350 XDestroyImage( image
);
356 XPutImage( splash
->display
, pixmap
, pixmap_gc
, image
, 0, 0, 0, 0, splash
->width
, splash
->height
);
357 XDestroyImage( image
);
360 XSetWindowBackgroundPixmap( splash
->display
, splash
->win
, pixmap
);
362 XFreeGC( splash
->display
, pixmap_gc
);
363 XFreePixmap( splash
->display
, pixmap
);
366 // The old method of hiding the window decorations
367 static void suppress_decorations_motif(struct splash
* splash
)
371 unsigned long flags
, functions
, decorations
;
375 Atom a
= XInternAtom( splash
->display
, "_MOTIF_WM_HINTS", False
);
377 mwmhints
.flags
= 15; // functions, decorations, input_mode, status
378 mwmhints
.functions
= 2; // ?
379 mwmhints
.decorations
= 0;
380 mwmhints
.input_mode
= 0;
382 XChangeProperty( splash
->display
, splash
->win
, a
, a
, 32,
383 PropModeReplace
, (unsigned char*)&mwmhints
, 5 );
386 // This is a splash, set it as such.
387 // If it fails, just hide the decorations...
388 static void suppress_decorations(struct splash
* splash
)
390 Atom atom_type
= XInternAtom( splash
->display
, "_NET_WM_WINDOW_TYPE", True
);
391 Atom atom_splash
= XInternAtom( splash
->display
, "_NET_WM_WINDOW_TYPE_SPLASH", True
);
393 if ( atom_type
!= None
&& atom_splash
!= None
)
394 XChangeProperty( splash
->display
, splash
->win
, atom_type
, XA_ATOM
, 32,
395 PropModeReplace
, (unsigned char*)&atom_splash
, 1 );
397 suppress_decorations_motif(splash
); // FIXME: Unconditional until Metacity/compiz's SPLASH handling is fixed
401 * Connects to the display and initializes splash with the screen details
403 * @return Success: 1; Failure: 0
405 static int splash_init_display( struct splash
* splash
, int argc
, char** argv
)
407 char *display_name
= NULL
;
410 int n_xinerama_screens
= 1;
411 XineramaScreenInfo
* p_screens
= NULL
;
414 for ( i
= 0; i
< argc
; i
++ )
416 if ( !strcmp( argv
[i
], "-display" ) || !strcmp( argv
[i
], "--display" ) )
418 display_name
= ( i
+ 1 < argc
)? argv
[i
+1]: NULL
;
424 display_name
= getenv( "DISPLAY" );
427 splash
->display
= XOpenDisplay( display_name
);
428 if ( !splash
->display
)
430 fprintf( stderr
, "Failed to open display\n" );
435 splash
->screen
= DefaultScreen( splash
->display
);
436 splash
->depth
= DefaultDepth( splash
->display
, splash
->screen
);
437 splash
->color_map
= DefaultColormap( splash
->display
, splash
->screen
);
438 splash
->visual
= DefaultVisual( splash
->display
, splash
->screen
);
440 splash
->display_width
= DisplayWidth( splash
->display
, splash
->screen
);
441 splash
->display_height
= DisplayHeight( splash
->display
, splash
->screen
);
442 splash
->display_x_pos
= 0;
443 splash
->display_y_pos
= 0;
446 p_screens
= XineramaQueryScreens( splash
->display
, &n_xinerama_screens
);
449 for( i
=0; i
< n_xinerama_screens
; i
++ )
451 if ( p_screens
[i
].screen_number
== splash
->screen
)
453 splash
->display_width
= p_screens
[i
].width
;
454 splash
->display_height
= p_screens
[i
].height
;
455 splash
->display_x_pos
= p_screens
[i
].x_org
;
456 splash
->display_y_pos
= p_screens
[i
].y_org
;
467 * Create the window for the splash screen
469 * @return Success: 1; Failure: 0
471 static int splash_create_window(struct splash
* splash
)
475 const char* name
= "LibreOffice";
476 const char* icon
= "icon"; // FIXME
477 XSizeHints size_hints
;
479 root_win
= RootWindow( splash
->display
, splash
->screen
);
481 splash
->win
= XCreateSimpleWindow( splash
->display
, root_win
,
482 (splash
->display_x_pos
+ (splash
->display_width
- splash
->width
)/2),
483 (splash
->display_y_pos
+ (splash
->display_height
- splash
->height
)/2),
484 splash
->width
, splash
->height
, 0,
485 BlackPixel( splash
->display
, splash
->screen
), BlackPixel( splash
->display
, splash
->screen
) );
487 XSetWindowColormap( splash
->display
, splash
->win
, splash
->color_map
);
490 #define FILL_COLOR( xcol,col ) xcol.red = 256*col.r; xcol.green = 256*col.g; xcol.blue = 256*col.b;
491 FILL_COLOR( splash
->barcolor
, splash
->barcol
);
492 FILL_COLOR( splash
->framecolor
, splash
->framecol
);
495 XAllocColor( splash
->display
, splash
->color_map
, &(splash
->barcolor
) );
496 XAllocColor( splash
->display
, splash
->color_map
, &(splash
->framecolor
) );
498 // not resizable, no decorations, etc.
499 splash
->gc
= XCreateGC( splash
->display
, splash
->win
, 0/*value_mask*/, &values
);
501 size_hints
.flags
= PPosition
| PSize
| PMinSize
| PMaxSize
;
502 size_hints
.x
= splash
->display_x_pos
;
503 size_hints
.y
= splash
->display_y_pos
;
504 size_hints
.width
= splash
->width
;
505 size_hints
.height
= splash
->height
;
506 size_hints
.min_width
= splash
->width
;
507 size_hints
.max_width
= splash
->width
;
508 size_hints
.min_height
= splash
->height
;
509 size_hints
.max_height
= splash
->height
;
511 XSetStandardProperties( splash
->display
, splash
->win
, name
, icon
, None
,
512 NULL
, 0, &size_hints
);
515 suppress_decorations(splash
);
516 create_pixmap(splash
);
519 XSelectInput( splash
->display
, splash
->win
, 0 );
520 XMapWindow( splash
->display
, splash
->win
);
525 // Re-draw & process the events
526 // Just throwing them away - we do not need anything more...
527 static void process_events(struct splash
* splash
)
532 XFlush( splash
->display
);
533 num_events
= XPending( splash
->display
);
534 while ( num_events
> 0 )
537 XNextEvent( splash
->display
, &xev
);
542 static rtl_String
* ustr_to_str( rtl_uString
* pStr
)
544 rtl_String
*pOut
= NULL
;
546 rtl_uString2String( &pOut
, rtl_uString_getStr( pStr
),
547 rtl_uString_getLength( pStr
), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
);
552 static sal_Bool
isHiDPI(struct splash
* splash
)
558 * GNOME currently enables HiDPI support when the screen resolution is at least 192 dpi
559 * and the screen height (in device pixels) is at least 1200.
562 if (splash
->display_height
< 1200)
565 pValStr
= XGetDefault(splash
->display
, "Xft", "dpi");
566 /* if it's too old to have this, assume it's not hidpi */
570 nDPI
= strtod(pValStr
, NULL
);
577 #define IMG_SUFFIX ".png"
579 static void splash_load_image( struct splash
* splash
, rtl_uString
* pUAppPath
)
581 /* FIXME-BCP47: if we wanted to support language tags here that would get
582 * complicated, this is C-source not C++ so LanguageTag can't be used. For
583 * now the splash screen will have to get along with language-territory. */
585 char *pBuffer
, *pSuffix
, *pLocale
;
587 rtl_Locale
*pLoc
= NULL
;
588 rtl_String
*pLang
, *pCountry
, *pAppPath
;
590 osl_getProcessLocale (&pLoc
);
591 pLang
= ustr_to_str (pLoc
->Language
);
592 pCountry
= ustr_to_str (pLoc
->Country
);
594 nLocSize
= strlen (pLang
->buffer
) + strlen (pCountry
->buffer
) + 3;
595 pLocale
= malloc (nLocSize
);
597 strcpy (pLocale
+ 1, pLang
->buffer
);
598 strcat (pLocale
, "_");
599 strcat (pLocale
, pCountry
->buffer
);
601 rtl_string_release( pCountry
);
602 rtl_string_release( pLang
);
604 pAppPath
= ustr_to_str (pUAppPath
);
605 pBuffer
= malloc (pAppPath
->length
+ nLocSize
+ 256);
606 strcpy (pBuffer
, pAppPath
->buffer
);
607 pSuffix
= pBuffer
+ pAppPath
->length
;
608 rtl_string_release( pAppPath
);
610 strcpy (pSuffix
, "intro");
611 strcat (pSuffix
, pLocale
);
612 strcat (pSuffix
, IMG_SUFFIX
);
613 if ( splash_load_bmp( splash
, pBuffer
) )
614 goto cleanup
; /* success */
616 /* load high resolution splash image */
617 splash
->bHasHiDpiImage
= sal_False
;
620 strcpy (pSuffix
, "intro-highres" IMG_SUFFIX
);
621 if ( splash_load_bmp( splash
, pBuffer
) )
623 splash
->bHasHiDpiImage
= sal_True
;
624 goto cleanup
; /* success */
627 /* load standard resolution splash image */
628 strcpy (pSuffix
, "intro" IMG_SUFFIX
);
629 if ( splash_load_bmp( splash
, pBuffer
) )
630 goto cleanup
; /* success */
632 fprintf (stderr
, "Failed to find intro image\n");
639 /* Load the colors and size of the splash. */
640 static void splash_load_defaults( struct splash
* splash
, rtl_uString
* pAppPath
, sal_Bool
* bNoDefaults
)
642 rtl_uString
*pSettings
= NULL
, *pTmp
= NULL
;
643 rtlBootstrapHandle handle
;
644 int logo
[1] = { -1 },
645 bar
[3] = { -1, -1, -1 },
646 frame
[3] = { -1, -1, -1 },
648 size
[2] = { -1, -1 };
650 /* construct the sofficerc file location */
651 rtl_uString_newFromAscii( &pSettings
, "file://" );
652 rtl_uString_newConcat( &pSettings
, pSettings
, pAppPath
);
653 rtl_uString_newConcat( &pSettings
, pSettings
, pTmp
);
654 rtl_uString_newFromAscii( &pTmp
, SAL_CONFIGFILE( "soffice" ) );
655 rtl_uString_newConcat( &pSettings
, pSettings
, pTmp
);
657 /* use it as the bootstrap file */
658 handle
= rtl_bootstrap_args_open( pSettings
);
661 get_bootstrap_value( logo
, 1, handle
, "Logo" );
662 get_bootstrap_value( bar
, 3, handle
, "ProgressBarColor" );
663 get_bootstrap_value( frame
, 3, handle
, "ProgressFrameColor" );
664 if (isHiDPI(splash
) && splash
->bHasHiDpiImage
)
666 get_bootstrap_value( pos
, 2, handle
, "ProgressPositionHigh" );
667 get_bootstrap_value( size
, 2, handle
, "ProgressSizeHigh" );
671 get_bootstrap_value( pos
, 2, handle
, "ProgressPosition" );
672 get_bootstrap_value( size
, 2, handle
, "ProgressSize" );
677 *bNoDefaults
= sal_True
;
680 splash_setup( splash
, bar
, frame
, pos
[0], pos
[1], size
[0], size
[1] );
683 rtl_bootstrap_args_close( handle
);
684 rtl_uString_release( pSettings
);
685 rtl_uString_release( pTmp
);
690 void splash_draw_progress( struct splash
* splash
, int progress
)
703 if ( progress
> 100 )
708 length
= ( progress
* splash
->barwidth
/ 100 ) - ( 2 * splash
->barspace
);
714 XSetForeground( splash
->display
, splash
->gc
, splash
->framecolor
.pixel
);
715 XDrawRectangle( splash
->display
, splash
->win
, splash
->gc
, splash
->tlx
, splash
->tly
,
716 splash
->barwidth
, splash
->barheight
);
719 XSetForeground( splash
->display
, splash
->gc
, splash
->barcolor
.pixel
);
720 XFillRectangle( splash
->display
, splash
->win
, splash
->gc
,
721 splash
->tlx
+ splash
->barspace
, splash
->tly
+ splash
->barspace
,
722 length
+ 1, splash
->barheight
- 2 * splash
->barspace
+ 1 );
725 process_events(splash
);
728 void splash_destroy(struct splash
* splash
)
737 XFreeGC(splash
->display
, splash
->gc
);
741 XCloseDisplay( splash
->display
);
742 splash
->display
= NULL
;
743 png_destroy_read_struct( &(splash
->png_ptr
), &(splash
->info_ptr
), NULL
);
748 struct splash
* splash_create(rtl_uString
* pAppPath
, int argc
, char** argv
)
750 struct splash
* splash
;
751 sal_Bool bNoDefaults
= sal_False
;
753 splash
= calloc(1, sizeof(struct splash
));
754 if (splash
&& !splash_init_display(splash
, argc
, argv
))
756 splash_destroy(splash
);
763 splash
->width
= WINDOW_WIDTH
;
764 splash
->height
= WINDOW_HEIGHT
;
768 splash
->barwidth
= 263;
769 splash
->barheight
= 8;
770 splash
->barspace
= PROGRESS_BARSPACE
;
771 splash
->barcol
.b
= 18;
772 splash
->barcol
.g
= 202;
773 splash
->barcol
.r
= 157;
774 splash
->framecol
.b
= 0xD3;
775 splash
->framecol
.g
= 0xD3;
776 splash
->framecol
.r
= 0xD3;
778 splash_load_image( splash
, pAppPath
);
779 splash_load_defaults( splash
, pAppPath
, &bNoDefaults
);
781 if (!bNoDefaults
&& splash_create_window(splash
))
783 splash_draw_progress( splash
, 0 );
787 splash_destroy(splash
);
791 #else /* not ENABLE_QUICKSTART_LIBPNG */
797 /* Stubs that will never be called in this case */
798 void splash_draw_progress( struct splash
* splash
, int progress
)
800 (void)splash
; (void)progress
;
803 void splash_destroy(struct splash
* splash
)
808 struct splash
* splash_create(rtl_uString
* pAppPath
, int argc
, char** argv
)
810 (void)pAppPath
; (void)argc
; (void)argv
;
815 #endif // ENABLE_QUICKSTART_LIBPNG
817 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */