
ncP              .   @   s
  d  Z  d d l m Z d d l Z d d l Z d d l Z d d l m Z d d l m	 Z	 d d l
 m Z m Z m Z d d l m Z y
 e Z Wn e k
 r Yn Xd d l Z d d	 l m Z m Z m Z m Z m Z m Z m Z m Z m Z m Z m Z d d
 l m  Z  m! Z! m" Z" m# Z# m$ Z$ m% Z% m& Z& m' Z' m( Z( m) Z) m* Z* m+ Z+ m, Z, m- Z- e e$  Z. e e!  Z/ e j0 d d d Z1 e1 j2 Z2 e* e2 _3 e+ g e2 _4 e j0 d d d Z5 d Z6 d Z7 d Z8 d Z9 d Z: d Z; Gd d   d e  Z< Gd d   d e j  Z= Gd d   d e j  Z> Gd d   d e j  Z? Gd d   d e j@  ZA Gd d   d e j  ZB e e e' e( e e<   ZC e5 jD ZE e eC e, e! g eE _4 e# eE _3 e5 jF ZF e eF _3 e5 jG ZG e# g eG _4 e" eG _3 e5 jH ZI e. e- e e g eI _4 e" eI _3 e5 jJ ZJ e. g eJ _4 e" eJ _3 e5 jK ZL e. g eL _4 e d ZM e5 jN ZN eM g eN _4 e" eN _3 e5 jO ZP e e% e g eP _4 e eP _3 e5 jQ ZR e e g eR _4 e eR _3 e5 jS ZS e e eM e% e e g eS _4 e eS _3 e5 jT ZT e e eB  e g eT _4 e eT _3 d ZU d ZV d ZW d ZX d ZY e5 jZ Z[ e& g e[ _4 e e[ _3 d  Z\ d Z] d! Z^ d" Z_ d# Z` i e e] 6e e^ 6e e_ 6e e` 6Za i ddd 6ded' 6dfd) 6dgd+ 6dhd- 6did  6djd0 6dkd2 6dld4 6dmd6 6dnd8 6dod8 6dpd8 6dqd< 6drd> 6dsd@ 6dtd@ 6dudC 6dvdE 6dwdG 6dxdI 6dydK 6dzdM 6d{dO 6d|dQ 6d}dS 6d~dU 6ddW 6ddY 6dd[ 6dd] 6dd_ 6dda 6ddc 6dde 6ddg 6ddi 6ddk 6ddm 6ddo 6ddq 6dds 6ddu 6ddw 6ddy 6dd{ 6dd} 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd 6dd6dd6dd6dd6dd	6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd!6dd#6dd%6dd'6dd)6dd+6dd-6dd/6dd16dd36dd56dd66dd86dd96dd;6dd=6dd?6ddA6ddC6ddE6ddG6ddI6ddK6d dM6ddN6Zb e   Zc e	 ed  Ze e	 ed  Zf i  Zg f  dddddddg Zh e ji dM  Zj e ji dM  Zk eM   Zl dPdQ  Zm dRdS  Zn en Zo d	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,g$ Zp d% aq d% ar d% as et d  dd	g  Zu dUdV  Zv dWdX  Zw dYdZ  Zx d[d\  Zy d]d^  Zz d_d`  Z{ dadb  Z| e} dck r
en   d d l~ Z~ e~ j~ ee  e~ j~ ef  n  d S(-  a  
This is the Windows backend for keyboard events, and is implemented by
invoking the Win32 API through the ctypes module. This is error prone
and can introduce very unpythonic failure modes, such as segfaults and
low level memory leaks. But it is also dependency-free, very performant
well documented on Microsoft's website and scattered examples.

# TODO:
- Keypad numbers still print as numbers even when numlock is off.
- No way to specify if user wants a keypad key or not in `map_char`.
    )unicode_literalsN)Lock)defaultdict   )KeyboardEventKEY_DOWNKEY_UP)normalize_name)c_shortc_charc_uint8c_int32c_intc_uintc_uint32c_long	StructureWINFUNCTYPEPOINTER)WORDDWORDBOOLHHOOKMSGLPWSTRWCHARWPARAMLPARAMLONGHMODULELPCWSTR	HINSTANCEHWNDkernel32use_last_errorTuser32         c               @   sC   e  Z d  Z d e f d e f d e f d e f d e f g Z d S)KBDLLHOOKSTRUCTvk_code	scan_codeflagstimedwExtraInfoN)__name__
__module____qualname__r   r   	ULONG_PTR_fields_ r4   r4   +C:\Python Projects\keyboard\_winkeyboard.pyr)   7   s
   				r)   c               @   sL   e  Z d  Z d e f d e f d e f d e f d e f d e f f Z d S)
MOUSEINPUTZdxdyZ	mouseDatadwFlagsr-   r.   N)r/   r0   r1   r   r   r2   r3   r4   r4   r4   r5   r6   ?   s   					r6   c               @   sC   e  Z d  Z d e f d e f d e f d e f d e f f Z d S)
KEYBDINPUTZwVkZwScanr8   r-   r.   N)r/   r0   r1   r   r   r2   r3   r4   r4   r4   r5   r9   G   s
   				r9   c               @   s1   e  Z d  Z d e f d e f d e f f Z d S)HARDWAREINPUTZuMsgZwParamLZwParamHN)r/   r0   r1   r   r   r3   r4   r4   r4   r5   r:   N   s   		r:   c               @   s1   e  Z d  Z d e f d e f d e f f Z d S)_INPUTunionmikihiN)r/   r0   r1   r6   r9   r:   r3   r4   r4   r4   r5   r;   S   s   		r;   c               @   s(   e  Z d  Z d e f d e f f Z d S)INPUTtypeunionN)r/   r0   r1   r   r;   r3   r4   r4   r4   r5   r?   X   s   	r?            i  i  i  control-break processingF	backspace   tab	   clear   enter   shiftctrl   alt   pause   	caps lock   ime kana mode   ime hanguel modeime hangul modeime junja mode   ime final mode   ime hanja mode   ime kanji modeesc   ime convert   ime nonconvert   
ime accept   ime mode change request   spacebar    page up!   	page down"   end#   home$   left%   up&   right'   down(   select)   print*   execute+   print screen,   insert-   delete.   help/   00   11   22   33   44   55   66   77   88   99   aA   bB   cC   dD   eE   fF   gG   hH   iI   jJ   kK   lL   mM   nN   oO   pP   qQ   rR   sS   tT   uU   vV   wW   xX   yY   zZ   left windows[   right windows\   applications]   sleep_   `   a   b   c   d   e   f   g   h   i   *j   +k   	separatorl   -m   decimaln   /o   f1p   f2q   f3r   f4s   f5t   f6u   f7v   f8w   f9x   f10y   f11z   f12{   f13|   f14}   f15~   f16   f17   f18   f19   f20   f21   f22   f23   f24   num lock   scroll lock   
left shift   right shift   	left ctrl   
right ctrl   	left menu   
right menu   browser back   browser forward   browser refresh   browser stop   browser search key   browser favorites   browser start and home   volume mute   volume down   	volume up   
next track   previous track   
stop media   play/pause media   
start mail   select media   start application 1   start application 2      ,      .   ime process   attn   crsel   exsel   	erase eof   play   zoom   	reserved    pa1      alt grc       	      c   s  |  | | f t  k } | t k } | r= | r= t | d Vn  d d | k t d <d d | k t d <d d | k t d <d d	 | k t d
 <d d | k t d <d d | k t d <t | |  t t t t  d  } | rt j rt j Vt | |  t t t t  d  n  t |  d >| d >Bt d  } | rGt j rGt j Vn  t	 j
 | t  d @} | d k rwt |  Vn  | r| rt | d Vn  d  S)Nr   r  rN   rD   zalt grrP   rR   r   z	caps lockrV   znum lockr#  zscroll lockr%  r^   i      )keypad_keysofficial_virtual_keyskeyboard_state	ToUnicodeunicode_bufferlenvalueGetKeyNameTextname_bufferr%   MapVirtualKeyWMAPVK_VK_TO_CHARchr)	r+   vkis_extended	modifiers	is_keypadZis_officialZunicode_retZname_retcharr4   r4   r5   get_event_names_  s,    !"r  c                 sP  t  t r d Sd d   t d  D }  d d   t d  D } x	|  | D] \ } } | | d d d f t k r{ qN n  | t k r | t | <n  x d d g D] } x t D] } | | | | f } t t |    } | r d d   | D } | | t | <xA t t t	 | |   D]# \ }	 }
 t
 |
 j |	 | f  qWq q Wq WqN Wxa d d g D]S } xJ t D]B } d	 g t d
 d | | f <t
 d	 j d d
 d | | f f  qiWq\WWd QXt d d        j i d f  6d d 6d d 6d d 6d d 6   f d d   } x< t t
 j    D]( \ }
 } t t |  d | t
 |
 <q Wd S)zX
    Ensures the scan code/virtual key code/name translation tables are
    filled.
    Nc             S   s+   g  |  ]! } | t  j | t d   f  q S)r   )r%   MapVirtualKeyExWMAPVK_VSC_TO_VK_EX).0scr4   r4   r5   
<listcomp>  s   	 z&_setup_name_tables.<locals>.<listcomp>rB   c             S   s+   g  |  ]! } t  j | t d   | f  q S)r   )r%   r  MAPVK_VK_TO_VSC_EX)r  r}  r4   r4   r5   r    s   	 r   r   c             S   s   g  |  ] } | j     q Sr4   )lower)r  namer4   r4   r5   r    s   	 alt gri  r+  c               S   s   d S)N
   r4   r4   r4   r4   r5   <lambda>  s    z$_setup_name_tables.<locals>.<lambda>rN   r'   rC   rO   r(   rQ   c                s5   |  \ } } | \ } } } }   | | | | | f S)Nr4   )liner   entryr+   r}  extendedr  )modifiers_preferencer4   r5   	order_key  s    z%_setup_name_tables.<locals>.order_keykey)zshift)r  )zctrl)zalt)tables_lockto_namerangescan_code_to_vkdistinct_modifierslistr  	enumeratemapr	   	from_nameappendr   updateitemssortedset)Zall_scan_codesZall_vksr+   r}  r  r  r  namesZlowercase_namesr   r  r  entriesr4   )r  r5   _setup_name_tables  s8     &*10r     c                s   t      f d d     f d d   } t d  } t |  } t d  } t d  } t | | | |  } t j t |  d S)af  
    Registers a Windows low level keyboard hook. The provided callback will
    be invoked for each high-level keyboard event, and is expected to return
    True if the key event should be passed to the next program, or False if
    the event is to be blocked.

    No event is processed until the Windows messages are pumped (see
    start_intercept).
    c       	   
      sM  | d k r t  r d a  d Sd t d t d t j d  d @d t j d
  d @d t j d  d @} | | | | f } | t k r t t |    t | <n  t | } | r | d n d  } | t k r |  t	 k a n  | d k r| d k rd a  |  t	 k a n  | | | f t
 k }   t d |  d | p:| d | d |   S)Nr1  FTrN   alt grnum lockr#  r   	caps lockrV   scroll lockr%  r   i  r+  
event_typer+   r  r  )zshift)r  )r  )r  )r  )ignore_next_right_altshift_is_pressedaltgr_is_pressedr%   ZGetKeyStater  r  r  	shift_vksr   rq  r   )	r  r}  r+   r~  r  r  r  r  r  )callbackr4   r5   process_key  s"    9
z&prepare_intercept.<locals>.process_keyc       
         s   y | j  j } t d B} | t k r | j  j | @| k r | d @rK t n t } | j  j d @} | j  j }   | | | |  } | s d Sn  Wn9 t k
 r }	 z t	 d  t
 j   WYd  d  }	 ~	 Xn Xt d  |  | |  S)Nrm   r   zError in keyboard hook:)contentsr*   LLKHF_INJECTED	VK_PACKETr,   r   r   r+   	Exceptionr   	traceback	print_excCallNextHookEx)
ZnCodeZwParamZlParamr}  Zfake_altr  r~  r+   Zshould_continuer   )r  r4   r5   low_level_keyboard_handler  s    
"
z5prepare_intercept.<locals>.low_level_keyboard_handlerrM   Nr   )	r  r   LowLevelKeyboardProcGetModuleHandleWr   SetWindowsHookExatexitregisterUnhookWindowsHookEx)r  r  ZWH_KEYBOARD_LLZkeyboard_callbackhandleZ	thread_idZkeyboard_hookr4   )r  r  r5   prepare_intercept  s    
!r  c             C   sG   t  |   t   } x- t | d d d  sB t |  t |  q Wd  S)Nr   )r  LPMSG
GetMessageTranslateMessageDispatchMessage)r  msgr4   r4   r5   listen0  s
    
	
r  c             c   sy   t    t j |   } | s: t d j t |      n  x8 | D]0 \ } } | \ } } } } | pi | | f VqA Wd  S)Nz+Key name {} is not mapped to any known key.)r  r  get
ValueErrorformatrepr)r  r  r   r  r+   r}  r~  r  r4   r4   r5   map_name7  s    r  c             C   s   |  d k r; t  j d |  | d  t  j d |  | d  nN |  d k rr t j |  d  } t  j | |  | d  n t  j |  d | d  d  S)Ni  rP   r   rR   )r%   Zkeybd_eventr  r  )coder  r}  r4   r4   r5   _send_eventA  s    r  c             C   s   t  |  d  d  S)Nr   )r  )r  r4   r4   r5   pressN  s    r  c             C   s   t  |  d  d  S)Nr'   )r  )r  r4   r4   r5   releaseQ  s    r  c             C   s5  t  |  j d   } g  } g  } x t d t |  d  D] } | | | d  \ } } t d | d >| t d d   } | j t t t	 d |    t d | d >| t t
 Bd d   } | j t t t	 d |    q: W| | } t |  }	 t |	 }
 |
 |   } t t j t   } t |	 | |  d  S)Nzutf-16ler   r'   rG   r=   )	bytearrayencoder  rv  r9   KEYEVENTF_UNICODEr  r?   INPUT_KEYBOARDr;   KEYEVENTF_KEYUPr   ctypessizeof	SendInput)	characterZ
surrogatesZpressesZreleasesr   Zhigherr  Z	structureZinputsZnInputsZLPINPUTZpInputsZcbSizer4   r4   r5   type_unicodeT  s     $#

r  __main__)rE   F)z	backspaceF)ztabF)clearF)rL   F)shiftF)zctrlF)zaltF)rS   F)rU   F)rW   F)rY   F)rZ   F)r[   F)r]   F)r_   F)ra   F)zescF)rd   F)rf   F)rh   F)rj   F)rl   F)rn   F)rp   F)zendF)zhomeF)zleftF)rx   F)zrightF)zdownF)zselectF)zprintF)zexecuteF)r   F)zinsertF)zdeleteF)zhelpF)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)r   F)zsleepF)r   T)r   T)r   T)r   T)r   T)r   T)r   T)r   T)r   T)r   T)r   T)r   T)z	separatorT)r   T)zdecimalT)r   T)zf1F)zf2F)r   F)r   F)r   F)r   F)r   F)r   F)r  F)r  F)r  F)r  F)r
  F)r  F)r  F)r  F)r  F)r  F)r  F)r  F)r  F)r  F)r  F)r   F)r"  F)r$  F)r&  F)r(  F)r*  F)r,  F)r.  F)r0  F)r2  F)r4  F)r6  F)r8  F)r:  F)r<  F)r>  F)r@  F)rB  F)rD  F)rF  F)rH  F)rJ  F)rL  F)rN  F)rP  F)rR  F)rT  F)r   F)rW  F)r   F)rZ  F)r\  F)r^  F)r`  F)rb  F)rd  F)zplayF)zzoomF)rj  F)rl  F)r  F)r  )ro  )r"  )r  r"  )rU   )r  rU   )ro  r"  )r  r  r   )r  r  r   )re   rM   r   )re   rM   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r#  r   )r   r#  r   )r   r   r   )r   ru   r   )r   r   r   )r   ry   r   )r   r   r   )r   ro   r   )r   r   r   )r   r   r   )r   r   r   )r   rw   r   )r   r   r   )r   rK   r   )r   r   r   )r   r{   r   )r   r   r   )r   r   r   )r   rs   r   )r   r   r   )r   r}   r   )r   r   r   )r   rq   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )__doc__
__future__r   rer  r  	threadingr   collectionsr   _keyboard_eventr   r   r   _canonical_namesr	   Zunichrr|  	NameErrorr  r
   r   r   r   r   r   r   r   r   r   r   ctypes.wintypesr   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r  r2   WinDLLr#   r  restypeargtypesr%   r  ZINPUT_MOUSEr  ZINPUT_HARDWAREr  r  r)   r6   r9   r:   Unionr;   r?   r  ZSetWindowsHookExWr  r  r  ZGetMessageWr  r  ZDispatchMessageAr  Zkeyboard_state_typeZGetKeyboardStateZGetKeyNameTextWrx  rz  ZMapVirtualKeyrt  r  r{  ZMAPVK_VK_TO_VSCZMAPVK_VSC_TO_VKr  r  Z
VkKeyScanWZ	VkKeyScanr  Z
WM_KEYDOWNZWM_KEYUPZWM_SYSKEYDOWNZWM_SYSKEYUPZkeyboard_event_typesrr  r  r  r  r  r  r  create_unicode_bufferry  ru  rs  r  r  initrq  r  r  r  r  r  r  r  r  r  r  r  r  r/   pprintr4   r4   r4   r5   <module>   st  
L^													
												

			 8	J
