X-Git-Url: http://git.nikiroo.be/?p=jvcard.git;a=blobdiff_plain;f=src%2Fcom%2Fgooglecode%2Flanterna%2Fterminal%2Fansi%2FUnixLikeTerminal.java;fp=src%2Fcom%2Fgooglecode%2Flanterna%2Fterminal%2Fansi%2FUnixLikeTerminal.java;h=0000000000000000000000000000000000000000;hp=7e99ebe9e493130397fedd08e9396e8c4dbd2f74;hb=f06c81000632cfb5f525ca458f719338f55f9f66;hpb=a73a906356c971b080c36368e71a15d87e8b8d31 diff --git a/src/com/googlecode/lanterna/terminal/ansi/UnixLikeTerminal.java b/src/com/googlecode/lanterna/terminal/ansi/UnixLikeTerminal.java deleted file mode 100644 index 7e99ebe..0000000 --- a/src/com/googlecode/lanterna/terminal/ansi/UnixLikeTerminal.java +++ /dev/null @@ -1,224 +0,0 @@ -package com.googlecode.lanterna.terminal.ansi; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.nio.charset.Charset; - -import com.googlecode.lanterna.input.KeyStroke; - -/** - * UnixLikeTerminal extends from ANSITerminal and defines functionality that is common to - * {@code UnixTerminal} and {@code CygwinTerminal}, like setting tty modes; echo, cbreak - * and minimum characters for reading as well as a shutdown hook to set the tty back to - * original state at the end. - *

- * If requested, it handles Control-C input to terminate the program, and hooks - * into Unix WINCH signal to detect when the user has resized the terminal, - * if supported by the JVM. - * - * @author Andreas - * @author Martin - */ -public abstract class UnixLikeTerminal extends ANSITerminal { - - /** - * This enum lets you control how Lanterna will handle a ctrl+c keystroke from the user. - */ - public enum CtrlCBehaviour { - /** - * Pressing ctrl+c doesn't kill the application, it will be added to the input queue as any other key stroke - */ - TRAP, - /** - * Pressing ctrl+c will restore the terminal and kill the application as it normally does with terminal - * applications. Lanterna will restore the terminal and then call {@code System.exit(1)} for this. - */ - CTRL_C_KILLS_APPLICATION, - } - - protected final CtrlCBehaviour terminalCtrlCBehaviour; - protected final File ttyDev; - private String sttyStatusToRestore; - - /** - * Creates a UnixTerminal using a specified input stream, output stream and character set, with a custom size - * querier instead of using the default one. This way you can override size detection (if you want to force the - * terminal to a fixed size, for example). You also choose how you want ctrl+c key strokes to be handled. - * - * @param terminalInput Input stream to read terminal input from - * @param terminalOutput Output stream to write terminal output to - * @param terminalCharset Character set to use when converting characters to bytes - * @param terminalCtrlCBehaviour Special settings on how the terminal will behave, see {@code UnixTerminalMode} for more - * details - * @param ttyDev File to redirect standard input from in exec(), if not null. - */ - @SuppressWarnings({"SameParameterValue", "WeakerAccess"}) - public UnixLikeTerminal( - InputStream terminalInput, - OutputStream terminalOutput, - Charset terminalCharset, - CtrlCBehaviour terminalCtrlCBehaviour, - File ttyDev) { - super(terminalInput, terminalOutput, terminalCharset); - this.terminalCtrlCBehaviour = terminalCtrlCBehaviour; - this.sttyStatusToRestore = null; - this.ttyDev = ttyDev; - } - - protected String exec(String... cmd) throws IOException { - if (ttyDev != null) { - //Here's what we try to do, but that is Java 7+ only: - // processBuilder.redirectInput(ProcessBuilder.Redirect.from(ttyDev)); - //instead, for Java 6, we join the cmd into a scriptlet with redirection - //and replace cmd by a call to sh with the scriptlet: - StringBuilder sb = new StringBuilder(); - for (String arg : cmd) { sb.append(arg).append(' '); } - sb.append("< ").append(ttyDev); - cmd = new String[] { "sh", "-c", sb.toString() }; - } - ProcessBuilder pb = new ProcessBuilder(cmd); - Process process = pb.start(); - ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream(); - InputStream stdout = process.getInputStream(); - int readByte = stdout.read(); - while(readByte >= 0) { - stdoutBuffer.write(readByte); - readByte = stdout.read(); - } - ByteArrayInputStream stdoutBufferInputStream = new ByteArrayInputStream(stdoutBuffer.toByteArray()); - BufferedReader reader = new BufferedReader(new InputStreamReader(stdoutBufferInputStream)); - StringBuilder builder = new StringBuilder(); - String line; - while((line = reader.readLine()) != null) { - builder.append(line); - } - reader.close(); - return builder.toString(); - } - - @Override - public KeyStroke pollInput() throws IOException { - //Check if we have ctrl+c coming - KeyStroke key = super.pollInput(); - isCtrlC(key); - return key; - } - - @Override - public KeyStroke readInput() throws IOException { - //Check if we have ctrl+c coming - KeyStroke key = super.readInput(); - isCtrlC(key); - return key; - } - - private void isCtrlC(KeyStroke key) throws IOException { - if(key != null - && terminalCtrlCBehaviour == CtrlCBehaviour.CTRL_C_KILLS_APPLICATION - && key.getCharacter() != null - && key.getCharacter() == 'c' - && !key.isAltDown() - && key.isCtrlDown()) { - - exitPrivateMode(); - System.exit(1); - } - } - - protected void setupWinResizeHandler() { - try { - Class signalClass = Class.forName("sun.misc.Signal"); - for(Method m : signalClass.getDeclaredMethods()) { - if("handle".equals(m.getName())) { - Object windowResizeHandler = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Class.forName("sun.misc.SignalHandler")}, new InvocationHandler() { - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if("handle".equals(method.getName())) { - getTerminalSize(); - } - return null; - } - }); - m.invoke(null, signalClass.getConstructor(String.class).newInstance("WINCH"), windowResizeHandler); - } - } - } catch(Throwable e) { - System.err.println(e.getMessage()); - } - } - - protected void setupShutdownHook() { - Runtime.getRuntime().addShutdownHook(new Thread("Lanterna STTY restore") { - @Override - public void run() { - try { - if (isInPrivateMode()) { - exitPrivateMode(); - } - } - catch(IOException ignored) {} - catch(IllegalStateException ignored) {} // still possible! - - try { - restoreSTTY(); - } - catch(IOException ignored) {} - } - }); - } - - /** - * Enabling cbreak mode will allow you to read user input immediately as the user enters the characters, as opposed - * to reading the data in lines as the user presses enter. If you want your program to respond to user input by the - * keyboard, you probably want to enable cbreak mode. - * - * @see POSIX terminal interface - * @param cbreakOn Should cbreak be turned on or not - * @throws IOException - */ - public void setCBreak(boolean cbreakOn) throws IOException { - sttyICanon(!cbreakOn); - } - - /** - * Enables or disables keyboard echo, meaning the immediate output of the characters you type on your keyboard. If - * your users are going to interact with this application through the keyboard, you probably want to disable echo - * mode. - * - * @param echoOn true if keyboard input will immediately echo, false if it's hidden - * @throws IOException - */ - public void setEcho(boolean echoOn) throws IOException { - sttyKeyEcho(echoOn); - } - - protected void saveSTTY() throws IOException { - if(sttyStatusToRestore == null) { - sttyStatusToRestore = sttySave(); - } - } - - protected synchronized void restoreSTTY() throws IOException { - if(sttyStatusToRestore != null) { - sttyRestore( sttyStatusToRestore ); - sttyStatusToRestore = null; - } - } - - // A couple of system-dependent helpers: - protected abstract void sttyKeyEcho(final boolean enable) throws IOException; - protected abstract void sttyMinimum1CharacterForRead() throws IOException; - protected abstract void sttyICanon(final boolean enable) throws IOException; - protected abstract String sttySave() throws IOException; - protected abstract void sttyRestore(String tok) throws IOException; - -} \ No newline at end of file