*/
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;
*/
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
// Constructors -----------------------------------------------------------
// ------------------------------------------------------------------------
+ /**
+ * Static constructor.
+ */
+ static {
+ checkForPtypipe();
+ }
+
/**
* Public constructor spawns a custom command line.
*
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";
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);
}
// 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.
) {
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+"));
// 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.
*
}
});
}
- if (getApplication() != null) {
- getApplication().postEvent(new TMenuEvent(
- TMenu.MID_REPAINT));
- }
+ app.doRepaint();
}
}
} // 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.
return 24;
}
+ /**
+ * Get the exit value for the emulator.
+ *
+ * @return exit value
+ */
+ public int getExitValue() {
+ return exitValue;
+ }
+
// ------------------------------------------------------------------------
// EditMenuUser -----------------------------------------------------------
// ------------------------------------------------------------------------