* Made GetChars() save against uninitialized keymaps (it will no longer crash).

* Added Map() function.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29667 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-03-23 14:15:44 +00:00
parent 42176b84a4
commit 94a62911e6
2 changed files with 56 additions and 47 deletions
+33 -29
View File
@@ -307,17 +307,21 @@ Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey)
} }
// get the char for a key given modifiers and active dead key //! Get the char for a key given modifiers and active dead key
void void
Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** chars, int32* numBytes) Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
char** chars, int32* numBytes)
{ {
int32 offset; int32 offset;
*numBytes = 0; *numBytes = 0;
*chars = NULL; *chars = NULL;
if (keyCode > 128 || fChars == NULL)
return;
// here we take NUMLOCK into account // here we take NUMLOCK into account
if (modifiers & B_NUM_LOCK) if ((modifiers & B_NUM_LOCK) != 0) {
switch (keyCode) { switch (keyCode) {
case 0x37: case 0x37:
case 0x38: case 0x38:
@@ -331,7 +335,8 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** c
case 0x64: case 0x64:
case 0x65: case 0x65:
modifiers ^= B_SHIFT_KEY; modifiers ^= B_SHIFT_KEY;
} }
}
// here we choose the right map given the modifiers // here we choose the right map given the modifiers
switch (modifiers & 0xcf) { switch (modifiers & 0xcf) {
@@ -345,50 +350,50 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** c
case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; break; case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; break;
default: offset = fKeys.normal_map[keyCode]; break; default: offset = fKeys.normal_map[keyCode]; break;
} }
// here we get the char size // here we get the char size
*numBytes = fChars[offset]; *numBytes = fChars[offset];
if (!*numBytes) if (!*numBytes)
return; return;
// here we take an potential active dead key // here we take an potential active dead key
int32 *dead_key; int32 *deadKey;
switch(activeDeadKey) { switch (activeDeadKey) {
case 1: dead_key = fKeys.acute_dead_key; break; case 1: deadKey = fKeys.acute_dead_key; break;
case 2: dead_key = fKeys.grave_dead_key; break; case 2: deadKey = fKeys.grave_dead_key; break;
case 3: dead_key = fKeys.circumflex_dead_key; break; case 3: deadKey = fKeys.circumflex_dead_key; break;
case 4: dead_key = fKeys.dieresis_dead_key; break; case 4: deadKey = fKeys.dieresis_dead_key; break;
case 5: dead_key = fKeys.tilde_dead_key; break; case 5: deadKey = fKeys.tilde_dead_key; break;
default: default:
{ {
// if not dead, we copy and return the char // if not dead, we copy and return the char
char *str = *chars = new char[*numBytes + 1]; char *str = *chars = new char[*numBytes + 1];
strncpy(str, &(fChars[offset+1]), *numBytes ); strncpy(str, &fChars[offset + 1], *numBytes);
str[*numBytes] = 0; str[*numBytes] = 0;
return; return;
} }
} }
// if dead key, we search for our current offset char in the dead key offset table // if dead key, we search for our current offset char in the dead key
// string comparison is needed // offset table string comparison is needed
for (int32 i=0; i<32; i++) { for (int32 i = 0; i < 32; i++) {
if (strncmp(&(fChars[offset+1]), &(fChars[dead_key[i]+1]), *numBytes ) == 0) { if (strncmp(&fChars[offset + 1], &fChars[deadKey[i] + 1], *numBytes)
*numBytes = fChars[dead_key[i+1]]; == 0) {
*numBytes = fChars[deadKey[i + 1]];
switch(*numBytes) {
switch (*numBytes) {
case 0: case 0:
// Not mapped // Not mapped
*chars = NULL; *chars = NULL;
break; break;
default: default:
{
// 1-, 2-, 3-, or 4-byte UTF-8 character // 1-, 2-, 3-, or 4-byte UTF-8 character
{
char *str = *chars = new char[*numBytes + 1]; char *str = *chars = new char[*numBytes + 1];
strncpy(str, &fChars[dead_key[i+1]+1], *numBytes ); strncpy(str, &fChars[deadKey[i + 1] + 1], *numBytes );
str[*numBytes] = 0; str[*numBytes] = 0;
}
break; break;
}
} }
return; return;
} }
@@ -397,9 +402,8 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** c
// if not found we return the current char mapped // if not found we return the current char mapped
*chars = new char[*numBytes + 1]; *chars = new char[*numBytes + 1];
strncpy(*chars, &(fChars[offset+1]), *numBytes ); strncpy(*chars, &fChars[offset + 1], *numBytes);
(*chars)[*numBytes] = 0; (*chars)[*numBytes] = 0;
} }
+23 -18
View File
@@ -1,35 +1,40 @@
/* /*
* Copyright 2004-2008 Haiku Inc. All rights reserved. * Copyright 2004-2009 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Jérôme Duval * Jérôme Duval
*/ */
#ifndef KEYMAP_H #ifndef KEYMAP_H
#define KEYMAP_H #define KEYMAP_H
#include <InterfaceDefs.h> #include <InterfaceDefs.h>
#include <Entry.h> #include <Entry.h>
class Keymap
{ class Keymap {
public: public:
status_t Load(entry_ref &ref); status_t Load(entry_ref& ref);
status_t Save(entry_ref &ref); status_t Save(entry_ref& ref);
void DumpKeymap(); void DumpKeymap();
bool IsModifierKey(uint32 keyCode); bool IsModifierKey(uint32 keyCode);
uint8 IsDeadKey(uint32 keyCode, uint32 modifiers); uint8 IsDeadKey(uint32 keyCode, uint32 modifiers);
bool IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey); bool IsDeadSecondKey(uint32 keyCode, uint32 modifiers,
void GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** chars, int32* numBytes); uint8 activeDeadKey);
status_t Use(); void GetChars(uint32 keyCode, uint32 modifiers,
bool Equals(const Keymap& map) const; uint8 activeDeadKey, char** chars,
int32* numBytes);
status_t Use();
bool Equals(const Keymap& map) const;
const key_map& Map() const { return fKeys; }
private: private:
char *fChars; char* fChars;
key_map fKeys; key_map fKeys;
uint32 fCharsSize; uint32 fCharsSize;
char fName[B_FILE_NAME_LENGTH]; char fName[B_FILE_NAME_LENGTH];
}; };