1
# -*- coding: utf-8 -*-
3
# (c) Copyright 2003-2006 Hewlett-Packard Development Company, L.P.
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
from __future__ import generators
25
import sys, os, os.path, mmap, struct, time, threading, Queue, socket
26
from cStringIO import StringIO
30
from base.codes import *
31
from base import device, utils, status, pml, msg
33
# Event queue values (UI ==> Copy thread)
36
# Update queue values (Copy thread ==> UI)
46
class PMLCopyDevice(device.Device):
47
def __init__(self, device_uri=None, printer_name=None,
48
hpssd_sock=None, hpiod_sock=None, callback=None):
50
device.Device.__init__(self, device_uri, printer_name,
51
hpssd_sock, hpiod_sock, callback)
53
self.copy_thread = None
55
def copy(self, num_copies=1, contrast=0, reduction=100,
56
quality=pml.COPIER_QUALITY_NORMAL,
57
fit_to_page=pml.COPIER_FIT_TO_PAGE_ENABLED,
58
update_queue=None, event_queue=None):
60
if not self.isCopyActive():
61
self.copy_thread = PMLCopyThread(self, num_copies, contrast, reduction, quality,
62
fit_to_page, update_queue, event_queue)
63
self.copy_thread.start()
68
def isCopyActive(self):
69
if self.copy_thread is not None:
70
return self.copy_thread.isAlive()
74
def waitForCopyThread(self):
75
if self.copy_thread is not None and \
76
self.copy_thread.isAlive():
78
self.copy_thread.join()
82
class PMLCopyThread(threading.Thread):
83
def __init__(self, dev, num_copies, contrast, reduction, quality,
84
fit_to_page, update_queue=None, event_queue=None):
86
threading.Thread.__init__(self)
88
self.num_copies = num_copies
89
self.contrast = contrast
90
self.reduction = reduction
91
self.quality = quality
92
self.fit_to_page = fit_to_page
93
self.event_queue = event_queue
94
self.update_queue = update_queue
104
STATE_SETUP_STATE = 40
105
STATE_SETUP_PARAMS = 50
108
STATE_RESET_TOKEN = 80
110
state = STATE_SET_TOKEN
112
while state != STATE_DONE: # ------------------------- Copier Thread
113
if self.check_for_cancel():
114
state = STATE_ABORTED
116
if state == STATE_ABORTED:
117
log.debug("%s State: Aborted" % ("*"*20))
118
self.write_queue(STATUS_ERROR)
119
state = STATE_RESET_TOKEN
121
if state == STATE_ERROR:
122
log.debug("%s State: Error" % ("*"*20))
123
self.write_queue(STATUS_ERROR)
124
state = STATE_RESET_TOKEN
126
elif state == STATE_SUCCESS:
127
log.debug("%s State: Success" % ("*"*20))
128
self.write_queue(STATUS_DONE)
129
state = STATE_RESET_TOKEN
131
elif state == STATE_BUSY:
132
log.debug("%s State: Busy" % ("*"*20))
133
self.write_queue(STATUS_ERROR)
134
state = STATE_RESET_TOKEN
136
elif state == STATE_SET_TOKEN:
137
log.debug("%s State: Acquire copy token" % ("*"*20))
139
self.write_queue(STATUS_SETTING_UP)
142
result_code, token = self.dev.getPML(pml.OID_COPIER_TOKEN)
144
log.debug("Unable to acquire copy token (1).")
147
if result_code > pml.ERROR_MAX_OK:
148
state = STATE_SETUP_STATE
149
log.debug("Skipping token acquisition.")
151
token = time.strftime("%d%m%Y%H:%M:%S", time.gmtime())
152
log.debug("Setting token: %s" % token)
154
self.dev.setPML(pml.OID_COPIER_TOKEN, token)
156
log.error("Unable to acquire copy token (2).")
159
result_code, check_token = self.dev.getPML(pml.OID_COPIER_TOKEN)
161
if check_token == token:
162
state = STATE_SETUP_STATE
164
log.error("Unable to acquire copy token (3).")
167
elif state == STATE_SETUP_STATE:
168
log.debug("%s State: Setup state" % ("*"*20))
170
result_code, copy_state = self.dev.getPML(pml.OID_COPIER_JOB)
172
if copy_state == pml.COPIER_JOB_IDLE:
173
self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_SETUP)
174
state = STATE_SETUP_PARAMS
180
elif state == STATE_SETUP_PARAMS:
181
log.debug("%s State: Setup Params" % ("*"*20))
184
if self.num_copies < 0: self.num_copies = 1
185
if self.num_copies > 99: self.num_copies = 99
187
self.dev.setPML(pml.OID_COPIER_JOB_NUM_COPIES, self.num_copies)
190
self.dev.setPML(pml.OID_COPIER_JOB_CONTRAST, self.contrast)
193
self.dev.setPML(pml.OID_COPIER_JOB_REDUCTION, self.reduction)
196
self.dev.setPML(pml.OID_COPIER_JOB_QUALITY, self.quality)
199
self.dev.setPML(pml.OID_COPIER_JOB_FIT_TO_PAGE, self.fit_to_page)
201
log.debug("num_copies = %d" % self.num_copies)
202
log.debug("contrast= %d" % self.contrast)
203
log.debug("reduction = %d" % self.reduction)
204
log.debug("quality = %d" % self.quality)
205
log.debug("fit_to_page = %d" % self.fit_to_page)
206
#log.debug("max_reduction = %d" % self.max_reduction)
207
#log.debug("max_enlargement = %d" % self.max_enlargement)
211
elif state == STATE_START:
212
log.debug("%s State: Start" % ("*"*20))
214
self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_START)
217
elif state == STATE_ACTIVE:
218
log.debug("%s State: Active" % ("*"*20))
221
result_code, copy_state = self.dev.getPML(pml.OID_COPIER_JOB)
223
if self.check_for_cancel():
224
self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_IDLE) # cancel
225
state = STATE_ABORTED
228
if copy_state == pml.COPIER_JOB_START:
229
log.debug("state = start")
233
if copy_state == pml.COPIER_JOB_ACTIVE:
234
self.write_queue(STATUS_ACTIVE)
235
log.debug("state = active")
239
elif copy_state == pml.COPIER_JOB_ABORTING:
240
log.debug("state = aborting")
241
state = STATE_ABORTED
244
elif copy_state == pml.COPIER_JOB_IDLE:
245
log.debug("state = idle")
246
state = STATE_SUCCESS
249
elif state == STATE_RESET_TOKEN:
250
log.debug("%s State: Release copy token" % ("*"*20))
253
self.dev.setPML(pml.OID_COPIER_TOKEN, '\x00'*16)
255
log.error("Unable to release copier token.")
260
def check_for_cancel(self):
262
while self.event_queue.qsize():
264
event = self.event_queue.get(0)
265
if event == COPY_CANCELED:
267
log.debug("Cancel pressed!")
273
def write_queue(self, message):
274
if self.update_queue is not None and message != self.prev_update:
275
self.update_queue.put(message)
277
self.prev_update = message