From 8357de88aa35ee998fefe321ee6dae9eb4993fa6 Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Fri, 10 Apr 2026 13:07:00 +0000 Subject: [PATCH] 8334868: Ensure CheckUninstallModalHook is called in WPageDialogPeer._show Ensure AwtDialog::CheckInstallModalHook and AwtDialog::ModalActivateNextWindow are always called after ::PageSetupDlg returns. Reverse the condition of the if statement and bail out if ::PageSetupDlg returns an error. Remove the doIt flag and use explicit returns: * JNI_FALSE if an error detected; * JNI_TRUE if the function reached its end without errors. Reviewed-by: dmarkov, prr --- .../native/libawt/windows/awt_PrintJob.cpp | 169 +++++++++--------- .../PrinterJob/PageDialogCancelTest.java | 9 +- .../PrinterJob/PageDialogFormatTest.java | 63 +++++++ 3 files changed, 152 insertions(+), 89 deletions(-) create mode 100644 test/jdk/java/awt/print/PrinterJob/PageDialogFormatTest.java diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp index 8d016d8b39f..b18fa5a7e2c 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2026, 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 @@ -522,7 +522,6 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) AwtComponent *awtParent = (parent != NULL) ? (AwtComponent *)JNI_GET_PDATA(parent) : NULL; HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL; - jboolean doIt = JNI_FALSE; PAGESETUPDLG setup; memset(&setup, 0, sizeof(setup)); @@ -578,7 +577,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) */ if ((setup.hDevMode == NULL) && (setup.hDevNames == NULL)) { CLEANUP_SHOW; - return doIt; + return JNI_FALSE; } } else { int measure = PSD_INTHOUSANDTHSOFINCHES; @@ -606,7 +605,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) pageFormatToSetup(env, self, page, &setup, AwtPrintControl::getPrintDC(env, self)); if (env->ExceptionCheck()) { CLEANUP_SHOW; - return doIt; + return JNI_FALSE; } setup.lpfnPageSetupHook = reinterpret_cast(pageDlgHook); @@ -615,89 +614,91 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) AwtDialog::CheckInstallModalHook(); BOOL ret = ::PageSetupDlg(&setup); - if (ret) { - - jobject paper = getPaper(env, page); - if (paper == NULL) { - CLEANUP_SHOW; - return doIt; - } - int units = setup.Flags & PSD_INTHOUSANDTHSOFINCHES ? - MM_HIENGLISH : - MM_HIMETRIC; - POINT paperSize; - RECT margins; - jint orientation; - - /* The printer may have been changed, and we track that change, - * but then need to get a new DC for the current printer so that - * we validate the paper size correctly - */ - if (setup.hDevNames != NULL) { - DEVNAMES* names = (DEVNAMES*)::GlobalLock(setup.hDevNames); - if (names != NULL) { - LPTSTR printer = (LPTSTR)names+names->wDeviceOffset; - SAVE_CONTROLWORD - HDC newDC = ::CreateDC(TEXT("WINSPOOL"), printer, NULL, NULL); - RESTORE_CONTROLWORD - if (newDC != NULL) { - HDC oldDC = AwtPrintControl::getPrintDC(env, self); - if (oldDC != NULL) { - ::DeleteDC(oldDC); - } - } - AwtPrintControl::setPrintDC(env, self, newDC); - } - ::GlobalUnlock(setup.hDevNames); - } - - /* Get the Windows paper and margins description. - */ - retrievePaperInfo(&setup, &paperSize, &margins, &orientation, - AwtPrintControl::getPrintDC(env, self)); - - /* Convert the Windows' paper and margins description - * and place them into a Paper instance. - */ - setPaperValues(env, paper, &paperSize, &margins, units); - if (env->ExceptionCheck()) { - CLEANUP_SHOW; - return doIt; - } - /* - * Put the updated Paper instance and the orientation into - * the PageFormat. - */ - setPaper(env, page, paper); - if (env->ExceptionCheck()) { - CLEANUP_SHOW; - return doIt; - } - setPageFormatOrientation(env, page, orientation); - if (env->ExceptionCheck()) { - CLEANUP_SHOW; - return JNI_FALSE; - } - if (setup.hDevMode != NULL) { - DEVMODE *devmode = (DEVMODE *)::GlobalLock(setup.hDevMode); - if (devmode != NULL) { - if (devmode->dmFields & DM_PAPERSIZE) { - jboolean err = setPrintPaperSize(env, self, devmode->dmPaperSize); - if (err) { - CLEANUP_SHOW; - return doIt; - } - } - } - ::GlobalUnlock(setup.hDevMode); - } - doIt = JNI_TRUE; - } AwtDialog::CheckUninstallModalHook(); - AwtDialog::ModalActivateNextWindow(NULL, target, peer); + if (!ret) { + CLEANUP_SHOW; + return JNI_FALSE; + } + + jobject paper = getPaper(env, page); + if (paper == NULL) { + CLEANUP_SHOW; + return JNI_FALSE; + } + int units = setup.Flags & PSD_INTHOUSANDTHSOFINCHES ? + MM_HIENGLISH : + MM_HIMETRIC; + POINT paperSize; + RECT margins; + jint orientation; + + /* The printer may have been changed, and we track that change, + * but then need to get a new DC for the current printer so that + * we validate the paper size correctly + */ + if (setup.hDevNames != NULL) { + DEVNAMES* names = (DEVNAMES*)::GlobalLock(setup.hDevNames); + if (names != NULL) { + LPTSTR printer = (LPTSTR)names+names->wDeviceOffset; + SAVE_CONTROLWORD + HDC newDC = ::CreateDC(TEXT("WINSPOOL"), printer, NULL, NULL); + RESTORE_CONTROLWORD + if (newDC != NULL) { + HDC oldDC = AwtPrintControl::getPrintDC(env, self); + if (oldDC != NULL) { + ::DeleteDC(oldDC); + } + } + AwtPrintControl::setPrintDC(env, self, newDC); + } + ::GlobalUnlock(setup.hDevNames); + } + + /* Get the Windows paper and margins description. + */ + retrievePaperInfo(&setup, &paperSize, &margins, &orientation, + AwtPrintControl::getPrintDC(env, self)); + + /* Convert the Windows' paper and margins description + * and place them into a Paper instance. + */ + setPaperValues(env, paper, &paperSize, &margins, units); + if (env->ExceptionCheck()) { + CLEANUP_SHOW; + return JNI_FALSE; + } + /* + * Put the updated Paper instance and the orientation into + * the PageFormat. + */ + setPaper(env, page, paper); + if (env->ExceptionCheck()) { + CLEANUP_SHOW; + return JNI_FALSE; + } + setPageFormatOrientation(env, page, orientation); + if (env->ExceptionCheck()) { + CLEANUP_SHOW; + return JNI_FALSE; + } + if (setup.hDevMode != NULL) { + DEVMODE *devmode = (DEVMODE *)::GlobalLock(setup.hDevMode); + if (devmode != NULL) { + if (devmode->dmFields & DM_PAPERSIZE) { + jboolean err = setPrintPaperSize(env, self, devmode->dmPaperSize); + if (err) { + ::GlobalUnlock(setup.hDevMode); + CLEANUP_SHOW; + return JNI_FALSE; + } + } + } + ::GlobalUnlock(setup.hDevMode); + } + HGLOBAL oldG = AwtPrintControl::getPrintHDMode(env, self); if (setup.hDevMode != oldG) { AwtPrintControl::setPrintHDMode(env, self, setup.hDevMode); @@ -710,7 +711,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) CLEANUP_SHOW; - return doIt; + return JNI_TRUE; CATCH_BAD_ALLOC_RET(0); } diff --git a/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java b/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java index f9ce1b7c196..fc3d251cb6c 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, 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 @@ -23,10 +23,10 @@ /* * @test - * @bug 8334366 + * @bug 8334366 8334868 * @key headful printer - * @summary Verifies original pageobject is returned unmodified - * on cancelling pagedialog + * @summary Verifies original PageFormat object is returned unmodified + * if PrinterJob.pageDialog is cancelled * @requires (os.family == "windows") * @run main PageDialogCancelTest */ @@ -55,4 +55,3 @@ public class PageDialogCancelTest { } } } - diff --git a/test/jdk/java/awt/print/PrinterJob/PageDialogFormatTest.java b/test/jdk/java/awt/print/PrinterJob/PageDialogFormatTest.java new file mode 100644 index 00000000000..b727ba12928 --- /dev/null +++ b/test/jdk/java/awt/print/PrinterJob/PageDialogFormatTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024, 2026, 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 8334366 8334868 + * @key headful printer + * @summary Verifies PageFormat object returned from PrinterJob.pageDialog + * changes to landscape orientation when "Landscape" is selected + * @requires (os.family == "windows") + * @run main PageDialogFormatTest + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.print.PageFormat; +import java.awt.print.PrinterJob; + +public class PageDialogFormatTest { + + public static void main(String[] args) throws Exception { + PrinterJob pj = PrinterJob.getPrinterJob(); + PageFormat oldFormat = new PageFormat(); + Robot robot = new Robot(); + Thread t1 = new Thread(() -> { + robot.delay(2000); + // Select Landscape orientation + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_ALT); + // Press OK + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.waitForIdle(); + }); + t1.start(); + PageFormat newFormat = pj.pageDialog(oldFormat); + if (newFormat.getOrientation() != PageFormat.LANDSCAPE) { + throw new RuntimeException("PageFormat didn't change to landscape"); + } + } +}