Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/desktop/unx/source/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 23 kB image not shown  

Quelle  splashx.c   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */


#include <config_vclplug.h>
#include "splashx.h"

#if defined(ENABLE_QUICKSTART_LIBPNG) && USING_X11

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#include <X11/extensions/Xinerama.h>

#include <osl/endian.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <png.h>

#include <osl/process.h>
#include <osl/thread.h>
#include <rtl/bootstrap.h>
#include <rtl/ustrbuf.h>

typedef struct {
    unsigned char b, g, r;
} color_t;

struct splash
{
    Display* display;
    int screen;
    int depth;
    int display_width;
    int display_height;
    int display_x_pos;
    int display_y_pos;
    Visual* visual;

    int width;
    int height;

    Colormap color_map;
    Window win;
    GC gc;
    //true when intro-highres loaded successfully
    sal_Bool bHasHiDpiImage;

// Progress bar values
// taken from desktop/source/splash/splash.cxx
    int tlx;
    int tly;
    int barwidth;
    int barheight;
    int barspace;
    color_t barcol;
    color_t framecol;

    XColor barcolor;
    XColor framecolor;

    unsigned char** bitmap_rows;
    png_structp png_ptr;
    png_infop info_ptr;

};

#define WINDOW_WIDTH  440
#define WINDOW_HEIGHT 299

#define PROGRESS_XOFFSET 12
#define PROGRESS_YOFFSET 18
#define PROGRESS_BARSPACE 2

/* libpng-1.2.41 */
#ifndef PNG_TRANSFORM_GRAY_TO_RGB
#  define PNG_TRANSFORM_GRAY_TO_RGB   0x2000
#endif

static int splash_load_bmp( struct splash* splash, const char *filename )
{
    FILE *file;

    if ( !(file = fopen( filename, "r" ) ) )
        return 0;

    splash->png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
    splash->info_ptr = png_create_info_struct(splash->png_ptr);
    png_init_io( splash->png_ptr, file );

    if( setjmp( png_jmpbuf( splash->png_ptr ) ) )
    {
        png_destroy_read_struct( &(splash->png_ptr), &(splash->info_ptr), NULL );
        fclose( file );
        return 0;
    }

    png_read_png( splash->png_ptr, splash->info_ptr,
                  PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA |
                  PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_BGR, NULL);

    splash->bitmap_rows = png_get_rows( splash->png_ptr, splash->info_ptr );
    splash->width = png_get_image_width( splash->png_ptr, splash->info_ptr );
    splash->height = png_get_image_height( splash->png_ptr, splash->info_ptr );

    fclose( file );
    return 1;
}

static void setup_color( int const 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
}

/* 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;

    /* 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;
        int i = 0;
        sal_Int32 nIndex = 0;
        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 );
}

// setup
static void splash_setup( struct splash* splash, int const barc[3], int const framec[3], int posx, int posy, int w, int h )
{
    if ( splash->width <= 500 )
    {
        splash->barwidth  = splash->width - ( 2 * PROGRESS_XOFFSET );
        splash->barheight = 6;
        splash->tlx = PROGRESS_XOFFSET;
        splash->tly = splash->height - PROGRESS_YOFFSET;

        splash->barcol.r = 0;
        splash->barcol.g = 0;
        splash->barcol.b = 128;
    }

    if ( posx >= 0 )
        splash->tlx = posx;
    if ( posy >= 0 )
        splash->tly = posy;
    if ( w >= 0 )
        splash->barwidth = w;
    if ( h >= 0 )
        splash->barheight = h;

    setup_color( barc, &(splash->barcol) );
    setup_color( framec, &(splash->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)
static int HIGHEST_BIT( unsigned long x )
{
    int i = 0;
    for ( ; x; ++i )
        x >>= 1;

    return i;
}

// Number of bits set to 1
static 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(struct splash* splash)
{
    Pixmap pixmap;
    GC pixmap_gc;
    XGCValues values;

    if ( !splash->bitmap_rows )
    {
        return;
    }
    pixmap = XCreatePixmap( splash->display, splash->win, splash->width, splash->height, splash->depth );

    pixmap_gc = XCreateGC( splash->display, pixmap, 0/*value_mask*/, &values );

    if ( splash->visual->class == TrueColor )
    {
        const unsigned long red_mask   = splash->visual->red_mask;
        const unsigned long green_mask = splash->visual->green_mask;
        const unsigned long blue_mask  = splash->visual->blue_mask;

        const unsigned long red_delta_mask   = ( 1UL << ( 8 - BITS( red_mask ) ) ) - 1;
        const unsigned long green_delta_mask = ( 1UL << ( 8 - BITS( green_mask ) ) ) - 1;
        const unsigned long blue_delta_mask  = ( 1UL << ( 8 - BITS( blue_mask ) ) ) - 1;

        const int red_shift   = HIGHEST_BIT( red_mask ) - 8;
        const int green_shift = HIGHEST_BIT( green_mask ) - 8;
        const int blue_shift  = HIGHEST_BIT( blue_mask ) - 8;

        XImage* image = XCreateImage( splash->display, splash->visual, splash->depth, ZPixmap,
                                      0, NULL, splash->width, splash->height, 32, 0 );

        const int bytes_per_line = image->bytes_per_line;
        const int bpp = image->bits_per_pixel;
        const int byte_order = image->byte_order;
#if defined OSL_LITENDIAN
        const int machine_byte_order = LSBFirst;
#else /* OSL_BIGENDIAN */
        const int machine_byte_order = MSBFirst;
#endif

        char *data = malloc( splash->height * bytes_per_line );
        char *out = data;
        image->data = data;

        // The following dithers & converts the color_t color to one
        // acceptable for the visual
#define COPY_IN_OUT( pix_size, code ) \
        { \
            int x, y; \
            for ( y = 0; y < splash->height; ++y ) \
            { \
                unsigned long red_delta = 0, green_delta = 0, blue_delta = 0; \
                color_t *in = (color_t *)(splash->bitmap_rows[y]);      \
                out = data + y * bytes_per_line; \
                for ( x = 0; x < splash->width; ++x, ++in  ) \
                { \
                    unsigned long red   = in->r + red_delta; \
                    unsigned long green = in->g + green_delta; \
                    unsigned long blue  = in->b + blue_delta; \
                    unsigned long pixel = 0; \
                    uint32_t tmp = 0; \
                    (void) tmp; \
                    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; \
                    pixel = \
                        ( SHIFT( red, red_shift ) & red_mask ) | \
                        ( SHIFT( green, green_shift ) & green_mask ) | \
                        ( SHIFT( blue, blue_shift ) & blue_mask ); \
                    code \
                } \
            } \
        }

        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, 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)
            {
#if defined OSL_LITENDIAN
                COPY_IN_OUT( 3, memcpy(out, &pixel, sizeof (color_t)); out += 3; )
#else /* OSL_BIGENDIAN */
                COPY_IN_OUT( 3, 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; )
#endif
            }
            else
                COPY_IN_OUT( 3, 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, 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( splash->display, pixmap_gc );
            XFreePixmap( splash->display, pixmap );
            XDestroyImage( image );
            return;
        }

#undef COPY_IN_OUT

        XPutImage( splash->display, pixmap, pixmap_gc, image, 0, 0, 0, 0, splash->width, splash->height );
        XDestroyImage( image );
    }

    XSetWindowBackgroundPixmap( splash->display, splash->win, pixmap );

    XFreeGC( splash->display, pixmap_gc );
    XFreePixmap( splash->display, pixmap );
}

// The old method of hiding the window decorations
static void suppress_decorations_motif(struct splash* splash)
{
    struct
    {
        unsigned long flags, functions, decorations;
        long input_mode;
    } mwmhints;

    Atom a = XInternAtom( splash->display, "_MOTIF_WM_HINTS"False );

    mwmhints.flags = 15; // functions, decorations, input_mode, status
    mwmhints.functions = 2; // ?
    mwmhints.decorations = 0;
    mwmhints.input_mode = 0;

    XChangeProperty( splash->display, splash->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(struct splash* splash)
{
    Atom atom_type = XInternAtom( splash->display, "_NET_WM_WINDOW_TYPE"True );
    Atom atom_splash = XInternAtom( splash->display, "_NET_WM_WINDOW_TYPE_SPLASH"True );

    if ( atom_type != None && atom_splash != None )
        XChangeProperty( splash->display, splash->win, atom_type, XA_ATOM, 32,
                         PropModeReplace, (unsigned char*)&atom_splash, 1 );
    //else
    suppress_decorations_motif(splash); // FIXME: Unconditional until Metacity/compiz's SPLASH handling is fixed
}

/**
 * Connects to the display and initializes splash with the screen details
 *
 * @return Success: 1; Failure: 0
 */

static int splash_init_display( struct splash* splash, int argc, char** argv )
{
    char *display_name = NULL;
    int i;
    int n_xinerama_screens = 1;
    XineramaScreenInfo* p_screens = NULL;

    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
    splash->display = XOpenDisplay( display_name );
    if ( !splash->display )
    {
        fprintf( stderr, "Failed to open display\n" );
        return 0;
    }

    // create the window
    splash->screen = DefaultScreen( splash->display );
    splash->depth = DefaultDepth( splash->display, splash->screen );
    splash->color_map = DefaultColormap( splash->display, splash->screen );
    splash->visual = DefaultVisual( splash->display, splash->screen );

    splash->display_width = DisplayWidth( splash->display, splash->screen );
    splash->display_height = DisplayHeight( splash->display, splash->screen );
    splash->display_x_pos = 0;
    splash->display_y_pos = 0;

    p_screens = XineramaQueryScreens( splash->display, &n_xinerama_screens );
    if( p_screens )
    {
        for( i=0; i < n_xinerama_screens; i++ )
        {
            if ( p_screens[i].screen_number == splash->screen )
            {
                splash->display_width = p_screens[i].width;
                splash->display_height = p_screens[i].height;
                splash->display_x_pos = p_screens[i].x_org;
                splash->display_y_pos = p_screens[i].y_org;
                break;
            }
        }
        XFree( p_screens );
    }
    return 1;
}

/**
 * Create the window for the splash screen
 *
 * @return Success: 1; Failure: 0
 */

static int splash_create_window(struct splash* splash)
{
    Window root_win;
    XGCValues values;
    const char* name = "LibreOffice";
    const char* icon = "icon"// FIXME
    XSizeHints size_hints;

    root_win = RootWindow( splash->display, splash->screen );

    splash->win = XCreateSimpleWindow( splash->display, root_win,
            (splash->display_x_pos + (splash->display_width - splash->width)/2),
            (splash->display_y_pos + (splash->display_height - splash->height)/2),
            splash->width, splash->height, 0,
            BlackPixel( splash->display, splash->screen ), BlackPixel( splash->display, splash->screen ) );

    XSetWindowColormap( splash->display, splash->win, splash->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( splash->barcolor, splash->barcol );
    FILL_COLOR( splash->framecolor, splash->framecol );
#undef FILL_COLOR

    XAllocColor( splash->display, splash->color_map, &(splash->barcolor) );
    XAllocColor( splash->display, splash->color_map, &(splash->framecolor) );

    // not resizable, no decorations, etc.
    splash->gc = XCreateGC( splash->display, splash->win, 0/*value_mask*/, &values );

    size_hints.flags = PPosition | PSize | PMinSize | PMaxSize;
    size_hints.x = splash->display_x_pos;
    size_hints.y = splash->display_y_pos;
    size_hints.width = splash->width;
    size_hints.height = splash->height;
    size_hints.min_width = splash->width;
    size_hints.max_width = splash->width;
    size_hints.min_height = splash->height;
    size_hints.max_height = splash->height;

    XSetStandardProperties( splash->display, splash->win, name, icon, None,
            NULL, 0, &size_hints );

    // the actual work
    suppress_decorations(splash);
    create_pixmap(splash);

    // show it
    XSelectInput( splash->display, splash->win, 0 );
    XMapWindow( splash->display, splash->win );

    return 1;
}

// Re-draw & process the events
// Just throwing them away - we do not need anything more...
static void process_events(struct splash* splash)
{
    XEvent xev;
    int num_events;

    XFlush( splash->display );
    num_events = XPending( splash->display );
    while ( num_events > 0 )
    {
        num_events--;
        XNextEvent( splash->display, &xev );
    }
}


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;
}

static sal_Bool isHiDPI(struct splash* splash)
{
    const char* pValStr;
    double nDPI;

    /*
     * GNOME currently enables HiDPI support when the screen resolution is at least 192 dpi
     * and the screen height (in device pixels) is at least 1200.
     */


    if (splash->display_height < 1200)
        return sal_False;

    pValStr = XGetDefault(splash->display, "Xft""dpi");
    /* if it's too old to have this, assume it's not hidpi */
    if (!pValStr)
        return sal_False;

    nDPI = strtod(pValStr, NULL);
    if (nDPI < 192)
        return sal_False;

    return sal_True;
}

#define IMG_SUFFIX           ".png"

static void splash_load_image( struct splash* splash, rtl_uString* pUAppPath )
{
    /* FIXME-BCP47: if we wanted to support language tags here that would get
     * complicated, this is C-source not C++ so LanguageTag can't be used. For
     * now the splash screen will have to get along with language-territory. */


    char *pBuffer, *pSuffix, *pLocale;
    int nLocSize;
    rtl_Locale *pLoc = NULL;
    rtl_String *pLang, *pCountry, *pAppPath;

    osl_getProcessLocale (&pLoc);
    pLang = ustr_to_str (pLoc->Language);
    pCountry = ustr_to_str (pLoc->Country);

    nLocSize = strlen (pLang->buffer) + strlen (pCountry->buffer) + 3;
    pLocale = malloc (nLocSize);
    pLocale[0] = '-';
    strcpy (pLocale + 1, pLang->buffer);
    strcat (pLocale, "_");
    strcat (pLocale, pCountry->buffer);

    rtl_string_release( pCountry );
    rtl_string_release( pLang );

    pAppPath = ustr_to_str (pUAppPath);
    pBuffer = malloc (pAppPath->length + nLocSize + 256);
    strcpy (pBuffer, pAppPath->buffer);
    pSuffix = pBuffer + pAppPath->length;
    rtl_string_release( pAppPath );

    strcpy (pSuffix, "intro");
    strcat (pSuffix, pLocale);
    strcat (pSuffix, IMG_SUFFIX);
    if ( splash_load_bmp( splash, pBuffer ) )
        goto cleanup; /* success */

    /* load high resolution splash image */
    splash->bHasHiDpiImage = sal_False;
    if (isHiDPI(splash))
    {
        strcpy (pSuffix, "intro-highres" IMG_SUFFIX);
        if ( splash_load_bmp( splash, pBuffer ) )
        {
            splash->bHasHiDpiImage = sal_True;
            goto cleanup; /* success */
        }
    }
    /* load standard resolution splash image */
    strcpy (pSuffix, "intro" IMG_SUFFIX);
    if ( splash_load_bmp( splash, pBuffer ) )
        goto cleanup;   /* success */

    fprintf (stderr, "Failed to find intro image\n");

 cleanup:
    free (pLocale);
    free (pBuffer);
}

/* Load the colors and size of the splash. */
static void splash_load_defaults( struct splash* splash, rtl_uString* pAppPath, sal_Bool* bNoDefaults )
{
    rtl_uString *pSettings = NULL, *pTmp = NULL;
    rtlBootstrapHandle handle;
    int logo[1] =  { -1 },
        bar[3] =   { -1, -1, -1 },
        frame[3] = { -1, -1, -1 },
        pos[2] =   { -1, -1 },
        size[2] =  { -1, -1 };

    /* construct the sofficerc file location */
    rtl_uString_newFromAscii( &pSettings, "file://" );
    rtl_uString_newConcat( &pSettings, pSettings, pAppPath );
    rtl_uString_newConcat( &pSettings, pSettings, pTmp );
    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 );

    /* get the values */
    get_bootstrap_value( logo,  1, handle, "Logo" );
    get_bootstrap_value( bar,   3, handle, "ProgressBarColor" );
    get_bootstrap_value( frame, 3, handle, "ProgressFrameColor" );
    if (isHiDPI(splash) && splash->bHasHiDpiImage)
    {
       get_bootstrap_value( pos,   2, handle, "ProgressPositionHigh" );
       get_bootstrap_value( size,  2, handle, "ProgressSizeHigh" );
    }
    else
    {
       get_bootstrap_value( pos,   2, handle, "ProgressPosition" );
       get_bootstrap_value( size,  2, handle, "ProgressSize" );
    }

    if ( logo[0] == 0 )
    {
        *bNoDefaults = sal_True;
    }

    splash_setup( splash, bar, frame, pos[0], pos[1], size[0], size[1] );

    /* cleanup */
    rtl_bootstrap_args_close( handle );
    rtl_uString_release( pSettings );
    rtl_uString_release( pTmp );
}


// Draw the progress
void splash_draw_progress( struct splash* splash, int progress )
{
    int length = 0;

    if (!splash)
    {
        return;
    }
    // sanity
    if ( progress < 0 )
    {
        progress = 0;
    }
    if ( progress > 100 )
    {
        progress = 100;
    }
    // draw progress...
    length = ( progress * splash->barwidth / 100 ) - ( 2 * splash->barspace );
    if ( length < 0 )
    {
        length = 0;
    }
    // border
    XSetForeground( splash->display, splash->gc, splash->framecolor.pixel );
    XDrawRectangle( splash->display, splash->win, splash->gc, splash->tlx, splash->tly,
            splash->barwidth, splash->barheight );

    // progress bar
    XSetForeground( splash->display, splash->gc, splash->barcolor.pixel );
    XFillRectangle( splash->display, splash->win, splash->gc,
            splash->tlx + splash->barspace, splash->tly + splash->barspace,
            length + 1, splash->barheight - 2 * splash->barspace + 1 );

    // pending events
    process_events(splash);
}

void splash_destroy(struct splash* splash)
{
    if(!splash)
        return;

    if(splash->display)
    {
        if(splash->gc)
        {
            XFreeGC(splash->display, splash->gc);
            splash->gc = NULL;
        }

        XCloseDisplay( splash->display );
        splash->display = NULL;
        png_destroy_read_struct( &(splash->png_ptr), &(splash->info_ptr), NULL );
    }
    free(splash);
}

struct splash* splash_create(rtl_uString* pAppPath, int argc, char** argv)
{
    struct splash* splash;
    sal_Bool bNoDefaults = sal_False;

    splash = calloc(1, sizeof(struct splash));
    if (splash && !splash_init_display(splash, argc, argv))
    {
        splash_destroy(splash);
        splash = NULL;
    }

    if (!splash)
        return NULL;

    splash->width = WINDOW_WIDTH;
    splash->height = WINDOW_HEIGHT;

    splash->tlx = 212;
    splash->tly = 216;
    splash->barwidth = 263;
    splash->barheight = 8;
    splash->barspace = PROGRESS_BARSPACE;
    splash->barcol.b = 18;
    splash->barcol.g = 202;
    splash->barcol.r = 157;
    splash->framecol.b = 0xD3;
    splash->framecol.g = 0xD3;
    splash->framecol.r = 0xD3;

    splash_load_image( splash, pAppPath );
    splash_load_defaults( splash, pAppPath, &bNoDefaults );

    if (!bNoDefaults && splash_create_window(splash))
    {
        splash_draw_progress( splash, 0 );
        return splash;
    }

    splash_destroy(splash);
    return NULL;
}

#else /* not ENABLE_QUICKSTART_LIBPNG */

struct splash
{
};

/* Stubs that will never be called in this case */
void splash_draw_progress( struct splash* splash, int progress )
{
    (void)splash; (void)progress;
}

void splash_destroy(struct splash* splash)
{
    (void)splash;
}

struct splash* splash_create(rtl_uString* pAppPath, int argc, char** argv)
{
    (void)pAppPath; (void)argc; (void)argv;
    return NULL;
}


#endif // defined(ENABLE_QUICKSTART_LIBPNG) && HAVE_FEATURE_UI

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=93 H=93 G=92

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.