--- /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<dmPaperToPrintService.length;id++) {
+ if (dmPaperToPrintService[id].equals(msn)) {
+ return id+1; // DMPAPER_LETTER == 1
+ }
+ }
+ if (msn.equals(MediaSizeName.ISO_A2)) {
+ return DMPAPER_A2;
+ }
+ else if (msn.equals(MediaSizeName.ISO_A6)) {
+ return DMPAPER_A6;
+ }
+ else if (msn.equals(MediaSizeName.JIS_B6)) {
+ return DMPAPER_B6_JIS;
+ }
+ }
+ return 0;
+ }
+
+ public MediaTray findMediaTray(int dmBin) {
+ if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {
+ return dmPaperBinToPrintService[dmBin-1];
+ }
+ MediaTray[] trays = getMediaTrays();
+ if (trays != null) {
+ for (int i=0;i<trays.length;i++) {
+ if(trays[i] instanceof Win32MediaTray) {
+ Win32MediaTray win32Tray = (Win32MediaTray)trays[i];
+ if (win32Tray.winID == dmBin) {
+ return win32Tray;
+ }
+ }
+ }
+ }
+ return Win32MediaTray.AUTO;
+ }
+
+ public MediaSizeName findWin32Media(int dmIndex) {
+ if (dmIndex >= 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<predefMedia.length;k++) {
+ if (predefMedia[k] == null) {
+ continue;
+ }
+
+ if (isSameSize(predefMedia[k].getX(MediaSize.MM),
+ predefMedia[k].getY(MediaSize.MM),
+ w, h)) {
+ return predefMedia[k].getMediaSizeName();
+ }
+ }
+ }
+ return null;
+ }
+
+
+ private MediaSize[] getMediaSizes(ArrayList idList, int[] media) {
+ String prnPort = getPort();
+ int[] mediaSz = getAllMediaSizes(printer, prnPort);
+ String[] winMediaNames = getAllMediaNames(printer, prnPort);
+ MediaSizeName msn = null;
+ MediaSize ms = null;
+ float wid, ht;
+
+ if ((mediaSz == null) || (winMediaNames == null)) {
+ return null;
+ }
+
+ int nMedia = mediaSz.length/2;
+ ArrayList msList = new ArrayList();
+
+ for (int i = 0; i < nMedia; i++, ms=null) {
+ wid = mediaSz[i*2]/10f;
+ ht = mediaSz[i*2+1]/10f;
+
+ // Make sure to validate wid & ht.
+ // HP LJ 4050 (german) causes IAE in Sonderformat paper, wid & ht
+ // returned is not constant.
+ if ((wid <= 0) || (ht <= 0)) {
+ //Remove corresponding ID from list
+ if (nMedia == media.length) {
+ Integer remObj = new Integer(media[i]);
+ idList.remove(idList.indexOf(remObj));
+ }
+ continue;
+ }
+ // Find matching media using dimensions.
+ // This call matches only with our own predefined sizes.
+ msn = findMatchingMediaSizeNameMM(wid, ht);
+ if (msn != null) {
+ ms = MediaSize.getMediaSizeForName(msn);
+ }
+
+ if (ms != null) {
+ msList.add(ms);
+ } else {
+ Win32MediaSize wms =
+ new Win32MediaSize(winMediaNames[i], media[i]);
+ try {
+ ms = new MediaSize(wid, ht, MediaSize.MM, wms);
+ msList.add(ms);
+ } catch(IllegalArgumentException e) {
+ if (nMedia == media.length) {
+ Integer remObj = new Integer(media[i]);
+ idList.remove(idList.indexOf(remObj));
+ }
+ }
+ }
+
+ }
+
+ MediaSize[] arr2 = new MediaSize[msList.size()];
+ msList.toArray(arr2);
+
+ return arr2;
+ }
+
+
+ private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
+ if (getJobStatus(printer, 2) != 1) {
+ return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
+ }
+ else {
+ return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
+ }
+ }
+
+ private PrinterState getPrinterState() {
+ if (isInvalid) {
+ return PrinterState.STOPPED;
+ } else {
+ return null;
+ }
+ }
+
+ private PrinterStateReasons getPrinterStateReasons() {
+ if (isInvalid) {
+ PrinterStateReasons psr = new PrinterStateReasons();
+ psr.put(PrinterStateReason.SHUTDOWN, Severity.ERROR);
+ return psr;
+ } else {
+ return null;
+ }
+ }
+
+ private QueuedJobCount getQueuedJobCount() {
+
+ int count = getJobStatus(printer, 1);
+ if (count != -1) {
+ return new QueuedJobCount(count);
+ }
+ else {
+ return new QueuedJobCount(0);
+ }
+ }
+
+ private boolean isSupportedCopies(Copies copies) {
+ synchronized (this) {
+ if (gotCopies == false) {
+ nCopies = getCopiesSupported(printer, getPort());
+ gotCopies = true;
+ }
+ }
+ int numCopies = copies.getValue();
+ return (numCopies > 0 && numCopies <= nCopies);
+ }
+
+ private boolean isSupportedMedia(MediaSizeName msn) {
+
+ initMedia();
+
+ if (mediaSizeNames != null) {
+ for (int i=0; i<mediaSizeNames.length; i++) {
+ if (msn.equals(mediaSizeNames[i])) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isSupportedMediaPrintableArea(MediaPrintableArea mpa) {
+
+ initMedia();
+
+ if (mediaPrintables != null) {
+ for (int i=0; i<mediaPrintables.length; i++) {
+ if (mpa.equals(mediaPrintables[i])) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isSupportedMediaTray(MediaTray msn) {
+ MediaTray[] trays = getMediaTrays();
+
+ if (trays != null) {
+ for (int i=0; i<trays.length; i++) {
+ if (msn.equals(trays[i])) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private int getPrinterCapabilities() {
+ if (prnCaps == 0) {
+ prnCaps = getCapabilities(printer, getPort());
+ }
+ return prnCaps;
+ }
+
+ private String getPort() {
+ if (port == null) {
+ port = getPrinterPort(printer);
+ }
+ return port;
+ }
+
+ /*
+ * NOTE: defaults indices must match those in WPrinterJob.cpp
+ */
+ private int[] getDefaultPrinterSettings() {
+ if (defaultSettings == null) {
+ defaultSettings = getDefaultSettings(printer, getPort());
+ }
+ return defaultSettings;
+ }
+
+ private PrinterResolution[] getPrintResolutions() {
+ if (printRes == null) {
+ int[] prnRes = getAllResolutions(printer, getPort());
+ if (prnRes == null) {
+ printRes = new PrinterResolution[0];
+ } else {
+ int nRes = prnRes.length/2;
+
+ ArrayList arrList = new ArrayList();
+ PrinterResolution pr;
+
+ for (int i=0; i<nRes; i++) {
+ try {
+ pr = new PrinterResolution(prnRes[i*2],
+ prnRes[i*2+1], PrinterResolution.DPI);
+ arrList.add(pr);
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ printRes = (PrinterResolution[])arrList.toArray(
+ new PrinterResolution[arrList.size()]);
+ }
+ }
+ return printRes;
+ }
+
+ private boolean isSupportedResolution(PrinterResolution res) {
+ PrinterResolution[] supportedRes = getPrintResolutions();
+ if (supportedRes != null) {
+ for (int i=0; i<supportedRes.length; i++) {
+ if (res.equals(supportedRes[i])) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public DocPrintJob createPrintJob() {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+ return new Win32PrintJob(this);
+ }
+
+ private PrintServiceAttributeSet getDynamicAttributes() {
+ PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
+ attrs.add(getPrinterIsAcceptingJobs());
+ attrs.add(getQueuedJobCount());
+ return attrs;
+ }
+
+ public PrintServiceAttributeSet getUpdatedAttributes() {
+ PrintServiceAttributeSet currSet = getDynamicAttributes();
+ if (lastSet == null) {
+ lastSet = currSet;
+ return AttributeSetUtilities.unmodifiableView(currSet);
+ } else {
+ PrintServiceAttributeSet updates =
+ new HashPrintServiceAttributeSet();
+ Attribute []attrs = currSet.toArray();
+ for (int i=0; i<attrs.length; i++) {
+ Attribute attr = attrs[i];
+ if (!lastSet.containsValue(attr)) {
+ updates.add(attr);
+ }
+ }
+ lastSet = currSet;
+ return AttributeSetUtilities.unmodifiableView(updates);
+ }
+ }
+
+ public void wakeNotifier() {
+ synchronized (this) {
+ if (notifier != null) {
+ notifier.wake();
+ }
+ }
+ }
+
+ public void addPrintServiceAttributeListener(PrintServiceAttributeListener
+ listener) {
+ synchronized (this) {
+ if (listener == null) {
+ return;
+ }
+ if (notifier == null) {
+ notifier = new ServiceNotifier(this);
+ }
+ notifier.addListener(listener);
+ }
+ }
+
+ public void removePrintServiceAttributeListener(
+ PrintServiceAttributeListener listener) {
+ synchronized (this) {
+ if (listener == null || notifier == null ) {
+ return;
+ }
+ notifier.removeListener(listener);
+ if (notifier.isEmpty()) {
+ notifier.stopNotifier();
+ notifier = null;
+ }
+ }
+ }
+
+ public <T extends PrintServiceAttribute> T
+ getAttribute(Class<T> 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<supportedDocFlavors.length; f++) {
+ if (flavor.equals(supportedDocFlavors[f])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Class<?>[] 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<? extends Attribute> 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<? extends Attribute> 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<mediaSizes.length) {
+ return mediaSizes[index].getMediaSizeName();
+ }
+ }
+
+ return mediaSizeNames[0];
+ }
+ }
+ } else if (category == MediaPrintableArea.class) {
+ /* Verify defPaper */
+ MediaSizeName msn = findWin32Media(defPaper);
+ if (msn != null &&
+ !isSupportedMedia(msn) && mediaSizeNames != null) {
+ defPaper = findPaperID(mediaSizeNames[0]);
+ }
+ float[] prnArea = getMediaPrintableArea(printer, defPaper);
+ if (prnArea != null) {
+ MediaPrintableArea printableArea = null;
+ try {
+ printableArea = new MediaPrintableArea(prnArea[0],
+ prnArea[1],
+ prnArea[2],
+ prnArea[3],
+ MediaPrintableArea.INCH);
+ } catch (IllegalArgumentException e) {
+ }
+ return printableArea;
+ }
+ return null;
+ } else if (category == SunAlternateMedia.class) {
+ 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 == Sides.class) {
+ switch(defSides) {
+ case DMDUP_VERTICAL :
+ return Sides.TWO_SIDED_LONG_EDGE;
+ case DMDUP_HORIZONTAL :
+ return Sides.TWO_SIDED_SHORT_EDGE;
+ default :
+ return Sides.ONE_SIDED;
+ }
+ } else if (category == PrinterResolution.class) {
+ int yRes = defYRes;
+ int xRes = defQuality;
+ if ((xRes < 0) || (yRes < 0)) {
+ int res = (yRes > 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<? extends Attribute> 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<attrs.length; i++) {
+ try {
+ attr = attrs[i];
+ if (!isAttributeCategorySupported(attr.getCategory())) {
+ unsupp.add(attr);
+ }
+ else if (!isAttributeValueSupported(attr, flavor, attributes)) {
+ unsupp.add(attr);
+ }
+ } catch (ClassCastException e) {
+ }
+ }
+ if (unsupp.isEmpty()) {
+ return null;
+ } else {
+ return unsupp;
+ }
+ }
+
+ public ServiceUIFactory getServiceUIFactory() {
+ return null;
+ }
+
+ public String toString() {
+ return "Win32 Printer : " + getName();
+ }
+
+ public boolean equals(Object obj) {
+ return (obj == this ||
+ (obj instanceof Win32PrintService &&
+ ((Win32PrintService)obj).getName().equals(getName())));
+ }
+
+ public int hashCode() {
+ return this.getClass().hashCode()+getName().hashCode();
+ }
+
+ public boolean usesClass(Class c) {
+ return (c == sun.awt.windows.WPrinterJob.class);
+ }
+
+ private native int[] getAllMediaIDs(String printerName, String port);
+ private native int[] getAllMediaSizes(String printerName, String port);
+ private native int[] getAllMediaTrays(String printerName, String port);
+ private native float[] getMediaPrintableArea(String printerName,
+ int paperSize);
+ private native String[] getAllMediaNames(String printerName, String port);
+ private native String[] getAllMediaTrayNames(String printerName, String port);
+ private native int getCopiesSupported(String printerName, String port);
+ private native int[] getAllResolutions(String printerName, String port);
+ private native int getCapabilities(String printerName, String port);
+
+ private native int[] getDefaultSettings(String printerName, String port);
+ private native int getJobStatus(String printerName, int type);
+ private native String getPrinterPort(String printerName);
+}
+
+
+class Win32MediaSize extends MediaSizeName {
+ private static ArrayList winStringTable = new ArrayList();
+ private static ArrayList winEnumTable = new ArrayList();
+
+ private int dmPaperID; // driver ID for this paper.
+
+ private Win32MediaSize(int x) {
+ super(x);
+
+ }
+
+ private synchronized static int nextValue(String name) {
+ winStringTable.add(name);
+ return (winStringTable.size()-1);
+ }
+
+ public Win32MediaSize(String name, int dmPaper) {
+ super(nextValue(name));
+ dmPaperID = dmPaper;
+ winEnumTable.add(this);
+ }
+
+ private MediaSizeName[] getSuperEnumTable() {
+ return (MediaSizeName[])super.getEnumValueTable();
+ }
+
+ static {
+ /* initialize Win32PrintService.predefMedia */
+ {
+ Win32MediaSize winMedia = new Win32MediaSize(-1);
+
+ // cannot call getSuperEnumTable directly because of static context
+ MediaSizeName[] enumMedia = winMedia.getSuperEnumTable();
+ if (enumMedia != null) {
+ Win32PrintService.predefMedia = new MediaSize[enumMedia.length];
+
+ for (int i=0; i<enumMedia.length; i++) {
+ Win32PrintService.predefMedia[i] =
+ MediaSize.getMediaSizeForName(enumMedia[i]);
+ }
+ }
+ }
+ }
+
+ int getDMPaper() {
+ return dmPaperID;
+ }
+
+ protected String[] getStringTable() {
+ String[] nameTable = new String[winStringTable.size()];
+ return (String[])winStringTable.toArray(nameTable);
+ }
+
+ protected EnumSyntax[] getEnumValueTable() {
+ MediaSizeName[] enumTable = new MediaSizeName[winEnumTable.size()];
+ return (MediaSizeName[])winEnumTable.toArray(enumTable);
+ }
+
+}