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 <JavaNativeFoundation/JavaNativeFoundation.h>
  30 
  31 #import "PrinterView.h"
  32 #import "ThreadUtilities.h"
  33 
  34 @implementation PrintModel
  35 
  36 - (id)initWithPrintInfo:(NSPrintInfo*)printInfo {
  37     self = [super init];
  38     if (self) {
  39         fPrintInfo = [printInfo retain];
  40     }
  41 
  42     return self;
  43 }
  44 
  45 - (void)dealloc {
  46     [fPrintInfo release];
  47     fPrintInfo = nil;
  48 
  49     [super dealloc];
  50 }
  51 
  52 - (BOOL)runPageSetup {
  53     __block BOOL fResult = NO;
  54 
  55     [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
  56         NSPageLayout* pageLayout = [NSPageLayout pageLayout];
  57         fResult = ([pageLayout runModalWithPrintInfo:fPrintInfo] == NSOKButton);
  58     }];
  59 
  60     return fResult;
  61 }
  62 
  63 - (BOOL)runJobSetup {
  64     __block BOOL fResult = NO;
  65 
  66     [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
  67         NSPrintPanel* printPanel = [NSPrintPanel printPanel];
  68         fResult = ([printPanel runModalWithPrintInfo:fPrintInfo] == NSOKButton);
  69     }];
  70 
  71     return fResult;
  72 }
  73 
  74 - (BOOL)runPrintLoopWithView:(NSView*)printerView waitUntilDone:(BOOL)wait withEnv:(JNIEnv *)env
  75 {
  76 AWT_ASSERT_NOT_APPKIT_THREAD;
  77 
  78     BOOL fResult = NO;
  79 
  80     // <rdar://problem/4310184> Because people like to put up modal dialogs during print operations,
  81     // we have to run the print operation on a non-AppKit thread or else we get a deadlock and errors
  82     // the AppKit team believes it's OK for us to call runOperation from non-AppKit threads,
  83     // as long as we don't show any panels, and we don't touch the NSPrintInfo or the NSView from other threads.
  84     if (wait) {
  85         fResult = [self safePrintLoop:printerView withEnv:env];
  86     } else {
  87         // Retain these so they don't go away while we're in Java
  88         [self retain];
  89         [printerView retain];
  90 
  91         static JNF_CLASS_CACHE(jc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob");
  92         static JNF_STATIC_MEMBER_CACHE(jm_detachPrintLoop, jc_CPrinterJob, "detachPrintLoop", "(JJ)V");
  93         JNFCallStaticVoidMethod(env, jm_detachPrintLoop, ptr_to_jlong(self), ptr_to_jlong(printerView)); // AWT_THREADING Safe (known object)
  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 JNF_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 JNF_COCOA_EXIT(env);
 140 }
 141