8167486: Device.getDisplayMode() doesn't report refresh rate on Linux in case of dual screen

Reviewed-by: serb
This commit is contained in:
Semyon Sadetsky 2016-10-17 10:14:38 +03:00
parent b3d5aa622e
commit 3419791e2d
4 changed files with 136 additions and 3 deletions

View File

@ -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 @@ public final class DisplayMode {
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object dm) {
if (dm instanceof DisplayMode) {
return equals((DisplayMode)dm);
@ -153,9 +154,20 @@ public final class DisplayMode {
/**
* {@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]");
}
}

View File

@ -118,6 +118,19 @@ typedef struct {
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 @@ XRROutputInfo * XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources,
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;

View File

@ -1667,6 +1667,11 @@ typedef XRROutputInfo * (*XRRGetOutputInfoType)(Display *dpy,
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 XRRGetScreenResourcesType awt_XRRGetScreenResources;
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 @@ X11GD_InitXrandrFuncs(JNIEnv *env)
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 @@ Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode
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 @@ Java_sun_awt_X11GraphicsDevice_enumDisplayModes
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;

View File

@ -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);
}
}
}
}