auto import from //depot/cupcake/@135843
This commit is contained in:
@@ -1,263 +0,0 @@
|
||||
#define LOG_TAG "KeyCharacterMap"
|
||||
|
||||
#include <ui/KeyCharacterMap.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
struct Header
|
||||
{
|
||||
char magic[8];
|
||||
unsigned int endian;
|
||||
unsigned int version;
|
||||
unsigned int keycount;
|
||||
unsigned char kbdtype;
|
||||
char padding[11];
|
||||
};
|
||||
|
||||
KeyCharacterMap::KeyCharacterMap()
|
||||
{
|
||||
}
|
||||
|
||||
KeyCharacterMap::~KeyCharacterMap()
|
||||
{
|
||||
free(m_keys);
|
||||
}
|
||||
|
||||
unsigned short
|
||||
KeyCharacterMap::get(int keycode, int meta)
|
||||
{
|
||||
Key* k = find_key(keycode);
|
||||
if (k != NULL) {
|
||||
return k->data[meta & META_MASK];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short
|
||||
KeyCharacterMap::getNumber(int keycode)
|
||||
{
|
||||
Key* k = find_key(keycode);
|
||||
if (k != NULL) {
|
||||
return k->number;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short
|
||||
KeyCharacterMap::getMatch(int keycode, const unsigned short* chars,
|
||||
int charsize, uint32_t modifiers)
|
||||
{
|
||||
Key* k = find_key(keycode);
|
||||
modifiers &= 3; // ignore the SYM key because we don't have keymap entries for it
|
||||
if (k != NULL) {
|
||||
const uint16_t* data = k->data;
|
||||
for (int j=0; j<charsize; j++) {
|
||||
uint16_t c = chars[j];
|
||||
for (int i=0; i<(META_MASK + 1); i++) {
|
||||
if ((modifiers == 0) || ((modifiers & i) != 0)) {
|
||||
if (c == data[i]) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short
|
||||
KeyCharacterMap::getDisplayLabel(int keycode)
|
||||
{
|
||||
Key* k = find_key(keycode);
|
||||
if (k != NULL) {
|
||||
return k->display_label;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
KeyCharacterMap::getKeyData(int keycode, unsigned short *displayLabel,
|
||||
unsigned short *number, unsigned short* results)
|
||||
{
|
||||
Key* k = find_key(keycode);
|
||||
if (k != NULL) {
|
||||
memcpy(results, k->data, sizeof(short)*(META_MASK + 1));
|
||||
*number = k->number;
|
||||
*displayLabel = k->display_label;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
KeyCharacterMap::find_char(uint16_t c, uint32_t* key, uint32_t* mods)
|
||||
{
|
||||
uint32_t N = m_keyCount;
|
||||
for (int j=0; j<(META_MASK + 1); j++) {
|
||||
Key const* keys = m_keys;
|
||||
for (uint32_t i=0; i<N; i++) {
|
||||
if (keys->data[j] == c) {
|
||||
*key = keys->keycode;
|
||||
*mods = j;
|
||||
return true;
|
||||
}
|
||||
keys++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
KeyCharacterMap::getEvents(uint16_t* chars, size_t len,
|
||||
Vector<int32_t>* keys, Vector<uint32_t>* modifiers)
|
||||
{
|
||||
for (size_t i=0; i<len; i++) {
|
||||
uint32_t k, mods;
|
||||
if (find_char(chars[i], &k, &mods)) {
|
||||
keys->add(k);
|
||||
modifiers->add(mods);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
KeyCharacterMap::Key*
|
||||
KeyCharacterMap::find_key(int keycode)
|
||||
{
|
||||
Key* keys = m_keys;
|
||||
int low = 0;
|
||||
int high = m_keyCount - 1;
|
||||
int mid;
|
||||
int n;
|
||||
while (low <= high) {
|
||||
mid = (low + high) / 2;
|
||||
n = keys[mid].keycode;
|
||||
if (keycode < n) {
|
||||
high = mid - 1;
|
||||
} else if (keycode > n) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
return keys + mid;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KeyCharacterMap*
|
||||
KeyCharacterMap::load(int id)
|
||||
{
|
||||
KeyCharacterMap* rv = NULL;
|
||||
char path[PATH_MAX];
|
||||
char propName[100];
|
||||
char dev[PROPERTY_VALUE_MAX];
|
||||
char tmpfn[PROPERTY_VALUE_MAX];
|
||||
int err;
|
||||
const char* root = getenv("ANDROID_ROOT");
|
||||
|
||||
sprintf(propName, "hw.keyboards.%u.devname", id);
|
||||
err = property_get(propName, dev, "");
|
||||
if (err > 0) {
|
||||
// replace all the spaces with underscores
|
||||
strcpy(tmpfn, dev);
|
||||
for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
|
||||
*p = '_';
|
||||
snprintf(path, sizeof(path), "%s/usr/keychars/%s.kcm.bin", root, tmpfn);
|
||||
//LOGD("load: dev='%s' path='%s'\n", dev, path);
|
||||
rv = try_file(path);
|
||||
if (rv != NULL) {
|
||||
return rv;
|
||||
}
|
||||
LOGW("Error loading keycharmap file '%s'. %s='%s'", path, propName, dev);
|
||||
} else {
|
||||
LOGW("No keyboard for id %d", id);
|
||||
}
|
||||
|
||||
snprintf(path, sizeof(path), "%s/usr/keychars/qwerty.kcm.bin", root);
|
||||
rv = try_file(path);
|
||||
if (rv == NULL) {
|
||||
LOGE("Can't find any keycharmaps (also tried %s)", path);
|
||||
return NULL;
|
||||
}
|
||||
LOGW("Using default keymap: %s", path);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
KeyCharacterMap*
|
||||
KeyCharacterMap::try_file(const char* filename)
|
||||
{
|
||||
KeyCharacterMap* rv = NULL;
|
||||
Key* keys;
|
||||
int fd;
|
||||
off_t filesize;
|
||||
Header header;
|
||||
int err;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
LOGW("Can't open keycharmap file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
filesize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
// validate the header
|
||||
if (filesize <= (off_t)sizeof(header)) {
|
||||
LOGW("Bad keycharmap - filesize=%d\n", (int)filesize);
|
||||
goto cleanup1;
|
||||
}
|
||||
|
||||
err = read(fd, &header, sizeof(header));
|
||||
if (err == -1) {
|
||||
LOGW("Error reading keycharmap file");
|
||||
goto cleanup1;
|
||||
}
|
||||
|
||||
if (0 != memcmp(header.magic, "keychar", 8)) {
|
||||
LOGW("Bad keycharmap magic token");
|
||||
goto cleanup1;
|
||||
}
|
||||
if (header.endian != 0x12345678) {
|
||||
LOGW("Bad keycharmap endians");
|
||||
goto cleanup1;
|
||||
}
|
||||
if ((header.version & 0xff) != 2) {
|
||||
LOGW("Only support keycharmap version 2 (got 0x%08x)", header.version);
|
||||
goto cleanup1;
|
||||
}
|
||||
if (filesize < (off_t)(sizeof(Header)+(sizeof(Key)*header.keycount))) {
|
||||
LOGW("Bad keycharmap file size\n");
|
||||
goto cleanup1;
|
||||
}
|
||||
|
||||
// read the key data
|
||||
keys = (Key*)malloc(sizeof(Key)*header.keycount);
|
||||
err = read(fd, keys, sizeof(Key)*header.keycount);
|
||||
if (err == -1) {
|
||||
LOGW("Error reading keycharmap file");
|
||||
free(keys);
|
||||
goto cleanup1;
|
||||
}
|
||||
|
||||
// return the object
|
||||
rv = new KeyCharacterMap;
|
||||
rv->m_keyCount = header.keycount;
|
||||
rv->m_keys = keys;
|
||||
rv->m_type = header.kbdtype;
|
||||
|
||||
cleanup1:
|
||||
close(fd);
|
||||
|
||||
return rv;
|
||||
}
|
||||
Reference in New Issue
Block a user