@ -1,57 +1,87 @@
@@ -1,57 +1,87 @@
use crate ::Device ;
use libc ::{ c_int , input_event } ;
use uinput_sys ::{ KEY_LEFTSHIFT , KEY_RIGHTSHIFT , KEY_CAPSLOCK } ;
use std ::fs ::File ;
use std ::io ::Read ;
use std ::collections ::HashMap ;
use std ::hash ::Hash ;
use std ::convert ::TryFrom ;
use crate ::{ Error , Result } ;
// 1 is down, 0 is up
const DOWN : i32 = 1 ;
const UP : i32 = 0 ;
const INVERT_KEY_FLAG : char = '^' ;
const CAPS_MODIFY_KEY_FLAG : char = '*' ;
const HALF_KEY_SEPARATOR : char = ':' ;
const LEFTSHIFT_INDEX : usize = KEY_LEFTSHIFT as usize ;
const RIGHTSHIFT_INDEX : usize = KEY_RIGHTSHIFT as usize ;
const CAPSLOCK_INDEX : usize = KEY_CAPSLOCK as usize ;
// nightly only...
//pub trait KeyCode = Into<usize> + TryFrom<usize> + Copy + Clone + Eq + Hash + Default + 'static;
#[ derive(PartialEq) ]
pub enum KeyState {
DOWN ,
UP ,
OTHER ,
}
pub trait KeyEvent < T >
where
T : Into < usize > ,
{
fn code ( & self ) -> T ;
fn value ( & self ) -> KeyState ;
}
const KEY_LEFTSHIFT_U16 : u16 = KEY_LEFTSHIFT as u16 ;
const KEY_RIGHTSHIFT_U16 : u16 = KEY_RIGHTSHIFT as u16 ;
const KEY_CAPSLOCK_U16 : u16 = KEY_CAPSLOCK as u16 ;
pub trait Keyboard < T , E , R = ( ) >
where
T : Into < usize > ,
E : KeyEvent < T > ,
{
fn send ( & self , event : & mut E ) -> Result < R > ;
fn send_mod_code ( & self , code : T , event : & mut E ) -> Result < R > ;
fn send_mod_code_value ( & self , code : T , up_not_down : bool , event : & mut E ) -> Result < R > ;
fn synchronize ( & self ) -> Result < R > ;
fn left_shift_code ( & self ) -> T ;
fn right_shift_code ( & self ) -> T ;
fn caps_lock_code ( & self ) -> T ;
fn block_key ( & self ) -> Result < R > ;
}
trait KeyMapper {
fn send_event ( & self , key_state : & [ bool ] , event : & mut input_event , device : & Device ) -> Result < ( ) > ;
pub trait KeyMapper < K , T , E , R >
where
T : Into < usize > ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > ;
}
pub struct KeyMaps {
keymaps : Vec < Box < KeyMapper > > ,
keymap_index_keys : HashMap < u16 , usize > ,
pub struct KeyMaps < K , T , E , R = ( ) >
where
T : Into < usize > + Copy + Clone + Eq + Hash ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
keymaps : Vec < Box < dyn KeyMapper < K , T , E , R > > > ,
keymap_index_keys : HashMap < T , usize > ,
switch_layout_keys : Vec < usize > ,
key_state : [ bool ; KEY_MAX ] ,
revert_default_key : u16 ,
revert_default_key : T ,
revert_keymap_index : usize ,
// above do not change, below does
chosen_keymap_index : usize ,
current_keymap_index : usize ,
}
fn parse_key ( key_map : & HashMap < & ' static str , c_int > , key : & str ) -> u16 {
fn parse_key < T : Clone + Copy > ( key_map : & HashMap < & ' static str , T > , key : & str ) -> T {
match key_map . get ( key . trim_matches ( | c : char | c . is_whitespace ( ) | | c = = INVERT_KEY_FLAG | | c = = CAPS_MODIFY_KEY_FLAG ) ) {
Some ( key_code ) = > * key_code as u16 ,
Some ( key_code ) = > * key_code ,
None = > panic! ( "unknown key: {}" , key . trim ( ) )
}
}
fn parse_keymap_numeric ( key_map : & HashMap < & ' static str , c_int > , keymap : & str ) -> Vec < u16 > {
fn parse_keymap_numeric < T : Clone + Copy > ( key_map : & HashMap < & ' static str , T > , keymap : & str ) -> Vec < T > {
keymap . split ( "," ) . map ( | k | parse_key ( key_map , k ) ) . collect ( )
}
fn parse_key_half_inverted ( key_map : & HashMap < & ' static str , c_int > , key : & str ) -> HalfInvertedKey {
fn parse_key_half_inverted < T : Clone + Copy > ( key_map : & HashMap < & ' static str , T > , key : & str ) -> HalfInvertedKey < T > {
HalfInvertedKey {
code : parse_key ( key_map , key ) ,
invert_shift : key . contains ( INVERT_KEY_FLAG ) ,
@ -60,14 +90,14 @@ fn parse_key_half_inverted(key_map: &HashMap<&'static str, c_int>, key: &str) ->
@@ -60,14 +90,14 @@ fn parse_key_half_inverted(key_map: &HashMap<&'static str, c_int>, key: &str) ->
}
// maybe shortcut to this if not contains * or :
fn parse_keymap_u16 ( key_map : & HashMap < & ' static str , c_int > , keymap : & str ) -> Vec < u16 > {
fn parse_keymap_u16 < T : Clone + Copy > ( key_map : & HashMap < & ' static str , T > , keymap : & str ) -> Vec < T > {
keymap . split ( "," ) . map ( | k | parse_key ( key_map , k ) ) . collect ( )
}
// todo: how do I return an iterator here instead of .collect to Vec?
fn parse_keymap ( key_map : & HashMap < & ' static str , c_int > , keymap : & str ) -> Vec < Key > {
fn parse_keymap < T : Copy > ( key_map : & HashMap < & ' static str , T > , keymap : & str ) -> Vec < Key < T > > {
keymap . split ( "," ) . map ( | k | {
let ret : Key = if k . contains ( HALF_KEY_SEPARATOR ) {
let ret : Key < T > = if k . contains ( HALF_KEY_SEPARATOR ) {
let keys : Vec < & str > = k . split ( HALF_KEY_SEPARATOR ) . collect ( ) ;
if keys . len ( ) ! = 2 {
panic! ( "split key can only have 2 keys, 1 :, has {} keys" , keys . len ( ) ) ;
@ -84,13 +114,18 @@ fn parse_keymap(key_map: &HashMap<&'static str, c_int>, keymap: &str) -> Vec<Key
@@ -84,13 +114,18 @@ fn parse_keymap(key_map: &HashMap<&'static str, c_int>, keymap: &str) -> Vec<Key
} ) . collect ( )
}
impl KeyMaps {
pub fn from_cfg < P : AsRef < Path > > ( key_map : & HashMap < & ' static str , c_int > , path : P ) -> KeyMaps {
impl < K , T , E , R > KeyMaps < K , T , E , R >
where
T : Into < usize > + TryFrom < usize > + Copy + Clone + Eq + Hash + Default + ' static ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
pub fn from_cfg < P : AsRef < Path > > ( key_map : & HashMap < & ' static str , T > , path : P ) -> KeyMaps < K , T , E , R > {
let key_map_config = parse_cfg ( path ) . expect ( "provided config cannot be found/parsed" ) ;
KeyMaps ::new ( key_map , key_map_config )
}
pub fn new ( key_map : & HashMap < & ' static str , c_int > , config : KeymapConfig ) -> KeyMaps {
pub fn new ( key_map : & HashMap < & ' static str , T > , config : KeymapConfig ) -> KeyMaps < K , T , E , R > {
if config . keymaps . len ( ) < 2 {
panic! ( "must have at least 2 keymaps (original and mapped) but only have {}," , config . keymaps . len ( ) ) ;
}
@ -99,10 +134,10 @@ impl KeyMaps {
@@ -99,10 +134,10 @@ impl KeyMaps {
}
let base_keymap = parse_keymap_numeric ( key_map , & config . keymaps [ 0 ] ) ;
//println!("base_keymap : {:?}", base_keymap);
let mut keymaps : Vec < Box < KeyMapper > > = vec! ( Box ::new ( Key ::Noop ) ) ; // todo: can we share the box?
let mut keymap_index_keys : HashMap < u16 , usize > = HashMap ::new ( ) ;
let mut keymaps : Vec < Box < dyn KeyMapper < K , T , E , R > > > = vec! ( Box ::new ( Key ::Noop ) ) ; // todo: can we share the box?
let mut keymap_index_keys : HashMap < T , usize > = HashMap ::new ( ) ;
for ( x , v ) in config . keymaps . iter ( ) . enumerate ( ) {
keymap_index_keys . insert ( * key_map . get ( & * x . to_string ( ) ) . unwrap ( ) as u16 , x ) ;
keymap_index_keys . insert ( * key_map . get ( & * x . to_string ( ) ) . unwrap ( ) , x ) ;
if x = = 0 {
continue ;
}
@ -141,7 +176,7 @@ impl KeyMaps {
@@ -141,7 +176,7 @@ impl KeyMaps {
KeyMaps {
keymaps : keymaps ,
keymap_index_keys : keymap_index_keys ,
switch_layout_keys : config . switch_layout_keys . iter ( ) . map ( | k | parse_key ( key_map , k ) as usize ) . collect ( ) ,
switch_layout_keys : config . switch_layout_keys . iter ( ) . map ( | k | parse_key ( key_map , k ) . into ( ) ) . collect ( ) ,
key_state : [ false ; KEY_MAX ] ,
// todo: detect key state? at least CAPSLOCK...
revert_default_key : parse_key ( key_map , & config . revert_default_key ) ,
@ -150,20 +185,21 @@ impl KeyMaps {
@@ -150,20 +185,21 @@ impl KeyMaps {
current_keymap_index : config . default_keymap_index ,
}
}
}
//}
//impl KeyMapper for KeyMaps {
impl KeyMaps {
pub fn send_event ( & mut self , mut event : & mut input_event , device : & Device ) -> Result < ( ) > {
//impl KeyMaps {
pub fn send_event ( & mut self , mut event : & mut E , device : & K ) -> Result < R > {
//println!("type: {} code: {} value: {}", event.type_, event.code, event.value);
if event . value ! = 2 {
let value = event . value ( ) ;
if value ! = KeyState ::OTHER {
// todo: index check here...
if event . code = = KEY_CAPSLOCK_U16 {
if event . value = = DOWN {
self . key_state [ CAPSLOCK_INDEX ] = ! self . key_state [ CAPSLOCK_INDEX ] ;
if event . code ( ) = = device . caps_lock_code ( ) {
if value = = KeyState ::DOWN {
self . key_state [ device . caps_lock_code ( ) . into ( ) ] = ! self . key_state [ device . caps_lock_code ( ) . into ( ) ] ;
}
} else {
self . key_state [ event . code as usize ] = event . value = = DOWN ;
self . key_state [ event . code ( ) . into ( ) ] = value = = KeyState ::DOWN ;
}
let mut switch_layout_keys_pressed = true ;
for layout_switch_key in self . switch_layout_keys . iter_mut ( ) {
@ -174,18 +210,18 @@ impl KeyMaps {
@@ -174,18 +210,18 @@ impl KeyMaps {
}
//println!("switch_layout_keys_pressed: {}", self.switch_layout_keys_pressed);
if switch_layout_keys_pressed {
let new_index = self . keymap_index_keys . get ( & event . code ) ;
let new_index = self . keymap_index_keys . get ( & event . code ( ) ) ;
if new_index . is_some ( ) {
self . chosen_keymap_index = * new_index . unwrap ( ) ;
self . current_keymap_index = self . chosen_keymap_index ; // todo: what if revert_default_key is held? for now ignore
return Ok ( ( ) ) ; // we don't want to also send this keypress, so bail
return device . block_key ( ) ; // we don't want to also send this keypress, so bail
}
}
if event . code = = self . revert_default_key {
match event . value {
if event . code ( ) = = self . revert_default_key {
match value {
// todo: ctrl+c will get c stuck because code c value 1 will be sent, but then we'll let go of ctrl, and code j value 0 is sent, so c is never released... fix that...
DOWN = > self . current_keymap_index = self . revert_keymap_index ,
UP = > self . current_keymap_index = self . chosen_keymap_index ,
KeyState ::DOWN = > self . current_keymap_index = self . revert_keymap_index ,
KeyState ::UP = > self . current_keymap_index = self . chosen_keymap_index ,
_ = > ( ) // do nothing for 2
}
}
@ -197,17 +233,17 @@ impl KeyMaps {
@@ -197,17 +233,17 @@ impl KeyMaps {
// 249 is one more than KEY_MICMUTE which is max key in uinput-sys event.rs
const KEY_MAX : usize = 249 ;
struct KeyMap {
struct KeyMap < T : Into < usize > + Copy > {
//keymap: Vec<Key>,
keymap : [ Key ; KEY_MAX ] ,
keymap : [ Key < T > ; KEY_MAX ] ,
}
impl KeyMap {
impl < T : Into < usize > + Copy > KeyMap < T > {
pub fn new ( ) -> Self {
//let mut keymap = [0u16; KEY_MAX];
//let mut keymap : [Box<KeyMapper>; KEY_MAX] = [Box::new(NOOP); KEY_MAX];
//let mut keymap : [Box<KeyMapper>; KEY_MAX] = [Box::new(0u16); KEY_MAX];
let keymap : [ Key ; KEY_MAX ] = [ Key ::Noop ; KEY_MAX ] ;
let keymap : [ Key < T > ; KEY_MAX ] = [ Key ::Noop ; KEY_MAX ] ;
/*
let mut keymap : Vec < Key > = Vec ::with_capacity ( KEY_MAX ) ;
#[ allow(unused_variables) ]
@ -234,25 +270,30 @@ impl KeyMap {
@@ -234,25 +270,30 @@ impl KeyMap {
self . keymap [ from as usize ] = to ;
}
* /
pub fn map ( & mut self , from : u16 , to : Key ) {
self . keymap [ from as usize ] = to ;
pub fn map ( & mut self , from : T , to : Key < T > ) {
self . keymap [ from . into ( ) ] = to ;
}
}
impl KeyMapper for KeyMap {
fn send_event ( & self , key_state : & [ bool ] , event : & mut input_event , device : & Device ) -> Result < ( ) > {
self . keymap [ event . code as usize ] . send_event ( key_state , event , device )
impl < K , T , E , R > KeyMapper < K , T , E , R > for KeyMap < T >
where
T : Into < usize > + Copy ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > {
self . keymap [ event . code ( ) . into ( ) ] . send_event ( key_state , event , device )
}
}
struct CodeKeyMap {
struct CodeKeyMap < T : Into < usize > + TryFrom < usize > + Copy + Default > {
//keymap: Vec<Key>,
keymap : [ u16 ; KEY_MAX ] ,
keymap : [ T ; KEY_MAX ] ,
}
impl CodeKeyMap {
impl < T : Into < usize > + TryFrom < usize > + Copy + Default > CodeKeyMap < T > {
pub fn new ( ) -> Self {
let mut keymap = [ 0 u16 ; KEY_MAX ] ;
let mut keymap = [ T ::default ( ) ; KEY_MAX ] ;
// which is rustier
/*
for x in 0 .. KEY_MAX {
@ -260,7 +301,7 @@ impl CodeKeyMap {
@@ -260,7 +301,7 @@ impl CodeKeyMap {
}
* /
for ( x , v ) in keymap . iter_mut ( ) . enumerate ( ) {
* v = x as u16 ;
* v = T ::try_from ( x ) . unwrap_or_else ( | _ | panic! ( "cannot convert from usize to T ????" ) ) ;
}
//println!("keymap: {:?}", &keymap[..]);
CodeKeyMap {
@ -268,29 +309,27 @@ impl CodeKeyMap {
@@ -268,29 +309,27 @@ impl CodeKeyMap {
}
}
pub fn map ( & mut self , from : u16 , to : u16 ) {
self . keymap [ from as usize ] = to ;
}
}
impl KeyMapper for CodeKeyMap {
fn send_event ( & self , key_state : & [ bool ] , event : & mut input_event , device : & Device ) -> Result < ( ) > {
self . keymap [ event . code as usize ] . send_event ( key_state , event , device )
pub fn map ( & mut self , from : T , to : T ) {
self . keymap [ from . into ( ) ] = to ;
}
}
#[ allow(unused_variables, unused_mut) ]
impl KeyMapper for u16 {
fn send_event ( & self , key_state : & [ bool ] , mut event : & mut input_event , device : & Device ) -> Result < ( ) > {
event . code = * self ;
device . write_event ( event )
impl < K , T , E , R > KeyMapper < K , T , E , R > for CodeKeyMap < T >
where
T : Into < usize > + TryFrom < usize > + Copy + Default ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , _key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > {
device . send_mod_code ( self . keymap [ event . code ( ) . into ( ) ] , event )
//self.keymap[event.code().into()].send_event(key_state, event, device)
}
}
// todo:capslock_nomodify is like a whole-key thing, not a half-key thing, split code/invert_shift to own struct, send into send_key from *InvertedKey, maybe anyway, consider it, maybe 1 char for whole key and another for half?
#[ derive(Clone, Copy) ]
struct HalfInvertedKey {
code : u16 ,
struct HalfInvertedKey < T : Clone + Copy > {
code : T ,
// code this is describing
invert_shift : bool ,
// true to invert shift for this code
@ -298,100 +337,102 @@ struct HalfInvertedKey {
@@ -298,100 +337,102 @@ struct HalfInvertedKey {
// true means capslock does not normally modify this, but you would like it to
}
impl HalfInvertedKey {
fn send_key ( & self , key_state : & [ bool ] , event : & mut input_event , device : & Device , left_shift : bool , right_shift : bool , caps_lock : bool ) -> Result < ( ) > {
let code = self . code ;
let value = event . value ;
let mut invert_shift = self . invert_shift ;
if value = = DOWN {
if caps_lock & & self . capslock_nomodify {
invert_shift = ! invert_shift ;
}
if invert_shift {
if left_shift {
event . code = KEY_LEFTSHIFT_U16 ;
event . value = UP ;
} else if right_shift {
event . code = KEY_RIGHTSHIFT_U16 ;
event . value = UP ;
} else {
event . code = KEY_LEFTSHIFT_U16 ;
event . value = DOWN ;
}
//event.code.send_event(key_state, event, device);
device . write_event ( event ) ? ;
// SYN_REPORT after, then key, then key's SYN_REPORT
device . synchronize ( ) ? ;
event . code = code ; // not needed since u16 does it
event . value = value ;
}
fn send_half_inverted_key < K , T , E , R > ( half_inverted_key : & HalfInvertedKey < T > , event : & mut E , device : & K , left_shift : bool , right_shift : bool , caps_lock : bool ) -> Result < R >
where
T : Into < usize > + Clone + Copy ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
let value = event . value ( ) ;
let mut invert_shift = half_inverted_key . invert_shift ;
if value = = KeyState ::DOWN {
if caps_lock & & half_inverted_key . capslock_nomodify {
invert_shift = ! invert_shift ;
}
code . send_event ( key_state , event , device ) ? ;
if value = = UP {
if caps_lock & & self . capslock_nomodify {
invert_shift = ! invert_shift ;
}
if invert_shift {
if left_shift {
event . code = KEY_LEFTSHIFT_U16 ;
event . value = DOWN ;
} else if right_shift {
event . code = KEY_RIGHTSHIFT_U16 ;
event . value = DOWN ;
} else {
event . code = KEY_LEFTSHIFT_U16 ;
event . value = UP ;
}
//event.code.send_event(key_state, event, device);
// SYN_REPORT first after key, then shift, then key's SYN_REPORT which will be used for shift's
device . synchronize ( ) ? ;
device . write_event ( event ) ? ;
// neither of these are needed now...
event . code = code ; // not needed since u16 does it
event . value = value ;
}
if invert_shift {
let ( shift_code , up_not_down ) = if left_shift {
( device . left_shift_code ( ) , true )
} else if right_shift {
( device . right_shift_code ( ) , true )
} else {
( device . left_shift_code ( ) , false )
} ;
device . send_mod_code_value ( shift_code , up_not_down , event ) ? ;
// SYN_REPORT after, then key, then key's SYN_REPORT
device . synchronize ( ) ? ;
}
}
let ret = device . send_mod_code ( half_inverted_key . code , event ) ? ;
if value = = KeyState ::UP {
if caps_lock & & half_inverted_key . capslock_nomodify {
invert_shift = ! invert_shift ;
}
if invert_shift {
let ( shift_code , up_not_down ) = if left_shift {
( device . left_shift_code ( ) , false )
} else if right_shift {
( device . right_shift_code ( ) , false )
} else {
( device . left_shift_code ( ) , true )
} ;
// SYN_REPORT first after key, then shift, then key's SYN_REPORT which will be used for shift's
device . synchronize ( ) ? ;
device . send_mod_code_value ( shift_code , up_not_down , event ) ? ;
}
Ok ( ( ) )
}
Ok ( ret )
}
impl KeyMapper for HalfInvertedKey {
fn send_event ( & self , key_state : & [ bool ] , event : & mut input_event , device : & Device ) -> Result < ( ) > {
let left_shift = key_state [ LEFTSHIFT_INDEX ] ;
let right_shift = key_state [ RIGHTSHIFT_INDEX ] ;
let caps_lock = key_state [ CAPSLOCK_INDEX ] ;
self . send_key ( key_state , event , device , left_shift , right_shift , caps_lock )
impl < K , T , E , R > KeyMapper < K , T , E , R > for HalfInvertedKey < T >
where
T : Into < usize > + Clone + Copy ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > {
let left_shift = key_state [ device . left_shift_code ( ) . into ( ) ] ;
let right_shift = key_state [ device . right_shift_code ( ) . into ( ) ] ;
let caps_lock = key_state [ device . caps_lock_code ( ) . into ( ) ] ;
send_half_inverted_key ( self , event , device , left_shift , right_shift , caps_lock )
}
}
#[ derive(Clone, Copy) ]
enum Key {
enum Key < T >
where
T : Copy + Clone
{
Noop ,
Direct ( u16 ) ,
HalfKey ( HalfInvertedKey ) ,
FullKey ( HalfInvertedKey , HalfInvertedKey ) ,
Direct ( T ) ,
HalfKey ( HalfInvertedKey < T > ) ,
FullKey ( HalfInvertedKey < T > , HalfInvertedKey < T > ) ,
}
impl KeyMapper for Key {
fn send_event ( & self , key_state : & [ bool ] , event : & mut input_event , device : & Device ) -> Result < ( ) > {
impl < K , T , E , R > KeyMapper < K , T , E , R > for Key < T >
where
T : Into < usize > + Copy ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > {
match * self {
Key ::Noop = > {
device . write_event ( event )
device . send ( event )
} ,
Key ::Direct ( code ) = > {
co de. send_event ( key_stat e , event , device )
devic e . send_mod_code ( cod e , event )
} ,
Key ::HalfKey ( ref key_half ) = > {
key_half . send_event ( key_state , event , device )
} ,
Key ::FullKey ( ref noshift_half , ref shift_half ) = > {
let left_shift = key_state [ LEFTSHIFT_INDEX ] ;
let right_shift = key_state [ RIGHTSHIFT_INDEX ] ;
let caps_lock = key_state [ CAPSLOCK_INDEX ] ;
let left_shift = key_state [ device . left_shift_code ( ) . into ( ) ] ;
let right_shift = key_state [ device . right_shift_code ( ) . into ( ) ] ;
let caps_lock = key_state [ device . caps_lock_code ( ) . into ( ) ] ;
if caps_lock ! = ( left_shift | | right_shift ) {
shift_half . send_key ( key_state , event , device , left_shift , right_shift , caps_lock )
send_half_inverted_key ( shift_half , event , device , left_shift , right_shift , caps_lock )
} else {
noshift_half . send_key ( key_state , event , device , left_shift , right_shift , caps_lock )
send_half_inverted_key ( noshift_half , event , device , left_shift , right_shift , caps_lock )
}
} ,
}