#!/usr/bin/env python
 
 
 
"""
 
Provides an interface to USB Printer Class devices.
Fournit une interface par une classe pour les appareils imprimante USB.
 
"""
 
 
 
import usb
 
import types
 
 
 
PRINTER_CLASS			= 0x07
 
PRINTER_SUBCLASS		= 0x01
 
UNIDIRECTIONAL_PROTOCOL	= 0x01
 
BIDIRECTIONAL_PROTOCOL	= 0x02
 
IEEE1284_4_PROTOCOL		= 0x03
 
VENDOR_PROTOCOL			= 0xff
 
 
 
class Printer:
 
	def __init__(self, device, configuration, interface):
 
		"""
 
                __init__(device, configuration, interface) -> None
 
 
 
                Initialize the device.
 
                        device: printer usb.Device object.
 
                        configuration: printer usb.Configuration object of the Device or configuration number.
 
                        interface: printer usb.Interface object representing the
 
                                   interface and altenate setting.
 
                        
 
                """
 
		if PRINTER_CLASS != interface.interfaceClass:
 
			raise TypeError, "Wrong interface class"
 
 
 
		self.__devhandle = device.open()
 
		self.__devhandle.setConfiguration(configuration)
 
		self.__devhandle.claimInterface(interface)
 
		self.__devhandle.setAltInterface(interface)
 
 
 
		self.__intf = interface.interfaceNumber
 
		self.__alt	= interface.alternateSetting
 
 
 
		self.__conf = (type(configuration) == types.IntType \
 
						or type(configuration) == types.LongType) and \
 
						configuration or \
 
						configuration.value
 
 
 
		# initialize members
 
		# TODO: automatic endpoints detection
 
		self.__bulkout	= 1
 
		self.__bulkin	= 0x82
 
 
 
	def __del__(self):
 
		try:
 
			self.__devhandle.releaseInterface(self.__intf)
 
			del self.__devhandle
 
		except:
 
			pass
 
 
 
	def getDeviceID(self, maxlen, timeout = 100):
 
		"""
 
                getDeviceID(maxlen, timeout = 100) -> device_id
 
 
 
                Get the device capabilities information.
 
                        maxlen: maxlength of the buffer.
 
                        timeout: operation timeout.
 
                """
 
		return self.__devhandle.controlMsg(requestType = 0xa1,
 
										   request = 0,
 
										   value = self.__conf - 1,
 
										   index = self.__alt + (self.__intf << 8),
 
										   buffer = maxlen,
 
										   timeout = timeout)
 
 
 
	def getPortStatus(self, timeout = 100):
 
		"""
 
                getPortStatus(timeout = 100) -> status
 
 
 
                Get the port status.
 
                        timeout: operation timeout.
 
                """
 
		return self.__devhandle.controlMsg(requestType = 0xa1,
 
										   request = 1,
 
										   value = 0,
 
										   index = self.__intf,
 
										   buffer = 1,
 
										   timeout = timeout)[0]
 
 
 
	def softReset(self, timeout = 100):
 
		"""
 
                softReset(timeout = 100) -> None
 
 
 
                Request flushes all buffers and resets the Bulk OUT
 
                and Bulk IN pipes to their default states.
 
                        timeout: the operation timeout.
 
                """
 
		self.__devhandle.controlMsg(requestType = 0x21,
 
								   	request = 2,
 
								   	value = 0,
 
								   	index = self.__intf,
 
								   	buffer = 0)
 
 
 
 
 
	def write(self, buffer, timeout = 100):
 
		"""
 
                write(buffer, timeout = 100) -> written
 
 
 
                Write data to printer.
 
                        buffer: data buffer.
 
                        timeout: operation timeout.
 
                """
 
		return self.__devhandle.bulkWrite(self.__bulkout,
 
										  buffer,
 
										  timeout)
 
 
 
	def read(self, numbytes, timeout = 100):
 
		"""
 
                read(numbytes, timeout = 100) -> data
 
 
 
                Read data from printer.
 
                        numbytes: number of bytes to read.
 
                        timeout: operation timeout.
 
                """
 
		return self.__devhandle.bulkRead(self.__bulkin,
 
										 numbytes,
 
										 timeout)
