1
0
mirror of https://github.com/pdewacht/brlaser synced 2025-04-20 10:06:44 +02:00

Compare commits

..

No commits in common. "master" and "v3" have entirely different histories.
master ... v3

26 changed files with 738 additions and 756 deletions

View File

@ -1,39 +0,0 @@
name: build
on: [ push, pull_request ]
jobs:
linux:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
compiler: [ clang++, gcc++ ]
steps:
- name: Add repository
run: sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
- name: Install packages
run: sudo apt install libcups2-dev
- uses: actions/checkout@v3
- name: Configure
run: cmake .
- name: Make
run: make
env:
CXX: ${{ matrix.compiler }}
- name: Run tests
run: make check
macos:
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
compiler: [ clang++, gcc++ ]
steps:
- uses: actions/checkout@v3
- name: Configure
run: cmake .
- name: Make
run: make
env:
CXX: ${{ matrix.compiler }}
- name: Run tests
run: make check

28
.gitignore vendored
View File

@ -1,2 +1,26 @@
*~
build/
#
# Autotools
#
/Makefile
/Makefile.in
/aclocal.m4
/autom4te.cache
/build-aux
/config.*
/configure
/stamp-*
.deps/
.dirstamp
*.log
*.trs
#
# Binaries
#
/src/rastertobrlaser
/src/brdecode
/test/test_lest
/test/test_line
/test/test_block
/brlaser.drv
*.o

View File

@ -1,140 +0,0 @@
cmake_minimum_required(VERSION 3.1)
project(brlaser CXX)
set(BRLASER_VERSION "6")
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "No build type selected, default to RelWithDebInfo")
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Build type (default RelWithDebInfo)" FORCE)
endif()
include(CMakePushCheckState)
include(CheckCXXCompilerFlag)
include(CheckIncludeFileCXX)
## Enable assertions for all builds
## (cmake by default sets NDEBUG for release builds)
foreach(var
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_MINSIZEREL)
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " "${var}" "${${var}}")
endforeach()
## Configure the compiler
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
macro(extra_cxx_compiler_flag FLAG)
string(REGEX REPLACE "[^A-Za-z_0-9]" "_" SFLAG ${FLAG})
check_cxx_compiler_flag(${FLAG} COMPILER_SUPPORT_${SFLAG})
if(COMPILER_SUPPORT_${SFLAG})
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} ${FLAG}")
endif()
endmacro(extra_cxx_compiler_flag)
# Compiler warnings
extra_cxx_compiler_flag("-Wall")
extra_cxx_compiler_flag("-Wno-missing-braces")
extra_cxx_compiler_flag("-Wdate-time")
# Some hardening flags
extra_cxx_compiler_flag("-fstack-protector-strong")
extra_cxx_compiler_flag("-Wformat")
extra_cxx_compiler_flag("-Wformat -Werror=format-security")
extra_cxx_compiler_flag("-D_FORTIFY_SOURCE=2")
# Enable the supported flags, but give priority to CXXFLAGS env var
set(CMAKE_CXX_FLAGS "${EXTRA_CXX_FLAGS} ${CMAKE_CXX_FLAGS}")
## Configure CUPS
find_program(CUPS_CONFIG NAMES cups-config)
if(NOT CUPS_CONFIG)
message(FATAL_ERROR "cups-config command not found. Are the CUPS development packages installed?")
endif()
if(NOT CUPS_DATA_DIR)
execute_process(
COMMAND "${CUPS_CONFIG}" --datadir
OUTPUT_VARIABLE CUPS_DATA_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
if(NOT CUPS_SERVER_BIN)
execute_process(
COMMAND "${CUPS_CONFIG}" --serverbin
OUTPUT_VARIABLE CUPS_SERVER_BIN
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
if(NOT CUPS_CFLAGS)
execute_process(
COMMAND "${CUPS_CONFIG}" --cflags
OUTPUT_VARIABLE CUPS_CFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
if(NOT CUPS_LDFLAGS)
execute_process(
COMMAND "${CUPS_CONFIG}" --ldflags
OUTPUT_VARIABLE CUPS_LDFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
if(NOT CUPS_LIBS)
execute_process(
COMMAND "${CUPS_CONFIG}" --image --libs
OUTPUT_VARIABLE CUPS_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${CUPS_CFLAGS}")
check_include_file_cxx(cups/raster.h HAVE_CUPS_RASTER_H)
cmake_pop_check_state()
if(NOT HAVE_CUPS_RASTER_H)
message(SEND_ERROR "<cups/raster.h> header not found. Are the CUPS development packages installed?")
endif()
## Build instructions
configure_file(
"${PROJECT_SOURCE_DIR}/brlaser.drv.in"
"${PROJECT_BINARY_DIR}/brlaser.drv")
configure_file(
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h")
include_directories("${PROJECT_BINARY_DIR}")
add_executable(rastertobrlaser src/main.cc src/job.cc src/line.cc src/debug.cc)
target_compile_options(rastertobrlaser PRIVATE ${CUPS_CFLAGS})
target_link_libraries(rastertobrlaser ${CUPS_LIBS})
target_link_libraries(rastertobrlaser ${CUPS_LDFLAGS})
add_executable(brdecode EXCLUDE_FROM_ALL src/brdecode.cc)
add_executable(test_lest test/test_lest.cc)
add_executable(test_line test/test_line.cc src/line.cc)
add_executable(test_block test/test_block.cc)
add_executable(test_job test/test_job.cc src/job.cc src/line.cc)
enable_testing()
add_test(test_lest test_lest)
add_test(test_line test_line)
add_test(test_block test_block)
add_test(test_job test_job)
# Autotools-style "make check" command
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
add_dependencies(check test_lest test_line test_block test_job)
# Installation
install(
TARGETS rastertobrlaser
DESTINATION "${CUPS_SERVER_BIN}/filter")
install(
FILES "${PROJECT_BINARY_DIR}/brlaser.drv"
DESTINATION "${CUPS_DATA_DIR}/drv")

View File

@ -1,17 +1,3 @@
brlaser v6 (2019-09-22)
Added support for some more Brother HL-series printers. These printers
had glitched output in earlier releases.
brlaser v5 (2019-05-18)
Fixed problems with Brother HL-series printers in 600 dpi mode. Thanks
to Onno Kortmann for the fix.
Added several printers.
brlaser v4 (2018-02-25)
Added several printers.
Merged duplex printing support from @xc-racer99. Enabled for DCP-7065DN.
Switched to a CMake build system.
brlaser v3 (2014-07-07)
Added DCP-7065DN description.

50
Makefile.am Normal file
View File

@ -0,0 +1,50 @@
ACLOCAL_AMFLAGS = -I m4
AM_CXXFLAGS = $(CUPS_CFLAGS)
TESTS = $(check_PROGRAMS)
dist_doc_DATA = README.md
drv_DATA = brlaser.drv
drvdir = $(CUPS_DATADIR)/drv
filter_PROGRAMS = src/rastertobrlaser
filterdir = $(CUPS_SERVERBIN)/filter
noinst_PROGRAMS = src/brdecode
check_PROGRAMS = \
test/test_lest \
test/test_line \
test/test_block
src_rastertobrlaser_SOURCES = \
src/main.cc \
src/debug.h \
src/debug.cc \
src/job.h \
src/job.cc \
src/block.h \
src/line.h \
src/line.cc
src_rastertobrlaser_LDADD = $(CUPS_LIBS)
src_brdecode_SOURCES = \
src/brdecode.cc
test_test_lest_SOURCES = \
test/test_lest.cc \
test/lest.hpp
test_test_line_SOURCES = \
test/test_line.cc \
src/line.h \
src/line.cc \
test/lest.hpp
test_test_block_SOURCES = \
test/test_block.cc \
src/block.h \
test/tempfile.h \
test/lest.hpp

View File

@ -1,98 +1,15 @@
brlaser: Brother laser printer driver
=====================================
Driver for (some) Brother laster printers
=========================================
brlaser is a CUPS driver for Brother laser printers.
Most Brother printers support a standard printer language such as PCL
or PostScript, but not all do. If you have a monochrome Brother laser
printer (or multi-function device) and the other open source drivers
don't work, this one might help.
Although most Brother printers support a standard printer language
such as PCL or PostScript, not all do. If you have a monochrome
Brother laser printer (or multi-function device) and the other open
source drivers don't work, this one might help.
It is known to support these printers:
This driver has been reported to work with these printers:
* Brother DCP-1510 series
* Brother DCP-1600 series
* Brother DCP-7030
* Brother DCP-7040
* Brother DCP-7055
* Brother DCP-7055W
* Brother DCP-7060D
* Brother DCP-7065DN
* Brother DCP-7080
* Brother DCP-L2500D series
* Brother DCP-L2520D series
* Brother DCP-L2520DW series
* Brother DCP-L2540DW series
* Brother HL-1110 series
* Brother HL-1200 series
* Brother HL-2030 series
* Brother HL-2140 series
* Brother HL-2220 series
* Brother HL-2270DW series
* Brother HL-5030 series
* Brother HL-L2300D series
* Brother HL-L2320D series
* Brother HL-L2340D series
* Brother HL-L2360D series
* Brother HL-L2375DW series
* Brother HL-L2390DW
* Brother MFC-1910W
* Brother MFC-7240
* Brother MFC-7360N
* Brother MFC-7365DN
* Brother MFC-7420
* Brother MFC-7460DN
* Brother MFC-7840W
* Brother MFC-L2710DW series
* Lenovo M7605D
Other printers
--------------
If your printer isn't included in the list above, just try selecting
any entry marked 'brlaser' and see if it works.
If it does, please create a new issue here in Github and include the
output of this command:
sudo lpinfo --include-schemes usb -l -v
Then I'll be able to add a proper entry for your printer.
Installation
------------
Some operating systems already ship this driver. This is the case for
at least Debian, Gentoo, Ubuntu, Raspbian, openSUSE, NixOS, Arch Linux
and Guix.
Look for a package named `printer-driver-brlaser`.
You'll also need Ghostscript, in case that's not installed
automatically.
Once brlaser is installed, you can add your printer using the usual
CUPS interface.
Building from source
--------------------
To compile brlaser you'll need CMake and the CUPS development packages
(libcups2-dev, libcupsimage2-dev or similar).
Get the code by cloning the git repo <!-- or downloading the [latest
release] -->. Compile and install with these commands:
cmake .
make
sudo make install
It might be needed to restart CUPS after this.
[latest release]: https://github.com/pdewacht/brlaser/releases/latest
Copyright
---------

15
autogen.sh Executable file
View File

@ -0,0 +1,15 @@
#! /bin/sh
srcdir=`dirname "$0"`
test -z "$srcdir" && srcdir=.
ORIGDIR=`pwd`
cd "$srcdir"
autoreconf --force -v --install || exit 1
cd "$ORIGDIR" || exit $?
if test -z "$NOCONFIGURE"; then
exec "$srcdir"/configure "$@"
fi

View File

@ -15,8 +15,6 @@
// You should have received a copy of the GNU General Public License
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
#define USING "using @CMAKE_PROJECT_NAME@ v@BRLASER_VERSION@"
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>
@ -26,7 +24,7 @@ Font *
// Manufacturer and driver version.
Manufacturer "Brother"
Version "@BRLASER_VERSION@"
Version @VERSION@
// Each filter provided by the driver...
Filter application/vnd.cups-raster 33 rastertobrlaser
@ -35,9 +33,7 @@ Filter application/vnd.cups-raster 33 rastertobrlaser
// The 1200dpi mode is weird: we need to send 1200x1200dpi raster
// data, but Brother only advertises 1200x600dpi. I wonder what
// is going on there.
// The 300dpi mode is reportedly not supported on all printers, so
// it's listed in individual printer blocks where we believe it works.
// Resolution k 1 0 0 0 "300dpi/300 DPI"
Resolution k 1 0 0 0 "300dpi/300 DPI"
*Resolution k 1 0 0 0 "600dpi/600 DPI"
Resolution k 1 0 0 0 "1200dpi/1200HQ"
@ -50,7 +46,7 @@ MediaSize B5
MediaSize B6
MediaSize EnvC5
MediaSize EnvMonarch
MediaSize EnvDL
MediaSize EnvPRC5
MediaSize Executive
MediaSize Legal
MediaSize Letter
@ -79,266 +75,16 @@ Option "brlaserEconomode/Toner save mode" Boolean AnySetup 10
Choice True/On "<</cupsInteger10 1>>setpagedevice"
{
ModelName "DCP-1510"
Attribute "NickName" "" "Brother DCP-1510 series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,XL2HB;MDL:DCP-1510 series;CLS:PRINTER;CID:Brother Laser Type1;"
Resolution k 1 0 0 0 "300dpi/300 DPI"
PCFileName "br1510.ppd"
}
{
ModelName "DCP-1600 series"
Attribute "NickName" "" "Brother DCP-1600 series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,XL2HB;MDL:DCP-1600 series;CLS:PRINTER;CID:Brother Laser Type1;"
PCFileName "br1600.ppd"
}
{
ModelName "DCP-7030"
Attribute "NickName" "" "Brother DCP-7030, $USING"
Attribute "NickName" "" "Brother DCP-7030, using @PACKAGE@ v@VERSION@"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7030;CLS:PRINTER;"
Resolution k 1 0 0 0 "300dpi/300 DPI"
PCFileName "br7030.ppd"
}
{
ModelName "DCP-7040"
Attribute "NickName" "" "Brother DCP-7040, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7040;CLS:PRINTER;"
Resolution k 1 0 0 0 "300dpi/300 DPI"
PCFileName "br7040.ppd"
}
{
ModelName "DCP-7055"
Attribute "NickName" "" "Brother DCP-7055, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7055;CLS:PRINTER;CID:Brother Laser Type1;"
Resolution k 1 0 0 0 "300dpi/300 DPI"
PCFileName "br7055.ppd"
}
{
ModelName "DCP-7055W"
Attribute "NickName" "" "Brother DCP-7055W, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7055W;CLS:PRINTER;CID:Brother Laser Type1;"
Resolution k 1 0 0 0 "300dpi/300 DPI"
PCFileName "br7055w.ppd"
}
{
ModelName "DCP-7060D"
Attribute "NickName" "" "Brother DCP-7060D, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7060D;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "br7060d.ppd"
}
{
ModelName "DCP-7065DN"
Attribute "NickName" "" "Brother DCP-7065DN, $USING"
Attribute "NickName" "" "Brother DCP-7065DN, using @PACKAGE@ v@VERSION@"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7065DN;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "br7065dn.ppd"
}
{
ModelName "DCP-7080"
Attribute "NickName" "" "Brother DCP-7080, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7080;CLS:PRINTER;CID:Brother Laser Type1;"
PCFileName "br7080.ppd"
}
{
ModelName "DCP-7080D"
Attribute "NickName" "" "Brother DCP-7080D, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7080D;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "br7080d.ppd"
}
{
ModelName "DCP-L2500D"
Attribute "NickName" "" "Brother DCP-L2500D series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-L2500D series;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "brl2500d.ppd"
}
{
ModelName "DCP-L2520D"
Attribute "NickName" "" "Brother DCP-L2520D series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-L2520D series;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "brl2520d.ppd"
}
{
ModelName "DCP-L2520DW"
Attribute "NickName" "" "Brother DCP-L2520DW series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-L2520DW series;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "brl2520dw.ppd"
}
{
ModelName "DCP-L2540DW"
Attribute "NickName" "" "Brother DCP-L2540DW series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-L2540DW series;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "brl2540.ppd"
}
{
ModelName "HL-1110"
Attribute "NickName" "" "Brother HL-1110 series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-1110 series;CLS:PRINTER;CID:Brother Laser Type3;"
Resolution k 1 0 0 0 "300dpi/300 DPI"
PCFileName "br1110.ppd"
}
{
ModelName "HL-1200"
Attribute "NickName" "" "Brother HL-1200 series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-1200 series;CLS:PRINTER;CID:Brother Laser Type3;"
PCFileName "br1200.ppd"
}
{
ModelName "HL-2030 series"
Attribute "NickName" "" "Brother HL-2030 series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-2030 series;CLS:PRINTER;"
PCFileName "br2030.ppd"
}
{
ModelName "HL-2140 series"
Attribute "NickName" "" "Brother HL-2140 series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-2140 series;CLS:PRINTER;"
PCFileName "br2140.ppd"
}
{
ModelName "HL-2220 series"
Attribute "NickName" "" "Brother HL-2220 series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-2220 series;CLS:PRINTER;"
PCFileName "br2220.ppd"
}
{
ModelName "HL-2270DW series"
Attribute "NickName" "" "Brother HL-2270DW series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,PCL,PCLXL;MDL:HL-2270DW series;CLS:PRINTER;CID:Brother Laser Type1;"
Resolution k 1 0 0 0 "300dpi/300 DPI"
Duplex rotated
PCFileName "br2270dw.ppd"
}
{
ModelName "HL-5030 series"
Attribute "NickName" "" "Brother HL-5030 series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,PCL;MDL:HL-5030 series;CLS:PRINTER;"
PCFileName "br5030.ppd"
}
{
ModelName "HL-L2300D"
Attribute "NickName" "" "Brother HL-L2300D series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-L2300D series;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "brl2300d.ppd"
}
{
ModelName "HL-L2320D"
Attribute "NickName" "" "Brother HL-L2320D series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-L2320D series;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "brl2320d.ppd"
}
{
ModelName "HL-L2340D"
Attribute "NickName" "" "Brother HL-L2340D series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP,URF;MDL:HL-L2340D series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ4,RS300-600,V1.3,DM1;"
Duplex rotated
PCFileName "brl2340d.ppd"
}
{
ModelName "HL-L2360D"
Attribute "NickName" "" "Brother HL-L2360D series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,PCL,PCLXL,URF;MDL:HL-L2360D series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ4,RS300-600,V1.3,DM1;"
Duplex rotated
PCFileName "brl2360d.ppd"
}
{
ModelName "HL-L2375DW"
Attribute "NickName" "" "Brother HL-L2375DW series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,PCL,PCLXL,URF;MDL:HL-L2375DW series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ3-4-5,RS300-600-1200,V1.4,DM1;"
Duplex rotated
PCFileName "brl2375w.ppd"
}
{
ModelName "HL-L2390DW"
Attribute "NickName" "" "Brother HL-L2390DW, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP,URF;MDL:HL-L2390DW;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ3-4-5,RS300-600-1200,V1.4,DM1;"
Duplex rotated
PCFileName "brl2390w.ppd"
}
{
ModelName "MFC-1910W"
Attribute "NickName" "" "Brother MFC-1910W, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;MFG:Brother;CMD:PJL,HBP;MDL:MFC-1910W series;CLS:PRINTER;CID:Brother Laser Type1;"
PCFileName "br1910w.ppd"
}
{
ModelName "MFC-7240"
Attribute "NickName" "" "Brother MFC-7240, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;MFG:Brother;CMD:PJL,HBP;MDL:MFC-7240;CLS:PRINTER;CID:Brother Laser Type1;"
PCFileName "br7240.ppd"
}
{
ModelName "MFC-7360N"
Attribute "NickName" "" "Brother MFC-7360N, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:MFC-7360N;CLS:PRINTER;CID:Brother Laser Type1;"
PCFileName "br7360n.ppd"
}
{
ModelName "MFC-7365DN"
Attribute "NickName" "" "Brother MFC-7365DN, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:MFC-7365DN;CLS:PRINTER;CID:Brother Laser Type1;"
Resolution k 1 0 0 0 "300dpi/300 DPI"
Duplex rotated
PCFileName "br7365dn.ppd"
}
{
ModelName "MFC-7420"
Attribute "NickName" "" "Brother Brother MFC-7420, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:MFC-7420;CLS:PRINTER;"
PCFileName "br7420.ppd"
}
{
ModelName "MFC-7460DN"
Attribute "NickName" "" "Brother MFC-7460DN, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:MFC-7460DN;CLS:PRINTER;CID:Brother Laser Type1;"
Duplex rotated
PCFileName "br7460dn.ppd"
}
{
ModelName "MFC-L2710DW series"
Attribute "NickName" "" "Brother MFC-L2710DW series, $USING"
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP,URF;MDL:MFC-L2710DW series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ3-4-5,RS300-600-1200,V1.4,DM1;"
Duplex rotated
PCFileName "brl2710.ppd"
}

View File

@ -1,2 +0,0 @@
#define PACKAGE "@CMAKE_PROJECT_NAME@"
#define VERSION "@BRLASER_VERSION@"

57
configure.ac Normal file
View File

@ -0,0 +1,57 @@
# This file is part of the brlaser printer driver.
#
# Copyright 2013 Peter De Wachter
#
# brlaser 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.
#
# brlaser 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 brlaser. If not, see <http:#www.gnu.org/licenses/>.
AC_PREREQ(2.68)
AC_INIT([brlaser], [3], [pdewacht@gmail.com], [brlaser],
[https://github.com/pdewacht/brlaser])
AC_CONFIG_SRCDIR([src/line.cc])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AC_LANG([C++])
AM_INIT_AUTOMAKE([1.11.1 foreign subdir-objects dist-xz -Wall -Werror])
AM_MAINTAINER_MODE([enable])
AM_SILENT_RULES([yes])
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX_11
AX_CXXFLAGS_WARN_ALL
dnl Use cups-config to detect the CUPS configuration.
AC_PATH_PROG(CUPS_CONFIG, cups-config)
AS_IF([test -z "$CUPS_CONFIG"],
[AC_MSG_ERROR(["cups-config" command not found. Please install the CUPS development package.])])
CUPS_CFLAGS=`"$CUPS_CONFIG" --cflags`
CUPS_LIBS=`"$CUPS_CONFIG" --image --libs`
CUPS_SERVERBIN=`"$CUPS_CONFIG" --serverbin`
CUPS_DATADIR=`"$CUPS_CONFIG" --datadir`
AC_SUBST(CUPS_CFLAGS)
AC_SUBST(CUPS_LIBS)
AC_SUBST(CUPS_SERVERBIN)
AC_SUBST(CUPS_DATADIR)
dnl 'cups-config --libs' lists a lot of libs we don't need/want,
dnl try to figure out whether the linker knows about --as-needed.
AC_ARG_ENABLE([as-needed],
AC_HELP_STRING([--disable-as-needed], [disable overlinking protection]))
AS_IF([test "x$enable_as_needed" != "xno"],
[AX_APPEND_LINK_FLAGS([-Wl,--as-needed])])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile brlaser.drv])
AC_OUTPUT

69
m4/ax_append_flag.m4 Normal file
View File

@ -0,0 +1,69 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
#
# DESCRIPTION
#
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
# added in between.
#
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
# FLAG.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# 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 3 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 <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 2
AC_DEFUN([AX_APPEND_FLAG],
[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl
AS_VAR_SET_IF(FLAGS,
[case " AS_VAR_GET(FLAGS) " in
*" $1 "*)
AC_RUN_LOG([: FLAGS already contains $1])
;;
*)
AC_RUN_LOG([: FLAGS="$FLAGS $1"])
AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"])
;;
esac],
[AS_VAR_SET(FLAGS,["$1"])])
AS_VAR_POPDEF([FLAGS])dnl
])dnl AX_APPEND_FLAG

View File

@ -0,0 +1,61 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
#
# DESCRIPTION
#
# For every FLAG1, FLAG2 it is checked whether the linker works with the
# flag. If it does, the flag is added FLAGS-VARIABLE
#
# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is
# used. During the check the flag is always added to the linker's flags.
#
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
# when the check is done. The check is thus made with the flags: "LDFLAGS
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
# issue an error when a bad flag is given.
#
# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG.
# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS.
#
# LICENSE
#
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# 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 3 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 <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 2
AC_DEFUN([AX_APPEND_LINK_FLAGS],
[for flag in $1; do
AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3])
done
])dnl AX_APPEND_LINK_FLAGS

122
m4/ax_cflags_warn_all.m4 Normal file
View File

@ -0,0 +1,122 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
#
# DESCRIPTION
#
# Try to find a compiler option that enables most reasonable warnings.
#
# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
#
# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
# Intel compilers. For a given compiler, the Fortran flags are much more
# experimental than their C equivalents.
#
# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
# - $2 add-value-if-not-found : nothing
# - $3 action-if-found : add value to shellvariable
# - $4 action-if-not-found : nothing
#
# NOTE: These macros depend on AX_APPEND_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
#
# 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 3 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 <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 14
AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
VAR,[VAR="no, unknown"
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-warn all % -warn all" dnl Intel
"-pedantic % -Wall" dnl GCC
"-xstrconst % -v" dnl Solaris C
"-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
"-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
"-ansi -ansiE % -fullwarn" dnl IRIX
"+ESlit % +w1" dnl HP-UX C
"-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
"-h conform % -h msglevel 2" dnl Cray C (Unicos)
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
])
AS_VAR_POPDEF([FLAGS])dnl
AC_REQUIRE([AX_APPEND_FLAG])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
*) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
])dnl AX_FLAGS_WARN_ALL
dnl implementation tactics:
dnl the for-argument contains a list of options. The first part of
dnl these does only exist to detect the compiler - usually it is
dnl a global option to enable -ansi or -extrawarnings. All other
dnl compilers will fail about it. That was needed since a lot of
dnl compilers will give false positives for some option-syntax
dnl like -Woption or -Xoption as they think of it is a pass-through
dnl to later compile stages or something. The "%" is used as a
dnl delimiter. A non-option comment can be given after "%%" marks
dnl which will be shown but not added to the respective C/CXXFLAGS.
AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
AC_LANG_PUSH([C])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([C])
])
AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
AC_LANG_PUSH([C++])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([C++])
])
AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
AC_LANG_PUSH([Fortran])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([Fortran])
])

73
m4/ax_check_link_flag.m4 Normal file
View File

@ -0,0 +1,73 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the linker or gives an error.
# (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
# when the check is done. The check is thus made with the flags: "LDFLAGS
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
# issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_LINK_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# 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 3 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 <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 3
AC_DEFUN([AX_CHECK_LINK_FLAG],
[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
ax_check_save_flags=$LDFLAGS
LDFLAGS="$LDFLAGS $4 $1"
AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
LDFLAGS=$ax_check_save_flags])
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_LINK_FLAGS

View File

@ -0,0 +1,133 @@
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++11
# standard; if necessary, add switches to CXXFLAGS to enable support.
#
# The first argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The second argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline C++11 support is required and that the macro
# should error out if no mode with that support is found. If specified
# 'optional', then configuration proceeds regardless, after defining
# HAVE_CXX11 if and only if a supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 3
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);
auto d = a;
])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
m4_if([$1], [], [],
[$1], [ext], [],
[$1], [noext], [],
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
AC_LANG_PUSH([C++])dnl
ac_success=no
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
ax_cv_cxx_compile_cxx11,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[ax_cv_cxx_compile_cxx11=yes],
[ax_cv_cxx_compile_cxx11=no])])
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
ac_success=yes
fi
m4_if([$1], [noext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=gnu++11 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
m4_if([$1], [ext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=c++11 -std=c++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx11_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
fi
else
if test x$ac_success = xno; then
HAVE_CXX11=0
AC_MSG_NOTICE([No compiler with C++11 support was found])
else
HAVE_CXX11=1
AC_DEFINE(HAVE_CXX11,1,
[define if the compiler supports basic C++11 syntax])
fi
AC_SUBST(HAVE_CXX11)
fi
])

View File

@ -27,23 +27,20 @@ class block {
block(): line_bytes_(0) {
}
bool empty() const {
return line_bytes_ == 0;
}
void add_line(std::vector<uint8_t> &&line) {
assert(!line.empty());
assert(line_fits(line.size()));
line_bytes_ += line.size();
lines_.emplace_back(line);
lines_.push_back(line);
}
bool line_fits(unsigned size) {
return line_bytes_ + size < max_block_size_;
return lines_.size() != max_lines_per_block_
&& line_bytes_ + size < max_block_size_;
}
void flush(FILE *f) {
if (!empty()) {
if (line_bytes_) {
fprintf(f, "%dw%c%c",
line_bytes_ + 2, 0,
static_cast<int>(lines_.size()));
@ -57,6 +54,7 @@ class block {
private:
static const unsigned max_block_size_ = 16350;
static const unsigned max_lines_per_block_ = 128;
std::vector<std::vector<uint8_t>> lines_;
int line_bytes_;

View File

@ -21,7 +21,6 @@
#include <algorithm>
#include <exception>
#include <vector>
#include <string>
namespace {

View File

@ -15,7 +15,6 @@
// You should have received a copy of the GNU General Public License
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
#include "config.h"
#include "debug.h"
#include <iostream>
#include <typeinfo>
@ -24,12 +23,12 @@ namespace {
template <typename T>
void dump(const char *name, const T &value) {
std::cerr << "DEBUG: " PACKAGE ": page header: " << name << " = " << value << '\n';
std::cerr << "DEBUG: page header: " << name << " = " << value << '\n';
}
template <typename T, int N>
void dump(const char *name, const T (&value)[N]) {
std::cerr << "DEBUG: " PACKAGE ": page header: " << name << " =";
std::cerr << "DEBUG: page header: " << name << " =";
for (int i = 0; i < N; ++i) {
std::cerr << ' ' << value[i];
}
@ -37,12 +36,12 @@ void dump(const char *name, const T (&value)[N]) {
}
void dump(const char *name, const char *value) {
std::cerr << "DEBUG: " PACKAGE ": page header: " << name << " = \"" << value << "\"\n";
std::cerr << "DEBUG: page header: " << name << " = \"" << value << "\"\n";
}
template <int N, int M>
void dump(const char *name, const char (&value)[N][M]) {
std::cerr << "DEBUG: " PACKAGE ": page header: " << name << " =";
std::cerr << "DEBUG: page header: " << name << " =";
for (int i = 0; i < N; ++i) {
std::cerr << " \"" << value[i] << '"';
}

View File

@ -26,18 +26,17 @@
job::job(FILE *out, const std::string &job_name)
: out_(out),
job_name_(job_name),
page_params_(),
pages_(0) {
page_params_() {
// Delete dubious characters from job name
std::replace_if(job_name_.begin(), job_name_.end(), [](char c) {
return c < 32 || c >= 127 || c == '"' || c == '\\';
}, ' ');
begin_job();
}
job::~job() {
if (pages_ != 0) {
end_job();
}
}
void job::begin_job() {
@ -74,24 +73,13 @@ void job::write_page_header() {
fprintf(out_, "@PJL SET PAGEPROTECT = AUTO\n");
fprintf(out_, "@PJL SET ORIENTATION = PORTRAIT\n");
fprintf(out_, "@PJL ENTER LANGUAGE = PCL\n");
fputs("\033E", out_);
fprintf(out_, "\033&l%dX", std::max(1, page_params_.num_copies));
if (page_params_.duplex) {
fputs("\033&l2S", out_);
}
}
void job::encode_page(const page_params &page_params,
int num_copies,
int lines,
int linesize,
nextline_fn nextline) {
if (pages_ == 0) {
begin_job();
}
++pages_;
if (!(page_params_ == page_params)) {
page_params_ = page_params;
write_page_header();
@ -101,28 +89,20 @@ void job::encode_page(const page_params &page_params,
std::vector<uint8_t> reference(linesize);
block block;
if (!nextline(line)) {
if (!nextline(line.data())) {
return;
}
block.add_line(encode_line(line));
std::swap(line, reference);
fputs("\033E", out_);
fprintf(out_, "\033&l%dX", std::max(1, num_copies));
fputs("\033*b1030m", out_);
// XXX brother driver uses 128 lines per band
const int lines_per_band = 64;
for (int i = 1; i < lines && nextline(line); ++i) {
std::vector<uint8_t> encoded;
if (i % lines_per_band == 0) {
block.flush(out_);
encoded = encode_line(line);
} else {
encoded = encode_line(line, reference);
for (int i = 1; i < lines && nextline(line.data()); ++i) {
std::vector<uint8_t> encoded = encode_line(line, reference);
if (!block.line_fits(encoded.size())) {
block.flush(out_);
encoded = encode_line(line);
}
}
block.add_line(std::move(encoded));
std::swap(line, reference);

View File

@ -21,21 +21,16 @@
#include <stdint.h>
#include <stdio.h>
#include <string>
#include <vector>
struct page_params {
int num_copies;
int resolution;
bool duplex;
bool economode;
std::string sourcetray;
std::string mediatype;
std::string papersize;
bool operator==(const page_params &o) const {
return num_copies == o.num_copies
&& resolution == o.resolution
&& duplex == o.duplex
return resolution == o.resolution
&& economode == o.economode
&& sourcetray == o.sourcetray
&& mediatype == o.mediatype
@ -45,20 +40,17 @@ struct page_params {
class job {
public:
typedef bool (*nextline_fn)(std::vector<uint8_t> &buf);
typedef bool (*nextline_fn)(uint8_t *buf);
explicit job(FILE *out, const std::string &job_name);
~job();
void encode_page(const page_params &params,
int num_copies,
int lines,
int linesize,
nextline_fn nextline);
int pages() const {
return pages_;
}
private:
void begin_job();
void end_job();
@ -67,7 +59,6 @@ class job {
FILE *out_;
std::string job_name_;
page_params page_params_;
int pages_;
};
#endif // JOB_H

View File

@ -145,12 +145,10 @@ vector<uint8_t> encode_line(const vector<uint8_t> &line,
int num_edits = 0;
auto line_it = line.begin();
auto line_end_it =
std::mismatch(line.rbegin(), line.rend(), reference.rbegin()).first.base();
auto ref_it = reference.begin();
while (1) {
int offset = skip_to_next_mismatch(&line_it, line_end_it, &ref_it);
if (line_it == line_end_it) {
int offset = skip_to_next_mismatch(&line_it, line.end(), &ref_it);
if (line_it == line.end()) {
// No more differences, we're done.
break;
}
@ -158,17 +156,17 @@ vector<uint8_t> encode_line(const vector<uint8_t> &line,
if (++num_edits == max_edits) {
// We've run out of edits. Just output the rest of the line in a big
// substitute command.
write_substitute(offset, line_it, line_end_it, &output);
write_substitute(offset, line_it, line.end(), &output);
break;
}
int s = substitute_length(line_it, line_end_it, ref_it);
int s = substitute_length(line_it, line.end(), ref_it);
if (s > 0) {
write_substitute(offset, line_it, std::next(line_it, s), &output);
line_it += s;
ref_it += s;
} else {
int r = repeat_length(line_it, line_end_it);
int r = repeat_length(line_it, line.end());
assert(r >= 2);
write_repeat(offset, r, *line_it, &output);
line_it += r;

View File

@ -17,6 +17,8 @@
#include <stdio.h>
#include <signal.h>
#include <locale.h>
#include <iconv.h>
#include <unistd.h>
#include <fcntl.h>
#include <cups/raster.h>
@ -29,64 +31,64 @@
#include "job.h"
#include "debug.h"
#ifndef O_BINARY
#define O_BINARY 0
#endif
namespace {
cups_raster_t *ras;
volatile sig_atomic_t interrupted = 0;
void sigterm_handler(int sig) {
interrupted = 1;
}
bool next_line(std::vector<uint8_t> &buf) {
cups_raster_t *ras;
cups_page_header2_t header;
bool next_line(uint8_t *buf) {
if (interrupted) {
return false;
}
return cupsRasterReadPixels(ras, buf.data(), buf.size()) == buf.size();
unsigned bytes = header.cupsBytesPerLine;
return cupsRasterReadPixels(ras, buf, bytes) == bytes;
}
// POSIX says the second argument of iconv has type 'char **', but
// some systems have 'const char **'. This class is used to work
// around this incompatibility.
class sloppy_ptr {
public:
explicit sloppy_ptr(const char **ptr): ptr_(ptr) { }
operator const char **() { return ptr_; }
operator char **() { return const_cast<char **>(ptr_); }
private:
const char **ptr_;
};
bool plain_ascii_string(const char *str) {
bool result = true;
for (; result && *str; str++) {
result = *str >= 32 && *str <= 126;
std::string ascii_job_name(const char *job_name, const char *charset) {
if (job_name && charset) {
iconv_t cd = iconv_open("ASCII//TRANSLIT//IGNORE", charset);
if (cd != (iconv_t) -1) {
char ascii[80];
const char *in_ptr = job_name;
size_t in_left = strlen(job_name);
char *out_ptr = ascii;
size_t out_left = sizeof(ascii) - 1;
while (in_left > 0) {
size_t err = iconv(cd,
sloppy_ptr(&in_ptr), &in_left,
&out_ptr, &out_left);
if (err == (size_t) -1) {
break;
}
return result;
}
*out_ptr = 0;
iconv_close(cd);
return ascii;
}
}
return "CUPS";
}
std::string ascii_job_name(const char *job_id, const char *job_user, const char *job_name) {
std::array<const char *, 3> parts = {{
job_id,
job_user,
job_name
}};
std::string result;
for (const char *part : parts) {
if (*part && plain_ascii_string(part)) {
if (!result.empty()) {
result += '/';
}
result += part;
}
}
if (result.empty()) {
result = "brlaser";
}
const int max_size = 79;
if (result.size() > max_size) {
result.resize(max_size);
}
return result;
}
page_params build_page_params(const cups_page_header2_t &header) {
page_params build_page_params() {
static const std::array<std::string, 6> sources = {{
"AUTO", "T1", "T2", "T3", "MP", "MANUAL"
}};
@ -99,18 +101,15 @@ page_params build_page_params(const cups_page_header2_t &header) {
{ "EnvC5", "C5" },
{ "EnvMonarch", "MONARCH" },
{ "EnvPRC5", "DL" },
{ "EnvDL", "DL" },
{ "Executive", "EXECUTIVE" },
{ "Legal", "LEGAL" },
{ "Letter", "LETTER" }
};
page_params p = { };
p.num_copies = header.NumCopies;
p.resolution = header.HWResolution[0];
p.economode = header.cupsInteger[10];
p.mediatype = header.MediaType;
p.duplex = header.Duplex;
if (header.MediaPosition < sources.size())
p.sourcetray = sources[header.MediaPosition];
@ -129,78 +128,66 @@ page_params build_page_params(const cups_page_header2_t &header) {
} // namespace
int main(int argc, char *argv[]) {
fprintf(stderr, "INFO: %s version %s\n", PACKAGE, VERSION);
if (argc != 6 && argc != 7) {
fprintf(stderr, "ERROR: rastertobrlaser job-id user title copies options [file]\n");
fprintf(stderr, "ERROR: %s job-id user title copies options [file]\n", argv[0]);
fprintf(stderr, "INFO: This program is a CUPS filter. It is not intended to be run manually.\n");
return 1;
}
const char *job_id = argv[1];
const char *job_user = argv[2];
// const char *job_id = argv[1];
// const char *job_user = argv[2];
const char *job_name = argv[3];
// const int job_copies = atoi(argv[4]);
// const char *job_options = argv[5];
const char *job_filename = argv[6];
// const char *job_charset = getenv("CHARSET");
const char *job_charset = getenv("CHARSET");
setlocale(LC_ALL, "");
signal(SIGTERM, sigterm_handler);
signal(SIGPIPE, SIG_IGN);
int fd = STDIN_FILENO;
int fd = 0;
if (job_filename) {
fd = open(job_filename, O_RDONLY | O_BINARY);
fd = open(job_filename, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "ERROR: " PACKAGE ": Unable to open raster file\n");
fprintf(stderr, "ERROR: Unable to open raster file\n");
return 1;
}
}
#ifdef __OpenBSD__
if (pledge("stdio", nullptr) != 0) {
fprintf(stderr, "ERROR: " PACKAGE ": pledge failed\n");
return 1;
}
#endif
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
if (!ras) {
fprintf(stderr, "DEBUG: " PACKAGE ": Cannot read raster data. Most likely an earlier filter in the pipeline failed.\n");
fprintf(stderr, "ERROR: Can't read raster data\n");
return 1;
}
int pages = 0;
{
job job(stdout, ascii_job_name(job_id, job_user, job_name));
cups_page_header2_t header;
job job(stdout, ascii_job_name(job_name, job_charset));
while (!interrupted && cupsRasterReadHeader2(ras, &header)) {
if (header.cupsBitsPerPixel != 1
|| header.cupsBitsPerColor != 1
|| header.cupsNumColors != 1
|| header.cupsBytesPerLine > 10000) {
fprintf(stderr, "ERROR: " PACKAGE ": Page %d: Bogus raster data.\n", job.pages() + 1);
dump_page_header(header);
return 1;
}
if (job.pages() == 0) {
fprintf(stderr, "DEBUG: " PACKAGE ": Page header of first page\n");
if (pages == 0) {
dump_page_header(header);
}
job.encode_page(build_page_params(header),
job.encode_page(build_page_params(),
header.NumCopies,
header.cupsHeight,
header.cupsBytesPerLine,
next_line);
fprintf(stderr, "PAGE: %d %d\n", job.pages(), header.NumCopies);
fprintf(stderr, "PAGE: %d %d\n", ++pages, header.NumCopies);
}
if (job.pages() == 0) {
fprintf(stderr, "ERROR: " PACKAGE ": No pages were found.\n");
}
if (pages == 0) {
fprintf(stderr, "ERROR: No pages were found.");
return 1;
}
fflush(stdout);
if (ferror(stdout)) {
fprintf(stderr, "DEBUG: " PACKAGE ": Could not write print data. Most likely the CUPS backend failed.\n");
fprintf(stderr, "ERROR: Could not write print data\n");
return 1;
}
return 0;

View File

@ -18,7 +18,6 @@
#ifndef TEMPFILE_H
#define TEMPFILE_H
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

View File

@ -19,25 +19,22 @@
#include <stdint.h>
#include <vector>
#include "tempfile.h"
#include "../src/block.h"
#include "src/block.h"
typedef std::vector<uint8_t> vec;
const lest::test specification[] = {
"A block is created empty",
"Block line limit",
[] {
block b;
EXPECT(b.empty());
for (int i = 0; i < 128; ++i) {
EXPECT(b.line_fits(1));
b.add_line(vec(1));
}
EXPECT(!b.line_fits(1));
},
"Adding a line makes a block no longer empty",
[] {
block b;
b.add_line(vec{1});
EXPECT(!b.empty());
},
"A block has a size limit of about 16 kilobyte",
"Block size limit",
[] {
block b;
for (int i = 0; i < 16; ++i) {
@ -47,33 +44,30 @@ const lest::test specification[] = {
EXPECT(!b.line_fits(400));
},
"Flushing an empty block does nothing",
"Flush",
[] {
block b;
{
tempfile f;
b.flush(f.file());
EXPECT(f.data().empty());
},
"Flush() writes the lines to a file with a proper header",
[] {
block b;
for (uint8_t n = 1; n < 6; ++n) {
b.add_line(vec{n, n});
}
for (uint8_t n = 0; n < 10; n += 2) {
vec line = {n, static_cast<uint8_t>(n+1)};
EXPECT(b.line_fits(line.size()));
b.add_line(std::move(line));
}
{
tempfile f;
b.flush(f.file());
EXPECT(( f.data() == vec{'1','2','w',0,5,1,1,2,2,3,3,4,4,5,5} ));
},
"After flush() a block is empty again",
[] {
block b;
b.add_line(vec{1});
EXPECT(( f.data() == vec{'1','2','w',0,5,0,1,2,3,4,5,6,7,8,9} ));
}
{
tempfile f;
b.flush(f.file());
EXPECT(b.empty());
EXPECT(f.data().empty());
}
},
};
int main() {

View File

@ -1,35 +0,0 @@
// This file is part of the brlaser printer driver.
//
// Copyright 2020 Peter De Wachter
//
// brlaser 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.
//
// brlaser 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 brlaser. If not, see <http://www.gnu.org/licenses/>.
#include "lest.hpp"
#include "tempfile.h"
#include "../src/job.h"
const lest::test specification[] = {
"An empty job produces no output",
[] {
tempfile f;
{
job j(f.file(), "name");
}
EXPECT(f.data().empty());
},
};
int main() {
return lest::run(specification);
}

View File

@ -19,7 +19,7 @@
#include <assert.h>
#include <stdint.h>
#include <vector>
#include "../src/line.h"
#include "src/line.h"
typedef std::vector<uint8_t> vec;