plug-ins/print/escputil.c plug-ins/print/.cvsignore new tool which
2000-10-29 Michael Natterer <mitch@gimp.org> * plug-ins/print/escputil.c * plug-ins/print/.cvsignore * plug-ins/print/Makefile.am: new tool which installs under <prefix>/bin and does stuff like cleaning and adjusting your printer's head. * plug-ins/print/README * plug-ins/print/RELNOTES: these files already say 4.0.1 now but I didn't tag the sourceforge tree of bumped the version number in Makefile.am (it's just about getting in the new executable as early as possible).
This commit is contained in:
parent
1e0c024cb0
commit
ca2625a05d
6 changed files with 929 additions and 7 deletions
14
ChangeLog
14
ChangeLog
|
|
@ -1,3 +1,17 @@
|
|||
2000-10-29 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* plug-ins/print/escputil.c
|
||||
* plug-ins/print/.cvsignore
|
||||
* plug-ins/print/Makefile.am: new tool which installs under
|
||||
<prefix>/bin and does stuff like cleaning and adjusting your
|
||||
printer's head.
|
||||
|
||||
* plug-ins/print/README
|
||||
* plug-ins/print/RELNOTES: these files already say 4.0.1 now but I
|
||||
didn't tag the sourceforge tree of bumped the version number in
|
||||
Makefile.am (it's just about getting in the new executable as early
|
||||
as possible).
|
||||
|
||||
2000-10-29 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* plug-ins/common/screenshot.c: tuned the dialog layout and cleaned
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ Makefile
|
|||
_libs
|
||||
.libs
|
||||
print
|
||||
escputil
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ EXTRA_DIST = print-printers.c
|
|||
|
||||
libexec_PROGRAMS = print
|
||||
|
||||
bin_PROGRAMS = escputil
|
||||
|
||||
print_SOURCES = \
|
||||
print-canon.c \
|
||||
print-dither.c \
|
||||
|
|
@ -24,6 +26,8 @@ print_SOURCES = \
|
|||
gimp_main_window.c \
|
||||
print_gimp.h
|
||||
|
||||
escputil_SOURCES = escputil.c
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
$(GTK_CFLAGS) \
|
||||
|
|
@ -44,6 +48,8 @@ LDADD = \
|
|||
$(GTK_LIBS) \
|
||||
$(INTLLIBS)
|
||||
|
||||
escputil_LDADD =
|
||||
|
||||
.PHONY: files
|
||||
|
||||
files:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
This is Gimp-Print version 4.0.0, the first stable release in the 4.0
|
||||
line. Gimp-print is the print facility for the Gimp, and in addition
|
||||
a suite of drivers that may be used with common UNIX spooling systems
|
||||
using GhostScript or CUPS. These drivers provide printing quality for
|
||||
This is Gimp-Print version 4.0.1, a stable release in the 4.0 line.
|
||||
Gimp-print is the print facility for the Gimp, and in addition a suite
|
||||
of drivers that may be used with common UNIX spooling systems using
|
||||
GhostScript or CUPS. These drivers provide printing quality for
|
||||
UNIX/Linux on a par with proprietary vendor-supplied drivers in many
|
||||
cases, and can be used for many of the most demanding printing tasks.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
This is gimp-print version 4.0.0, the first stable release in the 4.0
|
||||
line.
|
||||
This is gimp-print version 4.0.1, a stable release in the 4.0 line.
|
||||
|
||||
This software includes the Print plug-in for the Gimp (1.0, 1.1, and
|
||||
1.2), and GhostScript and CUPS drivers. The support for printers in
|
||||
|
|
@ -8,7 +7,18 @@ the Print plugin -- they use the identical code base. Please read
|
|||
Ghost/README and CUPS/README.txt for more information on this.
|
||||
|
||||
|
||||
Gimp-Print 4.0.0 is a major release of the Gimp Print plugin and
|
||||
Gimp-Print 4.0.1 contains the following fixes over Gimp-Print 4.0.0:
|
||||
|
||||
1) The copy of escputil.c in the Ghost subdirectory was older than the
|
||||
copy at top level.
|
||||
|
||||
2) escputil in either location would fail to compile without the GNU
|
||||
version of getopt() due to a syntax error.
|
||||
|
||||
3) The INSTALL file referred to an old version of gimp-print.
|
||||
|
||||
|
||||
Gimp-Print 4.0 is a major release of the Gimp Print plugin and
|
||||
associated stp GhostScript driver and CUPS driver. Among the new
|
||||
features over the 2.0 (distributed with the Gimp 1.0) and 3.0
|
||||
(distributed with some versions of the Gimp 1.1) releases are:
|
||||
|
|
|
|||
891
plug-ins/print/escputil.c
Normal file
891
plug-ins/print/escputil.c
Normal file
|
|
@ -0,0 +1,891 @@
|
|||
/*
|
||||
* "$Id$"
|
||||
*
|
||||
* Printer maintenance utility for Epson Stylus printers
|
||||
*
|
||||
* Copyright 2000 Robert Krawitz (rlk@alum.mit.edu)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
char *banner = "\
|
||||
Copyright 2000 Robert Krawitz (rlk@alum.mit.edu)\n\
|
||||
\n\
|
||||
This program is free software; you can redistribute it and/or modify it\n\
|
||||
under the terms of the GNU General Public License as published by the Free\n\
|
||||
Software Foundation; either version 2 of the License, or (at your option)\n\
|
||||
any later version.\n\
|
||||
\n\
|
||||
This program is distributed in the hope that it will be useful, but\n\
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n\
|
||||
for more details.\n\
|
||||
\n\
|
||||
You should have received a copy of the GNU General Public License\n\
|
||||
along with this program; if not, write to the Free Software\n\
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n";
|
||||
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
|
||||
struct option optlist[] =
|
||||
{
|
||||
{ "printer-name", 1, NULL, (int) 'P' },
|
||||
{ "raw-device", 1, NULL, (int) 'r' },
|
||||
{ "ink-level", 0, NULL, (int) 'i' },
|
||||
{ "clean-head", 0, NULL, (int) 'c' },
|
||||
{ "nozzle-check", 0, NULL, (int) 'n' },
|
||||
{ "align-head", 0, NULL, (int) 'a' },
|
||||
{ "usb", 0, NULL, (int) 'u' },
|
||||
{ "help", 0, NULL, (int) 'h' },
|
||||
{ "identify", 0, NULL, (int) 'd' },
|
||||
{ "model", 1, NULL, (int) 'm' },
|
||||
{ "quiet", 0, NULL, (int) 'q' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
char *help_msg = "\
|
||||
Usage: escputil [-P printer | -r device] [-m model] [-u]\n\
|
||||
[-c | -n | -a | -i] [-q]\n\
|
||||
-P|--printer-name Specify the name of the printer to operate on.\n\
|
||||
Default is the default system printer.\n\
|
||||
-r|--raw-device Specify the name of the device to write to directly\n\
|
||||
rather than going through a printer queue.\n\
|
||||
-c|--clean-head Clean the print head.\n\
|
||||
-n|--nozzle-check Print a nozzle test pattern.\n\
|
||||
Dirty or clogged nozzles will show as gaps in the\n\
|
||||
pattern. If you see any gaps, you should run a\n\
|
||||
head cleaning pass.\n\
|
||||
-a|--align-head Align the print head. CAUTION: Misuse of this\n\
|
||||
utility may result in poor print quality and/or\n\
|
||||
damage to the printer.\n\
|
||||
-i|--ink-level Obtain the ink level from the printer. This requires\n\
|
||||
read/write access to the raw printer device.\n\
|
||||
-d|--identify Query the printer for make and model information.\n\
|
||||
This requires read/write access to the raw printer\n\
|
||||
device.\n\
|
||||
-u|--usb The printer is connected via USB.\n\
|
||||
-h|--help Print this help message.\n\
|
||||
-q|--quiet Suppress the banner.\n\
|
||||
-m|--model Specify the precise printer model for head alignment.\n";
|
||||
#else
|
||||
char *help_msg = "\
|
||||
Usage: escputil [-P printer | -r device] [-u] [-c | -n | -a | -i] [-q]\n\
|
||||
-P Specify the name of the printer to operate on.\n\
|
||||
Default is the default system printer.\n\
|
||||
-r Specify the name of the device to write to directly\n\
|
||||
rather than going through a printer queue.\n\
|
||||
-c Clean the print head.\n\
|
||||
-n Print a nozzle test pattern.\n\
|
||||
Dirty or clogged nozzles will show as gaps in the\n\
|
||||
pattern. If you see any gaps, you should run a\n\
|
||||
head cleaning pass.\n\
|
||||
-a Align the print head. CAUTION: Misuse of this\n\
|
||||
utility may result in poor print quality and/or\n\
|
||||
damage to the printer.\n\
|
||||
-i Obtain the ink level from the printer. This requires\n\
|
||||
read/write access to the raw printer device.\n\
|
||||
-d Query the printer for make and model information. This\n\
|
||||
requires read/write access to the raw printer device.\n\
|
||||
-u The printer is connected via USB.\n\
|
||||
-h Print this help message.\n\
|
||||
-q Suppress the banner.\n\
|
||||
-m Specify the precise printer model for head alignment.\n";
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *short_name;
|
||||
char *long_name;
|
||||
int passes;
|
||||
int choices;
|
||||
} printer_t;
|
||||
|
||||
printer_t printer_list[] =
|
||||
{
|
||||
{ "color", "Stylus Color", 1, 7 },
|
||||
{ "pro", "Stylus Color Pro", 1, 7 },
|
||||
{ "pro-xl", "Stylus Color Pro XL", 1, 7 },
|
||||
{ "400", "Stylus Color 400", 1, 7 },
|
||||
{ "440", "Stylus Color 440", 1, 15 },
|
||||
{ "460", "Stylus Color 460", 1, 15 },
|
||||
{ "480", "Stylus Color 480", 1, 15 },
|
||||
{ "500", "Stylus Color 500", 1, 7 },
|
||||
{ "600", "Stylus Color 600", 1, 7 },
|
||||
{ "640", "Stylus Color 640", 1, 15 },
|
||||
{ "660", "Stylus Color 660", 1, 15 },
|
||||
{ "670", "Stylus Color 670", 3, 15 },
|
||||
{ "740", "Stylus Color 740", 3, 15 },
|
||||
{ "760", "Stylus Color 760", 3, 15 },
|
||||
{ "800", "Stylus Color 800", 1, 7 },
|
||||
{ "850", "Stylus Color 850", 1, 7 },
|
||||
{ "860", "Stylus Color 860", 3, 15 },
|
||||
{ "880", "Stylus Color 880", 3, 15 },
|
||||
{ "900", "Stylus Color 900", 3, 15 },
|
||||
{ "980", "Stylus Color 980", 3, 15 },
|
||||
{ "1160", "Stylus Color 1160", 3, 15 },
|
||||
{ "1500", "Stylus Color 1500", 1, 7 },
|
||||
{ "1520", "Stylus Color 1520", 1, 7 },
|
||||
{ "3000", "Stylus Color 3000", 1, 7 },
|
||||
{ "photo", "Stylus Photo", 1, 7 },
|
||||
{ "700", "Stylus Photo 700", 1, 7 },
|
||||
{ "ex", "Stylus Photo EX", 1, 7 },
|
||||
{ "720", "Stylus Photo 720", 3, 15 },
|
||||
{ "750", "Stylus Photo 750", 3, 15 },
|
||||
{ "870", "Stylus Photo 870", 3, 15 },
|
||||
{ "1200", "Stylus Photo 1200", 3, 15 },
|
||||
{ "1270", "Stylus Photo 1270", 3, 15 },
|
||||
{ "2000", "Stylus Photo 2000P", 2, 15 },
|
||||
{ NULL, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
void initialize_print_cmd(void);
|
||||
void do_head_clean(void);
|
||||
void do_nozzle_check(void);
|
||||
void do_align(void);
|
||||
void do_ink_level(void);
|
||||
void do_identify(void);
|
||||
|
||||
char *printer = NULL;
|
||||
char *raw_device = NULL;
|
||||
char *printer_model = NULL;
|
||||
char printer_cmd[1025];
|
||||
int bufpos = 0;
|
||||
int isUSB = 0;
|
||||
|
||||
void
|
||||
do_help(int code)
|
||||
{
|
||||
printer_t *printer = &printer_list[0];
|
||||
printf("%s", help_msg);
|
||||
printf("Available models are:\n");
|
||||
while (printer->short_name)
|
||||
{
|
||||
printf("%10s %s\n", printer->short_name, printer->long_name);
|
||||
printer++;
|
||||
}
|
||||
exit(code);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int quiet = 0;
|
||||
int operation = 0;
|
||||
int c;
|
||||
while (1)
|
||||
{
|
||||
#ifdef __GNU_LIBRARY__
|
||||
int option_index = 0;
|
||||
c = getopt_long(argc, argv, "P:r:icnaduqm:", optlist, &option_index);
|
||||
#else
|
||||
c = getopt(argc, argv, "P:r:icnaduqm:");
|
||||
#endif
|
||||
if (c == -1)
|
||||
break;
|
||||
switch (c)
|
||||
{
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
case 'c':
|
||||
case 'i':
|
||||
case 'n':
|
||||
case 'a':
|
||||
case 'd':
|
||||
if (operation)
|
||||
do_help(1);
|
||||
operation = c;
|
||||
break;
|
||||
case 'P':
|
||||
if (printer || raw_device)
|
||||
{
|
||||
printf("You may only specify one printer or raw device.\n");
|
||||
do_help(1);
|
||||
}
|
||||
printer = malloc(strlen(optarg) + 1);
|
||||
strcpy(printer, optarg);
|
||||
break;
|
||||
case 'r':
|
||||
if (printer || raw_device)
|
||||
{
|
||||
printf("You may only specify one printer or raw device.\n");
|
||||
do_help(1);
|
||||
}
|
||||
raw_device = malloc(strlen(optarg) + 1);
|
||||
strcpy(raw_device, optarg);
|
||||
break;
|
||||
case 'm':
|
||||
if (printer_model)
|
||||
{
|
||||
printf("You may only specify one printer model.\n");
|
||||
do_help(1);
|
||||
}
|
||||
printer_model = malloc(strlen(optarg) + 1);
|
||||
strcpy(printer_model, optarg);
|
||||
break;
|
||||
case 'u':
|
||||
isUSB = 1;
|
||||
break;
|
||||
case 'h':
|
||||
do_help(0);
|
||||
break;
|
||||
default:
|
||||
printf("%s\n", banner);
|
||||
fprintf(stderr, "Unknown option %c\n", c);
|
||||
do_help(1);
|
||||
}
|
||||
}
|
||||
if (!quiet)
|
||||
printf("%s\n", banner);
|
||||
if (operation == 0)
|
||||
do_help(1);
|
||||
initialize_print_cmd();
|
||||
switch(operation)
|
||||
{
|
||||
case 'c':
|
||||
do_head_clean();
|
||||
break;
|
||||
case 'n':
|
||||
do_nozzle_check();
|
||||
break;
|
||||
case 'i':
|
||||
do_ink_level();
|
||||
break;
|
||||
case 'a':
|
||||
do_align();
|
||||
break;
|
||||
case 'd':
|
||||
do_identify();
|
||||
break;
|
||||
default:
|
||||
do_help(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
do_print_cmd(void)
|
||||
{
|
||||
FILE *pfile;
|
||||
int bytes = 0;
|
||||
int retries = 0;
|
||||
char command[1024];
|
||||
memcpy(printer_cmd + bufpos, "\f\033\000\033\000", 5);
|
||||
bufpos += 5;
|
||||
if (raw_device)
|
||||
{
|
||||
pfile = fopen(raw_device, "wb");
|
||||
if (!pfile)
|
||||
{
|
||||
fprintf(stderr, "Cannot open device %s: %s\n", raw_device,
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!access("/bin/lpr", X_OK) ||
|
||||
!access("/usr/bin/lpr", X_OK) ||
|
||||
!access("/usr/bsd/lpr", X_OK))
|
||||
{
|
||||
if (printer == NULL)
|
||||
strcpy(command, "lpr -l");
|
||||
else
|
||||
sprintf(command, "lpr -P%s -l", printer);
|
||||
}
|
||||
else if (printer == NULL)
|
||||
strcpy(command, "lp -s -oraw");
|
||||
else
|
||||
sprintf(command, "lp -s -oraw -d%s", printer);
|
||||
|
||||
if ((pfile = popen(command, "w")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot print to printer %s with %s\n", printer,
|
||||
command);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
while (bytes < bufpos)
|
||||
{
|
||||
int status = fwrite(printer_cmd + bytes, 1, bufpos - bytes, pfile);
|
||||
if (status == 0)
|
||||
{
|
||||
retries++;
|
||||
if (retries > 2)
|
||||
{
|
||||
fprintf(stderr, "Unable to send command to printer\n");
|
||||
if (raw_device)
|
||||
fclose(pfile);
|
||||
else
|
||||
pclose(pfile);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (status == -1)
|
||||
{
|
||||
fprintf(stderr, "Unable to send command to printer\n");
|
||||
if (raw_device)
|
||||
fclose(pfile);
|
||||
else
|
||||
pclose(pfile);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes += status;
|
||||
retries = 0;
|
||||
}
|
||||
}
|
||||
if (raw_device)
|
||||
fclose(pfile);
|
||||
else
|
||||
pclose(pfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
initialize_print_cmd(void)
|
||||
{
|
||||
bufpos = 0;
|
||||
if (isUSB)
|
||||
{
|
||||
static char hdr[] = "\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@";
|
||||
memcpy(printer_cmd, hdr, sizeof(hdr) - 1); /* Do NOT include the null! */
|
||||
bufpos = sizeof(hdr) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_remote_cmd(char *cmd, int nargs, int a0, int a1, int a2, int a3)
|
||||
{
|
||||
static char remote_hdr[] = "\033@\033(R\010\000\000REMOTE1";
|
||||
static char remote_trailer[] = "\033\000\000\000\033\000";
|
||||
memcpy(printer_cmd + bufpos, remote_hdr, sizeof(remote_hdr) - 1);
|
||||
bufpos += sizeof(remote_hdr) - 1;
|
||||
memcpy(printer_cmd + bufpos, cmd, 2);
|
||||
bufpos += 2;
|
||||
printer_cmd[bufpos] = nargs % 256;
|
||||
printer_cmd[bufpos + 1] = (nargs >> 8) % 256;
|
||||
if (nargs > 0)
|
||||
printer_cmd[bufpos + 2] = a0;
|
||||
if (nargs > 1)
|
||||
printer_cmd[bufpos + 3] = a1;
|
||||
if (nargs > 2)
|
||||
printer_cmd[bufpos + 4] = a2;
|
||||
if (nargs > 3)
|
||||
printer_cmd[bufpos + 5] = a3;
|
||||
bufpos += 2 + nargs;
|
||||
memcpy(printer_cmd + bufpos, remote_trailer, sizeof(remote_trailer) - 1);
|
||||
bufpos += sizeof(remote_trailer) - 1;
|
||||
}
|
||||
|
||||
void
|
||||
add_newlines(int count)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
printer_cmd[bufpos++] = '\r';
|
||||
printer_cmd[bufpos++] = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
add_resets(int count)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
printer_cmd[bufpos++] = '\033';
|
||||
printer_cmd[bufpos++] = '\000';
|
||||
}
|
||||
}
|
||||
|
||||
char *colors[] = {
|
||||
"Black", "Cyan", "Magenta", "Yellow", "Light Cyan", "Light Magenta", 0
|
||||
};
|
||||
|
||||
void
|
||||
do_ink_level(void)
|
||||
{
|
||||
int fd;
|
||||
int status;
|
||||
char buf[1024];
|
||||
char *ind;
|
||||
int i;
|
||||
if (!raw_device)
|
||||
{
|
||||
fprintf(stderr, "Obtaining ink levels requires using a raw device.\n");
|
||||
exit(1);
|
||||
}
|
||||
fd = open(raw_device, O_RDWR, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
fprintf(stderr, "Cannot open %s read/write: %s\n", raw_device,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
do_remote_cmd("IQ", 1, 1, 0, 0, 0);
|
||||
add_resets(2);
|
||||
if (write(fd, printer_cmd, bufpos) < bufpos)
|
||||
{
|
||||
fprintf(stderr, "Cannot write to %s: %s\n", raw_device, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sleep(1);
|
||||
memset(buf, 0, 1024);
|
||||
status = read(fd, buf, 1023);
|
||||
if (status < 0)
|
||||
{
|
||||
fprintf(stderr, "Cannot read from %s: %s\n", raw_device,strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
ind = strchr(buf, 'I');
|
||||
if (!ind || ind[1] != 'Q' || ind[2] != ':')
|
||||
{
|
||||
fprintf(stderr, "Cannot parse output from printer\n");
|
||||
exit(1);
|
||||
}
|
||||
ind += 3;
|
||||
printf("%20s %s\n", "Ink color", "Percent remaining");
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
int val, j;
|
||||
if (!ind[0] || ind[0] == ';')
|
||||
exit(0);
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
if (ind[j] >= '0' && ind[j] <= '9')
|
||||
ind[j] -= '0';
|
||||
else if (ind[j] >= 'A' && ind[j] <= 'F')
|
||||
ind[j] = ind[j] - 'A' + 10;
|
||||
else if (ind[j] >= 'a' && ind[j] <= 'f')
|
||||
ind[j] = ind[j] - 'a' + 10;
|
||||
else
|
||||
exit(1);
|
||||
}
|
||||
val = (ind[0] << 4) + ind[1];
|
||||
printf("%20s %3d\n", colors[i], val);
|
||||
ind += 2;
|
||||
}
|
||||
(void) close(fd);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
do_identify(void)
|
||||
{
|
||||
int fd;
|
||||
int status;
|
||||
char buf[1024];
|
||||
if (!raw_device)
|
||||
{
|
||||
fprintf(stderr, "Printer identification requires using a raw device.\n");
|
||||
exit(1);
|
||||
}
|
||||
fd = open(raw_device, O_RDWR, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
fprintf(stderr, "Cannot open %s read/write: %s\n", raw_device,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
bufpos = 0;
|
||||
sprintf(printer_cmd, "\033\001@EJL ID\r\n");
|
||||
if (write(fd, printer_cmd, strlen(printer_cmd)) < strlen(printer_cmd))
|
||||
{
|
||||
fprintf(stderr, "Cannot write to %s: %s\n", raw_device, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sleep(1);
|
||||
memset(buf, 0, 1024);
|
||||
status = read(fd, buf, 1023);
|
||||
if (status < 0)
|
||||
{
|
||||
fprintf(stderr, "Cannot read from %s: %s\n", raw_device,strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
printf("%s\n", buf);
|
||||
(void) close(fd);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
do_head_clean(void)
|
||||
{
|
||||
do_remote_cmd("CH", 2, 0, 0, 0, 0);
|
||||
printf("Cleaning heads...\n");
|
||||
exit(do_print_cmd());
|
||||
}
|
||||
|
||||
void
|
||||
do_nozzle_check(void)
|
||||
{
|
||||
do_remote_cmd("VI", 2, 0, 0, 0, 0);
|
||||
do_remote_cmd("NC", 2, 0, 0, 0, 0);
|
||||
printf("Running nozzle check, please ensure paper is in the printer.\n");
|
||||
exit(do_print_cmd());
|
||||
}
|
||||
|
||||
char new_align_help[] = "\
|
||||
Please read these instructions very carefully before proceeding.\n\
|
||||
\n\
|
||||
This utility lets you align the print head of your Epson Stylus inkjet\n\
|
||||
printer. Misuse of this utility may cause your print quality to degrade\n\
|
||||
and possibly damage your printer. This utility has not been reviewed by\n\
|
||||
Seiko Epson for correctness, and is offered with no warranty at all. The\n\
|
||||
entire risk of using this utility lies with you.\n\
|
||||
\n\
|
||||
This utility prints %d test patterns. Each pattern looks very similar.\n\
|
||||
The patterns consist of a series of pairs of vertical lines that overlap.\n\
|
||||
Below each pair of lines is a number between %d and %d.\n\
|
||||
\n\
|
||||
When you inspect the pairs of lines, you should find the pair of lines that\n\
|
||||
is best in alignment, that is, that best forms a single vertical line.\n\
|
||||
Inspect the pairs very carefully to find the best match. Using a loupe\n\
|
||||
or magnifying glass is recommended for the most critical inspection.\n\
|
||||
It is also suggested that you use a good quality paper for the test,\n\
|
||||
so that the lines are well-formed and do not spread through the paper.\n\
|
||||
After picking the number matching the best pair, place the paper back in\n\
|
||||
the paper input tray before typing it in.\n\
|
||||
\n\
|
||||
Each pattern is similar, but later patterns use finer dots for more\n\
|
||||
critical alignment. You must run all of the passes to correctly align your\n\
|
||||
printer. After running all the alignment passes, the alignment\n\
|
||||
patterns will be printed once more. You should find that the middle-most\n\
|
||||
pair (#%d out of the %d) is the best for all patterns.\n\
|
||||
\n\
|
||||
After the passes are printed once more, you will be offered the\n\
|
||||
choices of (s)aving the result in the printer, (r)epeating the process,\n\
|
||||
or (q)uitting without saving. Quitting will not restore the previous\n\
|
||||
settings, but powering the printer off and back on will. If you quit,\n\
|
||||
you must repeat the entire process if you wish to later save the results.\n\
|
||||
It is essential that you not turn your printer off during this procedure.\n\n";
|
||||
|
||||
char old_align_help[] = "\
|
||||
Please read these instructions very carefully before proceeding.\n\
|
||||
\n\
|
||||
This utility lets you align the print head of your Epson Stylus inkjet\n\
|
||||
printer. Misuse of this utility may cause your print quality to degrade\n\
|
||||
and possibly damage your printer. This utility has not been reviewed by\n\
|
||||
Seiko Epson for correctness, and is offered with no warranty at all. The\n\
|
||||
entire risk of using this utility lies with you.\n\
|
||||
\n\
|
||||
This utility prints a test pattern that consist of a series of pairs of\n\
|
||||
vertical lines that overlap. Below each pair of lines is a number between\n\
|
||||
%d and %d.\n\
|
||||
\n\
|
||||
When you inspect the pairs of lines, you should find the pair of lines that\n\
|
||||
is best in alignment, that is, that best forms a single vertical align.\n\
|
||||
Inspect the pairs very carefully to find the best match. Using a loupe\n\
|
||||
or magnifying glass is recommended for the most critical inspection.\n\
|
||||
It is also suggested that you use a good quality paper for the test,\n\
|
||||
so that the lines are well-formed and do not spread through the paper.\n\
|
||||
After picking the number matching the best pair, place the paper back in\n\
|
||||
the paper input tray before typing it in.\n\
|
||||
\n\
|
||||
After running the alignment pattern, it will be printed once more. You\n\
|
||||
should find that the middle-most pair (#%d out of the %d) is the best.\n\
|
||||
You will then be offered the choices of (s)aving the result in the printer,\n\
|
||||
(r)epeating the process, or (q)uitting without saving. Quitting will not\n\
|
||||
restore the previous settings, but powering the printer off and back on will.\n\
|
||||
If you quit, you must repeat the entire process if you wish to later save\n\
|
||||
the results. It is essential that you not turn off your printer during\n\
|
||||
this procedure.\n\n";
|
||||
|
||||
void
|
||||
do_align_help(int passes, int choices)
|
||||
{
|
||||
if (passes > 1)
|
||||
printf(new_align_help, passes, 1, choices, (choices + 1) / 2, choices);
|
||||
else
|
||||
printf(old_align_help, 1, choices, (choices + 1) / 2, choices);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void
|
||||
align_error(void)
|
||||
{
|
||||
printf("Unable to send command to the printer, exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the thorny one.
|
||||
*/
|
||||
void
|
||||
do_align(void)
|
||||
{
|
||||
char inbuf[64];
|
||||
long answer;
|
||||
char *endptr;
|
||||
int passes = 0;
|
||||
int choices = 0;
|
||||
int curpass;
|
||||
int notfound = 1;
|
||||
printer_t *printer = &printer_list[0];
|
||||
char *printer_name = NULL;
|
||||
if (!printer_model)
|
||||
{
|
||||
char buf[1024];
|
||||
int fd;
|
||||
int status;
|
||||
char *pos = NULL;
|
||||
char *spos = NULL;
|
||||
if (!raw_device)
|
||||
{
|
||||
printf("Printer alignment must be done with a raw device or else\n");
|
||||
printf("the -m option must be used to specify a printer.\n");
|
||||
do_help(1);
|
||||
}
|
||||
printf("Attempting to detect printer model...");
|
||||
fflush(stdout);
|
||||
fd = open(raw_device, O_RDWR, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
fprintf(stderr, "\nCannot open %s read/write: %s\n", raw_device,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
bufpos = 0;
|
||||
sprintf(printer_cmd, "\033\001@EJL ID\r\n");
|
||||
if (write(fd, printer_cmd, strlen(printer_cmd)) < strlen(printer_cmd))
|
||||
{
|
||||
fprintf(stderr, "\nCannot write to %s: %s\n", raw_device,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sleep(1);
|
||||
memset(buf, 0, 1024);
|
||||
status = read(fd, buf, 1023);
|
||||
if (status < 0)
|
||||
{
|
||||
fprintf(stderr, "\nCannot read from %s: %s\n", raw_device,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
(void) close(fd);
|
||||
pos = strchr(buf, (int) ';');
|
||||
if (pos)
|
||||
pos = strchr(pos + 1, (int) ';');
|
||||
if (pos)
|
||||
pos = strchr(pos, (int) ':');
|
||||
if (pos)
|
||||
spos = strchr(pos, (int) ';');
|
||||
if (!pos)
|
||||
{
|
||||
fprintf(stderr, "\nCannot detect printer type. Please use -m to specify your printer model.\n");
|
||||
do_help(1);
|
||||
}
|
||||
if (spos)
|
||||
*spos = '\000';
|
||||
printer_model = pos + 1;
|
||||
printf("%s\n\n", printer_model);
|
||||
}
|
||||
while (printer->short_name && notfound)
|
||||
{
|
||||
if (!strcmp(printer_model, printer->short_name) ||
|
||||
!strcmp(printer_model, printer->long_name))
|
||||
{
|
||||
passes = printer->passes;
|
||||
choices = printer->choices;
|
||||
printer_name = printer->long_name;
|
||||
notfound = 0;
|
||||
}
|
||||
else
|
||||
printer++;
|
||||
}
|
||||
if (notfound)
|
||||
{
|
||||
printf("Printer model %s is not known.\n", printer_model);
|
||||
do_help(1);
|
||||
}
|
||||
|
||||
start:
|
||||
do_align_help(passes, choices);
|
||||
printf("This procedure assumes that your printer is an Epson %s.\n",
|
||||
printer_name);
|
||||
printf("If this is not your printer model, please type control-C now and\n");
|
||||
printf("choose your actual printer model.\n");
|
||||
printf("\n");
|
||||
printf("Please place a sheet of paper in your printer to begin the head\n");
|
||||
printf("alignment procedure.\n");
|
||||
memset(inbuf, 0, 64);
|
||||
fflush(stdin);
|
||||
fgets(inbuf, 63, stdin);
|
||||
putc('\n', stdout);
|
||||
fflush(stdout);
|
||||
initialize_print_cmd();
|
||||
for (curpass = 1; curpass <= passes; curpass ++)
|
||||
{
|
||||
top:
|
||||
add_newlines(7 * (curpass - 1));
|
||||
do_remote_cmd("DT", 3, 0, curpass - 1, 0, 0);
|
||||
if (do_print_cmd())
|
||||
align_error();
|
||||
reread:
|
||||
printf("Please inspect the print, and choose the best pair of lines\n");
|
||||
if (curpass == passes)
|
||||
printf("in pattern #%d, and then insert a fresh page in the input tray.\n",
|
||||
curpass);
|
||||
else
|
||||
printf("in pattern #%d, and then reinsert the page in the input tray.\n",
|
||||
curpass);
|
||||
printf("Type a pair number, '?' for help, or 'r' to retry this pattern. ==> ");
|
||||
fflush(stdout);
|
||||
memset(inbuf, 0, 64);
|
||||
fflush(stdin);
|
||||
fgets(inbuf, 63, stdin);
|
||||
putc('\n', stdout);
|
||||
switch (inbuf[0])
|
||||
{
|
||||
case 'r':
|
||||
case 'R':
|
||||
printf("Please insert a fresh sheet of paper, and then type the enter key.\n");
|
||||
initialize_print_cmd();
|
||||
fflush(stdin);
|
||||
fgets(inbuf, 15, stdin);
|
||||
putc('\n', stdout);
|
||||
fflush(stdout);
|
||||
goto top;
|
||||
case 'h':
|
||||
case '?':
|
||||
do_align_help(passes, choices);
|
||||
fflush(stdout);
|
||||
case '\n':
|
||||
case '\000':
|
||||
goto reread;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
answer = strtol(inbuf, &endptr, 10);
|
||||
if (endptr == inbuf)
|
||||
{
|
||||
printf("I cannot understand what you typed!\n");
|
||||
fflush(stdout);
|
||||
goto reread;
|
||||
}
|
||||
if (answer < 1 || answer > choices)
|
||||
{
|
||||
printf("The best pair of lines should be numbered between 1 and %d.\n",
|
||||
choices);
|
||||
fflush(stdout);
|
||||
goto reread;
|
||||
}
|
||||
if (curpass == passes)
|
||||
{
|
||||
printf("Aligning phase %d, and performing final test.\n", curpass);
|
||||
printf("Please insert a fresh sheet of paper.\n");
|
||||
}
|
||||
else
|
||||
printf("Aligning phase %d, and starting phase %d.\n", curpass,
|
||||
curpass + 1);
|
||||
fflush(stdout);
|
||||
initialize_print_cmd();
|
||||
do_remote_cmd("DA", 4, 0, curpass - 1, 0, answer);
|
||||
}
|
||||
for (curpass = 0; curpass < passes; curpass++)
|
||||
do_remote_cmd("DT", 3, 0, curpass, 0, 0);
|
||||
if (do_print_cmd())
|
||||
align_error();
|
||||
read_final:
|
||||
printf("Please inspect the final output very carefully to ensure that your\n");
|
||||
printf("printer is in proper alignment. You may now (s)ave the results in\n");
|
||||
printf("the printer, (q)uit without saving the results, or (r)epeat the entire\n");
|
||||
printf("process from the beginning. You will then be asked to confirm your choice\n");
|
||||
printf("What do you want to do (s, q, r)? ");
|
||||
fflush(stdout);
|
||||
memset(inbuf, 0, 64);
|
||||
fflush(stdin);
|
||||
fgets(inbuf, 15, stdin);
|
||||
putc('\n', stdout);
|
||||
switch (inbuf[0])
|
||||
{
|
||||
case 'q':
|
||||
case 'Q':
|
||||
printf("Please confirm by typing 'q' again that you wish to quit without saving: ");
|
||||
fflush(stdout);
|
||||
memset(inbuf, 0, 64);
|
||||
fflush(stdin);
|
||||
putc('\n', stdout);
|
||||
fgets(inbuf, 15, stdin);
|
||||
if (inbuf[0] == 'q' || inbuf[0] == 'Q')
|
||||
{
|
||||
printf("OK, your printer is aligned, but the alignment has not been saved.\n");
|
||||
printf("If you wish to save the alignment, you must repeat this process.\n");
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
printf("Please confirm by typing 'r' again that you wish to repeat the\n");
|
||||
printf("alignment process: ");
|
||||
fflush(stdout);
|
||||
memset(inbuf, 0, 64);
|
||||
fflush(stdin);
|
||||
putc('\n', stdout);
|
||||
fgets(inbuf, 15, stdin);
|
||||
if (inbuf[0] == 'r' || inbuf[0] == 'R')
|
||||
{
|
||||
printf("Repeating the alignment process.\n");
|
||||
goto start;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
printf("Please confirm by typing 's' again that you wish to save the settings\n");
|
||||
printf("to your printer. This will permanently alter the configuration of\n");
|
||||
printf("your printer. WARNING: this procedure has not been approved by\n");
|
||||
printf("Seiko Epson, and it may damage your printer. Proceed? ");
|
||||
|
||||
fflush(stdout);
|
||||
memset(inbuf, 0, 64);
|
||||
fflush(stdin);
|
||||
putc('\n', stdout);
|
||||
fgets(inbuf, 15, stdin);
|
||||
if (inbuf[0] == 's' || inbuf[0] == 'S')
|
||||
{
|
||||
printf("Please insert your alignment test page in the printer once more\n");
|
||||
printf("for the final save of your alignment settings. When the printer\n");
|
||||
printf("feeds the page through, your settings have been saved.\n");
|
||||
fflush(stdout);
|
||||
initialize_print_cmd();
|
||||
add_newlines(2);
|
||||
do_remote_cmd("SV", 0, 0, 0, 0, 0);
|
||||
add_newlines(2);
|
||||
if (do_print_cmd())
|
||||
align_error();
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("Unrecognized command.\n");
|
||||
goto read_final;
|
||||
}
|
||||
printf("Final command was not confirmed.\n");
|
||||
goto read_final;
|
||||
}
|
||||
Loading…
Reference in a new issue