1# -*- coding: utf-8 -*-
2#
3# (c) Copyright 2003-2015 HP Development Company, L.P.
4#
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.
9#
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.
14#
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
18#
19# Author: Don Welch
20#
21
22
23# Std Lib
24import struct
25import sys
26
27
28PACKET_FRAME = ord('$')
29PACKET_PAD = 0xff
30CMD_HEADER_FMT = ">BHBBBHH" # 10 bytes
31
32# Packet types
33PACKET_TYPE_COMMAND = 0
34PACKET_TYPE_DISABLE_PACING = 1
35PACKET_TYPE_ENABLE_PACING = 2
36PACKET_TYPE_RESUME_NORMAL_OPERATION = 3
37PACKET_TYPE_DISABLE_RESPONSES = 4
38PACKET_TYPE_ENABLE_RESPONSES = 5
39PACKET_TYPE_RESET_LIDIL = 6
40PACKET_TYPE_SYNC = 7
41PACKET_TYPE_SYNC_COMPLETE = 8
42
43# Commands
44
45# Handle Pen
46COMMAND_HANDLE_PEN = 8
47COMMAND_HANDLE_PEN_ENTER_PEN_CHANGE = 0
48COMMAND_HANDLE_PEN_COMPLETE_PEN_CHANGE = 1
49COMMAND_HANDLE_PEN_CLEAN_LEVEL1 = 2
50COMMAND_HANDLE_PEN_CLEAN_LEVEL2 = 3
51COMMAND_HANDLE_PEN_CLEAN_LEVEL3 = 4
52
53# Set ZCA
54COMMAND_ZCA = 12
55COMMAND_ZCA_OPERATION = 11
56
57# 0.3.8 Set Printer Alignment
58COMMAND_SET_PRINTER_ALIGNMENT = 12
59COMMAND_SET_PRINTER_ALIGNMENT_OPERATION = 6
60
61# 0.4.3 Set Pen Alignment
62COMMAND_SET_PEN_ALIGNMENT = 12
63COMMAND_SET_PEN_ALIGNMENT_OPERATION = 18
64COMMAND_SET_PEN_ALIGNMENT_PEN_BLACK = 0
65COMMAND_SET_PEN_ALIGNMENT_PEN_COLOR = 1
66COMMAND_SET_PEN_ALIGNMENT_PEN_PHOTO = 2
67COMMAND_SET_PEN_ALIGNMENT_ITEM_HORT = 0
68COMMAND_SET_PEN_ALIGNMENT_ITEM_VERT = 1
69COMMAND_SET_PEN_ALIGNMENT_ITEM_BIDI = 2
70
71# Set Pens Aligned
72COMMAND_SET_PENS_ALIGNED = 12
73COMMAND_SET_PENS_ALIGNED_OPERATION = 14
74COMMAND_SET_PENS_ALIGNED_K = 0x01
75COMMAND_SET_PENS_ALIGNED_C = 0x02
76COMMAND_SET_PENS_ALIGNED_M = 0x04
77COMMAND_SET_PENS_ALIGNED_Y = 0x08
78COMMAND_SET_PENS_ALIGNED_c = 0x10
79COMMAND_SET_PENS_ALIGNED_m = 0x20
80COMMAND_SET_PENS_ALIGNED_k = 0x40
81
82# Set Hue Compensation
83COMMAND_SET_HUE_COMPENSATION = 12
84COMMAND_SET_HUE_COMPENSATION_OPERATION = 16
85COMMAND_SET_HUE_COMPENSATION_PEN_COLOR = 0
86COMMAND_SET_HUE_COMPENSATION_PEN_PHOTO = 1
87
88# Print internal page 0.3.8 and 0.4.3
89COMMAND_PRINT_INTERNAL_PAGE = 12
90COMMAND_PRINT_INTERNAL_PAGE_OPERATION = 17
91
92# 0.5.4 Report Page
93COMMAND_REPORT_PAGE = 12
94COMMAND_REPORT_PAGE_OPERATION = 21
95COMMAND_REPORT_PAGE_PEN_CALIBRATION = 81
96COMMAND_REPORT_PAGE_PEN_CALIBRATION_VERIFY = 82
97
98# 0.5.4 Set Pen Alignment 3
99COMMAND_SET_PEN_ALIGNMENT_3 = 12
100COMMAND_SET_PEN_ALIGNMENT_3_OPERATION = 23
101COMMAND_SET_PEN_ALIGNMENT_3_K = 0x01
102COMMAND_SET_PEN_ALIGNMENT_3_C = 0x02
103COMMAND_SET_PEN_ALIGNMENT_3_M = 0x04
104COMMAND_SET_PEN_ALIGNMENT_3_Y = 0x08
105COMMAND_SET_PEN_ALIGNMENT_3_COLOR = 0x0e
106COMMAND_SET_PEN_ALIGNMENT_3_c = 0x10
107COMMAND_SET_PEN_ALIGNMENT_3_m = 0x20
108COMMAND_SET_PEN_ALIGNMENT_3_k = 0x40
109COMMAND_SET_PEN_ALIGNMENT_3_PHOTO = 0x70
110
111# Printer queries
112COMMAND_QUERY = 5
113QUERY_PRINTER_ALIGNMENT = 3 # 0.3.8
114QUERY_PEN_ALIGNMENT = 15 # 0.4.3
115
116# 0.5.4 Dynamic counters
117COMMAND_DYNAMIC_COUNTERS = 12
118COMMAND_DYNAMIC_COUNTERS_OPERATION = 5
119
120
121def buildLIDILPacket(packet_type, command=0, operation=0, other={}):
122    p = ''
123
124    if packet_type == PACKET_TYPE_DISABLE_PACING:
125        p = '$\x00\x10\x00\x01\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$'
126
127    elif packet_type == PACKET_TYPE_ENABLE_PACING:
128        p = '$\x00\x10\x00\x02\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$'
129
130    elif packet_type == PACKET_TYPE_RESUME_NORMAL_OPERATION:
131        p = '$\x00\x10\x00\x03\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$'
132
133    elif packet_type == PACKET_TYPE_ENABLE_RESPONSES:
134        p = '$\x00\x10\x00\x05\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$'
135
136    elif packet_type == PACKET_TYPE_DISABLE_RESPONSES:
137        p = '$\x00\x10\x00\x04\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$'
138
139    elif packet_type == PACKET_TYPE_SYNC:
140        fmt = ''.join([CMD_HEADER_FMT, 'B'*245, 'B', 'B'*2048])
141        p = struct.pack(fmt, PACKET_FRAME, 256, 0, PACKET_TYPE_SYNC, 0, 0, 2048, (0,)*245,
142                         PACKET_FRAME, (0,)*2048)
143
144    elif packet_type == PACKET_TYPE_SYNC_COMPLETE:
145        p = '$\x00\x10\x00\x08\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$'
146
147    elif packet_type == PACKET_TYPE_RESET_LIDIL:
148        p = '$\x00\x10\x00\x06\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$'
149
150    elif packet_type == PACKET_TYPE_COMMAND:
151
152        if command == COMMAND_HANDLE_PEN:
153            fmt = CMD_HEADER_FMT + "BBBBBB"
154            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
155                             0, 0, operation, PACKET_PAD, PACKET_PAD,  PACKET_PAD, PACKET_PAD, PACKET_FRAME)
156
157        elif command == COMMAND_SET_PRINTER_ALIGNMENT and operation == COMMAND_SET_PRINTER_ALIGNMENT_OPERATION: # 0.3.8
158            fmt = CMD_HEADER_FMT + "BHBBBBBBBBBBBBB"
159            b = (0, 0, other['k_bidi'], other['c_vert'], other['c_hort'], other['c_bidi'],
160                        other['c_vert'], other['c_hort'], other['c_bidi'], other['c_vert'],
161                        other['c_hort'], other['c_bidi'], PACKET_FRAME)
162
163            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
164                             0, 0, operation, 0x0f, *b)
165
166        elif command == COMMAND_SET_PEN_ALIGNMENT and operation == COMMAND_SET_PEN_ALIGNMENT_OPERATION: # 0.4.3
167            fmt = CMD_HEADER_FMT + "BBBbBB"
168            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
169                             0, 0, operation, other['pen'], other['item'], other['value'],
170                             PACKET_PAD, PACKET_FRAME)
171
172        elif command == COMMAND_REPORT_PAGE and operation == COMMAND_REPORT_PAGE_OPERATION: # 0.5.4
173            fmt = CMD_HEADER_FMT + "BHBBB"
174            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
175                            0, 0, operation, other['report'], PACKET_PAD, PACKET_PAD, PACKET_FRAME)
176
177        elif command == COMMAND_ZCA and operation == COMMAND_ZCA_OPERATION:
178            fmt = CMD_HEADER_FMT + "BBhBB"
179            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
180                             0, 0, operation, 0, other['zca'], PACKET_PAD, PACKET_FRAME)
181
182        elif command == COMMAND_SET_PENS_ALIGNED and operation == COMMAND_SET_PENS_ALIGNED_OPERATION:
183            fmt = CMD_HEADER_FMT + "BHBBB"
184            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
185                             0, 0, operation, other['colors'], PACKET_PAD, PACKET_PAD, PACKET_FRAME)
186
187        elif command == COMMAND_SET_HUE_COMPENSATION and operation == COMMAND_SET_HUE_COMPENSATION_OPERATION:
188            fmt = CMD_HEADER_FMT + "BBbBBB"
189            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
190                             0, 0, operation, other['which'], other['value'], PACKET_PAD,
191                             PACKET_PAD, PACKET_FRAME)
192
193        elif command == COMMAND_QUERY:
194            fmt = CMD_HEADER_FMT + "BBHBB"
195            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, COMMAND_QUERY,
196                             0, 0, 0, operation, 0, PACKET_PAD, PACKET_FRAME)
197
198        elif command == COMMAND_PRINT_INTERNAL_PAGE and operation == COMMAND_PRINT_INTERNAL_PAGE_OPERATION:
199            fmt = CMD_HEADER_FMT + "BBBBBB"
200            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
201                             0, 0, operation, PACKET_PAD, PACKET_PAD,
202                             PACKET_PAD, PACKET_PAD, PACKET_FRAME)
203
204        elif command == COMMAND_SET_PEN_ALIGNMENT_3 and operation == COMMAND_SET_PEN_ALIGNMENT_3_OPERATION: # 0.5.4
205            selections = other['selections']
206            num_selections = len(selections)
207            selections.append(PACKET_FRAME)
208            fmt = CMD_HEADER_FMT + "BIB" + "B"*(num_selections+1)
209
210            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
211                            0, 0, operation, other['active_colors'],
212                            num_selections, *selections)
213
214        elif command == COMMAND_DYNAMIC_COUNTERS and operation == COMMAND_DYNAMIC_COUNTERS_OPERATION: # 0.5.4
215            fmt = CMD_HEADER_FMT + "BIB"
216
217            p = struct.pack(fmt, PACKET_FRAME, struct.calcsize(fmt), 0, PACKET_TYPE_COMMAND, command,
218                            0, 0, operation, other['counter'], PACKET_FRAME)
219
220
221    assert len(p) >= 16
222
223    return p
224
225
226
227def buildSyncPacket():
228    return buildLIDILPacket(PACKET_TYPE_SYNC)
229
230def buildSyncCompletePacket():
231    return buildLIDILPacket(PACKET_TYPE_SYNC_COMPLETE)
232
233def buildResetPacket():
234    return buildLIDILPacket(PACKET_TYPE_RESET_LIDIL)
235
236def buildGetAlignmentValues038Packet():
237    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_QUERY, QUERY_PRINTER_ALIGNMENT)
238
239def buildGetAlignmentValues043Packet():
240    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_QUERY, QUERY_PEN_ALIGNMENT)
241
242def buildEnableResponsesPacket(enable=True):
243    if enable:
244        return buildLIDILPacket(PACKET_TYPE_ENABLE_RESPONSES)
245    else:
246        return buildLIDILPacket(PACKET_TYPE_DISABLE_RESPONSES)
247
248def buildSetPrinterAlignmentPacket(k_bidi,
249                                    c_vert,
250                                    c_hort,
251                                    c_bidi): # 0.3.8
252
253    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PRINTER_ALIGNMENT,
254                             COMMAND_SET_PRINTER_ALIGNMENT_OPERATION,
255                             other={'c_vert' : c_vert,
256                                     'c_hort' : c_hort,
257                                     'c_bidi' : c_bidi,
258                                     'k_bidi' : k_bidi,
259
260                                    })
261
262def buildPrintInternalPagePacket(): # Type 6
263    return buildLIDILPacket(PACKET_TYPE_COMMAND,
264                             COMMAND_PRINT_INTERNAL_PAGE,
265                             COMMAND_PRINT_INTERNAL_PAGE_OPERATION)
266
267
268def buildZCAPacket(value):
269    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_ZCA,
270                             COMMAND_ZCA_OPERATION,
271                             other={'zca' : value})
272
273def buildBlackBidiPacket(value): # 0.4.3
274    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
275                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
276                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_BLACK,
277                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_BIDI,
278                                     'value' : value})
279
280def buildPhotoBidiPacket(value): # 0.4.3
281    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
282                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
283                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_PHOTO,
284                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_BIDI,
285                                     'value' : value})
286
287def buildColorBidiPacket(value): # 0.4.3
288    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
289                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
290                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_COLOR,
291                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_BIDI,
292                                     'value' : value})
293
294
295def buildColorHortPacket(value): # 0.4.3
296    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
297                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
298                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_COLOR,
299                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_HORT,
300                                     'value' :  value})
301
302def buildColorVertPacket(value): # 0.4.3
303    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
304                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
305                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_COLOR,
306                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_VERT,
307                                     'value' :  value})
308
309def buildBlackVertPacket(value): # 0.4.3
310    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
311                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
312                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_BLACK,
313                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_VERT,
314                                     'value' :  value})
315def buildBlackHortPacket(value): # 0.4.3
316    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
317                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
318                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_BLACK,
319                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_HORT,
320                                     'value' :  value})
321
322def buildPhotoHortPacket(value): # 0.4.3
323    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
324                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
325                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_PHOTO,
326                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_HORT,
327                                     'value' :  value})
328def buildPhotoVertPacket(value): # 0.4.3
329    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT,
330                             COMMAND_SET_PEN_ALIGNMENT_OPERATION,
331                             other={'pen' : COMMAND_SET_PEN_ALIGNMENT_PEN_PHOTO,
332                                     'item' : COMMAND_SET_PEN_ALIGNMENT_ITEM_VERT,
333                                     'value' :  value})
334
335def buildPhotoHuePacket(value): # 0.4.3
336    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_HUE_COMPENSATION,
337                             COMMAND_SET_HUE_COMPENSATION_OPERATION,
338                             other={'which' : COMMAND_SET_HUE_COMPENSATION_PEN_PHOTO,
339                                     'value' :  value})
340
341
342def buildColorHuePacket(value): # 0.4.3
343   return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_HUE_COMPENSATION,
344                            COMMAND_SET_HUE_COMPENSATION_OPERATION,
345                            other={'which' : COMMAND_SET_HUE_COMPENSATION_PEN_COLOR,
346                                    'value' :  value})
347
348def buildSetPensAlignedPacket():
349    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PENS_ALIGNED,
350                              COMMAND_SET_PENS_ALIGNED_OPERATION,
351                              other={'colors' : COMMAND_SET_PENS_ALIGNED_C |
352                                                 COMMAND_SET_PENS_ALIGNED_M |
353                                                 COMMAND_SET_PENS_ALIGNED_Y |
354                                                 COMMAND_SET_PENS_ALIGNED_c |
355                                                 COMMAND_SET_PENS_ALIGNED_m |
356                                                 COMMAND_SET_PENS_ALIGNED_k |
357                                                 COMMAND_SET_PENS_ALIGNED_K})
358
359def buildReportPagePacket(report): # 0.5.4
360    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_REPORT_PAGE,
361                            COMMAND_REPORT_PAGE_OPERATION,
362                            other={'report': report})
363
364def buildSetPenAlignment3Packet(active_colors, selections): # 0.5.4
365    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_SET_PEN_ALIGNMENT_3,
366                            COMMAND_SET_PEN_ALIGNMENT_3_OPERATION,
367                            other={'active_colors': active_colors,
368                                   'selections': selections,})
369
370def buildDynamicCountersPacket(counter): # 0.5.4
371    return buildLIDILPacket(PACKET_TYPE_COMMAND, COMMAND_DYNAMIC_COUNTERS,
372                            COMMAND_DYNAMIC_COUNTERS_OPERATION,
373                            other={'counter': counter,})
374
375if __name__ == "__main__":
376
377    pass
378
379
380