diff --git a/src/java/org/lwjgl/opengl/WindowsKeyboard.java b/src/java/org/lwjgl/opengl/WindowsKeyboard.java index 47b4ed77..6e76ff85 100644 --- a/src/java/org/lwjgl/opengl/WindowsKeyboard.java +++ b/src/java/org/lwjgl/opengl/WindowsKeyboard.java @@ -51,7 +51,9 @@ final class WindowsKeyboard { private final WindowsDirectInputDevice keyboard; private final IntBuffer temp_data_buffer; private final ByteBuffer keyboard_state; + private final boolean unicode; private final CharBuffer unicode_buffer; + private final ByteBuffer ascii_buffer; public WindowsKeyboard(WindowsDirectInput dinput, long hwnd) throws LWJGLException { this.dinput = dinput; @@ -72,9 +74,19 @@ final class WindowsKeyboard { keyboard.acquire(); temp_data_buffer = BufferUtils.createIntBuffer(BUFFER_SIZE*WindowsDirectInputDevice.DATA_SIZE); keyboard_state = BufferUtils.createByteBuffer(256); - unicode_buffer = BufferUtils.createCharBuffer(BUFFER_SIZE); + unicode = isWindowsNT(); + if (unicode) { + unicode_buffer = BufferUtils.createCharBuffer(BUFFER_SIZE); + ascii_buffer = null; + } else { + unicode_buffer = null; + // ToAscii returns at most 2 characters + ascii_buffer = BufferUtils.createByteBuffer(2); + } } + private static native boolean isWindowsNT(); + public void destroy() { keyboard.unacquire(); keyboard.release(); @@ -117,12 +129,22 @@ final class WindowsKeyboard { if (virt_key != 0 && GetKeyboardState(keyboard_state) != 0) { // Mark key down in the scan code dwOfs = dwOfs & 0x7fff; - unicode_buffer.clear(); - int num_chars = ToUnicode(virt_key, + int num_chars; + if (unicode) { + unicode_buffer.clear(); + num_chars = ToUnicode(virt_key, dwOfs, keyboard_state, unicode_buffer, unicode_buffer.capacity(), 0); + } else { + ascii_buffer.clear(); + num_chars = ToAscii(virt_key, + dwOfs, + keyboard_state, + ascii_buffer, + 0); + } if (num_chars > 0) { int current_char = 0; do { @@ -130,7 +152,12 @@ final class WindowsKeyboard { dst.putInt(0); dst.put((byte)0); } - int char_int = ((int)unicode_buffer.get()) & 0xFFFF; + int char_int; + if (unicode) { + char_int = ((int)unicode_buffer.get()) & 0xFFFF; + } else { + char_int = ((int)ascii_buffer.get()) & 0xFF; + } dst.putInt(char_int); dst.putLong(nanos); current_char++; @@ -151,6 +178,7 @@ final class WindowsKeyboard { } private static native int MapVirtualKey(int uCode, int uMapType); private static native int ToUnicode(int wVirtKey, int wScanCode, ByteBuffer lpKeyState, CharBuffer pwszBuff, int cchBuff, int flags); + private static native int ToAscii(int wVirtKey, int wScanCode, ByteBuffer lpKeyState, ByteBuffer lpChar, int flags); private static native int GetKeyboardState(ByteBuffer lpKeyState); public void read(ByteBuffer buffer) { diff --git a/src/native/windows/org_lwjgl_opengl_WindowsKeyboard.c b/src/native/windows/org_lwjgl_opengl_WindowsKeyboard.c index 09a01e35..25af3184 100644 --- a/src/native/windows/org_lwjgl_opengl_WindowsKeyboard.c +++ b/src/native/windows/org_lwjgl_opengl_WindowsKeyboard.c @@ -45,12 +45,26 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsKeyboard_MapVirtualKey(JNIEn return MapVirtualKey(uCode, uMapType); } +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_WindowsKeyboard_isWindowsNT(JNIEnv *env, jclass unused) { + OSVERSIONINFO osvi; + + osvi.dwOSVersionInfoSize = sizeof(osvi); + GetVersionEx(&osvi); + return osvi.dwPlatformId == VER_PLATFORM_WIN32_NT ? JNI_TRUE : JNI_FALSE; +} + JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsKeyboard_ToUnicode(JNIEnv *env, jclass unused, jint wVirtKey, jint wScanCode, jobject lpKeyState_obj, jobject pwszBuff_obj, jint cchBuff, jint flags) { const PBYTE lpKeyState = (*env)->GetDirectBufferAddress(env, lpKeyState_obj); LPWSTR pwszBuff = (*env)->GetDirectBufferAddress(env, pwszBuff_obj); return ToUnicode(wVirtKey, wScanCode, lpKeyState, pwszBuff, cchBuff, flags); } +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsKeyboard_ToAscii(JNIEnv *env, jclass unused, jint wVirtKey, jint wScanCode, jobject lpKeyState_obj, jobject lpChar_obj, jint flags) { + const PBYTE lpKeyState = (*env)->GetDirectBufferAddress(env, lpKeyState_obj); + LPWORD lpChar = (*env)->GetDirectBufferAddress(env, lpChar_obj); + return ToAscii(wVirtKey, wScanCode, lpKeyState, lpChar, flags); +} + JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsKeyboard_GetKeyboardState(JNIEnv *env, jclass unused, jobject lpKeyState_obj) { PBYTE lpKeyState = (*env)->GetDirectBufferAddress(env, lpKeyState_obj); return GetKeyboardState(lpKeyState);