# HG changeset patch # User ssadetsky # Date 1476688478 -10800 # Node ID 7b9c71553d63f737edfd2eadf19c031a5e5b3adc # Parent 8b032394d44eae94147ef61650e3437c308bd45f 8167486: Device.getDisplayMode() doesn't report refresh rate on Linux in case of dual screen Reviewed-by: serb diff -r 8b032394d44e -r 7b9c71553d63 jdk/src/java.desktop/share/classes/java/awt/DisplayMode.java --- 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]"); + } } diff -r 8b032394d44e -r 7b9c71553d63 jdk/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h --- 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; diff -r 8b032394d44e -r 7b9c71553d63 jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c --- 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; diff -r 8b032394d44e -r 7b9c71553d63 jdk/test/java/awt/FullScreen/CurrentDisplayModeTest/CurrentDisplayModeTest.java --- /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 set = new HashSet<>( + Arrays.asList(screenDevice.getDisplayModes())); + if (!set.contains(currentMode)) { + throw new RuntimeException("Mode " + currentMode + + " is not found in the modes list " + set); + } + } + } +}