summaryrefslogtreecommitdiff
path: root/src/cups
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2017-06-19 08:38:07 +0200
committerDidier Raboud <odyx@debian.org>2017-06-19 08:38:07 +0200
commitaedf3e93e811c6c9d504274172861d266e1c5c97 (patch)
tree95e525108c5b6bd2ea3fa689cf11bfe4a5b982a9 /src/cups
parent7bd83d89975d166521a0b326b64b4cad80117750 (diff)
New upstream version 5.2.13~pre1
Diffstat (limited to 'src/cups')
-rw-r--r--src/cups/Makefile.in7
-rw-r--r--src/cups/backend_canonselphy.c81
-rw-r--r--src/cups/backend_canonselphyneo.c38
-rw-r--r--src/cups/backend_citizencw01.c4
-rw-r--r--src/cups/backend_common.c27
-rw-r--r--src/cups/backend_common.h5
-rw-r--r--src/cups/backend_dnpds40.c4
-rw-r--r--src/cups/backend_kodak1400.c4
-rw-r--r--src/cups/backend_kodak605.c4
-rw-r--r--src/cups/backend_kodak6800.c22
-rw-r--r--src/cups/backend_mitsu70x.c268
-rw-r--r--src/cups/backend_mitsu9550.c2
-rw-r--r--src/cups/backend_mitsup95d.c272
-rw-r--r--src/cups/backend_shinkos1245.c35
-rw-r--r--src/cups/backend_shinkos2145.c6
-rw-r--r--src/cups/backend_shinkos6145.c31
-rw-r--r--src/cups/backend_shinkos6245.c8
-rw-r--r--src/cups/backend_sonyupdr150.c2
-rw-r--r--src/cups/blacklist6
-rw-r--r--src/cups/cups-calibrate.c2
-rw-r--r--src/cups/genppd.c1
-rw-r--r--src/cups/rastertoprinter.c5
-rwxr-xr-xsrc/cups/test-ppds18
-rwxr-xr-xsrc/cups/test-rastertogutenprint.in20
24 files changed, 612 insertions, 260 deletions
diff --git a/src/cups/Makefile.in b/src/cups/Makefile.in
index cf76ab2..27bcc47 100644
--- a/src/cups/Makefile.in
+++ b/src/cups/Makefile.in
@@ -492,9 +492,11 @@ BZIP2 = @BZIP2@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+COMPRESS = @COMPRESS@
CONVERT = @CONVERT@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CSUF = @CSUF@
CUPS_CFLAGS = @CUPS_CFLAGS@
CUPS_CONFIG = @CUPS_CONFIG@
CUPS_LIBS = @CUPS_LIBS@
@@ -553,6 +555,7 @@ GUTENPRINT_MICRO_VERSION = @GUTENPRINT_MICRO_VERSION@
GUTENPRINT_MINOR_VERSION = @GUTENPRINT_MINOR_VERSION@
GUTENPRINT_RELEASE_VERSION = @GUTENPRINT_RELEASE_VERSION@
GUTENPRINT_VERSION = @GUTENPRINT_VERSION@
+GZIP = @GZIP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -578,6 +581,7 @@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_LIBS = @LIBUSB_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
+LRZIP = @LRZIP@
LTALLOCA = @LTALLOCA@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
@@ -605,6 +609,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
+PKGROOT = @PKGROOT@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
@@ -613,6 +618,7 @@ POSUB = @POSUB@
RANLIB = @RANLIB@
RELEASE_DATE = @RELEASE_DATE@
RM = @RM@
+RZIP = @RZIP@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -625,6 +631,7 @@ VERSION = @VERSION@
WHICH_PPDS = @WHICH_PPDS@
XGETTEXT = @XGETTEXT@
XGETTEXT_015 = @XGETTEXT_015@
+XZ = @XZ@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
diff --git a/src/cups/backend_canonselphy.c b/src/cups/backend_canonselphy.c
index 4d7e6d0..501cb0a 100644
--- a/src/cups/backend_canonselphy.c
+++ b/src/cups/backend_canonselphy.c
@@ -369,11 +369,11 @@ static struct printer_data selphy_printers[] = {
.model = "SELPHY CP Series (!CP-10/CP790)",
.init_length = 12,
.foot_length = 0, /* CP900 has four-byte NULL footer that can be safely ignored */
- .init_readback = { 0x01, 0x00, 0x00, 0x00, -1, 0x00, -1, 0x00, 0x00, 0x00, 0x00, -1 },
- .ready_y_readback = { 0x02, 0x00, 0x00, 0x00, 0x70, 0x00, -1, 0x00, 0x00, 0x00, 0x00, -1 },
- .ready_m_readback = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, -1 },
- .ready_c_readback = { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, -1 },
- .done_c_readback = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, -1 },
+ .init_readback = { 0x01, 0x00, 0x00, 0x00, -1, 0x00, -1, -1, 0x00, 0x00, 0x00, -1 },
+ .ready_y_readback = { 0x02, 0x00, 0x00, 0x00, 0x70, 0x00, -1, -1, 0x00, 0x00, 0x00, -1 },
+ .ready_m_readback = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -1, -1, 0x00, 0x00, 0x00, -1 },
+ .ready_c_readback = { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -1, -1, 0x00, 0x00, 0x00, -1 },
+ .done_c_readback = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, -1, -1, 0x00, 0x00, 0x00, -1 },
.clear_error = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.clear_error_len = 12,
.pgcode_offset = 3,
@@ -535,7 +535,7 @@ done:
return printer_type;
}
-/* Private data stucture */
+/* Private data structure */
struct canonselphy_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -1051,7 +1051,7 @@ static void canonselphy_cmdline(void)
struct dyesub_backend canonselphy_backend = {
.name = "Canon SELPHY CP/ES",
- .version = "0.92",
+ .version = "0.93",
.uri_prefix = "canonselphy",
.cmdline_usage = canonselphy_cmdline,
.cmdline_arg = canonselphy_cmdline_arg,
@@ -1166,7 +1166,7 @@ struct dyesub_backend canonselphy_backend = {
08 00 03 00 [pg] 00 [pg2] [xx] 00 00 00 00 [? transitions to this]
09 00 07 00 [pg] 00 [pg2] [xx] 00 00 00 00 [ready for C]
09 00 00 00 [pg] 00 [pg2] 00 00 00 00 00 [? transitions to this]
- 0b 00 00 00 [pg] 00 [pg2] 00 00 00 00 00 [? transisions to this]
+ 0b 00 00 00 [pg] 00 [pg2] 00 00 00 00 00 [? transitions to this]
0c 00 00 00 [pg] 00 [pg2] 00 00 00 00 00 [? transitions to this]
0f 00 00 00 [pg] 00 [pg2] 00 00 00 00 00 [? transitions to this]
13 00 00 00 [pg] 00 [pg2] 00 00 00 00 00 [? transitions to this]
@@ -1338,7 +1338,7 @@ struct dyesub_backend canonselphy_backend = {
01 00 00 00 00 00 00 00 00 00 00 00 [idle, waiting for init]
02 00 00 00 00 00 00 00 00 00 00 00 [init sent, paper feeding]
- 02 00 00 00 00 00 00 00 00 00 00 00 [init sent, paper feeding]
+ 02 00 00 00 00 00 00 00 00 00 00 00 [init sent, paper feeding]
02 00 00 00 00 00 00 00 00 00 00 00 [waiting for Y data]
04 00 00 00 00 00 00 00 00 00 00 00 [waiting for M data]
08 00 00 00 00 00 00 00 00 00 00 00 [waiting for C data]
@@ -1373,14 +1373,14 @@ struct dyesub_backend canonselphy_backend = {
Known readback values:
- 01 00 00 00 [ss] 00 [pg] 00 00 00 00 [xx] [idle, waiting for init]
- 02 00 [rr] 00 00 00 [pg] 00 00 00 00 [xx] [init sent, paper feeding]
- 02 00 [rr] 00 10 00 [pg] 00 00 00 00 [xx] [init sent, paper feeding]
- 02 00 [rr] 00 70 00 [pg] 00 00 00 00 [xx] [waiting for Y data]
- 04 00 00 00 00 00 [pg] 00 00 00 00 [xx] [waiting for M data]
- 08 00 00 00 00 00 [pg] 00 00 00 00 [xx] [waiting for C data]
- 10 00 00 00 00 00 [pg] 00 00 00 00 [xx] [C done, waiting]
- 20 00 00 00 00 00 [pg] 00 00 00 00 [xx] [All done]
+ 01 00 00 00 [ss] 00 [pg] [zz] 00 00 00 [xx] [idle, waiting for init]
+ 02 00 [rr] 00 00 00 [pg] [zz] 00 00 00 [xx] [init sent, paper feeding]
+ 02 00 [rr] 00 10 00 [pg] [zz] 00 00 00 [xx] [init sent, paper feeding]
+ 02 00 [rr] 00 70 00 [pg] [zz] 00 00 00 [xx] [waiting for Y data]
+ 04 00 00 00 00 00 [pg] [zz] 00 00 00 [xx] [waiting for M data]
+ 08 00 00 00 00 00 [pg] [zz] 00 00 00 [xx] [waiting for C data]
+ 10 00 00 00 00 00 [pg] [zz] 00 00 00 [xx] [C done, waiting]
+ 20 00 00 00 00 00 [pg] [zz] 00 00 00 [xx] [All done]
[xx] is 0x01 on the CP780/CP800/CP900, 0x00 on all others.
@@ -1405,51 +1405,6 @@ struct dyesub_backend canonselphy_backend = {
0x41 if the 'Wide' paper tray is loaded with a 'P' ribbon. A '0' is used
to signify nothing being loaded.
- ***************************************************************************
- Selphy CP820/CP910/CP1000/CP1200:
-
- Radically different spool file format! 300dpi, same print sizes, but also
- adding a 50x50mm sticker and 22x17.3mm ministickers, though I think the
- driver treats all of those as 'C' sizes for printing purposes.
-
- Printer does *not* require use of a spooler! Huzzah!
-
- 32-byte header:
-
- 0f 00 00 40 00 00 00 00 00 00 00 00 00 00 01 00
- 01 00 ?? 00 00 00 00 00 XX 04 00 00 WW ZZ 00 00
-
- ?? == 50 (P)
- == 4c (L)
- == 43 (C)
-
- XX == e0 (P)
- 80 (L)
- 40 (C)
-
- WW == 50 (P)
- c0 (L)
- 9c (C)
-
- ZZ == 07 (P)
- 05 (L)
- 02 (C)
-
- P == 7008800 == 2336256 * 3 + 32 (1872*1248)
- L == 5087264 == 1695744 * 3 + 32 (1536*1104)
- C == 2180384 == 726784 * 3 + 32 (1088*668)
-
- It is worth mentioning that the image payload is Y'CbCr rather than the
- traditional YMC (or even BGR) of other dyseubs. Our best guess is that
- we need to use the JPEG coefficients, although we realistically have
- no way of confirming this.
-
- It is hoped that the printers do support YMC data, but as of yet we
- have no way of determining if this is possible.
-
- Also, we have reports of the printer not quite behaving properly
- in the face of multiple jobs; it's possible this thing may need a
- backend after all, but more sniffs will need to be performed to determine
- what the status readbacks (if any) mean.
+ [zz] is 0x01 when on battery power, 0x00 otherwise.
*/
diff --git a/src/cups/backend_canonselphyneo.c b/src/cups/backend_canonselphyneo.c
index c29cbe6..e72b9db 100644
--- a/src/cups/backend_canonselphyneo.c
+++ b/src/cups/backend_canonselphyneo.c
@@ -41,7 +41,7 @@
/* Exported */
#define USB_VID_CANON 0x04a9
-#define USB_PID_CANON_CP820 XXX
+#define USB_PID_CANON_CP820 0x327b
#define USB_PID_CANON_CP910 0x327a
#define USB_PID_CANON_CP1000 0x32ae
#define USB_PID_CANON_CP1200 0x32b1
@@ -58,7 +58,7 @@ struct selphyneo_readback {
uint8_t data[12];
} __attribute((packed));
-/* Private data stucture */
+/* Private data structure */
struct selphyneo_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -97,6 +97,8 @@ static char *selphyneo_errors(uint8_t err)
return "Paper Feed";
case 0x03:
return "No Paper";
+ case 0x06:
+ return "Ink Cassette Empty";
case 0x07:
return "No Ink";
case 0x09:
@@ -388,7 +390,7 @@ static void selphyneo_cmdline(void)
struct dyesub_backend canonselphyneo_backend = {
.name = "Canon SELPHY CPneo",
- .version = "0.06",
+ .version = "0.08",
.uri_prefix = "canonselphyneo",
.cmdline_usage = selphyneo_cmdline,
.cmdline_arg = selphyneo_cmdline_arg,
@@ -398,7 +400,7 @@ struct dyesub_backend canonselphyneo_backend = {
.read_parse = selphyneo_read_parse,
.main_loop = selphyneo_main_loop,
.devices = {
-// { USB_VID_CANON, USB_PID_CANON_CP820, P_CP910, ""},
+ { USB_VID_CANON, USB_PID_CANON_CP820, P_CP910, ""},
{ USB_VID_CANON, USB_PID_CANON_CP910, P_CP910, ""},
{ USB_VID_CANON, USB_PID_CANON_CP1000, P_CP910, ""},
{ USB_VID_CANON, USB_PID_CANON_CP1200, P_CP910, ""},
@@ -421,7 +423,7 @@ struct dyesub_backend canonselphyneo_backend = {
32-byte header:
0f 00 00 40 00 00 00 00 00 00 00 00 00 00 01 00
- 01 00 TT 00 00 00 00 00 XX XX XX XX YY YY YY YY
+ 01 00 TT 00 00 00 00 ZZ XX XX XX XX YY YY YY YY
cols (le32) rows (le32)
50 e0 04 50 07 1248 * 1872 (P)
@@ -432,19 +434,17 @@ struct dyesub_backend canonselphyneo_backend = {
== 4c (L)
== 43 (C)
+ ZZ == 00 Y'CbCr data follows
+ == 01 CMY data follows
+
Followed by three planes of image data.
P == 7008800 == 2336256 * 3 + 32 (1872*1248)
L == 5087264 == 1695744 * 3 + 32 (1472*1152)
C == 2180384 == 726784 * 3 + 32 (1088*668)
- It is worth mentioning that the image payload is Y'CbCr rather than the
- traditional YMC (or even BGR) of other dyseubs. Our best guess is that
- we need to use the JPEG coefficients, although we realistically have
- no way of confirming this.
-
- It is hoped that the printers do support YMC data, but as of yet we
- have no way of determining if this is possible.
+ It is worth mentioning that the Y'CbCr image data is surmised to use the
+ JPEG coefficients, although we realistically have no way of confirming this.
Other questions:
@@ -488,4 +488,18 @@ Also, the first time a readback happens after plugging in the printer:
34 44 35 31 01 00 01 00 01 00 45 00 "4D51" ...??
+
+** ** ** ** This is what windows sends if you print over the network:
+
+00 00 00 00 40 00 00 00 02 00 00 00 00 00 04 00 Header [unknown]
+00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+00 00 01 00 HH HH HH HH 02 00 00 00 PP PP PP PP Header2 [unknown] PP == payload len, HH == payload + header2 len [ie + 3 ]
+CC CC CC CC RR RR RR RR 00 00 00 00 LL LL LL LL CC == cols, RR == rows, LL == plane len (ie RR * CC)
+L2 L2 L2 L2 L2 == LL * 2, apparently.
+
+[ ..followed by three planes of LL bytes, totalling PP bytes.. ]
+
*/
diff --git a/src/cups/backend_citizencw01.c b/src/cups/backend_citizencw01.c
index 618af86..0987916 100644
--- a/src/cups/backend_citizencw01.c
+++ b/src/cups/backend_citizencw01.c
@@ -43,7 +43,7 @@
#define USB_PID_CITIZEN_CW01 0x0002 // Maybe others?
//#define USB_PID_OLMEC_OP900 XXXX
-/* Private data stucture */
+/* Private data structure */
struct cw01_spool_hdr {
uint8_t type; /* 0x00 -> 0x06 */
uint8_t res; /* vertical resolution; 0x00 == 334dpi, 0x01 == 600dpi */
@@ -183,7 +183,7 @@ static char *cw01_statuses(char *str)
break;
}
- return "Unkown Error";
+ return "Unknown Error";
}
static int cw01_do_cmd(struct cw01_ctx *ctx,
diff --git a/src/cups/backend_common.c b/src/cups/backend_common.c
index bc39061..959eee4 100644
--- a/src/cups/backend_common.c
+++ b/src/cups/backend_common.c
@@ -1,7 +1,7 @@
/*
* CUPS Backend common code
*
- * Copyright (c) 2007-2016 Solomon Peachy <pizza@shaftnet.org>
+ * Copyright (c) 2007-2017 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -27,7 +27,7 @@
#include "backend_common.h"
-#define BACKEND_VERSION "0.70G"
+#define BACKEND_VERSION "0.71G"
#ifndef URI_PREFIX
#error "Must Define URI_PREFIX"
#endif
@@ -168,7 +168,7 @@ static int parse1284_data(const char *device_id, struct deviceid_dict* dict)
break;
}
return num;
-};
+}
static char *dict_find(const char *key, int dlen, struct deviceid_dict* dict)
{
@@ -368,7 +368,7 @@ static int print_scan_output(struct libusb_device *device,
char *ieee_id = NULL;
int i;
- uint8_t endp_up = 0, endp_down = 0;
+ uint8_t endp_up, endp_down;
DEBUG("Probing VID: %04X PID: %04x\n", desc->idVendor, desc->idProduct);
@@ -392,6 +392,7 @@ static int print_scan_output(struct libusb_device *device,
}
/* Find the endpoints */
+ endp_up = endp_down = 0;
for (i = 0 ; i < config->interface[iface].altsetting[altset].bNumEndpoints ; i++) {
if ((config->interface[iface].altsetting[altset].endpoint[i].bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) {
if (config->interface[iface].altsetting[altset].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_IN)
@@ -428,7 +429,7 @@ static int print_scan_output(struct libusb_device *device,
}
if (!manuf || !strlen(manuf)) { /* Last-ditch */
if (manuf) free(manuf);
- manuf = url_encode("Unknown");
+ manuf = url_encode("Unknown"); // XXX use USB VID?
}
/* Look up model number */
@@ -445,7 +446,7 @@ static int print_scan_output(struct libusb_device *device,
if (!product || !strlen(product)) { /* Last-ditch */
if (!product) free(product);
- product = url_encode("Unknown");
+ product = url_encode("Unknown"); // XXX Use USB PID?
}
/* Look up description */
@@ -496,7 +497,7 @@ static int print_scan_output(struct libusb_device *device,
if (serial) free(serial);
WARNING("**** THIS PRINTER DOES NOT REPORT A SERIAL NUMBER!\n");
WARNING("**** If you intend to use multiple printers of this type, you\n");
- WARNING("**** must only plug one in at a time or unexpected behaivor will occur!\n");
+ WARNING("**** must only plug one in at a time or unexpected behavior will occur!\n");
serial = strdup("NONE_UNKNOWN");
}
@@ -662,7 +663,7 @@ static struct dyesub_backend *find_backend(char *uri_prefix)
void print_license_blurb(void)
{
const char *license = "\n\
-Copyright 2007-2016 Solomon Peachy <pizza AT shaftnet DOT org>\n\
+Copyright 2007-2017 Solomon Peachy <pizza AT shaftnet DOT org>\n\
\n\
This program is free software; you can redistribute it and/or modify it\n\
under the terms of the GNU General Public License as published by the Free\n\
@@ -750,8 +751,7 @@ int main (int argc, char **argv)
struct dyesub_backend *backend = NULL;
void * backend_ctx = NULL;
- uint8_t endp_up = 0;
- uint8_t endp_down = 0;
+ uint8_t endp_up, endp_down;
int iface = 0; // XXX loop through interfaces
int altset = 0; // XXX loop through altsetting
@@ -933,6 +933,7 @@ int main (int argc, char **argv)
goto done_close;
}
+ endp_up = endp_down = 0;
for (i = 0 ; i < config->interface[iface].altsetting[altset].bNumEndpoints ; i++) {
if ((config->interface[iface].altsetting[altset].endpoint[i].bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) {
if (config->interface[iface].altsetting[altset].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_IN)
@@ -1015,7 +1016,8 @@ newpage:
goto done_claimed;
/* Log the completed page */
- PAGE("%d %d\n", current_page, copies);
+ if (!uri)
+ PAGE("%d %d\n", current_page, copies);
/* Since we have no way of telling if there's more data remaining
to be read (without actually trying to read it), always assume
@@ -1026,7 +1028,8 @@ done_multiple:
close(data_fd);
/* Done printing, log the total number of pages */
- PAGE("total %d\n", current_page * copies);
+ if (!uri)
+ PAGE("total %d\n", current_page * copies);
ret = CUPS_BACKEND_OK;
done_claimed:
diff --git a/src/cups/backend_common.h b/src/cups/backend_common.h
index fea04dc..4e489fc 100644
--- a/src/cups/backend_common.h
+++ b/src/cups/backend_common.h
@@ -1,7 +1,7 @@
/*
* CUPS Backend common code
*
- * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2017 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -117,6 +117,7 @@ enum {
P_MITSU_9800,
P_MITSU_9800S,
P_MITSU_9810,
+ P_MITSU_P93D,
P_MITSU_P95D,
P_DNP_DS40,
P_DNP_DS80,
@@ -180,7 +181,7 @@ extern struct dyesub_backend BACKEND;
#endif
/* CUPS compatibility */
-#define CUPS_BACKEND_OK 0 /* Sucess */
+#define CUPS_BACKEND_OK 0 /* Success */
#define CUPS_BACKEND_FAILED 1 /* Failed to print use CUPS policy */
#define CUPS_BACKEND_AUTH_REQUIRED 2 /* Auth required */
#define CUPS_BACKEND_HOLD 3 /* Hold this job only */
diff --git a/src/cups/backend_dnpds40.c b/src/cups/backend_dnpds40.c
index 650c963..68f2293 100644
--- a/src/cups/backend_dnpds40.c
+++ b/src/cups/backend_dnpds40.c
@@ -64,7 +64,7 @@
#define USB_PID_DNP_DS620 0x8b01
#define USB_PID_DNP_DS820 0x9001
-/* Private data stucture */
+/* Private data structure */
struct dnpds40_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -369,7 +369,7 @@ static char *dnpds80_duplex_statuses(int status)
break;
}
- return "Unkown Duplexer Error";
+ return "Unknown Duplexer Error";
}
static char *dnpds40_statuses(int status)
diff --git a/src/cups/backend_kodak1400.c b/src/cups/backend_kodak1400.c
index 3b97e3a..6851385 100644
--- a/src/cups/backend_kodak1400.c
+++ b/src/cups/backend_kodak1400.c
@@ -74,7 +74,7 @@ struct kodak1400_hdr {
} __attribute__((packed));
-/* Private data stucture */
+/* Private data structure */
struct kodak1400_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -643,7 +643,7 @@ struct dyesub_backend kodak1400_backend = {
00 00 00 00 NULL
XX 00 Glossy, 01 Matte (Note: Kodak805 only supports Glossy)
XX 01 to laminate, 00 to not.
- 01 Unkown, always set to 01
+ 01 Unknown, always set to 01
XX Lamination Strength:
3c Glossy
diff --git a/src/cups/backend_kodak605.c b/src/cups/backend_kodak605.c
index 1c0382d..ac4367a 100644
--- a/src/cups/backend_kodak605.c
+++ b/src/cups/backend_kodak605.c
@@ -91,7 +91,7 @@ struct kodak605_media_list {
struct kodak605_status {
struct kodak605_sts_hdr hdr;
/*@10*/ uint32_t ctr_life; /* Lifetime Prints */
- uint32_t ctr_maint; /* Prints since last maintainence */
+ uint32_t ctr_maint; /* Prints since last maintenance */
uint32_t ctr_media; /* Prints on current media */
uint32_t ctr_cut; /* Cutter Actuations */
uint32_t ctr_head; /* Prints on current head */
@@ -164,7 +164,7 @@ static const char *kodak68xx_mediatypes(int type)
#define CMDBUF_LEN 4
-/* Private data stucture */
+/* Private data structure */
struct kodak605_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
diff --git a/src/cups/backend_kodak6800.c b/src/cups/backend_kodak6800.c
index 63a6063..9df4200 100644
--- a/src/cups/backend_kodak6800.c
+++ b/src/cups/backend_kodak6800.c
@@ -1,7 +1,7 @@
/*
* Kodak 6800/6850 Photo Printer CUPS backend -- libusb-1.0 version
*
- * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2017 Solomon Peachy <pizza@shaftnet.org>
*
* Development of this backend was sponsored by:
*
@@ -113,14 +113,14 @@ enum {
WAIT_STATUS2_BUSY = 4,
};
-#define ERROR_STATUS2_CTRL_CIRCUIT (1<<31)
-#define ERROR_STATUS2_MECHANISM_CTRL (1<<30)
-#define ERROR_STATUS2_SENSOR (1<<13)
-#define ERROR_STATUS2_COVER_OPEN (1<<12)
-#define ERROR_STATUS2_TEMP_SENSOR (1<<9)
-#define ERROR_STATUS2_PAPER_JAM (1<<8)
-#define ERROR_STATUS2_PAPER_EMPTY (1<<6)
-#define ERROR_STATUS2_RIBBON_ERR (1<<4)
+#define ERROR_STATUS2_CTRL_CIRCUIT (0x80000000)
+#define ERROR_STATUS2_MECHANISM_CTRL (0x40000000)
+#define ERROR_STATUS2_SENSOR (0x00002000)
+#define ERROR_STATUS2_COVER_OPEN (0x00001000)
+#define ERROR_STATUS2_TEMP_SENSOR (0x00000200)
+#define ERROR_STATUS2_PAPER_JAM (0x00000100)
+#define ERROR_STATUS2_PAPER_EMPTY (0x00000040)
+#define ERROR_STATUS2_RIBBON_ERR (0x00000010)
enum {
CTRL_CIR_ERROR_EEPROM1 = 0x01,
@@ -221,7 +221,7 @@ struct kodak68x0_media_readback {
#define CMDBUF_LEN 17
-/* Private data stucture */
+/* Private data structure */
struct kodak6800_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -1257,7 +1257,7 @@ static int kodak6800_main_loop(void *vctx, int copies) {
/* Exported */
struct dyesub_backend kodak6800_backend = {
.name = "Kodak 6800/6850",
- .version = "0.57",
+ .version = "0.58",
.uri_prefix = "kodak6800",
.cmdline_usage = kodak6800_cmdline,
.cmdline_arg = kodak6800_cmdline_arg,
diff --git a/src/cups/backend_mitsu70x.c b/src/cups/backend_mitsu70x.c
index a0ab482..39a94e4 100644
--- a/src/cups/backend_mitsu70x.c
+++ b/src/cups/backend_mitsu70x.c
@@ -1,7 +1,7 @@
/*
* Mitsubishi CP-D70/D707 Photo Printer CUPS backend -- libusb-1.0 version
*
- * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2017 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -84,16 +84,19 @@ struct BandImage {
};
#endif
+#define REQUIRED_LIB_APIVERSION 4
+
/* Image processing library function prototypes */
#define LIB_NAME_RE "libMitsuD70ImageReProcess.so" // Reimplemented library
+typedef int (*lib70x_getapiversionFN)(void);
typedef int (*Get3DColorTableFN)(uint8_t *buf, const char *filename);
typedef struct CColorConv3D *(*Load3DColorTableFN)(const uint8_t *ptr);
typedef void (*Destroy3DColorTableFN)(struct CColorConv3D *this);
typedef void (*DoColorConvFN)(struct CColorConv3D *this, uint8_t *data, uint16_t cols, uint16_t rows, uint32_t bytes_per_row, int rgb_bgr);
typedef struct CPCData *(*get_CPCDataFN)(const char *filename);
typedef void (*destroy_CPCDataFN)(struct CPCData *data);
-typedef int (*do_image_effectFN)(struct CPCData *cpc, struct BandImage *input, struct BandImage *output, int sharpen, uint8_t rew[2]);
+typedef int (*do_image_effectFN)(struct CPCData *cpc, struct CPCData *ecpc, struct BandImage *input, struct BandImage *output, int sharpen, int reverse, uint8_t rew[2]);
typedef int (*send_image_dataFN)(struct BandImage *out, void *context,
int (*callback_fn)(void *context, void *buffer, uint32_t len));
@@ -109,6 +112,7 @@ typedef int (*send_image_dataFN)(struct BandImage *out, void *context,
#define USB_PID_MITSU_D70X 0x3B30
#define USB_PID_MITSU_K60 0x3B31
#define USB_PID_MITSU_D80 0x3B36
+#define USB_PID_MITSU_D90 0x3B60
#define USB_VID_KODAK 0x040a
#define USB_PID_KODAK305 0x404f
//#define USB_VID_FUJIFILM XXXXXX
@@ -117,7 +121,10 @@ typedef int (*send_image_dataFN)(struct BandImage *out, void *context,
/* Width of the laminate data file */
#define LAMINATE_STRIDE 1864
-/* Private data stucture */
+/* Max size of data chunk sent over */
+#define CHUNK_LEN (256*1024)
+
+/* Private data structure */
struct mitsu70x_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -140,23 +147,31 @@ struct mitsu70x_ctx {
char *laminatefname;
char *lutfname;
char *cpcfname;
+ char *ecpcfname;
void *dl_handle;
+ lib70x_getapiversionFN GetAPIVersion;
Get3DColorTableFN Get3DColorTable;
Load3DColorTableFN Load3DColorTable;
Destroy3DColorTableFN Destroy3DColorTable;
DoColorConvFN DoColorConv;
get_CPCDataFN GetCPCData;
destroy_CPCDataFN DestroyCPCData;
+ do_image_effectFN DoImageEffect60;
+ do_image_effectFN DoImageEffect70;
+ do_image_effectFN DoImageEffect80;
do_image_effectFN DoImageEffect;
send_image_dataFN SendImageData;
struct CColorConv3D *lut;
struct CPCData *cpcdata;
+ struct CPCData *ecpcdata;
char *last_cpcfname;
+ char *last_ecpcfname;
int raw_format;
+ int reverse;
int sharpen; /* ie mhdr.sharpen - 1 */
uint8_t rew[2]; /* 1 for rewind ok (default!) */
@@ -197,6 +212,7 @@ struct mitsu70x_jobs {
#define MECHA_STATUS_INIT 0x80
#define MECHA_STATUS_FEED 0x50
#define MECHA_STATUS_LOAD 0x40
+#define MECHA_STATUS_LOAD2 0x30
#define MECHA_STATUS_PRINT 0x20
#define MECHA_STATUS_IDLE 0x00
@@ -244,7 +260,7 @@ struct mitsu70x_jobs {
#define ERROR_STATUS0_RIBBONEND 0x09
#define ERROR_STATUS0_DOOROPEN_IDLE 0x0A
#define ERROR_STATUS0_DOOROPEN_PRNT 0x0B
-#define ERROR_STATUS0_POWEROFF 0x0C // nonsense.. heh.
+#define ERROR_STATUS0_POWEROFF 0x0C // Powered off during printing..?
#define ERROR_STATUS0_NOMCOP 0x0D
#define ERROR_STATUS0_RIBBONSKIP1 0x0E
#define ERROR_STATUS0_RIBBONSKIP2 0x0F
@@ -311,11 +327,15 @@ struct mitsu70x_printerstatus_resp {
uint8_t hdr[4]; /* E4 56 32 31 */
uint8_t memory;
uint8_t power;
- uint8_t unk[34];
+ uint8_t unk[20];
+ uint8_t sleeptime; /* In minutes, 0-10 */
+ uint8_t iserial; /* 0x00 for Enabled, 0x80 for Disabled */
+ uint8_t unk_b[12];
int16_t model[6]; /* LE, UTF-16 */
int16_t serno[6]; /* LE, UTF-16 */
struct mitsu70x_status_ver vers[7]; // components are 'MLRTF'
- uint8_t null[8];
+ uint8_t null[2];
+ uint8_t user_serno[6]; /* Supposedly, don't know how to set it */
struct mitsu70x_status_deck lower;
struct mitsu70x_status_deck upper;
} __attribute__((packed));
@@ -356,8 +376,8 @@ struct mitsu70x_hdr {
uint8_t sharpen; /* 0-9. 5 is "normal", 0 is "off" */
uint8_t mode; /* 0 for cooked YMC planar, 1 for packed BGR */
uint8_t use_lut; /* in BGR mode, 0 disables, 1 enables */
-
- uint8_t pad[448];
+ uint8_t reversed; /* 1 tells the backend the row data is correct */
+ uint8_t pad[447];
} __attribute__((packed));
/* Error dumps, etc */
@@ -370,6 +390,7 @@ static char *mitsu70x_mechastatus(uint8_t *sts)
case MECHA_STATUS_FEED:
return "Paper Feeding/Cutting";
case MECHA_STATUS_LOAD:
+ case MECHA_STATUS_LOAD2:
return "Media Loading";
case MECHA_STATUS_PRINT:
return "Printing";
@@ -609,6 +630,13 @@ static const char *mitsu70x_media_types(uint8_t brand, uint8_t type)
return "CK-K76R (6x8)";
else
return "Unknown";
+
+// Also CK-D715, CK-D718, CK-D720, CK-D723 (4x6,5x8,6x8,6x9) for D70-S model
+// CK-D746-U for D70-U model
+// CK-D820 (6x8) for D80-S model
+// CK-D868 (6x8) for D80 (non-S)
+// D90 can use _all_ of htese types except for the -U!
+
}
#define CMDBUF_LEN 512
@@ -653,30 +681,60 @@ static void mitsu70x_attach(void *vctx, struct libusb_device_handle *dev,
/* Attempt to open the library */
#if defined(WITH_DYNAMIC)
- INFO("Attempting to load image processing library\n");
+ DEBUG("Attempting to load image processing library\n");
ctx->dl_handle = DL_OPEN(LIB_NAME_RE);
if (!ctx->dl_handle)
WARNING("Image processing library not found, using internal fallback code\n");
if (ctx->dl_handle) {
+ ctx->GetAPIVersion = DL_SYM(ctx->dl_handle, "lib70x_getapiversion");
+ if (!ctx->GetAPIVersion) {
+ ERROR("Problem resolving API Version symbol in imaging processing library, too old or not installed?\n");
+ DL_CLOSE(ctx->dl_handle);
+ ctx->dl_handle = NULL;
+ return;
+ }
+ if (ctx->GetAPIVersion() != REQUIRED_LIB_APIVERSION) {
+ ERROR("Image processing library API version mismatch!\n");
+ DL_CLOSE(ctx->dl_handle);
+ ctx->dl_handle = NULL;
+ return;
+ }
+
ctx->Get3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Get3DColorTable");
ctx->Load3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Load3DColorTable");
ctx->Destroy3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Destroy3DColorTable");
ctx->DoColorConv = DL_SYM(ctx->dl_handle, "CColorConv3D_DoColorConv");
ctx->GetCPCData = DL_SYM(ctx->dl_handle, "get_CPCData");
ctx->DestroyCPCData = DL_SYM(ctx->dl_handle, "destroy_CPCData");
- ctx->DoImageEffect = DL_SYM(ctx->dl_handle, "do_image_effect");
+ ctx->DoImageEffect60 = DL_SYM(ctx->dl_handle, "do_image_effect60");
+ ctx->DoImageEffect70 = DL_SYM(ctx->dl_handle, "do_image_effect70");
+ ctx->DoImageEffect80 = DL_SYM(ctx->dl_handle, "do_image_effect80");
ctx->SendImageData = DL_SYM(ctx->dl_handle, "send_image_data");
if (!ctx->Get3DColorTable || !ctx->Load3DColorTable ||
!ctx->Destroy3DColorTable || !ctx->DoColorConv ||
!ctx->GetCPCData || !ctx->DestroyCPCData ||
- !ctx->DoImageEffect || !ctx->SendImageData) {
- WARNING("Problem resolving symbols in imaging processing library\n");
+ !ctx->DoImageEffect60 || !ctx->DoImageEffect70 ||
+ !ctx->DoImageEffect80 || !ctx->SendImageData) {
+ ERROR("Problem resolving symbols in imaging processing library\n");
DL_CLOSE(ctx->dl_handle);
ctx->dl_handle = NULL;
} else {
- INFO("Image processing library successfully loaded\n");
+ DEBUG("Image processing library successfully loaded\n");
}
}
+
+ switch (ctx->type) {
+ case P_MITSU_D80:
+ ctx->DoImageEffect = ctx->DoImageEffect80;
+ break;
+ case P_MITSU_K60:
+ case P_KODAK_305:
+ ctx->DoImageEffect = ctx->DoImageEffect60;
+ break;
+ default:
+ ctx->DoImageEffect = ctx->DoImageEffect70;
+ break;
+ }
#else
WARNING("Dynamic library support not enabled, using internal fallback code\n");
#endif
@@ -694,6 +752,8 @@ static void mitsu70x_teardown(void *vctx) {
if (ctx->dl_handle) {
if (ctx->cpcdata)
ctx->DestroyCPCData(ctx->cpcdata);
+ if (ctx->ecpcdata)
+ ctx->DestroyCPCData(ctx->ecpcdata);
if (ctx->lut)
ctx->Destroy3DColorTable(ctx->lut);
DL_CLOSE(ctx->dl_handle);
@@ -718,6 +778,7 @@ static int mitsu70x_read_parse(void *vctx, int data_fd) {
ctx->databuf = NULL;
}
+ /* Reset some state */
ctx->matte = 0;
ctx->rew[0] = 1;
ctx->rew[1] = 1;
@@ -752,6 +813,21 @@ repeat:
ctx->raw_format = !mhdr.mode;
+ /* Sanity check Matte mode */
+ if (!mhdr.laminate && mhdr.laminate_mode) {
+ if (ctx->type != P_MITSU_D70X) {
+ if (mhdr.speed != 0x03 && mhdr.speed != 0x04) {
+ WARNING("Forcing Ultrafine mode for matte printing!\n");
+ mhdr.speed = 0x04; /* Force UltraFine */
+ }
+ } else {
+ if (mhdr.speed != 0x03) {
+ mhdr.speed = 0x03; /* Force SuperFine */
+ WARNING("Forcing SuperFine mode for matte printing!\n");
+ }
+ }
+ }
+
/* Figure out the correction data table to use */
if (ctx->type == P_MITSU_D70X) {
ctx->laminatefname = CORRTABLE_PATH "/D70MAT01.raw";
@@ -774,12 +850,14 @@ repeat:
if (mhdr.speed == 3) {
ctx->cpcfname = CORRTABLE_PATH "/CPD80S01.cpc";
+ ctx->ecpcfname = CORRTABLE_PATH "/CPD80E01.cpc";
} else if (mhdr.speed == 4) {
ctx->cpcfname = CORRTABLE_PATH "/CPD80U01.cpc";
+ ctx->ecpcfname = NULL;
} else {
ctx->cpcfname = CORRTABLE_PATH "/CPD80N01.cpc";
+ ctx->ecpcfname = NULL;
}
- // XXX what about CPD80**E**01?
if (mhdr.hdr[3] != 0x01) {
WARNING("Print job has wrong submodel specifier (%x)\n", mhdr.hdr[3]);
mhdr.hdr[3] = 0x01;
@@ -831,11 +909,13 @@ repeat:
ctx->lutfname = NULL;
ctx->sharpen = mhdr.sharpen - 1;
+ ctx->reverse = !mhdr.reversed;
/* Clean up header back to pristine. */
mhdr.use_lut = 0;
mhdr.mode = 0;
mhdr.sharpen = 0;
+ mhdr.reversed = 0;
/* Work out total printjob size */
ctx->cols = be16_to_cpu(mhdr.cols);
@@ -921,10 +1001,11 @@ repeat:
ctx->DoColorConv(ctx->lut, spoolbuf, ctx->cols, ctx->rows, ctx->cols * 3, COLORCONV_BGR);
}
- /* Load in the CPC file, if needed! */
if (ctx->dl_handle) {
struct BandImage input;
+
+ /* Load in the CPC file, if needed */
if (ctx->cpcfname && ctx->cpcfname != ctx->last_cpcfname) {
ctx->last_cpcfname = ctx->cpcfname;
if (ctx->cpcdata)
@@ -936,8 +1017,23 @@ repeat:
}
}
- /* Convert using image processing library */
+ /* Load in the secondary CPC, if needed */
+ if (ctx->ecpcfname != ctx->last_ecpcfname) {
+ ctx->last_ecpcfname = ctx->ecpcfname;
+ if (ctx->ecpcdata)
+ ctx->DestroyCPCData(ctx->ecpcdata);
+ if (ctx->ecpcfname) {
+ ctx->ecpcdata = ctx->GetCPCData(ctx->ecpcfname);
+ if (!ctx->ecpcdata) {
+ ERROR("Unable to load CPC file '%s'\n", ctx->cpcfname);
+ return CUPS_BACKEND_CANCEL;
+ }
+ } else {
+ ctx->ecpcdata = NULL;
+ }
+ }
+ /* Convert using image processing library */
input.origin_rows = input.origin_cols = 0;
input.rows = ctx->rows;
input.cols = ctx->cols;
@@ -950,9 +1046,9 @@ repeat:
ctx->output.imgbuf = ctx->databuf + ctx->datalen;
ctx->output.bytes_per_row = ctx->cols * 3 * 2;
-
DEBUG("Running print data through processing library\n");
- if (ctx->DoImageEffect(ctx->cpcdata, &input, &ctx->output, ctx->sharpen, ctx->rew)) {
+ if (ctx->DoImageEffect(ctx->cpcdata, ctx->ecpcdata,
+ &input, &ctx->output, ctx->sharpen, ctx->reverse, ctx->rew)) {
ERROR("Image Processing failed, aborting!\n");
return CUPS_BACKEND_CANCEL;
}
@@ -1175,11 +1271,15 @@ static int mitsu70x_set_sleeptime(struct mitsu70x_ctx *ctx, uint8_t time)
uint8_t cmdbuf[4];
int ret;
- /* Send Job cancel. No response. */
+ /* 10 minutes max, according to all docs. */
+ if (time > 10)
+ time = 10;
+
+ /* Send Parameter.. */
memset(cmdbuf, 0, 4);
cmdbuf[0] = 0x1b;
cmdbuf[1] = 0x53;
- cmdbuf[2] = 0x53; // XXX also, 0x4e and 0x50 are other params.
+ cmdbuf[2] = 0x53;
cmdbuf[3] = time;
if ((ret = send_data(ctx->dev, ctx->endp_down,
@@ -1189,6 +1289,59 @@ static int mitsu70x_set_sleeptime(struct mitsu70x_ctx *ctx, uint8_t time)
return 0;
}
+static int mitsu70x_set_iserial(struct mitsu70x_ctx *ctx, uint8_t enabled)
+{
+ uint8_t cmdbuf[4];
+ int ret;
+
+ if (enabled)
+ enabled = 0;
+ else
+ enabled = 0x80;
+
+ /* Send Parameter.. */
+ memset(cmdbuf, 0, 4);
+ cmdbuf[0] = 0x1b;
+ cmdbuf[1] = 0x53;
+ cmdbuf[2] = 0x4e;
+ cmdbuf[3] = enabled;
+
+ if ((ret = send_data(ctx->dev, ctx->endp_down,
+ cmdbuf, 4)))
+ return ret;
+
+ return 0;
+}
+
+#if 0
+/* Switches between "Driver" and "SDK" modes.
+ Single-endpoint vs Multi-Endpoint, essentially.
+ Not sure about the polarity.
+ */
+static int mitsu70x_set_printermode(struct mitsu70x_ctx *ctx, uint8_t enabled)
+{
+ uint8_t cmdbuf[4];
+ int ret;
+
+ if (enabled)
+ enabled = 0;
+ else
+ enabled = 0x80;
+
+ /* Send Parameter.. */
+ memset(cmdbuf, 0, 4);
+ cmdbuf[0] = 0x1b;
+ cmdbuf[1] = 0x53;
+ cmdbuf[2] = 0x50;
+ cmdbuf[3] = enabled;
+
+ if ((ret = send_data(ctx->dev, ctx->endp_down,
+ cmdbuf, 4)))
+ return ret;
+
+ return 0;
+}
+#endif
static int mitsu70x_wakeup(struct mitsu70x_ctx *ctx)
{
int ret;
@@ -1210,9 +1363,25 @@ static int mitsu70x_wakeup(struct mitsu70x_ctx *ctx)
static int d70_library_callback(void *context, void *buffer, uint32_t len)
{
+ uint32_t chunk = len;
+ uint32_t offset = 0;
+ int ret = 0;
+
struct mitsu70x_ctx *ctx = context;
- return send_data(ctx->dev, ctx->endp_down, buffer, len);
+ while (chunk > 0) {
+ if (chunk > CHUNK_LEN)
+ chunk = CHUNK_LEN;
+
+ ret = send_data(ctx->dev, ctx->endp_down, buffer + offset, chunk);
+ if (ret < 0)
+ break;
+
+ offset += chunk;
+ chunk = len - offset;
+ }
+
+ return ret;
}
static int mitsu70x_main_loop(void *vctx, int copies)
@@ -1221,6 +1390,7 @@ static int mitsu70x_main_loop(void *vctx, int copies)
struct mitsu70x_jobstatus jobstatus;
struct mitsu70x_printerstatus_resp resp;
struct mitsu70x_hdr *hdr;
+ uint8_t last_status[4] = {0xff, 0xff, 0xff, 0xff};
int ret;
@@ -1368,21 +1538,7 @@ skip_status:
if (ctx->type != P_MITSU_D70X) {
hdr->rewind[0] = !ctx->rew[0];
hdr->rewind[1] = !ctx->rew[1];
- }
-
- /* Matte operation requires Ultrafine/superfine */
- if (ctx->matte) {
- if (ctx->type != P_MITSU_D70X) {
- if (hdr->speed != 0x03 && hdr->speed != 0x04) {
- WARNING("Forcing Ultrafine mode for matte printing!\n");
- hdr->speed = 0x04; /* Force UltraFine */
- }
- } else {
- if (hdr->speed != 0x03) {
- hdr->speed = 0x03; /* Force SuperFine */
- WARNING("Forcing Ultrafine mode for matte printing!\n");
- }
- }
+ DEBUG("Rewind Inhibit? %02x %02x\n", hdr->rewind[0], hdr->rewind[1]);
}
/* Any other fixups? */
@@ -1411,7 +1567,7 @@ skip_status:
/* K60 and 305 need data sent in 256K chunks, but the first
chunk needs to subtract the length of the 512-byte header */
- int chunk = 256*1024 - sizeof(struct mitsu70x_hdr);
+ int chunk = CHUNK_LEN - sizeof(struct mitsu70x_hdr);
int sent = 512;
while (chunk > 0) {
if ((ret = send_data(ctx->dev, ctx->endp_down,
@@ -1419,8 +1575,8 @@ skip_status:
return CUPS_BACKEND_FAILED;
sent += chunk;
chunk = ctx->datalen - sent;
- if (chunk > 256*1024)
- chunk = 256*1024;
+ if (chunk > CHUNK_LEN)
+ chunk = CHUNK_LEN;
}
}
@@ -1471,12 +1627,18 @@ skip_status:
return CUPS_BACKEND_STOP;
}
- INFO("%s: %x/%x/%x/%x\n",
- mitsu70x_jobstatuses(jobstatus.job_status),
- jobstatus.job_status[0],
- jobstatus.job_status[1],
- jobstatus.job_status[2],
- jobstatus.job_status[3]);
+ /* Only print if it's changed */
+ if (jobstatus.job_status[0] != last_status[0] ||
+ jobstatus.job_status[1] != last_status[1] ||
+ jobstatus.job_status[2] != last_status[2] ||
+ jobstatus.job_status[3] != last_status[3])
+ INFO("%s: %02x/%02x/%02x/%02x\n",
+ mitsu70x_jobstatuses(jobstatus.job_status),
+ jobstatus.job_status[0],
+ jobstatus.job_status[1],
+ jobstatus.job_status[2],
+ jobstatus.job_status[3]);
+
if (jobstatus.job_status[0] == JOB_STATUS0_END) {
if (jobstatus.job_status[1] ||
jobstatus.job_status[2] ||
@@ -1495,6 +1657,9 @@ skip_status:
INFO("Fast return mode enabled.\n");
break;
}
+
+ /* Update cache for the next round */
+ memcpy(last_status, jobstatus.job_status, 4);
} while(1);
/* Clean up */
@@ -1541,6 +1706,8 @@ static void mitsu70x_dump_printerstatus(struct mitsu70x_printerstatus_resp *resp
INFO("FW Component: %c %s (%04x)\n",
type, buf, be16_to_cpu(resp->vers[i].checksum));
}
+ INFO("Standby Timeout: %d minutes\n", resp->sleeptime);
+ INFO("iSerial Reporting: %s\n", resp->iserial ? "No" : "Yes" );
INFO("Lower Mechanical Status: %s\n",
mitsu70x_mechastatus(resp->lower.mecha_status));
@@ -1666,6 +1833,7 @@ static void mitsu70x_cmdline(void)
DEBUG("\t\t[ -s ] # Query status\n");
DEBUG("\t\t[ -f ] # Use fast return mode\n");
DEBUG("\t\t[ -k num ] # Set standby time (1-60 minutes, 0 disables)\n");
+ DEBUG("\t\t[ -x num ] # Set USB iSerialNumber Reporting (1 on, 0 off)\n");
DEBUG("\t\t[ -X jobid ] # Abort a printjob\n");}
static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv)
@@ -1676,7 +1844,7 @@ static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv)
if (!ctx)
return -1;
- while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "sX:k:")) >= 0) {
+ while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "sk:X:x:")) >= 0) {
switch(i) {
GETOPT_PROCESS_GLOBAL
case 'k':
@@ -1685,6 +1853,9 @@ static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv)
case 's':
j = mitsu70x_query_status(ctx);
break;
+ case 'x':
+ j = mitsu70x_set_iserial(ctx, atoi(optarg));
+ break;
case 'X':
j = mitsu70x_cancel_job(ctx, atoi(optarg));
break;
@@ -1702,7 +1873,7 @@ static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv)
/* Exported */
struct dyesub_backend mitsu70x_backend = {
.name = "Mitsubishi CP-D70/D707/K60/D80",
- .version = "0.55",
+ .version = "0.61",
.uri_prefix = "mitsu70x",
.cmdline_usage = mitsu70x_cmdline,
.cmdline_arg = mitsu70x_cmdline_arg,
@@ -1716,6 +1887,7 @@ struct dyesub_backend mitsu70x_backend = {
{ USB_VID_MITSU, USB_PID_MITSU_D70X, P_MITSU_D70X, ""},
{ USB_VID_MITSU, USB_PID_MITSU_K60, P_MITSU_K60, ""},
{ USB_VID_MITSU, USB_PID_MITSU_D80, P_MITSU_D80, ""},
+// { USB_VID_MITSU, USB_PID_MITSU_D90, P_MITSU_D90, ""},
{ USB_VID_KODAK, USB_PID_KODAK305, P_KODAK_305, ""},
// { USB_VID_FUJIFILM, USB_PID_FUJI_ASK300, P_FUJI_ASK300, ""},
{ 0, 0, 0, ""}
@@ -1751,7 +1923,7 @@ struct dyesub_backend mitsu70x_backend = {
YY YY == rows
QQ QQ == lamination columns (equal to XX XX)
ZZ ZZ == lamination rows (YY YY + 12 on D70x/D80/ASK300, YY YY on others)
- RR RR == "rewind inhibit", 01 01 enabled, normally 00 00
+ RR RR == "rewind inhibit", 01 01 enabled, normally 00 00 (All but D70x)
SS == Print mode: 00 = Fine, 03 = SuperFine (D70x/D80 only), 04 = UltraFine
(Matte requires Superfine or Ultrafine)
UU == 00 = Auto, 01 = Lower Deck (required for !D70x), 02 = Upper Deck
diff --git a/src/cups/backend_mitsu9550.c b/src/cups/backend_mitsu9550.c
index 12ff0e8..907c773 100644
--- a/src/cups/backend_mitsu9550.c
+++ b/src/cups/backend_mitsu9550.c
@@ -104,7 +104,7 @@ struct mitsu9550_cmd {
uint8_t cmd[4];
} __attribute__((packed));
-/* Private data stucture */
+/* Private data structure */
struct mitsu9550_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
diff --git a/src/cups/backend_mitsup95d.c b/src/cups/backend_mitsup95d.c
index 140e918..100462f 100644
--- a/src/cups/backend_mitsup95d.c
+++ b/src/cups/backend_mitsup95d.c
@@ -1,7 +1,11 @@
/*
- * Mitsubishi P95D Monochrome Thermal Photo Printer CUPS backend
+ * Mitsubishi P93D/P95D Monochrome Thermal Photo Printer CUPS backend
*
- * (c) 2016 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2016-2017 Solomon Peachy <pizza@shaftnet.org>
+ *
+ * Development of this backend was sponsored by:
+ *
+ * A benefactor who wishes to remain anonymous
*
* The latest version of this program can be found at:
*
@@ -40,14 +44,17 @@
#include "backend_common.h"
#define USB_VID_MITSU 0x06D3
+#define USB_PID_MITSU_P93D 0x0398
#define USB_PID_MITSU_P95D 0x3b10
-/* Private data stucture */
+/* Private data structure */
struct mitsup95d_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
+ int type;
+
uint8_t mem_clr[4]; // 1b 5a 43 00
int mem_clr_present;
@@ -57,7 +64,8 @@ struct mitsup95d_ctx {
uint8_t hdr2[50]; // 1b 57 21 2e ...
uint8_t hdr3[50]; // 1b 57 22 2e ...
- uint8_t hdr4[36]; // 1b 58 ...
+ uint8_t hdr4[42]; // 1b 58 ...
+ int hdr4_len; // 36 (P95) or 42 (P93)
uint8_t plane[12]; // 1b 5a 74 00 ...
uint8_t *databuf;
@@ -95,6 +103,8 @@ static void mitsup95d_attach(void *vctx, struct libusb_device_handle *dev,
device = libusb_get_device(dev);
libusb_get_device_descriptor(device, &desc);
+ ctx->type = lookup_printer_type(&mitsup95d_backend,
+ desc.idVendor, desc.idProduct);
}
static void mitsup95d_teardown(void *vctx) {
@@ -116,7 +126,7 @@ static int mitsup95d_read_parse(void *vctx, int data_fd) {
int i;
int remain;
int ptr_offset;
-
+
if (!ctx)
return CUPS_BACKEND_FAILED;
@@ -125,25 +135,20 @@ static int mitsup95d_read_parse(void *vctx, int data_fd) {
ctx->databuf = NULL;
}
ctx->mem_clr_present = 0;
-
+
top:
i = read(data_fd, buf, sizeof(buf));
+
if (i == 0)
return CUPS_BACKEND_CANCEL;
if (i < 0)
return CUPS_BACKEND_CANCEL;
-
if (buf[0] != 0x1b) {
ERROR("malformed data stream\n");
return CUPS_BACKEND_CANCEL;
}
switch (buf[1]) {
- case 0x43: /* Memory Clear */
- remain = 4;
- ptr = ctx->mem_clr;
- ctx->mem_clr_present = 1;
- break;
case 0x50: /* Footer */
remain = 2;
ptr = ctx->ftr;
@@ -157,12 +162,19 @@ top:
ptr = tmphdr;
break;
case 0x58: /* User Comment */
- remain = 36;
+ if (ctx->type == P_MITSU_P93D)
+ ctx->hdr4_len = 42;
+ else
+ ctx->hdr4_len = 36;
+ remain = ctx->hdr4_len;
ptr = ctx->hdr4;
break;
- case 0x5a: /* Plane header */
- remain = 12;
- ptr = ctx->plane;
+ case 0x5a: /* Plane header OR printer reset */
+ // reset memory: 1b 5a 43 ... [len 04]
+ // plane header: 1b 5a 74 ... [len 12]
+ // Read in the minimum length, and clean it up later */
+ ptr = tmphdr;
+ remain = 4;
break;
default:
ERROR("Unrecognized command! (%02x %02x)\n", buf[0], buf[1]);
@@ -172,7 +184,7 @@ top:
memcpy(ptr, buf, sizeof(buf));
remain -= sizeof(buf);
ptr_offset = sizeof(buf);
-
+
while (remain) {
i = read(data_fd, ptr + ptr_offset, remain);
if (i == 0)
@@ -181,8 +193,22 @@ top:
return CUPS_BACKEND_CANCEL;
remain -= i;
ptr_offset += i;
+
+ /* Handle the ambiguous 0x5a block */
+ if (buf[1] == 0x5a && remain == 0) {
+ if (tmphdr[2] == 0x74) { /* plane header */
+ ptr = ctx->plane;
+ remain = 12 - ptr_offset; /* Finish reading */
+ } else if (tmphdr[2] == 0x43) { /* reset memory */
+ ptr = ctx->mem_clr;
+ ctx->mem_clr_present = 1;
+ remain = 4 - ptr_offset;
+ }
+ memcpy(ptr, tmphdr, ptr_offset);
+ buf[1] = 0xff;
+ }
}
-
+
if (ptr == tmphdr) {
if (tmphdr[3] != 46) {
ERROR("Unexpected header chunk: %02x %02x %02x %02x\n",
@@ -239,21 +265,29 @@ static int mitsup95d_main_loop(void *vctx, int copies) {
struct mitsup95d_ctx *ctx = vctx;
uint8_t querycmd[4] = { 0x1b, 0x72, 0x00, 0x00 };
uint8_t queryresp[9];
-
+
int ret;
int num;
if (!ctx)
return CUPS_BACKEND_FAILED;
+ /* P93D is ... special. Windows switches to this halfway through
+ but it seems be okay to use it everywhere */
+ if (ctx->type == P_MITSU_P93D) {
+ querycmd[2] = 0x03;
+ }
+
/* Update printjob header to reflect number of requested copies */
if (ctx->hdr2[13] != 0xff)
ctx->hdr2[13] = copies;
- /* XXX Update unknown header field to match sniffs */
- if (ctx->hdr1[18] == 0x00)
- ctx->hdr1[18] = 0x01;
-
+ if (ctx->type == P_MITSU_P95D) {
+ /* XXX Update unknown header field to match sniffs */
+ if (ctx->hdr1[18] == 0x00)
+ ctx->hdr1[18] = 0x01;
+ }
+
INFO("Waiting for printer idle\n");
/* Query Status to make sure printer is idle */
@@ -263,22 +297,35 @@ static int mitsup95d_main_loop(void *vctx, int copies) {
return CUPS_BACKEND_FAILED;
ret = read_data(ctx->dev, ctx->endp_up,
queryresp, sizeof(queryresp), &num);
- if (num != sizeof(queryresp) || ret < 0) {
+ if (ret < 0)
+ return CUPS_BACKEND_FAILED;
+ if (ctx->type == P_MITSU_P95D && num != 9) {
+ return CUPS_BACKEND_FAILED;
+ } else if (ctx->type == P_MITSU_P93D && num != 8) {
return CUPS_BACKEND_FAILED;
}
- if (queryresp[5] & 0x40) {
- ERROR("Printer error %02x\n", queryresp[5]); // XXX decode
- return CUPS_BACKEND_STOP;
+ if (ctx->type == P_MITSU_P95D) {
+ if (queryresp[5] & 0x40) {
+ ERROR("Printer error %02x\n", queryresp[5]); // XXX decode
+ return CUPS_BACKEND_STOP;
+ }
+ if (queryresp[5] == 0x00)
+ break;
+ } else {
+ if (queryresp[6] == 0x45) {
+ ERROR("Printer error %02x\n", queryresp[7]);
+ return CUPS_BACKEND_STOP;
+ }
+ if (queryresp[6] == 0x30)
+ break;
}
- if (queryresp[5] == 0x00)
- break;
-
+
sleep(1);
} while (1);
INFO("Sending print job\n");
-
+
/* Send over Memory Clear, if present */
if (ctx->mem_clr_present) {
if ((ret = send_data(ctx->dev, ctx->endp_down,
@@ -302,7 +349,7 @@ static int mitsup95d_main_loop(void *vctx, int copies) {
ctx->hdr3, sizeof(ctx->hdr3))))
return CUPS_BACKEND_FAILED;
if ((ret = send_data(ctx->dev, ctx->endp_down,
- ctx->hdr4, sizeof(ctx->hdr4))))
+ ctx->hdr4, ctx->hdr4_len)))
return CUPS_BACKEND_FAILED;
/* Send plane header and image data */
@@ -319,16 +366,38 @@ static int mitsup95d_main_loop(void *vctx, int copies) {
return CUPS_BACKEND_FAILED;
ret = read_data(ctx->dev, ctx->endp_up,
queryresp, sizeof(queryresp), &num);
- if (num != sizeof(queryresp) || ret < 0) {
+
+ if (ret < 0)
+ return CUPS_BACKEND_FAILED;
+ if (ctx->type == P_MITSU_P95D && num != 9) {
+ return CUPS_BACKEND_FAILED;
+ } else if (ctx->type == P_MITSU_P93D && num != 8) {
return CUPS_BACKEND_FAILED;
}
+
if (queryresp[5] & 0x40) {
ERROR("Printer error %02x\n", queryresp[5]); // XXX decode
return CUPS_BACKEND_STOP;
}
- if (queryresp[5] != 0x00) {
- ERROR("Printer not ready (%02x)!\n", queryresp[5]);
- return CUPS_BACKEND_CANCEL;
+
+ if (ctx->type == P_MITSU_P95D) {
+ if (queryresp[5] & 0x40) {
+ ERROR("Printer error %02x\n", queryresp[5]); // XXX decode
+ return CUPS_BACKEND_STOP;
+ }
+ if (queryresp[5] != 0x00) {
+ ERROR("Printer not ready (%02x)!\n", queryresp[5]);
+ return CUPS_BACKEND_CANCEL;
+ }
+ } else {
+ if (queryresp[6] == 0x45) {
+ ERROR("Printer error %02x\n", queryresp[7]);
+ return CUPS_BACKEND_STOP;
+ }
+ if (queryresp[6] != 0x30) {
+ ERROR("Printer not ready (%02x)!\n", queryresp[6]);
+ return CUPS_BACKEND_CANCEL;
+ }
}
/* Send over Footer */
@@ -341,33 +410,53 @@ static int mitsup95d_main_loop(void *vctx, int copies) {
/* Query status until we're done.. */
do {
sleep(1);
-
+
/* Query Status */
if ((ret = send_data(ctx->dev, ctx->endp_down,
querycmd, sizeof(querycmd))))
return CUPS_BACKEND_FAILED;
ret = read_data(ctx->dev, ctx->endp_up,
queryresp, sizeof(queryresp), &num);
- if (num != sizeof(queryresp) || ret < 0) {
+
+ if (ret < 0)
+ return CUPS_BACKEND_FAILED;
+ if (ctx->type == P_MITSU_P95D && num != 9) {
+ return CUPS_BACKEND_FAILED;
+ } else if (ctx->type == P_MITSU_P93D && num != 8) {
return CUPS_BACKEND_FAILED;
}
- if (queryresp[5] & 0x40) {
- ERROR("Printer error %02x\n", queryresp[5]); // XXX decode
- return CUPS_BACKEND_STOP;
- }
- if (queryresp[5] == 0 && queryresp[7] == 0)
- break;
+ if (ctx->type == P_MITSU_P95D) {
+ if (queryresp[5] & 0x40) {
+ ERROR("Printer error %02x\n", queryresp[5]); // XXX decode
+ return CUPS_BACKEND_STOP;
+ }
+ if (queryresp[5] == 0x00)
+ break;
- if (queryresp[7] > 0) {
- if (fast_return) {
- INFO("Fast return mode enabled.\n");
+ if (queryresp[7] > 0) {
+ if (fast_return) {
+ INFO("Fast return mode enabled.\n");
+ break;
+ }
+ }
+ } else {
+ if (queryresp[6] == 0x45) {
+ ERROR("Printer error %02x\n", queryresp[7]);
+ return CUPS_BACKEND_STOP;
+ }
+ if (queryresp[6] == 0x30)
break;
+ if (queryresp[6] == 0x43 && queryresp[7] > 0) {
+ if (fast_return) {
+ INFO("Fast return mode enabled.\n");
+ break;
+ }
}
}
} while(1);
-
- INFO("Print complete\n");
+
+ INFO("Print complete\n");
return CUPS_BACKEND_OK;
}
@@ -392,8 +481,8 @@ static int mitsup95d_cmdline_arg(void *vctx, int argc, char **argv)
/* Exported */
struct dyesub_backend mitsup95d_backend = {
- .name = "Mitsubishi P95D",
- .version = "0.02",
+ .name = "Mitsubishi P93D/P95D",
+ .version = "0.05",
.uri_prefix = "mitsup95d",
.cmdline_arg = mitsup95d_cmdline_arg,
.init = mitsup95d_init,
@@ -402,6 +491,7 @@ struct dyesub_backend mitsup95d_backend = {
.read_parse = mitsup95d_read_parse,
.main_loop = mitsup95d_main_loop,
.devices = {
+ { USB_VID_MITSU, USB_PID_MITSU_P93D, P_MITSU_P93D, ""},
{ USB_VID_MITSU, USB_PID_MITSU_P95D, P_MITSU_P95D, ""},
{ 0, 0, 0, ""}
}
@@ -409,7 +499,7 @@ struct dyesub_backend mitsup95d_backend = {
/*****************************************************
- Mitsubishi P95D Spool Format
+ Mitsubishi P93D/P95D Spool Format
...All fields are BIG ENDIAN.
@@ -423,22 +513,31 @@ struct dyesub_backend mitsup95d_backend = {
PRINT_SETUP
- 1b 57 20 2e 00 0a 00 02 00 00 00 00 00 00 CC CC
+ 1b 57 20 2e 00 0a 00 ZZ 00 00 00 00 00 00 CC CC
RR RR XX 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00
- XX == 01 seen in sniffs, 00 seen in dumps. Unknown!
+ XX == 01 seen in sniffs, 00 seen in dumps. Unknown purpose.
+ ZZ == 00 on P93D, 02 on P95D
CC CC = columns, RR RR = rows (print dimensions)
PRINT_OPTIONS
+ P95:
1b 57 21 2e 00 4a aa 00 20 TT 00 00 64 NN 00 MM
[[ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 ]] 00 00 00 02 00 00 00 00 00 00 00 00 00 00
00 XY
+
+ P93:
+
+ 1b 57 21 2e 00 4a aa 00 00 TT 00 00 00 NN 00 MM
+ [[ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 ]] 00 00 00 02 00 00 00 00 00 00 00 00 00 00
+ 00 XY
NN = copies
1..200
@@ -449,19 +548,29 @@ struct dyesub_backend mitsup95d_backend = {
02 = Date
03 = DateTime
[[ .. ]] = actual comment (18 bytes), see below.
+
TT = media type
+
+ P95D:
+
00 = Standard
01 = High Density
02 = High Glossy
03 = High Glossy (K95HG)
- X = media cut length
+
+ P93D:
+
+ 00 = High Density
+ 01 = High Glossy
+ 02 = Standard
+
+ X = media cut length (P95D ONLY. P93 is 0)
4..8 (mm)
Y = flags
0x04 = Paper save
0x03 = Buzzer (3 = high, 2 = low, 0 = off)
-
- GAMMA ????
+ GAMMA (P95)
1b 57 22 2e 00 15 TT 00 00 00 00 00 LL BB CC 00
[[ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@@ -479,7 +588,20 @@ struct dyesub_backend mitsup95d_backend = {
01 = Yes
[[ .. ]] = Gamma table, loaded from LUT on disk. (skip first 16 bytes)
- USER_COMMENT
+ GAMMA (P93)
+
+ 1b 57 22 2e 00 d5 00 00 00 00 00 00 SS 00 LL 00
+ BB 00 CC 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00
+
+ SS = Sharpening (0 = low, 1 = normal, 2 = high)
+ LL = Gamma table
+ 00..04 Gamma table 1..5
+ BB = Brightness (signed 8-bit)
+ CC = Contrast (signed 8-bit)
+
+ USER_COMMENT (P95)
1b 58 [[ 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
@@ -488,6 +610,15 @@ struct dyesub_backend mitsup95d_backend = {
[[ .. ]] = Actual comment. 34 bytes payload, 0x20 -> 0x7e
(Null terminated?)
+ USER_COMMENT (P93)
+
+ 1b 58 [[ 20 20 20 20 20 20 20 20 20 20 20 20 20
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
+ 20 20 20 20 20 20 20 20 20 20 ]]
+
+ [[ .. ]] = Actual comment. 40 bytes payload, 0x20 -> 0x7e
+ (Null terminated?)
+
IMAGE_DATA
1b 5a 74 00 00 00 YY YY CC CC RR RR
@@ -505,7 +636,7 @@ struct dyesub_backend mitsup95d_backend = {
*********************************
- Printer Comms:
+ P95D Printer Comms:
STATUS query
@@ -524,13 +655,32 @@ struct dyesub_backend mitsup95d_backend = {
^
\--- 0x40 appears to be a flag that indicates error.
+ P93D Printer Comms:
+
+ STATUS query
+
+ -> 1b 72 0? 00
+ <- e4 72 0? 00 03 XX YY ZZ
+
+ ? could be 0x00 or 0x03. Seen both.
+
+Seen: 30 30 30
+ 30 43 01 <- 1 copies remaining
+ 30 43 00 <- 0 copies remaining
+ ^^
+ \-- 30 == idle, 43 == printing
+
+ 30 45 6f <- door open
+ 30 45 50 <- no paper
+
+ 45 == error?
****************************
UNKNOWNS:
* How multiple images are stacked for printing on a single page
- (col offset too? write four, then tell PRINT?) Is this the mystery 0x01?
- * How to adjust printer sharpness?
+ (col offset too? write four, then tell PRINT?)
+ * How to adjust P95D printer sharpness?
* Serial number query (iSerial appears bogus)
* What "custom gamma" table does to spool file?
diff --git a/src/cups/backend_shinkos1245.c b/src/cups/backend_shinkos1245.c
index 1b24797..b92b275 100644
--- a/src/cups/backend_shinkos1245.c
+++ b/src/cups/backend_shinkos1245.c
@@ -1,7 +1,7 @@
/*
* Shinko/Sinfonia CHC-S1245 CUPS backend -- libusb-1.0 version
*
- * (c) 2015-2016 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2015-2017 Solomon Peachy <pizza@shaftnet.org>
*
* Low-level documentation was provided by Sinfonia, Inc. Thank you!
*
@@ -135,7 +135,7 @@ struct shinkos1245_resp_status {
uint8_t status1;
uint32_t status2; /* BE */
uint8_t error;
- } state;
+ } __attribute__((packed)) state;
struct {
uint32_t lifetime; /* BE */
uint32_t maint; /* BE */
@@ -145,13 +145,13 @@ struct shinkos1245_resp_status {
uint8_t ver_boot;
uint8_t ver_ctrl;
uint8_t control_flag; // 0x00 == epson, 0x01 == cypress
- } counters;
+ } __attribute__((packed)) counters;
struct {
uint16_t main_boot;
uint16_t main_control;
uint16_t dsp_boot;
uint16_t dsp_control;
- } versions;
+ } __attribute__((packed)) versions;
struct {
uint8_t bank1_id;
uint8_t bank2_id;
@@ -161,7 +161,7 @@ struct shinkos1245_resp_status {
uint16_t bank2_remain; /* BE */
uint16_t bank2_complete; /* BE */
uint16_t bank2_spec; /* BE */
- } counters2;
+ } __attribute__((packed)) counters2;
uint8_t curve_status;
} __attribute__((packed));
@@ -191,14 +191,15 @@ enum {
WAIT_STATUS2_BUSY = 4,
};
-#define ERROR_STATUS2_CTRL_CIRCUIT (1<<31)
-#define ERROR_STATUS2_MECHANISM_CTRL (1<<30)
-#define ERROR_STATUS2_SENSOR (1<<13)
-#define ERROR_STATUS2_COVER_OPEN (1<<12)
-#define ERROR_STATUS2_TEMP_SENSOR (1<<9)
-#define ERROR_STATUS2_PAPER_JAM (1<<8)
-#define ERROR_STATUS2_PAPER_EMPTY (1<<6)
-#define ERROR_STATUS2_RIBBON_ERR (1<<4)
+
+#define ERROR_STATUS2_CTRL_CIRCUIT (0x80000000)
+#define ERROR_STATUS2_MECHANISM_CTRL (0x40000000)
+#define ERROR_STATUS2_SENSOR (0x00002000)
+#define ERROR_STATUS2_COVER_OPEN (0x00001000)
+#define ERROR_STATUS2_TEMP_SENSOR (0x00000200)
+#define ERROR_STATUS2_PAPER_JAM (0x00000100)
+#define ERROR_STATUS2_PAPER_EMPTY (0x00000040)
+#define ERROR_STATUS2_RIBBON_ERR (0x00000010)
enum {
CTRL_CIR_ERROR_EEPROM1 = 0x01,
@@ -291,7 +292,7 @@ struct shinkos1245_mediadesc {
struct shinkos1245_resp_media {
uint8_t code;
- uint8_t reserved[5];
+ uint8_t reserved[6];
uint8_t count; /* 1-5? */
struct shinkos1245_mediadesc data[NUM_MEDIAS];
} __attribute__((packed));
@@ -399,7 +400,7 @@ struct shinkos1245_resp_matte {
#define MATTE_MODE_MATTE 0x00
-/* Private data stucture */
+/* Private data structure */
struct shinkos1245_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -1536,7 +1537,7 @@ top:
cmd.mode = (ctx->hdr.mode & 0x3f) || ((ctx->hdr.dust & 0x3) << 6);
cmd.combo = ctx->hdr.method;
- /* Issue print commmand */
+ /* Issue print command */
i = shinkos1245_do_cmd(ctx, &cmd, sizeof(cmd),
&status1, sizeof(status1),
&num);
@@ -1639,7 +1640,7 @@ static int shinkos1245_query_serno(struct libusb_device_handle *dev, uint8_t end
struct dyesub_backend shinkos1245_backend = {
.name = "Shinko/Sinfonia CHC-S1245",
- .version = "0.11WIP",
+ .version = "0.13WIP",
.uri_prefix = "shinkos1245",
.cmdline_usage = shinkos1245_cmdline,
.cmdline_arg = shinkos1245_cmdline_arg,
diff --git a/src/cups/backend_shinkos2145.c b/src/cups/backend_shinkos2145.c
index ec7bcd6..d56ca2f 100644
--- a/src/cups/backend_shinkos2145.c
+++ b/src/cups/backend_shinkos2145.c
@@ -90,7 +90,7 @@ struct s2145_printjob_hdr {
uint32_t unk21;
} __attribute__((packed));
-/* Private data stucture */
+/* Private data structure */
struct shinkos2145_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -591,7 +591,7 @@ static char *error_str(uint8_t v) {
case ERROR_COMMS_TIMEOUT:
return "Main Communication Timeout";
case ERROR_MAINT_NEEDED:
- return "Maintainence Needed";
+ return "Maintenance Needed";
case ERROR_BAD_COMMAND:
return "Inappropriate Command";
case ERROR_PRINTER:
@@ -878,7 +878,7 @@ static int get_status(struct shinkos2145_ctx *ctx)
INFO(" Print Counts:\n");
INFO("\tSince Paper Changed:\t%08u\n", le32_to_cpu(resp->count_paper));
INFO("\tLifetime:\t\t%08u\n", le32_to_cpu(resp->count_lifetime));
- INFO("\tMaintainence:\t\t%08u\n", le32_to_cpu(resp->count_maint));
+ INFO("\tMaintenance:\t\t%08u\n", le32_to_cpu(resp->count_maint));
INFO("\tPrint Head:\t\t%08u\n", le32_to_cpu(resp->count_head));
INFO(" Cutter Actuations:\t%08u\n", le32_to_cpu(resp->count_cutter));
INFO(" Ribbon Remaining:\t%08u\n", le32_to_cpu(resp->count_ribbon_left));
diff --git a/src/cups/backend_shinkos6145.c b/src/cups/backend_shinkos6145.c
index 692a42c..e8d39b4 100644
--- a/src/cups/backend_shinkos6145.c
+++ b/src/cups/backend_shinkos6145.c
@@ -130,7 +130,7 @@ struct s6145_printjob_hdr {
uint32_t unk19;
uint32_t unk20;
- uint32_t unk21;
+ uint32_t ext_flags; /* 0x00 in the official headers. 0x01 to mark inout data as YMC planar */
} __attribute__((packed));
/* "Image Correction Parameter" File */
@@ -259,7 +259,7 @@ struct shinkos6145_correctionparam {
uint8_t pad[3948]; // @12436, null.
} __attribute__((packed)); /* 16384 bytes */
-/* Private data stucture */
+/* Private data structure */
struct shinkos6145_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -276,7 +276,8 @@ struct shinkos6145_ctx {
size_t datalen;
uint8_t ribbon_type;
-
+ uint8_t input_ymc;
+
uint16_t last_donor;
uint16_t last_remain;
uint16_t last_ribbon;
@@ -365,7 +366,7 @@ static char *cmd_names(uint16_t v) {
default:
return "Unknown Command";
}
-};
+}
struct s6145_print_cmd {
struct s6145_cmd_hdr hdr;
@@ -780,7 +781,7 @@ static char *error_str(uint8_t v) {
case ERROR_COMMS_TIMEOUT:
return "Main Communication Timeout";
case ERROR_MAINT_NEEDED:
- return "Maintainence Needed";
+ return "Maintenance Needed";
case ERROR_BAD_COMMAND:
return "Inappropriate Command";
case ERROR_PRINTER:
@@ -1194,7 +1195,7 @@ static int get_status(struct shinkos6145_ctx *ctx)
INFO(" Print Counts:\n");
INFO("\tSince Paper Changed:\t%08u\n", le32_to_cpu(resp->count_paper));
INFO("\tLifetime:\t\t%08u\n", le32_to_cpu(resp->count_lifetime));
- INFO("\tMaintainence:\t\t%08u\n", le32_to_cpu(resp->count_maint));
+ INFO("\tMaintenance:\t\t%08u\n", le32_to_cpu(resp->count_maint));
INFO("\tPrint Head:\t\t%08u\n", le32_to_cpu(resp->count_head));
INFO(" Cutter Actuations:\t%08u\n", le32_to_cpu(resp->count_cutter));
INFO(" Ribbon Remaining:\t%08u\n", le32_to_cpu(resp->count_ribbon_left));
@@ -1229,7 +1230,7 @@ static int get_status(struct shinkos6145_ctx *ctx)
return -1;
INFO("Lifetime Distance: %08u inches\n", le32_to_cpu(resp2->lifetime_distance));
- INFO("Maintainence Distance: %08u inches\n", le32_to_cpu(resp2->maint_distance));
+ INFO("Maintenance Distance: %08u inches\n", le32_to_cpu(resp2->maint_distance));
INFO("Head Distance: %08u inches\n", le32_to_cpu(resp2->head_distance));
/* Query various params */
@@ -2097,11 +2098,17 @@ static int shinkos6145_read_parse(void *vctx, int data_fd) {
return CUPS_BACKEND_CANCEL;
}
+ /* Extended spool format to re-purpose an unused header field.
+ When bit 0 is set, this tells the backend that the data is
+ already in planar YMC format (vs packed RGB) so we don't need
+ to do the conversion ourselves. Saves some processing overhead */
+ ctx->input_ymc = le32_to_cpu(ctx->hdr.ext_flags) & 0x01;
+
if (ctx->databuf) {
free(ctx->databuf);
ctx->databuf = NULL;
}
-
+
ctx->datalen = le32_to_cpu(ctx->hdr.rows) * le32_to_cpu(ctx->hdr.columns) * 3;
ctx->databuf = malloc(ctx->datalen);
if (!ctx->databuf) {
@@ -2320,10 +2327,8 @@ top:
ctx->corrdata->width = cpu_to_le16(le32_to_cpu(ctx->hdr.columns));
ctx->corrdata->height = cpu_to_le16(le32_to_cpu(ctx->hdr.rows));
- /* Convert packed RGB to planar YMC */
- // XXX would it make more sense to have Gutenprint generate
- // planar YMC data as an extension of the spooler format?
- {
+ /* Convert packed RGB to planar YMC if necessary */
+ if (!ctx->input_ymc) {
int planelen = le16_to_cpu(ctx->corrdata->width) * le16_to_cpu(ctx->corrdata->height);
uint8_t *databuf3 = malloc(ctx->datalen);
@@ -2483,7 +2488,7 @@ static int shinkos6145_query_serno(struct libusb_device_handle *dev, uint8_t end
struct dyesub_backend shinkos6145_backend = {
.name = "Shinko/Sinfonia CHC-S6145",
- .version = "0.21",
+ .version = "0.22",
.uri_prefix = "shinkos6145",
.cmdline_usage = shinkos6145_cmdline,
.cmdline_arg = shinkos6145_cmdline_arg,
diff --git a/src/cups/backend_shinkos6245.c b/src/cups/backend_shinkos6245.c
index b5b1c2b..414d55a 100644
--- a/src/cups/backend_shinkos6245.c
+++ b/src/cups/backend_shinkos6245.c
@@ -90,7 +90,7 @@ struct s6245_printjob_hdr {
uint32_t unk21;
} __attribute__((packed));
-/* Private data stucture */
+/* Private data structure */
struct shinkos6245_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -612,7 +612,7 @@ static char *error_str(uint8_t v) {
case ERROR_COMMS_TIMEOUT:
return "Main Communication Timeout";
case ERROR_MAINT_NEEDED:
- return "Maintainence Needed";
+ return "Maintenance Needed";
case ERROR_BAD_COMMAND:
return "Inappropriate Command";
case ERROR_PRINTER:
@@ -1003,7 +1003,7 @@ static int get_status(struct shinkos6245_ctx *ctx)
INFO(" Print Counts:\n");
INFO("\tSince Paper Changed:\t%08u\n", le32_to_cpu(resp->count_paper));
INFO("\tLifetime:\t\t%08u\n", le32_to_cpu(resp->count_lifetime));
- INFO("\tMaintainence:\t\t%08u\n", le32_to_cpu(resp->count_maint));
+ INFO("\tMaintenance:\t\t%08u\n", le32_to_cpu(resp->count_maint));
INFO("\tPrint Head:\t\t%08u\n", le32_to_cpu(resp->count_head));
INFO(" Cutter Actuations:\t%08u\n", le32_to_cpu(resp->count_cutter));
INFO(" Ribbon Remaining:\t%08u\n", le32_to_cpu(resp->count_ribbon_left));
@@ -1038,7 +1038,7 @@ static int get_status(struct shinkos6245_ctx *ctx)
return 0;
INFO("Lifetime Distance: %08u inches\n", le32_to_cpu(resp2->lifetime_distance));
- INFO("Maintainence Distance: %08u inches\n", le32_to_cpu(resp2->maint_distance));
+ INFO("Maintenance Distance: %08u inches\n", le32_to_cpu(resp2->maint_distance));
INFO("Head Distance: %08u inches\n", le32_to_cpu(resp2->head_distance));
return 0;
diff --git a/src/cups/backend_sonyupdr150.c b/src/cups/backend_sonyupdr150.c
index be8423f..a914d3f 100644
--- a/src/cups/backend_sonyupdr150.c
+++ b/src/cups/backend_sonyupdr150.c
@@ -45,7 +45,7 @@
#define USB_PID_SONY_UPDR200 0x035F
#define USB_PID_SONY_UPCR10 0x0226
-/* Private data stucture */
+/* Private data structure */
struct updr150_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
diff --git a/src/cups/blacklist b/src/cups/blacklist
index b0ddd2d..191e97d 100644
--- a/src/cups/blacklist
+++ b/src/cups/blacklist
@@ -75,6 +75,9 @@
# Canon SELPHY CP810
0x04a9 0x3256 blacklist
+# Canon SELPHY CP820
+0x04a9 0x327b blacklist
+
# Canon SELPHY CP900
0x04a9 0x3255 blacklist
@@ -178,6 +181,9 @@
# Mitsubishi CP-9810D/DW
0x06d3 0x3b21 blacklist
+# Mitsubishi P93D
+0x06d3 0x0398 blacklist
+
# Mitsubishi P95D
0x06d3 0x3b10 blacklist
diff --git a/src/cups/cups-calibrate.c b/src/cups/cups-calibrate.c
index cc1c789..205157b 100644
--- a/src/cups/cups-calibrate.c
+++ b/src/cups/cups-calibrate.c
@@ -370,7 +370,7 @@ main(int argc,
if (system(lpoptionscommand) == 0)
puts("Calibration profile successfully saved.");
else
- puts("An error occured while saving the calibration profile.");
+ puts("An error occurred while saving the calibration profile.");
return (0);
}
diff --git a/src/cups/genppd.c b/src/cups/genppd.c
index 2121f9d..49c13a9 100644
--- a/src/cups/genppd.c
+++ b/src/cups/genppd.c
@@ -685,6 +685,7 @@ main(int argc, /* I - Number of command-line arguments */
return 1;
}
} while (pid > 0);
+ stp_free(subprocesses);
}
if (parent && !verbose)
fprintf(stderr, " done.\n");
diff --git a/src/cups/rastertoprinter.c b/src/cups/rastertoprinter.c
index 7cc3501..23faa85 100644
--- a/src/cups/rastertoprinter.c
+++ b/src/cups/rastertoprinter.c
@@ -636,8 +636,8 @@ purge_excess_data(cups_image_t *cups)
char *buffer = stp_malloc(cups->header.cupsBytesPerLine);
if (buffer)
{
- if (! suppress_messages)
- fprintf(stderr, "DEBUG: Gutenprint: Purging %d row%s\n",
+ if (! suppress_messages && ! suppress_verbose_messages )
+ fprintf(stderr, "DEBUG2: Gutenprint: Purging %d row%s\n",
cups->header.cupsHeight - cups->row,
((cups->header.cupsHeight - cups->row) == 1 ? "" : "s"));
while (cups->row < cups->header.cupsHeight)
@@ -1298,6 +1298,7 @@ main(int argc, /* I - Number of command-line arguments */
stp_set_float_parameter(default_settings, "AppGamma", 1.0);
set_all_options(default_settings, options, num_options, ppd);
+ cupsFreeOptions(num_options, options);
ppdClose(ppd);
cups.ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
diff --git a/src/cups/test-ppds b/src/cups/test-ppds
index 7d8713c..27e5a8d 100755
--- a/src/cups/test-ppds
+++ b/src/cups/test-ppds
@@ -1,5 +1,23 @@
#!/bin/sh
+# Test PPD conformance
+#
+# Copyright 2006-2017 Robert Krawitz (rlk@alum.mit.edu)
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
# Keeping this up to date with changing CUPS versions is a real headache
make EXTRA_GENPPD_OPTS='-b -Z' ppd-clean ppd-global ppd-nls ppd-nonls
diff --git a/src/cups/test-rastertogutenprint.in b/src/cups/test-rastertogutenprint.in
index c64a8e4..b6a5b70 100755
--- a/src/cups/test-rastertogutenprint.in
+++ b/src/cups/test-rastertogutenprint.in
@@ -1,5 +1,23 @@
#!@SHELL@
+# Driver for rastertogutenprint tester.
+#
+# Copyright 2007-2017 Robert Krawitz (rlk@alum.mit.edu)
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
retval=0
if [ -z "$srcdir" -o "$srcdir" = "." ] ; then
@@ -83,7 +101,7 @@ if [ -n "$md5dir" -a ! -d "$md5dir" ] ; then
mkdir -p "$md5dir"
fi
-version="5.2";
+version="@GUTENPRINT_RELEASE_VERSION@";
cupsdir="/usr/lib/cups/filter"
if [ -x "$cupsdir/pstoraster" -o -x "$cupsdir/gstoraster" -o -x "$cupsdir/cgpdftoraster" ] ; then
pages="24-`expr 24 + $npages - 1`"