Compare commits

..

32 Commits

Author SHA1 Message Date
Nikita Tsarev
8dfd14f671 JBR-8353: Use a deletion queue to destroy data transfer objects [WLToolkit] 2025-10-20 21:09:46 +02:00
Nikita Gubarkov
49bed44184 JBR-9486 Vulkan: Handle VK_ERROR_OUT_OF_DATE_KHR 2025-10-16 20:32:31 +02:00
Vitaly Provodin
a270d9e6a3 clean up fixed issues from exclude lists, start 2026.1 2025-10-16 14:48:45 +04:00
Vitaly Provodin
11e3c06ba0 update exclude list on results of 25.165.38 test runs 2025-10-16 06:50:07 +04:00
Nikita Gubarkov
95c6f7c37f JBR-9481 Vulkan: OOM-safe BLIT 2025-10-15 18:44:53 +02:00
Nikita Provotorov
c4f2b64d19 JBR-5672: Wayland: support input methods.
Providing support of the "text-input-unstable-v3" protocol, except its surrounding text API (zwp_text_input_v3::set_surrounding_text + zwp_text_input_v3::delete_surrounding_text).
A new system property "sun.awt.wl.im.enabled"[=true|false] is introduced to enable/disable all the integrations with Wayland's native input methods. Set to 'true' by default.

(cherry picked from commit 1c37490f00)
2025-10-15 03:43:41 +02:00
Nikita Provotorov
9a6415585d fixup! JBR-6376: implement detecting of OS theme on linux
Adding the D-Bus libs as a dependency: it's required for src/java.desktop/linux/native/libawt/awt/dbus_interface.h

(cherry picked from commit 3fb240f4aa)
2025-10-14 20:53:18 +02:00
Nikita Gubarkov
51d7cd2afb JBR-9477 JBR API: Update local artifact group 2025-10-14 12:40:21 +02:00
bourgesl
3c66bdc1e9 JBR-9375 macOS: Right-click context menu shows blurry animation when opening
Disable NSWindow animationBehavior (=NSWindowAnimationBehaviorNone) by default except if the system property 'apple.awt.window.animation' = true
+ Fixed J2dRlsTraceLn
2025-10-14 08:16:47 +02:00
Nikita Gubarkov
e65cb43ba1 JBR-9438 Vulkan: JBR API for accessing configuration info 2025-10-13 16:52:02 +02:00
Nikita Tsarev
7c84fbe810 JBR-8353: Fix wrong order of java/wayland object destruction in DataOffer/DataSource [WLToolkit] 2025-10-10 14:29:00 +02:00
Vitaly Provodin
6c47534225 update exclude list on results of 25.152.37 test runs 2025-10-10 03:17:36 +04:00
Maxim Kartashev
ffde0964ef JBR-9451 Wayland: Calling other JNI functions in the scope of Get/ReleasePrimitiveArrayCritical or Get/ReleaseStringCritical 2025-10-09 16:38:25 +04:00
Alexey Ushakov
d0299a4c6a JBR-9292 Vulkan: RenderPerfTest missing frames 2025-10-08 22:51:35 +02:00
Nikita Gubarkov
1186447190 JBR-9457 Vulkan: Enable accelerated surfaces by default 2025-10-08 22:10:35 +02:00
Nikita Gubarkov
4eab05ccd9 JBR-7646 Vulkan: Implement painting modes 2025-10-08 22:10:35 +02:00
Nikita Gubarkov
74b4df4496 JBR-9450 Vulkan: Unify pipelines 2025-10-08 22:09:48 +02:00
Nikita Gubarkov
8f660e630c JBR-9439 Vulkan: Fix blit composites 2025-10-08 22:09:40 +02:00
Nikita Gubarkov
4bd1551dc4 JBR-8344 Vulkan: Fix color XOR 2025-10-08 16:46:02 +02:00
Nikita Tsarev
4879508145 JBR-9449: Use wl_proxy_create_wrapper when creating data source objects for thread-safety [WLToolkit] 2025-10-07 10:25:16 +02:00
Maxim Kartashev
84473294fb JBR-9364 Wayland: Popups are shifted with multiple monitor setup after monitor reconnected (Ubuntu) 2025-10-07 10:17:17 +04:00
bourgesl
57e694c1ae JBR-9408 Fix Marlin renderer statistics
Revert JBR-9283 changes to StatLong (completely) to avoid future conflicts

(cherry picked from commit bc60599b45bddcb2d251035f945b5616e43554d2)
(cherry picked from commit 5be4830ecf30e2c74d1e828e3482edca03d166c6)
2025-10-05 23:17:06 +02:00
bourgesl
12e0466566 JDK-8341381 Random lines appear in graphic causing by the fix of JDK-8297230
- Fix cubic offsetting artefacts (sort cubic roots + fixed numerical accuracy problem in ROC^2-w^2 = 0 solver + fixed EliminateInf)
- Restored lower precision using ulp(float) in point, line or flat bezier curve checks

(cherry picked from commit e72b87e6538dda97e6f0f2840040c6864b3f146e)
2025-10-05 23:04:09 +02:00
Nikita Gubarkov
02ab184c01 JBR-9425 Vulkan: Fix surface disposal 2025-10-01 13:19:46 +02:00
Vitaly Provodin
bf7dea965a update exclude list on results of 25.144.34 test runs 2025-10-01 08:48:01 +04:00
Maxim Kartashev
58b3c7ed57 JBR-9378 Wayland: Nullpointer exception in DefaultFrameDecoration, IDE hang on KDE 2025-09-30 16:34:04 +04:00
Maxim Kartashev
631811837d JBR-6990 Wayland: utilize relative-pointer-unstable-v1 protocol 2025-09-30 09:43:53 +04:00
Maxim Kartashev
3ff4b846da JBR-9384 Wayland: ShowPopupAfterHidePopupTest.java fails 2025-09-29 16:24:01 +04:00
Alexey Ushakov
b175e32148 JBR-9301 Vulkan: SwingSet2 crash window server
Clear native peer on windowClosing in Frame object

(cherry picked from commit 441bb9d12ebff4bf2e1629115b9414b0b22ec858)
2025-09-23 15:23:44 +02:00
Nikita Tsarev
8e287c09a0 JBR-9330: Set scale for drag images [WLToolkit] 2025-09-22 17:12:10 +02:00
Vitaly Provodin
28f9408b29 fixup! update exclude list on results of 25.135.30 test runs 2025-09-22 04:51:45 +04:00
Vitaly Provodin
338f1df777 update exclude list on results of 25.135.30 test runs 2025-09-21 16:19:29 +04:00
96 changed files with 6465 additions and 1070 deletions

2
.github/README.md vendored
View File

@@ -161,7 +161,7 @@ Install the necessary tools, libraries, and headers with:
```
$ sudo apt-get install autoconf make build-essential libx11-dev libxext-dev libxrender-dev libxtst-dev \
libxt-dev libxrandr-dev libcups2-dev libfontconfig1-dev libasound2-dev libspeechd-dev libwayland-dev \
wayland-protocols libxkbcommon-x11-0
wayland-protocols libxkbcommon-x11-0 libdbus-1-dev
```
Get Java 23 (for instance, [Azul Zulu Builds of OpenJDK 23](https://www.azul.com/downloads/?version=java-23&os=linux&package=jdk#zulu)).

View File

@@ -40,13 +40,13 @@ else ifeq ($(call isBuildOsEnv, windows.wsl1 windows.wsl2), true)
else
M2_REPO := $(HOME)/.m2/repository
endif
M2_ARTIFACT := $(M2_REPO)/com/jetbrains/jbr-api/SNAPSHOT
M2_ARTIFACT := $(M2_REPO)/org/jetbrains/runtime/jbr-api/SNAPSHOT
M2_POM_CONTENT := \
<?xml version="1.0" encoding="UTF-8"?> \
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" \
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> \
<modelVersion>4.0.0</modelVersion> \
<groupId>com.jetbrains</groupId> \
<groupId>org.jetbrains.runtime</groupId> \
<artifactId>jbr-api</artifactId> \
<version>SNAPSHOT</version> \
</project> \
@@ -65,7 +65,8 @@ jbr-api:
$(MKDIR) -p $(M2_ARTIFACT); \
$(ECHO) '$(M2_POM_CONTENT)' > $(M2_ARTIFACT)/$(ARTIFACT_NAME).pom; \
$(CP) "$(JBR_API_DIR)/out/$(ARTIFACT_NAME).jar" "$(M2_ARTIFACT)"; \
$(ECHO) "Installed into local Maven repository as com.jetbrains:jbr-api:SNAPSHOT"; \
$(ECHO) "Installed into local Maven repository as org.jetbrains.runtime:jbr-api:SNAPSHOT"; \
cd "$(M2_ARTIFACT)" && sha256sum --binary "$(ARTIFACT_NAME).jar"; \
else \
$(ECHO) "No Maven repository found at $(M2_REPO) - skipping local installation"; \
fi

View File

@@ -89,7 +89,7 @@ AC_DEFUN_ONCE([LIB_SETUP_VULKAN],
if (test "x${with_vulkan_shader_compiler}" = x || test "x${with_vulkan_shader_compiler}" = xglslc); then
UTIL_LOOKUP_PROGS(GLSLC, glslc)
SHADER_COMPILER="$GLSLC"
VULKAN_SHADER_COMPILER="glslc --target-env=vulkan1.2 -mfmt=num -o"
VULKAN_SHADER_COMPILER="glslc --target-env=vulkan1.2 -mfmt=num"
fi
# Check glslangValidator
@@ -97,7 +97,8 @@ AC_DEFUN_ONCE([LIB_SETUP_VULKAN],
test "x$SHADER_COMPILER" = x; then
UTIL_LOOKUP_PROGS(GLSLANG, glslangValidator)
SHADER_COMPILER="$GLSLANG"
VULKAN_SHADER_COMPILER="glslangValidator --target-env vulkan1.2 -x -o"
# Newer glslangValidator could use -P\"\#extension GL_GOOGLE_include_directive: require\"
VULKAN_SHADER_COMPILER="glslangValidator --target-env vulkan1.2 -x"
fi
if test "x$SHADER_COMPILER" = x; then

View File

@@ -35,6 +35,8 @@ WAYLAND_BASIC_PROTOCOL_FILES := \
$(WAYLAND_PROTOCOLS_ROOT)/staging/xdg-activation/xdg-activation-v1.xml \
$(WAYLAND_PROTOCOLS_ROOT)/unstable/primary-selection/primary-selection-unstable-v1.xml \
$(WAYLAND_PROTOCOLS_ROOT)/unstable/xdg-output/xdg-output-unstable-v1.xml \
$(WAYLAND_PROTOCOLS_ROOT)/unstable/relative-pointer/relative-pointer-unstable-v1.xml \
$(WAYLAND_PROTOCOLS_ROOT)/unstable/text-input/text-input-unstable-v3.xml \
$(GTK_SHELL1_PROTOCOL_PATH) \
#

View File

@@ -220,7 +220,7 @@ endif
# Compile Vulkan shaders
define compile-spirv
$(call MakeTargetDir)
$(VULKAN_SHADER_COMPILER) '$(call DecodeSpace, $@)' '$(call DecodeSpace, $<)'
$(VULKAN_SHADER_COMPILER) -D$(call uppercase,$(patsubst .%,STAGE_%,$(suffix $<))) -o '$(call DecodeSpace, $@)' '$(call DecodeSpace, $<)'
endef
spirv-name = $(strip $1).h

View File

@@ -75,6 +75,19 @@ BOOL isColorMatchingEnabled() {
return (BOOL)colorMatchingEnabled;
}
BOOL isWindowAnimationEnabled() {
static int windowAnimationEnabled = -1;
if (windowAnimationEnabled == -1) {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
if (env == NULL) return NO;
NSString* windowAnimationEnabledProp = [PropertiesUtilities javaSystemPropertyForKey:@"apple.awt.window.animation"
withEnv:env];
windowAnimationEnabled = [@"true" isCaseInsensitiveLike:windowAnimationEnabledProp] ? YES : NO;
J2dRlsTraceLn(J2D_TRACE_INFO, "AWTWindow_windowAnimationEnabled: %d", windowAnimationEnabled);
}
return (BOOL)windowAnimationEnabled;
}
@interface NSTitlebarAccessoryViewController (Private)
- (void)_setHidden:(BOOL)h animated:(BOOL)a;
@end
@@ -605,6 +618,10 @@ AWT_ASSERT_APPKIT_THREAD;
if (self.nsWindow == nil) return nil; // no hope either
[self.nsWindow release]; // the property retains the object already
if (!isWindowAnimationEnabled()
&& (self.nsWindow.animationBehavior != NSWindowAnimationBehaviorNone)) {
self.nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
}
if (isColorMatchingEnabled()) {
// Supported by both OpenGL & Metal pipelines
// Tell the system we have an sRGB backing store
@@ -3008,8 +3025,6 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetRoundedCor
NSWindow *w = (NSWindow *)jlong_to_ptr(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
w.hasShadow = YES;
w.contentView.wantsLayer = YES;
w.contentView.layer.cornerRadius = radius;
w.contentView.layer.masksToBounds = YES;
w.contentView.layer.opaque = NO;
@@ -3024,11 +3039,11 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetRoundedCor
w.contentView.layer.borderWidth = borderWidth;
w.contentView.layer.borderColor = color.CGColor;
}
w.contentView.wantsLayer = YES;
w.backgroundColor = NSColor.clearColor;
w.opaque = NO;
// remove corner radius animation
[w.contentView.layer removeAllAnimations];
w.hasShadow = YES;
[w invalidateShadow];
}];

View File

@@ -129,6 +129,7 @@ BOOL MTLLayer_isExtraRedrawEnabled() {
[NSNull null], @"anchorPoint",
[NSNull null], @"bounds",
[NSNull null], @"contents",
[NSNull null], @"cornerRadius",
[NSNull null], @"contentsScale",
[NSNull null], @"onOrderIn",
[NSNull null], @"onOrderOut",

View File

@@ -63,6 +63,7 @@ AWT_ASSERT_APPKIT_THREAD;
[NSNull null], @"anchorPoint",
[NSNull null], @"bounds",
[NSNull null], @"contents",
[NSNull null], @"cornerRadius",
[NSNull null], @"contentsScale",
[NSNull null], @"onOrderIn",
[NSNull null], @"onOrderOut",

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2025 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.
*/
package com.jetbrains.desktop;
import com.jetbrains.exported.JBRApi;
import sun.java2d.vulkan.VKEnv;
import sun.java2d.vulkan.VKGPU;
@JBRApi.Service
@JBRApi.Provides("Vulkan")
public class Vulkan {
Vulkan() {
if (!VKEnv.isVulkanEnabled()) throw new JBRApi.ServiceNotAvailableException("Vulkan is not enabled");
}
boolean isPresentationEnabled() {
return VKEnv.isPresentationEnabled();
}
Device[] getDevices() {
return VKEnv.getDevices().map(Device::new).toArray(Device[]::new);
}
@JBRApi.Provides("Vulkan.Device")
static class Device {
private final VKGPU device;
Device(VKGPU device) {
this.device = device;
}
String getName() {
return device.getName();
}
String getTypeString() {
return device.getType().toString();
}
int getCapabilities() {
return device.getCaps();
}
}
}

View File

@@ -4377,6 +4377,11 @@ public class Window extends Container implements Accessible {
}
}
@Override
public void addWindowListener(Window w, WindowListener listener) {
w.addWindowListener(listener);
}
private static void dumpCounter(final String counterName, final double valPerSecond) {
if (USE_COUNTERS) {
doLog(String.format("%s per second: %.2f", counterName, valPerSecond),

View File

@@ -37,6 +37,7 @@ import java.awt.event.InputEvent;
import java.awt.event.InvocationEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferStrategy;
import java.awt.peer.ComponentPeer;
@@ -337,6 +338,8 @@ public final class AWTAccessor {
double getCounterPerSecond(Window w, String counterName);
void dumpStats(Window w, boolean reset, StringBuilder sb);
void addWindowListener(Window w, WindowListener listener);
}
/**

View File

@@ -50,6 +50,7 @@ import java.awt.KeyboardFocusManager;
import java.awt.Label;
import java.awt.MenuComponent;
import java.awt.Panel;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.ScrollPane;
import java.awt.Scrollbar;
@@ -90,6 +91,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import com.jetbrains.exported.JBRApi;
import sun.awt.im.InputContext;
import sun.awt.image.ByteArrayImageSource;
import sun.awt.image.FileImageSource;
@@ -2084,6 +2086,23 @@ public abstract class SunToolkit extends Toolkit
return AWTAccessor.getAWTEventAccessor().isSystemGenerated(e);
}
@JBRApi.Service
@JBRApi.Provides("RelativePointerMovement")
public interface RelativePointerMovementInfoProvider {
private static RelativePointerMovementInfoProvider create() {
var tk = Toolkit.getDefaultToolkit();
if (tk instanceof ComponentFactory cf) {
var mouseInfoPeer = cf.getMouseInfoPeer();
if (mouseInfoPeer instanceof RelativePointerMovementInfoProvider p){
return p;
}
}
throw new JBRApi.ServiceNotAvailableException("Service not supported for toolkit " + tk.getClass().getName());
}
Point getAccumulatedMouseDeltaAndReset();
}
} // class SunToolkit

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2025, 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
@@ -144,7 +144,9 @@ final class Curve {
// finds points where the first and second derivative are
// perpendicular. This happens when g(t) = f'(t)*f''(t) == 0 (where
// * is a dot product). Unfortunately, we have to solve a cubic.
private int perpendiculardfddf(final double[] pts, final int off) {
private int perpendiculardfddf(final double[] pts, final int off,
final double A, final double B)
{
assert pts.length >= off + 4;
// these are the coefficients of some multiple of g(t) (not g(t),
@@ -155,7 +157,7 @@ final class Curve {
final double c = 2.0d * (dax * cx + day * cy) + dbx * dbx + dby * dby;
final double d = dbx * cx + dby * cy;
return Helpers.cubicRootsInAB(a, b, c, d, pts, off, 0.0d, 1.0d);
return Helpers.cubicRootsInAB(a, b, c, d, pts, off, A, B);
}
// Tries to find the roots of the function ROC(t)-w in [0, 1). It uses
@@ -171,35 +173,43 @@ final class Curve {
// at most 4 sub-intervals of (0,1). ROC has asymptotes at inflection
// points, so roc-w can have at least 6 roots. This shouldn't be a
// problem for what we're trying to do (draw a nice looking curve).
int rootsOfROCMinusW(final double[] roots, final int off, final double w2, final double err) {
int rootsOfROCMinusW(final double[] roots, final int off, final double w2,
final double A, final double B)
{
// no OOB exception, because by now off<=6, and roots.length >= 10
assert off <= 6 && roots.length >= 10;
int ret = off;
final int end = off + perpendiculardfddf(roots, off);
final int end = off + perpendiculardfddf(roots, off, A, B);
Helpers.isort(roots, off, end);
roots[end] = 1.0d; // always check interval end points
double t0 = 0.0d, ft0 = ROCsq(t0) - w2;
double t0 = 0.0d;
double ft0 = eliminateInf(ROCsq(t0) - w2);
double t1, ft1;
for (int i = off; i <= end; i++) {
double t1 = roots[i], ft1 = ROCsq(t1) - w2;
t1 = roots[i];
ft1 = eliminateInf(ROCsq(t1) - w2);
if (ft0 == 0.0d) {
roots[ret++] = t0;
} else if (ft1 * ft0 < 0.0d) { // have opposite signs
// (ROC(t)^2 == w^2) == (ROC(t) == w) is true because
// ROC(t) >= 0 for all t.
roots[ret++] = falsePositionROCsqMinusX(t0, t1, w2, err);
roots[ret++] = falsePositionROCsqMinusX(t0, t1, ft0, ft1, w2, A); // A = err
}
t0 = t1;
ft0 = ft1;
}
return ret - off;
}
private static double eliminateInf(final double x) {
return (x == Double.POSITIVE_INFINITY ? Double.MAX_VALUE :
(x == Double.NEGATIVE_INFINITY ? Double.MIN_VALUE : x));
private final static double MAX_ROC_SQ = 1e20;
private static double eliminateInf(final double x2) {
// limit the value of x to avoid numerical problems (smaller step):
// must handle NaN and +Infinity:
return (x2 <= MAX_ROC_SQ) ? x2 : MAX_ROC_SQ;
}
// A slight modification of the false position algorithm on wikipedia.
@@ -210,17 +220,18 @@ final class Curve {
// and turn out. Same goes for the newton's method
// algorithm in Helpers.java
private double falsePositionROCsqMinusX(final double t0, final double t1,
final double ft0, final double ft1,
final double w2, final double err)
{
final int iterLimit = 100;
int side = 0;
double t = t1, ft = eliminateInf(ROCsq(t) - w2);
double s = t0, fs = eliminateInf(ROCsq(s) - w2);
double s = t0, fs = eliminateInf(ft0);
double t = t1, ft = eliminateInf(ft1);
double r = s, fr;
for (int i = 0; i < iterLimit && Math.abs(t - s) > err * Math.abs(t + s); i++) {
for (int i = 0; i < iterLimit && Math.abs(t - s) > err; i++) {
r = (fs * t - ft * s) / (fs - ft);
fr = ROCsq(r) - w2;
fr = eliminateInf(ROCsq(r) - w2);
if (sameSign(fr, ft)) {
ft = fr; t = r;
if (side < 0) {
@@ -241,7 +252,7 @@ final class Curve {
break;
}
}
return r;
return (Math.abs(ft) <= Math.abs(fs)) ? t : s;
}
private static boolean sameSign(final double x, final double y) {
@@ -256,9 +267,9 @@ final class Curve {
final double dy = t * (t * day + dby) + cy;
final double ddx = 2.0d * dax * t + dbx;
final double ddy = 2.0d * day * t + dby;
final double dx2dy2 = dx * dx + dy * dy;
final double ddx2ddy2 = ddx * ddx + ddy * ddy;
final double ddxdxddydy = ddx * dx + ddy * dy;
return dx2dy2 * ((dx2dy2 * dx2dy2) / (dx2dy2 * ddx2ddy2 - ddxdxddydy * ddxdxddydy));
final double dx2dy2 = dx * dx + dy * dy; // positive
final double dxddyddxdy = dx * ddy - dy * ddx;
// may return +Infinity if dxddyddxdy = 0 or NaN if 0/0:
return (dx2dy2 * dx2dy2 * dx2dy2) / (dxddyddxdy * dxddyddxdy); // both positive
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2025, 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
@@ -564,7 +564,7 @@ public final class DMarlinRenderingEngine extends RenderingEngine
}
private static boolean nearZero(final double num) {
return Math.abs(num) < 2.0d * Math.ulp(num);
return Math.abs(num) < 2.0d * Helpers.ulp(num);
}
abstract static class NormalizingPathIterator implements PathIterator {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2025, 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
@@ -31,12 +31,19 @@ import sun.java2d.marlin.stats.StatLong;
final class Helpers implements MarlinConst {
private final static double T_ERR = 1e-4;
private final static double T_A = T_ERR;
private final static double T_B = 1.0 - T_ERR;
private static final double EPS = 1e-9d;
private Helpers() {
throw new Error("This is a non instantiable class");
}
/** use lower precision like former Pisces and Marlin (float-precision) */
static double ulp(final double value) { return Math.ulp((float)value); }
static boolean within(final double x, final double y) {
return within(x, y, EPS);
}
@@ -322,10 +329,10 @@ final class Helpers implements MarlinConst {
// now we must subdivide at points where one of the offset curves will have
// a cusp. This happens at ts where the radius of curvature is equal to w.
ret += c.rootsOfROCMinusW(ts, ret, w2, 0.0001d);
ret += c.rootsOfROCMinusW(ts, ret, w2, T_A, T_B);
ret = filterOutNotInAB(ts, 0, ret, 0.0001d, 0.9999d);
isort(ts, ret);
ret = filterOutNotInAB(ts, 0, ret, T_A, T_B);
isort(ts, 0, ret);
return ret;
}
@@ -354,7 +361,7 @@ final class Helpers implements MarlinConst {
if ((outCodeOR & OUTCODE_BOTTOM) != 0) {
ret += curve.yPoints(ts, ret, clipRect[1]);
}
isort(ts, ret);
isort(ts, 0, ret);
return ret;
}
@@ -374,11 +381,11 @@ final class Helpers implements MarlinConst {
}
}
static void isort(final double[] a, final int len) {
for (int i = 1, j; i < len; i++) {
static void isort(final double[] a, final int off, final int len) {
for (int i = off + 1, j; i < len; i++) {
final double ai = a[i];
j = i - 1;
for (; j >= 0 && a[j] > ai; j--) {
for (; j >= off && a[j] > ai; j--) {
a[j + 1] = a[j];
}
a[j + 1] = ai;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2025, 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
@@ -886,8 +886,8 @@ final class Stroker implements StartFlagPathConsumer2D, MarlinConst {
// if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4,
// in which case ignore if p1 == p2
final boolean p1eqp2 = Helpers.withinD(dx1, dy1, 6.0d * Math.ulp(y2));
final boolean p3eqp4 = Helpers.withinD(dx4, dy4, 6.0d * Math.ulp(y4));
final boolean p1eqp2 = Helpers.withinD(dx1, dy1, 6.0d * Helpers.ulp(y2));
final boolean p3eqp4 = Helpers.withinD(dx4, dy4, 6.0d * Helpers.ulp(y4));
if (p1eqp2 && p3eqp4) {
return getLineOffsets(x1, y1, x4, y4, leftOff, rightOff);
@@ -905,7 +905,7 @@ final class Stroker implements StartFlagPathConsumer2D, MarlinConst {
final double l1sq = dx1 * dx1 + dy1 * dy1;
final double l4sq = dx4 * dx4 + dy4 * dy4;
if (Helpers.within(dotsq, l1sq * l4sq, 4.0d * Math.ulp(dotsq))) {
if (Helpers.within(dotsq, l1sq * l4sq, 4.0d * Helpers.ulp(dotsq))) {
return getLineOffsets(x1, y1, x4, y4, leftOff, rightOff);
}
@@ -1078,8 +1078,8 @@ final class Stroker implements StartFlagPathConsumer2D, MarlinConst {
// equal if they're very close to each other.
// if p1 == p2 or p2 == p3: draw line from p1->p3
final boolean p1eqp2 = Helpers.withinD(dx12, dy12, 6.0d * Math.ulp(y2));
final boolean p2eqp3 = Helpers.withinD(dx23, dy23, 6.0d * Math.ulp(y3));
final boolean p1eqp2 = Helpers.withinD(dx12, dy12, 6.0d * Helpers.ulp(y2));
final boolean p2eqp3 = Helpers.withinD(dx23, dy23, 6.0d * Helpers.ulp(y3));
if (p1eqp2 || p2eqp3) {
return getLineOffsets(x1, y1, x3, y3, leftOff, rightOff);
@@ -1091,7 +1091,7 @@ final class Stroker implements StartFlagPathConsumer2D, MarlinConst {
final double l1sq = dx12 * dx12 + dy12 * dy12;
final double l3sq = dx23 * dx23 + dy23 * dy23;
if (Helpers.within(dotsq, l1sq * l3sq, 4.0d * Math.ulp(dotsq))) {
if (Helpers.within(dotsq, l1sq * l3sq, 4.0d * Helpers.ulp(dotsq))) {
return getLineOffsets(x1, y1, x3, y3, leftOff, rightOff);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@@ -27,7 +27,7 @@ package sun.java2d.marlin;
public final class Version {
private static final String VERSION = "marlin-0.9.4.7-Unsafe-OpenJDK";
private static final String VERSION = "marlin-0.9.4.9-Unsafe-OpenJDK";
public static String getVersion() {
return VERSION;

View File

@@ -31,18 +31,20 @@ package sun.java2d.marlin.stats;
public class StatLong {
public final String name;
public long count, sum, min, max;
public long count = 0L;
public long sum = 0L;
public long min = Integer.MAX_VALUE;
public long max = Integer.MIN_VALUE;
public StatLong(final String name) {
this.name = name;
reset();
}
public void reset() {
count = 0L;
sum = 0L;
min = Long.MAX_VALUE;
max = Long.MIN_VALUE;
min = Integer.MAX_VALUE;
max = Integer.MIN_VALUE;
}
public void add(final int val) {
@@ -76,7 +78,7 @@ public class StatLong {
sb.append(name).append('[').append(count);
sb.append("] sum: ").append(sum).append(" avg: ");
sb.append(trimTo3Digits(((double) sum) / count));
sb.append(" [").append(min).append(" - ").append(max).append("]");
sb.append(" [").append(min).append(" | ").append(max).append("]");
return sb;
}
@@ -87,7 +89,7 @@ public class StatLong {
* @return double value with only 3 decimal digits
*/
public static double trimTo3Digits(final double value) {
return Double.isFinite(value) ? ((long) (1e3d * value)) / 1e3d : Double.NaN;
return ((long) (1e3d * value)) / 1e3d;
}
}

View File

@@ -48,7 +48,7 @@ public final class VKEnv {
@SuppressWarnings("removal")
private static final boolean accelsd = vulkan && "true".equalsIgnoreCase(AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan.accelsd", "")));
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan.accelsd", "true")));
@SuppressWarnings("removal")
private static final int deviceNumber = !vulkan ? 0 : AccessController.doPrivileged(

View File

@@ -36,6 +36,7 @@ import sun.java2d.loops.CompositeType;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.SurfaceType;
import static sun.java2d.pipe.BufferedOpCodes.CONFIGURE_SURFACE;
import static sun.java2d.pipe.BufferedOpCodes.DISPOSE_SURFACE;
import sun.java2d.pipe.BufferedContext;
import sun.java2d.pipe.ParallelogramPipe;
import sun.java2d.pipe.PixelToParallelogramConverter;
@@ -43,7 +44,6 @@ import sun.java2d.pipe.RenderBuffer;
import sun.java2d.pipe.TextPipe;
import sun.java2d.pipe.hw.AccelSurface;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
@@ -137,6 +137,28 @@ public abstract class VKSurfaceData extends SurfaceData
}
}
/**
* Disposes the native resources associated with the given VKSurfaceData
* (referenced by the pData parameter). This method is invoked from
* the native Dispose() method from the Disposer thread when the
* Java-level VKSurfaceData object is about to go away.
*/
static void dispose(long pData) {
VKRenderQueue rq = VKRenderQueue.getInstance();
rq.lock();
try {
RenderBuffer buf = rq.getBuffer();
rq.ensureCapacityAndAlignment(12, 4);
buf.putInt(DISPOSE_SURFACE);
buf.putLong(pData);
// this call is expected to complete synchronously, so flush now
rq.flushNow();
} finally {
rq.unlock();
}
}
public BufferedImage getSnapshot(int x, int y, int width, int height) {
BufferedImage image = getFormat().createCompatibleImage(width, height, getTransparency());
SurfaceData sd = SurfaceData.getPrimarySurfaceData(image);

View File

@@ -1,20 +0,0 @@
#define ALPHA_TYPE_PRE_MULTIPLIED 0U
#define ALPHA_TYPE_STRAIGHT 1U
vec4 convertAlpha(vec4 color, uint inType, uint outType) {
if (inType == ALPHA_TYPE_STRAIGHT && outType == ALPHA_TYPE_PRE_MULTIPLIED) {
return vec4(color.rgb * color.a, color.a);
} else if (inType == ALPHA_TYPE_PRE_MULTIPLIED && outType == ALPHA_TYPE_STRAIGHT && color.a > 0.0) {
return vec4(color.rgb / color.a, color.a);
} else return color;
}
#ifdef ALPHA_TYPE_SPEC_INDEX
layout (constant_id = ALPHA_TYPE_SPEC_INDEX ) const uint const_InAlphaType = ALPHA_TYPE_PRE_MULTIPLIED;
layout (constant_id = ALPHA_TYPE_SPEC_INDEX+1) const uint const_OutAlphaType = ALPHA_TYPE_PRE_MULTIPLIED;
vec4 convertAlpha(vec4 color) {
return convertAlpha(color, const_InAlphaType, const_OutAlphaType);
}
#endif

View File

@@ -1,7 +1,7 @@
#version 450
#extension GL_GOOGLE_include_directive: require
#define ALPHA_TYPE_SPEC_INDEX 0
#include "alpha_type.glsl"
#include "common.glsl"
DEFAULT_PUSH_CONSTANTS();
layout(set = 0, binding = 0) uniform texture2D u_Texture;
layout(set = 1, binding = 0) uniform sampler u_Sampler;
@@ -9,5 +9,5 @@ layout(location = 0) in vec2 in_TexCoord;
layout(location = 0) out vec4 out_Color;
void main() {
out_Color = convertAlpha(texture(sampler2D(u_Texture, u_Sampler), in_TexCoord));
out_Color = APPLY_COMPOSITE(convertAlpha(texture(sampler2D(u_Texture, u_Sampler), in_TexCoord)));
}

View File

@@ -1,14 +1,12 @@
#version 450
layout(push_constant) uniform PushConstants {
mat2x3 transform;
} push;
#extension GL_GOOGLE_include_directive: require
#include "common.glsl"
layout(location = 0) in vec2 in_Position;
layout(location = 1) in vec2 in_TexCoord;
layout(location = 0) out vec2 out_TexCoord;
void main() {
gl_Position = vec4(vec3(in_Position, 1.0)*push.transform, 0.0, 1.0);
gl_Position = transformToDeviceSpace(in_Position);
out_TexCoord = in_TexCoord;
}

View File

@@ -1,11 +1,9 @@
#version 450
layout(push_constant) uniform PushConstants {
mat2x3 transform;
} push;
#extension GL_GOOGLE_include_directive: require
#include "common.glsl"
layout(location = 0) in ivec2 in_Position;
void main() {
gl_Position = vec4(vec3(in_Position, 1)*push.transform, 0.0, 1.0);
gl_Position = transformToDeviceSpace(in_Position);
}

View File

@@ -1,14 +1,12 @@
#version 450
layout(push_constant) uniform PushConstants {
mat2x3 transform;
} push;
#extension GL_GOOGLE_include_directive: require
#include "common.glsl"
layout(location = 0) in vec2 in_Position;
layout(location = 1) in vec4 in_Color;
layout(location = 1) in uint in_Color;
layout(location = 0) out flat vec4 out_Color;
void main() {
gl_Position = vec4(vec3(in_Position, 1)*push.transform, 0.0, 1.0);
out_Color = in_Color;
gl_Position = transformToDeviceSpace(in_Position);
out_Color = convertAlpha(decodeColor(in_Color)); // No need to APPLY_COMPOSITE - it was already done on the host.
}

View File

@@ -0,0 +1,103 @@
// Shader specialization.
#define SHADER_MOD_XOR 1U // Xor composite mode
#define SHADER_MOD_MASK 2U // MASK_FILL / MASK_BLIT
layout (constant_id = 0) const uint const_InAlphaType = 0;
layout (constant_id = 1) const uint const_OutAlphaType = 0;
layout (constant_id = 2) const uint const_ShaderVariant = 0;
layout (constant_id = 3) const uint const_ShaderModifier = 0;
// Host structs.
struct VKTransform {
float m00, m01, m02;
float m10, m11, m12;
};
struct VKCompositeConstants {
uint xorColor;
float extraAlpha;
};
// Vertex shader transformation support.
#ifdef STAGE_VERT
layout(push_constant) uniform PushConstants { VKTransform transform; } push;
vec4 transformToDeviceSpace(vec2 v) {
return vec4(vec3(v, 1.0) * mat2x3(push.transform.m00, push.transform.m01, push.transform.m02, push.transform.m10, push.transform.m11, push.transform.m12), 0.0, 1.0);
}
#endif
// Fragment shader push constant support.
#ifdef STAGE_FRAG
#define PUSH_CONSTANTS_IMPL(STATEMENT) \
layout(push_constant) uniform PushConstants { VKTransform _; VKCompositeConstants push_composite; STATEMENT }
#define DEFAULT_PUSH_CONSTANTS() PUSH_CONSTANTS_IMPL(STAGE_FRAG)
#define PUSH_CONSTANTS(TYPE) PUSH_CONSTANTS_IMPL(TYPE push;)
#endif
// Color conversion support.
#define ALPHA_TYPE_PRE_MULTIPLIED 0U
#define ALPHA_TYPE_STRAIGHT 1U
vec4 convertAlpha(vec4 color, uint inType, uint outType) {
if (inType == ALPHA_TYPE_STRAIGHT && outType == ALPHA_TYPE_PRE_MULTIPLIED) {
return vec4(color.rgb * color.a, color.a);
} else if (inType == ALPHA_TYPE_PRE_MULTIPLIED && outType == ALPHA_TYPE_STRAIGHT && color.a > 0.0) {
return vec4(color.rgb / color.a, color.a);
} else return color;
}
vec4 convertAlpha(vec4 color) {
return convertAlpha(color, const_InAlphaType, const_OutAlphaType);
}
// When applying alpha to a color, straight alpha only multiplies alpha,
// and pre-multiplied multiplies the whole color. Use this for convenience.
vec4 alphaMask(float alpha, uint alphaType) {
return alphaType == ALPHA_TYPE_PRE_MULTIPLIED ? vec4(alpha) : vec4(1.0, 1.0, 1.0, alpha);
}
// Decode color from uint-packed ARGB components.
vec4 decodeColor(uint srgb) {
return vec4((uvec4(srgb) >> uvec4(16, 8, 0, 24)) & 0xFFU) / 255.0;
}
#ifdef STAGE_FRAG
// Before outputting the color, some post-processing is needed:
// - For alpha composite, apply extra alpha.
// - For XOR composite, apply xor.
vec4 applyComposite(vec4 color, VKCompositeConstants composite) {
if ((const_ShaderModifier & SHADER_MOD_XOR) != 0) {
uvec4 xor = uvec4(composite.xorColor) >> uvec4(16, 8, 0, 24);
xor = (uvec4(color * 255.0) ^ xor) & 0xFFU;
return vec4(xor) / 255.0;
} else return color * alphaMask(composite.extraAlpha, const_OutAlphaType);
}
#define APPLY_COMPOSITE(COLOR) applyComposite(COLOR, push_composite)
// MASK_FILL / MASK_BLIT support.
int calculateMaskIndex(vec2 localCoord, ivec4 originOffsetAndScanline) {
ivec2 maskPos = ivec2(localCoord - vec2(originOffsetAndScanline.xy));
int offset = originOffsetAndScanline.z;
int scanline = originOffsetAndScanline.w;
return offset + scanline * maskPos.y + min(scanline, maskPos.x);
}
vec4 applyMaskOp(vec4 color, float mask) {
if ((const_ShaderModifier & SHADER_MOD_XOR) != 0) return color * float(mask > 0.0);
else return color * alphaMask(mask, const_OutAlphaType);
}
#define APPLY_MASK(COLOR) applyMaskOp(COLOR, imageLoad(u_Mask, calculateMaskIndex(gl_FragCoord.xy, in_OriginOffsetAndScanline)).r)
// Generic shader support.
#define GENERIC_INOUT() \
layout(location = 0) out vec4 out_Color; \
layout(location = 0) in vec2 in_Position; \
layout(location = 1) in flat uint in_Data; \
layout(location = 2) in flat ivec4 in_OriginOffsetAndScanline; \
layout(origin_upper_left) in vec4 gl_FragCoord; \
layout(set = 0, binding = 0, r8) uniform readonly restrict imageBuffer u_Mask
// Generic color output - handles composite and mask automatically.
#define OUTPUT(COLOR) out_Color = COLOR; out_Color = APPLY_COMPOSITE(out_Color); \
if ((const_ShaderModifier & SHADER_MOD_MASK) != 0) out_Color = APPLY_MASK(out_Color)
#endif

View File

@@ -0,0 +1,21 @@
#version 450
#extension GL_GOOGLE_include_directive: require
#include "common.glsl"
#define SHADER_VARIANT_GRADIENT_CLAMP 0
#define SHADER_VARIANT_GRADIENT_CYCLE 1
struct VKGradientPaintConstants {
vec4 c0, c1;
vec3 p;
};
PUSH_CONSTANTS(VKGradientPaintConstants);
GENERIC_INOUT();
void main() {
float t = dot(vec3(in_Position, 1.0), push.p);
t = const_ShaderVariant == SHADER_VARIANT_GRADIENT_CYCLE ?
abs(mod(t + 1.0, 2.0) - 1.0) : // Cycle
clamp(t, 0.0, 1.0); // Clamp
OUTPUT(convertAlpha(mix(push.c0, push.c1, t)));
}

View File

@@ -0,0 +1,21 @@
#version 450
#extension GL_GOOGLE_include_directive: require
#include "common.glsl"
layout(location = 0) in ivec4 in_PositionOffsetAndScanline;
layout(location = 1) in uint in_Data;
layout(location = 0) out vec2 out_Position;
layout(location = 1) out uint out_Data;
// This starts with "Origin" and not "Position" intentionally.
// When drawing, vertices are ordered in a such way, that provoking vertex is always the top-left one.
// This gives us an easy way to calculate offset within the rectangle without additional inputs.
layout(location = 2) out flat ivec4 out_OriginOffsetAndScanline;
void main() {
out_Position = in_PositionOffsetAndScanline.xy;
out_Data = in_Data;
out_OriginOffsetAndScanline = in_PositionOffsetAndScanline;
gl_Position = transformToDeviceSpace(in_PositionOffsetAndScanline.xy);
}

View File

@@ -1,4 +1,6 @@
#version 450
#extension GL_GOOGLE_include_directive: require
#include "common.glsl"
layout(set = 0, binding = 0, r8) uniform readonly restrict imageBuffer u_Mask;
@@ -10,9 +12,5 @@ layout(location = 1) in flat vec4 in_Color;
layout(location = 0) out vec4 out_Color;
void main() {
ivec2 maskPos = ivec2(gl_FragCoord.xy - vec2(in_OriginOffsetAndScanline.xy));
int offset = in_OriginOffsetAndScanline.z;
int scanline = in_OriginOffsetAndScanline.w;
int maskIndex = offset + scanline * maskPos.y + min(scanline, maskPos.x);
out_Color = in_Color * imageLoad(u_Mask, maskIndex).r;
out_Color = APPLY_MASK(in_Color);
}

View File

@@ -1,11 +1,9 @@
#version 450
layout(push_constant) uniform PushConstants {
mat2x3 transform;
} push;
#extension GL_GOOGLE_include_directive: require
#include "common.glsl"
layout(location = 0) in ivec4 in_PositionOffsetAndScanline;
layout(location = 1) in vec4 in_Color;
layout(location = 1) in uint in_Color;
// This starts with "Origin" and not "Position" intentionally.
// When drawing, vertices are ordered in a such way, that provoking vertex is always the top-left one.
@@ -14,7 +12,7 @@ layout(location = 0) out flat ivec4 out_OriginOffsetAndScanline;
layout(location = 1) out flat vec4 out_Color;
void main() {
gl_Position = vec4(vec3(in_PositionOffsetAndScanline.xy, 1)*push.transform, 0.0, 1.0);
gl_Position = transformToDeviceSpace(in_PositionOffsetAndScanline.xy);
out_OriginOffsetAndScanline = in_PositionOffsetAndScanline;
out_Color = in_Color;
out_Color = convertAlpha(decodeColor(in_Color));
}

View File

@@ -0,0 +1,15 @@
#version 450
#extension GL_GOOGLE_include_directive: require
#include "common.glsl"
layout(location = 0) in vec2 in_Position;
layout(location = 1) in uint in_Data;
layout(location = 0) out vec2 out_Position;
layout(location = 1) out uint out_Data;
layout(location = 2) out flat ivec4 _; // Unused output
void main() {
out_Position = in_Position;
out_Data = in_Data;
gl_Position = transformToDeviceSpace(in_Position);
}

View File

@@ -63,7 +63,7 @@
#define TRACE_USE_API 0
#define TRACE_REUSE 0
#define INIT_TEST 1
#define INIT_TEST 0
#define INIT_TEST_STEP 1
#define INIT_TEST_MAX 1024

View File

@@ -113,7 +113,7 @@ void VKBlitLoops_IsoBlit(VKSDOps* srcOps, jint filter,
VK_COMPONENT_SWIZZLE_ONE);
VKPackedSwizzle swizzle = srcOpaque ? OPAQUE_SWIZZLE : 0;
if (!VKRenderer_Validate(SHADER_BLIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, alphaType)) return;
if (!VKRenderer_Validate(SHADER_BLIT, NO_SHADER_VARIANT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, alphaType)) return;
VKRenderer_DrawImage(srcOps->image, srcOps->image->format, swizzle, filter, SAMPLER_WRAP_BORDER,
(float)sx1, (float)sy1, (float)sx2, (float)sy2, (float)dx1, (float)dy1, (float)dx2, (float)dy2);
VKRenderer_AddSurfaceDependency(srcOps, context->surface);
@@ -154,7 +154,7 @@ void VKBlitLoops_Blit(JNIEnv *env, SurfaceDataOps* src, jshort srctype, jint fil
}
if (srcInfo.bounds.x2 > srcInfo.bounds.x1 && srcInfo.bounds.y2 > srcInfo.bounds.y1) {
src->GetRasInfo(env, src, &srcInfo);
if (srcInfo.rasBase) {
while (srcInfo.rasBase) {
if (srcInfo.bounds.x1 != sx1) dx1 += (srcInfo.bounds.x1 - sx1) * (dx2 - dx1) / (sx2 - sx1);
if (srcInfo.bounds.y1 != sy1) dy1 += (srcInfo.bounds.y1 - sy1) * (dy2 - dy1) / (sy2 - sy1);
if (srcInfo.bounds.x2 != sx2) dx2 += (srcInfo.bounds.x2 - sx2) * (dx2 - dx1) / (sx2 - sx1);
@@ -165,13 +165,17 @@ void VKBlitLoops_Blit(JNIEnv *env, SurfaceDataOps* src, jshort srctype, jint fil
// Need to validate render pass early, as image may not yet be configured.
AlphaType alphaType = getSrcAlphaType(srctype);
if (!VKRenderer_Validate(SHADER_BLIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, alphaType)) return;
if (!VKRenderer_Validate(SHADER_BLIT, NO_SHADER_VARIANT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, alphaType)) break;
VKDevice* device = context->surface->device;
BlitSrcType type = decodeSrcType(device, srctype);
VKTexturePoolHandle* imageHandle =
VKTexturePool_GetTexture(VKRenderer_GetTexturePool(device->renderer), sw, sh, type.format);
VKImage* image = VKTexturePoolHandle_GetTexture(imageHandle);
if (!image) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "VKBlitLoops_Blit: could not get texture from the pool");
break;
}
VkDeviceSize dataSize = sh * sw * srcInfo.pixelStride;
VKBuffer buffer;
@@ -232,7 +236,9 @@ void VKBlitLoops_Blit(JNIEnv *env, SurfaceDataOps* src, jshort srctype, jint fil
VKRenderer_ExecOnCleanup(context->surface, VKBlitLoops_DisposeTexture, imageHandle);
VKRenderer_ExecOnCleanup(context->surface, VKBlitLoops_DisposeBuffer, buffer.handle);
VKRenderer_ExecOnCleanup(context->surface, VKBlitLoops_DisposeMemory, page);
} else {
break;
}
if (!srcInfo.rasBase) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "VKBlitLoops_Blit: could not get raster info");
}
SurfaceData_InvokeRelease(env, src, &srcInfo);

View File

@@ -56,7 +56,7 @@ VKComposites VKComposites_Create() {
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT },
{ .logicOpEnable = VK_TRUE,
.logicOp = VK_LOGIC_OP_XOR }, ALPHA_TYPE_PRE_MULTIPLIED });
.logicOp = VK_LOGIC_OP_XOR }, ALPHA_TYPE_STRAIGHT });
// NAME | SRC_COLOR | DST_COLOR | SRC_ALPHA | DST_ALPHA ||
ALPHA_BLEND( CLEAR , ZERO , ZERO , ZERO , ZERO );
@@ -138,7 +138,6 @@ void VKComposites_AddState(VKComposites* composites, VKCompositeMode mode, VKCom
state.blendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
state.blendState.pNext = NULL;
state.blendState.attachmentCount = 1;
state.outAlphaType = ALPHA_TYPE_PRE_MULTIPLIED;
MAP_AT(composites->map, (VKCompositeDescriptor) { mode, VK_FALSE }) = state;
// Using pre-multiplied alpha is necessary for correct blending,

View File

@@ -49,6 +49,7 @@ static size_t pipelineDescriptorHash(const void* ptr) {
hash(&h, d->inAlphaType);
hash(&h, d->composite);
hash(&h, d->shader);
hash(&h, d->shaderVariant);
hash(&h, d->topology);
return (size_t) h;
}
@@ -59,6 +60,7 @@ static bool pipelineDescriptorEquals(const void* ap, const void* bp) {
a->inAlphaType == b->inAlphaType &&
a->composite == b->composite &&
a->shader == b->shader &&
a->shaderVariant == b->shaderVariant &&
a->topology == b->topology;
}
@@ -144,12 +146,20 @@ static VKPipelineInfo VKPipelines_CreatePipelines(VKRenderPassContext* renderPas
VkPipelineShaderStageCreateInfo createInfos[2]; // vert + frag
} ShaderStages;
ShaderStages stages[count];
typedef struct {
uint32_t inAlphaType, outAlphaType, shaderVariant, shaderModifier;
} SpecializationData;
const VkSpecializationMapEntry SPECIALIZATION_ENTRIES[] = {
{ 0, 0, 4 },
{ 1, 4, 4 },
{ 2, 8, 4 },
{ 3, 12, 4 }
};
typedef struct {
VkSpecializationInfo info;
VkSpecializationMapEntry entries[2];
uint64_t data[1];
SpecializationData data;
} Specialization;
Specialization specializations[count][2];
Specialization specializations[count];
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStates[count];
VkPipelineDepthStencilStateCreateInfo depthStencilStates[count];
VkPipelineDynamicStateCreateInfo dynamicStates[count];
@@ -163,14 +173,19 @@ static VKPipelineInfo VKPipelines_CreatePipelines(VKRenderPassContext* renderPas
// - pStages (but stageCount is set to 2)
// - pVertexInputState
// - createInfo.layout
for (uint32_t j = 0; j < SARRAY_COUNT_OF(specializations[i]); j++) {
specializations[i][j].info = (VkSpecializationInfo) {
.mapEntryCount = 0,
.pMapEntries = specializations[i][j].entries,
.dataSize = 0,
.pData = specializations[i][j].data
};
}
specializations[i] = (Specialization) {
.info = {
.mapEntryCount = SARRAY_COUNT_OF(SPECIALIZATION_ENTRIES),
.pMapEntries = SPECIALIZATION_ENTRIES,
.dataSize = sizeof(SpecializationData),
.pData = &specializations[i].data
},
.data = {
descriptors[i].inAlphaType, pipelineInfos[i].outAlphaType, (uint32_t) descriptors[i].shaderVariant,
(descriptors[i].composite == LOGIC_COMPOSITE_XOR ? 1 : 0) |
(descriptors[i].shader & SHADER_MASK ? 2 : 0)
}
};
inputAssemblyStates[i] = (VkPipelineInputAssemblyStateCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = descriptors[i].topology
@@ -234,37 +249,38 @@ static VKPipelineInfo VKPipelines_CreatePipelines(VKRenderPassContext* renderPas
}
// Setup input states.
MAKE_INPUT_STATE(COLOR, VKColorVertex, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT);
MAKE_INPUT_STATE(MASK_FILL_COLOR, VKMaskFillColorVertex, VK_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SFLOAT);
MAKE_INPUT_STATE(PRIMITIVE, VKVertex, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32_UINT);
MAKE_INPUT_STATE(MASK_FILL, VKMaskFillVertex, VK_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32_UINT);
MAKE_INPUT_STATE(BLIT, VKTxVertex, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32_SFLOAT);
MAKE_INPUT_STATE(CLIP, VKIntVertex, VK_FORMAT_R32G32_SINT);
for (uint32_t i = 0; i < count; i++) {
// Setup shader-specific pipeline parameters.
switch (descriptors[i].shader) {
switch ((int) descriptors[i].shader) {
case SHADER_COLOR:
createInfos[i].pVertexInputState = &INPUT_STATE_COLOR;
createInfos[i].layout = pipelineContext->colorPipelineLayout;
createInfos[i].pVertexInputState = &INPUT_STATE_PRIMITIVE;
createInfos[i].layout = pipelineContext->commonPipelineLayout;
stages[i] = (ShaderStages) {{ shaders->color_vert, shaders->color_frag }};
break;
case SHADER_MASK_FILL_COLOR:
createInfos[i].pVertexInputState = &INPUT_STATE_MASK_FILL_COLOR;
case SHADER_COLOR | SHADER_MASK:
createInfos[i].pVertexInputState = &INPUT_STATE_MASK_FILL;
createInfos[i].layout = pipelineContext->maskFillPipelineLayout;
stages[i] = (ShaderStages) {{ shaders->mask_fill_color_vert, shaders->mask_fill_color_frag }};
break;
case SHADER_GRADIENT:
createInfos[i].pVertexInputState = &INPUT_STATE_PRIMITIVE;
createInfos[i].layout = pipelineContext->maskFillPipelineLayout;
stages[i] = (ShaderStages) {{ shaders->primitive_vert, shaders->gradient_frag }};
break;
case SHADER_GRADIENT | SHADER_MASK:
createInfos[i].pVertexInputState = &INPUT_STATE_MASK_FILL;
createInfos[i].layout = pipelineContext->maskFillPipelineLayout;
stages[i] = (ShaderStages) {{ shaders->mask_fill_vert, shaders->gradient_frag }};
break;
case SHADER_BLIT:
createInfos[i].pVertexInputState = &INPUT_STATE_BLIT;
createInfos[i].layout = pipelineContext->texturePipelineLayout;
stages[i] = (ShaderStages) {{ shaders->blit_vert, shaders->blit_frag }};
// Alpha conversion specialization.
uint32_t* spec = (uint32_t*) specializations[i][1].data;
spec[0] = descriptors[i].inAlphaType;
spec[1] = pipelineInfos[i].outAlphaType;
specializations[i][1].info.dataSize = 8;
specializations[i][1].entries[0] = (VkSpecializationMapEntry) { 0, 0, 4 };
specializations[i][1].entries[1] = (VkSpecializationMapEntry) { 1, 4, 4 };
specializations[i][1].info.mapEntryCount = 2;
stages[i].createInfos[1].pSpecializationInfo = &specializations[i][1].info;
break;
case SHADER_CLIP:
createInfos[i].pVertexInputState = &INPUT_STATE_CLIP;
@@ -290,6 +306,9 @@ static VKPipelineInfo VKPipelines_CreatePipelines(VKRenderPassContext* renderPas
default:
VK_FATAL_ERROR("Cannot create pipeline, unknown shader requested!");
}
for (uint32_t j = 0; j < createInfos[i].stageCount; j++) {
stages[i].createInfos[j].pSpecializationInfo = &specializations[i].info;
}
assert(createInfos[i].pDynamicState->dynamicStateCount <= MAX_DYNAMIC_STATES);
J2dRlsTraceLn(J2D_TRACE_INFO, "VKPipelines_CreatePipelines: stencilMode=%d, dstOpaque=%d, composite=%d, shader=%d, topology=%d",
descriptors[i].stencilMode, descriptors[i].dstOpaque, descriptors[i].composite, descriptors[i].shader, descriptors[i].topology);
@@ -303,6 +322,7 @@ static VKPipelineInfo VKPipelines_CreatePipelines(VKRenderPassContext* renderPas
J2dRlsTraceLn(J2D_TRACE_INFO, "VKPipelines_CreatePipelines: created %d pipelines", count);
for (uint32_t i = 0; i < count; i++) {
pipelineInfos[i].pipeline = pipelines[i];
pipelineInfos[i].layout = createInfos[i].layout;
MAP_AT(renderPassContext->pipelines, descriptors[i]) = pipelineInfos[i];
}
return pipelineInfos[0];
@@ -403,21 +423,49 @@ static VkResult VKPipelines_InitPipelineLayouts(VKDevice* device, VKPipelineCont
assert(device != NULL && pipelines != NULL);
VkResult result;
// We want all our pipelines to have same push constant range to ensure common state is compatible between pipelines.
VkPushConstantRange pushConstantRange = {
// We want all our pipelines to have the same push constant ranges to ensure a common state is compatible between pipelines.
VkPushConstantRange pushConstantRanges[] = {{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = 0,
.size = sizeof(VKTransform)
};
}, {
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.offset = PUSH_CONSTANTS_OFFSET,
.size = PUSH_CONSTANTS_SIZE
}};
// Common pipeline.
VkPipelineLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 0,
.pushConstantRangeCount = 1,
.pPushConstantRanges = &pushConstantRange
.pushConstantRangeCount = SARRAY_COUNT_OF(pushConstantRanges),
.pPushConstantRanges = pushConstantRanges
};
result = device->vkCreatePipelineLayout(device->handle, &createInfo, NULL, &pipelines->colorPipelineLayout);
result = device->vkCreatePipelineLayout(device->handle, &createInfo, NULL, &pipelines->commonPipelineLayout);
VK_IF_ERROR(result) return result;
// Mask fill pipeline.
VkDescriptorSetLayoutBinding maskBufferLayoutBinding = {
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.pImmutableSamplers = NULL
};
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1,
.pBindings = &maskBufferLayoutBinding
};
result = device->vkCreateDescriptorSetLayout(device->handle, &descriptorSetLayoutCreateInfo, NULL, &pipelines->maskFillDescriptorSetLayout);
VK_IF_ERROR(result) return result;
createInfo.setLayoutCount = 1;
createInfo.pSetLayouts = &pipelines->maskFillDescriptorSetLayout;
result = device->vkCreatePipelineLayout(device->handle, &createInfo, NULL, &pipelines->maskFillPipelineLayout);
VK_IF_ERROR(result) return result;
// Texture pipeline.
VkDescriptorSetLayoutBinding textureLayoutBinding = {
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
@@ -437,31 +485,11 @@ static VkResult VKPipelines_InitPipelineLayouts(VKDevice* device, VKPipelineCont
pipelines->textureDescriptorSetLayout,
pipelines->samplers.descriptorSetLayout
};
createInfo.setLayoutCount = 2;
createInfo.setLayoutCount = SARRAY_COUNT_OF(textureDescriptorSetLayouts);
createInfo.pSetLayouts = textureDescriptorSetLayouts;
result = device->vkCreatePipelineLayout(device->handle, &createInfo, NULL, &pipelines->texturePipelineLayout);
VK_IF_ERROR(result) return result;
VkDescriptorSetLayoutBinding maskBufferLayoutBinding = {
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.pImmutableSamplers = NULL
};
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1,
.pBindings = &maskBufferLayoutBinding
};
result = device->vkCreateDescriptorSetLayout(device->handle, &descriptorSetLayoutCreateInfo, NULL, &pipelines->maskFillDescriptorSetLayout);
VK_IF_ERROR(result) return result;
createInfo.setLayoutCount = 1;
createInfo.pSetLayouts = &pipelines->maskFillDescriptorSetLayout;
result = device->vkCreatePipelineLayout(device->handle, &createInfo, NULL, &pipelines->maskFillPipelineLayout);
VK_IF_ERROR(result) return result;
return VK_SUCCESS;
}
@@ -504,7 +532,7 @@ void VKPipelines_DestroyContext(VKPipelineContext* pipelineContext) {
VKPipelines_DestroyShaders(device, pipelineContext->shaders);
device->vkDestroyPipelineLayout(device->handle, pipelineContext->colorPipelineLayout, NULL);
device->vkDestroyPipelineLayout(device->handle, pipelineContext->commonPipelineLayout, NULL);
device->vkDestroyPipelineLayout(device->handle, pipelineContext->texturePipelineLayout, NULL);
device->vkDestroyDescriptorSetLayout(device->handle, pipelineContext->textureDescriptorSetLayout, NULL);
device->vkDestroyPipelineLayout(device->handle, pipelineContext->maskFillPipelineLayout, NULL);

View File

@@ -36,13 +36,26 @@
* Shader programs.
*/
typedef enum {
// Base shaders.
SHADER_COLOR,
SHADER_MASK_FILL_COLOR,
SHADER_GRADIENT,
SHADER_BLIT,
SHADER_CLIP,
NO_SHADER = 0x7FFFFFFF
NO_SHADER = 0x7FFFFFFF,
// Mask modifier bit (MASK_FILL & MASK_BLIT).
SHADER_MASK = ~NO_SHADER
} VKShader;
/**
* Shader variant.
* It is used to specialize shader behavior, and its meaning varies with each particular shader.
*/
typedef enum {
SHADER_VARIANT_GRADIENT_CLAMP = 0,
SHADER_VARIANT_GRADIENT_CYCLE = 1,
NO_SHADER_VARIANT = 0x7FFFFFFF
} VKShaderVariant;
typedef enum {
STENCIL_MODE_NONE = 0, // No stencil attachment.
STENCIL_MODE_OFF = 1, // Has stencil attachment, stencil test disabled.
@@ -59,12 +72,14 @@ typedef struct {
AlphaType inAlphaType : 1;
VKCompositeMode composite;
VKShader shader;
VKShaderVariant shaderVariant;
VkPrimitiveTopology topology;
} VKPipelineDescriptor;
typedef struct {
VkPipeline pipeline;
AlphaType outAlphaType;
VkPipeline pipeline;
VkPipelineLayout layout;
AlphaType outAlphaType;
} VKPipelineInfo;
/**
@@ -72,7 +87,7 @@ typedef struct {
*/
struct VKPipelineContext {
VKDevice* device;
VkPipelineLayout colorPipelineLayout;
VkPipelineLayout commonPipelineLayout;
VkDescriptorSetLayout textureDescriptorSetLayout;
VkPipelineLayout texturePipelineLayout;
VkDescriptorSetLayout maskFillDescriptorSetLayout;
@@ -93,14 +108,42 @@ struct VKRenderPassContext {
MAP(VKPipelineDescriptor, VKPipelineInfo) pipelines;
};
typedef struct {
unsigned int xorColor;
float extraAlpha;
} VKCompositeConstants;
typedef struct {
RGBA c0, c1;
float p0, p1, p3;
} VKGradientPaintConstants;
typedef union {
// The minimum guaranteed size of push constants is 128 bytes.
alignas(32) // The maximum alignment for built-in glsl types is 32 bytes (dvec4).
char data[(128 - sizeof(VKTransform) - sizeof(VKCompositeConstants)) / 32 * 32];
VKGradientPaintConstants gradientPaint;
} VKShaderConstants;
#define MAX_SHADER_CONSTANTS_SIZE 96 // We expect 96 bytes
typedef char VKShaderConstantsCheckOffset[sizeof(VKShaderConstants) == MAX_SHADER_CONSTANTS_SIZE ? 1 : -1]; // Verify.
typedef struct {
VKTransform transform;
VKCompositeConstants composite;
VKShaderConstants shader;
} VKPushConstants;
typedef char VKPushConstantsCheckSize[sizeof(VKPushConstants) <= 128 ? 1 : -1]; // We should not exceed 128 bytes.
static const uint32_t PUSH_CONSTANTS_OFFSET = (uintptr_t) &((VKPushConstants*) NULL)->composite;
static const uint32_t PUSH_CONSTANTS_SIZE = sizeof(VKPushConstants) - PUSH_CONSTANTS_OFFSET;
typedef struct {
int x, y;
} VKIntVertex;
typedef struct {
float x, y;
RGBA color;
} VKColorVertex;
unsigned int data;
} VKVertex;
typedef struct {
float px, py;
@@ -109,8 +152,8 @@ typedef struct {
typedef struct {
int x, y, maskOffset, maskScanline;
RGBA color;
} VKMaskFillColorVertex;
unsigned int data;
} VKMaskFillVertex;
VKPipelineContext* VKPipelines_CreateContext(VKDevice* device);
void VKPipelines_DestroyContext(VKPipelineContext* pipelines);

View File

@@ -93,6 +93,21 @@
#define OFFSET_XFORM sun_java2d_vulkan_VKBlitLoops_OFFSET_XFORM
#define OFFSET_ISOBLIT sun_java2d_vulkan_VKBlitLoops_OFFSET_ISOBLIT
static void applyXor() {
if (VKRenderer_GetContext()->shader == SHADER_COLOR) {
VKRenderer_GetContext()->vertexData ^= VKRenderer_GetContext()->constants.composite.xorColor;
}
}
static void setComposite(VKCompositeMode comp, unsigned int xorColor, float extraAlpha) {
VKRenderer_GetContext()->composite = comp;
if (VKRenderer_GetContext()->constants.composite.xorColor != xorColor ||
VKRenderer_GetContext()->constants.composite.extraAlpha != extraAlpha) {
VKRenderer_GetContext()->constants.composite = (VKCompositeConstants) { xorColor, extraAlpha };
VKRenderer_GetContext()->constantsModCount++;
}
}
JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
(JNIEnv *env, jobject oglrq, jlong buf, jint limit)
{
@@ -476,30 +491,26 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint flags = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_ALPHA_COMPOSITE(%d, %f, %d)", rule, extraAlpha, flags);
VKRenderer_GetContext()->renderColor = VKRenderer_GetContext()->color;
VKRenderer_GetContext()->composite = (VKCompositeMode) rule;
VKRenderer_GetContext()->extraAlpha = extraAlpha;
applyXor();
setComposite((VKCompositeMode) rule, 0, extraAlpha);
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:
{
jint xorPixel = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_XOR_COMPOSITE");
VKRenderer_GetContext()->renderColor = VKUtil_DecodeJavaColor(xorPixel, ALPHA_TYPE_STRAIGHT);
// TODO Fix XOR mode!
// VKRenderer_GetContext()->renderColor.a = 0.0f; // Alpha is left unchanged in XOR mode.
VKRenderer_GetContext()->composite = LOGIC_COMPOSITE_XOR;
VKRenderer_GetContext()->extraAlpha = 1.0f;
"VKRenderQueue_flushBuffer: SET_XOR_COMPOSITE(0x%08x)", xorPixel);
applyXor();
setComposite(LOGIC_COMPOSITE_XOR, xorPixel, -1.0f);
applyXor();
}
break;
case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_COMPOSITE");
VKRenderer_GetContext()->renderColor = VKRenderer_GetContext()->color;
VKRenderer_GetContext()->composite = ALPHA_COMPOSITE_SRC;
VKRenderer_GetContext()->extraAlpha = 1.0f;
applyXor();
setComposite(ALPHA_COMPOSITE_SRC, 0, 1.0f);
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM:
@@ -522,8 +533,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
};
VKRenderingContext* context = VKRenderer_GetContext();
if (VK_IS_NEQ_TRANSFORM(&context->transform, &transform)) {
context->transform = transform;
if (VK_IS_NEQ_TRANSFORM(&context->constants.transform, &transform)) {
context->constants.transform = transform;
context->transformModCount++;
}
}
@@ -533,8 +544,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_TRANSFORM");
VKRenderingContext* context = VKRenderer_GetContext();
if (VK_IS_NEQ_TRANSFORM(&context->transform, &VK_ID_TRANSFORM)) {
context->transform = VK_ID_TRANSFORM;
if (VK_IS_NEQ_TRANSFORM(&context->constants.transform, &VK_ID_TRANSFORM)) {
context->constants.transform = VK_ID_TRANSFORM;
context->transformModCount++;
}
}
@@ -568,9 +579,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
break;
case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:
{
jlong pData = NEXT_LONG(b);
VKSDOps* surface = NEXT_VK_SURFACE(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISPOSE_SURFACE");
VKSD_ResetSurface(surface);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:
@@ -643,31 +655,34 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
break;
case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
{
jint javaColor = NEXT_INT(b);
VKRenderer_GetContext()->color = VKUtil_DecodeJavaColor(javaColor, ALPHA_TYPE_STRAIGHT);
if (COMPOSITE_GROUP(VKRenderer_GetContext()->composite) == ALPHA_COMPOSITE_GROUP) {
VKRenderer_GetContext()->renderColor = VKRenderer_GetContext()->color;
}
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: SET_COLOR(0x%08x)", javaColor);
J2dTraceLn(J2D_TRACE_VERBOSE, // Print color values with straight alpha for convenience.
" srgb={%.3f, %.3f, %.3f, %.3f}",
VKUtil_GetRGBA(VKRenderer_GetContext()->color, ALPHA_TYPE_STRAIGHT).r,
VKUtil_GetRGBA(VKRenderer_GetContext()->color, ALPHA_TYPE_STRAIGHT).g,
VKUtil_GetRGBA(VKRenderer_GetContext()->color, ALPHA_TYPE_STRAIGHT).b,
VKUtil_GetRGBA(VKRenderer_GetContext()->color, ALPHA_TYPE_STRAIGHT).a);
VKRenderer_GetContext()->inAlphaType = ALPHA_TYPE_STRAIGHT;
VKRenderer_GetContext()->shader = SHADER_COLOR;
VKRenderer_GetContext()->shaderVariant = NO_SHADER_VARIANT;
VKRenderer_GetContext()->vertexData = NEXT_INT(b);
applyXor();
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: SET_COLOR(0x%08x)", VKRenderer_GetContext()->vertexData);
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:
{
jboolean useMask= NEXT_BOOLEAN(b);
jboolean cyclic = NEXT_BOOLEAN(b);
jdouble p0 = NEXT_DOUBLE(b);
jdouble p1 = NEXT_DOUBLE(b);
jdouble p3 = NEXT_DOUBLE(b);
jint pixel1 = NEXT_INT(b);
jint pixel2 = NEXT_INT(b);
jboolean useMask = NEXT_BOOLEAN(b); // Unused.
jboolean cyclic = NEXT_BOOLEAN(b);
jdouble p0 = NEXT_DOUBLE(b);
jdouble p1 = NEXT_DOUBLE(b);
jdouble p3 = NEXT_DOUBLE(b);
jint pixel1 = NEXT_INT(b);
jint pixel2 = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_GRADIENT_PAINT");
VKRenderer_GetContext()->inAlphaType = ALPHA_TYPE_PRE_MULTIPLIED;
VKRenderer_GetContext()->shader = SHADER_GRADIENT;
VKRenderer_GetContext()->shaderVariant = cyclic ? SHADER_VARIANT_GRADIENT_CYCLE : SHADER_VARIANT_GRADIENT_CLAMP;
VKRenderer_GetContext()->constants.shader.gradientPaint = (VKGradientPaintConstants) {
VKUtil_GetRGBA(VKUtil_DecodeJavaColor(pixel1, ALPHA_TYPE_PRE_MULTIPLIED), ALPHA_TYPE_PRE_MULTIPLIED),
VKUtil_GetRGBA(VKUtil_DecodeJavaColor(pixel2, ALPHA_TYPE_PRE_MULTIPLIED), ALPHA_TYPE_PRE_MULTIPLIED),
p0*2.0, p1*2.0, p3*2.0-0.5
};
VKRenderer_GetContext()->constantsModCount++;
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:

View File

@@ -164,6 +164,7 @@ struct VKRenderPass {
BufferWritingState maskFillBufferWriting;
VKPipelineDescriptor state;
uint64_t constantsModCount; // Just a tag to detect when constants were changed.
uint64_t transformModCount; // Just a tag to detect when transform was changed.
uint64_t clipModCount; // Just a tag to detect when clip was changed.
VkBool32 pendingFlush : 1;
@@ -176,12 +177,17 @@ struct VKRenderPass {
// which is only called from queue flusher thread, no need for synchronization.
static VKRenderingContext context = {
.surface = NULL,
.transform = VK_ID_TRANSFORM,
.transformModCount = 1,
.color = {},
.renderColor = {},
.composite = ALPHA_COMPOSITE_SRC_OVER,
.extraAlpha = 1.0f,
.inAlphaType = ALPHA_TYPE_UNKNOWN,
.shader = NO_SHADER,
.shaderVariant = NO_SHADER_VARIANT,
.vertexData = 0,
.constantsModCount = 1,
.transformModCount = 1,
.constants = {
.transform = VK_ID_TRANSFORM,
.composite = { 0, 1.0f }
},
.clipModCount = 1,
.clipRect = NO_CLIP,
.clipSpanVertices = NULL
@@ -221,7 +227,7 @@ static VkBool32 VKRenderer_CheckPoolDrain(void* pool, void* entry) {
return VK_FALSE;
}
#define VERTEX_BUFFER_SIZE (128 * 1024) // 128KiB - enough to draw 910 quads (6 verts) with VKColorVertex.
#define VERTEX_BUFFER_SIZE (128 * 1024) // 128KiB - enough to draw 1820 quads (6 verts) with VKVertex.
#define VERTEX_BUFFER_PAGE_SIZE (1 * 1024 * 1024) // 1MiB - fits 8 buffers.
static void VKRenderer_FindVertexBufferMemoryType(VKMemoryRequirements* requirements) {
VKAllocator_FindMemoryType(requirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
@@ -597,33 +603,47 @@ inline void VKRenderer_FlushDraw(VKSDOps* surface) {
static void VKRenderer_ResetDrawing(VKSDOps* surface) {
assert(surface != NULL && surface->renderPass != NULL);
VKRenderer* renderer = surface->device->renderer;
surface->renderPass->state.composite = NO_COMPOSITE;
surface->renderPass->state.shader = NO_SHADER;
surface->renderPass->transformModCount = 0;
surface->renderPass->firstVertex = 0;
surface->renderPass->vertexCount = 0;
surface->renderPass->vertexBufferWriting = (BufferWritingState) {NULL, 0, VK_FALSE};
surface->renderPass->maskFillBufferWriting = (BufferWritingState) {NULL, 0, VK_FALSE};
if (ARRAY_SIZE(surface->renderPass->flushRanges) > 0) {
VKRenderPass* renderPass = surface->renderPass;
renderPass->state.composite = NO_COMPOSITE;
renderPass->state.shader = NO_SHADER;
renderPass->constantsModCount = 0;
renderPass->transformModCount = 0;
renderPass->firstVertex = 0;
renderPass->vertexCount = 0;
renderPass->vertexBufferWriting = (BufferWritingState) { NULL, 0, VK_FALSE };
renderPass->maskFillBufferWriting = (BufferWritingState) { NULL, 0, VK_FALSE };
if (ARRAY_SIZE(renderPass->flushRanges) > 0) {
VK_IF_ERROR(surface->device->vkFlushMappedMemoryRanges(surface->device->handle,
ARRAY_SIZE(surface->renderPass->flushRanges), surface->renderPass->flushRanges)) {}
ARRAY_RESIZE(surface->renderPass->flushRanges, 0);
ARRAY_SIZE(renderPass->flushRanges), renderPass->flushRanges)) {}
ARRAY_RESIZE(renderPass->flushRanges, 0);
}
size_t vertexBufferCount = ARRAY_SIZE(surface->renderPass->vertexBuffers);
size_t maskFillBufferCount = ARRAY_SIZE(surface->renderPass->maskFillBuffers);
size_t cleanupQueueCount = ARRAY_SIZE(surface->renderPass->cleanupQueue);
size_t vertexBufferCount = ARRAY_SIZE(renderPass->vertexBuffers);
size_t maskFillBufferCount = ARRAY_SIZE(renderPass->maskFillBuffers);
size_t cleanupQueueCount = ARRAY_SIZE(renderPass->cleanupQueue);
for (uint32_t i = 0; i < vertexBufferCount; i++) {
POOL_RETURN(surface->device->renderer, vertexBufferPool, surface->renderPass->vertexBuffers[i]);
POOL_RETURN(renderer, vertexBufferPool, renderPass->vertexBuffers[i]);
}
for (uint32_t i = 0; i < maskFillBufferCount; i++) {
POOL_RETURN(surface->device->renderer, maskFillBufferPool, surface->renderPass->maskFillBuffers[i]);
POOL_RETURN(renderer, maskFillBufferPool, renderPass->maskFillBuffers[i]);
}
for (uint32_t i = 0; i < cleanupQueueCount; i++) {
POOL_RETURN(surface->device->renderer, cleanupQueue, surface->renderPass->cleanupQueue[i]);
POOL_RETURN(renderer, cleanupQueue, renderPass->cleanupQueue[i]);
}
ARRAY_RESIZE(surface->renderPass->vertexBuffers, 0);
ARRAY_RESIZE(surface->renderPass->maskFillBuffers, 0);
ARRAY_RESIZE(surface->renderPass->cleanupQueue, 0);
ARRAY_RESIZE(renderPass->vertexBuffers, 0);
ARRAY_RESIZE(renderPass->maskFillBuffers, 0);
ARRAY_RESIZE(renderPass->cleanupQueue, 0);
// Update dependencies on used surfaces.
for (uint32_t i = 0, surfaces = (uint32_t) ARRAY_SIZE(renderPass->usedSurfaces); i < surfaces; i++) {
VKSDOps* usedSurface = renderPass->usedSurfaces[i];
uint32_t newSize = 0, oldSize = (uint32_t) ARRAY_SIZE(usedSurface->dependentSurfaces);
for (uint32_t j = 0; j < oldSize; j++) {
VKSDOps* s = usedSurface->dependentSurfaces[j];
if (s != surface) usedSurface->dependentSurfaces[newSize++] = s;
}
if (newSize != oldSize) ARRAY_RESIZE(usedSurface->dependentSurfaces, newSize);
}
ARRAY_RESIZE(renderPass->usedSurfaces, 0);
}
/**
@@ -711,6 +731,7 @@ static VkBool32 VKRenderer_InitRenderPass(VKSDOps* surface) {
.composite = NO_COMPOSITE,
.shader = NO_SHADER
},
.constantsModCount = 0,
.transformModCount = 0,
.clipModCount = 0,
.pendingFlush = VK_FALSE,
@@ -877,19 +898,11 @@ VkBool32 VKRenderer_FlushRenderPass(VKSDOps* surface) {
VKRenderer* renderer = device->renderer;
VkCommandBuffer cb = VKRenderer_Record(renderer);
// Update dependencies on used surfaces.
// Update timestamps on used surfaces.
surface->lastTimestamp = renderer->writeTimestamp;
for (uint32_t i = 0, surfaces = (uint32_t) ARRAY_SIZE(surface->renderPass->usedSurfaces); i < surfaces; i++) {
VKSDOps* usedSurface = surface->renderPass->usedSurfaces[i];
usedSurface->lastTimestamp = renderer->writeTimestamp;
uint32_t newSize = 0, oldSize = (uint32_t) ARRAY_SIZE(usedSurface->dependentSurfaces);
for (uint32_t j = 0; j < oldSize; j++) {
VKSDOps* s = usedSurface->dependentSurfaces[j];
if (s != surface) usedSurface->dependentSurfaces[newSize++] = s;
}
if (newSize != oldSize) ARRAY_RESIZE(usedSurface->dependentSurfaces, newSize);
surface->renderPass->usedSurfaces[i]->lastTimestamp = renderer->writeTimestamp;
}
ARRAY_RESIZE(surface->renderPass->usedSurfaces, 0);
// Insert barriers to prepare surface for rendering.
VkImageMemoryBarrier barriers[2];
@@ -963,9 +976,12 @@ void VKRenderer_FlushSurface(VKSDOps* surface) {
uint32_t imageIndex;
VkResult acquireImageResult = device->vkAcquireNextImageKHR(device->handle, win->swapchain, UINT64_MAX,
acquireSemaphore, VK_NULL_HANDLE, &imageIndex);
if (acquireImageResult != VK_SUCCESS) {
// TODO possible suboptimal conditions
VK_IF_ERROR(acquireImageResult) {}
if (acquireImageResult != VK_SUCCESS && acquireImageResult != VK_SUBOPTIMAL_KHR) {
VK_IF_ERROR(acquireImageResult) {
// Failed, try again later.
surface->renderPass->pendingFlush = VK_TRUE;
return;
}
}
// Insert barriers to prepare both main (src) and swapchain (dst) images for blit.
@@ -1122,7 +1138,7 @@ static uint32_t VKRenderer_AllocateVertices(uint32_t primitives, uint32_t vertic
* This function can invalidate drawing state, always call it before VK_DRAW.
*/
static BufferWritingState VKRenderer_AllocateMaskFillBytes(uint32_t size) {
assert(size > 0);
// assert(size > 0); // size can be 0 when binding the buffer without allocating any data.
assert(size <= MASK_FILL_BUFFER_SIZE);
VKSDOps* surface = VKRenderer_GetContext()->surface;
BufferWritingState state = VKRenderer_AllocateBufferData(
@@ -1158,16 +1174,35 @@ static void VKRenderer_ValidateTransform() {
0.0f, 2.0f / (float) surface->image->extent.height, -1.0f
};
// Combine it with user transform.
VKUtil_ConcatenateTransform(&transform, &context->transform);
VKUtil_ConcatenateTransform(&transform, &context->constants.transform);
// Push the transform into shader.
surface->device->vkCmdPushConstants(
renderPass->commandBuffer,
surface->device->renderer->pipelineContext->colorPipelineLayout, // TODO what if our pipeline layout differs?
surface->device->renderer->pipelineContext->commonPipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VKTransform), &transform
);
}
}
static void VKRenderer_ValidateConstants() {
VKRenderingContext* context = VKRenderer_GetContext();
assert(context->surface != NULL);
VKSDOps* surface = context->surface;
VKRenderPass* renderPass = surface->renderPass;
// Update constants, ignoring clip and color shaders.
if (renderPass->constantsModCount != context->constantsModCount &&
renderPass->state.shader != SHADER_CLIP && renderPass->state.shader != SHADER_COLOR) {
J2dTraceLn(J2D_TRACE_VERBOSE, "VKRenderer_ValidateConstants: updating constants");
VKRenderer_FlushDraw(surface);
renderPass->constantsModCount = context->constantsModCount;
surface->device->vkCmdPushConstants(
renderPass->commandBuffer,
surface->device->renderer->pipelineContext->commonPipelineLayout,
VK_SHADER_STAGE_FRAGMENT_BIT, PUSH_CONSTANTS_OFFSET, PUSH_CONSTANTS_SIZE, &context->constants.composite
);
}
}
/**
* Setup stencil attachment according to the context clip state.
* If there is a clip shape, attachment is cleared with "fail" value and then
@@ -1204,6 +1239,7 @@ static void VKRenderer_SetupStencil() {
.inAlphaType = ALPHA_TYPE_UNKNOWN,
.composite = NO_COMPOSITE,
.shader = SHADER_CLIP,
.shaderVariant = NO_SHADER_VARIANT,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
}).pipeline);
// Reset vertex buffer binding.
@@ -1248,7 +1284,7 @@ void VKRenderer_RecordBarriers(VKRenderer* renderer,
/**
* Setup pipeline for drawing. Returns FALSE if surface is not yet ready for drawing.
*/
VkBool32 VKRenderer_Validate(VKShader shader, VkPrimitiveTopology topology, AlphaType inAlphaType) {
VkBool32 VKRenderer_Validate(VKShader shader, VKShaderVariant shaderVariant, VkPrimitiveTopology topology, AlphaType inAlphaType) {
assert(context.surface != NULL);
VKSDOps* surface = context.surface;
@@ -1290,10 +1326,18 @@ VkBool32 VKRenderer_Validate(VKShader shader, VkPrimitiveTopology topology, Alph
J2dTraceLn(J2D_TRACE_VERBOSE, "VKRenderer_Validate: updating clip");
surface->device->vkCmdSetScissor(renderPass->commandBuffer, 0, 1, &context.clipRect);
if (clipChanged) {
VKStencilMode stencilMode = STENCIL_MODE_NONE;
if (ARRAY_SIZE(context.clipSpanVertices) > 0) {
VKRenderer_SetupStencil();
renderPass->state.stencilMode = STENCIL_MODE_ON;
} else renderPass->state.stencilMode = surface->stencil != NULL ? STENCIL_MODE_OFF : STENCIL_MODE_NONE;
stencilMode = STENCIL_MODE_ON;
} else if (surface->stencil != NULL) {
stencilMode = STENCIL_MODE_OFF;
}
// Reset the pipeline when changing stencil mode.
if (renderPass->state.stencilMode != stencilMode) {
renderPass->state.shader = NO_SHADER;
}
renderPass->state.stencilMode = stencilMode;
}
}
// Validate current composite.
@@ -1309,6 +1353,7 @@ VkBool32 VKRenderer_Validate(VKShader shader, VkPrimitiveTopology topology, Alph
// Validate current pipeline.
if (renderPass->state.shader != shader ||
renderPass->state.shaderVariant != shaderVariant ||
renderPass->state.topology != topology ||
renderPass->state.inAlphaType != inAlphaType) {
J2dTraceLn(J2D_TRACE_VERBOSE, "VKRenderer_Validate: updating pipeline, old=%d, new=%d",
@@ -1316,6 +1361,7 @@ VkBool32 VKRenderer_Validate(VKShader shader, VkPrimitiveTopology topology, Alph
VKRenderer_FlushDraw(surface);
VkCommandBuffer cb = renderPass->commandBuffer;
renderPass->state.shader = shader;
renderPass->state.shaderVariant = shaderVariant;
renderPass->state.topology = topology;
renderPass->state.inAlphaType = inAlphaType;
VKPipelineInfo pipelineInfo = VKPipelines_GetPipelineInfo(renderPass->context, renderPass->state);
@@ -1323,10 +1369,26 @@ VkBool32 VKRenderer_Validate(VKShader shader, VkPrimitiveTopology topology, Alph
surface->device->vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineInfo.pipeline);
renderPass->vertexBufferWriting.bound = VK_FALSE;
renderPass->maskFillBufferWriting.bound = VK_FALSE;
// If pipeline uses mask fill layout, but the shader is not actually a MASK one, that must be a generic-layout pipeline.
// In that case, we need to bind a mask buffer, even if we won't ever use it.
// We could use VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT or nullDescriptor, but those require
// optional features or extensions, so don't bother for now...
// TODO this is ugly, do something with it.
if (pipelineInfo.layout == surface->device->renderer->pipelineContext->maskFillPipelineLayout && !(shader & SHADER_MASK)) {
VKRenderer_AllocateMaskFillBytes(0);
}
}
VKRenderer_ValidateConstants();
return VK_TRUE;
}
static VkBool32 VKRenderer_ValidatePaint(VKShader shaderModifier, VkBool32 fill) {
return VKRenderer_Validate(context.shader | shaderModifier, context.shaderVariant,
fill ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST : VK_PRIMITIVE_TOPOLOGY_LINE_LIST, context.inAlphaType);
}
// Drawing operations.
void VKRenderer_RenderRect(VkBool32 fill, jint x, jint y, jint w, jint h) {
@@ -1337,12 +1399,9 @@ void VKRenderer_RenderRect(VkBool32 fill, jint x, jint y, jint w, jint h) {
void VKRenderer_RenderParallelogram(VkBool32 fill,
jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12)
{
if (!VKRenderer_Validate(SHADER_COLOR,
fill ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
: VK_PRIMITIVE_TOPOLOGY_LINE_LIST, ALPHA_TYPE_UNKNOWN)) return; // Not ready.
RGBA c = VKRenderer_GetRGBA(context.surface, context.renderColor);
jfloat dx12, jfloat dy12) {
if (!VKRenderer_ValidatePaint(0, fill)) return; // Not ready.
/* dx21
* (p1)---------(p2) | (p1)------
* |\ \ | | \ dy21
@@ -1353,12 +1412,12 @@ void VKRenderer_RenderParallelogram(VkBool32 fill,
* dy21 \ |
* -----(p3)
*/
VKColorVertex p1 = {x11, y11, c};
VKColorVertex p2 = {x11 + dx21, y11 + dy21, c};
VKColorVertex p3 = {x11 + dx21 + dx12, y11 + dy21 + dy12, c};
VKColorVertex p4 = {x11 + dx12, y11 + dy12, c};
VKVertex p1 = {x11, y11, context.vertexData};
VKVertex p2 = {x11 + dx21, y11 + dy21, context.vertexData};
VKVertex p3 = {x11 + dx21 + dx12, y11 + dy21 + dy12, context.vertexData};
VKVertex p4 = {x11 + dx12, y11 + dy12, context.vertexData};
VKColorVertex* vs;
VKVertex* vs;
VK_DRAW(vs, 1, fill ? 6 : 8);
uint32_t i = 0;
vs[i++] = p1;
@@ -1375,19 +1434,18 @@ void VKRenderer_RenderParallelogram(VkBool32 fill,
void VKRenderer_FillSpans(jint spanCount, jint *spans) {
if (spanCount == 0) return;
if (!VKRenderer_Validate(SHADER_COLOR, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, ALPHA_TYPE_UNKNOWN)) return; // Not ready.
RGBA c = VKRenderer_GetRGBA(context.surface, context.renderColor);
if (!VKRenderer_ValidatePaint(0, VK_TRUE)) return; // Not ready.
jfloat x1 = (float)*(spans++);
jfloat y1 = (float)*(spans++);
jfloat x2 = (float)*(spans++);
jfloat y2 = (float)*(spans++);
VKColorVertex p1 = {x1, y1, c};
VKColorVertex p2 = {x2, y1, c};
VKColorVertex p3 = {x2, y2, c};
VKColorVertex p4 = {x1, y2, c};
VKVertex p1 = {x1, y1, context.vertexData};
VKVertex p2 = {x2, y1, context.vertexData};
VKVertex p3 = {x2, y2, context.vertexData};
VKVertex p4 = {x1, y2, context.vertexData};
VKColorVertex* vs;
VKVertex* vs;
VK_DRAW(vs, 1, 6);
vs[0] = p1; vs[1] = p2; vs[2] = p3; vs[3] = p3; vs[4] = p4; vs[5] = p1;
@@ -1404,8 +1462,8 @@ void VKRenderer_FillSpans(jint spanCount, jint *spans) {
void VKRenderer_MaskFill(jint x, jint y, jint w, jint h,
jint maskoff, jint maskscan, jint masklen, uint8_t *mask) {
if (!VKRenderer_Validate(SHADER_MASK_FILL_COLOR,
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, ALPHA_TYPE_UNKNOWN)) return; // Not ready.
if (!VKRenderer_ValidatePaint(SHADER_MASK, VK_TRUE)) return; // Not ready.
// maskoff is the offset from the beginning of mask,
// it's the same as x and y offset within a tile (maskoff % maskscan, maskoff / maskscan).
// maskscan is the number of bytes in a row/
@@ -1423,14 +1481,13 @@ void VKRenderer_MaskFill(jint x, jint y, jint w, jint h,
*((char *)maskState.data) = (char)0xFF;
}
VKMaskFillColorVertex* vs;
VKMaskFillVertex* vs;
VK_DRAW(vs, 1, 6);
RGBA c = VKRenderer_GetRGBA(context.surface, context.renderColor);
int offset = (int) maskState.offset;
VKMaskFillColorVertex p1 = {x, y, offset, maskscan, c};
VKMaskFillColorVertex p2 = {x + w, y, offset, maskscan, c};
VKMaskFillColorVertex p3 = {x + w, y + h, offset, maskscan, c};
VKMaskFillColorVertex p4 = {x, y + h, offset, maskscan, c};
VKMaskFillVertex p1 = {x, y, offset, maskscan, context.vertexData};
VKMaskFillVertex p2 = {x + w, y, offset, maskscan, context.vertexData};
VKMaskFillVertex p3 = {x + w, y + h, offset, maskscan, context.vertexData};
VKMaskFillVertex p4 = {x, y + h, offset, maskscan, context.vertexData};
// Always keep p1 as provoking vertex for correct origin calculation in vertex shader.
vs[0] = p1; vs[1] = p3; vs[2] = p2;
vs[3] = p1; vs[4] = p3; vs[5] = p4;

View File

@@ -36,21 +36,15 @@
struct VKRenderingContext {
VKSDOps* surface;
VKTransform transform;
VKCompositeMode composite;
AlphaType inAlphaType;
VKShader shader;
VKShaderVariant shaderVariant;
unsigned int vertexData;
VKPushConstants constants;
uint64_t constantsModCount;
uint64_t transformModCount;
// We keep this color separately from renderColor,
// because we need consistent state when switching between XOR and alpha
// composite modes. This variable holds last value set by SET_COLOR, while
// renderColor holds color, currently used for drawing, which may have
// also been provided by SET_XOR_COMPOSITE.
Color color;
Color renderColor;
VKCompositeMode composite;
// Extra alpha is not used when painting with plain color,
// in this case color.a already includes it.
float extraAlpha;
uint64_t clipModCount; // Used to track changes to the clip.
VkRect2D clipRect;
ARRAY(VKIntVertex) clipSpanVertices;
@@ -63,7 +57,7 @@ VKRenderer* VKRenderer_Create(VKDevice* device);
/**
* Setup pipeline for drawing. Returns FALSE if the surface is not yet ready for drawing.
*/
VkBool32 VKRenderer_Validate(VKShader shader, VkPrimitiveTopology topology, AlphaType inAlphaType);
VkBool32 VKRenderer_Validate(VKShader shader, VKShaderVariant shaderVariant, VkPrimitiveTopology topology, AlphaType inAlphaType);
/**
* Record commands into the primary command buffer (outside of a render pass).

View File

@@ -292,15 +292,7 @@ VkBool32 VKSD_ConfigureWindowSurface(VKWinSDOps* vkwinsdo) {
}
static void VKSD_OnDispose(JNIEnv* env, SurfaceDataOps* ops) {
// We are being called from the disposer thread, RQ might be working in parallel.
// VKRenderQueue.lock/unlock is equivalent to AWT_LOCK/AWT_UNLOCK,
// but those are only available in the toolkit-specific part of AWT, so we call RQ there.
jobject rq = JNU_CallStaticMethodByName(env, NULL,
"sun/java2d/vulkan/VKRenderQueue", "getInstance", "()Lsun/java2d/vulkan/VKRenderQueue;").l;
JNU_CallMethodByName(env, NULL, rq, "lock", "()V");
VKSD_ResetSurface((VKSDOps*) ops);
JNU_CallMethodByName(env, NULL, rq, "unlock", "()V");
(*env)->DeleteLocalRef(env, rq);
JNU_CallStaticMethodByName(env, NULL, "sun/java2d/vulkan/VKSurfaceData", "dispose", "(J)V", ptr_to_jlong(ops));
}
JNIEXPORT VKSDOps* VKSD_CreateSurface(JNIEnv* env, jobject vksd, jint type, jint format, jint backgroundRGB,

View File

@@ -62,7 +62,7 @@ typedef uint16_t VKPackedSwizzle;
*/
typedef struct {
float m00, m01, m02;
float m10 __attribute__((aligned(16))), m11, m12;
float m10, m11, m12;
} VKTransform;
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VKMemory);

View File

@@ -114,6 +114,8 @@ public class DefaultFrameDecoration extends FullFrameDecorationHelper {
@Override
protected Rectangle getMaximizeButtonBounds() {
if (!hasMaximizeButton()) return null;
int x = peer.getWidth() - BUTTON_SIZE * 2 - BUTTONS_RIGHT_PADDING
- BUTTONS_PADDING - BORDER_SIZE;
int y = (int) Math.floor((HEIGHT - BUTTON_SIZE + 1f) / 2);
@@ -122,6 +124,8 @@ public class DefaultFrameDecoration extends FullFrameDecorationHelper {
@Override
protected Rectangle getMinimizeButtonBounds() {
if (!hasMinimizeButton()) return null;
int x = peer.getWidth() - BUTTON_SIZE * 3 - BUTTONS_RIGHT_PADDING
- BUTTONS_PADDING * 2 - BORDER_SIZE;
int y = (int) Math.floor((HEIGHT - BUTTON_SIZE + 1f) / 2);

View File

@@ -268,7 +268,7 @@ public class WLComponentPeer implements ComponentPeer, WLSurfaceSizeListener {
return false;
}
private static Window getToplevelFor(Component component) {
public static Window getToplevelFor(Component component) {
Container container = component instanceof Container c ? c : component.getParent();
for (Container p = container; p != null; p = p.getParent()) {
if (p instanceof Window window && !isWlPopup(window)) {
@@ -285,7 +285,7 @@ public class WLComponentPeer implements ComponentPeer, WLSurfaceSizeListener {
: c.getParent();
}
static Point getRelativeLocation(Component c, Window toplevel) {
public static Point getRelativeLocation(Component c, Window toplevel) {
Objects.requireNonNull(c);
if (toplevel == null) {
@@ -1590,7 +1590,7 @@ public class WLComponentPeer implements ComponentPeer, WLSurfaceSizeListener {
* Converts a value in the Java coordinate system into the Wayland
* surface-local coordinate system.
*/
int javaUnitsToSurfaceUnits(int value) {
public final int javaUnitsToSurfaceUnits(int value) {
if (!WLGraphicsEnvironment.isDebugScaleEnabled()) {
return value;
} else {
@@ -1600,7 +1600,7 @@ public class WLComponentPeer implements ComponentPeer, WLSurfaceSizeListener {
}
}
int javaUnitsToSurfaceSize(int value) {
public final int javaUnitsToSurfaceSize(int value) {
if (!WLGraphicsEnvironment.isDebugScaleEnabled()) {
return value;
} else {

View File

@@ -89,6 +89,7 @@ public class WLDataDevice {
private static native void setSelectionImpl(int protocol, long nativePtr, long dataOfferNativePtr, long serial);
private static native void startDragImpl(long nativePtr, long dataOfferNativePtr,
long originSurfaceNativePtr, long serial);
private static native void performDeletionsOnEDTImpl(long nativePtr);
public boolean isProtocolSupported(int protocol) {
return isProtocolSupportedImpl(nativePtr, protocol);
@@ -246,6 +247,10 @@ public class WLDataDevice {
return result;
}
public void performDeletionsOnEDT() {
performDeletionsOnEDTImpl(nativePtr);
}
// Event handlers, called from native on the EDT
private void handleDnDEnter(WLDataOffer offer, long serial, long surfacePtr, double x, double y) {
WLDropTargetContextPeer.getInstance().handleEnter(offer, serial, surfacePtr, x, y);

View File

@@ -61,7 +61,7 @@ public class WLDataOffer {
}
// after calling destroy(), this object enters an invalid state and needs to be deleted
public void destroy() {
public synchronized void destroy() {
if (nativePtr != 0) {
destroyImpl(nativePtr);
nativePtr = 0;

View File

@@ -47,7 +47,7 @@ public class WLDataSource {
private static native void setDnDActionsImpl(long nativePtr, int actions);
private static native void setDnDIconImpl(long nativePtr, int width, int height, int offsetX, int offsetY, int[] pixels);
private static native void setDnDIconImpl(long nativePtr, int scale, int width, int height, int offsetX, int offsetY, int[] pixels);
WLDataSource(WLDataDevice dataDevice, int protocol, Transferable data) {
var wlDataTransferer = (WLDataTransferer) WLDataTransferer.getInstance();
@@ -96,7 +96,7 @@ public class WLDataSource {
setDnDActionsImpl(nativePtr, actions);
}
public void setDnDIcon(Image image, int offsetX, int offsetY) {
public void setDnDIcon(Image image, int scale, int offsetX, int offsetY) {
if (nativePtr == 0) {
throw new IllegalStateException("Native pointer is null");
}
@@ -118,7 +118,7 @@ public class WLDataSource {
bufferedImage.getRGB(0, 0, width, height, pixels, 0, width);
}
setDnDIconImpl(nativePtr, width, height, offsetX, offsetY, pixels);
setDnDIconImpl(nativePtr, scale, width, height, offsetX, offsetY, pixels);
}
public synchronized void destroy() {

View File

@@ -92,21 +92,33 @@ public class WLDragSourceContextPeer extends SunDragSourceContextPeer {
this.dataDevice = dataDevice;
}
private long getComponentWlSurfacePtr() {
private WLComponentPeer getPeer() {
var comp = getComponent();
while (comp != null) {
var peer = AWTAccessor.getComponentAccessor().getPeer(comp);
if (peer instanceof WLComponentPeer wlPeer) {
return wlPeer.getSurface().getWlSurfacePtr();
return wlPeer;
}
comp = comp.getParent();
}
return null;
}
return 0;
private WLMainSurface getSurface() {
WLComponentPeer peer = getPeer();
if (peer != null) {
return peer.getSurface();
}
return null;
}
@Override
protected void startDrag(Transferable trans, long[] formats, Map<Long, DataFlavor> formatMap) {
var mainSurface = getSurface();
if (mainSurface == null) {
return;
}
// formats and formatMap are unused, because WLDataSource already references the same DataTransferer singleton
var source = new WLDragSource(trans);
@@ -118,13 +130,14 @@ public class WLDragSourceContextPeer extends SunDragSourceContextPeer {
var dragImage = getDragImage();
if (dragImage != null) {
var dragImageOffset = getDragImageOffset();
source.setDnDIcon(dragImage, dragImageOffset.x, dragImageOffset.y);
source.setDnDIcon(dragImage,
mainSurface.getGraphicsDevice().getDisplayScale(),
dragImageOffset.x, dragImageOffset.y);
}
long eventSerial = WLToolkit.getInputState().pointerButtonSerial();
var wlSurface = getComponentWlSurfacePtr();
dataDevice.startDrag(source, wlSurface, eventSerial);
dataDevice.startDrag(source, mainSurface.getWlSurfacePtr(), eventSerial);
}
@Override

View File

@@ -26,6 +26,7 @@
package sun.awt.wl;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.peer.FramePeer;
import sun.awt.AWTAccessor;
@@ -42,6 +43,12 @@ public class WLFramePeer extends WLDecoratedPeer implements FramePeer {
super(target, target.isUndecorated(),
Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.ICONIFIED),
Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH));
AWTAccessor.getWindowAccessor().addWindowListener(target, new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
getFrame().removeNotify();
}
});
}
@Override

View File

@@ -38,35 +38,9 @@ import sun.java2d.wl.WLSurfaceSizeListener;
public abstract class WLGraphicsConfig extends GraphicsConfiguration {
private final WLGraphicsDevice device;
private final int x;
private final int y;
private final int xLogical; // logical (scaled) horizontal location; optional, could be zero
private final int yLogical; // logical (scaled) vertical location; optional, could be zero
private final int width;
private final int height;
private final int widthLogical; // logical (scaled) width; optional, could be zero
private final int heightLogical;// logical (scaled) height; optional, could be zero
private final int displayScale; // as reported by Wayland
private final double effectiveScale; // as enforced by Java
protected WLGraphicsConfig(WLGraphicsDevice device, int x, int y, int xLogical, int yLogical,
int width, int height, int widthLogical, int heightLogical,
int displayScale) {
protected WLGraphicsConfig(WLGraphicsDevice device) {
this.device = device;
this.x = x;
this.y = y;
this.xLogical = xLogical;
this.yLogical = yLogical;
this.width = width;
this.height = height;
this.widthLogical = widthLogical;
this.heightLogical = heightLogical;
this.displayScale = displayScale;
this.effectiveScale = WLGraphicsEnvironment.effectiveScaleFrom(displayScale);
}
boolean differsFrom(int width, int height, int scale) {
return width != this.width || height != this.height || scale != this.displayScale;
}
@Override
@@ -84,7 +58,7 @@ public abstract class WLGraphicsConfig extends GraphicsConfiguration {
@Override
public AffineTransform getDefaultTransform() {
double scale = effectiveScale;
double scale = device.getEffectiveScale();
return AffineTransform.getScaleInstance(scale, scale);
}
@@ -97,20 +71,18 @@ public abstract class WLGraphicsConfig extends GraphicsConfiguration {
@Override
public Rectangle getBounds() {
return (widthLogical > 0 && heightLogical > 0)
? new Rectangle(xLogical, yLogical, widthLogical, heightLogical)
: new Rectangle(x, y, width, height);
return device.getBounds();
}
public Rectangle getRealBounds() {
return new Rectangle(x, y, width, height);
return device.getRealBounds();
}
/**
* Returns the preferred Wayland buffer scale for this display configuration.
*/
public int getDisplayScale() {
return displayScale;
return device.getDisplayScale();
}
/**
@@ -118,7 +90,7 @@ public abstract class WLGraphicsConfig extends GraphicsConfiguration {
* if overridden with the sun.java2d.uiScale system property.
*/
public double getEffectiveScale() {
return effectiveScale;
return device.getEffectiveScale();
}
public abstract SurfaceType getSurfaceType();
@@ -127,6 +99,7 @@ public abstract class WLGraphicsConfig extends GraphicsConfiguration {
@Override
public String toString() {
return String.format("%dx%d@(%d, %d) %dx scale", width, height, x, y, displayScale);
Rectangle bounds = getBounds();
return String.format("%dx%d@(%d, %d) %dx scale", bounds.width, bounds.height, bounds.x, bounds.y, getDisplayScale());
}
}

View File

@@ -39,15 +39,21 @@ import java.util.HashSet;
import java.util.Set;
/**
* Corresponds to Wayland's output and is identified by its wlID and x, y coordinates
* in the multi-monitor setup. Whenever those change, this device is re-created.
* Corresponds to a Wayland output and is identified by its wlID.
* Owns all graphics configurations associated with this device.
* Encapsulates all the other properties of the output, such as its size
* and location in a multi-monitor configuration.
* Whenever any of these properties change, they are updated and
* the GraphicsConfiguration objects get re-created to let referents know of the change.
*/
public class WLGraphicsDevice extends GraphicsDevice {
private static final double MM_IN_INCH = 25.4;
/**
* ID of the corresponding wl_output object received from Wayland.
* Only changes when the device gets invalidated.
*/
private volatile int wlID; // only changes when the device gets invalidated
private volatile int wlID;
/**
* Some human-readable name of the device that came from Wayland.
@@ -58,75 +64,142 @@ public class WLGraphicsDevice extends GraphicsDevice {
/**
* The horizontal location of this device in the multi-monitor configuration.
*/
private volatile int x; // only changes when the device gets invalidated
private volatile int x;
/**
* The vertical location of this device in the multi-monitor configuration.
*/
private volatile int y; // only changes when the device gets invalidated
private volatile int y;
private volatile int xLogical; // logical (scaled) horizontal location; optional, could be zero
private volatile int yLogical; // logical (scaled) vertical location; optional, could be zero
/**
* Pixel width, mostly for accounting and reporting.
*/
private volatile int width;
private final int widthMm;
private final int heightMm;
/**
* Pixel height, mostly for accounting and reporting.
*/
private volatile int height;
// Configs are always the same in size and scale
private volatile GraphicsConfiguration[] configs = null;
/**
* Logical (scaled) width in Java units.
*/
private volatile int widthLogical;
// The default config is an object from the configs array
private volatile WLGraphicsConfig defaultConfig = null;
/**
* Logical (scaled) height in Java units.
*/
private volatile int heightLogical;
// Top-level window peers that consider this device as their primary one
// and get their graphics configuration from it
/**
* Width in millimeters.
*/
private volatile int widthMm;
/**
* Height in millimeters.
*/
private volatile int heightMm;
/**
* The device's scale factor as reported by Wayland.
* Since it is an integer, it's usually higher than the real fraction scale.
*/
private volatile int displayScale;
/**
* The effective scale factor as determined by Java.
*/
private volatile double effectiveScale;
private volatile GraphicsConfiguration[] configs;
private volatile WLGraphicsConfig defaultConfig; // A reference to the configs array
/**
* Top-level window peers that consider this device as their primary one
* and get their graphics configuration from it
*/
private final Set<WLComponentPeer> toplevels = new HashSet<>(); // guarded by 'this'
private WLGraphicsDevice(int id, int x, int y, int xLogical, int yLogical, int widthMm, int heightMm) {
private WLGraphicsDevice(int id,
String name,
int x, int y,
int width, int height,
int widthLogical, int heightLogical,
int widthMm, int heightMm,
int displayScale) {
assert width > 0 && height > 0;
assert widthLogical > 0 && heightLogical > 0;
assert widthMm > 0 && heightMm > 0;
assert displayScale > 0;
this.wlID = id;
this.name = name;
this.x = x;
this.y = y;
this.xLogical = xLogical;
this.yLogical = yLogical;
this.width = width;
this.height = height;
this.widthLogical = widthLogical;
this.heightLogical = heightLogical;
this.widthMm = widthMm;
this.heightMm = heightMm;
this.displayScale = displayScale;
this.effectiveScale = WLGraphicsEnvironment.effectiveScaleFrom(displayScale);
makeGC();
}
int getID() {
return wlID;
}
void updateConfiguration(String name, int width, int height, int widthLogical, int heightLogical, int scale) {
this.name = name;
WLGraphicsConfig config = defaultConfig;
// Note that all configs are of equal size and scale
if (config == null || config.differsFrom(width, height, scale)) {
GraphicsConfiguration[] newConfigs;
WLGraphicsConfig newDefaultConfig;
// It is necessary to create a new object whenever config changes as its
// identity is used to detect changes in scale, among other things.
if (VKEnv.isPresentationEnabled()) {
newConfigs = VKEnv.getDevices().flatMap(d -> d.getPresentableGraphicsConfigs().map(
gc -> WLVKGraphicsConfig.getConfig(
gc, this, x, y, xLogical, yLogical, width, height, widthLogical, heightLogical, scale)))
.toArray(WLGraphicsConfig[]::new);
newDefaultConfig = (WLGraphicsConfig) newConfigs[0];
} else {
// TODO: Actually, Wayland may support a lot more shared memory buffer configurations, need to
// subscribe to the wl_shm:format event and get the list from there.
newDefaultConfig = WLSMGraphicsConfig.getConfig(this, x, y, xLogical, yLogical, width, height, widthLogical, heightLogical, scale, true);
newConfigs = new GraphicsConfiguration[2];
newConfigs[0] = newDefaultConfig;
newConfigs[1] = WLSMGraphicsConfig.getConfig(this, x, y, xLogical, yLogical, width, height, widthLogical, heightLogical, scale, false);
}
configs = newConfigs;
defaultConfig = newDefaultConfig;
private void makeGC() {
GraphicsConfiguration[] newConfigs;
WLGraphicsConfig newDefaultConfig;
if (VKEnv.isPresentationEnabled()) {
newConfigs = VKEnv.getDevices().flatMap(d -> d.getPresentableGraphicsConfigs().map(
gc -> WLVKGraphicsConfig.getConfig(gc, this)))
.toArray(WLGraphicsConfig[]::new);
newDefaultConfig = (WLGraphicsConfig) newConfigs[0];
} else {
// TODO: Actually, Wayland may support a lot more shared memory buffer configurations, need to
// subscribe to the wl_shm:format event and get the list from there.
newDefaultConfig = WLSMGraphicsConfig.getConfig(this, true);
newConfigs = new GraphicsConfiguration[2];
newConfigs[0] = newDefaultConfig;
newConfigs[1] = WLSMGraphicsConfig.getConfig(this, false);
}
configs = newConfigs;
defaultConfig = newDefaultConfig;
}
void updateConfiguration(String name,
int x, int y,
int width, int height,
int widthLogical, int heightLogical,
int widthMm, int heightMm,
int scale) {
assert width > 0 && height > 0;
assert widthLogical > 0 && heightLogical > 0;
assert widthMm > 0 && heightMm > 0;
assert scale > 0;
this.name = name;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.widthLogical = widthLogical;
this.heightLogical = heightLogical;
this.widthMm = widthMm;
this.heightMm = heightMm;
this.displayScale = scale;
this.effectiveScale = WLGraphicsEnvironment.effectiveScaleFrom(scale);
// It is necessary to create new config objects whenever this device changes
// as GraphicsConfiguration identity is used to detect changes in scale, among other things.
makeGC();
// It is important that by the time displayChanged() events are delivered,
// all the peers on this device had their graphics configuration updated
// to refer to the new ones with, perhaps, different scale or resolution.
// to refer to the new ones with, perhaps, a different scale or resolution.
// This affects various BufferStrategy that use volatile images as their buffers.
notifyToplevels();
}
@@ -136,47 +209,36 @@ public class WLGraphicsDevice extends GraphicsDevice {
synchronized (this) {
toplevelsCopy.addAll(toplevels);
}
int wlOutputID = this.wlID;
// NB: each of those peers will likely receive another such notification
// from Wayland when it gets the wl_surface::enter event, but the second one
// will effectively be a no-op.
toplevelsCopy.forEach((peer) -> peer.notifyEnteredOutput(wlOutputID));
toplevelsCopy.forEach(WLComponentPeer::checkIfOnNewScreen);
}
/**
* Changes all aspects of this device including its identity to be that of the given
* Changes all aspects of this device, including its identity to be that of the given
* device. Only used for devices that are no longer physically present, but references
* to which may still exist in the program.
*/
void invalidate(WLGraphicsDevice similarDevice) {
// Note: It is expected that all the surface this device used to host have already received
// the 'leave' event and updated their device/graphics configurations accordingly.
this.wlID = similarDevice.wlID;
this.x = similarDevice.x;
this.y = similarDevice.y;
this.xLogical = similarDevice.xLogical;
this.yLogical = similarDevice.yLogical;
int newScale = similarDevice.getDisplayScale();
Rectangle newBounds = similarDevice.defaultConfig.getBounds();
Rectangle newRealBounds = similarDevice.defaultConfig.getRealBounds();
updateConfiguration(similarDevice.name, newRealBounds.width, newRealBounds.height, newBounds.width, newBounds.height, newScale);
updateConfiguration(similarDevice.name,
similarDevice.x,
similarDevice.y,
similarDevice.width,
similarDevice.height,
similarDevice.widthLogical,
similarDevice.heightLogical,
similarDevice.widthMm,
similarDevice.heightMm,
similarDevice.displayScale);
}
public static WLGraphicsDevice createWithConfiguration(int id, String name,
int x, int y, int xLogical, int yLogical,
int x, int y,
int width, int height, int widthLogical, int heightLogical,
int widthMm, int heightMm,
int scale) {
WLGraphicsDevice device = new WLGraphicsDevice(id, x, y, xLogical, yLogical, widthMm, heightMm);
device.updateConfiguration(name, width, height, widthLogical, heightLogical, scale);
return device;
}
/**
* Compares the identity of this device with the given attributes
* and returns true iff the attributes identify the same device.
*/
boolean isSameDeviceAs(int wlID, int x, int y, int xLogical, int yLogical) {
return this.wlID == wlID && this.x == x && this.y == y && this.xLogical == xLogical && this.yLogical == yLogical;
return new WLGraphicsDevice(id, name, x, y, width, height, widthLogical, heightLogical, widthMm, heightMm, scale);
}
boolean hasSameNameAs(WLGraphicsDevice otherDevice) {
@@ -207,8 +269,8 @@ public class WLGraphicsDevice extends GraphicsDevice {
public GraphicsConfiguration[] getConfigurations() {
// From wayland.xml, wl_output.mode event:
// "Non-current modes are deprecated. A compositor can decide to only
// advertise the current mode and never send other modes. Clients
// should not rely on non-current modes."
// advertise the current mode and never send other modes. Clients
// should not rely on non-current modes."
// So there's always the same set of configs.
return configs.clone();
}
@@ -218,8 +280,24 @@ public class WLGraphicsDevice extends GraphicsDevice {
return defaultConfig;
}
int getID() {
return wlID;
}
Rectangle getBounds() {
return new Rectangle(x, y, widthLogical, heightLogical);
}
Rectangle getRealBounds() {
return new Rectangle(x, y, width, height);
}
int getDisplayScale() {
return defaultConfig.getDisplayScale();
return displayScale;
}
double getEffectiveScale() {
return effectiveScale;
}
int getResolution() {
@@ -227,13 +305,6 @@ public class WLGraphicsDevice extends GraphicsDevice {
return getResolutionX(defaultConfig);
}
double getPhysicalResolution() {
Rectangle bounds = defaultConfig.getRealBounds();
double daigInPixels = Math.sqrt(bounds.width * bounds.width + bounds.height * bounds.height);
double diagInMm = Math.sqrt(widthMm * widthMm + heightMm * heightMm);
return daigInPixels * MM_IN_INCH / diagInMm;
}
double getPhysicalScale() {
Rectangle bounds = defaultConfig.getRealBounds();
double daigInPixels = Math.sqrt(bounds.width * bounds.width + bounds.height * bounds.height);
@@ -267,7 +338,7 @@ public class WLGraphicsDevice extends GraphicsDevice {
boolean fsSupported = isFullScreenSupported();
if (fsSupported && old != null) {
// enter windowed mode and restore original display mode
// enter windowed mode and restore the original display mode
exitFullScreenExclusive(old);
}
@@ -311,9 +382,8 @@ public class WLGraphicsDevice extends GraphicsDevice {
@Override
public String toString() {
var config = defaultConfig;
return String.format("WLGraphicsDevice: '%s' id=%d at (%d, %d) ((%d, %d) logical) with %s",
name, wlID, x, y, xLogical, yLogical,
config != null ? config : "<no configs>");
return String.format("WLGraphicsDevice: '%s' id=%d at (%d, %d) with %s",
name, wlID, x, y, config != null ? config : "<no configs>");
}
public Insets getInsets() {

View File

@@ -26,6 +26,7 @@
package sun.awt.wl;
import java.awt.AWTError;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
@@ -54,6 +55,8 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment implements HiD
private static final boolean debugScaleEnabled;
private final Dimension totalDisplayBounds = new Dimension();
private final List<WLGraphicsDevice> devices = new ArrayList<>(5);
@SuppressWarnings("restricted")
private static void loadAwt() {
System.loadLibrary("awt");
@@ -94,15 +97,30 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment implements HiD
}
}
@Override
public GraphicsDevice getDefaultScreenDevice() {
synchronized (devices) {
if (devices.isEmpty()) {
throw new AWTError("no screen devices");
}
return devices.getFirst();
}
}
@Override
public synchronized GraphicsDevice[] getScreenDevices() {
synchronized (devices) {
return devices.toArray(new GraphicsDevice[0]);
}
}
@Override
public boolean isDisplayLocal() {
return true;
}
private final List<WLGraphicsDevice> devices = new ArrayList<>(5);
private void notifyOutputConfigured(String name, String make, String model, int wlID,
int x, int y, int xLogical, int yLogical,
int x, int y,
int width, int height,
int widthLogical, int heightLogical,
int widthMm, int heightMm,
@@ -110,46 +128,35 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment implements HiD
// Called from native code whenever a new output appears or an existing one changes its properties
// NB: initially called during WLToolkit.initIDs() on the main thread; later on EDT.
if (log.isLoggable(Level.FINE)) {
log.fine(String.format("Output configured id=%d at (%d, %d) (%d, %d logical) %dx%d (%dx%d logical) %dx scale",
wlID, x, y, xLogical, yLogical, width, height, widthLogical, heightLogical, scale));
log.fine(String.format("Output configured id=%d at (%d, %d) %dx%d (%dx%d logical) %dx scale",
wlID, x, y, width, height, widthLogical, heightLogical, scale));
}
String humanID =
(name != null ? name + " " : "")
+ (make != null ? make + " " : "")
+ (model != null ? model : "");
synchronized (devices) {
boolean newOutput = true;
for (int i = 0; i < devices.size(); i++) {
final WLGraphicsDevice gd = devices.get(i);
if (gd.getID() == wlID) {
newOutput = false;
if (gd.isSameDeviceAs(wlID, x, y, xLogical, yLogical)) {
// These coordinates and the size are not scaled.
gd.updateConfiguration(humanID, width, height, widthLogical, heightLogical, scale);
} else {
final WLGraphicsDevice updatedDevice = WLGraphicsDevice.createWithConfiguration(wlID, humanID,
x, y, xLogical, yLogical, width, height, widthLogical, heightLogical,
widthMm, heightMm, scale);
devices.set(i, updatedDevice);
gd.invalidate(updatedDevice);
}
break;
}
}
if (newOutput) {
final WLGraphicsDevice gd = WLGraphicsDevice.createWithConfiguration(wlID, humanID,
x, y, xLogical, yLogical, width, height, widthLogical, heightLogical,
widthMm, heightMm, scale);
devices.add(gd);
}
if (LogDisplay.ENABLED) {
double effectiveScale = effectiveScaleFrom(scale);
LogDisplay log = newOutput ? LogDisplay.ADDED : LogDisplay.CHANGED;
log.log(wlID, (int) (width / effectiveScale) + "x" + (int) (height / effectiveScale), effectiveScale);
// Logical size comes from an optional protocol, so take the data from the main one, if absent
if (widthLogical == 0) widthLogical = width;
if (heightLogical == 0) heightLogical = height;
String humanID = deviceNameFrom(name, make, model);
WLGraphicsDevice gd = deviceWithID(wlID);
if (gd != null) {
// Some properties of an existing device have changed; update the existing device and
// let all the windows it hosts know about the change.
gd.updateConfiguration(humanID, x, y, width, height, widthLogical, heightLogical, widthMm, heightMm, scale);
} else {
WLGraphicsDevice newGD = WLGraphicsDevice.createWithConfiguration(wlID, humanID,
x, y, width, height, widthLogical, heightLogical,
widthMm, heightMm, scale);
synchronized (devices) {
devices.add(newGD);
}
}
if (LogDisplay.ENABLED) {
double effectiveScale = effectiveScaleFrom(scale);
LogDisplay log = (gd == null) ? LogDisplay.ADDED : LogDisplay.CHANGED;
log.log(wlID, (int) (width / effectiveScale) + "x" + (int) (height / effectiveScale), effectiveScale);
}
updateTotalDisplayBounds();
// Skip notification during the initial configuration events
@@ -158,6 +165,12 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment implements HiD
}
}
private static String deviceNameFrom(String name, String make, String model) {
return (name != null ? name + " " : "")
+ (make != null ? make + " " : "")
+ (model != null ? model : "");
}
private WLGraphicsDevice getSimilarDevice(WLGraphicsDevice modelDevice) {
WLGraphicsDevice similarDevice = devices.isEmpty() ? null : devices.getFirst();
for (WLGraphicsDevice device : devices) {
@@ -181,47 +194,33 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment implements HiD
log.fine(String.format("Output destroyed id=%d", wlID));
}
// NB: id may *not* be that of any output; if so, just ignore this event.
synchronized (devices) {
final Optional<WLGraphicsDevice> deviceOptional = devices.stream()
.filter(device -> device.getID() == wlID)
.findFirst();
if (deviceOptional.isPresent()) {
final WLGraphicsDevice destroyedDevice = deviceOptional.get();
if (LogDisplay.ENABLED) {
WLGraphicsConfig config = (WLGraphicsConfig) destroyedDevice.getDefaultConfiguration();
Rectangle bounds = config.getBounds();
LogDisplay.REMOVED.log(wlID, bounds.width + "x" + bounds.height, config.getEffectiveScale());
}
devices.remove(destroyedDevice);
final WLGraphicsDevice similarDevice = getSimilarDevice(destroyedDevice);
if (similarDevice != null) destroyedDevice.invalidate(similarDevice);
WLGraphicsDevice gd = deviceWithID(wlID);
if (gd != null) {
if (LogDisplay.ENABLED) {
WLGraphicsConfig config = (WLGraphicsConfig) gd.getDefaultConfiguration();
Rectangle bounds = config.getBounds();
LogDisplay.REMOVED.log(wlID, bounds.width + "x" + bounds.height, config.getEffectiveScale());
}
synchronized (devices) {
devices.remove(gd);
}
final WLGraphicsDevice similarDevice = getSimilarDevice(gd);
if (similarDevice != null) gd.invalidate(similarDevice);
}
updateTotalDisplayBounds();
displayChanged();
}
WLGraphicsDevice notifySurfaceEnteredOutput(WLComponentPeer wlComponentPeer, int wlOutputID) {
WLGraphicsDevice deviceWithID(int wlOutputID) {
synchronized (devices) {
for (WLGraphicsDevice gd : devices) {
if (gd.getID() == wlOutputID) {
return gd;
}
}
return null;
}
}
WLGraphicsDevice notifySurfaceLeftOutput(WLComponentPeer wlComponentPeer, int wlOutputID) {
synchronized (devices) {
for (WLGraphicsDevice gd : devices) {
if (gd.getID() == wlOutputID) {
return gd;
}
}
return null;
}
return null;
}
public Dimension getTotalDisplayBounds() {
@@ -231,17 +230,15 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment implements HiD
}
private void updateTotalDisplayBounds() {
Rectangle virtualBounds = new Rectangle();
synchronized (devices) {
Rectangle virtualBounds = new Rectangle();
for (GraphicsDevice gd : devices) {
for (GraphicsConfiguration gc : gd.getConfigurations()) {
virtualBounds = virtualBounds.union(gc.getBounds());
}
}
synchronized (totalDisplayBounds) {
totalDisplayBounds.setSize(virtualBounds.getSize());
for (var gd : devices) {
virtualBounds = virtualBounds.union(gd.getBounds());
}
}
synchronized (totalDisplayBounds) {
totalDisplayBounds.setSize(virtualBounds.getSize());
}
}
static double effectiveScaleFrom(int displayScale) {

View File

@@ -67,7 +67,7 @@ public class WLMainSurface extends WLSurface {
// Called from native code whenever the corresponding wl_surface enters an output (monitor)
synchronized (devices) {
final WLGraphicsEnvironment ge = (WLGraphicsEnvironment)WLGraphicsEnvironment.getLocalGraphicsEnvironment();
final WLGraphicsDevice gd = ge.notifySurfaceEnteredOutput(peer, wlOutputID);
final WLGraphicsDevice gd = ge.deviceWithID(wlOutputID);
if (gd != null) {
devices.add(gd);
}
@@ -81,7 +81,7 @@ public class WLMainSurface extends WLSurface {
// Called from native code whenever the corresponding wl_surface leaves an output (monitor)
synchronized (devices) {
final WLGraphicsEnvironment ge = (WLGraphicsEnvironment)WLGraphicsEnvironment.getLocalGraphicsEnvironment();
final WLGraphicsDevice gd = ge.notifySurfaceLeftOutput(peer, wlOutputID);
final WLGraphicsDevice gd = ge.deviceWithID(wlOutputID);
if (gd != null) {
devices.remove(gd);
}

View File

@@ -24,11 +24,16 @@
*/
package sun.awt.wl;
import sun.awt.SunToolkit;
import java.awt.Point;
import java.awt.Window;
import java.awt.peer.MouseInfoPeer;
public class WLMouseInfoPeer implements MouseInfoPeer {
public class WLMouseInfoPeer implements MouseInfoPeer, SunToolkit.RelativePointerMovementInfoProvider {
private final Object mouseDeltaLock = new Object();
private double mouseDeltaX = 0.0;
private double mouseDeltaY = 0.0;
@Override
public int fillPointWithCoords(Point point) {
@@ -55,4 +60,23 @@ public class WLMouseInfoPeer implements MouseInfoPeer {
return HOLDER.instance;
}
void accumulatePointerDelta(double dx, double dy) {
synchronized (mouseDeltaLock) {
mouseDeltaX += dx;
mouseDeltaY += dy;
}
}
@Override
public Point getAccumulatedMouseDeltaAndReset() {
var p = new Point();
synchronized (mouseDeltaLock) {
int idx = (int) mouseDeltaX;
int idy = (int) mouseDeltaY;
p.setLocation(idx, idy);
mouseDeltaX = mouseDeltaX - idx;
mouseDeltaY = mouseDeltaY - idy;
}
return p;
}
}

View File

@@ -58,36 +58,16 @@ public class WLSMGraphicsConfig extends WLGraphicsConfig
private final ColorModel colorModel;
private final SurfaceType surfaceType;
private WLSMGraphicsConfig(WLGraphicsDevice device,
int x,
int y,
int xLogical,
int yLogical,
int width,
int height,
int widthLogical,
int heightLogical,
int scale,
boolean translucencyCapable) {
super(device, x, y, xLogical, yLogical, width, height, widthLogical, heightLogical, scale);
private WLSMGraphicsConfig(WLGraphicsDevice device, boolean translucencyCapable) {
super(device);
this.translucencyCapable = translucencyCapable;
this.colorModel = colorModelFor(translucencyCapable ? Transparency.TRANSLUCENT : Transparency.OPAQUE);
// Note: GNOME Shell definitely expects alpha values to be pre-multiplied
this.surfaceType = translucencyCapable ? SurfaceType.IntArgbPre : SurfaceType.IntRgb;
}
public static WLSMGraphicsConfig getConfig(WLGraphicsDevice device,
int x,
int y,
int xLogical,
int yLogical,
int width,
int height,
int widthLogical,
int heightLogical,
int scale,
boolean translucencyCapable) {
var newConfig = new WLSMGraphicsConfig(device, x, y, xLogical, yLogical, width, height, widthLogical, heightLogical, scale, translucencyCapable);
public static WLSMGraphicsConfig getConfig(WLGraphicsDevice device, boolean translucencyCapable) {
var newConfig = new WLSMGraphicsConfig(device, translucencyCapable);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("New shared memory config " + newConfig);
}

View File

@@ -35,6 +35,7 @@ import sun.awt.PeerEvent;
import sun.awt.SunToolkit;
import sun.awt.UNIXToolkit;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.wl.im.WLInputMethodMetaDescriptor;
import sun.java2d.vulkan.VKEnv;
import sun.java2d.vulkan.VKRenderQueue;
import sun.util.logging.PlatformLogger;
@@ -254,6 +255,7 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
WLToolkit.awtLock();
try {
dispatchEventsOnEDT();
dataDevice.performDeletionsOnEDT();
} finally {
eventsQueued.release();
WLToolkit.awtUnlock();
@@ -295,6 +297,10 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
private static WLInputState inputState = WLInputState.initialState();
private static WLKeyboard keyboard;
private static void dispatchRelativePointerEvent(double dx, double dy) {
WLMouseInfoPeer.getInstance().accumulatePointerDelta(dx, dy);
}
private static void dispatchPointerEvent(WLPointerEvent e) {
// Invoked from the native code
assert EventQueue.isDispatchThread();
@@ -439,7 +445,6 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
final WLInputState newInputState = inputState.updatedFromKeyboardLeaveEvent(serial, surfacePtr);
final WLWindowPeer peer = peerFromSurface(surfacePtr);
if (peer != null && peer.getTarget() instanceof Window window) {
((WLToolkit) Toolkit.getDefaultToolkit()).ungrab(window);
final WindowEvent winLostFocusEvent = new WindowEvent(window, WindowEvent.WINDOW_LOST_FOCUS);
WLKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
WLKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
@@ -774,13 +779,27 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
return 16777216; // 24 bits per pixel, 8 bits per channel
}
/**
* {@link java.awt.event.InputMethodEvent#getText()} can contain attributes which provide AWT/Swing with additional useful information
* (e.g. a language of the text).
*
* One kind of the possible attributes is {@link InputMethodHighlight}. It informs AWT/Swing that some parts of
* the text are in different states of the text composing process, hence they should look differently from the others.
* However, it doesn't tell how exactly they should look; this choice is left to Toolkit's implementations,
* or more precisely implementations of this method.
*
* @param highlight a state of a part of InputMethodEvent's text
*
* @return a collection of {@link TextAttribute}s (with their corresponding values as documented) informing how exactly
* such text should look or {@code null} if a mapping can't be provided.
*
* @see Toolkit#mapInputMethodHighlight(InputMethodHighlight)
*/
@Override
public Map<TextAttribute, ?> mapInputMethodHighlight( InputMethodHighlight highlight) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Not implemented: WLToolkit.mapInputMethodHighlight()");
}
return null;
public Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) {
return WLInputMethodMetaDescriptor.mapInputMethodHighlight(highlight);
}
@Override
public boolean getLockingKeyState(int key) {
return switch (key) {
@@ -840,10 +859,7 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
*/
@Override
public InputMethodDescriptor getInputMethodAdapterDescriptor() {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Not implemented: WLToolkit.getInputMethodAdapterDescriptor()");
}
return null;
return WLInputMethodMetaDescriptor.getInstanceIfAvailableOnPlatform();
}
/**
@@ -852,9 +868,6 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
*/
@Override
public boolean enableInputMethodsForTextComponent() {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Not implemented: WLToolkit.enableInputMethodsForTextComponent()");
}
return true;
}
@@ -969,9 +982,10 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
var peer = AWTAccessor.getComponentAccessor().getPeer(w);
if (peer instanceof WLWindowPeer windowPeer) {
windowPeer.ungrab();
windowPeer.ungrab(false);
}
}
/**
* Returns if the java.awt.Desktop class is supported on the current
* desktop.

View File

@@ -33,6 +33,7 @@ import sun.java2d.wl.WLSMSurfaceData;
import javax.swing.JRootPane;
import javax.swing.RootPaneContainer;
import java.awt.AWTEvent;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
@@ -101,7 +102,7 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer, Surface
@Override
protected void wlSetVisible(boolean v) {
if (!v) ungrab();
if (!v) ungrab(true);
if (v && targetIsWlPopup() && shouldBeFocusedOnShowing()) {
requestWindowFocus();
@@ -206,7 +207,7 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer, Surface
@Override
public void dispose() {
ungrab();
ungrab(true);
resetCornerMasks();
super.dispose();
}
@@ -248,15 +249,17 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer, Surface
public void grab() {
if (grabbingWindow != null && !isGrabbing()) {
grabbingWindow.ungrab();
grabbingWindow.ungrab(false);
}
grabbingWindow = this;
}
public void ungrab() {
public void ungrab(boolean externalUngrab) {
if (isGrabbing()) {
grabbingWindow = null;
WLToolkit.postEvent(new UngrabEvent(getTarget()));
if (externalUngrab) {
WLToolkit.postEvent(new UngrabEvent(getTarget()));
}
}
}
@@ -264,6 +267,13 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer, Surface
return this == grabbingWindow;
}
@Override
void handleJavaWindowFocusEvent(AWTEvent e) {
if (e.getID() == WindowEvent.WINDOW_LOST_FOCUS) {
ungrab(true);
}
}
@Override
public BufferedImage getClientAreaSnapshot(int x, int y, int width, int height) {
// Move the coordinate system to the client area

View File

@@ -0,0 +1,214 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im;
import sun.awt.wl.im.text_input_unstable_v3.WLInputMethodDescriptorZwpTextInputV3;
import sun.util.logging.PlatformLogger;
import java.awt.AWTException;
import java.awt.Image;
import java.awt.font.TextAttribute;
import java.awt.im.InputMethodHighlight;
import java.awt.im.spi.InputMethod;
import java.awt.im.spi.InputMethodDescriptor;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
/**
* Since Wayland compositors may support multiple IM protocols,
* this class is responsible for choosing one specific among them,
* and the corresponding "real" implementation of {@code InputMethodDescriptor} from a subpackage.
*/
public final class WLInputMethodMetaDescriptor implements InputMethodDescriptor {
// NB: the class loading routine has to be as fast and not demanding on resources as possible.
// Also, it has to succeed in any practically possible situation.
// E.g. if the Wayland compositor doesn't support any known IM protocol,
// it mustn't prevent this class from being loaded successfully.
// Ideally, nothing additional should happen at the loading time.
//
// This class is directly used by WLToolkit to find and instantiate an InputMethod implementation.
// See java.text.MessageFormat for the formatting syntax
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.im.WLInputMethodMetaDescriptor");
/** @see sun.awt.wl.WLToolkit#mapInputMethodHighlight(InputMethodHighlight) */
public static Map<TextAttribute, ?> mapInputMethodHighlight(final InputMethodHighlight highlight) {
// NB: The implementation is supposed to produce results exactly equal to XToolkit's implementation
// for better visual consistency.
if (highlight == null)
return null;
switch (highlight.getState()) {
case InputMethodHighlight.RAW_TEXT -> {
if (highlight.isSelected())
return imHighlightMapSelectedRawText;
else
return imHighlightMapUnselectedRawText;
}
case InputMethodHighlight.CONVERTED_TEXT -> {
if (highlight.isSelected())
return imHighlightMapSelectedConvertedText;
else
return imHighlightMapUnselectedConvertedText;
}
}
return null;
}
public static WLInputMethodMetaDescriptor getInstanceIfAvailableOnPlatform() {
final WLInputMethodMetaDescriptor result;
if (!ENABLE_NATIVE_IM_SUPPORT) {
result = null;
} else {
// For now there's only 1 possible implementation of IM,
// but if/when there are more, this method will have to choose one of them.
// It'll be good if the preferable engine can be chosen via a system property.
final InputMethodDescriptor realImDescriptor = WLInputMethodDescriptorZwpTextInputV3.getInstanceIfAvailableOnPlatform();
if (realImDescriptor != null) {
result = new WLInputMethodMetaDescriptor(realImDescriptor);
} else {
result = null;
}
}
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("getInstanceIfAvailableOnPlatform(): result={0}, ENABLE_NATIVE_IM_SUPPORT={1}.", result, ENABLE_NATIVE_IM_SUPPORT);
}
return result;
}
/* java.awt.im.spi.InputMethodDescriptor methods section */
@Override
public Locale[] getAvailableLocales() throws AWTException {
final Locale[] result = realImDescriptor.getAvailableLocales();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("getAvailableLocales(): result={0}, this={1}.", Arrays.toString(result), this);
}
return result;
}
@Override
public boolean hasDynamicLocaleList() {
final boolean result = realImDescriptor.hasDynamicLocaleList();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("hasDynamicLocaleList(): result={0}, this={1}.", result, this);
}
return result;
}
@Override
public String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage) {
return realImDescriptor.getInputMethodDisplayName(inputLocale, displayLanguage);
}
@Override
public Image getInputMethodIcon(Locale inputLocale) {
return realImDescriptor.getInputMethodIcon(inputLocale);
}
@Override
public InputMethod createInputMethod() throws Exception {
final InputMethod result = realImDescriptor.createInputMethod();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("createInputMethod(): result={0}, this={1}.", result, this);
}
return result;
}
/* java.lang.Object methods section */
@Override
public String toString() {
return String.format("WLInputMethodMetaDescriptor@%d[realImDescriptor=%s]", System.identityHashCode(this), realImDescriptor);
}
/* Implementation details section */
/**
* The values are copied from XToolkit's implementation for better visual consistency with AWT on X11.
*
* @see #mapInputMethodHighlight(InputMethodHighlight)
* @see sun.awt.X11InputMethodBase
*/
private final static Map<TextAttribute, ?> imHighlightMapUnselectedRawText = Map.of(
TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD
);
private final static Map<TextAttribute, ?> imHighlightMapUnselectedConvertedText = Map.of(
TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_ONE_PIXEL
);
private final static Map<TextAttribute, ?> imHighlightMapSelectedRawText = Map.of(
TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON
);
private final static Map<TextAttribute, ?> imHighlightMapSelectedConvertedText = Map.of(
TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON
);
/**
* This flag allows disabling ALL integrations with native IMs. The idea is to allow users to disable
* unnecessary for them functionality if they face any problems because of it.
* Therefore, if it's {@code false}, the Toolkit code shouldn't use (directly or indirectly)
* any of Wayland's input methods-related APIs (e.g. the "text-input" protocol).
*/
private final static boolean ENABLE_NATIVE_IM_SUPPORT;
static {
boolean enableNativeImSupportInitializer = true;
try {
enableNativeImSupportInitializer = Boolean.parseBoolean(System.getProperty("sun.awt.wl.im.enabled", "true"));
} catch (Exception err) {
log.severe("Failed to read the value of the system property \"sun.awt.wl.im.enabled\". Assuming the default value(=true).", err);
}
ENABLE_NATIVE_IM_SUPPORT = enableNativeImSupportInitializer;
}
private final InputMethodDescriptor realImDescriptor;
private WLInputMethodMetaDescriptor(InputMethodDescriptor realImDescriptor) {
this.realImDescriptor = Objects.requireNonNull(realImDescriptor, "realImDescriptor");
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
/** Reason for the change of surrounding text or cursor position */
enum ChangeCause {
/** input method caused the change */
INPUT_METHOD(0),
/** something else than the input method caused the change */
OTHER (1);
public final int intValue;
ChangeCause(int intValue) {
this.intValue = intValue;
}
}

View File

@@ -0,0 +1,371 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import sun.util.logging.PlatformLogger;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.JTextComponent;
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.TextComponent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import java.lang.ref.WeakReference;
import java.util.Objects;
/**
* This class is intended to track all the cases when a new {@code zwp_text_input_v3::set_cursor_rectangle} request
* may have to be issued. Here are the examples of such cases:
* <ul>
* <li>The caret position has changed ;
* <li>The component has been moved/resized ;
* <li>The component's window has been moved/resized ;
* <li>The component's text has been changed ;
* </ul>
*/
class ClientComponentCaretPositionTracker implements ComponentListener, CaretListener, TextListener
{
// See java.text.MessageFormat for the formatting syntax
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.im.text_input_unstable_v3.ClientComponentCaretPositionTracker");
public ClientComponentCaretPositionTracker(WLInputMethodZwpTextInputV3 im) {
this.im = new WeakReference<>(Objects.requireNonNull(im, "im"));
}
public void startTracking(final Component component) {
assert(EventQueue.isDispatchThread());
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer(
String.format("startTracking(component=%s): im=%s, this=%s.", component, getOwnerIm(), this),
new Throwable("Stacktrace")
);
}
stopTrackingCurrentComponent();
if (component == null) {
return;
}
trackedComponent = new WeakReference<>(component);
lastKnownClientWindowBounds = null;
try {
// Moving and changing the size causes a possible change of caret position
component.addComponentListener(this);
if (component instanceof JTextComponent jtc) {
jtc.addCaretListener(this);
isCaretListenerInstalled = true;
} else if (component instanceof TextComponent tc) {
tc.addTextListener(this);
isTextListenerInstalled = true;
}
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
log.finest("startTracking(...): updated this={0}.", this);
}
} catch (Exception err) {
stopTrackingCurrentComponent();
throw err;
}
}
public void stopTrackingCurrentComponent() {
assert(EventQueue.isDispatchThread());
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer(String.format("stopTrackingCurrentComponent(): this=%s.", this), new Throwable("Stacktrace"));
}
final Component trackedComponentStrong = getTrackedComponentIfTracking();
if (trackedComponentStrong == null) {
return;
}
if (isTextListenerInstalled) {
isTextListenerInstalled = false;
try {
((TextComponent)trackedComponentStrong).removeTextListener(this);
} catch (Exception err) {
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
log.warning(String.format("stopTrackingCurrentComponent(): exception occurred while removing the text listener from %s.", trackedComponentStrong), err);
}
}
}
if (isCaretListenerInstalled) {
isCaretListenerInstalled = false;
try {
((JTextComponent)trackedComponentStrong).removeCaretListener(this);
} catch (Exception err) {
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
log.warning(String.format("stopTrackingCurrentComponent(): exception occurred while removing the caret listener from %s.", trackedComponentStrong), err);
}
}
}
try {
trackedComponentStrong.removeComponentListener(this);
} catch (Exception err) {
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
log.warning(String.format("stopTrackingCurrentComponent(): exception occurred while removing the component listener from %s.", trackedComponentStrong), err);
}
}
lastKnownClientWindowBounds = null;
updatesAreDeferred = false;
if (trackedComponent != null) {
trackedComponent.clear();
trackedComponent = null;
}
}
public Component getTrackedComponentIfTracking() {
assert(EventQueue.isDispatchThread());
final Component trackedComponentStrong;
if (trackedComponent == null) {
trackedComponentStrong = null;
} else {
trackedComponentStrong = trackedComponent.get();
}
if (trackedComponentStrong == null) {
isTextListenerInstalled = false;
isCaretListenerInstalled = false;
lastKnownClientWindowBounds = null;
updatesAreDeferred = false;
if (trackedComponent != null) {
trackedComponent.clear();
trackedComponent = null;
}
}
return trackedComponentStrong;
}
public void deferUpdates() {
assert(EventQueue.isDispatchThread());
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer(String.format("deferUpdates(): this=%s.", this), new Throwable("Stacktrace"));
}
updatesAreDeferred = true;
}
public void resumeUpdates(final boolean discardDeferredUpdates) {
assert(EventQueue.isDispatchThread());
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer(String.format("resumeUpdates(%b): this=%s.", discardDeferredUpdates, this), new Throwable("Stacktrace"));
}
if (getTrackedComponentIfTracking() == null) return;
updatesAreDeferred = false;
hasDeferredUpdates = hasDeferredUpdates && !discardDeferredUpdates;
if (hasDeferredUpdates) {
updateNotify();
}
}
public boolean areUpdatesDeferred() {
assert(EventQueue.isDispatchThread());
return updatesAreDeferred;
}
/* Listening callbacks */
/** This method is intended to be called from the owning IM's {@link java.awt.im.spi.InputMethod#dispatchEvent(AWTEvent)}. */
public void onIMDispatchEvent(AWTEvent event) {
assert(EventQueue.isDispatchThread());
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer("onIMDispatchEvent(event={0}): this={1}.", event, this);
}
final int eventId = event.getID();
if (eventId >= MouseEvent.MOUSE_FIRST && eventId <= MouseEvent.MOUSE_LAST) {
// MouseEvent or MouseWheelEvent
if (!isCaretListenerInstalled || eventId == MouseEvent.MOUSE_WHEEL) {
// We expect no mouse events except MouseWheelEvent can change the physical position of the caret
// without changing its logical position inside the document. The logical position is handled by caretUpdate.
// The event hasn't been handled by the component yet, so the caret position couldn't have been changed yet.
// Hence, we have to postpone the updating request.
EventQueue.invokeLater(this::updateNotify);
}
}
if (eventId >= KeyEvent.KEY_FIRST && eventId <= KeyEvent.KEY_LAST) {
if ( !isCaretListenerInstalled && (!isTextListenerInstalled || eventId != KeyEvent.KEY_TYPED) ) {
EventQueue.invokeLater(this::updateNotify);
}
}
}
/** This method is intended to be called from the owning IM's {@link java.awt.im.spi.InputMethod#notifyClientWindowChange(Rectangle)}. */
public void onIMNotifyClientWindowChange(Rectangle location) {
assert(EventQueue.isDispatchThread());
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer("onIMNotifyClientWindowChange(location={0}): this={1}.", location, this);
}
if (location != null) {
// null means the window has become iconified or invisible, so no need to try to update the caret position.
lastKnownClientWindowBounds = location;
updateNotify();
}
}
// ComponentListener
@Override
public void componentHidden(ComponentEvent e) {}
@Override
public void componentMoved(ComponentEvent e) {
updateNotify();
}
@Override
public void componentResized(ComponentEvent e) {
updateNotify();
}
@Override
public void componentShown(ComponentEvent e) {
updateNotify();
}
// CaretListener
@Override
public void caretUpdate(CaretEvent e) {
updateNotify();
}
// TextListener
@Override
public void textValueChanged(TextEvent e) {
updateNotify();
}
/* java.lang.Object methods section */
@Override
public String toString() {
final StringBuilder sb = new StringBuilder(1024);
sb.append("ClientComponentCaretPositionTracker@").append(System.identityHashCode(this));
sb.append('{');
sb.append("isCaretListenerInstalled=").append(isCaretListenerInstalled);
sb.append(", isTextListenerInstalled=").append(isTextListenerInstalled);
sb.append(", lastKnownClientWindowBounds=").append(lastKnownClientWindowBounds);
sb.append(", updatesAreDeferred=").append(updatesAreDeferred);
sb.append(", hasDeferredUpdates=").append(hasDeferredUpdates);
sb.append(", trackedComponent=").append(trackedComponent == null ? "null" : trackedComponent.get());
sb.append('}');
return sb.toString();
}
/* Implementation details */
private final WeakReference<WLInputMethodZwpTextInputV3> im;
private WeakReference<Component> trackedComponent = null;
private boolean isCaretListenerInstalled = false;
private boolean isTextListenerInstalled = false;
private Rectangle lastKnownClientWindowBounds = null;
private boolean updatesAreDeferred = false;
private boolean hasDeferredUpdates = false;
private WLInputMethodZwpTextInputV3 getOwnerIm() {
assert(EventQueue.isDispatchThread());
final WLInputMethodZwpTextInputV3 thisImStrong;
if (this.im == null) {
thisImStrong = null;
} else {
thisImStrong = this.im.get();
}
if (thisImStrong == null) {
stopTrackingCurrentComponent();
}
return thisImStrong;
}
private void updateNotify() {
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
log.finest(String.format("updateNotify(): this=%s.", this), new Throwable("Stacktrace"));
}
if (getTrackedComponentIfTracking() == null) return;
if (updatesAreDeferred) {
hasDeferredUpdates = true;
return;
}
hasDeferredUpdates = false;
final var imToNotify = getOwnerIm();
if (imToNotify != null) {
imToNotify.wlUpdateCursorRectangle(false);
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
/** Content hint is a bitmask to allow to modify the behavior of the text input */
enum ContentHint {
/** no special behavior */
NONE (0x0),
/** suggest word completions */
COMPLETION (0x1),
/** suggest word corrections */
SPELLCHECK (0x2),
/** switch to uppercase letters at the start of a sentence */
AUTO_CAPITALIZATION(0x4),
/** prefer lowercase letters */
LOWERCASE (0x8),
/** prefer uppercase letters */
UPPERCASE (0x10),
/** prefer casing for titles and headings (can be language dependent) */
TITLECASE (0x20),
/** characters should be hidden */
HIDDEN_TEXT (0x40),
/** typed text should not be stored */
SENSITIVE_DATA (0x80),
/** just Latin characters should be entered */
LATIN (0x100),
/** the text input is multiline */
MULTILINE (0x200);
public final int intMask;
ContentHint(int intMask) {
this.intMask = intMask;
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
/**
* The content purpose allows to specify the primary purpose of a text input.
* This allows an input method to show special purpose input panels with extra characters or to disallow some characters.
*/
enum ContentPurpose {
/** default input, allowing all characters */
NORMAL (0),
/** allow only alphabetic characters */
ALPHA (1),
/** allow only digits */
DIGITS (2),
/** input a number (including decimal separator and sign) */
NUMBER (3),
/** input a phone number */
PHONE (4),
/** input an URL */
URL (5),
/** input an email address */
EMAIL (6),
/** input a name of a person */
NAME (7),
/** input a password (combine with sensitive_data hint) */
PASSWORD(8),
/** input is a numeric password (combine with sensitive_data hint) */
PIN (9),
/** input a date */
DATE (10),
/** input a time */
TIME (11),
/** input a date and time */
DATETIME(12),
/** input for a terminal */
TERMINAL(13);
public final int intValue;
ContentPurpose(int intValue) {
this.intValue = intValue;
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import java.util.Arrays;
import java.util.Objects;
/**
* This class accumulates changes received as
* {@code zwp_text_input_v3::preedit_string}, {@code zwp_text_input_v3::commit_string} events until
* a {@code zwp_text_input_v3::done} event is received.
*/
final class IncomingChanges
{
public IncomingChanges updatePreeditString(byte[] newPreeditStringUtf8, int newPreeditStringCursorBeginUtf8Byte, int newPreeditStringCursorEndUtf8Byte) {
this.doUpdatePreeditString = true;
this.newPreeditStringUtf8 = newPreeditStringUtf8;
this.newPreeditStringCursorBeginUtf8Byte = newPreeditStringCursorBeginUtf8Byte;
this.newPreeditStringCursorEndUtf8Byte = newPreeditStringCursorEndUtf8Byte;
this.cachedResultPreeditString = null;
return this;
}
/**
* @return {@code null} if there are no changes in the preedit string
* (i.e. {@link #updatePreeditString(byte[], int, int)} hasn't been called);
* an instance of JavaPreeditString otherwise.
* @see JavaPreeditString
*/
public JavaPreeditString getPreeditString() {
if (cachedResultPreeditString != null) {
return cachedResultPreeditString;
}
cachedResultPreeditString = doUpdatePreeditString
? JavaPreeditString.fromWaylandPreeditString(newPreeditStringUtf8, newPreeditStringCursorBeginUtf8Byte, newPreeditStringCursorEndUtf8Byte)
: null;
return cachedResultPreeditString;
}
public IncomingChanges updateCommitString(byte[] newCommitStringUtf8) {
this.doUpdateCommitString = true;
this.newCommitStringUtf8 = newCommitStringUtf8;
this.cachedResultCommitString = null;
return this;
}
/**
* @return {@code null} if there are no changes in the commit string
* (i.e. {@link #updateCommitString(byte[])} hasn't been called);
* an instance of JavaCommitString otherwise.
* @see JavaCommitString
*/
public JavaCommitString getCommitString() {
if (cachedResultCommitString != null) {
return cachedResultCommitString;
}
cachedResultCommitString = doUpdateCommitString
? JavaCommitString.fromWaylandCommitString(newCommitStringUtf8)
: null;
return cachedResultCommitString;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
IncomingChanges that = (IncomingChanges) o;
return doUpdatePreeditString == that.doUpdatePreeditString &&
newPreeditStringCursorBeginUtf8Byte == that.newPreeditStringCursorBeginUtf8Byte &&
newPreeditStringCursorEndUtf8Byte == that.newPreeditStringCursorEndUtf8Byte &&
doUpdateCommitString == that.doUpdateCommitString &&
Arrays.equals(newPreeditStringUtf8, that.newPreeditStringUtf8) &&
Arrays.equals(newCommitStringUtf8, that.newCommitStringUtf8);
}
@Override
public int hashCode() {
return Objects.hash(
doUpdatePreeditString,
Arrays.hashCode(newPreeditStringUtf8),
newPreeditStringCursorBeginUtf8Byte,
newPreeditStringCursorEndUtf8Byte,
doUpdateCommitString,
Arrays.hashCode(newCommitStringUtf8)
);
}
// zwp_text_input_v3::preedit_string
private boolean doUpdatePreeditString = false;
private byte[] newPreeditStringUtf8 = null;
private int newPreeditStringCursorBeginUtf8Byte = 0;
private int newPreeditStringCursorEndUtf8Byte = 0;
private JavaPreeditString cachedResultPreeditString = null;
// zwp_text_input_v3::commit_string
private boolean doUpdateCommitString = false;
private byte[] newCommitStringUtf8 = null;
private JavaCommitString cachedResultCommitString = null;
}

View File

@@ -0,0 +1,199 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import java.awt.Rectangle;
import java.util.Objects;
/**
* This class encapsulates the entire state of an input context represented by an instance of {@code zwp_text_input_v3}.
*
* @see StateOfEnabled
*/
final class InputContextState {
/** pointer to a native context {@code zwp_text_input_v3} */
public final long nativeContextPtr;
public InputContextState(long nativeContextPtr) {
assert(nativeContextPtr != 0);
this.nativeContextPtr = nativeContextPtr;
}
/** @return 0 if the input context hasn't entered a surface yet. Otherwise, the native pointer to the surface. */
public long getCurrentWlSurfacePtr() {
return currentWlSurfacePtr;
}
public void setCurrentWlSurfacePtr(long currentWlSurfacePtr) {
this.currentWlSurfacePtr = currentWlSurfacePtr;
}
/**
* Notifies the InputContext that a set of changes has been sent and committed to the compositor
* via a {@code zwp_text_input_v3::commit} request. The InputContext reacts by incrementing its commit counter.
*
* @param changes represents the set of changes that have been sent and followed by a 'commit' request.
* Must not be {@code null} (but can be empty, which means only the 'commit' request has been issued).
*
* @return a new instance of {@link OutgoingBeingCommittedChanges} consisting of
* the passed changes and the new value of the commit counter.
*
* @throws NullPointerException if {@code changes} is {@code null}.
*
* @see OutgoingChanges
*/
public OutgoingBeingCommittedChanges syncWithCommittedOutgoingChanges(final OutgoingChanges changes) {
Objects.requireNonNull(changes, "changes");
// zwp_text_input_v3::done natively uses uint32_t for the serial,
// so it can't get greater than 0xFFFFFFFF.
this.commitCounter = (this.commitCounter + 1) % 0x100000000L;
return new OutgoingBeingCommittedChanges(changes, this.commitCounter);
}
public long getCommitCounter() {
return commitCounter;
}
/**
* This class represents the extended state of an {@code InputContextState} that only exists when the context
* is enabled.
*
* @param textChangeCause the property set via a {@code zwp_text_input_v3::set_text_change_cause} request. Must not be {@code null}.
* @param contentHint the property set via a {@code zwp_text_input_v3::set_content_type} request.
* @param contentPurpose the property set via a {@code zwp_text_input_v3::set_content_type} request. Must not be {@code null}.
* @param cursorRectangle the property set via a {@code zwp_text_input_v3::set_cursor_rectangle} request.
* {@code null} means "the text input does not support describing the cursor area".
*/
public record StateOfEnabled(
// zwp_text_input_v3::set_text_change_cause
ChangeCause textChangeCause,
// zwp_text_input_v3::set_content_type.hint
int contentHint,
// zwp_text_input_v3::set_content_type.purpose
ContentPurpose contentPurpose,
// zwp_text_input_v3::set_cursor_rectangle
Rectangle cursorRectangle
) {
public StateOfEnabled {
Objects.requireNonNull(textChangeCause, "textChangeCause");
Objects.requireNonNull(contentPurpose, "contentPurpose");
}
}
public StateOfEnabled getCurrentStateOfEnabled() {
return stateOfEnabled;
}
public boolean isEnabled() {
return getCurrentStateOfEnabled() != null;
}
/**
* NB: if you want to call setEnabledState(null), consider using {@code wlHandleContextGotDisabled()} of
* the owning {@link WLInputMethodZwpTextInputV3}.
*
* @param newState {@code null} to mark the InputContext as disabled,
* otherwise the InputContext will be marked as enabled and having the state as
* specified in the parameter.
*/
public void setEnabledState(StateOfEnabled newState) {
this.stateOfEnabled = newState;
}
public void syncWithAppliedIncomingChanges(final JavaPreeditString appliedPreeditString, final JavaCommitString appliedCommitString, final long doneSerial) {
this.latestAppliedPreeditString = Objects.requireNonNull(appliedPreeditString, "appliedPreeditString");
this.latestAppliedCommitString = Objects.requireNonNull(appliedCommitString, "appliedCommitString");
this.latestDoneSerial = doneSerial;
}
public JavaPreeditString getLatestAppliedPreeditString() {
return latestAppliedPreeditString;
}
public JavaCommitString getLatestAppliedCommitString() {
return latestAppliedCommitString;
}
public long getLatestDoneSerial() {
return latestDoneSerial;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder(512);
sb.append("InputContextState@").append(System.identityHashCode(this));
sb.append('{');
sb.append("nativeContextPtr=0x").append(Long.toHexString(nativeContextPtr));
sb.append(", currentWlSurfacePtr=0x").append(Long.toHexString(currentWlSurfacePtr));
sb.append(", commitCounter=").append(commitCounter);
sb.append(", latestDoneSerial=").append(latestDoneSerial);
sb.append(", stateOfEnabled=").append(stateOfEnabled);
sb.append(", latestAppliedPreeditString=").append(latestAppliedPreeditString);
sb.append(", latestAppliedCommitString=").append(latestAppliedCommitString);
sb.append('}');
return sb.toString();
}
// zwp_text_input_v3::enter.surface / zwp_text_input_v3::leave.surface
private long currentWlSurfacePtr = 0;
// zwp_text_input_v3::commit
/**
* How many times changes to this context have been committed (through {@code zwp_text_input_v3::commit}).
* Essentially, it means the most actual version of the context's state.
*/
private long commitCounter = 0;
// zwp_text_input_v3::done.serial
/**
* The {@code serial} parameter of the latest {@code zwp_text_input_v3::done} event received.
* Essentially, it means the latest version of the context's state known/confirmed by the compositor.
*/
private long latestDoneSerial = 0;
/** {@code null} if the InputContextState is disabled. */
private StateOfEnabled stateOfEnabled = null;
/**
* The latest preedit string applied as a result of the latest {@code zwp_text_input_v3::done} event received.
* Must never be {@code null} ; if a {@code zwp_text_input_v3::done} event wasn't preceded by a
* {@code zwp_text_input_v3::preedit_string} event, the field should be set to {@link PropertiesInitials#PREEDIT_STRING}.
*/
private JavaPreeditString latestAppliedPreeditString = PropertiesInitials.PREEDIT_STRING;
/**
* The latest commit string applied as a result of the latest {@code zwp_text_input_v3::done} event received.
* Must never be {@code null} ; if a {@code zwp_text_input_v3::done} event wasn't preceded by a
* {@code zwp_text_input_v3::commit_string} event, the field should be set to {@link PropertiesInitials#COMMIT_STRING}.
*/
private JavaCommitString latestAppliedCommitString = PropertiesInitials.COMMIT_STRING;
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import java.util.Objects;
record JavaCommitString(String text) {
public JavaCommitString {
Objects.requireNonNull(text, "text");
}
public static final JavaCommitString EMPTY = new JavaCommitString("");
/** Never returns {@code null}. */
public static JavaCommitString fromWaylandCommitString(byte[] utf8Bytes) {
return new JavaCommitString(Utilities.utf8BytesToJavaString(utf8Bytes));
}
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import java.util.Objects;
/**
* This class represents the result of a conversion of a UTF-8 preedit string received in a
* {@code zwp_text_input_v3::preedit_string} event to a Java UTF-16 string.
* If {@link #cursorBeginCodeUnit} and/or {@link #cursorEndCodeUnit} point at UTF-16 surrogate pairs,
* they're guaranteed to point at the very beginning of them as long as {@link #fromWaylandPreeditString} is
* used to perform the conversion.
* <p>
* {@link #fromWaylandPreeditString} never returns {@code null}.
* <p>
* See the specification of {@code zwp_text_input_v3::preedit_string} event for more info about
* cursor_begin, cursor_end values.
*
* @param text The preedit text string. Mustn't be {@code null} (use an empty string instead).
* @param cursorBeginCodeUnit UTF-16 equivalent of {@code preedit_string.cursor_begin}.
* @param cursorEndCodeUnit UTF-16 equivalent of {@code preedit_string.cursor_end}.
* It's not explicitly stated in the protocol specification, but it seems to be a valid
* situation when cursor_end < cursor_begin, which means
* the highlight extends to the right from the caret
* (e.g., when the text gets selected with Shift + Left Arrow).
*/
record JavaPreeditString(String text, int cursorBeginCodeUnit, int cursorEndCodeUnit) {
public JavaPreeditString {
Objects.requireNonNull(text, "text");
}
public static final JavaPreeditString EMPTY = new JavaPreeditString("", 0, 0);
public static final JavaPreeditString EMPTY_NO_CARET = new JavaPreeditString("", -1, -1);
public static JavaPreeditString fromWaylandPreeditString(
final byte[] utf8Bytes,
final int cursorBeginUtf8Byte,
final int cursorEndUtf8Byte
) {
// Java's UTF-8 -> UTF-16 conversion doesn't like trailing NUL codepoints, so let's trim them
final int utf8BytesWithoutNulLength = Utilities.getLengthOfUtf8BytesWithoutTrailingNULs(utf8Bytes);
// cursorBeginUtf8Byte, cursorEndUtf8Byte normalized relatively to the valid values range.
final int fixedCursorBeginUtf8Byte;
final int fixedCursorEndUtf8Byte;
if (cursorBeginUtf8Byte < 0 || cursorEndUtf8Byte < 0) {
fixedCursorBeginUtf8Byte = fixedCursorEndUtf8Byte = -1;
} else {
// 0 <= cursorBeginUtf8Byte <= fixedCursorBeginUtf8Byte <= utf8BytesWithoutNulLength
fixedCursorBeginUtf8Byte = Math.min(cursorBeginUtf8Byte, utf8BytesWithoutNulLength);
// 0 <= cursorEndUtf8Byte <= fixedCursorEndUtf8Byte <= utf8BytesWithoutNulLength
fixedCursorEndUtf8Byte = Math.min(cursorEndUtf8Byte, utf8BytesWithoutNulLength);
}
final var resultText = Utilities.utf8BytesToJavaString(utf8Bytes, 0, utf8BytesWithoutNulLength);
if (fixedCursorBeginUtf8Byte < 0 || fixedCursorEndUtf8Byte < 0) {
return new JavaPreeditString(resultText, -1, -1);
}
if (resultText == null) {
assert(fixedCursorBeginUtf8Byte == 0);
assert(fixedCursorEndUtf8Byte == 0);
return JavaPreeditString.EMPTY;
}
final String javaPrefixBeforeCursorBegin = (fixedCursorBeginUtf8Byte == 0)
? ""
: Utilities.utf8BytesToJavaString(utf8Bytes, 0, fixedCursorBeginUtf8Byte);
final String javaPrefixBeforeCursorEnd = (fixedCursorEndUtf8Byte == 0)
? ""
: Utilities.utf8BytesToJavaString(utf8Bytes, 0, fixedCursorEndUtf8Byte);
return new JavaPreeditString(
resultText,
javaPrefixBeforeCursorBegin.length(),
javaPrefixBeforeCursorEnd.length()
);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import java.util.Objects;
/**
* This class is intended to keep changes after they get committed and until they actually get applied.
*
* @param changeSet changes that have been sent and committed to the compositor,
* but not yet confirmed by it (via a {@code zwp_text_input_v3::done} event).
* Must not be {@code null}.
* @param commitCounter the number of times a {@code zwp_text_input_v3::commit} request has been issued to
* the corresponding {@link InputContextState}.
*
* @see OutgoingChanges
*/
record OutgoingBeingCommittedChanges(OutgoingChanges changeSet, long commitCounter) {
public OutgoingBeingCommittedChanges {
Objects.requireNonNull(changeSet, "changeSet");
}
}

View File

@@ -0,0 +1,166 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import java.awt.Rectangle;
import java.util.Objects;
/**
* This class is intended to accumulate changes for an {@link InputContextState} until
* they're sent via the set of requests
* {@code zwp_text_input_v3::enable}, {@code zwp_text_input_v3::disable}, {@code zwp_text_input_v3::set_*}
* and commited via {@code zwp_text_input_v3::commit}.
* <p>
* The reason of having to accumulate changes instead of applying them as soon as they appear is the following
* part of the {@code zpw_text_input_v3::done(serial)} event specification:
* {@code
* When the client receives a done event with a serial different than the number of past commit requests,
* it must proceed with evaluating and applying the changes as normal, except it should not change the
* current state of the zwp_text_input_v3 object. All pending state requests [...]
* on the zwp_text_input_v3 object should be sent and committed after receiving a
* zwp_text_input_v3.done event with a matching serial.
* }
*<p>
* All the properties this class includes are nullable where {@code null} means absence of this property change.
* In other words, if a property is null, the corresponding {@code zwp_text_input_v3::set_...} shouldn't be
* called when processing this instance of OutgoingChanges.
* <p>
* The modifier methods return {@code this} for method chaining.
*/
final class OutgoingChanges
{
// zwp_text_input_v3::enable / zwp_text_input_v3::disable
private Boolean newEnabled = null;
// zwp_text_input_v3::set_text_change_cause
private ChangeCause newTextChangeCause = null;
// zwp_text_input_v3::set_content_type
private Integer newContentTypeHint = null;
private ContentPurpose newContentTypePurpose = null;
// zwp_text_input_v3::set_cursor_rectangle
private Rectangle newCursorRectangle = null;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder(256);
sb.append("OutgoingChanges@").append(System.identityHashCode(this));
sb.append('[');
sb.append("newEnabled=").append(newEnabled);
sb.append(", newTextChangeCause=").append(newTextChangeCause);
sb.append(", newContentTypeHint=").append(newContentTypeHint);
sb.append(", newContentTypePurpose=").append(newContentTypePurpose);
sb.append(", newCursorRectangle=").append(newCursorRectangle);
sb.append(']');
return sb.toString();
}
public OutgoingChanges setEnabledState(Boolean newEnabled) {
this.newEnabled = newEnabled;
return this;
}
public Boolean getEnabledState() { return newEnabled; }
public OutgoingChanges setTextChangeCause(ChangeCause newTextChangeCause) {
this.newTextChangeCause = newTextChangeCause;
return this;
}
public ChangeCause getTextChangeCause() { return newTextChangeCause; }
/**
* Both parameters have to be {@code null} or not null simultaneously.
*
* @throws NullPointerException if one of the parameters is {@code null} while the other one is not.
*/
public OutgoingChanges setContentType(Integer newContentTypeHint, ContentPurpose newContentTypePurpose) {
if (newContentTypeHint == null && newContentTypePurpose == null) {
this.newContentTypeHint = null;
this.newContentTypePurpose = null;
} else {
final var contentHintAllMask =
ContentHint.NONE.intMask |
ContentHint.COMPLETION.intMask |
ContentHint.SPELLCHECK.intMask |
ContentHint.AUTO_CAPITALIZATION.intMask |
ContentHint.LOWERCASE.intMask |
ContentHint.UPPERCASE.intMask |
ContentHint.TITLECASE.intMask |
ContentHint.HIDDEN_TEXT.intMask |
ContentHint.SENSITIVE_DATA.intMask |
ContentHint.LATIN.intMask |
ContentHint.MULTILINE.intMask;
if ( (Objects.requireNonNull(newContentTypeHint, "newContentTypeHint") & ~contentHintAllMask) != 0 ) {
throw new IllegalArgumentException(String.format("newContentTypeHint=%d has invalid bits set", newContentTypeHint));
}
this.newContentTypeHint = newContentTypeHint;
this.newContentTypePurpose = Objects.requireNonNull(newContentTypePurpose, "newContentTypePurpose");
}
return this;
}
public Integer getContentTypeHint() { return newContentTypeHint; }
public ContentPurpose getContentTypePurpose() { return newContentTypePurpose; }
public OutgoingChanges setCursorRectangle(Rectangle newCursorRectangle) {
this.newCursorRectangle = newCursorRectangle;
return this;
}
public Rectangle getCursorRectangle() { return newCursorRectangle; }
public OutgoingChanges appendChangesFrom(OutgoingChanges src) {
if (src == null) return this;
if (getTextChangeCause() == null) {
setTextChangeCause(src.getTextChangeCause());
}
if (getContentTypeHint() == null) {
setContentType(src.getContentTypeHint(), src.getContentTypePurpose());
}
if (getCursorRectangle() == null) {
setCursorRectangle(src.getCursorRectangle());
}
return this;
}
public boolean isEmpty() {
return (getEnabledState() == null && getTextChangeCause() == null && getContentTypeHint() == null && getCursorRectangle() == null);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import java.awt.Rectangle;
interface PropertiesInitials {
/** {@code zwp_text_input_v3::set_text_change_cause} */
ChangeCause TEXT_CHANGE_CAUSE = ChangeCause.INPUT_METHOD;
/** {@code zwp_text_input_v3::set_content_type} (hint) */
int CONTENT_HINT = ContentHint.NONE.intMask;
/** {@code zwp_text_input_v3::set_content_type} (purpose) */
ContentPurpose CONTENT_PURPOSE = ContentPurpose.NORMAL;
/**
* {@code zwp_text_input_v3::set_cursor_rectangle}.
* <p>
* The initial values describing a cursor rectangle are empty.
* That means the text input does not support describing the cursor area.
* If the empty values get applied, subsequent attempts to change them may have no effect.
*/
Rectangle CURSOR_RECTANGLE = null;
/** {@code zwp_text_input_v3::preedit_string} */
JavaPreeditString PREEDIT_STRING = new JavaPreeditString("", 0, 0);
/** {@code zwp_text_input_v3::commit_string} */
JavaCommitString COMMIT_STRING = new JavaCommitString("");
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import java.nio.charset.StandardCharsets;
interface Utilities {
static int getLengthOfUtf8BytesWithoutTrailingNULs(final byte[] utf8Bytes) {
int lastNonNulIndex = (utf8Bytes == null) ? -1 : utf8Bytes.length - 1;
for (; lastNonNulIndex >= 0; --lastNonNulIndex) {
if (utf8Bytes[lastNonNulIndex] != 0) {
break;
}
}
return (lastNonNulIndex < 0) ? 0 : lastNonNulIndex + 1;
}
static String utf8BytesToJavaString(final byte[] utf8Bytes) {
if (utf8Bytes == null) {
return "";
}
return utf8BytesToJavaString(
utf8Bytes,
0,
// Java's UTF-8 -> UTF-16 conversion doesn't like trailing NUL codepoints, so let's trim them
getLengthOfUtf8BytesWithoutTrailingNULs(utf8Bytes)
);
}
static String utf8BytesToJavaString(final byte[] utf8Bytes, final int offset, final int length) {
return utf8Bytes == null ? "" : new String(utf8Bytes, offset, length, StandardCharsets.UTF_8);
}
}

View File

@@ -0,0 +1,203 @@
/*
* Copyright 2025 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.
*/
package sun.awt.wl.im.text_input_unstable_v3;
import sun.awt.wl.WLToolkit;
import sun.util.logging.PlatformLogger;
import java.awt.AWTException;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.im.spi.InputMethod;
import java.awt.im.spi.InputMethodDescriptor;
import java.util.Locale;
public final class WLInputMethodDescriptorZwpTextInputV3 implements InputMethodDescriptor {
// See java.text.MessageFormat for the formatting syntax
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.im.text_input_unstable_v3.WLInputMethodDescriptorZwpTextInputV3");
public static boolean isAvailableOnPlatform() {
return initAndGetIsAvailableOnPlatform();
}
public static WLInputMethodDescriptorZwpTextInputV3 getInstanceIfAvailableOnPlatform() {
if (!isAvailableOnPlatform()) {
return null;
}
return new WLInputMethodDescriptorZwpTextInputV3();
}
/* java.awt.im.spi.InputMethodDescriptor methods section */
@Override
public Locale[] getAvailableLocales() throws AWTException {
ensureIsAvailableOnPlatform();
return getAvailableLocalesInternal();
}
@Override
public boolean hasDynamicLocaleList() {
// Since the return value of {@link #getAvailableLocales()} doesn't currently change over time,
// it doesn't make sense to return true here.
return false;
}
@Override
public String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage) {
assert isAvailableOnPlatform();
// This is how it's implemented in all other Toolkits.
//
// We ignore the input locale.
// When displaying for the default locale, rely on the localized AWT properties;
// for any other locale, fall back to English.
String name = "System Input Methods";
if (Locale.getDefault().equals(displayLanguage)) {
name = Toolkit.getProperty("AWT.HostInputMethodDisplayName", name);
}
return name;
}
@Override
public Image getInputMethodIcon(Locale inputLocale) {
return null;
}
@Override
public InputMethod createInputMethod() throws Exception {
// NB: we should avoid returning null from this method because the calling code isn't really ready to get null
ensureIsAvailableOnPlatform();
final var result = new WLInputMethodZwpTextInputV3();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("createInputMethod(): result={0}.", result);
}
return result;
}
/* java.lang.Object methods section */
@Override
public String toString() {
return String.format("WLInputMethodDescriptorZwpTextInputV3@%d", System.identityHashCode(this));
}
/* Implementation details section */
/** Used as the return value for {@link #getAvailableLocales()}. */
private volatile static Locale toolkitStartupLocale = null;
private volatile static Boolean isAvailableOnPlatform = null;
static Locale[] getAvailableLocalesInternal() {
// This is how it's implemented in XToolkit.
//
// A better implementation would be obtaining all currently installed and enabled input sources
// (like on GNOME Settings -> Keyboard -> Input Sources) and mapping them to locales.
// However, there seem no universal Wayland API for that, so it seems can't be implemented reliably.
//
// So leaving as is at the moment.
//
// TODO: research how to implement this better along with {@link #hasDynamicLocaleList}
return new Locale[]{ (Locale)initAndGetToolkitStartupLocale().clone() };
}
private static Locale initAndGetToolkitStartupLocale() {
if (toolkitStartupLocale == null) {
synchronized (WLInputMethodDescriptorZwpTextInputV3.class) {
if (toolkitStartupLocale == null) {
toolkitStartupLocale = WLToolkit.getStartupLocale();
}
}
}
if (log.isLoggable(PlatformLogger.Level.CONFIG)) {
log.config("initAndGetToolkitStartupLocale(): toolkitStartupLocale={0}.", toolkitStartupLocale);
}
return toolkitStartupLocale;
}
private static boolean initAndGetIsAvailableOnPlatform() {
if (isAvailableOnPlatform == null) {
synchronized (WLInputMethodDescriptorZwpTextInputV3.class) {
try {
if (isAvailableOnPlatform == null) {
isAvailableOnPlatform = checkIfAvailableOnPlatform();
}
} catch (Exception err) {
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
log.warning("Failed to check whether the IM protocol is supported on the system", err);
}
isAvailableOnPlatform = false;
}
}
}
if (log.isLoggable(PlatformLogger.Level.CONFIG)) {
log.config("initAndGetIsAvailableOnPlatform(): isAvailableOnPlatform={0}.", isAvailableOnPlatform);
}
return isAvailableOnPlatform;
}
private static void ensureIsAvailableOnPlatform() throws AWTException {
if (!isAvailableOnPlatform()) {
throw new AWTException("sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3 is not supported on this system");
}
}
private WLInputMethodDescriptorZwpTextInputV3() {
assert isAvailableOnPlatform();
initAndGetToolkitStartupLocale();
}
/* JNI downcalls section */
/**
* This method checks if {@link WLInputMethodZwpTextInputV3} can function on this system.
* Basically, it means the Wayland compositor supports a minimal sufficient subset of the required protocols
* (currently the set only includes the "text-input-unstable-v3" protocol).
*
* @return true if {@link WLInputMethodZwpTextInputV3} can function on this system, false otherwise.
* @see <a href="https://wayland.app/protocols/text-input-unstable-v3">text-input-unstable-v3</a>
*/
private static native boolean checkIfAvailableOnPlatform();
}

View File

@@ -47,11 +47,8 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
private final VKGraphicsConfig offscreenConfig;
public WLVKGraphicsConfig(VKGraphicsConfig offscreenConfig, WLGraphicsDevice device,
int x, int y, int xLogical, int yLogical,
int width, int height, int widthLogical, int heightLogical,
int scale) {
super(device, x, y, xLogical, yLogical, width, height, widthLogical, heightLogical, scale);
public WLVKGraphicsConfig(VKGraphicsConfig offscreenConfig, WLGraphicsDevice device) {
super(device);
this.offscreenConfig = offscreenConfig;
}
@@ -65,11 +62,8 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
return getEffectiveScale();
}
public static WLVKGraphicsConfig getConfig(VKGraphicsConfig offscreenConfig, WLGraphicsDevice device,
int x, int y, int xLogical, int yLogical,
int width, int height, int widthLogical, int heightLogical,
int scale) {
return new WLVKGraphicsConfig(offscreenConfig, device, x, y, xLogical, yLogical, width, height, widthLogical, heightLogical, scale);
public static WLVKGraphicsConfig getConfig(VKGraphicsConfig offscreenConfig, WLGraphicsDevice device) {
return new WLVKGraphicsConfig(offscreenConfig, device);
}
@Override

View File

@@ -643,8 +643,19 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_GtkFrameDecoration_nativePaintTitleBar
jint pixel_width = ceil(width * scale);
jint pixel_height = ceil(height * scale);
jboolean is_copy = JNI_FALSE;
const char *title_c_str = "";
if (title) {
title_c_str = JNU_GetStringPlatformChars(env, title, &is_copy);
if (!title_c_str)
return;
}
unsigned char *buffer = (*env)->GetPrimitiveArrayCritical(env, dest, 0);
if (!buffer) {
if (is_copy) {
JNU_ReleaseStringPlatformChars(env, title, title_c_str);
}
JNU_ThrowOutOfMemoryError(env, "Could not get image buffer");
return;
}
@@ -660,25 +671,19 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_GtkFrameDecoration_nativePaintTitleBar
cairo_t *cr = p_cairo_create(surface);
jboolean is_copy = JNI_FALSE;
const char *title_c_str = "";
if (title) {
title_c_str = JNU_GetStringPlatformChars(env, title, &is_copy);
if (!title_c_str)
return;
}
draw_title_bar(decor, surface, cr, width, height, scale, title_c_str, buttonsState);
if (is_copy) {
JNU_ReleaseStringPlatformChars(env, title, title_c_str);
}
// Make sure pixels have been flush into the underlying buffer
p_cairo_surface_flush(surface);
p_gdk_threads_leave();
(*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0);
if (is_copy) {
JNU_ReleaseStringPlatformChars(env, title, title_c_str);
}
p_cairo_destroy(cr);
p_cairo_surface_destroy(surface);
}

View File

@@ -26,6 +26,7 @@
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <pthread.h>
#include "JNIUtilities.h"
#include "WLToolkit.h"
@@ -34,7 +35,6 @@
#include "sun_awt_wl_WLDataOffer.h"
#include "wayland-client-protocol.h"
// Types
enum DataTransferProtocol
@@ -43,6 +43,9 @@ enum DataTransferProtocol
DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION = sun_awt_wl_WLDataDevice_DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION,
};
struct DataSource;
struct DataOffer;
// native part of WLDataDevice, one instance per seat
// seat's wl_data_device and zwp_primary_selection_device_v1 have user pointers to this struct
struct DataDevice
@@ -54,12 +57,20 @@ struct DataDevice
struct wl_event_queue *dataSourceQueue;
struct wl_data_device *wlDataDevice;
struct zwp_primary_selection_device_v1 *zwpPrimarySelectionDevice;
pthread_mutex_t sourceDelMutex;
struct DataSource* sourceDelQueue;
pthread_mutex_t offerDelMutex;
struct DataOffer* offerDelQueue;
};
// native part of WLDataSource, remains alive until WLDataSource.destroy() is called
// pointer to this structure is the wl_data_source's (zwp_primary_selection_source_v1's) user pointer
struct DataSource
{
struct DataDevice* dataDevice;
enum DataTransferProtocol protocol;
// global reference to the corresponding WLDataSource object
// destroyed in WLDataSource.destroy()
@@ -75,12 +86,16 @@ struct DataSource
struct wl_surface* dragIcon;
struct wl_buffer* dragIconBuffer;
struct DataSource* nextDel;
};
// native part of WLDataOffer, remains alive until WLDataOffer.destroy() is called
// pointer to this structure is the wl_data_offer's (zwp_primary_selection_offer_v1's) user pointer
struct DataOffer
{
struct DataDevice* dataDevice;
enum DataTransferProtocol protocol;
// global reference to the corresponding WLDataOffer object
// destroyed in WLDataOffer.destroy()
@@ -93,6 +108,8 @@ struct DataOffer
struct wl_data_offer *wlDataOffer;
struct zwp_primary_selection_offer_v1 *zwpPrimarySelectionOffer;
};
struct DataOffer* nextDel;
};
// Java refs
@@ -271,9 +288,6 @@ DataSource_setDnDActions(const struct DataSource *source, uint32_t actions);
static struct DataOffer *
DataOffer_create(struct DataDevice *dataDevice, enum DataTransferProtocol protocol, void *waylandObject);
static void
DataOffer_destroy(struct DataOffer *offer);
static void
DataOffer_receive(struct DataOffer *offer, const char *mime, int fd);
@@ -317,10 +331,13 @@ static struct DataOffer *
DataOffer_create(struct DataDevice *dataDevice, enum DataTransferProtocol protocol, void *waylandObject)
{
struct DataOffer *offer = calloc(1, sizeof(struct DataOffer));
if (offer == NULL) {
return NULL;
}
offer->dataDevice = dataDevice;
JNIEnv *env = getEnv();
assert(env != NULL);
@@ -334,7 +351,7 @@ DataOffer_create(struct DataDevice *dataDevice, enum DataTransferProtocol protoc
return NULL;
}
// Cleared in DataOffer_destroy
// Cleared in DataOffer.destroy()
jobject globalRef = (*env)->NewGlobalRef(env, obj);
EXCEPTION_CLEAR(env);
@@ -345,50 +362,23 @@ DataOffer_create(struct DataDevice *dataDevice, enum DataTransferProtocol protoc
}
offer->javaObject = globalRef;
offer->protocol = protocol;
if (protocol == DATA_TRANSFER_PROTOCOL_WAYLAND) {
struct wl_data_offer *wlDataOffer = waylandObject;
wl_data_offer_add_listener(wlDataOffer, &wlDataOfferListener, offer);
offer->wlDataOffer = wlDataOffer;
offer->protocol = DATA_TRANSFER_PROTOCOL_WAYLAND;
wl_data_offer_add_listener(wlDataOffer, &wlDataOfferListener, offer);
}
if (protocol == DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION) {
struct zwp_primary_selection_offer_v1 *zwpPrimarySelectionOffer = waylandObject;
zwp_primary_selection_offer_v1_add_listener(zwpPrimarySelectionOffer, &zwpPrimarySelectionOfferListener, offer);
offer->zwpPrimarySelectionOffer = zwpPrimarySelectionOffer;
offer->protocol = DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION;
zwp_primary_selection_offer_v1_add_listener(zwpPrimarySelectionOffer, &zwpPrimarySelectionOfferListener, offer);
}
return offer;
}
static void
DataOffer_destroy(struct DataOffer *offer)
{
if (offer == NULL) {
return;
}
if (offer->javaObject != NULL) {
JNIEnv *env = getEnv();
assert(env != NULL);
(*env)->DeleteGlobalRef(env, offer->javaObject);
offer->javaObject = NULL;
}
if (offer->protocol == DATA_TRANSFER_PROTOCOL_WAYLAND) {
wl_data_offer_destroy(offer->wlDataOffer);
} else if (offer->protocol == DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION) {
zwp_primary_selection_offer_v1_destroy(offer->zwpPrimarySelectionOffer);
}
free(offer);
}
static void
DataOffer_receive(struct DataOffer *offer, const char *mime, int fd)
{
@@ -462,6 +452,68 @@ DataOffer_callSelectionHandler(struct DataDevice *dataDevice, struct DataOffer *
EXCEPTION_CLEAR(env);
}
static void
DataDevice_drainSourceDeletionQueue(struct DataDevice *dataDevice, JNIEnv* env) {
pthread_mutex_lock(&dataDevice->sourceDelMutex);
struct DataSource* source = dataDevice->sourceDelQueue;
while (source != NULL) {
if (source->protocol == DATA_TRANSFER_PROTOCOL_WAYLAND) {
wl_data_source_destroy(source->wlDataSource);
} else if (source->protocol == DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION) {
zwp_primary_selection_source_v1_destroy(source->zwpPrimarySelectionSource);
}
if (source->dragIconBuffer) {
wl_buffer_destroy(source->dragIconBuffer);
}
if (source->dragIcon) {
wl_surface_destroy(source->dragIcon);
}
if (source->javaObject != NULL) {
(*env)->DeleteGlobalRef(env, source->javaObject);
}
struct DataSource* next = source->nextDel;
free(source);
source = next;
}
dataDevice->sourceDelQueue = NULL;
pthread_mutex_unlock(&dataDevice->sourceDelMutex);
}
static void
DataDevice_drainOfferDeletionQueue(struct DataDevice *dataDevice, JNIEnv* env) {
pthread_mutex_lock(&dataDevice->offerDelMutex);
struct DataOffer* offer = dataDevice->offerDelQueue;
while (offer != NULL) {
if (offer->protocol == DATA_TRANSFER_PROTOCOL_WAYLAND) {
wl_data_offer_destroy(offer->wlDataOffer);
} else if (offer->protocol == DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION) {
zwp_primary_selection_offer_v1_destroy(offer->zwpPrimarySelectionOffer);
}
if (offer->javaObject != NULL) {
(*env)->DeleteGlobalRef(env, offer->javaObject);
}
struct DataOffer* next = offer->nextDel;
free(offer);
offer = next;
}
dataDevice->offerDelQueue = NULL;
pthread_mutex_unlock(&dataDevice->offerDelMutex);
}
// Event handlers
static void
@@ -824,6 +876,9 @@ Java_sun_awt_wl_WLDataDevice_initNative(JNIEnv *env, jobject obj, jlong wlSeatPt
return 0;
}
pthread_mutex_init(&dataDevice->sourceDelMutex, NULL);
pthread_mutex_init(&dataDevice->offerDelMutex, NULL);
dataDevice->javaObject = (*env)->NewGlobalRef(env, obj);
if ((*env)->ExceptionCheck(env)) {
goto error_cleanup;
@@ -865,7 +920,10 @@ Java_sun_awt_wl_WLDataDevice_initNative(JNIEnv *env, jobject obj, jlong wlSeatPt
return ptr_to_jlong(dataDevice);
error_cleanup:
error_cleanup:
pthread_mutex_destroy(&dataDevice->sourceDelMutex);
pthread_mutex_destroy(&dataDevice->offerDelMutex);
if (dataDevice->dataSourceQueue != NULL) {
wl_event_queue_destroy(dataDevice->dataSourceQueue);
}
@@ -912,6 +970,7 @@ Java_sun_awt_wl_WLDataDevice_dispatchDataSourceQueueImpl(JNIEnv *env, jclass cla
assert(dataDevice != NULL);
while (wl_display_dispatch_queue(wl_display, dataDevice->dataSourceQueue) != -1) {
DataDevice_drainSourceDeletionQueue(dataDevice, env);
}
}
@@ -955,27 +1014,36 @@ Java_sun_awt_wl_WLDataDevice_startDragImpl(JNIEnv *env, jclass clazz, jlong data
}
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLDataDevice_performDeletionsOnEDTImpl(JNIEnv *env, jclass clazz, jlong dataDeviceNativePtr) {
struct DataDevice *dataDevice = jlong_to_ptr(dataDeviceNativePtr);
assert(dataDevice != NULL);
DataDevice_drainOfferDeletionQueue(dataDevice, env);
}
JNIEXPORT jlong JNICALL
Java_sun_awt_wl_WLDataSource_initNative(JNIEnv *env, jobject javaObject, jlong dataDeviceNativePtr, jint protocol)
{
struct DataDevice *dataDevice = jlong_to_ptr(dataDeviceNativePtr);
assert(dataDevice != NULL);
struct DataSource *dataSource = calloc(1, sizeof(struct DataSource));
struct DataSource *source = calloc(1, sizeof(struct DataSource));
if (dataSource == NULL) {
if (source == NULL) {
JNU_ThrowOutOfMemoryError(env, "Failed to allocate DataSource");
return 0;
}
source->dataDevice = dataDevice;
// cleaned up in WLDataSource.destroy()
dataSource->javaObject = (*env)->NewGlobalRef(env, javaObject);
source->javaObject = (*env)->NewGlobalRef(env, javaObject);
if ((*env)->ExceptionCheck(env)) {
free(dataSource);
free(source);
return 0;
}
if (dataSource->javaObject == NULL) {
free(dataSource);
if (source->javaObject == NULL) {
free(source);
JNU_ThrowInternalError(env, "Failed to create a reference to WLDataSource");
return 0;
}
@@ -984,39 +1052,56 @@ Java_sun_awt_wl_WLDataSource_initNative(JNIEnv *env, jobject javaObject, jlong d
protocol = DATA_TRANSFER_PROTOCOL_WAYLAND;
}
source->protocol = protocol;
if (protocol == DATA_TRANSFER_PROTOCOL_WAYLAND) {
struct wl_data_source *wlDataSource = wl_data_device_manager_create_data_source(wl_ddm);
// To avoid race conditions when setting the dispatch queue,
// it's necessary to do this dance with wl_proxy_create_wrapper.
// See the docs for wl_proxy_create_wrapper for more details
struct wl_data_device_manager* dmWrapper = wl_proxy_create_wrapper(wl_ddm);
struct wl_data_source *wlDataSource = NULL;
if (dmWrapper != NULL) {
wl_proxy_set_queue((struct wl_proxy *) dmWrapper, dataDevice->dataSourceQueue);
wlDataSource = wl_data_device_manager_create_data_source(dmWrapper);
wl_proxy_wrapper_destroy(dmWrapper);
}
if (wlDataSource == NULL) {
free(dataSource);
free(source);
JNU_ThrowByName(env, "java/awt/AWTError", "Wayland error creating wl_data_source proxy");
return 0;
}
wl_proxy_set_queue((struct wl_proxy *) wlDataSource, dataDevice->dataSourceQueue);
wl_data_source_add_listener(wlDataSource, &wl_data_source_listener, dataSource);
source->wlDataSource = wlDataSource;
dataSource->protocol = DATA_TRANSFER_PROTOCOL_WAYLAND;
dataSource->wlDataSource = wlDataSource;
wl_data_source_add_listener(wlDataSource, &wl_data_source_listener, source);
}
if (protocol == DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION) {
struct zwp_primary_selection_source_v1 *zwpPrimarySelectionSource =
zwp_primary_selection_device_manager_v1_create_source(zwp_selection_dm);
struct zwp_primary_selection_device_manager_v1 *dmWrapper = wl_proxy_create_wrapper(zwp_selection_dm);
struct zwp_primary_selection_source_v1 *zwpPrimarySelectionSource = NULL;
if (dmWrapper != NULL) {
wl_proxy_set_queue((struct wl_proxy *) dmWrapper, dataDevice->dataSourceQueue);
zwpPrimarySelectionSource = zwp_primary_selection_device_manager_v1_create_source(dmWrapper);
wl_proxy_wrapper_destroy(dmWrapper);
}
if (zwpPrimarySelectionSource == NULL) {
free(dataSource);
free(source);
JNU_ThrowByName(env, "java/awt/AWTError", "Wayland error creating zwp_primary_selection_source_v1 proxy");
return 0;
}
wl_proxy_set_queue((struct wl_proxy *) zwpPrimarySelectionSource, dataDevice->dataSourceQueue);
zwp_primary_selection_source_v1_add_listener(zwpPrimarySelectionSource,
&zwp_primary_selection_source_v1_listener, dataSource);
source->zwpPrimarySelectionSource = zwpPrimarySelectionSource;
dataSource->protocol = DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION;
dataSource->zwpPrimarySelectionSource = zwpPrimarySelectionSource;
zwp_primary_selection_source_v1_add_listener(zwpPrimarySelectionSource,
&zwp_primary_selection_source_v1_listener, source);
}
return ptr_to_jlong(dataSource);
return ptr_to_jlong(source);
}
JNIEXPORT void JNICALL
@@ -1040,26 +1125,13 @@ Java_sun_awt_wl_WLDataSource_destroyImpl(JNIEnv *env, jclass clazz, jlong native
return;
}
if (source->javaObject != NULL) {
(*env)->DeleteGlobalRef(env, source->javaObject);
source->javaObject = NULL;
}
assert(source->dataDevice != NULL);
struct DataDevice* dataDevice = source->dataDevice;
if (source->protocol == DATA_TRANSFER_PROTOCOL_WAYLAND) {
wl_data_source_destroy(source->wlDataSource);
} else if (source->protocol == DATA_TRANSFER_PROTOCOL_PRIMARY_SELECTION) {
zwp_primary_selection_source_v1_destroy(source->zwpPrimarySelectionSource);
}
if (source->dragIconBuffer) {
wl_buffer_destroy(source->dragIconBuffer);
}
if (source->dragIcon) {
wl_surface_destroy(source->dragIcon);
}
free(source);
pthread_mutex_lock(&dataDevice->sourceDelMutex);
source->nextDel = dataDevice->sourceDelQueue;
dataDevice->sourceDelQueue = source;
pthread_mutex_unlock(&dataDevice->sourceDelMutex);
}
JNIEXPORT void JNICALL
@@ -1073,7 +1145,8 @@ Java_sun_awt_wl_WLDataSource_setDnDActionsImpl(JNIEnv *env,
}
JNIEXPORT void JNICALL Java_sun_awt_wl_WLDataSource_setDnDIconImpl
(JNIEnv * env, jclass clazz, jlong nativePtr, jint width, jint height, jint offsetX, jint offsetY, jintArray pixels)
(JNIEnv * env, jclass clazz, jlong nativePtr, jint scale,
jint width, jint height, jint offsetX, jint offsetY, jintArray pixels)
{
struct DataSource *source = jlong_to_ptr(nativePtr);
@@ -1126,6 +1199,10 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_WLDataSource_setDnDIconImpl
wl_surface_attach(source->dragIcon, source->dragIconBuffer, offsetX, offsetY);
#endif
if (scale >= 1) {
wl_surface_set_buffer_scale(source->dragIcon, scale);
}
wl_surface_damage_buffer(source->dragIcon, 0, 0, width, height);
// NOTE: we still need to commit the surface, this is done immediately after start_drag
@@ -1134,8 +1211,20 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_WLDataSource_setDnDIconImpl
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLDataOffer_destroyImpl(JNIEnv *env, jclass clazz, jlong nativePtr)
{
assert(env != NULL);
struct DataOffer *offer = jlong_to_ptr(nativePtr);
DataOffer_destroy(offer);
if (offer == NULL) {
return;
}
assert(offer->dataDevice != NULL);
struct DataDevice* dataDevice = offer->dataDevice;
pthread_mutex_lock(&dataDevice->offerDelMutex);
offer->nextDel = dataDevice->offerDelQueue;
dataDevice->offerDelQueue = offer;
pthread_mutex_unlock(&dataDevice->offerDelMutex);
}
JNIEXPORT void JNICALL

View File

@@ -43,8 +43,6 @@ typedef struct WLOutput {
int32_t x;
int32_t y;
int32_t x_logical;
int32_t y_logical;
int32_t width;
int32_t height;
int32_t width_logical;
@@ -59,6 +57,8 @@ typedef struct WLOutput {
char * make;
char * model;
char * name;
bool offset_known; // whether x and y were set by xdg_output
} WLOutput;
static jclass geClass;
@@ -83,10 +83,13 @@ wl_output_geometry(
{
WLOutput *output = data;
// TODO: there's also a recommended, but unstable interface xdg_output;
// we may want to switch to that one day.
output->x = x;
output->y = y;
if (!output->offset_known) {
// Ubuntu 22.04 has a bug that prevent Mutter from sending out updates to (x, y) in this
// geometry event. So we prefer to learn offset from xdg_output that will override
// (x, y) from this event.
output->x = x;
output->y = y;
}
output->subpixel = subpixel;
output->transform = transform;
output->width_mm = physical_width;
@@ -161,8 +164,6 @@ NotifyOutputConfigured(WLOutput* output)
output->id,
output->x,
output->y,
output->x_logical,
output->y_logical,
output->width,
output->height,
output->width_logical,
@@ -173,6 +174,8 @@ NotifyOutputConfigured(WLOutput* output)
(jint)output->transform,
(jint)output->scale);
JNU_CHECK_EXCEPTION(env);
output->offset_known = false;
}
static void
@@ -218,8 +221,12 @@ static void
zxdg_output_logical_position(void *data, struct zxdg_output_v1 *zxdg_output_v1, int32_t x, int32_t y)
{
WLOutput * output = data;
output->x_logical = x;
output->y_logical = y;
output->x = x;
output->y = y;
// Prevent the geometry event from overriding these values with potentially incorrect ones;
// see wl_output_geometry().
output->offset_known = true;
}
static void
@@ -257,7 +264,7 @@ WLGraphicsEnvironment_initIDs
CHECK_NULL_RETURN(
notifyOutputConfiguredMID = (*env)->GetMethodID(env, clazz,
"notifyOutputConfigured",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIIIIIIIIII)V"),
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIIIIIIII)V"),
JNI_FALSE);
CHECK_NULL_RETURN(
notifyOutputDestroyedMID = (*env)->GetMethodID(env, clazz,

View File

@@ -24,6 +24,7 @@
* questions.
*/
#include "relative-pointer-unstable-v1.h"
#ifdef HEADLESS
#error This file should not be included in headless library
#endif
@@ -80,6 +81,7 @@ struct gtk_shell1* gtk_shell1 = NULL;
#endif
struct wl_keyboard *wl_keyboard; // optional, check for NULL before use
struct wl_pointer *wl_pointer; // optional, check for NULL before use
struct zwp_relative_pointer_manager_v1* relative_pointer_manager; // optional, check for NULL before use
#define MAX_CURSOR_SCALE 100
struct wl_cursor_theme *cursor_themes[MAX_CURSOR_SCALE] = {NULL};
@@ -88,6 +90,8 @@ struct wl_data_device_manager *wl_ddm = NULL;
struct zwp_primary_selection_device_manager_v1 *zwp_selection_dm = NULL; // optional, check for NULL before use
struct zxdg_output_manager_v1 *zxdg_output_manager_v1 = NULL; // optional, check for NULL before use
struct zwp_text_input_manager_v3 *zwp_text_input_manager = NULL; // optional, check for NULL before use
static uint32_t num_of_outstanding_sync = 0;
// This group of definitions corresponds to declarations from awt.h
@@ -128,6 +132,7 @@ static jmethodID dispatchKeyboardKeyEventMID;
static jmethodID dispatchKeyboardModifiersEventMID;
static jmethodID dispatchKeyboardEnterEventMID;
static jmethodID dispatchKeyboardLeaveEventMID;
static jmethodID dispatchRelativePointerEventMID;
JNIEnv *getEnv() {
JNIEnv *env;
@@ -464,6 +469,31 @@ static const struct wl_keyboard_listener wl_keyboard_listener = {
.key = wl_keyboard_key
};
static void
wl_relative_motion(void *data,
struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
uint32_t utime_hi,
uint32_t utime_lo,
wl_fixed_t dx,
wl_fixed_t dy,
wl_fixed_t dx_unaccel,
wl_fixed_t dy_unaccel)
{
double ddx = wl_fixed_to_double(dx);
double ddy = wl_fixed_to_double(dy);
JNIEnv* env = getEnv();
(*env)->CallStaticVoidMethod(env,
tkClass,
dispatchRelativePointerEventMID,
ddx, ddy);
JNU_CHECK_EXCEPTION(env);
}
static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
.relative_motion = wl_relative_motion
};
static void
wl_seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
{
@@ -474,6 +504,14 @@ wl_seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
wl_pointer = wl_seat_get_pointer(wl_seat);
if (wl_pointer != NULL) {
wl_pointer_add_listener(wl_pointer, &wl_pointer_listener, NULL);
if (relative_pointer_manager != NULL) {
struct zwp_relative_pointer_v1* rptr
= zwp_relative_pointer_manager_v1_get_relative_pointer(relative_pointer_manager,
wl_pointer);
if (rptr != NULL) {
zwp_relative_pointer_v1_add_listener(rptr, &relative_pointer_listener, NULL);
}
}
}
} else if (!has_pointer && wl_pointer != NULL) {
wl_pointer_release(wl_pointer);
@@ -565,6 +603,9 @@ registry_global(void *data, struct wl_registry *wl_registry,
} else if (strcmp(interface, xdg_activation_v1_interface.name) == 0) {
xdg_activation_v1 = wl_registry_bind(wl_registry, name, &xdg_activation_v1_interface, 1);
}
else if (strcmp(interface, zwp_relative_pointer_manager_v1_interface.name) == 0) {
relative_pointer_manager = wl_registry_bind(wl_registry, name, &zwp_relative_pointer_manager_v1_interface, 1);
}
#ifdef HAVE_GTK_SHELL1
else if (strcmp(interface, gtk_shell1_interface.name) == 0) {
gtk_shell1 = wl_registry_bind(wl_registry, name, &gtk_shell1_interface, 1);
@@ -582,6 +623,14 @@ registry_global(void *data, struct wl_registry *wl_registry,
WLOutputXdgOutputManagerBecameAvailable();
process_new_listener_before_end_of_init();
}
} else if (strcmp(interface, zwp_text_input_manager_v3_interface.name) == 0) {
// If the requested version is higher than the provided one by the compositor,
// the event loop may shut down as soon as it gets launched (wl_display_dispatch will return -1),
// so let's protect from this since the component being obtained is not vital for work.
const uint32_t versionToBind = 1;
if (versionToBind <= version) {
zwp_text_input_manager = wl_registry_bind(wl_registry, name, &zwp_text_input_manager_v3_interface, versionToBind);
}
}
#ifdef WAKEFIELD_ROBOT
@@ -715,6 +764,10 @@ initJavaRefs(JNIEnv *env, jclass clazz)
"dispatchKeyboardModifiersEvent",
"(J)V"),
JNI_FALSE);
CHECK_NULL_RETURN(dispatchRelativePointerEventMID = (*env)->GetStaticMethodID(env, tkClass,
"dispatchRelativePointerEvent",
"(DD)V"),
JNI_FALSE);
jclass wlgeClass = (*env)->FindClass(env, "sun/awt/wl/WLGraphicsEnvironment");
CHECK_NULL_RETURN(wlgeClass, JNI_FALSE);

View File

@@ -30,6 +30,8 @@
#include "xdg-output-unstable-v1.h"
#include "primary-selection-unstable-v1.h"
#include "viewporter.h"
#include "relative-pointer-unstable-v1.h"
#include "text-input-unstable-v3.h"
#include "jvm_md.h"
#include "jni_util.h"
@@ -66,6 +68,8 @@ extern struct wl_cursor_theme *wl_cursor_theme;
extern struct wl_data_device_manager *wl_ddm;
extern struct zwp_primary_selection_device_manager_v1 *zwp_selection_dm; // optional, check for NULL before use
extern struct zxdg_output_manager_v1 *zxdg_output_manager_v1; // optional, check for NULL before use
extern struct zwp_relative_pointer_manager_v1* relative_pointer_manager;
extern struct zwp_text_input_manager_v3 *zwp_text_input_manager; // optional, check for NULL before use
JNIEnv *getEnv();

View File

@@ -0,0 +1,687 @@
/*
* Copyright 2025 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.
*/
#include "sun_awt_wl_im_text_input_unstable_v3_WLInputMethodDescriptorZwpTextInputV3.h"
#include "sun_awt_wl_im_text_input_unstable_v3_WLInputMethodZwpTextInputV3.h"
#include "WLToolkit.h" // wl_seat, zwp_text_input_*, uint[...]_t, int[...]_t
#include "JNIUtilities.h"
#include <stdbool.h> // bool, true, false
#include <string.h> // memset, strlen
#include <stdlib.h> // malloc, free
#include <assert.h> // assert
static bool checkIfTheImplementationIsAvailable() {
return (zwp_text_input_manager == NULL) ? false : true;
}
static struct {
jclass wlInputMethodClass;
/// `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3#zwp_text_input_v3_onEnter`
jmethodID mID_tiOnEnter;
/// `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3#zwp_text_input_v3_onLeave`
jmethodID mID_tiOnLeave;
/// `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3#zwp_text_input_v3_onPreeditString`
jmethodID mID_tiOnPreeditString;
/// `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3#zwp_text_input_v3_onCommitString`
jmethodID mID_tiOnCommitString;
/// `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3#zwp_text_input_v3_onDeleteSurroundingText`
jmethodID mID_tiOnDeleteSurroundingText;
/// `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3#zwp_text_input_v3_onDone`
jmethodID mID_tiOnDone;
} jniIDs = {0};
// ================================================= IMContext section ================================================
static void IMContext_zwp_text_input_v3_onEnter(void*, struct zwp_text_input_v3*, struct wl_surface*);
static void IMContext_zwp_text_input_v3_onLeave(void*, struct zwp_text_input_v3*, struct wl_surface*);
static void IMContext_zwp_text_input_v3_onPreeditString(void*, struct zwp_text_input_v3*, const char*, int32_t, int32_t);
static void IMContext_zwp_text_input_v3_onCommitString(void*, struct zwp_text_input_v3*, const char*);
static void IMContext_zwp_text_input_v3_onDeleteSurroundingText(void*, struct zwp_text_input_v3*, uint32_t, uint32_t);
static void IMContext_zwp_text_input_v3_onDone(void*, struct zwp_text_input_v3*, uint32_t);
static const struct zwp_text_input_v3_listener IMContext_zwp_text_input_v3_listener = {
.enter = &IMContext_zwp_text_input_v3_onEnter,
.leave = &IMContext_zwp_text_input_v3_onLeave,
.preedit_string = &IMContext_zwp_text_input_v3_onPreeditString,
.commit_string = &IMContext_zwp_text_input_v3_onCommitString,
.delete_surrounding_text = &IMContext_zwp_text_input_v3_onDeleteSurroundingText,
.done = &IMContext_zwp_text_input_v3_onDone,
};
/**
* The native-side counterpart of `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3`.
* On Java side these contexts are created and destroyed through
* `WLInputMethod#createNativeContext` and `WLInputMethod#destroyNativeContext` respectively.
*
* `IMContext` and `WLInputMethodZwpTextInputV3` are related in a 1:1 ratio - an instance of `WLInputMethodZwpTextInputV3` holds no more than 1
* instance of `IMContext` and an instance of `IMContext` only belongs to 1 instance of `WLInputMethodZwpTextInputV3`.
*/
struct IMContext {
/// A global reference to the instance of `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3` owning this instance of `IMContext`.
jobject wlInputMethodOwner;
/// Represents an input context for the entire `text-input-unstable-v3` protocol.
struct zwp_text_input_v3 *textInput;
};
/**
* Creates and fully initializes an instance of `struct IMContext`.
*
* @param wlInputMethodOwnerRefToCopy a reference to the owning instance of `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3`.
* NB: the reference will be copied via `NewGlobalRef` and no longer used.
* @return `null` if it has failed to create or completely initialize a new instance.
* In this case a corresponding exception of class `java.awt.AWTException` or of an unchecked exception class
* will be raised in @p env
*/
static struct IMContext* IMContext_Create(JNIEnv * const env, jobject wlInputMethodOwnerRefToCopy) {
struct wl_seat * const wlSeat = wl_seat;
struct zwp_text_input_manager_v3 * const textInputManager = zwp_text_input_manager;
struct IMContext *result = NULL;
jobject wlInputMethodOwner = NULL;
struct zwp_text_input_v3 *textInput = NULL;
if (wlSeat == NULL) {
JNU_ThrowByName(env, "java/awt/AWTException", "IMContext_Create: no wl_seat is available");
goto failure;
}
if (textInputManager == NULL) {
JNU_ThrowNullPointerException(env, "IMContext_Create: textInputManager is NULL");
goto failure;
}
wlInputMethodOwner = (*env)->NewGlobalRef(env, wlInputMethodOwnerRefToCopy);
if (wlInputMethodOwner == NULL) {
if ((*env)->ExceptionCheck(env) == JNI_FALSE) {
JNU_ThrowOutOfMemoryError(env, "IMContext_Create: NewGlobalRef(wlInputMethodOwnerRefToCopy) failed");
}
goto failure;
}
wlInputMethodOwnerRefToCopy = NULL; // To avoid misusages
result = malloc(sizeof(struct IMContext));
if (result == NULL) {
JNU_ThrowOutOfMemoryError(env, "IMContext_Create: malloc(sizeof(struct IMContext)) failed");
goto failure;
}
textInput = zwp_text_input_manager_v3_get_text_input(textInputManager, wlSeat);
if (textInput == NULL) {
JNU_ThrowByName(env, "java/awt/AWTException", "IMContext_Create: failed to obtain a new instance of zwp_text_input_v3");
goto failure;
}
// WLToolkit dispatches (almost) all native Wayland events on EDT, not on its thread.
// If it didn't, the callbacks being set here might be called even before this function finishes, hence even before
// the constructor of `sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3` finishes (because the constructor gets called on the
// EDT rather than on the toolkit thread).
// In that case we would have to take it into account while implementing the callbacks and
// `WLInputMethodZwpTextInputV3` class in general.
zwp_text_input_v3_add_listener(textInput, &IMContext_zwp_text_input_v3_listener, result);
(void)memset(result, 0, sizeof(struct IMContext));
result->wlInputMethodOwner = wlInputMethodOwner;
result->textInput = textInput;
return result;
failure:
if (textInput != NULL) {
zwp_text_input_v3_destroy(textInput);
textInput = NULL;
}
if (result != NULL) {
free(result);
result = NULL;
}
if (wlInputMethodOwner != NULL) {
(*env)->DeleteGlobalRef(env, wlInputMethodOwner);
wlInputMethodOwner = NULL;
}
return NULL;
}
/// Destroys the context previously created by IMContext_Create
static void IMContext_Destroy(JNIEnv * const env, struct IMContext * const imContext) {
assert(env != NULL);
assert(imContext != NULL);
if (imContext->textInput != NULL) {
zwp_text_input_v3_destroy(imContext->textInput);
imContext->textInput = NULL;
}
if (imContext->wlInputMethodOwner != NULL) {
(*env)->DeleteGlobalRef(env, imContext->wlInputMethodOwner);
imContext->wlInputMethodOwner = NULL;
}
free(imContext);
}
// The IMContext_zwp_text_input_v3_on* callbacks are supposed to be as a thin bridge to
// `WLInputMethodZwpTextInputV3`'s JNI upcalls as possible in terms of contained logic.
// Generally they should only invoke the corresponding upcalls with the received parameters.
//
// Exceptions after making JNI upcalls to WLInputMethodZwpTextInputV3 are checked (via JNU_CHECK_EXCEPTION),
// but not suppressed on a purpose: all the corresponding Java methods already handles any java.lang.Exception.
// So if an exception leaves any of those methods, it's something really strange and it's better to let WLToolkit
// get to know about it rather than log and try to continue the normal path.
// The checks are just made to suppress -Xcheck:jni warnings.
static void IMContext_zwp_text_input_v3_onEnter(
void * const ctx,
struct zwp_text_input_v3 * const textInput,
struct wl_surface * const surface
) {
const struct IMContext * const imContext = ctx;
JNIEnv *env = NULL;
if (imContext == NULL) {
return;
}
env = getEnv();
if (env == NULL) {
return;
}
(*env)->CallVoidMethod(env, imContext->wlInputMethodOwner, jniIDs.mID_tiOnEnter, ptr_to_jlong(surface));
JNU_CHECK_EXCEPTION(env);
}
static void IMContext_zwp_text_input_v3_onLeave(
void * const ctx,
struct zwp_text_input_v3 * const textInput,
struct wl_surface * const surface
) {
const struct IMContext * const imContext = ctx;
JNIEnv *env = NULL;
if (imContext == NULL) {
return;
}
env = getEnv();
if (env == NULL) {
return;
}
(*env)->CallVoidMethod(env, imContext->wlInputMethodOwner, jniIDs.mID_tiOnLeave, ptr_to_jlong(surface));
JNU_CHECK_EXCEPTION(env);
}
/**
* Converts a UTF-8 string to a Java byte array, throwing an OutOfMemoryError if the allocation fails. Another kind
* of exceptions may also appear, according to the implementation of 'NewByteArray' and 'SetByteArrayRegion'.
* Regardless of the returned value, always check 'env->ExceptionCheck()' after each call of this function.
*
* @param utf8Str UTF-8 string to convert.
* @param utf8StrSizeInBytes size of the UTF-8 string in bytes, or a negative value to ask the function to
* calculate it manually.
* @param env JNI environment. Mustn't be NULL.
* @param oomMessage message to use in the OutOfMemoryError exception if it appears. Mustn't be NULL.
*
* @return a local JNI reference to a Java byte array or NULL if 'utf8Str' is NULL,
* an exception occurred,
* or 'NewByteArray' returned NULL for some other reason.
*/
static jbyteArray utf8StrToJByteArrayOrThrowOOM(
const char * const utf8Str,
ssize_t utf8StrSizeInBytes,
JNIEnv * const env,
const char * const oomMessage
) {
jbyteArray result = NULL;
assert(env != NULL);
assert(oomMessage != NULL);
if (utf8Str == NULL) {
return NULL;
}
if (utf8StrSizeInBytes < 0) {
// Let's believe there's a trailing NUL codepoint (otherwise we can't calculate the string's size), and
// there are no NUL codepoints in the middle, though it's possible in general for UTF-8.
utf8StrSizeInBytes = (ssize_t)(strlen(utf8Str) + 1);
}
result = (*env)->NewByteArray(env, (jsize)utf8StrSizeInBytes);
if (result == NULL) {
if ((*env)->ExceptionCheck(env) == JNI_FALSE) {
JNU_ThrowOutOfMemoryError(env, oomMessage);
}
} else {
(*env)->SetByteArrayRegion(
env,
result,
0,
(jsize)utf8StrSizeInBytes,
(const jbyte*)utf8Str
);
}
return result;
}
static void IMContext_zwp_text_input_v3_onPreeditString(
void * const ctx,
struct zwp_text_input_v3 * const textInput,
const char * const preeditStringUtf8,
const int32_t cursorBeginUtf8Byte,
const int32_t cursorEndUtf8Byte
) {
const struct IMContext * const imContext = ctx;
JNIEnv *env = NULL;
jbyteArray preeditStringUtf8Bytes = NULL;
if (imContext == NULL) {
return;
}
env = getEnv();
if (env == NULL) {
return;
}
// may still be NULL
preeditStringUtf8Bytes = utf8StrToJByteArrayOrThrowOOM(
preeditStringUtf8,
// the zwp_text_input_v3::preedit_string event doesn't provide the length or size of the string separately,
// asking the function to manually calculate it.
-1,
env,
"IMContext_zwp_text_input_v3_onPreeditString: failed to allocate a new Java byte array"
);
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
return;
}
(*env)->CallVoidMethod(
env,
imContext->wlInputMethodOwner,
jniIDs.mID_tiOnPreeditString,
preeditStringUtf8Bytes,
(jint)cursorBeginUtf8Byte,
(jint)cursorEndUtf8Byte
);
JNU_CHECK_EXCEPTION(env);
}
static void IMContext_zwp_text_input_v3_onCommitString(
void * const ctx,
struct zwp_text_input_v3 * const textInput,
const char * const commitStringUtf8
) {
const struct IMContext * const imContext = ctx;
JNIEnv *env = NULL;
jbyteArray commitStringUtf8Bytes = NULL;
if (imContext == NULL) {
return;
}
env = getEnv();
if (env == NULL) {
return;
}
// may still be NULL
commitStringUtf8Bytes = utf8StrToJByteArrayOrThrowOOM(
commitStringUtf8,
// the zwp_text_input_v3::commit_string event doesn't provide the length or size of the string separately,
// asking the function to manually calculate it.
-1,
env,
"IMContext_zwp_text_input_v3_onCommitString: failed to allocate a new Java byte array"
);
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
return;
}
(*env)->CallVoidMethod(env, imContext->wlInputMethodOwner, jniIDs.mID_tiOnCommitString, commitStringUtf8Bytes);
JNU_CHECK_EXCEPTION(env);
}
static void IMContext_zwp_text_input_v3_onDeleteSurroundingText(
void * const ctx,
struct zwp_text_input_v3 * const textInput,
const uint32_t numberOfUtf8BytesBeforeToDelete,
const uint32_t numberOfUtf8BytesAfterToDelete
) {
const struct IMContext * const imContext = ctx;
JNIEnv *env = NULL;
if (imContext == NULL) {
return;
}
env = getEnv();
if (env == NULL) {
return;
}
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
return;
}
(*env)->CallVoidMethod(
env,
imContext->wlInputMethodOwner,
jniIDs.mID_tiOnDeleteSurroundingText,
(jlong)numberOfUtf8BytesBeforeToDelete,
(jlong)numberOfUtf8BytesAfterToDelete
);
JNU_CHECK_EXCEPTION(env);
}
static void IMContext_zwp_text_input_v3_onDone(
void *const ctx,
struct zwp_text_input_v3 * const textInput,
const uint32_t serial
) {
const struct IMContext * const imContext = ctx;
JNIEnv *env = NULL;
if (imContext == NULL) {
return;
}
env = getEnv();
if (env == NULL) {
return;
}
(*env)->CallVoidMethod(env, imContext->wlInputMethodOwner, jniIDs.mID_tiOnDone, (jlong)serial);
JNU_CHECK_EXCEPTION(env);
}
// ============================================= END of IMContext section =============================================
// =============================================== JNI downcalls section ==============================================
JNIEXPORT jboolean JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodDescriptorZwpTextInputV3_checkIfAvailableOnPlatform(JNIEnv * const env, const jclass clazz) {
return checkIfTheImplementationIsAvailable() ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_initIDs(JNIEnv * const env, const jclass clazz) {
CHECK_NULL_THROW_OOME(
env,
jniIDs.wlInputMethodClass = (*env)->NewGlobalRef(env, clazz),
"Allocation of a global reference to sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3 class failed"
);
jniIDs.mID_tiOnEnter =
(*env)->GetMethodID(env, jniIDs.wlInputMethodClass, "zwp_text_input_v3_onEnter", "(J)V");
if (jniIDs.mID_tiOnEnter == NULL) {
// DeleteGlobalRef is one of the few JNI functions that are safe to call while there's a pending exception
(*env)->DeleteGlobalRef(env, jniIDs.wlInputMethodClass);
(void)memset(&jniIDs, 0, sizeof(jniIDs));
return;
}
jniIDs.mID_tiOnLeave =
(*env)->GetMethodID(env, jniIDs.wlInputMethodClass, "zwp_text_input_v3_onLeave", "(J)V");
if (jniIDs.mID_tiOnLeave == NULL) {
(*env)->DeleteGlobalRef(env, jniIDs.wlInputMethodClass);
(void)memset(&jniIDs, 0, sizeof(jniIDs));
return;
}
jniIDs.mID_tiOnPreeditString =
(*env)->GetMethodID(env, jniIDs.wlInputMethodClass, "zwp_text_input_v3_onPreeditString", "([BII)V");
if (jniIDs.mID_tiOnPreeditString == NULL) {
(*env)->DeleteGlobalRef(env, jniIDs.wlInputMethodClass);
(void)memset(&jniIDs, 0, sizeof(jniIDs));
return;
}
jniIDs.mID_tiOnCommitString =
(*env)->GetMethodID(env, jniIDs.wlInputMethodClass, "zwp_text_input_v3_onCommitString", "([B)V");
if (jniIDs.mID_tiOnCommitString == NULL) {
(*env)->DeleteGlobalRef(env, jniIDs.wlInputMethodClass);
(void)memset(&jniIDs, 0, sizeof(jniIDs));
return;
}
jniIDs.mID_tiOnDeleteSurroundingText =
(*env)->GetMethodID(env, jniIDs.wlInputMethodClass, "zwp_text_input_v3_onDeleteSurroundingText", "(JJ)V");
if (jniIDs.mID_tiOnDeleteSurroundingText == NULL) {
(*env)->DeleteGlobalRef(env, jniIDs.wlInputMethodClass);
(void)memset(&jniIDs, 0, sizeof(jniIDs));
return;
}
jniIDs.mID_tiOnDone =
(*env)->GetMethodID(env, jniIDs.wlInputMethodClass, "zwp_text_input_v3_onDone", "(J)V");
if (jniIDs.mID_tiOnDone == NULL) {
(*env)->DeleteGlobalRef(env, jniIDs.wlInputMethodClass);
(void)memset(&jniIDs, 0, sizeof(jniIDs));
return;
}
}
JNIEXPORT jlong JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_createNativeContext(JNIEnv * const env, const jobject self) {
struct IMContext *result = NULL;
if (!checkIfTheImplementationIsAvailable()) {
JNU_ThrowByName(env, "java/awt/AWTException", "sun.awt.wl.im.text_input_unstable_v3.WLInputMethodZwpTextInputV3 is not supported on this system");
return 0;
}
result = IMContext_Create(env, self);
return ptr_to_jlong(result);
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_disposeNativeContext(
JNIEnv * const env,
const jclass clazz,
const jlong contextPtr
) {
struct IMContext *imContext = jlong_to_ptr(contextPtr);
if (imContext == NULL) {
JNU_ThrowNullPointerException(env, "contextPtr");
return;
}
IMContext_Destroy(env, imContext);
imContext = NULL;
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_zwp_1text_1input_1v3_1enable(
JNIEnv * const env,
const jobject self,
const jlong contextPtr
) {
const struct IMContext * const imContext = jlong_to_ptr(contextPtr);
struct zwp_text_input_v3 *textInput = NULL;
if (imContext == NULL) {
JNU_ThrowNullPointerException(env, "contextPtr");
return;
}
textInput = imContext->textInput;
if (textInput == NULL) {
JNU_ThrowByName(env, "java/lang/IllegalStateException", "textInput == NULL");
return;
}
zwp_text_input_v3_enable(textInput);
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_zwp_1text_1input_1v3_1disable(
JNIEnv * const env,
const jobject self,
const jlong contextPtr
) {
const struct IMContext * const imContext = jlong_to_ptr(contextPtr);
struct zwp_text_input_v3 *textInput = NULL;
if (imContext == NULL) {
JNU_ThrowNullPointerException(env, "contextPtr");
return;
}
textInput = imContext->textInput;
if (textInput == NULL) {
JNU_ThrowByName(env, "java/lang/IllegalStateException", "textInput == NULL");
return;
}
zwp_text_input_v3_disable(textInput);
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_zwp_1text_1input_1v3_1set_1cursor_1rectangle(
JNIEnv * const env,
const jobject self,
const jlong contextPtr,
const jint surfaceLocalX,
const jint surfaceLocalY,
const jint width,
const jint height
) {
const struct IMContext * const imContext = jlong_to_ptr(contextPtr);
struct zwp_text_input_v3 *textInput = NULL;
if (imContext == NULL) {
JNU_ThrowNullPointerException(env, "contextPtr");
return;
}
textInput = imContext->textInput;
if (textInput == NULL) {
JNU_ThrowByName(env, "java/lang/IllegalStateException", "textInput == NULL");
return;
}
zwp_text_input_v3_set_cursor_rectangle(
textInput,
(int32_t)surfaceLocalX,
(int32_t)surfaceLocalY,
(int32_t)width,
(int32_t)height
);
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_zwp_1text_1input_1v3_1set_1content_1type(
JNIEnv * const env,
const jobject self,
const jlong contextPtr,
const jint hint,
const jint purpose
) {
const struct IMContext * const imContext = jlong_to_ptr(contextPtr);
struct zwp_text_input_v3 *textInput = NULL;
if (imContext == NULL) {
JNU_ThrowNullPointerException(env, "contextPtr");
return;
}
textInput = imContext->textInput;
if (textInput == NULL) {
JNU_ThrowByName(env, "java/lang/IllegalStateException", "textInput == NULL");
return;
}
zwp_text_input_v3_set_content_type(textInput, (uint32_t)hint, (uint32_t)purpose);
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_zwp_1text_1input_1v3_1set_1text_1change_1cause(
JNIEnv * const env,
const jobject self,
const jlong contextPtr,
const jint changeCause
) {
const struct IMContext * const imContext = jlong_to_ptr(contextPtr);
struct zwp_text_input_v3 *textInput = NULL;
if (imContext == NULL) {
JNU_ThrowNullPointerException(env, "contextPtr");
return;
}
textInput = imContext->textInput;
if (textInput == NULL) {
JNU_ThrowByName(env, "java/lang/IllegalStateException", "textInput == NULL");
return;
}
zwp_text_input_v3_set_text_change_cause(textInput, (uint32_t)changeCause);
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_im_text_1input_1unstable_1v3_WLInputMethodZwpTextInputV3_zwp_1text_1input_1v3_1commit(
JNIEnv * const env,
const jobject self,
const jlong contextPtr
) {
const struct IMContext * const imContext = jlong_to_ptr(contextPtr);
struct zwp_text_input_v3 *textInput = NULL;
if (imContext == NULL) {
JNU_ThrowNullPointerException(env, "contextPtr");
return;
}
textInput = imContext->textInput;
if (textInput == NULL) {
JNU_ThrowByName(env, "java/lang/IllegalStateException", "textInput == NULL");
return;
}
zwp_text_input_v3_commit(textInput);
}
// =========================================== END of JNI downcalls section ===========================================

View File

@@ -58,7 +58,7 @@ gc/stress/gcold/TestGCOldWithShenandoah.java#aggressive JBR-8563 windows-aarch64
# :hotspot_runtime
runtime/ErrorHandling/AccessZeroNKlassHitsProtectionZone.java#coh_no_cds JBR-6616 windows-aarch64
runtime/ErrorHandling/AccessZeroNKlassHitsProtectionZone.java#coh_no_cds JBR-6616,JBR-9488 windows-aarch64,macosx-26.0
runtime/ErrorHandling/AccessZeroNKlassHitsProtectionZone.java#no_coh_cds JBR-6616 windows-aarch64
runtime/ErrorHandling/AccessZeroNKlassHitsProtectionZone.java#no_coh_no_cds JBR-6616 windows-aarch64
runtime/ErrorHandling/ErrorFileOverwriteTest.java JBR-8524 windows-aarch64

View File

@@ -95,7 +95,6 @@ compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java 8190680 generic-all
compiler/runtime/Test8168712.java 8211769,8211771 generic-ppc64,generic-ppc64le,linux-s390x
compiler/linkage/TestLinkageErrorInGenerateOopMap.java JBR-8524 windows-aarch64
compiler/loopopts/TestUnreachableInnerLoop.java 8288981 linux-s390x
compiler/rtm/locking/TestRTMAbortRatio.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestRTMAbortThreshold.java 8183263 generic-x64,generic-i586
@@ -116,7 +115,6 @@ compiler/c2/irTests/TestDuplicateBackedge.java 8318904 generic-all
compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-all
compiler/vectorapi/reshape/TestVectorReinterpret.java 8320897 aix-ppc64,linux-ppc64le
compiler/vectorapi/VectorLogicalOpIdentityTest.java 8302459 linux-x64,windows-x64
compiler/vectorapi/VectorRebracket128Test.java 8330538 generic-all
compiler/jvmci/TestUncaughtErrorInCompileMethod.java 8309073 generic-all
@@ -152,12 +150,6 @@ gc/TestAllocHumongousFragment.java#aggressive 8298781 generic-all
gc/TestAllocHumongousFragment.java#iu-aggressive 8298781 generic-all
gc/TestAllocHumongousFragment.java#g1 8298781 generic-all
gc/TestAllocHumongousFragment.java#static 8298781 generic-all
gc/TestAlwaysPreTouchBehavior.java#ParallelCollector 8334513 generic-all
gc/TestAlwaysPreTouchBehavior.java#SerialCollector 8334513 generic-all
gc/TestAlwaysPreTouchBehavior.java#Shenandoah 8334513 generic-all
gc/TestAlwaysPreTouchBehavior.java#G1 8334513 generic-all
gc/TestAlwaysPreTouchBehavior.java#Z 8334513 generic-all
gc/TestAlwaysPreTouchBehavior.java#Epsilon 8334513 generic-all
gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all
gc/shenandoah/oom/TestAllocOutOfMemory.java#large 8344312 linux-ppc64le
gc/shenandoah/TestEvilSyncBug.java#generational 8345501 generic-all
@@ -172,7 +164,6 @@ runtime/jni/terminatedThread/TestTerminatedThread.java 8317789 aix-ppc64
runtime/cds/CheckDefaultArchiveFile.java JBR-4227 generic-all
runtime/cds/SharedBaseAddress.java#id2 JBR-9078 windows-aarch64
runtime/cds/SharedBaseAddress.java#id3 JBR-9078 windows-aarch64
runtime/handshake/HandshakeSuspendExitTest.java 8318631 generic-all
runtime/modules/ClassLoaderNoUnnamedModuleTest.java JBR-8516 windows-aarch64
runtime/Monitor/SyncOnValueBasedClassTest.java 8340995,JBR-8517 linux-s390x,windows-aarch64
runtime/os/TestTracePageSizes.java#no-options 8267460 linux-aarch64
@@ -182,7 +173,7 @@ runtime/os/TestTracePageSizes.java#G1 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#Parallel 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#Serial 8267460 linux-aarch64
runtime/os/windows/TestAvailableProcessors.java JBR-8182 windows-all
runtime/ErrorHandling/CreateCoredumpOnCrash.java 8267433,JBR-7917,JBR-8528 macosx-x64,macosx-all,windows-aarch64
runtime/ErrorHandling/CreateCoredumpOnCrash.java JBR-7917,JBR-8528 macosx-all,windows-aarch64
runtime/Safepoint/TestAbortOnVMOperationTimeout.java JBR-8524 windows-aarch64
runtime/Safepoint/TestAbortVMOnSafepointTimeout.java JBR-8524 windows-aarch64
runtime/StackGuardPages/TestStackGuardPages.java 8303612 linux-all 8293452
@@ -191,7 +182,6 @@ runtime/stringtable/StringTableCorruptionTest.java JBR-8524 windows-aarch64
runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315,JBR-6289 linux-ppc64le,windows-aarch64
runtime/ErrorHandling/TestAbortVmOnException.java JBR-8514 windows-aarch64
runtime/ErrorHandling/UncaughtNativeExceptionTest.java JBR-8515 windows-aarch64
runtime/NMT/CheckForProperDetailStackTrace.java 8347002 linux-all
runtime/NMT/MallocLimitTest.java#compiler-limit-fatal JBR-8524 windows-aarch64
runtime/NMT/MallocLimitTest.java#global-limit-fatal JBR-8524 windows-aarch64
runtime/NMT/MallocLimitTest.java#multi-limit JBR-8524 windows-aarch64
@@ -209,10 +199,11 @@ containers/docker/TestPids.java 8356277 linux-all
runtime/memory/ReserveMemory.java initial_run windows-aarch64
runtime/memory/ReadFromNoaccessArea.java initial_run windows-aarch64
runtime/cds/appcds/ArchiveRelocationTest.java JBR-9420 macosx-26.0
runtime/cds/appcds/CommandLineFlagCombo.java JBR-6616 windows-aarch64
runtime/cds/appcds/complexURI/ComplexURITest.java JBR-6616 windows-aarch64
runtime/cds/appcds/lambdaForm/DefaultClassListLFInvokers.java JBR-9079 windows-aarch64
runtime/cds/DeterministicDump.java JBR-9077 windows-aarch64
runtime/cds/DeterministicDump.java JBR-9077,JBR-9421 windows-aarch64,macosx-26.0
runtime/cds/appcds/LotsOfSyntheticClasses.java JBR-8823 windows-all
runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java initial_run generic-all
runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java initial_run generic-all
@@ -229,8 +220,6 @@ runtime/cds/TestDefaultArchiveLoading.java#coops_nocoh JBR-6616 windows-aarch64
runtime/cds/TestDefaultArchiveLoading.java#nocoops_nocoh JBR-6616 windows-aarch64
runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java initial_run generic-all
sources/TestNoNULL.java JBR-8419 generic-all
#############################################################################
# :hotspot_serviceability
@@ -346,9 +335,9 @@ vmTestbase/vm/mlvm/meth/stress/compiler/deoptimize/Test.java#id1 8324756 generic
vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java 7199837 generic-all
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi001/Multi001.java JBR-8545 windows-aarch64
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi002/TestDescription.java JBR-8927,JBR-8545 windows-aarch64
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi003/TestDescription.java JBR-8927,JBR-8545 windows-aarch64
mTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription.java JBR-8927,JBR-8545 windows-aarch64
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi002/TestDescription.java JBR-8927,JBR-8545 windows-all
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi003/TestDescription.java JBR-8927,JBR-8545 windows-all
mTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription.java JBR-8927,JBR-8545 windows-all
vmTestbase/nsk/monitoring/ThreadMXBean/findMonitorDeadlockedThreads/find006/TestDescription.java 8310144 macosx-aarch64

View File

@@ -1034,6 +1034,8 @@ jdk_awt_wayland = \
-java/awt/MultipleGradientPaint \
-java/awt/Multiscreen/MouseEventTest/MouseEventTest.java \
-java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java \
-java/awt/Multiscreen/MultiScreenCheckScreenIDTest.java \
-java/awt/Multiscreen/UpdateGCTest/UpdateGCTest.java \
-java/awt/Paint/bug8024864.java \
-java/awt/Paint/ButtonRepaint.java \
-java/awt/Paint/CheckboxRepaint.java \
@@ -1087,6 +1089,7 @@ jdk_swing_wayland= \
-javax/swing/DefaultButtonModel/DefaultButtonModelCrashTest.java \
-javax/swing/dnd/7171812/bug7171812.java \
-javax/swing/event/FocusEventCauseTest.java \
-javax/swing/GraphicsConfigNotifier/TestMultiScreenGConfigNotify.java \
-javax/swing/JButton/4368790/bug4368790.java \
-javax/swing/JButton/8151303/PressedIconTest.java \
-javax/swing/JButton/bug4234034.java \

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2024-2025 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.
*
* 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.
*/
import jtreg.SkippedException;
import sun.awt.image.SurfaceManager;
import sun.java2d.SurfaceData;
import sun.java2d.vulkan.VKEnv;
import sun.java2d.vulkan.VKGraphicsConfig;
import sun.java2d.vulkan.VKRenderQueue;
import sun.java2d.vulkan.VKSurfaceData;
import java.awt.*;
import java.awt.image.VolatileImage;
import java.lang.foreign.MemorySegment;
import java.lang.ref.WeakReference;
/*
* @test
* @requires os.family == "linux"
* @library /test/lib
* @summary Verifies that disposal of blit destination image doesn't crash the process.
* @modules java.desktop/sun.java2d.vulkan:+open java.desktop/sun.java2d:+open java.desktop/sun.awt.image:+open
* @run main/othervm -Djava.awt.headless=true -Dsun.java2d.vulkan=True -Dsun.java2d.vulkan.accelsd=true -Dsun.java2d.vulkan.leOptimizations=true VulkanDisposeBlitDstTest
*/
public class VulkanDisposeBlitDstTest {
public static void main(String[] args) throws Exception {
if (!VKEnv.isVulkanEnabled()) {
throw new Error("Vulkan not enabled");
}
if (!VKEnv.isSurfaceDataAccelerated()) {
throw new Error("Accelerated surface data not enabled");
}
VKGraphicsConfig gc = VKEnv.getDevices().findFirst().get().getOffscreenGraphicsConfigs().findFirst().get();
VolatileImage a = gc.createCompatibleVolatileImage(100, 100, VolatileImage.TRANSLUCENT, VKSurfaceData.RT_TEXTURE);
VolatileImage b = gc.createCompatibleVolatileImage(100, 100, VolatileImage.TRANSLUCENT, VKSurfaceData.RT_TEXTURE);
// Blit a onto b
Graphics2D g = (Graphics2D) b.getGraphics();
g.drawImage(a, 0, 0, null);
g.dispose();
// Dispose b
WeakReference<SurfaceData> ref = new WeakReference<>(SurfaceManager.getManager(b).getPrimarySurfaceData());
MemorySegment vksd = MemorySegment.ofAddress(ref.get().getNativeOps()).reinterpret(160); // sizeof(VKSDOps)
b = null;
final int MAX_ITERATIONS = 1000;
for (int i = 0; i < MAX_ITERATIONS && ref.get() != null; i++) System.gc();
if (ref.get() != null) throw new SkippedException("SurfaceData was not collected after " + MAX_ITERATIONS + " iterations");
// Mess b's native data
Thread.sleep(100);
vksd.fill((byte) 0xec);
// Mutate a
g = (Graphics2D) a.getGraphics();
g.fillRect(10, 10, 10, 10);
g.dispose();
VKRenderQueue.getInstance().flushNow();
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2024-2025 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.
*
* 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.
*/
import jtreg.SkippedException;
import sun.awt.image.SurfaceManager;
import sun.java2d.SurfaceData;
import sun.java2d.vulkan.VKEnv;
import sun.java2d.vulkan.VKGraphicsConfig;
import sun.java2d.vulkan.VKRenderQueue;
import sun.java2d.vulkan.VKSurfaceData;
import java.awt.*;
import java.awt.image.VolatileImage;
import java.lang.foreign.MemorySegment;
import java.lang.ref.WeakReference;
/*
* @test
* @requires os.family == "linux"
* @library /test/lib
* @summary Verifies that disposal of blit source image doesn't crash the process.
* @modules java.desktop/sun.java2d.vulkan:+open java.desktop/sun.java2d:+open java.desktop/sun.awt.image:+open
* @run main/othervm -Djava.awt.headless=true -Dsun.java2d.vulkan=True -Dsun.java2d.vulkan.accelsd=true -Dsun.java2d.vulkan.leOptimizations=true VulkanDisposeBlitSrcTest
*/
public class VulkanDisposeBlitSrcTest {
public static void main(String[] args) throws Exception {
if (!VKEnv.isVulkanEnabled()) {
throw new Error("Vulkan not enabled");
}
if (!VKEnv.isSurfaceDataAccelerated()) {
throw new Error("Accelerated surface data not enabled");
}
VKGraphicsConfig gc = VKEnv.getDevices().findFirst().get().getOffscreenGraphicsConfigs().findFirst().get();
VolatileImage a = gc.createCompatibleVolatileImage(100, 100, VolatileImage.TRANSLUCENT, VKSurfaceData.RT_TEXTURE);
VolatileImage b = gc.createCompatibleVolatileImage(100, 100, VolatileImage.TRANSLUCENT, VKSurfaceData.RT_TEXTURE);
// Blit a onto b
Graphics2D g = (Graphics2D) b.getGraphics();
g.drawImage(a, 0, 0, null);
g.dispose();
// Dispose a
WeakReference<SurfaceData> ref = new WeakReference<>(SurfaceManager.getManager(a).getPrimarySurfaceData());
MemorySegment vksd = MemorySegment.ofAddress(ref.get().getNativeOps()).reinterpret(160); // sizeof(VKSDOps)
a = null;
final int MAX_ITERATIONS = 1000;
for (int i = 0; i < MAX_ITERATIONS && ref.get() != null; i++) System.gc();
if (ref.get() != null) throw new SkippedException("SurfaceData was not collected after " + MAX_ITERATIONS + " iterations");
// Mess a's native data
Thread.sleep(100);
vksd.fill((byte) 0xec);
// Flush b
b.getSnapshot();
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright 2025 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.
*
* 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.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.util.concurrent.CountDownLatch;
/*
* @test
* @requires os.family == "linux"
* @summary Verifies that robot correctly pick color
* @run main/othervm -Dawt.toolkit.name=WLToolkit -Dsun.java2d.vulkan=True -Dsun.java2d.vulkan.accelsd=true ClipRenderTest
* @run main/othervm -Dawt.toolkit.name=WLToolkit -Dsun.java2d.vulkan=True -Dsun.java2d.vulkan.accelsd=false ClipRenderTest
* @run main/othervm -Dawt.toolkit.name=WLToolkit -Dsun.java2d.vulkan=False ClipRenderTest
*/
public class ClipRenderTest {
final static int W = 600;
final static int H = 600;
final static CountDownLatch latchShownFrame = new CountDownLatch(1);
static volatile boolean failed = false;
static boolean compareColors(Color c1, Color c2, double tolerance) {
return Math.abs(c1.getRed() - c2.getRed()) < tolerance &&
Math.abs(c1.getGreen() - c2.getGreen()) < tolerance &&
Math.abs(c1.getBlue() - c2.getBlue()) < tolerance;
}
public static void main(String[] args) throws InterruptedException, AWTException {
if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) {
System.out.println("No WLToolkit, skipping test");
return;
}
final Robot robot = new Robot();
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Robot Test");
frame.setSize(W, H);
frame.add(new JPanel(){
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setClip(0, 0, W, H);
g2d.setColor(Color.BLUE);
g2d.setClip(new Ellipse2D.Double(W/3, H/3, W/3, H/3));
g2d.fillRect(W/3, H/3, W/3, H/3);
g2d.setClip(0, 0, W/3, H/3);
g2d.setColor(Color.RED);
g2d.fillRect(0, 0, W/3, H/3);
}
});
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowActivated(WindowEvent e) {
var loc = frame.getLocationOnScreen();
int x = loc.x + frame.getInsets().bottom + W/6;
int y = loc.y + frame.getInsets().left + H/6;
Color c = robot.getPixelColor(x, y);
if (!compareColors(c, Color.RED, 10)) {
System.out.println("Unexpected color: " + c + " at (" + x + ", " + y + ")");
failed = true;
}
x += W / 3;
y += H / 3;
c = robot.getPixelColor(x, y);
if (!compareColors(c, Color.BLUE, 10)) {
System.out.println("Unexpected color: " + c + " at (" + x + ", " + y + ")");
failed = true;
}
latchShownFrame.countDown();
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
latchShownFrame.await();
if (failed) throw new RuntimeException("Test failed");
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2025 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.
*
* 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.
*/
/**
* @test
* @summary
* @requires os.family == "linux"
* @key headful
* @library /test/lib
* @run main/othervm -Dsun.awt.wl.WindowDecorationStyle=builtin CloseOnlyDialogShownTest
*/
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
import java.awt.Robot;
import java.util.concurrent.atomic.AtomicReference;
public class CloseOnlyDialogShownTest {
public static void main(String[] args) throws Throwable {
AtomicReference<Throwable> edtFailure = new AtomicReference<>();
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
if (SwingUtilities.isEventDispatchThread()) {
edtFailure.compareAndSet(null, e);
e.printStackTrace();
}
});
AtomicReference<JDialog> holder = new AtomicReference<>();
SwingUtilities.invokeAndWait(() -> {
JDialog dialog = new JDialog((java.awt.Frame) null, "Close-only window", false);
holder.set(dialog);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.add(new JLabel("This dialog should show with only a close button."));
dialog.setMinimumSize(new Dimension(200, 120));
dialog.setVisible(true);
});
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(500);
SwingUtilities.invokeAndWait(() -> {
JDialog dialog = holder.get();
if (dialog != null) {
dialog.dispose();
}
});
if (edtFailure.get() != null) {
throw edtFailure.get();
}
}
}

View File

@@ -2,6 +2,7 @@ java/awt/Choice/ChoiceHandleMouseEvent_2.java JBR-7174 windows-all
java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java JBR-64 windows-all
java/awt/Choice/SelectItem/SelectCurrentItemTest.java JBR-8333 windows-all
java/awt/Choice/SelectItem/SelectNewItemTest.java JBR-8387 windows-x64
java/awt/datatransfer/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java JBR-9427 windows-x64
java/awt/Graphics/XORPaint.java#id0 JBR-7499 windows-x64
java/awt/Graphics2D/TextPerf.java JBR-8541 windows-x64
java/awt/grab/SystemMenuTest.java JBR-8944 windows-x64
@@ -18,7 +19,7 @@ java/awt/Mouse/MouseEnterExitTest.java JBR-8096 windows-x64
java/awt/Paint/PaintNativeOnUpdate.java JBR-5397,JBR-7415 macosx-all,windows-x64
java/awt/PopupMenu/PopupMenuLocation.java JBR-5397,JBR-7375 macosx-all,windows-x64
java/awt/Robot/CheckCommonColors/CheckCommonColors.java JBR-5397,JBR-6092 macosx-all,windows-x64
java/awt/Robot/NonEmptyErrorStream.java JBR-5510,JBR-7375 linux-5.18.2-arch1-1,windows-x64
java/awt/Robot/NonEmptyErrorStream.java JBR-7375 windows-x64
java/awt/Robot/RobotWheelTest/RobotWheelTest.java JBR-5397,JBR-7377 macosx-all,windows-x64
java/awt/Scrollbar/ScrollbarMouseWheelTest/ScrollbarMouseWheelTest.java JBR-5397,JBR-7531 macosx-all,windows-x64
java/awt/ScrollPane/ScrollPaneLimitation.java JBR-8579 windows-x64
@@ -37,12 +38,13 @@ javax/accessibility/JFileChooserAccessibleDescriptionTest.java JBR-5397,JBR-7379
javax/accessibility/SlowPanelIteration/SlowPanelIteration.java JBR-870,JBR-5397 windows-x64,linux-x64,macosx-all
javax/swing/event/FocusEventCauseTest.java JBR-7381 windows-x64
javax/swing/JButton/4796987/bug4796987.java JBR-9345 windows-x64
javax/swing/JButton/8151303/PressedIconTest.java JBR-5210,JBR-5510,JBR-5397 windows-all,linux-all,macosx-all
javax/swing/JButton/8151303/PressedIconTest.java JBR-5210,JBR-5397 windows-all,macosx-all
javax/swing/JComboBox/4743225/bug4743225.java JBR-5210,JBR-5397 windows-all,macosx-all
javax/swing/JComboBox/6559152/bug6559152.java JBR-5397,JBR-7382 macosx-all,windows-x64
javax/swing/JComboBox/8041909/ActionListenerExceptionTest.java JBR-5210 windows-all
javax/swing/JComboBox/bug4996503.java JBR-7412 windows-x64
javax/swing/JComboBox/EditableComboBoxPopupPos.java JBR-7383 windows-x64
javax/swing/JFileChooser/4150029/bug4150029.java JBR-9419 windows-x64
javax/swing/JFileChooser/4847375/bug4847375.java JBR-8855 windows-x64
javax/swing/JFileChooser/4966171/bug4966171.java JBR-8855 windows-x64
javax/swing/JFileChooser/FileChooserListenerLeak.java JBR-8855 windows-x64
@@ -51,7 +53,7 @@ javax/swing/JInternalFrame/Test6505027.java nobug macosx-all,linux-all,w
javax/swing/JMenuBar/MenuBarRTLBug.java JBR-7385 windows-x64
javax/swing/JPopupMenu/4634626/bug4634626.java nobug macosx-all,linux-all,windows-all
javax/swing/JPopupMenu/4966112/bug4966112.java nobug macosx-all,linux-all,windows-all
javax/swing/JPopupMenu/6415145/bug6415145.java 8197552,JBR-5397 macosx-all,windows-all
javax/swing/JPopupMenu/6415145/bug6415145.java JBR-5397 macosx-all
javax/swing/JSplitPane/4615365/JSplitPaneDividerLocationTest.java JBR-5397,JBR-5505 macosx-all,windows-all
javax/swing/JTree/4518432/JTreeNodeCopyPasteTest.java JBR-5397,JBR-8939 macosx-all,windows-x64
javax/swing/text/StyledEditorKit/4506788/bug4506788.java JBR-7386 windows-x64
@@ -61,6 +63,7 @@ jb/java/awt/Desktop/AboutHandlerTest.java nobug macosx-all,linux-all,w
jb/java/awt/Focus/ChainOfPopupsFocusTest.java JBR-8407 windows-x64
jb/java/awt/Focus/FrameAfterPopup.java JBR-9161 windows-x64
jb/java/awt/Focus/MaximizedCustomDecorationsTest.java JBR-9346 windows-x64
jb/java/awt/Focus/ModalDialogFromMenuTest.java JBR-9426 windows-x64
jb/java/awt/Focus/NewFrameAfterDialogTest.java JBR-7387 windows-x64
# VoiceOver on MacOS
@@ -93,16 +96,16 @@ javax/swing/JFileChooser/4524490/bug4524490.java JBR-5397,JBR-5846 macosx-all,wi
javax/swing/JFileChooser/6520101/bug6520101.java JBR-5397,JBR-7413 macosx-all,windows-x64
javax/swing/JFileChooser/8002077/bug8002077.java JBR-4880,JBR-5397 windows-all,macosx-all
javax/swing/JLabel/4138746/JLabelMnemonicsTest.java JBR-4949,JBR-5397 linux-all,windows-all,macosx-all
javax/swing/JLabel/6596966/bug6596966.java 8197552,JBR-5397 windows-all,macosx-all
javax/swing/JLabel/6596966/bug6596966.java JBR-5397 macosx-all
javax/swing/JList/4618767/JListSelectedElementTest.java JBR-4955,JBR-5397 windows-all,macosx-all
javax/swing/JList/6462008/bug6462008.java JBR-5397,JBR-6773 macosx-all,windows-all
javax/swing/JMenu/4213634/bug4213634.java 8197552,JBR-5397 windows-all,macosx-all
javax/swing/JMenu/4515762/bug4515762.java 8197552,JBR-5397 windows-all,macosx-all
javax/swing/JMenu/4213634/bug4213634.java JBR-5397 macosx-all
javax/swing/JMenu/4515762/bug4515762.java JBR-5397 macosx-all
javax/swing/JMenu/4692443/bug4692443.java JBR-5397,JBR-6093 macosx-all,windows-all
javax/swing/JMenu/6470128/bug6470128.java 8253184,JBR-6307,JBR-5397 windows-all,linux-all,macosx-all
javax/swing/JMenuBar/4750590/bug4750590.java JBR-5397,JBR-6094 macosx-all,windows-all
javax/swing/JMenuItem/4171437/bug4171437.java JBR-5397,JBR-6112 macosx-all,windows-all
javax/swing/JMenuItem/6249972/bug6249972.java 8197552,JBR-5397 windows-all,macosx-all
javax/swing/JMenuItem/6249972/bug6249972.java JBR-5397 macosx-all
javax/swing/JMenuItem/JMenuItemSetAcceleratorTest.java JBR-5397 macosx-all
javax/swing/JPopupMenu/4458079/bug4458079.java JBR-5397 macosx-all
javax/swing/JPopupMenu/4634626/bug4634626.java 8253184,JBR-5397 windows-all,macosx-all
@@ -123,7 +126,7 @@ javax/swing/plaf/basic/BasicRootPaneUI/HiddenDefaultButtonTest.java JBR-7310 win
javax/swing/plaf/synth/7158712/bug7158712.java JBR-125,8322653,JBR-5397 linux-all,windows-all,macosx-all
javax/swing/Popup/TaskbarPositionTest.java 8310689,JBR-5397 windows-all,macosx-all
javax/swing/text/CSSBorder/6796710/bug6796710.java JBR-5397,JBR-6465 macosx-all,windows-all,linux-aarch64
sanity/client/SwingSet/src/EditorPaneDemoTest.java JBR-5397,8212240,JBR-5510,JBR-6285,8253184 macosx-all,linux-all,windows-all
sanity/client/SwingSet/src/EditorPaneDemoTest.java JBR-5397,8212240,JBR-6285,8253184 macosx-all,linux-all,windows-all
sanity/client/SwingSet/src/ToolTipDemoTest.java JBR-5397 macosx-all
sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java JBR-5397 macosx-all
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5397 macosx-all
@@ -146,7 +149,7 @@ javax/swing/JComboBox/8182031/ComboPopupTest.java 8253184,JBR-5397 windows-all,m
javax/swing/JComboBox/JComboBoxPopupMenuEventTest.java JBR-5397 macosx-all
javax/swing/JComboBox/JComboBoxScrollFocusTest.java JBR-9094 windows-x64
javax/swing/JComboBox/JComboBoxWithTitledBorderTest.java JBR-5397 macosx-all
javax/swing/JEditorPane/8195095/ImageViewTest.java 8253184,JBR-5510,JBR-6283,JBR-5397 windows-all,linux-5.18.2-arch1-1,macosx-all
javax/swing/JEditorPane/8195095/ImageViewTest.java 8253184,JBR-6283,JBR-5397 windows-all,macosx-all
javax/swing/JSpinner/4670051/DateFieldUnderCursorTest.java JBR-5397 macosx-all
# Windows (ZoomText, NVDA, or JAWS is enabled during testing)
@@ -156,8 +159,8 @@ java/awt/Choice/ChoiceFreezeTest.java JBR-6952 windows-x64
java/awt/Choice/ChoiceMouseEventOutbounds.java TBD windows-x64
java/awt/Choice/ChoicePopupLocation/ChoicePopupLocation.java JBR-6857,JBR-5505 macosx-all,windows-all
java/awt/Choice/NonFocusablePopupMenuTest.java JBR-7961 windows-x64
java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java JBR-5510,8310487,JBR-6950 linux-5.18.2-arch1-1,linux-all,windows-x64
java/awt/Choice/ResizeAutoClosesChoice/ResizeAutoClosesChoice.java JBR-5510,JBR-5905 linux-5.18.2-arch1-1,linux-all,windows-x64
java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java 8310487,JBR-6950 linux-all,windows-x64
java/awt/Choice/ResizeAutoClosesChoice/ResizeAutoClosesChoice.java JBR-5905 linux-all,windows-x64
java/awt/Component/NativeInLightShow/NativeInLightShow.java JBR-7715 windows-x64
java/awt/Component/RepaintTest.java JBR-7754 windows-x64
java/awt/datatransfer/DragUnicodeBetweenJVMTest/DragUnicodeBetweenJVMTest.java JBR-5538 windows-x64
@@ -181,8 +184,8 @@ java/awt/im/memoryleak/InputContextMemoryLeakTest.java JBR-5505 windows-all
java/awt/LightweightComponent/MultipleAddNotifyTest/MultipleAddNotifyTest.java JBR-9252 windows-all
java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java JBR-5505 windows-all
java/awt/List/ItemEventTest/ItemEventTest.java JBR-5711,JBR-5505 windows-all,linux-all
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405,JBR-5510,JBR-5505 macosx-all,linux-5.18.2-arch1-1,windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-5510,JBR-5505 linux-5.18.2-arch1-1,windows-all
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405,JBR-5505 macosx-all,windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-5505 windows-all
java/awt/Mixing/MixingOnDialog.java JBR-5505 windows-all
java/awt/Mixing/MixingOnShrinkingHWButton.java JBR-5505 windows-all
java/awt/Mixing/OpaqueTest.java JBR-5707,JBR-5505 linux-all,windows-all

View File

@@ -13,7 +13,6 @@ javax/swing/JComponent/7154030/bug7154030.java JBR-7713 macosx-aarch64
javax/swing/JDialog/Transparency/TransparencyTest.java JBR-7554 macosx-aarch64
javax/swing/JSplitPane/4820080/JSplitPaneDragColorTest.java JBR-7247 macosx-all
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentCanvas.java JBR-7404 macosx-all
javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentPerPixelTranslucentGradient.java JBR-8327 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6
javax/swing/plaf/aqua/CustomComboBoxFocusTest.java JBR-5190 macosx-all
javax/swing/SwingGraphics/TranslateTest.java JBR-7510 macosx-aarch64

View File

@@ -112,17 +112,22 @@
############################################################################
java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java JBR-8960 windows-x64
java/awt/Focus/ModalDialogInFocusEventTest.java JBR-7818 linux-6.14.0-1010-aws
java/awt/Focus/ModalDialogInFocusEventTest.java JBR-7818 linux-6.14.0-1010-aws,linux-6.14.0-1012-aws,linux-6.14.0-1014-aws
java/awt/Frame/GetGraphicsStressTest/GetGraphicsStressTest.java JBR-8542 windows-all timeout
java/awt/Graphics2D/TextPerf.java JBR-8541 linux-all,windows-all
java/awt/GridBagLayout/ComponentShortage.java JBR-9347 macosx-x64
java/awt/GridBagLayout/ComponentShortage.java 8355280,JBR-9347 windows-all,linux-all,macosx-x64
java/awt/KeyboardFocusmanager/TypeAhead/EnqueueWithDialogTest/EnqueueWithDialogTest.java JBR-7077 linux-all,windows-all
java/awt/MenuItem/EnableTest.java JBR-8543 windows-all timeout
java/awt/Robot/NonEmptyErrorStream.java 8340330,JBR-5510,JBR-6275,JBR-8299,JBR-9259 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,macosx-all,linux-5.18.2-arch1-1,linux-aarch64,linux-6.15.8-100.fc41.x86_64
java/awt/Modal/MultipleDialogs/MixOfModalAndNonModalDialogs.java JBR-9317 linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Robot/NonEmptyErrorStream.java JBR-6275,JBR-8299,JBR-9259 macosx-all,linux-aarch64,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64
javax/swing/border/TestTitledBorderLeak.java JBR-9272 macosx-14.8
javax/swing/JButton/TestMnemonicAction.java JBR-6508 windows-all,linux-all,macosx-all
javax/swing/JComboBox/8072767/bug8072767.java JBR-5540 windows-all,macosx-all
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentCanvas.java JBR-7404 macosx-all
javax/swing/plaf/synth/7158712/bug7158712.java 8322653,JBR-9061 macosx-all,linux-6.8.0-1033-aws,linux-6.8.0-1036-aws
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,8340330,JBR-6274 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-all
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentGradient.java JBR-9446 macosx-all
javax/swing/plaf/synth/7158712/bug7158712.java 8322653,JBR-9061 macosx-all,linux-6.8.0-1033-aws,linux-6.8.0-1036-aws,linux-6.8.0-1039-aws
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,JBR-6274 windows-all,macosx-all
jb/build/ResolveSymbolsTest/ResolveSymbolsRealEnv.java JBR-8544 linux-all
jb/java/awt/Window/UndecoratedDialogInTransientsChain.java JBR-8710 windows-aarch64

View File

@@ -22,12 +22,12 @@ java/awt/Multiscreen/LocationRelativeToTest/LocationRelativeToTest.java 8253184,
java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java JBR-5442,JBR-6058 linux-all,windows-all
java/awt/Multiscreen/WindowGCChangeTest/WindowGCChangeTest.java JBR-5531,JBR-5442 macosx-all,linux-all
java/awt/Multiscreen/UpdateGCTest/UpdateGCTest.java JBR-5442 linux-all
java/awt/PopupMenu/PopupMenuLocation.java 8259913,8315878,JBR-7035,JBR-5442,JBR-7079 windows-all,macosx-aarch64,macosx-all,linux-all,linux-x64
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184,JBR-5510,JBR-5442,JBR-6092 windows-all,linux-all,macosx-aarch64
java/awt/PopupMenu/PopupMenuLocation.java 8259913,JBR-7035,JBR-5442,JBR-7079 windows-all,macosx-all,linux-all,linux-x64
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184,JBR-5442,JBR-6092 windows-all,linux-all,macosx-aarch64
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184,JBR-5442 windows-all,linux-all
java/awt/Robot/InfiniteLoopException.java 8342638,JBR-8830 windows-x64,windows-all,linux-all
java/awt/Robot/MouseLocationOnScreen/MouseLocationOnScreen.java JBR-5390 macosx-all,linux-all
java/awt/Robot/NonEmptyErrorStream.java JBR-5442,8340330,JBR-5510,JBR-8299 linux-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,linux-5.18.2-arch1-1,linux-aarch64
java/awt/Robot/NonEmptyErrorStream.java JBR-5442,JBR-8299 linux-all,,linux-aarch64
java/awt/Robot/RobotMoveMultiscreen.java JBR-5442 linux-all
java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java JBR-6065 windows-all
java/awt/Window/SlowMotion/SlowMotion.java JBR-5442 linux-all
@@ -108,7 +108,6 @@ java/awt/Modal/MultipleDialogs/MultipleDialogs4Test.java 8198665,8253184,JBR-551
java/awt/Paint/PaintNativeOnUpdate.java 8253184,JBR-5510 windows-all,linux-all
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8253184,NOBUG windows-all,linux-all
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureGtkTest.java NOBUG linux-all
java/awt/Window/8159168/SetShapeTest.java 8253184,JBR-5510 windows-all,linux-all
java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java JBR-5510 linux-all
java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java JBR-5510 linux-all
java/awt/Window/MultiWindowApp/MultiWindowAppTest.java 8253184,JBR-5510 windows-all,linux-all

View File

@@ -123,10 +123,12 @@ java/awt/event/MouseEvent/MouseClickTest/MouseClickTest.java 8168389 windows-all
java/awt/event/KeyEvent/CorrectTime/CorrectTime.java JBR-6665 linux-5.15.0-1083-aws,linux-5.15.0-1084-aws,windows-all
java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java 8224055,JBR-5906 macosx-all,linux-all
java/awt/event/MouseEvent/MouseButtonsAndKeyMasksTest/MouseButtonsAndKeyMasksTest.java JBR-6578 windows-all,linux-all
java/awt/event/SequencedEvent/MultipleContextsFunctionalTest.java 8305061 macosx-x64
java/awt/event/StressTest/MouseAndKeyEventStressTest.java JBR-6479 generic-all
java/awt/FileDialog/8003399/bug8003399.java JBR-6930 windows-all
java/awt/FlowLayout/PreferredLayoutSize.java JBR-6349 linux-all
java/awt/Focus/EmptyWindowKeyTest.java JBR-7913 windows-all
java/awt/Focus/FocusKeepTest.java JBR-9487 linux-6.8.0-1040-aws
java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java 8081489 generic-all
java/awt/Focus/FocusSubRequestTest/FocusSubRequestTest.java JBR-5178 windows-all
java/awt/Focus/FocusTransitionTest/FocusTransitionTest.java JBR-5809 linux-all
@@ -134,7 +136,7 @@ java/awt/Focus/FocusTraversalPolicy/ButtonGroupLayoutTraversal/ButtonGroupLayout
java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-all
java/awt/Focus/IconifiedFrameFocusChangeTest/IconifiedFrameFocusChangeTest.java 6849364 generic-all
java/awt/Focus/InactiveFocusRace.java 8023263,JBR-8586 linux-all,windows-x64
java/awt/Focus/InputVerifierTest3/InputVerifierTest3.java JBR-7311 linux-6.8.0-1036-aws
java/awt/Focus/InputVerifierTest3/InputVerifierTest3.java JBR-7311 linux-6.8.0-1036-aws,linux-6.8.0-1039-aws
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java 6848406 generic-all
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java 6848407 generic-all
java/awt/Focus/LabelScrollBarFocus.java JBR-8027 linux-all
@@ -144,11 +146,11 @@ java/awt/Focus/VetoableChangeListenerLoopTest.java JBR-5785 linux-all
java/awt/Frame/7024749/bug7024749.java JBR-5210 windows-all
java/awt/Frame/8158918/SetExtendedState.java JBR-6408 linux-all
java/awt/Frame/DisposeParentGC/DisposeParentGC.java JBR-7300 linux-all
java/awt/Frame/DisposeTest.java JBR-7937,JBR-7938,JBR-8718 macosx-aarch64,windows-x64,linux-5.18.2-arch1-1
java/awt/Frame/DisposeTest.java JBR-7937,JBR-7938 macosx-aarch64,windows-x64
java/awt/Frame/MaximizedUndecorated/MaximizedUndecorated.java 8022302 generic-all
java/awt/Frame/MaximizeUndecoratedTest.java JBR-8064 linux-all
java/awt/Frame/MaximizedToIconified/MaximizedToIconified.java JBR-7509 macosx-all
java/awt/Frame/MaximizedToMaximized/MaximizedToMaximized.java JBR-7947 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6
java/awt/Frame/MaximizedToMaximized/MaximizedToMaximized.java 8340374,JBR-7947 macosx-all
java/awt/Frame/MaximizedToOppositeScreen/MaximizedToOppositeScreenBig.java JBR-5303 windows-all
java/awt/Frame/RestoreToOppositeScreen/RestoreToOppositeScreen.java 8286840 linux-all
java/awt/Frame/InitialIconifiedTest.java 7144049,8203920 macosx-all,linux-all
@@ -202,49 +204,49 @@ java/awt/Focus/FocusPolicyTest.java 7160904 linux-all
java/awt/EventQueue/6980209/bug6980209.java 8198615 macosx-all
java/awt/Frame/SetMinimumSizeTest/SetMinimumSizeTest2.java JBR-5210 windows-all
java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java JBR-5210,JBR-6126 windows-all,linux-5.18.2-arch1-1,macosx-all
java/awt/grab/EmbeddedFrameTest1/EmbeddedFrameTest1.java 7080150,JBR-4880,8253184,JBR-5510 macosx-all,windows-all,linux-5.18.2-arch1-1
java/awt/grab/GrabOnUnfocusableToplevel/GrabOnUnfocusableToplevel.java 8169109,JBR-4880 linux-all,windows-all
java/awt/grab/EmbeddedFrameTest1/EmbeddedFrameTest1.java 7080150,JBR-4880,8253184 macosx-all,windows-all
java/awt/grab/GrabOnUnfocusableToplevel/GrabOnUnfocusableToplevel.java JBR-4880 windows-all
java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java 8168646 generic-all
java/awt/MenuShortcut/FunctionKeyShortcut.java JBR-9207 linux-6.15.8-100.fc41.x86_64
java/awt/MenuShortcut/FunctionKeyShortcut.java JBR-9207 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java 8049405,8253184 generic-all
java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java 8049405,8253184 generic-all
java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java 8294264 windows-x64
java/awt/Mixing/AWT_Mixing/OpaqueOverlappingChoice.java 8048171 generic-all
java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java 8159451 linux-all,windows-all,macosx-all
java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java 6986109 generic-all
java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java 6986109,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java 6986109, windows-all
java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java 8049405 generic-all
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405,JBR-5510 macosx-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java JBR-5210,8049405,JBR-5510 windows-all,macosx-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JButtonInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JButtonOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JColorChooserOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JEditorPaneInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JEditorPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JLabelInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JLabelOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JListInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JListOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JPanelInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JPanelOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JProgressBarInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JProgressBarOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JScrollBarInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JScrollBarOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java JBR-5210,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JSliderInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JSliderOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JSpinnerInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JSpinnerOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java 8158801,JBR-5510,JBR-8311 windows-all,linux-5.18.2-arch1-1,linux-all
java/awt/Mixing/AWT_Mixing/JTableOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JTextAreaInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JTextAreaOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405 macosx-all
java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java JBR-5210,8049405 windows-all,macosx-all
java/awt/Mixing/AWT_Mixing/JButtonInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JButtonOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JColorChooserOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JEditorPaneInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JEditorPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JLabelInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JLabelOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JListInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JListOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JPanelInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JPanelOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JProgressBarInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JProgressBarOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JScrollBarInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JScrollBarOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java JBR-5210 windows-all
java/awt/Mixing/AWT_Mixing/JSliderInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JSliderOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JSpinnerInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JSpinnerOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java 8158801,JBR-8311 windows-all,linux-all
java/awt/Mixing/AWT_Mixing/JTableOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JTextAreaInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JTextAreaOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801 windows-all
java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java 8253184 windows-all
java/awt/Mixing/HWDisappear.java 8253184 windows-all
java/awt/Mixing/MixingInHwPanel.java 8253184 windows-all
java/awt/Mixing/NonOpaqueInternalFrame.java 7124549 macosx-all
@@ -273,12 +275,12 @@ java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java 8073636,JBR-4211
java/awt/EventDispatchThread/PropertyPermissionOnEDT/PropertyPermissionOnEDT.java JBR-5225 windows-all
java/awt/FullScreen/AltTabCrashTest/AltTabCrashTest.java JBR-4905 windows-all,linux-all
java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 8266245 generic-all
java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java JBR-4275,JBR-4880,JBR-8278 linux-all,windows-all,macosx-all
java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java 7188711,8253184,JBR-8278 linux-all,windows-all,macosx-all
java/awt/FullScreen/UninitializedDisplayModeChangeTest/UninitializedDisplayModeChangeTest.java 7188711,8273617,JBR-4880,8253184 macosx-all,linux-all,windows-all
java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java JBR-4275,JBR-4880 linux-all,windows-all
java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java 8253184 windows-all
java/awt/FullScreen/UninitializedDisplayModeChangeTest/UninitializedDisplayModeChangeTest.java 8273617,JBR-4880,8253184 macosx-all,windows-all
java/awt/Focus/8013611/JDK8013611.java 8175366 windows-all,macosx-all
java/awt/Focus/6378278/InputVerifierTest.java JBR-5799 windows-all
java/awt/Focus/6981400/Test1.java 8029675,JBR-5510 windows-all,macosx-all,linux-5.18.2-arch1-1
java/awt/Focus/6981400/Test1.java 8029675 windows-all,macosx-all
java/awt/Focus/6981400/Test3.java 8173264 generic-all
java/awt/Focus/8000326/SetFocusTraversalKeysEnabledTest.java JBR-4997,JBR-5729 windows-all,linux-all
java/awt/Focus/8073453/AWTFocusTransitionTest.java JBR-5210,8298247 windows-all,linux-all
@@ -329,18 +331,18 @@ java/awt/TrayIcon/TrayIconMouseTest/TrayIconMouseTest.java 8150540,JBR-3107 wind
java/awt/TrayIcon/TrayIconPopup/TrayIconPopupClickTest.java 8150540,JBR-3107 windows-all,macosx-all,linux-all
java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java 8150540,JBR-3107 windows-all,linux-all
java/awt/Window/8027025/Test8027025.java 8253184 windows-all
java/awt/Window/8159168/SetShapeTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Window/8159168/SetShapeTest.java 8253184 windows-all
java/awt/Window/HandleWindowDestroyTest/HandleWindowDestroyTest.java JBR-6540 macosx-x64
java/awt/Window/SetWindowLocationByPlatformTest/SetWindowLocationByPlatformTest.java 8253184,JBR-5728 windows-all,linux-all
java/awt/Window/ShapedAndTranslucentWindows/SetShape.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Window/ShapedAndTranslucentWindows/SetShape.java 8253184 windows-all
java/awt/Window/ShapedAndTranslucentWindows/SetShapeAndClick.java 8197936,8253184 macosx-all,windows-all
java/awt/Window/ShapedAndTranslucentWindows/SetShapeDynamicallyAndClick.java 8013450,8253184 macosx-all,windows-all
java/awt/Window/ShapedAndTranslucentWindows/ShapedTranslucentWindowClick.java 8013450,8253184 macosx-all,windows-all
java/awt/Window/ShapedAndTranslucentWindows/TranslucentChoice.java 8253184 windows-all
java/awt/Window/ShapedAndTranslucentWindows/TranslucentWindowClick.java 8253184 windows-all
java/awt/Window/setLocRelativeTo/SetLocationRelativeToTest.java 8253184 windows-all
java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java JBR-5510,JBR-9192 linux-5.18.2-arch1-1,linux-6.15.8-100.fc41.x86_64
java/awt/Window/MultiWindowApp/MultiWindowAppTest.java 8253184,JBR-5510,JBR-6463 windows-all,linux-all
java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java JBR-9192 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Window/MultiWindowApp/MultiWindowAppTest.java 8253184,JBR-6463 windows-all,linux-all
java/awt/Window/ShapedAndTranslucentWindows/FocusAWTTest.java 8222328 windows-all,linux-all,macosx-all
java/awt/Window/ShapedAndTranslucentWindows/Shaped.java 8222328 windows-all,linux-all,macosx-all
java/awt/Window/ShapedAndTranslucentWindows/ShapedByAPI.java 8222328 windows-all,linux-all,macosx-all
@@ -354,12 +356,10 @@ java/awt/Window/Grab/GrabTest.java 8253184 windows-all
java/awt/Window/GrabSequence/GrabSequence.java 6848409 macosx-all,linux-all
java/awt/Window/LocationAtScreenCorner/LocationAtScreenCorner.java 8203371 linux-all
java/awt/FontClass/FontAccess.java JBR-5225 windows-all
java/awt/font/FontScaling/StretchedFontTest.java JBR-6225 macosx-all
java/awt/font/GlyphVector/LayoutCompatTest.java JBR-8437 linux-aarch64
java/awt/font/JNICheck/JNICheck.sh JBR-5011 linux-all
java/awt/font/TextLayout/ArabicDiacriticTest.java JBR-6760 linux-i386
java/awt/font/TextLayout/DecorationBoundsTest.java JBR-6760 linux-i386
java/awt/font/TextLayout/FormatCharAdvanceTest.java JBR-8289 macosx-all
java/awt/font/TextLayout/FontLayoutStressTest.java JBR-6760 linux-i386
java/awt/font/TextLayout/HitTest.java JBR-6760 linux-i386
java/awt/font/TextLayout/MissingCodePointLayoutTest.java JBR-6760 linux-i386
@@ -374,28 +374,24 @@ java/awt/font/TextLayout/VisibleAdvance.java JBR-6760 linux-i386
java/awt/image/BufferedImage/ICMColorDataTest/ICMColorDataTest.java 8233028 generic-all
java/awt/image/DrawImage/IncorrectAlphaSurface2SW.java 8056077 linux-all
java/awt/image/multiresolution/Corrupted2XImageTest.java 8264053 macosx-all
java/awt/image/multiresolution/MenuMultiresolutionIconTest.java JBR-4880,8253184,JBR-5510,JBR-6833 windows-all,linux-5.18.2-arch1-1,macosx-all
java/awt/image/multiresolution/MenuMultiresolutionIconTest.java JBR-4880,8253184,JBR-6833 windows-all,macosx-all
java/awt/image/multiresolution/MultiresolutionIconTest.java 8252812 windows-all,linux-all
java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java 8253184 windows-all
java/awt/print/Headless/HeadlessPrinterJob.java 8196088 windows-all
sun/awt/datatransfer/SuplementaryCharactersTransferTest.java 8011371 generic-all
sun/awt/font/TestArabicHebrew.java JBR-8826,JBR-9210 linux-5.18.2-arch1-1,linux-6.15.8-100.fc41.x86_64
sun/awt/font/TestDevTransform.java JBR-7882 linux-all,windows-all
sun/awt/font/TestArabicHebrew.java JBR-8826,JBR-9210 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
sun/awt/shell/ShellFolderMemoryLeak.java 8197794 windows-all
sun/awt/windows/TestPen.java JBR-8718 linux-5.18.2-arch1-1
sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java 8301177 generic-all
sun/java2d/DirectX/OpaqueImageToSurfaceBlitTest/OpaqueImageToSurfaceBlitTest.java JBR-5393 windows-aarch64
sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java 8196102 generic-all
sun/java2d/DirectX/RenderingToCachedGraphicsTest/RenderingToCachedGraphicsTest.java 8196180,8252812 windows-all,macosx-all,linux-all
sun/java2d/GdiRendering/GdiBlitOffscreenTest.java JBR-8718 linux-5.18.2-arch1-1
sun/java2d/loops/XORClearRect.java JBR-8718 linux-5.18.2-arch1-1
java/awt/Graphics/GDIResourceExhaustionTest.java JBR-8719 linux-5.18.2-arch1-1
java/awt/Graphics/NativeWin32Clear.java JBR-8689 linux-aarch64,linux-5.18.2-arch1-1
java/awt/Graphics/XORPaint.java#id1 JBR-8642 macosx-aarch64
java/awt/Graphics/XORPaint.java#id2 JBR-9348 linux-6.15.8-100.fc41.x86_64
java/awt/Graphics2D/CopyAreaOOB.java JBR-5354,JBR-9206 macosx-all,windows-all,linux-5.18.2-arch1-1,linux-6.15.8-100.fc41.x86_64
java/awt/Graphics2D/DrawString/DisposerTest.java JBR-5010,JBR-5510 linux-aarch64,linux-5.18.2-arch1-1
java/awt/Graphics/XORPaint.java#id2 JBR-9348 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Graphics2D/CopyAreaOOB.java JBR-5354,JBR-9206 macosx-all,windows-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Graphics2D/DrawString/DisposerTest.java JBR-5010 linux-aarch64
java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 generic-all
sun/java2d/SunGraphics2D/DrawImageBilinear.java 8297175 linux-all
sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java 8144029 macosx-all,linux-all,windows-all
@@ -418,13 +414,12 @@ java/awt/print/PrinterJob/GlyphPositions.java 7003378 generic-all
java/awt/Checkbox/CheckboxCheckerScalingTest.java JBR-8023 linux-all
java/awt/Choice/ChoiceLocationTest/ChoiceLocationTest.java JBR-5799 windows-all
java/awt/Choice/ChoiceFocusLostTest.java JBR-5799 windows-x64
java/awt/Choice/ChoiceMouseWheelTest/ChoiceMouseWheelTest.java 6849371,JBR-5210 macosx-all,linux-all,windows-all
java/awt/Choice/ChoiceMouseWheelTest/ChoiceMouseWheelTest.java JBR-5210 windows-all
java/awt/Choice/ChoicePopupLocation/ChoicePopupLocation.java JBR-6857 macosx-all
java/awt/Choice/NonFocusablePopupMenuTest.java JBR-7785 linux-5.18.2-arch1-1
java/awt/Component/ComponentLeakTest/ComponentLeakTest.java JBR-7911 windows-all
java/awt/Component/F10TopToplevel/F10TopToplevel.java JBR-5687 linux-all
java/awt/Component/GetScreenLocTest/GetScreenLocTest.java 4753654 generic-all
java/awt/Component/RepaintTest.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Component/SetComponentsBounds/SetComponentsBounds.java JBR-4275 linux-all
java/awt/Component/SetEnabledPerformance/SetEnabledPerformance.java 8165863 macosx-all
java/awt/Clipboard/PasteNullToTextComponentsTest.java 8234140 macosx-all,windows-all
@@ -443,7 +438,7 @@ java/awt/Frame/MiscUndecorated/FrameCloseTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244,JBR-5786 macosx-aarch64,generic-all
java/awt/Robot/HiDPIMouseClick/HiDPIRobotMouseClick.java 8253184 windows-all
java/awt/Robot/InfiniteLoopException.java 8342638 windows-all,linux-all
java/awt/Robot/NonEmptyErrorStream.java 8340330,JBR-5510,JBR-8299,JBR-9259 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,linux-5.18.2-arch1-1,linux-aarch64,linux-6.15.8-100.fc41.x86_64
java/awt/Robot/NonEmptyErrorStream.java JBR-8299,JBR-9259 linux-aarch64,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64
java/awt/Robot/RobotExtraButton/RobotExtraButton.java JBR-6554 linux-all
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009,8253184 macosx-all,windows-all
java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009,8253184 macosx-all,windows-all
@@ -536,7 +531,7 @@ java/awt/Modal/ModalBlockingTests/UnblockedDialogModelessTest.java 8198665,82531
java/awt/Modal/ModalBlockingTests/UnblockedDialogNonModalTest.java 8198665,8253184 macosx-all,windows-all
java/awt/Modal/ModalBlockingTests/UnblockedDialogSetModalTest.java 8198665,8253184 macosx-all,windows-all
java/awt/Modal/ModalBlockingTests/UnblockedDialogToolkitModalTest.java 8198665,8253184 macosx-all,windows-all
java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java 8066259,8253184,JBR-5510 macosx-all,windows-all,linux-5.18.2-arch1-1
java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java 8066259,8253184 macosx-all,windows-all
java/awt/Modal/ModalExclusionTests/ApplicationExcludeFrameFileTest.java 8047179,8253184 linux-all,macosx-all,windows-all
java/awt/Modal/ModalExclusionTests/ApplicationExcludeDialogFileTest.java 8047179,8253184 linux-all,macosx-all,windows-all
java/awt/Modal/ModalExclusionTests/ApplicationExcludeDialogPageSetupTest.java 8196431,8253184 linux-all,macosx-all,windows-all
@@ -588,15 +583,16 @@ java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal1Test.java 825318
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal2Test.java 8253184,8196432 windows-all,linux-all
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal3Test.java 8253184 windows-all
java/awt/Modal/ModalInternalFrameTest/ModalInternalFrameTest.java 8253184,JBR-6302 windows-all,linux-all
java/awt/Modal/MultipleDialogs/MixOfModalAndNonModalDialogs.java JBR-9317 linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Modal/MultipleDialogs/MultipleDialogs1Test.java 8198665,8253184 macosx-all,windows-all
java/awt/Modal/MultipleDialogs/MultipleDialogs2Test.java 8198665,8253184 macosx-all,windows-all
java/awt/Modal/MultipleDialogs/MultipleDialogs3Test.java 8198665,8253184 macosx-all,windows-all,linux-all
java/awt/Modal/MultipleDialogs/MultipleDialogs4Test.java 8198665,8253184,JBR-5510 macosx-all,windows-all,linux-5.18.2-arch1-1
java/awt/Modal/MultipleDialogs/MultipleDialogs4Test.java 8198665,8253184 macosx-all,windows-all
java/awt/Modal/MultipleDialogs/MultipleDialogs5Test.java 8198665,8253184 macosx-all,windows-all
java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java 8177326,8253184,JBR-6305 macosx-all,windows-all,linux-x64
java/awt/Mouse/EnterExitEvents/DragWindowTest.java 8253184 windows-all
java/awt/Mouse/EnterExitEvents/ModalDialogEnterExitEventsTest.java 8253184,JBR-5811 windows-all,linux-all
java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021,8253184,JBR-9208 macosx-all,windows-all,linux-6.15.8-100.fc41.x86_64
java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021,8253184,JBR-9208 macosx-all,windows-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java 8051455 macosx-all
java/awt/Mouse/ExtraMouseClick/ExtraMouseClick.java 8253184,JBR-5709 windows-all,linux-all
java/awt/Mouse/MouseComboBoxTest/MouseComboBoxTest.java 8253184,JBR-6752 windows-all,linux-all
@@ -625,8 +621,8 @@ java/awt/Modal/ToFront/FrameToFrontModal2Test.java 8253184 windows-all
java/awt/Modal/ToFront/FrameToFrontModal3Test.java 8253184 windows-all
java/awt/Modal/ToFront/FrameToFrontModal4Test.java 8253184 windows-all
java/awt/Modal/ToFront/FrameToFrontModal5Test.java 8253184 windows-all
java/awt/Modal/ToFront/FrameToFrontModeless1Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/ToFront/FrameToFrontNonModalTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/ToFront/FrameToFrontModeless1Test.java 8253184 windows-all
java/awt/Modal/ToFront/FrameToFrontNonModalTest.java 8253184 windows-all
java/awt/Modal/ToFront/FrameToFrontTKModal1Test.java 8253184 windows-all
java/awt/Modal/ToFront/FrameToFrontTKModal2Test.java 8253184 windows-all
java/awt/Modal/ToFront/FrameToFrontTKModal3Test.java 8253184 windows-all
@@ -675,24 +671,24 @@ java/awt/Modal/OnTop/OnTopAppModal3Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopAppModal4Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopAppModal5Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopAppModal6Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopDocModal1Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopDocModal2Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopDocModal3Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopDocModal4Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopDocModal5Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopDocModal6Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopDocModal1Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopDocModal2Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopDocModal3Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopDocModal4Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopDocModal5Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopDocModal6Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModal1Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModal2Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModal3Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModal4Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModal5Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModal6Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModeless1Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopModeless2Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopModeless3Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopModeless4Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopModeless5Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopModeless6Test.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Modal/OnTop/OnTopModeless1Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModeless2Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModeless3Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModeless4Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModeless5Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopModeless6Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopTKModal1Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopTKModal2Test.java 8253184 windows-all
java/awt/Modal/OnTop/OnTopTKModal3Test.java 8253184 windows-all
@@ -731,10 +727,9 @@ java/awt/Mouse/MouseWheelAbsXY/MouseWheelAbsXY.java 8253184 windows-all
java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java 6847163 linux-all,windows-all
java/awt/xembed/server/RunTestXEmbed.java 7034201 linux-all
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsDocModalTest.java 8164473 linux-all
java/awt/Frame/DecoratedFrameInsets/DecoratedFrameInsetsTest.java JBR-5205,JBR-9204 linux-5.4.0-1103-aws,linux-6.15.8-100.fc41.x86_64
java/awt/Frame/DynamicLayout/DynamicLayout.java JBR-9205 linux-6.15.8-100.fc41.x86_64
java/awt/Frame/DecoratedFrameInsets/DecoratedFrameInsetsTest.java JBR-5205,JBR-9204 linux-5.4.0-1103-aws,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Frame/DynamicLayout/DynamicLayout.java JBR-9205 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/GraphicsDevice/CheckDisplayModes.java JBR-8183 macosx-x64
java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java 7099223,8274106 macosx-all,linux-all,windows-all
java/awt/GraphicsDevice/DisplayModes/ExtraAllocationTest.java JBR-6384 macosx-all
java/awt/keyboard/AllKeyCode/AllKeyCode.java 8242930 macosx-all
@@ -756,8 +751,8 @@ java/awt/TrayIcon/RightClickWhenBalloonDisplayed/RightClickWhenBalloonDisplayed.
java/awt/Paint/bug8024864.java JBR-6544 generic-all
java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest/ComponentIsNotDrawnAfterRemoveAddTest.java 8253184,JBR-6844 windows-all,linux-5.18.2-arch1-1
java/awt/Paint/ListRepaint.java JBR-5060 linux-all
java/awt/Paint/PaintNativeOnUpdate.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/PopupMenu/PopupMenuLocation.java 8238720,JBR-7035,JBR-9257 windows-all,macosx-all,linux-6.15.8-100.fc41.x86_64
java/awt/Paint/PaintNativeOnUpdate.java 8253184 windows-all
java/awt/PopupMenu/PopupMenuLocation.java 8238720,JBR-7035,JBR-9251 windows-all,macosx-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/GridBagLayout/ComponentShortage.java 8355280 windows-all,linux-all
java/awt/GridBagLayout/GridBagLayoutIpadXYTest/GridBagLayoutIpadXYTest.java 8253184 windows-all
java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720,8322653 windows-all,macosx-all
@@ -772,10 +767,9 @@ java/awt/Window/MainKeyWindowTest/TestMainKeyWindow.java 8265985 macosx-all
java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeCrashTest.java JBR-5225 windows-all
java/awt/Robot/Delay/InterruptOfDelay.java 8265986 macosx-all
java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all
java/awt/Robot/ScreenCaptureRobotTest.java#id1 JBR-8720 linux-5.18.2-arch1-1
java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java JBR-5210,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243,JBR-5510,JBR-6632 macosx-all,linux-all
java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java JBR-5210 windows-all
java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243,JBR-6632 macosx-all,linux-all
java/awt/Dialog/ModalDialogPermission/ModalDialogPermission.java JBR-5225 windows-all
java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java JBR-5082 linux-all
java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787,8253184 linux-all,windows-all
@@ -833,7 +827,6 @@ javax/management/monitor/DerivedGaugeMonitorTest.java 8042211 generic-al
java/io/Console/CharsetTest.java JBR-8938 macosx-all
java/io/File/DeleteReadOnly.java JBR-8903 windows-all
java/io/File/EmptyPath.java JBR-8538 generic-all
java/io/File/WinTrailingSpace.java JBR-8978 windows-all
java/io/pathNames/GeneralWin32.java 8180264 windows-all
java/io/Serializable/font/FontSerialization.java JBR-8452 macosx-all,windows-all
@@ -847,9 +840,9 @@ com/sun/management/OperatingSystemMXBean/GetSystemCpuLoad.java 8030957 aix-all
java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java 8247426 generic-all
sun/management/jdp/JdpDefaultsTest.java 8241865,JBR-9229 linux-aarch64,macosx-all,linux-6.15.8-100.fc41.x86_64
sun/management/jdp/JdpJmxRemoteDynamicPortTest.java 8241865,JBR-9229 macosx-all,linux-6.15.8-100.fc41.x86_64
sun/management/jdp/JdpSpecificAddressTest.java 8241865,JBR-9229 macosx-all,linux-6.15.8-100.fc41.x86_64
sun/management/jdp/JdpDefaultsTest.java 8241865,JBR-9229 linux-aarch64,macosx-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
sun/management/jdp/JdpJmxRemoteDynamicPortTest.java 8241865,JBR-9229 macosx-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
sun/management/jdp/JdpSpecificAddressTest.java 8241865,JBR-9229 macosx-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.java JBR-8707 windows-all
sun/management/jmxremote/bootstrap/RmiBootstrapTest.java#id0 JBR-8707 windows-all
@@ -891,15 +884,16 @@ java/net/MulticastSocket/Test.java 7145658 macosx-a
# jdk_nio
java/nio/channels/AsynchronousSocketChannel/StressLoopback.java JBR-8817 windows-aarch64
java/nio/channels/DatagramChannel/AdaptorMulticasting.java 8144003,JBR-8455,JBR-8456,8308807,JBR-9219 macosx-all,aix-ppc64,linux-6.15.8-100.fc41.x86_64
java/nio/channels/DatagramChannel/AdaptorMulticasting.java 8144003,JBR-8455,JBR-8456,8308807,JBR-9219 macosx-all,aix-ppc64,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/nio/channels/DatagramChannel/BasicMulticastTests.java 8144003 macosx-all
java/nio/channels/DatagramChannel/Loopback.java JBR-9219 linux-6.15.8-100.fc41.x86_64
java/nio/channels/DatagramChannel/Loopback.java JBR-9219 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/nio/channels/DatagramChannel/ManySourcesAndTargets.java 8264385 macosx-aarch64
java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java 8144003,JBR-9218 macosx-all,linux-6.15.8-100.fc41.x86_64
java/nio/channels/DatagramChannel/Promiscuous.java 8144003,JBR-9218 macosx-all,linux-6.15.8-100.fc41.x86_64
java/nio/channels/DatagramChannel/PromiscuousIPv6.java JBR-8828,JBR-9218 macosx-x64,linux-6.15.8-100.fc41.x86_64
java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java 8144003,JBR-9218 macosx-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/nio/channels/DatagramChannel/Promiscuous.java 8144003,JBR-9218 macosx-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/nio/channels/DatagramChannel/PromiscuousIPv6.java JBR-8828,JBR-9218 macosx-x64,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/nio/channels/DatagramChannel/SendReceiveMaxSize.java JBR-9447 linux-6.14.0-1013-aws,linux-6.14.0-1014-aws
java/nio/channels/DatagramChannel/Unref.java 8233437 generic-all
java/nio/channels/FileChannel/LargeGatheringWrite.java JBR-9316 linux-6.15.8-100.fc41.x86_64
java/nio/channels/FileChannel/LargeGatheringWrite.java JBR-9316 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/nio/channels/Selector/LotsOfInterrupts.java#virtual JBR-8940 windows-aarch64
java/nio/channels/Selector/Wakeup.java 6963118 windows-all
@@ -952,7 +946,7 @@ sun/security/smartcardio/TestExclusive.java 8039280 generic-
sun/security/smartcardio/TestMultiplePresent.java 8039280 generic-all
sun/security/smartcardio/TestPresent.java 8039280 generic-all
sun/security/smartcardio/TestTransmit.java 8039280 generic-all
sun/security/ssl/SSLSessionImpl/MultiNSTClient.java JBR-9058 macosx-15.5,macosx-15.6
sun/security/ssl/SSLSessionImpl/MultiNSTClient.java JBR-9058 macosx-15.5,macosx-15.6,macosx-15.7,macosx-15.7.1
com/sun/crypto/provider/Cipher/DES/PerformanceTest.java 8039280 generic-all
com/sun/security/auth/callback/TextCallbackHandler/Default.java 8039280 generic-all
com/sun/security/auth/callback/TextCallbackHandler/Password.java 8039280 generic-all
@@ -1029,17 +1023,16 @@ javax/script/ScriptEngineOrder.sh JBR-8506 windows-all
javax/swing/plaf/basic/BasicComboPopup/JComboBoxPopupLocation/JComboBoxPopupLocation.java 8194945 macosx-all
javax/swing/plaf/basic/BasicDirectoryModel/LoaderThreadCount.java 8333880 windows-all
javax/swing/plaf/basic/BasicHTML/4251579/bug4251579.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/plaf/basic/BasicHTML/4251579/bug4251579.java 8253184 windows-all
javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java 8253184 windows-all
javax/swing/plaf/basic/BasicRootPaneUI/HiddenDefaultButtonTest.java JBR-8795 linux-aarch64
javax/swing/plaf/basic/BasicTableHeaderUI/6394566/bug6394566.java JBR-5846 windows-all
javax/swing/plaf/basic/BasicTextUI/8001470/bug8001470.java 8233177 linux-all,windows-all
javax/swing/plaf/basic/BasicTreeUI/8023474/bug8023474.java 8253184 linux-all,windows-all
javax/swing/plaf/nimbus/8041642/bug8041642.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/plaf/nimbus/8057791/bug8057791.java 8253184,JBR-5510,JBR-8300 windows-all,linux-5.18.2-arch1-1,macosx-all
javax/swing/plaf/nimbus/TestNimbusBGColor.java JBR-6464,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/plaf/nimbus/8041642/bug8041642.java 8253184 windows-all
javax/swing/plaf/nimbus/8057791/bug8057791.java 8253184,JBR-8300 windows-all,macosx-all
javax/swing/plaf/nimbus/TestNimbusBGColor.java JBR-6464 windows-all,
javax/swing/plaf/nimbus/TestNimbusOverride.java 8253184,JBR-5829 windows-all,linux-all
javax/swing/plaf/nimbus/TestNimbusTabbedPaneIconPosition.java JBR-8718 linux-5.18.2-arch1-1
javax/swing/plaf/windows/6921687/bug6921687.java 8253184 windows-all
javax/swing/plaf/windows/WindowsRootPaneUI/WrongAltProcessing/WrongAltProcessing.java JBR-4372 windows-all
@@ -1048,10 +1041,10 @@ javax/swing/DataTransfer/bug4655513.java JBR-8849 windows-aarch64,windows-10.0
javax/swing/DefaultButtonModel/DefaultButtonModelCrashTest.java JBR-5210,JBR-5799 windows-all
javax/swing/dnd/7171812/bug7171812.java 8253184 windows-all
javax/swing/dnd/8139050/NativeErrorsInTableDnD.java 8202765,JBR-5210 macosx-all,linux-all,windows-all
javax/swing/GraphicsConfigNotifier/StalePreferredSize.java JBR-5210 windows-all
javax/swing/GraphicsConfigNotifier/StalePreferredSize.java JBR-5210,JBR-9273 windows-all,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
javax/swing/JButton/4368790/bug4368790.java JBR-5210 windows-all
javax/swing/JButton/4659800/SpaceKeyActivatesButton.java JBR-4949 linux-all,windows-all
javax/swing/JButton/8151303/PressedIconTest.java JBR-5210,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/JButton/8151303/PressedIconTest.java JBR-5210 windows-all
javax/swing/JButton/bug4323121.java JBR-8924 windows-all
javax/swing/JButton/bug4490179.java JBR-8925 windows-all
javax/swing/JButton/bug4234034.java JBR-8997 windows-x64
@@ -1061,9 +1054,10 @@ javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id1 JBR-7965 windows-al
javax/swing/JButton/TestMnemonicAction.java JBR-6508 windows-all,linux-all
javax/swing/JColorChooser/Test6524757.java JBR-5210 windows-all
javax/swing/JColorChooser/Test6827032.java JBR-5210 windows-all
javax/swing/JComboBox/4231298/JComboBoxPrototypeDisplayValueTest.java JBR-6777 linux-all
javax/swing/JComboBox/4743225/bug4743225.java JBR-5210 windows-all
javax/swing/JComboBox/6236162/bug6236162.java JBR-5210 windows-all
javax/swing/JComboBox/6406264/bug6406264.java JBR-5210,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/JComboBox/6406264/bug6406264.java JBR-5210 windows-all
javax/swing/JComboBox/6607130/bug6607130.java JBR-5799 windows-x64
javax/swing/JComboBox/bug4248128.java JBR-8669 windows-all
javax/swing/JComboBox/bug4459267.java JBR-8656 windows-x64
@@ -1077,17 +1071,16 @@ javax/swing/JComboBox/ConsumedKeyTest/ConsumedKeyTest.java JBR-5210 windows-all
javax/swing/JComboBox/EditableComboBoxPopupPos.java JBR-8793 windows-all
javax/swing/JComboBox/TestComboBoxComponentRendering.java JBR-8270 linux-all
javax/swing/JComponent/6683775/bug6683775.java 8172337 generic-all
javax/swing/JDialog/Transparency/TransparencyTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/JDialog/Transparency/TransparencyTest.java 8253184 windows-all
javax/swing/JFrame/MaximizeWindowTest.java 8321289,JBR-8292 linux-all
javax/swing/JFrame/NSTexturedJFrame/NSTexturedJFrame.java JBR-8837 macosx-all
javax/swing/JLabel/4138746/JLabelMnemonicsTest.java JBR-4949 linux-all,windows-all
javax/swing/JLabel/6596966/bug6596966.java 8197552,JBR-9195 windows-all,linux-6.15.8-100.fc41.x86_64
javax/swing/JLabel/6596966/bug6596966.java JBR-9195 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
javax/swing/JLabel/7004134/bug7004134.java JBR-5437 linux-all
javax/swing/JLabel/bug4822331.java JBR-7422 windows-all
javax/swing/JList/6462008/bug6462008.java JBR-8063 windows-all
javax/swing/JList/bug4251306.java JBR-8648 windows-all
javax/swing/JMenu/4213634/bug4213634.java 8197552,JBR-8056 windows-all
javax/swing/JMenu/4515762/bug4515762.java 8197552 windows-all
javax/swing/JMenu/4213634/bug4213634.java JBR-8056 windows-all
javax/swing/JMenu/4692443/bug4692443.java JBR-6093 windows-all
javax/swing/JMenu/6470128/bug6470128.java 8253184,JBR-6307 windows-all,linux-all
javax/swing/JMenu/6538132/bug6538132.java JBR-894 windows-all
@@ -1095,45 +1088,41 @@ javax/swing/JMenu/8072900/WrongSelectionOnMouseOver.java JBR-5799,JBR-6306 windo
javax/swing/JMenu/bug4140643.java JBR-8489 windows-all
javax/swing/JMenu/PopupReferenceMemoryLeak.java JBR-5890,JBR-6056 windows-aarch64,windows-x64
javax/swing/JMenuBar/TestMenuMnemonic.java JBR-7301 windows-all
javax/swing/JMenuBar/TestMenuMnemonicLinuxAndMac.java JBR-7927,JBR-8718 linux-5.15.0-1080-aws,linux-5.15.0-1083-aws,linux-5.15.0-1084-aws,linux-5.18.2-arch1-1
javax/swing/JMenuBar/4750590/bug4750590.java 8197552,JBR-6094 windows-all,windows-x64
javax/swing/JMenuItem/4171437/bug4171437.java 8197552,JBR-6112 windows-all,windows-x64
javax/swing/JMenuBar/TestMenuMnemonicLinuxAndMac.java JBR-7927,JBR-9416 linux-5.15.0-1080-aws,linux-5.15.0-1083-aws,linux-5.15.0-1084-aws,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
javax/swing/JMenuBar/4750590/bug4750590.java JBR-6094 windows-x64
javax/swing/JMenuItem/4171437/bug4171437.java JBR-6112 windows-x64
javax/swing/JMenuItem/4654927/bug4654927.java JBR-164,JBR-4337 windows-all,linux-all
javax/swing/JMenuItem/6209975/bug6209975.java 8253184 windows-all
javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java JBR-5510,JBR-5545 linux-all,windows-all
javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java JBR-5545 linux-all,windows-all
javax/swing/JMenuItem/bug4839464.java JBR-5911 windows-all
javax/swing/JMenuItem/6249972/bug6249972.java 8197552 windows-all
javax/swing/JOptionPane/7138665/bug7138665.java JBR-5799,JBR-8171 windows-all,linux-all
javax/swing/JPasswordField/TestDisabledPasswordFieldForegroundColor.java JBR-8718 linux-5.18.2-arch1-1
javax/swing/JPopupMenu/4966112/bug4966112.java 8253184,JBR-7946 windows-all,linux-aarch64
javax/swing/JPopupMenu/6415145/bug6415145.java 8197552,JBR-7946 windows-all,linux-aarch64
javax/swing/JPopupMenu/6415145/bug6415145.java JBR-7946 linux-aarch64
javax/swing/JPopupMenu/6495920/bug6495920.java JBR-6928 linux-all
javax/swing/JPopupMenu/6515446/bug6515446.java 8197552,JBR-6531 windows-all,linux-all
javax/swing/JPopupMenu/6515446/bug6515446.java JBR-6531 linux-all
javax/swing/JPopupMenu/6544309/bug6544309.java JBR-6532 windows-all,linux-all
javax/swing/JPopupMenu/8173739/TestPopupMenu.java JBR-6959 linux-aarch64
javax/swing/JPopupMenu/SetInvokerJPopupMenuTest.java JBR-6021 linux-all
javax/swing/JRadioButton/4314194/bug4314194.java JBR-8718 linux-5.18.2-arch1-1
javax/swing/JRadioButton/8033699/bug8033699.java 8197552 windows-all
javax/swing/JRadioButton/8075609/bug8075609.java 8197552,8266085,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java 8197552,8266085 windows-all
javax/swing/JRadioButton/8075609/bug8075609.java 8266085 windows-all
javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java 8266085 windows-all
javax/swing/JRadioButton/FocusTraversal/FocusTraversal.java 8266085 windows-all
javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedTranslucentPerPixelTranslucentGradient.java 8233582,JBR-6481 linux-all,windows-all,macosx-all
javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedPerPixelTranslucentGradient.java 8233582,JBR-6360 linux-all,windows-all,macosx-all
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentCanvas.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentSwing.java 8194128,8253184,JBR-5510,JBR-6515 macosx-all,windows-all,linux-5.18.2-arch1-1,linux-all
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentCanvas.java 8253184 windows-all
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentSwing.java 8194128,8253184,JBR-6515 macosx-all,windows-all,linux-all
javax/swing/JWindow/ShapedAndTranslucentWindows/SetShapeAndClickSwing.java 8013450,8253184 macosx-all,windows-all
javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentJComboBox.java 8024627,8253184 macosx-all,windows-all
javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentPerPixelTranslucentGradient.java JBR-8327 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.5,macosx-15.6,macosx-15.6.1,macosx-15.7,macosx-15.7
javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentWindowClickSwing.java 8253184 windows-all
javax/swing/LookAndFeel/8145547/DemandGTK3.sh JBR-5510,JBR-9202 linux-5.18.2-arch1-1,linux-6.15.8-100.fc41.x86_64
javax/swing/LookAndFeel/8145547/DemandGTK3.sh JBR-9202 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64
# The next test below is an intermittent failure
javax/swing/JTree/DnD/LastNodeLowerHalfDrop.java 8159131 linux-all
javax/swing/JTree/4330357/bug4330357.java 8253184,JBR-6466 windows-all,linux-all
javax/swing/JTree/4633594/JTreeFocusTest.java 7105441,JBR-5210 macosx-all,windows-all
javax/swing/JTree/4908142/bug4908142.java 8197552,JBR-5846,JBR-151 windows-all
javax/swing/JTree/4908142/bug4908142.java JBR-5846,JBR-151 windows-all
javax/swing/JTree/6578666/bug6578666.java JBR-8103 windows-all
javax/swing/AbstractButton/6711682/bug6711682.java 8060765 windows-all,macosx-all,linux-5.15.0-39-generic,linux-5.15.0-33-generic,linux-5.19.0-1025-aws
javax/swing/AbstractButton/bug4133768.java JBR-8718 linux-5.18.2-arch1-1
javax/swing/AbstractButton/bug6298940.java JBR-8307,JBR-8718 windows-all,linux-5.18.2-arch1-1
javax/swing/AbstractButton/bug6298940.java JBR-8307 windows-all
javax/swing/Action/8133039/bug8133039.java JBR-5210 windows-all
javax/swing/ButtonGroup/TestButtonGroupFocusTraversal.java JBR-5210,JBR-8268 windows-all,linux-all
javax/swing/event/RightAltKeyTest.java JBR-5210 windows-all
@@ -1152,26 +1141,21 @@ javax/swing/JFileChooser/6396844/TwentyThousandTest.java 8198003 generic-all
javax/swing/JFileChooser/8194044/FileSystemRootTest.java 8305413,8327236 windows-aarch64,windows-all
javax/swing/JFormattedTextField/bug4863121.java JBR-7424 windows-all
javax/swing/JFrame/8016356/bug8016356.java JBR-108 windows-all
javax/swing/JFrame/8175301/ScaledFrameBackgroundTest.java 8274106,JBR-5510 macosx-aarch64,linux-5.18.2-arch1-1
javax/swing/JFrame/8175301/ScaledFrameBackgroundTest.java 8274106 macosx-aarch64
javax/swing/JPopupMenu/6800513/bug6800513.java 7184956,JBR-6533 macosx-all,linux-all,windows-all
javax/swing/JSlider/bug4382876.java JBR-8666 linux-6.14.0-1010-aws
javax/swing/JSlider/bug4382876.java JBR-8666 linux-6.14.0-1010-aws,linux-6.14.0-1012-aws,linux-6.14.0-1014-aws,linux-6.16.7-100.fc41.x86_64
javax/swing/JScrollBar/4708809/bug4708809.java 8169957 windows-x64
javax/swing/JScrollPane/HorizontalMouseWheelOnShiftPressed/HorizontalMouseWheelOnShiftPressed.java 8197552 windows-all
javax/swing/JSplitPane/4885629/bug4885629.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JTabbedPane/4361477/bug4361477.java JBR-5932 linux-all
javax/swing/JTabbedPane/4624207/bug4624207.java 8064922,8197552,JBR-6235 macosx-all,windows-all,linux-all 8064922:macosx-all, 8197552:windows-all
javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java 8253184,JBR-8498,JBR-8718 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,linux-5.18.2-arch1-1
javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java JBR-8718,JBR-8493 linux-5.18.2-arch1-1,macosx-15.4.1,macosx-15.5,macosx-15.6
javax/swing/JTabbedPane/4624207/bug4624207.java 8064922,JBR-6235 macosx-all,linux-all 8064922:macosx-all
javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java 8253184,JBR-8498 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,macosx-15.7,macosx-15.7.1
javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java JBR-8493 macosx-15.4.1,macosx-15.5,macosx-15.6,macosx-15.7,macosx-15.7.1
javax/swing/JToggleButton/TestSelectedKey.java JBR-5846 windows-all
javax/swing/JToolBar/4529206/bug4529206.java JBR-5387 linux-all
javax/swing/JToolTip/6219960/bug6219960.java 8253184 windows-all
javax/swing/JToolTip/TestTooltipBackgroundColor.java JBR-5510,JBR-9201 linux-5.18.2-arch1-1,linux-6.15.8-100.fc41.x86_64
javax/swing/SwingGraphics/TranslateTest.java JBR-8718 linux-5.18.2-arch1-1
javax/swing/JToolTip/TestTooltipBackgroundColor.java JBR-9201 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java 8160720 generic-all
javax/swing/text/AbstractDocument/8190763/TestCCEOnEditEvent.java JBR-5799,JBR-8290 windows-all,linux-all
javax/swing/text/DefaultCaret/HidingSelection/HidingSelectionTest.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/text/TableView/TableViewLayoutTest.java 8194936,JBR-4316,JBR-5510 linux-5.18.2-arch1-1,linux-all
javax/swing/ToolTipManager/Test6256140.java 8197552 windows-all
javax/swing/text/TableView/TableViewLayoutTest.java 8194936,JBR-4316 linux-all
javax/swing/JFileChooser/6798062/bug6798062.java 8146446 windows-all
javax/swing/JComboBox/4515752/DefaultButtonTest.java JBR-5799 windows-all
javax/swing/JComboBox/4523758/bug4523758.java 8253184 windows-all
@@ -1183,8 +1167,8 @@ javax/swing/JInternalFrame/6288609/TestJInternalFrameDispose.java JBR-788 window
javax/swing/JInternalFrame/6647340/bug6647340.java 8253184 windows-all
javax/swing/JInternalFrame/8145060/TestJInternalFrameMinimize.java JBR-788 windows-all,linux-all
javax/swing/JInternalFrame/8145896/TestJInternalFrameMaximize.java JBR-5539 windows-all
javax/swing/JInternalFrame/JInternalFrameTest.java JBR-9193 linux-6.15.8-100.fc41.x86_64
javax/swing/JInternalFrame/Test6325652.java JBR-6111,JBR-9194 windows-all,linux-6.15.8-100.fc41.x86_64
javax/swing/JInternalFrame/JInternalFrameTest.java JBR-9193 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
javax/swing/JInternalFrame/Test6325652.java JBR-6111,JBR-9194 windows-all,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
javax/swing/JInternalFrame/Test6505027.java JBR-5954 linux-all,macosx-all
javax/swing/JInternalFrame/Test6802868.java 8253184 windows-all
javax/swing/JPopupMenu/4634626/bug4634626.java 8253184 windows-all
@@ -1192,40 +1176,39 @@ javax/swing/JPopupMenu/4760494/bug4760494.java 8253184 windows-all
javax/swing/JPopupMenu/4870644/bug4870644.java 8194130 macosx-all,linux-all
javax/swing/ProgressMonitor/ProgressMonitorEscapeKeyPress.java JBR-5210 windows-all
javax/swing/JEditorPane/6917744/bug6917744.java 8213124 macosx-all
javax/swing/JEditorPane/8195095/ImageViewTest.java 8253184,JBR-5510,JBR-6283 windows-all,linux-5.18.2-arch1-1,macosx-all
javax/swing/JEditorPane/8195095/ImageViewTest.java 8253184,JBR-6283 windows-all,macosx-all
javax/swing/JRootPane/4670486/bug4670486.java JBR-6631 windows-all
javax/swing/JRootPane/DefaultButtonTest.java JBR-5739 windows-all,linux-all
javax/swing/text/html/HTMLEditorKit/5043626/bug5043626.java JBR-5210 windows-all
javax/swing/text/html/StyleSheet/bug4476002.java JBR-8718 linux-5.18.2-arch1-1
javax/swing/text/html/StyleSheet/bug4936917.java JBR-899,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/text/html/StyleSheet/bug4936917.java JBR-899 windows-all
javax/swing/plaf/metal/MetalBorders/ScaledMetalBorderTest.java#id0 JBR-5799 windows-all
javax/swing/plaf/metal/MetalBorders/ScaledMetalBorderTest.java#id1 JBR-5779 linux-all,macosx-all
javax/swing/plaf/metal/MetalGradient/8163193/ButtonGradientTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java 8253184,JBR-5510,JBR-803 windows-all,linux-5.18.2-arch1-1,linux-all,macosx-all
javax/swing/plaf/metal/MetalGradient/8163193/ButtonGradientTest.java 8253184 windows-all
javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java 8253184,JBR-803 windows-all,linux-all,macosx-all
javax/swing/plaf/synth/7158712/bug7158712.java 8322653 macosx-all
javax/swing/plaf/synth/SynthScrollbarThumbPainter/SynthScrollbarThumbPainterTest.java 8253184 windows-all
javax/swing/plaf/synth/Test6660049.java JBR-8397 windows-x64
javax/swing/JInternalFrame/5066752/bug5066752.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/JInternalFrame/8160248/JInternalFrameDraggingTest.java JBR-5510,JBR-6546 linux-5.18.2-arch1-1,windows-x64
javax/swing/JInternalFrame/5066752/bug5066752.java 8253184 windows-all
javax/swing/JInternalFrame/8160248/JInternalFrameDraggingTest.java JBR-6546 windows-x64
javax/swing/JInternalFrame/8020708/bug8020708.java JBR-4879,JBR-6512 windows-all,linux-all
javax/swing/JInternalFrame/8069348/bug8069348.java 8253184,JBR-900,JBR-8718 macosx-aarch64,windows-all,linux-5.18.2-arch1-1
javax/swing/JInternalFrame/8069348/bug8069348.java 8253184,JBR-900 macosx-aarch64,windows-all
javax/swing/text/DefaultEditorKit/4278839/bug4278839.java CODETOOLS-7901623 windows-all
javax/swing/text/GlyphPainter2/6427244/bug6427244.java JBR-896,JBR-6760 windows-all,linux-i386
javax/swing/text/JTextComponent/5074573/bug5074573.java CODETOOLS-7901623,JBR-5386 windows-all,linux-all
javax/swing/text/JTextComponent/6361367/bug6361367.java JBR-521,JBR-6687 windows-all,linux-5.18.2-arch1-1
javax/swing/text/JTextComponent/6361367/bug6361367.java JBR-521 windows-all
javax/swing/text/View/8014863/bug8014863.java JBR-5541 windows-all,linux-all
javax/swing/text/View/8048110/bug8048110.java JBR-9256,JBR-9207 windows-all,linux-6.16.7-100.fc41.x86_64
javax/swing/text/View/8156217/FPMethodCalledTest.java JBR-5542 linux-all
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,8340330 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952 windows-all
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184 windows-all
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8253184 windows-all
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184 windows-all
java/awt/Robot/ModifierRobotKey/ModifierRobotKeyTest.java JBR-5802 windows-all
java/awt/Robot/MouseLocationOnScreen/MouseLocationOnScreen.java JBR-9209 linux-6.15.8-100.fc41.x86_64
java/awt/ColorClass/AlphaColorTest.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Robot/MouseLocationOnScreen/MouseLocationOnScreen.java JBR-9209 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
sanity/client/SwingSet/src/ToolTipDemoTest.java 8293001 linux-all
sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java 8265770,8273312,JBR-5510 windows-all,macosx-all,linux-5.18.2-arch1-1
sanity/client/SwingSet/src/ColorChooserDemoTest.java JBR-5510,JBR-8933 linux-5.18.2-arch1-1,windows-aarch64,windows-10.0
sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java 8265770,8273312 windows-all,macosx-all
sanity/client/SwingSet/src/ColorChooserDemoTest.java JBR-8933 windows-aarch64,windows-10.0
sanity/client/SwingSet/src/DialogDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/FileChooserDemoTest.java JBR-8397 windows-all
sanity/client/SwingSet/src/FrameDemoTest.java 8253184 windows-all
@@ -1254,7 +1237,6 @@ java/text/Format/NumberFormat/Bug4944439.java JBR-8458 macosx-all
tools/jimage/VerifyJimage.java JBR-8453,JBR-8540 macosx-all,generic-all
tools/jlink/JLink20000Packages.java JBR-8702 windows-all
tools/jlink/JLinkReproducible3Test.java 8253688 linux-aarch64
tools/jlink/plugins/SystemModuleDescriptors/SystemModulesTest.java JBR-4137 generic-all
tools/jlink/plugins/VendorInfoPluginsTest.java JBR-8783 windows-aarch64
tools/jpackage/share/AddLauncherTest.java#id1 JBR-8701 windows-all
@@ -1269,7 +1251,6 @@ tools/launcher/VersionCheck.java JBR-2053 windows-all
# jdk_jdi
com/sun/jdi/FinalizerTest.java 8343606 generic-all
com/sun/jdi/RepStep.java 8043571 generic-all
com/sun/jdi/InvokeHangTest.java 8218463 linux-all
com/sun/jdi/SetLocalWhileThreadInNative.java JBR-8537 generic-all
@@ -1302,10 +1283,6 @@ sun/tools/jstat/jstatLineCounts4.sh 8268211 linux-aa
# jdk_other
jdk/incubator/vector/Double256VectorTests.java JBR-8703 linux-aarch64
jdk/incubator/vector/DoubleMaxVectorTests.java JBR-8703 linux-aarch64
jdk/incubator/vector/Float256VectorTests.java JBR-8703 linux-aarch64
jdk/incubator/vector/FloatMaxVectorTests.java JBR-8703 linux-aarch64
jdk/incubator/vector/ShortMaxVectorTests.java 8306592 generic-i586
jdk/incubator/vector/LoadJsvmlTest.java 8305390 windows-x64
@@ -1314,7 +1291,6 @@ jdk/incubator/vector/LoadJsvmlTest.java 8305390 windows-
# jdk_jfr
jdk/jfr/event/compiler/TestCodeSweeper.java 8338127 generic-all
jdk/jfr/event/io/TestFileReadOnly.java JBR-8539 macosx-all
jdk/jfr/event/io/TestIOTopFrame.java 8362556 generic-all
jdk/jfr/event/oldobject/TestShenandoah.java 8342951 generic-all
jdk/jfr/event/runtime/TestDumpReason.java JBR-8780 windows-aarch64
@@ -1323,9 +1299,9 @@ jdk/jfr/event/runtime/TestShutdownEvent.java JBR-8781 windows-aarch64
jdk/jfr/jvm/TestDumpOnCrash.java JBR-8780 windows-aarch64
jdk/jfr/jvm/TestWaste.java 8282427 generic-all
jdk/jfr/api/consumer/recordingstream/TestOnEvent.java 8255404 linux-x64
jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java JBR-8460 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6
jdk/jfr/api/consumer/streaming/TestJVMCrash.java JBR-8459 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6
jdk/jfr/api/consumer/streaming/TestJVMExit.java JBR-8460 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6
jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java JBR-8460 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,macosx-15.7,macosx-15.7.1
jdk/jfr/api/consumer/streaming/TestJVMCrash.java JBR-8459 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,macosx-15.7,macosx-15.7.1
jdk/jfr/api/consumer/streaming/TestJVMExit.java JBR-8460 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,macosx-15.7,macosx-15.7.1
jdk/jfr/tool/TestPrint.java JBR-8704 macosx-all
############################################################################
@@ -1363,7 +1339,7 @@ javax/swing/JFileChooser/6698013/bug6698013.java 8024419 macosx-all
javax/swing/JColorChooser/8065098/bug8065098.java 8065647 macosx-all
java/awt/Modal/PrintDialogsTest/PrintDialogsTest.java 8068378 generic-all
javax/swing/JTabbedPane/4666224/bug4666224.html 8144124 macosx-all
javax/swing/JTextArea/4697612/bug4697612.java JBR-9200 linux-6.15.8-100.fc41.x86_64
javax/swing/JTextArea/4697612/bug4697612.java JBR-9200 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
javax/swing/JTextArea/7049024/bug7049024.java JBR-5836 linux-all
javax/swing/JTextArea/8149849/DNDTextToScaledArea.java 8253184 windows-all
java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java 8162380,JBR-4207 generic-all,windows-all
@@ -1442,13 +1418,12 @@ com/sun/java/swing/plaf/windows/AltFocusIssueTest.java
jb/hotspot/AsyncProfilerRunnerTest.java JBR-7175 macosx-all
jb/java/awt/CustomTitleBar/DialogNativeControlsTest.java JBR-8794 windows-aarch64
jb/java/awt/Graphics2D/TextRender/OGLMetalTextRender.java JBR-4091,JBR-5392 windows-aarch64,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6
jb/java/awt/Graphics2D/TextRender/OGLMetalTextRender.java JBR-4091,JBR-5392 windows-aarch64,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,macosx-15.7,macosx-15.7.1
jb/java/awt/event/TouchScreenEvent/TouchScreenEventsTestLinux.sh JBR-4078 linux-all
jb/java/awt/Font/Font467.java JBR-3960 generic-all
jb/java/awt/image/BufferedFontRenderingTest.java JBR-6493 generic-all
jb/java/awt/keyboard/AltGrMustGenerateAltGrModifierTest4207.java JBR-4207 windows-all
jb/java/awt/Toolkit/AWTThreadingTest.java JBR-4350 macosx-all
jb/java/awt/Toolkit/DetectingOSThemeTest.java JBR-9228 linux-6.15.8-100.fc41.x86_64
jb/java/awt/Toolkit/LWCToolkitInvokeAndWaitTest.java JBR-4896,JBR-5163 macosx-all,
java/awt/Dialog/NonResizableDialogSysMenuResize/NonResizableDialogSysMenuResize.java JBR-4250 windows-all
@@ -1465,20 +1440,18 @@ java/awt/event/KeyEvent/KeyPressedModifiers.java JBR-8647 windows-all
java/awt/Frame/LayoutOnMaximizeTest/LayoutOnMaximizeTest.java JBR-4880 windows-all
java/awt/Frame/MiscUndecorated/UndecoratedInitiallyIconified.java JBR-4880 windows-all
java/awt/FullScreen/SetFSWindow/FSFrame.java 8253184 windows-all
java/awt/FullScreen/SetFullScreenTest.java JBR-8214 linux-5.18.2-arch1-1
java/awt/grab/MenuDragEvents/MenuDragEvents.java JBR-4880 windows-all
java/awt/image/mlib/MlibOpsTest.java JBR-5225 windows-all
java/awt/MenuBar/SeparatorsNavigation/SeparatorsNavigation.java JBR-4880 windows-all
javax/swing/JFileChooser/8002077/bug8002077.java JBR-4880 windows-all
javax/swing/JFileChooser/8013442/Test8013442.java JBR-8397 windows-all
javax/swing/JSlider/6348946/bug6348946.java 8197552,JBR-5387 windows-all,linux-all
javax/swing/JSlider/6348946/bug6348946.java JBR-5387 windows-all,linux-all
javax/swing/JSpinner/4973721/bug4973721.java JBR-4880 windows-all
javax/swing/JSpinner/5012888/bug5012888.java JBR-4880,8169958 windows-all,linux-all
javax/swing/JSpinner/8223788/JSpinnerButtonFocusTest.java JBR-5210 windows-all
javax/swing/JSpinner/JSpinnerFocusTest.java JBR-5288 windows-all
javax/swing/JSpinner/SpinnerTest.java JBR-4880 windows-all
javax/swing/JSpinner/TestJSpinnerFocusLost.java JBR-5210 windows-all
javax/swing/JTable/7068740/bug7068740.java 8197552 windows-all
javax/swing/JTable/7124218/SelectEditTableCell.java JBR-6679 windows-all
javax/swing/JTable/8236907/LastVisibleRow.java JBR-6066 macosx-aarch64
javax/swing/JTable/BugCellEditorListener.java JBR-6678 windows-all
@@ -1487,15 +1460,11 @@ javax/swing/text/AbstractDocument/6968363/Test6968363.java JBR-4880,JBR-6760 win
javax/swing/text/FlowView/LayoutTest.java JBR-4880 windows-all
javax/swing/text/html/7189299/bug7189299.java JBR-4880 windows-all
jb/java/awt/wayland/ImageTransformTest.java JBR-8825 linux-5.18.2-arch1-1
jb/java/awt/wayland/RobotGetOOBPixelsTest.java JBR-8029 linux-all
jb/java/awt/wayland/RobotGetPixelTest.java JBR-8029 linux-all
jb/java/awt/wayland/RobotGetPixelsTest.java JBR-8029 linux-all
jb/java/awt/wayland/VulkanBlitTest.java JBR-8394 linux-5.18.2-arch1-1,linux-5.15.0-1081-aws,linux-5.15.0-1083-aws,linux-5.15.0-1084-aws
jb/java/awt/wayland/VulkanCompositeTest.java JBR-8394 linux-5.18.2-arch1-1,linux-5.15.0-1081-aws,linux-5.15.0-1083-aws,linux-5.15.0-1084-aws
jb/java/awt/wayland/VulkanGCCompatibilityTest.java JBR-8394 linux-5.18.2-arch1-1
jb/java/awt/wayland/VulkanMaskFillTest.java JBR-8394 linux-5.18.2-arch1-1
jb/java/io/IoOverNio/FileTest.java JBR-8723 linux-6.15.8-100.fc41.x86_64
jb/java/io/IoOverNio/FileTest.java JBR-8723 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
javax/swing/text/StyledEditorKit/bug4329418.java
jb/java/jcef/HandleJSQueryTest3314.sh JBR-4866 linux-all
jb/java/jcef/HwFacadeWindowNoFrontTest.java JBR-6556 windows-all
@@ -1516,10 +1485,10 @@ jb/javax/swing/JComboBox/ComboBoxTransparentTittleBarTest.java JBR-5432,JBR-4875
jb/javax/swing/JDialog/JDialog186.java JBR-5210 windows-all
jb/javax/swing/JDialog/JDialog392.java JBR-4941 macosx-all,linux-all
jb/javax/swing/JDialog/JDialog705.java JBR-4934 generic-all
jb/javax/swing/JDialog/JDialog1054.java JBR-5004 macosx-all
jb/javax/swing/JEditorPane/ZeroMargin.java JBR-2256 generic-all
jb/javax/swing/JPopupMenu/JPopupMenuOutOfWindowTest.java JBR-6682 windows-all,linux-all
jb/java/awt/Window/FullScreenTwoFrames.java JBR-8276 macosx-all
jb/java/awt/Window/ModalDialogAndPopup.java JBR-4984 macosx-all
jb/java/jcef/MouseEventTest.java JBR-4908 linux-all
@@ -1528,51 +1497,29 @@ jb/java/lang/System/SetEnv394.java JBR-2988 generic-aarch64
jb/build/CDSArchivesTest.sh JBR-6616 windows-aarch64
jb/build/ResolveSymbolsTest/ResolveSymbolsTestMinEnv.java JBR-7910 linux-all
java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java JBR-5510,8310487 linux-5.18.2-arch1-1,linux-all
java/awt/Choice/ResizeAutoClosesChoice/ResizeAutoClosesChoice.java JBR-5510,JBR-5905 linux-5.18.2-arch1-1,linux-all
java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java 8310487 linux-all
java/awt/Choice/ResizeAutoClosesChoice/ResizeAutoClosesChoice.java JBR-5905 linux-all
java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java 8315733 macosx-all
java/awt/Frame/InvisibleOwner/InvisibleOwner.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Mixing/LWComboBox.java JBR-7595 linux-6.15.8-100.fc41.x86_64
java/awt/Mixing/LWComboBox.java JBR-7595 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64
java/awt/Mixing/LWPopupMenu.java JBR-824 generic-all
java/awt/Mixing/OpaqueTest.java JBR-5707 linux-all
java/awt/Mixing/OverlappingButtons.java JBR-5707 linux-all
java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JComponent/7154030/bug7154030.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JEditorPane/TestBrowserBGColor.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JRadioButton/8041561/bug8041561.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JSplitPane/4820080/JSplitPaneDragColorTest.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/Popup/TaskbarPositionTest.java 8310689 windows-all,macosx-all
javax/swing/PopupFactory/6276087/NonOpaquePopupMenuTest.java 8298124,JBR-5949 macosx-all,linux-all,windows-all
javax/swing/plaf/nimbus/8041642/ScrollBarThumbVisibleTest.java JBR-6485 linux-all,windows-all
javax/swing/text/CSSBorder/6796710/bug6796710.java JBR-6465 windows-all
javax/swing/text/html/CSS/4530474/bug4530474.java JBR-5510,JBR-5951 linux-5.18.2-arch1-1,windows-x64
jb/java/awt/CustomTitleBar/ActionListenerTest.java JBR-5819 macosx-all,windows-all
javax/swing/text/html/CSS/4530474/bug4530474.java JBR-5951 windows-x64
jb/java/awt/CustomTitleBar/FrameNativeControlsTest.java JBR-5345 windows-all
jb/java/awt/CustomTitleBar/JDialogNativeControlsTest.java JBR-5345 windows-x64
jb/java/awt/CustomTitleBar/HitTestClientArea.java JBR-6675 windows-all
jb/java/awt/CustomTitleBar/HitTestNonClientArea.java JBR-5465,JBR-5550 windows-all
jb/java/awt/CustomTitleBar/MaximizeWindowTest.java JBR-5465,JBR-5550 windows-all
jb/java/awt/CustomTitleBar/MaximizedWindowFocusTest.java JBR-5828 windows-all
jb/java/awt/CustomTitleBar/MinimizingWindowTest.java JBR-5345 windows-all
jb/java/awt/CustomTitleBar/MouseEventsOnClientArea.java JBR-6914 windows-all
jb/java/awt/CustomTitleBar/NativeControlsVisibilityTest.java JBR-5345,JBR-6835 windows-all,macosx-all
jb/java/awt/CustomTitleBar/WindowsControlWidthTest.java JBR-5345 windows-all
jb/java/awt/CustomTitleBar/WindowResizeTest.java JBR-5592 windows-all
sanity/client/SwingSet/src/EditorPaneDemoTest.java JBR-5510 linux-5.18.2-arch1-1
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5510 linux-5.18.2-arch1-1
sun/java2d/GdiRendering/InsetClipping.java 7124403,JBR-6513 windows-all,macosx-all,linux-all
java/awt/Choice/PopdownGeneratesMouseEvents/PopdownGeneratesMouseEvents.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Insets/DialogInsets.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Menu/OpensWithNoGrab/OpensWithNoGrab.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JFormattedTextField/TestSelectedTextBackgroundColor.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JMenu/JMenuSelectedColorTest.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JSpinner/4670051/DateFieldUnderCursorTest.java JBR-6684 generic-all
javax/swing/JSpinner/4788637/bug4788637.java JBR-5510 linux-5.18.2-arch1-1
jb/java/awt/Focus/BrokenTraversalAWT.java JBR-5799 windows-all
jb/java/awt/Focus/ComplexFocusSequence.java JBR-6728 linux-all,windows-x64
@@ -1583,21 +1530,9 @@ jb/java/awt/Focus/PopupIncomingFocusTest.java JBR-5799 windows-all
jb/java/awt/Focus/TitleBarClickTest.java JBR-6394 linux-5.18.2-arch1-1
com/sun/java/swing/plaf/gtk/bug6492108.java JBR-8021 linux-all
com/sun/java/swing/plaf/gtk/TestBackSpaceAction.java JBR-8791 linux-all
com/sun/java/swing/plaf/gtk/TestFileChooserSingleDirectorySelection.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Choice/ChoiceGeneratesItemEvents.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Choice/ChoiceStaysOpenedOnTAB.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureGtkTest.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Toolkit/DesktopProperties/rfe4758438.java JBR-5510 linux-5.18.2-arch1-1
com/sun/java/swing/plaf/gtk/TestBackSpaceAction.java JBR-8570 linux-all
java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java JBR-5765 macosx-all
javax/swing/JMenu/TestDisabledMenuForegroundColor.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JPasswordField/TestSelectedTextBackgroundColor.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JProgressBar/TestJProgressBarHighlightColor.java JBR-5510,JBR-9199 linux-5.18.2-arch1-1,linux-6.15.8-100.fc41.x86_64
javax/swing/JSlider/TestJSliderRendering.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JSpinner/TestSelectedTextBackgroundColor.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JTextPane/TestJTextPaneBackgroundColor.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JTree/TestTreeBackgroundColor.java JBR-5510 linux-5.18.2-arch1-1
sun/java2d/ClassCastExceptionForInvalidSurface.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JProgressBar/TestJProgressBarHighlightColor.java JBR-9199 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/font/DoubleAntialiasTest.java JBR-6760 linux-i386
java/awt/Paint/RepaintOnAWTShutdown.java JBR-6760 linux-i386

View File

@@ -8,7 +8,7 @@ java/awt/dnd/DnDAWTLockTest.java JBR-8745 linux-all
java/awt/dnd/DragOverDropTargetPerformanceTest.java JBR-5799 windows-all
java/awt/dnd/DragSourceGCrashTest.java JBR-8745 linux-all
java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java JBR-8745 linux-all
java/awt/dnd/InterJVMLinkTest.java JBR-9255 linux-6.15.8-100.fc41.x86_64
java/awt/dnd/InterJVMLinkTest.java JBR-9255 linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Dialog/ChoiceModalDialogTest.java JBR-8724 windows-all
java/awt/dnd/MozillaDnDTest.java JBR-6442 linux-all
java/awt/event/ComponentEvent/TextComponentTextEventTest.java JBR-6287 windows-all
@@ -32,8 +32,8 @@ java/awt/Frame/SetMaximizedBounds/SetMaximizedBounds.java JBR-6090 windows-all
java/awt/Frame/WindowDragTest/WindowDragTest.java JBR-6090 windows-all
java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java 7124275,JBR-5799 macosx-all,windows-all
java/awt/Focus/NonFocusableWindowTest/NonfocusableOwnerTest.java JBR-7299,JBR-8728 linux-all,windows-all
java/awt/grab/EmbeddedFrameTest1/EmbeddedFrameTest1.java 7080150,JBR-4880,8253184,JBR-5510,JBR-8725 macosx-all,windows-all,linux-5.18.2-arch1-1,linux-6.8.0-all
java/awt/Graphics/LineClipTest.java JBR-5071 linux-aarch64
java/awt/grab/EmbeddedFrameTest1/EmbeddedFrameTest1.java 7080150,JBR-4880,8253184,JBR-8725 macosx-all,windows-all,linux-6.8.0-all
java/awt/Graphics/LineClipTest.java JBR-9386 linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Graphics/NativeWin32Clear.java JBR-8730 windows-all
java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720,8322653,JBR-5071 windows-all,macosx-all,linux-all
java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720,8322653,JBR-5071 windows-all,macosx-all,linux-all
@@ -44,17 +44,19 @@ java/awt/List/ItemEventTest/ItemEventTest.java JBR-5711,JBR-6234 linux-all,windo
java/awt/List/TriggerActionEventTest.java JBR-6234 windows-all
java/awt/MenuItem/SetLabelTest.java JBR-8731 windows-all
java/awt/MenuShortcut/ActionCommandTest.java JBR-8822 windows-10.0
java/awt/MenuShortcut/FunctionKeyShortcut.java JBR-8732 windows-all
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405,JBR-5510,JBR-6134 macosx-all,linux-5.18.2-arch1-1,windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java JBR-5510,JBR-6234 linux-5.18.2-arch1-1,windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-5510,JBR-6134 linux-5.18.2-arch1-1,windows-all
java/awt/MenuShortcut/FunctionKeyShortcut.java JBR-8732,JBR-9207 windows-all,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405,JBR-6134 macosx-all,windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java JBR-6234 windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-6134 windows-all
java/awt/Mixing/MixingOnDialog.java JBR-6134 windows-all
java/awt/Modal/BlockedMouseInputTest2.java JBR-6090 windows-all
java/awt/Mouse/MouseEnterExitTest.java JBR-8096 linux-all,windows-all
java/awt/Mouse/TitleBarDoubleClick/TitleBarDoubleClick.java JBR-7309 linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/MouseInfo/ContainerResizeMousePositionTest.java JBR-7881,JBR-7915,JBR-8746 macosx-all,linux-all
java/awt/PopupMenu/PopupMenuLocation.java 8238720,JBR-7035,JBR-8726 windows-all,macosx-all,linux-all
java/awt/Robot/ScreenCaptureRobotTest.java#id0 JBR-8784 macosx-all
java/awt/Scrollbar/UnitIncrementTest.java JBR-8733 windows-all
java/awt/TextArea/ScrollbarIntersectionTest/ScrollbarIntersectionTest.java 8253184,JBR-9387 windows-all,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/TextField/GetTextTest/GetTextTest.java JBR-8734 windows-all
java/awt/Window/AlwaysOnTop/SyncAlwaysOnTopFieldTest.java JBR-6845 linux-all
java/awt/Window/TopLevelLocation/TopLevelLocation.java JBR-5799 windows-all
@@ -68,7 +70,7 @@ javax/swing/JButton/bug4490179.java JBR-8925 windows-all
javax/swing/JFileChooser/JFileChooserSetLocationTest.java JBR-8098 linux-all,windows-all
javax/swing/JInternalFrame/4202966/IntFrameCoord.java JBR-9006 window-all
javax/swing/JMenu/bug4342646.java JBR-8727 linux-all,windows-all
javax/swing/JPopupMenu/6580930/bug6580930.java JBR-5071 linux-6.8.0-1033-aws,linux-6.8.0-1036-aws,linux-6.15.8-100.fc41.x86_64
javax/swing/JPopupMenu/6580930/bug6580930.java JBR-5071 linux-6.8.0-1033-aws,linux-6.8.0-1036-aws,linux-6.8.0-1039-aws,linux-6.15.8-100.fc41.x86_64,linux-6.16.7-100.fc41.x86_64
javax/swing/JTable/JTableRightOrientationTest.java JBR-8102 linux-all,windows-all
javax/swing/text/ParagraphView/6364882/bug6364882.java JBR-8747 linux-all
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-8357 linux-all
@@ -86,8 +88,8 @@ jb/java/awt/Window/UndecoratedDialogInTransientsChain.java
jdk/editpad/EditPadTest.java JBR-5712 windows-all
sanity/client/SwingSet/src/ColorChooserDemoTest.java JBR-8354,JBR-8933 linux-all,windows-aarch64,windows-10.0
sanity/client/SwingSet/src/EditorPaneDemoTest.java JBR-5510,JBR-6285 linux-5.18.2-arch1-1,linux-all
sanity/client/SwingSet/src/GridBagLayoutDemoTest.java JBR-6285 linux-all
sanity/client/SwingSet/src/EditorPaneDemoTest.java JBR-6285 generic-all
sanity/client/SwingSet/src/GridBagLayoutDemoTest.java JBR-6285 generic-all
sanity/client/SwingSet/src/InternalFrameDemoTest.java JBR-6685 linux-all
sanity/client/SwingSet/src/ToolTipDemoTest.java 8293001,JBR-6293 linux-all,windows-all
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5204 linux-all,macosx-all,windows-all
@@ -136,6 +138,7 @@ java/awt/Robot/HiDPIScreenCapture/ScreenCaptureResolutionTest.java nobug generic
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java nobug generic-all
java/awt/Robot/ScreenCaptureRobotTest.java#id1 nobug generic-all
java/awt/Toolkit/ScreenInsetsDPIVariation/ScreenInsetsDPIVariation.java nobug generic-all
java/awt/TrayIcon/RightClickWhenBalloonDisplayed/RightClickWhenBalloonDisplayed.java 8238720,JBR-6931 windows-all,linux-aarch64,linux-6.16.7-100.fc41.x86_64,linux-6.16.7-200.fc42.x86_64
java/awt/Window/8159168/SetShapeTest.java nobug generic-all
java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java nobug generic-all
java/awt/Window/GetScreenLocation/GetScreenLocationTest.java nobug generic-all

View File

@@ -1,113 +1,15 @@
java/awt/Clipboard/CopyAnimatedGIFTest.java JBR-9100 linux-all
java/awt/Component/GetScreenLocTest/ComponentGetLocationOnScreenNPETest.java JBR-9100 linux-all
java/awt/Component/Revalidate/Revalidate.java JBR-9100 linux-all
java/awt/event/ComponentEvent/ComponentResizedTest.java JBR-9100 linux-all
java/awt/event/MouseEvent/MenuDragMouseEventAbsoluteCoordsTest/MenuDragMouseEventAbsoluteCoordsTest.java JBR-9100 linux-all
java/awt/event/MouseEvent/MouseEventAbsoluteCoordsTest.java JBR-9100 linux-all
java/awt/event/MouseEvent/MouseWheelEventAbsoluteCoordsTest/MouseWheelEventAbsoluteCoordsTest.java JBR-9100 linux-all
java/awt/event/OtherEvents/UndecoratedShrink.java JBR-9100 linux-all
java/awt/EventDispatchThread/PreserveDispathThread/PreserveDispatchThread.java JBR-9100 linux-all
java/awt/FileDialog/ExceptionAfterSetDirectory.java JBR-9100 linux-all
java/awt/font/GlyphVector/LayoutCompatTest.java JBR-8262 linux-all
java/awt/font/Rotate/RotateTest3.java JBR-9100 linux-all
java/awt/FullScreen/SetFSWindow/FSFrame.java JBR-9100 linux-all
java/awt/Graphics2D/ScaledTransform/ScaledTransform.java JBR-9100 linux-all
java/awt/Insets/DialogInsets.java JBR-9100 linux-all
java/awt/Multiscreen/LocationRelativeToTest/LocationRelativeToTest.java JBR-9100 linux-all
java/awt/Multiscreen/MultiScreenCheckScreenIDTest.java JBR-8263 linux-x64
java/awt/Multiscreen/UpdateGCTest/UpdateGCTest.java.UpdateGCTest
java/awt/Toolkit/SunDisplayChangerLeakTest/SunDisplayChangerLeakTest.java JBR-9100 linux-all
java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Disable.java JBR-9100 linux-all
javax/swing/AbstractButton/bug4147740.java JBR-9100 linux-all
javax/swing/AbstractButton/bug4246045.java JBR-9100 linux-all
javax/swing/border/Test6981576.java JBR-9100 linux-all
java/awt/image/DrawImage/BlitRotateClippedArea.java JBR-9026 linux-all
java/awt/image/DrawImage/EABlitTest.java JBR-9027 linux-all
javax/swing/GraphicsConfigNotifier/StalePreferredSize.java JBR-9031 linux-all
javax/swing/GraphicsConfigNotifier/TestMultiScreenGConfigNotify.java JBR-8266 linux-x64
javax/swing/GroupLayout/8079640/bug8079640.java JBR-9100 linux-all
javax/swing/JButton/JButtonPaintNPE/JButtonPaintNPE.java JBR-9100 linux-all
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id0 JBR-7928,JBR-9341 linux-6.8.0-1036-aws,linux-6.14.9-arch1-1
javax/swing/JColorChooser/Test4177735.java JBR-9100 linux-all
javax/swing/JComboBox/8019180/Test8019180.java JBR-9100 linux-all
javax/swing/JComboBox/bug4276920.java JBR-9100 linux-all
javax/swing/JComboBox/ShowPopupAfterHidePopupTest/ShowPopupAfterHidePopupTest.java JBR-9100 linux-all
javax/swing/JComboBox/TestComboBoxHeight.java JBR-9100 linux-all
javax/swing/JComponent/4337267/bug4337267.java JBR-9100 linux-all
javax/swing/JComponent/bug4962718.java JBR-9100 linux-all
javax/swing/JComponent/bug4979794.java JBR-9100 linux-all
javax/swing/JEditorPane/4492274/bug4492274.java JBR-9100 linux-all
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id0 JBR-7928,JBR-9341 linux-6.8.0-1036-aws,linux-6.8.0-1039-aws,linux-6.14.9-arch1-1
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id2 JBR-7928 linux-6.8.0-1036-aws,linux-6.8.0-1039-aws
javax/swing/JEditorPane/JEditorPaneFontFallback.java JBR-8305 linux-all
javax/swing/JFileChooser/6489130/bug6489130.java JBR-9100 linux-all
javax/swing/JFileChooser/DeserializedJFileChooser/DeserializedJFileChooserTest.java JBR-9100 linux-all
javax/swing/JFileChooser/FileSizeCheck.java JBR-9100 linux-all
javax/swing/JFileChooser/FileViewNPETest.java JBR-9100 linux-all
javax/swing/JFormattedTextField/bug4741926.java JBR-9321 linux-6.14.9-arch1-1
javax/swing/JFormattedTextField/TestSelectedTextBackgroundColor.java JBR-9100 linux-all
javax/swing/JFrame/AlwaysOnTop/AlwaysOnTopImeTest.java JBR-9100 linux-all
javax/swing/JFrame/HangNonVolatileBuffer/HangNonVolatileBuffer.java JBR-9100 linux-all
javax/swing/JInternalFrame/6647340/bug6647340.java JBR-9100 linux-all
javax/swing/JInternalFrame/InternalFrameIsNotCollectedTest.java JBR-9100 linux-all
javax/swing/JLayer/6824395/bug6824395.java JBR-9100 linux-all
javax/swing/JLayer/8041982/bug8041982.java JBR-9100 linux-all
javax/swing/JMenu/8178430/LabelDotTest.java JBR-9100 linux-all
javax/swing/JPanel/bug4907772.java JBR-9100 linux-all
javax/swing/JPasswordField/TestSelectedTextBackgroundColor.java JBR-9277 linux-6.14.9-arch1-1
javax/swing/JProgressBar/8161664/ProgressBarMemoryLeakTest.java JBR-9100 linux-all
javax/swing/JProgressBar/TestJProgressBarHighlightColor.java JBR-9100 linux-all
javax/swing/JScrollPane/bug8044371.java JBR-9100 linux-all
javax/swing/JScrollPane/Test6526631.java JBR-9100 linux-all
javax/swing/JSlider/TestJSliderRendering.java JBR-9100 linux-all
javax/swing/JSpinner/8008657/bug8008657.java JBR-9100 linux-all
javax/swing/JSpinner/bug4656590.java JBR-9100 linux-all
javax/swing/JSpinner/bug4680204.java JBR-9100 linux-all
javax/swing/JSpinner/TestSelectedTextBackgroundColor.java JBR-9277 linux-6.14.9-arch1-1
javax/swing/JSplitPane/4816114/bug4816114.java JBR-9100 linux-all
javax/swing/JSplitPane/JSplitPaneTestNegDivSize.java JBR-9100 linux-all
javax/swing/JTabbedPane/7170310/bug7170310.java JBR-9100 linux-all
javax/swing/JTabbedPane/8017284/bug8017284.java JBR-9100 linux-all
javax/swing/JTabbedPane/8134116/Bug8134116.java JBR-9100 linux-all
javax/swing/JTabbedPane/8137169/ScrollableTabbedPaneTest.java JBR-9100 linux-all
javax/swing/JTabbedPane/GetComponentAtTest.java JBR-9100 linux-all
javax/swing/JTabbedPane/TabbedPaneNPECheck.java JBR-9100 linux-all
javax/swing/JTabbedPane/TestNPEStateChgListener.java JBR-9100 linux-all
javax/swing/JTable/4170447/bug4170447.java JBR-9100 linux-all
javax/swing/JTable/8032874/bug8032874.java JBR-9100 linux-all
javax/swing/JTable/bug4159300.java JBR-9100 linux-all
javax/swing/JTextArea/JTextAreaOrientationTest.java JBR-9100 linux-all
javax/swing/JTextArea/JTextAreaWordWrapTest.java JBR-9100 linux-all
javax/swing/JTextArea/TextViewOOM/TextViewOOM.java JBR-9100 linux-all
javax/swing/JTextPane/JTextPaneDocumentAlignment.java JBR-9100 linux-all
javax/swing/JTextPane/JTextPaneDocumentWrapping.java JBR-9100 linux-all
javax/swing/JTextPane/TestJTextPaneBackgroundColor.java JBR-9100 linux-all
javax/swing/JTree/8041705/DefaultTreeCellRendererBorderTest.java JBR-9100 linux-all
javax/swing/JViewport/7107099/bug7107099.java JBR-9100 linux-all
javax/swing/InputVerifier/VerifyTarget/VerifyTargetTest.java JBR-9320 linux-6.14.9-arch1-1
javax/swing/LookAndFeel/8145547/DemandGTK.java JBR-9100 linux-all
javax/swing/LookAndFeel/8145547/DemandGTK3.sh JBR-9100 linux-all
javax/swing/plaf/basic/6866751/bug6866751.java JBR-9100 linux-all
javax/swing/plaf/nimbus/Test6919629.java JBR-9100 linux-all
javax/swing/reliability/TaskZoomJFrameRepaint.java JBR-9100 linux-all
javax/swing/RepaintManager/DisplayListenerLeak/DisplayListenerLeak.java JBR-9100 linux-all
javax/swing/Security/6657138/ComponentTest.java JBR-9100 linux-all
javax/swing/SpringLayout/bug4756178.java JBR-9100 linux-all
javax/swing/SpringLayout/bug4803649.java JBR-9100 linux-all
javax/swing/system/6799345/TestShutdown.java JBR-9100 linux-all
javax/swing/text/CompositeView/bug4398059.java JBR-9100 linux-all
javax/swing/text/DefaultStyledDocument/DocNegLenCharAttrTest.java JBR-9100 linux-all
javax/swing/text/html/7189299/bug7189299.java JBR-9100 linux-all
javax/swing/text/html/HTMLDocument/8058120/bug8058120.java JBR-9100 linux-all
javax/swing/text/html/HTMLEditorKit/4242228/bug4242228.java JBR-9100 linux-all
javax/swing/text/html/ImageView/bug4329185.java JBR-9100 linux-all
javax/swing/text/html/InlineView/bug4623342.java JBR-9100 linux-all
javax/swing/text/html/parser/Parser/7165725/bug7165725.java JBR-9100 linux-all
javax/swing/text/html/StyleSheet/bug4476002.java JBR-9100 linux-all
javax/swing/text/html/TableView/bug4412522.java JBR-9100 linux-all
javax/swing/text/html/TableView/bug4690812.java JBR-9100 linux-all
javax/swing/text/html/TableView/bug4813831.java JBR-9100 linux-all
javax/swing/text/NavigationFilter/6735293/bug6735293.java JBR-9100 linux-all
javax/swing/text/rtf/RTFWriteParagraphAlignTest.java JBR-9100 linux-all
javax/swing/text/View/8048110/bug8048110.java JBR-9100 linux-all
javax/swing/tree/DefaultTreeCellEditor/bug4480602.java JBR-9100 linux-all
javax/swing/tree/FixedHeightLayoutCache/bug4745001.java JBR-9100 linux-all

View File

@@ -2,6 +2,7 @@ javax/swing/JFileChooser/6520101/bug6520101.java JBR-8434 linux-all
javax/swing/JMenu/bug4342646.java JBR-8727 linux-all
javax/swing/JTable/JTableRightOrientationTest.java JBR-8102 linux-all
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-8357 linux-all
javax/swing/text/ParagraphView/6364882/bug6364882.java JBR-8324 linux-all
jb/java/awt/wayland/vulkan/ImageTransformTest.java JBR-8434 linux-all
jb/java/awt/wayland/vulkan/RobotGetPixelsTest.java JBR-8434 linux-all

View File

@@ -1,30 +1,17 @@
java/awt/font/GlyphVector/LayoutCompatTest.java JBR-8262 linux-all
java/awt/MenuShortcut/FunctionKeyShortcut.java JBR-7932 linux-all
java/awt/Multiscreen/MultiScreenCheckScreenIDTest.java JBR-8263 linux-x64
java/awt/Multiscreen/UpdateGCTest/UpdateGCTest.java JBR-8264 linux-x64
javax/swing/AbstractDocument/bug4549069.java JBR-8267 linux-6.14.0-1010-aws
javax/swing/JComponent/6989617/bug6989617.java JBR-8796 linux-6.14.0-1010-aws
javax/swing/JComponent/6989617/bug6989617.java JBR-8796 linux-6.14.0-1010-aws,linux-6.14.0-1012-aws,linux-6.14.0-1014-aws
javax/swing/JDesktopPane/TestDesktopManagerNPE.java JBR-8449 linux-x64
javax/swing/GraphicsConfigNotifier/TestMultiScreenGConfigNotify.java JBR-8266 linux-x64
javax/swing/InputVerifier/VerifyTarget/VerifyTargetTest.java JBR-7520,JBR-9320 linux-6.8.0-1036-aws,linux-6.14.9-arch1-1
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id0 JBR-7928,JBR-9341 linux-6.8.0-1036-aws,linux-6.14.9-arch1-1
javax/swing/JEditorPane/bug4325606.java JBR-8267 linux-aarch64
javax/swing/InputVerifier/VerifyTarget/VerifyTargetTest.java JBR-7520,JBR-9320 linux-6.8.0-1036-aws,linux-6.8.0-1039-aws,linux-6.14.9-arch1-1
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id0 JBR-7928,JBR-9341 linux-6.8.0-1036-aws,linux-6.8.0-1039-aws,linux-6.14.9-arch1-1
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id2 JBR-7928,JBR-9341 linux-6.8.0-1036-aws,linux-6.8.0-1039-aws,linux-6.14.9-arch1-1
javax/swing/JEditorPane/JEditorPaneFontFallback.java JBR-8305 linux-all
javax/swing/JFormattedTextField/bug4741926.java JBR-7530,JBR-9321 linux-all,linux-6.14.9-arch1-1
javax/swing/JFormattedTextField/TestSelectedTextBackgroundColor.java JBR-8790 linux-all
javax/swing/JInternalFrame/bug5009724.java JBR-7087 linux-all
javax/swing/JMenu/JMenuSelectedColorTest.java JBR-8551 linux-all
javax/swing/JPasswordField/TestSelectedTextBackgroundColor.java JBR-9277 linux-6.14.9-arch1-1
javax/swing/JPopupMenu/7156657/bug7156657.java JBR-8210 linux-all
javax/swing/JSlider/TestJSliderRendering.java JBR-8551 linux-all
javax/swing/JSpinner/TestSelectedTextBackgroundColor.java JBR-9277 linux-6.14.9-arch1-1
javax/swing/JTabbedPane/6495408/bug6495408.java JBR-8267 linux-aarch64
javax/swing/JToolTip/TestTooltipBackgroundColor.java JBR-8551 linux-all
javax/swing/LookAndFeel/8145547/DemandGTK3.sh JBR-8274 linux-all
javax/swing/text/html/CSS/bug8234913.java JBR-8306 linux-all
javax/swing/text/ParagraphView/6364882/bug6364882.java JBR-8324 linux-all
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-8304 linux-all
jb/java/awt/wayland/VulkanMaskFillTest.java JBR-8446 linux-6.8.0-1017-raspi
jb/javax/swing/wayland/WLPopupMoves.java JBR-8296 linux-all

View File

@@ -1,4 +1,5 @@
javax/swing/JFileChooser/6520101/bug6520101.java JBR-7140 linux-all
javax/swing/JMenu/bug4342646.java JBR-8727 linux-all
javax/swing/JTable/JTableRightOrientationTest.java JBR-8102 linux-all
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-8357 linux-all
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-8357 linux-all
javax/swing/text/ParagraphView/6364882/bug6364882.java JBR-8324 linux-all

View File

@@ -0,0 +1,601 @@
/*
* Copyright (c) 2025, 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.
*
* 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.
*/
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import static java.lang.System.out;
/**
* @test
* @bug 8341381
* @summary fix cubic offsetting issue (numerical accuracy)
* @run main/othervm/timeout=20 Bug8341381
* @modules java.desktop/sun.java2d.marlin
*/
public final class Bug8341381 {
static final boolean SHOW_GUI = false;
static final boolean CHECK_PIXELS = true;
static final boolean TRACE_ALL = false;
static final boolean TRACE_CHECK_PIXELS = false;
static final boolean SAVE_IMAGE = false;
static final boolean INTENSIVE = false;
static final double DPI = 96;
static final float STROKE_WIDTH = 15f;
// delay is 1 frame at 60hz
static final int DELAY = 16;
// off-screen test step (1.0 by default)
static final double STEP = (INTENSIVE) ? 1.0 / 117 : 1.0;
// stats:
static int N_TEST = 0;
static int N_FAIL = 0;
static final AtomicBoolean isMarlin = new AtomicBoolean();
static final CountDownLatch latch = new CountDownLatch(1);
public static void main(final String[] args) {
Locale.setDefault(Locale.US);
// FIRST: Get Marlin runtime state from its log:
// initialize j.u.l Logger:
final Logger log = Logger.getLogger("sun.java2d.marlin");
log.addHandler(new Handler() {
@Override
public void publish(LogRecord record) {
final String msg = record.getMessage();
if (msg != null) {
// last space to avoid matching other settings:
if (msg.startsWith("sun.java2d.renderer ")) {
isMarlin.set(msg.contains("DMarlinRenderingEngine"));
}
}
final Throwable th = record.getThrown();
// detect any Throwable:
if (th != null) {
out.println("Test failed:\n" + record.getMessage());
th.printStackTrace(out);
throw new RuntimeException("Test failed: ", th);
}
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
}
});
out.println("Bug8341381: start");
final long startTime = System.currentTimeMillis();
// enable Marlin logging & internal checks:
System.setProperty("sun.java2d.renderer.log", "true");
System.setProperty("sun.java2d.renderer.useLogger", "true");
try {
startTest();
out.println("WAITING ...");
latch.await(15, TimeUnit.SECONDS); // 2s typically
if (isMarlin.get()) {
out.println("Marlin renderer used at runtime.");
} else {
throw new RuntimeException("Marlin renderer NOT used at runtime !");
}
// show test report:
out.println("TESTS: " + N_TEST + " FAILS: " + N_FAIL);
if (N_FAIL > 0) {
throw new RuntimeException("Bug8341381: " + N_FAIL + " / " + N_TEST + " test(s) failed !");
}
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
} catch (InvocationTargetException ite) {
throw new RuntimeException(ite);
} finally {
final double elapsed = (System.currentTimeMillis() - startTime) / 1000.0;
out.println("Bug8341381: end (" + elapsed + " s)");
}
}
private static void startTest() throws InterruptedException, InvocationTargetException {
if (SHOW_GUI) {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
final JFrame viewer = new JFrame();
viewer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
viewer.setContentPane(new CanvasPanel(viewer));
viewer.pack();
viewer.setVisible(true);
}
});
return;
} else {
out.println("STEP: " + STEP);
new Thread(new Runnable() {
@Override
public void run() {
final Context ctx = new Context();
final Dimension initialDim = ctx.bugDisplay.getSize(DPI);
double w = initialDim.width;
double h = initialDim.height;
do {
ctx.shouldScale(w, h);
ctx.paintImage();
// resize component:
w -= STEP;
h -= STEP;
} while (ctx.iterate());
}
}).start();
}
}
static final class Context {
final BugDisplay bugDisplay = new BugDisplay();
double width = 0.0, height = 0.0;
BufferedImage bimg = null;
boolean shouldScale(final double w, final double h) {
if ((w != width) || (h != height) || !bugDisplay.isScaled) {
width = w;
height = h;
bugDisplay.scale(width, height);
N_TEST++;
return true;
}
return false;
}
void paintImage() {
final int w = bugDisplay.canvasWidth;
final int h = bugDisplay.canvasHeight;
if ((bimg == null) || (w > bimg.getWidth()) || (h > bimg.getHeight())) {
bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
}
final Graphics gi = bimg.getGraphics();
try {
bugDisplay.paint(gi);
} finally {
gi.dispose();
}
if (!bugDisplay.checkImage(bimg)) {
N_FAIL++;
}
}
boolean iterate() {
if ((bugDisplay.canvasWidth > 10) || (bugDisplay.canvasHeight > 10)) {
// continue:
return true;
}
out.println("Stop");
latch.countDown();
return false;
}
}
static final class CanvasPanel extends JPanel {
private static final long serialVersionUID = 1L;
private final Context ctx = new Context();
private boolean resized = false;
private Timer timer = null;
public CanvasPanel(final JFrame frame) {
timer = new Timer(DELAY, e -> {
if (resized) {
resized = false;
if (ctx.iterate()) {
// resize component:
setSize((int) Math.round(ctx.width - 1), (int) Math.round(ctx.height - 1));
} else {
timer.stop();
if (frame != null) {
frame.setVisible(false);
}
}
}
});
timer.setCoalesce(true);
timer.setRepeats(true);
timer.start();
}
@Override
public void paint(final Graphics g) {
final Dimension dim = getSize();
if (ctx.shouldScale(dim.width, dim.height)) {
this.resized = true;
}
super.paint(g);
// paint on buffered image:
if (CHECK_PIXELS) {
final int w = ctx.bugDisplay.canvasWidth;
final int h = ctx.bugDisplay.canvasHeight;
if (this.resized) {
ctx.paintImage();
}
g.drawImage(ctx.bimg.getSubimage(0, 0, w, h), 0, 0, null);
} else {
ctx.bugDisplay.paint(g);
}
}
@Override
public Dimension getPreferredSize() {
return ctx.bugDisplay.getSize(DPI);
}
}
static final class BugDisplay {
boolean isScaled = false;
int canvasWidth;
int canvasHeight;
private final static java.util.List<CubicCurve2D> curves1 = Arrays.asList(
new CubicCurve2D.Double(2191.0, 7621.0, 2191.0, 7619.0, 2191.0, 7618.0, 2191.0, 7617.0),
new CubicCurve2D.Double(2191.0, 7617.0, 2191.0, 7617.0, 2191.0, 7616.0, 2191.0, 7615.0),
new CubicCurve2D.Double(2198.0, 7602.0, 2200.0, 7599.0, 2203.0, 7595.0, 2205.0, 7590.0),
new CubicCurve2D.Double(2205.0, 7590.0, 2212.0, 7580.0, 2220.0, 7571.0, 2228.0, 7563.0),
new CubicCurve2D.Double(2228.0, 7563.0, 2233.0, 7557.0, 2239.0, 7551.0, 2245.0, 7546.0),
new CubicCurve2D.Double(2245.0, 7546.0, 2252.0, 7540.0, 2260.0, 7534.0, 2267.0, 7528.0),
new CubicCurve2D.Double(2267.0, 7528.0, 2271.0, 7526.0, 2275.0, 7524.0, 2279.0, 7521.0),
new CubicCurve2D.Double(2279.0, 7521.0, 2279.0, 7520.0, 2280.0, 7520.0, 2281.0, 7519.0)
);
private final static java.util.List<CubicCurve2D> curves2 = Arrays.asList(
new CubicCurve2D.Double(2281.0, 7519.0, 2282.0, 7518.0, 2282.0, 7517.0, 2283.0, 7516.0),
new CubicCurve2D.Double(2283.0, 7516.0, 2284.0, 7515.0, 2284.0, 7515.0, 2285.0, 7514.0),
new CubicCurve2D.Double(2291.0, 7496.0, 2292.0, 7495.0, 2292.0, 7494.0, 2291.0, 7493.0),
new CubicCurve2D.Double(2291.0, 7493.0, 2290.0, 7492.0, 2290.0, 7492.0, 2289.0, 7492.0),
new CubicCurve2D.Double(2289.0, 7492.0, 2288.0, 7491.0, 2286.0, 7492.0, 2285.0, 7492.0),
new CubicCurve2D.Double(2262.0, 7496.0, 2260.0, 7497.0, 2259.0, 7497.0, 2257.0, 7498.0),
new CubicCurve2D.Double(2257.0, 7498.0, 2254.0, 7498.0, 2251.0, 7499.0, 2248.0, 7501.0),
new CubicCurve2D.Double(2248.0, 7501.0, 2247.0, 7501.0, 2245.0, 7502.0, 2244.0, 7503.0),
new CubicCurve2D.Double(2207.0, 7523.0, 2203.0, 7525.0, 2199.0, 7528.0, 2195.0, 7530.0),
new CubicCurve2D.Double(2195.0, 7530.0, 2191.0, 7534.0, 2186.0, 7538.0, 2182.0, 7541.0)
);
private final static java.util.List<CubicCurve2D> curves3 = Arrays.asList(
new CubicCurve2D.Double(2182.0, 7541.0, 2178.0, 7544.0, 2174.0, 7547.0, 2170.0, 7551.0),
new CubicCurve2D.Double(2170.0, 7551.0, 2164.0, 7556.0, 2158.0, 7563.0, 2152.0, 7569.0),
new CubicCurve2D.Double(2152.0, 7569.0, 2148.0, 7573.0, 2145.0, 7577.0, 2141.0, 7582.0),
new CubicCurve2D.Double(2141.0, 7582.0, 2138.0, 7588.0, 2134.0, 7595.0, 2132.0, 7602.0),
new CubicCurve2D.Double(2132.0, 7602.0, 2132.0, 7605.0, 2131.0, 7608.0, 2131.0, 7617.0),
new CubicCurve2D.Double(2131.0, 7617.0, 2131.0, 7620.0, 2131.0, 7622.0, 2131.0, 7624.0),
new CubicCurve2D.Double(2131.0, 7624.0, 2131.0, 7630.0, 2132.0, 7636.0, 2135.0, 7641.0),
new CubicCurve2D.Double(2135.0, 7641.0, 2136.0, 7644.0, 2137.0, 7647.0, 2139.0, 7650.0),
new CubicCurve2D.Double(2139.0, 7650.0, 2143.0, 7658.0, 2149.0, 7664.0, 2155.0, 7670.0),
new CubicCurve2D.Double(2155.0, 7670.0, 2160.0, 7676.0, 2165.0, 7681.0, 2171.0, 7686.0)
);
private final static java.util.List<CubicCurve2D> curves4 = Arrays.asList(
new CubicCurve2D.Double(2171.0, 7686.0, 2174.0, 7689.0, 2177.0, 7692.0, 2180.0, 7694.0),
new CubicCurve2D.Double(2180.0, 7694.0, 2185.0, 7698.0, 2191.0, 7702.0, 2196.0, 7706.0),
new CubicCurve2D.Double(2196.0, 7706.0, 2199.0, 7708.0, 2203.0, 7711.0, 2207.0, 7713.0),
new CubicCurve2D.Double(2244.0, 7734.0, 2245.0, 7734.0, 2247.0, 7735.0, 2248.0, 7736.0),
new CubicCurve2D.Double(2248.0, 7736.0, 2251.0, 7738.0, 2254.0, 7739.0, 2257.0, 7739.0),
new CubicCurve2D.Double(2257.0, 7739.0, 2259.0, 7739.0, 2260.0, 7739.0, 2262.0, 7740.0),
new CubicCurve2D.Double(2285.0, 7745.0, 2286.0, 7745.0, 2288.0, 7745.0, 2289.0, 7745.0),
new CubicCurve2D.Double(2289.0, 7745.0, 2290.0, 7745.0, 2290.0, 7744.0, 2291.0, 7743.0),
new CubicCurve2D.Double(2291.0, 7743.0, 2292.0, 7742.0, 2292.0, 7741.0, 2291.0, 7740.0),
new CubicCurve2D.Double(2285.0, 7722.0, 2284.0, 7721.0, 2284.0, 7721.0, 2283.0, 7720.0),
new CubicCurve2D.Double(2283.0, 7720.0, 2282.0, 7719.0, 2282.0, 7719.0, 2281.0, 7718.0),
new CubicCurve2D.Double(2281.0, 7718.0, 2280.0, 7717.0, 2279.0, 7716.0, 2279.0, 7716.0),
new CubicCurve2D.Double(2279.0, 7716.0, 2275.0, 7712.0, 2271.0, 7710.0, 2267.0, 7708.0),
new CubicCurve2D.Double(2267.0, 7708.0, 2260.0, 7702.0, 2252.0, 7697.0, 2245.0, 7691.0),
new CubicCurve2D.Double(2245.0, 7691.0, 2239.0, 7685.0, 2233.0, 7679.0, 2228.0, 7673.0),
new CubicCurve2D.Double(2228.0, 7673.0, 2220.0, 7665.0, 2212.0, 7656.0, 2205.0, 7646.0),
new CubicCurve2D.Double(2205.0, 7646.0, 2203.0, 7641.0, 2200.0, 7637.0, 2198.0, 7634.0)
);
private final static Point2D.Double[] extent = {new Point2D.Double(0.0, 0.0), new Point2D.Double(7777.0, 10005.0)};
private final static Stroke STROKE = new BasicStroke(STROKE_WIDTH);
private final static Stroke STROKE_DASHED = new BasicStroke(STROKE_WIDTH, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL,
10.0f, new float[] {100f, 0f}, 0.0f);
// members:
private final java.util.List<CubicCurve2D> allCurves = new ArrayList<>();
private final Rectangle2D bboxAllCurves = new Rectangle2D.Double();
BugDisplay() {
allCurves.addAll(curves1);
allCurves.addAll(curves2);
allCurves.addAll(curves3);
allCurves.addAll(curves4);
// initialize bounding box:
double x1 = Double.POSITIVE_INFINITY;
double y1 = Double.POSITIVE_INFINITY;
double x2 = Double.NEGATIVE_INFINITY;
double y2 = Double.NEGATIVE_INFINITY;
for (final CubicCurve2D c : allCurves) {
final Rectangle2D r = c.getBounds2D();
if (r.getMinX() < x1) {
x1 = r.getMinX();
}
if (r.getMinY() < y1) {
y1 = r.getMinY();
}
if (r.getMaxX() > x2) {
x2 = r.getMaxX();
}
if (r.getMaxY() > y2) {
y2 = r.getMaxY();
}
}
// add margin of 10%:
final double m = 1.1 * STROKE_WIDTH;
bboxAllCurves.setFrameFromDiagonal(x1 - m, y1 - m, x2 + m, y2 + m);
}
public void paint(final Graphics g) {
final Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
// ------ scale
final AffineTransform tx_orig = g2d.getTransform();
final AffineTransform tx = getDrawTransform();
g2d.transform(tx);
// draw bbox:
if (!CHECK_PIXELS) {
g2d.setColor(Color.RED);
g2d.setStroke(STROKE);
g2d.draw(bboxAllCurves);
}
// draw curves:
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
g2d.setColor(Color.BLACK);
// dasher + stroker:
g2d.setStroke(STROKE_DASHED);
this.allCurves.forEach(g2d::draw);
// reset
g2d.setTransform(tx_orig);
}
private AffineTransform getDrawTransform() {
// ------ scale
double minX = extent[0].x, maxX = extent[1].x;
double minY = extent[0].y, maxY = extent[1].y;
// we're scaling and respecting the proportions, check which scale to use
double sx = this.canvasWidth / Math.abs(maxX - minX);
double sy = this.canvasHeight / Math.abs(maxY - minY);
double s = Math.min(sx, sy);
double m00, m11, m02, m12;
if (minX < maxX) {
m00 = s;
m02 = -s * minX;
} else {
// inverted X axis
m00 = -s;
m02 = this.canvasWidth + s * maxX;
}
if (minY < maxY) {
m11 = s;
m12 = -s * minY;
} else {
// inverted Y axis
m11 = -s;
m12 = this.canvasHeight + s * maxY;
}
// scale to the available view port
AffineTransform scaleTransform = new AffineTransform(m00, 0, 0, m11, m02, m12);
// invert the Y axis since (0, 0) is at top left for AWT
AffineTransform invertY = new AffineTransform(1, 0, 0, -1, 0, this.canvasHeight);
invertY.concatenate(scaleTransform);
return invertY;
}
public Dimension getSize(double dpi) {
double metricScalingFactor = 0.02539999969303608;
// 1 inch = 25,4 millimeter
final double factor = dpi * metricScalingFactor / 25.4;
int width = (int) Math.ceil(Math.abs(extent[1].x - extent[0].x) * factor);
int height = (int) Math.ceil(Math.abs(extent[1].y - extent[0].y) * factor);
return new Dimension(width, height);
}
public void scale(double w, double h) {
double extentWidth = Math.abs(extent[1].x - extent[0].x);
double extentHeight = Math.abs(extent[1].y - extent[0].y);
double fx = w / extentWidth;
if (fx * extentHeight > h) {
fx = h / extentHeight;
}
this.canvasWidth = (int) Math.round(fx * extentWidth);
this.canvasHeight = (int) Math.round(fx * extentHeight);
// out.println("canvas scaled (" + canvasWidth + " x " + canvasHeight + ")");
this.isScaled = true;
}
protected boolean checkImage(BufferedImage image) {
final AffineTransform tx = getDrawTransform();
final Point2D pMin = new Point2D.Double(bboxAllCurves.getMinX(), bboxAllCurves.getMinY());
final Point2D pMax = new Point2D.Double(bboxAllCurves.getMaxX(), bboxAllCurves.getMaxY());
final Point2D tMin = tx.transform(pMin, null);
final Point2D tMax = tx.transform(pMax, null);
int xMin = (int) tMin.getX();
int xMax = (int) tMax.getX();
if (xMin > xMax) {
int t = xMin;
xMin = xMax;
xMax = t;
}
int yMin = (int) tMin.getY();
int yMax = (int) tMax.getY();
if (yMin > yMax) {
int t = yMin;
yMin = yMax;
yMax = t;
}
// add pixel margin (AA):
xMin -= 3;
xMax += 4;
yMin -= 3;
yMax += 4;
if (xMin < 0 || xMax > image.getWidth()
|| yMin < 0 || yMax > image.getHeight()) {
return true;
}
// out.println("Checking rectangle: " + tMin + " to " + tMax);
// out.println("X min: " + xMin + " - max: " + xMax);
// out.println("Y min: " + yMin + " - max: " + yMax);
final Raster raster = image.getData();
final int expected = Color.WHITE.getRGB();
int nBadPixels = 0;
// horizontal lines:
for (int x = xMin; x <= xMax; x++) {
if (!checkPixel(raster, x, yMin, expected)) {
nBadPixels++;
}
if (!checkPixel(raster, x, yMax, expected)) {
nBadPixels++;
}
}
// vertical lines:
for (int y = yMin; y <= yMax; y++) {
if (!checkPixel(raster, xMin, y, expected)) {
nBadPixels++;
}
if (!checkPixel(raster, xMax, y, expected)) {
nBadPixels++;
}
}
if (nBadPixels != 0) {
out.println("(" + canvasWidth + " x " + canvasHeight + ") BAD pixels = " + nBadPixels);
if (SAVE_IMAGE) {
try {
final File file = new File("Bug8341381-" + canvasWidth + "-" + canvasHeight + ".png");
out.println("Writing file: " + file.getAbsolutePath());
ImageIO.write(image.getSubimage(0, 0, canvasWidth, canvasHeight), "PNG", file);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return false;
} else if (TRACE_ALL) {
out.println("(" + canvasWidth + " x " + canvasHeight + ") OK");
}
return true;
}
private final static int[] TMP_RGB = new int[1];
private static boolean checkPixel(final Raster raster,
final int x, final int y,
final int expected) {
final int[] rgb = (int[]) raster.getDataElements(x, y, TMP_RGB);
if (rgb[0] != expected) {
if (TRACE_CHECK_PIXELS) {
out.println("bad pixel at (" + x + ", " + y + ") = " + rgb[0]
+ " expected = " + expected);
}
return false;
}
return true;
}
}
}