summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/java/awt/print/JavaPrinterGraphics.java468
-rw-r--r--gnu/java/awt/print/JavaPrinterJob.java360
-rw-r--r--gnu/java/awt/print/SpooledDocument.java91
-rw-r--r--gnu/javax/print/ipp/IppRequest.java12
4 files changed, 930 insertions, 1 deletions
diff --git a/gnu/java/awt/print/JavaPrinterGraphics.java b/gnu/java/awt/print/JavaPrinterGraphics.java
new file mode 100644
index 000000000..72eeba6fb
--- /dev/null
+++ b/gnu/java/awt/print/JavaPrinterGraphics.java
@@ -0,0 +1,468 @@
+/* JavaPrinterGraphics.java -- AWT printer rendering class.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.print;
+
+import java.awt.print.PrinterGraphics;
+import java.awt.print.Printable;
+import java.awt.print.PrinterJob;
+import java.awt.print.Paper;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterException;
+import java.awt.geom.AffineTransform;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Shape;
+import java.awt.Rectangle;
+import java.text.AttributedCharacterIterator;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.awt.image.PixelGrabber;
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.io.PrintWriter;
+import java.io.FileWriter;
+import java.io.BufferedWriter;
+
+import gnu.java.awt.peer.gtk.GtkImage;
+
+/**
+ * Graphics context to draw to PostScript.
+ *
+ * @author Sven de Marothy
+ */
+public class JavaPrinterGraphics extends Graphics implements PrinterGraphics
+{
+
+ /**
+ * The used graphics context.
+ */
+ private Graphics g;
+
+ /**
+ * The associated printer job.
+ */
+ private PrinterJob printerJob;
+
+ /**
+ * The paper format.
+ */
+ PageFormat pageFormat;
+
+ /**
+ * Rendering resolution
+ */
+ private static final double DPI = 72.0;
+
+ /**
+ * Rendered image size.
+ */
+ private int xSize, ySize;
+
+ /**
+ * The image to render to.
+ */
+ private Image image;
+
+ public JavaPrinterGraphics( PrinterJob printerJob, PageFormat pageFormat )
+ {
+ this.printerJob = printerJob;
+ this.pageFormat = pageFormat;
+
+ // Create a really big image and draw to that.
+ xSize = (int)(DPI*pageFormat.getWidth()/72.0);
+ ySize = (int)(DPI*pageFormat.getHeight()/72.0);
+
+ // FIXME: This should at least be BufferedImage. Fix once we have a working B.I.
+ // Graphics2D should also be supported of course.
+ image = new GtkImage(xSize, ySize);
+
+ initImage();
+ }
+
+ /**
+ * The only method worthy of mention here.
+ */
+ public SpooledDocument spoolPostScript(Printable p)
+ throws PrinterException
+ {
+ try
+ {
+ // spool to a temporary file
+ File temp = File.createTempFile("cpspool", ".ps");
+ temp.deleteOnExit();
+
+ PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(temp)));
+ writePSHeader(out);
+ int status;
+ int index = 0;
+ while(p.print(this, pageFormat, index++) == Printable.PAGE_EXISTS)
+ {
+ g.dispose();
+ g = null;
+ writePage( out );
+ initImage();
+ }
+
+ out.println("%%Trailer");
+ out.println("grestore % restore original stuff");
+ out.println("%%EOF");
+ out.close();
+ return new SpooledDocument( temp );
+ }
+ catch (IOException e)
+ {
+ PrinterException pe = new PrinterException();
+ pe.initCause(e);
+ throw pe;
+ }
+ }
+
+ private void initImage()
+ {
+ g = image.getGraphics();
+ setColor(Color.white);
+ fillRect(0, 0, xSize, ySize);
+ setColor(Color.black);
+ }
+
+ private void writePSHeader(PrintWriter out)
+ {
+ Paper p = pageFormat.getPaper();
+ out.println("%!PS-Adobe-3.0");
+ out.println("%%Title: "+printerJob.getJobName());
+ out.println("%%Creator: GNU Classpath ");
+ out.println("%%DocumentData: Clean8Bit");
+ out.println("%%Orientation: "+ ((pageFormat.getOrientation() ==
+ PageFormat.PORTRAIT) ?
+ "Portrait" : "Landscape"));
+
+ // invert the Y axis so that we get screen-like coordinates instead.
+ AffineTransform pageTransform = new AffineTransform();
+ pageTransform.translate(0.0, p.getHeight());
+ pageTransform.scale(1.0,-1.0);
+ concatCTM(out, pageTransform);
+
+ out.println("%%DocumentNeededResources: font Times-Roman Helvetica Courier");
+ // out.println("%%Pages: "+); // FIXME # pages.
+ out.println("%%EndComments");
+
+ out.println("%%BeginProlog");
+ out.println("%%EndProlog");
+ out.println("%%BeginSetup");
+
+ // FIXME: Paper name
+ // E.g. "A4" "Letter"
+ // out.println("%%BeginFeature: *PageSize A4");
+
+ // 595x842; 612x792 respectively
+ out.println("<< /PageSize [" +p.getWidth() + " "+p.getHeight()+ "] >> setpagedevice");
+ out.println("%%EndFeature");
+
+ out.println("%%EndSetup");
+
+ // out.println("%%Page: 1 1");
+ out.println("%%BeginPageSetup");
+
+ out.println("gsave % first save");
+ }
+
+ private void writePage(PrintWriter out)
+ {
+ out.println("% writePage()");
+ out.println("gsave");
+ out.println(xSize+" "+ySize+" 8 [1 0 0 -1 0 "+ySize+" ]");
+ out.println("{currentfile 3 string readhexstring pop} bind");
+ out.println("false 3 colorimage");
+ int[] pixels = new int[xSize * ySize];
+ PixelGrabber pg = new PixelGrabber(image, 0, 0, xSize, ySize, pixels, 0, xSize);
+
+ try {
+ pg.grabPixels();
+ } catch (InterruptedException e) {
+ out.println("% Bug getting pixels!");
+ }
+
+ int n = 0;
+ for (int j = 0; j < ySize; j++) {
+ for (int i = 0; i < xSize; i++) {
+ out.print( colorTripleHex(new Color(pixels[j * xSize + i])) );
+ if(((++n)%11) == 0) out.println();
+ }
+ }
+
+ out.println();
+ out.println("%%EOF");
+ out.println("grestore");
+ out.println("showpage");
+ }
+
+ /**
+ * Get a nonsperated hex RGB triple, e.g. FFFFFF = white
+ */
+ private String colorTripleHex(Color c){
+ String s = "";
+
+ try {
+ s = Integer.toString( ( c.getRed() & 0xFF ) + 0x100, 16).substring(1)
+ + Integer.toString( ( c.getGreen() & 0xFF ) + 0x100, 16).substring(1)
+ + Integer.toString( ( c.getBlue() & 0xFF ) + 0x100, 16).substring(1);
+ } catch (Exception e){
+ s = "FFFFFF";
+ }
+
+ return s;
+ }
+
+ private void concatCTM(PrintWriter out, AffineTransform Tx){
+ double[] matrixElements = new double[6];
+ Tx.getMatrix(matrixElements);
+
+ out.print("[ ");
+ for(int i=0;i<6;i++)
+ out.print(matrixElements[i]+" ");
+ out.println("] concat");
+ }
+
+ //-----------------------------------------------------------------------------
+ /**
+ * PrinterGraphics method - Returns the printer job associated with this object.
+ */
+ public PrinterJob getPrinterJob()
+ {
+ return printerJob;
+ }
+
+ /**
+ * The rest of the methods here are just pass-throughs to g.
+ */
+ public void clearRect(int x, int y, int width, int height)
+ {
+ g.clearRect(x, y, width, height);
+ }
+
+ public void clipRect(int x, int y, int width, int height)
+ {
+ g.clipRect(x, y, width, height);
+ }
+
+ public void copyArea(int x, int y, int width, int height, int dx, int dy)
+ {
+ g.copyArea(x, y, width, height, dx, dy);
+ }
+
+ public Graphics create()
+ {
+ return g.create();
+ }
+
+ public void dispose()
+ {
+ }
+
+ public void drawArc(int x, int y, int width, int height, int startAngle,
+ int arcAngle)
+ {
+ g.drawArc(x, y, width, height, startAngle, arcAngle);
+ }
+
+ public boolean drawImage(Image img, int x, int y, Color bgcolor,
+ ImageObserver observer)
+ {
+ return drawImage(img, x, y, bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, ImageObserver observer)
+ {
+ return drawImage(img, x, y, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ Color bgcolor, ImageObserver observer)
+ {
+ return drawImage(img, x, y, width, height, bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ ImageObserver observer)
+ {
+ return drawImage(img, x, y, width, height, observer);
+ }
+
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+ ImageObserver observer)
+ {
+ return drawImage(img, dx1, dy1, dx2, dy2,
+ sx1, sy1, sx2, sy2, bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
+ {
+ return drawImage(img, dx1, dy1, dx2, dy2,
+ sx1, sy1, sx2, sy2, observer);
+ }
+
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ g.drawLine(x1, y1, x2, y2);
+ }
+
+ public void drawOval(int x, int y, int width, int height)
+ {
+ g.drawOval(x, y, width, height);
+ }
+
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ g.drawPolygon(xPoints, yPoints, nPoints);
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ g.drawPolyline(xPoints, yPoints, nPoints);
+ }
+
+ public void drawRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ g.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
+ }
+
+ public void drawString(AttributedCharacterIterator iterator, int x, int y)
+ {
+ g.drawString(iterator, x, y);
+ }
+
+ public void drawString(String str, int x, int y)
+ {
+ g.drawString(str, x, y);
+ }
+
+ public void fillArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle)
+ {
+ g.fillArc(x, y, width, height, startAngle, arcAngle);
+ }
+
+ public void fillOval(int x, int y, int width, int height)
+ {
+ g.fillOval(x, y, width, height);
+ }
+
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ g.fillPolygon(xPoints, yPoints, nPoints);
+ }
+
+ public void fillRect(int x, int y, int width, int height)
+ {
+ g.fillRect(x, y, width, height);
+ }
+
+ public void fillRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ g.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
+ }
+
+ public Shape getClip()
+ {
+ return g.getClip();
+ }
+
+ public Rectangle getClipBounds()
+ {
+ return g.getClipBounds();
+ }
+
+ public Color getColor()
+ {
+ return g.getColor();
+ }
+
+ public Font getFont()
+ {
+ return g.getFont();
+ }
+
+ public FontMetrics getFontMetrics(Font f)
+ {
+ return g.getFontMetrics(f);
+ }
+
+ public void setClip(int x, int y, int width, int height)
+ {
+ g.setClip(x, y, width, height);
+ }
+
+ public void setClip(Shape clip)
+ {
+ g.setClip(clip);
+ }
+
+ public void setColor(Color c)
+ {
+ g.setColor(c);
+ }
+
+ public void setFont(Font font)
+ {
+ g.setFont(font);
+ }
+
+ public void setPaintMode()
+ {
+ g.setPaintMode();
+ }
+
+ public void setXORMode(Color c1)
+ {
+ g.setXORMode(c1);
+ }
+
+ public void translate(int x, int y)
+ {
+ g.translate(x, y);
+ }
+}
+
diff --git a/gnu/java/awt/print/JavaPrinterJob.java b/gnu/java/awt/print/JavaPrinterJob.java
new file mode 100644
index 000000000..140209401
--- /dev/null
+++ b/gnu/java/awt/print/JavaPrinterJob.java
@@ -0,0 +1,360 @@
+/* JavaPrinterJob.java -- AWT printing implemented on javax.print.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.print;
+
+import java.util.Locale;
+import java.awt.HeadlessException;
+import java.awt.print.Pageable;
+import java.awt.print.Printable;
+import java.awt.print.PrinterGraphics;
+import java.awt.print.Book;
+import java.awt.print.PageFormat;
+import java.awt.print.Paper;
+import java.awt.print.PrinterJob;
+import java.awt.print.PrinterAbortException;
+import java.awt.print.PrinterException;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.DocFlavor;
+import javax.print.DocPrintJob;
+import javax.print.PrintException;
+import javax.print.StreamPrintServiceFactory;
+import javax.print.ServiceUI;
+import javax.print.attribute.IntegerSyntax;
+import javax.print.attribute.TextSyntax;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.JobName;
+import javax.print.attribute.standard.RequestingUserName;
+
+/**
+ * This is the default implementation of PrinterJob
+ *
+ * @author Sven de Marothy
+ */
+public class JavaPrinterJob extends PrinterJob
+{
+ /**
+ * The print service associated with this job
+ */
+ private PrintService printer = null;
+
+ /**
+ * Printing options;
+ */
+ private PrintRequestAttributeSet attributes;
+
+ /**
+ * Available print services
+ */
+ private static PrintService[] services;
+
+ /**
+ * The actual print job.
+ */
+ private DocPrintJob printJob;
+
+ /**
+ * The Printable object to print.
+ */
+ private Printable printable;
+
+ /**
+ * Page format.
+ */
+ private PageFormat pageFormat;
+
+ static
+ {
+ // lookup all services without any constraints
+ services = PrintServiceLookup.lookupPrintServices
+ (DocFlavor.INPUT_STREAM.POSTSCRIPT, null);
+ }
+
+ private static final Class copyClass = (new Copies(1)).getClass();
+ private static final Class jobNameClass = (new JobName("", null)).getClass();
+ private static final Class userNameClass = (new RequestingUserName("", null)).getClass();
+
+ /**
+ * Initializes a new instance of <code>PrinterJob</code>.
+ */
+ public JavaPrinterJob()
+ {
+ attributes = new HashPrintRequestAttributeSet();
+ setCopies(1);
+ setJobName("Java Printing");
+ pageFormat = new PageFormat(); // default page format.
+ }
+
+ /**
+ * Returns the number of copies to be printed.
+ *
+ * @return The number of copies to be printed.
+ */
+ public int getCopies()
+ {
+ return ((IntegerSyntax)attributes.get( jobNameClass )).getValue();
+ }
+
+ /**
+ * Sets the number of copies to be printed.
+ *
+ * @param copies The number of copies to be printed.
+ */
+ public void setCopies(int copies)
+ {
+ attributes.add( new Copies( copies ) );
+ }
+
+ /**
+ * Returns the name of the print job.
+ *
+ * @return The name of the print job.
+ */
+ public String getJobName()
+ {
+ return ((TextSyntax)attributes.get( jobNameClass )).getValue();
+ }
+
+ /**
+ * Sets the name of the print job.
+ *
+ * @param job_name The name of the print job.
+ */
+ public void setJobName(String job_name)
+ {
+ attributes.add( new JobName(job_name, Locale.getDefault()) );
+ }
+
+ /**
+ * Returns the printing user name.
+ *
+ * @return The printing username.
+ */
+ public String getUserName()
+ {
+ return ((TextSyntax)attributes.get( userNameClass )).getValue();
+ }
+
+ /**
+ * Cancels an in progress print job.
+ */
+ public void cancel()
+ {
+ }
+
+ /**
+ * Tests whether or not this job has been cancelled.
+ *
+ * @return <code>true</code> if this job has been cancelled, <code>false</code>
+ * otherwise.
+ */
+ public boolean isCancelled()
+ {
+ return false;
+ }
+
+ /**
+ * Clones the specified <code>PageFormat</code> object then alters the
+ * clone so that it represents the default page format.
+ *
+ * @param page_format The <code>PageFormat</code> to clone.
+ *
+ * @return A new default page format.
+ */
+ public PageFormat defaultPage(PageFormat page_format)
+ {
+ return new PageFormat();
+ }
+
+ /**
+ * Displays a dialog box to the user which allows the page format
+ * attributes to be modified.
+ *
+ * @param page_format The <code>PageFormat</code> object to modify.
+ *
+ * @return The modified <code>PageFormat</code>.
+ */
+ public PageFormat pageDialog(PageFormat page_format)
+ throws HeadlessException
+ {
+ return defaultPage(null);
+ }
+
+ /**
+ * Prints the pages.
+ */
+ public void print() throws PrinterException
+ {
+ if( printable == null )
+ return;
+ JavaPrinterGraphics pg = new JavaPrinterGraphics( this, pageFormat );
+
+ printJob = printer.createPrintJob();
+ SpooledDocument doc = pg.spoolPostScript( printable );
+ try
+ {
+ printJob.print(doc, attributes);
+ }
+ catch (PrintException pe)
+ {
+ PrinterException p = new PrinterException();
+ p.initCause(pe);
+ throw p;
+ }
+ }
+
+ /**
+ * Prints the page with given attributes.
+ */
+ public void print (PrintRequestAttributeSet attributes)
+ throws PrinterException
+ {
+ this.attributes = attributes;
+ print();
+ }
+
+ /**
+ * Displays a dialog box to the user which allows the print job
+ * attributes to be modified.
+ *
+ * @return <code>false</code> if the user cancels the dialog box,
+ * <code>true</code> otherwise.
+ */
+ public boolean printDialog() throws HeadlessException
+ {
+ return printDialog( attributes );
+ }
+
+ /**
+ * Displays a dialog box to the user which allows the print job
+ * attributes to be modified.
+ *
+ * @return <code>false</code> if the user cancels the dialog box,
+ * <code>true</code> otherwise.
+ */
+ public boolean printDialog(PrintRequestAttributeSet attributes)
+ throws HeadlessException
+ {
+ PrintService chosenPrinter = ServiceUI.printDialog
+ (null, 50, 50, services, null,
+ DocFlavor.INPUT_STREAM.POSTSCRIPT, attributes);
+
+ if( chosenPrinter != null )
+ {
+ try
+ {
+ setPrintService( chosenPrinter );
+ }
+ catch(PrinterException pe)
+ {
+ // Should not happen.
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * This sets the pages that are to be printed.
+ *
+ * @param pageable The pages to be printed, which may not be <code>null</code>.
+ */
+ public void setPageable(Pageable pageable)
+ {
+ // FIXME
+ }
+
+ /**
+ * Sets this specified <code>Printable</code> as the one to use for
+ * rendering the pages on the print device.
+ *
+ * @param printable The <code>Printable</code> for the print job.
+ */
+ public void setPrintable(Printable printable)
+ {
+ this.printable = printable;
+ }
+
+ /**
+ * Sets the <code>Printable</code> and the page format for the pages
+ * to be printed.
+ *
+ * @param printable The <code>Printable</code> for the print job.
+ * @param page_format The <code>PageFormat</code> for the print job.
+ */
+ public void setPrintable(Printable printable, PageFormat page_format)
+ {
+ this.printable = printable;
+ // FIXME
+ }
+
+ /**
+ * Makes any alterations to the specified <code>PageFormat</code>
+ * necessary to make it work with the current printer. The alterations
+ * are made to a clone of the input object, which is then returned.
+ *
+ * @param page_format The <code>PageFormat</code> to validate.
+ *
+ * @return The validated <code>PageFormat</code>.
+ */
+ public PageFormat validatePage(PageFormat page_format)
+ {
+ // FIXME
+ return page_format;
+ }
+
+ /**
+ * Change the printer for this print job to service. Subclasses that
+ * support setting the print service override this method. Throws
+ * PrinterException when the class doesn't support setting the printer,
+ * the service doesn't support Pageable or Printable interfaces for 2D
+ * print output.
+ * @param service The new printer to use.
+ * @throws PrinterException if service is not valid.
+ */
+ public void setPrintService(PrintService service)
+ throws PrinterException
+ {
+ if(!service.isDocFlavorSupported(DocFlavor.INPUT_STREAM.POSTSCRIPT))
+ throw new PrinterException("This printer service is not supported.");
+ printer = service;
+ }
+}
diff --git a/gnu/java/awt/print/SpooledDocument.java b/gnu/java/awt/print/SpooledDocument.java
new file mode 100644
index 000000000..b606a2ef6
--- /dev/null
+++ b/gnu/java/awt/print/SpooledDocument.java
@@ -0,0 +1,91 @@
+/* SpooledDocument.java -- Reurgitate a spooled PostScript file
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.print;
+
+import javax.print.Doc;
+import javax.print.DocFlavor;
+import javax.print.attribute.DocAttributeSet;
+import java.io.File;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class SpooledDocument implements Doc
+{
+ private FileInputStream fis;
+
+ public SpooledDocument(File file)
+ {
+ try
+ {
+ fis = new FileInputStream(file);
+ }
+ catch (FileNotFoundException ffne)
+ {
+ // Shouldn't happen.
+ }
+ }
+
+ public DocAttributeSet getAttributes()
+ {
+ return null;
+ }
+
+ public DocFlavor getDocFlavor()
+ {
+ return DocFlavor.INPUT_STREAM.POSTSCRIPT;
+ }
+
+ public Object getPrintData()
+ {
+ return fis;
+ }
+
+ public Reader getReaderForText()
+ {
+ return new InputStreamReader(fis);
+ }
+
+ public InputStream getStreamForBytes()
+ {
+ return fis;
+ }
+}
diff --git a/gnu/javax/print/ipp/IppRequest.java b/gnu/javax/print/ipp/IppRequest.java
index 8abab5192..ccfa9b272 100644
--- a/gnu/javax/print/ipp/IppRequest.java
+++ b/gnu/javax/print/ipp/IppRequest.java
@@ -119,6 +119,11 @@ public class IppRequest
{
/**
+ * The printer-poll timeout.
+ */
+ private static final int timeout = 1000;
+
+ /**
* Helper class used to write the attributes of a request
* into the supplied data output stream in the correct way.
*
@@ -838,7 +843,12 @@ public class IppRequest
out.flush();
stream.flush();
-
+
+ // Set the connection timeout, for if the printer is offline.
+ // FIXME: The print services polling should probably be done in its
+ // own thread.
+ connection.setConnectTimeout( timeout );
+
int responseCode = responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK)