Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m
41152 views
/*1* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/242526#import "java_awt_print_PageFormat.h"27#import "java_awt_print_Pageable.h"28#import "sun_lwawt_macosx_CPrinterJob.h"29#import "sun_lwawt_macosx_CPrinterPageDialog.h"3031#import <Cocoa/Cocoa.h>3233#import "PrinterView.h"34#import "PrintModel.h"35#import "ThreadUtilities.h"36#import "GeomUtilities.h"37#import "JNIUtilities.h"3839static jclass sjc_Paper = NULL;40static jclass sjc_PageFormat = NULL;41static jclass sjc_CPrinterJob = NULL;42static jclass sjc_CPrinterDialog = NULL;43static jmethodID sjm_getNSPrintInfo = NULL;44static jmethodID sjm_printerJob = NULL;4546#define GET_PAPER_CLASS() GET_CLASS(sjc_Paper, "java/awt/print/Paper");47#define GET_PAGEFORMAT_CLASS() GET_CLASS(sjc_PageFormat, "java/awt/print/PageFormat");48#define GET_CPRINTERDIALOG_CLASS() GET_CLASS(sjc_CPrinterDialog, "sun/lwawt/macosx/CPrinterDialog");49#define GET_CPRINTERDIALOG_CLASS_RETURN(ret) GET_CLASS_RETURN(sjc_CPrinterDialog, "sun/lwawt/macosx/CPrinterDialog", ret);50#define GET_CPRINTERJOB_CLASS() GET_CLASS(sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob");51#define GET_CPRINTERJOB_CLASS_RETURN(ret) GET_CLASS_RETURN(sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob", ret);5253#define GET_NSPRINTINFO_METHOD_RETURN(ret) \54GET_CPRINTERJOB_CLASS_RETURN(ret); \55GET_METHOD_RETURN(sjm_getNSPrintInfo, sjc_CPrinterJob, "getNSPrintInfo", "()J", ret);5657#define GET_CPRINTERDIALOG_FIELD_RETURN(ret) \58GET_CPRINTERDIALOG_CLASS_RETURN(ret); \59GET_FIELD_RETURN(sjm_printerJob, sjc_CPrinterDialog, "fPrinterJob", "Lsun/lwawt/macosx/CPrinterJob;", ret);6061static NSPrintInfo* createDefaultNSPrintInfo();6263static void makeBestFit(NSPrintInfo* src);6465static void nsPrintInfoToJavaPaper(JNIEnv* env, NSPrintInfo* src, jobject dst);66static void javaPaperToNSPrintInfo(JNIEnv* env, jobject src, NSPrintInfo* dst);6768static void nsPrintInfoToJavaPageFormat(JNIEnv* env, NSPrintInfo* src, jobject dst);69static void javaPageFormatToNSPrintInfo(JNIEnv* env, jobject srcPrinterJob, jobject srcPageFormat, NSPrintInfo* dst);7071static void nsPrintInfoToJavaPrinterJob(JNIEnv* env, NSPrintInfo* src, jobject dstPrinterJob, jobject dstPageable);72static void javaPrinterJobToNSPrintInfo(JNIEnv* env, jobject srcPrinterJob, jobject srcPageable, NSPrintInfo* dst);737475#ifdef __MAC_10_9 // code for SDK 10.9 or newer76#define NS_PORTRAIT NSPaperOrientationPortrait77#define NS_LANDSCAPE NSPaperOrientationLandscape78#else // code for SDK 10.8 or older79#define NS_PORTRAIT NSPortraitOrientation80#define NS_LANDSCAPE NSLandscapeOrientation81#endif8283static NSPrintInfo* createDefaultNSPrintInfo(JNIEnv* env, jstring printer)84{85NSPrintInfo* defaultPrintInfo = [[NSPrintInfo sharedPrintInfo] copy];86if (printer != NULL)87{88NSPrinter* nsPrinter = [NSPrinter printerWithName:JavaStringToNSString(env, printer)];89if (nsPrinter != nil)90{91[defaultPrintInfo setPrinter:nsPrinter];92}93}94[defaultPrintInfo setUpPrintOperationDefaultValues];9596// cmc 05/18/04 radr://3160443 : setUpPrintOperationDefaultValues sets the97// page margins to 72, 72, 90, 90 - need to use [NSPrintInfo imageablePageBounds]98// to get values from the printer.99// NOTE: currently [NSPrintInfo imageablePageBounds] does not update itself when100// the user selects a different printer - see radr://3657453. However, rather than101// directly querying the PPD here, we'll let AppKit printing do the work. The AppKit102// printing bug above is set to be fixed for Tiger.103NSRect imageableRect = [defaultPrintInfo imageablePageBounds];104[defaultPrintInfo setLeftMargin: imageableRect.origin.x];105[defaultPrintInfo setBottomMargin: imageableRect.origin.y]; //top and bottom are flipped because [NSPrintInfo imageablePageBounds] returns a flipped NSRect (bottom-left to top-right).106[defaultPrintInfo setRightMargin: [defaultPrintInfo paperSize].width-imageableRect.origin.x-imageableRect.size.width];107[defaultPrintInfo setTopMargin: [defaultPrintInfo paperSize].height-imageableRect.origin.y-imageableRect.size.height];108109return defaultPrintInfo;110}111112static void makeBestFit(NSPrintInfo* src)113{114// This will look at the NSPrintInfo's margins. If they are out of bounds to the115// imageable area of the page, it will set them to the largest possible size.116117NSRect imageable = [src imageablePageBounds];118119NSSize paperSize = [src paperSize];120121CGFloat fullLeftM = imageable.origin.x;122CGFloat fullRightM = paperSize.width - (imageable.origin.x + imageable.size.width);123124// These are flipped because [NSPrintInfo imageablePageBounds] returns a flipped125// NSRect (bottom-left to top-right).126CGFloat fullTopM = paperSize.height - (imageable.origin.y + imageable.size.height);127CGFloat fullBottomM = imageable.origin.y;128129if (fullLeftM > [src leftMargin])130{131[src setLeftMargin:fullLeftM];132}133134if (fullRightM > [src rightMargin])135{136[src setRightMargin:fullRightM];137}138139if (fullTopM > [src topMargin])140{141[src setTopMargin:fullTopM];142}143144if (fullBottomM > [src bottomMargin])145{146[src setBottomMargin:fullBottomM];147}148}149150// In AppKit Printing, the rectangle is always oriented. In AppKit Printing, setting151// the rectangle will always set the orientation.152// In java printing, the rectangle is oriented if accessed from PageFormat. It is153// not oriented when accessed from Paper.154155static void nsPrintInfoToJavaPaper(JNIEnv* env, NSPrintInfo* src, jobject dst)156{157GET_PAGEFORMAT_CLASS();158GET_PAPER_CLASS();159DECLARE_METHOD(jm_setSize, sjc_Paper, "setSize", "(DD)V");160DECLARE_METHOD(jm_setImageableArea, sjc_Paper, "setImageableArea", "(DDDD)V");161162jdouble jPaperW, jPaperH;163164// NSPrintInfo paperSize is oriented. java Paper is not oriented. Take165// the -[NSPrintInfo orientation] into account when setting the Paper166// rectangle.167168NSSize paperSize = [src paperSize];169switch ([src orientation]) {170case NS_PORTRAIT:171jPaperW = paperSize.width;172jPaperH = paperSize.height;173break;174175case NS_LANDSCAPE:176jPaperW = paperSize.height;177jPaperH = paperSize.width;178break;179180default:181jPaperW = paperSize.width;182jPaperH = paperSize.height;183break;184}185186(*env)->CallVoidMethod(env, dst, jm_setSize, jPaperW, jPaperH); // AWT_THREADING Safe (known object - always actual Paper)187CHECK_EXCEPTION();188189// Set the imageable area from the margins190CGFloat leftM = [src leftMargin];191CGFloat rightM = [src rightMargin];192CGFloat topM = [src topMargin];193CGFloat bottomM = [src bottomMargin];194195jdouble jImageX = leftM;196jdouble jImageY = topM;197jdouble jImageW = jPaperW - (leftM + rightM);198jdouble jImageH = jPaperH - (topM + bottomM);199200(*env)->CallVoidMethod(env, dst, jm_setImageableArea, jImageX, jImageY, jImageW, jImageH); // AWT_THREADING Safe (known object - always actual Paper)201CHECK_EXCEPTION();202}203204static void javaPaperToNSPrintInfo(JNIEnv* env, jobject src, NSPrintInfo* dst)205{206AWT_ASSERT_NOT_APPKIT_THREAD;207208GET_PAGEFORMAT_CLASS();209GET_PAPER_CLASS();210DECLARE_METHOD(jm_getWidth, sjc_Paper, "getWidth", "()D");211DECLARE_METHOD(jm_getHeight, sjc_Paper, "getHeight", "()D");212DECLARE_METHOD(jm_getImageableX, sjc_Paper, "getImageableX", "()D");213DECLARE_METHOD(jm_getImageableY, sjc_Paper, "getImageableY", "()D");214DECLARE_METHOD(jm_getImageableW, sjc_Paper, "getImageableWidth", "()D");215DECLARE_METHOD(jm_getImageableH, sjc_Paper, "getImageableHeight", "()D");216217// java Paper is always Portrait oriented. Set NSPrintInfo with this218// rectangle, and it's orientation may change. If necessary, be sure to call219// -[NSPrintInfo setOrientation] after this call, which will then220// adjust the -[NSPrintInfo paperSize] as well.221222jdouble jPhysicalWidth = (*env)->CallDoubleMethod(env, src, jm_getWidth); // AWT_THREADING Safe (!appKit)223CHECK_EXCEPTION();224jdouble jPhysicalHeight = (*env)->CallDoubleMethod(env, src, jm_getHeight); // AWT_THREADING Safe (!appKit)225CHECK_EXCEPTION();226227[dst setPaperSize:NSMakeSize(jPhysicalWidth, jPhysicalHeight)];228229// Set the margins from the imageable area230jdouble jImageX = (*env)->CallDoubleMethod(env, src, jm_getImageableX); // AWT_THREADING Safe (!appKit)231CHECK_EXCEPTION();232jdouble jImageY = (*env)->CallDoubleMethod(env, src, jm_getImageableY); // AWT_THREADING Safe (!appKit)233CHECK_EXCEPTION();234jdouble jImageW = (*env)->CallDoubleMethod(env, src, jm_getImageableW); // AWT_THREADING Safe (!appKit)235CHECK_EXCEPTION();236jdouble jImageH = (*env)->CallDoubleMethod(env, src, jm_getImageableH); // AWT_THREADING Safe (!appKit)237CHECK_EXCEPTION();238239[dst setLeftMargin:(CGFloat)jImageX];240[dst setTopMargin:(CGFloat)jImageY];241[dst setRightMargin:(CGFloat)(jPhysicalWidth - jImageW - jImageX)];242[dst setBottomMargin:(CGFloat)(jPhysicalHeight - jImageH - jImageY)];243}244245static void nsPrintInfoToJavaPageFormat(JNIEnv* env, NSPrintInfo* src, jobject dst)246{247AWT_ASSERT_NOT_APPKIT_THREAD;248249GET_CPRINTERJOB_CLASS();250GET_PAGEFORMAT_CLASS();251GET_PAPER_CLASS();252DECLARE_METHOD(jm_setOrientation, sjc_PageFormat, "setOrientation", "(I)V");253DECLARE_METHOD(jm_setPaper, sjc_PageFormat, "setPaper", "(Ljava/awt/print/Paper;)V");254DECLARE_METHOD(jm_Paper_ctor, sjc_Paper, "<init>", "()V");255256jint jOrientation;257switch ([src orientation]) {258case NS_PORTRAIT:259jOrientation = java_awt_print_PageFormat_PORTRAIT;260break;261262case NS_LANDSCAPE:263jOrientation = java_awt_print_PageFormat_LANDSCAPE; //+++gdb Are LANDSCAPE and REVERSE_LANDSCAPE still inverted?264break;265266/*267// AppKit printing doesn't support REVERSE_LANDSCAPE. Radar 2960295.268case NSReverseLandscapeOrientation:269jOrientation = java_awt_print_PageFormat.REVERSE_LANDSCAPE; //+++gdb Are LANDSCAPE and REVERSE_LANDSCAPE still inverted?270break;271*/272273default:274jOrientation = java_awt_print_PageFormat_PORTRAIT;275break;276}277278(*env)->CallVoidMethod(env, dst, jm_setOrientation, jOrientation); // AWT_THREADING Safe (!appKit)279CHECK_EXCEPTION();280281// Create a new Paper282jobject paper = (*env)->NewObject(env, sjc_Paper, jm_Paper_ctor); // AWT_THREADING Safe (known object)283CHECK_EXCEPTION();284if (paper == NULL) {285return;286}287288nsPrintInfoToJavaPaper(env, src, paper);289290// Set the Paper in the PageFormat291(*env)->CallVoidMethod(env, dst, jm_setPaper, paper); // AWT_THREADING Safe (!appKit)292CHECK_EXCEPTION();293294(*env)->DeleteLocalRef(env, paper);295}296297static void javaPageFormatToNSPrintInfo(JNIEnv* env, jobject srcPrintJob, jobject srcPageFormat, NSPrintInfo* dstPrintInfo)298{299AWT_ASSERT_NOT_APPKIT_THREAD;300301GET_CPRINTERJOB_CLASS();302GET_PAGEFORMAT_CLASS();303GET_PAPER_CLASS();304DECLARE_METHOD(jm_getOrientation, sjc_PageFormat, "getOrientation", "()I");305DECLARE_METHOD(jm_getPaper, sjc_PageFormat, "getPaper", "()Ljava/awt/print/Paper;");306DECLARE_METHOD(jm_getPrinterName, sjc_CPrinterJob, "getPrinterName", "()Ljava/lang/String;");307308// When setting page information (orientation, size) in NSPrintInfo, set the309// rectangle first. This is because setting the orientation will change the310// rectangle to match.311312// Set up the paper. This will force Portrait since java Paper is313// not oriented. Then setting the NSPrintInfo orientation below314// will flip NSPrintInfo's info as necessary.315jobject paper = (*env)->CallObjectMethod(env, srcPageFormat, jm_getPaper); // AWT_THREADING Safe (!appKit)316CHECK_EXCEPTION();317javaPaperToNSPrintInfo(env, paper, dstPrintInfo);318(*env)->DeleteLocalRef(env, paper);319320switch ((*env)->CallIntMethod(env, srcPageFormat, jm_getOrientation)) { // AWT_THREADING Safe (!appKit)321case java_awt_print_PageFormat_PORTRAIT:322[dstPrintInfo setOrientation:NS_PORTRAIT];323break;324325case java_awt_print_PageFormat_LANDSCAPE:326[dstPrintInfo setOrientation:NS_LANDSCAPE]; //+++gdb Are LANDSCAPE and REVERSE_LANDSCAPE still inverted?327break;328329// AppKit printing doesn't support REVERSE_LANDSCAPE. Radar 2960295.330case java_awt_print_PageFormat_REVERSE_LANDSCAPE:331[dstPrintInfo setOrientation:NS_LANDSCAPE]; //+++gdb Are LANDSCAPE and REVERSE_LANDSCAPE still inverted?332break;333334default:335[dstPrintInfo setOrientation:NS_PORTRAIT];336break;337}338CHECK_EXCEPTION();339340// <rdar://problem/4022422> NSPrinterInfo is not correctly set to the selected printer341// from the Java side of CPrinterJob. Has always assumed the default printer was the one we wanted.342if (srcPrintJob == NULL) return;343jobject printerNameObj = (*env)->CallObjectMethod(env, srcPrintJob, jm_getPrinterName);344CHECK_EXCEPTION();345if (printerNameObj == NULL) return;346NSString *printerName = JavaStringToNSString(env, printerNameObj);347if (printerName == nil) return;348NSPrinter *printer = [NSPrinter printerWithName:printerName];349if (printer == nil) return;350[dstPrintInfo setPrinter:printer];351}352353static void nsPrintInfoToJavaPrinterJob(JNIEnv* env, NSPrintInfo* src, jobject dstPrinterJob, jobject dstPageable)354{355GET_CPRINTERJOB_CLASS();356DECLARE_METHOD(jm_setService, sjc_CPrinterJob, "setPrinterServiceFromNative", "(Ljava/lang/String;)V");357DECLARE_METHOD(jm_setCopiesAttribute, sjc_CPrinterJob, "setCopiesAttribute", "(I)V");358DECLARE_METHOD(jm_setCollated, sjc_CPrinterJob, "setCollated", "(Z)V");359DECLARE_METHOD(jm_setPageRangeAttribute, sjc_CPrinterJob, "setPageRangeAttribute", "(IIZ)V");360DECLARE_METHOD(jm_setPrintToFile, sjc_CPrinterJob, "setPrintToFile", "(Z)V");361DECLARE_METHOD(jm_setDestinationFile, sjc_CPrinterJob, "setDestinationFile", "(Ljava/lang/String;)V");362363// get the selected printer's name, and set the appropriate PrintService on the Java side364NSString *name = [[src printer] name];365jstring printerName = NSStringToJavaString(env, name);366(*env)->CallVoidMethod(env, dstPrinterJob, jm_setService, printerName);367CHECK_EXCEPTION();368369NSMutableDictionary* printingDictionary = [src dictionary];370371if (src.jobDisposition == NSPrintSaveJob) {372(*env)->CallVoidMethod(env, dstPrinterJob, jm_setPrintToFile, true);373CHECK_EXCEPTION();374NSURL *url = [printingDictionary objectForKey:NSPrintJobSavingURL];375NSString *nsStr = [url absoluteString];376jstring str = NSStringToJavaString(env, nsStr);377(*env)->CallVoidMethod(env, dstPrinterJob, jm_setDestinationFile, str);378CHECK_EXCEPTION();379} else {380(*env)->CallVoidMethod(env, dstPrinterJob, jm_setPrintToFile, false);381CHECK_EXCEPTION();382}383384NSNumber* nsCopies = [printingDictionary objectForKey:NSPrintCopies];385if ([nsCopies respondsToSelector:@selector(integerValue)])386{387(*env)->CallVoidMethod(env, dstPrinterJob, jm_setCopiesAttribute, [nsCopies integerValue]); // AWT_THREADING Safe (known object)388CHECK_EXCEPTION();389}390391NSNumber* nsCollated = [printingDictionary objectForKey:NSPrintMustCollate];392if ([nsCollated respondsToSelector:@selector(boolValue)])393{394(*env)->CallVoidMethod(env, dstPrinterJob, jm_setCollated, [nsCollated boolValue] ? JNI_TRUE : JNI_FALSE); // AWT_THREADING Safe (known object)395CHECK_EXCEPTION();396}397398NSNumber* nsPrintAllPages = [printingDictionary objectForKey:NSPrintAllPages];399if ([nsPrintAllPages respondsToSelector:@selector(boolValue)])400{401jint jFirstPage = 0, jLastPage = java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES;402jboolean isRangeSet = false;403if (![nsPrintAllPages boolValue])404{405NSNumber* nsFirstPage = [printingDictionary objectForKey:NSPrintFirstPage];406if ([nsFirstPage respondsToSelector:@selector(integerValue)])407{408jFirstPage = [nsFirstPage integerValue] - 1;409}410411NSNumber* nsLastPage = [printingDictionary objectForKey:NSPrintLastPage];412if ([nsLastPage respondsToSelector:@selector(integerValue)])413{414jLastPage = [nsLastPage integerValue] - 1;415}416isRangeSet = true;417}418(*env)->CallVoidMethod(env, dstPrinterJob, jm_setPageRangeAttribute,419jFirstPage, jLastPage, isRangeSet); // AWT_THREADING Safe (known object)420CHECK_EXCEPTION();421422}423}424425static void javaPrinterJobToNSPrintInfo(JNIEnv* env, jobject srcPrinterJob, jobject srcPageable, NSPrintInfo* dst)426{427AWT_ASSERT_NOT_APPKIT_THREAD;428429DECLARE_CLASS(jc_Pageable, "java/awt/print/Pageable");430DECLARE_METHOD(jm_getCopies, sjc_CPrinterJob, "getCopiesInt", "()I");431DECLARE_METHOD(jm_isCollated, sjc_CPrinterJob, "isCollated", "()Z");432DECLARE_METHOD(jm_getFromPage, sjc_CPrinterJob, "getFromPageAttrib", "()I");433DECLARE_METHOD(jm_getToPage, sjc_CPrinterJob, "getToPageAttrib", "()I");434DECLARE_METHOD(jm_getMinPage, sjc_CPrinterJob, "getMinPageAttrib", "()I");435DECLARE_METHOD(jm_getMaxPage, sjc_CPrinterJob, "getMaxPageAttrib", "()I");436DECLARE_METHOD(jm_getSelectAttrib, sjc_CPrinterJob, "getSelectAttrib", "()I");437DECLARE_METHOD(jm_getNumberOfPages, jc_Pageable, "getNumberOfPages", "()I");438DECLARE_METHOD(jm_getPageFormat, sjc_CPrinterJob, "getPageFormatFromAttributes", "()Ljava/awt/print/PageFormat;");439DECLARE_METHOD(jm_getDestinationFile, sjc_CPrinterJob, "getDestinationFile", "()Ljava/lang/String;");440441NSMutableDictionary* printingDictionary = [dst dictionary];442443jint copies = (*env)->CallIntMethod(env, srcPrinterJob, jm_getCopies); // AWT_THREADING Safe (known object)444CHECK_EXCEPTION();445[printingDictionary setObject:[NSNumber numberWithInteger:copies] forKey:NSPrintCopies];446447jboolean collated = (*env)->CallBooleanMethod(env, srcPrinterJob, jm_isCollated); // AWT_THREADING Safe (known object)448CHECK_EXCEPTION();449[printingDictionary setObject:[NSNumber numberWithBool:collated ? YES : NO] forKey:NSPrintMustCollate];450jint selectID = (*env)->CallIntMethod(env, srcPrinterJob, jm_getSelectAttrib);451CHECK_EXCEPTION();452jint fromPage = (*env)->CallIntMethod(env, srcPrinterJob, jm_getFromPage);453CHECK_EXCEPTION();454jint toPage = (*env)->CallIntMethod(env, srcPrinterJob, jm_getToPage);455CHECK_EXCEPTION();456if (selectID ==0) {457[printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];458} else if (selectID == 2) {459// In Mac 10.7, Print ALL is deselected if PrintSelection is YES whether460// NSPrintAllPages is YES or NO461[printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];462[printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintSelectionOnly];463} else {464jint minPage = (*env)->CallIntMethod(env, srcPrinterJob, jm_getMinPage);465CHECK_EXCEPTION();466jint maxPage = (*env)->CallIntMethod(env, srcPrinterJob, jm_getMaxPage);467CHECK_EXCEPTION();468469// for PD_SELECTION or PD_NOSELECTION, check from/to page470// to determine which radio button to select471if (fromPage > minPage || toPage < maxPage) {472[printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];473} else {474[printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];475}476}477478// setting fromPage and toPage will not be shown in the dialog if printing All pages479[printingDictionary setObject:[NSNumber numberWithInteger:fromPage] forKey:NSPrintFirstPage];480[printingDictionary setObject:[NSNumber numberWithInteger:toPage] forKey:NSPrintLastPage];481482jobject page = (*env)->CallObjectMethod(env, srcPrinterJob, jm_getPageFormat);483CHECK_EXCEPTION();484if (page != NULL) {485javaPageFormatToNSPrintInfo(env, NULL, page, dst);486}487488jstring dest = (*env)->CallObjectMethod(env, srcPrinterJob, jm_getDestinationFile);489CHECK_EXCEPTION();490if (dest != NULL) {491[dst setJobDisposition:NSPrintSaveJob];492NSString *nsDestStr = JavaStringToNSString(env, dest);493NSURL *nsURL = [NSURL fileURLWithPath:nsDestStr isDirectory:NO];494[printingDictionary setObject:nsURL forKey:NSPrintJobSavingURL];495} else {496[dst setJobDisposition:NSPrintSpoolJob];497}498}499500/*501* Class: sun_lwawt_macosx_CPrinterJob502* Method: abortDoc503* Signature: ()V504*/505JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob_abortDoc506(JNIEnv *env, jobject jthis)507{508JNI_COCOA_ENTER(env);509// This is only called during the printLoop from the printLoop thread510NSPrintOperation* printLoop = [NSPrintOperation currentOperation];511NSPrintInfo* printInfo = [printLoop printInfo];512[printInfo setJobDisposition:NSPrintCancelJob];513JNI_COCOA_EXIT(env);514}515516/*517* Class: sun_lwawt_macosx_CPrinterJob518* Method: getDefaultPage519* Signature: (Ljava/awt/print/PageFormat;)V520*/521JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob_getDefaultPage522(JNIEnv *env, jobject jthis, jobject page)523{524JNI_COCOA_ENTER(env);525NSPrintInfo* printInfo = createDefaultNSPrintInfo(env, NULL);526527nsPrintInfoToJavaPageFormat(env, printInfo, page);528529[printInfo release];530JNI_COCOA_EXIT(env);531}532533/*534* Class: sun_lwawt_macosx_CPrinterJob535* Method: validatePaper536* Signature: (Ljava/awt/print/Paper;Ljava/awt/print/Paper;)V537*/538JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob_validatePaper539(JNIEnv *env, jobject jthis, jobject origpaper, jobject newpaper)540{541JNI_COCOA_ENTER(env);542543544NSPrintInfo* printInfo = createDefaultNSPrintInfo(env, NULL);545javaPaperToNSPrintInfo(env, origpaper, printInfo);546makeBestFit(printInfo);547nsPrintInfoToJavaPaper(env, printInfo, newpaper);548[printInfo release];549550JNI_COCOA_EXIT(env);551}552553/*554* Class: sun_lwawt_macosx_CPrinterJob555* Method: createNSPrintInfo556* Signature: ()J557*/558JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPrinterJob_createNSPrintInfo559(JNIEnv *env, jobject jthis)560{561jlong result = -1;562JNI_COCOA_ENTER(env);563// This is used to create the NSPrintInfo for this PrinterJob. Thread564// safety is assured by the java side of this call.565566NSPrintInfo* printInfo = createDefaultNSPrintInfo(env, NULL);567568result = ptr_to_jlong(printInfo);569570JNI_COCOA_EXIT(env);571return result;572}573574/*575* Class: sun_lwawt_macosx_CPrinterJob576* Method: dispose577* Signature: (J)V578*/579JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob_dispose580(JNIEnv *env, jobject jthis, jlong nsPrintInfo)581{582JNI_COCOA_ENTER(env);583if (nsPrintInfo != -1)584{585NSPrintInfo* printInfo = (NSPrintInfo*)jlong_to_ptr(nsPrintInfo);586[printInfo release];587}588JNI_COCOA_EXIT(env);589}590591592/*593* Class: sun_lwawt_macosx_CPrinterJob594* Method: printLoop595* Signature: ()V596*/597JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPrinterJob_printLoop598(JNIEnv *env, jobject jthis, jboolean blocks, jint firstPage, jint lastPage)599{600AWT_ASSERT_NOT_APPKIT_THREAD;601602GET_CPRINTERJOB_CLASS_RETURN(NO);603DECLARE_METHOD_RETURN(jm_getPageFormat, sjc_CPrinterJob, "getPageFormat", "(I)Ljava/awt/print/PageFormat;", NO);604DECLARE_METHOD_RETURN(jm_getPageFormatArea, sjc_CPrinterJob, "getPageFormatArea", "(Ljava/awt/print/PageFormat;)Ljava/awt/geom/Rectangle2D;", NO);605DECLARE_METHOD_RETURN(jm_getPrinterName, sjc_CPrinterJob, "getPrinterName", "()Ljava/lang/String;", NO);606DECLARE_METHOD_RETURN(jm_getPageable, sjc_CPrinterJob, "getPageable", "()Ljava/awt/print/Pageable;", NO);607DECLARE_METHOD_RETURN(jm_getPrinterTray, sjc_CPrinterJob, "getPrinterTray", "()Ljava/lang/String;", NO);608609jboolean retVal = JNI_FALSE;610611JNI_COCOA_ENTER(env);612// Get the first page's PageFormat for setting things up (This introduces613// and is a facet of the same problem in Radar 2818593/2708932).614jobject page = (*env)->CallObjectMethod(env, jthis, jm_getPageFormat, 0); // AWT_THREADING Safe (!appKit)615CHECK_EXCEPTION();616if (page != NULL) {617jobject pageFormatArea = (*env)->CallObjectMethod(env, jthis, jm_getPageFormatArea, page); // AWT_THREADING Safe (!appKit)618CHECK_EXCEPTION();619620PrinterView* printerView = [[PrinterView alloc] initWithFrame:JavaToNSRect(env, pageFormatArea) withEnv:env withPrinterJob:jthis];621[printerView setFirstPage:firstPage lastPage:lastPage];622623GET_NSPRINTINFO_METHOD_RETURN(NO)624NSPrintInfo* printInfo = (NSPrintInfo*)jlong_to_ptr((*env)->CallLongMethod(env, jthis, sjm_getNSPrintInfo)); // AWT_THREADING Safe (known object)625CHECK_EXCEPTION();626jobject printerTrayObj = (*env)->CallObjectMethod(env, jthis, jm_getPrinterTray);627CHECK_EXCEPTION();628if (printerTrayObj != NULL) {629NSString *printerTray = JavaStringToNSString(env, printerTrayObj);630if (printerTray != nil) {631[[printInfo printSettings] setObject:printerTray forKey:@"InputSlot"];632}633}634635// <rdar://problem/4156975> passing jthis CPrinterJob as well, so we can extract the printer name from the current job636javaPageFormatToNSPrintInfo(env, jthis, page, printInfo);637638// <rdar://problem/4093799> NSPrinterInfo is not correctly set to the selected printer639// from the Java side of CPrinterJob. Had always assumed the default printer was the one we wanted.640jobject printerNameObj = (*env)->CallObjectMethod(env, jthis, jm_getPrinterName);641CHECK_EXCEPTION();642if (printerNameObj != NULL) {643NSString *printerName = JavaStringToNSString(env, printerNameObj);644if (printerName != nil) {645NSPrinter *printer = [NSPrinter printerWithName:printerName];646if (printer != nil) [printInfo setPrinter:printer];647}648}649650// <rdar://problem/4367998> JTable.print attributes are ignored651jobject pageable = (*env)->CallObjectMethod(env, jthis, jm_getPageable); // AWT_THREADING Safe (!appKit)652CHECK_EXCEPTION();653javaPrinterJobToNSPrintInfo(env, jthis, pageable, printInfo);654655PrintModel* printModel = [[PrintModel alloc] initWithPrintInfo:printInfo];656657(void)[printModel runPrintLoopWithView:printerView waitUntilDone:blocks withEnv:env];658659// Only set this if we got far enough to call runPrintLoopWithView, or we will spin CPrinterJob.print() forever!660retVal = JNI_TRUE;661662[printModel release];663[printerView release];664665if (page != NULL)666{667(*env)->DeleteLocalRef(env, page);668}669670if (pageFormatArea != NULL)671{672(*env)->DeleteLocalRef(env, pageFormatArea);673}674}675JNI_COCOA_EXIT(env);676return retVal;677}678679/*680* Class: sun_lwawt_macosx_CPrinterPageDialog681* Method: showDialog682* Signature: ()Z683*/684JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPrinterPageDialog_showDialog685(JNIEnv *env, jobject jthis)686{687688DECLARE_CLASS_RETURN(jc_CPrinterPageDialog, "sun/lwawt/macosx/CPrinterPageDialog", NO);689DECLARE_FIELD_RETURN(jm_page, jc_CPrinterPageDialog, "fPage", "Ljava/awt/print/PageFormat;", NO);690691jboolean result = JNI_FALSE;692JNI_COCOA_ENTER(env);693GET_CPRINTERDIALOG_FIELD_RETURN(NO);694GET_NSPRINTINFO_METHOD_RETURN(NO)695jobject printerJob = (*env)->GetObjectField(env, jthis, sjm_printerJob);696if (printerJob == NULL) return NO;697NSPrintInfo* printInfo = (NSPrintInfo*)jlong_to_ptr((*env)->CallLongMethod(env, printerJob, sjm_getNSPrintInfo)); // AWT_THREADING Safe (known object)698CHECK_EXCEPTION();699if (printInfo == NULL) return result;700701jobject page = (*env)->GetObjectField(env, jthis, jm_page);702if (page == NULL) return NO;703704// <rdar://problem/4156975> passing NULL, because only a CPrinterJob has a real printer associated with it705javaPageFormatToNSPrintInfo(env, NULL, page, printInfo);706707PrintModel* printModel = [[PrintModel alloc] initWithPrintInfo:printInfo];708result = [printModel runPageSetup];709[printModel release];710711if (result)712{713nsPrintInfoToJavaPageFormat(env, printInfo, page);714}715716if (printerJob != NULL)717{718(*env)->DeleteLocalRef(env, printerJob);719}720721if (page != NULL)722{723(*env)->DeleteLocalRef(env, page);724}725726JNI_COCOA_EXIT(env);727return result;728}729730/*731* Class: sun_lwawt_macosx_CPrinterJobDialog732* Method: showDialog733* Signature: ()Z734*/735JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPrinterJobDialog_showDialog736(JNIEnv *env, jobject jthis)737{738DECLARE_CLASS_RETURN(jc_CPrinterJobDialog, "sun/lwawt/macosx/CPrinterJobDialog", NO);739DECLARE_FIELD_RETURN(jm_pageable, jc_CPrinterJobDialog, "fPageable", "Ljava/awt/print/Pageable;", NO);740741jboolean result = JNI_FALSE;742JNI_COCOA_ENTER(env);743GET_CPRINTERDIALOG_FIELD_RETURN(NO);744jobject printerJob = (*env)->GetObjectField(env, jthis, sjm_printerJob);745if (printerJob == NULL) return NO;746GET_NSPRINTINFO_METHOD_RETURN(NO)747NSPrintInfo* printInfo = (NSPrintInfo*)jlong_to_ptr((*env)->CallLongMethod(env, printerJob, sjm_getNSPrintInfo)); // AWT_THREADING Safe (known object)748749jobject pageable = (*env)->GetObjectField(env, jthis, jm_pageable);750if (pageable == NULL) return NO;751752javaPrinterJobToNSPrintInfo(env, printerJob, pageable, printInfo);753754PrintModel* printModel = [[PrintModel alloc] initWithPrintInfo:printInfo];755result = [printModel runJobSetup];756[printModel release];757758if (result)759{760nsPrintInfoToJavaPrinterJob(env, printInfo, printerJob, pageable);761}762763if (printerJob != NULL)764{765(*env)->DeleteLocalRef(env, printerJob);766}767768if (pageable != NULL)769{770(*env)->DeleteLocalRef(env, pageable);771}772773JNI_COCOA_EXIT(env);774return result;775}776777778