/*------------------------------------------------------------------------- | rxtx is a native interface to communication ports in java. | Copyright 1997-2004 by Trent Jarvi taj@www.linux.org.uk | | This library is free software; you can redistribute it and/or | modify it under the terms of the GNU Library General Public | License as published by the Free Software Foundation; either | version 2 of the License, or (at your option) any later version. | | This library 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 | Library General Public License for more details. | | You should have received a copy of the GNU Library General Public | License along with this library; if not, write to the Free | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --------------------------------------------------------------------------*/ package gnu.io; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.util.TooManyListenersException; import java.lang.Math; /** * LPRPort */ final class LPRPort extends ParallelPort { static { System.loadLibrary( "rxtxParallel" ); Initialize(); } /** Initialize the native library */ private native static void Initialize(); private final static boolean debug = false; /** Open the named port */ public LPRPort( String name ) throws PortInUseException { if (debug) System.out.println("LPRPort:LPRPort("+name+")"); /* commapi/javadocs/API_users_guide.html specifies that whenever an application tries to open a port in use by another application the PortInUseException will be thrown I know some didnt like it this way but I'm not sure how to avoid it. We will just be writing to a bogus fd if we catch the exeption Trent */ // try { fd = open( name ); this.name = name; // } catch ( PortInUseException e ){} if (debug) System.out.println("LPRPort:LPRPort("+name+") fd = " + fd); } private synchronized native int open( String name ) throws PortInUseException; /** File descriptor */ private int fd; /** Output stream */ private final ParallelOutputStream out = new ParallelOutputStream(); public OutputStream getOutputStream() { return out; } /** Input stream */ private final ParallelInputStream in = new ParallelInputStream(); public InputStream getInputStream() { return in; } /** return current mode LPT_MODE_SPP, LPT_MODE_PS2, LPT_MODE_EPP, or LPT_MODE_ECP */ private int lprmode=LPT_MODE_ANY; public int getMode() { return lprmode; } public int setMode(int mode) throws UnsupportedCommOperationException { try { setLPRMode(mode); } catch(UnsupportedCommOperationException e) { e.printStackTrace(); return -1; } lprmode = mode; return(0); } public void restart() { System.out.println("restart() is not implemented"); } public void suspend() { System.out.println("suspend() is not implemented"); } public native boolean setLPRMode(int mode) throws UnsupportedCommOperationException; public native boolean isPaperOut(); public native boolean isPrinterBusy(); public native boolean isPrinterError(); public native boolean isPrinterSelected(); public native boolean isPrinterTimedOut(); /** Close the port */ private native void nativeClose(); public synchronized void close() { if( fd < 0 ) return; nativeClose(); super.close(); removeEventListener(); fd = 0; Runtime.getRuntime().gc(); } /** Receive framing control */ public void enableReceiveFraming( int f ) throws UnsupportedCommOperationException { throw new UnsupportedCommOperationException( "Not supported" ); } public void disableReceiveFraming() {} public boolean isReceiveFramingEnabled() { return false; } public int getReceiveFramingByte() { return 0; } /** Receive timeout control */ private int timeout = 0; public void enableReceiveTimeout( int t ) { if( t > 0 ) timeout = t; else timeout = 0; } public void disableReceiveTimeout() { timeout = 0; } public boolean isReceiveTimeoutEnabled() { return timeout > 0; } public int getReceiveTimeout() { return timeout; } /** Receive threshold control */ private int threshold = 1; public void enableReceiveThreshold( int t ) { if( t > 1 ) threshold = t; else threshold = 1; } public void disableReceiveThreshold() { threshold = 1; } public int getReceiveThreshold() { return threshold; } public boolean isReceiveThresholdEnabled() { return threshold > 1; }; /** Input/output buffers These are native stubs... */ public native void setInputBufferSize( int size ); public native int getInputBufferSize(); public native void setOutputBufferSize( int size ); public native int getOutputBufferSize(); public native int getOutputBufferFree(); /** Write to the port */ protected native void writeByte( int b ) throws IOException; protected native void writeArray( byte b[], int off, int len ) throws IOException; protected native void drain() throws IOException; /** LPRPort read methods */ protected native int nativeavailable() throws IOException; protected native int readByte() throws IOException; protected native int readArray( byte b[], int off, int len ) throws IOException; /** Parallel Port Event listener */ private ParallelPortEventListener PPEventListener; /** Thread to monitor data */ private MonitorThread monThread; /** Process ParallelPortEvents */ native void eventLoop(); public boolean checkMonitorThread() { if(monThread != null) return monThread.isInterrupted(); return(true); } public synchronized boolean sendEvent( int event, boolean state ) { /* Let the native side know its time to die */ if ( fd == 0 || PPEventListener == null || monThread == null ) { return(true); } switch( event ) { case ParallelPortEvent.PAR_EV_BUFFER: if( monThread.monBuffer ) break; return(false); case ParallelPortEvent.PAR_EV_ERROR: if( monThread.monError ) break; return(false); default: System.err.println("unknown event:"+event); return(false); } ParallelPortEvent e = new ParallelPortEvent(this, event, !state, state ); if( PPEventListener != null ) PPEventListener.parallelEvent( e ); if ( fd == 0 || PPEventListener == null || monThread == null ) { return(true); } else { try{Thread.sleep(50);} catch(Exception exc){} return(false); } } /** Add an event listener */ public synchronized void addEventListener( ParallelPortEventListener lsnr ) throws TooManyListenersException { if( PPEventListener != null ) throw new TooManyListenersException(); PPEventListener = lsnr; monThread = new MonitorThread(); monThread.start(); } /** Remove the parallel port event listener */ public synchronized void removeEventListener() { PPEventListener = null; if( monThread != null ) { monThread.interrupt(); monThread = null; } } /** Note: these have to be separate boolean flags because the ParallelPortEvent constants are NOT bit-flags, they are just defined as integers from 1 to 10 -DPL */ public synchronized void notifyOnError( boolean enable ) { System.out.println("notifyOnError is not implemented yet"); monThread.monError = enable; } public synchronized void notifyOnBuffer( boolean enable ) { System.out.println("notifyOnBuffer is not implemented yet"); monThread.monBuffer = enable; } /** Finalize the port */ protected void finalize() { if ( fd > 0 ) close(); } /** Inner class for ParallelOutputStream */ class ParallelOutputStream extends OutputStream { public synchronized void write( int b ) throws IOException { if ( fd == 0 ) throw new IOException(); writeByte( b ); } public synchronized void write( byte b[] ) throws IOException { if ( fd == 0 ) throw new IOException(); writeArray( b, 0, b.length ); } public synchronized void write( byte b[], int off, int len ) throws IOException { if ( fd == 0 ) throw new IOException(); writeArray( b, off, len ); } public synchronized void flush() throws IOException { if ( fd == 0 ) throw new IOException(); //drain(); } } /** Inner class for ParallelInputStream */ class ParallelInputStream extends InputStream { public int read() throws IOException { if ( fd == 0 ) throw new IOException(); return readByte(); } public int read( byte b[] ) throws IOException { if ( fd == 0 ) throw new IOException(); return readArray( b, 0, b.length ); } public int read( byte b[], int off, int len ) throws IOException { if ( fd == 0 ) throw new IOException(); return readArray( b, off, len ); } public int available() throws IOException { if ( fd == 0 ) throw new IOException(); return nativeavailable(); } } class MonitorThread extends Thread { private boolean monError = false; private boolean monBuffer = false; MonitorThread() { } public void run() { eventLoop(); yield(); } } }