Add glfwGetKeyName

Fixes #464.
This commit is contained in:
Camilla Berglund
2015-07-02 14:24:50 +02:00
parent 67c6a45e0e
commit 9c315412e1
19 changed files with 273 additions and 16 deletions
+27
View File
@@ -72,7 +72,10 @@ static void changeToResourcesDirectory(void)
//
static void createKeyTables(void)
{
int scancode;
memset(_glfw.ns.publicKeys, -1, sizeof(_glfw.ns.publicKeys));
memset(_glfw.ns.nativeKeys, -1, sizeof(_glfw.ns.nativeKeys));
_glfw.ns.publicKeys[0x1D] = GLFW_KEY_0;
_glfw.ns.publicKeys[0x12] = GLFW_KEY_1;
@@ -188,6 +191,13 @@ static void createKeyTables(void)
_glfw.ns.publicKeys[0x51] = GLFW_KEY_KP_EQUAL;
_glfw.ns.publicKeys[0x43] = GLFW_KEY_KP_MULTIPLY;
_glfw.ns.publicKeys[0x4E] = GLFW_KEY_KP_SUBTRACT;
for (scancode = 0; scancode < 256; scancode++)
{
// Store the reverse translation for faster key name lookup
if (_glfw.ns.publicKeys[scancode] >= 0)
_glfw.ns.nativeKeys[_glfw.ns.publicKeys[scancode]] = scancode;
}
}
@@ -211,6 +221,17 @@ int _glfwPlatformInit(void)
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
// TODO: Catch kTISNotifySelectedKeyboardInputSourceChanged and update
_glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();
if (!_glfw.ns.inputSource)
return GLFW_FALSE;
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData)
return GLFW_FALSE;
if (!_glfwInitContextAPI())
return GLFW_FALSE;
@@ -222,6 +243,12 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void)
{
if (_glfw.ns.inputSource)
{
CFRelease(_glfw.ns.inputSource);
_glfw.ns.inputSource = NULL;
}
if (_glfw.ns.eventSource)
{
CFRelease(_glfw.ns.eventSource);
+12 -6
View File
@@ -30,8 +30,10 @@
#include <stdint.h>
#if defined(__OBJC__)
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
#else
#include <Carbon/Carbon.h>
#include <ApplicationServices/ApplicationServices.h>
typedef void* id;
#endif
@@ -73,13 +75,17 @@ typedef struct _GLFWwindowNS
//
typedef struct _GLFWlibraryNS
{
CGEventSourceRef eventSource;
id delegate;
id autoreleasePool;
id cursor;
CGEventSourceRef eventSource;
id delegate;
id autoreleasePool;
id cursor;
TISInputSourceRef inputSource;
id unicodeData;
short int publicKeys[256];
char* clipboardString;
char keyName[64];
short int publicKeys[256];
short int nativeKeys[GLFW_KEY_LAST + 1];
char* clipboardString;
} _GLFWlibraryNS;
+42
View File
@@ -1168,6 +1168,48 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
CGAssociateMouseAndMouseCursorPosition(true);
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
if (key != GLFW_KEY_UNKNOWN)
scancode = _glfw.ns.nativeKeys[key];
if (!_glfwIsPrintable(_glfw.ns.publicKeys[scancode]))
return NULL;
UInt32 deadKeyState = 0;
UniChar characters[8];
UniCharCount characterCount = 0;
if (UCKeyTranslate([(NSData*) _glfw.ns.unicodeData bytes],
scancode,
kUCKeyActionDisplay,
0,
LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit,
&deadKeyState,
sizeof(characters) / sizeof(characters[0]),
&characterCount,
characters) != noErr)
{
return NULL;
}
if (!characterCount)
return NULL;
CFStringRef string = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
characters,
characterCount,
kCFAllocatorNull);
CFStringGetCString(string,
_glfw.ns.keyName,
sizeof(_glfw.ns.keyName),
kCFStringEncodingUTF8);
CFRelease(string);
return _glfw.ns.keyName;
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
+18
View File
@@ -223,6 +223,18 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwIsPrintable(int key)
{
return (key >= GLFW_KEY_APOSTROPHE && key <= GLFW_KEY_WORLD_2) ||
(key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) ||
key == GLFW_KEY_KP_EQUAL;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
@@ -270,6 +282,12 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
}
}
GLFWAPI const char* glfwGetKeyName(int key, int scancode)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetKeyName(key, scancode);
}
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
+9
View File
@@ -428,6 +428,11 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
*/
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
/*! @copydoc glfwGetKeyName
* @ingroup platform
*/
const char* _glfwPlatformGetKeyName(int key, int scancode);
/*! @copydoc glfwGetMonitors
* @ingroup platform
*/
@@ -900,4 +905,8 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor);
*/
void _glfwFreeMonitors(_GLFWmonitor** monitors, int count);
/*! @ingroup utility
*/
int _glfwIsPrintable(int key);
#endif // _glfw3_internal_h_
+7
View File
@@ -802,6 +802,13 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return NULL;
}
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
+9
View File
@@ -130,7 +130,10 @@ static void terminateLibraries(void)
//
static void createKeyTables(void)
{
int scancode;
memset(_glfw.win32.publicKeys, -1, sizeof(_glfw.win32.publicKeys));
memset(_glfw.win32.nativeKeys, -1, sizeof(_glfw.win32.nativeKeys));
_glfw.win32.publicKeys[0x00B] = GLFW_KEY_0;
_glfw.win32.publicKeys[0x002] = GLFW_KEY_1;
@@ -252,6 +255,12 @@ static void createKeyTables(void)
_glfw.win32.publicKeys[0x11C] = GLFW_KEY_KP_ENTER;
_glfw.win32.publicKeys[0x037] = GLFW_KEY_KP_MULTIPLY;
_glfw.win32.publicKeys[0x04A] = GLFW_KEY_KP_SUBTRACT;
for (scancode = 0; scancode < 512; scancode++)
{
if (_glfw.win32.publicKeys[scancode] > 0)
_glfw.win32.nativeKeys[_glfw.win32.publicKeys[scancode]] = scancode;
}
}
+2
View File
@@ -182,7 +182,9 @@ typedef struct _GLFWlibraryWin32
{
DWORD foregroundLockTimeout;
char* clipboardString;
char keyName[64];
short int publicKeys[512];
short int nativeKeys[GLFW_KEY_LAST + 1];
// winmm.dll
struct {
+24
View File
@@ -1180,6 +1180,30 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
SetCursor(NULL);
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
WCHAR name[16];
if (key != GLFW_KEY_UNKNOWN)
scancode = _glfw.win32.nativeKeys[key];
if (!_glfwIsPrintable(_glfw.win32.publicKeys[scancode]))
return NULL;
if (!GetKeyNameTextW(scancode << 16, name, sizeof(name) / sizeof(WCHAR)))
return NULL;
if (!WideCharToMultiByte(CP_UTF8, 0, name, -1,
_glfw.win32.keyName,
sizeof(_glfw.win32.keyName),
NULL, NULL))
{
return NULL;
}
return _glfw.win32.keyName;
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
+6
View File
@@ -436,6 +436,12 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
_glfwPlatformSetCursor(window, window->wl.currentCursor);
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
// TODO
return NULL;
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
+7 -2
View File
@@ -234,6 +234,7 @@ static void createKeyTables(void)
int scancode, key;
memset(_glfw.x11.publicKeys, -1, sizeof(_glfw.x11.publicKeys));
memset(_glfw.x11.nativeKeys, -1, sizeof(_glfw.x11.nativeKeys));
if (_glfw.x11.xkb.available)
{
@@ -312,12 +313,16 @@ static void createKeyTables(void)
XkbFreeClientMap(desc, 0, True);
}
// Translate the un-translated key codes using traditional X11 KeySym
// lookups
for (scancode = 0; scancode < 256; scancode++)
{
// Translate the un-translated key codes using traditional X11 KeySym
// lookups
if (_glfw.x11.publicKeys[scancode] < 0)
_glfw.x11.publicKeys[scancode] = translateKeyCode(scancode);
// Store the reverse translation for faster key name lookup
if (_glfw.x11.publicKeys[scancode] > 0)
_glfw.x11.nativeKeys[_glfw.x11.publicKeys[scancode]] = scancode;
}
}
+4
View File
@@ -121,8 +121,12 @@ typedef struct _GLFWlibraryX11
int errorCode;
// Clipboard string (while the selection is owned)
char* clipboardString;
// Key name string
char keyName[64];
// X11 keycode to GLFW key LUT
short int publicKeys[256];
// GLFW key to X11 keycode LUT
short int nativeKeys[GLFW_KEY_LAST + 1];
// Window manager atoms
Atom WM_PROTOCOLS;
+28
View File
@@ -1939,6 +1939,34 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
}
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
KeySym keysym;
int extra;
if (!_glfw.x11.xkb.available)
return NULL;
if (key != GLFW_KEY_UNKNOWN)
scancode = _glfw.x11.nativeKeys[key];
if (!_glfwIsPrintable(_glfw.x11.publicKeys[scancode]))
return NULL;
keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
if (keysym == NoSymbol)
return NULL;
XkbTranslateKeySym(_glfw.x11.display, &keysym, 0,
_glfw.x11.keyName, sizeof(_glfw.x11.keyName),
&extra);
if (!strlen(_glfw.x11.keyName))
return NULL;
return _glfw.x11.keyName;
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)