Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/print/CUPSPrinter.java
32287 views
/*1* Copyright (c) 2003, 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.net.URL;28import java.net.HttpURLConnection;29import java.io.OutputStream;30import java.io.InputStream;31import java.util.ArrayList;32import java.util.HashMap;33import sun.print.IPPPrintService;34import sun.print.CustomMediaSizeName;35import sun.print.CustomMediaTray;36import javax.print.attribute.standard.Media;37import javax.print.attribute.standard.MediaSizeName;38import javax.print.attribute.standard.MediaSize;39import javax.print.attribute.standard.MediaTray;40import javax.print.attribute.standard.MediaPrintableArea;41import javax.print.attribute.Size2DSyntax;42import javax.print.attribute.Attribute;43import javax.print.attribute.EnumSyntax;44import javax.print.attribute.standard.PrinterName;454647public class CUPSPrinter {48private static final String debugPrefix = "CUPSPrinter>> ";49private static final double PRINTER_DPI = 72.0;50private boolean initialized;51private static native String getCupsServer();52private static native int getCupsPort();53private static native String getCupsDefaultPrinter();54private static native boolean canConnect(String server, int port);55private static native boolean initIDs();56// These functions need to be synchronized as57// CUPS does not support multi-threading.58private static synchronized native String[] getMedia(String printer);59private static synchronized native float[] getPageSizes(String printer);60//public static boolean useIPPMedia = false; will be used later6162private MediaPrintableArea[] cupsMediaPrintables;63private MediaSizeName[] cupsMediaSNames;64private CustomMediaSizeName[] cupsCustomMediaSNames;65private MediaTray[] cupsMediaTrays;6667public int nPageSizes = 0;68public int nTrays = 0;69private String[] media;70private float[] pageSizes;71private String printer;7273private static boolean libFound;74private static String cupsServer = null;75private static int cupsPort = 0;7677static {78// load awt library to access native code79java.security.AccessController.doPrivileged(80new java.security.PrivilegedAction<Void>() {81public Void run() {82System.loadLibrary("awt");83return null;84}85});86libFound = initIDs();87if (libFound) {88cupsServer = getCupsServer();89cupsPort = getCupsPort();90}91}929394CUPSPrinter (String printerName) {95if (printerName == null) {96throw new IllegalArgumentException("null printer name");97}98printer = printerName;99cupsMediaSNames = null;100cupsMediaPrintables = null;101cupsMediaTrays = null;102initialized = false;103104if (!libFound) {105throw new RuntimeException("cups lib not found");106} else {107// get page + tray names108media = getMedia(printer);109if (media == null) {110// either PPD file is not found or printer is unknown111throw new RuntimeException("error getting PPD");112}113114// get sizes115pageSizes = getPageSizes(printer);116if (pageSizes != null) {117nPageSizes = pageSizes.length/6;118119nTrays = media.length/2-nPageSizes;120assert (nTrays >= 0);121}122}123}124125126/**127* Returns array of MediaSizeNames derived from PPD.128*/129MediaSizeName[] getMediaSizeNames() {130initMedia();131return cupsMediaSNames;132}133134135/**136* Returns array of Custom MediaSizeNames derived from PPD.137*/138CustomMediaSizeName[] getCustomMediaSizeNames() {139initMedia();140return cupsCustomMediaSNames;141}142143public int getDefaultMediaIndex() {144return ((pageSizes.length >1) ? (int)(pageSizes[pageSizes.length -1]) : 0);145}146147/**148* Returns array of MediaPrintableArea derived from PPD.149*/150MediaPrintableArea[] getMediaPrintableArea() {151initMedia();152return cupsMediaPrintables;153}154155/**156* Returns array of MediaTrays derived from PPD.157*/158MediaTray[] getMediaTrays() {159initMedia();160return cupsMediaTrays;161}162163164/**165* Initialize media by translating PPD info to PrintService attributes.166*/167private synchronized void initMedia() {168if (initialized) {169return;170} else {171initialized = true;172}173174if (pageSizes == null) {175return;176}177178cupsMediaPrintables = new MediaPrintableArea[nPageSizes];179cupsMediaSNames = new MediaSizeName[nPageSizes];180cupsCustomMediaSNames = new CustomMediaSizeName[nPageSizes];181182CustomMediaSizeName msn;183MediaPrintableArea mpa;184float length, width, x, y, w, h;185186// initialize names and printables187for (int i=0; i<nPageSizes; i++) {188// media width and length189width = (float)(pageSizes[i*6]/PRINTER_DPI);190length = (float)(pageSizes[i*6+1]/PRINTER_DPI);191// media printable area192x = (float)(pageSizes[i*6+2]/PRINTER_DPI);193h = (float)(pageSizes[i*6+3]/PRINTER_DPI);194w = (float)(pageSizes[i*6+4]/PRINTER_DPI);195y = (float)(pageSizes[i*6+5]/PRINTER_DPI);196197msn = new CustomMediaSizeName(media[i*2], media[i*2+1],198width, length);199200// add to list of standard MediaSizeNames201if ((cupsMediaSNames[i] = msn.getStandardMedia()) == null) {202// add custom if no matching standard media203cupsMediaSNames[i] = msn;204205// add this new custom msn to MediaSize array206if ((width > 0.0) && (length > 0.0)) {207try {208new MediaSize(width, length,209Size2DSyntax.INCH, msn);210} catch (IllegalArgumentException e) {211/* PDF printer in Linux for Ledger paper causes212"IllegalArgumentException: X dimension > Y dimension".213We rotate based on IPP spec. */214new MediaSize(length, width, Size2DSyntax.INCH, msn);215}216}217}218219// add to list of custom MediaSizeName220// for internal use of IPPPrintService221cupsCustomMediaSNames[i] = msn;222223mpa = null;224try {225mpa = new MediaPrintableArea(x, y, w, h,226MediaPrintableArea.INCH);227} catch (IllegalArgumentException e) {228if (width > 0 && length > 0) {229mpa = new MediaPrintableArea(0, 0, width, length,230MediaPrintableArea.INCH);231}232}233cupsMediaPrintables[i] = mpa;234}235236// initialize trays237cupsMediaTrays = new MediaTray[nTrays];238239MediaTray mt;240for (int i=0; i<nTrays; i++) {241mt = new CustomMediaTray(media[(nPageSizes+i)*2],242media[(nPageSizes+i)*2+1]);243cupsMediaTrays[i] = mt;244}245246}247248/**249* Get CUPS default printer using IPP.250* Returns 2 values - index 0 is printer name, index 1 is the uri.251*/252static String[] getDefaultPrinter() {253// Try to get user/lpoptions-defined printer name from CUPS254// if not user-set, then go for server default destination255String printerInfo[] = new String[2];256printerInfo[0] = getCupsDefaultPrinter();257258if (printerInfo[0] != null) {259printerInfo[1] = null;260return printerInfo.clone();261}262try {263URL url = new URL("http", getServer(), getPort(), "");264final HttpURLConnection urlConnection =265IPPPrintService.getIPPConnection(url);266267if (urlConnection != null) {268OutputStream os = (OutputStream)java.security.AccessController.269doPrivileged(new java.security.PrivilegedAction() {270public Object run() {271try {272return urlConnection.getOutputStream();273} catch (Exception e) {274IPPPrintService.debug_println(debugPrefix+e);275}276return null;277}278});279280if (os == null) {281return null;282}283284AttributeClass attCl[] = {285AttributeClass.ATTRIBUTES_CHARSET,286AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,287new AttributeClass("requested-attributes",288AttributeClass.TAG_URI,289"printer-uri")290};291292if (IPPPrintService.writeIPPRequest(os,293IPPPrintService.OP_CUPS_GET_DEFAULT,294attCl)) {295296HashMap defaultMap = null;297298InputStream is = urlConnection.getInputStream();299HashMap[] responseMap = IPPPrintService.readIPPResponse(300is);301is.close();302303if (responseMap != null && responseMap.length > 0) {304defaultMap = responseMap[0];305} else {306IPPPrintService.debug_println(debugPrefix+307" empty response map for GET_DEFAULT.");308}309310if (defaultMap == null) {311os.close();312urlConnection.disconnect();313314/* CUPS on OS X, as initially configured, considers the315* default printer to be the last one used that's316* presently available. So if no default was317* reported, exec lpstat -d which has all the Apple318* special behaviour for this built in.319*/320if (PrintServiceLookupProvider.isMac()) {321printerInfo[0] = PrintServiceLookupProvider.322getDefaultPrinterNameSysV();323printerInfo[1] = null;324return (String[])printerInfo.clone();325} else {326return null;327}328}329330331AttributeClass attribClass = (AttributeClass)332defaultMap.get("printer-name");333334if (attribClass != null) {335printerInfo[0] = attribClass.getStringValue();336attribClass = (AttributeClass)337defaultMap.get("printer-uri-supported");338IPPPrintService.debug_println(debugPrefix+339"printer-uri-supported="+attribClass);340if (attribClass != null) {341printerInfo[1] = attribClass.getStringValue();342} else {343printerInfo[1] = null;344}345os.close();346urlConnection.disconnect();347return (String [])printerInfo.clone();348}349}350os.close();351urlConnection.disconnect();352}353} catch (Exception e) {354}355return null;356}357358359/**360* Get list of all CUPS printers using IPP.361*/362static String[] getAllPrinters() {363try {364URL url = new URL("http", getServer(), getPort(), "");365366final HttpURLConnection urlConnection =367IPPPrintService.getIPPConnection(url);368369if (urlConnection != null) {370OutputStream os = (OutputStream)java.security.AccessController.371doPrivileged(new java.security.PrivilegedAction() {372public Object run() {373try {374return urlConnection.getOutputStream();375} catch (Exception e) {376}377return null;378}379});380381if (os == null) {382return null;383}384385AttributeClass attCl[] = {386AttributeClass.ATTRIBUTES_CHARSET,387AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,388new AttributeClass("requested-attributes",389AttributeClass.TAG_KEYWORD,390"printer-uri-supported")391};392393if (IPPPrintService.writeIPPRequest(os,394IPPPrintService.OP_CUPS_GET_PRINTERS, attCl)) {395396InputStream is = urlConnection.getInputStream();397HashMap[] responseMap =398IPPPrintService.readIPPResponse(is);399400is.close();401os.close();402urlConnection.disconnect();403404if (responseMap == null || responseMap.length == 0) {405return null;406}407408ArrayList printerNames = new ArrayList();409for (int i=0; i< responseMap.length; i++) {410AttributeClass attribClass = (AttributeClass)411responseMap[i].get("printer-uri-supported");412413if (attribClass != null) {414String nameStr = attribClass.getStringValue();415printerNames.add(nameStr);416}417}418return (String[])printerNames.toArray(new String[] {});419} else {420os.close();421urlConnection.disconnect();422}423}424425} catch (Exception e) {426}427return null;428429}430431/**432* Returns CUPS server name.433*/434public static String getServer() {435return cupsServer;436}437438/**439* Returns CUPS port number.440*/441public static int getPort() {442return cupsPort;443}444445/**446* Detects if CUPS is running.447*/448public static boolean isCupsRunning() {449IPPPrintService.debug_println(debugPrefix+"libFound "+libFound);450if (libFound) {451IPPPrintService.debug_println(debugPrefix+"CUPS server "+getServer()+452" port "+getPort());453return canConnect(getServer(), getPort());454} else {455return false;456}457}458459460}461462463