/*
 * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "splashscreen_impl.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
#include <X11/Xmd.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <sys/types.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#include <iconv.h>
#include <langinfo.h>
#include <locale.h>
#include <fcntl.h>
#include <poll.h>
#include <sizecalc.h>
#include "jni.h"

static Bool shapeSupported;
static int shapeEventBase, shapeErrorBase;

void SplashRemoveDecoration(Splash * splash);


/* Could use npt but decided to cut down on linked code size */
char* SplashConvertStringAlloc(const char* in, int* size) {
    const char     *codeset;
    const char     *codeset_out;
    iconv_t         cd;
    size_t          rc;
    char           *buf = NULL, *out;
    size_t          bufSize, inSize, outSize;
    const char* old_locale;

    if (!in) {
        return NULL;
    }
    old_locale = setlocale(LC_ALL, "");

    codeset = nl_langinfo(CODESET);
    if ( codeset == NULL || codeset[0] == 0 ) {
        goto done;
    }
    /* we don't need BOM in output so we choose native BE or LE encoding here */
    codeset_out = (platformByteOrder()==BYTE_ORDER_MSBFIRST) ?
        "UCS-2BE" : "UCS-2LE";

    cd = iconv_open(codeset_out, codeset);
    if (cd == (iconv_t)-1 ) {
        goto done;
    }
    inSize = strlen(in);
    buf = SAFE_SIZE_ARRAY_ALLOC(malloc, inSize, 2);
    if (!buf) {
        return NULL;
    }
    bufSize = inSize*2; // need 2 bytes per char for UCS-2, this is
                        // 2 bytes per source byte max
    out = buf; outSize = bufSize;
    /* linux iconv wants char** source and solaris wants const char**...
       cast to void* */
    rc = iconv(cd, (void*)&in, &inSize, &out, &outSize);
    iconv_close(cd);

    if (rc == (size_t)-1) {
        free(buf);
        buf = NULL;
    } else {
        if (size) {
            *size = (bufSize-outSize)/2; /* bytes to wchars */
        }
    }
done:
    setlocale(LC_ALL, old_locale);
    return buf;
}

void
SplashInitFrameShape(Splash * splash, int imageIndex) {
    ImageRect maskRect;
    XRectangle *rects;
    SplashImage *frame = splash->frames + imageIndex;

    frame->rects = NULL;
    frame->numRects = 0;

    if (!splash->maskRequired)
        return;
    if (!shapeSupported)
        return;
    initRect(&maskRect, 0, 0, splash->width, splash->height, 1,
            splash->width * splash->imageFormat.depthBytes,
            splash->frames[imageIndex].bitmapBits, &splash->imageFormat);
    if (!IS_SAFE_SIZE_MUL(splash->width / 2 + 1, splash->height)) {
        return;
    }
    rects = SAFE_SIZE_ARRAY_ALLOC(malloc,
            sizeof(XRectangle), (splash->width / 2 + 1) * splash->height);
    if (!rects) {
        return;
    }

    frame->numRects = BitmapToYXBandedRectangles(&maskRect, rects);
    frame->rects = SAFE_SIZE_ARRAY_ALLOC(malloc, frame->numRects, sizeof(XRectangle));
    if (frame->rects) { // handle the error after the if(){}
        memcpy(frame->rects, rects, frame->numRects * sizeof(XRectangle));
    }
    free(rects);
}

unsigned
SplashTime(void) {
    struct timeval tv;
    struct timezone tz;
    unsigned long long msec;

    gettimeofday(&tv, &tz);
    msec = (unsigned long long) tv.tv_sec * 1000 +
        (unsigned long long) tv.tv_usec / 1000;

    return (unsigned) msec;
}

void
msec2timeval(unsigned time, struct timeval *tv) {
    tv->tv_sec = time / 1000;
    tv->tv_usec = (time % 1000) * 1000;
}

int
GetNumAvailableColors(Display * display, Screen * screen, unsigned map_entries) {
    unsigned long pmr[1];
    unsigned long pr[SPLASH_COLOR_MAP_SIZE];
    unsigned nFailed, nAllocated, done = 0, nPlanes = 0;
    Colormap cmap;
    unsigned numColors = SPLASH_COLOR_MAP_SIZE; // never try allocating more than that

    if (numColors > map_entries) {
        numColors = map_entries;
    }
    cmap = XDefaultColormapOfScreen(screen);
    nAllocated = 0;             /* lower bound */
    nFailed = numColors + 1;    /* upper bound */

    /* Binary search to determine the number of available cells */
    for (done = 0; !done;) {
        if (XAllocColorCells(display, cmap, 0, pmr, nPlanes, pr, numColors)) {
            nAllocated = numColors;
            XFreeColors(display, cmap, pr, numColors, 0);
            if (nAllocated < (nFailed - 1)) {
                numColors = (nAllocated + nFailed) / 2;
            } else
                done = 1;
        } else {
            nFailed = numColors;
            if (nFailed > (nAllocated + 1))
                numColors = (nAllocated + nFailed) / 2;
            else
                done = 1;
        }
    }
    return nAllocated;
}

Colormap
AllocColors(Display * display, Screen * screen, int numColors,
        unsigned long *pr) {
    unsigned long pmr[1];
    Colormap cmap = XDefaultColormapOfScreen(screen);

    XAllocColorCells(display, cmap, 0, pmr, 0, pr, numColors);
    return cmap;
}

void
FreeColors(Display * display, Screen * screen, int numColors,
        unsigned long *pr) {
    Colormap cmap = XDefaultColormapOfScreen(screen);

    XFreeColors(display, cmap, pr, numColors, 0);
}

static void SplashCenter(Splash * splash) {
    Atom atom, actual_type;
    int status, actual_format;
    unsigned long nitems, bytes_after;
    CARD16 *prop = NULL;

    /*  try centering using Xinerama hint
        if there's no hint, use the center of the screen */
    atom = XInternAtom(splash->display, "XINERAMA_CENTER_HINT", True);
    if (atom != None) {
        status = XGetWindowProperty(splash->display,
            XRootWindowOfScreen(splash->screen), atom, 0, 1, False, XA_INTEGER,
            &actual_type, &actual_format, &nitems,
            &bytes_after, (unsigned char**)(&prop));
        if (status == Success && actual_type != None && prop != NULL) {
            splash->x = prop[0] - splash->width/2;
            splash->y = prop[1] - splash->height/2;
            XFree(prop);
            return;
        }
        if (prop != NULL) {
            XFree(prop);
        }
    }
    splash->x = (XWidthOfScreen(splash->screen) - splash->width) / 2;
    splash->y = (XHeightOfScreen(splash->screen) - splash->height) / 2;
}

static void SplashUpdateSizeHints(Splash * splash) {
    if (splash->window) {
        XSizeHints sizeHints;

        sizeHints.flags = USPosition | PPosition | USSize | PSize | PMinSize | PMaxSize | PWinGravity;
        sizeHints.width = sizeHints.base_width = sizeHints.min_width = sizeHints.max_width = splash->width;
        sizeHints.height = sizeHints.base_height = sizeHints.min_height = sizeHints.max_height = splash->height;
        sizeHints.win_gravity = NorthWestGravity;

        XSetWMNormalHints(splash->display, splash->window, &sizeHints);
    }
}

void
SplashCreateWindow(Splash * splash) {
    XSetWindowAttributes attr;

    attr.backing_store = NotUseful;
    attr.colormap = XDefaultColormapOfScreen(splash->screen);
    attr.save_under = True;
    attr.cursor = splash->cursor = XCreateFontCursor(splash->display, XC_watch);
    attr.event_mask = ExposureMask;

    SplashCenter(splash);

    splash->window = XCreateWindow(splash->display, XRootWindowOfScreen(splash->screen),
        splash->x, splash->y, splash->width, splash->height, 0, CopyFromParent,
        InputOutput, CopyFromParent, CWColormap | CWBackingStore | CWSaveUnder | CWCursor | CWEventMask,
        &attr);
    SplashUpdateSizeHints(splash);


    splash->wmHints = XAllocWMHints();
    if (splash->wmHints) {
        splash->wmHints->flags = InputHint | StateHint;
        splash->wmHints->input = False;
        splash->wmHints->initial_state = NormalState;
        XSetWMHints(splash->display, splash->window, splash->wmHints);
    }
}

/* for changing the visible shape of a window to an nonrectangular form */
void
SplashUpdateShape(Splash * splash) {
    if (splash->currentFrame < 0 || !shapeSupported || !splash->maskRequired) {
        return;
    }
    XShapeCombineRectangles(splash->display, splash->window, ShapeClip, 0, 0,
            splash->frames[splash->currentFrame].rects,
            splash->frames[splash->currentFrame].numRects, ShapeSet, YXBanded);
    XShapeCombineRectangles(splash->display, splash->window, ShapeBounding,
            0, 0, splash->frames[splash->currentFrame].rects,
            splash->frames[splash->currentFrame].numRects, ShapeSet, YXBanded);
}

/* for reverting the visible shape of a window to an rectangular form */
void
SplashRevertShape(Splash * splash) {
    if (!shapeSupported)
        return;
    if (splash->maskRequired)
        return;

    XShapeCombineMask (splash->display, splash->window, ShapeClip,
                       0, 0, None, ShapeSet);
    XShapeCombineMask (splash->display, splash->window , ShapeBounding,
                       0, 0, None, ShapeSet);
}

int
ByteOrderToX(int byteOrder) {
    if (byteOrder == BYTE_ORDER_NATIVE)
        byteOrder = platformByteOrder();
    switch (byteOrder) {
    case BYTE_ORDER_LSBFIRST:
        return LSBFirst;
    case BYTE_ORDER_MSBFIRST:
        return MSBFirst;
    default:
        return -1;
    }
}

void
SplashRedrawWindow(Splash * splash) {
    if (splash->currentFrame < 0) {
        return;
    }

    XImage *ximage;

    // making this method redraw a part of the image does not make
    // much sense as SplashUpdateScreenData always re-generates
    // the image completely, so whole window is always redrawn

    SplashUpdateScreenData(splash);
    ximage = XCreateImage(splash->display, splash->visual,
            splash->screenFormat.depthBytes * 8, ZPixmap, 0, (char *) NULL,
            splash->width, splash->height, 8, 0);
    ximage->data = (char *) splash->screenData;
    ximage->bits_per_pixel = ximage->depth;
    ximage->bytes_per_line = ximage->depth * ximage->width / 8;
    ximage->byte_order = ByteOrderToX(splash->screenFormat.byteOrder);
    ximage->bitmap_unit = 8;
    XPutImage(splash->display, splash->window,
            XDefaultGCOfScreen(splash->screen), ximage, 0, 0, 0, 0,
            splash->width, splash->height);
    ximage->data = NULL;
    XDestroyImage(ximage);
    SplashRemoveDecoration(splash);
    XMapWindow(splash->display, splash->window);
    XFlush(splash->display);
}

void SplashReconfigureNow(Splash * splash) {
    SplashCenter(splash);
    if (splash->window) {
        XUnmapWindow(splash->display, splash->window);
        XMoveResizeWindow(splash->display, splash->window,
            splash->x, splash->y,
            splash->width, splash->height);
        SplashUpdateSizeHints(splash);
    }
    if (splash->maskRequired) {
        SplashUpdateShape(splash);
    } else {
        SplashRevertShape(splash);
    }
    SplashRedrawWindow(splash);
}


void
sendctl(Splash * splash, char code) {
//    if (splash->isVisible>0) {
    if (splash && splash->controlpipe[1]) {
        write(splash->controlpipe[1], &code, 1);
    }
}

int
SplashInitPlatform(Splash * splash) {
    int shapeVersionMajor, shapeVersionMinor;

    // This setting enables the synchronous Xlib mode!
    // Don't use it == 1 in production builds!
#if (defined DEBUG)
    _Xdebug = 1;
#endif

    pthread_mutex_init(&splash->lock, NULL);

    splash->display = XOpenDisplay(NULL);
    if (!splash->display) {
        splash->isVisible = -1;
        return 0;
    }

    shapeSupported = XShapeQueryExtension(splash->display, &shapeEventBase,
            &shapeErrorBase);
    if (shapeSupported) {
        XShapeQueryVersion(splash->display, &shapeVersionMajor,
                &shapeVersionMinor);
    }

    splash->screen = XDefaultScreenOfDisplay(splash->display);
    splash->visual = XDefaultVisualOfScreen(splash->screen);
    switch (splash->visual->class) {
    case TrueColor: {
            int depth = XDefaultDepthOfScreen(splash->screen);

            splash->byteAlignment = 1;
            splash->maskRequired = shapeSupported;
            initFormat(&splash->screenFormat, splash->visual->red_mask,
                    splash->visual->green_mask, splash->visual->blue_mask, 0);
            splash->screenFormat.byteOrder =
                (XImageByteOrder(splash->display) == LSBFirst ?
                 BYTE_ORDER_LSBFIRST : BYTE_ORDER_MSBFIRST);
            splash->screenFormat.depthBytes = (depth + 7) / 8;
            // TrueColor depth probably can't be less
            // than 8 bits, and it's always byte padded
            break;
        }
    case PseudoColor: {
            int availableColors;
            int numColors;
            int numComponents[3];
            unsigned long colorIndex[SPLASH_COLOR_MAP_SIZE];
            XColor xColors[SPLASH_COLOR_MAP_SIZE];
            int i;
            int depth = XDefaultDepthOfScreen(splash->screen);
            int scale = 65535 / MAX_COLOR_VALUE;

            availableColors = GetNumAvailableColors(splash->display, splash->screen,
                    splash->visual->map_entries);
            numColors = quantizeColors(availableColors, numComponents);
            if (numColors > availableColors) {
                // Could not allocate the color cells. Most probably
                // the pool got exhausted. Disable the splash screen.
                XCloseDisplay(splash->display);
                splash->isVisible = -1;
                splash->display = NULL;
                splash->screen = NULL;
                splash->visual = NULL;
                fprintf(stderr, "Warning: unable to initialize the splashscreen. Not enough available color cells.\n");
                return 0;
            }
            splash->cmap = AllocColors(splash->display, splash->screen,
                    numColors, colorIndex);
            for (i = 0; i < numColors; i++) {
                splash->colorIndex[i] = colorIndex[i];
            }
            initColorCube(numComponents, splash->colorMap, splash->dithers,
                    splash->colorIndex);
            for (i = 0; i < numColors; i++) {
                xColors[i].pixel = colorIndex[i];
                xColors[i].red = (unsigned short)
                    QUAD_RED(splash->colorMap[colorIndex[i]]) * scale;
                xColors[i].green = (unsigned short)
                    QUAD_GREEN(splash->colorMap[colorIndex[i]]) * scale;
                xColors[i].blue = (unsigned short)
                    QUAD_BLUE(splash->colorMap[colorIndex[i]]) * scale;
                xColors[i].flags = DoRed | DoGreen | DoBlue;
            }
            XStoreColors(splash->display, splash->cmap, xColors, numColors);
            initFormat(&splash->screenFormat, 0, 0, 0, 0);
            splash->screenFormat.colorIndex = splash->colorIndex;
            splash->screenFormat.depthBytes = (depth + 7) / 8;  // or always 8?
            splash->screenFormat.colorMap = splash->colorMap;
            splash->screenFormat.dithers = splash->dithers;
            splash->screenFormat.numColors = numColors;
            splash->screenFormat.byteOrder = BYTE_ORDER_NATIVE;
            break;
        }
    default:
        ; /* FIXME: should probably be fixed, but javaws splash screen doesn't support other visuals either */
    }
    return 1;
}


void
SplashCleanupPlatform(Splash * splash) {
    int i;

    if (splash->frames) {
        for (i = 0; i < splash->frameCount; i++) {
            if (splash->frames[i].rects) {
                free(splash->frames[i].rects);
                splash->frames[i].rects = NULL;
            }
        }
    }
    splash->maskRequired = shapeSupported;
}

void
SplashDonePlatform(Splash * splash) {
    pthread_mutex_destroy(&splash->lock);
    if (splash->cmap) {
        unsigned long colorIndex[SPLASH_COLOR_MAP_SIZE];
        int i;

        for (i = 0; i < splash->screenFormat.numColors; i++) {
            colorIndex[i] = splash->colorIndex[i];
        }
        FreeColors(splash->display, splash->screen,
                splash->screenFormat.numColors, colorIndex);
    }
    if (splash->window)
        XDestroyWindow(splash->display, splash->window);
    if (splash->wmHints)
        XFree(splash->wmHints);
    if (splash->cursor)
        XFreeCursor(splash->display, splash->cursor);
    if (splash->display)
        XCloseDisplay(splash->display);
}

void
SplashEventLoop(Splash * splash) {

    /*      Different from win32 implementation - this loop
       uses poll timeouts instead of a timer */
    /* we should have splash _locked_ on entry!!! */

    int xconn = XConnectionNumber(splash->display);

    while (1) {
        struct pollfd pfd[2];
        int timeout = -1;
        int ctl = splash->controlpipe[0];
        int rc;
        int pipes_empty;

        pfd[0].fd = xconn;
        pfd[0].events = POLLIN | POLLPRI;

        pfd[1].fd = ctl;
        pfd[1].events = POLLIN | POLLPRI;

        errno = 0;
        if (splash->isVisible>0 && SplashIsStillLooping(splash)) {
            timeout = splash->time + splash->frames[splash->currentFrame].delay
                - SplashTime();
            if (timeout < 0) {
                timeout = 0;
            }
        }
        SplashUnlock(splash);
        rc = poll(pfd, 2, timeout);
        SplashLock(splash);
        if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
                SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
            SplashNextFrame(splash);
            SplashUpdateShape(splash);
            SplashRedrawWindow(splash);
        }
        if (rc <= 0) {
            errno = 0;
            continue;
        }
        pipes_empty = 0;
        while(!pipes_empty) {
            char buf;

            pipes_empty = 1;
            if (read(ctl, &buf, sizeof(buf)) > 0) {
                pipes_empty = 0;
                switch (buf) {
                case SPLASHCTL_UPDATE:
                    if (splash->isVisible>0) {
                        SplashRedrawWindow(splash);
                    }
                    break;
                case SPLASHCTL_RECONFIGURE:
                    if (splash->isVisible>0) {
                        SplashReconfigureNow(splash);
                    }
                    break;
                case SPLASHCTL_QUIT:
                    return;
                }
            }
            // we're not using "while(XPending)", processing one event
            // at a time to avoid control pipe starvation
            if (XPending(splash->display)) {
                XEvent evt;

                pipes_empty = 0;
                XNextEvent(splash->display, &evt);
                switch (evt.type) {
                    case Expose:
                        if (splash->isVisible>0) {
                            // we're doing full redraw so we just
                            // skip the remaining painting events in the queue
                            while(XCheckTypedEvent(splash->display, Expose,
                                &evt));
                            SplashRedrawWindow(splash);
                        }
                        break;
                    /* ... */
                }
            }
        }
    }
}

/*  we can't use OverrideRedirect for the window as the window should not be
    always-on-top, so we must set appropriate wm hints

    this functions sets olwm, mwm and EWMH hints for undecorated window at once

    It works for: mwm, openbox, wmaker, metacity, KWin (FIXME: test more wm's)
    Should work for: fvwm2.5.x, blackbox, olwm
    Maybe works for: enlightenment, icewm
    Does not work for: twm, fvwm2.4.7

*/

void
SplashRemoveDecoration(Splash * splash) {
    Atom atom_set;
    Atom atom_list[4];

    /* the struct below was copied from MwmUtil.h */

    struct PROPMOTIFWMHINTS {
    /* 32-bit property items are stored as long on the client (whether
     * that means 32 bits or 64).  XChangeProperty handles the conversion
     * to the actual 32-bit quantities sent to the server.
     */
        unsigned long   flags;
        unsigned long   functions;
        unsigned long   decorations;
        long            inputMode;
        unsigned long   status;
    }
    mwm_hints;

    /* WM_TAKE_FOCUS hint to avoid wm's transfer of focus to this window */
    /* WM_DELETE_WINDOW hint to avoid closing this window with Alt-F4. See bug 6474035 */
    atom_set = XInternAtom(splash->display, "WM_PROTOCOLS", True);
    if (atom_set != None) {
        atom_list[0] = XInternAtom(splash->display, "WM_TAKE_FOCUS", True);
        atom_list[1] = XInternAtom(splash->display, "WM_DELETE_WINDOW", True);

        XChangeProperty(splash->display, splash->window, atom_set, XA_ATOM, 32,
                PropModeReplace, (unsigned char *) atom_list, 2);
    }

    /* mwm hints */
    atom_set = XInternAtom(splash->display, "_MOTIF_WM_HINTS", True);
    if (atom_set != None) {
        /* flags for decoration and functions */
        mwm_hints.flags = (1L << 1) | (1L << 0);
        mwm_hints.decorations = 0;
        mwm_hints.functions = 0;
        XChangeProperty(splash->display, splash->window, atom_set, atom_set,
                32, PropModeReplace, (unsigned char *) &mwm_hints, 5);
    }

    /* olwm hints */
    atom_set = XInternAtom(splash->display, "_OL_DECOR_DEL", True);
    if (atom_set != None) {
        atom_list[0] = XInternAtom(splash->display, "_OL_DECOR_RESIZE", True);
        atom_list[1] = XInternAtom(splash->display, "_OL_DECOR_HEADER", True);
        atom_list[2] = XInternAtom(splash->display, "_OL_DECOR_PIN", True);
        atom_list[3] = XInternAtom(splash->display, "_OL_DECOR_CLOSE", True);
        XChangeProperty(splash->display, splash->window, atom_set, XA_ATOM, 32,
                PropModeReplace, (unsigned char *) atom_list, 4);
    }

    /* generic EMWH hints
       we do not set _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_SPLASH
       hint support due to gnome making this window always-on-top
       so we have to set _NET_WM_STATE and _NET_WM_ALLOWED_ACTIONS correctly
       _NET_WM_STATE: SKIP_TASKBAR and SKIP_PAGER
       _NET_WM_ALLOWED_ACTIONS: disable all actions */
    atom_set = XInternAtom(splash->display, "_NET_WM_STATE", True);
    if (atom_set != None) {
        atom_list[0] = XInternAtom(splash->display,
                "_NET_WM_STATE_SKIP_TASKBAR", True);
        atom_list[1] = XInternAtom(splash->display,
                "_NET_WM_STATE_SKIP_PAGER", True);
        XChangeProperty(splash->display, splash->window, atom_set, XA_ATOM, 32,
                PropModeReplace, (unsigned char *) atom_list, 2);
    }
    atom_set = XInternAtom(splash->display, "_NET_WM_ALLOWED_ACTIONS", True);
    if (atom_set != None) {
        XChangeProperty(splash->display, splash->window, atom_set, XA_ATOM, 32,
                PropModeReplace, (unsigned char *) atom_list, 0);
    }
}

void
SplashPThreadDestructor(void *arg) {
    /* this will be used in case of emergency thread exit on xlib error */
    Splash *splash = (Splash *) arg;

    if (splash) {
        SplashCleanup(splash);
    }
}

void *
SplashScreenThread(void *param) {
    Splash *splash = (Splash *) param;
//    pthread_key_t key;

//    pthread_key_create(&key, SplashPThreadDestructor);
//    pthread_setspecific(key, splash);

    SplashLock(splash);
    pipe(splash->controlpipe);
    fcntl(splash->controlpipe[0], F_SETFL,
        fcntl(splash->controlpipe[0], F_GETFL, 0) | O_NONBLOCK);
    splash->time = SplashTime();
    SplashCreateWindow(splash);
    fflush(stdout);
    if (splash->window) {
        SplashRemoveDecoration(splash);
        XStoreName(splash->display, splash->window, "Java");
        XMapRaised(splash->display, splash->window);
        SplashUpdateShape(splash);
        SplashRedrawWindow(splash);
        //map the splash coordinates as per system scale
        splash->x /= splash->scaleFactor;
        splash->y /= splash->scaleFactor;
        SplashEventLoop(splash);
    }
    SplashUnlock(splash);
    SplashDone(splash);

    splash->isVisible=-1;
    return 0;
}

void
SplashCreateThread(Splash * splash) {
    pthread_t thr;
    pthread_attr_t attr;

    int rslt = pthread_attr_init(&attr);
    if (rslt != 0) return;
    rslt = pthread_create(&thr, &attr, SplashScreenThread, (void *) splash);
    if (rslt != 0) {
        fprintf(stderr, "Could not create SplashScreen thread, error number:%d\n", rslt);
    }
    pthread_attr_destroy(&attr);
}

void
SplashLock(Splash * splash) {
    pthread_mutex_lock(&splash->lock);
}

void
SplashUnlock(Splash * splash) {
    pthread_mutex_unlock(&splash->lock);
}

void
SplashClosePlatform(Splash * splash) {
    sendctl(splash, SPLASHCTL_QUIT);
}

void
SplashUpdate(Splash * splash) {
    sendctl(splash, SPLASHCTL_UPDATE);
}

void
SplashReconfigure(Splash * splash) {
    sendctl(splash, SPLASHCTL_RECONFIGURE);
}

JNIEXPORT jboolean
SplashGetScaledImageName(const char* jarName, const char* fileName,
                           float *scaleFactor, char *scaledImgName,
                           const size_t scaledImageNameLength)
{
    *scaleFactor = 1;
#ifndef __linux__
    return JNI_FALSE;
#endif
    *scaleFactor = (float)getNativeScaleFactor();
    return GetScaledImageName(fileName, scaledImgName, scaleFactor, scaledImageNameLength);
}

