* More cleanup, no functional change.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29671 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+202
-158
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 Haiku Inc. All rights reserved.
|
||||
* Copyright 2004-2009 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -8,75 +8,78 @@
|
||||
*/
|
||||
|
||||
#include "Keymap.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <File.h>
|
||||
|
||||
#include <input_globals.h>
|
||||
|
||||
static void
|
||||
print_key(char *chars, int32 offset)
|
||||
|
||||
static void
|
||||
print_key(char *chars, int32 offset)
|
||||
{
|
||||
int size = chars[offset++];
|
||||
|
||||
|
||||
switch (size) {
|
||||
case 0:
|
||||
// Not mapped
|
||||
printf("N/A");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// 1-byte UTF-8/ASCII character
|
||||
printf("%c", chars[offset]);
|
||||
break;
|
||||
|
||||
default:
|
||||
// 2-, 3-, or 4-byte UTF-8 character
|
||||
{
|
||||
char *str = new char[size + 1];
|
||||
strncpy(str, &(chars[offset]), size);
|
||||
str[size] = 0;
|
||||
printf("%s", str);
|
||||
delete [] str;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\t");
|
||||
case 0:
|
||||
// Not mapped
|
||||
printf("N/A");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// 1-byte UTF-8/ASCII character
|
||||
printf("%c", chars[offset]);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// 2-, 3-, or 4-byte UTF-8 character
|
||||
char *str = new char[size + 1];
|
||||
strncpy(str, &chars[offset], size);
|
||||
str[size] = 0;
|
||||
printf("%s", str);
|
||||
delete[] str;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\t");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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");
|
||||
for (int i = 0; i < 128; i++) {
|
||||
printf(" 0x%x\t", i);
|
||||
print_key(fChars, fKeys.normal_map[i]);
|
||||
print_key(fChars, fKeys.shift_map[i]);
|
||||
print_key(fChars, fKeys.caps_map[i]);
|
||||
print_key(fChars, fKeys.caps_shift_map[i]);
|
||||
print_key(fChars, fKeys.option_map[i]);
|
||||
print_key(fChars, fKeys.option_shift_map[i]);
|
||||
print_key(fChars, fKeys.option_caps_map[i]);
|
||||
print_key(fChars, fKeys.option_caps_shift_map[i]);
|
||||
print_key(fChars, fKeys.control_map[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// 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");
|
||||
for (int i = 0; i < 128; i++) {
|
||||
printf(" 0x%x\t", i);
|
||||
print_key(fChars, fKeys.normal_map[i]);
|
||||
print_key(fChars, fKeys.shift_map[i]);
|
||||
print_key(fChars, fKeys.caps_map[i]);
|
||||
print_key(fChars, fKeys.caps_shift_map[i]);
|
||||
print_key(fChars, fKeys.option_map[i]);
|
||||
print_key(fChars, fKeys.option_shift_map[i]);
|
||||
print_key(fChars, fKeys.option_caps_map[i]);
|
||||
print_key(fChars, fKeys.option_caps_shift_map[i]);
|
||||
print_key(fChars, fKeys.control_map[i]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
file format in big endian :
|
||||
struct key_map
|
||||
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
|
||||
status_t
|
||||
status_t
|
||||
Keymap::Load(entry_ref &ref)
|
||||
{
|
||||
status_t err;
|
||||
@@ -85,26 +88,26 @@ Keymap::Load(entry_ref &ref)
|
||||
fprintf(stderr, "error loading keymap: %s\n", strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
if (!fChars)
|
||||
delete[] fChars;
|
||||
@@ -118,46 +121,60 @@ Keymap::Load(entry_ref &ref)
|
||||
}
|
||||
|
||||
|
||||
// we save a map from a file
|
||||
status_t
|
||||
Keymap::Save(entry_ref &ref)
|
||||
//! We save a map from a file
|
||||
status_t
|
||||
Keymap::Save(entry_ref& ref)
|
||||
{
|
||||
status_t err;
|
||||
|
||||
BFile file(&ref, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE );
|
||||
if ((err = file.InitCheck()) != B_OK) {
|
||||
printf("error %s\n", strerror(err));
|
||||
return err;
|
||||
BFile file;
|
||||
status_t status = file.SetTo(&ref,
|
||||
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
|
||||
if (status != B_OK) {
|
||||
printf("error %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
for (uint32 i=0; i<sizeof(fKeys)/4; i++)
|
||||
((uint32*)&fKeys)[i] = B_HOST_TO_BENDIAN_INT32(((uint32*)&fKeys)[i]);
|
||||
|
||||
if ((err = file.Write(&fKeys, sizeof(fKeys))) < (ssize_t)sizeof(fKeys)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
for (uint32 i=0; i<sizeof(fKeys)/4; i++)
|
||||
((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);
|
||||
|
||||
fCharsSize = B_HOST_TO_BENDIAN_INT32(fCharsSize);
|
||||
|
||||
if ((err = file.Write(&fCharsSize, sizeof(uint32))) < (ssize_t)sizeof(uint32)) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize);
|
||||
|
||||
if ((err = file.Write(fChars, fCharsSize)) < (ssize_t)fCharsSize)
|
||||
return err;
|
||||
|
||||
err = file.WriteAttr("keymap:name", B_STRING_TYPE, 0, fName, strlen(fName));
|
||||
|
||||
for (uint32 i = 0; i < sizeof(fKeys) / 4; i++) {
|
||||
((uint32*)&fKeys)[i] = B_HOST_TO_BENDIAN_INT32(((uint32*)&fKeys)[i]);
|
||||
}
|
||||
|
||||
ssize_t bytesWritten = file.Write(&fKeys, sizeof(fKeys));
|
||||
if (bytesWritten < (ssize_t)sizeof(fKeys)) {
|
||||
if (bytesWritten < 0)
|
||||
return bytesWritten;
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < sizeof(fKeys) / 4; i++) {
|
||||
((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);
|
||||
}
|
||||
|
||||
fCharsSize = B_HOST_TO_BENDIAN_INT32(fCharsSize);
|
||||
|
||||
bytesWritten = file.Write(&fCharsSize, sizeof(uint32));
|
||||
if (bytesWritten < (ssize_t)sizeof(uint32)) {
|
||||
if (bytesWritten < 0)
|
||||
return bytesWritten;
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
|
||||
fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize);
|
||||
|
||||
bytesWritten = file.Write(fChars, fCharsSize);
|
||||
if (bytesWritten < (ssize_t)fCharsSize) {
|
||||
if (bytesWritten < 0)
|
||||
return bytesWritten;
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
|
||||
file.WriteAttr("keymap:name", B_STRING_TYPE, 0, fName, strlen(fName));
|
||||
// Failing would be non-fatal
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool Keymap::Equals(const Keymap& map) const
|
||||
bool
|
||||
Keymap::Equals(const Keymap& map) const
|
||||
{
|
||||
// not really efficient but this is the only way i found
|
||||
// to reliably compare keymaps (used only for apply and revert)
|
||||
@@ -165,67 +182,95 @@ bool Keymap::Equals(const Keymap& map) const
|
||||
}
|
||||
|
||||
|
||||
/* we need to know if a key is a modifier key to choose
|
||||
a valid key when several are pressed together
|
||||
/*! We need to know if a key is a modifier key to choose
|
||||
a valid key when several are pressed together.
|
||||
*/
|
||||
bool
|
||||
bool
|
||||
Keymap::IsModifierKey(uint32 keyCode)
|
||||
{
|
||||
if ((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))
|
||||
return true;
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// tell if a key is a dead key, needed for draw a dead key
|
||||
//! Tell if a key is a dead key, needed for draw a dead key.
|
||||
uint8
|
||||
Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers)
|
||||
{
|
||||
if (fChars == NULL)
|
||||
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;
|
||||
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)
|
||||
return 0;
|
||||
|
||||
if (offset <= 0)
|
||||
return 0;
|
||||
|
||||
uint32 numBytes = fChars[offset];
|
||||
|
||||
if (!numBytes)
|
||||
return 0;
|
||||
|
||||
char chars[4];
|
||||
strncpy(chars, &(fChars[offset+1]), numBytes );
|
||||
chars[numBytes] = 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,
|
||||
@@ -233,36 +278,34 @@ Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers)
|
||||
fKeys.dieresis_tables,
|
||||
fKeys.tilde_tables
|
||||
};
|
||||
|
||||
for (int32 i=0; i<5; i++) {
|
||||
|
||||
for (int32 i = 0; i < 5; i++) {
|
||||
if ((deadTables[i] & tableMask) == 0)
|
||||
continue;
|
||||
|
||||
|
||||
if (offset == deadOffsets[i])
|
||||
return i+1;
|
||||
|
||||
return i + 1;
|
||||
|
||||
uint32 deadNumBytes = fChars[deadOffsets[i]];
|
||||
|
||||
if (!deadNumBytes)
|
||||
continue;
|
||||
|
||||
if (strncmp(chars, &(fChars[deadOffsets[i]+1]), deadNumBytes ) == 0) {
|
||||
return i+1;
|
||||
}
|
||||
|
||||
if (strncmp(chars, &fChars[deadOffsets[i] + 1], deadNumBytes) == 0)
|
||||
return i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// tell if a key is a dead second key, needed for draw a dead second key
|
||||
//! 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;
|
||||
|
||||
|
||||
switch (modifiers & 0xcf) {
|
||||
case B_SHIFT_KEY: offset = fKeys.shift_map[keyCode]; break;
|
||||
case B_CAPS_LOCK: offset = fKeys.caps_map[keyCode]; break;
|
||||
@@ -274,12 +317,12 @@ Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey)
|
||||
case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; break;
|
||||
default: offset = fKeys.normal_map[keyCode]; break;
|
||||
}
|
||||
|
||||
|
||||
uint32 numBytes = fChars[offset];
|
||||
|
||||
|
||||
if (!numBytes)
|
||||
return false;
|
||||
|
||||
|
||||
int32* deadOffsets[] = {
|
||||
fKeys.acute_dead_key,
|
||||
fKeys.grave_dead_key,
|
||||
@@ -287,19 +330,20 @@ Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey)
|
||||
fKeys.dieresis_dead_key,
|
||||
fKeys.tilde_dead_key
|
||||
};
|
||||
|
||||
int32 *deadOffset = deadOffsets[activeDeadKey-1];
|
||||
|
||||
|
||||
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)
|
||||
|
||||
if (strncmp(&fChars[offset + 1], &fChars[deadOffset[i] + 1],
|
||||
deadNumBytes) == 0)
|
||||
return true;
|
||||
i++;
|
||||
}
|
||||
@@ -364,10 +408,10 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
|
||||
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:
|
||||
default:
|
||||
{
|
||||
// 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);
|
||||
str[*numBytes] = 0;
|
||||
return;
|
||||
@@ -384,26 +428,26 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
|
||||
switch (*numBytes) {
|
||||
case 0:
|
||||
// Not mapped
|
||||
*chars = NULL;
|
||||
break;
|
||||
*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;
|
||||
// 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
|
||||
// if not found we return the current char mapped
|
||||
*chars = new char[*numBytes + 1];
|
||||
strncpy(*chars, &fChars[offset + 1], *numBytes);
|
||||
(*chars)[*numBytes] = 0;
|
||||
(*chars)[*numBytes] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user