1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <hid/hid.h>
6 #include <hid/usages.h>
7 
8 #include <string.h>
9 #include <strings.h>
10 
11 #define KEYSET(bitmap, n) (bitmap[(n) >> 5] |= (1 << ((n)&31)))
12 #define KEYCLR(bitmap, n) (bitmap[(n) >> 5] &= ~(1 << ((n)&31)))
13 
hid_kbd_parse_report(uint8_t buf[8],hid_keys_t * keys)14 void hid_kbd_parse_report(uint8_t buf[8], hid_keys_t* keys) {
15     memset(keys, 0, sizeof(hid_keys_t));
16     // modifiers start at bit 224
17     keys->keymask[7] = buf[0];
18     for (int i = 2; i < 8; i++) {
19         if (buf[i] == 0) {
20             break;
21         }
22         KEYSET(keys->keymask, buf[i]);
23     }
24 }
25 
hid_kbd_pressed_keys(const hid_keys_t * prev,const hid_keys_t * cur,hid_keys_t * pressed)26 void hid_kbd_pressed_keys(const hid_keys_t* prev, const hid_keys_t* cur, hid_keys_t* pressed) {
27     memset(pressed, 0, sizeof(hid_keys_t));
28     for (int i = 0; i < 8; i++) {
29         pressed->keymask[i] = (prev->keymask[i] ^ cur->keymask[i]) & cur->keymask[i];
30     }
31 }
32 
hid_kbd_released_keys(const hid_keys_t * prev,const hid_keys_t * cur,hid_keys_t * released)33 void hid_kbd_released_keys(const hid_keys_t* prev, const hid_keys_t* cur, hid_keys_t* released) {
34     memset(released, 0, sizeof(hid_keys_t));
35     for (int i = 0; i < 8; i++) {
36         released->keymask[i] = (prev->keymask[i] ^ cur->keymask[i]) & prev->keymask[i];
37     }
38 }
39 
hid_kbd_next_key(hid_keys_t * keys)40 uint8_t hid_kbd_next_key(hid_keys_t* keys) {
41     for (int i = 0; i < 8; i++) {
42         int key = ffs(keys->keymask[i]);
43         if (key) {
44             key += i * 32 - 1;
45             KEYCLR(keys->keymask, key);
46             return key;
47         }
48     }
49     return 0;
50 }
51 
hid_map_key(uint32_t usage,bool shift,const keychar_t * keymap)52 uint8_t hid_map_key(uint32_t usage, bool shift, const keychar_t* keymap) {
53     if (usage > KEYMAP_SIZE) {
54         return 0;
55     } else if (shift) {
56         return keymap[usage].shift_c;
57     } else {
58         return keymap[usage].c;
59     }
60 }
61