diff -r fd16c54261b3 -r 90ce3da70b43 jdk/src/windows/classes/sun/print/Win32PrintService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/windows/classes/sun/print/Win32PrintService.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,1601 @@ +/* + * Copyright 2000-2006 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.print; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import java.util.Vector; + +import javax.print.DocFlavor; +import javax.print.DocPrintJob; +import javax.print.PrintService; +import javax.print.ServiceUIFactory; +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.AttributeSetUtilities; +import javax.print.attribute.EnumSyntax; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.PrintServiceAttribute; +import javax.print.attribute.PrintServiceAttributeSet; +import javax.print.attribute.HashPrintServiceAttributeSet; +import javax.print.attribute.standard.PrinterName; +import javax.print.attribute.standard.PrinterIsAcceptingJobs; +import javax.print.attribute.standard.QueuedJobCount; +import javax.print.attribute.standard.JobName; +import javax.print.attribute.standard.RequestingUserName; +import javax.print.attribute.standard.Chromaticity; +import javax.print.attribute.standard.Copies; +import javax.print.attribute.standard.CopiesSupported; +import javax.print.attribute.standard.Destination; +import javax.print.attribute.standard.Fidelity; +import javax.print.attribute.standard.Media; +import javax.print.attribute.standard.MediaSizeName; +import javax.print.attribute.standard.MediaSize; +import javax.print.attribute.standard.MediaTray; +import javax.print.attribute.standard.MediaPrintableArea; +import javax.print.attribute.standard.OrientationRequested; +import javax.print.attribute.standard.PageRanges; +import javax.print.attribute.standard.PrinterState; +import javax.print.attribute.standard.PrinterStateReason; +import javax.print.attribute.standard.PrinterStateReasons; +import javax.print.attribute.standard.Severity; +import javax.print.attribute.standard.Sides; +import javax.print.attribute.standard.ColorSupported; +import javax.print.attribute.standard.PrintQuality; +import javax.print.attribute.ResolutionSyntax; +import javax.print.attribute.standard.PrinterResolution; +import javax.print.attribute.standard.SheetCollate; +import javax.print.event.PrintServiceAttributeListener; +import java.util.ArrayList; + +import sun.print.SunPrinterJobService; + +public class Win32PrintService implements PrintService, AttributeUpdater, + SunPrinterJobService { + + public static MediaSize[] predefMedia; + + static { + Class c = Win32MediaSize.class; + } + + private static final DocFlavor[] supportedFlavors = { + DocFlavor.BYTE_ARRAY.GIF, + DocFlavor.INPUT_STREAM.GIF, + DocFlavor.URL.GIF, + DocFlavor.BYTE_ARRAY.JPEG, + DocFlavor.INPUT_STREAM.JPEG, + DocFlavor.URL.JPEG, + DocFlavor.BYTE_ARRAY.PNG, + DocFlavor.INPUT_STREAM.PNG, + DocFlavor.URL.PNG, + DocFlavor.SERVICE_FORMATTED.PAGEABLE, + DocFlavor.SERVICE_FORMATTED.PRINTABLE, + DocFlavor.BYTE_ARRAY.AUTOSENSE, + DocFlavor.URL.AUTOSENSE, + DocFlavor.INPUT_STREAM.AUTOSENSE + }; + + /* let's try to support a few of these */ + private static final Class[] serviceAttrCats = { + PrinterName.class, + PrinterIsAcceptingJobs.class, + QueuedJobCount.class, + ColorSupported.class, + }; + + /* it turns out to be inconvenient to store the other categories + * separately because many attributes are in multiple categories. + */ + private static Class[] otherAttrCats = { + JobName.class, + RequestingUserName.class, + Copies.class, + Destination.class, + OrientationRequested.class, + PageRanges.class, + Media.class, + MediaPrintableArea.class, + Fidelity.class, + // We support collation on 2D printer jobs, even if the driver can't. + SheetCollate.class, + SunAlternateMedia.class, + Chromaticity.class + }; + + + /* + * This table together with methods findWin32Media and + * findMatchingMediaSizeNameMM are declared public as these are also + * used in WPrinterJob.java. + */ + public static final MediaSizeName[] dmPaperToPrintService = { + MediaSizeName.NA_LETTER, MediaSizeName.NA_LETTER, + MediaSizeName.TABLOID, MediaSizeName.LEDGER, + MediaSizeName.NA_LEGAL, MediaSizeName.INVOICE, + MediaSizeName.EXECUTIVE, MediaSizeName.ISO_A3, + MediaSizeName.ISO_A4, MediaSizeName.ISO_A4, + MediaSizeName.ISO_A5, MediaSizeName.JIS_B4, + MediaSizeName.JIS_B5, MediaSizeName.FOLIO, + MediaSizeName.QUARTO, MediaSizeName.NA_10X14_ENVELOPE, + MediaSizeName.B, MediaSizeName.NA_LETTER, + MediaSizeName.NA_NUMBER_9_ENVELOPE, MediaSizeName.NA_NUMBER_10_ENVELOPE, + MediaSizeName.NA_NUMBER_11_ENVELOPE, MediaSizeName.NA_NUMBER_12_ENVELOPE, + MediaSizeName.NA_NUMBER_14_ENVELOPE, MediaSizeName.C, + MediaSizeName.D, MediaSizeName.E, + MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.ISO_C5, + MediaSizeName.ISO_C3, MediaSizeName.ISO_C4, + MediaSizeName.ISO_C6, MediaSizeName.ITALY_ENVELOPE, + MediaSizeName.ISO_B4, MediaSizeName.ISO_B5, + MediaSizeName.ISO_B6, MediaSizeName.ITALY_ENVELOPE, + MediaSizeName.MONARCH_ENVELOPE, MediaSizeName.PERSONAL_ENVELOPE, + MediaSizeName.NA_10X15_ENVELOPE, MediaSizeName.NA_9X12_ENVELOPE, + MediaSizeName.FOLIO, MediaSizeName.ISO_B4, + MediaSizeName.JAPANESE_POSTCARD, MediaSizeName.NA_9X11_ENVELOPE, + }; + + private static final MediaTray[] dmPaperBinToPrintService = { + MediaTray.TOP, MediaTray.BOTTOM, MediaTray.MIDDLE, + MediaTray.MANUAL, MediaTray.ENVELOPE, Win32MediaTray.ENVELOPE_MANUAL, + Win32MediaTray.AUTO, Win32MediaTray.TRACTOR, + Win32MediaTray.SMALL_FORMAT, Win32MediaTray.LARGE_FORMAT, + MediaTray.LARGE_CAPACITY, null, null, + MediaTray.MAIN, Win32MediaTray.FORMSOURCE, + }; + + // from wingdi.h + private static int DM_PAPERSIZE = 0x2; + private static int DM_PRINTQUALITY = 0x400; + private static int DM_YRESOLUTION = 0x2000; + private static final int DMRES_MEDIUM = -3; + private static final int DMRES_HIGH = -4; + private static final int DMORIENT_LANDSCAPE = 2; + private static final int DMDUP_VERTICAL = 2; + private static final int DMDUP_HORIZONTAL = 3; + private static final int DMCOLLATE_TRUE = 1; + + // media sizes with indices above dmPaperToPrintService' length + private static final int DMPAPER_A2 = 66; + private static final int DMPAPER_A6 = 70; + private static final int DMPAPER_B6_JIS = 88; + + + // Bit settings for getPrinterCapabilities which matches that + // of native getCapabilities in WPrinterJob.cpp + private static final int DEVCAP_COLOR = 0x0001; + private static final int DEVCAP_DUPLEX = 0x0002; + private static final int DEVCAP_COLLATE = 0x0004; + private static final int DEVCAP_QUALITY = 0x0008; + private static final int DEVCAP_POSTSCRIPT = 0x0010; + + private String printer; + private PrinterName name; + private String port; + + transient private PrintServiceAttributeSet lastSet; + transient private ServiceNotifier notifier = null; + + private MediaSizeName[] mediaSizeNames; + private MediaPrintableArea[] mediaPrintables; + private MediaTray[] mediaTrays; + private PrinterResolution[] printRes; + private int nCopies; + private int prnCaps; + private int[] defaultSettings; + + private boolean gotTrays; + private boolean gotCopies; + private boolean mediaInitialized; + + private ArrayList idList; + private MediaSize[] mediaSizes; + + private boolean isInvalid; + + Win32PrintService(String name) { + if (name == null) { + throw new IllegalArgumentException("null printer name"); + } + printer = name; + + // initialize flags + mediaInitialized = false; + gotTrays = false; + gotCopies = false; + isInvalid = false; + printRes = null; + prnCaps = 0; + defaultSettings = null; + port = null; + } + + public void invalidateService() { + isInvalid = true; + } + + public String getName() { + return printer; + } + + private PrinterName getPrinterName() { + if (name == null) { + name = new PrinterName(printer, null); + } + return name; + } + + public int findPaperID(MediaSizeName msn) { + if (msn instanceof Win32MediaSize) { + Win32MediaSize winMedia = (Win32MediaSize)msn; + return winMedia.getDMPaper(); + } else { + for (int id=0; id= 1 && dmBin <= dmPaperBinToPrintService.length) { + return dmPaperBinToPrintService[dmBin-1]; + } + MediaTray[] trays = getMediaTrays(); + if (trays != null) { + for (int i=0;i= 1 && dmIndex <= dmPaperToPrintService.length) { + switch(dmIndex) { + /* matching media sizes with indices beyond + dmPaperToPrintService's length */ + case DMPAPER_A2: + return MediaSizeName.ISO_A2; + case DMPAPER_A6: + return MediaSizeName.ISO_A6; + case DMPAPER_B6_JIS: + return MediaSizeName.JIS_B6; + default: + return dmPaperToPrintService[dmIndex - 1]; + } + } + + return null; + } + + private boolean addToUniqueList(ArrayList msnList, MediaSizeName mediaName) { + MediaSizeName msn; + for (int i=0; i< msnList.size(); i++) { + msn = (MediaSizeName)msnList.get(i); + if (msn == mediaName) { + return false; + } + } + msnList.add(mediaName); + return true; + } + + private synchronized void initMedia() { + if (mediaInitialized == true) { + return; + } + mediaInitialized = true; + int[] media = getAllMediaIDs(printer, getPort()); + if (media == null) { + return; + } + + ArrayList msnList = new ArrayList(); + ArrayList printableList = new ArrayList(); + MediaSizeName mediaName; + boolean added; + boolean queryFailure = false; + float[] prnArea; + + // Get all mediaSizes supported by the printer. + // We convert media to ArrayList idList and pass this to the + // function for getting mediaSizes. + // This is to ensure that mediaSizes and media IDs have 1-1 correspondence. + // We remove from ID list any invalid mediaSize. Though this is rare, + // it happens in HP 4050 German driver. + + idList = new ArrayList(); + for (int i=0; i < media.length; i++) { + idList.add(new Integer(media[i])); + } + + mediaSizes = getMediaSizes(idList, media); + for (int i = 0; i < idList.size(); i++) { + + // match Win ID with our predefined ID using table + mediaName = findWin32Media(((Integer)idList.get(i)).intValue()); + // Verify that this standard size is the same size as that + // reported by the driver. This should be the case except when + // the driver is mis-using a standard windows paper ID. + if (mediaName != null && + idList.size() == mediaSizes.length) { + MediaSize win32Size = MediaSize.getMediaSizeForName(mediaName); + MediaSize driverSize = mediaSizes[i]; + int error = 2540; // == 1/10" + if (Math.abs(win32Size.getX(1)-driverSize.getX(1)) > error || + Math.abs(win32Size.getY(1)-driverSize.getY(1)) > error) + { + mediaName = null; + } + } + + // No match found, then we get the MediaSizeName out of the MediaSize + // This requires 1-1 correspondence, lengths must be checked. + if ((mediaName == null) && (idList.size() == mediaSizes.length)) { + mediaName = mediaSizes[i].getMediaSizeName(); + } + + // Add mediaName to the msnList + if (mediaName != null) { + added = addToUniqueList(msnList, mediaName); + + // get MediaPrintableArea only for supported MediaSizeName ? + if (added && !queryFailure) { + prnArea=getMediaPrintableArea(printer, + ((Integer)idList.get(i)).intValue()); + if (prnArea != null) { + try { + MediaPrintableArea mpa = + new MediaPrintableArea(prnArea[0], + prnArea[1], + prnArea[2], + prnArea[3], + MediaPrintableArea.INCH); + printableList.add(mpa); + } catch (IllegalArgumentException iae) { + } + } else { + // Calling getMediaPrintableArea causes + // much overhead so if first attempt failed, we should + // just bail out. + if (i==0) { + queryFailure = true; + } + } + } + } + } + + // init mediaSizeNames + mediaSizeNames = new MediaSizeName[msnList.size()]; + msnList.toArray(mediaSizeNames); + + // init mediaPrintables + mediaPrintables = new MediaPrintableArea[printableList.size()]; + printableList.toArray(mediaPrintables); + } + + private synchronized MediaTray[] getMediaTrays() { + if (gotTrays == true && mediaTrays != null) { + return mediaTrays; + } + String prnPort = getPort(); + int[] mediaTr = getAllMediaTrays(printer, prnPort); + String[] winMediaTrayNames = getAllMediaTrayNames(printer, prnPort); + + if ((mediaTr == null) || (winMediaTrayNames == null)){ + return null; + } + + /* first count how many valid bins there are so we can allocate + * an array of the correct size + */ + int nTray = 0; + for (int i=0; i < mediaTr.length ; i++) { + if (mediaTr[i] > 0) nTray++; + } + + MediaTray[] arr = new MediaTray[nTray]; + int dmBin; + for (int i = 0, j=0; i < mediaTr.length; i++) { + dmBin = mediaTr[i]; + if (dmBin > 0) { + // check for unsupported DMBINs and create new Win32MediaTray + if ((dmBin > dmPaperBinToPrintService.length) + || (dmPaperBinToPrintService[dmBin-1] == null)) { + arr[j++] = new Win32MediaTray(dmBin, winMediaTrayNames[i]); + } else { + arr[j++] = dmPaperBinToPrintService[dmBin-1]; + } + } + // no else - For invalid ids, just ignore it because assigning a "default" + // value may result in duplicate trays. + } + mediaTrays = arr; + gotTrays = true; + return mediaTrays; + } + + private boolean isSameSize(float w1, float h1, float w2, float h2) { + float diffX = w1 - w2; + float diffY = h1 - h2; + // Get diff of reverse dimensions + // EPSON Stylus COLOR 860 reverses envelope's width & height + float diffXrev = w1 - h2; + float diffYrev = h1 - w2; + + if (((Math.abs(diffX)<=1) && (Math.abs(diffY)<=1)) || + ((Math.abs(diffXrev)<=1) && (Math.abs(diffYrev)<=1))){ + return true; + } else { + return false; + } + } + + public MediaSizeName findMatchingMediaSizeNameMM (float w, float h){ + if (predefMedia != null) { + for (int k=0; k 0 && numCopies <= nCopies); + } + + private boolean isSupportedMedia(MediaSizeName msn) { + + initMedia(); + + if (mediaSizeNames != null) { + for (int i=0; i T + getAttribute(Class category) + { + if (category == null) { + throw new NullPointerException("category"); + } + if (!(PrintServiceAttribute.class.isAssignableFrom(category))) { + throw new IllegalArgumentException("Not a PrintServiceAttribute"); + } + if (category == ColorSupported.class) { + int caps = getPrinterCapabilities(); + if ((caps & DEVCAP_COLOR) != 0) { + return (T)ColorSupported.SUPPORTED; + } else { + return (T)ColorSupported.NOT_SUPPORTED; + } + } else if (category == PrinterName.class) { + return (T)getPrinterName(); + } else if (category == PrinterState.class) { + return (T)getPrinterState(); + } else if (category == PrinterStateReasons.class) { + return (T)getPrinterStateReasons(); + } else if (category == QueuedJobCount.class) { + return (T)getQueuedJobCount(); + } else if (category == PrinterIsAcceptingJobs.class) { + return (T)getPrinterIsAcceptingJobs(); + } else { + return null; + } + } + + public PrintServiceAttributeSet getAttributes() { + + PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet(); + attrs.add(getPrinterName()); + attrs.add(getPrinterIsAcceptingJobs()); + PrinterState prnState = getPrinterState(); + if (prnState != null) { + attrs.add(prnState); + } + PrinterStateReasons prnStateReasons = getPrinterStateReasons(); + if (prnStateReasons != null) { + attrs.add(prnStateReasons); + } + attrs.add(getQueuedJobCount()); + int caps = getPrinterCapabilities(); + if ((caps & DEVCAP_COLOR) != 0) { + attrs.add(ColorSupported.SUPPORTED); + } else { + attrs.add(ColorSupported.NOT_SUPPORTED); + } + + return AttributeSetUtilities.unmodifiableView(attrs); + } + + public DocFlavor[] getSupportedDocFlavors() { + int len = supportedFlavors.length; + DocFlavor[] supportedDocFlavors; + int caps = getPrinterCapabilities(); + // doc flavors supported + // if PostScript is supported + if ((caps & DEVCAP_POSTSCRIPT) != 0) { + supportedDocFlavors = new DocFlavor[len+3]; + System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len); + supportedDocFlavors[len] = DocFlavor.BYTE_ARRAY.POSTSCRIPT; + supportedDocFlavors[len+1] = DocFlavor.INPUT_STREAM.POSTSCRIPT; + supportedDocFlavors[len+2] = DocFlavor.URL.POSTSCRIPT; + } else { + supportedDocFlavors = new DocFlavor[len]; + System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len); + } + return supportedDocFlavors; + } + + public boolean isDocFlavorSupported(DocFlavor flavor) { + /* To avoid a native query which may be time-consuming + * do not invoke native unless postscript support is being queried. + * Instead just check the ones we 'always' support + */ + DocFlavor[] supportedDocFlavors; + if (isPostScriptFlavor(flavor)) { + supportedDocFlavors = getSupportedDocFlavors(); + } else { + supportedDocFlavors = supportedFlavors; + } + for (int f=0; f[] getSupportedAttributeCategories() { + ArrayList categList = new ArrayList(otherAttrCats.length+3); + for (int i=0; i < otherAttrCats.length; i++) { + categList.add(otherAttrCats[i]); + } + + int caps = getPrinterCapabilities(); + + if ((caps & DEVCAP_DUPLEX) != 0) { + categList.add(Sides.class); + } + + if ((caps & DEVCAP_QUALITY) != 0) { + int[] defaults = getDefaultPrinterSettings(); + // Added check: if supported, we should be able to get the default. + if ((defaults[3] >= DMRES_HIGH) && (defaults[3] < 0)) { + categList.add(PrintQuality.class); + } + } + + PrinterResolution[] supportedRes = getPrintResolutions(); + if ((supportedRes!=null) && (supportedRes.length>0)) { + categList.add(PrinterResolution.class); + } + + return (Class[])categList.toArray(new Class[categList.size()]); + } + + public boolean + isAttributeCategorySupported(Class category) + { + + if (category == null) { + throw new NullPointerException("null category"); + } + + if (!(Attribute.class.isAssignableFrom(category))) { + throw new IllegalArgumentException(category + + " is not an Attribute"); + } + + Class[] classList = getSupportedAttributeCategories(); + for (int i = 0; i < classList.length; i++) { + if (category.equals(classList[i])) { + return true; + } + } + + return false; + } + + public Object + getDefaultAttributeValue(Class category) + { + if (category == null) { + throw new NullPointerException("null category"); + } + if (!Attribute.class.isAssignableFrom(category)) { + throw new IllegalArgumentException(category + + " is not an Attribute"); + } + + if (!isAttributeCategorySupported(category)) { + return null; + } + + int[] defaults = getDefaultPrinterSettings(); + // indices must match those in WPrinterJob.cpp + int defPaper = defaults[0]; + int defYRes = defaults[2]; + int defQuality = defaults[3]; + int defCopies = defaults[4]; + int defOrient = defaults[5]; + int defSides = defaults[6]; + int defCollate = defaults[7]; + + if (category == Copies.class) { + if (defCopies > 0) { + return new Copies(defCopies); + } else { + return new Copies(1); + } + } else if (category == Chromaticity.class) { + int caps = getPrinterCapabilities(); + if ((caps & DEVCAP_COLOR) == 0) { + return Chromaticity.MONOCHROME; + } else { + return Chromaticity.COLOR; + } + } else if (category == JobName.class) { + return new JobName("Java Printing", null); + } else if (category == OrientationRequested.class) { + if (defOrient == DMORIENT_LANDSCAPE) { + return OrientationRequested.LANDSCAPE; + } else { + return OrientationRequested.PORTRAIT; + } + } else if (category == PageRanges.class) { + return new PageRanges(1, Integer.MAX_VALUE); + } else if (category == Media.class) { + MediaSizeName msn = findWin32Media(defPaper); + if (msn != null) { + if (!isSupportedMedia(msn) && mediaSizeNames != null) { + msn = mediaSizeNames[0]; + defPaper = findPaperID(msn); + } + return msn; + } else { + initMedia(); + if ((mediaSizeNames != null) && (mediaSizeNames.length > 0)) { + // if 'mediaSizeNames' is not null, idList and mediaSizes + // cannot be null but to be safe, add a check + if ((idList != null) && (mediaSizes != null) && + (idList.size() == mediaSizes.length)) { + Integer defIdObj = new Integer(defPaper); + int index = idList.indexOf(defIdObj); + if (index>=0 && index xRes) ? yRes : xRes; + if (res > 0) { + return new PrinterResolution(res, res, PrinterResolution.DPI); + } + } + else { + return new PrinterResolution(xRes, yRes, PrinterResolution.DPI); + } + } else if (category == ColorSupported.class) { + int caps = getPrinterCapabilities(); + if ((caps & DEVCAP_COLOR) != 0) { + return ColorSupported.SUPPORTED; + } else { + return ColorSupported.NOT_SUPPORTED; + } + } else if (category == PrintQuality.class) { + if ((defQuality < 0) && (defQuality >= DMRES_HIGH)) { + switch (defQuality) { + case DMRES_HIGH: + return PrintQuality.HIGH; + case DMRES_MEDIUM: + return PrintQuality.NORMAL; + default: + return PrintQuality.DRAFT; + } + } + } else if (category == RequestingUserName.class) { + String userName = ""; + try { + userName = System.getProperty("user.name", ""); + } catch (SecurityException se) { + } + return new RequestingUserName(userName, null); + } else if (category == SheetCollate.class) { + if (defCollate == DMCOLLATE_TRUE) { + return SheetCollate.COLLATED; + } else { + return SheetCollate.UNCOLLATED; + } + } else if (category == Fidelity.class) { + return Fidelity.FIDELITY_FALSE; + } + return null; + } + + private boolean isPostScriptFlavor(DocFlavor flavor) { + if (flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT) || + flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) || + flavor.equals(DocFlavor.URL.POSTSCRIPT)) { + return true; + } + else { + return false; + } + } + + private boolean isPSDocAttr(Class category) { + if (category == OrientationRequested.class || category == Copies.class) { + return true; + } + else { + return false; + } + } + + private boolean isAutoSense(DocFlavor flavor) { + if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE) || + flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE) || + flavor.equals(DocFlavor.URL.AUTOSENSE)) { + return true; + } + else { + return false; + } + } + + public Object + getSupportedAttributeValues(Class category, + DocFlavor flavor, + AttributeSet attributes) + { + if (category == null) { + throw new NullPointerException("null category"); + } + if (!Attribute.class.isAssignableFrom(category)) { + throw new IllegalArgumentException(category + + " does not implement Attribute"); + } + if (flavor != null) { + if (!isDocFlavorSupported(flavor)) { + throw new IllegalArgumentException(flavor + + " is an unsupported flavor"); + // if postscript & category is already specified within the + // PostScript data we return null + } else if (isAutoSense(flavor) ||(isPostScriptFlavor(flavor) && + (isPSDocAttr(category)))){ + return null; + } + } + if (!isAttributeCategorySupported(category)) { + return null; + } + + if (category == JobName.class) { + return new JobName("Java Printing", null); + } else if (category == RequestingUserName.class) { + String userName = ""; + try { + userName = System.getProperty("user.name", ""); + } catch (SecurityException se) { + } + return new RequestingUserName(userName, null); + } else if (category == ColorSupported.class) { + int caps = getPrinterCapabilities(); + if ((caps & DEVCAP_COLOR) != 0) { + return ColorSupported.SUPPORTED; + } else { + return ColorSupported.NOT_SUPPORTED; + } + } else if (category == Chromaticity.class) { + if (flavor == null || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) || + flavor.equals(DocFlavor.BYTE_ARRAY.GIF) || + flavor.equals(DocFlavor.INPUT_STREAM.GIF) || + flavor.equals(DocFlavor.URL.GIF) || + flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) || + flavor.equals(DocFlavor.INPUT_STREAM.JPEG) || + flavor.equals(DocFlavor.URL.JPEG) || + flavor.equals(DocFlavor.BYTE_ARRAY.PNG) || + flavor.equals(DocFlavor.INPUT_STREAM.PNG) || + flavor.equals(DocFlavor.URL.PNG)) { + int caps = getPrinterCapabilities(); + if ((caps & DEVCAP_COLOR) == 0) { + Chromaticity []arr = new Chromaticity[1]; + arr[0] = Chromaticity.MONOCHROME; + return (arr); + } else { + Chromaticity []arr = new Chromaticity[2]; + arr[0] = Chromaticity.MONOCHROME; + arr[1] = Chromaticity.COLOR; + return (arr); + } + } else { + return null; + } + } else if (category == Destination.class) { + try { + return new Destination((new File("out.prn")).toURI()); + } catch (SecurityException se) { + try { + return new Destination(new URI("file:out.prn")); + } catch (URISyntaxException e) { + return null; + } + } + } else if (category == OrientationRequested.class) { + if (flavor == null || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) || + flavor.equals(DocFlavor.INPUT_STREAM.GIF) || + flavor.equals(DocFlavor.INPUT_STREAM.JPEG) || + flavor.equals(DocFlavor.INPUT_STREAM.PNG) || + flavor.equals(DocFlavor.BYTE_ARRAY.GIF) || + flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) || + flavor.equals(DocFlavor.BYTE_ARRAY.PNG) || + flavor.equals(DocFlavor.URL.GIF) || + flavor.equals(DocFlavor.URL.JPEG) || + flavor.equals(DocFlavor.URL.PNG)) { + OrientationRequested []arr = new OrientationRequested[3]; + arr[0] = OrientationRequested.PORTRAIT; + arr[1] = OrientationRequested.LANDSCAPE; + arr[2] = OrientationRequested.REVERSE_LANDSCAPE; + return arr; + } else { + return null; + } + } else if ((category == Copies.class) || + (category == CopiesSupported.class)) { + synchronized (this) { + if (gotCopies == false) { + nCopies = getCopiesSupported(printer, getPort()); + gotCopies = true; + } + } + return new CopiesSupported(1, nCopies); + } else if (category == Media.class) { + + initMedia(); + + int len = (mediaSizeNames == null) ? 0 : mediaSizeNames.length; + + MediaTray[] trays = getMediaTrays(); + + len += (trays == null) ? 0 : trays.length; + + Media []arr = new Media[len]; + if (mediaSizeNames != null) { + System.arraycopy(mediaSizeNames, 0, arr, + 0, mediaSizeNames.length); + } + if (trays != null) { + System.arraycopy(trays, 0, arr, + mediaSizeNames.length, trays.length); + } + return arr; + } else if (category == MediaPrintableArea.class) { + initMedia(); + + if (mediaPrintables == null) { + return null; + } + + // if getting printable area for a specific media size + Media mediaName; + if ((attributes != null) && + ((mediaName = + (Media)attributes.get(Media.class)) != null)) { + + if (mediaName instanceof MediaSizeName) { + MediaPrintableArea []arr = new MediaPrintableArea[1]; + + if (mediaSizeNames.length == mediaPrintables.length) { + + for (int j=0; j < mediaSizeNames.length; j++) { + + if (mediaName.equals(mediaSizeNames[j])) { + arr[0] = mediaPrintables[j]; + return arr; + } + } + } + + MediaSize ms = + MediaSize.getMediaSizeForName((MediaSizeName)mediaName); + + if (ms != null) { + arr[0] = new MediaPrintableArea(0, 0, + ms.getX(MediaSize.INCH), + ms.getY(MediaSize.INCH), + MediaPrintableArea.INCH); + return arr; + } else { + return null; + } + } + // else an instance of MediaTray, fall thru returning + // all MediaPrintableAreas + } + + MediaPrintableArea []arr = + new MediaPrintableArea[mediaPrintables.length]; + System.arraycopy(mediaPrintables, 0, arr, 0, mediaPrintables.length); + return arr; + } else if (category == SunAlternateMedia.class) { + return new SunAlternateMedia( + (Media)getDefaultAttributeValue(Media.class)); + } else if (category == PageRanges.class) { + if (flavor == null || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) { + PageRanges []arr = new PageRanges[1]; + arr[0] = new PageRanges(1, Integer.MAX_VALUE); + return arr; + } else { + return null; + } + } else if (category == PrinterResolution.class) { + PrinterResolution[] supportedRes = getPrintResolutions(); + if (supportedRes == null) { + return null; + } + PrinterResolution []arr = + new PrinterResolution[supportedRes.length]; + System.arraycopy(supportedRes, 0, arr, 0, supportedRes.length); + return arr; + } else if (category == Sides.class) { + if (flavor == null || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) { + Sides []arr = new Sides[3]; + arr[0] = Sides.ONE_SIDED; + arr[1] = Sides.TWO_SIDED_LONG_EDGE; + arr[2] = Sides.TWO_SIDED_SHORT_EDGE; + return arr; + } else { + return null; + } + } else if (category == PrintQuality.class) { + PrintQuality []arr = new PrintQuality[3]; + arr[0] = PrintQuality.DRAFT; + arr[1] = PrintQuality.HIGH; + arr[2] = PrintQuality.NORMAL; + return arr; + } else if (category == SheetCollate.class) { + if (flavor == null || + (flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) { + SheetCollate []arr = new SheetCollate[2]; + arr[0] = SheetCollate.COLLATED; + arr[1] = SheetCollate.UNCOLLATED; + return arr; + } else { + return null; + } + } else if (category == Fidelity.class) { + Fidelity []arr = new Fidelity[2]; + arr[0] = Fidelity.FIDELITY_FALSE; + arr[1] = Fidelity.FIDELITY_TRUE; + return arr; + } else { + return null; + } + } + + public boolean isAttributeValueSupported(Attribute attr, + DocFlavor flavor, + AttributeSet attributes) { + + if (attr == null) { + throw new NullPointerException("null attribute"); + } + Class category = attr.getCategory(); + if (flavor != null) { + if (!isDocFlavorSupported(flavor)) { + throw new IllegalArgumentException(flavor + + " is an unsupported flavor"); + // if postscript & category is already specified within the PostScript data + // we return false + } else if (isAutoSense(flavor) || (isPostScriptFlavor(flavor) && + (isPSDocAttr(category)))) { + return false; + } + } + + if (!isAttributeCategorySupported(category)) { + return false; + } + else if (category == Chromaticity.class) { + if ((flavor == null) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) || + flavor.equals(DocFlavor.BYTE_ARRAY.GIF) || + flavor.equals(DocFlavor.INPUT_STREAM.GIF) || + flavor.equals(DocFlavor.URL.GIF) || + flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) || + flavor.equals(DocFlavor.INPUT_STREAM.JPEG) || + flavor.equals(DocFlavor.URL.JPEG) || + flavor.equals(DocFlavor.BYTE_ARRAY.PNG) || + flavor.equals(DocFlavor.INPUT_STREAM.PNG) || + flavor.equals(DocFlavor.URL.PNG)) { + int caps = getPrinterCapabilities(); + if ((caps & DEVCAP_COLOR) != 0) { + return true; + } else { + return attr == Chromaticity.MONOCHROME; + } + } else { + return false; + } + } else if (category == Copies.class) { + return isSupportedCopies((Copies)attr); + + } else if (category == Destination.class) { + URI uri = ((Destination)attr).getURI(); + if ("file".equals(uri.getScheme()) && + !(uri.getSchemeSpecificPart().equals(""))) { + return true; + } else { + return false; + } + + } else if (category == Media.class) { + if (attr instanceof MediaSizeName) { + return isSupportedMedia((MediaSizeName)attr); + } + if (attr instanceof MediaTray) { + return isSupportedMediaTray((MediaTray)attr); + } + + } else if (category == MediaPrintableArea.class) { + return isSupportedMediaPrintableArea((MediaPrintableArea)attr); + + } else if (category == SunAlternateMedia.class) { + Media media = ((SunAlternateMedia)attr).getMedia(); + return isAttributeValueSupported(media, flavor, attributes); + + } else if (category == PageRanges.class || + category == SheetCollate.class || + category == Sides.class) { + if (flavor != null && + !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) { + return false; + } + } else if (category == PrinterResolution.class) { + if (attr instanceof PrinterResolution) { + return isSupportedResolution((PrinterResolution)attr); + } + } else if (category == OrientationRequested.class) { + if (attr == OrientationRequested.REVERSE_PORTRAIT || + (flavor != null) && + !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) || + flavor.equals(DocFlavor.INPUT_STREAM.GIF) || + flavor.equals(DocFlavor.INPUT_STREAM.JPEG) || + flavor.equals(DocFlavor.INPUT_STREAM.PNG) || + flavor.equals(DocFlavor.BYTE_ARRAY.GIF) || + flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) || + flavor.equals(DocFlavor.BYTE_ARRAY.PNG) || + flavor.equals(DocFlavor.URL.GIF) || + flavor.equals(DocFlavor.URL.JPEG) || + flavor.equals(DocFlavor.URL.PNG))) { + return false; + } + + } else if (category == ColorSupported.class) { + int caps = getPrinterCapabilities(); + boolean isColorSup = ((caps & DEVCAP_COLOR) != 0); + if ((!isColorSup && (attr == ColorSupported.SUPPORTED)) || + (isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) { + return false; + } + } + return true; + } + + public AttributeSet getUnsupportedAttributes(DocFlavor flavor, + AttributeSet attributes) { + + if (flavor != null && !isDocFlavorSupported(flavor)) { + throw new IllegalArgumentException("flavor " + flavor + + "is not supported"); + } + + if (attributes == null) { + return null; + } + + Attribute attr; + AttributeSet unsupp = new HashAttributeSet(); + Attribute []attrs = attributes.toArray(); + for (int i=0; i