+
     iF  c                  s   R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
Ht ^ RIHt ^ RIHtHtHtHtHt ^ RIt^ RIHtHt ^ RIHt ^ R	IHtHtHt ^ R
IHt ^ RI H!t! ^ RI"H#t# ^ RI$H%t% ^ RI&H't'H(t(H)t) ^ RI*H+t+ ^ RI,H-t-H.t. ]]/]]/,          3,          t0Rt1 ! R R]2]Pf                  4      t4 ! R R]2]Pf                  4      t5R R lt6R R lt7]! RR7       ! R R4      4       t8 ! R R]Pr                  4      t:R# ) z?Keeps injecting keycodes in the background based on the preset.)annotationsN)defaultdict)	dataclass)
Connection)DictListOptionalTupleUnion)InputCombinationInputConfig)Preset)_Groupclassify
DeviceType)MessageType)Context)EventReader)MappingParser)set_numlockis_numlock_onensure_numlock)logger)get_device_hash
DeviceHashzinput-remapperc                  s    ] tR t^9tRtRtR# )InjectorCommandCLOSE N)__name__
__module____qualname____firstlineno__r   __static_attributes__r       E/usr/lib/python3.14/site-packages/inputremapper/injection/injector.pyr   r   9   s    Er!   r   c                  s2    ] tR t^>tRtRtRtRtRtRt	Rt
RtR	# )
InjectorStateUNKNOWNSTARTINGZFAILEDRUNNINGSTOPPEDNO_GRABUPGRADE_EVDEVr   N)r   r   r   r   r$   r%   ERRORr&   r'   r(   r)   r    r   r!   r"   r#   r#   >   s%    GHEGGG#Mr!   r#   c               s$    V ^8  d   QhRRRRRR/# )   combinationr	   capabilitiesCapabilitiesDictreturnboolr   Zformat   "r"   __annotate__r3   H   s$      !1A	r!   c                st    V  F1  pVP                   VP                  VP                  . 4      9   g   K0   R# 	  R# )z@Are this combination or one of its sub keys in the capabilities?TF)codegettype)r,   r-   Zevents   && r"   is_in_capabilitiesr7   H   s3     ::))%**b99  r!   c               s$    V ^8  d   QhRRRRRR/# )r+   namestrsuffixr/   r   r1   r2   r"   r3   r3   S   s!       S S r!   c                s    ^PpV\        \        4      ,
          \        V4      ,
          ^,
          pV RV p\         RV RV 2p V # )z9Make sure the generated name is not longer than 80 chars.NZ )lenDEV_NAME)r8   r:   Zmax_lenZremaining_lenZmiddle   &&   r"   get_udev_namer>   S   sJ    Gc(m+c&k9A=M.=!FZq&*DKr!   T)Zfrozenc                  sR    ] tR t^\t$ ]P
                  tR]R&   R R ltR R lt	Rt
R# )	InjectorStateMessagezUnion[InjectorState]statec                   V ^8  d   QhRR/# r+   r/   r0   r   r1   r2   r"   r3   !InjectorStateMessage.__annotate__a   s     M M Mr!   c                	\    V P                   \        P                  \        P                  39   # N)r@   r#   r&   r%   self   &r"   activeZInjectorStateMessage.activea   s"    zzm33]5K5KLLLr!   c               rA   rB   r   r1   r2   r"   r3   rC   d   s     L L$ Lr!   c                	rD   rE   )r@   r#   r'   r(   rF   rH   r"   inactiveZInjectorStateMessage.inactived   s"    zzm33]5J5JKKKr!   r   N)r   r   r   r   r   Zinjector_stateZmessage_type__annotations__rI   rJ   r    r   r!   r"   r?   r?   \   s%    --LML Lr!   r?   c                  s$  a  ] tR t^ht$ RtR]R&   R]R&   R]R&   R]R	&   R
]R&   R]R&   R]R&   R]R&   RtR V 3R llt R R lt]	R R l4       t
 R R ltR R ltR R ltR tR  R! lt]R" R# l4       tR$ R% ltR& tR' R( ltR) R* ltR+tV ;t# ),InjectorzInitializes, starts and stops injections.

Is a process to make it non-blocking for the rest of the code and to
make running multiple injector easier. There is one process per
hardware-device that is being mapped.
r   groupr   presetzOptional[Context]contextzList[evdev.InputDevice]_devicesr#   _statezTuple[Connection, Connection]	_msg_pipezList[EventReader]_event_readerszasyncio.Event_stop_eventg?c               s(    V ^8  d   QhRRRRRRRR/# )	r+   rM   r   rN   r   mapping_parserr   r/   Noner   r1   r2   r"   r3   Injector.__annotate__{   s2     ) )) ) &	)
 
)r!   c                s   < Wn         W0n        \        P                  V n        \
        P                  ! 4       V n        W n        RV n	        . V n
        \        SV `1  VP                  R7       R# )z3

Parameters
----------
group
    the device group
N)r8   )rM   rU   r#   r$   rQ   multiprocessingZPiperR   rN   rO   rS   Zsuper__init__key)rG   rM   rN   rU   	__class__s   &&&&r"   rY   ZInjector.__init__{   sW     
,#++ )--/ eii(r!   c               rA   )r+   r/   r#   r   r1   r2   r"   r3   rW      s     " "= "r!   c                s   V P                   pV P                  ^,          P                  4       '       d$   V P                  ^,          P                  4       pKJ  V P	                  4       pV\
        P                  8g  ;'       g    TpV'       d   V\
        P                  8X  d   V'       d   \
        P                  pV\
        P                  \
        P                  39   d/   V'       g'   \
        P                  p\        P                  ! R4       \        P                  ! RV P                  P                  V P                  P                   V4       Wn         V P                   # )zMGet the state of the injection.

Can be safely called from the main process.
z'Injector was unexpectedly found stoppedz Injector state of "%s", "%s": %s)rQ   rR   ZpollrecvZis_aliver#   r$   r%   r&   r*   r   errordebugrM   rZ   rN   r8   )rG   r@   ZaliveZstarted   &   r"   	get_stateZInjector.get_state   s     nnQ$$&&NN1%**,E  =00099E---%%..//1F1FGGPU &++FG.JJNNKK		
 {{r!   c               rA   r+   r/   rV   r   r1   r2   r"   r3   rW      s     6 6 6r!   c                s    \         P                  ! RV P                  P                  4       V P                  ^,          P                  \        P                  4       R# )zEStop injecting keycodes.

Can be safely called from the main procss.
z*Stopping injecting keycodes for group "%s"N)r   inforM   rZ   rR   sendr   r   rF   rH   r"   stop_injectingZInjector.stop_injecting   s8     	@$**..Qq445r!   c                    V ^8  d   QhRRRR/# r+   input_configr
   r/   Optional[evdev.InputDevice]r   r1   r2   r"   r3   rW      s      '	$r!   c                s   V P                    Uu/ uF  p\        V4      VbK  	  ppVP                  VP                  4      ;p'       d>   VP                  VP                  RR7      P                  VP                  . 4      9   d   V# R# u upi )z~find the InputDevice specified by the InputConfig

ensures the devices supports the type and code specified by the InputConfigFZabsinfoN)rP   r   r5   origin_hashr4   r-   r6   )rG   rg   deviceZdevices_by_hash   &&  r"   _find_input_deviceZInjector._find_input_device   s     JNWv?62F:W %(()A)ABB6B  F$7$7$7$F$J$J!!2%   Xs   Bc               re   rf   r   r1   r2   r"   r3   rW      s      '	$r!   c                sZ  a \         P                  \         P                  \         P                  \         P                  \         P
                  \         P                  \         P                  .oV P                   Uu. uFB  pVP                  VP                  RR7      P                  VP                  . 4      9   g   K@  VNKD  	  pp\        V4      ^8  d   \        VV3R lR7      ^ ,          # \        V4      ^8X  d   VP                  4       # \         P"                  ! RV 24       R# u upi )z@find the InputDevice specified by the InputConfig fallback logicFri   c                s8   < SP                  \        V 4      4      # rE   )indexr   )Zdrankings   &r"   Z<lambda>Z6Injector._find_input_device_fallback.<locals>.<lambda>   s    GMM(1+4Nr!   )rZ   zCould not find input for N)r   ZKEYBOARDZGAMEPADZMOUSEZTOUCHPADZGRAPHICS_TABLETZCAMERAr$   rP   r4   r-   r5   r6   r;   ZsortedZpopr   r]   )rG   rg   rk   Z
candidatesro   s   &&  @r"   _find_input_device_fallbackZ$Injector._find_input_device_fallback   s    
 &&
 --/
'  ""5"155l6G6GLM F' 	 /
 z?Q **NOPQRRz?a>>##0?@/
s   ;=D(=D(c               rA   )r+   r/   z#Dict[DeviceHash, evdev.InputDevice]r   r1   r2   r"   r3   rW      s      B r!   c                sr   / p\        4       pV P                   F'  pVP                   F  pVP                  V4       K  	  K)  	  V F,  pV P	                  V4      ;p'       g   K  WQVP
                  &   K.  	  / pVP                  4        F+  pV P                  V4      ;p'       g   K  WV\        V4      &   K-  	  V# )z9Grab all InputDevices that match a mappings' origin_hash.)	setrN   input_combinationZaddrm   pathvalues_grab_devicer   )rG   Zneeded_devicesZinput_configsmappingrg   rk   Zgrabbed_devicess   &      r"   _grab_devicesZInjector._grab_devices   s      {{G ' 9 9!!,/ !: #
 *L"55lCCFC *06;;' * $++-F**622v22;A 78 . r!   c                s   \        \        4      pV P                   F-  pVP                   F  pW,          P	                  V4       K  	  K/  	  V F  pV P                  V4      '       d   K  V P                  V4      ;p'       g   K7  W,           FT  p\        VP                  4      p\        V4      pVP                  V4      pWW,          P                  VR7      WW&   WRn        KV  	  K  	  R# )zQUpdate all InputConfigs in the preset to include correct origin_hash
information.)rj   N)
r   ZlistrN   rr   appendrm   rp   r   rn   Zmodify)rG   Zmappings_by_inputrv   rg   rk   r,   device_hashZidxs   &       r"   _update_presetZInjector._update_preset  s     (-{{G ' 9 9!/66w? !: # .L&&|44">>|LLFL,::15g6O6O1P-f5!''5#.#3#:#:{#:#S ,7) ; .r!   c               re   )r+   rk   evdev.InputDevicer/   rh   r   r1   r2   r"   r3   rW   '  s      #4 9T r!   c                s   Rp\        ^
4       F7  p VP                  4        \        P                  ! RVP                  4       Vu # 	  \        P                  ! RVP                  4       \        P                  ! \        V4      4       R#   \
         dW   pTp\        P                  ! RTP                  T^,           4       \        P                  ! T P                  4        Rp?K  Rp?ii ; i)zTry to grab the device, return None if not possible.

Without grab, original events from it would reach the display server
even though they are mapped.
NzGrab %szFailed attempts to grab %s: %dz%Cannot grab %s, it is possibly in use)ZrangeZgrabr   r^   rs   ZIOErrortimesleepregrab_timeoutr]   r9   )rG   rk   r]   ZattemptZerrr=   r"   ru   ZInjector._grab_device'  s     RyG	0Y4	 ! 	<fkkJSZ   0 =v{{GVWKX

4..//0s   2BC,AC''C,c               re   )r+   input_devicer{   r/   r.   r   r1   r2   r"   r3   rW   ?  s      ): ?O r!   c                sj   \         P                  pV P                  RR7      pVP                  V9   d   W!P                   VP                  V9   d   W!P                   VP
                  VP                  VP                  . 4      9   d,   W!P                  ,          P                  VP
                  4       V# )z#Copy capabilities for a new device.Tri   )	evdevecodesr-   ZEV_SYNZEV_FFZ
ABS_VOLUMEr5   ZEV_ABSZremove)r   r   r-   s   &  r"   _copy_capabilitiesZInjector._copy_capabilities>  s      $000> ==L(]]+<<<'\\* 0 0 CC '..v/@/@Ar!   c               rA   ra   r   r1   r2   r"   r3   rW   U  s      T r!   c                s  "   \         P                  ! 4       p \         P                  ! 4       pVP                  V P                  ^ ,          P                  4       VP                  4       VP                  4       G Rj  xL
  VP                  4        V P                  ^ ,          P                  4       pV\        P                  8X  g   K  V P                  4       G Rj  xL
  R#  Lf L5i)z<Wait for messages from the main process to do special stuff.N)asyncioget_event_loopEventZ
add_readerrR   Zfilenorq   ZwaitZclearr\   r   r   _close)rG   loopZframe_availableZmsgr_   r"   _msg_listenerZInjector._msg_listenerU  s     %%'%mmoOOODNN1-4468K8KL!&&(((!!#..#((*Co+++kkm## )
 $s+   A:C'<C#=AC'	C'C%C'%C'c                	sX  "   \         P                  ! R 4       V P                  P                  4        \        P
                  ! R4      G Rj  xL
  \        P                  ! 4       pVP                  4        V P                  ^ ,          P                  \        P                  4       R#  L[5i)zReceived close signalg?N)r   r^   rT   rq   r   r}   r   ZstoprR   rc   r#   r'   )rG   r   s   & r"   r   ZInjector._closec  ss     ,- mmC    %%'		q}445 	!s   A
B*B(AB*c               re   )r+   sourcer{   r/   zevdev.UInputr   r1   r2   r"   r3   rW   q  s      0A l r!   c           
     	sF    \         P                  ! \        VP                  R 4      V P	                  V4      VP
                  P                  VP
                  P                  VP
                  P                  VP
                  P                  VP                  4       R7      pV#   \         dt   pR\        T4      9   d]   \        P                  ! R4       T P                  ^ ,          P!                  \"        P$                  4       \&        P(                  ! ^4       ThRp?ii ; i)Z	forwarded)r8   Zeventsvendorproductversionbustypeinput_propsr   z1Please upgrade your python-evdev version. ExitingN)r   ZUInputr>   r8   r   rb   r   r   r   r   r   Z	TypeErrorr9   r   r]   rR   rc   r#   r)   sysZexit)rG   r   Z
forward_toZerl   r"   _create_forwarding_deviceZ"Injector._create_forwarding_deviceq  s    	"6;;<..v6
 {{))++++++"..0J,   	A& PQq!&&}'B'BCG	s   BB" "D -A.DD c               rA   ra   r   r1   r2   r"   r3   rW     s     [V [VT [Vr!   c           	     s   \         P                  ! RV P                  P                  4       \        P
                  ! 4       p\        P                  ! V4       V P                  P                  4       V n        V P                  4        V P                  4       p/ pVP                  4        F  w  rEV P                  V4      W4&   K  	  \        V P                  VVV P                  4      V n        \        P"                  ! 4       V n        \'        V4      ^ 8X  dI   \         P(                  ! R4       V P*                  ^ ,          P-                  \.        P0                  4       R# \3        4       p. pV Fd  p\5        V P                   W$,          V P$                  4      pVP7                  VP9                  4       4       V P:                  P7                  V4       Kf  	  VP7                  V P=                  4       4       \?        V4       V P*                  ^ ,          P-                  \.        P@                  4        VPC                  \        PD                  ! V!  4       \'        V4      ^ 8  d   \         PL                  ! R4       VPO                  4        F  p
 V
PQ                  4        K  	  R#   \F         d   p	\I        T	4      R8w  d   T	h Rp	?	LrRp	?	i\J         d+   p	\         P(                  ! R\I        T	4      4        Rp	?	LRp	?	ii ; i  \J         d7   p	\         PL                  ! RT
PR                  \I        T	4      4        Rp	?	K  Rp	?	ii ; i)a  The injection worker that keeps injecting until terminated.

Stuff is non-blocking by using asyncio in order to do multiple things
somewhat concurrently.

Use this function as starting point in a process. It creates
the loops needed to read and map events and keeps running them.
z&Starting injecting the preset for "%s"zDid not grab any deviceNz+Event loop stopped before Future completed.z%Failed to run injector coroutines: %szInjector coroutines endedzOSError for ungrab on %s: %s)*r   rb   rM   rZ   r   Znew_event_loopZset_event_loopZget_devicesrP   rz   rw   Zitemsr   r   rN   rU   rO   r   rT   r;   r]   rR   rc   r#   r(   r   r   rx   runrS   r   r   r&   Zrun_until_completeZgatherZRuntimeErrorr9   ZOSErrorr^   rt   Zungrabrs   )rG   r   ZsourcesZforward_devicesry   rk   Znumlock_stateZ
coroutinesZevent_readerr]   r   s   &          r"   r   ZInjector.run  s|    	<djjnnM %%'t$

..0 	 $$&#*==?K+/+I+I&+QO( $3
 KK	
 #==?w<1LL23NN1""=#8#89%
"K&$  L
 l..01&&|4 # 	$,,./ 	M"q}445	N##GNNJ$?@ z?Q LL45nn&FV	 '  	 5zJJ K 	NLL@#e*MM	N  V;V[[#e*UUVsB   .#J! K>!K;,KK;K; K66K;>L?	+L::L?)	rP   rS   rR   rQ   rT   rO   rM   rU   rN   )r   r   r   r   __doc__rK   r~   rY   r`   r   rd   rm   rp   rw   rz   ru   Zstaticmethodr   r   r   r   r   r    Z__classcell__)r[   s   @r"   rL   rL   h   s     MN%%,,%%N) )8 :"H 6 6 " <48..  ,6:[V [Vr!   rL   );r   Z
__future__r    r   ZenumrX   r   r|   Zcollectionsr   Zdataclassesr   Zmultiprocessing.connectionr   Ztypingr   r   r   r   r   r   Z"inputremapper.configs.input_configr	   r
   Zinputremapper.configs.presetr   Zinputremapper.groupsr   r   r   Z)inputremapper.gui.messages.message_brokerr   Zinputremapper.injection.contextr   Z$inputremapper.injection.event_readerr   Z7inputremapper.injection.mapping_handlers.mapping_parserr   Zinputremapper.injection.numlockr   r   r   Zinputremapper.logging.loggerr   Zinputremapper.utilsr   r   Zintr.   r<   r9   ZEnumr   r#   r7   r>   r?   ZProcessrL   r   r!   r"   <module>r      s   * F "    
  # ! 1 5 5  L / 
 B 3 < Q V V / ;T#Y' c499 
$C $ $L L LAV&& AVr!   