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-02-21 06:43:17 +00:00
# include "keymap.h"
2011-02-10 06:51:30 +00:00
# include "host.h"
2010-10-29 06:17:18 +00:00
# include "debug.h"
# include "timer.h"
2012-01-15 15:41:06 +00:00
# include "usb_keycodes.h"
2010-10-29 06:17:18 +00:00
# include "layer.h"
2011-02-12 15:15:51 +00:00
2010-10-29 06:17:18 +00:00
/*
2010-11-03 08:33:20 +00:00
* Parameters :
2012-05-27 05:04:28 +00:00
* SWITCH_DELAY | = = = = = = = |
2011-01-22 19:19:17 +00:00
* SEND_FN_TERM | = = = = = = = = = = = = = = = = |
2010-11-03 08:33:20 +00:00
*
* Fn key processing cases :
2011-01-22 19:19:17 +00:00
* 1. release Fn after SEND_FN_TERM .
2010-11-03 08:33:20 +00:00
* Layer sw ___________ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ | ___
* Fn press ___ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ | ___
* Fn send ___________________________
*
2011-01-22 19:19:17 +00:00
* 2. release Fn during SEND_FN_TERM . ( not layer used )
2010-11-03 08:33:20 +00:00
* Layer sw ___________ | ~ ~ ~ ~ ~ ~ | ________
* Fn press ___ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ | ________
* Fn key send __________________ | ~ | ______
* other key press ___________________________
* other key send ___________________________
*
2011-01-22 19:19:17 +00:00
* 3. release Fn during SEND_FN_TERM . ( layer used )
2010-11-03 08:33:20 +00:00
* Layer sw ___________ | ~ ~ ~ ~ ~ ~ | ________
* Fn press ___ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ | ________
* Fn key send ___________________________
* Fn send ___________________________
* other key press _____________ | ~ ~ | __________
* other key send _____________ | ~ ~ | __________
*
2012-05-27 05:04:28 +00:00
* 4. press other key during SWITCH_DELAY .
2010-11-03 08:33:20 +00:00
* Layer sw ___________________________
* Fn key press ___ | ~ ~ ~ ~ ~ ~ ~ ~ ~ | _____________
* Fn key send ______ | ~ ~ ~ ~ ~ ~ | _____________
* other key press ______ | ~ ~ ~ | ________________
* other key send _______ | ~ ~ | ________________
*
* 5. press Fn while press other key .
* Layer sw ___________________________
* Fn key press ___ | ~ ~ ~ ~ ~ ~ ~ ~ ~ | _____________
* Fn key send ___ | ~ ~ ~ ~ ~ ~ ~ ~ ~ | _____________
* other key press ~ ~ ~ ~ ~ ~ ~ | ___________________
* other key send ~ ~ ~ ~ ~ ~ ~ | ___________________
2010-11-03 16:08:24 +00:00
*
* 6. press Fn twice quickly and keep holding down . ( repeat )
* Layer sw ___________________________
* Fn key press ___ | ~ | ____ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
* Fn key send _____ | ~ | __ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2010-11-03 08:33:20 +00:00
*/
2012-05-27 05:04:28 +00:00
// LAYER_SWITCH_DELAY: prevent from moving to new layer
# ifndef LAYER_SWITCH_DELAY
# define LAYER_SWITCH_DELAY 150
# endif
2010-10-29 06:17:18 +00:00
2010-11-03 08:33:20 +00:00
// LAYER_SEND_FN_TERM: send keycode if release key in this term
2012-05-27 05:04:28 +00:00
# ifndef LAYER_SEND_FN_TERM
# define LAYER_SEND_FN_TERM 500
# endif
2010-10-29 06:17:18 +00:00
2011-01-22 19:19:17 +00:00
uint8_t default_layer = 0 ;
uint8_t current_layer = 0 ;
2010-10-29 06:17:18 +00:00
static bool layer_used = false ;
2011-01-22 19:19:17 +00:00
static uint8_t new_layer ( uint8_t fn_bits ) ;
2010-10-29 06:17:18 +00:00
uint8_t layer_get_keycode ( uint8_t row , uint8_t col )
{
uint8_t code = keymap_get_keycode ( current_layer , row , col ) ;
// normal key or mouse key
2011-01-06 06:37:14 +00:00
if ( ( IS_KEY ( code ) | | IS_MOUSEKEY ( code ) ) ) {
2010-10-29 06:17:18 +00:00
layer_used = true ;
2010-11-03 08:33:20 +00:00
}
2010-10-29 06:17:18 +00:00
return code ;
}
2011-01-22 19:19:17 +00:00
// bit substract b from a
2011-05-04 12:19:34 +00:00
# define BIT_SUBST(a, b) (a&(a^b))
2010-10-29 06:17:18 +00:00
void layer_switching ( uint8_t fn_bits )
{
// layer switching
2010-11-03 16:08:24 +00:00
static uint8_t last_fn = 0 ;
2010-11-03 08:33:20 +00:00
static uint8_t last_mods = 0 ;
2010-10-29 06:17:18 +00:00
static uint16_t last_timer = 0 ;
2010-11-03 16:08:24 +00:00
static uint8_t sent_fn = 0 ;
2010-10-29 06:17:18 +00:00
2011-01-22 19:19:17 +00:00
if ( fn_bits = = last_fn ) { // Fn state is not changed
if ( fn_bits = = 0 ) {
// do nothing
2010-11-03 08:33:20 +00:00
} else {
2012-05-27 05:04:28 +00:00
if ( ! keymap_fn_keycode ( BIT_SUBST ( fn_bits , sent_fn ) ) | |
timer_elapsed ( last_timer ) > LAYER_SWITCH_DELAY ) {
2011-05-04 12:19:34 +00:00
uint8_t _layer_to_switch = new_layer ( BIT_SUBST ( fn_bits , sent_fn ) ) ;
2011-01-22 19:19:17 +00:00
if ( current_layer ! = _layer_to_switch ) { // not switch layer yet
2012-05-27 05:04:28 +00:00
debug ( " Fn case: 1,2,3(LAYER_SWITCH_DELAY passed) \n " ) ;
2011-01-22 19:19:17 +00:00
debug ( " Switch Layer: " ) ; debug_hex ( current_layer ) ;
current_layer = _layer_to_switch ;
layer_used = false ;
debug ( " -> " ) ; debug_hex ( current_layer ) ; debug ( " \n " ) ;
}
} else {
2011-02-10 06:51:30 +00:00
if ( host_has_anykey ( ) ) { // other keys is pressed
2011-05-04 12:19:34 +00:00
uint8_t _fn_to_send = BIT_SUBST ( fn_bits , sent_fn ) ;
2011-01-22 19:19:17 +00:00
if ( _fn_to_send ) {
2012-05-27 05:04:28 +00:00
debug ( " Fn case: 4(press other key during SWITCH_DELAY.) \n " ) ;
2011-01-22 19:19:17 +00:00
// send only Fn key first
2012-05-27 05:04:28 +00:00
uint8_t tmp_mods = keyboard_report - > mods ;
host_add_code ( keymap_fn_keycode ( _fn_to_send ) ) ;
2011-02-10 06:51:30 +00:00
host_set_mods ( last_mods ) ;
host_send_keyboard_report ( ) ;
2012-05-27 05:04:28 +00:00
host_set_mods ( tmp_mods ) ;
host_del_code ( keymap_fn_keycode ( _fn_to_send ) ) ;
2011-01-22 19:19:17 +00:00
sent_fn | = _fn_to_send ;
}
}
2010-11-03 08:33:20 +00:00
}
2011-01-22 19:19:17 +00:00
// add Fn keys to send
2011-02-10 06:51:30 +00:00
//host_add_code(keymap_fn_keycode(fn_bits&sent_fn)); // TODO: do all Fn keys
2010-10-29 06:17:18 +00:00
}
2011-01-22 19:19:17 +00:00
} else { // Fn state is changed(edge)
uint8_t fn_changed = 0 ;
debug ( " fn_bits: " ) ; debug_bin ( fn_bits ) ; debug ( " \n " ) ;
debug ( " sent_fn: " ) ; debug_bin ( sent_fn ) ; debug ( " \n " ) ;
debug ( " last_fn: " ) ; debug_bin ( last_fn ) ; debug ( " \n " ) ;
debug ( " last_mods: " ) ; debug_hex ( last_mods ) ; debug ( " \n " ) ;
debug ( " last_timer: " ) ; debug_hex16 ( last_timer ) ; debug ( " \n " ) ;
2012-05-27 05:04:28 +00:00
debug ( " timer_count: " ) ; debug_hex16 ( timer_count ) ; debug ( " \n " ) ;
2011-01-22 19:19:17 +00:00
// pressed Fn
2011-05-04 12:19:34 +00:00
if ( ( fn_changed = BIT_SUBST ( fn_bits , last_fn ) ) ) {
2012-05-27 05:04:28 +00:00
debug ( " fn_changed: " ) ; debug_bin ( fn_changed ) ; debug ( " \n " ) ;
2011-02-10 06:51:30 +00:00
if ( host_has_anykey ( ) ) {
2011-01-22 19:19:17 +00:00
debug ( " Fn case: 5(pressed Fn with other key) \n " ) ;
sent_fn | = fn_changed ;
} else if ( fn_changed & sent_fn ) { // pressed same Fn in a row
2012-05-27 05:04:28 +00:00
if ( timer_elapsed ( last_timer ) > LAYER_SEND_FN_TERM ) {
2011-05-04 12:19:34 +00:00
debug ( " Fn case: 6(not repeat) \n " ) ;
2011-01-22 19:19:17 +00:00
// time passed: not repeate
sent_fn & = ~ fn_changed ;
} else {
2011-05-04 12:19:34 +00:00
debug ( " Fn case: 6(repeat) \n " ) ;
2011-01-22 19:19:17 +00:00
}
2010-11-03 08:33:20 +00:00
}
2011-01-22 19:19:17 +00:00
}
// released Fn
2011-05-04 12:19:34 +00:00
if ( ( fn_changed = BIT_SUBST ( last_fn , fn_bits ) ) ) {
2012-05-27 05:04:28 +00:00
debug ( " fn_changed: " ) ; debug_bin ( fn_changed ) ; debug ( " \n " ) ;
2011-01-22 19:19:17 +00:00
if ( timer_elapsed ( last_timer ) < LAYER_SEND_FN_TERM ) {
2011-05-04 12:19:34 +00:00
if ( ! layer_used & & BIT_SUBST ( fn_changed , sent_fn ) ) {
2011-01-22 19:19:17 +00:00
debug ( " Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM) \n " ) ;
// send only Fn key first
2012-05-27 05:04:28 +00:00
uint8_t tmp_mods = keyboard_report - > mods ;
host_add_code ( keymap_fn_keycode ( fn_changed ) ) ;
2011-02-10 06:51:30 +00:00
host_set_mods ( last_mods ) ;
host_send_keyboard_report ( ) ;
2012-05-27 05:04:28 +00:00
host_set_mods ( tmp_mods ) ;
host_del_code ( keymap_fn_keycode ( fn_changed ) ) ;
2011-01-22 19:19:17 +00:00
sent_fn | = fn_changed ;
}
2010-10-29 06:17:18 +00:00
}
2011-01-22 19:19:17 +00:00
debug ( " Switch Layer(released Fn): " ) ; debug_hex ( current_layer ) ;
2011-05-04 12:19:34 +00:00
current_layer = new_layer ( BIT_SUBST ( fn_bits , sent_fn ) ) ;
2011-01-22 19:19:17 +00:00
debug ( " -> " ) ; debug_hex ( current_layer ) ; debug ( " \n " ) ;
2010-10-29 06:17:18 +00:00
}
2011-01-22 19:19:17 +00:00
2011-05-04 12:19:34 +00:00
layer_used = false ;
2010-11-03 16:08:24 +00:00
last_fn = fn_bits ;
2011-02-08 15:03:58 +00:00
last_mods = keyboard_report - > mods ;
2010-11-03 08:33:20 +00:00
last_timer = timer_read ( ) ;
2010-10-29 06:17:18 +00:00
}
2011-01-22 19:19:17 +00:00
// send Fn keys
for ( uint8_t i = 0 ; i < 8 ; i + + ) {
if ( ( sent_fn & fn_bits ) & ( 1 < < i ) ) {
2011-02-10 06:51:30 +00:00
host_add_code ( keymap_fn_keycode ( 1 < < i ) ) ;
2011-01-22 19:19:17 +00:00
}
}
}
inline
static uint8_t new_layer ( uint8_t fn_bits )
{
return ( fn_bits ? keymap_fn_layer ( fn_bits ) : default_layer ) ;
2010-10-29 06:17:18 +00:00
}