3
NZQ                 @   s  d dl Z d dlZd dlZd dlZd dlT d dlmZ d dlmZ d dl	m
Z
 dZe jde jde jd	e jd
e jde jdiZe jde jde jde jde jde jde jdiZdZG dd dZG dd dZG dd dejZdd Z dd Z!dd  Z"d%d!d"Z#d#d$ Z$dS )&    N)*)utils)to_bytes_utf8)queue   	TYPE_BOOLTYPE_INT
TYPE_FIXEDTYPE_STRINGTYPE_BUTTON
TYPE_GROUP	UNIT_NONE
UNIT_PIXELUNIT_BITUNIT_MMUNIT_DPIUNIT_PERCENTUNIT_MICROSECONDi   c               @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )OptionaN  Class representing a SANE option.
    Attributes:
    index -- number from 0 to n, giving the option number
    name -- a string uniquely identifying the option
    title -- single-line string containing a title for the option
    desc -- a long string describing the option; useful as a help message
    type -- type of this option.  Possible values: TYPE_BOOL,
            TYPE_INT, TYPE_STRING, and so forth.
    unit -- units of this option.  Possible values: UNIT_NONE,
            UNIT_PIXEL, etc.
    size -- size of the value in bytes
    cap -- capabilities available; CAP_EMULATED, CAP_SOFT_SELECT, etc.
    constraint -- constraint on values.  Possible values:
        None : No constraint
        (min,max,step)  Integer values, from min to max, stepping by
        list of integers or strings: only the listed values are allowed
    c          
   C   sX   dd l }|| _|\	| _| _| _| _| _| _| _| _	| _
t| jtdkrTt| j| _d S )Nr    )string
cur_deviceindexnametitledesctypeunitsizecap
constraintstr)selfargsr   r    r$   /usr/share/hplip/scan/sane.py__init__h   s
    (zOption.__init__c             C   s   t j| jS )N)scanextisOptionActiver   )r"   r$   r$   r%   isActiver   s    zOption.isActivec             C   s   t j| jS )N)r'   isOptionSettabler   )r"   r$   r$   r%   
isSettableu   s    zOption.isSettablec             C   sh   | j  rd}nd}| j r.d}| jj| j}nd}d}d| j|| j| j| jt| j	 t
| j | j||f
 S )Nyesnoz <not available, inactive option>z
Name:      %s
Cur value: %s
Index:     %d
Title:     %s
Desc:      %s
Type:      %s
Unit:      %s
Constr:    %s
isActive:    %s
isSettable:  %s
)r+   r)   r   	getOptionr   r   r   r   TYPE_STRr   UNIT_STRr   r    s)r"   ZsettableZactiveZcurValuer$   r$   r%   __repr__x   s    zOption.__repr__c             C   sF  |d k	o| j d k	r4t| j tf kr|| j d k rZ| j d }tjd| j| j||f  n2|| j d kr| j d }tjd| j| j||f  | jj| j| nt| j tg krB|| j krB| j d }tj}x.| j D ]$}t	|| |k rt	|| }|}qW tjd| j| j|dj
| j |f  | jj| j| n| jj| j}|S )Nr   z6Invalid value for %s (%s < min value of %d). Using %d.r   z6Invalid value for %s (%s > max value of %d). Using %d.z?Invalid value for %s (%s not in constraint list: %s). Using %d.z, )r    r   logwarnr   r   	setOptionsysmaxsizeabsjoinr.   )r"   valuevZmin_distxr$   r$   r%   limitAndSet   s0    


zOption.limitAndSetN)	__name__
__module____qualname____doc__r&   r)   r+   r2   r=   r$   r$   r$   r%   r   U   s   
r   c               @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
d"ddZdd Zdd Zdd Zdd Zdd Zdd Zd d! ZdS )#
ScanDevicea   Class representing a SANE device.
    Methods:
    startScan()    -- initiate a scan, using the current settings
    cancelScan()   -- cancel an in-progress scanning operation

    Also available, but rather low-level:
    getParameters() -- get the current parameter settings of the device
    getOptions()    -- return a list of tuples describing all the options.

    Attributes:
    optlist -- list of option names

    You can also access an option name to retrieve its value, and to
    set it.  For example, if one option has a .name attribute of
    imagemode, and scanner is a ScanDevice object, you can do:
         print scanner.imagemode
         scanner.imagemode = 'Full frame'
         scanner.['imagemode'] returns the corresponding Option object.
    c             C   s$   d | _ tj|| _i | _| j  d S )N)scan_threadr'   
openDevicedevoptions_ScanDevice__load_options_dict)r"   rE   r$   r$   r%   r&      s    zScanDevice.__init__c             C   sB   | j }| jj }x,|D ]$}t|| }|jtjkr|||j< qW d S )N)rF   rE   
getOptionsr   r   r'   r   r   )r"   optsZopt_listtor$   r$   r%   Z__load_options_dict   s    


zScanDevice.__load_options_dictc             C   s   | j }||kr|||< d S || }|jtjkr<tjd|  tj|jsVtjd|  tj|jsptjd|  t|t	kr|jtj
krt|}y| jj|j|| _W n( tjk
r   tjd||f  d S X | jtj@ r| j  d S )NzGroups can't be set: %szInactive option: %sz#Option can't be set by software: %sz#Unable to set option %s to value %s)rF   r   r'   r   r3   errorr(   r   r*   intr	   floatrE   r5   r   Zlast_optZINFO_RELOAD_OPTIONSrG   )r"   keyr:   rI   optr$   r$   r%   r5      s(    zScanDevice.setOptionc             C   s   | j }|dkrt|j S |dkrB|d |d f|d |d ffS ||krVtd| || }|jtjkrvtd| |jtjkrtd	| tj|j	std
| | j
j|jS )NZoptlistZareaztl-xztl-yzbr-xzbr-yzNo such attribute: %szButtons don't have values: %szGroups don't have values: %s zInactive option: %s)rF   listkeysAttributeErrorr   r'   r   r   r(   r   rE   r.   r   )r"   rO   rI   rP   r$   r$   r%   r.     s     zScanDevice.getOptionc             C   s   | j }||kr|| S d S )N)rF   )r"   rO   rI   r$   r$   r%   getOptionObj4  s    zScanDevice.getOptionObjc             C   s
   | j j S )a?  Return a 6-tuple holding all the current device settings:
           (format, format_name, last_frame, (pixels_per_line, lines), depth, bytes_per_line)

            - format is the SANE frame type
            - format is one of 'grey', 'color' (RGB), 'red', 'green', 'blue'.
            - last_frame [bool] indicates if this is the last frame of a multi frame image
            - (pixels_per_line, lines) specifies the size of the scanned image (x,y)
            - lines denotes the number of scanlines per frame
            - depth gives number of pixels per sample
        )rE   getParameters)r"   r$   r$   r%   rU   :  s    zScanDevice.getParametersc             C   s
   | j j S )z<Return a list of tuples describing all the available options)rE   rH   )r"   r$   r$   r%   rH   H  s    zScanDevice.getOptionsBGRANc             C   s~   | j  sn| jj }| jj \| _| _| _| _| _| _	| _
t| j|||| _d| j_| jj  d| j| j
 |fS ddtjfS dS )z]
            Perform a scan with the current device.
            Calls sane_start().
        TFr   N)isScanActiverE   	startScanrU   formatformat_name
last_framepixels_per_linelinesdepthbytes_per_line
ScanThreadrC   scan_activestartr'   ZSANE_STATUS_DEVICE_BUSY)r"   byte_formatupdate_queueevent_queuestatusr$   r$   r%   rX   M  s    
&
zScanDevice.startScanc             C   s
   | j j S )z)Cancel an in-progress scanning operation.)rE   
cancelScan)r"   r$   r$   r%   rg   `  s    zScanDevice.cancelScanc          
   C   s>   | j  s:| j}|j|j|j|j|j|j|j|j	|j
|jf
S dS )z6Get the output buffer and info about a completed scan.N)rW   rC   bufferrY   rZ   r\   r]   r^   r_   	pad_bytes
total_readtotal_write)r"   r1   r$   r$   r%   getScane  s    zScanDevice.getScanc             C   sF   | j  sB| j}y|jj  tj|j W n ttfk
r@   Y nX dS )z-Cleanup the scan file after a completed scan.N)	rW   rC   rh   closeosremovebuffer_pathIOErrorrS   )r"   r1   r$   r$   r%   freeScann  s    
zScanDevice.freeScanc             C   s$   | j d k	r| j j o| j jS dS d S )NF)rC   isAlivera   )r"   r$   r$   r%   rW   z  s    
zScanDevice.isScanActivec             C   sD   | j d k	r@| j j r@| j jr@y| j j  W n tk
r>   Y nX d S )N)rC   rs   ra   r9   KeyboardInterrupt)r"   r$   r$   r%   waitForScanDone  s    

zScanDevice.waitForScanDonec             C   s4   | j d k	r0x$| j j r"| j jr"d S tjd qW d S )Ng?)rC   rs   ra   timesleep)r"   r$   r$   r%   waitForScanActive  s    

zScanDevice.waitForScanActivec             C   s   | j j  dS )z#Close the SANE device after a scan.N)rE   	closeScan)r"   r$   r$   r%   ry     s    zScanDevice.closeScan)rV   NN)r>   r?   r@   rA   r&   rG   r5   r.   rT   rU   rH   rX   rg   rl   rr   rW   ru   rx   ry   r$   r$   r$   r%   rB      s    !
	rB   c               @   s.   e Zd ZdddZdd Zdd Zd	d
 ZdS )r`   rV   Nc             C   s   t jj|  d| _|| _|| _|| _tjdd\| _	| _
tj| j	d| _d| _d| _d	| _d
| _d| _d| _d| _d| _d| _|| _d| _d S )NTZhpscan)prefixzw+br   r   r   r{   r{   r{   r{   r{   r{   )	threadingThreadr&   ra   rE   rd   re   r   Zmake_temp_fileZ	buffer_fdrp   rn   fdopenrh   rY   rZ   r[   r\   r]   r^   r_   ri   rj   rc   rk   )r"   Zdevicerc   rd   re   r$   r$   r%   r&     s$    zScanThread.__init__c             C   sH   | j d k	rDyt|}W n ttfk
r2   d}Y nX | j j||f d S )Nr   r{   )rd   rM   
ValueError	TypeErrorZput)r"   rf   Z
bytes_readr$   r$   r%   updateQueue  s    

zScanThread.updateQueuec                s  ddl m} | jj \| _| _| _| _| _| _	| _
tjd| j  tjd| j  tjd| j  tjd| j  tjd| j  tjd| j	  tjd	| j
  tjd
| j  | jj}| j
}| jtjkrl| j	dkrv| j
d| j  | _tjd| j  d | jdkrd y| jj|\}W n< tjk
r` } z|jd }| j|d W Y d d }~X nX x|tjkrfrt}|dj fddtd|| j dD  |  j|7  _|  j||| j d  7  _| j|| j tjd| j  n
tjd y| jj|\}W n@ tjk
rT } z |jd }| j|| j P W Y d d }~X nX | j rfP qfW n
| jtj krv| j	dkr| j
| jd d  | _tjd| j  y| jj|\}W n< tjk
r } z|jd }| j|d W Y d d }~X nX x|tjkrrt}|djfddtd|| j D  |  j|7  _|  j|| j d 7  _| j|| j tjd| j  n
tjd y| jj|\}W n@ tjk
r } z |jd }| j|| j P W Y d d }~X nX | j r P q W nx| j	dkrv| j
| j | _tjd| j  y| jj|\}W n< tjk
rx } z|jd }| j|d W Y d d }~X nX x|tjkrtrt}|djfddtd|| j D  |  j|7  _|  j|| j d 7  _| j|| j tjd| j  n
tjd y| jj|\}W n@ tjk
rb } z |jd }| j|| j P W Y d d }~X nX | j r|P q|W | jj!d d| _"tjd d S )Nr   )r   z	format=%dzformat_name=%szlast_frame=%dzppl=%dzlines=%dzdepth=%dzbpl=%dzbyte_format=%s      zpad_bytes=%dr   ZRGBA    c                s"   g | ]}||d    d qS )r      r$   ).0r   )dirrJ   r$   r%   
<listcomp>  s    z"ScanThread.run.<locals>.<listcomp>zColor Read %d bytesg?   c                s&   g | ] d j  fdddD qS )r   c                s,   g | ]$}|t   d   @ r$dndqS )r   s      s   )ord)r   k)r   rJ   r$   r%   r     s    z-ScanThread.run.<locals>.<listcomp>.<listcomp>   @          r         r   )r   r   r   r   r   r   r   r   )r9   )r   )rJ   )r   r%   r     s    r   zLineart Read %d bytesc                s$   g | ]}d  ||d   d qS )r   r   r   r$   )r   r   )rJ   r$   r%   r   *  s    r   zGray Read %d bytesFzScan thread exiting...r{   )#base.sixextr   rE   rU   rY   rZ   r[   r\   r]   r^   r_   r3   debugrc   rh   writer'   Z	FRAME_RGBri   ZreadScanrL   r#   r   ZSANE_STATUS_GOODlenr9   rangerj   rk   rv   rw   checkCancelZ
FRAME_GRAYseekra   )r"   r   wZ
readbufferstZstObjZlen_tr$   )r   rJ   r%   run  s    &
,



(



(


zScanThread.runc             C   sb   d}xX| j j r\y0| j jd}|tkr>d}tjd | jj  W q tj	k
rX   P Y qX qW |S )NFr   TzCancel pressed!)
re   ZqsizegetEVENT_SCAN_CANCELEDr3   r   rE   Z	canclScanr   ZEmpty)r"   ZcanceledZeventr$   r$   r%   r   C  s    
zScanThread.checkCancel)rV   NN)r>   r?   r@   r&   r   r   r   r$   r$   r$   r%   r`     s   
~r`   c               C   s   t j S )N)r'   initr$   r$   r$   r%   r   U  s    r   c               C   s   t j S )N)r'   deInitr$   r$   r$   r%   r   Y  s    r   c             C   s   t | S )zOpen a device for scanning)rB   )rE   r$   r$   r%   rD   ]  s    rD   c             C   s
   t j| S )N)r'   
getDevices)Z
local_onlyr$   r$   r%   r   b  s    r   c             C   s   t jdtj| | f  d S )NzSANE: %s (code=%d))r3   rL   r'   ZgetErrorMessage)coder$   r$   r%   reportErrorf  s    r   )r   )%r'   r|   rv   rn   Zbase.gbaser   r   r   Zbase.sixext.movesr   r   r   r   r	   r
   r   r   r/   r   r   r   r   r   r   r   r0   ZMAX_READSIZEr   rB   r}   r`   r   r   rD   r   r   r$   r$   r$   r%   <module>9   s:   
} S 2
