/*
* This file is a part of Alchemy OS project.
* Copyright (C) 2011-2014, Sergey Basalaev <sbasalaev@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package alchemy.apps;
import alchemy.io.IO;
import alchemy.libs.ui.UiMenu;
import alchemy.system.NativeApp;
import alchemy.system.Process;
import alchemy.system.ProcessKilledException;
import alchemy.system.UIServer;
import java.util.ArrayList;
/**
* Terminal emulation for PC version.
*
* @author Sergey Basalaev
*/
public class Terminal extends NativeApp {
private static final String HELP =
"terminal - run command in the new terminal\n" +
"Usage: terminal [-k] <command> <args>...";
private static final String VERSION = "PC terminal v2.1";
public Terminal() { }
@Override
public int main(Process p, String[] args) throws Exception {
// parse arguments
boolean keep = false;
String childCmd = null;
ArrayList<String> cmdArgs = new ArrayList<String>();
boolean readArgs = false;
for (String arg : args) {
if (readArgs) {
cmdArgs.add(arg);
} else if (arg.equals("-v")) {
IO.println(p.stdout, VERSION);
return 0;
} else if (arg.equals("-h")) {
IO.println(p.stdout, HELP);
return 0;
} else if (arg.equals("-k")) {
keep = true;
} else if (arg.startsWith("-")) {
IO.println(p.stderr, "Unknown option " + arg);
return 1;
} else {
childCmd = arg;
readArgs = true;
}
}
if (childCmd == null) childCmd = "sh";
String[] childArgs = cmdArgs.toArray(new String[0]);
// create terminal screen
TerminalScreen screen = new TerminalScreen(childCmd + " - Terminal");
UiMenu eofMenu = new UiMenu("Send EOF", 1, UiMenu.MT_SCREEN);
UiMenu killMenu = new UiMenu("Kill", 2, UiMenu.MT_SCREEN);
screen.addMenu(eofMenu);
screen.addMenu(killMenu);
// start subprocess
Process child = new Process(p, childCmd, childArgs);
child.stdin = screen.in;
child.stdout = screen.out;
child.stderr = screen.err;
UIServer.setScreen(p, screen);
child.start();
// wait for child to die and process menus
while (child.getState() != Process.ENDED) {
Thread.sleep(100);
Object[] ev = UIServer.readEvent(p, false);
if (ev != null && ev[0] == UIServer.EVENT_MENU) {
if (ev[2] == killMenu) {
child.kill();
} else if (ev[1] == eofMenu) {
screen.sendEOF();
}
}
if (p.killed) throw new ProcessKilledException();
}
if (keep) {
screen.end(p.getName());
}
return child.getExitCode();
}
}