Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/print/Win32PrintService.java
32287 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.print;2627import java.awt.Window;28import java.awt.print.PrinterJob;29import java.io.File;30import java.net.URI;31import java.net.URISyntaxException;32import java.util.ArrayList;33import java.util.HashMap;34import javax.print.DocFlavor;35import javax.print.DocPrintJob;36import javax.print.PrintService;37import javax.print.ServiceUIFactory;38import javax.print.attribute.Attribute;39import javax.print.attribute.AttributeSet;40import javax.print.attribute.AttributeSetUtilities;41import javax.print.attribute.EnumSyntax;42import javax.print.attribute.HashAttributeSet;43import javax.print.attribute.PrintRequestAttributeSet;44import javax.print.attribute.PrintServiceAttribute;45import javax.print.attribute.PrintServiceAttributeSet;46import javax.print.attribute.HashPrintServiceAttributeSet;47import javax.print.attribute.standard.PrinterName;48import javax.print.attribute.standard.PrinterIsAcceptingJobs;49import javax.print.attribute.standard.QueuedJobCount;50import javax.print.attribute.standard.JobName;51import javax.print.attribute.standard.RequestingUserName;52import javax.print.attribute.standard.Chromaticity;53import javax.print.attribute.standard.Copies;54import javax.print.attribute.standard.CopiesSupported;55import javax.print.attribute.standard.Destination;56import javax.print.attribute.standard.Fidelity;57import javax.print.attribute.standard.Media;58import javax.print.attribute.standard.MediaSizeName;59import javax.print.attribute.standard.MediaSize;60import javax.print.attribute.standard.MediaTray;61import javax.print.attribute.standard.MediaPrintableArea;62import javax.print.attribute.standard.OrientationRequested;63import javax.print.attribute.standard.PageRanges;64import javax.print.attribute.standard.PrinterState;65import javax.print.attribute.standard.PrinterStateReason;66import javax.print.attribute.standard.PrinterStateReasons;67import javax.print.attribute.standard.Severity;68import javax.print.attribute.standard.Sides;69import javax.print.attribute.standard.ColorSupported;70import javax.print.attribute.standard.PrintQuality;71import javax.print.attribute.standard.PrinterResolution;72import javax.print.attribute.standard.SheetCollate;73import javax.print.event.PrintServiceAttributeListener;74import sun.awt.windows.WPrinterJob;7576public class Win32PrintService implements PrintService, AttributeUpdater,77SunPrinterJobService {7879public static MediaSize[] predefMedia = Win32MediaSize.getPredefMedia();8081private static final DocFlavor[] supportedFlavors = {82DocFlavor.BYTE_ARRAY.GIF,83DocFlavor.INPUT_STREAM.GIF,84DocFlavor.URL.GIF,85DocFlavor.BYTE_ARRAY.JPEG,86DocFlavor.INPUT_STREAM.JPEG,87DocFlavor.URL.JPEG,88DocFlavor.BYTE_ARRAY.PNG,89DocFlavor.INPUT_STREAM.PNG,90DocFlavor.URL.PNG,91DocFlavor.SERVICE_FORMATTED.PAGEABLE,92DocFlavor.SERVICE_FORMATTED.PRINTABLE,93DocFlavor.BYTE_ARRAY.AUTOSENSE,94DocFlavor.URL.AUTOSENSE,95DocFlavor.INPUT_STREAM.AUTOSENSE96};9798/* let's try to support a few of these */99private static final Class[] serviceAttrCats = {100PrinterName.class,101PrinterIsAcceptingJobs.class,102QueuedJobCount.class,103ColorSupported.class,104};105106/* it turns out to be inconvenient to store the other categories107* separately because many attributes are in multiple categories.108*/109private static Class[] otherAttrCats = {110JobName.class,111RequestingUserName.class,112Copies.class,113Destination.class,114OrientationRequested.class,115PageRanges.class,116Media.class,117MediaPrintableArea.class,118Fidelity.class,119// We support collation on 2D printer jobs, even if the driver can't.120SheetCollate.class,121SunAlternateMedia.class,122Chromaticity.class123};124125126/*127* This table together with methods findWin32Media and128* findMatchingMediaSizeNameMM are declared public as these are also129* used in WPrinterJob.java.130*/131public static final MediaSizeName[] dmPaperToPrintService = {132MediaSizeName.NA_LETTER, MediaSizeName.NA_LETTER,133MediaSizeName.TABLOID, MediaSizeName.LEDGER,134MediaSizeName.NA_LEGAL, MediaSizeName.INVOICE,135MediaSizeName.EXECUTIVE, MediaSizeName.ISO_A3,136MediaSizeName.ISO_A4, MediaSizeName.ISO_A4,137MediaSizeName.ISO_A5, MediaSizeName.JIS_B4,138MediaSizeName.JIS_B5, MediaSizeName.FOLIO,139MediaSizeName.QUARTO, MediaSizeName.NA_10X14_ENVELOPE,140MediaSizeName.B, MediaSizeName.NA_LETTER,141MediaSizeName.NA_NUMBER_9_ENVELOPE, MediaSizeName.NA_NUMBER_10_ENVELOPE,142MediaSizeName.NA_NUMBER_11_ENVELOPE, MediaSizeName.NA_NUMBER_12_ENVELOPE,143MediaSizeName.NA_NUMBER_14_ENVELOPE, MediaSizeName.C,144MediaSizeName.D, MediaSizeName.E,145MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.ISO_C5,146MediaSizeName.ISO_C3, MediaSizeName.ISO_C4,147MediaSizeName.ISO_C6, MediaSizeName.ITALY_ENVELOPE,148MediaSizeName.ISO_B4, MediaSizeName.ISO_B5,149MediaSizeName.ISO_B6, MediaSizeName.ITALY_ENVELOPE,150MediaSizeName.MONARCH_ENVELOPE, MediaSizeName.PERSONAL_ENVELOPE,151MediaSizeName.NA_10X15_ENVELOPE, MediaSizeName.NA_9X12_ENVELOPE,152MediaSizeName.FOLIO, MediaSizeName.ISO_B4,153MediaSizeName.JAPANESE_POSTCARD, MediaSizeName.NA_9X11_ENVELOPE,154};155156private static final MediaTray[] dmPaperBinToPrintService = {157MediaTray.TOP, MediaTray.BOTTOM, MediaTray.MIDDLE,158MediaTray.MANUAL, MediaTray.ENVELOPE, Win32MediaTray.ENVELOPE_MANUAL,159Win32MediaTray.AUTO, Win32MediaTray.TRACTOR,160Win32MediaTray.SMALL_FORMAT, Win32MediaTray.LARGE_FORMAT,161MediaTray.LARGE_CAPACITY, null, null,162MediaTray.MAIN, Win32MediaTray.FORMSOURCE,163};164165// from wingdi.h166private static int DM_PAPERSIZE = 0x2;167private static int DM_PRINTQUALITY = 0x400;168private static int DM_YRESOLUTION = 0x2000;169private static final int DMRES_MEDIUM = -3;170private static final int DMRES_HIGH = -4;171private static final int DMORIENT_LANDSCAPE = 2;172private static final int DMDUP_VERTICAL = 2;173private static final int DMDUP_HORIZONTAL = 3;174private static final int DMCOLLATE_TRUE = 1;175private static final int DMCOLOR_MONOCHROME = 1;176private static final int DMCOLOR_COLOR = 2;177178179// media sizes with indices above dmPaperToPrintService' length180private static final int DMPAPER_A2 = 66;181private static final int DMPAPER_A6 = 70;182private static final int DMPAPER_B6_JIS = 88;183184185// Bit settings for getPrinterCapabilities which matches that186// of native getCapabilities in WPrinterJob.cpp187private static final int DEVCAP_COLOR = 0x0001;188private static final int DEVCAP_DUPLEX = 0x0002;189private static final int DEVCAP_COLLATE = 0x0004;190private static final int DEVCAP_QUALITY = 0x0008;191private static final int DEVCAP_POSTSCRIPT = 0x0010;192193private String printer;194private PrinterName name;195private String port;196197transient private PrintServiceAttributeSet lastSet;198transient private ServiceNotifier notifier = null;199200private MediaSizeName[] mediaSizeNames;201private MediaPrintableArea[] mediaPrintables;202private MediaTray[] mediaTrays;203private PrinterResolution[] printRes;204private HashMap mpaMap;205private int nCopies;206private int prnCaps;207private int[] defaultSettings;208209private boolean gotTrays;210private boolean gotCopies;211private boolean mediaInitialized;212private boolean mpaListInitialized;213214private ArrayList idList;215private MediaSize[] mediaSizes;216217private boolean isInvalid;218219Win32PrintService(String name) {220if (name == null) {221throw new IllegalArgumentException("null printer name");222}223printer = name;224225// initialize flags226mediaInitialized = false;227gotTrays = false;228gotCopies = false;229isInvalid = false;230printRes = null;231prnCaps = 0;232defaultSettings = null;233port = null;234}235236public void invalidateService() {237isInvalid = true;238}239240public String getName() {241return printer;242}243244private PrinterName getPrinterName() {245if (name == null) {246name = new PrinterName(printer, null);247}248return name;249}250251public int findPaperID(MediaSizeName msn) {252if (msn instanceof Win32MediaSize) {253Win32MediaSize winMedia = (Win32MediaSize)msn;254return winMedia.getDMPaper();255} else {256for (int id=0; id<dmPaperToPrintService.length;id++) {257if (dmPaperToPrintService[id].equals(msn)) {258return id+1; // DMPAPER_LETTER == 1259}260}261if (msn.equals(MediaSizeName.ISO_A2)) {262return DMPAPER_A2;263}264else if (msn.equals(MediaSizeName.ISO_A6)) {265return DMPAPER_A6;266}267else if (msn.equals(MediaSizeName.JIS_B6)) {268return DMPAPER_B6_JIS;269}270}271272// If not found in predefined Windows ID, then we search through273// the returned IDs of the driver because they can define their own274// unique IDs.275initMedia();276277if ((idList != null) && (mediaSizes != null) &&278(idList.size() == mediaSizes.length)) {279for (int i=0; i< idList.size(); i++) {280if (mediaSizes[i].getMediaSizeName() == msn) {281return ((Integer)idList.get(i)).intValue();282}283}284}285return 0;286}287288public int findTrayID(MediaTray tray) {289290getMediaTrays(); // make sure they are initialised.291292if (tray instanceof Win32MediaTray) {293Win32MediaTray winTray = (Win32MediaTray)tray;294return winTray.getDMBinID();295}296for (int id=0; id<dmPaperBinToPrintService.length; id++) {297if (tray.equals(dmPaperBinToPrintService[id])) {298return id+1; // DMBIN_FIRST = 1;299}300}301return 0; // didn't find the tray302}303304public MediaTray findMediaTray(int dmBin) {305if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {306return dmPaperBinToPrintService[dmBin-1];307}308MediaTray[] trays = getMediaTrays();309if (trays != null) {310for (int i=0;i<trays.length;i++) {311if(trays[i] instanceof Win32MediaTray) {312Win32MediaTray win32Tray = (Win32MediaTray)trays[i];313if (win32Tray.winID == dmBin) {314return win32Tray;315}316}317}318}319return Win32MediaTray.AUTO;320}321322public MediaSizeName findWin32Media(int dmIndex) {323if (dmIndex >= 1 && dmIndex <= dmPaperToPrintService.length) {324return dmPaperToPrintService[dmIndex - 1];325}326switch(dmIndex) {327/* matching media sizes with indices beyond328dmPaperToPrintService's length */329case DMPAPER_A2:330return MediaSizeName.ISO_A2;331case DMPAPER_A6:332return MediaSizeName.ISO_A6;333case DMPAPER_B6_JIS:334return MediaSizeName.JIS_B6;335default:336return null;337}338}339340private boolean addToUniqueList(ArrayList msnList, MediaSizeName mediaName) {341MediaSizeName msn;342for (int i=0; i< msnList.size(); i++) {343msn = (MediaSizeName)msnList.get(i);344if (msn == mediaName) {345return false;346}347}348msnList.add(mediaName);349return true;350}351352private synchronized void initMedia() {353if (mediaInitialized == true) {354return;355}356mediaInitialized = true;357int[] media = getAllMediaIDs(printer, getPort());358if (media == null) {359return;360}361362ArrayList msnList = new ArrayList();363ArrayList<Win32MediaSize> trailingWmsList = new ArrayList<Win32MediaSize>();364ArrayList printableList = new ArrayList();365MediaSizeName mediaName;366boolean added;367boolean queryFailure = false;368float[] prnArea;369370// Get all mediaSizes supported by the printer.371// We convert media to ArrayList idList and pass this to the372// function for getting mediaSizes.373// This is to ensure that mediaSizes and media IDs have 1-1 correspondence.374// We remove from ID list any invalid mediaSize. Though this is rare,375// it happens in HP 4050 German driver.376377idList = new ArrayList();378for (int i=0; i < media.length; i++) {379idList.add(Integer.valueOf(media[i]));380}381382ArrayList<String> dmPaperNameList = new ArrayList<String>();383mediaSizes = getMediaSizes(idList, media, dmPaperNameList);384for (int i = 0; i < idList.size(); i++) {385386// match Win ID with our predefined ID using table387mediaName = findWin32Media(((Integer)idList.get(i)).intValue());388// Verify that this standard size is the same size as that389// reported by the driver. This should be the case except when390// the driver is mis-using a standard windows paper ID.391if (mediaName != null &&392idList.size() == mediaSizes.length) {393MediaSize win32Size = MediaSize.getMediaSizeForName(mediaName);394MediaSize driverSize = mediaSizes[i];395int error = 2540; // == 1/10"396if (Math.abs(win32Size.getX(1)-driverSize.getX(1)) > error ||397Math.abs(win32Size.getY(1)-driverSize.getY(1)) > error)398{399mediaName = null;400}401}402boolean dmPaperIDMatched = (mediaName != null);403404// No match found, then we get the MediaSizeName out of the MediaSize405// This requires 1-1 correspondence, lengths must be checked.406if ((mediaName == null) && (idList.size() == mediaSizes.length)) {407mediaName = mediaSizes[i].getMediaSizeName();408}409410// Add mediaName to the msnList411added = false;412if (mediaName != null) {413added = addToUniqueList(msnList, mediaName);414}415if ((!dmPaperIDMatched || !added) && (idList.size() == dmPaperNameList.size())) {416/* The following block allows to add such media names to the list, whose sizes417* matched with media sizes predefined in JDK, while whose paper IDs did not,418* or whose sizes and paper IDs both did not match with any predefined in JDK.419*/420Win32MediaSize wms = Win32MediaSize.findMediaName(dmPaperNameList.get(i));421if ((wms == null) && (idList.size() == mediaSizes.length)) {422wms = new Win32MediaSize(dmPaperNameList.get(i), (Integer)idList.get(i));423mediaSizes[i] = new MediaSize(mediaSizes[i].getX(MediaSize.MM),424mediaSizes[i].getY(MediaSize.MM), MediaSize.MM, wms);425}426if ((wms != null) && (wms != mediaName)) {427if (!added) {428added = addToUniqueList(msnList, mediaName = wms);429} else {430trailingWmsList.add(wms);431}432}433}434}435for (Win32MediaSize wms : trailingWmsList) {436added = addToUniqueList(msnList, wms);437}438439// init mediaSizeNames440mediaSizeNames = new MediaSizeName[msnList.size()];441msnList.toArray(mediaSizeNames);442}443444445/*446* Gets a list of MediaPrintableAreas using a call to native function.447* msn is MediaSizeName used to get a specific printable area. If null,448* it will get all the supported MediPrintableAreas.449*/450private synchronized MediaPrintableArea[] getMediaPrintables(MediaSizeName msn)451{452if (msn == null) {453if (mpaListInitialized == true) {454return mediaPrintables;455}456} else {457// get from cached mapping of MPAs458if (mpaMap != null && (mpaMap.get(msn) != null)) {459MediaPrintableArea[] mpaArr = new MediaPrintableArea[1];460mpaArr[0] = (MediaPrintableArea)mpaMap.get(msn);461return mpaArr;462}463}464465initMedia();466467if ((mediaSizeNames == null) || (mediaSizeNames.length == 0)) {468return null;469}470471MediaSizeName[] loopNames;472if (msn != null) {473loopNames = new MediaSizeName[1];474loopNames[0] = msn;475} else {476loopNames = mediaSizeNames;477}478479if (mpaMap == null) {480mpaMap = new HashMap();481}482483for (int i=0; i < loopNames.length; i++) {484MediaSizeName mediaName = loopNames[i];485486if (mpaMap.get(mediaName) != null) {487continue;488}489490if (mediaName != null) {491int defPaper = findPaperID(mediaName);492float[] prnArea = (defPaper != 0) ? getMediaPrintableArea(printer, defPaper) : null;493MediaPrintableArea printableArea = null;494if (prnArea != null) {495try {496printableArea = new MediaPrintableArea(prnArea[0],497prnArea[1],498prnArea[2],499prnArea[3],500MediaPrintableArea.INCH);501502mpaMap.put(mediaName, printableArea);503}504catch (IllegalArgumentException e) {505}506} else {507// if getting MPA failed, we use MediaSize508MediaSize ms =509MediaSize.getMediaSizeForName((MediaSizeName)mediaName);510511if (ms != null) {512try {513printableArea = new MediaPrintableArea(0, 0,514ms.getX(MediaSize.INCH),515ms.getY(MediaSize.INCH),516MediaPrintableArea.INCH);517mpaMap.put(mediaName, printableArea);518} catch (IllegalArgumentException e) {519}520}521}522} //mediaName != null523}524525if (mpaMap.size() == 0) {526return null;527}528529if (msn != null) {530if (mpaMap.get(msn) == null) {531return null;532}533MediaPrintableArea[] mpaArr = new MediaPrintableArea[1];534// by this time, we've already gotten the desired MPA535mpaArr[0] = (MediaPrintableArea)mpaMap.get(msn);536return mpaArr;537} else {538mediaPrintables = (MediaPrintableArea[])mpaMap.values().toArray(new MediaPrintableArea[0]);539mpaListInitialized = true;540return mediaPrintables;541}542}543544545private synchronized MediaTray[] getMediaTrays() {546if (gotTrays == true && mediaTrays != null) {547return mediaTrays;548}549String prnPort = getPort();550int[] mediaTr = getAllMediaTrays(printer, prnPort);551String[] winMediaTrayNames = getAllMediaTrayNames(printer, prnPort);552553if ((mediaTr == null) || (winMediaTrayNames == null)){554return null;555}556557/* first count how many valid bins there are so we can allocate558* an array of the correct size559*/560int nTray = 0;561for (int i=0; i < mediaTr.length ; i++) {562if (mediaTr[i] > 0) nTray++;563}564565MediaTray[] arr = new MediaTray[nTray];566int dmBin;567568/* Some drivers in Win 7 don't have the same length for DC_BINS and569* DC_BINNAMES so there is no guarantee that lengths of mediaTr and570* winMediaTrayNames are equal. To avoid getting ArrayIndexOutOfBounds,571* we need to make sure we get the minimum of the two.572*/573574for (int i = 0, j=0; i < Math.min(mediaTr.length, winMediaTrayNames.length); i++) {575dmBin = mediaTr[i];576if (dmBin > 0) {577// check for unsupported DMBINs and create new Win32MediaTray578if ((dmBin > dmPaperBinToPrintService.length)579|| (dmPaperBinToPrintService[dmBin-1] == null)) {580arr[j++] = new Win32MediaTray(dmBin, winMediaTrayNames[i]);581} else {582arr[j++] = dmPaperBinToPrintService[dmBin-1];583}584}585// no else - For invalid ids, just ignore it because assigning a "default"586// value may result in duplicate trays.587}588mediaTrays = arr;589gotTrays = true;590return mediaTrays;591}592593private boolean isSameSize(float w1, float h1, float w2, float h2) {594float diffX = w1 - w2;595float diffY = h1 - h2;596// Get diff of reverse dimensions597// EPSON Stylus COLOR 860 reverses envelope's width & height598float diffXrev = w1 - h2;599float diffYrev = h1 - w2;600601if (((Math.abs(diffX)<=1) && (Math.abs(diffY)<=1)) ||602((Math.abs(diffXrev)<=1) && (Math.abs(diffYrev)<=1))){603return true;604} else {605return false;606}607}608609public MediaSizeName findMatchingMediaSizeNameMM (float w, float h){610if (predefMedia != null) {611for (int k=0; k<predefMedia.length;k++) {612if (predefMedia[k] == null) {613continue;614}615616if (isSameSize(predefMedia[k].getX(MediaSize.MM),617predefMedia[k].getY(MediaSize.MM),618w, h)) {619return predefMedia[k].getMediaSizeName();620}621}622}623return null;624}625626627private MediaSize[] getMediaSizes(ArrayList idList, int[] media, ArrayList<String> dmPaperNameList) {628if (dmPaperNameList == null) {629dmPaperNameList = new ArrayList<String>();630}631632String prnPort = getPort();633int[] mediaSz = getAllMediaSizes(printer, prnPort);634String[] winMediaNames = getAllMediaNames(printer, prnPort);635MediaSizeName msn = null;636MediaSize ms = null;637float wid, ht;638639if ((mediaSz == null) || (winMediaNames == null)) {640return null;641}642643int nMedia = mediaSz.length/2;644ArrayList msList = new ArrayList();645646for (int i = 0; i < nMedia; i++, ms=null) {647wid = mediaSz[i*2]/10f;648ht = mediaSz[i*2+1]/10f;649650// Make sure to validate wid & ht.651// HP LJ 4050 (german) causes IAE in Sonderformat paper, wid & ht652// returned is not constant.653if ((wid <= 0) || (ht <= 0)) {654//Remove corresponding ID from list655if (nMedia == media.length) {656Integer remObj = Integer.valueOf(media[i]);657idList.remove(idList.indexOf(remObj));658}659continue;660}661// Find matching media using dimensions.662// This call matches only with our own predefined sizes.663msn = findMatchingMediaSizeNameMM(wid, ht);664if (msn != null) {665ms = MediaSize.getMediaSizeForName(msn);666}667668if (ms != null) {669msList.add(ms);670dmPaperNameList.add(winMediaNames[i]);671} else {672Win32MediaSize wms = Win32MediaSize.findMediaName(winMediaNames[i]);673if (wms == null) {674wms = new Win32MediaSize(winMediaNames[i], media[i]);675}676try {677ms = new MediaSize(wid, ht, MediaSize.MM, wms);678msList.add(ms);679dmPaperNameList.add(winMediaNames[i]);680} catch(IllegalArgumentException e) {681if (nMedia == media.length) {682Integer remObj = Integer.valueOf(media[i]);683idList.remove(idList.indexOf(remObj));684}685}686}687}688689MediaSize[] arr2 = new MediaSize[msList.size()];690msList.toArray(arr2);691692return arr2;693}694695private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {696if (getJobStatus(printer, 2) != 1) {697return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;698}699else {700return PrinterIsAcceptingJobs.ACCEPTING_JOBS;701}702}703704private PrinterState getPrinterState() {705if (isInvalid) {706return PrinterState.STOPPED;707} else {708return null;709}710}711712private PrinterStateReasons getPrinterStateReasons() {713if (isInvalid) {714PrinterStateReasons psr = new PrinterStateReasons();715psr.put(PrinterStateReason.SHUTDOWN, Severity.ERROR);716return psr;717} else {718return null;719}720}721722private QueuedJobCount getQueuedJobCount() {723724int count = getJobStatus(printer, 1);725if (count != -1) {726return new QueuedJobCount(count);727}728else {729return new QueuedJobCount(0);730}731}732733private boolean isSupportedCopies(Copies copies) {734synchronized (this) {735if (gotCopies == false) {736nCopies = getCopiesSupported(printer, getPort());737gotCopies = true;738}739}740int numCopies = copies.getValue();741return (numCopies > 0 && numCopies <= nCopies);742}743744private boolean isSupportedMedia(MediaSizeName msn) {745746initMedia();747748if (mediaSizeNames != null) {749for (int i=0; i<mediaSizeNames.length; i++) {750if (msn.equals(mediaSizeNames[i])) {751return true;752}753}754}755return false;756}757758private boolean isSupportedMediaPrintableArea(MediaPrintableArea mpa) {759760getMediaPrintables(null);761762if (mediaPrintables != null) {763for (int i=0; i<mediaPrintables.length; i++) {764if (mpa.equals(mediaPrintables[i])) {765return true;766}767}768}769return false;770}771772private boolean isSupportedMediaTray(MediaTray msn) {773MediaTray[] trays = getMediaTrays();774775if (trays != null) {776for (int i=0; i<trays.length; i++) {777if (msn.equals(trays[i])) {778return true;779}780}781}782return false;783}784785private int getPrinterCapabilities() {786if (prnCaps == 0) {787prnCaps = getCapabilities(printer, getPort());788}789return prnCaps;790}791792private String getPort() {793if (port == null) {794port = getPrinterPort(printer);795}796return port;797}798799/*800* NOTE: defaults indices must match those in WPrinterJob.cpp801*/802private int[] getDefaultPrinterSettings() {803if (defaultSettings == null) {804defaultSettings = getDefaultSettings(printer, getPort());805}806return defaultSettings;807}808809private PrinterResolution[] getPrintResolutions() {810if (printRes == null) {811int[] prnRes = getAllResolutions(printer, getPort());812if (prnRes == null) {813printRes = new PrinterResolution[0];814} else {815int nRes = prnRes.length/2;816817ArrayList arrList = new ArrayList();818PrinterResolution pr;819820for (int i=0; i<nRes; i++) {821try {822pr = new PrinterResolution(prnRes[i*2],823prnRes[i*2+1], PrinterResolution.DPI);824arrList.add(pr);825} catch (IllegalArgumentException e) {826}827}828829printRes = (PrinterResolution[])arrList.toArray(830new PrinterResolution[arrList.size()]);831}832}833return printRes;834}835836private boolean isSupportedResolution(PrinterResolution res) {837PrinterResolution[] supportedRes = getPrintResolutions();838if (supportedRes != null) {839for (int i=0; i<supportedRes.length; i++) {840if (res.equals(supportedRes[i])) {841return true;842}843}844}845return false;846}847848public DocPrintJob createPrintJob() {849SecurityManager security = System.getSecurityManager();850if (security != null) {851security.checkPrintJobAccess();852}853return new Win32PrintJob(this);854}855856private PrintServiceAttributeSet getDynamicAttributes() {857PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();858attrs.add(getPrinterIsAcceptingJobs());859attrs.add(getQueuedJobCount());860return attrs;861}862863public PrintServiceAttributeSet getUpdatedAttributes() {864PrintServiceAttributeSet currSet = getDynamicAttributes();865if (lastSet == null) {866lastSet = currSet;867return AttributeSetUtilities.unmodifiableView(currSet);868} else {869PrintServiceAttributeSet updates =870new HashPrintServiceAttributeSet();871Attribute []attrs = currSet.toArray();872for (int i=0; i<attrs.length; i++) {873Attribute attr = attrs[i];874if (!lastSet.containsValue(attr)) {875updates.add(attr);876}877}878lastSet = currSet;879return AttributeSetUtilities.unmodifiableView(updates);880}881}882883public void wakeNotifier() {884synchronized (this) {885if (notifier != null) {886notifier.wake();887}888}889}890891public void addPrintServiceAttributeListener(PrintServiceAttributeListener892listener) {893synchronized (this) {894if (listener == null) {895return;896}897if (notifier == null) {898notifier = new ServiceNotifier(this);899}900notifier.addListener(listener);901}902}903904public void removePrintServiceAttributeListener(905PrintServiceAttributeListener listener) {906synchronized (this) {907if (listener == null || notifier == null ) {908return;909}910notifier.removeListener(listener);911if (notifier.isEmpty()) {912notifier.stopNotifier();913notifier = null;914}915}916}917918public <T extends PrintServiceAttribute> T919getAttribute(Class<T> category)920{921if (category == null) {922throw new NullPointerException("category");923}924if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {925throw new IllegalArgumentException("Not a PrintServiceAttribute");926}927if (category == ColorSupported.class) {928int caps = getPrinterCapabilities();929if ((caps & DEVCAP_COLOR) != 0) {930return (T)ColorSupported.SUPPORTED;931} else {932return (T)ColorSupported.NOT_SUPPORTED;933}934} else if (category == PrinterName.class) {935return (T)getPrinterName();936} else if (category == PrinterState.class) {937return (T)getPrinterState();938} else if (category == PrinterStateReasons.class) {939return (T)getPrinterStateReasons();940} else if (category == QueuedJobCount.class) {941return (T)getQueuedJobCount();942} else if (category == PrinterIsAcceptingJobs.class) {943return (T)getPrinterIsAcceptingJobs();944} else {945return null;946}947}948949public PrintServiceAttributeSet getAttributes() {950951PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();952attrs.add(getPrinterName());953attrs.add(getPrinterIsAcceptingJobs());954PrinterState prnState = getPrinterState();955if (prnState != null) {956attrs.add(prnState);957}958PrinterStateReasons prnStateReasons = getPrinterStateReasons();959if (prnStateReasons != null) {960attrs.add(prnStateReasons);961}962attrs.add(getQueuedJobCount());963int caps = getPrinterCapabilities();964if ((caps & DEVCAP_COLOR) != 0) {965attrs.add(ColorSupported.SUPPORTED);966} else {967attrs.add(ColorSupported.NOT_SUPPORTED);968}969970return AttributeSetUtilities.unmodifiableView(attrs);971}972973public DocFlavor[] getSupportedDocFlavors() {974int len = supportedFlavors.length;975DocFlavor[] supportedDocFlavors;976int caps = getPrinterCapabilities();977// doc flavors supported978// if PostScript is supported979if ((caps & DEVCAP_POSTSCRIPT) != 0) {980supportedDocFlavors = new DocFlavor[len+3];981System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);982supportedDocFlavors[len] = DocFlavor.BYTE_ARRAY.POSTSCRIPT;983supportedDocFlavors[len+1] = DocFlavor.INPUT_STREAM.POSTSCRIPT;984supportedDocFlavors[len+2] = DocFlavor.URL.POSTSCRIPT;985} else {986supportedDocFlavors = new DocFlavor[len];987System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);988}989return supportedDocFlavors;990}991992public boolean isDocFlavorSupported(DocFlavor flavor) {993/* To avoid a native query which may be time-consuming994* do not invoke native unless postscript support is being queried.995* Instead just check the ones we 'always' support996*/997DocFlavor[] supportedDocFlavors;998if (isPostScriptFlavor(flavor)) {999supportedDocFlavors = getSupportedDocFlavors();1000} else {1001supportedDocFlavors = supportedFlavors;1002}1003for (int f=0; f<supportedDocFlavors.length; f++) {1004if (flavor.equals(supportedDocFlavors[f])) {1005return true;1006}1007}1008return false;1009}10101011public Class<?>[] getSupportedAttributeCategories() {1012ArrayList categList = new ArrayList(otherAttrCats.length+3);1013for (int i=0; i < otherAttrCats.length; i++) {1014categList.add(otherAttrCats[i]);1015}10161017int caps = getPrinterCapabilities();10181019if ((caps & DEVCAP_DUPLEX) != 0) {1020categList.add(Sides.class);1021}10221023if ((caps & DEVCAP_QUALITY) != 0) {1024int[] defaults = getDefaultPrinterSettings();1025// Added check: if supported, we should be able to get the default.1026if ((defaults[3] >= DMRES_HIGH) && (defaults[3] < 0)) {1027categList.add(PrintQuality.class);1028}1029}10301031PrinterResolution[] supportedRes = getPrintResolutions();1032if ((supportedRes!=null) && (supportedRes.length>0)) {1033categList.add(PrinterResolution.class);1034}10351036return (Class[])categList.toArray(new Class[categList.size()]);1037}10381039public boolean1040isAttributeCategorySupported(Class<? extends Attribute> category)1041{10421043if (category == null) {1044throw new NullPointerException("null category");1045}10461047if (!(Attribute.class.isAssignableFrom(category))) {1048throw new IllegalArgumentException(category +1049" is not an Attribute");1050}10511052Class[] classList = getSupportedAttributeCategories();1053for (int i = 0; i < classList.length; i++) {1054if (category.equals(classList[i])) {1055return true;1056}1057}10581059return false;1060}10611062public Object1063getDefaultAttributeValue(Class<? extends Attribute> category)1064{1065if (category == null) {1066throw new NullPointerException("null category");1067}1068if (!Attribute.class.isAssignableFrom(category)) {1069throw new IllegalArgumentException(category +1070" is not an Attribute");1071}10721073if (!isAttributeCategorySupported(category)) {1074return null;1075}10761077int[] defaults = getDefaultPrinterSettings();1078// indices must match those in WPrinterJob.cpp1079int defPaper = defaults[0];1080int defYRes = defaults[2];1081int defQuality = defaults[3];1082int defCopies = defaults[4];1083int defOrient = defaults[5];1084int defSides = defaults[6];1085int defCollate = defaults[7];1086int defColor = defaults[8];10871088if (category == Copies.class) {1089if (defCopies > 0) {1090return new Copies(defCopies);1091} else {1092return new Copies(1);1093}1094} else if (category == Chromaticity.class) {1095if (defColor == DMCOLOR_COLOR) {1096return Chromaticity.COLOR;1097} else {1098return Chromaticity.MONOCHROME;1099}1100} else if (category == JobName.class) {1101return new JobName("Java Printing", null);1102} else if (category == OrientationRequested.class) {1103if (defOrient == DMORIENT_LANDSCAPE) {1104return OrientationRequested.LANDSCAPE;1105} else {1106return OrientationRequested.PORTRAIT;1107}1108} else if (category == PageRanges.class) {1109return new PageRanges(1, Integer.MAX_VALUE);1110} else if (category == Media.class) {1111MediaSizeName msn = findWin32Media(defPaper);1112if (msn != null) {1113if (!isSupportedMedia(msn) && mediaSizeNames != null) {1114msn = mediaSizeNames[0];1115defPaper = findPaperID(msn);1116}1117return msn;1118} else {1119initMedia();1120if ((mediaSizeNames != null) && (mediaSizeNames.length > 0)) {1121// if 'mediaSizeNames' is not null, idList and mediaSizes1122// cannot be null but to be safe, add a check1123if ((idList != null) && (mediaSizes != null) &&1124(idList.size() == mediaSizes.length)) {1125Integer defIdObj = Integer.valueOf(defPaper);1126int index = idList.indexOf(defIdObj);1127if (index>=0 && index<mediaSizes.length) {1128return mediaSizes[index].getMediaSizeName();1129}1130}11311132return mediaSizeNames[0];1133}1134}1135} else if (category == MediaPrintableArea.class) {1136/* Verify defPaper */1137MediaSizeName msn = findWin32Media(defPaper);1138if (msn != null &&1139!isSupportedMedia(msn) && mediaSizeNames != null) {1140defPaper = findPaperID(mediaSizeNames[0]);1141}1142float[] prnArea = getMediaPrintableArea(printer, defPaper);1143if (prnArea != null) {1144MediaPrintableArea printableArea = null;1145try {1146printableArea = new MediaPrintableArea(prnArea[0],1147prnArea[1],1148prnArea[2],1149prnArea[3],1150MediaPrintableArea.INCH);1151} catch (IllegalArgumentException e) {1152}1153return printableArea;1154}1155return null;1156} else if (category == SunAlternateMedia.class) {1157return null;1158} else if (category == Destination.class) {1159try {1160return new Destination((new File("out.prn")).toURI());1161} catch (SecurityException se) {1162try {1163return new Destination(new URI("file:out.prn"));1164} catch (URISyntaxException e) {1165return null;1166}1167}1168} else if (category == Sides.class) {1169switch(defSides) {1170case DMDUP_VERTICAL :1171return Sides.TWO_SIDED_LONG_EDGE;1172case DMDUP_HORIZONTAL :1173return Sides.TWO_SIDED_SHORT_EDGE;1174default :1175return Sides.ONE_SIDED;1176}1177} else if (category == PrinterResolution.class) {1178int yRes = defYRes;1179int xRes = defQuality;1180if ((xRes < 0) || (yRes < 0)) {1181int res = (yRes > xRes) ? yRes : xRes;1182if (res > 0) {1183return new PrinterResolution(res, res, PrinterResolution.DPI);1184}1185}1186else {1187return new PrinterResolution(xRes, yRes, PrinterResolution.DPI);1188}1189} else if (category == ColorSupported.class) {1190int caps = getPrinterCapabilities();1191if ((caps & DEVCAP_COLOR) != 0) {1192return ColorSupported.SUPPORTED;1193} else {1194return ColorSupported.NOT_SUPPORTED;1195}1196} else if (category == PrintQuality.class) {1197if ((defQuality < 0) && (defQuality >= DMRES_HIGH)) {1198switch (defQuality) {1199case DMRES_HIGH:1200return PrintQuality.HIGH;1201case DMRES_MEDIUM:1202return PrintQuality.NORMAL;1203default:1204return PrintQuality.DRAFT;1205}1206}1207} else if (category == RequestingUserName.class) {1208String userName = "";1209try {1210userName = System.getProperty("user.name", "");1211} catch (SecurityException se) {1212}1213return new RequestingUserName(userName, null);1214} else if (category == SheetCollate.class) {1215if (defCollate == DMCOLLATE_TRUE) {1216return SheetCollate.COLLATED;1217} else {1218return SheetCollate.UNCOLLATED;1219}1220} else if (category == Fidelity.class) {1221return Fidelity.FIDELITY_FALSE;1222}1223return null;1224}12251226private boolean isPostScriptFlavor(DocFlavor flavor) {1227if (flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT) ||1228flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) ||1229flavor.equals(DocFlavor.URL.POSTSCRIPT)) {1230return true;1231}1232else {1233return false;1234}1235}12361237private boolean isPSDocAttr(Class category) {1238if (category == OrientationRequested.class || category == Copies.class) {1239return true;1240}1241else {1242return false;1243}1244}12451246private boolean isAutoSense(DocFlavor flavor) {1247if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE) ||1248flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE) ||1249flavor.equals(DocFlavor.URL.AUTOSENSE)) {1250return true;1251}1252else {1253return false;1254}1255}12561257public Object1258getSupportedAttributeValues(Class<? extends Attribute> category,1259DocFlavor flavor,1260AttributeSet attributes)1261{1262if (category == null) {1263throw new NullPointerException("null category");1264}1265if (!Attribute.class.isAssignableFrom(category)) {1266throw new IllegalArgumentException(category +1267" does not implement Attribute");1268}1269if (flavor != null) {1270if (!isDocFlavorSupported(flavor)) {1271throw new IllegalArgumentException(flavor +1272" is an unsupported flavor");1273// if postscript & category is already specified within the1274// PostScript data we return null1275} else if (isAutoSense(flavor) ||(isPostScriptFlavor(flavor) &&1276(isPSDocAttr(category)))){1277return null;1278}1279}1280if (!isAttributeCategorySupported(category)) {1281return null;1282}12831284if (category == JobName.class) {1285return new JobName("Java Printing", null);1286} else if (category == RequestingUserName.class) {1287String userName = "";1288try {1289userName = System.getProperty("user.name", "");1290} catch (SecurityException se) {1291}1292return new RequestingUserName(userName, null);1293} else if (category == ColorSupported.class) {1294int caps = getPrinterCapabilities();1295if ((caps & DEVCAP_COLOR) != 0) {1296return ColorSupported.SUPPORTED;1297} else {1298return ColorSupported.NOT_SUPPORTED;1299}1300} else if (category == Chromaticity.class) {1301if (flavor == null ||1302flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||1303flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||1304flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||1305flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||1306flavor.equals(DocFlavor.URL.GIF) ||1307flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||1308flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||1309flavor.equals(DocFlavor.URL.JPEG) ||1310flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||1311flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||1312flavor.equals(DocFlavor.URL.PNG)) {1313int caps = getPrinterCapabilities();1314if ((caps & DEVCAP_COLOR) == 0) {1315Chromaticity []arr = new Chromaticity[1];1316arr[0] = Chromaticity.MONOCHROME;1317return (arr);1318} else {1319Chromaticity []arr = new Chromaticity[2];1320arr[0] = Chromaticity.MONOCHROME;1321arr[1] = Chromaticity.COLOR;1322return (arr);1323}1324} else {1325return null;1326}1327} else if (category == Destination.class) {1328try {1329return new Destination((new File("out.prn")).toURI());1330} catch (SecurityException se) {1331try {1332return new Destination(new URI("file:out.prn"));1333} catch (URISyntaxException e) {1334return null;1335}1336}1337} else if (category == OrientationRequested.class) {1338if (flavor == null ||1339flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||1340flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||1341flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||1342flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||1343flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||1344flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||1345flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||1346flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||1347flavor.equals(DocFlavor.URL.GIF) ||1348flavor.equals(DocFlavor.URL.JPEG) ||1349flavor.equals(DocFlavor.URL.PNG)) {1350OrientationRequested []arr = new OrientationRequested[3];1351arr[0] = OrientationRequested.PORTRAIT;1352arr[1] = OrientationRequested.LANDSCAPE;1353arr[2] = OrientationRequested.REVERSE_LANDSCAPE;1354return arr;1355} else {1356return null;1357}1358} else if ((category == Copies.class) ||1359(category == CopiesSupported.class)) {1360synchronized (this) {1361if (gotCopies == false) {1362nCopies = getCopiesSupported(printer, getPort());1363gotCopies = true;1364}1365}1366return new CopiesSupported(1, nCopies);1367} else if (category == Media.class) {13681369initMedia();13701371int len = (mediaSizeNames == null) ? 0 : mediaSizeNames.length;13721373MediaTray[] trays = getMediaTrays();13741375len += (trays == null) ? 0 : trays.length;13761377Media []arr = new Media[len];1378if (mediaSizeNames != null) {1379System.arraycopy(mediaSizeNames, 0, arr,13800, mediaSizeNames.length);1381}1382if (trays != null) {1383System.arraycopy(trays, 0, arr,1384len - trays.length, trays.length);1385}1386return arr;1387} else if (category == MediaPrintableArea.class) {1388// if getting printable area for a specific media size1389Media mediaName = null;1390if ((attributes != null) &&1391((mediaName =1392(Media)attributes.get(Media.class)) != null)) {13931394if (!(mediaName instanceof MediaSizeName)) {1395// if an instance of MediaTray, fall thru returning1396// all MediaPrintableAreas1397mediaName = null;1398}1399}14001401MediaPrintableArea[] mpas =1402getMediaPrintables((MediaSizeName)mediaName);1403if (mpas != null) {1404MediaPrintableArea[] arr = new MediaPrintableArea[mpas.length];1405System.arraycopy(mpas, 0, arr, 0, mpas.length);1406return arr;1407} else {1408return null;1409}1410} else if (category == SunAlternateMedia.class) {1411return new SunAlternateMedia(1412(Media)getDefaultAttributeValue(Media.class));1413} else if (category == PageRanges.class) {1414if (flavor == null ||1415flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||1416flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {1417PageRanges []arr = new PageRanges[1];1418arr[0] = new PageRanges(1, Integer.MAX_VALUE);1419return arr;1420} else {1421return null;1422}1423} else if (category == PrinterResolution.class) {1424PrinterResolution[] supportedRes = getPrintResolutions();1425if (supportedRes == null) {1426return null;1427}1428PrinterResolution []arr =1429new PrinterResolution[supportedRes.length];1430System.arraycopy(supportedRes, 0, arr, 0, supportedRes.length);1431return arr;1432} else if (category == Sides.class) {1433if (flavor == null ||1434flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||1435flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {1436Sides []arr = new Sides[3];1437arr[0] = Sides.ONE_SIDED;1438arr[1] = Sides.TWO_SIDED_LONG_EDGE;1439arr[2] = Sides.TWO_SIDED_SHORT_EDGE;1440return arr;1441} else {1442return null;1443}1444} else if (category == PrintQuality.class) {1445PrintQuality []arr = new PrintQuality[3];1446arr[0] = PrintQuality.DRAFT;1447arr[1] = PrintQuality.HIGH;1448arr[2] = PrintQuality.NORMAL;1449return arr;1450} else if (category == SheetCollate.class) {1451if (flavor == null ||1452(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||1453flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {1454SheetCollate []arr = new SheetCollate[2];1455arr[0] = SheetCollate.COLLATED;1456arr[1] = SheetCollate.UNCOLLATED;1457return arr;1458} else {1459return null;1460}1461} else if (category == Fidelity.class) {1462Fidelity []arr = new Fidelity[2];1463arr[0] = Fidelity.FIDELITY_FALSE;1464arr[1] = Fidelity.FIDELITY_TRUE;1465return arr;1466} else {1467return null;1468}1469}14701471public boolean isAttributeValueSupported(Attribute attr,1472DocFlavor flavor,1473AttributeSet attributes) {14741475if (attr == null) {1476throw new NullPointerException("null attribute");1477}1478Class category = attr.getCategory();1479if (flavor != null) {1480if (!isDocFlavorSupported(flavor)) {1481throw new IllegalArgumentException(flavor +1482" is an unsupported flavor");1483// if postscript & category is already specified within the PostScript data1484// we return false1485} else if (isAutoSense(flavor) || (isPostScriptFlavor(flavor) &&1486(isPSDocAttr(category)))) {1487return false;1488}1489}14901491if (!isAttributeCategorySupported(category)) {1492return false;1493}1494else if (category == Chromaticity.class) {1495if ((flavor == null) ||1496flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||1497flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||1498flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||1499flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||1500flavor.equals(DocFlavor.URL.GIF) ||1501flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||1502flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||1503flavor.equals(DocFlavor.URL.JPEG) ||1504flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||1505flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||1506flavor.equals(DocFlavor.URL.PNG)) {1507int caps = getPrinterCapabilities();1508if ((caps & DEVCAP_COLOR) != 0) {1509return true;1510} else {1511return attr == Chromaticity.MONOCHROME;1512}1513} else {1514return false;1515}1516} else if (category == Copies.class) {1517return isSupportedCopies((Copies)attr);15181519} else if (category == Destination.class) {1520URI uri = ((Destination)attr).getURI();1521if ("file".equals(uri.getScheme()) &&1522!(uri.getSchemeSpecificPart().equals(""))) {1523return true;1524} else {1525return false;1526}15271528} else if (category == Media.class) {1529if (attr instanceof MediaSizeName) {1530return isSupportedMedia((MediaSizeName)attr);1531}1532if (attr instanceof MediaTray) {1533return isSupportedMediaTray((MediaTray)attr);1534}15351536} else if (category == MediaPrintableArea.class) {1537return isSupportedMediaPrintableArea((MediaPrintableArea)attr);15381539} else if (category == SunAlternateMedia.class) {1540Media media = ((SunAlternateMedia)attr).getMedia();1541return isAttributeValueSupported(media, flavor, attributes);15421543} else if (category == PageRanges.class ||1544category == SheetCollate.class ||1545category == Sides.class) {1546if (flavor != null &&1547!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||1548flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {1549return false;1550}1551} else if (category == PrinterResolution.class) {1552if (attr instanceof PrinterResolution) {1553return isSupportedResolution((PrinterResolution)attr);1554}1555} else if (category == OrientationRequested.class) {1556if (attr == OrientationRequested.REVERSE_PORTRAIT ||1557(flavor != null) &&1558!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||1559flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||1560flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||1561flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||1562flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||1563flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||1564flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||1565flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||1566flavor.equals(DocFlavor.URL.GIF) ||1567flavor.equals(DocFlavor.URL.JPEG) ||1568flavor.equals(DocFlavor.URL.PNG))) {1569return false;1570}15711572} else if (category == ColorSupported.class) {1573int caps = getPrinterCapabilities();1574boolean isColorSup = ((caps & DEVCAP_COLOR) != 0);1575if ((!isColorSup && (attr == ColorSupported.SUPPORTED)) ||1576(isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) {1577return false;1578}1579}1580return true;1581}15821583public AttributeSet getUnsupportedAttributes(DocFlavor flavor,1584AttributeSet attributes) {15851586if (flavor != null && !isDocFlavorSupported(flavor)) {1587throw new IllegalArgumentException("flavor " + flavor +1588"is not supported");1589}15901591if (attributes == null) {1592return null;1593}15941595Attribute attr;1596AttributeSet unsupp = new HashAttributeSet();1597Attribute []attrs = attributes.toArray();1598for (int i=0; i<attrs.length; i++) {1599try {1600attr = attrs[i];1601if (!isAttributeCategorySupported(attr.getCategory())) {1602unsupp.add(attr);1603}1604else if (!isAttributeValueSupported(attr, flavor, attributes)) {1605unsupp.add(attr);1606}1607} catch (ClassCastException e) {1608}1609}1610if (unsupp.isEmpty()) {1611return null;1612} else {1613return unsupp;1614}1615}16161617private Win32DocumentPropertiesUI docPropertiesUI = null;16181619private static class Win32DocumentPropertiesUI1620extends DocumentPropertiesUI {16211622Win32PrintService service;16231624private Win32DocumentPropertiesUI(Win32PrintService s) {1625service = s;1626}16271628public PrintRequestAttributeSet1629showDocumentProperties(PrinterJob job,1630Window owner,1631PrintService service,1632PrintRequestAttributeSet aset) {16331634if (!(job instanceof WPrinterJob)) {1635return null;1636}1637WPrinterJob wJob = (WPrinterJob)job;1638return wJob.showDocumentProperties(owner, service, aset);1639}1640}16411642private synchronized DocumentPropertiesUI getDocumentPropertiesUI() {1643return new Win32DocumentPropertiesUI(this);1644}16451646private static class Win32ServiceUIFactory extends ServiceUIFactory {16471648Win32PrintService service;16491650Win32ServiceUIFactory(Win32PrintService s) {1651service = s;1652}16531654public Object getUI(int role, String ui) {1655if (role <= ServiceUIFactory.MAIN_UIROLE) {1656return null;1657}1658if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE &&1659DocumentPropertiesUI.DOCPROPERTIESCLASSNAME.equals(ui))1660{1661return service.getDocumentPropertiesUI();1662}1663throw new IllegalArgumentException("Unsupported role");1664}16651666public String[] getUIClassNamesForRole(int role) {16671668if (role <= ServiceUIFactory.MAIN_UIROLE) {1669return null;1670}1671if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE) {1672String[] names = new String[0];1673names[0] = DocumentPropertiesUI.DOCPROPERTIESCLASSNAME;1674return names;1675}1676throw new IllegalArgumentException("Unsupported role");1677}1678}16791680private Win32ServiceUIFactory uiFactory = null;16811682public synchronized ServiceUIFactory getServiceUIFactory() {1683if (uiFactory == null) {1684uiFactory = new Win32ServiceUIFactory(this);1685}1686return uiFactory;1687}16881689public String toString() {1690return "Win32 Printer : " + getName();1691}16921693public boolean equals(Object obj) {1694return (obj == this ||1695(obj instanceof Win32PrintService &&1696((Win32PrintService)obj).getName().equals(getName())));1697}16981699public int hashCode() {1700return this.getClass().hashCode()+getName().hashCode();1701}17021703public boolean usesClass(Class c) {1704return (c == sun.awt.windows.WPrinterJob.class);1705}17061707private native int[] getAllMediaIDs(String printerName, String port);1708private native int[] getAllMediaSizes(String printerName, String port);1709private native int[] getAllMediaTrays(String printerName, String port);1710private native float[] getMediaPrintableArea(String printerName,1711int paperSize);1712private native String[] getAllMediaNames(String printerName, String port);1713private native String[] getAllMediaTrayNames(String printerName, String port);1714private native int getCopiesSupported(String printerName, String port);1715private native int[] getAllResolutions(String printerName, String port);1716private native int getCapabilities(String printerName, String port);17171718private native int[] getDefaultSettings(String printerName, String port);1719private native int getJobStatus(String printerName, int type);1720private native String getPrinterPort(String printerName);1721}172217231724class Win32MediaSize extends MediaSizeName {1725private static ArrayList winStringTable = new ArrayList();1726private static ArrayList winEnumTable = new ArrayList();1727private static MediaSize[] predefMedia;17281729private int dmPaperID; // driver ID for this paper.17301731private Win32MediaSize(int x) {1732super(x);17331734}17351736private synchronized static int nextValue(String name) {1737winStringTable.add(name);1738return (winStringTable.size()-1);1739}17401741public static synchronized Win32MediaSize findMediaName(String name) {1742int nameIndex = winStringTable.indexOf(name);1743if (nameIndex != -1) {1744return (Win32MediaSize)winEnumTable.get(nameIndex);1745}1746return null;1747}17481749public static MediaSize[] getPredefMedia() {1750return predefMedia;1751}17521753public Win32MediaSize(String name, int dmPaper) {1754super(nextValue(name));1755dmPaperID = dmPaper;1756winEnumTable.add(this);1757}17581759private MediaSizeName[] getSuperEnumTable() {1760return (MediaSizeName[])super.getEnumValueTable();1761}17621763static {1764/* initialize predefMedia */1765{1766Win32MediaSize winMedia = new Win32MediaSize(-1);17671768// cannot call getSuperEnumTable directly because of static context1769MediaSizeName[] enumMedia = winMedia.getSuperEnumTable();1770if (enumMedia != null) {1771predefMedia = new MediaSize[enumMedia.length];17721773for (int i=0; i<enumMedia.length; i++) {1774predefMedia[i] = MediaSize.getMediaSizeForName(enumMedia[i]);1775}1776}1777}1778}17791780int getDMPaper() {1781return dmPaperID;1782}17831784protected String[] getStringTable() {1785String[] nameTable = new String[winStringTable.size()];1786return (String[])winStringTable.toArray(nameTable);1787}17881789protected EnumSyntax[] getEnumValueTable() {1790MediaSizeName[] enumTable = new MediaSizeName[winEnumTable.size()];1791return (MediaSizeName[])winEnumTable.toArray(enumTable);1792}17931794}179517961797