Compare commits

...

1 Commits

Author SHA1 Message Date
Dmitrii Morskii
1780f1bffb attempt 2023-08-24 13:54:42 +02:00
16 changed files with 3150 additions and 306 deletions

View File

@@ -934,11 +934,9 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
else ifeq ($(call isTargetOs, windows), true)
LIBSPLASHSCREEN_CFLAGS += -DWITH_WIN32
else
LIBSPLASHSCREEN_CFLAGS += -DWITH_X11 $(X_CFLAGS)
LIBSPLASHSCREEN_CFLAGS += $(X_CFLAGS)
endif
LIBSPLASHSCREEN_LIBS :=
ifeq ($(call isTargetOs, macosx), true)
LIBSPLASHSCREEN_LIBS += \
$(LIBM) -lpthread -liconv -losxapp \
@@ -954,51 +952,62 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
endif
LIBSPLASHSCREEN_HEADER_DIRS += \
libsplashscreen \
libosxapp \
java.base:libjava \
#
$(eval $(call SetupJdkLibrary, BUILD_LIBSPLASHSCREEN, \
NAME := splashscreen, \
EXTRA_SRC := $(LIBSPLASHSCREEN_EXTRA_SRC), \
LIBSPLASHSCREEN_CFLAGS := $(CFLAGS_JDKLIB) $(LIBSPLASHSCREEN_CFLAGS) $(GIFLIB_CFLAGS) $(LIBJPEG_CFLAGS) $(PNG_CFLAGS) $(LIBZ_CFLAGS)
LIBSPLASHSCREEN_EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c
LIBSPLASHSCREEN_LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN)
LIBSPLASHSCREEN_LIBS := $(JDKLIB_LIBS) $(LIBSPLASHSCREEN_LIBS) $(LIBZ_LIBS) $(GIFLIB_LIBS) $(LIBJPEG_LIBS) $(PNG_LIBS)
LIBSPLASHSCREEN_DISABLED_WARNINGS_gcc := sign-compare implicit-fallthrough shift-negative-value maybe-uninitialized unused-function type-limits unused-result
LIBSPLASHSCREEN_DISABLED_WARNINGS_clang := deprecated-non-prototype format-nonliteral sign-compare incompatible-pointer-types deprecated-declarations
LIBSPLASHSCREEN_DISABLED_WARNINGS_microsoft := 4018 4267 4244
$(eval $(call SetupJdkLibrary, BUILD_LIBXSPLASHSCREEN, \
NAME := xsplashscreen, \
EXTRA_SRC := $(LIBSPLASHSCREEN_EXTRA_SRC) libxsplashscreen libsplashscreen, \
EXCLUDE_SRC_PATTERNS := $(LIBSPLASHSCREEN_EXCLUDE_SRC_PATTERNS), \
EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c, \
DISABLED_WARNINGS_gcc := $(LIBSPLASHSCREEN_DISABLED_WARNINGS_gcc), \
DISABLED_WARNINGS_clang := $(LIBSPLASHSCREEN_DISABLED_WARNINGS_clang), \
DISABLED_WARNINGS_microsoft := $(LIBSPLASHSCREEN_DISABLED_WARNINGS_microsoft), \
EXCLUDE_FILES := $(LIBSPLASHSCREEN_EXCLUDE_FILES), \
EXCLUDES := $(LIBSPLASHSCREEN_EXCLUDES), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBSPLASHSCREEN_CFLAGS) \
$(GIFLIB_CFLAGS) $(LIBJPEG_CFLAGS) $(PNG_CFLAGS) $(LIBZ_CFLAGS), \
EXTRA_HEADER_DIRS := $(LIBSPLASHSCREEN_HEADER_DIRS), \
DISABLED_WARNINGS_gcc_dgif_lib.c := sign-compare, \
DISABLED_WARNINGS_gcc_jcmaster.c := implicit-fallthrough, \
DISABLED_WARNINGS_gcc_jdphuff.c := shift-negative-value, \
DISABLED_WARNINGS_gcc_png.c := maybe-uninitialized, \
DISABLED_WARNINGS_gcc_pngerror.c := maybe-uninitialized, \
DISABLED_WARNINGS_gcc_splashscreen_gfx_impl.c := implicit-fallthrough maybe-uninitialized, \
DISABLED_WARNINGS_gcc_splashscreen_impl.c := implicit-fallthrough sign-compare unused-function, \
DISABLED_WARNINGS_gcc_splashscreen_sys.c := type-limits unused-result, \
DISABLED_WARNINGS_clang := deprecated-non-prototype, \
DISABLED_WARNINGS_clang_dgif_lib.c := sign-compare, \
DISABLED_WARNINGS_clang_gzwrite.c := format-nonliteral, \
DISABLED_WARNINGS_clang_splashscreen_impl.c := sign-compare, \
DISABLED_WARNINGS_clang_splashscreen_png.c := incompatible-pointer-types, \
DISABLED_WARNINGS_clang_splashscreen_sys.m := deprecated-declarations, \
DISABLED_WARNINGS_microsoft_dgif_lib.c := 4018 4267, \
DISABLED_WARNINGS_microsoft_splashscreen_impl.c := 4018 4267 4244, \
DISABLED_WARNINGS_microsoft_splashscreen_png.c := 4267, \
DISABLED_WARNINGS_microsoft_splashscreen_sys.c := 4267 4244, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
CFLAGS := -DWITH_X11 $(LIBSPLASHSCREEN_CFLAGS), \
EXTRA_HEADER_DIRS := libxsplashscreen $(LIBSPLASHSCREEN_HEADER_DIRS), \
LDFLAGS := $(LIBSPLASHSCREEN_LDFLAGS), \
LDFLAGS_macosx := -L$(INSTALL_LIBRARIES_HERE), \
LDFLAGS_windows := -delayload:user32.dll, \
LIBS := $(JDKLIB_LIBS) $(LIBSPLASHSCREEN_LIBS) $(LIBZ_LIBS) \
$(GIFLIB_LIBS) $(LIBJPEG_LIBS) $(PNG_LIBS), \
LIBS := $(LIBSPLASHSCREEN_LIBS), \
LIBS_aix := -liconv, \
))
TARGETS += $(BUILD_LIBSPLASHSCREEN)
$(eval $(call SetupJdkLibrary, BUILD_LIBWLSPLASHSCREEN, \
NAME := wlsplashscreen, \
EXTRA_SRC := $(LIBSPLASHSCREEN_EXTRA_SRC) libwlsplashscreen libsplashscreen, \
EXCLUDE_SRC_PATTERNS := $(LIBSPLASHSCREEN_EXCLUDE_SRC_PATTERNS), \
DISABLED_WARNINGS_gcc := $(LIBSPLASHSCREEN_DISABLED_WARNINGS_gcc), \
DISABLED_WARNINGS_clang := $(LIBSPLASHSCREEN_DISABLED_WARNINGS_clang), \
DISABLED_WARNINGS_microsoft := $(LIBSPLASHSCREEN_DISABLED_WARNINGS_microsoft), \
EXCLUDE_FILES := $(LIBSPLASHSCREEN_EXCLUDE_FILES), \
EXCLUDES := $(LIBSPLASHSCREEN_EXCLUDES), \
OPTIMIZATION := LOW, \
CFLAGS := -DWITH_WL $(LIBSPLASHSCREEN_CFLAGS), \
EXTRA_HEADER_DIRS := libwlsplashscreen $(LIBSPLASHSCREEN_HEADER_DIRS), \
LDFLAGS := $(LIBSPLASHSCREEN_LDFLAGS), \
LDFLAGS_macosx := -L$(INSTALL_LIBRARIES_HERE), \
LDFLAGS_windows := -delayload:user32.dll, \
LIBS := -lwayland-client -lwayland-cursor $(LIBSPLASHSCREEN_LIBS), \
LIBS_aix := -liconv, \
))
TARGETS += $(BUILD_LIBXSPLASHSCREEN) $(BUILD_LIBWLSPLASHSCREEN)
ifeq ($(call isTargetOs, macosx), true)
$(BUILD_LIBSPLASHSCREEN): $(call FindLib, $(MODULE), osxapp)
$(BUILD_LIBXSPLASHSCREEN): $(call FindLib, $(MODULE), osxapp)
$(BUILD_LIBWLSPLASHSCREEN): $(call FindLib, $(MODULE), osxapp)
endif
endif

View File

@@ -176,6 +176,7 @@ static int KnownVMIndex(const char* name);
static void FreeKnownVMs();
static jboolean IsWildCardEnabled();
const char* SPLASHSCREEN_SO = JNI_LIB_NAME("xsplashscreen");
#define SOURCE_LAUNCHER_MAIN_ENTRY "jdk.compiler/com.sun.tools.javac.launcher.Main"
@@ -1080,6 +1081,8 @@ SelectVersion(int argc, char **argv, char **main_class)
headlessflag = 1;
} else if (JLI_StrCCmp(arg, "-Djava.awt.headless=") == 0) {
headlessflag = 0;
} else if (JLI_StrCCmp(arg, "-Dawt.toolkit.name=WLToolkit") == 0) {
SPLASHSCREEN_SO = JNI_LIB_NAME("wlsplashscreen");
} else if (JLI_StrCCmp(arg, "-splash:") == 0) {
splash_file_name = arg+8;
}

View File

@@ -646,7 +646,7 @@ SetExecname(char **argv)
}
/* --- Splash Screen shared library support --- */
static const char* SPLASHSCREEN_SO = JNI_LIB_NAME("splashscreen");
extern const char* SPLASHSCREEN_SO;
static void* hSplashLib = NULL;
void* SplashProcAddress(const char* name) {

View File

@@ -29,6 +29,8 @@ import java.awt.image.*;
import java.net.URL;
import java.net.URLConnection;
import java.io.File;
import sun.awt.PlatformGraphicsInfo;
import sun.util.logging.PlatformLogger;
import sun.awt.image.SunWritableRaster;
@@ -132,7 +134,11 @@ public final class SplashScreen {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("splashscreen");
if (PlatformGraphicsInfo.getToolkitID() == PlatformGraphicsInfo.TK_WAYLAND) {
System.loadLibrary("wlsplashscreen");
} else {
System.loadLibrary("xsplashscreen");
}
return null;
}
});

View File

@@ -29,6 +29,7 @@
/* splashscreen_gfx is a general purpose code for converting pixmaps between various visuals
it is not very effective, but is universal and concise */
#include "splashscreen_config_common.h"
#include "splashscreen_config.h"
enum

View File

@@ -132,7 +132,7 @@ SplashIsStillLooping(Splash * splash)
}
void
SplashUpdateScreenData(Splash * splash)
SplashUpdateScreenData(Splash * splash, void *data)
{
ImageRect srcRect, dstRect;
if (splash->currentFrame < 0) {
@@ -151,9 +151,11 @@ SplashUpdateScreenData(Splash * splash)
(splash->screenStride + splash->byteAlignment - 1) &
~(splash->byteAlignment - 1);
}
splash->screenData = malloc(splash->height * splash->screenStride);
if (data == NULL) {
splash->screenData = malloc(splash->height * splash->screenStride);
}
initRect(&dstRect, 0, 0, splash->width, splash->height, 1,
splash->screenStride, splash->screenData, &splash->screenFormat);
splash->screenStride, data != NULL ? data : splash->screenData, &splash->screenFormat);
if (splash->overlayData) {
convertRect2(&srcRect, &dstRect, CVT_BLEND, &splash->overlayRect);
}

View File

@@ -26,10 +26,13 @@
#ifndef SPLASHSCREEN_IMPL_H
#define SPLASHSCREEN_IMPL_H
#include "splashscreen_config_common.h"
#include "splashscreen_config.h"
#include "splashscreen_gfx.h"
#include "jni.h"
#include <stdbool.h>
JNIEXPORT int
SplashLoadMemory(void *pdata, int size); /* requires preloading the file */
@@ -68,6 +71,13 @@ typedef struct SplashImage
#define SPLASH_COLOR_MAP_SIZE 0x100
typedef struct Buffer {
void *data;
int size;
struct wl_buffer *wl_buffer;
bool available;
} Buffer;
typedef struct Splash
{
ImageFormat screenFormat; /* must be preset before image decoding */
@@ -111,6 +121,15 @@ typedef struct Splash
pthread_mutex_t lock;
Cursor cursor;
XWMHints* wmHints;
#elif defined(WITH_WL)
int controlpipe[2];
Buffer main_buffer;
Buffer buffers[3];
wayland_state* state;
int window_width;
int window_height;
int native_scale;
pthread_mutex_t lock;
#elif defined(WITH_MACOSX)
pthread_mutex_t lock;
int controlpipe[2];
@@ -151,7 +170,7 @@ void SplashNextFrame(Splash * splash);
void SplashStart(Splash * splash);
void SplashDone(Splash * splash);
void SplashUpdateScreenData(Splash * splash);
void SplashUpdateScreenData(Splash * splash, void *data);
void SplashCleanup(Splash * splash);

View File

@@ -47,7 +47,7 @@ public class PlatformGraphicsInfo {
private static int toolkitID = TK_UNDEF;
private static int getToolkitID() {
public static int getToolkitID() {
if (toolkitID == TK_UNDEF) {
@SuppressWarnings("removal")
String name = AccessController.doPrivileged(

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2005, 2018, 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.
*/
/* platform-dependent definitions */
#ifndef SPLASHSCREEN_CONFIG_COMMON_H
#define SPLASHSCREEN_CONFIG_COMMON_H
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "systemScale.h"
typedef uint32_t rgbquad_t;
typedef uint16_t word_t;
typedef uint8_t byte_t;
#define SPLASHCTL_QUIT 'Q'
#define SPLASHCTL_UPDATE 'U'
#define SPLASHCTL_RECONFIGURE 'R'
#define INLINE static
#endif

View File

@@ -0,0 +1,268 @@
/*
* Copyright (c) 2005, 2019, 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 <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 <stdbool.h>
#include "jni.h"
const int POLL_TIMEOUT = 50;
void SplashEventLoop(Splash * splash);
bool SplashCreateWindow(Splash * splash);
void SplashRedrawWindow(Splash * splash);
void SplashUpdateCursor(Splash * splash);
void SplashSetup(Splash * splash);
void SplashUpdateShape(Splash * splash);
void SplashReconfigureNow(Splash * splash);
bool FlushEvents(Splash * splash);
bool DispatchEvents(Splash * splash);
int GetDisplayFD(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
SplashEventLoop(Splash * splash) {
struct pollfd pfd[2];
int rc;
pfd[0].fd = splash->controlpipe[0];
pfd[0].events = POLLIN | POLLPRI;
pfd[0].revents = 0;
pfd[1].fd = GetDisplayFD(splash);
pfd[1].events = POLLIN | POLLPRI;
pfd[1].revents = 0;
while (true) {
if (!FlushEvents(splash)) {
break;
}
if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
SplashNextFrame(splash);
SplashUpdateShape(splash);
SplashRedrawWindow(splash);
}
SplashUnlock(splash);
rc = poll(pfd, 2, POLL_TIMEOUT);
SplashLock(splash);
SplashUpdateCursor(splash);
if (rc <= 0) {
continue;
}
if (pfd[1].revents) {
if (!DispatchEvents(splash)) {
break;
}
}
if (pfd[0].revents) {
char buf;
if (read(splash->controlpipe[0], &buf, sizeof(buf)) > 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;
}
}
}
}
}
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
SplashPThreadDestructor(void *data) {
Splash *splash = data;
if (splash) {
SplashCleanup(splash);
}
}
void *
SplashScreenThread(void *data) {
Splash *splash = data;
SplashLock(splash);
pipe(splash->controlpipe);
fcntl(splash->controlpipe[0], F_SETFL, fcntl(splash->controlpipe[0], F_GETFL, 0) | O_NONBLOCK);
splash->time = SplashTime();
bool init = SplashCreateWindow(splash);
fflush(stdout);
if (init) {
SplashSetup(splash);
SplashRedrawWindow(splash);
SplashEventLoop(splash);
}
SplashUnlock(splash);
SplashDone(splash);
splash->isVisible=-1;
return 0;
}
void
SplashCreateThread(Splash * splash) {
pthread_t thr;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&thr, &attr, SplashScreenThread, (void *) splash);
}
void
sendctl(Splash * splash, char code) {
if (splash && splash->controlpipe[1]) {
write(splash->controlpipe[1], &code, 1);
}
}
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(NULL, 1);
return GetScaledImageName(fileName, scaledImgName, scaleFactor, scaledImageNameLength);
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2005, 2018, 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.
*/
/* platform-dependent definitions */
#ifndef SPLASHSCREEN_CONFIG_H
#define SPLASHSCREEN_CONFIG_H
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "systemScale.h"
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#include <wayland-client.h>
#include <stdio.h>
#include <wayland-cursor.h>
#include "xdg-shell-client-protocol.h"
typedef struct wayland_state {
struct wl_display *wl_display;
struct wl_registry *wl_registry;
struct wl_shm *wl_shm;
struct wl_compositor *wl_compositor;
struct wl_subcompositor *wl_subcompositor;
struct wl_seat *wl_seat;
struct wl_pointer *pointer;
struct xdg_wm_base *xdg_wm_base;
struct wl_surface *wl_surface;
struct wl_surface *wl_subsurfaces_surface;
struct wl_subsurface *wl_subsurfaces_subsurface;
struct xdg_surface *xdg_surface;
struct xdg_toplevel *xdg_toplevel;
struct wl_cursor_theme *cursor_theme;
struct wl_cursor *default_cursor;
struct wl_surface *cursor_surface;
} wayland_state;
// Actually the following Rect machinery is unused since we don't use shapes
typedef int RECT_T;
#define RECT_EQ_X(r1,r2) ((r1) == (r2))
#define RECT_SET(r,xx,yy,ww,hh) ;
#define RECT_INC_HEIGHT(r) ;
#endif

View File

@@ -0,0 +1,457 @@
/*
* Copyright (c) 2005, 2019, 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 <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"
const int BUFFER_SIZE = 3;
static bool is_cursor_animated = false;
#define NULL_CHECK(val, message) if (val == NULL) { fprintf(stderr, message); return false; }
void SplashReconfigureNow(Splash * splash);
void SplashRedrawWindow(Splash * splash);
static void
randname(char *buf) {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
long r = ts.tv_nsec;
for (int i = 0; i < 6; ++i) {
buf[i] = 'A'+(r&15)+(r&16)*2;
r >>= 5;
}
}
static int
create_shm_file(void) {
int retries = 100;
do {
char name[] = "/wl_shm-XXXXXX";
randname(name + sizeof(name) - 7);
--retries;
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
if (fd >= 0) {
shm_unlink(name);
return fd;
}
} while (retries > 0 && errno == EEXIST);
return -1;
}
static int
allocate_shm_file(size_t size) {
int fd = create_shm_file();
if (fd < 0)
return -1;
int ret;
do {
ret = ftruncate(fd, size);
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
close(fd);
return -1;
}
return fd;
}
static bool
alloc_buffer(int width, int height, struct wl_shm *wl_shm, Buffer *buffer, int format, int format_size) {
int size = width * height * format_size;
int fd = allocate_shm_file(size);
buffer->size = size;
if (fd == -1) {
return false;
}
buffer->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buffer->data == MAP_FAILED) {
close(fd);
return false;
}
struct wl_shm_pool *pool = wl_shm_create_pool(wl_shm, fd, size);
buffer->wl_buffer = wl_shm_pool_create_buffer(pool, 0, width, height, width * format_size, format);
wl_shm_pool_destroy(pool);
close(fd);
return true;
}
static void
registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version) {
wayland_state *state = data;
if (strcmp(interface, wl_shm_interface.name) == 0) {
state->wl_shm = wl_registry_bind(
wl_registry, name, &wl_shm_interface, 1);
} else if (strcmp(interface, wl_compositor_interface.name) == 0) {
state->wl_compositor = wl_registry_bind(
wl_registry, name, &wl_compositor_interface, 4);
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
state->wl_seat = wl_registry_bind(
wl_registry, name, &wl_seat_interface, 1);
} else if (strcmp(interface, wl_subcompositor_interface.name) == 0) {
state->wl_subcompositor = wl_registry_bind(
wl_registry, name, &wl_subcompositor_interface, 1);
} else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
state->xdg_wm_base = wl_registry_bind(
wl_registry, name, &xdg_wm_base_interface, 1);
}
}
static void
registry_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name) {
}
static const struct wl_registry_listener wl_registry_listener = {
.global = registry_global,
.global_remove = registry_global_remove,
};
static void
wl_buffer_release(void *data, struct wl_buffer *wl_buffer) {
Buffer* buffer = data;
buffer->available = true;
}
static const struct wl_buffer_listener wl_buffer_listener = {
.release = wl_buffer_release,
};
void
xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) {
struct Splash *splash = data;
xdg_surface_ack_configure(xdg_surface, serial);
SplashReconfigureNow(splash);
}
static const struct xdg_surface_listener xdg_surface_listener = {
.configure = xdg_surface_configure,
};
static void
handle_toplevel_configure(void *data, struct xdg_toplevel *toplevel, int32_t width, int32_t height,
struct wl_array *states) {
struct Splash *splash = data;
if (width > 0 && height > 0 && (splash->window_width == 0 || splash->window_height == 0)) {
splash->window_width = width;
splash->window_height = height;
}
}
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
.configure = handle_toplevel_configure,
};
static void
pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface,
wl_fixed_t sx, wl_fixed_t sy) {
wayland_state *state = data;
is_cursor_animated = true;
struct wl_cursor_image *image = state->default_cursor->images[0];
wl_pointer_set_cursor(pointer, serial, state->cursor_surface, image->hotspot_x, image->hotspot_y);
}
static void
pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface) {
is_cursor_animated = false;
}
static void
pointer_handle_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {
}
static void
pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
}
static const struct wl_pointer_listener pointer_listener = {
.enter = pointer_handle_enter,
.leave = pointer_handle_leave,
.motion = pointer_handle_motion,
.button = pointer_handle_button,
};
static void
seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) {
wayland_state *state = data;
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !state->pointer) {
state->pointer = wl_seat_get_pointer(seat);
wl_pointer_add_listener(state->pointer, &pointer_listener, state);
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && state->pointer) {
wl_pointer_destroy(state->pointer);
state->pointer = NULL;
}
}
static const struct wl_seat_listener wl_seat_listener = {
.capabilities = seat_handle_capabilities,
};
static void
xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial) {
xdg_wm_base_pong(xdg_wm_base, serial);
}
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
.ping = xdg_wm_base_ping,
};
bool
SplashCreateWindow(Splash * splash) {
splash->state->pointer = NULL;
splash->window_width = 0;
splash->window_height = 0;
splash->native_scale = getNativeScaleFactor(NULL, 1);
if (splash->native_scale == -1.0) {
fprintf(stderr, "Cannot get native scale\n");
return false;
}
splash->state->wl_surface = wl_compositor_create_surface(splash->state->wl_compositor);
NULL_CHECK(splash->state->wl_surface, "Cannot create surface\n")
splash->state->wl_subsurfaces_surface = wl_compositor_create_surface(splash->state->wl_compositor);
NULL_CHECK(splash->state->wl_subsurfaces_surface, "Cannot create surface\n")
wl_surface_set_buffer_scale(splash->state->wl_subsurfaces_surface, splash->native_scale);
wl_surface_set_buffer_scale(splash->state->wl_surface, splash->native_scale);
xdg_wm_base_add_listener(splash->state->xdg_wm_base, &xdg_wm_base_listener, splash->state);
splash->state->xdg_surface = xdg_wm_base_get_xdg_surface(splash->state->xdg_wm_base, splash->state->wl_surface);
NULL_CHECK(splash->state->wl_subsurfaces_surface, "Cannot get xdg_surface\n")
xdg_surface_add_listener(splash->state->xdg_surface, &xdg_surface_listener, splash);
splash->state->xdg_toplevel = xdg_surface_get_toplevel(splash->state->xdg_surface);
NULL_CHECK(splash->state->xdg_toplevel, "Cannot get xdg_toplevel\n")
xdg_toplevel_set_maximized(splash->state->xdg_toplevel);
xdg_toplevel_add_listener(splash->state->xdg_toplevel,&xdg_toplevel_listener, splash);
splash->state->cursor_surface = wl_compositor_create_surface(splash->state->wl_compositor);
NULL_CHECK(splash->state->cursor_surface, "Cannot get cursor_surface\n")
wl_seat_add_listener(splash->state->wl_seat, &wl_seat_listener, splash->state);
splash->state->wl_subsurfaces_subsurface = wl_subcompositor_get_subsurface(
splash->state->wl_subcompositor, splash->state->wl_subsurfaces_surface, splash->state->wl_surface);
NULL_CHECK(splash->state->wl_subsurfaces_subsurface, "Cannot create subsurface\n")
wl_subsurface_set_desync(splash->state->wl_subsurfaces_subsurface);
for (int i = 0; i < BUFFER_SIZE; i++) {
if (!alloc_buffer(splash->width, splash->height,
splash->state->wl_shm, &splash->buffers[i], WL_SHM_FORMAT_XRGB8888, 4)) {
fprintf(stderr, "Cannot allocate enough memory\n");
return false;
}
wl_buffer_add_listener(splash->buffers[i].wl_buffer, &wl_buffer_listener, &splash->buffers[i]);
splash->buffers[i].available = true;
SplashUpdateScreenData(splash, splash->buffers[i].data);
}
splash->state->cursor_theme = wl_cursor_theme_load(NULL, 32, splash->state->wl_shm);
NULL_CHECK(splash->state->cursor_theme, "unable to load default theme\n")
splash->state->default_cursor = wl_cursor_theme_get_cursor(splash->state->cursor_theme, "watch");
NULL_CHECK(splash->state->cursor_theme, "unable to load pointer\n")
return true;
}
int
SplashInitPlatform(Splash * splash) {
#if (defined DEBUG)
_Xdebug = 1;
#endif
pthread_mutex_init(&splash->lock, NULL);
splash->state = malloc(sizeof(wayland_state));
NULL_CHECK(splash->state, "Cannot allocate enough memory\n")
splash->byteAlignment = 1;
splash->maskRequired = 0;
initFormat(&splash->screenFormat, 0xff0000, 0xff00, 0xff, 0xff000000);
splash->screenFormat.byteOrder = 1 ? BYTE_ORDER_LSBFIRST : BYTE_ORDER_MSBFIRST;
splash->screenFormat.depthBytes = 4;
splash->state->wl_display = wl_display_connect(NULL);
NULL_CHECK(splash->state->wl_display, "Cannot connect to display\n")
splash->state->wl_shm = NULL;
splash->state->wl_compositor = NULL;
splash->state->wl_subcompositor = NULL;
splash->state->wl_seat = NULL;
splash->state->xdg_wm_base = NULL;
splash->state->wl_registry = wl_display_get_registry(splash->state->wl_display);
NULL_CHECK(splash->state->wl_registry, "Cannot get display's registry\n")
wl_registry_add_listener(splash->state->wl_registry, &wl_registry_listener, splash->state);
wl_display_roundtrip(splash->state->wl_display);
NULL_CHECK(splash->state->wl_shm, "wl_shm not initialized\n")
NULL_CHECK(splash->state->wl_compositor, "wl_compositor not initialized\n")
NULL_CHECK(splash->state->wl_subcompositor, "wl_subcompositor not initialized\n")
NULL_CHECK(splash->state->wl_seat, "wl_seat not initialized\n")
NULL_CHECK(splash->state->xdg_wm_base, "xdg_wm_base not initialized\n")
return true;
}
void
SplashReconfigureNow(Splash * splash) {
struct wl_region *region = wl_compositor_create_region(splash->state->wl_compositor);
wl_region_subtract(region, 0, 0, splash->window_width, splash->window_height);
wl_region_add(region, splash->x, splash->y, splash->width / splash->native_scale, splash->height / splash->native_scale);
wl_surface_set_input_region(splash->state->wl_surface, region);
wl_surface_set_opaque_region(splash->state->wl_surface, region);
wl_region_destroy(region);
splash->x = ((splash->window_width - splash->width / splash->native_scale) / 2);
splash->y = ((splash->window_height - splash->height / splash->native_scale) / 2);
wl_subsurface_set_position(splash->state->wl_subsurfaces_subsurface, splash->x, splash->y);
alloc_buffer(splash->window_width * splash->native_scale, splash->window_height * splash->native_scale,
splash->state->wl_shm, &splash->main_buffer, WL_SHM_FORMAT_ARGB8888, 4);
memset(splash->main_buffer.data, 0, splash->window_width * splash->window_height * 4);
wl_surface_attach(splash->state->wl_surface, splash->main_buffer.wl_buffer, 0, 0);
wl_surface_damage(splash->state->wl_surface, 0, 0, splash->window_width, splash->window_height);
wl_surface_commit(splash->state->wl_surface);
SplashRedrawWindow(splash);
}
void
SplashRedrawWindow(Splash * splash) {
for (int i = 0; i < BUFFER_SIZE; i++) {
if (splash->buffers[i].available) {
SplashUpdateScreenData(splash, splash->buffers[i].data);
wl_surface_attach(splash->state->wl_subsurfaces_surface, splash->buffers[i].wl_buffer, 0, 0);
wl_surface_damage(splash->state->wl_subsurfaces_surface, 0, 0, splash->window_width, splash->window_height);
wl_surface_commit(splash->state->wl_subsurfaces_surface);
splash->buffers[i].available = false;
}
}
}
bool
FlushEvents(Splash * splash) {
if (wl_display_dispatch_pending(splash->state->wl_display) == -1)
return false;
if (wl_display_flush(splash->state->wl_display) == -1)
return false;
return true;
}
bool
DispatchEvents(Splash * splash) {
return (wl_display_dispatch(splash->state->wl_display) != -1);
}
int
GetDisplayFD(Splash * splash) {
return wl_display_get_fd(splash->state->wl_display);
}
void
SplashUpdateCursor(Splash * splash) {
const int EVENTS_PER_FRAME = 2;
static int index = 0;
if (is_cursor_animated) {
wayland_state *state = splash->state;
struct wl_buffer *buffer;
struct wl_cursor *cursor = state->default_cursor;
struct wl_cursor_image *image;
if (cursor) {
image = state->default_cursor->images[index / EVENTS_PER_FRAME];
index = (index + 1) % (state->default_cursor->image_count * EVENTS_PER_FRAME);
buffer = wl_cursor_image_get_buffer(image);
if (!buffer)
return;
wl_surface_attach(state->cursor_surface, buffer, 0, 0);
wl_surface_damage(state->cursor_surface, 0, 0, image->width, image->height);
wl_surface_commit(state->cursor_surface);
}
}
}
void
SplashCleanupPlatform(Splash * splash) {
munmap(splash->main_buffer.data, splash->main_buffer.size);
for (int i = 0; i < BUFFER_SIZE; i++) {
munmap(splash->buffers[i].data, splash->buffers[i].size);
}
}
void
SplashDonePlatform(Splash * splash) {
pthread_mutex_destroy(&splash->lock);
wl_buffer_destroy(splash->main_buffer.wl_buffer);
for (int i = 0; i < BUFFER_SIZE; i++) {
wl_buffer_destroy(splash->buffers[i].wl_buffer);
}
xdg_surface_destroy(splash->state->xdg_surface);
wl_shm_destroy(splash->state->wl_shm);
xdg_wm_base_destroy(splash->state->xdg_wm_base);
wl_compositor_destroy(splash->state->wl_compositor);
wl_subcompositor_destroy(splash->state->wl_subcompositor);
wl_registry_destroy(splash->state->wl_registry);
wl_surface_destroy(splash->state->wl_surface);
wl_display_flush(splash->state->wl_display);
wl_display_disconnect(splash->state->wl_display);
free(splash->state);
}
void
SplashSetup(Splash * splash) {
}
void
SplashUpdateShape(Splash * splash) {
}
void
SplashInitFrameShape(Splash * splash, int imageIndex) {
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,204 @@
// Copyright 2023 JetBrains s.r.o.
// 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.
/* Generated by wayland-scanner 1.18.0 */
/*
* Copyright © 2008-2013 Kristian Høgsberg
* Copyright © 2013 Rafael Antognolli
* Copyright © 2013 Jasper St. Pierre
* Copyright © 2010-2013 Intel Corporation
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
* Copyright © 2015-2017 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface xdg_popup_interface;
extern const struct wl_interface xdg_positioner_interface;
extern const struct wl_interface xdg_surface_interface;
extern const struct wl_interface xdg_toplevel_interface;
static const struct wl_interface *xdg_shell_types[] = {
NULL,
NULL,
NULL,
NULL,
&xdg_positioner_interface,
&xdg_surface_interface,
&wl_surface_interface,
&xdg_toplevel_interface,
&xdg_popup_interface,
&xdg_surface_interface,
&xdg_positioner_interface,
&xdg_toplevel_interface,
&wl_seat_interface,
NULL,
NULL,
NULL,
&wl_seat_interface,
NULL,
&wl_seat_interface,
NULL,
NULL,
&wl_output_interface,
&wl_seat_interface,
NULL,
&xdg_positioner_interface,
NULL,
};
static const struct wl_message xdg_wm_base_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "create_positioner", "n", xdg_shell_types + 4 },
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
{ "pong", "u", xdg_shell_types + 0 },
};
static const struct wl_message xdg_wm_base_events[] = {
{ "ping", "u", xdg_shell_types + 0 },
};
const struct wl_interface xdg_wm_base_interface = {
"xdg_wm_base", 3,
4, xdg_wm_base_requests,
1, xdg_wm_base_events,
};
static const struct wl_message xdg_positioner_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "set_size", "ii", xdg_shell_types + 0 },
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
{ "set_anchor", "u", xdg_shell_types + 0 },
{ "set_gravity", "u", xdg_shell_types + 0 },
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
{ "set_offset", "ii", xdg_shell_types + 0 },
{ "set_reactive", "3", xdg_shell_types + 0 },
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
"xdg_positioner", 3,
10, xdg_positioner_requests,
0, NULL,
};
static const struct wl_message xdg_surface_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "get_toplevel", "n", xdg_shell_types + 7 },
{ "get_popup", "n?oo", xdg_shell_types + 8 },
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
{ "ack_configure", "u", xdg_shell_types + 0 },
};
static const struct wl_message xdg_surface_events[] = {
{ "configure", "u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
"xdg_surface", 3,
5, xdg_surface_requests,
1, xdg_surface_events,
};
static const struct wl_message xdg_toplevel_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "set_parent", "?o", xdg_shell_types + 11 },
{ "set_title", "s", xdg_shell_types + 0 },
{ "set_app_id", "s", xdg_shell_types + 0 },
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
{ "move", "ou", xdg_shell_types + 16 },
{ "resize", "ouu", xdg_shell_types + 18 },
{ "set_max_size", "ii", xdg_shell_types + 0 },
{ "set_min_size", "ii", xdg_shell_types + 0 },
{ "set_maximized", "", xdg_shell_types + 0 },
{ "unset_maximized", "", xdg_shell_types + 0 },
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
{ "unset_fullscreen", "", xdg_shell_types + 0 },
{ "set_minimized", "", xdg_shell_types + 0 },
};
static const struct wl_message xdg_toplevel_events[] = {
{ "configure", "iia", xdg_shell_types + 0 },
{ "close", "", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
"xdg_toplevel", 3,
14, xdg_toplevel_requests,
2, xdg_toplevel_events,
};
static const struct wl_message xdg_popup_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "grab", "ou", xdg_shell_types + 22 },
{ "reposition", "3ou", xdg_shell_types + 24 },
};
static const struct wl_message xdg_popup_events[] = {
{ "configure", "iiii", xdg_shell_types + 0 },
{ "popup_done", "", xdg_shell_types + 0 },
{ "repositioned", "3u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
"xdg_popup", 3,
3, xdg_popup_requests,
3, xdg_popup_events,
};

View File

@@ -41,9 +41,6 @@
#include <stdio.h>
#include "systemScale.h"
typedef uint32_t rgbquad_t;
typedef uint16_t word_t;
typedef uint8_t byte_t;
typedef XRectangle RECT_T;
#define RECT_EQ_X(r1,r2) ((r1).x==(r2).x && (r1).width==(r2).width)
@@ -51,10 +48,4 @@ typedef XRectangle RECT_T;
(r).height=(hh);
#define RECT_INC_HEIGHT(r) (r).height++;
#define SPLASHCTL_QUIT 'Q'
#define SPLASHCTL_UPDATE 'U'
#define SPLASHCTL_RECONFIGURE 'R'
#define INLINE static
#endif

View File

@@ -49,60 +49,6 @@ 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;
@@ -136,25 +82,6 @@ SplashInitFrameShape(Splash * splash, int imageIndex) {
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];
@@ -208,7 +135,8 @@ FreeColors(Display * display, Screen * screen, int numColors,
XFreeColors(display, cmap, pr, numColors, 0);
}
static void SplashCenter(Splash * splash) {
static void
SplashCenter(Splash * splash) {
Atom type, atom, actual_type;
int status, actual_format;
unsigned long nitems, bytes_after;
@@ -236,7 +164,8 @@ static void SplashCenter(Splash * splash) {
splash->y = (XHeightOfScreen(splash->screen) - splash->height) / 2;
}
static void SplashUpdateSizeHints(Splash * splash) {
static void
SplashUpdateSizeHints(Splash * splash) {
if (splash->window) {
XSizeHints sizeHints;
@@ -249,7 +178,7 @@ static void SplashUpdateSizeHints(Splash * splash) {
}
}
void
bool
SplashCreateWindow(Splash * splash) {
XSizeHints sizeHints;
@@ -277,6 +206,8 @@ SplashCreateWindow(Splash * splash) {
splash->wmHints->initial_state = NormalState;
XSetWMHints(splash->display, splash->window, splash->wmHints);
}
return (bool) splash->window;
}
/* for changing the visible shape of a window to an nonrectangular form */
@@ -333,7 +264,7 @@ SplashRedrawWindow(Splash * splash) {
// much sense as SplashUpdateScreenData always re-generates
// the image completely, so whole window is always redrawn
SplashUpdateScreenData(splash);
SplashUpdateScreenData(splash, NULL);
ximage = XCreateImage(splash->display, splash->visual,
splash->screenFormat.depthBytes * 8, ZPixmap, 0, (char *) NULL,
splash->width, splash->height, 8, 0);
@@ -352,7 +283,8 @@ SplashRedrawWindow(Splash * splash) {
XFlush(splash->display);
}
void SplashReconfigureNow(Splash * splash) {
void
SplashReconfigureNow(Splash * splash) {
SplashCenter(splash);
if (splash->window) {
XUnmapWindow(splash->display, splash->window);
@@ -369,15 +301,6 @@ void SplashReconfigureNow(Splash * 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
HandleError(Display * disp, XErrorEvent * err) {
// silently ignore non-fatal errors
@@ -548,93 +471,38 @@ SplashDonePlatform(Splash * splash) {
XCloseDisplay(splash->display);
}
void
SplashEventLoop(Splash * splash) {
bool
FlushEvents(Splash * splash) {
return true;
}
/* Different from win32 implementation - this loop
uses poll timeouts instead of a timer */
/* we should have splash _locked_ on entry!!! */
bool
DispatchEvents(Splash * splash) {
// we're not using "while(XPending)", processing one event
// at a time to avoid control pipe starvation
if (XPending(splash->display)) {
XEvent evt;
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;
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);
}
}
// 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;
/* ... */
}
}
break;
/* ... */
}
}
return true;
}
int
GetDisplayFD(Splash * splash) {
return XConnectionNumber(splash->display);
}
/* we can't use OverrideRedirect for the window as the window should not be
@@ -725,93 +593,13 @@ SplashRemoveDecoration(Splash * splash) {
}
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;
SplashSetup(Splash * splash) {
SplashRemoveDecoration(splash);
XStoreName(splash->display, splash->window, "Java");
XMapRaised(splash->display, splash->window);
SplashUpdateShape(splash);
}
void
SplashCreateThread(Splash * splash) {
pthread_t thr;
pthread_attr_t attr;
int rc;
pthread_attr_init(&attr);
rc = pthread_create(&thr, &attr, SplashScreenThread, (void *) splash);
}
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(NULL, 1);
return GetScaledImageName(fileName, scaledImgName, scaleFactor, scaledImageNameLength);
}
SplashUpdateCursor(Splash * splash) {
}