From c8496daccfbef15d8d63b448c9999710ea60d71d Mon Sep 17 00:00:00 2001 From: Kevin Lamonte Date: Mon, 9 Mar 2015 16:28:53 -0400 Subject: [PATCH] TTYSessionInfo --- Makefile | 2 + demos/Demo1.java | 4 + src/jexer/session/SessionInfo.java | 9 ++ src/jexer/session/TSessionInfo.java | 12 ++ src/jexer/session/TTYSessionInfo.java | 209 ++++++++++++++++++++++++++ 5 files changed, 236 insertions(+) create mode 100644 src/jexer/session/TTYSessionInfo.java diff --git a/Makefile b/Makefile index 490814a..d05f898 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,7 @@ JEXER_SRC = $(SRC_DIR)/jexer/TApplication.java \ $(SRC_DIR)/jexer/event/TResizeEvent.java \ $(SRC_DIR)/jexer/session/SessionInfo.java \ $(SRC_DIR)/jexer/session/TSessionInfo.java \ + $(SRC_DIR)/jexer/session/TTYSessionInfo.java \ $(SRC_DIR)/jexer/io/Screen.java \ $(SRC_DIR)/jexer/backend/Backend.java @@ -75,6 +76,7 @@ JEXER_BIN = $(TARGET_DIR)/jexer/TApplication.class \ $(TARGET_DIR)/jexer/event/TResizeEvent.class \ $(TARGET_DIR)/jexer/session/SessionInfo.class \ $(TARGET_DIR)/jexer/session/TSessionInfo.class \ + $(TARGET_DIR)/jexer/session/TTYSessionInfo.class \ $(TARGET_DIR)/jexer/io/Screen.class \ $(TARGET_DIR)/jexer/backend/Backend.class diff --git a/demos/Demo1.java b/demos/Demo1.java index 6f4869a..ada690d 100644 --- a/demos/Demo1.java +++ b/demos/Demo1.java @@ -33,6 +33,7 @@ import jexer.bits.*; import jexer.TApplication; +import jexer.session.TTYSessionInfo; /** * The demo application itself. @@ -44,6 +45,9 @@ class DemoApplication extends TApplication { public DemoApplication() { try { ColorTheme theme = new ColorTheme(); + TTYSessionInfo tty = new TTYSessionInfo(); + System.out.println("width: " + tty.getWindowWidth()); + System.out.println("height: " + tty.getWindowHeight()); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/jexer/session/SessionInfo.java b/src/jexer/session/SessionInfo.java index 0c10637..340ffd3 100644 --- a/src/jexer/session/SessionInfo.java +++ b/src/jexer/session/SessionInfo.java @@ -68,11 +68,20 @@ public interface SessionInfo { /** * Text window width getter + * + * @return the window width */ public int getWindowWidth(); /** * Text window height getter + * + * @return the window height */ public int getWindowHeight(); + + /** + * Re-query the text window size + */ + public void queryWindowSize(); } diff --git a/src/jexer/session/TSessionInfo.java b/src/jexer/session/TSessionInfo.java index a0dc75c..1575a6c 100644 --- a/src/jexer/session/TSessionInfo.java +++ b/src/jexer/session/TSessionInfo.java @@ -96,6 +96,8 @@ public class TSessionInfo implements SessionInfo { /** * Text window width getter + * + * @return the window width */ public int getWindowWidth() { return windowWidth; @@ -103,8 +105,18 @@ public class TSessionInfo implements SessionInfo { /** * Text window height getter + * + * @return the window height */ public int getWindowHeight() { return windowHeight; } + + /** + * Re-query the text window size + */ + public void queryWindowSize() { + // NOP + } + } diff --git a/src/jexer/session/TTYSessionInfo.java b/src/jexer/session/TTYSessionInfo.java new file mode 100644 index 0000000..b65eb0d --- /dev/null +++ b/src/jexer/session/TTYSessionInfo.java @@ -0,0 +1,209 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: This module is licensed under the GNU Lesser General + * Public License Version 3. Please see the file "COPYING" in this + * directory for more information about the GNU Lesser General Public + * License Version 3. + * + * Copyright (C) 2015 Kevin Lamonte + * + * This program 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 + * 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 + * http://www.gnu.org/licenses/, or write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +package jexer.session; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.Date; +import java.util.StringTokenizer; + +/** + * TTYSessionInfo queries environment variables and the tty window size for + * the session information. The username is taken from + * getpwuid(geteuid()).pw_name, language is taken from LANG, and text window + * size from ioctl(TIOCGWINSIZ). + */ +public class TTYSessionInfo implements SessionInfo { + + /** + * User name + */ + private String username = ""; + + /** + * Language + */ + private String language = ""; + + /** + * Text window width. Default is 80x24 (same as VT100-ish terminals). + */ + private int windowWidth = 80; + + /** + * Text window height. Default is 80x24 (same as VT100-ish terminals). + */ + private int windowHeight = 24; + + /** + * Time at which the window size was refreshed + */ + private Date lastQueryWindowTime; + + /** + * Username getter + * + * @return the username + */ + public String getUsername() { + return this.username; + } + + /** + * Username setter + * + * @param username the value + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * Language getter + * + * @return the language + */ + public String getLanguage() { + return this.language; + } + + /** + * Language setter + * + * @param language the value + */ + public void setLanguage(String language) { + this.language = language; + } + + /** + * Call 'stty size' to obtain the tty window size. windowWidth and + * windowHeight are set automatically. + */ + private void sttyWindowSize() { + String [] cmd = { + "/bin/sh", "-c", "stty size < /dev/tty" + }; + try { + System.out.println("spawn stty"); + + Process process = Runtime.getRuntime().exec(cmd); + BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); + String line = in.readLine(); + if ((line != null) && (line.length() > 0)) { + StringTokenizer tokenizer = new StringTokenizer(line); + windowHeight = Integer.parseInt(tokenizer.nextToken()); + windowWidth = Integer.parseInt(tokenizer.nextToken()); + } + while (true) { + BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); + line = err.readLine(); + if ((line != null) && (line.length() > 0)) { + System.err.println("Error output from stty: " + line); + } + try{ + process.waitFor(); + break; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + int rc = process.exitValue(); + if (rc != 0) { + System.err.println("stty returned error code: " + rc); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Text window width getter + * + * @return the window width + */ + public int getWindowWidth() { + if (System.getProperty("os.name").startsWith("Windows")) { + // Always use 80x25 for Windows (same as DOS) + return 80; + } + return windowWidth; + } + + /** + * Text window height getter + * + * @return the window height + */ + public int getWindowHeight() { + if (System.getProperty("os.name").startsWith("Windows")) { + // Always use 80x25 for Windows (same as DOS) + return 25; + } + return windowHeight; + } + + /** + * Re-query the text window size + */ + public void queryWindowSize() { + if (lastQueryWindowTime == null) { + lastQueryWindowTime = new Date(); + } else { + Date now = new Date(); + if (now.getTime() - lastQueryWindowTime.getTime() < 3000) { + // Don't re-spawn stty, it's been too soon. + return; + } + } + if (System.getProperty("os.name").startsWith("Linux") || + System.getProperty("os.name").startsWith("Mac OS X") || + System.getProperty("os.name").startsWith("SunOS") || + System.getProperty("os.name").startsWith("FreeBSD") + ) { + // Use stty to get the window size + sttyWindowSize(); + } + } + + /** + * Public constructor + */ + public TTYSessionInfo() { + // Populate lang and user from the environment + username = System.getProperty("user.name"); + language = System.getProperty("user.language"); + queryWindowSize(); + } +} -- 2.27.0