2 * This file is part of lanterna (http://code.google.com/p/lanterna/).
4 * lanterna is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * Copyright (C) 2010-2015 Martin
19 package com
.googlecode
.lanterna
.terminal
.ansi
;
23 import java
.nio
.charset
.Charset
;
25 import com
.googlecode
.lanterna
.TerminalSize
;
28 * This class extends UnixLikeTerminal and implements the Unix-specific parts.
30 * If you need to have Lanterna to call stty at a different location, you'll need to
31 * subclass this and override {@code getSTTYCommand()}.
35 @SuppressWarnings("WeakerAccess")
36 public class UnixTerminal
extends UnixLikeTerminal
{
38 protected final UnixTerminalSizeQuerier terminalSizeQuerier
;
39 private final boolean catchSpecialCharacters
;
42 * Creates a UnixTerminal with default settings, using System.in and System.out for input/output, using the default
43 * character set on the system as the encoding and trap ctrl+c signal instead of killing the application.
44 * @throws IOException If there was an I/O error initializing the terminal
46 public UnixTerminal() throws IOException
{
47 this(System
.in
, System
.out
, Charset
.defaultCharset());
51 * Creates a UnixTerminal using a specified input stream, output stream and character set. Ctrl+c signal will be
52 * trapped instead of killing the application.
54 * @param terminalInput Input stream to read terminal input from
55 * @param terminalOutput Output stream to write terminal output to
56 * @param terminalCharset Character set to use when converting characters to bytes
57 * @throws java.io.IOException If there was an I/O error initializing the terminal
60 InputStream terminalInput
,
61 OutputStream terminalOutput
,
62 Charset terminalCharset
) throws IOException
{
63 this(terminalInput
, terminalOutput
, terminalCharset
, null);
67 * Creates a UnixTerminal using a specified input stream, output stream and character set, with a custom size
68 * querier instead of using the default one. This way you can override size detection (if you want to force the
69 * terminal to a fixed size, for example). Ctrl+c signal will be trapped instead of killing the application.
71 * @param terminalInput Input stream to read terminal input from
72 * @param terminalOutput Output stream to write terminal output to
73 * @param terminalCharset Character set to use when converting characters to bytes
74 * @param customSizeQuerier Object to use for looking up the size of the terminal, or null to use the built-in
76 * @throws java.io.IOException If there was an I/O error initializing the terminal
78 @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
80 InputStream terminalInput
,
81 OutputStream terminalOutput
,
82 Charset terminalCharset
,
83 UnixTerminalSizeQuerier customSizeQuerier
) throws IOException
{
84 this(terminalInput
, terminalOutput
, terminalCharset
, customSizeQuerier
, CtrlCBehaviour
.CTRL_C_KILLS_APPLICATION
);
88 * Creates a UnixTerminal using a specified input stream, output stream and character set, with a custom size
89 * querier instead of using the default one. This way you can override size detection (if you want to force the
90 * terminal to a fixed size, for example). You also choose how you want ctrl+c key strokes to be handled.
92 * @param terminalInput Input stream to read terminal input from
93 * @param terminalOutput Output stream to write terminal output to
94 * @param terminalCharset Character set to use when converting characters to bytes
95 * @param customSizeQuerier Object to use for looking up the size of the terminal, or null to use the built-in
97 * @param terminalCtrlCBehaviour Special settings on how the terminal will behave, see {@code UnixTerminalMode} for more
99 * @throws java.io.IOException If there was an I/O error initializing the terminal
101 @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
103 InputStream terminalInput
,
104 OutputStream terminalOutput
,
105 Charset terminalCharset
,
106 UnixTerminalSizeQuerier customSizeQuerier
,
107 CtrlCBehaviour terminalCtrlCBehaviour
) throws IOException
{
111 terminalCtrlCBehaviour
,
112 new File("/dev/tty"));
114 this.terminalSizeQuerier
= customSizeQuerier
;
116 //Make sure to set an initial size
119 setupWinResizeHandler();
123 sttyMinimum1CharacterForRead();
124 if("false".equals(System
.getProperty("com.googlecode.lanterna.terminal.UnixTerminal.catchSpecialCharacters", "").trim().toLowerCase())) {
125 catchSpecialCharacters
= false;
128 catchSpecialCharacters
= true;
129 disableSpecialCharacters();
135 public TerminalSize
getTerminalSize() throws IOException
{
136 if(terminalSizeQuerier
!= null) {
137 return terminalSizeQuerier
.queryTerminalSize();
140 return super.getTerminalSize();
144 protected void sttyKeyEcho(final boolean enable
) throws IOException
{
145 exec(getSTTYCommand(), enable ?
"echo" : "-echo");
149 protected void sttyMinimum1CharacterForRead() throws IOException
{
150 exec(getSTTYCommand(), "min", "1");
154 protected void sttyICanon(final boolean enable
) throws IOException
{
155 exec(getSTTYCommand(), enable ?
"icanon" : "-icanon");
159 protected String
sttySave() throws IOException
{
160 return exec(getSTTYCommand(), "-g").trim();
164 protected void sttyRestore(String tok
) throws IOException
{
165 exec(getSTTYCommand(), tok
);
169 //What was the problem with this one? I don't remember... Restoring ctrl+c for now (see below)
170 private void restoreEOFCtrlD() throws IOException {
171 exec(getShellCommand(), "-c", getSTTYCommand() + " eof ^d < /dev/tty");
174 private void disableSpecialCharacters() throws IOException {
175 exec(getShellCommand(), "-c", getSTTYCommand() + " intr undef < /dev/tty");
176 exec(getShellCommand(), "-c", getSTTYCommand() + " start undef < /dev/tty");
177 exec(getShellCommand(), "-c", getSTTYCommand() + " stop undef < /dev/tty");
178 exec(getShellCommand(), "-c", getSTTYCommand() + " susp undef < /dev/tty");
181 private void restoreSpecialCharacters() throws IOException {
182 exec(getShellCommand(), "-c", getSTTYCommand() + " intr ^C < /dev/tty");
183 exec(getShellCommand(), "-c", getSTTYCommand() + " start ^Q < /dev/tty");
184 exec(getShellCommand(), "-c", getSTTYCommand() + " stop ^S < /dev/tty");
185 exec(getShellCommand(), "-c", getSTTYCommand() + " susp ^Z < /dev/tty");
191 * This method causes certain keystrokes (at the moment only ctrl+c) to be passed in to the program instead of
192 * interpreted by the shell and affect the program. For example, ctrl+c will send an interrupt that causes the
193 * JVM to shut down, but this method will make it pass in ctrl+c as a normal KeyStroke instead (you can still make
194 * ctrl+c kill the application, but Lanterna can do this for you after having restored the terminal).
196 * Please note that this method is generally called automatically (i.e. it's turned on by default), unless you
197 * define a system property "com.googlecode.lanterna.terminal.UnixTerminal.catchSpecialCharacters" and set it to
198 * the string "false".
199 * @throws IOException If there was an I/O error when attempting to disable special characters
200 * @see com.googlecode.lanterna.terminal.ansi.UnixLikeTerminal.CtrlCBehaviour
202 public void disableSpecialCharacters() throws IOException
{
203 exec(getSTTYCommand(), "intr", "undef");
207 * This method restores the special characters disabled by {@code disableSpecialCharacters()}, if it has been
209 * @throws IOException If there was an I/O error when attempting to restore special characters
211 public void restoreSpecialCharacters() throws IOException
{
212 exec(getSTTYCommand(), "intr", "^C");
216 protected synchronized void restoreSTTY() throws IOException
{
218 if(catchSpecialCharacters
) {
219 restoreSpecialCharacters();
223 protected String
getSTTYCommand() {