2 * Epson Inkjet Printer Driver (ESC/P-R) for Linux
3 * Copyright (C) 2002-2005 AVASYS CORPORATION.
4 * Copyright (C) Seiko Epson Corporation 2002-2012.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA.
25 #include <cups/cups.h>
27 #include <cups/raster.h>
34 /* added 22-04-2004 */
39 #define WIDTH_BYTES(bits) (((bits) + 31) / 32 * 4)
41 #define PIPSLITE_WRAPPER_VERSION "* epson-escpr-wrapepr is a part of " PACKAGE_STRING
44 typedef struct rtp_filter_option {
45 char model[NAME_MAX + 1];
46 char model_low[NAME_MAX + 1];
47 char ink[NAME_MAX + 1];
48 char media[NAME_MAX + 1];
49 char quality[NAME_MAX + 1];
50 char duplex[NAME_MAX + 1];
53 /* Static functions */
54 static int get_option_for_ppd (const char *, filter_option_t *);
55 static int get_option_for_arg (const char *, filter_option_t *);
56 /* Get value for PPD. */
57 static char * get_default_choice (ppd_file_t *, const char *);
59 /* added 22-04-2004 */
60 static void sig_set (void);
61 static void sigterm_handler (int sig);
66 #define DEBUG_PATH "/tmp/eps_wrapper.txt"
67 static FILE *debug_f = NULL;
69 static void debug_msg(const char *fmt, ...){
74 debug_f = fopen(DEBUG_PATH, "wb");
78 fchmod (fileno (debug_f), 0777);
82 vfprintf (debug_f, fmt, ap);
90 * $$$ CUPS Filter Options $$$
92 * printer - The name of the printer queue
93 * (normally this is the name of the program being run)
94 * job - The numeric job ID for the job being printed
95 * user - The string from the originating-user-name attribute
96 * title - The string from the job-name attribute
97 * copies - The numeric value from the number-copies attribute
98 * options - String representations of the job template attributes, separated
99 * by spaces. Boolean attributes are provided as "name" for true
100 * values and "noname" for false values. All other attributes are
101 * provided as "name=value" for single-valued attributes and
102 * "name=value1,value2,...,valueN" for set attributes
103 * filename - The request file
106 main (int argc, char *argv[])
108 int fd; /* file descriptor */
111 cups_raster_t *ras; /* raster stream for printing */
112 cups_page_header_t header; /* page device dictionary header */
113 filter_option_t fopt;
118 while (flag) sleep (3);
119 #endif /* USE_DEBUGGER */
123 memset (&fopt, 0, sizeof (filter_option_t));
124 /* added 22-04-2004 */
127 if (argc < 6 || argc > 7)
129 for ( i = 1; i < argc; i++ ) {
130 if ( (0 == strncmp(argv[i], "-v", (strlen("-v")+1)) )
131 || (0 == strncmp(argv[i], "--version", (strlen("--version")+1)) )
133 fprintf(stderr, "%s\n", PIPSLITE_WRAPPER_VERSION);
135 } else if ( (0 == strncmp(argv[i], "-h", (strlen("-h")+1)) )
136 || (0 == strncmp(argv[i], "--help", (strlen("--help")+1)) )
138 fprintf(stderr, "%s\n", PIPSLITE_WRAPPER_VERSION);
142 fprintf (stderr, "Insufficient options.\n");
148 fd = open (argv[6], O_RDONLY);
160 if (get_option_for_arg (argv[5], &fopt))
162 fprintf (stderr, "Cannot read filter option. Cannot get option of PIPS.");
163 debug_msg("Cannot read filter option. Cannot get option of PIPS.");
166 if (get_option_for_ppd (argv[0], &fopt))
168 fprintf (stderr, "PPD file not found, or PPD file is broken. Cannot get option of PIPS.");
169 debug_msg("PPD file not found, or PPD file is broken. Cannot get option of PIPS.");
173 ras = cupsRasterOpen (fd, CUPS_RASTER_READ);
176 fprintf (stderr, "Can't open CUPS raster file.");
177 debug_msg("Can't open CUPS raster file");
182 while (cupsRasterReadHeader (ras, &header) && !cancel_flg)
192 sprintf (tmpbuf, "%s/%s \"%s\" %d %d %d %s %s %s %s",
198 header.HWResolution[0],
204 debug_msg("tmpbuf = [%s]\n", tmpbuf);
205 pfp = popen (tmpbuf, "w");
209 debug_msg("popen error");
215 image_bytes = WIDTH_BYTES(header.cupsBytesPerLine * 8);
216 image_raw = (char *)calloc (sizeof (char), image_bytes);
218 for (i = 0; i < header.cupsHeight && !cancel_flg; i ++)
220 if (!cupsRasterReadPixels (ras, (unsigned char*)image_raw, header.cupsBytesPerLine))
222 fprintf (stderr, "cupsRasterReadPixels");
223 debug_msg("cupsRasterReadPixels error");
227 write_size = fwrite (image_raw, image_bytes, 1, pfp);
231 debug_msg("fwrite error");
240 cupsRasterClose (ras);
246 get_option_for_ppd (const char *printer, filter_option_t *filter_opt_p)
248 char *ppd_path; /* Path of PPD */
249 ppd_file_t *ppd_p; /* Struct of PPD */
250 char *opt; /* Temporary buffer (PPD option) */
253 /* Get option from PPD. */
254 ppd_path = (char *) cupsGetPPD (printer);
255 ppd_p = ppdOpenFile (ppd_path);
260 /* Make library file name */
261 strcpy (filter_opt_p->model, ppd_p->modelname);
262 for (i = 0; filter_opt_p->model[i] != '\0' && i < NAME_MAX; i ++)
263 filter_opt_p->model_low[i] = tolower (filter_opt_p->model[i]);
264 filter_opt_p->model_low[i] = '\0';
267 if (filter_opt_p->media[0] == '\0')
269 opt = get_default_choice (ppd_p, "PageSize");
273 strcpy (filter_opt_p->media, opt);
277 if (filter_opt_p->ink[0] == '\0')
279 opt = get_default_choice (ppd_p, "Ink");
283 strcpy (filter_opt_p->ink, opt);
287 if (filter_opt_p->quality[0] == '\0')
289 opt = get_default_choice (ppd_p, "Quality");
293 strcpy (filter_opt_p->quality, opt);
297 if (filter_opt_p->duplex[0] == '\0')
299 opt = get_default_choice (ppd_p, "Duplex");
302 debug_msg("can not get duplex\n");
303 strcpy (filter_opt_p->duplex, "None");
307 strcpy (filter_opt_p->duplex, opt);
310 #ifdef INK_CHANGE_SYSTEM
312 if (filter_opt_p->inkset[0] == '\0')
314 opt = get_default_choice (ppd_p, "InkSet");
318 strcpy (filter_opt_p->inkset, opt);
328 get_option_for_arg (const char *opt_str, filter_option_t *filter_opt_p)
331 cups_option_t *option_p;
334 const char *media_names[] = { "PageSize", "PageRegion", "media", "" };
337 if (strlen (opt_str) == 0)
342 opt_num = cupsParseOptions (opt_str, opt_num, &option_p);
344 for (i = 0; *media_names[i] != '\0'; i ++) /* chenged Wed Jan 28 2009 */
346 opt = cupsGetOption (media_names[i], opt_num, option_p);
351 num = strcspn (opt, ",");
352 if (num >= PPD_MAX_NAME)
357 strncpy (filter_opt_p->media, opt, num);
358 filter_opt_p->media[num] = '\0';
364 opt = cupsGetOption ("Ink", opt_num, option_p);
366 strcpy (filter_opt_p->ink, opt);
368 opt = cupsGetOption ("Quality", opt_num, option_p);
371 strcpy (filter_opt_p->quality, opt);
372 debug_msg("Quality = [%s]\n", opt);
375 opt = cupsGetOption ("Duplex", opt_num, option_p);
377 strcpy (filter_opt_p->duplex, opt);
383 /* Get value for PPD */
385 get_default_choice (ppd_file_t *ppd_p, const char *key)
387 ppd_option_t *option;
388 ppd_choice_t *choice;
390 option = ppdFindOption (ppd_p, key);
394 choice = ppdFindChoice (option, option->defchoice);
398 return choice->choice;
405 #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
406 sigset (SIGTERM, sigterm_handler);
407 #elif defined(HAVE_SIGACTION)
409 struct sigaction action;
411 memset (&action, 0, sizeof(action));
413 sigemptyset (&action.sa_mask);
414 action.sa_handler = sigterm_handler;
415 sigaction (SIGTERM, &action, NULL);
418 signal (SIGTERM, sigterm_handler);
419 #endif /* HAVE_SIGSET */
426 sigterm_handler (int sig)