summaryrefslogtreecommitdiff
path: root/src/cups
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2016-09-20 11:56:08 +0200
committerDidier Raboud <odyx@debian.org>2016-09-20 11:56:08 +0200
commit7f5731038556e5b03d2a886163ca2c873c77333d (patch)
tree8f4194af3949a73accf44b2b0bd8ebfa990ac577 /src/cups
parenta313257bdec71bc92a56598e74d9097c16cb6e48 (diff)
New upstream version 5.2.12~pre2
Diffstat (limited to 'src/cups')
-rw-r--r--src/cups/Makefile.am7
-rw-r--r--src/cups/Makefile.in363
-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.c67
-rw-r--r--src/cups/backend_common.h29
-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.c1609
-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/blacklist10
-rw-r--r--src/cups/command.types7
-rw-r--r--src/cups/commandtoepson.c7
-rw-r--r--src/cups/cups-calibrate.c13
-rw-r--r--src/cups/cups-genppdupdate.in1
-rw-r--r--src/cups/genppd.c7
-rw-r--r--src/cups/i18n.c7
-rw-r--r--src/cups/i18n.h7
-rw-r--r--src/cups/mitsu70x_print.c801
-rw-r--r--src/cups/rastertoprinter.c15
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 $".
- */