-
Notifications
You must be signed in to change notification settings - Fork 12
/
usb_keyboard_event.h
111 lines (92 loc) · 2.05 KB
/
usb_keyboard_event.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Converts USB key events into modifier bitfield and key list of report structure
#include <stdint.h>
#include <stdbool.h>
// Calls usb_keyboard_send() if report is dirty
void usb_keyboard_update( void );
// Marks report as dirty
void usb_keyboard_touch( void );
// Adjusts report structure to reflect pressed/released key
void report_usb_event( uint8_t code, bool pressed );
//// Code
#include "usb_keyboard.h"
#include "keycode.h"
#include "config.h"
#include <stdbool.h>
#ifndef DEBUG
#define DEBUG( e )
#endif
static bool usb_report_dirty;
enum { max_keys = 6 };
// Marks report as dirty so it'll be sent on the next update
void usb_keyboard_touch( void )
{
usb_report_dirty = true;
}
// Calls usb_keyboard_send() only if changes have been made to report via report_usb_event()
void usb_keyboard_update( void )
{
if ( usb_report_dirty )
{
usb_report_dirty = false;
usb_keyboard_send();
}
}
// Adds key press/release to current report
void usb_keyboard_event( uint8_t code, bool pressed )
{
if ( !code )
return;
usb_report_dirty = true;
if ( KC_LCTRL <= code && code <= KC_RGUI )
{
// Modifier; route to mask rather than keys list
uint8_t mask = 1 << (code - KC_LCTRL);
keyboard_modifier_keys |= mask;
if ( !pressed )
keyboard_modifier_keys ^= mask;
}
else
{
// Find key
uint8_t* p = keyboard_keys + max_keys;
do
{
if ( *--p == code )
break;
}
while ( p != keyboard_keys );
if ( !pressed )
{
// Remove key
if ( *p == code )
{
*p = 0;
return;
}
DEBUG(debug_byte( code ));
DEBUG(debug_str( "released key not in list\n" ));
}
else
{
// Don't add if already there (sometimes keyboard gives multiple
// key down events when pressing lots of keys)
if ( *p == code )
{
DEBUG(debug_str( "pressed key already in list\n" ));
return;
}
// Add to first empty entry
p = keyboard_keys + max_keys;
do
{
if ( *--p == 0 )
{
*p = code;
return;
}
}
while ( p != keyboard_keys );
DEBUG(debug_str( "too many keys pressed\n" ));
}
}
}