X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=blobdiff_plain;f=src%2Fjexer%2FTTerminalWidget.java;h=bf51e6b5c2fd67b78b55d6e280e44f68d3b335aa;hp=8c01e120618ebf0fc933c4a0da4ed9c47f8cc545;hb=HEAD;hpb=ee831bf6d859effbe0069991267e13d5bbca5861 diff --git a/src/jexer/TTerminalWidget.java b/src/jexer/TTerminalWidget.java index 8c01e12..bf51e6b 100644 --- a/src/jexer/TTerminalWidget.java +++ b/src/jexer/TTerminalWidget.java @@ -28,27 +28,20 @@ */ package jexer; -import java.awt.Font; -import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; - -import java.io.InputStream; +import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import jexer.backend.ECMA48Terminal; import jexer.backend.GlyphMaker; -import jexer.backend.MultiScreen; import jexer.backend.SwingTerminal; import jexer.bits.Cell; -import jexer.bits.CellAttributes; import jexer.event.TCommandEvent; import jexer.event.TKeypressEvent; import jexer.event.TMenuEvent; @@ -86,6 +79,11 @@ public class TTerminalWidget extends TScrollableWidget */ private Process shell; + /** + * If true, something called 'ptypipe' is on the PATH and executable. + */ + private static boolean ptypipeOnPath = false; + /** * If true, we are using the ptypipe utility to support dynamic window * resizing. ptypipe is available at @@ -165,6 +163,13 @@ public class TTerminalWidget extends TScrollableWidget // Constructors ----------------------------------------------------------- // ------------------------------------------------------------------------ + /** + * Static constructor. + */ + static { + checkForPtypipe(); + } + /** * Public constructor spawns a custom command line. * @@ -238,6 +243,14 @@ public class TTerminalWidget extends TScrollableWidget fullCommand = new String[command.length + 1]; fullCommand[0] = "ptypipe"; System.arraycopy(command, 0, fullCommand, 1, command.length); + } else if (System.getProperty("jexer.TTerminal.ptypipe", + "auto").equals("auto") + && (ptypipeOnPath == true) + ) { + ptypipe = true; + fullCommand = new String[command.length + 1]; + fullCommand[0] = "ptypipe"; + System.arraycopy(command, 0, fullCommand, 1, command.length); } else if (System.getProperty("os.name").startsWith("Windows")) { fullCommand = new String[3]; fullCommand[0] = "cmd"; @@ -253,12 +266,24 @@ public class TTerminalWidget extends TScrollableWidget fullCommand[5] = stringArrayToString(command); } else { // Default: behave like Linux - fullCommand = new String[5]; - fullCommand[0] = "script"; - fullCommand[1] = "-fqe"; - fullCommand[2] = "/dev/null"; - fullCommand[3] = "-c"; - fullCommand[4] = stringArrayToString(command); + if (System.getProperty("jexer.TTerminal.setsid", + "true").equals("false") + ) { + fullCommand = new String[5]; + fullCommand[0] = "script"; + fullCommand[1] = "-fqe"; + fullCommand[2] = "/dev/null"; + fullCommand[3] = "-c"; + fullCommand[4] = stringArrayToString(command); + } else { + fullCommand = new String[6]; + fullCommand[0] = "setsid"; + fullCommand[1] = "script"; + fullCommand[2] = "-fqe"; + fullCommand[3] = "/dev/null"; + fullCommand[4] = "-c"; + fullCommand[5] = stringArrayToString(command); + } } spawnShell(fullCommand); } @@ -322,6 +347,7 @@ public class TTerminalWidget extends TScrollableWidget // GNU differ on the '-f' vs '-F' flags, we need two different // commands. Lovely. String cmdShellGNU = "script -fqe /dev/null"; + String cmdShellGNUSetsid = "setsid script -fqe /dev/null"; String cmdShellBSD = "script -q -F /dev/null"; // ptypipe is another solution that permits dynamic window resizing. @@ -334,12 +360,24 @@ public class TTerminalWidget extends TScrollableWidget ) { ptypipe = true; spawnShell(cmdShellPtypipe.split("\\s+")); + } else if (System.getProperty("jexer.TTerminal.ptypipe", + "auto").equals("auto") + && (ptypipeOnPath == true) + ) { + ptypipe = true; + spawnShell(cmdShellPtypipe.split("\\s+")); } else if (System.getProperty("os.name").startsWith("Windows")) { spawnShell(cmdShellWindows.split("\\s+")); } else if (System.getProperty("os.name").startsWith("Mac")) { spawnShell(cmdShellBSD.split("\\s+")); } else if (System.getProperty("os.name").startsWith("Linux")) { - spawnShell(cmdShellGNU.split("\\s+")); + if (System.getProperty("jexer.TTerminal.setsid", + "true").equals("false") + ) { + spawnShell(cmdShellGNU.split("\\s+")); + } else { + spawnShell(cmdShellGNUSetsid.split("\\s+")); + } } else { // When all else fails, assume GNU. spawnShell(cmdShellGNU.split("\\s+")); @@ -757,6 +795,43 @@ public class TTerminalWidget extends TScrollableWidget // TTerminalWidget -------------------------------------------------------- // ------------------------------------------------------------------------ + /** + * Check for 'ptypipe' on the path. If available, set ptypipeOnPath. + */ + private static void checkForPtypipe() { + String systemPath = System.getenv("PATH"); + if (systemPath == null) { + return; + } + + String [] paths = systemPath.split(File.pathSeparator); + if (paths == null) { + return; + } + if (paths.length == 0) { + return; + } + for (int i = 0; i < paths.length; i++) { + File path = new File(paths[i]); + if (path.exists() && path.isDirectory()) { + File [] files = path.listFiles(); + if (files == null) { + continue; + } + if (files.length == 0) { + continue; + } + for (int j = 0; j < files.length; j++) { + File file = files[j]; + if (file.canExecute() && file.getName().equals("ptypipe")) { + ptypipeOnPath = true; + return; + } + } + } + } + } + /** * Get the desired window title. * @@ -980,6 +1055,19 @@ public class TTerminalWidget extends TScrollableWidget } // synchronized (emulator) } + /** + * Wait for a period of time to get output from the launched process. + * + * @param millis millis to wait for, or 0 to wait forever + * @return true if the launched process has emitted something + */ + public boolean waitForOutput(final int millis) { + if (emulator == null) { + return false; + } + return emulator.waitForOutput(millis); + } + /** * Check if a mouse press/release/motion event coordinate is over the * emulator. @@ -1186,6 +1274,15 @@ public class TTerminalWidget extends TScrollableWidget return 24; } + /** + * Get the exit value for the emulator. + * + * @return exit value + */ + public int getExitValue() { + return exitValue; + } + // ------------------------------------------------------------------------ // EditMenuUser ----------------------------------------------------------- // ------------------------------------------------------------------------