* 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:
Axel Dörfler
2009-03-24 09:43:39 +00:00
parent 0b5931e024
commit 193882e035
+202 -158
View File
@@ -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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -8,75 +8,78 @@
*/ */
#include "Keymap.h" #include "Keymap.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ByteOrder.h> #include <ByteOrder.h>
#include <File.h> #include <File.h>
#include <input_globals.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++]; int size = chars[offset++];
switch (size) { switch (size) {
case 0: case 0:
// Not mapped // Not mapped
printf("N/A"); printf("N/A");
break; break;
case 1: case 1:
// 1-byte UTF-8/ASCII character // 1-byte UTF-8/ASCII character
printf("%c", chars[offset]); printf("%c", chars[offset]);
break; break;
default: default:
// 2-, 3-, or 4-byte UTF-8 character {
{ // 2-, 3-, or 4-byte UTF-8 character
char *str = new char[size + 1]; char *str = new char[size + 1];
strncpy(str, &(chars[offset]), size); strncpy(str, &chars[offset], size);
str[size] = 0; str[size] = 0;
printf("%s", str); printf("%s", str);
delete [] str; delete[] str;
} break;
break; }
} }
printf("\t"); printf("\t");
} }
void void
Keymap::DumpKeymap() Keymap::DumpKeymap()
{ {
// Print a chart of the normal, shift, option, and option+shift // Print a chart of the normal, shift, option, and option+shift
// keys. // 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\tControl\n");
for (int i = 0; i < 128; i++) { for (int i = 0; i < 128; i++) {
printf(" 0x%x\t", i); printf(" 0x%x\t", i);
print_key(fChars, fKeys.normal_map[i]); print_key(fChars, fKeys.normal_map[i]);
print_key(fChars, fKeys.shift_map[i]); print_key(fChars, fKeys.shift_map[i]);
print_key(fChars, fKeys.caps_map[i]); print_key(fChars, fKeys.caps_map[i]);
print_key(fChars, fKeys.caps_shift_map[i]); print_key(fChars, fKeys.caps_shift_map[i]);
print_key(fChars, fKeys.option_map[i]); print_key(fChars, fKeys.option_map[i]);
print_key(fChars, fKeys.option_shift_map[i]); print_key(fChars, fKeys.option_shift_map[i]);
print_key(fChars, fKeys.option_caps_map[i]); print_key(fChars, fKeys.option_caps_map[i]);
print_key(fChars, fKeys.option_caps_shift_map[i]); print_key(fChars, fKeys.option_caps_shift_map[i]);
print_key(fChars, fKeys.control_map[i]); print_key(fChars, fKeys.control_map[i]);
printf("\n"); printf("\n");
} }
} }
/* /*
file format in big endian : file format in big endian :
struct key_map struct key_map
uint32 size of following charset uint32 size of following charset
charset (offsets go into this with size of character followed by character) charset (offsets go into this with size of character followed by character)
*/ */
// we load a map from a file // we load a map from a file
status_t status_t
Keymap::Load(entry_ref &ref) Keymap::Load(entry_ref &ref)
{ {
status_t err; status_t err;
@@ -85,26 +88,26 @@ Keymap::Load(entry_ref &ref)
fprintf(stderr, "error loading keymap: %s\n", strerror(err)); fprintf(stderr, "error loading keymap: %s\n", strerror(err));
return err; return err;
} }
BFile file(&entry, B_READ_ONLY); BFile file(&entry, B_READ_ONLY);
if ((err = file.InitCheck()) != B_OK) { if ((err = file.InitCheck()) != B_OK) {
fprintf(stderr, "error loading keymap: %s\n", strerror(err)); fprintf(stderr, "error loading keymap: %s\n", strerror(err));
return err; return err;
} }
if ((err = file.Read(&fKeys, sizeof(fKeys))) < (ssize_t)sizeof(fKeys)) { if ((err = file.Read(&fKeys, sizeof(fKeys))) < (ssize_t)sizeof(fKeys)) {
fprintf(stderr, "error reading keymap keys: %s\n", strerror(err)); fprintf(stderr, "error reading keymap keys: %s\n", strerror(err));
return B_BAD_VALUE; return B_BAD_VALUE;
} }
for (uint32 i=0; i<sizeof(fKeys)/4; i++) for (uint32 i=0; i<sizeof(fKeys)/4; i++)
((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]); ((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);
if ((err = file.Read(&fCharsSize, sizeof(uint32))) < (ssize_t)sizeof(uint32)) { if ((err = file.Read(&fCharsSize, sizeof(uint32))) < (ssize_t)sizeof(uint32)) {
fprintf(stderr, "error reading keymap size: %s\n", strerror(err)); fprintf(stderr, "error reading keymap size: %s\n", strerror(err));
return B_BAD_VALUE; return B_BAD_VALUE;
} }
fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize); fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize);
if (!fChars) if (!fChars)
delete[] fChars; delete[] fChars;
@@ -118,46 +121,60 @@ Keymap::Load(entry_ref &ref)
} }
// we save a map from a file //! We save a map from a file
status_t status_t
Keymap::Save(entry_ref &ref) Keymap::Save(entry_ref& ref)
{ {
status_t err; BFile file;
status_t status = file.SetTo(&ref,
BFile file(&ref, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE ); B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if ((err = file.InitCheck()) != B_OK) { if (status != B_OK) {
printf("error %s\n", strerror(err)); printf("error %s\n", strerror(status));
return err; 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; 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 // not really efficient but this is the only way i found
// to reliably compare keymaps (used only for apply and revert) // 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 /*! We need to know if a key is a modifier key to choose
a valid key when several are pressed together a valid key when several are pressed together.
*/ */
bool bool
Keymap::IsModifierKey(uint32 keyCode) Keymap::IsModifierKey(uint32 keyCode)
{ {
if ((keyCode == fKeys.caps_key) return keyCode == fKeys.caps_key
|| (keyCode == fKeys.num_key) || keyCode == fKeys.num_key
|| (keyCode == fKeys.scroll_key) || keyCode == fKeys.scroll_key
|| (keyCode == fKeys.left_shift_key) || keyCode == fKeys.left_shift_key
|| (keyCode == fKeys.right_shift_key) || keyCode == fKeys.right_shift_key
|| (keyCode == fKeys.left_command_key) || keyCode == fKeys.left_command_key
|| (keyCode == fKeys.right_command_key) || keyCode == fKeys.right_command_key
|| (keyCode == fKeys.left_control_key) || keyCode == fKeys.left_control_key
|| (keyCode == fKeys.right_control_key) || keyCode == fKeys.right_control_key
|| (keyCode == fKeys.left_option_key) || keyCode == fKeys.left_option_key
|| (keyCode == fKeys.right_option_key) || keyCode == fKeys.right_option_key
|| (keyCode == fKeys.menu_key)) || keyCode == fKeys.menu_key;
return true;
return false;
} }
// 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 uint8
Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers) Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers)
{ {
if (fChars == NULL)
return 0;
int32 offset; int32 offset;
uint32 tableMask = 0; uint32 tableMask = 0;
switch (modifiers & 0xcf) { switch (modifiers & 0xcf) {
case B_SHIFT_KEY: offset = fKeys.shift_map[keyCode]; tableMask = B_SHIFT_TABLE; break; case B_SHIFT_KEY:
case B_CAPS_LOCK: offset = fKeys.caps_map[keyCode]; tableMask = B_CAPS_TABLE; break; offset = fKeys.shift_map[keyCode];
case B_CAPS_LOCK|B_SHIFT_KEY: offset = fKeys.caps_shift_map[keyCode]; tableMask = B_CAPS_SHIFT_TABLE; break; tableMask = B_SHIFT_TABLE;
case B_OPTION_KEY: offset = fKeys.option_map[keyCode]; tableMask = B_OPTION_TABLE; break; break;
case B_OPTION_KEY|B_SHIFT_KEY: offset = fKeys.option_shift_map[keyCode]; tableMask = B_OPTION_SHIFT_TABLE; break; case B_CAPS_LOCK:
case B_OPTION_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_map[keyCode]; tableMask = B_OPTION_CAPS_TABLE; break; offset = fKeys.caps_map[keyCode];
case B_OPTION_KEY|B_SHIFT_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_shift_map[keyCode]; tableMask = B_OPTION_CAPS_SHIFT_TABLE; break; tableMask = B_CAPS_TABLE;
case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; tableMask = B_CONTROL_TABLE; break; break;
default: offset = fKeys.normal_map[keyCode]; tableMask = B_NORMAL_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) if (offset <= 0)
return 0; return 0;
uint32 numBytes = fChars[offset]; uint32 numBytes = fChars[offset];
if (!numBytes) if (!numBytes)
return 0; return 0;
char chars[4]; char chars[4];
strncpy(chars, &(fChars[offset+1]), numBytes ); strncpy(chars, &fChars[offset + 1], numBytes);
chars[numBytes] = 0; chars[numBytes] = 0;
int32 deadOffsets[] = { int32 deadOffsets[] = {
fKeys.acute_dead_key[1], fKeys.acute_dead_key[1],
fKeys.grave_dead_key[1], fKeys.grave_dead_key[1],
fKeys.circumflex_dead_key[1], fKeys.circumflex_dead_key[1],
fKeys.dieresis_dead_key[1], fKeys.dieresis_dead_key[1],
fKeys.tilde_dead_key[1] fKeys.tilde_dead_key[1]
}; };
uint32 deadTables[] = { uint32 deadTables[] = {
fKeys.acute_tables, fKeys.acute_tables,
fKeys.grave_tables, fKeys.grave_tables,
@@ -233,36 +278,34 @@ Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers)
fKeys.dieresis_tables, fKeys.dieresis_tables,
fKeys.tilde_tables fKeys.tilde_tables
}; };
for (int32 i=0; i<5; i++) { for (int32 i = 0; i < 5; i++) {
if ((deadTables[i] & tableMask) == 0) if ((deadTables[i] & tableMask) == 0)
continue; continue;
if (offset == deadOffsets[i]) if (offset == deadOffsets[i])
return i+1; return i + 1;
uint32 deadNumBytes = fChars[deadOffsets[i]]; uint32 deadNumBytes = fChars[deadOffsets[i]];
if (!deadNumBytes) if (!deadNumBytes)
continue; continue;
if (strncmp(chars, &(fChars[deadOffsets[i]+1]), deadNumBytes ) == 0) { if (strncmp(chars, &fChars[deadOffsets[i] + 1], deadNumBytes) == 0)
return i+1; return i + 1;
}
} }
return 0; 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 bool
Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey) Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey)
{ {
if (!activeDeadKey) if (!activeDeadKey)
return false; return false;
int32 offset; int32 offset;
switch (modifiers & 0xcf) { switch (modifiers & 0xcf) {
case B_SHIFT_KEY: offset = fKeys.shift_map[keyCode]; break; case B_SHIFT_KEY: offset = fKeys.shift_map[keyCode]; break;
case B_CAPS_LOCK: offset = fKeys.caps_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; case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; break;
default: offset = fKeys.normal_map[keyCode]; break; default: offset = fKeys.normal_map[keyCode]; break;
} }
uint32 numBytes = fChars[offset]; uint32 numBytes = fChars[offset];
if (!numBytes) if (!numBytes)
return false; return false;
int32* deadOffsets[] = { int32* deadOffsets[] = {
fKeys.acute_dead_key, fKeys.acute_dead_key,
fKeys.grave_dead_key, fKeys.grave_dead_key,
@@ -287,19 +330,20 @@ Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey)
fKeys.dieresis_dead_key, fKeys.dieresis_dead_key,
fKeys.tilde_dead_key fKeys.tilde_dead_key
}; };
int32 *deadOffset = deadOffsets[activeDeadKey-1]; int32 *deadOffset = deadOffsets[activeDeadKey-1];
for (int32 i=0; i<32; i++) { for (int32 i=0; i<32; i++) {
if (offset == deadOffset[i]) if (offset == deadOffset[i])
return true; return true;
uint32 deadNumBytes = fChars[deadOffset[i]]; uint32 deadNumBytes = fChars[deadOffset[i]];
if (!deadNumBytes) if (!deadNumBytes)
continue; 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; return true;
i++; i++;
} }
@@ -364,10 +408,10 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
case 3: deadKey = fKeys.circumflex_dead_key; break; case 3: deadKey = fKeys.circumflex_dead_key; break;
case 4: deadKey = fKeys.dieresis_dead_key; break; case 4: deadKey = fKeys.dieresis_dead_key; break;
case 5: deadKey = 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;
@@ -384,26 +428,26 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey,
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[deadKey[i + 1] + 1], *numBytes ); strncpy(str, &fChars[deadKey[i + 1] + 1], *numBytes);
str[*numBytes] = 0; str[*numBytes] = 0;
break; break;
} }
} }
return; return;
} }
i++; i++;
} }
// 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;
} }