/*
* This file is part of lanterna (http://code.google.com/p/lanterna/).
*
* lanterna 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see
*
* NOTE: This class is experimental and does not fully work! Some of the operations, like disabling echo and
* changing cbreak seems to be impossible to do without resorting to native code. Running "stty raw" before starting the
* JVM will improve compatibility.
*
* @author Martin
* @author Andreas
*/
public class CygwinTerminal extends UnixLikeTerminal {
private static final Pattern STTY_SIZE_PATTERN = Pattern.compile(".*rows ([0-9]+);.*columns ([0-9]+);.*");
private static final String STTY_LOCATION = findProgram("stty.exe");
/**
* Creates a new CygwinTerminal based off input and output streams and a character set to use
* @param terminalInput Input stream to read input from
* @param terminalOutput Output stream to write output to
* @param terminalCharset Character set to use when writing to the output stream
* @throws IOException If there was an I/O error when trying to initialize the class and setup the terminal
*/
public CygwinTerminal(
InputStream terminalInput,
OutputStream terminalOutput,
Charset terminalCharset) throws IOException {
super(terminalInput, terminalOutput, terminalCharset,
CtrlCBehaviour.TRAP, null);
//Make sure to set an initial size
onResized(80, 24);
saveSTTY();
setCBreak(true);
setEcho(false);
sttyMinimum1CharacterForRead();
setupShutdownHook();
}
@Override
public TerminalSize getTerminalSize() {
try {
String stty = exec(findSTTY(), "-F", getPseudoTerminalDevice(), "-a");
Matcher matcher = STTY_SIZE_PATTERN.matcher(stty);
if(matcher.matches()) {
return new TerminalSize(Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(1)));
}
else {
return new TerminalSize(80, 24);
}
}
catch(Throwable e) {
return new TerminalSize(80, 24);
}
}
@Override
protected void sttyKeyEcho(final boolean enable) throws IOException {
runSTTYCommand(enable ? "echo" : "-echo");
}
@Override
protected void sttyMinimum1CharacterForRead() throws IOException {
runSTTYCommand("min", "1");
}
@Override
protected void sttyICanon(final boolean enable) throws IOException {
runSTTYCommand(enable ? "icanon" : "cbreak");
}
@Override
protected String sttySave() throws IOException {
return runSTTYCommand("-g").trim();
}
@Override
protected void sttyRestore(String tok) throws IOException {
runSTTYCommand(tok);
}
protected String findSTTY() {
return STTY_LOCATION;
}
private String runSTTYCommand(String... parameters) throws IOException {
List