diff options
Diffstat (limited to 'src')
33 files changed, 3509 insertions, 475 deletions
diff --git a/src/cups/Makefile.am b/src/cups/Makefile.am index ed3a800..62ce028 100644 --- a/src/cups/Makefile.am +++ b/src/cups/Makefile.am @@ -114,7 +114,7 @@ commandtoepson_SOURCES = commandtoepson.c commandtoepson_LDADD = $(CUPS_LIBS) if BUILD_LIBUSB_BACKENDS -backend_gutenprint_SOURCES = backend_canonselphy.c backend_kodak1400.c backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c backend_sonyupdr150.c backend_dnpds40.c backend_mitsu70x.c backend_citizencw01.c backend_mitsu9550.c backend_common.c backend_common.h backend_shinkos1245.c backend_shinkos6145.c backend_shinkos6245.c +backend_gutenprint_SOURCES = backend_canonselphy.c backend_canonselphyneo.c backend_kodak1400.c backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c backend_sonyupdr150.c backend_dnpds40.c backend_mitsu70x.c backend_citizencw01.c backend_mitsu9550.c backend_common.c backend_common.h backend_shinkos1245.c backend_shinkos6145.c backend_shinkos6245.c backend_mitsup95d.c backend_gutenprint_LDADD = $(LIBUSB_LIBS) $(LIBUSB_BACKEND_LIBDEPS) backend_gutenprint_CPPFLAGS = $(LIBUSB_CFLAGS) -DURI_PREFIX=\"gutenprint$(GUTENPRINT_MAJOR_VERSION)$(GUTENPRINT_MINOR_VERSION)+usb\" -DLIBUSB_PRE_1_0_10 diff --git a/src/cups/Makefile.in b/src/cups/Makefile.in index fcb9787..cf76ab2 100644 --- a/src/cups/Makefile.in +++ b/src/cups/Makefile.in @@ -125,12 +125,14 @@ PROGRAMS = $(bin_PROGRAMS) $(cupsexec_backend_PROGRAMS) \ $(cupsexec_driver_PROGRAMS) $(cupsexec_filter_PROGRAMS) \ $(sbin_PROGRAMS) am__backend_gutenprint_SOURCES_DIST = backend_canonselphy.c \ - backend_kodak1400.c backend_kodak6800.c backend_kodak605.c \ - backend_shinkos2145.c backend_sonyupdr150.c backend_dnpds40.c \ - backend_mitsu70x.c backend_citizencw01.c backend_mitsu9550.c \ - backend_common.c backend_common.h backend_shinkos1245.c \ - backend_shinkos6145.c backend_shinkos6245.c + backend_canonselphyneo.c backend_kodak1400.c \ + backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c \ + backend_sonyupdr150.c backend_dnpds40.c backend_mitsu70x.c \ + backend_citizencw01.c backend_mitsu9550.c backend_common.c \ + backend_common.h backend_shinkos1245.c backend_shinkos6145.c \ + backend_shinkos6245.c backend_mitsup95d.c @BUILD_LIBUSB_BACKENDS_TRUE@am_backend_gutenprint_OBJECTS = backend_gutenprint-backend_canonselphy.$(OBJEXT) \ +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_canonselphyneo.$(OBJEXT) \ @BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_kodak1400.$(OBJEXT) \ @BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_kodak6800.$(OBJEXT) \ @BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_kodak605.$(OBJEXT) \ @@ -143,7 +145,8 @@ am__backend_gutenprint_SOURCES_DIST = backend_canonselphy.c \ @BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_common.$(OBJEXT) \ @BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_shinkos1245.$(OBJEXT) \ @BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_shinkos6145.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_shinkos6245.$(OBJEXT) +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_shinkos6245.$(OBJEXT) \ +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_mitsup95d.$(OBJEXT) backend_gutenprint_OBJECTS = $(am_backend_gutenprint_OBJECTS) am__DEPENDENCIES_1 = @BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_DEPENDENCIES = \ @@ -721,7 +724,7 @@ commandtocanon_SOURCES = commandtocanon.c commandtocanon_LDADD = $(CUPS_LIBS) commandtoepson_SOURCES = commandtoepson.c commandtoepson_LDADD = $(CUPS_LIBS) -@BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_SOURCES = backend_canonselphy.c backend_kodak1400.c backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c backend_sonyupdr150.c backend_dnpds40.c backend_mitsu70x.c backend_citizencw01.c backend_mitsu9550.c backend_common.c backend_common.h backend_shinkos1245.c backend_shinkos6145.c backend_shinkos6245.c +@BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_SOURCES = backend_canonselphy.c backend_canonselphyneo.c backend_kodak1400.c backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c backend_sonyupdr150.c backend_dnpds40.c backend_mitsu70x.c backend_citizencw01.c backend_mitsu9550.c backend_common.c backend_common.h backend_shinkos1245.c backend_shinkos6145.c backend_shinkos6245.c backend_mitsup95d.c @BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_LDADD = $(LIBUSB_LIBS) $(LIBUSB_BACKEND_LIBDEPS) @BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_CPPFLAGS = $(LIBUSB_CFLAGS) -DURI_PREFIX=\"gutenprint$(GUTENPRINT_MAJOR_VERSION)$(GUTENPRINT_MINOR_VERSION)+usb\" -DLIBUSB_PRE_1_0_10 cups_genppd_@GUTENPRINT_RELEASE_VERSION@_SOURCES = genppd.c i18n.c i18n.h @@ -1111,6 +1114,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_canonselphy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_canonselphyneo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_citizencw01.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_dnpds40.Po@am__quote@ @@ -1119,6 +1123,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_kodak6800.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_mitsu70x.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_mitsu9550.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_mitsup95d.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_shinkos1245.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_shinkos2145.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_shinkos6145.Po@am__quote@ @@ -1169,6 +1174,20 @@ backend_gutenprint-backend_canonselphy.obj: backend_canonselphy.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_canonselphy.obj `if test -f 'backend_canonselphy.c'; then $(CYGPATH_W) 'backend_canonselphy.c'; else $(CYGPATH_W) '$(srcdir)/backend_canonselphy.c'; fi` +backend_gutenprint-backend_canonselphyneo.o: backend_canonselphyneo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_canonselphyneo.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_canonselphyneo.Tpo -c -o backend_gutenprint-backend_canonselphyneo.o `test -f 'backend_canonselphyneo.c' || echo '$(srcdir)/'`backend_canonselphyneo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_canonselphyneo.Tpo $(DEPDIR)/backend_gutenprint-backend_canonselphyneo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_canonselphyneo.c' object='backend_gutenprint-backend_canonselphyneo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_canonselphyneo.o `test -f 'backend_canonselphyneo.c' || echo '$(srcdir)/'`backend_canonselphyneo.c + +backend_gutenprint-backend_canonselphyneo.obj: backend_canonselphyneo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_canonselphyneo.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_canonselphyneo.Tpo -c -o backend_gutenprint-backend_canonselphyneo.obj `if test -f 'backend_canonselphyneo.c'; then $(CYGPATH_W) 'backend_canonselphyneo.c'; else $(CYGPATH_W) '$(srcdir)/backend_canonselphyneo.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_canonselphyneo.Tpo $(DEPDIR)/backend_gutenprint-backend_canonselphyneo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_canonselphyneo.c' object='backend_gutenprint-backend_canonselphyneo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_canonselphyneo.obj `if test -f 'backend_canonselphyneo.c'; then $(CYGPATH_W) 'backend_canonselphyneo.c'; else $(CYGPATH_W) '$(srcdir)/backend_canonselphyneo.c'; fi` + backend_gutenprint-backend_kodak1400.o: backend_kodak1400.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_kodak1400.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_kodak1400.Tpo -c -o backend_gutenprint-backend_kodak1400.o `test -f 'backend_kodak1400.c' || echo '$(srcdir)/'`backend_kodak1400.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_kodak1400.Tpo $(DEPDIR)/backend_gutenprint-backend_kodak1400.Po @@ -1351,6 +1370,20 @@ backend_gutenprint-backend_shinkos6245.obj: backend_shinkos6245.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_shinkos6245.obj `if test -f 'backend_shinkos6245.c'; then $(CYGPATH_W) 'backend_shinkos6245.c'; else $(CYGPATH_W) '$(srcdir)/backend_shinkos6245.c'; fi` +backend_gutenprint-backend_mitsup95d.o: backend_mitsup95d.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_mitsup95d.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_mitsup95d.Tpo -c -o backend_gutenprint-backend_mitsup95d.o `test -f 'backend_mitsup95d.c' || echo '$(srcdir)/'`backend_mitsup95d.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_mitsup95d.Tpo $(DEPDIR)/backend_gutenprint-backend_mitsup95d.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_mitsup95d.c' object='backend_gutenprint-backend_mitsup95d.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_mitsup95d.o `test -f 'backend_mitsup95d.c' || echo '$(srcdir)/'`backend_mitsup95d.c + +backend_gutenprint-backend_mitsup95d.obj: backend_mitsup95d.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_mitsup95d.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_mitsup95d.Tpo -c -o backend_gutenprint-backend_mitsup95d.obj `if test -f 'backend_mitsup95d.c'; then $(CYGPATH_W) 'backend_mitsup95d.c'; else $(CYGPATH_W) '$(srcdir)/backend_mitsup95d.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_mitsup95d.Tpo $(DEPDIR)/backend_gutenprint-backend_mitsup95d.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_mitsup95d.c' object='backend_gutenprint-backend_mitsup95d.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_mitsup95d.obj `if test -f 'backend_mitsup95d.c'; then $(CYGPATH_W) 'backend_mitsup95d.c'; else $(CYGPATH_W) '$(srcdir)/backend_mitsup95d.c'; fi` + cups_genppd_@GUTENPRINT_RELEASE_VERSION@-genppd.o: genppd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_genppd_@GUTENPRINT_RELEASE_VERSION@_CFLAGS) $(CFLAGS) -MT cups_genppd_@GUTENPRINT_RELEASE_VERSION@-genppd.o -MD -MP -MF $(DEPDIR)/cups_genppd_@GUTENPRINT_RELEASE_VERSION@-genppd.Tpo -c -o cups_genppd_@GUTENPRINT_RELEASE_VERSION@-genppd.o `test -f 'genppd.c' || echo '$(srcdir)/'`genppd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cups_genppd_@GUTENPRINT_RELEASE_VERSION@-genppd.Tpo $(DEPDIR)/cups_genppd_@GUTENPRINT_RELEASE_VERSION@-genppd.Po diff --git a/src/cups/backend_canonselphy.c b/src/cups/backend_canonselphy.c index 4da082a..4d7e6d0 100644 --- a/src/cups/backend_canonselphy.c +++ b/src/cups/backend_canonselphy.c @@ -561,6 +561,20 @@ struct canonselphy_ctx { uint8_t cp900; }; +static int canonselphy_send_reset(struct canonselphy_ctx *ctx) +{ + uint8_t rstcmd[12] = { 0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + int ret; + + if ((ret = send_data(ctx->dev, ctx->endp_down, + rstcmd, sizeof(rstcmd)))) + return CUPS_BACKEND_FAILED; + + return CUPS_BACKEND_OK; +} + static void *canonselphy_init(void) { struct canonselphy_ctx *ctx = malloc(sizeof(struct canonselphy_ctx)); @@ -1016,9 +1030,12 @@ static int canonselphy_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL)) >= 0) { + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "R")) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL + case 'R': + canonselphy_send_reset(ctx); + break; } if (j) return j; @@ -1027,10 +1044,16 @@ static int canonselphy_cmdline_arg(void *vctx, int argc, char **argv) return 0; } +static void canonselphy_cmdline(void) +{ + DEBUG("\t\t[ -R ] # Reset printer\n"); +} + struct dyesub_backend canonselphy_backend = { .name = "Canon SELPHY CP/ES", - .version = "0.91", + .version = "0.92", .uri_prefix = "canonselphy", + .cmdline_usage = canonselphy_cmdline, .cmdline_arg = canonselphy_cmdline_arg, .init = canonselphy_init, .attach = canonselphy_attach, diff --git a/src/cups/backend_canonselphyneo.c b/src/cups/backend_canonselphyneo.c new file mode 100644 index 0000000..c29cbe6 --- /dev/null +++ b/src/cups/backend_canonselphyneo.c @@ -0,0 +1,491 @@ +/* + * Canon SELPHY CPneo series CUPS backend -- libusb-1.0 version + * + * (c) 2016 Solomon Peachy <pizza@shaftnet.org> + * + * The latest version of this program can be found at: + * + * http://git.shaftnet.org/cgit/selphy_print.git + * + * 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. + * + * [http://www.gnu.org/licenses/gpl-2.0.html] + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <signal.h> + +#define BACKEND canonselphyneo_backend + +#include "backend_common.h" + +/* Exported */ +#define USB_VID_CANON 0x04a9 +#define USB_PID_CANON_CP820 XXX +#define USB_PID_CANON_CP910 0x327a +#define USB_PID_CANON_CP1000 0x32ae +#define USB_PID_CANON_CP1200 0x32b1 + +/* Header data structure */ +struct selphyneo_hdr { + uint8_t data[24]; + uint32_t cols; /* LE */ + uint32_t rows; /* LE */ +} __attribute((packed)); + +/* Readback data structure */ +struct selphyneo_readback { + uint8_t data[12]; +} __attribute((packed)); + +/* Private data stucture */ +struct selphyneo_ctx { + struct libusb_device_handle *dev; + uint8_t endp_up; + uint8_t endp_down; + + uint8_t *databuf; + uint32_t datalen; +}; + +static char *selphyneo_statuses(uint8_t sts) +{ + switch(sts) { + case 0x01: + return "Idle"; + case 0x02: + return "Feeding Paper"; + case 0x04: + return "Printing YELLOW"; + case 0x08: + return "Printing MAGENTA"; + case 0x10: + return "Printing CYAN"; + case 0x20: + return "Printing LAMINATE"; + default: + return "Unknown state!"; + } +} + +static char *selphyneo_errors(uint8_t err) +{ + switch(err) { + case 0x00: + return "None"; + case 0x02: + return "Paper Feed"; + case 0x03: + return "No Paper"; + case 0x07: + return "No Ink"; + case 0x09: + return "No Paper and Ink"; + case 0x0A: + return "Incorrect media for job"; + default: + return "Unknown Error"; + } +} + +static char *selphynew_pgcodes(uint8_t type) { + + switch (type & 0xf) { + case 0x01: + return "P"; + case 0x02: + return "L"; + case 0x03: + return "C"; + case 0x00: + return "None"; + default: + return "Unknown"; + } +} + +static int selphyneo_send_reset(struct selphyneo_ctx *ctx) +{ + uint8_t rstcmd[12] = { 0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + int ret; + + if ((ret = send_data(ctx->dev, ctx->endp_down, + rstcmd, sizeof(rstcmd)))) + return CUPS_BACKEND_FAILED; + + return CUPS_BACKEND_OK; +} + +static void *selphyneo_init(void) +{ + struct selphyneo_ctx *ctx = malloc(sizeof(struct selphyneo_ctx)); + if (!ctx) { + ERROR("Memory Allocation Failure!\n"); + return NULL; + } + memset(ctx, 0, sizeof(struct selphyneo_ctx)); + + return ctx; +} + +extern struct dyesub_backend selphyneo_backend; + +static void selphyneo_attach(void *vctx, struct libusb_device_handle *dev, + uint8_t endp_up, uint8_t endp_down, uint8_t jobid) +{ + struct selphyneo_ctx *ctx = vctx; + struct libusb_device *device; + struct libusb_device_descriptor desc; + + UNUSED(jobid); + + ctx->dev = dev; + ctx->endp_up = endp_up; + ctx->endp_down = endp_down; + + device = libusb_get_device(dev); + libusb_get_device_descriptor(device, &desc); +} + +static void selphyneo_teardown(void *vctx) { + struct selphyneo_ctx *ctx = vctx; + + if (!ctx) + return; + + if (ctx->databuf) + free(ctx->databuf); + + free(ctx); +} + +static int selphyneo_read_parse(void *vctx, int data_fd) +{ + struct selphyneo_ctx *ctx = vctx; + struct selphyneo_hdr hdr; + int i, remain; + + if (!ctx) + return CUPS_BACKEND_FAILED; + + /* Read the header.. */ + i = read(data_fd, &hdr, sizeof(hdr)); + if (i != sizeof(hdr)) { + if (i == 0) + return CUPS_BACKEND_CANCEL; + ERROR("Read failed (%d/%d)\n", + i, (int)sizeof(hdr)); + perror("ERROR: Read failed"); + return CUPS_BACKEND_FAILED; + } + + /* Determine job length */ + switch(hdr.data[18]) { + case 0x50: /* P */ + case 0x4c: /* L */ + case 0x43: /* C */ + remain = le32_to_cpu(hdr.cols) * le32_to_cpu(hdr.rows) * 3; + break; + default: + ERROR("Unknown print size! (%02x, %ux%u)\n", + hdr.data[10], le32_to_cpu(hdr.cols), le32_to_cpu(hdr.rows)); + return CUPS_BACKEND_CANCEL; + } + + /* Allocate a buffer */ + ctx->datalen = 0; + ctx->databuf = malloc(remain + sizeof(hdr)); + if (!ctx->databuf) { + ERROR("Memory allocation failure!\n"); + return CUPS_BACKEND_FAILED; + } + + /* Store the read-in header */ + memcpy(ctx->databuf, &hdr, sizeof(hdr)); + ctx->datalen += sizeof(hdr); + + /* Read in data */ + while (remain > 0) { + i = read(data_fd, ctx->databuf + ctx->datalen, remain); + if (i < 0) + return CUPS_BACKEND_CANCEL; + remain -= i; + ctx->datalen += i; + } + + return CUPS_BACKEND_OK; +} + +static int selphyneo_main_loop(void *vctx, int copies) { + struct selphyneo_ctx *ctx = vctx; + struct selphyneo_readback rdback; + + int ret, num; + + /* Read in the printer status to clear last state */ + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) &rdback, sizeof(rdback), &num); + + /* And again, for the markers */ + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) &rdback, sizeof(rdback), &num); + + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='%s'\n", selphynew_pgcodes(rdback.data[6])); + + ATTR("marker-types=ribbonWax\n"); + +top: + INFO("Waiting for printer idle\n"); + + do { + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) &rdback, sizeof(rdback), &num); + + if (ret < 0) + return CUPS_BACKEND_FAILED; + + if (rdback.data[0] == 0x01) + break; + + INFO("Printer state: %s\n", selphyneo_statuses(rdback.data[0])); + + switch (rdback.data[2]) { + case 0x00: + break; + case 0x0A: + ERROR("Printer error: %s (%02x)\n", selphyneo_errors(rdback.data[2]), rdback.data[2]); + ATTR("marker-levels=%d\n", 0); + return CUPS_BACKEND_CANCEL; + default: + ERROR("Printer error: %s (%02x)\n", selphyneo_errors(rdback.data[2]), rdback.data[2]); + ATTR("marker-levels=%d\n", 0); + return CUPS_BACKEND_STOP; + } + + sleep(1); + } while(1); + + ATTR("marker-levels=%d\n", -3); /* ie Unknown but OK */ + + INFO("Sending spool data\n"); + /* Send the data over in 256K chunks */ + { + int chunk = 256*1024; + int sent = 0; + while (chunk > 0) { + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->databuf + sent, chunk))) + return CUPS_BACKEND_FAILED; + sent += chunk; + chunk = ctx->datalen - sent; + if (chunk > 256*1024) + chunk = 256*1024; + } + } + + /* Read in the printer status to clear last state */ + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) &rdback, sizeof(rdback), &num); + + INFO("Waiting for printer acknowledgement\n"); + do { + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) &rdback, sizeof(rdback), &num); + + if (ret < 0) + return CUPS_BACKEND_FAILED; + + if (rdback.data[0] == 0x01) + break; + + INFO("Printer state: %s\n", selphyneo_statuses(rdback.data[0])); + + switch (rdback.data[2]) { + case 0x00: + break; + case 0x0A: + ERROR("Printer error: %s (%02x)\n", selphyneo_errors(rdback.data[2]), rdback.data[2]); + ATTR("marker-levels=%d\n", 0); + return CUPS_BACKEND_CANCEL; + default: + ERROR("Printer error: %s (%02x)\n", selphyneo_errors(rdback.data[2]), rdback.data[2]); + ATTR("marker-levels=%d\n", 0); + return CUPS_BACKEND_STOP; + } + + if (rdback.data[0] > 0x02 && fast_return) { + INFO("Fast return mode enabled.\n"); + break; + } + + sleep(1); + } while(1); + + /* Clean up */ + if (terminate) + copies = 1; + + INFO("Print complete (%d copies remaining)\n", copies - 1); + + if (copies && --copies) { + goto top; + } + + return CUPS_BACKEND_OK; +} + +static int selphyneo_cmdline_arg(void *vctx, int argc, char **argv) +{ + struct selphyneo_ctx *ctx = vctx; + int i, j = 0; + + if (!ctx) + return -1; + + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "R")) >= 0) { + switch(i) { + GETOPT_PROCESS_GLOBAL + case 'R': + selphyneo_send_reset(ctx); + break; + } + + if (j) return j; + } + + return 0; +} + +static void selphyneo_cmdline(void) +{ + DEBUG("\t\t[ -R ] # Reset printer\n"); +} + +struct dyesub_backend canonselphyneo_backend = { + .name = "Canon SELPHY CPneo", + .version = "0.06", + .uri_prefix = "canonselphyneo", + .cmdline_usage = selphyneo_cmdline, + .cmdline_arg = selphyneo_cmdline_arg, + .init = selphyneo_init, + .attach = selphyneo_attach, + .teardown = selphyneo_teardown, + .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_CP910, P_CP910, ""}, + { USB_VID_CANON, USB_PID_CANON_CP1000, P_CP910, ""}, + { USB_VID_CANON, USB_PID_CANON_CP1200, P_CP910, ""}, + { 0, 0, 0, ""} + } +}; +/* + + *************************************************************************** + + Stream formats and readback codes for supported printers + + *************************************************************************** + 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. + + 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 + + cols (le32) rows (le32) + 50 e0 04 50 07 1248 * 1872 (P) + 4c 80 04 c0 05 1152 * 1472 (L) + 43 40 04 9c 02 1088 * 668 (C) + + TT == 50 (P) + == 4c (L) + == 43 (C) + + 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. + + Other questions: + + * Printer supports different lamination types, how to control? + + Data Readback: + + XX 00 YY 00 00 00 ZZ 00 00 00 00 00 + + XX == Status + + 01 Idle + 02 Feeding Paper + 04 Printing Y + 08 Printing M + 10 Printing C + 20 Printing L + + YY == Error + + 00 None + 02 No Paper (?) + 03 No Paper + 07 No Ink + 09 No Paper and Ink + 0A Media/Job mismatch + + ZZ == Media? + + 01 + 10 + 11 + ^-- Ribbon + ^-- Paper + + 1 == P + 2 == L ?? + 3 == C + +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" ...?? + +*/ diff --git a/src/cups/backend_common.c b/src/cups/backend_common.c index 643d738..bc39061 100644 --- a/src/cups/backend_common.c +++ b/src/cups/backend_common.c @@ -27,7 +27,7 @@ #include "backend_common.h" -#define BACKEND_VERSION "0.67G" +#define BACKEND_VERSION "0.70G" #ifndef URI_PREFIX #error "Must Define URI_PREFIX" #endif @@ -42,8 +42,6 @@ int extra_vid = -1; int extra_pid = -1; int extra_type = -1; int copies = 1; -char *use_serno = NULL; -int current_page = 0; /* Support Functions */ static int backend_claim_interface(struct libusb_device_handle *dev, int iface) @@ -54,6 +52,8 @@ static int backend_claim_interface(struct libusb_device_handle *dev, int iface) ret = libusb_claim_interface(dev, iface); if (!ret) break; + if (ret != LIBUSB_ERROR_BUSY) + break; sleep(1); } while (--attempts > 0); @@ -63,11 +63,11 @@ static int backend_claim_interface(struct libusb_device_handle *dev, int iface) return ret; } +/* Interface **MUST** already be claimed! */ #define ID_BUF_SIZE 2048 -static char *get_device_id(struct libusb_device_handle *dev) +static char *get_device_id(struct libusb_device_handle *dev, int iface) { int length; - int iface = 0; char *buf = malloc(ID_BUF_SIZE + 1); if (!buf) { @@ -75,12 +75,6 @@ static char *get_device_id(struct libusb_device_handle *dev) return NULL; } - if (libusb_kernel_driver_active(dev, iface)) - libusb_detach_kernel_driver(dev, iface); - - if (backend_claim_interface(dev, iface)) - return NULL; - if (libusb_control_transfer(dev, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_INTERFACE, @@ -114,8 +108,6 @@ static char *get_device_id(struct libusb_device_handle *dev) buf[length] = '\0'; done: - libusb_release_interface(dev, iface); - return buf; } @@ -368,10 +360,17 @@ static int print_scan_output(struct libusb_device *device, struct libusb_device_handle *dev; char buf[256]; char *product = NULL, *serial = NULL, *manuf = NULL, *descr = NULL; - + int iface = 0; // XXX loop through interfaces + int altset = 0; // XXX loop through altsetting + struct libusb_config_descriptor *config = NULL; int dlen = 0; struct deviceid_dict dict[MAX_DICT]; char *ieee_id = NULL; + int i; + + uint8_t endp_up = 0, endp_down = 0; + + DEBUG("Probing VID: %04X PID: %04x\n", desc->idVendor, desc->idProduct); if (libusb_open(device, &dev)) { ERROR("Could not open device %04x:%04x (need to be root?)\n", desc->idVendor, desc->idProduct); @@ -379,10 +378,38 @@ static int print_scan_output(struct libusb_device *device, goto abort; } - ieee_id = get_device_id(dev); + if (libusb_kernel_driver_active(dev, iface)) + libusb_detach_kernel_driver(dev, iface); + + if (backend_claim_interface(dev, iface)) { + found = -1; + goto abort_close; + } + + if (libusb_get_active_config_descriptor(device, &config)) { + found = -1; + goto abort_release; + } - /* Get IEEE1284 info */ - dlen = parse1284_data(ieee_id, dict); + /* Find the endpoints */ + 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) + endp_up = config->interface[iface].altsetting[altset].endpoint[i].bEndpointAddress; + else + endp_down = config->interface[iface].altsetting[altset].endpoint[i].bEndpointAddress; + } + if (endp_up && endp_down) + break; + } + + /* Query IEEE1284 info only if it's a PRINTER class */ + if (desc->bDeviceClass == LIBUSB_CLASS_PRINTER || + (desc->bDeviceClass == LIBUSB_CLASS_PER_INTERFACE && + config->interface[iface].altsetting[altset].bInterfaceClass == LIBUSB_CLASS_PRINTER)) { + ieee_id = get_device_id(dev, iface); + dlen = parse1284_data(ieee_id, dict); + } /* Look up mfg string. */ if (manuf2 && strlen(manuf2)) { @@ -459,38 +486,10 @@ static int print_scan_output(struct libusb_device *device, sanitize_string(buf); serial = url_encode(buf); } else if (backend->query_serno) { /* Get from backend hook */ - int iface = 0; - - struct libusb_config_descriptor *config = NULL; - - if (libusb_kernel_driver_active(dev, iface)) - libusb_detach_kernel_driver(dev, iface); - - /* Try to claim the printer, and handle transient failures */ - if (!backend_claim_interface(dev, iface)) { - int i; - uint8_t endp_up = 0, endp_down = 0; - libusb_get_active_config_descriptor(device, &config); - for (i = 0 ; i < config->interface[0].altsetting[0].bNumEndpoints ; i++) { - if ((config->interface[0].altsetting[0].endpoint[i].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_BULK) { - if (config->interface[0].altsetting[0].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_IN) - endp_up = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; - else - endp_down = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; - } - if (endp_up && endp_down) - break; - } - - buf[0] = 0; - /* Ignore result since a failure isn't critical here */ - backend->query_serno(dev, endp_up, endp_down, buf, STR_LEN_MAX); - libusb_release_interface(dev, iface); - } + buf[0] = 0; + /* Ignore result since a failure isn't critical here */ + backend->query_serno(dev, endp_up, endp_down, buf, STR_LEN_MAX); serial = url_encode(buf); - - if (config) - libusb_free_config_descriptor(config); } if (!serial || !strlen(serial)) { /* Last-ditch */ @@ -501,10 +500,6 @@ static int print_scan_output(struct libusb_device *device, serial = strdup("NONE_UNKNOWN"); } - if (dyesub_debug) - DEBUG("VID: %04X PID: %04X Manuf: '%s' Product: '%s' Serial: '%s'\n", - desc->idVendor, desc->idProduct, manuf, product, serial); - if (scan_only) { int k = 0; @@ -527,16 +522,27 @@ static int print_scan_output(struct libusb_device *device, found = -1; } + if (dyesub_debug) + DEBUG("VID: %04X PID: %04X Manuf: '%s' Product: '%s' Serial: '%s' found: %d\n", + desc->idVendor, desc->idProduct, manuf, product, serial, found); + /* Free things up */ if(serial) free(serial); if(manuf) free(manuf); if(product) free(product); if(descr) free(descr); - if (ieee_id) free(ieee_id); + if(ieee_id) free(ieee_id); + + if (config) libusb_free_config_descriptor(config); + +abort_release: + + libusb_release_interface(dev, iface); + +abort_close: libusb_close(dev); abort: - /* Clean up the dictionary */ while (dlen--) { free (dict[dlen].key); @@ -555,13 +561,16 @@ extern struct dyesub_backend shinkos2145_backend; extern struct dyesub_backend shinkos6145_backend; extern struct dyesub_backend shinkos6245_backend; extern struct dyesub_backend canonselphy_backend; +extern struct dyesub_backend canonselphyneo_backend; extern struct dyesub_backend mitsu70x_backend; extern struct dyesub_backend mitsu9550_backend; +extern struct dyesub_backend mitsup95d_backend; extern struct dyesub_backend dnpds40_backend; extern struct dyesub_backend cw01_backend; static struct dyesub_backend *backends[] = { &canonselphy_backend, + &canonselphyneo_backend, &kodak6800_backend, &kodak605_backend, &kodak1400_backend, @@ -572,6 +581,7 @@ static struct dyesub_backend *backends[] = { &updr150_backend, &mitsu70x_backend, &mitsu9550_backend, + &mitsup95d_backend, &dnpds40_backend, &cw01_backend, NULL, @@ -713,8 +723,7 @@ void print_help(char *argv0, struct dyesub_backend *backend) DEBUG("Standalone %s backend version %s\n", backend->name, backend->version); DEBUG("\t%s\n", backend->uri_prefix); - DEBUG("\t[ -D ] [ -G ] \n"); - DEBUG("\t[ -V extra_vid ] [ -P extra_pid ] [ -T extra_type ] \n"); + DEBUG("\t[ -D ] [ -G ] [ -f ]\n"); if (backend->cmdline_usage) backend->cmdline_usage(); DEBUG("\t[ -d copies ] [ infile | - ]\n"); @@ -744,18 +753,23 @@ int main (int argc, char **argv) uint8_t endp_up = 0; uint8_t endp_down = 0; + int iface = 0; // XXX loop through interfaces + int altset = 0; // XXX loop through altsetting + int data_fd = fileno(stdin); int i; int claimed; int ret = CUPS_BACKEND_OK; - int iface = 0; + int found = -1; int jobid = 0; + int current_page = 0; char *uri; char *fname = NULL; + char *use_serno = NULL; DEBUG("Multi-Call Dye-sublimation CUPS Backend version %s\n", BACKEND_VERSION); @@ -919,12 +933,12 @@ int main (int argc, char **argv) goto done_close; } - for (i = 0 ; i < config->interface[0].altsetting[0].bNumEndpoints ; i++) { - if ((config->interface[0].altsetting[0].endpoint[i].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_BULK) { - if (config->interface[0].altsetting[0].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_IN) - endp_up = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; + 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) + endp_up = config->interface[iface].altsetting[altset].endpoint[i].bEndpointAddress; else - endp_down = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; + endp_down = config->interface[iface].altsetting[altset].endpoint[i].bEndpointAddress; } if (endp_up && endp_down) break; @@ -1081,3 +1095,17 @@ uint16_t uint16_to_packed_bcd(uint16_t val) return bcd; } + +uint32_t packed_bcd_to_uint32(char *in, int len) +{ + uint32_t out = 0; + + while (len--) { + out *= 10; + out += (*in >> 4); + out *= 10; + out += (*in & 0xf); + in++; + } + return out; +} diff --git a/src/cups/backend_common.h b/src/cups/backend_common.h index 2462058..fea04dc 100644 --- a/src/cups/backend_common.h +++ b/src/cups/backend_common.h @@ -95,6 +95,7 @@ enum { P_CP790, P_CP_XXX, P_CP10, + P_CP910, P_KODAK_6800, P_KODAK_6850, P_KODAK_1400_805, @@ -116,12 +117,14 @@ enum { P_MITSU_9800, P_MITSU_9800S, P_MITSU_9810, + P_MITSU_P95D, P_DNP_DS40, P_DNP_DS80, P_DNP_DS80D, P_CITIZEN_CW01, P_DNP_DSRX1, P_DNP_DS620, + P_DNP_DS820, P_FUJI_ASK300, P_END, }; @@ -138,7 +141,7 @@ struct dyesub_backend { char *name; char *version; char *uri_prefix; - void (*cmdline_usage)(void); + void (*cmdline_usage)(void); /* Optional */ void *(*init)(void); void (*attach)(void *ctx, struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, uint8_t jobid); @@ -146,7 +149,7 @@ struct dyesub_backend { int (*cmdline_arg)(void *ctx, int argc, char **argv); int (*read_parse)(void *ctx, int data_fd); int (*main_loop)(void *ctx, int copies); - int (*query_serno)(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len); + int (*query_serno)(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len); /* Optional */ struct device_id devices[]; }; @@ -161,6 +164,7 @@ void print_license_blurb(void); void print_help(char *argv0, struct dyesub_backend *backend); uint16_t uint16_to_packed_bcd(uint16_t val); +uint32_t packed_bcd_to_uint32(char *in, int len); /* Global data */ extern int terminate; @@ -170,8 +174,6 @@ extern int extra_vid; extern int extra_pid; extern int extra_type; extern int copies; -extern char *use_serno; -extern int current_page; #if defined(BACKEND) extern struct dyesub_backend BACKEND; diff --git a/src/cups/backend_dnpds40.c b/src/cups/backend_dnpds40.c index 41eec62..650c963 100644 --- a/src/cups/backend_dnpds40.c +++ b/src/cups/backend_dnpds40.c @@ -62,6 +62,7 @@ #define USB_VID_DNP 0x1452 #define USB_PID_DNP_DS620 0x8b01 +#define USB_PID_DNP_DS820 0x9001 /* Private data stucture */ struct dnpds40_ctx { @@ -91,15 +92,21 @@ struct dnpds40_ctx { int matte; int cutter; int can_rewind; + + int printspeed; + int mediaoffset; int manual_copies; int correct_count; + uint32_t native_width; int supports_6x9; int supports_2x6; int supports_3x5x2; int supports_matte; + int supports_finematte; int supports_luster; + int supports_advmatte; int supports_fullcut; int supports_rewind; int supports_standby; @@ -111,7 +118,11 @@ struct dnpds40_ctx { int supports_counterp; int supports_adv_fullcut; int supports_mediaoffset; - + int supports_media_ext; + int supports_printspeed; + int supports_lowspeed; + int supports_highdensity; + int supports_gamma; uint8_t *databuf; int datalen; }; @@ -154,6 +165,18 @@ struct dnpds40_cmd { #define MULTICUT_5x5 29 #define MULTICUT_6x4_5 30 #define MULTICUT_6x4_5X2 31 +#define MULTICUT_8x7 32 +#define MULTICUT_8x9 33 +#define MULTICUT_A5 34 +#define MULTICUT_A5X2 35 +#define MULTICUT_A4x4 36 +#define MULTICUT_A4x5 37 +#define MULTICUT_A4x6 38 +#define MULTICUT_A4x8 39 +#define MULTICUT_A4x10 40 +#define MULTICUT_A4 41 +#define MULTICUT_A4x5X2 43 + #define MULTICUT_S_SIMPLEX 100 #define MULTICUT_S_FRONT 200 @@ -214,6 +237,7 @@ static char *dnpds40_printer_type(int type) case P_DNP_DS80D: return "DS80DX"; case P_DNP_DSRX1: return "DSRX1"; case P_DNP_DS620: return "DS620"; + case P_DNP_DS820: return "DS820"; default: break; } return "Unknown"; @@ -231,6 +255,32 @@ static char *dnpds40_media_types(int media) case 400: return "6x9 (A5W)"; case 500: return "8x10"; case 510: return "8x12"; + case 600: return "A4"; + default: + break; + } + + return "Unknown type"; +} + +static char *dnpds620_media_extension_code(int media) +{ + switch (media) { + case 00: return "Normal Paper"; + case 01: return "Sticky Paper"; + case 99: return "Unknown Paper"; + default: + break; + } + + return "Unknown type"; +} + +static char *dnpds820_media_subtypes(int media) +{ + switch (media) { + case 0001: return "SD"; + case 0003: return "PP"; default: break; } @@ -377,9 +427,10 @@ static int dnpds40_do_cmd(struct dnpds40_ctx *ctx, return CUPS_BACKEND_OK; } -static uint8_t * dnpds40_resp_cmd(struct dnpds40_ctx *ctx, +static uint8_t *dnpds40_resp_cmd2(struct dnpds40_ctx *ctx, struct dnpds40_cmd *cmd, - int *len) + int *len, + uint8_t *buf, uint32_t buf_len) { char tmp[9]; uint8_t *respbuf; @@ -388,7 +439,7 @@ static uint8_t * dnpds40_resp_cmd(struct dnpds40_ctx *ctx, memset(tmp, 0, sizeof(tmp)); - if ((ret = dnpds40_do_cmd(ctx, cmd, NULL, 0))) + if ((ret = dnpds40_do_cmd(ctx, cmd, buf, buf_len))) return NULL; /* Read in the response header */ @@ -427,6 +478,8 @@ static uint8_t * dnpds40_resp_cmd(struct dnpds40_ctx *ctx, return respbuf; } +#define dnpds40_resp_cmd(__ctx, __cmd, __len) dnpds40_resp_cmd2(__ctx, __cmd, __len, NULL, 0) + static int dnpds40_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len) { struct dnpds40_cmd cmd; @@ -591,6 +644,7 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev, /* Per-printer options */ switch (ctx->type) { case P_DNP_DS40: + ctx->native_width = 1920; ctx->supports_6x9 = 1; if (FW_VER_CHECK(1,04)) ctx->supports_counterp = 1; @@ -601,12 +655,14 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev, break; case P_DNP_DS80: case P_DNP_DS80D: + ctx->native_width = 2560; if (FW_VER_CHECK(1,02)) ctx->supports_counterp = 1; if (FW_VER_CHECK(1,30)) ctx->supports_matte = 1; break; case P_DNP_DSRX1: + ctx->native_width = 1920; ctx->supports_counterp = 1; ctx->supports_matte = 1; if (FW_VER_CHECK(1,10)) @@ -619,6 +675,7 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev, } break; case P_DNP_DS620: + ctx->native_width = 1920; ctx->correct_count = 1; ctx->supports_counterp = 1; ctx->supports_matte = 1; @@ -633,14 +690,40 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev, ctx->supports_iserial = 1; ctx->supports_6x6 = 1; ctx->supports_5x5 = 1; + ctx->supports_lowspeed = 1; if (FW_VER_CHECK(0,30)) ctx->supports_3x5x2 = 1; if (FW_VER_CHECK(1,10)) ctx->supports_6x9 = ctx->supports_6x4_5 = 1; if (FW_VER_CHECK(1,20)) - ctx->supports_adv_fullcut = 1; + ctx->supports_adv_fullcut = ctx->supports_advmatte = 1; if (FW_VER_CHECK(1,30)) - ctx->supports_luster = 1; + ctx->supports_luster = ctx->supports_finematte = 1; + if (FW_VER_CHECK(1,33)) + ctx->supports_media_ext = 1; + break; + case P_DNP_DS820: + ctx->native_width = 2560; + ctx->correct_count = 1; + ctx->supports_counterp = 1; + ctx->supports_matte = 1; + ctx->supports_fullcut = 1; + ctx->supports_mqty_default = 1; + if (strchr(ctx->version, 'A')) + ctx->supports_rewind = 0; + else + ctx->supports_rewind = 1; + ctx->supports_standby = 1; + ctx->supports_iserial = 1; + ctx->supports_adv_fullcut = 1; + ctx->supports_advmatte = 1; + ctx->supports_luster = 1; + ctx->supports_finematte = 1; + ctx->supports_printspeed = 1; + ctx->supports_lowspeed = 1; + ctx->supports_highdensity = 1; + if (FW_VER_CHECK(0,50)) + ctx->supports_gamma = 1; break; default: ERROR("Unknown vid/pid %04x/%04x (%d)\n", desc.idVendor, desc.idProduct, ctx->type); @@ -780,7 +863,7 @@ static void dnpds40_teardown(void *vctx) { free(ctx); } -#define MAX_PRINTJOB_LEN (((2560*7536+1024+54))*3+1024) /* Worst-case */ +#define MAX_PRINTJOB_LEN (((2560*7536+1024+54))*3+1024) /* Worst-case, YMC */ static int dnpds40_read_parse(void *vctx, int data_fd) { struct dnpds40_ctx *ctx = vctx; @@ -820,7 +903,9 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { ctx->manual_copies = 0; ctx->multicut = 0; ctx->fullcut = 0; + ctx->printspeed = -1; ctx->can_rewind = 0; + ctx->buf_needed = 0; while (run) { int remain, i, j; @@ -902,6 +987,25 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { WARNING("Printer FW does not support full cutter control!\n"); continue; } + + if (ctx->type == P_DNP_DS820) { + if (j != 24) { + WARNING("Full cutter argument length incorrect, ignoring!\n"); + continue; + } + } else if (j != 16) { + WARNING("Full cutter argument length incorrect, ignoring!\n"); + continue; + } else if (!ctx->supports_adv_fullcut) { + if (ctx->databuf[ctx->datalen + 32 + 12] != '0' || + ctx->databuf[ctx->datalen + 32 + 13] != '0' || + ctx->databuf[ctx->datalen + 32 + 14] != '0') { + WARNING("Full cutter scrap setting not supported on this firmware, ignoring!\n"); + continue; + } + } + // XXX enforce cut counts/sizes? + ctx->fullcut = 1; } if(!memcmp("IMAGE YPLANE", ctx->databuf + ctx->datalen + 2, 12)) { @@ -926,18 +1030,21 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { /* Validate horizontal size */ memcpy(&y_ppm, ctx->databuf + ctx->datalen + 32 + 18, sizeof(y_ppm)); y_ppm = le32_to_cpu(y_ppm); - if (ctx->type == P_DNP_DS80 || - ctx->type == P_DNP_DS80D) { - if (y_ppm != 2560) { - ERROR("Incorrect horizontal resolution (%u), aborting!\n", y_ppm); - return CUPS_BACKEND_CANCEL; - } - } else { - if (y_ppm != 1920) { - ERROR("Incorrect horizontal resolution (%u), aborting!\n", y_ppm); - return CUPS_BACKEND_CANCEL; - } + if (y_ppm != ctx->native_width) { + ERROR("Incorrect horizontal resolution (%u), aborting!\n", y_ppm); + return CUPS_BACKEND_CANCEL; + } + } + if(!memcmp("CNTRL PRINTSPEED", ctx->databuf + ctx->datalen + 2, 16)) { + if (!ctx->supports_printspeed) { + WARNING("Printer does not support PRINTSPEED\n"); + continue; } + memcpy(buf, ctx->databuf + ctx->datalen + 32, 8); + ctx->printspeed = atoi(buf) / 10; + + /* We'll insert this ourselves later. */ + continue; } /* This is the last block.. */ @@ -953,14 +1060,32 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { return CUPS_BACKEND_CANCEL; /* Sanity check matte mode */ - if (ctx->matte == 22 && !ctx->supports_luster) { + if (ctx->matte == 21 && !ctx->supports_finematte) { + WARNING("Printer FW does not support Fine Matte mode, downgrading to normal matte\n"); + ctx->matte = 1; + } else if (ctx->matte == 22 && !ctx->supports_luster) { WARNING("Printer FW does not support Luster mode, downgrading to normal matte\n"); - ctx->matte -= 21; - } else if (ctx->matte > 1) { - WARNING("Unknown matte mode selected, downgrading to normal matte\n"); - ctx->matte -= 21; + ctx->matte = 1; + } else if (ctx->matte > 1 && !ctx->supports_advmatte) { + WARNING("Printer FW does not support advanced matte modes, downgrading to normal matte\n"); + ctx->matte = 1; + } + + /* Pick a sane default value for printspeed if not specified */ + if (ctx->printspeed == -1 || ctx->printspeed > 3) + { + if (dpi == 600) + ctx->printspeed = 1; + else + ctx->printspeed = 0; } - + /* And sanity-check whatever value is there */ + if (ctx->printspeed == 0 && dpi == 600) { + ctx->printspeed = 1; + } else if (ctx->printspeed == 1 && dpi == 300) { + ctx->printspeed = 0; + } + /* Make sure MULTICUT is sane, most validation needs this */ if (!ctx->multicut) { WARNING("Missing or illegal MULTICUT command!\n"); @@ -981,19 +1106,23 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { /* Figure out the number of buffers we need. */ ctx->buf_needed = 1; + if (dpi == 600) { - if (ctx->type == P_DNP_DS620) { + switch(ctx->type) { + case P_DNP_DS620: if (ctx->multicut == MULTICUT_6x9 || ctx->multicut == MULTICUT_6x4_5X2) ctx->buf_needed = 2; - } else if (ctx->type == P_DNP_DS80) { /* DS80/CX-W */ + break; + case P_DNP_DS80: /* DS80/CX-W */ if (ctx->matte && (ctx->multicut == MULTICUT_8xA4LEN || ctx->multicut == MULTICUT_8x4X3 || ctx->multicut == MULTICUT_8x8_8x4 || ctx->multicut == MULTICUT_8x6X2 || ctx->multicut == MULTICUT_8x12)) ctx->buf_needed = 2; - } else if (ctx->type == P_DNP_DS80D) { /* DS80D */ + break; + case P_DNP_DS80D: if (ctx->matte) { int mcut = ctx->multicut; @@ -1014,13 +1143,26 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { mcut == MULTICUT_S_8x4X3) ctx->buf_needed = 2; } - } else { /* DS40/CX/RX1/CY/etc */ - if (ctx->multicut == MULTICUT_6x8 || - ctx->multicut == MULTICUT_6x9 || - ctx->multicut == MULTICUT_6x4X2 || - ctx->multicut == MULTICUT_5x7 || - ctx->multicut == MULTICUT_5x3_5X2) - ctx->buf_needed = 2; + break; + case P_DNP_DS820: + // Nothing; all sizes only need 1 buffer + break; + default: /* DS40/CX/RX1/CY/everything else */ + if (ctx->matte) { + if (ctx->multicut == MULTICUT_6x8 || + ctx->multicut == MULTICUT_6x9 || + ctx->multicut == MULTICUT_6x4X2 || + ctx->multicut == MULTICUT_5x7 || + ctx->multicut == MULTICUT_5x3_5X2) + ctx->buf_needed = 2; + + } else { + if (ctx->multicut == MULTICUT_6x8 || + ctx->multicut == MULTICUT_6x9 || + ctx->multicut == MULTICUT_6x4X2) + ctx->buf_needed = 1; + } + break; } } @@ -1073,17 +1215,43 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { ctx->can_rewind = 1; break; case 500: //"8x10" - if (ctx->multicut < MULTICUT_8x10 || ctx->multicut == MULTICUT_8x12 || + if (ctx->type == P_DNP_DS820 && + (ctx->multicut == MULTICUT_8x7 || ctx->multicut == MULTICUT_8x9)) { + /* These are okay */ + } else if (ctx->multicut < MULTICUT_8x10 || ctx->multicut == MULTICUT_8x12 || ctx->multicut == MULTICUT_8x6X2 || ctx->multicut >= MULTICUT_8x6_8x5 ) { ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); return CUPS_BACKEND_CANCEL; } + + /* 8x4, 8x5 can be rewound */ + if (ctx->multicut == MULTICUT_8x4 || + ctx->multicut == MULTICUT_8x5) + ctx->can_rewind = 1; break; case 510: //"8x12" - if (ctx->multicut < MULTICUT_8x10 || ctx->multicut > MULTICUT_8xA4LEN) { + if (ctx->multicut < MULTICUT_8x10 || (ctx->multicut > MULTICUT_8xA4LEN && !(ctx->multicut == MULTICUT_8x7 || ctx->multicut == MULTICUT_8x9))) { ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); return CUPS_BACKEND_CANCEL; } + + /* 8x4, 8x5, 8x6 can be rewound */ + if (ctx->multicut == MULTICUT_8x4 || + ctx->multicut == MULTICUT_8x5 || + ctx->multicut == MULTICUT_8x6) + ctx->can_rewind = 1; + break; + case 600: //"A4" + if (ctx->multicut < MULTICUT_A5 || ctx->multicut > MULTICUT_A4x5X2) { + ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut); + return CUPS_BACKEND_CANCEL; + } + /* A4xn and A5 can be rewound */ + if (ctx->multicut == MULTICUT_A4x4 || + ctx->multicut == MULTICUT_A4x5 || + ctx->multicut == MULTICUT_A4x6 || + ctx->multicut == MULTICUT_A5) + ctx->can_rewind = 1; break; default: ERROR("Unknown media (%u vs %u)!\n", ctx->media, ctx->multicut); @@ -1170,8 +1338,8 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { } skip_checks: - DEBUG("dpi %u matte %d mcut %u cutter %d, bufs %d\n", - dpi, ctx->matte, ctx->multicut, ctx->cutter, ctx->buf_needed); + DEBUG("dpi %u matte %d mcut %u cutter %d, bufs %d spd %d\n", + dpi, ctx->matte, ctx->multicut, ctx->cutter, ctx->buf_needed, ctx->printspeed); return CUPS_BACKEND_OK; } @@ -1204,6 +1372,7 @@ static int dnpds40_main_loop(void *vctx, int copies) { ATTR("marker-names='%s'\n", dnpds40_media_types(ctx->media)); ATTR("marker-types=ribbonWax\n"); } + top: /* Query status */ @@ -1351,7 +1520,7 @@ top: } } - /* Set overcoat parameters */ + /* Set overcoat parameters if appropriate */ if (ctx->supports_matte) { snprintf(buf, sizeof(buf), "%08d", ctx->matte); dnpds40_build_cmd(&cmd, "CNTRL", "OVERCOAT", 8); @@ -1367,6 +1536,14 @@ top: return CUPS_BACKEND_FAILED; } + /* Send over the printspeed if appropriate */ + if (ctx->supports_printspeed) { + snprintf(buf, sizeof(buf), "%08d", ctx->printspeed * 10); + dnpds40_build_cmd(&cmd, "CNTRL", "PRINTSPEED", 8); + if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8))) + return CUPS_BACKEND_FAILED; + } + /* Program in the multicut setting */ snprintf(buf, sizeof(buf), "%08u", ctx->multicut); dnpds40_build_cmd(&cmd, "IMAGE", "MULTICUT", 8); @@ -1684,7 +1861,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) free(resp); - if (ctx->type == P_DNP_DS620) { + if (ctx->supports_lowspeed) { /* "Low Speed" */ dnpds40_build_cmd(&cmd, "TBL_RD", "CWD610_Version", 0); @@ -1710,10 +1887,56 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) free(resp); } + if (ctx->supports_highdensity) { + uint8_t buf[5]; + int i = 0; + + snprintf((char*)buf, sizeof(buf), "%04d", i); + + /* "High Density" */ + dnpds40_build_cmd(&cmd, "TBL_RD", "CWD620_Version", 4); + + resp = dnpds40_resp_cmd2(ctx, &cmd, &len, buf, 4); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + + INFO("High Density Color Data: %s ", (char*)resp); + + free(resp); + + dnpds40_build_cmd(&cmd, "TBL_RD", "CWD620_Checksum", 4); + + resp = dnpds40_resp_cmd2(ctx, &cmd, &len, buf, 4); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + + DEBUG2("(%s)\n", (char*)resp); + + free(resp); + } + if (ctx->supports_gamma) { + /* "Low Speed" */ + dnpds40_build_cmd(&cmd, "TBL_RD", "CTRLD_GAMMA16", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + + INFO("Gamma Correction Data Checksum: %s\n", (char*)resp); + + free(resp); + } if (ctx->supports_standby) { - int i; /* Get Standby stuff */ + int i; + dnpds40_build_cmd(&cmd, "MNT_RD", "STANDBY_TIME", 0); resp = dnpds40_resp_cmd(ctx, &cmd, &len); @@ -1778,9 +2001,9 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) return CUPS_BACKEND_FAILED; dnpds40_cleanup_string((char*)resp, len); - len = atoi((char*)resp); + count = atoi((char*)resp); - INFO("Printer Status: %s (%d)\n", dnpds40_statuses(len), len); + INFO("Printer Status: %s (%d)\n", dnpds40_statuses(count), count); free(resp); @@ -1793,9 +2016,9 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) return CUPS_BACKEND_FAILED; dnpds40_cleanup_string((char*)resp, len); - len = atoi((char*)resp); + count = atoi((char*)resp); - INFO("Duplexer Status: %s\n", dnpds80_duplex_statuses(len)); + INFO("Duplexer Status: %s\n", dnpds80_duplex_statuses(count)); free(resp); } @@ -1829,6 +2052,34 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) /* Report media */ INFO("Media Type: %s\n", dnpds40_media_types(ctx->media)); + if (ctx->supports_media_ext) { + int type; + dnpds40_build_cmd(&cmd, "INFO", "MEDIA_EXT_CODE", 0); + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + *(resp+2) = 0; // Only the first two chars are used. + type = atoi((char*)resp); + INFO("Media Code: %s\n", dnpds620_media_extension_code(type)); + free(resp); + } + + /* Try to figure out media subtype */ + if (ctx->type == P_DNP_DS820) { + int type; + dnpds40_build_cmd(&cmd, "INFO", "MEDIA_CLASS_RFID", 0); + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + type = atoi((char*)resp); + INFO("Media Subtype: %s\n", dnpds820_media_subtypes(type)); + free(resp); + } + /* Report Cut Media */ if (ctx->type == P_DNP_DS80D) INFO("Duplex Media Type: %s\n", dnpds80_duplex_media_types(ctx->media)); @@ -1896,7 +2147,8 @@ static int dnpds40_get_counters(struct dnpds40_ctx *ctx) free(resp); - if (ctx->type == P_DNP_DS620) { + if (ctx->type == P_DNP_DS620 || + ctx->type == P_DNP_DS820) { /* Generate command */ dnpds40_build_cmd(&cmd, "MNT_RD", "COUNTER_HEAD", 0); @@ -2232,7 +2484,7 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv) /* Exported */ struct dyesub_backend dnpds40_backend = { .name = "DNP DS40/DS80/DSRX1/DS620", - .version = "0.89", + .version = "0.91", .uri_prefix = "dnpds40", .cmdline_usage = dnpds40_cmdline, .cmdline_arg = dnpds40_cmdline_arg, @@ -2250,6 +2502,7 @@ struct dyesub_backend dnpds40_backend = { { USB_VID_DNP, USB_PID_DNP_DS620, P_DNP_DS620, ""}, { USB_VID_DNP, USB_PID_DNP_DS80D, P_DNP_DS80D, ""}, { USB_VID_CITIZEN, USB_PID_CITIZEN_CW02, P_DNP_DS40, ""}, + { USB_VID_DNP, USB_PID_DNP_DS820, P_DNP_DS820, ""}, { 0, 0, 0, ""} } }; diff --git a/src/cups/backend_mitsu70x.c b/src/cups/backend_mitsu70x.c index 16099ba..a0ab482 100644 --- a/src/cups/backend_mitsu70x.c +++ b/src/cups/backend_mitsu70x.c @@ -108,7 +108,7 @@ typedef int (*send_image_dataFN)(struct BandImage *out, void *context, #define USB_VID_MITSU 0x06D3 #define USB_PID_MITSU_D70X 0x3B30 #define USB_PID_MITSU_K60 0x3B31 -//#define USB_PID_MITSU_D80 XXXXXX +#define USB_PID_MITSU_D80 0x3B36 #define USB_VID_KODAK 0x040a #define USB_PID_KODAK305 0x404f //#define USB_VID_FUJIFILM XXXXXX @@ -137,8 +137,6 @@ struct mitsu70x_ctx { uint16_t last_donor_u; int num_decks; - int supports_jobs_query; - char *laminatefname; char *lutfname; char *cpcfname; @@ -180,14 +178,16 @@ struct mitsu70x_jobstatus { uint8_t reserved[6]; } __attribute__((packed)); +struct mitsu70x_job { + uint16_t id; /* BE */ + uint8_t status[4]; +} __attribute__((packed)); + +#define NUM_JOBS 170 + struct mitsu70x_jobs { uint8_t hdr[4]; /* E4 56 31 31 */ - uint16_t dummy; - uint16_t jobid_0; /* BE */ - uint8_t job0_status[4]; - uint16_t jobid_1; /* BE */ - uint8_t job1_status[4]; - // XXX are there more? + struct mitsu70x_job jobs[NUM_JOBS]; } __attribute__((packed)); #define TEMPERATURE_NORMAL 0x00 @@ -288,9 +288,9 @@ struct mitsu70x_jobs { struct mitsu70x_status_deck { uint8_t mecha_status[2]; - uint8_t temperature; + uint8_t temperature; /* D70 family only, K60 no */ uint8_t error_status[3]; - uint8_t rsvd_a[10]; + uint8_t rsvd_a[10]; /* K60 family [1] == temperature? [3:6] == lifetime prints in BCD */ uint8_t media_brand; uint8_t media_type; @@ -298,9 +298,7 @@ struct mitsu70x_status_deck { uint16_t capacity; /* media capacity */ uint16_t remain; /* media remaining */ uint8_t rsvd_c[2]; - - uint16_t rsvd_d; - uint16_t prints; /* lifetime prints on deck? */ + uint8_t lifetime_prints[4]; /* lifetime prints on deck + 10, in BCD! */ uint16_t rsvd_e[17]; } __attribute__((packed)); @@ -316,12 +314,15 @@ struct mitsu70x_printerstatus_resp { uint8_t unk[34]; int16_t model[6]; /* LE, UTF-16 */ int16_t serno[6]; /* LE, UTF-16 */ - struct mitsu70x_status_ver vers[7]; // components are 'LMFTR??' + struct mitsu70x_status_ver vers[7]; // components are 'MLRTF' uint8_t null[8]; struct mitsu70x_status_deck lower; struct mitsu70x_status_deck upper; } __attribute__((packed)); +#define EK305_0104_M_CSUM 0x2878 /* 1.04 316F8 3 2878 */ +#define MD70X_0112_M_CSUM 0x9FC3 /* 1.12 316W1 1 9FC3 */ + struct mitsu70x_memorystatus_resp { uint8_t hdr[3]; /* E4 56 33 */ uint8_t memory; @@ -588,14 +589,24 @@ static char *mitsu70x_errors(uint8_t *err) static const char *mitsu70x_media_types(uint8_t brand, uint8_t type) { - if (brand == 0xff && type == 0x02) - return "CKD746 (4x6)"; + if (brand == 0xff && type == 0x01) + return "CK-D735 (3.5x5)"; + else if (brand == 0xff && type == 0x02) + return "CK-D746 (4x6)"; + else if (brand == 0xff && type == 0x04) + return "CK-D757 (5x7)"; + else if (brand == 0xff && type == 0x05) + return "CK-D769 (6x9)"; else if (brand == 0xff && type == 0x0f) - return "CKD768 (6x8)"; + return "CK-D768 (6x8)"; + else if (brand == 0x6c && type == 0x84) + return "Kodak 5R (5x7)"; else if (brand == 0x6c && type == 0x8f) return "Kodak 6R (6x8)"; + else if (brand == 0x61 && type == 0x84) + return "CK-K57R (5x7)"; else if (brand == 0x61 && type == 0x8f) - return "CKK76R (6x8)"; + return "CK-K76R (6x8)"; else return "Unknown"; } @@ -640,12 +651,6 @@ static void mitsu70x_attach(void *vctx, struct libusb_device_handle *dev, ctx->last_donor_l = ctx->last_donor_u = 65535; - if (ctx->type == P_KODAK_305 || - ctx->type == P_MITSU_K60) - ctx->supports_jobs_query = 0; - else - ctx->supports_jobs_query = 1; - /* Attempt to open the library */ #if defined(WITH_DYNAMIC) INFO("Attempting to load image processing library\n"); @@ -1036,6 +1041,7 @@ static int mitsu70x_get_jobstatus(struct mitsu70x_ctx *ctx, struct mitsu70x_jobs return 0; } +#if 0 static int mitsu70x_get_jobs(struct mitsu70x_ctx *ctx, struct mitsu70x_jobs *resp) { uint8_t cmdbuf[CMDBUF_LEN]; @@ -1068,6 +1074,7 @@ static int mitsu70x_get_jobs(struct mitsu70x_ctx *ctx, struct mitsu70x_jobs *res return 0; } +#endif static int mitsu70x_get_memorystatus(struct mitsu70x_ctx *ctx, struct mitsu70x_memorystatus_resp *resp) { @@ -1213,7 +1220,6 @@ static int mitsu70x_main_loop(void *vctx, int copies) struct mitsu70x_ctx *ctx = vctx; struct mitsu70x_jobstatus jobstatus; struct mitsu70x_printerstatus_resp resp; - struct mitsu70x_jobs jobs; struct mitsu70x_hdr *hdr; int ret; @@ -1290,6 +1296,15 @@ top: mitsu70x_media_types(resp.lower.media_brand, resp.lower.media_type)); ATTR("marker-types=ribbonWax\n"); } + + /* FW sanity checking */ + if (ctx->type == P_KODAK_305) { + if (be16_to_cpu(resp.vers[0].checksum) != EK305_0104_M_CSUM) + WARNING("Printer FW out of date. Highly recommend upgrading EK305 to v1.04!\n"); + } else if (ctx->type == P_MITSU_D70X) { + if (be16_to_cpu(resp.vers[0].checksum) != MD70X_0112_M_CSUM) + WARNING("Printer FW out of date. Highly recommend upgrading D70/D707 to v1.12!\n"); + } skip_status: /* Perform memory status query */ @@ -1313,21 +1328,29 @@ skip_status: } } +#if 0 /* Make sure we don't have any jobid collisions */ - if (ctx->supports_jobs_query) { + { + int i; + struct mitsu70x_jobs jobs; + ret = mitsu70x_get_jobs(ctx, &jobs); if (ret) return CUPS_BACKEND_FAILED; - while (ctx->jobid == be16_to_cpu(jobs.jobid_0) || - ctx->jobid == be16_to_cpu(jobs.jobid_1)) { - ctx->jobid++; - if (!ctx->jobid) + for (i = 0 ; i < NUM_JOBS ; i++) { + if (jobs.jobs[0].id == 0) + break; + if (ctx->jobid == be16_to_cpu(jobs.jobs[0].id)) { ctx->jobid++; + if (!ctx->jobid) + ctx->jobid++; + i = -1; + } } - } else { - while(!ctx->jobid || ctx->jobid == be16_to_cpu(jobstatus.jobid)) - ctx->jobid++; } +#endif + while(!ctx->jobid || ctx->jobid == be16_to_cpu(jobstatus.jobid)) + ctx->jobid++; /* Set jobid */ hdr->jobid = cpu_to_be16(ctx->jobid); @@ -1489,7 +1512,7 @@ skip_status: static void mitsu70x_dump_printerstatus(struct mitsu70x_printerstatus_resp *resp) { - unsigned int i; + uint32_t i; INFO("Model : "); for (i = 0 ; i < 6 ; i++) { @@ -1503,12 +1526,20 @@ static void mitsu70x_dump_printerstatus(struct mitsu70x_printerstatus_resp *resp DEBUG2("\n"); for (i = 0 ; i < 7 ; i++) { char buf[7]; + char type; if (resp->vers[i].ver[5] == '@') /* "DUMMY@" */ continue; memcpy(buf, resp->vers[i].ver, 6); buf[6] = 0; - INFO("Component #%u ID: %s (checksum %04x)\n", - i, buf, be16_to_cpu(resp->vers[i].checksum)); + if (i == 0) type = 'M'; + else if (i == 1) type = 'L'; + else if (i == 2) type = 'R'; + else if (i == 3) type = 'T'; + else if (i == 4) type = 'F'; + else type = i + 0x30; + + INFO("FW Component: %c %s (%04x)\n", + type, buf, be16_to_cpu(resp->vers[i].checksum)); } INFO("Lower Mechanical Status: %s\n", @@ -1526,7 +1557,11 @@ static void mitsu70x_dump_printerstatus(struct mitsu70x_printerstatus_resp *resp INFO("Lower Prints remaining: %03d/%03d\n", be16_to_cpu(resp->lower.remain), be16_to_cpu(resp->lower.capacity)); -// INFO("Lower Lifetime prints: %d\n", be16_to_cpu(resp->lower.prints)); + + i = packed_bcd_to_uint32((char*)resp->lower.lifetime_prints, 4); + if (i) + i-= 10; + INFO("Lower Lifetime prints: %u\n", i); if (resp->upper.mecha_status[0] != MECHA_STATUS_INIT) { INFO("Upper Mechanical Status: %s\n", @@ -1544,13 +1579,20 @@ static void mitsu70x_dump_printerstatus(struct mitsu70x_printerstatus_resp *resp INFO("Upper Prints remaining: %03d/%03d\n", be16_to_cpu(resp->upper.remain), be16_to_cpu(resp->upper.capacity)); + + i = packed_bcd_to_uint32((char*)resp->upper.lifetime_prints, 4); + if (i) + i-= 10; + INFO("Upper Lifetime prints: %u\n", i); } } static int mitsu70x_query_status(struct mitsu70x_ctx *ctx) { struct mitsu70x_printerstatus_resp resp; +#if 0 struct mitsu70x_jobs jobs; +#endif struct mitsu70x_jobstatus jobstatus; int ret; @@ -1574,19 +1616,21 @@ top: if (!ret) mitsu70x_dump_printerstatus(&resp); - if (ctx->supports_jobs_query) { - ret = mitsu70x_get_jobs(ctx, &jobs); - if (!ret) { - INFO("JOB0 ID : %06u\n", jobs.jobid_0); - INFO("JOB0 status : %s\n", mitsu70x_jobstatuses(jobs.job0_status)); - INFO("JOB1 ID : %06u\n", jobs.jobid_1); - INFO("JOB1 status : %s\n", mitsu70x_jobstatuses(jobs.job1_status)); - // XXX are there more? + INFO("JOB00 ID : %06u\n", jobstatus.jobid); + INFO("JOB00 status : %s\n", mitsu70x_jobstatuses(jobstatus.job_status)); + +#if 0 + ret = mitsu70x_get_jobs(ctx, &jobs); + if (!ret) { + int i; + for (i = 0 ; i < NUM_JOBS ; i++) { + if (jobs.jobs[i].id == 0) + break; + INFO("JOB%02d ID : %06u\n", i, jobs.jobs[i].id); + INFO("JOB%02d status : %s\n", i, mitsu70x_jobstatuses(jobs.jobs[i].status)); } - } else { - INFO("JOB0 ID : %06u\n", jobstatus.jobid); - INFO("JOB0 status : %s\n", mitsu70x_jobstatuses(jobstatus.job_status)); } +#endif done: return ret; @@ -1658,7 +1702,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.51", + .version = "0.55", .uri_prefix = "mitsu70x", .cmdline_usage = mitsu70x_cmdline, .cmdline_arg = mitsu70x_cmdline_arg, @@ -1671,7 +1715,7 @@ struct dyesub_backend mitsu70x_backend = { .devices = { { 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_D80, P_MITSU_D80, ""}, { USB_VID_KODAK, USB_PID_KODAK305, P_KODAK_305, ""}, // { USB_VID_FUJIFILM, USB_PID_FUJI_ASK300, P_FUJI_ASK300, ""}, { 0, 0, 0, ""} diff --git a/src/cups/backend_mitsu9550.c b/src/cups/backend_mitsu9550.c index 1599e9f..12ff0e8 100644 --- a/src/cups/backend_mitsu9550.c +++ b/src/cups/backend_mitsu9550.c @@ -39,15 +39,17 @@ #include "backend_common.h" -#define USB_VID_MITSU 0x06D3 -#define USB_PID_MITSU_9000D 0x0393 -#define USB_PID_MITSU_9500D 0x0394 +#define USB_VID_MITSU 0x06D3 +#define USB_PID_MITSU_9500D 0x0393 +#define USB_PID_MITSU_9000D 0x0394 +#define USB_PID_MITSU_9000AM 0x0395 #define USB_PID_MITSU_9550D 0x03A1 #define USB_PID_MITSU_9550DS 0x03A5 // or DZ/DZS/DZU #define USB_PID_MITSU_9600D 0x03A9 //#define USB_PID_MITSU_9600DS XXXXXX -//#define USB_PID_MITSU_9800D XXXXXX +#define USB_PID_MITSU_9800D 0x03AD #define USB_PID_MITSU_9800DS 0x03AE +#define USB_PID_MITSU_98__D 0x3B21 //#define USB_PID_MITSU_9810D XXXXXX //#define USB_PID_MITSU_9820DS XXXXXX @@ -150,7 +152,8 @@ struct mitsu9550_status { uint8_t sts1; // MM uint8_t nullb[1]; uint16_t copies; // BE, NN - uint8_t nullc[6]; + uint8_t sts2; // ZZ (9600 only?) + uint8_t nullc[5]; uint8_t sts3; // QQ uint8_t sts4; // RR uint8_t sts5; // SS @@ -162,9 +165,9 @@ struct mitsu9550_status { struct mitsu9550_status2 { uint8_t hdr[2]; /* 21 2e */ - uint8_t unk[40]; - uint8_t remain; /* BE, media remaining */ - uint8_t unkb[4]; + uint8_t unk[39]; + uint16_t remain; /* BE, media remaining */ + uint8_t unkb[4]; /* 0a 00 00 01 */ } __attribute__((packed)); #define CMDBUF_LEN 64 @@ -226,6 +229,11 @@ struct mitsu9550_status2 { sleep(1); \ goto top; \ } \ + /* Check for known errors */ \ + if (sts->sts2 != 0) { \ + ERROR("Printer cover open!\n"); \ + return CUPS_BACKEND_STOP; \ + } \ } while (0); static void *mitsu9550_init(void) @@ -909,6 +917,11 @@ top: ERROR("Unexpected response (sts3 %02x)\n", sts->sts3); return CUPS_BACKEND_FAILED; } + /* Check for known errors */ + if (sts->sts2 != 0) { + ERROR("Printer cover open!\n"); + return CUPS_BACKEND_STOP; + } } /* Send "end data" command */ @@ -1013,7 +1026,11 @@ top: INFO("Fast return mode enabled.\n"); break; } - + /* Check for known errors */ + if (sts->sts2 != 0) { + ERROR("Printer cover open!\n"); + return CUPS_BACKEND_STOP; + } sleep(1); } @@ -1036,8 +1053,15 @@ static void mitsu9550_dump_status(struct mitsu9550_status *resp) resp->sts1, resp->sts1 ? "Printing": "Idle"); INFO("Pages remaining : %03d\n", be16_to_cpu(resp->copies)); - INFO("Other status : %02x %02x %02x %02x %02x\n", - resp->sts3, resp->sts4, resp->sts5, resp->sts6, resp->sts7); + INFO("Other status : %02x %02x %02x %02x %02x %02x\n", + resp->sts2, resp->sts3, resp->sts4, + resp->sts5, resp->sts6, resp->sts7); +} + +static void mitsu9550_dump_status2(struct mitsu9550_status2 *resp) +{ + INFO("Prints remaining on media : %03d\n", + be16_to_cpu(resp->remain)); } static int mitsu9550_query_media(struct mitsu9550_ctx *ctx) @@ -1066,6 +1090,19 @@ static int mitsu9550_query_status(struct mitsu9550_ctx *ctx) return ret; } +static int mitsu9550_query_status2(struct mitsu9550_ctx *ctx) +{ + struct mitsu9550_status2 resp; + int ret; + + ret = mitsu9550_get_status(ctx, (uint8_t*) &resp, 0, 1, 0); + + if (!ret) + mitsu9550_dump_status2(&resp); + + return ret; +} + static int mitsu9550_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len) { struct mitsu9550_cmd cmd; @@ -1141,6 +1178,8 @@ static int mitsu9550_cmdline_arg(void *vctx, int argc, char **argv) break; case 's': j = mitsu9550_query_status(ctx); + if (!j) + j = mitsu9550_query_status2(ctx); break; default: break; /* Ignore completely */ @@ -1155,7 +1194,7 @@ static int mitsu9550_cmdline_arg(void *vctx, int argc, char **argv) /* Exported */ struct dyesub_backend mitsu9550_backend = { .name = "Mitsubishi CP-9550 family", - .version = "0.27", + .version = "0.29", .uri_prefix = "mitsu9550", .cmdline_usage = mitsu9550_cmdline, .cmdline_arg = mitsu9550_cmdline_arg, @@ -1166,14 +1205,16 @@ struct dyesub_backend mitsu9550_backend = { .main_loop = mitsu9550_main_loop, .query_serno = mitsu9550_query_serno, .devices = { + { USB_VID_MITSU, USB_PID_MITSU_9000AM, P_MITSU_9550, ""}, { USB_VID_MITSU, USB_PID_MITSU_9000D, P_MITSU_9550, ""}, { USB_VID_MITSU, USB_PID_MITSU_9500D, P_MITSU_9550, ""}, { USB_VID_MITSU, USB_PID_MITSU_9550D, P_MITSU_9550, ""}, { USB_VID_MITSU, USB_PID_MITSU_9550DS, P_MITSU_9550S, ""}, { USB_VID_MITSU, USB_PID_MITSU_9600D, P_MITSU_9600, ""}, // { USB_VID_MITSU, USB_PID_MITSU_9600D, P_MITSU_9600S, ""}, -// { USB_VID_MITSU, USB_PID_MITSU_9800D, P_MITSU_9800, ""}, + { USB_VID_MITSU, USB_PID_MITSU_9800D, P_MITSU_9800, ""}, { USB_VID_MITSU, USB_PID_MITSU_9800DS, P_MITSU_9800S, ""}, + { USB_VID_MITSU, USB_PID_MITSU_98__D, P_MITSU_9810, ""}, // { USB_VID_MITSU, USB_PID_MITSU_9810D, P_MITSU_9810, ""}, // { USB_VID_MITSU, USB_PID_MITSU_9820DS, P_MITSU_9820S, ""}, { 0, 0, 0, ""} @@ -1298,7 +1339,7 @@ struct dyesub_backend mitsu9550_backend = { Status Query -> 1b 56 30 00 - -> 30 2e 00 00 00 00 MM 00 NN NN 00 00 00 00 00 00 :: MM, NN + -> 30 2e 00 00 00 00 MM 00 NN NN ZZ 00 00 00 00 00 :: MM, NN, ZZ QQ RR SS 00 00 00 00 00 00 00 00 00 00 00 00 00 :: QQ, RR, SS 00 00 00 00 00 00 00 00 00 00 00 00 TT UU 00 00 :: TT, UU @@ -1395,10 +1436,7 @@ struct dyesub_backend mitsu9550_backend = { Seen on 9600DW - ?? 3e 00 00 8a 44 :: scrap bin? - ?? 3e 00 00 8a 45 :: No scrap bin | no paper? - ?? 3e 00 00 8a 46 :: no ribbon - ?? 3e 00 00 8a 47 :: Cover open + ZZ == 08 Door open Working theory of interpreting the status flags: diff --git a/src/cups/backend_mitsup95d.c b/src/cups/backend_mitsup95d.c new file mode 100644 index 0000000..140e918 --- /dev/null +++ b/src/cups/backend_mitsup95d.c @@ -0,0 +1,539 @@ +/* + * Mitsubishi P95D Monochrome Thermal Photo Printer CUPS backend + * + * (c) 2016 Solomon Peachy <pizza@shaftnet.org> + * + * The latest version of this program can be found at: + * + * http://git.shaftnet.org/cgit/selphy_print.git + * + * 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. + * + * [http://www.gnu.org/licenses/gpl-2.0.html] + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <signal.h> + +#define BACKEND mitsup95d_backend + +#include "backend_common.h" + +#define USB_VID_MITSU 0x06D3 +#define USB_PID_MITSU_P95D 0x3b10 + +/* Private data stucture */ +struct mitsup95d_ctx { + struct libusb_device_handle *dev; + uint8_t endp_up; + uint8_t endp_down; + + uint8_t mem_clr[4]; // 1b 5a 43 00 + int mem_clr_present; + + uint8_t hdr[2]; // 1b 51 + + uint8_t hdr1[50]; // 1b 57 20 2e ... + uint8_t hdr2[50]; // 1b 57 21 2e ... + uint8_t hdr3[50]; // 1b 57 22 2e ... + + uint8_t hdr4[36]; // 1b 58 ... + uint8_t plane[12]; // 1b 5a 74 00 ... + + uint8_t *databuf; + uint32_t datalen; + + uint8_t ftr[2]; +}; + + +static void *mitsup95d_init(void) +{ + struct mitsup95d_ctx *ctx = malloc(sizeof(struct mitsup95d_ctx)); + if (!ctx) { + ERROR("Memory Allocation Failure!\n"); + return NULL; + } + memset(ctx, 0, sizeof(struct mitsup95d_ctx)); + + return ctx; +} + +static void mitsup95d_attach(void *vctx, struct libusb_device_handle *dev, + uint8_t endp_up, uint8_t endp_down, uint8_t jobid) +{ + struct mitsup95d_ctx *ctx = vctx; + struct libusb_device *device; + struct libusb_device_descriptor desc; + + UNUSED(jobid); + + ctx->dev = dev; + ctx->endp_up = endp_up; + ctx->endp_down = endp_down; + + device = libusb_get_device(dev); + libusb_get_device_descriptor(device, &desc); + +} + +static void mitsup95d_teardown(void *vctx) { + struct mitsup95d_ctx *ctx = vctx; + + if (!ctx) + return; + + if (ctx->databuf) + free(ctx->databuf); + free(ctx); +} + +static int mitsup95d_read_parse(void *vctx, int data_fd) { + struct mitsup95d_ctx *ctx = vctx; + uint8_t buf[2]; /* Enough to read in any header */ + uint8_t tmphdr[50]; + uint8_t *ptr; + int i; + int remain; + int ptr_offset; + + if (!ctx) + return CUPS_BACKEND_FAILED; + + if (ctx->databuf) { + free(ctx->databuf); + 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; + break; + case 0x51: /* Job Header */ + remain = 2; + ptr = ctx->hdr; + break; + case 0x57: /* Geeneral headers */ + remain = sizeof(tmphdr); + ptr = tmphdr; + break; + case 0x58: /* User Comment */ + remain = 36; + ptr = ctx->hdr4; + break; + case 0x5a: /* Plane header */ + remain = 12; + ptr = ctx->plane; + break; + default: + ERROR("Unrecognized command! (%02x %02x)\n", buf[0], buf[1]); + return CUPS_BACKEND_CANCEL; + } + + 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) + return CUPS_BACKEND_CANCEL; + if (i < 0) + return CUPS_BACKEND_CANCEL; + remain -= i; + ptr_offset += i; + } + + if (ptr == tmphdr) { + if (tmphdr[3] != 46) { + ERROR("Unexpected header chunk: %02x %02x %02x %02x\n", + tmphdr[0], tmphdr[1], tmphdr[2], tmphdr[3]); + return CUPS_BACKEND_CANCEL; + } + switch (tmphdr[2]) { + case 0x20: + ptr = ctx->hdr1; + break; + case 0x21: + ptr = ctx->hdr2; + break; + case 0x22: + ptr = ctx->hdr3; + break; + default: + ERROR("Unexpected header chunk: %02x %02x %02x %02x\n", + tmphdr[0], tmphdr[1], tmphdr[2], tmphdr[3]); + } + memcpy(ptr, tmphdr, sizeof(tmphdr)); + } else if (ptr == ctx->plane) { + uint16_t rows = ctx->plane[10] << 8 | ctx->plane[11]; + uint16_t cols = ctx->plane[8] << 8 | ctx->plane[9]; + + remain = rows * cols; + + /* Allocate buffer for the payload */ + ctx->datalen = 0; + ctx->databuf = malloc(remain); + if (!ctx->databuf) { + ERROR("Memory allocation failure!\n"); + return CUPS_BACKEND_FAILED; + } + + /* Read it in */ + while (remain) { + i = read(data_fd, ctx->databuf + ctx->datalen, remain); + if (i == 0) + return CUPS_BACKEND_CANCEL; + if (i < 0) + return CUPS_BACKEND_CANCEL; + remain -= i; + ctx->datalen += i; + } + } else if (ptr == ctx->ftr) { + return CUPS_BACKEND_OK; + } + + goto top; +} + +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; + + /* 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; + + INFO("Waiting for printer idle\n"); + + /* Query Status to make sure printer is idle */ + do { + 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) { + 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) + 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, + ctx->mem_clr, sizeof(ctx->mem_clr)))) + return CUPS_BACKEND_FAILED; + } + + /* Send Job Start */ + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->hdr, sizeof(ctx->hdr)))) + return CUPS_BACKEND_FAILED; + + /* Send over headers */ + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->hdr1, sizeof(ctx->hdr1)))) + return CUPS_BACKEND_FAILED; + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->hdr2, sizeof(ctx->hdr2)))) + return CUPS_BACKEND_FAILED; + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->hdr3, sizeof(ctx->hdr3)))) + return CUPS_BACKEND_FAILED; + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->hdr4, sizeof(ctx->hdr4)))) + return CUPS_BACKEND_FAILED; + + /* Send plane header and image data */ + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->plane, sizeof(ctx->plane)))) + return CUPS_BACKEND_FAILED; + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->databuf, ctx->datalen))) + return CUPS_BACKEND_FAILED; + + /* Query Status to sanity-check job */ + 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) { + 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; + } + + /* Send over Footer */ + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->ftr, sizeof(ctx->ftr)))) + return CUPS_BACKEND_FAILED; + + INFO("Waiting for completion\n"); + + /* 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) { + 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 (queryresp[7] > 0) { + if (fast_return) { + INFO("Fast return mode enabled.\n"); + break; + } + } + } while(1); + + INFO("Print complete\n"); + return CUPS_BACKEND_OK; +} + +static int mitsup95d_cmdline_arg(void *vctx, int argc, char **argv) +{ + struct canonselphy_ctx *ctx = vctx; + int i, j = 0; + + if (!ctx) + return -1; + + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL)) >= 0) { + switch(i) { + GETOPT_PROCESS_GLOBAL + } + + if (j) return j; + } + + return 0; +} + +/* Exported */ +struct dyesub_backend mitsup95d_backend = { + .name = "Mitsubishi P95D", + .version = "0.02", + .uri_prefix = "mitsup95d", + .cmdline_arg = mitsup95d_cmdline_arg, + .init = mitsup95d_init, + .attach = mitsup95d_attach, + .teardown = mitsup95d_teardown, + .read_parse = mitsup95d_read_parse, + .main_loop = mitsup95d_main_loop, + .devices = { + { USB_VID_MITSU, USB_PID_MITSU_P95D, P_MITSU_P95D, ""}, + { 0, 0, 0, ""} + } +}; + +/***************************************************** + + Mitsubishi P95D Spool Format + + ...All fields are BIG ENDIAN. + + MEMORY_CLEAR (optional) + + 1b 5a 43 00 + + JOB_HDR + + 1b 51 + + PRINT_SETUP + + 1b 57 20 2e 00 0a 00 02 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! + + CC CC = columns, RR RR = rows (print dimensions) + + PRINT_OPTIONS + + + 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 + + NN = copies + 1..200 + 0xff (continuous print) + MM = comment type + 00 = None + 01 = Printer Setting + 02 = Date + 03 = DateTime + [[ .. ]] = actual comment (18 bytes), see below. + TT = media type + 00 = Standard + 01 = High Density + 02 = High Glossy + 03 = High Glossy (K95HG) + X = media cut length + 4..8 (mm) + Y = flags + 0x04 = Paper save + 0x03 = Buzzer (3 = high, 2 = low, 0 = off) + + + GAMMA ???? + + 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 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 ]] + + LL = Gamma table + 00 = Printer Setting + 01..05 Gamma table 1..5 + 10 = Use LUT + BB = Brightness (signed 8-bit) + CC = Contrast (signed 8-bit) + TT = Table present + 00 = No + 01 = Yes + [[ .. ]] = Gamma table, loaded from LUT on disk. (skip first 16 bytes) + + USER_COMMENT + + 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 ]] + + [[ .. ]] = Actual comment. 34 bytes payload, 0x20 -> 0x7e + (Null terminated?) + + IMAGE_DATA + + 1b 5a 74 00 00 00 YY YY CC CC RR RR + [[ .. data ... ]] + + CC CC = columns + RR CC = rows + YY YY = row offset + + Followed by C*R bytes of monochrome data, 0xff = white, 0x00 = black + + PRINT_START + + 1b 50 + + ********************************* + + Printer Comms: + + STATUS query + + -> 1b 72 00 00 + <- e4 72 00 00 04 XX 00 YY 00 + + YY == remaining copies + XX == Status? + 00 == Idle + 02 == Printing + 43 == Door open + 44 == No Paper + 4? == "Button" + 4? == "Gear Lock" + 4? == Head Up + ^ + \--- 0x40 appears to be a flag that indicates 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? + * 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 a2bbdd2..1b24797 100644 --- a/src/cups/backend_shinkos1245.c +++ b/src/cups/backend_shinkos1245.c @@ -497,7 +497,7 @@ static int shinkos1245_get_media(struct shinkos1245_ctx *ctx) shinkos1245_fill_hdr(&cmd.hdr); memset(cmd.pad, 0, sizeof(cmd.pad)); for (i = 1 ; i <= 3 ; i++) { - cmd.cmd[0] = 0x0a || (i << 4); + cmd.cmd[0] = 0x0a | (i << 4); ret = shinkos1245_do_cmd(ctx, &cmd, sizeof(cmd), &resp, sizeof(resp), &num); @@ -1639,7 +1639,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.10WIP", + .version = "0.11WIP", .uri_prefix = "shinkos1245", .cmdline_usage = shinkos1245_cmdline, .cmdline_arg = shinkos1245_cmdline_arg, diff --git a/src/cups/blacklist b/src/cups/blacklist index 650dd04..b0ddd2d 100644 --- a/src/cups/blacklist +++ b/src/cups/blacklist @@ -78,6 +78,15 @@ # Canon SELPHY CP900 0x04a9 0x3255 blacklist +# Canon SELPHY CP910 +0x04a9 0x327a blacklist + +# Canon SELPHY CP1000 +0x04a9 0x32ae blacklist + +# Canon SELPHY CP1200 +0x04a9 0x32b1 blacklist + # Canon SELPHY ES1 0x04a9 0x3141 blacklist @@ -135,12 +144,22 @@ # Sony UP-CR10L 0x054c 0x0226 blacklist -# Mitsubishi CP-D70/CP-D707 +# Mitsubishi CP-D70DW/CP-D707DW 0x06d3 0x3b30 blacklist +# Mitsubishi CP-D80DW +0x06d3 0x3b36 blacklist + # Mitsubishi CP-K60DW-S 0x06d3 0x3b31 blacklist +# Mitsubishi CP-9000D/DW/AM +0x06d3 0x0394 blacklist +0x06d3 0x0395 blacklist + +# Mitsubishi CP-9500D +0x06d3 0x0393 blacklist + # Mitsubishi CP-9550D/DW 0x06d3 0x03a1 blacklist @@ -150,9 +169,18 @@ # Mitsubishi CP-9600D/DW 0x06d3 0x03a9 blacklist +# Mitsubishi CP-9800D/DW +0x06d3 0x03ad blacklist + # Mitsubishi CP-9800DW-S 0x06d3 0x03ae blacklist +# Mitsubishi CP-9810D/DW +0x06d3 0x3b21 blacklist + +# Mitsubishi P95D +0x06d3 0x3b10 blacklist + # Citizen CW-01 0x1343 0x0002 blacklist @@ -175,5 +203,8 @@ 0x1343 0x0008 blacklist 0x1452 0x8b01 blacklist +# DNP DS820 +0x1452 0x9001 blacklist + # CIAAT Brava 21 0x10ce 0x001e blacklist diff --git a/src/cups/genppd.c b/src/cups/genppd.c index 0c8830d..2121f9d 100644 --- a/src/cups/genppd.c +++ b/src/cups/genppd.c @@ -56,6 +56,8 @@ #include <errno.h> #include <libgen.h> #include <strings.h> +#include <sys/types.h> +#include <sys/wait.h> #if defined(HAVE_VARARGS_H) && !defined(HAVE_STDARG_H) #include <varargs.h> #else @@ -454,6 +456,10 @@ main(int argc, /* I - Number of command-line arguments */ int opt_printmodels = 0;/* Print available models */ int which_ppds = 2; /* Simplified PPD's = 1, full = 2, no color opts = 4 */ + unsigned parallel = 1; /* Generate PPD files in parallel */ + unsigned rotor = 0; /* Rotor for generating PPD files in parallel */ + pid_t *subprocesses = NULL; + int parent = 1; /* * Parse command-line args... @@ -598,6 +604,32 @@ main(int argc, /* I - Number of command-line arguments */ * Write PPD files... */ + if (getenv("STP_PARALLEL")) + { + parallel = atoi(getenv("STP_PARALLEL")); + if (parallel < 1 || parallel > 256) + parallel = 1; + } + if (parallel) + { + subprocesses = stp_malloc(sizeof(pid_t) * parallel); + for (rotor = 0; rotor < parallel; rotor++) + { + pid_t pid = fork(); + if (pid == 0) /* Child */ + { + parent = 0; + break; + } + else if (pid > 0) + subprocesses[rotor] = pid; + else + { + fprintf(stderr, "Cannot fork: %s\n", strerror(errno)); + return 1; + } + } + } if (models) { int n; @@ -607,16 +639,19 @@ main(int argc, /* I - Number of command-line arguments */ if (!printer) printer = stp_get_printer_by_long_name(models[n]); - if (printer) + if (n % parallel == rotor && printer) { - if (generate_model_ppds(prefix, verbose, printer, language, - which_ppds)) - return 1; - } - else - { - printf("Driver not found: %s\n", models[n]); - return (1); + if (printer) + { + if (generate_model_ppds(prefix, verbose, printer, language, + which_ppds)) + return 1; + } + else + { + printf("Driver not found: %s\n", models[n]); + return (1); + } } } stp_free(models); @@ -626,16 +661,32 @@ main(int argc, /* I - Number of command-line arguments */ for (i = 0; i < stp_printer_model_count(); i++) { printer = stp_get_printer_by_index(i); - - if (printer) + + if (i % parallel == rotor && printer) { + if (! verbose && (i % 50) == 0) + fputc('.',stderr); if (generate_model_ppds(prefix, verbose, printer, language, which_ppds)) return 1; } } } - if (!verbose) + if (subprocesses) + { + pid_t pid; + do + { + int status; + pid = waitpid(-1, &status, 0); + if (pid > 0 && (!WIFEXITED(status) || WEXITSTATUS(status) != 0)) + { + fprintf(stderr, "failed!\n"); + return 1; + } + } while (pid > 0); + } + if (parent && !verbose) fprintf(stderr, " done.\n"); return (0); @@ -676,7 +727,6 @@ generate_ppd( ppd_location[1024]; /* Installed location */ struct stat dir; /* Prefix dir status */ const char *ppd_infix; - static int ppd_counter = 0; /* Notification counter */ /* * Skip the PostScript drivers... @@ -740,8 +790,6 @@ generate_ppd( if (verbose) fprintf(stderr, "Writing %s...\n", filename); - else if ((ppd_counter++ % 50) == 0) - fprintf(stderr, "."); snprintf(ppd_location, sizeof(ppd_location), "%s%s%s/%s", cups_modeldir, @@ -1539,9 +1587,17 @@ print_one_option(gpFile fp, stp_vars_t *v, const stp_string_list_t *po, int skip_color = (ppd_type == PPD_NO_COLOR_OPTS && is_color_opt); if (is_color_opt) gpprintf(fp, "*ColorKeyWords: \"Stp%s\"\n", desc->name); - gpprintf(fp, "*OpenUI *Stp%s/%s: PickOne\n", - desc->name, stp_i18n_lookup(po, desc->text)); - gpprintf(fp, "*OrderDependency: 10 AnySetup *Stp%s\n", desc->name); + +#ifndef FULL_RAW + if (desc->p_type != STP_PARAMETER_TYPE_RAW) + { +#endif + gpprintf(fp, "*OpenUI *Stp%s/%s: PickOne\n", + desc->name, stp_i18n_lookup(po, desc->text)); + gpprintf(fp, "*OrderDependency: 10 AnySetup *Stp%s\n", desc->name); +#ifndef FULL_RAW + } +#endif switch (desc->p_type) { case STP_PARAMETER_TYPE_STRING_LIST: @@ -1578,6 +1634,22 @@ print_one_option(gpFile fp, stp_vars_t *v, const stp_string_list_t *po, desc->name, opt->name, stp_i18n_lookup(po, opt->text)); } break; + case STP_PARAMETER_TYPE_RAW: + print_close_ui = 0; +#ifdef FULL_RAW /* XXX not sure if the standalone Custom... bit is sufficient */ + gpprintf(fp, "*StpStp%s: %d %d %d %d %d %.3f %.3f %.3f\n", + desc->name, desc->p_type, desc->is_mandatory, desc->p_class, + desc->p_level, desc->channel, 0.0, 0.0, 0.0); + gpprintf(fp, "*DefaultStp%s: None\n", desc->name); + gpprintf(fp, "*StpDefaultStp%s: None\n", desc->name); + gpprintf(fp, "*Stp%s %s/%s: \"\"\n", desc->name, "None", _("None")); + gpprintf(fp, "*CloseUI: *Stp%s\n", desc->name); +#endif + gpprintf(fp, "*CustomStp%s True: \"pop\"\n", desc->name); + gpprintf(fp, "*ParamCustomStp%s Text/%s: 1 string %d %d\n\n", + desc->name, _("Text"), 0, 0); + + break; case STP_PARAMETER_TYPE_BOOLEAN: gpprintf(fp, "*OPOptionHints Stp%s: \"checkbox\"\n", lparam->name); gpprintf(fp, "*StpStp%s: %d %d %d %d %d %.3f %.3f %.3f\n", @@ -1988,12 +2060,9 @@ write_ppd( } stp_parameter_description_destroy(&desc); - stp_describe_parameter(v, "NativeCopies", &desc); - if (desc.p_type == STP_PARAMETER_TYPE_BOOLEAN) + if (stp_check_boolean_parameter(v, "NativeCopies", STP_PARAMETER_ACTIVE)) nativecopies = stp_get_boolean_parameter(v, "NativeCopies"); - stp_parameter_description_destroy(&desc); - if (nativecopies) gpputs(fp, "*cupsManualCopies: False\n"); else @@ -2382,6 +2451,7 @@ write_ppd( if (lparam->p_class != j || lparam->p_level != k || is_special_option(lparam->name) || lparam->read_only || (lparam->p_type != STP_PARAMETER_TYPE_STRING_LIST && + lparam->p_type != STP_PARAMETER_TYPE_RAW && lparam->p_type != STP_PARAMETER_TYPE_BOOLEAN && lparam->p_type != STP_PARAMETER_TYPE_DIMENSION && lparam->p_type != STP_PARAMETER_TYPE_INT && diff --git a/src/cups/rastertoprinter.c b/src/cups/rastertoprinter.c index e68c90d..7cc3501 100644 --- a/src/cups/rastertoprinter.c +++ b/src/cups/rastertoprinter.c @@ -1124,7 +1124,6 @@ main(int argc, /* I - Number of command-line arguments */ (void) gettimeofday(&t1, NULL); stp_init(); version_id = stp_get_version(); - default_settings = stp_vars_create(); /* * Check for valid arguments... @@ -1290,6 +1289,7 @@ main(int argc, /* I - Number of command-line arguments */ if (! suppress_messages) fprintf(stderr, "DEBUG: Gutenprint: Using fd %d\n", fd); + default_settings = stp_vars_create_copy(stp_printer_get_defaults(printer)); stp_set_printer_defaults(default_settings, printer); #ifdef ENABLE_CUPS_LOAD_SAVE_OPTIONS if (load_file_name) @@ -1335,7 +1335,7 @@ main(int argc, /* I - Number of command-line arguments */ if (! suppress_messages) { fprintf(stderr, "DEBUG: Gutenprint: ================ Printing page %d ================\n", cups.page + 1); - fprintf(stderr, "PAGE: %d 1\n", cups.page + 1); + fprintf(stderr, "PAGE: %d %d\n", cups.page + 1, cups.header.NumCopies); } v = initialize_page(&cups, default_settings, page_size_name); #ifdef ENABLE_CUPS_LOAD_SAVE_OPTIONS @@ -1352,7 +1352,16 @@ main(int argc, /* I - Number of command-line arguments */ fprintf(stderr, "DEBUG: Gutenprint: Interim page settings:\n"); stpi_vars_print_error(v, "DEBUG"); } + stp_merge_printvars(v, stp_printer_get_defaults(printer)); + + /* Pass along Collation settings */ + stp_set_boolean_parameter(v, "Collate", cups.header.Collate); + stp_set_boolean_parameter_active(v, "Collate", STP_PARAMETER_ACTIVE); + /* Pass along Copy settings */ + stp_set_int_parameter(v, "NumCopies", cups.header.NumCopies); + stp_set_int_parameter_active(v, "NumCopies", STP_PARAMETER_ACTIVE); + /* Pass along the page number */ stp_set_int_parameter(v, "PageNumber", cups.page); cups.row = 0; if (! suppress_messages) diff --git a/src/cups/test-ppds b/src/cups/test-ppds index 542fd27..7d8713c 100755 --- a/src/cups/test-ppds +++ b/src/cups/test-ppds @@ -14,7 +14,11 @@ cupstestppdopts='-I profiles -W sizes -I filters' ppd_count=`find ppd \( -name '*.ppd.gz' -o -name '*.ppd' \) -print | wc -l` -failures="`find ppd -name '*.ppd*' -print | sort | xargs cupstestppd $cupstestppdopts |grep 'FAIL$' | awk -F: '{print $1}'`" +if [ -n "$STP_PARALLEL" ] ; then + PARALLEL="-P $STP_PARALLEL" +fi + +failures="`find ppd -name '*.ppd*' -print | sort -t/ -k3 -k2 | xargs $PARALLEL cupstestppd $cupstestppdopts |grep 'FAIL$' | awk -F: '{print $1}'`" if [ -z "$failures" ] ; then echo "All $ppd_count PPD files pass" diff --git a/src/cups/test-rastertogutenprint.in b/src/cups/test-rastertogutenprint.in index f3f1464..c64a8e4 100755 --- a/src/cups/test-rastertogutenprint.in +++ b/src/cups/test-rastertogutenprint.in @@ -30,6 +30,7 @@ outdir='' cupsargs='' postscript='' npages=3 +jobs=${STP_PARALLEL:-1} enable_static='@ENABLE_STATIC@' enable_shared='@ENABLE_SHARED@' @@ -59,6 +60,7 @@ set_args() { -m|--md5dir) shift; md5dir="$1" ;; -p|--pages) shift; npages="$1" ;; -P|--postscript) shift; postscript=1 ;; + -t|--parallel) shift; jobs="$1" ;; --) shift; args="$@"; return ;; *) return ;; esac @@ -132,16 +134,6 @@ if [ -z "$verbose" ] ; then export STP_SUPPRESS_MESSAGES fi -is_duplicate() { - model=`gunzip -c "$1" | grep '^.StpDriverModelFamily' | awk '{print $2}'` - for m in $all_models; do - if [ "$model" = "$m" ] ; then - skip=1 - fi - done - all_models="$model $all_models" -} - # Note that using CUPS arguments may trigger valgrind memory leaks in # CUPS. #cupsargs='PageSize=Custom.400.00x500.00' @@ -245,29 +237,38 @@ do_output() { fi } -if [ -d ppd/C ] ; then - for f in `get_ppds $args` ; do +runme() { + f="$1" + p=$(echo -n "`basename $f |sed -e 's/stp-//' -e 's/@GUTENPRINT_RELEASE_VERSION@.ppd.*$//'`... ") + PPD=$f + export PPD + if [ -x "$cupsdir/cgpdftoraster" ] ; then + output="$p `($cupsdir/cgpdftoraster 1 1 1 1 "" < "$tfile" 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" + elif [ -f "$tfile" -a -x "$cupsdir/gstoraster" ] ; then + output="$p `($cupsdir/gstoraster 1 1 1 1 \"$cupsargs\" < "$tfile" 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" + elif [ -f "$tfile" ] ; then + output="$p `($cupsdir/pstops 1 1 1 1 \"$cupsargs\" < "$tfile" 2>/dev/null | $cupsdir/pstoraster 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" + elif [ -x "$cupsdir/pstoraster" ] ; then + output="$p `($cupsdir/pdftops 1 1 1 1 \"$cupsargs\" < "$tfile" 2>/dev/null | $cupsdir/pstops 1 1 1 1 \"$pages$cupsargs\" 2>/dev/null | $cupsdir/pstoraster 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" + elif [ -x "$cupsdir/gstoraster" ] ; then + output="$p `($cupsdir/pdftops 1 1 1 1 \"$cupsargs\" < "$tfile" 2>/dev/null | $cupsdir/gstoraster 1 1 1 1 \"$pages$cupsargs\" 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" + else + output="$p `($cupsdir/imagetoraster 1 1 1 1 \"$cupsargs\" < calibrate.ppm 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2`" + fi + return $? +} + +runall() { + jobs="${1:-1}" + rotor="${2:-0}" + shift + shift + retval=0 + jobno=0 + for f in "$@" ; do skip='' - if [ -n "$single" ] ; then - is_duplicate $f - fi - if [ -z "$skip" ] ; then - echo -n "`basename $f |sed -e 's/stp-//' -e 's/@GUTENPRINT_RELEASE_VERSION@.ppd.*$//'`... " - PPD=$f - export PPD - if [ -x "$cupsdir/cgpdftoraster" ] ; then - output="`($cupsdir/cgpdftoraster 1 1 1 1 "" < "$tfile" 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" - elif [ -f "$tfile" -a -x "$cupsdir/gstoraster" ] ; then - output="`($cupsdir/gstoraster 1 1 1 1 \"$cupsargs\" < "$tfile" 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" - elif [ -f "$tfile" ] ; then - output="`($cupsdir/pstops 1 1 1 1 \"$cupsargs\" < "$tfile" 2>/dev/null | $cupsdir/pstoraster 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" - elif [ -x "$cupsdir/pstoraster" ] ; then - output="`($cupsdir/pdftops 1 1 1 1 \"$cupsargs\" < "$tfile" 2>/dev/null | $cupsdir/pstops 1 1 1 1 \"$pages$cupsargs\" 2>/dev/null | $cupsdir/pstoraster 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" - elif [ -x "$cupsdir/gstoraster" ] ; then - output="`($cupsdir/pdftops 1 1 1 1 \"$cupsargs\" < "$tfile" 2>/dev/null | $cupsdir/gstoraster 1 1 1 1 \"$pages$cupsargs\" 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2 `" - else - output="`($cupsdir/imagetoraster 1 1 1 1 \"$cupsargs\" < calibrate.ppm 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2`" - fi + if [ $((jobno % jobs)) -eq $rotor ] ; then + runme "$f" if [ $? -ne 0 ] ; then retval=1 fi @@ -277,6 +278,45 @@ if [ -d ppd/C ] ; then retval=1 fi fi + jobno=$((jobno+1)) + done + return $retval +} + +retval=0 +if [ -d ppd/C ] ; then + files=$(get_ppds $args) + if [ -n "$single" ] ; then + all_models="" + nondup_files="" + for f in $files ; do + if [ "$(basename $f .gz)" = "$(basename $f)" ] ; then + model=$(grep '^.StpDriverModelFamily' $f | awk '{print $2}') + else + model=$(gunzip -c $f | grep '^.StpDriverModelFamily' | awk '{print $2}') + fi + skip=0 + for m in $all_models ; do + if [ "$model" = "$m" ] ; then + skip=1 + break + fi + done + if [ "$skip" -eq 0 ] ; then + all_models="$model $all_models" + nondup_files="$nondup_files $f" + fi + done + files=$nondup_files + fi + for i in $(seq 0 $(($jobs-1))) ; do + runall $jobs $i $files & + done + for i in $(seq 0 $(($jobs-1))) ; do + wait -n + if [ "$?" -gt 0 ] ; then + retval=1 + fi done fi if [ -f "$tfile" ] ; then diff --git a/src/escputil/d4lib.c b/src/escputil/d4lib.c index aef85be..a8e9ff2 100644 --- a/src/escputil/d4lib.c +++ b/src/escputil/d4lib.c @@ -690,7 +690,7 @@ static int _readData(int fd, unsigned char *buf, int len) if ( total == 6 ) { - toGet = (header[2] >> 8) + header[3] - 6; + toGet = (header[2] << 8) + header[3] - 6; if (debugD4) printf("+++toGet: %i\n", toGet); total = 0; diff --git a/src/escputil/escputil.c b/src/escputil/escputil.c index 76c5fc8..971ca30 100644 --- a/src/escputil/escputil.c +++ b/src/escputil/escputil.c @@ -26,6 +26,7 @@ #include <stdio.h> #include <unistd.h> #include <string.h> +#include <strings.h> #include <stdlib.h> #include <errno.h> #include <signal.h> diff --git a/src/gimp2/print_gimp.h b/src/gimp2/print_gimp.h index e9a0ca6..7f95161 100644 --- a/src/gimp2/print_gimp.h +++ b/src/gimp2/print_gimp.h @@ -36,7 +36,7 @@ #include <gutenprintui2/gutenprintui.h> #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-pedantic" +#pragma GCC diagnostic ignored "-Wpedantic" #include <libgimp/gimp.h> #include <libgimp/gimpui.h> #pragma GCC diagnostic pop diff --git a/src/gutenprintui2/ui-utils.c b/src/gutenprintui2/ui-utils.c index 272e04f..baf5865 100644 --- a/src/gutenprintui2/ui-utils.c +++ b/src/gutenprintui2/ui-utils.c @@ -50,7 +50,7 @@ typedef void (*StpuiBasicCallback) (GObject *object, /* local callbacks of dialog_new () */ #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-pedantic" +#pragma GCC diagnostic ignored "-Wpedantic" static gint dialog_delete_callback (GtkWidget *widget, GdkEvent *event, @@ -82,7 +82,7 @@ dialog_delete_callback (GtkWidget *widget, * */ #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-pedantic" +#pragma GCC diagnostic ignored "-Wpedantic" static void dialog_create_action_areav (GtkDialog *dialog, va_list args) diff --git a/src/main/curve.c b/src/main/curve.c index 9c0795e..d552cc7 100644 --- a/src/main/curve.c +++ b/src/main/curve.c @@ -85,9 +85,6 @@ static const char *const stpi_wrap_mode_names[] = "wrap" }; -static const int stpi_wrap_mode_count = -(sizeof(stpi_wrap_mode_names) / sizeof(const char *)); - /* * Get the total number of points in the base sequence class */ diff --git a/src/main/generic-options.c b/src/main/generic-options.c index c91e41c..ed360f6 100644 --- a/src/main/generic-options.c +++ b/src/main/generic-options.c @@ -79,7 +79,19 @@ static const stp_parameter_t the_parameters[] = "PageNumber", N_("Page Number"), "Color=No,Category=Job Mode", N_("Page number"), STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_CORE, - STP_PARAMETER_LEVEL_BASIC, 0, 1, STP_CHANNEL_NONE, 1, 0 + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "NumCopies", N_("Number of Copies"), "Color=No,Category=Job Mode", + N_("Number of Copies"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_CORE, + STP_PARAMETER_LEVEL_INTERNAL, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, + { + "Collate", N_("Collate the Job"), "Color=No,Category=Job Mode", + N_("Collate the Job"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_CORE, + STP_PARAMETER_LEVEL_INTERNAL, 1, 0, STP_CHANNEL_NONE, 1, 0 }, }; @@ -252,5 +264,15 @@ stpi_describe_generic_parameter(const stp_vars_t *v, const char *name, description->bounds.integer.lower = 0; description->bounds.integer.upper = INT_MAX; } + else if (strcmp(name, "NumCopies") == 0) + { + description->deflt.integer = 1; + description->bounds.integer.lower = 1; + description->bounds.integer.upper = INT_MAX; + } + else if (strcmp(name, "Collate") == 0) + { + description->deflt.boolean = 0; + } } diff --git a/src/main/module.c b/src/main/module.c index c21d320..5d223bf 100644 --- a/src/main/module.c +++ b/src/main/module.c @@ -46,6 +46,9 @@ static int stp_module_register(stp_module_t *module); static void *stp_dlsym(void *handle, const char *symbol, const char *modulename); #endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-const-variable" + static const stpi_internal_module_class_t module_classes[] = { {STP_MODULE_CLASS_MISC, N_("Miscellaneous (unclassified)")}, @@ -54,6 +57,7 @@ static const stpi_internal_module_class_t module_classes[] = {STP_MODULE_CLASS_DITHER, N_("Dither algorithm")}, {STP_MODULE_CLASS_INVALID, NULL} /* Must be last */ }; +#pragma GCC diagnostic pop #if !defined(MODULE) extern stp_module_t print_canon_LTX_stp_module_data; diff --git a/src/main/print-color.c b/src/main/print-color.c index cf9c51b..6edd61b 100644 --- a/src/main/print-color.c +++ b/src/main/print-color.c @@ -1475,6 +1475,7 @@ stpi_compute_lut(stp_vars_t *v) for (i = 0; i < STP_CHANNEL_LIMIT; i++) { + STPI_ASSERT(i < raw_channel_param_count, v); if (lut->output_color_description->channel_count < 1 && i < lut->out_channels) setup_channel(v, i, &(raw_channel_params[i])); diff --git a/src/main/print-dpl.c b/src/main/print-dpl.c index 0802838..fde76ea 100644 --- a/src/main/print-dpl.c +++ b/src/main/print-dpl.c @@ -799,9 +799,11 @@ pcx_header (stp_vars_t * v, stp_image_t * image) unsigned short top; /* y = 0 is at bottom */ unsigned short bytes; short xdpi; - int *xdpi_p = (int *) (&xdpi); + int i_xdpi; + int *xdpi_p = (&i_xdpi); short ydpi; - int *ydpi_p = (int *) (&ydpi); + int i_ydpi; + int *ydpi_p = (&i_ydpi); int n; const short zero = 0; @@ -813,6 +815,9 @@ pcx_header (stp_vars_t * v, stp_image_t * image) /* Get resolutions */ dpl_describe_resolution (v, xdpi_p, ydpi_p); + xdpi = (short) i_xdpi; + ydpi = (short) i_ydpi; + bytes = (xdpi * 4 + 7 ) / 8; /* must be an even number */ if (bytes != (bytes & 0xfffe)) bytes++; diff --git a/src/main/print-lexmark.c b/src/main/print-lexmark.c index dcf9cbf..5d48bfb 100644 --- a/src/main/print-lexmark.c +++ b/src/main/print-lexmark.c @@ -951,7 +951,7 @@ get_media_type(const char *name, const lexmark_cap_t * caps) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-pedantic" +#pragma GCC diagnostic ignored "-Wpedantic" static inline int lexmark_source_type(const char *name, const lexmark_cap_t * caps) { diff --git a/src/main/print-olympus.c b/src/main/print-olympus.c index 73dfa67..59c8d0c 100644 --- a/src/main/print-olympus.c +++ b/src/main/print-olympus.c @@ -36,7 +36,7 @@ #include <string.h> #include <stdio.h> #include <limits.h> - +#include <time.h> /* For strftime() and localtime_r() */ #ifdef __GNUC__ #define inline __inline__ #endif @@ -55,6 +55,7 @@ #define DYESUB_FEATURE_BIGENDIAN 0x00000400 #define DYESUB_FEATURE_RGBtoYCBCR 0x00000800 #define DYESUB_FEATURE_DUPLEX 0x00001000 +#define DYESUB_FEATURE_MONOCHROME 0x00002000 /* Monochrome only..? */ #define DYESUB_PORTRAIT 0 #define DYESUB_LANDSCAPE 1 @@ -177,24 +178,53 @@ typedef struct { typedef struct { int multicut; + const char *print_speed; /* DS820 only */ } dnp_privdata_t; typedef struct { int quality; int finedeep; + int contrast; } mitsu9550_privdata_t; typedef struct { int quality; int laminate_offset; -#ifdef MITSU70X_8BPP int use_lut; -#endif int sharpen; + int delay; } mitsu70x_privdata_t; +typedef struct +{ + int sharpen; +} kodak9810_privdata_t; + +typedef struct +{ + int sharpen; + int matte_intensity; +} kodak8500_privdata_t; + +typedef struct +{ + int matte_intensity; + int dust_removal; +} shinko1245_privdata_t; + +typedef struct +{ + int clear_mem; + int cont_print; + int gamma; + int flags; + int comment; + char usercomment[34]; + char commentbuf[19]; /* With one extra byte for null termination */ +} mitsu_p95d_privdata_t; + /* Private data for dyesub driver as a whole */ typedef struct { @@ -211,10 +241,15 @@ typedef struct int bpp; const char* duplex_mode; int page_number; + int copies; union { dnp_privdata_t dnp; mitsu9550_privdata_t m9550; mitsu70x_privdata_t m70x; + kodak9810_privdata_t k9810; + kodak8500_privdata_t k8500; + shinko1245_privdata_t s1245; + mitsu_p95d_privdata_t m95d; } privdata; } dyesub_privdata_t; @@ -306,6 +341,13 @@ static const ink_t bgr_inks[] = LIST(ink_list_t, bgr_ink_list, ink_t, bgr_inks); +static const ink_t w_inks[] = +{ + { "Whitescale", 1, "BW", "\1" }, +}; + +LIST(ink_list_t, w_ink_list, ink_t, w_inks); + /* Olympus P-10 */ static const dyesub_resolution_t res_310dpi[] = { @@ -318,7 +360,6 @@ static const dyesub_pagesize_t p10_page[] = { { "w288h432", "4x6", 298, 430, 0, 0, 0, 0, DYESUB_PORTRAIT}, /* 4x6" */ { "B7", "3.5x5", 266, 370, 0, 0, 0, 0, DYESUB_PORTRAIT}, /* 3.5x5" */ - { "Custom", NULL, 298, 430, 28, 28, 48, 48, DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, p10_page_list, dyesub_pagesize_t, p10_page); @@ -327,7 +368,6 @@ static const dyesub_printsize_t p10_printsize[] = { { "310x310", "w288h432", 1280, 1848}, { "310x310", "B7", 1144, 1591}, - { "310x310", "Custom", 1280, 1848}, }; LIST(dyesub_printsize_list_t, p10_printsize_list, dyesub_printsize_t, p10_printsize); @@ -377,7 +417,6 @@ LIST(dyesub_resolution_list_t, res_320dpi_list, dyesub_resolution_t, res_320dpi) static const dyesub_pagesize_t p200_page[] = { { "ISOB7", "80x125mm", -1, -1, 16, 17, 33, 33, DYESUB_PORTRAIT}, - { "Custom", NULL, -1, -1, 16, 17, 33, 33, DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, p200_page_list, dyesub_pagesize_t, p200_page); @@ -385,7 +424,6 @@ LIST(dyesub_pagesize_list_t, p200_page_list, dyesub_pagesize_t, p200_page); static const dyesub_printsize_t p200_printsize[] = { { "320x320", "ISOB7", 960, 1280}, - { "320x320", "Custom", 960, 1280}, }; LIST(dyesub_printsize_list_t, p200_printsize_list, dyesub_printsize_t, p200_printsize); @@ -441,7 +479,6 @@ LIST(dyesub_resolution_list_t, p300_res_list, dyesub_resolution_t, p300_res); static const dyesub_pagesize_t p300_page[] = { { "A6", "A6", -1, -1, 28, 28, 48, 48, DYESUB_PORTRAIT}, - { "Custom", NULL, -1, -1, 28, 28, 48, 48, DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, p300_page_list, dyesub_pagesize_t, p300_page); @@ -450,8 +487,6 @@ static const dyesub_printsize_t p300_printsize[] = { { "306x306", "A6", 1024, 1376}, { "153x153", "A6", 512, 688}, - { "306x306", "Custom", 1024, 1376}, - { "153x153", "Custom", 512, 688}, }; LIST(dyesub_printsize_list_t, p300_printsize_list, dyesub_printsize_t, p300_printsize); @@ -551,7 +586,6 @@ static const dyesub_pagesize_t p400_page[] = { "A4", "A4", -1, -1, 22, 22, 54, 54, DYESUB_PORTRAIT}, { "c8x10", "A5 wide", -1, -1, 58, 59, 84, 85, DYESUB_PORTRAIT}, { "C6", "2 Postcards (A4)", -1, -1, 9, 9, 9, 9, DYESUB_PORTRAIT}, - { "Custom", NULL, -1, -1, 22, 22, 54, 54, DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, p400_page_list, dyesub_pagesize_t, p400_page); @@ -561,7 +595,6 @@ static const dyesub_printsize_t p400_printsize[] = { "314x314", "A4", 2400, 3200}, { "314x314", "c8x10", 2000, 2400}, { "314x314", "C6", 1328, 1920}, - { "314x314", "Custom", 2400, 3200}, }; LIST(dyesub_printsize_list_t, p400_printsize_list, dyesub_printsize_t, p400_printsize); @@ -678,7 +711,6 @@ static const dyesub_pagesize_t p440_page[] = { "c8x10", "A5 wide", -1, -1, 58, 59, 72, 72, DYESUB_PORTRAIT}, { "C6", "2 Postcards (A4)", -1, -1, 9, 9, 9, 9, DYESUB_PORTRAIT}, { "w255h581", "A6 wide", -1, -1, 25, 25, 25, 24, DYESUB_PORTRAIT}, - { "Custom", NULL, -1, -1, 22, 22, 54, 54, DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, p440_page_list, dyesub_pagesize_t, p440_page); @@ -689,7 +721,6 @@ static const dyesub_printsize_t p440_printsize[] = { "314x314", "c8x10", 2000, 2508}, { "314x314", "C6", 1328, 1920}, { "314x314", "w255h581", 892, 2320}, - { "314x314", "Custom", 2508, 3200}, }; LIST(dyesub_printsize_list_t, p440_printsize_list, dyesub_printsize_t, p440_printsize); @@ -697,8 +728,7 @@ LIST(dyesub_printsize_list_t, p440_printsize_list, dyesub_printsize_t, p440_prin static void p440_printer_init_func(stp_vars_t *v) { dyesub_privdata_t *pd = get_privdata(v); - int wide = ! (strcmp(pd->pagesize, "A4") == 0 - || strcmp(pd->pagesize, "Custom") == 0); + int wide = strcmp(pd->pagesize, "A4") != 0; stp_zprintf(v, "\033FP"); dyesub_nputc(v, '\0', 61); stp_zprintf(v, "\033Y"); @@ -734,8 +764,7 @@ static void p440_printer_end_func(stp_vars_t *v) static void p440_block_init_func(stp_vars_t *v) { dyesub_privdata_t *pd = get_privdata(v); - int wide = ! (strcmp(pd->pagesize, "A4") == 0 - || strcmp(pd->pagesize, "Custom") == 0); + int wide = strcmp(pd->pagesize, "A4") != 0; stp_zprintf(v, "\033ZT"); if (wide) @@ -774,7 +803,6 @@ static const dyesub_pagesize_t ps100_page[] = { { "w288h432", "4x6", 296, 426, 0, 0, 0, 0, DYESUB_PORTRAIT},/* 4x6" */ { "B7", "3.5x5", 264, 366, 0, 0, 0, 0, DYESUB_PORTRAIT}, /* 3.5x5" */ - { "Custom", NULL, 296, 426, 0, 0, 0, 0, DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, ps100_page_list, dyesub_pagesize_t, ps100_page); @@ -783,7 +811,6 @@ static const dyesub_printsize_t ps100_printsize[] = { { "306x306", "w288h432", 1254, 1808}, { "306x306", "B7", 1120, 1554}, - { "306x306", "Custom", 1254, 1808}, }; LIST(dyesub_printsize_list_t, ps100_printsize_list, dyesub_printsize_t, ps100_printsize); @@ -802,7 +829,7 @@ static void ps100_printer_init_func(stp_vars_t *v) stp_put16_be(pd->h_size, v); /* paper height (px) */ stp_put16_be(pd->w_size, v); /* paper width (px) */ dyesub_nputc(v, '\0', 3); - stp_putc('\1', v); /* number of copies */ + stp_putc(pd->copies, v); /* number of copies */ dyesub_nputc(v, '\0', 8); stp_putc('\1', v); dyesub_nputc(v, '\0', 15); @@ -1117,11 +1144,11 @@ static void cp900_printer_end_func(stp_vars_t *v) dyesub_nputc(v, 0x0, 4); } -/* Canon CP820/CP910 */ +/* Canon CP820/CP910/CP1000/CP1200 and beynod */ static const dyesub_pagesize_t cp910_page[] = { { "Postcard", "Postcard 100x148mm", PT(1248,300)+1, PT(1872,300)+1, 13, 13, 16, 19, DYESUB_PORTRAIT}, - { "w253h337", "CP_L 89x119mm", PT(1104,300)+1, PT(1536,300)+1, 13, 13, 15, 15, DYESUB_PORTRAIT}, + { "w253h337", "CP_L 89x119mm", PT(1152,300)+1, PT(1472,300)+1, 13, 13, 15, 15, DYESUB_PORTRAIT}, { "w155h244", "Card 54x86mm", PT(1088,300)+1, PT(668,300)+1, 13, 13, 15, 15, DYESUB_LANDSCAPE}, }; @@ -1130,7 +1157,7 @@ LIST(dyesub_pagesize_list_t, cp910_page_list, dyesub_pagesize_t, cp910_page); static const dyesub_printsize_t cp910_printsize[] = { { "300x300", "Postcard", 1248, 1872}, - { "300x300", "w253h337", 1104, 1536}, + { "300x300", "w253h337", 1152, 1472}, { "300x300", "w155h244", 668, 1088}, }; @@ -1155,28 +1182,8 @@ static void cp910_printer_init_func(stp_vars_t *v) dyesub_nputc(v, '\0', 5); - pg = (strcmp(pd->pagesize, "Postcard") == 0 ? 0xe0 : - (strcmp(pd->pagesize, "w253h337") == 0 ? 0x80 : - (strcmp(pd->pagesize, "w155h244") == 0 ? 0x40 : - 0xe0 ))); - stp_putc(pg, v); - - stp_putc(0x04, v); - dyesub_nputc(v, '\0', 2); - - pg = (strcmp(pd->pagesize, "Postcard") == 0 ? 0x50 : - (strcmp(pd->pagesize, "w253h337") == 0 ? 0xc0 : - (strcmp(pd->pagesize, "w155h244") == 0 ? 0x9c : - 0x50 ))); - stp_putc(pg, v); - - pg = (strcmp(pd->pagesize, "Postcard") == 0 ? 0x07 : - (strcmp(pd->pagesize, "w253h337") == 0 ? 0x05 : - (strcmp(pd->pagesize, "w155h244") == 0 ? 0x02 : - 0x07 ))); - stp_putc(pg, v); - - dyesub_nputc(v, '\0', 2); + stp_put32_le(pd->w_size, v); + stp_put32_le(pd->h_size, v); } /* Sony DPP-EX5, DPP-EX7 */ @@ -1192,8 +1199,6 @@ static const dyesub_pagesize_t dppex5_page[] = { { "w288h432", "Postcard", PT(1664,403)+1, PT(2466,403)+1, 13, 14, 18, 17, DYESUB_PORTRAIT}, - { "Custom", NULL, PT(1664,403)+1, PT(2466,403)+1, 13, 14, 18, 17, - DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, dppex5_page_list, dyesub_pagesize_t, dppex5_page); @@ -1201,7 +1206,6 @@ LIST(dyesub_pagesize_list_t, dppex5_page_list, dyesub_pagesize_t, dppex5_page); static const dyesub_printsize_t dppex5_printsize[] = { { "403x403", "w288h432", 1664, 2466}, - { "403x403", "Custom", 1664, 2466}, }; LIST(dyesub_printsize_list_t, dppex5_printsize_list, dyesub_printsize_t, dppex5_printsize); @@ -1263,11 +1267,6 @@ static const dyesub_pagesize_t updp10_page[] = { { "w288h432", "UPC-10P23 (4x6)", -1, -1, 12, 12, 18, 18, DYESUB_LANDSCAPE}, { "w288h387", "UPC-10P34 (4x5)", -1, 384, 12, 12, 16, 16, DYESUB_LANDSCAPE}, -#if 0 - /* We can't have two paper sizes that are the same size --rlk 20080813 */ - { "w288h432", "UPC-10S01 (Sticker)", -1, -1, 12, 12, 18, 18, DYESUB_LANDSCAPE}, -#endif - { "Custom", NULL, -1, -1, 12, 12, 0, 0, DYESUB_LANDSCAPE}, }; LIST(dyesub_pagesize_list_t, updp10_page_list, dyesub_pagesize_t, updp10_page); @@ -1276,7 +1275,6 @@ static const dyesub_printsize_t updp10_printsize[] = { { "300x300", "w288h432", 1200, 1800}, { "300x300", "w288h387", 1200, 1600}, - { "300x300", "Custom", 1200, 1800}, }; LIST(dyesub_printsize_list_t, updp10_printsize_list, dyesub_printsize_t, updp10_printsize); @@ -1513,7 +1511,7 @@ static void updr150_200_printer_init_func(stp_vars_t *v, int updr200) "\x1b\xee\x00\x00\x00\x02\x00" "\x02\x00\x00\x00" "\x00", 1, 43, v); - stp_putc(1, v); /* Copies */ + stp_putc(pd->copies, v); if (updr200) { /* UP-DR200-specific! */ stp_zfwrite("\x07\x00\x00\x00" @@ -1680,7 +1678,7 @@ static void upcr10_printer_end_func(stp_vars_t *v) stp_zfwrite("\xfa\xff\xff\xff" "\x09\x00\x00\x00" "\x1b\xee\x00\x00\x00\x02\x00\x00", 1, 16, v); - stp_putc(1, v); /* Copies */ + stp_putc(pd->copies, v); stp_zfwrite("\x07\x00\x00\x00" "\x1b\x17\x00\x00\x00\x00\x00", 1, 11, v); stp_zfwrite("\xf9\xff\xff\xff" @@ -1696,7 +1694,6 @@ static const dyesub_pagesize_t cx400_page[] = { "w288h432", "4x6", 295, 428, 24, 24, 23, 22, DYESUB_PORTRAIT}, { "w288h387", "4x5 3/8", 295, 386, 24, 24, 23, 23, DYESUB_PORTRAIT}, { "w288h504", "4x7", 295, 513, 24, 24, 23, 22, DYESUB_PORTRAIT}, - { "Custom", NULL, 295, 428, 0, 0, 0, 0, DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, cx400_page_list, dyesub_pagesize_t, cx400_page); @@ -1706,7 +1703,6 @@ static const dyesub_printsize_t cx400_printsize[] = { "310x310", "w288h387", 1268, 1658}, { "310x310", "w288h432", 1268, 1842}, { "310x310", "w288h504", 1268, 2208}, - { "310x310", "Custom", 1268, 1842}, }; LIST(dyesub_printsize_list_t, cx400_printsize_list, dyesub_printsize_t, cx400_printsize); @@ -1756,7 +1752,6 @@ LIST(dyesub_resolution_list_t, res_306dpi_list, dyesub_resolution_t, res_306dpi) static const dyesub_pagesize_t nx500_page[] = { { "Postcard", "Postcard", -1, -1, 21, 21, 29, 29, DYESUB_PORTRAIT}, - { "Custom", NULL, -1, -1, 21, 21, 29, 29, DYESUB_PORTRAIT}, }; LIST(dyesub_pagesize_list_t, nx500_page_list, dyesub_pagesize_t, nx500_page); @@ -1764,7 +1759,6 @@ LIST(dyesub_pagesize_list_t, nx500_page_list, dyesub_pagesize_t, nx500_page); static const dyesub_printsize_t nx500_printsize[] = { { "306x306", "Postcard", 1024, 1518}, - { "306x306", "Custom", 1024, 1518}, }; LIST(dyesub_printsize_list_t, nx500_printsize_list, dyesub_printsize_t, nx500_printsize); @@ -1791,8 +1785,6 @@ static const dyesub_pagesize_t kodak_dock_page[] = { { "w288h432", "4x6", PT(1248,300)+1, PT(1856,300)+1, 0, 0, 0, 0, DYESUB_PORTRAIT}, /* 4x6 */ - { "Custom", NULL, PT(1248,300)+1, PT(1856,300)+1, 0, 0, 0, 0, - DYESUB_PORTRAIT}, /* 4x6 */ }; LIST(dyesub_pagesize_list_t, kodak_dock_page_list, dyesub_pagesize_t, kodak_dock_page); @@ -1800,7 +1792,6 @@ LIST(dyesub_pagesize_list_t, kodak_dock_page_list, dyesub_pagesize_t, kodak_dock static const dyesub_printsize_t kodak_dock_printsize[] = { { "300x300", "w288h432", 1248, 1856}, - { "300x300", "Custom", 1248, 1856}, }; LIST(dyesub_printsize_list_t, kodak_dock_printsize_list, dyesub_printsize_t, kodak_dock_printsize); @@ -1870,12 +1861,33 @@ static const dyesub_printsize_t kodak_6850_printsize[] = LIST(dyesub_printsize_list_t, kodak_6850_printsize_list, dyesub_printsize_t, kodak_6850_printsize); +static unsigned short short_to_packed_bcd(unsigned short val) +{ + unsigned short bcd; + unsigned short i; + + /* Handle from 0-9999 */ + i = val % 10; + bcd = i; + val /= 10; + i = val % 10; + bcd |= (i << 4); + val /= 10; + i = val % 10; + bcd |= (i << 8); + val /= 10; + i = val % 10; + bcd |= (i << 12); + + return bcd; +} + static void kodak_68xx_printer_init(stp_vars_t *v) { dyesub_privdata_t *pd = get_privdata(v); stp_zfwrite("\x03\x1b\x43\x48\x43\x0a\x00\x01", 1, 8, v); - stp_put16_be(0x01, v); /* Number of copies in BCD */ + stp_put16_be(short_to_packed_bcd(pd->copies), v); /* Number of copies in BCD */ stp_put16_be(pd->w_size, v); stp_put16_be(pd->h_size, v); @@ -1920,7 +1932,7 @@ static void kodak_605_printer_init(stp_vars_t *v) dyesub_privdata_t *pd = get_privdata(v); stp_zfwrite("\x01\x40\x0a\x00\x01", 1, 5, v); - stp_putc(0x01, v); /* Number of copies */ + stp_put16_be(short_to_packed_bcd(pd->copies), v); /* Number of copies in BCD */ stp_putc(0x00, v); stp_put16_le(pd->w_size, v); stp_put16_le(pd->h_size, v); @@ -2056,7 +2068,7 @@ static void kodak_805_printer_init(stp_vars_t *v) dyesub_nputc(v, 0x00, 12); } -/* Kodak 9810 */ +/* Kodak 9810 / 8800 */ static const dyesub_pagesize_t kodak_9810_page[] = { { "c8x10", "8x10", PT(2464,300)+1, PT(3024,300)+1, 0, 0, 0, 0, DYESUB_PORTRAIT}, @@ -2080,6 +2092,63 @@ static const laminate_t kodak_9810_laminate[] = LIST(laminate_list_t, kodak_9810_laminate_list, laminate_t, kodak_9810_laminate); +static const stp_parameter_t kodak_9810_parameters[] = +{ + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (0 is off, 18 is normal, 24 is max"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define kodak_9810_parameter_count (sizeof(kodak_9810_parameters) / sizeof(const stp_parameter_t)) + +static int +kodak_9810_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities( + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "Sharpen") == 0) + { + description->deflt.integer = 18; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 24; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int kodak_9810_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + pd->privdata.k9810.sharpen = stp_get_int_parameter(v, "Sharpen"); + + return 1; +} + static void kodak_9810_printer_init(stp_vars_t *v) { dyesub_privdata_t *pd = get_privdata(v); @@ -2175,14 +2244,14 @@ static void kodak_9810_printer_init(stp_vars_t *v) dyesub_nputc(v, 0x00, 4); stp_put32_be(2, v); stp_putc(0xFF, v); - stp_putc(0x12, v); /* SHARPENING -- 0 is off, 0x12 Normal, 0x19 is High */ + stp_putc(pd->privdata.k9810.sharpen, v); /* Number of Copies */ stp_putc(0x1b, v); stp_zfwrite("FlsPgCopies ", 1, 19, v); dyesub_nputc(v, 0x00, 4); stp_put32_be(4, v); - stp_put32_be(1, v); /* Number of copies, at least 1 */ + stp_put32_be(pd->copies, v); /* Mirroring */ stp_putc(0x1b, v); @@ -2293,7 +2362,7 @@ static void kodak_8810_printer_init(stp_vars_t *v) stp_putc(0x12, v); stp_putc(0x00, v); stp_putc(0x01, v); - stp_put16_le(0x01, v); /* Actually, # of copies */ + stp_put16_le(pd->copies, v); stp_put16_le(pd->w_size, v); stp_put16_le(pd->h_size, v); stp_put16_le(pd->w_size, v); @@ -2336,7 +2405,7 @@ static void kodak_70xx_printer_init(stp_vars_t *v) dyesub_privdata_t *pd = get_privdata(v); stp_zfwrite("\x01\x40\x0a\x00\x01", 1, 5, v); - stp_put16_le(0x01, v); /* Actually, # of copies */ + stp_put16_le(pd->copies, v); stp_put16_le(pd->w_size, v); stp_put16_le(pd->h_size, v); @@ -2389,18 +2458,8 @@ LIST(dyesub_printsize_list_t, kodak_8500_printsize_list, dyesub_printsize_t, kod static const dyesub_media_t kodak_8500_media[] = { - { "Glossy", N_("Glossy"), {2, "\x00\x00"}}, - { "Matte+5", N_("Matte +5"), {2, "\x01\x05"}}, - { "Matte+4", N_("Matte +4"), {2, "\x01\x04"}}, - { "Matte+3", N_("Matte +3"), {2, "\x01\x03"}}, - { "Matte+2", N_("Matte +2"), {2, "\x01\x02"}}, - { "Matte+1", N_("Matte +1"), {2, "\x01\x01"}}, - { "Matte", N_("Matte"), {2, "\x01\x00"}}, - { "Matte-1", N_("Matte -1"), {2, "\x01\xff"}}, - { "Matte-2", N_("Matte -2"), {2, "\x01\xfe"}}, - { "Matte-3", N_("Matte -3"), {2, "\x01\xfd"}}, - { "Matte-4", N_("Matte -4"), {2, "\x01\xfc"}}, - { "Matte-5", N_("Matte -5"), {2, "\x01\xfb"}}, + { "Glossy", N_("Glossy"), {1, "\x00"}}, + { "Matte", N_("Matte"), {1, "\x01"}}, }; LIST(dyesub_media_list_t, kodak_8500_media_list, dyesub_media_t, kodak_8500_media); @@ -2412,6 +2471,77 @@ static const laminate_t kodak_8500_laminate[] = LIST(laminate_list_t, kodak_8500_laminate_list, laminate_t, kodak_8500_laminate); +static const stp_parameter_t kodak_8500_parameters[] = +{ + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (-5 through +5)"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MatteIntensity", N_("Matte Intensity"), "Color=No,Category=Advanced Printer Setup", + N_("Strengh of matte lamination pattern (-5 through +5)"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define kodak_8500_parameter_count (sizeof(kodak_8500_parameters) / sizeof(const stp_parameter_t)) + +static int +kodak_8500_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities( + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "Sharpen") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -5; + description->bounds.integer.upper = 5; + description->is_active = 1; + } + else if (strcmp(name, "MatteIntensity") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -5; + description->bounds.integer.upper = 5; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int kodak_8500_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + pd->privdata.k8500.sharpen = stp_get_int_parameter(v, "Sharpen"); + pd->privdata.k8500.matte_intensity = stp_get_int_parameter(v, "MatteIntensity"); + + return 1; +} + static void kodak_8500_printer_init(stp_vars_t *v) { dyesub_privdata_t *pd = get_privdata(v); @@ -2421,7 +2551,7 @@ static void kodak_8500_printer_init(stp_vars_t *v) /* Number of copies */ stp_putc(0x1b, v); stp_putc(0x4e, v); - stp_putc(1, v); /* 1-50 */ + stp_putc(pd->copies > 50 ? 50 : pd->copies, v); /* 1-50 */ dyesub_nputc(v, 0x00, 61); /* Paper type. Fixed. */ stp_putc(0x1b, v); @@ -2436,22 +2566,27 @@ static void kodak_8500_printer_init(stp_vars_t *v) stp_put16_be(pd->w_size, v); stp_put16_be(pd->h_size, v); dyesub_nputc(v, 0x00, 57); - /* Sharpening -- XXX not exported. */ + /* Sharpening */ stp_putc(0x1b, v); stp_putc(0x46, v); stp_putc(0x50, v); - stp_putc(0, v); /* 8-bit signed, range is +- 5. IOW, 0xfb->0x5 */ + stp_putc(pd->privdata.k8500.sharpen, v); dyesub_nputc(v, 0x00, 60); /* Lamination */ stp_putc(0x1b, v); stp_putc(0x59, v); - if (*((const char*)((pd->laminate->seq).data)) == 0x02) { /* None */ + if (*((const char*)((pd->laminate->seq).data)) == 0x02) { /* No lamination */ stp_putc(0x02, v); stp_putc(0x00, v); } else { stp_zfwrite((const char*)((pd->media->seq).data), 1, (pd->media->seq).bytes, v); - } + if (*((const char*)((pd->media->seq).data)) == 0x01) { /* Matte */ + stp_putc(pd->privdata.k8500.matte_intensity, v); + } else { + stp_putc(0x00, v); + } + } dyesub_nputc(v, 0x00, 60); /* Unknown */ stp_putc(0x1b, v); @@ -2488,6 +2623,469 @@ static void kodak_8500_printer_end(stp_vars_t *v) dyesub_nputc(v, 0x00, 62); } +/* Mitsubishi P95D/DW */ +static const dyesub_resolution_t res_325dpi[] = +{ + { "325x325", 325, 325}, +}; + +LIST(dyesub_resolution_list_t, res_325dpi_list, dyesub_resolution_t, res_325dpi); + +/* All are "custom" page sizes.. bleh.. */ +static const dyesub_pagesize_t mitsu_p95d_page[] = +{ + { "w213h284", "1280x960", PT(960,325)+1, PT(1280,325)+1, 0, 0, 0, 0, + DYESUB_LANDSCAPE}, + { "w227h284", "1280x1024", PT(1024,325)+1, PT(1280,325)+1, 0, 0, 0, 0, + DYESUB_LANDSCAPE}, + { "w284h284", "1280x1280", PT(1280,325)+1, PT(1280,325)+1, 0, 0, 0, 0, + DYESUB_PORTRAIT}, + { "w284h426", "1280x1920", PT(1280,325)+1, PT(1920,325)+1, 0, 0, 0, 0, + DYESUB_PORTRAIT}, + { "w284h1277", "1280x5760", PT(1280,325)+1, PT(5760,325)+1, 0, 0, 0, 0, + DYESUB_PORTRAIT}, + /* A true "custom" size, printer will cut at the image boundary */ + { "Custom", NULL, PT(1280,325)+1, -1, 0, 0, 0, 0, + DYESUB_PORTRAIT}, +}; + +LIST(dyesub_pagesize_list_t, mitsu_p95d_page_list, dyesub_pagesize_t, mitsu_p95d_page); + +static const dyesub_printsize_t mitsu_p95d_printsize[] = +{ + { "325x325", "w213h284", 960, 1280}, + { "325x325", "w227h284", 1024, 1280}, + { "325x325", "w284h284", 1280, 1280}, + { "325x325", "w284h426", 1280, 1920}, + { "325x325", "w284h1277", 1280, 5760}, + { "325x325", "Custom", 1280, 5760}, /* Maximum */ +}; + +LIST(dyesub_printsize_list_t, mitsu_p95d_printsize_list, dyesub_printsize_t, mitsu_p95d_printsize); + +static const dyesub_media_t mitsu_p95d_medias[] = +{ + {"Standard", N_("Standard (KP61B)"), {1, "\x00"}}, + {"HighDensity", N_("High Density (KP65HM)"), {1, "\x01"}}, + {"HighGlossy", N_("High Glossy (KP91HG)"), {1, "\x02"}}, + {"HighGlossyK95HG", N_("High Glosy (K95HG)"), {1, "\x03"}}, +}; + +LIST(dyesub_media_list_t, mitsu_p95d_media_list, dyesub_media_t, mitsu_p95d_medias); + +static const dyesub_stringitem_t mitsu_p95d_gammas[] = +{ + { "Printer", N_ ("Printer-Defined Setting") }, + { "T1", N_ ("Table 1") }, + { "T2", N_ ("Table 2") }, + { "T3", N_ ("Table 3") }, + { "T4", N_ ("Table 4") }, + { "T5", N_ ("Table 5") }, + { "LUT", N_ ("Use LUT") }, +}; +LIST(dyesub_stringlist_t, mitsu_p95d_gamma_list, dyesub_stringitem_t, mitsu_p95d_gammas); + +static const dyesub_stringitem_t mitsu_p95d_buzzers[] = +{ + { "Off", N_ ("Off") }, + { "Low", N_ ("Low") }, + { "High", N_ ("High") }, +}; +LIST(dyesub_stringlist_t, mitsu_p95d_buzzer_list, dyesub_stringitem_t, mitsu_p95d_buzzers); + +static const dyesub_stringitem_t mitsu_p95d_cutters[] = +{ + { "PaperSave", N_ ("Paper Save") }, + { "4mm", N_ ("4mm") }, + { "5mm", N_ ("5mm") }, + { "6mm", N_ ("6mm") }, + { "7mm", N_ ("7mm") }, + { "8mm", N_ ("8mm") }, +}; +LIST(dyesub_stringlist_t, mitsu_p95d_cutter_list, dyesub_stringitem_t, mitsu_p95d_cutters); + +static const dyesub_stringitem_t mitsu_p95d_comments[] = +{ + { "Off", N_ ("Off") }, + { "Settings", N_ ("Printer Settings") }, + { "Date", N_ ("Date") }, + { "DateTime", N_ ("Date and Time") }, +}; +LIST(dyesub_stringlist_t, mitsu_p95d_comment_list, dyesub_stringitem_t, mitsu_p95d_comments); + +static const stp_parameter_t mitsu_p95d_parameters[] = +{ + { + "P95Gamma", N_("Printer Gamma Correction"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Gamma Correction"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Buzzer", N_("Printer Buzzer"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Buzzer"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MediaCut", N_("Media Cut Length"), "Color=No,Category=Advanced Printer Setup", + N_("Media Cut Length"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Comment", N_("Generate Comment"), "Color=No,Category=Advanced Printer Setup", + N_("Generate Comment"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "ClearMemory", N_("Clear Memory"), "Color=No,Category=Advanced Printer Setup", + N_("Clear Memory"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "ContinuousPrint", N_("Continuous Printing"), "Color=No,Category=Advanced Printer Setup", + N_("Continuous Printing"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "P95Brightness", N_("Brightness"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Brightness Adjustment"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "P95Contrast", N_("Contrast"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Contrast Adjustment"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "UserComment", N_("User Comment"), "Color=No,Category=Advanced Printer Setup", + N_("User-specified comment (0-34 characters from 0x20->0x7E), null terminated if under 34 characters long"), + STP_PARAMETER_TYPE_RAW, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 0, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu_p95d_parameter_count (sizeof(mitsu_p95d_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu_p95d_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities( + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "P95Gamma") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_gamma_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } else if (strcmp(name, "Buzzer") == 0) { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_buzzer_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 2)->name; + description->is_active = 1; + } else if (strcmp(name, "MediaCut") == 0) { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_cutter_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 2)->name; + description->is_active = 1; + } else if (strcmp(name, "Comment") == 0) { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_comment_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } else if (strcmp(name, "ClearMemory") == 0) { + description->is_active = 1; + description->deflt.boolean = 0; + } else if (strcmp(name, "ContinuousPrint") == 0) { + description->is_active = 1; + description->deflt.boolean = 0; + } else if (strcmp(name, "P95Brightness") == 0) { + description->deflt.integer = 0; + description->bounds.integer.lower = -127; + description->bounds.integer.upper = 127; + description->is_active = 1; + } else if (strcmp(name, "P95Contrast") == 0) { + description->deflt.integer = 0; + description->bounds.integer.lower = -127; + description->bounds.integer.upper = 127; + description->is_active = 1; + } else if (strcmp(name, "UserComment") == 0) { + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu_p95d_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + const char *gamma = stp_get_string_parameter(v, "P95Gamma"); + const char *buzzer = stp_get_string_parameter(v, "Buzzer"); + const char *cutter = stp_get_string_parameter(v, "MediaCut"); + const char *comment = stp_get_string_parameter(v, "Comment"); + const stp_raw_t *usercomment = NULL; + + /* Sanity check */ + if (stp_check_raw_parameter(v, "UserComment", STP_PARAMETER_ACTIVE)) { + usercomment = stp_get_raw_parameter(v, "UserComment"); + if (usercomment->bytes > 34) { + stp_eprintf(v, _("StpUserComment must be between 0 and 34 bytes!\n")); + return 0; + } + } + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + pd->privdata.m95d.clear_mem = stp_get_boolean_parameter(v, "ClearMemory"); + pd->privdata.m95d.cont_print = stp_get_boolean_parameter(v, "ContinuousPrint"); + + if (pd->copies > 200) + pd->copies = 200; + + if (!strcmp(gamma, "Printer")) { + pd->privdata.m95d.gamma = 0x00; + } else if (!strcmp(gamma, "T1")) { + pd->privdata.m95d.gamma = 0x01; + } else if (!strcmp(gamma, "T2")) { + pd->privdata.m95d.gamma = 0x02; + } else if (!strcmp(gamma, "T3")) { + pd->privdata.m95d.gamma = 0x03; + } else if (!strcmp(gamma, "T4")) { + pd->privdata.m95d.gamma = 0x04; + } else if (!strcmp(gamma, "T5")) { + pd->privdata.m95d.gamma = 0x05; + } else if (!strcmp(gamma, "LUT")) { + pd->privdata.m95d.gamma = 0x10; + } + + if (!strcmp(buzzer, "Off")) { + pd->privdata.m95d.flags |= 0x00; + } else if (!strcmp(buzzer, "Low")) { + pd->privdata.m95d.flags |= 0x02; + } else if (!strcmp(buzzer, "High")) { + pd->privdata.m95d.flags |= 0x03; + } + + if (!strcmp(cutter, "PaperSave")) { + pd->privdata.m95d.flags |= 0x54; + } else if (!strcmp(cutter, "4mm")) { + pd->privdata.m95d.flags |= 0x40; + } else if (!strcmp(cutter, "5mm")) { + pd->privdata.m95d.flags |= 0x50; + } else if (!strcmp(cutter, "6mm")) { + pd->privdata.m95d.flags |= 0x60; + } else if (!strcmp(cutter, "7mm")) { + pd->privdata.m95d.flags |= 0x70; + } else if (!strcmp(cutter, "8mm")) { + pd->privdata.m95d.flags |= 0x80; + } + + if (!strcmp(comment, "Off")) { + memset(pd->privdata.m95d.commentbuf, 0, sizeof(pd->privdata.m95d.commentbuf)); + pd->privdata.m95d.comment = 0; + } else if (!strcmp(comment, "Settings")) { + memset(pd->privdata.m95d.commentbuf, 0, sizeof(pd->privdata.m95d.commentbuf)); + pd->privdata.m95d.comment = 1; + } else if (!strcmp(comment, "Date")) { + struct tm tmp; + time_t t; + t = time(NULL); + localtime_r(&t, &tmp); + strftime(pd->privdata.m95d.commentbuf, sizeof(pd->privdata.m95d.commentbuf), " %F", &tmp); + pd->privdata.m95d.comment = 2; + } else if (!strcmp(comment, "DateTime")) { + struct tm tmp; + time_t t; + t = time(NULL); + localtime_r(&t, &tmp); + strftime(pd->privdata.m95d.commentbuf, sizeof(pd->privdata.m95d.commentbuf), " %F %R", &tmp); + pd->privdata.m95d.comment = 3; + } + + if (usercomment) { + if (strncmp("None", usercomment->data, usercomment->bytes)) { + int i; + memcpy(pd->privdata.m95d.usercomment, usercomment->data, usercomment->bytes); + if (usercomment->bytes < 34) + pd->privdata.m95d.usercomment[usercomment->bytes] = 0; + for (i = 0 ; i < usercomment->bytes ; i++) { + if (pd->privdata.m95d.usercomment[i] < 0x20 || + pd->privdata.m95d.usercomment[i] > 0x7F) + pd->privdata.m95d.usercomment[i] = 0x20; + } + } + } else { + memset(pd->privdata.m95d.usercomment, 0x20, sizeof(pd->privdata.m95d.usercomment)); + } + + return 1; +} + +static const char *p95d_lut = "\x00\x12\x01\x5e\x03\x52\x05\xdc\x08\x66\x0a\x96\x0c\x3a\x0d\x70\x0e\x42\x0e\xce\x0f\x32\x0f\x78\x0f\xa0\x0f\xb4\x0f\xc8\x0f\xd8\x0f\xff"; /* Taken from "P95D.lut" dated 2016-05-25 */ + +static void mitsu_p95d_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Header */ + stp_putc(0x1b, v); + stp_putc(0x51, v); + + /* Clear memory */ + if (pd->privdata.m95d.clear_mem) { + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x43, v); + stp_putc(0x00, v); + } + + /* Page Setup */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + stp_putc(0x00, v); + stp_putc(0x02, v); + dyesub_nputc(v, 0x00, 6); + stp_put16_be(pd->w_size, v); /* Columns */ + stp_put16_be(pd->h_size, v); /* Rows */ + + /* This is only set under Windows if a "custom" size is selected, + but the USB comms always show it set to 1... */ + if (!strcmp(pd->pagesize,"Custom")) + stp_putc(0x01, v); + else + stp_putc(0x00, v); + dyesub_nputc(v, 0x00, 31); + + /* Print Options */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x4a, v); + stp_putc(0xaa, v); + stp_putc(0x00, v); + stp_putc(0x20, v); + stp_zfwrite((pd->media->seq).data, 1, 1, v); /* Media Type */ + stp_putc(0x00, v); + stp_putc(0x00, v); + stp_putc(0x64, v); + if (pd->privdata.m95d.cont_print) + stp_putc(0xff, v); + else + stp_putc(pd->copies, v); + stp_putc(0x00, v); + stp_putc(pd->privdata.m95d.comment, v); + stp_zfwrite(pd->privdata.m95d.commentbuf, 1, sizeof(pd->privdata.m95d.commentbuf) -1, v); + dyesub_nputc(v, 0x00, 3); + stp_putc(0x02, v); + dyesub_nputc(v, 0x00, 11); + stp_putc(pd->privdata.m95d.flags, v); + + /* Gamma */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x22, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x15, v); + if (pd->privdata.m95d.gamma == 0x10) + stp_putc(0x01, v); + else + stp_putc(0x00, v); + dyesub_nputc(v, 0x00, 5); + stp_putc(pd->privdata.m95d.gamma, v); + dyesub_nputc(v, 0x00, 3); + if (pd->privdata.m95d.gamma == 0x10) { + stp_zfwrite(p95d_lut, 1, sizeof(p95d_lut), v); /* XXX only for K95HG? */ + } else { + dyesub_nputc(v, 0x00, 34); + } + + /* User Comment */ + stp_putc(0x1b, v); + stp_putc(0x58, v); + stp_zfwrite(pd->privdata.m95d.usercomment, 1, sizeof(pd->privdata.m95d.usercomment), v); +} + +static void mitsu_p95d_plane_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Plane header */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x74, v); + stp_putc(0x00, v); + stp_put16_be(0, v); /* Column Offset */ + stp_put16_be(0, v); /* Row Offset */ + stp_put16_be(pd->w_size, v); /* Columns */ + stp_put16_be(pd->h_size, v); /* Rows */ +} + +static void mitsu_p95d_printer_end(stp_vars_t *v) +{ + /* Kick off the actual print */ + stp_putc(0x1b, v); + stp_putc(0x50, v); +} + /* Mitsubishi CP3020D/DU/DE */ static const dyesub_pagesize_t mitsu_cp3020d_page[] = { @@ -2527,7 +3125,7 @@ static void mitsu_cp3020d_printer_init(stp_vars_t *v) /* Number of copies */ stp_putc(0x1b, v); stp_putc(0x4e, v); - stp_putc(1, v); /* 1-50 */ + stp_putc(pd->copies > 50 ? 50 : pd->copies, v); /* 1-50 */ dyesub_nputc(v, 0x00, 61); /* Unknown */ stp_putc(0x1b, v); @@ -2617,7 +3215,7 @@ static void mitsu_cp3020da_printer_init(stp_vars_t *v) stp_putc(0x00, v); stp_putc(0x02, v); dyesub_nputc(v, 0x00, 19); - stp_putc(0x01, v); /* Copies -- 01-50d */ + stp_putc(pd->copies > 50 ? 50 : pd->copies, v); /* 1-50 */ dyesub_nputc(v, 0x00, 20); /* Contrast ? */ stp_putc(0x1b, v); @@ -2665,6 +3263,185 @@ static void mitsu_cp3020da_plane_init(stp_vars_t *v) stp_put16_be(pd->h_size, v); /* Number of rows in this block */ } +/* Mitsubishi 9500D/DW */ +static const dyesub_resolution_t res_m9500[] = +{ + { "346x346", 346, 346}, + { "346x792", 346, 792}, +}; + +LIST(dyesub_resolution_list_t, res_m9500_list, dyesub_resolution_t, res_m9500); + +static const dyesub_pagesize_t mitsu_cp9500_page[] = +{ + { "B7", "3.5x5", PT(1240,346)+1, PT(1812,346)+1, 0, 0, 0, 0, + DYESUB_LANDSCAPE}, + { "w288h432", "4x6", PT(1416,346)+1, PT(2152,346)+1, 0, 0, 0, 0, + DYESUB_LANDSCAPE}, + { "w360h504", "5x7", PT(1812,346)+1, PT(2452,346)+1, 0, 0, 0, 0, + DYESUB_PORTRAIT}, + { "w432h576", "6x8", PT(2152,346)+1, PT(2792,346)+1, 0, 0, 0, 0, + DYESUB_PORTRAIT}, + { "w432h648", "6x9", PT(2152,346)+1, PT(3146,346)+1, 0, 0, 0, 0, + DYESUB_PORTRAIT}, +}; + +LIST(dyesub_pagesize_list_t, mitsu_cp9500_page_list, dyesub_pagesize_t, mitsu_cp9500_page); + +static const dyesub_printsize_t mitsu_cp9500_printsize[] = +{ + { "346x346", "B7", 1240, 1812}, + { "346x792", "B7", 2480, 1812}, + { "346x346", "w288h432", 1416, 2152}, + { "346x792", "w288h432", 2832, 2152}, + { "346x346", "w360h504", 1812, 2452}, + { "346x792", "w360h504", 1812, 4904}, + { "346x346", "w432h576", 2152, 2792}, + { "346x792", "w432h576", 2152, 5584}, + { "346x346", "w432h648", 2152, 3146}, + { "346x792", "w432h648", 2152, 6292}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cp9500_printsize_list, dyesub_printsize_t, mitsu_cp9500_printsize); + +static void mitsu_cp9500_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Init */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x80, v); + stp_putc(0x00, v); + stp_putc(0x22, v); + stp_putc(0xa8, v); + stp_putc(0x03, v); + dyesub_nputc(v, 0x00, 18); + stp_put16_be(pd->copies, v); + dyesub_nputc(v, 0x00, 19); + stp_putc(0x01, v); + /* Parameters 1 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + stp_putc(0x10, v); + dyesub_nputc(v, 0x00, 7); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + dyesub_nputc(v, 0x00, 32); + /* Parameters 2 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x22, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0xf0, v); + dyesub_nputc(v, 0x00, 5); + stp_putc(0x00, v); // XXX 0x01 for "High Contrast" mode + dyesub_nputc(v, 0x00, 38); + /* Unknown */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x26, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x70, v); + dyesub_nputc(v, 0x00, 6); + stp_putc(0x01, v); + stp_putc(0x01, v); + dyesub_nputc(v, 0x00, 36); +} + +static void mitsu_cp9500_printer_end(stp_vars_t *v) +{ + /* Page Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + stp_putc(0x57, v); + stp_putc(0x00, v); +} + +static const dyesub_stringitem_t mitsu9500_contrasts[] = +{ + { "Photo", N_ ("Photo") }, + { "HighContrast", N_ ("High Contrast") }, +}; +LIST(dyesub_stringlist_t, mitsu9500_contrast_list, dyesub_stringitem_t, mitsu9500_contrasts); + +static const stp_parameter_t mitsu9500_parameters[] = +{ + { + "CP9500Contrast", N_("Printer Contrast"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Contrast"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu9500_parameter_count (sizeof(mitsu9500_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu9500_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities( + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "CP9500Contrast") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu9500_contrast_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu9500_parse_parameters(stp_vars_t *v) +{ + const char *contrast = stp_get_string_parameter(v, "CP9500Contrast"); + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + if (strcmp(contrast, "HighContrast") == 0) { + pd->privdata.m9550.contrast = 1; + } else { + pd->privdata.m9550.contrast = 0; + } + + return 1; +} + /* Mitsubishi 9550D/DW */ static const dyesub_resolution_t res_346dpi[] = { @@ -2816,7 +3593,7 @@ static void mitsu_cp9550_printer_init(stp_vars_t *v) stp_putc(0x08, v); stp_putc(0x03, v); dyesub_nputc(v, 0x00, 18); - stp_put16_be(1, v); /* Copies */ + stp_put16_be(pd->copies, v); dyesub_nputc(v, 0x00, 2); if (strcmp(pd->pagesize,"w288h432-div2") == 0) stp_putc(0x83, v); @@ -2960,7 +3737,7 @@ static void mitsu_cp9600_printer_init(stp_vars_t *v) stp_putc(0x00, v); stp_putc(0x03, v); dyesub_nputc(v, 0x00, 18); - stp_put16_be(1, v); /* Copies */ + stp_put16_be(pd->copies, v); dyesub_nputc(v, 0x00, 19); stp_putc(0x01, v); /* Parameters 2 */ @@ -3148,7 +3925,7 @@ static void mitsu_cp98xx_printer_init(stp_vars_t *v, int model) stp_putc(0x08, v); stp_putc(0x01, v); dyesub_nputc(v, 0x00, 18); - stp_put16_be(1, v); /* Copies */ + stp_put16_be(pd->copies, v); dyesub_nputc(v, 0x00, 8); stp_putc(pd->privdata.m9550.quality, v); dyesub_nputc(v, 0x00, 10); @@ -3295,7 +4072,7 @@ static const stp_parameter_t mitsu70x_parameters[] = }, #ifdef MITSU70X_8BPP { - "UseLUT", N_("Internal Color Correction"), "Color=No,Category=Advanced Printer Setup", + "UseLUT", N_("Internal Color Correction"), "Color=Yes,Category=Advanced Printer Setup", N_("Use Internal Color Correction"), STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 @@ -3345,6 +4122,7 @@ mitsu70x_load_parameters(const stp_vars_t *v, const char *name, #ifdef MITSU70X_8BPP else if (strcmp(name, "UseLUT") == 0) { + description->deflt.boolean = 0; description->is_active = 1; } else if (strcmp(name, "Sharpen") == 0) @@ -3607,6 +4385,7 @@ mitsu_k60_load_parameters(const stp_vars_t *v, const char *name, #ifdef MITSU70X_8BPP else if (strcmp(name, "UseLUT") == 0) { + description->deflt.boolean = 0; description->is_active = 1; } else if (strcmp(name, "Sharpen") == 0) @@ -3744,6 +4523,35 @@ static const dyesub_stringitem_t mitsu_d90_qualities[] = }; LIST(dyesub_stringlist_t, mitsu_d90_quality_list, dyesub_stringitem_t, mitsu_d90_qualities); +static const stp_parameter_t mitsu_d90_parameters[] = +{ + { + "PrintSpeed", N_("Print Speed"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "UseLUT", N_("Internal Color Correction"), "Color=Yes,Category=Advanced Printer Setup", + N_("Use Internal Color Correction"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (0 is off, 1 is min, 9 is max"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "ComboWait", N_("Combo Print Wait Time"), "Color=No,Category=Advanced Printer Setup", + N_("How many seconds to wait for a second print before starting"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu_d90_parameter_count (sizeof(mitsu_d90_parameters) / sizeof(const stp_parameter_t)) + static int mitsu_d90_load_parameters(const stp_vars_t *v, const char *name, stp_parameter_t *description) @@ -3776,9 +4584,9 @@ mitsu_d90_load_parameters(const stp_vars_t *v, const char *name, description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; description->is_active = 1; } -#ifdef MITSU70X_8BPP else if (strcmp(name, "UseLUT") == 0) { + description->deflt.boolean = 0; description->is_active = 1; } else if (strcmp(name, "Sharpen") == 0) @@ -3788,7 +4596,13 @@ mitsu_d90_load_parameters(const stp_vars_t *v, const char *name, description->bounds.integer.upper = 9; description->is_active = 1; } -#endif + else if (strcmp(name, "ComboWait") == 0) + { + description->deflt.integer = 5; + description->bounds.integer.lower = 1; + description->bounds.integer.upper = 25; + description->is_active = 1; + } else { return 0; @@ -3814,10 +4628,9 @@ static int mitsu_d90_parse_parameters(stp_vars_t *v) pd->privdata.m70x.quality = 0; } -#ifdef MITSU70X_8BPP pd->privdata.m70x.use_lut = stp_get_boolean_parameter(v, "UseLUT"); pd->privdata.m70x.sharpen = stp_get_int_parameter(v, "Sharpen"); -#endif + pd->privdata.m70x.delay = stp_get_int_parameter(v, "ComboWait"); return 1; } @@ -3894,13 +4707,15 @@ static void mitsu_cpd90_printer_init(stp_vars_t *v) static void mitsu_cpd90_printer_end(stp_vars_t *v) { + dyesub_privdata_t *pd = get_privdata(v); + /* Wrap it up */ stp_putc(0x1b, v); stp_putc(0x42, v); stp_putc(0x51, v); stp_putc(0x31, v); stp_putc(0x00, v); - stp_putc(0x05, v); /* XXX seconds to wait for second print */ + stp_putc(pd->privdata.m70x.delay, v); } /* Fujifilm ASK-300 */ @@ -3947,8 +4762,6 @@ static const dyesub_pagesize_t shinko_chcs9045_page[] = DYESUB_PORTRAIT}, { "w283h425", "Sticker paper", PT(1092,300)+1, PT(1726,300)+1, 0, 0, 0, 0, DYESUB_LANDSCAPE}, - { "Custom", NULL, PT(1240,300)+1, PT(1844,300)+1, 0, 0, 0, 0, - DYESUB_LANDSCAPE}, }; LIST(dyesub_pagesize_list_t, shinko_chcs9045_page_list, dyesub_pagesize_t, shinko_chcs9045_page); @@ -3960,7 +4773,6 @@ static const dyesub_printsize_t shinko_chcs9045_printsize[] = { "300x300", "w360h504", 1548, 2140}, { "300x300", "w432h648", 1844, 2740}, { "300x300", "w283h425", 1092, 1726}, - { "300x300", "Custom", 1240, 1844}, }; LIST(dyesub_printsize_list_t, shinko_chcs9045_printsize_list, dyesub_printsize_t, shinko_chcs9045_printsize); @@ -4090,7 +4902,7 @@ static void shinko_chcs2145_printer_init(stp_vars_t *v) stp_put32_le(0x00, v); stp_put32_le(pd->w_size, v); /* Columns */ stp_put32_le(pd->h_size, v); /* Rows */ - stp_put32_le(0x01, v); /* Copies */ + stp_put32_le(pd->copies, v); /* Copies */ stp_put32_le(0x00, v); stp_put32_le(0x00, v); @@ -4164,6 +4976,103 @@ static const laminate_t shinko_chcs1245_laminate[] = LIST(laminate_list_t, shinko_chcs1245_laminate_list, laminate_t, shinko_chcs1245_laminate); +static const dyesub_stringitem_t shinko_chcs1245_dusts[] = +{ + { "PrinterDefault", N_ ("Printer Default") }, + { "Off", N_ ("Off") }, + { "On", N_ ("On") } +}; +LIST(dyesub_stringlist_t, shinko_chcs1245_dust_list, dyesub_stringitem_t, shinko_chcs1245_dusts); + +static const stp_parameter_t shinko_chcs1245_parameters[] = +{ + { + "DustRemoval", N_("Dust Removal"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MatteIntensity", N_("Matte Intensity"), "Color=No,Category=Advanced Printer Setup", + N_("Strengh of matte lamination pattern (-25 through +25)"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define shinko_chcs1245_parameter_count (sizeof(shinko_chcs1245_parameters) / sizeof(const stp_parameter_t)) + +static int +shinko_chcs1245_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities( + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "DustRemoval") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &shinko_chcs1245_dust_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "MatteIntensity") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -25; + description->bounds.integer.upper = 25; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int shinko_chcs1245_parse_parameters(stp_vars_t *v) +{ + const char *dust = stp_get_string_parameter(v, "DustRemoval"); + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + + if (strcmp(dust, "PrinterDefault") == 0) { + pd->privdata.s1245.dust_removal = 3; + } else if (strcmp(dust, "Off") == 0) { + pd->privdata.s1245.dust_removal = 1; + } else if (strcmp(dust, "On") == 0) { + pd->privdata.s1245.dust_removal = 2; + } else { + pd->privdata.s1245.dust_removal = 0; + } + + pd->privdata.s1245.matte_intensity = stp_get_int_parameter(v, "MatteIntensity"); + + return 1; +} + static void shinko_chcs1245_printer_init(stp_vars_t *v) { dyesub_privdata_t *pd = get_privdata(v); @@ -4209,15 +5118,15 @@ static void shinko_chcs1245_printer_init(stp_vars_t *v) stp_put32_le(0x00, v); if (((const unsigned char*)(pd->laminate->seq).data)[0] == 0x02 || ((const unsigned char*)(pd->laminate->seq).data)[0] == 0x03) { - stp_put32_le(0x07fffffff, v); /* Glossy */ + stp_put32_le(0x07fffffff, v); /* Glossy */ } else { - stp_put32_le(0x0, v); /* XXX matte intensity -25>0>+25 */ + stp_put32_le(pd->privdata.s1245.matte_intensity, v); /* matte intensity */ } - stp_put32_le(0x00, v); /* XXX "dust removal mode" -- 0x00 printer default, 0x02 on, 0x01 for off. */ + stp_put32_le(pd->privdata.s1245.dust_removal, v); /* Dust Removal Mode */ stp_put32_le(pd->w_size, v); /* Columns */ stp_put32_le(pd->h_size, v); /* Rows */ - stp_put32_le(0x01, v); /* Copies */ + stp_put32_le(pd->copies, v); /* Copies */ stp_put32_le(0x00, v); stp_put32_le(0x00, v); @@ -4324,7 +5233,7 @@ static void shinko_chcs6245_printer_init(stp_vars_t *v) stp_put32_le(0x00, v); stp_put32_le(pd->w_size, v); /* Columns */ stp_put32_le(pd->h_size, v); /* Rows */ - stp_put32_le(0x01, v); /* Copies */ + stp_put32_le(pd->copies, v); /* Copies */ stp_put32_le(0x00, v); stp_put32_le(0x00, v); @@ -4455,7 +5364,7 @@ static void shinko_chcs6145_printer_init(stp_vars_t *v) stp_put32_le(0x00, v); stp_put32_le(pd->w_size, v); /* Columns */ stp_put32_le(pd->h_size, v); /* Rows */ - stp_put32_le(0x01, v); /* Copies */ + stp_put32_le(pd->copies, v); /* Copies */ stp_put32_le(0x00, v); stp_put32_le(0x00, v); @@ -4574,7 +5483,7 @@ static void dnp_printer_start_common(stp_vars_t *v) (pd->laminate->seq).bytes, v); /* Lamination mode */ /* Set quantity.. Backend overrides as needed. */ - stp_zprintf(v, "\033PCNTRL QTY 000000080000001\r"); + stp_zprintf(v, "\033PCNTRL QTY 00000008%07d\r", pd->copies); } static void dnpds40_printer_start(stp_vars_t *v) @@ -4681,7 +5590,7 @@ static const dyesub_pagesize_t dnpds80_page[] = { "c8x10-div2", "8x5*2", PT(2560,300)+1, PT(3102,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "c8x10-w576h432_w576h288", "8x6+8x4", PT(2560,300)+1, PT(3102,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h792-w576h432_w576h360", "8x6+8x5", PT(2560,300)+1, PT(3402,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, - { "A4", "A4 Length", PT(2560,300)+1, PT(3544,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h842", "8x11.7", PT(2560,300)+1, PT(3544,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h864", "8x12", PT(2560,300)+1, PT(3636,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h864-div2", "8x6*2", PT(2560,300)+1, PT(3702,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h864-w576h576_w576h288", "8x8+8x4", PT(2560,300)+1, PT(3702,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, @@ -4712,8 +5621,8 @@ static const dyesub_printsize_t dnpds80_printsize[] = { "300x600", "c8x10-w576h432_w576h288", 2560, 6204}, { "300x300", "w576h792-w576h432_w576h360", 2560, 3402}, { "300x600", "w576h792-w576h432_w576h360", 2560, 6804}, - { "300x300", "A4", 2560, 3544}, - { "300x600", "A4", 2560, 7088}, + { "300x300", "w576h842", 2560, 3544}, + { "300x600", "w576h842", 2560, 7088}, { "300x300", "w576h864", 2560, 3636}, { "300x600", "w576h864", 2560, 7272}, { "300x300", "w576h864-div2", 2560, 3702}, @@ -4760,7 +5669,7 @@ static int dnpds80_parse_parameters(stp_vars_t *v) multicut = 19; } else if (!strcmp(pagesize, "w576h864-div3")) { multicut = 20; - } else if (!strcmp(pagesize, "A4")) { + } else if (!strcmp(pagesize, "w576h842")) { multicut = 21; } else { stp_eprintf(v, _("Illegal print size selected for roll media!\n")); @@ -4802,14 +5711,12 @@ static int dnpds80dx_parse_parameters(stp_vars_t *v) const char *pagesize; const dyesub_media_t* media = NULL; const char* duplex_mode; - int page_number; dyesub_privdata_t *pd = get_privdata(v); int multicut = 0; pagesize = stp_get_string_parameter(v, "PageSize"); duplex_mode = stp_get_string_parameter(v, "Duplex"); media = dyesub_get_mediatype(v); - page_number = stp_get_int_parameter(v, "PageNumber"); if (!strcmp(media->name, "Roll")) { if (strcmp(duplex_mode, "None") && strcmp(duplex_mode, "Standard")) { @@ -4851,17 +5758,19 @@ static int dnpds80dx_parse_parameters(stp_vars_t *v) return 0; } + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + /* Add correct offset to multicut mode based on duplex state */ if (!strcmp(duplex_mode, "None") || !strcmp(duplex_mode, "Standard")) multicut += 100; /* Simplex */ - else if (page_number & 1) + else if (pd->page_number & 1) multicut += 300; /* Duplex, back */ else multicut += 200; /* Duplex, front */ - /* No need to set global params if there's no privdata yet */ - if (pd) - pd->privdata.dnp.multicut = multicut; + pd->privdata.dnp.multicut = multicut; return 1; } @@ -4888,7 +5797,7 @@ static const dyesub_pagesize_t dnpds80dx_page[] = { "w576h774-w576h756", "8x10.5", PT(2560,300)+1, PT(3186,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h774", "8x10.75", PT(2560,300)+1, PT(3186,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h792-w576h432_w576h360", "8x6+8x5", PT(2560,300)+1, PT(3402,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, - { "A4", "A4 Length", PT(2560,300)+1, PT(3544,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h842", "8x11.7", PT(2560,300)+1, PT(3544,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h864", "8x12", PT(2560,300)+1, PT(3636,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h864-div2", "8x6*2", PT(2560,300)+1, PT(3702,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, { "w576h864-w576h576_w576h288", "8x8+8x4", PT(2560,300)+1, PT(3702,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, @@ -4924,8 +5833,8 @@ static const dyesub_printsize_t dnpds80dx_printsize[] = { "300x600", "w576h774-w576h756", 2560, 6372}, { "300x300", "w576h792-w576h432_w576h360", 2560, 3402}, { "300x600", "w576h792-w576h432_w576h360", 2560, 6804}, - { "300x300", "A4", 2560, 3544}, - { "300x600", "A4", 2560, 7088}, + { "300x300", "w576h842", 2560, 3544}, + { "300x600", "w567h842", 2560, 7088}, { "300x300", "w576h864", 2560, 3636}, { "300x600", "w576h864", 2560, 7272}, { "300x300", "w576h864-div2", 2560, 3702}, @@ -5025,6 +5934,7 @@ static const laminate_t dnpds620_laminate[] = { {"Glossy", N_("Glossy"), {3, "000"}}, {"Matte", N_("Matte"), {3, "001"}}, + {"MatteFine", N_("Matte Fine"), {3, "021"}}, {"MatteLuster", N_("Matte Luster"), {3, "022"}}, }; @@ -5144,6 +6054,247 @@ static void dnpds620_printer_start(stp_vars_t *v) } } +/* Dai Nippon Printing DS820 */ + +/* Imaging area is wider than print size, we always must supply the + printer with the full imaging width. */ +static const dyesub_pagesize_t dnpds820_page[] = +{ + { "w288h576", "8x4", PT(1236,300)+1, PT(2560,300)+1, 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE}, + { "w360h576", "8x5", PT(1536,300)+1, PT(2560,300)+1, 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE}, + { "w432h576", "8x6", PT(1836,300)+1, PT(2560,300)+1, 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE}, + { "w504h576", "8x7", PT(2136,300)+1, PT(2560,300)+1, 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE}, + { "w576h576", "8x8", PT(2436,300)+1, PT(2560,300)+1, 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE}, + { "w576h576-div2", "8x4*2", PT(2502,300)+1, PT(2560,300)+1, 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE}, + { "w576h648", "8x9", PT(2560,300)+1, PT(2736,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h648-w576h360_w576h288", "8x5+8x4", PT(2560,300)+1, PT(2802,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "c8x10", "8x10", PT(2560,300)+1, PT(3036,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "c8x10-div2", "8x5*2", PT(2560,300)+1, PT(3102,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "c8x10-w576h432_w576h288", "8x6+8x4", PT(2560,300)+1, PT(3102,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h792-w576h432_w576h360", "8x6+8x5", PT(2560,300)+1, PT(3402,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h842", "8x11.7", PT(2560,300)+1, PT(3544,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h864", "8x12", PT(2560,300)+1, PT(3636,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h864-div2", "8x6*2", PT(2560,300)+1, PT(3702,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h864-w576h576_w576h288", "8x8+8x4", PT(2560,300)+1, PT(3702,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + { "w576h864-div3", "8x4*3", PT(2560,300)+1, PT(3768,300)+1, PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT}, + + { "A4x4inch", "A4x4inch", PT(1236,300)+1, PT(2560,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_LANDSCAPE}, + { "A4x5inch", "A4x5inch", PT(1536,300)+1, PT(2560,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_LANDSCAPE}, + { "A5", "A5", PT(1784,300)+1, PT(2560,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_LANDSCAPE}, + { "A4x6inch", "A4x6inch", PT(1836,300)+1, PT(2560,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_LANDSCAPE}, + { "A4x8inch", "A4x8inch", PT(2436,300)+1, PT(2560,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_LANDSCAPE}, + { "A4x10inch", "A4x10inch", PT(2560,300)+1, PT(3036,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_PORTRAIT}, + { "A4x10inch-div2", "A4x5inch*2", PT(2560,300)+1, PT(3102,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_PORTRAIT}, + { "A4", "A4", PT(2560,300)+1, PT(3544,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_PORTRAIT}, + { "A4-div2", "A5*2", PT(2560,300)+1, PT(3598,300)+1, PT(16,300), PT(16,300), 0, 0, DYESUB_PORTRAIT}, +}; + +LIST(dyesub_pagesize_list_t, dnpds820_page_list, dyesub_pagesize_t, dnpds820_page); + +static const dyesub_printsize_t dnpds820_printsize[] = +{ + { "300x300", "w288h576", 1236, 2560}, + { "300x600", "w288h576", 2472, 2560}, + { "300x300", "w360h576", 1536, 2560}, + { "300x600", "w360h576", 3072, 2560}, + { "300x300", "w432h576", 1836, 2560}, + { "300x600", "w432h576", 3672, 2560}, + { "300x300", "w504h576", 2136, 2560}, + { "300x600", "w504h576", 4272, 2560}, + { "300x300", "w576h576", 2436, 2560}, + { "300x600", "w576h576", 4872, 2560}, + { "300x300", "w576h576-div2", 2502, 2560}, + { "300x600", "w576h576-div2", 5004, 2560}, + { "300x300", "w576h648", 2560, 2736}, + { "300x600", "w576h648", 2560, 5472}, + { "300x300", "w576h648-w576h360_w576h288", 2560, 2802}, + { "300x600", "w576h648-w576h360_w576h288", 2560, 5604}, + { "300x300", "c8x10", 2560, 3036}, + { "300x600", "c8x10", 2560, 6072}, + { "300x300", "c8x10-div2", 2560, 3102}, + { "300x600", "c8x10-div2", 2560, 6204}, + { "300x300", "c8x10-w576h432_w576h288", 2560, 3102}, + { "300x600", "c8x10-w576h432_w576h288", 2560, 6204}, + { "300x300", "w576h792-w576h432_w576h360", 2560, 3402}, + { "300x600", "w576h792-w576h432_w576h360", 2560, 6804}, + { "300x300", "w576h842", 2560, 3544}, + { "300x600", "w576h842", 2560, 7088}, + { "300x300", "w576h864", 2560, 3636}, + { "300x600", "w576h864", 2560, 7272}, + { "300x300", "w576h864-div2", 2560, 3702}, + { "300x600", "w576h864-div2", 2560, 7404}, + { "300x300", "w576h864-w576h576_w576h288", 2560, 3702}, + { "300x600", "w576h864-w576h576_w576h288", 2560, 7404}, + { "300x300", "w576h864-div3", 2560, 3768}, + { "300x600", "w576h864-div3", 2560, 7536}, + + { "300x300", "A4x4inch", 2560, 1236}, + { "300x600", "A4x4inch", 2560, 2472}, + { "300x300", "A4x5inch", 2560, 1536}, + { "300x600", "A4x5inch", 2560, 3072}, + { "300x300", "A5", 2560, 1784}, + { "300x600", "A5", 2560, 3568}, + { "300x300", "A4x6inch", 2560, 1836}, + { "300x600", "A4x6inch", 2560, 3672}, + { "300x300", "A4x8inch", 2560, 2436}, + { "300x600", "A4x8inch", 2560, 4872}, + { "300x300", "A4x10inch", 2560, 3036}, + { "300x600", "A4x10inch", 2560, 6072}, + { "300x300", "A4x10inch-div2", 2560, 3102}, + { "300x600", "A4x10inch-div2", 2560, 6204}, + { "300x300", "A4", 2560, 3544}, + { "300x600", "A4", 2560, 7088}, + { "300x300", "A4-div2", 2560, 3598}, + { "300x600", "A4-div2", 2560, 7196}, +}; + +LIST(dyesub_printsize_list_t, dnpds820_printsize_list, dyesub_printsize_t, dnpds820_printsize); + +static void dnpds820_printer_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Common code */ + dnp_printer_start_common(v); + + /* Configure multi-cut/page size */ + stp_zprintf(v, "\033PIMAGE MULTICUT 00000008000000"); + + if (!strcmp(pd->pagesize, "c8x10")) { + stp_zprintf(v, "06"); + } else if (!strcmp(pd->pagesize, "w576h864")) { + stp_zprintf(v, "07"); + } else if (!strcmp(pd->pagesize, "w288h576")) { + stp_zprintf(v, "08"); + } else if (!strcmp(pd->pagesize, "w360h576")) { + stp_zprintf(v, "09"); + } else if (!strcmp(pd->pagesize, "w432h576")) { + stp_zprintf(v, "10"); + } else if (!strcmp(pd->pagesize, "w576h576")) { + stp_zprintf(v, "11"); + } else if (!strcmp(pd->pagesize, "w576h576-div2")) { + stp_zprintf(v, "13"); + } else if (!strcmp(pd->pagesize, "c8x10-div2")) { + stp_zprintf(v, "14"); + } else if (!strcmp(pd->pagesize, "w576h864-div2")) { + stp_zprintf(v, "15"); + } else if (!strcmp(pd->pagesize, "w576h648-w576h360_w576h288")) { + stp_zprintf(v, "16"); + } else if (!strcmp(pd->pagesize, "c8x10-w576h432_w576h288")) { + stp_zprintf(v, "17"); + } else if (!strcmp(pd->pagesize, "w576h792-w576h432_w576h360")) { + stp_zprintf(v, "18"); + } else if (!strcmp(pd->pagesize, "w576h864-w576h576_w576h288")) { + stp_zprintf(v, "19"); + } else if (!strcmp(pd->pagesize, "w576h864-div3")) { + stp_zprintf(v, "20"); + } else if (!strcmp(pd->pagesize, "w576h842")) { + stp_zprintf(v, "21"); + } else if (!strcmp(pd->pagesize, "w504h576")) { + stp_zprintf(v, "32"); + } else if (!strcmp(pd->pagesize, "w576h648")) { + stp_zprintf(v, "33"); + } else if (!strcmp(pd->pagesize, "A5")) { + stp_zprintf(v, "34"); + } else if (!strcmp(pd->pagesize, "A4x4inch")) { + stp_zprintf(v, "36"); + } else if (!strcmp(pd->pagesize, "A4x5inch")) { + stp_zprintf(v, "37"); + } else if (!strcmp(pd->pagesize, "A4x6inch")) { + stp_zprintf(v, "38"); + } else if (!strcmp(pd->pagesize, "A4x8inch")) { + stp_zprintf(v, "39"); + } else if (!strcmp(pd->pagesize, "A4x10inch")) { + stp_zprintf(v, "40"); + } else if (!strcmp(pd->pagesize, "A4x10inch-div2")) { + stp_zprintf(v, "43"); + } else if (!strcmp(pd->pagesize, "A4")) { + stp_zprintf(v, "41"); + } else if (!strcmp(pd->pagesize, "A4-div2")) { + stp_zprintf(v, "43"); + } else { + stp_zprintf(v, "00"); /* should not be possible */ + } + + if (!strcmp(pd->privdata.dnp.print_speed, "LowSpeed")) { + stp_zprintf(v, "\033PCNTRL PRINTSPEED 0000000800000020"); + } else if (!strcmp(pd->privdata.dnp.print_speed, "HighDensity")) { + stp_zprintf(v, "\033PCNTRL PRINTSPEED 0000000800000030"); + } +} + +static const dyesub_stringitem_t dnpds820_print_speeds[] = +{ + { "Normal", N_ ("Normal") }, + { "LowSpeed", N_ ("Low Speed") }, + { "HighDensity", N_ ("High Density") } +}; +LIST(dyesub_stringlist_t, dnpds820_printspeeds_list, dyesub_stringitem_t, dnpds820_print_speeds); + +static const stp_parameter_t ds820_parameters[] = +{ + { + "PrintSpeed", N_("Print Speed"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define ds820_parameter_count (sizeof(ds820_parameters) / sizeof(const stp_parameter_t)) + +static int +ds820_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities( + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "PrintSpeed") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &dnpds820_printspeeds_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int ds820_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + const char *print_speed; + + print_speed = stp_get_string_parameter(v, "PrintSpeed"); + + if (pd) { + pd->privdata.dnp.print_speed = print_speed; + } + + return 1; +} + /* Citizen CW-01 */ static const dyesub_resolution_t res_citizen_cw01_dpi[] = { @@ -5180,8 +6331,8 @@ static const dyesub_printsize_t citizen_cw01_printsize[] = { "334x600", "w360h504", 2048, 4276}, { "334x334", "w432h576", 2048, 2710}, { "334x600", "w432h576", 2048, 4870}, - { "334x334", "w432h576", 2048, 3050}, - { "334x600", "w432h576", 2048, 5480}, + { "334x334", "w432h648", 2048, 3050}, + { "334x600", "w432h648", 2048, 5480}, }; LIST(dyesub_printsize_list_t, citizen_cw01_printsize_list, dyesub_printsize_t, citizen_cw01_printsize); @@ -5213,7 +6364,7 @@ static void citizen_cw01_printer_start(stp_vars_t *v) } else { stp_putc(0x00, v); } - stp_putc(0x01, v); /* This is actually number of copies */ + stp_putc(pd->copies, v); stp_putc(0x00, v); /* Compute plane size */ @@ -5807,7 +6958,7 @@ static const dyesub_cap_t dyesub_model_capabilities[] = NULL, NULL, NULL, 0, NULL, NULL, }, - { /* Kodak Professional 9810 */ + { /* Kodak Professional 9810 (and 8800) */ 4006, &ymc_ink_list, &res_300dpi_list, @@ -5822,7 +6973,10 @@ static const dyesub_cap_t dyesub_model_capabilities[] = NULL, &kodak_9810_laminate_list, NULL, NULL, NULL, - NULL, 0, NULL, NULL, + kodak_9810_parameters, + kodak_9810_parameter_count, + kodak_9810_load_parameters, + kodak_9810_parse_parameters, }, { /* Kodak 8810 */ 4007, @@ -5889,7 +7043,10 @@ static const dyesub_cap_t dyesub_model_capabilities[] = NULL, &kodak_8500_laminate_list, &kodak_8500_media_list, NULL, NULL, - NULL, 0, NULL, NULL, + kodak_8500_parameters, + kodak_8500_parameter_count, + kodak_8500_load_parameters, + kodak_8500_parse_parameters, }, { /* Mitsubishi CP3020D/DU/DE */ 4101, @@ -6100,8 +7257,8 @@ static const dyesub_cap_t dyesub_model_capabilities[] = NULL, &mitsu_cpd70x_laminate_list, NULL, NULL, NULL, - mitsu70x_parameters, - mitsu70x_parameter_count, + mitsu_d90_parameters, + mitsu_d90_parameter_count, mitsu_d90_load_parameters, mitsu_d90_parse_parameters, }, @@ -6193,6 +7350,46 @@ static const dyesub_cap_t dyesub_model_capabilities[] = mitsu9810_load_parameters, mitsu9810_parse_parameters, }, + { /* Mitsubishi P95D/DW */ + 4114, + &w_ink_list, + &res_325dpi_list, + &mitsu_p95d_page_list, + &mitsu_p95d_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_MONOCHROME, + &mitsu_p95d_printer_init, &mitsu_p95d_printer_end, + &mitsu_p95d_plane_start, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, &mitsu_p95d_media_list, + NULL, NULL, + mitsu_p95d_parameters, + mitsu_p95d_parameter_count, + mitsu_p95d_load_parameters, + mitsu_p95d_parse_parameters, + }, + { /* Mitsubishi CP9500D */ + 4115, + &bgr_ink_list, + &res_m9500_list, + &mitsu_cp9500_page_list, + &mitsu_cp9500_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE, + &mitsu_cp9500_printer_init, &mitsu_cp9500_printer_end, + &mitsu_cp3020da_plane_init, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + mitsu9500_parameters, + mitsu9500_parameter_count, + mitsu9500_load_parameters, + mitsu9500_parse_parameters, + }, { /* Shinko CHC-S9045 (experimental) */ 5000, &rgb_ink_list, @@ -6239,7 +7436,10 @@ static const dyesub_cap_t dyesub_model_capabilities[] = NULL, &shinko_chcs1245_laminate_list, NULL, NULL, NULL, - NULL, 0, NULL, NULL, + shinko_chcs1245_parameters, + shinko_chcs1245_parameter_count, + shinko_chcs1245_load_parameters, + shinko_chcs1245_parse_parameters, }, { /* Shinko/Sinfonia CHC-S6245 */ 5003, @@ -6391,6 +7591,26 @@ static const dyesub_cap_t dyesub_model_capabilities[] = NULL, NULL, NULL, 0, NULL, dnpds80dx_parse_parameters, }, + { /* Dai Nippon Printing DS820 */ + 6007, + &bgr_ink_list, + &res_dnpds40_dpi_list, + &dnpds820_page_list, + &dnpds820_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_PLANE_LEFTTORIGHT, + &dnpds820_printer_start, &dnpds40_printer_end, + &dnpds40_plane_init, NULL, + NULL, NULL, + NULL, + &dnpds620_laminate_list, NULL, + NULL, NULL, + ds820_parameters, + ds820_parameter_count, + ds820_load_parameters, + ds820_parse_parameters, + }, }; static const stp_parameter_t the_parameters[] = @@ -6430,7 +7650,7 @@ static const stp_parameter_t the_parameters[] = /* better durability of output by covering it with transparent */ /* laminate surface. This surface can be of different patterns: */ /* common are matte, glossy or texture. */ - "Laminate", N_("Laminate Pattern"), "Color=Yes,Category=Advanced Printer Setup", + "Laminate", N_("Laminate Pattern"), "Color=No,Category=Advanced Printer Setup", N_("Laminate Pattern"), STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, STP_PARAMETER_LEVEL_BASIC, 1, 0, STP_CHANNEL_NONE, 1, 0 @@ -6448,17 +7668,17 @@ static const stp_parameter_t the_parameters[] = STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 }, { - "NativeCopies", N_("Printer Generates Copies Natively"), "Color=No,Category=Advanced Printer Functionality", - N_("Printer Generates Copies"), - STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, - STP_PARAMETER_LEVEL_INTERNAL, 0, 0, STP_CHANNEL_NONE, 0, 1 - }, - { "Duplex", N_("Double-Sided Printing"), "Color=No,Category=Basic Printer Setup", N_("Duplex/Tumble Setting"), STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 }, + { + "NativeCopies", N_("Printer Generates Copies Natively"), "Color=No,Category=Job Mode", + N_("Printer Generates Copies"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_INTERNAL, 0, 0, STP_CHANNEL_NONE, 0, 1 + }, }; static int the_parameter_count = @@ -6763,8 +7983,12 @@ dyesub_parameters(const stp_vars_t *v, const char *name, else if (strcmp(name, "PrintingMode") == 0) { description->bounds.str = stp_string_list_create(); - stp_string_list_add_string - (description->bounds.str, "Color", _("Color")); + if (dyesub_feature(caps, DYESUB_FEATURE_MONOCHROME)) + stp_string_list_add_string(description->bounds.str, + "BW", _("Black and White")); + else + stp_string_list_add_string(description->bounds.str, + "Color", _("Color")); description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; } @@ -7370,6 +8594,15 @@ dyesub_do_print(stp_vars_t *v, stp_image_t *image) if((pd->page_number & 1) && pd->duplex_mode && !strcmp(pd->duplex_mode,"DuplexNoTumble")) image = stpi_buffer_image(image,BUFFER_FLAG_FLIP_X | BUFFER_FLAG_FLIP_Y); + /* Check to see if we're to generate more than one copy */ + if (stp_check_boolean_parameter(v, "NativeCopies", STP_PARAMETER_ACTIVE) && + stp_get_boolean_parameter(v, "NativeCopies") && + stp_check_int_parameter(v, "NumCopies", STP_PARAMETER_ACTIVE)) + pd->copies = stp_get_int_parameter(v, "NumCopies"); + else + pd->copies = 1; + /* FIXME: What about Collation? Any special handling here? */ + pd->pagesize = stp_get_string_parameter(v, "PageSize"); if (caps->laminate) pd->laminate = dyesub_get_laminate_pattern(v); @@ -7470,7 +8703,7 @@ dyesub_do_print(stp_vars_t *v, stp_image_t *image) pv.empty_byte[0] = 0xff; /* Y */ pv.empty_byte[1] = 0x80; /* Cb */ pv.empty_byte[2] = 0x80; /* Cr */ - } else if (strcmp(ink_type, "RGB") == 0 || strcmp(ink_type, "BGR") == 0) { + } else if (strcmp(ink_type, "RGB") == 0 || strcmp(ink_type, "BGR") == 0 || strcmp(ink_type, "Whitescale") == 0) { pv.empty_byte[0] = 0xff; pv.empty_byte[1] = 0xff; pv.empty_byte[2] = 0xff; diff --git a/src/main/print-pcl.c b/src/main/print-pcl.c index 0169c8b..9445b04 100644 --- a/src/main/print-pcl.c +++ b/src/main/print-pcl.c @@ -369,12 +369,6 @@ static const short standard_papersizes[] = -1, }; -static const short letter_only_papersizes[] = -{ - PCL_PAPERSIZE_LETTER, - -1 -}; - static const short letter_a4_papersizes[] = { PCL_PAPERSIZE_A4, @@ -1403,6 +1397,8 @@ static const pcl_cap_t pcl_model_capabilities[] = }, }; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-const-variable" static const char standard_sat_adjustment[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" @@ -1418,6 +1414,7 @@ static const char standard_sat_adjustment[] = "</sequence>\n" "</curve>\n" "</gutenprint>\n"; +#pragma GCC diagnostic pop static const char standard_lum_adjustment[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" @@ -2566,8 +2563,6 @@ pcl_do_print(stp_vars_t *v, stp_image_t *image) the_left_margin; /* Corrected left margin */ int manual_feed_left_adjust = 0; int extra_left_margin = 0; - stp_curve_t *lum_adjustment; - stp_curve_t *hue_adjustment; double density; int label = 0; @@ -3226,13 +3221,30 @@ pcl_do_print(stp_vars_t *v, stp_image_t *image) if (!stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_ACTIVE)) { - hue_adjustment = stp_curve_create_from_string(standard_hue_adjustment); + stp_curve_t *hue_adjustment = + stp_curve_create_from_string(standard_hue_adjustment); stp_set_curve_parameter(v, "HueMap", hue_adjustment); stp_curve_destroy(hue_adjustment); } if (!stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_ACTIVE)) { - lum_adjustment = stp_curve_create_from_string(standard_lum_adjustment); + stp_curve_t *lum_adjustment = + stp_curve_create_from_string(standard_lum_adjustment); +#if 0 + /* + * This would represent a change to the PCL driver in 5.2.12 + * + * This call was missing and has represented a bug (if a clearly + * non-fatal one) in the PCL driver since time immemorial. The + * non-use of the variable was finally called out by gcc6. In my + * judgment, fixing the bug and changing the output of many PCL + * printers (even if it were for the better) would be more problematic + * than leaving the output as-is. + * + * - Robert Krawitz 2016-12-29 + */ + stp_set_curve_parameter(v, "LumMap", lum_adjustment); +#endif stp_curve_destroy(lum_adjustment); } diff --git a/src/testpattern/Makefile.am b/src/testpattern/Makefile.am index 8e3089d..0482a05 100644 --- a/src/testpattern/Makefile.am +++ b/src/testpattern/Makefile.am @@ -25,12 +25,12 @@ include $(top_srcdir)/scripts/global.mk pkgdatadir = $(datadir)/$(PACKAGE)/samples -TESTS = run-testpattern-1 run-testpattern-2 - - ## Programs if BUILD_TESTPATTERN + +TESTS = run-testpattern-1 run-testpattern-2 + bin_PROGRAMS = testpattern noinst_PROGRAMS = printers printer_options noinst_SCRIPTS = run-testpattern-2 compare-checksums compress-checksums uncompress-checksums @@ -58,9 +58,10 @@ endif ## Generate checksums if BUILD_TESTPATTERN + checksums: testpattern run-testpattern-2 ./compress-checksums $(MKDIR_P) Checksums - ./run-testpattern-2 -q -M Checksums/sums.@GUTENPRINT_VERSION@.in + ./run-testpattern-2 -q -M Checksums/sums.$(SPREFIX)@GUTENPRINT_VERSION@.in ./compress-checksums < Checksums/sums.@GUTENPRINT_VERSION@.in |$(BZIP2) -c > Checksums/sums.@GUTENPRINT_VERSION@.bz2 rm -f Checksums/sums.@GUTENPRINT_VERSION@.in endif diff --git a/src/testpattern/Makefile.in b/src/testpattern/Makefile.in index 9b44a91..feec3ce 100644 --- a/src/testpattern/Makefile.in +++ b/src/testpattern/Makefile.in @@ -633,7 +633,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include $(LOCAL_CPPFLAGS) $(GNUCFLAGS) GUTENPRINTUI_LIBS = $(top_builddir)/src/gutenprintui/libgutenprintui.la -TESTS = run-testpattern-1 run-testpattern-2 +@BUILD_TESTPATTERN_TRUE@TESTS = run-testpattern-1 run-testpattern-2 @BUILD_TESTPATTERN_TRUE@noinst_SCRIPTS = run-testpattern-2 compare-checksums compress-checksums uncompress-checksums AM_LFLAGS = -i AM_YFLAGS = -d @@ -1243,7 +1243,7 @@ testpattern.o: testpatterny.o @BUILD_TESTPATTERN_TRUE@checksums: testpattern run-testpattern-2 ./compress-checksums @BUILD_TESTPATTERN_TRUE@ $(MKDIR_P) Checksums -@BUILD_TESTPATTERN_TRUE@ ./run-testpattern-2 -q -M Checksums/sums.@GUTENPRINT_VERSION@.in +@BUILD_TESTPATTERN_TRUE@ ./run-testpattern-2 -q -M Checksums/sums.$(SPREFIX)@GUTENPRINT_VERSION@.in @BUILD_TESTPATTERN_TRUE@ ./compress-checksums < Checksums/sums.@GUTENPRINT_VERSION@.in |$(BZIP2) -c > Checksums/sums.@GUTENPRINT_VERSION@.bz2 @BUILD_TESTPATTERN_TRUE@ rm -f Checksums/sums.@GUTENPRINT_VERSION@.in diff --git a/src/testpattern/run-testpattern-2.in b/src/testpattern/run-testpattern-2.in index 8df73b8..00608ff 100644 --- a/src/testpattern/run-testpattern-2.in +++ b/src/testpattern/run-testpattern-2.in @@ -4,6 +4,7 @@ use Getopt::Long; Getopt::Long::Configure("bundling", "no_ignore_case", "pass_through"); use strict; +use POSIX ":sys_wait_h"; my $valgrind = 0; my $callgrind = 0; @@ -66,6 +67,7 @@ my $list_printers = 0; my $list_options = 0; my $verbose = 0; my $use_unused_options = 0; +my $proc_count = 1; my @default_options = (); my %base_settings = ("DitherAlgorithm" => "Fast"); @@ -77,6 +79,13 @@ my %stp_float_values; my %stp_int_values; my %rerun_cases; +if (defined $ENV{"STP_PARALLEL"}) { + $proc_count = $ENV{"STP_PARALLEL"}; + if ($proc_count > 1) { + $quiet = 1; + } +} + GetOptions("C=s" => \$csum_type, "G=s" => \$geometry, "H!" => \$halt_on_error, @@ -106,7 +115,8 @@ GetOptions("C=s" => \$csum_type, "N!" => \$use_unused_options, "v+" => \$valgrind, "x=s" => \@exclude_list, - "y=s" => \@exclude_patterns); + "y=s" => \@exclude_patterns, + "t:i" => \$proc_count); sub print_help_and_exit() { my $options = join("\n ", sort @standard_options); @@ -831,6 +841,9 @@ if ($list_options) { } else { my $valgrind_command; my $valopts; + if ($gdb_attach) { + $proc_count = 1; + } if ($callgrind) { $valopts = '--tool=callgrind --dump-instr=yes --trace-jump=yes'; $valgrind = 4; @@ -871,27 +884,58 @@ if ($list_options) { } my ($qopt) = $quiet ? "-q" : ""; my ($Hopt) = $halt_on_error ? "-H" : ""; - $testpattern_command = "$valgrind_command ./testpattern -y $suppress $qopt $Hopt"; - if ($single > 1) { - $SIG{TERM} = sub() { stopit() }; - $SIG{HUP} = sub() { stopit() }; - $SIG{INT} = sub() { stopit() }; - foreach my $printer (@printer_list) { - do_printer($printer, undef); + my (@children); + my ($child_no); + my ($kid); + if ($proc_count > 1) { + for ($child_no = 0; $child_no < $proc_count; $child_no++) { + $kid = fork(); + if ($kid == 0) { + last; + } else { + push @children, $kid; + } } - } elsif ($single) { - $SIG{PIPE} = sub() { restart_testpattern() }; - foreach my $printer (@printer_list) { - restart_testpattern(1); - do_printer($printer, $global_fh); - $status |= close $global_fh; - $status |= ($? & 255); + if ($kid == 0) { + my (@xprinter_list); + foreach my $i (0..$#printer_list) { + if ($i % $proc_count == $child_no) { + push @xprinter_list, $printer_list[$i]; + } + } + @printer_list = @xprinter_list; + } + } + if ($proc_count > 1 && $kid > 0) { + while ($proc_count > 0 && $kid > 0) { + $kid = waitpid(-1, 0); + if ($kid > 0 && $? > 0) { + $error++; + } } } else { - $SIG{PIPE} = sub() { restart_testpattern() }; - restart_testpattern(1); - map { do_printer($_, $global_fh) } @printer_list; - $status = close $global_fh; + $testpattern_command = "$valgrind_command ./testpattern -y $suppress $qopt $Hopt"; + if ($single > 1) { + $SIG{TERM} = sub() { stopit() }; + $SIG{HUP} = sub() { stopit() }; + $SIG{INT} = sub() { stopit() }; + foreach my $printer (@printer_list) { + do_printer($printer, undef); + } + } elsif ($single) { + $SIG{PIPE} = sub() { restart_testpattern() }; + foreach my $printer (@printer_list) { + restart_testpattern(1); + do_printer($printer, $global_fh); + $status |= close $global_fh; + $status |= ($? & 255); + } + } else { + $SIG{PIPE} = sub() { restart_testpattern() }; + restart_testpattern(1); + map { do_printer($_, $global_fh) } @printer_list; + $status = close $global_fh; + } } if ($quiet == 2) { print STDERR "\n"; @@ -903,7 +947,8 @@ if ($list_options) { if ($single > 1) { print STDERR "$error cases failed\n"; } else { - print STDERR "*** $error CRASHES NOTED***\n"; + my ($plural) = ($error > 1 ? "ES" : ""); + print STDERR "*** $error CRASH${plural} NOTED***\n"; } } exit 1; diff --git a/src/xml/papers.xml b/src/xml/papers.xml index feda100..a097fcf 100644 --- a/src/xml/papers.xml +++ b/src/xml/papers.xml @@ -278,6 +278,41 @@ <!-- Other common photographic paper sizes --> + <paper name="w213h284"> + <description translate="value" value="1280x960"/> + <comment value="Only used by Mitsubishi P95DW"/> + <width value="213"/> + <height value="284"/> + <unit value="english-extended"/> + </paper> + <paper name="w227h284"> + <description translate="value" value="1280x1024"/> + <comment value="Only used by Mitsubishi P95DW"/> + <width value="227"/> + <height value="284"/> + <unit value="english-extended"/> + </paper> + <paper name="w284h284"> + <description translate="value" value="1280x1280"/> + <comment value="Only used by Mitsubishi P95DW"/> + <width value="284"/> + <height value="284"/> + <unit value="english-extended"/> + </paper> + <paper name="w284h426"> + <description translate="value" value="1280x1920"/> + <comment value="Only used by Mitsubishi P95DW"/> + <width value="284"/> + <height value="426"/> + <unit value="english-extended"/> + </paper> + <paper name="w284h1277"> + <description translate="value" value="1280x5760"/> + <comment value="Only used by Mitsubishi P95DW"/> + <width value="284"/> + <height value="1277"/> + <unit value="english-extended"/> + </paper> <paper name="w360h360"> <description translate="value" value="5x5"/> <comment value="Only used by certain dyesub models"/> @@ -285,13 +320,27 @@ <height value="360"/> <unit value="english-extended"/> </paper> - <paper name="w576h576"> + <paper name="w504h576"> + <description translate="value" value="8x7"/> + <comment value="Only used by DS820 dyesub printer"/> + <width value="576"/> + <height value="504"/> + <unit value="english-extended"/> + </paper> + <paper name="w576h576"> <description translate="value" value="8x8"/> <comment value="Only used by certain dyesub models"/> <width value="576"/> <height value="576"/> <unit value="english-extended"/> </paper> + <paper name="w576h648"> + <description translate="value" value="8x9"/> + <comment value="Only used by DS820 dyesub printer"/> + <width value="576"/> + <height value="648"/> + <unit value="english-extended"/> + </paper> <paper name="w576h774"> <description translate="value" value="8x10.75"/> <comment value="Only used by DS80DX dyesub printer"/> @@ -306,6 +355,13 @@ <height value="864"/> <unit value="english-extended"/> </paper> + <paper name="w576h842"> + <description translate="value" value="8x11.7"/> + <comment value="Only used by DS80, DS80DX, DS820 dyesub printers"/> + <width value="595"/> + <height value="842"/> + <unit value="english-extended"/> + </paper> <paper name="w612h864"> <description translate="value" value="8.5x12"/> <comment value="Only used by Kodak 1400 and 805 dyesub printers"/> @@ -1663,6 +1719,55 @@ They can be removed once we figure out a better paper API --> + <paper name="A4-div2"> + <description translate="value" value="A5*2"/> + <comment value="Only used by DNP DS820"/> + <width value="595"/> + <height value="842"/> + <unit value="metric"/> + </paper> + <paper name="A4x4inch"> + <description translate="value" value="A4 width * 4inch"/> + <comment value="Only used by DNP DS820"/> + <width value="595"/> + <height value="288"/> + <unit value="metric"/> + </paper> + <paper name="A4x5inch"> + <description translate="value" value="A4 width * 5inch"/> + <comment value="Only used by DNP DS820"/> + <width value="595"/> + <height value="360"/> + <unit value="metric"/> + </paper> + <paper name="A4x6inch"> + <description translate="value" value="A4 width * 6inch"/> + <comment value="Only used by DNP DS820"/> + <width value="595"/> + <height value="432"/> + <unit value="metric"/> + </paper> + <paper name="A4x8inch"> + <description translate="value" value="A4 width * 8inch"/> + <comment value="Only used by DNP DS820"/> + <width value="595"/> + <height value="576"/> + <unit value="metric"/> + </paper> + <paper name="A4x10inch"> + <description translate="value" value="A4 width * 10inch"/> + <comment value="Only used by DNP DS820"/> + <width value="595"/> + <height value="720"/> + <unit value="metric"/> + </paper> + <paper name="A4x10inch-div2"> + <description translate="value" value="A4 width * 5 inch x2"/> + <comment value="Only used by DNP DS820"/> + <width value="595"/> + <height value="720"/> + <unit value="metric"/> + </paper> <paper name="w288h432-div2"> <description translate="value" value="2x6*2"/> <width value="288"/> @@ -1738,8 +1843,8 @@ <width value="576"/> <height value="774"/> <unit value="english-extended"/> - <type value="special"/> - </paper> + <type value="special"/> + </paper> <paper name="w576h792-w576h432_w576h360"> <description translate="value" value="8x6+8x5"/> <width value="576"/> diff --git a/src/xml/printers.xml b/src/xml/printers.xml index c9260c1..117fd58 100644 --- a/src/xml/printers.xml +++ b/src/xml/printers.xml @@ -1710,18 +1710,18 @@ <printer translate="name" name="Epson Stylus TX645" driver="escp2-tx645" manufacturer="Epson" model="118" parameters="standard_params" /> <printer translate="name" name="Epson Stylus TX650" driver="escp2-tx650" manufacturer="Epson" model="97" parameters="standard_params" /> <printer translate="name" name="Epson Stylus TX659" driver="escp2-tx659" manufacturer="Epson" model="97" parameters="standard_params" /> - <printer translate="name" name="Epson Stylus XP100" driver="escp2-xp100" manufacturer="Epson" model="123" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P400" driver="escp2-p400" manufacturer="Epson" model="91" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P600" driver="escp2-p600" manufacturer="Epson" model="102" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P800" driver="escp2-p800" manufacturer="Epson" model="102" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P6000" driver="escp2-p6000" manufacturer="Epson" model="89" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P7000" driver="escp2-p7000" manufacturer="Epson" model="124" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P7000 Commercial Edition" driver="escp2-p7000c" manufacturer="Epson" model="126" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P8000" driver="escp2-p8000" manufacturer="Epson" model="90" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P9000" driver="escp2-p9000" manufacturer="Epson" model="125" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P9000 Commercial Edition" driver="escp2-p9000c" manufacturer="Epson" model="127" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P10000" driver="escp2-p10000" manufacturer="Epson" model="90" parameters="standard_params" /> - <printer translate="name" name="Epson SureColor P20000" driver="escp2-p20000" manufacturer="Epson" model="88" parameters="standard_params" /> + <printer translate="name" name="Epson Stylus XP100" driver="escp2-xp100" manufacturer="Epson" model="123" parameters="standard_params">EXPERIMENTAL</printer> + <printer translate="name" name="Epson SureColor P400" driver="escp2-p400" manufacturer="Epson" model="91" parameters="standard_params">EXPERIMENTAL</printer> + <printer translate="name" name="Epson SureColor P600" driver="escp2-p600" manufacturer="Epson" model="115" parameters="standard_params">EXPERIMENTAL</printer> + <printer translate="name" name="Epson SureColor P800" driver="escp2-p800" manufacturer="Epson" model="102" parameters="standard_params">EXPERIMENTAL</printer> + <printer translate="name" name="Epson SureColor P6000" driver="escp2-p6000" manufacturer="Epson" model="89" parameters="standard_params">EXPERIMENTAL</printer> + <printer translate="name" name="Epson SureColor P7000" driver="escp2-p7000" manufacturer="Epson" model="124" parameters="standard_params">EXPERIMENTAL</printer> + <printer translate="name" name="Epson SureColor P7000 Commercial Edition" driver="escp2-p7000c" manufacturer="Epson" model="126" parameters="standard_params">EXPERIMENTAL; violet ink not supported</printer> + <printer translate="name" name="Epson SureColor P8000" driver="escp2-p8000" manufacturer="Epson" model="90" parameters="standard_params">EXPERIMENTAL</printer> + <printer translate="name" name="Epson SureColor P9000" driver="escp2-p9000" manufacturer="Epson" model="125" parameters="standard_params">EXPERIMENTAL</printer> + <printer translate="name" name="Epson SureColor P9000 Commercial Edition" driver="escp2-p9000c" manufacturer="Epson" model="127" parameters="standard_params">EXPERIMENTAL; violet ink not supported</printer> + <printer translate="name" name="Epson SureColor P10000" driver="escp2-p10000" manufacturer="Epson" model="90" parameters="standard_params">EXPERIMENTAL; only three levels of gray supported</printer> + <printer translate="name" name="Epson SureColor P20000" driver="escp2-p20000" manufacturer="Epson" model="88" parameters="standard_params">EXPERIMENTAL; only three levels of gray supported</printer> <printer translate="name" name="Epson PictureMate" driver="escp2-picmate" manufacturer="Epson" model="73" parameters="standard_params" /> <printer translate="name" name="Epson PictureMate Dash" driver="escp2-picmatedash" manufacturer="Epson" model="86" parameters="standard_params" /> <printer translate="name" name="Epson PictureMate Deluxe" driver="escp2-picmated" manufacturer="Epson" model="73" parameters="standard_params" /> @@ -1921,7 +1921,6 @@ <printer translate="name" name="Brother HL-1250" deviceid="MFG:Brother;MDL:HL-1250 series;CMD:PCL5,PJL,PCLXL;" driver="brother-hl-1250" manufacturer="Brother" model="6" parameters="pcl_laser_params" /> <printer translate="name" name="Brother HL-1260" deviceid="MFG:Brother;MDL:HL-1250 series;CMD:PCL5,PJL,PCLXL;" driver="brother-hl-1260" manufacturer="Brother" model="6" parameters="pcl_laser_params" /> <printer translate="name" name="Brother HL-1270N" driver="brother-hl-1270n" manufacturer="Brother" model="6" parameters="pcl_laser_params" /> - <printer translate="name" name="Brother HL-1430" deviceid="MFG:Brother;MDL:HL-1430 series;CMD:PJL;" driver="brother-hl-1430" manufacturer="Brother" model="6" parameters="pcl_laser_params" /> <printer translate="name" name="Brother HL-1440" deviceid="MFG:Brother;MDL:HL-1440 series;CMD:PCL4,PJL;" driver="brother-hl-1440" manufacturer="Brother" model="6" parameters="pcl_laser_params" /> <printer translate="name" name="Brother HL-1450" deviceid="MFG:Brother;MDL:Brother HL-1450 series;" driver="brother-hl-1450" manufacturer="Brother" model="6" parameters="pcl_laser_params" /> <printer translate="name" name="Brother HL-1470N" deviceid="MFG:Brother;MDL:Brother HL-1470N series;" driver="brother-hl-1470n" manufacturer="Brother" model="6" parameters="pcl_laser_params" /> @@ -2894,7 +2893,7 @@ <printer translate="name" name="Olympus P-330NE" driver="olympus-p330ne" manufacturer="Olympus" model="0" /> <printer translate="name" name="Olympus P-400" driver="olympus-p400" manufacturer="Olympus" model="1" /> <printer translate="name" name="Olympus P-440" driver="olympus-p440" manufacturer="Olympus" model="3" /> - <printer translate="name" name="Olympus P-S100" driver="olympus-ps100" manufacturer="Olympus" model="20" /> + <printer translate="name" name="Olympus P-S100" driver="olympus-ps100" manufacturer="Olympus" model="20" parameters="nativecopies" /> <printer translate="name" name="Canon CP-10" deviceid="MFG:Canon;CMD:Raster3;MDL:CP-10;CLS:PRINTER;DES:Canon CP-10;VER:1.00;" driver="canon-cp10" manufacturer="Canon" model="1002" parameters="nativecopies" /> <printer translate="name" name="Canon CP-100" deviceid="MFG:Canon;CMD:Raster3;MDL:CP-100;CLS:PRINTER;DES:Canon CP-100;VER:1.00;" driver="canon-cp100" manufacturer="Canon" model="1000" parameters="nativecopies" /> <printer translate="name" name="Canon CP-200" deviceid="MFG:Canon;CMD:Raster3;MDL:CP-200;CLS:PRINTER;DES:Canon CP-200;VER:1.00;" driver="canon-cp200" manufacturer="Canon" model="1000" parameters="nativecopies" /> @@ -2918,11 +2917,11 @@ <printer translate="name" name="Canon SELPHY CP790" deviceid="MFG:Canon;CMD:Raster3;MDL:CP790;CLS:PRINTER;DES:Canon CP790;VER:1.00;" driver="canon-cp790" manufacturer="Canon" model="1008" parameters="nativecopies" /> <printer translate="name" name="Canon SELPHY CP800" deviceid="MFG:Canon;CMD:Raster3;MDL:CP800;CLS:PRINTER;DES:Canon CP800;VER:1.00;" driver="canon-cp800" manufacturer="Canon" model="1009" parameters="nativecopies" /> <printer translate="name" name="Canon SELPHY CP810" deviceid="MFG:Canon;CMD:Raster3;MDL:CP810;CLS:PRINTER;DES:Canon CP810;VER:3.05;" driver="canon-cp810" manufacturer="Canon" model="1009" parameters="nativecopies" /> - <printer translate="name" name="Canon SELPHY CP820" driver="canon-cp820" manufacturer="Canon" model="1011" /> + <printer translate="name" name="Canon SELPHY CP820" driver="canon-cp820" manufacturer="Canon" model="1011" parameters="nativecopies"/> <printer translate="name" name="Canon SELPHY CP900" deviceid="MFG:Canon;CMD:Raster3;MDL:CP900;CLS:PRINTER;DES:Canon CP900;VER:5.77;" driver="canon-cp900" manufacturer="Canon" model="1010" parameters="nativecopies" /> - <printer translate="name" name="Canon SELPHY CP910" deviceid="MFG:Canon;CMD:Raster3;MDL:CP910;CLS:PRINTER;DES:Canon CP910;VER:1.00;CID:CA_YCC_ICP;" driver="canon-cp910" manufacturer="Canon" model="1011" /> - <printer translate="name" name="Canon SELPHY CP1000" driver="canon-cp1000" manufacturer="Canon" model="1011" /> - <printer translate="name" name="Canon SELPHY CP1200" deviceid="MFG:Canon;CMD:Raster3;MDL:SELPHY CP1200;CLS:PRINTER;DES:Canon SELPHY CP1200;VER:1.00;CID:CA_YCC_ICP;" driver="canon-cp1200" manufacturer="Canon" model="1011" /> + <printer translate="name" name="Canon SELPHY CP910" deviceid="MFG:Canon;CMD:Raster3;MDL:CP910;CLS:PRINTER;DES:Canon CP910;VER:1.00;CID:CA_YCC_ICP;" driver="canon-cp910" manufacturer="Canon" model="1011" parameters="nativecopies" /> + <printer translate="name" name="Canon SELPHY CP1000" deviceid="MFG:Canon;CMD:Raster3;MDL:CP1000;CLS:PRINTER;DES:Canon CP1000;VER:1.00;CID:CA_YCC_ICP;" driver="canon-cp1000" manufacturer="Canon" model="1011" parameters="nativecopies" /> + <printer translate="name" name="Canon SELPHY CP1200" deviceid="MFG:Canon;CMD:Raster3;MDL:SELPHY CP1200;CLS:PRINTER;DES:Canon SELPHY CP1200;VER:1.00;CID:CA_YCC_ICP;" driver="canon-cp1200" manufacturer="Canon" model="1011" parameters="nativecopies"/> <printer translate="name" name="Canon SELPHY ES1" deviceid="MFG:Canon;CMD:Raster3;MDL:ES1;CLS:PRINTER;DES:Canon SELPHY ES1;VER:1.00;" driver="canon-es1" manufacturer="Canon" model="1003" parameters="nativecopies" /> <printer translate="name" name="Canon SELPHY ES2" deviceid="MFG:Canon;CMD:Raster3;MDL:ES2;CLS:PRINTER;DES:Canon SELPHY ES2;VER:1.00;" driver="canon-es2" manufacturer="Canon" model="1005" parameters="nativecopies" /> <printer translate="name" name="Canon SELPHY ES3" deviceid="MFG:Canon;CMD:Raster3;MDL:ES3;CLS:PRINTER;DES:Canon SELPHY ES3;VER:1.00;" driver="canon-es3" manufacturer="Canon" model="1006" parameters="nativecopies" /> @@ -2953,25 +2952,26 @@ <printer translate="name" name="Kodak 605" deviceid="MFG:Eastman Kodak Company;CMD:SUPCC;MCL:KODAK 605 Photo Printer;CLS:PRINTER;DES:Thermal Dye Photo Printer;" driver="kodak-605" manufacturer="Kodak" model="4003" parameters="nativecopies" /> <printer translate="name" name="Kodak 1400" deviceid="MFG:Eastman Kodak Company;CMD:EK1;MDL: 1400 Printer;CLS:Printer;DES:Kodak 1400 Printer;`" driver="kodak-1400" manufacturer="Kodak" model="4004" parameters="nativecopies" /> <printer translate="name" name="Kodak 805" deviceid="MFG:Eastman Kodak Company;CMD:EK2;MDL: KODAK 805 Photo Printer;CLS:Printer;DES:Kodak 805 Photo Printer;" driver="kodak-805" manufacturer="Kodak" model="4005" parameters="nativecopies" /> - <printer translate="name" name="Kodak 8500" driver="kodak-8500" manufacturer="Kodak" model="4100">EXPERIMENTAL</printer> - <printer translate="name" name="Kodak 9810" driver="kodak-9810" manufacturer="Kodak" model="4006">EXPERIMENTAL</printer> - <printer translate="name" name="Kodak 8810" driver="kodak-8810" manufacturer="Kodak" model="4007">EXPERIMENTAL</printer> - <printer translate="name" name="Kodak 7000" driver="kodak-7000" manufacturer="Kodak" model="4008">EXPERIMENTAL</printer> - <printer translate="name" name="Kodak 7010" driver="kodak-7010" manufacturer="Kodak" model="4008">EXPERIMENTAL</printer> - <printer translate="name" name="Kodak 7015" driver="kodak-7015" manufacturer="Kodak" model="4009">EXPERIMENTAL</printer> - <printer translate="name" name="Mitsubishi CP-3020D" driver="mitsubishi-3020d" manufacturer="Mitsubishi" model="4101">EXPERIMENTAL</printer> - <printer translate="name" name="Mitsubishi CP-3020DU" driver="mitsubishi-3020du" manufacturer="Mitsubishi" model="4101">EXPERIMENTAL</printer> - <printer translate="name" name="Mitsubishi CP-3020DE" driver="mitsubishi-3020de" manufacturer="Mitsubishi" model="4101">EXPERIMENTAL</printer> - <printer translate="name" name="Mitsubishi CP-3020DA" driver="mitsubishi-3020da" manufacturer="Mitsubishi" model="4102">EXPERIMENTAL</printer> - <printer translate="name" name="Mitsubishi CP-3020DAE" driver="mitsubishi-3020dae" manufacturer="Mitsubishi" model="4102">EXPERIMENTAL</printer> + <printer translate="name" name="Kodak 8500" driver="kodak-8500" manufacturer="Kodak" model="4100" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Kodak 9810" driver="kodak-9810" manufacturer="Kodak" model="4006" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Kodak 8800" driver="kodak-8800" manufacturer="Kodak" model="4006" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Kodak 8810" driver="kodak-8810" manufacturer="Kodak" model="4007" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Kodak 7000" driver="kodak-7000" manufacturer="Kodak" model="4008" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Kodak 7010" driver="kodak-7010" manufacturer="Kodak" model="4008" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Kodak 7015" driver="kodak-7015" manufacturer="Kodak" model="4009" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Mitsubishi CP-3020D" driver="mitsubishi-3020d" manufacturer="Mitsubishi" model="4101" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Mitsubishi CP-3020DU" driver="mitsubishi-3020du" manufacturer="Mitsubishi" model="4101" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Mitsubishi CP-3020DE" driver="mitsubishi-3020de" manufacturer="Mitsubishi" model="4101" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Mitsubishi CP-3020DA" driver="mitsubishi-3020da" manufacturer="Mitsubishi" model="4102" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Mitsubishi CP-3020DAE" driver="mitsubishi-3020dae" manufacturer="Mitsubishi" model="4102" parameters="nativecopies">EXPERIMENTAL</printer> <printer translate="name" name="Mitsubishi CP-9550D" deviceid="MFG:MITSUBISHI;CMD:MEL;MDL:CP9550D ;CLS:PRINTER;DES:MITSUBISHI CP9550D" driver="mitsubishi-9550d" manufacturer="Mitsubishi" model="4103" parameters="nativecopies" /> <printer translate="name" name="Mitsubishi CP-9550DW" driver="mitsubishi-9550dw" manufacturer="Mitsubishi" model="4103" parameters="nativecopies" /> <printer translate="name" name="Mitsubishi CP-9810D" driver="mitsubishi-9810d" manufacturer="Mitsubishi" model="4104" parameters="nativecopies">EXPERIMENTAL</printer> <printer translate="name" name="Mitsubishi CP-9810DW" driver="mitsubishi-9810dw" manufacturer="Mitsubishi" model="4104" parameters="nativecopies">EXPERIMENTAL</printer> - <printer translate="name" name="Mitsubishi CP-D70DW" deviceid="MFG:MITSUBISHI;CMD:MEL;MDL:CP60D70D707D;CLS:PRINTER;DES:MITSUBISHI CP60D70D707D" driver="mitsubishi-d70dw" manufacturer="Mitsubishi" model="4105" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Mitsubishi CP-D70DW" deviceid="MFG:MITSUBISHI;CMD:MEL;MDL:CP60D70D707D;CLS:PRINTER;DES:MITSUBISHI CP60D70D707D" driver="mitsubishi-d70dw" manufacturer="Mitsubishi" model="4105" parameters="nativecopies" /> <printer translate="name" name="Mitsubishi CP-D707DW" deviceid="MFG:MITSUBISHI;CMD:MEL;MDL:CP60D70D707D;CLS:PRINTER;DES:MITSUBISHI CP60D70D707D" driver="mitsubishi-d707dw" manufacturer="Mitsubishi" model="4105" parameters="nativecopies">EXPERIMENTAL</printer> <printer translate="name" name="Mitsubishi CP-K60DW-S" driver="mitsubishi-k60dw" manufacturer="Mitsubishi" model="4106" parameters="nativecopies" /> - <printer translate="name" name="Mitsubishi CP-D80DW" driver="mitsubishi-d80dw" manufacturer="Mitsubishi" model="4107" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Mitsubishi CP-D80DW" deviceid="MFG:MITSUBISHI;CMD:MEL;MDL:CPD80D;CLS:PRINTER;DES:MITSUBISHI_CPD80D" driver="mitsubishi-d80dw" manufacturer="Mitsubishi" model="4107" parameters="nativecopies" /> <printer translate="name" name="Kodak 305" deviceid="MFG:KODAK;CMD:KODAK305;MDL:305 Photo Printer;CLS:PRINTER;DES:KODAK 305 Photo Printer" driver="kodak-305" manufacturer="Kodak" model="4108" parameters="nativecopies" /> <printer translate="name" name="Mitsubishi CP-D90DW" driver="mitsubishi-d90dw" manufacturer="Mitsubishi" model="4109" parameters="nativecopies">EXPERIMENTAL</printer> <printer translate="name" name="Mitsubishi CP-9600DW" driver="mitsubishi-9600dw" manufacturer="Mitsubishi" model="4110" parameters="nativecopies" /> @@ -2982,7 +2982,9 @@ <printer translate="name" name="Mitsubishi CP-9800DW" driver="mitsubishi-9800dw" manufacturer="Mitsubishi" model="4113" >EXPERIMENTAL</printer> <printer translate="name" name="Mitsubishi CP-9800DZ" deviceid="MFG:MITSUBISHI;CMD:MEL;MDL:CP9800DZ;CLS:PRINTER;DES:MITSUBISHI CP9800DZ;" driver="mitsubishi-9800dz" manufacturer="Mitsubishi" model="4113" parameters="nativecopies" /> <printer translate="name" name="Mitsubishi CP-9800DW-S" driver="mitsubishi-9800dw-s" manufacturer="Mitsubishi" model="4113" parameters="nativecopies" /> + <printer translate="name" name="Mitsubishi P95D" driverid="MFG:MITSUBISHI;CMD:MEL;MDL:P95D ;CLS:PRINTER;DES:MITSUBISHI P95D ;" driver="mitsubishi-p95d" manufacturer="Mitsubishi" model="4114" parameters="nativecopies" /> <printer translate="name" name="Shinko CHC-S9045" driver="shinko-chcs9045" manufacturer="Shinko" model="5000" /> + <printer translate="name" name="Mitsubishi CP-9500DW" driver="mitsubishi-9500dw" manufacturer="Mitsubishi" model="4115" parameters="nativecopies" /> <printer translate="name" name="Shinko CHC-S2145" deviceid="MFG:SHINKO;CMD:SUPCC;MDL:CHC-S2145;CLS:PRINTER;DES:SHINKO CHC-S2145;" driver="shinko-chcs2145" manufacturer="Shinko" model="5001" parameters="nativecopies" /> <printer translate="name" name="Sinfonia S2145/S2" driver="sinfonia-chcs2145" manufacturer="Sinfonia" model="5001" parameters="nativecopies" /> <printer translate="name" name="Shinko CHC-S1245" driver="shinko-chcs1245" manufacturer="Shinko" model="5002" parameters="nativecopies">EXPERIMENTAL</printer> @@ -3005,6 +3007,7 @@ <printer translate="name" name="Citizen OP900II" driver="citizen-op900ii" manufacturer="Citizen" model="6000" parameters="nativecopies">EXPERIMENTAL</printer> <printer translate="name" name="Mitsubishi CP-3800DW" driver="mitsubishi-cp-3800dw" manufacturer="Mitsubishi" model="6001" parameters="nativecopies" /> <printer translate="name" name="Dai Nippon Printing DS80DX" driver="dnp-ds80dx" manufacturer="Dai Nippon Printing" model="6006" parameters="nativecopies">EXPERIMENTAL</printer> + <printer translate="name" name="Dai Nippon Printing DS820" driver="dnp-ds820" deviceid="MANUFACTURER:Dai Nippon Printing ;MODEL:DP-DS820;" manufacturer="Dai Nippon Printing" model="6007" parameters="nativecopies" /> </family> <family name="raw"> <printer translate="name" name="RAW DATA 16 bit" driver="raw-data-16" manufacturer="" model="0" /> |