Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/windows/classes/sun/print/Win32PrintService.java
41152 views
1
/*
2
* Copyright (c) 2000, 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.awt.GraphicsEnvironment;
29
import java.awt.Toolkit;
30
import java.awt.Window;
31
import java.awt.print.PrinterJob;
32
import java.io.File;
33
import java.net.URI;
34
import java.net.URISyntaxException;
35
import java.util.ArrayList;
36
import java.util.HashMap;
37
import javax.print.DocFlavor;
38
import javax.print.DocPrintJob;
39
import javax.print.PrintService;
40
import javax.print.ServiceUIFactory;
41
import javax.print.attribute.Attribute;
42
import javax.print.attribute.AttributeSet;
43
import javax.print.attribute.AttributeSetUtilities;
44
import javax.print.attribute.EnumSyntax;
45
import javax.print.attribute.HashAttributeSet;
46
import javax.print.attribute.PrintRequestAttributeSet;
47
import javax.print.attribute.PrintServiceAttribute;
48
import javax.print.attribute.PrintServiceAttributeSet;
49
import javax.print.attribute.HashPrintServiceAttributeSet;
50
import javax.print.attribute.standard.PrinterName;
51
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
52
import javax.print.attribute.standard.QueuedJobCount;
53
import javax.print.attribute.standard.JobName;
54
import javax.print.attribute.standard.RequestingUserName;
55
import javax.print.attribute.standard.Chromaticity;
56
import javax.print.attribute.standard.Copies;
57
import javax.print.attribute.standard.CopiesSupported;
58
import javax.print.attribute.standard.Destination;
59
import javax.print.attribute.standard.DialogOwner;
60
import javax.print.attribute.standard.DialogTypeSelection;
61
import javax.print.attribute.standard.Fidelity;
62
import javax.print.attribute.standard.Media;
63
import javax.print.attribute.standard.MediaSizeName;
64
import javax.print.attribute.standard.MediaSize;
65
import javax.print.attribute.standard.MediaTray;
66
import javax.print.attribute.standard.MediaPrintableArea;
67
import javax.print.attribute.standard.OrientationRequested;
68
import javax.print.attribute.standard.PageRanges;
69
import javax.print.attribute.standard.PrinterState;
70
import javax.print.attribute.standard.PrinterStateReason;
71
import javax.print.attribute.standard.PrinterStateReasons;
72
import javax.print.attribute.standard.Severity;
73
import javax.print.attribute.standard.Sides;
74
import javax.print.attribute.standard.ColorSupported;
75
import javax.print.attribute.standard.PrintQuality;
76
import javax.print.attribute.standard.PrinterResolution;
77
import javax.print.attribute.standard.SheetCollate;
78
import javax.print.event.PrintServiceAttributeListener;
79
import sun.awt.windows.WPrinterJob;
80
81
public class Win32PrintService implements PrintService, AttributeUpdater,
82
SunPrinterJobService {
83
84
public static MediaSize[] predefMedia = Win32MediaSize.getPredefMedia();
85
86
private static final DocFlavor[] supportedFlavors = {
87
DocFlavor.BYTE_ARRAY.GIF,
88
DocFlavor.INPUT_STREAM.GIF,
89
DocFlavor.URL.GIF,
90
DocFlavor.BYTE_ARRAY.JPEG,
91
DocFlavor.INPUT_STREAM.JPEG,
92
DocFlavor.URL.JPEG,
93
DocFlavor.BYTE_ARRAY.PNG,
94
DocFlavor.INPUT_STREAM.PNG,
95
DocFlavor.URL.PNG,
96
DocFlavor.SERVICE_FORMATTED.PAGEABLE,
97
DocFlavor.SERVICE_FORMATTED.PRINTABLE,
98
DocFlavor.BYTE_ARRAY.AUTOSENSE,
99
DocFlavor.URL.AUTOSENSE,
100
DocFlavor.INPUT_STREAM.AUTOSENSE
101
};
102
103
/* let's try to support a few of these */
104
private static final Class<?>[] serviceAttrCats = {
105
PrinterName.class,
106
PrinterIsAcceptingJobs.class,
107
QueuedJobCount.class,
108
ColorSupported.class,
109
};
110
111
/* it turns out to be inconvenient to store the other categories
112
* separately because many attributes are in multiple categories.
113
*/
114
private static Class<?>[] otherAttrCats = {
115
JobName.class,
116
RequestingUserName.class,
117
Copies.class,
118
Destination.class,
119
OrientationRequested.class,
120
PageRanges.class,
121
Media.class,
122
MediaPrintableArea.class,
123
Fidelity.class,
124
// We support collation on 2D printer jobs, even if the driver can't.
125
SheetCollate.class,
126
SunAlternateMedia.class,
127
Chromaticity.class
128
};
129
130
131
/*
132
* This table together with methods findWin32Media and
133
* findMatchingMediaSizeNameMM are declared public as these are also
134
* used in WPrinterJob.java.
135
*/
136
public static final MediaSizeName[] dmPaperToPrintService = {
137
MediaSizeName.NA_LETTER, MediaSizeName.NA_LETTER,
138
MediaSizeName.TABLOID, MediaSizeName.LEDGER,
139
MediaSizeName.NA_LEGAL, MediaSizeName.INVOICE,
140
MediaSizeName.EXECUTIVE, MediaSizeName.ISO_A3,
141
MediaSizeName.ISO_A4, MediaSizeName.ISO_A4,
142
MediaSizeName.ISO_A5, MediaSizeName.JIS_B4,
143
MediaSizeName.JIS_B5, MediaSizeName.FOLIO,
144
MediaSizeName.QUARTO, MediaSizeName.NA_10X14_ENVELOPE,
145
MediaSizeName.B, MediaSizeName.NA_LETTER,
146
MediaSizeName.NA_NUMBER_9_ENVELOPE, MediaSizeName.NA_NUMBER_10_ENVELOPE,
147
MediaSizeName.NA_NUMBER_11_ENVELOPE, MediaSizeName.NA_NUMBER_12_ENVELOPE,
148
MediaSizeName.NA_NUMBER_14_ENVELOPE, MediaSizeName.C,
149
MediaSizeName.D, MediaSizeName.E,
150
MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.ISO_C5,
151
MediaSizeName.ISO_C3, MediaSizeName.ISO_C4,
152
MediaSizeName.ISO_C6, MediaSizeName.ITALY_ENVELOPE,
153
MediaSizeName.ISO_B4, MediaSizeName.ISO_B5,
154
MediaSizeName.ISO_B6, MediaSizeName.ITALY_ENVELOPE,
155
MediaSizeName.MONARCH_ENVELOPE, MediaSizeName.PERSONAL_ENVELOPE,
156
MediaSizeName.NA_10X15_ENVELOPE, MediaSizeName.NA_9X12_ENVELOPE,
157
MediaSizeName.FOLIO, MediaSizeName.ISO_B4,
158
MediaSizeName.JAPANESE_POSTCARD, MediaSizeName.NA_9X11_ENVELOPE,
159
};
160
161
private static final MediaTray[] dmPaperBinToPrintService = {
162
MediaTray.TOP, MediaTray.BOTTOM, MediaTray.MIDDLE,
163
MediaTray.MANUAL, MediaTray.ENVELOPE, Win32MediaTray.ENVELOPE_MANUAL,
164
Win32MediaTray.AUTO, Win32MediaTray.TRACTOR,
165
Win32MediaTray.SMALL_FORMAT, Win32MediaTray.LARGE_FORMAT,
166
MediaTray.LARGE_CAPACITY, null, null,
167
MediaTray.MAIN, Win32MediaTray.FORMSOURCE,
168
};
169
170
// from wingdi.h
171
private static int DM_PAPERSIZE = 0x2;
172
private static int DM_PRINTQUALITY = 0x400;
173
private static int DM_YRESOLUTION = 0x2000;
174
private static final int DMRES_MEDIUM = -3;
175
private static final int DMRES_HIGH = -4;
176
private static final int DMORIENT_LANDSCAPE = 2;
177
private static final int DMDUP_VERTICAL = 2;
178
private static final int DMDUP_HORIZONTAL = 3;
179
private static final int DMCOLLATE_TRUE = 1;
180
private static final int DMCOLOR_MONOCHROME = 1;
181
private static final int DMCOLOR_COLOR = 2;
182
183
184
// media sizes with indices above dmPaperToPrintService' length
185
private static final int DMPAPER_A2 = 66;
186
private static final int DMPAPER_A6 = 70;
187
private static final int DMPAPER_B6_JIS = 88;
188
189
190
// Bit settings for getPrinterCapabilities which matches that
191
// of native getCapabilities in WPrinterJob.cpp
192
private static final int DEVCAP_COLOR = 0x0001;
193
private static final int DEVCAP_DUPLEX = 0x0002;
194
private static final int DEVCAP_COLLATE = 0x0004;
195
private static final int DEVCAP_QUALITY = 0x0008;
196
private static final int DEVCAP_POSTSCRIPT = 0x0010;
197
198
private String printer;
199
private PrinterName name;
200
private String port;
201
202
private transient PrintServiceAttributeSet lastSet;
203
private transient ServiceNotifier notifier = null;
204
205
private MediaSizeName[] mediaSizeNames;
206
private MediaPrintableArea[] mediaPrintables;
207
private MediaTray[] mediaTrays;
208
private PrinterResolution[] printRes;
209
private HashMap<MediaSizeName, MediaPrintableArea> mpaMap;
210
private int nCopies;
211
private int prnCaps;
212
private int[] defaultSettings;
213
214
private boolean gotTrays;
215
private boolean gotCopies;
216
private boolean mediaInitialized;
217
private boolean mpaListInitialized;
218
219
private ArrayList<Integer> idList;
220
private MediaSize[] mediaSizes;
221
222
private boolean isInvalid;
223
224
Win32PrintService(String name) {
225
if (name == null) {
226
throw new IllegalArgumentException("null printer name");
227
}
228
printer = name;
229
230
// initialize flags
231
mediaInitialized = false;
232
gotTrays = false;
233
gotCopies = false;
234
isInvalid = false;
235
printRes = null;
236
prnCaps = 0;
237
defaultSettings = null;
238
port = null;
239
}
240
241
public void invalidateService() {
242
isInvalid = true;
243
}
244
245
public String getName() {
246
return printer;
247
}
248
249
private PrinterName getPrinterName() {
250
if (name == null) {
251
name = new PrinterName(printer, null);
252
}
253
return name;
254
}
255
256
public int findPaperID(MediaSizeName msn) {
257
if (msn instanceof Win32MediaSize) {
258
Win32MediaSize winMedia = (Win32MediaSize)msn;
259
return winMedia.getDMPaper();
260
} else {
261
for (int id=0; id<dmPaperToPrintService.length;id++) {
262
if (dmPaperToPrintService[id].equals(msn)) {
263
return id+1; // DMPAPER_LETTER == 1
264
}
265
}
266
if (msn.equals(MediaSizeName.ISO_A2)) {
267
return DMPAPER_A2;
268
}
269
else if (msn.equals(MediaSizeName.ISO_A6)) {
270
return DMPAPER_A6;
271
}
272
else if (msn.equals(MediaSizeName.JIS_B6)) {
273
return DMPAPER_B6_JIS;
274
}
275
}
276
277
// If not found in predefined Windows ID, then we search through
278
// the returned IDs of the driver because they can define their own
279
// unique IDs.
280
initMedia();
281
282
if ((idList != null) && (mediaSizes != null) &&
283
(idList.size() == mediaSizes.length)) {
284
for (int i=0; i< idList.size(); i++) {
285
if (mediaSizes[i].getMediaSizeName() == msn) {
286
return idList.get(i).intValue();
287
}
288
}
289
}
290
return 0;
291
}
292
293
public int findTrayID(MediaTray tray) {
294
295
getMediaTrays(); // make sure they are initialised.
296
297
if (tray instanceof Win32MediaTray) {
298
Win32MediaTray winTray = (Win32MediaTray)tray;
299
return winTray.getDMBinID();
300
}
301
for (int id=0; id<dmPaperBinToPrintService.length; id++) {
302
if (tray.equals(dmPaperBinToPrintService[id])) {
303
return id+1; // DMBIN_FIRST = 1;
304
}
305
}
306
return 0; // didn't find the tray
307
}
308
309
public MediaTray findMediaTray(int dmBin) {
310
if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {
311
return dmPaperBinToPrintService[dmBin-1];
312
}
313
MediaTray[] trays = getMediaTrays();
314
if (trays != null) {
315
for (int i=0;i<trays.length;i++) {
316
if(trays[i] instanceof Win32MediaTray) {
317
Win32MediaTray win32Tray = (Win32MediaTray)trays[i];
318
if (win32Tray.winID == dmBin) {
319
return win32Tray;
320
}
321
}
322
}
323
}
324
return Win32MediaTray.AUTO;
325
}
326
327
public MediaSizeName findWin32Media(int dmIndex) {
328
if (dmIndex >= 1 && dmIndex <= dmPaperToPrintService.length) {
329
return dmPaperToPrintService[dmIndex - 1];
330
}
331
switch(dmIndex) {
332
/* matching media sizes with indices beyond
333
dmPaperToPrintService's length */
334
case DMPAPER_A2:
335
return MediaSizeName.ISO_A2;
336
case DMPAPER_A6:
337
return MediaSizeName.ISO_A6;
338
case DMPAPER_B6_JIS:
339
return MediaSizeName.JIS_B6;
340
default:
341
return null;
342
}
343
}
344
345
private boolean addToUniqueList(ArrayList<MediaSizeName> msnList,
346
MediaSizeName mediaName) {
347
MediaSizeName msn;
348
for (int i=0; i< msnList.size(); i++) {
349
msn = msnList.get(i);
350
if (msn == mediaName) {
351
return false;
352
}
353
}
354
msnList.add(mediaName);
355
return true;
356
}
357
358
private synchronized void initMedia() {
359
if (mediaInitialized == true) {
360
return;
361
}
362
mediaInitialized = true;
363
int[] media = getAllMediaIDs(printer, getPort());
364
if (media == null) {
365
return;
366
}
367
368
ArrayList<MediaSizeName> msnList = new ArrayList<>();
369
ArrayList<Win32MediaSize> trailingWmsList = new ArrayList<Win32MediaSize>();
370
MediaSizeName mediaName;
371
boolean added;
372
boolean queryFailure = false;
373
float[] prnArea;
374
375
// Get all mediaSizes supported by the printer.
376
// We convert media to ArrayList idList and pass this to the
377
// function for getting mediaSizes.
378
// This is to ensure that mediaSizes and media IDs have 1-1 correspondence.
379
// We remove from ID list any invalid mediaSize. Though this is rare,
380
// it happens in HP 4050 German driver.
381
382
idList = new ArrayList<>();
383
for (int i=0; i < media.length; i++) {
384
idList.add(Integer.valueOf(media[i]));
385
}
386
387
ArrayList<String> dmPaperNameList = new ArrayList<String>();
388
mediaSizes = getMediaSizes(idList, media, dmPaperNameList);
389
for (int i = 0; i < idList.size(); i++) {
390
391
// match Win ID with our predefined ID using table
392
mediaName = findWin32Media(idList.get(i).intValue());
393
// Verify that this standard size is the same size as that
394
// reported by the driver. This should be the case except when
395
// the driver is mis-using a standard windows paper ID.
396
if (mediaName != null &&
397
idList.size() == mediaSizes.length) {
398
MediaSize win32Size = MediaSize.getMediaSizeForName(mediaName);
399
MediaSize driverSize = mediaSizes[i];
400
int error = 2540; // == 1/10"
401
if (Math.abs(win32Size.getX(1)-driverSize.getX(1)) > error ||
402
Math.abs(win32Size.getY(1)-driverSize.getY(1)) > error)
403
{
404
mediaName = null;
405
}
406
}
407
boolean dmPaperIDMatched = (mediaName != null);
408
409
// No match found, then we get the MediaSizeName out of the MediaSize
410
// This requires 1-1 correspondence, lengths must be checked.
411
if ((mediaName == null) && (idList.size() == mediaSizes.length)) {
412
mediaName = mediaSizes[i].getMediaSizeName();
413
}
414
415
// Add mediaName to the msnList
416
added = false;
417
if (mediaName != null) {
418
added = addToUniqueList(msnList, mediaName);
419
}
420
if ((!dmPaperIDMatched || !added) && (idList.size() == dmPaperNameList.size())) {
421
/* The following block allows to add such media names to the list, whose sizes
422
* matched with media sizes predefined in JDK, while whose paper IDs did not,
423
* or whose sizes and paper IDs both did not match with any predefined in JDK.
424
*/
425
Win32MediaSize wms = Win32MediaSize.findMediaName(dmPaperNameList.get(i));
426
if ((wms == null) && (idList.size() == mediaSizes.length)) {
427
wms = new Win32MediaSize(dmPaperNameList.get(i), idList.get(i));
428
mediaSizes[i] = new MediaSize(mediaSizes[i].getX(MediaSize.MM),
429
mediaSizes[i].getY(MediaSize.MM), MediaSize.MM, wms);
430
}
431
if ((wms != null) && (wms != mediaName)) {
432
if (!added) {
433
added = addToUniqueList(msnList, mediaName = wms);
434
} else {
435
trailingWmsList.add(wms);
436
}
437
}
438
}
439
}
440
for (Win32MediaSize wms : trailingWmsList) {
441
added = addToUniqueList(msnList, wms);
442
}
443
444
// init mediaSizeNames
445
mediaSizeNames = new MediaSizeName[msnList.size()];
446
msnList.toArray(mediaSizeNames);
447
}
448
449
450
/*
451
* Gets a list of MediaPrintableAreas using a call to native function.
452
* msn is MediaSizeName used to get a specific printable area. If null,
453
* it will get all the supported MediPrintableAreas.
454
*/
455
private synchronized MediaPrintableArea[] getMediaPrintables(MediaSizeName msn)
456
{
457
if (msn == null) {
458
if (mpaListInitialized == true) {
459
return mediaPrintables;
460
}
461
} else {
462
// get from cached mapping of MPAs
463
if (mpaMap != null && (mpaMap.get(msn) != null)) {
464
MediaPrintableArea[] mpaArr = new MediaPrintableArea[1];
465
mpaArr[0] = mpaMap.get(msn);
466
return mpaArr;
467
}
468
}
469
470
initMedia();
471
472
if ((mediaSizeNames == null) || (mediaSizeNames.length == 0)) {
473
return null;
474
}
475
476
MediaSizeName[] loopNames;
477
if (msn != null) {
478
loopNames = new MediaSizeName[1];
479
loopNames[0] = msn;
480
} else {
481
loopNames = mediaSizeNames;
482
}
483
484
if (mpaMap == null) {
485
mpaMap = new HashMap<>();
486
}
487
488
for (int i=0; i < loopNames.length; i++) {
489
MediaSizeName mediaName = loopNames[i];
490
491
if (mpaMap.get(mediaName) != null) {
492
continue;
493
}
494
495
if (mediaName != null) {
496
int defPaper = findPaperID(mediaName);
497
float[] prnArea = (defPaper != 0) ? getMediaPrintableArea(printer, defPaper) : null;
498
MediaPrintableArea printableArea = null;
499
if (prnArea != null) {
500
try {
501
printableArea = new MediaPrintableArea(prnArea[0],
502
prnArea[1],
503
prnArea[2],
504
prnArea[3],
505
MediaPrintableArea.INCH);
506
507
mpaMap.put(mediaName, printableArea);
508
}
509
catch (IllegalArgumentException e) {
510
}
511
} else {
512
// if getting MPA failed, we use MediaSize
513
MediaSize ms = MediaSize.getMediaSizeForName(mediaName);
514
515
if (ms != null) {
516
try {
517
printableArea = new MediaPrintableArea(0, 0,
518
ms.getX(MediaSize.INCH),
519
ms.getY(MediaSize.INCH),
520
MediaPrintableArea.INCH);
521
mpaMap.put(mediaName, printableArea);
522
} catch (IllegalArgumentException e) {
523
}
524
}
525
}
526
} //mediaName != null
527
}
528
529
if (mpaMap.size() == 0) {
530
return null;
531
}
532
533
if (msn != null) {
534
if (mpaMap.get(msn) == null) {
535
return null;
536
}
537
MediaPrintableArea[] mpaArr = new MediaPrintableArea[1];
538
// by this time, we've already gotten the desired MPA
539
mpaArr[0] = mpaMap.get(msn);
540
return mpaArr;
541
} else {
542
mediaPrintables = mpaMap.values().toArray(new MediaPrintableArea[0]);
543
mpaListInitialized = true;
544
return mediaPrintables;
545
}
546
}
547
548
549
private synchronized MediaTray[] getMediaTrays() {
550
if (gotTrays == true && mediaTrays != null) {
551
return mediaTrays;
552
}
553
String prnPort = getPort();
554
int[] mediaTr = getAllMediaTrays(printer, prnPort);
555
String[] winMediaTrayNames = getAllMediaTrayNames(printer, prnPort);
556
557
if ((mediaTr == null) || (winMediaTrayNames == null)){
558
return null;
559
}
560
561
/* first count how many valid bins there are so we can allocate
562
* an array of the correct size
563
*/
564
int nTray = 0;
565
for (int i=0; i < mediaTr.length ; i++) {
566
if (mediaTr[i] > 0) nTray++;
567
}
568
569
MediaTray[] arr = new MediaTray[nTray];
570
int dmBin;
571
572
/* Some drivers in Win 7 don't have the same length for DC_BINS and
573
* DC_BINNAMES so there is no guarantee that lengths of mediaTr and
574
* winMediaTrayNames are equal. To avoid getting ArrayIndexOutOfBounds,
575
* we need to make sure we get the minimum of the two.
576
*/
577
578
for (int i = 0, j=0; i < Math.min(mediaTr.length, winMediaTrayNames.length); i++) {
579
dmBin = mediaTr[i];
580
if (dmBin > 0) {
581
// check for unsupported DMBINs and create new Win32MediaTray
582
if ((dmBin > dmPaperBinToPrintService.length)
583
|| (dmPaperBinToPrintService[dmBin-1] == null)) {
584
arr[j++] = new Win32MediaTray(dmBin, winMediaTrayNames[i]);
585
} else {
586
arr[j++] = dmPaperBinToPrintService[dmBin-1];
587
}
588
}
589
// no else - For invalid ids, just ignore it because assigning a "default"
590
// value may result in duplicate trays.
591
}
592
mediaTrays = arr;
593
gotTrays = true;
594
return mediaTrays;
595
}
596
597
private boolean isSameSize(float w1, float h1, float w2, float h2) {
598
float diffX = w1 - w2;
599
float diffY = h1 - h2;
600
// Get diff of reverse dimensions
601
// EPSON Stylus COLOR 860 reverses envelope's width & height
602
float diffXrev = w1 - h2;
603
float diffYrev = h1 - w2;
604
605
if (((Math.abs(diffX)<=1) && (Math.abs(diffY)<=1)) ||
606
((Math.abs(diffXrev)<=1) && (Math.abs(diffYrev)<=1))){
607
return true;
608
} else {
609
return false;
610
}
611
}
612
613
public MediaSizeName findMatchingMediaSizeNameMM (float w, float h){
614
if (predefMedia != null) {
615
for (int k=0; k<predefMedia.length;k++) {
616
if (predefMedia[k] == null) {
617
continue;
618
}
619
620
if (isSameSize(predefMedia[k].getX(MediaSize.MM),
621
predefMedia[k].getY(MediaSize.MM),
622
w, h)) {
623
return predefMedia[k].getMediaSizeName();
624
}
625
}
626
}
627
return null;
628
}
629
630
631
private MediaSize[] getMediaSizes(ArrayList<Integer> idList, int[] media,
632
ArrayList<String> dmPaperNameList) {
633
if (dmPaperNameList == null) {
634
dmPaperNameList = new ArrayList<String>();
635
}
636
637
String prnPort = getPort();
638
int[] mediaSz = getAllMediaSizes(printer, prnPort);
639
String[] winMediaNames = getAllMediaNames(printer, prnPort);
640
MediaSizeName msn = null;
641
MediaSize ms = null;
642
float wid, ht;
643
644
if ((mediaSz == null) || (winMediaNames == null)) {
645
return null;
646
}
647
648
int nMedia = mediaSz.length/2;
649
ArrayList<MediaSize> msList = new ArrayList<>();
650
651
for (int i = 0; i < nMedia; i++, ms=null) {
652
wid = mediaSz[i*2]/10f;
653
ht = mediaSz[i*2+1]/10f;
654
655
// Make sure to validate wid & ht.
656
// HP LJ 4050 (german) causes IAE in Sonderformat paper, wid & ht
657
// returned is not constant.
658
if ((wid <= 0) || (ht <= 0)) {
659
//Remove corresponding ID from list
660
if (nMedia == media.length) {
661
Integer remObj = Integer.valueOf(media[i]);
662
idList.remove(idList.indexOf(remObj));
663
}
664
continue;
665
}
666
// Find matching media using dimensions.
667
// This call matches only with our own predefined sizes.
668
msn = findMatchingMediaSizeNameMM(wid, ht);
669
if (msn != null) {
670
ms = MediaSize.getMediaSizeForName(msn);
671
}
672
673
if (ms != null) {
674
msList.add(ms);
675
dmPaperNameList.add(winMediaNames[i]);
676
} else {
677
Win32MediaSize wms = Win32MediaSize.findMediaName(winMediaNames[i]);
678
if (wms == null) {
679
wms = new Win32MediaSize(winMediaNames[i], media[i]);
680
}
681
try {
682
ms = new MediaSize(wid, ht, MediaSize.MM, wms);
683
msList.add(ms);
684
dmPaperNameList.add(winMediaNames[i]);
685
} catch(IllegalArgumentException e) {
686
if (nMedia == media.length) {
687
Integer remObj = Integer.valueOf(media[i]);
688
idList.remove(idList.indexOf(remObj));
689
}
690
}
691
}
692
}
693
694
MediaSize[] arr2 = new MediaSize[msList.size()];
695
msList.toArray(arr2);
696
697
return arr2;
698
}
699
700
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
701
if (getJobStatus(printer, 2) != 1) {
702
return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
703
}
704
else {
705
return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
706
}
707
}
708
709
private PrinterState getPrinterState() {
710
if (isInvalid) {
711
return PrinterState.STOPPED;
712
} else {
713
return null;
714
}
715
}
716
717
private PrinterStateReasons getPrinterStateReasons() {
718
if (isInvalid) {
719
PrinterStateReasons psr = new PrinterStateReasons();
720
psr.put(PrinterStateReason.SHUTDOWN, Severity.ERROR);
721
return psr;
722
} else {
723
return null;
724
}
725
}
726
727
private QueuedJobCount getQueuedJobCount() {
728
729
int count = getJobStatus(printer, 1);
730
if (count != -1) {
731
return new QueuedJobCount(count);
732
}
733
else {
734
return new QueuedJobCount(0);
735
}
736
}
737
738
private boolean isSupportedCopies(Copies copies) {
739
synchronized (this) {
740
if (gotCopies == false) {
741
nCopies = getCopiesSupported(printer, getPort());
742
gotCopies = true;
743
}
744
}
745
int numCopies = copies.getValue();
746
return (numCopies > 0 && numCopies <= nCopies);
747
}
748
749
private boolean isSupportedMedia(MediaSizeName msn) {
750
751
initMedia();
752
753
if (mediaSizeNames != null) {
754
for (int i=0; i<mediaSizeNames.length; i++) {
755
if (msn.equals(mediaSizeNames[i])) {
756
return true;
757
}
758
}
759
}
760
return false;
761
}
762
763
private boolean isSupportedMediaPrintableArea(MediaPrintableArea mpa) {
764
765
getMediaPrintables(null);
766
int units = MediaPrintableArea.INCH;
767
768
if (mediaPrintables != null) {
769
for (int i=0; i<mediaPrintables.length; i++) {
770
if ((mpa.getX(units) >= mediaPrintables[i].getX(units)) &&
771
(mpa.getY(units) >= mediaPrintables[i].getY(units)) &&
772
(mpa.getX(units) + mpa.getWidth(units) <=
773
mediaPrintables[i].getX(units) +
774
mediaPrintables[i].getWidth(units)) &&
775
(mpa.getY(units) + mpa.getHeight(units) <=
776
mediaPrintables[i].getY(units) +
777
mediaPrintables[i].getHeight(units))) {
778
return true;
779
}
780
}
781
}
782
return false;
783
}
784
785
private boolean isSupportedMediaTray(MediaTray msn) {
786
MediaTray[] trays = getMediaTrays();
787
788
if (trays != null) {
789
for (int i=0; i<trays.length; i++) {
790
if (msn.equals(trays[i])) {
791
return true;
792
}
793
}
794
}
795
return false;
796
}
797
798
private int getPrinterCapabilities() {
799
if (prnCaps == 0) {
800
prnCaps = getCapabilities(printer, getPort());
801
}
802
return prnCaps;
803
}
804
805
private String getPort() {
806
if (port == null) {
807
port = getPrinterPort(printer);
808
}
809
return port;
810
}
811
812
/*
813
* NOTE: defaults indices must match those in WPrinterJob.cpp
814
*/
815
private int[] getDefaultPrinterSettings() {
816
if (defaultSettings == null) {
817
defaultSettings = getDefaultSettings(printer, getPort());
818
}
819
return defaultSettings;
820
}
821
822
private PrinterResolution[] getPrintResolutions() {
823
if (printRes == null) {
824
int[] prnRes = getAllResolutions(printer, getPort());
825
if (prnRes == null) {
826
printRes = new PrinterResolution[0];
827
} else {
828
int nRes = prnRes.length/2;
829
830
ArrayList<PrinterResolution> arrList = new ArrayList<>();
831
PrinterResolution pr;
832
833
for (int i=0; i<nRes; i++) {
834
try {
835
pr = new PrinterResolution(prnRes[i*2],
836
prnRes[i*2+1], PrinterResolution.DPI);
837
arrList.add(pr);
838
} catch (IllegalArgumentException e) {
839
}
840
}
841
842
printRes = arrList.toArray(new PrinterResolution[arrList.size()]);
843
}
844
}
845
return printRes;
846
}
847
848
private boolean isSupportedResolution(PrinterResolution res) {
849
PrinterResolution[] supportedRes = getPrintResolutions();
850
if (supportedRes != null) {
851
for (int i=0; i<supportedRes.length; i++) {
852
if (res.equals(supportedRes[i])) {
853
return true;
854
}
855
}
856
}
857
return false;
858
}
859
860
public DocPrintJob createPrintJob() {
861
@SuppressWarnings("removal")
862
SecurityManager security = System.getSecurityManager();
863
if (security != null) {
864
security.checkPrintJobAccess();
865
}
866
return new Win32PrintJob(this);
867
}
868
869
private PrintServiceAttributeSet getDynamicAttributes() {
870
PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
871
attrs.add(getPrinterIsAcceptingJobs());
872
attrs.add(getQueuedJobCount());
873
return attrs;
874
}
875
876
public PrintServiceAttributeSet getUpdatedAttributes() {
877
PrintServiceAttributeSet currSet = getDynamicAttributes();
878
if (lastSet == null) {
879
lastSet = currSet;
880
return AttributeSetUtilities.unmodifiableView(currSet);
881
} else {
882
PrintServiceAttributeSet updates =
883
new HashPrintServiceAttributeSet();
884
Attribute []attrs = currSet.toArray();
885
for (int i=0; i<attrs.length; i++) {
886
Attribute attr = attrs[i];
887
if (!lastSet.containsValue(attr)) {
888
updates.add(attr);
889
}
890
}
891
lastSet = currSet;
892
return AttributeSetUtilities.unmodifiableView(updates);
893
}
894
}
895
896
public void wakeNotifier() {
897
synchronized (this) {
898
if (notifier != null) {
899
notifier.wake();
900
}
901
}
902
}
903
904
public void addPrintServiceAttributeListener(PrintServiceAttributeListener
905
listener) {
906
synchronized (this) {
907
if (listener == null) {
908
return;
909
}
910
if (notifier == null) {
911
notifier = new ServiceNotifier(this);
912
}
913
notifier.addListener(listener);
914
}
915
}
916
917
public void removePrintServiceAttributeListener(
918
PrintServiceAttributeListener listener) {
919
synchronized (this) {
920
if (listener == null || notifier == null ) {
921
return;
922
}
923
notifier.removeListener(listener);
924
if (notifier.isEmpty()) {
925
notifier.stopNotifier();
926
notifier = null;
927
}
928
}
929
}
930
931
@SuppressWarnings("unchecked")
932
public <T extends PrintServiceAttribute> T
933
getAttribute(Class<T> category)
934
{
935
if (category == null) {
936
throw new NullPointerException("category");
937
}
938
if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {
939
throw new IllegalArgumentException("Not a PrintServiceAttribute");
940
}
941
if (category == ColorSupported.class) {
942
int caps = getPrinterCapabilities();
943
if ((caps & DEVCAP_COLOR) != 0) {
944
return (T)ColorSupported.SUPPORTED;
945
} else {
946
return (T)ColorSupported.NOT_SUPPORTED;
947
}
948
} else if (category == PrinterName.class) {
949
return (T)getPrinterName();
950
} else if (category == PrinterState.class) {
951
return (T)getPrinterState();
952
} else if (category == PrinterStateReasons.class) {
953
return (T)getPrinterStateReasons();
954
} else if (category == QueuedJobCount.class) {
955
return (T)getQueuedJobCount();
956
} else if (category == PrinterIsAcceptingJobs.class) {
957
return (T)getPrinterIsAcceptingJobs();
958
} else {
959
return null;
960
}
961
}
962
963
public PrintServiceAttributeSet getAttributes() {
964
965
PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
966
attrs.add(getPrinterName());
967
attrs.add(getPrinterIsAcceptingJobs());
968
PrinterState prnState = getPrinterState();
969
if (prnState != null) {
970
attrs.add(prnState);
971
}
972
PrinterStateReasons prnStateReasons = getPrinterStateReasons();
973
if (prnStateReasons != null) {
974
attrs.add(prnStateReasons);
975
}
976
attrs.add(getQueuedJobCount());
977
int caps = getPrinterCapabilities();
978
if ((caps & DEVCAP_COLOR) != 0) {
979
attrs.add(ColorSupported.SUPPORTED);
980
} else {
981
attrs.add(ColorSupported.NOT_SUPPORTED);
982
}
983
984
return AttributeSetUtilities.unmodifiableView(attrs);
985
}
986
987
public DocFlavor[] getSupportedDocFlavors() {
988
int len = supportedFlavors.length;
989
DocFlavor[] supportedDocFlavors;
990
int caps = getPrinterCapabilities();
991
// doc flavors supported
992
// if PostScript is supported
993
if ((caps & DEVCAP_POSTSCRIPT) != 0) {
994
supportedDocFlavors = new DocFlavor[len+3];
995
System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);
996
supportedDocFlavors[len] = DocFlavor.BYTE_ARRAY.POSTSCRIPT;
997
supportedDocFlavors[len+1] = DocFlavor.INPUT_STREAM.POSTSCRIPT;
998
supportedDocFlavors[len+2] = DocFlavor.URL.POSTSCRIPT;
999
} else {
1000
supportedDocFlavors = new DocFlavor[len];
1001
System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);
1002
}
1003
return supportedDocFlavors;
1004
}
1005
1006
public boolean isDocFlavorSupported(DocFlavor flavor) {
1007
/* To avoid a native query which may be time-consuming
1008
* do not invoke native unless postscript support is being queried.
1009
* Instead just check the ones we 'always' support
1010
*/
1011
DocFlavor[] supportedDocFlavors;
1012
if (isPostScriptFlavor(flavor)) {
1013
supportedDocFlavors = getSupportedDocFlavors();
1014
} else {
1015
supportedDocFlavors = supportedFlavors;
1016
}
1017
for (int f=0; f<supportedDocFlavors.length; f++) {
1018
if (flavor.equals(supportedDocFlavors[f])) {
1019
return true;
1020
}
1021
}
1022
return false;
1023
}
1024
1025
public Class<?>[] getSupportedAttributeCategories() {
1026
ArrayList<Class<?>> categList = new ArrayList<>(otherAttrCats.length+3);
1027
for (int i=0; i < otherAttrCats.length; i++) {
1028
categList.add(otherAttrCats[i]);
1029
}
1030
1031
int caps = getPrinterCapabilities();
1032
1033
if ((caps & DEVCAP_DUPLEX) != 0) {
1034
categList.add(Sides.class);
1035
}
1036
1037
if ((caps & DEVCAP_QUALITY) != 0) {
1038
int[] defaults = getDefaultPrinterSettings();
1039
// Added check: if supported, we should be able to get the default.
1040
if ((defaults[3] >= DMRES_HIGH) && (defaults[3] < 0)) {
1041
categList.add(PrintQuality.class);
1042
}
1043
}
1044
1045
PrinterResolution[] supportedRes = getPrintResolutions();
1046
if ((supportedRes!=null) && (supportedRes.length>0)) {
1047
categList.add(PrinterResolution.class);
1048
}
1049
1050
if (GraphicsEnvironment.isHeadless() == false) {
1051
categList.add(DialogOwner.class);
1052
categList.add(DialogTypeSelection.class);
1053
}
1054
return categList.toArray(new Class<?>[categList.size()]);
1055
}
1056
1057
public boolean
1058
isAttributeCategorySupported(Class<? extends Attribute> category)
1059
{
1060
1061
if (category == null) {
1062
throw new NullPointerException("null category");
1063
}
1064
1065
if (!(Attribute.class.isAssignableFrom(category))) {
1066
throw new IllegalArgumentException(category +
1067
" is not an Attribute");
1068
}
1069
1070
Class<?>[] classList = getSupportedAttributeCategories();
1071
for (int i = 0; i < classList.length; i++) {
1072
if (category.equals(classList[i])) {
1073
return true;
1074
}
1075
}
1076
1077
return false;
1078
}
1079
1080
public Object
1081
getDefaultAttributeValue(Class<? extends Attribute> category)
1082
{
1083
if (category == null) {
1084
throw new NullPointerException("null category");
1085
}
1086
if (!Attribute.class.isAssignableFrom(category)) {
1087
throw new IllegalArgumentException(category +
1088
" is not an Attribute");
1089
}
1090
1091
if (!isAttributeCategorySupported(category)) {
1092
return null;
1093
}
1094
1095
int[] defaults = getDefaultPrinterSettings();
1096
// indices must match those in WPrinterJob.cpp
1097
int defPaper = defaults[0];
1098
int defYRes = defaults[2];
1099
int defQuality = defaults[3];
1100
int defCopies = defaults[4];
1101
int defOrient = defaults[5];
1102
int defSides = defaults[6];
1103
int defCollate = defaults[7];
1104
int defColor = defaults[8];
1105
1106
if (category == Copies.class) {
1107
if (defCopies > 0) {
1108
return new Copies(defCopies);
1109
} else {
1110
return new Copies(1);
1111
}
1112
} else if (category == Chromaticity.class) {
1113
if (defColor == DMCOLOR_COLOR) {
1114
return Chromaticity.COLOR;
1115
} else {
1116
return Chromaticity.MONOCHROME;
1117
}
1118
} else if (category == JobName.class) {
1119
return new JobName("Java Printing", null);
1120
} else if (category == OrientationRequested.class) {
1121
if (defOrient == DMORIENT_LANDSCAPE) {
1122
return OrientationRequested.LANDSCAPE;
1123
} else {
1124
return OrientationRequested.PORTRAIT;
1125
}
1126
} else if (category == PageRanges.class) {
1127
return new PageRanges(1, Integer.MAX_VALUE);
1128
} else if (category == Media.class) {
1129
MediaSizeName msn = findWin32Media(defPaper);
1130
if (msn != null) {
1131
if (!isSupportedMedia(msn) && mediaSizeNames != null) {
1132
msn = mediaSizeNames[0];
1133
defPaper = findPaperID(msn);
1134
}
1135
return msn;
1136
} else {
1137
initMedia();
1138
if ((mediaSizeNames != null) && (mediaSizeNames.length > 0)) {
1139
// if 'mediaSizeNames' is not null, idList and mediaSizes
1140
// cannot be null but to be safe, add a check
1141
if ((idList != null) && (mediaSizes != null) &&
1142
(idList.size() == mediaSizes.length)) {
1143
Integer defIdObj = Integer.valueOf(defPaper);
1144
int index = idList.indexOf(defIdObj);
1145
if (index>=0 && index<mediaSizes.length) {
1146
return mediaSizes[index].getMediaSizeName();
1147
}
1148
}
1149
1150
return mediaSizeNames[0];
1151
}
1152
}
1153
} else if (category == MediaPrintableArea.class) {
1154
/* Verify defPaper */
1155
MediaSizeName msn = findWin32Media(defPaper);
1156
if (msn != null &&
1157
!isSupportedMedia(msn) && mediaSizeNames != null) {
1158
defPaper = findPaperID(mediaSizeNames[0]);
1159
}
1160
float[] prnArea = getMediaPrintableArea(printer, defPaper);
1161
if (prnArea != null) {
1162
MediaPrintableArea printableArea = null;
1163
try {
1164
printableArea = new MediaPrintableArea(prnArea[0],
1165
prnArea[1],
1166
prnArea[2],
1167
prnArea[3],
1168
MediaPrintableArea.INCH);
1169
} catch (IllegalArgumentException e) {
1170
}
1171
return printableArea;
1172
}
1173
return null;
1174
} else if (category == SunAlternateMedia.class) {
1175
return null;
1176
} else if (category == Destination.class) {
1177
try {
1178
return new Destination((new File("out.prn")).toURI());
1179
} catch (SecurityException se) {
1180
try {
1181
return new Destination(new URI("file:out.prn"));
1182
} catch (URISyntaxException e) {
1183
return null;
1184
}
1185
}
1186
} else if (category == Sides.class) {
1187
switch(defSides) {
1188
case DMDUP_VERTICAL :
1189
return Sides.TWO_SIDED_LONG_EDGE;
1190
case DMDUP_HORIZONTAL :
1191
return Sides.TWO_SIDED_SHORT_EDGE;
1192
default :
1193
return Sides.ONE_SIDED;
1194
}
1195
} else if (category == PrinterResolution.class) {
1196
int yRes = defYRes;
1197
int xRes = defQuality;
1198
if ((xRes < 0) || (yRes < 0)) {
1199
int res = (yRes > xRes) ? yRes : xRes;
1200
if (res > 0) {
1201
return new PrinterResolution(res, res, PrinterResolution.DPI);
1202
}
1203
}
1204
else {
1205
return new PrinterResolution(xRes, yRes, PrinterResolution.DPI);
1206
}
1207
} else if (category == ColorSupported.class) {
1208
int caps = getPrinterCapabilities();
1209
if ((caps & DEVCAP_COLOR) != 0) {
1210
return ColorSupported.SUPPORTED;
1211
} else {
1212
return ColorSupported.NOT_SUPPORTED;
1213
}
1214
} else if (category == PrintQuality.class) {
1215
if ((defQuality < 0) && (defQuality >= DMRES_HIGH)) {
1216
switch (defQuality) {
1217
case DMRES_HIGH:
1218
return PrintQuality.HIGH;
1219
case DMRES_MEDIUM:
1220
return PrintQuality.NORMAL;
1221
default:
1222
return PrintQuality.DRAFT;
1223
}
1224
}
1225
} else if (category == RequestingUserName.class) {
1226
String userName = "";
1227
try {
1228
userName = System.getProperty("user.name", "");
1229
} catch (SecurityException se) {
1230
}
1231
return new RequestingUserName(userName, null);
1232
} else if (category == SheetCollate.class) {
1233
if (defCollate == DMCOLLATE_TRUE) {
1234
return SheetCollate.COLLATED;
1235
} else {
1236
return SheetCollate.UNCOLLATED;
1237
}
1238
} else if (category == Fidelity.class) {
1239
return Fidelity.FIDELITY_FALSE;
1240
}
1241
return null;
1242
}
1243
1244
private boolean isPostScriptFlavor(DocFlavor flavor) {
1245
if (flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT) ||
1246
flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) ||
1247
flavor.equals(DocFlavor.URL.POSTSCRIPT)) {
1248
return true;
1249
}
1250
else {
1251
return false;
1252
}
1253
}
1254
1255
private boolean isPSDocAttr(Class<?> category) {
1256
if (category == OrientationRequested.class || category == Copies.class) {
1257
return true;
1258
}
1259
else {
1260
return false;
1261
}
1262
}
1263
1264
private boolean isAutoSense(DocFlavor flavor) {
1265
if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE) ||
1266
flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE) ||
1267
flavor.equals(DocFlavor.URL.AUTOSENSE)) {
1268
return true;
1269
}
1270
else {
1271
return false;
1272
}
1273
}
1274
1275
public Object
1276
getSupportedAttributeValues(Class<? extends Attribute> category,
1277
DocFlavor flavor,
1278
AttributeSet attributes)
1279
{
1280
if (category == null) {
1281
throw new NullPointerException("null category");
1282
}
1283
if (!Attribute.class.isAssignableFrom(category)) {
1284
throw new IllegalArgumentException(category +
1285
" does not implement Attribute");
1286
}
1287
if (flavor != null) {
1288
if (!isDocFlavorSupported(flavor)) {
1289
throw new IllegalArgumentException(flavor +
1290
" is an unsupported flavor");
1291
// if postscript & category is already specified within the
1292
// PostScript data we return null
1293
} else if (isAutoSense(flavor) ||(isPostScriptFlavor(flavor) &&
1294
(isPSDocAttr(category)))){
1295
return null;
1296
}
1297
}
1298
if (!isAttributeCategorySupported(category)) {
1299
return null;
1300
}
1301
1302
if (category == JobName.class) {
1303
return new JobName("Java Printing", null);
1304
} else if (category == RequestingUserName.class) {
1305
String userName = "";
1306
try {
1307
userName = System.getProperty("user.name", "");
1308
} catch (SecurityException se) {
1309
}
1310
return new RequestingUserName(userName, null);
1311
} else if (category == ColorSupported.class) {
1312
int caps = getPrinterCapabilities();
1313
if ((caps & DEVCAP_COLOR) != 0) {
1314
return ColorSupported.SUPPORTED;
1315
} else {
1316
return ColorSupported.NOT_SUPPORTED;
1317
}
1318
} else if (category == Chromaticity.class) {
1319
if (flavor == null ||
1320
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
1321
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
1322
flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
1323
flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
1324
flavor.equals(DocFlavor.URL.GIF) ||
1325
flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
1326
flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
1327
flavor.equals(DocFlavor.URL.JPEG) ||
1328
flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
1329
flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
1330
flavor.equals(DocFlavor.URL.PNG)) {
1331
int caps = getPrinterCapabilities();
1332
if ((caps & DEVCAP_COLOR) == 0) {
1333
Chromaticity []arr = new Chromaticity[1];
1334
arr[0] = Chromaticity.MONOCHROME;
1335
return (arr);
1336
} else {
1337
Chromaticity []arr = new Chromaticity[2];
1338
arr[0] = Chromaticity.MONOCHROME;
1339
arr[1] = Chromaticity.COLOR;
1340
return (arr);
1341
}
1342
} else {
1343
return null;
1344
}
1345
} else if (category == Destination.class) {
1346
try {
1347
return new Destination((new File("out.prn")).toURI());
1348
} catch (SecurityException se) {
1349
try {
1350
return new Destination(new URI("file:out.prn"));
1351
} catch (URISyntaxException e) {
1352
return null;
1353
}
1354
}
1355
} else if (category == OrientationRequested.class) {
1356
if (flavor == null ||
1357
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
1358
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
1359
flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
1360
flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
1361
flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
1362
flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
1363
flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
1364
flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
1365
flavor.equals(DocFlavor.URL.GIF) ||
1366
flavor.equals(DocFlavor.URL.JPEG) ||
1367
flavor.equals(DocFlavor.URL.PNG)) {
1368
OrientationRequested []arr = new OrientationRequested[3];
1369
arr[0] = OrientationRequested.PORTRAIT;
1370
arr[1] = OrientationRequested.LANDSCAPE;
1371
arr[2] = OrientationRequested.REVERSE_LANDSCAPE;
1372
return arr;
1373
} else {
1374
return null;
1375
}
1376
} else if ((category == Copies.class) ||
1377
(category == CopiesSupported.class)) {
1378
synchronized (this) {
1379
if (gotCopies == false) {
1380
nCopies = getCopiesSupported(printer, getPort());
1381
gotCopies = true;
1382
}
1383
}
1384
return new CopiesSupported(1, nCopies);
1385
} else if (category == Media.class) {
1386
1387
initMedia();
1388
1389
int len = (mediaSizeNames == null) ? 0 : mediaSizeNames.length;
1390
1391
MediaTray[] trays = getMediaTrays();
1392
1393
len += (trays == null) ? 0 : trays.length;
1394
1395
Media []arr = new Media[len];
1396
if (mediaSizeNames != null) {
1397
System.arraycopy(mediaSizeNames, 0, arr,
1398
0, mediaSizeNames.length);
1399
}
1400
if (trays != null) {
1401
System.arraycopy(trays, 0, arr,
1402
len - trays.length, trays.length);
1403
}
1404
return arr;
1405
} else if (category == MediaPrintableArea.class) {
1406
// if getting printable area for a specific media size
1407
Media mediaName = null;
1408
if ((attributes != null) &&
1409
((mediaName =
1410
(Media)attributes.get(Media.class)) != null)) {
1411
1412
if (!(mediaName instanceof MediaSizeName)) {
1413
// if an instance of MediaTray, fall thru returning
1414
// all MediaPrintableAreas
1415
mediaName = null;
1416
}
1417
}
1418
1419
MediaPrintableArea[] mpas =
1420
getMediaPrintables((MediaSizeName)mediaName);
1421
if (mpas != null) {
1422
MediaPrintableArea[] arr = new MediaPrintableArea[mpas.length];
1423
System.arraycopy(mpas, 0, arr, 0, mpas.length);
1424
return arr;
1425
} else {
1426
return null;
1427
}
1428
} else if (category == SunAlternateMedia.class) {
1429
return new SunAlternateMedia(
1430
(Media)getDefaultAttributeValue(Media.class));
1431
} else if (category == PageRanges.class) {
1432
if (flavor == null ||
1433
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
1434
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
1435
PageRanges []arr = new PageRanges[1];
1436
arr[0] = new PageRanges(1, Integer.MAX_VALUE);
1437
return arr;
1438
} else {
1439
return null;
1440
}
1441
} else if (category == PrinterResolution.class) {
1442
PrinterResolution[] supportedRes = getPrintResolutions();
1443
if (supportedRes == null) {
1444
return null;
1445
}
1446
PrinterResolution []arr =
1447
new PrinterResolution[supportedRes.length];
1448
System.arraycopy(supportedRes, 0, arr, 0, supportedRes.length);
1449
return arr;
1450
} else if (category == Sides.class) {
1451
if (flavor == null ||
1452
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
1453
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
1454
Sides []arr = new Sides[3];
1455
arr[0] = Sides.ONE_SIDED;
1456
arr[1] = Sides.TWO_SIDED_LONG_EDGE;
1457
arr[2] = Sides.TWO_SIDED_SHORT_EDGE;
1458
return arr;
1459
} else {
1460
return null;
1461
}
1462
} else if (category == PrintQuality.class) {
1463
PrintQuality []arr = new PrintQuality[3];
1464
arr[0] = PrintQuality.DRAFT;
1465
arr[1] = PrintQuality.HIGH;
1466
arr[2] = PrintQuality.NORMAL;
1467
return arr;
1468
} else if (category == SheetCollate.class) {
1469
if (flavor == null ||
1470
(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
1471
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
1472
SheetCollate []arr = new SheetCollate[2];
1473
arr[0] = SheetCollate.COLLATED;
1474
arr[1] = SheetCollate.UNCOLLATED;
1475
return arr;
1476
} else {
1477
return null;
1478
}
1479
} else if (category == Fidelity.class) {
1480
Fidelity []arr = new Fidelity[2];
1481
arr[0] = Fidelity.FIDELITY_FALSE;
1482
arr[1] = Fidelity.FIDELITY_TRUE;
1483
return arr;
1484
} else {
1485
return null;
1486
}
1487
}
1488
1489
public boolean isAttributeValueSupported(Attribute attr,
1490
DocFlavor flavor,
1491
AttributeSet attributes) {
1492
1493
if (attr == null) {
1494
throw new NullPointerException("null attribute");
1495
}
1496
Class<? extends Attribute> category = attr.getCategory();
1497
if (flavor != null) {
1498
if (!isDocFlavorSupported(flavor)) {
1499
throw new IllegalArgumentException(flavor +
1500
" is an unsupported flavor");
1501
// if postscript & category is already specified within the PostScript data
1502
// we return false
1503
} else if (isAutoSense(flavor) || (isPostScriptFlavor(flavor) &&
1504
(isPSDocAttr(category)))) {
1505
return false;
1506
}
1507
}
1508
1509
if (!isAttributeCategorySupported(category)) {
1510
return false;
1511
}
1512
else if (category == Chromaticity.class) {
1513
if ((flavor == null) ||
1514
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
1515
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
1516
flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
1517
flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
1518
flavor.equals(DocFlavor.URL.GIF) ||
1519
flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
1520
flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
1521
flavor.equals(DocFlavor.URL.JPEG) ||
1522
flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
1523
flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
1524
flavor.equals(DocFlavor.URL.PNG)) {
1525
int caps = getPrinterCapabilities();
1526
if ((caps & DEVCAP_COLOR) != 0) {
1527
return true;
1528
} else {
1529
return attr == Chromaticity.MONOCHROME;
1530
}
1531
} else {
1532
return false;
1533
}
1534
} else if (category == Copies.class) {
1535
return isSupportedCopies((Copies)attr);
1536
1537
} else if (category == Destination.class) {
1538
URI uri = ((Destination)attr).getURI();
1539
if ("file".equals(uri.getScheme()) &&
1540
!uri.getSchemeSpecificPart().isEmpty()) {
1541
return true;
1542
} else {
1543
return false;
1544
}
1545
1546
} else if (category == Media.class) {
1547
if (attr instanceof MediaSizeName) {
1548
return isSupportedMedia((MediaSizeName)attr);
1549
}
1550
if (attr instanceof MediaTray) {
1551
return isSupportedMediaTray((MediaTray)attr);
1552
}
1553
1554
} else if (category == MediaPrintableArea.class) {
1555
return isSupportedMediaPrintableArea((MediaPrintableArea)attr);
1556
1557
} else if (category == SunAlternateMedia.class) {
1558
Media media = ((SunAlternateMedia)attr).getMedia();
1559
return isAttributeValueSupported(media, flavor, attributes);
1560
1561
} else if (category == PageRanges.class ||
1562
category == SheetCollate.class ||
1563
category == Sides.class) {
1564
if (flavor != null &&
1565
!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
1566
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
1567
return false;
1568
}
1569
} else if (category == PrinterResolution.class) {
1570
if (attr instanceof PrinterResolution) {
1571
return isSupportedResolution((PrinterResolution)attr);
1572
}
1573
} else if (category == OrientationRequested.class) {
1574
if (attr == OrientationRequested.REVERSE_PORTRAIT ||
1575
(flavor != null) &&
1576
!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
1577
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
1578
flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
1579
flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
1580
flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
1581
flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
1582
flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
1583
flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
1584
flavor.equals(DocFlavor.URL.GIF) ||
1585
flavor.equals(DocFlavor.URL.JPEG) ||
1586
flavor.equals(DocFlavor.URL.PNG))) {
1587
return false;
1588
}
1589
1590
} else if (category == ColorSupported.class) {
1591
int caps = getPrinterCapabilities();
1592
boolean isColorSup = ((caps & DEVCAP_COLOR) != 0);
1593
if ((!isColorSup && (attr == ColorSupported.SUPPORTED)) ||
1594
(isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) {
1595
return false;
1596
}
1597
} else if (category == DialogTypeSelection.class) {
1598
return true; // isHeadless was checked by category support
1599
} else if (category == DialogOwner.class) {
1600
DialogOwner owner = (DialogOwner)attr;
1601
DialogTypeSelection dts = (attributes == null) ? null :
1602
(DialogTypeSelection)attributes.get(DialogTypeSelection.class);
1603
if (dts == DialogTypeSelection.NATIVE) {
1604
return DialogOwnerAccessor.getID(owner) != 0;
1605
} else {
1606
if (DialogOwnerAccessor.getID(owner) != 0) {
1607
return false;
1608
} else if (owner.getOwner() != null) {
1609
return true;
1610
} else {
1611
return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
1612
}
1613
}
1614
}
1615
return true;
1616
}
1617
1618
public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
1619
AttributeSet attributes) {
1620
1621
if (flavor != null && !isDocFlavorSupported(flavor)) {
1622
throw new IllegalArgumentException("flavor " + flavor +
1623
" is not supported");
1624
}
1625
1626
if (attributes == null) {
1627
return null;
1628
}
1629
1630
Attribute attr;
1631
AttributeSet unsupp = new HashAttributeSet();
1632
Attribute []attrs = attributes.toArray();
1633
for (int i=0; i<attrs.length; i++) {
1634
try {
1635
attr = attrs[i];
1636
if (!isAttributeCategorySupported(attr.getCategory())) {
1637
unsupp.add(attr);
1638
}
1639
else if (!isAttributeValueSupported(attr, flavor, attributes)) {
1640
unsupp.add(attr);
1641
}
1642
} catch (ClassCastException e) {
1643
}
1644
}
1645
if (unsupp.isEmpty()) {
1646
return null;
1647
} else {
1648
return unsupp;
1649
}
1650
}
1651
1652
private Win32DocumentPropertiesUI docPropertiesUI = null;
1653
1654
private static class Win32DocumentPropertiesUI
1655
extends DocumentPropertiesUI {
1656
1657
Win32PrintService service;
1658
1659
private Win32DocumentPropertiesUI(Win32PrintService s) {
1660
service = s;
1661
}
1662
1663
public PrintRequestAttributeSet
1664
showDocumentProperties(PrinterJob job,
1665
Window owner,
1666
PrintService service,
1667
PrintRequestAttributeSet aset) {
1668
1669
if (!(job instanceof WPrinterJob)) {
1670
return null;
1671
}
1672
WPrinterJob wJob = (WPrinterJob)job;
1673
return wJob.showDocumentProperties(owner, service, aset);
1674
}
1675
}
1676
1677
private synchronized DocumentPropertiesUI getDocumentPropertiesUI() {
1678
return new Win32DocumentPropertiesUI(this);
1679
}
1680
1681
private static class Win32ServiceUIFactory extends ServiceUIFactory {
1682
1683
Win32PrintService service;
1684
1685
Win32ServiceUIFactory(Win32PrintService s) {
1686
service = s;
1687
}
1688
1689
public Object getUI(int role, String ui) {
1690
if (role <= ServiceUIFactory.MAIN_UIROLE) {
1691
return null;
1692
}
1693
if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE &&
1694
DocumentPropertiesUI.DOCPROPERTIESCLASSNAME.equals(ui))
1695
{
1696
return service.getDocumentPropertiesUI();
1697
}
1698
throw new IllegalArgumentException("Unsupported role");
1699
}
1700
1701
public String[] getUIClassNamesForRole(int role) {
1702
1703
if (role <= ServiceUIFactory.MAIN_UIROLE) {
1704
return null;
1705
}
1706
if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE) {
1707
String[] names = new String[0];
1708
names[0] = DocumentPropertiesUI.DOCPROPERTIESCLASSNAME;
1709
return names;
1710
}
1711
throw new IllegalArgumentException("Unsupported role");
1712
}
1713
}
1714
1715
private Win32ServiceUIFactory uiFactory = null;
1716
1717
public synchronized ServiceUIFactory getServiceUIFactory() {
1718
if (uiFactory == null) {
1719
uiFactory = new Win32ServiceUIFactory(this);
1720
}
1721
return uiFactory;
1722
}
1723
1724
public String toString() {
1725
return "Win32 Printer : " + getName();
1726
}
1727
1728
public boolean equals(Object obj) {
1729
return (obj == this ||
1730
(obj instanceof Win32PrintService &&
1731
((Win32PrintService)obj).getName().equals(getName())));
1732
}
1733
1734
public int hashCode() {
1735
return this.getClass().hashCode()+getName().hashCode();
1736
}
1737
1738
public boolean usesClass(Class<?> c) {
1739
return (c == sun.awt.windows.WPrinterJob.class);
1740
}
1741
1742
private native int[] getAllMediaIDs(String printerName, String port);
1743
private native int[] getAllMediaSizes(String printerName, String port);
1744
private native int[] getAllMediaTrays(String printerName, String port);
1745
private native float[] getMediaPrintableArea(String printerName,
1746
int paperSize);
1747
private native String[] getAllMediaNames(String printerName, String port);
1748
private native String[] getAllMediaTrayNames(String printerName, String port);
1749
private native int getCopiesSupported(String printerName, String port);
1750
private native int[] getAllResolutions(String printerName, String port);
1751
private native int getCapabilities(String printerName, String port);
1752
1753
private native int[] getDefaultSettings(String printerName, String port);
1754
private native int getJobStatus(String printerName, int type);
1755
private native String getPrinterPort(String printerName);
1756
}
1757
1758
@SuppressWarnings("serial") // JDK implementation class
1759
class Win32MediaSize extends MediaSizeName {
1760
private static ArrayList<String> winStringTable = new ArrayList<>();
1761
private static ArrayList<Win32MediaSize> winEnumTable = new ArrayList<>();
1762
private static MediaSize[] predefMedia;
1763
1764
private int dmPaperID; // driver ID for this paper.
1765
1766
private Win32MediaSize(int x) {
1767
super(x);
1768
1769
}
1770
1771
private static synchronized int nextValue(String name) {
1772
winStringTable.add(name);
1773
return (winStringTable.size()-1);
1774
}
1775
1776
public static synchronized Win32MediaSize findMediaName(String name) {
1777
int nameIndex = winStringTable.indexOf(name);
1778
if (nameIndex != -1) {
1779
return winEnumTable.get(nameIndex);
1780
}
1781
return null;
1782
}
1783
1784
public static MediaSize[] getPredefMedia() {
1785
return predefMedia;
1786
}
1787
1788
public Win32MediaSize(String name, int dmPaper) {
1789
super(nextValue(name));
1790
dmPaperID = dmPaper;
1791
winEnumTable.add(this);
1792
}
1793
1794
private MediaSizeName[] getSuperEnumTable() {
1795
return (MediaSizeName[])super.getEnumValueTable();
1796
}
1797
1798
static {
1799
/* initialize predefMedia */
1800
{
1801
Win32MediaSize winMedia = new Win32MediaSize(-1);
1802
1803
// cannot call getSuperEnumTable directly because of static context
1804
MediaSizeName[] enumMedia = winMedia.getSuperEnumTable();
1805
if (enumMedia != null) {
1806
predefMedia = new MediaSize[enumMedia.length];
1807
1808
for (int i=0; i<enumMedia.length; i++) {
1809
predefMedia[i] = MediaSize.getMediaSizeForName(enumMedia[i]);
1810
}
1811
}
1812
}
1813
}
1814
1815
int getDMPaper() {
1816
return dmPaperID;
1817
}
1818
1819
protected String[] getStringTable() {
1820
String[] nameTable = new String[winStringTable.size()];
1821
return winStringTable.toArray(nameTable);
1822
}
1823
1824
protected EnumSyntax[] getEnumValueTable() {
1825
MediaSizeName[] enumTable = new MediaSizeName[winEnumTable.size()];
1826
return winEnumTable.toArray(enumTable);
1827
}
1828
1829
}
1830
1831