Keymap: Add a method to get modified characters for a key

This method fills out the passed-in BList of modified utf-8 characters for
a given utf-8 character and set of modifiers.

For example if you pass in "=" and B_SHIFT_KEY the list will get filled
out with each character in the shift map that has "=" in the normal map.

Each supported keymap modifier combination is available.

The reason this is useful will soon become apparent.

A BList is used because the character might be mapped multiple times,
for example if you have a Mac keyboard you've got two "=" keys, one in
0x1d and one in 0x6a.

The caller is responsible for creating the BList and destroying it as well as
freeing the resulting character strings.
This commit is contained in:
John Scipione
2013-10-18 03:10:00 -04:00
parent 000e7d4088
commit 1d04310459
2 changed files with 60 additions and 0 deletions
+5
View File
@@ -14,6 +14,8 @@
#include <InterfaceDefs.h>
class BList;
class BKeymap {
public:
BKeymap();
@@ -38,6 +40,9 @@ public:
void GetChars(uint32 keyCode, uint32 modifiers,
uint8 activeDeadKey, char** chars,
int32* numBytes) const;
status_t GetModifiedCharacters(const char* normal,
int32 modifiers,
BList* _modifiedCharacters);
const key_map& Map() const { return fKeys; }
+55
View File
@@ -19,6 +19,7 @@
#include <ByteOrder.h>
#include <File.h>
#include <List.h>
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
# include "SystemKeymap.h"
@@ -441,6 +442,60 @@ BKeymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
}
status_t
BKeymap::GetModifiedCharacters(const char* normal, int32 modifiers,
BList* _modifiedCharacters)
{
if (normal == NULL || strcmp(normal, "") == 0
|| _modifiedCharacters == NULL) {
return B_BAD_VALUE;
}
int32 normalOffset;
int32 modifiedOffset;
for(uint32 i = 0; i < 128; i++) {
normalOffset = fKeys.normal_map[i];
size_t sizeNormal = fChars[normalOffset++];
if (sizeNormal == 0
|| memcmp(normal, fChars + normalOffset, sizeNormal) != 0) {
// this character isn't mapped or doesn't match
continue;
}
if (modifiers == B_SHIFT_KEY)
modifiedOffset = fKeys.shift_map[i];
else if (modifiers == B_CONTROL_KEY)
modifiedOffset = fKeys.control_map[i];
else if (modifiers == B_OPTION_KEY)
modifiedOffset = fKeys.option_map[i];
else if (modifiers == (B_OPTION_KEY | B_SHIFT_KEY))
modifiedOffset = fKeys.option_shift_map[i];
else if (modifiers == B_CAPS_LOCK)
modifiedOffset = fKeys.caps_map[i];
else if (modifiers == (B_CAPS_LOCK | B_SHIFT_KEY))
modifiedOffset = fKeys.caps_shift_map[i];
else if (modifiers == (B_OPTION_KEY | B_CAPS_LOCK))
modifiedOffset = fKeys.option_caps_map[i];
else if (modifiers == (B_OPTION_KEY | B_CAPS_LOCK | B_SHIFT_KEY))
modifiedOffset = fKeys.option_caps_shift_map[i];
else
return B_BAD_VALUE;
size_t sizeModified = fChars[modifiedOffset++];
char* modified = (char*)malloc(sizeModified + 1);
if (modified == NULL)
return B_NO_MEMORY;
memcpy(modified, fChars + modifiedOffset, sizeModified);
modified[sizeModified] = '\0';
_modifiedCharacters->AddItem(modified);
}
return B_OK;
}
bool
BKeymap::operator==(const BKeymap& other) const
{