mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8375221: Update code to get PrinterResolution from CUPS/IPP print service
Reviewed-by: serb, psadhukhan
This commit is contained in:
parent
2c3ad0f425
commit
e08fb3a914
@ -174,6 +174,30 @@ public final class AttributeClass {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 3 int values.
|
||||
* xres, yres, resolution as either dpi or dpcm
|
||||
* The resolution is just a single byte of data.
|
||||
*/
|
||||
public int[] getIntResolutionValue() {
|
||||
int[] res = {0, 0, 0};
|
||||
byte[] bufArray = (byte[])myValue;
|
||||
if (bufArray != null) {
|
||||
int nBytes = 4; // 32-bit signed integer
|
||||
for (int j=0; j<2; j++) { // 2 set of integers
|
||||
byte[] intBytes = new byte[nBytes];
|
||||
// REMIND: # bytes should be 8
|
||||
for (int i=0; i< nBytes; i++) {
|
||||
//+ 1 because the 1st byte is length
|
||||
intBytes[i] = bufArray[i+(4*j)+1];
|
||||
}
|
||||
res[j] = convertToInt(intBytes);
|
||||
}
|
||||
res[2] = (int)bufArray[9];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns String value.
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. 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
|
||||
@ -141,7 +141,7 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService
|
||||
private MediaSizeName[] mediaSizeNames;
|
||||
private CustomMediaSizeName[] customMediaSizeNames;
|
||||
private int defaultMediaIndex;
|
||||
private int[] rawResolutions = null;
|
||||
private int[] ppdResolutions = null;
|
||||
private PrinterResolution[] printerResolutions = null;
|
||||
private boolean isCupsPrinter;
|
||||
private boolean init;
|
||||
@ -205,8 +205,7 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService
|
||||
OrientationRequested.PORTRAIT,
|
||||
new PageRanges(1),
|
||||
//PresentationDirection,
|
||||
// CUPS does not supply printer-resolution attribute
|
||||
//new PrinterResolution(300, 300, PrinterResolution.DPI),
|
||||
new PrinterResolution(300, 300, PrinterResolution.DPI),
|
||||
//PrintQuality.NORMAL,
|
||||
new RequestingUserName("", Locale.getDefault()),
|
||||
//SheetCollate.UNCOLLATED, //CUPS has no sheet collate?
|
||||
@ -467,7 +466,9 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService
|
||||
: getSupportedOutputBins();
|
||||
customMediaSizeNames = cps.getCustomMediaSizeNames();
|
||||
defaultMediaIndex = cps.getDefaultMediaIndex();
|
||||
rawResolutions = cps.getRawResolutions();
|
||||
if (ppdResolutions == null) {
|
||||
ppdResolutions = cps.getRawResolutions();
|
||||
}
|
||||
}
|
||||
urlConnection.disconnect();
|
||||
init = true;
|
||||
@ -821,14 +822,7 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
return getPrintResolutions();
|
||||
} else if (category == OutputBin.class) {
|
||||
return Arrays.copyOf(outputBins, outputBins.length);
|
||||
}
|
||||
@ -1137,8 +1131,6 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService
|
||||
catList.add(Chromaticity.class);
|
||||
}
|
||||
|
||||
// CUPS does not report printer resolution via IPP but it
|
||||
// may be gleaned from the PPD.
|
||||
PrinterResolution[] supportedRes = getPrintResolutions();
|
||||
if (supportedRes != null && (supportedRes.length > 0)) {
|
||||
catList.add(PrinterResolution.class);
|
||||
@ -1264,7 +1256,6 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized PrintServiceAttributeSet getAttributes() {
|
||||
if (!init) {
|
||||
@ -1684,9 +1675,7 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService
|
||||
} else if (category == PrinterResolution.class) {
|
||||
PrinterResolution[] supportedRes = getPrintResolutions();
|
||||
if ((supportedRes != null) && (supportedRes.length > 0)) {
|
||||
return supportedRes[0];
|
||||
} else {
|
||||
return new PrinterResolution(300, 300, PrinterResolution.DPI);
|
||||
return supportedRes[0];
|
||||
}
|
||||
} else if (category == OutputBin.class) {
|
||||
if (attribClass != null) {
|
||||
@ -1697,26 +1686,40 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Called only from contexts that have called initAttributes().
|
||||
* Try IPP first, and if that produces nothing, fall back to the PPD
|
||||
*/
|
||||
private PrinterResolution[] getPrintResolutions() {
|
||||
int[] rawResolutions = null;
|
||||
if (printerResolutions == null) {
|
||||
if (rawResolutions == null) {
|
||||
printerResolutions = new PrinterResolution[0];
|
||||
} else {
|
||||
int numRes = rawResolutions.length / 2;
|
||||
PrinterResolution[] pres = new PrinterResolution[numRes];
|
||||
for (int i=0; i < numRes; i++) {
|
||||
pres[i] = new PrinterResolution(rawResolutions[i*2],
|
||||
rawResolutions[i*2+1],
|
||||
PrinterResolution.DPI);
|
||||
}
|
||||
printerResolutions = pres;
|
||||
AttributeClass attribClass = (getAttMap != null) ?
|
||||
getAttMap.get("printer-resolution-supported")
|
||||
: null;
|
||||
if (attribClass != null) {
|
||||
rawResolutions = attribClass.getIntResolutionValue();
|
||||
}
|
||||
if (rawResolutions == null) {
|
||||
rawResolutions = ppdResolutions;
|
||||
}
|
||||
if (rawResolutions == null) {
|
||||
rawResolutions = new int[] { 300, 300, 3 } ;
|
||||
}
|
||||
int numRes = rawResolutions.length / 3;
|
||||
PrinterResolution[] pres = new PrinterResolution[numRes];
|
||||
for (int i = 0; i < numRes; i++) {
|
||||
int units = (rawResolutions[i*3+2] == 4) ? PrinterResolution.DPCM : PrinterResolution.DPI;
|
||||
pres[i] = new PrinterResolution(rawResolutions[i*3],
|
||||
rawResolutions[i*3+1],
|
||||
units);
|
||||
}
|
||||
printerResolutions = pres;
|
||||
}
|
||||
return printerResolutions;
|
||||
return printerResolutions.clone();
|
||||
}
|
||||
|
||||
private boolean isSupportedResolution(PrinterResolution res) {
|
||||
PrinterResolution[] supportedRes = getPrintResolutions();
|
||||
PrinterResolution[] supportedRes =
|
||||
(PrinterResolution[])getSupportedAttributeValues(PrinterResolution.class, null, null);
|
||||
if (supportedRes != null) {
|
||||
for (int i=0; i<supportedRes.length; i++) {
|
||||
if (res.equals(supportedRes[i])) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. 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
|
||||
@ -52,6 +52,8 @@ typedef ppd_file_t* (*fn_ppdOpenFile)(const char *);
|
||||
typedef void (*fn_ppdClose)(ppd_file_t *);
|
||||
typedef ppd_option_t* (*fn_ppdFindOption)(ppd_file_t *, const char *);
|
||||
typedef ppd_size_t* (*fn_ppdPageSize)(ppd_file_t *, char *);
|
||||
typedef ppd_attr_t* (*fn_ppdFindAttr)(ppd_file_t *, const char *name, const char *spec);
|
||||
typedef ppd_attr_t* (*fn_ppdFindNextAttr)(ppd_file_t *, const char *name, const char *spec);
|
||||
|
||||
fn_cupsServer j2d_cupsServer;
|
||||
fn_ippPort j2d_ippPort;
|
||||
@ -64,6 +66,8 @@ fn_cupsFreeDests j2d_cupsFreeDests;
|
||||
fn_ppdOpenFile j2d_ppdOpenFile;
|
||||
fn_ppdClose j2d_ppdClose;
|
||||
fn_ppdFindOption j2d_ppdFindOption;
|
||||
fn_ppdFindAttr j2d_ppdFindAttr;
|
||||
fn_ppdFindNextAttr j2d_ppdFindNextAttr;
|
||||
fn_ppdPageSize j2d_ppdPageSize;
|
||||
|
||||
|
||||
@ -152,6 +156,18 @@ Java_sun_print_CUPSPrinter_initIDs(JNIEnv *env,
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
j2d_ppdFindAttr = (fn_ppdFindAttr)dlsym(handle, "ppdFindAttr");
|
||||
if (j2d_ppdFindAttr == NULL) {
|
||||
dlclose(handle);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
j2d_ppdFindNextAttr = (fn_ppdFindNextAttr)dlsym(handle, "ppdFindNextAttr");
|
||||
if (j2d_ppdFindNextAttr == NULL) {
|
||||
dlclose(handle);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
j2d_ppdPageSize = (fn_ppdPageSize)dlsym(handle, "ppdPageSize");
|
||||
if (j2d_ppdPageSize == NULL) {
|
||||
dlclose(handle);
|
||||
@ -636,6 +652,9 @@ Java_sun_print_CUPSPrinter_getResolutions(JNIEnv *env,
|
||||
return;
|
||||
}
|
||||
|
||||
// IPP value of 3 means DPI, 4 means dpcm
|
||||
jobject dpi = (*env)->NewObject(env, intCls, intCtr, 3);
|
||||
CHECK_NULL(dpi);
|
||||
|
||||
// NOTE: cupsGetPPD returns a pointer to a filename of a temporary file.
|
||||
// unlink() must be called to remove the file after using it.
|
||||
@ -672,6 +691,7 @@ Java_sun_print_CUPSPrinter_getResolutions(JNIEnv *env,
|
||||
CHECK_NULL(ryObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, dpi);
|
||||
}
|
||||
|
||||
for (i = 0; i < resolution->num_choices; i++) {
|
||||
@ -700,6 +720,41 @@ Java_sun_print_CUPSPrinter_getResolutions(JNIEnv *env,
|
||||
CHECK_NULL(ryObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, dpi);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ppd_attr_t *defresolution = j2d_ppdFindAttr(ppd, "DefaultResolution", NULL);
|
||||
if (defresolution == NULL) {
|
||||
defresolution = j2d_ppdFindAttr(ppd, "Resolution", NULL);
|
||||
}
|
||||
if (defresolution != NULL) {
|
||||
int matches = sscanf(defresolution->value, "%dx%ddpi", &defx, &defy);
|
||||
if (matches == 2) {
|
||||
if (defx <= 0 || defy <= 0) {
|
||||
defx = 0;
|
||||
defy = 0;
|
||||
}
|
||||
} else {
|
||||
matches = sscanf(defresolution->value, "%ddpi", &defx);
|
||||
if (matches == 1) {
|
||||
if (defx <= 0) {
|
||||
defx = 0;
|
||||
} else {
|
||||
defy = defx;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defx > 0) {
|
||||
jobject rxObj, ryObj;
|
||||
rxObj = (*env)->NewObject(env, intCls, intCtr, defx);
|
||||
CHECK_NULL(rxObj);
|
||||
ryObj = (*env)->NewObject(env, intCls, intCtr, defy);
|
||||
CHECK_NULL(ryObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, dpi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, BELLSOFT. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -54,7 +54,7 @@ import java.awt.print.PrinterJob;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8251928
|
||||
* @bug 8251928 8375221
|
||||
* @key printer
|
||||
* @summary Printable.print method should reflect printer's DPI
|
||||
* @library /java/awt/regtesthelpers
|
||||
@ -201,7 +201,9 @@ public class PrintablePrintDPI implements Printable {
|
||||
attributeSet.add(OrientationRequested.PORTRAIT);
|
||||
job.setPrintService(printService);
|
||||
job.setPrintable(this);
|
||||
job.print(attributeSet);
|
||||
if (job.printDialog(attributeSet)) {
|
||||
job.print(attributeSet);
|
||||
}
|
||||
} catch (PrinterException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user