package Ġcom . dev build . dd app . event source Ċ Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . delay Ċ import Ġkotlinx . coroutines . launch Ċ import Ġlc . k ra . system . keyboard . Global Keyboard Hook Ċ import Ġlc . k ra . system . keyboard . event . Global KeyEvent Ċ import Ġlc . k ra . system . keyboard . event . Global Key Listener Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . concurrent . atomic . Atomic Long Ċ Ċ class ĠKeyboard EventSource ( ĊĠĠĠ Ġval Ġkey : ĠInt Ġ= ĠGlobal KeyEvent . VK _ SPACE , ĊĠĠĠ Ġval Ġkeyboard Hook : ĠGlobal Keyboard Hook Ġ= ĠGlobal Keyboard Hook ( true ) Ċ ) Ġ: ĊĠĠĠ ĠEvent Source (), ĠGlobal Key Listener Ġ{ ĊĠĠĠ Ġval Ġlog Ġ= ĠLoggerFactory . getLogger (" Keyboard EventSource ") ĊĠĠĠ Ġval Ġpressed Keys Ġ= ĠConcurrent HashMap < Int , ĠLong >() ĊĠĠĠ Ġval Ġkey Counts Ġ= ĠConcurrent HashMap < Int , ĠAtomic Long >() ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġkeyboard Hook . add Key Listener ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġif Ġkey Ġis Ġheld , Ġthen Ġmultiple Ġpressed Ġevents Ġare Ġsent ĊĠĠĠ Ġoverride Ġfun Ġkey Pressed ( event : ĠGlobal KeyEvent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// log . info (" key Ġdown Ġ${ event . virtual KeyCode }") ĊĠĠĠĠĠĠĠ Ġpressed Keys . put If Absent ( event . virtual KeyCode , ĠSystem . currentTimeMillis ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġkey Released ( event : ĠGlobal KeyEvent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// log . info (" key Ġup Ġ${ event . virtual KeyCode }") ĊĠĠĠĠĠĠĠ Ġval Ġt 0 Ġ= Ġpressed Keys . remove ( event . virtual KeyCode ) Ġ?: Ġ 0 L ĊĠĠĠĠĠĠĠ Ġval Ġt 1 Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠ Ġif Ġ( t 1 Ġ- Ġt 0 Ġ< Ġ 5 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Counts . put If Absent ( event . virtual KeyCode , ĠAtomic Long ( 1 L )) Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Counts [ event . virtual KeyCode ] !!. add AndGet ( 1 L ); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠGlobal Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( 5 0 0 L ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Counts [ event . virtual KeyCode ]?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Gesture Event ( Event ( EventType . N _ CLICK , Ġit . get ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Gesture Event ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent ( EventType . LONG _ PRESS , Ġ(( t 1 Ġ- Ġt 0 ) Ġ/ Ġ 1 0 0 0 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Gesture Event ( e : ĠEvent ) Ġ= ĊĠĠĠĠĠĠĠ ĠGlobal Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Listeners ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġreset () Ġ= Ġkey Counts . clear () Ċ } Ċ