diff options
author | Didier Raboud <odyx@debian.org> | 2016-09-20 11:56:08 +0200 |
---|---|---|
committer | Didier Raboud <odyx@debian.org> | 2016-09-20 11:56:08 +0200 |
commit | 7f5731038556e5b03d2a886163ca2c873c77333d (patch) | |
tree | 8f4194af3949a73accf44b2b0bd8ebfa990ac577 /src/cups | |
parent | a313257bdec71bc92a56598e74d9097c16cb6e48 (diff) |
New upstream version 5.2.12~pre2
Diffstat (limited to 'src/cups')
-rw-r--r-- | src/cups/Makefile.am | 7 | ||||
-rw-r--r-- | src/cups/Makefile.in | 363 | ||||
-rw-r--r-- | src/cups/backend_canonselphy.c (renamed from src/cups/selphy_print.c) | 183 | ||||
-rw-r--r-- | src/cups/backend_citizencw01.c (renamed from src/cups/citizencw01_print.c) | 5 | ||||
-rw-r--r-- | src/cups/backend_common.c | 67 | ||||
-rw-r--r-- | src/cups/backend_common.h | 29 | ||||
-rw-r--r-- | src/cups/backend_dnpds40.c (renamed from src/cups/dnpds40_print.c) | 1178 | ||||
-rw-r--r-- | src/cups/backend_kodak1400.c (renamed from src/cups/kodak1400_print.c) | 7 | ||||
-rw-r--r-- | src/cups/backend_kodak605.c (renamed from src/cups/kodak605_print.c) | 134 | ||||
-rw-r--r-- | src/cups/backend_kodak6800.c (renamed from src/cups/kodak6800_print.c) | 199 | ||||
-rw-r--r-- | src/cups/backend_mitsu70x.c | 1609 | ||||
-rw-r--r-- | src/cups/backend_mitsu9550.c (renamed from src/cups/mitsu9550_print.c) | 232 | ||||
-rw-r--r-- | src/cups/backend_shinkos1245.c (renamed from src/cups/shinko_s1245_print.c) | 102 | ||||
-rw-r--r-- | src/cups/backend_shinkos2145.c (renamed from src/cups/shinko_s2145_print.c) | 121 | ||||
-rw-r--r-- | src/cups/backend_shinkos6145.c (renamed from src/cups/shinko_s6145_print.c) | 438 | ||||
-rw-r--r-- | src/cups/backend_shinkos6245.c (renamed from src/cups/shinko_s6245_print.c) | 122 | ||||
-rw-r--r-- | src/cups/backend_sonyupdr150.c (renamed from src/cups/sony_updr150_print.c) | 2 | ||||
-rw-r--r-- | src/cups/blacklist | 10 | ||||
-rw-r--r-- | src/cups/command.types | 7 | ||||
-rw-r--r-- | src/cups/commandtoepson.c | 7 | ||||
-rw-r--r-- | src/cups/cups-calibrate.c | 13 | ||||
-rw-r--r-- | src/cups/cups-genppdupdate.in | 1 | ||||
-rw-r--r-- | src/cups/genppd.c | 7 | ||||
-rw-r--r-- | src/cups/i18n.c | 7 | ||||
-rw-r--r-- | src/cups/i18n.h | 7 | ||||
-rw-r--r-- | src/cups/mitsu70x_print.c | 801 | ||||
-rw-r--r-- | src/cups/rastertoprinter.c | 15 |
27 files changed, 3768 insertions, 1905 deletions
diff --git a/src/cups/Makefile.am b/src/cups/Makefile.am index 4e1fd1c..ed3a800 100644 --- a/src/cups/Makefile.am +++ b/src/cups/Makefile.am @@ -1,4 +1,3 @@ -## $Id: Makefile.am,v 1.152 2015/11/18 13:29:29 speachy Exp $ ## Copyright (C) 2000 Roger Leigh ## ## This program is free software; you can redistribute it and/or modify @@ -51,7 +50,7 @@ else cups_modeldir = $(pkgdatadir)/model/gutenprint/@GUTENPRINT_RELEASE_VERSION@/ endif -LOCAL_CPPFLAGS = $(GUTENPRINT_CFLAGS) $(CUPS_CFLAGS) -DBASE_VERSION=$(BASE_VERSION) +LOCAL_CPPFLAGS = $(GUTENPRINT_CFLAGS) $(CUPS_CFLAGS) -DBASE_VERSION=$(BASE_VERSION) -DSBINDIR=\"$(sbindir)/\" STP_NONLS_ENV= STP_MODULE_PATH=$(top_builddir)/src/main/.libs:$(top_builddir)/src/main STP_DATA_PATH=$(top_srcdir)/src/xml @@ -115,9 +114,9 @@ commandtoepson_SOURCES = commandtoepson.c commandtoepson_LDADD = $(CUPS_LIBS) if BUILD_LIBUSB_BACKENDS -backend_gutenprint_SOURCES = selphy_print.c kodak1400_print.c kodak6800_print.c kodak605_print.c shinko_s2145_print.c sony_updr150_print.c dnpds40_print.c mitsu70x_print.c citizencw01_print.c mitsu9550_print.c backend_common.c backend_common.h shinko_s1245_print.c shinko_s6145_print.c shinko_s6245_print.c +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_LDADD = $(LIBUSB_LIBS) +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 endif diff --git a/src/cups/Makefile.in b/src/cups/Makefile.in index 2139d69..94a6dc8 100644 --- a/src/cups/Makefile.in +++ b/src/cups/Makefile.in @@ -84,8 +84,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ DIST_COMMON = $(top_srcdir)/scripts/global.mk $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am $(top_srcdir)/scripts/mkinstalldirs \ - $(srcdir)/Info.plist.in $(srcdir)/cups-genppdupdate.in \ + $(srcdir)/Makefile.am $(srcdir)/Info.plist.in \ + $(srcdir)/cups-genppdupdate.in \ $(srcdir)/test-rastertogutenprint.in \ $(top_srcdir)/scripts/depcomp \ $(top_srcdir)/scripts/test-driver COPYING README @@ -99,19 +99,18 @@ DIST_COMMON = $(top_srcdir)/scripts/global.mk $(srcdir)/Makefile.in \ subdir = src/cups ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/isc-posix.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/stp.m4 \ - $(top_srcdir)/m4/stp_cups.m4 $(top_srcdir)/m4/stp_gimp.m4 \ - $(top_srcdir)/m4/stp_option.m4 $(top_srcdir)/m4/stp_release.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/stp.m4 $(top_srcdir)/m4/stp_cups.m4 \ + $(top_srcdir)/m4/stp_gimp.m4 $(top_srcdir)/m4/stp_option.m4 \ + $(top_srcdir)/m4/stp_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs +mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = Info.plist cups-genppdupdate \ test-rastertogutenprint @@ -125,29 +124,30 @@ am__installdirs = "$(DESTDIR)$(bindir)" \ PROGRAMS = $(bin_PROGRAMS) $(cupsexec_backend_PROGRAMS) \ $(cupsexec_driver_PROGRAMS) $(cupsexec_filter_PROGRAMS) \ $(sbin_PROGRAMS) -am__backend_gutenprint_SOURCES_DIST = selphy_print.c kodak1400_print.c \ - kodak6800_print.c kodak605_print.c shinko_s2145_print.c \ - sony_updr150_print.c dnpds40_print.c mitsu70x_print.c \ - citizencw01_print.c mitsu9550_print.c backend_common.c \ - backend_common.h shinko_s1245_print.c shinko_s6145_print.c \ - shinko_s6245_print.c -@BUILD_LIBUSB_BACKENDS_TRUE@am_backend_gutenprint_OBJECTS = backend_gutenprint-selphy_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-kodak1400_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-kodak6800_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-kodak605_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-shinko_s2145_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-sony_updr150_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-dnpds40_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-mitsu70x_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-citizencw01_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-mitsu9550_print.$(OBJEXT) \ +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 +@BUILD_LIBUSB_BACKENDS_TRUE@am_backend_gutenprint_OBJECTS = backend_gutenprint-backend_canonselphy.$(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) \ +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_shinkos2145.$(OBJEXT) \ +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_sonyupdr150.$(OBJEXT) \ +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_dnpds40.$(OBJEXT) \ +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_mitsu70x.$(OBJEXT) \ +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_citizencw01.$(OBJEXT) \ +@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_mitsu9550.$(OBJEXT) \ @BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_common.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-shinko_s1245_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-shinko_s6145_print.$(OBJEXT) \ -@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-shinko_s6245_print.$(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) backend_gutenprint_OBJECTS = $(am_backend_gutenprint_OBJECTS) am__DEPENDENCIES_1 = @BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_DEPENDENCIES = \ +@BUILD_LIBUSB_BACKENDS_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_LIBUSB_BACKENDS_TRUE@ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -517,9 +517,6 @@ ENABLE_STATIC = @ENABLE_STATIC@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIND = @FIND@ -FOOMATIC_CONFIGURE = @FOOMATIC_CONFIGURE@ -FOOMATIC_KITLOAD = @FOOMATIC_KITLOAD@ -FOOMATIC_PPDFILE = @FOOMATIC_PPDFILE@ GENPPD_LIBS = @GENPPD_LIBS@ GIMP2_CFLAGS = @GIMP2_CFLAGS@ GIMP2_LIBS = @GIMP2_LIBS@ @@ -552,9 +549,6 @@ GUTENPRINT_MICRO_VERSION = @GUTENPRINT_MICRO_VERSION@ GUTENPRINT_MINOR_VERSION = @GUTENPRINT_MINOR_VERSION@ GUTENPRINT_RELEASE_VERSION = @GUTENPRINT_RELEASE_VERSION@ GUTENPRINT_VERSION = @GUTENPRINT_VERSION@ -IJS_CFLAGS = @IJS_CFLAGS@ -IJS_CONFIG = @IJS_CONFIG@ -IJS_LIBS = @IJS_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -575,6 +569,7 @@ LIBREADLINE_DEPS = @LIBREADLINE_DEPS@ LIBS = $(INTLLIBS) @LIBS@ LIBTOOL = @LIBTOOL@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIBUSB_BACKEND_LIBDEPS = @LIBUSB_BACKEND_LIBDEPS@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIPO = @LIPO@ @@ -706,7 +701,7 @@ cupsexec_filterdir = $(pkglibdir)/filter @CUPS_PPDS_AT_TOP_LEVEL_FALSE@cups_modeldir = $(pkgdatadir)/model/gutenprint/@GUTENPRINT_RELEASE_VERSION@/ @CUPS_PPDS_AT_TOP_LEVEL_TRUE@cups_modeldir = $(pkgdatadir)/model/ @CUPS_PPDS_AT_TOP_LEVEL_TRUE@DONT_UNINSTALL_PPDS = true -LOCAL_CPPFLAGS = $(GUTENPRINT_CFLAGS) $(CUPS_CFLAGS) -DBASE_VERSION=$(BASE_VERSION) +LOCAL_CPPFLAGS = $(GUTENPRINT_CFLAGS) $(CUPS_CFLAGS) -DBASE_VERSION=$(BASE_VERSION) -DSBINDIR=\"$(sbindir)/\" STP_NONLS_ENV = STP_MODULE_PATH=$(top_builddir)/src/main/.libs:$(top_builddir)/src/main STP_DATA_PATH=$(top_srcdir)/src/xml STP_ENV = $(STP_NONLS_ENV) STP_LOCALEDIR=$(top_srcdir)/src/cups/catalog @BUILD_GLOBALIZED_CUPS_PPDS_FALSE@@BUILD_TRANSLATED_CUPS_PPDS_TRUE@PPD = $(PPD_NLS_1) @@ -725,8 +720,8 @@ commandtocanon_SOURCES = commandtocanon.c commandtocanon_LDADD = $(CUPS_LIBS) commandtoepson_SOURCES = commandtoepson.c commandtoepson_LDADD = $(CUPS_LIBS) -@BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_SOURCES = selphy_print.c kodak1400_print.c kodak6800_print.c kodak605_print.c shinko_s2145_print.c sony_updr150_print.c dnpds40_print.c mitsu70x_print.c citizencw01_print.c mitsu9550_print.c backend_common.c backend_common.h shinko_s1245_print.c shinko_s6145_print.c shinko_s6245_print.c -@BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_LDADD = $(LIBUSB_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_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 cups_genppd_@GUTENPRINT_RELEASE_VERSION@_CFLAGS = -DALL_LINGUAS='"$(ALL_LINGUAS)"' $(BUILD_SIMPLE_PPDS) $(TRANSLATE_PPDS) @@ -1114,20 +1109,20 @@ mostlyclean-compile: 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_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-citizencw01_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-dnpds40_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-kodak1400_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-kodak605_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-kodak6800_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-mitsu70x_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-mitsu9550_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-selphy_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-shinko_s1245_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-shinko_s2145_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-shinko_s6145_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-shinko_s6245_print.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-sony_updr150_print.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_dnpds40.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_kodak1400.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_kodak605.Po@am__quote@ +@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_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@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_shinkos6245.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commandtocanon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commandtoepson.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cups-calibrate.Po@am__quote@ @@ -1159,145 +1154,145 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -backend_gutenprint-selphy_print.o: selphy_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-selphy_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-selphy_print.Tpo -c -o backend_gutenprint-selphy_print.o `test -f 'selphy_print.c' || echo '$(srcdir)/'`selphy_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-selphy_print.Tpo $(DEPDIR)/backend_gutenprint-selphy_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='selphy_print.c' object='backend_gutenprint-selphy_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_canonselphy.o: backend_canonselphy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_canonselphy.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_canonselphy.Tpo -c -o backend_gutenprint-backend_canonselphy.o `test -f 'backend_canonselphy.c' || echo '$(srcdir)/'`backend_canonselphy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_canonselphy.Tpo $(DEPDIR)/backend_gutenprint-backend_canonselphy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_canonselphy.c' object='backend_gutenprint-backend_canonselphy.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-selphy_print.o `test -f 'selphy_print.c' || echo '$(srcdir)/'`selphy_print.c +@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.o `test -f 'backend_canonselphy.c' || echo '$(srcdir)/'`backend_canonselphy.c -backend_gutenprint-selphy_print.obj: selphy_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-selphy_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-selphy_print.Tpo -c -o backend_gutenprint-selphy_print.obj `if test -f 'selphy_print.c'; then $(CYGPATH_W) 'selphy_print.c'; else $(CYGPATH_W) '$(srcdir)/selphy_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-selphy_print.Tpo $(DEPDIR)/backend_gutenprint-selphy_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='selphy_print.c' object='backend_gutenprint-selphy_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_canonselphy.obj: backend_canonselphy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_canonselphy.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_canonselphy.Tpo -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` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_canonselphy.Tpo $(DEPDIR)/backend_gutenprint-backend_canonselphy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_canonselphy.c' object='backend_gutenprint-backend_canonselphy.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-selphy_print.obj `if test -f 'selphy_print.c'; then $(CYGPATH_W) 'selphy_print.c'; else $(CYGPATH_W) '$(srcdir)/selphy_print.c'; fi` +@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-kodak1400_print.o: kodak1400_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-kodak1400_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-kodak1400_print.Tpo -c -o backend_gutenprint-kodak1400_print.o `test -f 'kodak1400_print.c' || echo '$(srcdir)/'`kodak1400_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-kodak1400_print.Tpo $(DEPDIR)/backend_gutenprint-kodak1400_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kodak1400_print.c' object='backend_gutenprint-kodak1400_print.o' libtool=no @AMDEPBACKSLASH@ +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 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_kodak1400.c' object='backend_gutenprint-backend_kodak1400.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-kodak1400_print.o `test -f 'kodak1400_print.c' || echo '$(srcdir)/'`kodak1400_print.c +@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_kodak1400.o `test -f 'backend_kodak1400.c' || echo '$(srcdir)/'`backend_kodak1400.c -backend_gutenprint-kodak1400_print.obj: kodak1400_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-kodak1400_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-kodak1400_print.Tpo -c -o backend_gutenprint-kodak1400_print.obj `if test -f 'kodak1400_print.c'; then $(CYGPATH_W) 'kodak1400_print.c'; else $(CYGPATH_W) '$(srcdir)/kodak1400_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-kodak1400_print.Tpo $(DEPDIR)/backend_gutenprint-kodak1400_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kodak1400_print.c' object='backend_gutenprint-kodak1400_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_kodak1400.obj: 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.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_kodak1400.Tpo -c -o backend_gutenprint-backend_kodak1400.obj `if test -f 'backend_kodak1400.c'; then $(CYGPATH_W) 'backend_kodak1400.c'; else $(CYGPATH_W) '$(srcdir)/backend_kodak1400.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_kodak1400.Tpo $(DEPDIR)/backend_gutenprint-backend_kodak1400.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_kodak1400.c' object='backend_gutenprint-backend_kodak1400.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-kodak1400_print.obj `if test -f 'kodak1400_print.c'; then $(CYGPATH_W) 'kodak1400_print.c'; else $(CYGPATH_W) '$(srcdir)/kodak1400_print.c'; fi` +@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_kodak1400.obj `if test -f 'backend_kodak1400.c'; then $(CYGPATH_W) 'backend_kodak1400.c'; else $(CYGPATH_W) '$(srcdir)/backend_kodak1400.c'; fi` -backend_gutenprint-kodak6800_print.o: kodak6800_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-kodak6800_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-kodak6800_print.Tpo -c -o backend_gutenprint-kodak6800_print.o `test -f 'kodak6800_print.c' || echo '$(srcdir)/'`kodak6800_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-kodak6800_print.Tpo $(DEPDIR)/backend_gutenprint-kodak6800_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kodak6800_print.c' object='backend_gutenprint-kodak6800_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_kodak6800.o: backend_kodak6800.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_kodak6800.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_kodak6800.Tpo -c -o backend_gutenprint-backend_kodak6800.o `test -f 'backend_kodak6800.c' || echo '$(srcdir)/'`backend_kodak6800.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_kodak6800.Tpo $(DEPDIR)/backend_gutenprint-backend_kodak6800.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_kodak6800.c' object='backend_gutenprint-backend_kodak6800.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-kodak6800_print.o `test -f 'kodak6800_print.c' || echo '$(srcdir)/'`kodak6800_print.c +@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_kodak6800.o `test -f 'backend_kodak6800.c' || echo '$(srcdir)/'`backend_kodak6800.c -backend_gutenprint-kodak6800_print.obj: kodak6800_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-kodak6800_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-kodak6800_print.Tpo -c -o backend_gutenprint-kodak6800_print.obj `if test -f 'kodak6800_print.c'; then $(CYGPATH_W) 'kodak6800_print.c'; else $(CYGPATH_W) '$(srcdir)/kodak6800_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-kodak6800_print.Tpo $(DEPDIR)/backend_gutenprint-kodak6800_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kodak6800_print.c' object='backend_gutenprint-kodak6800_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_kodak6800.obj: backend_kodak6800.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_kodak6800.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_kodak6800.Tpo -c -o backend_gutenprint-backend_kodak6800.obj `if test -f 'backend_kodak6800.c'; then $(CYGPATH_W) 'backend_kodak6800.c'; else $(CYGPATH_W) '$(srcdir)/backend_kodak6800.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_kodak6800.Tpo $(DEPDIR)/backend_gutenprint-backend_kodak6800.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_kodak6800.c' object='backend_gutenprint-backend_kodak6800.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-kodak6800_print.obj `if test -f 'kodak6800_print.c'; then $(CYGPATH_W) 'kodak6800_print.c'; else $(CYGPATH_W) '$(srcdir)/kodak6800_print.c'; fi` +@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_kodak6800.obj `if test -f 'backend_kodak6800.c'; then $(CYGPATH_W) 'backend_kodak6800.c'; else $(CYGPATH_W) '$(srcdir)/backend_kodak6800.c'; fi` -backend_gutenprint-kodak605_print.o: kodak605_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-kodak605_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-kodak605_print.Tpo -c -o backend_gutenprint-kodak605_print.o `test -f 'kodak605_print.c' || echo '$(srcdir)/'`kodak605_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-kodak605_print.Tpo $(DEPDIR)/backend_gutenprint-kodak605_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kodak605_print.c' object='backend_gutenprint-kodak605_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_kodak605.o: backend_kodak605.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_kodak605.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_kodak605.Tpo -c -o backend_gutenprint-backend_kodak605.o `test -f 'backend_kodak605.c' || echo '$(srcdir)/'`backend_kodak605.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_kodak605.Tpo $(DEPDIR)/backend_gutenprint-backend_kodak605.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_kodak605.c' object='backend_gutenprint-backend_kodak605.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-kodak605_print.o `test -f 'kodak605_print.c' || echo '$(srcdir)/'`kodak605_print.c +@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_kodak605.o `test -f 'backend_kodak605.c' || echo '$(srcdir)/'`backend_kodak605.c -backend_gutenprint-kodak605_print.obj: kodak605_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-kodak605_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-kodak605_print.Tpo -c -o backend_gutenprint-kodak605_print.obj `if test -f 'kodak605_print.c'; then $(CYGPATH_W) 'kodak605_print.c'; else $(CYGPATH_W) '$(srcdir)/kodak605_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-kodak605_print.Tpo $(DEPDIR)/backend_gutenprint-kodak605_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kodak605_print.c' object='backend_gutenprint-kodak605_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_kodak605.obj: backend_kodak605.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_kodak605.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_kodak605.Tpo -c -o backend_gutenprint-backend_kodak605.obj `if test -f 'backend_kodak605.c'; then $(CYGPATH_W) 'backend_kodak605.c'; else $(CYGPATH_W) '$(srcdir)/backend_kodak605.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_kodak605.Tpo $(DEPDIR)/backend_gutenprint-backend_kodak605.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_kodak605.c' object='backend_gutenprint-backend_kodak605.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-kodak605_print.obj `if test -f 'kodak605_print.c'; then $(CYGPATH_W) 'kodak605_print.c'; else $(CYGPATH_W) '$(srcdir)/kodak605_print.c'; fi` +@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_kodak605.obj `if test -f 'backend_kodak605.c'; then $(CYGPATH_W) 'backend_kodak605.c'; else $(CYGPATH_W) '$(srcdir)/backend_kodak605.c'; fi` -backend_gutenprint-shinko_s2145_print.o: shinko_s2145_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-shinko_s2145_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-shinko_s2145_print.Tpo -c -o backend_gutenprint-shinko_s2145_print.o `test -f 'shinko_s2145_print.c' || echo '$(srcdir)/'`shinko_s2145_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-shinko_s2145_print.Tpo $(DEPDIR)/backend_gutenprint-shinko_s2145_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shinko_s2145_print.c' object='backend_gutenprint-shinko_s2145_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_shinkos2145.o: backend_shinkos2145.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_shinkos2145.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_shinkos2145.Tpo -c -o backend_gutenprint-backend_shinkos2145.o `test -f 'backend_shinkos2145.c' || echo '$(srcdir)/'`backend_shinkos2145.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_shinkos2145.Tpo $(DEPDIR)/backend_gutenprint-backend_shinkos2145.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_shinkos2145.c' object='backend_gutenprint-backend_shinkos2145.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-shinko_s2145_print.o `test -f 'shinko_s2145_print.c' || echo '$(srcdir)/'`shinko_s2145_print.c +@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_shinkos2145.o `test -f 'backend_shinkos2145.c' || echo '$(srcdir)/'`backend_shinkos2145.c -backend_gutenprint-shinko_s2145_print.obj: shinko_s2145_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-shinko_s2145_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-shinko_s2145_print.Tpo -c -o backend_gutenprint-shinko_s2145_print.obj `if test -f 'shinko_s2145_print.c'; then $(CYGPATH_W) 'shinko_s2145_print.c'; else $(CYGPATH_W) '$(srcdir)/shinko_s2145_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-shinko_s2145_print.Tpo $(DEPDIR)/backend_gutenprint-shinko_s2145_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shinko_s2145_print.c' object='backend_gutenprint-shinko_s2145_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_shinkos2145.obj: backend_shinkos2145.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_shinkos2145.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_shinkos2145.Tpo -c -o backend_gutenprint-backend_shinkos2145.obj `if test -f 'backend_shinkos2145.c'; then $(CYGPATH_W) 'backend_shinkos2145.c'; else $(CYGPATH_W) '$(srcdir)/backend_shinkos2145.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_shinkos2145.Tpo $(DEPDIR)/backend_gutenprint-backend_shinkos2145.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_shinkos2145.c' object='backend_gutenprint-backend_shinkos2145.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-shinko_s2145_print.obj `if test -f 'shinko_s2145_print.c'; then $(CYGPATH_W) 'shinko_s2145_print.c'; else $(CYGPATH_W) '$(srcdir)/shinko_s2145_print.c'; fi` +@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_shinkos2145.obj `if test -f 'backend_shinkos2145.c'; then $(CYGPATH_W) 'backend_shinkos2145.c'; else $(CYGPATH_W) '$(srcdir)/backend_shinkos2145.c'; fi` -backend_gutenprint-sony_updr150_print.o: sony_updr150_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-sony_updr150_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-sony_updr150_print.Tpo -c -o backend_gutenprint-sony_updr150_print.o `test -f 'sony_updr150_print.c' || echo '$(srcdir)/'`sony_updr150_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-sony_updr150_print.Tpo $(DEPDIR)/backend_gutenprint-sony_updr150_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sony_updr150_print.c' object='backend_gutenprint-sony_updr150_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_sonyupdr150.o: backend_sonyupdr150.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_sonyupdr150.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Tpo -c -o backend_gutenprint-backend_sonyupdr150.o `test -f 'backend_sonyupdr150.c' || echo '$(srcdir)/'`backend_sonyupdr150.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Tpo $(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_sonyupdr150.c' object='backend_gutenprint-backend_sonyupdr150.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-sony_updr150_print.o `test -f 'sony_updr150_print.c' || echo '$(srcdir)/'`sony_updr150_print.c +@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_sonyupdr150.o `test -f 'backend_sonyupdr150.c' || echo '$(srcdir)/'`backend_sonyupdr150.c -backend_gutenprint-sony_updr150_print.obj: sony_updr150_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-sony_updr150_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-sony_updr150_print.Tpo -c -o backend_gutenprint-sony_updr150_print.obj `if test -f 'sony_updr150_print.c'; then $(CYGPATH_W) 'sony_updr150_print.c'; else $(CYGPATH_W) '$(srcdir)/sony_updr150_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-sony_updr150_print.Tpo $(DEPDIR)/backend_gutenprint-sony_updr150_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sony_updr150_print.c' object='backend_gutenprint-sony_updr150_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_sonyupdr150.obj: backend_sonyupdr150.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_sonyupdr150.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Tpo -c -o backend_gutenprint-backend_sonyupdr150.obj `if test -f 'backend_sonyupdr150.c'; then $(CYGPATH_W) 'backend_sonyupdr150.c'; else $(CYGPATH_W) '$(srcdir)/backend_sonyupdr150.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Tpo $(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_sonyupdr150.c' object='backend_gutenprint-backend_sonyupdr150.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-sony_updr150_print.obj `if test -f 'sony_updr150_print.c'; then $(CYGPATH_W) 'sony_updr150_print.c'; else $(CYGPATH_W) '$(srcdir)/sony_updr150_print.c'; fi` +@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_sonyupdr150.obj `if test -f 'backend_sonyupdr150.c'; then $(CYGPATH_W) 'backend_sonyupdr150.c'; else $(CYGPATH_W) '$(srcdir)/backend_sonyupdr150.c'; fi` -backend_gutenprint-dnpds40_print.o: dnpds40_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-dnpds40_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-dnpds40_print.Tpo -c -o backend_gutenprint-dnpds40_print.o `test -f 'dnpds40_print.c' || echo '$(srcdir)/'`dnpds40_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-dnpds40_print.Tpo $(DEPDIR)/backend_gutenprint-dnpds40_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dnpds40_print.c' object='backend_gutenprint-dnpds40_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_dnpds40.o: backend_dnpds40.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_dnpds40.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_dnpds40.Tpo -c -o backend_gutenprint-backend_dnpds40.o `test -f 'backend_dnpds40.c' || echo '$(srcdir)/'`backend_dnpds40.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_dnpds40.Tpo $(DEPDIR)/backend_gutenprint-backend_dnpds40.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_dnpds40.c' object='backend_gutenprint-backend_dnpds40.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-dnpds40_print.o `test -f 'dnpds40_print.c' || echo '$(srcdir)/'`dnpds40_print.c +@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_dnpds40.o `test -f 'backend_dnpds40.c' || echo '$(srcdir)/'`backend_dnpds40.c -backend_gutenprint-dnpds40_print.obj: dnpds40_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-dnpds40_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-dnpds40_print.Tpo -c -o backend_gutenprint-dnpds40_print.obj `if test -f 'dnpds40_print.c'; then $(CYGPATH_W) 'dnpds40_print.c'; else $(CYGPATH_W) '$(srcdir)/dnpds40_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-dnpds40_print.Tpo $(DEPDIR)/backend_gutenprint-dnpds40_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dnpds40_print.c' object='backend_gutenprint-dnpds40_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_dnpds40.obj: backend_dnpds40.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_dnpds40.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_dnpds40.Tpo -c -o backend_gutenprint-backend_dnpds40.obj `if test -f 'backend_dnpds40.c'; then $(CYGPATH_W) 'backend_dnpds40.c'; else $(CYGPATH_W) '$(srcdir)/backend_dnpds40.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_dnpds40.Tpo $(DEPDIR)/backend_gutenprint-backend_dnpds40.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_dnpds40.c' object='backend_gutenprint-backend_dnpds40.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-dnpds40_print.obj `if test -f 'dnpds40_print.c'; then $(CYGPATH_W) 'dnpds40_print.c'; else $(CYGPATH_W) '$(srcdir)/dnpds40_print.c'; fi` +@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_dnpds40.obj `if test -f 'backend_dnpds40.c'; then $(CYGPATH_W) 'backend_dnpds40.c'; else $(CYGPATH_W) '$(srcdir)/backend_dnpds40.c'; fi` -backend_gutenprint-mitsu70x_print.o: mitsu70x_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-mitsu70x_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-mitsu70x_print.Tpo -c -o backend_gutenprint-mitsu70x_print.o `test -f 'mitsu70x_print.c' || echo '$(srcdir)/'`mitsu70x_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-mitsu70x_print.Tpo $(DEPDIR)/backend_gutenprint-mitsu70x_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mitsu70x_print.c' object='backend_gutenprint-mitsu70x_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_mitsu70x.o: backend_mitsu70x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_mitsu70x.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_mitsu70x.Tpo -c -o backend_gutenprint-backend_mitsu70x.o `test -f 'backend_mitsu70x.c' || echo '$(srcdir)/'`backend_mitsu70x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_mitsu70x.Tpo $(DEPDIR)/backend_gutenprint-backend_mitsu70x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_mitsu70x.c' object='backend_gutenprint-backend_mitsu70x.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-mitsu70x_print.o `test -f 'mitsu70x_print.c' || echo '$(srcdir)/'`mitsu70x_print.c +@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_mitsu70x.o `test -f 'backend_mitsu70x.c' || echo '$(srcdir)/'`backend_mitsu70x.c -backend_gutenprint-mitsu70x_print.obj: mitsu70x_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-mitsu70x_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-mitsu70x_print.Tpo -c -o backend_gutenprint-mitsu70x_print.obj `if test -f 'mitsu70x_print.c'; then $(CYGPATH_W) 'mitsu70x_print.c'; else $(CYGPATH_W) '$(srcdir)/mitsu70x_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-mitsu70x_print.Tpo $(DEPDIR)/backend_gutenprint-mitsu70x_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mitsu70x_print.c' object='backend_gutenprint-mitsu70x_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_mitsu70x.obj: backend_mitsu70x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_mitsu70x.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_mitsu70x.Tpo -c -o backend_gutenprint-backend_mitsu70x.obj `if test -f 'backend_mitsu70x.c'; then $(CYGPATH_W) 'backend_mitsu70x.c'; else $(CYGPATH_W) '$(srcdir)/backend_mitsu70x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_mitsu70x.Tpo $(DEPDIR)/backend_gutenprint-backend_mitsu70x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_mitsu70x.c' object='backend_gutenprint-backend_mitsu70x.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-mitsu70x_print.obj `if test -f 'mitsu70x_print.c'; then $(CYGPATH_W) 'mitsu70x_print.c'; else $(CYGPATH_W) '$(srcdir)/mitsu70x_print.c'; fi` +@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_mitsu70x.obj `if test -f 'backend_mitsu70x.c'; then $(CYGPATH_W) 'backend_mitsu70x.c'; else $(CYGPATH_W) '$(srcdir)/backend_mitsu70x.c'; fi` -backend_gutenprint-citizencw01_print.o: citizencw01_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-citizencw01_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-citizencw01_print.Tpo -c -o backend_gutenprint-citizencw01_print.o `test -f 'citizencw01_print.c' || echo '$(srcdir)/'`citizencw01_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-citizencw01_print.Tpo $(DEPDIR)/backend_gutenprint-citizencw01_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='citizencw01_print.c' object='backend_gutenprint-citizencw01_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_citizencw01.o: backend_citizencw01.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_citizencw01.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_citizencw01.Tpo -c -o backend_gutenprint-backend_citizencw01.o `test -f 'backend_citizencw01.c' || echo '$(srcdir)/'`backend_citizencw01.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_citizencw01.Tpo $(DEPDIR)/backend_gutenprint-backend_citizencw01.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_citizencw01.c' object='backend_gutenprint-backend_citizencw01.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-citizencw01_print.o `test -f 'citizencw01_print.c' || echo '$(srcdir)/'`citizencw01_print.c +@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_citizencw01.o `test -f 'backend_citizencw01.c' || echo '$(srcdir)/'`backend_citizencw01.c -backend_gutenprint-citizencw01_print.obj: citizencw01_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-citizencw01_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-citizencw01_print.Tpo -c -o backend_gutenprint-citizencw01_print.obj `if test -f 'citizencw01_print.c'; then $(CYGPATH_W) 'citizencw01_print.c'; else $(CYGPATH_W) '$(srcdir)/citizencw01_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-citizencw01_print.Tpo $(DEPDIR)/backend_gutenprint-citizencw01_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='citizencw01_print.c' object='backend_gutenprint-citizencw01_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_citizencw01.obj: backend_citizencw01.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_citizencw01.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_citizencw01.Tpo -c -o backend_gutenprint-backend_citizencw01.obj `if test -f 'backend_citizencw01.c'; then $(CYGPATH_W) 'backend_citizencw01.c'; else $(CYGPATH_W) '$(srcdir)/backend_citizencw01.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_citizencw01.Tpo $(DEPDIR)/backend_gutenprint-backend_citizencw01.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_citizencw01.c' object='backend_gutenprint-backend_citizencw01.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-citizencw01_print.obj `if test -f 'citizencw01_print.c'; then $(CYGPATH_W) 'citizencw01_print.c'; else $(CYGPATH_W) '$(srcdir)/citizencw01_print.c'; fi` +@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_citizencw01.obj `if test -f 'backend_citizencw01.c'; then $(CYGPATH_W) 'backend_citizencw01.c'; else $(CYGPATH_W) '$(srcdir)/backend_citizencw01.c'; fi` -backend_gutenprint-mitsu9550_print.o: mitsu9550_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-mitsu9550_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-mitsu9550_print.Tpo -c -o backend_gutenprint-mitsu9550_print.o `test -f 'mitsu9550_print.c' || echo '$(srcdir)/'`mitsu9550_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-mitsu9550_print.Tpo $(DEPDIR)/backend_gutenprint-mitsu9550_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mitsu9550_print.c' object='backend_gutenprint-mitsu9550_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_mitsu9550.o: backend_mitsu9550.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_mitsu9550.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_mitsu9550.Tpo -c -o backend_gutenprint-backend_mitsu9550.o `test -f 'backend_mitsu9550.c' || echo '$(srcdir)/'`backend_mitsu9550.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_mitsu9550.Tpo $(DEPDIR)/backend_gutenprint-backend_mitsu9550.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_mitsu9550.c' object='backend_gutenprint-backend_mitsu9550.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-mitsu9550_print.o `test -f 'mitsu9550_print.c' || echo '$(srcdir)/'`mitsu9550_print.c +@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_mitsu9550.o `test -f 'backend_mitsu9550.c' || echo '$(srcdir)/'`backend_mitsu9550.c -backend_gutenprint-mitsu9550_print.obj: mitsu9550_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-mitsu9550_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-mitsu9550_print.Tpo -c -o backend_gutenprint-mitsu9550_print.obj `if test -f 'mitsu9550_print.c'; then $(CYGPATH_W) 'mitsu9550_print.c'; else $(CYGPATH_W) '$(srcdir)/mitsu9550_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-mitsu9550_print.Tpo $(DEPDIR)/backend_gutenprint-mitsu9550_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mitsu9550_print.c' object='backend_gutenprint-mitsu9550_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_mitsu9550.obj: backend_mitsu9550.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_mitsu9550.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_mitsu9550.Tpo -c -o backend_gutenprint-backend_mitsu9550.obj `if test -f 'backend_mitsu9550.c'; then $(CYGPATH_W) 'backend_mitsu9550.c'; else $(CYGPATH_W) '$(srcdir)/backend_mitsu9550.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_mitsu9550.Tpo $(DEPDIR)/backend_gutenprint-backend_mitsu9550.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_mitsu9550.c' object='backend_gutenprint-backend_mitsu9550.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-mitsu9550_print.obj `if test -f 'mitsu9550_print.c'; then $(CYGPATH_W) 'mitsu9550_print.c'; else $(CYGPATH_W) '$(srcdir)/mitsu9550_print.c'; fi` +@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_mitsu9550.obj `if test -f 'backend_mitsu9550.c'; then $(CYGPATH_W) 'backend_mitsu9550.c'; else $(CYGPATH_W) '$(srcdir)/backend_mitsu9550.c'; fi` backend_gutenprint-backend_common.o: backend_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_common.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_common.Tpo -c -o backend_gutenprint-backend_common.o `test -f 'backend_common.c' || echo '$(srcdir)/'`backend_common.c @@ -1313,47 +1308,47 @@ backend_gutenprint-backend_common.obj: backend_common.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_common.obj `if test -f 'backend_common.c'; then $(CYGPATH_W) 'backend_common.c'; else $(CYGPATH_W) '$(srcdir)/backend_common.c'; fi` -backend_gutenprint-shinko_s1245_print.o: shinko_s1245_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-shinko_s1245_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-shinko_s1245_print.Tpo -c -o backend_gutenprint-shinko_s1245_print.o `test -f 'shinko_s1245_print.c' || echo '$(srcdir)/'`shinko_s1245_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-shinko_s1245_print.Tpo $(DEPDIR)/backend_gutenprint-shinko_s1245_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shinko_s1245_print.c' object='backend_gutenprint-shinko_s1245_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_shinkos1245.o: backend_shinkos1245.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_shinkos1245.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_shinkos1245.Tpo -c -o backend_gutenprint-backend_shinkos1245.o `test -f 'backend_shinkos1245.c' || echo '$(srcdir)/'`backend_shinkos1245.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_shinkos1245.Tpo $(DEPDIR)/backend_gutenprint-backend_shinkos1245.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_shinkos1245.c' object='backend_gutenprint-backend_shinkos1245.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-shinko_s1245_print.o `test -f 'shinko_s1245_print.c' || echo '$(srcdir)/'`shinko_s1245_print.c +@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_shinkos1245.o `test -f 'backend_shinkos1245.c' || echo '$(srcdir)/'`backend_shinkos1245.c -backend_gutenprint-shinko_s1245_print.obj: shinko_s1245_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-shinko_s1245_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-shinko_s1245_print.Tpo -c -o backend_gutenprint-shinko_s1245_print.obj `if test -f 'shinko_s1245_print.c'; then $(CYGPATH_W) 'shinko_s1245_print.c'; else $(CYGPATH_W) '$(srcdir)/shinko_s1245_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-shinko_s1245_print.Tpo $(DEPDIR)/backend_gutenprint-shinko_s1245_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shinko_s1245_print.c' object='backend_gutenprint-shinko_s1245_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_shinkos1245.obj: backend_shinkos1245.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_shinkos1245.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_shinkos1245.Tpo -c -o backend_gutenprint-backend_shinkos1245.obj `if test -f 'backend_shinkos1245.c'; then $(CYGPATH_W) 'backend_shinkos1245.c'; else $(CYGPATH_W) '$(srcdir)/backend_shinkos1245.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_shinkos1245.Tpo $(DEPDIR)/backend_gutenprint-backend_shinkos1245.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_shinkos1245.c' object='backend_gutenprint-backend_shinkos1245.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-shinko_s1245_print.obj `if test -f 'shinko_s1245_print.c'; then $(CYGPATH_W) 'shinko_s1245_print.c'; else $(CYGPATH_W) '$(srcdir)/shinko_s1245_print.c'; fi` +@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_shinkos1245.obj `if test -f 'backend_shinkos1245.c'; then $(CYGPATH_W) 'backend_shinkos1245.c'; else $(CYGPATH_W) '$(srcdir)/backend_shinkos1245.c'; fi` -backend_gutenprint-shinko_s6145_print.o: shinko_s6145_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-shinko_s6145_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-shinko_s6145_print.Tpo -c -o backend_gutenprint-shinko_s6145_print.o `test -f 'shinko_s6145_print.c' || echo '$(srcdir)/'`shinko_s6145_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-shinko_s6145_print.Tpo $(DEPDIR)/backend_gutenprint-shinko_s6145_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shinko_s6145_print.c' object='backend_gutenprint-shinko_s6145_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_shinkos6145.o: backend_shinkos6145.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_shinkos6145.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_shinkos6145.Tpo -c -o backend_gutenprint-backend_shinkos6145.o `test -f 'backend_shinkos6145.c' || echo '$(srcdir)/'`backend_shinkos6145.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_shinkos6145.Tpo $(DEPDIR)/backend_gutenprint-backend_shinkos6145.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_shinkos6145.c' object='backend_gutenprint-backend_shinkos6145.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-shinko_s6145_print.o `test -f 'shinko_s6145_print.c' || echo '$(srcdir)/'`shinko_s6145_print.c +@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_shinkos6145.o `test -f 'backend_shinkos6145.c' || echo '$(srcdir)/'`backend_shinkos6145.c -backend_gutenprint-shinko_s6145_print.obj: shinko_s6145_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-shinko_s6145_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-shinko_s6145_print.Tpo -c -o backend_gutenprint-shinko_s6145_print.obj `if test -f 'shinko_s6145_print.c'; then $(CYGPATH_W) 'shinko_s6145_print.c'; else $(CYGPATH_W) '$(srcdir)/shinko_s6145_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-shinko_s6145_print.Tpo $(DEPDIR)/backend_gutenprint-shinko_s6145_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shinko_s6145_print.c' object='backend_gutenprint-shinko_s6145_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_shinkos6145.obj: backend_shinkos6145.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_shinkos6145.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_shinkos6145.Tpo -c -o backend_gutenprint-backend_shinkos6145.obj `if test -f 'backend_shinkos6145.c'; then $(CYGPATH_W) 'backend_shinkos6145.c'; else $(CYGPATH_W) '$(srcdir)/backend_shinkos6145.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_shinkos6145.Tpo $(DEPDIR)/backend_gutenprint-backend_shinkos6145.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_shinkos6145.c' object='backend_gutenprint-backend_shinkos6145.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-shinko_s6145_print.obj `if test -f 'shinko_s6145_print.c'; then $(CYGPATH_W) 'shinko_s6145_print.c'; else $(CYGPATH_W) '$(srcdir)/shinko_s6145_print.c'; fi` +@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_shinkos6145.obj `if test -f 'backend_shinkos6145.c'; then $(CYGPATH_W) 'backend_shinkos6145.c'; else $(CYGPATH_W) '$(srcdir)/backend_shinkos6145.c'; fi` -backend_gutenprint-shinko_s6245_print.o: shinko_s6245_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-shinko_s6245_print.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-shinko_s6245_print.Tpo -c -o backend_gutenprint-shinko_s6245_print.o `test -f 'shinko_s6245_print.c' || echo '$(srcdir)/'`shinko_s6245_print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-shinko_s6245_print.Tpo $(DEPDIR)/backend_gutenprint-shinko_s6245_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shinko_s6245_print.c' object='backend_gutenprint-shinko_s6245_print.o' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_shinkos6245.o: backend_shinkos6245.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_shinkos6245.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_shinkos6245.Tpo -c -o backend_gutenprint-backend_shinkos6245.o `test -f 'backend_shinkos6245.c' || echo '$(srcdir)/'`backend_shinkos6245.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_shinkos6245.Tpo $(DEPDIR)/backend_gutenprint-backend_shinkos6245.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_shinkos6245.c' object='backend_gutenprint-backend_shinkos6245.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-shinko_s6245_print.o `test -f 'shinko_s6245_print.c' || echo '$(srcdir)/'`shinko_s6245_print.c +@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.o `test -f 'backend_shinkos6245.c' || echo '$(srcdir)/'`backend_shinkos6245.c -backend_gutenprint-shinko_s6245_print.obj: shinko_s6245_print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-shinko_s6245_print.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-shinko_s6245_print.Tpo -c -o backend_gutenprint-shinko_s6245_print.obj `if test -f 'shinko_s6245_print.c'; then $(CYGPATH_W) 'shinko_s6245_print.c'; else $(CYGPATH_W) '$(srcdir)/shinko_s6245_print.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-shinko_s6245_print.Tpo $(DEPDIR)/backend_gutenprint-shinko_s6245_print.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shinko_s6245_print.c' object='backend_gutenprint-shinko_s6245_print.obj' libtool=no @AMDEPBACKSLASH@ +backend_gutenprint-backend_shinkos6245.obj: backend_shinkos6245.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_shinkos6245.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_shinkos6245.Tpo -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` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_shinkos6245.Tpo $(DEPDIR)/backend_gutenprint-backend_shinkos6245.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_shinkos6245.c' object='backend_gutenprint-backend_shinkos6245.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-shinko_s6245_print.obj `if test -f 'shinko_s6245_print.c'; then $(CYGPATH_W) 'shinko_s6245_print.c'; else $(CYGPATH_W) '$(srcdir)/shinko_s6245_print.c'; fi` +@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` 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 diff --git a/src/cups/selphy_print.c b/src/cups/backend_canonselphy.c index 8da09e0..4da082a 100644 --- a/src/cups/selphy_print.c +++ b/src/cups/backend_canonselphy.c @@ -1,7 +1,7 @@ /* * Canon SELPHY ES/CP series CUPS backend -- libusb-1.0 version * - * (c) 2007-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2007-2016 Solomon Peachy <pizza@shaftnet.org> * * The latest version of this program can be found at: * @@ -91,9 +91,22 @@ struct printer_data { int16_t paper_codes[256]; int16_t pgcode_offset; /* Offset into printjob for paper type */ int16_t paper_code_offset; /* Offset in readback for paper type */ - int (*error_detect)(uint8_t *rdbuf); + int (*error_detect)(uint8_t *rdbuf); + char *(*pgcode_names)(uint8_t pgcode); }; +static char *generic_pgcode_names(uint8_t pgcode) +{ + switch(pgcode & 0xf) { + case 0x01: return "P"; + case 0x02: return "L"; + case 0x03: return "C"; + case 0x04: return "W"; + case 0x0f: return "None"; + default: return "Unknown"; + } +} + static int es1_error_detect(uint8_t *rdbuf) { if (rdbuf[1] == 0x01) { @@ -105,9 +118,11 @@ static int es1_error_detect(uint8_t *rdbuf) return 1; } else if (rdbuf[4] == 0x01 && rdbuf[5] == 0xff && rdbuf[6] == 0xff && rdbuf[7] == 0xff) { + ATTR("marker-levels=%d\n", 0); ERROR("No media loaded!\n"); return 1; } else if (rdbuf[0] == 0x0f) { + ATTR("marker-levels=%d\n", 0); ERROR("Out of media!\n"); return 1; } @@ -127,11 +142,13 @@ static int es2_error_detect(uint8_t *rdbuf) rdbuf[4] == 0x05 && rdbuf[5] == 0x05 && rdbuf[6] == 0x02) { + ATTR("marker-levels=%d\n", 0); ERROR("No media loaded!\n"); return 1; } if (rdbuf[0] == 0x14) { + ATTR("marker-levels=%d\n", 0); ERROR("Out of media!\n"); return 1; } @@ -145,6 +162,7 @@ static int es3_error_detect(uint8_t *rdbuf) if (rdbuf[10] == 0x0f) { ERROR("Communications Error\n"); } else if (rdbuf[10] == 0x01) { + ATTR("marker-levels=%d\n", 0); ERROR("No media loaded!\n"); } else { ERROR("Unknown error - %02x + %02x\n", @@ -153,6 +171,7 @@ static int es3_error_detect(uint8_t *rdbuf) return 1; } else if (rdbuf[8] == 0x03 && rdbuf[10] == 0x02) { + ATTR("marker-levels=%d\n", 0); ERROR("No media loaded!\n"); return 1; } else if (rdbuf[8] == 0x08 && @@ -182,10 +201,12 @@ static int es40_error_detect(uint8_t *rdbuf) if (rdbuf[3] == 0x01) ERROR("Generic communication error\n"); - else if (rdbuf[3] == 0x32) + else if (rdbuf[3] == 0x32) { + ATTR("marker-levels=%d\n", 0); ERROR("Cover open or media empty!\n"); - else + } else ERROR("Unknown error - %02x\n", rdbuf[3]); + return 1; } @@ -200,15 +221,18 @@ static int cp790_error_detect(uint8_t *rdbuf) ERROR("No paper tray loaded!\n"); return 1; } else if (rdbuf[3]) { - if ((rdbuf[3] & 0xf) == 0x02) // 0x12 0x22 + if ((rdbuf[3] & 0xf) == 0x02) { // 0x12 0x22 + ATTR("marker-levels=%d\n", 0); ERROR("No paper tray loaded!\n"); - else if ((rdbuf[3] & 0xf) == 0x03) // 0x13 0x23 + } else if ((rdbuf[3] & 0xf) == 0x03) { // 0x13 0x23 + ATTR("marker-levels=%d\n", 0); ERROR("Empty paper tray or feed error!\n"); - else if (rdbuf[3] == 0x11) + } else if (rdbuf[3] == 0x11) ERROR("Paper feed error!\n"); - else if (rdbuf[3] == 0x21) + else if (rdbuf[3] == 0x21) { + ATTR("marker-levels=%d\n", 0); ERROR("Ribbon depleted!\n"); - else + } else ERROR("Unknown error - %02x\n", rdbuf[3]); return 1; } @@ -216,19 +240,28 @@ static int cp790_error_detect(uint8_t *rdbuf) return 0; } +static char *cp10_pgcode_names(uint8_t pgcode) +{ + switch (pgcode) { + default: return "C"; + }; +} static int cp10_error_detect(uint8_t *rdbuf) { if (!rdbuf[2]) return 0; - if (rdbuf[2] == 0x80) + if (rdbuf[2] == 0x80) { + ATTR("marker-levels=%d\n", 0); ERROR("No ribbon loaded\n"); - else if (rdbuf[2] == 0x08) + } else if (rdbuf[2] == 0x08) { + ATTR("marker-levels=%d\n", 0); ERROR("Ribbon depleted!\n"); - else if (rdbuf[2] == 0x01) + } else if (rdbuf[2] == 0x01) { + ATTR("marker-levels=%d\n", 0); ERROR("No paper loaded!\n"); - else + } else ERROR("Unknown error - %02x\n", rdbuf[2]); return 1; } @@ -238,13 +271,15 @@ static int cpxxx_error_detect(uint8_t *rdbuf) if (!rdbuf[2]) return 0; - if (rdbuf[2] == 0x01) + if (rdbuf[2] == 0x01) { + ATTR("marker-levels=%d\n", 0); ERROR("Paper feed problem!\n"); - else if (rdbuf[2] == 0x04) + } else if (rdbuf[2] == 0x04) ERROR("Ribbon problem!\n"); - else if (rdbuf[2] == 0x08) + else if (rdbuf[2] == 0x08) { + ATTR("marker-levels=%d\n", 0); ERROR("Ribbon depleted!\n"); - else + } else ERROR("Unknown error - %02x\n", rdbuf[2]); return 1; } @@ -264,6 +299,7 @@ static struct printer_data selphy_printers[] = { .pgcode_offset = 3, .paper_code_offset = 6, .error_detect = es1_error_detect, + .pgcode_names = generic_pgcode_names, }, { .type = P_ES2_20, .model = "SELPHY ES2/ES20", @@ -279,6 +315,7 @@ static struct printer_data selphy_printers[] = { .pgcode_offset = 2, .paper_code_offset = 4, .error_detect = es2_error_detect, + .pgcode_names = generic_pgcode_names, }, { .type = P_ES3_30, .model = "SELPHY ES3/ES30", @@ -294,6 +331,7 @@ static struct printer_data selphy_printers[] = { .pgcode_offset = 2, .paper_code_offset = -1, .error_detect = es3_error_detect, + .pgcode_names = NULL, }, { .type = P_ES40, .model = "SELPHY ES40", @@ -309,6 +347,7 @@ static struct printer_data selphy_printers[] = { .pgcode_offset = 2, .paper_code_offset = 11, .error_detect = es40_error_detect, + .pgcode_names = generic_pgcode_names, }, { .type = P_CP790, .model = "SELPHY CP790", @@ -321,10 +360,10 @@ static struct printer_data selphy_printers[] = { .done_c_readback = { 0x00, 0x00, 0x10, 0x00, -1, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, .clear_error = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, .clear_error_len = 12, - // .paper_codes .pgcode_offset = 2, .paper_code_offset = -1, /* Uses a different technique */ .error_detect = cp790_error_detect, + .pgcode_names = generic_pgcode_names, }, { .type = P_CP_XXX, .model = "SELPHY CP Series (!CP-10/CP790)", @@ -337,10 +376,10 @@ static struct printer_data selphy_printers[] = { .done_c_readback = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, -1 }, .clear_error = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, .clear_error_len = 12, - // .paper_codes .pgcode_offset = 3, .paper_code_offset = 6, .error_detect = cpxxx_error_detect, + .pgcode_names = generic_pgcode_names, }, { .type = P_CP10, .model = "SELPHY CP-10", @@ -353,10 +392,10 @@ static struct printer_data selphy_printers[] = { .done_c_readback = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, .clear_error = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, .clear_error_len = 12, - // .paper_codes - .pgcode_offset = -1, + .pgcode_offset = 2, .paper_code_offset = -1, .error_detect = cp10_error_detect, + .pgcode_names = cp10_pgcode_names, }, { .type = -1 }, }; @@ -592,25 +631,46 @@ static void canonselphy_teardown(void *vctx) { free(ctx); } -static int canonselphy_early_parse(void *vctx, int data_fd) +static int canonselphy_read_parse(void *vctx, int data_fd) { struct canonselphy_ctx *ctx = vctx; - int printer_type, i; + int i, remain; + int printer_type; + int offset = 0; if (!ctx) - return -1; + return CUPS_BACKEND_FAILED; - /* Figure out printer this file is intended for */ - i = read(data_fd, ctx->buffer, MAX_HEADER); - if (i != MAX_HEADER) { + /* The CP900 job *may* have a 4-byte null footer after the + job contents. Ignore it if it comes through here.. */ + i = read(data_fd, ctx->buffer, 4); + if (i != 4) { if (i == 0) - return -1; - ERROR("Read failed (%d/%d/%d)\n", - i, 0, MAX_HEADER); + return CUPS_BACKEND_CANCEL; + ERROR("Read failed (%d/%d)\n", i, 4); perror("ERROR: Read failed"); - return -1; + return CUPS_BACKEND_FAILED; + } + /* if it's not the null header.. don't ignore! */ + if (ctx->buffer[0] != 0 || + ctx->buffer[1] != 0 || + ctx->buffer[2] != 0 || + ctx->buffer[3] != 0) { + offset = 4; } + /* Read the rest of the header.. */ + i = read(data_fd, ctx->buffer + offset, MAX_HEADER - offset); + if (i != MAX_HEADER - offset) { + if (i == 0) + return CUPS_BACKEND_CANCEL; + ERROR("Read failed (%d/%d)\n", + i, MAX_HEADER - offset); + perror("ERROR: Read failed"); + return CUPS_BACKEND_FAILED; + } + + /* Figure out printer this file is intended for */ printer_type = parse_printjob(ctx->buffer, &ctx->bw_mode, &ctx->plane_len); /* Special cases for some models */ if (printer_type == P_ES40_CP790) { @@ -628,39 +688,27 @@ static int canonselphy_early_parse(void *vctx, int data_fd) } } if (!ctx->printer) { - ERROR("Unrecognized printjob file format!\n"); - return -1; + ERROR("Error mapping printjob to printer type!\n"); + return CUPS_BACKEND_FAILED; } INFO("%sFile intended for a '%s' printer\n", ctx->bw_mode? "B/W " : "", ctx->printer->model); if (ctx->printer->type != ctx->type) { ERROR("Printer/Job mismatch (%d/%d)\n", ctx->type, ctx->printer->type); - return -1; + return CUPS_BACKEND_CANCEL; } - ctx->plane_len += 12; /* Add in plane header length! */ + /* Paper code setup */ if (ctx->printer->pgcode_offset != -1) ctx->paper_code = ctx->printer->paper_codes[ctx->buffer[ctx->printer->pgcode_offset]]; else ctx->paper_code = -1; - return printer_type; -} - -static int canonselphy_read_parse(void *vctx, int data_fd) -{ - struct canonselphy_ctx *ctx = vctx; - int i, remain; - - if (!ctx) - return CUPS_BACKEND_FAILED; - - /* Perform early parsing */ - i = canonselphy_early_parse(ctx, data_fd); - if (i < 0) - return CUPS_BACKEND_FAILED; + /* Add in plane header length! */ + ctx->plane_len += 12; + /* Now prep for the job */ if (ctx->header) { free(ctx->header); ctx->header = NULL; @@ -754,6 +802,13 @@ static int canonselphy_main_loop(void *vctx, int copies) { if (ret < 0) return CUPS_BACKEND_FAILED; + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='%s'\n", ctx->printer->pgcode_names? ctx->printer->pgcode_names(rdbuf[ctx->printer->paper_code_offset]) : "Unknown"); + ATTR("marker-types=ribbonWax\n"); + ATTR("marker-levels=%d\n", -3); /* ie Unknown but OK */ + top: if (state != last_state) { @@ -909,7 +964,7 @@ top: if (ctx->cp900) state = S_PRINTER_CP900_FOOTER; else - state = S_PRINTER_DONE; + state = S_FINISHED; } break; case S_PRINTER_CP900_FOOTER: { @@ -960,10 +1015,7 @@ static int canonselphy_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - - /* Reset arg parsing */ - optind = 1; - opterr = 0; + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL)) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL @@ -977,7 +1029,7 @@ static int canonselphy_cmdline_arg(void *vctx, int argc, char **argv) struct dyesub_backend canonselphy_backend = { .name = "Canon SELPHY CP/ES", - .version = "0.89", + .version = "0.91", .uri_prefix = "canonselphy", .cmdline_arg = canonselphy_cmdline_arg, .init = canonselphy_init, @@ -1285,7 +1337,7 @@ struct dyesub_backend canonselphy_backend = { Init func: 40 00 00 [pgcode] 00 00 00 00 00 00 00 00 Plane func: 40 01 00 [plane] [length, 32-bit LE] 00 00 00 00 - End func: 00 00 00 00 # NOTE: CP900 only, and not necessary! + End func: 00 00 00 00 # NOTE: Present (and necessary) on CP900 only. Error clear: 40 10 00 00 00 00 00 00 00 00 00 00 @@ -1331,13 +1383,13 @@ struct dyesub_backend canonselphy_backend = { to signify nothing being loaded. *************************************************************************** - Selphy CP820/CP910: + Selphy CP820/CP910/CP1000/CP1200: Radically different spool file format! 300dpi, same print sizes, but also adding a 50x50mm sticker and 22x17.3mm ministickers, though I think the driver treats all of those as 'C' sizes for printing purposes. - Printer does *not* apparently require use of a spooler! + Printer does *not* require use of a spooler! Huzzah! 32-byte header: @@ -1364,4 +1416,17 @@ struct dyesub_backend canonselphy_backend = { L == 5087264 == 1695744 * 3 + 32 (1536*1104) C == 2180384 == 726784 * 3 + 32 (1088*668) + It is worth mentioning that the image payload is Y'CbCr rather than the + traditional YMC (or even BGR) of other dyseubs. Our best guess is that + we need to use the JPEG coefficients, although we realistically have + no way of confirming this. + + It is hoped that the printers do support YMC data, but as of yet we + have no way of determining if this is possible. + + Also, we have reports of the printer not quite behaving properly + in the face of multiple jobs; it's possible this thing may need a + backend after all, but more sniffs will need to be performed to determine + what the status readbacks (if any) mean. + */ diff --git a/src/cups/citizencw01_print.c b/src/cups/backend_citizencw01.c index 37313b5..618af86 100644 --- a/src/cups/citizencw01_print.c +++ b/src/cups/backend_citizencw01.c @@ -1,7 +1,7 @@ /* * Citizen CW-01 Photo Printer CUPS backend -- libusb-1.0 version * - * (c) 2014-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2014-2016 Solomon Peachy <pizza@shaftnet.org> * * The latest version of this program can be found at: * @@ -826,9 +826,6 @@ static int cw01_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - /* Reset arg parsing */ - optind = 1; - opterr = 0; while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "inN:s")) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL diff --git a/src/cups/backend_common.c b/src/cups/backend_common.c index 4d682a8..171f564 100644 --- a/src/cups/backend_common.c +++ b/src/cups/backend_common.c @@ -1,7 +1,7 @@ /* * CUPS Backend common code * - * Copyright (c) 2007-2015 Solomon Peachy <pizza@shaftnet.org> + * Copyright (c) 2007-2016 Solomon Peachy <pizza@shaftnet.org> * * The latest version of this program can be found at: * @@ -27,7 +27,7 @@ #include "backend_common.h" -#define BACKEND_VERSION "0.63G" +#define BACKEND_VERSION "0.67G" #ifndef URI_PREFIX #error "Must Define URI_PREFIX" #endif @@ -74,7 +74,7 @@ static char *get_device_id(struct libusb_device_handle *dev) ERROR("Memory allocation failure (%d bytes)\n", ID_BUF_SIZE+1); return NULL; } - + if (libusb_kernel_driver_active(dev, iface)) libusb_detach_kernel_driver(dev, iface); @@ -100,10 +100,10 @@ static char *get_device_id(struct libusb_device_handle *dev) if (length > ID_BUF_SIZE || length < 14) length = (((unsigned)buf[1] & 255) << 8) | ((unsigned)buf[0] & 255); - + if (length > ID_BUF_SIZE) length = ID_BUF_SIZE; - + if (length < 14) { *buf = '\0'; goto done; @@ -212,7 +212,7 @@ int read_data(struct libusb_device_handle *dev, uint8_t endp, if (dyesub_debug) { DEBUG("Received %d bytes from printer\n", *readlen); } - + if ((dyesub_debug > 1 && buflen < 4096) || dyesub_debug > 2) { int i = *readlen; @@ -295,7 +295,7 @@ static char *sanitize_string(char *str) { return str; } -/* +/* These functions are Public Domain code obtained from: @@ -318,13 +318,13 @@ static char *url_encode(char *str) { ERROR("Memory allocation failure (%d bytes)\n", (int) strlen(str)*3 + 1); return NULL; } - + while (*pstr) { if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') *pbuf++ = *pstr; - else if (*pstr == ' ') + else if (*pstr == ' ') *pbuf++ = '+'; - else + else *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); pstr++; } @@ -345,7 +345,7 @@ static char *url_decode(char *str) { *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); pstr += 2; } - } else if (*pstr == '+') { + } else if (*pstr == '+') { *pbuf++ = ' '; } else { *pbuf++ = *pstr; @@ -439,7 +439,7 @@ static int print_scan_output(struct libusb_device *device, free(product2); return -1; } - + sprintf(descr, "%s %s", manuf3, product2); free(product2); free(manuf3); @@ -461,7 +461,7 @@ static int print_scan_output(struct libusb_device *device, } else if (backend->query_serno) { /* Get from backend hook */ int iface = 0; - struct libusb_config_descriptor *config; + struct libusb_config_descriptor *config = NULL; if (libusb_kernel_driver_active(dev, iface)) libusb_detach_kernel_driver(dev, iface); @@ -478,6 +478,8 @@ static int print_scan_output(struct libusb_device *device, else endp_down = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; } + if (endp_up && endp_down) + break; } buf[0] = 0; @@ -486,6 +488,9 @@ static int print_scan_output(struct libusb_device *device, libusb_release_interface(dev, iface); } serial = url_encode(buf); + + if (config) + libusb_free_config_descriptor(config); } if (!serial || !strlen(serial)) { /* Last-ditch */ @@ -499,7 +504,7 @@ static int print_scan_output(struct libusb_device *device, 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; @@ -515,9 +520,8 @@ static int print_scan_output(struct libusb_device *device, prefix, buf, serial, backend->uri_prefix, descr, descr, ieee_id? ieee_id : ""); - } - + /* If a serial number was passed down, use it. */ if (match_serno && strcmp(match_serno, (char*)serial)) { found = -1; @@ -528,7 +532,7 @@ static int print_scan_output(struct libusb_device *device, if(manuf) free(manuf); if(product) free(product); if(descr) free(descr); - if(ieee_id) free(ieee_id); + if (ieee_id) free(ieee_id); libusb_close(dev); abort: @@ -631,7 +635,6 @@ static int find_and_enumerate(struct libusb_context *ctx, static struct dyesub_backend *find_backend(char *uri_prefix) { int i; - if (!uri_prefix) return NULL; @@ -649,7 +652,7 @@ static struct dyesub_backend *find_backend(char *uri_prefix) void print_license_blurb(void) { const char *license = "\n\ -Copyright 2007-2015 Solomon Peachy <pizza AT shaftnet DOT org>\n\ +Copyright 2007-2016 Solomon Peachy <pizza AT shaftnet DOT org>\n\ \n\ This program is free software; you can redistribute it and/or modify it\n\ under the terms of the GNU General Public License as published by the Free\n\ @@ -683,7 +686,7 @@ void print_help(char *argv0, struct dyesub_backend *backend) if (!backend) backend = find_backend(ptr); - + if (!backend) { int i; DEBUG("Environment variables:\n"); @@ -694,8 +697,6 @@ void print_help(char *argv0, struct dyesub_backend *backend) DEBUG("Standalone Usage:\n"); DEBUG("\t%s\n", URI_PREFIX); DEBUG(" [ -D ] [ -G ] [ -f ]\n"); - DEBUG(" [ -S serialnum ] \n"); - DEBUG(" [ -V extra_vid ] [ -P extra_pid ] [ -T extra_type ] \n"); DEBUG(" [ backend_specific_args ] \n"); DEBUG(" [ -d copies ] \n"); DEBUG(" [ - | infile ] \n"); @@ -730,12 +731,12 @@ void print_help(char *argv0, struct dyesub_backend *backend) libusb_exit(ctx); } -int main (int argc, char **argv) +int main (int argc, char **argv) { struct libusb_context *ctx = NULL; struct libusb_device **list = NULL; struct libusb_device_handle *dev; - struct libusb_config_descriptor *config; + struct libusb_config_descriptor *config = NULL; struct dyesub_backend *backend = NULL; void * backend_ctx = NULL; @@ -758,7 +759,7 @@ int main (int argc, char **argv) DEBUG("Multi-Call Dye-sublimation CUPS Backend version %s\n", BACKEND_VERSION); - DEBUG("Copyright 2007-2015 Solomon Peachy\n"); + DEBUG("Copyright 2007-2016 Solomon Peachy\n"); DEBUG("This free software comes with ABSOLUTELY NO WARRANTY! \n"); DEBUG("Licensed under the GNU GPL. Run with '-G' for more details.\n"); DEBUG("\n"); @@ -831,7 +832,7 @@ int main (int argc, char **argv) /* Always enable fast return in CUPS mode */ fast_return++; } else { - /* Standalone mode */ + /* Standalone mode */ /* Try to guess backend from executable name */ if (!backend) { @@ -842,7 +843,7 @@ int main (int argc, char **argv) ptr = argv[0]; backend = find_backend(ptr); } - + srand(getpid()); jobid = rand(); } @@ -925,8 +926,13 @@ int main (int argc, char **argv) else endp_down = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; } + if (endp_up && endp_down) + break; } + if (config) + libusb_free_config_descriptor(config); + /* Initialize backend */ DEBUG("Initializing '%s' backend (version %s)\n", backend->name, backend->version); @@ -994,6 +1000,9 @@ newpage: if (ret) goto done_claimed; + /* Log the completed page */ + PAGE("%d %d\n", current_page, copies); + /* Since we have no way of telling if there's more data remaining to be read (without actually trying to read it), always assume multiple print jobs. */ @@ -1002,8 +1011,8 @@ newpage: done_multiple: close(data_fd); - /* Done printing */ - INFO("All printing done (%d pages * %d copies)\n", current_page, copies); + /* Done printing, log the total number of pages */ + PAGE("total %d\n", current_page * copies); ret = CUPS_BACKEND_OK; done_claimed: diff --git a/src/cups/backend_common.h b/src/cups/backend_common.h index a220f2c..d088aaa 100644 --- a/src/cups/backend_common.h +++ b/src/cups/backend_common.h @@ -1,7 +1,7 @@ /* * CUPS Backend common code * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org> * * The latest version of this program can be found at: * @@ -99,23 +99,26 @@ enum { P_KODAK_6850, P_KODAK_1400_805, P_KODAK_605, + P_KODAK_305, P_SHINKO_S2145, P_SHINKO_S1245, P_SHINKO_S6245, - P_SHINKO_S6145, - P_SHINKO_S6145D, + P_SHINKO_S6145, + P_SHINKO_S6145D, P_SONY_UPDR150, P_SONY_UPCR10, P_MITSU_D70X, - P_MITSU_K60, + P_MITSU_D80, + P_MITSU_K60, P_MITSU_9550, - P_MITSU_9550S, + P_MITSU_9550S, P_DNP_DS40, P_DNP_DS80, P_DNP_DS80D, P_CITIZEN_CW01, P_DNP_DSRX1, P_DNP_DS620, + P_FUJI_ASK300, P_END, }; @@ -181,7 +184,7 @@ extern struct dyesub_backend BACKEND; #define CUPS_BACKEND_RETRY_CURRENT 7 /* Retry immediately */ /* Argument processing */ -#define GETOPT_LIST_GLOBAL "d:DfGhP:S:T:V:" +#define GETOPT_LIST_GLOBAL "d:DfGh" #define GETOPT_PROCESS_GLOBAL \ case 'd': \ copies = atoi(optarg); \ @@ -197,18 +200,6 @@ extern struct dyesub_backend BACKEND; exit(0); \ case 'h': \ print_help(argv[0], &BACKEND); \ - exit(0); \ - case 'P': \ - extra_pid = strtol(optarg, NULL, 16); \ - break; \ - case 'S': \ - use_serno = optarg; \ - break; \ - case 'T': \ - extra_type = atoi(optarg); \ - break; \ - case 'V': \ - extra_pid = strtol(optarg, NULL, 16); \ - break; + exit(0); #endif /* __BACKEND_COMMON_H */ diff --git a/src/cups/dnpds40_print.c b/src/cups/backend_dnpds40.c index fdec638..4a08d36 100644 --- a/src/cups/dnpds40_print.c +++ b/src/cups/backend_dnpds40.c @@ -1,12 +1,13 @@ /* * DNP DS40/DS80 Photo Printer CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org> * * Development of this backend was sponsored by: * * Marco Di Antonio and [ ilgruppodigitale.com ] * LiveLink Technology [ www.livelinktechnology.net ] + * A generous benefactor who wishes to remain anonymous * * The latest version of this program can be found at: * @@ -30,9 +31,12 @@ * */ -//#define MATTE_STATE //#define DNP_ONLY -#define MATTE_GLOSSY_2BUF + +/* Enables caching of last print type to speed up + job pipelining. Without this we always have to + assume the worst */ +//#define STATE_DIR "/tmp" #include <stdio.h> #include <stdlib.h> @@ -52,15 +56,13 @@ #define USB_PID_DNP_DS40 0x0003 // Also Citizen CX #define USB_PID_DNP_DS80 0x0004 // Also Citizen CX-W, and Mitsubishi CP-3800DW #define USB_PID_DNP_DSRX1 0x0005 // Also Citizen CY +#define USB_PID_CITIZEN_CW02 0x0006 +#define USB_PID_DNP_DS80D 0x0007 +#define USB_PID_DNP_DS620_OLD 0x0008 #define USB_VID_DNP 0x1452 #define USB_PID_DNP_DS620 0x8b01 -//#define USB_PID_DNP_DS80D XXXX - -//#define USB_PID_CITIZEN_CW-02 XXXXX -//#define USB_PID_CITIZEN_OP900II XXXXX - /* Private data stucture */ struct dnpds40_ctx { struct libusb_device_handle *dev; @@ -73,32 +75,42 @@ struct dnpds40_ctx { char *version; int buf_needed; - int last_matte; int ver_major; int ver_minor; - int media; + uint32_t media; + uint32_t duplex_media; + uint16_t media_count_new; uint32_t multicut; + + uint32_t last_multicut; + int last_matte; + + int fullcut; int matte; int cutter; int can_rewind; - + int mediaoffset; int manual_copies; + int correct_count; + int supports_6x9; int supports_2x6; int supports_3x5x2; int supports_matte; + int supports_luster; int supports_fullcut; int supports_rewind; int supports_standby; int supports_6x4_5; int supports_mqty_default; int supports_iserial; - - uint8_t *qty_offset; - uint8_t *buffctrl_offset; - uint8_t *multicut_offset; + int supports_6x6; + int supports_5x5; + int supports_counterp; + int supports_adv_fullcut; + int supports_mediaoffset; uint8_t *databuf; int datalen; @@ -116,6 +128,50 @@ struct dnpds40_cmd { /* All unused elements are set to 0x20 (ie ascii space) */ }; +#define MULTICUT_5x3_5 1 +#define MULTICUT_6x4 2 +#define MULTICUT_5x7 3 +#define MULTICUT_6x8 4 +#define MULTICUT_6x9 5 +#define MULTICUT_8x10 6 +#define MULTICUT_8x12 7 +#define MULTICUT_8x4 8 +#define MULTICUT_8x5 9 +#define MULTICUT_8x6 10 +#define MULTICUT_8x8 11 +#define MULTICUT_6x4X2 12 +#define MULTICUT_8x4X2 13 +#define MULTICUT_8x5X2 14 +#define MULTICUT_8x6X2 15 +#define MULTICUT_8x5_8x4 16 +#define MULTICUT_8x6_8x4 17 +#define MULTICUT_8x6_8x5 18 +#define MULTICUT_8x8_8x4 19 +#define MULTICUT_8x4X3 20 +#define MULTICUT_8xA4LEN 21 +#define MULTICUT_5x3_5X2 22 +#define MULTICUT_6x6 27 +#define MULTICUT_5x5 29 +#define MULTICUT_6x4_5 30 +#define MULTICUT_6x4_5X2 31 + +#define MULTICUT_S_SIMPLEX 100 +#define MULTICUT_S_FRONT 200 +#define MULTICUT_S_BACK 300 + +#define MULTICUT_S_8x10 6 +#define MULTICUT_S_8x12 7 +#define MULTICUT_S_8x4 8 +#define MULTICUT_S_8x5 9 +#define MULTICUT_S_8x6 10 +#define MULTICUT_S_8x8 11 +#define MULTICUT_S_8x4X2 13 +#define MULTICUT_S_8x5X2 14 +#define MULTICUT_S_8x6X2 15 +#define MULTICUT_S_8x10_5 25 +#define MULTICUT_S_8x10_75 26 +#define MULTICUT_S_8x4X3 28 // different than roll type. + #define min(__x, __y) ((__x) < (__y)) ? __x : __y static void dnpds40_build_cmd(struct dnpds40_cmd *cmd, char *arg1, char *arg2, uint32_t arg3_len) @@ -150,9 +206,24 @@ static void dnpds40_cleanup_string(char *start, int len) } } +static char *dnpds40_printer_type(int type) +{ + switch(type) { + case P_DNP_DS40: return "DS40"; + case P_DNP_DS80: return "DS80"; + case P_DNP_DS80D: return "DS80DX"; + case P_DNP_DSRX1: return "DSRX1"; + case P_DNP_DS620: return "DS620"; + default: break; + } + return "Unknown"; +} + static char *dnpds40_media_types(int media) { switch (media) { + case 100: return "UNKNOWN100"; // seen in driver dumps + case 110: return "UNKNOWN110"; // seen in driver dumps case 200: return "5x3.5 (L)"; case 210: return "5x7 (2L)"; case 300: return "6x4 (PC)"; @@ -167,8 +238,95 @@ static char *dnpds40_media_types(int media) return "Unknown type"; } +static char *dnpds80_duplex_media_types(int media) +{ + switch (media) { + case 100: return "8x10.75"; + case 200: return "8x12"; + default: + break; + } + + return "Unknown type"; +} + +static char *dnpds80_duplex_statuses(int status) +{ + switch (status) { + case 5000: return "No Error"; + + case 5500: return "Duplex Unit Not Connected"; + + case 5017: return "Paper Jam: Supply Sensor On"; + case 5018: return "Paper Jam: Supply Sensor Off"; + case 5019: return "Paper Jam: Slot Sensor On"; + case 5020: return "Paper Jam: Slot Sensor Off"; + case 5021: return "Paper Jam: Pass Sensor On"; + case 5022: return "Paper Jam: Pass Sensor Off"; + case 5023: return "Paper Jam: Shell Sensor 1 On"; + case 5024: return "Paper Jam: Shell Sensor 1 Off"; + case 5025: return "Paper Jam: Shell Sensor 2 On"; + case 5026: return "Paper Jam: Shell Sensor 2 Off"; + case 5027: return "Paper Jam: Eject Sensor On"; + case 5028: return "Paper Jam: Eject Sensor Off"; + case 5029: return "Paper Jam: Slot FG Sensor"; + case 5030: return "Paper Jam: Shell FG Sensor"; + + case 5033: return "Paper Supply Sensor Off"; + case 5034: return "Printer Feed Slot Sensor Off"; + case 5035: return "Pinch Pass Sensor Off"; + case 5036: return "Shell Pass Sensor 1 Off"; + case 5037: return "Shell Pass Sensor 2 Off"; + case 5038: return "Eject Sensor Off"; + + case 5049: return "Capstan Drive Control Error"; + case 5065: return "Shell Roller Error"; + + case 5081: return "Pinch Open Error"; + case 5082: return "Pinch Close Error"; + case 5083: return "Pinch Init Error"; + case 5084: return "Pinch Position Error"; + + case 5097: return "Pass Guide Supply Error"; + case 5098: return "Pass Guide Shell Error"; + case 5099: return "Pass Guide Eject Error"; + case 5100: return "Pass Guide Init Error"; + case 5101: return "Pass Guide Position Error"; + + case 5113: return "Side Guide Home Error"; + case 5114: return "Side Guide Position Error"; + case 5115: return "Side Guide Init Error"; + + case 5129: return "Act Guide Home Error"; + + case 5145: return "Shell Rotate Home Error"; + case 5146: return "Shell Rotate Rev Error"; + + case 5161: return "Paper Feed Lever Down Error"; + case 5162: return "Paper Feed Lever Lock Error"; + case 5163: return "Paper Feed Lever Up Error"; + + case 5177: return "Cutter Home Error"; + case 5178: return "Cutter Away Error"; + case 5179: return "Cutter Init Error"; + case 5180: return "Cutter Position Error"; + + case 5193: return "Paper Tray Removed"; + case 5209: return "Cover Opened"; + case 5241: return "System Error"; + + default: + break; + } + + return "Unkown Duplexer Error"; +} + static char *dnpds40_statuses(int status) { + if (status >= 5000 && status <= 5999) + return dnpds80_duplex_statuses(status); + switch (status) { case 0: return "Idle"; case 1: return "Printing"; @@ -308,7 +466,6 @@ static void *dnpds40_init(void) memset(ctx, 0, sizeof(struct dnpds40_ctx)); ctx->type = P_ANY; - ctx->last_matte = -1; return ctx; } @@ -391,6 +548,33 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev, } } + if (ctx->type == P_DNP_DS80D) { + struct dnpds40_cmd cmd; + uint8_t *resp; + int len = 0; + + /* Query Duplex Media Info */ + dnpds40_build_cmd(&cmd, "INFO", "CUT_PAPER", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (resp) { + char tmp[5]; + + dnpds40_cleanup_string((char*)resp, len); + + memcpy(tmp, resp + 4, 4); + tmp[4] = 0; + + ctx->duplex_media = atoi(tmp); + + /* Subtract out the paper status */ + if (ctx->duplex_media & 3) + ctx->duplex_media -= (ctx->duplex_media & 3); + + free(resp); + } + } + #ifdef DNP_ONLY /* Only allow DNP printers to work. Rebadged versions should not. */ @@ -408,42 +592,161 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev, switch (ctx->type) { case P_DNP_DS40: ctx->supports_6x9 = 1; + if (FW_VER_CHECK(1,04)) + ctx->supports_counterp = 1; if (FW_VER_CHECK(1,30)) ctx->supports_matte = 1; if (FW_VER_CHECK(1,40)) ctx->supports_2x6 = 1; - if (FW_VER_CHECK(1,50)) - ctx->supports_3x5x2 = 1; - if (FW_VER_CHECK(1,51)) - ctx->supports_fullcut = 1; break; case P_DNP_DS80: + case P_DNP_DS80D: + 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->supports_counterp = 1; ctx->supports_matte = 1; - ctx->supports_mqty_default = 1; // 1.10 does. Maybe older too? if (FW_VER_CHECK(1,10)) - ctx->supports_2x6 = 1; + ctx->supports_2x6 = ctx->supports_mqty_default = 1; + if (FW_VER_CHECK(1,20)) + ctx->supports_3x5x2 = 1; + if (FW_VER_CHECK(2,00)) { /* AKA RX1HS */ + ctx->supports_mediaoffset = 1; + ctx->supports_iserial = 1; + } break; case P_DNP_DS620: + ctx->correct_count = 1; + ctx->supports_counterp = 1; ctx->supports_matte = 1; ctx->supports_2x6 = 1; ctx->supports_fullcut = 1; ctx->supports_mqty_default = 1; - ctx->supports_rewind = 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_6x6 = 1; + ctx->supports_5x5 = 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; + if (FW_VER_CHECK(1,30)) + ctx->supports_luster = 1; break; default: ERROR("Unknown vid/pid %04x/%04x (%d)\n", desc.idVendor, desc.idProduct, ctx->type); return; } + + ctx->last_matte = -1; +#ifdef STATE_DIR + /* Check our current job's lamination vs previous job. */ + { + /* Load last matte status from file */ + char buf[64]; + FILE *f; + snprintf(buf, sizeof(buf), STATE_DIR "/%s-last", ctx->serno); + f = fopen(buf, "r"); + if (f) { + fscanf(f, "%d", &ctx->last_matte); + fclose(f); + } + } +#endif + + if (ctx->supports_mediaoffset) { + /* Get Media Offset */ + struct dnpds40_cmd cmd; + uint8_t *resp; + int len = 0; + + dnpds40_build_cmd(&cmd, "INFO", "MEDIA_OFFSET", 0); + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (resp) { + ctx->mediaoffset = atoi((char*)resp+4); + free(resp); + } + } else if (!ctx->correct_count) { + ctx->mediaoffset = 50; + } + + if (ctx->supports_mqty_default) { + struct dnpds40_cmd cmd; + uint8_t *resp; + int len = 0; + + dnpds40_build_cmd(&cmd, "INFO", "MQTY_DEFAULT", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (resp) { + dnpds40_cleanup_string((char*)resp, len); + ctx->media_count_new = atoi((char*)resp+4); + free(resp); + ctx->media_count_new -= ctx->mediaoffset; + } + } else { + /* Look it up for legacy models & FW */ + switch (ctx->type) { + case P_DNP_DS40: + switch (ctx->media) { + case 200: // L + ctx->media_count_new = 460; + break; + case 210: // 2L + ctx->media_count_new = 230; + break; + case 300: // PC + ctx->media_count_new = 400; + break; + case 310: // A5 + ctx->media_count_new = 200; + break; + case 400: // A5W + ctx->media_count_new = 180; + break; + default: + ctx->media_count_new = 999; // non-zero + } + break; + case P_DNP_DSRX1: + switch (ctx->media) { + case 300: // PC + ctx->media_count_new = 700; + break; + case 310: // A5 + ctx->media_count_new = 350; + break; + default: + ctx->media_count_new = 999; // non-zero + } + break; + case P_DNP_DS80: + case P_DNP_DS80D: + switch (ctx->media) { + case 500: // 8x10 + ctx->media_count_new = 130; + break; + case 510: // 8x12 + ctx->media_count_new = 110; + break; + default: + ctx->media_count_new = 999; // non-zero + } + break; + default: + ctx->media_count_new = 999; // non-zero + break; + } + } } static void dnpds40_teardown(void *vctx) { @@ -452,6 +755,19 @@ static void dnpds40_teardown(void *vctx) { if (!ctx) return; + if (ctx->type == P_DNP_DS80D) { + struct dnpds40_cmd cmd; + + /* Check to see if last print was the front side + of a duplex job, and if so, cancel things so we're done */ + if (ctx->last_multicut >= 200 && + ctx->last_multicut < 300) { + dnpds40_build_cmd(&cmd, "CNTRL", "DUPLEX_CANCEL", 0); + if ((dnpds40_do_cmd(ctx, &cmd, NULL, 0)) != 0) + return; + } + } + if (ctx->databuf) free(ctx->databuf); if (ctx->serno) @@ -468,7 +784,7 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { int run = 1; char buf[9] = { 0 }; - uint32_t matte, dpi, cutter; + uint32_t dpi; if (!ctx) return CUPS_BACKEND_FAILED; @@ -495,12 +811,13 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { } /* Clear everything out */ - matte = 0; dpi = 0; - cutter = 0; + ctx->matte = 0; + ctx->cutter = 0; ctx->manual_copies = 0; ctx->multicut = 0; - ctx->buffctrl_offset = ctx->qty_offset = ctx->multicut_offset = 0; + ctx->fullcut = 0; + ctx->can_rewind = 0; while (run) { int remain, i, j; @@ -542,43 +859,47 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { /* Check for some offsets */ if(!memcmp("CNTRL QTY", ctx->databuf + ctx->datalen+2, 9)) { - ctx->qty_offset = ctx->databuf + ctx->datalen + 32; + /* Ignore this. We will insert our own later on */ + continue; } if(!memcmp("CNTRL CUTTER", ctx->databuf + ctx->datalen+2, 12)) { memcpy(buf, ctx->databuf + ctx->datalen + 32, 8); - cutter = atoi(buf); + ctx->cutter = atoi(buf); + /* We'll insert it ourselves later */ + continue; } if(!memcmp("CNTRL BUFFCNTRL", ctx->databuf + ctx->datalen+2, 15)) { - /* If the printer doesn't support matte, it doesn't - support buffcntrl. strip it from the stream */ - if (ctx->supports_matte) { - ctx->buffctrl_offset = ctx->databuf + ctx->datalen + 32; - } else { - WARNING("Printer FW does not support BUFFCNTRL, please update\n"); - continue; - } + /* Ignore this. We will insert our own later on + if the printer and job support it. */ + continue; } if(!memcmp("CNTRL OVERCOAT", ctx->databuf + ctx->datalen+2, 14)) { - /* If the printer doesn't support matte, it doesn't - support buffcntrl. strip it from the stream */ if (ctx->supports_matte) { memcpy(buf, ctx->databuf + ctx->datalen + 32, 8); - matte = atoi(buf); + ctx->matte = atoi(buf); } else { - WARNING("Printer FW does not support matte prints, please update\n"); - continue; + WARNING("Printer FW does not support matte prints, using glossy mode\n"); } + /* We'll insert our own later, if appropriate */ + continue; } if(!memcmp("IMAGE MULTICUT", ctx->databuf + ctx->datalen+2, 14)) { - ctx->multicut_offset = ctx->databuf + ctx->datalen + 32; memcpy(buf, ctx->databuf + ctx->datalen + 32, 8); ctx->multicut = atoi(buf); + /* Backend automatically handles rewind support, so + ignore application requests to use it. */ + if (ctx->multicut > 400) + ctx->multicut -= 400; + + /* We'll insert this ourselves later. */ + continue; } if(!memcmp("CNTRL FULL_CUTTER_SET", ctx->databuf + ctx->datalen+2, 21)) { if (!ctx->supports_fullcut) { - WARNING("Printer FW does not support cutter control, please update!\n"); + WARNING("Printer FW does not support full cutter control!\n"); continue; } + ctx->fullcut = 1; } if(!memcmp("IMAGE YPLANE", ctx->databuf + ctx->datalen + 2, 12)) { uint32_t y_ppm; /* Pixels Per Meter */ @@ -595,21 +916,22 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { dpi = 600; break; default: - ERROR("Unrecognized printjob resolution (%d ppm)\n", y_ppm); + ERROR("Unrecognized printjob resolution (%u ppm)\n", y_ppm); return CUPS_BACKEND_CANCEL; } /* 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) { + if (ctx->type == P_DNP_DS80 || + ctx->type == P_DNP_DS80D) { if (y_ppm != 2560) { - ERROR("Incorrect horizontal resolution (%d), aborting!\n", y_ppm); + ERROR("Incorrect horizontal resolution (%u), aborting!\n", y_ppm); return CUPS_BACKEND_CANCEL; } } else { if (y_ppm != 1920) { - ERROR("Incorrect horizontal resolution (%d), aborting!\n", y_ppm); + ERROR("Incorrect horizontal resolution (%u), aborting!\n", y_ppm); return CUPS_BACKEND_CANCEL; } } @@ -623,160 +945,230 @@ static int dnpds40_read_parse(void *vctx, int data_fd) { ctx->datalen += sizeof(struct dnpds40_cmd) + j; } + /* If we have no data.. don't bother */ if (!ctx->datalen) return CUPS_BACKEND_CANCEL; - /* Figure out the number of buffers we need. Most only need one. */ - if (ctx->multicut) { - ctx->buf_needed = 1; - - if (dpi == 600) { - if (ctx->type == P_DNP_DS620) { - if (ctx->multicut == 5 || // 6x9 - ctx->multicut == 31) // 6x4.5*2 - ctx->buf_needed = 2; - } else if (ctx->type == P_DNP_DS80) { /* DS80/CX-W */ - if (matte && (ctx->multicut == 21 || // A4 length - ctx->multicut == 20 || // 8x4*3 - ctx->multicut == 19 || // 8x8+8x4 - ctx->multicut == 15 || // 8x6*2 - ctx->multicut == 7)) // 8x12 - ctx->buf_needed = 2; - } else { /* DS40/CX/RX1/CY/etc */ - if (ctx->multicut == 4 || // 6x8 - ctx->multicut == 5 || // 6x9 - ctx->multicut == 12) // 6x4*2 - ctx->buf_needed = 2; - else if (matte && ctx->multicut == 3) // 5x7 - ctx->buf_needed = 2; - } - } - } else { - WARNING("Missing or illegal MULTICUT command, can't validate print job against loaded media!\n"); + /* Sanity check matte mode */ + 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; + } + + /* Make sure MULTICUT is sane, most validation needs this */ + if (!ctx->multicut) { + WARNING("Missing or illegal MULTICUT command!\n"); if (dpi == 300) ctx->buf_needed = 1; else ctx->buf_needed = 2; + + goto skip_checks; } - ctx->matte = (int)matte; - ctx->cutter = cutter; - ctx->can_rewind = 0; + /* Only DS80D supports Cut Paper types */ + if (ctx->multicut > 100 && + ctx->type != P_DNP_DS80D) { + ERROR("Only DS80D supports cut-paper sizes!\n"); + return CUPS_BACKEND_CANCEL; + } - DEBUG("dpi %u matte %u mcut %u cutter %d, bufs %d\n", - dpi, matte, ctx->multicut, cutter, ctx->buf_needed); + /* Figure out the number of buffers we need. */ + ctx->buf_needed = 1; + if (dpi == 600) { + if (ctx->type == 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 */ + 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 */ + if (ctx->matte) { + int mcut = ctx->multicut; + + if (mcut > MULTICUT_S_BACK) + mcut -= MULTICUT_S_BACK; + else if (mcut > MULTICUT_S_FRONT) + mcut -= MULTICUT_S_FRONT; + + if (mcut == MULTICUT_8xA4LEN || + mcut == MULTICUT_8x4X3 || + mcut == MULTICUT_8x8_8x4 || + mcut == MULTICUT_8x6X2 || + mcut == MULTICUT_8x12) + ctx->buf_needed = 2; - /* Sanity-check printjob type vs loaded media */ - if (ctx->multicut) { + if (mcut == MULTICUT_S_8x12 || + mcut == MULTICUT_S_8x6X2 || + 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; + } + } + + /* Sanity-check type vs loaded media */ + if (ctx->multicut < 100) { switch(ctx->media) { case 200: //"5x3.5 (L)" - if (ctx->multicut != 1) { - ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut); + if (ctx->multicut != MULTICUT_5x3_5) { + ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); return CUPS_BACKEND_CANCEL; } break; case 210: //"5x7 (2L)" - if (ctx->multicut != 1 && ctx->multicut != 3 && - ctx->multicut != 22 && ctx->multicut != 29) { - ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut); + if (ctx->multicut != MULTICUT_5x3_5 && ctx->multicut != MULTICUT_5x7 && + ctx->multicut != MULTICUT_5x3_5X2 && ctx->multicut != MULTICUT_5x5) { + ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); return CUPS_BACKEND_CANCEL; } /* Only 3.5x5 on 7x5 media can be rewound */ - if (ctx->multicut == 1) + if (ctx->multicut == MULTICUT_5x3_5) ctx->can_rewind = 1; break; case 300: //"6x4 (PC)" - if (ctx->multicut != 2) { - ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut); + if (ctx->multicut != MULTICUT_6x4) { + ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); return CUPS_BACKEND_CANCEL; } break; case 310: //"6x8 (A5)" - if (ctx->multicut != 2 && ctx->multicut != 4 && - ctx->multicut != 12 && - ctx->multicut != 27 && ctx->multicut != 30) { - ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut); + if (ctx->multicut != MULTICUT_6x4 && ctx->multicut != MULTICUT_6x8 && + ctx->multicut != MULTICUT_6x4X2 && + ctx->multicut != MULTICUT_6x6 && ctx->multicut != 30) { + ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); return CUPS_BACKEND_CANCEL; } /* Only 6x4 on 6x8 media can be rewound */ - if (ctx->multicut == 2) + if (ctx->multicut == MULTICUT_6x4) ctx->can_rewind = 1; break; case 400: //"6x9 (A5W)" - if (ctx->multicut != 2 && ctx->multicut != 4 && - ctx->multicut != 5 && ctx->multicut != 12 && - ctx->multicut != 27 && - ctx->multicut != 30 && ctx->multicut != 31) { - ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut); + if (ctx->multicut != MULTICUT_6x4 && ctx->multicut != MULTICUT_6x8 && + ctx->multicut != MULTICUT_6x9 && ctx->multicut != MULTICUT_6x4X2 && + ctx->multicut != MULTICUT_6x6 && + ctx->multicut != MULTICUT_6x4_5 && ctx->multicut != MULTICUT_6x4_5X2) { + ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); return CUPS_BACKEND_CANCEL; } /* Only 6x4 or 6x4.5 on 6x9 media can be rewound */ - if (ctx->multicut == 2 || ctx->multicut == 30) + if (ctx->multicut == MULTICUT_6x4 || ctx->multicut == MULTICUT_6x4_5) ctx->can_rewind = 1; break; case 500: //"8x10" - if (ctx->multicut < 6 || ctx->multicut == 7 || - ctx->multicut == 15 || ctx->multicut >= 18 ) { - ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut); + 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; } break; case 510: //"8x12" - if (ctx->multicut < 6 || ctx->multicut > 21) { - ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut); + if (ctx->multicut < MULTICUT_8x10 || ctx->multicut > MULTICUT_8xA4LEN) { + ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); + return CUPS_BACKEND_CANCEL; + } + break; + default: + ERROR("Unknown media (%u vs %u)!\n", ctx->media, ctx->multicut); + return CUPS_BACKEND_CANCEL; + } + } else if (ctx->multicut < 400) { + int mcut = ctx->multicut; + + switch(ctx->duplex_media) { + case 100: //"8x10.75" + if (mcut > MULTICUT_S_BACK) + mcut -= MULTICUT_S_BACK; + else if (mcut > MULTICUT_S_FRONT) + mcut -= MULTICUT_S_FRONT; + + if (mcut == MULTICUT_S_8x12 || + mcut == MULTICUT_S_8x6X2 || + mcut == MULTICUT_S_8x4X3) { + ERROR("Incorrect media for job loaded (%u vs %u)\n", ctx->media, ctx->multicut); return CUPS_BACKEND_CANCEL; } break; + case 200: //"8x12" + /* Everything is legal */ + break; default: - ERROR("Unknown media (%d vs %d)!\n", ctx->media, ctx->multicut); + ERROR("Unknown duplexer media (%u vs %u)!\n", ctx->duplex_media, ctx->multicut); return CUPS_BACKEND_CANCEL; } + } else { + ERROR("Multicut value out of range! (%u)\n", ctx->multicut); + return CUPS_BACKEND_CANCEL; + } + + /* Additional santity checks, make sure printer support exists */ + if (!ctx->supports_6x6 && ctx->multicut == MULTICUT_6x6) { + ERROR("Printer does not support 6x6 prints, aborting!\n"); + return CUPS_BACKEND_CANCEL; } - /* Additional santity checks */ - if ((ctx->multicut == 27 || ctx->multicut == 29) && - ctx->type != P_DNP_DS620) { - ERROR("Printer does not support 6x6 or 5x5 prints, aborting!\n"); + if (!ctx->supports_5x5 && ctx->multicut == MULTICUT_5x5) { + ERROR("Printer does not support 5x5 prints, aborting!\n"); return CUPS_BACKEND_CANCEL; } - if ((ctx->multicut == 30 || ctx->multicut == 31) && + if ((ctx->multicut == MULTICUT_6x4_5 || ctx->multicut == MULTICUT_6x4_5X2) && !ctx->supports_6x4_5) { ERROR("Printer does not support 6x4.5 prints, aborting!\n"); return CUPS_BACKEND_CANCEL; } - if (ctx->multicut == 5 && !ctx->supports_6x9) { + if (ctx->multicut == MULTICUT_6x9 && !ctx->supports_6x9) { ERROR("Printer does not support 6x9 prints, aborting!\n"); return CUPS_BACKEND_CANCEL; } - if (ctx->multicut == 22 && !ctx->supports_3x5x2) { + if (ctx->multicut == MULTICUT_5x3_5X2 && !ctx->supports_3x5x2) { ERROR("Printer does not support 3.5x5*2 prints, aborting!\n"); return CUPS_BACKEND_CANCEL; } + if (ctx->fullcut && !ctx->supports_adv_fullcut && + ctx->multicut != MULTICUT_6x8) { + ERROR("Printer does not support full control on sizes other than 6x8, aborting!\n"); + return CUPS_BACKEND_CANCEL; + } + if (ctx->cutter == 120) { - if (ctx->multicut == 2 || ctx->multicut == 4) { + if (ctx->multicut == MULTICUT_6x4 || ctx->multicut == MULTICUT_6x8) { if (!ctx->supports_2x6) { ERROR("Printer does not support 2x6 prints, aborting!\n"); return CUPS_BACKEND_CANCEL; } } else { - ERROR("Printer only supports 2-inch cuts on 4x6 or 8x6 jobs!"); + ERROR("Printer only supports legacy 2-inch cuts on 4x6 or 8x6 jobs!"); return CUPS_BACKEND_CANCEL; } /* Work around firmware bug on DS40 where if we run out of media, we can't resume the job without losing the - cutter setting. XXX add version test? */ + cutter setting. */ + // XXX add version test? what about other printers? ctx->manual_copies = 1; } - if (ctx->matte && !ctx->supports_matte) { - ERROR("Printer FW does not support matte operation, please update!\n"); - return CUPS_BACKEND_CANCEL; - } +skip_checks: + DEBUG("dpi %u matte %d mcut %u cutter %d, bufs %d\n", + dpi, ctx->matte, ctx->multicut, ctx->cutter, ctx->buf_needed); return CUPS_BACKEND_OK; } @@ -785,91 +1177,40 @@ static int dnpds40_main_loop(void *vctx, int copies) { struct dnpds40_ctx *ctx = vctx; int ret; struct dnpds40_cmd cmd; - uint8_t *resp = NULL; + uint8_t *resp; int len = 0; uint8_t *ptr; char buf[9]; int status; int buf_needed; + int count = 0; if (!ctx) return CUPS_BACKEND_FAILED; - /* Update quantity offset with count */ - // XXX this breaks if ctx->manual_copies is set, but the job - // has a CNTRL QTY != 1 - if (!ctx->manual_copies && copies > 1) { - snprintf(buf, sizeof(buf), "%07d\r", copies); - if (ctx->qty_offset) { - memcpy(ctx->qty_offset, buf, 8); - } else { - dnpds40_build_cmd(&cmd, "CNTRL", "QTY", 8); - if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8))) - return CUPS_BACKEND_FAILED; - } - - copies = 1; - } - - /* Enable job resumption on correctable errors */ - if (ctx->supports_matte) { - snprintf(buf, sizeof(buf), "%08d", 1); - if (ctx->buffctrl_offset) { - memcpy(ctx->buffctrl_offset, buf, 8); - } else { - dnpds40_build_cmd(&cmd, "CNTRL", "BUFFCNTRL", 8); - if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8))) - return CUPS_BACKEND_FAILED; - } - } - -#ifdef MATTE_STATE - /* Check our current job's lamination vs previous job. */ - { - /* Load last matte status from file */ - char buf[64]; - FILE *f; - snprintf(buf, sizeof(buf), "/tmp/%s-last", ctx->serno); - f = fopen(buf, "r"); - if (f) { - fscanf(f, "%d", &ctx->last_matte); - fclose(f); - } - } -#endif - buf_needed = ctx->buf_needed; -#ifdef MATTE_GLOSSY_2BUF - if (ctx->matte != ctx->last_matte) - buf_needed = 2; /* Switching needs both buffers */ -#endif + /* If we switch major overcoat modes, we need both buffers */ + if (!!ctx->matte != ctx->last_matte) + buf_needed = 2; - ctx->last_matte = ctx->matte; -#ifdef MATTE_STATE - { - /* Store last matte status into file */ - char buf[64]; - FILE *f; - snprintf(buf, sizeof(buf), "/tmp/%s-last", ctx->serno); - f = fopen(buf, "w"); - if (f) { - fprintf(f, "%08d", ctx->last_matte); - fclose(f); - } + if (ctx->media_count_new) { + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='%s'\n", dnpds40_media_types(ctx->media)); + ATTR("marker-types=ribbonWax\n"); } -#endif - top: /* Query status */ dnpds40_build_cmd(&cmd, "STATUS", "", 0); - if (resp) free(resp); resp = dnpds40_resp_cmd(ctx, &cmd, &len); if (!resp) return CUPS_BACKEND_FAILED; dnpds40_cleanup_string((char*)resp, len); status = atoi((char*)resp); + free(resp); /* Figure out what's going on */ switch(status) { @@ -878,7 +1219,6 @@ top: { int bufs; - if (resp) free(resp); /* Query buffer state */ dnpds40_build_cmd(&cmd, "INFO", "FREE_PBUFFER", 0); resp = dnpds40_resp_cmd(ctx, &cmd, &len); @@ -889,6 +1229,7 @@ top: dnpds40_cleanup_string((char*)resp, len); /* Check to see if we have sufficient buffers */ bufs = atoi(((char*)resp)+3); + free(resp); if (bufs < buf_needed) { INFO("Insufficient printer buffers (%d vs %d), retrying...\n", bufs, buf_needed); sleep(1); @@ -925,59 +1266,110 @@ top: return CUPS_BACKEND_HOLD; } - /* Verify we have sufficient media for prints */ { - int i = 0; + /* Figure out remaining native prints */ + dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + + count = atoi((char*)resp+4); + free(resp); + + /* Old-sk00l models report one less than they should */ + if (!ctx->correct_count) + count++; + + count -= ctx->mediaoffset; + + if (ctx->media_count_new) { + ATTR("marker-levels=%d\n", count * 100 / ctx->media_count_new); + ATTR("marker-message=\"%d native prints remaining on '%s' ribbon\"\n", count, dnpds40_media_types(ctx->media)); + } /* See if we can rewind to save media */ if (ctx->can_rewind && ctx->supports_rewind) { - /* Tell the printer we want to rewind, if possible. */ - snprintf(buf, sizeof(buf), "%08d", ctx->multicut + 400); - memcpy(ctx->multicut_offset, buf, 8); + /* Tell printer to use rewind */ + ctx->multicut += 400; /* Get Media remaining */ dnpds40_build_cmd(&cmd, "INFO", "RQTY", 0); - if (resp) free(resp); resp = dnpds40_resp_cmd(ctx, &cmd, &len); if (!resp) return CUPS_BACKEND_FAILED; dnpds40_cleanup_string((char*)resp, len); - i = atoi((char*)resp+4); + count = atoi((char*)resp+4); + free(resp); } - /* If we didn't succeed with RQTY, try MQTY */ - if (i == 0) { - dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0); + /* Verify we have sufficient media for prints */ - if (resp) free(resp); - resp = dnpds40_resp_cmd(ctx, &cmd, &len); - if (!resp) - return CUPS_BACKEND_FAILED; - - dnpds40_cleanup_string((char*)resp, len); - - i = atoi((char*)resp+4); - - /* For some reason all but the DS620 report 50 too high */ - if (ctx->type != P_DNP_DS620 && i > 0) - i -= 50; - } -#if 0 - if (i < 1) { +#if 0 // disabled this to allow error to be reported on the printer panel + if (count < 1) { ERROR("Printer out of media, please correct!\n"); return CUPS_BACKEND_STOP; } #endif - if (i < copies) { - WARNING("Printer does not have sufficient remaining media to complete job..\n"); + + if (count < copies) { + WARNING("Printer does not have sufficient remaining media (%d) to complete job (%d)\n", copies, count); } } - /* Send the stream over as individual data chunks */ - ptr = ctx->databuf; + /* Store our last multicut state */ + ctx->last_multicut = ctx->multicut; + + /* Tell printer how many copies to make */ + snprintf(buf, sizeof(buf), "%07d\r", ctx->manual_copies ? 1 : copies); + dnpds40_build_cmd(&cmd, "CNTRL", "QTY", 8); + if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8))) + return CUPS_BACKEND_FAILED; + + if (!ctx->manual_copies) + copies = 1; + + /* Enable job resumption on correctable errors */ + if (ctx->supports_matte) { + snprintf(buf, sizeof(buf), "%08d", 1); + /* DS80D does not support BUFFCNTRL when using + cut media; all others support this */ + if (ctx->type != P_DNP_DS80D || + ctx->multicut < 100) { + dnpds40_build_cmd(&cmd, "CNTRL", "BUFFCNTRL", 8); + if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8))) + return CUPS_BACKEND_FAILED; + } + } + + /* Set overcoat parameters */ + if (ctx->supports_matte) { + snprintf(buf, sizeof(buf), "%08d", ctx->matte); + dnpds40_build_cmd(&cmd, "CNTRL", "OVERCOAT", 8); + if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8))) + return CUPS_BACKEND_FAILED; + } + + /* Program in the cutter setting */ + if (ctx->cutter) { + snprintf(buf, sizeof(buf), "%08d", ctx->cutter); + dnpds40_build_cmd(&cmd, "CNTRL", "CUTTER", 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); + if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8))) + return CUPS_BACKEND_FAILED; + /* Finally, send the stream over as individual data chunks */ + ptr = ctx->databuf; while(ptr && ptr < (ctx->databuf + ctx->datalen)) { int i; buf[8] = 0; @@ -990,6 +1382,56 @@ top: ptr += i; } + sleep(1); /* Give things a moment */ + + if (fast_return) { + INFO("Fast return mode enabled.\n"); + } else { + INFO("Waiting for job to complete...\n"); + + while (1) { + /* Query status */ + dnpds40_build_cmd(&cmd, "STATUS", "", 0); + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + dnpds40_cleanup_string((char*)resp, len); + status = atoi((char*)resp); + free(resp); + + /* If we're idle or there's an error..*/ + if (status == 0) + break; + if (status >= 1000) { + ERROR("Printer encountered error: %s\n", dnpds40_statuses(status)); + break; + } + sleep(1); + } + + /* Figure out remaining native prints */ + dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + + count = atoi((char*)resp+4); + free(resp); + + /* Old-sk00l models report one less than they should */ + if (!ctx->correct_count) + count++; + + count -= ctx->mediaoffset; + + if (ctx->media_count_new) { + ATTR("marker-levels=%d\n", count * 100 / ctx->media_count_new); + ATTR("marker-message=\"%d native prints remaining on '%s' ribbon\"\n", count, dnpds40_media_types(ctx->media)); + } + } /* Clean up */ if (terminate) @@ -998,13 +1440,27 @@ top: INFO("Print complete (%d copies remaining)\n", copies - 1); if (copies && --copies) { -#ifdef MATTE_GLOSSY_2BUF /* No need to wait on buffers due to matte switching */ buf_needed = ctx->buf_needed; -#endif goto top; } + /* Finally, account for overcoat mode of last print */ + ctx->last_matte = !!ctx->matte; +#ifdef STATE_DIR + { + /* Store last matte status into file */ + char buf[64]; + FILE *f; + snprintf(buf, sizeof(buf), STATE_DIR "/%s-last", ctx->serno); + f = fopen(buf, "w"); + if (f) { + fprintf(f, "%08d", ctx->last_matte); + fclose(f); + } + } +#endif + return CUPS_BACKEND_OK; } @@ -1081,11 +1537,28 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) uint8_t *resp; int len = 0; + INFO("Model: %s\n", dnpds40_printer_type(ctx->type)); + /* Serial number already queried */ - INFO("Serial Number: '%s'\n", ctx->serno); + INFO("Serial Number: %s\n", ctx->serno); /* Firmware version already queried */ - INFO("Firmware Version: '%s'\n", ctx->version); + INFO("Firmware Version: %s\n", ctx->version); + + /* Figure out Duplexer */ + if (ctx->type == P_DNP_DS80D) { + dnpds40_build_cmd(&cmd, "INFO", "UNIT_FVER", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + + INFO("Duplexer Version: %s\n", resp); + + free(resp); + } /* Get Media Color offset */ dnpds40_build_cmd(&cmd, "INFO", "MCOLOR", 0); @@ -1096,7 +1569,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Media Color Offset: '%02x%02x%02x%02x'\n", *(resp+2), *(resp+3), + INFO("Media Color Offset: Y %u M %u C %u L %u\n", *(resp+2), *(resp+3), *(resp+4), *(resp+5)); free(resp); @@ -1110,7 +1583,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Media Class: '%s'\n", (char*)resp); + INFO("Media Class: %d\n", atoi((char*)resp + 4)); free(resp); @@ -1123,12 +1596,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Media Lot Code: '"); - /* 16-byte data in a 20-byte response */ - for (len = 0 ; len < 16 ; len++) { - DEBUG2("%c", *(resp+len+2)); - } - DEBUG2("'\n"); + INFO("Media Lot Code: %s\n", (char*)resp+2); free(resp); /* Get Media ID Set (?) */ @@ -1140,7 +1608,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Media ID(?): '%s'\n", (char*)resp+4); + INFO("Media ID: %d\n", atoi((char*)resp+4)); free(resp); @@ -1153,7 +1621,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Ribbon ID(?): '%s'\n", (char*)resp+4); + INFO("Ribbon ID: %s\n", (char*)resp); free(resp); @@ -1168,7 +1636,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("300 DPI Color Data Version: '%s' ", (char*)resp); + INFO("300 DPI Color Data: %s ", (char*)resp); free(resp); @@ -1180,7 +1648,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - DEBUG2("Checksum: '%s'\n", (char*)resp); + DEBUG2("(%s)\n", (char*)resp); free(resp); @@ -1193,7 +1661,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("600 DPI Color Data Version: '%s' ", (char*)resp); + INFO("600 DPI Color Data: %s ", (char*)resp); free(resp); @@ -1205,7 +1673,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - DEBUG2("Checksum: '%s'\n", (char*)resp); + DEBUG2("(%s)\n", (char*)resp); free(resp); @@ -1219,7 +1687,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Low Speed Color Data Version: '%s' ", (char*)resp); + INFO("Low Speed Color Data: %s ", (char*)resp); free(resp); @@ -1231,12 +1699,13 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - DEBUG2("Checksum: '%s'\n", (char*)resp); + DEBUG2("(%s)\n", (char*)resp); free(resp); } - if (ctx->type == P_DNP_DS620) { + if (ctx->supports_standby) { + int i; /* Get Standby stuff */ dnpds40_build_cmd(&cmd, "MNT_RD", "STANDBY_TIME", 0); @@ -1245,8 +1714,9 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) return CUPS_BACKEND_FAILED; dnpds40_cleanup_string((char*)resp, len); - - INFO("Standby Transition time: '%s' minutes\n", (char*)resp); + i = atoi((char*)resp); + + INFO("Standby Transition time: %d minutes\n", i); free(resp); @@ -1258,13 +1728,15 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) return CUPS_BACKEND_FAILED; dnpds40_cleanup_string((char*)resp, len); - - INFO("Media End kept across power cycles: '%s'\n", (char*)resp); + i = atoi((char*)resp); + INFO("Media End kept across power cycles: %s\n", + i ? "Yes" : "No"); free(resp); } if (ctx->supports_iserial) { + int i; /* Get USB serial descriptor status */ dnpds40_build_cmd(&cmd, "MNT_RD", "USB_ISERI_SET", 0); @@ -1273,8 +1745,10 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx) return CUPS_BACKEND_FAILED; dnpds40_cleanup_string((char*)resp, len); + i = atoi((char*)resp); - INFO("Report Serial Number in USB descriptor: '%s'\n", (char*)resp); + INFO("Report Serial Number in USB descriptor: %s\n", + i ? "Yes" : "No"); free(resp); } @@ -1287,6 +1761,7 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) struct dnpds40_cmd cmd; uint8_t *resp; int len = 0; + int count; /* Generate command */ dnpds40_build_cmd(&cmd, "STATUS", "", 0); @@ -1298,10 +1773,26 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); len = atoi((char*)resp); - INFO("Printer Status: %d => %s\n", len, dnpds40_statuses(len)); + INFO("Printer Status: %s (%d)\n", dnpds40_statuses(len), len); free(resp); + /* Figure out Duplexer */ + if (ctx->type == P_DNP_DS80D) { + dnpds40_build_cmd(&cmd, "INFO", "UNIT_STATUS", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + len = atoi((char*)resp); + + INFO("Duplexer Status: %s\n", dnpds80_duplex_statuses(len)); + + free(resp); + } + /* Get remaining print quantity */ dnpds40_build_cmd(&cmd, "INFO", "PQTY", 0); @@ -1311,7 +1802,7 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Prints remaining in job: '%s'\n", (char*)resp + 4); + INFO("Prints remaining in job: %d\n", atoi((char*)resp + 4)); free(resp); @@ -1324,29 +1815,19 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Free Buffers: '%s'\n", (char*)resp + 3); + INFO("Free Buffers: %d\n", atoi((char*)resp + 3)); free(resp); /* Report media */ - INFO("Media Type: '%s'\n", dnpds40_media_types(ctx->media)); + INFO("Media Type: %s\n", dnpds40_media_types(ctx->media)); - if (ctx->supports_mqty_default) { - /* Get Media remaining */ - dnpds40_build_cmd(&cmd, "INFO", "MQTY_DEFAULT", 0); - - resp = dnpds40_resp_cmd(ctx, &cmd, &len); - if (!resp) - return CUPS_BACKEND_FAILED; + /* Report Cut Media */ + if (ctx->type == P_DNP_DS80D) + INFO("Duplex Media Type: %s\n", dnpds80_duplex_media_types(ctx->media)); - dnpds40_cleanup_string((char*)resp, len); - - len = atoi((char*)resp+4); - - INFO("Prints Available on New Media: '%d'\n", len); - - free(resp); - } + if (ctx->media_count_new) + INFO("Native Prints Available on New Media: %u\n", ctx->media_count_new); /* Get Media remaining */ dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0); @@ -1357,13 +1838,15 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - len = atoi((char*)resp+4); - if (ctx->type != P_DNP_DS620 && len > 0) - len -= 50; + count = atoi((char*)resp+4); + free(resp); - INFO("Prints Remaining on Media: '%d'\n", len); + /* Old-sk00l models report one less than they should */ + if (!ctx->correct_count) + count++; - free(resp); + count -= ctx->mediaoffset; + INFO("Native Prints Remaining on Media: %d\n", count); if (ctx->supports_rewind) { /* Get Media remaining */ @@ -1375,10 +1858,12 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("L/PC Prints Remaining on Media: '%s'\n", (char*)resp + 4); - + count = atoi((char*)resp+4); free(resp); + } else { + // Do nothing, re-use native print count. } + INFO("Half-Size Prints Remaining on Media: %d\n", count); return 0; } @@ -1398,10 +1883,25 @@ static int dnpds40_get_counters(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Lifetime Counter: '%s'\n", (char*)resp+2); + INFO("Lifetime Counter: %d\n", atoi((char*)resp+2)); free(resp); + if (ctx->type == P_DNP_DS620) { + /* Generate command */ + dnpds40_build_cmd(&cmd, "MNT_RD", "COUNTER_HEAD", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + + INFO("Head Counter: %d\n", atoi((char*)resp+2)); + + free(resp); + } + /* Generate command */ dnpds40_build_cmd(&cmd, "MNT_RD", "COUNTER_A", 0); @@ -1411,7 +1911,7 @@ static int dnpds40_get_counters(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("A Counter: '%s'\n", (char*)resp+2); + INFO("A Counter: %d\n", atoi((char*)resp+2)); free(resp); @@ -1424,22 +1924,24 @@ static int dnpds40_get_counters(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("B Counter: '%s'\n", (char*)resp+2); + INFO("B Counter: %d\n", atoi((char*)resp+2)); free(resp); - /* Generate command */ - dnpds40_build_cmd(&cmd, "MNT_RD", "COUNTER_P", 0); + if (ctx->supports_counterp) { + /* Generate command */ + dnpds40_build_cmd(&cmd, "MNT_RD", "COUNTER_P", 0); - resp = dnpds40_resp_cmd(ctx, &cmd, &len); - if (!resp) - return CUPS_BACKEND_FAILED; + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; - dnpds40_cleanup_string((char*)resp, len); + dnpds40_cleanup_string((char*)resp, len); - INFO("P Counter: '%s'\n", (char*)resp+2); + INFO("P Counter: %d\n", atoi((char*)resp+2)); - free(resp); + free(resp); + } if (ctx->supports_matte) { /* Generate command */ @@ -1451,7 +1953,7 @@ static int dnpds40_get_counters(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("M Counter: '%s'\n", (char*)resp+2); + INFO("M Counter: %d\n", atoi((char*)resp+2)); free(resp); @@ -1464,7 +1966,21 @@ static int dnpds40_get_counters(struct dnpds40_ctx *ctx) dnpds40_cleanup_string((char*)resp, len); - INFO("Matte Counter: '%s'\n", (char*)resp+4); + INFO("Matte Counter: %d\n", atoi((char*)resp+4)); + + free(resp); + } + + if (ctx->type == P_DNP_DS80D) { + dnpds40_build_cmd(&cmd, "MNT_RD", "COUNTER_DUPLEX", 0); + + resp = dnpds40_resp_cmd(ctx, &cmd, &len); + if (!resp) + return CUPS_BACKEND_FAILED; + + dnpds40_cleanup_string((char*)resp, len); + + INFO("Duplexer Counter: %d\n", atoi((char*)resp)); free(resp); } @@ -1491,6 +2007,34 @@ static int dnpds40_clear_counter(struct dnpds40_ctx *ctx, char counter) return 0; } +static int dnpds40_cancel_job(struct dnpds40_ctx *ctx) +{ + struct dnpds40_cmd cmd; + int ret; + + /* Generate command */ + dnpds40_build_cmd(&cmd, "CNTRL", "CANCEL", 0); + + if ((ret = dnpds40_do_cmd(ctx, &cmd, NULL, 0))) + return ret; + + return 0; +} + +static int dnpds40_reset_printer(struct dnpds40_ctx *ctx) +{ + struct dnpds40_cmd cmd; + int ret; + + /* Generate command */ + dnpds40_build_cmd(&cmd, "CNTRL", "PRINTER_RESET", 0); + + if ((ret = dnpds40_do_cmd(ctx, &cmd, NULL, 0))) + return ret; + + return 0; +} + static int dnpds620_standby_mode(struct dnpds40_ctx *ctx, int delay) { struct dnpds40_cmd cmd; @@ -1560,13 +2104,15 @@ static void dnpds40_cmdline(void) { DEBUG("\t\t[ -i ] # Query printer info\n"); DEBUG("\t\t[ -I ] # Query sensor info\n"); - DEBUG("\t\t[ -s ] # Query status\n"); + DEBUG("\t\t[ -k num ] # Set standby time (1-99 minutes, 0 disables)\n"); + DEBUG("\t\t[ -K num ] # Keep Media Status Across Power Cycles (1 on, 0 off)\n"); DEBUG("\t\t[ -n ] # Query counters\n"); DEBUG("\t\t[ -N A|B|M ] # Clear counter A/B/M\n"); DEBUG("\t\t[ -p num ] # Set counter P\n"); - DEBUG("\t\t[ -k num ] # Set standby time (1-99 minutes, 0 disables)\n"); - DEBUG("\t\t[ -K num ] # Keep Media Status Across Power Cycles (1 on, 0 off)\n"); + DEBUG("\t\t[ -R ] # Reset printer\n"); + DEBUG("\t\t[ -s ] # Query status\n"); DEBUG("\t\t[ -x num ] # Set USB iSerialNumber Reporting (1 on, 0 off)\n"); + DEBUG("\t\t[ -X ] # Cancel current print job\n"); } static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv) @@ -1577,38 +2123,15 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - /* Reset arg parsing */ - optind = 1; - opterr = 0; - while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "iInN:p:sK:k:")) >= 0) { + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "iIk:K:nN:p:Rsx:X")) >= 0) { switch(i) { - GETOPT_PROCESS_GLOBAL + GETOPT_PROCESS_GLOBAL case 'i': j = dnpds40_get_info(ctx); break; case 'I': j = dnpds40_get_sensors(ctx); break; - case 'n': - j = dnpds40_get_counters(ctx); - break; - case 'N': - if (optarg[0] != 'A' && - optarg[0] != 'B' && - optarg[0] != 'M') - return CUPS_BACKEND_FAILED; - if (!ctx->supports_matte) { - ERROR("Printer FW does not support matte functions, please update!\n"); - return CUPS_BACKEND_FAILED; - } - j = dnpds40_clear_counter(ctx, optarg[0]); - break; - case 'p': - j = dnpds40_set_counter_p(ctx, optarg); - break; - case 's': - j = dnpds40_get_status(ctx); - break; case 'k': { int time = atoi(optarg); if (!ctx->supports_standby) { @@ -1639,6 +2162,35 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv) j = dnpds620_media_keep_mode(ctx, keep); break; } + case 'n': + j = dnpds40_get_counters(ctx); + break; + case 'N': + if (optarg[0] != 'A' && + optarg[0] != 'B' && + optarg[0] != 'M') + return CUPS_BACKEND_FAILED; + if (!ctx->supports_matte) { + ERROR("Printer FW does not support matte functions, please update!\n"); + return CUPS_BACKEND_FAILED; + } + j = dnpds40_clear_counter(ctx, optarg[0]); + break; + case 'p': + if (!ctx->supports_counterp) { + ERROR("Printer FW dows not support P counter!\n"); + return CUPS_BACKEND_FAILED; + } + j = dnpds40_set_counter_p(ctx, optarg); + break; + case 'R': { + j = dnpds40_reset_printer(ctx); + break; + } + case 's': { + j = dnpds40_get_status(ctx); + break; + } case 'x': { int enable = atoi(optarg); if (!ctx->supports_iserial) { @@ -1654,6 +2206,10 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv) j = dnpds620_iserial_mode(ctx, enable); break; } + case 'X': { + j = dnpds40_cancel_job(ctx); + break; + } default: break; /* Ignore completely */ } @@ -1667,7 +2223,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.61.2", + .version = "0.88", .uri_prefix = "dnpds40", .cmdline_usage = dnpds40_cmdline, .cmdline_arg = dnpds40_cmdline_arg, @@ -1681,10 +2237,10 @@ struct dyesub_backend dnpds40_backend = { { USB_VID_CITIZEN, USB_PID_DNP_DS40, P_DNP_DS40, ""}, { USB_VID_CITIZEN, USB_PID_DNP_DS80, P_DNP_DS80, ""}, { USB_VID_CITIZEN, USB_PID_DNP_DSRX1, P_DNP_DSRX1, ""}, + { USB_VID_CITIZEN, USB_PID_DNP_DS620_OLD, P_DNP_DS620, ""}, { 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_CW-02, P_DNP_DS40, ""}, -// { USB_VID_CITIZEN, USB_PID_CITIZEN_OP900II, P_DNP_DS40, ""}, + { USB_VID_DNP, USB_PID_DNP_DS80D, P_DNP_DS80D, ""}, + { USB_VID_CITIZEN, USB_PID_CITIZEN_CW02, P_DNP_DS40, ""}, { 0, 0, 0, ""} } }; diff --git a/src/cups/kodak1400_print.c b/src/cups/backend_kodak1400.c index c8e257c..3b97e3a 100644 --- a/src/cups/kodak1400_print.c +++ b/src/cups/backend_kodak1400.c @@ -1,7 +1,7 @@ /* * Kodak Professional 1400/805 CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org> * * The latest version of this program can be found at: * @@ -264,9 +264,6 @@ int kodak1400_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - /* Reset arg parsing */ - optind = 1; - opterr = 0; while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "C:")) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL @@ -395,7 +392,7 @@ static int kodak1400_read_parse(void *vctx, int data_fd) { do { ret = read(data_fd, ptr, remain); if (ret < 0) { - ERROR("Read failed (%d/%d/%d) (%d/%d @ %d)\n", + ERROR("Read failed (%d/%d/%u) (%d/%u @ %d)\n", ret, remain, ctx->hdr.columns, i, ctx->hdr.rows, j); perror("ERROR: Read failed"); diff --git a/src/cups/kodak605_print.c b/src/cups/backend_kodak605.c index ad2e6bf..1c0382d 100644 --- a/src/cups/kodak605_print.c +++ b/src/cups/backend_kodak605.c @@ -1,7 +1,7 @@ /* * Kodak 605 Photo Printer CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org> * * The latest version of this program can be found at: * @@ -74,13 +74,16 @@ struct kodak605_medium { struct kodak605_media_list { struct kodak605_sts_hdr hdr; uint8_t unk; /* always seen 02 */ - uint8_t type; /* KODAK_MEDIA_* */ + uint8_t type; /* KODAK68x0_MEDIA_* */ uint8_t count; struct kodak605_medium entries[]; } __attribute__((packed)); -#define KODAK_MEDIA_6R 0x0b -#define KODAK_MEDIA_NONE 0x00 +#define KODAK68x0_MEDIA_6R 0x0b // 197-4096 +#define KODAK68x0_MEDIA_UNK 0x03 +#define KODAK68x0_MEDIA_6TR2 0x2c // 396-2941 +#define KODAK68x0_MEDIA_NONE 0x00 +/* 6R: Also seen: 101-0867, 141-9597, 659-9054, 169-6418, DNP 900-060 */ #define MAX_MEDIA_LEN 128 @@ -145,6 +148,20 @@ static char *bank_statuses(uint8_t v) } } +static const char *kodak68xx_mediatypes(int type) +{ + switch(type) { + case KODAK68x0_MEDIA_NONE: + return "No media"; + case KODAK68x0_MEDIA_6R: + case KODAK68x0_MEDIA_6TR2: + return "Kodak 6R"; + default: + return "Unknown"; + } + return "Unknown"; +} + #define CMDBUF_LEN 4 /* Private data stucture */ @@ -161,6 +178,8 @@ struct kodak605_ctx { uint8_t *databuf; int datalen; + + uint8_t last_donor; }; static int kodak605_get_media(struct kodak605_ctx *ctx, struct kodak605_media_list *media) @@ -231,7 +250,12 @@ static void kodak605_attach(void *vctx, struct libusb_device_handle *dev, desc.idVendor, desc.idProduct); /* Make sure jobid is sane */ - ctx->jobid = (jobid & 0x7f) + 1; + ctx->jobid = jobid & 0x7f; + if (!ctx->jobid) + ctx->jobid++; + + /* Init */ + ctx->last_donor = 255; /* Query media info */ if (kodak605_get_media(ctx, ctx->media)) { @@ -366,8 +390,12 @@ static int kodak605_main_loop(void *vctx, int copies) { return CUPS_BACKEND_HOLD; } - /* Use specified jobid */ - ctx->hdr.jobid = ctx->jobid; + /* Tell CUPS about the consumables we report */ + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='%s'\n", kodak68xx_mediatypes(ctx->media->type)); + ATTR("marker-types=ribbonWax\n"); INFO("Waiting for printer idle\n"); @@ -375,8 +403,23 @@ static int kodak605_main_loop(void *vctx, int copies) { if ((ret = kodak605_get_status(ctx, &sts))) return CUPS_BACKEND_FAILED; + if (ctx->last_donor != sts.donor) { + ctx->last_donor = sts.donor; + ATTR("marker-levels=%u\n", sts.donor); + } + // XXX check for errors + /* Make sure we're not colliding with an existing + jobid */ + while (ctx->jobid == sts.b1_id || + ctx->jobid == sts.b2_id) { + ctx->jobid++; + ctx->jobid &= 0x7f; + if (!ctx->jobid) + ctx->jobid++; + } + /* Wait for a free buffer */ if (sts.b1_sts == BANK_STATUS_FREE || sts.b2_sts == BANK_STATUS_FREE) { @@ -386,8 +429,11 @@ static int kodak605_main_loop(void *vctx, int copies) { sleep(1); } + /* Use specified jobid */ + ctx->hdr.jobid = ctx->jobid; + { - INFO("Sending image header\n"); + INFO("Sending image header (internal id %u)\n", ctx->jobid); if ((ret = send_data(ctx->dev, ctx->endp_down, (uint8_t*)&ctx->hdr, sizeof(ctx->hdr)))) return CUPS_BACKEND_FAILED; @@ -415,10 +461,15 @@ static int kodak605_main_loop(void *vctx, int copies) { INFO("Waiting for printer to acknowledge completion\n"); do { sleep(1); - if ((ret = kodak605_get_status(ctx, &sts))) + if ((kodak605_get_status(ctx, &sts)) != 0) return CUPS_BACKEND_FAILED; - // XXX check for errors ? + // XXX check for errors + + if (ctx->last_donor != sts.donor) { + ctx->last_donor = sts.donor; + ATTR("marker-levels=%u\n", sts.donor); + } // XXX check for errors ? /* Wait for completion */ if (sts.b1_id == ctx->jobid && sts.b1_complete == sts.b1_total) @@ -437,40 +488,66 @@ static int kodak605_main_loop(void *vctx, int copies) { return CUPS_BACKEND_OK; } -static void kodak605_dump_status(struct kodak605_status *sts) +static void kodak605_dump_status(struct kodak605_ctx *ctx, struct kodak605_status *sts) { INFO("Bank 1: %s Job %03u @ %03u/%03u\n", bank_statuses(sts->b1_sts), sts->b1_id, - le16_to_cpu(sts->b1_complete), le16_to_cpu(sts->b1_complete)); + le16_to_cpu(sts->b1_complete), le16_to_cpu(sts->b1_total)); INFO("Bank 2: %s Job %03u @ %03u/%03u\n", bank_statuses(sts->b2_sts), sts->b2_id, - le16_to_cpu(sts->b2_complete), le16_to_cpu(sts->b2_complete)); + le16_to_cpu(sts->b2_complete), le16_to_cpu(sts->b2_total)); + + INFO("Lifetime prints : %u\n", be32_to_cpu(sts->ctr_life)); + INFO("Cutter actuations : %u\n", be32_to_cpu(sts->ctr_cut)); + INFO("Head prints : %u\n", be32_to_cpu(sts->ctr_head)); + INFO("Media prints : %u\n", be32_to_cpu(sts->ctr_media)); + { + int max; - INFO("Lifetime prints : %d\n", be32_to_cpu(sts->ctr_life)); - INFO("Cutter actuations : %d\n", be32_to_cpu(sts->ctr_cut)); - INFO("Head prints : %d\n", be32_to_cpu(sts->ctr_head)); - INFO("Media prints : %d\n", be32_to_cpu(sts->ctr_media)); - INFO("Donor : %d%%\n", sts->donor); + switch(ctx->media->type) { + case KODAK68x0_MEDIA_6R: + case KODAK68x0_MEDIA_6TR2: + max = 375; + break; + default: + max = 0; + break; + } + + if (max) { + INFO("\t Remaining : %u\n", max - be32_to_cpu(sts->ctr_media)); + } else { + INFO("\t Remaining : Unknown\n"); + } + } + + INFO("Donor : %u%%\n", sts->donor); } static void kodak605_dump_mediainfo(struct kodak605_media_list *media) { int i; - if (media->type == KODAK_MEDIA_NONE) { + if (media->type == KODAK68x0_MEDIA_NONE) { DEBUG("No Media Loaded\n"); return; } - if (media->type == KODAK_MEDIA_6R) { - DEBUG("Media type: 6R (Kodak 197-4096 or equivalent)\n"); - } else { - DEBUG("Media type %02x (unknown, please report!)\n", media->type); - } + switch (media->type) { + case KODAK68x0_MEDIA_6R: + INFO("Media type: 6R (Kodak 197-4096 or equivalent)\n"); + break; + case KODAK68x0_MEDIA_6TR2: + INFO("Media type: 6R (Kodak 396-2941 or equivalent)\n"); + break; + default: + INFO("Media type %02x (unknown, please report!)\n", media->type); + break; + } DEBUG("Legal print sizes:\n"); for (i = 0 ; i < media->count ; i++) { - DEBUG("\t%d: %dx%d\n", i, + DEBUG("\t%d: %ux%u\n", i, le16_to_cpu(media->entries[i].cols), le16_to_cpu(media->entries[i].rows)); } @@ -567,9 +644,6 @@ static int kodak605_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - /* Reset arg parsing */ - optind = 1; - opterr = 0; while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "C:ms")) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL @@ -584,7 +658,7 @@ static int kodak605_cmdline_arg(void *vctx, int argc, char **argv) j = kodak605_get_status(ctx, &sts); if (!j) - kodak605_dump_status(&sts); + kodak605_dump_status(ctx, &sts); break; } default: @@ -600,7 +674,7 @@ static int kodak605_cmdline_arg(void *vctx, int argc, char **argv) /* Exported */ struct dyesub_backend kodak605_backend = { .name = "Kodak 605", - .version = "0.24", + .version = "0.27", .uri_prefix = "kodak605", .cmdline_usage = kodak605_cmdline, .cmdline_arg = kodak605_cmdline_arg, diff --git a/src/cups/kodak6800_print.c b/src/cups/backend_kodak6800.c index 1e77850..63a6063 100644 --- a/src/cups/kodak6800_print.c +++ b/src/cups/backend_kodak6800.c @@ -1,7 +1,7 @@ /* * Kodak 6800/6850 Photo Printer CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org> * * Development of this backend was sponsored by: * @@ -199,7 +199,7 @@ struct kodak6800_printsize { uint16_t height; /* BE */ uint8_t type; /* MEDIA_TYPE_* [ ie paper ] */ uint8_t code; /* 00, 01, 02, 03, 04, 05 seen. An index? */ - uint8_t code2; /* 00, 01 seen. Seems to be 1 only after a 4x6 printed. */ + uint8_t code2; /* 00, 01 seen. Alternates every other 4x6 printed, but only 1 on unknown/1844x2490 print size. */ uint8_t null[2]; } __attribute__((packed)); @@ -207,15 +207,17 @@ struct kodak6800_printsize { struct kodak68x0_media_readback { uint8_t hdr; /* Always 0x01 */ - uint8_t media; /* Always 0x00 (none), 0x0b or 0x03 */ + uint8_t type; /* Media code, KODAK68x0_MEDIA_xxx */ uint8_t null[5]; uint8_t count; /* Always 0x04 (6800) or 0x06 (6850)? */ struct kodak6800_printsize sizes[]; } __attribute__((packed)); -#define KODAK68x0_MEDIA_6R 0x0b +#define KODAK68x0_MEDIA_6R 0x0b // 197-4096 #define KODAK68x0_MEDIA_UNK 0x03 +#define KODAK68x0_MEDIA_6TR2 0x2c // 396-2941 #define KODAK68x0_MEDIA_NONE 0x00 +/* 6R: Also seen: 101-0867, 141-9597, 659-9054, 169-6418, DNP 900-060 */ #define CMDBUF_LEN 17 @@ -234,8 +236,24 @@ struct kodak6800_ctx { struct kodak6800_hdr hdr; uint8_t *databuf; int datalen; + + uint8_t last_donor; }; +static const char *kodak68xx_mediatypes(int type) +{ + switch(type) { + case KODAK68x0_MEDIA_NONE: + return "No media"; + case KODAK68x0_MEDIA_6R: + case KODAK68x0_MEDIA_6TR2: + return "Kodak 6R"; + default: + return "Unknown"; + } + return "Unknown"; +} + /* Baseline commands */ static int kodak6800_do_cmd(struct kodak6800_ctx *ctx, void *cmd, int cmd_len, @@ -258,26 +276,34 @@ static int kodak6800_do_cmd(struct kodak6800_ctx *ctx, return 0; } + + static void kodak68x0_dump_mediainfo(struct kodak68x0_media_readback *media) { int i; - if (media->media == KODAK68x0_MEDIA_NONE) { + if (media->type == KODAK68x0_MEDIA_NONE) { INFO("No Media Loaded\n"); return; } - if (media->media == KODAK68x0_MEDIA_6R) { + switch (media->type) { + case KODAK68x0_MEDIA_6R: INFO("Media type: 6R (Kodak 197-4096 or equivalent)\n"); - } else { - INFO("Media type %02x (unknown, please report!)\n", media->media); + break; + case KODAK68x0_MEDIA_6TR2: + INFO("Media type: 6R (Kodak 396-2941 or equivalent)\n"); + break; + default: + INFO("Media type %02x (unknown, please report!)\n", media->type); + break; } INFO("Legal print sizes:\n"); for (i = 0 ; i < media->count ; i++) { INFO("\t%d: %dx%d (%02x) %s\n", i, - be16_to_cpu(media->sizes[i].width), - be16_to_cpu(media->sizes[i].height), - media->sizes[i].code, - media->sizes[i].code2? "Disallowed" : ""); + be16_to_cpu(media->sizes[i].width), + be16_to_cpu(media->sizes[i].height), + media->sizes[i].code, + media->sizes[i].code2? "Disallowed?" : ""); } INFO("\n"); } @@ -296,6 +322,7 @@ static int kodak6800_get_mediainfo(struct kodak6800_ctx *ctx, struct kodak68x0_m req[3] = 0x48; req[4] = 0x43; req[5] = 0x1a; + req[6] = 0x00; /* This can be non-zero for additional "banks" */ /* Issue command and get response */ if ((ret = kodak6800_do_cmd(ctx, req, sizeof(req), @@ -345,6 +372,36 @@ static int kodak68x0_canceljob(struct kodak6800_ctx *ctx, return 0; } +static int kodak68x0_reset(struct kodak6800_ctx *ctx) +{ + uint8_t req[16]; + int ret, num; + struct kodak68x0_status_readback sts; + + memset(req, 0, sizeof(req)); + + req[0] = 0x03; + req[1] = 0x1b; + req[2] = 0x43; + req[3] = 0x48; + req[4] = 0xc0; + + /* Issue command and get response */ + if ((ret = kodak6800_do_cmd(ctx, req, sizeof(req), + &sts, sizeof(sts), + &num))) + return ret; + + /* Validate proper response */ + if (sts.hdr != CMD_CODE_OK) { + ERROR("Unexpected response from job cancel!\n"); + return -99; + } + + return 0; +} + + /* Structure dumps */ static char *kodak68x0_status_str(struct kodak68x0_status_readback *resp) { @@ -512,10 +569,10 @@ static void kodak68x0_dump_status(struct kodak6800_ctx *ctx, struct kodak68x0_st kodak68x0_status_str(status), status->status1, be32_to_cpu(status->status2), status->errcode); - INFO("Bank 1 ID: %d\n", status->b1_jobid); + INFO("Bank 1 ID: %u\n", status->b1_jobid); INFO("\tPrints: %d/%d complete\n", be16_to_cpu(status->b1_complete), be16_to_cpu(status->b1_total)); - INFO("Bank 2 ID: %d\n", status->b2_jobid); + INFO("Bank 2 ID: %u\n", status->b2_jobid); INFO("\tPrints: %d/%d complete\n", be16_to_cpu(status->b2_complete), be16_to_cpu(status->b2_total)); @@ -536,30 +593,34 @@ static void kodak68x0_dump_status(struct kodak6800_ctx *ctx, struct kodak68x0_st INFO("Tone Curve Status: %s\n", detail); INFO("Counters:\n"); - INFO("\tLifetime : %d\n", be32_to_cpu(status->lifetime)); - INFO("\tThermal Head : %d\n", be32_to_cpu(status->maint)); - INFO("\tCutter : %d\n", be32_to_cpu(status->cutter)); + INFO("\tLifetime : %u\n", be32_to_cpu(status->lifetime)); + INFO("\tThermal Head : %u\n", be32_to_cpu(status->maint)); + INFO("\tCutter : %u\n", be32_to_cpu(status->cutter)); if (ctx->type == P_KODAK_6850) { int max; - INFO("\tMedia : %d\n", be32_to_cpu(status->media)); + INFO("\tMedia : %u\n", be32_to_cpu(status->media)); - if (ctx->media->media == KODAK68x0_MEDIA_6R) { + switch(ctx->media->type) { + case KODAK68x0_MEDIA_6R: + case KODAK68x0_MEDIA_6TR2: max = 375; - } else { + break; + default: max = 0; + break; } if (max) { - INFO("\t Remaining : %d\n", max - be32_to_cpu(status->media)); + INFO("\t Remaining : %d\n", max - be32_to_cpu(status->media)); } else { - INFO("\t Remaining : Unknown\n"); + INFO("\t Remaining : Unknown\n"); } } - INFO("Main FW version: %d\n", be16_to_cpu(status->main_fw)); - INFO("DSP FW version : %d\n", be16_to_cpu(status->dsp_fw)); - INFO("Donor : %d%%\n", status->donor); + INFO("Main FW version : %d\n", be16_to_cpu(status->main_fw)); + INFO("DSP FW version : %d\n", be16_to_cpu(status->dsp_fw)); + INFO("Donor : %u%%\n", status->donor); INFO("\n"); } @@ -623,8 +684,8 @@ static int kodak6800_get_tonecurve(struct kodak6800_ctx *ctx, char *fname) cmdbuf[8] = 0x4e; cmdbuf[9] = 0x45; cmdbuf[10] = 0x72; - cmdbuf[11] = 0x01; - cmdbuf[12] = 0x00; + cmdbuf[11] = 0x01; /* 01 for user tonecurve, can be 00 or 02 */ + cmdbuf[12] = 0x00; /* param table? */ cmdbuf[13] = 0x00; cmdbuf[14] = 0x00; cmdbuf[15] = 0x00; @@ -739,8 +800,8 @@ static int kodak6800_set_tonecurve(struct kodak6800_ctx *ctx, char *fname) cmdbuf[8] = 0x4e; cmdbuf[9] = 0x45; cmdbuf[10] = 0x77; - cmdbuf[11] = 0x01; - cmdbuf[12] = 0x00; + cmdbuf[11] = 0x01; /* User TC. Can be 00 or 02 */ + cmdbuf[12] = 0x00; /* param table? */ cmdbuf[13] = 0x00; cmdbuf[14] = 0x00; cmdbuf[15] = 0x00; @@ -838,7 +899,7 @@ static int kodak6800_query_serno(struct libusb_device_handle *dev, uint8_t endp_ return 0; } -static int kodak6850_send_init(struct kodak6800_ctx *ctx) +static int kodak6850_send_unk(struct kodak6800_ctx *ctx) { uint8_t cmdbuf[16]; uint8_t rdbuf[64]; @@ -869,12 +930,13 @@ static int kodak6850_send_init(struct kodak6800_ctx *ctx) return CUPS_BACKEND_FAILED; } - // XXX I believe this the media position - // saying when we have a 4x6 left on an 8x6 blank +#if 0 + // XXX No particular idea what this actually is if (rdbuf[1] != 0x01 && rdbuf[1] != 0x00) { ERROR("Unexpected status code (0x%02x)!\n", rdbuf[1]); return CUPS_BACKEND_FAILED; } +#endif return ret; } @@ -884,6 +946,7 @@ static void kodak6800_cmdline(void) DEBUG("\t\t[ -C filename ] # Set tone curve\n"); DEBUG("\t\t[ -m ] # Query media\n"); DEBUG("\t\t[ -s ] # Query status\n"); + DEBUG("\t\t[ -R ] # Reset printer\n"); DEBUG("\t\t[ -X jobid ] # Cancel Job\n"); } @@ -895,7 +958,7 @@ static int kodak6800_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "C:c:msX:")) >= 0) { + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "C:c:mRsX:")) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL case 'c': @@ -907,6 +970,9 @@ static int kodak6800_cmdline_arg(void *vctx, int argc, char **argv) case 'm': kodak68x0_dump_mediainfo(ctx->media); break; + case 'R': + kodak68x0_reset(ctx); + break; case 's': { struct kodak68x0_status_readback status; j = kodak6800_get_status(ctx, &status); @@ -961,7 +1027,12 @@ static void kodak6800_attach(void *vctx, struct libusb_device_handle *dev, desc.idVendor, desc.idProduct); /* Ensure jobid is sane */ - ctx->jobid = (jobid & 0x7f) + 1; + ctx->jobid = jobid & 0x7f; + if (!ctx->jobid) + ctx->jobid++; + + /* Init */ + ctx->last_donor = 255; /* Query media info */ if (kodak6800_get_mediainfo(ctx, ctx->media)) { @@ -1053,18 +1124,11 @@ static int kodak6800_main_loop(void *vctx, int copies) { /* Printer handles generating copies.. */ ctx->hdr.copies = cpu_to_be16(uint16_to_packed_bcd(copies)); - /* Validate media */ - if (ctx->media->media != KODAK68x0_MEDIA_6R && - ctx->media->media != KODAK68x0_MEDIA_UNK) { - ERROR("Unrecognized media type %02x\n", ctx->media->media); - return CUPS_BACKEND_STOP; - } - /* Validate against supported media list */ for (num = 0 ; num < ctx->media->count; num++) { if (ctx->media->sizes[num].height == ctx->hdr.rows && ctx->media->sizes[num].width == ctx->hdr.columns && - ctx->media->sizes[num].code2 == 0x00) + ctx->media->sizes[num].code2 == 0x00) // XXX code2? break; } if (num == ctx->media->count) { @@ -1072,12 +1136,24 @@ static int kodak6800_main_loop(void *vctx, int copies) { return CUPS_BACKEND_HOLD; } + /* Tell CUPS about the consumables we report */ + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='%s'\n", kodak68xx_mediatypes(ctx->media->type)); + ATTR("marker-types=ribbonWax\n"); + INFO("Waiting for printer idle\n"); while(1) { if (kodak6800_get_status(ctx, &status)) return CUPS_BACKEND_FAILED; + if (ctx->last_donor != status.donor) { + ctx->last_donor = status.donor; + ATTR("marker-levels=%u\n", status.donor); + } + if (status.status1 == STATE_STATUS1_ERROR) { INFO("Printer State: %s # %02x %08x %02x\n", kodak68x0_status_str(&status), @@ -1088,6 +1164,16 @@ static int kodak6800_main_loop(void *vctx, int copies) { if (status.status == STATUS_IDLE) break; + /* make sure we're not colliding with an existing + jobid */ + while (ctx->jobid == status.b1_jobid || + ctx->jobid == status.b2_jobid) { + ctx->jobid++; + ctx->jobid &= 0x7f; + if (!ctx->jobid) + ctx->jobid++; + } + /* See if we have an open bank */ if (!status.b1_remain || !status.b2_remain) @@ -1096,9 +1182,9 @@ static int kodak6800_main_loop(void *vctx, int copies) { sleep(1); } + /* This command is unknown, sort of a secondary status query */ if (ctx->type == P_KODAK_6850) { -// INFO("Sending 6850 init sequence\n"); - ret = kodak6850_send_init(ctx); + ret = kodak6850_send_unk(ctx); if (ret) return ret; } @@ -1107,6 +1193,7 @@ static int kodak6800_main_loop(void *vctx, int copies) { #if 0 /* If we want to disable 4x6 rewind on 8x6 media.. */ + // XXX not sure about this...? if (ctx->hdr.size == 0x00 && be16_to_cpu(ctx->media->sizes[0].width) == 0x0982) { ctx->hdr.size = 0x06; @@ -1114,7 +1201,7 @@ static int kodak6800_main_loop(void *vctx, int copies) { } #endif - INFO("Initiating Print Job\n"); + INFO("Sending Print Job (internal id %u)\n", ctx->jobid); if ((ret = kodak6800_do_cmd(ctx, (uint8_t*) &ctx->hdr, sizeof(ctx->hdr), &status, sizeof(status), &num))) @@ -1127,8 +1214,8 @@ static int kodak6800_main_loop(void *vctx, int copies) { // sleep(1); // Appears to be necessary for reliability INFO("Sending image data\n"); - if ((ret = send_data(ctx->dev, ctx->endp_down, - ctx->databuf, ctx->datalen))) + if ((send_data(ctx->dev, ctx->endp_down, + ctx->databuf, ctx->datalen)) != 0) return CUPS_BACKEND_FAILED; INFO("Waiting for printer to acknowledge completion\n"); @@ -1137,6 +1224,11 @@ static int kodak6800_main_loop(void *vctx, int copies) { if (kodak6800_get_status(ctx, &status)) return CUPS_BACKEND_FAILED; + if (ctx->last_donor != status.donor) { + ctx->last_donor = status.donor; + ATTR("marker-levels=%u\n", status.donor); + } + if (status.status1 == STATE_STATUS1_ERROR) { INFO("Printer State: %s # %02x %08x %02x\n", kodak68x0_status_str(&status), @@ -1165,7 +1257,7 @@ static int kodak6800_main_loop(void *vctx, int copies) { /* Exported */ struct dyesub_backend kodak6800_backend = { .name = "Kodak 6800/6850", - .version = "0.51", + .version = "0.57", .uri_prefix = "kodak6800", .cmdline_usage = kodak6800_cmdline, .cmdline_arg = kodak6800_cmdline_arg, @@ -1193,7 +1285,8 @@ struct dyesub_backend kodak6800_backend = { Header: - 03 1b 43 48 43 0a 00 01 Fixed header + 03 1b 43 48 43 0a 00 Fixed header + II Job ID (1-255) NN NN Number of copies in BCD form (0001->9999) WW WW Number of columns (Fixed at 1844 on 6800) HH HH Number of rows. @@ -1209,12 +1302,14 @@ struct dyesub_backend kodak6800_backend = { ************************************************************************ + This command is unique to the 6850: + -> 03 1b 43 48 43 4c 00 00 00 00 00 00 00 00 00 00 [???] <- [51 octets] - 01 01 43 48 43 4c 00 00 00 00 00 00 00 00 00 00 - 00 00 01 29 00 00 3b 0a 00 00 00 0e 00 03 02 90 - 00 01 02 1d 03 00 00 00 00 01 00 01 00 00 00 00 + 01 01 43 48 43 4c 00 00 00 00 00 00 00 00 00 00 <-- Everything after this + 00 00 01 29 00 00 3b 0a 00 00 00 0e 00 03 02 90 line is the same as + 00 01 02 1d 03 00 00 00 00 01 00 01 00 00 00 00 the "status" resp. 00 00 00 01 00 43 48 43 4c 00 00 00 00 00 00 00 00 00 00 diff --git a/src/cups/backend_mitsu70x.c b/src/cups/backend_mitsu70x.c new file mode 100644 index 0000000..e0b0587 --- /dev/null +++ b/src/cups/backend_mitsu70x.c @@ -0,0 +1,1609 @@ +/* + * Mitsubishi CP-D70/D707 Photo Printer CUPS backend -- libusb-1.0 version + * + * (c) 2013-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 mitsu70x_backend + +#include "backend_common.h" + +#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_VID_KODAK 0x040a +#define USB_PID_KODAK305 0x404f +//#define USB_VID_FUJIFILM XXXXXX +//#define USB_PID_FUJI_ASK300 XXXXXX + +//#define ENABLE_CORRTABLES + +/* Private data stucture */ +struct mitsu70x_ctx { + struct libusb_device_handle *dev; + uint8_t endp_up; + uint8_t endp_down; + int type; + + uint8_t *databuf; + int datalen; + + uint32_t matte; + + uint16_t jobid; + uint16_t rows; + uint16_t cols; + + uint16_t last_donor_l; + uint16_t last_donor_u; + int num_decks; + +#ifdef ENABLE_CORRTABLES + struct mitsu70x_corrdata *corrdata; + struct mitsu70x_corrdatalens *corrdatalens; + char *laminatefname; + char *lutfname; + + int raw_format; +#endif +}; + +/* Printer data structures */ +struct mitsu70x_jobstatus { + uint8_t hdr[4]; + uint16_t jobid; + uint16_t mecha_no; + uint8_t job_status[4]; + uint8_t memory; + uint8_t power; + uint8_t mecha_status[2]; + uint8_t temperature; + uint8_t error_status[3]; + uint8_t reserved[6]; +} __attribute__((packed)); + +struct mitsu70x_jobs { + uint8_t hdr[4]; + uint16_t dummy; + uint16_t jobid_0; + uint8_t job0_status[4]; + uint16_t jobid_1; + uint8_t job1_status[4]; + // XXX are there more? +} __attribute__((packed)); + +#define TEMPERATURE_NORMAL 0x00 +#define TEMPERATURE_PREHEAT 0x40 +#define TEMPERATURE_COOLING 0x80 + +#define MECHA_STATUS_INIT 0x80 +#define MECHA_STATUS_FEED 0x50 +#define MECHA_STATUS_LOAD 0x40 +#define MECHA_STATUS_PRINT 0x20 +#define MECHA_STATUS_IDLE 0x00 + +#define JOB_STATUS0_NONE 0x00 +#define JOB_STATUS0_DATA 0x10 +#define JOB_STATUS0_QUEUE 0x20 +#define JOB_STATUS0_PRINT 0x50 +#define JOB_STATUS0_ASSIGN 0x70 // XXX undefined. +#define JOB_STATUS0_END 0x80 + +#define JOB_STATUS1_PRINT_MEDIALOAD 0x10 +#define JOB_STATUS1_PRINT_PRE_Y 0x20 +#define JOB_STATUS1_PRINT_Y 0x30 +#define JOB_STATUS1_PRINT_PRE_M 0x40 +#define JOB_STATUS1_PRINT_M 0x50 +#define JOB_STATUS1_PRINT_PRE_C 0x60 +#define JOB_STATUS1_PRINT_C 0x70 +#define JOB_STATUS1_PRINT_PRE_OC 0x80 +#define JOB_STATUS1_PRINT_OC 0x90 +#define JOB_STATUS1_PRINT_EJECT 0xA0 + +#define JOB_STATUS1_END_OK 0x00 +#define JOB_STATUS1_END_MECHA 0x10 // 0x10...0x7f +#define JOB_STATUS1_END_HEADER 0x80 +#define JOB_STATUS1_END_PRINT 0x90 +#define JOB_STATUS1_END_INTERRUPT 0xA0 + +#define JOB_STATUS2_END_HEADER_ERROR 0x00 +#define JOB_STATUS2_END_HEADER_MEMORY 0x10 +#define JOB_STATUS2_END_PRINT_MEDIA 0x00 +#define JOB_STATUS2_END_PRINT_PREVERR 0x10 +#define JOB_STATUS2_END_INT_TIMEOUT 0x00 +#define JOB_STATUS2_END_INT_CANCEL 0x10 +#define JOB_STATUS2_END_INT_DISCON 0x20 + +/* Error codes */ +#define ERROR_STATUS0_NOSTRIPBIN 0x01 +#define ERROR_STATUS0_NORIBBON 0x02 +#define ERROR_STATUS0_NOPAPER 0x03 +#define ERROR_STATUS0_MEDIAMISMATCH 0x04 +#define ERROR_STATUS0_RIBBONCNTEND 0x05 +#define ERROR_STATUS0_BADRIBBON 0x06 +#define ERROR_STATUS0_BADJOBPARAM 0x07 +#define ERROR_STATUS0_PAPEREND 0x08 +#define ERROR_STATUS0_RIBBONEND 0x09 +#define ERROR_STATUS0_DOOROPEN_IDLE 0x0A +#define ERROR_STATUS0_DOOROPEN_PRNT 0x0B +#define ERROR_STATUS0_POWEROFF 0x0C // nonsense.. heh. +#define ERROR_STATUS0_NOMCOP 0x0D +#define ERROR_STATUS0_RIBBONSKIP1 0x0E +#define ERROR_STATUS0_RIBBONSKIP2 0x0F +#define ERROR_STATUS0_RIBBONJAM 0x10 +#define ERROR_STATUS0_RIBBON_OTHER 0x11 // 0x11->0x1F +#define ERROR_STATUS0_PAPER_JAM 0x20 // 0x20->0x2F +#define ERROR_STATUS0_MECHANICAL 0x30 // 0x30->0x39 +#define ERROR_STATUS0_RFID 0x3A +#define ERROR_STATUS0_FLASH 0x3B +#define ERROR_STATUS0_EEPROM 0x3C +#define ERROR_STATUS0_PREHEAT 0x3D +#define ERROR_STATUS0_MDASTATE 0x3E +#define ERROR_STATUS0_PSUFANLOCKED 0x3F +#define ERROR_STATUS0_OTHERS 0x40 // 0x40..? + +/* Error classifications */ +#define ERROR_STATUS1_PAPER 0x01 +#define ERROR_STATUS1_RIBBON 0x02 +#define ERROR_STATUS1_SETTING 0x03 +#define ERROR_STATUS1_OPEN 0x05 +#define ERROR_STATUS1_NOSTRIPBIN 0x06 +#define ERROR_STATUS1_PAPERJAM 0x07 +#define ERROR_STATUS1_RIBBONSYS 0x08 +#define ERROR_STATUS1_MECHANICAL 0x09 +#define ERROR_STATUS1_ELECTRICAL 0x0A +#define ERROR_STATUS1_FIRMWARE 0x0E +#define ERROR_STATUS1_OTHER 0x0F + +/* Error recovery conditions */ +#define ERROR_STATUS2_AUTO 0x00 +#define ERROR_STATUS2_RELOAD_PAPER 0x01 +#define ERROR_STATUS2_RELOAD_RIBBON 0x02 +#define ERROR_STATUS2_CHANGE_BOTH 0x03 +#define ERROR_STATUS2_CHANGE_ONE 0x04 +#define ERROR_STATUS2_CLOSEUNIT 0x05 +#define ERROR_STATUS2_ATTACHSTRIPBIN 0x06 +#define ERROR_STATUS2_CLEARJAM 0x07 +#define ERROR_STATUS2_CHECKRIBBON 0x08 +#define ERROR_STATUS2_OPENCLOSEUNIT 0x0A +#define ERROR_STATUS2_POWEROFF 0x0F + +struct mitsu70x_status_deck { + uint8_t mecha_status[2]; + uint8_t temperature; + uint8_t error_status[3]; + uint8_t rsvd_a[10]; + + uint8_t media_brand; + uint8_t media_type; + uint8_t rsvd_b[2]; + 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? */ + uint16_t rsvd_e[17]; +} __attribute__((packed)); + +struct mitsu70x_status_ver { + char ver[6]; + uint16_t checksum; /* Presumably BE */ +} __attribute__((packed)); + +struct mitsu70x_printerstatus_resp { + uint8_t hdr[4]; + uint8_t unk[36]; + int16_t model[6]; /* LE, UTF-16 */ + int16_t serno[6]; /* LE, UTF-16 */ + struct mitsu70x_status_ver vers[7]; // components are 'LMFTR??' + uint8_t null[8]; + struct mitsu70x_status_deck lower; + struct mitsu70x_status_deck upper; +} __attribute__((packed)); + +struct mitsu70x_memorystatus_resp { + uint8_t hdr[3]; + uint8_t memory; + uint8_t size; + uint8_t rsvd; +} __attribute__((packed)); + +struct mitsu70x_hdr { + uint8_t hdr[4]; /* 1b 5a 54 XX */ + uint16_t jobid; + uint8_t zero0[10]; + + uint16_t cols; + uint16_t rows; + uint16_t lamcols; + uint16_t lamrows; + uint8_t speed; + uint8_t zero1[7]; + + uint8_t deck; /* 0 = default, 1 = lower, 2 = upper */ + uint8_t zero2[7]; + uint8_t laminate; /* 00 == on, 01 == off */ + uint8_t laminate_mode; + uint8_t zero3[6]; + + uint8_t multicut; + uint8_t zero4[15]; + + uint8_t pad[448]; +} __attribute__((packed)); + +#ifdef ENABLE_CORRTABLES +/* Correction data definitions */ +#define CORRDATA_DEF +struct mitsu70x_corrdata { + uint16_t liney[2730]; + uint16_t linem[2730]; + uint16_t linec[2730]; + uint16_t gnmby[256]; // B->Y conversion matrix + uint16_t gnmgm[256]; // G->M conversion matrix + uint16_t gnmrc[256]; // R->C conversion matrix + double fm[256]; + double ksp[128]; + double ksm[128]; + double osp[128]; + double osm[128]; + double kp[11]; + double km[11]; + double hk[4]; + uint16_t speed[3]; + double fh[5]; /* only 4 in length on D70 Normal/Superfine */ + double shk[72]; + double uh[101]; + uint16_t rolk[13]; /* Missing on D70x family */ + uint32_t rev[76]; /* Missing on D70x and ASK300 */ +}; + +struct mitsu70x_corrdatalens { + size_t liney; + size_t linem; + size_t linec; + size_t gnmby; + size_t gnmgm; + size_t gnmrc; + size_t fm; + size_t ksp; + size_t ksm; + size_t osp; + size_t osm; + size_t kp; + size_t km; + size_t hk; + size_t speed; + size_t fh; + size_t shk; + size_t uh; + size_t rolk; + size_t rev; +}; + +#include "D70/CPD70N01.h" // Normal/Fine +#include "D70/CPD70S01.h" // Superfine +#include "D70/CPD70U01.h" // Ultrafine +//#include "D70/CPD80E01.h" // ??? +#include "D70/CPD80N01.h" // Normal/Fine +#include "D70/CPD80S01.h" // Superfine +#include "D70/CPD80U01.h" // Ultrafine +#include "D70/ASK300T1.h" // Normal/Fine +#include "D70/ASK300T3.h" // Superfine/Ultrafine +#include "D70/CPS60T01.h" // Normal/Fine +#include "D70/CPS60T03.h" // Superfine/Ultrafine +#include "D70/EK305T01.h" // Normal/Fine +#include "D70/EK305T03.h" // Superfine/Ultrafine +#endif + +/* Error dumps, etc */ + +static char *mitsu70x_mechastatus(uint8_t *sts) +{ + switch(sts[0]) { + case MECHA_STATUS_INIT: + return "Initializing"; + case MECHA_STATUS_FEED: + return "Paper Feeding/Cutting"; + case MECHA_STATUS_LOAD: + return "Media Loading"; + case MECHA_STATUS_PRINT: + return "Printing"; + case MECHA_STATUS_IDLE: + return "Idle"; + default: + break; + } + return "Unknown Mechanical Status"; +} + +static char *mitsu70x_jobstatuses(uint8_t *sts) +{ + switch(sts[0]) { + case JOB_STATUS0_NONE: + return "No Job"; + case JOB_STATUS0_DATA: + return "Data transfer"; + case JOB_STATUS0_QUEUE: + return "Queued for printing"; + case JOB_STATUS0_PRINT: + switch(sts[1]) { + case JOB_STATUS1_PRINT_MEDIALOAD: + return "Media loading"; + case JOB_STATUS1_PRINT_PRE_Y: + return "Waiting to print yellow plane"; + case JOB_STATUS1_PRINT_Y: + return "Printing yellow plane"; + case JOB_STATUS1_PRINT_PRE_M: + return "Waiting to print magenta plane"; + case JOB_STATUS1_PRINT_M: + return "Printing magenta plane"; + case JOB_STATUS1_PRINT_PRE_C: + return "Waiting to print cyan plane"; + case JOB_STATUS1_PRINT_C: + return "Printing cyan plane"; + case JOB_STATUS1_PRINT_PRE_OC: + return "Waiting to laminate page"; + case JOB_STATUS1_PRINT_OC: + return "Laminating page"; + case JOB_STATUS1_PRINT_EJECT: + return "Ejecting page"; + default: + return "Unknown 'Print' status1\n"; + } + break; + case JOB_STATUS0_ASSIGN: + return "Unknown 'Assignment' status1\n"; + case JOB_STATUS0_END: + switch(sts[1]) { + case JOB_STATUS1_END_OK: + return "Normal End"; + case JOB_STATUS1_END_HEADER: + case JOB_STATUS1_END_PRINT: + switch(sts[2]) { + case JOB_STATUS2_END_PRINT_MEDIA: + return "Incorrect mediasize"; + case JOB_STATUS2_END_PRINT_PREVERR: + return "Previous job terminated abnormally"; + default: + return "Unknown 'End Print' status2"; + } + break; + case JOB_STATUS1_END_INTERRUPT: + switch(sts[2]) { + case JOB_STATUS2_END_INT_TIMEOUT: + return "Timeout"; + case JOB_STATUS2_END_INT_CANCEL: + return "Job cancelled"; + case JOB_STATUS2_END_INT_DISCON: + return "Printer disconnected"; + default: + return "Unknown 'End Print' status2"; + } + break; + default: + if (sts[1] >= 0x10 && sts[1] <= 0x7f) + return "Mechanical Error"; + else + return "Unknown 'End' status1"; + } + break; + default: + break; + } + + return "Unknown status0"; +} + +static char *mitsu70x_errorclass(uint8_t *err) +{ + switch(err[1]) { + case ERROR_STATUS1_PAPER: + return "Paper"; + case ERROR_STATUS1_RIBBON: + return "Ribbon"; + case ERROR_STATUS1_SETTING: + return "Job settings"; + case ERROR_STATUS1_OPEN: + return "Cover open"; + case ERROR_STATUS1_NOSTRIPBIN: + return "No cut bin"; + case ERROR_STATUS1_PAPERJAM: + return "Paper jam"; + case ERROR_STATUS1_RIBBONSYS: + return "Ribbon system"; + case ERROR_STATUS1_MECHANICAL: + return "Mechanical"; + case ERROR_STATUS1_ELECTRICAL: + return "Electrical"; + case ERROR_STATUS1_FIRMWARE: + return "Firmware"; + case ERROR_STATUS1_OTHER: + return "Other"; + default: + break; + } + return "Unknown error class"; +} + +static char *mitsu70x_errorrecovery(uint8_t *err) +{ + switch(err[1]) { + case ERROR_STATUS2_AUTO: + return "Automatic recovery"; + case ERROR_STATUS2_RELOAD_PAPER: + return "Reload or change paper"; + case ERROR_STATUS2_RELOAD_RIBBON: + return "Reload or change ribbon"; + case ERROR_STATUS2_CHANGE_BOTH: + return "Change paper and ribbon"; + case ERROR_STATUS2_CHANGE_ONE: + return "Change paper or ribbon"; + case ERROR_STATUS2_CLOSEUNIT: + return "Close printer"; + case ERROR_STATUS2_ATTACHSTRIPBIN: + return "Attach Strip Bin"; + case ERROR_STATUS2_CLEARJAM: + return "Remove and reload paper"; + case ERROR_STATUS2_CHECKRIBBON: + return "Check ribbon and reload paper"; + case ERROR_STATUS2_OPENCLOSEUNIT: + return "Open then close printer"; + case ERROR_STATUS2_POWEROFF: + return "Power-cycle printer"; + default: + break; + } + return "Unknown recovery"; +} + +static char *mitsu70x_errors(uint8_t *err) +{ + switch(err[0]) { + case ERROR_STATUS0_NOSTRIPBIN: + return "Strip bin not attached"; + case ERROR_STATUS0_NORIBBON: + return "No ribbon detected"; + case ERROR_STATUS0_NOPAPER: + return "No paper loaded"; + case ERROR_STATUS0_MEDIAMISMATCH: + return "Ribbon/Paper mismatch"; + case ERROR_STATUS0_RIBBONCNTEND: + return "Ribbon count end"; + case ERROR_STATUS0_BADRIBBON: + return "Illegal Ribbon"; + case ERROR_STATUS0_BADJOBPARAM: + return "Job does not match loaded media"; + case ERROR_STATUS0_PAPEREND: + return "End of paper detected"; + case ERROR_STATUS0_RIBBONEND: + return "End of ribbon detected"; + case ERROR_STATUS0_DOOROPEN_IDLE: + case ERROR_STATUS0_DOOROPEN_PRNT: + return "Printer door open"; + case ERROR_STATUS0_POWEROFF: + return "Printer powered off"; // nonsense.. + case ERROR_STATUS0_RIBBONSKIP1: + case ERROR_STATUS0_RIBBONSKIP2: + return "Ribbon skipped"; + case ERROR_STATUS0_RIBBONJAM: + return "Ribbon stuck to paper"; + case ERROR_STATUS0_RFID: + return "RFID read error"; + case ERROR_STATUS0_FLASH: + return "FLASH read error"; + case ERROR_STATUS0_EEPROM: + return "EEPROM read error"; + case ERROR_STATUS0_PREHEAT: + return "Preheating unit time out"; + case ERROR_STATUS0_MDASTATE: + return "Unknown MDA state"; + case ERROR_STATUS0_PSUFANLOCKED: + return "Power supply fan locked up"; + default: + break; + } + + if (err[0] >= ERROR_STATUS0_RIBBON_OTHER && + err[0] < ERROR_STATUS0_PAPER_JAM) { + return "Unknown ribbon error"; + // XXX use err[1]/err[2] codes? + } + if (err[0] >= ERROR_STATUS0_PAPER_JAM && + err[0] < ERROR_STATUS0_MECHANICAL) { + return "Paper jam"; + // XXX use err[1]/err[2] codes? + } + if (err[0] >= ERROR_STATUS0_MECHANICAL && + err[0] < ERROR_STATUS0_RFID) { + return "Unknown mechanical error"; + // XXX use err[1]/err[2] codes? + } + + return "Unknown error"; +} + +static const char *mitsu70x_media_types(uint8_t brand, uint8_t type) +{ + if (brand == 0xff && type == 0x02) + return "CKD746 (4x6)"; + else if (brand == 0xff && type == 0x0f) + return "CKD768 (6x8)"; + else if (brand == 0x6c && type == 0x8f) + return "Kodak 6R (6x8)"; + else if (brand == 0x61 && type == 0x8f) + return "CKK76R (6x8)"; + else + return "Unknown"; +} + +#define CMDBUF_LEN 512 +#define READBACK_LEN 256 + +static void *mitsu70x_init(void) +{ + struct mitsu70x_ctx *ctx = malloc(sizeof(struct mitsu70x_ctx)); + if (!ctx) { + ERROR("Memory Allocation Failure!\n"); + return NULL; + } + memset(ctx, 0, sizeof(struct mitsu70x_ctx)); + + return ctx; +} + +static void mitsu70x_attach(void *vctx, struct libusb_device_handle *dev, + uint8_t endp_up, uint8_t endp_down, uint8_t jobid) +{ + struct mitsu70x_ctx *ctx = vctx; + struct libusb_device *device; + struct libusb_device_descriptor desc; + + ctx->jobid = jobid; + if (!ctx->jobid) + 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); + + ctx->type = lookup_printer_type(&mitsu70x_backend, + desc.idVendor, desc.idProduct); + + ctx->last_donor_l = ctx->last_donor_u = 65535;} + +static void mitsu70x_teardown(void *vctx) { + struct mitsu70x_ctx *ctx = vctx; + + if (!ctx) + return; + + if (ctx->databuf) + free(ctx->databuf); + free(ctx); +} + +static int mitsu70x_read_parse(void *vctx, int data_fd) { + struct mitsu70x_ctx *ctx = vctx; + int i, remain; + struct mitsu70x_hdr mhdr; + + if (!ctx) + return CUPS_BACKEND_FAILED; + + if (ctx->databuf) { + free(ctx->databuf); + ctx->databuf = NULL; + } + + ctx->matte = 0; + +repeat: + /* Read in initial header */ + remain = sizeof(mhdr); + while (remain > 0) { + i = read(data_fd, ((uint8_t*)&mhdr) + sizeof(mhdr) - remain, remain); + if (i == 0) + return CUPS_BACKEND_CANCEL; + if (i < 0) + return CUPS_BACKEND_CANCEL; + remain -= i; + } + + /* Skip over wakeup header if it's present. */ + if (mhdr.hdr[0] == 0x1b && + mhdr.hdr[1] == 0x45 && + mhdr.hdr[2] == 0x57 && + mhdr.hdr[3] == 0x55) { + goto repeat; + } + + /* Sanity check header */ + if (mhdr.hdr[0] != 0x1b && + mhdr.hdr[1] != 0x5a && + mhdr.hdr[2] != 0x54) { + ERROR("Unrecognized data format!\n"); + return CUPS_BACKEND_CANCEL; + } + +#ifdef ENABLE_CORRTABLES + ctx->raw_format = 1; // XXX until we define a new spool format for + // the data. Maybe reuse D90 header? + + /* Figure out the correction data table to use */ + if (ctx->type == P_MITSU_D70X) { + ctx->laminatefname = "D70MAT01.raw"; + ctx->lutfname = "CPD70L01.lut"; + + if (mhdr.speed == 3) { + ctx->corrdata = &CPD70S01_data; + ctx->corrdatalens = &CPD70S01_lengths; + } else if (mhdr.speed == 4) { + ctx->corrdata = &CPD70U01_data; + ctx->corrdatalens = &CPD70U01_lengths; + } else { + ctx->corrdata = &CPD70N01_data; + ctx->corrdatalens = &CPD70N01_lengths; + } + } else if (ctx->type == P_MITSU_D80) { + ctx->laminatefname = "D80MAT01.raw"; + ctx->lutfname = "CPD80L01.lut"; + + if (mhdr.speed == 3) { + ctx->corrdata = &CPD80S01_data; + ctx->corrdatalens = &CPD80S01_lengths; + } else if (mhdr.speed == 4) { + ctx->corrdata = &CPD80U01_data; + ctx->corrdatalens = &CPD80U01_lengths; + } else { + ctx->corrdata = &CPD80N01_data; + ctx->corrdatalens = &CPD80N01_lengths; + } + // XXX what about CPD80**E**01? + } else if (ctx->type == P_MITSU_K60) { + ctx->laminatefname = "S60MAT02.raw"; + ctx->lutfname = "CPS60L01.lut"; + + if (mhdr.speed == 3 || mhdr.speed == 4) { + ctx->corrdata = &CPS60T03_data; + ctx->corrdatalens = &CPS60T03_lengths; + } else { + ctx->corrdata = &CPS60T01_data; + ctx->corrdatalens = &CPS60T01_lengths; + } + + } else if (ctx->type == P_KODAK_305) { + ctx->laminatefname = "EK305MAT.raw"; // Same as K60 + ctx->lutfname = "EK305L01.lut"; + + if (mhdr.speed == 3 || mhdr.speed == 4) { + ctx->corrdata = &EK305T03_data; + ctx->corrdatalens = &EK305T03_lengths; + } else { + ctx->corrdata = &EK305T01_data; + ctx->corrdatalens = &EK305T01_lengths; + } + } else if (ctx->type == P_FUJI_ASK300) { + ctx->laminatefname = "ASK300M2.raw"; // Same as D70 + ctx->lutfname = "CPD70L01.lut"; // XXX guess! + + if (mhdr.speed == 3 || mhdr.speed == 4) { + ctx->corrdata = &ASK300T3_data; + ctx->corrdatalens = &ASK300T3_lengths; + } else { + ctx->corrdata = &ASK300T1_data; + ctx->corrdatalens = &ASK300T1_lengths; + } + } +#endif + + /* Work out printjob size */ + ctx->cols = be16_to_cpu(mhdr.cols); + ctx->rows = be16_to_cpu(mhdr.rows); + + remain = ctx->rows * ctx->cols * 2; + remain = (remain + 511) / 512 * 512; /* Round to nearest 512 bytes. */ + remain *= 3; /* One for each plane */ + + if (!mhdr.laminate && mhdr.laminate_mode) { + i = be16_to_cpu(mhdr.lamcols) * be16_to_cpu(mhdr.lamrows) * 2; + i = (i + 511) / 512 * 512; /* Round to nearest 512 bytes. */ + ctx->matte = i; + } + + ctx->databuf = malloc(sizeof(mhdr) + remain + ctx->matte); + if (!ctx->databuf) { + ERROR("Memory allocation failure!\n"); + return CUPS_BACKEND_FAILED; + } + + memcpy(ctx->databuf, &mhdr, sizeof(mhdr)); + ctx->datalen += sizeof(mhdr); + +#ifndef ENABLE_CORRTABLES + /* Read matte from spool... */ + remain += ctx->matte; +#endif + + /* Read in the spool data */ + 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; + ctx->datalen += i; + remain -= i; + } + +#ifdef ENABLE_CORRTABLES + /* Read matte from matte file */ + if (!ctx->raw_format && ctx->matte) { + int fd; + fd = open(ctx->laminatefname, O_RDONLY); + if (fd < 0) { + ERROR("Unable to open matte lamination data file '%s'\n", ctx->laminatefname); + return CUPS_BACKEND_CANCEL; + } + remain = ctx->matte; + while (remain) { + i = read(fd, ctx->databuf + ctx->datalen, remain); + if (i == 0) + return CUPS_BACKEND_CANCEL; + if (i < 0) + return CUPS_BACKEND_CANCEL; + ctx->datalen += i; + remain -= i; + } + } +#endif + + return CUPS_BACKEND_OK; +} + +static int mitsu70x_get_jobstatus(struct mitsu70x_ctx *ctx, struct mitsu70x_jobstatus *resp, uint16_t jobid) +{ + uint8_t cmdbuf[CMDBUF_LEN]; + int num, ret; + + /* Send Printer Query */ + memset(cmdbuf, 0, CMDBUF_LEN); + cmdbuf[0] = 0x1b; + cmdbuf[1] = 0x56; + cmdbuf[2] = 0x31; + cmdbuf[3] = 0x30; // XXX 30 == specific, 31 = "all" + + cmdbuf[4] = (jobid >> 8) & 0xff; + cmdbuf[5] = jobid & 0xff; + + if ((ret = send_data(ctx->dev, ctx->endp_down, + cmdbuf, 6))) + return ret; + + memset(resp, 0, sizeof(*resp)); + + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) resp, sizeof(*resp), &num); + + if (ret < 0) + return ret; + if (num != sizeof(*resp)) { + ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*resp)); + return 4; + } + + return 0; +} + +#ifdef BROKEN_ON_EK305 // XXX broken on EK305 +static int mitsu70x_get_jobs(struct mitsu70x_ctx *ctx, struct mitsu70x_jobs *resp) +{ + uint8_t cmdbuf[CMDBUF_LEN]; + int num, ret; + + /* Send Printer Query */ + memset(cmdbuf, 0, CMDBUF_LEN); + cmdbuf[0] = 0x1b; + cmdbuf[1] = 0x56; + cmdbuf[2] = 0x31; + cmdbuf[3] = 0x31; + cmdbuf[4] = 0x00; + cmdbuf[5] = 0x00; + + if ((ret = send_data(ctx->dev, ctx->endp_down, + cmdbuf, 6))) + return ret; + + memset(resp, 0, sizeof(*resp)); + + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) resp, sizeof(*resp), &num); + + if (ret < 0) + return ret; + if (num != sizeof(*resp)) { + ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*resp)); + return 4; + } + + return 0; +} +#endif + +static int mitsu70x_get_memorystatus(struct mitsu70x_ctx *ctx, struct mitsu70x_memorystatus_resp *resp) +{ + uint8_t cmdbuf[CMDBUF_LEN]; + + uint16_t tmp; + + int num; + int ret; + + memset(cmdbuf, 0, CMDBUF_LEN); + cmdbuf[0] = 0x1b; + cmdbuf[1] = 0x56; + cmdbuf[2] = 0x33; + cmdbuf[3] = 0x00; + tmp = cpu_to_be16(ctx->cols); + memcpy(cmdbuf + 4, &tmp, 2); + tmp = cpu_to_be16(ctx->rows); + memcpy(cmdbuf + 6, &tmp, 2); + cmdbuf[8] = ctx->matte ? 0x80 : 0x00; + cmdbuf[9] = 0x00; + + if ((ret = send_data(ctx->dev, ctx->endp_down, + cmdbuf, 10))) + return CUPS_BACKEND_FAILED; + + /* Read in the printer status */ + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) resp, sizeof(*resp), &num); + if (ret < 0) + return CUPS_BACKEND_FAILED; + + if (num != sizeof(*resp)) { + ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*resp)); + return CUPS_BACKEND_FAILED; + } + + /* Make sure response is sane */ + if (resp->hdr[0] != 0xe4 || + resp->hdr[1] != 0x56 || + resp->hdr[2] != 0x33) { + ERROR("Unknown response from printer\n"); + return CUPS_BACKEND_FAILED; + } + + return 0; +} + + +static int mitsu70x_get_printerstatus(struct mitsu70x_ctx *ctx, struct mitsu70x_printerstatus_resp *resp) +{ + uint8_t cmdbuf[CMDBUF_LEN]; + int num, ret; + + /* Send Printer Query */ + memset(cmdbuf, 0, CMDBUF_LEN); + cmdbuf[0] = 0x1b; + cmdbuf[1] = 0x56; + cmdbuf[2] = 0x32; + cmdbuf[3] = 0x30; + if ((ret = send_data(ctx->dev, ctx->endp_down, + cmdbuf, 4))) + return ret; + memset(resp, 0, sizeof(*resp)); + ret = read_data(ctx->dev, ctx->endp_up, + (uint8_t*) resp, sizeof(*resp), &num); + + if (ret < 0) + return ret; + if (num != sizeof(*resp)) { + ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*resp)); + return 4; + } + + return 0; +} + +static int mitsu70x_cancel_job(struct mitsu70x_ctx *ctx, uint16_t jobid) +{ + uint8_t cmdbuf[4]; + int ret; + + /* Send Job cancel. No response. */ + memset(cmdbuf, 0, 4); + cmdbuf[0] = 0x1b; + cmdbuf[1] = 0x44; + cmdbuf[2] = (jobid >> 8) & 0xff; + cmdbuf[3] = jobid & 0xffl; + if ((ret = send_data(ctx->dev, ctx->endp_down, + cmdbuf, 4))) + return ret; + + return 0; +} + +static int mitsu70x_set_sleeptime(struct mitsu70x_ctx *ctx, uint8_t time) +{ + uint8_t cmdbuf[4]; + int ret; + + /* Send Job cancel. No response. */ + memset(cmdbuf, 0, 4); + cmdbuf[0] = 0x1b; + cmdbuf[1] = 0x53; + cmdbuf[2] = 0x53; + cmdbuf[3] = time; + + if ((ret = send_data(ctx->dev, ctx->endp_down, + cmdbuf, 4))) + return ret; + + return 0; +} + +static int mitsu70x_main_loop(void *vctx, int copies) { + struct mitsu70x_ctx *ctx = vctx; + struct mitsu70x_jobstatus jobstatus; + struct mitsu70x_printerstatus_resp resp; +#ifdef BROKEN_ON_EK305 + struct mitsu70x_jobs jobs; +#endif + struct mitsu70x_hdr *hdr; + + int ret; + + if (!ctx) + return CUPS_BACKEND_FAILED; + + hdr = (struct mitsu70x_hdr*) ctx->databuf; + + INFO("Waiting for printer idle...\n"); + +top: + /* Query job status for jobid 0 (global) */ + ret = mitsu70x_get_jobstatus(ctx, &jobstatus, 0x0000); + if (ret) + return CUPS_BACKEND_FAILED; + + /* Make sure we're awake! */ + if (jobstatus.power) { + uint8_t buf[512]; + + memset(buf, 0, sizeof(buf)); + buf[0] = 0x1b; + buf[1] = 0x45; + buf[2] = 0x57; + buf[3] = 0x55; + + INFO("Waking up printer...\n"); + if ((ret = send_data(ctx->dev, ctx->endp_down, + buf, sizeof(buf)))) + return CUPS_BACKEND_FAILED; + sleep(1); + goto top; + } + + /* Make sure temperature is sane */ + if (jobstatus.temperature == TEMPERATURE_COOLING) { + INFO("Printer cooling down...\n"); + sleep(1); + goto top; + } + + /* See if we hit a printer error. */ + if (jobstatus.error_status[0]) { + ERROR("%s/%s -> %s: %02x/%02x/%02x\n", + mitsu70x_errorclass(jobstatus.error_status), + mitsu70x_errors(jobstatus.error_status), + mitsu70x_errorrecovery(jobstatus.error_status), + jobstatus.error_status[0], + jobstatus.error_status[1], + jobstatus.error_status[2]); + return CUPS_BACKEND_STOP; + } + + if (ctx->num_decks) + goto skip_status; + + /* Tell CUPS about the consumables we report */ + ret = mitsu70x_get_printerstatus(ctx, &resp); + if (ret) + return CUPS_BACKEND_FAILED; + + if (resp.upper.mecha_status[0] != MECHA_STATUS_INIT) + ctx->num_decks = 2; + else + ctx->num_decks = 1; + + if (ctx->type == P_MITSU_D70X && + ctx->num_decks == 2) { + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00,#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100,100\n"); + ATTR("marker-low-levels=10,10\n"); + ATTR("marker-names='\"%s\"','\"%s\"'\n", + mitsu70x_media_types(resp.lower.media_brand, resp.lower.media_type), + mitsu70x_media_types(resp.upper.media_brand, resp.upper.media_type)); + ATTR("marker-types=ribbonWax,ribbonWax\n"); + } else { + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='%s'\n", + mitsu70x_media_types(resp.lower.media_brand, resp.lower.media_type)); + ATTR("marker-types=ribbonWax\n"); + } + +skip_status: + /* Perform memory status query */ + { + struct mitsu70x_memorystatus_resp memory; + INFO("Checking Memory availability\n"); + + ret = mitsu70x_get_memorystatus(ctx, &memory); + if (ret) + return CUPS_BACKEND_FAILED; + + /* Check size is sane */ + if (memory.size || memory.memory == 0xff) { + ERROR("Unsupported print size!\n"); + return CUPS_BACKEND_CANCEL; + } + if (memory.memory) { + INFO("Printer buffers full, retrying!\n"); + sleep(1); + goto top; + } + } + +#ifdef BROKEN_ON_EK305 // XXX broken on K305, at least. + /* Make sure we don't have any jobid collisions */ + 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) + ctx->jobid++; + } +#endif + + /* Set jobid */ + hdr->jobid = cpu_to_be16(ctx->jobid); + + /* Set deck */ + if (ctx->type == P_MITSU_D70X) { + hdr->deck = 0; /* D70 use automatic deck selection */ + /* XXX alternatively route it based on state and media? */ + } else { + hdr->deck = 1; /* All others only have a "lower" deck. */ + } + + /* Matte operation requires Ultrafine/superfine */ + if (ctx->matte) { + if (ctx->type != P_MITSU_D70X) { + hdr->speed = 0x04; /* Force UltraFine */ + } else { + hdr->speed = 0x03; /* Force SuperFine */ + } + } + + /* Any other fixups? */ +#if 1 // XXX is this actually needed? + if ((ctx->type == P_MITSU_K60 || ctx->type == P_KODAK_305) && + ctx->cols == 0x0748 && + ctx->rows == 0x04c2) { + hdr->multicut = 1; // XXX only if print count even? + } +#endif + + /* We're clear to send data over! */ + INFO("Sending Print Job (internal id %u)\n", ctx->jobid); + + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->databuf, + sizeof(struct mitsu70x_hdr)))) + return CUPS_BACKEND_FAILED; + + { + /* K60 and 305 need data sent in 256K chunks, but the first + chunk needs to subtract the length of the 512-byte header */ + + // XXX is this special case actually needed? + int chunk = 256*1024 - sizeof(struct mitsu70x_hdr); + int sent = 512; + 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; + } + } + + /* Then wait for completion, if so desired.. */ + INFO("Waiting for printer to acknowledge completion\n"); + + do { + uint16_t donor_u, donor_l; + + sleep(1); + + ret = mitsu70x_get_printerstatus(ctx, &resp); + if (ret) + return CUPS_BACKEND_FAILED; + + donor_l = be16_to_cpu(resp.lower.remain) * 100 / be16_to_cpu(resp.lower.capacity); + + if (ctx->type == P_MITSU_D70X && + ctx->num_decks == 2) { + donor_u = be16_to_cpu(resp.upper.remain) * 100 / be16_to_cpu(resp.upper.capacity); + if (donor_l != ctx->last_donor_l || + donor_u != ctx->last_donor_u) { + ctx->last_donor_l = donor_l; + ctx->last_donor_u = donor_u; + ATTR("marker-levels=%d,%d\n", donor_l, donor_u); + } + } else { + if (donor_l != ctx->last_donor_l) { + ctx->last_donor_l = donor_l; + ATTR("marker-levels=%d\n", donor_l); + } + } + + /* Query job status for our used jobid */ + ret = mitsu70x_get_jobstatus(ctx, &jobstatus, ctx->jobid); + if (ret) + return CUPS_BACKEND_FAILED; + + /* See if we hit a printer error. */ + if (jobstatus.error_status[0]) { + ERROR("%s/%s -> %s: %02x/%02x/%02x\n", + mitsu70x_errorclass(jobstatus.error_status), + mitsu70x_errors(jobstatus.error_status), + mitsu70x_errorrecovery(jobstatus.error_status), + jobstatus.error_status[0], + jobstatus.error_status[1], + jobstatus.error_status[2]); + return CUPS_BACKEND_STOP; + } + + INFO("%s: %x/%x/%x/%x\n", + mitsu70x_jobstatuses(jobstatus.job_status), + jobstatus.job_status[0], + jobstatus.job_status[1], + jobstatus.job_status[2], + jobstatus.job_status[3]); + if (jobstatus.job_status[0] == JOB_STATUS0_END) { + if (jobstatus.job_status[1] || + jobstatus.job_status[2] || + jobstatus.job_status[3]) { + ERROR("Abnormal exit: %02x/%02x/%02x\n", + jobstatus.error_status[0], + jobstatus.error_status[1], + jobstatus.error_status[2]); + return CUPS_BACKEND_STOP; + } + /* Job complete */ + break; + } + + if (fast_return) { + INFO("Fast return mode enabled.\n"); + break; + } + } 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 void mitsu70x_dump_printerstatus(struct mitsu70x_printerstatus_resp *resp) +{ + unsigned int i; + + INFO("Model : "); + for (i = 0 ; i < 6 ; i++) { + DEBUG2("%c", le16_to_cpu(resp->model[i]) & 0x7f); + } + DEBUG2("\n"); + INFO("Serial Number : "); + for (i = 0 ; i < 6 ; i++) { + DEBUG2("%c", le16_to_cpu(resp->serno[i]) & 0x7f); + } + DEBUG2("\n"); + for (i = 0 ; i < 7 ; i++) { + char buf[7]; + 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)); + } + + INFO("Lower Mechanical Status: %s\n", + mitsu70x_mechastatus(resp->lower.mecha_status)); + if (resp->lower.error_status[0]) { + INFO("Lower Error Status: %s/%s -> %s\n", + mitsu70x_errorclass(resp->lower.error_status), + mitsu70x_errors(resp->lower.error_status), + mitsu70x_errorrecovery(resp->lower.error_status)); + } + INFO("Lower Media type: %s (%02x/%02x)\n", + mitsu70x_media_types(resp->lower.media_brand, resp->lower.media_type), + resp->lower.media_brand, + resp->lower.media_type); + INFO("Lower Prints remaining: %03d/%03d\n", + be16_to_cpu(resp->lower.remain), + be16_to_cpu(resp->lower.capacity)); + + if (resp->upper.mecha_status[0] != MECHA_STATUS_INIT) { + INFO("Upper Mechanical Status: %s\n", + mitsu70x_mechastatus(resp->upper.mecha_status)); + if (resp->upper.error_status[0]) { + INFO("Upper Error Status: %s/%s -> %s\n", + mitsu70x_errorclass(resp->upper.error_status), + mitsu70x_errors(resp->upper.error_status), + mitsu70x_errorrecovery(resp->upper.error_status)); + } + INFO("Upper Media type: %s (%02x/%02x)\n", + mitsu70x_media_types(resp->upper.media_brand, resp->upper.media_type), + resp->upper.media_brand, + resp->upper.media_type); + INFO("Upper Prints remaining: %03d/%03d\n", + be16_to_cpu(resp->upper.remain), + be16_to_cpu(resp->upper.capacity)); + } +} + +static int mitsu70x_query_status(struct mitsu70x_ctx *ctx) +{ + struct mitsu70x_printerstatus_resp resp; +#ifdef BROKEN_ON_EK305 + struct mitsu70x_jobs jobs; +#endif + int ret; + + ret = mitsu70x_get_printerstatus(ctx, &resp); + if (!ret) + mitsu70x_dump_printerstatus(&resp); + +#ifdef BROKEN_ON_EK305 // XXX broken on EK305, at least + 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? + } +#endif + + return ret; +} + +static int mitsu70x_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len) +{ + int ret, i; + struct mitsu70x_printerstatus_resp resp = { .hdr = { 0 } }; + + struct mitsu70x_ctx ctx = { + .dev = dev, + .endp_up = endp_up, + .endp_down = endp_down, + }; + + ret = mitsu70x_get_printerstatus(&ctx, &resp); + + if (buf_len > 6) /* Will we ever have a buffer under 6 bytes? */ + buf_len = 6; + + for (i = 0 ; i < buf_len ; i++) { + *buf++ = le16_to_cpu(resp.serno[i]) & 0x7f; + } + *buf = 0; /* Null-terminate the returned string */ + + return ret; +} + + +static void mitsu70x_cmdline(void) +{ + DEBUG("\t\t[ -s ] # Query status\n"); + DEBUG("\t\t[ -f ] # Use fast return mode\n"); + DEBUG("\t\t[ -k num ] # Set standby time (1-60 minutes, 0 disables)\n"); + DEBUG("\t\t[ -X jobid ] # Abort a printjob\n");} + +static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv) +{ + struct mitsu70x_ctx *ctx = vctx; + int i, j = 0; + + if (!ctx) + return -1; + + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "sX:k:")) >= 0) { + switch(i) { + GETOPT_PROCESS_GLOBAL + case 'k': + j = mitsu70x_set_sleeptime(ctx, atoi(optarg)); + break; + case 's': + j = mitsu70x_query_status(ctx); + break; + case 'X': + j = mitsu70x_cancel_job(ctx, atoi(optarg)); + break; + default: + break; /* Ignore completely */ + } + + if (j) return j; + } + + return 0; +} + + +/* Exported */ +struct dyesub_backend mitsu70x_backend = { + .name = "Mitsubishi CP-D70/D707/K60/D80", + .version = "0.41WIP", + .uri_prefix = "mitsu70x", + .cmdline_usage = mitsu70x_cmdline, + .cmdline_arg = mitsu70x_cmdline_arg, + .init = mitsu70x_init, + .attach = mitsu70x_attach, + .teardown = mitsu70x_teardown, + .read_parse = mitsu70x_read_parse, + .main_loop = mitsu70x_main_loop, + .query_serno = mitsu70x_query_serno, + .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_KODAK, USB_PID_KODAK305, P_KODAK_305, ""}, +// { USB_VID_FUJIFILM, USB_PID_FUJI_ASK300, P_FUJI_ASK300, ""}, + { 0, 0, 0, ""} + } +}; + +/* Mitsubish CP-D70DW/CP-D707DW/CP-K60DW-S/CP-D80DW/Kodak 305 data format + + Spool file consists of two headers followed by three image planes + and an optional lamination data plane. All blocks are rounded up to + a 512-byte boundary. + + All multi-byte numbers are big endian, ie MSB first. + + Header 1: (Init) (AKA Wake Up) + + 1b 45 57 55 00 00 00 00 00 00 00 00 00 00 00 00 + (padded by NULLs to a 512-byte boundary) + + Header 2: (Header) + + 1b 5a 54 PP JJ JJ 00 00 00 00 00 00 00 00 00 00 + XX XX YY YY QQ QQ ZZ ZZ SS 00 00 00 00 00 00 00 + UU 00 00 00 00 00 00 00 00 TT 00 00 00 00 00 00 + RR 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + (padded by NULLs to a 512-byte boundary) + + PP == 0x01 on D70x/D80, 0x02 on K60, 0x90 on K305 + JJ JJ == Job ID, can leave at 00 00 + XX XX == columns + YY YY == rows + QQ QQ == lamination columns (equal to XX XX) + ZZ ZZ == lamination rows (YY YY + 12) + SS == Print mode: 00 = Fine, 03 = SuperFine (D70x/D80 only), 04 = UltraFine + (Matte requires Superfine or Ultrafine) + UU == 00 = Auto, 01 = Lower Deck (required for !D70x), 02 = Upper Deck + TT == lamination: 00 glossy, 02 matte. + RR == 00 (normal), 01 = (Double-cut 4x6), 05 = (double-cut 2x6) + + Data planes: + 16-bit data, rounded up to 512-byte block (XX * YY * 2 bytes) + + Lamination plane: (only present if QQ and ZZ are nonzero) + 16-byte data, rounded up to 512-byte block (QQ * ZZ * 2 bytes) + + ******************************************************************** + + Command format: + + -> 1b 56 32 30 + <- [256 byte payload] + + PRINTER STATUS + + e4 56 32 30 00 00 00 00 00 00 00 00 00 00 00 00 .V20............ + 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 ................ + 44 80 00 00 5f 00 00 3d 43 00 50 00 44 00 37 00 D..._..=C.P.D.7. + 30 00 44 00 30 00 30 00 31 00 31 00 31 00 37 00 0.D.0.0.1.1.1.7. + 33 31 36 54 31 33 21 a3 33 31 35 42 31 32 f5 e5 316T13!.315B12.. + 33 31 39 42 31 31 a3 fb 33 31 38 45 31 32 50 0d 319B11..318E12P. + 33 31 37 41 32 32 a3 82 44 55 4d 4d 59 40 00 00 317A22..DUMMY@.. + 44 55 4d 4d 59 40 00 00 00 00 00 00 00 00 00 00 DUMMY@.......... + + LOWER DECK STATUS + + 00 00 00 00 00 00 02 04 3f 00 00 04 96 00 00 00 MM MM: media capacity + ff 0f 01 00 MM MM NN NN 00 00 00 00 05 28 75 80 NN NN: prints remaining + 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 + 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 + + alt (some sort of error state) + + 00 00 00 0a 05 05 01 d5 38 00 00 00 14 00 00 00 + ff ff ff ff ff ff ff ff ff ff 00 00 00 27 72 80 + 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 + 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 + + UPPER DECK STATUS (if present) + + XX XX 00 00 00 00 01 ee 3d 00 00 06 39 00 00 00 MM MM: media capacity + ff 02 00 00 MM MM NN NN 00 00 00 00 06 67 78 00 NN NN: prints remaining + 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 XX XX: 0x80 00 if no deck + 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 + + alt (no deck present) + + 80 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 + ff ff ff ff ff ff ff ff ff ff 00 00 00 00 80 00 + 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 + 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 + + -> 1b 56 31 30 00 00 + <- [26 byte payload] + + CP-D707DW: + + e4 56 31 30 00 00 00 XX YY ZZ 00 00 TT 00 00 00 + 00 00 00 00 WW 00 00 00 00 00 + + XX/YY/ZZ and WW/TT are unknown. Observed values: + + 00 00 00 00/00 + 40 80 a0 80/0f + 80 80 a0 + 40 80 90 + 40 80 00 + + also seen: + + e4 56 31 30 00 00 00 00 00 00 00 00 0f 00 00 00 + 00 0a 05 05 80 00 00 00 00 00 + + e4 56 31 30 00 00 00 40 80 90 10 00 0f 00 00 00 + 00 0a 05 05 80 00 00 00 00 00 + + e4 56 31 30 00 00 00 00 40 80 00 00 00 ff 40 00 + 00 00 00 00 80 00 00 00 00 00 + + print just submitted: + + e4 56 31 30 00 00 00 00 40 20 00 00 00 8c 00 00 + 00 00 00 00 80 00 00 00 00 00 + + prints running... + + e4 56 31 30 00 00 00 00 40 20 00 00 00 cf 00 20 + 00 00 00 00 80 00 00 00 00 00 + + CP-K60DW-S: + + e4 56 31 30 00 00 00 XX YY 00 00 00 0f 00 00 00 + 00 00 00 00 80 00 00 00 00 00 + + XX/YY are unknown, observed values: + + 40/80 + 00/00 + + Memory status query: + + -> 1b 56 33 00 XX XX YY YY UU 00 + + XX XX == columns + YY YY == rows + UU == 0x00 glossy, 0x80 matte + + <- [ 6 byte payload ] + + e4 56 33 00 00 00 + e4 56 33 00 00 01 + e4 56 33 ff 01 01 + + |--- Size check, 00 ok, 01 fail + |------ Memory check, 00 ok, 01 fail, ff bad size + + ** ** ** ** ** ** + + The windows drivers seem to send the id and status queries before + and in between each of the chunks sent to the printer. There doesn't + appear to be any particular intelligence in the protocol, but it didn't + work when the raw dump was submitted as-is. + + ** ** ** ** ** ** + +Various deck status dumps: + +0080 00 00 00 00 00 00 01 d2 39 00 00 00 07 00 00 00 ........9....... +0090 61 8f 00 00 01 40 01 36 00 00 00 00 00 17 79 80 a....@.6......y. + +0080 00 00 00 00 00 00 01 c6 39 00 00 00 08 00 00 00 ........9....... +0090 61 8f 00 00 01 40 01 35 00 00 00 00 00 18 79 80 a....@.5......y. + +0080 00 00 00 00 00 00 02 19 50 00 00 00 19 00 00 01 ........P....... +0090 6c 8f 00 00 01 40 01 22 00 00 00 00 00 27 83 80 l....@.".....'.. + +0080 00 00 00 00 00 00 02 00 3e 00 00 04 96 00 00 00 ........>....... +0090 ff 0f 01 00 00 c8 00 52 00 00 00 00 05 28 75 80 .......R.....(u. + +00c0 00 00 00 00 00 00 01 f3 3d 00 00 06 39 00 00 00 ........=...9... +00d0 ff 02 00 00 01 90 00 c3 00 00 00 00 06 67 78 00 .............gx. + +0080 00 00 00 00 00 00 01 d0 38 00 00 03 70 00 00 00 ........8...p... +0090 ff 02 00 00 01 90 00 1e 01 00 00 00 03 83 72 80 ..............r. + +0080 00 00 00 00 00 00 01 d6 39 00 00 00 20 00 00 00 ........9... ... +0090 ff 02 00 00 01 90 01 7c 01 00 00 00 00 33 72 80 .......|.....3r. + + 00 00 00 0a 05 05 01 d5 38 00 00 00 14 00 00 00 + ff ff ff ff ff ff ff ff ff ff 00 00 00 27 72 80 ?? Error ?? + + 80 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 + ff ff ff ff ff ff ff ff ff ff 00 00 00 00 80 00 NO DECK PRESENT + */ diff --git a/src/cups/mitsu9550_print.c b/src/cups/backend_mitsu9550.c index 952baa3..d257227 100644 --- a/src/cups/mitsu9550_print.c +++ b/src/cups/backend_mitsu9550.c @@ -1,7 +1,7 @@ /* * Mitsubishi CP-9550DW[-S] Photo Printer CUPS backend * - * (c) 2014-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2014-2016 Solomon Peachy <pizza@shaftnet.org> * * The latest version of this program can be found at: * @@ -57,6 +57,10 @@ struct mitsu9550_ctx { uint16_t rows; uint16_t cols; + + uint16_t last_donor; + uint16_t last_remain; + int marker_reported; }; /* Spool file structures */ @@ -141,6 +145,63 @@ struct mitsu9550_status2 { #define CMDBUF_LEN 64 #define READBACK_LEN 128 +#define QUERY_STATUS() \ + do {\ + struct mitsu9550_status *sts = (struct mitsu9550_status*) rdbuf;\ + /* struct mitsu9550_status2 *sts2 = (struct mitsu9550_status2*) rdbuf; */ \ + struct mitsu9550_media *media = (struct mitsu9550_media *) rdbuf; \ + uint16_t donor, remain; \ + /* media */ \ + ret = mitsu9550_get_status(ctx, rdbuf, 0, 0, 1); \ + if (ret < 0) \ + return CUPS_BACKEND_FAILED; \ + \ + /* Tell CUPS about the consumables we report */ \ + if (!ctx->marker_reported) { \ + ctx->marker_reported = 1; \ + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); \ + ATTR("marker-high-levels=100\n"); \ + ATTR("marker-low-levels=10\n"); \ + ATTR("marker-names='%s'\n", mitsu9550_media_types(media->type)); \ + ATTR("marker-types=ribbonWax\n"); \ + } \ + \ + /* Sanity-check media response */ \ + if (media->remain == 0 || media->max == 0) { \ + ERROR("Printer out of media!\n"); \ + ATTR("marker-levels=%d\n", 0); \ + return CUPS_BACKEND_HOLD; \ + } \ + donor = be16_to_cpu(media->remain)/be16_to_cpu(media->max); \ + if (donor != ctx->last_donor) { \ + ctx->last_donor = donor; \ + ATTR("marker-levels=%u\n", donor); \ + } \ + remain = be16_to_cpu(media->remain); \ + if (remain != ctx->last_remain) { \ + ctx->last_remain = remain; \ + ATTR("marker-message=\"%u prints remaining on '%s' ribbon\"\n", remain, mitsu9550_media_types(media->type)); \ + } \ + if (validate_media(media->type, ctx->cols, ctx->rows)) { \ + ERROR("Incorrect media (%u) type for printjob (%ux%u)!\n", media->type, ctx->cols, ctx->rows); \ + return CUPS_BACKEND_HOLD; \ + } \ + /* status2 */ \ + ret = mitsu9550_get_status(ctx, rdbuf, 0, 1, 0); \ + if (ret < 0) \ + return CUPS_BACKEND_FAILED; \ + /* status */ \ + ret = mitsu9550_get_status(ctx, rdbuf, 1, 0, 0); \ + if (ret < 0) \ + return CUPS_BACKEND_FAILED; \ + \ + /* Make sure we're idle */ \ + if (sts->sts5 != 0) { /* Printer ready for another job */ \ + sleep(1); \ + goto top; \ + } \ + } while (0); + static void *mitsu9550_init(void) { struct mitsu9550_ctx *ctx = malloc(sizeof(struct mitsu9550_ctx)); @@ -170,7 +231,9 @@ static void mitsu9550_attach(void *vctx, struct libusb_device_handle *dev, libusb_get_device_descriptor(device, &desc); ctx->type = lookup_printer_type(&mitsu9550_backend, - desc.idVendor, desc.idProduct); + desc.idVendor, desc.idProduct); + + ctx->last_donor = ctx->last_remain = 65535; } @@ -282,6 +345,27 @@ static int mitsu9550_get_status(struct mitsu9550_ctx *ctx, uint8_t *resp, int st return 0; } +static char *mitsu9550_media_types(uint8_t type) +{ + switch (type) { + case 0x01: + return "3.5x5"; + case 0x02: + return "4x6"; + case 0x03: + return "PC"; + case 0x04: + return "5x7"; + case 0x05: + return "6x9"; + case 0x06: + return "V"; + default: + return "Unknown"; + } + return NULL; +} + static int validate_media(int type, int cols, int rows) { switch(type) { case 0x01: /* 3.5x5 */ @@ -322,9 +406,8 @@ static int mitsu9550_main_loop(void *vctx, int copies) { struct mitsu9550_hdr2 *hdr2; struct mitsu9550_cmd cmd; uint8_t rdbuf[READBACK_LEN]; - uint8_t *ptr; - + int ret; if (!ctx) @@ -335,11 +418,11 @@ static int mitsu9550_main_loop(void *vctx, int copies) { hdr2->copies = cpu_to_be16(copies); ptr = ctx->databuf; - + top: if (ctx->type == P_MITSU_9550S) { int num; - + /* Send "unknown 1" command */ cmd.cmd[0] = 0x1b; cmd.cmd[1] = 0x53; @@ -348,7 +431,7 @@ top: if ((ret = send_data(ctx->dev, ctx->endp_down, (uint8_t*) &cmd, sizeof(cmd)))) return CUPS_BACKEND_FAILED; - + /* Send "unknown 2" command */ cmd.cmd[0] = 0x1b; cmd.cmd[1] = 0x4b; @@ -357,7 +440,7 @@ top: if ((ret = send_data(ctx->dev, ctx->endp_down, (uint8_t*) &cmd, sizeof(cmd)))) return CUPS_BACKEND_FAILED; - + ret = read_data(ctx->dev, ctx->endp_up, rdbuf, READBACK_LEN, &num); if (ret < 0) @@ -365,43 +448,10 @@ top: // seen so far: eb 4b 7f 00 02 00 5e } - /* Query statuses */ - { - struct mitsu9550_status *sts = (struct mitsu9550_status*) rdbuf; - //struct mitsu9550_status2 *sts2 = (struct mitsu9550_status2*) rdbuf; - struct mitsu9550_media *media = (struct mitsu9550_media *) rdbuf; - - ret = mitsu9550_get_status(ctx, rdbuf, 0, 0, 1); // media - if (ret < 0) - return CUPS_BACKEND_FAILED; - - /* Sanity-check media response */ - if (media->remain == 0 || media->max == 0) { - ERROR("Printer out of media!\n"); - return CUPS_BACKEND_HOLD; - } - if (validate_media(media->type, ctx->cols, ctx->rows)) { - ERROR("Incorrect media (%d) type for printjob (%dx%d)!\n", media->type, ctx->cols, ctx->rows); - return CUPS_BACKEND_HOLD; - } - - ret = mitsu9550_get_status(ctx, rdbuf, 0, 1, 0); // status2 - if (ret < 0) - return CUPS_BACKEND_FAILED; - - ret = mitsu9550_get_status(ctx, rdbuf, 1, 0, 0); // status - if (ret < 0) - return CUPS_BACKEND_FAILED; - - /* Make sure we're idle */ - if (sts->sts5 != 0) { /* Printer ready for another job */ - sleep(1); - goto top; - } - } + QUERY_STATUS(); /* Now it's time for the actual print job! */ - + if (ctx->type == P_MITSU_9550S) { cmd.cmd[0] = 0x1b; cmd.cmd[1] = 0x44; @@ -411,41 +461,8 @@ top: (uint8_t*) &cmd, 4))) return CUPS_BACKEND_FAILED; } - - /* Query statuses */ - { - struct mitsu9550_status *sts = (struct mitsu9550_status*) rdbuf; -// struct mitsu9550_status2 *sts2 = (struct mitsu9550_status2*) rdbuf; - struct mitsu9550_media *media = (struct mitsu9550_media *) rdbuf; - ret = mitsu9550_get_status(ctx, rdbuf, 0, 0, 1); // media - if (ret < 0) - return CUPS_BACKEND_FAILED; - - /* Sanity-check media response */ - if (media->remain == 0 || media->max == 0) { - ERROR("Printer out of media!\n"); - return CUPS_BACKEND_HOLD; - } - if (validate_media(media->type, ctx->cols, ctx->rows)) { - ERROR("Incorrect media (%d) type for printjob (%dx%d)!\n", media->type, ctx->cols, ctx->rows); - return CUPS_BACKEND_HOLD; - } - - ret = mitsu9550_get_status(ctx, rdbuf, 0, 1, 0); // status2 - if (ret < 0) - return CUPS_BACKEND_FAILED; - - ret = mitsu9550_get_status(ctx, rdbuf, 1, 0, 0); // status - if (ret < 0) - return CUPS_BACKEND_FAILED; - - /* Make sure we're idle */ - if (sts->sts5 != 0) { /* Printer ready for another job */ - sleep(1); - goto top; - } - } + QUERY_STATUS(); /* Send printjob headers from spool data */ if ((ret = send_data(ctx->dev, ctx->endp_down, @@ -513,6 +530,7 @@ top: struct mitsu9550_status *sts = (struct mitsu9550_status*) rdbuf; // struct mitsu9550_status2 *sts2 = (struct mitsu9550_status2*) rdbuf; struct mitsu9550_media *media = (struct mitsu9550_media *) rdbuf; + uint16_t donor, remain; ret = mitsu9550_get_status(ctx, rdbuf, 0, 0, 1); // media if (ret < 0) @@ -521,8 +539,19 @@ top: /* Sanity-check media response */ if (media->remain == 0 || media->max == 0) { ERROR("Printer out of media!\n"); + ATTR("marker-levels=%d\n", 0); return CUPS_BACKEND_HOLD; } + donor = be16_to_cpu(media->remain)/be16_to_cpu(media->max); + if (donor != ctx->last_donor) { + ctx->last_donor = donor; + ATTR("marker-levels=%d\n", donor); + } + remain = be16_to_cpu(media->remain); + if (remain != ctx->last_remain) { + ctx->last_remain = remain; + ATTR("marker-message=\"%u prints remaining on '%s' ribbon\"\n", remain, mitsu9550_media_types(media->type)); + } ret = mitsu9550_get_status(ctx, rdbuf, 0, 1, 0); // status2 if (ret < 0) @@ -565,7 +594,8 @@ top: struct mitsu9550_status *sts = (struct mitsu9550_status*) rdbuf; // struct mitsu9550_status2 *sts2 = (struct mitsu9550_status2*) rdbuf; struct mitsu9550_media *media = (struct mitsu9550_media *) rdbuf; - + uint16_t donor, remain; + ret = mitsu9550_get_status(ctx, rdbuf, 0, 0, 1); // media if (ret < 0) return CUPS_BACKEND_FAILED; @@ -573,13 +603,24 @@ top: /* Sanity-check media response */ if (media->remain == 0 || media->max == 0) { ERROR("Printer out of media!\n"); + ATTR("marker-levels=%d\n", 0); return CUPS_BACKEND_HOLD; } + donor = be16_to_cpu(media->remain)/be16_to_cpu(media->max); + if (donor != ctx->last_donor) { + ctx->last_donor = donor; + ATTR("marker-levels=%d\n", donor); + } + remain = be16_to_cpu(media->remain); + if (remain != ctx->last_remain) { + ctx->last_remain = remain; + ATTR("marker-message=\"%u prints remaining on '%s' ribbon\"\n", remain, mitsu9550_media_types(media->type)); + } ret = mitsu9550_get_status(ctx, rdbuf, 0, 1, 0); // status2 if (ret < 0) return CUPS_BACKEND_FAILED; - + ret = mitsu9550_get_status(ctx, rdbuf, 1, 0, 0); // status if (ret < 0) return CUPS_BACKEND_FAILED; @@ -601,33 +642,12 @@ top: sleep(1); } - + INFO("Print complete\n"); return CUPS_BACKEND_OK; } -static char *mitsu9550_media_types(uint8_t type) -{ - switch (type) { - case 0x01: - return "3.5x5"; - case 0x02: - return "4x6"; - case 0x03: - return "PC"; - case 0x04: - return "5x7"; - case 0x05: - return "6x9"; - case 0x06: - return "V"; - default: - return "Unknown"; - } - return NULL; -} - static void mitsu9550_dump_media(struct mitsu9550_media *resp) { INFO("Media type : %02x (%s)\n", @@ -644,7 +664,6 @@ static void mitsu9550_dump_status(struct mitsu9550_status *resp) be16_to_cpu(resp->copies)); INFO("Other status : %02x %02x %02x %02x %02x\n", resp->sts3, resp->sts4, resp->sts5, resp->sts6, resp->sts7); - } static int mitsu9550_query_media(struct mitsu9550_ctx *ctx) @@ -707,7 +726,7 @@ static int mitsu9550_query_serno(struct libusb_device_handle *dev, uint8_t endp_ /* If response is truncated, handle it */ num -= (sizeof(cmd) + 1); if ((unsigned int) num != rdbuf[4]) - WARNING("Short serno read! (%d vs %d)\r\n", + WARNING("Short serno read! (%d vs %u)\r\n", num, rdbuf[4]); /* model and serial number are encoded as 16-bit unicode, @@ -740,12 +759,9 @@ static int mitsu9550_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - /* Reset arg parsing */ - optind = 1; - opterr = 0; while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "ms")) >= 0) { switch(i) { - GETOPT_PROCESS_GLOBAL + GETOPT_PROCESS_GLOBAL case 'm': j = mitsu9550_query_media(ctx); break; @@ -765,7 +781,7 @@ static int mitsu9550_cmdline_arg(void *vctx, int argc, char **argv) /* Exported */ struct dyesub_backend mitsu9550_backend = { .name = "Mitsubishi CP-9550DW-S", - .version = "0.15", + .version = "0.16", .uri_prefix = "mitsu9550", .cmdline_usage = mitsu9550_cmdline, .cmdline_arg = mitsu9550_cmdline_arg, diff --git a/src/cups/shinko_s1245_print.c b/src/cups/backend_shinkos1245.c index 72b5ec9..b375cba 100644 --- a/src/cups/shinko_s1245_print.c +++ b/src/cups/backend_shinkos1245.c @@ -1,7 +1,7 @@ /* * Shinko/Sinfonia CHC-S1245 CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2015-2016 Solomon Peachy <pizza@shaftnet.org> * * Low-level documentation was provided by Sinfonia, Inc. Thank you! * @@ -271,8 +271,6 @@ enum { CURVE_TABLE_STATUS_CURRENT = 0x02, }; -// XXX Paper jam has 0x01 -> 0xff as error codes - /* Query media info */ struct shinkos1245_cmd_getmedia { struct shinkos1245_cmd_hdr hdr; @@ -608,6 +606,30 @@ static int shinkos1245_canceljob(struct shinkos1245_ctx *ctx, return 0; } +static int shinkos1245_reset(struct shinkos1245_ctx *ctx) +{ + struct shinkos1245_cmd_reset cmd; + struct shinkos1245_resp_status sts; + + int ret, num; + + shinkos1245_fill_hdr(&cmd.hdr); + cmd.cmd[0] = 0xc0; + + ret = shinkos1245_do_cmd(ctx, &cmd, sizeof(cmd), + &sts, sizeof(sts), &num); + if (ret < 0) { + ERROR("Failed to execute RESET command\n"); + return ret; + } + if (sts.code != CMD_CODE_OK) { + ERROR("Bad return code on RESET command\n"); + return -99; + } + return 0; +} + + static int shinkos1245_set_matte(struct shinkos1245_ctx *ctx, int intensity) { @@ -868,26 +890,26 @@ static void shinkos1245_dump_status(struct shinkos1245_resp_status *sts) shinkos1245_status_str(sts), sts->state.status1, sts->state.status2, sts->state.error); INFO("Counters:\n"); - INFO("\tLifetime : %d\n", be32_to_cpu(sts->counters.lifetime)); - INFO("\tThermal Head : %d\n", be32_to_cpu(sts->counters.maint)); - INFO("\tMedia : %d\n", be32_to_cpu(sts->counters.media)); - INFO("\tCutter : %d\n", be32_to_cpu(sts->counters.cutter)); + INFO("\tLifetime : %u\n", be32_to_cpu(sts->counters.lifetime)); + INFO("\tThermal Head : %u\n", be32_to_cpu(sts->counters.maint)); + INFO("\tMedia : %u\n", be32_to_cpu(sts->counters.media)); + INFO("\tCutter : %u\n", be32_to_cpu(sts->counters.cutter)); INFO("Versions:\n"); - INFO("\tUSB Boot : %d\n", sts->counters.ver_boot); - INFO("\tUSB Control : %d\n", sts->counters.ver_ctrl); - INFO("\tMain Boot : %d\n", be16_to_cpu(sts->versions.main_boot)); - INFO("\tMain Control: %d\n", be16_to_cpu(sts->versions.main_control)); - INFO("\tDSP Boot : %d\n", be16_to_cpu(sts->versions.dsp_boot)); - INFO("\tDSP Control : %d\n", be16_to_cpu(sts->versions.dsp_control)); + INFO("\tUSB Boot : %u\n", sts->counters.ver_boot); + INFO("\tUSB Control : %u\n", sts->counters.ver_ctrl); + INFO("\tMain Boot : %u\n", be16_to_cpu(sts->versions.main_boot)); + INFO("\tMain Control: %u\n", be16_to_cpu(sts->versions.main_control)); + INFO("\tDSP Boot : %u\n", be16_to_cpu(sts->versions.dsp_boot)); + INFO("\tDSP Control : %u\n", be16_to_cpu(sts->versions.dsp_control)); // INFO("USB TypeFlag: %02x\n", sts->counters.control_flag); - INFO("Bank 1 ID: %d\n", sts->counters2.bank1_id); + INFO("Bank 1 ID: %u\n", sts->counters2.bank1_id); INFO("\tPrints: %d/%d complete\n", be16_to_cpu(sts->counters2.bank1_complete), be16_to_cpu(sts->counters2.bank1_spec)); - INFO("Bank 2 ID: %d\n", sts->counters2.bank2_id); + INFO("Bank 2 ID: %u\n", sts->counters2.bank2_id); INFO("\tPrints: %d/%d complete\n", be16_to_cpu(sts->counters2.bank2_complete), be16_to_cpu(sts->counters2.bank2_spec)); @@ -917,7 +939,7 @@ static void shinkos1245_dump_media(struct shinkos1245_mediadesc *medias, INFO("Supported print sizes: %d\n", count); for (i = 0 ; i < count ; i++) { - INFO("\t %02x: %04d*%04d (%02x/%02d)\n", + INFO("\t %02x: %04u*%04u (%02x/%02u)\n", medias[i].print_type, medias[i].columns, medias[i].rows, @@ -1042,7 +1064,7 @@ static int set_tonecurve(struct shinkos1245_ctx *ctx, int type, int table, char struct shinkos1245_cmd_tone cmd; struct shinkos1245_resp_status resp; - INFO("Read %d/%d Tone Curve from '%s'\n", type, table, fname); // XXX + INFO("Read %d/%d Tone Curve from '%s'\n", type, table, fname); /* Allocate space */ remaining = TONE_CURVE_SIZE; @@ -1152,6 +1174,7 @@ static void shinkos1245_cmdline(void) DEBUG("\t\t[ -s ] # Query status\n"); DEBUG("\t\t[ -u ] # Query user string\n"); DEBUG("\t\t[ -U sometext ] # Set user string\n"); + DEBUG("\t\t[ -R ] # Reset printer\n"); DEBUG("\t\t[ -X jobid ] # Abort a printjob\n"); DEBUG("\t\t[ -F ] # Tone curve refers to FINE mode\n"); DEBUG("\t\t[ -c filename ] # Get user/NV tone curve\n"); @@ -1168,7 +1191,7 @@ int shinkos1245_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:l:L:FmsuU:X:")) >= 0) { + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:l:L:FmRsuU:X:")) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL case 'F': @@ -1191,6 +1214,9 @@ int shinkos1245_cmdline_arg(void *vctx, int argc, char **argv) if (!j) shinkos1245_dump_media(ctx->medias, ctx->num_medias); break; + case 'R': + j = shinkos1245_reset(ctx); + break; case 's': { struct shinkos1245_resp_status sts; j = shinkos1245_get_status(ctx, &sts); @@ -1257,7 +1283,9 @@ static void shinkos1245_attach(void *vctx, struct libusb_device_handle *dev, desc.idVendor, desc.idProduct); /* Ensure jobid is sane */ - ctx->jobid = (jobid & 0x7f) + 1; + ctx->jobid = jobid & 0x7f; + if (!ctx->jobid) + ctx->jobid++; } @@ -1298,7 +1326,7 @@ static int shinkos1245_read_parse(void *vctx, int data_fd) { ctx->hdr.model = le32_to_cpu(ctx->hdr.model); if(ctx->hdr.model != 1245) { - ERROR("Unrecognized printer (%d)!\n", ctx->hdr.model); + ERROR("Unrecognized printer (%u)!\n", ctx->hdr.model); return CUPS_BACKEND_CANCEL; } @@ -1365,8 +1393,6 @@ static int shinkos1245_main_loop(void *vctx, int copies) { int i, num, last_state = -1, state = S_IDLE; struct shinkos1245_resp_status status1, status2; - // XXX query printer info - /* Query Media information if necessary */ if (!ctx->num_medias) shinkos1245_get_media(ctx); @@ -1388,7 +1414,7 @@ static int shinkos1245_main_loop(void *vctx, int copies) { } /* Fix max print count. */ - if (copies > 9999) // XXX test against remaining media + if (copies > 9999) // XXX test against remaining media? copies = 9999; top: @@ -1404,7 +1430,7 @@ top: if (memcmp(&status1, &status2, sizeof(status1))) { memcpy(&status2, &status1, sizeof(status1)); - // status changed, check for errors and whatnot + // status changed. } else if (state == last_state) { sleep(1); goto top; @@ -1420,8 +1446,6 @@ top: switch (state) { case S_IDLE: - INFO("Waiting for printer idle\n"); - if (status1.state.status1 == STATE_STATUS1_STANDBY) { state = S_PRINTER_READY_CMD; break; @@ -1431,12 +1455,26 @@ top: state = S_PRINTER_READY_CMD; break; } - - // XXX what about STATUS_WAIT ? - // XXX see if printer has an empty bank? - +#if 0 // XXX is this necessary + if (status1.state.status1 == STATE_STATUS1_WAIT) { + INFO("Printer busy: %s\n", + shinkos1245_status_str(&status1)); + break; + } +#endif /* If the printer is "busy" check to see if there's any open memory banks so we can queue the next print */ + + /* make sure we're not colliding with an existing + jobid */ + while (ctx->jobid == status1.counters2.bank1_id || + ctx->jobid == status1.counters2.bank2_id) { + ctx->jobid++; + ctx->jobid &= 0x7f; + if (!ctx->jobid) + ctx->jobid++; + } + if (!status1.counters2.bank1_remain || !status1.counters2.bank2_remain) { state = S_PRINTER_READY_CMD; @@ -1465,7 +1503,7 @@ top: } } - INFO("Initiating print job (internal id %d)\n", ctx->jobid); + INFO("Sending print job (internal id %u)\n", ctx->jobid); shinkos1245_fill_hdr(&cmd.hdr); cmd.cmd[0] = 0x0a; @@ -1582,7 +1620,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.07WIP", + .version = "0.09WIP", .uri_prefix = "shinkos1245", .cmdline_usage = shinkos1245_cmdline, .cmdline_arg = shinkos1245_cmdline_arg, diff --git a/src/cups/shinko_s2145_print.c b/src/cups/backend_shinkos2145.c index c6fd88f..ec7bcd6 100644 --- a/src/cups/shinko_s2145_print.c +++ b/src/cups/backend_shinkos2145.c @@ -1,7 +1,7 @@ /* * Shinko/Sinfonia CHC-S2145 CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org> * * Development of this backend was sponsored by: * @@ -103,6 +103,10 @@ struct shinkos2145_ctx { uint8_t *databuf; int datalen; + + uint16_t last_donor; + uint16_t last_remain; + uint16_t media_prints; }; /* Structs for printer */ @@ -179,7 +183,7 @@ struct s2145_print_cmd { #define PRINT_MEDIA_6x8 0x06 #define PRINT_MEDIA_2x6 0x07 -static char *print_medias (uint8_t v) { +static char *print_sizes (uint8_t v) { switch (v) { case PRINT_MEDIA_4x6: return "4x6"; @@ -198,6 +202,23 @@ static char *print_medias (uint8_t v) { } } +static int print_counts (uint8_t v) { + switch (v) { + case PRINT_MEDIA_4x6: + return 700; + case PRINT_MEDIA_5x3_5: + return 800; + case PRINT_MEDIA_5x7: + return 400; + case PRINT_MEDIA_6x9: + return 310; + case PRINT_MEDIA_6x8: + return 350; + default: + return 700; + } +} + #define PRINT_MODE_DEFAULT 0x01 #define PRINT_MODE_STD_GLOSSY 0x02 #define PRINT_MODE_FINE_GLOSSY 0x03 @@ -784,7 +805,7 @@ struct s2145_getunique_resp { #define READBACK_LEN 128 /* Needs to be larger than largest response hdr */ #define CMDBUF_LEN sizeof(struct s2145_print_cmd) -uint8_t rdbuf[READBACK_LEN]; +static uint8_t rdbuf[READBACK_LEN]; static int s2145_do_cmd(struct shinkos2145_ctx *ctx, uint8_t *cmd, int cmdlen, @@ -868,7 +889,7 @@ static int get_status(struct shinkos2145_ctx *ctx) le16_to_cpu(resp->bank1_specified), le16_to_cpu(resp->bank1_remaining)); - INFO("Bank 2: 0x%02x (%s) Job %03d @ %03d/%03d (%03d remaining)\n", + INFO("Bank 2: 0x%02x (%s) Job %03u @ %03u/%03u (%03u remaining)\n", resp->bank2_status, bank_statuses(resp->bank1_status), resp->bank2_printid, le16_to_cpu(resp->bank2_finished), @@ -906,7 +927,7 @@ static int get_fwinfo(struct shinkos2145_ctx *ctx) if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s2145_fwinfo_resp) - sizeof(struct s2145_status_hdr))) continue; - + INFO(" %s\t ver %02x.%02x\n", fwinfo_targets(i), resp->major, resp->minor); #if 0 @@ -937,21 +958,21 @@ static int get_errorlog(struct shinkos2145_ctx *ctx) ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd)); return ret; } - + if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s2145_errorlog_resp) - sizeof(struct s2145_status_hdr))) return -2; - INFO("Stored Error Events: %d entries:\n", resp->count); + INFO("Stored Error Events: %u entries:\n", resp->count); for (i = 0 ; i < resp->count ; i++) { INFO(" %02d: @ %08u prints : 0x%02x/0x%02x (%s)\n", i, le32_to_cpu(resp->items[i].print_counter), - resp->items[i].major, resp->items[i].minor, + resp->items[i].major, resp->items[i].minor, error_codes(resp->items[i].major, resp->items[i].minor)); } return 0; } -static int get_mediainfo(struct shinkos2145_ctx *ctx) +static int get_mediainfo(struct shinkos2145_ctx *ctx) { struct s2145_cmd_hdr cmd; struct s2145_mediainfo_resp *resp = (struct s2145_mediainfo_resp *) rdbuf; @@ -968,23 +989,23 @@ static int get_mediainfo(struct shinkos2145_ctx *ctx) ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd)); return ret; } - + if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s2145_mediainfo_resp) - sizeof(struct s2145_status_hdr))) return -2; - INFO("Supported Media Information: %d entries:\n", resp->count); + INFO("Supported Media Information: %u entries:\n", resp->count); for (i = 0 ; i < resp->count ; i++) { - INFO(" %02d: C 0x%02x (%s), %04dx%04d, M 0x%02x (%s), P 0x%02x (%s)\n", i, - resp->items[i].code, print_medias(resp->items[i].code), + INFO(" %02d: C 0x%02x (%s), %04ux%04u, M 0x%02x (%s), P 0x%02x (%s)\n", i, + resp->items[i].code, print_sizes(resp->items[i].code), le16_to_cpu(resp->items[i].columns), - le16_to_cpu(resp->items[i].rows), + le16_to_cpu(resp->items[i].rows), resp->items[i].media_type, media_types(resp->items[i].media_type), resp->items[i].print_type, print_methods(resp->items[i].print_type)); } return 0; } -static int get_user_string(struct shinkos2145_ctx *ctx) +static int get_user_string(struct shinkos2145_ctx *ctx) { struct s2145_cmd_hdr cmd; struct s2145_getunique_resp *resp = (struct s2145_getunique_resp*) rdbuf; @@ -1296,9 +1317,6 @@ int shinkos2145_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - /* Reset arg parsing */ - optind = 1; - opterr = 0; while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "b:c:C:eFil:L:mr:R:suU:X:")) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL @@ -1368,7 +1386,7 @@ static void *shinkos2145_init(void) if (!ctx) { ERROR("Memory allocation failure! (%d bytes)\n", (int)sizeof(struct shinkos2145_ctx)); - + return NULL; } memset(ctx, 0, sizeof(struct shinkos2145_ctx)); @@ -1394,7 +1412,12 @@ static void shinkos2145_attach(void *vctx, struct libusb_device_handle *dev, desc.idVendor, desc.idProduct); /* Ensure jobid is sane */ - ctx->jobid = (jobid & 0x7f) + 1; + ctx->jobid = (jobid & 0x7f); + if (!ctx->jobid) + ctx->jobid++; + + /* Initialize donor */ + ctx->last_donor = ctx->last_remain = ctx->media_prints = 65535; } static void shinkos2145_teardown(void *vctx) { @@ -1436,7 +1459,7 @@ static int shinkos2145_read_parse(void *vctx, int data_fd) { } if (le32_to_cpu(ctx->hdr.model) != 2145) { - ERROR("Unrecognized printer (%d)!\n", le32_to_cpu(ctx->hdr.model)); + ERROR("Unrecognized printer (%u)!\n", le32_to_cpu(ctx->hdr.model)); return CUPS_BACKEND_CANCEL; } @@ -1514,12 +1537,17 @@ static int shinkos2145_main_loop(void *vctx, int copies) { ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd)); return CUPS_BACKEND_FAILED; } - + if (le16_to_cpu(media->hdr.payload_len) != (sizeof(struct s2145_mediainfo_resp) - sizeof(struct s2145_status_hdr))) return CUPS_BACKEND_FAILED; /* Validate print sizes */ for (i = 0; i < media->count ; i++) { + /* Figure out the media type... */ + int media_prints = print_counts(media->items[i].code); + if (media_prints < ctx->media_prints) + ctx->media_prints = media_prints; + /* Look for matching media */ if (le16_to_cpu(media->items[i].columns) == cpu_to_le16(le32_to_cpu(ctx->hdr.columns)) && le16_to_cpu(media->items[i].rows) == cpu_to_le16(le32_to_cpu(ctx->hdr.rows)) && @@ -1531,6 +1559,13 @@ static int shinkos2145_main_loop(void *vctx, int copies) { return CUPS_BACKEND_HOLD; } + /* Tell CUPS about the consumables we report */ + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='Color'\n"); + ATTR("marker-types=ribbonWax\n"); + // XXX check copies against remaining media! top: @@ -1553,12 +1588,27 @@ top: } if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) { + uint16_t donor, remain; + memcpy(rdbuf2, rdbuf, READBACK_LEN); - INFO("Printer Status: 0x%02x (%s)\n", + INFO("Printer Status: 0x%02x (%s)\n", sts->hdr.status, status_str(sts->hdr.status)); + + /* Guessimate a percentage for the remaining media */ + donor = le32_to_cpu(sts->count_ribbon_left) * 100 / ctx->media_prints; + if (donor != ctx->last_donor) { + ctx->last_donor = donor; + ATTR("marker-levels=%d\n", donor); + } + remain = le32_to_cpu(sts->count_ribbon_left); + if (remain != ctx->last_remain) { + ctx->last_remain = remain; + ATTR("marker-message=\"%d prints remaining on ribbon\"\n", remain); + } + if (sts->hdr.result != RESULT_SUCCESS) - goto printer_error; + goto printer_error; if (sts->hdr.error == ERROR_PRINTER) goto printer_error; } else if (state == last_state) { @@ -1567,19 +1617,30 @@ top: } last_state = state; - fflush(stderr); + fflush(stderr); switch (state) { case S_IDLE: INFO("Waiting for printer idle\n"); + + /* make sure we're not colliding with an existing + jobid */ + while (ctx->jobid == sts->bank1_printid || + ctx->jobid == sts->bank2_printid) { + ctx->jobid++; + ctx->jobid &= 0x7f; + if (!ctx->jobid) + ctx->jobid++; + } + /* If either bank is free, continue */ - if (sts->bank1_status == BANK_STATUS_FREE || - sts->bank2_status == BANK_STATUS_FREE) + if (sts->bank1_status == BANK_STATUS_FREE || + sts->bank2_status == BANK_STATUS_FREE) state = S_PRINTER_READY_CMD; break; case S_PRINTER_READY_CMD: - INFO("Initiating print job (internal id %d)\n", ctx->jobid); + INFO("Sending print job (internal id %u)\n", ctx->jobid); memset(cmdbuf, 0, CMDBUF_LEN); print->hdr.cmd = cpu_to_le16(S2145_CMD_PRINTJOB); @@ -1636,7 +1697,7 @@ top: if (state != S_FINISHED) goto top; - + INFO("Print complete\n"); return CUPS_BACKEND_OK; @@ -1692,7 +1753,7 @@ static int shinkos2145_query_serno(struct libusb_device_handle *dev, uint8_t end struct dyesub_backend shinkos2145_backend = { .name = "Shinko/Sinfonia CHC-S2145", - .version = "0.46", + .version = "0.48", .uri_prefix = "shinkos2145", .cmdline_usage = shinkos2145_cmdline, .cmdline_arg = shinkos2145_cmdline_arg, diff --git a/src/cups/shinko_s6145_print.c b/src/cups/backend_shinkos6145.c index ee5a45a..692a42c 100644 --- a/src/cups/shinko_s6145_print.c +++ b/src/cups/backend_shinkos6145.c @@ -1,7 +1,7 @@ /* * Shinko/Sinfonia CHC-S6145 CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2015-2016 Solomon Peachy <pizza@shaftnet.org> * * Low-level documentation was provided by Sinfonia. Thank you! * @@ -32,11 +32,8 @@ * * You must still adhere to all other terms of the license to this program * (ie GPLv2) and the license of the libS6145ImageProcess library. - * - * Please note that the authors of this program *do not* have permission to - * redistribute this library, which was provided only in binary form. - * - * */ + * + */ #include <stdio.h> #include <stdlib.h> @@ -50,14 +47,44 @@ #include <signal.h> #include <time.h> +/* For Integration into gutenprint */ +#if defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#if defined(USE_DLOPEN) +#define WITH_DYNAMIC +#include <dlfcn.h> +#define DL_INIT() do {} while(0) +#define DL_OPEN(__x) dlopen(__x, RTLD_NOW) +#define DL_SYM(__x, __y) dlsym(__x, __y) +#define DL_CLOSE(__x) dlclose(__x) +#define DL_EXIT() do {} while(0) +#elif defined(USE_LTDL) +#define WITH_DYNAMIC +#include <ltdl.h> +#define DL_INIT() lt_dlinit() +#define DL_OPEN(__x) lt_dlopen(__x) +#define DL_SYM(__x, __y) lt_dlsym(__x, __y) +#define DL_CLOSE(__x) do {} while(0) +#define DL_EXIT() lt_dlexit() +#else +#define DL_INIT() do {} while(0) +#define DL_CLOSE(__x) do {} while(0) +#define DL_EXIT() do {} while(0) +#warning "No dynamic loading support!" +#endif + #define BACKEND shinkos6145_backend #include "backend_common.h" -#if defined(WITH_6145_LIB) -/* Note that this is a proprietary library, and *NOT* GPL compatible! */ -#include "libS6145ImageProcess.h" -#endif +/* Image processing library function prototypes */ +typedef int (*ImageProcessingFN)(unsigned char *, unsigned short *, void *); +typedef int (*ImageAvrCalcFN)(unsigned char *, unsigned short, unsigned short, unsigned char *); + +#define LIB_NAME "libS6145ImageProcess.so" // Official library +#define LIB_NAME_RE "libS6145ImageReProcess.so" // Reimplemented library enum { S_IDLE = 0, @@ -248,11 +275,25 @@ struct shinkos6145_ctx { uint8_t *databuf; size_t datalen; + uint8_t ribbon_type; + + uint16_t last_donor; + uint16_t last_remain; + uint16_t last_ribbon; + + uint8_t *eeprom; + size_t eepromlen; + + void *dl_handle; + ImageProcessingFN ImageProcessing; + ImageAvrCalcFN ImageAvrCalc; + struct shinkos6145_correctionparam *corrdata; size_t corrdatalen; }; static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx); +static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx); /* Structs for printer */ struct s6145_cmd_hdr { @@ -831,13 +872,13 @@ struct s6145_status_resp { uint32_t count_head; uint32_t count_ribbon_left; uint32_t reserved; - + uint8_t bank1_printid; uint16_t bank1_remaining; uint16_t bank1_finished; uint16_t bank1_specified; uint8_t bank1_status; - + uint8_t bank2_printid; uint16_t bank2_remaining; uint16_t bank2_finished; @@ -846,7 +887,7 @@ struct s6145_status_resp { uint8_t reserved2[16]; uint8_t tonecurve_status; - uint8_t reserved3[6]; + uint8_t reserved3[6]; } __attribute__((packed)); #define BANK_STATUS_FREE 0x00 @@ -914,8 +955,14 @@ struct s6145_mediainfo_item { #define MEDIA_6x8 0x06 #define MEDIA_2x6 0x07 #define MEDIA_6x6 0x08 - -static char *print_medias (uint8_t v) { +#define MEDIA_89x60mm 0x10 +#define MEDIA_89x59mm 0x11 +#define MEDIA_89x58mm 0x12 +#define MEDIA_89x57mm 0x13 +#define MEDIA_89x56mm 0x14 +#define MEDIA_89x55mm 0x15 + +static char *print_sizes (uint8_t v) { switch (v) { case MEDIA_4x6: return "4x6"; @@ -931,6 +978,18 @@ static char *print_medias (uint8_t v) { return "2x6"; case MEDIA_6x6: return "6x6"; + case MEDIA_89x60mm: + return "89x60mm"; + case MEDIA_89x59mm: + return "89x59mm"; + case MEDIA_89x58mm: + return "89x58mm"; + case MEDIA_89x57mm: + return "89x57mm"; + case MEDIA_89x56mm: + return "89x56mm"; + case MEDIA_89x55mm: + return "89x55mm"; default: return "Unknown"; } @@ -942,8 +1001,27 @@ static char *print_medias (uint8_t v) { #define RIBBON_5x7 0x03 #define RIBBON_6x8 0x04 #define RIBBON_6x9 0x05 +// XXX what about 89xXXXmm ribbons? -static char *print_ribbons (uint8_t v) { +static int ribbon_sizes (uint8_t v) { + switch (v) { + case RIBBON_4x6: + return 300; + case RIBBON_3_5x5: + return 340; + case RIBBON_5x7: + return 170; + case RIBBON_6x8: + return 150; + case RIBBON_6x9: + return 130; // XXX guessed + // XXX 89x??? rubbons. + default: + return 300; // don't want 0. + } +} + +static const char *print_ribbons (uint8_t v) { switch (v) { case RIBBON_NONE: return "None"; @@ -957,6 +1035,7 @@ static char *print_ribbons (uint8_t v) { return "6x8"; case RIBBON_6x9: return "6x9"; + // XXX 89x??? rubbons. default: return "Unknown"; } @@ -1126,7 +1205,7 @@ static int get_status(struct shinkos6145_ctx *ctx) le16_to_cpu(resp->bank1_specified), le16_to_cpu(resp->bank1_remaining)); - INFO("Bank 2: 0x%02x (%s) Job %03d @ %03d/%03d (%03d remaining)\n", + INFO("Bank 2: 0x%02x (%s) Job %03u @ %03u/%03u (%03u remaining)\n", resp->bank2_status, bank_statuses(resp->bank1_status), resp->bank2_printid, le16_to_cpu(resp->bank2_finished), @@ -1149,11 +1228,19 @@ static int get_status(struct shinkos6145_ctx *ctx) if (le16_to_cpu(resp2->hdr.payload_len) != (sizeof(struct s6145_getextcounter_resp) - sizeof(struct s6145_status_hdr))) return -1; - INFO("Lifetime Distance: %08d inches\n", le32_to_cpu(resp2->lifetime_distance)); - INFO("Maintainence Distance: %08d inches\n", le32_to_cpu(resp2->maint_distance)); - INFO("Head Distance: %08d inches\n", le32_to_cpu(resp2->head_distance)); + INFO("Lifetime Distance: %08u inches\n", le32_to_cpu(resp2->lifetime_distance)); + INFO("Maintainence Distance: %08u inches\n", le32_to_cpu(resp2->maint_distance)); + INFO("Head Distance: %08u inches\n", le32_to_cpu(resp2->head_distance)); /* Query various params */ + if(ctx->type == P_SHINKO_S6145D) { + if ((ret = get_param(ctx, PARAM_REGION_CODE, &val))) { + ERROR("Failed to execute command\n"); + return ret; + } + INFO("Region Code: %#x\n", val); + + } if ((ret = get_param(ctx, PARAM_PAPER_PRESV, &val))) { ERROR("Failed to execute command\n"); return ret; @@ -1257,7 +1344,7 @@ static int get_errorlog(struct shinkos6145_ctx *ctx) if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s6145_errorlog_resp) - sizeof(struct s6145_status_hdr))) return -2; - INFO("Stored Error Events: %d entries:\n", resp->count); + INFO("Stored Error Events: %u entries:\n", resp->count); for (i = 0 ; i < resp->count ; i++) { INFO(" %02d: @ %08u prints : 0x%02x/0x%02x (%s)\n", i, le32_to_cpu(resp->items[i].print_counter), @@ -1284,17 +1371,17 @@ static int get_mediainfo(struct shinkos6145_ctx *ctx) ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd)); return ret; } - + if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s6145_mediainfo_resp) - sizeof(struct s6145_status_hdr))) return -2; INFO("Loaded Media Type: %s\n", print_ribbons(resp->ribbon)); - INFO("Supported Print Sizes: %d entries:\n", resp->count); + INFO("Supported Print Sizes: %u entries:\n", resp->count); for (i = 0 ; i < resp->count ; i++) { - INFO(" %02d: C 0x%02x (%s), %04dx%04d, P 0x%02x (%s)\n", i, - resp->items[i].media_code, print_medias(resp->items[i].media_code), + INFO(" %02d: C 0x%02x (%s), %04ux%04u, P 0x%02x (%s)\n", i, + resp->items[i].media_code, print_sizes(resp->items[i].media_code), le16_to_cpu(resp->items[i].columns), - le16_to_cpu(resp->items[i].rows), + le16_to_cpu(resp->items[i].rows), resp->items[i].print_method, print_methods(resp->items[i].print_method)); } return 0; @@ -1445,6 +1532,36 @@ static int shinkos6145_dump_corrdata(struct shinkos6145_ctx *ctx, char *fname) return ret; } +static int shinkos6145_dump_eeprom(struct shinkos6145_ctx *ctx, char *fname) +{ + int ret; + + ret = shinkos6145_get_eeprom(ctx); + if (ret) { + ERROR("Failed to execute command\n"); + return ret; + } + + /* Open file and write it out */ + { + int fd = open(fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); + if (fd < 0) { + ERROR("Unable to open filename\n"); + return fd; + } + + write(fd, ctx->eeprom, ctx->eepromlen); + close(fd); + } + + /* Free the buffers */ + free(ctx->eeprom); + ctx->eeprom = NULL; + ctx->eepromlen = 0; + + return ret; +} + static int get_tonecurve(struct shinkos6145_ctx *ctx, int type, char *fname) { struct s6145_readtone_cmd cmd; @@ -1607,7 +1724,7 @@ static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx) } ctx->corrdatalen = le16_to_cpu(resp->total_size); - INFO("Fetching %lu bytes of image correction data\n", ctx->corrdatalen); + INFO("Fetching %zu bytes of image correction data\n", ctx->corrdatalen); ctx->corrdata = malloc(sizeof(struct shinkos6145_correctionparam)); if (!ctx->corrdata) { @@ -1631,68 +1748,45 @@ static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx) total += sizeof(data.data); if (data.remain_pkt == 0) - DEBUG("correction block transferred (%lu/%lu total)\n", total, ctx->corrdatalen); + DEBUG("correction block transferred (%zu/%zu total)\n", total, ctx->corrdatalen); } -#if !defined(WITH_6145_LIB) - /* Sanity check correction data */ - { - int i; - struct shinkos6145_correctionparam *corrdata = ctx->corrdata; - - for (i = 0 ; i < 256 ; i++) { - if (le16_to_cpu(corrdata->pulseTransTable_Y[i]) > le16_to_cpu(corrdata->printMaxPulse_Y) || - le16_to_cpu(corrdata->pulseTransTable_M[i]) > le16_to_cpu(corrdata->printMaxPulse_M) || - le16_to_cpu(corrdata->pulseTransTable_C[i]) > le16_to_cpu(corrdata->printMaxPulse_C) || - le16_to_cpu(corrdata->pulseTransTable_O[i]) > le16_to_cpu(corrdata->printMaxPulse_O)) { - ret = -10; - goto done; - } - } - if (!corrdata->tableTankParam_Y.trdTankSize || - !corrdata->tableTankParam_M.trdTankSize || - !corrdata->tableTankParam_C.trdTankSize || - !corrdata->tableTankParam_O.trdTankSize) { - ret = -14; - goto done; - } - if (!corrdata->tableTankParam_Y.sndTankSize || - !corrdata->tableTankParam_M.sndTankSize || - !corrdata->tableTankParam_C.sndTankSize || - !corrdata->tableTankParam_O.sndTankSize) { - ret = -15; - goto done; - } - if (!corrdata->tableTankParam_Y.fstTankSize || - !corrdata->tableTankParam_M.fstTankSize || - !corrdata->tableTankParam_C.fstTankSize || - !corrdata->tableTankParam_O.fstTankSize) { - ret = -16; - goto done; - } - if (corrdata->val_1 > 1 || - corrdata->val_2 > 1 || - corrdata->printOpLevel > 0xff || - corrdata->matteMode > 1) { - ret = -17; - goto done; - } - if (corrdata->randomBase[0] > 0xff || - corrdata->randomBase[1] > 0xff || - corrdata->randomBase[2] > 0xff || - corrdata->randomBase[3] > 0xff) { - ret = -18; - goto done; - } - if (!corrdata->matteSize || - corrdata->matteSize > 2) { - ret = -19; - goto done; - } +done: + return ret; +} + +static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx) +{ + struct s6145_cmd_hdr cmd; + struct s6145_geteeprom_resp *resp = (struct s6145_geteeprom_resp *) rdbuf; + + int ret, num; + cmd.cmd = cpu_to_le16(S6145_CMD_GETEEPROM); + cmd.len = 0; + + if (ctx->eeprom) { + free(ctx->eeprom); + ctx->eeprom = NULL; + } + + if ((ret = s6145_do_cmd(ctx, + (uint8_t*)&cmd, sizeof(cmd), + sizeof(*resp), + &num)) < 0) { + ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd)); + goto done; } -#endif + + ctx->eepromlen = le16_to_cpu(resp->hdr.payload_len); + ctx->eeprom = malloc(ctx->eepromlen); + if (!ctx->eeprom) { + ERROR("Memory allocation failure\n"); + ret = -ENOMEM; + goto done; + } + memcpy(ctx->eeprom, resp->data, ctx->eepromlen); done: return ret; @@ -1709,6 +1803,7 @@ static void shinkos6145_cmdline(void) DEBUG("\t\t[ -l filename ] # Get current tone curve\n"); DEBUG("\t\t[ -L filename ] # Set current tone curve\n"); DEBUG("\t\t[ -m ] # Query media\n"); + DEBUG("\t\t[ -q filename ] # Extract eeprom data\n"); DEBUG("\t\t[ -Q filename ] # Extract image correction params\n"); DEBUG("\t\t[ -r ] # Reset user/NV tone curve\n"); DEBUG("\t\t[ -R ] # Reset printer to factory defaults\n"); @@ -1724,7 +1819,7 @@ int shinkos6145_cmdline_arg(void *vctx, int argc, char **argv) if (!ctx) return -1; - while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFik:l:L:mr:Q:R:sX:")) >= 0) { + while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFik:l:L:mr:Q:q:R:sX:")) >= 0) { switch(i) { GETOPT_PROCESS_GLOBAL case 'c': @@ -1744,17 +1839,17 @@ int shinkos6145_cmdline_arg(void *vctx, int argc, char **argv) break; case 'k': { uint32_t i = atoi(optarg); - if (i < 5) + if (i <= 5) i = 0; - else if (i < 15) + else if (i <= 15) i = 1; - else if (i < 30) + else if (i <= 30) i = 2; - else if (i < 60) + else if (i <= 60) i = 3; - else if (i < 120) + else if (i <= 120) i = 4; - else if (i < 240) + else if (i <= 240) i = 5; else i = 5; @@ -1771,6 +1866,9 @@ int shinkos6145_cmdline_arg(void *vctx, int argc, char **argv) case 'm': j = get_mediainfo(ctx); break; + case 'q': + j = shinkos6145_dump_eeprom(ctx, optarg); + break; case 'Q': j = shinkos6145_dump_corrdata(ctx, optarg); break; @@ -1805,6 +1903,8 @@ static void *shinkos6145_init(void) } memset(ctx, 0, sizeof(struct shinkos6145_ctx)); + DL_INIT(); + return ctx; } @@ -1824,9 +1924,35 @@ static void shinkos6145_attach(void *vctx, struct libusb_device_handle *dev, ctx->type = lookup_printer_type(&shinkos6145_backend, desc.idVendor, desc.idProduct); - + + /* Attempt to open the library */ +#if defined(WITH_DYNAMIC) + INFO("Attempting to load image processing library\n"); + ctx->dl_handle = DL_OPEN(LIB_NAME); /* Try the Sinfonia one first */ + if (!ctx->dl_handle) + ctx->dl_handle = DL_OPEN(LIB_NAME_RE); /* Then the RE one */ + if (!ctx->dl_handle) + WARNING("Image processing library not found, using internal fallback code\n"); + if (ctx->dl_handle) { + ctx->ImageProcessing = DL_SYM(ctx->dl_handle, "ImageProcessing"); + ctx->ImageAvrCalc = DL_SYM(ctx->dl_handle, "ImageAvrCalc"); + if (!ctx->ImageProcessing || !ctx->ImageAvrCalc) { + WARNING("Problem resolving symbols in imaging processing library\n"); + DL_CLOSE(ctx->dl_handle); + ctx->dl_handle = NULL; + } else { + INFO("Image processing library successfully loaded\n"); + } + } +#else + WARNING("Dynamic library support not enabled, using internal fallback code\n"); +#endif + /* Ensure jobid is sane */ ctx->jobid = (jobid & 0x7f) + 1; + + /* Initialize donor */ + ctx->last_donor = ctx->last_remain = 65535; } static void shinkos6145_teardown(void *vctx) { @@ -1837,13 +1963,18 @@ static void shinkos6145_teardown(void *vctx) { if (ctx->databuf) free(ctx->databuf); + if (ctx->eeprom) + free(ctx->eeprom); if (ctx->corrdata) free(ctx->corrdata); + if (ctx->dl_handle) + DL_CLOSE(ctx->dl_handle); + DL_EXIT(); + free(ctx); } -#if !defined (WITH_6145_LIB) static void lib6145_calc_avg(struct shinkos6145_ctx *ctx, uint16_t rows, uint16_t cols) { uint32_t plane, i, planelen; @@ -1917,8 +2048,7 @@ static void lib6145_process_image(uint8_t *src, uint16_t *dest, /* Generate lamination plane, if desired */ if (oc_mode > PRINT_MODE_NO_OC) { - // XXX matters if we're using glossy/matte.. - // or should we just dump over the contents of the "raw" file? + // XXX matters if we're using glossy/matte... for (row = 0 ; row < le16_to_cpu(corrdata->height) ; row++) { for (col = 0 ; col < row_lim; col++) { uint16_t val; @@ -1934,8 +2064,6 @@ static void lib6145_process_image(uint8_t *src, uint16_t *dest, } } } -#endif - static int shinkos6145_read_parse(void *vctx, int data_fd) { struct shinkos6145_ctx *ctx = vctx; @@ -1964,11 +2092,11 @@ static int shinkos6145_read_parse(void *vctx, int data_fd) { } if (le32_to_cpu(ctx->hdr.model) != 6145) { - ERROR("Unrecognized printer (%d)!\n", le32_to_cpu(ctx->hdr.model)); + ERROR("Unrecognized printer (%u)!\n", le32_to_cpu(ctx->hdr.model)); return CUPS_BACKEND_CANCEL; } - + if (ctx->databuf) { free(ctx->databuf); ctx->databuf = NULL; @@ -2044,7 +2172,7 @@ static int shinkos6145_main_loop(void *vctx, int copies) { ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd)); return CUPS_BACKEND_FAILED; } - + if (le16_to_cpu(media->hdr.payload_len) != (sizeof(struct s6145_mediainfo_resp) - sizeof(struct s6145_status_hdr))) return CUPS_BACKEND_FAILED; @@ -2061,10 +2189,18 @@ static int shinkos6145_main_loop(void *vctx, int copies) { ERROR("Incorrect media loaded for print!\n"); return CUPS_BACKEND_HOLD; } - // XXX sanity-check media vs size - // don't know if media information above will catch this. - // XXX check copies against remaining media! + ctx->last_ribbon = media->ribbon; + + /* Tell CUPS about the consumables we report */ + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='%s'\n", print_ribbons(media->ribbon)); + ATTR("marker-types=ribbonWax\n"); + ctx->ribbon_type = media->ribbon; + + // XXX check copies against remaining media? /* Query printer mode */ ret = get_param(ctx, PARAM_OC_PRINT, &cur_mode); @@ -2072,7 +2208,7 @@ static int shinkos6145_main_loop(void *vctx, int copies) { ERROR("Failed to execute command\n"); return ret; } - + top: if (state != last_state) { if (dyesub_debug) @@ -2093,21 +2229,36 @@ top: } if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) { + uint16_t donor, remain; + memcpy(rdbuf2, rdbuf, READBACK_LEN); INFO("Printer Status: 0x%02x (%s)\n", sts->hdr.status, status_str(sts->hdr.status)); + + /* Guessimate a percentage for the remaining media */ + donor = le32_to_cpu(sts->count_ribbon_left) * 100 / ribbon_sizes(ctx->ribbon_type); + if (donor != ctx->last_donor) { + ctx->last_donor = donor; + ATTR("marker-levels=%d\n", donor); + } + remain = le32_to_cpu(sts->count_ribbon_left); + if (remain != ctx->last_remain) { + ctx->last_remain = remain; + ATTR("marker-message=\"%d prints remaining on '%s' ribbon\"\n", remain, print_ribbons(media->ribbon)); + } + if (sts->hdr.result != RESULT_SUCCESS) goto printer_error; if (sts->hdr.status == ERROR_PRINTER) - goto printer_error; + goto printer_error; } else if (state == last_state) { sleep(1); goto top; } last_state = state; - fflush(stderr); + fflush(stderr); switch (state) { case S_IDLE: @@ -2119,8 +2270,6 @@ top: break; case S_PRINTER_READY_CMD: { - // XXX send "get eeprom backup command" ? - /* Set matte/etc */ uint32_t oc_mode = le32_to_cpu(ctx->hdr.oc_mode); @@ -2147,6 +2296,12 @@ top: updated = 1; } + ret = shinkos6145_get_eeprom(ctx); + if (ret) { + ERROR("Failed to execute command\n"); + return ret; + } + /* Get image correction parameters if necessary */ if (updated || !ctx->corrdata || !ctx->corrdatalen) { ret = shinkos6145_get_imagecorr(ctx); @@ -2166,6 +2321,8 @@ top: ctx->corrdata->height = cpu_to_le16(le32_to_cpu(ctx->hdr.rows)); /* Convert packed RGB to planar YMC */ + // XXX would it make more sense to have Gutenprint generate + // planar YMC data as an extension of the spooler format? { int planelen = le16_to_cpu(ctx->corrdata->width) * le16_to_cpu(ctx->corrdata->height); uint8_t *databuf3 = malloc(ctx->datalen); @@ -2184,29 +2341,27 @@ top: } /* Perform the actual library transform */ -#if defined(WITH_6145_LIB) -#if defined(S6145_RE) - INFO("Calling Reverse-Engineered Image Processing Library...\n"); -#else - INFO("Calling Sinfonia Image Processing Library...\n"); -#endif - if (ImageAvrCalc(ctx->databuf, le32_to_cpu(ctx->hdr.columns), le32_to_cpu(ctx->hdr.rows), ctx->image_avg)) { - ERROR("Library returned error!\n"); - return CUPS_BACKEND_FAILED; - } + if (ctx->dl_handle) { + INFO("Calling image processing library...\n"); - ImageProcessing(ctx->databuf, databuf2, ctx->corrdata); -#else - INFO("Calling Internal Fallback Image Processing Library...\n"); + if (ctx->ImageAvrCalc(ctx->databuf, le32_to_cpu(ctx->hdr.columns), le32_to_cpu(ctx->hdr.rows), ctx->image_avg)) { + ERROR("Library returned error!\n"); + return CUPS_BACKEND_FAILED; + } + ctx->ImageProcessing(ctx->databuf, databuf2, ctx->corrdata); + } else { + WARNING("Utilizing fallback internal image processing code\n"); + WARNING(" *** Output quality will be poor! *** \n"); - lib6145_calc_avg(ctx, le32_to_cpu(ctx->hdr.columns), le32_to_cpu(ctx->hdr.rows)); - lib6145_process_image(ctx->databuf, databuf2, ctx->corrdata, oc_mode); -#endif + lib6145_calc_avg(ctx, le32_to_cpu(ctx->hdr.columns), le32_to_cpu(ctx->hdr.rows)); + lib6145_process_image(ctx->databuf, databuf2, ctx->corrdata, oc_mode); + } + free(ctx->databuf); ctx->databuf = (uint8_t*) databuf2; ctx->datalen = newlen; - INFO("Initiating print job (internal id %d)\n", ctx->jobid); + INFO("Sending print job (internal id %u)\n", ctx->jobid); memset(cmdbuf, 0, CMDBUF_LEN); print->hdr.cmd = cpu_to_le16(S6145_CMD_PRINTJOB); @@ -2246,6 +2401,8 @@ top: } INFO("Sending image data to printer\n"); + // XXX we shouldn't send the lamination layer over if + // it's not needed. hdr->oc_mode == PRINT_MODE_NO_OC if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->databuf, ctx->datalen))) return CUPS_BACKEND_FAILED; @@ -2326,7 +2483,7 @@ static int shinkos6145_query_serno(struct libusb_device_handle *dev, uint8_t end struct dyesub_backend shinkos6145_backend = { .name = "Shinko/Sinfonia CHC-S6145", - .version = "0.14WIP", + .version = "0.21", .uri_prefix = "shinkos6145", .cmdline_usage = shinkos6145_cmdline, .cmdline_arg = shinkos6145_cmdline_arg, @@ -2343,7 +2500,7 @@ struct dyesub_backend shinkos6145_backend = { } }; -/* CHC-S6145 data format +/* CHC-S6145 spool file format Spool file consists of an 116-byte header, followed by RGB-packed data, followed by a 4-byte footer. Header appears to consist of a series of @@ -2362,31 +2519,4 @@ struct dyesub_backend shinkos6145_backend = { 04 03 02 01 [[ footer ]] - * CIAAT Brava 21 data format - - This printer is supposed to be a variant of the S6145, but uses a - different spool format -- but seems to use the same command language. - - 01 40 12 00 II NN NN YY YY XX XX TT 00 00 00 00 00 00 01 MM QQ ZZ - - II == Job ID (01-255, backend fills) - NN NN == copies (LE) - YY YY == Columns (LE) - XX XX == Rows (LE) - MM == Overcoat (02 = glossy, 03 = matte, 01 = none) - TT == Type (00 = 4x6, 03 = 5x7, 06 = 8x6, 07 = 2x6) - QQ == Multicut (00 = normal, 01 = none, 02 = 2*4x6, - 04 = 2*2x6, 80 = 4x6-notrim) - ZZ == Cyan Average (backend fills) - - 1844*2434 8x6 - 1844*2492 4x6*2 - 1548*2140 5x7 - 1844*1240 4x6 (and 2x6*2) - 1844*1210 4x6-notrim (WTF?) - 1844*634 2x6 - - - [[ Followed by XX*YY*3 bytes of image data, RGB ]] - */ diff --git a/src/cups/shinko_s6245_print.c b/src/cups/backend_shinkos6245.c index e4b57e9..b5b1c2b 100644 --- a/src/cups/shinko_s6245_print.c +++ b/src/cups/backend_shinkos6245.c @@ -1,7 +1,7 @@ /* * Shinko/Sinfonia CHC-S6245 CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2015-2016 Solomon Peachy <pizza@shaftnet.org> * * Low-level documentation was provided by Sinfonia, Inc. Thank you! * @@ -103,6 +103,10 @@ struct shinkos6245_ctx { uint8_t *databuf; int datalen; + + uint16_t last_donor; + uint16_t last_remain; + uint8_t ribbon_code; }; /* Structs for printer */ @@ -517,7 +521,7 @@ static char *error_codes(uint8_t major, uint8_t minor) return "Paper Jam: Precut Print Position Off"; case 0x20: return "Paper Jam: Precut Print Position On"; - + case 0x29: return "Paper Jam: Printing Paper Top On"; case 0x2A: @@ -700,13 +704,13 @@ struct s6245_status_resp { uint32_t count_head; uint32_t count_ribbon_left; uint32_t reserved; - + uint8_t bank1_printid; uint16_t bank1_remaining; uint16_t bank1_finished; uint16_t bank1_specified; uint8_t bank1_status; - + uint8_t bank2_printid; uint16_t bank2_remaining; uint16_t bank2_finished; @@ -715,7 +719,7 @@ struct s6245_status_resp { uint8_t reserved2[16]; uint8_t tonecurve_status; - uint8_t reserved3[6]; + uint8_t reserved3[6]; } __attribute__((packed)); #define BANK_STATUS_FREE 0x00 @@ -787,7 +791,7 @@ struct s6245_mediainfo_item { #define MEDIA_8x6_2 0x32 #define MEDIA_8x4_3 0x40 -static char *print_medias (uint8_t v) { +static const char *print_sizes (uint8_t v) { switch (v) { case MEDIA_8x10: return "8x10"; @@ -816,10 +820,36 @@ static char *print_medias (uint8_t v) { struct s6245_mediainfo_resp { struct s6245_status_hdr hdr; - uint8_t count; + uint8_t ribbon_code; + uint8_t reserved; + uint8_t count; struct s6245_mediainfo_item items[10]; /* Not all necessarily used */ } __attribute__((packed)); +static const char *ribbon_sizes (uint8_t v) { + switch (v) { + case 0x00: + return "None"; + case 0x11: + return "8x10"; + case 0x12: + return "8x12"; + default: + return "Unknown"; + } +} + +static int ribbon_counts (uint8_t v) { + switch (v) { + case 0x11: + return 120; + case 0x12: + return 100; + default: + return 120; + } +} + struct s6245_errorlog_resp { struct s6245_status_hdr hdr; uint16_t error_count; @@ -899,7 +929,7 @@ struct s6245_fwinfo_resp { #define READBACK_LEN 512 /* Needs to be larger than largest response hdr */ #define CMDBUF_LEN sizeof(struct s6245_print_cmd) -uint8_t rdbuf[READBACK_LEN]; +static uint8_t rdbuf[READBACK_LEN]; static int s6245_do_cmd(struct shinkos6245_ctx *ctx, uint8_t *cmd, int cmdlen, @@ -984,7 +1014,7 @@ static int get_status(struct shinkos6245_ctx *ctx) le16_to_cpu(resp->bank1_specified), le16_to_cpu(resp->bank1_remaining)); - INFO("Bank 2: 0x%02x (%s) Job %03d @ %03d/%03d (%03d remaining)\n", + INFO("Bank 2: 0x%02x (%s) Job %03u @ %03u/%03u (%03u remaining)\n", resp->bank2_status, bank_statuses(resp->bank1_status), resp->bank2_printid, le16_to_cpu(resp->bank2_finished), @@ -1007,9 +1037,9 @@ static int get_status(struct shinkos6245_ctx *ctx) if (le16_to_cpu(resp2->hdr.payload_len) != (sizeof(struct s6245_getextcounter_resp) - sizeof(struct s6245_status_hdr))) return 0; - INFO("Lifetime Distance: %08d inches\n", le32_to_cpu(resp2->lifetime_distance)); - INFO("Maintainence Distance: %08d inches\n", le32_to_cpu(resp2->maint_distance)); - INFO("Head Distance: %08d inches\n", le32_to_cpu(resp2->head_distance)); + INFO("Lifetime Distance: %08u inches\n", le32_to_cpu(resp2->lifetime_distance)); + INFO("Maintainence Distance: %08u inches\n", le32_to_cpu(resp2->maint_distance)); + INFO("Head Distance: %08u inches\n", le32_to_cpu(resp2->head_distance)); return 0; } @@ -1080,13 +1110,13 @@ static int get_errorlog(struct shinkos6245_ctx *ctx) return -2; INFO("Stored Error ID %d:\n", i); - INFO(" %04d-%02d-%02d %02d:%02d:%02d @ %08u prints : 0x%02x/0x%02x (%s)\n", + INFO(" %04d-%02u-%02u %02u:%02u:%02u @ %08u prints : 0x%02x/0x%02x (%s)\n", resp->time_year + 2000, resp->time_month, resp->time_day, resp->time_hour, resp->time_min, resp->time_sec, le32_to_cpu(resp->print_counter), resp->error_major, resp->error_minor, error_codes(resp->error_major, resp->error_minor)); - INFO(" Temp: %02d/%02d Hum: %02d\n", + INFO(" Temp: %02u/%02u Hum: %02u\n", resp->printer_thermistor, resp->head_thermistor, resp->printer_humidity); } while (++i < le16_to_cpu(resp->error_count)); @@ -1110,14 +1140,15 @@ static int get_mediainfo(struct shinkos6245_ctx *ctx) ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd)); return ret; } - + if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s6245_mediainfo_resp) - sizeof(struct s6245_status_hdr))) return -2; - INFO("Supported Media Information: %d entries:\n", resp->count); + INFO("Loaded Media Type: %s\n", ribbon_sizes(resp->ribbon_code)); + INFO("Supported Media Information: %u entries:\n", resp->count); for (i = 0 ; i < resp->count ; i++) { - INFO(" %02d: C 0x%02x (%s), %04dx%04d, P 0x%02x (%s)\n", i, - resp->items[i].media_code, print_medias(resp->items[i].media_code), + INFO(" %02d: C 0x%02x (%s), %04ux%04u, P 0x%02x (%s)\n", i, + resp->items[i].media_code, print_sizes(resp->items[i].media_code), le16_to_cpu(resp->items[i].columns), le16_to_cpu(resp->items[i].rows), resp->items[i].print_method, print_methods(resp->items[i].print_method)); @@ -1470,15 +1501,20 @@ static void shinkos6245_attach(void *vctx, struct libusb_device_handle *dev, ctx->dev = dev; ctx->endp_up = endp_up; ctx->endp_down = endp_down; - + device = libusb_get_device(dev); libusb_get_device_descriptor(device, &desc); - + ctx->type = lookup_printer_type(&shinkos6245_backend, desc.idVendor, desc.idProduct); /* Ensure jobid is sane */ - ctx->jobid = (jobid & 0x7f) + 1; + ctx->jobid = jobid & 0x7f; + if (!ctx->jobid) + ctx->jobid++; + + /* Initialize donor */ + ctx->last_donor = ctx->last_remain = 65535; } static void shinkos6245_teardown(void *vctx) { @@ -1520,7 +1556,7 @@ static int shinkos6245_read_parse(void *vctx, int data_fd) { } if (le32_to_cpu(ctx->hdr.model) != 6245) { - ERROR("Unrecognized printer (%d)!\n", le32_to_cpu(ctx->hdr.model)); + ERROR("Unrecognized printer (%u)!\n", le32_to_cpu(ctx->hdr.model)); return CUPS_BACKEND_CANCEL; } @@ -1635,6 +1671,7 @@ static int shinkos6245_main_loop(void *vctx, int copies) { ERROR("Incorrect media loaded for print!\n"); return CUPS_BACKEND_HOLD; } + ctx->ribbon_code = media->ribbon_code; /* Send Set Time */ { @@ -1664,6 +1701,13 @@ static int shinkos6245_main_loop(void *vctx, int copies) { goto printer_error; } + /* Tell CUPS about the consumables we report */ + ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); + ATTR("marker-high-levels=100\n"); + ATTR("marker-low-levels=10\n"); + ATTR("marker-names='%s'\n", ribbon_sizes(ctx->ribbon_code)); + ATTR("marker-types=ribbonWax\n"); + // XXX check copies against remaining media! top: @@ -1686,12 +1730,27 @@ top: } if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) { + uint16_t donor, remain; + memcpy(rdbuf2, rdbuf, READBACK_LEN); INFO("Printer Status: 0x%02x (%s)\n", sts->hdr.status, status_str(sts->hdr.status)); + + /* Guessimate a percentage for the remaining media */ + donor = le32_to_cpu(sts->count_ribbon_left) * 100 / ribbon_counts(ctx->ribbon_code); + if (donor != ctx->last_donor) { + ctx->last_donor = donor; + ATTR("marker-levels=%d\n", donor); + } + remain = le32_to_cpu(sts->count_ribbon_left); + if (remain != ctx->last_remain) { + ctx->last_remain = remain; + ATTR("marker-message=\"%d prints remaining on '%s' ribbon\"\n", remain, ribbon_sizes(ctx->ribbon_code)); + } + if (sts->hdr.result != RESULT_SUCCESS) - goto printer_error; + goto printer_error; if (sts->hdr.error == ERROR_PRINTER) goto printer_error; } else if (state == last_state) { @@ -1700,11 +1759,22 @@ top: } last_state = state; - fflush(stderr); + fflush(stderr); switch (state) { case S_IDLE: INFO("Waiting for printer idle\n"); + + /* make sure we're not colliding with an existing + jobid */ + while (ctx->jobid == sts->bank1_printid || + ctx->jobid == sts->bank2_printid) { + ctx->jobid++; + ctx->jobid &= 0x7f; + if (!ctx->jobid) + ctx->jobid++; + } + /* If either bank is free, continue */ if (sts->bank1_status == BANK_STATUS_FREE || sts->bank2_status == BANK_STATUS_FREE) @@ -1714,7 +1784,7 @@ top: case S_PRINTER_READY_CMD: // XXX send "get eeprom backup command" - INFO("Initiating print job (internal id %d)\n", ctx->jobid); + INFO("Sending print job (internal id %u)\n", ctx->jobid); memset(cmdbuf, 0, CMDBUF_LEN); print->hdr.cmd = cpu_to_le16(S6245_CMD_PRINTJOB); @@ -1825,7 +1895,7 @@ static int shinkos6245_query_serno(struct libusb_device_handle *dev, uint8_t end struct dyesub_backend shinkos6245_backend = { .name = "Shinko/Sinfonia CHC-S6245", - .version = "0.04WIP", + .version = "0.07WIP", .uri_prefix = "shinkos6245", .cmdline_usage = shinkos6245_cmdline, .cmdline_arg = shinkos6245_cmdline_arg, diff --git a/src/cups/sony_updr150_print.c b/src/cups/backend_sonyupdr150.c index 0121443..be8423f 100644 --- a/src/cups/sony_updr150_print.c +++ b/src/cups/backend_sonyupdr150.c @@ -1,7 +1,7 @@ /* * Sony UP-DR150 Photo Printer CUPS backend -- libusb-1.0 version * - * (c) 2013-2015 Solomon Peachy <pizza@shaftnet.org> + * (c) 2013-2016 Solomon Peachy <pizza@shaftnet.org> * * The latest version of this program can be found at: * diff --git a/src/cups/blacklist b/src/cups/blacklist index b137624..573145e 100644 --- a/src/cups/blacklist +++ b/src/cups/blacklist @@ -159,5 +159,15 @@ # DNP DS-RX1 + Citizen CY 0x1343 0x0005 blacklist +# Citizen CW-02 +0x1343 0x0006 blacklist + +# DNP DS80D +0x1343 0x0007 blacklist + # DNP DS620 +0x1343 0x0008 blacklist 0x1452 0x8b01 blacklist + +# CIAAT Brava 21 +0x10ce 0x001e blacklist diff --git a/src/cups/command.types b/src/cups/command.types index 6b5f181..e03f094 100644 --- a/src/cups/command.types +++ b/src/cups/command.types @@ -1,6 +1,3 @@ -# -# "$Id: command.types,v 1.2 2007/12/23 17:31:51 easysw Exp $" -# # MIME types file for the CUPS drivers. # # Copyright 1993-2000 by Easy Software Products. @@ -22,7 +19,3 @@ # Define the new application/vnd.cups-command filetype... application/vnd.cups-command string(0,'#CUPS-COMMAND') - -# -# End of "$Id: command.types,v 1.2 2007/12/23 17:31:51 easysw Exp $". -# diff --git a/src/cups/commandtoepson.c b/src/cups/commandtoepson.c index e2d03b2..7706a04 100644 --- a/src/cups/commandtoepson.c +++ b/src/cups/commandtoepson.c @@ -1,6 +1,4 @@ /* - * "$Id: commandtoepson.c,v 1.4 2011/08/13 16:24:17 rlk Exp $" - * * EPSON ESC/P2 command filter for the Common UNIX Printing System. * * Copyright 1993-2000 by Easy Software Products. @@ -227,8 +225,3 @@ main(int argc, /* I - Number of command-line arguments */ return (0); } - - -/* - * End of "$Id: commandtoepson.c,v 1.4 2011/08/13 16:24:17 rlk Exp $". - */ diff --git a/src/cups/cups-calibrate.c b/src/cups/cups-calibrate.c index 28070b1..cc1c789 100644 --- a/src/cups/cups-calibrate.c +++ b/src/cups/cups-calibrate.c @@ -1,5 +1,4 @@ /* - * "$Id: cups-calibrate.c,v 1.6 2007/12/23 17:31:51 easysw Exp $" * * Super simple color calibration program for the Common UNIX * Printing System. @@ -95,14 +94,12 @@ main(int argc, puts("This program allows you to calibrate the color output of printers"); puts("using the Gutenprint CUPS or ESP Print Pro drivers."); puts(""); - puts("Please note that this program ONLY works with the Gutenprint CUPS or"); - puts("ESP Print Pro drivers. If you are using the Gimp-Print stp driver of"); - puts("GhostScript or the drivers of the Print plug-in for the GIMP, this"); - puts("calibration will not work."); + puts("Please note that this program ONLY works with the Gutenprint CUPS"); + puts("driver."); puts(""); - puts("These drivers by the text \"CUPS+Gutenprint\" or \"ESP Print Pro\" in"); - puts("the model description displayed by the CUPS web interface, KUPS,"); - puts("the ESP Print Pro Printer Manager, or printerdrake."); + puts("These drivers by the text \"CUPS+Gutenprint\""); + puts("the model description displayed by the CUPS web interface or"); + puts("similar tool."); puts(""); puts("If you are not using the correct driver, press CTRL+C now and"); puts("reinstall your printer queue with the appropriate driver first."); diff --git a/src/cups/cups-genppdupdate.in b/src/cups/cups-genppdupdate.in index 61b7206..fbfbc6b 100644 --- a/src/cups/cups-genppdupdate.in +++ b/src/cups/cups-genppdupdate.in @@ -1,5 +1,4 @@ #! @PERL@ -w -# $Id: cups-genppdupdate.in,v 1.61 2014/06/04 01:16:47 rlk Exp $ # Update CUPS PPDs for Gutenprint queues. # Copyright (C) 2002-2003 Roger Leigh (rleigh@debian.org) # diff --git a/src/cups/genppd.c b/src/cups/genppd.c index f026246..53b970d 100644 --- a/src/cups/genppd.c +++ b/src/cups/genppd.c @@ -1,6 +1,4 @@ /* - * "$Id: genppd.c,v 1.205 2015/10/17 16:27:18 rlk Exp $" - * * PPD file generation program for the CUPS drivers. * * Copyright 1993-2008 by Mike Sweet and Robert Krawitz. @@ -2739,8 +2737,3 @@ write_ppd( return (0); } - - -/* - * End of "$Id: genppd.c,v 1.205 2015/10/17 16:27:18 rlk Exp $". - */ diff --git a/src/cups/i18n.c b/src/cups/i18n.c index ee3e749..afe59a3 100644 --- a/src/cups/i18n.c +++ b/src/cups/i18n.c @@ -1,6 +1,4 @@ /* - * "$Id: i18n.c,v 1.9 2013/12/14 19:23:58 rlk Exp $" - * * Internationalization functions for CUPS drivers. * * Copyright 2008 Michael Sweet (mike@easysw.com) @@ -476,8 +474,3 @@ stpi_unquote(char *s) /* IO - Original string */ *d = '\0'; } - - -/* - * End of "$Id: i18n.c,v 1.9 2013/12/14 19:23:58 rlk Exp $". - */ diff --git a/src/cups/i18n.h b/src/cups/i18n.h index a75510b..222b2c3 100644 --- a/src/cups/i18n.h +++ b/src/cups/i18n.h @@ -1,6 +1,4 @@ /* - * "$Id: i18n.h,v 1.3 2009/04/11 19:05:12 rlk Exp $" - * * Internationalization definitions for CUPS drivers. * * Copyright 2008 Michael Sweet (mike@easysw.com) @@ -40,8 +38,3 @@ extern const char *stp_i18n_lookup(const stp_string_list_t *po, const char *message); extern void stp_i18n_printf(const stp_string_list_t *po, const char *message, ...); - - -/* - * End of "$Id: i18n.h,v 1.3 2009/04/11 19:05:12 rlk Exp $". - */ diff --git a/src/cups/mitsu70x_print.c b/src/cups/mitsu70x_print.c deleted file mode 100644 index 18b9218..0000000 --- a/src/cups/mitsu70x_print.c +++ /dev/null @@ -1,801 +0,0 @@ -/* - * Mitsubishi CP-D70/D707 Photo Printer CUPS backend -- libusb-1.0 version - * - * (c) 2013-2015 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 mitsu70x_backend - -#include "backend_common.h" - -#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_VID_KODAK 0x040a -#define USB_PID_KODAK305 0x404f - -/* Private data stucture */ -struct mitsu70x_ctx { - struct libusb_device_handle *dev; - uint8_t endp_up; - uint8_t endp_down; - int type; - - uint8_t *databuf; - int datalen; - - uint16_t rows; - uint16_t cols; -}; - -/* Program states */ -enum { - S_IDLE = 0, - S_SENT_ATTN, - S_SENT_HDR, - S_SENT_DATA, - S_FINISHED, -}; - -/* Printer data structures */ -struct mitsu70x_state { - uint32_t hdr; - uint8_t data[22]; -} __attribute__((packed)); - -struct mitsu70x_status_deck { - uint16_t present; /* 0x80 for NOT present, 0x00 otherwise */ - uint16_t unk[9]; - uint16_t capacity; /* media capacity */ - uint16_t remain; /* media remaining */ - uint16_t unkb[2]; - uint16_t prints; /* lifetime prints on deck? */ - uint16_t unkc[1]; - uint16_t blank[16]; /* All fields are 0x8000 */ -} __attribute__((packed)); - -struct mitsu70x_status_ver { - char ver[6]; - uint8_t unk[2]; /* checksum? */ -} __attribute__((packed)); - -struct mitsu70x_status_resp { - uint8_t hdr[4]; - uint8_t unk[36]; - int16_t model[6]; /* LE, UTF-16 */ - int16_t serno[6]; /* LE, UTF-16 */ - struct mitsu70x_status_ver vers[7]; - uint8_t null[8]; - struct mitsu70x_status_deck lower; - struct mitsu70x_status_deck upper; -} __attribute__((packed)); - -struct mitsu70x_hdr { - uint32_t cmd; - uint8_t zero0[12]; - - uint16_t cols; - uint16_t rows; - uint16_t lamcols; - uint16_t lamrows; - uint8_t superfine; - uint8_t zero1[7]; - - uint8_t deck; - uint8_t zero2[7]; - uint8_t zero3; - uint8_t laminate; - uint8_t zero4[6]; - - uint8_t multicut; - uint8_t zero5[15]; - - uint8_t zero6[448]; -} __attribute__((packed)); - -#define CMDBUF_LEN 512 -#define READBACK_LEN 256 - -static void *mitsu70x_init(void) -{ - struct mitsu70x_ctx *ctx = malloc(sizeof(struct mitsu70x_ctx)); - if (!ctx) { - ERROR("Memory Allocation Failure!\n"); - return NULL; - } - memset(ctx, 0, sizeof(struct mitsu70x_ctx)); - - return ctx; -} - -static void mitsu70x_attach(void *vctx, struct libusb_device_handle *dev, - uint8_t endp_up, uint8_t endp_down, uint8_t jobid) -{ - struct mitsu70x_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); - - ctx->type = lookup_printer_type(&mitsu70x_backend, - desc.idVendor, desc.idProduct); -} - - -static void mitsu70x_teardown(void *vctx) { - struct mitsu70x_ctx *ctx = vctx; - - if (!ctx) - return; - - if (ctx->databuf) - free(ctx->databuf); - free(ctx); -} - -static int mitsu70x_read_parse(void *vctx, int data_fd) { - struct mitsu70x_ctx *ctx = vctx; - uint8_t hdr[1024]; - int i, remain; - struct mitsu70x_hdr *mhdr = (struct mitsu70x_hdr*)(hdr + sizeof(struct mitsu70x_hdr)); - - if (!ctx) - return CUPS_BACKEND_FAILED; - - if (ctx->databuf) { - free(ctx->databuf); - ctx->databuf = NULL; - } - - /* Read in initial header */ - remain = sizeof(hdr); - while (remain > 0) { - i = read(data_fd, hdr + sizeof(hdr) - remain, remain); - if (i == 0) - return CUPS_BACKEND_CANCEL; - if (i < 0) - return CUPS_BACKEND_CANCEL; - remain -= i; - } - - /* Sanity check */ - if (hdr[0] != 0x1b || - hdr[1] != 0x45 || - hdr[2] != 0x57 || - hdr[3] != 0x55) { - ERROR("Unrecognized data format!\n"); - return CUPS_BACKEND_CANCEL; - } - - /* Work out printjob size */ - ctx->cols = be16_to_cpu(mhdr->cols); - ctx->rows = be16_to_cpu(mhdr->rows); - - remain = ctx->rows * ctx->cols * 2; - remain = (remain + 511) / 512 * 512; /* Round to nearest 512 bytes. */ - remain *= 3; /* One for each plane */ - - if (mhdr->laminate) { - i = be16_to_cpu(mhdr->lamcols) * be16_to_cpu(mhdr->lamrows) * 2; - i = (i + 511) / 512 * 512; /* Round to nearest 512 bytes. */ - remain += i; - } - - ctx->databuf = malloc(sizeof(hdr) + remain); - if (!ctx->databuf) { - ERROR("Memory allocation failure!\n"); - return CUPS_BACKEND_FAILED; - } - - memcpy(ctx->databuf, &hdr, sizeof(hdr)); - ctx->datalen += sizeof(hdr); - - /* Read in the spool data */ - 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; - ctx->datalen += i; - remain -= i; - } - - return CUPS_BACKEND_OK; -} - -static int mitsu70x_do_pagesetup(struct mitsu70x_ctx *ctx) -{ - uint8_t cmdbuf[CMDBUF_LEN]; - uint8_t rdbuf[READBACK_LEN]; - - uint16_t tmp; - - int num, ret; - - memset(cmdbuf, 0, CMDBUF_LEN); - cmdbuf[0] = 0x1b; - cmdbuf[1] = 0x56; - cmdbuf[2] = 0x33; - cmdbuf[3] = 0x00; - tmp = cpu_to_be16(ctx->cols); - memcpy(cmdbuf + 4, &tmp, 2); - tmp = cpu_to_be16(ctx->rows); - memcpy(cmdbuf + 6, &tmp, 2); - cmdbuf[8] = 0x00; // or 0x80?? - cmdbuf[9] = 0x00; - - if ((ret = send_data(ctx->dev, ctx->endp_down, - cmdbuf, 10))) - return CUPS_BACKEND_FAILED; - - /* Read in the printer status */ - ret = read_data(ctx->dev, ctx->endp_up, - rdbuf, READBACK_LEN, &num); - if (ret < 0) - return CUPS_BACKEND_FAILED; - - if (num != 6) { - ERROR("Short Read! (%d/%d)\n", num, 26); - return CUPS_BACKEND_FAILED; - } - - /* Make sure response is sane */ - if (rdbuf[0] != 0xe4 || - rdbuf[1] != 0x56 || - rdbuf[2] != 0x33) { - ERROR("Unknown response from printer\n"); - return CUPS_BACKEND_FAILED; - } - - return 0; -} - -static int mitsu70x_get_state(struct mitsu70x_ctx *ctx, struct mitsu70x_state *resp) -{ - uint8_t cmdbuf[CMDBUF_LEN]; - int num, ret; - - /* Send Printer Query */ - memset(cmdbuf, 0, CMDBUF_LEN); - cmdbuf[0] = 0x1b; - cmdbuf[1] = 0x56; - cmdbuf[2] = 0x31; - cmdbuf[3] = 0x30; - cmdbuf[4] = 0x00; - cmdbuf[5] = 0x00; - - if ((ret = send_data(ctx->dev, ctx->endp_down, - cmdbuf, 6))) - return ret; - - memset(resp, 0, sizeof(*resp)); - - ret = read_data(ctx->dev, ctx->endp_up, - (uint8_t*) resp, sizeof(*resp), &num); - - if (ret < 0) - return ret; - if (num != sizeof(*resp)) { - ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*resp)); - return 4; - } - - return 0; -} - -static int mitsu70x_get_status(struct mitsu70x_ctx *ctx, struct mitsu70x_status_resp *resp) -{ - uint8_t cmdbuf[CMDBUF_LEN]; - int num, ret; - - /* Send Printer Query */ - memset(cmdbuf, 0, CMDBUF_LEN); - cmdbuf[0] = 0x1b; - cmdbuf[1] = 0x56; - cmdbuf[2] = 0x32; - cmdbuf[3] = 0x30; - if ((ret = send_data(ctx->dev, ctx->endp_down, - cmdbuf, 4))) - return ret; - memset(resp, 0, sizeof(*resp)); - ret = read_data(ctx->dev, ctx->endp_up, - (uint8_t*) resp, sizeof(*resp), &num); - - if (ret < 0) - return ret; - if (num != sizeof(*resp)) { - ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*resp)); - return 4; - } - - return 0; -} - -static int mitsu70x_main_loop(void *vctx, int copies) { - struct mitsu70x_ctx *ctx = vctx; - - struct mitsu70x_state rdbuf = { .hdr = 0 }, rdbuf2 = { .hdr = 0 }; - - int last_state = -1, state = S_IDLE; - int ret; - - if (!ctx) - return CUPS_BACKEND_FAILED; - -top: - if (state != last_state) { - if (dyesub_debug) - DEBUG("last_state %d new %d\n", last_state, state); - } - - ret = mitsu70x_get_state(ctx, &rdbuf); - if (ret) - return CUPS_BACKEND_FAILED; - - if (memcmp(&rdbuf, &rdbuf2, sizeof(rdbuf))) { - memcpy(&rdbuf2, &rdbuf, sizeof(rdbuf)); - } else if (state == last_state) { - sleep(1); - } - last_state = state; - - fflush(stderr); - - switch (state) { - case S_IDLE: - INFO("Waiting for printer idle\n"); -#if 0 // XXX no idea if this works.. - if (rdbuf.data[9] != 0x00) { - break; - } -#endif - INFO("Sending attention sequence\n"); - if ((ret = send_data(ctx->dev, ctx->endp_down, - ctx->databuf, sizeof(struct mitsu70x_hdr)))) - return CUPS_BACKEND_FAILED; - - state = S_SENT_ATTN; - break; - case S_SENT_ATTN: { - struct mitsu70x_status_resp resp; - ret = mitsu70x_get_status(ctx, &resp); - if (ret < 0) - return CUPS_BACKEND_FAILED; - - /* Yes, do it twice.. */ - - ret = mitsu70x_get_status(ctx, &resp); - if (ret < 0) - return CUPS_BACKEND_FAILED; - - // XXX check resp for sanity? - - state = S_SENT_HDR; - break; - } - case S_SENT_HDR: - INFO("Sending Page setup sequence\n"); - if ((ret = mitsu70x_do_pagesetup(ctx))) - return ret; - - INFO("Sending header sequence\n"); - - /* K60 may require fixups */ - if (ctx->type == P_MITSU_K60) { - struct mitsu70x_hdr *hdr = (struct mitsu70x_hdr*) (ctx->databuf + sizeof(struct mitsu70x_hdr)); - /* K60 only has a lower deck */ - hdr->deck = 1; - - /* 4x6 prints on 6x8 media need multicut mode */ - if (ctx->cols == 0x0748 && - ctx->rows == 0x04c2) - hdr->multicut = 1; - } - - if ((ret = send_data(ctx->dev, ctx->endp_down, - ctx->databuf + sizeof(struct mitsu70x_hdr), - sizeof(struct mitsu70x_hdr)))) - return CUPS_BACKEND_FAILED; - - INFO("Sending data\n"); - - { - /* K60 and 305 need data sent in 256K chunks, but the first - chunk needs to subtract the length of the 512-byte header */ - int chunk = 256*1024 - sizeof(struct mitsu70x_hdr); - int sent = 1024; - while (ctx->datalen > 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; - } - } - - state = S_SENT_DATA; - break; - case S_SENT_DATA: - INFO("Waiting for printer to acknowledge completion\n"); - - state = S_FINISHED; - break; - default: - break; - }; - - if (state != S_FINISHED) - goto top; - - /* Clean up */ - if (terminate) - copies = 1; - - INFO("Print complete (%d copies remaining)\n", copies - 1); - - if (copies && --copies) { - state = S_IDLE; - goto top; - } - - return CUPS_BACKEND_OK; -} - -static void mitsu70x_dump_status(struct mitsu70x_status_resp *resp) -{ - unsigned int i; - - INFO("Model : "); - for (i = 0 ; i < 6 ; i++) { - DEBUG2("%c", le16_to_cpu(resp->model[i]) & 0x7f); - } - DEBUG2("\n"); - INFO("Serial Number : "); - for (i = 0 ; i < 6 ; i++) { - DEBUG2("%c", le16_to_cpu(resp->serno[i]) & 0x7f); - } - DEBUG2("\n"); - for (i = 0 ; i < 7 ; i++) { - char buf[7]; - if (resp->vers[i].ver[5] == '@') /* "DUMMY@" */ - continue; - memcpy(buf, resp->vers[i].ver, 6); - buf[6] = 0; - INFO("Component #%d ID: %s (%02x%02x)\n", - i, buf, resp->vers[i].unk[0], resp->vers[i].unk[1]); - } - if (resp->upper.present) { /* IOW, Not present */ - INFO("Prints remaining: %03d/%03d\n", - be16_to_cpu(resp->lower.remain), - be16_to_cpu(resp->lower.capacity)); - } else { - INFO("Prints remaining: Lower: %03d/%03d\n" - " Upper: %03d/%03d\n", - be16_to_cpu(resp->lower.remain), - be16_to_cpu(resp->lower.capacity), - be16_to_cpu(resp->upper.remain), - be16_to_cpu(resp->upper.capacity)); - } -} - -static int mitsu70x_query_status(struct mitsu70x_ctx *ctx) -{ - struct mitsu70x_status_resp resp; - int ret; - - ret = mitsu70x_get_status(ctx, &resp); - - if (!ret) - mitsu70x_dump_status(&resp); - - return ret; -} - -static int mitsu70x_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len) -{ - int ret, i; - struct mitsu70x_status_resp resp = { .hdr = { 0 } }; - - struct mitsu70x_ctx ctx = { - .dev = dev, - .endp_up = endp_up, - .endp_down = endp_down, - }; - - ret = mitsu70x_get_status(&ctx, &resp); - - if (buf_len > 6) /* Will we ever have a buffer under 6 bytes? */ - buf_len = 6; - - for (i = 0 ; i < buf_len ; i++) { - *buf++ = le16_to_cpu(resp.serno[i]) & 0x7f; - } - *buf = 0; /* Null-terminate the returned string */ - - return ret; -} - - -static void mitsu70x_cmdline(void) -{ - DEBUG("\t\t[ -s ] # Query status\n"); -} - -static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv) -{ - struct mitsu70x_ctx *ctx = vctx; - int i, j = 0; - - if (!ctx) - return -1; - - /* Reset arg parsing */ - optind = 1; - opterr = 0; - while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "s")) >= 0) { - switch(i) { - GETOPT_PROCESS_GLOBAL - case 's': - j = mitsu70x_query_status(ctx); - break; - default: - break; /* Ignore completely */ - } - - if (j) return j; - } - - return 0; -} - - -/* Exported */ -struct dyesub_backend mitsu70x_backend = { - .name = "Mitsubishi CP-D70/D707/K60", - .version = "0.32WIP", - .uri_prefix = "mitsu70x", - .cmdline_usage = mitsu70x_cmdline, - .cmdline_arg = mitsu70x_cmdline_arg, - .init = mitsu70x_init, - .attach = mitsu70x_attach, - .teardown = mitsu70x_teardown, - .read_parse = mitsu70x_read_parse, - .main_loop = mitsu70x_main_loop, - .query_serno = mitsu70x_query_serno, - .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_D70X, ""}, - { USB_VID_KODAK, USB_PID_KODAK305, P_MITSU_K60, ""}, - { 0, 0, 0, ""} - } -}; - -/* Mitsubish CP-D70DW/CP-D707DW/CP-K60DW-S/CP-D80DW/Kodak 305 data format - - Spool file consists of two headers followed by three image planes - and an optional lamination data plane. All blocks are rounded up to - a 512-byte boundary. - - All multi-byte numbers are big endian, ie MSB first. - - Header 1: (Init) - - 1b 45 57 55 00 00 00 00 00 00 00 00 00 00 00 00 - (padded by NULLs to a 512-byte boundary) - - Header 2: (Header) - - 1b 5a 54 PP 00 00 00 00 00 00 00 00 00 00 00 00 - XX XX YY YY QQ QQ ZZ ZZ SS 00 00 00 00 00 00 00 - UU 00 00 00 00 00 00 00 00 TT 00 00 00 00 00 00 - RR 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - - (padded by NULLs to a 512-byte boundary) - - PP == 0x01 on D70x/D80, 0x02 on K60/305 - XX XX == columns - YY YY == rows - QQ QQ == lamination columns (equal to XX XX) - ZZ ZZ == lamination rows (YY YY + 12) - SS == Print mode: 00 = Fine, 03 = SuperFine (D70x/D80 only), 04 = UltraFine - (Matte requires Superfine or Ultrafine) - UU == 00 = Auto, 01 = Lower Deck (required for K60/305), 02 = Upper Deck - TT == lamination: 00 glossy, 02 matte. - RR == 00 (normal), 01 = (Double-cut 4x6), 05 = (double-cut 2x6) - - Data planes: - 16-bit data, rounded up to 512-byte block (XX * YY * 2 bytes) - - Lamination plane: (only present if QQ and ZZ are nonzero) - 16-byte data, rounded up to 512-byte block (QQ * ZZ * 2 bytes) - - ******************************************************************** - - Command format: - - -> 1b 56 32 30 - <- [256 byte payload] - - PRINTER STATUS - - e4 56 32 30 00 00 00 00 00 00 00 00 00 00 00 00 .V20............ - 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 ................ - 44 80 00 00 5f 00 00 3d 43 00 50 00 44 00 37 00 D..._..=C.P.D.7. - 30 00 44 00 30 00 30 00 31 00 31 00 31 00 37 00 0.D.0.0.1.1.1.7. - 33 31 36 54 31 33 21 a3 33 31 35 42 31 32 f5 e5 316T13!.315B12.. - 33 31 39 42 31 31 a3 fb 33 31 38 45 31 32 50 0d 319B11..318E12P. - 33 31 37 41 32 32 a3 82 44 55 4d 4d 59 40 00 00 317A22..DUMMY@.. - 44 55 4d 4d 59 40 00 00 00 00 00 00 00 00 00 00 DUMMY@.......... - - LOWER DECK STATUS - - 00 00 00 00 00 00 02 04 3f 00 00 04 96 00 00 00 MM MM: media capacity - ff 0f 01 00 MM MM NN NN 00 00 00 00 05 28 75 80 NN NN: prints remaining - 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 - 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 - - alt (some sort of error state) - - 00 00 00 0a 05 05 01 d5 38 00 00 00 14 00 00 00 - ff ff ff ff ff ff ff ff ff ff 00 00 00 27 72 80 - 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 - 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 - - UPPER DECK STATUS (if present) - - XX XX 00 00 00 00 01 ee 3d 00 00 06 39 00 00 00 MM MM: media capacity - ff 02 00 00 MM MM NN NN 00 00 00 00 06 67 78 00 NN NN: prints remaining - 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 XX XX: 0x80 00 if no deck - 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 - - alt (no deck present) - - 80 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 - ff ff ff ff ff ff ff ff ff ff 00 00 00 00 80 00 - 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 - 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 - - -> 1b 56 31 30 00 00 - <- [26 byte payload] - - CP-D707DW: - - e4 56 31 30 00 00 00 XX YY ZZ 00 00 TT 00 00 00 - 00 00 00 00 WW 00 00 00 00 00 - - XX/YY/ZZ and WW/TT are unknown. Observed values: - - 00 00 00 00/00 - 40 80 a0 80/0f - 80 80 a0 - 40 80 90 - 40 80 00 - - also seen: - - e4 56 31 30 00 00 00 00 00 00 00 00 0f 00 00 00 - 00 0a 05 05 80 00 00 00 00 00 - - e4 56 31 30 00 00 00 40 80 90 10 00 0f 00 00 00 - 00 0a 05 05 80 00 00 00 00 00 - - e4 56 31 30 00 00 00 00 40 80 00 00 00 ff 40 00 - 00 00 00 00 80 00 00 00 00 00 - - print just submitted: - - e4 56 31 30 00 00 00 00 40 20 00 00 00 8c 00 00 - 00 00 00 00 80 00 00 00 00 00 - - prints running... - - e4 56 31 30 00 00 00 00 40 20 00 00 00 cf 00 20 - 00 00 00 00 80 00 00 00 00 00 - - - - CP-K60DW-S: - - e4 56 31 30 00 00 00 XX YY 00 00 00 0f 00 00 00 - 00 00 00 00 80 00 00 00 00 00 - - XX/YY are unknown, observed values: - - 40/80 - 00/00 - - Sent to start a print - - -> 1b 56 33 00 XX XX YY YY UU 00 - - XX XX == columns - YY YY == rows - UU == Unknown, seen 0x00 and 0x80 - - <- [ 6 byte payload ] - - e4 56 33 00 00 00 - e4 56 33 00 00 01 - e5 56 33 ff 01 01 (which appeared to work) - - ** ** ** ** ** ** - - The windows drivers seem to send the id and status queries before - and in between each of the chunks sent to the printer. There doesn't - appear to be any particular intelligence in the protocol, but it didn't - work when the raw dump was submitted as-is. - - ** ** ** ** ** ** - -Various deck status dumps: - -0080 00 00 00 00 00 00 01 d2 39 00 00 00 07 00 00 00 ........9....... -0090 61 8f 00 00 01 40 01 36 00 00 00 00 00 17 79 80 a....@.6......y. - -0080 00 00 00 00 00 00 01 c6 39 00 00 00 08 00 00 00 ........9....... -0090 61 8f 00 00 01 40 01 35 00 00 00 00 00 18 79 80 a....@.5......y. - -0080 00 00 00 00 00 00 02 19 50 00 00 00 19 00 00 01 ........P....... -0090 6c 8f 00 00 01 40 01 22 00 00 00 00 00 27 83 80 l....@.".....'.. - -0080 00 00 00 00 00 00 02 00 3e 00 00 04 96 00 00 00 ........>....... -0090 ff 0f 01 00 00 c8 00 52 00 00 00 00 05 28 75 80 .......R.....(u. - -00c0 00 00 00 00 00 00 01 f3 3d 00 00 06 39 00 00 00 ........=...9... -00d0 ff 02 00 00 01 90 00 c3 00 00 00 00 06 67 78 00 .............gx. - -0080 00 00 00 00 00 00 01 d0 38 00 00 03 70 00 00 00 ........8...p... -0090 ff 02 00 00 01 90 00 1e 01 00 00 00 03 83 72 80 ..............r. - -0080 00 00 00 00 00 00 01 d6 39 00 00 00 20 00 00 00 ........9... ... -0090 ff 02 00 00 01 90 01 7c 01 00 00 00 00 33 72 80 .......|.....3r. - - 00 00 00 0a 05 05 01 d5 38 00 00 00 14 00 00 00 - ff ff ff ff ff ff ff ff ff ff 00 00 00 27 72 80 ?? Error ?? - - 80 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 - ff ff ff ff ff ff ff ff ff ff 00 00 00 00 80 00 NO DECK PRESENT - */ diff --git a/src/cups/rastertoprinter.c b/src/cups/rastertoprinter.c index 4a1ae9c..1a89bc5 100644 --- a/src/cups/rastertoprinter.c +++ b/src/cups/rastertoprinter.c @@ -1,6 +1,4 @@ /* - * "$Id: rastertoprinter.c,v 1.143 2014/01/04 00:31:37 rlk Exp $" - * * Gutenprint based raster filter for the Common UNIX Printing System. * * Copyright 1993-2008 by Mike Sweet. @@ -1091,7 +1089,6 @@ main(int argc, /* I - Number of command-line arguments */ stp_vars_t *default_settings; int initialized_job = 0; const char *version_id; - const char *release_version_id; struct tms tms; long clocks_per_sec; struct timeval t1, t2; @@ -1126,7 +1123,6 @@ main(int argc, /* I - Number of command-line arguments */ (void) gettimeofday(&t1, &tz); stp_init(); version_id = stp_get_version(); - release_version_id = stp_get_release_version(); default_settings = stp_vars_create(); /* @@ -1209,13 +1205,13 @@ main(int argc, /* I - Number of command-line arguments */ strlen(CUPS_PPD_NICKNAME_STRING)) != ' '))) { stp_i18n_printf(po, _("ERROR: The PPD version (%s) is not compatible with " - "Gutenprint %s.\n"), + "Gutenprint %s. Please run `%scups-genppdupdate' as administrator.\n"), ppd->nickname+strlen(ppd->modelname)+strlen(CUPS_PPD_NICKNAME_STRING), - version_id); + version_id, SBINDIR); fprintf(stderr, "DEBUG: Gutenprint: If you have upgraded your version of Gutenprint\n"); fprintf(stderr, "DEBUG: Gutenprint: recently, you must reinstall all printer queues.\n"); fprintf(stderr, "DEBUG: Gutenprint: If the previous installed version of Gutenprint\n"); - fprintf(stderr, "DEBUG: Gutenprint: was 5.0.0 or higher, you can use the `cups-genppdupdate.%s'\n", release_version_id); + fprintf(stderr, "DEBUG: Gutenprint: was 5.0.0 or higher, you can use the `cups-genppdupdate'\n"); fprintf(stderr, "DEBUG: Gutenprint: program to do this; if the previous installed version\n"); fprintf(stderr, "DEBUG: Gutenprint: was older, you can use the Modify Printer command via\n"); fprintf(stderr, "DEBUG: Gutenprint: the CUPS web interface: http://localhost:631/printers.\n"); @@ -1707,8 +1703,3 @@ Image_width(stp_image_t *image) /* I - Image */ fprintf(stderr, "DEBUG: Gutenprint: Image_width %d\n", cups->adjusted_width); return (cups->adjusted_width); } - - -/* - * End of "$Id: rastertoprinter.c,v 1.143 2014/01/04 00:31:37 rlk Exp $". - */ |