U
    PeK:                     @   s   d Z dZddlZddlZddlZddlmZ ddlmZ G dd deZ	dej
krXdZnddlZd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mZmZ dd
lmZ ddlmZ ddl m!Z! G dd deZe"de dS )au  
Native support for Multitouch devices on Linux, using libmtdev.
===============================================================

The Mtdev project is a part of the Ubuntu Maverick multitouch architecture.
You can read more on http://wiki.ubuntu.com/Multitouch

To configure MTDev, it's preferable to use probesysfs providers.
Check :py:class:`~kivy.input.providers.probesysfs` for more information.

Otherwise, add this to your configuration::

    [input]
    # devicename = hidinput,/dev/input/eventXX
    acert230h = mtdev,/dev/input/event2

.. note::
    You must have read access to the input event.

You can use a custom range for the X, Y and pressure values.
On some drivers, the range reported is invalid.
To fix that, you can add these options to the argument line:

* invert_x : 1 to invert X axis
* invert_y : 1 to invert Y axis
* min_position_x : X minimum
* max_position_x : X maximum
* min_position_y : Y minimum
* max_position_y : Y maximum
* min_pressure : pressure minimum
* max_pressure : pressure maximum
* min_touch_major : width shape minimum
* max_touch_major : width shape maximum
* min_touch_minor : width shape minimum
* max_touch_minor : height shape maximum
* rotation : 0,90,180 or 270 to rotate

An inverted display configuration will look like this::

    [input]
    # example for inverting touch events
    display = mtdev,/dev/input/event0,invert_x=1,invert_y=1
)MTDMotionEventProviderMTDMotionEvent    N)MotionEvent)	ShapeRectc                       s0   e Zd Z fddZ fddZdd Z  ZS )r   c                    s*   | dd | dd t j|| d S )NZis_touchTZtype_idtouch)
setdefaultsuper__init__)selfargskwargs	__class__ >/tmp/pip-unpacked-wheel-xzebddm3/kivy/input/providers/mtdev.pyr	   8   s    zMTDMotionEvent.__init__c                    s   d|kr|d | _ nd| _ d|kr.|d | _nd| _dg| _d|krxd|krxt | _|d | j_|d | j_| jd d|kr|d | _| jd t	 
| d S )	Nxypossize_wsize_hshapepressure)sxsyZprofiler   r   widthheightappendr   r   depack)r
   r   r   r   r   r   =   s     
zMTDMotionEvent.depackc                 C   s,   | j | j| j| jf\}}}}d||||f S )Nz-<MTDMotionEvent id=%d pos=(%f, %f) device=%s>)idr   r   device)r
   ir   r   dr   r   r   __str__Q   s    zMTDMotionEvent.__str__)__name__
__module____qualname__r	   r   r#   __classcell__r   r   r   r   r   6   s   r   ZKIVY_DOC)DeviceMTDEV_TYPE_EV_ABSMTDEV_CODE_SLOTMTDEV_CODE_POSITION_XMTDEV_CODE_POSITION_YMTDEV_CODE_PRESSUREMTDEV_CODE_TOUCH_MAJORMTDEV_CODE_TOUCH_MINORMTDEV_CODE_TRACKING_IDMTDEV_ABS_POSITION_XMTDEV_ABS_POSITION_YMTDEV_ABS_TOUCH_MINORMTDEV_ABS_TOUCH_MAJOR)MotionEventProvider)MotionEventFactory)Loggerc                       s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
r   )min_position_xmax_position_xmin_position_ymax_position_ymin_pressuremax_pressuremin_touch_majormax_touch_majormin_touch_minormax_touch_minorinvert_xinvert_yrotationc              	      st  t t| || d | _d | _t | _|d}|sLt	d t	d d S |d | _t
d| j  |dd  D ]}|dkrqr|d}t|d	krd
| }t	| qr|\}}|tjkrt	d|  qrzt|| j|< W n0 tk
r   d||f }t	| Y qrY nX t
d|t|f  qrd| jkr@d| jd< n0| jd dkrpt	d| jd  d| jd< d S )N,z*MTD: No filename pass to MTD configurationz&MTD: Use /dev/input/event0 for exampler   zMTD: Read event from <%s>    =   z.MTD: Bad parameter %s: Not in key=value formatzMTD: unknown %s optionz#MTD: invalid value %s for option %szMTD: Set custom %s to %drD   )r   Z        z%HIDInput: invalid rotation value ({}))r   r   r	   _deviceinput_fndictdefault_rangessplitr7   errorinfolenoptionsint
ValueErrorformat)r
   r    r   argerrkeyvaluer   r   r   r	   s   sN    








zMTDMotionEventProvider.__init__c              	   C   s`   | j d krd S d| _t | _tj| jj| j	t
| j| j | j| jdd| _d| j_| j  d S )Nr   )queuerN   r    rP   )nametargetr   T)rN   uidcollectionsdequer]   	threadingThreadr   r$   _thread_runrO   r    rP   threaddaemonstart)r
   r   r   r   rh      s     

zMTDMotionEventProvider.startc              
      s2  | d}| d| d | dj }i g i }i fdd} fdd}d	d
 }|}d}	zt|}
W nH tk
r } z*|jdkrtd| W Y 
d S  W 5 d }~X Y nX t }|
t	}|d|j
}|d|j}td|||f  |
t}|d|j
}|d|j}td|||f  |
t}|d|j
}|d|j}td|||f  |
t}|d|j
}|d|j}td|||f  |dd}|dd}td|||f  tt|dd}tt|dd}td |||f  |d!dtd"|f  d}|
r.|d#kr|td$|  tj|sVtd% q:|
  t|}
td&|  d}q|
d#rq|q||
  }|d kr|d'7 }qd}|jtkr|jtkr|j}	q|	krt |	< |	 }|j}|j}|tkr"||||}||||d( n|t krLd)|||| }||||d* n|t!krh|||||d+< n|t"kr|||||d,< nt|t#kr|||||d-< nX|t$kr|d.krd/|d0< |%|	 |fd1d2|D  |&  qn||d3< nq|%|	 q|r|fd4d2|D  |&  qd S )5NrN   r]   r    rP   c                    sf   |\}}|rd| } dkr&|| |< n< dkr8|| |< n* dkrNd| | |< n dkrbd| | |< d S )N      ?r   rJ   rK   rL   r   )pointr\   invertZcoordsZcxcy)rD   r   r   assign_coord   s    

z8MTDMotionEventProvider._thread_run.<locals>.assign_coordc              	      s   | D ]}d|krq|d }z| }W n* t k
rP   t ||}||j< Y nX || d}|krvd}| d|krd}|d= |j= | |  ||f qd S )Nr   updatebegindeleteend)KeyErrorr   r   mover   removeZupdate_time_end)Zpointsr   tidr   action)r    r]   touchestouches_sentr   r   process   s*    


z3MTDMotionEventProvider._thread_run.<locals>.processc                 S   s8   z| | t ||  W S  tk
r2   | |  Y S X d S N)floatZeroDivisionError)r\   ZvminZvmaxr   r   r   	normalize   s    z5MTDMotionEventProvider._thread_run.<locals>.normalizer      zUMTD: Unable to open device "{0}". Please ensure you have the appropriate permissions.r8   r9   z%MTD: <%s> range position X is %d - %dr:   r;   z%MTD: <%s> range position Y is %d - %dr>   r?   z&MTD: <%s> range touch major is %d - %dr@   rA   z&MTD: <%s> range touch minor is %d - %dr<   r=      z#MTD: <%s> range pressure is %d - %drB   rC   z*MTD: <%s> axes inversion: X is %d, Y is %drD   zMTD: <%s> rotation set to %di  z#MTD: <%s> input device disconnectedg?z"MTD: <%s> input device reconnectedrF   Zxyri   Zyxr   r   r   r   Trp   c                    s   g | ]} | qS r   r   .0r   l_pointsr   r   
<listcomp>g  s     z6MTDMotionEventProvider._thread_run.<locals>.<listcomp>r   c                    s   g | ]} | qS r   r   r   r   r   r   r   s  s     )'getr(   OSErrorerrnor7   warnrX   setZget_absr1   ZminimummaximumrS   r2   r4   r3   rV   boolospathexiststimesleepcloseZidletyper)   coder*   r\   rO   r+   r,   r-   r.   r/   r0   addclear)r
   r   rN   Zdrsrj   rm   ry   r}   _fnZ_slotrM   eZ_changesabZrange_min_position_xZrange_max_position_xZrange_min_position_yZrange_max_position_yZrange_min_majorZrange_max_majorZrange_min_minorZrange_max_minorZrange_min_pressureZrange_max_pressurerB   rC   ZfailuresdataZev_valueZev_codevalr   )r    r   r]   rD   rw   rx   r   re      s   



























z"MTDMotionEventProvider._thread_runc                 C   s0   z| j  \}}||| qW n   Y nX d S rz   )r]   popleft)r
   Zdispatch_fnZ
event_typer   r   r   r   rn   v  s
    zMTDMotionEventProvider.update)	r$   r%   r&   rU   r	   rh   re   rn   r'   r   r   r   r   r   i   s   6 >r   Zmtdev)#__doc____all__r   os.pathr   Zkivy.input.motioneventr   Zkivy.input.shaper   r   environr   rc   ra   Zkivy.lib.mtdevr(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   Zkivy.input.providerr5   Zkivy.input.factoryr6   Zkivy.loggerr7   registerr   r   r   r   <module>   s&   , 
<  