diff options
author | Didier Raboud <odyx@debian.org> | 2017-06-19 08:38:07 +0200 |
---|---|---|
committer | Didier Raboud <odyx@debian.org> | 2017-06-19 08:38:07 +0200 |
commit | aedf3e93e811c6c9d504274172861d266e1c5c97 (patch) | |
tree | 95e525108c5b6bd2ea3fa689cf11bfe4a5b982a9 /src/cups | |
parent | 7bd83d89975d166521a0b326b64b4cad80117750 (diff) |
New upstream version 5.2.13~pre1
Diffstat (limited to 'src/cups')
-rw-r--r-- | src/cups/Makefile.in | 7 | ||||
-rw-r--r-- | src/cups/backend_canonselphy.c | 81 | ||||
-rw-r--r-- | src/cups/backend_canonselphyneo.c | 38 | ||||
-rw-r--r-- | src/cups/backend_citizencw01.c | 4 | ||||
-rw-r--r-- | src/cups/backend_common.c | 27 | ||||
-rw-r--r-- | src/cups/backend_common.h | 5 | ||||
-rw-r--r-- | src/cups/backend_dnpds40.c | 4 | ||||
-rw-r--r-- | src/cups/backend_kodak1400.c | 4 | ||||
-rw-r--r-- | src/cups/backend_kodak605.c | 4 | ||||
-rw-r--r-- | src/cups/backend_kodak6800.c | 22 | ||||
-rw-r--r-- | src/cups/backend_mitsu70x.c | 268 | ||||
-rw-r--r-- | src/cups/backend_mitsu9550.c | 2 | ||||
-rw-r--r-- | src/cups/backend_mitsup95d.c | 272 | ||||
-rw-r--r-- | src/cups/backend_shinkos1245.c | 35 | ||||
-rw-r--r-- | src/cups/backend_shinkos2145.c | 6 | ||||
-rw-r--r-- | src/cups/backend_shinkos6145.c | 31 | ||||
-rw-r--r-- | src/cups/backend_shinkos6245.c | 8 | ||||
-rw-r--r-- | src/cups/backend_sonyupdr150.c | 2 | ||||
-rw-r--r-- | src/cups/blacklist | 6 | ||||
-rw-r--r-- | src/cups/cups-calibrate.c | 2 | ||||
-rw-r--r-- | src/cups/genppd.c | 1 | ||||
-rw-r--r-- | src/cups/rastertoprinter.c | 5 | ||||
-rwxr-xr-x | src/cups/test-ppds | 18 | ||||
-rwxr-xr-x | src/cups/test-rastertogutenprint.in | 20 |
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`" |