Skip to content

Commit

Permalink
Keymap: Add a method to get modified characters for a key
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jscipione committed Oct 18, 2013
1 parent 000e7d4 commit 1d04310
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
5 changes: 5 additions & 0 deletions headers/private/shared/Keymap.h
Expand Up @@ -14,6 +14,8 @@
#include <InterfaceDefs.h>


class BList;

class BKeymap {
public:
BKeymap();
Expand All @@ -38,6 +40,9 @@ class BKeymap {
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; }

Expand Down
55 changes: 55 additions & 0 deletions src/kits/shared/Keymap.cpp
Expand Up @@ -19,6 +19,7 @@

#include <ByteOrder.h>
#include <File.h>
#include <List.h>

#ifdef HAIKU_TARGET_PLATFORM_HAIKU
# include "SystemKeymap.h"
Expand Down Expand Up @@ -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
{
Expand Down

0 comments on commit 1d04310

Please sign in to comment.