blob: 8618803671e83c013f9de133738829732cefac25 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <hid/hid.h>
#include <hid/usages.h>
#include <string.h>
#include <strings.h>
#define KEYSET(bitmap, n) (bitmap[(n) >> 5] |= (1 << ((n)&31)))
#define KEYCLR(bitmap, n) (bitmap[(n) >> 5] &= ~(1 << ((n)&31)))
void hid_kbd_parse_report(uint8_t buf[8], hid_keys_t* keys) {
memset(keys, 0, sizeof(hid_keys_t));
// modifiers start at bit 224
keys->keymask[7] = buf[0];
for (int i = 2; i < 8; i++) {
if (buf[i] == 0) {
continue;
}
KEYSET(keys->keymask, buf[i]);
}
}
void hid_kbd_pressed_keys(const hid_keys_t* prev, const hid_keys_t* cur, hid_keys_t* pressed) {
memset(pressed, 0, sizeof(hid_keys_t));
for (int i = 0; i < 8; i++) {
pressed->keymask[i] = (prev->keymask[i] ^ cur->keymask[i]) & cur->keymask[i];
}
}
void hid_kbd_released_keys(const hid_keys_t* prev, const hid_keys_t* cur, hid_keys_t* released) {
memset(released, 0, sizeof(hid_keys_t));
for (int i = 0; i < 8; i++) {
released->keymask[i] = (prev->keymask[i] ^ cur->keymask[i]) & prev->keymask[i];
}
}
uint8_t hid_kbd_next_key(hid_keys_t* keys) {
for (int i = 0; i < 8; i++) {
int key = ffs(keys->keymask[i]);
if (key) {
key += i * 32 - 1;
KEYCLR(keys->keymask, key);
return key;
}
}
return 0;
}
uint8_t hid_map_key(uint32_t usage, bool shift, const keychar_t* keymap) {
if (usage > KEYMAP_SIZE) {
return 0;
} else if (shift) {
return keymap[usage].shift_c;
} else {
return keymap[usage].c;
}
}