* Factored out a single base class out of the three Keymap implementations we
had in our tree. * Adapted Keymap, <input>keyboard, and consoled to use it - the additional functionality is implemented via a subclass in the first two cases. * "keymap" will come next. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36328 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval
|
||||
* Axel Dörfler, [email protected].
|
||||
*/
|
||||
#ifndef _KEYMAP_H
|
||||
#define _KEYMAP_H
|
||||
|
||||
|
||||
#include <DataIO.h>
|
||||
#include <InterfaceDefs.h>
|
||||
|
||||
|
||||
class BKeymap {
|
||||
public:
|
||||
BKeymap();
|
||||
virtual ~BKeymap();
|
||||
|
||||
status_t SetTo(const char* path);
|
||||
status_t SetTo(BDataIO& stream);
|
||||
status_t SetToCurrent();
|
||||
status_t SetToDefault();
|
||||
void Unset();
|
||||
|
||||
bool IsModifierKey(uint32 keyCode) const;
|
||||
uint32 Modifier(uint32 keyCode) const;
|
||||
uint32 KeyForModifier(uint32 modifier) const;
|
||||
uint8 IsDeadKey(uint32 keyCode,
|
||||
uint32 modifiers,
|
||||
bool* isEnabled = NULL) const;
|
||||
bool IsDeadSecondKey(uint32 keyCode,
|
||||
uint32 modifiers,
|
||||
uint8 activeDeadKey) const;
|
||||
void GetChars(uint32 keyCode, uint32 modifiers,
|
||||
uint8 activeDeadKey, char** chars,
|
||||
int32* numBytes) const;
|
||||
|
||||
const key_map& Map() const { return fKeys; }
|
||||
|
||||
bool operator==(const BKeymap& other) const;
|
||||
bool operator!=(const BKeymap& other) const;
|
||||
|
||||
BKeymap& operator=(const BKeymap& other);
|
||||
|
||||
protected:
|
||||
int32 Offset(uint32 keyCode, uint32 modifiers,
|
||||
uint32* _table = NULL) const;
|
||||
uint8 DeadKeyIndex(int32 offset) const;
|
||||
|
||||
protected:
|
||||
char* fChars;
|
||||
key_map fKeys;
|
||||
uint32 fCharsSize;
|
||||
};
|
||||
|
||||
|
||||
#endif // KEYMAP_H
|
||||
@@ -12,7 +12,7 @@ Addon <input>keyboard :
|
||||
TeamMonitorWindow.cpp
|
||||
TeamListItem.cpp
|
||||
|
||||
: input_server be $(TARGET_LIBSUPC++) ;
|
||||
: input_server be libshared.a $(TARGET_LIBSUPC++) ;
|
||||
|
||||
Package haiku-inputkit-cvs :
|
||||
<input>keyboard :
|
||||
|
||||
@@ -531,8 +531,8 @@ KeyboardDevice::_UpdateSettings(uint32 opcode)
|
||||
if (opcode == 0 || opcode == B_KEY_MAP_CHANGED
|
||||
|| opcode == B_KEY_LOCKS_CHANGED) {
|
||||
BAutolock lock(fKeymapLock);
|
||||
fKeymap.LoadCurrent();
|
||||
fModifiers = fKeymap.Locks();
|
||||
fKeymap.RetrieveCurrent();
|
||||
fModifiers = fKeymap.Map().lock_settings;
|
||||
_UpdateLEDs();
|
||||
fControlKey = fKeymap.KeyForModifier(B_LEFT_CONTROL_KEY);
|
||||
fCommandKey = fKeymap.KeyForModifier(B_LEFT_COMMAND_KEY);
|
||||
|
||||
@@ -13,11 +13,7 @@
|
||||
#include <File.h>
|
||||
#include <InputServerTypes.h>
|
||||
#include <Message.h>
|
||||
#ifdef CONSOLED
|
||||
# include <FindDirectory.h>
|
||||
#else
|
||||
# include <input_globals.h>
|
||||
#endif
|
||||
#include <input_globals.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <new>
|
||||
@@ -64,6 +60,17 @@ print_key(char *chars, int32 offset)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
Keymap::Keymap()
|
||||
{
|
||||
RetrieveCurrent();
|
||||
}
|
||||
|
||||
|
||||
Keymap::~Keymap()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Keymap::DumpKeymap()
|
||||
{
|
||||
@@ -87,413 +94,20 @@ Keymap::DumpKeymap()
|
||||
}
|
||||
|
||||
|
||||
Keymap::Keymap()
|
||||
:
|
||||
fChars(NULL)
|
||||
{
|
||||
#ifndef CONSOLED
|
||||
key_map *keys;
|
||||
_get_key_map(&keys, &fChars, &fCharsSize);
|
||||
|
||||
if (keys) {
|
||||
memcpy(&fKeys, keys, sizeof(key_map));
|
||||
free(keys);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Keymap::~Keymap()
|
||||
{
|
||||
free(fChars);
|
||||
}
|
||||
|
||||
|
||||
/* we need to know if a key is a modifier key to choose
|
||||
a valid key when several are pressed together
|
||||
*/
|
||||
bool
|
||||
Keymap::IsModifierKey(uint32 keyCode)
|
||||
{
|
||||
return keyCode == fKeys.caps_key
|
||||
|| keyCode == fKeys.num_key
|
||||
|| keyCode == fKeys.scroll_key
|
||||
|| keyCode == fKeys.left_shift_key
|
||||
|| keyCode == fKeys.right_shift_key
|
||||
|| keyCode == fKeys.left_command_key
|
||||
|| keyCode == fKeys.right_command_key
|
||||
|| keyCode == fKeys.left_control_key
|
||||
|| keyCode == fKeys.right_control_key
|
||||
|| keyCode == fKeys.left_option_key
|
||||
|| keyCode == fKeys.right_option_key
|
||||
|| keyCode == fKeys.menu_key;
|
||||
}
|
||||
|
||||
|
||||
//! We need to know a modifier for a key
|
||||
uint32
|
||||
Keymap::Modifier(uint32 keyCode)
|
||||
{
|
||||
if (keyCode == fKeys.caps_key)
|
||||
return B_CAPS_LOCK;
|
||||
if (keyCode == fKeys.num_key)
|
||||
return B_NUM_LOCK;
|
||||
if (keyCode == fKeys.scroll_key)
|
||||
return B_SCROLL_LOCK;
|
||||
if (keyCode == fKeys.left_shift_key)
|
||||
return B_LEFT_SHIFT_KEY | B_SHIFT_KEY;
|
||||
if (keyCode == fKeys.right_shift_key)
|
||||
return B_RIGHT_SHIFT_KEY | B_SHIFT_KEY;
|
||||
if (keyCode == fKeys.left_command_key)
|
||||
return B_LEFT_COMMAND_KEY | B_COMMAND_KEY;
|
||||
if (keyCode == fKeys.right_command_key)
|
||||
return B_RIGHT_COMMAND_KEY | B_COMMAND_KEY;
|
||||
if (keyCode == fKeys.left_control_key)
|
||||
return B_LEFT_CONTROL_KEY | B_CONTROL_KEY;
|
||||
if (keyCode == fKeys.right_control_key)
|
||||
return B_RIGHT_CONTROL_KEY | B_CONTROL_KEY;
|
||||
if (keyCode == fKeys.left_option_key)
|
||||
return B_LEFT_OPTION_KEY | B_OPTION_KEY;
|
||||
if (keyCode == fKeys.right_option_key)
|
||||
return B_RIGHT_OPTION_KEY | B_OPTION_KEY;
|
||||
if (keyCode == fKeys.menu_key)
|
||||
return B_MENU_KEY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
Keymap::KeyForModifier(uint32 modifier)
|
||||
{
|
||||
if (modifier == B_CAPS_LOCK)
|
||||
return fKeys.caps_key;
|
||||
if (modifier == B_NUM_LOCK)
|
||||
return fKeys.num_key;
|
||||
if (modifier == B_SCROLL_LOCK)
|
||||
return fKeys.scroll_key;
|
||||
if (modifier == B_LEFT_SHIFT_KEY || modifier == B_SHIFT_KEY)
|
||||
return fKeys.left_shift_key;
|
||||
if (modifier == B_RIGHT_SHIFT_KEY)
|
||||
return fKeys.right_shift_key;
|
||||
if (modifier == B_LEFT_COMMAND_KEY || modifier == B_COMMAND_KEY)
|
||||
return fKeys.left_command_key;
|
||||
if (modifier == B_RIGHT_COMMAND_KEY)
|
||||
return fKeys.right_command_key;
|
||||
if (modifier == B_LEFT_CONTROL_KEY || modifier == B_CONTROL_KEY)
|
||||
return fKeys.left_control_key;
|
||||
if (modifier == B_RIGHT_CONTROL_KEY)
|
||||
return fKeys.right_control_key;
|
||||
if (modifier == B_LEFT_OPTION_KEY || modifier == B_OPTION_KEY)
|
||||
return fKeys.left_option_key;
|
||||
if (modifier == B_RIGHT_OPTION_KEY)
|
||||
return fKeys.right_option_key;
|
||||
if (modifier == B_MENU_KEY)
|
||||
return fKeys.menu_key;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//! Tell if a key is a dead key, needed for draw a dead key
|
||||
uint8
|
||||
Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers)
|
||||
{
|
||||
if (keyCode >= 256)
|
||||
return 0;
|
||||
|
||||
int32 offset;
|
||||
uint32 tableMask = 0;
|
||||
|
||||
switch (modifiers & 0xcf) {
|
||||
case B_SHIFT_KEY: offset = fKeys.shift_map[keyCode]; tableMask = B_SHIFT_TABLE; break;
|
||||
case B_CAPS_LOCK: offset = fKeys.caps_map[keyCode]; tableMask = B_CAPS_TABLE; break;
|
||||
case B_CAPS_LOCK|B_SHIFT_KEY: offset = fKeys.caps_shift_map[keyCode]; tableMask = B_CAPS_SHIFT_TABLE; break;
|
||||
case B_OPTION_KEY: offset = fKeys.option_map[keyCode]; tableMask = B_OPTION_TABLE; break;
|
||||
case B_OPTION_KEY|B_SHIFT_KEY: offset = fKeys.option_shift_map[keyCode]; tableMask = B_OPTION_SHIFT_TABLE; break;
|
||||
case B_OPTION_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_map[keyCode]; tableMask = B_OPTION_CAPS_TABLE; break;
|
||||
case B_OPTION_KEY|B_SHIFT_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_shift_map[keyCode]; tableMask = B_OPTION_CAPS_SHIFT_TABLE; break;
|
||||
case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; tableMask = B_CONTROL_TABLE; break;
|
||||
default: offset = fKeys.normal_map[keyCode]; tableMask = B_NORMAL_TABLE; break;
|
||||
}
|
||||
|
||||
if (offset <= 0 || offset > fCharsSize)
|
||||
return 0;
|
||||
|
||||
uint32 numBytes = fChars[offset];
|
||||
if (!numBytes)
|
||||
return 0;
|
||||
|
||||
char chars[4];
|
||||
strncpy(chars, &(fChars[offset+1]), numBytes );
|
||||
chars[numBytes] = 0;
|
||||
|
||||
int32 deadOffsets[] = {
|
||||
fKeys.acute_dead_key[1],
|
||||
fKeys.grave_dead_key[1],
|
||||
fKeys.circumflex_dead_key[1],
|
||||
fKeys.dieresis_dead_key[1],
|
||||
fKeys.tilde_dead_key[1]
|
||||
};
|
||||
|
||||
uint32 deadTables[] = {
|
||||
fKeys.acute_tables,
|
||||
fKeys.grave_tables,
|
||||
fKeys.circumflex_tables,
|
||||
fKeys.dieresis_tables,
|
||||
fKeys.tilde_tables
|
||||
};
|
||||
|
||||
for (int32 i = 0; i < 5; i++) {
|
||||
if ((deadTables[i] & tableMask) == 0)
|
||||
continue;
|
||||
|
||||
if (offset == deadOffsets[i])
|
||||
return i + 1;
|
||||
|
||||
uint32 deadNumBytes = fChars[deadOffsets[i]];
|
||||
if (!deadNumBytes)
|
||||
continue;
|
||||
|
||||
if (!strncmp(chars, &(fChars[deadOffsets[i] + 1]), deadNumBytes))
|
||||
return i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//! Tell if a key is a dead second key, needed for draw a dead second key
|
||||
bool
|
||||
Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey)
|
||||
{
|
||||
if (!activeDeadKey || keyCode >= 256)
|
||||
return false;
|
||||
|
||||
int32 offset;
|
||||
|
||||
switch (modifiers & 0xcf) {
|
||||
case B_SHIFT_KEY: offset = fKeys.shift_map[keyCode]; break;
|
||||
case B_CAPS_LOCK: offset = fKeys.caps_map[keyCode]; break;
|
||||
case B_CAPS_LOCK|B_SHIFT_KEY: offset = fKeys.caps_shift_map[keyCode]; break;
|
||||
case B_OPTION_KEY: offset = fKeys.option_map[keyCode]; break;
|
||||
case B_OPTION_KEY|B_SHIFT_KEY: offset = fKeys.option_shift_map[keyCode]; break;
|
||||
case B_OPTION_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_map[keyCode]; break;
|
||||
case B_OPTION_KEY|B_SHIFT_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_shift_map[keyCode]; break;
|
||||
case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; break;
|
||||
default: offset = fKeys.normal_map[keyCode]; break;
|
||||
}
|
||||
|
||||
if (offset <= 0 || offset > fCharsSize)
|
||||
return false;
|
||||
|
||||
uint32 numBytes = fChars[offset];
|
||||
if (!numBytes)
|
||||
return false;
|
||||
|
||||
int32* deadOffsets[] = {
|
||||
fKeys.acute_dead_key,
|
||||
fKeys.grave_dead_key,
|
||||
fKeys.circumflex_dead_key,
|
||||
fKeys.dieresis_dead_key,
|
||||
fKeys.tilde_dead_key
|
||||
};
|
||||
|
||||
int32 *deadOffset = deadOffsets[activeDeadKey-1];
|
||||
|
||||
for (int32 i=0; i<32; i++) {
|
||||
if (offset == deadOffset[i])
|
||||
return true;
|
||||
|
||||
uint32 deadNumBytes = fChars[deadOffset[i]];
|
||||
if (!deadNumBytes)
|
||||
continue;
|
||||
|
||||
if (!strncmp(&(fChars[offset+1]), &(fChars[deadOffset[i]+1]), deadNumBytes))
|
||||
return true;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! Get the char for a key given modifiers and active dead key
|
||||
void
|
||||
Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
|
||||
char** chars, int32* numBytes)
|
||||
{
|
||||
*numBytes = 0;
|
||||
*chars = NULL;
|
||||
|
||||
if (keyCode >= 256)
|
||||
return;
|
||||
|
||||
// here we take NUMLOCK into account
|
||||
if (modifiers & B_NUM_LOCK) {
|
||||
switch (keyCode) {
|
||||
case 0x37:
|
||||
case 0x38:
|
||||
case 0x39:
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
modifiers ^= B_SHIFT_KEY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32 offset;
|
||||
|
||||
// here we choose the right map given the modifiers
|
||||
switch (modifiers & 0xcf) {
|
||||
case B_SHIFT_KEY: offset = fKeys.shift_map[keyCode]; break;
|
||||
case B_CAPS_LOCK: offset = fKeys.caps_map[keyCode]; break;
|
||||
case B_CAPS_LOCK|B_SHIFT_KEY: offset = fKeys.caps_shift_map[keyCode]; break;
|
||||
case B_OPTION_KEY: offset = fKeys.option_map[keyCode]; break;
|
||||
case B_OPTION_KEY|B_SHIFT_KEY: offset = fKeys.option_shift_map[keyCode]; break;
|
||||
case B_OPTION_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_map[keyCode]; break;
|
||||
case B_OPTION_KEY|B_SHIFT_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_shift_map[keyCode]; break;
|
||||
case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; break;
|
||||
|
||||
default:
|
||||
offset = fKeys.normal_map[keyCode];
|
||||
break;
|
||||
}
|
||||
|
||||
if (offset <= 0)
|
||||
return;
|
||||
|
||||
// here we get the char size
|
||||
*numBytes = fChars[offset];
|
||||
if (!*numBytes)
|
||||
return;
|
||||
|
||||
// here we take an potential active dead key
|
||||
int32 *deadKey;
|
||||
switch (activeDeadKey) {
|
||||
case 1: deadKey = fKeys.acute_dead_key; break;
|
||||
case 2: deadKey = fKeys.grave_dead_key; break;
|
||||
case 3: deadKey = fKeys.circumflex_dead_key; break;
|
||||
case 4: deadKey = fKeys.dieresis_dead_key; break;
|
||||
case 5: deadKey = fKeys.tilde_dead_key; break;
|
||||
default:
|
||||
{
|
||||
// if not dead, we copy and return the char
|
||||
char *str = *chars = new (std::nothrow) char[*numBytes + 1];
|
||||
if (str == NULL) {
|
||||
*numBytes = 0;
|
||||
return;
|
||||
}
|
||||
strncpy(str, &(fChars[offset + 1]), *numBytes);
|
||||
str[*numBytes] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if dead key, we search for our current offset char in the dead key offset table
|
||||
// string comparison is needed
|
||||
for (int32 i = 0; i < 32; i++) {
|
||||
if (strncmp(&(fChars[offset + 1]), &(fChars[deadKey[i] + 1]), *numBytes) == 0) {
|
||||
*numBytes = fChars[deadKey[i + 1]];
|
||||
|
||||
switch (*numBytes) {
|
||||
case 0:
|
||||
// Not mapped
|
||||
*chars = NULL;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// 1-, 2-, 3-, or 4-byte UTF-8 character
|
||||
char *str = *chars = new (std::nothrow) char[*numBytes + 1];
|
||||
if (str == NULL) {
|
||||
*numBytes = 0;
|
||||
return;
|
||||
}
|
||||
strncpy(str, &fChars[deadKey[i + 1] + 1], *numBytes);
|
||||
str[*numBytes] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// if not found we return the whole sequence (the dead key itself plus
|
||||
// the following char)
|
||||
int32 deadKeyNumBytes = fChars[deadKey[1]];
|
||||
int32 fullNumBytes = deadKeyNumBytes + *numBytes;
|
||||
*chars = new (std::nothrow) char[fullNumBytes + 1];
|
||||
if (*chars == NULL) {
|
||||
*numBytes = 0;
|
||||
return;
|
||||
}
|
||||
strncpy(*chars, &fChars[deadKey[1] + 1], deadKeyNumBytes);
|
||||
strncpy(*chars + deadKeyNumBytes, &fChars[offset + 1], *numBytes);
|
||||
*numBytes = fullNumBytes;
|
||||
(*chars)[fullNumBytes] = 0;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Keymap::LoadCurrent()
|
||||
Keymap::RetrieveCurrent()
|
||||
{
|
||||
#ifndef CONSOLED
|
||||
key_map* keys = NULL;
|
||||
free(fChars);
|
||||
fChars = NULL;
|
||||
Unset();
|
||||
|
||||
_get_key_map(&keys, &fChars, &fCharsSize);
|
||||
key_map* keys;
|
||||
_get_key_map(&keys, &fChars, (ssize_t*)&fCharsSize);
|
||||
if (!keys) {
|
||||
fprintf(stderr, "error while getting current keymap!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
memcpy(&fKeys, keys, sizeof(fKeys));
|
||||
free(keys);
|
||||
return B_OK;
|
||||
#else // CONSOLED
|
||||
char path[PATH_MAX];
|
||||
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, -1, false,
|
||||
path, sizeof(path));
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
strlcat(path, "/Key_map", sizeof(path));
|
||||
int file = open(path, O_RDONLY);
|
||||
if (file < 0)
|
||||
return errno;
|
||||
|
||||
if (read(file, &fKeys, sizeof(fKeys)) < (ssize_t)sizeof(fKeys)) {
|
||||
fprintf(stderr, "error reading keymap keys\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < sizeof(fKeys) / 4; i++)
|
||||
((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);
|
||||
|
||||
if (read(file, &fCharsSize, sizeof(uint32)) < (ssize_t)sizeof(uint32)) {
|
||||
fprintf(stderr, "error reading keymap size\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize);
|
||||
if (fCharsSize < 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
fChars = new char[fCharsSize];
|
||||
|
||||
if (read(file, fChars, fCharsSize) < 0) {
|
||||
fprintf(stderr, "error reading keymap chars\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
#endif // CONSOLED
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004, Haiku.
|
||||
* Copyright 2004-2010, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -9,33 +9,18 @@
|
||||
#define KEYMAP_H
|
||||
|
||||
|
||||
#include <InterfaceDefs.h>
|
||||
#include <Keymap.h>
|
||||
#include <Entry.h>
|
||||
|
||||
|
||||
class Keymap {
|
||||
class Keymap : public BKeymap {
|
||||
public:
|
||||
Keymap();
|
||||
~Keymap();
|
||||
|
||||
void DumpKeymap();
|
||||
bool IsModifierKey(uint32 keyCode);
|
||||
uint32 Modifier(uint32 keyCode);
|
||||
uint32 KeyForModifier(uint32 modifier);
|
||||
uint8 IsDeadKey(uint32 keyCode, uint32 modifiers);
|
||||
bool IsDeadSecondKey(uint32 keyCode,
|
||||
uint32 modifiers, uint8 activeDeadKey);
|
||||
void GetChars(uint32 keyCode, uint32 modifiers,
|
||||
uint8 activeDeadKey, char** chars,
|
||||
int32* numBytes);
|
||||
uint32 Locks() { return fKeys.lock_settings; };
|
||||
|
||||
status_t LoadCurrent();
|
||||
|
||||
private:
|
||||
char* fChars;
|
||||
key_map fKeys;
|
||||
ssize_t fCharsSize;
|
||||
status_t RetrieveCurrent();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,25 +1,9 @@
|
||||
SubDir HAIKU_TOP src bin consoled ;
|
||||
|
||||
UsePrivateHeaders input ;
|
||||
UsePrivateHeaders kernel ;
|
||||
UsePrivateHeaders input kernel shared ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src apps terminal ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_COMMON_DEBUG_OBJECT_DIR) servers input ] ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons input_server devices
|
||||
keyboard ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src servers input ] ;
|
||||
|
||||
{
|
||||
local defines = [ FDefines CONSOLED ] ;
|
||||
SubDirCcFlags $(defines) -Wall -Wno-multichar ;
|
||||
SubDirC++Flags $(defines) -Wall -Wno-multichar ;
|
||||
}
|
||||
|
||||
Application consoled :
|
||||
consoled.cpp
|
||||
|
||||
Keymap.cpp
|
||||
: $(TARGET_LIBSUPC++)
|
||||
: be libshared.a $(TARGET_LIBSUPC++)
|
||||
;
|
||||
|
||||
Includes [ FGristFiles consoled.cpp ] : <src!servers!input>SystemKeymap.h ;
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <FindDirectory.h>
|
||||
#include <image.h>
|
||||
#include <InterfaceDefs.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include <keyboard_mouse_driver.h>
|
||||
|
||||
#include "SystemKeymap.h"
|
||||
#include "Keymap.h"
|
||||
#include <Keymap.h>
|
||||
|
||||
|
||||
struct console;
|
||||
@@ -91,8 +90,19 @@ keyboard_reader(void* arg)
|
||||
uint8 activeDeadKey = 0;
|
||||
uint32 modifiers = 0;
|
||||
|
||||
Keymap keymap;
|
||||
keymap.LoadCurrent();
|
||||
BKeymap keymap;
|
||||
// Load current keymap from disk (we can't talk to the input server)
|
||||
// TODO: find a better way (we shouldn't have to care about the on-disk
|
||||
// location)
|
||||
char path[PATH_MAX];
|
||||
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, -1, false,
|
||||
path, sizeof(path));
|
||||
if (status == B_OK) {
|
||||
strlcat(path, "/Key_map", sizeof(path));
|
||||
status = keymap.SetTo(path);
|
||||
}
|
||||
if (status != B_OK)
|
||||
keymap.SetToDefault();
|
||||
|
||||
for (;;) {
|
||||
raw_key_info rawKeyInfo;
|
||||
|
||||
@@ -5,6 +5,7 @@ AddSubDirSupportedPlatforms libbe_test ;
|
||||
|
||||
UseLibraryHeaders agg ;
|
||||
UsePrivateHeaders shared libbe ;
|
||||
UseHeaders [ FDirName $(HAIKU_COMMON_DEBUG_OBJECT_DIR) servers input ] ;
|
||||
|
||||
# for RWLockManager only
|
||||
UsePrivateSystemHeaders ;
|
||||
@@ -17,12 +18,14 @@ StaticLibrary libshared.a :
|
||||
CommandPipe.cpp
|
||||
DragTrackingFilter.cpp
|
||||
HashString.cpp
|
||||
Keymap.cpp
|
||||
RWLockManager.cpp
|
||||
ShakeTrackingFilter.cpp
|
||||
StringForSize.cpp
|
||||
Variant.cpp
|
||||
;
|
||||
|
||||
Includes [ FGristFiles Keymap.cpp ] : <src!servers!input>SystemKeymap.h ;
|
||||
|
||||
UseLibraryHeaders mapm ;
|
||||
|
||||
|
||||
@@ -0,0 +1,537 @@
|
||||
/*
|
||||
* Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval
|
||||
* Axel Dörfler, [email protected].
|
||||
*/
|
||||
|
||||
|
||||
#include <Keymap.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <File.h>
|
||||
|
||||
#include "SystemKeymap.h"
|
||||
// generated by the build system
|
||||
|
||||
|
||||
// Private only at this point, as we might want to improve the dead key
|
||||
// implementation in the future
|
||||
enum dead_key_index {
|
||||
kDeadKeyAcute = 1,
|
||||
kDeadKeyGrave,
|
||||
kDeadKeyCircumflex,
|
||||
kDeadKeyDiaeresis,
|
||||
kDeadKeyTilde
|
||||
};
|
||||
|
||||
|
||||
static const uint32 kModifierKeys = B_SHIFT_KEY | B_COMMAND_KEY | B_CONTROL_KEY
|
||||
| B_CAPS_LOCK | B_OPTION_KEY | B_MENU_KEY;
|
||||
|
||||
|
||||
BKeymap::BKeymap()
|
||||
:
|
||||
fChars(NULL),
|
||||
fCharsSize(0)
|
||||
{
|
||||
Unset();
|
||||
}
|
||||
|
||||
|
||||
BKeymap::~BKeymap()
|
||||
{
|
||||
delete[] fChars;
|
||||
}
|
||||
|
||||
|
||||
/*! Load a map from a file.
|
||||
File format in big endian:
|
||||
struct key_map
|
||||
uint32 size of following charset
|
||||
charset (offsets go into this with size of character followed by
|
||||
character)
|
||||
*/
|
||||
status_t
|
||||
BKeymap::SetTo(const char* path)
|
||||
{
|
||||
BFile file;
|
||||
status_t status = file.SetTo(path, B_READ_ONLY);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return SetTo(file);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BKeymap::SetTo(BDataIO& stream)
|
||||
{
|
||||
if (stream.Read(&fKeys, sizeof(fKeys)) < 1)
|
||||
return B_IO_ERROR;
|
||||
|
||||
// convert from big-endian
|
||||
for (uint32 i = 0; i < sizeof(fKeys) / 4; i++) {
|
||||
((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);
|
||||
}
|
||||
|
||||
if (fKeys.version != 3)
|
||||
return B_BAD_DATA;
|
||||
|
||||
if (stream.Read(&fCharsSize, sizeof(uint32)) < 1)
|
||||
return B_IO_ERROR;
|
||||
|
||||
fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize);
|
||||
if (fCharsSize > 16 * 1024) {
|
||||
Unset();
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
delete[] fChars;
|
||||
fChars = new char[fCharsSize];
|
||||
|
||||
if (stream.Read(fChars, fCharsSize) != (ssize_t)fCharsSize) {
|
||||
Unset();
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BKeymap::SetToCurrent()
|
||||
{
|
||||
#if (defined(__BEOS__) || defined(__HAIKU__))
|
||||
key_map* keys = NULL;
|
||||
get_key_map(&keys, &fChars);
|
||||
if (!keys)
|
||||
return B_ERROR;
|
||||
|
||||
memcpy(&fKeys, keys, sizeof(fKeys));
|
||||
free(keys);
|
||||
return B_OK;
|
||||
#else // ! __BEOS__
|
||||
fprintf(stderr, "Unsupported operation on this platform!\n");
|
||||
exit(1);
|
||||
#endif // ! __BEOS__
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BKeymap::SetToDefault()
|
||||
{
|
||||
fKeys = kSystemKeymap;
|
||||
fCharsSize = kSystemKeyCharsSize;
|
||||
|
||||
fChars = new (std::nothrow) char[fCharsSize];
|
||||
if (fChars == NULL) {
|
||||
Unset();
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(fChars, kSystemKeyChars, fCharsSize);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BKeymap::Unset()
|
||||
{
|
||||
delete fChars;
|
||||
fChars = NULL;
|
||||
fCharsSize = 0;
|
||||
|
||||
memset(&fKeys, 0, sizeof(fKeys));
|
||||
}
|
||||
|
||||
|
||||
/*! We need to know if a key is a modifier key to choose
|
||||
a valid key when several are pressed together
|
||||
*/
|
||||
bool
|
||||
BKeymap::IsModifierKey(uint32 keyCode) const
|
||||
{
|
||||
return keyCode == fKeys.caps_key
|
||||
|| keyCode == fKeys.num_key
|
||||
|| keyCode == fKeys.left_shift_key
|
||||
|| keyCode == fKeys.right_shift_key
|
||||
|| keyCode == fKeys.left_command_key
|
||||
|| keyCode == fKeys.right_command_key
|
||||
|| keyCode == fKeys.left_control_key
|
||||
|| keyCode == fKeys.right_control_key
|
||||
|| keyCode == fKeys.left_option_key
|
||||
|| keyCode == fKeys.right_option_key
|
||||
|| keyCode == fKeys.menu_key;
|
||||
}
|
||||
|
||||
|
||||
//! We need to know a modifier for a key
|
||||
uint32
|
||||
BKeymap::Modifier(uint32 keyCode) const
|
||||
{
|
||||
if (keyCode == fKeys.caps_key)
|
||||
return B_CAPS_LOCK;
|
||||
if (keyCode == fKeys.num_key)
|
||||
return B_NUM_LOCK;
|
||||
if (keyCode == fKeys.scroll_key)
|
||||
return B_SCROLL_LOCK;
|
||||
if (keyCode == fKeys.left_shift_key)
|
||||
return B_LEFT_SHIFT_KEY | B_SHIFT_KEY;
|
||||
if (keyCode == fKeys.right_shift_key)
|
||||
return B_RIGHT_SHIFT_KEY | B_SHIFT_KEY;
|
||||
if (keyCode == fKeys.left_command_key)
|
||||
return B_LEFT_COMMAND_KEY | B_COMMAND_KEY;
|
||||
if (keyCode == fKeys.right_command_key)
|
||||
return B_RIGHT_COMMAND_KEY | B_COMMAND_KEY;
|
||||
if (keyCode == fKeys.left_control_key)
|
||||
return B_LEFT_CONTROL_KEY | B_CONTROL_KEY;
|
||||
if (keyCode == fKeys.right_control_key)
|
||||
return B_RIGHT_CONTROL_KEY | B_CONTROL_KEY;
|
||||
if (keyCode == fKeys.left_option_key)
|
||||
return B_LEFT_OPTION_KEY | B_OPTION_KEY;
|
||||
if (keyCode == fKeys.right_option_key)
|
||||
return B_RIGHT_OPTION_KEY | B_OPTION_KEY;
|
||||
if (keyCode == fKeys.menu_key)
|
||||
return B_MENU_KEY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
BKeymap::KeyForModifier(uint32 modifier) const
|
||||
{
|
||||
if (modifier == B_CAPS_LOCK)
|
||||
return fKeys.caps_key;
|
||||
if (modifier == B_NUM_LOCK)
|
||||
return fKeys.num_key;
|
||||
if (modifier == B_SCROLL_LOCK)
|
||||
return fKeys.scroll_key;
|
||||
if (modifier == B_LEFT_SHIFT_KEY || modifier == B_SHIFT_KEY)
|
||||
return fKeys.left_shift_key;
|
||||
if (modifier == B_RIGHT_SHIFT_KEY)
|
||||
return fKeys.right_shift_key;
|
||||
if (modifier == B_LEFT_COMMAND_KEY || modifier == B_COMMAND_KEY)
|
||||
return fKeys.left_command_key;
|
||||
if (modifier == B_RIGHT_COMMAND_KEY)
|
||||
return fKeys.right_command_key;
|
||||
if (modifier == B_LEFT_CONTROL_KEY || modifier == B_CONTROL_KEY)
|
||||
return fKeys.left_control_key;
|
||||
if (modifier == B_RIGHT_CONTROL_KEY)
|
||||
return fKeys.right_control_key;
|
||||
if (modifier == B_LEFT_OPTION_KEY || modifier == B_OPTION_KEY)
|
||||
return fKeys.left_option_key;
|
||||
if (modifier == B_RIGHT_OPTION_KEY)
|
||||
return fKeys.right_option_key;
|
||||
if (modifier == B_MENU_KEY)
|
||||
return fKeys.menu_key;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Checks whether a key is a dead key.
|
||||
If it is, the enabled/disabled state of that dead key will be passed
|
||||
out via isEnabled (isEnabled is not touched for non-dead keys).
|
||||
*/
|
||||
uint8
|
||||
BKeymap::IsDeadKey(uint32 keyCode, uint32 modifiers, bool* _isEnabled) const
|
||||
{
|
||||
uint32 tableMask = 0;
|
||||
int32 offset = Offset(keyCode, modifiers, &tableMask);
|
||||
uint8 deadKeyIndex = DeadKeyIndex(offset);
|
||||
if (deadKeyIndex > 0 && _isEnabled != NULL) {
|
||||
uint32 deadTables[] = {
|
||||
fKeys.acute_tables,
|
||||
fKeys.grave_tables,
|
||||
fKeys.circumflex_tables,
|
||||
fKeys.dieresis_tables,
|
||||
fKeys.tilde_tables
|
||||
};
|
||||
*_isEnabled = (deadTables[deadKeyIndex - 1] & tableMask) != 0;
|
||||
}
|
||||
|
||||
return deadKeyIndex;
|
||||
}
|
||||
|
||||
|
||||
//! Tell if a key is a dead second key.
|
||||
bool
|
||||
BKeymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers,
|
||||
uint8 activeDeadKey) const
|
||||
{
|
||||
if (!activeDeadKey)
|
||||
return false;
|
||||
|
||||
int32 offset = Offset(keyCode, modifiers);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
uint32 numBytes = fChars[offset];
|
||||
if (!numBytes)
|
||||
return false;
|
||||
|
||||
const int32* deadOffsets[] = {
|
||||
fKeys.acute_dead_key,
|
||||
fKeys.grave_dead_key,
|
||||
fKeys.circumflex_dead_key,
|
||||
fKeys.dieresis_dead_key,
|
||||
fKeys.tilde_dead_key
|
||||
};
|
||||
|
||||
const int32* deadOffset = deadOffsets[activeDeadKey - 1];
|
||||
|
||||
for (int32 i = 0; i < 32; i++) {
|
||||
if (offset == deadOffset[i])
|
||||
return true;
|
||||
|
||||
uint32 deadNumBytes = fChars[deadOffset[i]];
|
||||
|
||||
if (!deadNumBytes)
|
||||
continue;
|
||||
|
||||
if (strncmp(&fChars[offset + 1], &fChars[deadOffset[i] + 1],
|
||||
deadNumBytes) == 0)
|
||||
return true;
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! Get the char for a key given modifiers and active dead key
|
||||
void
|
||||
BKeymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
|
||||
char** chars, int32* numBytes) const
|
||||
{
|
||||
*numBytes = 0;
|
||||
*chars = NULL;
|
||||
|
||||
if (keyCode > 128 || fChars == NULL)
|
||||
return;
|
||||
|
||||
// here we take NUMLOCK into account
|
||||
if ((modifiers & B_NUM_LOCK) != 0) {
|
||||
switch (keyCode) {
|
||||
case 0x37:
|
||||
case 0x38:
|
||||
case 0x39:
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
modifiers ^= B_SHIFT_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
int32 offset = Offset(keyCode, modifiers);
|
||||
if (offset < 0)
|
||||
return;
|
||||
|
||||
// here we get the char size
|
||||
*numBytes = fChars[offset];
|
||||
if (!*numBytes)
|
||||
return;
|
||||
|
||||
// here we take an potential active dead key
|
||||
const int32* deadKey;
|
||||
switch (activeDeadKey) {
|
||||
case kDeadKeyAcute:
|
||||
deadKey = fKeys.acute_dead_key;
|
||||
break;
|
||||
case kDeadKeyGrave:
|
||||
deadKey = fKeys.grave_dead_key;
|
||||
break;
|
||||
case kDeadKeyCircumflex:
|
||||
deadKey = fKeys.circumflex_dead_key;
|
||||
break;
|
||||
case kDeadKeyDiaeresis:
|
||||
deadKey = fKeys.dieresis_dead_key;
|
||||
break;
|
||||
case kDeadKeyTilde:
|
||||
deadKey = fKeys.tilde_dead_key;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// if not dead, we copy and return the char
|
||||
char* str = *chars = new char[*numBytes + 1];
|
||||
strncpy(str, &fChars[offset + 1], *numBytes);
|
||||
str[*numBytes] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if dead key, we search for our current offset char in the dead key
|
||||
// offset table string comparison is needed
|
||||
for (int32 i = 0; i < 32; i++) {
|
||||
if (strncmp(&fChars[offset + 1], &fChars[deadKey[i] + 1], *numBytes)
|
||||
== 0) {
|
||||
*numBytes = fChars[deadKey[i + 1]];
|
||||
|
||||
switch (*numBytes) {
|
||||
case 0:
|
||||
// Not mapped
|
||||
*chars = NULL;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// 1-, 2-, 3-, or 4-byte UTF-8 character
|
||||
char *str = *chars = new char[*numBytes + 1];
|
||||
strncpy(str, &fChars[deadKey[i + 1] + 1], *numBytes);
|
||||
str[*numBytes] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// if not found we return the current char mapped
|
||||
*chars = new char[*numBytes + 1];
|
||||
strncpy(*chars, &fChars[offset + 1], *numBytes);
|
||||
(*chars)[*numBytes] = 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BKeymap::operator==(const BKeymap& other) const
|
||||
{
|
||||
return fCharsSize == other.fCharsSize
|
||||
&& !memcmp(&fKeys, &other.fKeys, sizeof(fKeys))
|
||||
&& !memcmp(fChars, other.fChars, sizeof(fChars));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BKeymap::operator!=(const BKeymap& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
BKeymap&
|
||||
BKeymap::operator=(const BKeymap& other)
|
||||
{
|
||||
Unset();
|
||||
|
||||
fChars = new char[fCharsSize];
|
||||
fCharsSize = other.fCharsSize;
|
||||
memcpy(fChars, other.fChars, fCharsSize);
|
||||
memcpy(&fKeys, &other.fKeys, sizeof(fKeys));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BKeymap::Offset(uint32 keyCode, uint32 modifiers, uint32* _table) const
|
||||
{
|
||||
int32 offset;
|
||||
uint32 table;
|
||||
|
||||
if (keyCode >= 128)
|
||||
return -1;
|
||||
|
||||
switch (modifiers & kModifierKeys) {
|
||||
case B_SHIFT_KEY:
|
||||
offset = fKeys.shift_map[keyCode];
|
||||
table = B_SHIFT_TABLE;
|
||||
break;
|
||||
case B_CAPS_LOCK:
|
||||
offset = fKeys.caps_map[keyCode];
|
||||
table = B_CAPS_TABLE;
|
||||
break;
|
||||
case B_CAPS_LOCK | B_SHIFT_KEY:
|
||||
offset = fKeys.caps_shift_map[keyCode];
|
||||
table = B_CAPS_SHIFT_TABLE;
|
||||
break;
|
||||
case B_OPTION_KEY:
|
||||
offset = fKeys.option_map[keyCode];
|
||||
table = B_OPTION_TABLE;
|
||||
break;
|
||||
case B_OPTION_KEY | B_SHIFT_KEY:
|
||||
offset = fKeys.option_shift_map[keyCode];
|
||||
table = B_OPTION_SHIFT_TABLE;
|
||||
break;
|
||||
case B_OPTION_KEY | B_CAPS_LOCK:
|
||||
offset = fKeys.option_caps_map[keyCode];
|
||||
table = B_OPTION_CAPS_TABLE;
|
||||
break;
|
||||
case B_OPTION_KEY | B_SHIFT_KEY | B_CAPS_LOCK:
|
||||
offset = fKeys.option_caps_shift_map[keyCode];
|
||||
table = B_OPTION_CAPS_SHIFT_TABLE;
|
||||
break;
|
||||
case B_CONTROL_KEY:
|
||||
offset = fKeys.control_map[keyCode];
|
||||
table = B_CONTROL_TABLE;
|
||||
break;
|
||||
default:
|
||||
offset = fKeys.normal_map[keyCode];
|
||||
table = B_NORMAL_TABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_table != NULL)
|
||||
*_table = table;
|
||||
|
||||
if (offset >= (int32)fCharsSize)
|
||||
return -1;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
BKeymap::DeadKeyIndex(int32 offset) const
|
||||
{
|
||||
if (fChars == NULL || offset <= 0)
|
||||
return 0;
|
||||
|
||||
uint32 numBytes = fChars[offset];
|
||||
if (!numBytes)
|
||||
return 0;
|
||||
|
||||
char chars[4];
|
||||
strncpy(chars, &fChars[offset + 1], numBytes);
|
||||
chars[numBytes] = 0;
|
||||
|
||||
const int32 deadOffsets[] = {
|
||||
fKeys.acute_dead_key[1],
|
||||
fKeys.grave_dead_key[1],
|
||||
fKeys.circumflex_dead_key[1],
|
||||
fKeys.dieresis_dead_key[1],
|
||||
fKeys.tilde_dead_key[1]
|
||||
};
|
||||
|
||||
uint8 result = 0;
|
||||
for (int32 i = 0; i < 5; i++) {
|
||||
if (offset == deadOffsets[i]) {
|
||||
result = i + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 deadNumBytes = fChars[deadOffsets[i]];
|
||||
if (!deadNumBytes)
|
||||
continue;
|
||||
|
||||
if (strncmp(chars, &fChars[deadOffsets[i] + 1], deadNumBytes) == 0) {
|
||||
result = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -12,7 +12,7 @@ Preference Keymap :
|
||||
KeymapListItem.cpp
|
||||
KeymapWindow.cpp
|
||||
|
||||
: be tracker liblocale.so $(TARGET_LIBSTDC++)
|
||||
: be tracker liblocale.so libshared.a $(TARGET_LIBSTDC++)
|
||||
: Keymap.rdef
|
||||
;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2009 Haiku Inc. All rights reserved.
|
||||
* Copyright 2004-2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -8,6 +8,7 @@
|
||||
* Axel Dörfler, axeld@pinc-software.de.
|
||||
*/
|
||||
|
||||
|
||||
#include "Keymap.h"
|
||||
|
||||
#include <new>
|
||||
@@ -61,8 +62,6 @@ print_key(char *chars, int32 offset)
|
||||
|
||||
Keymap::Keymap()
|
||||
:
|
||||
fChars(NULL),
|
||||
fCharsSize(0),
|
||||
fModificationMessage(NULL)
|
||||
{
|
||||
}
|
||||
@@ -96,7 +95,8 @@ Keymap::DumpKeymap()
|
||||
{
|
||||
// Print a chart of the normal, shift, option, and option+shift
|
||||
// keys.
|
||||
printf("Key #\tNormal\tShift\tCaps\tC+S\tOption\tO+S\tO+C\tO+C+S\tControl\n");
|
||||
printf("Key #\tNormal\tShift\tCaps\tC+S\tOption\tO+S\tO+C\tO+C+S\t"
|
||||
"Control\n");
|
||||
for (int i = 0; i < 128; i++) {
|
||||
printf(" 0x%x\t", i);
|
||||
print_key(fChars, fKeys.normal_map[i]);
|
||||
@@ -113,61 +113,29 @@ Keymap::DumpKeymap()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
file format in big endian :
|
||||
struct key_map
|
||||
uint32 size of following charset
|
||||
charset (offsets go into this with size of character followed by character)
|
||||
*/
|
||||
// we load a map from a file
|
||||
//! Load a map from a file
|
||||
status_t
|
||||
Keymap::Load(entry_ref &ref)
|
||||
{
|
||||
status_t err;
|
||||
BEntry entry(&ref, true);
|
||||
if ((err = entry.InitCheck()) != B_OK) {
|
||||
fprintf(stderr, "error loading keymap: %s\n", strerror(err));
|
||||
return err;
|
||||
}
|
||||
BEntry entry;
|
||||
status_t status = entry.SetTo(&ref, true);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BFile file(&entry, B_READ_ONLY);
|
||||
if ((err = file.InitCheck()) != B_OK) {
|
||||
fprintf(stderr, "error loading keymap: %s\n", strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = file.Read(&fKeys, sizeof(fKeys))) < (ssize_t)sizeof(fKeys)) {
|
||||
fprintf(stderr, "error reading keymap keys: %s\n", strerror(err));
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < sizeof(fKeys) / 4; i++)
|
||||
((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);
|
||||
|
||||
if ((err = file.Read(&fCharsSize, sizeof(uint32))) < (ssize_t)sizeof(uint32)) {
|
||||
fprintf(stderr, "error reading keymap size: %s\n", strerror(err));
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize);
|
||||
delete[] fChars;
|
||||
|
||||
fChars = new char[fCharsSize];
|
||||
|
||||
ssize_t bytesRead = file.Read(fChars, fCharsSize);
|
||||
if (bytesRead < 0) {
|
||||
fprintf(stderr, "error reading keymap chars: %s\n", strerror(err));
|
||||
return (status_t)bytesRead;
|
||||
}
|
||||
status = SetTo(file);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
// fetch name from attribute and fall back to filename
|
||||
|
||||
bytesRead = file.ReadAttr("keymap:name", B_STRING_TYPE, 0, fName,
|
||||
ssize_t bytesRead = file.ReadAttr("keymap:name", B_STRING_TYPE, 0, fName,
|
||||
sizeof(fName));
|
||||
if (bytesRead > 0)
|
||||
fName[bytesRead] = '\0';
|
||||
else
|
||||
strlcpy(fName, ref.name, sizeof(fName));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -219,103 +187,6 @@ Keymap::Save(entry_ref& ref)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Keymap::Equals(const Keymap& other) const
|
||||
{
|
||||
// not really efficient but this is the only way i found
|
||||
// to reliably compare keymaps (used only for apply and revert)
|
||||
return fCharsSize == other.fCharsSize
|
||||
&& !memcmp(&other.fKeys, &fKeys, sizeof(key_map))
|
||||
&& !memcmp(other.fChars, fChars, fCharsSize);
|
||||
}
|
||||
|
||||
|
||||
/*! We need to know if a key is a modifier key to choose
|
||||
a valid key when several are pressed together.
|
||||
*/
|
||||
bool
|
||||
Keymap::IsModifierKey(uint32 keyCode)
|
||||
{
|
||||
return keyCode == fKeys.caps_key
|
||||
|| keyCode == fKeys.num_key
|
||||
|| keyCode == fKeys.scroll_key
|
||||
|| keyCode == fKeys.left_shift_key
|
||||
|| keyCode == fKeys.right_shift_key
|
||||
|| keyCode == fKeys.left_command_key
|
||||
|| keyCode == fKeys.right_command_key
|
||||
|| keyCode == fKeys.left_control_key
|
||||
|| keyCode == fKeys.right_control_key
|
||||
|| keyCode == fKeys.left_option_key
|
||||
|| keyCode == fKeys.right_option_key
|
||||
|| keyCode == fKeys.menu_key;
|
||||
}
|
||||
|
||||
|
||||
//! We need to know a modifier for a key
|
||||
uint32
|
||||
Keymap::Modifier(uint32 keyCode)
|
||||
{
|
||||
if (keyCode == fKeys.caps_key)
|
||||
return B_CAPS_LOCK;
|
||||
if (keyCode == fKeys.num_key)
|
||||
return B_NUM_LOCK;
|
||||
if (keyCode == fKeys.scroll_key)
|
||||
return B_SCROLL_LOCK;
|
||||
if (keyCode == fKeys.left_shift_key)
|
||||
return B_LEFT_SHIFT_KEY | B_SHIFT_KEY;
|
||||
if (keyCode == fKeys.right_shift_key)
|
||||
return B_RIGHT_SHIFT_KEY | B_SHIFT_KEY;
|
||||
if (keyCode == fKeys.left_command_key)
|
||||
return B_LEFT_COMMAND_KEY | B_COMMAND_KEY;
|
||||
if (keyCode == fKeys.right_command_key)
|
||||
return B_RIGHT_COMMAND_KEY | B_COMMAND_KEY;
|
||||
if (keyCode == fKeys.left_control_key)
|
||||
return B_LEFT_CONTROL_KEY | B_CONTROL_KEY;
|
||||
if (keyCode == fKeys.right_control_key)
|
||||
return B_RIGHT_CONTROL_KEY | B_CONTROL_KEY;
|
||||
if (keyCode == fKeys.left_option_key)
|
||||
return B_LEFT_OPTION_KEY | B_OPTION_KEY;
|
||||
if (keyCode == fKeys.right_option_key)
|
||||
return B_RIGHT_OPTION_KEY | B_OPTION_KEY;
|
||||
if (keyCode == fKeys.menu_key)
|
||||
return B_MENU_KEY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
Keymap::KeyForModifier(uint32 modifier)
|
||||
{
|
||||
if (modifier == B_CAPS_LOCK)
|
||||
return fKeys.caps_key;
|
||||
if (modifier == B_NUM_LOCK)
|
||||
return fKeys.num_key;
|
||||
if (modifier == B_SCROLL_LOCK)
|
||||
return fKeys.scroll_key;
|
||||
if (modifier == B_LEFT_SHIFT_KEY || modifier == B_SHIFT_KEY)
|
||||
return fKeys.left_shift_key;
|
||||
if (modifier == B_RIGHT_SHIFT_KEY)
|
||||
return fKeys.right_shift_key;
|
||||
if (modifier == B_LEFT_COMMAND_KEY || modifier == B_COMMAND_KEY)
|
||||
return fKeys.left_command_key;
|
||||
if (modifier == B_RIGHT_COMMAND_KEY)
|
||||
return fKeys.right_command_key;
|
||||
if (modifier == B_LEFT_CONTROL_KEY || modifier == B_CONTROL_KEY)
|
||||
return fKeys.left_control_key;
|
||||
if (modifier == B_RIGHT_CONTROL_KEY)
|
||||
return fKeys.right_control_key;
|
||||
if (modifier == B_LEFT_OPTION_KEY || modifier == B_OPTION_KEY)
|
||||
return fKeys.left_option_key;
|
||||
if (modifier == B_RIGHT_OPTION_KEY)
|
||||
return fKeys.right_option_key;
|
||||
if (modifier == B_MENU_KEY)
|
||||
return fKeys.menu_key;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Keymap::SetModifier(uint32 keyCode, uint32 modifier)
|
||||
{
|
||||
@@ -362,81 +233,13 @@ Keymap::SetModifier(uint32 keyCode, uint32 modifier)
|
||||
}
|
||||
|
||||
|
||||
/*! Checks whether a key is a dead key.
|
||||
If it is, the enabled/disabled state of that dead key will be passed
|
||||
out via isEnabled (isEnabled is not touched for non-dead keys).
|
||||
*/
|
||||
uint8
|
||||
Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers, bool* isEnabled)
|
||||
{
|
||||
uint32 tableMask = 0;
|
||||
int32 offset = _Offset(keyCode, modifiers, &tableMask);
|
||||
uint8 deadKeyIndex = _GetDeadKeyIndex(offset);
|
||||
if (deadKeyIndex > 0 && isEnabled != NULL) {
|
||||
uint32 deadTables[] = {
|
||||
fKeys.acute_tables,
|
||||
fKeys.grave_tables,
|
||||
fKeys.circumflex_tables,
|
||||
fKeys.dieresis_tables,
|
||||
fKeys.tilde_tables
|
||||
};
|
||||
*isEnabled = (deadTables[deadKeyIndex - 1] & tableMask) != 0;
|
||||
}
|
||||
|
||||
return deadKeyIndex;
|
||||
}
|
||||
|
||||
|
||||
//! Tell if a key is a dead second key, needed for draw a dead second key.
|
||||
bool
|
||||
Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey)
|
||||
{
|
||||
if (!activeDeadKey)
|
||||
return false;
|
||||
|
||||
int32 offset = _Offset(keyCode, modifiers);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
uint32 numBytes = fChars[offset];
|
||||
if (!numBytes)
|
||||
return false;
|
||||
|
||||
int32* deadOffsets[] = {
|
||||
fKeys.acute_dead_key,
|
||||
fKeys.grave_dead_key,
|
||||
fKeys.circumflex_dead_key,
|
||||
fKeys.dieresis_dead_key,
|
||||
fKeys.tilde_dead_key
|
||||
};
|
||||
|
||||
int32 *deadOffset = deadOffsets[activeDeadKey - 1];
|
||||
|
||||
for (int32 i=0; i<32; i++) {
|
||||
if (offset == deadOffset[i])
|
||||
return true;
|
||||
|
||||
uint32 deadNumBytes = fChars[deadOffset[i]];
|
||||
|
||||
if (!deadNumBytes)
|
||||
continue;
|
||||
|
||||
if (strncmp(&fChars[offset + 1], &fChars[deadOffset[i] + 1],
|
||||
deadNumBytes) == 0)
|
||||
return true;
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! Enables/disables the "deadness" of the given keycode/modifier combo.
|
||||
void
|
||||
Keymap::SetDeadKeyEnabled(uint32 keyCode, uint32 modifiers, bool enabled)
|
||||
{
|
||||
uint32 tableMask = 0;
|
||||
int32 offset = _Offset(keyCode, modifiers, &tableMask);
|
||||
uint8 deadKeyIndex = _GetDeadKeyIndex(offset);
|
||||
int32 offset = Offset(keyCode, modifiers, &tableMask);
|
||||
uint8 deadKeyIndex = DeadKeyIndex(offset);
|
||||
if (deadKeyIndex > 0) {
|
||||
uint32* deadTables[] = {
|
||||
&fKeys.acute_tables,
|
||||
@@ -529,105 +332,6 @@ Keymap::SetDeadKeyTrigger(dead_key_index deadKeyIndex, const BString& trigger)
|
||||
}
|
||||
|
||||
|
||||
//! Get the char for a key given modifiers and active dead key
|
||||
void
|
||||
Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
|
||||
char** chars, int32* numBytes)
|
||||
{
|
||||
*numBytes = 0;
|
||||
*chars = NULL;
|
||||
|
||||
if (keyCode > 128 || fChars == NULL)
|
||||
return;
|
||||
|
||||
// here we take NUMLOCK into account
|
||||
if ((modifiers & B_NUM_LOCK) != 0) {
|
||||
switch (keyCode) {
|
||||
case 0x37:
|
||||
case 0x38:
|
||||
case 0x39:
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
modifiers ^= B_SHIFT_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
int32 offset = _Offset(keyCode, modifiers);
|
||||
if (offset < 0)
|
||||
return;
|
||||
|
||||
// here we get the char size
|
||||
*numBytes = fChars[offset];
|
||||
if (!*numBytes)
|
||||
return;
|
||||
|
||||
// here we take an potential active dead key
|
||||
int32 *deadKey;
|
||||
switch (activeDeadKey) {
|
||||
case kDeadKeyAcute:
|
||||
deadKey = fKeys.acute_dead_key;
|
||||
break;
|
||||
case kDeadKeyGrave:
|
||||
deadKey = fKeys.grave_dead_key;
|
||||
break;
|
||||
case kDeadKeyCircumflex:
|
||||
deadKey = fKeys.circumflex_dead_key;
|
||||
break;
|
||||
case kDeadKeyDiaeresis:
|
||||
deadKey = fKeys.dieresis_dead_key;
|
||||
break;
|
||||
case kDeadKeyTilde:
|
||||
deadKey = fKeys.tilde_dead_key;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// if not dead, we copy and return the char
|
||||
char *str = *chars = new char[*numBytes + 1];
|
||||
strncpy(str, &fChars[offset + 1], *numBytes);
|
||||
str[*numBytes] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if dead key, we search for our current offset char in the dead key
|
||||
// offset table string comparison is needed
|
||||
for (int32 i = 0; i < 32; i++) {
|
||||
if (strncmp(&fChars[offset + 1], &fChars[deadKey[i] + 1], *numBytes)
|
||||
== 0) {
|
||||
*numBytes = fChars[deadKey[i + 1]];
|
||||
|
||||
switch (*numBytes) {
|
||||
case 0:
|
||||
// Not mapped
|
||||
*chars = NULL;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// 1-, 2-, 3-, or 4-byte UTF-8 character
|
||||
char *str = *chars = new char[*numBytes + 1];
|
||||
strncpy(str, &fChars[deadKey[i + 1] + 1], *numBytes);
|
||||
str[*numBytes] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// if not found we return the current char mapped
|
||||
*chars = new char[*numBytes + 1];
|
||||
strncpy(*chars, &fChars[offset + 1], *numBytes);
|
||||
(*chars)[*numBytes] = 0;
|
||||
}
|
||||
|
||||
|
||||
//! We make our input server use the map in /boot/home/config/settings/Keymap
|
||||
status_t
|
||||
Keymap::Use()
|
||||
@@ -640,7 +344,7 @@ void
|
||||
Keymap::SetKey(uint32 keyCode, uint32 modifiers, int8 deadKey,
|
||||
const char* bytes, int32 numBytes)
|
||||
{
|
||||
int32 offset = _Offset(keyCode, modifiers);
|
||||
int32 offset = Offset(keyCode, modifiers);
|
||||
if (offset < 0)
|
||||
return;
|
||||
|
||||
@@ -684,64 +388,6 @@ Keymap::operator=(const Keymap& other)
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Keymap::_Offset(uint32 keyCode, uint32 modifiers, uint32* _table)
|
||||
{
|
||||
int32 offset;
|
||||
uint32 table;
|
||||
|
||||
if (keyCode >= 128)
|
||||
return -1;
|
||||
|
||||
switch (modifiers & kModifierKeys) {
|
||||
case B_SHIFT_KEY:
|
||||
offset = fKeys.shift_map[keyCode];
|
||||
table = B_SHIFT_TABLE;
|
||||
break;
|
||||
case B_CAPS_LOCK:
|
||||
offset = fKeys.caps_map[keyCode];
|
||||
table = B_CAPS_TABLE;
|
||||
break;
|
||||
case B_CAPS_LOCK | B_SHIFT_KEY:
|
||||
offset = fKeys.caps_shift_map[keyCode];
|
||||
table = B_CAPS_SHIFT_TABLE;
|
||||
break;
|
||||
case B_OPTION_KEY:
|
||||
offset = fKeys.option_map[keyCode];
|
||||
table = B_OPTION_TABLE;
|
||||
break;
|
||||
case B_OPTION_KEY | B_SHIFT_KEY:
|
||||
offset = fKeys.option_shift_map[keyCode];
|
||||
table = B_OPTION_SHIFT_TABLE;
|
||||
break;
|
||||
case B_OPTION_KEY | B_CAPS_LOCK:
|
||||
offset = fKeys.option_caps_map[keyCode];
|
||||
table = B_OPTION_CAPS_TABLE;
|
||||
break;
|
||||
case B_OPTION_KEY | B_SHIFT_KEY | B_CAPS_LOCK:
|
||||
offset = fKeys.option_caps_shift_map[keyCode];
|
||||
table = B_OPTION_CAPS_SHIFT_TABLE;
|
||||
break;
|
||||
case B_CONTROL_KEY:
|
||||
offset = fKeys.control_map[keyCode];
|
||||
table = B_CONTROL_TABLE;
|
||||
break;
|
||||
default:
|
||||
offset = fKeys.normal_map[keyCode];
|
||||
table = B_NORMAL_TABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_table != NULL)
|
||||
*_table = table;
|
||||
|
||||
if (offset >= (int32)fCharsSize)
|
||||
return -1;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Keymap::_SetChars(int32 offset, const char* bytes, int32 numBytes)
|
||||
{
|
||||
@@ -790,46 +436,3 @@ Keymap::_SetChars(int32 offset, const char* bytes, int32 numBytes)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
Keymap::_GetDeadKeyIndex(int32 offset)
|
||||
{
|
||||
if (fChars == NULL || offset <= 0)
|
||||
return 0;
|
||||
|
||||
uint32 numBytes = fChars[offset];
|
||||
if (!numBytes)
|
||||
return 0;
|
||||
|
||||
char chars[4];
|
||||
strncpy(chars, &fChars[offset + 1], numBytes);
|
||||
chars[numBytes] = 0;
|
||||
|
||||
int32 deadOffsets[] = {
|
||||
fKeys.acute_dead_key[1],
|
||||
fKeys.grave_dead_key[1],
|
||||
fKeys.circumflex_dead_key[1],
|
||||
fKeys.dieresis_dead_key[1],
|
||||
fKeys.tilde_dead_key[1]
|
||||
};
|
||||
|
||||
uint8 result = 0;
|
||||
for (int32 i = 0; i < 5; i++) {
|
||||
if (offset == deadOffsets[i]) {
|
||||
result = i + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 deadNumBytes = fChars[deadOffsets[i]];
|
||||
if (!deadNumBytes)
|
||||
continue;
|
||||
|
||||
if (strncmp(chars, &fChars[deadOffsets[i] + 1], deadNumBytes) == 0) {
|
||||
result = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2009 Haiku Inc. All rights reserved.
|
||||
* Copyright 2004-2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -10,7 +10,8 @@
|
||||
#define KEYMAP_H
|
||||
|
||||
|
||||
#include <InterfaceDefs.h>
|
||||
#include <Keymap.h>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Messenger.h>
|
||||
#include <String.h>
|
||||
@@ -25,7 +26,7 @@ enum dead_key_index {
|
||||
};
|
||||
|
||||
|
||||
class Keymap {
|
||||
class Keymap : public BKeymap {
|
||||
public:
|
||||
Keymap();
|
||||
~Keymap();
|
||||
@@ -38,15 +39,8 @@ public:
|
||||
|
||||
void DumpKeymap();
|
||||
|
||||
bool IsModifierKey(uint32 keyCode);
|
||||
uint32 Modifier(uint32 keyCode);
|
||||
uint32 KeyForModifier(uint32 modifier);
|
||||
status_t SetModifier(uint32 keyCode, uint32 modifier);
|
||||
|
||||
uint8 IsDeadKey(uint32 keyCode, uint32 modifiers,
|
||||
bool* isEnabled = NULL);
|
||||
bool IsDeadSecondKey(uint32 keyCode, uint32 modifiers,
|
||||
uint8 activeDeadKey);
|
||||
void SetDeadKeyEnabled(uint32 keyCode, uint32 modifiers,
|
||||
bool enabled);
|
||||
void GetDeadKeyTrigger(dead_key_index deadKeyIndex,
|
||||
@@ -54,11 +48,7 @@ public:
|
||||
void SetDeadKeyTrigger(dead_key_index deadKeyIndex,
|
||||
const BString& trigger);
|
||||
|
||||
void GetChars(uint32 keyCode, uint32 modifiers,
|
||||
uint8 activeDeadKey, char** chars,
|
||||
int32* numBytes);
|
||||
status_t Use();
|
||||
bool Equals(const Keymap& map) const;
|
||||
|
||||
void SetKey(uint32 keyCode, uint32 modifiers,
|
||||
int8 deadKey, const char* bytes,
|
||||
@@ -72,15 +62,10 @@ public:
|
||||
Keymap& operator=(const Keymap& other);
|
||||
|
||||
private:
|
||||
int32 _Offset(uint32 keyCode, uint32 modifiers,
|
||||
uint32* _table = NULL);
|
||||
bool _SetChars(int32 offset, const char* bytes,
|
||||
int32 numBytes);
|
||||
uint8 _GetDeadKeyIndex(int32 offset);
|
||||
|
||||
char* fChars;
|
||||
key_map fKeys;
|
||||
uint32 fCharsSize;
|
||||
private:
|
||||
char fName[B_FILE_NAME_LENGTH];
|
||||
|
||||
BMessenger fTarget;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2009 Haiku Inc. All rights reserved.
|
||||
* Copyright 2004-2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -647,12 +647,12 @@ KeymapWindow::_UpdateDeadKeyMenu()
|
||||
void
|
||||
KeymapWindow::_UpdateButtons()
|
||||
{
|
||||
if (!fCurrentMap.Equals(fAppliedMap)) {
|
||||
if (fCurrentMap != fAppliedMap) {
|
||||
fCurrentMap.SetName(kCurrentKeymapName);
|
||||
_UseKeymap();
|
||||
}
|
||||
|
||||
fRevertButton->SetEnabled(!fCurrentMap.Equals(fPreviousMap));
|
||||
fRevertButton->SetEnabled(fCurrentMap != fPreviousMap);
|
||||
|
||||
_UpdateDeadKeyMenu();
|
||||
_UpdateSwitchShortcutButton();
|
||||
|
||||
Reference in New Issue
Block a user