Merge
authorprr
Tue, 17 Nov 2015 13:09:16 -0800
changeset 34405 d152b09f62ba
parent 34403 b4ca8477370e (diff)
parent 33866 e4b2a5f4dea0 (current diff)
child 34406 a6823037ceb8
Merge
jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java
jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
jdk/test/java/util/stream/bootlib/java/util/stream/CollectorOps.java
jdk/test/java/util/stream/bootlib/java/util/stream/DefaultMethodStreams.java
jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java
jdk/test/java/util/stream/bootlib/java/util/stream/FlagDeclaringOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java
jdk/test/java/util/stream/bootlib/java/util/stream/IntermediateTestOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java
jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestMode.java
jdk/test/java/util/stream/bootlib/java/util/stream/LoggingTestCase.java
jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java
jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java
jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java
jdk/test/java/util/stream/bootlib/java/util/stream/StatefulTestOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/StatelessTestOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/StreamOpFlagTestHelper.java
jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java
jdk/test/java/util/stream/bootlib/java/util/stream/TestData.java
jdk/test/java/util/stream/bootlib/java/util/stream/TestFlagExpectedOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/ThowableHelper.java
jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/FlagOpTest.java
jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/NodeBuilderTest.java
jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/SliceSpliteratorTest.java
jdk/test/java/util/stream/boottest/java/util/stream/SpinedBufferTest.java
jdk/test/java/util/stream/boottest/java/util/stream/StreamFlagsTest.java
jdk/test/java/util/stream/boottest/java/util/stream/StreamOpFlagsTest.java
jdk/test/java/util/stream/boottest/java/util/stream/StreamReuseTest.java
--- a/jdk/make/mapfiles/libawt/mapfile-vers-linux	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/make/mapfiles/libawt/mapfile-vers-linux	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/make/mapfiles/libawt_xawt/mapfile-vers	Tue Nov 17 13:09:16 2015 -0800
@@ -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.base/windows/native/launcher/java.manifest	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.base/windows/native/launcher/java.manifest	Tue Nov 17 13:09:16 2015 -0800
@@ -37,7 +37,7 @@
   <!-- Indicate JDK is high-dpi aware. -->
   <asmv3:application>
     <asmv3:windowsSettings  xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
-       <dpiAware>true</dpiAware>
+       <dpiAware>true/PM</dpiAware>
     </asmv3:windowsSettings>
   </asmv3:application>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CCompositeGlyphMapper.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,155 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.font;
+
+public final class CCompositeGlyphMapper extends CompositeGlyphMapper {
+
+    private CompositeFont font;
+    private CharToGlyphMapper slotMappers[];
+
+    public CCompositeGlyphMapper(CompositeFont compFont) {
+        super(compFont);
+        font = compFont;
+        slotMappers = new CharToGlyphMapper[font.numSlots];
+        missingGlyph = 0;
+    }
+
+    private CharToGlyphMapper getSlotMapper(int slot) {
+        CharToGlyphMapper mapper = slotMappers[slot];
+        if (mapper == null) {
+            mapper = font.getSlotFont(slot).getMapper();
+            slotMappers[slot] = mapper;
+        }
+        return mapper;
+    }
+
+    public boolean canDisplay(char ch) {
+        int glyph = charToGlyph(ch);
+        return glyph != missingGlyph;
+    }
+
+    private int convertToGlyph(int unicode) {
+        for (int slot = 0; slot < font.numSlots; slot++) {
+            CharToGlyphMapper mapper = getSlotMapper(slot);
+            int glyphCode = mapper.charToGlyph(unicode);
+            // The CFont Mappers will return a negative code
+            // for fonts that will fill the glyph from fallbacks
+            // - cascading font in OSX-speak. But we need to be
+            //  know here that only the codes > 0 are really present.
+            if (glyphCode > 0) {
+                glyphCode = compositeGlyphCode(slot, glyphCode);
+                return glyphCode;
+            }
+        }
+        return missingGlyph;
+    }
+
+    public int getNumGlyphs() {
+        int numGlyphs = 0;
+        for (int slot=0; slot<1 /*font.numSlots*/; slot++) {
+           CharToGlyphMapper mapper = slotMappers[slot];
+           if (mapper == null) {
+               mapper = font.getSlotFont(slot).getMapper();
+               slotMappers[slot] = mapper;
+           }
+           numGlyphs += mapper.getNumGlyphs();
+        }
+        return numGlyphs;
+    }
+
+    public int charToGlyph(int unicode) {
+        return convertToGlyph(unicode);
+    }
+
+    public int charToGlyph(char unicode) {
+        return convertToGlyph(unicode);
+    }
+
+    public boolean charsToGlyphsNS(int count, char[] unicodes, int[] glyphs) {
+
+        for (int i=0; i<count; i++) {
+            int code = unicodes[i]; // char is unsigned.
+
+            if (code >= HI_SURROGATE_START &&
+                code <= HI_SURROGATE_END && i < count - 1) {
+                char low = unicodes[i + 1];
+
+                if (low >= LO_SURROGATE_START &&
+                    low <= LO_SURROGATE_END) {
+                    code = (code - HI_SURROGATE_START) *
+                        0x400 + low - LO_SURROGATE_START + 0x10000;
+                    glyphs[i + 1] = INVISIBLE_GLYPH_ID;
+                }
+            }
+
+            glyphs[i] = convertToGlyph(code);
+
+            if (code < FontUtilities.MIN_LAYOUT_CHARCODE) {
+                continue;
+            }
+            else if (FontUtilities.isComplexCharCode(code)) {
+                return true;
+            }
+            else if (code >= 0x10000) {
+                i += 1; // Empty glyph slot after surrogate
+                continue;
+            }
+        }
+
+        return false;
+    }
+
+    public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {
+        for (int i=0; i<count; i++) {
+            int code = unicodes[i]; // char is unsigned.
+
+            if (code >= HI_SURROGATE_START &&
+                code <= HI_SURROGATE_END && i < count - 1) {
+                char low = unicodes[i + 1];
+
+                if (low >= LO_SURROGATE_START &&
+                    low <= LO_SURROGATE_END) {
+                    code = (code - HI_SURROGATE_START) *
+                        0x400 + low - LO_SURROGATE_START + 0x10000;
+
+                    glyphs[i] = convertToGlyph(code);
+                    i += 1; // Empty glyph slot after surrogate
+                    glyphs[i] = INVISIBLE_GLYPH_ID;
+                    continue;
+                }
+            }
+
+            glyphs[i] = convertToGlyph(code);
+        }
+    }
+
+    public void charsToGlyphs(int count, int[] unicodes, int[] glyphs) {
+        for (int i=0; i<count; i++) {
+             glyphs[i] = convertToGlyph(unicodes[i]);
+        }
+    }
+
+}
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CFont.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFont.java	Tue Nov 17 13:09:16 2015 -0800
@@ -31,12 +31,13 @@
 import java.awt.geom.GeneralPath;;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
 
 // Right now this class is final to avoid a problem with native code.
 // For some reason the JNI IsInstanceOf was not working correctly
 // so we are checking the class specifically. If we subclass this
 // we need to modify the native code in CFontWrapper.m
-public final class CFont extends PhysicalFont {
+public final class CFont extends PhysicalFont implements FontSubstitution {
 
     /* CFontStrike doesn't call these methods so they are unimplemented.
      * They are here to meet the requirements of PhysicalFont, needed
@@ -76,6 +77,20 @@
        throw new InternalError("Not implemented");
     }
 
+    @Override
+    protected long getLayoutTableCache() {
+        return getLayoutTableCacheNative(getNativeFontPtr());
+    }
+
+    @Override
+    protected byte[] getTableBytes(int tag) {
+        return getTableBytesNative(getNativeFontPtr(), tag);
+    }
+
+    private native synchronized long getLayoutTableCacheNative(long nativeFontPtr);
+
+    private native byte[] getTableBytesNative(long nativeFontPtr, int tag);
+
     private static native long createNativeFont(final String nativeFontName,
                                                 final int style);
     private static native void disposeNativeFont(final long nativeFontPtr);
@@ -179,10 +194,51 @@
     protected synchronized long getNativeFontPtr() {
         if (nativeFontPtr == 0L) {
             nativeFontPtr = createNativeFont(nativeFontName, style);
-}
+        }
         return nativeFontPtr;
     }
 
+    static native void getCascadeList(long nativeFontPtr, ArrayList<String> listOfString);
+
+    private CompositeFont createCompositeFont() {
+        ArrayList<String> listOfString = new ArrayList<String>();
+        getCascadeList(nativeFontPtr, listOfString);
+
+        FontManager fm = FontManagerFactory.getInstance();
+        int numFonts = 1 + listOfString.size();
+        PhysicalFont[] fonts = new PhysicalFont[numFonts];
+        fonts[0] = this;
+        int idx = 1;
+        for (String s : listOfString) {
+            if (s.equals(".AppleSymbolsFB"))  {
+                // Don't know why we get the weird name above .. replace.
+                s = "AppleSymbols";
+            }
+            Font2D f2d = fm.findFont2D(s, Font.PLAIN, FontManager.NO_FALLBACK);
+            if (f2d == null || f2d == this) {
+                continue;
+            }
+            fonts[idx++] = (PhysicalFont)f2d;
+        }
+        if (idx < fonts.length) {
+            PhysicalFont[] orig = fonts;
+            fonts = new PhysicalFont[idx];
+            System.arraycopy(orig, 0, fonts, 0, idx);
+        }
+        CompositeFont compFont = new CompositeFont(fonts);
+        compFont.mapper = new CCompositeGlyphMapper(compFont);
+        return compFont;
+    }
+
+    private CompositeFont compFont;
+
+    public CompositeFont getCompositeFont2D() {
+        if (compFont == null) {
+           compFont = createCompositeFont();
+        }
+        return compFont;
+    }
+
     protected synchronized void finalize() {
         if (nativeFontPtr != 0) {
             disposeNativeFont(nativeFontPtr);
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CStrike.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CStrike.java	Tue Nov 17 13:09:16 2015 -0800
@@ -31,7 +31,7 @@
 
 import sun.awt.SunHints;
 
-public final class CStrike extends FontStrike {
+public final class CStrike extends PhysicalStrike {
 
     // Creates the native strike
     private static native long createNativeStrikePtr(long nativeFontPtr,
--- a/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java	Tue Nov 17 13:09:16 2015 -0800
@@ -166,7 +166,12 @@
     }
 
     @Override
-    public int getDefaultScale() {
+    public double getDefaultScaleX() {
+        return scale;
+    }
+
+    @Override
+    public double getDefaultScaleY() {
         return scale;
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -1156,7 +1156,9 @@
             && !(dst instanceof NullSurfaceData)
             && !(src instanceof NullSurfaceData)
             && src.getSurfaceType().equals(dst.getSurfaceType())
-            && src.getDefaultScale() == dst.getDefaultScale()) {
+            && src.getDefaultScaleX() == dst.getDefaultScaleX()
+            && src.getDefaultScaleY() == dst.getDefaultScaleY())
+        {
             final Rectangle size = src.getBounds();
             final Blit blit = Blit.locate(src.getSurfaceType(),
                                           CompositeType.Src,
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.h	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.h	Tue Nov 17 13:09:16 2015 -0800
@@ -26,6 +26,8 @@
 #import <Cocoa/Cocoa.h>
 #import <JavaRuntimeSupport/JavaRuntimeSupport.h>
 
+#import "fontscalerdefs.h"
+
 #define MAX_STACK_ALLOC_GLYPH_BUFFER_SIZE 256
 
 @interface AWTFont : NSObject {
@@ -33,6 +35,7 @@
     NSFont    *fFont;
     CGFontRef  fNativeCGFont;
     BOOL       fIsFakeItalic;
+    TTLayoutTableCache* layoutTableCache;
 }
 
 + (AWTFont *) awtFontForName:(NSString *)name
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m	Tue Nov 17 13:09:16 2015 -0800
@@ -42,10 +42,33 @@
     if (self) {
         fFont = [font retain];
         fNativeCGFont = CTFontCopyGraphicsFont((CTFontRef)font, NULL);
+        layoutTableCache = NULL;
     }
     return self;
 }
 
+static TTLayoutTableCache* newCFontLayoutTableCache() {
+  TTLayoutTableCache* ltc = calloc(1, sizeof(TTLayoutTableCache));
+  if (ltc) {
+    int i;
+    for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
+      ltc->entries[i].len = -1;
+    }
+  }
+  return ltc;
+}
+
+static void freeCFontLayoutTableCache(TTLayoutTableCache* ltc) {
+  if (ltc) {
+    int i;
+    for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
+      if(ltc->entries[i].ptr) free (ltc->entries[i].ptr);
+    }
+    if (ltc->kernPairs) free(ltc->kernPairs);
+    free(ltc);
+  }
+}
+
 - (void) dealloc {
     [fFont release];
     fFont = nil;
@@ -53,6 +76,10 @@
     if (fNativeCGFont) {
         CGFontRelease(fNativeCGFont);
     fNativeCGFont = NULL;
+    if (layoutTableCache != NULL) {
+        freeCFontLayoutTableCache(layoutTableCache);
+        layoutTableCache = NULL;
+    }
     }
 
     [super dealloc];
@@ -63,6 +90,10 @@
         CGFontRelease(fNativeCGFont);
     fNativeCGFont = NULL;
     }
+    if (layoutTableCache != NULL) {
+        freeCFontLayoutTableCache(layoutTableCache);
+        layoutTableCache = NULL;
+    }
     [super finalize];
 }
 
@@ -345,6 +376,95 @@
 
 /*
  * Class:     sun_font_CFont
+ * Method:    getPlatformFontPtrNative
+ * Signature: (JI)[B
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_font_CFont_getCGFontPtrNative
+    (JNIEnv *env, jclass clazz,
+     jlong awtFontPtr)
+{
+    AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
+    return (jlong)(awtFont->fNativeCGFont);
+}
+
+/*
+ * Class:     sun_font_CFont
+ * Method:    getLayoutTableCacheNative
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_font_CFont_getLayoutTableCacheNative
+    (JNIEnv *env, jclass clazz,
+     jlong awtFontPtr)
+{
+    AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
+    if (awtFont->layoutTableCache == NULL) {
+        awtFont->layoutTableCache = newCFontLayoutTableCache();
+    }
+    return (jlong)(awtFont->layoutTableCache);
+}
+
+/*
+ * Class:     sun_font_CFont
+ * Method:    getTableBytesNative
+ * Signature: (JI)[B
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_sun_font_CFont_getTableBytesNative
+    (JNIEnv *env, jclass clazz,
+     jlong awtFontPtr, jint jtag)
+{
+    jbyteArray jbytes = NULL;
+JNF_COCOA_ENTER(env);
+
+    CTFontTableTag tag = (CTFontTableTag)jtag;
+    int i, found = 0;
+    AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
+    NSFont* nsFont = awtFont->fFont;
+    CTFontRef ctfont = (CTFontRef)nsFont;
+    CFArrayRef tagsArray =
+        CTFontCopyAvailableTables(ctfont, kCTFontTableOptionNoOptions);
+    CFIndex numTags = CFArrayGetCount(tagsArray);
+    for (i=0; i<numTags; i++) {
+        if (tag ==
+            (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tagsArray, i)) {
+            found = 1;
+            break;
+        }
+    }
+    CFRelease(tagsArray);
+    if (!found) {
+        return NULL;
+    }
+    CFDataRef table = CTFontCopyTable(ctfont, tag, kCTFontTableOptionNoOptions);
+    if (table == NULL) {
+        return NULL;
+    }
+
+    char *tableBytes = (char*)(CFDataGetBytePtr(table));
+    size_t tableLength = CFDataGetLength(table);
+    if (tableBytes == NULL || tableLength == 0) {
+        CFRelease(table);
+        return NULL;
+    }
+
+    jbytes = (*env)->NewByteArray(env, (jsize)tableLength);
+    if (jbytes == NULL) {
+        return NULL;
+    }
+    (*env)->SetByteArrayRegion(env, jbytes, 0,
+                               (jsize)tableLength,
+                               (jbyte*)tableBytes);
+    CFRelease(table);
+
+JNF_COCOA_EXIT(env);
+
+    return jbytes;
+}
+
+/*
+ * Class:     sun_font_CFont
  * Method:    initNativeFont
  * Signature: (Ljava/lang/String;I)J
  */
@@ -460,3 +580,42 @@
 {
 }
 #endif
+
+/*
+ * Class:     sun_awt_FontDescriptor
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_font_CFont_getCascadeList
+    (JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString)
+{
+    jclass alc = (*env)->FindClass(env, "java/util/ArrayList");
+    if (alc == NULL) return;
+    jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z");
+    if (addMID == NULL) return;
+
+    CFIndex i;
+    AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
+    NSFont* nsFont = awtFont->fFont;
+    CTFontRef font = (CTFontRef)nsFont;
+    CFStringRef base = CTFontCopyFullName(font);
+    CFArrayRef codes = CFLocaleCopyISOLanguageCodes();
+
+#ifdef DEBUG
+    NSLog(@"BaseFont is : %@", (NSString*)base);
+#endif
+    CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes);
+    CFIndex cnt = CFArrayGetCount(fds);
+    for (i=0; i<cnt; i++) {
+        CTFontDescriptorRef ref = CFArrayGetValueAtIndex(fds, i);
+        CFStringRef fontname =
+            CTFontDescriptorCopyAttribute(ref, kCTFontNameAttribute);
+#ifdef DEBUG
+        NSLog(@"Font is : %@", (NSString*)fontname);
+#endif
+        jstring jFontName = (jstring)JNFNSToJavaString(env, fontname);
+        (*env)->CallBooleanMethod(env, arrayListOfString, addMID, jFontName); 
+        (*env)->DeleteLocalRef(env, jFontName);
+    }
+}
--- a/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java	Tue Nov 17 13:09:16 2015 -0800
@@ -1753,11 +1753,6 @@
         if (isVisible()) {
             setVisible(false);
         }
-        if (isSelected()) {
-            try {
-                setSelected(false);
-            } catch (PropertyVetoException pve) {}
-        }
         if (!isClosed) {
           firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
           isClosed = true;
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTabbedPane.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTabbedPane.java	Tue Nov 17 13:09:16 2015 -0800
@@ -2095,9 +2095,10 @@
          */
         void setDisplayedMnemonicIndex(int mnemonicIndex) {
             if (this.mnemonicIndex != mnemonicIndex) {
-                if (mnemonicIndex != -1 && (title == null ||
+                String t = getTitle();
+                if (mnemonicIndex != -1 && (t == null ||
                         mnemonicIndex < 0 ||
-                        mnemonicIndex >= title.length())) {
+                        mnemonicIndex >= t.length())) {
                     throw new IllegalArgumentException(
                                 "Invalid mnemonic index: " + mnemonicIndex);
                 }
@@ -2116,7 +2117,7 @@
 
         void updateDisplayedMnemonicIndex() {
             setDisplayedMnemonicIndex(
-                SwingUtilities.findDisplayedMnemonicIndex(title, mnemonic));
+                SwingUtilities.findDisplayedMnemonicIndex(getTitle(), mnemonic));
         }
 
         /////////////////
@@ -2133,10 +2134,9 @@
         public String getAccessibleName() {
             if (accessibleName != null) {
                 return accessibleName;
-            } else if (title != null) {
-                return title;
+            } else {
+                return getTitle();
             }
-            return null;
         }
 
         public String getAccessibleDescription() {
@@ -2156,7 +2156,7 @@
             AccessibleStateSet states;
             states = parent.getAccessibleContext().getAccessibleStateSet();
             states.add(AccessibleState.SELECTABLE);
-            int i = parent.indexOfTab(title);
+            int i = parent.indexOfTabComponent(tabComponent);
             if (i == parent.getSelectedIndex()) {
                 states.add(AccessibleState.SELECTED);
             }
@@ -2164,7 +2164,7 @@
         }
 
         public int getAccessibleIndexInParent() {
-            return parent.indexOfTab(title);
+            return parent.indexOfTabComponent(tabComponent);
         }
 
         public int getAccessibleChildrenCount() {
@@ -2272,10 +2272,8 @@
         }
 
         public Rectangle getBounds() {
-            int i = parent.indexOfTab(title);
-            // Check for no title. Even though that's a bug in the app we should
-            // inhibit an ArrayIndexOutOfBoundsException from getTabBounds.
-            return (i == -1) ? null : parent.getUI().getTabBounds(parent, i);
+            return parent.getUI().
+                getTabBounds(parent, parent.indexOfTabComponent(tabComponent));
         }
 
         public void setBounds(Rectangle r) {
@@ -2343,6 +2341,11 @@
                 return null;
             }
         }
+
+        private String getTitle() {
+            return getTitleAt(parent.indexOfComponent(component));
+        }
+
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/TablePrintable.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/javax/swing/TablePrintable.java	Tue Nov 17 13:09:16 2015 -0800
@@ -205,11 +205,9 @@
      */
     public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
                                                        throws PrinterException {
-
         // for easy access to these values
         final int imgWidth = (int)pageFormat.getImageableWidth();
         final int imgHeight = (int)pageFormat.getImageableHeight();
-
         if (imgWidth <= 0) {
             throw new PrinterException("Width of printable area is too small.");
         }
@@ -302,10 +300,12 @@
             // been divided by it
             int scaledWidth = (int)(imgWidth / sf);
             int scaledHeight = (int)((availableSpace - hclip.height) / sf);
-
             // calculate the area of the table to be printed for this page
             findNextClip(scaledWidth, scaledHeight);
 
+            if (!((table.getBounds()).intersects(clip))) {
+                return NO_SUCH_PAGE;
+            }
             last++;
         }
 
@@ -343,7 +343,6 @@
         tempRect.width = imgWidth;
         tempRect.height = availableSpace;
         g2d.clip(tempRect);
-
         // if we have a scale factor, scale the graphics object to fit
         // the entire width
         if (sf != 1.0D) {
@@ -389,7 +388,26 @@
 
         // draw a box around the table
         g2d.setColor(Color.BLACK);
-        g2d.drawRect(0, 0, clip.width, hclip.height + clip.height);
+
+        // compute the visible portion of table and draw the rect around it
+        Rectangle visibleBounds = clip.intersection(table.getBounds());
+        Point upperLeft = visibleBounds.getLocation();
+        Point lowerRight = new Point(visibleBounds.x + visibleBounds.width,
+                                     visibleBounds.y + visibleBounds.height);
+
+        int rMin = table.rowAtPoint(upperLeft);
+        int rMax = table.rowAtPoint(lowerRight);
+        if (rMin == -1) {
+            rMin = 0;
+        }
+        if (rMax == -1) {
+            rMax = table.getRowCount();
+        }
+        int rowHeight = 0;
+        for(int visrow = rMin; visrow < rMax; visrow++) {
+            rowHeight += table.getRowHeight(visrow);
+        }
+        g2d.drawRect(0, 0, visibleBounds.width, hclip.height + rowHeight);
 
         // dispose the graphics copy
         g2d.dispose();
@@ -509,7 +527,6 @@
             if (++col >= colCount) {
                 // reset col to 0 to indicate we're finished all columns
                 col = 0;
-
                 break;
             }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java	Tue Nov 17 13:09:16 2015 -0800
@@ -1812,9 +1812,11 @@
 
         boolean ltr = table.getComponentOrientation().isLeftToRight();
 
-        Point upperLeft = clip.getLocation();
-        Point lowerRight = new Point(clip.x + clip.width - 1,
-                                     clip.y + clip.height - 1);
+        // compute the visible part of table which needs to be painted
+        Rectangle visibleBounds = clip.intersection(bounds);
+        Point upperLeft = visibleBounds.getLocation();
+        Point lowerRight = new Point(visibleBounds.x + visibleBounds.width - 1,
+                                     visibleBounds.y + visibleBounds.height - 1);
 
         int rMin = table.rowAtPoint(upperLeft);
         int rMax = table.rowAtPoint(lowerRight);
@@ -1843,6 +1845,21 @@
             cMax = table.getColumnCount()-1;
         }
 
+        Container comp = SwingUtilities.getUnwrappedParent(table);
+        if (comp != null) {
+            comp = comp.getParent();
+        }
+
+        if (comp != null && !(comp instanceof JViewport) && !(comp instanceof JScrollPane)) {
+            // We did rMax-1 to paint the same number of rows that are drawn on console
+            // otherwise 1 extra row is printed per page than that are displayed
+            // when there is no scrollPane and we do printing of table
+            // but not when rmax is already pointing to index of last row
+            if (rMax != (table.getRowCount() - 1)) {
+                rMax = rMax - 1;
+            }
+        }
+
         // Paint the grid.
         paintGrid(g, rMin, rMax, cMin, cMax);
 
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/BufImgSurfaceData.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/BufImgSurfaceData.java	Tue Nov 17 13:09:16 2015 -0800
@@ -50,6 +50,8 @@
     BufferedImage bufImg;
     private BufferedImageGraphicsConfig graphicsConfig;
     RenderLoops solidloops;
+    private final double scaleX;
+    private final double scaleY;
 
     private static native void initIDs(Class<?> ICM, Class<?> ICMColorData);
 
@@ -73,6 +75,12 @@
     }
 
     public static SurfaceData createData(BufferedImage bufImg) {
+        return createData(bufImg, 1, 1);
+    }
+
+    public static SurfaceData createData(BufferedImage bufImg,
+                                         double scaleX, double scaleY)
+    {
         if (bufImg == null) {
             throw new NullPointerException("BufferedImage cannot be null");
         }
@@ -82,31 +90,36 @@
         // REMIND: Check the image type and pick an appropriate subclass
         switch (type) {
         case BufferedImage.TYPE_INT_BGR:
-            sData = createDataIC(bufImg, SurfaceType.IntBgr);
+            sData = createDataIC(bufImg, SurfaceType.IntBgr, scaleX, scaleY);
             break;
         case BufferedImage.TYPE_INT_RGB:
-            sData = createDataIC(bufImg, SurfaceType.IntRgb);
+            sData = createDataIC(bufImg, SurfaceType.IntRgb, scaleX, scaleY);
             break;
         case BufferedImage.TYPE_INT_ARGB:
-            sData = createDataIC(bufImg, SurfaceType.IntArgb);
+            sData = createDataIC(bufImg, SurfaceType.IntArgb, scaleX, scaleY);
             break;
         case BufferedImage.TYPE_INT_ARGB_PRE:
-            sData = createDataIC(bufImg, SurfaceType.IntArgbPre);
+            sData = createDataIC(bufImg, SurfaceType.IntArgbPre, scaleX, scaleY);
             break;
         case BufferedImage.TYPE_3BYTE_BGR:
-            sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2);
+            sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2,
+                                 scaleX, scaleY);
             break;
         case BufferedImage.TYPE_4BYTE_ABGR:
-            sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3);
+            sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3,
+                                 scaleX, scaleY);
             break;
         case BufferedImage.TYPE_4BYTE_ABGR_PRE:
-            sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3);
+            sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3,
+                                 scaleX, scaleY);
             break;
         case BufferedImage.TYPE_USHORT_565_RGB:
-            sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null);
+            sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null,
+                                 scaleX, scaleY);
             break;
         case BufferedImage.TYPE_USHORT_555_RGB:
-            sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null);
+            sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null,
+                                 scaleX, scaleY);
             break;
         case BufferedImage.TYPE_BYTE_INDEXED:
             {
@@ -128,14 +141,16 @@
                 default:
                     throw new InternalError("Unrecognized transparency");
                 }
-                sData = createDataBC(bufImg, sType, 0);
+                sData = createDataBC(bufImg, sType, 0, scaleX, scaleY);
             }
             break;
         case BufferedImage.TYPE_BYTE_GRAY:
-            sData = createDataBC(bufImg, SurfaceType.ByteGray, 0);
+            sData = createDataBC(bufImg, SurfaceType.ByteGray, 0,
+                                 scaleX, scaleY);
             break;
         case BufferedImage.TYPE_USHORT_GRAY:
-            sData = createDataSC(bufImg, SurfaceType.UshortGray, null);
+            sData = createDataSC(bufImg, SurfaceType.UshortGray, null,
+                                 scaleX, scaleY);
             break;
         case BufferedImage.TYPE_BYTE_BINARY:
             {
@@ -154,7 +169,7 @@
                 default:
                     throw new InternalError("Unrecognized pixel size");
                 }
-                sData = createDataBP(bufImg, sType);
+                sData = createDataBP(bufImg, sType, scaleX, scaleY);
             }
             break;
         case BufferedImage.TYPE_CUSTOM:
@@ -191,7 +206,7 @@
                             sType = SurfaceType.AnyDcm;
                         }
                     }
-                    sData = createDataIC(bufImg, sType);
+                    sData = createDataIC(bufImg, sType, scaleX, scaleY);
                     break;
                 } else if (raster instanceof ShortComponentRaster &&
                            raster.getNumDataElements() == 1 &&
@@ -233,11 +248,12 @@
                             icm = null;
                         }
                     }
-                    sData = createDataSC(bufImg, sType, icm);
+                    sData = createDataSC(bufImg, sType, icm, scaleX, scaleY);
                     break;
                 }
-                sData = new BufImgSurfaceData(raster.getDataBuffer(),
-                                              bufImg, SurfaceType.Custom);
+                sData = new BufImgSurfaceData(raster.getDataBuffer(), bufImg,
+                                              SurfaceType.Custom,
+                                              scaleX, scaleY);
             }
             break;
         }
@@ -250,11 +266,15 @@
     }
 
     public static SurfaceData createDataIC(BufferedImage bImg,
-                                           SurfaceType sType) {
+                                           SurfaceType sType,
+                                           double scaleX,
+                                           double scaleY)
+    {
         IntegerComponentRaster icRaster =
             (IntegerComponentRaster)bImg.getRaster();
         BufImgSurfaceData bisd =
-            new BufImgSurfaceData(icRaster.getDataBuffer(), bImg, sType);
+            new BufImgSurfaceData(icRaster.getDataBuffer(), bImg, sType,
+                                  scaleX, scaleY);
         bisd.initRaster(icRaster.getDataStorage(),
                         icRaster.getDataOffset(0) * 4, 0,
                         icRaster.getWidth(),
@@ -267,11 +287,14 @@
 
     public static SurfaceData createDataSC(BufferedImage bImg,
                                            SurfaceType sType,
-                                           IndexColorModel icm) {
+                                           IndexColorModel icm,
+                                           double scaleX, double scaleY)
+    {
         ShortComponentRaster scRaster =
             (ShortComponentRaster)bImg.getRaster();
         BufImgSurfaceData bisd =
-            new BufImgSurfaceData(scRaster.getDataBuffer(), bImg, sType);
+            new BufImgSurfaceData(scRaster.getDataBuffer(), bImg, sType,
+                                  scaleX, scaleY);
         bisd.initRaster(scRaster.getDataStorage(),
                         scRaster.getDataOffset(0) * 2, 0,
                         scRaster.getWidth(),
@@ -284,11 +307,14 @@
 
     public static SurfaceData createDataBC(BufferedImage bImg,
                                            SurfaceType sType,
-                                           int primaryBank) {
+                                           int primaryBank,
+                                           double scaleX, double scaleY)
+    {
         ByteComponentRaster bcRaster =
             (ByteComponentRaster)bImg.getRaster();
         BufImgSurfaceData bisd =
-            new BufImgSurfaceData(bcRaster.getDataBuffer(), bImg, sType);
+            new BufImgSurfaceData(bcRaster.getDataBuffer(), bImg, sType,
+                                  scaleX, scaleY);
         ColorModel cm = bImg.getColorModel();
         IndexColorModel icm = ((cm instanceof IndexColorModel)
                                ? (IndexColorModel) cm
@@ -304,11 +330,14 @@
     }
 
     public static SurfaceData createDataBP(BufferedImage bImg,
-                                           SurfaceType sType) {
+                                           SurfaceType sType,
+                                           double scaleX, double scaleY)
+    {
         BytePackedRaster bpRaster =
             (BytePackedRaster)bImg.getRaster();
         BufImgSurfaceData bisd =
-            new BufImgSurfaceData(bpRaster.getDataBuffer(), bImg, sType);
+            new BufImgSurfaceData(bpRaster.getDataBuffer(), bImg, sType,
+                                  scaleX, scaleY);
         ColorModel cm = bImg.getColorModel();
         IndexColorModel icm = ((cm instanceof IndexColorModel)
                                ? (IndexColorModel) cm
@@ -350,15 +379,22 @@
                                      IndexColorModel icm);
 
     public BufImgSurfaceData(DataBuffer db,
-                             BufferedImage bufImg, SurfaceType sType)
+                             BufferedImage bufImg,
+                             SurfaceType sType,
+                             double scaleX,
+                             double scaleY)
     {
         super(SunWritableRaster.stealTrackable(db),
               sType, bufImg.getColorModel());
         this.bufImg = bufImg;
+        this.scaleX = scaleX;
+        this.scaleY = scaleY;
     }
 
     protected BufImgSurfaceData(SurfaceType surfaceType, ColorModel cm) {
         super(surfaceType, cm);
+        this.scaleX = 1;
+        this.scaleY = 1;
     }
 
     public void initSolidLoops() {
@@ -395,7 +431,8 @@
 
     public synchronized GraphicsConfiguration getDeviceConfiguration() {
         if (graphicsConfig == null) {
-            graphicsConfig = BufferedImageGraphicsConfig.getConfig(bufImg);
+            graphicsConfig = BufferedImageGraphicsConfig
+                    .getConfig(bufImg, scaleX, scaleY);
         }
         return graphicsConfig;
     }
@@ -418,6 +455,16 @@
         return bufImg;
     }
 
+    @Override
+    public double getDefaultScaleX() {
+        return scaleX;
+    }
+
+    @Override
+    public double getDefaultScaleY() {
+        return scaleY;
+    }
+
     public static final class ICMColorData {
         private long pData = 0L;
 
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/BufferedImageGraphicsConfig.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/BufferedImageGraphicsConfig.java	Tue Nov 17 13:09:16 2015 -0800
@@ -45,19 +45,32 @@
     extends GraphicsConfiguration
 {
     private static final int numconfigs = BufferedImage.TYPE_BYTE_BINARY;
-    private static BufferedImageGraphicsConfig configs[] =
+    private static BufferedImageGraphicsConfig standardConfigs[] =
+        new BufferedImageGraphicsConfig[numconfigs];
+    private static BufferedImageGraphicsConfig scaledConfigs[] =
         new BufferedImageGraphicsConfig[numconfigs];
 
     public static BufferedImageGraphicsConfig getConfig(BufferedImage bImg) {
+        return getConfig(bImg, 1, 1);
+    }
+
+    public static BufferedImageGraphicsConfig getConfig(BufferedImage bImg,
+                                                        double scaleX,
+                                                        double scaleY)
+    {
         BufferedImageGraphicsConfig ret;
         int type = bImg.getType();
+
+        BufferedImageGraphicsConfig[] configs = (scaleX == 1 && scaleY == 1)
+                ? standardConfigs : scaledConfigs;
+
         if (type > 0 && type < numconfigs) {
             ret = configs[type];
-            if (ret != null) {
+            if (ret != null && ret.scaleX == scaleX && ret.scaleY == scaleY) {
                 return ret;
             }
         }
-        ret = new BufferedImageGraphicsConfig(bImg, null);
+        ret = new BufferedImageGraphicsConfig(bImg, null, scaleX, scaleY);
         if (type > 0 && type < numconfigs) {
             configs[type] = ret;
         }
@@ -67,8 +80,16 @@
     GraphicsDevice gd;
     ColorModel model;
     Raster raster;
+    private final double scaleX;
+    private final double scaleY;
 
     public BufferedImageGraphicsConfig(BufferedImage bufImg, Component comp) {
+        this(bufImg, comp, 1, 1);
+    }
+
+    public BufferedImageGraphicsConfig(BufferedImage bufImg, Component comp,
+                                       double scaleX, double scaleY)
+    {
         if (comp == null) {
             this.gd = new BufferedImageDevice(this);
         } else {
@@ -77,6 +98,8 @@
         }
         this.model = bufImg.getColorModel();
         this.raster = bufImg.getRaster().createCompatibleWritableRaster(1, 1);
+        this.scaleX = scaleX;
+        this.scaleY = scaleY;
     }
 
     /**
@@ -138,7 +161,7 @@
      * For image buffers, this Transform will be the Identity transform.
      */
     public AffineTransform getDefaultTransform() {
-        return new AffineTransform();
+        return AffineTransform.getScaleInstance(scaleX, scaleY);
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java	Tue Nov 17 13:09:16 2015 -0800
@@ -233,8 +233,17 @@
      * or a backup surface.
      */
     public BufferedImage getBackupImage() {
-        return graphicsConfig.createCompatibleImage(getWidth(), getHeight(),
-                                                    getTransparency());
+        return getBackupImage(1, 1);
+    }
+
+    /**
+     * This method creates a BufferedImage intended for use as a "snapshot"
+     * or a backup surface with the given horizontal and vertical scale factors.
+     */
+    public BufferedImage getBackupImage(double scaleX, double scaleY) {
+        int w = (int) Math.ceil(getWidth() * scaleX);
+        int h = (int) Math.ceil(getHeight() * scaleY);
+        return graphicsConfig.createCompatibleImage(w, h, getTransparency());
     }
 
     public BufferedImage getSnapshot() {
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/SurfaceManager.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/SurfaceManager.java	Tue Nov 17 13:09:16 2015 -0800
@@ -290,16 +290,30 @@
     }
 
     /**
-     * Returns a scale factor of the image. This is utility method, which
-     * fetches information from the SurfaceData of the image.
+     * Returns a horizontal scale factor of the image. This is utility method,
+     * which fetches information from the SurfaceData of the image.
      *
-     * @see SurfaceData#getDefaultScale
+     * @see SurfaceData#getDefaultScaleX
      */
-    public static int getImageScale(final Image img) {
+    public static double getImageScaleX(final Image img) {
         if (!(img instanceof VolatileImage)) {
             return 1;
         }
         final SurfaceManager sm = getManager(img);
-        return sm.getPrimarySurfaceData().getDefaultScale();
+        return sm.getPrimarySurfaceData().getDefaultScaleX();
+    }
+
+    /**
+     * Returns a vertical scale factor of the image. This is utility method,
+     * which fetches information from the SurfaceData of the image.
+     *
+     * @see SurfaceData#getDefaultScaleY
+     */
+    public static double getImageScaleY(final Image img) {
+        if (!(img instanceof VolatileImage)) {
+            return 1;
+        }
+        final SurfaceManager sm = getManager(img);
+        return sm.getPrimarySurfaceData().getDefaultScaleY();
     }
 }
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/VolatileSurfaceManager.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/VolatileSurfaceManager.java	Tue Nov 17 13:09:16 2015 -0800
@@ -25,18 +25,16 @@
 
 package sun.awt.image;
 
-import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsEnvironment;
 import java.awt.ImageCapabilities;
+import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
 import java.awt.image.VolatileImage;
 import sun.awt.DisplayChangedListener;
-import sun.awt.image.SunVolatileImage;
 import sun.java2d.SunGraphicsEnvironment;
 import sun.java2d.SurfaceData;
-import sun.java2d.loops.CompositeType;
 import static sun.java2d.pipe.hw.AccelSurface.*;
 
 /**
@@ -260,12 +258,16 @@
      */
     protected SurfaceData getBackupSurface() {
         if (sdBackup == null) {
-            BufferedImage bImg = vImg.getBackupImage();
+            GraphicsConfiguration gc = vImg.getGraphicsConfig();
+            AffineTransform tx = gc.getDefaultTransform();
+            double scaleX = tx.getScaleX();
+            double scaleY = tx.getScaleY();
+            BufferedImage bImg = vImg.getBackupImage(scaleX, scaleY);
             // Sabotage the acceleration capabilities of the BufImg surface
             SunWritableRaster.stealTrackable(bImg
                                              .getRaster()
                                              .getDataBuffer()).setUntrackable();
-            sdBackup = BufImgSurfaceData.createData(bImg);
+            sdBackup = BufImgSurfaceData.createData(bImg, scaleX, scaleY);
         }
         return sdBackup;
     }
--- a/jdk/src/java.desktop/share/classes/sun/font/CompositeFont.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/font/CompositeFont.java	Tue Nov 17 13:09:16 2015 -0800
@@ -149,6 +149,25 @@
         }
     }
 
+    /*
+     * Build a composite from a set of individual slot fonts.
+     */
+    CompositeFont(PhysicalFont[] slotFonts) {
+
+        isStdComposite = false;
+        handle = new Font2DHandle(this);
+        fullName = slotFonts[0].fullName;
+        familyName = slotFonts[0].familyName;
+        style = slotFonts[0].style;
+
+        numMetricsSlots = 1; /* Only the physical Font */
+        numSlots = slotFonts.length;
+
+        components = new PhysicalFont[numSlots];
+        System.arraycopy(slotFonts, 0, components, 0, numSlots);
+        deferredInitialisation = new boolean[numSlots]; // all false.
+    }
+
     /* This method is currently intended to be called only from
      * FontManager.getCompositeFontUIResource(Font)
      * It creates a new CompositeFont with the contents of the Physical
--- a/jdk/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java	Tue Nov 17 13:09:16 2015 -0800
@@ -42,7 +42,7 @@
  * this appears to cause problems.
  */
 
-public final class CompositeGlyphMapper extends CharToGlyphMapper {
+public class CompositeGlyphMapper extends CharToGlyphMapper {
 
     public static final int SLOTMASK =  0xff000000;
     public static final int GLYPHMASK = 0x00ffffff;
--- a/jdk/src/java.desktop/share/classes/sun/font/Font2D.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/font/Font2D.java	Tue Nov 17 13:09:16 2015 -0800
@@ -461,10 +461,17 @@
      * to check the font class before attempting to run, rather than needing
      * to promote this method up from TrueTypeFont
      */
-    byte[] getTableBytes(int tag) {
+    protected byte[] getTableBytes(int tag) {
         return null;
     }
 
+    /* implemented for fonts backed by an sfnt that has
+     * OpenType or AAT layout tables.
+     */
+    protected long getLayoutTableCache() {
+        return 0L;
+    }
+
     /* for layout code */
     protected long getUnitsPerEm() {
         return 2048;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/font/FontSubstitution.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,38 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package sun.font;
+
+
+
+/**
+ * Interface that indicates a Font2D that is not a Composite but has the
+ * property that it internally behaves like one, substituting glyphs
+ * from another font at render time.
+ * In this case the Font must provide a way to behave like a regular
+ * composite when that behaviour is not wanted.
+ */
+public interface FontSubstitution {
+    public CompositeFont getCompositeFont2D();
+}
--- a/jdk/src/java.desktop/share/classes/sun/font/GlyphLayout.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/font/GlyphLayout.java	Tue Nov 17 13:09:16 2015 -0800
@@ -408,6 +408,9 @@
         int lang = -1; // default for now
 
         Font2D font2D = FontUtilities.getFont2D(font);
+        if (font2D instanceof FontSubstitution) {
+            font2D = ((FontSubstitution)font2D).getCompositeFont2D();
+        }
 
         _textRecord.init(text, offset, lim, min, max);
         int start = offset;
--- a/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java	Tue Nov 17 13:09:16 2015 -0800
@@ -1124,6 +1124,9 @@
 
     private void initFontData() {
         font2D = FontUtilities.getFont2D(font);
+        if (font2D instanceof FontSubstitution) {
+           font2D = ((FontSubstitution)font2D).getCompositeFont2D();
+        }
         float s = font.getSize2D();
         if (font.isTransformed()) {
             ftx = font.getTransform();
@@ -1742,7 +1745,12 @@
                                                      aa, fm);
             // Get the strike via the handle. Shouldn't matter
             // if we've invalidated the font but its an extra precaution.
-            FontStrike strike = sgv.font2D.handle.font2D.getStrike(desc);  // !!! getStrike(desc, false)
+        // do we want the CompFont from CFont here ?
+        Font2D f2d = sgv.font2D;
+        if (f2d instanceof FontSubstitution) {
+           f2d = ((FontSubstitution)f2d).getCompositeFont2D();
+        }
+            FontStrike strike = f2d.handle.font2D.getStrike(desc);  // !!! getStrike(desc, false)
 
             return new GlyphStrike(sgv, strike, dx, dy);
         }
--- a/jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java	Tue Nov 17 13:09:16 2015 -0800
@@ -155,10 +155,7 @@
                        Point2D.Float pt, GVData data) {
         Font2D font = key.font();
         FontStrike strike = font.getStrike(desc);
-        long layoutTables = 0;
-        if (font instanceof TrueTypeFont) {
-            layoutTables = ((TrueTypeFont) font).getLayoutTableCache();
-        }
+        long layoutTables = font.getLayoutTableCache();
         nativeLayout(font, strike, mat, gmask, baseIndex,
              tr.text, tr.start, tr.limit, tr.min, tr.max,
              key.script(), key.lang(), typo_flags, pt, data,
--- a/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java	Tue Nov 17 13:09:16 2015 -0800
@@ -874,8 +874,8 @@
         }
     }
 
-    /* NB: is it better to move declaration to Font2D? */
-    long getLayoutTableCache() {
+    @Override
+    protected long getLayoutTableCache() {
         try {
           return getScaler().getLayoutTableCache();
         } catch(FontScalerException fe) {
@@ -884,7 +884,7 @@
     }
 
     @Override
-    byte[] getTableBytes(int tag) {
+    protected byte[] getTableBytes(int tag) {
         ByteBuffer buffer = getTableBuffer(tag);
         if (buffer == null) {
             return null;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java	Tue Nov 17 13:09:16 2015 -0800
@@ -61,7 +61,6 @@
 import java.awt.Rectangle;
 import java.text.AttributedCharacterIterator;
 import java.awt.Font;
-import java.awt.Point;
 import java.awt.image.ImageObserver;
 import java.awt.Transparency;
 import java.awt.font.GlyphVector;
@@ -99,6 +98,7 @@
 import static java.awt.geom.AffineTransform.TYPE_FLIP;
 import static java.awt.geom.AffineTransform.TYPE_MASK_SCALE;
 import static java.awt.geom.AffineTransform.TYPE_TRANSLATION;
+import java.awt.image.VolatileImage;
 import sun.awt.image.MultiResolutionToolkitImage;
 import sun.awt.image.ToolkitImage;
 
@@ -3086,30 +3086,50 @@
     }
 // end of text rendering methods
 
-    private boolean isHiDPIImage(final Image img) {
-        return (SurfaceManager.getImageScale(img) != 1)
-                || img instanceof MultiResolutionImage;
-    }
-
-    private boolean drawHiDPIImage(Image img, int dx1, int dy1, int dx2,
-                                   int dy2, int sx1, int sy1, int sx2, int sy2,
-                                   Color bgcolor, ImageObserver observer) {
-
-        if (SurfaceManager.getImageScale(img) != 1) {  // Volatile Image
-            final int scale = SurfaceManager.getImageScale(img);
-            sx1 = Region.clipScale(sx1, scale);
-            sx2 = Region.clipScale(sx2, scale);
-            sy1 = Region.clipScale(sy1, scale);
-            sy2 = Region.clipScale(sy2, scale);
-        } else if (img instanceof MultiResolutionImage) {
+    private Boolean drawHiDPIImage(Image img,
+                                   int dx1, int dy1, int dx2, int dy2,
+                                   int sx1, int sy1, int sx2, int sy2,
+                                   Color bgcolor, ImageObserver observer,
+                                   AffineTransform xform) {
+
+        if (img instanceof VolatileImage) {
+            final SurfaceData sd = SurfaceManager.getManager(img)
+                    .getPrimarySurfaceData();
+            final double scaleX = sd.getDefaultScaleX();
+            final double scaleY = sd.getDefaultScaleY();
+            if (scaleX == 1 && scaleY == 1) {
+                return null;
+            }
+            sx1 = Region.clipScale(sx1, scaleX);
+            sx2 = Region.clipScale(sx2, scaleX);
+            sy1 = Region.clipScale(sy1, scaleY);
+            sy2 = Region.clipScale(sy2, scaleY);
+
+            AffineTransform tx = null;
+            if (xform != null) {
+                tx = new AffineTransform(transform);
+                transform(xform);
+            }
+            boolean result = scaleImage(img, dx1, dy1, dx2, dy2,
+                                        sx1, sy1, sx2, sy2,
+                                        bgcolor, observer);
+            if (tx != null) {
+                transform.setTransform(tx);
+                invalidateTransform();
+            }
+            return result;
+        } else if (resolutionVariantHint != SunHints.INTVAL_RESOLUTION_VARIANT_BASE
+                   && (img instanceof MultiResolutionImage)) {
             // get scaled destination image size
 
             int width = img.getWidth(observer);
             int height = img.getHeight(observer);
 
-            Image resolutionVariant = getResolutionVariant(
-                    (MultiResolutionImage) img, width, height,
-                    dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2);
+            MultiResolutionImage mrImage = (MultiResolutionImage) img;
+            Image resolutionVariant = getResolutionVariant(mrImage, width, height,
+                                                           dx1, dy1, dx2, dy2,
+                                                           sx1, sy1, sx2, sy2,
+                                                           xform);
 
             if (resolutionVariant != img && resolutionVariant != null) {
                 // recalculate source region for the resolution variant
@@ -3123,8 +3143,8 @@
 
                 if (0 < width && 0 < height && 0 < rvWidth && 0 < rvHeight) {
 
-                    float widthScale = ((float) rvWidth) / width;
-                    float heightScale = ((float) rvHeight) / height;
+                    double widthScale = ((double) rvWidth) / width;
+                    double heightScale = ((double) rvHeight) / height;
 
                     sx1 = Region.clipScale(sx1, widthScale);
                     sy1 = Region.clipScale(sy1, heightScale);
@@ -3133,10 +3153,29 @@
 
                     observer = rvObserver;
                     img = resolutionVariant;
+
+                    if (xform != null) {
+                        assert dx1 == 0 && dy1 == 0;
+                        assert dx2 == img.getWidth(observer);
+                        assert dy2 == img.getHeight(observer);
+                        AffineTransform renderTX = new AffineTransform(xform);
+                        renderTX.scale(1 / widthScale, 1 / heightScale);
+                        return transformImage(img, renderTX, observer);
+                    }
+
+                    return scaleImage(img, dx1, dy1, dx2, dy2,
+                                      sx1, sy1, sx2, sy2,
+                                      bgcolor, observer);
                 }
             }
         }
-
+        return null;
+    }
+
+    private boolean scaleImage(Image img, int dx1, int dy1, int dx2, int dy2,
+                               int sx1, int sy1, int sx2, int sy2,
+                               Color bgcolor, ImageObserver observer)
+    {
         try {
             return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1, sy1,
                                         sx2, sy2, bgcolor, observer);
@@ -3156,9 +3195,30 @@
         }
     }
 
+    private boolean transformImage(Image img,
+                                   AffineTransform xform,
+                                   ImageObserver observer)
+    {
+        try {
+            return imagepipe.transformImage(this, img, xform, observer);
+        } catch (InvalidPipeException e) {
+            try {
+                revalidateAll();
+                return imagepipe.transformImage(this, img, xform, observer);
+            } catch (InvalidPipeException e2) {
+                // Still catching the exception; we are not yet ready to
+                // validate the surfaceData correctly.  Fail for now and
+                // try again next time around.
+                return false;
+            }
+        } finally {
+            surfaceData.markDirty();
+        }
+    }
+
     private Image getResolutionVariant(MultiResolutionImage img,
             int srcWidth, int srcHeight, int dx1, int dy1, int dx2, int dy2,
-            int sx1, int sy1, int sx2, int sy2) {
+            int sx1, int sy1, int sx2, int sy2, AffineTransform xform) {
 
         if (srcWidth <= 0 || srcHeight <= 0) {
             return null;
@@ -3171,7 +3231,16 @@
             return null;
         }
 
-        int type = transform.getType();
+        AffineTransform tx;
+
+        if (xform == null) {
+            tx = transform;
+        } else {
+            tx = new AffineTransform(transform);
+            tx.concatenate(xform);
+        }
+
+        int type = tx.getType();
         int dw = dx2 - dx1;
         int dh = dy2 - dy1;
 
@@ -3198,13 +3267,13 @@
                 destRegionWidth = dw;
                 destRegionHeight = dh;
             } else if ((type & ~(TYPE_TRANSLATION | TYPE_FLIP | TYPE_MASK_SCALE)) == 0) {
-                destRegionWidth = dw * transform.getScaleX();
-                destRegionHeight = dh * transform.getScaleY();
+                destRegionWidth = dw * tx.getScaleX();
+                destRegionHeight = dh * tx.getScaleY();
             } else {
                 destRegionWidth = dw * Math.hypot(
-                        transform.getScaleX(), transform.getShearY());
+                        tx.getScaleX(), tx.getShearY());
                 destRegionHeight = dh * Math.hypot(
-                        transform.getShearX(), transform.getScaleY());
+                        tx.getShearX(), tx.getScaleY());
             }
             destImageWidth = Math.abs(srcWidth * destRegionWidth / sw);
             destImageHeight = Math.abs(srcHeight * destRegionHeight / sh);
@@ -3277,9 +3346,11 @@
 
         final int imgW = img.getWidth(null);
         final int imgH = img.getHeight(null);
-        if (isHiDPIImage(img)) {
-            return drawHiDPIImage(img, x, y, x + width, y + height, 0, 0, imgW,
-                                  imgH, bg, observer);
+        Boolean hidpiImageDrawn = drawHiDPIImage(img, x, y, x + width, y + height,
+                                                 0, 0, imgW, imgH, bg, observer,
+                                                 null);
+        if (hidpiImageDrawn != null) {
+            return hidpiImageDrawn;
         }
 
         if (width == imgW && height == imgH) {
@@ -3323,11 +3394,13 @@
             return true;
         }
 
-        if (isHiDPIImage(img)) {
-            final int imgW = img.getWidth(null);
-            final int imgH = img.getHeight(null);
-            return drawHiDPIImage(img, x, y, x + imgW, y + imgH, 0, 0, imgW,
-                                  imgH, bg, observer);
+        final int imgW = img.getWidth(null);
+        final int imgH = img.getHeight(null);
+        Boolean hidpiImageDrawn = drawHiDPIImage(img, x, y, x + imgW, y + imgH,
+                                                 0, 0, imgW, imgH, bg, observer,
+                                                 null);
+        if (hidpiImageDrawn != null) {
+            return hidpiImageDrawn;
         }
 
         try {
@@ -3378,9 +3451,12 @@
             return true;
         }
 
-        if (isHiDPIImage(img)) {
-            return drawHiDPIImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
-                                  bgcolor, observer);
+        Boolean hidpiImageDrawn = drawHiDPIImage(img, dx1, dy1, dx2, dy2,
+                                                 sx1, sy1, sx2, sy2,
+                                                 bgcolor, observer, null);
+
+        if (hidpiImageDrawn != null) {
+            return hidpiImageDrawn;
         }
 
         if (((sx2 - sx1) == (dx2 - dx1)) &&
@@ -3461,33 +3537,16 @@
             return drawImage(img, 0, 0, null, observer);
         }
 
-        if (isHiDPIImage(img)) {
-            final int w = img.getWidth(null);
-            final int h = img.getHeight(null);
-            final AffineTransform tx = new AffineTransform(transform);
-            transform(xform);
-            boolean result = drawHiDPIImage(img, 0, 0, w, h, 0, 0, w, h, null,
-                                            observer);
-            transform.setTransform(tx);
-            invalidateTransform();
-            return result;
+        final int w = img.getWidth(null);
+        final int h = img.getHeight(null);
+        Boolean hidpiImageDrawn = drawHiDPIImage(img, 0, 0, w, h, 0, 0, w, h,
+                                                 null, observer, xform);
+
+        if (hidpiImageDrawn != null) {
+            return hidpiImageDrawn;
         }
 
-        try {
-            return imagepipe.transformImage(this, img, xform, observer);
-        } catch (InvalidPipeException e) {
-            try {
-                revalidateAll();
-                return imagepipe.transformImage(this, img, xform, observer);
-            } catch (InvalidPipeException e2) {
-                // Still catching the exception; we are not yet ready to
-                // validate the surfaceData correctly.  Fail for now and
-                // try again next time around.
-                return false;
-            }
-        } finally {
-            surfaceData.markDirty();
-        }
+        return transformImage(img, xform, observer);
     }
 
     public void drawImage(BufferedImage bImg,
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java	Tue Nov 17 13:09:16 2015 -0800
@@ -66,6 +66,8 @@
 import sun.font.FontManagerFactory;
 import sun.font.FontManagerForSGE;
 import sun.font.NativeFont;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This is an implementation of a GraphicsEnvironment object for the
@@ -80,6 +82,15 @@
     public static boolean isOpenSolaris;
     private static Font defaultFont;
 
+    private static final boolean uiScaleEnabled;
+    private static final double debugScale;
+
+    static {
+        uiScaleEnabled = "true".equals(AccessController.doPrivileged(
+                new GetPropertyAction("sun.java2d.uiScale.enabled", "true")));
+        debugScale = uiScaleEnabled ? getScaleFactor("sun.java2d.uiScale") : -1;
+    }
+
     public SunGraphicsEnvironment() {
         java.security.AccessController.doPrivileged(
                                     new java.security.PrivilegedAction<Object>() {
@@ -341,4 +352,41 @@
     public boolean isFlipStrategyPreferred(ComponentPeer peer) {
         return false;
     }
+
+    public static boolean isUIScaleEnabled() {
+        return uiScaleEnabled;
+    }
+
+    public static double getDebugScale() {
+        return debugScale;
+    }
+
+    public static double getScaleFactor(String propertyName) {
+
+        String scaleFactor = AccessController.doPrivileged(
+                new GetPropertyAction(propertyName, "-1"));
+
+        if (scaleFactor == null || scaleFactor.equals("-1")) {
+            return -1;
+        }
+
+        try {
+            double units = 1.0;
+
+            if (scaleFactor.endsWith("x")) {
+                scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 1);
+            } else if (scaleFactor.endsWith("dpi")) {
+                units = 96;
+                scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 3);
+            } else if (scaleFactor.endsWith("%")) {
+                units = 100;
+                scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 1);
+            }
+
+            double scale = Double.parseDouble(scaleFactor);
+            return scale <= 0 ? -1 : scale / units;
+        } catch (NumberFormatException ignored) {
+            return -1;
+        }
+    }
 }
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SurfaceData.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SurfaceData.java	Tue Nov 17 13:09:16 2015 -0800
@@ -1059,12 +1059,22 @@
     public abstract Object getDestination();
 
     /**
-     * Returns default scale factor of the destination surface. Scale factor
-     * describes the mapping between virtual and physical coordinates of the
+     * Returns default horizontal scale factor of the destination surface. Scale
+     * factor describes the mapping between virtual and physical coordinates of the
      * SurfaceData. If the scale is 2 then virtual pixel coordinates need to be
      * doubled for physical pixels.
      */
-    public int getDefaultScale() {
+    public double getDefaultScaleX() {
+        return 1;
+    }
+
+    /**
+     * Returns default vertical scale factor of the destination surface. Scale
+     * factor describes the mapping between virtual and physical coordinates of the
+     * SurfaceData. If the scale is 2 then virtual pixel coordinates need to be
+     * doubled for physical pixels.
+     */
+    public double getDefaultScaleY() {
         return 1;
     }
 }
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java	Tue Nov 17 13:09:16 2015 -0800
@@ -736,9 +736,10 @@
         atfm.scale(m00, m11);
         atfm.translate(srcX-sx1, srcY-sy1);
 
-        final int scale = SurfaceManager.getImageScale(img);
-        final int imgW = img.getWidth(null) * scale;
-        final int imgH = img.getHeight(null) * scale;
+        final double scaleX = SurfaceManager.getImageScaleX(img);
+        final double scaleY = SurfaceManager.getImageScaleY(img);
+        final int imgW = (int) Math.ceil(img.getWidth(null) * scaleX);
+        final int imgH = (int) Math.ceil(img.getHeight(null) * scaleY);
         srcW += srcX;
         srcH += srcY;
         // Make sure we are not out of bounds
--- a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java	Tue Nov 17 13:09:16 2015 -0800
@@ -740,7 +740,19 @@
         }
         updatePageAttributes(service, page);
 
-        PageFormat newPage = pageDialog(attributes);
+        PageFormat newPage = null;
+        DialogTypeSelection dts =
+            (DialogTypeSelection)attributes.get(DialogTypeSelection.class);
+        if (dts == DialogTypeSelection.NATIVE) {
+            // Remove DialogTypeSelection.NATIVE to prevent infinite loop in
+            // RasterPrinterJob.
+            attributes.remove(DialogTypeSelection.class);
+            newPage = pageDialog(attributes);
+            // restore attribute
+            attributes.add(DialogTypeSelection.NATIVE);
+        } else {
+            newPage = pageDialog(attributes);
+        }
 
         if (newPage == null) {
             return page;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XChoicePeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedClientHelper.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbeddedFramePeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuBarPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuWindow.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWarningWindow.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XlibUtil.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsConfig.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c	Tue Nov 17 13:09:16 2015 -0800
@@ -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	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h	Tue Nov 17 13:09:16 2015 -0800
@@ -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);
--- a/jdk/src/java.desktop/windows/classes/sun/awt/Win32GraphicsConfig.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/Win32GraphicsConfig.java	Tue Nov 17 13:09:16 2015 -0800
@@ -106,7 +106,7 @@
     /**
      * Return the graphics device associated with this configuration.
      */
-    public GraphicsDevice getDevice() {
+    public Win32GraphicsDevice getDevice() {
         return screen;
     }
 
@@ -182,7 +182,9 @@
      * For image buffers, this Transform will be the Identity transform.
      */
     public AffineTransform getDefaultTransform() {
-        return new AffineTransform();
+        double scaleX = screen.getDefaultScaleX();
+        double scaleY = screen.getDefaultScaleY();
+        return AffineTransform.getScaleInstance(scaleX, scaleY);
     }
 
     /**
--- a/jdk/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java	Tue Nov 17 13:09:16 2015 -0800
@@ -37,13 +37,19 @@
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.awt.event.WindowListener;
+import java.awt.geom.Point2D;
 import java.awt.image.ColorModel;
 import java.util.ArrayList;
 import java.util.Vector;
 import java.awt.peer.WindowPeer;
+import java.security.AccessController;
 import sun.awt.windows.WWindowPeer;
+import sun.java2d.SunGraphicsEnvironment;
 import sun.java2d.opengl.WGLGraphicsConfig;
 import sun.java2d.windows.WindowsFlags;
+import sun.security.action.GetPropertyAction;
+import static sun.awt.Win32GraphicsEnvironment.debugScaleX;
+import static sun.awt.Win32GraphicsEnvironment.debugScaleY;
 
 /**
  * This is an implementation of a GraphicsDevice object for a single
@@ -81,6 +87,9 @@
     // activation/deactivation listener for the full-screen window
     private WindowListener fsWindowListener;
 
+    private float scaleX;
+    private float scaleY;
+
     static {
 
         // 4455041 - Even when ddraw is disabled, ddraw.dll is loaded when
@@ -97,6 +106,10 @@
     private static native void initIDs();
 
     native void initDevice(int screen);
+    native void initNativeScale(int screen);
+    native void setNativeScale(int screen, float scaleX, float scaleY);
+    native float getNativeScaleX(int screen);
+    native float getNativeScaleY(int screen);
 
     public Win32GraphicsDevice(int screennum) {
         this.screen = screennum;
@@ -109,6 +122,7 @@
         valid = true;
 
         initDevice(screennum);
+        initScaleFactors();
     }
 
     /**
@@ -128,6 +142,31 @@
         return screen;
     }
 
+    public float getDefaultScaleX() {
+        return scaleX;
+    }
+
+    public float getDefaultScaleY() {
+        return scaleY;
+    }
+
+    private void initScaleFactors() {
+        if (SunGraphicsEnvironment.isUIScaleEnabled()) {
+            if (debugScaleX > 0 && debugScaleY > 0) {
+                scaleX = debugScaleX;
+                scaleY = debugScaleY;
+                setNativeScale(screen, scaleX, scaleY);
+            } else {
+                initNativeScale(screen);
+                scaleX = getNativeScaleX(screen);
+                scaleY = getNativeScaleY(screen);
+            }
+        } else {
+            scaleX = 1;
+            scaleY = 1;
+        }
+    }
+
     /**
      * Returns whether this is a valid devicie. Device can become
      * invalid as a result of device removal event.
@@ -486,6 +525,7 @@
         configs = null;
         // pass on to all top-level windows on this display
         topLevels.notifyListeners();
+        initScaleFactors();
     }
 
     /**
--- a/jdk/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java	Tue Nov 17 13:09:16 2015 -0800
@@ -51,6 +51,9 @@
 
 public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
 
+    static final float debugScaleX;
+    static final float debugScaleY;
+
     static {
         // Ensure awt is loaded already.  Also, this forces static init
         // of WToolkit and Toolkit, which we depend upon
@@ -61,6 +64,21 @@
 
         // Install correct surface manager factory.
         SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
+
+        double sx = -1;
+        double sy = -1;
+        if (isUIScaleEnabled()) {
+            sx = getScaleFactor("sun.java2d.win.uiScaleX");
+            sy = getScaleFactor("sun.java2d.win.uiScaleY");
+            if (sx <= 0 || sy <= 0) {
+                double s = getDebugScale();
+                sx = s;
+                sy = s;
+            }
+        }
+
+        debugScaleX = (float) sx;
+        debugScaleY = (float) sy;
     }
 
     /**
--- a/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Tue Nov 17 13:09:16 2015 -0800
@@ -141,6 +141,9 @@
     public static final int SHGDN_FORADDRESSBAR     = 0x4000;
     public static final int SHGDN_FORPARSING        = 0x8000;
 
+    /** The referent to be registered with the Disposer. */
+    private Object disposerReferent = new Object();
+
     // Values for system call LoadIcon()
     public enum SystemIcon {
         IDI_APPLICATION(32512),
@@ -297,7 +300,7 @@
             }
         }, InterruptedException.class);
 
-        sun.java2d.Disposer.addRecord(this, disposer);
+        sun.java2d.Disposer.addObjectRecord(disposerReferent, disposer);
     }
 
 
@@ -309,7 +312,7 @@
         this.isLib = isLib;
         this.disposer.pIShellFolder = pIShellFolder;
         this.disposer.relativePIDL = relativePIDL;
-        sun.java2d.Disposer.addRecord(this, disposer);
+        sun.java2d.Disposer.addObjectRecord(disposerReferent, disposer);
     }
 
 
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java	Tue Nov 17 13:09:16 2015 -0800
@@ -294,6 +294,12 @@
 
     synchronized native void reshapeFrame(int x, int y, int width, int height);
 
+    native Dimension getNativeWindowSize();
+
+    public Dimension getScaledWindowSize() {
+        return getNativeWindowSize();
+    }
+
     public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
         if (!focusAllowedFor()) {
             return false;
@@ -490,8 +496,7 @@
         }
 
         // get current GD
-        Win32GraphicsDevice oldDev = (Win32GraphicsDevice)winGraphicsConfig
-                                     .getDevice();
+        Win32GraphicsDevice oldDev = winGraphicsConfig.getDevice();
 
         Win32GraphicsDevice newDev;
         GraphicsDevice devs[] = GraphicsEnvironment
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java	Tue Nov 17 13:09:16 2015 -0800
@@ -63,9 +63,12 @@
 import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*;
 import sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType;
 import java.awt.BufferCapabilities.FlipContents;
+import java.awt.Dimension;
 import java.awt.Window;
+import java.awt.geom.AffineTransform;
 import sun.awt.SunToolkit;
 import sun.awt.image.SunVolatileImage;
+import sun.awt.windows.WWindowPeer;
 import sun.java2d.ScreenUpdateManager;
 import sun.java2d.StateTracker;
 import sun.java2d.SurfaceDataProxy;
@@ -162,6 +165,8 @@
 
     private int type;
     private int width, height;
+    private final double scaleX;
+    private final double scaleY;
     // these fields are set from the native code when the surface is
     // initialized
     private int nativeWidth, nativeHeight;
@@ -218,16 +223,29 @@
     {
         super(getCustomSurfaceType(type), cm);
         this.graphicsDevice = gc.getD3DDevice();
+        this.scaleX = type == TEXTURE ? 1 : graphicsDevice.getDefaultScaleX();
+        this.scaleY = type == TEXTURE ? 1 : graphicsDevice.getDefaultScaleY();
         this.peer = peer;
         this.type = type;
-        this.width = width;
-        this.height = height;
+
+        if (scaleX == 1 && scaleY == 1) {
+            this.width = width;
+            this.height = height;
+        } else if (peer instanceof WWindowPeer) {
+            Dimension scaledSize = ((WWindowPeer) peer).getScaledWindowSize();
+            this.width = scaledSize.width;
+            this.height = scaledSize.height;
+        } else {
+            this.width = (int) Math.ceil(width * scaleX);
+            this.height = (int) Math.ceil(height * scaleY);
+        }
+
         this.offscreenImage = image;
         this.backBuffersNum = numBackBuffers;
         this.swapEffect = swapEffect;
         this.syncType = vSyncType;
 
-        initOps(graphicsDevice.getScreen(), width, height);
+        initOps(graphicsDevice.getScreen(), this.width, this.height);
         if (type == WINDOW) {
             // we put the surface into the "lost"
             // state; it will be restored by the D3DScreenUpdateManager
@@ -241,6 +259,16 @@
     }
 
     @Override
+    public double getDefaultScaleX() {
+        return scaleX;
+    }
+
+    @Override
+    public double getDefaultScaleY() {
+        return scaleY;
+    }
+
+    @Override
     public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
         return D3DSurfaceDataProxy.
             createProxy(srcData,
@@ -777,8 +805,12 @@
 
     public Rectangle getBounds() {
         if (type == FLIP_BACKBUFFER || type == WINDOW) {
+            double scaleX = getDefaultScaleX();
+            double scaleY = getDefaultScaleY();
             Rectangle r = peer.getBounds();
             r.x = r.y = 0;
+            r.width = (int) Math.ceil(r.width * scaleX);
+            r.height = (int) Math.ceil(r.height * scaleY);
             return r;
         } else {
             return new Rectangle(width, height);
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/opengl/WGLSurfaceData.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/opengl/WGLSurfaceData.java	Tue Nov 17 13:09:16 2015 -0800
@@ -31,8 +31,10 @@
 import java.awt.GraphicsEnvironment;
 import java.awt.Image;
 import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
 import java.awt.image.ColorModel;
 import sun.awt.SunToolkit;
+import sun.awt.Win32GraphicsDevice;
 import sun.awt.windows.WComponentPeer;
 import sun.java2d.SurfaceData;
 
@@ -40,6 +42,8 @@
 
     protected WComponentPeer peer;
     private WGLGraphicsConfig graphicsConfig;
+    protected double scaleX = 1;
+    protected double scaleY = 1;
 
     private native void initOps(long pConfigInfo, WComponentPeer peer,
                                 long hwnd);
@@ -50,6 +54,9 @@
         super(gc, cm, type);
         this.peer = peer;
         this.graphicsConfig = gc;
+        Win32GraphicsDevice device = gc.getDevice();
+        this.scaleX = type == TEXTURE ? 1 : device.getDefaultScaleX();
+        this.scaleY = type == TEXTURE ? 1 : device.getDefaultScaleY();
 
         long pConfigInfo = gc.getNativeConfigInfo();
         long hwnd = peer != null ? peer.getHWnd() : 0L;
@@ -57,6 +64,16 @@
         initOps(pConfigInfo, peer, hwnd);
     }
 
+    @Override
+    public double getDefaultScaleX() {
+        return scaleX;
+    }
+
+    @Override
+    public double getDefaultScaleY() {
+        return scaleY;
+    }
+
     public GraphicsConfiguration getDeviceConfiguration() {
         return graphicsConfig;
     }
@@ -148,6 +165,8 @@
         public Rectangle getBounds() {
             Rectangle r = peer.getBounds();
             r.x = r.y = 0;
+            r.width = (int) Math.ceil(r.width * scaleX);
+            r.height = (int) Math.ceil(r.height * scaleY);
             return r;
         }
 
@@ -208,11 +227,11 @@
         {
             super(peer, gc, cm, type);
 
-            this.width = width;
-            this.height = height;
+            this.width = (int) Math.ceil(width * scaleX);
+            this.height = (int) Math.ceil(height * scaleY);
             offscreenImage = image;
 
-            initSurface(width, height);
+            initSurface(this.width, this.height);
         }
 
         public SurfaceData getReplacement() {
@@ -222,6 +241,8 @@
         public Rectangle getBounds() {
             if (type == FLIP_BACKBUFFER) {
                 Rectangle r = peer.getBounds();
+                r.width = (int) Math.ceil(r.width * scaleX);
+                r.height = (int) Math.ceil(r.height * scaleY);
                 r.x = r.y = 0;
                 return r;
             } else {
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java	Tue Nov 17 13:09:16 2015 -0800
@@ -28,6 +28,7 @@
 import java.awt.Rectangle;
 import java.awt.GraphicsConfiguration;
 import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
 import java.awt.image.ColorModel;
 import java.awt.image.ComponentColorModel;
 import java.awt.image.DirectColorModel;
@@ -77,6 +78,9 @@
 
     private static native void initIDs(Class<?> xorComp);
 
+    private final double scaleX;
+    private final double scaleY;
+
     static {
         initIDs(XORComposite.class);
         if (WindowsFlags.isGdiBlitEnabled()) {
@@ -265,13 +269,23 @@
         this.graphicsConfig =
             (Win32GraphicsConfig) peer.getGraphicsConfiguration();
         this.solidloops = graphicsConfig.getSolidLoops(sType);
-
-        Win32GraphicsDevice gd =
-            (Win32GraphicsDevice)graphicsConfig.getDevice();
+        Win32GraphicsDevice gd = graphicsConfig.getDevice();
+        scaleX = gd.getDefaultScaleX();
+        scaleY = gd.getDefaultScaleY();
         initOps(peer, depth, rMask, gMask, bMask, gd.getScreen());
         setBlitProxyKey(graphicsConfig.getProxyKey());
     }
 
+    @Override
+    public double getDefaultScaleX() {
+        return scaleX;
+    }
+
+    @Override
+    public double getDefaultScaleY() {
+        return scaleY;
+    }
+
     /**
      * {@inheritDoc}
      *
@@ -288,6 +302,8 @@
     public Rectangle getBounds() {
         Rectangle r = peer.getBounds();
         r.x = r.y = 0;
+        r.width = (int) Math.ceil(r.width * scaleX);
+        r.height = (int) Math.ceil(r.height * scaleY);
         return r;
     }
 
--- a/jdk/src/java.desktop/windows/native/libawt/windows/MouseInfo.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/MouseInfo.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -94,12 +94,21 @@
         pointClass = (jclass)env->NewGlobalRef(pointClassLocal);
         env->DeleteLocalRef(pointClassLocal);
     }
+
+    int screen = AwtWin32GraphicsDevice::GetDefaultDeviceIndex();
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
+
     xID = env->GetFieldID(pointClass, "x", "I");
     CHECK_NULL_RETURN(xID, (jint)0);
     yID = env->GetFieldID(pointClass, "y", "I");
     CHECK_NULL_RETURN(yID, (jint)0);
-    env->SetIntField(point, xID, pt.x);
-    env->SetIntField(point, yID, pt.y);
+
+    int x = (device == NULL) ? pt.x : device->ScaleDownX(pt.x);
+    int y = (device == NULL) ? pt.y : device->ScaleDownY(pt.y);
+
+    env->SetIntField(point, xID, x);
+    env->SetIntField(point, yID, y);
 
     // Always return 0 on Windows: we assume there's always a
     // virtual screen device used.
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Choice.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Choice.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -206,9 +206,10 @@
     int itemHeight =(int)::SendMessage(GetHWnd(), CB_GETITEMHEIGHT, (UINT)0,0);
     int numItemsToShow = (int)::SendMessage(GetHWnd(), CB_GETCOUNT, 0,0);
     numItemsToShow = min(MINIMUM_NUMBER_OF_VISIBLE_ITEMS, numItemsToShow);
+
     // drop-down height snaps to nearest line, so add a
     // fudge factor of 1/2 line to ensure last line shows
-    return itemHeight*numItemsToShow + itemHeight/2;
+    return ScaleDownY(itemHeight * numItemsToShow + itemHeight / 2);
 }
 
 // get the height of the field portion of the combobox
@@ -221,7 +222,7 @@
     // Win 4.x (3d edge) vs 3.x (1 pixel line)
     borderHeight = ::GetSystemMetrics(SM_CYEDGE);
     fieldHeight += borderHeight*2;
-    return fieldHeight;
+    return ScaleDownY(fieldHeight);
 }
 
 // gets the total height of the combobox, including drop down
@@ -325,8 +326,8 @@
      * Fix: Set the Choice to its actual size in the component.
      */
     ::GetClientRect(GetHWnd(), &rc);
-    env->SetIntField(target, AwtComponent::widthID,  (jint)rc.right);
-    env->SetIntField(target, AwtComponent::heightID, (jint)rc.bottom);
+    env->SetIntField(target, AwtComponent::widthID, ScaleDownX(rc.right));
+    env->SetIntField(target, AwtComponent::heightID, ScaleDownY(rc.bottom));
 
     env->DeleteLocalRef(target);
     env->DeleteLocalRef(parent);
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -963,6 +963,12 @@
     ::MapWindowPoints(HWND_DESKTOP, ::GetParent(GetHWnd()), (LPPOINT)&rc, 2);
     DTRACE_PRINTLN4("AwtComponent::Reshape from %d, %d, %d, %d", rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
 #endif
+
+    x = ScaleUpX(x);
+    y = ScaleUpY(y);
+    w = ScaleUpX(w);
+    h = ScaleUpY(h);
+
     AwtWindow* container = GetContainer();
     AwtComponent* parent = GetParent();
     if (container != NULL && container == parent) {
@@ -2212,8 +2218,11 @@
         }
         for(i = 0; i < 2; i++) {
             if (un[i] != 0) {
-                DoCallback("handleExpose", "(IIII)V", un[i]->left, un[i]->top,
-                    un[i]->right-un[i]->left, un[i]->bottom-un[i]->top);
+                DoCallback("handleExpose", "(IIII)V",
+                           ScaleDownX(un[i]->left),
+                           ScaleDownY(un[i]->top),
+                           ScaleDownX(un[i]->right - un[i]->left),
+                           ScaleDownY(un[i]->bottom - un[i]->top));
             }
         }
         delete [] buffer;
@@ -4608,6 +4617,34 @@
     }
 }
 
+int AwtComponent::ScaleUpX(int x) {
+    int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
+    return device == NULL ? x : device->ScaleUpX(x);
+}
+
+int AwtComponent::ScaleUpY(int y) {
+    int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
+    return device == NULL ? y : device->ScaleUpY(y);
+}
+
+int AwtComponent::ScaleDownX(int x) {
+    int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
+    return device == NULL ? x : device->ScaleDownX(x);
+}
+
+int AwtComponent::ScaleDownY(int y) {
+    int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
+    return device == NULL ? y : device->ScaleDownY(y);
+}
+
 jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) {
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
@@ -4901,8 +4938,9 @@
     jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst,
                                         target,
                                         id, when, modifiers,
-                                        x+insets.left, y+insets.top,
-                                        xAbs, yAbs,
+                                        ScaleDownX(x + insets.left),
+                                        ScaleDownY(y + insets.top),
+                                        ScaleDownX(xAbs), ScaleDownY(yAbs),
                                         clickCount, popupTrigger, button);
 
     if (safe_ExceptionOccurred(env)) {
@@ -4969,8 +5007,10 @@
                                              mouseWheelEventConst,
                                              target,
                                              id, when, modifiers,
-                                             x+insets.left, y+insets.top,
-                                             xAbs, yAbs,
+                                             ScaleDownX(x + insets.left),
+                                             ScaleDownY(y + insets.top),
+                                             ScaleDownX(xAbs),
+                                             ScaleDownY(yAbs),
                                              clickCount, popupTrigger,
                                              scrollType, scrollAmount,
                                              roundedWheelRotation, preciseWheelRotation);
@@ -5476,7 +5516,8 @@
         RECT rect;
         VERIFY(::GetWindowRect(p->GetHWnd(),&rect));
         result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V",
-            rect.left, rect.top);
+                                     p->ScaleDownX(rect.left),
+                                     p->ScaleDownY(rect.top));
     }
 ret:
     env->DeleteGlobalRef(self);
@@ -7064,6 +7105,11 @@
         target = parent;
     }
 
+    x = ScaleUpX(x);
+    y = ScaleUpY(y);
+    width = ScaleUpX(width);
+    height = ScaleUpY(height);
+
     // Test whether component's bounds match the native window's
     RECT rect;
     VERIFY(::GetWindowRect(GetHWnd(), &rect));
@@ -7256,5 +7302,4 @@
         removedDCs = removedDCs->next;
         delete tmpDCList;
     }
-}
-
+}
\ No newline at end of file
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Tue Nov 17 13:09:16 2015 -0800
@@ -746,6 +746,11 @@
     virtual void FillBackground(HDC hMemoryDC, SIZE &size);
     virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
 
+    int ScaleUpX(int x);
+    int ScaleUpY(int y);
+    int ScaleDownX(int x);
+    int ScaleDownY(int y);
+
 private:
     /* A bitmask keeps the button's numbers as MK_LBUTTON, MK_MBUTTON, MK_RBUTTON
      * which are allowed to
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -398,6 +398,38 @@
 
 }
 
+static int ScaleUpX(float x) {
+    int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
+        ::GetDesktopWindow());
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
+    return device == NULL ? x : device->ScaleUpX(x);
+}
+
+static int ScaleUpY(int y) {
+    int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
+        ::GetDesktopWindow());
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
+    return device == NULL ? y : device->ScaleUpY(y);
+}
+
+static int ScaleDownX(int x) {
+    int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
+        ::GetDesktopWindow());
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
+    return device == NULL ? x : device->ScaleDownX(x);
+}
+
+static int ScaleDownY(int y) {
+    int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
+        ::GetDesktopWindow());
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
+    return device == NULL ? y : device->ScaleDownY(y);
+}
+
 static HFONT CreateHFont_sub(LPCWSTR name, int style, int height,
                              int angle=0, float awScale=1.0f)
 {
@@ -424,7 +456,7 @@
     logFont.lfUnderline = 0;//(style & java_awt_Font_UNDERLINE) != 0;
 
     // Get point size
-    logFont.lfHeight = -height;
+    logFont.lfHeight = ScaleUpY(-height);
 
     // Set font name
     WCHAR tmpname[80];
@@ -451,7 +483,7 @@
             VERIFY(::DeleteObject(oldFont));
         }
         avgWidth = tm.tmAveCharWidth;
-        logFont.lfWidth = (LONG)((fabs)(avgWidth*awScale));
+        logFont.lfWidth = (LONG) ScaleUpX((fabs) (avgWidth * awScale));
         hFont = ::CreateFontIndirect(&logFont);
         DASSERT(hFont != NULL);
         VERIFY(::ReleaseDC(0, hDC));
@@ -535,19 +567,20 @@
     int ascent = metrics.tmAscent;
     int descent = metrics.tmDescent;
     int leading = metrics.tmExternalLeading;
-    env->SetIntField(fontMetrics, AwtFont::ascentID, ascent);
-    env->SetIntField(fontMetrics, AwtFont::descentID, descent);
-    env->SetIntField(fontMetrics, AwtFont::leadingID, leading);
-    env->SetIntField(fontMetrics, AwtFont::heightID, metrics.tmAscent +
-                     metrics.tmDescent + leading);
-    env->SetIntField(fontMetrics, AwtFont::maxAscentID, ascent);
-    env->SetIntField(fontMetrics, AwtFont::maxDescentID, descent);
+
+    env->SetIntField(fontMetrics, AwtFont::ascentID, ScaleDownY(ascent));
+    env->SetIntField(fontMetrics, AwtFont::descentID, ScaleDownY(descent));
+    env->SetIntField(fontMetrics, AwtFont::leadingID, ScaleDownX(leading));
+    env->SetIntField(fontMetrics, AwtFont::heightID,
+        ScaleDownY(metrics.tmAscent + metrics.tmDescent + leading));
+    env->SetIntField(fontMetrics, AwtFont::maxAscentID, ScaleDownY(ascent));
+    env->SetIntField(fontMetrics, AwtFont::maxDescentID, ScaleDownY(descent));
 
     int maxHeight =  ascent + descent + leading;
-    env->SetIntField(fontMetrics, AwtFont::maxHeightID, maxHeight);
+    env->SetIntField(fontMetrics, AwtFont::maxHeightID, ScaleDownY(maxHeight));
 
     int maxAdvance = metrics.tmMaxCharWidth;
-    env->SetIntField(fontMetrics, AwtFont::maxAdvanceID, maxAdvance);
+    env->SetIntField(fontMetrics, AwtFont::maxAdvanceID, ScaleDownX(maxAdvance));
 
     awtFont->m_overhang = metrics.tmOverhang;
 
@@ -818,6 +851,7 @@
     jobject font = env->GetObjectField(self, AwtFont::fontID);
 
     long ret = AwtFont::getMFStringWidth(hDC, font, str);
+    ret = ScaleDownX(ret);
     VERIFY(::ReleaseDC(0, hDC));
     return ret;
 
@@ -924,7 +958,7 @@
     }
 
     env->ReleasePrimitiveArrayCritical(str, pStrBody, 0);
-    return result;
+    return ScaleDownX(result);
 
     CATCH_BAD_ALLOC_RET(0);
 }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -80,6 +80,13 @@
                                      (PVOID)newSpeed,
                                      SPIF_SENDCHANGE);
 
+      int primaryIndex = AwtWin32GraphicsDevice::GetDefaultDeviceIndex();
+      Devices::InstanceAccess devices;
+      AwtWin32GraphicsDevice *device = devices->GetDevice(primaryIndex);
+
+      x = (device == NULL) ? x : device->ScaleUpX(x);
+      y = (device == NULL) ? y : device->ScaleUpY(y);
+
       POINT curPos;
       ::GetCursorPos(&curPos);
       x -= curPos.x;
@@ -217,11 +224,24 @@
         AwtWin32GraphicsDevice::SelectPalette(hdcMem, primaryIndex);
     AwtWin32GraphicsDevice::RealizePalette(hdcMem, primaryIndex);
 
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(primaryIndex);
+    int sWidth = (device == NULL) ? width : device->ScaleUpX(width);
+    int sHeight = (device == NULL) ? height : device->ScaleUpY(height);
+
     // copy screen image to offscreen bitmap
     // CAPTUREBLT flag is required to capture WS_EX_LAYERED windows' contents
     // correctly on Win2K/XP
-    VERIFY(::BitBlt(hdcMem, 0, 0, width, height, hdcScreen, x, y,
-                                                SRCCOPY|CAPTUREBLT) != 0);
+    if (width == sWidth && height == sHeight) {
+        VERIFY(::BitBlt(hdcMem, 0, 0, width, height, hdcScreen, x, y,
+               SRCCOPY | CAPTUREBLT) != 0);
+    } else {
+        int sX = (device == NULL) ? x : device->ScaleUpX(x);
+        int sY = (device == NULL) ? y : device->ScaleUpY(y);
+        VERIFY(::StretchBlt(hdcMem, 0, 0, width, height,
+               hdcScreen, sX, sY, sWidth, sHeight,
+               SRCCOPY | CAPTUREBLT) != 0);
+    }
 
     static const int BITS_PER_PIXEL = 32;
     static const int BYTES_PER_PIXEL = BITS_PER_PIXEL/8;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -2355,8 +2355,13 @@
 {
     TRY;
 
-    return ::GetSystemMetrics(SM_CXSCREEN);
-
+    int width = ::GetSystemMetrics(SM_CXSCREEN);
+
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(
+                        AwtWin32GraphicsDevice::GetDefaultDeviceIndex());
+
+    return (device == NULL) ? width : device->ScaleDownX(width);
     CATCH_BAD_ALLOC_RET(0);
 }
 
@@ -2370,7 +2375,12 @@
 {
     TRY;
 
-    return ::GetSystemMetrics(SM_CYSCREEN);
+    int height = ::GetSystemMetrics(SM_CYSCREEN);
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(
+                        AwtWin32GraphicsDevice::GetDefaultDeviceIndex());
+
+    return (device == NULL) ? height : device->ScaleDownY(height);
 
     CATCH_BAD_ALLOC_RET(0);
 }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -95,19 +95,31 @@
     mid = env->GetMethodID(clazz, "<init>", "(IIII)V");
     if (mid != 0) {
         RECT rRW = {0, 0, 0, 0};
+        Devices::InstanceAccess devices;
+        AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
+
         if (TRUE == MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen), &rRW)) {
-            bounds = env->NewObject(clazz, mid,
-                                    rRW.left, rRW.top,
-                                    rRW.right - rRW.left,
-                                    rRW.bottom - rRW.top);
+
+            int x = (device == NULL) ? rRW.left : device->ScaleDownX(rRW.left);
+            int y = (device == NULL) ? rRW.top  : device->ScaleDownY(rRW.top);
+            int w = (device == NULL) ? rRW.right - rRW.left
+                                     : device->ScaleDownX(rRW.right - rRW.left);
+            int h = (device == NULL) ? rRW.bottom - rRW.top
+                                     : device->ScaleDownY(rRW.bottom - rRW.top);
+
+            bounds = env->NewObject(clazz, mid, x, y, w, h);
+
         }
         else {
             // 4910760 - don't return a null bounds, return the bounds of the
             // primary screen
+            int w = ::GetSystemMetrics(SM_CXSCREEN);
+            int h = ::GetSystemMetrics(SM_CYSCREEN);
+
             bounds = env->NewObject(clazz, mid,
                                     0, 0,
-                                    ::GetSystemMetrics(SM_CXSCREEN),
-                                    ::GetSystemMetrics(SM_CYSCREEN));
+                                    device == NULL ? w : device->ScaleDownX(w),
+                                    device == NULL ? h : device->ScaleDownY(h));
         }
         if (safe_ExceptionOccurred(env)) {
            return 0;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -49,6 +49,12 @@
 #include "dither.h"
 #include "img_util_md.h"
 #include "Devices.h"
+#include <d2d1.h>
+#pragma comment(lib, "d2d1")
+
+#ifndef MDT_Effective_DPI
+#define MDT_Effective_DPI 0
+#endif
 
 uns_ordered_dither_array img_oda_alpha;
 
@@ -74,6 +80,8 @@
 {
     this->screen  = screen;
     this->devicesArray = arr;
+    this->scaleX = 1;
+    this->scaleY = 1;
     javaDevice = NULL;
     colorData = new ImgColorData;
     colorData->grayscale = GS_NOTGRAY;
@@ -617,6 +625,104 @@
 }
 
 /**
+ * Sets horizontal and vertical scale factors
+ */
+void AwtWin32GraphicsDevice::SetScale(float sx, float sy)
+{
+    scaleX = sx;
+    scaleY = sy;
+}
+
+int AwtWin32GraphicsDevice::ScaleUpX(int x)
+{
+    return (int)ceil(x * scaleX);
+}
+
+int AwtWin32GraphicsDevice::ScaleUpY(int y)
+{
+    return (int)ceil(y * scaleY);
+}
+
+int AwtWin32GraphicsDevice::ScaleDownX(int x)
+{
+    return (int)ceil(x / scaleX);
+}
+
+int AwtWin32GraphicsDevice::ScaleDownY(int y)
+{
+    return (int)ceil(y / scaleY);
+}
+
+void AwtWin32GraphicsDevice::InitDesktopScales()
+{
+    unsigned x = 0;
+    unsigned y = 0;
+    float dpiX = -1.0f;
+    float dpiY = -1.0f;
+
+    // for debug purposes
+    static float scale = -2.0f;
+    if (scale == -2) {
+        scale = -1;
+        char *uiScale = getenv("J2D_UISCALE");
+        if (uiScale != NULL) {
+            scale = (float)strtod(uiScale, NULL);
+            if (errno == ERANGE || scale <= 0) {
+                scale = -1;
+            }
+        }
+    }
+
+    if (scale > 0) {
+        SetScale(scale, scale);
+        return;
+    }
+
+    typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*);
+    static HMODULE hLibSHCoreDll = NULL;
+    static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL;
+
+    if (hLibSHCoreDll == NULL) {
+        hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll");
+        if (hLibSHCoreDll != NULL) {
+            lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress(
+                hLibSHCoreDll, "GetDpiForMonitor");
+        }
+    }
+
+    if (lpGetDpiForMonitor != NULL) {
+        HRESULT hResult = lpGetDpiForMonitor(GetMonitor(),
+                                             MDT_Effective_DPI, &x, &y);
+        if (hResult == S_OK) {
+            dpiX = static_cast<float>(x);
+            dpiY = static_cast<float>(y);
+        }
+    } else {
+        ID2D1Factory* m_pDirect2dFactory;
+        HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
+                                        &m_pDirect2dFactory);
+        if (res == S_OK) {
+            m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
+            m_pDirect2dFactory->Release();
+        }
+    }
+
+    if (dpiX > 0 && dpiY > 0) {
+        SetScale(dpiX / 96, dpiY / 96);
+    }
+}
+
+float AwtWin32GraphicsDevice::GetScaleX()
+{
+    return scaleX;
+}
+
+float AwtWin32GraphicsDevice::GetScaleY()
+{
+    return scaleY;
+}
+
+/**
  * Disables offscreen acceleration for this device.  This
  * sets a flag in the java object that is used to determine
  * whether offscreen surfaces can be created on the device.
@@ -1304,3 +1410,65 @@
     Devices::InstanceAccess devices;
     devices->GetDevice(screen)->SetJavaDevice(env, thisPtr);
 }
+
+/*
+ * Class:     sun_awt_Win32GraphicsDevice
+ * Method:    setNativeScale
+ * Signature: (I,F,F)V
+ */
+JNIEXPORT void JNICALL
+    Java_sun_awt_Win32GraphicsDevice_setNativeScale
+    (JNIEnv *env, jobject thisPtr, jint screen, jfloat scaleX, jfloat scaleY)
+{
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
+
+    if (device != NULL ) {
+        device->SetScale(scaleX, scaleY);
+    }
+}
+
+/*
+ * Class:     sun_awt_Win32GraphicsDevice
+ * Method:    getNativeScaleX
+ * Signature: (I)F
+ */
+JNIEXPORT jfloat JNICALL
+    Java_sun_awt_Win32GraphicsDevice_getNativeScaleX
+    (JNIEnv *env, jobject thisPtr, jint screen)
+{
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
+    return (device == NULL) ? 1 : device->GetScaleX();
+}
+
+/*
+ * Class:     sun_awt_Win32GraphicsDevice
+ * Method:    getNativeScaleY
+ * Signature: (I)F
+ */
+JNIEXPORT jfloat JNICALL
+    Java_sun_awt_Win32GraphicsDevice_getNativeScaleY
+    (JNIEnv *env, jobject thisPtr, jint screen)
+{
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
+    return (device == NULL) ? 1 : device->GetScaleY();
+}
+
+/*
+* Class:     sun_awt_Win32GraphicsDevice
+* Method:    initNativeScale
+* Signature: (I)V;
+*/
+JNIEXPORT void JNICALL
+Java_sun_awt_Win32GraphicsDevice_initNativeScale
+(JNIEnv *env, jobject thisPtr, jint screen)
+{
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
+
+    if (device != NULL) {
+        device->InitDesktopScales();
+    }
+}
\ No newline at end of file
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h	Tue Nov 17 13:09:16 2015 -0800
@@ -66,6 +66,14 @@
     void                    Release();
     void                    DisableOffscreenAcceleration();
     void                    Invalidate(JNIEnv *env);
+    void                    InitDesktopScales();
+    void                    SetScale(float scaleX, float scaleY);
+    float                   GetScaleX();
+    float                   GetScaleY();
+    int                     ScaleUpX(int x);
+    int                     ScaleUpY(int y);
+    int                     ScaleDownX(int x);
+    int                     ScaleDownY(int y);
 
     static int              DeviceIndexForWindow(HWND hWnd);
     static jobject          GetColorModel(JNIEnv *env, jboolean dynamic,
@@ -107,6 +115,8 @@
     LPMONITORINFO           pMonitorInfo;
     jobject                 javaDevice;
     Devices                 *devicesArray;
+    float                   scaleX;
+    float                   scaleY;
 
     static HDC              MakeDCFromMonitor(HMONITOR);
 };
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp	Tue Nov 17 13:09:16 2015 -0800
@@ -1407,19 +1407,19 @@
     /* Get insets into our peer directly */
     jobject peerInsets = (env)->GetObjectField(peer, AwtPanel::insets_ID);
     DASSERT(!safe_ExceptionOccurred(env));
+
     if (peerInsets != NULL) { // may have been called during creation
-        (env)->SetIntField(peerInsets, AwtInsets::topID, m_insets.top);
-        (env)->SetIntField(peerInsets, AwtInsets::bottomID,
-                           m_insets.bottom);
-        (env)->SetIntField(peerInsets, AwtInsets::leftID, m_insets.left);
-        (env)->SetIntField(peerInsets, AwtInsets::rightID, m_insets.right);
+        (env)->SetIntField(peerInsets, AwtInsets::topID, ScaleDownY(m_insets.top));
+        (env)->SetIntField(peerInsets, AwtInsets::bottomID, ScaleDownY(m_insets.bottom));
+        (env)->SetIntField(peerInsets, AwtInsets::leftID, ScaleDownX(m_insets.left));
+        (env)->SetIntField(peerInsets, AwtInsets::rightID, ScaleDownX(m_insets.right));
     }
     /* Get insets into the Inset object (if any) that was passed */
     if (insets != NULL) {
-        (env)->SetIntField(insets, AwtInsets::topID, m_insets.top);
-        (env)->SetIntField(insets, AwtInsets::bottomID, m_insets.bottom);
-        (env)->SetIntField(insets, AwtInsets::leftID, m_insets.left);
-        (env)->SetIntField(insets, AwtInsets::rightID, m_insets.right);
+        (env)->SetIntField(insets, AwtInsets::topID, ScaleDownY(m_insets.top));
+        (env)->SetIntField(insets, AwtInsets::bottomID, ScaleDownY(m_insets.bottom));
+        (env)->SetIntField(insets, AwtInsets::leftID, ScaleDownX(m_insets.left));
+        (env)->SetIntField(insets, AwtInsets::rightID, ScaleDownX(m_insets.right));
     }
     env->DeleteLocalRef(peerInsets);
 
@@ -1735,10 +1735,10 @@
     RECT rect;
     ::GetWindowRect(GetHWnd(), &rect);
 
-    (env)->SetIntField(target, AwtComponent::xID, rect.left);
-    (env)->SetIntField(target, AwtComponent::yID, rect.top);
-    (env)->SetIntField(peer, AwtWindow::sysXID, rect.left);
-    (env)->SetIntField(peer, AwtWindow::sysYID, rect.top);
+    (env)->SetIntField(target, AwtComponent::xID, ScaleDownX(rect.left));
+    (env)->SetIntField(target, AwtComponent::yID, ScaleDownY(rect.top));
+    (env)->SetIntField(peer, AwtWindow::sysXID, ScaleDownX(rect.left));
+    (env)->SetIntField(peer, AwtWindow::sysYID, ScaleDownY(rect.top));
     SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
 
     env->DeleteLocalRef(target);
@@ -1803,12 +1803,12 @@
     int newWidth = w + m_insets.left + m_insets.right;
     int newHeight = h + m_insets.top + m_insets.bottom;
 
-    (env)->SetIntField(target, AwtComponent::widthID, newWidth);
-    (env)->SetIntField(target, AwtComponent::heightID, newHeight);
+    (env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(newWidth));
+    (env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(newHeight));
 
     jobject peer = GetPeer(env);
-    (env)->SetIntField(peer, AwtWindow::sysWID, newWidth);
-    (env)->SetIntField(peer, AwtWindow::sysHID, newHeight);
+    (env)->SetIntField(peer, AwtWindow::sysWID, ScaleDownX(newWidth));
+    (env)->SetIntField(peer, AwtWindow::sysHID, ScaleDownY(newHeight));
 
     if (!AwtWindow::IsResizing()) {
         WindowResized();
@@ -3072,6 +3072,25 @@
     delete data;
 }
 
+void AwtWindow::_GetNativeWindowSize(void* param) {
+
+    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+    SizeStruct *ss = (SizeStruct *)param;
+    jobject self = ss->window;
+    AwtWindow *window = NULL;
+    PDATA pData;
+    JNI_CHECK_PEER_RETURN(self);
+    window = (AwtWindow *)pData;
+
+    RECT rc;
+    ::GetWindowRect(window->GetHWnd(), &rc);
+    ss->w = rc.right - rc.left;
+    ss->h = rc.bottom - rc.top;
+
+    env->DeleteGlobalRef(self);
+}
+
 extern "C" {
 
 /*
@@ -3303,6 +3322,46 @@
 
 /*
  * Class:     sun_awt_windows_WWindowPeer
+* Method:    getNativeWindowSize
+* Signature: ()Ljava/awt/Dimension;
+*/
+JNIEXPORT jobject JNICALL Java_sun_awt_windows_WWindowPeer_getNativeWindowSize
+(JNIEnv *env, jobject self) {
+
+    jobject res = NULL;
+    TRY;
+    SizeStruct *ss = new SizeStruct;
+    ss->window = env->NewGlobalRef(self);
+
+    AwtToolkit::GetInstance().SyncCall(AwtWindow::_GetNativeWindowSize, ss);
+
+    int w = ss->w;
+    int h = ss->h;
+
+    delete ss;
+    // global ref is deleted in _GetNativeWindowSize()
+
+    static jmethodID dimMID = NULL;
+    static jclass dimClassID = NULL;
+    if (dimClassID == NULL) {
+        jclass dimClassIDLocal = env->FindClass("java/awt/Dimension");
+        CHECK_NULL_RETURN(dimClassIDLocal, NULL);
+        dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal);
+        env->DeleteLocalRef(dimClassIDLocal);
+    }
+
+    if (dimMID == NULL) {
+        dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
+        CHECK_NULL_RETURN(dimMID, NULL);
+    }
+
+    return env->NewObject(dimClassID, dimMID, w, h);
+
+    CATCH_BAD_ALLOC_RET(NULL);
+}
+
+/*
+ * Class:     sun_awt_windows_WWindowPeer
  * Method:    getSysMinWidth
  * Signature: ()I
  */
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.h	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.h	Tue Nov 17 13:09:16 2015 -0800
@@ -241,6 +241,7 @@
     static void _UpdateWindow(void* param);
     static void _RepositionSecurityWarning(void* param);
     static void _SetFullScreenExclusiveModeState(void* param);
+    static void _GetNativeWindowSize(void* param);
 
     inline static BOOL IsResizing() {
         return sm_resizing;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/HiDPIMouseClick/HiDPIRobotMouseClick.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,87 @@
+/*
+ * 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.Frame;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.UIManager;
+
+/* @test
+ * @bug 8073320
+ * @summary  Windows HiDPI support
+ * @author Alexander Scherbatiy
+ * @requires (os.family == "windows")
+ * @run main/othervm -Dsun.java2d.win.uiScale=2 HiDPIRobotMouseClick
+ */
+public class HiDPIRobotMouseClick {
+
+    private static volatile int mouseX;
+    private static volatile int mouseY;
+
+    public static void main(String[] args) throws Exception {
+
+        try {
+            UIManager.setLookAndFeel(
+                    "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+        } catch (Exception e) {
+            return;
+        }
+
+        Frame frame = new Frame();
+        frame.setBounds(30, 20, 400, 300);
+        frame.setUndecorated(true);
+
+        frame.addMouseListener(new MouseAdapter() {
+
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                mouseX = e.getXOnScreen();
+                mouseY = e.getYOnScreen();
+            }
+        });
+
+        frame.setVisible(true);
+
+        Robot robot = new Robot();
+        robot.waitForIdle();
+        Thread.sleep(200);
+
+        Rectangle rect = frame.getBounds();
+        rect.setLocation(frame.getLocationOnScreen());
+
+        int x = (int) rect.getCenterX();
+        int y = (int) rect.getCenterY();
+
+        robot.mouseMove(x, y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle();
+
+        if (x != mouseX || y != mouseY) {
+            throw new RuntimeException("Wrong mouse click point!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,115 @@
+/*
+ * 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.BorderLayout;
+import java.awt.Canvas;
+import java.awt.Color;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Panel;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.image.BufferedImage;
+import javax.swing.UIManager;
+
+/* @test
+ * @bug 8073320
+ * @summary  Windows HiDPI support
+ * @author Alexander Scherbatiy
+ * @requires (os.family == "windows")
+ * @run main/othervm -Dsun.java2d.win.uiScaleX=3 -Dsun.java2d.win.uiScaleY=2
+ *                    HiDPIRobotScreenCaptureTest
+ */
+public class HiDPIRobotScreenCaptureTest {
+
+    private static final Color[] COLORS = {
+        Color.GREEN, Color.BLUE, Color.ORANGE, Color.RED};
+
+    public static void main(String[] args) throws Exception {
+
+        try {
+            UIManager.setLookAndFeel(
+                    "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+        } catch (Exception e) {
+            return;
+        }
+
+        Frame frame = new Frame();
+        frame.setBounds(40, 30, 400, 300);
+        frame.setUndecorated(true);
+
+        Panel panel = new Panel(new BorderLayout());
+        Canvas canvas = new Canvas() {
+            @Override
+            public void paint(Graphics g) {
+                super.paint(g);
+                int w = getWidth();
+                int h = getHeight();
+                g.setColor(COLORS[0]);
+                g.fillRect(0, 0, w / 2, h / 2);
+                g.setColor(COLORS[1]);
+                g.fillRect(w / 2, 0, w / 2, h / 2);
+                g.setColor(COLORS[2]);
+                g.fillRect(0, h / 2, w / 2, h / 2);
+                g.setColor(COLORS[3]);
+                g.fillRect(w / 2, h / 2, w / 2, h / 2);
+            }
+        };
+
+        panel.add(canvas);
+        frame.add(panel);
+        frame.setVisible(true);
+        Robot robot = new Robot();
+        robot.waitForIdle();
+        Thread.sleep(200);
+
+        Rectangle rect = canvas.getBounds();
+        rect.setLocation(canvas.getLocationOnScreen());
+
+        BufferedImage image = robot.createScreenCapture(rect);
+        frame.dispose();
+
+        int w = image.getWidth();
+        int h = image.getHeight();
+
+        if (w != frame.getWidth() || h != frame.getHeight()) {
+            throw new RuntimeException("Wrong image size!");
+        }
+
+        if (image.getRGB(w / 4, h / 4) != COLORS[0].getRGB()) {
+            throw new RuntimeException("Wrong image color!");
+        }
+
+        if (image.getRGB(3 * w / 4, h / 4) != COLORS[1].getRGB()) {
+            throw new RuntimeException("Wrong image color!");
+        }
+
+        if (image.getRGB(w / 4, 3 * h / 4) != COLORS[2].getRGB()) {
+            throw new RuntimeException("Wrong image color!");
+        }
+
+        if (image.getRGB(3 * w / 4, 3 * h / 4) != COLORS[3].getRGB()) {
+            throw new RuntimeException("Wrong image color!");
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/TextLayout/OSXLigatureTest.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,82 @@
+/*
+ * 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 7162125
+ * @summary Test ligatures form on OS X.
+ */
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.font.TextAttribute;
+import java.util.HashMap;
+import java.util.Map;
+
+public class OSXLigatureTest {
+
+    public static void main(String[] args) {
+        if (!System.getProperty("os.name").startsWith("Mac")) {
+            return;
+        }
+        String ligStr = "ffi";
+        int w = 50, h = 50;
+
+        BufferedImage bi1 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+        Graphics2D bi1Graphics = bi1.createGraphics();
+        bi1Graphics.setColor(Color.white);
+        bi1Graphics.fillRect(0, 0, w, h);
+        bi1Graphics.setColor(Color.black);
+        Font noLigFont = new Font("Gill Sans", Font.PLAIN, 30);
+        bi1Graphics.setFont(noLigFont);
+        bi1Graphics.drawString(ligStr, 10, 40);
+
+        BufferedImage bi2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+        Graphics2D bi2Graphics = bi2.createGraphics();
+        bi2Graphics.setColor(Color.white);
+        bi2Graphics.fillRect(0, 0, w, h);
+        bi2Graphics.setColor(Color.black);
+        Map<TextAttribute, Object> attributes = new HashMap<>();
+        attributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
+        Font ligFont = noLigFont.deriveFont(attributes);
+        bi2Graphics.setFont(ligFont);
+        bi2Graphics.drawString(ligStr, 10, 40);
+
+        boolean same = true;
+        for (int x = 0; x < w; x++) {
+            for (int y = 0; y < h; y++) {
+                int c1 = bi1.getRGB(x, y);
+                int c2 = bi2.getRGB(x, y);
+                same &= (c1 == c2);
+            }
+            if (!same) {
+               break;
+            }
+        }
+        if (same) {
+            throw new RuntimeException("Images do not differ - no ligature");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesLinuxTest.java	Tue Nov 17 13:09:16 2015 -0800
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesWindowsTest.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,139 @@
+/*
+ * 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 8073320
+ * @summary  Windows HiDPI support
+ * @author Alexander Scherbatiy
+ * @requires (os.family == "windows")
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=false
+ *                   -Dsun.java2d.win.uiScaleX=3 -Dsun.java2d.win.uiScaleY=2
+ *                    HiDPIPropertiesWindowsTest UISCALE_DISABLED
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=false
+ *                   -Dsun.java2d.uiScale=3
+ *                    HiDPIPropertiesWindowsTest UISCALE_DISABLED
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=false
+ *                   -Dsun.java2d.uiScale=3
+ *                   -Dsun.java2d.win.uiScaleX=5 -Dsun.java2d.win.uiScaleY=6
+ *                    HiDPIPropertiesWindowsTest UISCALE_DISABLED
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=true
+ *                   -Dsun.java2d.uiScale=3
+ *                    HiDPIPropertiesWindowsTest UISCALE_3
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=true
+ *                   -Dsun.java2d.uiScale=4
+ *                   -Dsun.java2d.win.uiScaleX=2 -Dsun.java2d.win.uiScaleY=3
+ *                    HiDPIPropertiesWindowsTest UISCALE_2X3
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=true
+ *                   -Dsun.java2d.win.uiScaleX=3 -Dsun.java2d.win.uiScaleY=2
+ *                    HiDPIPropertiesWindowsTest UISCALE_3X2
+ * @run main/othervm -Dsun.java2d.uiScale=4
+ *                    HiDPIPropertiesWindowsTest UISCALE_4
+ * @run main/othervm -Dsun.java2d.uiScale=4
+ *                   -Dsun.java2d.win.uiScaleX=2 -Dsun.java2d.win.uiScaleY=3
+ *                    HiDPIPropertiesWindowsTest UISCALE_2X3
+ * @run main/othervm -Dsun.java2d.win.uiScaleX=4 -Dsun.java2d.win.uiScaleY=5
+ *                    HiDPIPropertiesWindowsTest UISCALE_4X5
+ * @run main/othervm -Dsun.java2d.uiScale=3
+ *                   -Dsun.java2d.win.uiScaleX=0 -Dsun.java2d.win.uiScaleY=0
+ *                    HiDPIPropertiesWindowsTest UISCALE_3
+ * @run main/othervm -Dsun.java2d.uiScale=4
+ *                   -Dsun.java2d.win.uiScaleX=-7 -Dsun.java2d.win.uiScaleY=-8
+ *                    HiDPIPropertiesWindowsTest UISCALE_4
+ * @run main/othervm -Dsun.java2d.uiScale=4x
+ *                    HiDPIPropertiesWindowsTest UISCALE_4
+ * @run main/othervm -Dsun.java2d.win.uiScaleX=4x -Dsun.java2d.win.uiScaleY=5x
+ *                    HiDPIPropertiesWindowsTest UISCALE_4X5
+ * @run main/othervm -Dsun.java2d.uiScale=384dpi
+ *                    HiDPIPropertiesWindowsTest UISCALE_4
+ * @run main/othervm -Dsun.java2d.uiScale=300%
+ *                    HiDPIPropertiesWindowsTest UISCALE_3
+ * @run main/othervm -Dsun.java2d.win.uiScaleX=400% -Dsun.java2d.win.uiScaleY=500%
+ *                    HiDPIPropertiesWindowsTest UISCALE_4X5
+ * @run main/othervm -Dsun.java2d.win.uiScaleX=288dpi -Dsun.java2d.win.uiScaleY=192dpi
+ *                    HiDPIPropertiesWindowsTest UISCALE_3X2
+ * @run main/othervm -Dsun.java2d.win.uiScaleX=200% -Dsun.java2d.win.uiScaleY=288dpi
+ *                    HiDPIPropertiesWindowsTest UISCALE_2X3
+ */
+public class HiDPIPropertiesWindowsTest {
+
+    public static void main(String[] args) throws Exception {
+
+        try {
+            UIManager.setLookAndFeel(
+                    "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+        } 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;
+            case "UISCALE_2X3":
+                testScale(2.0, 3.0);
+                break;
+            case "UISCALE_3X2":
+                testScale(3.0, 2.0);
+                break;
+            case "UISCALE_4X5":
+                testScale(4.0, 5.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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/MultiResolutionImage/MultiResolutionDrawImageWithTransformTest.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,248 @@
+/*
+ * 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.Color;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.BaseMultiResolutionImage;
+import static java.awt.RenderingHints.KEY_RESOLUTION_VARIANT;
+import static java.awt.RenderingHints.VALUE_RESOLUTION_VARIANT_SIZE_FIT;
+import java.awt.geom.AffineTransform;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import sun.java2d.StateTrackable;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.loops.SurfaceType;
+
+/**
+ * @test
+ * @bug 8073320
+ * @author Alexander Scherbatiy
+ * @summary Windows HiDPI support
+ * @modules java.desktop/sun.java2d java.desktop/sun.java2d.loops
+ * @run main MultiResolutionDrawImageWithTransformTest
+ */
+public class MultiResolutionDrawImageWithTransformTest {
+
+    private static final int SCREEN_SIZE = 400;
+    private static final int IMAGE_SIZE = SCREEN_SIZE / 4;
+    private static final Color BACKGROUND_COLOR = Color.PINK;
+    private static final Color[] COLORS = {
+        Color.CYAN, Color.GREEN, Color.BLUE, Color.ORANGE
+    };
+
+    public static void main(String[] args) throws Exception {
+
+        int length = COLORS.length;
+        BufferedImage[] resolutionVariants = new BufferedImage[length];
+        for (int i = 0; i < length; i++) {
+            resolutionVariants[i] = createRVImage(getSize(i), COLORS[i]);
+        }
+
+        BaseMultiResolutionImage mrImage = new BaseMultiResolutionImage(
+                resolutionVariants);
+
+        // scale 1, transform 1, resolution variant 1
+        Color color = getImageColor(mrImage, 1, 1);
+        if (!getColorForScale(1).equals(color)) {
+            throw new RuntimeException("Wrong resolution variant!");
+        }
+
+        // scale 1, transform 2, resolution variant 2
+        color = getImageColor(mrImage, 1, 2);
+        if (!getColorForScale(2).equals(color)) {
+            throw new RuntimeException("Wrong resolution variant!");
+        }
+
+        // scale 2, transform 1, resolution variant 2
+        color = getImageColor(mrImage, 2, 1);
+        if (!getColorForScale(2).equals(color)) {
+            throw new RuntimeException("Wrong resolution variant!");
+        }
+
+        // scale 2, transform 2, resolution variant 4
+        color = getImageColor(mrImage, 2, 2);
+        if (!getColorForScale(4).equals(color)) {
+            throw new RuntimeException("Wrong resolution variant!");
+        }
+    }
+
+    private static Color getColorForScale(int scale) {
+        return COLORS[scale - 1];
+    }
+
+    private static Color getImageColor(Image image, double configScale,
+            double transformScale) {
+
+        TestSurfaceData surface = new TestSurfaceData(SCREEN_SIZE, SCREEN_SIZE,
+                configScale);
+        SunGraphics2D g2d = new SunGraphics2D(surface,
+                Color.BLACK, Color.BLACK, null);
+        g2d.setRenderingHint(KEY_RESOLUTION_VARIANT,
+                VALUE_RESOLUTION_VARIANT_SIZE_FIT);
+        AffineTransform tx = AffineTransform.getScaleInstance(transformScale,
+                transformScale);
+        g2d.drawImage(image, tx, null);
+        g2d.dispose();
+
+        int backgroundX = (int) (1.5 * image.getWidth(null) * transformScale);
+        int backgroundY = (int) (1.5 * image.getHeight(null) * transformScale);
+        Color backgroundColor = surface.getColor(backgroundX, backgroundY);
+        //surface.show(String.format("Config: %f, transform: %f", configScale, transformScale));
+        if (!BACKGROUND_COLOR.equals(backgroundColor)) {
+            throw new RuntimeException("Wrong background color!");
+        }
+        return surface.getColor(IMAGE_SIZE / 4, IMAGE_SIZE / 4);
+    }
+
+    private static int getSize(int i) {
+        return (i + 1) * IMAGE_SIZE;
+    }
+
+    private static BufferedImage createRVImage(int size, Color color) {
+        BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
+        Graphics g = image.createGraphics();
+        g.setColor(color);
+        g.fillRect(0, 0, size, size);
+        g.dispose();
+        return image;
+    }
+
+    static class TestGraphicsConfig extends GraphicsConfiguration {
+
+        private final double scale;
+
+        TestGraphicsConfig(double scale) {
+            this.scale = scale;
+        }
+
+        @Override
+        public GraphicsDevice getDevice() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public ColorModel getColorModel() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public ColorModel getColorModel(int transparency) {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public AffineTransform getDefaultTransform() {
+            return AffineTransform.getScaleInstance(scale, scale);
+        }
+
+        @Override
+        public AffineTransform getNormalizingTransform() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public Rectangle getBounds() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+    }
+
+    static class TestSurfaceData extends SurfaceData {
+
+        private final int width;
+        private final int height;
+        private final GraphicsConfiguration gc;
+        private final BufferedImage buffImage;
+        private final double scale;
+
+        public TestSurfaceData(int width, int height, double scale) {
+            super(StateTrackable.State.DYNAMIC, SurfaceType.Custom, ColorModel.getRGBdefault());
+            this.scale = scale;
+            gc = new TestGraphicsConfig(scale);
+            this.width = (int) Math.ceil(scale * width);
+            this.height = (int) Math.ceil(scale * height);
+            buffImage = new BufferedImage(this.width, this.height,
+                    BufferedImage.TYPE_INT_RGB);
+
+            Graphics imageGraphics = buffImage.createGraphics();
+            imageGraphics.setColor(BACKGROUND_COLOR);
+            imageGraphics.fillRect(0, 0, this.width, this.height);
+            imageGraphics.dispose();
+        }
+
+        Color getColor(int x, int y) {
+            int sx = (int) Math.ceil(x * scale);
+            int sy = (int) Math.ceil(y * scale);
+            return new Color(buffImage.getRGB(sx, sy));
+        }
+
+        @Override
+        public SurfaceData getReplacement() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public GraphicsConfiguration getDeviceConfiguration() {
+            return gc;
+        }
+
+        @Override
+        public Raster getRaster(int x, int y, int w, int h) {
+            return buffImage.getRaster();
+        }
+
+        @Override
+        public Rectangle getBounds() {
+            return new Rectangle(0, 0, width, height);
+        }
+
+        @Override
+        public Object getDestination() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        private void show(String title) {
+            Frame frame = new Frame() {
+
+                @Override
+                public void paint(Graphics g) {
+                    super.paint(g);
+                    g.drawImage(buffImage, 0, 0, this);
+                    g.setColor(Color.GRAY);
+                    g.drawRect(0, 0, width, height);
+                    g.drawRect(0, height / 2, width, height / 2);
+                    g.drawRect(width / 2, 0, width / 2, height);
+                }
+            };
+            frame.setTitle(title);
+            frame.setSize(width, height);
+            frame.setVisible(true);
+        }
+    }
+}
--- a/jdk/test/java/awt/print/PageFormat/ImageableAreaTest.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/test/java/awt/print/PageFormat/ImageableAreaTest.java	Tue Nov 17 13:09:16 2015 -0800
@@ -45,7 +45,7 @@
 
 /**
  * @test
- * @bug 8044444
+ * @bug 8044444 8081491
  * @summary The output's 'Page-n' footer does not show completely
  * @author Alexandr Scherbatiy
  * @run main/manual ImageableAreaTest
@@ -58,11 +58,13 @@
             @Override
             public void run() {
 
+
                 createAndShowTestDialog(
                         "1. Press the Print Table button\n"
                         + " Java print dialog should appear.\n"
                         + "2. Press the Print button on the Java Print dialog.\n"
-                        + "2. Check that the page number is correctly printed.\n"
+                        + "3. Check that the page number is correctly printed.\n"
+                        + "4. Check only the visible part of the table is printed.\n"
                         + "If so, press PASS, else press FAIL.",
                         "Page number is not correctly printed!",
                         ImageableAreaTest::printWithJavaPrintDialog);
@@ -71,24 +73,47 @@
                         "1. Press the Print Table button\n"
                         + " The table should be printed without the print dialog.\n"
                         + "2. Check that the page number is correctly printed.\n"
+                        + "3. Check only the visible part of the table is printed.\n"
                         + "If so, press PASS, else press FAIL.",
                         "Page number is not correctly printed!",
                         ImageableAreaTest::printWithoutPrintDialog);
 
+
+
                 createAndShowTestDialog(
                         "1. Press the Print Table button\n"
                         + " Java print dialog should appear.\n"
                         + "2. Press the Print button on the Java Print dialog.\n"
                         + "3. Check that the table has about half size of the printed page\n"
+                        + "4. Check only the visible part of the table is printed.\n"
                         + "If so, press PASS, else press FAIL.",
                         "Custom imageable area is not correctly printed!",
                         ImageableAreaTest::printWithCustomImageareaSize);
+
+                createAndShowTestDialog(
+                        "1. Press the Print Table button\n"
+                        + " Java print dialog should appear.\n"
+                        + "2. Press the Print button on the Java Print dialog.\n"
+                        + "3. Check that the rows with different height is printed.\n"
+                        + "4. Check only the visible part of the table is printed.\n"
+                        + "If so, press PASS, else press FAIL.",
+                        "Row with different height is not correctly printed!",
+                        ImageableAreaTest::printDifferentRowHeight);
+
+                createAndShowTestDialog(
+                        "1. Press the Print Table button\n"
+                        + " Java print dialog should appear.\n"
+                        + "2. Press the Print button on the Java Print dialog.\n"
+                        + "3. Check that the only 1 row is shown & printed.\n"
+                        + "If so, press PASS, else press FAIL.",
+                        "Only 1 Row is not correctly printed!",
+                        ImageableAreaTest::printOneRowWithJavaPrintDialog);
             }
         });
     }
 
     private static void printWithJavaPrintDialog() {
-        final JTable table = createAuthorTable(42);
+        final JTable table = createAuthorTable(50);
         Printable printable = table.getPrintable(
                 JTable.PrintMode.NORMAL,
                 new MessageFormat("Author Table"),
@@ -110,7 +135,7 @@
 
     private static void printWithoutPrintDialog() {
 
-        final JTable table = createAuthorTable(42);
+        final JTable table = createAuthorTable(50);
         PrintRequestAttributeSet pras
                 = new HashPrintRequestAttributeSet();
         pras.add(new Copies(1));
@@ -132,6 +157,50 @@
         }
     }
 
+    private static void printDifferentRowHeight() {
+        final JTable table = createAuthorTable(50);
+        table.setRowHeight(15, table.getRowHeight(15)+10);
+        Printable printable = table.getPrintable(
+                JTable.PrintMode.NORMAL,
+                new MessageFormat("Author Table"),
+                new MessageFormat("Page - {0}"));
+
+        PrinterJob job = PrinterJob.getPrinterJob();
+        job.setPrintable(printable);
+
+        boolean printAccepted = job.printDialog();
+        if (printAccepted) {
+            try {
+                job.print();
+                closeFrame();
+            } catch (PrinterException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+    }
+
+    private static void printOneRowWithJavaPrintDialog() {
+        final JTable table = createAuthorTable(1);
+        Printable printable = table.getPrintable(
+                JTable.PrintMode.NORMAL,
+                new MessageFormat("Author Table"),
+                new MessageFormat("Page - {0}"));
+
+        PrinterJob job = PrinterJob.getPrinterJob();
+        job.setPrintable(printable);
+
+        boolean printAccepted = job.printDialog();
+        if (printAccepted) {
+            try {
+                job.print();
+                closeFrame();
+            } catch (PrinterException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
     private static void printWithCustomImageareaSize() {
         final JTable table = createAuthorTable(18);
         PrintRequestAttributeSet printAttributes = new HashPrintRequestAttributeSet();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/PageDlgStackOverflowTest.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,53 @@
+/*
+ * 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.print.PrinterJob;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.standard.DialogTypeSelection;
+
+/**
+ * @test
+ * @bug 8039412
+ * @run main/manual PageDlgStackOverflowTest
+ * @summary Calling pageDialog() after printDialog with
+ *          DialogTypeSelection.NATIVE should not result in StackOverflowError
+ */
+public class PageDlgStackOverflowTest {
+
+    public static void main(String args[]) {
+        PrinterJob job = PrinterJob.getPrinterJob();
+        if (job == null) {
+            return;
+        }
+        PrintRequestAttributeSet pSet =
+             new HashPrintRequestAttributeSet();
+        pSet.add(DialogTypeSelection.NATIVE);
+        job.printDialog(pSet);
+        try {
+            job.pageDialog(pSet);
+        } catch (StackOverflowError e) {
+            throw new RuntimeException("StackOverflowError is thrown");
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JInternalFrame/6288609/TestJInternalFrameDispose.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,158 @@
+/*
+ * 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 6288609
+ * @summary JInternalFrame.setDefaultCloseOperation() interferes with "close"
+              behavior
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main TestJInternalFrameDispose
+ */
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import javax.swing.JFrame;
+import javax.swing.JDesktopPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JInternalFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
+public class TestJInternalFrameDispose {
+
+    private static JDesktopPane desktopPane;
+    private static JFrame frame = new JFrame("Test Frame");
+    private static int count = 0;
+    private static JMenu menu;
+    private static JMenuBar menuBar;
+    private static JMenuItem menuItem;
+    private static Robot robot;
+    private static JInternalFrame internalFrame;
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                createUI();
+            }
+        });
+
+        robot.waitForIdle();
+        executeTest();
+        dispose();
+    }
+
+    private static void createUI() {
+
+        desktopPane = new JDesktopPane();
+        frame.getContentPane().add(desktopPane);
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        menuBar = new JMenuBar();
+        frame.setJMenuBar(menuBar);
+
+        menu = new JMenu("File");
+        menuBar.add(menu);
+
+        menuItem = new JMenuItem("New Child");
+        menuItem.addActionListener(
+                new ActionListener() {
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        JInternalFrame f = new JInternalFrame("Child "
+                                + (++count), true, true, true, true);
+                        f.setDefaultCloseOperation(
+                                JInternalFrame.DO_NOTHING_ON_CLOSE);
+                        f.addInternalFrameListener(new InternalFrameAdapter() {
+                            @Override
+                            public void internalFrameClosing(
+                                    InternalFrameEvent e) {
+                                        e.getInternalFrame().dispose();
+                                    }
+                        });
+                        f.setSize(200, 300);
+                        f.setLocation(count * 20, count * 20);
+                        desktopPane.add(f);
+                        f.setVisible(true);
+                    }
+                });
+        menu.add(menuItem);
+
+        frame.setSize(400, 500);
+        frame.setLocationRelativeTo(null);
+        frame.setVisible(true);
+    }
+
+    private static void executeTest() throws Exception {
+
+        Point point = Util.getCenterPoint(menu);
+        performMouseOperations(point);
+        point = Util.getCenterPoint(menuItem);
+        performMouseOperations(point);
+        point = Util.getCenterPoint(menu);
+        performMouseOperations(point);
+        point = Util.getCenterPoint(menuItem);
+        performMouseOperations(point);
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                internalFrame = desktopPane.getSelectedFrame();
+                internalFrame.doDefaultCloseAction();
+                internalFrame = desktopPane.getSelectedFrame();
+            }
+        });
+
+        robot.delay(2000);
+        if (internalFrame == null) {
+            dispose();
+            throw new RuntimeException("Test Failed");
+        }
+    }
+
+    private static void dispose() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+    }
+
+    private static void performMouseOperations(Point point) {
+        robot.mouseMove(point.x, point.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.delay(1000);
+        robot.waitForIdle();
+    }
+}
--- a/jdk/test/javax/swing/JRadioButton/FocusTraversal/FocusTraversal.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/test/javax/swing/JRadioButton/FocusTraversal/FocusTraversal.java	Tue Nov 17 13:09:16 2015 -0800
@@ -22,43 +22,82 @@
  */
 
 /* @test
-   @bug 8129940
-   @summary JRadioButton does not honor non-standard FocusTraversalKeys
-   @author Semyon Sadetsky
-  */
-
-import javax.swing.*;
-import java.awt.*;
+ @bug 8129940 8132770
+ @summary JRadioButton should run custom FocusTraversalKeys for all LaFs
+ @run main FocusTraversal
+ */
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.KeyboardFocusManager;
+import java.awt.Robot;
 import java.awt.event.KeyEvent;
 import java.util.HashSet;
 import java.util.Set;
+import javax.swing.ButtonGroup;
+import javax.swing.FocusManager;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+import javax.swing.LookAndFeel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
 
 public class FocusTraversal {
 
     private static JFrame frame;
     private static JRadioButton a;
+    private static JRadioButton b;
+    private static JRadioButton c;
     private static JRadioButton d;
     private static JTextField next;
     private static JTextField prev;
+    private static Robot robot;
 
     public static void main(String[] args) throws Exception {
+
+        robot = new Robot();
+        robot.delay(2000);
+        UIManager.LookAndFeelInfo[] lookAndFeelArray
+                = UIManager.getInstalledLookAndFeels();
+        for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
+            executeCase(lookAndFeelItem.getClassName());
+        }
+    }
+
+    private static void executeCase(String lookAndFeelString)
+            throws Exception {
+        if (tryLookAndFeel(lookAndFeelString)) {
+            createUI(lookAndFeelString);
+            robot.delay(2000);
+            runTestCase();
+            robot.delay(2000);
+            cleanUp();
+            robot.delay(2000);
+        }
+    }
+
+    private static void createUI(final String lookAndFeelString)
+            throws Exception {
         SwingUtilities.invokeAndWait(new Runnable() {
             @Override
             public void run() {
-                frame = new JFrame("FocusTraversalTest");
-                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
-                frame.setUndecorated(true);
-
                 Set<KeyStroke> keystrokes = new HashSet<KeyStroke>();
                 keystrokes.add(KeyStroke.getKeyStroke("TAB"));
                 keystrokes.add(KeyStroke.getKeyStroke("ENTER"));
+                frame = new JFrame("FocusTraversalTest " + lookAndFeelString);
+                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+                frame.setUndecorated(true);
                 frame.setFocusTraversalKeys(
                         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
                         keystrokes);
 
                 a = new JRadioButton("a");
-                JRadioButton b = new JRadioButton("b");
-                JRadioButton c = new JRadioButton("c");
+                b = new JRadioButton("b");
+                c = new JRadioButton("c");
                 d = new JRadioButton("d");
 
                 ButtonGroup radioButtonGroup = new ButtonGroup();
@@ -84,61 +123,102 @@
 
                 frame.add(root);
                 frame.pack();
+                frame.setLocationRelativeTo(null);
                 frame.setVisible(true);
-            }
-        });
-
-        SwingUtilities.invokeAndWait(new Runnable() {
-            @Override
-            public void run() {
-                a.requestFocus();
+                frame.toFront();
             }
         });
+    }
 
-        Robot robot = new Robot();
-        robot.waitForIdle();
+    private static void runTestCase() throws Exception {
+        LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
+        focusOn(a);
+        if (isExcludedLookAndFeel(lookAndFeel)) {
+            robot.keyPress(KeyEvent.VK_ENTER);
+            robot.keyRelease(KeyEvent.VK_ENTER);
+            robot.waitForIdle();
+            isFocusOwner(b, "forward");
+            robot.keyPress(KeyEvent.VK_SHIFT);
+            robot.keyPress(KeyEvent.VK_TAB);
+            robot.keyRelease(KeyEvent.VK_TAB);
+            robot.keyRelease(KeyEvent.VK_SHIFT);
+            robot.waitForIdle();
+            isFocusOwner(a, "backward");
+
+        } else {
 
-        robot.setAutoDelay(200);
+            robot.keyPress(KeyEvent.VK_ENTER);
+            robot.keyRelease(KeyEvent.VK_ENTER);
+            robot.waitForIdle();
+            isFocusOwner(next, "forward");
+            robot.keyPress(KeyEvent.VK_SHIFT);
+            robot.keyPress(KeyEvent.VK_TAB);
+            robot.keyRelease(KeyEvent.VK_TAB);
+            robot.keyRelease(KeyEvent.VK_SHIFT);
+            robot.waitForIdle();
+            isFocusOwner(d, "backward");
+        }
 
-        robot.keyPress(KeyEvent.VK_ENTER);
-        robot.keyRelease(KeyEvent.VK_ENTER);
-        robot.waitForIdle();
+    }
+
+    private static boolean isExcludedLookAndFeel(LookAndFeel lookAndFeel) {
 
+        return lookAndFeel.toString().toLowerCase().contains("aqua")
+                || lookAndFeel.toString().toLowerCase().contains("nimbus")
+                || lookAndFeel.toString().toLowerCase().contains("gtk");
+    }
+
+    private static void focusOn(Component component)
+            throws Exception {
         SwingUtilities.invokeAndWait(new Runnable() {
             @Override
             public void run() {
-                Component focusOwner =
-                        FocusManager.getCurrentManager().getFocusOwner();
-                if (focusOwner != next) {
+                component.requestFocusInWindow();
+            }
+        });
+    }
+
+    private static void isFocusOwner(Component queriedFocusOwner,
+            String direction)
+            throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                Component actualFocusOwner
+                        = FocusManager.getCurrentManager().getFocusOwner();
+                if (actualFocusOwner != queriedFocusOwner) {
+                    frame.dispose();
                     throw new RuntimeException(
-                            "Focus component is wrong after forward key " + focusOwner);
+                            "Focus component is wrong after " + direction
+                            + " direction ");
+
                 }
             }
         });
+    }
 
-        robot.keyPress(KeyEvent.VK_SHIFT);
-        robot.keyPress(KeyEvent.VK_TAB);
-        robot.keyRelease(KeyEvent.VK_TAB);
-        robot.keyRelease(KeyEvent.VK_SHIFT);
-        robot.waitForIdle();
+    private static boolean tryLookAndFeel(String lookAndFeelString)
+            throws Exception {
+
+        try {
+            UIManager.setLookAndFeel(
+                    lookAndFeelString);
+
+        } catch (UnsupportedLookAndFeelException
+                | ClassNotFoundException
+                | InstantiationException
+                | IllegalAccessException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private static void cleanUp() throws Exception {
         SwingUtilities.invokeAndWait(new Runnable() {
             @Override
             public void run() {
-                Component focusOwner =
-                        FocusManager.getCurrentManager().getFocusOwner();
-                if (focusOwner != d) {
-                    throw new RuntimeException(
-                            "Focus component is wrong after backward key " + focusOwner);
-                }
-            }
-        });
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
                 frame.dispose();
             }
         });
-        System.out.println("ok");
-
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTabbedPane/8134116/Bug8134116.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,130 @@
+
+import java.awt.*;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.List;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.swing.*;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+
+/*
+ * @test
+ * @bug 8134116
+ * @summary JTabbedPane$Page.getBounds throws IndexOutOfBoundsException
+ * @run main Bug8134116
+ */
+public class Bug8134116 {
+
+    public static void main(String args[]) throws Exception {
+
+        try {
+            UIManager.setLookAndFeel(new NimbusLookAndFeel());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        SwingUtilities.invokeAndWait(() -> {
+            JPanel panel0 = new JPanel();
+            BadPane badPane = new BadPane();
+            badPane.add("zero", panel0);
+            badPane.add("one", null);
+            JFrame frame = new JFrame();
+            frame.add(badPane);
+            frame.setSize(300, 300);
+            frame.setVisible(true);
+
+            AccessibleContext ac = badPane.getAccessibleContext();
+            Accessible page0 = ac.getAccessibleChild(0);
+            if (page0 == null) {
+                // Not something being tested, but checking anyway
+                throw new RuntimeException("getAccessibleChild(0) is null");
+            }
+            Accessible page1 = ac.getAccessibleChild(1);
+            if (page1 == null) {
+                // Not something being tested, but checking anyway
+                throw new RuntimeException("getAccessibleChild(1) is null");
+            }
+            // page0 and page1 are a JTabbedPane.Page, a private inner class
+            // and is an AccessibleContext
+            // and implements Accessible and AccessibleComponent
+            AccessibleContext pac0 = page0.getAccessibleContext();
+            AccessibleContext pac1 = page1.getAccessibleContext();
+
+            // the following would fail if JDK-8134116 fix not present
+
+            // test Page.getBounds
+            // ensure no IndexOutOfBoundsException
+            pac0.getAccessibleComponent().getBounds();
+
+            // test Page.getAccessibleStateSet
+            // At this point page 0 is selected
+            AccessibleStateSet accSS0 = pac0.getAccessibleStateSet();
+            if (!accSS0.contains(AccessibleState.SELECTED)) {
+                String msg = "Empty title -> AccessibleState.SELECTED not set";
+                throw new RuntimeException(msg);
+            }
+
+            // test Page.getAccessibleIndexInParent
+            if (pac0.getAccessibleIndexInParent() == -1) {
+                String msg = "Empty title -> negative AccessibleIndexInParent";
+                throw new RuntimeException(msg);
+            }
+
+            // test Page.getAccessibleName
+            String accName = pac0.getAccessibleName();
+            if (!accName.equals("zero")) {
+                String msg = "Empty title -> empty AccessibleName";
+                throw new RuntimeException(msg);
+            }
+            // test Page.getAccessibleName when component is null
+            accName = pac1.getAccessibleName();
+            if (!accName.equals("one")) {
+                String msg = "AccessibleName of null panel not 'one'";
+                throw new RuntimeException(msg);
+            }
+
+            // test Page.setDisplayedMnemonicIndex
+            //  Empty title -> IllegalArgumnetException
+            badPane.setDisplayedMnemonicIndexAt(0, 1);
+
+            // test Page.updateDisplayedMnemonicIndex
+            badPane.setMnemonicAt(0, KeyEvent.VK_Z);
+            if (badPane.getDisplayedMnemonicIndexAt(0) == -1) {
+                String msg="Empty title -> getDisplayedMnemonicIndexAt failure";
+                throw new RuntimeException(msg);
+            }
+        });
+    }
+
+    // The following is likely what is being done in Burp Suite
+    // https://portswigger.net/burp/ which fails in the same way, i.e. the
+    // pages List in JTabbedPane is not being managed properly and thus
+    // Page.title is "" for each page.  The overridden insertTab manages titles
+    // in the subclass passing a "" title to the superclass JTabbedPane through
+    // its insertTab.  Later an overridden getTitleAt returns the titles as
+    // managed by the subclass.
+    static class BadPane extends JTabbedPane {
+        private List<String> titles;
+
+        BadPane() {
+            titles = new ArrayList<String>(1);
+        }
+
+        @Override
+        public void insertTab( String title, Icon icon, Component component,
+                               String tip, int index ) {
+            titles.add(index, title);
+            super.insertTab("", icon, component, tip, index);
+        }
+
+        @Override
+        public String getTitleAt(int i) {
+            return titles.get(i);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/7124218/SelectEditTableCell.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,201 @@
+/*
+ * 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 7124218
+ * @summary verifies different behaviour of SPACE and ENTER in JTable
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main SelectEditTableCell
+ */
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JFrame;
+import javax.swing.JTable;
+import javax.swing.LookAndFeel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+public class SelectEditTableCell {
+
+    private static JFrame frame;
+    private static JTable table;
+    private static Robot robot;
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        robot.delay(2000);
+        UIManager.LookAndFeelInfo[] lookAndFeelArray
+                = UIManager.getInstalledLookAndFeels();
+        for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
+            executeCase(lookAndFeelItem.getClassName());
+        }
+
+    }
+
+    private static void executeCase(String lookAndFeelString) throws Exception {
+        if (tryLookAndFeel(lookAndFeelString)) {
+            createUI(lookAndFeelString);
+            robot.delay(2000);
+            runTestCase();
+            robot.delay(2000);
+            cleanUp();
+            robot.delay(2000);
+        }
+
+    }
+
+    private static void createUI(final String lookAndFeelString)
+            throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                String[][] data = {{"Foo"}};
+                String[] cols = {"One"};
+                table = new JTable(data, cols);
+                table.setSelectionMode(
+                        DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+                frame = new JFrame(lookAndFeelString);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.getContentPane().add(table);
+                frame.pack();
+                frame.setSize(500, frame.getSize().height);
+                frame.setLocationRelativeTo(null);
+                frame.setVisible(true);
+                frame.toFront();
+            }
+        });
+    }
+
+    private static void runTestCase() throws Exception {
+        Point centerPoint;
+        centerPoint = Util.getCenterPoint(table);
+        LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
+        robot.mouseMove(centerPoint.x, centerPoint.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                table.clearSelection();
+                if (table.isEditing() || table.isCellSelected(0, 0)) {
+                    // assumption is bad, bail
+                    frame.dispose();
+                    throw new AssertionError("Failed assumption: assumed no"
+                            + "editing and no selection.");
+                }
+            }
+        });
+        robot.waitForIdle();
+        int fetchKeyCode;
+        keyTap(fetchKeyCode = isMac(lookAndFeel)
+                ? KeyEvent.VK_ENTER : KeyEvent.VK_SPACE);
+        final int keyCode = fetchKeyCode;
+        robot.waitForIdle();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                if (!table.isCellSelected(0, 0)) {
+                    frame.dispose();
+                    throw new RuntimeException(((keyCode == KeyEvent.VK_ENTER)
+                            ? "Enter" : "Space")
+                            + " should select cell");
+                }
+            }
+        });
+        robot.waitForIdle();
+        keyTap(KeyEvent.VK_SPACE);
+        robot.waitForIdle();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                if (!table.isEditing()) {
+                    frame.dispose();
+                    throw new RuntimeException("Space should start editing");
+                }
+                table.getCellEditor().cancelCellEditing();
+                table.clearSelection();
+                if (table.isEditing() || table.isCellSelected(0, 0)) {
+                    // assumption is bad, bail
+                    frame.dispose();
+                    throw new AssertionError("Failed assumption: assumed no "
+                            + "editing and no selection.");
+                }
+            }
+        });
+        robot.waitForIdle();
+        // hitting a letter key will start editing
+        keyTap(KeyEvent.VK_A);
+        keyTap(KeyEvent.VK_SPACE);
+        keyTap(KeyEvent.VK_A);
+        robot.waitForIdle();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                if (table.isCellSelected(0, 0)) {
+                    frame.dispose();
+                    throw new RuntimeException("Space should not select when "
+                            + "already editing.");
+                }
+            }
+        });
+    }
+
+    private static void cleanUp() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+    }
+
+    private static boolean isMac(LookAndFeel lookAndFeel) {
+
+        return lookAndFeel.toString().toLowerCase().contains("mac");
+    }
+
+    private static void keyTap(int keyCode) {
+        robot.keyPress(keyCode);
+        robot.keyRelease(keyCode);
+    }
+
+    private static boolean tryLookAndFeel(String lookAndFeelString)
+            throws Exception {
+        try {
+            UIManager.setLookAndFeel(
+                    lookAndFeelString);
+
+        } catch (UnsupportedLookAndFeelException
+                | ClassNotFoundException
+                | InstantiationException
+                | IllegalAccessException e) {
+            return false;
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/JTableScrollTest.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,182 @@
+/* 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.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Color;
+import java.awt.Dialog;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JFrame;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JButton;
+import javax.swing.table.TableModel;
+import javax.swing.JScrollPane;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.SwingUtilities;
+
+/**
+ * @test
+ * @bug 8081491
+ * @summary Scrolling a JTable creates artifacts
+ * @run main/manual JTableScrollTest
+ */
+public class JTableScrollTest {
+    static JFrame frame = new JFrame();
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                doTest(JTableScrollTest::createTable);
+            }
+        });
+    }
+
+    private static void createTable() {
+        // final
+        final String[] names = {
+            new String("first_name"),
+            new String("last_name"),
+            new String("favorite_color"),
+            new String("favorite_food")
+        };
+
+        // Create the dummy data (a few rows of names)
+        final Object[][] data = {
+          {"Mike", "Albers",      "green",      "strawberry"},
+          {"Mark", "Andrews",     "blue",       "grapes"},
+          {"Brian", "Beck",       "black",      "raspberry"},
+          {"Lara", "Bunni",       "red",        "strawberry"},
+          {"Roger", "Brinkley",   "blue",       "peach"},
+          {"Brent", "Christian",  "black",      "broccoli"},
+          {"Mark", "Davidson",    "darkgreen",  "asparagus"},
+          {"Jeff", "Dinkins",     "blue",       "kiwi"},
+          {"Ewan", "Dinkins",     "yellow",     "strawberry"},
+          {"Amy", "Fowler",       "violet",     "raspberry"},
+          {"Hania", "Gajewska",   "purple",     "raspberry"},
+          {"David", "Geary",      "blue",       "watermelon"},
+          {"Ryan", "Gosling",    "pink",       "donut"},
+          {"Eric", "Hawkes",      "blue",       "pickle"},
+          {"Shannon", "Hickey",   "green",      "grapes"},
+          {"Earl", "Johnson",     "green",      "carrot"},
+          {"Robi", "Khan",        "green",      "apple"},
+          {"Robert", "Kim",       "blue",       "strawberry"},
+          {"Janet", "Koenig",     "turquoise",  "peach"},
+          {"Jeff", "Kesselman",   "blue",       "pineapple"},
+          {"Onno", "Kluyt",       "orange",     "broccoli"},
+          {"Peter", "Korn",       "sunpurple",  "sparegrass"},
+          {"Rick", "Levenson",    "black",      "raspberry"},
+          {"Brian", "Lichtenwalter", "blue", "pear"},
+          {"Malini", "Minasandram", "beige",    "corn"},
+          {"Michael", "Martak",   "green",      "strawberry"},
+          {"David", "Mendenhall", "forestgreen", "peach"},
+          {"Phil", "Milne",       "pink", "banana"},
+          {"Lynn", "Monsanto",    "cybergreen",  "peach"},
+          {"Hans", "Muller",      "rustred",     "pineapple"},
+          {"Joshua", "Outwater",  "blue",        "pineapple"},
+          {"Tim", "Prinzing",     "blue",        "pepper"},
+          {"Raj", "Premkumar",    "blue",    "broccoli"},
+          {"Howard", "Rosen",     "green",    "strawberry"},
+          {"Ray", "Ryan",         "black",   "banana"},
+          {"Georges", "Saab",     "aqua",     "cantaloupe"},
+          {"Tom", "Santos",       "blue",       "pepper"},
+          {"Rich", "Schiavi",     "blue",       "pepper"},
+          {"Nancy", "Schorr",     "green",      "watermelon"},
+          {"Keith", "Sprochi",    "darkgreen",   "watermelon"},
+          {"Matt", "Tucker",      "eblue",       "broccoli"},
+          {"Dmitri", "Trembovetski", "red",      "tomato"},
+          {"Scott", "Violet",     "violet",      "banana"},
+          {"Kathy", "Walrath",    "darkgreen",   "pear"},
+        };
+
+    // Create a model of the data.
+        TableModel dataModel = new AbstractTableModel() {
+            public int getColumnCount() { return names.length; }
+            public int getRowCount() { return data.length;}
+            public Object getValueAt(int row, int col) {return data[row][col];}
+            public String getColumnName(int column) {return names[column];}
+            public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
+            public boolean isCellEditable(int row, int col) {return col != 5;}
+            public void setValueAt(Object aValue, int row, int column) { data[row][column] = aValue; }
+         };
+
+    // Create the table
+        JTable tableView = new JTable(dataModel);
+        tableView.setBackground(Color.WHITE);
+        tableView.setForeground(Color.BLACK);
+        tableView.setSize(600, 800);
+        JScrollPane scrollpane = new JScrollPane(tableView);
+        frame.add(scrollpane);
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+    private static void doTest(Runnable action) {
+        String description =
+          "JTable with rows will be displayed along with scrollbar.\n"
+           + "Scroll the table. Verify no arifacts are shown and rows.\n"
+           + " are correctly displayed.";
+        final JDialog dialog = new JDialog();
+        dialog.setTitle("ScrollArtifactTest ");
+        JTextArea textArea = new JTextArea(description);
+        textArea.setEditable(false);
+        final JButton testButton = new JButton("Create Table");
+        final JButton passButton = new JButton("PASS");
+        passButton.setEnabled(false);
+        passButton.addActionListener((e) -> {
+            dialog.dispose();
+            if (frame != null) {
+                frame.setVisible(false);
+                frame.dispose();
+            }
+        });
+        final JButton failButton = new JButton("FAIL");
+        failButton.setEnabled(false);
+        failButton.addActionListener((e) -> {
+            dialog.dispose();
+            if (frame != null) {
+                frame.setVisible(false);
+                frame.dispose();
+            }
+            throw new RuntimeException("Scrollbar artifact shown");
+        });
+        testButton.addActionListener((e) -> {
+            testButton.setEnabled(false);
+            action.run();
+            passButton.setEnabled(true);
+            failButton.setEnabled(true);
+        });
+        JPanel mainPanel = new JPanel(new BorderLayout());
+        mainPanel.add(textArea, BorderLayout.CENTER);
+        JPanel buttonPanel = new JPanel(new FlowLayout());
+        buttonPanel.add(testButton);
+        buttonPanel.add(passButton);
+        buttonPanel.add(failButton);
+        mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+        dialog.add(mainPanel);
+        dialog.pack();
+        dialog.setVisible(true);
+    }
+
+
+}
--- a/jdk/test/javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java	Tue Nov 17 10:29:28 2015 -0800
+++ b/jdk/test/javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java	Tue Nov 17 13:09:16 2015 -0800
@@ -36,10 +36,10 @@
 
 /**
  * @test
- * @bug 8015085
+ * @bug 8015085 8079253
  * @summary Shortening via " ... " is broken for Strings containing a combining
  *          diaeresis.
- * @author Sergey Bylokhov
+ * @run main TestBadBreak
  */
 public class TestBadBreak {
 
@@ -79,6 +79,7 @@
                         g2d.dispose();
                     }
                 };
+                label.setOpaque(true);
                 frame.getContentPane().add(label);
                 frame.setBounds(200, 200, 200, 90);
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/awt/shell/ShellFolderMemoryLeak.java	Tue Nov 17 13:09:16 2015 -0800
@@ -0,0 +1,226 @@
+/*
+ * 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 8030099
+ * @summary Memory usage of java process increases
+            after calling Win32ShellFolder:listFiles
+            multiple times on some directory with
+            large number of files/folders
+ * @modules java.desktop/sun.awt
+ * @requires (os.family == "windows")
+ * @run main/timeout=1000 ShellFolderMemoryLeak
+ */
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import sun.awt.shell.ShellFolder;
+
+public class ShellFolderMemoryLeak {
+
+    private final static String tempDir = System.getProperty("java.io.tmpdir");
+    private static Process process;
+    public static void main(String[] args) throws Exception {
+        if (args.length == 0) {
+            boolean testResultParallel
+                    = createChildProcessWithParallelCollector();
+            String result = "";
+            if (!testResultParallel) {
+                result = "Test failed with Parallel collector";
+            }
+            boolean testResultDefault
+                    = createChildProcessWithDefaultCollector();
+            if (!testResultDefault && !testResultParallel) {
+                result += " and with default collector both.";
+            } else if (!testResultDefault) {
+                result = "Test failed with default collector";
+            }
+            if (!"".equals(result)) {
+                throw new RuntimeException(result);
+            }
+        } else {
+            testListFile(args[args.length - 1]);
+        }
+    }
+
+    public static boolean createChildProcessWithDefaultCollector()
+            throws Exception {
+        String testDirectory = "TestDirectory1";
+        testDirectory = tempDir + testDirectory +File.separator;
+        createTestData(testDirectory);
+        return runProcess("", testDirectory);
+    }
+
+    public static boolean createChildProcessWithParallelCollector()
+            throws Exception {
+        String testDirectory = "TestDirectory2";
+        testDirectory = tempDir + testDirectory +File.separator;
+        createTestData(testDirectory);
+        return runProcess(" -XX:+UseParallelGC", testDirectory);
+    }
+
+    public static boolean runProcess(String arg1, String arg2) throws Exception {
+        String javaPath = System.getProperty("java.home");
+        String classPathDir = System.getProperty("java.class.path");
+
+        //creating java process which run same class with different Xmx value
+        String command = javaPath + File.separator + "bin" + File.separator
+                + "java -Xmx256M" + arg1 + " -cp "
+                + classPathDir
+                + " ShellFolderMemoryLeak " + arg2;
+        process = Runtime.getRuntime().exec(command);
+        BufferedReader input = null;
+        InputStream errorStream = null;
+        String line = null;
+        try {
+            int exitVal = process.waitFor();
+            input = new BufferedReader(new InputStreamReader(
+                    process.getInputStream()));
+            while ((line = input.readLine()) != null) {
+            }
+            errorStream = process.getErrorStream();
+            if (checkExceptions(errorStream) || exitVal != 0) {
+                return false;
+            }
+        } catch (IllegalThreadStateException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (input != null) {
+                input.close();
+            }
+            if (errorStream != null) {
+                errorStream.close();
+            }
+            process.destroy();
+        }
+        return true;
+    }
+
+    public static boolean checkExceptions(InputStream in) throws IOException {
+        String tempString;
+        int count = in.available();
+        boolean exception = false;
+        while (count > 0) {
+            byte[] b = new byte[count];
+            in.read(b);
+            tempString = new String(b);
+            if (!exception) {
+                exception = tempString.contains("RunTimeException");
+            }
+            count = in.available();
+        }
+        return exception;
+    }
+
+    private static void createTestData(String testDirectory) {
+        String folder = "folder_";
+        File testFolder = new File(testDirectory);
+        if (testFolder.exists()) {
+            clearTestData(testDirectory);
+        } else {
+            if (testFolder.mkdir()) {
+                for (int inx = 0; inx < 100; inx++) {
+                    new File(testFolder + File.separator + folder + inx).mkdir();
+                }
+            } else {
+                throw new RuntimeException("Failed to create testDirectory");
+            }
+        }
+    }
+
+    public static void deleteDirectory(File file)
+            throws IOException {
+
+        if (file.isDirectory()) {
+            if (file.list().length == 0) {
+                file.delete();
+            } else {
+                String files[] = file.list();
+                for (String temp : files) {
+                    File fileDelete = new File(file, temp);
+                    deleteDirectory(fileDelete);
+                }
+                if (file.list().length == 0) {
+                    file.delete();
+                }
+            }
+        }
+    }
+
+    private static void testListFile(String testDirectory) {
+        try {
+            int mb = 1024 * 1024;
+            ShellFolder folder = ShellFolder.getShellFolder(
+                    new File(testDirectory));
+            Runtime instance = Runtime.getRuntime();
+
+            //Memory used before calling listFiles
+            long startmem = instance.totalMemory() - instance.freeMemory();
+            long start = System.currentTimeMillis();
+            long endmem = 0;
+
+            //Calling listFiles for 5 minutes with sleep of 10 ms.
+            while ((System.currentTimeMillis() - start) < 300000) {
+                try {
+                    folder.listFiles();
+                    Thread.sleep(10);
+                    endmem = instance.totalMemory() - instance.freeMemory();
+                } catch (InterruptedException ex) {
+                    Logger.getLogger(ShellFolderMemoryLeak.class.getName())
+                            .log(Level.SEVERE, "InterruptedException", ex);
+                }
+            }
+
+            //Total increase in memory after 5 minutes
+            long result = (endmem - startmem) / mb;
+
+            if (result > 100) {
+                clearTestData(testDirectory);
+                throw new RuntimeException("Test Failed");
+            }
+            clearTestData(testDirectory);
+        } catch (FileNotFoundException ex) {
+            if(process != null && process.isAlive()) {
+                process.destroy();
+            }
+            Logger.getLogger(ShellFolderMemoryLeak.class.getName())
+                    .log(Level.SEVERE, "File Not Found Exception", ex);
+        }
+    }
+
+    private static void clearTestData(String testDirectory) {
+        File testFolder = new File(testDirectory);
+        try {
+            deleteDirectory(testFolder);
+        } catch (IOException ex) {
+            Logger.getLogger(ShellFolderMemoryLeak.class.getName())
+                    .log(Level.SEVERE, "Unable to delete files", ex);
+        }
+    }
+}
\ No newline at end of file