8167486: Device.getDisplayMode() doesn't report refresh rate on Linux in case of dual screen
Reviewed-by: serb
--- a/jdk/src/java.desktop/share/classes/java/awt/DisplayMode.java Mon Oct 17 09:58:37 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/java/awt/DisplayMode.java Mon Oct 17 10:14:38 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -142,6 +142,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean equals(Object dm) {
if (dm instanceof DisplayMode) {
return equals((DisplayMode)dm);
@@ -153,9 +154,20 @@
/**
* {@inheritDoc}
*/
+ @Override
public int hashCode() {
return getWidth() + getHeight() + getBitDepth() * 7
+ getRefreshRate() * 13;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return getWidth() + "x" + getHeight() + "x" +
+ (getBitDepth() > 0 ? getBitDepth() + "bpp": "[Multi depth]")
+ + "@" + (getRefreshRate() > 0 ? getRefreshRate() + "Hz" :
+ "[Unknown refresh rate]");
+ }
}
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h Mon Oct 17 09:58:37 2016 +0300
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h Mon Oct 17 10:14:38 2016 +0300
@@ -118,6 +118,19 @@
RRMode *modes;
} XRROutputInfo;
+typedef struct {
+ Time timestamp;
+ int x, y;
+ unsigned int width, height;
+ RRMode mode;
+ Rotation rotation;
+ int noutput;
+ RROutput *outputs;
+ Rotation rotations;
+ int npossible;
+ RROutput *possible;
+} XRRCrtcInfo;
+
XRRScreenResources *XRRGetScreenResources (Display *dpy, Window window);
void XRRFreeScreenResources (XRRScreenResources *resources);
@@ -126,6 +139,11 @@
RROutput output);
void XRRFreeOutputInfo (XRROutputInfo *outputInfo);
+XRRCrtcInfo *XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources,
+ RRCrtc crtc);
+void XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo);
+
+
/* internal representation is private to the library */
typedef struct _XRRScreenConfiguration XRRScreenConfiguration;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Mon Oct 17 09:58:37 2016 +0300
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Mon Oct 17 10:14:38 2016 +0300
@@ -1667,6 +1667,11 @@
typedef void (*XRRFreeOutputInfoType)(XRROutputInfo *outputInfo);
+typedef XRRCrtcInfo* (*XRRGetCrtcInfoType)(Display *dpy,
+ XRRScreenResources *resources, RRCrtc crtc);
+
+typedef void (*XRRFreeCrtcInfoType)(XRRCrtcInfo *crtcInfo);
+
static XRRQueryVersionType awt_XRRQueryVersion;
static XRRGetScreenInfoType awt_XRRGetScreenInfo;
static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo;
@@ -1680,6 +1685,8 @@
static XRRFreeScreenResourcesType awt_XRRFreeScreenResources;
static XRRGetOutputInfoType awt_XRRGetOutputInfo;
static XRRFreeOutputInfoType awt_XRRFreeOutputInfo;
+static XRRGetCrtcInfoType awt_XRRGetCrtcInfo;
+static XRRFreeCrtcInfoType awt_XRRFreeCrtcInfo;
#define LOAD_XRANDR_FUNC(f) \
do { \
@@ -1755,6 +1762,8 @@
LOAD_XRANDR_FUNC(XRRFreeScreenResources);
LOAD_XRANDR_FUNC(XRRGetOutputInfo);
LOAD_XRANDR_FUNC(XRRFreeOutputInfo);
+ LOAD_XRANDR_FUNC(XRRGetCrtcInfo);
+ LOAD_XRANDR_FUNC(XRRFreeCrtcInfo);
return JNI_TRUE;
}
@@ -1895,7 +1904,49 @@
AWT_LOCK();
- if (screen < ScreenCount(awt_display)) {
+ if (usingXinerama && XScreenCount(awt_display) > 0) {
+ XRRScreenResources *res = awt_XRRGetScreenResources(awt_display,
+ RootWindow(awt_display, 0));
+ if (res) {
+ if (res->noutput > screen) {
+ XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display,
+ res, res->outputs[screen]);
+ if (output_info) {
+ if (output_info->crtc) {
+ XRRCrtcInfo *crtc_info =
+ awt_XRRGetCrtcInfo (awt_display, res,
+ output_info->crtc);
+ if (crtc_info) {
+ if (crtc_info->mode) {
+ int i;
+ for (i = 0; i < res->nmode; i++) {
+ XRRModeInfo *mode = &res->modes[i];
+ if (mode->id == crtc_info->mode) {
+ float rate = 0;
+ if (mode->hTotal && mode->vTotal) {
+ rate = ((float)mode->dotClock /
+ ((float)mode->hTotal *
+ (float)mode->vTotal));
+ }
+ displayMode = X11GD_CreateDisplayMode(
+ env,
+ mode->width,
+ mode->height,
+ BIT_DEPTH_MULTI,
+ (int)(rate +.2));
+ break;
+ }
+ }
+ }
+ awt_XRRFreeCrtcInfo(crtc_info);
+ }
+ }
+ awt_XRRFreeOutputInfo(output_info);
+ }
+ }
+ awt_XRRFreeScreenResources(res);
+ }
+ } else {
config = awt_XRRGetScreenInfo(awt_display,
RootWindow(awt_display, screen));
@@ -1954,7 +2005,7 @@
res, res->outputs[screen]);
if (output_info) {
int i;
- for (i = 0; i < res->nmode; i++) {
+ for (i = 0; i < output_info->nmode; i++) {
RRMode m = output_info->modes[i];
int j;
XRRModeInfo *mode;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/FullScreen/CurrentDisplayModeTest/CurrentDisplayModeTest.java Mon Oct 17 10:14:38 2016 +0300
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+ * @test
+ * @bug 8022810
+ * @summary Device.getDisplayMode() doesn't report refresh rate on Linux in case
+ * of dual screen
+ * @run main CurrentDisplayModeTest
+ */
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CurrentDisplayModeTest {
+ public static void main(String[] args) {
+ GraphicsDevice[] screenDevices = GraphicsEnvironment.
+ getLocalGraphicsEnvironment().getScreenDevices();
+ for (GraphicsDevice screenDevice : screenDevices) {
+ DisplayMode currentMode = screenDevice.getDisplayMode();
+ System.out.println("current mode " + currentMode);
+ Set<DisplayMode> set = new HashSet<>(
+ Arrays.asList(screenDevice.getDisplayModes()));
+ if (!set.contains(currentMode)) {
+ throw new RuntimeException("Mode " + currentMode +
+ " is not found in the modes list " + set);
+ }
+ }
+ }
+}