|
From: <cr...@us...> - 2008-09-13 08:02:26
|
Revision: 4556
http://jnode.svn.sourceforge.net/jnode/?rev=4556&view=rev
Author: crawley
Date: 2008-09-13 08:02:20 +0000 (Sat, 13 Sep 2008)
Log Message:
-----------
Converted the console subsystem to be natively character (Reader/Writer)
based rather than byte (Stream) based, and propagated the API changes
throughout the system.
Modified Paths:
--------------
trunk/core/src/core/org/jnode/log4j/config/Log4jConfigurePlugin.java
trunk/core/src/core/org/jnode/log4j/config/VirtualConsoleAppender.java
trunk/core/src/core/org/jnode/util/Queue.java
trunk/core/src/driver/org/jnode/driver/console/TextConsole.java
trunk/core/src/driver/org/jnode/driver/console/textscreen/Line.java
trunk/core/src/driver/org/jnode/driver/console/textscreen/TextScreenConsole.java
trunk/core/src/driver/org/jnode/driver/console/textscreen/TextScreenConsoleManager.java
trunk/core/src/driver/org/jnode/driver/console/textscreen/TextScreenConsolePlugin.java
trunk/core/src/driver/org/jnode/driver/input/KeyboardEvent.java
trunk/distr/src/apps/org/jnode/apps/telnetd/RemoteConsoleManager.java
trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java
trunk/shell/src/shell/org/jnode/shell/CommandLine.java
trunk/shell/src/shell/org/jnode/shell/CommandRunner.java
trunk/shell/src/shell/org/jnode/shell/CommandShell.java
trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java
trunk/shell/src/shell/org/jnode/shell/PathnamePattern.java
trunk/shell/src/shell/org/jnode/shell/Shell.java
trunk/shell/src/shell/org/jnode/shell/command/HelpCommand.java
trunk/shell/src/shell/org/jnode/shell/command/JavaCommand.java
trunk/shell/src/shell/org/jnode/shell/command/SyntaxCommand.java
trunk/shell/src/shell/org/jnode/shell/command/debug/RemoteOutputCommand.java
trunk/shell/src/shell/org/jnode/shell/command/driver/console/ConsoleCommand.java
trunk/shell/src/shell/org/jnode/shell/help/Argument.java
trunk/shell/src/shell/org/jnode/shell/help/CommandLineElement.java
trunk/shell/src/shell/org/jnode/shell/help/Help.java
trunk/shell/src/shell/org/jnode/shell/help/Parameter.java
trunk/shell/src/shell/org/jnode/shell/help/argument/EnumOptionArgument.java
trunk/shell/src/shell/org/jnode/shell/help/argument/OptionArgument.java
trunk/shell/src/shell/org/jnode/shell/help/def/DefaultHelp.java
trunk/shell/src/shell/org/jnode/shell/io/BaseCommandIO.java
trunk/shell/src/shell/org/jnode/shell/io/CommandIO.java
trunk/shell/src/shell/org/jnode/shell/io/CommandIOMarker.java
trunk/shell/src/shell/org/jnode/shell/io/CommandInput.java
trunk/shell/src/shell/org/jnode/shell/io/CommandInputOutput.java
trunk/shell/src/shell/org/jnode/shell/io/CommandOutput.java
trunk/shell/src/shell/org/jnode/shell/syntax/Log4jLoggerArgument.java
trunk/shell/src/shell/org/jnode/shell/syntax/OptionSetSyntax.java
trunk/shell/src/test/org/jnode/test/shell/help/DefaultHelpTest.java
trunk/shell/src/test/org/jnode/test/shell/io/ReaderInputStreamTest.java
trunk/shell/src/test/org/jnode/test/shell/io/WriterOutputStreamTest.java
Added Paths:
-----------
trunk/core/src/core/org/jnode/log4j/config/JNodeConsoleAppender.java
trunk/core/src/core/org/jnode/util/ReaderInputStream.java
trunk/core/src/core/org/jnode/util/WriterOutputStream.java
trunk/core/src/driver/org/jnode/driver/console/spi/ConsoleWriter.java
trunk/core/src/driver/org/jnode/driver/console/textscreen/KeyboardReader.java
trunk/shell/src/shell/org/jnode/shell/io/FanoutWriter.java
Removed Paths:
-------------
trunk/core/src/driver/org/jnode/driver/console/ConsoleInputStream.java
trunk/core/src/driver/org/jnode/driver/console/spi/ConsoleOutputStream.java
trunk/core/src/driver/org/jnode/driver/console/spi/ConsolePrintStream.java
trunk/core/src/driver/org/jnode/driver/console/textscreen/KeyboardInputStream.java
trunk/shell/src/shell/org/jnode/shell/io/FanoutOutputStream.java
trunk/shell/src/shell/org/jnode/shell/io/ReaderInputStream.java
trunk/shell/src/shell/org/jnode/shell/io/WriterOutputStream.java
Added: trunk/core/src/core/org/jnode/log4j/config/JNodeConsoleAppender.java
===================================================================
--- trunk/core/src/core/org/jnode/log4j/config/JNodeConsoleAppender.java (rev 0)
+++ trunk/core/src/core/org/jnode/log4j/config/JNodeConsoleAppender.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -0,0 +1,74 @@
+/*
+ * $Id: Log4jConfigurePlugin.java 4387 2008-08-03 07:55:38Z fduminy $
+ *
+ * JNode.org
+ * Copyright (C) 2003-2006 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jnode.log4j.config;
+
+import java.io.Writer;
+
+import org.apache.log4j.Layout;
+import org.apache.log4j.WriterAppender;
+import org.jnode.driver.console.TextConsole;
+
+/**
+ * Custom Log4j appender class for appending to JNode consoles. This appender
+ * avoids the unnecessary Writer to Stream to Writer wrappering that goes on
+ * if we use the standard Log4j ConsoleAppender. (JNode's consoles are natively
+ * character oriented rather than byte oriented.)
+ *
+ * @author cr...@jn...
+ */
+public class JNodeConsoleAppender extends WriterAppender {
+
+ private Writer writer;
+
+ /**
+ * Create an appender for a given JNode console.
+ * @param layout the appender's initial log message layout.
+ * @param console the target console.
+ * @param toErr if <code>true</code> output to the console's 'err' stream,
+ * otherwise to it's 'out' stream.
+ */
+ public JNodeConsoleAppender(Layout layout, TextConsole console, boolean toErr) {
+ super();
+ this.layout = layout;
+ this.immediateFlush = true;
+ this.writer = toErr ? console.getErr() : console.getOut();
+ super.setWriter(this.writer);
+ }
+
+ @Override
+ protected void closeWriter() {
+ // Ignore the close request. We don't own the writer.
+ }
+
+ @Override
+ public void activateOptions() {
+ super.setWriter(writer);
+ }
+
+ @Override
+ public synchronized void setWriter(Writer writer) {
+ if (writer != this.writer) {
+ throw new IllegalArgumentException("cannot change the writer");
+ }
+ super.setWriter(writer);
+ }
+
+}
Modified: trunk/core/src/core/org/jnode/log4j/config/Log4jConfigurePlugin.java
===================================================================
--- trunk/core/src/core/org/jnode/log4j/config/Log4jConfigurePlugin.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/core/org/jnode/log4j/config/Log4jConfigurePlugin.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -32,6 +32,7 @@
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
+import org.apache.log4j.WriterAppender;
import org.jnode.driver.console.ConsoleManager;
import org.jnode.driver.console.TextConsole;
import org.jnode.naming.InitialNaming;
@@ -39,6 +40,7 @@
import org.jnode.plugin.PluginDescriptor;
import org.jnode.plugin.PluginException;
import org.jnode.system.BootLog;
+import org.jnode.util.WriterOutputStream;
/**
* @author Ewout Prangsma (ep...@us...)
@@ -58,6 +60,7 @@
* @see org.jnode.plugin.Plugin#startPlugin()
*/
protected void startPlugin() throws PluginException {
+ System.err.println("Running in Log4jConfigurePlugin.startPlugin");
final Logger root = Logger.getRootLogger();
try {
// Create the appenders
@@ -72,12 +75,23 @@
conMgr.registerConsole(console);
console.setAcceleratorKeyCode(KeyEvent.VK_F7);
- final VirtualConsoleAppender debugApp = new VirtualConsoleAppender(console, new PatternLayout(LAYOUT));
+ final VirtualConsoleAppender debugApp =
+ new VirtualConsoleAppender(console, new PatternLayout(LAYOUT));
debugApp.setThreshold(Level.DEBUG);
- BootLog.setDebugOut(new PrintStream(console.getOut()));
+ BootLog.setDebugOut(new PrintStream(new WriterOutputStream(console.getOut()), true));
- final ConsoleAppender infoApp = new ConsoleAppender(new PatternLayout(LAYOUT));
+ // This doesn't work yet. It sends to the F7 console, whereas we really want to send
+ // the log messages to the current active console.
+// final WriterAppender infoApp =
+// new JNodeConsoleAppender(new PatternLayout(LAYOUT), console, false);
+
+ // This kind of works. It sends to whatever System.out currently is at the point
+ // that the appender is created. But if this plugin is started too late, this will
+ // could be almost anything.
+ final WriterAppender infoApp =
+ new ConsoleAppender(new PatternLayout(LAYOUT));
infoApp.setThreshold(Level.INFO);
+ infoApp.setImmediateFlush(true);
// Add the new appenders
root.addAppender(debugApp);
@@ -86,10 +100,12 @@
// Remove the existing appenders.
for (Enumeration<?> appEnum = root.getAllAppenders(); appEnum.hasMoreElements();) {
final Appender appender = (Appender) appEnum.nextElement();
- if ((appender != debugApp) && (appender != infoApp)) {
+ if (appender != debugApp && appender != infoApp) {
root.removeAppender(appender);
}
}
+ System.err.println("Sending a test log message");
+ root.error("Test log message");
} catch (NameNotFoundException ex) {
root.error("ConsoleManager not found", ex);
}
Modified: trunk/core/src/core/org/jnode/log4j/config/VirtualConsoleAppender.java
===================================================================
--- trunk/core/src/core/org/jnode/log4j/config/VirtualConsoleAppender.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/core/org/jnode/log4j/config/VirtualConsoleAppender.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -21,7 +21,6 @@
package org.jnode.log4j.config;
-import java.io.OutputStreamWriter;
import org.apache.log4j.Layout;
import org.apache.log4j.WriterAppender;
import org.jnode.driver.console.TextConsole;
@@ -38,6 +37,6 @@
*/
public VirtualConsoleAppender(TextConsole console, Layout layout) {
setLayout(layout);
- setWriter(new OutputStreamWriter(console.getOut()));
+ setWriter(console.getOut());
}
}
Modified: trunk/core/src/core/org/jnode/util/Queue.java
===================================================================
--- trunk/core/src/core/org/jnode/util/Queue.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/core/org/jnode/util/Queue.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -27,6 +27,8 @@
* @author epr
*/
public class Queue<T> {
+
+ public static final int NO_WAIT = -1;
/**
* The actual queue
@@ -47,7 +49,7 @@
*/
public synchronized T get(boolean ignoreInteruptions, long timeout) {
while (queue.isEmpty()) {
- if (closed) {
+ if (closed || timeout == NO_WAIT) {
return null;
}
try {
@@ -62,7 +64,6 @@
return null;
}
}
- //T result = queue.get(0);
return queue.remove(0);
}
Added: trunk/core/src/core/org/jnode/util/ReaderInputStream.java
===================================================================
--- trunk/core/src/core/org/jnode/util/ReaderInputStream.java (rev 0)
+++ trunk/core/src/core/org/jnode/util/ReaderInputStream.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -0,0 +1,147 @@
+/*
+ * $Id: ThreadCommandInvoker.java 3374 2007-08-02 18:15:27Z lsantha $
+ *
+ * JNode.org
+ * Copyright (C) 2007 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jnode.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+
+/**
+ * This class wraps a Reader with the InputStream API. It is used internally
+ * by the JNode shell, and is not recommended for general use.
+ *
+ * @author cr...@jn...
+ */
+public class ReaderInputStream extends InputStream {
+ private final Reader reader;
+
+ private CharBuffer chars = CharBuffer.allocate(1024);
+ private ByteBuffer bytes = ByteBuffer.allocate(2048);
+
+ private CharsetEncoder encoder;
+
+ public ReaderInputStream(Reader reader) {
+ this(reader, Charset.defaultCharset().name());
+ }
+
+ public ReaderInputStream(Reader reader, String encoding) {
+ this.reader = reader;
+ this.encoder = Charset.forName(encoding).newEncoder();
+ this.bytes.position(bytes.limit());
+ this.chars.position(chars.limit());
+ }
+
+ @Override
+ public synchronized int read() throws IOException {
+ if (bytes.remaining() == 0) {
+ if (fillBuffer(true) == -1) {
+ return -1;
+ }
+ }
+ return bytes.get();
+ }
+
+ @Override
+ public synchronized int read(byte[] b, int off, int len) throws IOException {
+ if (off < 0 || off > b.length || len < 0 || off + len > b.length || off + len < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ // This implementation is simple-minded. I'm sure we could recode it to avoid
+ // the 'bytes.get' copying step if we thought about it.
+ int count = 0;
+ do {
+ if (bytes.remaining() == 0) {
+ int nosRead = fillBuffer(count == 0);
+ if (nosRead <= 0) {
+ return count > 0 ? count : -1;
+ }
+ }
+ int toCopy = Math.min(bytes.remaining(), len);
+ bytes.get(b, off, toCopy);
+ count += toCopy;
+ len -= toCopy;
+ off += toCopy;
+ } while (count < len);
+ return count;
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ return this.read(b, 0, b.length);
+ }
+
+ /**
+ * This method puts bytes into the (empty) 'bytes' buffer. It returns
+ * <code>false</code> if no bytes were copied either because the reader
+ * would have blocked or because it returned <code>-1</code>.
+ *
+ * @param wait if <code>true</code> allow the reader to block.
+ * @return the number of bytes added; <code>-1</code> if none were added
+ * and the reader is at the EOF.
+ * @throws IOException
+ */
+ private int fillBuffer(boolean wait) throws IOException {
+ bytes.clear();
+ // The loop is necessary because of the way that an encoder has to deal
+ // with UTF-16 surrogate pairs.
+ CoderResult cr = null;
+ int count;
+ do {
+ if (chars.remaining() == 0 || cr == CoderResult.UNDERFLOW) {
+ if (chars.remaining() == 0) {
+ if (!reader.ready() && !wait) {
+ bytes.flip();
+ return 0;
+ }
+ chars.clear();
+ } else {
+ char[] tmp = new char[chars.remaining()];
+ chars.get(tmp);
+ chars.clear();
+ chars.put(tmp);
+ }
+ if (reader.read(chars) == -1) {
+ chars.flip();
+ cr = encoder.encode(chars, bytes, true);
+ if (cr.isError()) {
+ cr.throwException();
+ }
+ count = bytes.position();
+ bytes.flip();
+ return count > 0 ? count : -1;
+ }
+ chars.flip();
+ }
+ cr = encoder.encode(chars, bytes, false);
+ if (cr.isError()) {
+ cr.throwException();
+ }
+ count = bytes.position();
+ } while (wait && count == 0);
+ bytes.flip();
+ return count;
+ }
+}
Added: trunk/core/src/core/org/jnode/util/WriterOutputStream.java
===================================================================
--- trunk/core/src/core/org/jnode/util/WriterOutputStream.java (rev 0)
+++ trunk/core/src/core/org/jnode/util/WriterOutputStream.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -0,0 +1,124 @@
+/*
+ * $Id: ShellManager.java 3571 2007-10-26 21:30:12Z lsantha $
+ *
+ * JNode.org
+ * Copyright (C) 2003-2006 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jnode.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+
+/**
+ * This class wraps a Writer with the OutputStream API. It is used internally
+ * by the JNode shell, and is not recommended for general use.
+ *
+ * @author cr...@jn...
+ */
+public class WriterOutputStream extends OutputStream {
+
+ private ByteBuffer bytes = ByteBuffer.allocate(2048);
+ private CharBuffer chars = CharBuffer.allocate(2048);
+
+ private Writer writer;
+ private CharsetDecoder decoder;
+
+ public WriterOutputStream(Writer writer) {
+ this(writer, Charset.defaultCharset().name());
+ }
+
+ public WriterOutputStream(Writer writer, String encoding) {
+ this.writer = writer;
+ this.decoder = Charset.forName(encoding).newDecoder();
+ bytes.clear();
+ chars.clear();
+ }
+
+ @Override
+ public synchronized void write(int b) throws IOException {
+ bytes.put((byte) b);
+ if (bytes.remaining() == 0) {
+ flush(false);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ flush(false);
+ writer.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ flush(true);
+ writer.close();
+ }
+
+ private synchronized int flush(boolean all) throws IOException {
+ if (bytes.position() > 0) {
+ bytes.flip();
+ chars.clear();
+ CoderResult cr = decoder.decode(bytes, chars, all);
+ int count = chars.position();
+ if (count > 0) {
+ int pos = chars.arrayOffset();
+ writer.write(chars.array(), pos, count);
+ }
+ if (cr.isError() || (all && cr == CoderResult.UNDERFLOW)) {
+ cr.throwException();
+ }
+ if (bytes.remaining() > 0) {
+ byte[] tmp = new byte[bytes.remaining()];
+ bytes.get(tmp);
+ bytes.clear();
+ bytes.put(tmp);
+ } else {
+ bytes.clear();
+ }
+ return count;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public synchronized void write(byte[] b, int off, int len) throws IOException {
+ if (off < 0 || off > b.length || len < 0 || off + len > b.length || off + len < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ while (len > 0) {
+ int toWrite = Math.min(len, bytes.remaining());
+ bytes.put(b, off, toWrite);
+ off += toWrite;
+ len -= toWrite;
+ if (bytes.remaining() == 0) {
+ flush(false);
+ }
+ }
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ this.write(b, 0, b.length);
+ }
+}
Deleted: trunk/core/src/driver/org/jnode/driver/console/ConsoleInputStream.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/ConsoleInputStream.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/driver/org/jnode/driver/console/ConsoleInputStream.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -1,87 +0,0 @@
-/*
- * $Id$
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 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 Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-package org.jnode.driver.console;
-
-import java.io.IOException;
-import java.io.InputStream;
-import org.jnode.driver.input.KeyboardEvent;
-import org.jnode.driver.input.KeyboardListener;
-import org.jnode.util.Queue;
-
-/**
- * @author epr
- */
-public class ConsoleInputStream extends InputStream implements KeyboardListener {
-
- private final Queue<KeyboardEvent> queue = new Queue<KeyboardEvent>();
- private boolean echo = false;
-
- public ConsoleInputStream(Console console) {
- console.addKeyboardListener(this);
- }
-
- /**
- * @return Available bytes
- * @throws IOException
- * @see java.io.InputStream#available()
- */
- public int available() throws IOException {
- return queue.size();
- }
-
- /**
- * @return int
- * @throws IOException
- * @see java.io.InputStream#read()
- */
- public int read() throws IOException {
- while (true) {
- KeyboardEvent event = (KeyboardEvent) queue.get();
- if (!event.isConsumed()) {
- event.consume();
- char ch = event.getKeyChar();
- if (ch != 0) {
- if (echo) {
- System.out.print(ch);
- }
- return ch;
- }
- }
- }
- }
-
- /**
- * @param event
- * @see org.jnode.driver.input.KeyboardListener#keyPressed(org.jnode.driver.input.KeyboardEvent)
- */
- public void keyPressed(KeyboardEvent event) {
- //log.debug("got event(" + event + ")");
- queue.add(event);
- }
-
- /**
- * @param event
- * @see org.jnode.driver.input.KeyboardListener#keyReleased(org.jnode.driver.input.KeyboardEvent)
- */
- public void keyReleased(KeyboardEvent event) {
- }
-}
Modified: trunk/core/src/driver/org/jnode/driver/console/TextConsole.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/TextConsole.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/driver/org/jnode/driver/console/TextConsole.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -21,8 +21,8 @@
package org.jnode.driver.console;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
/**
* @author Ewout Prangsma (ep...@us...)
@@ -155,25 +155,27 @@
public void setTabSize(int tabSize);
/**
- * Gets the input stream of this console.
+ * Gets the Reader that delivers input characters from this console. These
+ * characters are the result of processing keyboard events, performing line
+ * editing and completion.
*
* @return
*/
- public InputStream getIn();
+ public Reader getIn();
/**
- * Gets the error stream of this console.
+ * Gets the Writer that receives 'error' output for this console.
*
* @return
*/
- public OutputStream getErr();
+ public Writer getErr();
/**
- * Gets the output stream of this console.
+ * Gets the Writer that receives 'normal' output for this console.
*
* @return
*/
- public OutputStream getOut();
+ public Writer getOut();
/**
* Is the cursor visible.
@@ -196,7 +198,7 @@
public InputCompleter getCompleter();
/**
- * Ges the console's input completer
+ * Set the console's input completer
*
* @param The new completer or <code>null</code>.
*/
Deleted: trunk/core/src/driver/org/jnode/driver/console/spi/ConsoleOutputStream.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/spi/ConsoleOutputStream.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/driver/org/jnode/driver/console/spi/ConsoleOutputStream.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -1,94 +0,0 @@
-/*
- * $Id$
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 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 Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-package org.jnode.driver.console.spi;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.jnode.driver.console.TextConsole;
-
-/**
- * @author epr
- * @author Levente S\u00e1ntha (ls...@us...)
- */
-public class ConsoleOutputStream extends OutputStream {
-
- private static final int BUFFER_SIZE = 160;
- private final char[] buffer = new char[BUFFER_SIZE];
- private TextConsole console;
- private int fgColor;
-
-
- /**
- * Create a new instance
- *
- * @param console
- * @param fgColor
- */
- public ConsoleOutputStream(TextConsole console, int fgColor) {
- this.console = console;
- this.fgColor = fgColor;
- }
-
- /**
- * @param b
- * @throws IOException
- * @see java.io.OutputStream#write(int)
- */
- public void write(int b) throws IOException {
- console.putChar((char) b, fgColor);
- }
-
- public void write(byte[] b, int off, int len)
- throws IOException, NullPointerException, IndexOutOfBoundsException {
- if (off < 0 || len < 0 || off + len > b.length)
- throw new ArrayIndexOutOfBoundsException();
-
- int bi = 0;
- for (int i = 0; i < len; ++i) {
- if (bi >= BUFFER_SIZE) {
- console.putChar(buffer, 0, BUFFER_SIZE, fgColor);
- bi = 0;
- }
- buffer[bi++] = (char) b[off + i];
- }
-
- console.putChar(buffer, 0, bi, fgColor);
- }
-
-
- /**
- * @return int
- */
- public int getFgColor() {
- return fgColor;
- }
-
- /**
- * Sets the fgColor.
- *
- * @param fgColor The fgColor to set
- */
- public void setFgColor(int fgColor) {
- this.fgColor = fgColor;
- }
-
-}
Deleted: trunk/core/src/driver/org/jnode/driver/console/spi/ConsolePrintStream.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/spi/ConsolePrintStream.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/driver/org/jnode/driver/console/spi/ConsolePrintStream.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -1,17 +0,0 @@
-package org.jnode.driver.console.spi;
-
-import java.io.PrintStream;
-
-public class ConsolePrintStream extends PrintStream {
- public ConsolePrintStream(ConsoleOutputStream out) {
- super(out);
- }
-
- public int getFgColor() {
- return ((ConsoleOutputStream) out).getFgColor();
- }
-
- public void setFgColor(int color) {
- ((ConsoleOutputStream) out).setFgColor(color);
- }
-}
Added: trunk/core/src/driver/org/jnode/driver/console/spi/ConsoleWriter.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/spi/ConsoleWriter.java (rev 0)
+++ trunk/core/src/driver/org/jnode/driver/console/spi/ConsoleWriter.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -0,0 +1,98 @@
+/*
+ * $Id: ConsoleOutputStream.java 4153 2008-05-30 12:20:45Z lsantha $
+ *
+ * JNode.org
+ * Copyright (C) 2003-2006 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package org.jnode.driver.console.spi;
+
+import java.io.IOException;
+import java.io.Writer;
+import org.jnode.driver.console.TextConsole;
+
+/**
+ * @author epr
+ * @author Levente S\u00e1ntha (ls...@us...)
+ */
+public class ConsoleWriter extends Writer {
+
+ private static final int BUFFER_SIZE = 160;
+ private final char[] buffer = new char[BUFFER_SIZE];
+ private TextConsole console;
+ private int fgColor;
+
+
+ /**
+ * Create a new instance
+ *
+ * @param console
+ * @param fgColor
+ */
+ public ConsoleWriter(TextConsole console, int fgColor) {
+ this.console = console;
+ this.fgColor = fgColor;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ console.putChar((char) b, fgColor);
+ }
+
+ public void write(char[] cbuf, int off, int len)
+ throws IOException, NullPointerException, IndexOutOfBoundsException {
+ if (off < 0 || len < 0 || off + len > cbuf.length)
+ throw new ArrayIndexOutOfBoundsException();
+
+ int bi = 0;
+ for (int i = 0; i < len; ++i) {
+ if (bi >= BUFFER_SIZE) {
+ console.putChar(buffer, 0, BUFFER_SIZE, fgColor);
+ bi = 0;
+ }
+ buffer[bi++] = (char) cbuf[off + i];
+ }
+
+ console.putChar(buffer, 0, bi, fgColor);
+ }
+
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ /**
+ * @return int
+ */
+ public int getFgColor() {
+ return fgColor;
+ }
+
+ /**
+ * Sets the fgColor.
+ *
+ * @param fgColor The fgColor to set
+ */
+ public void setFgColor(int fgColor) {
+ this.fgColor = fgColor;
+ }
+
+}
Deleted: trunk/core/src/driver/org/jnode/driver/console/textscreen/KeyboardInputStream.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/textscreen/KeyboardInputStream.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/driver/org/jnode/driver/console/textscreen/KeyboardInputStream.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -1,390 +0,0 @@
-package org.jnode.driver.console.textscreen;
-
-import java.awt.event.KeyEvent;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-
-import org.jnode.driver.console.InputCompleter;
-import org.jnode.driver.console.TextConsole;
-import org.jnode.driver.input.KeyboardEvent;
-import org.jnode.system.event.FocusEvent;
-import org.jnode.system.event.FocusListener;
-
-
-/**
- * KeyInputStream maps keyboard events into a stream of characters. Current functionality includes:
- * <ul>
- * <li>line buffering and line editing, using a text console,
- * <li>integrated input history and completion,
- * <li>CTRL-D is interpretted as a 'soft' EOF mark,KeyboardInputStream
- * <li>listens to keyboard focus events.
- * </ul>
- * <p/>
- * Future enhancements include:
- * <ul>
- * <li>a "raw" mode in which characters and other keyboard events are delivered without line editing,
- * <li>a "no echo" mode in which line editting occurs without echoing of input characters,
- * <li>making the active characters and keycodes "soft",
- * <li>making completion and history context sensitive; e.g. when switching between a shell and
- * an application, and
- * <li>code refactoring to support classical terminal devices and remote consoles.
- * </ul>
- * <p/>
- * Bugs:
- * <ul>
- * <li>The current method of echoing the input is suboptimal, and is broken in the case where an
- * application outputs a prompt string to stdout or stderr.
- * </ul>
- *
- * @author cr...@jn...
- */
-public class KeyboardInputStream extends InputStream
- implements FocusListener {
-
- public static final byte CTRL_L = 12;
- public static final byte CTRL_D = 4;
-
- private boolean eof;
-
- private byte[] buffer;
- private int pos;
- private int lim;
-
- private static final char NO_CHAR = 0;
-
- private final Line currentLine;
- private final TextConsole console;
- private InputCompleter completer;
- private final PrintStream out;
-
- private String currentPrompt;
-
- /**
- * Contains an index to the current history line, counting from zero. The
- * value -1 denotes the current line.
- */
- private int historyIndex = -1;
-
- /**
- * Contains the current line; i.e. the text being entered by the user.
- */
- private String savedCurrentLine;
-
- private final KeyboardHandler keyboardHandler;
- private final FocusListener focusListener;
-
- public KeyboardInputStream(KeyboardHandler kbHandler, TextConsole console) {
- this.keyboardHandler = kbHandler;
- this.console = console;
- this.out = new PrintStream(console.getOut());
- this.currentLine = new Line(console);
- this.pos = this.lim = 0;
-
- if (keyboardHandler instanceof FocusListener) {
- this.focusListener = (FocusListener) keyboardHandler;
- } else {
- this.focusListener = null;
- }
- }
-
- public boolean isSoftEOF() {
- return eof;
- }
-
- public void clearSoftEOF() {
- eof = false;
- }
-
- @Override
- public int available() throws IOException {
- if (eof) {
- return 0; /* per the JDK 1.6 API docs */
- } else {
- // FIXME - what about the case where the line buffer is empty
- // and there are unconsumed input events in the queue?
- return currentLine.getLineLength();
- }
- }
-
- /**
- * @see java.io.InputStream#close()
- */
- public void close() throws IOException {
- keyboardHandler.close();
- super.close();
- }
-
- /**
- * Pull a keyboard event from the queue and process it.
- *
- * @return true if the event was processed
- */
- private boolean processEvent() {
- KeyboardEvent event = keyboardHandler.getEvent();
- if (!event.isConsumed()) {
- char ch = event.getKeyChar();
- if (ch != NO_CHAR) {
- event.consume();
- return !processChar(ch);
- } else {
- int kc = event.getKeyCode();
- int mods = event.getModifiers();
- if (processVirtualKeystroke(kc, mods)) {
- event.consume();
- }
- return true;
- }
- } else {
- return true;
- }
- }
-
- /**
- * Process a keystroke interpretted as a character.
- *
- * @param ch the character to process
- * @return <code>true</code> if the character should cause the current
- * line buffer contents to be returned to the user.
- */
- private boolean processChar(char ch) {
- boolean breakChar = false;
- switch (ch) {
- // if its a backspace we want to remove one from the end of our
- // current
- // line
- case KeyEvent.VK_BACK_SPACE:
- if (currentLine.backspace()) {
- refreshCurrentLine();
- }
- break;
- // if its an enter key we want to process the command, and then
- // resume
- // the thread
- case '\n':
- currentLine.moveEnd();
- refreshCurrentLine();
- out.println();
- currentLine.appendChar(ch);
- breakChar = true;
- historyIndex = -1;
- break;
- // if it's the tab key, we want to trigger command line completion
- case '\t':
- if (completer != null) {
- if (currentLine.complete()) {
- currentLine.start(true);
- }
- out.print(currentPrompt);
- refreshCurrentLine();
- }
- break;
- // interpret ^D as a soft EOF
- // FIXME - behavior correct? cf bash's treatment of ^D
- case CTRL_D:
- currentLine.moveEnd();
- refreshCurrentLine();
- out.println();
- eof = true;
- breakChar = true;
- break;
- // ^L means kill current line and redraw screen.
- // FIXME - is this behavior useful?
- case CTRL_L:
- this.console.clear();
- this.console.setCursor(0, 0);
- out.print(currentPrompt);
- currentLine.start();
- refreshCurrentLine();
- break;
- default:
- // otherwise add it to our current line
- currentLine.appendChar(ch);
- refreshCurrentLine();
- historyIndex = -1;
- }
- return breakChar;
- }
-
- /**
- * Process a keystroke that doesn't have an associated char value.
- *
- * @param code key code
- * @param modifiers key modifiers
- * @return <code>true</code> if the keystroke has been recognized and
- * acted on, <code>false</code> otherwise.
- */
- private boolean processVirtualKeystroke(int code, int modifiers) {
- if (modifiers != 0) {
- return false;
- }
- switch (code) {
- case KeyEvent.VK_UP:
- // Previous history item
- if (completer != null) {
- if (historyIndex == -1) {
- historyIndex = completer.getInputHistory().size();
- savedCurrentLine = currentLine.getContent();
- }
- historyIndex--;
-
- updateCurrentLine();
- }
- break;
- case KeyEvent.VK_DOWN:
- // Next history item
- if (completer != null) {
- if (historyIndex == -1)
- savedCurrentLine = currentLine.getContent();
-
- if (historyIndex == completer.getInputHistory().size() - 1)
- historyIndex = -2;
-
- historyIndex++;
-
- updateCurrentLine();
-
- }
- break;
- case KeyEvent.VK_LEFT:
- // Left the cursor goes left
- if (currentLine.moveLeft()) {
- refreshCurrentLine();
- }
- break;
- case KeyEvent.VK_RIGHT:
- // Right the cursor goes right
- if (currentLine.moveRight()) {
- refreshCurrentLine();
- }
- break;
- case KeyEvent.VK_HOME:
- // The cursor goes at the start
- currentLine.moveBegin();
- refreshCurrentLine();
- break;
- case KeyEvent.VK_END:
- // the cursor goes at the end of line
- currentLine.moveEnd();
- refreshCurrentLine();
- break;
- // if its a delete we want to remove one under the cursor
- case KeyEvent.VK_DELETE:
- currentLine.delete();
- refreshCurrentLine();
- break;
- default:
- // ignore other virtual keys.
- return false;
- }
- return true;
- }
-
- private void updateCurrentLine() {
- if (historyIndex > -1) {
- currentLine.setContent(completer.getInputHistory().getLineAt(historyIndex));
- } else {
- currentLine.setContent(savedCurrentLine);
- }
- refreshCurrentLine();
- currentLine.moveEnd();
- }
-
- private void refreshCurrentLine() {
- currentLine.refreshCurrentLine();
- }
-
- private boolean fillBuffer() throws IOException {
- int x = console.getCursorX();
- int y = console.getCursorY();
- StringBuffer sb = new StringBuffer(x);
- for (int i = 0; i < x; i++) {
- sb.append(console.getChar(i, y));
- }
- currentPrompt = sb.toString();
-
- currentLine.start();
- while (processEvent()) { /* */
- }
- buffer = currentLine.consumeBytes();
- lim = buffer.length;
- pos = 0;
- return pos < lim;
- }
-
- @Override
- public int read() throws IOException {
- if (pos >= lim) {
- if (eof || !fillBuffer()) {
- return -1;
- }
- }
- return buffer[pos++];
- }
-
- @Override
- public int read(byte[] buff, int off, int len) throws IOException {
- int nosRead = 0;
- if (pos >= lim) {
- if (eof || !fillBuffer()) {
- return -1;
- }
- }
- while (nosRead < len && pos < lim) {
- buff[nosRead + off] = buffer[pos];
- nosRead++;
- pos++;
- }
- return nosRead;
- }
-
- @Override
- public int read(byte[] buff) throws IOException {
- return read(buff, 0, buff.length);
- }
-
- @Override
- public void mark(int readLimit) {
- }
-
- @Override
- public boolean markSupported() {
- return false;
- }
-
- @Override
- public void reset() throws IOException {
- throw new UnsupportedOperationException("Mark/reset not supported");
- }
-
- @Override
- public long skip(long n) throws IOException {
- // I don't expect this method will be used much.
- for (long i = 0; i < n; i++) {
- if (read() == -1) {
- return i;
- }
- }
- return n;
- }
-
- public InputCompleter getCompleter() {
- return completer;
- }
-
- public void setCompleter(InputCompleter completer) {
- this.completer = completer;
- }
-
- public void focusGained(FocusEvent event) {
- if (focusListener != null) {
- focusListener.focusGained(event);
- }
- }
-
- public void focusLost(FocusEvent event) {
- if (focusListener != null) {
- focusListener.focusLost(event);
- }
- }
-}
Added: trunk/core/src/driver/org/jnode/driver/console/textscreen/KeyboardReader.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/textscreen/KeyboardReader.java (rev 0)
+++ trunk/core/src/driver/org/jnode/driver/console/textscreen/KeyboardReader.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -0,0 +1,385 @@
+package org.jnode.driver.console.textscreen;
+
+import java.awt.event.KeyEvent;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.PrintStream;
+import java.io.Writer;
+
+import org.jnode.driver.console.InputCompleter;
+import org.jnode.driver.console.TextConsole;
+import org.jnode.driver.input.KeyboardEvent;
+import org.jnode.system.event.FocusEvent;
+import org.jnode.system.event.FocusListener;
+
+
+/**
+ * KeyboardInputStream maps keyboard events into a stream of characters. Current functionality includes:
+ * <ul>
+ * <li>line buffering and line editing, using a text console,
+ * <li>integrated input history and completion,
+ * <li>CTRL-D is interpreted as a 'soft' EOF mark,KeyboardInputStream
+ * <li>listens to keyboard focus events.
+ * </ul>
+ * <p/>
+ * Future enhancements include:
+ * <ul>
+ * <li>a "raw" mode in which characters and other keyboard events are delivered without line editing,
+ * <li>a "no echo" mode in which line editing occurs without echoing of input characters,
+ * <li>making the active characters and keycodes "soft",
+ * <li>making completion and history context sensitive; e.g. when switching between a shell and
+ * an application, and
+ * <li>code refactoring to support classical terminal devices and remote consoles.
+ * </ul>
+ * <p/>
+ * Bugs:
+ * <ul>
+ * <li>The current method of echoing the input is suboptimal, and is broken in the case where an
+ * application outputs a prompt string to stdout or stderr.
+ * </ul>
+ *
+ * @author cr...@jn...
+ */
+public class KeyboardReader extends Reader
+ implements FocusListener {
+
+ public static final byte CTRL_L = 12;
+ public static final byte CTRL_D = 4;
+
+ private boolean eof;
+
+ private char[] buffer;
+ private int pos;
+ private int lim;
+
+ private static final char NO_CHAR = 0;
+
+ private final Line currentLine;
+ private final TextConsole console;
+ private InputCompleter completer;
+ private final Writer out;
+
+ private String currentPrompt;
+
+ /**
+ * Contains an index to the current history line, counting from zero. The
+ * value -1 denotes the current line.
+ */
+ private int historyIndex = -1;
+
+ /**
+ * Contains the current line; i.e. the text being entered by the user.
+ */
+ private String savedCurrentLine;
+
+ private final KeyboardHandler keyboardHandler;
+ private final FocusListener focusListener;
+
+ public KeyboardReader(KeyboardHandler kbHandler, TextConsole console) {
+ this.keyboardHandler = kbHandler;
+ this.console = console;
+ this.out = console.getOut();
+ this.currentLine = new Line(console);
+ this.pos = this.lim = 0;
+
+ if (keyboardHandler instanceof FocusListener) {
+ this.focusListener = (FocusListener) keyboardHandler;
+ } else {
+ this.focusListener = null;
+ }
+ }
+
+ public boolean isSoftEOF() {
+ return eof;
+ }
+
+ public void clearSoftEOF() {
+ eof = false;
+ }
+
+ @Override
+ public boolean ready() throws IOException {
+ return eof || currentLine.getLineLength() > 0;
+ }
+
+ /**
+ * @see java.io.Reader#close()
+ */
+ public void close() throws IOException {
+ keyboardHandler.close();
+ }
+
+ /**
+ * Pull a keyboard event from the queue and process it.
+ *
+ * @return true if the event was processed
+ */
+ private boolean processEvent() throws IOException {
+ KeyboardEvent event = keyboardHandler.getEvent();
+ if (!event.isConsumed()) {
+ char ch = event.getKeyChar();
+ if (ch != NO_CHAR) {
+ event.consume();
+ return !processChar(ch);
+ } else {
+ int kc = event.getKeyCode();
+ int mods = event.getModifiers();
+ if (processVirtualKeystroke(kc, mods)) {
+ event.consume();
+ }
+ return true;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Process a keystroke interpreted as a character.
+ *
+ * @param ch the character to process
+ * @return <code>true</code> if the character should cause the current
+ * line buffer contents to be returned to the user.
+ */
+ private boolean processChar(char ch) throws IOException {
+ boolean breakChar = false;
+ switch (ch) {
+ // if its a backspace we want to remove one from the end of our
+ // current
+ // line
+ case KeyEvent.VK_BACK_SPACE:
+ if (currentLine.backspace()) {
+ refreshCurrentLine();
+ }
+ break;
+ // if its an enter key we want to process the command, and then
+ // resume
+ // the thread
+ case '\n':
+ currentLine.moveEnd();
+ refreshCurrentLine();
+ out.write('\n');
+ currentLine.appendChar(ch);
+ breakChar = true;
+ historyIndex = -1;
+ break;
+ // if it's the tab key, we want to trigger command line completion
+ case '\t':
+ if (completer != null) {
+ if (currentLine.complete()) {
+ currentLine.start(true);
+ }
+ out.write(currentPrompt);
+ refreshCurrentLine();
+ }
+ break;
+ // interpret ^D as a soft EOF
+ // FIXME - behavior correct? cf bash's treatment of ^D
+ case CTRL_D:
+ currentLine.moveEnd();
+ refreshCurrentLine();
+ out.write('\n');
+ eof = true;
+ breakChar = true;
+ break;
+ // ^L means kill current line and redraw screen.
+ // FIXME - is this behavior useful?
+ case CTRL_L:
+ this.console.clear();
+ this.console.setCursor(0, 0);
+ out.write(currentPrompt);
+ currentLine.start();
+ refreshCurrentLine();
+ break;
+ default:
+ // otherwise add it to our current line
+ currentLine.appendChar(ch);
+ refreshCurrentLine();
+ historyIndex = -1;
+ }
+ return breakChar;
+ }
+
+ /**
+ * Process a keystroke that doesn't have an associated char value.
+ *
+ * @param code key code
+ * @param modifiers key modifiers
+ * @return <code>true</code> if the keystroke has been recognized and
+ * acted on, <code>false</code> otherwise.
+ * @throws IOException
+ */
+ private boolean processVirtualKeystroke(int code, int modifiers) throws IOException {
+ if (modifiers != 0) {
+ return false;
+ }
+ switch (code) {
+ case KeyEvent.VK_UP:
+ // Previous history item
+ if (completer != null) {
+ if (historyIndex == -1) {
+ historyIndex = completer.getInputHistory().size();
+ savedCurrentLine = currentLine.getContent();
+ }
+ historyIndex--;
+
+ updateCurrentLine();
+ }
+ break;
+ case KeyEvent.VK_DOWN:
+ // Next history item
+ if (completer != null) {
+ if (historyIndex == -1)
+ savedCurrentLine = currentLine.getContent();
+
+ if (historyIndex == completer.getInputHistory().size() - 1)
+ historyIndex = -2;
+
+ historyIndex++;
+
+ updateCurrentLine();
+
+ }
+ break;
+ case KeyEvent.VK_LEFT:
+ // Left the cursor goes left
+ if (currentLine.moveLeft()) {
+ refreshCurrentLine();
+ }
+ break;
+ case KeyEvent.VK_RIGHT:
+ // Right the cursor goes right
+ if (currentLine.moveRight()) {
+ refreshCurrentLine();
+ }
+ break;
+ case KeyEvent.VK_HOME:
+ // The cursor goes at the start
+ currentLine.moveBegin();
+ refreshCurrentLine();
+ break;
+ case KeyEvent.VK_END:
+ // the cursor goes at the end of line
+ currentLine.moveEnd();
+ refreshCurrentLine();
+ break;
+ // if its a delete we want to remove one under the cursor
+ case KeyEvent.VK_DELETE:
+ currentLine.delete();
+ refreshCurrentLine();
+ break;
+ default:
+ // ignore other virtual keys.
+ return false;
+ }
+ return true;
+ }
+
+ private void updateCurrentLine() throws IOException {
+ if (historyIndex > -1) {
+ currentLine.setContent(completer.getInputHistory().getLineAt(historyIndex));
+ } else {
+ currentLine.setContent(savedCurrentLine);
+ }
+ refreshCurrentLine();
+ currentLine.moveEnd();
+ }
+
+ private void refreshCurrentLine() throws IOException {
+ currentLine.refreshCurrentLine();
+ }
+
+ private boolean fillBuffer() throws IOException {
+ int x = console.getCursorX();
+ int y = console.getCursorY();
+ StringBuffer sb = new StringBuffer(x);
+ for (int i = 0; i < x; i++) {
+ sb.append(console.getChar(i, y));
+ }
+ currentPrompt = sb.toString();
+
+ currentLine.start();
+ while (processEvent()) { /* */
+ }
+ buffer = currentLine.consumeChars();
+ lim = buffer.length;
+ pos = 0;
+ return pos < lim;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (pos >= lim) {
+ if (eof || !fillBuffer()) {
+ return -1;
+ }
+ }
+ return buffer[pos++];
+ }
+
+ @Override
+ public int read(char[] buff, int off, int len) throws IOException {
+ int nosRead = 0;
+ if (pos >= lim) {
+ if (eof || !fillBuffer()) {
+ return -1;
+ }
+ }
+ while (nosRead < len && pos < lim) {
+ buff[nosRead + off] = buffer[pos];
+ nosRead++;
+ pos++;
+ }
+ return nosRead;
+ }
+
+ @Override
+ public int read(char[] buff) throws IOException {
+ return read(buff, 0, buff.length);
+ }
+
+ @Override
+ public void mark(int readLimit) {
+ }
+
+ @Override
+ public boolean markSupported() {
+ return false;
+ }
+
+ @Override
+ public void reset() throws IOException {
+ throw new UnsupportedOperationException("Mark/reset not supported");
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ // I don't expect this method will be used much.
+ for (long i = 0; i < n; i++) {
+ if (read() == -1) {
+ return i;
+ }
+ }
+ return n;
+ }
+
+ public InputCompleter getCompleter() {
+ return completer;
+ }
+
+ public void setCompleter(InputCompleter completer) {
+ this.completer = completer;
+ }
+
+ public void focusGained(FocusEvent event) {
+ if (focusListener != null) {
+ focusListener.focusGained(event);
+ }
+ }
+
+ public void focusLost(FocusEvent event) {
+ if (focusListener != null) {
+ focusListener.focusLost(event);
+ }
+ }
+}
Modified: trunk/core/src/driver/org/jnode/driver/console/textscreen/Line.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/textscreen/Line.java 2008-09-11 18:40:09 UTC (rev 4555)
+++ trunk/core/src/driver/org/jnode/driver/console/textscreen/Line.java 2008-09-13 08:02:20 UTC (rev 4556)
@@ -21,13 +21,14 @@
package org.jnode.driver.console.textscreen;
+import java.io.IOException;
import java.util.Arrays;
import java.util.SortedSet;
import org.jnode.driver.console.CompletionInfo;
import org.jnode.driver.console.InputCompleter;
import org.jnode.driver.console.ScrollableTextConsole;
import org.jnode.driver.console.TextConsole;
-import org.jnode.driver.console.spi.ConsolePrintStream;
+import org.jnode.driver.console.spi.ConsoleWriter;
/**
@@ -68,11 +69,11 @@
private final TextConsole console;
- private ConsolePrintStream out;
+ private ConsoleWriter out;
public Line(TextConsole console) {
this.console = console;
- this.out = (ConsolePrintStream) console.getOut();
+ this.out = (ConsoleWriter) console.getOut();
}
public void start() {
@@ -101,12 +102,14 @@
return currentLine.toString();
}
- public byte[] getBytes() {
- return currentLine.toString().getBytes();
+ public char[] getChars() {
+ char[] res = new char[currentLine.length()];
+ currentLine.getChars(0, currentLine.length(), res, 0);
+ return res;
}
- public byte[] consumeBytes() {
- byte[] res = getBytes();
+ public char[] consumeChars() {
+ char[] res = getChars();
currentLine.setLength(0);
return res;
}
@@ -161,7 +164,7 @@
}
}
- public boolean complete() {
+ public boolean complete() throws IOException {
CompletionInfo info = null;
InputCompleter completer...
[truncated message content] |