diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsConfig.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsConfig.java index d1e41c2c9249..0eeb65d0e3cf 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsConfig.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsConfig.java @@ -218,11 +218,9 @@ public class Win32GraphicsConfig extends GraphicsConfiguration return (super.toString()+"[dev="+device+",pixfmt="+visual+"]"); } - private native Rectangle getBounds(int screen); - @Override public Rectangle getBounds() { - return getBounds(device.getScreen()); + return device.getBounds(); } @Override diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java index 5fc34c05e4d5..d8ab98c5736f 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java @@ -106,11 +106,12 @@ public class Win32GraphicsDevice extends GraphicsDevice implements 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); + private native void initDevice(int screen); + private static native void initNativeScale(int screen); + private static native void setNativeScale(int screen, float scaleX, float scaleY); + private static native float getNativeScaleX(int screen); + private static native float getNativeScaleY(int screen); + private static native Rectangle getBounds(int screen); public Win32GraphicsDevice(int screennum) { this.screen = screennum; @@ -169,6 +170,10 @@ public class Win32GraphicsDevice extends GraphicsDevice implements } } + public Rectangle getBounds() { + return getBounds(getScreen()); + } + /** * Returns whether this is a valid device. Device can become * invalid as a result of device removal event. @@ -256,7 +261,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements } } - private native int getMaxConfigsImpl(int screen); + private static native int getMaxConfigsImpl(int screen); /** * Returns whether or not the PixelFormat indicated by index is @@ -268,7 +273,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements * are disabled. Do not call this function with an index of 0. * @param index a PixelFormat index */ - private native boolean isPixFmtSupported(int index, int screen); + private static native boolean isPixFmtSupported(int index, int screen); /** * Returns the PixelFormatID of the default graphics configuration @@ -287,7 +292,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements * Returns the default PixelFormat ID from GDI. Do not call if PixelFormats * are disabled. */ - private native int getDefaultPixIDImpl(int screen); + private static native int getDefaultPixIDImpl(int screen); /** * Returns the default graphics configuration @@ -541,9 +546,8 @@ public class Win32GraphicsDevice extends GraphicsDevice implements dynamicColorModel = null; defaultConfig = null; configs = null; - initScaleFactors(); - Rectangle screenBounds = getDefaultConfiguration().getBounds(); + Rectangle screenBounds = getBounds(); resizeFSWindow(getFullScreenWindow(), screenBounds); // pass on to all top-level windows on this display @@ -577,8 +581,8 @@ public class Win32GraphicsDevice extends GraphicsDevice implements /** * Creates and returns the color model associated with this device */ - private native ColorModel makeColorModel (int screen, - boolean dynamic); + private static native ColorModel makeColorModel(int screen, + boolean dynamic); /** * Returns a dynamic ColorModel which is updated when there diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java index ea006a39a173..2a7825f8847f 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java @@ -31,6 +31,7 @@ import java.awt.GraphicsDevice; import java.awt.peer.ComponentPeer; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Arrays; import java.util.ListIterator; import sun.awt.windows.WToolkit; @@ -147,41 +148,23 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment { */ @Override public void displayChanged() { + if (screens != null) { + if (oldDevices == null) { + oldDevices = new ArrayList<>(); + } + for (int i = 0; i < screens.length; i++) { + if (screens[i] instanceof Win32GraphicsDevice gd) { + oldDevices.add(new WeakReference<>(gd)); + } else { + // REMIND: can we ever have anything other than Win32GD? + assert (false) : screens[i]; + } + } + } + // create the new devices // getNumScreens() will return the correct current number of screens GraphicsDevice[] newDevices = new GraphicsDevice[getNumScreens()]; - GraphicsDevice[] oldScreens = screens; - // go through the list of current devices and determine if they - // could be reused, or will have to be replaced - if (oldScreens != null) { - for (int i = 0; i < oldScreens.length; i++) { - if (!(screens[i] instanceof Win32GraphicsDevice)) { - // REMIND: can we ever have anything other than Win32GD? - assert (false) : oldScreens[i]; - continue; - } - Win32GraphicsDevice gd = (Win32GraphicsDevice)oldScreens[i]; - // devices may be invalidated from the native code when the - // display change happens (device add/removal also causes a - // display change) - if (!gd.isValid()) { - if (oldDevices == null) { - oldDevices = - new ArrayList>(); - } - oldDevices.add(new WeakReference(gd)); - } else if (i < newDevices.length) { - // reuse the device - newDevices[i] = gd; - } - } - oldScreens = null; - } - // create the new devices (those that weren't reused) - for (int i = 0; i < newDevices.length; i++) { - if (newDevices[i] == null) { - newDevices[i] = makeScreenDevice(i); - } - } + Arrays.setAll(newDevices, this::makeScreenDevice); // install the new array of devices // Note: no synchronization here, it doesn't matter if a thread gets // a new or an old array this time around diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java index de115a0002bb..1e0d12b56f57 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java @@ -631,6 +631,14 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, AWTAccessor.getComponentAccessor(). setGraphicsConfiguration((Component)target, winGraphicsConfig); + + // Windows may have already sent us WM_PAINT, + // which we have processed before updating the GC, + // so force full repaint just to be sure we don't leave damaged content. + if (oldDev != newDev) { + Rectangle b = getBounds(); + handlePaint(0, 0, b.width, b.height); + } } /** diff --git a/src/java.desktop/windows/native/libawt/windows/Devices.cpp b/src/java.desktop/windows/native/libawt/windows/Devices.cpp index f36914e4606c..ed9d5065d0d1 100644 --- a/src/java.desktop/windows/native/libawt/windows/Devices.cpp +++ b/src/java.desktop/windows/native/libawt/windows/Devices.cpp @@ -214,6 +214,7 @@ BOOL Devices::UpdateInstance(JNIEnv *env) } for (i = 0; i < numScreens; ++i) { rawDevices[i]->Initialize(); + rawDevices[i]->InitDesktopScales(); } { CriticalSection::Lock l(arrayLock); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp index 6e54ca567a08..ff98dea1bbfd 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp @@ -912,6 +912,20 @@ void AwtToolkit::DestroyComponentHWND(HWND hwnd) void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment); #endif +static BOOL CALLBACK UpdateAllThreadWindowSizes(HWND hWnd, LPARAM) +{ + TRY; + AwtComponent *c = AwtComponent::GetComponent(hWnd); + if (c) { + RECT r; + GetWindowRect(hWnd, &r); + c->WmSize(SIZENORMAL, r.right-r.left, r.bottom-r.top); + c->Invalidate(NULL); + } + return TRUE; + CATCH_BAD_ALLOC_RET(FALSE); +} + /* * An AwtToolkit window is just a means of routing toolkit messages to here. */ @@ -1302,6 +1316,7 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, case WM_DISPLAYCHANGE: { // Reinitialize screens initScreens(env); + ::EnumThreadWindows(MainThread(), (WNDENUMPROC)UpdateAllThreadWindowSizes, 0); // Notify Java side - call WToolkit.displayChanged() jclass clazz = env->FindClass("sun/awt/windows/WToolkit"); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp index 463c1fdee10d..acb3cbfde33d 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp @@ -76,50 +76,3 @@ inline int shiftToMask(int numBits, int shift) { mask = mask << shift; return mask; } - -/* - * Class: sun_awt_Win32GraphicsConfig - * Method: getBounds - * Signature: ()Ljava/awt/Rectangle - */ -JNIEXPORT jobject JNICALL - Java_sun_awt_Win32GraphicsConfig_getBounds(JNIEnv *env, jobject thisobj, - jint screen) -{ - jclass clazz; - jmethodID mid; - jobject bounds = NULL; - - clazz = env->FindClass("java/awt/Rectangle"); - CHECK_NULL_RETURN(clazz, NULL); - mid = env->GetMethodID(clazz, "", "(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)) { - 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, rRW.left, rRW.top, 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, - device == NULL ? w : device->ScaleDownX(w), - device == NULL ? h : device->ScaleDownY(h)); - } - if (safe_ExceptionOccurred(env)) { - return 0; - } - } - return bounds; -} diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp index 223d1a8d60c2..a4fbb205e106 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp @@ -1017,7 +1017,7 @@ Java_sun_awt_Win32GraphicsDevice_initIDs(JNIEnv *env, jclass cls) */ JNIEXPORT jint JNICALL Java_sun_awt_Win32GraphicsDevice_getMaxConfigsImpl - (JNIEnv* jniEnv, jobject theThis, jint screen) { + (JNIEnv* jniEnv, jclass clazz, jint screen) { TRY; HDC hDC = AwtWin32GraphicsDevice::GetDCFromScreen(screen); @@ -1044,7 +1044,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_Win32GraphicsDevice_getMaxConfigsImpl */ JNIEXPORT jboolean JNICALL Java_sun_awt_Win32GraphicsDevice_isPixFmtSupported - (JNIEnv* env, jobject theThis, jint pixFmtID, jint screen) { + (JNIEnv* env, jclass clazz, jint pixFmtID, jint screen) { TRY; jboolean suppColor = JNI_TRUE; HDC hDC = AwtWin32GraphicsDevice::GetDCFromScreen(screen); @@ -1086,7 +1086,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_Win32GraphicsDevice_isPixFmtSupported */ JNIEXPORT jint JNICALL Java_sun_awt_Win32GraphicsDevice_getDefaultPixIDImpl - (JNIEnv* env, jobject theThis, jint screen) { + (JNIEnv* env, jclass clazz, jint screen) { TRY; int pixFmtID = 0; HDC hDC = AwtWin32GraphicsDevice::GetDCFromScreen(screen); @@ -1118,7 +1118,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_Win32GraphicsDevice_getDefaultPixIDImpl } if (JNI_FALSE == Java_sun_awt_Win32GraphicsDevice_isPixFmtSupported( - env, theThis, pixFmtID, screen)) { + env, clazz, pixFmtID, screen)) { /* Can't find a suitable pixel format ID. Fall back on 0. */ pixFmtID = 0; } @@ -1415,7 +1415,7 @@ JNIEXPORT void JNICALL Java_sun_awt_Win32GraphicsDevice_enumDisplayModes JNIEXPORT jobject JNICALL Java_sun_awt_Win32GraphicsDevice_makeColorModel - (JNIEnv *env, jobject thisPtr, jint screen, jboolean dynamic) + (JNIEnv *env, jclass clazz, jint screen, jboolean dynamic) { Devices::InstanceAccess devices; return devices->GetDevice(screen)->GetColorModel(env, dynamic); @@ -1428,10 +1428,10 @@ JNIEXPORT jobject JNICALL */ JNIEXPORT void JNICALL Java_sun_awt_Win32GraphicsDevice_initDevice - (JNIEnv *env, jobject thisPtr, jint screen) + (JNIEnv *env, jobject graphicsDevice, jint screen) { Devices::InstanceAccess devices; - devices->GetDevice(screen)->SetJavaDevice(env, thisPtr); + devices->GetDevice(screen)->SetJavaDevice(env, graphicsDevice); } /* @@ -1441,7 +1441,7 @@ JNIEXPORT void JNICALL */ JNIEXPORT void JNICALL Java_sun_awt_Win32GraphicsDevice_setNativeScale - (JNIEnv *env, jobject thisPtr, jint screen, jfloat scaleX, jfloat scaleY) + (JNIEnv *env, jclass clazz, jint screen, jfloat scaleX, jfloat scaleY) { Devices::InstanceAccess devices; AwtWin32GraphicsDevice *device = devices->GetDevice(screen); @@ -1459,7 +1459,7 @@ JNIEXPORT void JNICALL */ JNIEXPORT jfloat JNICALL Java_sun_awt_Win32GraphicsDevice_getNativeScaleX - (JNIEnv *env, jobject thisPtr, jint screen) + (JNIEnv *env, jclass clazz, jint screen) { Devices::InstanceAccess devices; AwtWin32GraphicsDevice *device = devices->GetDevice(screen); @@ -1473,7 +1473,7 @@ JNIEXPORT jfloat JNICALL */ JNIEXPORT jfloat JNICALL Java_sun_awt_Win32GraphicsDevice_getNativeScaleY - (JNIEnv *env, jobject thisPtr, jint screen) + (JNIEnv *env, jclass clazz, jint screen) { Devices::InstanceAccess devices; AwtWin32GraphicsDevice *device = devices->GetDevice(screen); @@ -1487,7 +1487,7 @@ JNIEXPORT jfloat JNICALL */ JNIEXPORT void JNICALL Java_sun_awt_Win32GraphicsDevice_initNativeScale -(JNIEnv *env, jobject thisPtr, jint screen) +(JNIEnv *env, jclass clazz, jint screen) { Devices::InstanceAccess devices; AwtWin32GraphicsDevice *device = devices->GetDevice(screen); @@ -1496,3 +1496,48 @@ Java_sun_awt_Win32GraphicsDevice_initNativeScale device->InitDesktopScales(); } } + +/* + * Class: sun_awt_Win32GraphicsDevice + * Method: getBounds + * Signature: (I)Ljava/awt/Rectangle + */ +JNIEXPORT jobject JNICALL + Java_sun_awt_Win32GraphicsDevice_getBounds(JNIEnv *env, jclass clazz, jint screen) +{ + jmethodID mid; + jobject bounds = NULL; + + clazz = env->FindClass("java/awt/Rectangle"); + CHECK_NULL_RETURN(clazz, NULL); + mid = env->GetMethodID(clazz, "", "(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)) { + 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, rRW.left, rRW.top, 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, + device == NULL ? w : device->ScaleDownX(w), + device == NULL ? h : device->ScaleDownY(h)); + } + if (safe_ExceptionOccurred(env)) { + return 0; + } + } + return bounds; +}