]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - pjrc/host.c
8da88517b5cffb8c59a61a8d62a6f59860e6cda9
[max/tmk_keyboard.git] / pjrc / host.c
1 #include <stdint.h>
2 #include "usb_keycodes.h"
3 #include "usb_keyboard.h"
4 #include "usb_mouse.h"
5 #include "debug.h"
6 #include "host.h"
7 #include "util.h"
8
9
10 #ifdef USB_NKRO_ENABLE
11 bool keyboard_nkro = false;
12 #endif
13
14 static report_keyboard_t report0;
15 static report_keyboard_t report1;
16 report_keyboard_t *keyboard_report = &report0;
17 report_keyboard_t *keyboard_report_prev = &report1;
18
19 static inline void add_key_byte(uint8_t code);
20 static inline void add_key_bit(uint8_t code);
21
22
23 uint8_t host_keyboard_leds(void)
24 {
25     return usb_keyboard_leds;
26 }
27
28 /* keyboard report operations */
29 void host_add_key(uint8_t key)
30 {
31 #ifdef USB_NKRO_ENABLE
32     if (keyboard_nkro) {
33         add_key_bit(key);
34         return;
35     }
36 #endif
37     add_key_byte(key);
38 }
39
40 void host_add_mod_bit(uint8_t mod)
41 {
42     keyboard_report->mods |= mod;
43 }
44
45 void host_set_mods(uint8_t mods)
46 {
47     keyboard_report->mods = mods;
48 }
49
50 void host_add_code(uint8_t code)
51 {
52     if (IS_MOD(code)) {
53         host_add_mod_bit(MOD_BIT(code));
54     } else {
55         host_add_key(code);
56     }
57 }
58
59 void host_swap_keyboard_report(void)
60 {
61     report_keyboard_t *tmp = keyboard_report_prev;
62     keyboard_report_prev = keyboard_report;
63     keyboard_report = tmp;
64 }
65
66 void host_clear_keyboard_report(void)
67 {
68     keyboard_report->mods = 0;
69     for (int8_t i = 0; i < REPORT_KEYS; i++) {
70         keyboard_report->keys[i] = 0;
71     }
72 }
73
74 uint8_t host_has_anykey(void)
75 {
76     uint8_t cnt = 0;
77     for (int i = 0; i < REPORT_KEYS; i++) {
78         if (keyboard_report->keys[i])
79             cnt++;
80     }
81     return cnt;
82 }
83
84 uint8_t host_get_first_key(void)
85 {
86 #ifdef USB_NKRO_ENABLE
87     if (keyboard_nkro) {
88         uint8_t i = 0;
89         for (; i < REPORT_KEYS && !keyboard_report->keys[i]; i++)
90             ;
91         return i<<3 | biton(keyboard_report->keys[i]);
92     }
93 #endif
94     return keyboard_report->keys[0];
95 }
96
97
98 void host_send_keyboard_report(void)
99 {
100     usb_keyboard_send_report(keyboard_report);
101 }
102
103 void host_mouse_send(report_mouse_t *report)
104 {
105     usb_mouse_send(report->x, report->y, report->v, report->h, report->buttons);
106 }
107
108
109 static inline void add_key_byte(uint8_t code)
110 {
111     // TODO: fix ugly code
112     int8_t i = 0;
113     int8_t empty = -1;
114     for (; i < REPORT_KEYS; i++) {
115         if (keyboard_report_prev->keys[i] == code) {
116             keyboard_report->keys[i] = code;
117             break;
118         }
119         if (empty == -1 &&
120                 keyboard_report_prev->keys[i] == 0 &&
121                 keyboard_report->keys[i] == 0) {
122             empty = i;
123         }
124     }
125     if (i == REPORT_KEYS) {
126         if (empty != -1) {
127             keyboard_report->keys[empty] = code;
128         }
129     }
130 }
131
132 static inline void add_key_bit(uint8_t code)
133 {
134     if ((code>>3) < REPORT_KEYS) {
135         keyboard_report->keys[code>>3] |= 1<<(code&7);
136     } else {
137         debug("add_key_bit: can't add: "); phex(code); debug("\n");
138     }
139 }