Implemented Terminal cursor methods on windows.

This commit is contained in:
Adam Murdoch
2012-08-04 17:56:12 +10:00
parent e0c31aa176
commit 347ae83782
3 changed files with 232 additions and 112 deletions

View File

@@ -51,11 +51,11 @@ Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_isConsole(
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_getConsoleSize (JNIEnv *env, jclass target, jint output, jobject dimension, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_getConsoleSize(JNIEnv *env, jclass target, jint output, jobject dimension, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {
mark_failed_with_message(env, "not a terminal", result);
mark_failed_with_message(env, "not a console", result);
return;
}
if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
@@ -156,4 +156,81 @@ Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_foreground
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_left(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X -= count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_right(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X += count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_up(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.Y -= count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_down(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.Y += count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_startLine(JNIEnv *env, jclass target, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X = 0;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_clearToEndOfLine(JNIEnv *env, jclass target, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
for (int i = console_info.dwCursorPosition.X; i < console_info.dwSize.X; i++) {
WriteConsole(current_console, " ", 1, NULL, NULL);
}
}
#endif

View File

@@ -1,110 +1,141 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.NativeException;
import net.rubygrapefruit.platform.Terminal;
import net.rubygrapefruit.platform.TerminalAccess;
import net.rubygrapefruit.platform.TerminalSize;
import net.rubygrapefruit.platform.internal.jni.WindowsConsoleFunctions;
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 console size for %s: %s", this, result.getMessage()));
}
return size;
}
@Override
public Terminal bold() {
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) {
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() {
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() {
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;
}
@Override
public Terminal cursorDown(int count) throws NativeException {
throw new UnsupportedOperationException();
}
@Override
public Terminal cursorUp(int count) throws NativeException {
throw new UnsupportedOperationException();
}
@Override
public Terminal cursorLeft(int count) throws NativeException {
throw new UnsupportedOperationException();
}
@Override
public Terminal cursorRight(int count) throws NativeException {
throw new UnsupportedOperationException();
}
@Override
public Terminal cursorStartOfLine() throws NativeException {
throw new UnsupportedOperationException();
}
@Override
public Terminal clearToEndOfLine() throws NativeException {
throw new UnsupportedOperationException();
}
}
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.NativeException;
import net.rubygrapefruit.platform.Terminal;
import net.rubygrapefruit.platform.TerminalAccess;
import net.rubygrapefruit.platform.TerminalSize;
import net.rubygrapefruit.platform.internal.jni.TerminfoFunctions;
import net.rubygrapefruit.platform.internal.jni.WindowsConsoleFunctions;
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 console size for %s: %s", this, result.getMessage()));
}
return size;
}
@Override
public Terminal bold() {
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) {
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() {
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() {
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;
}
@Override
public Terminal cursorDown(int count) throws NativeException {
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.down(count, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not move cursor down for %s: %s", this, result.getMessage()));
}
return this;
}
@Override
public Terminal cursorUp(int count) throws NativeException {
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.up(count, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not move cursor up for %s: %s", this, result.getMessage()));
}
return this;
}
@Override
public Terminal cursorLeft(int count) throws NativeException {
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.left(count, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not move cursor left for %s: %s", this, result.getMessage()));
}
return this;
}
@Override
public Terminal cursorRight(int count) throws NativeException {
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.right(count, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not move cursor right for %s: %s", this, result.getMessage()));
}
return this;
}
@Override
public Terminal cursorStartOfLine() throws NativeException {
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.startLine(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not move cursor to start of line for %s: %s", this, result.getMessage()));
}
return this;
}
@Override
public Terminal clearToEndOfLine() throws NativeException {
FunctionResult result = new FunctionResult();
WindowsConsoleFunctions.clearToEndOfLine(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could clear to end of line for %s: %s", this, result.getMessage()));
}
return this;
}
}

View File

@@ -17,4 +17,16 @@ public class WindowsConsoleFunctions {
public static native void reset(FunctionResult result);
public static native void foreground(int ansiColor, FunctionResult result);
public static native void left(int count, FunctionResult result);
public static native void right(int count, FunctionResult result);
public static native void up(int count, FunctionResult result);
public static native void down(int count, FunctionResult result);
public static native void startLine(FunctionResult result);
public static native void clearToEndOfLine(FunctionResult result);
}