--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/macosx/native/sun/awt/CPrinterJob.m Tue Mar 06 20:34:38 2012 +0000
@@ -0,0 +1,661 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+
+#import "java_awt_print_PageFormat.h"
+#import "java_awt_print_Pageable.h"
+#import "sun_lwawt_macosx_CPrinterJob.h"
+#import "sun_lwawt_macosx_CPrinterPageDialog.h"
+
+#import <Cocoa/Cocoa.h>
+#import <JavaNativeFoundation/JavaNativeFoundation.h>
+
+#import "PrinterView.h"
+#import "PrintModel.h"
+#import "ThreadUtilities.h"
+#import "GeomUtilities.h"
+
+static JNF_CLASS_CACHE(sjc_Paper, "java/awt/print/Paper");
+static JNF_CLASS_CACHE(sjc_PageFormat, "java/awt/print/PageFormat");
+static JNF_CLASS_CACHE(sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob");
+static JNF_CLASS_CACHE(sjc_CPrinterDialog, "sun/lwawt/macosx/CPrinterDialog");
+static JNF_MEMBER_CACHE(sjm_getNSPrintInfo, sjc_CPrinterJob, "getNSPrintInfo", "()J");
+static JNF_MEMBER_CACHE(sjm_printerJob, sjc_CPrinterDialog, "fPrinterJob", "Lsun/lwawt/macosx/CPrinterJob;");
+
+static NSPrintInfo* createDefaultNSPrintInfo();
+
+static void makeBestFit(NSPrintInfo* src);
+
+static void nsPrintInfoToJavaPaper(JNIEnv* env, NSPrintInfo* src, jobject dst);
+static void javaPaperToNSPrintInfo(JNIEnv* env, jobject src, NSPrintInfo* dst);
+
+static void nsPrintInfoToJavaPageFormat(JNIEnv* env, NSPrintInfo* src, jobject dst);
+static void javaPageFormatToNSPrintInfo(JNIEnv* env, jobject srcPrinterJob, jobject srcPageFormat, NSPrintInfo* dst);
+
+static void nsPrintInfoToJavaPrinterJob(JNIEnv* env, NSPrintInfo* src, jobject dstPrinterJob, jobject dstPageable);
+static void javaPrinterJobToNSPrintInfo(JNIEnv* env, jobject srcPrinterJob, jobject srcPageable, NSPrintInfo* dst);
+
+
+static NSPrintInfo* createDefaultNSPrintInfo(JNIEnv* env, jstring printer)
+{
+ NSPrintInfo* defaultPrintInfo = [[NSPrintInfo sharedPrintInfo] copy];
+ if (printer != NULL)
+ {
+ NSPrinter* nsPrinter = [NSPrinter printerWithName:JNFJavaToNSString(env, printer)];
+ if (nsPrinter != nil)
+ {
+ [defaultPrintInfo setPrinter:nsPrinter];
+ }
+ }
+ [defaultPrintInfo setUpPrintOperationDefaultValues];
+
+ // cmc 05/18/04 radr://3160443 : setUpPrintOperationDefaultValues sets the
+ // page margins to 72, 72, 90, 90 - need to use [NSPrintInfo imageablePageBounds]
+ // to get values from the printer.
+ // NOTE: currently [NSPrintInfo imageablePageBounds] does not update itself when
+ // the user selects a different printer - see radr://3657453. However, rather than
+ // directly querying the PPD here, we'll let AppKit printing do the work. The AppKit
+ // printing bug above is set to be fixed for Tiger.
+ NSRect imageableRect = [defaultPrintInfo imageablePageBounds];
+ [defaultPrintInfo setLeftMargin: imageableRect.origin.x];
+ [defaultPrintInfo setBottomMargin: imageableRect.origin.y]; //top and bottom are flipped because [NSPrintInfo imageablePageBounds] returns a flipped NSRect (bottom-left to top-right).
+ [defaultPrintInfo setRightMargin: [defaultPrintInfo paperSize].width-imageableRect.origin.x-imageableRect.size.width];
+ [defaultPrintInfo setTopMargin: [defaultPrintInfo paperSize].height-imageableRect.origin.y-imageableRect.size.height];
+
+ return defaultPrintInfo;
+}
+
+static void makeBestFit(NSPrintInfo* src)
+{
+ // This will look at the NSPrintInfo's margins. If they are out of bounds to the
+ // imageable area of the page, it will set them to the largest possible size.
+
+ NSRect imageable = [src imageablePageBounds];
+
+ NSSize paperSize = [src paperSize];
+
+ CGFloat fullLeftM = imageable.origin.x;
+ CGFloat fullRightM = paperSize.width - (imageable.origin.x + imageable.size.width);
+
+ // These are flipped because [NSPrintInfo imageablePageBounds] returns a flipped
+ // NSRect (bottom-left to top-right).
+ CGFloat fullTopM = paperSize.height - (imageable.origin.y + imageable.size.height);
+ CGFloat fullBottomM = imageable.origin.y;
+
+ if (fullLeftM > [src leftMargin])
+ {
+ [src setLeftMargin:fullLeftM];
+ }
+
+ if (fullRightM > [src rightMargin])
+ {
+ [src setRightMargin:fullRightM];
+ }
+
+ if (fullTopM > [src topMargin])
+ {
+ [src setTopMargin:fullTopM];
+ }
+
+ if (fullBottomM > [src bottomMargin])
+ {
+ [src setBottomMargin:fullBottomM];
+ }
+}
+
+// In AppKit Printing, the rectangle is always oriented. In AppKit Printing, setting
+// the rectangle will always set the orientation.
+// In java printing, the rectangle is oriented if accessed from PageFormat. It is
+// not oriented when accessed from Paper.
+
+static void nsPrintInfoToJavaPaper(JNIEnv* env, NSPrintInfo* src, jobject dst)
+{
+ static JNF_MEMBER_CACHE(jm_setSize, sjc_Paper, "setSize", "(DD)V");
+ static JNF_MEMBER_CACHE(jm_setImageableArea, sjc_Paper, "setImageableArea", "(DDDD)V");
+
+ jdouble jPaperW, jPaperH;
+
+ // NSPrintInfo paperSize is oriented. java Paper is not oriented. Take
+ // the -[NSPrintInfo orientation] into account when setting the Paper
+ // rectangle.
+
+ NSSize paperSize = [src paperSize];
+ switch ([src orientation]) {
+ case NSPortraitOrientation:
+ jPaperW = paperSize.width;
+ jPaperH = paperSize.height;
+ break;
+
+ case NSLandscapeOrientation:
+ jPaperW = paperSize.height;
+ jPaperH = paperSize.width;
+ break;
+
+ default:
+ jPaperW = paperSize.width;
+ jPaperH = paperSize.height;
+ break;
+ }
+
+ JNFCallVoidMethod(env, dst, jm_setSize, jPaperW, jPaperH); // AWT_THREADING Safe (known object - always actual Paper)
+
+ // Set the imageable area from the margins
+ CGFloat leftM = [src leftMargin];
+ CGFloat rightM = [src rightMargin];
+ CGFloat topM = [src topMargin];
+ CGFloat bottomM = [src bottomMargin];
+
+ jdouble jImageX = leftM;
+ jdouble jImageY = topM;
+ jdouble jImageW = jPaperW - (leftM + rightM);
+ jdouble jImageH = jPaperH - (topM + bottomM);
+
+ JNFCallVoidMethod(env, dst, jm_setImageableArea, jImageX, jImageY, jImageW, jImageH); // AWT_THREADING Safe (known object - always actual Paper)
+}
+
+static void javaPaperToNSPrintInfo(JNIEnv* env, jobject src, NSPrintInfo* dst)
+{
+ AWT_ASSERT_NOT_APPKIT_THREAD;
+
+ static JNF_MEMBER_CACHE(jm_getWidth, sjc_Paper, "getWidth", "()D");
+ static JNF_MEMBER_CACHE(jm_getHeight, sjc_Paper, "getHeight", "()D");
+ static JNF_MEMBER_CACHE(jm_getImageableX, sjc_Paper, "getImageableX", "()D");
+ static JNF_MEMBER_CACHE(jm_getImageableY, sjc_Paper, "getImageableY", "()D");
+ static JNF_MEMBER_CACHE(jm_getImageableW, sjc_Paper, "getImageableWidth", "()D");
+ static JNF_MEMBER_CACHE(jm_getImageableH, sjc_Paper, "getImageableHeight", "()D");
+
+ // java Paper is always Portrait oriented. Set NSPrintInfo with this
+ // rectangle, and it's orientation may change. If necessary, be sure to call
+ // -[NSPrintInfo setOrientation] after this call, which will then
+ // adjust the -[NSPrintInfo paperSize] as well.
+
+ jdouble jPhysicalWidth = JNFCallDoubleMethod(env, src, jm_getWidth); // AWT_THREADING Safe (!appKit)
+ jdouble jPhysicalHeight = JNFCallDoubleMethod(env, src, jm_getHeight); // AWT_THREADING Safe (!appKit)
+
+ [dst setPaperSize:NSMakeSize(jPhysicalWidth, jPhysicalHeight)];
+
+ // Set the margins from the imageable area
+ jdouble jImageX = JNFCallDoubleMethod(env, src, jm_getImageableX); // AWT_THREADING Safe (!appKit)
+ jdouble jImageY = JNFCallDoubleMethod(env, src, jm_getImageableY); // AWT_THREADING Safe (!appKit)
+ jdouble jImageW = JNFCallDoubleMethod(env, src, jm_getImageableW); // AWT_THREADING Safe (!appKit)
+ jdouble jImageH = JNFCallDoubleMethod(env, src, jm_getImageableH); // AWT_THREADING Safe (!appKit)
+
+ [dst setLeftMargin:(CGFloat)jImageX];
+ [dst setTopMargin:(CGFloat)jImageY];
+ [dst setRightMargin:(CGFloat)(jPhysicalWidth - jImageW - jImageX)];
+ [dst setBottomMargin:(CGFloat)(jPhysicalHeight - jImageH - jImageY)];
+}
+
+static void nsPrintInfoToJavaPageFormat(JNIEnv* env, NSPrintInfo* src, jobject dst)
+{
+ AWT_ASSERT_NOT_APPKIT_THREAD;
+
+ static JNF_MEMBER_CACHE(jm_setOrientation, sjc_PageFormat, "setOrientation", "(I)V");
+ static JNF_MEMBER_CACHE(jm_setPaper, sjc_PageFormat, "setPaper", "(Ljava/awt/print/Paper;)V");
+ static JNF_CTOR_CACHE(jm_Paper_ctor, sjc_Paper, "()V");
+
+ jint jOrientation;
+ NSPrintingOrientation nsOrientation = [src orientation];
+ switch (nsOrientation) {
+ case NSPortraitOrientation:
+ jOrientation = java_awt_print_PageFormat_PORTRAIT;
+ break;
+
+ case NSLandscapeOrientation:
+ jOrientation = java_awt_print_PageFormat_LANDSCAPE; //+++gdb Are LANDSCAPE and REVERSE_LANDSCAPE still inverted?
+ break;
+
+/*
+ // AppKit printing doesn't support REVERSE_LANDSCAPE. Radar 2960295.
+ case NSReverseLandscapeOrientation:
+ jOrientation = java_awt_print_PageFormat.REVERSE_LANDSCAPE; //+++gdb Are LANDSCAPE and REVERSE_LANDSCAPE still inverted?
+ break;
+*/
+
+ default:
+ jOrientation = java_awt_print_PageFormat_PORTRAIT;
+ break;
+ }
+
+ JNFCallVoidMethod(env, dst, jm_setOrientation, jOrientation); // AWT_THREADING Safe (!appKit)
+
+ // Create a new Paper
+ jobject paper = JNFNewObject(env, jm_Paper_ctor); // AWT_THREADING Safe (known object)
+
+ nsPrintInfoToJavaPaper(env, src, paper);
+
+ // Set the Paper in the PageFormat
+ JNFCallVoidMethod(env, dst, jm_setPaper, paper); // AWT_THREADING Safe (!appKit)
+
+ (*env)->DeleteLocalRef(env, paper);
+}
+
+static void javaPageFormatToNSPrintInfo(JNIEnv* env, jobject srcPrintJob, jobject srcPageFormat, NSPrintInfo* dstPrintInfo)
+{
+ AWT_ASSERT_NOT_APPKIT_THREAD;
+
+ static JNF_MEMBER_CACHE(jm_getOrientation, sjc_PageFormat, "getOrientation", "()I");
+ static JNF_MEMBER_CACHE(jm_getPaper, sjc_PageFormat, "getPaper", "()Ljava/awt/print/Paper;");
+ static JNF_MEMBER_CACHE(jm_getPrinterName, sjc_CPrinterJob, "getPrinterName", "()Ljava/lang/String;");
+
+ // When setting page information (orientation, size) in NSPrintInfo, set the
+ // rectangle first. This is because setting the orientation will change the
+ // rectangle to match.
+
+ // Set up the paper. This will force Portrait since java Paper is
+ // not oriented. Then setting the NSPrintInfo orientation below
+ // will flip NSPrintInfo's info as necessary.
+ jobject paper = JNFCallObjectMethod(env, srcPageFormat, jm_getPaper); // AWT_THREADING Safe (!appKit)
+ javaPaperToNSPrintInfo(env, paper, dstPrintInfo);
+ (*env)->DeleteLocalRef(env, paper);
+
+ switch (JNFCallIntMethod(env, srcPageFormat, jm_getOrientation)) { // AWT_THREADING Safe (!appKit)
+ case java_awt_print_PageFormat_PORTRAIT:
+ [dstPrintInfo setOrientation:NSPortraitOrientation];
+ break;
+
+ case java_awt_print_PageFormat_LANDSCAPE:
+ [dstPrintInfo setOrientation:NSLandscapeOrientation]; //+++gdb Are LANDSCAPE and REVERSE_LANDSCAPE still inverted?
+ break;
+
+ // AppKit printing doesn't support REVERSE_LANDSCAPE. Radar 2960295.
+ case java_awt_print_PageFormat_REVERSE_LANDSCAPE:
+ [dstPrintInfo setOrientation:NSLandscapeOrientation]; //+++gdb Are LANDSCAPE and REVERSE_LANDSCAPE still inverted?
+ break;
+
+ default:
+ [dstPrintInfo setOrientation:NSPortraitOrientation];
+ break;
+ }
+
+ // <rdar://problem/4022422> NSPrinterInfo is not correctly set to the selected printer
+ // from the Java side of CPrinterJob. Has always assumed the default printer was the one we wanted.
+ if (srcPrintJob == NULL) return;
+ jobject printerNameObj = JNFCallObjectMethod(env, srcPrintJob, jm_getPrinterName);
+ if (printerNameObj == NULL) return;
+ NSString *printerName = JNFJavaToNSString(env, printerNameObj);
+ if (printerName == nil) return;
+ NSPrinter *printer = [NSPrinter printerWithName:printerName];
+ if (printer == nil) return;
+ [dstPrintInfo setPrinter:printer];
+}
+
+static void nsPrintInfoToJavaPrinterJob(JNIEnv* env, NSPrintInfo* src, jobject dstPrinterJob, jobject dstPageable)
+{
+ static JNF_MEMBER_CACHE(jm_setService, sjc_CPrinterJob, "setPrinterServiceFromNative", "(Ljava/lang/String;)V");
+ static JNF_MEMBER_CACHE(jm_setCopies, sjc_CPrinterJob, "setCopies", "(I)V");
+ static JNF_MEMBER_CACHE(jm_setCollated, sjc_CPrinterJob, "setCollated", "(Z)V");
+ static JNF_MEMBER_CACHE(jm_setPageRange, sjc_CPrinterJob, "setPageRange", "(II)V");
+
+ // get the selected printer's name, and set the appropriate PrintService on the Java side
+ NSString *name = [[src printer] name];
+ jstring printerName = JNFNSToJavaString(env, name);
+ JNFCallVoidMethod(env, dstPrinterJob, jm_setService, printerName);
+
+
+ NSMutableDictionary* printingDictionary = [src dictionary];
+
+ NSNumber* nsCopies = [printingDictionary objectForKey:NSPrintCopies];
+ if ([nsCopies respondsToSelector:@selector(integerValue)])
+ {
+ JNFCallVoidMethod(env, dstPrinterJob, jm_setCopies, [nsCopies integerValue]); // AWT_THREADING Safe (known object)
+ }
+
+ NSNumber* nsCollated = [printingDictionary objectForKey:NSPrintMustCollate];
+ if ([nsCollated respondsToSelector:@selector(boolValue)])
+ {
+ JNFCallVoidMethod(env, dstPrinterJob, jm_setCollated, [nsCollated boolValue] ? JNI_TRUE : JNI_FALSE); // AWT_THREADING Safe (known object)
+ }
+
+ NSNumber* nsPrintAllPages = [printingDictionary objectForKey:NSPrintAllPages];
+ if ([nsPrintAllPages respondsToSelector:@selector(boolValue)])
+ {
+ jint jFirstPage = 0, jLastPage = java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES;
+ if (![nsPrintAllPages boolValue])
+ {
+ NSNumber* nsFirstPage = [printingDictionary objectForKey:NSPrintFirstPage];
+ if ([nsFirstPage respondsToSelector:@selector(integerValue)])
+ {
+ jFirstPage = [nsFirstPage integerValue] - 1;
+ }
+
+ NSNumber* nsLastPage = [printingDictionary objectForKey:NSPrintLastPage];
+ if ([nsLastPage respondsToSelector:@selector(integerValue)])
+ {
+ jLastPage = [nsLastPage integerValue] - 1;
+ }
+ }
+
+ JNFCallVoidMethod(env, dstPrinterJob, jm_setPageRange, jFirstPage, jLastPage); // AWT_THREADING Safe (known object)
+ }
+}
+
+static void javaPrinterJobToNSPrintInfo(JNIEnv* env, jobject srcPrinterJob, jobject srcPageable, NSPrintInfo* dst)
+{
+ AWT_ASSERT_NOT_APPKIT_THREAD;
+
+ static JNF_CLASS_CACHE(jc_Pageable, "java/awt/print/Pageable");
+ static JNF_MEMBER_CACHE(jm_getCopies, sjc_CPrinterJob, "getCopiesInt", "()I");
+ static JNF_MEMBER_CACHE(jm_isCollated, sjc_CPrinterJob, "isCollated", "()Z");
+ static JNF_MEMBER_CACHE(jm_getNumberOfPages, jc_Pageable, "getNumberOfPages", "()I");
+
+ NSMutableDictionary* printingDictionary = [dst dictionary];
+
+ jint copies = JNFCallIntMethod(env, srcPrinterJob, jm_getCopies); // AWT_THREADING Safe (known object)
+ [printingDictionary setObject:[NSNumber numberWithInteger:copies] forKey:NSPrintCopies];
+
+ jboolean collated = JNFCallBooleanMethod(env, srcPrinterJob, jm_isCollated); // AWT_THREADING Safe (known object)
+ [printingDictionary setObject:[NSNumber numberWithBool:collated ? YES : NO] forKey:NSPrintMustCollate];
+
+ jint jNumPages = JNFCallIntMethod(env, srcPageable, jm_getNumberOfPages); // AWT_THREADING Safe (!appKit)
+ if (jNumPages != java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES)
+ {
+ [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
+
+ [printingDictionary setObject:[NSNumber numberWithInteger:1] forKey:NSPrintFirstPage];
+ [printingDictionary setObject:[NSNumber numberWithInteger:jNumPages] forKey:NSPrintLastPage];
+ }
+ else
+ {
+ [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
+ }
+}
+
+/*
+ * Class: sun_lwawt_macosx_EventDispatchAccess
+ * Method: pumpEventsAndWait
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_EventDispatchAccess_pumpEventsAndWait
+(JNIEnv *env, jobject eda)
+{
+ static JNF_CLASS_CACHE(jc_Thread, "java/lang/Thread");
+ static JNF_STATIC_MEMBER_CACHE(jm_currentThread, jc_Thread, "currentThread", "()Ljava/lang/Thread;");
+ static JNF_CLASS_CACHE(jc_EventDispatchThread, "java/awt/EventDispatchThread");
+ static JNF_MEMBER_CACHE(jm_macosxGetConditional, jc_EventDispatchThread, "_macosxGetConditional", "(Ljava/lang/Object;)Ljava/awt/Conditional;");
+ static JNF_MEMBER_CACHE(jm_pumpEvents, jc_EventDispatchThread, "pumpEvents", "(Ljava/awt/Conditional;)V");
+
+JNF_COCOA_DURING(env);
+
+ jobject thread = JNFCallStaticObjectMethod(env, jm_currentThread);
+ jobject conditional = JNFCallObjectMethod(env, thread, jm_macosxGetConditional, eda);
+ if (conditional != NULL) {
+ JNFCallVoidMethod(env, thread, jm_pumpEvents, conditional);
+ }
+
+JNF_COCOA_HANDLE(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPrinterJob
+ * Method: abortDoc
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob_abortDoc
+ (JNIEnv *env, jobject jthis)
+{
+JNF_COCOA_ENTER(env);
+ // This is only called during the printLoop from the printLoop thread
+ NSPrintOperation* printLoop = [NSPrintOperation currentOperation];
+ NSPrintInfo* printInfo = [printLoop printInfo];
+ [printInfo setJobDisposition:NSPrintCancelJob];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPrinterJob
+ * Method: getDefaultPage
+ * Signature: (Ljava/awt/print/PageFormat;)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob_getDefaultPage
+ (JNIEnv *env, jobject jthis, jobject page)
+{
+JNF_COCOA_ENTER(env);
+ NSPrintInfo* printInfo = createDefaultNSPrintInfo(env, NULL);
+
+ nsPrintInfoToJavaPageFormat(env, printInfo, page);
+
+ [printInfo release];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPrinterJob
+ * Method: validatePaper
+ * Signature: (Ljava/awt/print/Paper;Ljava/awt/print/Paper;)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob_validatePaper
+ (JNIEnv *env, jobject jthis, jobject origpaper, jobject newpaper)
+{
+JNF_COCOA_ENTER(env);
+
+ NSPrintInfo* printInfo = createDefaultNSPrintInfo(env, NULL);
+ javaPaperToNSPrintInfo(env, origpaper, printInfo);
+ makeBestFit(printInfo);
+ nsPrintInfoToJavaPaper(env, printInfo, newpaper);
+ [printInfo release];
+
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPrinterJob
+ * Method: createNSPrintInfo
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPrinterJob_createNSPrintInfo
+ (JNIEnv *env, jobject jthis)
+{
+ jlong result = -1;
+JNF_COCOA_ENTER(env);
+ // This is used to create the NSPrintInfo for this PrinterJob. Thread
+ // safety is assured by the java side of this call.
+
+ NSPrintInfo* printInfo = createDefaultNSPrintInfo(env, NULL);
+ if (printInfo) CFRetain(printInfo); // GC
+ [printInfo release];
+
+ result = ptr_to_jlong(printInfo);
+
+JNF_COCOA_EXIT(env);
+ return result;
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPrinterJob
+ * Method: dispose
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob_dispose
+ (JNIEnv *env, jobject jthis, jlong nsPrintInfo)
+{
+JNF_COCOA_ENTER(env);
+ if (nsPrintInfo != -1)
+ {
+ NSPrintInfo* printInfo = (NSPrintInfo*)jlong_to_ptr(nsPrintInfo);
+ if (printInfo) CFRelease(printInfo); // GC
+ }
+JNF_COCOA_EXIT(env);
+}
+
+
+/*
+ * Class: sun_lwawt_macosx_CPrinterJob
+ * Method: printLoop
+ * Signature: ()V
+ */
+JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPrinterJob_printLoop
+ (JNIEnv *env, jobject jthis, jboolean blocks, jint firstPage, jint lastPage)
+{
+ AWT_ASSERT_NOT_APPKIT_THREAD;
+
+ static JNF_MEMBER_CACHE(jm_getPageFormat, sjc_CPrinterJob, "getPageFormat", "(I)Ljava/awt/print/PageFormat;");
+ static JNF_MEMBER_CACHE(jm_getPageFormatArea, sjc_CPrinterJob, "getPageFormatArea", "(Ljava/awt/print/PageFormat;)Ljava/awt/geom/Rectangle2D;");
+ static JNF_MEMBER_CACHE(jm_getPrinterName, sjc_CPrinterJob, "getPrinterName", "()Ljava/lang/String;");
+ static JNF_MEMBER_CACHE(jm_getPageable, sjc_CPrinterJob, "getPageable", "()Ljava/awt/print/Pageable;");
+
+ jboolean retVal = JNI_FALSE;
+
+JNF_COCOA_ENTER(env);
+ // Get the first page's PageFormat for setting things up (This introduces
+ // and is a facet of the same problem in Radar 2818593/2708932).
+ jobject page = JNFCallObjectMethod(env, jthis, jm_getPageFormat, 0); // AWT_THREADING Safe (!appKit)
+ if (page != NULL) {
+ jobject pageFormatArea = JNFCallObjectMethod(env, jthis, jm_getPageFormatArea, page); // AWT_THREADING Safe (!appKit)
+
+ PrinterView* printerView = [[PrinterView alloc] initWithFrame:JavaToNSRect(env, pageFormatArea) withEnv:env withPrinterJob:jthis];
+ [printerView setFirstPage:firstPage lastPage:lastPage];
+
+ NSPrintInfo* printInfo = (NSPrintInfo*)jlong_to_ptr(JNFCallLongMethod(env, jthis, sjm_getNSPrintInfo)); // AWT_THREADING Safe (known object)
+
+ // <rdar://problem/4156975> passing jthis CPrinterJob as well, so we can extract the printer name from the current job
+ javaPageFormatToNSPrintInfo(env, jthis, page, printInfo);
+
+ // <rdar://problem/4093799> NSPrinterInfo is not correctly set to the selected printer
+ // from the Java side of CPrinterJob. Had always assumed the default printer was the one we wanted.
+ jobject printerNameObj = JNFCallObjectMethod(env, jthis, jm_getPrinterName);
+ if (printerNameObj != NULL) {
+ NSString *printerName = JNFJavaToNSString(env, printerNameObj);
+ if (printerName != nil) {
+ NSPrinter *printer = [NSPrinter printerWithName:printerName];
+ if (printer != nil) [printInfo setPrinter:printer];
+ }
+ }
+
+ // <rdar://problem/4367998> JTable.print attributes are ignored
+ jobject pageable = JNFCallObjectMethod(env, jthis, jm_getPageable); // AWT_THREADING Safe (!appKit)
+ javaPrinterJobToNSPrintInfo(env, jthis, pageable, printInfo);
+
+ PrintModel* printModel = [[PrintModel alloc] initWithPrintInfo:printInfo];
+
+ (void)[printModel runPrintLoopWithView:printerView waitUntilDone:blocks withEnv:env];
+
+ // Only set this if we got far enough to call runPrintLoopWithView, or we will spin CPrinterJob.print() forever!
+ retVal = JNI_TRUE;
+
+ [printModel release];
+ [printerView release];
+
+ if (page != NULL)
+ {
+ (*env)->DeleteLocalRef(env, page);
+ }
+
+ if (pageFormatArea != NULL)
+ {
+ (*env)->DeleteLocalRef(env, pageFormatArea);
+ }
+ }
+JNF_COCOA_EXIT(env);
+ return retVal;
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPrinterPageDialog
+ * Method: showDialog
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPrinterPageDialog_showDialog
+ (JNIEnv *env, jobject jthis)
+{
+
+ static JNF_CLASS_CACHE(jc_CPrinterPageDialog, "sun/lwawt/macosx/CPrinterPageDialog");
+ static JNF_MEMBER_CACHE(jm_page, jc_CPrinterPageDialog, "fPage", "Ljava/awt/print/PageFormat;");
+
+ jboolean result = JNI_FALSE;
+JNF_COCOA_ENTER(env);
+ jobject printerJob = JNFGetObjectField(env, jthis, sjm_printerJob);
+ NSPrintInfo* printInfo = (NSPrintInfo*)jlong_to_ptr(JNFCallLongMethod(env, printerJob, sjm_getNSPrintInfo)); // AWT_THREADING Safe (known object)
+
+ jobject page = JNFGetObjectField(env, jthis, jm_page);
+
+ // <rdar://problem/4156975> passing NULL, because only a CPrinterJob has a real printer associated with it
+ javaPageFormatToNSPrintInfo(env, NULL, page, printInfo);
+
+ PrintModel* printModel = [[PrintModel alloc] initWithPrintInfo:printInfo];
+ result = [printModel runPageSetup];
+ [printModel release];
+
+ if (result)
+ {
+ nsPrintInfoToJavaPageFormat(env, printInfo, page);
+ }
+
+ if (printerJob != NULL)
+ {
+ (*env)->DeleteLocalRef(env, printerJob);
+ }
+
+ if (page != NULL)
+ {
+ (*env)->DeleteLocalRef(env, page);
+ }
+
+JNF_COCOA_EXIT(env);
+ return result;
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPrinterJobDialog
+ * Method: showDialog
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPrinterJobDialog_showDialog
+ (JNIEnv *env, jobject jthis)
+{
+ static JNF_CLASS_CACHE(jc_CPrinterJobDialog, "sun/lwawt/macosx/CPrinterJobDialog");
+ static JNF_MEMBER_CACHE(jm_pageable, jc_CPrinterJobDialog, "fPageable", "Ljava/awt/print/Pageable;");
+
+ jboolean result = JNI_FALSE;
+JNF_COCOA_ENTER(env);
+ jobject printerJob = JNFGetObjectField(env, jthis, sjm_printerJob);
+ NSPrintInfo* printInfo = (NSPrintInfo*)jlong_to_ptr(JNFCallLongMethod(env, printerJob, sjm_getNSPrintInfo)); // AWT_THREADING Safe (known object)
+
+ jobject pageable = JNFGetObjectField(env, jthis, jm_pageable);
+
+ javaPrinterJobToNSPrintInfo(env, printerJob, pageable, printInfo);
+
+ PrintModel* printModel = [[PrintModel alloc] initWithPrintInfo:printInfo];
+ result = [printModel runJobSetup];
+ [printModel release];
+
+ if (result)
+ {
+ nsPrintInfoToJavaPrinterJob(env, printInfo, printerJob, pageable);
+ }
+
+ if (printerJob != NULL)
+ {
+ (*env)->DeleteLocalRef(env, printerJob);
+ }
+
+ if (pageable != NULL)
+ {
+ (*env)->DeleteLocalRef(env, pageable);
+ }
+
+JNF_COCOA_EXIT(env);
+ return result;
+}