Change build scripts
[jvcard.git] / src / com / googlecode / lanterna / terminal / ansi / CygwinTerminal.java
CommitLineData
a3b510ab
NR
1/*
2 * This file is part of lanterna (http://code.google.com/p/lanterna/).
3 *
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.
8 *
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.
13 *
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/>.
16 *
17 * Copyright (C) 2010-2015 Martin
18 */
19package com.googlecode.lanterna.terminal.ansi;
20
21import com.googlecode.lanterna.TerminalSize;
22
23import java.io.*;
24import java.nio.charset.Charset;
25import java.util.ArrayList;
26import java.util.Arrays;
27import java.util.List;
28import java.util.regex.Matcher;
29import java.util.regex.Pattern;
30
31/**
32 * This class extends UnixLikeTerminal and implements the Cygwin-specific implementations. This means, running a Java
33 * application using Lanterna inside the Cygwin Terminal application. The standard Windows command prompt (cmd.exe) is
34 * not supported by this class.<p>
35 * <p>
36 * <b>NOTE:</b> This class is experimental and does not fully work! Some of the operations, like disabling echo and
37 * changing cbreak seems to be impossible to do without resorting to native code. Running "stty raw" before starting the
38 * JVM will improve compatibility.
39 *
40 * @author Martin
41 * @author Andreas
42 */
43public class CygwinTerminal extends UnixLikeTerminal {
44
45 private static final Pattern STTY_SIZE_PATTERN = Pattern.compile(".*rows ([0-9]+);.*columns ([0-9]+);.*");
46 private static final String STTY_LOCATION = findProgram("stty.exe");
47
48 /**
49 * Creates a new CygwinTerminal based off input and output streams and a character set to use
50 * @param terminalInput Input stream to read input from
51 * @param terminalOutput Output stream to write output to
52 * @param terminalCharset Character set to use when writing to the output stream
53 * @throws IOException If there was an I/O error when trying to initialize the class and setup the terminal
54 */
55 public CygwinTerminal(
56 InputStream terminalInput,
57 OutputStream terminalOutput,
58 Charset terminalCharset) throws IOException {
59 super(terminalInput, terminalOutput, terminalCharset,
60 CtrlCBehaviour.TRAP, null);
61
62 //Make sure to set an initial size
63 onResized(80, 24);
64
65 saveSTTY();
66 setCBreak(true);
67 setEcho(false);
68 sttyMinimum1CharacterForRead();
69 setupShutdownHook();
70 }
71
72 @Override
73 public TerminalSize getTerminalSize() {
74 try {
75 String stty = exec(findSTTY(), "-F", getPseudoTerminalDevice(), "-a");
76 Matcher matcher = STTY_SIZE_PATTERN.matcher(stty);
77 if(matcher.matches()) {
78 return new TerminalSize(Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(1)));
79 }
80 else {
81 return new TerminalSize(80, 24);
82 }
83 }
84 catch(Throwable e) {
85 return new TerminalSize(80, 24);
86 }
87 }
88
89 @Override
90 protected void sttyKeyEcho(final boolean enable) throws IOException {
91 runSTTYCommand(enable ? "echo" : "-echo");
92 }
93
94 @Override
95 protected void sttyMinimum1CharacterForRead() throws IOException {
96 runSTTYCommand("min", "1");
97 }
98
99 @Override
100 protected void sttyICanon(final boolean enable) throws IOException {
101 runSTTYCommand(enable ? "icanon" : "cbreak");
102 }
103
104 @Override
105 protected String sttySave() throws IOException {
106 return runSTTYCommand("-g").trim();
107 }
108
109 @Override
110 protected void sttyRestore(String tok) throws IOException {
111 runSTTYCommand(tok);
112 }
113
114 protected String findSTTY() {
115 return STTY_LOCATION;
116 }
117
118 private String runSTTYCommand(String... parameters) throws IOException {
119 List<String> commandLine = new ArrayList<String>(Arrays.asList(
120 findSTTY(),
121 "-F",
122 getPseudoTerminalDevice()));
123 commandLine.addAll(Arrays.asList(parameters));
124 return exec(commandLine.toArray(new String[commandLine.size()]));
125 }
126
127 private String getPseudoTerminalDevice() {
128 //This will only work if you only have one terminal window open, otherwise we'll need to figure out somehow
129 //which pty to use, which could be very tricky...
130 return "/dev/pty0";
131 }
132
133 private static String findProgram(String programName) {
134 String[] paths = System.getProperty("java.library.path").split(";");
135 for(String path : paths) {
136 File shBin = new File(path, programName);
137 if(shBin.exists()) {
138 return shBin.getAbsolutePath();
139 }
140 }
141 return programName;
142 }
143
144}