lwjgl2-arm64/src/native/macosx/org_lwjgl_input_Keyboard.cpp

397 lines
14 KiB
C++
Raw Normal View History

2002-12-18 04:38:57 +01:00
/*
* Copyright (c) 2002 Light Weight Java Game Library Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'Light Weight Java Game Library' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* $Id$
*
* Mac OS X keyboard handling.
2002-12-18 04:38:57 +01:00
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision$
*/
2003-10-06 16:00:44 +02:00
#include "Window.h"
2003-10-01 11:02:52 +02:00
#include "tools.h"
2002-12-18 04:38:57 +01:00
#include "org_lwjgl_input_Keyboard.h"
2003-10-07 13:23:12 +02:00
#define EVENT_BUFFER_SIZE 100
2003-09-30 12:52:05 +02:00
#define KEYBOARD_SIZE 256
2003-10-07 12:04:38 +02:00
#define UNICODE_BUFFER_SIZE 10
2002-12-18 04:38:57 +01:00
2003-10-06 17:28:12 +02:00
static unsigned char key_buf[KEYBOARD_SIZE];
static unsigned char key_map[KEYBOARD_SIZE];
2003-10-07 13:23:12 +02:00
static unsigned char input_event_buffer[EVENT_BUFFER_SIZE];
static unsigned char output_event_buffer[EVENT_BUFFER_SIZE];
2003-10-07 12:04:38 +02:00
2003-10-07 13:23:12 +02:00
static int list_start = 0;
static int list_end = 0;
static bool buffer_enabled = false;
static bool translation_enabled = false;
2003-10-07 12:04:38 +02:00
2003-10-07 13:23:12 +02:00
static void putEventElement(unsigned char byte) {
int next_index = (list_end + 1)%EVENT_BUFFER_SIZE;
if (next_index == list_start) {
#ifdef _DEBUG
printf("Keyboard buffer overflow!\n");
#endif
return;
}
input_event_buffer[list_end] = byte;
list_end = next_index;
}
static bool hasMoreEvents(void) {
return list_start != list_end;
}
static void copyEvent(int event_size, int event_index) {
int output_index = event_index*event_size;
for (int i = 0; i < event_size; i++) {
output_event_buffer[output_index] = input_event_buffer[list_start];
list_start = (list_start + 1)%EVENT_BUFFER_SIZE;
output_index++;
}
}
static bool handleMappedKey(unsigned char mapped_code, unsigned char state) {
2003-10-07 12:04:38 +02:00
unsigned char old_state = key_buf[mapped_code];
if (old_state != state) {
key_buf[mapped_code] = state;
2003-10-07 13:23:12 +02:00
if (buffer_enabled) {
putEventElement(mapped_code);
putEventElement(state);
return true;
}
2003-10-07 12:04:38 +02:00
}
2003-10-07 13:23:12 +02:00
return false;
2003-10-07 12:04:38 +02:00
}
2003-10-06 17:28:12 +02:00
2003-10-07 13:23:12 +02:00
static bool handleKey(UInt32 key_code, unsigned char state) {
2003-10-06 17:28:12 +02:00
if (key_code >= KEYBOARD_SIZE) {
#ifdef _DEBUG
2003-10-07 13:23:12 +02:00
printf("Key code >= %d %x\n", KEYBOARD_SIZE, (unsigned int)key_code);
2003-10-06 17:28:12 +02:00
#endif
2003-10-07 13:23:12 +02:00
return false;
2003-10-06 17:28:12 +02:00
}
unsigned char mapped_code = key_map[key_code];
2003-10-07 12:04:38 +02:00
if (mapped_code == 0) {
#ifdef _DEBUG
printf("unknown key code: %x\n", (unsigned int)key_code);
#endif
2003-10-07 13:23:12 +02:00
return false;
2003-10-06 17:28:12 +02:00
}
2003-10-07 13:23:12 +02:00
return handleMappedKey(mapped_code, state);
}
static unsigned char getSecondByte(UniChar ch) {
return (unsigned char)(ch & 0xff);
}
static unsigned char getFirstByte(UniChar ch) {
return (unsigned char)((ch & 0xff00) >> 16);
2003-10-07 12:04:38 +02:00
}
2003-10-07 13:23:12 +02:00
static bool writeChars(int num_chars, UniChar *buffer) {
if (num_chars == 0)
return false;
unsigned char b0 = getFirstByte(buffer[0]);
unsigned char b1 = getSecondByte(buffer[0]);
putEventElement(b0);
putEventElement(b1);
for (int i = 1; i < num_chars; i++) {
putEventElement(0);
putEventElement(0);
b0 = getFirstByte(buffer[i]);
b1 = getSecondByte(buffer[i]);
putEventElement(b0);
putEventElement(b1);
}
return true;
2003-10-07 12:04:38 +02:00
}
2003-10-07 13:23:12 +02:00
static bool handleUnicode(EventRef event) {
2003-10-07 12:04:38 +02:00
UniChar unicode_buffer[UNICODE_BUFFER_SIZE];
UInt32 data_size;
int num_chars;
OSStatus err = GetEventParameter(event, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0, &data_size, NULL);
if (err != noErr) {
#ifdef _DEBUG
printf("Could not get unicode char count\n");
#endif
2003-10-07 13:23:12 +02:00
return false;
2003-10-07 12:04:38 +02:00
}
num_chars = data_size/sizeof(UniChar);
if (num_chars >= UNICODE_BUFFER_SIZE) {
#ifdef _DEBUG
printf("Unicode chars could not fit in buffer\n");
#endif
2003-10-07 13:23:12 +02:00
return false;
2003-10-07 12:04:38 +02:00
}
err = GetEventParameter(event, kEventParamKeyUnicodes, typeUnicodeText, NULL, data_size, NULL, unicode_buffer);
if (err != noErr) {
#ifdef _DEBUG
printf("Could not get unicode chars\n");
#endif
2003-10-07 13:23:12 +02:00
return false;
2003-10-07 12:04:38 +02:00
}
2003-10-07 13:23:12 +02:00
return writeChars(num_chars, unicode_buffer);
2003-10-06 17:28:12 +02:00
}
2003-10-06 16:00:44 +02:00
static pascal OSStatus doKeyDown(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
UInt32 key_code;
OSStatus err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(key_code), NULL, &key_code);
if (err != noErr) {
#ifdef _DEBUG
printf("Could not get event key code\n");
#endif
return eventNotHandledErr;
}
2003-10-07 13:23:12 +02:00
lock();
if (handleKey(key_code, 1)) {
if (translation_enabled) {
if (!handleUnicode(event)) {
putEventElement(0);
putEventElement(0);
}
} else {
putEventElement(0);
putEventElement(0);
}
}
unlock();
return noErr;
2003-10-06 16:00:44 +02:00
}
static pascal OSStatus doKeyUp(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
UInt32 key_code;
OSStatus err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(key_code), NULL, &key_code);
if (err != noErr) {
#ifdef _DEBUG
printf("Could not get event key code\n");
#endif
return eventNotHandledErr;
}
2003-10-07 13:23:12 +02:00
lock();
if (handleKey(key_code, 0)) {
putEventElement(0);
putEventElement(0);
}
unlock();
2003-10-06 16:00:44 +02:00
return noErr;
}
2003-10-06 17:28:12 +02:00
static void handleModifier(UInt32 modifier_bit_mask, UInt32 modifier_bit, unsigned char key_code) {
bool key_down = (modifier_bit_mask & modifier_bit) == modifier_bit;
unsigned char key_state = key_down ? 1 : 0;
2003-10-07 13:23:12 +02:00
if (handleMappedKey(key_code, key_state)) {
putEventElement(0);
putEventElement(0);
}
2003-10-06 17:28:12 +02:00
}
static pascal OSStatus doKeyModifier(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
UInt32 modifier_bits;
OSStatus err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifier_bits), NULL, &modifier_bits);
if (err != noErr) {
#ifdef _DEBUG
printf("Could not get event key code\n");
#endif
return eventNotHandledErr;
2003-10-06 16:00:44 +02:00
}
2003-10-06 17:28:12 +02:00
handleModifier(modifier_bits, controlKey, 0x1d);
handleModifier(modifier_bits, rightControlKey, 0x9d);
handleModifier(modifier_bits, shiftKey, 0x2a);
handleModifier(modifier_bits, rightShiftKey, 0x36);
handleModifier(modifier_bits, optionKey, 0x38);
handleModifier(modifier_bits, rightOptionKey, 0xb8);
handleModifier(modifier_bits, cmdKey, 0xdb);
handleModifier(modifier_bits, alphaLock, 0x3a);
handleModifier(modifier_bits, kEventKeyModifierNumLockMask, 0x45);
//handleModifier(modifier_bits, rightCmdKey, 0xdc);
return noErr;
}
bool registerKeyboardHandler(JNIEnv* env, WindowRef win_ref) {
2003-10-07 17:10:24 +02:00
bool error = registerHandler(env, win_ref, doKeyUp, kEventClassKeyboard, kEventRawKeyUp);
error = error || registerHandler(env, win_ref, doKeyDown, kEventClassKeyboard, kEventRawKeyDown);
error = error || registerHandler(env, win_ref, doKeyModifier, kEventClassKeyboard, kEventRawKeyModifiersChanged);
2003-10-06 17:28:12 +02:00
return !error;
2002-12-18 04:38:57 +01:00
}
2003-10-07 12:04:38 +02:00
static void setupMappings(void) {
memset(key_map, 0, KEYBOARD_SIZE*sizeof(unsigned char));
key_map[0x35] = org_lwjgl_input_Keyboard_KEY_ESCAPE;
key_map[0x12] = org_lwjgl_input_Keyboard_KEY_1;
key_map[0x13] = org_lwjgl_input_Keyboard_KEY_2;
key_map[0x14] = org_lwjgl_input_Keyboard_KEY_3;
key_map[0x15] = org_lwjgl_input_Keyboard_KEY_4;
key_map[0x17] = org_lwjgl_input_Keyboard_KEY_5;
key_map[0x16] = org_lwjgl_input_Keyboard_KEY_6;
key_map[0x1a] = org_lwjgl_input_Keyboard_KEY_7;
key_map[0x1c] = org_lwjgl_input_Keyboard_KEY_8;
key_map[0x19] = org_lwjgl_input_Keyboard_KEY_9;
key_map[0x1d] = org_lwjgl_input_Keyboard_KEY_0;
key_map[0x1b] = org_lwjgl_input_Keyboard_KEY_MINUS;
key_map[0x18] = org_lwjgl_input_Keyboard_KEY_EQUALS;
key_map[0x33] = org_lwjgl_input_Keyboard_KEY_BACK;
key_map[0x30] = org_lwjgl_input_Keyboard_KEY_TAB;
key_map[0x0c] = org_lwjgl_input_Keyboard_KEY_Q;
key_map[0x0d] = org_lwjgl_input_Keyboard_KEY_W;
key_map[0x0e] = org_lwjgl_input_Keyboard_KEY_E;
key_map[0x0f] = org_lwjgl_input_Keyboard_KEY_R;
key_map[0x11] = org_lwjgl_input_Keyboard_KEY_T;
key_map[0x10] = org_lwjgl_input_Keyboard_KEY_Y;
key_map[0x20] = org_lwjgl_input_Keyboard_KEY_U;
key_map[0x22] = org_lwjgl_input_Keyboard_KEY_I;
key_map[0x1f] = org_lwjgl_input_Keyboard_KEY_O;
key_map[0x23] = org_lwjgl_input_Keyboard_KEY_P;
key_map[0x21] = org_lwjgl_input_Keyboard_KEY_LBRACKET;
key_map[0x1e] = org_lwjgl_input_Keyboard_KEY_RBRACKET;
key_map[0x24] = org_lwjgl_input_Keyboard_KEY_RETURN;
key_map[0x00] = org_lwjgl_input_Keyboard_KEY_A;
key_map[0x01] = org_lwjgl_input_Keyboard_KEY_S;
key_map[0x02] = org_lwjgl_input_Keyboard_KEY_D;
key_map[0x03] = org_lwjgl_input_Keyboard_KEY_F;
key_map[0x05] = org_lwjgl_input_Keyboard_KEY_G;
key_map[0x04] = org_lwjgl_input_Keyboard_KEY_H;
key_map[0x26] = org_lwjgl_input_Keyboard_KEY_J;
key_map[0x28] = org_lwjgl_input_Keyboard_KEY_K;
key_map[0x25] = org_lwjgl_input_Keyboard_KEY_L;
key_map[0x29] = org_lwjgl_input_Keyboard_KEY_SEMICOLON;
key_map[0x27] = org_lwjgl_input_Keyboard_KEY_APOSTROPHE;
key_map[0x2a] = org_lwjgl_input_Keyboard_KEY_GRAVE;
key_map[0x32] = org_lwjgl_input_Keyboard_KEY_BACKSLASH;
key_map[0x06] = org_lwjgl_input_Keyboard_KEY_Z;
key_map[0x07] = org_lwjgl_input_Keyboard_KEY_X;
key_map[0x08] = org_lwjgl_input_Keyboard_KEY_C;
key_map[0x09] = org_lwjgl_input_Keyboard_KEY_V;
key_map[0x0b] = org_lwjgl_input_Keyboard_KEY_B;
key_map[0x2d] = org_lwjgl_input_Keyboard_KEY_N;
key_map[0x2e] = org_lwjgl_input_Keyboard_KEY_M;
key_map[0x2b] = org_lwjgl_input_Keyboard_KEY_COMMA;
key_map[0x2f] = org_lwjgl_input_Keyboard_KEY_PERIOD;
key_map[0x2c] = org_lwjgl_input_Keyboard_KEY_SLASH;
key_map[0x43] = org_lwjgl_input_Keyboard_KEY_MULTIPLY;
key_map[0x31] = org_lwjgl_input_Keyboard_KEY_SPACE;
key_map[0x7a] = org_lwjgl_input_Keyboard_KEY_F1;
key_map[0x78] = org_lwjgl_input_Keyboard_KEY_F2;
key_map[0x63] = org_lwjgl_input_Keyboard_KEY_F3;
key_map[0x76] = org_lwjgl_input_Keyboard_KEY_F4;
key_map[0x60] = org_lwjgl_input_Keyboard_KEY_F5;
key_map[0x61] = org_lwjgl_input_Keyboard_KEY_F6;
key_map[0x62] = org_lwjgl_input_Keyboard_KEY_F7;
key_map[0x64] = org_lwjgl_input_Keyboard_KEY_F8;
key_map[0x65] = org_lwjgl_input_Keyboard_KEY_F9;
key_map[0x6d] = org_lwjgl_input_Keyboard_KEY_F10;
key_map[0x59] = org_lwjgl_input_Keyboard_KEY_NUMPAD7;
key_map[0x5b] = org_lwjgl_input_Keyboard_KEY_NUMPAD8;
key_map[0x5c] = org_lwjgl_input_Keyboard_KEY_NUMPAD9;
key_map[0x4e] = org_lwjgl_input_Keyboard_KEY_SUBTRACT;
key_map[0x56] = org_lwjgl_input_Keyboard_KEY_NUMPAD4;
key_map[0x57] = org_lwjgl_input_Keyboard_KEY_NUMPAD5;
key_map[0x58] = org_lwjgl_input_Keyboard_KEY_NUMPAD6;
key_map[0x45] = org_lwjgl_input_Keyboard_KEY_ADD;
key_map[0x53] = org_lwjgl_input_Keyboard_KEY_NUMPAD1;
key_map[0x54] = org_lwjgl_input_Keyboard_KEY_NUMPAD2;
key_map[0x55] = org_lwjgl_input_Keyboard_KEY_NUMPAD3;
key_map[0x52] = org_lwjgl_input_Keyboard_KEY_NUMPAD0;
key_map[0x41] = org_lwjgl_input_Keyboard_KEY_DECIMAL;
key_map[0x67] = org_lwjgl_input_Keyboard_KEY_F11;
key_map[0x6f] = org_lwjgl_input_Keyboard_KEY_F12;
key_map[0x51] = org_lwjgl_input_Keyboard_KEY_NUMPADEQUALS;
key_map[0x4c] = org_lwjgl_input_Keyboard_KEY_NUMPADENTER;
key_map[0x4b] = org_lwjgl_input_Keyboard_KEY_DIVIDE;
key_map[0x73] = org_lwjgl_input_Keyboard_KEY_HOME;
key_map[0x7e] = org_lwjgl_input_Keyboard_KEY_UP;
key_map[0x74] = org_lwjgl_input_Keyboard_KEY_PRIOR;
key_map[0x7b] = org_lwjgl_input_Keyboard_KEY_LEFT;
key_map[0x7c] = org_lwjgl_input_Keyboard_KEY_RIGHT;
key_map[0x7d] = org_lwjgl_input_Keyboard_KEY_DOWN;
key_map[0x79] = org_lwjgl_input_Keyboard_KEY_NEXT;
}
2003-10-06 17:28:12 +02:00
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_initIDs(JNIEnv * env, jclass clazz) {
2002-12-18 04:38:57 +01:00
}
2003-10-06 17:28:12 +02:00
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate(JNIEnv * env, jclass clazz) {
2003-10-07 13:23:12 +02:00
lock();
2003-10-07 12:04:38 +02:00
buffer_enabled = false;
2003-10-07 13:23:12 +02:00
translation_enabled = false;
list_end = 0;
list_start = 0;
2003-10-06 17:28:12 +02:00
memset(key_buf, 0, KEYBOARD_SIZE*sizeof(unsigned char));
2003-10-07 12:04:38 +02:00
setupMappings();
2003-10-07 13:23:12 +02:00
unlock();
2002-12-18 04:38:57 +01:00
}
2003-10-06 17:28:12 +02:00
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy(JNIEnv * env, jclass clazz) {
2002-12-18 04:38:57 +01:00
}
2003-10-06 17:28:12 +02:00
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nPoll(JNIEnv * env, jclass clazz, jobject buffer) {
unsigned char *new_keyboard_buffer = (unsigned char *)env->GetDirectBufferAddress(buffer);
lock();
memcpy(new_keyboard_buffer, key_buf, KEYBOARD_SIZE*sizeof(unsigned char));
unlock();
2003-10-01 11:02:52 +02:00
}
2003-09-30 12:52:05 +02:00
2003-10-06 17:28:12 +02:00
JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nRead(JNIEnv * env, jclass clazz) {
2003-10-07 13:23:12 +02:00
int num_events = 0;
lock();
int event_size;
if (translation_enabled)
event_size = 4;
else
event_size = 2;
while (hasMoreEvents()) {
copyEvent(event_size, num_events);
num_events++;
}
unlock();
return num_events;
2002-12-18 04:38:57 +01:00
}
2003-10-06 17:28:12 +02:00
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableTranslation(JNIEnv *env, jclass clazz) {
2003-10-07 13:23:12 +02:00
translation_enabled = true;
2003-09-30 12:52:05 +02:00
}
2003-10-06 17:28:12 +02:00
JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer(JNIEnv * env, jclass clazz) {
2003-10-07 12:04:38 +02:00
jfieldID fid_readBuffer = env->GetStaticFieldID(clazz, "readBuffer", "Ljava/nio/ByteBuffer;");
2003-10-07 13:23:12 +02:00
jobject new_buffer = env->NewDirectByteBuffer(&output_event_buffer, EVENT_BUFFER_SIZE);
2003-10-07 12:04:38 +02:00
env->SetStaticObjectField(clazz, fid_readBuffer, new_buffer);
buffer_enabled = true;
2003-10-07 13:23:12 +02:00
return EVENT_BUFFER_SIZE/2;
2003-10-06 17:28:12 +02:00
}
JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nisStateKeySet(JNIEnv *env, jclass clazz, jint key) {
return org_lwjgl_input_Keyboard_STATE_UNKNOWN;
2002-12-18 04:38:57 +01:00
}