Implemented Terminal.bold(), foreground(), normal() and reset().

This commit is contained in:
Adam Murdoch
2012-08-04 14:08:19 +10:00
parent e9b300f610
commit 7ee843612a
9 changed files with 196 additions and 24 deletions

View File

@@ -0,0 +1,17 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.Terminal;
public abstract class AbstractTerminal implements Terminal {
public final void init() {
doInit();
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run() {
reset();
}
});
}
protected abstract void doInit();
}

View File

@@ -9,29 +9,29 @@ import net.rubygrapefruit.platform.internal.jni.TerminfoFunctions;
import java.io.PrintStream;
public class DefaultTerminal implements Terminal {
public class TerminfoTerminal extends AbstractTerminal {
private final TerminalAccess.Output output;
private final PrintStream stream;
private Color foreground;
public DefaultTerminal(TerminalAccess.Output output) {
public TerminfoTerminal(TerminalAccess.Output output) {
this.output = output;
stream = output == TerminalAccess.Output.Stdout ? System.out : System.err;
}
public void init() {
@Override
public String toString() {
return output.toString().toLowerCase();
}
@Override
protected void doInit() {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.initTerminal(output.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not open terminal: %s", result.getMessage()));
throw new NativeException(String.format("Could not open terminal for %s: %s", this, result.getMessage()));
}
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run() {
reset();
}
});
}
@Override
@@ -40,7 +40,7 @@ public class DefaultTerminal implements Terminal {
FunctionResult result = new FunctionResult();
PosixTerminalFunctions.getTerminalSize(output.ordinal(), terminalSize, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not get terminal size: %s", result.getMessage()));
throw new NativeException(String.format("Could not get terminal size for %s: %s", this, result.getMessage()));
}
return terminalSize;
}
@@ -51,7 +51,7 @@ public class DefaultTerminal implements Terminal {
FunctionResult result = new FunctionResult();
TerminfoFunctions.foreground(color.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not switch foreground color: %s", result.getMessage()));
throw new NativeException(String.format("Could not switch foreground color for %s: %s", this, result.getMessage()));
}
foreground = color;
return this;
@@ -63,7 +63,7 @@ public class DefaultTerminal implements Terminal {
FunctionResult result = new FunctionResult();
TerminfoFunctions.bold(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not switch to bold mode: %s", result.getMessage()));
throw new NativeException(String.format("Could not switch to bold mode for %s: %s", this, result.getMessage()));
}
return this;
}
@@ -83,7 +83,7 @@ public class DefaultTerminal implements Terminal {
FunctionResult result = new FunctionResult();
TerminfoFunctions.reset(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not reset terminal: %s", result.getMessage()));
throw new NativeException(String.format("Could not reset terminal for %s: %s", this, result.getMessage()));
}
return this;
}

View File

@@ -18,7 +18,7 @@ public class TerminfoTerminalAccess implements TerminalAccess {
throw new UnsupportedOperationException("Currently only one output can be used as a terminal.");
}
DefaultTerminal terminal = new DefaultTerminal(output);
TerminfoTerminal terminal = new TerminfoTerminal(output);
terminal.init();
currentlyOpen = output;

View File

@@ -6,41 +6,75 @@ import net.rubygrapefruit.platform.TerminalAccess;
import net.rubygrapefruit.platform.TerminalSize;
import net.rubygrapefruit.platform.internal.jni.WindowsConsoleFunctions;
public class WindowsTerminal implements Terminal {
public class WindowsTerminal extends AbstractTerminal {
private final TerminalAccess.Output output;
public WindowsTerminal(TerminalAccess.Output output) {
this.output = output;
}
@Override
public String toString() {
return output.toString().toLowerCase();
}
@Override
protected void doInit() {
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.initConsole(output.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not open console for %s: %s", this, result.getMessage()));
}
}
@Override
public TerminalSize getTerminalSize() {
FunctionResult result = new FunctionResult();
MutableTerminalSize size = new MutableTerminalSize();
WindowsConsoleFunctions.getConsoleSize(output.ordinal(), size, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not determine terminal size: %s", result.getMessage()));
throw new NativeException(String.format("Could not determine console size for %s: %s", this, result.getMessage()));
}
return size;
}
@Override
public Terminal bold() {
throw new UnsupportedOperationException();
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.bold(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not switch console to bold mode for %s: %s", this, result.getMessage()));
}
return this;
}
@Override
public Terminal foreground(Color color) {
throw new UnsupportedOperationException();
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.foreground(color.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not change console foreground color for %s: %s", this, result.getMessage()));
}
return this;
}
@Override
public Terminal normal() {
throw new UnsupportedOperationException();
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.normal(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not switch console to normal mode for %s: %s", this, result.getMessage()));
}
return this;
}
@Override
public Terminal reset() {
throw new UnsupportedOperationException();
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.reset(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not reset console for %s: %s", this, result.getMessage()));
}
return this;
}
}

View File

@@ -6,6 +6,8 @@ import net.rubygrapefruit.platform.TerminalAccess;
import net.rubygrapefruit.platform.internal.jni.WindowsConsoleFunctions;
public class WindowsTerminalAccess implements TerminalAccess {
private static Output currentlyOpen;
@Override
public boolean isTerminal(Output output) {
FunctionResult result = new FunctionResult();
@@ -19,6 +21,14 @@ public class WindowsTerminalAccess implements TerminalAccess {
@Override
public Terminal getTerminal(Output output) {
return new WindowsTerminal(output);
if (currentlyOpen != null) {
throw new UnsupportedOperationException("Currently only one output can be used as a terminal.");
}
WindowsTerminal terminal = new WindowsTerminal(output);
terminal.init();
currentlyOpen = output;
return terminal;
}
}

View File

@@ -7,4 +7,14 @@ public class WindowsConsoleFunctions {
public static native boolean isConsole(int filedes, FunctionResult result);
public static native void getConsoleSize(int filedes, MutableTerminalSize size, FunctionResult result);
public static native void initConsole(int filedes, FunctionResult result);
public static native void bold(FunctionResult result);
public static native void normal(FunctionResult result);
public static native void reset(FunctionResult result);
public static native void foreground(int ansiColor, FunctionResult result);
}