/*-------------------------------------------------------------------------
| 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();
}
}
}