Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java
41152 views
1
/*
2
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.print;
27
28
import java.net.URL;
29
import java.net.HttpURLConnection;
30
import java.io.OutputStream;
31
import java.io.InputStream;
32
import java.util.ArrayList;
33
import java.util.HashMap;
34
import sun.print.IPPPrintService;
35
import sun.print.CustomMediaSizeName;
36
import sun.print.CustomMediaTray;
37
import javax.print.attribute.standard.Media;
38
import javax.print.attribute.standard.MediaSizeName;
39
import javax.print.attribute.standard.MediaSize;
40
import javax.print.attribute.standard.MediaTray;
41
import javax.print.attribute.standard.MediaPrintableArea;
42
import javax.print.attribute.standard.PrinterResolution;
43
import javax.print.attribute.Size2DSyntax;
44
import javax.print.attribute.Attribute;
45
import javax.print.attribute.EnumSyntax;
46
import javax.print.attribute.standard.PrinterName;
47
48
49
@SuppressWarnings("removal")
50
public class CUPSPrinter {
51
private static final String debugPrefix = "CUPSPrinter>> ";
52
private static final double PRINTER_DPI = 72.0;
53
private boolean initialized;
54
private static native String getCupsServer();
55
private static native int getCupsPort();
56
private static native String getCupsDefaultPrinter();
57
private static native boolean canConnect(String server, int port);
58
private static native boolean initIDs();
59
// These functions need to be synchronized as
60
// CUPS does not support multi-threading.
61
private static synchronized native String[] getMedia(String printer);
62
private static synchronized native float[] getPageSizes(String printer);
63
private static synchronized native void
64
getResolutions(String printer, ArrayList<Integer> resolutionList);
65
//public static boolean useIPPMedia = false; will be used later
66
67
private MediaPrintableArea[] cupsMediaPrintables;
68
private MediaSizeName[] cupsMediaSNames;
69
private CustomMediaSizeName[] cupsCustomMediaSNames;
70
private MediaTray[] cupsMediaTrays;
71
72
public int nPageSizes = 0;
73
public int nTrays = 0;
74
private String[] media;
75
private float[] pageSizes;
76
int[] resolutionsArray;
77
private String printer;
78
79
private static boolean libFound;
80
private static String cupsServer = null;
81
private static int cupsPort = 0;
82
83
static {
84
// load awt library to access native code
85
java.security.AccessController.doPrivileged(
86
new java.security.PrivilegedAction<Void>() {
87
public Void run() {
88
System.loadLibrary("awt");
89
return null;
90
}
91
});
92
libFound = initIDs();
93
if (libFound) {
94
cupsServer = getCupsServer();
95
cupsPort = getCupsPort();
96
}
97
}
98
99
100
CUPSPrinter (String printerName) {
101
if (printerName == null) {
102
throw new IllegalArgumentException("null printer name");
103
}
104
printer = printerName;
105
cupsMediaSNames = null;
106
cupsMediaPrintables = null;
107
cupsMediaTrays = null;
108
initialized = false;
109
110
if (!libFound) {
111
throw new RuntimeException("cups lib not found");
112
} else {
113
// get page + tray names
114
media = getMedia(printer);
115
if (media == null) {
116
// either PPD file is not found or printer is unknown
117
throw new RuntimeException("error getting PPD");
118
}
119
120
// get sizes
121
pageSizes = getPageSizes(printer);
122
if (pageSizes != null) {
123
nPageSizes = pageSizes.length/6;
124
125
nTrays = media.length/2-nPageSizes;
126
assert (nTrays >= 0);
127
}
128
ArrayList<Integer> resolutionList = new ArrayList<>();
129
getResolutions(printer, resolutionList);
130
resolutionsArray = new int[resolutionList.size()];
131
for (int i=0; i < resolutionList.size(); i++) {
132
resolutionsArray[i] = resolutionList.get(i);
133
}
134
}
135
}
136
137
138
/**
139
* Returns array of MediaSizeNames derived from PPD.
140
*/
141
MediaSizeName[] getMediaSizeNames() {
142
initMedia();
143
return cupsMediaSNames;
144
}
145
146
147
/**
148
* Returns array of Custom MediaSizeNames derived from PPD.
149
*/
150
CustomMediaSizeName[] getCustomMediaSizeNames() {
151
initMedia();
152
return cupsCustomMediaSNames;
153
}
154
155
public int getDefaultMediaIndex() {
156
return ((pageSizes.length >1) ? (int)(pageSizes[pageSizes.length -1]) : 0);
157
}
158
159
/**
160
* Returns array of MediaPrintableArea derived from PPD.
161
*/
162
MediaPrintableArea[] getMediaPrintableArea() {
163
initMedia();
164
return cupsMediaPrintables;
165
}
166
167
/**
168
* Returns array of MediaTrays derived from PPD.
169
*/
170
MediaTray[] getMediaTrays() {
171
initMedia();
172
return cupsMediaTrays;
173
}
174
175
/**
176
* return the raw packed array of supported printer resolutions.
177
*/
178
int[] getRawResolutions() {
179
return resolutionsArray;
180
}
181
182
/**
183
* Initialize media by translating PPD info to PrintService attributes.
184
*/
185
private synchronized void initMedia() {
186
if (initialized) {
187
return;
188
} else {
189
initialized = true;
190
}
191
192
if (pageSizes == null) {
193
return;
194
}
195
196
cupsMediaPrintables = new MediaPrintableArea[nPageSizes];
197
cupsMediaSNames = new MediaSizeName[nPageSizes];
198
cupsCustomMediaSNames = new CustomMediaSizeName[nPageSizes];
199
200
CustomMediaSizeName msn;
201
MediaPrintableArea mpa;
202
float length, width, x, y, w, h;
203
204
// initialize names and printables
205
for (int i=0; i<nPageSizes; i++) {
206
// media width and length
207
width = (float)(pageSizes[i*6]/PRINTER_DPI);
208
length = (float)(pageSizes[i*6+1]/PRINTER_DPI);
209
// media printable area
210
x = (float)(pageSizes[i*6+2]/PRINTER_DPI);
211
h = (float)(pageSizes[i*6+3]/PRINTER_DPI);
212
w = (float)(pageSizes[i*6+4]/PRINTER_DPI);
213
y = (float)(pageSizes[i*6+5]/PRINTER_DPI);
214
215
msn = new CustomMediaSizeName(media[i*2], media[i*2+1],
216
width, length);
217
218
// add to list of standard MediaSizeNames
219
if ((cupsMediaSNames[i] = msn.getStandardMedia()) == null) {
220
// add custom if no matching standard media
221
cupsMediaSNames[i] = msn;
222
223
// add this new custom msn to MediaSize array
224
if ((width > 0.0) && (length > 0.0)) {
225
try {
226
new MediaSize(width, length,
227
Size2DSyntax.INCH, msn);
228
} catch (IllegalArgumentException e) {
229
/* PDF printer in Linux for Ledger paper causes
230
"IllegalArgumentException: X dimension > Y dimension".
231
We rotate based on IPP spec. */
232
new MediaSize(length, width, Size2DSyntax.INCH, msn);
233
}
234
}
235
}
236
237
// add to list of custom MediaSizeName
238
// for internal use of IPPPrintService
239
cupsCustomMediaSNames[i] = msn;
240
241
mpa = null;
242
try {
243
mpa = new MediaPrintableArea(x, y, w, h,
244
MediaPrintableArea.INCH);
245
} catch (IllegalArgumentException e) {
246
if (width > 0 && length > 0) {
247
mpa = new MediaPrintableArea(0, 0, width, length,
248
MediaPrintableArea.INCH);
249
}
250
}
251
cupsMediaPrintables[i] = mpa;
252
}
253
254
// initialize trays
255
cupsMediaTrays = new MediaTray[nTrays];
256
257
MediaTray mt;
258
for (int i=0; i<nTrays; i++) {
259
mt = new CustomMediaTray(media[(nPageSizes+i)*2],
260
media[(nPageSizes+i)*2+1]);
261
cupsMediaTrays[i] = mt;
262
}
263
264
}
265
266
/**
267
* Get CUPS default printer using IPP.
268
* Returns 2 values - index 0 is printer name, index 1 is the uri.
269
*/
270
static String[] getDefaultPrinter() {
271
// Try to get user/lpoptions-defined printer name from CUPS
272
// if not user-set, then go for server default destination
273
String[] printerInfo = new String[2];
274
printerInfo[0] = getCupsDefaultPrinter();
275
276
if (printerInfo[0] != null) {
277
printerInfo[1] = null;
278
return printerInfo.clone();
279
}
280
try {
281
URL url = new URL("http", getServer(), getPort(), "");
282
final HttpURLConnection urlConnection =
283
IPPPrintService.getIPPConnection(url);
284
285
if (urlConnection != null) {
286
OutputStream os = java.security.AccessController.
287
doPrivileged(new java.security.PrivilegedAction<OutputStream>() {
288
public OutputStream run() {
289
try {
290
return urlConnection.getOutputStream();
291
} catch (Exception e) {
292
IPPPrintService.debug_println(debugPrefix+e);
293
}
294
return null;
295
}
296
});
297
298
if (os == null) {
299
return null;
300
}
301
302
AttributeClass[] attCl = {
303
AttributeClass.ATTRIBUTES_CHARSET,
304
AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,
305
new AttributeClass("requested-attributes",
306
AttributeClass.TAG_URI,
307
"printer-uri")
308
};
309
310
if (IPPPrintService.writeIPPRequest(os,
311
IPPPrintService.OP_CUPS_GET_DEFAULT,
312
attCl)) {
313
314
HashMap<String, AttributeClass> defaultMap = null;
315
316
InputStream is = urlConnection.getInputStream();
317
HashMap<String, AttributeClass>[] responseMap = IPPPrintService.readIPPResponse(
318
is);
319
is.close();
320
321
if (responseMap != null && responseMap.length > 0) {
322
defaultMap = responseMap[0];
323
} else {
324
IPPPrintService.debug_println(debugPrefix+
325
" empty response map for GET_DEFAULT.");
326
}
327
328
if (defaultMap == null) {
329
os.close();
330
urlConnection.disconnect();
331
332
/* CUPS on OS X, as initially configured, considers the
333
* default printer to be the last one used that's
334
* presently available. So if no default was
335
* reported, exec lpstat -d which has all the Apple
336
* special behaviour for this built in.
337
*/
338
if (PrintServiceLookupProvider.isMac()) {
339
printerInfo[0] = PrintServiceLookupProvider.
340
getDefaultPrinterNameSysV();
341
printerInfo[1] = null;
342
return printerInfo.clone();
343
} else {
344
return null;
345
}
346
}
347
348
349
AttributeClass attribClass = defaultMap.get("printer-name");
350
351
if (attribClass != null) {
352
printerInfo[0] = attribClass.getStringValue();
353
attribClass = defaultMap.get("printer-uri-supported");
354
IPPPrintService.debug_println(debugPrefix+
355
"printer-uri-supported="+attribClass);
356
if (attribClass != null) {
357
printerInfo[1] = attribClass.getStringValue();
358
} else {
359
printerInfo[1] = null;
360
}
361
os.close();
362
urlConnection.disconnect();
363
return printerInfo.clone();
364
}
365
}
366
os.close();
367
urlConnection.disconnect();
368
}
369
} catch (Exception e) {
370
}
371
return null;
372
}
373
374
375
/**
376
* Get list of all CUPS printers using IPP.
377
*/
378
static String[] getAllPrinters() {
379
try {
380
URL url = new URL("http", getServer(), getPort(), "");
381
382
final HttpURLConnection urlConnection =
383
IPPPrintService.getIPPConnection(url);
384
385
if (urlConnection != null) {
386
OutputStream os = java.security.AccessController.
387
doPrivileged(new java.security.PrivilegedAction<OutputStream>() {
388
public OutputStream run() {
389
try {
390
return urlConnection.getOutputStream();
391
} catch (Exception e) {
392
}
393
return null;
394
}
395
});
396
397
if (os == null) {
398
return null;
399
}
400
401
AttributeClass[] attCl = {
402
AttributeClass.ATTRIBUTES_CHARSET,
403
AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,
404
new AttributeClass("requested-attributes",
405
AttributeClass.TAG_KEYWORD,
406
"printer-uri-supported")
407
};
408
409
if (IPPPrintService.writeIPPRequest(os,
410
IPPPrintService.OP_CUPS_GET_PRINTERS, attCl)) {
411
412
InputStream is = urlConnection.getInputStream();
413
HashMap<String, AttributeClass>[] responseMap =
414
IPPPrintService.readIPPResponse(is);
415
416
is.close();
417
os.close();
418
urlConnection.disconnect();
419
420
if (responseMap == null || responseMap.length == 0) {
421
return null;
422
}
423
424
ArrayList<String> printerNames = new ArrayList<>();
425
for (int i=0; i< responseMap.length; i++) {
426
AttributeClass attribClass =
427
responseMap[i].get("printer-uri-supported");
428
429
if (attribClass != null) {
430
String nameStr = attribClass.getStringValue();
431
printerNames.add(nameStr);
432
}
433
}
434
return printerNames.toArray(new String[] {});
435
} else {
436
os.close();
437
urlConnection.disconnect();
438
}
439
}
440
441
} catch (Exception e) {
442
}
443
return null;
444
445
}
446
447
/**
448
* Returns CUPS server name.
449
*/
450
public static String getServer() {
451
return cupsServer;
452
}
453
454
/**
455
* Returns CUPS port number.
456
*/
457
public static int getPort() {
458
return cupsPort;
459
}
460
461
/**
462
* Detects if CUPS is running.
463
*/
464
public static boolean isCupsRunning() {
465
IPPPrintService.debug_println(debugPrefix+"libFound "+libFound);
466
if (libFound) {
467
IPPPrintService.debug_println(debugPrefix+"CUPS server "+getServer()+
468
" port "+getPort());
469
return canConnect(getServer(), getPort());
470
} else {
471
return false;
472
}
473
}
474
475
476
}
477
478