diff -Pru sane-backends/backend/Makefile.in sane-backends-new/backend/Makefile.in --- sane-backends/backend/Makefile.in 2008-05-07 19:04:40.000000000 +0200 +++ sane-backends-new/backend/Makefile.in 2008-06-04 22:02:02.000000000 +0200 @@ -96,6 +96,7 @@ as6e.c as6e.h \ avision.c avision.conf.in avision.h \ bh.c bh.conf.in bh.h \ + brother.c brother.h brother.conf \ canon.c canon.conf.in canon.h canon-sane.c canon-scsi.c \ canon630u.c canon630u-common.c canon630u.conf.in \ canon_pp.conf.in canon_pp.h canon_pp.c canon_pp-dev.c \ @@ -384,6 +385,9 @@ libsane-bh.la: ../sanei/sanei_config2.lo libsane-bh.la: ../sanei/sanei_constrain_value.lo libsane-bh.la: ../sanei/sanei_scsi.lo +libsane-brother.la: ../sanei/sanei_config2.lo +libsane-brother.la: ../sanei/sanei_constrain_value.lo +libsane-brother.la: ../sanei/sanei_usb.lo libsane-canon.la: ../sanei/sanei_config2.lo libsane-canon.la: ../sanei/sanei_constrain_value.lo libsane-canon.la: ../sanei/sanei_scsi.lo diff -Pru sane-backends/backend/Makefile.in~ sane-backends-new/backend/Makefile.in~ --- sane-backends/backend/Makefile.in~ 1970-01-01 01:00:00.000000000 +0100 +++ sane-backends-new/backend/Makefile.in~ 2008-06-04 22:02:02.000000000 +0200 @@ -0,0 +1,626 @@ +SHELL = /bin/sh + +VPATH = @srcdir@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = .. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +package_version = @PACKAGE_STRING@ +distdir = $(top_srcdir)/$(PACKAGE)-$(VERSION) + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datarootdir = @datarootdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +locksanedir = @locksanedir@ +libdir = @libdir@ +libsanedir = $(libdir)/sane +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +configdir = ${sysconfdir}/sane.d +BEOS_ADDONDIR = @BEOS_ADDONDIR@ + +V_MAJOR = @V_MAJOR@ +V_MINOR = @V_MINOR@ +V_REV = @V_REV@ +DLL_PRELOAD = @DLL_PRELOAD@ +DLL_PRELOAD_EXTRAS = $(foreach be,$(DLL_PRELOAD),$($(addprefix EXTRA_,$(be)))) + +MKDIR = $(top_srcdir)/mkinstalldirs +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_LOCKPATH = @INSTALL_LOCKPATH@ +LOCKPATH_GROUP = @LOCKPATH_GROUP@ + +RANLIB = @RANLIB@ +LN_S = @LN_S@ + +CC = @CC@ +INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ +BACKENDLIBS = @LIBS@ @DL_LIB@ +DEFS = @DEFS@ +DYNAMIC_FLAG=@DYNAMIC_FLAG@ +USE_LINKS=@USE_LINKS@ + +LIBTOOL = ../libtool +MCOMP = --mode=compile +MLINK = --mode=link +MINST = --mode=install + +COMPILE = $(CC) -c $(CFLAGS) $(DEFS) $(INCLUDES) $(CPPFLAGS) + +DISTCLEAN_FILES = @DISTCLEAN_FILES@ + +FIRMWARE_DIRS = artec_eplus48u gt68xx snapscan epjitsu + +@SET_MAKE@ + +PRELOADABLE_BACKENDS = @BACKENDS@ + +ALL_BACKENDS = $(PRELOADABLE_BACKENDS) dll + +LIBS = $(addprefix libsane-,$(addsuffix .la,$(ALL_BACKENDS))) +CONFIGS = $(addsuffix .conf,$(ALL_BACKENDS)) saned.conf + +EXTRA = sane_strstatus.lo ../sanei/sanei_init_debug.lo ../sanei/sanei_config.lo + +# With libtool-1.0, we have to mention each library object explicitly... ;-( +ifneq (@LIBOBJS@ @ALLOCA@,) +LIBLIB_FUNCS = $(basename @LIBOBJS@ @ALLOCA@) +else +LIBLIB_FUNCS = +endif + +LIBOBJS = $(addprefix ../lib/,$(addsuffix .lo,$(LIBLIB_FUNCS))) + +DISTFILES = Makefile.in saned.conf.in sane_strstatus.c stubs.c \ + abaton.c abaton.conf.in abaton.h \ + agfafocus.c agfafocus.conf.in agfafocus.h \ + apple.c apple.conf.in apple.h \ + artec.c artec.conf.in artec.h \ + artec_eplus48u.c artec_eplus48u.h artec_eplus48u.conf.in \ + as6e.c as6e.h \ + avision.c avision.conf.in avision.h \ + bh.c bh.conf.in bh.h \ + canon.c canon.conf.in canon.h canon-sane.c canon-scsi.c \ + canon630u.c canon630u-common.c canon630u.conf.in \ + canon_pp.conf.in canon_pp.h canon_pp.c canon_pp-dev.c \ + canon_pp-dev.h canon_pp-io.c canon_pp-io.h \ + cardscan.c cardscan.conf.in cardscan.h \ + coolscan.c coolscan.conf.in coolscan.h coolscan-scsidef.h \ + coolscan2.c coolscan2.conf.in \ + coolscan3.c coolscan3.conf.in \ + dc210.c dc210.conf.in dc210.h \ + dc240.c dc240.conf.in dc240.h \ + dc25.c dc25.conf.in dc25.h \ + dell1600n_net.c dell1600n_net.conf.in \ + dll.aliases dll.c dll.conf.in \ + dmc.c dmc.conf.in dmc.h \ + epjitsu.c epjitsu.conf.in epjitsu.h epjitsu-cmd.h \ + epson.c epson_scsi.c epson_usb.c epson.conf.in epson.h epson_scsi.h \ + epson_usb.h \ + epson2_net.c epson2_net.h epson2.c epson2.h epson2_scsi.c epson2_scsi.h \ + epson2-io.c epson2-io.h epson2-commands.c epson2-commands.h\ + epson2.conf.in\ + fujitsu.c fujitsu.conf.in fujitsu.h fujitsu-scsi.h \ + genesys.c genesys.h genesys_gl646.c genesys_low.h \ + genesys.conf.in genesys_devices.c genesys_gl841.c \ + genesys_conv.c genesys_conv_hlp.c \ + gphoto2.c gphoto2.conf.in gphoto2.h \ + gt68xx.c gt68xx.h gt68xx_high.c gt68xx_high.h gt68xx_mid.c gt68xx_mid.h \ + gt68xx_gt6801.c gt68xx_gt6801.h gt68xx_gt6816.c gt68xx_gt6816.h \ + gt68xx_low.c gt68xx_low.h gt68xx_devices.c gt68xx_generic.c \ + gt68xx_generic.h gt68xx_shm_channel.c gt68xx_shm_channel.h gt68xx.conf.in \ + hp-accessor.c hp-accessor.h hp.c hp.conf.in hp-device.c hp-device.h hp.h \ + hp-handle.c hp-handle.h hp-hpmem.c hp-option.c \ + hp-option.h hp.README hp-scl.c hp-scl.h hp-scsi.h hp.TODO \ + hp3500.c \ + hp3900.c hp3900.conf.in hp3900_config.c hp3900_debug.c hp3900_rts8822.c \ + hp3900_sane.c hp3900_types.c hp3900_usb.c \ + hp4200.c hp4200.conf.in hp4200.h hp4200_lm9830.c hp4200_lm9830.h \ + hp5400.c hp5400.h hp5400.conf.in hp5400_debug.c hp5400_debug.h \ + hp5400_internal.c hp5400_internal.h hp5400_xfer.h hp5400_sane.c \ + hp5400_sanei.c hp5400_sanei.h \ + hp5590.c hp5590_cmds.c hp5590_low.c hp5590_cmds.h hp5590_low.h \ + hpljm1005.c \ + hpsj5s.c hpsj5s.conf.in hpsj5s.h \ + hs2p.c hs2p.conf.in hs2p-scsi.c hs2p.h hs2p-scsi.h hs2p-saneopts.h \ + ibm.c ibm.conf.in ibm.h ibm-scsi.c \ + leo.c leo.h leo.conf.in \ + lexmark.c lexmark_low.c lexmark_models.c lexmark_sensors.c lexmark.h \ + lexmark.conf.in \ + lm9830.h \ + ma1509.c ma1509.conf.in ma1509.h \ + matsushita.c matsushita.conf.in matsushita.h \ + microtek.c microtek.conf.in microtek.h \ + microtek2.c microtek2.conf.in microtek2.h \ + mustek.c mustek.conf.in mustek.h \ + mustek_pp.c mustek_pp.conf.in mustek_pp.h mustek_pp_cis.c mustek_pp_cis.h \ + mustek_pp_decl.h mustek_pp_drivers.h mustek_pp_null.c mustek_pp_ccd300.c \ + mustek_pp_ccd300.h mustek_scsi_pp.c mustek_scsi_pp.h \ + mustek_usb.c mustek_usb.conf.in mustek_usb.h mustek_usb_high.c \ + mustek_usb_high.h mustek_usb_low.c mustek_usb_low.h mustek_usb_mid.c \ + mustek_usb_mid.h \ + mustek_usb2.c mustek_usb2.h mustek_usb2_asic.c mustek_usb2_asic.h \ + mustek_usb2_high.c mustek_usb2_high.h mustek_usb2_reflective.c \ + mustek_usb2_transparent.c \ + nec.c nec.conf.in nec.h \ + net.c net.conf.in net.h \ + niash.c niash_core.c niash_core.h niash_xfer.c niash_xfer.h \ + pie.c pie.conf.in pie-scsidef.h \ + pint.c pint.h \ + pixma.c pixma.h pixma_common.c pixma_common.h pixma_mp150.c pixma_mp730.c \ + pixma_mp750.c pixma_sane_options.c pixma_sane_options.h pixma_io.h \ + pixma_io_sanei.c pixma_rename.h pixma_imageclass.c \ + plustek.c plustek.conf.in plustek-usbdevs.c plustek.h plustek-usb.c \ + plustek-usb.h plustek-usbhw.c plustek-usbimg.c plustek-usbio.c \ + plustek-usbmap.c plustek-usbscan.c plustek-usbshading.c plustek-usbcalfile.c \ + plustek-usbcal.c \ + plustek-pp_dac.c plustek-pp_dbg.h plustek-pp_detect.c plustek-pp_genericio.c \ + plustek-pp_hwdefs.h plustek-pp_image.c plustek-pp_io.c plustek-pp_map.c \ + plustek-pp_misc.c plustek-pp_models.c plustek-pp_motor.c plustek-pp_p12.c \ + plustek-pp_p12ccd.c plustek-pp_p48xx.c plustek-pp_p9636.c \ + plustek-pp_procfs.c plustek-pp_procs.h plustek-pp_ptdrv.c plustek-pp_scale.c \ + plustek-pp_scan.h plustek-pp_scandata.h plustek-pp_sysdep.h plustek-pp_tpa.c \ + plustek-pp_types.h plustek_pp.c plustek-pp_wrapper.c plustek_pp.conf.in \ + plustek-pp.h \ + pnm.c \ + qcam.c qcam.conf.in qcam.h \ + ricoh.c ricoh.conf.in ricoh.h ricoh-scsi.c \ + rts8891.c rts8891.h rts8891_low.h rts88xx_lib.c \ + rts8891_devices.c rts8891_low.c rts88xx_lib.h rts8891.conf.in \ + s9036.c s9036.conf.in s9036.h \ + sceptre.c sceptre.conf.in sceptre.h \ + sharp.c sharp.conf.in sharp.h \ + sm3600.c sm3600-color.c sm3600-gray.c sm3600.h sm3600-homerun.c \ + sm3600-scanmtek.c sm3600-scantool.h sm3600-scanusb.c sm3600-scanutil.c \ + sm3840.conf.in sm3840.c sm3840_lib.c sm3840_params.h sm3840_scan.c sm3840.h \ + sm3840_lib.h \ + snapscan.c snapscan-data.c snapscan.conf.in snapscan.h snapscan-scsi.c \ + snapscan-sources.c snapscan-mutex.c snapscan-sources.h snapscan-usb.c \ + snapscan-usb.h snapscan-options.c \ + sp15c.c sp15c.conf.in sp15c.h sp15c-scsi.h \ + st400.c st400.conf.in st400.h \ + stv680.c stv680.conf.in stv680.h \ + tamarack.c tamarack.conf.in tamarack.h \ + teco1.c teco1.conf.in teco1.h \ + teco2.c teco2.conf.in teco2.h \ + teco3.c teco3.conf.in teco3.h \ + test.c test.conf.in test.h test-picture.c \ + u12.c u12.h u12-scanner.h u12-hwdef.h u12.conf.in u12-shading.c u12-tpa.c \ + u12-ccd.c u12-hw.c u12-if.c u12-image.c u12-io.c u12-map.c u12-motor.c \ + umax.c umax.conf.in umax.h umax-scanner.c umax-scanner.h umax-scsidef.h \ + umax-uc1200s.c umax-uc1200se.c umax-uc1260.c umax-uc630.c umax-uc840.c \ + umax-ug630.c umax-ug80.c umax-usb.c \ + umax_pp.c umax_pp.conf.in umax_pp.h umax_pp_low.c umax_pp_low.h \ + umax_pp_mid.c umax_pp_mid.h \ + umax1220u.c umax1220u-common.c umax1220u.conf.in \ + v4l.c v4l.conf.in v4l-frequencies.h v4l.h + +.PHONY: all clean depend dist distclean install uninstall + +libsane-%.la: %.lo %-s.lo $(EXTRA) $(LIBOBJS) + @$(LIBTOOL) $(MLINK) $(CC) -export-dynamic -o $@ $($*_LIBS) \ + $(LDFLAGS) $(BACKENDLIBS) $^ @LIBTOOL_LINK_EXTRA@ -rpath $(libsanedir) \ + -version-number $(V_MAJOR):$(V_MINOR):$(V_REV) $(DYNAMIC_FLAG) + +%-s.lo: %-s.c + @$(LIBTOOL) $(MCOMP) $(COMPILE) -DSTUBS -DBACKEND_NAME=$* $< + +%.lo: %.c + @$(LIBTOOL) $(MCOMP) $(COMPILE) -DBACKEND_NAME=$* \ + -DLIBDIR=$(libsanedir) $< + +%-s.c: $(srcdir)/stubs.c + rm -f $@ + $(LN_S) $(srcdir)/stubs.c $@ + +# Don't delete any intermediate files. +.PRECIOUS: %-s.c %-s.lo %.lo dll-preload.c + +all: $(LIBS) libsane.la becfg + +install: $(INSTALL_LOCKPATH) install-be@BE_INSTALL_FLAVOR@ install-libsane install-becfg + +install-be: + $(MKDIR) $(DESTDIR)$(libdir) $(DESTDIR)$(libsanedir) $(DESTDIR)$(configdir) $(DESTDIR)$(configdir)/dll.d + @# Install all backends in $(prefix)/lib/sane/ + @list="$(LIBS)"; for be in $$list; do \ + echo installing $${be} in $(DESTDIR)$(libsanedir)/$${be}...; \ + $(LIBTOOL) $(MINST) $(INSTALL_PROGRAM) $${be} \ + $(DESTDIR)$(libsanedir)/$${be} >/dev/null || exit 1; \ + done + @$(LIBTOOL) $(MINST) --finish $(DESTDIR)$(libsanedir) >/dev/null + @# Remove libsane.* links in lib/sane/ as these links to libsane-v4l.so + @# cause misdetection of scanners. + rm -f $(DESTDIR)$(libsanedir)/libsane.* + @# Create library links manually. Actually this is libtool's job but it doesn't + @# seem to work on some platforms. + @# Assume the dll name without any versions is last + @if test "$(USE_LINKS)" = "yes" ; then \ + dllend=`../tools/libtool-get-dll-ext libsane-dll.la`; \ + list="$(ALL_BACKENDS)"; cd $(DESTDIR)$(libsanedir) && for be in $$list; do \ + file=libsane-$${be}.$$dllend.$(V_MAJOR); \ + lib=`grep dlname= libsane-$${be}.la | cut -f2 -d"'"`; \ + if test ! -f $${file} -a -n "$${lib}"; then \ + $(LN_S) $${lib} $${file}; \ + fi; \ + done; \ + fi + +install-be-beos: + $(MKDIR) $(DESTDIR)$(libdir) $(DESTDIR)$(libsanedir) $(DESTDIR)$(configdir) $(DESTDIR)$(configdir)/dll.d $(DESTDIR)$(BEOS_ADDONDIR) + @list="$(ALL_BACKENDS)"; for be in $$list; do \ + echo installing $${be} in $(BEOS_ADDONDIR)/$${be}...; \ + cp -p .libs/libsane-$${be}.so $(DESTDIR)$(BEOS_ADDONDIR)/$${be} || exit 1; \ + done + +install-libsane: + @echo installing libsane.la in $(DESTDIR)$(libdir)/libsane.la... + @$(LIBTOOL) $(MINST) $(INSTALL_PROGRAM) libsane.la \ + $(DESTDIR)$(libdir)/libsane.la >/dev/null + @$(LIBTOOL) $(MINST) --finish $(DESTDIR)$(libdir) + +install-becfg: + @list="$(CONFIGS)"; for cfg in $$list; do \ + if test ! -r $${cfg}; then continue; fi; \ + if test -f $(DESTDIR)$(configdir)/$${cfg}; then \ + echo NOT overwriting $${cfg} in $(configdir)...; \ + else \ + echo installing $${cfg} in $(configdir)/$${cfg}...; \ + $(INSTALL_DATA) $${cfg} $(DESTDIR)$(configdir)/$${cfg} \ + || exit 1; \ + fi; \ + done + for dir in $(FIRMWARE_DIRS) ; do \ + $(MKDIR) $(DESTDIR)$(datadir)/sane/$${dir} ; \ + done + +install-lockpath: + $(MKDIR) -m 775 -g $(LOCKPATH_GROUP) $(DESTDIR)$(locksanedir) + +uninstall: + rm -rf $(libsanedir) $(configdir) $(locksanedir) + rm -f $(libdir)/libsane.* + -for dir in $(FIRMWARE_DIRS) ; do \ + rmdir $(datadir)/sane/$${dir} ; \ + done + +dll.lo: dll-preload.c + +dll-preload.c: + rm -f $@ + list="$(DLL_PRELOAD)"; for be in $$list; do \ + echo "PRELOAD_DECL($$be)" >> $@; \ + done + echo "static struct backend preloaded_backends[] = {" >> $@ + sep=""; \ + list="$(DLL_PRELOAD)"; \ + if test -z "$${list}"; then \ + echo { 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }} >> $@; \ + else \ + for be in $$list; do \ + echo "$${sep}PRELOAD_DEFN($$be)" >> $@; \ + sep=","; \ + done; \ + fi + echo "};" >> $@ + +libsane.la: dll.lo dll-s.lo $(EXTRA) $(addsuffix .lo,$(DLL_PRELOAD)) $(LIBOBJS) + @$(LIBTOOL) $(MLINK) $(CC) -o $@ $(LDFLAGS) $(BACKENDLIBS) $^ \ + $(addsuffix .lo,$(DLL_PRELOAD_EXTRAS)) @LIBTOOL_LINK_EXTRA@ \ + -rpath $(libdir) -version-number $(V_MAJOR):$(V_MINOR):$(V_REV) + +# Generate .conf files for all existing .conf.in files +becfg: $(patsubst %.conf.in,%.conf,$(wildcard *.conf.in)) +%.conf: %.conf.in + @echo Generating $@ from $^ + @sed -e 's|@DATADIR@|$(datadir)|g' \ + -e 's|@CONFIGDIR@|$(configdir)|g' \ + -e 's|@DOCDIR@|$(docdir)|g' \ + -e 's|@LIBDIR@|$(libdir)/sane|g' \ + -e 's|@BINDIR@|$(bindir)|g' \ + -e 's|@SBINDIR@|$(sbindir)|g' \ + -e 's|@PACKAGEVERSION@|$(package_version)|g' $? > $@ + + + +# additional dependencies + +EXTRA_canon_pp = canon_pp-io canon_pp-dev +EXTRA_genesys = genesys_gl646 genesys_gl841 +EXTRA_hp = hp-accessor hp-device hp-handle hp-hpmem hp-option hp-scl +EXTRA_umax_pp = umax_pp_low umax_pp_mid +EXTRA_epson = epson_scsi epson_usb +EXTRA_epson2 = epson2_scsi epson_usb epson2_net epson2-io epson2-commands +EXTRA_lexmark = lexmark_low +EXTRA_pixma = pixma_io_sanei pixma_common pixma_mp150 pixma_mp730 pixma_mp750 pixma_imageclass +EXTRA_rts8891 = rts88xx_lib + +# When preloading dll, we need to add in all preloaded objects: +libsane-dll.la: $(addsuffix .lo,$(DLL_PRELOAD)) +libsane-dll.la: $(addsuffix .lo,$(DLL_PRELOAD_EXTRAS)) + +# We must not build SANE backend libraries that contain unresolved references +# to any of the sanei routines. These explicit dependencies take care of +# this: + +libsane-abaton.la: ../sanei/sanei_config2.lo +libsane-abaton.la: ../sanei/sanei_constrain_value.lo +libsane-abaton.la: ../sanei/sanei_scsi.lo +libsane-agfafocus.la: ../sanei/sanei_config2.lo +libsane-agfafocus.la: ../sanei/sanei_constrain_value.lo +libsane-agfafocus.la: ../sanei/sanei_scsi.lo +libsane-agfafocus.la: ../sanei/sanei_thread.lo +libsane-apple.la: ../sanei/sanei_config2.lo +libsane-apple.la: ../sanei/sanei_constrain_value.lo +libsane-apple.la: ../sanei/sanei_scsi.lo +libsane-artec.la: ../sanei/sanei_config2.lo +libsane-artec.la: ../sanei/sanei_constrain_value.lo +libsane-artec.la: ../sanei/sanei_scsi.lo +libsane-artec_eplus48u.la: ../sanei/sanei_constrain_value.lo +libsane-artec_eplus48u.la: ../sanei/sanei_usb.lo +libsane-artec_eplus48u.la: ../sanei/sanei_thread.lo +libsane-as6e.la: ../sanei/sanei_constrain_value.lo +libsane-avision.la: ../sanei/sanei_config2.lo +libsane-avision.la: ../sanei/sanei_constrain_value.lo +libsane-avision.la: ../sanei/sanei_scsi.lo +libsane-avision.la: ../sanei/sanei_usb.lo +libsane-avision.la: ../sanei/sanei_thread.lo +libsane-bh.la: ../sanei/sanei_config2.lo +libsane-bh.la: ../sanei/sanei_constrain_value.lo +libsane-bh.la: ../sanei/sanei_scsi.lo +libsane-canon.la: ../sanei/sanei_config2.lo +libsane-canon.la: ../sanei/sanei_constrain_value.lo +libsane-canon.la: ../sanei/sanei_scsi.lo +libsane-canon630u.la: ../sanei/sanei_constrain_value.lo +libsane-canon630u.la: ../sanei/sanei_usb.lo +libsane-canon_pp.la: $(addsuffix .lo,$(EXTRA_canon_pp)) +libsane-cardscan.la: ../sanei/sanei_constrain_value.lo +libsane-cardscan.la: ../sanei/sanei_usb.lo +libsane-coolscan.la: ../sanei/sanei_config2.lo +libsane-coolscan.la: ../sanei/sanei_constrain_value.lo +libsane-coolscan.la: ../sanei/sanei_scsi.lo +libsane-coolscan.la: ../sanei/sanei_thread.lo +libsane-coolscan2.la: ../sanei/sanei_config2.lo +libsane-coolscan2.la: ../sanei/sanei_constrain_value.lo +libsane-coolscan2.la: ../sanei/sanei_scsi.lo +libsane-coolscan2.la: ../sanei/sanei_usb.lo +libsane-coolscan3.la: ../sanei/sanei_config2.lo +libsane-coolscan3.la: ../sanei/sanei_constrain_value.lo +libsane-coolscan3.la: ../sanei/sanei_scsi.lo +libsane-coolscan3.la: ../sanei/sanei_usb.lo +libsane-dc25.la: ../sanei/sanei_constrain_value.lo +libsane-dc210.la: ../sanei/sanei_constrain_value.lo ../sanei/sanei_jpeg.lo +libsane-dc240.la: ../sanei/sanei_constrain_value.lo ../sanei/sanei_jpeg.lo +libsane-dmc.la: ../sanei/sanei_config2.lo +libsane-dmc.la: ../sanei/sanei_constrain_value.lo +libsane-dmc.la: ../sanei/sanei_scsi.lo +libsane-epjitsu.la: ../sanei/sanei_constrain_value.lo +libsane-epjitsu.la: ../sanei/sanei_usb.lo +libsane-epson.la: $(addsuffix .lo,$(EXTRA_epson)) +libsane-epson.la: ../sanei/sanei_config2.lo +libsane-epson.la: ../sanei/sanei_constrain_value.lo +libsane-epson.la: ../sanei/sanei_scsi.lo +libsane-epson.la: ../sanei/sanei_usb.lo +libsane-epson.la: ../sanei/sanei_pio.lo +libsane-epson2.la: $(addsuffix .lo,$(EXTRA_epson2)) +libsane-epson2.la: ../sanei/sanei_config2.lo +libsane-epson2.la: ../sanei/sanei_constrain_value.lo +libsane-epson2.la: ../sanei/sanei_scsi.lo +libsane-epson2.la: ../sanei/sanei_usb.lo +libsane-epson2.la: ../sanei/sanei_pio.lo +libsane-epson2.la: ../sanei/sanei_tcp.lo +libsane-epson2.la: ../sanei/sanei_udp.lo +libsane-fujitsu.la: ../sanei/sanei_config2.lo +libsane-fujitsu.la: ../sanei/sanei_constrain_value.lo +libsane-fujitsu.la: ../sanei/sanei_scsi.lo +libsane-fujitsu.la: ../sanei/sanei_usb.lo +libsane-genesys.la: ../sanei/sanei_constrain_value.lo +libsane-genesys.la: ../sanei/sanei_usb.lo +libsane-genesys.la: $(addsuffix .lo,$(EXTRA_genesys)) +libsane-gphoto2.la: ../sanei/sanei_constrain_value.lo ../sanei/sanei_jpeg.lo +libsane-gt68xx.la: ../sanei/sanei_constrain_value.lo +libsane-gt68xx.la: ../sanei/sanei_usb.lo +libsane-hp.la: ../sanei/sanei_config2.lo +libsane-hp.la: ../sanei/sanei_constrain_value.lo +libsane-hp.la: ../sanei/sanei_scsi.lo +libsane-hp.la: ../sanei/sanei_usb.lo +libsane-hp.la: $(addsuffix .lo,$(EXTRA_hp)) +libsane-hp.la: ../sanei/sanei_pio.lo +libsane-hp.la: ../sanei/sanei_thread.lo +libsane-hp3500.la: ../sanei/sanei_usb.lo +libsane-hp3500.la: ../sanei/sanei_thread.lo +libsane-hp3500.la: ../sanei/sanei_constrain_value.lo +libsane-hp3900.la: ../sanei/sanei_usb.lo +libsane-hp4200.la: ../sanei/sanei_constrain_value.lo +libsane-hp4200.la: ../sanei/sanei_usb.lo +libsane-hp4200.la: ../sanei/sanei_pv8630.lo +libsane-hp5400.la: ../sanei/sanei_usb.lo +libsane-hp5590.la: ../sanei/sanei_usb.lo +libsane-hpljm1005.la: ../sanei/sanei_usb.lo +libsane-hpljm1005.la: ../sanei/sanei_constrain_value.lo +libsane-hs2p.la: ../sanei/sanei_scsi.lo +libsane-hs2p.la: ../sanei/sanei_config2.lo +libsane-hs2p.la: ../sanei/sanei_constrain_value.lo +libsane-ibm.la: ../sanei/sanei_scsi.lo +libsane-ibm.la: ../sanei/sanei_config2.lo +libsane-ibm.la: ../sanei/sanei_constrain_value.lo +libsane-leo.la: ../sanei/sanei_config2.lo +libsane-leo.la: ../sanei/sanei_constrain_value.lo +libsane-leo.la: ../sanei/sanei_scsi.lo +libsane-lexmark.la: $(addsuffix .lo,$(EXTRA_lexmark)) +libsane-lexmark.la: ../sanei/sanei_constrain_value.lo +libsane-lexmark.la: ../sanei/sanei_usb.lo +libsane-ma1509.la: ../sanei/sanei_constrain_value.lo +libsane-ma1509.la: ../sanei/sanei_usb.lo +libsane-matsushita.la: ../sanei/sanei_config2.lo +libsane-matsushita.la: ../sanei/sanei_constrain_value.lo +libsane-matsushita.la: ../sanei/sanei_scsi.lo +libsane-microtek.la: ../sanei/sanei_config2.lo +libsane-microtek.la: ../sanei/sanei_constrain_value.lo +libsane-microtek.la: ../sanei/sanei_scsi.lo +libsane-microtek2.la: ../sanei/sanei_config2.lo +libsane-microtek2.la: ../sanei/sanei_constrain_value.lo +libsane-microtek2.la: ../sanei/sanei_scsi.lo +libsane-microtek2.la: ../sanei/sanei_thread.lo +libsane-mustek.la: ../sanei/sanei_config2.lo +libsane-mustek.la: ../sanei/sanei_constrain_value.lo +libsane-mustek.la: ../sanei/sanei_scsi.lo +libsane-mustek.la: ../sanei/sanei_ab306.lo +libsane-mustek.la: ../sanei/sanei_thread.lo +libsane-mustek.la: ../sanei/sanei_pa4s2.lo +libsane-mustek_pp.la: ../sanei/sanei_constrain_value.lo +libsane-mustek_pp.la: ../sanei/sanei_pa4s2.lo +libsane-mustek_usb.la: ../sanei/sanei_constrain_value.lo +libsane-mustek_usb.la: ../sanei/sanei_usb.lo +libsane-mustek_usb2.la: ../sanei/sanei_usb.lo +libsane-mustek_usb2.la: ../sanei/sanei_constrain_value.lo +libsane-nec.la: ../sanei/sanei_config2.lo +libsane-nec.la: ../sanei/sanei_constrain_value.lo +libsane-nec.la: ../sanei/sanei_scsi.lo +libsane-net.la: ../sanei/sanei_codec_bin.lo +libsane-net.la: ../sanei/sanei_net.lo +libsane-net.la: ../sanei/sanei_wire.lo +libsane-niash.la: ../sanei/sanei_constrain_value.lo +libsane-niash.la: ../sanei/sanei_usb.lo +libsane-pie.la: ../sanei/sanei_config2.lo +libsane-pie.la: ../sanei/sanei_constrain_value.lo +libsane-pie.la: ../sanei/sanei_scsi.lo +libsane-pie.la: ../sanei/sanei_thread.lo +libsane-pint.la: ../sanei/sanei_constrain_value.lo +libsane-pixma.la: ../sanei/sanei_usb.lo +libsane-pixma.la: ../sanei/sanei_thread.lo +libsane-pixma.la: $(addsuffix .lo,$(EXTRA_pixma)) +libsane-plustek.la: ../sanei/sanei_constrain_value.lo +libsane-plustek.la: ../sanei/sanei_usb.lo +libsane-plustek.la: ../sanei/sanei_lm983x.lo +libsane-plustek.la: ../sanei/sanei_thread.lo +libsane-plustek.la: ../sanei/sanei_access.lo +libsane-plustek_pp.la: ../sanei/sanei_constrain_value.lo +libsane-plustek_pp.la: ../sanei/sanei_thread.lo +libsane-plustek_pp.la: ../sanei/sanei_pp.lo +libsane-pnm.la: ../sanei/sanei_constrain_value.lo +libsane-qcam.la: ../sanei/sanei_constrain_value.lo +libsane-ricoh.la: ../sanei/sanei_config2.lo +libsane-ricoh.la: ../sanei/sanei_constrain_value.lo +libsane-ricoh.la: ../sanei/sanei_scsi.lo +libsane-rts8891.la: $(addsuffix .lo,$(EXTRA_rts8891)) +libsane-rts8891.la: ../sanei/sanei_constrain_value.lo +libsane-rts8891.la: ../sanei/sanei_usb.lo +libsane-s9036.la: ../sanei/sanei_config2.lo +libsane-s9036.la: ../sanei/sanei_constrain_value.lo +libsane-s9036.la: ../sanei/sanei_scsi.lo +libsane-sceptre.la: ../sanei/sanei_constrain_value.lo +libsane-sceptre.la: ../sanei/sanei_config2.lo +libsane-sceptre.la: ../sanei/sanei_scsi.lo +libsane-sharp.la: ../sanei/sanei_config2.lo +libsane-sharp.la: ../sanei/sanei_constrain_value.lo +libsane-sharp.la: ../sanei/sanei_scsi.lo +libsane-sm3600.la: ../sanei/sanei_constrain_value.lo +libsane-sm3600.la: ../sanei/sanei_usb.lo +libsane-sm3840.la: ../sanei/sanei_config2.lo +libsane-sm3840.la: ../sanei/sanei_constrain_value.lo +libsane-sm3840.la: ../sanei/sanei_usb.lo +libsane-sm3840.la: ../sanei/sanei_scsi.lo +libsane-snapscan.la: ../sanei/sanei_config2.lo +libsane-snapscan.la: ../sanei/sanei_constrain_value.lo +libsane-snapscan.la: ../sanei/sanei_scsi.lo +libsane-snapscan.la: ../sanei/sanei_usb.lo +libsane-snapscan.la: ../sanei/sanei_thread.lo +libsane-sp15c.la: ../sanei/sanei_config2.lo +libsane-sp15c.la: ../sanei/sanei_constrain_value.lo +libsane-sp15c.la: ../sanei/sanei_scsi.lo +libsane-sp15c.la: ../sanei/sanei_thread.lo +libsane-st400.la: ../sanei/sanei_config2.lo +libsane-st400.la: ../sanei/sanei_constrain_value.lo +libsane-st400.la: ../sanei/sanei_scsi.lo +libsane-stv680.la: ../sanei/sanei_constrain_value.lo +libsane-stv680.la: ../sanei/sanei_usb.lo +libsane-tamarack.la: ../sanei/sanei_config2.lo +libsane-tamarack.la: ../sanei/sanei_constrain_value.lo +libsane-tamarack.la: ../sanei/sanei_scsi.lo +libsane-tamarack.la: ../sanei/sanei_thread.lo +libsane-test.la: ../sanei/sanei_constrain_value.lo +libsane-test.la: ../sanei/sanei_thread.lo +libsane-teco1.la: ../sanei/sanei_config2.lo +libsane-teco1.la: ../sanei/sanei_constrain_value.lo +libsane-teco1.la: ../sanei/sanei_scsi.lo +libsane-teco2.la: ../sanei/sanei_config2.lo +libsane-teco2.la: ../sanei/sanei_constrain_value.lo +libsane-teco2.la: ../sanei/sanei_scsi.lo +libsane-teco3.la: ../sanei/sanei_config2.lo +libsane-teco3.la: ../sanei/sanei_constrain_value.lo +libsane-teco3.la: ../sanei/sanei_scsi.lo +libsane-u12.la: ../sanei/sanei_constrain_value.lo +libsane-u12.la: ../sanei/sanei_usb.lo +libsane-u12.la: ../sanei/sanei_thread.lo +libsane-umax.la: ../sanei/sanei_config2.lo +libsane-umax.la: ../sanei/sanei_constrain_value.lo +libsane-umax.la: ../sanei/sanei_scsi.lo +libsane-umax.la: ../sanei/sanei_usb.lo +libsane-umax.la: ../sanei/sanei_pv8630.lo +libsane-umax.la: ../sanei/sanei_thread.lo +libsane-umax_pp.la: $(addsuffix .lo,$(EXTRA_umax_pp)) +libsane-umax_pp.la: ../sanei/sanei_constrain_value.lo +libsane-umax1220u.la: ../sanei/sanei_constrain_value.lo +libsane-umax1220u.la: ../sanei/sanei_usb.lo +libsane-umax1220u.la: ../sanei/sanei_pv8630.lo +libsane-v4l.la: ../sanei/sanei_constrain_value.lo + +ifneq ($(DLL_PRELOAD),) +# need to make dll dependent on all sanei files: +libsane-dll.la libsane.la: ../sanei/sanei_config.lo +libsane-dll.la libsane.la: ../sanei/sanei_config2.lo +libsane-dll.la libsane.la: ../sanei/sanei_codec_bin.lo +libsane-dll.la libsane.la: ../sanei/sanei_constrain_value.lo +libsane-dll.la libsane.la: ../sanei/sanei_net.lo +libsane-dll.la libsane.la: ../sanei/sanei_scsi.lo +libsane-dll.la libsane.la: ../sanei/sanei_wire.lo +libsane-dll.la libsane.la: ../sanei/sanei_ab306.lo +libsane-dll.la libsane.la: ../sanei/sanei_pio.lo +libsane-dll.la libsane.la: ../sanei/sanei_pa4s2.lo +libsane-dll.la libsane.la: ../sanei/sanei_pp.lo +libsane-dll.la libsane.la: ../sanei/sanei_usb.lo +libsane-dll.la libsane.la: ../sanei/sanei_pv8630.lo +libsane-dll.la libsane.la: ../sanei/sanei_lm983x.lo +libsane-dll.la libsane.la: ../sanei/sanei_access.lo +libsane-dll.la libsane.la: ../sanei/sanei_thread.lo +ifneq (@SANEI_JPEG@,) +libsane-dll.la libsane.la: ../sanei/sanei_jpeg.lo +endif +endif + + +depend: + makedepend $(INCLUDES) *.c 2>/dev/null + makedepend -a -o.lo $(INCLUDES) *.c 2>/dev/null + +clean: + rm -f *.lo *.o *.la libsane.la dll-preload.c *.conf + find . -type l -name \*-s.c | xargs rm -f + rm -rf .libs + +distclean: clean + rm -f $(DISTCLEAN_FILES) + rm -f Makefile libsane.so + +dist: $(DISTFILES) + for file in $(DISTFILES); do \ + ln $$file $(distdir)/backend 2> /dev/null \ + || cp -p $$file $(distdir)/backend ; \ + done diff -Pru sane-backends/backend/brother.c sane-backends-new/backend/brother.c --- sane-backends/backend/brother.c 1970-01-01 01:00:00.000000000 +0100 +++ sane-backends-new/backend/brother.c 2008-06-04 22:04:52.000000000 +0200 @@ -0,0 +1,979 @@ +/* sane - Scanner Access Now Easy. + + This file (C) 2003 Fernando Trias + + This 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. + + Thi 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 sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for Brother MFC multifunction + scanner/fax/printer + +History: + +20 Feb 2003 FT Initial version + 1 Mar 2003 FT 1. Read input into temp buffer in order to match + up color lines and send at least one complete + line at a time back to the frontend. + 2. Add alignment and rounding to coordinates. 24-bit + color must be rounded to even pixels. 8-bit gray + must be rounded to nearest nibble (0xNNN0). + 3. Add sending control sequence at start of each scan. + 4. Create device_read/write fxn to incorporate future + parallel port code. + 3 Apr 2003 FT Clean up code and distribute to brother-mfc mailing + list. + +Credits: + +This driver would not have been possible without the investigative +work of Dmitri Katchalov (dmitrik@users.sourceforge.net), who deciphered +the protocol used to communicate with the MFC. He also researched the +parallel port interface, which may be added to this driver at some +point in the future. + +Also, Franklin Meng (fmeng@users.sourceforge.net) provided a lot of raw +data for the USB protocol, as well as discovering how to fax with the +MFC. + +http://www.sourceforge.net/projects/brother-mfc + +*/ + +#define BUILD 1 + +#include "../include/sane/config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../include/sane/sane.h" +#include "../include/sane/saneopts.h" +#include "../include/sane/sanei_usb.h" +#include "../include/sane/sanei_pio.h" +#include "../include/sane/sanei_config.h" + +#define BACKEND_NAME brother +#define BROTHER_CONFIG_FILE "brother.conf" + +#include "../include/sane/sanei_backend.h" + +#include "brother.h" + +static BrotherMFC *first_dev = NULL; +static const SANE_Device **devlist = 0; +static int num_devices = 0; + +#define DBG_error 1 + +/*****************************************/ + +static const SANE_Int dpi_list[] = + {4, 100, 200, 300, 600}; + +static SANE_String_Const scan_mode_list[] = { + COLOR_STR, + GRAY_STR, + BLACK_WHITE_STR, + NULL +}; + +static SANE_Range x_range; +static SANE_Range y_range; + +/*****************************************/ + +SANE_Status device_write(BrotherMFC *dev, const SANE_Byte *buf, size_t *len); +SANE_Status device_read(BrotherMFC *dev, SANE_Byte *buf, size_t *len); +BrotherMFC *find_dev(SANE_String_Const devname); +SANE_Status attach_one_usb(SANE_String_Const devname); +SANE_Status attach_one_device(SANE_String_Const devname, int dtype); +SANE_Status send_scan_command(BrotherMFC *dev); +int process_buffer(BrotherMFC *dev, SANE_Byte *buf, SANE_Int maxlen); + +/* Returns the length of the longest string, including the terminating + * character. */ +static size_t +max_string_size (SANE_String_Const strings[]) +{ + size_t size, max_size = 0; + int i; + + for (i = 0; strings[i]; ++i) { + size = strlen (strings[i]) + 1; + if (size > max_size) { + max_size = size; + } + } + + return max_size; +} + +/* Write data to a device - this function should be used instead + * of writing directly to the device in order to automatically + * support either USB or parallel port + */ +SANE_Status device_write(BrotherMFC *dev, const SANE_Byte *buf, size_t *len) +{ + SANE_Status status; + if (dev->port == BROTHER_USB) { + status = sanei_usb_write_bulk(dev->husb, buf, len); + return status; + } + else if (dev->port == BROTHER_PARPORT) { + return SANE_STATUS_INVAL; + } + return SANE_STATUS_INVAL; +} + +SANE_Status device_read(BrotherMFC *dev, SANE_Byte *buf, size_t *len) +{ + SANE_Status status; + if (dev->port == BROTHER_USB) { + status = sanei_usb_read_bulk(dev->husb, buf, len); + return status; + } + else if (dev->port == BROTHER_PARPORT) { + return SANE_STATUS_INVAL; + } + return SANE_STATUS_INVAL; +} + +BrotherMFC * +find_dev(SANE_String_Const devname) +{ + BrotherMFC *dev; + for(dev = first_dev; dev; dev = dev->next) { + if (strcmp(dev->sane.name, devname)==0) { + return dev; + } + } + return NULL; +} + +SANE_Status +attach_one_usb(SANE_String_Const devname) +{ + return attach_one_device(devname, BROTHER_USB); +} + +SANE_Status +attach_one_device(SANE_String_Const devname, int dtype) +{ + BrotherMFC *dev; + + dev = find_dev(devname); + if (dev) { + return SANE_STATUS_GOOD; + } + + dev = malloc(sizeof(BrotherMFC)); + if (dev == NULL) { + DBG (DBG_error, "ERROR: not enough memory\n"); + return SANE_STATUS_NO_MEM; + } + + memset(dev, 0, sizeof(BrotherMFC)); + + dev->devicename = strdup(devname); + dev->sane.name = dev->devicename; + dev->sane.vendor = "Brother"; + dev->sane.model = "MFC"; + dev->sane.type = "multi-function peripheral"; + + dev->port = dtype; + + dev->next = first_dev; + first_dev = dev; + + num_devices++; + + return SANE_STATUS_GOOD; +} + + +SANE_Status +sane_init (SANE_Int *vc, SANE_Auth_Callback cb) +{ + char str[1024]; + char usb[256]; + FILE * fp; + + /* all MFC devices seem to have the same code */ + strcpy(usb, "usb 0x4f9 0x111"); + + DBG( 1, "brother.c: test debug msg\n"); + + fp = sanei_config_open (BROTHER_CONFIG_FILE); + + if (fp) { + while (sanei_config_read (str, sizeof (str), fp)) { + if (strncmp(str, "usb", 3)==0) { + strcpy(usb, str); + } + } + fclose(fp); + } + + cb = cb; + + /* try USB devices */ + sanei_usb_init(); + sanei_usb_attach_matching_devices(usb, attach_one_usb); + + if (num_devices==0) { + /* TODO: no USB, so try the parallel port */ + } + + if (vc) { + *vc = SANE_VERSION_CODE (V_MAJOR, V_MINOR, BUILD); + } + return SANE_STATUS_GOOD; +} + +SANE_Status +sane_get_devices (const SANE_Device ***dl, SANE_Bool local) +{ + BrotherMFC *dev; + int i; + + local = local; + + if (devlist) free(devlist); + + devlist = malloc((num_devices + 1) * sizeof(devlist[0])); + if (!devlist) { + DBG( 1, "out of memory (line %d)\n", __LINE__); + return SANE_STATUS_NO_MEM; + } + + i = 0; + + for (dev = first_dev; i < num_devices; dev = dev->next) { + devlist[i++] = &dev->sane; + } + + devlist[i++] = 0; + *dl = devlist; + return SANE_STATUS_GOOD; +} + +SANE_Status +sane_open (SANE_String_Const name, SANE_Handle *h) +{ + unsigned int i; + char cap[] = "\x1bQ\n\x80"; + char bx[0xff]; + size_t len, len2; + BrotherMFC *dev; + SANE_Status status; + + if (name[0]) { + dev = find_dev(name); + if (!dev) { + status = attach_one_usb(name); + if (status != SANE_STATUS_GOOD) return status; + } + } + else { + dev = first_dev; + } + + if (!dev) { + DBG (DBG_error, "No scanner available\n"); + return SANE_STATUS_INVAL; + } + + /* save the handle */ + *h = dev; + + if (dev->port == BROTHER_USB) { + status = sanei_usb_open(name, &dev->husb); + + if (status != SANE_STATUS_GOOD) { + return status; + } + + /* some sort of a reset, not entirely sure */ + len = sizeof(bx); + status = sanei_usb_control_msg(dev->husb, 0xc0, 1, 2, 0, + len, (unsigned char*)bx); + if (status != SANE_STATUS_GOOD) { + return status; + } + + /* the returned message contains a number of times we're supposed + to poll for data. */ + sleep(1); + len2 = bx[0]; + for(i=0; ihusb, + (unsigned char *)bx, &len); + } + } + else if (dev->port == BROTHER_PARPORT) { + /* TODO: initialize the par port */ + } + + /* get device capabilities */ + len = sizeof(cap)-1; + status = device_write(dev, (SANE_Byte *)cap, &len); + if (status != SANE_STATUS_GOOD) { + return status; + } + + sleep(1); + len = sizeof(dev->devcap); + status = device_read(dev, (SANE_Byte *)&dev->devcap, &len); + if (status != SANE_STATUS_GOOD) { + return status; + } + + if (dev->devcap.magic[0] != 0xC1) { + return SANE_STATUS_INVAL; + } + + dev->scanning = 0; + dev->startscan = 0; + + memset (dev->opt, 0, sizeof (dev->opt)); + memset (dev->val, 0, sizeof (dev->val)); + + for (i = 0; i < OPT_NUM_OPTIONS; ++i) { + dev->opt[i].size = sizeof (SANE_Word); + dev->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; + } + + x_range.min = SANE_FIX (0); + x_range.max = SANE_FIX (8.5 * MM_PER_INCH); + x_range.quant = 0; + y_range.min = SANE_FIX (0); + y_range.max = SANE_FIX (11.5 * MM_PER_INCH); + y_range.quant = 0; + + /* Number of options. */ + dev->opt[OPT_NUM_OPTS].name = ""; + dev->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; + dev->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; + dev->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; + dev->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; + dev->val[OPT_NUM_OPTS].w = OPT_NUM_OPTIONS; + + /* Mode group */ + dev->opt[OPT_MODE_GROUP].title = SANE_I18N ("Scan mode"); + dev->opt[OPT_MODE_GROUP].desc = ""; /* not valid for a group */ + dev->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; + dev->opt[OPT_MODE_GROUP].cap = 0; + dev->opt[OPT_MODE_GROUP].size = 0; + dev->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; + + /* Scanner supported modes */ + dev->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; + dev->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; + dev->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; + dev->opt[OPT_MODE].type = SANE_TYPE_STRING; + dev->opt[OPT_MODE].size = max_string_size (scan_mode_list); + dev->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; + dev->opt[OPT_MODE].constraint.string_list = scan_mode_list; + dev->val[OPT_MODE].s = (SANE_Char *) strdup (scan_mode_list[0]); + + /* X and Y resolution */ + dev->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; + dev->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; + dev->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; + dev->opt[OPT_RESOLUTION].type = SANE_TYPE_INT; + dev->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; + dev->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST; + dev->opt[OPT_RESOLUTION].constraint.word_list = dpi_list; + dev->val[OPT_RESOLUTION].w = dpi_list[1]; + + /* Geometry group */ + dev->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N ("Geometry"); + dev->opt[OPT_GEOMETRY_GROUP].desc = ""; /* not valid for a group */ + dev->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; + dev->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; + dev->opt[OPT_GEOMETRY_GROUP].size = 0; + dev->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; + + /* Upper left X */ + dev->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; + dev->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; + dev->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; + dev->opt[OPT_TL_X].type = SANE_TYPE_FIXED; + dev->opt[OPT_TL_X].unit = SANE_UNIT_MM; + dev->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; + dev->opt[OPT_TL_X].constraint.range = &x_range; + dev->val[OPT_TL_X].w = x_range.min; + + /* Upper left Y */ + dev->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; + dev->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; + dev->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; + dev->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; + dev->opt[OPT_TL_Y].unit = SANE_UNIT_MM; + dev->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; + dev->opt[OPT_TL_Y].constraint.range = &y_range; + dev->val[OPT_TL_Y].w = y_range.min; + + /* Bottom-right x */ + dev->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; + dev->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; + dev->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; + dev->opt[OPT_BR_X].type = SANE_TYPE_FIXED; + dev->opt[OPT_BR_X].unit = SANE_UNIT_MM; + dev->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; + dev->opt[OPT_BR_X].constraint.range = &x_range; + dev->val[OPT_BR_X].w = x_range.max; + + /* Bottom-right y */ + dev->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; + dev->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; + dev->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; + dev->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; + dev->opt[OPT_BR_Y].unit = SANE_UNIT_MM; + dev->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; + dev->opt[OPT_BR_Y].constraint.range = &y_range; + dev->val[OPT_BR_Y].w = y_range.max; + + dev->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; + dev->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW; + dev->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW; + dev->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL; + dev->val[OPT_PREVIEW].w = 0; + + return SANE_STATUS_GOOD; +} + +const SANE_Option_Descriptor * +sane_get_option_descriptor (SANE_Handle h, SANE_Int opt) +{ + BrotherMFC *dev = h; + if (opt < 0 || opt >= OPT_NUM_OPTIONS) { + return NULL; + } + return dev->opt + opt; +} + +SANE_Status +sane_control_option (SANE_Handle h, SANE_Int opt, SANE_Action act, + void *val, SANE_Word *info) +{ + SANE_Word cap; + BrotherMFC *dev = h; + + if (info) *info = 0; + + if (!val) return SANE_STATUS_INVAL; + + if (opt < 0 || opt >= OPT_NUM_OPTIONS) { + return SANE_STATUS_INVAL; + } + + if (dev->scanning) { + return SANE_STATUS_DEVICE_BUSY; + } + + cap = dev->opt[opt].cap; + if (!SANE_OPTION_IS_ACTIVE (cap)) { + return SANE_STATUS_INVAL; + } + + switch (act) + { + case SANE_ACTION_GET_VALUE: + switch (opt) + { + /* word options */ + case OPT_NUM_OPTS: + case OPT_PREVIEW: + case OPT_RESOLUTION: + case OPT_TL_Y: + case OPT_BR_Y: + case OPT_TL_X: + case OPT_BR_X: + *(SANE_Word *) val = dev->val[opt].w; + return SANE_STATUS_GOOD; + case OPT_MODE: + strcpy (val, dev->val[opt].s); + return SANE_STATUS_GOOD; + default: + return SANE_STATUS_INVAL; + } + break; + case SANE_ACTION_SET_VALUE: + if (!SANE_OPTION_IS_SETTABLE (cap)) { + DBG (DBG_error, "could not set option, not settable\n"); + return SANE_STATUS_INVAL; + } + switch (opt) + { + /* word options */ + case OPT_NUM_OPTS: + case OPT_PREVIEW: + case OPT_RESOLUTION: + case OPT_TL_Y: + case OPT_BR_Y: + case OPT_TL_X: + case OPT_BR_X: + dev->val[opt].w = *(SANE_Word *) val; + if (info) *info |= SANE_INFO_RELOAD_PARAMS; + return SANE_STATUS_GOOD; + case OPT_MODE: + if (strcmp (dev->val[opt].s, val) == 0) + return SANE_STATUS_GOOD; + free (dev->val[opt].s); + dev->val[opt].s = (SANE_Char *) strdup (val); + return SANE_STATUS_GOOD; + default: + return SANE_STATUS_INVAL; + } + break; + default: + break; + } + return SANE_STATUS_UNSUPPORTED; +} + +SANE_Status +sane_get_parameters (SANE_Handle h, SANE_Parameters *parms) +{ + BrotherMFC *dev = h; + char *mode; + int round; + + mode = dev->val[OPT_MODE].s; + + /* Depending on the color depth, pixels and bytes must be aligned. + I'm not sure what the optimal numbers are, but these work for + the MFC 6800 */ + if (strcmp(mode, COLOR_STR)==0) { + dev->colormode = BROTHER_COLOR_MODE_RGB; + round = ~1; + } + else if (strcmp(mode, GRAY_STR)==0) { + dev->colormode = BROTHER_COLOR_MODE_GRAY; + round = ~7; + } + else { + dev->colormode = BROTHER_COLOR_MODE_BW; + round = ~255; + } + + /* for now, preview is the same res as the request */ + if (0 && dev->val[OPT_PREVIEW].w) { /* this code is disabled */ + dev->x_resolution = 100; + dev->y_resolution = 100; + dev->x_tl = 0; + dev->y_tl = 0; + dev->x_br = mmToIlu(SANE_UNFIX(x_range.max)+0.5); + dev->y_br = mmToIlu(SANE_UNFIX(y_range.max)+0.5); + } + else { + dev->x_resolution = dev->val[OPT_RESOLUTION].w; + dev->y_resolution = dev->val[OPT_RESOLUTION].w; + dev->x_tl = mmToIlu (SANE_UNFIX(dev->val[OPT_TL_X].w))+0.5; + dev->y_tl = mmToIlu (SANE_UNFIX(dev->val[OPT_TL_Y].w))+0.5; + dev->x_br = mmToIlu (SANE_UNFIX(dev->val[OPT_BR_X].w))+0.5; + dev->y_br = mmToIlu (SANE_UNFIX(dev->val[OPT_BR_Y].w))+0.5; + } + + /* Now round the X coordinates */ + dev->x_tl &= round; + dev->x_br &= round; + + /* width is the difference, but length is one less; at least + that's the way it is for the MFC 6800 */ + dev->width = dev->x_br - dev->x_tl; + dev->length = dev->y_br - dev->y_tl - 1; + + memset(&dev->params, 0, sizeof(SANE_Parameters)); + + /* set the right parameters for the color mode */ + if (strcmp(mode, COLOR_STR)==0) { + dev->params.format = SANE_FRAME_RGB; + dev->params.lines = dev->length; + dev->params.pixels_per_line = dev->width; + /* 3 bytes per pixel (24-bit color) */ + dev->params.bytes_per_line = dev->params.pixels_per_line * 3; + dev->params.depth = 8; + dev->interleave = 3; + } + else if (strcmp(mode, GRAY_STR)==0) { + dev->params.format = SANE_FRAME_GRAY; + dev->params.lines = dev->length; + dev->params.pixels_per_line = dev->width; + dev->params.bytes_per_line = dev->params.pixels_per_line; + dev->params.depth = 8; + dev->interleave = 1; + } + else { /* BLACK_WHITE_STR */ + dev->params.format = SANE_FRAME_GRAY; + dev->params.lines = dev->length; + dev->params.pixels_per_line = dev->width; + /* 8 pixels per byte, so divide */ + dev->params.bytes_per_line = dev->params.pixels_per_line / 8; + dev->params.depth = 1; + dev->interleave = 1; + } + + dev->params.last_frame = SANE_TRUE; + + if (parms) *parms = dev->params; + + return SANE_STATUS_GOOD; +} + +SANE_Status +sane_start (SANE_Handle h) +{ + BrotherMFC *dev = h; + /* The scan command is sent in the first call to scan_read + in order to ensure that all parameters have been saved + properly. Perhaps this is not necessary, but it seemed + to help for me. - FT */ + dev->startscan = 1; + dev->scanning = 1; + return SANE_STATUS_GOOD; +} + +SANE_Status +send_scan_command(BrotherMFC *dev) +{ + SANE_Status status; + char bx[1024]; + size_t len; + int i, ok; + + /* if we are scanning, then something went wrong and we're being + called twice */ + /* if (dev->scanning) return SANE_STATUS_CANCELLED; */ + + /* sanity checks for resolution */ + ok = 0; + for(i=1; i <= dpi_list[0]; i++) { + if (dev->x_resolution == dpi_list[i]) ok++; + if (dev->y_resolution == dpi_list[i]) ok++; + } + + if (ok != 2) { /* didn't find both resolutions */ + DBG (1, "invalid resolution requested"); + return SANE_STATUS_INVAL; + } + + sprintf(bx, "\x1bX\n" + "R=%d,%d\n" + "M=%s\n" + "C=NONE\n" /* compression */ + "B=50\n" /* brightness */ + "N=50\n" /* contrast */ + "U=OFF\n" /* autofeeder, etc.? */ + "P=OFF\n" + "A=%d,%d,%d,%d\n" + "\x80", + dev->x_resolution, dev->y_resolution, + dev->colormode, + dev->x_tl, dev->y_tl, + dev->x_br, dev->y_br+1 + ); + len = strlen(bx); + status = device_write(dev, (SANE_Byte *)bx, &len); + if (status != SANE_STATUS_GOOD) { + DBG (DBG_error, "cannot write scan command\n"); + return SANE_STATUS_INVAL; + } + + dev->startscan = 0; + dev->scan_lines = 0; /* keep count of scanned lines */ + + /* init the data read buffer */ + dev->readlen = sizeof(dev->readbuf); + dev->readi = 0; + + dev->logfile = fopen("/tmp/sane.raw", "wb"); + + return SANE_STATUS_GOOD; +} + +/* This function is called by sane_read() to see if there's enough + read data to send one or more complete lines to the front end */ +int +process_buffer(BrotherMFC *dev, SANE_Byte *buf, SANE_Int maxlen) +{ + unsigned int rechead, reclen, recnum, len; + unsigned int k, j, i, i2; + unsigned int count , bcount; + unsigned char * start; + + rechead = 3; /* header is status byte, followed by length word */ + reclen = dev->params.pixels_per_line + rechead; /* add rec overhead */ + reclen *= dev->interleave; /* times number of bytes per pixel */ + + /* are there records in the buffer already? */ + if (dev->readi > reclen) { + start = dev->readbuf; + /* now calculate the read record length from the first record */ + count = start[1] + start[2]*256; + reclen = count + rechead; /* add rec overhead */ + reclen *= dev->interleave; + + /* how many complete records? (use integer math) */ + recnum = dev->readi / reclen; + /* do the records fit into the buffer? */ + if (recnum > maxlen / reclen) { + recnum = maxlen / reclen; + } + + /* length of output records (take out headers) */ + len = recnum * dev->params.bytes_per_line; + + /* now process individual scan lines. in full-color, each + line of output is composed of three lines: a line of + red, a line of green and a line of blue. these lines + must be merge into the format sane expects: a red value, + a green value and a blue value in sequence. */ + j = 0; + for(k=0; k < recnum; k++) { + /* read one line */ + if (start[0] & 0x80) break; /* check for error flag */ + count = start[1] + start[2]*256; /* two-byte length */ + bcount = count + rechead; /* record length incl 3-byte header */ + if (count <= 0) break; + /* now process the data line */ + for(i=0; iinterleave) { + /* interleave the color bytes if required */ + for(i2=0; i2interleave; i2++) { + if (j+i2 < (unsigned)maxlen) { + buf[j+i2] = start[i+3 + bcount*i2]; + } + } + } + dev->scan_lines++; + start += bcount * dev->interleave; + } + + count = recnum * reclen; /* number of bytes we have processed */ + /* now copy the end of the buffer to the start */ + memcpy(dev->readbuf, + dev->readbuf + count, + dev->readi - count + 1); + dev->readi -= count; + + return len; + } + + return 0; +} + +/* sane_read() will return data from a buffer that is processed by the + process_buffer() function. It is necessary to keep a separate buffer + for data from the scanner because the scanner will return one color + at a time and thus, may return partial lines (lines where not all three + colors are present). process_buffer() keeps track of the number of + complete lines and then rearranges the colors to suit what sane_read() + must return. +*/ + +SANE_Status +sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp) +{ + unsigned int i = 0; + unsigned char *tmp; + size_t len; + SANE_Status status; + BrotherMFC *dev = h; + + *lenp = 0; + + if (!dev->scanning) { + return SANE_STATUS_EOF; + } + + if (dev->startscan) { + status = send_scan_command(dev); + if (status != SANE_STATUS_GOOD) { + return status; + } + } + + /* Do we have buffered data that we can process now? */ + len = process_buffer(dev, buf, maxlen); + if (len) { + *lenp = len; + return SANE_STATUS_GOOD; + } + + /* point the next byte to fill */ + tmp = dev->readbuf + dev->readi; + /* read only as many bytes as remain in the buffer */ + maxlen = dev->readlen - dev->readi; + + /* attempt to read from the device; repeat 10 times + and wait for data to appear */ + for(i=10; i>0; i--) { + len = maxlen; + status = device_read(dev, tmp, &len); + if (status == SANE_STATUS_GOOD) { + if (len > 0) { + dev->readi += len; + break; + } + sleep(1); + } + else if (status == SANE_STATUS_EOF) { + sleep(1); + } + else { + return status; + } + } + + if (dev->logfile) fwrite(tmp, 1, len, dev->logfile); + + /* process error codes */ + if (len>=1 && tmp[0] & 0x80) + { + unsigned char code; + + code = tmp[0]; + /* process any remaining data in read-ahead buffer */ + *lenp = process_buffer(dev, buf, maxlen); + dev->params.last_frame = 1; + + if (code == 0x80) { /* page end */ + return SANE_STATUS_EOF; + } + if (code == 0x81 || tmp[0] == 0xE3) { /* next page */ + return SANE_STATUS_EOF; + } + if (code == 0x83) { /* cancel ack */ + return SANE_STATUS_CANCELLED; + } + if (code == 0xC2) { /* no document */ + return SANE_STATUS_NO_DOCS; + } + if (code == 0xC3) { /* document jam */ + return SANE_STATUS_JAMMED; + } + if (code == 0xC4) { /* cover open */ + return SANE_STATUS_COVER_OPEN; + } + return SANE_STATUS_IO_ERROR; + } + + /* process remaining data (if any) in read-ahead buffer */ + *lenp = process_buffer(dev, buf, maxlen); + + return SANE_STATUS_GOOD; +} + +SANE_Status +sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking) +{ + BrotherMFC *dev = h; + + if (!dev->scanning) { + return SANE_STATUS_INVAL; + } + else if (non_blocking) { + return SANE_STATUS_GOOD; + } + else { + return SANE_STATUS_UNSUPPORTED; + } +} + +SANE_Status +sane_get_select_fd (SANE_Handle h, SANE_Int *fdp) +{ + h = h; fdp = fdp; + return SANE_STATUS_UNSUPPORTED; +} + +void +sane_cancel (SANE_Handle h) +{ + SANE_Status status; + char * bx = "\x1bR\n\x80"; + size_t len; + BrotherMFC *dev = h; + + len = strlen(bx); + status = device_write(dev, (SANE_Byte *)bx, &len); + if (status != SANE_STATUS_GOOD) { + DBG (DBG_error, "cannot write cancel command\n"); + } + dev->scanning = 0; + dev->startscan = 0; + + if (dev->logfile) fclose(dev->logfile); +} + +void +sane_close (SANE_Handle dev_orig) +{ + int i; + BrotherMFC *dev_tmp; + BrotherMFC *dev = dev_orig; + + DBG (5, "sane_close()\n"); + + if (first_dev == dev) { + first_dev = dev->next; + } + else { + dev_tmp = first_dev; + while (dev_tmp->next && dev_tmp->next != dev) { + dev_tmp = dev_tmp->next; + } + if (dev_tmp->next != NULL) { + dev_tmp->next = dev_tmp->next->next; + } + } + + if (dev->port == BROTHER_USB) { + sanei_usb_close(dev->husb); + } + else if (dev->port == BROTHER_PARPORT) { + /* TODO: close the par port */ + } + + for (i = 1; i < OPT_NUM_OPTIONS; i++) { + if (dev->opt[i].type == SANE_TYPE_STRING && dev->val[i].s) { + free (dev->val[i].s); + } + } + free (dev); + num_devices--; +} + +void +sane_exit (void) +{ + while (first_dev) { + sane_close (first_dev); + } + + if (devlist) { + free (devlist); + devlist = NULL; + } +} diff -Pru sane-backends/backend/brother.conf sane-backends-new/backend/brother.conf --- sane-backends/backend/brother.conf 1970-01-01 01:00:00.000000000 +0100 +++ sane-backends-new/backend/brother.conf 2008-06-04 22:04:52.000000000 +0200 @@ -0,0 +1 @@ +port /dev/usb/lp0 diff -Pru sane-backends/backend/brother.h sane-backends-new/backend/brother.h --- sane-backends/backend/brother.h 1970-01-01 01:00:00.000000000 +0100 +++ sane-backends-new/backend/brother.h 2008-06-04 22:04:52.000000000 +0200 @@ -0,0 +1,97 @@ +#define BROTHER_COLOR_TEXT 1 +#define BROTHER_COLOR_ERRDIF 2 +#define BROTHER_COLOR_GRAY64 4 +#define BROTHER_COLOR_C256 8 +#define BROTHER_COLOR_CGRAY 0x10 +#define BROTHER_COLOR_PAL 0x20 + +#define BROTHER_COLOR_MODE_GRAY "GRAY64" +#define BROTHER_COLOR_MODE_RGB "CGRAY" +#define BROTHER_COLOR_MODE_BW "TEXT" + +#define BROTHER_USB 1 +#define BROTHER_PARPORT 2 + +/* data returned when querying MFC functionality */ +struct brother_info { + unsigned char magic[2]; + unsigned char size; + unsigned char res1; + unsigned char signalType; + unsigned char colorType; + unsigned char ntsc[2]; + unsigned char pal[2]; + unsigned char secam[2]; + unsigned char hwType; + unsigned char hwVersion; + unsigned char dpi; + unsigned char res2; + unsigned char res3[256]; +}; + + +#define BLACK_WHITE_STR SANE_I18N("Black & White") +#define GRAY_STR SANE_I18N("Grayscale") +#define COLOR_STR SANE_I18N("Color") + +#define MM_PER_INCH 25.4 +#define mmToIlu(mm) (((mm) * dev->x_resolution) / MM_PER_INCH) +#define iluToMm(ilu) (((ilu) * MM_PER_INCH) / dev->x_resolution) + +enum BrotherOption +{ + /* Must come first */ + OPT_NUM_OPTS = 0, + OPT_MODE_GROUP, + OPT_MODE, + OPT_RESOLUTION, /* X and Y resolution */ + OPT_GEOMETRY_GROUP, + OPT_TL_X, /* upper left X */ + OPT_TL_Y, /* upper left Y */ + OPT_BR_X, /* bottom right X */ + OPT_BR_Y, /* bottom right Y */ + OPT_PREVIEW, + OPT_NUM_OPTIONS +}; + +struct BrotherMFC { + struct BrotherMFC *next; + + SANE_Device sane; + + int scanning; + int startscan; + int port; + + int x_resolution; + int y_resolution; + int x_tl; + int y_tl; + int x_br; + int y_br; + int width; + int length; + unsigned int interleave; + const char *colormode; + FILE *logfile; + + unsigned char readbuf[32767]; + unsigned int readi; + unsigned int readlen; + + int scan_lines; + + struct brother_info devcap; + + char * devicename; + + /*struct usb_dev_handle * usb;*/ + SANE_Int husb; + + SANE_Parameters params; + SANE_Option_Descriptor opt[OPT_NUM_OPTIONS]; + Option_Value val[OPT_NUM_OPTIONS]; +}; + +typedef struct BrotherMFC BrotherMFC; +