2
Copyright (C) 2009 Volker Berlin (i-net software)
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
26
import ikvm.awt.IkvmToolkit;
28
import java.awt.Toolkit;
30
import java.io.BufferedReader;
31
import java.io.InputStream;
32
import java.io.InputStreamReader;
33
import java.io.IOException;
34
import java.util.ArrayList;
35
import java.security.AccessController;
36
import java.security.PrivilegedActionException;
37
import java.security.PrivilegedExceptionAction;
38
import javax.print.DocFlavor;
39
import javax.print.MultiDocPrintService;
40
import javax.print.PrintService;
41
import javax.print.PrintServiceLookup;
42
import javax.print.attribute.Attribute;
43
import javax.print.attribute.AttributeSet;
44
import javax.print.attribute.HashPrintRequestAttributeSet;
45
import javax.print.attribute.HashPrintServiceAttributeSet;
46
import javax.print.attribute.PrintRequestAttribute;
47
import javax.print.attribute.PrintRequestAttributeSet;
48
import javax.print.attribute.PrintServiceAttribute;
49
import javax.print.attribute.PrintServiceAttributeSet;
50
import javax.print.attribute.standard.PrinterName;
52
public class Win32PrintServiceLookup extends PrintServiceLookup {
54
private final PrintPeer peer = IkvmToolkit.DefaultToolkit.get().getPrintPeer();
56
private String defaultPrinter;
57
private PrintService defaultPrintService;
58
private String[] printers; /* excludes the default printer */
59
private PrintService[] printServices; /* includes the default printer */
62
/* Want the PrintService which is default print service to have
63
* equality of reference with the equivalent in list of print services
64
* This isn't required by the API and there's a risk doing this will
65
* lead people to assume its guaranteed.
67
public synchronized PrintService[] getPrintServices() {
68
SecurityManager security = System.getSecurityManager();
69
if (security != null) {
70
security.checkPrintJobAccess();
72
if (printServices == null) {
78
private synchronized void refreshServices() {
79
printers = peer.getAllPrinterNames();
80
if (printers == null) {
81
// In Windows it is safe to assume no default if printers == null so we
82
// don't get the default.
83
printServices = new PrintService[0];
87
PrintService[] newServices = new PrintService[printers.length];
88
PrintService defService = getDefaultPrintService();
89
for (int p = 0; p < printers.length; p++) {
90
if (defService != null &&
91
printers[p].equals(defService.getName())) {
92
newServices[p] = defService;
94
if (printServices == null) {
95
newServices[p] = new Win32PrintService(printers[p], peer);
98
for (j = 0; j < printServices.length; j++) {
99
if ((printServices[j]!= null) &&
100
(printers[p].equals(printServices[j].getName()))) {
101
newServices[p] = printServices[j];
102
printServices[j] = null;
106
if (j == printServices.length) {
107
newServices[p] = new Win32PrintService(printers[p], peer);
113
printServices = newServices;
117
public synchronized PrintService getPrintServiceByName(String name) {
119
if (name == null || name.equals("")) {
122
/* getPrintServices() is now very fast. */
123
PrintService[] printServices = getPrintServices();
124
for (int i=0; i<printServices.length; i++) {
125
if (printServices[i].getName().equals(name)) {
126
return printServices[i];
133
boolean matchingService(PrintService service,
134
PrintServiceAttributeSet serviceSet) {
135
if (serviceSet != null) {
136
Attribute [] attrs = serviceSet.toArray();
137
Attribute serviceAttr;
138
for (int i=0; i<attrs.length; i++) {
140
= service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
141
if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
149
public PrintService[] getPrintServices(DocFlavor flavor,
150
AttributeSet attributes) {
152
SecurityManager security = System.getSecurityManager();
153
if (security != null) {
154
security.checkPrintJobAccess();
156
PrintRequestAttributeSet requestSet = null;
157
PrintServiceAttributeSet serviceSet = null;
159
if (attributes != null && !attributes.isEmpty()) {
161
requestSet = new HashPrintRequestAttributeSet();
162
serviceSet = new HashPrintServiceAttributeSet();
164
Attribute[] attrs = attributes.toArray();
165
for (int i=0; i<attrs.length; i++) {
166
if (attrs[i] instanceof PrintRequestAttribute) {
167
requestSet.add(attrs[i]);
168
} else if (attrs[i] instanceof PrintServiceAttribute) {
169
serviceSet.add(attrs[i]);
175
* Special case: If client is asking for a particular printer
176
* (by name) then we can save time by getting just that service
177
* to check against the rest of the specified attributes.
179
PrintService[] services = null;
180
if (serviceSet != null && serviceSet.get(PrinterName.class) != null) {
181
PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
182
PrintService service = getPrintServiceByName(name.getValue());
183
if (service == null || !matchingService(service, serviceSet)) {
184
services = new PrintService[0];
186
services = new PrintService[1];
187
services[0] = service;
190
services = getPrintServices();
193
if (services.length == 0) {
196
ArrayList matchingServices = new ArrayList();
197
for (int i=0; i<services.length; i++) {
200
getUnsupportedAttributes(flavor, requestSet) == null) {
201
matchingServices.add(services[i]);
203
} catch (IllegalArgumentException e) {
206
services = new PrintService[matchingServices.size()];
207
return (PrintService[])matchingServices.toArray(services);
212
* return empty array as don't support multi docs
214
public MultiDocPrintService[]
215
getMultiDocPrintServices(DocFlavor[] flavors,
216
AttributeSet attributes) {
217
SecurityManager security = System.getSecurityManager();
218
if (security != null) {
219
security.checkPrintJobAccess();
221
return new MultiDocPrintService[0];
225
public synchronized PrintService getDefaultPrintService() {
226
SecurityManager security = System.getSecurityManager();
227
if (security != null) {
228
security.checkPrintJobAccess();
232
// Windows does not have notification for a change in default
233
// so we always get the latest.
234
defaultPrinter = peer.getDefaultPrinterName();
235
if (defaultPrinter == null) {
239
if ((defaultPrintService != null) &&
240
defaultPrintService.getName().equals(defaultPrinter)) {
242
return defaultPrintService;
245
// Not the same as default so proceed to get new PrintService.
247
// clear defaultPrintService
248
defaultPrintService = null;
250
if (printServices != null) {
251
for (int j=0; j<printServices.length; j++) {
252
if (defaultPrinter.equals(printServices[j].getName())) {
253
defaultPrintService = printServices[j];
259
if (defaultPrintService == null) {
260
defaultPrintService = new Win32PrintService(defaultPrinter, peer);
262
return defaultPrintService;