Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java
32287 views
/*1* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.awt;2627import java.awt.AWTError;28import java.awt.GraphicsDevice;29import java.awt.Point;30import java.awt.Rectangle;31import java.io.BufferedReader;32import java.io.File;33import java.io.FileReader;34import java.io.FileNotFoundException;35import java.io.InputStream;36import java.io.IOException;37import java.io.StreamTokenizer;38import java.net.InetAddress;39import java.net.NetworkInterface;40import java.net.SocketException;41import java.net.UnknownHostException;4243import java.util.*;4445import sun.awt.motif.MFontConfiguration;46import sun.font.FcFontConfiguration;47import sun.font.Font2D;48import sun.font.FontManager;49import sun.font.NativeFont;50import sun.java2d.SunGraphicsEnvironment;51import sun.java2d.SurfaceManagerFactory;52import sun.java2d.UnixSurfaceManagerFactory;53import sun.util.logging.PlatformLogger;54import sun.java2d.xr.XRSurfaceData;5556/**57* This is an implementation of a GraphicsEnvironment object for the58* default local GraphicsEnvironment used by the Java Runtime Environment59* for X11 environments.60*61* @see GraphicsDevice62* @see GraphicsConfiguration63*/64public class X11GraphicsEnvironment65extends SunGraphicsEnvironment66{67private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11GraphicsEnvironment");68private static final PlatformLogger screenLog = PlatformLogger.getLogger("sun.awt.screen.X11GraphicsEnvironment");6970private static Boolean xinerState;7172static {73java.security.AccessController.doPrivileged(74new java.security.PrivilegedAction() {75public Object run() {76System.loadLibrary("awt");7778/*79* Note: The MToolkit object depends on the static initializer80* of X11GraphicsEnvironment to initialize the connection to81* the X11 server.82*/83if (!isHeadless()) {84// first check the OGL system property85boolean glxRequested = false;86String prop = System.getProperty("sun.java2d.opengl");87if (prop != null) {88if (prop.equals("true") || prop.equals("t")) {89glxRequested = true;90} else if (prop.equals("True") || prop.equals("T")) {91glxRequested = true;92glxVerbose = true;93}94}9596// Now check for XRender system property97boolean xRenderRequested = true;98boolean xRenderIgnoreLinuxVersion = false;99String xProp = System.getProperty("sun.java2d.xrender");100if (xProp != null) {101if (xProp.equals("false") || xProp.equals("f")) {102xRenderRequested = false;103} else if (xProp.equals("True") || xProp.equals("T")) {104xRenderRequested = true;105xRenderVerbose = true;106}107108if(xProp.equalsIgnoreCase("t") || xProp.equalsIgnoreCase("true")) {109xRenderIgnoreLinuxVersion = true;110}111}112113// initialize the X11 display connection114initDisplay(glxRequested);115116// only attempt to initialize GLX if it was requested117if (glxRequested) {118glxAvailable = initGLX();119if (glxVerbose && !glxAvailable) {120System.out.println(121"Could not enable OpenGL " +122"pipeline (GLX 1.3 not available)");123}124}125126// only attempt to initialize Xrender if it was requested127if (xRenderRequested) {128xRenderAvailable = initXRender(xRenderVerbose, xRenderIgnoreLinuxVersion);129if (xRenderVerbose && !xRenderAvailable) {130System.out.println(131"Could not enable XRender pipeline");132}133}134135if (xRenderAvailable) {136XRSurfaceData.initXRSurfaceData();137}138}139140return null;141}142});143144// Install the correct surface manager factory.145SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());146147}148149150private static boolean glxAvailable;151private static boolean glxVerbose;152153private static native boolean initGLX();154155public static boolean isGLXAvailable() {156return glxAvailable;157}158159public static boolean isGLXVerbose() {160return glxVerbose;161}162163private static boolean xRenderVerbose;164private static boolean xRenderAvailable;165166private static native boolean initXRender(boolean verbose, boolean ignoreLinuxVersion);167public static boolean isXRenderAvailable() {168return xRenderAvailable;169}170171public static boolean isXRenderVerbose() {172return xRenderVerbose;173}174175/**176* Checks if Shared Memory extension can be used.177* Returns:178* -1 if server doesn't support MITShm179* 1 if server supports it and it can be used180* 0 otherwise181*/182private static native int checkShmExt();183184private static native String getDisplayString();185private Boolean isDisplayLocal;186187/**188* This should only be called from the static initializer, so no need for189* the synchronized keyword.190*/191private static native void initDisplay(boolean glxRequested);192193public X11GraphicsEnvironment() {194}195196protected native int getNumScreens();197198protected GraphicsDevice makeScreenDevice(int screennum) {199return new X11GraphicsDevice(screennum);200}201202protected native int getDefaultScreenNum();203/**204* Returns the default screen graphics device.205*/206public GraphicsDevice getDefaultScreenDevice() {207GraphicsDevice[] screens = getScreenDevices();208if (screens.length == 0) {209throw new AWTError("no screen devices");210}211int index = getDefaultScreenNum();212return screens[0 < index && index < screens.length ? index : 0];213}214215public boolean isDisplayLocal() {216if (isDisplayLocal == null) {217SunToolkit.awtLock();218try {219if (isDisplayLocal == null) {220isDisplayLocal = Boolean.valueOf(_isDisplayLocal());221}222} finally {223SunToolkit.awtUnlock();224}225}226return isDisplayLocal.booleanValue();227}228229private static boolean _isDisplayLocal() {230if (isHeadless()) {231return true;232}233234String isRemote = (String)java.security.AccessController.doPrivileged(235new sun.security.action.GetPropertyAction("sun.java2d.remote"));236if (isRemote != null) {237return isRemote.equals("false");238}239240int shm = checkShmExt();241if (shm != -1) {242return (shm == 1);243}244245// If XServer doesn't support ShMem extension,246// try the other way247248String display = getDisplayString();249int ind = display.indexOf(':');250final String hostName = display.substring(0, ind);251if (ind <= 0) {252// ':0' case253return true;254}255256Boolean result = (Boolean)java.security.AccessController.doPrivileged(257new java.security.PrivilegedAction() {258public Object run() {259InetAddress remAddr[] = null;260Enumeration locals = null;261Enumeration interfaces = null;262try {263interfaces = NetworkInterface.getNetworkInterfaces();264remAddr = InetAddress.getAllByName(hostName);265if (remAddr == null) {266return Boolean.FALSE;267}268} catch (UnknownHostException e) {269System.err.println("Unknown host: " + hostName);270return Boolean.FALSE;271} catch (SocketException e1) {272System.err.println(e1.getMessage());273return Boolean.FALSE;274}275276for (; interfaces.hasMoreElements();) {277locals = ((NetworkInterface)interfaces.nextElement()).getInetAddresses();278for (; locals.hasMoreElements();) {279for (int i = 0; i < remAddr.length; i++) {280if (locals.nextElement().equals(remAddr[i])) {281return Boolean.TRUE;282}283}284}285}286return Boolean.FALSE;287}});288return result.booleanValue();289}290291292293/**294* Returns face name for default font, or null if295* no face names are used for CompositeFontDescriptors296* for this platform.297*/298public String getDefaultFontFaceName() {299300return null;301}302303private static native boolean pRunningXinerama();304private static native Point getXineramaCenterPoint();305306/**307* Override for Xinerama case: call new Solaris API for getting the correct308* centering point from the windowing system.309*/310public Point getCenterPoint() {311if (runningXinerama()) {312Point p = getXineramaCenterPoint();313if (p != null) {314return p;315}316}317return super.getCenterPoint();318}319320/**321* Override for Xinerama case322*/323public Rectangle getMaximumWindowBounds() {324if (runningXinerama()) {325return getXineramaWindowBounds();326} else {327return super.getMaximumWindowBounds();328}329}330331public boolean runningXinerama() {332if (xinerState == null) {333// pRunningXinerama() simply returns a global boolean variable,334// so there is no need to synchronize here335xinerState = Boolean.valueOf(pRunningXinerama());336if (screenLog.isLoggable(PlatformLogger.Level.FINER)) {337screenLog.finer("Running Xinerama: " + xinerState);338}339}340return xinerState.booleanValue();341}342343/**344* Return the bounds for a centered Window on a system running in Xinerama345* mode.346*347* Calculations are based on the assumption of a perfectly rectangular348* display area (display edges line up with one another, and displays349* have consistent width and/or height).350*351* The bounds to return depend on the arrangement of displays and on where352* Windows are to be centered. There are two common situations:353*354* 1) The center point lies at the center of the combined area of all the355* displays. In this case, the combined area of all displays is356* returned.357*358* 2) The center point lies at the center of a single display. In this case359* the user most likely wants centered Windows to be constrained to that360* single display. The boundaries of the one display are returned.361*362* It is possible for the center point to be at both the center of the363* entire display space AND at the center of a single monitor (a square of364* 9 monitors, for instance). In this case, the entire display area is365* returned.366*367* Because the center point is arbitrarily settable by the user, it could368* fit neither of the cases above. The fallback case is to simply return369* the combined area for all screens.370*/371protected Rectangle getXineramaWindowBounds() {372Point center = getCenterPoint();373Rectangle unionRect, tempRect;374GraphicsDevice[] gds = getScreenDevices();375Rectangle centerMonitorRect = null;376int i;377378// if center point is at the center of all monitors379// return union of all bounds380//381// MM*MM MMM M382// M*M *383// MMM M384385// if center point is at center of a single monitor (but not of all386// monitors)387// return bounds of single monitor388//389// MMM MM390// MM* *M391392// else, center is in some strange spot (such as on the border between393// monitors), and we should just return the union of all monitors394//395// MM MMM396// MM MMM397398unionRect = getUsableBounds(gds[0]);399400for (i = 0; i < gds.length; i++) {401tempRect = getUsableBounds(gds[i]);402if (centerMonitorRect == null &&403// add a pixel or two for fudge-factor404(tempRect.width / 2) + tempRect.x > center.x - 1 &&405(tempRect.height / 2) + tempRect.y > center.y - 1 &&406(tempRect.width / 2) + tempRect.x < center.x + 1 &&407(tempRect.height / 2) + tempRect.y < center.y + 1) {408centerMonitorRect = tempRect;409}410unionRect = unionRect.union(tempRect);411}412413// first: check for center of all monitors (video wall)414// add a pixel or two for fudge-factor415if ((unionRect.width / 2) + unionRect.x > center.x - 1 &&416(unionRect.height / 2) + unionRect.y > center.y - 1 &&417(unionRect.width / 2) + unionRect.x < center.x + 1 &&418(unionRect.height / 2) + unionRect.y < center.y + 1) {419420if (screenLog.isLoggable(PlatformLogger.Level.FINER)) {421screenLog.finer("Video Wall: center point is at center of all displays.");422}423return unionRect;424}425426// next, check if at center of one monitor427if (centerMonitorRect != null) {428if (screenLog.isLoggable(PlatformLogger.Level.FINER)) {429screenLog.finer("Center point at center of a particular " +430"monitor, but not of the entire virtual display.");431}432return centerMonitorRect;433}434435// otherwise, the center is at some weird spot: return unionRect436if (screenLog.isLoggable(PlatformLogger.Level.FINER)) {437screenLog.finer("Center point is somewhere strange - return union of all bounds.");438}439return unionRect;440}441442/**443* From the DisplayChangedListener interface; devices do not need444* to react to this event.445*/446@Override447public void paletteChanged() {448}449}450451452