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