--- old/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c 2016-05-13 09:34:03.062628771 +0300 +++ new/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c 2016-05-13 09:34:02.930628775 +0300 @@ -1657,6 +1657,16 @@ (*XRRConfigRotationsType)(XRRScreenConfiguration *config, Rotation *current_rotation); +typedef XRRScreenResources* (*XRRGetScreenResourcesType)(Display *dpy, + Window window); + +typedef void (*XRRFreeScreenResourcesType)(XRRScreenResources *resources); + +typedef XRROutputInfo * (*XRRGetOutputInfoType)(Display *dpy, + XRRScreenResources *resources, RROutput output); + +typedef void (*XRRFreeOutputInfoType)(XRROutputInfo *outputInfo); + static XRRQueryVersionType awt_XRRQueryVersion; static XRRGetScreenInfoType awt_XRRGetScreenInfo; static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo; @@ -1666,6 +1676,10 @@ static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration; static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate; static XRRConfigRotationsType awt_XRRConfigRotations; +static XRRGetScreenResourcesType awt_XRRGetScreenResources; +static XRRFreeScreenResourcesType awt_XRRFreeScreenResources; +static XRRGetOutputInfoType awt_XRRGetOutputInfo; +static XRRFreeOutputInfoType awt_XRRFreeOutputInfo; #define LOAD_XRANDR_FUNC(f) \ do { \ @@ -1737,6 +1751,10 @@ LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration); LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate); LOAD_XRANDR_FUNC(XRRConfigRotations); + LOAD_XRANDR_FUNC(XRRGetScreenResources); + LOAD_XRANDR_FUNC(XRRFreeScreenResources); + LOAD_XRANDR_FUNC(XRRGetOutputInfo); + LOAD_XRANDR_FUNC(XRRFreeOutputInfo); return JNI_TRUE; } @@ -1924,36 +1942,73 @@ jint screen, jobject arrayList) { #ifndef HEADLESS - XRRScreenConfiguration *config; AWT_LOCK(); - config = awt_XRRGetScreenInfo(awt_display, - RootWindow(awt_display, screen)); - if (config != NULL) { - int nsizes, i, j; - XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes); - - if (sizes != NULL) { - for (i = 0; i < nsizes; i++) { - int nrates; - XRRScreenSize size = sizes[i]; - short *rates = awt_XRRConfigRates(config, i, &nrates); - - for (j = 0; j < nrates; j++) { - X11GD_AddDisplayMode(env, arrayList, - size.width, - size.height, - BIT_DEPTH_MULTI, - rates[j]); - if ((*env)->ExceptionCheck(env)) { - break; + 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) { + int i; + for (i = 0; i < res->nmode; i++) { + RRMode m = output_info->modes[i]; + int j; + XRRModeInfo *mode; + for (j = 0; j < res->nmode; j++) { + mode = &res->modes[j]; + if (mode->id == m) { + float rate = 0; + if (mode->hTotal && mode->vTotal) { + rate = ((float)mode->dotClock / + ((float)mode->hTotal * + (float)mode->vTotal)); + } + X11GD_AddDisplayMode(env, arrayList, + mode->width, mode->height, + BIT_DEPTH_MULTI, (int)(rate +.2)); + break; + } + } } + awt_XRRFreeOutputInfo(output_info); } } + awt_XRRFreeScreenResources(res); } + } else { + XRRScreenConfiguration *config; - awt_XRRFreeScreenConfigInfo(config); + config = awt_XRRGetScreenInfo(awt_display, + RootWindow(awt_display, screen)); + if (config != NULL) { + int nsizes, i, j; + XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes); + + if (sizes != NULL) { + for (i = 0; i < nsizes; i++) { + int nrates; + XRRScreenSize size = sizes[i]; + short *rates = awt_XRRConfigRates(config, i, &nrates); + + for (j = 0; j < nrates; j++) { + X11GD_AddDisplayMode(env, arrayList, + size.width, + size.height, + BIT_DEPTH_MULTI, + rates[j]); + if ((*env)->ExceptionCheck(env)) { + break; + } + } + } + } + + awt_XRRFreeScreenConfigInfo(config); + } } AWT_FLUSH_UNLOCK(); --- old/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h 2016-05-13 09:34:03.446628757 +0300 +++ new/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h 2016-05-13 09:34:03.302628762 +0300 @@ -5,8 +5,8 @@ /* * $XFree86: xc/lib/Xrandr/Xrandr.h,v 1.9 2002/09/29 23:39:44 keithp Exp $ * - * Copyright © 2000 Compaq Computer Corporation, Inc. - * Copyright © 2002 Hewlett-Packard Company, Inc. + * Copyright � 2000 Compaq Computer Corporation, Inc. + * Copyright � 2002 Hewlett-Packard Company, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -66,6 +66,65 @@ int mheight; } XRRScreenChangeNotifyEvent; +typedef XID RROutput; +typedef XID RRCrtc; +typedef XID RRMode; + +typedef unsigned long XRRModeFlags; + +typedef struct { + RRMode id; + unsigned int width; + unsigned int height; + unsigned long dotClock; + unsigned int hSyncStart; + unsigned int hSyncEnd; + unsigned int hTotal; + unsigned int hSkew; + unsigned int vSyncStart; + unsigned int vSyncEnd; + unsigned int vTotal; + char *name; + unsigned int nameLength; + XRRModeFlags modeFlags; +} XRRModeInfo; + +typedef struct { + Time timestamp; + Time configTimestamp; + int ncrtc; + RRCrtc *crtcs; + int noutput; + RROutput *outputs; + int nmode; + XRRModeInfo *modes; +} XRRScreenResources; + +typedef struct { + Time timestamp; + RRCrtc crtc; + char *name; + int nameLen; + unsigned long mm_width; + unsigned long mm_height; + Connection connection; + SubpixelOrder subpixel_order; + int ncrtc; + RRCrtc *crtcs; + int nclone; + RROutput *clones; + int nmode; + int npreferred; + RRMode *modes; +} XRROutputInfo; + +XRRScreenResources *XRRGetScreenResources (Display *dpy, Window window); + +void XRRFreeScreenResources (XRRScreenResources *resources); + +XRROutputInfo * XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, + RROutput output); +void XRRFreeOutputInfo (XRROutputInfo *outputInfo); /* internal representation is private to the library */ typedef struct _XRRScreenConfiguration XRRScreenConfiguration; --- old/src/java.desktop/unix/native/libawt_xawt/awt/randr.h 2016-05-13 09:34:03.802628744 +0300 +++ new/src/java.desktop/unix/native/libawt_xawt/awt/randr.h 2016-05-13 09:34:03.666628749 +0300 @@ -5,8 +5,8 @@ /* * $XFree86: xc/include/extensions/randr.h,v 1.4 2001/11/24 07:24:58 keithp Exp $ * - * Copyright © 2000, Compaq Computer Corporation, - * Copyright © 2002, Hewlett Packard, Inc. + * Copyright � 2000, Compaq Computer Corporation, + * Copyright � 2002, Hewlett Packard, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -31,6 +31,7 @@ #ifndef _RANDR_H_ #define _RANDR_H_ +typedef unsigned short Connection; typedef unsigned short Rotation; typedef unsigned short SizeID; typedef unsigned short SubpixelOrder; --- /dev/null 2016-05-13 08:14:24.113033683 +0300 +++ new/test/java/awt/GraphicsDevice/DisplayModes/CompareToXrandrTest.java 2016-05-13 09:34:04.046628736 +0300 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, 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 Cannot list all the available display modes on Ubuntu linux in case + * of two screen devices + * @run main CompareToXrandrTest + */ + +import java.awt.GraphicsEnvironment; +import java.awt.GraphicsDevice; +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class CompareToXrandrTest { + + public static void main(String[] args) throws Exception { + if (!new File("/usr/bin/xrandr").exists()) { + System.out.println("No xrandr tool to compare"); + return; + } + + BufferedReader reader = new BufferedReader(new InputStreamReader( + Runtime.getRuntime().exec("/usr/bin/xrandr").getInputStream())); + reader.readLine(); + reader.readLine(); + Pattern pattern = Pattern.compile("^\\s*(\\d+x\\d+)"); + + for (GraphicsDevice d : GraphicsEnvironment + .getLocalGraphicsEnvironment().getScreenDevices()) { + + Set xrandrModes = reader.lines().map(pattern::matcher) + .takeWhile(Matcher::find).map(m -> m.group(1)) + .collect(Collectors.toSet()); + + Set javaModes = Arrays.stream(d.getDisplayModes()) + .map(m -> m.getWidth() + "x" + m.getHeight()) + .collect(Collectors.toSet()); + + if (!xrandrModes.equals(javaModes)) { + throw new RuntimeException("Failed"); + } else { + System.out.println("Device " + d + ": " + javaModes.size() + + " modes found."); + } + } + } +}