From 68c05722af51e2bcad6b923c64dfa27b52f33dce Mon Sep 17 00:00:00 2001 From: klirichek Date: Thu, 28 Mar 2019 15:56:56 +0700 Subject: [PATCH] Global refactor All pre-built binaries removed from the project. Building is now done with CMake. PPDs are have to be built from shipped driver sources (however couple of defaults are still placed in sources as a fallback). CMake also includes install instructions (so after build 'sudo make install' will give you working solution both on Linux and on Mac Os). --- CMakeLists.txt | 78 +++++-- Makefile | 17 -- README.md | 60 ++++- ZJ-58.ppd | 117 ---------- install | 3 + rastertozj.c | 624 ++++++++++++++++++++++++++++++++----------------- zj-58.drv | 66 ------ zj58.ppd | 212 +++++++++++++++++ zj80.ppd | 212 +++++++++++++++++ zjdrv.drv | 216 +++++++++++++++++ 10 files changed, 1152 insertions(+), 453 deletions(-) delete mode 100644 Makefile delete mode 100644 ZJ-58.ppd delete mode 100644 zj-58.drv create mode 100644 zj58.ppd create mode 100644 zj80.ppd create mode 100644 zjdrv.drv diff --git a/CMakeLists.txt b/CMakeLists.txt index c8bf3f0..0a9aea2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required ( VERSION 3.12 ) +cmake_minimum_required ( VERSION 3.0 ) # set default build type to Release (if nothing else provided from outside yet) IF ( NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES ) @@ -9,27 +9,29 @@ ENDIF () project ( rastertozj C ) -#set ( CMAKE_INSTALL_PREFIX "/usr" CACHE FILEPATH "force install to /usr" FORCE ) - function( DIAG VARR ) message ( STATUS "${VARR} -> ${${VARR}}" ) endfunction() -# build the filter binary +# requirements to build the filter binary find_package ( Cups REQUIRED ) find_library ( CUPSIMAGELIB NAMES cupsimage ) mark_as_advanced ( CUPSIMAGELIB ) -set ( DEBUGFILE "/tmp/debugraster.txt" CACHE STRING "File where to make debug output if DEBUGP is set" ) -option ( DEBUGP "Whetner to output debug info" ON ) - add_executable ( rastertozj rastertozj.c ) target_compile_options ( rastertozj PRIVATE -Wall -fPIC ) target_include_directories ( rastertozj PRIVATE ${CUPS_INCLUDE_DIR} ) target_link_libraries ( rastertozj PRIVATE ${CUPS_LIBRARIES} ${CUPSIMAGELIB} ) -if ( DEBUGP ) - target_compile_definitions ( rastertozj PRIVATE DEBUGP DEBUGFILE="${DEBUGFILE}") +if ( CMAKE_BUILD_TYPE STREQUAL "Debug" ) + target_compile_definitions ( rastertozj PRIVATE DEBUGP ) + if ( APPLE ) + target_compile_definitions ( rastertozj PRIVATE SAFEDEBUG ) + message ( STATUS "On Mac OSX log is saved in sandbox, as /private/var/spool/cups/tmp" ) + elseif ( UNIX ) + set ( DEBUGFILE "/tmp/debugraster.txt" CACHE STRING "File where to make debug output if we build ad Debug" ) + target_compile_definitions ( rastertozj PRIVATE DEBUGFILE="${DEBUGFILE}" ) + endif () endif () # build ppds @@ -38,37 +40,63 @@ if ( NOT DEFINED PPDC ) endif () mark_as_advanced( PPDC ) +set ( PPDS "" ) if ( PPDC ) - set ( ENV{LANG} c ) - execute_process ( - COMMAND "${PPDC}" -d "${CMAKE_CURRENT_BINARY_DIR}" "zj-58.drv" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE res - OUTPUT_VARIABLE _CONTENT - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE ) + set ( DRVSRC "${CMAKE_CURRENT_SOURCE_DIR}/zjdrv.drv") + set ( PPDDIR "${CMAKE_CURRENT_BINARY_DIR}/ppd" ) + list (APPEND PPDS "${PPDDIR}/zj58.ppd" ) + list (APPEND PPDS "${PPDDIR}/xp58.ppd" ) + list (APPEND PPDS "${PPDDIR}/tm20.ppd" ) + list (APPEND PPDS "${PPDDIR}/zj80.ppd" ) + ADD_CUSTOM_COMMAND ( OUTPUT ${PPDS} + COMMAND LANG=c ${PPDC} ${DRVSRC} + MAIN_DEPENDENCY ${DRVSRC} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Building PPDs" + VERBATIM + ) + ADD_CUSTOM_TARGET ( ppds ALL DEPENDS ${PPDS} ) +else() + message (STATUS "No ppdc found; fall back to defaultly shipped ZJ-58.ppd") + list ( APPEND PPDS "${CMAKE_CURRENT_SOURCE_DIR}/zj58.ppd" ) + list ( APPEND PPDS "${CMAKE_CURRENT_SOURCE_DIR}/zj80.ppd" ) endif() # installation stuff -# this one works if you perform 'make install' -set ( CMAKE_INSTALL_PREFIX "/usr" CACHE FILEPATH "this is forced to /usr" FORCE ) - -# this one works if you perform 'make package' - it is kind of root for all packaging +# Set both installation prefixes to / +set ( CMAKE_INSTALL_PREFIX "/" CACHE FILEPATH "this is forced to /" FORCE ) set ( CPACK_PACKAGING_INSTALL_PREFIX "/" ) +set ( CPACK_PACKAGE_CONTACT "Alexey N. Vinogradov (a.n.vinogradov@gmail.com)" ) - -include ( GNUInstallDirs ) +set ( CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON ) +set ( CPACK_DEBIAN_PACKAGE_PREDEPENDS "libcups2-dev, libcupsimage2-dev" ) +set ( CPACK_DEBIAN_PACKAGE_SECTION "libs" ) +set ( CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/klirichek/zj-58") if ( APPLE ) set ( FILTERPATH "usr/libexec/cups/filter" ) set ( PPDPATH "Library/Printers/PPDs/Contents/Resources") + set ( OWNER "root:wheel") + install ( CODE "EXECUTE_PROCESS(COMMAND sudo launchctl stop org.cups.cupsd)" ) + install ( TARGETS rastertozj DESTINATION ${FILTERPATH} ) + # this line sets correct target permissions, due to CUPS requirements + # However as a side effect you'll need either fakeroot, either sudo to even perform 'make package' because of it. + install ( CODE "EXECUTE_PROCESS(COMMAND chown ${OWNER} \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${FILTERPATH}/rastertozj\")" ) + install ( FILES ${PPDS} DESTINATION "${PPDPATH}" ) + install ( CODE "EXECUTE_PROCESS(COMMAND sudo launchctl start org.cups.cupsd)" ) elseif ( UNIX ) set ( FILTERPATH "usr/lib/cups/filter" ) set ( PPDPATH "usr/share/cups/model/zjiang/" ) + set ( OWNER "root:root") + install ( CODE "EXECUTE_PROCESS(COMMAND /etc/init.d/cups stop)" ) + install ( TARGETS rastertozj DESTINATION ${FILTERPATH} ) + # this line sets correct target permissions, due to CUPS requirements + # However as a side effect you'll need either fakeroot, either sudo to even perform 'make package' because of it. + install ( CODE "EXECUTE_PROCESS(COMMAND chown ${OWNER} \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${FILTERPATH}/rastertozj\")" ) + install ( FILES ${PPDS} DESTINATION "${PPDPATH}" ) + install ( CODE "EXECUTE_PROCESS(COMMAND /etc/init.d/cups start)" ) endif() -install ( TARGETS rastertozj DESTINATION ${FILTERPATH} ) -install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/zj58.ppd DESTINATION "${PPDPATH}" ) include (CPack) diff --git a/Makefile b/Makefile deleted file mode 100644 index 2098bea..0000000 --- a/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -CC=gcc -RM=rm -f -CFLAGS=-Wl,-rpath,/usr/lib -Wall -fPIC -O3 -LDFLAGS= -LDLIBS=-lcupsimage -lcups - -SRCS=rastertozj.c -OBJS=$(subst .c,.o,$(SRCS)) - -all: rastertozj - -rastertozj: $(OBJS) - gcc $(LDFLAGS) -o rastertozj rastertozj.o $(LDLIBS) - -rastertozj.o: rastertozj.c - gcc $(CFLAGS) -c rastertozj.c - diff --git a/README.md b/README.md index 94ff3aa..cba386d 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,53 @@ -zj-58 +CUPS driver for thermal receipt printers (was: zj-58) +===================================================== + +CUPS filter for thermal receipt printers for rolls 58 and 80mm. + +Originally it was filter for Zijiang zj-58 with specific PPD, +but later it is revealed that it actually works with many other cheap 58mm printers, like +Xprinter XP-58, etc. Also support for 80mm printers added. + +Printing is performed from cups-raster using ESC/POS sequence 'GS v 0 '. +Empty (zero) lines feeded as 'feed' command (to avoid send empty raster). + +Also 2 Cash Drawers supported, with tunable impulse length for 'on' and 'off.' + +Build ===== -CUPS filter for thermal printer Zjiang ZJ-58 +You need toolchain, CMake and cups-devel. + +It may be achieved, say (as example) by running +``` +sudo apt install build-essential cmake libcups2-dev libcupsimage2-dev +``` + +After it the filter could be built by the sequence of commands: + +``` + mkdir build && cd build && cmake .. + make +``` + + +Installation +============ + +Need administrative rights! + +``` + sudo make install +``` + +'Sudo' is necessary to stop/restart cups service before operation, and also to place files with necessary rights. + + +Debian packaging +================ -The linux driver provided on Zjiang site unfortunately doesn't work. -First, it is 32-bit binary (and so, on x64 system need some x86 libs to be installed). -Second, it's PPD is not correct - it just doesn't show any advanced settings because of it. -Finally, raster filter just crashes on any try to run it! -But even if you run it, you'll see that it's working with printer is not optimal: for example, if it sees a blank line, it will send the blank raster to print (instead of just use 'feeding' command, which is definitely faster!) +For simplicity done with the same script as installation, so also need adminstrative rights. +``` + sudo cpack -G DEB +``` -This is the solution: -PPD is fixed and works. -Filter is provided as src (you can found a list of packages need to be installed in order to build it in the header of source). -Also, printing of blank lines is optimized. +That will stop/start cups as a side effect, however that is not critical. \ No newline at end of file diff --git a/ZJ-58.ppd b/ZJ-58.ppd deleted file mode 100644 index 5c77cc5..0000000 --- a/ZJ-58.ppd +++ /dev/null @@ -1,117 +0,0 @@ -*PPD-Adobe: "4.3" -*FormatVersion: "4.3" -*FileVersion: "1.2" -*LanguageVersion: English -*LanguageEncoding: ISOLatin1 -*PCFileName: "zj58.ppd" -*Manufacturer: "Zijiang" -*Product: "(zj-58)" -*1284DeviceID: "MFG:Zijiang;CMD:Zijiang;MDL:ZJ-58;CLS:PRINTER;" -*cupsVersion: 1.1 -*cupsManualCopies: True -*cupsModelNumber: 58 -*cupsFilter: "application/vnd.cups-raster 0 rastertozj" -*ModelName: "ZJ-58" -*ShortNickName: "ZJ-58" -*NickName: "Zijiang ZJ-58" -*PSVersion: "(3010.000) 550" -*LanguageLevel: "3" -*ColorDevice: False -*DefaultColorSpace: Gray -*FileSystem: False -*Throughput: "1" -*LandscapeOrientation: Plus90 -*VariablePaperSize: True -*TTRasterizer: Type42 - -*OpenUI *PageSize/Media Size: PickOne -*OrderDependency: 10 AnySetup *PageSize -*DefaultPageSize: X48MMY105MM - -*PageSize X48MMY105MM/58mm x 105mm: "<>setpagedevice" -*PageSize X48MMY210MM/58mm x 210mm: "<>setpagedevice" -*PageSize X48MMY297MM/58mm x 297mm: "<>setpagedevice" -*PageSize X48MMY3276MM/58mm x 3276mm: "<>setpagedevice" - -*CloseUI: *PageSize - -*OpenUI *PageRegion: PickOne -*OrderDependency: 10 AnySetup *PageRegion -*DefaultPageRegion: X48mmY105mm - -*PageRegion X48MMY105MM/58mm x 105mm: "<>setpagedevice" -*PageRegion X48MMY210MM/58mm x 210mm: "<>setpagedevice" -*PageRegion X48MMY297MM/58mm x 297mm: "<>setpagedevice" -*PageRegion X48MMY3276MM/58mm x 3276mm: "<>setpagedevice" - -*DefaultImageableArea: X48MMY105MM - -*ImageableArea X48MMY105MM: "0 0 136 298" -*ImageableArea X48MMY210MM: "0 0 136 595" -*ImageableArea X48MMY297MM: "0 0 136 842" -*ImageableArea X48MMY3276MM: "0 0 136 9286" - -*DefaultPaperDimension: X48MMY105MM - -*PaperDimension X48MMY105MM: "136 298" -*PaperDimension X48MMY210MM: "136 595" -*PaperDimension X48MMY297MM: "136 842" -*PaperDimension X48MMY3276MM: "136 9286" - -*MaxMediaWidth: "136" -*MaxMediaHeight: "9286" -*HWMargins: 0 0 0 0 -*CustomPageSize True: "pop pop pop <>setpagedevice" -*ParamCustomPageSize Width: 1 points 48 136 -*ParamCustomPageSize Height: 2 points 48 9282 -*ParamCustomPageSize WidthOffset: 3 points 0 0 -*ParamCustomPageSize HeightOffset: 4 points 0 0 -*ParamCustomPageSize Orientation: 5 int 0 0 - -*OpenGroup: CutGroup/Cut Options -*OpenUI *FeedDist/Feed distance after print: PickOne -*DefaultFeedDist: 2feed9mm -*FeedDist 0feed3mm/feed 3mm: "" -*FeedDist 1feed6mm/feed 6mm: "" -*FeedDist 2feed9mm/feed 9mm: "" -*FeedDist 3feed12mm/feed 12mm: "" -*FeedDist 4feed15mm/feed 15mm: "" -*FeedDist 5feed18mm/feed 18mm: "" -*FeedDist 6feed21mm/feed 21mm: "" -*FeedDist 7feed24mm/feed 24mm: "" -*FeedDist 8feed27mm/feed 27mm: "" -*FeedDist 9feed30mm/feed 30mm: "" -*FeedDist 10feed33mm/feed 33mm: "" -*FeedDist 11feed36mm/feed 36mm: "" -*FeedDist 12feed39mm/feed 39mm: "" -*FeedDist 13feed42mm/feed 42mm: "" -*FeedDist 14feed45mm/feed 45mm: "" -*CloseUI: *FeedDist - - -*OpenUI *BlankSpace/Blank space at page's end: PickOne -*DefaultBlankSpace: 1NoPrint -*BlankSpace 0Print/Print: "" -*BlankSpace 1NoPrint/Do not print: "" -*CloseUI: *BlankSpace - -*CloseGroup: *CutGroup - -*OpenGroup: *CashDrawerGroup/Cash Drawer Control -*OpenUI *CashDrawer1Setting/Cash Drawer 1: PickOne -*DefaultCashDrawer1Setting: 0NotCashDrawer1 -*CashDrawer1Setting 0NotCashDrawer1/Not Cash Drawer 1: "" -*CashDrawer1Setting 1NotCashDrawer1BeforePrinting/Cash Drawer 1 Before Printing: "" -*CashDrawer1Setting 2NotCashDrawer1BeforePrinting/Cash Drawer 1 After Printing: "" -*CloseUI: *CashDrawer1Setting - -*OpenUI *CashDrawer2Setting/Cash Drawer 2: PickOne -*DefaultCashDrawer2Setting: 0NotCashDrawer2 -*CashDrawer2Setting 0NotCashDrawer2/Not Cash Drawer 2: "" -*CashDrawer2Setting 1NotCashDrawer2BeforePrinting/Cash Drawer 2 Before Printing: "" -*CashDrawer2Setting 2NotCashDrawer2BeforePrinting/Cash Drawer 2 After Printing: "" -*CloseUI: *CashDrawer2Setting -*CloseGroup: *CashDrawerGroup - - -*% End diff --git a/install b/install index 45e0e08..96576c2 100755 --- a/install +++ b/install @@ -3,6 +3,9 @@ # Installs zj-58 driver # Tested as working under Ubuntu 14.04 +# Deprecated. Don't use this script; +# use build with cmake and then 'make install' instead + /etc/init.d/cups stop cp rastertozj /usr/lib/cups/filter/ mkdir -p /usr/share/cups/model/zjiang diff --git a/rastertozj.c b/rastertozj.c index 7c4f288..2b9bbbe 100644 --- a/rastertozj.c +++ b/rastertozj.c @@ -11,56 +11,85 @@ #define DEBUGFILE "/tmp/debugraster.txt" #endif +static inline int min(int a, int b) { + if (a > b) + return b; + return a; +} + +// settings and their stuff struct settings_ { - int cashDrawer1; - int cashDrawer2; - int blankSpace; - int feedDist; + int modelNum; // the only setting we get from PPD. + unsigned CashDrawer1; + unsigned CashDrawer2; + unsigned CashDrawer1On; + unsigned CashDrawer1Off; + unsigned CashDrawer2On; + unsigned CashDrawer2Off; + cups_bool_t InsertSheet; + cups_adv_t AdvanceMedia; + cups_cut_t CutMedia; + unsigned int AdvanceDistance; }; struct settings_ settings; -struct command { - int length; - char *command; -}; - -/* - * zj uses kind of epson ESC/P dialect code. Here is subset of commands - * - * initialize - esc @ - * cash drawer 1 - esc p 0 @ P - * cash drawer 2 - esc p 1 @ P - * start raster - esc v 0 - * skip lines - esc j - * cut - esc i - */ -// define printer initialize command -static const struct command printerInitializeCommand = {2, - (char[2]){0x1b, 0x40}}; // esc @ - -// define cashDrawerEjector command -static const struct command cashDrawerEject[2] = { - {5, (char[5]){0x1b, 0x70, 0, 0x40, 0x50}}, // esc p N @ P - {5, (char[5]){0x1b, 0x70, 1, 0x40, 0x50}}}; +static void initializeSettings(char *commandLineOptionSettings, struct settings_ *pSettings) { + ppd_file_t *pPpd = ppdOpenFile(getenv("PPD")); + // char* sDestination = getenv("DestinationPrinterID"); + memset(pSettings, 0, sizeof(struct settings_)); + pSettings->modelNum = pPpd->model_number; + ppdClose(pPpd); +} -// define raster mode start command -static const struct command rasterModeStartCommand = { - 4, (char[4]){0x1d, 0x76, 0x30, 0}}; // esc v 0 +static void update_settings_from_job (cups_page_header2_t * pHeader) +{ + if (!pHeader) + return; + settings.CashDrawer1 = pHeader->cupsInteger[0]; + settings.CashDrawer2 = pHeader->cupsInteger[1]; + settings.CashDrawer1On = pHeader->cupsInteger[2]; + settings.CashDrawer1Off = pHeader->cupsInteger[3]; + settings.CashDrawer2On = pHeader->cupsInteger[4]; + settings.CashDrawer2Off = pHeader->cupsInteger[5]; + settings.InsertSheet = pHeader->cupsInteger[6]; + settings.AdvanceMedia = pHeader->AdvanceMedia; + settings.CutMedia = pHeader->CutMedia; + settings.AdvanceDistance = pHeader->AdvanceDistance; +} #ifndef DEBUGP - static inline void mputchar(char c) { putchar(c); } - +#define DEBUGSTARTPRINT() +#define DEBUGFINISHPRINT() +#define DEBUGPRINT(...) #else - FILE *lfd = 0; -// putchar with debug wrapper +// putchar with debug wrappers static inline void mputchar(char c) { unsigned char m = c; if (lfd) fprintf(lfd, "%02x ", m); putchar(m); } +// on macos cups filters works in a sandbox and cant write +// filtes everywhere. We'll use $TMPDIR/debugraster.txt for them +#ifdef SAFEDEBUG +static inline void DEBUGSTARTPRINT() { + char * tmpfolder = getenv("TMPDIR"); + const char *filename = "/debugraster.txt"; + char *dbgpath = (char *)malloc(strlen(tmpfolder) + strlen(filename) + 1); + strcpy(dbgpath,tmpfolder); + strcat(dbgpath,filename); + lfd = fopen(dbgpath,"w"); + free(dbgpath); +} +#else +#define DEBUGSTARTPRINT() lfd = fopen(DEBUGFILE, "w") +#endif +#define DEBUGFINISHPRINT() \ + if (lfd) \ + fclose(lfd) +#define DEBUGPRINT(...) if (lfd) fprintf(lfd, "\n" __VA_ARGS__) #endif // procedure to output an array @@ -70,91 +99,106 @@ static inline void outputarray(const char *array, int length) { mputchar(array[i]); } -// output a command -static inline void outputCommand(struct command output) { - outputarray(output.command, output.length); -} +// output a command. -1 is because we determine them as string literals, +// so \0 implicitly added at the end, but we don't need it at all +#define SendCommand(COMMAND) outputarray((COMMAND),sizeof((COMMAND))-1) -static inline int lo(int val) { return val & 0xFF; } +static inline void mputnum(unsigned int val) { + mputchar(val&0xFFU); + mputchar((val>>8)&0xFFU); +} -static inline int hi(int val) { return lo(val >> 8); } +/* + * zj uses kind of epson ESC/POS dialect code. Here is subset of commands + * + * initialize - esc @ + * cash drawer 1 - esc p 0 @ P + * cash drawer 2 - esc p 1 @ P // @ =0x40 and P=0x50 and + * where *2ms is pulse on time, *2ms is pulse off. + * start raster - GS v 0 // 0 is full-density, may be also 1, 2, 4 + * skip lines - esc J // then N [0..255], each value 1/44 inches (0.176mm) + * // another commands out-of-spec: + * esc 'i' - cutter; xprinter android example shows as GS V \1 (1D 56 01) + * esc '8' - wait{4, cutter also (char[4]){29,'V','A',20}}; GS V 'A' 20 + */ -// enter raster mode and set up x and y dimensions -static inline void rasterheader(int xsize, int ysize) { - outputCommand(rasterModeStartCommand); - mputchar(lo(xsize)); - mputchar(hi(xsize)); - mputchar(lo(ysize)); - mputchar(hi(ysize)); -} +// define printer initialize command +static const char escInit[] = "\x1b@"; -// print all unprinted (i.e. flush the buffer) -// then feed given number of lines -static inline void skiplines(int size) { - mputchar(0x1b); - mputchar(0x4a); // esc j - mputchar(size); -} +// define cashDrawerEjector command +static const char escCashDrawerEject[] = "\x1bp"; -// get an option -static inline int getOptionChoiceIndex(const char *choiceName, - ppd_file_t *ppd) { - ppd_choice_t *choice; - ppd_option_t *option; +// define raster mode start command +static const char escRasterMode[] = "\x1dv0\0"; - choice = ppdFindMarkedChoice(ppd, choiceName); +// define flush command +static const char escFlush[] = "\x1bJ"; - if (choice == NULL) { - if ((option = ppdFindOption(ppd, choiceName)) == NULL) - return -1; - if ((choice = ppdFindChoice(option, option->defchoice)) == NULL) - return -1; - } +// define cut command +//static const char escCut[] = "\x1bi"; +static const char escCut[] = "\x1dV\1"; - return atoi(choice->choice); +// enter raster mode and set up x and y dimensions +static inline void sendRasterHeader(int xsize, int ysize) { + // outputCommand(rasterModeStartCommand); + SendCommand(escRasterMode); + mputnum(xsize); + mputnum(ysize); } -static void initializeSettings(char *commandLineOptionSettings) { - ppd_file_t *ppd = NULL; - cups_option_t *options = NULL; - int numOptions = 0; - - ppd = ppdOpenFile(getenv("PPD")); +static inline void flushLines(unsigned short lines) +{ + SendCommand(escFlush); + mputchar (lines); +} - ppdMarkDefaults(ppd); +// print all unprinted (i.e. flush the buffer) +static inline void flushBuffer() { + flushLines(0); +} - numOptions = cupsParseOptions(commandLineOptionSettings, 0, &options); - if ((numOptions != 0) && (options != NULL)) { - cupsMarkOptions(ppd, numOptions, options); - cupsFreeOptions(numOptions, options); +// flush, then feed 24 lines +static inline void flushManyLines(int iLines) +{ + DEBUGPRINT("Skip %d empty lines: ", iLines); + while ( iLines ) + { + int iStride = min (iLines, 24); + flushLines ( iStride ); + iLines -= iStride; } +} - memset(&settings, 0x00, sizeof(struct settings_)); - - settings.cashDrawer1 = getOptionChoiceIndex("CashDrawer1Setting", ppd); - settings.cashDrawer2 = getOptionChoiceIndex("CashDrawer2Setting", ppd); - settings.blankSpace = getOptionChoiceIndex("BlankSpace", ppd); - settings.feedDist = getOptionChoiceIndex("FeedDist", ppd); +inline static void CashDrawerEject (unsigned iDrawer, unsigned iOn, + unsigned iOff) +{ + SendCommand(escCashDrawerEject); + mputchar(iDrawer); + mputchar(iOn); + mputchar(iOff); +} - ppdClose(ppd); +inline static void cutMedia() +{ + SendCommand(escCut); } // sent on the beginning of print job -void jobSetup() { - if (settings.cashDrawer1 == 1) - outputCommand(cashDrawerEject[0]); - if (settings.cashDrawer2 == 1) - outputCommand(cashDrawerEject[1]); - outputCommand(printerInitializeCommand); +void setupJob() { + SendCommand(escInit); + if (settings.CashDrawer1 == 1) + CashDrawerEject(0,settings.CashDrawer1On,settings.CashDrawer1Off); + if (settings.CashDrawer2 == 1) + CashDrawerEject(1, settings.CashDrawer2On, settings.CashDrawer2Off); } // sent at the very end of print job -void ShutDown() { - if (settings.cashDrawer1 == 2) - outputCommand(cashDrawerEject[0]); - if (settings.cashDrawer2 == 2) - outputCommand(cashDrawerEject[1]); - outputCommand(printerInitializeCommand); +void finalizeJob() { + if (settings.CashDrawer1 == 2) + CashDrawerEject(0, settings.CashDrawer1On, settings.CashDrawer1Off); + if (settings.CashDrawer2 == 2) + CashDrawerEject(1, settings.CashDrawer2On, settings.CashDrawer2Off); +// SendCommand(escInit); } // sent at the end of every page @@ -163,10 +207,7 @@ typedef void (*__sighandler_t)(int); #endif __sighandler_t old_signal; -void EndPage() { - int i; - for (i = 0; i < settings.feedDist; ++i) - skiplines(0x18); +void finishPage() { signal(15, old_signal); } @@ -175,166 +216,315 @@ void cancelJob() { int i = 0; for (; i < 0x258; ++i) mputchar(0); - EndPage(); - ShutDown(); + finishPage(); } // invoked before starting to print a page -void pageSetup() { old_signal = signal(15, cancelJob); } +void startPage() { old_signal = signal(15, cancelJob); } + +void DebugPrintHeader (cups_page_header2_t* pHeader) +{ + DEBUGPRINT( + "MediaClass '%s'\n" + "MediaColor '%s'\n" + "MediaType '%s'\n" + "OutputType '%s'\n" + "AdvanceDistance %d\n" + "AdvanceMedia %d\n" + "Collate %d\n" + "CutMedia %d\n" + "Duplex %d\n" + "HWResolution %d %d\n" + "ImagingBoundingBox %d %d %d %d\n" + "InsertSheet %d\n" + "Jog %d\n" + "LeadingEdge %d\n" + "Margins %d %d\n" + "ManualFeed %d\n" + "MediaPosition %d\n" + "MediaWeight %d\n" + "MirrorPrint %d\n" + "NegativePrint %d\n" + "NumCopies %d\n" + "Orientation %d\n" + "OutputFaceUp %d\n" + "PageSize %d %d\n" + "Separations %d\n" + "TraySwitch %d\n" + "Tumble %d\n" + "cupsWidth %d\n" + "cupsHeight %d\n" + "cupsMediaType %d\n" + "cupsBitsPerColor %d\n" + "cupsBitsPerPixel %d\n" + "cupsBytesPerLine %d\n" + "cupsColorOrder %d\n" + "cupsColorSpace %d\n" + "cupsCompression %d\n" + "cupsRowCount %d\n" + "cupsRowFeed %d\n" + "cupsRowStep %d\n" + "cupsNumColors %d\n" + "cupsBorderlessScalingFactor %f\n" + "cupsPageSize %f %f\n" + "cupsImagingBBox %f %f %f %f\n" + "cupsInteger %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n" + "cupsReal %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n" + "cupsString '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'\n" + "cupsMarkerType '%s'\n" + "cupsRenderingIntent '%s'\n" + "cupsPageSizeName '%s'\n", + pHeader->MediaClass, pHeader->MediaColor, pHeader->MediaType, + pHeader->OutputType, pHeader->AdvanceDistance, pHeader->AdvanceMedia, + pHeader->Collate, pHeader->CutMedia, pHeader->Duplex, + pHeader->HWResolution[0], pHeader->HWResolution[1], + pHeader->ImagingBoundingBox[0], pHeader->ImagingBoundingBox[1], + pHeader->ImagingBoundingBox[2], pHeader->ImagingBoundingBox[3], + pHeader->InsertSheet, pHeader->Jog, pHeader->LeadingEdge, pHeader->Margins[0], + pHeader->Margins[1], pHeader->ManualFeed, pHeader->MediaPosition, + pHeader->MediaWeight, pHeader->MirrorPrint, pHeader->NegativePrint, + pHeader->NumCopies, pHeader->Orientation, pHeader->OutputFaceUp, + pHeader->PageSize[0], pHeader->PageSize[1], pHeader->Separations, + pHeader->TraySwitch, pHeader->Tumble, pHeader->cupsWidth, pHeader->cupsHeight, + pHeader->cupsMediaType, pHeader->cupsBitsPerColor, pHeader->cupsBitsPerPixel, + pHeader->cupsBytesPerLine, pHeader->cupsColorOrder, pHeader->cupsColorSpace, + pHeader->cupsCompression, pHeader->cupsRowCount, pHeader->cupsRowFeed, + pHeader->cupsRowStep, pHeader->cupsNumColors, + pHeader->cupsBorderlessScalingFactor, pHeader->cupsPageSize[0], + pHeader->cupsPageSize[1], pHeader->cupsImagingBBox[0], + pHeader->cupsImagingBBox[1], pHeader->cupsImagingBBox[2], + pHeader->cupsImagingBBox[3], pHeader->cupsInteger[0], + pHeader->cupsInteger[1], pHeader->cupsInteger[2], pHeader->cupsInteger[3], + pHeader->cupsInteger[4], pHeader->cupsInteger[5], pHeader->cupsInteger[6], + pHeader->cupsInteger[7], pHeader->cupsInteger[8], pHeader->cupsInteger[9], + pHeader->cupsInteger[10], pHeader->cupsInteger[11], pHeader->cupsInteger[12], + pHeader->cupsInteger[13], pHeader->cupsInteger[14], pHeader->cupsInteger[15], + pHeader->cupsReal[0], pHeader->cupsReal[1], pHeader->cupsReal[2], + pHeader->cupsReal[3], pHeader->cupsReal[4], pHeader->cupsReal[5], + pHeader->cupsReal[6], pHeader->cupsReal[7], pHeader->cupsReal[8], + pHeader->cupsReal[9], pHeader->cupsReal[10], pHeader->cupsReal[11], + pHeader->cupsReal[12], pHeader->cupsReal[13], pHeader->cupsReal[14], + pHeader->cupsReal[15], pHeader->cupsString[0], pHeader->cupsString[1], + pHeader->cupsString[2], pHeader->cupsString[3], pHeader->cupsString[4], + pHeader->cupsString[5], pHeader->cupsString[6], pHeader->cupsString[7], + pHeader->cupsString[8], pHeader->cupsString[9], pHeader->cupsString[10], + pHeader->cupsString[11], pHeader->cupsString[12], pHeader->cupsString[13], + pHeader->cupsString[14], pHeader->cupsString[15], pHeader->cupsMarkerType, + pHeader->cupsRenderingIntent, pHeader->cupsPageSizeName); +} + +// rearrange (compress) rows in pBuf, discarding tails of them +static inline unsigned compress_buffer(unsigned char *pBuf, unsigned iSize, + unsigned int iWideStride, unsigned int iStride) { + const unsigned char *pEnd = pBuf + iSize; + unsigned char *pTarget = pBuf; + while (pBuf < pEnd) { + int iBytes = min(pEnd - pBuf, iStride); + memmove(pTarget, pBuf, iBytes); + pTarget += iBytes; + pBuf += iWideStride; + } + return min(iSize, pTarget - pBuf); +} + +// returns -1 if whole line iz filled by zeros. Otherwise 0. +static inline int line_is_empty(const unsigned char *pBuf, unsigned iSize) { + int i; + for (i = 0; i < iSize; ++i) + if (pBuf[i]) + return 0; + return -1; +} + +static inline void send_raster(const unsigned char *pBuf, int width8, + int height) { + if (!height) + return; + DEBUGPRINT("Raster block %dx%d pixels\n", width8*8, height); + sendRasterHeader(width8, height); + outputarray((char *)pBuf, width8 * height); + flushBuffer(); +} + +#define EXITPRINT(CODE) \ + { \ + if (pRasterSrc) \ + cupsRasterClose(pRasterSrc); \ + if (pRasterBuf) \ + free(pRasterBuf); \ + if (fd) \ + close(fd); \ + return (CODE); \ + } ////////////////////////////////////////////// ////////////////////////////////////////////// int main(int argc, char *argv[]) { - int fd = 0; // File descriptor providing CUPS raster data - cups_raster_t *ras = NULL; // Raster stream for printing - cups_page_header2_t header; // CUPS Page header - int page = 0; // Current page - int y = 0; // Vertical position in page 0 <= y <= header.cupsHeight - - unsigned char *rasterData = NULL; // Pointer to raster data from CUPS - unsigned char *originalRasterDataPtr = - NULL; // Copy of original pointer for freeing buffer - if (argc < 6 || argc > 7) { fputs("ERROR: rastertozj job-id user title copies options [file]\n", stderr); return EXIT_FAILURE; } + int fd = STDIN_FILENO; // File descriptor providing CUPS raster data if (argc == 7) { if ((fd = open(argv[6], O_RDONLY)) == -1) { perror("ERROR: Unable to open raster file - "); sleep(1); return EXIT_FAILURE; } - } else - fd = 0; + } -#ifdef DEBUGP - lfd = fopen(DEBUGFILE, "w"); -#endif + DEBUGSTARTPRINT(); + int iCurrentPage = 0; + // CUPS Page tHeader + cups_page_header2_t tHeader; + unsigned char *pRasterBuf = NULL; // Pointer to raster data from CUPS + // Raster stream for printing + cups_raster_t *pRasterSrc = cupsRasterOpen(fd, CUPS_RASTER_READ); + initializeSettings(argv[5],&settings); + + DEBUGPRINT("ModelNumber from PPD '%d'\n", settings.modelNum); + + // set max num of pixels per line depended from model number (from ppd) + int iMaxWidth = settings.modelNum; + if (!iMaxWidth) + iMaxWidth = 0x240; - initializeSettings(argv[5]); - jobSetup(); - ras = cupsRasterOpen(fd, CUPS_RASTER_READ); - page = 0; + // postpone start of the job until we parse first header and get necessary values from there. + int iJobStarted = 0; - while (cupsRasterReadHeader2(ras, &header)) { - if ((header.cupsHeight == 0) || (header.cupsBytesPerLine == 0)) + // loop over the whole raster, page by page + while (cupsRasterReadHeader2(pRasterSrc, &tHeader)) { + if ((!tHeader.cupsHeight) || (!tHeader.cupsBytesPerLine)) break; -#ifdef DEBUGP - if (lfd) - fprintf(lfd, "\nheader.cupsHeight=%d, header.cupsBytesPerLine=%d\n", - header.cupsHeight, header.cupsBytesPerLine); -#endif + update_settings_from_job( &tHeader ); - if (rasterData == NULL) { - rasterData = malloc(header.cupsBytesPerLine * 24); - if (rasterData == NULL) { - if (originalRasterDataPtr != NULL) - free(originalRasterDataPtr); - cupsRasterClose(ras); - if (fd != 0) - close(fd); - return EXIT_FAILURE; - } - originalRasterDataPtr = rasterData; // used to later free the memory + if (!iJobStarted) + { + setupJob(); + iJobStarted = 1; } - fprintf(stderr, "PAGE: %d %d\n", ++page, header.NumCopies); - pageSetup(); + DebugPrintHeader ( &tHeader ); - int foo = (header.cupsWidth > 0x180) ? 0x180 : header.cupsWidth; + if (!pRasterBuf) { + pRasterBuf = malloc(tHeader.cupsBytesPerLine * 24); + if (!pRasterBuf) // hope it never goes here... + EXITPRINT(EXIT_FAILURE) + } + + fprintf(stderr, "PAGE: %d %d\n", ++iCurrentPage, tHeader.NumCopies); + + startPage(); + + // calculate num of bytes to print given width having 1 bit per pixel. + int foo = min(tHeader.cupsWidth, iMaxWidth); // 0x240 for 80mm (72mm printable) foo = (foo + 7) & 0xFFFFFFF8; - int width_size = foo >> 3; + int width_bytes = foo >> 3; // in bytes, [0..0x30] -#ifdef DEBUGP - if (lfd) - fprintf(lfd, "\nheader.cupsWidth=%d, foo=%d, width_size=%d\n", - header.cupsWidth, foo, width_size); -#endif - y = 0; + DEBUGPRINT("cupsWidth=%d, cupsBytesPerLine=%d; foo=%d, width_bytes=%d", + tHeader.cupsWidth, tHeader.cupsBytesPerLine, foo, width_bytes ); + + int iRowsToPrint = tHeader.cupsHeight; int zeroy = 0; - while (y < header.cupsHeight) { - if ((y & 127) != 0) - fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", page, - (100 * y / header.cupsHeight)); + // loop over one page, top to bottom by blocks of most 24 scan lines + while (iRowsToPrint) { + fprintf(stderr, "INFO: Printing iCurrentPage %d, %d%% complete...\n", + iCurrentPage, + (100 * (tHeader.cupsHeight - iRowsToPrint) / tHeader.cupsHeight)); - int rest = header.cupsHeight - y; - if (rest > 24) - rest = 24; + int iBlockHeight = min(iRowsToPrint, 24); -#ifdef DEBUGP - if (lfd) - fprintf(lfd, "\nProcessing block of %d, starting from %d lines\n", rest, - y); -#endif - y += rest; - - if (y) { - unsigned char *buf = rasterData; - int j; - for (j = 0; j < rest; ++j) { - if (!cupsRasterReadPixels(ras, buf, header.cupsBytesPerLine)) - break; - buf += width_size; - } -#ifdef DEBUGP - if (lfd) - fprintf(lfd, "\nRead %d lines\n", j); -#endif - if (j < rest) - continue; - } - int rest_bytes = rest * width_size; - int j; - for (j = 0; j < rest_bytes; ++j) - if (rasterData[j] != 0) - break; - -#ifdef DEBUGP - if (lfd) - fprintf(lfd, "\nChecked %d bytes of %d for zero\n", j, rest_bytes); -#endif + DEBUGPRINT("--------Processing block of %d, starting from %d lines", + iBlockHeight, tHeader.cupsHeight - iRowsToPrint); - if (j >= rest_bytes) { - ++zeroy; - continue; + iRowsToPrint -= iBlockHeight; + unsigned iBytesChunk = 0; + + // first, fetch whole block from the image + if (iBlockHeight) + iBytesChunk = cupsRasterReadPixels( + pRasterSrc, pRasterBuf, tHeader.cupsBytesPerLine * iBlockHeight); + + DEBUGPRINT("--------Got %d from %d requested bytes", + iBytesChunk, + tHeader.cupsBytesPerLine * + iBlockHeight); + + // if original image is wider - rearrange buffer so that our calculated + // lines come one-by-one without extra gaps + if (width_bytes < tHeader.cupsBytesPerLine) { + DEBUGPRINT("--------Compress line from %d to %d bytes", tHeader.cupsBytesPerLine, width_bytes); + iBytesChunk = compress_buffer(pRasterBuf, iBytesChunk, + tHeader.cupsBytesPerLine, width_bytes); } - for (; zeroy > 0; --zeroy) - skiplines(24); + // runaround for sometimes truncated output of cupsRasterReadPixels + if (iBytesChunk < width_bytes * iBlockHeight) { + DEBUGPRINT("--------Restore truncated gap of %d bytes", + width_bytes * iBlockHeight - iBytesChunk); + memset(pRasterBuf + iBytesChunk, 0, + width_bytes * iBlockHeight - iBytesChunk); + iBytesChunk = width_bytes * iBlockHeight; + } - rasterheader(width_size, rest); - outputarray((char *)rasterData, width_size * 24); - skiplines(0); - } + // lazy output of current raster. First check current line if it is zero. + // if there were many zeroes and met non-zero - flush zeros by 'feed' cmd + // if opposite - send non-zero chunk as raster. + unsigned char *pBuf = pRasterBuf; + unsigned char *pChunk = pBuf; + const unsigned char *pEnd = pBuf + iBytesChunk; + int nonzerolines = 0; + while ( pBuf 0; --zeroy) - skiplines(24); + // page is finished. + // m.b. we have to print empty tail at the end + if (settings.InsertSheet) + flushManyLines (zeroy); - EndPage(); - } + if (settings.AdvanceMedia == CUPS_ADVANCE_PAGE) + flushManyLines(settings.AdvanceDistance); - ShutDown(); + if (settings.CutMedia == CUPS_CUT_PAGE) + cutMedia(); - if (originalRasterDataPtr) - free(originalRasterDataPtr); - cupsRasterClose(ras); - if (fd) - close(fd); + finishPage(); + } // loop over all pages pages - fputs(page ? "INFO: Ready to print.\n" : "ERROR: No pages found!\n", stderr); + if (settings.AdvanceMedia==CUPS_ADVANCE_JOB) + flushManyLines(settings.AdvanceDistance); -#ifdef DEBUGP - if (lfd) - fclose(lfd); -#endif + if (settings.CutMedia == CUPS_CUT_JOB) + cutMedia(); - return page ? EXIT_SUCCESS : EXIT_FAILURE; + finalizeJob(); + fputs(iCurrentPage ? "INFO: Ready to print.\n" : "ERROR: No pages found!\n", + stderr); + DEBUGFINISHPRINT(); + EXITPRINT(iCurrentPage ? EXIT_SUCCESS : EXIT_FAILURE) } // end of rastertozj.c diff --git a/zj-58.drv b/zj-58.drv deleted file mode 100644 index d55fcad..0000000 --- a/zj-58.drv +++ /dev/null @@ -1,66 +0,0 @@ -// CUPS PPD Compiler CUPS v2.1.3 -// (Don't edit .ppd directly, edit this file instead, then use -// ppdc zj-58.drv to generate zj58.ppd) -// Include necessary files... -#include -#include - -// Zijiang ZJ-58 -{ - Manufacturer "Zijiang" - ModelName "ZJ-58" - PCFileName "zj58.ppd" - Version "1.2" - DriverType ps - ModelNumber 58 - ManualCopies Yes - Throughput 1 - Attribute "NickName" "" "Zijiang ZJ-58" - Attribute "ShortNickName" "" "ZJ-58" - Attribute "Product" "" "(zj-58)" - Attribute "1284DeviceID" "" "MFG:Zijiang;CMD:Zijiang;MDL:ZJ-58;CLS:PRINTER;" - Attribute "PSVersion" "" "(3010.000) 550" - Attribute "LanguageLevel" "" "3" - Attribute "DefaultColorSpace" "" "Gray" - Attribute "FileSystem" "" "False" - Attribute "LandscapeOrientation" "" "Plus90" - Attribute "TTRasterizer" "" "Type42" - Attribute "VariablePaperSize" "" "True" - Filter "application/vnd.cups-raster 0 rastertozj" - - *CustomMedia "X48MMY105MM/58mm x 105mm" 136.00 298.00 0.00 0.00 0.00 0.00 "<>setpagedevice" "<>setpagedevice" - CustomMedia "X48MMY210MM/58mm x 210mm" 136.00 595.00 0.00 0.00 0.00 0.00 "<>setpagedevice" "<>setpagedevice" - CustomMedia "X48MMY297MM/58mm x 297mm" 136.00 842.00 0.00 0.00 0.00 0.00 "<>setpagedevice" "<>setpagedevice" - CustomMedia "X48MMY3276MM/58mm x 3276mm" 136.00 9286.00 0.00 0.00 0.00 0.00 "<>setpagedevice" "<>setpagedevice" - - Group "CutGroup/Cut Options" - Option "FeedDist/Feed distance after print" PickOne AnySetup 0.0 - Choice "0feed3mm/feed 3mm" "" - Choice "1feed6mm/feed 6mm" "" - *Choice "2feed9mm/feed 9mm" "" - Choice "3feed12mm/feed 12mm" "" - Choice "4feed15mm/feed 15mm" "" - Choice "5feed18mm/feed 18mm" "" - Choice "6feed21mm/feed 21mm" "" - Choice "7feed24mm/feed 24mm" "" - Choice "8feed27mm/feed 27mm" "" - Choice "9feed30mm/feed 30mm" "" - Choice "10feed33mm/feed 33mm" "" - Choice "11feed36mm/feed 36mm" "" - Choice "12feed39mm/feed 39mm" "" - Choice "13feed42mm/feed 42mm" "" - Choice "14feed45mm/feed 45mm" "" - Option "BlankSpace/Blank space at page's end" PickOne AnySetup 0.0 - Choice "0Print/Print" "" - *Choice "1NoPrint/Do not print" "" - Group "*CashDrawerGroup/Cash Drawer Control" - Option "CashDrawer1Setting/Cash Drawer 1" PickOne AnySetup 0.0 - *Choice "0NotCashDrawer1/Not Cash Drawer 1" "" - Choice "1NotCashDrawer1BeforePrinting/Cash Drawer 1 Before Printing" "" - Choice "2NotCashDrawer1BeforePrinting/Cash Drawer 1 After Printing" "" - Option "CashDrawer2Setting/Cash Drawer 2" PickOne AnySetup 0.0 - *Choice "0NotCashDrawer2/Not Cash Drawer 2" "" - Choice "1NotCashDrawer2BeforePrinting/Cash Drawer 2 Before Printing" "" - Choice "2NotCashDrawer2BeforePrinting/Cash Drawer 2 After Printing" "" - -} diff --git a/zj58.ppd b/zj58.ppd new file mode 100644 index 0000000..737f433 --- /dev/null +++ b/zj58.ppd @@ -0,0 +1,212 @@ +*PPD-Adobe: "4.3" +*%%%% PPD file for ZJ-58 with CUPS. +*%%%% Created by the CUPS PPD Compiler CUPS v2.2.7. +*FormatVersion: "4.3" +*FileVersion: "1.2" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "zj58.ppd" +*Product: "(zj-58)" +*Manufacturer: "Zijiang" +*ModelName: "Zijiang ZJ-58" +*ShortNickName: "ZJ-58" +*NickName: "Zijiang ZJ-58" +*PSVersion: "(3010.000) 550" +*LanguageLevel: "3" +*ColorDevice: False +*DefaultColorSpace: Gray +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*TTRasterizer: Type42 +*% Driver-defined attributes... +*VariablePaperSize: True +*1284DeviceID: "MFG:Zijiang;CMD:Zijiang;MDL:ZJ-58;CLS:PRINTER;" +*cupsVersion: 2.2 +*cupsModelNumber: 384 +*cupsManualCopies: True +*cupsFilter: "application/vnd.cups-raster 100 rastertozj" +*cupsLanguages: "en" +*UIConstraints: *CashDrawer1Setting *OptionCash1 False +*UIConstraints: *OptionCash1 False *CashDrawer1Setting +*UIConstraints: *CashDrawer2Setting *OptionCash2 False +*UIConstraints: *OptionCash2 False *CashDrawer2Setting +*UIConstraints: *CutMedia *OptionCutter False +*UIConstraints: *OptionCutter False *CutMedia +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: X48MMY65MM +*PageSize X48MMY65MM/58mm x 65mm: "<>setpagedevice" +*PageSize X48MMY105MM/58mm x 105mm: "<>setpagedevice" +*PageSize X48MMY210MM/58mm x 210mm: "<>setpagedevice" +*PageSize X48MMY297MM/58mm x 297mm: "<>setpagedevice" +*PageSize X48MMY3276MM/58mm x 3276mm: "<>setpagedevice" +*CloseUI: *PageSize +*OpenUI *PageRegion/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: X48MMY65MM +*PageRegion X48MMY65MM/58mm x 65mm: "<>setpagedevice" +*PageRegion X48MMY105MM/58mm x 105mm: "<>setpagedevice" +*PageRegion X48MMY210MM/58mm x 210mm: "<>setpagedevice" +*PageRegion X48MMY297MM/58mm x 297mm: "<>setpagedevice" +*PageRegion X48MMY3276MM/58mm x 3276mm: "<>setpagedevice" +*CloseUI: *PageRegion +*DefaultImageableArea: X48MMY65MM +*ImageableArea X48MMY65MM/58mm x 65mm: "14 0 150 182" +*ImageableArea X48MMY105MM/58mm x 105mm: "14 0 150 298" +*ImageableArea X48MMY210MM/58mm x 210mm: "14 0 150 595" +*ImageableArea X48MMY297MM/58mm x 297mm: "14 0 150 842" +*ImageableArea X48MMY3276MM/58mm x 3276mm: "14 0 150 9286" +*DefaultPaperDimension: X48MMY65MM +*PaperDimension X48MMY65MM/58mm x 65mm: "164 182" +*PaperDimension X48MMY105MM/58mm x 105mm: "164 298" +*PaperDimension X48MMY210MM/58mm x 210mm: "164 595" +*PaperDimension X48MMY297MM/58mm x 297mm: "164 842" +*PaperDimension X48MMY3276MM/58mm x 3276mm: "164 9286" +*MaxMediaWidth: "164" +*MaxMediaHeight: "9286" +*HWMargins: 14 0 14 0 +*CustomPageSize True: "pop pop pop <>setpagedevice" +*ParamCustomPageSize Width: 1 points 164 164 +*ParamCustomPageSize Height: 2 points 56 9286 +*ParamCustomPageSize WidthOffset: 3 points 0 0 +*ParamCustomPageSize HeightOffset: 4 points 0 0 +*ParamCustomPageSize Orientation: 5 int 0 0 +*OpenUI *CutMedia/Cut Media: PickOne +*OrderDependency: 10 AnySetup *CutMedia +*DefaultCutMedia: None +*CutMedia None/No cutting: "<>setpagedevice" +*CutMedia EndOfPage/Cut at every page: "<>setpagedevice" +*CutMedia EndOfJob/Cut at every job: "<>setpagedevice" +*CloseUI: *CutMedia +*OpenGroup: InstallableOptions/Installable Options +*OpenUI *OptionCash1/Cash drawer 1: Boolean +*OrderDependency: 10 AnySetup *OptionCash1 +*DefaultOptionCash1: False +*OptionCash1 False/Not Installed: "" +*OptionCash1 True/Installed: "" +*CloseUI: *OptionCash1 +*OpenUI *OptionCash2/Cash drawer 2: Boolean +*OrderDependency: 10 AnySetup *OptionCash2 +*DefaultOptionCash2: False +*OptionCash2 False/Not Installed: "" +*OptionCash2 True/Installed: "" +*CloseUI: *OptionCash2 +*OpenUI *OptionCutter/Cutter: Boolean +*OrderDependency: 10 AnySetup *OptionCutter +*DefaultOptionCutter: False +*OptionCutter False/Not Installed: "" +*OptionCutter True/Installed: "" +*CloseUI: *OptionCutter +*CloseGroup: InstallableOptions +*OpenGroup: BlankGroup/Blank Options +*OpenUI *FeedDist/Feed distance: PickOne +*OrderDependency: 10 AnySetup *FeedDist +*DefaultFeedDist: 2feed9mm +*FeedDist 0feed3mm/3mm: "<>setpagedevice" +*FeedDist 1feed6mm/6mm: "<>setpagedevice" +*FeedDist 2feed9mm/9mm: "<>setpagedevice" +*FeedDist 3feed12mm/12mm: "<>setpagedevice" +*FeedDist 4feed15mm/15mm: "<>setpagedevice" +*FeedDist 5feed18mm/18mm: "<>setpagedevice" +*FeedDist 6feed21mm/21mm: "<>setpagedevice" +*FeedDist 7feed24mm/24mm: "<>setpagedevice" +*FeedDist 8feed27mm/27mm: "<>setpagedevice" +*FeedDist 9feed30mm/30mm: "<>setpagedevice" +*FeedDist 10feed33mm/33mm: "<>setpagedevice" +*FeedDist 11feed36mm/36mm: "<>setpagedevice" +*FeedDist 12feed39mm/39mm: "<>setpagedevice" +*FeedDist 13feed42mm/42mm: "<>setpagedevice" +*FeedDist 14feed45mm/45mm: "<>setpagedevice" +*CloseUI: *FeedDist +*OpenUI *FeedWhere/When to feed: PickOne +*OrderDependency: 10 AnySetup *FeedWhere +*DefaultFeedWhere: AfterJob +*FeedWhere None/Never: "" +*FeedWhere AfterPage/After each page: "<>setpagedevice" +*FeedWhere AfterJob/After whole printing: "<>setpagedevice" +*CloseUI: *FeedWhere +*OpenUI *BlankSpace/Blank space at page's end: Boolean +*OrderDependency: 10 AnySetup *BlankSpace +*DefaultBlankSpace: False +*BlankSpace True/Print: "<>setpagedevice" +*BlankSpace False/None: "<>setpagedevice" +*CloseUI: *BlankSpace +*CloseGroup: BlankGroup +*OpenGroup: *CashDrawerGroup/Cash Drawer Control +*OpenUI *CashDrawer1Setting/Cash Drawer 1: PickOne +*OrderDependency: 10 DocumentSetup *CashDrawer1Setting +*DefaultCashDrawer1Setting: None +*CashDrawer1Setting None/None: "<>setpagedevice" +*CashDrawer1Setting 1BeforePrinting/Before Printing: "<>setpagedevice" +*CashDrawer1Setting 1AfterPrinting/After Printing: "<>setpagedevice" +*CloseUI: *CashDrawer1Setting +*OpenUI *CashDrawer2Setting/Cash Drawer 2: PickOne +*OrderDependency: 10 DocumentSetup *CashDrawer2Setting +*DefaultCashDrawer2Setting: None +*CashDrawer2Setting None/None: "<>setpagedevice" +*CashDrawer2Setting 2BeforePrinting/Before Printing: "<>setpagedevice" +*CashDrawer2Setting 2AfterPrinting/After Printing: "<>setpagedevice" +*CloseUI: *CashDrawer2Setting +*CloseGroup: *CashDrawerGroup +*OpenGroup: *CashDrawerTune/Cash Drawer Tune +*OpenUI *CashDrawer1PulseOn/Cash Drawer 1 pulse ON time: PickOne +*OrderDependency: 9 DocumentSetup *CashDrawer1PulseOn +*DefaultCashDrawer1PulseOn: 40XMS +*CashDrawer1PulseOn None/None: "" +*CashDrawer1PulseOn 10XMS/32mS: "<>setpagedevice" +*CashDrawer1PulseOn 20XMS/64mS: "<>setpagedevice" +*CashDrawer1PulseOn 30XMS/96mS: "<>setpagedevice" +*CashDrawer1PulseOn 40XMS/128mS: "<>setpagedevice" +*CashDrawer1PulseOn 50XMS/160mS: "<>setpagedevice" +*CashDrawer1PulseOn 60XMS/192mS: "<>setpagedevice" +*CashDrawer1PulseOn 70XMS/224mS: "<>setpagedevice" +*CashDrawer1PulseOn 80XMS/256mS: "<>setpagedevice" +*CloseUI: *CashDrawer1PulseOn +*OpenUI *CashDrawer1PulseOff/Cash Drawer 1 pulse OFF time: PickOne +*OrderDependency: 9 DocumentSetup *CashDrawer1PulseOff +*DefaultCashDrawer1PulseOff: 50XMS +*CashDrawer1PulseOff None/None: "" +*CashDrawer1PulseOff 10XMS/32mS: "<>setpagedevice" +*CashDrawer1PulseOff 20XMS/64mS: "<>setpagedevice" +*CashDrawer1PulseOff 30XMS/96mS: "<>setpagedevice" +*CashDrawer1PulseOff 40XMS/128mS: "<>setpagedevice" +*CashDrawer1PulseOff 50XMS/160mS: "<>setpagedevice" +*CashDrawer1PulseOff 60XMS/192mS: "<>setpagedevice" +*CashDrawer1PulseOff 70XMS/224mS: "<>setpagedevice" +*CashDrawer1PulseOff 80XMS/256mS: "<>setpagedevice" +*CloseUI: *CashDrawer1PulseOff +*OpenUI *CashDrawer2PulseOn/Cash Drawer 2 pulse ON time: PickOne +*OrderDependency: 9 DocumentSetup *CashDrawer2PulseOn +*DefaultCashDrawer2PulseOn: 40XMS +*CashDrawer2PulseOn None/None: "" +*CashDrawer2PulseOn 10XMS/32mS: "<>setpagedevice" +*CashDrawer2PulseOn 20XMS/64mS: "<>setpagedevice" +*CashDrawer2PulseOn 30XMS/96mS: "<>setpagedevice" +*CashDrawer2PulseOn 40XMS/128mS: "<>setpagedevice" +*CashDrawer2PulseOn 50XMS/160mS: "<>setpagedevice" +*CashDrawer2PulseOn 60XMS/192mS: "<>setpagedevice" +*CashDrawer2PulseOn 70XMS/224mS: "<>setpagedevice" +*CashDrawer2PulseOn 80XMS/256mS: "<>setpagedevice" +*CloseUI: *CashDrawer2PulseOn +*OpenUI *CashDrawer2PulseOff/Cash Drawer 2 pulse OFF time: PickOne +*OrderDependency: 9 DocumentSetup *CashDrawer2PulseOff +*DefaultCashDrawer2PulseOff: 50XMS +*CashDrawer2PulseOff None/None: "" +*CashDrawer2PulseOff 10XMS/32mS: "<>setpagedevice" +*CashDrawer2PulseOff 20XMS/64mS: "<>setpagedevice" +*CashDrawer2PulseOff 30XMS/96mS: "<>setpagedevice" +*CashDrawer2PulseOff 40XMS/128mS: "<>setpagedevice" +*CashDrawer2PulseOff 50XMS/160mS: "<>setpagedevice" +*CashDrawer2PulseOff 60XMS/192mS: "<>setpagedevice" +*CashDrawer2PulseOff 70XMS/224mS: "<>setpagedevice" +*CashDrawer2PulseOff 80XMS/256mS: "<>setpagedevice" +*CloseUI: *CashDrawer2PulseOff +*OpenUI *Resolution/Resolution: PickOne +*OrderDependency: 10 AnySetup *Resolution +*DefaultResolution: 203x203dpi +*Resolution 203x203dpi/203 DPI Grayscale: "<>setpagedevice" +*CloseUI: *Resolution +*CloseGroup: *CashDrawerTune +*DefaultFont: Courier +*% End of zj58.ppd, 10245 bytes. diff --git a/zj80.ppd b/zj80.ppd new file mode 100644 index 0000000..6ac713d --- /dev/null +++ b/zj80.ppd @@ -0,0 +1,212 @@ +*PPD-Adobe: "4.3" +*%%%% PPD file for ZJ-80 with CUPS. +*%%%% Created by the CUPS PPD Compiler CUPS v2.2.7. +*FormatVersion: "4.3" +*FileVersion: "1.2" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "zj80.ppd" +*Product: "(zj-80)" +*Manufacturer: "Zijiang" +*ModelName: "Zijiang ZJ-80" +*ShortNickName: "ZJ-80" +*NickName: "Zijiang ZJ-80" +*PSVersion: "(3010.000) 550" +*LanguageLevel: "3" +*ColorDevice: False +*DefaultColorSpace: Gray +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*TTRasterizer: Type42 +*% Driver-defined attributes... +*VariablePaperSize: True +*1284DeviceID: "MFG:Zijiang;CMD:Zijiang;MDL:ZJ-80;CLS:PRINTER;" +*cupsVersion: 2.2 +*cupsModelNumber: 560 +*cupsManualCopies: True +*cupsFilter: "application/vnd.cups-raster 100 rastertozj" +*cupsLanguages: "en" +*UIConstraints: *CashDrawer1Setting *OptionCash1 False +*UIConstraints: *OptionCash1 False *CashDrawer1Setting +*UIConstraints: *CashDrawer2Setting *OptionCash2 False +*UIConstraints: *OptionCash2 False *CashDrawer2Setting +*UIConstraints: *CutMedia *OptionCutter False +*UIConstraints: *OptionCutter False *CutMedia +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: X70MMY65MM +*PageSize X70MMY65MM/80mm x 65mm: "<>setpagedevice" +*PageSize X70MMY105MM/80mm x 105mm: "<>setpagedevice" +*PageSize X70MMY210MM/80mm x 210mm: "<>setpagedevice" +*PageSize X70MMY297MM/80mm x 297mm: "<>setpagedevice" +*PageSize X70MMY3276MM/80mm x 3276mm: "<>setpagedevice" +*CloseUI: *PageSize +*OpenUI *PageRegion/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: X70MMY65MM +*PageRegion X70MMY65MM/80mm x 65mm: "<>setpagedevice" +*PageRegion X70MMY105MM/80mm x 105mm: "<>setpagedevice" +*PageRegion X70MMY210MM/80mm x 210mm: "<>setpagedevice" +*PageRegion X70MMY297MM/80mm x 297mm: "<>setpagedevice" +*PageRegion X70MMY3276MM/80mm x 3276mm: "<>setpagedevice" +*CloseUI: *PageRegion +*DefaultImageableArea: X70MMY65MM +*ImageableArea X70MMY65MM/80mm x 65mm: "14 0 212 182" +*ImageableArea X70MMY105MM/80mm x 105mm: "14 0 212 298" +*ImageableArea X70MMY210MM/80mm x 210mm: "14 0 212 595" +*ImageableArea X70MMY297MM/80mm x 297mm: "14 0 212 842" +*ImageableArea X70MMY3276MM/80mm x 3276mm: "14 0 212 9286" +*DefaultPaperDimension: X70MMY65MM +*PaperDimension X70MMY65MM/80mm x 65mm: "226 182" +*PaperDimension X70MMY105MM/80mm x 105mm: "226 298" +*PaperDimension X70MMY210MM/80mm x 210mm: "226 595" +*PaperDimension X70MMY297MM/80mm x 297mm: "226 842" +*PaperDimension X70MMY3276MM/80mm x 3276mm: "226 9286" +*MaxMediaWidth: "226" +*MaxMediaHeight: "9286" +*HWMargins: 14 0 14 0 +*CustomPageSize True: "pop pop pop <>setpagedevice" +*ParamCustomPageSize Width: 1 points 226 226 +*ParamCustomPageSize Height: 2 points 56 9286 +*ParamCustomPageSize WidthOffset: 3 points 0 0 +*ParamCustomPageSize HeightOffset: 4 points 0 0 +*ParamCustomPageSize Orientation: 5 int 0 0 +*OpenUI *CutMedia/Cut Media: PickOne +*OrderDependency: 10 AnySetup *CutMedia +*DefaultCutMedia: None +*CutMedia None/No cutting: "<>setpagedevice" +*CutMedia EndOfPage/Cut at every page: "<>setpagedevice" +*CutMedia EndOfJob/Cut at every job: "<>setpagedevice" +*CloseUI: *CutMedia +*OpenGroup: InstallableOptions/Installable Options +*OpenUI *OptionCash1/Cash drawer 1: Boolean +*OrderDependency: 10 AnySetup *OptionCash1 +*DefaultOptionCash1: False +*OptionCash1 False/Not Installed: "" +*OptionCash1 True/Installed: "" +*CloseUI: *OptionCash1 +*OpenUI *OptionCash2/Cash drawer 2: Boolean +*OrderDependency: 10 AnySetup *OptionCash2 +*DefaultOptionCash2: False +*OptionCash2 False/Not Installed: "" +*OptionCash2 True/Installed: "" +*CloseUI: *OptionCash2 +*OpenUI *OptionCutter/Cutter: Boolean +*OrderDependency: 10 AnySetup *OptionCutter +*DefaultOptionCutter: False +*OptionCutter False/Not Installed: "" +*OptionCutter True/Installed: "" +*CloseUI: *OptionCutter +*CloseGroup: InstallableOptions +*OpenGroup: BlankGroup/Blank Options +*OpenUI *FeedDist/Feed distance: PickOne +*OrderDependency: 10 AnySetup *FeedDist +*DefaultFeedDist: 2feed9mm +*FeedDist 0feed3mm/3mm: "<>setpagedevice" +*FeedDist 1feed6mm/6mm: "<>setpagedevice" +*FeedDist 2feed9mm/9mm: "<>setpagedevice" +*FeedDist 3feed12mm/12mm: "<>setpagedevice" +*FeedDist 4feed15mm/15mm: "<>setpagedevice" +*FeedDist 5feed18mm/18mm: "<>setpagedevice" +*FeedDist 6feed21mm/21mm: "<>setpagedevice" +*FeedDist 7feed24mm/24mm: "<>setpagedevice" +*FeedDist 8feed27mm/27mm: "<>setpagedevice" +*FeedDist 9feed30mm/30mm: "<>setpagedevice" +*FeedDist 10feed33mm/33mm: "<>setpagedevice" +*FeedDist 11feed36mm/36mm: "<>setpagedevice" +*FeedDist 12feed39mm/39mm: "<>setpagedevice" +*FeedDist 13feed42mm/42mm: "<>setpagedevice" +*FeedDist 14feed45mm/45mm: "<>setpagedevice" +*CloseUI: *FeedDist +*OpenUI *FeedWhere/When to feed: PickOne +*OrderDependency: 10 AnySetup *FeedWhere +*DefaultFeedWhere: AfterJob +*FeedWhere None/Never: "" +*FeedWhere AfterPage/After each page: "<>setpagedevice" +*FeedWhere AfterJob/After whole printing: "<>setpagedevice" +*CloseUI: *FeedWhere +*OpenUI *BlankSpace/Blank space at page's end: Boolean +*OrderDependency: 10 AnySetup *BlankSpace +*DefaultBlankSpace: False +*BlankSpace True/Print: "<>setpagedevice" +*BlankSpace False/None: "<>setpagedevice" +*CloseUI: *BlankSpace +*CloseGroup: BlankGroup +*OpenGroup: *CashDrawerGroup/Cash Drawer Control +*OpenUI *CashDrawer1Setting/Cash Drawer 1: PickOne +*OrderDependency: 10 DocumentSetup *CashDrawer1Setting +*DefaultCashDrawer1Setting: None +*CashDrawer1Setting None/None: "<>setpagedevice" +*CashDrawer1Setting 1BeforePrinting/Before Printing: "<>setpagedevice" +*CashDrawer1Setting 1AfterPrinting/After Printing: "<>setpagedevice" +*CloseUI: *CashDrawer1Setting +*OpenUI *CashDrawer2Setting/Cash Drawer 2: PickOne +*OrderDependency: 10 DocumentSetup *CashDrawer2Setting +*DefaultCashDrawer2Setting: None +*CashDrawer2Setting None/None: "<>setpagedevice" +*CashDrawer2Setting 2BeforePrinting/Before Printing: "<>setpagedevice" +*CashDrawer2Setting 2AfterPrinting/After Printing: "<>setpagedevice" +*CloseUI: *CashDrawer2Setting +*CloseGroup: *CashDrawerGroup +*OpenGroup: *CashDrawerTune/Cash Drawer Tune +*OpenUI *CashDrawer1PulseOn/Cash Drawer 1 pulse ON time: PickOne +*OrderDependency: 9 DocumentSetup *CashDrawer1PulseOn +*DefaultCashDrawer1PulseOn: 40XMS +*CashDrawer1PulseOn None/None: "" +*CashDrawer1PulseOn 10XMS/32mS: "<>setpagedevice" +*CashDrawer1PulseOn 20XMS/64mS: "<>setpagedevice" +*CashDrawer1PulseOn 30XMS/96mS: "<>setpagedevice" +*CashDrawer1PulseOn 40XMS/128mS: "<>setpagedevice" +*CashDrawer1PulseOn 50XMS/160mS: "<>setpagedevice" +*CashDrawer1PulseOn 60XMS/192mS: "<>setpagedevice" +*CashDrawer1PulseOn 70XMS/224mS: "<>setpagedevice" +*CashDrawer1PulseOn 80XMS/256mS: "<>setpagedevice" +*CloseUI: *CashDrawer1PulseOn +*OpenUI *CashDrawer1PulseOff/Cash Drawer 1 pulse OFF time: PickOne +*OrderDependency: 9 DocumentSetup *CashDrawer1PulseOff +*DefaultCashDrawer1PulseOff: 50XMS +*CashDrawer1PulseOff None/None: "" +*CashDrawer1PulseOff 10XMS/32mS: "<>setpagedevice" +*CashDrawer1PulseOff 20XMS/64mS: "<>setpagedevice" +*CashDrawer1PulseOff 30XMS/96mS: "<>setpagedevice" +*CashDrawer1PulseOff 40XMS/128mS: "<>setpagedevice" +*CashDrawer1PulseOff 50XMS/160mS: "<>setpagedevice" +*CashDrawer1PulseOff 60XMS/192mS: "<>setpagedevice" +*CashDrawer1PulseOff 70XMS/224mS: "<>setpagedevice" +*CashDrawer1PulseOff 80XMS/256mS: "<>setpagedevice" +*CloseUI: *CashDrawer1PulseOff +*OpenUI *CashDrawer2PulseOn/Cash Drawer 2 pulse ON time: PickOne +*OrderDependency: 9 DocumentSetup *CashDrawer2PulseOn +*DefaultCashDrawer2PulseOn: 40XMS +*CashDrawer2PulseOn None/None: "" +*CashDrawer2PulseOn 10XMS/32mS: "<>setpagedevice" +*CashDrawer2PulseOn 20XMS/64mS: "<>setpagedevice" +*CashDrawer2PulseOn 30XMS/96mS: "<>setpagedevice" +*CashDrawer2PulseOn 40XMS/128mS: "<>setpagedevice" +*CashDrawer2PulseOn 50XMS/160mS: "<>setpagedevice" +*CashDrawer2PulseOn 60XMS/192mS: "<>setpagedevice" +*CashDrawer2PulseOn 70XMS/224mS: "<>setpagedevice" +*CashDrawer2PulseOn 80XMS/256mS: "<>setpagedevice" +*CloseUI: *CashDrawer2PulseOn +*OpenUI *CashDrawer2PulseOff/Cash Drawer 2 pulse OFF time: PickOne +*OrderDependency: 9 DocumentSetup *CashDrawer2PulseOff +*DefaultCashDrawer2PulseOff: 50XMS +*CashDrawer2PulseOff None/None: "" +*CashDrawer2PulseOff 10XMS/32mS: "<>setpagedevice" +*CashDrawer2PulseOff 20XMS/64mS: "<>setpagedevice" +*CashDrawer2PulseOff 30XMS/96mS: "<>setpagedevice" +*CashDrawer2PulseOff 40XMS/128mS: "<>setpagedevice" +*CashDrawer2PulseOff 50XMS/160mS: "<>setpagedevice" +*CashDrawer2PulseOff 60XMS/192mS: "<>setpagedevice" +*CashDrawer2PulseOff 70XMS/224mS: "<>setpagedevice" +*CashDrawer2PulseOff 80XMS/256mS: "<>setpagedevice" +*CloseUI: *CashDrawer2PulseOff +*OpenUI *Resolution/Resolution: PickOne +*OrderDependency: 10 AnySetup *Resolution +*DefaultResolution: 203x203dpi +*Resolution 203x203dpi/203 DPI Grayscale: "<>setpagedevice" +*CloseUI: *Resolution +*CloseGroup: *CashDrawerTune +*DefaultFont: Courier +*% End of zj80.ppd, 10245 bytes. diff --git a/zjdrv.drv b/zjdrv.drv new file mode 100644 index 0000000..49fc364 --- /dev/null +++ b/zjdrv.drv @@ -0,0 +1,216 @@ +// CUPS PPD Compiler CUPS v2.1.3 +// (Don't edit .ppd directly, edit this file instead, then use +// ppdc zj-58.drv to generate zj58.ppd) + +// common for all thermal printers +Version "1.2" +DriverType custom +ManualCopies Yes +Throughput 1 +Attribute "PSVersion" "" "(3010.000) 550" +Attribute "LanguageLevel" "" "3" +Attribute "DefaultColorSpace" "" "Gray" +Attribute "FileSystem" "" "False" +Attribute "LandscapeOrientation" "" "Plus90" +Attribute "TTRasterizer" "" "Type42" +Attribute "VariablePaperSize" "" "True" +Filter "application/vnd.cups-raster 100 rastertozj" +ColorDevice False +VariablePaperSize Yes + +// cutter +Option "CutMedia/Cut Media" PickOne AnySetup 10 + *Choice "None/No cutting" "<>setpagedevice" + Choice "EndOfPage/Cut at every page" "<>setpagedevice" + Choice "EndOfJob/Cut at every job" "<>setpagedevice" + +Group "BlankGroup/Blank Options" + Option "FeedDist/Feed distance" PickOne AnySetup 10 + Choice "0feed3mm/3mm" "<>setpagedevice" + Choice "1feed6mm/6mm" "<>setpagedevice" + *Choice "2feed9mm/9mm" "<>setpagedevice" + Choice "3feed12mm/12mm" "<>setpagedevice" + Choice "4feed15mm/15mm" "<>setpagedevice" + Choice "5feed18mm/18mm" "<>setpagedevice" + Choice "6feed21mm/21mm" "<>setpagedevice" + Choice "7feed24mm/24mm" "<>setpagedevice" + Choice "8feed27mm/27mm" "<>setpagedevice" + Choice "9feed30mm/30mm" "<>setpagedevice" + Choice "10feed33mm/33mm" "<>setpagedevice" + Choice "11feed36mm/36mm" "<>setpagedevice" + Choice "12feed39mm/39mm" "<>setpagedevice" + Choice "13feed42mm/42mm" "<>setpagedevice" + Choice "14feed45mm/45mm" "<>setpagedevice" + + Option "FeedWhere/When to feed" PickOne AnySetup 10 + Choice "None/Never" "" + Choice "AfterPage/After each page" "<>setpagedevice" + *Choice "AfterJob/After whole printing" "<>setpagedevice" + + Option "BlankSpace/Blank space at page's end" Boolean AnySetup 10 + Choice "True/Print" "<>setpagedevice" + *Choice "False/None" "<>setpagedevice" + +Group "*CashDrawerGroup/Cash Drawer Control" + Option "CashDrawer1Setting/Cash Drawer 1" PickOne DocumentSetup 10 + *Choice "None/None" "<>setpagedevice" + Choice "1BeforePrinting/Before Printing" "<>setpagedevice" + Choice "1AfterPrinting/After Printing" "<>setpagedevice" + + Option "CashDrawer2Setting/Cash Drawer 2" PickOne DocumentSetup 10 + *Choice "None/None" "<>setpagedevice" + Choice "2BeforePrinting/Before Printing" "<>setpagedevice" + Choice "2AfterPrinting/After Printing" "<>setpagedevice" + +Group "*CashDrawerTune/Cash Drawer Tune" + Option "CashDrawer1PulseOn/Cash Drawer 1 pulse ON time" PickOne DocumentSetup 9 + Choice "None/None" "" + Choice "10XMS/32mS" "<>setpagedevice" + Choice "20XMS/64mS" "<>setpagedevice" + Choice "30XMS/96mS" "<>setpagedevice" + *Choice "40XMS/128mS" "<>setpagedevice" + Choice "50XMS/160mS" "<>setpagedevice" + Choice "60XMS/192mS" "<>setpagedevice" + Choice "70XMS/224mS" "<>setpagedevice" + Choice "80XMS/256mS" "<>setpagedevice" + + Option "CashDrawer1PulseOff/Cash Drawer 1 pulse OFF time" PickOne DocumentSetup 9 + Choice "None/None" "" + Choice "10XMS/32mS" "<>setpagedevice" + Choice "20XMS/64mS" "<>setpagedevice" + Choice "30XMS/96mS" "<>setpagedevice" + Choice "40XMS/128mS" "<>setpagedevice" + *Choice "50XMS/160mS" "<>setpagedevice" + Choice "60XMS/192mS" "<>setpagedevice" + Choice "70XMS/224mS" "<>setpagedevice" + Choice "80XMS/256mS" "<>setpagedevice" + + Option "CashDrawer2PulseOn/Cash Drawer 2 pulse ON time" PickOne DocumentSetup 9 + Choice "None/None" "" + Choice "10XMS/32mS" "<>setpagedevice" + Choice "20XMS/64mS" "<>setpagedevice" + Choice "30XMS/96mS" "<>setpagedevice" + *Choice "40XMS/128mS" "<>setpagedevice" + Choice "50XMS/160mS" "<>setpagedevice" + Choice "60XMS/192mS" "<>setpagedevice" + Choice "70XMS/224mS" "<>setpagedevice" + Choice "80XMS/256mS" "<>setpagedevice" + + Option "CashDrawer2PulseOff/Cash Drawer 2 pulse OFF time" PickOne DocumentSetup 9 + Choice "None/None" "" + Choice "10XMS/32mS" "<>setpagedevice" + Choice "20XMS/64mS" "<>setpagedevice" + Choice "30XMS/96mS" "<>setpagedevice" + Choice "40XMS/128mS" "<>setpagedevice" + *Choice "50XMS/160mS" "<>setpagedevice" + Choice "60XMS/192mS" "<>setpagedevice" + Choice "70XMS/224mS" "<>setpagedevice" + Choice "80XMS/256mS" "<>setpagedevice" + + + Installable "OptionCash1/Cash drawer 1" + UIConstraints "*CashDrawer1Setting *OptionCash1 False" + // UIConstraints "*CashDrawer1PulseOn *OptionCash1 False" + // UIConstraints "*CashDrawer1PulseOff *OptionCash1 False" + +// Attribute cupsUIConstraints Cash1Off "*OptionCash1 False *CashDrawer1Setting" +// Attribute cupsUIConstraints Cash1Off "*OptionCash1 False *CashDrawer1PulseOn" +// Attribute cupsUIConstraints Cash1Off "*OptionCash1 False *CashDrawer1PulseOff" +// Attribute cupsUIResolver Cash1Off "*CashDrawer1Setting None *CashDrawer1PulseOn None *CashDrawer1PulseOff None" +// Attribute cupsUIResolver Cash1Off "*CashDrawer1PulseOn None" +// Attribute cupsUIResolver Cash1Off "*CashDrawer1PulseOff None" + + Installable "OptionCash2/Cash drawer 2" + UIConstraints "*CashDrawer2Setting *OptionCash2 False" + // UIConstraints "*CashDrawer2PulseOn *OptionCash2 False" + // UIConstraints "*CashDrawer2PulseOff *OptionCash2 False" + + Installable "OptionCutter/Cutter" + UIConstraints "*CutMedia *OptionCutter False" + +// Attribute cupsUIConstraints CutterOff "*OptionCutter False *CutMedia" +// Attribute cupsUIResolver CutterOff "*CutMedia None" + + +Option "Resolution/Resolution" PickOne AnySetup 10 +*Choice "203x203dpi/203 DPI Grayscale" "<>setpagedevice" + +HWMargins 14 0 14 0 + +// 58mm printers +{ + #define POINTS 164 + #define PIXELS 384 + + // model num is used by filter to determine raster width. 384 for 48mm, 560 for 70mm + ModelNumber $PIXELS + MinSize $POINTS 56 + MaxSize $POINTS 9286 + + *CustomMedia "X48MMY65MM/58mm x 65mm" $POINTS 182 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + CustomMedia "X48MMY105MM/58mm x 105mm" $POINTS 298 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + CustomMedia "X48MMY210MM/58mm x 210mm" $POINTS 595 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + CustomMedia "X48MMY297MM/58mm x 297mm" $POINTS 842 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + CustomMedia "X48MMY3276MM/58mm x 3276mm" $POINTS 9286 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + + // Zijiang ZJ-58 + { + Manufacturer "Zijiang" + ModelName "ZJ-58" + PCFileName "zj58.ppd" + Attribute "NickName" "" "Zijiang ZJ-58" + Attribute "ShortNickName" "" "ZJ-58" + Attribute "Product" "" "(zj-58)" + Attribute "1284DeviceID" "" "MFG:Zijiang;CMD:Zijiang;MDL:ZJ-58;CLS:PRINTER;" + } + + // XPrinter XP-58 + { + Manufacturer "J-speed" + ModelName "XP-58" + PCFileName "xp58.ppd" + Attribute "NickName" "" "J-speed XP-58" + Attribute "ShortNickName" "" "XP-58" + Attribute "Product" "" "(xp-58)" + Attribute "1284DeviceID" "" "MFG:J-speed;CMD:Xprinter;MDL:XP-58;CLS:PRINTER;" + } +} + +// 80mm printers +{ + #define POINTS 226 + #define PIXELS 560 + // model num is used by filter to determine raster width. 58 -> 0x180, 80 -> 0x240. + ModelNumber $PIXELS + MinSize $POINTS 56 + MaxSize $POINTS 9286 + + *CustomMedia "X70MMY65MM/80mm x 65mm" $POINTS 182 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + CustomMedia "X70MMY105MM/80mm x 105mm" $POINTS 298 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + CustomMedia "X70MMY210MM/80mm x 210mm" $POINTS 595 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + CustomMedia "X70MMY297MM/80mm x 297mm" $POINTS 842 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + CustomMedia "X70MMY3276MM/80mm x 3276mm" $POINTS 9286 14 0 14 0 "<>setpagedevice" "<>setpagedevice" + + // Zijiang ZJ-80 + { + Manufacturer "Zijiang" + ModelName "ZJ-80" + PCFileName "zj80.ppd" + Attribute "NickName" "" "Zijiang ZJ-80" + Attribute "ShortNickName" "" "ZJ-80" + Attribute "Product" "" "(zj-80)" + Attribute "1284DeviceID" "" "MFG:Zijiang;CMD:Zijiang;MDL:ZJ-80;CLS:PRINTER;" + } + + // Epson TM-T20 + { + Manufacturer "Epson" + ModelName "TM-T20" + PCFileName "tm20.ppd" + Attribute "NickName" "" "Epson TM-T20" + Attribute "ShortNickName" "" "TM-T20" + Attribute "Product" "" "(TM-T20)" + Attribute "1MFG:Epson;CMD:Epson;MDL:TMT20;CLS:PRINTER;" + } +} +