001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Aleksei V. Ivaschenko
019: * @version $Revision: 1.4 $
020: */package org.apache.harmony.x.print;
021:
022: import java.io.File;
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.net.URL;
026: import java.util.ArrayList;
027: import java.util.Arrays;
028: import java.util.HashMap;
029: import java.util.Locale;
030: import javax.print.Doc;
031: import javax.print.DocFlavor;
032: import javax.print.PrintException;
033: import javax.print.attribute.Attribute;
034: import javax.print.attribute.AttributeSet;
035: import javax.print.attribute.HashPrintServiceAttributeSet;
036: import javax.print.attribute.PrintRequestAttributeSet;
037: import javax.print.attribute.PrintServiceAttributeSet;
038: import javax.print.attribute.standard.Chromaticity;
039: import javax.print.attribute.standard.ColorSupported;
040: import javax.print.attribute.standard.Copies;
041: import javax.print.attribute.standard.CopiesSupported;
042: import javax.print.attribute.standard.Destination;
043: import javax.print.attribute.standard.JobName;
044: import javax.print.attribute.standard.Media;
045: import javax.print.attribute.standard.MediaSize;
046: import javax.print.attribute.standard.MediaSizeName;
047: import javax.print.attribute.standard.OrientationRequested;
048: import javax.print.attribute.standard.PagesPerMinute;
049: import javax.print.attribute.standard.PagesPerMinuteColor;
050: import javax.print.attribute.standard.PrinterIsAcceptingJobs;
051: import javax.print.attribute.standard.PrinterLocation;
052: import javax.print.attribute.standard.PrinterName;
053: import javax.print.attribute.standard.PrinterResolution;
054: import javax.print.attribute.standard.QueuedJobCount;
055: import javax.print.attribute.standard.RequestingUserName;
056: import javax.print.attribute.standard.SheetCollate;
057: import javax.print.attribute.standard.Sides;
058:
059: import org.apache.harmony.x.print.PrintClient;
060:
061: /*
062: * GDIClient is a print client based on windows GDI inteface.
063: * See description of PrintClient interface for more information.
064: */
065: class GDIClient implements PrintClient {
066:
067: private String serviceName = null;
068: private boolean isPrinting = false;
069:
070: private static final int MAX_BUFFER_SIZE = 10240;
071:
072: private static final int ATTRIBUTES_ARRAY_SIZE = 8;
073: private static final int COPIES_INDEX = 0;
074: private static final int SIDES_INDEX = 1;
075: private static final int PAPER_ID_INDEX = 2;
076: private static final int COLLATE_INDEX = 3;
077: private static final int CHROMATICITY_INDEX = 4;
078: private static final int ORIENTATION_INDEX = 5;
079: private static final int XRESOLUTION_INDEX = 6;
080: private static final int YRESOLUTION_INDEX = 7;
081:
082: private static final int NOT_STANDARD_MEDIA = 1000;
083: private HashMap medias = new HashMap();
084:
085: GDIClient(String serviceName) {
086: this .serviceName = serviceName;
087: }
088:
089: /*
090: * @see org.apache.harmony.x.print.PrintClient#getSupportedDocFlavors()
091: */
092: public DocFlavor[] getSupportedDocFlavors() {
093: if (checkPostScript(serviceName)) {
094: return new DocFlavor[] {
095: new DocFlavor.INPUT_STREAM("INTERNAL/postscript"),
096: DocFlavor.INPUT_STREAM.POSTSCRIPT,
097: DocFlavor.BYTE_ARRAY.POSTSCRIPT,
098: DocFlavor.URL.POSTSCRIPT,
099: DocFlavor.INPUT_STREAM.AUTOSENSE,
100: DocFlavor.BYTE_ARRAY.AUTOSENSE,
101: DocFlavor.URL.AUTOSENSE };
102: } else {
103: return new DocFlavor[] {
104: new DocFlavor.INPUT_STREAM("INTERNAL/postscript"),
105: DocFlavor.INPUT_STREAM.AUTOSENSE,
106: DocFlavor.BYTE_ARRAY.AUTOSENSE,
107: DocFlavor.URL.AUTOSENSE };
108: }
109: }
110:
111: /*
112: * @see org.apache.harmony.x.print.PrintClient#getAttributes()
113: */
114: public PrintServiceAttributeSet getAttributes() {
115: PrintServiceAttributeSet attributes = new HashPrintServiceAttributeSet();
116: attributes
117: .add(new PrinterName(serviceName, Locale.getDefault()));
118: if (getColorSupported(serviceName)) {
119: attributes.add(ColorSupported.SUPPORTED);
120: int colorPPM = getPagesPerMinuteColor(serviceName);
121: if (colorPPM > 0) {
122: attributes.add(new PagesPerMinuteColor(colorPPM));
123: }
124: } else {
125: attributes.add(ColorSupported.NOT_SUPPORTED);
126: }
127:
128: int pagesPerMinute = getPagesPerMinute(serviceName);
129: if (pagesPerMinute > 0) {
130: attributes.add(new PagesPerMinute(pagesPerMinute));
131: }
132:
133: String printerLocation = getPrinterLocation(serviceName);
134: if (printerLocation != null) {
135: attributes.add(new PrinterLocation(printerLocation, Locale
136: .getDefault()));
137: }
138:
139: int acceptingJobs = getPrinterIsAcceptingJobs(serviceName);
140: if (acceptingJobs == 0) {
141: attributes.add(PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS);
142: } else if (acceptingJobs == 1) {
143: attributes.add(PrinterIsAcceptingJobs.ACCEPTING_JOBS);
144: }
145:
146: int jobCount = getQueuedJobCount(serviceName);
147: if (jobCount >= 0) {
148: attributes.add(new QueuedJobCount(jobCount));
149: }
150: return attributes;
151: }
152:
153: /*
154: * @see org.apache.harmony.x.print.PrintClient#getSupportedAttributeCategories()
155: */
156: public Class[] getSupportedAttributeCategories() {
157: ArrayList supportedCategories = new ArrayList();
158: if (getCopiesSupported(serviceName) >= 1) {
159: supportedCategories.add(Copies.class);
160: }
161: if (getSidesSupported(serviceName)) {
162: supportedCategories.add(Sides.class);
163: }
164: if (getSupportedMediaSizeNames() != null) {
165: supportedCategories.add(Media.class);
166: }
167: if (getResolutionsSupported(serviceName) != null) {
168: supportedCategories.add(PrinterResolution.class);
169: }
170: if (getOrientationSupported(serviceName)) {
171: supportedCategories.add(OrientationRequested.class);
172: }
173: if (getCollateSupported(serviceName)) {
174: supportedCategories.add(SheetCollate.class);
175: }
176: supportedCategories.add(Chromaticity.class);
177: supportedCategories.add(JobName.class);
178: supportedCategories.add(RequestingUserName.class);
179: supportedCategories.add(Destination.class);
180:
181: Class[] categories = new Class[supportedCategories.size()];
182: supportedCategories.toArray(categories);
183: return categories;
184: }
185:
186: /*
187: * @see org.apache.harmony.x.print.PrintClient#getDefaultAttributeValue(
188: * java.lang.Class)
189: */
190: public Object getDefaultAttributeValue(Class category) {
191: if (category.equals(JobName.class)) {
192: return new JobName("Java GDI client print job", Locale.US);
193: } else if (category.equals(RequestingUserName.class)) {
194: return new RequestingUserName(System
195: .getProperty("user.name"), Locale.US);
196: } else if (category.equals(Destination.class)) {
197: File file = new File(System.getProperty("user.dir")
198: + File.separator + "output.prn");
199: return new Destination(file.toURI());
200: } else if (category.equals(SheetCollate.class)) {
201: return SheetCollate.COLLATED;
202: } else if (category.equals(Copies.class)) {
203: return new Copies(1);
204: }
205: return null;
206: }
207:
208: /*
209: * @see org.apache.harmony.x.print.PrintClient#isAttributeValueSupported(
210: * javax.print.attribute.Attribute, javax.print.DocFlavor,
211: * javax.print.attribute.AttributeSet)
212: */
213: public boolean isAttributeValueSupported(Attribute attribute,
214: DocFlavor flavor, AttributeSet attributes) {
215: Class category = attribute.getCategory();
216: if (category.equals(JobName.class)
217: || category.equals(RequestingUserName.class)) {
218: return true;
219: } else if (category.equals(Destination.class)) {
220: Destination destination = (Destination) attribute;
221: if (destination.getURI().getScheme().equals("file")) {
222: return true;
223: }
224: }
225: if (flavor != null) {
226: if (flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE)
227: || flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE)
228: || flavor.equals(DocFlavor.URL.AUTOSENSE)
229: || flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT)
230: || flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT)
231: || flavor.equals(DocFlavor.URL.POSTSCRIPT)) {
232: return false;
233: }
234: }
235: if (category.equals(Copies.class)) {
236: CopiesSupported copies = (CopiesSupported) getSupportedAttributeValues(
237: category, flavor, attributes);
238: int value = ((Copies) attribute).getValue();
239: if (copies != null && copies.contains(value)) {
240: return true;
241: }
242: } else if (category.equals(Sides.class)) {
243: Sides[] sides = (Sides[]) getSupportedAttributeValues(
244: category, flavor, attributes);
245: if (sides != null) {
246: for (int i = 0; i < sides.length; i++) {
247: if (sides[i].equals(attribute)) {
248: return true;
249: }
250: }
251: }
252: } else if (category.equals(Media.class)) {
253: Media[] medias = (Media[]) getSupportedAttributeValues(
254: category, flavor, attributes);
255: if (medias != null) {
256: for (int i = 0; i < medias.length; i++) {
257: if (medias[i].equals(attribute)) {
258: return true;
259: }
260: }
261: }
262: } else if (category.equals(Chromaticity.class)) {
263: if (attribute.equals(Chromaticity.COLOR)) {
264: if (!getColorSupported(serviceName)) {
265: return false;
266: }
267: }
268: return true;
269: } else if (category.equals(OrientationRequested.class)) {
270: if (getOrientationSupported(serviceName)) {
271: if (attribute.equals(OrientationRequested.PORTRAIT)
272: || attribute
273: .equals(OrientationRequested.LANDSCAPE))
274: return true;
275: }
276: } else if (category.equals(PrinterResolution.class)) {
277: int[] resolutions = getResolutionsSupported(serviceName);
278: if (resolutions != null && resolutions.length > 1) {
279: PrinterResolution resolution = (PrinterResolution) attribute;
280: int xres = resolution
281: .getCrossFeedResolution(PrinterResolution.DPI);
282: int yres = resolution
283: .getFeedResolution(PrinterResolution.DPI);
284: for (int i = 0; i < resolutions.length / 2; i++) {
285: if (xres == resolutions[i * 2]
286: && yres == resolutions[i * 2 + 1]) {
287: return true;
288: }
289: }
290: }
291: } else if (category.equals(SheetCollate.class)) {
292: if (getCollateSupported(serviceName)) {
293: if (attribute == SheetCollate.COLLATED
294: || attribute == SheetCollate.UNCOLLATED) {
295: return true;
296: }
297: }
298: }
299: return false;
300: }
301:
302: /*
303: * @see org.apache.harmony.x.print.PrintClient#getSupportedAttributeValues(
304: * java.lang.Class, javax.print.DocFlavor,
305: * javax.print.attribute.AttributeSet)
306: */
307: public Object getSupportedAttributeValues(Class category,
308: DocFlavor flavor, AttributeSet attributes) {
309: if (flavor != null
310: && (flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE)
311: || flavor
312: .equals(DocFlavor.BYTE_ARRAY.AUTOSENSE)
313: || flavor.equals(DocFlavor.URL.AUTOSENSE)
314: || flavor
315: .equals(DocFlavor.INPUT_STREAM.POSTSCRIPT)
316: || flavor
317: .equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT) || flavor
318: .equals(DocFlavor.URL.POSTSCRIPT))) {
319: return null;
320: }
321: if (category.equals(Copies.class)) {
322: int copies = getCopiesSupported(serviceName);
323: if (copies == 1) {
324: return new CopiesSupported(1);
325: } else if (copies > 1) {
326: return new CopiesSupported(1, copies);
327: }
328: } else if (category.equals(Sides.class)) {
329: if (getSidesSupported(serviceName)) {
330: return new Sides[] { Sides.ONE_SIDED,
331: Sides.TWO_SIDED_SHORT_EDGE,
332: Sides.TWO_SIDED_LONG_EDGE, Sides.DUPLEX,
333: Sides.TUMBLE };
334: }
335: } else if (category.equals(Media.class)) {
336: return getSupportedMediaSizeNames();
337: } else if (category.equals(MediaSizeName.class)) {
338: return getSupportedMediaSizeNames();
339: } else if (category.equals(Chromaticity.class)) {
340: if (getColorSupported(serviceName)) {
341: return new Chromaticity[] { Chromaticity.MONOCHROME,
342: Chromaticity.COLOR };
343: } else {
344: return new Chromaticity[] { Chromaticity.MONOCHROME };
345: }
346: } else if (category.equals(OrientationRequested.class)) {
347: if (getOrientationSupported(serviceName)) {
348: return new OrientationRequested[] {
349: OrientationRequested.PORTRAIT,
350: OrientationRequested.LANDSCAPE };
351: }
352: } else if (category.equals(PrinterResolution.class)) {
353: int[] resolutions = getResolutionsSupported(serviceName);
354: if (resolutions != null && resolutions.length > 1) {
355: PrinterResolution[] res = new PrinterResolution[resolutions.length / 2];
356: for (int i = 0; i < resolutions.length / 2; i++) {
357: res[i] = new PrinterResolution(resolutions[i * 2],
358: resolutions[i * 2 + 1],
359: PrinterResolution.DPI);
360: }
361: return res;
362: }
363: } else if (category.equals(SheetCollate.class)) {
364: if (getCollateSupported(serviceName)) {
365: return new SheetCollate[] { SheetCollate.COLLATED,
366: SheetCollate.UNCOLLATED };
367: }
368: }
369: return null;
370: }
371:
372: private MediaSizeName[] getSupportedMediaSizeNames() {
373: int[][] mediaSizes = getMediaSizesSupported(serviceName);
374: if (mediaSizes == null || mediaSizes.length == 0) {
375: return null;
376: }
377: int[] ids = getMediaIDs(serviceName);
378: String[] names = getMediaNames(serviceName);
379: if (ids == null || names == null
380: || ids.length != mediaSizes.length
381: || names.length != mediaSizes.length) {
382: /*
383: * Something wrong. Don't know exactly what happend,
384: * but printer driver returned different ammount of
385: * sizes, IDs and names of media.
386: */
387: return null;
388: }
389: MediaSizeName[] mediaNames = GDIMediaName
390: .getStandardMediaSizeNames();
391: if (mediaNames == null || mediaNames.length == 0) {
392: return null;
393: }
394: ArrayList result = new ArrayList();
395: medias.clear();
396: for (int i = 0; i < mediaSizes.length; i++) {
397: float sizeX = mediaSizes[i][0] / 10.0f;
398: float sizeY = mediaSizes[i][1] / 10.0f;
399: if (sizeX > 0 && sizeY > 0) {
400: boolean standardFound = false;
401: for (int j = 0; j < mediaNames.length; j++) {
402: MediaSize mediaSize = MediaSize
403: .getMediaSizeForName(mediaNames[j]);
404: if (mediaSize != null
405: && Math.abs(sizeX
406: - mediaSize.getX(MediaSize.MM)) < 1
407: && Math.abs(sizeY
408: - mediaSize.getY(MediaSize.MM)) < 1) {
409: standardFound = true;
410: if (!result.contains(mediaNames[j])) {
411: result.add(mediaNames[j]);
412: medias.put(mediaNames[j], new Integer(
413: ids[i]));
414: /* TODO:
415: * Do we have to do this break? If not,
416: * all names of one size returned.
417: */
418: break;
419: }
420: }
421: }
422: if (!standardFound) {
423: GDIMediaName name = new GDIMediaName(names[i],
424: NOT_STANDARD_MEDIA + i);
425: MediaSizeName sname = MediaSize.findMedia(sizeX,
426: sizeY, MediaSize.MM);
427: if (sname == null) {
428: MediaSize size = new MediaSize(sizeX, sizeY,
429: MediaSize.MM, name);
430: } else {
431: MediaSize size = MediaSize
432: .getMediaSizeForName(sname);
433: if (size.getX(MediaSize.MM) != sizeX
434: || size.getY(MediaSize.MM) != sizeY) {
435: MediaSize newSize = new MediaSize(sizeX,
436: sizeY, MediaSize.MM, name);
437: }
438: }
439: if (!result.contains(name)) {
440: result.add(name);
441: medias.put(name, new Integer(ids[i]));
442: }
443: }
444: }
445: }
446: if (result.size() > 0) {
447: return (MediaSizeName[]) result
448: .toArray(new MediaSizeName[0]);
449: }
450: return null;
451: }
452:
453: private MediaSize[] getSupportedMediaSizes() {
454: MediaSizeName[] mediaSizeNames = getSupportedMediaSizeNames();
455: if (mediaSizeNames != null) {
456: MediaSize[] mediaSizes = new MediaSize[mediaSizeNames.length];
457: for (int i = 0; i < mediaSizeNames.length; i++) {
458: mediaSizes[i] = MediaSize
459: .getMediaSizeForName(mediaSizeNames[i]);
460: }
461: return mediaSizes;
462: }
463: return null;
464: }
465:
466: //----------------------- Printing ---------------------------------------------
467:
468: /*
469: * @see org.apache.harmony.x.print.PrintClient#print(javax.print.Doc,
470: * javax.print.attribute.PrintRequestAttributeSet)
471: */
472: public void print(Doc doc, PrintRequestAttributeSet attributes)
473: throws PrintException {
474: synchronized (this ) {
475: DocFlavor flavor = doc.getDocFlavor();
476: if (flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT)
477: || flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT)
478: || flavor.equals(DocFlavor.URL.POSTSCRIPT)
479: || flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE)
480: || flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE)
481: || flavor.equals(DocFlavor.URL.AUTOSENSE)) {
482: InputStream data = null;
483: try {
484: if (flavor.equals(DocFlavor.URL.POSTSCRIPT)) {
485: data = ((URL) doc.getPrintData()).openStream();
486: } else {
487: data = doc.getStreamForBytes();
488: }
489: } catch (IOException ioe) {
490: throw new PrintException(
491: "Can't read data from document souce");
492: }
493: int printerID = startDocPrinter(serviceName,
494: convertAttributes(attributes, flavor),
495: getJobName(attributes),
496: getDestination(attributes));
497: if (printerID != 0) {
498: byte[] buffer = new byte[10240];
499: try {
500: int bytesRead = data.read(buffer);
501: while (bytesRead >= 0) {
502: if (!writePrinter(buffer, bytesRead,
503: printerID)) {
504: endDocPrinter(printerID);
505: throw new PrintException(
506: "Can't send data to printer");
507: }
508: bytesRead = data.read(buffer);
509: }
510: } catch (IOException ioe) {
511: throw new PrintException(
512: "Can't read print data from Doc");
513: }
514: if (!endDocPrinter(printerID)) {
515: throw new PrintException(
516: "Can't finish job normally");
517: }
518: } else {
519: throw new PrintException("Can't start printing");
520: }
521: } else if (flavor.getMimeType().toLowerCase().equals(
522: "internal/postscript")
523: && flavor.getRepresentationClassName().equals(
524: "java.io.InputStream")) {
525: InputStream data = null;
526: try {
527: data = (InputStream) doc.getPrintData();
528: } catch (IOException ioe) {
529: throw new PrintException(
530: "Can't read data from document souce");
531: }
532: PSInterpreter interpreter = new PSInterpreter(data,
533: serviceName, this , attributes);
534: interpreter.interpret();
535: } else {
536: throw new PrintException("DocFlavor is not supported");
537: }
538: }
539: }
540:
541: int[] convertAttributes(PrintRequestAttributeSet attrs,
542: DocFlavor flavor) throws PrintException {
543: PrintRequestAttributeSet attributes = null;
544: if (attrs == null
545: || flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE)
546: || flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE)
547: || flavor.equals(DocFlavor.URL.AUTOSENSE)) {
548: int[] defaultValues = { -1, -1, -1, -1, -1, -1, -1, -1 };
549: return defaultValues;
550: } else {
551: attributes = attrs;
552: }
553: Attribute[] requestAttrs = attributes.toArray();
554: int[] printAttributes = new int[ATTRIBUTES_ARRAY_SIZE];
555: Arrays.fill(printAttributes, -1);
556: for (int i = 0; i < requestAttrs.length; i++) {
557: Class category = requestAttrs[i].getCategory();
558: if (!isAttributeValueSupported(requestAttrs[i], flavor,
559: attrs)) {
560: // Do nothing or throw PrintException if Fidelity supported.
561: } else if (category.equals(Copies.class)) {
562: Copies copies = (Copies) requestAttrs[i];
563: printAttributes[COPIES_INDEX] = copies.getValue();
564: } else if (category.equals(Sides.class)) {
565: Sides sides = (Sides) requestAttrs[i];
566: printAttributes[SIDES_INDEX] = 1;
567: if (sides.equals(Sides.DUPLEX)
568: || sides.equals(Sides.TWO_SIDED_LONG_EDGE)) {
569: printAttributes[SIDES_INDEX] = 2;
570: } else if (sides.equals(Sides.TUMBLE)
571: || sides.equals(Sides.TWO_SIDED_SHORT_EDGE)) {
572: printAttributes[SIDES_INDEX] = 3;
573: }
574: } else if (category.equals(Media.class)) {
575: if (medias.containsKey(requestAttrs[i])) {
576: Integer id = (Integer) medias.get(requestAttrs[i]);
577: printAttributes[PAPER_ID_INDEX] = id.intValue();
578: }
579: } else if (category.equals(Chromaticity.class)) {
580: if (requestAttrs[i].equals(Chromaticity.MONOCHROME)) {
581: printAttributes[CHROMATICITY_INDEX] = 1;
582: } else if (requestAttrs[i].equals(Chromaticity.COLOR)) {
583: printAttributes[CHROMATICITY_INDEX] = 2;
584: }
585: } else if (category.equals(OrientationRequested.class)) {
586: if (requestAttrs[i]
587: .equals(OrientationRequested.PORTRAIT)) {
588: printAttributes[ORIENTATION_INDEX] = 1;
589: } else if (requestAttrs[i]
590: .equals(OrientationRequested.LANDSCAPE)) {
591: printAttributes[ORIENTATION_INDEX] = 2;
592: }
593: } else if (category.equals(PrinterResolution.class)) {
594: PrinterResolution res = (PrinterResolution) requestAttrs[i];
595: int xres = res
596: .getCrossFeedResolution(PrinterResolution.DPI);
597: int yres = res.getFeedResolution(PrinterResolution.DPI);
598: printAttributes[XRESOLUTION_INDEX] = xres;
599: printAttributes[YRESOLUTION_INDEX] = yres;
600: } else if (category.equals(SheetCollate.class)) {
601: SheetCollate collate = (SheetCollate) requestAttrs[i];
602: if (collate == SheetCollate.COLLATED) {
603: printAttributes[COLLATE_INDEX] = 1;
604: } else if (collate == SheetCollate.UNCOLLATED) {
605: printAttributes[COLLATE_INDEX] = 0;
606: }
607: }
608: }
609: return printAttributes;
610: }
611:
612: String getDestination(PrintRequestAttributeSet attrs)
613: throws PrintException {
614: if (attrs != null) {
615: if (attrs.containsKey(Destination.class)) {
616: Destination destination = (Destination) attrs
617: .get(Destination.class);
618: if (!destination.getURI().getScheme().equals("file")) {
619: throw new PrintException(
620: "Only files supported as destinations.");
621: }
622: String file = destination.getURI().getPath();
623: if (file.startsWith("/")) {
624: file = file.substring(1);
625: }
626: return file;
627: }
628: }
629: return null;
630: }
631:
632: String getJobName(PrintRequestAttributeSet attrs) {
633: if (attrs != null) {
634: if (attrs.containsKey(JobName.class)) {
635: JobName name = (JobName) attrs.get(JobName.class);
636: return name.getValue();
637: }
638: }
639: return "Java GDI client print job";
640: }
641:
642: //----------------------- DocFlavors -------------------------------------------
643:
644: private static native boolean checkPostScript(String serviceName);
645:
646: //----------------------- PrintService attributes ------------------------------
647:
648: private static native boolean getColorSupported(String printerName);
649:
650: private static native int getPagesPerMinute(String printerNmae);
651:
652: private static native int getPagesPerMinuteColor(String printerNmae);
653:
654: private static native int getPrinterIsAcceptingJobs(
655: String printerNmae);
656:
657: private static native String getPrinterLocation(String printerNmae);
658:
659: private static native int getQueuedJobCount(String printerName);
660:
661: // --------------------- Print request attributes -----------------------------
662:
663: private static native int getCopiesSupported(String printerName);
664:
665: private static native boolean getSidesSupported(String printerName);
666:
667: private static native int[][] getMediaSizesSupported(
668: String printerName);
669:
670: private static native int[] getMediaIDs(String printerName);
671:
672: private static native String[] getMediaNames(String printerName);
673:
674: private static native int[] getMediaTraysSupported(
675: String printerName);
676:
677: private static native int[] getResolutionsSupported(
678: String printerName);
679:
680: private static native boolean getOrientationSupported(
681: String printerName);
682:
683: private static native boolean getCollateSupported(String printerName);
684:
685: //----------------------- Printing methods -------------------------------------
686:
687: private static native int startDocPrinter(String serviceName,
688: int[] attributes, String jobName, String destination);
689:
690: private static native boolean writePrinter(byte[] data, int bytes,
691: int printerID);
692:
693: private static native boolean endDocPrinter(int printerID);
694:
695: //----------------------- Internal classes -------------------------------------
696:
697: private static class GDIMediaName extends MediaSizeName {
698:
699: static final long serialVersionUID = 8176250163720875699L;
700:
701: private static GDIMediaName staticMediaName = new GDIMediaName(
702: -1);
703: private String mediaName = null;
704:
705: private GDIMediaName(int value) {
706: super (value);
707: }
708:
709: private GDIMediaName(String mediaName, int value) {
710: super (value);
711: this .mediaName = mediaName;
712: }
713:
714: private static MediaSizeName[] getStandardMediaSizeNames() {
715: return (MediaSizeName[]) staticMediaName
716: .getEnumValueTable();
717: }
718:
719: public String toString() {
720: return mediaName;
721: }
722:
723: public boolean equals(MediaSizeName name) {
724: if (name.hashCode() == hashCode()) {
725: return true;
726: }
727: return false;
728: }
729:
730: public int hashCode() {
731: return mediaName.hashCode();
732: }
733: }
734: }
|