summaryrefslogtreecommitdiff
path: root/src/cups
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2019-09-13 17:56:14 +0200
committerDidier Raboud <odyx@debian.org>2019-09-13 17:56:14 +0200
commitb38516f13a1f563aa1eb7faf80965755ac63e3e6 (patch)
treefd60cd4095a45f7327d28dfe04bbfb34b7d7215a /src/cups
parente50542121e724e851fc5d6c68bb773f80c0bc12c (diff)
New upstream version 5.3.3
Diffstat (limited to 'src/cups')
-rw-r--r--src/cups/Makefile.am41
-rw-r--r--src/cups/Makefile.in154
-rw-r--r--src/cups/README116
-rw-r--r--src/cups/backend_canonselphy.c22
-rw-r--r--src/cups/backend_canonselphyneo.c10
-rw-r--r--src/cups/backend_common.c143
-rw-r--r--src/cups/backend_common.h70
-rw-r--r--src/cups/backend_dnpds40.c583
-rw-r--r--src/cups/backend_kodak1400.c36
-rw-r--r--src/cups/backend_kodak605.c725
-rw-r--r--src/cups/backend_kodak6800.c730
-rw-r--r--src/cups/backend_magicard.c28
-rw-r--r--src/cups/backend_mitsu70x.c95
-rw-r--r--src/cups/backend_mitsu9550.c495
-rw-r--r--src/cups/backend_mitsud90.c10
-rw-r--r--src/cups/backend_mitsup95d.c19
-rw-r--r--src/cups/backend_shinkos1245.c521
-rw-r--r--src/cups/backend_shinkos2145.c1081
-rw-r--r--src/cups/backend_shinkos6145.c1487
-rw-r--r--src/cups/backend_shinkos6245.c1279
-rw-r--r--src/cups/backend_sinfonia.c1154
-rw-r--r--src/cups/backend_sinfonia.h562
-rw-r--r--src/cups/backend_sonyupd.c1024
-rw-r--r--src/cups/backend_sonyupdr150.c568
-rw-r--r--src/cups/blacklist24
-rw-r--r--src/cups/cups-genppd.c23
-rw-r--r--src/cups/gutenprint.c2
-rw-r--r--src/cups/test-ppds.test.in (renamed from src/cups/test-ppds.in)20
-rw-r--r--src/cups/test-rastertogutenprint.in169
-rw-r--r--src/cups/test-rastertogutenprint.test.in (renamed from src/cups/test-rastertogutenprint.check.in)4
30 files changed, 5316 insertions, 5879 deletions
diff --git a/src/cups/Makefile.am b/src/cups/Makefile.am
index 2f70701..1812d55 100644
--- a/src/cups/Makefile.am
+++ b/src/cups/Makefile.am
@@ -99,11 +99,13 @@ endif
AM_TESTS_ENVIRONMENT=$(STP_ENV)
test-rastertogutenprint: min-pagesize
-test-rastertogutenprint.check: test-rastertogutenprint
-TESTS= test-ppds test-rastertogutenprint.check
-noinst_SCRIPTS=test-ppds \
+test-rastertogutenprint.test: test-rastertogutenprint
+TESTS= test-ppds.test test-rastertogutenprint.test
+test-rastertogutenprint.log: test-ppds.log
+
+noinst_SCRIPTS=test-ppds.test \
test-rastertogutenprint \
- test-rastertogutenprint.check \
+ test-rastertogutenprint.test \
min-pagesize
endif
@@ -121,7 +123,7 @@ commandtoepson_SOURCES = commandtoepson.c
commandtoepson_LDADD = $(CUPS_LIBS)
if BUILD_LIBUSB_BACKENDS
-backend_gutenprint_SOURCES = backend_canonselphy.c backend_canonselphyneo.c backend_kodak1400.c backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c backend_sonyupdr150.c backend_dnpds40.c backend_mitsu70x.c backend_mitsu9550.c backend_common.c backend_common.h backend_shinkos1245.c backend_shinkos6145.c backend_shinkos6245.c backend_mitsup95d.c backend_magicard.c backend_mitsud90.c
+backend_gutenprint_SOURCES = backend_canonselphy.c backend_canonselphyneo.c backend_kodak1400.c backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c backend_sonyupd.c backend_dnpds40.c backend_mitsu70x.c backend_mitsu9550.c backend_sinfonia.c backend_sinfonia.h backend_common.c backend_common.h backend_shinkos1245.c backend_shinkos6145.c backend_shinkos6245.c backend_mitsup95d.c backend_magicard.c backend_mitsud90.c
backend_gutenprint_LDADD = $(LIBUSB_LIBS) $(LIBUSB_BACKEND_LIBDEPS)
backend_gutenprint_CPPFLAGS = $(LIBUSB_CFLAGS) -DURI_PREFIX=\"gutenprint$(GUTENPRINT_MAJOR_VERSION)$(GUTENPRINT_MINOR_VERSION)+usb\" -DLIBUSB_PRE_1_0_10
@@ -229,7 +231,7 @@ all-local: $(INSTALL_DATA_LOCAL_DEPS)
ppd: ppd-stamp
-ppd-stamp: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(top_srcdir)/src/xml/xml-stamp
+ppd-stamp: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(top_srcdir)/src/xml/xml-stamp ppd-stamp-pre
$(MAKE) ppd-stamp-pre
$(MAKE) ppd-stamp-phony
touch ppd-stamp
@@ -256,60 +258,60 @@ ppd-nonls: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Non-localized PPDs:"
$(MKDIR_P) $(PPD_DIR)/C
$(MAKE) ppd-catalog-clean
- LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -l C -p $(PPD_DIR)/C @WHICH_PPDS@
+ LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -l C -p $(PPD_DIR)/C @WHICH_PPDS@ $(EXTRA_GENPPD_OPTS)
ppd-nonls-a: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Non-localized PPDs (all):"
$(MKDIR_P) $(PPD_DIR)/C
$(MAKE) ppd-catalog-clean
- LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -l C -p $(PPD_DIR)/C -a
+ LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -l C -p $(PPD_DIR)/C -a $(EXTRA_GENPPD_OPTS)
ppd-nonls-s: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Non-localized PPDs (simplified):"
$(MKDIR_P) $(PPD_DIR)/C
$(MAKE) ppd-catalog-clean
- LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -l C -p $(PPD_DIR)/C -s
+ LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -l C -p $(PPD_DIR)/C -s $(EXTRA_GENPPD_OPTS)
ppd-global: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs:"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global @WHICH_PPDS@
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global @WHICH_PPDS@ $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-a: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (all):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -a
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -a $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-s: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (simplified):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -s
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -s $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-ln: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (localized numbers for testing):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -N @WHICH_PPDS@
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -N @WHICH_PPDS@ $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-ln-a: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (all, localized numbers for testing):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -N -a
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -N -a $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-ln-s: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (all, localized numbers for testing):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -N -s
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -N -s $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-nls: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ ppd-nonls
@@ -319,7 +321,7 @@ ppd-nls: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ ppd-nonls
for language in `$(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -L` ; do \
$(MKDIR_P) $(PPD_DIR)/$$language ; \
echo -n "$$language: " ; \
- LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -l $$language -p $(PPD_DIR)/$$language; \
+ LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -l $$language -p $(PPD_DIR)/$$language $(EXTRA_GENPPD_OPTS); \
done
$(MAKE) ppd-catalog-clean
@@ -330,7 +332,7 @@ ppd-nls-a: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ ppd-nonls
for language in `$(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -L` ; do \
$(MKDIR_P) $(PPD_DIR)/$$language ; \
echo -n "$$language: " ; \
- LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) @WHICH_PPDS@ -l $$language -p $(PPD_DIR)/$$language -a; \
+ LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -l $$language -p $(PPD_DIR)/$$language -a $(EXTRA_GENPPD_OPTS); \
done
$(MAKE) ppd-catalog-clean
@@ -341,7 +343,7 @@ ppd-nls-s: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ ppd-nonls
for language in `$(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -L` ; do \
$(MKDIR_P) $(PPD_DIR)/$$language ; \
echo -n "$$language: " ; \
- LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) @WHICH_PPDS@ -l $$language -p $(PPD_DIR)/$$language -s; \
+ LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -l $$language -p $(PPD_DIR)/$$language -s $(EXTRA_GENPPD_OPTS); \
done
$(MAKE) ppd-catalog-clean
@@ -363,12 +365,11 @@ clean-local: ppd-catalog-clean ppd-clean
## Clean
CLEANFILES = ppd-stamp
-DISTCLEANFILES = cups-genppdupdate test-ppds
+DISTCLEANFILES = cups-genppdupdate test-ppds.test
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = \
COPYING \
- README \
blacklist \
calibrate.ppm \
command.txt \
diff --git a/src/cups/Makefile.in b/src/cups/Makefile.in
index 605047b..ecaf5a7 100644
--- a/src/cups/Makefile.in
+++ b/src/cups/Makefile.in
@@ -102,24 +102,25 @@ host_triplet = @host@
@BUILD_CUPS_TRUE@@BUILD_LIBUSB_BACKENDS_TRUE@cupsexec_backend_PROGRAMS = backend_gutenprint$(EXEEXT)
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/intlmacosx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4local/stp.m4 \
+ $(top_srcdir)/m4local/stp_cups.m4 \
+ $(top_srcdir)/m4local/stp_option.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(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_option.m4 \
- $(top_srcdir)/m4/stp_release.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/stp_release.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES = Info.plist cups-genppdupdate test-ppds \
+CONFIG_CLEAN_FILES = Info.plist cups-genppdupdate test-ppds.test \
min-pagesize test-rastertogutenprint \
- test-rastertogutenprint.check
+ test-rastertogutenprint.test
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(cupsexec_backenddir)" \
@@ -133,21 +134,22 @@ PROGRAMS = $(bin_PROGRAMS) $(cupsexec_backend_PROGRAMS) \
am__backend_gutenprint_SOURCES_DIST = backend_canonselphy.c \
backend_canonselphyneo.c backend_kodak1400.c \
backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c \
- backend_sonyupdr150.c backend_dnpds40.c backend_mitsu70x.c \
- backend_mitsu9550.c backend_common.c backend_common.h \
- backend_shinkos1245.c backend_shinkos6145.c \
- backend_shinkos6245.c backend_mitsup95d.c backend_magicard.c \
- backend_mitsud90.c
+ backend_sonyupd.c backend_dnpds40.c backend_mitsu70x.c \
+ backend_mitsu9550.c backend_sinfonia.c backend_sinfonia.h \
+ backend_common.c backend_common.h backend_shinkos1245.c \
+ backend_shinkos6145.c backend_shinkos6245.c \
+ backend_mitsup95d.c backend_magicard.c backend_mitsud90.c
@BUILD_LIBUSB_BACKENDS_TRUE@am_backend_gutenprint_OBJECTS = backend_gutenprint-backend_canonselphy.$(OBJEXT) \
@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_canonselphyneo.$(OBJEXT) \
@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_kodak1400.$(OBJEXT) \
@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_kodak6800.$(OBJEXT) \
@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_kodak605.$(OBJEXT) \
@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_sonyupd.$(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_mitsu9550.$(OBJEXT) \
+@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_sinfonia.$(OBJEXT) \
@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_common.$(OBJEXT) \
@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_shinkos1245.$(OBJEXT) \
@BUILD_LIBUSB_BACKENDS_TRUE@ backend_gutenprint-backend_shinkos6145.$(OBJEXT) \
@@ -269,7 +271,8 @@ am__depfiles_remade = \
./$(DEPDIR)/backend_gutenprint-backend_shinkos2145.Po \
./$(DEPDIR)/backend_gutenprint-backend_shinkos6145.Po \
./$(DEPDIR)/backend_gutenprint-backend_shinkos6245.Po \
- ./$(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Po \
+ ./$(DEPDIR)/backend_gutenprint-backend_sinfonia.Po \
+ ./$(DEPDIR)/backend_gutenprint-backend_sonyupd.Po \
./$(DEPDIR)/commandtocanon.Po ./$(DEPDIR)/commandtoepson.Po \
./$(DEPDIR)/cups-calibrate.Po \
./$(DEPDIR)/cups_genppd_@GUTENPRINT_RELEASE_VERSION@-cups-genppd.Po \
@@ -493,8 +496,12 @@ RECHECK_LOGS = $(TEST_LOGS)
AM_RECURSIVE_TARGETS = check recheck
TEST_SUITE_LOG = test-suite.log
TEST_EXTENSIONS = @EXEEXT@ .test
-LOG_DRIVER = $(SHELL) $(top_srcdir)/scripts/test-driver
-LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/scripts/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
am__set_b = \
case '$@' in \
*/*) \
@@ -505,19 +512,13 @@ am__set_b = \
*) \
b='$*';; \
esac
-am__test_logs1 = $(TESTS:=.log)
-am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/scripts/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
- $(TEST_LOG_FLAGS)
am__DIST_COMMON = $(srcdir)/Info.plist.in $(srcdir)/Makefile.in \
$(srcdir)/cups-genppdupdate.in $(srcdir)/min-pagesize.in \
- $(srcdir)/test-ppds.in \
- $(srcdir)/test-rastertogutenprint.check.in \
+ $(srcdir)/test-ppds.test.in \
$(srcdir)/test-rastertogutenprint.in \
+ $(srcdir)/test-rastertogutenprint.test.in \
$(top_srcdir)/scripts/depcomp $(top_srcdir)/scripts/global.mk \
- $(top_srcdir)/scripts/test-driver COPYING README
+ $(top_srcdir)/scripts/test-driver COPYING
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgdatadir = $(cups_conf_datadir)
pkglibdir = $(cups_conf_serverbin)
@@ -568,7 +569,6 @@ EXEEXT = @EXEEXT@
FGREP = @FGREP@
FIND = @FIND@
GENPPD_LIBS = @GENPPD_LIBS@
-GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GIMP2_CFLAGS = @GIMP2_CFLAGS@
GIMP2_LIBS = @GIMP2_LIBS@
GIMPTOOL2_CHECK = @GIMPTOOL2_CHECK@
@@ -677,7 +677,6 @@ VERSION = @VERSION@
WHICH_PPDS = @WHICH_PPDS@
XGETTEXT = @XGETTEXT@
XGETTEXT_015 = @XGETTEXT_015@
-XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XZ = @XZ@
YACC = @YACC@
YFLAGS = @YFLAGS@
@@ -771,10 +770,10 @@ STP_ENV = $(STP_NONLS_ENV) STP_LOCALEDIR=$(top_builddir)/src/cups/$(PPD_DIR)cata
@BUILD_SIMPLIFIED_CUPS_PPDS_TRUE@BUILD_SIMPLE_PPDS = -DGENERATE_SIMPLIFIED_PPDS
@BUILD_CUPS_TRUE@sbin_SCRIPTS = cups-genppdupdate
@BUILD_CUPS_TRUE@AM_TESTS_ENVIRONMENT = $(STP_ENV)
-@BUILD_CUPS_TRUE@TESTS = test-ppds test-rastertogutenprint.check
-@BUILD_CUPS_TRUE@noinst_SCRIPTS = test-ppds \
+@BUILD_CUPS_TRUE@TESTS = test-ppds.test test-rastertogutenprint.test
+@BUILD_CUPS_TRUE@noinst_SCRIPTS = test-ppds.test \
@BUILD_CUPS_TRUE@ test-rastertogutenprint \
-@BUILD_CUPS_TRUE@ test-rastertogutenprint.check \
+@BUILD_CUPS_TRUE@ test-rastertogutenprint.test \
@BUILD_CUPS_TRUE@ min-pagesize
@BUILD_GENPPD_STATIC_TRUE@STATIC_LDOPTS = -static -export-dynamic
@@ -784,7 +783,7 @@ commandtocanon_SOURCES = commandtocanon.c
commandtocanon_LDADD = $(CUPS_LIBS)
commandtoepson_SOURCES = commandtoepson.c
commandtoepson_LDADD = $(CUPS_LIBS)
-@BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_SOURCES = backend_canonselphy.c backend_canonselphyneo.c backend_kodak1400.c backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c backend_sonyupdr150.c backend_dnpds40.c backend_mitsu70x.c backend_mitsu9550.c backend_common.c backend_common.h backend_shinkos1245.c backend_shinkos6145.c backend_shinkos6245.c backend_mitsup95d.c backend_magicard.c backend_mitsud90.c
+@BUILD_LIBUSB_BACKENDS_TRUE@backend_gutenprint_SOURCES = backend_canonselphy.c backend_canonselphyneo.c backend_kodak1400.c backend_kodak6800.c backend_kodak605.c backend_shinkos2145.c backend_sonyupd.c backend_dnpds40.c backend_mitsu70x.c backend_mitsu9550.c backend_sinfonia.c backend_sinfonia.h backend_common.c backend_common.h backend_shinkos1245.c backend_shinkos6145.c backend_shinkos6245.c backend_mitsup95d.c backend_magicard.c backend_mitsud90.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 = cups-genppd.c genppd.c genppd.h i18n.c i18n.h
@@ -806,11 +805,10 @@ pkgsysconf_DATA = $(CUPS_CONF)
@USE_NLS_TRUE@PPD_NLS_1 = ppd-nls
@BUILD_LIBUSB_BACKENDS_TRUE@INSTALL_BLACKLIST = install-blacklist
CLEANFILES = ppd-stamp
-DISTCLEANFILES = cups-genppdupdate test-ppds
+DISTCLEANFILES = cups-genppdupdate test-ppds.test
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = \
COPYING \
- README \
blacklist \
calibrate.ppm \
command.txt \
@@ -854,13 +852,13 @@ Info.plist: $(top_builddir)/config.status $(srcdir)/Info.plist.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
cups-genppdupdate: $(top_builddir)/config.status $(srcdir)/cups-genppdupdate.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
-test-ppds: $(top_builddir)/config.status $(srcdir)/test-ppds.in
+test-ppds.test: $(top_builddir)/config.status $(srcdir)/test-ppds.test.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
min-pagesize: $(top_builddir)/config.status $(srcdir)/min-pagesize.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
test-rastertogutenprint: $(top_builddir)/config.status $(srcdir)/test-rastertogutenprint.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
-test-rastertogutenprint.check: $(top_builddir)/config.status $(srcdir)/test-rastertogutenprint.check.in
+test-rastertogutenprint.test: $(top_builddir)/config.status $(srcdir)/test-rastertogutenprint.test.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@@ -1193,7 +1191,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_shinkos2145.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_shinkos6145.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_shinkos6245.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_sinfonia.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_gutenprint-backend_sonyupd.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commandtocanon.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commandtoepson.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cups-calibrate.Po@am__quote@ # am--include-marker
@@ -1317,19 +1316,19 @@ backend_gutenprint-backend_shinkos2145.obj: backend_shinkos2145.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_shinkos2145.obj `if test -f 'backend_shinkos2145.c'; then $(CYGPATH_W) 'backend_shinkos2145.c'; else $(CYGPATH_W) '$(srcdir)/backend_shinkos2145.c'; fi`
-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@
+backend_gutenprint-backend_sonyupd.o: backend_sonyupd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_sonyupd.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_sonyupd.Tpo -c -o backend_gutenprint-backend_sonyupd.o `test -f 'backend_sonyupd.c' || echo '$(srcdir)/'`backend_sonyupd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_sonyupd.Tpo $(DEPDIR)/backend_gutenprint-backend_sonyupd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_sonyupd.c' object='backend_gutenprint-backend_sonyupd.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_sonyupdr150.o `test -f 'backend_sonyupdr150.c' || echo '$(srcdir)/'`backend_sonyupdr150.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_sonyupd.o `test -f 'backend_sonyupd.c' || echo '$(srcdir)/'`backend_sonyupd.c
-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@
+backend_gutenprint-backend_sonyupd.obj: backend_sonyupd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_sonyupd.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_sonyupd.Tpo -c -o backend_gutenprint-backend_sonyupd.obj `if test -f 'backend_sonyupd.c'; then $(CYGPATH_W) 'backend_sonyupd.c'; else $(CYGPATH_W) '$(srcdir)/backend_sonyupd.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_sonyupd.Tpo $(DEPDIR)/backend_gutenprint-backend_sonyupd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_sonyupd.c' object='backend_gutenprint-backend_sonyupd.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_sonyupdr150.obj `if test -f 'backend_sonyupdr150.c'; then $(CYGPATH_W) 'backend_sonyupdr150.c'; else $(CYGPATH_W) '$(srcdir)/backend_sonyupdr150.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_sonyupd.obj `if test -f 'backend_sonyupd.c'; then $(CYGPATH_W) 'backend_sonyupd.c'; else $(CYGPATH_W) '$(srcdir)/backend_sonyupd.c'; fi`
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
@@ -1373,6 +1372,20 @@ backend_gutenprint-backend_mitsu9550.obj: backend_mitsu9550.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_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_sinfonia.o: backend_sinfonia.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_sinfonia.o -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_sinfonia.Tpo -c -o backend_gutenprint-backend_sinfonia.o `test -f 'backend_sinfonia.c' || echo '$(srcdir)/'`backend_sinfonia.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_sinfonia.Tpo $(DEPDIR)/backend_gutenprint-backend_sinfonia.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_sinfonia.c' object='backend_gutenprint-backend_sinfonia.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_sinfonia.o `test -f 'backend_sinfonia.c' || echo '$(srcdir)/'`backend_sinfonia.c
+
+backend_gutenprint-backend_sinfonia.obj: backend_sinfonia.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backend_gutenprint-backend_sinfonia.obj -MD -MP -MF $(DEPDIR)/backend_gutenprint-backend_sinfonia.Tpo -c -o backend_gutenprint-backend_sinfonia.obj `if test -f 'backend_sinfonia.c'; then $(CYGPATH_W) 'backend_sinfonia.c'; else $(CYGPATH_W) '$(srcdir)/backend_sinfonia.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_sinfonia.Tpo $(DEPDIR)/backend_gutenprint-backend_sinfonia.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend_sinfonia.c' object='backend_gutenprint-backend_sinfonia.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(backend_gutenprint_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backend_gutenprint-backend_sinfonia.obj `if test -f 'backend_sinfonia.c'; then $(CYGPATH_W) 'backend_sinfonia.c'; else $(CYGPATH_W) '$(srcdir)/backend_sinfonia.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
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backend_gutenprint-backend_common.Tpo $(DEPDIR)/backend_gutenprint-backend_common.Po
@@ -1796,20 +1809,6 @@ recheck: all
am__force_recheck=am--force-recheck \
TEST_LOGS="$$log_list"; \
exit $$?
-test-ppds.log: test-ppds
- @p='test-ppds'; \
- b='test-ppds'; \
- $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
- --log-file $$b.log --trs-file $$b.trs \
- $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
- "$$tst" $(AM_TESTS_FD_REDIRECT)
-test-rastertogutenprint.check.log: test-rastertogutenprint.check
- @p='test-rastertogutenprint.check'; \
- b='test-rastertogutenprint.check'; \
- $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
- --log-file $$b.log --trs-file $$b.trs \
- $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
- "$$tst" $(AM_TESTS_FD_REDIRECT)
.test.log:
@p='$<'; \
$(am__set_b); \
@@ -1931,7 +1930,8 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/backend_gutenprint-backend_shinkos2145.Po
-rm -f ./$(DEPDIR)/backend_gutenprint-backend_shinkos6145.Po
-rm -f ./$(DEPDIR)/backend_gutenprint-backend_shinkos6245.Po
- -rm -f ./$(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Po
+ -rm -f ./$(DEPDIR)/backend_gutenprint-backend_sinfonia.Po
+ -rm -f ./$(DEPDIR)/backend_gutenprint-backend_sonyupd.Po
-rm -f ./$(DEPDIR)/commandtocanon.Po
-rm -f ./$(DEPDIR)/commandtoepson.Po
-rm -f ./$(DEPDIR)/cups-calibrate.Po
@@ -2010,7 +2010,8 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/backend_gutenprint-backend_shinkos2145.Po
-rm -f ./$(DEPDIR)/backend_gutenprint-backend_shinkos6145.Po
-rm -f ./$(DEPDIR)/backend_gutenprint-backend_shinkos6245.Po
- -rm -f ./$(DEPDIR)/backend_gutenprint-backend_sonyupdr150.Po
+ -rm -f ./$(DEPDIR)/backend_gutenprint-backend_sinfonia.Po
+ -rm -f ./$(DEPDIR)/backend_gutenprint-backend_sonyupd.Po
-rm -f ./$(DEPDIR)/commandtocanon.Po
-rm -f ./$(DEPDIR)/commandtoepson.Po
-rm -f ./$(DEPDIR)/cups-calibrate.Po
@@ -2093,7 +2094,8 @@ $(top_builddir)/src/gutenprintui2/libgutenprintui2.la:
@BUILD_CUPS_TRUE@@BUILD_LIBUSB_BACKENDS_TRUE@ chmod 700 $(DESTDIR)$(pkglibdir)/backend/backend_gutenprint
@BUILD_CUPS_TRUE@@BUILD_LIBUSB_BACKENDS_TRUE@ mv $(DESTDIR)$(pkglibdir)/backend/backend_gutenprint "$(DESTDIR)$(pkglibdir)/backend/gutenprint$(GUTENPRINT_MAJOR_VERSION)$(GUTENPRINT_MINOR_VERSION)+usb"
@BUILD_CUPS_TRUE@test-rastertogutenprint: min-pagesize
-@BUILD_CUPS_TRUE@test-rastertogutenprint.check: test-rastertogutenprint
+@BUILD_CUPS_TRUE@test-rastertogutenprint.test: test-rastertogutenprint
+@BUILD_CUPS_TRUE@test-rastertogutenprint.log: test-ppds.log
@BUILD_LIBUSB_BACKENDS_TRUE@install-blacklist:
@BUILD_LIBUSB_BACKENDS_TRUE@ $(MKDIR_P) $(DESTDIR)$(cupsdata_blacklistdir)
@BUILD_LIBUSB_BACKENDS_TRUE@ $(INSTALL_DATA) $(srcdir)/blacklist $(DESTDIR)$(cupsdata_blacklistdir)/net.sf.gimp-print.usb-quirks
@@ -2158,7 +2160,7 @@ all-local: $(INSTALL_DATA_LOCAL_DEPS)
ppd: ppd-stamp
-ppd-stamp: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(top_srcdir)/src/xml/xml-stamp
+ppd-stamp: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(top_srcdir)/src/xml/xml-stamp ppd-stamp-pre
$(MAKE) ppd-stamp-pre
$(MAKE) ppd-stamp-phony
touch ppd-stamp
@@ -2185,60 +2187,60 @@ ppd-nonls: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Non-localized PPDs:"
$(MKDIR_P) $(PPD_DIR)/C
$(MAKE) ppd-catalog-clean
- LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -l C -p $(PPD_DIR)/C @WHICH_PPDS@
+ LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -l C -p $(PPD_DIR)/C @WHICH_PPDS@ $(EXTRA_GENPPD_OPTS)
ppd-nonls-a: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Non-localized PPDs (all):"
$(MKDIR_P) $(PPD_DIR)/C
$(MAKE) ppd-catalog-clean
- LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -l C -p $(PPD_DIR)/C -a
+ LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -l C -p $(PPD_DIR)/C -a $(EXTRA_GENPPD_OPTS)
ppd-nonls-s: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Non-localized PPDs (simplified):"
$(MKDIR_P) $(PPD_DIR)/C
$(MAKE) ppd-catalog-clean
- LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -l C -p $(PPD_DIR)/C -s
+ LC_ALL= LANG= LANGUAGE= $(STP_NONLS_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -l C -p $(PPD_DIR)/C -s $(EXTRA_GENPPD_OPTS)
ppd-global: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs:"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global @WHICH_PPDS@
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global @WHICH_PPDS@ $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-a: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (all):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -a
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -a $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-s: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (simplified):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -s
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -s $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-ln: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (localized numbers for testing):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -N @WHICH_PPDS@
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -N @WHICH_PPDS@ $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-ln-a: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (all, localized numbers for testing):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -N -a
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -N -a $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-global-ln-s: cups-genppd.@GUTENPRINT_RELEASE_VERSION@
@echo "Global PPDs (all, localized numbers for testing):"
$(MKDIR_P) $(PPD_DIR)/Global
$(MAKE) ppd-catalog
- LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -p $(PPD_DIR)/Global -N -s
+ LC_ALL= LANG= LANGUAGE= $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -p $(PPD_DIR)/Global -N -s $(EXTRA_GENPPD_OPTS)
$(MAKE) ppd-catalog-clean
ppd-nls: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ ppd-nonls
@@ -2248,7 +2250,7 @@ ppd-nls: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ ppd-nonls
for language in `$(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -L` ; do \
$(MKDIR_P) $(PPD_DIR)/$$language ; \
echo -n "$$language: " ; \
- LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) -l $$language -p $(PPD_DIR)/$$language; \
+ LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ -l $$language -p $(PPD_DIR)/$$language $(EXTRA_GENPPD_OPTS); \
done
$(MAKE) ppd-catalog-clean
@@ -2259,7 +2261,7 @@ ppd-nls-a: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ ppd-nonls
for language in `$(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -L` ; do \
$(MKDIR_P) $(PPD_DIR)/$$language ; \
echo -n "$$language: " ; \
- LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) @WHICH_PPDS@ -l $$language -p $(PPD_DIR)/$$language -a; \
+ LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -l $$language -p $(PPD_DIR)/$$language -a $(EXTRA_GENPPD_OPTS); \
done
$(MAKE) ppd-catalog-clean
@@ -2270,7 +2272,7 @@ ppd-nls-s: cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ ppd-nonls
for language in `$(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -L` ; do \
$(MKDIR_P) $(PPD_DIR)/$$language ; \
echo -n "$$language: " ; \
- LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ $(EXTRA_GENPPD_OPTS) @WHICH_PPDS@ -l $$language -p $(PPD_DIR)/$$language -s; \
+ LC_ALL=$$language LANG=$$language LANGUAGE=$$language $(STP_ENV) ./cups-genppd.@GUTENPRINT_RELEASE_VERSION@ @WHICH_PPDS@ -l $$language -p $(PPD_DIR)/$$language -s $(EXTRA_GENPPD_OPTS); \
done
$(MAKE) ppd-catalog-clean
diff --git a/src/cups/README b/src/cups/README
deleted file mode 100644
index 5deadb2..0000000
--- a/src/cups/README
+++ /dev/null
@@ -1,116 +0,0 @@
-README.txt - 11/21/2001 - CUPS Drivers based on Gutenprint
-----------------------------------------------------------
-
-This file describes the CUPS drivers based on the Gutenprint project.
-
-Note: to use these drivers you must have CUPS 1.1.9 or higher. We
-recommend use of CUPS 1.1.12 or higher.
-
-All code is Copyright 1997-2001 by Easy Software Products and/or the
-Gutenprint project and is provided under the terms of the GNU General
-Public License. The licensing details are provided in the file
-"LICENSE.txt".
-
-
-INTRODUCTION
-
-The CUPS drivers contain all of the files needed to support
-photo-quality printing on any printer supported by the Gutenprint
-project. You can find out more about the Common UNIX Printing System
-("CUPS"), an IPP-based printing system for UNIX/Linux, at:
-
- http://www.cups.org
-
-
-WHY DRIVERS FOR CUPS?
-
-CUPS is designed from the ground up to support printing to modern
-printers. In order to support as many applications as possible, CUPS
-provides a PostScript RIP (currently based on GNU GhostScript 5.50) as
-well as an image file RIP and many file filters that handle conversion
-of files to a format usable by a printer driver. The filter interface
-is extensible to support new types of files that can be printed
-(e.g. a GNOME metafile, etc.) All of this filtering happens "behind
-the scenes" so is transparent to the user.
-
-In addition, CUPS uses PostScript Printer Description ("PPD") files to
-describe printers, allowing applications to see the available printer
-features and capabilities easily. The CUPS PPD files add a few
-additional attributes to the standard PPD specification to support
-printing to non-PS printers.
-
-
-WHAT TOOLS ARE INCLUDED?
-
-We provide two tools for making CUPS drivers.
-
-The first is called "cups-calibrate" which allows you to do
-super-simple color calibration of your printer drivers. It is an
-interactive program that prints several calibration images through
-your driver until a final profile is produced.
-
-The second is called "genppd" which generates PPD files. These PPD
-files are created in several languages. The program reads printer
-driver information from the Gutenprint driver database and produces a
-PPD file for each driver. Normally, users do not have to use this
-tool directly; it is run automatically in the build process.
-
-
-WHAT DRIVERS ARE INCLUDED?
-
-We support all of the Gutenprint drivers supported by the project. The
-Canon and EPSON drivers also support simple printer commands to do head
-cleaning, test prints, and alignment, as well as an EPSON-specific
-backend that provides ink level information to the user.
-
-The printer drivers in this distribution are so-called "raster"
-printer drivers. This means that they receive a stream of images, one
-per page, that contain all of the colors, etc. for the printer. The
-printer driver then only needs to convert this to the appropriate
-printer commands and raster data to get a printed page.
-
-We also have a new experimental interface for printer commands using
-CUPS printer command files - ASCII text files with printer commands in
-them. This allows you to do a head cleaning, align the print heads,
-etc.
-
-
-WHAT SOFTWARE DO I NEED?
-
-Currently, CUPS 1.1.9 or higher is required, as is an ANSI C compliant
-compiler like GCC. The code has been tested on a number of vendor
-compilers and should be quite portable.
-
-
-HOW DO I START USING THESE DRIVERS?
-
-Please read the README file at top level.
-
-
-WHO DO I CONTACT TO GET HELP?
-
-For support issues, you should contact
-gimp-print-devel@sourceforge.net, the developer mailing list for the
-Gutenprint project in general.
-
-The primary author of this driver is Michael Sweet of Easy Software
-Products (mike@easysw.com). Mike is also the main developer for CUPS.
-Please don't expect an instant response (or even a response within a
-week) as Mike often accumulates a backlog of 100 or more messages each
-day.
-
-
-COMMERCIAL SUPPORT
-
-Easy Software Products provides commercial support for all of
-its printing products. Please see our web site for more
-information:
-
- http://www.easysw.com
-
-
-LEGAL STUFF
-
-CUPS, the Common UNIX Printing System, and the CUPS logo are the
-trademark property of Easy Software Products. Please see the
-CUPS software license for the terms of its use.
diff --git a/src/cups/backend_canonselphy.c b/src/cups/backend_canonselphy.c
index 42b3f45..978df0d 100644
--- a/src/cups/backend_canonselphy.c
+++ b/src/cups/backend_canonselphy.c
@@ -691,15 +691,6 @@ static void canonselphy_cleanup_job(const void *vjob) {
free((void*)job);
}
-static void canonselphy_teardown(void *vctx) {
- struct canonselphy_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int canonselphy_read_parse(void *vctx, const void **vjob, int data_fd, int copies)
{
struct canonselphy_ctx *ctx = vctx;
@@ -725,8 +716,10 @@ static int canonselphy_read_parse(void *vctx, const void **vjob, int data_fd, in
job contents. Ignore it if it comes through here.. */
i = read(data_fd, rdbuf, 4);
if (i != 4) {
- if (i == 0)
+ if (i == 0) {
+ canonselphy_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
+ }
ERROR("Read failed (%d/%d)\n", i, 4);
perror("ERROR: Read failed");
canonselphy_cleanup_job(job);
@@ -743,8 +736,10 @@ static int canonselphy_read_parse(void *vctx, const void **vjob, int data_fd, in
/* Read the rest of the header.. */
i = read(data_fd, rdbuf + offset, MAX_HEADER - offset);
if (i != MAX_HEADER - offset) {
- if (i == 0)
+ if (i == 0) {
+ canonselphy_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
+ }
ERROR("Read failed (%d/%d)\n",
i, MAX_HEADER - offset);
perror("ERROR: Read failed");
@@ -763,8 +758,8 @@ static int canonselphy_read_parse(void *vctx, const void **vjob, int data_fd, in
}
if (printer_type != ctx->type) {
- ERROR("Printer/Job mismatch (%d/%d)\n", ctx->type, ctx->printer->type);
- free(job);
+ ERROR("Printer/Job mismatch (%d/%d/%d)\n", ctx->type, ctx->printer->type, printer_type);
+ canonselphy_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
}
@@ -1161,7 +1156,6 @@ struct dyesub_backend canonselphy_backend = {
.cmdline_arg = canonselphy_cmdline_arg,
.init = canonselphy_init,
.attach = canonselphy_attach,
- .teardown = canonselphy_teardown,
.read_parse = canonselphy_read_parse,
.cleanup_job = canonselphy_cleanup_job,
.main_loop = canonselphy_main_loop,
diff --git a/src/cups/backend_canonselphyneo.c b/src/cups/backend_canonselphyneo.c
index 93f539d..f822912 100644
--- a/src/cups/backend_canonselphyneo.c
+++ b/src/cups/backend_canonselphyneo.c
@@ -251,15 +251,6 @@ static void selphyneo_cleanup_job(const void *vjob) {
free((void*)job);
}
-static void selphyneo_teardown(void *vctx) {
- struct selphyneo_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int selphyneo_read_parse(void *vctx, const void **vjob, int data_fd, int copies)
{
struct selphyneo_ctx *ctx = vctx;
@@ -547,7 +538,6 @@ struct dyesub_backend canonselphyneo_backend = {
.init = selphyneo_init,
.attach = selphyneo_attach,
.cleanup_job = selphyneo_cleanup_job,
- .teardown = selphyneo_teardown,
.read_parse = selphyneo_read_parse,
.main_loop = selphyneo_main_loop,
.query_markers = selphyneo_query_markers,
diff --git a/src/cups/backend_common.c b/src/cups/backend_common.c
index 09ea078..22e65d4 100644
--- a/src/cups/backend_common.c
+++ b/src/cups/backend_common.c
@@ -1,7 +1,7 @@
/*
* CUPS Backend common code
*
- * Copyright (c) 2007-2018 Solomon Peachy <pizza@shaftnet.org>
+ * Copyright (c) 2007-2019 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -27,19 +27,19 @@
*/
#include "backend_common.h"
+#include <errno.h>
-#define BACKEND_VERSION "0.88G"
+#define BACKEND_VERSION "0.94G"
#ifndef URI_PREFIX
#error "Must Define URI_PREFIX"
#endif
-#define NUM_CLAIM_ATTEMPTS 10
-
#define URB_XFER_SIZE (64*1024)
#define XFER_TIMEOUT 15000
#define USB_SUBCLASS_PRINTER 0x1
#define USB_INTERFACE_PROTOCOL_BIDIR 0x2
+#define USB_INTERFACE_PROTOCOL_IPP 0x4
/* Global Variables */
int dyesub_debug = 0;
@@ -48,16 +48,18 @@ int fast_return = 0;
int extra_vid = -1;
int extra_pid = -1;
int extra_type = -1;
-int copies = 1;
+int ncopies = 1;
+int collate = 0;
int test_mode = 0;
int old_uri = 0;
+int quiet = 0;
static int max_xfer_size = URB_XFER_SIZE;
static int xfer_timeout = XFER_TIMEOUT;
/* Support Functions */
-static int backend_claim_interface(struct libusb_device_handle *dev, int iface,
- int num_claim_attempts)
+int backend_claim_interface(struct libusb_device_handle *dev, int iface,
+ int num_claim_attempts)
{
int ret;
do {
@@ -300,7 +302,7 @@ int send_data(struct libusb_device_handle *dev, uint8_t endp,
}
if (ret < 0) {
- ERROR("Failure to send data to printer (libusb error %d: (%d/%d to 0x%02x))\n", ret, num, len, endp);
+ ERROR("Failure to send data to printer (libusb error %d: (%d/%d to 0x%02x))\n", ret, num, len2, endp);
return ret;
}
len -= num;
@@ -435,8 +437,16 @@ static int probe_device(struct libusb_device *device,
continue;
}
-#if 0
- // Make sure it's a printer class device that supports bidir comms (XXX Is this always true?)
+#if 1
+ /* Explicitly exclude IPP-over-USB interfaces */
+ if (desc->bDeviceClass == LIBUSB_CLASS_PER_INTERFACE &&
+ config->interface[iface].altsetting[altset].bInterfaceClass == LIBUSB_CLASS_PRINTER &&
+ config->interface[iface].altsetting[altset].bInterfaceSubClass == USB_SUBCLASS_PRINTER &&
+ config->interface[iface].altsetting[altset].bInterfaceProtocol == USB_INTERFACE_PROTOCOL_IPP) {
+ continue;
+ }
+#else
+ // Make sure it's a printer class device that supports bidir comms (XXX Is this necessarily true?)
if (desc->bDeviceClass == LIBUSB_CLASS_PRINTER ||
(desc->bDeviceClass == LIBUSB_CLASS_PER_INTERFACE &&
config->interface[iface].altsetting[altset].bInterfaceClass == LIBUSB_CLASS_PRINTER &&
@@ -544,9 +554,9 @@ candidate:
if (!descr || !strlen(descr)) { /* Last-ditch, generate */
char *product2 = url_decode(product);
char *manuf3 = url_decode(manuf);
- descr = malloc(256);
+ descr = malloc(514); /* 256 + 256 + 1 + 1 */
if (!descr) {
- ERROR("Memory allocation failure (%d bytes)\n", 256);
+ ERROR("Memory allocation failure (%d bytes)\n", 514);
if (manuf3)
free(manuf3);
if (product2)
@@ -554,7 +564,7 @@ candidate:
return -1;
}
- sprintf(descr, "%s %s", manuf3, product2);
+ snprintf(descr, 514, "%s %s", manuf3, product2);
free(product2);
free(manuf3);
}
@@ -656,7 +666,16 @@ abort:
return found;
}
-extern struct dyesub_backend updr150_backend;
+void generic_teardown(void *vctx)
+{
+ if (!vctx)
+ return;
+
+ free(vctx);
+}
+
+extern struct dyesub_backend sonyupd_backend;
+extern struct dyesub_backend sonyupdneo_backend;
extern struct dyesub_backend kodak6800_backend;
extern struct dyesub_backend kodak605_backend;
extern struct dyesub_backend kodak1400_backend;
@@ -683,7 +702,7 @@ static struct dyesub_backend *backends[] = {
&shinkos2145_backend,
&shinkos6145_backend,
&shinkos6245_backend,
- &updr150_backend,
+ &sonyupd_backend,
&mitsu70x_backend,
&mitsud90_backend,
&mitsu9550_backend,
@@ -812,7 +831,7 @@ static int query_markers(struct dyesub_backend *backend, void *ctx, int full)
void print_license_blurb(void)
{
const char *license = "\n\
-Copyright 2007-2018 Solomon Peachy <pizza AT shaftnet DOT org>\n\
+Copyright 2007-2019 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\
@@ -848,13 +867,13 @@ void print_help(char *argv0, struct dyesub_backend *backend)
if (!backend) {
int i;
DEBUG("Environment variables:\n");
- DEBUG(" DYESUB_DEBUG EXTRA_PID EXTRA_VID EXTRA_TYPE BACKEND SERIAL OLD_URI_SCHEME\n");
+ DEBUG(" DYESUB_DEBUG EXTRA_PID EXTRA_VID EXTRA_TYPE BACKEND SERIAL OLD_URI_SCHEME BACKEND_QUIET\n");
DEBUG("CUPS Usage:\n");
DEBUG("\tDEVICE_URI=someuri %s job user title num-copies options [ filename ]\n", URI_PREFIX);
DEBUG("\n");
DEBUG("Standalone Usage:\n");
DEBUG("\t%s\n", URI_PREFIX);
- DEBUG(" [ -D ] [ -G ] [ -f ]\n");
+ DEBUG(" [ -D ] [ -G ] [ -f ] [ -v ]\n");
DEBUG(" [ backend_specific_args ] \n");
DEBUG(" [ -d copies ] \n");
DEBUG(" [ - | infile ] \n");
@@ -964,14 +983,9 @@ int main (int argc, char **argv)
char *use_serno = NULL;
int printer_type;
- DEBUG("Multi-Call Dye-sublimation CUPS Backend version %s\n",
- BACKEND_VERSION);
- DEBUG("Copyright 2007-2018 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");
-
- /* First pass at cmdline parsing */
+ /* Handle environment variables */
+ if (getenv("BACKEND_QUIET"))
+ quiet = atoi(getenv("BACKEND_QUIET"));
if (getenv("DYESUB_DEBUG"))
dyesub_debug = atoi(getenv("DYESUB_DEBUG"));
if (getenv("EXTRA_PID"))
@@ -998,6 +1012,13 @@ int main (int argc, char **argv)
exit(1);
}
+ DEBUG("Multi-Call Dye-sublimation CUPS Backend version %s\n",
+ BACKEND_VERSION);
+ DEBUG("Copyright 2007-2019 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");
+
use_serno = getenv("SERIAL");
uri = getenv("DEVICE_URI"); /* CUPS backend mode! */
type = getenv("FINAL_CONTENT_TYPE"); /* CUPS content type -- ie raster or command */
@@ -1012,7 +1033,7 @@ int main (int argc, char **argv)
if (argv[base])
jobid = atoi(argv[base]);
if (argv[base + 3])
- copies = atoi(argv[base + 3]);
+ ncopies = atoi(argv[base + 3]);
if (argc > 6)
fname = argv[base + 5];
else
@@ -1216,7 +1237,13 @@ bypass:
if (!fname) {
if (uri)
- fprintf(stderr, "ERROR: No input file specified\n");
+ ERROR("ERROR: No input file specified\n");
+ goto done_claimed;
+ }
+
+ if (ncopies < 1) {
+ ERROR("ERROR: need to have at least 1 copy!\n");
+ ret = CUPS_BACKEND_FAILED;
goto done_claimed;
}
@@ -1226,7 +1253,7 @@ bypass:
if (data_fd < 0) {
perror("ERROR:Can't open input file");
ret = CUPS_BACKEND_FAILED;
- goto done;
+ goto done_claimed;
}
}
@@ -1242,7 +1269,7 @@ bypass:
if (i < 0) {
perror("ERROR:Can't open input");
ret = CUPS_BACKEND_FAILED;
- goto done;
+ goto done_claimed;
}
/* Ignore SIGPIPE */
@@ -1250,7 +1277,7 @@ bypass:
signal(SIGTERM, sigterm_handler);
/* Time for the main processing loop */
- INFO("Printing started (%d copies)\n", copies);
+ INFO("Printing started (%d copies)\n", ncopies);
/* See if it's a CUPS command stream, and if yes, handle it! */
if (type && !strcmp("application/vnd.cups-command", type))
@@ -1262,7 +1289,7 @@ bypass:
newpage:
/* Read in data */
- if ((ret = backend->read_parse(backend_ctx, &job, data_fd, copies))) {
+ if ((ret = backend->read_parse(backend_ctx, &job, data_fd, ncopies))) {
if (current_page)
goto done_multiple;
else
@@ -1276,11 +1303,11 @@ newpage:
/* Create our own joblist if necessary */
if (!(backend->flags & BACKEND_FLAG_JOBLIST)) {
- struct dyesub_joblist *list = dyesub_joblist_create(backend, backend_ctx);
+ struct dyesub_joblist *jlist = dyesub_joblist_create(backend, backend_ctx);
if (!list)
goto done_claimed;
- dyesub_joblist_addjob(list, job);
- job = list;
+ dyesub_joblist_addjob(jlist, job);
+ job = jlist;
}
/* Dump the full marker dump */
@@ -1303,7 +1330,7 @@ newpage:
/* Log the completed page */
if (!uri)
- PAGE("%d %d\n", current_page, copies);
+ PAGE("%d %d\n", current_page, ncopies);
/* Dump a marker status update */
ret = query_markers(backend, backend_ctx, !current_page);
@@ -1320,7 +1347,7 @@ done_multiple:
/* Done printing, log the total number of pages */
if (!uri)
- PAGE("total %d\n", current_page * copies);
+ PAGE("total %d\n", current_page * ncopies);
ret = CUPS_BACKEND_OK;
done_claimed:
@@ -1333,7 +1360,10 @@ done_close:
done:
if (backend && backend_ctx) {
- backend->teardown(backend_ctx);
+ if (backend->teardown)
+ backend->teardown(backend_ctx);
+ else
+ generic_teardown(backend_ctx);
// STATE("-org.gutenprint-attached-to-device");
}
@@ -1354,7 +1384,7 @@ void dump_markers(struct marker *markers, int marker_count, int full)
ATTR("marker-colors=");
for (i = 0 ; i < marker_count; i++) {
- DEBUG2(markers[i].color);
+ DEBUG2("%s", markers[i].color);
if ((i+1) < marker_count)
DEBUG2(",");
}
@@ -1433,6 +1463,35 @@ minimal:
}
}
+int dyesub_read_file(char *filename, void *databuf, int datalen,
+ int *actual_len)
+{
+ int len;
+ int fd = open(filename, O_RDONLY);
+
+ if (fd < 0) {
+ ERROR("Unable to open '%s'\n", filename);
+ return CUPS_BACKEND_FAILED;
+ }
+ len = read(fd, databuf, datalen);
+ if (len < 0) {
+ ERROR("Bad Read! (%d/%d)\n", len, errno);
+ close(fd);
+ return CUPS_BACKEND_FAILED;
+ }
+ if (!actual_len && (datalen != len)) {
+ ERROR("Read mismatch (%d vs %d)\n", len, datalen);
+ close(fd);
+ return CUPS_BACKEND_FAILED;
+ }
+ close(fd);
+
+ if (actual_len)
+ *actual_len = len;
+
+ return CUPS_BACKEND_OK;
+}
+
uint16_t uint16_to_packed_bcd(uint16_t val)
{
uint16_t bcd;
@@ -1481,7 +1540,11 @@ struct dyesub_joblist *dyesub_joblist_create(struct dyesub_backend *backend, voi
list->backend = backend;
list->ctx = ctx;
list->num_entries = 0;
- list->copies = 1;
+
+ if (collate)
+ list->copies = ncopies;
+ else
+ list->copies = 1;
return list;
}
diff --git a/src/cups/backend_common.h b/src/cups/backend_common.h
index 3fd58db..2decab2 100644
--- a/src/cups/backend_common.h
+++ b/src/cups/backend_common.h
@@ -1,7 +1,7 @@
/*
* CUPS Backend common code
*
- * (c) 2013-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2019 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -43,21 +43,40 @@
#define __BACKEND_COMMON_H
#define STR_LEN_MAX 64
-#define STATE( ... ) fprintf(stderr, "STATE: " __VA_ARGS__ )
-#define ATTR( ... ) fprintf(stderr, "ATTR: " __VA_ARGS__ )
-#define PAGE( ... ) fprintf(stderr, "PAGE: " __VA_ARGS__ )
-#define DEBUG( ... ) fprintf(stderr, "DEBUG: " __VA_ARGS__ )
-#define DEBUG2( ... ) fprintf(stderr, __VA_ARGS__ )
-#define INFO( ... ) fprintf(stderr, "INFO: " __VA_ARGS__ )
-#define WARNING( ... ) fprintf(stderr, "WARNING: " __VA_ARGS__ )
+#define STATE( ... ) do { if (!quiet) fprintf(stderr, "STATE: " __VA_ARGS__ ); } while(0)
+#define ATTR( ... ) do { if (!quiet) fprintf(stderr, "ATTR: " __VA_ARGS__ ); } while(0)
+#define PAGE( ... ) do { if (!quiet) fprintf(stderr, "PAGE: " __VA_ARGS__ ); } while(0)
+#define DEBUG( ... ) do { if (!quiet) fprintf(stderr, "DEBUG: " __VA_ARGS__ ); } while(0)
+#define DEBUG2( ... ) do { if (!quiet) fprintf(stderr, __VA_ARGS__ ); } while(0)
+#define INFO( ... ) do { if (!quiet) fprintf(stderr, "INFO: " __VA_ARGS__ ); } while(0)
+#define WARNING( ... ) do { fprintf(stderr, "WARNING: " __VA_ARGS__ ); } while(0)
#define ERROR( ... ) do { fprintf(stderr, "ERROR: " __VA_ARGS__ ); sleep(1); } while (0)
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+#define le64_to_cpu(__x) __x
#define le32_to_cpu(__x) __x
#define le16_to_cpu(__x) __x
#define be16_to_cpu(__x) ntohs(__x)
#define be32_to_cpu(__x) ntohl(__x)
+#define be64_to_cpu(__x) ((__uint64_t)( \
+ (((__uint64_t)(__x) & (__uint64_t)0x00000000000000ffULL) << 56) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x000000000000ff00ULL) << 40) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x0000000000ff0000ULL) << 24) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x00000000ff000000ULL) << 8) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x000000ff00000000ULL) >> 8) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x0000ff0000000000ULL) >> 24) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x00ff000000000000ULL) >> 40) | \
+ (((__uint64_t)(__x) & (__uint64_t)0xff00000000000000ULL) >> 56)))
#else
+#define le64_to_cpu(__x) ((__uint64_t)( \
+ (((__uint64_t)(__x) & (__uint64_t)0x00000000000000ffULL) << 56) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x000000000000ff00ULL) << 40) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x0000000000ff0000ULL) << 24) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x00000000ff000000ULL) << 8) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x000000ff00000000ULL) >> 8) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x0000ff0000000000ULL) >> 24) | \
+ (((__uint64_t)(__x) & (__uint64_t)0x00ff000000000000ULL) >> 40) | \
+ (((__uint64_t)(__x) & (__uint64_t)0xff00000000000000ULL) >> 56)))
#define le32_to_cpu(x) \
({ \
uint32_t __x = (x); \
@@ -74,6 +93,7 @@
(((uint16_t)(__x) & (uint16_t)0x00ff) << 8) | \
(((uint16_t)(__x) & (uint16_t)0xff00) >> 8))); \
})
+#define be64_to_cpu(__x) __x
#define be32_to_cpu(__x) __x
#define be16_to_cpu(__x) __x
#endif
@@ -132,7 +152,16 @@ enum {
P_DNP_DSRX1 = 41,
P_FUJI_ASK300 = 42,
P_MAGICARD = 43,
- P_SONY_UPD89x = 44,
+ P_SONY_UPD895 = 44,
+ P_SONY_UPD897 = 45,
+ P_SONY_UPD898 = 46,
+ P_SONY_UPCR20L = 47,
+ P_SONY_UPDR80 = 48,
+ P_KODAK_8810 = 49,
+ P_KODAK_7000 = 50,
+ P_KODAK_701X = 51,
+ P_KODAK_6900 = 52,
+ P_SHINKO_S2245 = 53,
P_END,
};
@@ -195,9 +224,19 @@ void dump_markers(struct marker *markers, int marker_count, int full);
void print_license_blurb(void);
void print_help(char *argv0, struct dyesub_backend *backend);
+int dyesub_read_file(char *filename, void *databuf, int datalen,
+ int *actual_len);
+
uint16_t uint16_to_packed_bcd(uint16_t val);
uint32_t packed_bcd_to_uint32(char *in, int len);
+void generic_teardown(void *vctx);
+
+/* USB enumeration and attachment */
+#define NUM_CLAIM_ATTEMPTS 10
+int backend_claim_interface(struct libusb_device_handle *dev, int iface,
+ int num_claim_attempts);
+
/* Job list manipulation */
struct dyesub_joblist *dyesub_joblist_create(struct dyesub_backend *backend, void *ctx);
int dyesub_joblist_addjob(struct dyesub_joblist *list, const void *job);
@@ -211,8 +250,10 @@ extern int fast_return;
extern int extra_vid;
extern int extra_pid;
extern int extra_type;
-extern int copies;
+extern int ncopies;
+extern int collate;
extern int test_mode;
+extern int quiet;
enum {
TEST_MODE_NONE = 0,
@@ -236,10 +277,10 @@ extern struct dyesub_backend BACKEND;
#define CUPS_BACKEND_RETRY_CURRENT 7 /* Retry immediately */
/* Argument processing */
-#define GETOPT_LIST_GLOBAL "d:DfGh"
+#define GETOPT_LIST_GLOBAL "d:DfGhv"
#define GETOPT_PROCESS_GLOBAL \
case 'd': \
- copies = atoi(optarg); \
+ ncopies = atoi(optarg); \
break; \
case 'D': \
dyesub_debug++; \
@@ -252,6 +293,9 @@ extern struct dyesub_backend BACKEND;
exit(0); \
case 'h': \
print_help(argv[0], &BACKEND); \
- exit(0);
+ exit(0); \
+ case 'v': \
+ quiet++; \
+ break;
#endif /* __BACKEND_COMMON_H */
diff --git a/src/cups/backend_dnpds40.c b/src/cups/backend_dnpds40.c
index b9ed3e4..c029bca 100644
--- a/src/cups/backend_dnpds40.c
+++ b/src/cups/backend_dnpds40.c
@@ -1,7 +1,7 @@
/*
* Citizen / DNP Photo Printer CUPS backend -- libusb-1.0 version
*
- * (c) 2013-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2019 Solomon Peachy <pizza@shaftnet.org>
*
* Development of this backend was sponsored by:
*
@@ -68,6 +68,7 @@ struct dnpds40_printjob {
int printspeed;
int can_rewind;
int buf_needed;
+ int cut_paper;
};
struct dnpds40_ctx {
@@ -86,6 +87,7 @@ struct dnpds40_ctx {
/* State */
uint32_t media;
uint32_t duplex_media;
+ int duplex_media_status;
uint16_t media_count_new;
uint32_t last_multicut;
@@ -95,7 +97,8 @@ struct dnpds40_ctx {
int correct_count;
int needs_mlot;
- struct marker marker;
+ struct marker marker[2];
+ int marker_count;
/* Printer capabilities */
uint32_t native_width;
@@ -175,7 +178,6 @@ struct dnpds40_cmd {
#define MULTICUT_A4 41
#define MULTICUT_A4x5X2 43
-
#define MULTICUT_S_SIMPLEX 100
#define MULTICUT_S_FRONT 200
#define MULTICUT_S_BACK 300
@@ -195,31 +197,14 @@ struct dnpds40_cmd {
#define min(__x, __y) ((__x) < (__y)) ? __x : __y
-/* Legacy CW-01 spool file support */
-struct cw01_spool_hdr {
- uint8_t type; /* 0x00 -> 0x06 */
- uint8_t res; /* vertical resolution; 0x00 == 334dpi, 0x01 == 600dpi */
- uint8_t copies; /* number of prints */
- uint8_t null0;
- uint32_t plane_len; /* LE */
- uint8_t null1[4];
-};
-
-#define DPI_334 0
-#define DPI_600 1
-
-#define TYPE_DSC 0
-#define TYPE_L 1
-#define TYPE_PC 2
-#define TYPE_2DSC 3
-#define TYPE_3L 4
-#define TYPE_A5 5
-#define TYPE_A6 6
-/* Legacy CW-01 spool file support */
+/* Legacy spool file support */
+static int legacy_cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data);
+static int legacy_dnp_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data);
+static int legacy_dnp620_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data);
+static int legacy_dnp820_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data);
-static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd,
- struct cw01_spool_hdr *hdr, int read_data);
static void dnpds40_cleanup_job(const void *vjob);
+static int dnpds40_query_markers(void *vctx, struct marker **markers, int *count);
#define JOB_EQUIV(__x) if (job1->__x != job2->__x) goto done
@@ -419,7 +404,7 @@ static void dnpds40_cleanup_string(char *start, int len)
}
}
-static char *dnpds40_printer_type(int type)
+static const char *dnpds40_printer_type(int type)
{
switch(type) {
case P_DNP_DS40: return "DS40";
@@ -435,7 +420,7 @@ static char *dnpds40_printer_type(int type)
return "Unknown";
}
-static char *dnpds40_media_types(int media)
+static const char *dnpds40_media_types(int media)
{
switch (media) {
case 100: return "UNKNOWN100"; // seen in driver dumps
@@ -455,7 +440,7 @@ static char *dnpds40_media_types(int media)
return "Unknown type";
}
-static char *dnpds620_media_extension_code(int media)
+static const char *dnpds620_media_extension_code(int media)
{
switch (media) {
case 00: return "Normal Paper";
@@ -468,7 +453,7 @@ static char *dnpds620_media_extension_code(int media)
return "Unknown type";
}
-static char *dnpds820_media_subtypes(int media)
+static const char *dnpds820_media_subtypes(int media)
{
switch (media) {
case 0001: return "SD";
@@ -480,7 +465,7 @@ static char *dnpds820_media_subtypes(int media)
return "Unknown type";
}
-static char *dnpds80_duplex_media_types(int media)
+static const char *dnpds80_duplex_media_types(int media)
{
switch (media) {
case 100: return "8x10.75";
@@ -492,7 +477,22 @@ static char *dnpds80_duplex_media_types(int media)
return "Unknown type";
}
-static char *dnpds80_duplex_statuses(int status)
+#define DUPLEX_UNIT_PAPER_NONE 0
+#define DUPLEX_UNIT_PAPER_PROTECTIVE 1
+#define DUPLEX_UNIT_PAPER_PRESENT 2
+
+static const char *dnpds80_duplex_paper_status(int media)
+{
+ switch (media) {
+ case DUPLEX_UNIT_PAPER_NONE: return "No Paper";
+ case DUPLEX_UNIT_PAPER_PROTECTIVE: return "Protective Sheet";
+ case DUPLEX_UNIT_PAPER_PRESENT: return "Cut Paper Present";
+ default:
+ return "Unknown";
+ }
+}
+
+static const char *dnpds80_duplex_statuses(int status)
{
switch (status) {
case 5000: return "No Error";
@@ -564,7 +564,7 @@ static char *dnpds80_duplex_statuses(int status)
return "Unknown Duplexer Error";
}
-static char *dnpds40_statuses(int status)
+static const char *dnpds40_statuses(int status)
{
if (status >= 5000 && status <= 5999)
return dnpds80_duplex_statuses(status);
@@ -746,6 +746,41 @@ static int dnpds40_query_mqty(struct dnpds40_ctx *ctx)
return count;
}
+static int dnpds80dx_query_paper(struct dnpds40_ctx *ctx)
+{
+ struct dnpds40_cmd cmd;
+ uint8_t *resp;
+ int len = 0;
+
+ /* Query Duplex Media Info */
+ dnpds40_build_cmd(&cmd, "INFO", "UNIT_CUT_PAPER", 0);
+
+ resp = dnpds40_resp_cmd(ctx, &cmd, &len);
+ if (resp) {
+ char tmp[5];
+ char status;
+
+ dnpds40_cleanup_string((char*)resp, len);
+
+ memcpy(tmp, resp + 4, 4);
+ status = tmp[3];
+ tmp[3] = '0';
+ tmp[4] = 0;
+
+ ctx->duplex_media = atoi(tmp);
+
+ tmp[0] = tmp[1] = tmp[2] = '0';
+ tmp[3] = status;
+ ctx->duplex_media_status = atoi(tmp);
+
+ free(resp);
+ } else {
+ return CUPS_BACKEND_FAILED;
+ }
+
+ return CUPS_BACKEND_OK;
+}
+
static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type,
uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
{
@@ -819,32 +854,8 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
}
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);
- } else {
+ if (dnpds80dx_query_paper(ctx))
return CUPS_BACKEND_FAILED;
- }
}
#if (defined(DNP_ONLY) || defined(CITIZEN_ONLY))
@@ -948,7 +959,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
break;
case P_DNP_DS620:
ctx->native_width = 1920;
- ctx->max_height = 5480;
+ ctx->max_height = 5604;
ctx->correct_count = 1;
ctx->supports_counterp = 1;
ctx->supports_matte = 1;
@@ -1153,10 +1164,19 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
}
/* Fill out marker structure */
- ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
- ctx->marker.name = dnpds40_media_types(ctx->media);
- ctx->marker.levelmax = ctx->media_count_new;
- ctx->marker.levelnow = -2;
+ ctx->marker[0].color = "#00FFFF#FF00FF#FFFF00";
+ ctx->marker[0].name = dnpds40_media_types(ctx->media);
+ ctx->marker[0].levelmax = ctx->media_count_new;
+ ctx->marker[0].levelnow = -2;
+ ctx->marker_count = 1;
+
+ if (ctx->type == P_DNP_DS80D) {
+ ctx->marker[1].color = "#00FFFF#FF00FF#FFFF00";
+ ctx->marker[1].name = dnpds80_duplex_media_types(ctx->duplex_media);
+ ctx->marker[1].levelmax = ctx->marker[0].levelmax/2;
+ ctx->marker[1].levelnow = -2;
+ ctx->marker_count++;
+ }
return CUPS_BACKEND_OK;
}
@@ -1230,6 +1250,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
job->databuf = malloc(MAX_PRINTJOB_LEN);
if (!job->databuf) {
+ dnpds40_cleanup_job(job);
ERROR("Memory allocation failure!\n");
return CUPS_BACKEND_RETRY_CURRENT;
}
@@ -1250,29 +1271,36 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
return CUPS_BACKEND_CANCEL;
}
- if (job->databuf[job->datalen + 0] != 0x1b ||
- job->databuf[job->datalen + 1] != 0x50) {
- struct cw01_spool_hdr hdr;
- /* See if it's the "classic" CW01 header */
- memcpy(&hdr, job->databuf + job->datalen, sizeof(hdr));
- hdr.plane_len = le32_to_cpu(hdr.plane_len);
-
- if (hdr.type > 0x06 ||
- hdr.res > 0x01 ||
- hdr.null1[0] || hdr.null1[1] || hdr.null1[2] || hdr.null1[3]) {
- ERROR("Unrecognized header data format @%d!\n", job->datalen);
- dnpds40_cleanup_job(job);
- } else {
- job->dpi = (hdr.res == DPI_600) ? 600 : 334;
- i = cw01_read_parse(job, data_fd, &hdr, i);
- if (i == CUPS_BACKEND_OK)
+ /* Special case handling for beginning of job */
+ if (job->datalen == 0) {
+ /* See if job lacks the standard ESC-P start sequence */
+ if (job->databuf[job->datalen + 0] != 0x1b ||
+ job->databuf[job->datalen + 1] != 0x50) {
+ switch(ctx->type) {
+ case P_CITIZEN_CW01:
+ i = legacy_cw01_read_parse(job, data_fd, i);
+ break;
+ case P_DNP_DS620:
+ i = legacy_dnp620_read_parse(job, data_fd, i);
+ break;
+ case P_DNP_DS820:
+ i = legacy_dnp820_read_parse(job, data_fd, i);
+ break;
+ case P_DNP_DSRX1:
+ case P_DNP_DS40:
+ case P_DNP_DS80:
+ case P_DNP_DS80D:
+ default:
+ i = legacy_dnp_read_parse(job, data_fd, i);
+ break;
+ }
+
+ if (i == CUPS_BACKEND_OK) {
goto parsed;
- else {
- dnpds40_cleanup_job(job);
- return i;
}
+ dnpds40_cleanup_job(job);
+ return i;
}
- return CUPS_BACKEND_CANCEL;
}
/* Parse out length of data chunk, if any */
@@ -1285,7 +1313,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
i = read(data_fd, job->databuf + job->datalen + sizeof(struct dnpds40_cmd),
remain);
if (i < 0) {
- ERROR("Data Read Error: %d (%d/%d @%d)\n", i, remain, j, job->datalen);
+ ERROR("Data Read Error: %d (%d/%d @%d/%d)\n", i, remain, j, job->datalen,MAX_PRINTJOB_LEN);
dnpds40_cleanup_job(job);
return i;
}
@@ -1372,7 +1400,11 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
case 11808:
job->dpi = 300;
break;
+ case 13146:
+ job->dpi = 334;
+ break;
case 23615:
+ case 23616:
job->dpi = 600;
break;
default:
@@ -1439,7 +1471,7 @@ parsed:
/* And sanity-check whatever value is there */
if (job->printspeed == 0 && job->dpi == 600) {
job->printspeed = 1;
- } else if (job->printspeed == 1 && job->dpi == 300) {
+ } else if (job->printspeed >= 1 && job->dpi == 300) {
job->printspeed = 0;
}
@@ -1455,11 +1487,14 @@ parsed:
}
/* Only DS80D supports Cut Paper types */
- if (job->multicut > 100 &&
- ctx->type != P_DNP_DS80D) {
- ERROR("Only DS80D supports cut-paper sizes!\n");
- dnpds40_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
+ if (job->multicut > 100) {
+ if ( ctx->type == P_DNP_DS80D) {
+ job->cut_paper = 1;
+ } else {
+ ERROR("Only DS80D supports cut-paper sizes!\n");
+ dnpds40_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
}
/* Figure out the number of buffers we need. */
@@ -1887,12 +1922,16 @@ top:
{
/* Figure out remaining native prints */
- ctx->marker.levelnow = dnpds40_query_mqty(ctx);
- if (ctx->marker.levelnow < 0)
+ if (dnpds40_query_markers(ctx, NULL, NULL))
return CUPS_BACKEND_FAILED;
- dump_markers(&ctx->marker, 1, 0);
+ if (ctx->marker[0].levelnow < 0)
+ return CUPS_BACKEND_FAILED;
+ dump_markers(ctx->marker, ctx->marker_count, 0);
- count = ctx->marker.levelnow; // For logic below.
+ // For logic below.
+ count = ctx->marker[0].levelnow;
+ if (job->cut_paper && count > ctx->marker[1].levelnow)
+ count = ctx->marker[1].levelnow;
/* See if we can rewind to save media */
if (job->can_rewind && ctx->supports_rewind) {
@@ -1944,6 +1983,13 @@ top:
}
}
+ /* Work around a bug in older gutenprint releases. */
+ if (ctx->last_multicut >= 200 && ctx->last_multicut < 300 &&
+ multicut >= 200 && multicut < 300) {
+ WARNING("Bogus multicut value for duplex page, correcting\n");
+ multicut += 100;
+ }
+
/* Store our last multicut state */
ctx->last_multicut = multicut;
@@ -1995,7 +2041,7 @@ top:
/* Program in the multicut setting, if one exists */
if (multicut) {
- snprintf(buf, sizeof(buf), "%08u", multicut);
+ snprintf(buf, sizeof(buf), "%08d", multicut);
dnpds40_build_cmd(&cmd, "IMAGE", "MULTICUT", 8);
if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8)))
return CUPS_BACKEND_FAILED;
@@ -2046,26 +2092,9 @@ top:
}
/* Figure out remaining native prints */
- dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0);
-
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
+ if (dnpds40_query_markers(ctx, NULL, NULL))
return CUPS_BACKEND_FAILED;
-
- dnpds40_cleanup_string((char*)resp, len);
-
- count = atoi((char*)resp+4);
- free(resp);
-
- if (count) {
- /* Old-sk00l models report one less than they should */
- if (!ctx->correct_count)
- count++;
-
- count -= ctx->mediaoffset;
- }
- ctx->marker.levelnow = count;
- dump_markers(&ctx->marker, 1, 0);
+ dump_markers(ctx->marker, ctx->marker_count, 0);
}
/* Clean up */
@@ -2528,6 +2557,7 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx)
count = atoi((char*)resp);
INFO("Duplexer Status: %s\n", dnpds80_duplex_statuses(count));
+ INFO("Duplexer Media Status: %s\n", dnpds80_duplex_paper_status(ctx->duplex_media_status));
free(resp);
}
@@ -2589,8 +2619,10 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx)
}
/* Report Cut Media */
- if (ctx->type == P_DNP_DS80D)
- INFO("Duplex Media Type: %s\n", dnpds80_duplex_media_types(ctx->media));
+ if (ctx->type == P_DNP_DS80D) {
+ INFO("Duplex Media Type: %s\n", dnpds80_duplex_media_types(ctx->duplex_media));
+ INFO("Duplexer Media Status: %s\n", dnpds80_duplex_paper_status(ctx->duplex_media_status));
+ }
if (ctx->media_count_new)
INFO("Native Prints Available on New Media: %u\n", ctx->media_count_new);
@@ -2888,18 +2920,18 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv)
j = dnpds40_get_sensors(ctx);
break;
case 'k': {
- int time = atoi(optarg);
+ int sleeptime = atoi(optarg);
if (!ctx->supports_standby) {
ERROR("Printer does not support standby\n");
j = -1;
break;
}
- if (time < 0 || time > 99) {
+ if (sleeptime < 0 || sleeptime > 99) {
ERROR("Value out of range (0-99)");
j = -1;
break;
}
- j = dnpds620_standby_mode(ctx, time);
+ j = dnpds620_standby_mode(ctx, sleeptime);
break;
}
case 'K': {
@@ -2979,13 +3011,32 @@ static int dnpds40_query_markers(void *vctx, struct marker **markers, int *count
{
struct dnpds40_ctx *ctx = vctx;
- *markers = &ctx->marker;
- *count = 1;
+ if (markers)
+ *markers = ctx->marker;
+ if (count)
+ *count = ctx->marker_count;
+
+ ctx->marker[0].levelnow = dnpds40_query_mqty(ctx);
- ctx->marker.levelnow = dnpds40_query_mqty(ctx);
- if (ctx->marker.levelnow < 0)
+ if (ctx->marker[0].levelnow < 0)
return CUPS_BACKEND_FAILED;
+ if (ctx->type == P_DNP_DS80D) {
+ if (dnpds80dx_query_paper(ctx))
+ return CUPS_BACKEND_FAILED;
+ switch (ctx->duplex_media_status) {
+ case DUPLEX_UNIT_PAPER_NONE:
+ ctx->marker[1].levelnow = 0;
+ break;
+ case DUPLEX_UNIT_PAPER_PROTECTIVE:
+ ctx->marker[1].levelnow = -1;
+ break;
+ case DUPLEX_UNIT_PAPER_PRESENT:
+ ctx->marker[1].levelnow = -3;
+ break;
+ }
+ }
+
return CUPS_BACKEND_OK;
}
@@ -3019,7 +3070,7 @@ static const char *dnpds40_prefixes[] = {
/* Exported */
struct dyesub_backend dnpds40_backend = {
.name = "DNP DS-series / Citizen C-series",
- .version = "0.109",
+ .version = "0.117",
.uri_prefixes = dnpds40_prefixes,
.flags = BACKEND_FLAG_JOBLIST,
.cmdline_usage = dnpds40_cmdline,
@@ -3046,25 +3097,29 @@ struct dyesub_backend dnpds40_backend = {
}
};
-/* Legacy CW-01 spool file support */
-
-static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd,
- struct cw01_spool_hdr *hdr, int read_data)
+/* Windows spool file support */
+static int legacy_spool_helper(struct dnpds40_printjob *job, int data_fd,
+ int read_data, int hdrlen, uint32_t plane_len,
+ int parse_dpi)
{
+ uint8_t *buf;
+ uint8_t bmp_hdr[14];
int i, remain;
uint32_t j;
- uint8_t *buf;
- uint8_t plane_hdr[14];
- remain = hdr->plane_len * 3;
+ /* Allocate a temp processing buffer */
+ remain = plane_len * 3;
buf = malloc(remain);
if (!buf) {
ERROR("Memory allocation failure!\n");
return CUPS_BACKEND_RETRY_CURRENT;
}
- j = read_data - sizeof(*hdr);
- memcpy(buf, job->databuf, j);
+
+ /* Copy over the post-jobhdr crap into our processing buffer */
+ j = read_data - hdrlen;
+ memcpy(buf, job->databuf + hdrlen, j);
remain -= j;
+
/* Read in the remaining spool data */
while (remain) {
i = read(data_fd, buf + j, remain);
@@ -3078,58 +3133,67 @@ static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd,
j += i;
}
- /* Generate plane header (same for all planes) */
- j = cpu_to_le32(hdr->plane_len) + 24;
- memset(plane_hdr, 0, sizeof(plane_hdr));
- plane_hdr[0] = 0x42;
- plane_hdr[1] = 0x4d;
- memcpy(plane_hdr + 2, &j, sizeof(j));
- plane_hdr[10] = 0x40;
- plane_hdr[11] = 0x04;
+ if (parse_dpi) {
+ /* Parse out Y DPI */
+ memcpy(&j, buf + 28, sizeof(j));
+ j = le32_to_cpu(j);
+ switch(j) {
+ case 11808:
+ job->dpi = 300;
+ break;
+ case 23615:
+ case 23616:
+ job->dpi = 600;
+ break;
+ default:
+ ERROR("Unrecognized printjob resolution (%u ppm)\n", j);
+ free(buf);
+ return CUPS_BACKEND_CANCEL;
+ }
+ }
- /* Okay, generate a new stream into job->databuf! */
-#if 0
- job->datalen += sprintf((char*)job->databuf + job->datalen,
- "\033PCNTRL QTY 00000008%07d\r", hdr->copies);
- job->datalen += sprintf((char*)job->databuf + job->datalen,
- "\033PCNTRL CUTTER 0000000800000000");
-#else
- /* QTY is stripped from the stream, and CUTTER is stashed away */
- job->cutter = 0;
-#endif
+ /* Generate bitmap file header (same for all planes) */
+ j = cpu_to_le32(plane_len + 24);
+ memset(bmp_hdr, 0, sizeof(bmp_hdr));
+ bmp_hdr[0] = 0x42;
+ bmp_hdr[1] = 0x4d;
+ memcpy(bmp_hdr + 2, &j, sizeof(j));
+ bmp_hdr[10] = 0x40;
+ bmp_hdr[11] = 0x04;
+ /* Set up planes */
j = 0;
/* Y plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
- "\033PIMAGE YPLANE %08u", hdr->plane_len + 24);
- memcpy(job->databuf + job->datalen, plane_hdr, sizeof(plane_hdr));
- job->datalen += sizeof(plane_hdr);
- memcpy(job->databuf + job->datalen, buf + j, hdr->plane_len);
- job->datalen += hdr->plane_len;
- j += hdr->plane_len;
+ "\033PIMAGE YPLANE %08u", plane_len + 24);
+ memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
+ job->datalen += sizeof(bmp_hdr);
+ memcpy(job->databuf + job->datalen, buf + j, plane_len);
+ job->datalen += plane_len;
+ j += plane_len;
memset(job->databuf + job->datalen, 0, 10);
job->datalen += 10;
/* M plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
- "\033PIMAGE MPLANE %08u", hdr->plane_len + 24);
- memcpy(job->databuf + job->datalen, plane_hdr, sizeof(plane_hdr));
- job->datalen += sizeof(plane_hdr);
- memcpy(job->databuf + job->datalen, buf + j, hdr->plane_len);
- job->datalen += hdr->plane_len;
- j += hdr->plane_len;
+ "\033PIMAGE MPLANE %08u", plane_len + 24);
+ memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
+ job->datalen += sizeof(bmp_hdr);
+ memcpy(job->databuf + job->datalen, buf + j, plane_len);
+ job->datalen += plane_len;
+ j += plane_len;
memset(job->databuf + job->datalen, 0, 10);
job->datalen += 10;
/* C plane */
job->datalen += sprintf((char*)job->databuf + job->datalen,
- "\033PIMAGE CPLANE %08u", hdr->plane_len + 24);
- memcpy(job->databuf + job->datalen, plane_hdr, sizeof(plane_hdr));
- job->datalen += sizeof(plane_hdr);
- memcpy(job->databuf + job->datalen, buf + j, hdr->plane_len);
- job->datalen += hdr->plane_len;
- j += hdr->plane_len;
+ "\033PIMAGE CPLANE %08u", plane_len + 24);
+ memcpy(job->databuf + job->datalen, bmp_hdr, sizeof(bmp_hdr));
+ job->datalen += sizeof(bmp_hdr);
+ memcpy(job->databuf + job->datalen, buf + j, plane_len);
+ job->datalen += plane_len;
+ j += plane_len;
memset(job->databuf + job->datalen, 0, 10);
job->datalen += 10;
@@ -3143,6 +3207,183 @@ static int cw01_read_parse(struct dnpds40_printjob *job, int data_fd,
return CUPS_BACKEND_OK;
}
+struct cw01_spool_hdr {
+ uint8_t type; /* TYPE_??? */
+ uint8_t res; /* DPI_??? */
+ uint8_t copies; /* number of prints */
+ uint8_t null0;
+ uint32_t plane_len; /* LE */
+ uint8_t null1[4];
+};
+
+#define DPI_334 0
+#define DPI_600 1
+
+#define TYPE_DSC 0
+#define TYPE_L 1
+#define TYPE_PC 2
+#define TYPE_2DSC 3
+#define TYPE_3L 4
+#define TYPE_A5 5
+#define TYPE_A6 6
+
+static int legacy_cw01_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data)
+{
+ struct cw01_spool_hdr hdr;
+ uint32_t plane_len;
+
+ /* get original header out of structure */
+ memcpy(&hdr, job->databuf + job->datalen, sizeof(hdr));
+
+ /* Early parsing and sanity checking */
+ plane_len = le32_to_cpu(hdr.plane_len);
+
+ if (hdr.type > TYPE_A6 ||
+ hdr.res > DPI_600 ||
+ hdr.null1[0] || hdr.null1[1] || hdr.null1[2] || hdr.null1[3]) {
+ ERROR("Unrecognized header data format @%d!\n", job->datalen);
+ return CUPS_BACKEND_CANCEL;
+ }
+ job->dpi = (hdr.res == DPI_600) ? 600 : 334;
+ job->cutter = 0;
+
+ return legacy_spool_helper(job, data_fd, read_data,
+ sizeof(hdr), plane_len, 0);
+}
+
+struct rx1_spool_hdr {
+ uint8_t type; /* equals MULTICUT_?? - 1 */
+ uint8_t null0;
+ uint8_t copies; /* number of copies, always fixed at 01.. */
+ uint8_t null1;
+ uint32_t plane_len; /* LE */
+ uint8_t flags; /* combination of FLAG_?? */
+ uint8_t null2[3];
+};
+
+#define FLAG_MATTE 0x02
+#define FLAG_NORETRY 0x08
+#define FLAG_2INCH 0x10
+
+static int legacy_dnp_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data)
+{
+ struct rx1_spool_hdr hdr;
+ uint32_t plane_len;
+
+ /* get original header out of structure */
+ memcpy(&hdr, job->databuf + job->datalen, sizeof(hdr));
+
+ /* Early parsing and sanity checking */
+ plane_len = le32_to_cpu(hdr.plane_len);
+
+ if (hdr.type >= MULTICUT_A4x5X2 ||
+ hdr.null2[0] || hdr.null2[1] || hdr.null2[2]) {
+ ERROR("Unrecognized header data format @%d!\n", job->datalen);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Don't bother with FW version checks for legacy stuff */
+ job->multicut = hdr.type + 1;
+ job->matte = (hdr.flags & FLAG_MATTE) ? 1 : 0;
+ job->cutter = (hdr.flags & FLAG_2INCH) ? 120 : 0;
+
+ return legacy_spool_helper(job, data_fd, read_data,
+ sizeof(hdr), plane_len, 1);
+}
+
+struct ds620_spool_hdr {
+ uint8_t type; /* MULTICUT_?? -1, but >0x90 is a flag for rewind */
+ uint8_t copies; /* Always fixed at 01..*/
+ uint8_t null0[2];
+ uint8_t quality; /* 0x02 is HQ, 0x00 is HS. Equivalent to DPI. */
+ uint8_t unk[3]; /* Always 00 01 00 */
+ uint32_t plane_len; /* LE */
+ uint8_t flags; /* FLAG_?? */
+ uint8_t null1[3];
+};
+#define FLAG_LUSTER 0x04
+#define FLAG_FINEMATTE 0x06
+
+static int legacy_dnp620_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data)
+{
+ struct ds620_spool_hdr hdr;
+ uint32_t plane_len;
+
+ /* get original header out of structure */
+ memcpy(&hdr, job->databuf + job->datalen, sizeof(hdr));
+
+ /* Early parsing and sanity checking */
+ plane_len = le32_to_cpu(hdr.plane_len);
+
+ /* Used to signify rewind request. Backend handles automatically. */
+ if (hdr.type > 0x90)
+ hdr.type -= 0x90;
+
+ if (hdr.type > MULTICUT_A4x5X2 ||
+ hdr.null1[0] || hdr.null1[1] || hdr.null1[2]) {
+ ERROR("Unrecognized header data format @%d!\n", job->datalen);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Don't bother with FW version checks for legacy stuff */
+ job->multicut = hdr.type + 1;
+ if ((hdr.flags & FLAG_FINEMATTE) == FLAG_FINEMATTE)
+ job->matte = 21;
+ else if (hdr.flags & FLAG_LUSTER)
+ job->matte = 22;
+ else if (hdr.flags & FLAG_MATTE)
+ job->matte = 1;
+
+ job->cutter = (hdr.flags & FLAG_2INCH) ? 120 : 0;
+
+ return legacy_spool_helper(job, data_fd, read_data,
+ sizeof(hdr), plane_len, 1);
+}
+
+#define FLAG_820_HD 0x80
+#define FLAG_820_RETRY 0x20
+#define FLAG_820_LUSTER 0x06
+#define FLAG_820_FMATTE 0x04
+#define FLAG_820_MATTE 0x02
+
+static int legacy_dnp820_read_parse(struct dnpds40_printjob *job, int data_fd, int read_data)
+{
+ struct ds620_spool_hdr hdr;
+ uint32_t plane_len;
+
+ /* get original header out of structure */
+ memcpy(&hdr, job->databuf + job->datalen, sizeof(hdr));
+
+ /* Early parsing and sanity checking */
+ plane_len = le32_to_cpu(hdr.plane_len);
+
+ /* Used to signify rewind request. Backend handles automatically. */
+ if (hdr.type > 0x90)
+ hdr.type -= 0x90;
+
+ if (hdr.type > MULTICUT_A4x5X2 ||
+ hdr.null1[0] || hdr.null1[1] || hdr.null1[2]) {
+ ERROR("Unrecognized header data format @%d!\n", job->datalen);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Don't bother with FW version checks for legacy stuff */
+ job->multicut = hdr.type + 1;
+ if ((hdr.flags & FLAG_820_FMATTE) == FLAG_820_FMATTE)
+ job->matte = 21;
+ else if (hdr.flags & FLAG_820_LUSTER)
+ job->matte = 22;
+ else if (hdr.flags & FLAG_820_MATTE)
+ job->matte = 1;
+
+ if (hdr.flags & FLAG_820_HD)
+ job->printspeed = 3;
+
+ return legacy_spool_helper(job, data_fd, read_data,
+ sizeof(hdr), plane_len, 1);
+}
+
+
/*
Basic spool file format for CW01
@@ -3151,11 +3392,11 @@ TT RR NN 00 XX XX XX XX 00 00 00 00 <- FILE header.
NN : copies (0x01 or more)
RR : resolution; 0 == 334 dpi, 1 == 600dpi
- TT : type 0x02 == 4x6, 0x01 == 5x3.5
+ TT : type 0x02 == 4x6, 0x01 == 5x3.5, 0x06 = 6x9
XX XX XX XX : plane length (LE)
plane length * 3 + 12 == file length.
-Followed by three planes, each with this header:
+Followed by three planes, each with this 40b header:
28 00 00 00 00 08 00 00 RR RR 00 00 01 00 08 00
00 00 00 00 00 00 00 00 5a 33 00 00 YY YY 00 00
diff --git a/src/cups/backend_kodak1400.c b/src/cups/backend_kodak1400.c
index 99bd678..88fe9b0 100644
--- a/src/cups/backend_kodak1400.c
+++ b/src/cups/backend_kodak1400.c
@@ -1,7 +1,7 @@
/*
* Kodak Professional 1400/805 CUPS backend -- libusb-1.0 version
*
- * (c) 2013-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2019 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -154,7 +154,7 @@ static int send_plane(struct kodak1400_ctx *ctx,
return 0;
}
-#define UPDATE_SIZE 1552
+#define TONE_CURVE_SIZE 1552
static int kodak1400_set_tonecurve(struct kodak1400_ctx *ctx, char *fname)
{
libusb_device_handle *dev = ctx->dev;
@@ -167,7 +167,7 @@ static int kodak1400_set_tonecurve(struct kodak1400_ctx *ctx, char *fname)
INFO("Set Tone Curve from '%s'\n", fname);
- uint16_t *data = malloc(UPDATE_SIZE);
+ uint16_t *data = malloc(TONE_CURVE_SIZE);
if (!data) {
ERROR("Memory Allocation Failure!\n");
@@ -175,23 +175,17 @@ static int kodak1400_set_tonecurve(struct kodak1400_ctx *ctx, char *fname)
}
/* Read in file */
- int tc_fd = open(fname, O_RDONLY);
- if (tc_fd < 0) {
- ret = -1;
+ if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE, NULL))) {
+ ERROR("Failed to read Tone Curve file\n");
goto done;
}
- if (read(tc_fd, data, UPDATE_SIZE) != UPDATE_SIZE) {
- ret = -2;
- goto done;
- }
- close(tc_fd);
/* Byteswap data to printer's format */
- for (ret = 0; ret < (UPDATE_SIZE-16)/2 ; ret++) {
+ for (ret = 0; ret < (TONE_CURVE_SIZE-16)/2 ; ret++) {
data[ret] = cpu_to_le16(be16_to_cpu(data[ret]));
}
/* Null-terminate */
- memset(data + (UPDATE_SIZE-16)/2, 0, 16);
+ memset(data + (TONE_CURVE_SIZE-16)/2, 0, 16);
/* Clear tables */
memset(cmdbuf, 0, sizeof(cmdbuf));
@@ -226,14 +220,14 @@ static int kodak1400_set_tonecurve(struct kodak1400_ctx *ctx, char *fname)
cmdbuf[2] = 0x02;
cmdbuf[3] = 0x03;
cmdbuf[4] = 0x06;
- cmdbuf[5] = 0x10; /* 06 10 == UPDATE_SIZE */
+ cmdbuf[5] = 0x10; /* 06 10 == TONE_CURVE_SIZE */
if ((ret = send_data(dev, endp_down,
cmdbuf, 6)))
goto done;
/* Send the payload over */
if ((ret = send_data(dev, endp_down,
- (uint8_t *) data, UPDATE_SIZE)))
+ (uint8_t *) data, TONE_CURVE_SIZE)))
goto done;
/* get the response */
@@ -334,15 +328,6 @@ static void kodak1400_cleanup_job(const void *vjob)
free((void*)job);
}
-static void kodak1400_teardown(void *vctx) {
- struct kodak1400_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int kodak1400_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct kodak1400_ctx *ctx = vctx;
int i, ret;
@@ -661,13 +646,12 @@ static const char *kodak1400_prefixes[] = {
struct dyesub_backend kodak1400_backend = {
.name = "Kodak 1400/805",
- .version = "0.39",
+ .version = "0.40",
.uri_prefixes = kodak1400_prefixes,
.cmdline_usage = kodak1400_cmdline,
.cmdline_arg = kodak1400_cmdline_arg,
.init = kodak1400_init,
.attach = kodak1400_attach,
- .teardown = kodak1400_teardown,
.cleanup_job = kodak1400_cleanup_job,
.read_parse = kodak1400_read_parse,
.main_loop = kodak1400_main_loop,
diff --git a/src/cups/backend_kodak605.c b/src/cups/backend_kodak605.c
index 64524d4..423308b 100644
--- a/src/cups/backend_kodak605.c
+++ b/src/cups/backend_kodak605.c
@@ -1,7 +1,7 @@
/*
* Kodak 605 Photo Printer CUPS backend -- libusb-1.0 version
*
- * (c) 2013-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2019 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -39,58 +39,34 @@
#define BACKEND kodak605_backend
#include "backend_common.h"
+#include "backend_sinfonia.h"
#define USB_VID_KODAK 0x040A
#define USB_PID_KODAK_605 0x402E
+#define USB_PID_KODAK_7000 0x4035
+#define USB_PID_KODAK_7010 0x4037
+#define USB_PID_KODAK_7015 0x4038
-/* Command Header */
-struct kodak605_cmd {
- uint16_t cmd; /* LE */
- uint16_t len; /* LE, not counting this header */
-} __attribute__((packed));
-
-struct kodak605_sts_hdr {
- uint8_t result; /* RESULT_* */
- uint8_t unk_1[5]; /* 00 00 00 00 00 */
- uint8_t sts_1; /* 01/02 */
- uint8_t sts_2; /* 00/61->6b ?? temperature? */
- uint16_t length; /* LE, not counting this header */
-} __attribute__((packed));
-
-#define RESULT_SUCCESS 0x01
-#define RESULT_FAIL 0x02
+/* List of confirmed commands */
+//#define SINFONIA_CMD_GETSTATUS 0x0001
+//#define SINFONIA_CMD_MEDIAINFO 0x0002
+//#define SINFONIA_CMD_PRINTJOB 0x4001
+//#define SINFONIA_CMD_UPDATE 0xC004
/* Media structure */
-struct kodak605_medium {
- uint8_t index;
- uint16_t cols; /* LE */
- uint16_t rows; /* LE */
- uint8_t type; /* MEDIA_TYPE_* */
- uint8_t unk[4]; /* 00 00 00 00 */
-} __attribute__((packed));
-
-#define MEDIA_TYPE_UNKNOWN 0x00
-#define MEDIA_TYPE_PAPER 0x01
-
struct kodak605_media_list {
- struct kodak605_sts_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint8_t unk; /* always seen 02 */
uint8_t type; /* KODAK68x0_MEDIA_* */
uint8_t count;
- struct kodak605_medium entries[];
+ struct sinfonia_mediainfo_item entries[];
} __attribute__((packed));
-#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
/* Status response */
struct kodak605_status {
- struct kodak605_sts_hdr hdr;
+ struct sinfonia_status_hdr hdr;
/*@10*/ uint32_t ctr_life; /* Lifetime Prints */
uint32_t ctr_maint; /* Prints since last maintenance */
uint32_t ctr_media; /* Prints on current media */
@@ -98,12 +74,12 @@ struct kodak605_status {
uint32_t ctr_head; /* Prints on current head */
/*@30*/ uint8_t donor; /* Donor Percentage remaining */
/*@31*/ uint8_t null_1[7]; /* 00 00 00 00 00 00 00 */
-/*@38*/ uint8_t b1_id; /* 00/01/02 */
+/*@38*/ uint8_t b1_id; /* jobid */
uint16_t b1_remain;
uint16_t b1_complete;
uint16_t b1_total;
/*@45*/ uint8_t b1_sts; /* See BANK_STATUS_* */
- uint8_t b2_id; /* 00/01/02 */
+ uint8_t b2_id; /* jobid */
uint16_t b2_remain;
uint16_t b2_complete;
uint16_t b2_total;
@@ -113,141 +89,236 @@ struct kodak605_status {
/*@57*/ uint16_t complete; /* in current job */
/*@59*/ uint16_t total; /* in current job */
/*@61*/ uint8_t null_2[9]; /* 00 00 00 00 00 00 00 00 00 */
-/*@70*/ uint8_t unk_12[6]; /* 01 00 00 00 00 00 */
-} __attribute__((packed));
-
-/* File header */
-struct kodak605_hdr {
- uint8_t hdr[4]; /* 01 40 0a 00 */
- uint8_t jobid;
- uint16_t copies; /* LE, 0x0001 or more */
- uint16_t columns; /* LE, always 0x0734 */
- uint16_t rows; /* LE */
- uint8_t media; /* 0x03 for 6x8, 0x01 for 6x4 */
- uint8_t laminate; /* 0x02 to laminate, 0x01 for not */
- uint8_t mode; /* Print mode -- 0x00, 0x01 seen */
+/*@70*/ uint8_t unk_12[6]; /* 01 00 00 00 00 00 (605) 01 01 01 01 00 00 (EK7000) */
+/*@76*/ uint8_t unk_13[1]; // EK7000-series only?
} __attribute__((packed));
-#define BANK_STATUS_FREE 0x00
-#define BANK_STATUS_XFER 0x01
-#define BANK_STATUS_FULL 0x02
-#define BANK_STATUS_PRINTING 0x12
-
-static char *bank_statuses(uint8_t v)
-{
- switch (v) {
- case BANK_STATUS_FREE:
- return "Free";
- case BANK_STATUS_XFER:
- return "Xfer";
- case BANK_STATUS_FULL:
- return "Full";
- case BANK_STATUS_PRINTING:
- return "Printing";
- default:
- return "Unknown";
- }
-}
-
-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 structure */
-struct kodak605_printjob {
- struct kodak605_hdr hdr;
- uint8_t *databuf;
- int datalen;
-};
-
struct kodak605_ctx {
- struct libusb_device_handle *dev;
- uint8_t endp_up;
- uint8_t endp_down;
- int type;
+ struct sinfonia_usbdev dev;
+
uint8_t jobid;
struct kodak605_media_list *media;
struct marker marker;
-
};
+/* Note this is for Kodak 7000-series only! */
+static const char *error_codes(uint8_t major, uint8_t minor)
+{
+ switch(major) {
+ case 0x01: /* "Controller Error" */
+ switch(minor) {
+ case 0x01:
+ return "Controller: EEPROM Write Timeout";
+ case 0x02:
+ return "Controller: EEPROM Verify";
+ case 0x09:
+ return "Controller: DSP FW Boot";
+ case 0x0A:
+ return "Controller: Invalid Print Parameter Table";
+ case 0x0B:
+ return "Controller: DSP FW Mismatch";
+ case 0x0C:
+ return "Controller: Print Parameter Table Mismatch";
+ case 0x0D:
+ return "Controller: ASIC Error";
+ case 0x0E:
+ return "Controller: FPGA Error";
+ case 0x0F:
+ return "Controller: Main FW Checksum";
+ case 0x10:
+ return "Controller: Main FW Write Failed";
+ case 0x11:
+ return "Controller: DSP Checksum";
+ case 0x12:
+ return "Controller: DSP FW Write Failed";
+ case 0x13:
+ return "Controller: Print Parameter Table Checksum";
+ case 0x14:
+ return "Controller: Print Parameter Table Write Failed";
+ case 0x15:
+ return "Controller: User Tone Curve Write Failed";
+ case 0x16:
+ return "Controller: Main-DSP Communication";
+ case 0x17:
+ return "Controller: DSP DMA Failed";
+ case 0x18:
+ return "Controller: Matte Pattern Write Failed";
+ case 0x19:
+ return "Controller: Matte not Initialized";
+ case 0x20:
+ return "Controller: Serial Number Error";
+ default:
+ return "Controller: Unknown";
+ }
+ case 0x02: /* "Mechanical Error" */
+ switch (minor) {
+ case 0x01:
+ return "Mechanical: Pinch Head Up";
+ case 0x02:
+ return "Mechanical: Pinch Head Down";
+ case 0x03:
+ return "Mechanical: Pinch Roll Main Up Feed Up";
+ case 0x04:
+ return "Mechanical: Pinch Roll Main Dn Feed Up";
+ case 0x05:
+ return "Mechanical: Pinch Roll Main Dn Feed Dn";
+ case 0x06:
+ return "Mechanical: Pinch Roll Eject Up";
+ case 0x07:
+ return "Mechanical: Pinch Roll Eject Dn";
+ case 0x0B:
+ return "Mechanical: Cutter (Left->Right)";
+ case 0x0C:
+ return "Mechanical: Cutter (Right->Left)";
+ default:
+ return "Mechanical: Unknown";
+ }
+ case 0x03: /* "Sensor Error" */
+ switch (minor) {
+ case 0x01:
+ return "Sensor: Head Up/Dn All On";
+ case 0x02:
+ return "Sensor: Feed Pitch Roll Up/Dn All On";
+ case 0x05:
+ return "Sensor: Cutter L/R All On";
+ case 0x06:
+ return "Sensor: Cutter L Stuck On";
+ case 0x07:
+ return "Sensor: Cutter Move not Detected";
+ case 0x08:
+ return "Sensor: Cutter R Stuck On";
+ case 0x09:
+ return "Sensor: Head Up Unstable";
+ case 0x0A:
+ return "Sensor: Head Dn Unstable";
+ case 0x0B:
+ return "Sensor: Main/Feed Pinch Up Unstabe";
+ case 0x0C:
+ return "Sensor: Main/Feed Pinch Dn Unstable";
+ case 0x0D:
+ return "Sensor: Eject Up Unstable";
+ case 0x0E:
+ return "Sensor: Eject Dn Unstable";
+ case 0x0F:
+ return "Sensor: Left Cutter Unstable";
+ case 0x10:
+ return "Sensor: Right Cutter Unstable";
+ case 0x11:
+ return "Sensor: Center Cutter Unstable";
+ case 0x12:
+ return "Sensor: Upper Cover Unstable";
+ case 0x13:
+ return "Sensor: Paper Cover Unstable";
+ case 0x14:
+ return "Sensor: Ribbon Takeup Unstable";
+ case 0x15:
+ return "Sensor: Ribbon Supply Unstable";
+ default:
+ return "Sensor: Unknown";
+ }
+ case 0x04: /* "Temperature Sensor Error" */
+ switch (minor) {
+ case 0x01:
+ return "Temp Sensor: Thermal Head High";
+ case 0x02:
+ return "Temp Sensor: Thermal Head Low";
+ case 0x05:
+ return "Temp Sensor: Environment High";
+ case 0x09:
+ return "Temp Sensor: Environment Low";
+ case 0x0A:
+ return "Temp Sensor: Preheat";
+ default:
+ return "Temp Sensor: Unknown";
+ }
+ case 0x5: /* "Paper Jam" */
+ switch (minor) {
+ // XXX these have been seen on EK7000:
+ // case 0x0c:
+ // case 0x36:
+ case 0x3D:
+ return "Paper Jam: Feed Cut->Home";
+ case 0x3E:
+ return "Paper Jam: Feed Cut->Exit Stuck Off";
+ case 0x3F:
+ return "Paper Jam: Feed Cut->Exit Stuck On";
+ case 0x4A:
+ return "Paper Jam: Idle / Paper Set";
+ case 0x51:
+ return "Paper Jam: Paper Exit On";
+ case 0x52:
+ return "Paper Jam: Print Position On";
+ case 0x53:
+ return "Paper Jam: Paper Empty On";
+ case 0x54:
+ return "Paper Jam: Idle / Paper Not Set";
+ default:
+ return "Paper Jam: Unknown";
+ }
+ case 0x06: /* User Error */
+ switch (minor) {
+ case 0x01:
+ return "Drawer Unit Open";
+ case 0x02:
+ return "Incorrect Ribbon";
+ case 0x03:
+ return "No/Empty Ribbon";
+ case 0x04:
+ return "Mismatched Ribbon";
+ case 0x08:
+ return "No Paper";
+ case 0x0C:
+ return "Paper End";
+ default:
+ return "User: Unknown";
+ }
+ default:
+ return "Unknown";
+ }
+}
+
static int kodak605_get_media(struct kodak605_ctx *ctx, struct kodak605_media_list *media)
{
- uint8_t cmdbuf[4];
+ struct sinfonia_cmd_hdr cmd;
- int ret, num = 0;
+ int i, ret, num = 0;
- /* Send Media Query */
- cmdbuf[0] = 0x02;
- cmdbuf[1] = 0x00;
- cmdbuf[2] = 0x00;
- cmdbuf[3] = 0x00;
- if ((ret = send_data(ctx->dev, ctx->endp_down,
- cmdbuf, sizeof(cmdbuf))))
- return ret;
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_MEDIAINFO);
+ cmd.len = cpu_to_le16(0);
- /* Read in the printer status */
- ret = read_data(ctx->dev, ctx->endp_up,
- (uint8_t*) media, MAX_MEDIA_LEN, &num);
- if (ret < 0)
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)media, MAX_MEDIA_LEN,
+ &num))) {
return ret;
-
- if (num < (int)sizeof(*media)) {
- ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*media));
- return CUPS_BACKEND_FAILED;
}
- if (media->hdr.result != RESULT_SUCCESS) {
- ERROR("Unexpected response from media query (%x)!\n", media->hdr.result);
- return CUPS_BACKEND_FAILED;
- }
+ for (i = 0 ; i < media->count; i++) {
+ media->entries[i].rows = le16_to_cpu(media->entries[i].rows);
+ media->entries[i].columns = le16_to_cpu(media->entries[i].columns);
+ }
return 0;
}
static int kodak605_get_status(struct kodak605_ctx *ctx, struct kodak605_status *sts)
{
- uint8_t cmdbuf[4];
+ struct sinfonia_cmd_hdr cmd;
int ret, num = 0;
- /* Send Status Query */
- cmdbuf[0] = 0x01;
- cmdbuf[1] = 0x00;
- cmdbuf[2] = 0x00;
- cmdbuf[3] = 0x00;
- if ((ret = send_data(ctx->dev, ctx->endp_down,
- cmdbuf, sizeof(cmdbuf))))
- return ret;
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
+ cmd.len = cpu_to_le16(0);
- /* Read in the printer status */
- ret = read_data(ctx->dev, ctx->endp_up,
- (uint8_t*) sts, sizeof(*sts), &num);
- if (ret < 0)
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)sts, sizeof(*sts), &num)) < 0) {
return ret;
-
- if (num < (int)sizeof(*sts)) {
- ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*sts));
- return CUPS_BACKEND_FAILED;
- }
-
- if (sts->hdr.result != RESULT_SUCCESS) {
- ERROR("Unexpected response from status query (%x)!\n", sts->hdr.result);
- return CUPS_BACKEND_FAILED;
}
return 0;
@@ -272,10 +343,11 @@ static int kodak605_attach(void *vctx, struct libusb_device_handle *dev, int typ
{
struct kodak605_ctx *ctx = vctx;
- ctx->dev = dev;
- ctx->endp_up = endp_up;
- ctx->endp_down = endp_down;
- ctx->type = type;
+ ctx->dev.dev = dev;
+ ctx->dev.endp_up = endp_up;
+ ctx->dev.endp_down = endp_down;
+ ctx->dev.type = type;
+ ctx->dev.error_codes = &error_codes;
/* Make sure jobid is sane */
ctx->jobid = jobid & 0x7f;
@@ -289,7 +361,7 @@ static int kodak605_attach(void *vctx, struct libusb_device_handle *dev, int typ
return CUPS_BACKEND_FAILED;
}
} else {
- int media_code = KODAK68x0_MEDIA_6TR2;
+ int media_code = KODAK6_MEDIA_6TR2;
if (getenv("MEDIA_CODE"))
media_code = atoi(getenv("MEDIA_CODE"));
@@ -297,37 +369,18 @@ static int kodak605_attach(void *vctx, struct libusb_device_handle *dev, int typ
}
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
- ctx->marker.name = kodak68xx_mediatypes(ctx->media->type);
+ ctx->marker.name = kodak6_mediatypes(ctx->media->type);
ctx->marker.levelmax = 100; /* Ie percentage */
ctx->marker.levelnow = -2;
return CUPS_BACKEND_OK;
}
-static void kodak605_cleanup_job(const void *vjob)
-{
- const struct kodak605_printjob *job = vjob;
-
- if (job->databuf)
- free(job->databuf);
-
- free((void*)job);
-}
-
-static void kodak605_teardown(void *vctx) {
- struct kodak605_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int kodak605_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct kodak605_ctx *ctx = vctx;
int ret;
- struct kodak605_printjob *job = NULL;
+ struct sinfonia_printjob *job = NULL;
if (!ctx)
return CUPS_BACKEND_CANCEL;
@@ -339,51 +392,16 @@ static int kodak605_read_parse(void *vctx, const void **vjob, int data_fd, int c
}
memset(job, 0, sizeof(*job));
- /* Read in then validate header */
- ret = read(data_fd, &job->hdr, sizeof(job->hdr));
- if (ret < 0 || ret != sizeof(job->hdr)) {
- if (ret == 0)
- return CUPS_BACKEND_CANCEL;
- ERROR("Read failed (%d/%d/%d)\n",
- ret, 0, (int)sizeof(job->hdr));
- perror("ERROR: Read failed");
- return CUPS_BACKEND_CANCEL;
- }
-
- if (job->hdr.hdr[0] != 0x01 ||
- job->hdr.hdr[1] != 0x40 ||
- job->hdr.hdr[2] != 0x0a ||
- job->hdr.hdr[3] != 0x00) {
- ERROR("Unrecognized data format!\n");
- return CUPS_BACKEND_CANCEL;
- }
-
- job->datalen = le16_to_cpu(job->hdr.rows) * le16_to_cpu(job->hdr.columns) * 3;
- job->databuf = malloc(job->datalen);
- if (!job->databuf) {
- ERROR("Memory allocation failure!\n");
- return CUPS_BACKEND_RETRY_CURRENT;
- }
-
- {
- int remain = job->datalen;
- uint8_t *ptr = job->databuf;
- do {
- ret = read(data_fd, ptr, remain);
- if (ret < 0) {
- ERROR("Read failed (%d/%d/%d)\n",
- ret, remain, job->datalen);
- perror("ERROR: Read failed");
- return CUPS_BACKEND_CANCEL;
- }
- ptr += ret;
- remain -= ret;
- } while (remain);
+ /* Read in header */
+ ret = sinfonia_raw10_read_parse(data_fd, job);
+ if (ret) {
+ free(job);
+ return ret;
}
/* Printer handles generating copies.. */
- if (le16_to_cpu(job->hdr.copies) < copies)
- job->hdr.copies = cpu_to_le16(copies);
+ if (le16_to_cpu(job->jp.copies) < (uint16_t)copies)
+ job->jp.copies = cpu_to_le16(copies);
*vjob = job;
@@ -397,20 +415,17 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
int num, ret;
- const struct kodak605_printjob *job = vjob;
+ const struct sinfonia_printjob *job = vjob;
if (!ctx)
return CUPS_BACKEND_FAILED;
if (!job)
return CUPS_BACKEND_FAILED;
- struct kodak605_hdr hdr;
- memcpy(&hdr, &job->hdr, sizeof(hdr));
-
/* Validate against supported media list */
for (num = 0 ; num < ctx->media->count; num++) {
- if (ctx->media->entries[num].rows == hdr.rows &&
- ctx->media->entries[num].cols == hdr.columns)
+ if (ctx->media->entries[num].rows == job->jp.rows &&
+ ctx->media->entries[num].columns == job->jp.columns)
break;
}
if (num == ctx->media->count) {
@@ -429,7 +444,16 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
dump_markers(&ctx->marker, 1, 0);
}
- // XXX check for errors
+ if (sts.hdr.result != RESULT_SUCCESS) {
+ ERROR("Printer Status: %02x (%s)\n", sts.hdr.status,
+ sinfonia_status_str(sts.hdr.status));
+ ERROR("Result: %02x Error: %02x (%s) %02x/%02x = %s\n",
+ sts.hdr.result, sts.hdr.error,
+ sinfonia_error_str(sts.hdr.error),
+ sts.hdr.printer_major, sts.hdr.printer_minor,
+ error_codes(sts.hdr.printer_major, sts.hdr.printer_minor));
+ return CUPS_BACKEND_FAILED;
+ }
/* Make sure we're not colliding with an existing
jobid */
@@ -450,35 +474,55 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
sleep(1);
}
- /* Use specified jobid */
+ /* Send print job */
+ struct sinfonia_printcmd10_hdr hdr;
+
+ INFO("Sending print job (internal id %u)\n", ctx->jobid);
+
+ /* Set up header */
+ hdr.hdr.cmd = cpu_to_le16(SINFONIA_CMD_PRINTJOB);
+ hdr.hdr.len = cpu_to_le16(10);
hdr.jobid = ctx->jobid;
+ hdr.rows = cpu_to_le16(job->jp.rows);
+ hdr.columns = cpu_to_le16(job->jp.columns);
+ hdr.copies = cpu_to_le16(job->jp.copies);
+ hdr.media = job->jp.media;
+ hdr.oc_mode = job->jp.oc_mode;
+ hdr.method = job->jp.method;
+
+retry_print:
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&hdr, sizeof(hdr),
+ (uint8_t*)&sts.hdr, sizeof(sts.hdr),
+ &num)) < 0) {
+ return ret;
+ }
- {
- INFO("Sending image header (internal id %u)\n", ctx->jobid);
- if ((ret = send_data(ctx->dev, ctx->endp_down,
- (uint8_t*)&hdr, sizeof(hdr))))
- return CUPS_BACKEND_FAILED;
+ if (sts.hdr.result != RESULT_SUCCESS) {
+ if (sts.hdr.error == ERROR_BUFFER_FULL) {
+ INFO("Printer Buffers full, retrying\n");
+ sleep(1);
+ goto retry_print;
+ } else if ((sts.hdr.status & 0xf0) == 0x30 || sts.hdr.status == ERROR_BUFFER_FULL) {
+ INFO("Printer busy (%02x : %s), retrying\n", sts.hdr.status, sinfonia_status_str(sts.hdr.status));
- struct kodak605_sts_hdr resp;
- if ((ret = read_data(ctx->dev, ctx->endp_up,
- (uint8_t*) &resp, sizeof(resp), &num)))
- return CUPS_BACKEND_FAILED;
+ } else {
+ ERROR("Unexpected response from print command!\n");
+ ERROR("Printer Status: %02x: %s\n", sts.hdr.status, sinfonia_status_str(sts.hdr.status));
+ ERROR("Result: %02x Error: %02x (%02x %02x = %s)\n",
+ sts.hdr.result, sts.hdr.error,
+ sts.hdr.printer_major, sts.hdr.printer_minor,
+ error_codes(sts.hdr.printer_major, sts.hdr.printer_minor));
- if (resp.result != RESULT_SUCCESS) {
- ERROR("Unexpected response from print command (%x)!\n", resp.result);
return CUPS_BACKEND_FAILED;
}
- // XXX what about resp.sts1 or resp.sts2?
}
- sleep(1);
INFO("Sending image data\n");
- if ((ret = send_data(ctx->dev, ctx->endp_down,
+ if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
job->databuf, job->datalen)))
return CUPS_BACKEND_FAILED;
- INFO("Image data sent\n");
-
INFO("Waiting for printer to acknowledge completion\n");
do {
sleep(1);
@@ -489,7 +533,19 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
ctx->marker.levelnow = sts.donor;
dump_markers(&ctx->marker, 1, 0);
}
- // XXX check for errors
+
+ INFO("Printer Status: %02x (%s)\n", sts.hdr.status,
+ sinfonia_status_str(sts.hdr.status));
+
+ if (sts.hdr.result != RESULT_SUCCESS ||
+ sts.hdr.error == ERROR_PRINTER) {
+ INFO("Result: %02x Error: %02x (%s) %02x/%02x = %s\n",
+ sts.hdr.result, sts.hdr.error,
+ sinfonia_error_str(sts.hdr.error),
+ sts.hdr.printer_major, sts.hdr.printer_minor,
+ error_codes(sts.hdr.printer_major, sts.hdr.printer_minor));
+ return CUPS_BACKEND_STOP;
+ }
/* Wait for completion */
if (sts.b1_id == ctx->jobid && sts.b1_complete == sts.b1_total)
@@ -497,6 +553,9 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
if (sts.b2_id == ctx->jobid && sts.b2_complete == sts.b2_total)
break;
+ if (sts.hdr.status == STATUS_READY)
+ break;
+
if (fast_return) {
INFO("Fast return mode enabled.\n");
break;
@@ -504,40 +563,49 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
} while(1);
INFO("Print complete\n");
-
return CUPS_BACKEND_OK;
}
static void kodak605_dump_status(struct kodak605_ctx *ctx, struct kodak605_status *sts)
{
+ INFO("Status: %02x (%s)\n",
+ sts->hdr.status, sinfonia_status_str(sts->hdr.status));
+ INFO("Error: %02x (%s) %02x/%02x = %s\n",
+ sts->hdr.error, sinfonia_error_str(sts->hdr.error),
+ sts->hdr.printer_major, sts->hdr.printer_minor,
+ error_codes(sts->hdr.printer_major, sts->hdr.printer_minor));
+
INFO("Bank 1: %s Job %03u @ %03u/%03u\n",
- bank_statuses(sts->b1_sts), sts->b1_id,
+ sinfonia_bank_statuses(sts->b1_sts), sts->b1_id,
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,
+ sinfonia_bank_statuses(sts->b2_sts), sts->b2_id,
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));
+ INFO("Lifetime prints : %u\n", le32_to_cpu(sts->ctr_life));
+ INFO("Cutter actuations : %u\n", le32_to_cpu(sts->ctr_cut));
+ INFO("Head prints : %u\n", le32_to_cpu(sts->ctr_head));
+ INFO("Media prints : %u\n", le32_to_cpu(sts->ctr_media));
{
int max;
switch(ctx->media->type) {
- case KODAK68x0_MEDIA_6R:
- case KODAK68x0_MEDIA_6TR2:
+ case KODAK6_MEDIA_6R:
+ case KODAK6_MEDIA_6TR2:
max = 375;
break;
+ case KODAK7_MEDIA_6R:
+ max = 570;
+ break;
default:
max = 0;
break;
}
if (max) {
- INFO("\t Remaining : %u\n", max - be32_to_cpu(sts->ctr_media));
+ INFO("\t Remaining : %u\n", max - le32_to_cpu(sts->ctr_media));
} else {
- INFO("\t Remaining : Unknown\n");
+ INFO("\t Remaining : Unknown\n");
}
}
@@ -548,112 +616,36 @@ static void kodak605_dump_mediainfo(struct kodak605_media_list *media)
{
int i;
- if (media->type == KODAK68x0_MEDIA_NONE) {
+ if (media->type == KODAK6_MEDIA_NONE) {
DEBUG("No Media Loaded\n");
return;
}
-
- 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;
- }
+ kodak6_dumpmediacommon(media->type);
DEBUG("Legal print sizes:\n");
for (i = 0 ; i < media->count ; i++) {
- DEBUG("\t%d: %ux%u\n", i,
- le16_to_cpu(media->entries[i].cols),
- le16_to_cpu(media->entries[i].rows));
+ DEBUG("\t%d: %ux%u (%x)\n", i,
+ media->entries[i].columns,
+ media->entries[i].rows,
+ media->entries[i].code);
}
DEBUG("\n");
}
-#define UPDATE_SIZE 1536
-static int kodak605_set_tonecurve(struct kodak605_ctx *ctx, char *fname)
-{
- libusb_device_handle *dev = ctx->dev;
- uint8_t endp_down = ctx->endp_down;
- uint8_t endp_up = ctx->endp_up;
-
- uint8_t cmdbuf[16];
- uint8_t respbuf[16];
- int ret, num = 0;
-
- uint16_t *data = malloc(UPDATE_SIZE);
-
- INFO("Set Tone Curve from '%s'\n", fname);
-
- /* Read in file */
- int tc_fd = open(fname, O_RDONLY);
- if (tc_fd < 0) {
- ret = -1;
- goto done;
- }
- if (read(tc_fd, data, UPDATE_SIZE) != UPDATE_SIZE) {
- ret = 4;
- goto done;
- }
- close(tc_fd);
-
- /* Byteswap data to printer's format */
- for (ret = 0; ret < (UPDATE_SIZE/2) ; ret++) {
- data[ret] = cpu_to_le16(be16_to_cpu(data[ret]));
- }
-
- /* Initial Request */
- cmdbuf[0] = 0x04;
- cmdbuf[1] = 0xc0;
- cmdbuf[2] = 0x0a;
- cmdbuf[3] = 0x00;
- cmdbuf[4] = 0x03;
- cmdbuf[5] = 0x01;
- cmdbuf[6] = 0x00;
- cmdbuf[7] = 0x00;
- cmdbuf[8] = 0x00;
- cmdbuf[9] = 0x00;
- cmdbuf[10] = 0x00; /* 00 06 in LE means 1536 bytes */
- cmdbuf[11] = 0x06;
- cmdbuf[12] = 0x00;
- cmdbuf[13] = 0x00;
-
- if ((ret = send_data(dev, endp_down,
- cmdbuf, 14)))
- goto done;
-
- /* Get response back */
- ret = read_data(dev, endp_up,
- respbuf, sizeof(respbuf), &num);
- if (ret < 0)
- goto done;
-
- if (num != 10) {
- ERROR("Short Read! (%d/%d)\n", num, 10);
- ret = 4;
- goto done;
- }
-
- /* Send the data over! */
- ret = send_data(dev, endp_up,
- (uint8_t*)data, sizeof(data));
-
- done:
- /* We're done */
- free(data);
- return ret;
-}
-
-
static void kodak605_cmdline(void)
{
+ DEBUG("\t\t[ -c filename ] # Get user/NV tone curve\n");
DEBUG("\t\t[ -C filename ] # Set tone curve\n");
+ DEBUG("\t\t[ -e ] # Query error log\n");
+ DEBUG("\t\t[ -F ] # Flash Printer LED\n");
+ DEBUG("\t\t[ -i ] # Query printer info\n");
+ 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[ -r ] # Reset user/NV tone curve\n");
+ DEBUG("\t\t[ -R ] # Reset printer to factory defaults\n");
DEBUG("\t\t[ -s ] # Query status\n");
+ DEBUG("\t\t[ -X jobid ] # Cancel job\n");
}
static int kodak605_cmdline_arg(void *vctx, int argc, char **argv)
@@ -664,15 +656,39 @@ static int kodak605_cmdline_arg(void *vctx, int argc, char **argv)
if (!ctx)
return -1;
- while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "C:ms")) >= 0) {
+ while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFil:L:mrRsX:")) >= 0) {
switch(i) {
GETOPT_PROCESS_GLOBAL
+ case 'c':
+ j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_USER, optarg);
+ break;
case 'C':
- j = kodak605_set_tonecurve(ctx, optarg);
+ j = sinfonia_settonecurve(&ctx->dev, TONECURVE_USER, optarg);
+ break;
+ case 'e':
+ j = sinfonia_geterrorlog(&ctx->dev);
+ break;
+ case 'F':
+ j = sinfonia_flashled(&ctx->dev);
+ break;
+ case 'i':
+ j = sinfonia_getfwinfo(&ctx->dev);
+ break;
+ case 'l':
+ j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
+ break;
+ case 'L':
+ j = sinfonia_settonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'm':
kodak605_dump_mediainfo(ctx->media);
break;
+ case 'r':
+ j = sinfonia_resetcurve(&ctx->dev, RESET_TONE_CURVE, TONE_CURVE_ID);
+ break;
+ case 'R':
+ j = sinfonia_resetcurve(&ctx->dev, RESET_PRINTER, 0);
+ break;
case 's': {
struct kodak605_status sts;
@@ -680,6 +696,9 @@ static int kodak605_cmdline_arg(void *vctx, int argc, char **argv)
if (!j)
kodak605_dump_status(ctx, &sts);
break;
+ case 'X':
+ j = sinfonia_canceljob(&ctx->dev, atoi(optarg));
+ break;
}
default:
break; /* Ignore completely */
@@ -710,34 +729,37 @@ static int kodak605_query_markers(void *vctx, struct marker **markers, int *coun
static const char *kodak605_prefixes[] = {
"kodak605", // Family driver, do NOT nuke.
- "kodak-605",
+ "kodak-605", "kodak-7000", "kodak-7010", "kodak-7015",
NULL,
};
/* Exported */
struct dyesub_backend kodak605_backend = {
- .name = "Kodak 605",
- .version = "0.33",
+ .name = "Kodak 605/70xx",
+ .version = "0.45" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = kodak605_prefixes,
.cmdline_usage = kodak605_cmdline,
.cmdline_arg = kodak605_cmdline_arg,
.init = kodak605_init,
.attach = kodak605_attach,
- .teardown = kodak605_teardown,
- .cleanup_job = kodak605_cleanup_job,
+ .cleanup_job = sinfonia_cleanup_job,
.read_parse = kodak605_read_parse,
.main_loop = kodak605_main_loop,
.query_markers = kodak605_query_markers,
.devices = {
{ USB_VID_KODAK, USB_PID_KODAK_605, P_KODAK_605, "Kodak", "kodak-605"},
+ { USB_VID_KODAK, USB_PID_KODAK_7000, P_KODAK_7000, "Kodak", "kodak-7000"},
+ { USB_VID_KODAK, USB_PID_KODAK_7010, P_KODAK_701X, "Kodak", "kodak-7010"},
+ { USB_VID_KODAK, USB_PID_KODAK_7015, P_KODAK_701X, "Kodak", "kodak-7015"},
{ 0, 0, 0, NULL, NULL}
}
};
-/* Kodak 605 data format
+/* Kodak 605/70xx data format
Spool file consists of 14-byte header followed by plane-interleaved BGR data.
- Native printer resolution is 1844 pixels per row, and 1240 or 2434 rows.
+ Native printer resolution is 1844 pixels per row on all models but 7015,
+ which is 1548 pixels per row.
All fields are LITTLE ENDIAN unless otherwise specified
@@ -746,15 +768,18 @@ struct dyesub_backend kodak605_backend = {
01 40 0a 00 Fixed header
XX Job ID
CC CC Number of copies (1-???)
- WW WW Number of columns (Fixed at 1844)
- HH HH Number of rows (1240 or 2434)
+ WW WW Number of columns (Fixed at 1844 or 1548)
+ HH HH Number of rows
DD 0x01 (4x6) 0x03 (8x6)
- LL Laminate, 0x01 (off) or 0x02 (on)
+ LL Laminate, 0x01/0x02/0x03 (off/on/satin[70xx only])
00 Print Mode (???)
************************************************************************
- Note: Kodak 605 is actually a Shinko CHC-S1545-5A
+ Note: Kodak 605 is actually a Shinko CHC-S1545-5A
+ Note: Kodak 7000 is actually a Shinko CHC-S1645-5A
+ Note: Kodak 7010 is actually a Shinko CHC-S1645-5B
+ Note: Kodak 7015 is actually a Shinko CHC-S1645-5C
************************************************************************
diff --git a/src/cups/backend_kodak6800.c b/src/cups/backend_kodak6800.c
index 79d950b..06c54cb 100644
--- a/src/cups/backend_kodak6800.c
+++ b/src/cups/backend_kodak6800.c
@@ -1,7 +1,7 @@
/*
* Kodak 6800/6850 Photo Printer CUPS backend -- libusb-1.0 version
*
- * (c) 2013-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2019 Solomon Peachy <pizza@shaftnet.org>
*
* Development of this backend was sponsored by:
*
@@ -43,6 +43,7 @@
#define BACKEND kodak6800_backend
#include "backend_common.h"
+#include "backend_sinfonia.h"
#define USB_VID_KODAK 0x040A
#define USB_PID_KODAK_6800 0x4021
@@ -55,9 +56,9 @@ struct kodak6800_hdr {
uint16_t copies; /* BE, in BCD format (1-9999) */
uint16_t columns; /* BE */
uint16_t rows; /* BE */
- uint8_t size; /* 0x06 for 6x8, 0x00 for 6x4, 0x07 for 5x7 */
+ uint8_t size; /* media size; 0x06 for 6x8, 0x00 for 6x4, 0x07 for 5x7 */
uint8_t laminate; /* 0x01 to laminate, 0x00 for not */
- uint8_t mode; /* 0x00 or 0x01 (for 4x6 on 6x8 media) */
+ uint8_t method; /* 0x00 or 0x01 (for 4x6 on 6x8 media), 0x21 for 2x6, 0x23 for 3x6 */
} __attribute__((packed));
struct kodak68x0_status_readback {
@@ -68,15 +69,15 @@ struct kodak68x0_status_readback {
uint8_t errcode; /* Error ## */
uint32_t lifetime; /* Lifetime Prints (BE) */
uint32_t maint; /* Maint Prints (BE) */
- uint32_t media; /* Media Prints (6850), Unknown (6800) (BE) */
- uint32_t cutter; /* Cutter Actuations (BE) */
+ uint32_t media; /* Media Prints (6850), Unknown (6800) (BE) */
+ uint32_t cutter; /* Cutter Actuations (BE) */
uint8_t nullB[2];
uint8_t errtype; /* seen 0x00 or 0xd0 */
uint8_t donor; /* Percentage, 0-100 */
uint16_t main_boot; /* Always 003 */
- uint16_t main_fw; /* seen 652, 656, 670, 671 (6850) and 232 (6800) */
+ uint16_t main_fw; /* seen 6xx/8xx (6850) and 2xx/3xx/4xx (6800) */
uint16_t dsp_boot; /* Always 001 */
- uint16_t dsp_fw; /* Seen 540, 541, 560 (6850) and 131 (6800) */
+ uint16_t dsp_fw; /* Seen 5xx (6850) and 1xx (6800) */
uint8_t b1_jobid;
uint8_t b2_jobid;
uint16_t b1_remain; /* Remaining prints in job */
@@ -88,181 +89,43 @@ struct kodak68x0_status_readback {
uint8_t curve_status; /* Always seems to be 0x00 */
} __attribute__((packed));
-enum {
- CMD_CODE_OK = 1,
- CMD_CODE_BAD = 2,
-};
-
-enum {
- STATUS_PRINTING = 1,
- STATUS_IDLE = 2,
-};
-
-enum {
- STATE_STATUS1_STANDBY = 1,
- STATE_STATUS1_ERROR = 2,
- STATE_STATUS1_WAIT = 3,
-};
-
-#define STATE_STANDBY_STATUS2 0x0
-
-enum {
- WAIT_STATUS2_INIT = 0,
- WAIT_STATUS2_RIBBON = 1,
- WAIT_STATUS2_THERMAL = 2,
- WAIT_STATUS2_OPERATING = 3,
- WAIT_STATUS2_BUSY = 4,
-};
-
-#define ERROR_STATUS2_CTRL_CIRCUIT (0x80000000)
-#define ERROR_STATUS2_MECHANISM_CTRL (0x40000000)
-#define ERROR_STATUS2_SENSOR (0x00002000)
-#define ERROR_STATUS2_COVER_OPEN (0x00001000)
-#define ERROR_STATUS2_TEMP_SENSOR (0x00000200)
-#define ERROR_STATUS2_PAPER_JAM (0x00000100)
-#define ERROR_STATUS2_PAPER_EMPTY (0x00000040)
-#define ERROR_STATUS2_RIBBON_ERR (0x00000010)
-
-enum {
- CTRL_CIR_ERROR_EEPROM1 = 0x01,
- CTRL_CIR_ERROR_EEPROM2 = 0x02,
- CTRL_CIR_ERROR_DSP = 0x04,
- CTRL_CIR_ERROR_CRC_MAIN = 0x06,
- CTRL_CIR_ERROR_DL_MAIN = 0x07,
- CTRL_CIR_ERROR_CRC_DSP = 0x08,
- CTRL_CIR_ERROR_DL_DSP = 0x09,
- CTRL_CIR_ERROR_ASIC = 0x0a,
- CTRL_CIR_ERROR_DRAM = 0x0b,
- CTRL_CIR_ERROR_DSPCOMM = 0x29,
-};
-
-enum {
- MECH_ERROR_HEAD_UP = 0x01,
- MECH_ERROR_HEAD_DOWN = 0x02,
- MECH_ERROR_MAIN_PINCH_UP = 0x03,
- MECH_ERROR_MAIN_PINCH_DOWN = 0x04,
- MECH_ERROR_SUB_PINCH_UP = 0x05,
- MECH_ERROR_SUB_PINCH_DOWN = 0x06,
- MECH_ERROR_FEEDIN_PINCH_UP = 0x07,
- MECH_ERROR_FEEDIN_PINCH_DOWN = 0x08,
- MECH_ERROR_FEEDOUT_PINCH_UP = 0x09,
- MECH_ERROR_FEEDOUT_PINCH_DOWN = 0x0a,
- MECH_ERROR_CUTTER_LR = 0x0b,
- MECH_ERROR_CUTTER_RL = 0x0c,
-};
-
-enum {
- SENSOR_ERROR_CUTTER = 0x05,
- SENSOR_ERROR_HEAD_DOWN = 0x09,
- SENSOR_ERROR_HEAD_UP = 0x0a,
- SENSOR_ERROR_MAIN_PINCH_DOWN = 0x0b,
- SENSOR_ERROR_MAIN_PINCH_UP = 0x0c,
- SENSOR_ERROR_FEED_PINCH_DOWN = 0x0d,
- SENSOR_ERROR_FEED_PINCH_UP = 0x0e,
- SENSOR_ERROR_EXIT_PINCH_DOWN = 0x0f,
- SENSOR_ERROR_EXIT_PINCH_UP = 0x10,
- SENSOR_ERROR_LEFT_CUTTER = 0x11,
- SENSOR_ERROR_RIGHT_CUTTER = 0x12,
- SENSOR_ERROR_CENTER_CUTTER = 0x13,
- SENSOR_ERROR_UPPER_CUTTER = 0x14,
- SENSOR_ERROR_PAPER_FEED_COVER = 0x15,
-};
-
-enum {
- TEMP_SENSOR_ERROR_HEAD_HIGH = 0x01,
- TEMP_SENSOR_ERROR_HEAD_LOW = 0x02,
- TEMP_SENSOR_ERROR_ENV_HIGH = 0x03,
- TEMP_SENSOR_ERROR_ENV_LOW = 0x04,
-};
-
-enum {
- COVER_OPEN_ERROR_UPPER = 0x01,
- COVER_OPEN_ERROR_LOWER = 0x02,
-};
-
-enum {
- PAPER_EMPTY_ERROR = 0x00,
-};
-
-enum {
- RIBBON_ERROR = 0x00,
-};
-
-enum {
- CURVE_TABLE_STATUS_INITIAL = 0x00,
- CURVE_TABLE_STATUS_USERSET = 0x01,
- CURVE_TABLE_STATUS_CURRENT = 0x02,
-};
-
-struct kodak6800_printsize {
- uint8_t hdr; /* Always 0x06 */
- uint16_t width; /* BE */
- 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. Alternates every other 4x6 printed, but only 1 on unknown/1844x2490 print size. */
- uint8_t null[2];
-} __attribute__((packed));
-
-#define MAX_MEDIA_LEN 128
+#define MAX_MEDIAS 16
struct kodak68x0_media_readback {
uint8_t hdr; /* Always 0x01 */
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[];
+ struct sinfonia_mediainfo_item sizes[];
} __attribute__((packed));
-#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
/* Private data structure */
-struct kodak6800_printjob {
- struct kodak6800_hdr hdr;
- uint8_t *databuf;
- int datalen;
- int copies;
-};
-
struct kodak6800_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
+ int supports_sub4x6;
uint8_t jobid;
- struct kodak68x0_media_readback *media;
+ struct sinfonia_mediainfo_item sizes[MAX_MEDIAS];
+ uint8_t media_count;
+ uint8_t media_type;
+
+ struct kodak68x0_status_readback sts;
struct marker marker;
};
-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,
- void *resp, int resp_len,
- int *actual_len)
+ void *cmd, int cmd_len,
+ void *resp, int resp_len,
+ int *actual_len)
{
int ret;
@@ -280,66 +143,82 @@ static int kodak6800_do_cmd(struct kodak6800_ctx *ctx,
return 0;
}
-static void kodak68x0_dump_mediainfo(struct kodak68x0_media_readback *media)
+static void kodak68x0_dump_mediainfo(struct sinfonia_mediainfo_item *sizes,
+ uint8_t media_count, uint8_t media_type)
{
int i;
- if (media->type == KODAK68x0_MEDIA_NONE) {
+
+ if (media_type == KODAK6_MEDIA_NONE) {
INFO("No Media Loaded\n");
return;
}
+ kodak6_dumpmediacommon(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;
- }
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?" : "");
+ for (i = 0 ; i < media_count ; i++) {
+ INFO("\t%d: %dx%d (%02x)\n", i,
+ sizes[i].columns,
+ sizes[i].rows,
+ sizes[i].method);
}
INFO("\n");
}
-static int kodak6800_get_mediainfo(struct kodak6800_ctx *ctx, struct kodak68x0_media_readback *media)
+#define MAX_MEDIA_LEN (sizeof(struct kodak68x0_media_readback) + MAX_MEDIAS * sizeof(struct sinfonia_mediainfo_item))
+
+static int kodak6800_get_mediainfo(struct kodak6800_ctx *ctx)
{
+ struct kodak68x0_media_readback *media;
uint8_t req[16];
- int ret, num;
+ int ret, num, i, j;
memset(req, 0, sizeof(req));
- memset(media, 0, sizeof(*media));
+ media = malloc(MAX_MEDIA_LEN);
+ if (!media) {
+ ERROR("Memory allocation failure!\n");
+ return CUPS_BACKEND_RETRY_CURRENT;
+ }
- req[0] = 0x03;
- req[1] = 0x1b;
- req[2] = 0x43;
- req[3] = 0x48;
- req[4] = 0x43;
- req[5] = 0x1a;
- req[6] = 0x00; /* This can be non-zero for additional "banks" */
+ for (j = 0 ; j < 2 ; j ++) {
+ memset(media, 0, sizeof(*media));
- /* Issue command and get response */
- if ((ret = kodak6800_do_cmd(ctx, req, sizeof(req),
- media, MAX_MEDIA_LEN,
- &num)))
- return ret;
+ req[0] = 0x03;
+ req[1] = 0x1b;
+ req[2] = 0x43;
+ req[3] = 0x48;
+ req[4] = 0x43;
+ req[5] = 0x1a;
+ req[6] = j;
- /* Validate proper response */
- if (media->hdr != CMD_CODE_OK ||
- media->null[0] != 0x00) {
- ERROR("Unexpected response from media query!\n");
- return CUPS_BACKEND_STOP;
+ /* Issue command and get response */
+ if ((ret = kodak6800_do_cmd(ctx, req, sizeof(req),
+ media, MAX_MEDIA_LEN,
+ &num))) {
+ free(media);
+ return ret;
+ }
+
+ /* Validate proper response */
+ if (media->hdr != CMD_CODE_OK ||
+ media->null[0] != 0x00) {
+ ERROR("Unexpected response from media query!\n");
+ free(media);
+ return CUPS_BACKEND_STOP;
+ }
+ ctx->media_type = media->type;
+
+ for (i = 0; i < media->count ; i++) {
+ memcpy(&ctx->sizes[ctx->media_count], &media->sizes[i], sizeof(struct sinfonia_mediainfo_item));
+ ctx->sizes[ctx->media_count].rows = be16_to_cpu(ctx->sizes[ctx->media_count].rows);
+ ctx->sizes[ctx->media_count].columns = be16_to_cpu(ctx->sizes[ctx->media_count].columns);
+ ctx->media_count++;
+ }
+ if (i < 6)
+ break;
}
- return 0;
+ free(media);
+ return CUPS_BACKEND_OK;
}
static int kodak68x0_canceljob(struct kodak6800_ctx *ctx,
@@ -347,7 +226,6 @@ static int kodak68x0_canceljob(struct kodak6800_ctx *ctx,
{
uint8_t req[16];
int ret, num;
- struct kodak68x0_status_readback sts;
memset(req, 0, sizeof(req));
@@ -361,12 +239,12 @@ static int kodak68x0_canceljob(struct kodak6800_ctx *ctx,
/* Issue command and get response */
if ((ret = kodak6800_do_cmd(ctx, req, sizeof(req),
- &sts, sizeof(sts),
+ &ctx->sts, sizeof(ctx->sts),
&num)))
return ret;
/* Validate proper response */
- if (sts.hdr != CMD_CODE_OK) {
+ if (ctx->sts.hdr != CMD_CODE_OK) {
ERROR("Unexpected response from job cancel!\n");
return -99;
}
@@ -378,7 +256,6 @@ 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));
@@ -390,12 +267,12 @@ static int kodak68x0_reset(struct kodak6800_ctx *ctx)
/* Issue command and get response */
if ((ret = kodak6800_do_cmd(ctx, req, sizeof(req),
- &sts, sizeof(sts),
+ &ctx->sts, sizeof(ctx->sts),
&num)))
return ret;
/* Validate proper response */
- if (sts.hdr != CMD_CODE_OK) {
+ if (ctx->sts.hdr != CMD_CODE_OK) {
ERROR("Unexpected response from job cancel!\n");
return -99;
}
@@ -403,153 +280,6 @@ static int kodak68x0_reset(struct kodak6800_ctx *ctx)
return 0;
}
-
-/* Structure dumps */
-static char *kodak68x0_status_str(struct kodak68x0_status_readback *resp)
-{
- switch(resp->status1) {
- case STATE_STATUS1_STANDBY:
- return "Standby (Ready)";
- case STATE_STATUS1_WAIT:
- switch (be32_to_cpu(resp->status2)) {
- case WAIT_STATUS2_INIT:
- return "Wait (Initializing)";
- case WAIT_STATUS2_RIBBON:
- return "Wait (Ribbon Winding)";
- case WAIT_STATUS2_THERMAL:
- return "Wait (Thermal Protection)";
- case WAIT_STATUS2_OPERATING:
- return "Wait (Operating)";
- case WAIT_STATUS2_BUSY:
- return "Wait (Busy)";
- default:
- return "Wait (Unknown)";
- }
- case STATE_STATUS1_ERROR:
- switch (be32_to_cpu(resp->status2)) {
- case ERROR_STATUS2_CTRL_CIRCUIT:
- switch (resp->errcode) {
- case CTRL_CIR_ERROR_EEPROM1:
- return "Error (EEPROM1)";
- case CTRL_CIR_ERROR_EEPROM2:
- return "Error (EEPROM2)";
- case CTRL_CIR_ERROR_DSP:
- return "Error (DSP)";
- case CTRL_CIR_ERROR_CRC_MAIN:
- return "Error (Main CRC)";
- case CTRL_CIR_ERROR_DL_MAIN:
- return "Error (Main Download)";
- case CTRL_CIR_ERROR_CRC_DSP:
- return "Error (DSP CRC)";
- case CTRL_CIR_ERROR_DL_DSP:
- return "Error (DSP Download)";
- case CTRL_CIR_ERROR_ASIC:
- return "Error (ASIC)";
- case CTRL_CIR_ERROR_DRAM:
- return "Error (DRAM)";
- case CTRL_CIR_ERROR_DSPCOMM:
- return "Error (DSP Communincation)";
- default:
- return "Error (Unknown Circuit)";
- }
- case ERROR_STATUS2_MECHANISM_CTRL:
- switch (resp->errcode) {
- case MECH_ERROR_HEAD_UP:
- return "Error (Head Up Mechanism)";
- case MECH_ERROR_HEAD_DOWN:
- return "Error (Head Down Mechanism)";
- case MECH_ERROR_MAIN_PINCH_UP:
- return "Error (Main Pinch Up Mechanism)";
- case MECH_ERROR_MAIN_PINCH_DOWN:
- return "Error (Main Pinch Down Mechanism)";
- case MECH_ERROR_SUB_PINCH_UP:
- return "Error (Sub Pinch Up Mechanism)";
- case MECH_ERROR_SUB_PINCH_DOWN:
- return "Error (Sub Pinch Down Mechanism)";
- case MECH_ERROR_FEEDIN_PINCH_UP:
- return "Error (Feed-in Pinch Up Mechanism)";
- case MECH_ERROR_FEEDIN_PINCH_DOWN:
- return "Error (Feed-in Pinch Down Mechanism)";
- case MECH_ERROR_FEEDOUT_PINCH_UP:
- return "Error (Feed-out Pinch Up Mechanism)";
- case MECH_ERROR_FEEDOUT_PINCH_DOWN:
- return "Error (Feed-out Pinch Down Mechanism)";
- case MECH_ERROR_CUTTER_LR:
- return "Error (Left->Right Cutter)";
- case MECH_ERROR_CUTTER_RL:
- return "Error (Right->Left Cutter)";
- default:
- return "Error (Unknown Mechanism)";
- }
- case ERROR_STATUS2_SENSOR:
- switch (resp->errcode) {
- case SENSOR_ERROR_CUTTER:
- return "Error (Cutter Sensor)";
- case SENSOR_ERROR_HEAD_DOWN:
- return "Error (Head Down Sensor)";
- case SENSOR_ERROR_HEAD_UP:
- return "Error (Head Up Sensor)";
- case SENSOR_ERROR_MAIN_PINCH_DOWN:
- return "Error (Main Pinch Down Sensor)";
- case SENSOR_ERROR_MAIN_PINCH_UP:
- return "Error (Main Pinch Up Sensor)";
- case SENSOR_ERROR_FEED_PINCH_DOWN:
- return "Error (Feed Pinch Down Sensor)";
- case SENSOR_ERROR_FEED_PINCH_UP:
- return "Error (Feed Pinch Up Sensor)";
- case SENSOR_ERROR_EXIT_PINCH_DOWN:
- return "Error (Exit Pinch Up Sensor)";
- case SENSOR_ERROR_EXIT_PINCH_UP:
- return "Error (Exit Pinch Up Sensor)";
- case SENSOR_ERROR_LEFT_CUTTER:
- return "Error (Left Cutter Sensor)";
- case SENSOR_ERROR_RIGHT_CUTTER:
- return "Error (Right Cutter Sensor)";
- case SENSOR_ERROR_CENTER_CUTTER:
- return "Error (Center Cutter Sensor)";
- case SENSOR_ERROR_UPPER_CUTTER:
- return "Error (Upper Cutter Sensor)";
- case SENSOR_ERROR_PAPER_FEED_COVER:
- return "Error (Paper Feed Cover)";
- default:
- return "Error (Unknown Sensor)";
- }
- case ERROR_STATUS2_COVER_OPEN:
- switch (resp->errcode) {
- case COVER_OPEN_ERROR_UPPER:
- return "Error (Upper Cover Open)";
- case COVER_OPEN_ERROR_LOWER:
- return "Error (Lower Cover Open)";
- default:
- return "Error (Unknown Cover Open)";
- }
- case ERROR_STATUS2_TEMP_SENSOR:
- switch (resp->errcode) {
- case TEMP_SENSOR_ERROR_HEAD_HIGH:
- return "Error (Head Temperature High)";
- case TEMP_SENSOR_ERROR_HEAD_LOW:
- return "Error (Head Temperature Low)";
- case TEMP_SENSOR_ERROR_ENV_HIGH:
- return "Error (Environmental Temperature High)";
- case TEMP_SENSOR_ERROR_ENV_LOW:
- return "Error (Environmental Temperature Low)";
- default:
- return "Error (Unknown Temperature)";
- }
- case ERROR_STATUS2_PAPER_JAM:
- return "Error (Paper Jam)";
- case ERROR_STATUS2_PAPER_EMPTY:
- return "Error (Paper Empty)";
- case ERROR_STATUS2_RIBBON_ERR:
- return "Error (Ribbon)";
- default:
- return "Error (Unknown)";
- }
- default:
- return "Unknown!";
- }
-}
-
static void kodak68x0_dump_status(struct kodak6800_ctx *ctx, struct kodak68x0_status_readback *status)
{
char *detail;
@@ -568,8 +298,8 @@ static void kodak68x0_dump_status(struct kodak6800_ctx *ctx, struct kodak68x0_st
INFO("Printer Status : %s\n", detail);
INFO("Printer State : %s # %02x %08x %02x\n",
- kodak68x0_status_str(status),
- status->status1, be32_to_cpu(status->status2), status->errcode);
+ sinfonia_1x45_status_str(status->status1, status->status2, status->errcode),
+ status->status1, status->status2, status->errcode);
INFO("Bank 1 ID: %u\n", status->b1_jobid);
INFO("\tPrints: %d/%d complete\n",
@@ -604,9 +334,9 @@ static void kodak68x0_dump_status(struct kodak6800_ctx *ctx, struct kodak68x0_st
INFO("\tMedia : %u\n", be32_to_cpu(status->media));
- switch(ctx->media->type) {
- case KODAK68x0_MEDIA_6R:
- case KODAK68x0_MEDIA_6TR2:
+ switch(ctx->media_type) {
+ case KODAK6_MEDIA_6R:
+ case KODAK6_MEDIA_6TR2:
max = 375;
break;
default:
@@ -615,7 +345,7 @@ static void kodak68x0_dump_status(struct kodak6800_ctx *ctx, struct kodak68x0_st
}
if (max) {
- INFO("\t Remaining : %d\n", max - be32_to_cpu(status->media));
+ INFO("\t Remaining : %u\n", max - be32_to_cpu(status->media));
} else {
INFO("\t Remaining : Unknown\n");
}
@@ -654,11 +384,12 @@ static int kodak6800_get_status(struct kodak6800_ctx *ctx,
return -99;
}
+ /* Byteswap important stuff */
+ status->status2 = be32_to_cpu(status->status2);
+
return 0;
}
-
-#define UPDATE_SIZE 1536
static int kodak6800_get_tonecurve(struct kodak6800_ctx *ctx, char *fname)
{
uint8_t cmdbuf[16];
@@ -666,7 +397,7 @@ static int kodak6800_get_tonecurve(struct kodak6800_ctx *ctx, char *fname)
int ret, num = 0;
int i;
- uint16_t *data = malloc(UPDATE_SIZE);
+ uint16_t *data = malloc(TONE_CURVE_SIZE);
if (!data) {
ERROR("Memory Allocation Failure\n");
return -1;
@@ -745,7 +476,7 @@ static int kodak6800_get_tonecurve(struct kodak6800_ctx *ctx, char *fname)
for (i = 0 ; i < 768; i++) {
/* Byteswap appropriately */
data[i] = cpu_to_be16(le16_to_cpu(data[i]));
- write(tc_fd, &data[i], sizeof(uint16_t));
+ ret = write(tc_fd, &data[i], sizeof(uint16_t));
}
close(tc_fd);
}
@@ -764,7 +495,7 @@ static int kodak6800_set_tonecurve(struct kodak6800_ctx *ctx, char *fname)
int ret, num = 0;
int remain;
- uint16_t *data = malloc(UPDATE_SIZE);
+ uint16_t *data = malloc(TONE_CURVE_SIZE);
uint8_t *ptr;
if (!data) {
@@ -775,19 +506,13 @@ static int kodak6800_set_tonecurve(struct kodak6800_ctx *ctx, char *fname)
INFO("Set Tone Curve from '%s'\n", fname);
/* Read in file */
- int tc_fd = open(fname, O_RDONLY);
- if (tc_fd < 0) {
- ret = -1;
- goto done;
- }
- if (read(tc_fd, data, UPDATE_SIZE) != UPDATE_SIZE) {
- ret = -2;
+ if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE, NULL))) {
+ ERROR("Failed to read Tone Curve file\n");
goto done;
}
- close(tc_fd);
/* Byteswap data to printer's format */
- for (ret = 0; ret < (UPDATE_SIZE)/2 ; ret++) {
+ for (ret = 0; ret < (TONE_CURVE_SIZE)/2 ; ret++) {
data[ret] = cpu_to_le16(be16_to_cpu(data[ret]));
}
@@ -828,7 +553,7 @@ static int kodak6800_set_tonecurve(struct kodak6800_ctx *ctx, char *fname)
}
ptr = (uint8_t*) data;
- remain = UPDATE_SIZE;
+ remain = TONE_CURVE_SIZE;
while (remain > 0) {
int count = remain > 63 ? 63 : remain;
@@ -971,16 +696,15 @@ static int kodak6800_cmdline_arg(void *vctx, int argc, char **argv)
j = kodak6800_set_tonecurve(ctx, optarg);
break;
case 'm':
- kodak68x0_dump_mediainfo(ctx->media);
+ kodak68x0_dump_mediainfo(ctx->sizes, ctx->media_count, ctx->media_type);
break;
case 'R':
kodak68x0_reset(ctx);
break;
case 's': {
- struct kodak68x0_status_readback status;
- j = kodak6800_get_status(ctx, &status);
+ j = kodak6800_get_status(ctx, &ctx->sts);
if (!j)
- kodak68x0_dump_status(ctx, &status);
+ kodak68x0_dump_status(ctx, &ctx->sts);
break;
}
case 'X':
@@ -1005,8 +729,6 @@ static void *kodak6800_init(void)
}
memset(ctx, 0, sizeof(struct kodak6800_ctx));
- ctx->media = malloc(MAX_MEDIA_LEN);
-
return ctx;
}
@@ -1026,51 +748,57 @@ static int kodak6800_attach(void *vctx, struct libusb_device_handle *dev, int ty
ctx->jobid++;
if (test_mode < TEST_MODE_NOATTACH) {
+ /* Query printer status */
+ if (kodak6800_get_status(ctx, &ctx->sts)) {
+ ERROR("Can't query status\n");
+ return CUPS_BACKEND_FAILED;
+ }
+ uint16_t fw = be16_to_cpu(ctx->sts.main_fw);
+ if (ctx->type == P_KODAK_6850) {
+ if ((fw >= 878) ||
+ (fw < 800 && fw >= 678)) {
+ ctx->supports_sub4x6 = 1;
+ } else {
+ WARNING("Printer FW out of date, recommend updating for current media and features\n");
+ }
+ } else {
+ if ((fw >= 459) ||
+ (fw < 400 && fw >= 359) ||
+ (fw < 300 && fw >= 259)) {
+ ctx->supports_sub4x6 = 1;
+ } else {
+ WARNING("Printer FW out of date, recommend updating for current media and features\n");
+ }
+ }
+
/* Query media info */
- if (kodak6800_get_mediainfo(ctx, ctx->media)) {
+ if (kodak6800_get_mediainfo(ctx)) {
ERROR("Can't query media\n");
return CUPS_BACKEND_FAILED;
}
} else {
- int media_code = KODAK68x0_MEDIA_6TR2;
+ int media_code = KODAK6_MEDIA_6TR2;
if (getenv("MEDIA_CODE"))
media_code = atoi(getenv("MEDIA_CODE"));
- ctx->media->type = media_code;
+ ctx->media_type = media_code;
+ ctx->supports_sub4x6 = 1;
}
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
- ctx->marker.name = kodak68xx_mediatypes(ctx->media->type);
+ ctx->marker.name = kodak6_mediatypes(ctx->media_type);
ctx->marker.levelmax = 100; /* Ie percentage */
ctx->marker.levelnow = -2;
return CUPS_BACKEND_OK;
}
-static void kodak6800_cleanup_job(const void *vjob)
-{
- const struct kodak6800_printjob *job = vjob;
-
- if (job->databuf)
- free(job->databuf);
-
- free((void*)job);
-}
-
-static void kodak6800_teardown(void *vctx) {
- struct kodak6800_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int kodak6800_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct kodak6800_ctx *ctx = vctx;
int ret;
- struct kodak6800_printjob *job = NULL;
+ struct kodak6800_hdr hdr;
+ struct sinfonia_printjob *job = NULL;
if (!ctx)
return CUPS_BACKEND_FAILED;
@@ -1083,31 +811,51 @@ static int kodak6800_read_parse(void *vctx, const void **vjob, int data_fd, int
memset(job, 0, sizeof(*job));
/* Read in then validate header */
- ret = read(data_fd, &job->hdr, sizeof(job->hdr));
- if (ret < 0 || ret != sizeof(job->hdr)) {
- if (ret == 0)
+ ret = read(data_fd, &hdr, sizeof(hdr));
+ if (ret < 0 || ret != sizeof(hdr)) {
+ if (ret == 0) {
+ sinfonia_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
+ }
ERROR("Read failed (%d/%d/%d)\n",
- ret, 0, (int)sizeof(job->hdr));
+ ret, 0, (int)sizeof(hdr));
perror("ERROR: Read failed");
+ sinfonia_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
}
- if (job->hdr.hdr[0] != 0x03 ||
- job->hdr.hdr[1] != 0x1b ||
- job->hdr.hdr[2] != 0x43 ||
- job->hdr.hdr[3] != 0x48 ||
- job->hdr.hdr[4] != 0x43) {
+ if (hdr.hdr[0] != 0x03 ||
+ hdr.hdr[1] != 0x1b ||
+ hdr.hdr[2] != 0x43 ||
+ hdr.hdr[3] != 0x48 ||
+ hdr.hdr[4] != 0x43) {
ERROR("Unrecognized data format!\n");
+ sinfonia_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
}
- job->datalen = be16_to_cpu(job->hdr.rows) * be16_to_cpu(job->hdr.columns) * 3;
+ uint16_t rows = be16_to_cpu(hdr.rows);
+ uint16_t cols = be16_to_cpu(hdr.columns);
+ if (rows != 1240 && rows != 2434 && rows != 2140 && !ctx->supports_sub4x6) {
+ ERROR("Printer Firmware does not support non-4x6/8x6/5x7 prints, please upgrade!\n");
+ sinfonia_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ job->datalen = rows * cols * 3;
job->databuf = malloc(job->datalen);
if (!job->databuf) {
ERROR("Memory allocation failure!\n");
+ sinfonia_cleanup_job(job);
return CUPS_BACKEND_RETRY_CURRENT;
}
+ /* Windows driver only sends 634 rows of data, work around */
+ if (rows == 636 && hdr.size == 6 && hdr.method == 0) {
+ rows = 634;
+ job->datalen -= 1844*2*3;
+ }
+
+ /* Read in the spool data */
{
int remain = job->datalen;
uint8_t *ptr = job->databuf;
@@ -1117,6 +865,7 @@ static int kodak6800_read_parse(void *vctx, const void **vjob, int data_fd, int
ERROR("Read failed (%d/%d/%d)\n",
ret, remain, job->datalen);
perror("ERROR: Read failed");
+ sinfonia_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
}
ptr += ret;
@@ -1124,13 +873,47 @@ static int kodak6800_read_parse(void *vctx, const void **vjob, int data_fd, int
} while (remain);
}
- /* Fix max print count. */
- if (copies > 9999) // XXX test against remaining media
- copies = 9999;
+ /* Undo the Windows workaround... */
+ if (rows == 634) {
+ rows = 636;
+ job->datalen += 1844*2*3;
+ }
+
+ /* Perform some header re-jiggery */
+ if (hdr.size == 0) {
+ if (cols == 1844)
+ hdr.size = 6;
+ else if (cols == 1548)
+ hdr.size = 7;
+ }
+ if (hdr.method == 0) {
+ if (rows == 636) {
+ hdr.method = 0x21;
+ } else if (rows == 936) {
+ hdr.method = 0x23;
+ } else if (rows == 1240) {
+ hdr.method = 0x01;
+ } else if (rows == 1282) {
+ hdr.method = 0x20;
+ } else if (rows == 1882) {
+ hdr.method = 0x22;
+ } else if (rows == 2490) {
+ hdr.method = 0x2;
+ }
+ }
+
+ hdr.copies = be16_to_cpu(hdr.copies);
+ hdr.copies = packed_bcd_to_uint32((char*)&hdr.copies, 2);
+ if (hdr.copies > 1)
+ copies = hdr.copies;
- /* Printer handles generating copies.. */
- if (le16_to_cpu(job->hdr.copies) < copies)
- job->hdr.copies = cpu_to_be16(uint16_to_packed_bcd(copies));
+ /* Fill out job structure */
+ job->jp.copies = copies;
+ job->jp.rows = rows;
+ job->jp.columns = cols;
+ job->jp.media = hdr.size;
+ job->jp.oc_mode = hdr.laminate;
+ job->jp.method = hdr.method;
*vjob = job;
@@ -1139,28 +922,27 @@ static int kodak6800_read_parse(void *vctx, const void **vjob, int data_fd, int
static int kodak6800_main_loop(void *vctx, const void *vjob) {
struct kodak6800_ctx *ctx = vctx;
- struct kodak68x0_status_readback status;
int num, ret;
+ int copies;
- const struct kodak6800_printjob *job = vjob;
+ const struct sinfonia_printjob *job = vjob;
if (!ctx)
return CUPS_BACKEND_FAILED;
if (!job)
return CUPS_BACKEND_FAILED;
- struct kodak6800_hdr hdr;
- memcpy(&hdr, &job->hdr, sizeof(hdr));
+ copies = job->jp.copies;
/* Validate against supported media list */
- for (num = 0 ; num < ctx->media->count; num++) {
- if (ctx->media->sizes[num].height == hdr.rows &&
- ctx->media->sizes[num].width == hdr.columns &&
- ctx->media->sizes[num].code2 == 0x00) // XXX code2?
+ for (num = 0 ; num < ctx->media_count; num++) {
+ if (ctx->sizes[num].rows == job->jp.rows &&
+ ctx->sizes[num].columns == job->jp.columns &&
+ ctx->sizes[num].method == job->jp.method)
break;
}
- if (num == ctx->media->count) {
+ if (num == ctx->media_count) {
ERROR("Print size unsupported by media!\n");
return CUPS_BACKEND_HOLD;
}
@@ -1168,28 +950,25 @@ static int kodak6800_main_loop(void *vctx, const void *vjob) {
INFO("Waiting for printer idle\n");
while(1) {
- if (kodak6800_get_status(ctx, &status))
+ if (kodak6800_get_status(ctx, &ctx->sts))
return CUPS_BACKEND_FAILED;
- if (ctx->marker.levelnow != status.donor) {
- ctx->marker.levelnow = status.donor;
+ if (ctx->marker.levelnow != ctx->sts.donor) {
+ ctx->marker.levelnow = ctx->sts.donor;
dump_markers(&ctx->marker, 1, 0);
}
- if (status.status1 == STATE_STATUS1_ERROR) {
+ if (ctx->sts.status1 == STATE_STATUS1_ERROR) {
INFO("Printer State: %s # %02x %08x %02x\n",
- kodak68x0_status_str(&status),
- status.status1, be32_to_cpu(status.status2), status.errcode);
+ sinfonia_1x45_status_str(ctx->sts.status1, ctx->sts.status2, ctx->sts.errcode),
+ ctx->sts.status1, ctx->sts.status2, ctx->sts.errcode);
return CUPS_BACKEND_FAILED;
}
- 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) {
+ while (ctx->jobid == ctx->sts.b1_jobid ||
+ ctx->jobid == ctx->sts.b2_jobid) {
ctx->jobid++;
ctx->jobid &= 0x7f;
if (!ctx->jobid)
@@ -1197,8 +976,8 @@ static int kodak6800_main_loop(void *vctx, const void *vjob) {
}
/* See if we have an open bank */
- if (!status.b1_remain ||
- !status.b2_remain)
+ if (!ctx->sts.b1_remain ||
+ !ctx->sts.b2_remain)
break;
sleep(1);
@@ -1211,25 +990,34 @@ static int kodak6800_main_loop(void *vctx, const void *vjob) {
return ret;
}
- hdr.jobid = ctx->jobid;
+ /* Fix max print count. */
+ if (copies > 9999)
+ copies = 9999;
-#if 0
- /* If we want to disable 4x6 rewind on 8x6 media.. */
- // XXX not sure about this...?
- if (hdr.size == 0x00 &&
- be16_to_cpu(ctx->media->sizes[0].width) == 0x0982) {
- hdr.size = 0x06;
- hdr.mode = 0x01;
- }
-#endif
+ /* Fill out printjob header */
+ struct kodak6800_hdr hdr;
+ hdr.hdr[0] = 0x03;
+ hdr.hdr[1] = 0x1b;
+ hdr.hdr[2] = 0x43;
+ hdr.hdr[3] = 0x48;
+ hdr.hdr[4] = 0x43;
+ hdr.hdr[5] = 0x0a;
+ hdr.hdr[6] = 0x00;
+ hdr.jobid = ctx->jobid;
+ hdr.copies = uint16_to_packed_bcd(copies);
+ hdr.columns = cpu_to_be16(job->jp.columns);
+ hdr.rows = cpu_to_be16(job->jp.rows);
+ hdr.size = job->jp.media;
+ hdr.laminate = job->jp.oc_mode;
+ hdr.method = job->jp.method;
INFO("Sending Print Job (internal id %u)\n", ctx->jobid);
if ((ret = kodak6800_do_cmd(ctx, (uint8_t*) &hdr, sizeof(hdr),
- &status, sizeof(status),
+ &ctx->sts, sizeof(ctx->sts),
&num)))
return ret;
- if (status.hdr != CMD_CODE_OK) {
+ if (ctx->sts.hdr != CMD_CODE_OK) {
ERROR("Unexpected response from print command!\n");
return CUPS_BACKEND_FAILED;
}
@@ -1243,25 +1031,25 @@ static int kodak6800_main_loop(void *vctx, const void *vjob) {
INFO("Waiting for printer to acknowledge completion\n");
do {
sleep(1);
- if (kodak6800_get_status(ctx, &status))
+ if (kodak6800_get_status(ctx, &ctx->sts))
return CUPS_BACKEND_FAILED;
- if (ctx->marker.levelnow != status.donor) {
- ctx->marker.levelnow = status.donor;
+ if (ctx->marker.levelnow != ctx->sts.donor) {
+ ctx->marker.levelnow = ctx->sts.donor;
dump_markers(&ctx->marker, 1, 0);
}
- if (status.status1 == STATE_STATUS1_ERROR) {
+ if (ctx->sts.status1 == STATE_STATUS1_ERROR) {
INFO("Printer State: %s # %02x %08x %02x\n",
- kodak68x0_status_str(&status),
- status.status1, be32_to_cpu(status.status2), status.errcode);
+ sinfonia_1x45_status_str(ctx->sts.status1, ctx->sts.status2, ctx->sts.errcode),
+ ctx->sts.status1, ctx->sts.status2, ctx->sts.errcode);
return CUPS_BACKEND_FAILED;
}
/* If all prints are complete, we're done! */
- if (status.b1_jobid == hdr.jobid && status.b1_complete == status.b1_total)
+ if (ctx->sts.b1_jobid == hdr.jobid && ctx->sts.b1_complete == ctx->sts.b1_total)
break;
- if (status.b2_jobid == hdr.jobid && status.b2_complete == status.b2_total)
+ if (ctx->sts.b2_jobid == hdr.jobid && ctx->sts.b2_complete == ctx->sts.b2_total)
break;
if (fast_return) {
@@ -1279,13 +1067,12 @@ static int kodak6800_main_loop(void *vctx, const void *vjob) {
static int kodak6800_query_markers(void *vctx, struct marker **markers, int *count)
{
struct kodak6800_ctx *ctx = vctx;
- struct kodak68x0_status_readback status;
/* Query printer status */
- if (kodak6800_get_status(ctx, &status))
+ if (kodak6800_get_status(ctx, &ctx->sts))
return CUPS_BACKEND_FAILED;
- ctx->marker.levelnow = status.donor;
+ ctx->marker.levelnow = ctx->sts.donor;
*markers = &ctx->marker;
*count = 1;
@@ -1304,14 +1091,13 @@ static const char *kodak6800_prefixes[] = {
/* Exported */
struct dyesub_backend kodak6800_backend = {
.name = "Kodak 6800/6850",
- .version = "0.65",
+ .version = "0.73" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = kodak6800_prefixes,
.cmdline_usage = kodak6800_cmdline,
.cmdline_arg = kodak6800_cmdline_arg,
.init = kodak6800_init,
.attach = kodak6800_attach,
- .teardown = kodak6800_teardown,
- .cleanup_job = kodak6800_cleanup_job,
+ .cleanup_job = sinfonia_cleanup_job,
.read_parse = kodak6800_read_parse,
.main_loop = kodak6800_main_loop,
.query_serno = kodak6800_query_serno,
@@ -1341,7 +1127,7 @@ struct dyesub_backend kodak6800_backend = {
HH HH Number of rows.
SS Print size -- 0x00 (4x6) 0x06 (8x6) 0x07 (5x7 on 6850)
LL Laminate mode -- 0x00 (off) or 0x01 (on)
- UU Print mode -- 0x00 (normal) or (0x01) 4x6 on 8x6
+ UU Print mode -- 0x00 (normal) or 0x01 (4x6 on 8x6) 0x21 (2x6) 0x23 (3x6)
************************************************************************
@@ -1366,4 +1152,18 @@ struct dyesub_backend kodak6800_backend = {
00 01 02 1c 00 00 00 00 00 01 00 01 00 00 00 00
00 00 00
+ An additional command that's also unknown
+
+-> 03 1b 43 48 43 4d 01 00 00 00 00 00 00 00 00 00
+<- 01 02 01 00 00 00 00 00 00 00 5d ca 00 00 5d ca
+ 00 00 00 15 00 00 b8 f8 00 00 00 40 00 03 02 a6
+ 00 01 02 31 1e 00 00 00 00 01 00 01 00 00 00 00
+ 00 00 00
+
+ One more note for the 6850. These sizes have been seen:
+
+ 1844x2434, method 0x03
+ 1844x2490, method 0x05
+ 1844x2222, method 0x00
+
*/
diff --git a/src/cups/backend_magicard.c b/src/cups/backend_magicard.c
index d356bba..64da470 100644
--- a/src/cups/backend_magicard.c
+++ b/src/cups/backend_magicard.c
@@ -475,15 +475,6 @@ static void magicard_cleanup_job(const void *vjob)
free((void*)job);
}
-static void magicard_teardown(void *vctx) {
- struct magicard_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static void downscale_and_extract(int gamma, uint32_t pixels,
uint8_t *y_i, uint8_t *m_i, uint8_t *c_i,
uint8_t *y_o, uint8_t *m_o, uint8_t *c_o, uint8_t *k_o)
@@ -552,7 +543,8 @@ static void downscale_and_extract(int gamma, uint32_t pixels,
}
}
-#define MAX_PRINTJOB_LEN (1016*672*4) + 1024 /* 1016*672 * 4color */
+#define MAX_HEADERS_LEN 2048
+#define MAX_PRINTJOB_LEN (1016*672*4) + MAX_HEADERS_LEN /* 1016*672 * 4color */
#define INITIAL_BUF_LEN 1024
static int magicard_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct magicard_ctx *ctx = vctx;
@@ -629,7 +621,10 @@ static int magicard_read_parse(void *vctx, const void **vjob, int data_fd, int c
char *ptr;
ptr = strtok((char*)initial_buf + ++buf_offset, ",\x1c");
- while (ptr && *ptr != 0x1c) {
+ while (ptr
+ && ((ptr - (char*)initial_buf) < INITIAL_BUF_LEN)
+ && ((ptr - (char*)initial_buf) + strnlen(ptr, INITIAL_BUF_LEN) < INITIAL_BUF_LEN)
+ && *ptr != 0x1c) {
if (!strcmp("X-GP-8", ptr)) {
x_gp_8bpp = 1;
} else if (!strncmp("TDT", ptr, 3)) {
@@ -655,6 +650,13 @@ static int magicard_read_parse(void *vctx, const void **vjob, int data_fd, int c
len_k = atoi(ptr + 3);
}
} else {
+ /* Safety valve */
+ if (strlen(ptr) + job->datalen > MAX_HEADERS_LEN) {
+ ERROR("headers too long, bogus job!\n");
+ magicard_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
+
/* Everything else goes in */
job->datalen += sprintf((char*)job->databuf + job->datalen, ",%s", ptr);
}
@@ -843,6 +845,7 @@ static int magicard_read_parse(void *vctx, const void **vjob, int data_fd, int c
static int magicard_main_loop(void *vctx, const void *vjob) {
struct magicard_ctx *ctx = vctx;
int ret;
+ int copies;
const struct magicard_printjob *job = vjob;
@@ -945,13 +948,12 @@ static const char *magicard_prefixes[] = {
struct dyesub_backend magicard_backend = {
.name = "Magicard family",
- .version = "0.15",
+ .version = "0.16",
.uri_prefixes = magicard_prefixes,
.cmdline_arg = magicard_cmdline_arg,
.cmdline_usage = magicard_cmdline,
.init = magicard_init,
.attach = magicard_attach,
- .teardown = magicard_teardown,
.cleanup_job = magicard_cleanup_job,
.read_parse = magicard_read_parse,
.main_loop = magicard_main_loop,
diff --git a/src/cups/backend_mitsu70x.c b/src/cups/backend_mitsu70x.c
index 154fabb..687caac 100644
--- a/src/cups/backend_mitsu70x.c
+++ b/src/cups/backend_mitsu70x.c
@@ -324,8 +324,8 @@ struct mitsu70x_status_deck {
uint8_t media_brand;
uint8_t media_type;
uint8_t rsvd_b[2];
- uint16_t capacity; /* media capacity */
- uint16_t remain; /* media remaining */
+ int16_t capacity; /* media capacity */
+ int16_t remain; /* media remaining */
uint8_t rsvd_c[2];
uint8_t lifetime_prints[4]; /* lifetime prints on deck + 10, in BCD! */
uint8_t rsvd_d[2]; // Unknown
@@ -805,6 +805,7 @@ static int mitsu70x_attach(void *vctx, struct libusb_device_handle *dev, int typ
resp.upper.media_type = media_code;
resp.lower.media_type = media_code;
resp.dual_deck = 0x80; /* Make it a dual deck */
+ resp.vers[0].ver[0] = 0;
}
/* Figure out if we're a D707 with two decks */
@@ -833,10 +834,11 @@ static int mitsu70x_attach(void *vctx, struct libusb_device_handle *dev, int typ
if (ctx->type == P_KODAK_305) {
/* Known versions:
v1.02: M 316E81 1433 (Add Ultrafine and matte support)
- v1.04: M 316F83 2878 (Add 2x6 strip and support "Triton" media)
+ v1.04: M 316F83 2878 (Add 2x6 strip and support new "Triton" media)
+ v3.01: M 443A12 8908 (add 5" media support)
*/
- if (strncmp(resp.vers[0].ver, "316F83", 6) < 0)
- WARNING("Printer FW out of date. Highly recommend upgrading EK305 to v1.04 or newer!\n");
+ if (strncmp(resp.vers[0].ver, "443A12", 6) < 0)
+ WARNING("Printer FW out of date. Highly recommend upgrading EK305 to v3.01 or newer!\n");
} else if (ctx->type == P_MITSU_K60) {
/* Known versions:
v1.05: M 316M31 148C (Add HG media support)
@@ -1295,7 +1297,7 @@ repeat:
}
if (job->lutfname && ctx->lut) {
- DEBUG("Running print data through LUT\n");
+ DEBUG("Running print data through 3D LUT\n");
ctx->DoColorConv(ctx->lut, job->spoolbuf, job->cols, job->rows, job->cols * 3, COLORCONV_BGR);
}
@@ -1721,7 +1723,7 @@ static int mitsu70x_main_loop(void *vctx, const void *vjob)
int ret;
int copies;
- int deck;
+ int deck, legal, reqdeck;
struct mitsu70x_printjob *job = (struct mitsu70x_printjob *) vjob; // XXX not clean.
// const struct mitsu70x_printjob *job = vjob;
@@ -1734,6 +1736,9 @@ static int mitsu70x_main_loop(void *vctx, const void *vjob)
copies = job->copies;
hdr = (struct mitsu70x_hdr*) job->databuf;
+ /* Keep track of deck requested */
+ reqdeck = hdr->deck;
+
if (job->raw_format)
goto bypass;
@@ -1865,7 +1870,7 @@ top:
/* First, try to respect requested deck */
if (ctx->type == P_MITSU_D70X) {
- deck = hdr->deck; /* Respect D70 deck choice, 0 is automatic. */
+ deck = reqdeck; /* Respect D70 deck choice, 0 is automatic. */
} else {
deck = 1; /* All others have one deck only */
}
@@ -1901,6 +1906,7 @@ top:
job->decks_ok[0], job->decks_ok[1]);
/* Okay, we know which decks are _legal_, pick one to use */
+ legal = deck;
if (deck & 1) {
if (jobstatus.temperature == TEMPERATURE_COOLING) {
if (ctx->num_decks == 2)
@@ -1909,7 +1915,8 @@ top:
INFO("Printer cooling down...\n");
deck &= ~1;
} else if (jobstatus.error_status[0]) {
- ERROR("%s/%s -> %s: %02x/%02x/%02x\n",
+ ERROR("%s %s/%s -> %s: %02x/%02x/%02x\n",
+ ctx->num_decks == 2 ? "LOWER:": "",
mitsu70x_errorclass(jobstatus.error_status),
mitsu70x_errors(jobstatus.error_status),
mitsu70x_errorrecovery(jobstatus.error_status),
@@ -1917,8 +1924,9 @@ top:
jobstatus.error_status[1],
jobstatus.error_status[2]);
deck &= ~1;
+ legal &= ~1; /* Deck is offline! */
} else if (jobstatus.mecha_status[0] != MECHA_STATUS_IDLE) {
- deck = ~1;
+ deck &= ~1;
}
}
if (deck & 2) {
@@ -1934,8 +1942,9 @@ top:
jobstatus.error_status_up[1],
jobstatus.error_status_up[2]);
deck &= ~2;
+ legal &= ~2; /* Deck is offline! */
} else if (jobstatus.mecha_status_up[0] != MECHA_STATUS_IDLE) {
- deck = ~2;
+ deck &= ~2;
}
}
@@ -1950,18 +1959,28 @@ top:
if (ctx->num_decks > 1)
DEBUG("Deck selected: %d\n", deck);
+ /* Great, we have no decks we can currently print this job on.. */
if (deck == 0) {
/* Halt queue if printer is entirely offline */
if (ctx->num_decks == 2) {
- if (jobstatus.error_status[0] && jobstatus.error_status_up[0])
+ if (jobstatus.error_status[0] && jobstatus.error_status_up[0]) {
+ ERROR("Both decks offline due to errors\n");
return CUPS_BACKEND_STOP;
- // XXX what if we only have one legal deck, and it's unavailable? We don't want to retry indefinitely here..
+ }
} else {
- if (jobstatus.error_status[0])
+ if (jobstatus.error_status[0]) {
+ ERROR("Printer offline due to errors\n");
return CUPS_BACKEND_STOP;
+ }
}
- /* No decks available yet, retry */
+ /* Hold job if we have no legal decks for it, but printer is online. */
+ if (!legal) {
+ ERROR("Legal deck for printjob has errors, aborting job");
+ return CUPS_BACKEND_HOLD;
+ }
+
+ /* Legal decks are busy, retry */
sleep(1);
goto top;
}
@@ -2085,7 +2104,7 @@ top:
return CUPS_BACKEND_FAILED;
/* See if we hit a printer error. */
- if (deck == 0) {
+ if (deck == 1) {
if (jobstatus.error_status[0]) {
ERROR("%s/%s -> %s: %02x/%02x/%02x\n",
mitsu70x_errorclass(jobstatus.error_status),
@@ -2094,9 +2113,14 @@ top:
jobstatus.error_status[0],
jobstatus.error_status[1],
jobstatus.error_status[2]);
+
+ /* Retry job on the other deck.. */
+ if (ctx->num_decks == 2)
+ goto top;
+
return CUPS_BACKEND_STOP;
}
- } else if (deck == 1) {
+ } else if (deck == 2) {
if (jobstatus.error_status_up[0]) {
ERROR("UPPER: %s/%s -> %s: %02x/%02x/%02x\n",
mitsu70x_errorclass(jobstatus.error_status_up),
@@ -2105,6 +2129,11 @@ top:
jobstatus.error_status_up[0],
jobstatus.error_status_up[1],
jobstatus.error_status_up[2]);
+
+ /* Retry job on the other deck.. */
+ if (ctx->num_decks == 2)
+ goto top;
+
return CUPS_BACKEND_STOP;
}
}
@@ -2136,16 +2165,20 @@ top:
break;
}
+ /* See if we can return early, but wait until printing has started! */
+ if (fast_return && copies <= 1 && /* Copies generated by backend! */
+ jobstatus.job_status[0] == JOB_STATUS0_PRINT &&
+ jobstatus.job_status[1] > JOB_STATUS1_PRINT_MEDIALOAD)
+ {
+ INFO("Fast return mode enabled.\n");
+ break;
+ }
+
/* On a two deck system, try to use the second deck
for additional copies. If we can't use it, we'll block. */
if (ctx->num_decks > 1 && copies > 1)
break;
- if (fast_return && copies <= 1) { /* Copies generated by backend! */
- INFO("Fast return mode enabled.\n");
- break;
- }
-
/* Update cache for the next round */
memcpy(last_status, jobstatus.job_status, 4);
} while(1);
@@ -2167,6 +2200,7 @@ static void mitsu70x_dump_printerstatus(struct mitsu70x_ctx *ctx,
struct mitsu70x_printerstatus_resp *resp)
{
uint32_t i;
+ uint8_t memory = ~resp->memory;
INFO("Model : ");
for (i = 0 ; i < 6 ; i++) {
@@ -2198,6 +2232,15 @@ static void mitsu70x_dump_printerstatus(struct mitsu70x_ctx *ctx,
INFO("Standby Timeout: %d minutes\n", resp->sleeptime);
INFO("iSerial Reporting: %s\n", resp->iserial ? "No" : "Yes" );
INFO("Power Status: %s\n", resp->power ? "Sleeping" : "Awake");
+ INFO("Available Memory Banks: %s%s%s%s%s%s%s%s\n",
+ (memory & 0x01) ? "mem8 " : "",
+ (memory & 0x02) ? "mem7 " : "",
+ (memory & 0x04) ? "mem6 " : "",
+ (memory & 0x08) ? "mem5 " : "",
+ (memory & 0x10) ? "mem4 " : "",
+ (memory & 0x20) ? "mem3 " : "",
+ (memory & 0x40) ? "mem2 " : "",
+ (memory & 0x80) ? "mem1 " : "");
if (resp->lower.error_status[0]) {
INFO("Lower Error Status: %s/%s -> %s\n",
@@ -2292,6 +2335,7 @@ static int mitsu70x_query_jobs(struct mitsu70x_ctx *ctx)
}
INFO("Temperature: %s\n", mitsu70x_temperatures(jobstatus.temperature));
}
+
// memory status?
#if 0
@@ -2354,7 +2398,6 @@ static void mitsu70x_cmdline(void)
DEBUG("\t\t[ -j ] # Query job status\n");
DEBUG("\t\t[ -w ] # Wake up printer\n");
DEBUG("\t\t[ -W ] # Wake up printer and wait\n");
- DEBUG("\t\t[ -f ] # Use fast return mode\n");
DEBUG("\t\t[ -k num ] # Set standby time (1-60 minutes, 0 disables)\n");
DEBUG("\t\t[ -x num ] # Set USB iSerialNumber Reporting (1 on, 0 off)\n");
DEBUG("\t\t[ -X jobid ] # Abort a printjob\n");}
@@ -2437,7 +2480,7 @@ static int mitsu70x_query_markers(void *vctx, struct marker **markers, int *coun
static const char *mitsu70x_prefixes[] = {
"mitsu70x", // Family entry, do not nuke.
- "mitsubishi-d70dw", "mitsubishi-d80dw", "mitsubishi-k60dw", "kodak-305", "fujifilm-ask-300"
+ "mitsubishi-d70dw", "mitsubishi-d80dw", "mitsubishi-k60dw", "kodak-305", "fujifilm-ask-300",
// Extras
"mitsubishi-d707dw", "mitsubishi-k60dws",
// backwards compatibility
@@ -2448,7 +2491,7 @@ static const char *mitsu70x_prefixes[] = {
/* Exported */
struct dyesub_backend mitsu70x_backend = {
.name = "Mitsubishi CP-D70 family",
- .version = "0.88",
+ .version = "0.95",
.uri_prefixes = mitsu70x_prefixes,
.flags = BACKEND_FLAG_JOBLIST,
.cmdline_usage = mitsu70x_cmdline,
@@ -2471,7 +2514,7 @@ struct dyesub_backend mitsu70x_backend = {
}
};
-/* Mitsubish CP-D70DW/D707DW/K60DW-S/D80DW, Kodak 305, Fuji ASK-300
+/* Mitsubish CP-D70DW/D707DW/K60DW-S/D80DW, Kodak 305, Fujifilm ASK-300
data format:
Spool file consists of two headers followed by three image planes
diff --git a/src/cups/backend_mitsu9550.c b/src/cups/backend_mitsu9550.c
index ab7530a..98473ca 100644
--- a/src/cups/backend_mitsu9550.c
+++ b/src/cups/backend_mitsu9550.c
@@ -1,7 +1,7 @@
/*
* Mitsubishi CP-9xxx Photo Printer Family CUPS backend
*
- * (c) 2014-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2014-2019 Solomon Peachy <pizza@shaftnet.org>
*
* The latest version of this program can be found at:
*
@@ -43,21 +43,59 @@
#define BACKEND mitsu9550_backend
+
+#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
+
#include "backend_common.h"
-#define USB_VID_MITSU 0x06D3
-#define USB_PID_MITSU_9500D 0x0393
-#define USB_PID_MITSU_9000D 0x0394
-#define USB_PID_MITSU_9000AM 0x0395
-#define USB_PID_MITSU_9550D 0x03A1
-#define USB_PID_MITSU_9550DS 0x03A5 // or DZ/DZS/DZU
-#define USB_PID_MITSU_9600D 0x03A9
-//#define USB_PID_MITSU_9600DS XXXXXX
-#define USB_PID_MITSU_9800D 0x03AD
-#define USB_PID_MITSU_9800DS 0x03AE
-#define USB_PID_MITSU_98__D 0x3B21
-//#define USB_PID_MITSU_9810D XXXXXX
-//#define USB_PID_MITSU_9820DS XXXXXX
+// #include "lib70x/libMitsuD70ImageReProcess.h"
+
+#ifndef LUT_LEN
+#define COLORCONV_RGB 0
+#define COLORCONV_BGR 1
+
+#define LUT_LEN 14739
+struct BandImage {
+ void *imgbuf;
+ int32_t bytes_per_row;
+ uint16_t origin_cols;
+ uint16_t origin_rows;
+ uint16_t cols;
+ uint16_t rows;
+};
+#endif
+
+#define REQUIRED_LIB_APIVERSION 4
+
+/* Image processing library function prototypes */
+#define LIB_NAME_RE "libMitsuD70ImageReProcess.so" // Reimplemented library
+
+typedef int (*lib70x_getapiversionFN)(void);
+typedef int (*Get3DColorTableFN)(uint8_t *buf, const char *filename);
+typedef struct CColorConv3D *(*Load3DColorTableFN)(const uint8_t *ptr);
+typedef void (*Destroy3DColorTableFN)(struct CColorConv3D *this);
+typedef void (*DoColorConvFN)(struct CColorConv3D *this, uint8_t *data, uint16_t cols, uint16_t rows, uint32_t bytes_per_row, int rgb_bgr);
#ifndef CORRTABLE_PATH
#ifdef PACKAGE_DATA_DIR
@@ -73,80 +111,90 @@
#define LAMINATE_STRIDE 1868
#define DATATABLE_SIZE 42204
+/* USB VIDs and PIDs */
+
+#define USB_VID_MITSU 0x06D3
+#define USB_PID_MITSU_9500D 0x0393
+#define USB_PID_MITSU_9000D 0x0394
+#define USB_PID_MITSU_9000AM 0x0395
+#define USB_PID_MITSU_9550D 0x03A1
+#define USB_PID_MITSU_9550DS 0x03A5 // or DZ/DZS/DZU
+#define USB_PID_MITSU_9600D 0x03A9
+//#define USB_PID_MITSU_9600DS XXXXXX
+#define USB_PID_MITSU_9800D 0x03AD
+#define USB_PID_MITSU_9800DS 0x03AE
+#define USB_PID_MITSU_98__D 0x3B21
+//#define USB_PID_MITSU_9810D XXXXXX
+//#define USB_PID_MITSU_9820DS XXXXXX
+
/* Spool file structures */
/* Print parameters1 */
struct mitsu9550_hdr1 {
- uint8_t cmd[4]; /* 1b 57 20 2e */
+ uint8_t cmd[4]; /* 1b 57 20 2e */
uint8_t unk[10]; /* 00 0a 10 00 [...] */
- uint16_t cols; /* BE */
- uint16_t rows; /* BE */
- uint8_t matte; /* CP9810/9820 only. 01 for matte, 00 glossy */
+ uint16_t cols; /* BE */
+ uint16_t rows; /* BE */
+ uint8_t matte; /* CP9810/9820 only. 01 for matte, 00 glossy */
uint8_t null[31];
} __attribute__((packed));
/* Print parameters2 */
struct mitsu9550_hdr2 {
- uint8_t cmd[4]; /* 1b 57 21 2e */
- uint8_t unk[24]; /* 00 80 00 22 08 03 [...] */
- uint16_t copies; /* BE, 1-680 */
+ uint8_t cmd[4]; /* 1b 57 21 2e */
+ uint8_t unk[24]; /* 00 80 00 22 08 03 [...] */
+ uint16_t copies; /* BE, 1-680 */
uint8_t null[2];
- uint8_t cut; /* 00 == normal, 83 == 2x6*2 */
+ uint8_t cut; /* 00 == normal, 83 == 2x6*2 */
uint8_t unkb[5];
- uint8_t mode; /* 00 == fine, 80 == superfine */
+ uint8_t mode; /* 00 == fine, 80 == superfine */
uint8_t unkc[11]; /* 00 [...] 00 01 */
} __attribute__((packed));
/* Fine Deep selection (9550 only) */
struct mitsu9550_hdr3 {
- uint8_t cmd[4]; /* 1b 57 22 2e */
- uint8_t unk[7]; /* 00 40 00 [...] */
- uint8_t mode2; /* 00 == normal, 01 == finedeep */
+ uint8_t cmd[4]; /* 1b 57 22 2e */
+ uint8_t unk[7]; /* 00 40 00 [...] */
+ uint8_t mode2; /* 00 == normal, 01 == finedeep */
uint8_t null[38];
} __attribute__((packed));
/* Error policy? */
struct mitsu9550_hdr4 {
- uint8_t cmd[4]; /* 1b 57 26 2e */
- uint8_t unk[46]; /* 00 70 00 00 00 00 00 00 01 01 00 [...] */
+ uint8_t cmd[4]; /* 1b 57 26 2e */
+ uint8_t unk[46]; /* 00 70 00 00 00 00 00 00 01 01 00 [...] */
} __attribute__((packed));
/* Data plane header */
struct mitsu9550_plane {
- uint8_t cmd[4]; /* 1b 5a 54 XX */ /* XX == 0x10 if 16bpp, 0x00 for 8bpp */
+ uint8_t cmd[4]; /* 1b 5a 54 XX */ /* XX == 0x10 if 16bpp, 0x00 for 8bpp */
uint16_t col_offset; /* BE, normally 0, where we start dumping data */
uint16_t row_offset; /* BE, normally 0, where we start dumping data */
uint16_t cols; /* BE */
uint16_t rows; /* BE */
} __attribute__((packed));
-/* CP98xx Tabular Data */
+/* CP98xx Tabular Data, as stored in data file! */
struct mitsu98xx_data {
- uint16_t GNMby[256]; // @0
- uint16_t GNMgm[256]; // @512
- uint16_t GNMrc[256]; // @1024
- double GammaParams[3]; // @1536
- uint8_t KH[2048]; // @1560
- uint32_t unk_b[3]; // @3608
-
- struct {
- double unka[256]; // @0
- double unkb[256]; // @2048
- uint32_t unkc[10]; // @4096
- double unkd[256]; // @4136
- double unke[256]; // @6184 // *= sharp->coef[X]
- uint32_t unkf[10]; // @8232
- double unkg[256]; // @8272
- // @10320
- } WMAM; // @3620
- uint8_t unc_d[4]; // @13940 @10320 (from wmam start)
- struct {
- uint32_t unk_a; // @13944/10324 (padding?)
- double coef[10]; // @13948/10328 (sharpness coefficients, level 0-9)
- uint32_t unk_b[5]; // @14028/10408
- } sharp; // total 104, @13944/10324
- uint8_t unk_e[20]; // @14048/10428
- // @14068/10448
+ /* @ 0 */ uint16_t GNMby[256]; /* BGR Order uncertain */
+ /* @ 512 */ uint16_t GNMgm[256];
+ /* @ 1024 */ uint16_t GNMrc[256];
+ /* @ 1536 */ uint16_t unk_sharp[20]; /* Actual format is: u16, u16[9], u16, u16[9] */
+ /* @ 1576 */ double GammaAdj[3]; /* Assumed to be same order as tables (BGR?) */
+ /* @ 1600 */ struct {
+ /* @ 0 */ double unka[256];
+ /* @ 2048 */ double unkb[256];
+ /* @ 4096 */ uint32_t unkc[10];
+ /* @ 4136 */ double unkd[256];
+ /* @ 6184 */ double unke[256]; // *= sharp->coef[X]
+ /* @ 8232 */ uint32_t unkf[10];
+ /* @ 8272 */ double unkg[256];
+ /* @10320 */
+ } WMAM;
+ /* @11920 */ double sharp_coef[11]; /* 0 is off, 1-10 are the levels. Default is 5. [4 in settings] */
+ /* @12008 */ uint32_t unk_kh[3];
+ /* @12020 */ uint8_t KH[2048];
+ /* @14068 */
} __attribute__((packed));
struct mitsu98xx_tables {
@@ -194,8 +242,15 @@ struct mitsu9550_ctx {
struct marker marker;
/* CP98xx stuff */
- struct mitsu98xx_tables *m98xxdata;
+ void *dl_handle;
+ lib70x_getapiversionFN GetAPIVersion;
+ Get3DColorTableFN Get3DColorTable;
+ Load3DColorTableFN Load3DColorTable;
+ Destroy3DColorTableFN Destroy3DColorTable;
+ DoColorConvFN DoColorConv;
+
struct CColorConv3D *lut;
+ struct mitsu98xx_tables *m98xxdata;
};
/* Printer data structures */
@@ -290,11 +345,9 @@ static void mitsu98xx_dogamma(uint8_t *src, uint16_t *dest, uint8_t plane,
{
src += plane;
while(len--) {
- *dest++ = table[*src];
+ *dest++ = cpu_to_be16(table[*src]);
src += 3;
}
- /* TODO: Eventually, when we do real processing of this data, we will need to
- have the gamma table in native endian format and generate BE data at the end. */
}
static int mitsu98xx_fillmatte(struct mitsu9550_printjob *job)
@@ -302,7 +355,7 @@ static int mitsu98xx_fillmatte(struct mitsu9550_printjob *job)
int fd, i;
uint32_t j, remain;
- DEBUG("Reading %d bytes of matte data from disk (%d/%d)\n", job->cols * job->rows, job->cols, LAMINATE_STRIDE);
+ DEBUG("Reading %d bytes of matte data from disk (%d/%d)\n", job->cols * job->rows * 2, job->cols, LAMINATE_STRIDE);
fd = open(MITSU_M98xx_LAMINATE_FILE, O_RDONLY);
if (fd < 0) {
WARNING("Unable to open matte lamination data file '%s'\n", MITSU_M98xx_LAMINATE_FILE);
@@ -318,8 +371,8 @@ static int mitsu98xx_fillmatte(struct mitsu9550_printjob *job)
matte->cmd[3] = 0x10;
matte->row_offset = 0;
matte->col_offset = 0;
- matte->cols = job->hdr1.cols;
- matte->rows = job->hdr1.rows;
+ matte->cols = cpu_to_be16(job->hdr1.cols);
+ matte->rows = cpu_to_be16(job->hdr1.rows);
job->datalen += sizeof(struct mitsu9550_plane);
/* Read in the matte data plane */
@@ -355,173 +408,12 @@ done:
return CUPS_BACKEND_OK;
}
-/*** 3D color Lookup table stuff. Taken out of lib70x ****/
+#ifndef LUT_LEN
#define LUT_LEN 14739
#define COLORCONV_RGB 0
#define COLORCONV_BGR 1
-
-struct CColorConv3D {
- uint8_t lut[17][17][17][3];
-};
-
-/* Load the Lookup table off of disk into *PRE-ALLOCATED* buffer */
-int CColorConv3D_Get3DColorTable(uint8_t *buf, const char *filename)
-{
- FILE *stream;
-
- if (!filename)
- return 1;
- if (!*filename)
- return 2;
- if (!buf)
- return 3;
-
- stream = fopen(filename, "rb");
- if (!stream)
- return 4;
-
- fseek(stream, 0, SEEK_END);
- if (ftell(stream) < LUT_LEN) {
- fclose(stream);
- return 5;
- }
- fseek(stream, 0, SEEK_SET);
- fread(buf, 1, LUT_LEN, stream);
- fclose(stream);
-
- return 0;
-}
-
-/* Parse the on-disk LUT data into the structure.... */
-struct CColorConv3D *CColorConv3D_Load3DColorTable(const uint8_t *ptr)
-{
- struct CColorConv3D *this;
- this = malloc(sizeof(*this));
- if (!this)
- return NULL;
-
- int i, j, k;
-
- for (i = 0 ; i <= 16 ; i++) {
- for (j = 0 ; j <= 16 ; j++) {
- for (k = 0; k <= 16; k++) {
- this->lut[k][j][i][2] = *ptr++;
- this->lut[k][j][i][1] = *ptr++;
- this->lut[k][j][i][0] = *ptr++;
- }
- }
- }
- return this;
-}
-void CColorConv3D_Destroy3DColorTable(struct CColorConv3D *this)
-{
- free(this);
-}
-
-/* Transform a single pixel. */
-static void CColorConv3D_DoColorConvPixel(struct CColorConv3D *this, uint8_t *redp, uint8_t *grnp, uint8_t *blup)
-{
- int red_h;
- int grn_h;
- int blu_h;
- int grn_li;
- int red_li;
- int blu_li;
- int red_l;
- int grn_l;
- int blu_l;
-
- uint8_t *tab0; // @ 14743
- uint8_t *tab1; // @ 14746
- uint8_t *tab2; // @ 14749
- uint8_t *tab3; // @ 14752
- uint8_t *tab4; // @ 14755
- uint8_t *tab5; // @ 14758
- uint8_t *tab6; // @ 14761
- uint8_t *tab7; // @ 14764
-
- red_h = *redp >> 4;
- red_l = *redp & 0xF;
- red_li = 16 - red_l;
-
- grn_h = *grnp >> 4;
- grn_l = *grnp & 0xF;
- grn_li = 16 - grn_l;
-
- blu_h = *blup >> 4;
- blu_l = *blup & 0xF;
- blu_li = 16 - blu_l;
-
-// printf("%d %d %d =>", *redp, *grnp, *blup);
-
- tab0 = this->lut[red_h+0][grn_h+0][blu_h+0];
- tab1 = this->lut[red_h+1][grn_h+0][blu_h+0];
- tab2 = this->lut[red_h+0][grn_h+1][blu_h+0];
- tab3 = this->lut[red_h+1][grn_h+1][blu_h+0];
- tab4 = this->lut[red_h+0][grn_h+0][blu_h+1];
- tab5 = this->lut[red_h+1][grn_h+0][blu_h+1];
- tab6 = this->lut[red_h+0][grn_h+1][blu_h+1];
- tab7 = this->lut[red_h+1][grn_h+1][blu_h+1];
-
-#if 0
- printf(" %d %d %d ", tab0[0], tab0[1], tab0[2]);
- printf(" %d %d %d ", tab1[0], tab1[1], tab1[2]);
- printf(" %d %d %d ", tab2[0], tab2[1], tab2[2]);
- printf(" %d %d %d ", tab3[0], tab3[1], tab3[2]);
- printf(" %d %d %d ", tab4[0], tab4[1], tab4[2]);
- printf(" %d %d %d ", tab5[0], tab5[1], tab5[2]);
- printf(" %d %d %d ", tab6[0], tab6[1], tab6[2]);
- printf(" %d %d %d ", tab7[0], tab7[1], tab7[2]);
#endif
- *redp = (blu_li
- * (grn_li * (red_li * tab0[0] + red_l * tab1[0])
- + grn_l * (red_li * tab2[0] + red_l * tab3[0]))
- + blu_l
- * (grn_li * (red_li * tab4[0] + red_l * tab5[0])
- + grn_l * (red_li * tab6[0] + red_l * tab7[0]))
- + 2048) >> 12;
- *grnp = (blu_li
- * (grn_li * (red_li * tab0[1] + red_l * tab1[1])
- + grn_l * (red_li * tab2[1] + red_l * tab3[1]))
- + blu_l
- * (grn_li * (red_li * tab4[1] + red_l * tab5[1])
- + grn_l * (red_li * tab6[1] + red_l * tab7[1]))
- + 2048) >> 12;
- *blup = (blu_li
- * (grn_li * (red_li * tab0[2] + red_l * tab1[2])
- + grn_l * (red_li * tab2[2] + red_l * tab3[2]))
- + blu_l
- * (grn_li * (red_li * tab4[2] + red_l * tab5[2])
- + grn_l * (red_li * tab6[2] + red_l * tab7[2]))
- + 2048) >> 12;
-
-// printf("=> %d %d %d\n", *redp, *grnp, *blup);
-}
-
-/* Perform a total conversion on an entire image */
-void CColorConv3D_DoColorConv(struct CColorConv3D *this, uint8_t *data, uint16_t cols, uint16_t rows, uint32_t stride, int rgb_bgr)
-{
- uint16_t i, j;
-
- uint8_t *ptr;
-
- for ( i = 0; i < rows ; i++ )
- {
- ptr = data;
- for ( j = 0; cols > j; j++ )
- {
- if (rgb_bgr) {
- CColorConv3D_DoColorConvPixel(this, ptr + 2, ptr + 1, ptr);
- } else {
- CColorConv3D_DoColorConvPixel(this, ptr, ptr + 1, ptr + 2);
- }
- ptr += 3;
- }
- data += stride;
- }
-}
-/* ---- end 3D LUT ---- */
static int mitsu9550_get_status(struct mitsu9550_ctx *ctx, uint8_t *resp, int status, int status2, int media);
static char *mitsu9550_media_types(uint8_t type, uint8_t is_s);
@@ -534,6 +426,8 @@ static void *mitsu9550_init(void)
}
memset(ctx, 0, sizeof(struct mitsu9550_ctx));
+ DL_INIT();
+
return ctx;
}
@@ -559,6 +453,46 @@ static int mitsu9550_attach(void *vctx, struct libusb_device_handle *dev, int ty
ctx->type == P_MITSU_9810)
ctx->is_98xx = 1;
+ /* Attempt to open the library */
+#if defined(WITH_DYNAMIC)
+ if (!ctx->is_98xx) goto skip;
+
+ DEBUG("Attempting to load image processing library\n");
+ ctx->dl_handle = DL_OPEN(LIB_NAME_RE);
+ if (!ctx->dl_handle)
+ WARNING("Image processing library not found, using internal fallback code\n");
+ if (ctx->dl_handle) {
+ ctx->GetAPIVersion = DL_SYM(ctx->dl_handle, "lib70x_getapiversion");
+ if (!ctx->GetAPIVersion) {
+ ERROR("Problem resolving API Version symbol in imaging processing library, too old or not installed?\n");
+ DL_CLOSE(ctx->dl_handle);
+ ctx->dl_handle = NULL;
+ return CUPS_BACKEND_FAILED;
+ }
+ if (ctx->GetAPIVersion() != REQUIRED_LIB_APIVERSION) {
+ ERROR("Image processing library API version mismatch!\n");
+ DL_CLOSE(ctx->dl_handle);
+ ctx->dl_handle = NULL;
+ return CUPS_BACKEND_FAILED;
+ }
+
+ ctx->Get3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Get3DColorTable");
+ ctx->Load3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Load3DColorTable");
+ ctx->Destroy3DColorTable = DL_SYM(ctx->dl_handle, "CColorConv3D_Destroy3DColorTable");
+ ctx->DoColorConv = DL_SYM(ctx->dl_handle, "CColorConv3D_DoColorConv");
+ if (!ctx->Get3DColorTable || !ctx->Load3DColorTable ||
+ !ctx->Destroy3DColorTable || !ctx->DoColorConv ) {
+ ERROR("Problem resolving symbols in imaging processing library\n");
+ DL_CLOSE(ctx->dl_handle);
+ ctx->dl_handle = NULL;
+ return CUPS_BACKEND_FAILED;
+ } else {
+ DEBUG("Image processing library successfully loaded\n");
+ }
+ }
+skip:
+#endif
+
if (test_mode < TEST_MODE_NOATTACH) {
if (mitsu9550_get_status(ctx, (uint8_t*) &media, 0, 0, 1))
return CUPS_BACKEND_FAILED;
@@ -596,10 +530,14 @@ static void mitsu9550_teardown(void *vctx) {
if (!ctx)
return;
- if (ctx->lut)
- CColorConv3D_Destroy3DColorTable(ctx->lut);
- if (ctx->m98xxdata)
- free(ctx->m98xxdata);
+ if (ctx->dl_handle) {
+ if (ctx->lut)
+ ctx->Destroy3DColorTable(ctx->lut);
+ if (ctx->m98xxdata)
+ free(ctx->m98xxdata);
+ DL_CLOSE(ctx->dl_handle);
+ }
+
free(ctx);
}
@@ -700,31 +638,56 @@ hdr_done:
/* Read in CP98xx data tables if necessary */
if (ctx->is_98xx && !job->is_raw && !ctx->m98xxdata) {
- int fd;
-
- DEBUG("Reading in 98xx data from disk\n");
- fd = open(MITSU_M98xx_DATATABLE_FILE, O_RDONLY);
- if (fd < 0) {
- ERROR("Unable to open 98xx data table file '%s'\n", MITSU_M98xx_DATATABLE_FILE);
- mitsu9550_cleanup_job(job);
- return CUPS_BACKEND_FAILED;
- }
+ int ret;
ctx->m98xxdata = malloc(DATATABLE_SIZE);
if (!ctx->m98xxdata) {
ERROR("Memory allocation Failure!\n");
mitsu9550_cleanup_job(job);
return CUPS_BACKEND_RETRY_CURRENT;
}
- remain = DATATABLE_SIZE;
- while (remain) {
- i = read(fd, ((uint8_t*)ctx->m98xxdata) + (DATATABLE_SIZE - remain), remain);
- if (i < 0) {
- mitsu9550_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
+
+ DEBUG("Reading in 98xx data from disk\n");
+ if ((ret = dyesub_read_file(MITSU_M98xx_DATATABLE_FILE, ctx->m98xxdata, DATATABLE_SIZE, NULL))) {
+ ERROR("Unable to read 98xx data table file '%s'\n", MITSU_M98xx_DATATABLE_FILE);
+ free(ctx->m98xxdata);
+ return ret;
+ }
+
+ /* Byteswap data table to native endianness, if necessary */
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+ int j;
+ struct mitsu98xx_data *ptr = &ctx->m98xxdata->superfine;
+ for (j = 0 ; j < 3 ; j++) {
+ for (i = 3 ; i < 3 ; i++) {
+ ptr->GammaAdj[i] = be64_to_cpu(ptr->GammaAdj[i]);
+ ptr->unk_kh[i] = be32_to_cpu(ptr->unk_kh[i]);
}
- remain -= i;
+ for (i = 0 ; i < 10 ; i++) {
+ ptr->WMAM.unkc[i] = be32_to_cpu(ptr->WMAM.unkc[i]);
+ ptr->WMAM.unkf[i] = be32_to_cpu(ptr->WMAM.unkf[i]);
+ }
+ for (i = 0 ; i < 11 ; i++) {
+ ptr->sharp_coef[i] = be64_to_cpu(ptr->sharp_coef[i]);
+ }
+ for (i = 0 ; i < 20 ; i++) {
+ ptr->unk_sharp[i] = be16_to_cpu(ptr->unk_sharp[i]);
+ }
+ for (i = 0 ; i < 256 ; i++) {
+ ptr->WMAM.unka[i] = be64_to_cpu(ptr->WMAM.unka[i]);
+ ptr->WMAM.unkb[i] = be64_to_cpu(ptr->WMAM.unkb[i]);
+ ptr->WMAM.unkd[i] = be64_to_cpu(ptr->WMAM.unkd[i]);
+ ptr->WMAM.unke[i] = be64_to_cpu(ptr->WMAM.unke[i]);
+ ptr->WMAM.unkg[i] = be64_to_cpu(ptr->WMAM.unkg[i]);
+
+ ptr->GNMby[i] = be16_to_cpu(ptr->GNMby[i]);
+ ptr->GNMgm[i] = be16_to_cpu(ptr->GNMgm[i]);
+ ptr->GNMrc[i] = be16_to_cpu(ptr->GNMrc[i]);
+
+ }
+ // XXX TODO: KH[2048]
+ ptr++;
}
- close(fd);
+#endif
}
if (job->is_raw) {
@@ -832,8 +795,10 @@ hdr_done:
memcpy(job->databuf + job->datalen, buf, 4);
job->datalen += 4;
- /* Unless we have a matte plane following, we're done */
- if (job->hdr1.matte != 0x01)
+ /* Unless we have a raw matte plane following,
+ we're done */
+ if (job->hdr1.matte != 0x01 ||
+ !job->is_raw)
break;
remain = sizeof(buf);
} else {
@@ -856,31 +821,40 @@ hdr_done:
}
}
- /* Apply LUT */
+ /* Apply LUT, if job calls for it.. */
if (ctx->is_98xx && !job->is_raw && job->hdr2.unkc[9]) {
- DEBUG("Applying 3D LUT\n");
+
+ if (!ctx->dl_handle) {
+ // XXXFALLBACK write fallback code?
+ ERROR("!!! Image Processing Library not found, aborting!\n");
+ mitsu9550_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
+
if (!ctx->lut) {
- uint8_t *buf = malloc(LUT_LEN);
- if (!buf) {
+ uint8_t *lbuf = malloc(LUT_LEN);
+ if (!lbuf) {
ERROR("Memory allocation failure!\n");
mitsu9550_cleanup_job(job);
return CUPS_BACKEND_RETRY_CURRENT;
}
- if (CColorConv3D_Get3DColorTable(buf, MITSU_M98xx_LUT_FILE)) {
+ if (ctx->Get3DColorTable(lbuf, MITSU_M98xx_LUT_FILE)) {
ERROR("Unable to open LUT file '%s'\n", MITSU_M98xx_LUT_FILE);
mitsu9550_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
}
- ctx->lut = CColorConv3D_Load3DColorTable(buf);
- free(buf);
+ ctx->lut = ctx->Load3DColorTable(lbuf);
+ free(lbuf);
if (!ctx->lut) {
ERROR("Unable to parse LUT\n");
mitsu9550_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
}
}
- CColorConv3D_DoColorConv(ctx->lut, job->databuf + sizeof(struct mitsu9550_plane),
- job->cols, job->rows, job->cols * 3, COLORCONV_BGR);
+
+ DEBUG("Running print data through 3D LUT\n");
+ ctx->DoColorConv(ctx->lut, job->databuf + sizeof(struct mitsu9550_plane),
+ job->cols, job->rows, job->cols * 3, COLORCONV_BGR);
job->hdr2.unkc[9] = 0;
}
@@ -1199,7 +1173,7 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) {
int i, remain, planelen;
planelen = job->rows * job->cols * 2;
- remain = (job->hdr1.matte ? 3 : 4) * (planelen + sizeof(struct mitsu9550_plane)) + sizeof(struct mitsu9550_cmd);
+ remain = (job->hdr1.matte ? 4 : 3) * (planelen + sizeof(struct mitsu9550_plane)) + sizeof(struct mitsu9550_cmd) * (job->hdr1.matte? 2 : 1) + LAMINATE_STRIDE * 2;
newbuf = malloc(remain);
if (!newbuf) {
ERROR("Memory allocation Failure!\n");
@@ -1254,7 +1228,7 @@ static int mitsu9550_main_loop(void *vctx, const void *vjob) {
newlen += planelen;
/* And finally, the job footer. */
- memcpy(newbuf + newlen, job->databuf + sizeof(struct mitsu9550_plane) + planelen * 3, sizeof(struct mitsu9550_cmd));
+ memcpy(newbuf + newlen, job->databuf + sizeof(struct mitsu9550_plane) + planelen/2 * 3, sizeof(struct mitsu9550_cmd));
newlen += sizeof(struct mitsu9550_cmd);
/* Clean up, and move pointer to new buffer; */
@@ -1362,7 +1336,6 @@ top:
/* Send over plane data */
while(ptr < (job->databuf + job->datalen)) {
struct mitsu9550_plane *plane = (struct mitsu9550_plane *)ptr;
- uint32_t planelen;
if (plane->cmd[0] != 0x1b ||
plane->cmd[1] != 0x5a ||
plane->cmd[2] != 0x54)
@@ -1457,7 +1430,7 @@ top:
/* Don't forget the 9810's matte plane */
if (job->hdr1.matte) {
struct mitsu9550_plane *plane = (struct mitsu9550_plane *)ptr;
- uint32_t planelen = be16_to_cpu(plane->rows) * be16_to_cpu(plane->cols);
+ planelen = be16_to_cpu(plane->rows) * be16_to_cpu(plane->cols);
if (plane->cmd[3] == 0x10)
planelen *= 2;
@@ -1735,7 +1708,7 @@ static const char *mitsu9550_prefixes[] = {
/* Exported */
struct dyesub_backend mitsu9550_backend = {
.name = "Mitsubishi CP9xxx family",
- .version = "0.41",
+ .version = "0.47",
.uri_prefixes = mitsu9550_prefixes,
.cmdline_usage = mitsu9550_cmdline,
.cmdline_arg = mitsu9550_cmdline_arg,
diff --git a/src/cups/backend_mitsud90.c b/src/cups/backend_mitsud90.c
index 9655e55..2a5764c 100644
--- a/src/cups/backend_mitsud90.c
+++ b/src/cups/backend_mitsud90.c
@@ -559,15 +559,6 @@ static void mitsud90_cleanup_job(const void *vjob)
free((void*)job);
}
-static void mitsud90_teardown(void *vctx) {
- struct mitsud90_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int mitsud90_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct mitsud90_ctx *ctx = vctx;
int i, remain;
@@ -1232,7 +1223,6 @@ struct dyesub_backend mitsud90_backend = {
.init = mitsud90_init,
.attach = mitsud90_attach,
.cleanup_job = mitsud90_cleanup_job,
- .teardown = mitsud90_teardown,
.read_parse = mitsud90_read_parse,
.main_loop = mitsud90_main_loop,
.query_markers = mitsud90_query_markers,
diff --git a/src/cups/backend_mitsup95d.c b/src/cups/backend_mitsup95d.c
index c4e0054..284cc01 100644
--- a/src/cups/backend_mitsup95d.c
+++ b/src/cups/backend_mitsup95d.c
@@ -169,15 +169,6 @@ static void mitsup95d_cleanup_job(const void *vjob)
free((void*)job);
}
-static void mitsup95d_teardown(void *vctx) {
- struct mitsup95d_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int mitsup95d_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct mitsup95d_ctx *ctx = vctx;
uint8_t buf[2]; /* Enough to read in any header */
@@ -584,6 +575,13 @@ static int mitsup95d_query_markers(void *vctx, struct marker **markers, int *cou
}
}
+ /* Lot state */
+ if (ctx->marker.levelnow)
+ STATE("-media-empty\n");
+ else
+ STATE("+media-empty\n");
+
+
*markers = &ctx->marker;
*count = 1;
@@ -601,13 +599,12 @@ static const char *mitsup95d_prefixes[] = {
/* Exported */
struct dyesub_backend mitsup95d_backend = {
.name = "Mitsubishi P93D/P95D",
- .version = "0.11",
+ .version = "0.12",
.uri_prefixes = mitsup95d_prefixes,
.cmdline_arg = mitsup95d_cmdline_arg,
.cmdline_usage = mitsup95d_cmdline,
.init = mitsup95d_init,
.attach = mitsup95d_attach,
- .teardown = mitsup95d_teardown,
.cleanup_job = mitsup95d_cleanup_job,
.read_parse = mitsup95d_read_parse,
.main_loop = mitsup95d_main_loop,
diff --git a/src/cups/backend_shinkos1245.c b/src/cups/backend_shinkos1245.c
index cd0d34c..99fc690 100644
--- a/src/cups/backend_shinkos1245.c
+++ b/src/cups/backend_shinkos1245.c
@@ -1,7 +1,7 @@
/*
* Shinko/Sinfonia CHC-S1245 CUPS backend -- libusb-1.0 version
*
- * (c) 2015-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2015-2019 Solomon Peachy <pizza@shaftnet.org>
*
* Low-level documentation was provided by Sinfonia, Inc. Thank you!
*
@@ -41,46 +41,7 @@
#define BACKEND shinkos1245_backend
#include "backend_common.h"
-
-/* Structure of printjob header. All fields are LITTLE ENDIAN */
-struct s1245_printjob_hdr {
- uint32_t len1; /* Fixed at 0x10 */
- uint32_t model; /* Equal to the printer model (eg '1245' or '2145' decimal) */
- uint32_t unk2; /* Null */
- uint32_t unk3; /* Fixed at 0x01 */
-
- uint32_t len2; /* Fixed at 0x64 */
- uint32_t unk5; /* Null */
- uint32_t media; /* Fixed at 0x10 */
- uint32_t unk6; /* Null */
-
- uint32_t method; /* Print Method */
- uint32_t mode; /* Print Mode */
- uint32_t unk7; /* Null */
- int32_t mattedepth; /* 0x7fffffff for glossy, 0x00 +- 25 for matte */
-
- uint32_t dust; /* Dust control */
- uint32_t columns;
- uint32_t rows;
- uint32_t copies;
-
- uint32_t unk10; /* Null */
- uint32_t unk11; /* Null */
- uint32_t unk12; /* Null */
- uint32_t unk13; /* 0xceffffff */
-
- uint32_t unk14; /* Null */
- uint32_t unk15; /* 0xceffffff */
- uint32_t dpi; /* Fixed at '300' (decimal) */
- uint32_t unk16; /* 0xceffffff */
-
- uint32_t unk17; /* Null */
- uint32_t unk18; /* 0xceffffff */
- uint32_t unk19; /* Null */
- uint32_t unk20; /* Null */
-
- uint32_t unk21; /* Null */
-} __attribute__((packed));
+#include "backend_sinfonia.h"
/* Printer data structures */
struct shinkos1245_cmd_hdr {
@@ -166,113 +127,6 @@ struct shinkos1245_resp_status {
uint8_t curve_status;
} __attribute__((packed));
-enum {
- CMD_CODE_OK = 1,
- CMD_CODE_BAD = 2,
-};
-
-enum {
- STATUS_PRINTING = 1,
- STATUS_IDLE = 2,
-};
-
-enum {
- STATE_STATUS1_STANDBY = 1,
- STATE_STATUS1_ERROR = 2,
- STATE_STATUS1_WAIT = 3,
-};
-
-#define STATE_STANDBY_STATUS2 0x0
-
-enum {
- WAIT_STATUS2_INIT = 0,
- WAIT_STATUS2_RIBBON = 1,
- WAIT_STATUS2_THERMAL = 2,
- WAIT_STATUS2_OPERATING = 3,
- WAIT_STATUS2_BUSY = 4,
-};
-
-
-#define ERROR_STATUS2_CTRL_CIRCUIT (0x80000000)
-#define ERROR_STATUS2_MECHANISM_CTRL (0x40000000)
-#define ERROR_STATUS2_SENSOR (0x00002000)
-#define ERROR_STATUS2_COVER_OPEN (0x00001000)
-#define ERROR_STATUS2_TEMP_SENSOR (0x00000200)
-#define ERROR_STATUS2_PAPER_JAM (0x00000100)
-#define ERROR_STATUS2_PAPER_EMPTY (0x00000040)
-#define ERROR_STATUS2_RIBBON_ERR (0x00000010)
-
-enum {
- CTRL_CIR_ERROR_EEPROM1 = 0x01,
- CTRL_CIR_ERROR_EEPROM2 = 0x02,
- CTRL_CIR_ERROR_DSP = 0x04,
- CTRL_CIR_ERROR_CRC_MAIN = 0x06,
- CTRL_CIR_ERROR_DL_MAIN = 0x07,
- CTRL_CIR_ERROR_CRC_DSP = 0x08,
- CTRL_CIR_ERROR_DL_DSP = 0x09,
- CTRL_CIR_ERROR_ASIC = 0x0a,
- CTRL_CIR_ERROR_DRAM = 0x0b,
- CTRL_CIR_ERROR_DSPCOMM = 0x29,
-};
-
-enum {
- MECH_ERROR_HEAD_UP = 0x01,
- MECH_ERROR_HEAD_DOWN = 0x02,
- MECH_ERROR_MAIN_PINCH_UP = 0x03,
- MECH_ERROR_MAIN_PINCH_DOWN = 0x04,
- MECH_ERROR_SUB_PINCH_UP = 0x05,
- MECH_ERROR_SUB_PINCH_DOWN = 0x06,
- MECH_ERROR_FEEDIN_PINCH_UP = 0x07,
- MECH_ERROR_FEEDIN_PINCH_DOWN = 0x08,
- MECH_ERROR_FEEDOUT_PINCH_UP = 0x09,
- MECH_ERROR_FEEDOUT_PINCH_DOWN = 0x0a,
- MECH_ERROR_CUTTER_LR = 0x0b,
- MECH_ERROR_CUTTER_RL = 0x0c,
-};
-
-enum {
- SENSOR_ERROR_CUTTER = 0x05,
- SENSOR_ERROR_HEAD_DOWN = 0x09,
- SENSOR_ERROR_HEAD_UP = 0x0a,
- SENSOR_ERROR_MAIN_PINCH_DOWN = 0x0b,
- SENSOR_ERROR_MAIN_PINCH_UP = 0x0c,
- SENSOR_ERROR_FEED_PINCH_DOWN = 0x0d,
- SENSOR_ERROR_FEED_PINCH_UP = 0x0e,
- SENSOR_ERROR_EXIT_PINCH_DOWN = 0x0f,
- SENSOR_ERROR_EXIT_PINCH_UP = 0x10,
- SENSOR_ERROR_LEFT_CUTTER = 0x11,
- SENSOR_ERROR_RIGHT_CUTTER = 0x12,
- SENSOR_ERROR_CENTER_CUTTER = 0x13,
- SENSOR_ERROR_UPPER_CUTTER = 0x14,
- SENSOR_ERROR_PAPER_FEED_COVER = 0x15,
-};
-
-enum {
- TEMP_SENSOR_ERROR_HEAD_HIGH = 0x01,
- TEMP_SENSOR_ERROR_HEAD_LOW = 0x02,
- TEMP_SENSOR_ERROR_ENV_HIGH = 0x03,
- TEMP_SENSOR_ERROR_ENV_LOW = 0x04,
-};
-
-enum {
- COVER_OPEN_ERROR_UPPER = 0x01,
- COVER_OPEN_ERROR_LOWER = 0x02,
-};
-
-enum {
- PAPER_EMPTY_ERROR = 0x00,
-};
-
-enum {
- RIBBON_ERROR = 0x00,
-};
-
-enum {
- CURVE_TABLE_STATUS_INITIAL = 0x00,
- CURVE_TABLE_STATUS_USERSET = 0x01,
- CURVE_TABLE_STATUS_CURRENT = 0x02,
-};
-
/* Query media info */
struct shinkos1245_cmd_getmedia {
struct shinkos1245_cmd_hdr hdr;
@@ -280,28 +134,15 @@ struct shinkos1245_cmd_getmedia {
uint8_t pad[10];
} __attribute__((packed));
-struct shinkos1245_mediadesc {
- uint8_t code; /* Fixed at 0x10 */
- uint16_t columns; /* BE */
- uint16_t rows; /* BE */
- uint8_t type; /* MEDIA_TYPE_* */
- uint8_t print_type; /* aka "print method" in the spool file */
- uint8_t reserved[3];
-} __attribute__((packed));
-
#define NUM_MEDIAS 5 /* Maximum per message */
struct shinkos1245_resp_media {
uint8_t code;
uint8_t reserved[6];
uint8_t count; /* 1-5? */
- struct shinkos1245_mediadesc data[NUM_MEDIAS];
+ struct sinfonia_mediainfo_item data[NUM_MEDIAS];
} __attribute__((packed));
-enum {
- MEDIA_TYPE_UNKNOWN = 0x00,
- MEDIA_TYPE_PAPER = 0x01,
-};
enum {
PRINT_TYPE_STANDARD = 0x00,
@@ -359,7 +200,6 @@ enum {
PARAM_TABLE_FINE = 2,
};
-#define TONE_CURVE_SIZE 1536
#define TONE_CURVE_DATA_BLOCK_SIZE 64
/* Query Model information */
@@ -400,15 +240,9 @@ struct shinkos1245_resp_matte {
} __attribute__((packed));
#define MATTE_MODE_MATTE 0x00
+#define MAX_MEDIA_ITEMS 15
/* Private data structure */
-struct shinkos1245_printjob {
- uint8_t *databuf;
- int datalen;
-
- int copies;
-};
-
struct shinkos1245_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
@@ -417,9 +251,7 @@ struct shinkos1245_ctx {
uint8_t jobid;
- struct s1245_printjob_hdr hdr;
-
- struct shinkos1245_mediadesc medias[15];
+ struct sinfonia_mediainfo_item medias[MAX_MEDIA_ITEMS];
int num_medias;
int media_8x12;
@@ -493,6 +325,9 @@ static int shinkos1245_get_status(struct shinkos1245_ctx *ctx,
return -99;
}
+ /* Byteswap important stuff */
+ resp->state.status2 = be32_to_cpu(resp->state.status2);
+
return 0;
}
@@ -527,7 +362,7 @@ static int shinkos1245_get_media(struct shinkos1245_ctx *ctx)
ctx->medias[ctx->num_medias].columns = be16_to_cpu(resp.data[j].columns);
ctx->medias[ctx->num_medias].rows = be16_to_cpu(resp.data[j].rows);
ctx->medias[ctx->num_medias].type = resp.data[j].type;
- ctx->medias[ctx->num_medias].print_type = resp.data[j].print_type;
+ ctx->medias[ctx->num_medias].method = resp.data[j].method;
ctx->num_medias++;
if (ctx->medias[i].rows >= 3636)
@@ -697,153 +532,6 @@ static int shinkos1245_get_matte(struct shinkos1245_ctx *ctx,
return 0;
}
-
-/* Structure dumps */
-static char *shinkos1245_status_str(struct shinkos1245_resp_status *resp)
-{
- switch(resp->state.status1) {
- case STATE_STATUS1_STANDBY:
- return "Standby (Ready)";
- case STATE_STATUS1_WAIT:
- switch (resp->state.status2) {
- case WAIT_STATUS2_INIT:
- return "Wait (Initializing)";
- case WAIT_STATUS2_RIBBON:
- return "Wait (Ribbon Winding)";
- case WAIT_STATUS2_THERMAL:
- return "Wait (Thermal Protection)";
- case WAIT_STATUS2_OPERATING:
- return "Wait (Operating)";
- case WAIT_STATUS2_BUSY:
- return "Wait (Busy)";
- default:
- return "Wait (Unknown)";
- }
- case STATE_STATUS1_ERROR:
- switch (resp->state.status2) {
- case ERROR_STATUS2_CTRL_CIRCUIT:
- switch (resp->state.error) {
- case CTRL_CIR_ERROR_EEPROM1:
- return "Error (EEPROM1)";
- case CTRL_CIR_ERROR_EEPROM2:
- return "Error (EEPROM2)";
- case CTRL_CIR_ERROR_DSP:
- return "Error (DSP)";
- case CTRL_CIR_ERROR_CRC_MAIN:
- return "Error (Main CRC)";
- case CTRL_CIR_ERROR_DL_MAIN:
- return "Error (Main Download)";
- case CTRL_CIR_ERROR_CRC_DSP:
- return "Error (DSP CRC)";
- case CTRL_CIR_ERROR_DL_DSP:
- return "Error (DSP Download)";
- case CTRL_CIR_ERROR_ASIC:
- return "Error (ASIC)";
- case CTRL_CIR_ERROR_DRAM:
- return "Error (DRAM)";
- case CTRL_CIR_ERROR_DSPCOMM:
- return "Error (DSP Communincation)";
- default:
- return "Error (Unknown Circuit)";
- }
- case ERROR_STATUS2_MECHANISM_CTRL:
- switch (resp->state.error) {
- case MECH_ERROR_HEAD_UP:
- return "Error (Head Up Mechanism)";
- case MECH_ERROR_HEAD_DOWN:
- return "Error (Head Down Mechanism)";
- case MECH_ERROR_MAIN_PINCH_UP:
- return "Error (Main Pinch Up Mechanism)";
- case MECH_ERROR_MAIN_PINCH_DOWN:
- return "Error (Main Pinch Down Mechanism)";
- case MECH_ERROR_SUB_PINCH_UP:
- return "Error (Sub Pinch Up Mechanism)";
- case MECH_ERROR_SUB_PINCH_DOWN:
- return "Error (Sub Pinch Down Mechanism)";
- case MECH_ERROR_FEEDIN_PINCH_UP:
- return "Error (Feed-in Pinch Up Mechanism)";
- case MECH_ERROR_FEEDIN_PINCH_DOWN:
- return "Error (Feed-in Pinch Down Mechanism)";
- case MECH_ERROR_FEEDOUT_PINCH_UP:
- return "Error (Feed-out Pinch Up Mechanism)";
- case MECH_ERROR_FEEDOUT_PINCH_DOWN:
- return "Error (Feed-out Pinch Down Mechanism)";
- case MECH_ERROR_CUTTER_LR:
- return "Error (Left->Right Cutter)";
- case MECH_ERROR_CUTTER_RL:
- return "Error (Right->Left Cutter)";
- default:
- return "Error (Unknown Mechanism)";
- }
- case ERROR_STATUS2_SENSOR:
- switch (resp->state.error) {
- case SENSOR_ERROR_CUTTER:
- return "Error (Cutter Sensor)";
- case SENSOR_ERROR_HEAD_DOWN:
- return "Error (Head Down Sensor)";
- case SENSOR_ERROR_HEAD_UP:
- return "Error (Head Up Sensor)";
- case SENSOR_ERROR_MAIN_PINCH_DOWN:
- return "Error (Main Pinch Down Sensor)";
- case SENSOR_ERROR_MAIN_PINCH_UP:
- return "Error (Main Pinch Up Sensor)";
- case SENSOR_ERROR_FEED_PINCH_DOWN:
- return "Error (Feed Pinch Down Sensor)";
- case SENSOR_ERROR_FEED_PINCH_UP:
- return "Error (Feed Pinch Up Sensor)";
- case SENSOR_ERROR_EXIT_PINCH_DOWN:
- return "Error (Exit Pinch Up Sensor)";
- case SENSOR_ERROR_EXIT_PINCH_UP:
- return "Error (Exit Pinch Up Sensor)";
- case SENSOR_ERROR_LEFT_CUTTER:
- return "Error (Left Cutter Sensor)";
- case SENSOR_ERROR_RIGHT_CUTTER:
- return "Error (Right Cutter Sensor)";
- case SENSOR_ERROR_CENTER_CUTTER:
- return "Error (Center Cutter Sensor)";
- case SENSOR_ERROR_UPPER_CUTTER:
- return "Error (Upper Cutter Sensor)";
- case SENSOR_ERROR_PAPER_FEED_COVER:
- return "Error (Paper Feed Cover)";
- default:
- return "Error (Unknown Sensor)";
- }
- case ERROR_STATUS2_COVER_OPEN:
- switch (resp->state.error) {
- case COVER_OPEN_ERROR_UPPER:
- return "Error (Upper Cover Open)";
- case COVER_OPEN_ERROR_LOWER:
- return "Error (Lower Cover Open)";
- default:
- return "Error (Unknown Cover Open)";
- }
- case ERROR_STATUS2_TEMP_SENSOR:
- switch (resp->state.error) {
- case TEMP_SENSOR_ERROR_HEAD_HIGH:
- return "Error (Head Temperature High)";
- case TEMP_SENSOR_ERROR_HEAD_LOW:
- return "Error (Head Temperature Low)";
- case TEMP_SENSOR_ERROR_ENV_HIGH:
- return "Error (Environmental Temperature High)";
- case TEMP_SENSOR_ERROR_ENV_LOW:
- return "Error (Environmental Temperature Low)";
- default:
- return "Error (Unknown Temperature)";
- }
- case ERROR_STATUS2_PAPER_JAM:
- return "Error (Paper Jam)";
- case ERROR_STATUS2_PAPER_EMPTY:
- return "Error (Paper Empty)";
- case ERROR_STATUS2_RIBBON_ERR:
- return "Error (Ribbon)";
- default:
- return "Error (Unknown)";
- }
- default:
- return "Unknown!";
- }
-}
-
static char* shinkos1245_tonecurves(int type, int table)
{
switch (type) {
@@ -897,10 +585,8 @@ static void shinkos1245_dump_status(struct shinkos1245_ctx *ctx,
INFO("Printer Status: %s\n", detail);
/* Byteswap */
- sts->state.status2 = be32_to_cpu(sts->state.status2);
-
INFO("Printer State: %s # %02x %08x %02x\n",
- shinkos1245_status_str(sts),
+ sinfonia_1x45_status_str(sts->state.status1, sts->state.status2, sts->state.error),
sts->state.status1, sts->state.status2, sts->state.error);
INFO("Counters:\n");
INFO("\tLifetime : %u\n", be32_to_cpu(sts->counters.lifetime));
@@ -944,7 +630,7 @@ static void shinkos1245_dump_status(struct shinkos1245_ctx *ctx,
INFO("Tone Curve Status: %s\n", detail);
}
-static void shinkos1245_dump_media(struct shinkos1245_mediadesc *medias,
+static void shinkos1245_dump_media(struct sinfonia_mediainfo_item *medias,
int media_8x12,
int count)
{
@@ -954,11 +640,12 @@ 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: %04u*%04u (%02x/%02u)\n",
- medias[i].print_type,
+ INFO("\t %02d: %04u*%04u (%02x/%02u)\n",
+ i,
medias[i].columns,
medias[i].rows,
- medias[i].type, medias[i].print_type);
+ medias[i].type,
+ medias[i].method);
}
}
@@ -1091,21 +778,11 @@ static int set_tonecurve(struct shinkos1245_ctx *ctx, int type, int table, char
}
ptr = data;
- /* Open file and read it in */
- {
- int tc_fd = open(fname, O_RDONLY);
- if (tc_fd < 0) {
- ret = tc_fd;
- goto done;
- }
-
- ret = read(tc_fd, data, TONE_CURVE_SIZE);
- if (ret < 0) {
- close(tc_fd);
- goto done;
- }
- close(tc_fd);
+ /* Read in file */
+ if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE, NULL))) {
+ ERROR("Failed to read Tone Curve file\n");
+ goto done;
}
/* Issue a tone_write_start */
@@ -1321,31 +998,11 @@ static int shinkos1245_attach(void *vctx, struct libusb_device_handle *dev, int
return CUPS_BACKEND_OK;
}
-static void shinkos1245_cleanup_job(const void *vjob)
-{
- const struct shinkos1245_printjob *job = vjob;
-
- if (job->databuf)
- free(job->databuf);
-
- free((void*)job);
-}
-
-static void shinkos1245_teardown(void *vctx) {
- struct shinkos1245_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int shinkos1245_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct shinkos1245_ctx *ctx = vctx;
int ret;
- uint8_t tmpbuf[4];
- struct shinkos1245_printjob *job = NULL;
+ struct sinfonia_printjob *job = NULL;
if (!ctx)
return CUPS_BACKEND_FAILED;
@@ -1356,88 +1013,18 @@ static int shinkos1245_read_parse(void *vctx, const void **vjob, int data_fd, in
return CUPS_BACKEND_RETRY_CURRENT;
}
memset(job, 0, sizeof(*job));
- job->copies = copies;
- /* Read in then validate header */
- ret = read(data_fd, &ctx->hdr, sizeof(ctx->hdr));
- if (ret < 0) {
- shinkos1245_cleanup_job(job);
+ /* Common read/parse code */
+ ret = sinfonia_read_parse(data_fd, 1245, job);
+ if (ret) {
+ free(job);
return ret;
}
- if (ret != sizeof(ctx->hdr)) {
- shinkos1245_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
- }
-
- if (le32_to_cpu(ctx->hdr.len1) != 0x10 ||
- le32_to_cpu(ctx->hdr.len2) != 0x64 ||
- le32_to_cpu(ctx->hdr.dpi) != 300) {
- ERROR("Unrecognized header data format!\n");
- shinkos1245_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
- }
-
- ctx->hdr.model = le32_to_cpu(ctx->hdr.model);
- if(ctx->hdr.model != 1245) {
- ERROR("Unrecognized printer (%u)!\n", ctx->hdr.model);
- shinkos1245_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
- }
-
- /* Finish byteswapping */
- ctx->hdr.media = le32_to_cpu(ctx->hdr.media);
- ctx->hdr.method = le32_to_cpu(ctx->hdr.method);
- ctx->hdr.mode = le32_to_cpu(ctx->hdr.mode);
- ctx->hdr.mattedepth = le32_to_cpu(ctx->hdr.mattedepth);
- ctx->hdr.dust = le32_to_cpu(ctx->hdr.dust);
- ctx->hdr.columns = le32_to_cpu(ctx->hdr.columns);
- ctx->hdr.rows = le32_to_cpu(ctx->hdr.rows);
- ctx->hdr.copies = le32_to_cpu(ctx->hdr.copies);
-
- /* Allocate space */
- job->datalen = ctx->hdr.rows * ctx->hdr.columns * 3;
- job->databuf = malloc(job->datalen);
- if (!job->databuf) {
- ERROR("Memory allocation failure!\n");
- shinkos1245_cleanup_job(job);
- return CUPS_BACKEND_RETRY_CURRENT;
- }
-
- {
- int remain = job->datalen;
- uint8_t *ptr = job->databuf;
- do {
- ret = read(data_fd, ptr, remain);
- if (ret < 0) {
- ERROR("Read failed (%d/%d/%d)\n",
- ret, remain, job->datalen);
- perror("ERROR: Read failed");
- shinkos1245_cleanup_job(job);
- return ret;
- }
- ptr += ret;
- remain -= ret;
- } while (remain);
- }
-
- /* Make sure footer is sane too */
- ret = read(data_fd, tmpbuf, 4);
- if (ret != 4) {
- ERROR("Read failed (%d/%d/%d)\n",
- ret, 4, 4);
- perror("ERROR: Read failed");
- shinkos1245_cleanup_job(job);
- return ret;
- }
- if (tmpbuf[0] != 0x04 ||
- tmpbuf[1] != 0x03 ||
- tmpbuf[2] != 0x02 ||
- tmpbuf[3] != 0x01) {
- ERROR("Unrecognized footer data format!\n");
- shinkos1245_cleanup_job(job);
- return CUPS_BACKEND_FAILED;
- }
+ if (job->jp.copies > 1)
+ job->copies = job->jp.copies;
+ else
+ job->copies = copies;
*vjob = job;
return CUPS_BACKEND_OK;
@@ -1447,8 +1034,9 @@ static int shinkos1245_main_loop(void *vctx, const void *vjob) {
struct shinkos1245_ctx *ctx = vctx;
int i, num, last_state = -1, state = S_IDLE;
struct shinkos1245_resp_status status1, status2;
+ int copies;
- const struct shinkos1245_printjob *job = vjob;
+ const struct sinfonia_printjob *job = vjob;
if (!ctx)
return CUPS_BACKEND_FAILED;
@@ -1459,10 +1047,10 @@ static int shinkos1245_main_loop(void *vctx, const void *vjob) {
/* Make sure print size is supported */
for (i = 0 ; i < ctx->num_medias ; i++) {
- if (ctx->hdr.media == ctx->medias[i].code &&
- ctx->hdr.method == ctx->medias[i].print_type &&
- ctx->hdr.rows == ctx->medias[i].rows &&
- ctx->hdr.columns == ctx->medias[i].columns)
+ if (job->jp.media == ctx->medias[i].code &&
+ job->jp.method == ctx->medias[i].method &&
+ job->jp.rows == ctx->medias[i].rows &&
+ job->jp.columns == ctx->medias[i].columns)
break;
}
if (i == ctx->num_medias) {
@@ -1508,14 +1096,10 @@ top:
break;
}
- if (status1.print_status == STATUS_IDLE) {
- state = S_PRINTER_READY_CMD;
- break;
- }
#if 0 // XXX is this necessary
if (status1.state.status1 == STATE_STATUS1_WAIT) {
INFO("Printer busy: %s\n",
- shinkos1245_status_str(&status1));
+ sinfonia_1x45_status_str(status1.state.status1, status1.state.status2, status1.state.error));
break;
}
#endif
@@ -1542,15 +1126,15 @@ top:
struct shinkos1245_cmd_print cmd;
/* Set matte intensity */
- if (ctx->hdr.mattedepth != 0x7fffffff) {
+ if (job->jp.mattedepth != 0x7fffffff) {
int current = -1;
i = shinkos1245_get_matte(ctx, &current);
if (i < 0)
- goto printer_error;
- if (current != ctx->hdr.mattedepth) {
- i = shinkos1245_set_matte(ctx, ctx->hdr.mattedepth);
+ goto printer_error2;
+ if (current != job->jp.mattedepth) {
+ i = shinkos1245_set_matte(ctx, job->jp.mattedepth);
if (i < 0)
- goto printer_error;
+ goto printer_error2;
if (i > 0) {
INFO("Can't set matte intensity when printing in progress...\n");
state = S_IDLE;
@@ -1567,17 +1151,18 @@ top:
cmd.cmd[1] = 0x00;
cmd.id = ctx->jobid;
- cmd.count = cpu_to_be16(uint16_to_packed_bcd(copies));
- cmd.columns = cpu_to_be16(ctx->hdr.columns);
- cmd.rows = cpu_to_be16(ctx->hdr.rows);
- cmd.media = ctx->hdr.media;
- cmd.mode = (ctx->hdr.mode & 0x3f) || ((ctx->hdr.dust & 0x3) << 6);
- cmd.combo = ctx->hdr.method;
+ cmd.count = uint16_to_packed_bcd(copies);
+ cmd.columns = cpu_to_be16(job->jp.columns);
+ cmd.rows = cpu_to_be16(job->jp.rows);
+ cmd.media = job->jp.media;
+ cmd.mode = (job->jp.oc_mode & 0x3f) || ((job->jp.dust & 0x3) << 6);
+ cmd.combo = job->jp.method;
/* Issue print command */
i = shinkos1245_do_cmd(ctx, &cmd, sizeof(cmd),
&status1, sizeof(status1),
&num);
+ status1.state.status2 = be32_to_cpu(status1.state.status2);
if (i < 0)
goto printer_error;
@@ -1628,13 +1213,10 @@ top:
return CUPS_BACKEND_OK;
printer_error:
- /* Byteswap */
- status1.state.status2 = be32_to_cpu(status1.state.status2);
-
ERROR("Printer Error: %s # %02x %08x %02x\n",
- shinkos1245_status_str(&status1),
+ sinfonia_1x45_status_str(status1.state.status1, status1.state.status2, status1.state.error),
status1.state.status1, status1.state.status2, status1.state.error);
-
+printer_error2:
return CUPS_BACKEND_FAILED;
}
@@ -1698,14 +1280,13 @@ static const char *shinkos1245_prefixes[] = {
struct dyesub_backend shinkos1245_backend = {
.name = "Shinko/Sinfonia CHC-S1245/E1",
- .version = "0.26",
+ .version = "0.31" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = shinkos1245_prefixes,
.cmdline_usage = shinkos1245_cmdline,
.cmdline_arg = shinkos1245_cmdline_arg,
.init = shinkos1245_init,
.attach = shinkos1245_attach,
- .teardown = shinkos1245_teardown,
- .cleanup_job = shinkos1245_cleanup_job,
+ .cleanup_job = sinfonia_cleanup_job,
.read_parse = shinkos1245_read_parse,
.main_loop = shinkos1245_main_loop,
.query_serno = shinkos1245_query_serno,
diff --git a/src/cups/backend_shinkos2145.c b/src/cups/backend_shinkos2145.c
index 749b59a..bc0df33 100644
--- a/src/cups/backend_shinkos2145.c
+++ b/src/cups/backend_shinkos2145.c
@@ -1,7 +1,7 @@
-/*
+ /*
* Shinko/Sinfonia CHC-S2145 CUPS backend -- libusb-1.0 version
*
- * (c) 2013-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2013-2019 Solomon Peachy <pizza@shaftnet.org>
*
* Development of this backend was sponsored by:
*
@@ -43,6 +43,7 @@
#define BACKEND shinkos2145_backend
#include "backend_common.h"
+#include "backend_sinfonia.h"
enum {
S_IDLE = 0,
@@ -51,156 +52,25 @@ enum {
S_FINISHED,
};
-/* Structure of printjob header. All fields are LITTLE ENDIAN */
-struct s2145_printjob_hdr {
- uint32_t len1; /* Fixed at 0x10 */
- uint32_t model; /* Equal to the printer model (eg '2145' or '1245' decimal) */
- uint32_t unk2;
- uint32_t unk3; /* Fixed at 0x01 */
-
- uint32_t len2; /* Fixed at 0x64 */
- uint32_t unk5;
- uint32_t media;
- uint32_t unk6;
-
- uint32_t method;
- uint32_t mode;
- uint32_t unk7;
- uint32_t unk8;
-
- uint32_t unk9;
- uint32_t columns;
- uint32_t rows;
- uint32_t copies;
-
- uint32_t unk10;
- uint32_t unk11;
- uint32_t unk12;
- uint32_t unk13;
-
- uint32_t unk14;
- uint32_t unk15;
- uint32_t dpi; /* Fixed at '300' (decimal) */
- uint32_t unk16;
-
- uint32_t unk17;
- uint32_t unk18;
- uint32_t unk19;
- uint32_t unk20;
-
- uint32_t unk21;
-} __attribute__((packed));
-
/* Structs for printer */
-struct s2145_cmd_hdr {
- uint16_t cmd;
- uint16_t len; /* Not including this header */
-} __attribute__((packed));
-
-#define S2145_CMD_STATUS 0x0001
-#define S2145_CMD_MEDIAINFO 0x0002
-#define S2145_CMD_MODELNAME 0x0003
-#define S2145_CMD_ERRORLOG 0x0004
-#define S2145_CMD_PRINTJOB 0x4001
-#define S2145_CMD_CANCELJOB 0x4002
-#define S2145_CMD_FLASHLED 0x4003
-#define S2145_CMD_RESET 0x4004
-#define S2145_CMD_READTONE 0x4005
-#define S2145_CMD_BUTTON 0x4006
-#define S2145_CMD_GETUNIQUE 0x8003
-#define S2145_CMD_FWINFO 0xC003
-#define S2145_CMD_UPDATE 0xC004
-#define S2145_CMD_SETUNIQUE 0xC007
-
-static char *cmd_names(uint16_t v) {
- switch (le16_to_cpu(v)) {
- case S2145_CMD_STATUS:
- return "Get Status";
- case S2145_CMD_MEDIAINFO:
- return "Get Media Info";
- case S2145_CMD_MODELNAME:
- return "Get Model Name";
- case S2145_CMD_ERRORLOG:
- return "Get Error Log";
- case S2145_CMD_PRINTJOB:
- return "Print";
- case S2145_CMD_CANCELJOB:
- return "Cancel Print";
- case S2145_CMD_FLASHLED:
- return "Flash LEDs";
- case S2145_CMD_RESET:
- return "Reset";
- case S2145_CMD_READTONE:
- return "Read Tone Curve";
- case S2145_CMD_BUTTON:
- return "Button Enable";
- case S2145_CMD_GETUNIQUE:
- return "Get Unique String";
- case S2145_CMD_FWINFO:
- return "Get Firmware Info";
- case S2145_CMD_UPDATE:
- return "Update";
- case S2145_CMD_SETUNIQUE:
- return "Set Unique String";
- default:
- return "Unknown Command";
- }
-}
-
-struct s2145_print_cmd {
- struct s2145_cmd_hdr hdr;
- uint8_t id;
- uint16_t count;
- uint16_t columns;
- uint16_t rows;
- uint8_t media;
- uint8_t mode;
- uint8_t method;
-} __attribute__((packed));
-
-#define PRINT_MEDIA_4x6 0x00
-#define PRINT_MEDIA_5x3_5 0x01
-#define PRINT_MEDIA_5x7 0x03
-#define PRINT_MEDIA_6x9 0x05
-#define PRINT_MEDIA_6x8 0x06
-#define PRINT_MEDIA_2x6 0x07
-
-static char *print_sizes (uint8_t v) {
- switch (v) {
- case PRINT_MEDIA_4x6:
- return "4x6";
- case PRINT_MEDIA_5x3_5:
- return "5x3.5";
- case PRINT_MEDIA_5x7:
- return "5x7";
- case PRINT_MEDIA_6x9:
- return "6x9";
- case PRINT_MEDIA_6x8:
- return "6x8";
- case PRINT_MEDIA_2x6:
- return "2x6";
- default:
- return "Unknown";
- }
-}
-
static int print_counts (uint8_t v) {
switch (v) {
- case PRINT_MEDIA_4x6:
+ case CODE_4x6:
return 700;
- case PRINT_MEDIA_5x3_5:
+ case CODE_3_5x5:
return 800;
- case PRINT_MEDIA_5x7:
+ case CODE_5x7:
return 400;
- case PRINT_MEDIA_6x9:
+ case CODE_6x9:
return 310;
- case PRINT_MEDIA_6x8:
+ case CODE_6x8:
return 350;
default:
return 700;
}
}
+#if 0
#define PRINT_MODE_DEFAULT 0x01
#define PRINT_MODE_STD_GLOSSY 0x02
#define PRINT_MODE_FINE_GLOSSY 0x03
@@ -209,8 +79,7 @@ static int print_counts (uint8_t v) {
#define PRINT_MODE_STD_EGLOSSY 0x06
#define PRINT_MODE_FINE_EGLOSSY 0x07
-#if 0
-static char *print_modes(uint8_t v) {
+static char *s2145_print_modes(uint8_t v) {
switch (v) {
case PRINT_MODE_DEFAULT:
return "Default";
@@ -232,30 +101,8 @@ static char *print_modes(uint8_t v) {
}
#endif
-#define PRINT_METHOD_STD 0x00
-#define PRINT_METHOD_4x6_2UP 0x02
-#define PRINT_METHOD_2x6_2UP 0x04
-
-static char *print_methods (uint8_t v) {
- switch (v) {
- case PRINT_METHOD_STD:
- return "Standard";
- case PRINT_METHOD_4x6_2UP:
- return "4x6 2up";
- case PRINT_METHOD_2x6_2UP:
- return "2x6 2up";
- default:
- return "Unknown";
- }
-}
-
-struct s2145_cancel_cmd {
- struct s2145_cmd_hdr hdr;
- uint8_t id;
-} __attribute__((packed));
-
struct s2145_reset_cmd {
- struct s2145_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint8_t target;
} __attribute__((packed));
@@ -263,23 +110,18 @@ struct s2145_reset_cmd {
#define RESET_USER_CURVE 0x04
struct s2145_readtone_cmd {
- struct s2145_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint8_t curveid;
} __attribute__((packed));
struct s2145_button_cmd {
- struct s2145_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint8_t enabled;
} __attribute__((packed));
#define BUTTON_ENABLED 0x01
#define BUTTON_DISABLED 0x00
-struct s2145_fwinfo_cmd {
- struct s2145_cmd_hdr hdr;
- uint8_t target;
-} __attribute__((packed));
-
#define FWINFO_TARGET_MAIN_BOOT 0x01
#define FWINFO_TARGET_MAIN_APP 0x02
#define FWINFO_TARGET_DSP_BOOT 0x03
@@ -310,61 +152,19 @@ static char *fwinfo_targets (uint8_t v) {
}
struct s2145_update_cmd {
- struct s2145_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint32_t reserved;
uint32_t size;
} __attribute__((packed));
-#define UPDATE_TARGET_USER 0x03
-#define UPDATE_TARGET_CURRENT 0x04
-
-static char *update_targets (uint8_t v) {
- switch (v) {
- case UPDATE_TARGET_USER:
- return "User";
- case UPDATE_TARGET_CURRENT:
- return "Current";
- default:
- return "Unknown";
- }
-}
-
-#define UPDATE_SIZE 0x600
-/* Update is three channels, Y, M, C;
- each is 256 entries of 11-bit data padded to 16-bits.
- Printer expects LE data. We use BE data on disk.
-*/
-
struct s2145_setunique_cmd {
- struct s2145_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint8_t len;
uint8_t data[23]; /* Not necessarily all used. */
} __attribute__((packed));
-struct s2145_status_hdr {
- uint8_t result;
- uint8_t error;
- uint8_t printer_major;
- uint8_t printer_minor;
- uint8_t reserved[3];
- uint8_t status;
- uint16_t payload_len;
-} __attribute__((packed));
-
-#define RESULT_SUCCESS 0x01
-#define RESULT_FAIL 0x02
-
-#define ERROR_NONE 0x00
-#define ERROR_INVALID_PARAM 0x01
-#define ERROR_MAIN_APP_INACTIVE 0x02
-#define ERROR_COMMS_TIMEOUT 0x03
-#define ERROR_MAINT_NEEDED 0x04
-#define ERROR_BAD_COMMAND 0x05
-#define ERROR_PRINTER 0x11
-#define ERROR_BUFFER_FULL 0x21
-
-static char *error_codes(uint8_t major, uint8_t minor)
+static const char *error_codes(uint8_t major, uint8_t minor)
{
switch(major) {
case 0x01: /* "Controller Error" */
@@ -562,105 +362,8 @@ static char *error_codes(uint8_t major, uint8_t minor)
}
}
-static char *error_str(uint8_t v) {
- switch (v) {
- case ERROR_NONE:
- return "None";
- case ERROR_INVALID_PARAM:
- return "Invalid Command Parameter";
- case ERROR_MAIN_APP_INACTIVE:
- return "Main App Inactive";
- case ERROR_COMMS_TIMEOUT:
- return "Main Communication Timeout";
- case ERROR_MAINT_NEEDED:
- return "Maintenance Needed";
- case ERROR_BAD_COMMAND:
- return "Inappropriate Command";
- case ERROR_PRINTER:
- return "Printer Error";
- case ERROR_BUFFER_FULL:
- return "Buffer Full";
- default:
- return "Unknown";
- }
-}
-
-#define STATUS_READY 0x00
-#define STATUS_INIT_CPU 0x31
-#define STATUS_INIT_RIBBON 0x32
-#define STATUS_INIT_PAPER 0x33
-#define STATUS_THERMAL_PROTECT 0x34
-#define STATUS_USING_PANEL 0x35
-#define STATUS_SELF_DIAG 0x36
-#define STATUS_DOWNLOADING 0x37
-
-#define STATUS_FEEDING_PAPER 0x61
-#define STATUS_PRE_HEAT 0x62
-#define STATUS_PRINT_Y 0x63
-#define STATUS_BACK_FEED_Y 0x64
-#define STATUS_PRINT_M 0x65
-#define STATUS_BACK_FEED_M 0x66
-#define STATUS_PRINT_C 0x67
-#define STATUS_BACK_FEED_C 0x68
-#define STATUS_PRINT_OP 0x69
-#define STATUS_PAPER_CUT 0x6A
-#define STATUS_PAPER_EJECT 0x6B
-#define STATUS_BACK_FEED_E 0x6C
-#define STATUS_FINISHED 0x6D
-
-static char *status_str(uint8_t v) {
- switch (v) {
- case STATUS_READY:
- return "Ready";
- case STATUS_INIT_CPU:
- return "Initializing CPU";
- case STATUS_INIT_RIBBON:
- return "Initializing Ribbon";
- case STATUS_INIT_PAPER:
- return "Loading Paper";
- case STATUS_THERMAL_PROTECT:
- return "Thermal Protection";
- case STATUS_USING_PANEL:
- return "Using Operation Panel";
- case STATUS_SELF_DIAG:
- return "Processing Self Diagnosis";
- case STATUS_DOWNLOADING:
- return "Processing Download";
- case STATUS_FEEDING_PAPER:
- return "Feeding Paper";
- case STATUS_PRE_HEAT:
- return "Pre-Heating";
- case STATUS_PRINT_Y:
- return "Printing Yellow";
- case STATUS_BACK_FEED_Y:
- return "Back-Feeding - Yellow Complete";
- case STATUS_PRINT_M:
- return "Printing Magenta";
- case STATUS_BACK_FEED_M:
- return "Back-Feeding - Magenta Complete";
- case STATUS_PRINT_C:
- return "Printing Cyan";
- case STATUS_BACK_FEED_C:
- return "Back-Feeding - Cyan Complete";
- case STATUS_PRINT_OP:
- return "Laminating";
- case STATUS_PAPER_CUT:
- return "Cutting Paper";
- case STATUS_PAPER_EJECT:
- return "Ejecting Paper";
- case STATUS_BACK_FEED_E:
- return "Back-Feeding - Ejected";
- case STATUS_FINISHED:
- return "Print Finished";
- case ERROR_PRINTER:
- return "Printer Error";
- default:
- return "Unknown";
- }
-}
-
struct s2145_status_resp {
- struct s2145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint32_t count_lifetime;
uint32_t count_maint;
uint32_t count_paper;
@@ -680,240 +383,104 @@ struct s2145_status_resp {
uint8_t tonecurve_status;
} __attribute__((packed));
-#define BANK_STATUS_FREE 0x00
-#define BANK_STATUS_XFER 0x01
-#define BANK_STATUS_FULL 0x02
-
-static char *bank_statuses(uint8_t v)
-{
- switch (v) {
- case BANK_STATUS_FREE:
- return "Free";
- case BANK_STATUS_XFER:
- return "Xfer";
- case BANK_STATUS_FULL:
- return "Full";
- default:
- return "Unknown";
- }
-}
-
-#define TONECURVE_INIT 0x00
-#define TONECURVE_USER 0x01
-#define TONECURVE_CURRENT 0x02
-
-static char *tonecurve_statuses (uint8_t v)
-{
- switch(v) {
- case 0:
- return "Initial";
- case 1:
- return "UserSet";
- case 2:
- return "Current";
- default:
- return "Unknown";
- }
-}
-
struct s2145_readtone_resp {
- struct s2145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint16_t total_size;
} __attribute__((packed));
-struct s2145_mediainfo_item {
- uint8_t code;
- uint16_t columns;
- uint16_t rows;
- uint8_t media_type;
- uint8_t print_type; /* The same as the "print method" */
- uint8_t reserved[3];
-} __attribute__((packed));
-
-#define MEDIA_TYPE_UNKNOWN 0x00
-#define MEDIA_TYPE_PAPER 0x01
-
-static char *media_types(uint8_t v) {
- switch (v) {
- case MEDIA_TYPE_UNKNOWN:
- return "Unknown";
- case MEDIA_TYPE_PAPER:
- return "Paper";
- default:
- return "Unknown";
- }
-}
-
struct s2145_mediainfo_resp {
- struct s2145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint8_t count;
- struct s2145_mediainfo_item items[10]; /* Not all necessarily used */
+ struct sinfonia_mediainfo_item items[10]; /* Not all necessarily used */
} __attribute__((packed));
struct s2145_modelname_resp {
- struct s2145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint8_t vendor[4];
uint8_t product[4];
uint8_t modelname[40];
} __attribute__((packed));
-struct s2145_error_item {
- uint8_t major;
- uint8_t minor;
- uint32_t print_counter;
-} __attribute__((packed));
-
-struct s2145_errorlog_resp {
- struct s2145_status_hdr hdr;
- uint8_t count;
- struct s2145_error_item items[10]; /* Not all necessarily used */
-} __attribute__((packed));
-
-struct s2145_fwinfo_resp {
- struct s2145_status_hdr hdr;
- uint8_t name[8];
- uint8_t type[16];
- uint8_t date[10];
- uint8_t major;
- uint8_t minor;
- uint16_t checksum;
-} __attribute__((packed));
-
struct s2145_getunique_resp {
- struct s2145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint8_t data[24]; /* Not necessarily all used. */
} __attribute__((packed));
/* Private data structure */
-struct shinkos2145_printjob {
- struct s2145_printjob_hdr hdr;
-
- uint8_t *databuf;
- int datalen;
- int copies;
-};
-
struct shinkos2145_ctx {
- struct libusb_device_handle *dev;
- uint8_t endp_up;
- uint8_t endp_down;
+ struct sinfonia_usbdev dev;
uint8_t jobid;
- int type;
-
struct s2145_mediainfo_resp media;
struct marker marker;
int media_code;
};
-#define READBACK_LEN 128 /* Needs to be larger than largest response hdr */
-#define CMDBUF_LEN sizeof(struct s2145_print_cmd)
-
-static uint8_t rdbuf[READBACK_LEN];
-
-static int s2145_do_cmd(struct shinkos2145_ctx *ctx,
- uint8_t *cmd, int cmdlen,
- int minlen, int *num)
-{
- int ret;
- struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
-
- libusb_device_handle *dev = ctx->dev;
- uint8_t endp_up = ctx->endp_up;
- uint8_t endp_down = ctx->endp_down;
-
- if ((ret = send_data(dev, endp_down,
- cmd, cmdlen)))
- return (ret < 0) ? ret : -99;
-
- ret = read_data(dev, endp_up,
- rdbuf, READBACK_LEN, num);
-
- if (ret < 0)
- return ret;
- if (*num < minlen) {
- ERROR("Short read! (%d/%d))\n", *num, minlen);
- return -99;
- }
-
- if (resp->result != RESULT_SUCCESS) {
- INFO("Printer Status: %02x (%s)\n", resp->status,
- status_str(resp->status));
- INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
- resp->result, resp->error, resp->printer_major,
- resp->printer_minor, error_codes(resp->printer_major, resp->printer_minor));
- return -99;
- }
-
- return ret;
-}
-
static int get_status(struct shinkos2145_ctx *ctx)
{
- struct s2145_cmd_hdr cmd;
- struct s2145_status_resp *resp = (struct s2145_status_resp *) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s2145_status_resp resp;
int ret, num = 0;
- cmd.cmd = cpu_to_le16(S2145_CMD_STATUS);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
- if ((ret = s2145_do_cmd(ctx,
+ if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
+ (uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
return ret;
}
- INFO("Printer Status: 0x%02x (%s)\n", resp->hdr.status,
- status_str(resp->hdr.status));
- if (resp->hdr.status == ERROR_PRINTER) {
- if(resp->hdr.error == ERROR_NONE)
- resp->hdr.error = resp->hdr.status;
+ INFO("Printer Status: 0x%02x (%s)\n", resp.hdr.status,
+ sinfonia_status_str(resp.hdr.status));
+ if (resp.hdr.status == ERROR_PRINTER) {
+ if(resp.hdr.error == ERROR_NONE)
+ resp.hdr.error = resp.hdr.status;
INFO(" Error 0x%02x (%s) 0x%02x/0x%02x (%s)\n",
- resp->hdr.error,
- error_str(resp->hdr.error),
- resp->hdr.printer_major,
- resp->hdr.printer_minor, error_codes(resp->hdr.printer_major, resp->hdr.printer_minor));
+ resp.hdr.error,
+ sinfonia_error_str(resp.hdr.error),
+ resp.hdr.printer_major,
+ resp.hdr.printer_minor, error_codes(resp.hdr.printer_major, resp.hdr.printer_minor));
}
- if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s2145_status_resp) - sizeof(struct s2145_status_hdr)))
+ if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct s2145_status_resp) - sizeof(struct sinfonia_status_hdr)))
return 0;
INFO(" Print Counts:\n");
- INFO("\tSince Paper Changed:\t%08u\n", le32_to_cpu(resp->count_paper));
- INFO("\tLifetime:\t\t%08u\n", le32_to_cpu(resp->count_lifetime));
- INFO("\tMaintenance:\t\t%08u\n", le32_to_cpu(resp->count_maint));
- INFO("\tPrint Head:\t\t%08u\n", le32_to_cpu(resp->count_head));
- INFO(" Cutter Actuations:\t%08u\n", le32_to_cpu(resp->count_cutter));
- INFO(" Ribbon Remaining:\t%08u\n", le32_to_cpu(resp->count_ribbon_left));
+ INFO("\tSince Paper Changed:\t%08u\n", le32_to_cpu(resp.count_paper));
+ INFO("\tLifetime:\t\t%08u\n", le32_to_cpu(resp.count_lifetime));
+ INFO("\tMaintenance:\t\t%08u\n", le32_to_cpu(resp.count_maint));
+ INFO("\tPrint Head:\t\t%08u\n", le32_to_cpu(resp.count_head));
+ INFO(" Cutter Actuations:\t%08u\n", le32_to_cpu(resp.count_cutter));
+ INFO(" Ribbon Remaining:\t%08u\n", le32_to_cpu(resp.count_ribbon_left));
INFO("Bank 1: 0x%02x (%s) Job %03u @ %03u/%03u (%03u remaining)\n",
- resp->bank1_status, bank_statuses(resp->bank1_status),
- resp->bank1_printid,
- le16_to_cpu(resp->bank1_finished),
- le16_to_cpu(resp->bank1_specified),
- le16_to_cpu(resp->bank1_remaining));
+ resp.bank1_status, sinfonia_bank_statuses(resp.bank1_status),
+ resp.bank1_printid,
+ le16_to_cpu(resp.bank1_finished),
+ le16_to_cpu(resp.bank1_specified),
+ le16_to_cpu(resp.bank1_remaining));
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),
- le16_to_cpu(resp->bank2_specified),
- le16_to_cpu(resp->bank2_remaining));
+ resp.bank2_status, sinfonia_bank_statuses(resp.bank1_status),
+ resp.bank2_printid,
+ le16_to_cpu(resp.bank2_finished),
+ le16_to_cpu(resp.bank2_specified),
+ le16_to_cpu(resp.bank2_remaining));
- INFO("Tonecurve Status: 0x%02x (%s)\n", resp->tonecurve_status, tonecurve_statuses(resp->tonecurve_status));
+ INFO("Tonecurve Status: 0x%02x (%s)\n", resp.tonecurve_status, sinfonia_tonecurve_statuses(resp.tonecurve_status));
return 0;
}
static int get_fwinfo(struct shinkos2145_ctx *ctx)
{
- struct s2145_fwinfo_cmd cmd;
- struct s2145_fwinfo_resp *resp = (struct s2145_fwinfo_resp *)rdbuf;
+ struct sinfonia_fwinfo_cmd cmd;
+ struct sinfonia_fwinfo_resp resp;
int num = 0;
int i;
- cmd.hdr.cmd = cpu_to_le16(S2145_CMD_FWINFO);
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_FWINFO);
cmd.hdr.len = cpu_to_le16(1);
INFO("FW Information:\n");
@@ -922,106 +489,74 @@ static int get_fwinfo(struct shinkos2145_ctx *ctx)
int ret;
cmd.target = i;
- if ((ret = s2145_do_cmd(ctx,
+ if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
+ (uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
- ERROR("Failed to execute %s command (%d)\n", cmd_names(cmd.hdr.cmd), ret);
continue;
}
- if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s2145_fwinfo_resp) - sizeof(struct s2145_status_hdr)))
+ if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_fwinfo_resp) - sizeof(struct sinfonia_status_hdr)))
continue;
INFO(" %s\t ver %02x.%02x\n", fwinfo_targets(i),
- resp->major, resp->minor);
+ resp.major, resp.minor);
#if 0
- INFO(" name: '%s'\n", resp->name);
- INFO(" type: '%s'\n", resp->type);
- INFO(" date: '%s'\n", resp->date);
- INFO(" version: %02x.%02x (CRC %04x)\n", resp->major, resp->minor,
- le16_to_cpu(resp->checksum));
+ INFO(" name: '%s'\n", resp.name);
+ INFO(" type: '%s'\n", resp.type);
+ INFO(" date: '%s'\n", resp.date);
+ INFO(" version: %02x.%02x (CRC %04x)\n", resp.major, resp.minor,
+ le16_to_cpu(resp.checksum));
#endif
}
return 0;
}
-static int get_errorlog(struct shinkos2145_ctx *ctx)
-{
- struct s2145_cmd_hdr cmd;
- struct s2145_errorlog_resp *resp = (struct s2145_errorlog_resp *) rdbuf;
- int ret, num = 0;
- int i;
-
- cmd.cmd = cpu_to_le16(S2145_CMD_ERRORLOG);
- cmd.len = cpu_to_le16(0);
-
- if ((ret = s2145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
- &num)) < 0) {
- 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: %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,
- error_codes(resp->items[i].major, resp->items[i].minor));
- }
- return 0;
-}
-
static void dump_mediainfo(struct s2145_mediainfo_resp *resp)
{
int i;
INFO("Supported Media Information: %u entries:\n", resp->count);
for (i = 0 ; i < resp->count ; i++) {
- 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),
- resp->items[i].media_type, media_types(resp->items[i].media_type),
- resp->items[i].print_type, print_methods(resp->items[i].print_type));
+ INFO(" %02d: C 0x%02x (%s), %04ux%04u, P 0x%02x (%s)\n", i,
+ resp->items[i].code,
+ sinfonia_print_codes(resp->items[i].code, 0),
+ resp->items[i].columns,
+ resp->items[i].rows,
+ resp->items[i].method,
+ sinfonia_print_methods(resp->items[i].method));
}
}
static int get_user_string(struct shinkos2145_ctx *ctx)
{
- struct s2145_cmd_hdr cmd;
- struct s2145_getunique_resp *resp = (struct s2145_getunique_resp*) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s2145_getunique_resp resp;
int ret, num = 0;
- cmd.cmd = cpu_to_le16(S2145_CMD_GETUNIQUE);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETUNIQUE);
cmd.len = cpu_to_le16(0);
- if ((ret = s2145_do_cmd(ctx,
+ if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp) - 1,
+ (uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
return ret;
}
/* Null-terminate */
- resp->hdr.payload_len = le16_to_cpu(resp->hdr.payload_len);
- if (resp->hdr.payload_len > 23)
- resp->hdr.payload_len = 23;
- resp->data[resp->hdr.payload_len] = 0;
- INFO("Unique String: '%s'\n", resp->data);
+ resp.hdr.payload_len = le16_to_cpu(resp.hdr.payload_len);
+ if (resp.hdr.payload_len > 23)
+ resp.hdr.payload_len = 23;
+ resp.data[resp.hdr.payload_len] = 0;
+ INFO("Unique String: '%s'\n", resp.data);
return 0;
}
static int set_user_string(struct shinkos2145_ctx *ctx, char *str)
{
struct s2145_setunique_cmd cmd;
- struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
+ struct sinfonia_status_hdr resp;
int ret, num = 0;
if (str) {
@@ -1034,59 +569,13 @@ static int set_user_string(struct shinkos2145_ctx *ctx, char *str)
cmd.len = 0;
}
- cmd.hdr.cmd = cpu_to_le16(S2145_CMD_SETUNIQUE);
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_SETUNIQUE);
cmd.hdr.len = cpu_to_le16(cmd.len + 1);
- if ((ret = s2145_do_cmd(ctx,
+ if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, cmd.len + 1 + sizeof(cmd.hdr),
- sizeof(*resp),
- &num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
- return ret;
- }
-
- return 0;
-}
-
-static int cancel_job(struct shinkos2145_ctx *ctx, char *str)
-{
- struct s2145_cancel_cmd cmd;
- struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
- int ret, num = 0;
-
- if (!str)
- return -1;
-
- cmd.id = atoi(str);
-
- cmd.hdr.cmd = cpu_to_le16(S2145_CMD_CANCELJOB);
- cmd.hdr.len = cpu_to_le16(1);
-
- if ((ret = s2145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
- &num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
- return ret;
- }
-
- return 0;
-}
-
-static int flash_led(struct shinkos2145_ctx *ctx)
-{
- struct s2145_cmd_hdr cmd;
- struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
- int ret, num = 0;
-
- cmd.cmd = cpu_to_le16(S2145_CMD_FLASHLED);
- cmd.len = cpu_to_le16(0);
-
- if ((ret = s2145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
+ (uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
return ret;
}
@@ -1096,19 +585,19 @@ static int flash_led(struct shinkos2145_ctx *ctx)
static int reset_curve(struct shinkos2145_ctx *ctx, int target)
{
struct s2145_reset_cmd cmd;
- struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
+ struct sinfonia_status_hdr resp;
+
int ret, num = 0;
cmd.target = target;
- cmd.hdr.cmd = cpu_to_le16(S2145_CMD_RESET);
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_RESET);
cmd.hdr.len = cpu_to_le16(1);
- if ((ret = s2145_do_cmd(ctx,
+ if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
+ (uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
return ret;
}
@@ -1118,19 +607,18 @@ static int reset_curve(struct shinkos2145_ctx *ctx, int target)
static int button_set(struct shinkos2145_ctx *ctx, int enable)
{
struct s2145_button_cmd cmd;
- struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
+ struct sinfonia_status_hdr resp;
int ret, num = 0;
- cmd.hdr.cmd = cpu_to_le16(S2145_CMD_BUTTON);
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_BUTTON);
cmd.hdr.len = cpu_to_le16(1);
cmd.enabled = enable;
- if ((ret = s2145_do_cmd(ctx,
+ if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
+ (uint8_t*)&cmd, sizeof(resp),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
return ret;
}
@@ -1140,43 +628,42 @@ static int button_set(struct shinkos2145_ctx *ctx, int enable)
static int get_tonecurve(struct shinkos2145_ctx *ctx, int type, char *fname)
{
struct s2145_readtone_cmd cmd;
- struct s2145_readtone_resp *resp = (struct s2145_readtone_resp *) rdbuf;
+ struct s2145_readtone_resp resp;
int ret, num = 0;
uint8_t *data;
- uint16_t curves[UPDATE_SIZE] = { 0 } ;
+ uint16_t curves[TONE_CURVE_SIZE] = { 0 } ;
int i,j;
cmd.curveid = type;
- cmd.hdr.cmd = cpu_to_le16(S2145_CMD_READTONE);
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_READTONE);
cmd.hdr.len = cpu_to_le16(1);
- INFO("Dump %s Tone Curve to '%s'\n", tonecurve_statuses(type), fname);
+ INFO("Dump %s Tone Curve to '%s'\n", sinfonia_tonecurve_statuses(type), fname);
- if ((ret = s2145_do_cmd(ctx,
+ if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
+ (uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
return ret;
}
- resp->total_size = le16_to_cpu(resp->total_size);
+ resp.total_size = le16_to_cpu(resp.total_size);
- data = malloc(resp->total_size * 2);
+ data = malloc(resp.total_size * 2);
if (!data) {
ERROR("Memory allocation failure! (%d bytes)\n",
- resp->total_size * 2);
+ resp.total_size * 2);
return -1;
}
i = 0;
- while (i < resp->total_size) {
- ret = read_data(ctx->dev, ctx->endp_up,
+ while (i < resp.total_size) {
+ ret = read_data(ctx->dev.dev, ctx->dev.endp_up,
data + i,
- resp->total_size * 2 - i,
+ resp.total_size * 2 - i,
&num);
if (ret < 0)
goto done;
@@ -1184,7 +671,7 @@ static int get_tonecurve(struct shinkos2145_ctx *ctx, int type, char *fname)
}
i = j = 0;
- while (i < resp->total_size) {
+ while (i < resp.total_size) {
memcpy(curves + j, data + i+2, data[i+1]);
j += data[i+1] / 2;
i += data[i+1] + 2;
@@ -1198,11 +685,11 @@ static int get_tonecurve(struct shinkos2145_ctx *ctx, int type, char *fname)
goto done;
}
- for (i = 0 ; i < UPDATE_SIZE; i++) {
+ for (i = 0 ; i < TONE_CURVE_SIZE; i++) {
/* Byteswap appropriately */
curves[i] = cpu_to_be16(le16_to_cpu(curves[i]));
}
- ret = write(tc_fd, curves, UPDATE_SIZE * sizeof(uint16_t));
+ ret = write(tc_fd, curves, TONE_CURVE_SIZE * sizeof(uint16_t));
if (ret < 0)
ERROR("Can't write curve file\n");
else
@@ -1220,59 +707,53 @@ done:
static int set_tonecurve(struct shinkos2145_ctx *ctx, int target, char *fname)
{
struct s2145_update_cmd cmd;
- struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
+ struct sinfonia_status_hdr resp;
int ret, num = 0;
- INFO("Set %s Tone Curve from '%s'\n", update_targets(target), fname);
+ INFO("Set %s Tone Curve from '%s'\n", sinfonia_update_targets(target), fname);
- uint16_t *data = malloc(UPDATE_SIZE * sizeof(uint16_t));
+ uint16_t *data = malloc(TONE_CURVE_SIZE * sizeof(uint16_t));
if (!data) {
ERROR("Memory allocation failure! (%d bytes)\n",
- UPDATE_SIZE);
+ TONE_CURVE_SIZE);
return -1;
}
/* Read in file */
- int tc_fd = open(fname, O_RDONLY);
- if (tc_fd < 0) {
- ret = -1;
- goto done;
- }
- if (read(tc_fd, data, UPDATE_SIZE * sizeof(uint16_t)) != (UPDATE_SIZE * sizeof(uint16_t))) {
- ret = -2;
+ if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE, NULL))) {
+ ERROR("Failed to read Tone Curve file\n");
goto done;
}
- close(tc_fd);
+
/* Byteswap data to local CPU.. */
- for (ret = 0; ret < UPDATE_SIZE ; ret++) {
+ for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
data[ret] = be16_to_cpu(data[ret]);
}
/* Set up command */
cmd.target = target;
cmd.reserved = 0;
- cmd.size = cpu_to_le32(UPDATE_SIZE * sizeof(uint16_t));
+ cmd.size = cpu_to_le32(TONE_CURVE_SIZE * sizeof(uint16_t));
- cmd.hdr.cmd = cpu_to_le16(S2145_CMD_UPDATE);
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_UPDATE);
cmd.hdr.len = cpu_to_le16(sizeof(struct s2145_update_cmd)-sizeof(cmd.hdr));
/* Byteswap data to format printer is expecting.. */
- for (ret = 0; ret < UPDATE_SIZE ; ret++) {
+ for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
data[ret] = cpu_to_le16(data[ret]);
}
- if ((ret = s2145_do_cmd(ctx,
+ if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
+ (uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
goto done;
}
/* Sent transfer */
- if ((ret = send_data(ctx->dev, ctx->endp_down,
- (uint8_t *) data, UPDATE_SIZE * sizeof(uint16_t)))) {
+ if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
+ (uint8_t *) data, TONE_CURVE_SIZE * sizeof(uint16_t)))) {
goto done;
}
@@ -1288,7 +769,6 @@ static void shinkos2145_cmdline(void)
DEBUG("\t\t[ -c filename ] # Get user/NV tone curve\n");
DEBUG("\t\t[ -C filename ] # Set user/NV tone curve\n");
DEBUG("\t\t[ -e ] # Query error log\n");
- DEBUG("\t\t[ -f ] # Use fast return mode\n");
DEBUG("\t\t[ -F ] # Flash Printer LED\n");
DEBUG("\t\t[ -i ] # Query printer info\n");
DEBUG("\t\t[ -l filename ] # Get current tone curve\n");
@@ -1328,10 +808,10 @@ int shinkos2145_cmdline_arg(void *vctx, int argc, char **argv)
j = set_tonecurve(ctx, TONECURVE_USER, optarg);
break;
case 'e':
- j = get_errorlog(ctx);
+ j = sinfonia_geterrorlog(&ctx->dev);
break;
case 'F':
- j = flash_led(ctx);
+ j = sinfonia_flashled(&ctx->dev);
break;
case 'i':
j = get_fwinfo(ctx);
@@ -1361,7 +841,7 @@ int shinkos2145_cmdline_arg(void *vctx, int argc, char **argv)
j = set_user_string(ctx, optarg);
break;
case 'X':
- j = cancel_job(ctx, optarg);
+ j = sinfonia_canceljob(&ctx->dev, atoi(optarg));
break;
default:
break; /* Ignore completely */
@@ -1391,12 +871,12 @@ static int shinkos2145_attach(void *vctx, struct libusb_device_handle *dev, int
uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
{
struct shinkos2145_ctx *ctx = vctx;
- int i;
- ctx->dev = dev;
- ctx->endp_up = endp_up;
- ctx->endp_down = endp_down;
- ctx->type = type;
+ ctx->dev.dev = dev;
+ ctx->dev.endp_up = endp_up;
+ ctx->dev.endp_down = endp_down;
+ ctx->dev.type = type;
+ ctx->dev.error_codes = &error_codes;
/* Ensure jobid is sane */
ctx->jobid = (jobid & 0x7f);
@@ -1406,21 +886,25 @@ static int shinkos2145_attach(void *vctx, struct libusb_device_handle *dev, int
int media_prints = 65536;
if (test_mode < TEST_MODE_NOATTACH) {
/* Query Media */
- struct s2145_cmd_hdr cmd;
- struct s2145_mediainfo_resp *resp = (struct s2145_mediainfo_resp *) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
int num = 0;
+ int i;
- cmd.cmd = cpu_to_le16(S2145_CMD_MEDIAINFO);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_MEDIAINFO);
cmd.len = cpu_to_le16(0);
- if (s2145_do_cmd(ctx,
+ if (sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
+ (uint8_t*)&ctx->media, sizeof(ctx->media),
&num)) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
return CUPS_BACKEND_FAILED;
}
- memcpy(&ctx->media, resp, sizeof(ctx->media));
+
+ /* Byteswap media descriptor.. */
+ for (i = 0 ; i < ctx->media.count ; i++) {
+ ctx->media.items[i].columns = le16_to_cpu(ctx->media.items[i].columns);
+ ctx->media.items[i].rows = le16_to_cpu(ctx->media.items[i].rows);
+ }
/* Figure out the media type... */
for (i = 0 ; i < ctx->media.count ; i++) {
@@ -1430,7 +914,7 @@ static int shinkos2145_attach(void *vctx, struct libusb_device_handle *dev, int
}
}
} else {
- int media_code = PRINT_MEDIA_6x9;
+ int media_code = CODE_6x9;
if (getenv("MEDIA_CODE"))
media_code = atoi(getenv("MEDIA_CODE"));
@@ -1439,38 +923,17 @@ static int shinkos2145_attach(void *vctx, struct libusb_device_handle *dev, int
}
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
- ctx->marker.name = print_sizes(ctx->media_code);
+ ctx->marker.name = sinfonia_print_codes(ctx->media_code, 0);
ctx->marker.levelmax = media_prints;
ctx->marker.levelnow = -2;
return CUPS_BACKEND_OK;
}
-static void shinkos2145_cleanup_job(const void *vjob)
-{
- const struct shinkos2145_printjob *job = vjob;
-
- if (job->databuf)
- free(job->databuf);
-
- free((void*)job);
-}
-
-static void shinkos2145_teardown(void *vctx) {
- struct shinkos2145_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int shinkos2145_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct shinkos2145_ctx *ctx = vctx;
+ struct sinfonia_printjob *job = NULL;
int ret;
- uint8_t tmpbuf[4];
-
- struct shinkos2145_printjob *job = NULL;
if (!ctx)
return CUPS_BACKEND_FAILED;
@@ -1481,70 +944,18 @@ static int shinkos2145_read_parse(void *vctx, const void **vjob, int data_fd, in
return CUPS_BACKEND_RETRY_CURRENT;
}
memset(job, 0, sizeof(*job));
- job->copies = copies; // XXX hdr.copies
-
- /* Read in then validate header */
- ret = read(data_fd, &job->hdr, sizeof(job->hdr));
- if (ret < 0 || ret != sizeof(job->hdr)) {
- if (ret == 0)
- return CUPS_BACKEND_CANCEL;
- ERROR("Read failed (%d/%d/%d)\n",
- ret, 0, (int)sizeof(job->hdr));
- perror("ERROR: Read failed");
- return ret;
- }
-
- if (le32_to_cpu(job->hdr.len1) != 0x10 ||
- le32_to_cpu(job->hdr.len2) != 0x64 ||
- le32_to_cpu(job->hdr.dpi) != 300) {
- ERROR("Unrecognized header data format!\n");
- return CUPS_BACKEND_CANCEL;
- }
-
- if (le32_to_cpu(job->hdr.model) != 2145) {
- ERROR("Unrecognized printer (%u)!\n", le32_to_cpu(job->hdr.model));
- return CUPS_BACKEND_CANCEL;
- }
-
- job->datalen = le32_to_cpu(job->hdr.rows) * le32_to_cpu(job->hdr.columns) * 3;
- job->databuf = malloc(job->datalen);
- if (!job->databuf) {
- ERROR("Memory allocation failure!\n");
- return CUPS_BACKEND_RETRY_CURRENT;
- }
-
- {
- int remain = job->datalen;
- uint8_t *ptr = job->databuf;
- do {
- ret = read(data_fd, ptr, remain);
- if (ret < 0) {
- ERROR("Read failed (%d/%d/%d)\n",
- ret, remain, job->datalen);
- perror("ERROR: Read failed");
- return ret;
- }
- ptr += ret;
- remain -= ret;
- } while (remain);
- }
-
- /* Make sure footer is sane too */
- ret = read(data_fd, tmpbuf, 4);
- if (ret != 4) {
- ERROR("Read failed (%d/%d/%d)\n",
- ret, 4, 4);
- perror("ERROR: Read failed");
+ /* Common read/parse code */
+ ret = sinfonia_read_parse(data_fd, 2145, job);
+ if (ret) {
+ free(job);
return ret;
}
- if (tmpbuf[0] != 0x04 ||
- tmpbuf[1] != 0x03 ||
- tmpbuf[2] != 0x02 ||
- tmpbuf[3] != 0x01) {
- ERROR("Unrecognized footer data format!\n");
- return CUPS_BACKEND_FAILED;
- }
+
+ if (job->jp.copies > 1)
+ job->copies = job->jp.copies;
+ else
+ job->copies = copies;
*vjob = job;
@@ -1555,23 +966,19 @@ static int shinkos2145_main_loop(void *vctx, const void *vjob) {
struct shinkos2145_ctx *ctx = vctx;
int ret, num;
- uint8_t cmdbuf[CMDBUF_LEN];
- uint8_t rdbuf2[READBACK_LEN];
int i, last_state = -1, state = S_IDLE;
- struct s2145_cmd_hdr *cmd = (struct s2145_cmd_hdr *) cmdbuf;;
- struct s2145_print_cmd *print = (struct s2145_print_cmd *) cmdbuf;
- struct s2145_status_resp *sts = (struct s2145_status_resp *) rdbuf;
-
- struct shinkos2145_printjob *job = (struct shinkos2145_printjob*) vjob;
+ struct sinfonia_printjob *job = (struct sinfonia_printjob*) vjob;
+ struct sinfonia_cmd_hdr cmd;
+ struct s2145_status_resp sts, sts2;
/* Validate print sizes */
for (i = 0; i < ctx->media.count ; i++) {
/* Look for matching media */
- if (le16_to_cpu(ctx->media.items[i].columns) == cpu_to_le16(le32_to_cpu(job->hdr.columns)) &&
- le16_to_cpu(ctx->media.items[i].rows) == cpu_to_le16(le32_to_cpu(job->hdr.rows)) &&
- ctx->media.items[i].print_type == le32_to_cpu(job->hdr.method))
+ if (ctx->media.items[i].columns == job->jp.columns &&
+ ctx->media.items[i].rows == job->jp.rows &&
+ ctx->media.items[i].method == job->jp.method)
break;
}
if (i == ctx->media.count) {
@@ -1588,32 +995,30 @@ top:
}
/* Send Status Query */
- memset(cmdbuf, 0, CMDBUF_LEN);
- cmd->cmd = cpu_to_le16(S2145_CMD_STATUS);
- cmd->len = cpu_to_le16(0);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
+ cmd.len = cpu_to_le16(0);
- if ((ret = s2145_do_cmd(ctx,
- cmdbuf, sizeof(*cmd),
- sizeof(struct s2145_status_hdr),
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd));
return CUPS_BACKEND_FAILED;
}
- if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) {
- memcpy(rdbuf2, rdbuf, READBACK_LEN);
+ if (memcmp(&sts, &sts2, sizeof(sts))) {
+ memcpy(&sts2, &sts, sizeof(sts));
INFO("Printer Status: 0x%02x (%s)\n",
- sts->hdr.status, status_str(sts->hdr.status));
+ sts.hdr.status, sinfonia_status_str(sts.hdr.status));
- if (ctx->marker.levelnow != (int)sts->count_ribbon_left) {
- ctx->marker.levelnow = sts->count_ribbon_left;
+ if (ctx->marker.levelnow != (int)sts.count_ribbon_left) {
+ ctx->marker.levelnow = sts.count_ribbon_left;
dump_markers(&ctx->marker, 1, 0);
}
- if (sts->hdr.result != RESULT_SUCCESS)
+ if (sts.hdr.result != RESULT_SUCCESS)
goto printer_error;
- if (sts->hdr.error == ERROR_PRINTER)
+ if (sts.hdr.error == ERROR_PRINTER)
goto printer_error;
} else if (state == last_state) {
sleep(1);
@@ -1629,8 +1034,8 @@ top:
/* make sure we're not colliding with an existing
jobid */
- while (ctx->jobid == sts->bank1_printid ||
- ctx->jobid == sts->bank2_printid) {
+ while (ctx->jobid == sts.bank1_printid ||
+ ctx->jobid == sts.bank2_printid) {
ctx->jobid++;
ctx->jobid &= 0x7f;
if (!ctx->jobid)
@@ -1638,47 +1043,48 @@ top:
}
/* 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:
+ case S_PRINTER_READY_CMD: {
+ struct sinfonia_printcmd10_hdr print;
+
INFO("Sending print job (internal id %u)\n", ctx->jobid);
- memset(cmdbuf, 0, CMDBUF_LEN);
- print->hdr.cmd = cpu_to_le16(S2145_CMD_PRINTJOB);
- print->hdr.len = cpu_to_le16(sizeof (*print) - sizeof(*cmd));
-
- print->id = ctx->jobid;
- print->count = cpu_to_le16(job->copies);
- print->columns = cpu_to_le16(le32_to_cpu(job->hdr.columns));
- print->rows = cpu_to_le16(le32_to_cpu(job->hdr.rows));
- print->media = le32_to_cpu(job->hdr.media);
- print->mode = le32_to_cpu(job->hdr.mode);
- print->method = le32_to_cpu(job->hdr.method);
-
- if ((ret = s2145_do_cmd(ctx,
- cmdbuf, sizeof(*print),
- sizeof(struct s2145_status_hdr),
+ memset(&print, 0, sizeof(print));
+ print.hdr.cmd = cpu_to_le16(SINFONIA_CMD_PRINTJOB);
+ print.hdr.len = cpu_to_le16(sizeof(print) - sizeof(print.hdr));
+
+ print.jobid = ctx->jobid;
+ print.copies = cpu_to_le16(job->copies);
+ print.columns = cpu_to_le16(job->jp.columns);
+ print.rows = cpu_to_le16(job->jp.rows);
+ print.media = job->jp.media;
+ print.oc_mode = job->jp.oc_mode;
+ print.method = job->jp.method;
+
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&print, sizeof(print),
+ (uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(print->hdr.cmd));
return ret;
}
- if (sts->hdr.result != RESULT_SUCCESS) {
- if (sts->hdr.error == ERROR_BUFFER_FULL) {
+ if (sts.hdr.result != RESULT_SUCCESS) {
+ if (sts.hdr.error == ERROR_BUFFER_FULL) {
INFO("Printer Buffers full, retrying\n");
break;
- } else if ((sts->hdr.status & 0xf0) == 0x30 || sts->hdr.status == 0x21) {
- INFO("Printer busy (%s), retrying\n", status_str(sts->hdr.status));
+ } else if ((sts.hdr.status & 0xf0) == 0x30 || sts.hdr.status == 0x21) {
+ INFO("Printer busy (%s), retrying\n", sinfonia_status_str(sts.hdr.status));
break;
- } else if (sts->hdr.status != ERROR_NONE)
+ } else if (sts.hdr.status != ERROR_NONE)
goto printer_error;
}
INFO("Sending image data to printer\n");
- if ((ret = send_data(ctx->dev, ctx->endp_down,
+ if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
job->databuf, job->datalen)))
return CUPS_BACKEND_FAILED;
@@ -1686,13 +1092,14 @@ top:
sleep(1);
state = S_PRINTER_SENT_DATA;
break;
+ }
case S_PRINTER_SENT_DATA:
if (fast_return) {
INFO("Fast return mode enabled.\n");
state = S_FINISHED;
- } else if (sts->hdr.status == STATUS_READY ||
- sts->hdr.status == STATUS_FINISHED ||
- sts->hdr.status == ERROR_PRINTER) {
+ } else if (sts.hdr.status == STATUS_READY ||
+ sts.hdr.status == STATUS_FINISHED ||
+ sts.hdr.status == ERROR_PRINTER) {
state = S_FINISHED;
}
break;
@@ -1703,14 +1110,14 @@ top:
if (state != S_FINISHED)
goto top;
- if (sts->hdr.status == ERROR_PRINTER) {
- if(sts->hdr.error == ERROR_NONE)
- sts->hdr.error = sts->hdr.status;
+ if (sts.hdr.status == ERROR_PRINTER) {
+ if(sts.hdr.error == ERROR_NONE)
+ sts.hdr.error = sts.hdr.status;
INFO(" Error 0x%02x (%s) 0x%02x/0x%02x (%s)\n",
- sts->hdr.error,
- error_str(sts->hdr.error),
- sts->hdr.printer_major,
- sts->hdr.printer_minor, error_codes(sts->hdr.printer_major, sts->hdr.printer_minor));
+ sts.hdr.error,
+ sinfonia_error_str(sts.hdr.error),
+ sts.hdr.printer_major,
+ sts.hdr.printer_minor, error_codes(sts.hdr.printer_major, sts.hdr.printer_minor));
}
INFO("Print complete\n");
@@ -1719,45 +1126,41 @@ top:
printer_error:
ERROR("Printer reported error: %#x (%s) status: %#x (%s) -> %#x.%#x (%s)\n",
- sts->hdr.error,
- error_str(sts->hdr.error),
- sts->hdr.status,
- status_str(sts->hdr.status),
- sts->hdr.printer_major, sts->hdr.printer_minor,
- error_codes(sts->hdr.printer_major, sts->hdr.printer_minor));
+ sts.hdr.error,
+ sinfonia_error_str(sts.hdr.error),
+ sts.hdr.status,
+ sinfonia_status_str(sts.hdr.status),
+ sts.hdr.printer_major, sts.hdr.printer_minor,
+ error_codes(sts.hdr.printer_major, sts.hdr.printer_minor));
return CUPS_BACKEND_FAILED;
}
static int shinkos2145_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len)
{
- struct s2145_cmd_hdr cmd;
- struct s2145_getunique_resp *resp = (struct s2145_getunique_resp*) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s2145_getunique_resp resp;
int ret, num = 0;
- struct shinkos2145_ctx ctx = {
+ struct sinfonia_usbdev sdev = {
.dev = dev,
.endp_up = endp_up,
.endp_down = endp_down,
};
- cmd.cmd = cpu_to_le16(S2145_CMD_GETUNIQUE);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETUNIQUE);
cmd.len = cpu_to_le16(0);
- if ((ret = s2145_do_cmd(&ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp) - 1,
- &num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if ((ret = sinfonia_docmd(&sdev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
return ret;
}
- /* Null-terminate */
- resp->hdr.payload_len = le16_to_cpu(resp->hdr.payload_len);
- if (resp->hdr.payload_len > 23)
- resp->hdr.payload_len = 23;
- resp->data[resp->hdr.payload_len] = 0;
- strncpy(buf, (char*)resp->data, buf_len);
- buf[buf_len-1] = 0; /* ensure it's null terminated */
+ /* Copy and Null-terminate */
+ num = (buf_len > (int)sizeof(resp.data)) ? (int)sizeof(resp.data) : (buf_len - 1);
+ memcpy(buf, resp.data, num);
+ buf[num] = 0;
return CUPS_BACKEND_OK;
}
@@ -1765,23 +1168,22 @@ static int shinkos2145_query_serno(struct libusb_device_handle *dev, uint8_t end
static int shinkos2145_query_markers(void *vctx, struct marker **markers, int *count)
{
struct shinkos2145_ctx *ctx = vctx;
- struct s2145_cmd_hdr cmd;
- struct s2145_status_resp *sts = (struct s2145_status_resp *) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s2145_status_resp sts;
int num;
/* Query Status */
- cmd.cmd = cpu_to_le16(S2145_CMD_STATUS);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
- if (s2145_do_cmd(ctx,
+ if (sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
- sizeof(*sts),
+ (uint8_t*)&sts, sizeof(sts),
&num)) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
return CUPS_BACKEND_FAILED;
}
- ctx->marker.levelnow = ctx->marker.levelmax - le32_to_cpu(sts->count_ribbon_left);
+ ctx->marker.levelnow = ctx->marker.levelmax - le32_to_cpu(sts.count_ribbon_left);
*markers = &ctx->marker;
*count = 1;
@@ -1804,14 +1206,13 @@ static const char *shinkos2145_prefixes[] = {
struct dyesub_backend shinkos2145_backend = {
.name = "Shinko/Sinfonia CHC-S2145/S2",
- .version = "0.55",
+ .version = "0.61" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = shinkos2145_prefixes,
.cmdline_usage = shinkos2145_cmdline,
.cmdline_arg = shinkos2145_cmdline_arg,
.init = shinkos2145_init,
.attach = shinkos2145_attach,
- .teardown = shinkos2145_teardown,
- .cleanup_job = shinkos2145_cleanup_job,
+ .cleanup_job = sinfonia_cleanup_job,
.read_parse = shinkos2145_read_parse,
.main_loop = shinkos2145_main_loop,
.query_serno = shinkos2145_query_serno,
diff --git a/src/cups/backend_shinkos6145.c b/src/cups/backend_shinkos6145.c
index e795831..bbe5912 100644
--- a/src/cups/backend_shinkos6145.c
+++ b/src/cups/backend_shinkos6145.c
@@ -1,7 +1,7 @@
/*
* Shinko/Sinfonia CHC-S6145 CUPS backend -- libusb-1.0 version
*
- * (c) 2015-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2015-2019 Solomon Peachy <pizza@shaftnet.org>
*
* Low-level documentation was provided by Sinfonia. Thank you!
*
@@ -79,6 +79,7 @@
#define BACKEND shinkos6145_backend
#include "backend_common.h"
+#include "backend_sinfonia.h"
/* Image processing library function prototypes */
typedef int (*ImageProcessingFN)(unsigned char *, unsigned short *, void *);
@@ -94,46 +95,6 @@ enum {
S_FINISHED,
};
-/* Structure of printjob header. All fields are LITTLE ENDIAN */
-struct s6145_printjob_hdr {
- uint32_t len1; /* Fixed at 0x10 */
- uint32_t model; /* Equal to the printer model (eg '6245' or '1245' decimal) */
- uint32_t media_w; /* 0x02 for 5", 0x03 for 6" */
- uint32_t unk3; /* Fixed at 0x01 */
-
- uint32_t len2; /* Fixed at 0x64 */
- uint32_t unk5;
- uint32_t media; /* 0x08 5x5, 0x03 5x7, 0x07 2x6, 0x00 4x6, 0x06 6x6/6x6+6x2/4x6*2/6x8 */
- uint32_t unk6;
-
- uint32_t method; /* 0x00 normal, 0x02 4x6*2, 0x04 2x6*2, 0x05 6x6+2x6 */
- uint32_t qual; /* 0x00 default, 0x01 std */
- uint32_t oc_mode; /* 0x00 default, 0x01 off, 0x02 glossy, 0x03 matte */
- uint32_t unk8;
-
- uint32_t unk9;
- uint32_t columns;
- uint32_t rows;
- uint32_t copies;
-
- uint32_t unk10;
- uint32_t unk11;
- uint32_t unk12;
- uint32_t unk13;
-
- uint32_t unk14;
- uint32_t unk15;
- uint32_t dpi; /* Fixed at '300' (decimal) */
- uint32_t unk16;
-
- uint32_t unk17;
- uint32_t unk18;
- uint32_t unk19;
- uint32_t unk20;
-
- uint32_t ext_flags; /* 0x00 in the official headers. 0x01 to mark inout data as YMC planar */
-} __attribute__((packed));
-
/* "Image Correction Parameter" File */
// 128 bytes total, apparently an array of 32-bit values
struct tankParamTable {
@@ -261,79 +222,8 @@ struct shinkos6145_correctionparam {
} __attribute__((packed)); /* 16384 bytes */
/* Structs for printer */
-struct s6145_cmd_hdr {
- uint16_t cmd;
- uint16_t len; /* Not including this header */
-} __attribute__((packed));
-
-#define S6145_CMD_GETSTATUS 0x0001
-#define S6145_CMD_MEDIAINFO 0x0002
-#define S6145_CMD_ERRORLOG 0x0004
-#define S6145_CMD_GETPARAM 0x0005
-#define S6145_CMD_GETSERIAL 0x0006
-#define S6145_CMD_PRINTSTAT 0x0007
-#define S6145_CMD_EXTCOUNTER 0x0008
-#define S6145_CMD_MEMORYBANK 0x000A // Brava 21 only?
-
-#define S6145_CMD_PRINTJOB 0x4001
-#define S6145_CMD_CANCELJOB 0x4002
-#define S6145_CMD_FLASHLED 0x4003
-#define S6145_CMD_RESET 0x4004
-#define S6145_CMD_READTONE 0x4005
-#define S6145_CMD_SETPARAM 0x4007
-
-#define S6145_CMD_GETCORR 0x400D
-#define S6145_CMD_GETEEPROM 0x400E
-#define S6145_CMD_SETEEPROM 0x400F
-
-#define S6145_CMD_FWINFO 0xC003
-#define S6145_CMD_UPDATE 0xC004
-
-static char *cmd_names(uint16_t v) {
- switch (le16_to_cpu(v)) {
- case S6145_CMD_GETSTATUS:
- return "Get Status";
- case S6145_CMD_MEDIAINFO:
- return "Get Media Info";
- case S6145_CMD_ERRORLOG:
- return "Get Error Log";
- case S6145_CMD_GETPARAM:
- return "Get Parameter";
- case S6145_CMD_GETSERIAL:
- return "Get Serial Number";
- case S6145_CMD_PRINTSTAT:
- return "Get Print ID Status";
- case S6145_CMD_EXTCOUNTER:
- return "Get Extended Counters";
- case S6145_CMD_PRINTJOB:
- return "Print";
- case S6145_CMD_CANCELJOB:
- return "Cancel Print";
- case S6145_CMD_FLASHLED:
- return "Flash LEDs";
- case S6145_CMD_RESET:
- return "Reset";
- case S6145_CMD_READTONE:
- return "Read Tone Curve";
- case S6145_CMD_SETPARAM:
- return "Set Parameter";
- case S6145_CMD_GETCORR:
- return "Get Image Correction Parameter";
- case S6145_CMD_GETEEPROM:
- return "Get EEPROM Backup Parameter";
- case S6145_CMD_SETEEPROM:
- return "Set EEPROM Backup Parameter";
- case S6145_CMD_FWINFO:
- return "Get Firmware Info";
- case S6145_CMD_UPDATE:
- return "Update";
- default:
- return "Unknown Command";
- }
-}
-
struct s6145_print_cmd {
- struct s6145_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint8_t id;
uint16_t count;
uint16_t columns;
@@ -346,77 +236,6 @@ struct s6145_print_cmd {
uint8_t image_avg;
} __attribute__((packed));
-#define PRINT_MODE_NO_OC 0x01
-#define PRINT_MODE_GLOSSY 0x02
-#define PRINT_MODE_MATTE 0x03
-
-#if 0
-static char *print_modes(uint8_t v) {
- switch (v) {
- case PRINT_MODE_NO_OC:
- return "No Overcoat";
- case PRINT_MODE_GLOSSY:
- return "Glossy";
- case PRINT_MODE_MATTE:
- return "Matte";
- default:
- return "Unknown";
- }
-}
-#endif
-
-#define PRINT_METHOD_STD 0x00
-#define PRINT_METHOD_COMBO_2 0x02
-#define PRINT_METHOD_SPLIT 0x04
-#define PRINT_METHOD_DOUBLE 0x08
-#define PRINT_METHOD_NOTRIM 0x80
-
-static char *print_methods (uint8_t v) {
- switch (v & 0xf) {
- case PRINT_METHOD_STD:
- return "Standard";
- case PRINT_METHOD_COMBO_2:
- return "2up";
- case PRINT_METHOD_SPLIT:
- return "Split";
- case PRINT_METHOD_DOUBLE:
- return "Double";
- default:
- return "Unknown";
- }
-}
-
-struct s6145_cancel_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t id;
-} __attribute__((packed));
-
-struct s6145_reset_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t target;
- uint8_t curveid;
-} __attribute__((packed));
-
-#define RESET_PRINTER 0x03
-#define RESET_TONE_CURVE 0x04
-
-#define TONE_CURVE_ID 0x01
-
-struct s6145_readtone_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t target;
- uint8_t curveid;
-} __attribute__((packed));
-
-#define READ_TONE_CURVE_USER 0x01
-#define READ_TONE_CURVE_CURR 0x02
-
-struct s6145_setparam_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t target;
- uint32_t param;
-} __attribute__((packed));
-
#define PARAM_OC_PRINT 0x20
#define PARAM_PAPER_PRESV 0x3d
#define PARAM_DRIVER_MODE 0x3e
@@ -445,103 +264,7 @@ struct s6145_setparam_cmd {
#define PARAM_SLEEP_120MIN 0x00000004
#define PARAM_SLEEP_240MIN 0x00000005
-struct s6145_seteeprom_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t data[256]; /* Maxlen */
-} __attribute__((packed));
-
-struct s6145_errorlog_cmd {
- struct s6145_cmd_hdr hdr;
- uint16_t index; /* 0 is latest */
-} __attribute__((packed));
-
-struct s6145_getparam_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t target;
-} __attribute__((packed));
-
-struct s6145_getprintidstatus_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t id;
-} __attribute__((packed));
-
-struct s6145_fwinfo_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t target;
-} __attribute__((packed));
-
-#define FWINFO_TARGET_MAIN_BOOT 0x01
-#define FWINFO_TARGET_MAIN_APP 0x02
-#define FWINFO_TARGET_PRINT_TABLES 0x03
-#define FWINFO_TARGET_DSP 0x04
-
-static char *fwinfo_targets (uint8_t v) {
- switch (v) {
- case FWINFO_TARGET_MAIN_BOOT:
- return "Main Boot ";
- case FWINFO_TARGET_MAIN_APP:
- return "Main App ";
- case FWINFO_TARGET_DSP:
- return "DSP ";
- case FWINFO_TARGET_PRINT_TABLES:
- return "Print Tables";
- default:
- return "Unknown ";
- }
-}
-
-struct s6145_update_cmd {
- struct s6145_cmd_hdr hdr;
- uint8_t target;
- uint8_t curve_id;
- uint8_t reset; // ??
- uint8_t reserved[3];
- uint32_t size;
-} __attribute__((packed));
-
-#define UPDATE_TARGET_USER 0x03
-#define UPDATE_TARGET_CURRENT 0x04
-
-static char *update_targets (uint8_t v) {
- switch (v) {
- case UPDATE_TARGET_USER:
- return "User";
- case UPDATE_TARGET_CURRENT:
- return "Current";
- default:
- return "Unknown";
- }
-}
-
-#define UPDATE_SIZE 0x600
-/* Update is three channels, Y, M, C;
- each is 256 entries of 11-bit data padded to 16-bits.
- Printer expects LE data. We use BE data on disk.
-*/
-
-struct s6145_status_hdr {
- uint8_t result;
- uint8_t error;
- uint8_t printer_major;
- uint8_t printer_minor;
- uint8_t reserved[3];
- uint8_t status;
- uint16_t payload_len;
-} __attribute__((packed));
-
-#define RESULT_SUCCESS 0x01
-#define RESULT_FAIL 0x02
-
-#define ERROR_NONE 0x00
-#define ERROR_INVALID_PARAM 0x01
-#define ERROR_MAIN_APP_INACTIVE 0x02
-#define ERROR_COMMS_TIMEOUT 0x03
-#define ERROR_MAINT_NEEDED 0x04
-#define ERROR_BAD_COMMAND 0x05
-#define ERROR_PRINTER 0x11
-#define ERROR_BUFFER_FULL 0x21
-
-static char *error_codes(uint8_t major, uint8_t minor)
+static const char *error_codes(uint8_t major, uint8_t minor)
{
switch(major) {
case 0x01: /* "Controller Error" */
@@ -734,102 +457,8 @@ static char *error_codes(uint8_t major, uint8_t minor)
}
}
-static char *error_str(uint8_t v) {
- switch (v) {
- case ERROR_NONE:
- return "None";
- case ERROR_INVALID_PARAM:
- return "Invalid Command Parameter";
- case ERROR_MAIN_APP_INACTIVE:
- return "Main App Inactive";
- case ERROR_COMMS_TIMEOUT:
- return "Main Communication Timeout";
- case ERROR_MAINT_NEEDED:
- return "Maintenance Needed";
- case ERROR_BAD_COMMAND:
- return "Inappropriate Command";
- case ERROR_PRINTER:
- return "Printer Error";
- case ERROR_BUFFER_FULL:
- return "Buffer Full";
- default:
- return "Unknown";
- }
-}
-
-#define STATUS_READY 0x00
-#define STATUS_INIT_CPU 0x31
-#define STATUS_INIT_RIBBON 0x32
-#define STATUS_INIT_PAPER 0x33
-#define STATUS_THERMAL_PROTECT 0x34
-#define STATUS_USING_PANEL 0x35
-#define STATUS_SELF_DIAG 0x36
-#define STATUS_DOWNLOADING 0x37
-
-#define STATUS_FEEDING_PAPER 0x61
-#define STATUS_PRE_HEAT 0x62
-#define STATUS_PRINT_Y 0x63
-#define STATUS_BACK_FEED_Y 0x64
-#define STATUS_PRINT_M 0x65
-#define STATUS_BACK_FEED_M 0x66
-#define STATUS_PRINT_C 0x67
-#define STATUS_BACK_FEED_C 0x68
-#define STATUS_PRINT_OP 0x69
-#define STATUS_PAPER_CUT 0x6A
-#define STATUS_PAPER_EJECT 0x6B
-#define STATUS_BACK_FEED_E 0x6C
-
-static char *status_str(uint8_t v) {
- switch (v) {
- case STATUS_READY:
- return "Ready";
- case STATUS_INIT_CPU:
- return "Initializing CPU";
- case STATUS_INIT_RIBBON:
- return "Initializing Ribbon";
- case STATUS_INIT_PAPER:
- return "Loading Paper";
- case STATUS_THERMAL_PROTECT:
- return "Thermal Protection";
- case STATUS_USING_PANEL:
- return "Using Operation Panel";
- case STATUS_SELF_DIAG:
- return "Processing Self Diagnosis";
- case STATUS_DOWNLOADING:
- return "Processing Download";
- case STATUS_FEEDING_PAPER:
- return "Feeding Paper";
- case STATUS_PRE_HEAT:
- return "Pre-Heating";
- case STATUS_PRINT_Y:
- return "Printing Yellow";
- case STATUS_BACK_FEED_Y:
- return "Back-Feeding - Yellow Complete";
- case STATUS_PRINT_M:
- return "Printing Magenta";
- case STATUS_BACK_FEED_M:
- return "Back-Feeding - Magenta Complete";
- case STATUS_PRINT_C:
- return "Printing Cyan";
- case STATUS_BACK_FEED_C:
- return "Back-Feeding - Cyan Complete";
- case STATUS_PRINT_OP:
- return "Laminating";
- case STATUS_PAPER_CUT:
- return "Cutting Paper";
- case STATUS_PAPER_EJECT:
- return "Ejecting Paper";
- case STATUS_BACK_FEED_E:
- return "Back-Feeding - Ejected";
- case ERROR_PRINTER:
- return "Printer Error";
- default:
- return "Unknown";
- }
-}
-
struct s6145_status_resp {
- struct s6145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint32_t count_lifetime;
uint32_t count_maint;
uint32_t count_paper;
@@ -855,111 +484,11 @@ struct s6145_status_resp {
uint8_t reserved3[6];
} __attribute__((packed));
-#define BANK_STATUS_FREE 0x00
-#define BANK_STATUS_XFER 0x01
-#define BANK_STATUS_FULL 0x02
-#define BANK_STATUS_PRINTING 0x12
-
-static char *bank_statuses(uint8_t v)
-{
- switch (v) {
- case BANK_STATUS_FREE:
- return "Free";
- case BANK_STATUS_XFER:
- return "Xfer";
- case BANK_STATUS_FULL:
- return "Full";
- case BANK_STATUS_PRINTING:
- return "Printing";
- default:
- return "Unknown";
- }
-}
-
-#define TONECURVE_INIT 0x00
-#define TONECURVE_USER 0x01
-#define TONECURVE_CURRENT 0x02
-
-static char *tonecurve_statuses (uint8_t v)
-{
- switch(v) {
- case 0:
- return "Initial";
- case 1:
- return "UserSet";
- case 2:
- return "Current";
- default:
- return "Unknown";
- }
-}
-
struct s6145_geteeprom_resp {
- struct s6145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint8_t data[256];
} __attribute__((packed));
-struct s6145_readtone_resp {
- struct s6145_status_hdr hdr;
- uint16_t total_size;
-} __attribute__((packed));
-
-struct s6145_mediainfo_item {
- uint8_t media_code;
- uint16_t columns;
- uint16_t rows;
- uint8_t reserved;
- uint8_t print_method; /* PRINT_METHOD_* */
- uint8_t reserved2[3];
-} __attribute__((packed));
-
-#define MEDIA_4x6 0x00
-#define MEDIA_3_5x5 0x01
-#define MEDIA_5x7 0x03
-#define MEDIA_6x9 0x05
-#define MEDIA_6x8 0x06
-#define MEDIA_2x6 0x07
-#define MEDIA_6x6 0x08
-#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";
- case MEDIA_3_5x5:
- return "3.5x5";
- case MEDIA_5x7:
- return "5x7";
- case MEDIA_6x9:
- return "6x9";
- case MEDIA_6x8:
- return "6x8";
- case MEDIA_2x6:
- 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";
- }
-}
-
#define RIBBON_NONE 0x00
#define RIBBON_4x6 0x01
#define RIBBON_3_5x5 0x02
@@ -1000,76 +529,22 @@ static const char *print_ribbons (uint8_t v) {
return "6x8";
case RIBBON_6x9:
return "6x9";
- // XXX 89x??? rubbons.
+ // XXX 89x??? ribbons.
default:
return "Unknown";
}
}
struct s6145_mediainfo_resp {
- struct s6145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint8_t ribbon;
uint8_t reserved;
uint8_t count;
- struct s6145_mediainfo_item items[10]; /* Not all necessarily used */
-} __attribute__((packed));
-
-struct s6145_error_item {
- uint8_t major;
- uint8_t minor;
- uint32_t print_counter;
-} __attribute__((packed));
-
-struct s6145_errorlog_resp {
- struct s6145_status_hdr hdr;
- uint8_t count;
- struct s6145_error_item items[10]; /* Not all necessarily used */
-} __attribute__((packed));
-
-struct s6145_getparam_resp {
- struct s6145_status_hdr hdr;
- uint32_t param;
-} __attribute__((packed));
-
-struct s6145_getserial_resp {
- struct s6145_status_hdr hdr;
- uint8_t data[8];
-} __attribute__((packed));
-
-struct s6145_getprintidstatus_resp {
- struct s6145_status_hdr hdr;
- uint8_t id;
- uint16_t remaining;
- uint16_t finished;
- uint16_t specified;
- uint16_t status;
-} __attribute__((packed));
-
-#define STATUS_WAITING 0x0000
-#define STATUS_PRINTING 0x0100
-#define STATUS_COMPLETED 0x0200
-#define STATUS_ERROR 0xFFFF
-
-struct s6145_getextcounter_resp {
- struct s6145_status_hdr hdr;
- uint32_t lifetime_distance; /* Inches */
- uint32_t maint_distance;
- uint32_t head_distance;
- uint8_t reserved[32];
-} __attribute__((packed));
-
-struct s6145_fwinfo_resp {
- struct s6145_status_hdr hdr;
- uint8_t name[8];
- uint8_t type[16];
- uint8_t date[10];
- uint8_t major;
- uint8_t minor;
- uint16_t checksum;
+ struct sinfonia_mediainfo_item items[10]; /* Not all necessarily used */
} __attribute__((packed));
struct s6145_imagecorr_resp {
- struct s6145_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint16_t total_size;
} __attribute__((packed));
@@ -1080,20 +555,8 @@ struct s6145_imagecorr_data {
} __attribute__((packed));
/* Private data structure */
-struct shinkos6145_printjob {
- uint8_t *databuf;
- size_t datalen;
-
- struct s6145_printjob_hdr hdr;
-
- int copies;
-};
-
struct shinkos6145_ctx {
- struct libusb_device_handle *dev;
- uint8_t endp_up;
- uint8_t endp_down;
- int type;
+ struct sinfonia_usbdev dev;
uint8_t jobid;
@@ -1116,152 +579,106 @@ struct shinkos6145_ctx {
static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx);
static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx);
-static int get_param(struct shinkos6145_ctx *ctx, int target, uint32_t *param);
-
-#define READBACK_LEN 512 /* Needs to be larger than largest response hdr */
-#define CMDBUF_LEN sizeof(struct s6145_print_cmd)
-
-uint8_t rdbuf[READBACK_LEN];
-
-static int s6145_do_cmd(struct shinkos6145_ctx *ctx,
- uint8_t *cmd, int cmdlen,
- int minlen, int *num)
-{
- int ret;
- struct s6145_status_hdr *resp = (struct s6145_status_hdr *) rdbuf;
-
- libusb_device_handle *dev = ctx->dev;
- uint8_t endp_up = ctx->endp_up;
- uint8_t endp_down = ctx->endp_down;
-
- if ((ret = send_data(dev, endp_down,
- cmd, cmdlen)))
- return (ret < 0) ? ret : -99;
-
- ret = read_data(dev, endp_up,
- rdbuf, READBACK_LEN, num);
-
- if (ret < 0)
- return ret;
- if (*num < minlen) {
- ERROR("Short read! (%d/%d))\n", *num, minlen);
- return -99;
- }
-
- if (resp->result != RESULT_SUCCESS) {
- INFO("Printer Status: %02x (%s)\n", resp->status,
- status_str(resp->status));
- INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
- resp->result, resp->error, resp->printer_major,
- resp->printer_minor, error_codes(resp->printer_major, resp->printer_minor));
- return -99;
- }
-
- return ret;
-}
static int get_status(struct shinkos6145_ctx *ctx)
{
- struct s6145_cmd_hdr cmd;
- struct s6145_status_resp *resp = (struct s6145_status_resp *) rdbuf;
- struct s6145_getextcounter_resp *resp2 = (struct s6145_getextcounter_resp *) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s6145_status_resp resp;
+ struct sinfonia_getextcounter_resp resp2;
int ret, num = 0;
uint32_t val;
- cmd.cmd = cpu_to_le16(S6145_CMD_GETSTATUS);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
- 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));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp), &num)) < 0) {
return ret;
}
- INFO("Printer Status: 0x%02x (%s)\n", resp->hdr.status,
- status_str(resp->hdr.status));
- if (resp->hdr.status == ERROR_PRINTER) {
- if(resp->hdr.error == ERROR_NONE)
- resp->hdr.error = resp->hdr.status;
+ INFO("Printer Status: 0x%02x (%s)\n", resp.hdr.status,
+ sinfonia_status_str(resp.hdr.status));
+ if (resp.hdr.status == ERROR_PRINTER) {
+ if(resp.hdr.error == ERROR_NONE)
+ resp.hdr.error = resp.hdr.status;
INFO(" Error 0x%02x (%s) 0x%02x/0x%02x (%s)\n",
- resp->hdr.error,
- error_str(resp->hdr.error),
- resp->hdr.printer_major,
- resp->hdr.printer_minor, error_codes(resp->hdr.printer_major, resp->hdr.printer_minor));
+ resp.hdr.error,
+ sinfonia_error_str(resp.hdr.error),
+ resp.hdr.printer_major,
+ resp.hdr.printer_minor, error_codes(resp.hdr.printer_major, resp.hdr.printer_minor));
}
- if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s6145_status_resp) - sizeof(struct s6145_status_hdr)))
+ if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct s6145_status_resp) - sizeof(struct sinfonia_status_hdr)))
return -1;
INFO(" Print Counts:\n");
- INFO("\tSince Paper Changed:\t%08u\n", le32_to_cpu(resp->count_paper));
- INFO("\tLifetime:\t\t%08u\n", le32_to_cpu(resp->count_lifetime));
- INFO("\tMaintenance:\t\t%08u\n", le32_to_cpu(resp->count_maint));
- INFO("\tPrint Head:\t\t%08u\n", le32_to_cpu(resp->count_head));
- INFO(" Cutter Actuations:\t%08u\n", le32_to_cpu(resp->count_cutter));
- INFO(" Ribbon Remaining:\t%08u\n", le32_to_cpu(resp->count_ribbon_left));
+ INFO("\tSince Paper Changed:\t%08u\n", le32_to_cpu(resp.count_paper));
+ INFO("\tLifetime:\t\t%08u\n", le32_to_cpu(resp.count_lifetime));
+ INFO("\tMaintenance:\t\t%08u\n", le32_to_cpu(resp.count_maint));
+ INFO("\tPrint Head:\t\t%08u\n", le32_to_cpu(resp.count_head));
+ INFO(" Cutter Actuations:\t%08u\n", le32_to_cpu(resp.count_cutter));
+ INFO(" Ribbon Remaining:\t%08u\n", le32_to_cpu(resp.count_ribbon_left));
INFO("Bank 1: 0x%02x (%s) Job %03u @ %03u/%03u (%03u remaining)\n",
- resp->bank1_status, bank_statuses(resp->bank1_status),
- resp->bank1_printid,
- le16_to_cpu(resp->bank1_finished),
- le16_to_cpu(resp->bank1_specified),
- le16_to_cpu(resp->bank1_remaining));
+ resp.bank1_status, sinfonia_bank_statuses(resp.bank1_status),
+ resp.bank1_printid,
+ le16_to_cpu(resp.bank1_finished),
+ le16_to_cpu(resp.bank1_specified),
+ le16_to_cpu(resp.bank1_remaining));
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),
- le16_to_cpu(resp->bank2_specified),
- le16_to_cpu(resp->bank2_remaining));
+ resp.bank2_status, sinfonia_bank_statuses(resp.bank1_status),
+ resp.bank2_printid,
+ le16_to_cpu(resp.bank2_finished),
+ le16_to_cpu(resp.bank2_specified),
+ le16_to_cpu(resp.bank2_remaining));
- INFO("Tonecurve Status: 0x%02x (%s)\n", resp->tonecurve_status, tonecurve_statuses(resp->tonecurve_status));
+ INFO("Tonecurve Status: 0x%02x (%s)\n", resp.tonecurve_status, sinfonia_tonecurve_statuses(resp.tonecurve_status));
/* Query Extended counters */
- cmd.cmd = cpu_to_le16(S6145_CMD_EXTCOUNTER);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_EXTCOUNTER);
cmd.len = cpu_to_le16(0);
- if ((ret = s6145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp2),
- &num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp2, sizeof(resp2),
+ &num)) < 0) {
return ret;
}
- if (le16_to_cpu(resp2->hdr.payload_len) != (sizeof(struct s6145_getextcounter_resp) - sizeof(struct s6145_status_hdr)))
+ if (le16_to_cpu(resp2.hdr.payload_len) != (sizeof(struct sinfonia_getextcounter_resp) - sizeof(struct sinfonia_status_hdr)))
return -1;
- INFO("Lifetime Distance: %08u inches\n", le32_to_cpu(resp2->lifetime_distance));
- INFO("Maintenance Distance: %08u inches\n", le32_to_cpu(resp2->maint_distance));
- INFO("Head Distance: %08u inches\n", le32_to_cpu(resp2->head_distance));
+ INFO("Lifetime Distance: %08u inches\n", le32_to_cpu(resp2.lifetime_distance));
+ INFO("Maintenance Distance: %08u inches\n", le32_to_cpu(resp2.maint_distance));
+ INFO("Head Distance: %08u inches\n", le32_to_cpu(resp2.head_distance));
/* Query various params */
- if (ctx->type == P_SHINKO_S6145D) {
- if ((ret = get_param(ctx, PARAM_REGION_CODE, &val))) {
+ if (ctx->dev.type == P_SHINKO_S6145D) {
+ if ((ret = sinfonia_getparam(&ctx->dev, 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))) {
+ if ((ret = sinfonia_getparam(&ctx->dev, PARAM_PAPER_PRESV, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
INFO("Paper Preserve mode: %s\n", (val ? "On" : "Off"));
- if ((ret = get_param(ctx, PARAM_DRIVER_MODE, &val))) {
+ if ((ret = sinfonia_getparam(&ctx->dev, PARAM_DRIVER_MODE, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
INFO("Driver mode: %s\n", (val ? "On" : "Off"));
- if ((ret = get_param(ctx, PARAM_PAPER_MODE, &val))) {
+ if ((ret = sinfonia_getparam(&ctx->dev, PARAM_PAPER_MODE, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
INFO("Paper load mode: %s\n", (val ? "Cut" : "No Cut"));
- if ((ret = get_param(ctx, PARAM_SLEEP_TIME, &val))) {
+ if ((ret = sinfonia_getparam(&ctx->dev, PARAM_SLEEP_TIME, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
@@ -1285,77 +702,6 @@ static int get_status(struct shinkos6145_ctx *ctx)
return 0;
}
-static int get_fwinfo(struct shinkos6145_ctx *ctx)
-{
- struct s6145_fwinfo_cmd cmd;
- struct s6145_fwinfo_resp *resp = (struct s6145_fwinfo_resp *)rdbuf;
- int num = 0;
- int i;
-
- cmd.hdr.cmd = cpu_to_le16(S6145_CMD_FWINFO);
- cmd.hdr.len = cpu_to_le16(1);
-
- INFO("FW Information:\n");
-
- for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_PRINT_TABLES ; i++) {
- int ret;
- cmd.target = i;
-
- if ((ret = s6145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
- &num)) < 0) {
- ERROR("Failed to execute %s command (%d)\n", cmd_names(cmd.hdr.cmd), ret);
- continue;
- }
-
- if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s6145_fwinfo_resp) - sizeof(struct s6145_status_hdr)))
- continue;
-
- INFO(" %s\t ver %02x.%02x\n", fwinfo_targets(i),
- resp->major, resp->minor);
-#if 0
- INFO(" name: '%s'\n", resp->name);
- INFO(" type: '%s'\n", resp->type);
- INFO(" date: '%s'\n", resp->date);
- INFO(" version: %02x.%02x (CRC %04x)\n", resp->major, resp->minor,
- le16_to_cpu(resp->checksum));
-#endif
- }
- return 0;
-}
-
-static int get_errorlog(struct shinkos6145_ctx *ctx)
-{
- struct s6145_cmd_hdr cmd;
- struct s6145_errorlog_resp *resp = (struct s6145_errorlog_resp *) rdbuf;
- int ret, num = 0;
- int i;
-
- cmd.cmd = cpu_to_le16(S6145_CMD_ERRORLOG);
- cmd.len = cpu_to_le16(0);
-
- 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));
- return ret;
- }
-
- if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s6145_errorlog_resp) - sizeof(struct s6145_status_hdr)))
- return -2;
-
- 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,
- error_codes(resp->items[i].major, resp->items[i].minor));
- }
- return 0;
-}
-
static void dump_mediainfo(struct s6145_mediainfo_resp *resp)
{
int i;
@@ -1364,126 +710,13 @@ static void dump_mediainfo(struct s6145_mediainfo_resp *resp)
INFO("Supported Print Sizes: %u entries:\n", resp->count);
for (i = 0 ; i < resp->count ; i++) {
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));
- }
-}
-
-static int cancel_job(struct shinkos6145_ctx *ctx, char *str)
-{
- struct s6145_cancel_cmd cmd;
- struct s6145_status_hdr *resp = (struct s6145_status_hdr *) rdbuf;
- int ret, num = 0;
-
- if (!str)
- return -1;
-
- cmd.id = atoi(str);
-
- cmd.hdr.cmd = cpu_to_le16(S6145_CMD_CANCELJOB);
- cmd.hdr.len = cpu_to_le16(1);
-
- 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.hdr.cmd));
- return ret;
+ resp->items[i].code,
+ sinfonia_print_codes(resp->items[i].code, 0),
+ resp->items[i].columns,
+ resp->items[i].rows,
+ resp->items[i].method,
+ sinfonia_print_methods(resp->items[i].method));
}
-
- return 0;
-}
-
-static int flash_led(struct shinkos6145_ctx *ctx)
-{
- struct s6145_cmd_hdr cmd;
- struct s6145_status_hdr *resp = (struct s6145_status_hdr *) rdbuf;
- int ret, num = 0;
-
- cmd.cmd = cpu_to_le16(S6145_CMD_FLASHLED);
- cmd.len = cpu_to_le16(0);
-
- 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));
- return ret;
- }
-
- return 0;
-}
-
-
-static int set_param(struct shinkos6145_ctx *ctx, int target, uint32_t param)
-{
- struct s6145_setparam_cmd cmd;
- struct s6145_status_hdr *resp = (struct s6145_status_hdr *) rdbuf;
- int ret, num = 0;
-
- /* Set up command */
- cmd.target = target;
- cmd.param = cpu_to_le32(param);
-
- cmd.hdr.cmd = cpu_to_le16(S6145_CMD_SETPARAM);
- cmd.hdr.len = cpu_to_le16(sizeof(struct s6145_setparam_cmd)-sizeof(cmd.hdr));
-
- if ((ret = s6145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
- &num)) < 0) {
- ERROR("Failed to execute %s command (%d)\n", cmd_names(cmd.hdr.cmd), ret);
- }
-
- return ret;
-}
-
-static int get_param(struct shinkos6145_ctx *ctx, int target, uint32_t *param)
-{
- struct s6145_getparam_cmd cmd;
- struct s6145_getparam_resp *resp = (struct s6145_getparam_resp *) rdbuf;
- int ret, num = 0;
-
- /* Set up command */
- cmd.target = target;
-
- cmd.hdr.cmd = cpu_to_le16(S6145_CMD_GETPARAM);
- cmd.hdr.len = cpu_to_le16(sizeof(struct s6145_getparam_cmd)-sizeof(cmd.hdr));
-
- if ((ret = s6145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
- &num)) < 0) {
- ERROR("Failed to execute %s command (%d)\n", cmd_names(cmd.hdr.cmd), ret);
- }
- *param = le32_to_cpu(resp->param);
-
- return ret;
-}
-
-
-static int reset_curve(struct shinkos6145_ctx *ctx, int target)
-{
- struct s6145_reset_cmd cmd;
- struct s6145_status_hdr *resp = (struct s6145_status_hdr *) rdbuf;
- int ret, num = 0;
-
- cmd.target = target;
-
- cmd.hdr.cmd = cpu_to_le16(S6145_CMD_RESET);
- cmd.hdr.len = cpu_to_le16(1);
-
- 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.hdr.cmd));
- return ret;
- }
-
- return 0;
}
static int shinkos6145_dump_corrdata(struct shinkos6145_ctx *ctx, char *fname)
@@ -1504,7 +737,7 @@ static int shinkos6145_dump_corrdata(struct shinkos6145_ctx *ctx, char *fname)
return fd;
}
- write(fd, ctx->corrdata, sizeof(struct shinkos6145_correctionparam));
+ ret = write(fd, ctx->corrdata, sizeof(struct shinkos6145_correctionparam));
close(fd);
}
@@ -1534,7 +767,7 @@ static int shinkos6145_dump_eeprom(struct shinkos6145_ctx *ctx, char *fname)
return fd;
}
- write(fd, ctx->eeprom, ctx->eepromlen);
+ ret = write(fd, ctx->eeprom, ctx->eepromlen);
close(fd);
}
@@ -1546,152 +779,14 @@ static int shinkos6145_dump_eeprom(struct shinkos6145_ctx *ctx, char *fname)
return ret;
}
-static int get_tonecurve(struct shinkos6145_ctx *ctx, int type, char *fname)
-{
- struct s6145_readtone_cmd cmd;
- struct s6145_readtone_resp *resp = (struct s6145_readtone_resp *) rdbuf;
- int ret, num = 0;
-
- uint8_t *data;
- uint16_t curves[UPDATE_SIZE] = { 0 };
-
- int i,j;
-
- cmd.target = type;
- cmd.curveid = TONE_CURVE_ID;
-
- cmd.hdr.cmd = cpu_to_le16(S6145_CMD_READTONE);
- cmd.hdr.len = cpu_to_le16(1);
-
- INFO("Dump %s Tone Curve to '%s'\n", tonecurve_statuses(type), fname);
-
- 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.hdr.cmd));
- return ret;
- }
-
- resp->total_size = le16_to_cpu(resp->total_size);
-
- data = malloc(resp->total_size * 2);
- if (!data) {
- ERROR("Memory Allocation Failure!\n");
- return -1;
- }
-
- i = 0;
- while (i < resp->total_size) {
- ret = read_data(ctx->dev, ctx->endp_up,
- data + i,
- resp->total_size * 2 - i,
- &num);
- if (ret < 0)
- goto done;
- i += num;
- }
-
- i = j = 0;
- while (i < resp->total_size) {
- memcpy(curves + j, data + i+2, data[i+1]);
- j += data[i+1] / 2;
- i += data[i+1] + 2;
- }
-
- /* Open file and write it out */
- {
- int tc_fd = open(fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
- if (tc_fd < 0) {
- ret = -1;
- goto done;
- }
-
- for (i = 0 ; i < UPDATE_SIZE; i++) {
- /* Byteswap appropriately */
- curves[i] = cpu_to_be16(le16_to_cpu(curves[i]));
- }
- write(tc_fd, curves, UPDATE_SIZE * sizeof(uint16_t));
- close(tc_fd);
- }
-
-done:
- free(data);
- return ret;
-}
-
-static int set_tonecurve(struct shinkos6145_ctx *ctx, int target, char *fname)
-{
- struct s6145_update_cmd cmd;
- struct s6145_status_hdr *resp = (struct s6145_status_hdr *) rdbuf;
- int ret, num = 0;
-
- INFO("Set %s Tone Curve from '%s'\n", update_targets(target), fname);
-
- uint16_t *data = malloc(UPDATE_SIZE * sizeof(uint16_t));
- if (!data) {
- ERROR("Memory Allocation Failure!\n");
- return -1;
- }
-
- /* Read in file */
- int tc_fd = open(fname, O_RDONLY);
- if (tc_fd < 0) {
- ret = -1;
- goto done;
- }
- if (read(tc_fd, data, UPDATE_SIZE * sizeof(uint16_t)) != (UPDATE_SIZE * sizeof(uint16_t))) {
- ret = -2;
- goto done;
- }
- close(tc_fd);
- /* Byteswap data to local CPU.. */
- for (ret = 0; ret < UPDATE_SIZE ; ret++) {
- data[ret] = be16_to_cpu(data[ret]);
- }
-
- /* Set up command */
- cmd.target = target;
- cmd.reserved[0] = cmd.reserved[1] = cmd.reserved[2] = 0;
- cmd.reset = 0;
- cmd.size = cpu_to_le32(UPDATE_SIZE * sizeof(uint16_t));
-
- cmd.hdr.cmd = cpu_to_le16(S6145_CMD_UPDATE);
- cmd.hdr.len = cpu_to_le16(sizeof(struct s6145_update_cmd)-sizeof(cmd.hdr));
-
- /* Byteswap data to format printer is expecting.. */
- for (ret = 0; ret < UPDATE_SIZE ; ret++) {
- data[ret] = cpu_to_le16(data[ret]);
- }
-
- 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.hdr.cmd));
- goto done;
- }
-
- /* Sent transfer */
- if ((ret = send_data(ctx->dev, ctx->endp_down,
- (uint8_t *) data, UPDATE_SIZE * sizeof(uint16_t)))) {
- goto done;
- }
-
-done:
- free(data);
-
- return ret;
-}
-
static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx)
{
- struct s6145_cmd_hdr cmd;
- struct s6145_imagecorr_resp *resp = (struct s6145_imagecorr_resp *) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s6145_imagecorr_resp resp;
size_t total = 0;
int ret, num;
- cmd.cmd = cpu_to_le16(S6145_CMD_GETCORR);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETCORR);
cmd.len = 0;
if (ctx->corrdata) {
@@ -1699,15 +794,14 @@ static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx)
ctx->corrdata = 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));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
goto done;
}
- ctx->corrdatalen = le16_to_cpu(resp->total_size);
+ ctx->corrdatalen = le16_to_cpu(resp.total_size);
INFO("Fetching %zu bytes of image correction data\n", ctx->corrdatalen);
ctx->corrdata = malloc(sizeof(struct shinkos6145_correctionparam));
@@ -1722,7 +816,7 @@ static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx)
while (total < ctx->corrdatalen) {
struct s6145_imagecorr_data data;
- ret = read_data(ctx->dev, ctx->endp_up, (uint8_t *) &data,
+ ret = read_data(ctx->dev.dev, ctx->dev.endp_up, (uint8_t *) &data,
sizeof(data),
&num);
if (ret < 0)
@@ -1743,11 +837,11 @@ done:
static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx)
{
- struct s6145_cmd_hdr cmd;
- struct s6145_geteeprom_resp *resp = (struct s6145_geteeprom_resp *) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s6145_geteeprom_resp resp;
int ret, num;
- cmd.cmd = cpu_to_le16(S6145_CMD_GETEEPROM);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETEEPROM);
cmd.len = 0;
if (ctx->eeprom) {
@@ -1755,22 +849,21 @@ static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx)
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));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
goto done;
}
- ctx->eepromlen = le16_to_cpu(resp->hdr.payload_len);
+ 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);
+ memcpy(ctx->eeprom, resp.data, ctx->eepromlen);
done:
return ret;
@@ -1803,26 +896,26 @@ 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:q:R:sX:")) >= 0) {
+ while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFik:l:L:mr:Q:q:rR:sX:")) >= 0) {
switch(i) {
GETOPT_PROCESS_GLOBAL
case 'c':
- j = get_tonecurve(ctx, TONECURVE_USER, optarg);
+ j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'C':
- j = set_tonecurve(ctx, TONECURVE_USER, optarg);
+ j = sinfonia_settonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'e':
- j = get_errorlog(ctx);
+ j = sinfonia_geterrorlog(&ctx->dev);
break;
case 'F':
- j = flash_led(ctx);
+ j = sinfonia_flashled(&ctx->dev);
break;
case 'i':
- j = get_fwinfo(ctx);
+ j = sinfonia_getfwinfo(&ctx->dev);
break;
case 'k': {
- uint32_t i = atoi(optarg);
+ i = atoi(optarg);
if (i <= 5)
i = 0;
else if (i <= 15)
@@ -1838,14 +931,14 @@ int shinkos6145_cmdline_arg(void *vctx, int argc, char **argv)
else
i = 5;
- j = set_param(ctx, PARAM_SLEEP_TIME, i);
+ j = sinfonia_setparam(&ctx->dev, PARAM_SLEEP_TIME, i);
break;
}
case 'l':
- j = get_tonecurve(ctx, TONECURVE_CURRENT, optarg);
+ j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'L':
- j = set_tonecurve(ctx, TONECURVE_CURRENT, optarg);
+ j = sinfonia_settonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'm':
dump_mediainfo(&ctx->media);
@@ -1857,16 +950,16 @@ int shinkos6145_cmdline_arg(void *vctx, int argc, char **argv)
j = shinkos6145_dump_corrdata(ctx, optarg);
break;
case 'r':
- j = reset_curve(ctx, RESET_TONE_CURVE);
+ j = sinfonia_resetcurve(&ctx->dev, RESET_TONE_CURVE, TONE_CURVE_ID);
break;
case 'R':
- j = reset_curve(ctx, RESET_PRINTER);
+ j = sinfonia_resetcurve(&ctx->dev, RESET_PRINTER, 0);
break;
case 's':
j = get_status(ctx);
break;
case 'X':
- j = cancel_job(ctx, optarg);
+ j = sinfonia_canceljob(&ctx->dev, atoi(optarg));
break;
default:
break; /* Ignore completely */
@@ -1897,10 +990,11 @@ static int shinkos6145_attach(void *vctx, struct libusb_device_handle *dev, int
{
struct shinkos6145_ctx *ctx = vctx;
- ctx->dev = dev;
- ctx->endp_up = endp_up;
- ctx->endp_down = endp_down;
- ctx->type = type;
+ ctx->dev.dev = dev;
+ ctx->dev.endp_up = endp_up;
+ ctx->dev.endp_down = endp_down;
+ ctx->dev.type = type;
+ ctx->dev.error_codes = &error_codes;
/* Attempt to open the library */
#if defined(WITH_DYNAMIC)
@@ -1926,22 +1020,31 @@ static int shinkos6145_attach(void *vctx, struct libusb_device_handle *dev, int
#endif
/* Ensure jobid is sane */
- ctx->jobid = (jobid & 0x7f) + 1;
+ ctx->jobid = (jobid & 0x7f);
+ if (!ctx->jobid)
+ ctx->jobid++;
if (test_mode < TEST_MODE_NOATTACH) {
/* Query Media */
- struct s6145_mediainfo_resp *resp = (struct s6145_mediainfo_resp *) rdbuf;
- struct s6145_cmd_hdr cmd;
+ struct sinfonia_cmd_hdr cmd;
int num;
- if (s6145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp),
- &num)) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_MEDIAINFO);
+ cmd.len = cpu_to_le16(0);
+
+ if (sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&ctx->media, sizeof(ctx->media),
+ &num)) {
return CUPS_BACKEND_FAILED;
}
- memcpy(&ctx->media, resp, sizeof(*resp));
+
+ /* Byteswap media descriptor.. */
+ int i;
+ for (i = 0 ; i < ctx->media.count ; i++) {
+ ctx->media.items[i].columns = le16_to_cpu(ctx->media.items[i].columns);
+ ctx->media.items[i].rows = le16_to_cpu(ctx->media.items[i].rows);
+ }
} else {
int media_code = RIBBON_6x8;
if (getenv("MEDIA_CODE"))
@@ -1958,16 +1061,6 @@ static int shinkos6145_attach(void *vctx, struct libusb_device_handle *dev, int
return CUPS_BACKEND_OK;
}
-static void shinkos6145_cleanup_job(const void *vjob)
-{
- const struct shinkos6145_printjob *job = vjob;
-
- if (job->databuf)
- free(job->databuf);
-
- free((void*)job);
-}
-
static void shinkos6145_teardown(void *vctx) {
struct shinkos6145_ctx *ctx = vctx;
@@ -1987,7 +1080,7 @@ static void shinkos6145_teardown(void *vctx) {
}
static void lib6145_calc_avg(struct shinkos6145_ctx *ctx,
- const struct shinkos6145_printjob *job,
+ const struct sinfonia_printjob *job,
uint16_t rows, uint16_t cols)
{
uint32_t plane, i, planelen;
@@ -2080,131 +1173,58 @@ static void lib6145_process_image(uint8_t *src, uint16_t *dest,
static int shinkos6145_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct shinkos6145_ctx *ctx = vctx;
+ struct sinfonia_printjob *job = NULL;
int ret;
- uint8_t tmpbuf[4];
+ int model;
uint8_t input_ymc;
- struct shinkos6145_printjob *job = NULL;
-
if (!ctx)
return CUPS_BACKEND_FAILED;
+ if (ctx->dev.type == P_SHINKO_S6145 ||
+ ctx->dev.type == P_SHINKO_S6145D)
+ model = 6145;
+ else
+ model = 2245;
+
job = malloc(sizeof(*job));
if (!job) {
ERROR("Memory allocation failure!\n");
return CUPS_BACKEND_RETRY_CURRENT;
}
memset(job, 0, sizeof(*job));
- job->copies = copies; // XXX hdr.copies?
-
- /* Read in then validate header */
- ret = read(data_fd, &job->hdr, sizeof(job->hdr));
- if (ret < 0 || ret != sizeof(job->hdr)) {
- shinkos6145_cleanup_job(job);
- if (ret == 0)
- return CUPS_BACKEND_CANCEL;
- ERROR("Read failed (%d/%d/%d)\n",
- ret, 0, (int)sizeof(job->hdr));
- perror("ERROR: Read failed");
- return ret;
- }
-#define SWAP_HDR(__x) job->hdr.__x = le32_to_cpu(job->hdr.__x)
-
- SWAP_HDR(len1);
- SWAP_HDR(model);
- SWAP_HDR(media_w);
- SWAP_HDR(len2);
- SWAP_HDR(media);
- SWAP_HDR(method);
- SWAP_HDR(qual);
- SWAP_HDR(oc_mode);
- SWAP_HDR(columns);
- SWAP_HDR(rows);
- SWAP_HDR(copies);
- SWAP_HDR(dpi);
- SWAP_HDR(ext_flags);
-
-#undef SWAP_HDR
-
- if (job->hdr.len1 != 0x10 ||
- job->hdr.len2 != 0x64 ||
- job->hdr.dpi != 300) {
- ERROR("Unrecognized header data format!\n");
- shinkos6145_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
+ /* Common read/parse code */
+ if (ctx->dev.type == P_KODAK_6900) {
+ ret = sinfonia_raw28_read_parse(data_fd, job);
+ } else {
+ ret = sinfonia_read_parse(data_fd, model, job);
}
-
- if (job->hdr.model != 6145) {
- ERROR("Unrecognized printer (%u)!\n", job->hdr.model);
- shinkos6145_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
+ if (ret) {
+ free(job);
+ return ret;
}
- if (!job->hdr.rows || !job->hdr.columns) {
- ERROR("Bad print job header!\n");
- shinkos6145_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
- }
+ if (job->jp.copies > 1)
+ job->copies = job->jp.copies;
+ else
+ job->copies = copies;
/* Extended spool format to re-purpose an unused header field.
When bit 0 is set, this tells the backend that the data is
already in planar YMC format (vs packed RGB) so we don't need
to do the conversion ourselves. Saves some processing overhead */
- input_ymc = job->hdr.ext_flags & 0x01;
-
- job->datalen = job->hdr.rows * job->hdr.columns * 3;
- job->databuf = malloc(job->datalen);
- if (!job->databuf) {
- ERROR("Memory allocation failure!\n");
- shinkos6145_cleanup_job(job);
- return CUPS_BACKEND_RETRY_CURRENT;
- }
-
- {
- int remain = job->datalen;
- uint8_t *ptr = job->databuf;
- do {
- ret = read(data_fd, ptr, remain);
- if (ret < 0) {
- ERROR("Read failed (%d/%d/%zu)\n",
- ret, remain, job->datalen);
- perror("ERROR: Read failed");
- shinkos6145_cleanup_job(job);
- return ret;
- }
- ptr += ret;
- remain -= ret;
- } while (remain);
- }
-
- /* Make sure footer is sane too */
- ret = read(data_fd, tmpbuf, 4);
- if (ret != 4) {
- ERROR("Read failed (%d/%d/%d)\n",
- ret, 4, 4);
- perror("ERROR: Read failed");
- shinkos6145_cleanup_job(job);
- return ret;
- }
- if (tmpbuf[0] != 0x04 ||
- tmpbuf[1] != 0x03 ||
- tmpbuf[2] != 0x02 ||
- tmpbuf[3] != 0x01) {
- ERROR("Unrecognized footer data format!\n");
- shinkos6145_cleanup_job(job);
- return CUPS_BACKEND_FAILED;
- }
+ input_ymc = job->jp.ext_flags & 0x01;
/* Convert packed RGB to planar YMC if necessary */
if (!input_ymc) {
INFO("Converting Packed RGB to Planar YMC\n");
- int planelen = job->hdr.columns * job->hdr.rows;
+ int planelen = job->jp.columns * job->jp.rows;
uint8_t *databuf3 = malloc(job->datalen);
int i;
if (!databuf3) {
ERROR("Memory allocation failure!\n");
- shinkos6145_cleanup_job(job);
+ sinfonia_cleanup_job(job);
return CUPS_BACKEND_RETRY_CURRENT;
}
for (i = 0 ; i < planelen ; i++) {
@@ -2234,49 +1254,29 @@ static int shinkos6145_main_loop(void *vctx, const void *vjob) {
struct shinkos6145_ctx *ctx = vctx;
int ret, num;
- uint8_t cmdbuf[CMDBUF_LEN];
- uint8_t rdbuf2[READBACK_LEN];
int i, last_state = -1, state = S_IDLE;
- struct s6145_cmd_hdr *cmd = (struct s6145_cmd_hdr *) cmdbuf;
- struct s6145_print_cmd *print = (struct s6145_print_cmd *) cmdbuf;
- struct s6145_status_resp *sts = (struct s6145_status_resp *) rdbuf;
- struct s6145_mediainfo_resp *media = (struct s6145_mediainfo_resp *) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s6145_status_resp sts, sts2;
uint32_t cur_mode;
- struct shinkos6145_printjob *job = (struct shinkos6145_printjob*) vjob; /* XXX stupid, we can't do this. */
+ struct sinfonia_printjob *job = (struct sinfonia_printjob*) vjob; /* XXX stupid, we can't do this. */
if (!job)
return CUPS_BACKEND_FAILED;
- /* Send Media Query */
- memset(cmdbuf, 0, CMDBUF_LEN);
- cmd->cmd = cpu_to_le16(S6145_CMD_MEDIAINFO);
- cmd->len = cpu_to_le16(0);
-
- if ((ret = s6145_do_cmd(ctx,
- cmdbuf, sizeof(*cmd),
- sizeof(*media),
- &num)) < 0) {
- 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;
-
/* Validate print sizes */
- for (i = 0; i < media->count ; i++) {
+ for (i = 0; i < ctx->media.count ; i++) {
/* Look for matching media */
- if (le16_to_cpu(media->items[i].columns) == job->hdr.columns &&
- le16_to_cpu(media->items[i].rows) == job->hdr.rows &&
- media->items[i].print_method == job->hdr.method &&
- media->items[i].media_code == job->hdr.media)
+ if (ctx->media.items[i].columns == job->jp.columns &&
+ ctx->media.items[i].rows == job->jp.rows &&
+ ctx->media.items[i].method == job->jp.method &&
+ ctx->media.items[i].code == job->jp.media)
break;
}
- if (i == media->count) {
+ if (i == ctx->media.count) {
ERROR("Incorrect media loaded for print!\n");
return CUPS_BACKEND_HOLD;
}
@@ -2284,7 +1284,7 @@ static int shinkos6145_main_loop(void *vctx, const void *vjob) {
// XXX check copies against remaining media?
/* Query printer mode */
- ret = get_param(ctx, PARAM_OC_PRINT, &cur_mode);
+ ret = sinfonia_getparam(&ctx->dev, PARAM_OC_PRINT, &cur_mode);
if (ret) {
ERROR("Failed to execute command\n");
return ret;
@@ -2297,32 +1297,30 @@ top:
}
/* Send Status Query */
- memset(cmdbuf, 0, CMDBUF_LEN);
- cmd->cmd = cpu_to_le16(S6145_CMD_GETSTATUS);
- cmd->len = cpu_to_le16(0);
-
- if ((ret = s6145_do_cmd(ctx,
- cmdbuf, sizeof(*cmd),
- sizeof(struct s6145_status_hdr),
- &num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd));
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
+ cmd.len = cpu_to_le16(0);
+
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&sts, sizeof(sts),
+ &num)) < 0) {
return CUPS_BACKEND_FAILED;
}
- if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) {
- memcpy(rdbuf2, rdbuf, READBACK_LEN);
+ if (memcmp(&sts, &sts2, sizeof(sts))) {
+ memcpy(&sts2, &sts, sizeof(sts));
INFO("Printer Status: 0x%02x (%s)\n",
- sts->hdr.status, status_str(sts->hdr.status));
+ sts.hdr.status, sinfonia_status_str(sts.hdr.status));
- if (ctx->marker.levelnow != (int)sts->count_ribbon_left) {
- ctx->marker.levelnow = sts->count_ribbon_left;
+ if (ctx->marker.levelnow != (int)sts.count_ribbon_left) {
+ ctx->marker.levelnow = sts.count_ribbon_left;
dump_markers(&ctx->marker, 1, 0);
}
- if (sts->hdr.result != RESULT_SUCCESS)
+ if (sts.hdr.result != RESULT_SUCCESS)
goto printer_error;
- if (sts->hdr.status == ERROR_PRINTER)
+ if (sts.hdr.status == ERROR_PRINTER)
goto printer_error;
} else if (state == last_state) {
sleep(1);
@@ -2336,15 +1334,15 @@ top:
case S_IDLE:
INFO("Waiting for printer idle\n");
/* 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: {
/* Set matte/etc */
- uint32_t oc_mode = job->hdr.oc_mode;
+ uint32_t oc_mode = job->jp.oc_mode;
uint32_t updated = 0;
if (!oc_mode) /* if nothing set, default to glossy */
@@ -2354,13 +1352,13 @@ top:
/* If cur_mode is not the same as desired oc_mode,
change it -- but we have to wait until the printer
is COMPLETELY idle */
- 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) {
INFO("Need to switch overcoat mode, waiting for printer idle\n");
sleep(1);
goto top;
}
- ret = set_param(ctx, PARAM_OC_PRINT, oc_mode);
+ ret = sinfonia_setparam(&ctx->dev, PARAM_OC_PRINT, oc_mode);
if (ret) {
ERROR("Failed to execute command\n");
return ret;
@@ -2385,19 +1383,19 @@ top:
/* Set up library transform... */
uint32_t newlen = le16_to_cpu(ctx->corrdata->headDots) *
- job->hdr.rows * sizeof(uint16_t) * 4;
+ job->jp.rows * sizeof(uint16_t) * 4;
uint16_t *databuf2 = malloc(newlen);
/* Set the size in the correctiondata */
- ctx->corrdata->width = cpu_to_le16(job->hdr.columns);
- ctx->corrdata->height = cpu_to_le16(job->hdr.rows);
+ ctx->corrdata->width = cpu_to_le16(job->jp.columns);
+ ctx->corrdata->height = cpu_to_le16(job->jp.rows);
/* Perform the actual library transform */
if (ctx->dl_handle) {
INFO("Calling image processing library...\n");
- if (ctx->ImageAvrCalc(job->databuf, job->hdr.columns, job->hdr.rows, ctx->image_avg)) {
+ if (ctx->ImageAvrCalc(job->databuf, job->jp.columns, job->jp.rows, ctx->image_avg)) {
free(databuf2);
ERROR("Library returned error!\n");
return CUPS_BACKEND_FAILED;
@@ -2407,7 +1405,7 @@ top:
WARNING("Utilizing fallback internal image processing code\n");
WARNING(" *** Output quality will be poor! *** \n");
- lib6145_calc_avg(ctx, job, job->hdr.columns, job->hdr.rows);
+ lib6145_calc_avg(ctx, job, job->jp.columns, job->jp.rows);
lib6145_process_image(job->databuf, databuf2, ctx->corrdata, oc_mode);
}
@@ -2415,49 +1413,50 @@ top:
job->databuf = (uint8_t*) databuf2;
job->datalen = newlen;
+ struct s6145_print_cmd print;
+
INFO("Sending print job (internal id %u)\n", ctx->jobid);
- memset(cmdbuf, 0, CMDBUF_LEN);
- print->hdr.cmd = cpu_to_le16(S6145_CMD_PRINTJOB);
- print->hdr.len = cpu_to_le16(sizeof (*print) - sizeof(*cmd));
+ memset(&print, 0, sizeof(print));
+ print.hdr.cmd = cpu_to_le16(SINFONIA_CMD_PRINTJOB);
+ print.hdr.len = cpu_to_le16(sizeof (print) - sizeof(cmd));
- print->id = ctx->jobid;
- print->count = cpu_to_le16(job->copies);
- print->columns = cpu_to_le16(job->hdr.columns);
- print->rows = cpu_to_le16(job->hdr.rows);
- print->image_avg = ctx->image_avg[2]; /* Cyan level */
- print->method = cpu_to_le32(job->hdr.method);
- print->combo_wait = 0;
+ print.id = ctx->jobid;
+ print.count = cpu_to_le16(job->copies);
+ print.columns = cpu_to_le16(job->jp.columns);
+ print.rows = cpu_to_le16(job->jp.rows);
+ print.image_avg = ctx->image_avg[2]; /* Cyan level */
+ print.method = cpu_to_le32(job->jp.method);
+ print.combo_wait = 0;
/* Brava21 header has a few quirks */
- if(ctx->type == P_SHINKO_S6145D) {
- print->media = job->hdr.media;
- print->unk_1 = 0x01;
+ if(ctx->dev.type == P_SHINKO_S6145D) {
+ print.media = job->jp.media;
+ print.unk_1 = 0x01;
}
- if ((ret = s6145_do_cmd(ctx,
- cmdbuf, sizeof(*print),
- sizeof(struct s6145_status_hdr),
- &num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(print->hdr.cmd));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&print, sizeof(print),
+ (uint8_t*)&sts, sizeof(sts),
+ &num)) < 0) {
return ret;
}
- if (sts->hdr.result != RESULT_SUCCESS) {
- if (sts->hdr.error == ERROR_BUFFER_FULL) {
+ if (sts.hdr.result != RESULT_SUCCESS) {
+ if (sts.hdr.error == ERROR_BUFFER_FULL) {
INFO("Printer Buffers full, retrying\n");
break;
- } else if ((sts->hdr.status & 0xf0) == 0x30 || sts->hdr.status == 0x21) {
- INFO("Printer busy (%s), retrying\n", status_str(sts->hdr.status));
+ } else if ((sts.hdr.status & 0xf0) == 0x30 || sts.hdr.status == 0x21) {
+ INFO("Printer busy (%s), retrying\n", sinfonia_status_str(sts.hdr.status));
break;
- } else if (sts->hdr.status != ERROR_NONE)
+ } else if (sts.hdr.status != ERROR_NONE)
goto printer_error;
}
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,
+ if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
job->databuf, job->datalen)))
return CUPS_BACKEND_FAILED;
@@ -2470,7 +1469,7 @@ top:
if (fast_return) {
INFO("Fast return mode enabled.\n");
state = S_FINISHED;
- } else if (sts->hdr.status == STATUS_READY) {
+ } else if (sts.hdr.status == STATUS_READY) {
state = S_FINISHED;
}
break;
@@ -2487,45 +1486,41 @@ top:
printer_error:
ERROR("Printer reported error: %#x (%s) status: %#x (%s) -> %#x.%#x (%s)\n",
- sts->hdr.error,
- error_str(sts->hdr.error),
- sts->hdr.status,
- status_str(sts->hdr.status),
- sts->hdr.printer_major, sts->hdr.printer_minor,
- error_codes(sts->hdr.printer_major, sts->hdr.printer_minor));
+ sts.hdr.error,
+ sinfonia_error_str(sts.hdr.error),
+ sts.hdr.status,
+ sinfonia_status_str(sts.hdr.status),
+ sts.hdr.printer_major, sts.hdr.printer_minor,
+ error_codes(sts.hdr.printer_major, sts.hdr.printer_minor));
return CUPS_BACKEND_FAILED;
}
static int shinkos6145_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len)
{
- struct s6145_cmd_hdr cmd;
- struct s6145_getserial_resp *resp = (struct s6145_getserial_resp*) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct sinfonia_getserial_resp resp;
int ret, num = 0;
- struct shinkos6145_ctx ctx = {
+ struct sinfonia_usbdev sdev = {
.dev = dev,
.endp_up = endp_up,
.endp_down = endp_down,
};
- cmd.cmd = cpu_to_le16(S6145_CMD_GETSERIAL);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSERIAL);
cmd.len = cpu_to_le16(0);
- if ((ret = s6145_do_cmd(&ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*resp) - 1,
- &num)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if ((ret = sinfonia_docmd(&sdev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
return ret;
}
- /* Null-terminate */
- resp->hdr.payload_len = le16_to_cpu(resp->hdr.payload_len);
- if (resp->hdr.payload_len > 23)
- resp->hdr.payload_len = 23;
- resp->data[resp->hdr.payload_len] = 0;
- strncpy(buf, (char*)resp->data, buf_len);
- buf[buf_len-1] = 0; /* ensure it's null terminated */
+ /* Copy and Null-terminate */
+ num = (buf_len > (int)sizeof(resp.data)) ? (int)sizeof(resp.data) : (buf_len - 1);
+ memcpy(buf, resp.data, num);
+ buf[num] = 0;
return CUPS_BACKEND_OK;
}
@@ -2533,23 +1528,22 @@ static int shinkos6145_query_serno(struct libusb_device_handle *dev, uint8_t end
static int shinkos6145_query_markers(void *vctx, struct marker **markers, int *count)
{
struct shinkos6145_ctx *ctx = vctx;
- struct s6145_cmd_hdr cmd;
- struct s6145_status_resp *sts = (struct s6145_status_resp *) rdbuf;
+ struct sinfonia_cmd_hdr cmd;
+ struct s6145_status_resp sts;
int num;
/* Query Status */
- cmd.cmd = cpu_to_le16(S6145_CMD_GETSTATUS);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
- if (s6145_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(*sts),
- &num)) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if (sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&sts, sizeof(sts),
+ &num)) {
return CUPS_BACKEND_FAILED;
}
- ctx->marker.levelnow = le32_to_cpu(sts->count_ribbon_left);
+ ctx->marker.levelnow = le32_to_cpu(sts.count_ribbon_left);
*markers = &ctx->marker;
*count = 1;
@@ -2561,9 +1555,15 @@ static int shinkos6145_query_markers(void *vctx, struct marker **markers, int *c
#define USB_VID_SHINKO 0x10CE
#define USB_PID_SHINKO_S6145 0x0019
#define USB_PID_SHINKO_S6145D 0x001E /* Aka CIAAT Brava 21 */
+#define USB_PID_SHINKO_S2245 0x0039
+#define USB_VID_KODAK 0x040a
+//#define USB_PID_KODAK_6900 0xXXXX /* Aka S2245-6A */
+#define USB_VID_HITI 0x0D16
+#define USB_PID_HITI_M610 0x0010
static const char *shinkos6145_prefixes[] = {
"sinfonia-chcs6145", "ciaat-brava-21",
+ "sinfonia-chcs2245", "hiti-m610", // "kodak-6900",
// extras
"shinko-chcs6145",
// backwards-compatiblity
@@ -2572,15 +1572,15 @@ static const char *shinkos6145_prefixes[] = {
};
struct dyesub_backend shinkos6145_backend = {
- .name = "Shinko/Sinfonia CHC-S6145/CS2",
- .version = "0.30",
+ .name = "Shinko/Sinfonia CHC-S6145/CS2/S2245/S3",
+ .version = "0.40" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = shinkos6145_prefixes,
.cmdline_usage = shinkos6145_cmdline,
.cmdline_arg = shinkos6145_cmdline_arg,
.init = shinkos6145_init,
.attach = shinkos6145_attach,
.teardown = shinkos6145_teardown,
- .cleanup_job = shinkos6145_cleanup_job,
+ .cleanup_job = sinfonia_cleanup_job,
.read_parse = shinkos6145_read_parse,
.main_loop = shinkos6145_main_loop,
.query_serno = shinkos6145_query_serno,
@@ -2588,6 +1588,9 @@ struct dyesub_backend shinkos6145_backend = {
.devices = {
{ USB_VID_SHINKO, USB_PID_SHINKO_S6145, P_SHINKO_S6145, NULL, "sinfonia-chcs6145"},
{ USB_VID_SHINKO, USB_PID_SHINKO_S6145D, P_SHINKO_S6145D, NULL, "ciaat-brava-21"},
+ { USB_VID_SHINKO, USB_PID_SHINKO_S2245, P_SHINKO_S2245, NULL, "sinfonia-chcs2245"},
+// { USB_VID_KODAK, USB_PID_KODAK_6900, P_SHINKO_S2245, NULL, "sinfonia-chcs6145"},
+ { USB_VID_HITI, USB_PID_HITI_M610, P_SHINKO_S2245, NULL, "hiti-m610"},
{ 0, 0, 0, NULL, NULL}
}
};
diff --git a/src/cups/backend_shinkos6245.c b/src/cups/backend_shinkos6245.c
index 5d75e0d..0fd1af0 100644
--- a/src/cups/backend_shinkos6245.c
+++ b/src/cups/backend_shinkos6245.c
@@ -1,7 +1,7 @@
/*
* Shinko/Sinfonia CHC-S6245 CUPS backend -- libusb-1.0 version
*
- * (c) 2015-2018 Solomon Peachy <pizza@shaftnet.org>
+ * (c) 2015-2019 Solomon Peachy <pizza@shaftnet.org>
*
* Low-level documentation was provided by Sinfonia, Inc. Thank you!
*
@@ -42,7 +42,7 @@
#define BACKEND shinkos6245_backend
#include "backend_common.h"
-
+#include "backend_sinfonia.h"
enum {
S_IDLE = 0,
@@ -51,198 +51,21 @@ enum {
S_FINISHED,
};
-/* Structure of printjob header. All fields are LITTLE ENDIAN */
-struct s6245_printjob_hdr {
- uint32_t len1; /* Fixed at 0x10 */
- uint32_t model; /* Equal to the printer model (eg '6245' or '1245' decimal) */
- uint32_t unk2;
- uint32_t unk3; /* Fixed at 0x01 */
-
- uint32_t len2; /* Fixed at 0x64 */
- uint32_t unk5;
- uint32_t media; // 8x4->8x12
- uint32_t unk6;
-
- uint32_t unk7;
- uint32_t unk7a;
- uint32_t oc_mode; /* 6145/6245 only, Matte/Glossy/None */
- uint32_t unk8;
-
- uint32_t unk9;
- uint32_t columns;
- uint32_t rows;
- uint32_t copies;
-
- uint32_t unk10;
- uint32_t unk11;
- uint32_t unk12;
- uint32_t unk13;
-
- uint32_t unk14;
- uint32_t unk15;
- uint32_t dpi; /* Fixed at '300' (decimal) */
- uint32_t unk16;
-
- uint32_t unk17;
- uint32_t unk18;
- uint32_t unk19;
- uint32_t unk20;
-
- uint32_t unk21;
-} __attribute__((packed));
-
/* Structs for printer */
-struct s6245_cmd_hdr {
- uint16_t cmd;
- uint16_t len; /* Not including this header */
-} __attribute__((packed));
-
-#define S6245_CMD_GETSTATUS 0x0001
-#define S6245_CMD_MEDIAINFO 0x0002
-#define S6245_CMD_ERRORLOG 0x0004
-#define S6245_CMD_GETPARAM 0x0005
-#define S6245_CMD_GETSERIAL 0x0006
-#define S6245_CMD_PRINTSTAT 0x0007
-#define S6245_CMD_EXTCOUNTER 0x0008
-
-#define S6245_CMD_PRINTJOB 0x4001
-#define S6245_CMD_CANCELJOB 0x4002
-#define S6245_CMD_FLASHLED 0x4003
-#define S6245_CMD_RESET 0x4004
-#define S6245_CMD_READTONE 0x4005
-#define S6245_CMD_SETPARAM 0x4007
-
-#define S6245_CMD_GETEEPROM 0x400E
-#define S6245_CMD_SETEEPROM 0x400F
-#define S6245_CMD_SETTIME 0x4011
-
-#define S6245_CMD_FWINFO 0xC003
-#define S6245_CMD_UPDATE 0xC004
-
-static char *cmd_names(uint16_t v) {
- switch (le16_to_cpu(v)) {
- case S6245_CMD_GETSTATUS:
- return "Get Status";
- case S6245_CMD_MEDIAINFO:
- return "Get Media Info";
- case S6245_CMD_ERRORLOG:
- return "Get Error Log";
- case S6245_CMD_GETPARAM:
- return "Get Parameter";
- case S6245_CMD_GETSERIAL:
- return "Get Serial Number";
- case S6245_CMD_PRINTSTAT:
- return "Get Print ID Status";
- case S6245_CMD_EXTCOUNTER:
- return "Get Extended Counters";
- case S6245_CMD_PRINTJOB:
- return "Print";
- case S6245_CMD_CANCELJOB:
- return "Cancel Print";
- case S6245_CMD_FLASHLED:
- return "Flash LEDs";
- case S6245_CMD_RESET:
- return "Reset";
- case S6245_CMD_READTONE:
- return "Read Tone Curve";
- case S6245_CMD_SETPARAM:
- return "Set Parameter";
- case S6245_CMD_GETEEPROM:
- return "Get EEPROM Backup Parameter";
- case S6245_CMD_SETEEPROM:
- return "Set EEPROM Backup Parameter";
- case S6245_CMD_SETTIME:
- return "Time Setting";
- case S6245_CMD_FWINFO:
- return "Get Firmware Info";
- case S6245_CMD_UPDATE:
- return "Update";
- default:
- return "Unknown Command";
- }
-}
-
struct s6245_print_cmd {
- struct s6245_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint8_t id;
uint16_t count;
uint16_t columns;
uint16_t rows;
- uint8_t reserved[8]; // columns and rows repeated, then nulls
+ uint16_t columns2; /* These are necessary for EK8810 */
+ uint16_t rows2; /* */
+ uint8_t reserved[4];
uint8_t mode;
uint8_t method;
uint8_t reserved2;
} __attribute__((packed));
-#define PRINT_MODE_NO_OC 0x01
-#define PRINT_MODE_GLOSSY 0x02
-#define PRINT_MODE_MATTE 0x03
-
-#if 0
-static char *print_modes(uint8_t v) {
- switch (v) {
- case PRINT_MODE_NO_OC:
- return "No Overcoat";
- case PRINT_MODE_GLOSSY:
- return "Glossy";
- case PRINT_MODE_MATTE:
- return "Matte";
- default:
- return "Unknown";
- }
-}
-#endif
-
-#define PRINT_METHOD_STD 0x00
-#define PRINT_METHOD_COMBO_2 0x02
-#define PRINT_METHOD_COMBO_3 0x03
-
-#define PRINT_METHOD_DISABLE_ERR 0x10
-
-static char *print_methods (uint8_t v) {
- switch (v & 0xf) {
- case PRINT_METHOD_STD:
- return "Standard";
- case PRINT_METHOD_COMBO_2:
- return "2up";
- case PRINT_METHOD_COMBO_3:
- return "3up";
- default:
- return "Unknown";
- }
-}
-
-struct s6245_cancel_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t id;
-} __attribute__((packed));
-
-struct s6245_reset_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t target;
- uint8_t curveid;
-} __attribute__((packed));
-
-#define RESET_PRINTER 0x03
-#define RESET_TONE_CURVE 0x04
-
-#define TONE_CURVE_ID 0x01
-
-struct s6245_readtone_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t target;
- uint8_t curveid;
-} __attribute__((packed));
-
-#define READ_TONE_CURVE_USER 0x01
-#define READ_TONE_CURVE_CURR 0x02
-
-struct s6245_setparam_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t target;
- uint32_t param;
-} __attribute__((packed));
-
#define PARAM_DRIVER_MODE 0x3e
#define PARAM_PAPER_MODE 0x3f
#define PARAM_SLEEP_TIME 0x54
@@ -260,13 +83,8 @@ struct s6245_setparam_cmd {
#define PARAM_SLEEP_120MIN 0x00000004
#define PARAM_SLEEP_240MIN 0x00000005
-struct s6245_seteeprom_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t data[256]; /* Maxlen */
-} __attribute__((packed));
-
struct s6245_settime_cmd {
- struct s6245_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint8_t enable; /* 0 or 1 */
uint8_t second;
uint8_t minute;
@@ -277,98 +95,11 @@ struct s6245_settime_cmd {
} __attribute__((packed));
struct s6245_errorlog_cmd {
- struct s6245_cmd_hdr hdr;
+ struct sinfonia_cmd_hdr hdr;
uint16_t index; /* 0 is latest */
} __attribute__((packed));
-struct s6245_getparam_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t target;
-} __attribute__((packed));
-
-struct s6245_getprintidstatus_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t id;
-} __attribute__((packed));
-
-struct s6245_fwinfo_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t target;
-} __attribute__((packed));
-
-#define FWINFO_TARGET_MAIN_BOOT 0x01
-#define FWINFO_TARGET_MAIN_APP 0x02
-#define FWINFO_TARGET_PRINT_TABLES 0x03
-#define FWINFO_TARGET_DSP 0x04
-
-static char *fwinfo_targets (uint8_t v) {
- switch (v) {
- case FWINFO_TARGET_MAIN_BOOT:
- return "Main Boot ";
- case FWINFO_TARGET_MAIN_APP:
- return "Main App ";
- case FWINFO_TARGET_DSP:
- return "DSP ";
- case FWINFO_TARGET_PRINT_TABLES:
- return "Print Tables";
- default:
- return "Unknown ";
- }
-}
-
-struct s6245_update_cmd {
- struct s6245_cmd_hdr hdr;
- uint8_t target;
- uint8_t curve_id;
- uint8_t reset; // ??
- uint8_t reserved[3];
- uint32_t size;
-} __attribute__((packed));
-
-#define UPDATE_TARGET_USER 0x03
-#define UPDATE_TARGET_CURRENT 0x04
-
-static char *update_targets (uint8_t v) {
- switch (v) {
- case UPDATE_TARGET_USER:
- return "User";
- case UPDATE_TARGET_CURRENT:
- return "Current";
- default:
- return "Unknown";
- }
-}
-
-#define UPDATE_SIZE 0x600
-/* Update is three channels, Y, M, C;
- each is 256 entries of 11-bit data padded to 16-bits.
- Printer expects LE data. We use BE data on disk.
-*/
-
-struct s6245_status_hdr {
- uint8_t result;
- uint8_t error;
- uint8_t printer_major;
- uint8_t printer_minor;
- uint8_t reserved[2];
- uint8_t mode;
- uint8_t status;
- uint16_t payload_len;
-} __attribute__((packed));
-
-#define RESULT_SUCCESS 0x01
-#define RESULT_FAIL 0x02
-
-#define ERROR_NONE 0x00
-#define ERROR_INVALID_PARAM 0x01
-#define ERROR_MAIN_APP_INACTIVE 0x02
-#define ERROR_COMMS_TIMEOUT 0x03
-#define ERROR_MAINT_NEEDED 0x04
-#define ERROR_BAD_COMMAND 0x05
-#define ERROR_PRINTER 0x11
-#define ERROR_BUFFER_FULL 0x21
-
-static char *error_codes(uint8_t major, uint8_t minor)
+static const char *error_codes(uint8_t major, uint8_t minor)
{
switch(major) {
case 0x01: /* "Controller Error" */
@@ -583,102 +314,8 @@ static char *error_codes(uint8_t major, uint8_t minor)
}
}
-static char *error_str(uint8_t v) {
- switch (v) {
- case ERROR_NONE:
- return "None";
- case ERROR_INVALID_PARAM:
- return "Invalid Command Parameter";
- case ERROR_MAIN_APP_INACTIVE:
- return "Main App Inactive";
- case ERROR_COMMS_TIMEOUT:
- return "Main Communication Timeout";
- case ERROR_MAINT_NEEDED:
- return "Maintenance Needed";
- case ERROR_BAD_COMMAND:
- return "Inappropriate Command";
- case ERROR_PRINTER:
- return "Printer Error";
- case ERROR_BUFFER_FULL:
- return "Buffer Full";
- default:
- return "Unknown";
- }
-}
-
-#define STATUS_READY 0x00
-#define STATUS_INIT_CPU 0x31
-#define STATUS_INIT_RIBBON 0x32
-#define STATUS_INIT_PAPER 0x33
-#define STATUS_THERMAL_PROTECT 0x34
-#define STATUS_USING_PANEL 0x35
-#define STATUS_SELF_DIAG 0x36
-#define STATUS_DOWNLOADING 0x37
-
-#define STATUS_FEEDING_PAPER 0x61
-#define STATUS_PRE_HEAT 0x62
-#define STATUS_PRINT_Y 0x63
-#define STATUS_BACK_FEED_Y 0x64
-#define STATUS_PRINT_M 0x65
-#define STATUS_BACK_FEED_M 0x66
-#define STATUS_PRINT_C 0x67
-#define STATUS_BACK_FEED_C 0x68
-#define STATUS_PRINT_OP 0x69
-#define STATUS_PAPER_CUT 0x6A
-#define STATUS_PAPER_EJECT 0x6B
-#define STATUS_BACK_FEED_E 0x6C
-
-static char *status_str(uint8_t v) {
- switch (v) {
- case STATUS_READY:
- return "Ready";
- case STATUS_INIT_CPU:
- return "Initializing CPU";
- case STATUS_INIT_RIBBON:
- return "Initializing Ribbon";
- case STATUS_INIT_PAPER:
- return "Loading Paper";
- case STATUS_THERMAL_PROTECT:
- return "Thermal Protection";
- case STATUS_USING_PANEL:
- return "Using Operation Panel";
- case STATUS_SELF_DIAG:
- return "Processing Self Diagnosis";
- case STATUS_DOWNLOADING:
- return "Processing Download";
- case STATUS_FEEDING_PAPER:
- return "Feeding Paper";
- case STATUS_PRE_HEAT:
- return "Pre-Heating";
- case STATUS_PRINT_Y:
- return "Printing Yellow";
- case STATUS_BACK_FEED_Y:
- return "Back-Feeding - Yellow Complete";
- case STATUS_PRINT_M:
- return "Printing Magenta";
- case STATUS_BACK_FEED_M:
- return "Back-Feeding - Magenta Complete";
- case STATUS_PRINT_C:
- return "Printing Cyan";
- case STATUS_BACK_FEED_C:
- return "Back-Feeding - Cyan Complete";
- case STATUS_PRINT_OP:
- return "Laminating";
- case STATUS_PAPER_CUT:
- return "Cutting Paper";
- case STATUS_PAPER_EJECT:
- return "Ejecting Paper";
- case STATUS_BACK_FEED_E:
- return "Back-Feeding - Ejected";
- case ERROR_PRINTER:
- return "Printer Error";
- default:
- return "Unknown";
- }
-}
-
struct s6245_status_resp {
- struct s6245_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint32_t count_lifetime;
uint32_t count_maint;
uint32_t count_paper;
@@ -704,117 +341,35 @@ struct s6245_status_resp {
uint8_t reserved3[6];
} __attribute__((packed));
-#define BANK_STATUS_FREE 0x00
-#define BANK_STATUS_XFER 0x01
-#define BANK_STATUS_FULL 0x02
-#define BANK_STATUS_PRINTING 0x12
-
-static char *bank_statuses(uint8_t v)
-{
- switch (v) {
- case BANK_STATUS_FREE:
- return "Free";
- case BANK_STATUS_XFER:
- return "Xfer";
- case BANK_STATUS_FULL:
- return "Full";
- case BANK_STATUS_PRINTING:
- return "Printing";
- default:
- return "Unknown";
- }
-}
-
-#define TONECURVE_INIT 0x00
-#define TONECURVE_USER 0x01
-#define TONECURVE_CURRENT 0x02
-
-static char *tonecurve_statuses (uint8_t v)
-{
- switch(v) {
- case 0:
- return "Initial";
- case 1:
- return "UserSet";
- case 2:
- return "Current";
- default:
- return "Unknown";
- }
-}
-
struct s6245_geteeprom_resp {
- struct s6245_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint8_t data[256];
} __attribute__((packed));
-struct s6245_readtone_resp {
- struct s6245_status_hdr hdr;
- uint16_t total_size;
-} __attribute__((packed));
-
-struct s6245_mediainfo_item {
- uint8_t media_code;
- uint16_t columns;
- uint16_t rows;
- uint8_t reserved;
- uint8_t print_method; /* PRINT_METHOD_* */
- uint8_t reserved2[3];
-} __attribute__((packed));
-
-#define MEDIA_8x10 0x10
-#define MEDIA_8x12 0x11
-#define MEDIA_8x4 0x20
-#define MEDIA_8x5 0x21
-#define MEDIA_8x6 0x22
-#define MEDIA_8x8 0x23
-#define MEDIA_8x4_2 0x30
-#define MEDIA_8x5_2 0x31
-#define MEDIA_8x6_2 0x32
-#define MEDIA_8x4_3 0x40
-
-static const char *print_sizes (uint8_t v) {
- switch (v) {
- case MEDIA_8x10:
- return "8x10";
- case MEDIA_8x12:
- return "8x12";
- case MEDIA_8x4:
- return "8x4";
- case MEDIA_8x5:
- return "8x5";
- case MEDIA_8x6:
- return "8x6";
- case MEDIA_8x8:
- return "8x8";
- case MEDIA_8x4_2:
- return "8x4*2";
- case MEDIA_8x5_2:
- return "8x5*2";
- case MEDIA_8x6_2:
- return "8x6*2";
- case MEDIA_8x4_3:
- return "8x4*3";
- default:
- return "Unknown";
- }
-}
-
struct s6245_mediainfo_resp {
- struct s6245_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint8_t ribbon_code;
uint8_t reserved;
uint8_t count;
- struct s6245_mediainfo_item items[10]; /* Not all necessarily used */
+ struct sinfonia_mediainfo_item items[10]; /* Not all necessarily used */
} __attribute__((packed));
+#define RIBBON_NONE 0x00
+#define RIBBON_8x10 0x11
+#define RIBBON_8x12 0x12
+
+#define RIBBON_8x10K 0x03 /* XXX GUESS - EK8810 */
+#define RIBBON_8x12K 0x04 /* EK8810 */
+
static const char *ribbon_sizes (uint8_t v) {
switch (v) {
- case 0x00:
+ case RIBBON_NONE:
return "None";
- case 0x11:
+ case RIBBON_8x10:
+ case RIBBON_8x10K:
return "8x10";
- case 0x12:
+ case RIBBON_8x12:
+ case RIBBON_8x12K:
return "8x12";
default:
return "Unknown";
@@ -823,17 +378,21 @@ static const char *ribbon_sizes (uint8_t v) {
static int ribbon_counts (uint8_t v) {
switch (v) {
- case 0x11:
+ case RIBBON_8x10:
return 120;
- case 0x12:
+ case RIBBON_8x12:
return 100;
+ case RIBBON_8x10K:
+ return 250;
+ case RIBBON_8x12K:
+ return 250;
default:
return 120;
}
}
struct s6245_errorlog_resp {
- struct s6245_status_hdr hdr;
+ struct sinfonia_status_hdr hdr;
uint16_t error_count;
uint8_t error_major;
uint8_t error_minor;
@@ -864,62 +423,9 @@ struct s6245_errorlog_resp {
uint8_t reserved5[8];
} __attribute__((packed));
-struct s6245_getparam_resp {
- struct s6245_status_hdr hdr;
- uint32_t param;
-} __attribute__((packed));
-
-struct s6245_getserial_resp {
- struct s6245_status_hdr hdr;
- uint8_t data[8];
-} __attribute__((packed));
-
-struct s6245_getprintidstatus_resp {
- struct s6245_status_hdr hdr;
- uint8_t id;
- uint16_t remaining;
- uint16_t finished;
- uint16_t specified;
- uint16_t status;
-} __attribute__((packed));
-
-#define STATUS_WAITING 0x0000
-#define STATUS_PRINTING 0x0100
-#define STATUS_COMPLETED 0x0200
-#define STATUS_ERROR 0xFFFF
-
-struct s6245_getextcounter_resp {
- struct s6245_status_hdr hdr;
- uint32_t lifetime_distance; /* Inches */
- uint32_t maint_distance;
- uint32_t head_distance;
- uint8_t reserved[32];
-} __attribute__((packed));
-
-struct s6245_fwinfo_resp {
- struct s6245_status_hdr hdr;
- uint8_t name[8];
- uint8_t type[16];
- uint8_t date[10];
- uint8_t major;
- uint8_t minor;
- uint16_t checksum;
-} __attribute__((packed));
-
/* Private data structure */
-struct shinkos6245_printjob {
- uint8_t *databuf;
- int datalen;
- int copies;
-
- struct s6245_printjob_hdr hdr;
-};
-
struct shinkos6245_ctx {
- struct libusb_device_handle *dev;
- uint8_t endp_up;
- uint8_t endp_down;
- int type;
+ struct sinfonia_usbdev dev;
uint8_t jobid;
@@ -928,71 +434,37 @@ struct shinkos6245_ctx {
struct s6245_mediainfo_resp media;
};
-#define READBACK_LEN 512 /* Needs to be larger than largest response hdr */
#define CMDBUF_LEN sizeof(struct s6245_print_cmd)
-static int s6245_do_cmd(struct shinkos6245_ctx *ctx,
- uint8_t *cmd, int cmdlen,
- int buflen,
- int *num, struct s6245_status_hdr *resp)
-{
- libusb_device_handle *dev = ctx->dev;
- uint8_t endp_up = ctx->endp_up;
- uint8_t endp_down = ctx->endp_down;
- int ret;
-
- if ((ret = send_data(dev, endp_down,
- cmd, cmdlen)))
- return (ret < 0) ? ret : -99;
-
- ret = read_data(dev, endp_up,
- (uint8_t *)resp, buflen, num);
-
- if (ret < 0)
- return ret;
-
- if (resp->result != RESULT_SUCCESS) {
- INFO("Printer Status: %02x (%s)\n", resp->status,
- status_str(resp->status));
- INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
- resp->result, resp->error, resp->printer_major,
- resp->printer_minor, error_codes(resp->printer_major, resp->printer_minor));
- return -99;
- }
-
- return ret;
-}
-
static int get_status(struct shinkos6245_ctx *ctx)
{
- struct s6245_cmd_hdr cmd;
+ struct sinfonia_cmd_hdr cmd;
struct s6245_status_resp resp;
- struct s6245_getextcounter_resp resp2;
+ struct sinfonia_getextcounter_resp resp2;
int ret, num = 0;
- cmd.cmd = cpu_to_le16(S6245_CMD_GETSTATUS);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*) &resp, sizeof(resp),
+ &num)) < 0) {
return ret;
}
INFO("Printer Status: 0x%02x (%s)\n", resp.hdr.status,
- status_str(resp.hdr.status));
+ sinfonia_status_str(resp.hdr.status));
if (resp.hdr.status == ERROR_PRINTER) {
if(resp.hdr.error == ERROR_NONE)
resp.hdr.error = resp.hdr.status;
INFO(" Error 0x%02x (%s) 0x%02x/0x%02x (%s)\n",
resp.hdr.error,
- error_str(resp.hdr.error),
+ sinfonia_error_str(resp.hdr.error),
resp.hdr.printer_major,
resp.hdr.printer_minor, error_codes(resp.hdr.printer_major, resp.hdr.printer_minor));
}
- if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct s6245_status_resp) - sizeof(struct s6245_status_hdr)))
+ if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct s6245_status_resp) - sizeof(struct sinfonia_status_hdr)))
return 0;
INFO(" Print Counts:\n");
@@ -1001,35 +473,40 @@ static int get_status(struct shinkos6245_ctx *ctx)
INFO("\tMaintenance:\t\t%08u\n", le32_to_cpu(resp.count_maint));
INFO("\tPrint Head:\t\t%08u\n", le32_to_cpu(resp.count_head));
INFO(" Cutter Actuations:\t%08u\n", le32_to_cpu(resp.count_cutter));
- INFO(" Ribbon Remaining:\t%08u\n", le32_to_cpu(resp.count_ribbon_left));
+ INFO(" Ribbon Remaining:\t%8u%%\n", le32_to_cpu(resp.count_ribbon_left));
+ INFO(" Prints Remaining:\t%8u\n", ribbon_counts(ctx->media.ribbon_code) - le32_to_cpu(resp.count_paper));
INFO("Bank 1: 0x%02x (%s) Job %03u @ %03u/%03u (%03u remaining)\n",
- resp.bank1_status, bank_statuses(resp.bank1_status),
+ resp.bank1_status, sinfonia_bank_statuses(resp.bank1_status),
resp.bank1_printid,
le16_to_cpu(resp.bank1_finished),
le16_to_cpu(resp.bank1_specified),
le16_to_cpu(resp.bank1_remaining));
INFO("Bank 2: 0x%02x (%s) Job %03u @ %03u/%03u (%03u remaining)\n",
- resp.bank2_status, bank_statuses(resp.bank1_status),
+ resp.bank2_status, sinfonia_bank_statuses(resp.bank1_status),
resp.bank2_printid,
le16_to_cpu(resp.bank2_finished),
le16_to_cpu(resp.bank2_specified),
le16_to_cpu(resp.bank2_remaining));
- INFO("Tonecurve Status: 0x%02x (%s)\n", resp.tonecurve_status, tonecurve_statuses(resp.tonecurve_status));
+ INFO("Tonecurve Status: 0x%02x (%s)\n", resp.tonecurve_status, sinfonia_tonecurve_statuses(resp.tonecurve_status));
+
/* Query Extended counters */
- cmd.cmd = cpu_to_le16(S6245_CMD_EXTCOUNTER);
+ if (ctx->dev.type == P_KODAK_8810)
+ return 0; /* Kodak 8810 returns 12 bytes of garbage. */
+
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_EXTCOUNTER);
cmd.len = cpu_to_le16(0);
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp2),
- &num, (void*)&resp2)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp2, sizeof(resp2),
+ &num)) < 0) {
return ret;
}
- if (le16_to_cpu(resp2.hdr.payload_len) != (sizeof(struct s6245_getextcounter_resp) - sizeof(struct s6245_status_hdr)))
+
+ if (le16_to_cpu(resp2.hdr.payload_len) < 12)
return 0;
INFO("Lifetime Distance: %08u inches\n", le32_to_cpu(resp2.lifetime_distance));
@@ -1039,46 +516,6 @@ static int get_status(struct shinkos6245_ctx *ctx)
return 0;
}
-static int get_fwinfo(struct shinkos6245_ctx *ctx)
-{
- struct s6245_fwinfo_cmd cmd;
- struct s6245_fwinfo_resp resp;
- int num = 0;
- int i;
-
- cmd.hdr.cmd = cpu_to_le16(S6245_CMD_FWINFO);
- cmd.hdr.len = cpu_to_le16(1);
-
- INFO("FW Information:\n");
-
- for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_PRINT_TABLES ; i++) {
- int ret;
- cmd.target = i;
-
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command (%d)\n", cmd_names(cmd.hdr.cmd), ret);
- continue;
- }
-
- if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct s6245_fwinfo_resp) - sizeof(struct s6245_status_hdr)))
- continue;
-
- INFO(" %s\t ver %02x.%02x\n", fwinfo_targets(i),
- resp.major, resp.minor);
-#if 0
- INFO(" name: '%s'\n", resp.name);
- INFO(" type: '%s'\n", resp.type);
- INFO(" date: '%s'\n", resp.date);
- INFO(" version: %02x.%02x (CRC %04x)\n", resp.major, resp.minor,
- le16_to_cpu(resp.checksum));
-#endif
- }
- return 0;
-}
-
static int get_errorlog(struct shinkos6245_ctx *ctx)
{
struct s6245_errorlog_cmd cmd;
@@ -1086,22 +523,21 @@ static int get_errorlog(struct shinkos6245_ctx *ctx)
int num = 0;
int i = 0;
- cmd.hdr.cmd = cpu_to_le16(S6245_CMD_ERRORLOG);
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_ERRORLOG);
cmd.hdr.len = cpu_to_le16(2);
do {
int ret;
cmd.index = i;
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command (%d)\n", cmd_names(cmd.hdr.cmd), ret);
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
return ret;
}
- if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct s6245_errorlog_resp) - sizeof(struct s6245_status_hdr)))
+ if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct s6245_errorlog_resp) - sizeof(struct sinfonia_status_hdr)))
return -2;
INFO("Stored Error ID %d:\n", i);
@@ -1126,240 +562,13 @@ static void dump_mediainfo(struct s6245_mediainfo_resp *resp)
INFO("Supported Media Information: %u entries:\n", resp->count);
for (i = 0 ; i < resp->count ; i++) {
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));
- }
-}
-
-static int cancel_job(struct shinkos6245_ctx *ctx, char *str)
-{
- struct s6245_cancel_cmd cmd;
- struct s6245_status_hdr resp;
- int ret, num = 0;
-
- if (!str)
- return -1;
-
- cmd.id = atoi(str);
-
- cmd.hdr.cmd = cpu_to_le16(S6245_CMD_CANCELJOB);
- cmd.hdr.len = cpu_to_le16(1);
-
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
- return ret;
- }
-
- return 0;
-}
-
-static int flash_led(struct shinkos6245_ctx *ctx)
-{
- struct s6245_cmd_hdr cmd;
- struct s6245_status_hdr resp;
- int ret, num = 0;
-
- cmd.cmd = cpu_to_le16(S6245_CMD_FLASHLED);
- cmd.len = cpu_to_le16(0);
-
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
- return ret;
- }
-
- return 0;
-}
-
-
-static int set_param(struct shinkos6245_ctx *ctx, int target, uint32_t param)
-{
- struct s6245_setparam_cmd cmd;
- struct s6245_status_hdr resp;
- int ret, num = 0;
-
- /* Set up command */
- cmd.target = target;
- cmd.param = cpu_to_le32(param);
-
- cmd.hdr.cmd = cpu_to_le16(S6245_CMD_SETPARAM);
- cmd.hdr.len = cpu_to_le16(sizeof(struct s6245_setparam_cmd)-sizeof(cmd.hdr));
-
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command (%d)\n", cmd_names(cmd.hdr.cmd), ret);
- }
-
- return ret;
-}
-
-static int reset_curve(struct shinkos6245_ctx *ctx, int target)
-{
- struct s6245_reset_cmd cmd;
- struct s6245_status_hdr resp;
- int ret, num = 0;
-
- cmd.target = target;
-
- cmd.hdr.cmd = cpu_to_le16(S6245_CMD_RESET);
- cmd.hdr.len = cpu_to_le16(1);
-
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
- return ret;
- }
-
- return 0;
-}
-
-static int get_tonecurve(struct shinkos6245_ctx *ctx, int type, char *fname)
-{
- struct s6245_readtone_cmd cmd;
- struct s6245_readtone_resp resp;
- int ret, num = 0;
-
- uint8_t *data;
- uint16_t curves[UPDATE_SIZE] = { 0 };
-
- int i,j;
-
- cmd.target = type;
- cmd.curveid = TONE_CURVE_ID;
-
- cmd.hdr.cmd = cpu_to_le16(S6245_CMD_READTONE);
- cmd.hdr.len = cpu_to_le16(1);
-
- INFO("Dump %s Tone Curve to '%s'\n", tonecurve_statuses(type), fname);
-
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
- return ret;
- }
-
- resp.total_size = le16_to_cpu(resp.total_size);
-
- data = malloc(resp.total_size * 2);
- if (!data) {
- ERROR("Memory Allocation Failure!\n");
- return -1;
- }
-
- i = 0;
- while (i < resp.total_size) {
- ret = read_data(ctx->dev, ctx->endp_up,
- data + i,
- resp.total_size * 2 - i,
- &num);
- if (ret < 0)
- goto done;
- i += num;
- }
-
- i = j = 0;
- while (i < resp.total_size) {
- memcpy(curves + j, data + i+2, data[i+1]);
- j += data[i+1] / 2;
- i += data[i+1] + 2;
- }
-
- /* Open file and write it out */
- {
- int tc_fd = open(fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
- if (tc_fd < 0) {
- ret = -1;
- goto done;
- }
-
- for (i = 0 ; i < UPDATE_SIZE; i++) {
- /* Byteswap appropriately */
- curves[i] = cpu_to_be16(le16_to_cpu(curves[i]));
- }
- write(tc_fd, curves, UPDATE_SIZE * sizeof(uint16_t));
- close(tc_fd);
- }
-
-done:
- free(data);
- return ret;
-}
-
-static int set_tonecurve(struct shinkos6245_ctx *ctx, int target, char *fname)
-{
- struct s6245_update_cmd cmd;
- struct s6245_status_hdr resp;
- int ret, num = 0;
-
- INFO("Set %s Tone Curve from '%s'\n", update_targets(target), fname);
-
- uint16_t *data = malloc(UPDATE_SIZE * sizeof(uint16_t));
- if (!data) {
- ERROR("Memory Allocation Failure!\n");
- return -1;
- }
-
- /* Read in file */
- int tc_fd = open(fname, O_RDONLY);
- if (tc_fd < 0) {
- ret = -1;
- goto done;
- }
- if (read(tc_fd, data, UPDATE_SIZE * sizeof(uint16_t)) != (UPDATE_SIZE * sizeof(uint16_t))) {
- ret = -2;
- goto done;
- }
- close(tc_fd);
- /* Byteswap data to local CPU.. */
- for (ret = 0; ret < UPDATE_SIZE ; ret++) {
- data[ret] = be16_to_cpu(data[ret]);
- }
-
- /* Set up command */
- cmd.target = target;
- cmd.reserved[0] = cmd.reserved[1] = cmd.reserved[2] = 0;
- cmd.reset = 0;
- cmd.size = cpu_to_le32(UPDATE_SIZE * sizeof(uint16_t));
-
- cmd.hdr.cmd = cpu_to_le16(S6245_CMD_UPDATE);
- cmd.hdr.len = cpu_to_le16(sizeof(struct s6245_update_cmd)-sizeof(cmd.hdr));
-
- /* Byteswap data to format printer is expecting.. */
- for (ret = 0; ret < UPDATE_SIZE ; ret++) {
- data[ret] = cpu_to_le16(data[ret]);
- }
-
- if ((ret = s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.hdr.cmd));
- goto done;
- }
-
- /* Sent transfer */
- if ((ret = send_data(ctx->dev, ctx->endp_down,
- (uint8_t *) data, UPDATE_SIZE * sizeof(uint16_t)))) {
- goto done;
+ resp->items[i].code,
+ sinfonia_print_codes(resp->items[i].code, 1),
+ resp->items[i].columns,
+ resp->items[i].rows,
+ resp->items[i].method,
+ sinfonia_print_methods(resp->items[i].method));
}
-
-done:
- free(data);
-
- return ret;
}
static void shinkos6245_cmdline(void)
@@ -1387,26 +596,30 @@ int shinkos6245_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:R:sX:")) >= 0) {
+ while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFik:l:L:mrR:sX:")) >= 0) {
switch(i) {
GETOPT_PROCESS_GLOBAL
case 'c':
- j = get_tonecurve(ctx, TONECURVE_USER, optarg);
+ j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'C':
- j = set_tonecurve(ctx, TONECURVE_USER, optarg);
+ j = sinfonia_settonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'e':
- j = get_errorlog(ctx);
+ if (ctx->dev.type == P_KODAK_8810) {
+ j = sinfonia_geterrorlog(&ctx->dev);
+ } else {
+ j = get_errorlog(ctx);
+ }
break;
case 'F':
- j = flash_led(ctx);
+ j = sinfonia_flashled(&ctx->dev);
break;
case 'i':
- j = get_fwinfo(ctx);
+ j = sinfonia_getfwinfo(&ctx->dev);
break;
case 'k': {
- uint32_t i = atoi(optarg);
+ i = atoi(optarg);
if (i < 5)
i = 0;
else if (i < 15)
@@ -1422,29 +635,29 @@ int shinkos6245_cmdline_arg(void *vctx, int argc, char **argv)
else
i = 5;
- j = set_param(ctx, PARAM_SLEEP_TIME, i);
+ j = sinfonia_setparam(&ctx->dev, PARAM_SLEEP_TIME, i);
break;
}
case 'l':
- j = get_tonecurve(ctx, TONECURVE_CURRENT, optarg);
+ j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'L':
- j = set_tonecurve(ctx, TONECURVE_CURRENT, optarg);
+ j = sinfonia_settonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'm':
dump_mediainfo(&ctx->media);
break;
case 'r':
- j = reset_curve(ctx, RESET_TONE_CURVE);
+ j = sinfonia_resetcurve(&ctx->dev, RESET_TONE_CURVE, TONE_CURVE_ID);
break;
case 'R':
- j = reset_curve(ctx, RESET_PRINTER);
+ j = sinfonia_resetcurve(&ctx->dev, RESET_PRINTER, 0);
break;
case 's':
j = get_status(ctx);
break;
case 'X':
- j = cancel_job(ctx, optarg);
+ j = sinfonia_canceljob(&ctx->dev, atoi(optarg));
break;
default:
break; /* Ignore completely */
@@ -1475,10 +688,11 @@ static int shinkos6245_attach(void *vctx, struct libusb_device_handle *dev, int
int num;
- ctx->dev = dev;
- ctx->endp_up = endp_up;
- ctx->endp_down = endp_down;
- ctx->type = type;
+ ctx->dev.dev = dev;
+ ctx->dev.endp_up = endp_up;
+ ctx->dev.endp_down = endp_down;
+ ctx->dev.type = type;
+ ctx->dev.error_codes = &error_codes;
/* Ensure jobid is sane */
ctx->jobid = jobid & 0x7f;
@@ -1487,59 +701,44 @@ static int shinkos6245_attach(void *vctx, struct libusb_device_handle *dev, int
/* Query Media */
if (test_mode < TEST_MODE_NOATTACH) {
- struct s6245_cmd_hdr cmd;
- cmd.cmd = cpu_to_le16(S6245_CMD_MEDIAINFO);
+ struct sinfonia_cmd_hdr cmd;
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_MEDIAINFO);
cmd.len = cpu_to_le16(0);
- if (s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(ctx->media),
- &num, (void*)&ctx->media)) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if (sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&ctx->media, sizeof(ctx->media),
+ &num)) {
return CUPS_BACKEND_FAILED;
}
+
+ /* Byteswap media descriptor.. */
+ int i;
+ for (i = 0 ; i < ctx->media.count ; i++) {
+ ctx->media.items[i].columns = le16_to_cpu(ctx->media.items[i].columns);
+ ctx->media.items[i].rows = le16_to_cpu(ctx->media.items[i].rows);
+ }
+
} else {
- int media_code = 0x12;
+ int media_code = RIBBON_8x12;
if (getenv("MEDIA_CODE"))
media_code = atoi(getenv("MEDIA_CODE"));
-
ctx->media.ribbon_code = media_code;
}
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
ctx->marker.name = ribbon_sizes(ctx->media.ribbon_code);
- ctx->marker.levelmax = ribbon_counts(ctx->media.ribbon_code);
+ ctx->marker.levelmax = 100;
ctx->marker.levelnow = -2;
return CUPS_BACKEND_OK;
}
-static void shinkos6245_cleanup_job(const void *vjob)
-{
- const struct shinkos6245_printjob *job = vjob;
-
- if (job->databuf)
- free(job->databuf);
-
- free((void*)job);
-}
-
-static void shinkos6245_teardown(void *vctx) {
- struct shinkos6245_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
static int shinkos6245_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
struct shinkos6245_ctx *ctx = vctx;
+ struct sinfonia_printjob *job = NULL;
int ret;
- uint8_t tmpbuf[4];
-
- struct shinkos6245_printjob *job = NULL;
if (!ctx)
return CUPS_BACKEND_FAILED;
@@ -1550,75 +749,22 @@ static int shinkos6245_read_parse(void *vctx, const void **vjob, int data_fd, in
return CUPS_BACKEND_RETRY_CURRENT;
}
memset(job, 0, sizeof(*job));
- job->copies = copies; // XXX hdr.copies
-
- /* Read in then validate header */
- ret = read(data_fd, &job->hdr, sizeof(job->hdr));
- if (ret < 0 || ret != sizeof(job->hdr)) {
- if (ret == 0)
- return CUPS_BACKEND_CANCEL;
- ERROR("Read failed (%d/%d/%d)\n",
- ret, 0, (int)sizeof(job->hdr));
- perror("ERROR: Read failed");
- return ret;
- }
-
- if (le32_to_cpu(job->hdr.len1) != 0x10 ||
- le32_to_cpu(job->hdr.len2) != 0x64 ||
- le32_to_cpu(job->hdr.dpi) != 300) {
- ERROR("Unrecognized header data format!\n");
- return CUPS_BACKEND_CANCEL;
- }
-
- if (le32_to_cpu(job->hdr.model) != 6245) {
- ERROR("Unrecognized printer (%u)!\n", le32_to_cpu(job->hdr.model));
-
- return CUPS_BACKEND_CANCEL;
- }
-
- if (job->databuf) {
- free(job->databuf);
- job->databuf = NULL;
- }
-
- job->datalen = le32_to_cpu(job->hdr.rows) * le32_to_cpu(job->hdr.columns) * 3;
- job->databuf = malloc(job->datalen);
- if (!job->databuf) {
- ERROR("Memory allocation failure!\n");
- return CUPS_BACKEND_RETRY_CURRENT;
- }
- {
- int remain = job->datalen;
- uint8_t *ptr = job->databuf;
- do {
- ret = read(data_fd, ptr, remain);
- if (ret < 0) {
- ERROR("Read failed (%d/%d/%d)\n",
- ret, remain, job->datalen);
- perror("ERROR: Read failed");
- return ret;
- }
- ptr += ret;
- remain -= ret;
- } while (remain);
+ /* Common read/parse code */
+ if (ctx->dev.type == P_KODAK_8810) {
+ ret = sinfonia_raw18_read_parse(data_fd, job);
+ } else {
+ ret = sinfonia_read_parse(data_fd, 6245, job);
}
-
- /* Make sure footer is sane too */
- ret = read(data_fd, tmpbuf, 4);
- if (ret != 4) {
- ERROR("Read failed (%d/%d/%d)\n",
- ret, 4, 4);
- perror("ERROR: Read failed");
+ if (ret) {
+ free(job);
return ret;
}
- if (tmpbuf[0] != 0x04 ||
- tmpbuf[1] != 0x03 ||
- tmpbuf[2] != 0x02 ||
- tmpbuf[3] != 0x01) {
- ERROR("Unrecognized footer data format!\n");
- return CUPS_BACKEND_FAILED;
- }
+
+ if (job->jp.copies > 1)
+ job->copies = job->jp.copies;
+ else
+ job->copies = copies;
*vjob = job;
@@ -1631,16 +777,16 @@ static int shinkos6245_main_loop(void *vctx, const void *vjob) {
int ret, num;
uint8_t cmdbuf[CMDBUF_LEN];
- int i, last_state = -1, state = S_IDLE;
+ int last_state = -1, state = S_IDLE;
uint8_t mcut;
int copies;
- struct s6245_cmd_hdr *cmd = (struct s6245_cmd_hdr *) cmdbuf;;
+ struct sinfonia_cmd_hdr *cmd = (struct sinfonia_cmd_hdr *) cmdbuf;;
struct s6245_print_cmd *print = (struct s6245_print_cmd *) cmdbuf;
struct s6245_status_resp sts, sts2;
- struct s6245_status_hdr resp;
+ struct sinfonia_status_hdr resp;
- struct shinkos6245_printjob *job = (struct shinkos6245_printjob*) vjob;
+ struct sinfonia_printjob *job = (struct sinfonia_printjob*) vjob;
copies = job->copies;
@@ -1651,13 +797,13 @@ static int shinkos6245_main_loop(void *vctx, const void *vjob) {
copies = 120;
/* Set up mcut */
- switch (le32_to_cpu(job->hdr.media)) {
- case MEDIA_8x4_2:
- case MEDIA_8x5_2:
- case MEDIA_8x6_2:
+ switch (job->jp.media) {
+ case CODE_8x4_2:
+ case CODE_8x5_2:
+ case CODE_8x6_2:
mcut = PRINT_METHOD_COMBO_2;
break;
- case MEDIA_8x4_3:
+ case CODE_8x4_3:
mcut = PRINT_METHOD_COMBO_3;
break;
default:
@@ -1665,44 +811,56 @@ static int shinkos6245_main_loop(void *vctx, const void *vjob) {
}
// XXX what about mcut |= PRINT_METHOD_DISABLE_ERR;
+#if 0
+ int i;
/* Validate print sizes */
for (i = 0; i < ctx->media.count ; i++) {
/* Look for matching media */
- if (le16_to_cpu(ctx->media.items[i].columns) == cpu_to_le16(le32_to_cpu(job->hdr.columns)) &&
- le16_to_cpu(ctx->media.items[i].rows) == cpu_to_le16(le32_to_cpu(job->hdr.rows)))
+ if (ctx->media.items[i].columns == job->jp.columns &&
+ ctx->media.items[i].rows == job->jp.rows)
break;
}
if (i == ctx->media.count) {
ERROR("Incorrect media loaded for print!\n");
return CUPS_BACKEND_HOLD;
}
+#else
+ if (ctx->media.ribbon_code != RIBBON_8x12 &&
+ ctx->media.ribbon_code != RIBBON_8x12K &&
+ job->jp.rows > 3024) {
+ ERROR("Incorrect media loaded for print!\n");
+ return CUPS_BACKEND_HOLD;
+ }
+
+#endif
/* Send Set Time */
- {
- struct s6245_settime_cmd *stime = (struct s6245_settime_cmd *)cmdbuf;
+ if (ctx->dev.type != P_KODAK_8810) {
+ struct s6245_settime_cmd *settime = (struct s6245_settime_cmd *)cmdbuf;
time_t now = time(NULL);
struct tm *cur = localtime(&now);
memset(cmdbuf, 0, CMDBUF_LEN);
- cmd->cmd = cpu_to_le16(S6245_CMD_SETTIME);
+ cmd->cmd = cpu_to_le16(SINFONIA_CMD_SETTIME);
cmd->len = cpu_to_le16(0);
- stime->enable = 1;
- stime->second = cur->tm_sec;
- stime->minute = cur->tm_min;
- stime->hour = cur->tm_hour;
- stime->day = cur->tm_mday;
- stime->month = cur->tm_mon;
- stime->year = cur->tm_year + 1900 - 2000;
-
- if ((ret = s6245_do_cmd(ctx,
- cmdbuf, sizeof(*stime),
- sizeof(struct s6245_status_hdr),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(stime->hdr.cmd));
+ settime->enable = 1;
+ settime->second = cur->tm_sec;
+ settime->minute = cur->tm_min;
+ settime->hour = cur->tm_hour;
+ settime->day = cur->tm_mday;
+ settime->month = cur->tm_mon;
+ settime->year = cur->tm_year + 1900 - 2000;
+
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ cmdbuf, sizeof(*settime),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
return CUPS_BACKEND_FAILED;
}
- if (resp.result != RESULT_SUCCESS)
- goto printer_error;
+ if (resp.result != RESULT_SUCCESS) {
+ ERROR("Bad result %02x\n", resp.result);
+ goto fail;
+ }
}
// XXX check copies against remaining media!
@@ -1715,14 +873,13 @@ top:
/* Send Status Query */
memset(cmdbuf, 0, CMDBUF_LEN);
- cmd->cmd = cpu_to_le16(S6245_CMD_GETSTATUS);
+ cmd->cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd->len = cpu_to_le16(0);
- if ((ret = s6245_do_cmd(ctx,
- cmdbuf, sizeof(*cmd),
- sizeof(sts),
- &num, (void*)&sts)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ cmdbuf, sizeof(*cmd),
+ (uint8_t*)&sts, sizeof(sts),
+ &num)) < 0) {
return CUPS_BACKEND_FAILED;
}
@@ -1730,7 +887,7 @@ top:
memcpy(&sts2, &sts, sizeof(sts));
INFO("Printer Status: 0x%02x (%s)\n",
- sts.hdr.status, status_str(sts.hdr.status));
+ sts.hdr.status, sinfonia_status_str(sts.hdr.status));
if (ctx->marker.levelnow != (int)sts.count_ribbon_left) {
ctx->marker.levelnow = sts.count_ribbon_left;
@@ -1775,21 +932,19 @@ top:
INFO("Sending print job (internal id %u)\n", ctx->jobid);
memset(cmdbuf, 0, CMDBUF_LEN);
- print->hdr.cmd = cpu_to_le16(S6245_CMD_PRINTJOB);
+ print->hdr.cmd = cpu_to_le16(SINFONIA_CMD_PRINTJOB);
print->hdr.len = cpu_to_le16(sizeof (*print) - sizeof(*cmd));
-
print->id = ctx->jobid;
print->count = cpu_to_le16(copies);
- print->columns = cpu_to_le16(le32_to_cpu(job->hdr.columns));
- print->rows = cpu_to_le16(le32_to_cpu(job->hdr.rows));
- print->mode = le32_to_cpu(job->hdr.oc_mode);
+ print->columns = print->columns2 = cpu_to_le16(job->jp.columns);
+ print->rows = print->rows2 = cpu_to_le16(job->jp.rows);
+ print->mode = job->jp.oc_mode;
print->method = mcut;
- if ((ret = s6245_do_cmd(ctx,
- cmdbuf, sizeof(*print),
- sizeof(resp),
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(print->hdr.cmd));
+ if ((ret = sinfonia_docmd(&ctx->dev,
+ cmdbuf, sizeof(*print),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
return ret;
}
@@ -1797,15 +952,15 @@ top:
if (resp.error == ERROR_BUFFER_FULL) {
INFO("Printer Buffers full, retrying\n");
break;
- } else if ((resp.status & 0xf0) == 0x30 || sts.hdr.status == 0x21) {
- INFO("Printer busy (%s), retrying\n", status_str(sts.hdr.status));
+ } else if ((resp.status & 0xf0) == 0x30 || sts.hdr.status == ERROR_BUFFER_FULL) {
+ INFO("Printer busy (%s), retrying\n", sinfonia_status_str(sts.hdr.status));
break;
} else if (resp.status != ERROR_NONE)
goto printer_error;
}
INFO("Sending image data to printer\n");
- if ((ret = send_data(ctx->dev, ctx->endp_down,
+ if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
job->databuf, job->datalen)))
return CUPS_BACKEND_FAILED;
@@ -1835,44 +990,41 @@ top:
printer_error:
ERROR("Printer reported error: %#x (%s) status: %#x (%s) -> %#x.%#x (%s)\n",
sts.hdr.error,
- error_str(sts.hdr.error),
+ sinfonia_error_str(sts.hdr.error),
sts.hdr.status,
- status_str(sts.hdr.status),
+ sinfonia_status_str(sts.hdr.status),
sts.hdr.printer_major, sts.hdr.printer_minor,
error_codes(sts.hdr.printer_major, sts.hdr.printer_minor));
+fail:
return CUPS_BACKEND_FAILED;
}
static int shinkos6245_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len)
{
- struct s6245_cmd_hdr cmd;
- struct s6245_getserial_resp resp;
+ struct sinfonia_cmd_hdr cmd;
+ struct sinfonia_getserial_resp resp;
int ret, num = 0;
- struct shinkos6245_ctx ctx = {
+ struct sinfonia_usbdev sdev = {
.dev = dev,
.endp_up = endp_up,
.endp_down = endp_down,
};
- cmd.cmd = cpu_to_le16(S6245_CMD_GETSERIAL);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSERIAL);
cmd.len = cpu_to_le16(0);
- if ((ret = s6245_do_cmd(&ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(resp) - 1,
- &num, (void*)&resp)) < 0) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if ((ret = sinfonia_docmd(&sdev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
return ret;
}
- /* Null-terminate */
- resp.hdr.payload_len = le16_to_cpu(resp.hdr.payload_len);
- if (resp.hdr.payload_len > 23)
- resp.hdr.payload_len = 23;
- resp.data[resp.hdr.payload_len] = 0;
- strncpy(buf, (char*)resp.data, buf_len);
- buf[buf_len-1] = 0; /* ensure it's null terminated */
+ /* Copy and Null-terminate */
+ num = (buf_len > (int)sizeof(resp.data)) ? (int)sizeof(resp.data) : (buf_len - 1);
+ memcpy(buf, resp.data, num);
+ buf[num] = 0;
return CUPS_BACKEND_OK;
}
@@ -1880,19 +1032,18 @@ static int shinkos6245_query_serno(struct libusb_device_handle *dev, uint8_t end
static int shinkos6245_query_markers(void *vctx, struct marker **markers, int *count)
{
struct shinkos6245_ctx *ctx = vctx;
- struct s6245_cmd_hdr cmd;
+ struct sinfonia_cmd_hdr cmd;
struct s6245_status_resp status;
int num;
/* Query Status */
- cmd.cmd = cpu_to_le16(S6245_CMD_GETSTATUS);
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
- if (s6245_do_cmd(ctx,
- (uint8_t*)&cmd, sizeof(cmd),
- sizeof(status),
- &num, (void*)&status)) {
- ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
+ if (sinfonia_docmd(&ctx->dev,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&status, sizeof(status),
+ &num)) {
return CUPS_BACKEND_FAILED;
}
@@ -1909,9 +1060,11 @@ static int shinkos6245_query_markers(void *vctx, struct marker **markers, int *c
#define USB_PID_SHINKO_S6245 0x001D
#define USB_VID_HITI 0x0D16
#define USB_PID_HITI_P910L 0x000E
+#define USB_VID_KODAK 0x040A
+#define USB_PID_KODAK_8810 0x404D
static const char *shinkos6245_prefixes[] = {
- "sinfonia-chcs6245", "hiti-p910l",
+ "sinfonia-chcs6245", "hiti-p910l", "kodak-8810",
// extras
"shinko-chcs6245",
// backwards compatibility
@@ -1920,15 +1073,14 @@ static const char *shinkos6245_prefixes[] = {
};
struct dyesub_backend shinkos6245_backend = {
- .name = "Shinko/Sinfonia CHC-S6245",
- .version = "0.14WIP",
+ .name = "Sinfonia CHC-S6245 / Kodak 8810",
+ .version = "0.22" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = shinkos6245_prefixes,
.cmdline_usage = shinkos6245_cmdline,
.cmdline_arg = shinkos6245_cmdline_arg,
.init = shinkos6245_init,
.attach = shinkos6245_attach,
- .teardown = shinkos6245_teardown,
- .cleanup_job = shinkos6245_cleanup_job,
+ .cleanup_job = sinfonia_cleanup_job,
.read_parse = shinkos6245_read_parse,
.main_loop = shinkos6245_main_loop,
.query_serno = shinkos6245_query_serno,
@@ -1936,6 +1088,7 @@ struct dyesub_backend shinkos6245_backend = {
.devices = {
{ USB_VID_SHINKO, USB_PID_SHINKO_S6245, P_SHINKO_S6245, NULL, "shinfonia-chcs6245"},
{ USB_VID_HITI, USB_PID_HITI_P910L, P_SHINKO_S6245, NULL, "hiti-p910l"},
+ { USB_VID_KODAK, USB_PID_KODAK_8810, P_KODAK_8810, NULL, "kodak-8810"},
{ 0, 0, 0, NULL, NULL}
}
};
@@ -1959,4 +1112,20 @@ struct dyesub_backend shinkos6245_backend = {
04 03 02 01 [[ footer ]]
+ Kodak 8810 data format: (Note: EK8810 is actually a Sinfonia CHC-S1845-5A)
+
+ Spool file is the print_cmd_hdr (22 bytes) followed by RGB-packed data.
+
+ 01 40 0a 00 Fixed header
+ XX Job ID
+ CC CC Number of copies (1-???)
+ WW WW Number of columns
+ HH HH Number of rows
+ WW WW Number of columns
+ HH HH Number of rows
+ 00 00 00 00 Reserved/Unknown
+ LL Laminate, 0x02/0x03 (on/satin)
+ MM Print Method
+ 00 Reserved/Unknown
+
*/
diff --git a/src/cups/backend_sinfonia.c b/src/cups/backend_sinfonia.c
new file mode 100644
index 0000000..07d7716
--- /dev/null
+++ b/src/cups/backend_sinfonia.c
@@ -0,0 +1,1154 @@
+ /*
+ * Shinko/Sinfonia Common Code
+ *
+ * (c) 2019 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]
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+
+#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>
+
+#include "backend_common.h"
+#include "backend_sinfonia.h"
+
+int sinfonia_read_parse(int data_fd, uint32_t model,
+ struct sinfonia_printjob *job)
+{
+ uint32_t hdr[29];
+ int ret, i;
+ uint8_t tmpbuf[4];
+
+ /* Read in header */
+ ret = read(data_fd, hdr, SINFONIA_HDR_LEN);
+ if (ret < 0 || ret != SINFONIA_HDR_LEN) {
+ if (ret == 0)
+ return CUPS_BACKEND_CANCEL;
+ ERROR("Read failed (%d/%d)\n",
+ ret, SINFONIA_HDR_LEN);
+ perror("ERROR: Read failed");
+ return ret;
+ }
+
+ /* Byteswap everything */
+ for (i = 0 ; i < (SINFONIA_HDR_LEN / 4) ; i++) {
+ hdr[i] = le32_to_cpu(hdr[i]);
+ }
+
+ /* Sanity-check headers */
+ if (hdr[0] != SINFONIA_HDR1_LEN ||
+ hdr[4] != SINFONIA_HDR2_LEN ||
+ hdr[22] != SINFONIA_DPI) {
+ ERROR("Unrecognized header data format!\n");
+ return CUPS_BACKEND_CANCEL;
+ }
+ if (hdr[1] != model) {
+ ERROR("job/printer mismatch (%u/%u)!\n", hdr[1], model);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ if (!hdr[13] || !hdr[14]) {
+ ERROR("Bad job cols/rows!\n");
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Work out data length */
+ job->datalen = hdr[13] * hdr[14] * 3;
+ job->databuf = malloc(job->datalen);
+ if (!job->databuf) {
+ ERROR("Memory allocation failure!\n");
+ return CUPS_BACKEND_RETRY_CURRENT;
+ }
+
+ /* Read in payload data */
+ {
+ uint32_t remain = job->datalen;
+ uint8_t *ptr = job->databuf;
+ do {
+ ret = read(data_fd, ptr, remain);
+ if (ret < 0) {
+ ERROR("Read failed (%d/%u/%d)\n",
+ ret, remain, job->datalen);
+ perror("ERROR: Read failed");
+ free(job->databuf);
+ job->databuf = NULL;
+ return ret;
+ }
+ ptr += ret;
+ remain -= ret;
+ } while (remain);
+ }
+
+ /* Make sure footer is sane too */
+ ret = read(data_fd, tmpbuf, 4);
+ if (ret != 4) {
+ ERROR("Read failed (%d/%d)\n", ret, 4);
+ perror("ERROR: Read failed");
+ free(job->databuf);
+ job->databuf = NULL;
+ return ret;
+ }
+ if (tmpbuf[0] != 0x04 ||
+ tmpbuf[1] != 0x03 ||
+ tmpbuf[2] != 0x02 ||
+ tmpbuf[3] != 0x01) {
+ ERROR("Unrecognized footer data format!\n");
+ free (job->databuf);
+ job->databuf = NULL;
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Fill out job params */
+ job->jp.media = hdr[6];
+ if (hdr[1] != 6245)
+ job->jp.method = hdr[8];
+ if (hdr[1] == 2245 || hdr[1] == 6245)
+ job->jp.quality = hdr[9];
+ if (hdr[1] == 1245 || hdr[1] == 2145)
+ job->jp.oc_mode = hdr[9];
+ else
+ job->jp.oc_mode = hdr[10];
+ if (hdr[1] == 1245)
+ job->jp.mattedepth = hdr[11];
+ if (hdr[1] == 1245)
+ job->jp.dust = hdr[12];
+ job->jp.columns = hdr[13];
+ job->jp.rows = hdr[14];
+ job->jp.copies = hdr[15];
+
+ if (hdr[1] == 2245 || hdr[1] == 6145)
+ job->jp.ext_flags = hdr[28];
+
+ return CUPS_BACKEND_OK;
+}
+
+int sinfonia_raw10_read_parse(int data_fd, struct sinfonia_printjob *job)
+{
+ struct sinfonia_printcmd10_hdr hdr;
+ int ret;
+
+ /* Read in header */
+ ret = read(data_fd, &hdr, sizeof(hdr));
+ if (ret < 0 || ret != sizeof(hdr)) {
+ if (ret == 0)
+ return CUPS_BACKEND_CANCEL;
+ ERROR("Read failed (%d/%d/%d)\n",
+ ret, 0, (int)sizeof(hdr));
+ perror("ERROR: Read failed");
+ return CUPS_BACKEND_CANCEL;
+ }
+ /* Validate header */
+ if (le16_to_cpu(hdr.hdr.cmd) != 0x4001 ||
+ le16_to_cpu(hdr.hdr.len) != 10) {
+ ERROR("Unrecognized data format!\n");
+ return CUPS_BACKEND_CANCEL;
+ }
+ job->jp.copies = le16_to_cpu(hdr.copies);
+ job->jp.rows = le16_to_cpu(hdr.rows);
+ job->jp.columns = le16_to_cpu(hdr.columns);
+ job->jp.media = hdr.media;
+ job->jp.oc_mode = hdr.oc_mode;
+ job->jp.method = hdr.method;
+
+ /* Allocate buffer */
+ job->datalen = job->jp.rows * job->jp.columns * 3;
+ job->databuf = malloc(job->datalen);
+ if (!job->databuf) {
+ ERROR("Memory allocation failure!\n");
+ return CUPS_BACKEND_RETRY_CURRENT;
+ }
+
+ {
+ int remain = job->datalen;
+ uint8_t *ptr = job->databuf;
+ do {
+ ret = read(data_fd, ptr, remain);
+ if (ret < 0) {
+ ERROR("Read failed (%d/%d/%d)\n",
+ ret, remain, job->datalen);
+ perror("ERROR: Read failed");
+ return CUPS_BACKEND_CANCEL;
+ }
+ ptr += ret;
+ remain -= ret;
+ } while (remain);
+ }
+
+ return CUPS_BACKEND_OK;
+}
+
+int sinfonia_raw18_read_parse(int data_fd, struct sinfonia_printjob *job)
+{
+ struct sinfonia_printcmd18_hdr hdr;
+ int ret;
+
+ /* Read in header */
+ ret = read(data_fd, &hdr, sizeof(hdr));
+ if (ret < 0 || ret != sizeof(hdr)) {
+ if (ret == 0)
+ return CUPS_BACKEND_CANCEL;
+ ERROR("Read failed (%d/%d/%d)\n",
+ ret, 0, (int)sizeof(hdr));
+ perror("ERROR: Read failed");
+ return CUPS_BACKEND_CANCEL;
+ }
+ /* Validate header */
+ if (le16_to_cpu(hdr.hdr.cmd) != SINFONIA_CMD_PRINTJOB ||
+ le16_to_cpu(hdr.hdr.len) != 18) {
+ ERROR("Unrecognized data format!\n");
+ return CUPS_BACKEND_CANCEL;
+ }
+ job->jp.copies = le16_to_cpu(hdr.copies);
+ job->jp.rows = le16_to_cpu(hdr.rows);
+ job->jp.columns = le16_to_cpu(hdr.columns);
+ job->jp.media = hdr.media;
+ job->jp.oc_mode = hdr.oc_mode;
+ job->jp.method = hdr.method;
+
+ /* Allocate buffer */
+ job->datalen = job->jp.rows * job->jp.columns * 3;
+ job->databuf = malloc(job->datalen);
+ if (!job->databuf) {
+ ERROR("Memory allocation failure!\n");
+ return CUPS_BACKEND_RETRY_CURRENT;
+ }
+
+ {
+ int remain = job->datalen;
+ uint8_t *ptr = job->databuf;
+ do {
+ ret = read(data_fd, ptr, remain);
+ if (ret < 0) {
+ ERROR("Read failed (%d/%d/%d)\n",
+ ret, remain, job->datalen);
+ perror("ERROR: Read failed");
+ return CUPS_BACKEND_CANCEL;
+ }
+ ptr += ret;
+ remain -= ret;
+ } while (remain);
+ }
+
+ return CUPS_BACKEND_OK;
+}
+
+int sinfonia_raw28_read_parse(int data_fd, struct sinfonia_printjob *job)
+{
+ struct sinfonia_printcmd28_hdr hdr;
+ int ret;
+
+ /* Read in header */
+ ret = read(data_fd, &hdr, sizeof(hdr));
+ if (ret < 0 || ret != sizeof(hdr)) {
+ if (ret == 0)
+ return CUPS_BACKEND_CANCEL;
+ ERROR("Read failed (%d/%d/%d)\n",
+ ret, 0, (int)sizeof(hdr));
+ perror("ERROR: Read failed");
+ return CUPS_BACKEND_CANCEL;
+ }
+ /* Validate header */
+ if (le16_to_cpu(hdr.hdr.cmd) != SINFONIA_CMD_PRINTJOB ||
+ le16_to_cpu(hdr.hdr.len) != 28) {
+ ERROR("Unrecognized data format!\n");
+ return CUPS_BACKEND_CANCEL;
+ }
+ job->jp.copies = le16_to_cpu(hdr.copies);
+ job->jp.rows = le16_to_cpu(hdr.rows);
+ job->jp.columns = le16_to_cpu(hdr.columns);
+ job->jp.media = hdr.media;
+ job->jp.oc_mode = hdr.options & 0x03;
+ job->jp.quality = hdr.options & 0x08;
+ job->jp.method = hdr.method;
+
+ /* Allocate buffer */
+ job->datalen = job->jp.rows * job->jp.columns * 3;
+ job->databuf = malloc(job->datalen);
+ if (!job->databuf) {
+ ERROR("Memory allocation failure!\n");
+ return CUPS_BACKEND_RETRY_CURRENT;
+ }
+
+ {
+ int remain = job->datalen;
+ uint8_t *ptr = job->databuf;
+ do {
+ ret = read(data_fd, ptr, remain);
+ if (ret < 0) {
+ ERROR("Read failed (%d/%d/%d)\n",
+ ret, remain, job->datalen);
+ perror("ERROR: Read failed");
+ return CUPS_BACKEND_CANCEL;
+ }
+ ptr += ret;
+ remain -= ret;
+ } while (remain);
+ }
+
+ return CUPS_BACKEND_OK;
+}
+
+void sinfonia_cleanup_job(const void *vjob)
+{
+ const struct sinfonia_printjob *job = vjob;
+
+ if (job->databuf)
+ free(job->databuf);
+
+ free((void*)job);
+}
+
+int sinfonia_docmd(struct sinfonia_usbdev *usbh,
+ uint8_t *cmd, int cmdlen,
+ uint8_t *resp, int resplen,
+ int *num)
+{
+ libusb_device_handle *dev = usbh->dev;
+ uint8_t endp_up = usbh->endp_up;
+ uint8_t endp_down = usbh->endp_down;
+ int ret;
+
+ struct sinfonia_cmd_hdr *cmdhdr = (struct sinfonia_cmd_hdr *) cmd;
+ struct sinfonia_status_hdr *resphdr = (struct sinfonia_status_hdr *)resp;
+
+ if ((ret = send_data(dev, endp_down,
+ cmd, cmdlen))) {
+ goto fail;
+ }
+
+ ret = read_data(dev, endp_up,
+ (uint8_t *)resp, resplen, num);
+
+ if (ret < 0)
+ goto fail;
+
+ if (resphdr->result != RESULT_SUCCESS) {
+ INFO("Printer Status: %02x (%s)\n", resphdr->status,
+ sinfonia_status_str(resphdr->status));
+ INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
+ resphdr->result, resphdr->error, resphdr->printer_major,
+ resphdr->printer_minor, usbh->error_codes(resphdr->printer_major, resphdr->printer_minor));
+ goto fail;
+ }
+
+ return 0;
+fail:
+ ERROR("Failed to execute %s command\n", sinfonia_cmd_names(cmdhdr->cmd));
+ return ret;
+}
+
+int sinfonia_flashled(struct sinfonia_usbdev *usbh)
+{
+ struct sinfonia_cmd_hdr cmd;
+ struct sinfonia_status_hdr resp;
+ int ret, num = 0;
+
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_FLASHLED);
+ cmd.len = cpu_to_le16(0);
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+int sinfonia_canceljob(struct sinfonia_usbdev *usbh, int id)
+{
+ struct sinfonia_cancel_cmd cmd;
+ struct sinfonia_status_hdr resp;
+ int ret, num = 0;
+
+ cmd.id = id;
+
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_CANCELJOB);
+ cmd.hdr.len = cpu_to_le16(1);
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+int sinfonia_getparam(struct sinfonia_usbdev *usbh, int target, uint32_t *param)
+{
+ struct sinfonia_getparam_cmd cmd;
+ struct sinfonia_getparam_resp resp;
+ int ret, num = 0;
+
+ /* Set up command */
+ cmd.target = target;
+
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_GETPARAM);
+ cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_getparam_cmd)-sizeof(cmd.hdr));
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ }
+ *param = le32_to_cpu(resp.param);
+
+ return ret;
+}
+
+int sinfonia_setparam(struct sinfonia_usbdev *usbh, int target, uint32_t param)
+{
+ struct sinfonia_setparam_cmd cmd;
+ struct sinfonia_status_hdr resp;
+ int ret, num = 0;
+
+ /* Set up command */
+ cmd.target = target;
+ cmd.param = cpu_to_le32(param);
+
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_SETPARAM);
+ cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_setparam_cmd)-sizeof(cmd.hdr));
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ }
+
+ return ret;
+}
+
+int sinfonia_getfwinfo(struct sinfonia_usbdev *usbh)
+{
+ struct sinfonia_fwinfo_cmd cmd;
+ struct sinfonia_fwinfo_resp resp;
+ int num = 0;
+ int i;
+
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_FWINFO);
+ cmd.hdr.len = cpu_to_le16(1);
+
+ resp.hdr.payload_len = 0;
+
+ INFO("FW Information:\n");
+
+ for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_PRINT_TABLES2 ; i++) {
+ int ret;
+ cmd.target = i;
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ continue;
+ }
+
+ if (resp.major == 0)
+ continue;
+
+ if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_fwinfo_resp) - sizeof(struct sinfonia_status_hdr)))
+ continue;
+
+ INFO(" %s\t ver %02x.%02x\n", sinfonia_fwinfo_targets(i),
+ resp.major, resp.minor);
+#if 0
+ INFO(" name: '%s'\n", resp.name);
+ INFO(" type: '%s'\n", resp.type);
+ INFO(" date: '%s'\n", resp.date);
+ INFO(" version: %02x.%02x (CRC %04x)\n", resp.major, resp.minor,
+ le16_to_cpu(resp.checksum));
+#endif
+ }
+ return 0;
+}
+
+int sinfonia_geterrorlog(struct sinfonia_usbdev *usbh)
+{
+ struct sinfonia_cmd_hdr cmd;
+ struct sinfonia_errorlog_resp resp;
+ int ret, num = 0;
+ int i;
+
+ cmd.cmd = cpu_to_le16(SINFONIA_CMD_ERRORLOG);
+ cmd.len = cpu_to_le16(0);
+
+ resp.hdr.payload_len = 0;
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ return ret;
+ }
+
+ if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_errorlog_resp) - sizeof(struct sinfonia_status_hdr)))
+ return -2;
+
+ 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,
+ usbh->error_codes(resp.items[i].major, resp.items[i].minor));
+ }
+ return 0;
+}
+
+int sinfonia_resetcurve(struct sinfonia_usbdev *usbh, int target, int id)
+{
+ struct sinfonia_reset_cmd cmd;
+ struct sinfonia_status_hdr resp;
+ int ret, num = 0;
+
+ cmd.target = target;
+ cmd.curveid = id;
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_RESET);
+ cmd.hdr.len = cpu_to_le16(2);
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+int sinfonia_gettonecurve(struct sinfonia_usbdev *usbh, int type, char *fname)
+{
+ struct sinfonia_readtone_cmd cmd;
+ struct sinfonia_readtone_resp resp;
+ int ret, num = 0;
+
+ uint8_t *data;
+ uint16_t curves[TONE_CURVE_SIZE] = { 0 };
+
+ int i,j;
+
+ cmd.target = type;
+ cmd.curveid = TONE_CURVE_ID;
+
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_READTONE);
+ cmd.hdr.len = cpu_to_le16(1);
+
+ resp.hdr.payload_len = 0;
+
+ INFO("Dump %s Tone Curve to '%s'\n", sinfonia_tonecurve_statuses(type), fname);
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ return ret;
+ }
+
+ if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_readtone_resp) - sizeof(struct sinfonia_status_hdr)))
+ return -2;
+
+ resp.total_size = le16_to_cpu(resp.total_size);
+
+ data = malloc(resp.total_size * 2);
+ if (!data) {
+ ERROR("Memory Allocation Failure!\n");
+ return -1;
+ }
+
+ i = 0;
+ while (i < resp.total_size) {
+ ret = read_data(usbh->dev, usbh->endp_up,
+ data + i,
+ resp.total_size * 2 - i,
+ &num);
+ if (ret < 0)
+ goto done;
+ i += num;
+ }
+
+ i = j = 0;
+ while (i < resp.total_size) {
+ memcpy(curves + j, data + i+2, data[i+1]);
+ j += data[i+1] / 2;
+ i += data[i+1] + 2;
+ }
+
+ /* Open file and write it out */
+ {
+ int tc_fd = open(fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
+ if (tc_fd < 0) {
+ ret = -1;
+ goto done;
+ }
+
+ for (i = 0 ; i < TONE_CURVE_SIZE; i++) {
+ /* Byteswap appropriately */
+ curves[i] = cpu_to_be16(le16_to_cpu(curves[i]));
+ }
+ ret = write(tc_fd, curves, TONE_CURVE_SIZE * sizeof(uint16_t));
+ close(tc_fd);
+ }
+
+done:
+ free(data);
+ return ret;
+}
+
+int sinfonia_settonecurve(struct sinfonia_usbdev *usbh, int target, char *fname)
+{
+ struct sinfonia_update_cmd cmd;
+ struct sinfonia_status_hdr resp;
+ int ret, num = 0;
+
+ INFO("Set %s Tone Curve from '%s'\n", sinfonia_update_targets(target), fname);
+
+ uint16_t *data = malloc(TONE_CURVE_SIZE * sizeof(uint16_t));
+ if (!data) {
+ ERROR("Memory Allocation Failure!\n");
+ return -1;
+ }
+
+ /* Read in file */
+ if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE * sizeof(uint16_t), NULL))) {
+ ERROR("Failed to read Tone Curve file\n");
+ goto done;
+ }
+
+ /* Byteswap data to local CPU.. */
+ for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
+ data[ret] = be16_to_cpu(data[ret]);
+ }
+
+ /* Set up command */
+ cmd.target = target;
+ cmd.curve_id = TONE_CURVE_ID;
+ cmd.reserved[0] = cmd.reserved[1] = cmd.reserved[2] = 0;
+ cmd.reset = 0;
+ cmd.size = cpu_to_le32(TONE_CURVE_SIZE * sizeof(uint16_t));
+
+ cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_UPDATE);
+ cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_update_cmd)-sizeof(cmd.hdr));
+
+ /* Byteswap data to format printer is expecting.. */
+ for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
+ data[ret] = cpu_to_le16(data[ret]);
+ }
+
+ if ((ret = sinfonia_docmd(usbh,
+ (uint8_t*)&cmd, sizeof(cmd),
+ (uint8_t*)&resp, sizeof(resp),
+ &num)) < 0) {
+ return ret;
+ }
+
+ /* Sent transfer */
+ if ((ret = send_data(usbh->dev, usbh->endp_down,
+ (uint8_t *) data, TONE_CURVE_SIZE * sizeof(uint16_t)))) {
+ goto done;
+ }
+
+done:
+ free(data);
+
+ return ret;
+}
+
+const char *sinfonia_update_targets (uint8_t v) {
+ switch (v) {
+ case UPDATE_TARGET_USER:
+ return "User";
+ case UPDATE_TARGET_CURRENT:
+ return "Current";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_tonecurve_statuses (uint8_t v)
+{
+ switch(v) {
+ case 0:
+ return "Initial";
+ case 1:
+ return "UserSet";
+ case 2:
+ return "Current";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_bank_statuses(uint8_t v)
+{
+ switch (v) {
+ case BANK_STATUS_FREE:
+ return "Free";
+ case BANK_STATUS_XFER:
+ return "Xfer";
+ case BANK_STATUS_FULL:
+ return "Full";
+ case BANK_STATUS_PRINTING:
+ return "Printing";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_error_str(uint8_t v) {
+ switch (v) {
+ case ERROR_NONE:
+ return "None";
+ case ERROR_INVALID_PARAM:
+ return "Invalid Command Parameter";
+ case ERROR_MAIN_APP_INACTIVE:
+ return "Main App Inactive";
+ case ERROR_COMMS_TIMEOUT:
+ return "Main Communication Timeout";
+ case ERROR_MAINT_NEEDED:
+ return "Maintenance Needed";
+ case ERROR_BAD_COMMAND:
+ return "Inappropriate Command";
+ case ERROR_PRINTER:
+ return "Printer Error";
+ case ERROR_BUFFER_FULL:
+ return "Buffer Full";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_media_types(uint8_t v) {
+ switch (v) {
+ case MEDIA_TYPE_UNKNOWN:
+ return "Unknown";
+ case MEDIA_TYPE_PAPER:
+ return "Paper";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_print_methods (uint8_t v) {
+ switch (v & 0xf) {
+ case PRINT_METHOD_STD:
+ return "Standard";
+ case PRINT_METHOD_COMBO_2:
+ return "2up";
+ case PRINT_METHOD_COMBO_3:
+ return "3up";
+ case PRINT_METHOD_SPLIT:
+ return "Split";
+ case PRINT_METHOD_DOUBLE:
+ return "Double";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_print_modes(uint8_t v) {
+ switch (v) {
+ case PRINT_MODE_NO_OC:
+ return "No Overcoat";
+ case PRINT_MODE_GLOSSY:
+ return "Glossy";
+ case PRINT_MODE_MATTE:
+ return "Matte";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_fwinfo_targets (uint8_t v) {
+ switch (v) {
+ case FWINFO_TARGET_MAIN_BOOT:
+ return "Main Boot ";
+ case FWINFO_TARGET_MAIN_APP:
+ return "Main App ";
+ case FWINFO_TARGET_PRINT_TABLES:
+ case FWINFO_TARGET_PRINT_TABLES2: // Seen on EK70xx
+ return "Print Tables";
+ case FWINFO_TARGET_DSP:
+ return "DSP ";
+ case FWINFO_TARGET_USB:
+ return "USB ";
+ default:
+ return "Unknown ";
+ }
+}
+
+const char *sinfonia_print_codes (uint8_t v, int eightinch) {
+ if (eightinch) {
+ switch (v) {
+ case CODE_8x10:
+ return "8x10";
+ case CODE_8x12:
+ case CODE_8x12K:
+ return "8x12";
+ case CODE_8x4:
+ return "8x4";
+ case CODE_8x5:
+ return "8x5";
+ case CODE_8x6:
+ return "8x6";
+ case CODE_8x8:
+ return "8x8";
+ case CODE_8x4_2:
+ return "8x4*2";
+ case CODE_8x5_2:
+ return "8x5*2";
+ case CODE_8x6_2:
+ return "8x6*2";
+ case CODE_8x4_3:
+ return "8x4*3";
+ default:
+ return "Unknown";
+ }
+ }
+
+ switch (v) {
+ case CODE_4x6:
+ return "4x6";
+ case CODE_3_5x5:
+ return "3.5x5";
+ case CODE_5x7:
+ return "5x7";
+ case CODE_6x9:
+ return "6x9";
+ case CODE_6x8:
+ return "6x8";
+ case CODE_2x6:
+ return "2x6";
+ case CODE_6x6:
+ return "6x6";
+ case CODE_89x60mm:
+ return "89x60mm";
+ case CODE_89x59mm:
+ return "89x59mm";
+ case CODE_89x58mm:
+ return "89x58mm";
+ case CODE_89x57mm:
+ return "89x57mm";
+ case CODE_89x56mm:
+ return "89x56mm";
+ case CODE_89x55mm:
+ return "89x55mm";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_status_str(uint8_t v) {
+ switch (v) {
+ case STATUS_READY:
+ return "Ready";
+ case STATUS_INIT_CPU:
+ return "Initializing CPU";
+ case STATUS_INIT_RIBBON:
+ return "Initializing Ribbon";
+ case STATUS_INIT_PAPER:
+ return "Loading Paper";
+ case STATUS_THERMAL_PROTECT:
+ return "Thermal Protection";
+ case STATUS_USING_PANEL:
+ return "Using Operation Panel";
+ case STATUS_SELF_DIAG:
+ return "Processing Self Diagnosis";
+ case STATUS_DOWNLOADING:
+ return "Processing Download";
+ case STATUS_FEEDING_PAPER:
+ return "Feeding Paper";
+ case STATUS_PRE_HEAT:
+ return "Pre-Heating";
+ case STATUS_PRINT_Y:
+ return "Printing Yellow";
+ case STATUS_BACK_FEED_Y:
+ return "Back-Feeding - Yellow Complete";
+ case STATUS_PRINT_M:
+ return "Printing Magenta";
+ case STATUS_BACK_FEED_M:
+ return "Back-Feeding - Magenta Complete";
+ case STATUS_PRINT_C:
+ return "Printing Cyan";
+ case STATUS_BACK_FEED_C:
+ return "Back-Feeding - Cyan Complete";
+ case STATUS_PRINT_OP:
+ return "Laminating";
+ case STATUS_PAPER_CUT:
+ return "Cutting Paper";
+ case STATUS_PAPER_EJECT:
+ return "Ejecting Paper";
+ case STATUS_BACK_FEED_E:
+ return "Back-Feeding - Ejected";
+ case STATUS_FINISHED:
+ return "Print Finished";
+ case ERROR_PRINTER:
+ return "Printer Error";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *sinfonia_cmd_names(uint16_t v) {
+ switch (le16_to_cpu(v)) {
+ case SINFONIA_CMD_GETSTATUS:
+ return "Get Status";
+ case SINFONIA_CMD_MEDIAINFO:
+ return "Get Media Info";
+ case SINFONIA_CMD_MODELNAME:
+ return "Get Model Name";
+ case SINFONIA_CMD_ERRORLOG:
+ return "Get Error Log";
+ case SINFONIA_CMD_GETPARAM:
+ return "Get Parameter";
+ case SINFONIA_CMD_GETSERIAL:
+ return "Get Serial Number";
+ case SINFONIA_CMD_PRINTSTAT:
+ return "Get Print ID Status";
+ case SINFONIA_CMD_EXTCOUNTER:
+ return "Get Extended Counters";
+ case SINFONIA_CMD_PRINTJOB:
+ return "Print";
+ case SINFONIA_CMD_CANCELJOB:
+ return "Cancel Print";
+ case SINFONIA_CMD_FLASHLED:
+ return "Flash LEDs";
+ case SINFONIA_CMD_RESET:
+ return "Reset";
+ case SINFONIA_CMD_READTONE:
+ return "Read Tone Curve";
+ case SINFONIA_CMD_BUTTON:
+ return "Button Enable";
+ case SINFONIA_CMD_SETPARAM:
+ return "Set Parameter";
+ case SINFONIA_CMD_GETUNIQUE:
+ return "Get Unique String";
+ case SINFONIA_CMD_GETCORR:
+ return "Get Image Correction Parameter";
+ case SINFONIA_CMD_GETEEPROM:
+ return "Get EEPROM Backup Parameter";
+ case SINFONIA_CMD_SETEEPROM:
+ return "Set EEPROM Backup Parameter";
+ case SINFONIA_CMD_SETTIME:
+ return "Time Setting";
+ case SINFONIA_CMD_DIAGNOSTIC:
+ return "Diagnostic";
+ case SINFONIA_CMD_FWINFO:
+ return "Get Firmware Info";
+ case SINFONIA_CMD_UPDATE:
+ return "Update";
+ case SINFONIA_CMD_SETUNIQUE:
+ return "Set Unique String";
+ default:
+ return "Unknown Command";
+ }
+}
+
+const char *kodak6_mediatypes(int type)
+{
+ switch(type) {
+ case KODAK6_MEDIA_NONE:
+ return "No media";
+ case KODAK6_MEDIA_6R:
+ case KODAK6_MEDIA_6TR2:
+ case KODAK7_MEDIA_6R:
+ return "Kodak 6R";
+
+ default:
+ return "Unknown";
+ }
+ return "Unknown";
+}
+
+void kodak6_dumpmediacommon(int type)
+{
+ switch (type) {
+ case KODAK6_MEDIA_6R:
+ INFO("Media type: 6R (Kodak 197-4096 or equivalent)\n");
+ break;
+ case KODAK6_MEDIA_6TR2:
+ INFO("Media type: 6R (Kodak 396-2941 or equivalent)\n");
+ break;
+ case KODAK7_MEDIA_6R:
+ INFO("Media type: 6R (Kodak 659-9047 or equivalent)\n");
+ break;
+ default:
+ INFO("Media type %02x (unknown, please report!)\n", type);
+ break;
+ }
+}
+
+/* Below are for S1145 (EK68xx) and S1245 only! */
+const char *sinfonia_1x45_status_str(uint8_t status1, uint32_t status2, uint8_t error)
+{
+ switch(status1) {
+ case STATE_STATUS1_STANDBY:
+ return "Standby (Ready)";
+ case STATE_STATUS1_WAIT:
+ switch (status2) {
+ case WAIT_STATUS2_INIT:
+ return "Wait (Initializing)";
+ case WAIT_STATUS2_RIBBON:
+ return "Wait (Ribbon Winding)";
+ case WAIT_STATUS2_THERMAL:
+ return "Wait (Thermal Protection)";
+ case WAIT_STATUS2_OPERATING:
+ return "Wait (Operating)";
+ case WAIT_STATUS2_BUSY:
+ return "Wait (Busy)";
+ default:
+ return "Wait (Unknown)";
+ }
+ case STATE_STATUS1_ERROR:
+ switch (status2) {
+ case ERROR_STATUS2_CTRL_CIRCUIT:
+ switch (error) {
+ case CTRL_CIR_ERROR_EEPROM1:
+ return "Error (EEPROM1)";
+ case CTRL_CIR_ERROR_EEPROM2:
+ return "Error (EEPROM2)";
+ case CTRL_CIR_ERROR_DSP:
+ return "Error (DSP)";
+ case CTRL_CIR_ERROR_CRC_MAIN:
+ return "Error (Main CRC)";
+ case CTRL_CIR_ERROR_DL_MAIN:
+ return "Error (Main Download)";
+ case CTRL_CIR_ERROR_CRC_DSP:
+ return "Error (DSP CRC)";
+ case CTRL_CIR_ERROR_DL_DSP:
+ return "Error (DSP Download)";
+ case CTRL_CIR_ERROR_ASIC:
+ return "Error (ASIC)";
+ case CTRL_CIR_ERROR_DRAM:
+ return "Error (DRAM)";
+ case CTRL_CIR_ERROR_DSPCOMM:
+ return "Error (DSP Communincation)";
+ default:
+ return "Error (Unknown Circuit)";
+ }
+ case ERROR_STATUS2_MECHANISM_CTRL:
+ switch (error) {
+ case MECH_ERROR_HEAD_UP:
+ return "Error (Head Up Mechanism)";
+ case MECH_ERROR_HEAD_DOWN:
+ return "Error (Head Down Mechanism)";
+ case MECH_ERROR_MAIN_PINCH_UP:
+ return "Error (Main Pinch Up Mechanism)";
+ case MECH_ERROR_MAIN_PINCH_DOWN:
+ return "Error (Main Pinch Down Mechanism)";
+ case MECH_ERROR_SUB_PINCH_UP:
+ return "Error (Sub Pinch Up Mechanism)";
+ case MECH_ERROR_SUB_PINCH_DOWN:
+ return "Error (Sub Pinch Down Mechanism)";
+ case MECH_ERROR_FEEDIN_PINCH_UP:
+ return "Error (Feed-in Pinch Up Mechanism)";
+ case MECH_ERROR_FEEDIN_PINCH_DOWN:
+ return "Error (Feed-in Pinch Down Mechanism)";
+ case MECH_ERROR_FEEDOUT_PINCH_UP:
+ return "Error (Feed-out Pinch Up Mechanism)";
+ case MECH_ERROR_FEEDOUT_PINCH_DOWN:
+ return "Error (Feed-out Pinch Down Mechanism)";
+ case MECH_ERROR_CUTTER_LR:
+ return "Error (Left->Right Cutter)";
+ case MECH_ERROR_CUTTER_RL:
+ return "Error (Right->Left Cutter)";
+ default:
+ return "Error (Unknown Mechanism)";
+ }
+ case ERROR_STATUS2_SENSOR:
+ switch (error) {
+ case SENSOR_ERROR_CUTTER:
+ return "Error (Cutter Sensor)";
+ case SENSOR_ERROR_HEAD_DOWN:
+ return "Error (Head Down Sensor)";
+ case SENSOR_ERROR_HEAD_UP:
+ return "Error (Head Up Sensor)";
+ case SENSOR_ERROR_MAIN_PINCH_DOWN:
+ return "Error (Main Pinch Down Sensor)";
+ case SENSOR_ERROR_MAIN_PINCH_UP:
+ return "Error (Main Pinch Up Sensor)";
+ case SENSOR_ERROR_FEED_PINCH_DOWN:
+ return "Error (Feed Pinch Down Sensor)";
+ case SENSOR_ERROR_FEED_PINCH_UP:
+ return "Error (Feed Pinch Up Sensor)";
+ case SENSOR_ERROR_EXIT_PINCH_DOWN:
+ return "Error (Exit Pinch Up Sensor)";
+ case SENSOR_ERROR_EXIT_PINCH_UP:
+ return "Error (Exit Pinch Up Sensor)";
+ case SENSOR_ERROR_LEFT_CUTTER:
+ return "Error (Left Cutter Sensor)";
+ case SENSOR_ERROR_RIGHT_CUTTER:
+ return "Error (Right Cutter Sensor)";
+ case SENSOR_ERROR_CENTER_CUTTER:
+ return "Error (Center Cutter Sensor)";
+ case SENSOR_ERROR_UPPER_CUTTER:
+ return "Error (Upper Cutter Sensor)";
+ case SENSOR_ERROR_PAPER_FEED_COVER:
+ return "Error (Paper Feed Cover)";
+ default:
+ return "Error (Unknown Sensor)";
+ }
+ case ERROR_STATUS2_COVER_OPEN:
+ switch (error) {
+ case COVER_OPEN_ERROR_UPPER:
+ return "Error (Upper Cover Open)";
+ case COVER_OPEN_ERROR_LOWER:
+ return "Error (Lower Cover Open)";
+ default:
+ return "Error (Unknown Cover Open)";
+ }
+ case ERROR_STATUS2_TEMP_SENSOR:
+ switch (error) {
+ case TEMP_SENSOR_ERROR_HEAD_HIGH:
+ return "Error (Head Temperature High)";
+ case TEMP_SENSOR_ERROR_HEAD_LOW:
+ return "Error (Head Temperature Low)";
+ case TEMP_SENSOR_ERROR_ENV_HIGH:
+ return "Error (Environmental Temperature High)";
+ case TEMP_SENSOR_ERROR_ENV_LOW:
+ return "Error (Environmental Temperature Low)";
+ default:
+ return "Error (Unknown Temperature)";
+ }
+ case ERROR_STATUS2_PAPER_JAM:
+ return "Error (Paper Jam)";
+ case ERROR_STATUS2_PAPER_EMPTY:
+ return "Error (Paper Empty)";
+ case ERROR_STATUS2_RIBBON_ERR:
+ return "Error (Ribbon)";
+ default:
+ return "Error (Unknown)";
+ }
+ default:
+ return "Unknown!";
+ }
+}
diff --git a/src/cups/backend_sinfonia.h b/src/cups/backend_sinfonia.h
new file mode 100644
index 0000000..9f8030e
--- /dev/null
+++ b/src/cups/backend_sinfonia.h
@@ -0,0 +1,562 @@
+ /*
+ * Shinko/Sinfonia Common Code
+ *
+ * (c) 2019 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]
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+
+#define LIBSINFONIA_VER "0.08"
+
+#define SINFONIA_HDR1_LEN 0x10
+#define SINFONIA_HDR2_LEN 0x64
+#define SINFONIA_HDR_LEN (SINFONIA_HDR1_LEN + SINFONIA_HDR2_LEN)
+#define SINFONIA_DPI 300
+
+struct sinfonia_job_param {
+ uint32_t columns;
+ uint32_t rows;
+ uint32_t copies;
+
+ uint32_t method;
+ uint32_t media;
+ uint32_t oc_mode;
+
+ uint32_t quality;
+
+ int mattedepth;
+ uint32_t dust;
+
+ uint32_t ext_flags;
+};
+
+struct sinfonia_printjob {
+ struct sinfonia_job_param jp;
+
+ uint8_t *databuf;
+ int datalen;
+ int copies;
+};
+
+int sinfonia_read_parse(int data_fd, uint32_t model,
+ struct sinfonia_printjob *job);
+
+int sinfonia_raw10_read_parse(int data_fd, struct sinfonia_printjob *job);
+int sinfonia_raw18_read_parse(int data_fd, struct sinfonia_printjob *job);
+int sinfonia_raw28_read_parse(int data_fd, struct sinfonia_printjob *job);
+void sinfonia_cleanup_job(const void *vjob);
+
+/* Common usb functions */
+struct sinfonia_usbdev {
+ struct libusb_device_handle *dev;
+ uint8_t endp_up;
+ uint8_t endp_down;
+ int type;
+
+ char const *(*error_codes)(uint8_t major, uint8_t minor);
+};
+int sinfonia_docmd(struct sinfonia_usbdev *usbh,
+ uint8_t *cmd, int cmdlen,
+ uint8_t *resp, int resplen,
+ int *num);
+int sinfonia_flashled(struct sinfonia_usbdev *usbh);
+int sinfonia_canceljob(struct sinfonia_usbdev *usbh, int id);
+int sinfonia_getparam(struct sinfonia_usbdev *usbh, int target, uint32_t *param);
+int sinfonia_setparam(struct sinfonia_usbdev *usbh, int target, uint32_t param);
+int sinfonia_getfwinfo(struct sinfonia_usbdev *usbh);
+int sinfonia_geterrorlog(struct sinfonia_usbdev *usbh);
+int sinfonia_resetcurve(struct sinfonia_usbdev *usbh, int target, int id);
+int sinfonia_gettonecurve(struct sinfonia_usbdev *usbh, int type, char *fname);
+int sinfonia_settonecurve(struct sinfonia_usbdev *usbh, int target, char *fname);
+
+#define BANK_STATUS_FREE 0x00
+#define BANK_STATUS_XFER 0x01
+#define BANK_STATUS_FULL 0x02
+#define BANK_STATUS_PRINTING 0x12 /* Not on S2145 */
+
+const char *sinfonia_bank_statuses(uint8_t v);
+
+#define UPDATE_TARGET_USER 0x03
+#define UPDATE_TARGET_CURRENT 0x04
+
+/* Update is three channels, Y, M, C;
+ each is 256 entries of 11-bit data padded to 16-bits.
+ Printer expects LE data. We use BE data on disk.
+*/
+#define TONE_CURVE_SIZE 0x600
+const char *sinfonia_update_targets (uint8_t v);
+
+#define TONECURVE_INIT 0x00
+#define TONECURVE_USER 0x01
+#define TONECURVE_CURRENT 0x02
+
+const char *sinfonia_tonecurve_statuses (uint8_t v);
+
+struct sinfonia_error_item {
+ uint8_t major;
+ uint8_t minor;
+ uint32_t print_counter;
+} __attribute__((packed));
+
+#define ERROR_NONE 0x00
+#define ERROR_INVALID_PARAM 0x01
+#define ERROR_MAIN_APP_INACTIVE 0x02
+#define ERROR_COMMS_TIMEOUT 0x03
+#define ERROR_MAINT_NEEDED 0x04
+#define ERROR_BAD_COMMAND 0x05
+#define ERROR_PRINTER 0x11
+#define ERROR_BUFFER_FULL 0x21
+
+const char *sinfonia_error_str(uint8_t v);
+
+enum {
+ MEDIA_TYPE_UNKNOWN = 0x00,
+ MEDIA_TYPE_PAPER = 0x01,
+};
+
+const char *sinfonia_media_types(uint8_t v);
+
+#define PRINT_MODE_NO_OC 0x01
+#define PRINT_MODE_GLOSSY 0x02
+#define PRINT_MODE_MATTE 0x03
+const char *sinfonia_print_modes(uint8_t v);
+
+#define PRINT_METHOD_STD 0x00
+#define PRINT_METHOD_COMBO_2 0x02
+#define PRINT_METHOD_COMBO_3 0x03 // S6245 only
+#define PRINT_METHOD_SPLIT 0x04
+#define PRINT_METHOD_DOUBLE 0x08 // S6145 only
+#define PRINT_METHOD_DISABLE_ERR 0x10 // S6245 only
+#define PRINT_METHOD_NOTRIM 0x80 // S6145 only
+
+const char *sinfonia_print_methods (uint8_t v);
+
+#define FWINFO_TARGET_MAIN_BOOT 0x01
+#define FWINFO_TARGET_MAIN_APP 0x02
+#define FWINFO_TARGET_PRINT_TABLES 0x03
+#define FWINFO_TARGET_DSP 0x04
+#define FWINFO_TARGET_USB 0x06
+#define FWINFO_TARGET_PRINT_TABLES2 0x07
+
+const char *sinfonia_fwinfo_targets (uint8_t v);
+
+/* Common command structs */
+struct sinfonia_cmd_hdr {
+ uint16_t cmd;
+ uint16_t len; /* Not including this header */
+} __attribute__((packed));
+
+struct sinfonia_status_hdr {
+ uint8_t result;
+ uint8_t error;
+ uint8_t printer_major;
+ uint8_t printer_minor;
+ uint8_t reserved[2];
+ uint8_t mode; /* S6245 and EK605 only, so far */
+ uint8_t status;
+ uint16_t payload_len;
+} __attribute__((packed));
+
+struct sinfonia_cancel_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t id;
+} __attribute__((packed));
+
+struct sinfonia_fwinfo_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t target;
+} __attribute__((packed));
+
+struct sinfonia_fwinfo_resp {
+ struct sinfonia_status_hdr hdr;
+ uint8_t name[8];
+ uint8_t type[16];
+ uint8_t date[10];
+ uint8_t major;
+ uint8_t minor;
+ uint16_t checksum;
+} __attribute__((packed));
+
+struct sinfonia_errorlog_resp {
+ struct sinfonia_status_hdr hdr;
+ uint8_t count;
+ struct sinfonia_error_item items[10]; /* Not all necessarily used */
+} __attribute__((packed));
+
+struct sinfonia_mediainfo_item {
+ uint8_t code;
+ uint16_t columns;
+ uint16_t rows;
+ uint8_t type; /* S2145, EK68xx, EK605 only -- MEDIA_TYPE_* */
+ uint8_t method; /* PRINT_METHOD_* */
+ uint8_t flag; /* EK68xx only */
+ uint8_t reserved[2];
+} __attribute__((packed));
+
+struct sinfonia_setparam_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t target;
+ uint32_t param;
+} __attribute__((packed));
+
+struct sinfonia_diagnostic_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t arg1;
+ uint8_t arg2;
+ uint8_t arg3;
+} __attribute__((packed));
+
+struct sinfonia_getparam_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t target;
+} __attribute__((packed));
+
+struct sinfonia_getparam_resp {
+ struct sinfonia_status_hdr hdr;
+ uint32_t param;
+} __attribute__((packed));
+
+struct sinfonia_getprintidstatus_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t id;
+} __attribute__((packed));
+
+struct sinfonia_getprintidstatus_resp {
+ struct sinfonia_status_hdr hdr;
+ uint8_t id;
+ uint16_t remaining;
+ uint16_t finished;
+ uint16_t specified;
+ uint16_t status;
+} __attribute__((packed));
+
+#define IDSTATUS_WAITING 0x0000
+#define IDSTATUS_PRINTING 0x0100
+#define IDSTATUS_COMPLETED 0x0200
+#define IDSTATUS_ERROR 0xFFFF
+
+struct sinfonia_reset_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t target;
+ uint8_t curveid;
+} __attribute__((packed));
+
+#define RESET_PRINTER 0x03
+#define RESET_TONE_CURVE 0x04
+
+#define TONE_CURVE_ID 0x01
+
+struct sinfonia_readtone_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t target;
+ uint8_t curveid;
+} __attribute__((packed));
+
+#define READ_TONE_CURVE_USER 0x01
+#define READ_TONE_CURVE_CURR 0x02
+
+struct sinfonia_readtone_resp {
+ struct sinfonia_status_hdr hdr;
+ uint16_t total_size;
+} __attribute__((packed));
+
+struct sinfonia_update_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t target;
+ uint8_t curve_id;
+ uint8_t reset; // ??
+ uint8_t reserved[3];
+ uint32_t size;
+} __attribute__((packed));
+
+struct sinfonia_getserial_resp {
+ struct sinfonia_status_hdr hdr;
+ uint8_t data[8];
+} __attribute__((packed));
+
+struct sinfonia_getextcounter_resp {
+ struct sinfonia_status_hdr hdr;
+ uint32_t lifetime_distance; /* Inches */
+ uint32_t maint_distance;
+ uint32_t head_distance;
+ uint8_t reserved[32];
+} __attribute__((packed));
+
+struct sinfonia_seteeprom_cmd {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t data[256]; /* Maxlen */
+} __attribute__((packed));
+
+struct sinfonia_printcmd10_hdr {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t jobid;
+ uint16_t copies;
+ uint16_t columns;
+ uint16_t rows;
+ uint8_t media;
+ uint8_t oc_mode;
+ uint8_t method;
+} __attribute__((packed));
+
+struct sinfonia_printcmd18_hdr {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t jobid;
+ uint16_t copies;
+ uint16_t columns;
+ uint16_t rows;
+ uint8_t reserved[8]; // columns and rows repeated, then nulls
+ uint8_t oc_mode;
+ uint8_t method;
+ uint8_t media; // reserved?
+} __attribute__((packed));
+
+struct sinfonia_printcmd28_hdr {
+ struct sinfonia_cmd_hdr hdr;
+ uint8_t jobid;
+ uint16_t copies;
+ uint16_t columns;
+ uint16_t rows;
+ uint8_t media;
+ uint8_t reserved[7];
+ uint8_t options;
+ uint8_t method;
+ uint8_t reserved2[11];
+} __attribute__((packed));
+
+#define CODE_4x6 0x00
+#define CODE_3_5x5 0x01
+#define CODE_5x7 0x03
+#define CODE_6x9 0x05
+#define CODE_6x8 0x06
+#define CODE_2x6 0x07
+#define CODE_6x6 0x08
+
+#define CODE_8x10 0x10
+#define CODE_8x12 0x11
+#define CODE_8x4 0x20
+#define CODE_8x5 0x21
+#define CODE_8x6 0x22
+#define CODE_8x8 0x23
+#define CODE_8x4_2 0x30
+#define CODE_8x5_2 0x31
+#define CODE_8x6_2 0x32
+#define CODE_8x4_3 0x40
+
+#define CODE_8x12K 0x02 /* Kodak 8810 */
+
+
+#define CODE_89x60mm 0x10
+#define CODE_89x59mm 0x11
+#define CODE_89x58mm 0x12
+#define CODE_89x57mm 0x13
+#define CODE_89x56mm 0x14
+#define CODE_89x55mm 0x15
+
+const char *sinfonia_print_codes (uint8_t v, int eightinch);
+
+#define STATUS_READY 0x00
+#define STATUS_INIT_CPU 0x31
+#define STATUS_INIT_RIBBON 0x32
+#define STATUS_INIT_PAPER 0x33
+#define STATUS_THERMAL_PROTECT 0x34
+#define STATUS_USING_PANEL 0x35
+#define STATUS_SELF_DIAG 0x36
+#define STATUS_DOWNLOADING 0x37
+
+#define STATUS_FEEDING_PAPER 0x61
+#define STATUS_PRE_HEAT 0x62
+#define STATUS_PRINT_Y 0x63
+#define STATUS_BACK_FEED_Y 0x64
+#define STATUS_PRINT_M 0x65
+#define STATUS_BACK_FEED_M 0x66
+#define STATUS_PRINT_C 0x67
+#define STATUS_BACK_FEED_C 0x68
+#define STATUS_PRINT_OP 0x69
+#define STATUS_PAPER_CUT 0x6A
+#define STATUS_PAPER_EJECT 0x6B
+#define STATUS_BACK_FEED_E 0x6C
+#define STATUS_FINISHED 0x6D
+
+const char *sinfonia_status_str(uint8_t v);
+
+#define SINFONIA_CMD_GETSTATUS 0x0001
+#define SINFONIA_CMD_MEDIAINFO 0x0002
+#define SINFONIA_CMD_MODELNAME 0x0003 // 2145 only
+#define SINFONIA_CMD_ERRORLOG 0x0004
+#define SINFONIA_CMD_GETPARAM 0x0005 // !2145
+#define SINFONIA_CMD_GETSERIAL 0x0006 // !2145
+#define SINFONIA_CMD_PRINTSTAT 0x0007 // !2145
+#define SINFONIA_CMD_EXTCOUNTER 0x0008 // !2145
+
+#define SINFONIA_CMD_MEMORYBANK 0x000A // Brava 21 only?
+
+#define SINFONIA_CMD_PRINTJOB 0x4001
+#define SINFONIA_CMD_CANCELJOB 0x4002
+#define SINFONIA_CMD_FLASHLED 0x4003
+#define SINFONIA_CMD_RESET 0x4004
+#define SINFONIA_CMD_READTONE 0x4005
+#define SINFONIA_CMD_BUTTON 0x4006 // 2145 only
+#define SINFONIA_CMD_SETPARAM 0x4007
+
+#define SINFONIA_CMD_GETUNIQUE 0x8003 // 2145 only
+
+#define SINFONIA_CMD_GETCORR 0x400D
+#define SINFONIA_CMD_GETEEPROM 0x400E
+#define SINFONIA_CMD_SETEEPROM 0x400F
+#define SINFONIA_CMD_SETTIME 0x4011 // 6245 only
+
+#define SINFONIA_CMD_DIAGNOSTIC 0xC001 // ??
+#define SINFONIA_CMD_FWINFO 0xC003
+#define SINFONIA_CMD_UPDATE 0xC004
+#define SINFONIA_CMD_SETUNIQUE 0xC007 // 2145 only
+
+const char *sinfonia_cmd_names(uint16_t v);
+
+//#define KODAK6_MEDIA_5R // 189-9160
+#define KODAK6_MEDIA_6R 0x0b // 197-4096 [ Also: 101-0867, 141-9597, 659-9054, 169-6418, DNP-900-060 ]
+#define KODAK6_MEDIA_UNK 0x03 // ??? reported but unknown
+#define KODAK6_MEDIA_6TR2 0x2c // 396-2941
+//#define KODAK6_MEDIA_5FR2 // 6900-compatible
+//#define KODAK6_MEDIA_6FR2 // 6900-compatible, 102-5925
+#define KODAK6_MEDIA_NONE 0x00
+//#define KODAK7_MEDIA_5R // 164-9011 137-0600
+#define KODAK7_MEDIA_6R 0x29 // 659-9047 166-1925 396-2966 846-2004 103-7688 DNP-900-070 -- ALSO FUJI R68-D2P570 16578944
+//#define KODAK7_MEDIA_6TA2
+//#define KODAK7_MEDIA_5TA2
+
+const char *kodak6_mediatypes(int type);
+void kodak6_dumpmediacommon(int type);
+
+#define RESULT_SUCCESS 0x01
+#define RESULT_FAIL 0x02
+
+/* ********** Below are for the old S1145 (EK68xx) and S1245 only! */
+
+enum {
+ CMD_CODE_OK = 1,
+ CMD_CODE_BAD = 2,
+};
+
+enum {
+ STATUS_PRINTING = 1,
+ STATUS_IDLE = 2,
+};
+
+enum {
+ STATE_STATUS1_STANDBY = 1,
+ STATE_STATUS1_ERROR = 2,
+ STATE_STATUS1_WAIT = 3,
+};
+
+#define STATE_STANDBY_STATUS2 0x0
+
+enum {
+ WAIT_STATUS2_INIT = 0,
+ WAIT_STATUS2_RIBBON = 1,
+ WAIT_STATUS2_THERMAL = 2,
+ WAIT_STATUS2_OPERATING = 3,
+ WAIT_STATUS2_BUSY = 4,
+};
+
+#define ERROR_STATUS2_CTRL_CIRCUIT (0x80000000)
+#define ERROR_STATUS2_MECHANISM_CTRL (0x40000000)
+#define ERROR_STATUS2_SENSOR (0x00002000)
+#define ERROR_STATUS2_COVER_OPEN (0x00001000)
+#define ERROR_STATUS2_TEMP_SENSOR (0x00000200)
+#define ERROR_STATUS2_PAPER_JAM (0x00000100)
+#define ERROR_STATUS2_PAPER_EMPTY (0x00000040)
+#define ERROR_STATUS2_RIBBON_ERR (0x00000010)
+
+enum {
+ CTRL_CIR_ERROR_EEPROM1 = 0x01,
+ CTRL_CIR_ERROR_EEPROM2 = 0x02,
+ CTRL_CIR_ERROR_DSP = 0x04,
+ CTRL_CIR_ERROR_CRC_MAIN = 0x06,
+ CTRL_CIR_ERROR_DL_MAIN = 0x07,
+ CTRL_CIR_ERROR_CRC_DSP = 0x08,
+ CTRL_CIR_ERROR_DL_DSP = 0x09,
+ CTRL_CIR_ERROR_ASIC = 0x0a,
+ CTRL_CIR_ERROR_DRAM = 0x0b,
+ CTRL_CIR_ERROR_DSPCOMM = 0x29,
+};
+
+enum {
+ MECH_ERROR_HEAD_UP = 0x01,
+ MECH_ERROR_HEAD_DOWN = 0x02,
+ MECH_ERROR_MAIN_PINCH_UP = 0x03,
+ MECH_ERROR_MAIN_PINCH_DOWN = 0x04,
+ MECH_ERROR_SUB_PINCH_UP = 0x05,
+ MECH_ERROR_SUB_PINCH_DOWN = 0x06,
+ MECH_ERROR_FEEDIN_PINCH_UP = 0x07,
+ MECH_ERROR_FEEDIN_PINCH_DOWN = 0x08,
+ MECH_ERROR_FEEDOUT_PINCH_UP = 0x09,
+ MECH_ERROR_FEEDOUT_PINCH_DOWN = 0x0a,
+ MECH_ERROR_CUTTER_LR = 0x0b,
+ MECH_ERROR_CUTTER_RL = 0x0c,
+};
+
+enum {
+ SENSOR_ERROR_CUTTER = 0x05,
+ SENSOR_ERROR_HEAD_DOWN = 0x09,
+ SENSOR_ERROR_HEAD_UP = 0x0a,
+ SENSOR_ERROR_MAIN_PINCH_DOWN = 0x0b,
+ SENSOR_ERROR_MAIN_PINCH_UP = 0x0c,
+ SENSOR_ERROR_FEED_PINCH_DOWN = 0x0d,
+ SENSOR_ERROR_FEED_PINCH_UP = 0x0e,
+ SENSOR_ERROR_EXIT_PINCH_DOWN = 0x0f,
+ SENSOR_ERROR_EXIT_PINCH_UP = 0x10,
+ SENSOR_ERROR_LEFT_CUTTER = 0x11,
+ SENSOR_ERROR_RIGHT_CUTTER = 0x12,
+ SENSOR_ERROR_CENTER_CUTTER = 0x13,
+ SENSOR_ERROR_UPPER_CUTTER = 0x14,
+ SENSOR_ERROR_PAPER_FEED_COVER = 0x15,
+};
+
+enum {
+ TEMP_SENSOR_ERROR_HEAD_HIGH = 0x01,
+ TEMP_SENSOR_ERROR_HEAD_LOW = 0x02,
+ TEMP_SENSOR_ERROR_ENV_HIGH = 0x03,
+ TEMP_SENSOR_ERROR_ENV_LOW = 0x04,
+};
+
+enum {
+ COVER_OPEN_ERROR_UPPER = 0x01,
+ COVER_OPEN_ERROR_LOWER = 0x02,
+};
+
+enum {
+ PAPER_EMPTY_ERROR = 0x00,
+};
+
+enum {
+ RIBBON_ERROR = 0x00,
+};
+
+enum {
+ CURVE_TABLE_STATUS_INITIAL = 0x00,
+ CURVE_TABLE_STATUS_USERSET = 0x01,
+ CURVE_TABLE_STATUS_CURRENT = 0x02,
+};
+
+const char *sinfonia_1x45_status_str(uint8_t status1, uint32_t status2, uint8_t error);
diff --git a/src/cups/backend_sonyupd.c b/src/cups/backend_sonyupd.c
new file mode 100644
index 0000000..1180039
--- /dev/null
+++ b/src/cups/backend_sonyupd.c
@@ -0,0 +1,1024 @@
+/*
+ * Sony UP-D series Photo Printer CUPS backend -- libusb-1.0 version
+ *
+ * (c) 2013-2019 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, see <https://www.gnu.org/licenses/>.
+ *
+ * [http://www.gnu.org/licenses/gpl-2.0.html]
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+
+#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 sonyupd_backend
+
+#include "backend_common.h"
+
+/* Printer status
+ --> 1b e0 00 00 00 00 XX 00 [[ XX is 0xe on UPD895, 0xf on others ]]
+ <-- this struct
+*/
+struct sony_updsts {
+ uint8_t len; /* 0x0d/0x0e (ie number of bytes AFTER this one) */
+ uint8_t zero1; /* 0x00 */
+ uint8_t printing; /* UPD_PRINTING_* */
+ uint8_t remain; /* Number of remaining pages */
+ uint8_t zero2;
+ uint8_t sts1; /* UPD_STS1_* */
+ uint8_t sts2; /* seconday status */
+ uint8_t sts3; /* tertiary status */
+ uint16_t unk; /* seen 0x04a0 UP-CR10L, 0x04a8 on UP-DR150 */
+ uint16_t max_cols; /* BE */
+ uint16_t max_rows; /* BE */
+ uint8_t percent; /* 0-99, if job is printing (UP-D89x) */
+} __attribute__((packed));
+
+#define UPD_PRINTING_BW 0xe0 /* UPD-895/897 only */
+#define UPD_PRINTING_Y 0x40
+#define UPD_PRINTING_M 0x80
+#define UPD_PRINTING_C 0xc0
+#define UPD_PRINTING_O 0x20
+#define UPD_PRINTING_IDLE 0x00
+
+#define UPD_STS1_IDLE 0x00
+#define UPD_STS1_DOOROPEN 0x08
+#define UPD_STS1_NOPAPER 0x40
+#define UPD_STS1_PRINTING 0x80
+
+/* Private data structures */
+struct upd_printjob {
+ uint8_t *databuf;
+ int datalen;
+
+ int copies;
+ uint16_t rows;
+ uint16_t cols;
+ uint32_t imglen;
+};
+
+struct upd_ctx {
+ struct libusb_device_handle *dev;
+ uint8_t endp_up;
+ uint8_t endp_down;
+ int type;
+
+ int native_bpp;
+
+ struct sony_updsts stsbuf;
+
+ struct marker marker;
+};
+
+/* Now for the code */
+static void* upd_init(void)
+{
+ struct upd_ctx *ctx = malloc(sizeof(struct upd_ctx));
+ if (!ctx) {
+ ERROR("Memory Allocation Failure!");
+ return NULL;
+ }
+ memset(ctx, 0, sizeof(struct upd_ctx));
+ return ctx;
+}
+
+static int upd_attach(void *vctx, struct libusb_device_handle *dev, int type,
+ uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
+{
+ struct upd_ctx *ctx = vctx;
+
+ UNUSED(jobid);
+
+ ctx->dev = dev;
+ ctx->endp_up = endp_up;
+ ctx->endp_down = endp_down;
+ ctx->type = type;
+
+ if (ctx->type == P_SONY_UPD895 || ctx->type == P_SONY_UPD897) {
+ ctx->marker.color = "#000000"; /* Ie black! */
+ ctx->native_bpp = 1;
+ } else {
+ ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
+ ctx->native_bpp = 3;
+ }
+
+ ctx->marker.name = "Unknown";
+ ctx->marker.levelmax = -1;
+ ctx->marker.levelnow = -2;
+
+ return CUPS_BACKEND_OK;
+}
+
+static void upd_cleanup_job(const void *vjob)
+{
+ const struct upd_printjob *job = vjob;
+
+ if (job->databuf)
+ free(job->databuf);
+
+ free((void*)job);
+}
+
+// UP-DR200
+// 2UPC-R203 3.5x5 (770)
+// 2UPC-R204 4x6 (700)
+// 2UPC-R205 5x7 (400)
+// 2UPC-R206 6x8 (350)
+
+// UP-DR150
+// 2UPC-R153 (610)
+// 2UPC-R154 (550)
+// 2UPC-R155 (335)
+// 2UPC-R156 (295)
+
+// print order: ->YMCO->
+// current prints (power on)
+// total prints (lifetime)
+// f/w version
+
+static char* upd895_statuses(uint8_t code)
+{
+ switch (code) {
+ case UPD_STS1_IDLE:
+ return "Idle";
+ case UPD_STS1_DOOROPEN:
+ return "Door open";
+ case UPD_STS1_NOPAPER:
+ return "No paper";
+ case UPD_STS1_PRINTING:
+ return "Printing";
+ default:
+ return "Unknown";
+ }
+}
+
+static int sony_get_status(struct upd_ctx *ctx, struct sony_updsts *buf)
+{
+ int ret, num = 0;
+ uint8_t query[7] = { 0x1b, 0xe0, 0, 0, 0, 0x0f, 0 };
+
+ if (ctx->type == P_SONY_UPD895)
+ query[5] = 0x0e;
+
+ if ((ret = send_data(ctx->dev, ctx->endp_down,
+ query, sizeof(query))))
+ return CUPS_BACKEND_FAILED;
+
+ ret = read_data(ctx->dev, ctx->endp_up, (uint8_t*) buf, sizeof(*buf),
+ &num);
+
+ if (ret < 0)
+ return CUPS_BACKEND_FAILED;
+#if 0
+ if (ctx->type == P_SONY_UPD895 && ret != 14)
+ return CUPS_BACKEND_FAILED;
+ else if (ret != 15)
+ return CUPS_BACKEND_FAILED;
+#endif
+
+ ctx->stsbuf.max_cols = be16_to_cpu(ctx->stsbuf.max_cols);
+ ctx->stsbuf.max_rows = be16_to_cpu(ctx->stsbuf.max_rows);
+
+ return CUPS_BACKEND_OK;
+}
+
+#define MAX_PRINTJOB_LEN (2048*2764*3 + 2048)
+
+static int upd_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
+ struct upd_ctx *ctx = vctx;
+ int len, run = 1;
+ uint32_t copies_offset = 0;
+ uint32_t param_offset = 0;
+ uint32_t data_offset = 0;
+
+ struct upd_printjob *job = NULL;
+
+ if (!ctx)
+ return CUPS_BACKEND_FAILED;
+
+ job = malloc(sizeof(*job));
+ if (!job) {
+ ERROR("Memory allocation failure!\n");
+ return CUPS_BACKEND_RETRY_CURRENT;
+ }
+ memset(job, 0, sizeof(*job));
+ job->copies = copies;
+
+ job->datalen = 0;
+ job->databuf = malloc(MAX_PRINTJOB_LEN);
+ if (!job->databuf) {
+ ERROR("Memory allocation failure!\n");
+ upd_cleanup_job(job);
+ return CUPS_BACKEND_RETRY_CURRENT;
+ }
+
+ while(run) {
+ int i;
+ int keep = 0;
+ i = read(data_fd, job->databuf + job->datalen, 4);
+ if (i < 0) {
+ upd_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
+ if (i == 0)
+ break;
+
+ memcpy(&len, job->databuf + job->datalen, sizeof(len));
+ len = le32_to_cpu(len);
+
+ /* Filter out chunks we don't send to the printer */
+ if (len & 0xf0000000) {
+ switch (len) {
+ case 0xfffffff3:
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ if (ctx->type == P_SONY_UPDR150)
+ run = 0;
+ break;
+ case 0xfffffff7:
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ if (ctx->type == P_SONY_UPCR10)
+ run = 0;
+ break;
+ case 0xfffffff8: // 895
+ case 0xfffffff4: // 897
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ if (ctx->type == P_SONY_UPD895 || ctx->type == P_SONY_UPD897)
+ run = 0;
+ break;
+ case 0xffffff97:
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 12);
+ len = 12;
+ break;
+ case 0xffffffef:
+ if (ctx->type == P_SONY_UPD895 || ctx->type == P_SONY_UPD897) {
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ break;
+ }
+ /* Intentional Fallthrough */
+ case 0xffffffeb:
+ case 0xffffffee:
+ case 0xfffffff5:
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 4);
+ len = 4;
+ break;
+ case 0xffffffec:
+ if (ctx->type == P_SONY_UPD897) {
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 4);
+ len = 4;
+ break;
+ }
+ /* Intentional Fallthrough */
+ default:
+ if(dyesub_debug)
+ DEBUG("Block ID '%08x' (len %d)\n", len, 0);
+ len = 0;
+ break;
+ }
+ } else {
+ /* Only keep these chunks */
+ if(dyesub_debug)
+ DEBUG("Data block (len %d)\n", len);
+ if (len > 0)
+ keep = 1;
+ }
+ if (keep)
+ job->datalen += sizeof(uint32_t);
+
+ /* Make sure we're not too large */
+ if (job->datalen + len > MAX_PRINTJOB_LEN) {
+ ERROR("Buffer overflow when parsing printjob! (%d+%d)\n",
+ job->datalen, len);
+ upd_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Read in the data chunk */
+ while(len > 0) {
+ i = read(data_fd, job->databuf + job->datalen, len);
+ if (i < 0) {
+ upd_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
+ if (i == 0)
+ break;
+
+ /* Work out offset of copies command */
+ if (job->databuf[job->datalen] == 0x1b) {
+ int offset = 0;
+ if (i == 7)
+ offset = 4;
+
+ switch (job->databuf[job->datalen + 1]) {
+ case 0x15: /* Print dimensions */
+ param_offset = job->datalen + 16 + offset;
+ break;
+ case 0xee:
+ copies_offset = job->datalen + 7 + offset;
+ break;
+ case 0xe1: /* Image dimensions */
+ param_offset = job->datalen + 14 + offset;
+ break;
+ case 0xea:
+ data_offset = job->datalen + 6 + offset;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (keep)
+ job->datalen += i;
+ len -= i;
+ }
+ }
+ if (!job->datalen) {
+ upd_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Some models specify copies in the print job */
+ if (copies_offset) {
+ uint16_t tmp = copies;
+ tmp = cpu_to_be16(copies);
+ memcpy(job->databuf + copies_offset, &tmp, sizeof(tmp));
+ job->copies = 1;
+ }
+
+ /* Parse some other stuff */
+ if (param_offset) {
+ memcpy(&job->cols, job->databuf + param_offset, sizeof(uint16_t));
+ memcpy(&job->rows, job->databuf + param_offset + 2, sizeof(uint16_t));
+ job->cols = be16_to_cpu(job->cols);
+ job->rows = be16_to_cpu(job->rows);
+ }
+ if (data_offset) {
+ memcpy(&job->imglen, job->databuf + data_offset, sizeof(uint32_t));
+ job->imglen = be32_to_cpu(job->imglen);
+ }
+
+ /* Sanity check job parameters */
+ if (job->imglen != (uint32_t)(job->rows * job->cols * ctx->native_bpp))
+ {
+ ERROR("Job data length mismatch (%u vs %d)!\n",
+ job->imglen, job->rows * job->cols * ctx->native_bpp);
+ upd_cleanup_job(job);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ *vjob = job;
+
+ return CUPS_BACKEND_OK;
+}
+
+static int upd_main_loop(void *vctx, const void *vjob) {
+ struct upd_ctx *ctx = vctx;
+ int i, ret;
+ int copies;
+
+ const struct upd_printjob *job = vjob;
+
+ if (!ctx)
+ return CUPS_BACKEND_FAILED;
+ if (!job)
+ return CUPS_BACKEND_FAILED;
+
+ copies = job->copies;
+
+top:
+ /* Send Unknown CMD. Resets? */
+ if (ctx->type == P_SONY_UPD897) {
+ const uint8_t cmdbuf[7] = { 0x1b, 0x1f, 0, 0, 0, 0, 0 };
+ ret = send_data(ctx->dev, ctx->endp_down,
+ cmdbuf, sizeof(cmdbuf));
+ if (ret)
+ return CUPS_BACKEND_FAILED;
+ }
+
+ /* Query printer status */
+ ret = sony_get_status(ctx, &ctx->stsbuf);
+
+ if (ret)
+ return CUPS_BACKEND_FAILED;
+
+ /* Sanity check job parameters */
+ if (job->rows > ctx->stsbuf.max_rows ||
+ job->cols > ctx->stsbuf.max_cols) {
+ ERROR("Job dimensions (%u/%u) exceed printer max (%u/%u)\n",
+ job->cols, job->rows,
+ ctx->stsbuf.max_cols,
+ ctx->stsbuf.max_rows);
+ return CUPS_BACKEND_CANCEL;
+ }
+
+ /* Check for idle */
+ if (ctx->stsbuf.sts1 != 0x00) {
+ if (ctx->stsbuf.sts1 == 0x80) {
+ INFO("Waiting for printer idle...\n");
+ sleep(1);
+ goto top;
+ }
+ }
+
+ /* Send RESET */
+ if (ctx->type != P_SONY_UPD895) {
+ const uint8_t rstbuf[7] = { 0x1b, 0x16, 0, 0, 0, 0, 0 };
+ ret = send_data(ctx->dev, ctx->endp_down,
+ rstbuf, sizeof(rstbuf));
+ if (ret)
+ return CUPS_BACKEND_FAILED;
+ }
+
+#if 0 /* Unknown query */
+ if (ctx->type == P_SONY_UPD897) {
+ // -> 1b e6 00 00 00 08 00
+ // <- ???
+ }
+#endif
+
+ /* Send over job */
+ i = 0;
+ while (i < job->datalen) {
+ uint32_t len;
+ memcpy(&len, job->databuf + i, sizeof(len));
+ len = le32_to_cpu(len);
+
+ i += sizeof(uint32_t);
+
+ if ((ret = send_data(ctx->dev, ctx->endp_down,
+ job->databuf + i, len)))
+ return CUPS_BACKEND_FAILED;
+
+ i += len;
+ }
+
+ // XXX generate and send copy cmd instead of using the offset.
+ // 1b ee 00 00 00 02 00 NN NN (BE)
+
+ /* Wait for completion! */
+retry:
+ sleep(1);
+
+ /* Check for idle */
+ ret = sony_get_status(ctx, &ctx->stsbuf);
+ if (ret)
+ return ret;
+
+ switch (ctx->stsbuf.sts1) {
+ case UPD_STS1_IDLE:
+ goto done;
+ case UPD_STS1_PRINTING:
+ break;
+ default:
+ ERROR("Printer error: %s (%02x)\n", upd895_statuses(ctx->stsbuf.sts1),
+ ctx->stsbuf.sts1);
+ return CUPS_BACKEND_STOP;
+ }
+
+ if (fast_return && ctx->stsbuf.printing != UPD_PRINTING_IDLE) {
+ INFO("Fast return mode enabled.\n");
+ } else {
+ goto retry;
+ }
+
+ /* Clean up */
+ if (terminate)
+ copies = 1;
+
+done:
+ INFO("Print complete (%d copies remaining)\n", copies - 1);
+
+ if (copies && --copies) {
+ goto top;
+ }
+
+ return CUPS_BACKEND_OK;
+}
+
+static int upd895_dump_status(struct upd_ctx *ctx)
+{
+ int ret = sony_get_status(ctx, &ctx->stsbuf);
+ if (ret < 0)
+ return CUPS_BACKEND_FAILED;
+
+ INFO("Printer status: %s (%02x)\n", upd895_statuses(ctx->stsbuf.sts1), ctx->stsbuf.sts1);
+ if (ctx->stsbuf.printing != UPD_PRINTING_IDLE &&
+ ctx->stsbuf.sts1 == UPD_STS1_PRINTING)
+ INFO("Remaining copies: %d\n", ctx->stsbuf.remain);
+
+ return CUPS_BACKEND_OK;
+}
+
+
+static void upd_cmdline(void)
+{
+ DEBUG("\t\t[ -s ] # Query printer status\n");
+}
+
+static int upd_cmdline_arg(void *vctx, int argc, char **argv)
+{
+ struct upd_ctx *ctx = vctx;
+ int i, j = 0;
+
+ if (!ctx)
+ return -1;
+
+ while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "s")) >= 0) {
+ switch(i) {
+ GETOPT_PROCESS_GLOBAL
+ case 's':
+ j = upd895_dump_status(ctx);
+ break;
+ }
+
+ if (j) return j;
+ }
+
+ return 0;
+}
+
+static int upd_query_markers(void *vctx, struct marker **markers, int *count)
+{
+ struct upd_ctx *ctx = vctx;
+ int ret = sony_get_status(ctx, &ctx->stsbuf);
+
+ *markers = &ctx->marker;
+ *count = 1;
+
+ if (ret)
+ return CUPS_BACKEND_FAILED;
+
+ if (ctx->stsbuf.sts1 == 0x40 ||
+ ctx->stsbuf.sts1 == 0x08) {
+ ctx->marker.levelnow = 0;
+ STATE("+media-empty\n");
+ } else {
+ ctx->marker.levelnow = -3;
+ STATE("-media-empty\n");
+ }
+
+ return CUPS_BACKEND_OK;
+}
+
+static const char *sonyupd_prefixes[] = {
+ "sonyupd",
+ "sony-updr150", "sony-updr200", "sony-upcr10l",
+ "sony-upd895", "sony-upd897", "dnp-sl10",
+ // Backwards compatibility
+ "sonyupdr150",
+ "sonyupdr200", "sonyupcr10",
+ NULL
+};
+
+/* Exported */
+#define USB_VID_SONY 0x054C
+#define USB_PID_SONY_UPDR150 0x01E8
+#define USB_PID_SONY_UPDR200 0x035F
+#define USB_PID_SONY_UPCR10 0x0226
+#define USB_PID_SONY_UPD895 0x0049
+#define USB_PID_SONY_UPD897 0x01E7
+
+struct dyesub_backend sonyupd_backend = {
+ .name = "Sony UP-D",
+ .version = "0.37",
+ .uri_prefixes = sonyupd_prefixes,
+ .cmdline_arg = upd_cmdline_arg,
+ .cmdline_usage = upd_cmdline,
+ .init = upd_init,
+ .attach = upd_attach,
+ .cleanup_job = upd_cleanup_job,
+ .read_parse = upd_read_parse,
+ .main_loop = upd_main_loop,
+ .query_markers = upd_query_markers,
+ .devices = {
+ { USB_VID_SONY, USB_PID_SONY_UPDR150, P_SONY_UPDR150, NULL, "sony-updr150"},
+ { USB_VID_SONY, USB_PID_SONY_UPDR200, P_SONY_UPDR150, NULL, "sony-updr200"},
+ { USB_VID_SONY, USB_PID_SONY_UPCR10, P_SONY_UPCR10, NULL, "sony-upcr10l"},
+ { USB_VID_SONY, USB_PID_SONY_UPD895, P_SONY_UPD895, NULL, "sonyupd895"},
+ { USB_VID_SONY, USB_PID_SONY_UPD897, P_SONY_UPD897, NULL, "sony-upd897"},
+ { 0, 0, 0, NULL, NULL}
+ }
+};
+
+/* Sony spool file format
+
+ The spool file is a series of 4-byte commands, followed by optional
+ arguments. The purpose of the commands is unknown, but they presumably
+ instruct the driver to perform certain things.
+
+ If you treat these 4 bytes as a 32-bit little-endian number, if any of the
+ least significant 4 bits are non-zero, the value is is to
+ be interpreted as a driver command. If the most significant bits are
+ zero, the value signifies that the following N bytes of data should be
+ sent to the printer as-is.
+
+ Known driver "commands":
+
+ 97 ff ff ff
+ eb ff ff ff ?? 00 00 00
+ ec ff ff ff ?? 00 00 00
+ ed ff ff ff ?? 00 00 00
+ ee ff ff ff ?? 00 00 00
+ ef ff ff ff XX 00 00 00 # XX == print size (0x01/0x02/0x03/0x04)
+ ef ff ff ff # On UP-D895/897
+ f3 ff ff ff
+ f4 ff ff ff # End of job on UP-D897
+ f5 ff ff ff YY 00 00 00 # YY == ??? (seen 0x01)
+ f7 ff ff ff # End of job on UP-D895
+
+ All printer commands start with 0x1b, and are at least 7 bytes long.
+ General Command format:
+
+ 1b XX ?? ?? ?? LL 00 # XX is cmd, LL is data or response length.
+
+ UNKNOWN QUERY [possibly media?]
+
+ <- 1b 03 00 00 00 13 00
+ -> 70 00 00 00 00 00 00 0b 00 00 00 00 00 00 00 00
+ 00 00 00
+
+ UNKNOWN CMD (UP-DR & SL10 & UP-D895 & UP-DP10) [ possibly START ]
+
+ <- 1b 0a 00 00 00 00 00
+
+ PRINT DIMENSIONS
+
+ <- 1b 15 00 00 00 0d 00
+ <- 00 00 00 00 ZZ QQ QQ WW WW YY YY XX XX
+
+ QQ/WW/YY/XX are (origin_cols/origin_rows/cols/rows) in BE.
+ ZZ is 0x07 on UP-DR series, 0x01 on UP-D89x series.
+
+ RESET
+
+ <- 1b 16 00 00 00 00 00
+
+ UNKNOWN CMD (UP-DR & SL & UP-D897, may be PRINT START?)
+
+ <- 1b 17 00 00 00 00 00
+
+ UNKNOWN CMD
+
+ <- 1b 1f 00 00 00 00 00
+
+ SET PARAM
+
+ <- 1b c0 00 NN LL 00 00 # LL is response length, NN is number.
+ <- [ NN bytes]
+
+ QUERY PARAM
+
+ <- 1b c1 00 NN LL 00 00 # LL is response length, NN is number.
+ -> [ NN bytes ]
+
+ PARAMS SEEN:
+ 03, len 5 [ 02 03 00 01 XX ] (UPDR200, 00 = normal, 02 is multicut/div2 print, 01 seen at end of stream too..
+ 02, len 06 [ 02 02 00 03 00 00 ]
+ 01, len 10 [ 02 01 00 06 00 02 00 00 00 00 ] (UP-D897)
+ 00, len 5 [ 02 01 00 01 XX ] XX == Gamma table
+
+ STATUS QUERY
+
+ <- 1b e0 00 00 00 XX 00 # XX = 0xe (UP-D895), 0xf (All others)
+ -> [14 or 15 bytes, see 'struct sony_updsts' ]
+
+ IMAGE DIMENSIONS & OVERCOAT
+
+ <- 1b e1 00 00 00 0b 00
+ <- 00 ZZ QQ 00 00 00 00 XX XX YY YY # XX = cols, YY == rows, ZZ == 0x04 on UP-DP10, otherwise 0x80. QQ == 00 glossy, 08 texture (UP-DP10 + UP-DR150), 0c matte, +0x10 for "nocorrection" on UP-DR200..
+
+ UNKNOWN
+
+ <- 1b e5 00 00 00 08 00
+ <- 00 00 00 00 00 00 00 XX 00 # Seen 01, 12, 0d, etc.
+
+ UNKNOWN (UP-D897)
+
+ <- 1b e6 00 00 00 08 00
+ <- 07 00 00 00 00 00 00 00
+
+ DATA TRANSFER
+
+ <- 1b ea 00 00 00 00 ZZ ZZ ZZ ZZ 00 # ZZ is BIG ENDIAN
+ <- [ ZZ ZZ ZZ ZZ bytes of data ]
+
+ UNKNOWN CMD (UP-DR and UP-D)
+
+ <- 1b ed 00 00 00 00 00
+
+ UNKNOWN (UPDR series)
+
+ <- 1b ef 00 00 00 06 00
+ -> 05 00 00 00 00 22
+
+ COPIES
+
+ <- 1b ee 00 00 00 02 00
+ <- NN NN # Number of copies (BE, 1-???)
+
+ UNKNOWN (UPDR series)
+
+ <- 1b f5 00 00 00 02 00
+ <- ?? ??
+
+ ************************************************************************
+
+ The data stream sent to the printer consists of all the commands in the
+ spool file, plus a couple other ones that generate responses. It is
+ unknown if those additional commands are necessary. This is a typical
+ sequence:
+
+[[ Sniff start of a UP-DR150 ]]
+
+<- 1b e0 00 00 00 0f 00 [ STATUS QUERY ]
+-> 0e 00 00 00 00 00 00 00 04 a8 08 00 0a a4 00
+ ----- -----
+ MAX_C MAX_R
+<- 1b 16 00 00 00 00 00
+-> "reset" ??
+
+[[ begin job ]]
+
+<- 1b ef 00 00 00 06 00
+-> 05 00 00 00 00 22
+
+<- 1b e5 00 00 00 08 00 ** In spool file
+<- 00 00 00 00 00 00 01 00
+
+<- 1b c1 00 02 06 00 00 [ Query Param 2, length 6 ]
+-> 02 02 00 03 00 00
+
+<- 1b ee 00 00 00 02 00 ** In spool file
+<- 00 01
+
+<- 1b 15 00 00 00 0d 00 ** In spool file
+<- 00 00 00 00 07 00 00 00 00 08 00 0a a4
+
+<- 1b 03 00 00 00 13 00
+-> 70 00 00 00 00 00 00 0b 00 00 00 00 00 00 00 00
+ 00 00 00
+
+<- 1b e1 00 00 00 0b 00 ** In spool file
+<- 00 80 00 00 00 00 00 08 00 0a a4
+
+<- 1b 03 00 00 00 13 00
+-> 70 00 00 00 00 00 00 0b 00 00 00 00 00 00 00 00
+ 00 00 00
+
+<- 1b ea 00 00 00 00 00 ff 60 00 00 ** In spool file
+<- [[ 0x0060ff00 bytes of data ]]
+
+<- 1b e0 00 00 00 0f 00
+-> 0e 00 00 00 00 00 00 00 04 a8 08 00 0a a4 00
+
+<- 1b 0a 00 00 00 00 00 ** In spool file
+<- 1b 17 00 00 00 00 00 ** In spool file
+
+[[fin]]
+
+ **************
+
+ Sony UP-CL10 / DNP SL-10 spool format:
+
+60 ff ff ff f8 ff ff ff fd ff ff ff
+14 00 00 00
+1b 15 00 00 00 0d 00 00 00 00 00 07 00 00 00 00 WW WW HH HH
+fb ff ff ff f4 ff ff ff
+0b 00 00 00
+1b ea 00 00 00 00 SH SH SH SH 00
+SL SL SL SL
+
+ [[ Data, rows * cols * 3 bytes ]]
+
+f3 ff ff ff
+0f 00 00 00
+1b e5 00 00 00 08 00 00 00 00 00 00 00 00 00
+12 00 00 00
+1b e1 00 00 00 0b 00 00 80 00 00 00 00 00 WW WW HH HH
+fa ff ff ff
+09 00 00 00
+1b ee 00 00 00 02 00 00 NN
+07 00 00 00
+1b 0a 00 00 00 00 00
+f9 ff ff ff fc ff ff ff
+07 00 00 00
+1b 17 00 00 00 00 00
+f7 ff ff ff
+
+ WW WW == Columns, Big Endian
+ HH HH == Rows, Big Endian
+ SL SL SL SL == Plane size, Little Endian (Rows * Cols * 3)
+ SH SH SH SH == Plane size, Big Endian (Rows * Cols * 3)
+ NN == Copies
+
+ **************
+
+ Sony UP-D895 spool format:
+
+ XX XX == cols, BE (fixed at 1280/0x500)
+ YY YY == rows, BE (798/0x031e,1038/0x040e,1475/0x05c3, 2484/09b4) @ 960/1280/1920/3840+4096
+ SS SS SS SS == data len (rows * cols, LE)
+ S' S' S' S' == data len (rows * cols, BE)
+ NN == copies (1 -> ??)
+ GG GG == ??? 0000/0050/011b/04aa/05aa at each resolution.
+ G' == Gamma 01 (soft), 03 (hard), 02 (normal)
+
+ 9c ff ff ff 97 ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff
+
+ 14 00 00 00
+ 1b 15 00 00 00 0d 00 00 00 00 00 01 GG GG 00 00 YY YY XX XX
+ 0b 00 00 00
+ 1b ea 00 00 00 00 S' S' S' S' 00
+ SS SS SS SS
+ ...DATA... (rows * cols)
+ ff ff ff ff
+ 09 00 00 00
+ 1b ee 00 00 00 02 00 00 NN
+ 0f 00 00 00
+ 1b e5 00 00 00 08 00 00 00 00 00 00 00 00 00
+ 0c 00 00 00
+ 1b c0 00 00 00 05 00 02 00 00 01 G'
+ 11 00 00 00
+ 1b c0 00 01 00 0a 00 02 01 00 06 00 00 00 00 00 00
+ 12 00 00 00
+ 1b e1 00 00 00 0b 00 00 08 00 GG GG 00 00 YY YY XX XX
+ 07 00 00 00
+ 1b 0a 00 00 00 00 00
+ fd ff ff ff f7 ff ff ff f8 ff ff ff
+
+ **************
+
+ Sony UP-D897 spool format:
+
+ NN NN == copies (00 for printer selected)
+ XX XX == cols (fixed @ 1280)
+ YY YY == rows
+ GG == gamma -- Table 2 == 2, Table 1 == 3, Table 3 == 1, Table 4 == 4
+ DD == "dark" +- 64.
+ LL == "light" +- 64.
+ AA == "advanced" +- 32.
+ SS == Sharpness 0-14
+ ZZ ZZ ZZ ZZ == Data length (BE)
+ Z` Z` Z` Z` == Data length (LE)
+
+
+ 83 ff ff ff fc ff ff ff
+ fb ff ff ff f5 ff ff ff
+ f1 ff ff ff f0 ff ff ff
+ ef ff ff ff
+
+ 14 00 00 00
+ 1b 15 00 00 00 0d 00 00 00 00 00 01 00 a2 00 00 YY YY XX XX
+
+ 0b 00 00 00
+ 1b ea 00 00 00 00 ZZ ZZ ZZ ZZ 00
+
+ Z` Z` Z` Z`
+ ...DATA...
+
+ ea ff ff ff
+
+ 09 00 00 00
+ 1b ee 00 00 00 02 00 NN NN
+
+ ee ff ff ff 01 00 00 00
+
+ 0e 00 00 00
+ 1b e5 00 00 00 08 00 00 00 00 00 DD LL SS AA
+
+ eb ff ff ff ?? 00 00 00 <--- 02/05 5 at #3, 2 otherwise. Sharpness?
+
+ 0c 00 00 00
+ 1b c0 00 00 00 05 00 02 00 00 01 GG
+
+ ec ff ff ff ?? 00 00 00 <--- 01/00/02/01/01 Seen. Unknown.
+
+ 11 00 00 00
+ 1b c0 00 01 00 0a 00 02 01 00 06 00 00 00 00 00 00
+
+ ed ff ff ff 00 00 00 00
+
+ 12 00 00 00
+ 1b e1 00 00 00 0b 00 00 08 00 00 a2 00 00 YY YY XX XX
+
+ fa ff ff ff
+
+ 07 00 00 00
+ 1b 0a 00 00 00 00 00
+
+ fc ff ff ff fd ff ff ff ff ff ff ff
+
+ 07 00 00 00
+ 1b 17 00 00 00 00 00
+
+ f4 ff ff ff
+
+ ****************
+
+ UP-D895 comms protocol:
+
+ <-- 1b e0 00 00 00 0e 00
+ --> 0d 00 XX YY 00 SS 00 ZZ 00 00 10 00 05 00
+
+ XX : 0xe0 when printing, 0x00 otherwise.
+ YY : Number of remaining copies
+ SS : Status
+ 0x00 = Idle
+ 0x08 = Door open
+ 0x40 = Paper empty
+ 0x80 = Printing
+ ?? = Cooling down
+ ?? = Busy / Waiting
+ ZZ : Status2
+ 0x01 = Print complete
+ 0x02 = no prints yet
+
+ UP-D897 comms protocol:
+
+ <-- 1b e0 00 00 00 0f 00
+ --> 0e 00 XX YY 00 SS RR 01 02 02 10 00 05 00 PP
+
+ XX : 0xe0 when printing, 0x00 otherwise.
+ YY : Number of remaining copies
+ SS : Status
+ 0x00 = Idle
+?? 0x08 = Door open
+ 0x40 = Paper empty
+ 0x80 = Printing
+ ?? = Cooling down
+ ?? = Busy / Waiting
+ RR : Status 2
+ 0x00 = Okay
+ 0x08 = ?? Error state?
+ 0x80 = Printing
+ PP : Percentage complete (0-99)
+
+Other commands seen:
+
+ <-- 1b 16 00 00 00 00 00 -- Reset
+
+ <-- 1b c1 00 01 00 0a 00 -- Query ID 1, legth 10
+ --> 02 01 00 06 00 02 00 00 00 00
+
+ <-- 1b c1 00 00 00 05 00 -- Query id 0, length 5
+ --> 02 01 00 01 03
+
+ <-- 1b e6 00 00 00 08 00
+ --> 07 00 00 00 00 00 00 00
+
+ <-- 1b 17 00 00 00 00 00 -- Unknown?
+
+ UP-CR10L
+
+ 2UPC-C13 (300)
+ 2UPC-C14 (200)
+ 2UPC-C15 (172)
+
+ Status progression when printing:
+
+ 0e 00 00 00 00 00 00 00 04 a0 04 e0 07 38 00
+ 0e 00 00 01 00 80 00 01 04 a0 04 e0 07 38 64
+ 0e 00 40 01 00 80 00 01 04 a0 04 e0 07 38 64 <-- Y
+ 0e 00 80 01 00 80 00 01 04 a0 04 e0 07 38 64 <-- M
+ 0e 00 c0 01 00 80 00 01 04 a0 04 e0 07 38 64 <-- C
+ 0e 00 20 01 00 80 00 01 04 a0 04 e0 07 38 64 <-- O
+ 0e 00 20 01 00 80 00 01 04 a0 04 e0 07 38 00
+ 0e 00 00 01 00 80 00 01 04 a0 04 e0 07 38 00
+ 0e 00 00 00 00 00 00 00 04 a0 04 e0 07 38 00
+
+*/
diff --git a/src/cups/backend_sonyupdr150.c b/src/cups/backend_sonyupdr150.c
deleted file mode 100644
index 5e8ae2e..0000000
--- a/src/cups/backend_sonyupdr150.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Sony UP-DR150 Photo Printer CUPS backend -- libusb-1.0 version
- *
- * (c) 2013-2018 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, see <https://www.gnu.org/licenses/>.
- *
- * [http://www.gnu.org/licenses/gpl-2.0.html]
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- */
-
-#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 updr150_backend
-
-#include "backend_common.h"
-
-/* Private data structure */
-struct updr150_printjob {
- uint8_t *databuf;
- int datalen;
- int copies;
-};
-
-struct updr150_ctx {
- struct libusb_device_handle *dev;
- uint8_t endp_up;
- uint8_t endp_down;
- int type;
-
- struct marker marker;
-};
-
-static void* updr150_init(void)
-{
- struct updr150_ctx *ctx = malloc(sizeof(struct updr150_ctx));
- if (!ctx) {
- ERROR("Memory Allocation Failure!");
- return NULL;
- }
- memset(ctx, 0, sizeof(struct updr150_ctx));
- return ctx;
-}
-
-static int updr150_attach(void *vctx, struct libusb_device_handle *dev, int type,
- uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
-{
- struct updr150_ctx *ctx = vctx;
-
- UNUSED(jobid);
-
- ctx->dev = dev;
- ctx->endp_up = endp_up;
- ctx->endp_down = endp_down;
- ctx->type = type;
-
- ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
- ctx->marker.name = "Unknown";
- ctx->marker.levelmax = -1;
- ctx->marker.levelnow = -2;
-
- return CUPS_BACKEND_OK;
-}
-
-static void updr150_cleanup_job(const void *vjob)
-{
- const struct updr150_printjob *job = vjob;
-
- if (job->databuf)
- free(job->databuf);
-
- free((void*)job);
-}
-
-static void updr150_teardown(void *vctx) {
- struct updr150_ctx *ctx = vctx;
-
- if (!ctx)
- return;
-
- free(ctx);
-}
-
-#define MAX_PRINTJOB_LEN 16736455
-static int updr150_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
- struct updr150_ctx *ctx = vctx;
- int len, run = 1;
- uint32_t copies_offset = 0;
-
- struct updr150_printjob *job = NULL;
-
- if (!ctx)
- return CUPS_BACKEND_FAILED;
-
- job = malloc(sizeof(*job));
- if (!job) {
- ERROR("Memory allocation failure!\n");
- return CUPS_BACKEND_RETRY_CURRENT;
- }
- memset(job, 0, sizeof(*job));
- job->copies = copies;
-
- job->datalen = 0;
- job->databuf = malloc(MAX_PRINTJOB_LEN);
- if (!job->databuf) {
- ERROR("Memory allocation failure!\n");
- updr150_cleanup_job(job);
- return CUPS_BACKEND_RETRY_CURRENT;
- }
-
- while(run) {
- int i;
- int keep = 0;
- i = read(data_fd, job->databuf + job->datalen, 4);
- if (i < 0) {
- updr150_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
- }
- if (i == 0)
- break;
-
- memcpy(&len, job->databuf + job->datalen, sizeof(len));
- len = le32_to_cpu(len);
-
- /* Filter out chunks we don't send to the printer */
- if (len & 0xf0000000) {
- switch (len) {
- case 0xfffffff3:
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 0);
- len = 0;
- if (ctx->type == P_SONY_UPDR150)
- run = 0;
- break;
- case 0xfffffff7:
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 0);
- len = 0;
- if (ctx->type == P_SONY_UPCR10)
- run = 0;
- break;
- case 0xfffffff8: // 895
- case 0xfffffff4: // 897
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 0);
- len = 0;
- if (ctx->type == P_SONY_UPD89x)
- run = 0;
- break;
- case 0xffffffeb:
- case 0xffffffec:
- case 0xffffffed:
- case 0xffffffee:
- case 0xffffffef:
- case 0xfffffff5:
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 4);
- len = 4;
- break;
- default:
- if(dyesub_debug)
- DEBUG("Block ID '%08x' (len %d)\n", len, 0);
- len = 0;
- break;
- }
- } else {
- /* Only keep these chunks */
- if(dyesub_debug)
- DEBUG("Data block (len %d)\n", len);
- keep = 1;
- }
- if (keep)
- job->datalen += sizeof(uint32_t);
-
- /* Read in the data chunk */
- while(len > 0) {
- i = read(data_fd, job->databuf + job->datalen, len);
- if (i < 0) {
- updr150_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
- }
- if (i == 0)
- break;
-
- if (job->databuf[job->datalen] == 0x1b &&
- job->databuf[job->datalen + 1] == 0xee) {
- if (ctx->type == P_SONY_UPCR10)
- copies_offset = job->datalen + 8;
- else
- copies_offset = job->datalen + 12;
- }
-
- if (keep)
- job->datalen += i;
- len -= i;
- }
- }
- if (!job->datalen) {
- updr150_cleanup_job(job);
- return CUPS_BACKEND_CANCEL;
- }
-
- /* Some models specify copies in the print job */
- if (copies_offset) {
- job->databuf[copies_offset] = job->copies;
- job->copies = 1;
- }
-
- *vjob = job;
-
- return CUPS_BACKEND_OK;
-}
-
-static int updr150_main_loop(void *vctx, const void *vjob) {
- struct updr150_ctx *ctx = vctx;
- int i, ret;
- int copies;
-
- const struct updr150_printjob *job = vjob;
-
- if (!ctx)
- return CUPS_BACKEND_FAILED;
- if (!job)
- return CUPS_BACKEND_FAILED;
-
- copies = job->copies;
-
-top:
- i = 0;
- while (i < job->datalen) {
- uint32_t len;
- memcpy(&len, job->databuf + i, sizeof(len));
- len = le32_to_cpu(len);
-
- i += sizeof(uint32_t);
-
- if ((ret = send_data(ctx->dev, ctx->endp_down,
- job->databuf + i, len)))
- return CUPS_BACKEND_FAILED;
-
- i += len;
- }
-
- /* Clean up */
- if (terminate)
- copies = 1;
-
- INFO("Print complete (%d copies remaining)\n", copies - 1);
-
- if (copies && --copies) {
- goto top;
- }
-
- return CUPS_BACKEND_OK;
-}
-
-static int updr150_cmdline_arg(void *vctx, int argc, char **argv)
-{
- struct updr150_ctx *ctx = vctx;
- int i, j = 0;
-
- if (!ctx)
- return -1;
-
- while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL)) >= 0) {
- switch(i) {
- GETOPT_PROCESS_GLOBAL
- }
-
- if (j) return j;
- }
-
- return 0;
-}
-
-static int updr150_query_markers(void *vctx, struct marker **markers, int *count)
-{
- struct updr150_ctx *ctx = vctx;
-
- *markers = &ctx->marker;
- *count = 1;
-
- return CUPS_BACKEND_OK;
-}
-
-static const char *sonyupdr150_prefixes[] = {
- "sonyupdr150", // Family name.
- "sony-updr150", "sony-updr200", "sony-upcr10",
- // Backwards compatibility
- "sonyupdr200", "sonyupcr10",
-// "sonyupd895", "sonyupd897", "sonyupd898",
- NULL
-};
-
-/* Exported */
-#define USB_VID_SONY 0x054C
-#define USB_PID_SONY_UPDR150 0x01E8
-#define USB_PID_SONY_UPDR200 0x035F
-#define USB_PID_SONY_UPCR10 0x0226
-//#define USB_PID_SONY_UPD895 XXXXX // 0x7ea6?
-//#define USB_PID_SONY_UPD897 XXXXX // 0xbce7?
-//#define USB_PID_SONY_UPD898 XXXXX // 0x589a?
-
-struct dyesub_backend updr150_backend = {
- .name = "Sony UP-DR150/UP-DR200/UP-CR10",
- .version = "0.26",
- .uri_prefixes = sonyupdr150_prefixes,
- .cmdline_arg = updr150_cmdline_arg,
- .init = updr150_init,
- .attach = updr150_attach,
- .teardown = updr150_teardown,
- .cleanup_job = updr150_cleanup_job,
- .read_parse = updr150_read_parse,
- .main_loop = updr150_main_loop,
- .query_markers = updr150_query_markers,
- .devices = {
- { USB_VID_SONY, USB_PID_SONY_UPDR150, P_SONY_UPDR150, NULL, "sony-updr150"},
- { USB_VID_SONY, USB_PID_SONY_UPDR200, P_SONY_UPDR150, NULL, "sony-updr200"},
- { USB_VID_SONY, USB_PID_SONY_UPCR10, P_SONY_UPCR10, NULL, "sony-upcr10"},
-// { USB_VID_SONY, USB_PID_SONY_UPD895MD, P_SONY_UPD89x, NULL, "sonyupd895"},
-// { USB_VID_SONY, USB_PID_SONY_UPD897MD, P_SONY_UPD89x, NULL, "sonyupd897"},
-// { USB_VID_SONY, USB_PID_SONY_UPD898MD, P_SONY_UPD89x, NULL, "sonyupd898"},
- { 0, 0, 0, NULL, NULL}
- }
-};
-
-/* Sony UP-DR150/UP-DR200 Spool file format
-
- The spool file is a series of 4-byte commands, followed by optional
- arguments. The purpose of the commands is unknown, but they presumably
- instruct the driver to perform certain things.
-
- If you treat these 4 bytes as a 32-bit little-endian number, if any of the
- most significant 4 bits are non-zero, the value is is to
- be interpreted as a driver command. If the most significant bits are
- zero, the value signifies that the following N bytes of data should be
- sent to the printer as-is.
-
- Known driver "commands":
-
- eb ff ff ff ?? 00 00 00
- ec ff ff ff ?? 00 00 00
- ed ff ff ff ?? 00 00 00
- ee ff ff ff ?? 00 00 00
- ef ff ff ff XX 00 00 00 # XX == print size (0x01/0x02/0x03/0x04)
- f5 ff ff ff YY 00 00 00 # YY == ??? (seen 0x01)
-
- All printer commands start with 0x1b, and are at least 7 bytes long.
-
- ************************************************************************
-
- The data stream sent to the printer consists of all the commands in the
- spool file, plus a couple other ones that generate responses. It is
- unknown if those additional commands are necessary. This is a typical
- sequence:
-
-[[ Sniff start of a UP-DR150 ]]
-
-<- 1b e0 00 00 00 0f 00
--> 0e 00 00 00 00 00 00 00 00 04 a8 08 0a a4 00
-
-<- 1b 16 00 00 00 00 00
--> "reset" ??
-
-[[ begin job ]]
-
-<- 1b ef 00 00 00 06 00
--> 05 00 00 00 00 22
-
-<- 1b e5 00 00 00 08 00 ** In spool file
-<- 00 00 00 00 00 00 01 00
-
-<- 1b c1 00 02 06 00 00
--> 02 02 00 03 00 00
-
-<- 1b ee 00 00 00 02 00 ** In spool file
-<- 00 01
-
-<- 1b 15 00 00 00 0d 00 ** In spool file
-<- 00 00 00 00 07 00 00 00 00 08 00 0a a4
-
-<- 1b 03 00 00 00 13 00
--> 70 00 00 00 00 00 00 0b 00 00 00 00 00 00 00 00
- 00 00 00
-
-<- 1b e1 00 00 00 0b 00 ** In spool file
-<- 00 80 00 00 00 00 00 08 00 0a a4
-
-<- 1b 03 00 00 00 13 00
--> 70 00 00 00 00 00 00 0b 00 00 00 00 00 00 00 00
- 00 00 00
-
-<- 1b ea 00 00 00 00 00 ff 60 00 00 ** In spool file
-<- [[ 0x0060ff00 bytes of data ]]
-
-<- 1b e0 00 00 00 0f 00
--> 0e 00 00 00 00 00 00 00 04 a8 08 00 0a a4 00
-
-<- 1b 0a 00 00 00 00 00 ** In spool file
-<- 1b 17 00 00 00 00 00 ** In spool file
-
-[[fin]]
-
- **************
-
- Sony UP-CL10 / DNP SL-10 spool format:
-
-60 ff ff ff
-f8 ff ff ff
-fd ff ff ff 14 00 00 00 1b 15 00 00 00 0d 00 00 00 00 00 07 00 00 00 00 WW WW HH HH
-fb ff ff ff
-f4 ff ff ff 0b 00 00 00 1b ea 00 00 00 00 SH SH SH SH 00 SL SL SL SL
-
- [[ Data, rows * cols * 3 bytes ]]
-
-f3 ff ff ff 0f 00 00 00 1b e5 00 00 00 08 00 00 00 00 00 00 00 00 00
- 12 00 00 00 1b e1 00 00 00 0b 00 00 80 00 00 00 00 00 WW WW HH HH
-fa ff ff ff 09 00 00 00 1b ee 00 00 00 02 00 00 NN
- 07 00 00 00 1b 0a 00 00 00 00 00
-f9 ff ff ff
-fc ff ff ff 07 00 00 00 1b 17 00 00 00 00 00
-f7 ff ff ff
-
- WW WW == Columns, Big Endian
- HH HH == Rows, Big Endian
- SL SL SL SL == Plane size, Little Endian (Rows * Cols * 3)
- SH SH SH SH == Plane size, Big Endian (Rows * Cols * 3)
- NN == Copies
-
- **************
-
- Sony UP-D895 spool format:
-
- XX XX == cols, BE (fixed at 1280/0x500)
- YY YY == rows, BE (798/0x031e,1038/0x040e,1475/0x05c3, 2484/09b4) @ 960/1280/1920/3840+4096
- SS SS SS SS == data len (rows * cols, LE)
- S' S' S' S' == data len (rows * cols, BE)
- NN == copies (1 -> ??)
- GG GG == ??? 0000/0050/011b/04aa/05aa at each resolution.
- G' == Gamma 01 (soft), 03 (hard), 02 (normal)
-
- 9c ff ff ff 97 ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff
-
- 14 00 00 00
- 1b 15 00 00 00 0d 00 00 00 00 00 01 GG GG 00 00 YY YY XX XX
- 0b 00 00 00
- 1b ea 00 00 00 00 S' S' S' S' 00
- SS SS SS SS
- ...DATA... (rows * cols)
- ff ff ff ff
- 09 00 00 00
- 1b ee 00 00 00 02 00 00 NN
- 0f 00 00 00
- 1b e5 00 00 00 08 00 00 00 00 00 00 00 00 00
- 0c 00 00 00
- 1b c0 00 00 00 05 00 02 00 00 01 G'
- 11 00 00 00
- 1b c0 00 01 00 0a 00 02 01 00 06 00 00 00 00 00 00
- 12 00 00 00
- 1b e1 00 00 00 0b 00 00 08 00 GG GG 00 00 YY YY XX XX
- 07 00 00 00
- 1b 0a 00 00 00 00 00
- fd ff ff ff f7 ff ff ff f8 ff ff ff
-
- **************
-
- Sony UP-D897 spool format:
-
- NN NN == copies (00 for printer selected)
- XX XX == cols (fixed @ 1280)
- YY YY == rows
- GG == gamma -- Table 2 == 2, Table 1 == 3, Table 3 == 1, Table 4 == 4
- DD == "dark" +- 64.
- LL == "light" +- 64.
- AA == "advanced" +- 32.
- SS == Sharpness 0-14
- ZZ ZZ ZZ ZZ == Data length (BE)
- Z` Z` Z` Z` == Data length (LE)
-
-
- 83 ff ff ff fc ff ff ff fb ff ff ff f5 ff ff ff f1 ff ff ff f0 ff ff ff ef ff ff ff
-
- 07 00 00 00
- 1b 15 00 00 00 0d 00
- 0d 00 00 00
- 00 00 00 00 01 00 a2 00 00 YY YY XX XX
-
- 0b 00 00 00
- 1b ea 00 00 00 00 ZZ ZZ ZZ ZZ 00
-
- Z` Z` Z` Z`
- ...DATA...
-
- ea ff ff ff
-
- 07 00 00 00
- 1b ee 00 00 00 02 00
- 02 00 00 00
- 00 NN
-
- ee ff ff ff 01 00 00 00
-
- 07 00 00 00
- 1b e5 00 00 00 08 00
- 08 00 00 00
- 00 00 00 00 DD LL SS AA
-
- eb ff ff ff ?? 00 00 00 <--- 02/05 5 at #3, 2 otherwise. Sharpness?
-
- 07 00 00 00
- 1b c0 00 00 00 05 00
- 05 00 00 00
- 02 00 00 01 GG
-
- ec ff ff ff ?? 00 00 00 <--- 01/00/02/01/01 Seen. Unknown.
-
- 07 00 00 00
- 1b c0 00 01 00 0a 00
- 0a 00 00 00
- 02 01 00 06 00 00 00 00 00 00
-
- ed ff ff ff 00 00 00 00
-
- 07 00 00 00
- 1b e1 00 00 00 0b 00
- 0b 00 00 00
- 00 08 00 00 a2 00 00 YY YY XX XX
-
- fa ff ff ff
-
- 07 00 00 00
- 1b 0a 00 00 00 00 00
-
- fc ff ff ff
- fd ff ff ff
- ff ff ff ff
-
- 07 00 00 00
- 1b 17 00 00 00 00 00
-
- f4 ff ff ff
-
-*/
diff --git a/src/cups/blacklist b/src/cups/blacklist
index 157fd47..7bd61c6 100644
--- a/src/cups/blacklist
+++ b/src/cups/blacklist
@@ -123,6 +123,18 @@
# Kodak 6850
0x040a 0x402b blacklist
+# Kodak 7000
+0x040a 0x4035 blacklist
+
+# Kodak 7010/7015
+0x040a 0x4037 blacklist
+
+# Kodak 8800/9810
+0x040a 0x4023 blacklist
+
+# Kodak 8810
+0x040a 0x404d blacklist
+
# Kodak 605
0x040a 0x402e blacklist
@@ -135,6 +147,9 @@
# Shinko CHC-S2145 (aka Sinfonia S2)
0x10ce 0x000e blacklist
+# Shinko CHC-S2245 (aka Sinfonia S3)
+0x10ce 0x0039 blacklist
+
# Shinko CHC-S6145 (aka Sinfonia CS2)
0x10ce 0x0019 blacklist
@@ -150,6 +165,12 @@
# Sony UP-CR10L
0x054c 0x0226 blacklist
+# Sony UP-D895
+0x054c 0x0049 blacklist
+
+# Sony UP-D897
+0x054c 0x01e7 blacklist
+
# Mitsubishi CP-D70DW/CP-D707DW
0x06d3 0x3b30 blacklist
@@ -226,6 +247,9 @@
# Fujifilm ASK-300
0x04cb 0x5006 blacklist
+# HiTi M610
+0x0d16 0x0010 blacklist
+
# HiTi P910L
0x0d16 0x000e blacklist
diff --git a/src/cups/cups-genppd.c b/src/cups/cups-genppd.c
index fde7c46..f8791fa 100644
--- a/src/cups/cups-genppd.c
+++ b/src/cups/cups-genppd.c
@@ -70,6 +70,8 @@ main(int argc, /* I - Number of command-line arguments */
no color opts = 4 */
unsigned parallel = 1; /* Generate PPD files in parallel */
unsigned rotor = 0; /* Rotor for generating PPD files in parallel */
+ unsigned test_rotor = 0; /* Testing (serialized) rotor */
+ unsigned test_rotor_circumference = 1; /* Testing (serialized) rotor size */
pid_t *subprocesses = NULL;
int parent = 1;
#ifdef HAVE_LIBZ
@@ -88,7 +90,7 @@ main(int argc, /* I - Number of command-line arguments */
for (;;)
{
- if ((i = getopt(argc, argv, "23hvqc:p:l:LMVd:saNCbZzS")) == -1)
+ if ((i = getopt(argc, argv, "23hvqc:p:l:LMVd:saNCbZzSr:R:")) == -1)
break;
switch (i)
@@ -175,12 +177,23 @@ main(int argc, /* I - Number of command-line arguments */
case 'S':
skip_duplicate_ppds = 1;
break;
+ case 'r':
+ test_rotor = atoi(optarg);
+ break;
+ case 'R':
+ test_rotor_circumference = atoi(optarg);
+ break;
default:
usage();
exit(EXIT_FAILURE);
break;
}
}
+ if (test_rotor_circumference < 1 || test_rotor >= test_rotor_circumference)
+ {
+ test_rotor = 0;
+ test_rotor_circumference = 1;
+ }
#ifdef HAVE_LIBZ
if (use_compression)
gpext = ".gz";
@@ -280,6 +293,7 @@ main(int argc, /* I - Number of command-line arguments */
}
else
{
+ int test_rotor_current = -1;
stp_string_list_t *seen_models = NULL;
if (skip_duplicate_ppds)
seen_models = stp_string_list_create();
@@ -287,6 +301,7 @@ main(int argc, /* I - Number of command-line arguments */
for (i = 0; i < stp_printer_model_count(); i++)
{
printer = stp_get_printer_by_index(i);
+ test_rotor_current++;
if (skip_duplicate_ppds)
{
char model_family[128];
@@ -299,7 +314,8 @@ main(int argc, /* I - Number of command-line arguments */
stp_string_list_add_string_unsafe(seen_models, model_family,
model_family);
}
-
+ if (test_rotor_current % test_rotor_circumference != test_rotor)
+ continue;
if (i % parallel == rotor && printer)
{
if (! verbose && (i % 100) == 0)
@@ -488,6 +504,9 @@ help(void)
" -Z Don't compress PPD files.\n"
#endif
" -S Skip PPD files with duplicate model identifiers.\n"
+ " -R size Generate every size'th PPD file.\n"
+ " -r divisor Generate the PPD files (N % size == divisor).\n"
+ "\n"
"models:\n"
" A list of printer models, either the driver or quoted full name.\n");
}
diff --git a/src/cups/gutenprint.c b/src/cups/gutenprint.c
index 6ab2194..56b5599 100644
--- a/src/cups/gutenprint.c
+++ b/src/cups/gutenprint.c
@@ -122,7 +122,7 @@ cat_ppd(const char *uri) /* I - Driver URI */
const char *lang = NULL;
char *s;
char filename[1024], /* Filename */
- ppd_location[1024]; /* Installed location */
+ ppd_location[2048]; /* Installed location */
const char *infix = "";
ppd_type_t ppd_type = PPD_STANDARD;
gpfile outFD;
diff --git a/src/cups/test-ppds.in b/src/cups/test-ppds.test.in
index 3664f4e..84dfbfc 100644
--- a/src/cups/test-ppds.in
+++ b/src/cups/test-ppds.test.in
@@ -39,30 +39,36 @@ if [[ -n "$STP_TEST_LOG_PREFIX" ]] ; then
exec 2>&1
fi
-[[ -n "$STP_TEST_DEBUG" ]] && DEBUG=echo
+DEBUG=${STP_TEST_DEBUG:+echo}
[[ -z $STP_TEST_SUITE || -z $STP_TEST_PROFILE ]] && STP_TEST_PROFILE=full
+[[ -n $STP_TEST_COMPONENTS && $STP_TEST_COMPONENTS != '*CUPS*' && $STP_TEST_COMPONENTS != '*test-ppds*' ]] && exit 77
+
PPD_DIR=ppdtest
PPD_PARALLEL=200
+echo '****************************************************************'
+
+rotor="-R ${STP_TEST_ROTOR_CIRCUMFERENCE:-1} -r ${STP_TEST_ROTOR:-0}"
+
function test_full() {
rm -rf "$PPD_DIR"
echo "GENERATING PPD FILES (all):"
set -e
- $DEBUG make "PPD_DIR=$PPD_DIR" EXTRA_GENPPD_OPTS='-b -Z' ppd-clean ppd-global-a ppd-nls-a ppd-nonls-a
+ $DEBUG make "PPD_DIR=$PPD_DIR" EXTRA_GENPPD_OPTS="$rotor -b -Z" ppd-clean ppd-global-a ppd-nls-a ppd-nonls-a
}
function test_fast() {
rm -rf "$PPD_DIR"
echo "GENERATING PPD FILES (fast):"
set -e
- $DEBUG make "PPD_DIR=$PPD_DIR" EXTRA_GENPPD_OPTS='-b -Z' ppd-clean ppd-nonls
+ $DEBUG make "PPD_DIR=$PPD_DIR" EXTRA_GENPPD_OPTS="$rotor -b -Z" ppd-clean ppd-nonls
if [[ -n $STP_TEST_DIST ]] ; then
echo "GENERATING PPD FILES (global):"
set -e
- $DEBUG make "PPD_DIR=$PPD_DIR" EXTRA_GENPPD_OPTS='-b -Z -S' ppd-global
+ $DEBUG make "PPD_DIR=$PPD_DIR" EXTRA_GENPPD_OPTS="$rotor -b -Z -S" ppd-global
fi
PPD_PARALLEL=20
}
@@ -71,7 +77,7 @@ function test_minimal() {
rm -rf "$PPD_DIR"
echo "GENERATING PPD FILES (minimal):"
set -e
- $DEBUG make "PPD_DIR=$PPD_DIR" EXTRA_GENPPD_OPTS='-b -Z -S' ppd-clean ppd-nonls
+ $DEBUG make "PPD_DIR=$PPD_DIR" EXTRA_GENPPD_OPTS="$rotor -b -Z -S" ppd-clean ppd-nonls
PPD_PARALLEL=20
}
@@ -84,7 +90,7 @@ case "$STP_TEST_PROFILE" in
esac
if [[ -n "$STP_TEST_DEBUG" ]] ; then
- echo "Would run $0 $@"
+ echo "Would run $0 $*"
exit 0
fi
@@ -120,7 +126,7 @@ fi
# Use this with PPD files with translated numbers (genppd -N)
# With normal globalized PPD files this will yield hundreds of megabytes
# of errors.
-echo $failures | xargs cupstestppd -r $cupstestppdopts 2>&1
+echo "$failures" | xargs cupstestppd -r $cupstestppdopts 2>&1
fail_count=`echo "$failures" | wc -l`
echo "$fail_count/$ppd_count fail"
diff --git a/src/cups/test-rastertogutenprint.in b/src/cups/test-rastertogutenprint.in
index 410814d..0d9f761 100644
--- a/src/cups/test-rastertogutenprint.in
+++ b/src/cups/test-rastertogutenprint.in
@@ -37,10 +37,11 @@ declare make_ppds=1
declare skip_simplified=0
declare postscript=0
declare use_explicit_quality=0
-declare extra_genppd_opts=-Z
+declare extra_genppd_opts="-Z"
declare use_smallest_pagesize=0
declare cupsargs=''
-declare printers_to_test=''
+declare -a printers_to_test
+declare dontrun=0
if [ -n "$STP_TEST_DEBUG" ] ; then
echo "Would run with single=$single skip_simplified=$skip_simplified extra_genppd_opts=$extra_genppd_opts cupsargs=$cupsargs use_explicit_quality=$use_explicit_quality valopts=$valopts valgrind=$valgrind"
@@ -86,11 +87,12 @@ Usage: test-rastertogutenprint [options] [PPD files...]
-L Use highest available quality setting
-X Don't use explicit quality setting
-N Use the smallest available page size
+ -d Don't actually run the command
EOF
exit 0;
}
-while getopts "hvcgsVnO:m:o:p:St:lLXf:N" opt ; do
+while getopts "hvcgsVnO:m:o:p:PSt:lLXf:Nd" opt ; do
case "$opt" in
h*) usage ;;
v) valgrind=$((valgrind + 1)) ;;
@@ -98,7 +100,7 @@ while getopts "hvcgsVnO:m:o:p:St:lLXf:N" opt ; do
g) valopts='--vgdb=yes --error-exitcode=1' ;;
s) single=1 ;;
V) verbose=$((verbose+1)) ;;
- n) make_ppds='' ;;
+ n) make_ppds=0 ;;
O) outdir="$OPTARG"; mkdir -p "$outdir" ;;
o) cupsargs="$cupsargs $OPTARG" ;;
m) md5dir="$OPTARG"; mkdir -p "$md5dir" ;;
@@ -111,11 +113,15 @@ while getopts "hvcgsVnO:m:o:p:St:lLXf:N" opt ; do
l) use_explicit_quality=1 ;;
L) use_explicit_quality=2 ;;
N) use_smallest_pagesize=1 ;;
+ d) dontrun=1 ;;
\?) usage ;;
*) echo "Unknown argument $opt"; usage ;;
esac
done
+STP_TEST_ROTOR=${STP_TEST_ROTOR:-0}
+STP_TEST_ROTOR_CIRCUMFERENCE=${STP_TEST_ROTOR_CIRCUMFERENCE:-1}
+
case "$valgrind" in
4)
valopts='--tool=callgrind --dump-instr=yes --trace-jump=yes --error-exitcode=1'
@@ -129,6 +135,25 @@ esac
shift $((OPTIND - 1))
+if (( $# > 0 )) ; then
+ single=0
+ for i in $(seq 1 $#) ; do
+ (( (i - 1) % $STP_TEST_ROTOR_CIRCUMFERENCE == $STP_TEST_ROTOR )) && printers_to_test+=($1)
+ shift
+ done
+ (( ${#printers_to_test[@]} == 0 )) && exit 77
+fi
+
+(( single > 0 )) && extra_genppd_opts="$extra_genppd_opts -S"
+
+if (( STP_TEST_ROTOR_CIRCUMFERENCE > 1 &&
+ STP_TEST_ROTOR >= 0 &&
+ STP_TEST_ROTOR < STP_TEST_ROTOR_CIRCUMFERENCE )) ; then
+ extra_genppd_opts="$extra_genppd_opts -R $STP_TEST_ROTOR_CIRCUMFERENCE -r $STP_TEST_ROTOR"
+ STP_TEST_ROTOR=0
+ STP_TEST_ROTOR_CIRCUMFERENCE=1
+fi
+
version="@GUTENPRINT_RELEASE_VERSION@";
rgp="./rastertogutenprint.$version"
cupsdir="$(cups-config --serverbin)/filter"
@@ -145,8 +170,8 @@ if [[ ! -x $cgpdftoraster && ! -x $pdftops && ! -x $gstoraster ]] ; then
fi
if [[ -x $pstoraster || -x $gstoraster || -x $cgpdftoraster ]] ; then
- pages="24-$((24 + $npages - 1))"
- (( $postscript > 0 )) && pages="page-ranges=$pages"
+ pages="24-$((24 + npages - 1))"
+ (( postscript > 0 )) && pages="page-ranges=$pages"
else
pages=''
fi
@@ -157,20 +182,20 @@ cleanup() {
}
pdfjam=$(type -p pdfjam)
-[[ -n $pdfjam ]] && postscript=1
+[[ -z $pdfjam ]] && postscript=1
-if (( $postscript > 0 )) ; then
+if (( postscript > 0 )) ; then
pdftops=$(type -p pdftops)
if [[ -n $pdftops && ! -x $cgpdftoraster ]] ; then
tfile=$(mktemp)
trap cleanup 1 2 3 6 14 15 30
- "$pdftops" -f 24 -l $((24 + $npages - 1)) "$testfile" $tfile
+ "$pdftops" -f 24 -l $((24 + npages - 1)) "$testfile" "$tfile"
fi
else
tfile=$(mktemp)
trap cleanup 1 2 3 6 14 15 30
- "$pdfjam" -q "$testfile" "$pages" -o $tfile
+ "$pdfjam" -q "$testfile" "$pages" -o "$tfile"
fi
case "$verbose" in
@@ -193,10 +218,10 @@ esac
#cupsargs='PageSize=A8'
get_ppds() {
- if [[ -n $@ || -n $printers_to_test ]] ; then
- for f in "$@" $printers_to_test ; do
+ if [[ -n $* ]] ; then
+ for f in "$@" ; do
if [[ -r $f ]] ; then
- echo $f
+ echo "$f"
elif [[ -r ppd/C/$f ]] ; then
echo "ppd/C/$f"
elif [[ -f ppd/C/${f}.ppd ]] ; then
@@ -248,19 +273,21 @@ get_ppds() {
fi
}
-if [[ -n $make_ppds || ! -d ppd/C ]] ; then
+if [[ $make_ppds -gt 0 || ! -d ppd/C ]] ; then
rm -rf ppd/C
## not all systems can work with gzipped PPDs
+ extra_genppd_opts="$extra_genppd_opts ${printers_to_test[*]}"
if [[ $skip_simplified == 1 ]] ; then
- EXTRA_GENPPD_OPTS="$extra_genppd_opts" make ppd-nonls
+ echo make ppd-nonls EXTRA_GENPPD_OPTS="$extra_genppd_opts"
+ make ppd-nonls EXTRA_GENPPD_OPTS="$extra_genppd_opts"
else
- EXTRA_GENPPD_OPTS="$extra_genppd_opts" make ppd-nonls-a
+ make ppd-nonls-a EXTRA_GENPPD_OPTS="$extra_genppd_opts"
fi
fi
find_page_size() {
ppd=$1
- (( $use_smallest_pagesize == 0 )) && return;
+ (( use_smallest_pagesize == 0 )) && return;
driver=$(grep '^\*StpDriverName' "$ppd" | sed -e 's/^[^"]*"//' -e 's/"//g')
pagesize=$(./min-pagesize "$driver")
[[ -n "$pagesize" ]] && echo "PageSize=$pagesize"
@@ -275,20 +302,20 @@ find_resolution() {
high_resolution=0
high_resolution_name=''
for r in $resolutions ; do
- res=$(sed -e 's/dpi//' -e 's/x/ \\\* /' -e 's/^\([0-9]*\)$/\1 \\\* \1/' <<< $r)
+ res=$(sed -e 's/dpi//' -e 's/x/ \\\* /' -e 's/^\([0-9]*\)$/\1 \\\* \1/' <<< "$r")
resnum=$(eval "expr $res")
- if (( $resnum > $high_resolution )) ; then
+ if (( resnum > high_resolution )) ; then
high_resolution=$resnum
high_resolution_name=$r
fi
- if (( $resnum < $low_resolution )) ; then
+ if (( resnum < low_resolution )) ; then
low_resolution=$resnum
low_resolution_name=$r
fi
done
- if (( $use_explicit_quality == 1 )) ; then
+ if (( use_explicit_quality == 1 )) ; then
echo "Resolution=$low_resolution_name"
- elif (( $use_explicit_quality == 2 )) ; then
+ elif (( use_explicit_quality == 2 )) ; then
echo "Resolution=$high_resolution_name"
fi
@@ -296,16 +323,16 @@ find_resolution() {
find_quality_preset() {
ppd=$1
- if (( $use_explicit_quality == 1 )) ; then
- for q in ${quality_presets[@]} ; do
+ if (( use_explicit_quality == 1 )) ; then
+ for q in "${quality_presets[@]}" ; do
if grep -q "^\\*StpQuality $q" "$ppd" ; then
echo "StpQuality=$q"
return
fi
done
- elif (( "$use_explicit_quality" == 2 )) ; then
+ elif (( use_explicit_quality == 2 )) ; then
best_quality=''
- for q in ${quality_presets[@]} ; do
+ for q in "${quality_presets[@]}" ; do
grep -q "^\\*StpQuality $q" "$ppd" && best_quality=$q
done
[[ -n $best_quality ]] && echo "StpQuality=$best_quality"
@@ -318,11 +345,11 @@ find_quality() {
echo "Can't find $ppd!" 1>&2
exit 1;
fi
- (( "$use_explicit_quality" == 0 )) && return
+ (( use_explicit_quality == 0 )) && return
if grep -q '\*Resolution' "$ppd" ; then
- find_resolution $ppd
+ find_resolution "$ppd"
else
- find_quality_preset $ppd
+ find_quality_preset "$ppd"
fi
}
@@ -330,30 +357,30 @@ xgrep() {
pat=$1
file=$2
if [[ $file == *.gz ]] ; then
- egrep -m1 $pat $file
+ grep -E -m1 "$pat" "$file"
else
- zgrep $pat $file
+ zgrep "$pat" "$file"
fi
}
runcmd() {
qualarg=$(find_quality "$PPD")
sizearg=$(find_page_size "$PPD")
- a='1 1 1 1'
+ a=(1 1 1 1)
qarg="$qualarg $sizearg $cupsargs"
if [[ -x $cgpdftoraster ]] ; then
# cgpdftoraster doesn't like arguments. How rude.
- $cgpdftoraster $a "" < "$tfile"
+ $cgpdftoraster "${a[@]}" "" < "$tfile"
elif [[ -f $tfile && -x $gstoraster ]] ; then
- $gstoraster $a "$qarg" < "$tfile"
+ $gstoraster "${a[@]}" "$qarg" < "$tfile"
elif [[ -f $tfile ]] ; then
- $pstops $a $"qarg" < "$tfile"
+ $pstops "${a[@]}" $"qarg" < "$tfile"
elif [[ -x $pstoraster ]] ; then
- $pdftops $a "$qarg" < "$tfile" | $pstops $a "$pages$qarg" | $pstoraster
+ $pdftops "${a[@]}" "$qarg" < "$tfile" | $pstops "${a[@]}" "$pages$qarg" | $pstoraster
elif [[ -x $gstoraster ]] ; then
- $pdftops $a "$qarg" < "$tfile" | $gstoraster $a "$pages$qarg"
+ $pdftops "${a[@]}" "$qarg" < "$tfile" | $gstoraster "${a[@]}" "$pages$qarg"
else
- $imagetoraster $a "$qarg" < calibrate.ppm
+ $imagetoraster "${a[@]}" "$qarg" < calibrate.ppm
fi
}
@@ -385,19 +412,22 @@ run_rastertogp() {
4) $vg $rgpc "$qarg" ;;
5) cat ;;
6) cat > /dev/null ;;
- *) $rgp 1 1 1 1 "$qarg"
+ *) $rgpc "$qarg"
esac
}
runme() {
f="$1"
+ m=${all_models[$f]}
p=${f#*stp-}
p=${p/${version}./}
export PPD=$f
- if [[ -n $outdir || -n $md5dir ]] ; then
- output="${p%.ppd*}...$( (runcmd 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2)"
+ if (( dontrun > 0 )) ; then
+ output="${p%.ppd*} ($m)"
+ elif [[ -n $outdir || -n $md5dir ]] ; then
+ output="${p%.ppd*} ($m)...$( (runcmd 2>/dev/null | run_rastertogp | do_output) 2>&1 3>&2)"
else
- output="${p%.ppd*}...$( (runcmd 2>/dev/null | run_rastertogp >/dev/null) 2>&1 3>&2)"
+ output="${p%.ppd*} ($m)...$( (runcmd 2>/dev/null | run_rastertogp >/dev/null) 2>&1 3>&2)"
fi
return $?
}
@@ -409,13 +439,12 @@ runall() {
retval=0
jobno=0
for f in "$@" ; do
- if (( $jobno == $rotor )) ; then
- runme "$f"
- (( $? != 0 )) && retval=1
+ if (( jobno == rotor )) ; then
+ runme "$f" || retval=1
echo "$output"
grep -q 'ERROR:' <<< "$output" && retval=1
fi
- jobno=$((($jobno+1) % $jobs))
+ jobno=$(((jobno+1) % jobs))
done
return $retval
}
@@ -423,8 +452,8 @@ runall() {
get_models() {
re='\*StpDriverModelFamily: '
if (( ${#all_models[*]} <= 1 )) ; then
- declare -a models=($(xargs grep -m1 -H "^$re" <<< $@ | sed "s/:$re/=/"))
- for m in ${models[@]} ; do
+ declare -a models=($(xargs grep -m1 -H "^$re" <<< "$*" | sed "s/:$re/=/"))
+ for m in "${models[@]}" ; do
model=${m#*=}
file=${m%%=*}
all_models[$file]=$model
@@ -434,50 +463,48 @@ get_models() {
retval=0
if [[ -d ppd/C ]] ; then
- declare -a files=($(get_ppds "$@"))
+ declare -a files=($(get_ppds))
declare -A models
declare -a nfiles
- if (( $skip_simplified > 0 )) ; then
- for f in ${files[@]} ; do
- [[ $f != *.sim.ppd* ]] && nfiles+=($f)
+ if (( skip_simplified > 0 )) ; then
+ for f in "${files[@]}" ; do
+ [[ $f != *.sim.ppd* ]] && nfiles+=("$f")
done
- files=(${nfiles[@]})
+ files=("${nfiles[@]}")
fi
+ get_models "${files[@]}"
if [[ -n $family ]] ; then
- get_models ${files[@]}
nfiles=()
- for f in ${files[@]} ; do
- [[ ${all_models[$f]} =~ $family ]] && nfiles+=($f)
+ for f in "${files[@]}" ; do
+ [[ ${all_models[$f]} =~ $family ]] && nfiles+=("$f")
done
- files=(${nfiles[@]})
+ files=("${nfiles[@]}")
fi
- if (( $single != 0 )) ; then
+ if (( single != 0 )) ; then
declare -A seen_models
nfiles=()
- get_models ${files[@]}
- for f in ${files[@]} ; do
+ get_models "${files[@]}"
+ for f in "${files[@]}" ; do
model=${all_models[$f]}
[[ $f == *.sim.ppd ]] && model="${model}_sim"
if [[ -z ${seen_models[$model]} ]] ; then
- nfiles+=($f)
+ nfiles+=("$f")
seen_models[$model]=1
fi
done
- files=(${nfiles[@]})
+ files=("${nfiles[@]}")
fi
- (( ${#files[@]} < $jobs )) && jobs=${#files[@]}
- declare -a subproc=($(seq 0 $((jobs-1))))
+ (( ${#files[@]} < jobs )) && jobs=${#files[@]}
# Fire 'em off in the background...
- for i in ${subproc[@]} ; do
- runall $jobs $i ${files[@]} &
+ for i in $(seq 0 $((jobs-1))) ; do
+ runall "$jobs" "$i" "${files[@]}" &
done
# And wait for them to complete.
- for i in ${subproc[@]} ; do
- wait -n
- (( $? != 0 )) && retval=1
+ for i in $(seq 0 $((jobs-1))) ; do
+ wait -n || retval=1
done
fi
[[ -n $tfile ]] && rm -f "$tfile"
-(( $retval == 0 )) && rm -rf ppd/C && rmdir ppd
-exit $retval
+(( retval == 0 && make_ppds > 0 )) && rm -rf ppd/C && rmdir ppd
+exit "$retval"
diff --git a/src/cups/test-rastertogutenprint.check.in b/src/cups/test-rastertogutenprint.test.in
index cd3f38b..e2f74f8 100644
--- a/src/cups/test-rastertogutenprint.check.in
+++ b/src/cups/test-rastertogutenprint.test.in
@@ -29,6 +29,8 @@ fi
STP_TEST_PROFILE=${STP_TEST_PROFILE:-full}
+[[ -n $STP_TEST_COMPONENTS && $STP_TEST_COMPONENTS != '*CUPS*' && $STP_TEST_COMPONENTS != '*test-rastertogutenprint*' ]] && exit 77
+
set -e
declare FASTOPT="-o StpDitherAlgorithm=VeryFast -l -N -o ColorCorrection=Raw"
@@ -69,7 +71,7 @@ function test_valgrind() {
case "$STP_TEST_PROFILE" in
full|fast|valgrind|valgrind_minimal|valgrind_fast|minimal)
- test_$STP_TEST_PROFILE
+ test_"$STP_TEST_PROFILE"
;;
*)
exit 77