1 /*
   2  * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 
  27 #import "PrintModel.h"
  28 
  29 #import "PrinterView.h"
  30 #import "ThreadUtilities.h"
  31 #import "JNIUtilities.h"
  32 
  33 @implementation PrintModel
  34 
  35 - (id)initWithPrintInfo:(NSPrintInfo*)printInfo {
  36     self = [super init];
  37     if (self) {
  38         fPrintInfo = [printInfo retain];
  39     }
  40 
  41     return self;
  42 }
  43 
  44 - (void)dealloc {
  45     [fPrintInfo release];
  46     fPrintInfo = nil;
  47 
  48     [super dealloc];
  49 }
  50 
  51 - (BOOL)runPageSetup {
  52     __block BOOL fResult = NO;
  53 
  54     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
  55         NSPageLayout* pageLayout = [NSPageLayout pageLayout];
  56         fResult = ([pageLayout runModalWithPrintInfo:fPrintInfo] == NSOKButton);
  57     }];
  58 
  59     return fResult;
  60 }
  61 
  62 - (BOOL)runJobSetup {
  63     __block BOOL fResult = NO;
  64 
  65     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
  66         NSPrintPanel* printPanel = [NSPrintPanel printPanel];
  67         fResult = ([printPanel runModalWithPrintInfo:fPrintInfo] == NSOKButton);
  68     }];
  69 
  70     return fResult;
  71 }
  72 
  73 - (BOOL)runPrintLoopWithView:(NSView*)printerView waitUntilDone:(BOOL)wait withEnv:(JNIEnv *)env
  74 {
  75 AWT_ASSERT_NOT_APPKIT_THREAD;
  76 
  77     BOOL fResult = NO;
  78 
  79     // <rdar://problem/4310184> Because people like to put up modal dialogs during print operations,
  80     // we have to run the print operation on a non-AppKit thread or else we get a deadlock and errors
  81     // the AppKit team believes it's OK for us to call runOperation from non-AppKit threads,
  82     // as long as we don't show any panels, and we don't touch the NSPrintInfo or the NSView from other threads.
  83     if (wait) {
  84         fResult = [self safePrintLoop:printerView withEnv:env];
  85     } else {
  86         // Retain these so they don't go away while we're in Java
  87         [self retain];
  88         [printerView retain];
  89 
  90         DECLARE_CLASS_RETURN(jc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob", NO);
  91         DECLARE_STATIC_METHOD_RETURN(jm_detachPrintLoop, jc_CPrinterJob, "detachPrintLoop", "(JJ)V", NO);
  92         (*env)->CallStaticVoidMethod(env, jc_CPrinterJob, jm_detachPrintLoop, ptr_to_jlong(self), ptr_to_jlong(printerView)); // AWT_THREADING Safe (known object)
  93         CHECK_EXCEPTION();
  94     }
  95 
  96     return fResult;
  97 }
  98 
  99 - (BOOL) safePrintLoop:(id)arg withEnv:(JNIEnv *)env
 100 {
 101 AWT_ASSERT_NOT_APPKIT_THREAD;
 102 
 103     PrinterView* printerView = (PrinterView*)arg;
 104     BOOL fResult;
 105     @try {
 106         NSPrintOperation* printLoop = [NSPrintOperation printOperationWithView:printerView printInfo:fPrintInfo];
 107         [printLoop setShowPanels:NO];    //+++gdb Problem: This will avoid progress bars...
 108         //[printLoop setCanSpawnSeparateThread:YES]; //+++gdb Need to check this...
 109 
 110         fResult = [printLoop runOperation];
 111     } @finally {
 112         // Tell CPrinterJob that things are done.
 113         [printerView complete:env];
 114     }
 115     return fResult;
 116 }
 117 
 118 @end
 119 
 120 /*
 121  * Class:     sun_lwawt_macosx_CPrinterJob
 122  * Method:    _safePrintLoop
 123  * Signature: (JJ)V
 124  */
 125 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPrinterJob__1safePrintLoop
 126 (JNIEnv *env, jclass clz, jlong target, jlong view)
 127 {
 128 JNI_COCOA_ENTER(env);
 129 
 130     PrintModel *model = (PrintModel *)jlong_to_ptr(target);
 131     PrinterView *arg = (PrinterView *)jlong_to_ptr(view);
 132 
 133     [model safePrintLoop:arg withEnv:env];
 134 
 135     // These are to match the retains in runPrintLoopWithView:
 136     [model release];
 137     [arg release];
 138 
 139 JNI_COCOA_EXIT(env);
 140 }
 141