5d858c6e2ba5996b605bee7d191e32bde9b3d77a
[nikiroo-utils.git] / src / jexer / session / TTYSessionInfo.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * License: LGPLv3 or later
5 *
6 * This module is licensed under the GNU Lesser General Public License
7 * Version 3. Please see the file "COPYING" in this directory for more
8 * information about the GNU Lesser General Public License Version 3.
9 *
10 * Copyright (C) 2015 Kevin Lamonte
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, see
24 * http://www.gnu.org/licenses/, or write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * 02110-1301 USA
27 *
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 * @version 1
30 */
31 package jexer.session;
32
33 import java.io.BufferedReader;
34 import java.io.InputStreamReader;
35 import java.io.IOException;
36 import java.util.Date;
37 import java.util.StringTokenizer;
38
39 /**
40 * TTYSessionInfo queries environment variables and the tty window size for
41 * the session information. The username is taken from user.name, language
42 * is taken from user.language, and text window size from 'stty size'.
43 */
44 public final class TTYSessionInfo implements SessionInfo {
45
46 /**
47 * User name.
48 */
49 private String username = "";
50
51 /**
52 * Language.
53 */
54 private String language = "";
55
56 /**
57 * Text window width. Default is 80x24 (same as VT100-ish terminals).
58 */
59 private int windowWidth = 80;
60
61 /**
62 * Text window height. Default is 80x24 (same as VT100-ish terminals).
63 */
64 private int windowHeight = 24;
65
66 /**
67 * Time at which the window size was refreshed.
68 */
69 private Date lastQueryWindowTime;
70
71 /**
72 * Username getter.
73 *
74 * @return the username
75 */
76 public String getUsername() {
77 return this.username;
78 }
79
80 /**
81 * Username setter.
82 *
83 * @param username the value
84 */
85 public void setUsername(final String username) {
86 this.username = username;
87 }
88
89 /**
90 * Language getter.
91 *
92 * @return the language
93 */
94 public String getLanguage() {
95 return this.language;
96 }
97
98 /**
99 * Language setter.
100 *
101 * @param language the value
102 */
103 public void setLanguage(final String language) {
104 this.language = language;
105 }
106
107 /**
108 * Call 'stty size' to obtain the tty window size. windowWidth and
109 * windowHeight are set automatically.
110 */
111 private void sttyWindowSize() {
112 String [] cmd = {
113 "/bin/sh", "-c", "stty size < /dev/tty"
114 };
115 try {
116 Process process = Runtime.getRuntime().exec(cmd);
117 BufferedReader in = new BufferedReader(
118 new InputStreamReader(process.getInputStream(), "UTF-8"));
119 String line = in.readLine();
120 if ((line != null) && (line.length() > 0)) {
121 StringTokenizer tokenizer = new StringTokenizer(line);
122 int rc = Integer.parseInt(tokenizer.nextToken());
123 if (rc > 0) {
124 windowHeight = rc;
125 }
126 rc = Integer.parseInt(tokenizer.nextToken());
127 if (rc > 0) {
128 windowWidth = rc;
129 }
130 }
131 while (true) {
132 BufferedReader err = new BufferedReader(
133 new InputStreamReader(process.getErrorStream(),
134 "UTF-8"));
135 line = err.readLine();
136 if ((line != null) && (line.length() > 0)) {
137 System.err.println("Error output from stty: " + line);
138 }
139 try {
140 process.waitFor();
141 break;
142 } catch (InterruptedException e) {
143 e.printStackTrace();
144 }
145 }
146 int rc = process.exitValue();
147 if (rc != 0) {
148 System.err.println("stty returned error code: " + rc);
149 }
150 } catch (IOException e) {
151 e.printStackTrace();
152 }
153 }
154
155 /**
156 * Text window width getter.
157 *
158 * @return the window width
159 */
160 public int getWindowWidth() {
161 if (System.getProperty("os.name").startsWith("Windows")) {
162 // Always use 80x25 for Windows (same as DOS)
163 return 80;
164 }
165 return windowWidth;
166 }
167
168 /**
169 * Text window height getter.
170 *
171 * @return the window height
172 */
173 public int getWindowHeight() {
174 if (System.getProperty("os.name").startsWith("Windows")) {
175 // Always use 80x25 for Windows (same as DOS)
176 return 25;
177 }
178 return windowHeight;
179 }
180
181 /**
182 * Re-query the text window size.
183 */
184 public void queryWindowSize() {
185 if (lastQueryWindowTime == null) {
186 lastQueryWindowTime = new Date();
187 } else {
188 Date now = new Date();
189 if (now.getTime() - lastQueryWindowTime.getTime() < 3000) {
190 // Don't re-spawn stty, it's been too soon.
191 return;
192 }
193 }
194 if (System.getProperty("os.name").startsWith("Linux")
195 || System.getProperty("os.name").startsWith("Mac OS X")
196 || System.getProperty("os.name").startsWith("SunOS")
197 || System.getProperty("os.name").startsWith("FreeBSD")
198 ) {
199 // Use stty to get the window size
200 sttyWindowSize();
201 }
202 }
203
204 /**
205 * Public constructor.
206 */
207 public TTYSessionInfo() {
208 // Populate lang and user from the environment
209 username = System.getProperty("user.name");
210 language = System.getProperty("user.language");
211 queryWindowSize();
212 }
213 }