--- a/jdk/make/mapfiles/libawt/mapfile-vers-linux Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/make/mapfiles/libawt/mapfile-vers-linux Fri Nov 13 18:36:14 2015 +0400
@@ -206,6 +206,7 @@
Java_sun_awt_X11GraphicsDevice_enumDisplayModes;
Java_sun_awt_X11GraphicsDevice_configDisplayMode;
Java_sun_awt_X11GraphicsDevice_resetNativeData;
+ Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor;
Java_sun_awt_X11GraphicsEnvironment_checkShmExt;
Java_sun_awt_X11GraphicsEnvironment_getDefaultScreenNum;
Java_sun_awt_X11GraphicsEnvironment_getDisplayString;
--- a/jdk/make/mapfiles/libawt_xawt/mapfile-vers Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/make/mapfiles/libawt_xawt/mapfile-vers Fri Nov 13 18:36:14 2015 +0400
@@ -214,6 +214,7 @@
Java_sun_awt_X11GraphicsDevice_enumDisplayModes;
Java_sun_awt_X11GraphicsDevice_configDisplayMode;
Java_sun_awt_X11GraphicsDevice_resetNativeData;
+ Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor;
Java_sun_awt_X11GraphicsConfig_initIDs;
Java_sun_awt_X11GraphicsConfig_getXResolution;
Java_sun_awt_X11GraphicsConfig_getYResolution;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java Fri Nov 13 18:36:14 2015 +0400
@@ -80,9 +80,7 @@
pack();
Dimension size = getSize();
- // TODO: When 6356322 is fixed we should get screen bounds in
- // this way: eframe.getGraphicsConfiguration().getBounds().
- Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Rectangle scrSize = getGraphicsConfiguration().getBounds();
if (corner.x < scrSize.width/2 && corner.y < scrSize.height/2) { // 1st square
setLocation(corner.x + indent, corner.y + indent);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java Fri Nov 13 18:36:14 2015 +0400
@@ -300,6 +300,22 @@
}
/**
+ * Returns scale factor of the window. It is used to convert native
+ * coordinates to local and vice verse.
+ */
+ protected int getScale() {
+ return 1;
+ }
+
+ protected int scaleUp(int x) {
+ return x;
+ }
+
+ protected int scaleDown(int x) {
+ return x;
+ }
+
+ /**
* Creates window with parameters specified by <code>params</code>
* @see #init
*/
@@ -366,15 +382,17 @@
log.fine("Creating window for " + this + " with the following attributes: \n" + params);
}
window = XlibWrapper.XCreateWindow(XToolkit.getDisplay(),
- parentWindow.longValue(),
- bounds.x, bounds.y, // location
- bounds.width, bounds.height, // size
- 0, // border
- depth.intValue(), // depth
- visual_class.intValue(), // class
- visual.longValue(), // visual
- value_mask, // value mask
- xattr.pData); // attributes
+ parentWindow.longValue(),
+ scaleUp(bounds.x),
+ scaleUp(bounds.y),
+ scaleUp(bounds.width),
+ scaleUp(bounds.height),
+ 0, // border
+ depth.intValue(), // depth
+ visual_class.intValue(), // class
+ visual.longValue(), // visual
+ value_mask, // value mask
+ xattr.pData); // attributes
if (window == 0) {
throw new IllegalStateException("Couldn't create window because of wrong parameters. Run with NOISY_AWT to see details");
@@ -492,18 +510,18 @@
// we want to reset PPosition in hints. This is necessary
// for locationByPlatform functionality
if ((flags & XUtilConstants.PPosition) != 0) {
- hints.set_x(x);
- hints.set_y(y);
+ hints.set_x(scaleUp(x));
+ hints.set_y(scaleUp(y));
}
if ((flags & XUtilConstants.PSize) != 0) {
- hints.set_width(width);
- hints.set_height(height);
+ hints.set_width(scaleUp(width));
+ hints.set_height(scaleUp(height));
} else if ((hints.get_flags() & XUtilConstants.PSize) != 0) {
flags |= XUtilConstants.PSize;
}
if ((flags & XUtilConstants.PMinSize) != 0) {
- hints.set_min_width(width);
- hints.set_min_height(height);
+ hints.set_min_width(scaleUp(width));
+ hints.set_min_height(scaleUp(height));
} else if ((hints.get_flags() & XUtilConstants.PMinSize) != 0) {
flags |= XUtilConstants.PMinSize;
//Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
@@ -512,31 +530,31 @@
if ((flags & XUtilConstants.PMaxSize) != 0) {
if (maxBounds != null) {
if (maxBounds.width != Integer.MAX_VALUE) {
- hints.set_max_width(maxBounds.width);
+ hints.set_max_width(scaleUp(maxBounds.width));
} else {
hints.set_max_width(XToolkit.getDefaultScreenWidth());
}
if (maxBounds.height != Integer.MAX_VALUE) {
- hints.set_max_height(maxBounds.height);
+ hints.set_max_height(scaleUp(maxBounds.height));
} else {
hints.set_max_height(XToolkit.getDefaultScreenHeight());
}
} else {
- hints.set_max_width(width);
- hints.set_max_height(height);
+ hints.set_max_width(scaleUp(width));
+ hints.set_max_height(scaleUp(height));
}
} else if ((hints.get_flags() & XUtilConstants.PMaxSize) != 0) {
flags |= XUtilConstants.PMaxSize;
if (maxBounds != null) {
if (maxBounds.width != Integer.MAX_VALUE) {
- hints.set_max_width(maxBounds.width);
+ hints.set_max_width(scaleUp(maxBounds.width));
} else {
- hints.set_max_width(XToolkit.getDefaultScreenWidth());
+ hints.set_max_width(scaleUp(XToolkit.getDefaultScreenWidth()));
}
if (maxBounds.height != Integer.MAX_VALUE) {
- hints.set_max_height(maxBounds.height);
+ hints.set_max_height(scaleUp(maxBounds.height));
} else {
- hints.set_max_height(XToolkit.getDefaultScreenHeight());
+ hints.set_max_height(scaleUp(XToolkit.getDefaultScreenHeight()));
}
} else {
// Leave intact
@@ -723,7 +741,9 @@
height = Math.max(MIN_SIZE, height);
XToolkit.awtLock();
try {
- XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);
+ XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(),
+ scaleUp(x), scaleUp(y),
+ scaleUp(width), scaleUp(height));
} finally {
XToolkit.awtUnlock();
}
@@ -756,7 +776,8 @@
rpt.x = x + srcPeer.getAbsoluteX();
rpt.y = y + srcPeer.getAbsoluteY();
} else {
- rpt = XlibUtil.translateCoordinates(src, dst, new Point(x, y));
+ int scale = srcPeer == null ? 1 : srcPeer.getScale();
+ rpt = XlibUtil.translateCoordinates(src, dst, new Point(x, y), scale);
}
return rpt;
}
@@ -1042,10 +1063,11 @@
if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
insLog.finer("Configure, {0}", xe);
}
- x = xe.get_x();
- y = xe.get_y();
- width = xe.get_width();
- height = xe.get_height();
+
+ x = scaleDown(xe.get_x());
+ y = scaleDown(xe.get_y());
+ width = scaleDown(xe.get_width());
+ height = scaleDown(xe.get_height());
}
/**
* Checks ButtonRelease released all Mouse buttons
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XChoicePeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XChoicePeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -785,7 +785,7 @@
numItemsDisplayed = Math.min(MAX_UNFURLED_ITEMS, numItems);
}
Point global = XChoicePeer.this.toGlobal(0,0);
- Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ Rectangle screen = graphicsConfig.getBounds();
if (alignUnder != null) {
Rectangle choiceRec = XChoicePeer.this.getBounds();
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -158,7 +158,9 @@
XComponentPeer newPeer = (XComponentPeer)newNativeParent;
XToolkit.awtLock();
try {
- XlibWrapper.XReparentWindow(XToolkit.getDisplay(), getWindow(), newPeer.getContentWindow(), x, y);
+ XlibWrapper.XReparentWindow(XToolkit.getDisplay(),
+ getWindow(), newPeer.getContentWindow(),
+ scaleUp(x), scaleUp(y));
parentWindow = newPeer;
} finally {
XToolkit.awtUnlock();
@@ -1394,6 +1396,12 @@
XToolkit.awtLock();
try {
if (shape != null) {
+
+ int scale = getScale();
+ if (scale != 1) {
+ shape = shape.getScaledRegion(scale, scale);
+ }
+
XlibWrapper.SetRectangularShape(
XToolkit.getDisplay(),
getWindow(),
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -737,16 +737,12 @@
updateChildrenSizes();
- // Bounds of the window
- Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds(target);
-
Point newLocation = getNewLocation(xe, currentInsets.left, currentInsets.top);
-
WindowDimensions newDimensions =
new WindowDimensions(newLocation,
- new Dimension(xe.get_width(), xe.get_height()),
- copy(currentInsets),
- true);
+ new Dimension(scaleDown(xe.get_width()),
+ scaleDown(xe.get_height())),
+ copy(currentInsets), true);
if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
insLog.finer("Insets are {0}, new dimensions {1}",
@@ -793,7 +789,8 @@
try {
updateSizeHints(rec.x, rec.y, rec.width, rec.height);
XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getShell(),
- rec.x, rec.y, rec.width, rec.height);
+ scaleUp(rec.x), scaleUp(rec.y),
+ scaleUp(rec.width), scaleUp(rec.height));
}
finally {
XToolkit.awtUnlock();
@@ -806,7 +803,8 @@
XToolkit.awtLock();
try {
updateSizeHints(rec.x, rec.y, rec.width, rec.height);
- XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
+ XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(),
+ scaleUp(rec.width), scaleUp(rec.height));
}
finally {
XToolkit.awtUnlock();
@@ -819,7 +817,8 @@
XToolkit.awtLock();
try {
updateSizeHints(rec.x, rec.y, rec.width, rec.height);
- XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
+ XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(),
+ scaleUp(rec.x), scaleUp(rec.y));
}
finally {
XToolkit.awtUnlock();
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -83,6 +83,8 @@
private long[] sourceFormats = null;
/* The XID of the root subwindow that contains the current target. */
private long targetRootSubwindow = 0;
+ /* window scale factor */
+ int windowScale = 1;
/* The pointer location. */
private int xRoot = 0;
private int yRoot = 0;
@@ -130,8 +132,8 @@
long xcursor = 0;
long rootWindow = 0;
- long dragWindow = 0;
long timeStamp = 0;
+ windowScale = wpeer.getScale();
/* Retrieve the X cursor for the drag operation. */
{
@@ -156,8 +158,6 @@
rootWindow = XlibWrapper.RootWindow(XToolkit.getDisplay(), screen);
}
- dragWindow = XWindow.getXAWTRootWindow().getWindow();
-
timeStamp = XToolkit.getCurrentServerTime();
int dropActions = getDragSourceContext().getSourceActions();
@@ -441,8 +441,8 @@
private void updateTargetWindow(XMotionEvent xmotion) {
assert XToolkit.isAWTLockHeldByCurrentThread();
- int x = xmotion.get_x_root();
- int y = xmotion.get_y_root();
+ int x = scaleDown(xmotion.get_x_root());
+ int y = scaleDown(xmotion.get_y_root());
long time = xmotion.get_time();
long subwindow = xmotion.get_subwindow();
@@ -498,9 +498,13 @@
if (!dragInProgress) {
return;
}
- if (xRoot != xmotion.get_x_root() || yRoot != xmotion.get_y_root()) {
- xRoot = xmotion.get_x_root();
- yRoot = xmotion.get_y_root();
+
+ int motionXRoot = scaleDown(xmotion.get_x_root());
+ int motionYRoot = scaleDown(xmotion.get_y_root());
+
+ if (xRoot != motionXRoot || yRoot != motionYRoot) {
+ xRoot = motionXRoot;
+ yRoot = motionYRoot;
postDragSourceDragEvent(targetAction,
XWindow.getModifiers(xmotion.get_state(),0,0),
@@ -519,8 +523,8 @@
updateTargetWindow(xmotion);
if (dragProtocol != null) {
- dragProtocol.sendMoveMessage(xmotion.get_x_root(),
- xmotion.get_y_root(),
+ dragProtocol.sendMoveMessage(scaleDown(xmotion.get_x_root()),
+ scaleDown(xmotion.get_y_root()),
sourceAction, sourceActions,
xmotion.get_time());
}
@@ -528,8 +532,8 @@
private void processDrop(XButtonEvent xbutton) {
try {
- dragProtocol.initiateDrop(xbutton.get_x_root(),
- xbutton.get_y_root(),
+ dragProtocol.initiateDrop(scaleDown(xbutton.get_x_root()),
+ scaleDown(xbutton.get_y_root()),
sourceAction, sourceActions,
xbutton.get_time());
} catch (XException e) {
@@ -805,4 +809,12 @@
dndInProgress = false;
cleanup(XConstants.CurrentTime);
}
+
+ public int scaleUp(int x) {
+ return x * windowScale;
+ }
+
+ public int scaleDown(int x) {
+ return x / windowScale;
+ }
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedClientHelper.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedClientHelper.java Fri Nov 13 18:36:14 2015 +0400
@@ -182,7 +182,7 @@
embedded.notifyStopped();
// check if newParent is a root window
X11GraphicsConfig gc = (X11GraphicsConfig)embedded.getGraphicsConfiguration();
- X11GraphicsDevice gd = (X11GraphicsDevice)gc.getDevice();
+ X11GraphicsDevice gd = gc.getDevice();
if ((newParent == XlibUtil.getRootWindow(gd.getScreen())) ||
(newParent == XToolkit.getDefaultRootWindow()))
{
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbeddedFramePeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbeddedFramePeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -146,18 +146,18 @@
// fix for 5063031
// if we use super.handleConfigureNotifyEvent() we would get wrong
// size and position because embedded frame really is NOT a decorated one
- checkIfOnNewScreen(toGlobal(new Rectangle(xe.get_x(),
- xe.get_y(),
- xe.get_width(),
- xe.get_height())));
+ checkIfOnNewScreen(toGlobal(new Rectangle(scaleDown(xe.get_x()),
+ scaleDown(xe.get_y()),
+ scaleDown(xe.get_width()),
+ scaleDown(xe.get_height()))));
Rectangle oldBounds = getBounds();
synchronized (getStateLock()) {
- x = xe.get_x();
- y = xe.get_y();
- width = xe.get_width();
- height = xe.get_height();
+ x = scaleDown(xe.get_x());
+ y = scaleDown(xe.get_y());
+ width = scaleDown(xe.get_width());
+ height = scaleDown(xe.get_height());
dimensions.setClientSize(width, height);
dimensions.setLocation(x, y);
@@ -215,10 +215,10 @@
try {
XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
getWindow(), attr.pData);
- x = attr.get_x();
- y = attr.get_y();
- w = attr.get_width();
- h = attr.get_height();
+ x = scaleDown(attr.get_x());
+ y = scaleDown(attr.get_y());
+ w = scaleDown(attr.get_width());
+ h = scaleDown(attr.get_height());
} finally {
XToolkit.awtUnlock();
}
@@ -276,7 +276,7 @@
{
Point absoluteLoc = XlibUtil.translateCoordinates(getWindow(),
XToolkit.getDefaultRootWindow(),
- new Point(0, 0));
+ new Point(0, 0), getScale());
return absoluteLoc != null ? absoluteLoc.x : 0;
}
@@ -284,7 +284,7 @@
{
Point absoluteLoc = XlibUtil.translateCoordinates(getWindow(),
XToolkit.getDefaultRootWindow(),
- new Point(0, 0));
+ new Point(0, 0), getScale());
return absoluteLoc != null ? absoluteLoc.y : 0;
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuBarPeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuBarPeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -296,7 +296,7 @@
*/
protected Rectangle getSubmenuBounds(Rectangle itemBounds, Dimension windowSize) {
Rectangle globalBounds = toGlobal(itemBounds);
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension screenSize = graphicsConfig.getBounds().getSize();
Rectangle res;
res = fitWindowBelow(globalBounds, windowSize, screenSize);
if (res != null) {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuWindow.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuWindow.java Fri Nov 13 18:36:14 2015 +0400
@@ -278,7 +278,7 @@
*/
protected Rectangle getSubmenuBounds(Rectangle itemBounds, Dimension windowSize) {
Rectangle globalBounds = toGlobal(itemBounds);
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension screenSize = graphicsConfig.getBounds().getSize();
Rectangle res;
res = fitWindowRight(globalBounds, windowSize, screenSize);
if (res != null) {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -30,6 +30,7 @@
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsDevice;
import java.awt.peer.MouseInfoPeer;
+import sun.awt.X11GraphicsDevice;
import sun.awt.AWTAccessor;
@@ -64,6 +65,12 @@
if (pointerFound) {
point.x = Native.getInt(XlibWrapper.larg3);
point.y = Native.getInt(XlibWrapper.larg4);
+ GraphicsDevice device = gds[i];
+ if (device instanceof X11GraphicsDevice) {
+ int scale = ((X11GraphicsDevice) device).getScaleFactor();
+ point.x = XlibUtil.scaleDown(point.x, scale);
+ point.y = XlibUtil.scaleDown(point.y, scale);
+ }
return i;
}
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -215,7 +215,7 @@
*/
protected Rectangle getWindowBounds(Point origin, Dimension windowSize) {
Rectangle globalBounds = new Rectangle(origin.x, origin.y, 0, 0);
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension screenSize = graphicsConfig.getBounds().getSize();
Rectangle res;
res = fitWindowRight(globalBounds, windowSize, screenSize);
if (res != null) {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -64,7 +64,7 @@
@Override
public void mouseMove(int x, int y) {
- mouseMoveImpl(xgc, x, y);
+ mouseMoveImpl(xgc, xgc.scaleUp(x), xgc.scaleUp(y));
}
@Override
@@ -95,7 +95,8 @@
@Override
public int getRGBPixel(int x, int y) {
int pixelArray[] = new int[1];
- getRGBPixelsImpl(xgc, x, y, 1, 1, pixelArray, isGtkSupported);
+ getRGBPixelsImpl(xgc, x, y, 1, 1, xgc.getScale(), pixelArray,
+ isGtkSupported);
return pixelArray[0];
}
@@ -103,7 +104,7 @@
public int [] getRGBPixels(Rectangle bounds) {
int pixelArray[] = new int[bounds.width*bounds.height];
getRGBPixelsImpl(xgc, bounds.x, bounds.y, bounds.width, bounds.height,
- pixelArray, isGtkSupported);
+ xgc.getScale(), pixelArray, isGtkSupported);
return pixelArray;
}
@@ -118,5 +119,6 @@
private static synchronized native void keyReleaseImpl(int keycode);
private static synchronized native void getRGBPixelsImpl(X11GraphicsConfig xgc,
- int x, int y, int width, int height, int pixelArray[], boolean isGtkSupported);
+ int x, int y, int width, int height, int scale,
+ int pixelArray[], boolean isGtkSupported);
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Fri Nov 13 18:36:14 2015 +0400
@@ -57,6 +57,7 @@
import sun.security.action.GetPropertyAction;
import sun.security.action.GetBooleanAction;
import sun.util.logging.PlatformLogger;
+import static sun.awt.X11.XlibUtil.scaleDown;
public final class XToolkit extends UNIXToolkit implements Runnable {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XToolkit");
@@ -422,7 +423,7 @@
}
}
- private void processGlobalMotionEvent(XEvent e) {
+ private void processGlobalMotionEvent(XEvent e, XBaseWindow win) {
// Only our windows guaranteely generate MotionNotify, so we
// should track enter/leave, to catch the moment when to
// switch to XQueryPointer
@@ -431,9 +432,11 @@
awtLock();
try {
if (lastCursorPos == null) {
- lastCursorPos = new Point(ev.get_x_root(), ev.get_y_root());
+ lastCursorPos = new Point(win.scaleDown(ev.get_x_root()),
+ win.scaleDown(ev.get_y_root()));
} else {
- lastCursorPos.setLocation(ev.get_x_root(), ev.get_y_root());
+ lastCursorPos.setLocation(win.scaleDown(ev.get_x_root()),
+ win.scaleDown(ev.get_y_root()));
}
} finally {
awtUnlock();
@@ -452,9 +455,11 @@
awtLock();
try {
if (lastCursorPos == null) {
- lastCursorPos = new Point(ev.get_x_root(), ev.get_y_root());
+ lastCursorPos = new Point(win.scaleDown(ev.get_x_root()),
+ win.scaleDown(ev.get_y_root()));
} else {
- lastCursorPos.setLocation(ev.get_x_root(), ev.get_y_root());
+ lastCursorPos.setLocation(win.scaleDown(ev.get_x_root()),
+ win.scaleDown(ev.get_y_root()));
}
} finally {
awtUnlock();
@@ -492,10 +497,11 @@
private void dispatchEvent(XEvent ev) {
final XAnyEvent xany = ev.get_xany();
- if (windowToXWindow(xany.get_window()) != null &&
- (ev.get_type() == XConstants.MotionNotify || ev.get_type() == XConstants.EnterNotify || ev.get_type() == XConstants.LeaveNotify))
- {
- processGlobalMotionEvent(ev);
+ XBaseWindow baseWindow = windowToXWindow(xany.get_window());
+ if (baseWindow != null && (ev.get_type() == XConstants.MotionNotify
+ || ev.get_type() == XConstants.EnterNotify
+ || ev.get_type() == XConstants.LeaveNotify)) {
+ processGlobalMotionEvent(ev, baseWindow);
}
if( ev.get_type() == XConstants.MappingNotify ) {
@@ -670,8 +676,8 @@
XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
XToolkit.getDefaultRootWindow(),
pattr.pData);
- screenWidth = pattr.get_width();
- screenHeight = pattr.get_height();
+ screenWidth = config.scaleDown(pattr.get_width());
+ screenHeight = config.scaleDown(pattr.get_height());
} finally {
pattr.dispose();
}
@@ -701,7 +707,7 @@
return getDefaultScreenHeight();
}
- private static Rectangle getWorkArea(long root)
+ private static Rectangle getWorkArea(long root, int scale)
{
XAtom XA_NET_WORKAREA = XAtom.get("_NET_WORKAREA");
@@ -717,7 +723,10 @@
int rootWidth = (int)Native.getLong(native_ptr, 2);
int rootHeight = (int)Native.getLong(native_ptr, 3);
- return new Rectangle(rootX, rootY, rootWidth, rootHeight);
+ return new Rectangle(scaleDown(rootX, scale),
+ scaleDown(rootY, scale),
+ scaleDown(rootWidth, scale),
+ scaleDown(rootHeight, scale));
}
}
finally
@@ -750,15 +759,16 @@
try
{
X11GraphicsConfig x11gc = (X11GraphicsConfig)gc;
- X11GraphicsDevice x11gd = (X11GraphicsDevice)x11gc.getDevice();
+ X11GraphicsDevice x11gd = x11gc.getDevice();
long root = XlibUtil.getRootWindow(x11gd.getScreen());
- Rectangle rootBounds = XlibUtil.getWindowGeometry(root);
+ int scale = x11gc.getScale();
+ Rectangle rootBounds = XlibUtil.getWindowGeometry(root, scale);
X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
GraphicsEnvironment.getLocalGraphicsEnvironment();
if (!x11ge.runningXinerama())
{
- Rectangle workArea = XToolkit.getWorkArea(root);
+ Rectangle workArea = XToolkit.getWorkArea(root, scale);
if (workArea != null)
{
return new Insets(workArea.y,
@@ -768,7 +778,7 @@
}
}
- return getScreenInsetsManually(root, rootBounds, gc.getBounds());
+ return getScreenInsetsManually(root, rootBounds, gc.getBounds(), scale);
}
finally
{
@@ -783,7 +793,8 @@
*
* This method should be called under XToolkit.awtLock()
*/
- private Insets getScreenInsetsManually(long root, Rectangle rootBounds, Rectangle screenBounds)
+ private Insets getScreenInsetsManually(long root, Rectangle rootBounds,
+ Rectangle screenBounds, int scale)
{
/*
* During the manual calculation of screen insets we iterate
@@ -831,20 +842,23 @@
if (strutPresent)
{
// second, verify that window is located on the proper screen
- Rectangle windowBounds = XlibUtil.getWindowGeometry(window);
+ Rectangle windowBounds = XlibUtil.getWindowGeometry(window,
+ scale);
if (windowLevel > 1)
{
- windowBounds = XlibUtil.translateCoordinates(window, root, windowBounds);
+ windowBounds = XlibUtil.translateCoordinates(window, root,
+ windowBounds,
+ scale);
}
// if _NET_WM_STRUT_PARTIAL is present, we should use its values to detect
// if the struts area intersects with screenBounds, however some window
// managers don't set this hint correctly, so we just get intersection with windowBounds
if (windowBounds != null && windowBounds.intersects(screenBounds))
{
- int left = (int)Native.getLong(native_ptr, 0);
- int right = (int)Native.getLong(native_ptr, 1);
- int top = (int)Native.getLong(native_ptr, 2);
- int bottom = (int)Native.getLong(native_ptr, 3);
+ int left = scaleDown((int)Native.getLong(native_ptr, 0), scale);
+ int right = scaleDown((int)Native.getLong(native_ptr, 1), scale);
+ int top = scaleDown((int)Native.getLong(native_ptr, 2), scale);
+ int bottom = scaleDown((int)Native.getLong(native_ptr, 3), scale);
/*
* struts could be relative to root window bounds, so
@@ -2487,7 +2501,8 @@
oops_updated = false;
long event_number = getEventNumber();
// Generate OOPS ConfigureNotify event
- XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(), ++oops_position, 0);
+ XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(),
+ win.scaleUp(++oops_position), 0);
// Change win position each time to avoid system optimization
if (oops_position > 50) {
oops_position = 0;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Fri Nov 13 18:36:14 2015 +0400
@@ -1024,8 +1024,12 @@
shellBounds.translate(-window.currentInsets.left, -window.currentInsets.top);
window.updateSizeHints(window.getDimensions());
requestWMExtents(window.getWindow());
- XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), window.getShell(),
- shellBounds.x, shellBounds.y, shellBounds.width, shellBounds.height);
+ XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(),
+ window.getShell(),
+ window.scaleUp(shellBounds.x),
+ window.scaleUp(shellBounds.y),
+ window.scaleUp(shellBounds.width),
+ window.scaleUp(shellBounds.height));
/* REMINDER: will need to revisit when setExtendedStateBounds is added */
//Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
//We need to update frame's minimum size, not to reset it
@@ -1058,8 +1062,12 @@
window.updateSizeHints(newDimensions);
requestWMExtents(window.getWindow());
XToolkit.XSync();
- XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), window.getShell(),
- shellBounds.x, shellBounds.y, shellBounds.width, shellBounds.height);
+ XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(),
+ window.getShell(),
+ window.scaleUp(shellBounds.x),
+ window.scaleUp(shellBounds.y),
+ window.scaleUp(shellBounds.width),
+ window.scaleUp(shellBounds.height));
}
if (!justChangeSize) { /* update decorations */
setShellDecor(window);
@@ -1701,6 +1709,12 @@
pattr.dispose();
}
}
+
+ correctWM.top = win.scaleUp(correctWM.top);
+ correctWM.bottom = win.scaleUp(correctWM.bottom);
+ correctWM.left = win.scaleUp(correctWM.left);
+ correctWM.right = win.scaleUp(correctWM.right);
+
if (storedInsets.get(win.getClass()) == null) {
storedInsets.put(win.getClass(), correctWM);
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWarningWindow.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWarningWindow.java Fri Nov 13 18:36:14 2015 +0400
@@ -258,10 +258,10 @@
super.handleExposeEvent(xev);
XExposeEvent xe = xev.get_xexpose();
- final int x = xe.get_x();
- final int y = xe.get_y();
- final int width = xe.get_width();
- final int height = xe.get_height();
+ final int x = scaleDown(xe.get_x());
+ final int y = scaleDown(xe.get_y());
+ final int width = scaleDown(xe.get_width());
+ final int height = scaleDown(xe.get_height());
SunToolkit.executeOnEventHandlerThread(target,
new Runnable() {
public void run() {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java Fri Nov 13 18:36:14 2015 +0400
@@ -548,10 +548,11 @@
if (isEventDisabled(xev)) {
return;
}
- int x = xe.get_x();
- int y = xe.get_y();
- int w = xe.get_width();
- int h = xe.get_height();
+
+ int x = scaleDown(xe.get_x());
+ int y = scaleDown(xe.get_y());
+ int w = scaleDown(xe.get_width());
+ int h = scaleDown(xe.get_height());
Component target = getEventSource();
ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor();
@@ -676,10 +677,11 @@
when = xbe.get_time();
long jWhen = XToolkit.nowMillisUTC_offset(when);
- int x = xbe.get_x();
- int y = xbe.get_y();
+ int x = scaleDown(xbe.get_x());
+ int y = scaleDown(xbe.get_y());
if (xev.get_xany().get_window() != window) {
- Point localXY = toLocal(xbe.get_x_root(), xbe.get_y_root());
+ Point localXY = toLocal(scaleDown(xbe.get_x_root()),
+ scaleDown(xbe.get_y_root()));
x = localXY.x;
y = localXY.y;
}
@@ -730,8 +732,8 @@
MouseEvent me = new MouseEvent(getEventSource(),
type == XConstants.ButtonPress ? MouseEvent.MOUSE_PRESSED : MouseEvent.MOUSE_RELEASED,
jWhen,modifiers, x, y,
- xbe.get_x_root(),
- xbe.get_y_root(),
+ scaleDown(xbe.get_x_root()),
+ scaleDown(xbe.get_y_root()),
clickCount,popupTrigger,button);
postEventToEventQueue(me);
@@ -744,8 +746,8 @@
jWhen,
modifiers,
x, y,
- xbe.get_x_root(),
- xbe.get_y_root(),
+ scaleDown(xbe.get_x_root()),
+ scaleDown(xbe.get_y_root()),
clickCount,
false, button));
}
@@ -757,8 +759,8 @@
MouseWheelEvent mwe = new MouseWheelEvent(getEventSource(),MouseEvent.MOUSE_WHEEL, jWhen,
modifiers,
x, y,
- xbe.get_x_root(),
- xbe.get_y_root(),
+ scaleDown(xbe.get_x_root()),
+ scaleDown(xbe.get_y_root()),
1,false,MouseWheelEvent.WHEEL_UNIT_SCROLL,
3,button==4 ? -1 : 1);
postEventToEventQueue(mwe);
@@ -805,8 +807,8 @@
/*
Fix for 6176814 . Add multiclick checking.
*/
- int x = xme.get_x();
- int y = xme.get_y();
+ int x = scaleDown(xme.get_x());
+ int y = scaleDown(xme.get_y());
XWindow lastWindow = (lastWindowRef != null) ? (lastWindowRef.get()):(null);
if (!(lastWindow == this &&
@@ -828,7 +830,8 @@
Component source = getEventSource();
if (xme.get_window() != window) {
- Point localXY = toLocal(xme.get_x_root(), xme.get_y_root());
+ Point localXY = toLocal(scaleDown(xme.get_x_root()),
+ scaleDown(xme.get_y_root()));
x = localXY.x;
y = localXY.y;
}
@@ -837,7 +840,9 @@
*/
if ((isDragging && clickCount == 0) || !isDragging) {
MouseEvent mme = new MouseEvent(source, mouseEventType, jWhen,
- modifiers, x, y, xme.get_x_root(), xme.get_y_root(),
+ modifiers, x, y,
+ scaleDown(xme.get_x_root()),
+ scaleDown(xme.get_y_root()),
clickCount, popupTrigger, MouseEvent.NOBUTTON);
postEventToEventQueue(mme);
}
@@ -949,10 +954,11 @@
int modifiers = getModifiers(xce.get_state(),0,0);
int clickCount = 0;
boolean popupTrigger = false;
- int x = xce.get_x();
- int y = xce.get_y();
+ int x = scaleDown(xce.get_x());
+ int y = scaleDown(xce.get_y());
if (xce.get_window() != window) {
- Point localXY = toLocal(xce.get_x_root(), xce.get_y_root());
+ Point localXY = toLocal(scaleDown(xce.get_x_root()),
+ scaleDown(xce.get_y_root()));
x = localXY.x;
y = localXY.y;
}
@@ -960,18 +966,27 @@
// This code tracks boundary crossing and ensures MOUSE_ENTER/EXIT
// are posted in alternate pairs
if (compWithMouse != null) {
- MouseEvent me = new MouseEvent(compWithMouse,
- MouseEvent.MOUSE_EXITED, jWhen, modifiers, xce.get_x(),
- xce.get_y(), xce.get_x_root(), xce.get_y_root(), clickCount, popupTrigger,
- MouseEvent.NOBUTTON);
+ MouseEvent me = new MouseEvent(compWithMouse, MouseEvent.MOUSE_EXITED,
+ jWhen, modifiers,
+ scaleDown(xce.get_x()),
+ scaleDown(xce.get_y()),
+ scaleDown(xce.get_x_root()),
+ scaleDown(xce.get_y_root()),
+ clickCount, popupTrigger,
+ MouseEvent.NOBUTTON);
postEventToEventQueue(me);
eventLog.finest("Clearing last window ref");
lastWindowRef = null;
}
if (xce.get_type() == XConstants.EnterNotify) {
MouseEvent me = new MouseEvent(getEventSource(), MouseEvent.MOUSE_ENTERED,
- jWhen, modifiers, xce.get_x(), xce.get_y(), xce.get_x_root(), xce.get_y_root(), clickCount,
- popupTrigger, MouseEvent.NOBUTTON);
+ jWhen, modifiers,
+ scaleDown(xce.get_x()),
+ scaleDown(xce.get_y()),
+ scaleDown(xce.get_x_root()),
+ scaleDown(xce.get_y_root()),
+ clickCount, popupTrigger,
+ MouseEvent.NOBUTTON);
postEventToEventQueue(me);
}
}
@@ -1531,4 +1546,18 @@
}
}
+ @Override
+ protected int getScale() {
+ return graphicsConfig.getScale();
+ }
+
+ @Override
+ protected int scaleUp(int x) {
+ return graphicsConfig.scaleUp(x);
+ }
+
+ @Override
+ protected int scaleDown(int x) {
+ return graphicsConfig.scaleDown(x);
+ }
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Fri Nov 13 18:36:14 2015 +0400
@@ -29,6 +29,7 @@
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.WindowEvent;
+import java.awt.geom.AffineTransform;
import java.awt.peer.ComponentPeer;
import java.awt.peer.WindowPeer;
@@ -750,10 +751,10 @@
private Point queryXLocation()
{
- return XlibUtil.translateCoordinates(
- getContentWindow(),
- XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()),
- new Point(0, 0));
+ return XlibUtil.translateCoordinates(getContentWindow(), XlibWrapper
+ .RootWindow(XToolkit.getDisplay(),
+ getScreenNumber()),
+ new Point(0, 0), getScale());
}
protected Point getNewLocation(XConfigureEvent xe, int leftInset, int topInset) {
@@ -764,7 +765,8 @@
Point newLocation = targetBounds.getLocation();
if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
// Location, Client size + insets
- newLocation = new Point(xe.get_x() - leftInset, xe.get_y() - topInset);
+ newLocation = new Point(scaleDown(xe.get_x()) - leftInset,
+ scaleDown(xe.get_y()) - topInset);
} else {
// ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
// a window is resized but the client can not tell if the window was
@@ -807,12 +809,12 @@
* See getNewLocation() for the details.
*/
Point newLocation = getNewLocation(xe, 0, 0);
- xe.set_x(newLocation.x);
- xe.set_y(newLocation.y);
- checkIfOnNewScreen(new Rectangle(xe.get_x(),
- xe.get_y(),
- xe.get_width(),
- xe.get_height()));
+ xe.set_x(scaleUp(newLocation.x));
+ xe.set_y(scaleUp(newLocation.y));
+ checkIfOnNewScreen(new Rectangle(newLocation.x,
+ newLocation.y,
+ scaleDown(xe.get_width()),
+ scaleDown(xe.get_height())));
// Don't call super until we've handled a screen change. Otherwise
// there could be a race condition in which a ComponentListener could
@@ -2115,7 +2117,9 @@
XCrossingEvent xce = xev.get_xcrossing();
if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
grabLog.fine("{0}, when grabbed {1}, contains {2}",
- xce, isGrabbed(), containsGlobal(xce.get_x_root(), xce.get_y_root()));
+ xce, isGrabbed(),
+ containsGlobal(scaleDown(xce.get_x_root()),
+ scaleDown(xce.get_y_root())));
}
if (isGrabbed()) {
// When window is grabbed, all events are dispatched to
@@ -2141,7 +2145,9 @@
XMotionEvent xme = xev.get_xmotion();
if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
grabLog.finer("{0}, when grabbed {1}, contains {2}",
- xme, isGrabbed(), containsGlobal(xme.get_x_root(), xme.get_y_root()));
+ xme, isGrabbed(),
+ containsGlobal(scaleDown(xme.get_x_root()),
+ scaleDown(xme.get_y_root())));
}
if (isGrabbed()) {
boolean dragging = false;
@@ -2166,9 +2172,10 @@
// So, I do not want to implement complicated logic for better retargeting.
target = pressTarget.isVisible() ? pressTarget : this;
xme.set_window(target.getWindow());
- Point localCoord = target.toLocal(xme.get_x_root(), xme.get_y_root());
- xme.set_x(localCoord.x);
- xme.set_y(localCoord.y);
+ Point localCoord = target.toLocal(scaleDown(xme.get_x_root()),
+ scaleDown(xme.get_y_root()));
+ xme.set_x(scaleUp(localCoord.x));
+ xme.set_y(scaleUp(localCoord.y));
}
if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
grabLog.finer(" - Grab event target {0}", target);
@@ -2182,7 +2189,9 @@
// note that we need to pass dragging events to the grabber (6390326)
// see comment above for more inforamtion.
- if (!containsGlobal(xme.get_x_root(), xme.get_y_root()) && !dragging) {
+ if (!containsGlobal(scaleDown(xme.get_x_root()),
+ scaleDown(xme.get_y_root()))
+ && !dragging) {
// Outside of Java
return;
}
@@ -2195,7 +2204,6 @@
public void handleButtonPressRelease(XEvent xev) {
XButtonEvent xbe = xev.get_xbutton();
-
/*
* Ignore the buttons above 20 due to the bit limit for
* InputEvent.BUTTON_DOWN_MASK.
@@ -2206,7 +2214,11 @@
}
if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
grabLog.fine("{0}, when grabbed {1}, contains {2} ({3}, {4}, {5}x{6})",
- xbe, isGrabbed(), containsGlobal(xbe.get_x_root(), xbe.get_y_root()), getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight());
+ xbe, isGrabbed(),
+ containsGlobal(scaleDown(xbe.get_x_root()),
+ scaleDown(xbe.get_y_root())),
+ getAbsoluteX(), getAbsoluteY(),
+ getWidth(), getHeight());
}
if (isGrabbed()) {
// When window is grabbed, all events are dispatched to
@@ -2232,9 +2244,10 @@
// see 6390326 for more information.
target = pressTarget.isVisible() ? pressTarget : this;
xbe.set_window(target.getWindow());
- Point localCoord = target.toLocal(xbe.get_x_root(), xbe.get_y_root());
- xbe.set_x(localCoord.x);
- xbe.set_y(localCoord.y);
+ Point localCoord = target.toLocal(scaleDown(xbe.get_x_root()),
+ scaleDown(xbe.get_y_root()));
+ xbe.set_x(scaleUp(localCoord.x));
+ xbe.set_y(scaleUp(localCoord.y));
pressTarget = this;
}
if (target != null && target != getContentXWindow() && target != this) {
@@ -2246,7 +2259,10 @@
// Target is either us or our content window -
// check that event is inside. 'Us' in case of
// shell will mean that this will also filter out press on title
- if ((target == this || target == getContentXWindow()) && !containsGlobal(xbe.get_x_root(), xbe.get_y_root())) {
+ if ((target == this || target == getContentXWindow())
+ && !containsGlobal(scaleDown(xbe.get_x_root()),
+ scaleDown(xbe.get_y_root())))
+ {
// Outside this toplevel hierarchy
// According to the specification of UngrabEvent, post it
// when press occurs outside of the window and not on its owned windows
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XlibUtil.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XlibUtil.java Fri Nov 13 18:36:14 2015 +0400
@@ -102,7 +102,7 @@
/**
* Returns the bounds of the given window, in absolute coordinates
*/
- static Rectangle getWindowGeometry(long window)
+ static Rectangle getWindowGeometry(long window, int scale)
{
XToolkit.awtLock();
try
@@ -126,7 +126,9 @@
long width = Native.getUInt(XlibWrapper.larg4);
long height = Native.getUInt(XlibWrapper.larg5);
- return new Rectangle(x, y, (int)width, (int)height);
+ return new Rectangle(scaleDown(x, scale), scaleDown(y, scale),
+ scaleDown((int) width, scale),
+ scaleDown((int) height, scale));
}
finally
{
@@ -138,7 +140,7 @@
* Translates the given point from one window to another. Returns
* null if the translation is failed
*/
- static Point translateCoordinates(long src, long dst, Point p)
+ static Point translateCoordinates(long src, long dst, Point p, int scale)
{
Point translated = null;
@@ -146,7 +148,7 @@
try
{
XTranslateCoordinates xtc =
- new XTranslateCoordinates(src, dst, p.x, p.y);
+ new XTranslateCoordinates(src, dst, p.x * scale, p.y * scale);
try
{
int status = xtc.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
@@ -154,7 +156,8 @@
((XErrorHandlerUtil.saved_error == null) ||
(XErrorHandlerUtil.saved_error.get_error_code() == XConstants.Success)))
{
- translated = new Point(xtc.get_dest_x(), xtc.get_dest_y());
+ translated = new Point(scaleDown(xtc.get_dest_x(), scale),
+ scaleDown(xtc.get_dest_y(), scale));
}
}
finally
@@ -174,9 +177,12 @@
* Translates the given rectangle from one window to another.
* Returns null if the translation is failed
*/
- static Rectangle translateCoordinates(long src, long dst, Rectangle r)
+ static Rectangle translateCoordinates(long src, long dst, Rectangle r,
+ int scale)
{
- Point translatedLoc = translateCoordinates(src, dst, r.getLocation());
+ Point translatedLoc = translateCoordinates(src, dst, r.getLocation(),
+ scale);
+
if (translatedLoc == null)
{
return null;
@@ -406,4 +412,8 @@
return 1 << (7 + button);
}
}
+
+ static int scaleDown(int x, int scale) {
+ return x / scale;
+ }
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsConfig.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsConfig.java Fri Nov 13 18:36:14 2015 +0400
@@ -133,7 +133,7 @@
/**
* Return the graphics device associated with this configuration.
*/
- public GraphicsDevice getDevice() {
+ public X11GraphicsDevice getDevice() {
return screen;
}
@@ -256,7 +256,20 @@
* For image buffers, this Transform will be the Identity transform.
*/
public AffineTransform getDefaultTransform() {
- return new AffineTransform();
+ double scale = getScale();
+ return AffineTransform.getScaleInstance(scale, scale);
+ }
+
+ public int getScale() {
+ return getDevice().getScaleFactor();
+ }
+
+ public int scaleUp(int x) {
+ return x * getScale();
+ }
+
+ public int scaleDown(int x) {
+ return x / getScale();
}
/**
@@ -308,7 +321,14 @@
}
public Rectangle getBounds() {
- return pGetBounds(screen.getScreen());
+ Rectangle rect = pGetBounds(screen.getScreen());
+ if (getScale() != 1) {
+ rect.x = scaleDown(rect.x);
+ rect.y = scaleDown(rect.y);
+ rect.width = scaleDown(rect.width);
+ rect.height = scaleDown(rect.height);
+ }
+ return rect;
}
private native Rectangle pGetBounds(int screenNum);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java Fri Nov 13 18:36:14 2015 +0400
@@ -43,6 +43,7 @@
import sun.java2d.loops.SurfaceType;
import sun.awt.util.ThreadGroupUtils;
+import sun.java2d.SunGraphicsEnvironment;
import sun.misc.ManagedLocalsThread;
/**
@@ -63,9 +64,11 @@
private SunDisplayChanger topLevels = new SunDisplayChanger();
private DisplayMode origDisplayMode;
private boolean shutdownHookRegistered;
+ private final int scale;
public X11GraphicsDevice(int screennum) {
this.screen = screennum;
+ this.scale = initScaleFactor();
}
/*
@@ -279,6 +282,7 @@
int width, int height,
int displayMode);
private static native void resetNativeData(int screen);
+ private static native int getNativeScaleFactor(int screen);
/**
* Returns true only if:
@@ -509,6 +513,27 @@
topLevels.add(client);
}
+ public int getScaleFactor() {
+ return scale;
+ }
+
+ private int initScaleFactor() {
+
+ if (SunGraphicsEnvironment.isUIScaleEnabled()) {
+
+ double debugScale = SunGraphicsEnvironment.getDebugScale();
+
+ if (debugScale >= 1) {
+ return (int) debugScale;
+ }
+
+ int nativeScale = getNativeScaleFactor(screen);
+ return nativeScale >= 1 ? nativeScale : 1;
+ }
+
+ return 1;
+ }
+
/**
* Remove a DisplayChangeListener from this X11GraphicsDevice.
*/
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java Fri Nov 13 18:36:14 2015 +0400
@@ -244,7 +244,8 @@
int width, int height,
ColorModel cm, Image image,
long drawable,
- int transparency) {
+ int transparency,
+ boolean isTexture) {
int depth;
// If we have a 32 bit color model for the window it needs
// alpha to support translucency of the window so we need
@@ -267,7 +268,7 @@
return new XRPixmapSurfaceData
(gc, width, height, image, getSurfaceType(gc, transparency),
cm, drawable, transparency,
- XRUtils.getPictureFormatForTransparency(transparency), depth);
+ XRUtils.getPictureFormatForTransparency(transparency), depth, isTexture);
}
protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc,
@@ -542,11 +543,16 @@
}
public static class XRWindowSurfaceData extends XRSurfaceData {
+
+ protected final int scale;
+
public XRWindowSurfaceData(X11ComponentPeer peer,
XRGraphicsConfig gc, SurfaceType sType) {
super(peer, gc, sType, peer.getColorModel(),
peer.getColorModel().getPixelSize(), Transparency.OPAQUE);
+ this.scale = gc.getScale();
+
if (isXRDrawableValid()) {
// If we have a 32 bit color model for the window it needs
// alpha to support translucency of the window so we need
@@ -571,6 +577,8 @@
public Rectangle getBounds() {
Rectangle r = peer.getBounds();
r.x = r.y = 0;
+ r.width *= scale;
+ r.height *= scale;
return r;
}
@@ -596,6 +604,16 @@
super.invalidate();
}
+
+ @Override
+ public double getDefaultScaleX() {
+ return scale;
+ }
+
+ @Override
+ public double getDefaultScaleY() {
+ return scale;
+ }
}
public static class XRInternalSurfaceData extends XRSurfaceData {
@@ -627,18 +645,20 @@
int width;
int height;
int transparency;
+ private final int scale;
public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height,
Image image, SurfaceType sType,
ColorModel cm, long drawable,
int transparency, int pictFormat,
- int depth) {
+ int depth, boolean isTexture) {
super(null, gc, sType, cm, depth, transparency);
- this.width = width;
- this.height = height;
+ this.scale = isTexture ? 1 : gc.getDevice().getScaleFactor();
+ this.width = width * scale;
+ this.height = height * scale;
offscreenImage = image;
this.transparency = transparency;
- initSurface(depth, width, height, drawable, pictFormat);
+ initSurface(depth, this.width, this.height, drawable, pictFormat);
initXRender(pictFormat);
makePipes();
@@ -696,6 +716,16 @@
public Object getDestination() {
return offscreenImage;
}
+
+ @Override
+ public double getDefaultScaleX() {
+ return scale;
+ }
+
+ @Override
+ public double getDefaultScaleY() {
+ return scale;
+ }
}
public long getGC() {
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Fri Nov 13 18:36:14 2015 +0400
@@ -59,8 +59,9 @@
public SurfaceData validateSurfaceData(SurfaceData srcData,
SurfaceData cachedData, int w, int h) {
if (cachedData == null) {
- cachedData = XRSurfaceData.createData(xrgc, w, h, xrgc
- .getColorModel(), null, 0, getTransparency());
+ cachedData = XRSurfaceData.createData(xrgc, w, h,
+ xrgc.getColorModel(), null, 0,
+ getTransparency(), true);
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRVolatileSurfaceManager.java Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRVolatileSurfaceManager.java Fri Nov 13 18:36:14 2015 +0400
@@ -59,10 +59,10 @@
drawable = ((Long)context).longValue();
}
sData = XRSurfaceData.createData(gc,
- vImg.getWidth(),
- vImg.getHeight(),
- cm, vImg, drawable,
- vImg.getTransparency());
+ vImg.getWidth(),
+ vImg.getHeight(),
+ cm, vImg, drawable,
+ vImg.getTransparency(), false);
} catch (NullPointerException ex) {
sData = null;
} catch (OutOfMemoryError er) {
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Fri Nov 13 18:36:14 2015 +0400
@@ -2082,3 +2082,38 @@
/**
* End DisplayMode/FullScreen support
*/
+
+int getScale(const char *name) {
+ char *uiScale = getenv(name);
+ if (uiScale != NULL) {
+ double scale = strtod(uiScale, NULL);
+ if (errno == ERANGE || scale < 1) {
+ return -1;
+ }
+ return (int) scale;
+ }
+ return -1;
+}
+
+/*
+ * Class: sun_awt_X11GraphicsDevice
+ * Method: getNativeScaleFactor
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor
+ (JNIEnv *env, jobject this, jint screen) {
+
+ // for debug purposes
+ static int scale = -2.0;
+
+ if (scale == -2) {
+ scale = getScale("J2D_UISCALE");
+ }
+
+ if (scale >= 1) {
+ return scale;
+ }
+
+ return getScale("GDK_SCALE");
+}
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c Fri Nov 13 18:36:14 2015 +0400
@@ -210,6 +210,7 @@
jint jy,
jint jwidth,
jint jheight,
+ jint scale,
jintArray pixelArray,
jboolean isGtkSupported) {
XImage *image;
@@ -231,13 +232,18 @@
AWT_LOCK();
+ jint sx = jx * scale;
+ jint sy = jy * scale;
+ jint swidth = jwidth * scale;
+ jint sheight = jheight * scale;
+
rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
if (!XGetWindowAttributes(awt_display, rootWindow, &attr)
- || jx + jwidth <= attr.x
- || attr.x + attr.width <= jx
- || jy + jheight <= attr.y
- || attr.y + attr.height <= jy) {
+ || sx + swidth <= attr.x
+ || attr.x + attr.width <= sx
+ || sy + sheight <= attr.y
+ || attr.y + attr.height <= sy) {
AWT_UNLOCK();
return; // Does not intersect with root window
@@ -246,14 +252,14 @@
gboolean gtk_failed = TRUE;
jint _x, _y;
- jint x = MAX(jx, attr.x);
- jint y = MAX(jy, attr.y);
- jint width = MIN(jx + jwidth, attr.x + attr.width) - x;
- jint height = MIN(jy + jheight, attr.y + attr.height) - y;
+ jint x = MAX(sx, attr.x);
+ jint y = MAX(sy, attr.y);
+ jint width = MIN(sx + swidth, attr.x + attr.width) - x;
+ jint height = MIN(sy + sheight, attr.y + attr.height) - y;
- int dx = attr.x > jx ? attr.x - jx : 0;
- int dy = attr.y > jy ? attr.y - jy : 0;
+ int dx = attr.x > sx ? attr.x - sx : 0;
+ int dy = attr.y > sy ? attr.y - sy : 0;
int index;
@@ -264,6 +270,19 @@
pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(NULL, root, NULL,
x, y, 0, 0, width, height);
+ if (pixbuf && scale != 1) {
+ GdkPixbuf *scaledPixbuf;
+ x /= scale;
+ y /= scale;
+ width /= scale;
+ height /= scale;
+ dx /= scale;
+ dy /= scale;
+ scaledPixbuf = (*fp_gdk_pixbuf_scale_simple)(pixbuf, width, height,
+ GDK_INTERP_BILINEAR);
+ (*fp_g_object_unref)(pixbuf);
+ pixbuf = scaledPixbuf;
+ }
if (pixbuf) {
int nchan = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
@@ -312,7 +331,7 @@
}
if (gtk_failed) {
- image = getWindowImage(awt_display, rootWindow, x, y, width, height);
+ image = getWindowImage(awt_display, rootWindow, sx, sy, swidth, sheight);
ary = (*env)->GetPrimitiveArrayCritical(env, pixelArray, NULL);
@@ -322,10 +341,16 @@
return;
}
+ dx /= scale;
+ dy /= scale;
+ width /= scale;
+ height /= scale;
+
/* convert to Java ARGB pixels */
for (_y = 0; _y < height; _y++) {
for (_x = 0; _x < width; _x++) {
- jint pixel = (jint) XGetPixel(image, _x, _y); /* Note ignore upper
+ jint pixel = (jint) XGetPixel(image, _x * scale, _y * scale);
+ /* Note ignore upper
* 32-bits on 64-bit
* OSes.
*/
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Fri Nov 13 18:36:14 2015 +0400
@@ -648,6 +648,8 @@
fp_gdk_pixmap_new = dl_symbol("gdk_pixmap_new");
fp_gdk_pixbuf_get_from_drawable =
dl_symbol("gdk_pixbuf_get_from_drawable");
+ fp_gdk_pixbuf_scale_simple =
+ dl_symbol("gdk_pixbuf_scale_simple");
fp_gdk_gc_new = dl_symbol("gdk_gc_new");
fp_gdk_rgb_gc_set_foreground =
dl_symbol("gdk_rgb_gc_set_foreground");
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h Fri Nov 13 05:02:26 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h Fri Nov 13 18:36:14 2015 +0400
@@ -270,6 +270,13 @@
G_PARAM_PRIVATE = 1 << 5
} GParamFlags;
+typedef enum {
+ GDK_INTERP_NEAREST,
+ GDK_INTERP_TILES,
+ GDK_INTERP_BILINEAR,
+ GDK_INTERP_HYPER
+} GdkInterpType;
+
/* We define all structure pointers to be void* */
typedef void GError;
typedef void GMainContext;
@@ -787,6 +794,8 @@
GdkPixbuf *(*fp_gdk_pixbuf_get_from_drawable)(GdkPixbuf *dest,
GdkDrawable *src, GdkColormap *cmap, int src_x, int src_y,
int dest_x, int dest_y, int width, int height);
+GdkPixbuf *(*fp_gdk_pixbuf_scale_simple)(GdkPixbuf *src,
+ int dest_width, int dest_heigh, GdkInterpType interp_type);
void (*fp_gtk_widget_destroy)(GtkWidget *widget);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesLinuxTest.java Fri Nov 13 18:36:14 2015 +0400
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import javax.swing.UIManager;
+
+/* @test
+ * @bug 8137571
+ * @summary Linux HiDPI Graphics support
+ * @author Alexander Scherbatiy
+ * @requires (os.family == "linux")
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=false
+ * -Dsun.java2d.uiScale=2
+ * HiDPIPropertiesLinuxTest UISCALE_DISABLED
+ * HiDPIPropertiesTest UISCALE_DISABLED
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=true
+ * -Dsun.java2d.uiScale=3
+ * HiDPIPropertiesLinuxTest UISCALE_3
+ * @run main/othervm -Dsun.java2d.uiScale=4
+ * HiDPIPropertiesLinuxTest UISCALE_4
+ */
+public class HiDPIPropertiesLinuxTest {
+
+ public static void main(String[] args) throws Exception {
+
+ try {
+ UIManager.setLookAndFeel(
+ "com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
+ } catch (Exception e) {
+ return;
+ }
+
+ String testCase = args[0];
+ switch (testCase) {
+ case "UISCALE_DISABLED":
+ testScale(1.0, 1.0);
+ break;
+ case "UISCALE_3":
+ testScale(3.0, 3.0);
+ break;
+ case "UISCALE_4":
+ testScale(4.0, 4.0);
+ break;
+ default:
+ throw new RuntimeException("Unknown test case: " + testCase);
+ }
+ }
+
+ private static void testScale(double scaleX, double scaleY) {
+
+ Dialog dialog = new Dialog((Frame) null, true) {
+
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+ AffineTransform tx = ((Graphics2D) g).getTransform();
+ dispose();
+ if (scaleX != tx.getScaleX() || scaleY != tx.getScaleY()) {
+ throw new RuntimeException(String.format("Wrong scale:"
+ + "[%f, %f] instead of [%f, %f].",
+ tx.getScaleX(), tx.getScaleY(), scaleX, scaleY));
+ }
+ }
+ };
+ dialog.setSize(200, 300);
+ dialog.setVisible(true);
+ }
+}