2011-07-20 15:32:52 +00:00
/*
Copyright 2011 Jun Wako < wakojun @ gmail . com >
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/>.
*/
2011-01-02 14:52:13 +00:00
# include <stdint.h>
# include <util/delay.h>
# include "usb_keycodes.h"
2011-02-10 06:51:30 +00:00
# include "host.h"
# include "timer.h"
# include "print.h"
# include "debug.h"
2011-01-02 14:52:13 +00:00
# include "mousekey.h"
2011-02-10 06:51:30 +00:00
static report_mouse_t report ;
static report_mouse_t report_prev ;
2011-01-02 14:52:13 +00:00
static uint8_t mousekey_repeat = 0 ;
2011-02-10 06:51:30 +00:00
static void mousekey_debug ( void ) ;
2011-01-02 14:52:13 +00:00
/*
* TODO : fix acceleration algorithm
* see wikipedia http : //en.wikipedia.org/wiki/Mouse_keys
*/
# ifndef MOUSEKEY_DELAY_TIME
# define MOUSEKEY_DELAY_TIME 255
# endif
2011-02-12 15:15:51 +00:00
// acceleration parameters
uint8_t mousekey_move_unit = 2 ;
uint8_t mousekey_resolution = 5 ;
2011-01-02 14:52:13 +00:00
static inline uint8_t move_unit ( void )
{
2011-02-12 15:15:51 +00:00
uint16_t unit = 5 + mousekey_repeat * 2 ;
return ( unit > 63 ? 63 : unit ) ;
2011-01-02 14:52:13 +00:00
}
void mousekey_decode ( uint8_t code )
{
2011-02-10 06:51:30 +00:00
if ( code = = KB_MS_UP ) report . y = - move_unit ( ) ;
else if ( code = = KB_MS_DOWN ) report . y = move_unit ( ) ;
else if ( code = = KB_MS_LEFT ) report . x = - move_unit ( ) ;
else if ( code = = KB_MS_RIGHT ) report . x = move_unit ( ) ;
else if ( code = = KB_MS_BTN1 ) report . buttons | = MOUSE_BTN1 ;
else if ( code = = KB_MS_BTN2 ) report . buttons | = MOUSE_BTN2 ;
else if ( code = = KB_MS_BTN3 ) report . buttons | = MOUSE_BTN3 ;
else if ( code = = KB_MS_BTN4 ) report . buttons | = MOUSE_BTN4 ;
else if ( code = = KB_MS_BTN5 ) report . buttons | = MOUSE_BTN5 ;
2011-09-17 13:39:50 +00:00
else if ( code = = KB_MS_WH_UP ) report . v + = move_unit ( ) / 4 ;
else if ( code = = KB_MS_WH_DOWN ) report . v - = move_unit ( ) / 4 ;
else if ( code = = KB_MS_WH_LEFT ) report . h - = move_unit ( ) / 4 ;
else if ( code = = KB_MS_WH_RIGHT ) report . h + = move_unit ( ) / 4 ;
2011-01-02 14:52:13 +00:00
}
bool mousekey_changed ( void )
{
2011-02-10 06:51:30 +00:00
return ( report . buttons ! = report_prev . buttons | |
2011-02-12 15:15:51 +00:00
report . x | | report . y | | report . v | | report . h ) ;
2011-01-02 14:52:13 +00:00
}
2011-02-10 06:51:30 +00:00
void mousekey_send ( void )
2011-01-02 14:52:13 +00:00
{
2011-02-10 06:51:30 +00:00
static uint16_t last_timer = 0 ;
if ( ! mousekey_changed ( ) ) {
2011-01-02 14:52:13 +00:00
mousekey_repeat = 0 ;
2011-02-12 15:15:51 +00:00
mousekey_clear_report ( ) ;
2011-02-10 06:51:30 +00:00
return ;
2011-01-02 14:52:13 +00:00
}
2011-02-10 06:51:30 +00:00
// send immediately when buttun state is changed
if ( report . buttons = = report_prev . buttons ) {
2011-09-17 13:39:50 +00:00
if ( timer_elapsed ( last_timer ) < 100 ) {
2011-02-12 15:15:51 +00:00
mousekey_clear_report ( ) ;
2011-02-10 06:51:30 +00:00
return ;
}
}
2011-02-12 15:15:51 +00:00
if ( mousekey_repeat ! = 0xFF ) {
mousekey_repeat + + ;
}
2011-02-10 06:51:30 +00:00
if ( report . x & & report . y ) {
report . x * = 0.7 ;
report . y * = 0.7 ;
}
mousekey_debug ( ) ;
host_mouse_send ( & report ) ;
2011-02-12 15:15:51 +00:00
report_prev = report ;
2011-02-10 06:51:30 +00:00
last_timer = timer_read ( ) ;
mousekey_clear_report ( ) ;
}
void mousekey_clear_report ( void )
{
report . buttons = 0 ;
report . x = 0 ;
report . y = 0 ;
2011-02-12 15:15:51 +00:00
report . v = 0 ;
report . h = 0 ;
2011-02-10 06:51:30 +00:00
}
static void mousekey_debug ( void )
{
if ( ! debug_mouse ) return ;
print ( " mousekey[btn|x y v h]: " ) ;
phex ( report . buttons ) ; print ( " | " ) ;
phex ( report . x ) ; print ( " " ) ;
phex ( report . y ) ; print ( " " ) ;
phex ( report . v ) ; print ( " " ) ;
phex ( report . h ) ;
2011-02-12 15:15:51 +00:00
phex ( mousekey_repeat ) ;
2011-02-10 06:51:30 +00:00
print ( " \n " ) ;
2011-01-02 14:52:13 +00:00
}