Use correct handle when detecthing console on windows.

This commit is contained in:
Adam Murdoch
2012-10-10 16:51:02 +11:00
parent 827387dd78
commit 2fb75c790c

View File

@@ -1,339 +1,339 @@
#ifdef WIN32 #ifdef WIN32
#include "native.h" #include "native.h"
#include "generic.h" #include "generic.h"
#include <windows.h> #include <windows.h>
#include <wchar.h> #include <wchar.h>
/* /*
* Marks the given result as failed, using the current value of GetLastError() * Marks the given result as failed, using the current value of GetLastError()
*/ */
void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) { void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
mark_failed_with_code(env, message, GetLastError(), result); mark_failed_with_code(env, message, GetLastError(), result);
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getSystemInfo(JNIEnv *env, jclass target, jobject info, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getSystemInfo(JNIEnv *env, jclass target, jobject info, jobject result) {
jclass infoClass = env->GetObjectClass(info); jclass infoClass = env->GetObjectClass(info);
OSVERSIONINFOEX versionInfo; OSVERSIONINFOEX versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (GetVersionEx((OSVERSIONINFO*)&versionInfo) == 0) { if (GetVersionEx((OSVERSIONINFO*)&versionInfo) == 0) {
mark_failed_with_errno(env, "could not get version info", result); mark_failed_with_errno(env, "could not get version info", result);
return; return;
} }
SYSTEM_INFO systemInfo; SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo); GetNativeSystemInfo(&systemInfo);
jstring arch = NULL; jstring arch = NULL;
if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
arch = env->NewStringUTF("amd64"); arch = env->NewStringUTF("amd64");
} else if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { } else if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
arch = env->NewStringUTF("x86"); arch = env->NewStringUTF("x86");
} else if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { } else if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
arch = env->NewStringUTF("ia64"); arch = env->NewStringUTF("ia64");
} else { } else {
arch = env->NewStringUTF("unknown"); arch = env->NewStringUTF("unknown");
} }
jmethodID method = env->GetMethodID(infoClass, "windows", "(IIIZLjava/lang/String;)V"); jmethodID method = env->GetMethodID(infoClass, "windows", "(IIIZLjava/lang/String;)V");
env->CallVoidMethod(info, method, versionInfo.dwMajorVersion, versionInfo.dwMinorVersion, env->CallVoidMethod(info, method, versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
versionInfo.dwBuildNumber, versionInfo.wProductType == VER_NT_WORKSTATION, versionInfo.dwBuildNumber, versionInfo.wProductType == VER_NT_WORKSTATION,
arch); arch);
} }
/* /*
* Process functions * Process functions
*/ */
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_getPid(JNIEnv *env, jclass target) { Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_getPid(JNIEnv *env, jclass target) {
return GetCurrentProcessId(); return GetCurrentProcessId();
} }
/* /*
* File system functions * File system functions
*/ */
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_PosixFileSystemFunctions_listFileSystems(JNIEnv *env, jclass target, jobject info, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_PosixFileSystemFunctions_listFileSystems(JNIEnv *env, jclass target, jobject info, jobject result) {
wchar_t* volumeName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1)); wchar_t* volumeName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1));
jclass info_class = env->GetObjectClass(info); jclass info_class = env->GetObjectClass(info);
jmethodID method = env->GetMethodID(info_class, "add", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V"); jmethodID method = env->GetMethodID(info_class, "add", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V");
HANDLE handle = FindFirstVolumeW(volumeName, MAX_PATH+1); HANDLE handle = FindFirstVolumeW(volumeName, MAX_PATH+1);
if (handle == INVALID_HANDLE_VALUE) { if (handle == INVALID_HANDLE_VALUE) {
free(volumeName); free(volumeName);
mark_failed_with_errno(env, "could not find first volume", result); mark_failed_with_errno(env, "could not find first volume", result);
return; return;
} }
wchar_t* deviceName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1)); wchar_t* deviceName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1));
wchar_t* pathNames = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1)); wchar_t* pathNames = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1));
wchar_t* fsName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1)); wchar_t* fsName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1));
while(true) { while(true) {
// Chop off the trailing '\' // Chop off the trailing '\'
size_t len = wcslen(volumeName); size_t len = wcslen(volumeName);
if (len < 5) { if (len < 5) {
mark_failed_with_message(env, "volume name is too short", result); mark_failed_with_message(env, "volume name is too short", result);
break; break;
} }
volumeName[len-1] = L'\0'; volumeName[len-1] = L'\0';
if (QueryDosDeviceW(&volumeName[4], deviceName, MAX_PATH+1) == 0) { if (QueryDosDeviceW(&volumeName[4], deviceName, MAX_PATH+1) == 0) {
mark_failed_with_errno(env, "could not query dos device", result); mark_failed_with_errno(env, "could not query dos device", result);
break; break;
} }
volumeName[len-1] = L'\\'; volumeName[len-1] = L'\\';
DWORD used; DWORD used;
if (GetVolumePathNamesForVolumeNameW(volumeName, pathNames, MAX_PATH+1, &used) == 0) { if (GetVolumePathNamesForVolumeNameW(volumeName, pathNames, MAX_PATH+1, &used) == 0) {
// TODO - try again if the buffer is too small // TODO - try again if the buffer is too small
mark_failed_with_errno(env, "could not query volume paths", result); mark_failed_with_errno(env, "could not query volume paths", result);
break; break;
} }
wchar_t* cur = pathNames; wchar_t* cur = pathNames;
if (cur[0] != L'\0') { if (cur[0] != L'\0') {
if(GetVolumeInformationW(cur, NULL, 0, NULL, NULL, NULL, fsName, MAX_PATH+1) == 0) { if(GetVolumeInformationW(cur, NULL, 0, NULL, NULL, NULL, fsName, MAX_PATH+1) == 0) {
if (GetLastError() != ERROR_NOT_READY) { if (GetLastError() != ERROR_NOT_READY) {
mark_failed_with_errno(env, "could not query volume information", result); mark_failed_with_errno(env, "could not query volume information", result);
break; break;
} }
wcscpy(fsName, L"unknown"); wcscpy(fsName, L"unknown");
} }
for (;cur[0] != L'\0'; cur += wcslen(cur) + 1) { for (;cur[0] != L'\0'; cur += wcslen(cur) + 1) {
env->CallVoidMethod(info, method, env->NewString((jchar*)deviceName, wcslen(deviceName)), env->CallVoidMethod(info, method, env->NewString((jchar*)deviceName, wcslen(deviceName)),
env->NewString((jchar*)fsName, wcslen(fsName)), env->NewString((jchar*)cur, wcslen(cur)), JNI_FALSE); env->NewString((jchar*)fsName, wcslen(fsName)), env->NewString((jchar*)cur, wcslen(cur)), JNI_FALSE);
} }
} }
if (FindNextVolumeW(handle, volumeName, MAX_PATH) == 0) { if (FindNextVolumeW(handle, volumeName, MAX_PATH) == 0) {
if (GetLastError() != ERROR_NO_MORE_FILES) { if (GetLastError() != ERROR_NO_MORE_FILES) {
mark_failed_with_errno(env, "could find next volume", result); mark_failed_with_errno(env, "could find next volume", result);
} }
break; break;
} }
} }
free(volumeName); free(volumeName);
free(deviceName); free(deviceName);
free(pathNames); free(pathNames);
free(fsName); free(fsName);
FindVolumeClose(handle); FindVolumeClose(handle);
} }
/* /*
* Console functions * Console functions
*/ */
HANDLE getHandle(JNIEnv *env, int output, jobject result) { HANDLE getHandle(JNIEnv *env, int output, jobject result) {
HANDLE handle = output == 1 ? GetStdHandle(STD_OUTPUT_HANDLE) : GetStdHandle(STD_ERROR_HANDLE); HANDLE handle = output == 0 ? GetStdHandle(STD_OUTPUT_HANDLE) : GetStdHandle(STD_ERROR_HANDLE);
if (handle == INVALID_HANDLE_VALUE) { if (handle == INVALID_HANDLE_VALUE) {
mark_failed_with_errno(env, "could not get console handle", result); mark_failed_with_errno(env, "could not get console handle", result);
return NULL; return NULL;
} }
return handle; return handle;
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_isConsole(JNIEnv *env, jclass target, jint output, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_isConsole(JNIEnv *env, jclass target, jint output, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info; CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result); HANDLE handle = getHandle(env, output, result);
if (handle == NULL) { if (handle == NULL) {
return JNI_FALSE; return JNI_FALSE;
} }
if (!GetConsoleScreenBufferInfo(handle, &console_info)) { if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
if (GetLastError() == ERROR_INVALID_HANDLE) { if (GetLastError() == ERROR_INVALID_HANDLE) {
return JNI_FALSE; return JNI_FALSE;
} }
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
return JNI_FALSE; return JNI_FALSE;
} }
return JNI_TRUE; return JNI_TRUE;
} }
JNIEXPORT void JNICALL 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; CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result); HANDLE handle = getHandle(env, output, result);
if (handle == NULL) { if (handle == NULL) {
mark_failed_with_message(env, "not a console", result); mark_failed_with_message(env, "not a console", result);
return; return;
} }
if (!GetConsoleScreenBufferInfo(handle, &console_info)) { if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
return; return;
} }
jclass dimensionClass = env->GetObjectClass(dimension); jclass dimensionClass = env->GetObjectClass(dimension);
jfieldID widthField = env->GetFieldID(dimensionClass, "cols", "I"); jfieldID widthField = env->GetFieldID(dimensionClass, "cols", "I");
env->SetIntField(dimension, widthField, console_info.srWindow.Right - console_info.srWindow.Left + 1); env->SetIntField(dimension, widthField, console_info.srWindow.Right - console_info.srWindow.Left + 1);
jfieldID heightField = env->GetFieldID(dimensionClass, "rows", "I"); jfieldID heightField = env->GetFieldID(dimensionClass, "rows", "I");
env->SetIntField(dimension, heightField, console_info.srWindow.Bottom - console_info.srWindow.Top + 1); env->SetIntField(dimension, heightField, console_info.srWindow.Bottom - console_info.srWindow.Top + 1);
} }
HANDLE current_console = NULL; HANDLE current_console = NULL;
WORD original_attributes = 0; WORD original_attributes = 0;
WORD current_attributes = 0; WORD current_attributes = 0;
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_initConsole(JNIEnv *env, jclass target, jint output, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_initConsole(JNIEnv *env, jclass target, jint output, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info; CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result); HANDLE handle = getHandle(env, output, result);
if (handle == NULL) { if (handle == NULL) {
mark_failed_with_message(env, "not a terminal", result); mark_failed_with_message(env, "not a terminal", result);
return; return;
} }
if (!GetConsoleScreenBufferInfo(handle, &console_info)) { if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
if (GetLastError() == ERROR_INVALID_HANDLE) { if (GetLastError() == ERROR_INVALID_HANDLE) {
mark_failed_with_message(env, "not a console", result); mark_failed_with_message(env, "not a console", result);
} else { } else {
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
} }
return; return;
} }
current_console = handle; current_console = handle;
original_attributes = console_info.wAttributes; original_attributes = console_info.wAttributes;
current_attributes = original_attributes; current_attributes = original_attributes;
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_normal(env, target, result); Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_normal(env, target, result);
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_bold(JNIEnv *env, jclass target, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_bold(JNIEnv *env, jclass target, jobject result) {
current_attributes |= FOREGROUND_INTENSITY; current_attributes |= FOREGROUND_INTENSITY;
if (!SetConsoleTextAttribute(current_console, current_attributes)) { if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result); mark_failed_with_errno(env, "could not set text attributes", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_normal(JNIEnv *env, jclass target, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_normal(JNIEnv *env, jclass target, jobject result) {
current_attributes &= ~FOREGROUND_INTENSITY; current_attributes &= ~FOREGROUND_INTENSITY;
SetConsoleTextAttribute(current_console, current_attributes); SetConsoleTextAttribute(current_console, current_attributes);
if (!SetConsoleTextAttribute(current_console, current_attributes)) { if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result); mark_failed_with_errno(env, "could not set text attributes", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_reset(JNIEnv *env, jclass target, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_reset(JNIEnv *env, jclass target, jobject result) {
if (!SetConsoleTextAttribute(current_console, original_attributes)) { if (!SetConsoleTextAttribute(current_console, original_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result); mark_failed_with_errno(env, "could not set text attributes", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_foreground(JNIEnv *env, jclass target, jint color, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_foreground(JNIEnv *env, jclass target, jint color, jobject result) {
current_attributes &= ~ (FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN); current_attributes &= ~ (FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);
switch (color) { switch (color) {
case 0: case 0:
break; break;
case 1: case 1:
current_attributes |= FOREGROUND_RED; current_attributes |= FOREGROUND_RED;
break; break;
case 2: case 2:
current_attributes |= FOREGROUND_GREEN; current_attributes |= FOREGROUND_GREEN;
break; break;
case 3: case 3:
current_attributes |= FOREGROUND_RED|FOREGROUND_GREEN; current_attributes |= FOREGROUND_RED|FOREGROUND_GREEN;
break; break;
case 4: case 4:
current_attributes |= FOREGROUND_BLUE; current_attributes |= FOREGROUND_BLUE;
break; break;
case 5: case 5:
current_attributes |= FOREGROUND_RED|FOREGROUND_BLUE; current_attributes |= FOREGROUND_RED|FOREGROUND_BLUE;
break; break;
case 6: case 6:
current_attributes |= FOREGROUND_GREEN|FOREGROUND_BLUE; current_attributes |= FOREGROUND_GREEN|FOREGROUND_BLUE;
break; break;
default: default:
current_attributes |= FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; current_attributes |= FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE;
break; break;
} }
SetConsoleTextAttribute(current_console, current_attributes); SetConsoleTextAttribute(current_console, current_attributes);
if (!SetConsoleTextAttribute(current_console, current_attributes)) { if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result); mark_failed_with_errno(env, "could not set text attributes", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_left(JNIEnv *env, jclass target, jint count, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_left(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info; CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) { if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
return; return;
} }
console_info.dwCursorPosition.X -= count; console_info.dwCursorPosition.X -= count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) { if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result); mark_failed_with_errno(env, "could not set cursor position", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_right(JNIEnv *env, jclass target, jint count, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_right(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info; CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) { if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
return; return;
} }
console_info.dwCursorPosition.X += count; console_info.dwCursorPosition.X += count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) { if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result); mark_failed_with_errno(env, "could not set cursor position", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_up(JNIEnv *env, jclass target, jint count, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_up(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info; CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) { if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
return; return;
} }
console_info.dwCursorPosition.Y -= count; console_info.dwCursorPosition.Y -= count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) { if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result); mark_failed_with_errno(env, "could not set cursor position", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_down(JNIEnv *env, jclass target, jint count, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_down(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info; CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) { if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
return; return;
} }
console_info.dwCursorPosition.Y += count; console_info.dwCursorPosition.Y += count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) { if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result); mark_failed_with_errno(env, "could not set cursor position", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_startLine(JNIEnv *env, jclass target, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_startLine(JNIEnv *env, jclass target, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info; CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) { if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
return; return;
} }
console_info.dwCursorPosition.X = 0; console_info.dwCursorPosition.X = 0;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) { if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result); mark_failed_with_errno(env, "could not set cursor position", result);
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_clearToEndOfLine(JNIEnv *env, jclass target, jobject result) { Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_clearToEndOfLine(JNIEnv *env, jclass target, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info; CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) { if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result); mark_failed_with_errno(env, "could not get console buffer", result);
return; return;
} }
DWORD count; DWORD count;
if (!FillConsoleOutputCharacterW(current_console, L' ', console_info.dwSize.X - console_info.dwCursorPosition.X, console_info.dwCursorPosition, &count)) { if (!FillConsoleOutputCharacterW(current_console, L' ', console_info.dwSize.X - console_info.dwCursorPosition.X, console_info.dwCursorPosition, &count)) {
mark_failed_with_errno(env, "could not clear console", result); mark_failed_with_errno(env, "could not clear console", result);
} }
} }
#endif #endif