2011-09-17 13:39:50 +00:00
/*
2012-10-09 07:50:14 +00:00
Copyright 2011 , 2012 Jun Wako < wakojun @ gmail . com >
2011-09-17 13:39:50 +00:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <stdint.h>
# include <avr/interrupt.h>
2012-10-09 05:36:13 +00:00
# include "keycode.h"
2011-09-17 13:39:50 +00:00
# include "host.h"
# include "util.h"
# include "debug.h"
# ifdef NKRO_ENABLE
bool keyboard_nkro = false ;
# endif
2012-10-09 07:50:14 +00:00
report_keyboard_t * keyboard_report = & ( report_keyboard_t ) { } ;
2012-10-11 19:46:37 +00:00
report_mouse_t mouse_report = { } ;
2011-09-17 13:39:50 +00:00
2012-10-11 19:46:37 +00:00
static host_driver_t * driver ;
static uint16_t last_system_report = 0 ;
static uint16_t last_consumer_report = 0 ;
2011-09-17 13:39:50 +00:00
static inline void add_key_byte ( uint8_t code ) ;
2012-05-27 05:04:28 +00:00
static inline void del_key_byte ( uint8_t code ) ;
2011-09-17 13:39:50 +00:00
static inline void add_key_bit ( uint8_t code ) ;
2012-05-27 05:04:28 +00:00
static inline void del_key_bit ( uint8_t code ) ;
2011-09-17 13:39:50 +00:00
void host_set_driver ( host_driver_t * d )
{
driver = d ;
}
host_driver_t * host_get_driver ( void )
{
return driver ;
}
uint8_t host_keyboard_leds ( void )
{
if ( ! driver ) return 0 ;
return ( * driver - > keyboard_leds ) ( ) ;
}
2012-10-11 19:46:37 +00:00
/* send report */
void host_keyboard_send ( report_keyboard_t * report )
{
if ( ! driver ) return ;
( * driver - > send_keyboard ) ( report ) ;
if ( debug_keyboard ) {
2013-05-14 07:18:22 +00:00
dprint ( " keys: " ) ;
2012-10-11 19:46:37 +00:00
for ( int i = 0 ; i < REPORT_KEYS ; i + + ) {
2013-05-14 07:18:22 +00:00
dprintf ( " %02X " , keyboard_report - > keys [ i ] ) ;
2012-10-11 19:46:37 +00:00
}
2013-05-14 07:18:22 +00:00
dprintf ( " mods: %02X \n " , keyboard_report - > mods ) ;
2012-10-11 19:46:37 +00:00
}
}
void host_mouse_send ( report_mouse_t * report )
{
if ( ! driver ) return ;
( * driver - > send_mouse ) ( report ) ;
}
void host_system_send ( uint16_t report )
{
if ( report = = last_system_report ) return ;
last_system_report = report ;
if ( ! driver ) return ;
( * driver - > send_system ) ( report ) ;
}
void host_consumer_send ( uint16_t report )
{
if ( report = = last_consumer_report ) return ;
last_consumer_report = report ;
if ( ! driver ) return ;
( * driver - > send_consumer ) ( report ) ;
}
2011-09-17 13:39:50 +00:00
2012-10-11 19:46:37 +00:00
/* keyboard report utils */
2011-09-17 13:39:50 +00:00
void host_add_key ( uint8_t key )
{
# ifdef NKRO_ENABLE
if ( keyboard_nkro ) {
add_key_bit ( key ) ;
return ;
}
# endif
add_key_byte ( key ) ;
}
2012-05-27 05:04:28 +00:00
void host_del_key ( uint8_t key )
{
# ifdef NKRO_ENABLE
if ( keyboard_nkro ) {
del_key_bit ( key ) ;
return ;
}
# endif
del_key_byte ( key ) ;
}
2012-10-09 07:50:14 +00:00
void host_clear_keys ( void )
{
for ( int8_t i = 0 ; i < REPORT_KEYS ; i + + ) {
keyboard_report - > keys [ i ] = 0 ;
}
}
2013-01-13 01:24:20 +00:00
uint8_t host_get_mods ( void )
{
return keyboard_report - > mods ;
}
2012-12-15 17:32:07 +00:00
void host_add_mods ( uint8_t mods )
2011-09-17 13:39:50 +00:00
{
2012-12-15 17:32:07 +00:00
keyboard_report - > mods | = mods ;
2011-09-17 13:39:50 +00:00
}
2012-12-15 17:32:07 +00:00
void host_del_mods ( uint8_t mods )
2012-05-27 05:04:28 +00:00
{
2012-12-15 17:32:07 +00:00
keyboard_report - > mods & = ~ mods ;
2012-05-27 05:04:28 +00:00
}
2011-09-17 13:39:50 +00:00
void host_set_mods ( uint8_t mods )
{
keyboard_report - > mods = mods ;
}
2012-10-09 07:50:14 +00:00
void host_clear_mods ( void )
2011-09-17 13:39:50 +00:00
{
keyboard_report - > mods = 0 ;
}
uint8_t host_has_anykey ( void )
{
uint8_t cnt = 0 ;
for ( int i = 0 ; i < REPORT_KEYS ; i + + ) {
if ( keyboard_report - > keys [ i ] )
cnt + + ;
}
return cnt ;
}
2012-10-11 19:46:37 +00:00
uint8_t host_has_anymod ( void )
{
return bitpop ( keyboard_report - > mods ) ;
}
2011-09-17 13:39:50 +00:00
uint8_t host_get_first_key ( void )
{
# ifdef NKRO_ENABLE
if ( keyboard_nkro ) {
uint8_t i = 0 ;
for ( ; i < REPORT_KEYS & & ! keyboard_report - > keys [ i ] ; i + + )
;
return i < < 3 | biton ( keyboard_report - > keys [ i ] ) ;
}
# endif
return keyboard_report - > keys [ 0 ] ;
}
void host_send_keyboard_report ( void )
{
if ( ! driver ) return ;
2012-10-11 19:46:37 +00:00
host_keyboard_send ( keyboard_report ) ;
2011-09-17 13:39:50 +00:00
}
2012-10-11 19:46:37 +00:00
uint8_t host_mouse_in_use ( void )
2012-10-09 07:50:14 +00:00
{
2012-10-11 19:46:37 +00:00
return ( mouse_report . buttons | mouse_report . x | mouse_report . y | mouse_report . v | mouse_report . h ) ;
2012-10-09 07:50:14 +00:00
}
2012-10-11 19:46:37 +00:00
uint16_t host_last_sysytem_report ( void )
2011-09-17 13:39:50 +00:00
{
2012-10-11 19:46:37 +00:00
return last_system_report ;
2011-09-17 13:39:50 +00:00
}
2012-10-11 19:46:37 +00:00
uint16_t host_last_consumer_report ( void )
2011-09-17 13:39:50 +00:00
{
2012-10-11 19:46:37 +00:00
return last_consumer_report ;
2011-09-17 13:39:50 +00:00
}
static inline void add_key_byte ( uint8_t code )
{
int8_t i = 0 ;
int8_t empty = - 1 ;
for ( ; i < REPORT_KEYS ; i + + ) {
2012-10-09 07:50:14 +00:00
if ( keyboard_report - > keys [ i ] = = code ) {
2011-09-17 13:39:50 +00:00
break ;
}
2012-10-09 07:50:14 +00:00
if ( empty = = - 1 & & keyboard_report - > keys [ i ] = = 0 ) {
2011-09-17 13:39:50 +00:00
empty = i ;
}
}
if ( i = = REPORT_KEYS ) {
if ( empty ! = - 1 ) {
keyboard_report - > keys [ empty ] = code ;
}
}
}
2012-05-27 05:04:28 +00:00
static inline void del_key_byte ( uint8_t code )
{
int i = 0 ;
for ( ; i < REPORT_KEYS ; i + + ) {
if ( keyboard_report - > keys [ i ] = = code ) {
keyboard_report - > keys [ i ] = 0 ;
}
}
}
2011-09-17 13:39:50 +00:00
static inline void add_key_bit ( uint8_t code )
{
if ( ( code > > 3 ) < REPORT_KEYS ) {
keyboard_report - > keys [ code > > 3 ] | = 1 < < ( code & 7 ) ;
} else {
2013-05-14 07:18:22 +00:00
dprintf ( " add_key_bit: can't add: %02X \n " , code ) ;
2011-09-17 13:39:50 +00:00
}
}
2012-05-27 05:04:28 +00:00
static inline void del_key_bit ( uint8_t code )
{
if ( ( code > > 3 ) < REPORT_KEYS ) {
keyboard_report - > keys [ code > > 3 ] & = ~ ( 1 < < ( code & 7 ) ) ;
} else {
2013-05-14 07:18:22 +00:00
dprintf ( " del_key_bit: can't del: %02X \n " , code ) ;
2012-05-27 05:04:28 +00:00
}
}