0001: /*
0002: * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: package sun.print;
0027:
0028: import java.io.File;
0029: import java.net.URI;
0030: import java.net.URISyntaxException;
0031: import java.net.URL;
0032:
0033: import java.util.Vector;
0034:
0035: import javax.print.DocFlavor;
0036: import javax.print.DocPrintJob;
0037: import javax.print.PrintService;
0038: import javax.print.ServiceUIFactory;
0039: import javax.print.attribute.Attribute;
0040: import javax.print.attribute.AttributeSet;
0041: import javax.print.attribute.AttributeSetUtilities;
0042: import javax.print.attribute.EnumSyntax;
0043: import javax.print.attribute.HashAttributeSet;
0044: import javax.print.attribute.PrintServiceAttribute;
0045: import javax.print.attribute.PrintServiceAttributeSet;
0046: import javax.print.attribute.HashPrintServiceAttributeSet;
0047: import javax.print.attribute.standard.PrinterName;
0048: import javax.print.attribute.standard.PrinterIsAcceptingJobs;
0049: import javax.print.attribute.standard.QueuedJobCount;
0050: import javax.print.attribute.standard.JobName;
0051: import javax.print.attribute.standard.RequestingUserName;
0052: import javax.print.attribute.standard.Chromaticity;
0053: import javax.print.attribute.standard.Copies;
0054: import javax.print.attribute.standard.CopiesSupported;
0055: import javax.print.attribute.standard.Destination;
0056: import javax.print.attribute.standard.Fidelity;
0057: import javax.print.attribute.standard.Media;
0058: import javax.print.attribute.standard.MediaSizeName;
0059: import javax.print.attribute.standard.MediaSize;
0060: import javax.print.attribute.standard.MediaTray;
0061: import javax.print.attribute.standard.MediaPrintableArea;
0062: import javax.print.attribute.standard.OrientationRequested;
0063: import javax.print.attribute.standard.PageRanges;
0064: import javax.print.attribute.standard.PrinterState;
0065: import javax.print.attribute.standard.PrinterStateReason;
0066: import javax.print.attribute.standard.PrinterStateReasons;
0067: import javax.print.attribute.standard.Severity;
0068: import javax.print.attribute.standard.Sides;
0069: import javax.print.attribute.standard.ColorSupported;
0070: import javax.print.attribute.standard.PrintQuality;
0071: import javax.print.attribute.ResolutionSyntax;
0072: import javax.print.attribute.standard.PrinterResolution;
0073: import javax.print.attribute.standard.SheetCollate;
0074: import javax.print.event.PrintServiceAttributeListener;
0075: import java.util.ArrayList;
0076:
0077: import sun.print.SunPrinterJobService;
0078:
0079: public class Win32PrintService implements PrintService,
0080: AttributeUpdater, SunPrinterJobService {
0081:
0082: public static MediaSize[] predefMedia;
0083:
0084: static {
0085: Class c = Win32MediaSize.class;
0086: }
0087:
0088: private static final DocFlavor[] supportedFlavors = {
0089: DocFlavor.BYTE_ARRAY.GIF, DocFlavor.INPUT_STREAM.GIF,
0090: DocFlavor.URL.GIF, DocFlavor.BYTE_ARRAY.JPEG,
0091: DocFlavor.INPUT_STREAM.JPEG, DocFlavor.URL.JPEG,
0092: DocFlavor.BYTE_ARRAY.PNG, DocFlavor.INPUT_STREAM.PNG,
0093: DocFlavor.URL.PNG, DocFlavor.SERVICE_FORMATTED.PAGEABLE,
0094: DocFlavor.SERVICE_FORMATTED.PRINTABLE,
0095: DocFlavor.BYTE_ARRAY.AUTOSENSE, DocFlavor.URL.AUTOSENSE,
0096: DocFlavor.INPUT_STREAM.AUTOSENSE };
0097:
0098: /* let's try to support a few of these */
0099: private static final Class[] serviceAttrCats = { PrinterName.class,
0100: PrinterIsAcceptingJobs.class, QueuedJobCount.class,
0101: ColorSupported.class, };
0102:
0103: /* it turns out to be inconvenient to store the other categories
0104: * separately because many attributes are in multiple categories.
0105: */
0106: private static Class[] otherAttrCats = { JobName.class,
0107: RequestingUserName.class, Copies.class, Destination.class,
0108: OrientationRequested.class, PageRanges.class, Media.class,
0109: MediaPrintableArea.class, Fidelity.class,
0110: // We support collation on 2D printer jobs, even if the driver can't.
0111: SheetCollate.class, SunAlternateMedia.class,
0112: Chromaticity.class };
0113:
0114: /*
0115: * This table together with methods findWin32Media and
0116: * findMatchingMediaSizeNameMM are declared public as these are also
0117: * used in WPrinterJob.java.
0118: */
0119: public static final MediaSizeName[] dmPaperToPrintService = {
0120: MediaSizeName.NA_LETTER, MediaSizeName.NA_LETTER,
0121: MediaSizeName.TABLOID, MediaSizeName.LEDGER,
0122: MediaSizeName.NA_LEGAL, MediaSizeName.INVOICE,
0123: MediaSizeName.EXECUTIVE, MediaSizeName.ISO_A3,
0124: MediaSizeName.ISO_A4, MediaSizeName.ISO_A4,
0125: MediaSizeName.ISO_A5, MediaSizeName.JIS_B4,
0126: MediaSizeName.JIS_B5, MediaSizeName.FOLIO,
0127: MediaSizeName.QUARTO, MediaSizeName.NA_10X14_ENVELOPE,
0128: MediaSizeName.B, MediaSizeName.NA_LETTER,
0129: MediaSizeName.NA_NUMBER_9_ENVELOPE,
0130: MediaSizeName.NA_NUMBER_10_ENVELOPE,
0131: MediaSizeName.NA_NUMBER_11_ENVELOPE,
0132: MediaSizeName.NA_NUMBER_12_ENVELOPE,
0133: MediaSizeName.NA_NUMBER_14_ENVELOPE, MediaSizeName.C,
0134: MediaSizeName.D, MediaSizeName.E,
0135: MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.ISO_C5,
0136: MediaSizeName.ISO_C3, MediaSizeName.ISO_C4,
0137: MediaSizeName.ISO_C6, MediaSizeName.ITALY_ENVELOPE,
0138: MediaSizeName.ISO_B4, MediaSizeName.ISO_B5,
0139: MediaSizeName.ISO_B6, MediaSizeName.ITALY_ENVELOPE,
0140: MediaSizeName.MONARCH_ENVELOPE,
0141: MediaSizeName.PERSONAL_ENVELOPE,
0142: MediaSizeName.NA_10X15_ENVELOPE,
0143: MediaSizeName.NA_9X12_ENVELOPE, MediaSizeName.FOLIO,
0144: MediaSizeName.ISO_B4, MediaSizeName.JAPANESE_POSTCARD,
0145: MediaSizeName.NA_9X11_ENVELOPE, };
0146:
0147: private static final MediaTray[] dmPaperBinToPrintService = {
0148: MediaTray.TOP, MediaTray.BOTTOM, MediaTray.MIDDLE,
0149: MediaTray.MANUAL, MediaTray.ENVELOPE,
0150: Win32MediaTray.ENVELOPE_MANUAL, Win32MediaTray.AUTO,
0151: Win32MediaTray.TRACTOR, Win32MediaTray.SMALL_FORMAT,
0152: Win32MediaTray.LARGE_FORMAT, MediaTray.LARGE_CAPACITY,
0153: null, null, MediaTray.MAIN, Win32MediaTray.FORMSOURCE, };
0154:
0155: // from wingdi.h
0156: private static int DM_PAPERSIZE = 0x2;
0157: private static int DM_PRINTQUALITY = 0x400;
0158: private static int DM_YRESOLUTION = 0x2000;
0159: private static final int DMRES_MEDIUM = -3;
0160: private static final int DMRES_HIGH = -4;
0161: private static final int DMORIENT_LANDSCAPE = 2;
0162: private static final int DMDUP_VERTICAL = 2;
0163: private static final int DMDUP_HORIZONTAL = 3;
0164: private static final int DMCOLLATE_TRUE = 1;
0165:
0166: // media sizes with indices above dmPaperToPrintService' length
0167: private static final int DMPAPER_A2 = 66;
0168: private static final int DMPAPER_A6 = 70;
0169: private static final int DMPAPER_B6_JIS = 88;
0170:
0171: // Bit settings for getPrinterCapabilities which matches that
0172: // of native getCapabilities in WPrinterJob.cpp
0173: private static final int DEVCAP_COLOR = 0x0001;
0174: private static final int DEVCAP_DUPLEX = 0x0002;
0175: private static final int DEVCAP_COLLATE = 0x0004;
0176: private static final int DEVCAP_QUALITY = 0x0008;
0177: private static final int DEVCAP_POSTSCRIPT = 0x0010;
0178:
0179: private String printer;
0180: private PrinterName name;
0181: private String port;
0182:
0183: transient private PrintServiceAttributeSet lastSet;
0184: transient private ServiceNotifier notifier = null;
0185:
0186: private MediaSizeName[] mediaSizeNames;
0187: private MediaPrintableArea[] mediaPrintables;
0188: private MediaTray[] mediaTrays;
0189: private PrinterResolution[] printRes;
0190: private int nCopies;
0191: private int prnCaps;
0192: private int[] defaultSettings;
0193:
0194: private boolean gotTrays;
0195: private boolean gotCopies;
0196: private boolean mediaInitialized;
0197:
0198: private ArrayList idList;
0199: private MediaSize[] mediaSizes;
0200:
0201: private boolean isInvalid;
0202:
0203: Win32PrintService(String name) {
0204: if (name == null) {
0205: throw new IllegalArgumentException("null printer name");
0206: }
0207: printer = name;
0208:
0209: // initialize flags
0210: mediaInitialized = false;
0211: gotTrays = false;
0212: gotCopies = false;
0213: isInvalid = false;
0214: printRes = null;
0215: prnCaps = 0;
0216: defaultSettings = null;
0217: port = null;
0218: }
0219:
0220: public void invalidateService() {
0221: isInvalid = true;
0222: }
0223:
0224: public String getName() {
0225: return printer;
0226: }
0227:
0228: private PrinterName getPrinterName() {
0229: if (name == null) {
0230: name = new PrinterName(printer, null);
0231: }
0232: return name;
0233: }
0234:
0235: public MediaSizeName findWin32Media(int dmIndex) {
0236: if (dmIndex >= 1 && dmIndex <= dmPaperToPrintService.length) {
0237: switch (dmIndex) {
0238: /* matching media sizes with indices beyond
0239: dmPaperToPrintService's length */
0240: case DMPAPER_A2:
0241: return MediaSizeName.ISO_A2;
0242: case DMPAPER_A6:
0243: return MediaSizeName.ISO_A6;
0244: case DMPAPER_B6_JIS:
0245: return MediaSizeName.JIS_B6;
0246: default:
0247: return dmPaperToPrintService[dmIndex - 1];
0248: }
0249: }
0250:
0251: return null;
0252: }
0253:
0254: private boolean addToUniqueList(ArrayList msnList,
0255: MediaSizeName mediaName) {
0256: MediaSizeName msn;
0257: for (int i = 0; i < msnList.size(); i++) {
0258: msn = (MediaSizeName) msnList.get(i);
0259: if (msn == mediaName) {
0260: return false;
0261: }
0262: }
0263: msnList.add(mediaName);
0264: return true;
0265: }
0266:
0267: private synchronized void initMedia() {
0268: if (mediaInitialized == true) {
0269: return;
0270: }
0271: mediaInitialized = true;
0272: int[] media = getAllMediaIDs(printer, getPort());
0273: if (media == null) {
0274: return;
0275: }
0276:
0277: ArrayList msnList = new ArrayList();
0278: ArrayList printableList = new ArrayList();
0279: MediaSizeName mediaName;
0280: boolean added;
0281: boolean queryFailure = false;
0282: float[] prnArea;
0283:
0284: // Get all mediaSizes supported by the printer.
0285: // We convert media to ArrayList idList and pass this to the
0286: // function for getting mediaSizes.
0287: // This is to ensure that mediaSizes and media IDs have 1-1 correspondence.
0288: // We remove from ID list any invalid mediaSize. Though this is rare,
0289: // it happens in HP 4050 German driver.
0290:
0291: idList = new ArrayList();
0292: for (int i = 0; i < media.length; i++) {
0293: idList.add(new Integer(media[i]));
0294: }
0295:
0296: mediaSizes = getMediaSizes(idList, media);
0297: for (int i = 0; i < idList.size(); i++) {
0298:
0299: // match Win ID with our predefined ID using table
0300: mediaName = findWin32Media(((Integer) idList.get(i))
0301: .intValue());
0302:
0303: // No match found, then we get the MediaSizeName out of the MediaSize
0304: // This requires 1-1 correspondence, lengths must be checked.
0305: if ((mediaName == null)
0306: && (idList.size() == mediaSizes.length)) {
0307: mediaName = mediaSizes[i].getMediaSizeName();
0308: }
0309:
0310: // Add mediaName to the msnList
0311: if (mediaName != null) {
0312: added = addToUniqueList(msnList, mediaName);
0313:
0314: // get MediaPrintableArea only for supported MediaSizeName ?
0315: if (added && !queryFailure) {
0316: prnArea = getMediaPrintableArea(printer,
0317: ((Integer) idList.get(i)).intValue());
0318: if (prnArea != null) {
0319: try {
0320: MediaPrintableArea mpa = new MediaPrintableArea(
0321: prnArea[0], prnArea[1], prnArea[2],
0322: prnArea[3], MediaPrintableArea.INCH);
0323: printableList.add(mpa);
0324: } catch (IllegalArgumentException iae) {
0325: }
0326: } else {
0327: // Calling getMediaPrintableArea causes
0328: // much overhead so if first attempt failed, we should
0329: // just bail out.
0330: if (i == 0) {
0331: queryFailure = true;
0332: }
0333: }
0334: }
0335: }
0336: }
0337:
0338: // init mediaSizeNames
0339: mediaSizeNames = new MediaSizeName[msnList.size()];
0340: msnList.toArray(mediaSizeNames);
0341:
0342: // init mediaPrintables
0343: mediaPrintables = new MediaPrintableArea[printableList.size()];
0344: printableList.toArray(mediaPrintables);
0345: }
0346:
0347: private synchronized MediaTray[] getMediaTrays() {
0348: if (gotTrays == true) {
0349: return mediaTrays;
0350: }
0351: gotTrays = true;
0352: String prnPort = getPort();
0353: int[] mediaTr = getAllMediaTrays(printer, prnPort);
0354: String[] winMediaTrayNames = getAllMediaTrayNames(printer,
0355: prnPort);
0356:
0357: if ((mediaTr == null) || (winMediaTrayNames == null)) {
0358: return null;
0359: }
0360:
0361: /* first count how many valid bins there are so we can allocate
0362: * an array of the correct size
0363: */
0364: int nTray = 0;
0365: for (int i = 0; i < mediaTr.length; i++) {
0366: if (mediaTr[i] > 0)
0367: nTray++;
0368: }
0369:
0370: MediaTray[] arr = new MediaTray[nTray];
0371: int dmBin;
0372: for (int i = 0, j = 0; i < mediaTr.length; i++) {
0373: dmBin = mediaTr[i];
0374: if (dmBin > 0) {
0375: // check for unsupported DMBINs and create new Win32MediaTray
0376: if ((dmBin > dmPaperBinToPrintService.length)
0377: || (dmPaperBinToPrintService[dmBin - 1] == null)) {
0378: arr[j++] = new Win32MediaTray(dmBin,
0379: winMediaTrayNames[i]);
0380: } else {
0381: arr[j++] = dmPaperBinToPrintService[dmBin - 1];
0382: }
0383: }
0384: // no else - For invalid ids, just ignore it because assigning a "default"
0385: // value may result in duplicate trays.
0386: }
0387: return arr;
0388: }
0389:
0390: private boolean isSameSize(float w1, float h1, float w2, float h2) {
0391: float diffX = w1 - w2;
0392: float diffY = h1 - h2;
0393: // Get diff of reverse dimensions
0394: // EPSON Stylus COLOR 860 reverses envelope's width & height
0395: float diffXrev = w1 - h2;
0396: float diffYrev = h1 - w2;
0397:
0398: if (((Math.abs(diffX) <= 1) && (Math.abs(diffY) <= 1))
0399: || ((Math.abs(diffXrev) <= 1) && (Math.abs(diffYrev) <= 1))) {
0400: return true;
0401: } else {
0402: return false;
0403: }
0404: }
0405:
0406: public MediaSizeName findMatchingMediaSizeNameMM(float w, float h) {
0407: if (predefMedia != null) {
0408: for (int k = 0; k < predefMedia.length; k++) {
0409: if (predefMedia[k] == null) {
0410: continue;
0411: }
0412:
0413: if (isSameSize(predefMedia[k].getX(MediaSize.MM),
0414: predefMedia[k].getY(MediaSize.MM), w, h)) {
0415: return predefMedia[k].getMediaSizeName();
0416: }
0417: }
0418: }
0419: return null;
0420: }
0421:
0422: private MediaSize[] getMediaSizes(ArrayList idList, int[] media) {
0423: String prnPort = getPort();
0424: int[] mediaSz = getAllMediaSizes(printer, prnPort);
0425: String[] winMediaNames = getAllMediaNames(printer, prnPort);
0426: MediaSizeName msn = null;
0427: MediaSize ms = null;
0428: float wid, ht;
0429:
0430: if ((mediaSz == null) || (winMediaNames == null)) {
0431: return null;
0432: }
0433:
0434: int nMedia = mediaSz.length / 2;
0435: ArrayList msList = new ArrayList();
0436:
0437: for (int i = 0; i < nMedia; i++, ms = null) {
0438: wid = mediaSz[i * 2] / 10;
0439: ht = mediaSz[i * 2 + 1] / 10;
0440:
0441: // Make sure to validate wid & ht.
0442: // HP LJ 4050 (german) causes IAE in Sonderformat paper, wid & ht
0443: // returned is not constant.
0444: if ((wid <= 0) || (ht <= 0)) {
0445: //Remove corresponding ID from list
0446: if (nMedia == media.length) {
0447: Integer remObj = new Integer(media[i]);
0448: idList.remove(idList.indexOf(remObj));
0449: }
0450: continue;
0451: }
0452: // Find matching media using dimensions.
0453: // This call matches only with our own predefined sizes.
0454: msn = findMatchingMediaSizeNameMM(wid, ht);
0455: if (msn != null) {
0456: ms = MediaSize.getMediaSizeForName(msn);
0457: }
0458:
0459: if (ms != null) {
0460: msList.add(ms);
0461: } else {
0462: Win32MediaSize wms = new Win32MediaSize(
0463: winMediaNames[i]);
0464: try {
0465: ms = new MediaSize(wid, ht, MediaSize.MM, wms);
0466: msList.add(ms);
0467: } catch (IllegalArgumentException e) {
0468: if (nMedia == media.length) {
0469: Integer remObj = new Integer(media[i]);
0470: idList.remove(idList.indexOf(remObj));
0471: }
0472: }
0473: }
0474:
0475: }
0476:
0477: MediaSize[] arr2 = new MediaSize[msList.size()];
0478: msList.toArray(arr2);
0479:
0480: return arr2;
0481: }
0482:
0483: private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
0484: if (getJobStatus(printer, 2) != 1) {
0485: return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
0486: } else {
0487: return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
0488: }
0489: }
0490:
0491: private PrinterState getPrinterState() {
0492: if (isInvalid) {
0493: return PrinterState.STOPPED;
0494: } else {
0495: return null;
0496: }
0497: }
0498:
0499: private PrinterStateReasons getPrinterStateReasons() {
0500: if (isInvalid) {
0501: PrinterStateReasons psr = new PrinterStateReasons();
0502: psr.put(PrinterStateReason.SHUTDOWN, Severity.ERROR);
0503: return psr;
0504: } else {
0505: return null;
0506: }
0507: }
0508:
0509: private QueuedJobCount getQueuedJobCount() {
0510:
0511: int count = getJobStatus(printer, 1);
0512: if (count != -1) {
0513: return new QueuedJobCount(count);
0514: } else {
0515: return new QueuedJobCount(0);
0516: }
0517: }
0518:
0519: private boolean isSupportedCopies(Copies copies) {
0520: synchronized (this ) {
0521: if (gotCopies == false) {
0522: nCopies = getCopiesSupported(printer, getPort());
0523: gotCopies = true;
0524: }
0525: }
0526: int numCopies = copies.getValue();
0527: return (numCopies > 0 && numCopies <= nCopies);
0528: }
0529:
0530: private boolean isSupportedMedia(MediaSizeName msn) {
0531:
0532: initMedia();
0533:
0534: if (mediaSizeNames != null) {
0535: for (int i = 0; i < mediaSizeNames.length; i++) {
0536: if (msn.equals(mediaSizeNames[i])) {
0537: return true;
0538: }
0539: }
0540: }
0541: return false;
0542: }
0543:
0544: private boolean isSupportedMediaPrintableArea(MediaPrintableArea mpa) {
0545:
0546: initMedia();
0547:
0548: if (mediaPrintables != null) {
0549: for (int i = 0; i < mediaPrintables.length; i++) {
0550: if (mpa.equals(mediaPrintables[i])) {
0551: return true;
0552: }
0553: }
0554: }
0555: return false;
0556: }
0557:
0558: private boolean isSupportedMediaTray(MediaTray msn) {
0559: mediaTrays = getMediaTrays();
0560:
0561: if (mediaTrays != null) {
0562: for (int i = 0; i < mediaTrays.length; i++) {
0563: if (msn.equals(mediaTrays[i])) {
0564: return true;
0565: }
0566: }
0567: }
0568: return false;
0569: }
0570:
0571: private int getPrinterCapabilities() {
0572: if (prnCaps == 0) {
0573: prnCaps = getCapabilities(printer, getPort());
0574: }
0575: return prnCaps;
0576: }
0577:
0578: private String getPort() {
0579: if (port == null) {
0580: port = getPrinterPort(printer);
0581: }
0582: return port;
0583: }
0584:
0585: /*
0586: * NOTE: defaults indices must match those in WPrinterJob.cpp
0587: */
0588: private int[] getDefaultPrinterSettings() {
0589: if (defaultSettings == null) {
0590: defaultSettings = getDefaultSettings(printer);
0591: }
0592: return defaultSettings;
0593: }
0594:
0595: private PrinterResolution[] getPrintResolutions() {
0596: if (printRes == null) {
0597: int[] prnRes = getAllResolutions(printer, getPort());
0598: if (prnRes == null) {
0599: printRes = new PrinterResolution[0];
0600: } else {
0601: int nRes = prnRes.length / 2;
0602:
0603: ArrayList arrList = new ArrayList();
0604: PrinterResolution pr;
0605:
0606: for (int i = 0; i < nRes; i++) {
0607: try {
0608: pr = new PrinterResolution(prnRes[i * 2],
0609: prnRes[i * 2 + 1],
0610: PrinterResolution.DPI);
0611: arrList.add(pr);
0612: } catch (IllegalArgumentException e) {
0613: }
0614: }
0615:
0616: printRes = (PrinterResolution[]) arrList
0617: .toArray(new PrinterResolution[arrList.size()]);
0618: }
0619: }
0620: return printRes;
0621: }
0622:
0623: private boolean isSupportedResolution(PrinterResolution res) {
0624: PrinterResolution[] supportedRes = getPrintResolutions();
0625: if (supportedRes != null) {
0626: for (int i = 0; i < supportedRes.length; i++) {
0627: if (res.equals(supportedRes[i])) {
0628: return true;
0629: }
0630: }
0631: }
0632: return false;
0633: }
0634:
0635: public DocPrintJob createPrintJob() {
0636: SecurityManager security = System.getSecurityManager();
0637: if (security != null) {
0638: security.checkPrintJobAccess();
0639: }
0640: return new Win32PrintJob(this );
0641: }
0642:
0643: private PrintServiceAttributeSet getDynamicAttributes() {
0644: PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
0645: attrs.add(getPrinterIsAcceptingJobs());
0646: attrs.add(getQueuedJobCount());
0647: return attrs;
0648: }
0649:
0650: public PrintServiceAttributeSet getUpdatedAttributes() {
0651: PrintServiceAttributeSet currSet = getDynamicAttributes();
0652: if (lastSet == null) {
0653: lastSet = currSet;
0654: return AttributeSetUtilities.unmodifiableView(currSet);
0655: } else {
0656: PrintServiceAttributeSet updates = new HashPrintServiceAttributeSet();
0657: Attribute[] attrs = currSet.toArray();
0658: for (int i = 0; i < attrs.length; i++) {
0659: Attribute attr = attrs[i];
0660: if (!lastSet.containsValue(attr)) {
0661: updates.add(attr);
0662: }
0663: }
0664: lastSet = currSet;
0665: return AttributeSetUtilities.unmodifiableView(updates);
0666: }
0667: }
0668:
0669: public void wakeNotifier() {
0670: synchronized (this ) {
0671: if (notifier != null) {
0672: notifier.wake();
0673: }
0674: }
0675: }
0676:
0677: public void addPrintServiceAttributeListener(
0678: PrintServiceAttributeListener listener) {
0679: synchronized (this ) {
0680: if (listener == null) {
0681: return;
0682: }
0683: if (notifier == null) {
0684: notifier = new ServiceNotifier(this );
0685: }
0686: notifier.addListener(listener);
0687: }
0688: }
0689:
0690: public void removePrintServiceAttributeListener(
0691: PrintServiceAttributeListener listener) {
0692: synchronized (this ) {
0693: if (listener == null || notifier == null) {
0694: return;
0695: }
0696: notifier.removeListener(listener);
0697: if (notifier.isEmpty()) {
0698: notifier.stopNotifier();
0699: notifier = null;
0700: }
0701: }
0702: }
0703:
0704: public <T extends PrintServiceAttribute> T getAttribute(
0705: Class<T> category) {
0706: if (category == null) {
0707: throw new NullPointerException("category");
0708: }
0709: if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {
0710: throw new IllegalArgumentException(
0711: "Not a PrintServiceAttribute");
0712: }
0713: if (category == ColorSupported.class) {
0714: int caps = getPrinterCapabilities();
0715: if ((caps & DEVCAP_COLOR) != 0) {
0716: return (T) ColorSupported.SUPPORTED;
0717: } else {
0718: return (T) ColorSupported.NOT_SUPPORTED;
0719: }
0720: } else if (category == PrinterName.class) {
0721: return (T) getPrinterName();
0722: } else if (category == PrinterState.class) {
0723: return (T) getPrinterState();
0724: } else if (category == PrinterStateReasons.class) {
0725: return (T) getPrinterStateReasons();
0726: } else if (category == QueuedJobCount.class) {
0727: return (T) getQueuedJobCount();
0728: } else if (category == PrinterIsAcceptingJobs.class) {
0729: return (T) getPrinterIsAcceptingJobs();
0730: } else {
0731: return null;
0732: }
0733: }
0734:
0735: public PrintServiceAttributeSet getAttributes() {
0736:
0737: PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
0738: attrs.add(getPrinterName());
0739: attrs.add(getPrinterIsAcceptingJobs());
0740: PrinterState prnState = getPrinterState();
0741: if (prnState != null) {
0742: attrs.add(prnState);
0743: }
0744: PrinterStateReasons prnStateReasons = getPrinterStateReasons();
0745: if (prnStateReasons != null) {
0746: attrs.add(prnStateReasons);
0747: }
0748: attrs.add(getQueuedJobCount());
0749: int caps = getPrinterCapabilities();
0750: if ((caps & DEVCAP_COLOR) != 0) {
0751: attrs.add(ColorSupported.SUPPORTED);
0752: } else {
0753: attrs.add(ColorSupported.NOT_SUPPORTED);
0754: }
0755:
0756: return AttributeSetUtilities.unmodifiableView(attrs);
0757: }
0758:
0759: public DocFlavor[] getSupportedDocFlavors() {
0760: int len = supportedFlavors.length;
0761: DocFlavor[] supportedDocFlavors;
0762: int caps = getPrinterCapabilities();
0763: // doc flavors supported
0764: // if PostScript is supported
0765: if ((caps & DEVCAP_POSTSCRIPT) != 0) {
0766: supportedDocFlavors = new DocFlavor[len + 3];
0767: System.arraycopy(supportedFlavors, 0, supportedDocFlavors,
0768: 0, len);
0769: supportedDocFlavors[len] = DocFlavor.BYTE_ARRAY.POSTSCRIPT;
0770: supportedDocFlavors[len + 1] = DocFlavor.INPUT_STREAM.POSTSCRIPT;
0771: supportedDocFlavors[len + 2] = DocFlavor.URL.POSTSCRIPT;
0772: } else {
0773: supportedDocFlavors = new DocFlavor[len];
0774: System.arraycopy(supportedFlavors, 0, supportedDocFlavors,
0775: 0, len);
0776: }
0777: return supportedDocFlavors;
0778: }
0779:
0780: public boolean isDocFlavorSupported(DocFlavor flavor) {
0781: /* To avoid a native query which may be time-consuming
0782: * do not invoke native unless postscript support is being queried.
0783: * Instead just check the ones we 'always' support
0784: */
0785: DocFlavor[] supportedDocFlavors;
0786: if (isPostScriptFlavor(flavor)) {
0787: supportedDocFlavors = getSupportedDocFlavors();
0788: } else {
0789: supportedDocFlavors = supportedFlavors;
0790: }
0791: for (int f = 0; f < supportedDocFlavors.length; f++) {
0792: if (flavor.equals(supportedDocFlavors[f])) {
0793: return true;
0794: }
0795: }
0796: return false;
0797: }
0798:
0799: public Class<?>[] getSupportedAttributeCategories() {
0800: ArrayList categList = new ArrayList(otherAttrCats.length + 3);
0801: for (int i = 0; i < otherAttrCats.length; i++) {
0802: categList.add(otherAttrCats[i]);
0803: }
0804:
0805: int caps = getPrinterCapabilities();
0806:
0807: if ((caps & DEVCAP_DUPLEX) != 0) {
0808: categList.add(Sides.class);
0809: }
0810:
0811: if ((caps & DEVCAP_QUALITY) != 0) {
0812: int[] defaults = getDefaultPrinterSettings();
0813: // Added check: if supported, we should be able to get the default.
0814: if ((defaults[3] >= DMRES_HIGH) && (defaults[3] < 0)) {
0815: categList.add(PrintQuality.class);
0816: }
0817: }
0818:
0819: PrinterResolution[] supportedRes = getPrintResolutions();
0820: if ((supportedRes != null) && (supportedRes.length > 0)) {
0821: categList.add(PrinterResolution.class);
0822: }
0823:
0824: return (Class[]) categList.toArray(new Class[categList.size()]);
0825: }
0826:
0827: public boolean isAttributeCategorySupported(
0828: Class<? extends Attribute> category) {
0829:
0830: if (category == null) {
0831: throw new NullPointerException("null category");
0832: }
0833:
0834: if (!(Attribute.class.isAssignableFrom(category))) {
0835: throw new IllegalArgumentException(category
0836: + " is not an Attribute");
0837: }
0838:
0839: Class[] classList = getSupportedAttributeCategories();
0840: for (int i = 0; i < classList.length; i++) {
0841: if (category.equals(classList[i])) {
0842: return true;
0843: }
0844: }
0845:
0846: return false;
0847: }
0848:
0849: public Object getDefaultAttributeValue(
0850: Class<? extends Attribute> category) {
0851: if (category == null) {
0852: throw new NullPointerException("null category");
0853: }
0854: if (!Attribute.class.isAssignableFrom(category)) {
0855: throw new IllegalArgumentException(category
0856: + " is not an Attribute");
0857: }
0858:
0859: if (!isAttributeCategorySupported(category)) {
0860: return null;
0861: }
0862:
0863: int[] defaults = getDefaultPrinterSettings();
0864: // indices must match those in WPrinterJob.cpp
0865: int defPaper = defaults[0];
0866: int defYRes = defaults[2];
0867: int defQuality = defaults[3];
0868: int defCopies = defaults[4];
0869: int defOrient = defaults[5];
0870: int defSides = defaults[6];
0871: int defCollate = defaults[7];
0872:
0873: if (category == Copies.class) {
0874: if (defCopies > 0) {
0875: return new Copies(defCopies);
0876: } else {
0877: return new Copies(1);
0878: }
0879: } else if (category == Chromaticity.class) {
0880: int caps = getPrinterCapabilities();
0881: if ((caps & DEVCAP_COLOR) == 0) {
0882: return Chromaticity.MONOCHROME;
0883: } else {
0884: return Chromaticity.COLOR;
0885: }
0886: } else if (category == JobName.class) {
0887: return new JobName("Java Printing", null);
0888: } else if (category == OrientationRequested.class) {
0889: if (defOrient == DMORIENT_LANDSCAPE) {
0890: return OrientationRequested.LANDSCAPE;
0891: } else {
0892: return OrientationRequested.PORTRAIT;
0893: }
0894: } else if (category == PageRanges.class) {
0895: return new PageRanges(1, Integer.MAX_VALUE);
0896: } else if (category == Media.class) {
0897: MediaSizeName msn = findWin32Media(defPaper);
0898: if (msn != null) {
0899: return msn;
0900: } else {
0901: initMedia();
0902:
0903: if ((mediaSizeNames != null)
0904: && (mediaSizeNames.length > 0)) {
0905: // if 'mediaSizeNames' is not null, idList and mediaSizes cannot
0906: // be null but to be safe, add a check
0907: if ((idList != null) && (mediaSizes != null)
0908: && (idList.size() == mediaSizes.length)) {
0909: Integer defIdObj = new Integer(defPaper);
0910: int index = idList.indexOf(defIdObj);
0911: if (index >= 0 && index < mediaSizes.length) {
0912: return mediaSizes[index].getMediaSizeName();
0913: }
0914: }
0915:
0916: return mediaSizeNames[0];
0917: }
0918: }
0919: } else if (category == MediaPrintableArea.class) {
0920: float[] prnArea = getMediaPrintableArea(printer, defPaper);
0921: if (prnArea != null) {
0922: MediaPrintableArea printableArea = null;
0923: try {
0924: printableArea = new MediaPrintableArea(prnArea[0],
0925: prnArea[1], prnArea[2], prnArea[3],
0926: MediaPrintableArea.INCH);
0927: } catch (IllegalArgumentException e) {
0928: }
0929: return printableArea;
0930: }
0931: return null;
0932: } else if (category == SunAlternateMedia.class) {
0933: return null;
0934: } else if (category == Destination.class) {
0935: try {
0936: return new Destination((new File("out.prn")).toURI());
0937: } catch (SecurityException se) {
0938: try {
0939: return new Destination(new URI("file:out.prn"));
0940: } catch (URISyntaxException e) {
0941: return null;
0942: }
0943: }
0944: } else if (category == Sides.class) {
0945: switch (defSides) {
0946: case DMDUP_VERTICAL:
0947: return Sides.TWO_SIDED_LONG_EDGE;
0948: case DMDUP_HORIZONTAL:
0949: return Sides.TWO_SIDED_SHORT_EDGE;
0950: default:
0951: return Sides.ONE_SIDED;
0952: }
0953: } else if (category == PrinterResolution.class) {
0954: int yRes = defYRes;
0955: int xRes = defQuality;
0956: if ((xRes < 0) || (yRes < 0)) {
0957: int res = (yRes > xRes) ? yRes : xRes;
0958: if (res > 0) {
0959: return new PrinterResolution(res, res,
0960: PrinterResolution.DPI);
0961: }
0962: } else {
0963: return new PrinterResolution(xRes, yRes,
0964: PrinterResolution.DPI);
0965: }
0966: } else if (category == ColorSupported.class) {
0967: int caps = getPrinterCapabilities();
0968: if ((caps & DEVCAP_COLOR) != 0) {
0969: return ColorSupported.SUPPORTED;
0970: } else {
0971: return ColorSupported.NOT_SUPPORTED;
0972: }
0973: } else if (category == PrintQuality.class) {
0974: if ((defQuality < 0) && (defQuality >= DMRES_HIGH)) {
0975: switch (defQuality) {
0976: case DMRES_HIGH:
0977: return PrintQuality.HIGH;
0978: case DMRES_MEDIUM:
0979: return PrintQuality.NORMAL;
0980: default:
0981: return PrintQuality.DRAFT;
0982: }
0983: }
0984: } else if (category == RequestingUserName.class) {
0985: String userName = "";
0986: try {
0987: userName = System.getProperty("user.name", "");
0988: } catch (SecurityException se) {
0989: }
0990: return new RequestingUserName(userName, null);
0991: } else if (category == SheetCollate.class) {
0992: if (defCollate == DMCOLLATE_TRUE) {
0993: return SheetCollate.COLLATED;
0994: } else {
0995: return SheetCollate.UNCOLLATED;
0996: }
0997: } else if (category == Fidelity.class) {
0998: return Fidelity.FIDELITY_FALSE;
0999: }
1000: return null;
1001: }
1002:
1003: private boolean isPostScriptFlavor(DocFlavor flavor) {
1004: if (flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT)
1005: || flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT)
1006: || flavor.equals(DocFlavor.URL.POSTSCRIPT)) {
1007: return true;
1008: } else {
1009: return false;
1010: }
1011: }
1012:
1013: private boolean isPSDocAttr(Class category) {
1014: if (category == OrientationRequested.class
1015: || category == Copies.class) {
1016: return true;
1017: } else {
1018: return false;
1019: }
1020: }
1021:
1022: private boolean isAutoSense(DocFlavor flavor) {
1023: if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE)
1024: || flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE)
1025: || flavor.equals(DocFlavor.URL.AUTOSENSE)) {
1026: return true;
1027: } else {
1028: return false;
1029: }
1030: }
1031:
1032: public Object getSupportedAttributeValues(
1033: Class<? extends Attribute> category, DocFlavor flavor,
1034: AttributeSet attributes) {
1035: if (category == null) {
1036: throw new NullPointerException("null category");
1037: }
1038: if (!Attribute.class.isAssignableFrom(category)) {
1039: throw new IllegalArgumentException(category
1040: + " does not implement Attribute");
1041: }
1042: if (flavor != null) {
1043: if (!isDocFlavorSupported(flavor)) {
1044: throw new IllegalArgumentException(flavor
1045: + " is an unsupported flavor");
1046: // if postscript & category is already specified within the
1047: // PostScript data we return null
1048: } else if (isAutoSense(flavor)
1049: || (isPostScriptFlavor(flavor) && (isPSDocAttr(category)))) {
1050: return null;
1051: }
1052: }
1053: if (!isAttributeCategorySupported(category)) {
1054: return null;
1055: }
1056:
1057: if (category == JobName.class) {
1058: return new JobName("Java Printing", null);
1059: } else if (category == RequestingUserName.class) {
1060: String userName = "";
1061: try {
1062: userName = System.getProperty("user.name", "");
1063: } catch (SecurityException se) {
1064: }
1065: return new RequestingUserName(userName, null);
1066: } else if (category == ColorSupported.class) {
1067: int caps = getPrinterCapabilities();
1068: if ((caps & DEVCAP_COLOR) != 0) {
1069: return ColorSupported.SUPPORTED;
1070: } else {
1071: return ColorSupported.NOT_SUPPORTED;
1072: }
1073: } else if (category == Chromaticity.class) {
1074: if (flavor == null
1075: || flavor
1076: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1077: || flavor
1078: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)
1079: || flavor.equals(DocFlavor.BYTE_ARRAY.GIF)
1080: || flavor.equals(DocFlavor.INPUT_STREAM.GIF)
1081: || flavor.equals(DocFlavor.URL.GIF)
1082: || flavor.equals(DocFlavor.BYTE_ARRAY.JPEG)
1083: || flavor.equals(DocFlavor.INPUT_STREAM.JPEG)
1084: || flavor.equals(DocFlavor.URL.JPEG)
1085: || flavor.equals(DocFlavor.BYTE_ARRAY.PNG)
1086: || flavor.equals(DocFlavor.INPUT_STREAM.PNG)
1087: || flavor.equals(DocFlavor.URL.PNG)) {
1088: int caps = getPrinterCapabilities();
1089: if ((caps & DEVCAP_COLOR) == 0) {
1090: Chromaticity[] arr = new Chromaticity[1];
1091: arr[0] = Chromaticity.MONOCHROME;
1092: return (arr);
1093: } else {
1094: Chromaticity[] arr = new Chromaticity[2];
1095: arr[0] = Chromaticity.MONOCHROME;
1096: arr[1] = Chromaticity.COLOR;
1097: return (arr);
1098: }
1099: } else {
1100: return null;
1101: }
1102: } else if (category == Destination.class) {
1103: try {
1104: return new Destination((new File("out.prn")).toURI());
1105: } catch (SecurityException se) {
1106: try {
1107: return new Destination(new URI("file:out.prn"));
1108: } catch (URISyntaxException e) {
1109: return null;
1110: }
1111: }
1112: } else if (category == OrientationRequested.class) {
1113: if (flavor == null
1114: || flavor
1115: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1116: || flavor
1117: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)
1118: || flavor.equals(DocFlavor.INPUT_STREAM.GIF)
1119: || flavor.equals(DocFlavor.INPUT_STREAM.JPEG)
1120: || flavor.equals(DocFlavor.INPUT_STREAM.PNG)
1121: || flavor.equals(DocFlavor.BYTE_ARRAY.GIF)
1122: || flavor.equals(DocFlavor.BYTE_ARRAY.JPEG)
1123: || flavor.equals(DocFlavor.BYTE_ARRAY.PNG)
1124: || flavor.equals(DocFlavor.URL.GIF)
1125: || flavor.equals(DocFlavor.URL.JPEG)
1126: || flavor.equals(DocFlavor.URL.PNG)) {
1127: OrientationRequested[] arr = new OrientationRequested[3];
1128: arr[0] = OrientationRequested.PORTRAIT;
1129: arr[1] = OrientationRequested.LANDSCAPE;
1130: arr[2] = OrientationRequested.REVERSE_LANDSCAPE;
1131: return arr;
1132: } else {
1133: return null;
1134: }
1135: } else if ((category == Copies.class)
1136: || (category == CopiesSupported.class)) {
1137: synchronized (this ) {
1138: if (gotCopies == false) {
1139: nCopies = getCopiesSupported(printer, getPort());
1140: gotCopies = true;
1141: }
1142: }
1143: return new CopiesSupported(1, nCopies);
1144: } else if (category == Media.class) {
1145:
1146: initMedia();
1147:
1148: int len = (mediaSizeNames == null) ? 0
1149: : mediaSizeNames.length;
1150:
1151: mediaTrays = getMediaTrays();
1152:
1153: len += (mediaTrays == null) ? 0 : mediaTrays.length;
1154:
1155: Media[] arr = new Media[len];
1156: if (mediaSizeNames != null) {
1157: System.arraycopy(mediaSizeNames, 0, arr, 0,
1158: mediaSizeNames.length);
1159: }
1160: if (mediaTrays != null) {
1161: System.arraycopy(mediaTrays, 0, arr,
1162: mediaSizeNames.length, mediaTrays.length);
1163: }
1164: return arr;
1165: } else if (category == MediaPrintableArea.class) {
1166: initMedia();
1167:
1168: if (mediaPrintables == null) {
1169: return null;
1170: }
1171:
1172: // if getting printable area for a specific media size
1173: Media mediaName;
1174: if ((attributes != null)
1175: && ((mediaName = (Media) attributes
1176: .get(Media.class)) != null)) {
1177:
1178: if (mediaName instanceof MediaSizeName) {
1179: MediaPrintableArea[] arr = new MediaPrintableArea[1];
1180:
1181: if (mediaSizeNames.length == mediaPrintables.length) {
1182:
1183: for (int j = 0; j < mediaSizeNames.length; j++) {
1184:
1185: if (mediaName.equals(mediaSizeNames[j])) {
1186: arr[0] = mediaPrintables[j];
1187: return arr;
1188: }
1189: }
1190: }
1191:
1192: MediaSize ms = MediaSize
1193: .getMediaSizeForName((MediaSizeName) mediaName);
1194:
1195: if (ms != null) {
1196: arr[0] = new MediaPrintableArea(0, 0, ms
1197: .getX(MediaSize.INCH), ms
1198: .getY(MediaSize.INCH),
1199: MediaPrintableArea.INCH);
1200: return arr;
1201: } else {
1202: return null;
1203: }
1204: }
1205: // else an instance of MediaTray, fall thru returning
1206: // all MediaPrintableAreas
1207: }
1208:
1209: MediaPrintableArea[] arr = new MediaPrintableArea[mediaPrintables.length];
1210: System.arraycopy(mediaPrintables, 0, arr, 0,
1211: mediaPrintables.length);
1212: return arr;
1213: } else if (category == SunAlternateMedia.class) {
1214: return new SunAlternateMedia(
1215: (Media) getDefaultAttributeValue(Media.class));
1216: } else if (category == PageRanges.class) {
1217: if (flavor == null
1218: || flavor
1219: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1220: || flavor
1221: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
1222: PageRanges[] arr = new PageRanges[1];
1223: arr[0] = new PageRanges(1, Integer.MAX_VALUE);
1224: return arr;
1225: } else {
1226: return null;
1227: }
1228: } else if (category == PrinterResolution.class) {
1229: PrinterResolution[] supportedRes = getPrintResolutions();
1230: if (supportedRes == null) {
1231: return null;
1232: }
1233: PrinterResolution[] arr = new PrinterResolution[supportedRes.length];
1234: System.arraycopy(supportedRes, 0, arr, 0,
1235: supportedRes.length);
1236: return arr;
1237: } else if (category == Sides.class) {
1238: if (flavor == null
1239: || flavor
1240: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1241: || flavor
1242: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
1243: Sides[] arr = new Sides[3];
1244: arr[0] = Sides.ONE_SIDED;
1245: arr[1] = Sides.TWO_SIDED_LONG_EDGE;
1246: arr[2] = Sides.TWO_SIDED_SHORT_EDGE;
1247: return arr;
1248: } else {
1249: return null;
1250: }
1251: } else if (category == PrintQuality.class) {
1252: PrintQuality[] arr = new PrintQuality[3];
1253: arr[0] = PrintQuality.DRAFT;
1254: arr[1] = PrintQuality.HIGH;
1255: arr[2] = PrintQuality.NORMAL;
1256: return arr;
1257: } else if (category == SheetCollate.class) {
1258: if (flavor == null
1259: || (flavor
1260: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || flavor
1261: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
1262: SheetCollate[] arr = new SheetCollate[2];
1263: arr[0] = SheetCollate.COLLATED;
1264: arr[1] = SheetCollate.UNCOLLATED;
1265: return arr;
1266: } else {
1267: return null;
1268: }
1269: } else if (category == Fidelity.class) {
1270: Fidelity[] arr = new Fidelity[2];
1271: arr[0] = Fidelity.FIDELITY_FALSE;
1272: arr[1] = Fidelity.FIDELITY_TRUE;
1273: return arr;
1274: } else {
1275: return null;
1276: }
1277: }
1278:
1279: public boolean isAttributeValueSupported(Attribute attr,
1280: DocFlavor flavor, AttributeSet attributes) {
1281:
1282: if (attr == null) {
1283: throw new NullPointerException("null attribute");
1284: }
1285: Class category = attr.getCategory();
1286: if (flavor != null) {
1287: if (!isDocFlavorSupported(flavor)) {
1288: throw new IllegalArgumentException(flavor
1289: + " is an unsupported flavor");
1290: // if postscript & category is already specified within the PostScript data
1291: // we return false
1292: } else if (isAutoSense(flavor)
1293: || (isPostScriptFlavor(flavor) && (isPSDocAttr(category)))) {
1294: return false;
1295: }
1296: }
1297:
1298: if (!isAttributeCategorySupported(category)) {
1299: return false;
1300: } else if (attr.getCategory() == Chromaticity.class) {
1301: if ((flavor == null)
1302: || flavor
1303: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1304: || flavor
1305: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)
1306: || flavor.equals(DocFlavor.BYTE_ARRAY.GIF)
1307: || flavor.equals(DocFlavor.INPUT_STREAM.GIF)
1308: || flavor.equals(DocFlavor.URL.GIF)
1309: || flavor.equals(DocFlavor.BYTE_ARRAY.JPEG)
1310: || flavor.equals(DocFlavor.INPUT_STREAM.JPEG)
1311: || flavor.equals(DocFlavor.URL.JPEG)
1312: || flavor.equals(DocFlavor.BYTE_ARRAY.PNG)
1313: || flavor.equals(DocFlavor.INPUT_STREAM.PNG)
1314: || flavor.equals(DocFlavor.URL.PNG)) {
1315: int caps = getPrinterCapabilities();
1316: if ((caps & DEVCAP_COLOR) != 0) {
1317: return true;
1318: } else {
1319: return attr == Chromaticity.MONOCHROME;
1320: }
1321: } else {
1322: return false;
1323: }
1324: } else if (attr.getCategory() == Copies.class) {
1325: return isSupportedCopies((Copies) attr);
1326:
1327: } else if (attr.getCategory() == Destination.class) {
1328: URI uri = ((Destination) attr).getURI();
1329: if ("file".equals(uri.getScheme())
1330: && !(uri.getSchemeSpecificPart().equals(""))) {
1331: return true;
1332: } else {
1333: return false;
1334: }
1335:
1336: } else if (attr.getCategory() == Media.class) {
1337: if (attr instanceof MediaSizeName) {
1338: return isSupportedMedia((MediaSizeName) attr);
1339: }
1340: if (attr instanceof MediaTray) {
1341: return isSupportedMediaTray((MediaTray) attr);
1342: }
1343:
1344: } else if (attr.getCategory() == MediaPrintableArea.class) {
1345: return isSupportedMediaPrintableArea((MediaPrintableArea) attr);
1346:
1347: } else if (attr.getCategory() == SunAlternateMedia.class) {
1348: Media media = ((SunAlternateMedia) attr).getMedia();
1349: return isAttributeValueSupported(media, flavor, attributes);
1350:
1351: } else if (attr.getCategory() == PageRanges.class) {
1352: if (flavor != null
1353: && !(flavor
1354: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || flavor
1355: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
1356: return false;
1357: }
1358: } else if (attr.getCategory() == SheetCollate.class) {
1359: if (flavor != null
1360: && !flavor
1361: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1362: && !flavor
1363: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
1364: return false;
1365: }
1366: } else if (attr.getCategory() == Sides.class) {
1367: if (flavor != null
1368: && !(flavor
1369: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || flavor
1370: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
1371: return false;
1372: }
1373: } else if (attr.getCategory() == PrinterResolution.class) {
1374: if (attr instanceof PrinterResolution) {
1375: return isSupportedResolution((PrinterResolution) attr);
1376: }
1377: } else if (attr.getCategory() == OrientationRequested.class) {
1378: if (attr == OrientationRequested.REVERSE_PORTRAIT
1379: || (flavor != null)
1380: && !(flavor
1381: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1382: || flavor
1383: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)
1384: || flavor
1385: .equals(DocFlavor.INPUT_STREAM.GIF)
1386: || flavor
1387: .equals(DocFlavor.INPUT_STREAM.JPEG)
1388: || flavor
1389: .equals(DocFlavor.INPUT_STREAM.PNG)
1390: || flavor.equals(DocFlavor.BYTE_ARRAY.GIF)
1391: || flavor.equals(DocFlavor.BYTE_ARRAY.JPEG)
1392: || flavor.equals(DocFlavor.BYTE_ARRAY.PNG)
1393: || flavor.equals(DocFlavor.URL.GIF)
1394: || flavor.equals(DocFlavor.URL.JPEG) || flavor
1395: .equals(DocFlavor.URL.PNG))) {
1396: return false;
1397: }
1398:
1399: } else if (attr.getCategory() == ColorSupported.class) {
1400: int caps = getPrinterCapabilities();
1401: boolean isColorSup = ((caps & DEVCAP_COLOR) != 0);
1402: if ((!isColorSup && (attr == ColorSupported.SUPPORTED))
1403: || (isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) {
1404: return false;
1405: }
1406: }
1407: return true;
1408: }
1409:
1410: public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
1411: AttributeSet attributes) {
1412:
1413: if (flavor != null && !isDocFlavorSupported(flavor)) {
1414: throw new IllegalArgumentException("flavor " + flavor
1415: + "is not supported");
1416: }
1417:
1418: if (attributes == null) {
1419: return null;
1420: }
1421:
1422: Attribute attr;
1423: AttributeSet unsupp = new HashAttributeSet();
1424: Attribute[] attrs = attributes.toArray();
1425: for (int i = 0; i < attrs.length; i++) {
1426: try {
1427: attr = attrs[i];
1428: if (!isAttributeCategorySupported(attr.getCategory())) {
1429: unsupp.add(attr);
1430: } else if (!isAttributeValueSupported(attr, flavor,
1431: attributes)) {
1432: unsupp.add(attr);
1433: }
1434: } catch (ClassCastException e) {
1435: }
1436: }
1437: if (unsupp.isEmpty()) {
1438: return null;
1439: } else {
1440: return unsupp;
1441: }
1442: }
1443:
1444: public ServiceUIFactory getServiceUIFactory() {
1445: return null;
1446: }
1447:
1448: public String toString() {
1449: return "Win32 Printer : " + getName();
1450: }
1451:
1452: public boolean equals(Object obj) {
1453: return (obj == this || (obj instanceof Win32PrintService && ((Win32PrintService) obj)
1454: .getName().equals(getName())));
1455: }
1456:
1457: public int hashCode() {
1458: return this .getClass().hashCode() + getName().hashCode();
1459: }
1460:
1461: public boolean usesClass(Class c) {
1462: return (c == sun.awt.windows.WPrinterJob.class);
1463: }
1464:
1465: private native int[] getAllMediaIDs(String printerName, String port);
1466:
1467: private native int[] getAllMediaSizes(String printerName,
1468: String port);
1469:
1470: private native int[] getAllMediaTrays(String printerName,
1471: String port);
1472:
1473: private native float[] getMediaPrintableArea(String printerName,
1474: int paperSize);
1475:
1476: private native String[] getAllMediaNames(String printerName,
1477: String port);
1478:
1479: private native String[] getAllMediaTrayNames(String printerName,
1480: String port);
1481:
1482: private native int getCopiesSupported(String printerName,
1483: String port);
1484:
1485: private native int[] getAllResolutions(String printerName,
1486: String port);
1487:
1488: private native int getCapabilities(String printerName, String port);
1489:
1490: private native int[] getDefaultSettings(String printerName);
1491:
1492: private native int getJobStatus(String printerName, int type);
1493:
1494: private native String getPrinterPort(String printerName);
1495: }
1496:
1497: class Win32MediaSize extends MediaSizeName {
1498: private static ArrayList winStringTable = new ArrayList();
1499: private static ArrayList winEnumTable = new ArrayList();
1500:
1501: private Win32MediaSize(int x) {
1502: super (x);
1503:
1504: }
1505:
1506: private synchronized static int nextValue(String name) {
1507: winStringTable.add(name);
1508: return (winStringTable.size() - 1);
1509: }
1510:
1511: public Win32MediaSize(String name) {
1512: super (nextValue(name));
1513: winEnumTable.add(this );
1514: }
1515:
1516: private MediaSizeName[] getSuperEnumTable() {
1517: return (MediaSizeName[]) super .getEnumValueTable();
1518: }
1519:
1520: static {
1521: /* initialize Win32PrintService.predefMedia */
1522: {
1523: Win32MediaSize winMedia = new Win32MediaSize(-1);
1524:
1525: // cannot call getSuperEnumTable directly because of static context
1526: MediaSizeName[] enumMedia = winMedia.getSuperEnumTable();
1527: if (enumMedia != null) {
1528: Win32PrintService.predefMedia = new MediaSize[enumMedia.length];
1529:
1530: for (int i = 0; i < enumMedia.length; i++) {
1531: Win32PrintService.predefMedia[i] = MediaSize
1532: .getMediaSizeForName(enumMedia[i]);
1533: }
1534: }
1535: }
1536: }
1537:
1538: protected String[] getStringTable() {
1539: String[] nameTable = new String[winStringTable.size()];
1540: return (String[]) winStringTable.toArray(nameTable);
1541: }
1542:
1543: protected EnumSyntax[] getEnumValueTable() {
1544: MediaSizeName[] enumTable = new MediaSizeName[winEnumTable
1545: .size()];
1546: return (MediaSizeName[]) winEnumTable.toArray(enumTable);
1547: }
1548:
1549: }
|