wip
author"Luc Saillard <luc@saillard.org>"
Tue Jun 03 19:45:58 2008 +0200 (5 months ago)
changeset 509e373da444a2
parent 49dca72f92aa03
child 51096867bc19cd
wip
po/9lpr.pot
src/9lpr.c
src/foomatic-rip.c
src/ppd.c
--- a/po/9lpr.pot Mon Jun 02 16:52:11 2008 +0200
+++ b/po/9lpr.pot Tue Jun 03 19:45:58 2008 +0200
@@ -7,7 +7,7 @@ msgstr ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-06 10:49+0200\n"
+"POT-Creation-Date: 2008-06-03 14:35+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -15,25 +15,25 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/9lpr.c:213
+#: src/9lpr.c:227
msgid "PPD is invalid\n"
msgstr ""
-#: src/9lpr.c:218
+#: src/9lpr.c:232
msgid "PPD is correct\n"
msgstr ""
-#: src/9lpr.c:232
+#: src/9lpr.c:246
msgid ""
"No printer has been detected.\n"
"Perhaps you have a model that is not supported or the cable is not plugged.\n"
msgstr ""
-#: src/9lpr.c:241
+#: src/9lpr.c:255
msgid "You choose to print on stdout, but no PPD has been selected."
msgstr ""
-#: src/9lpr.c:257
+#: src/9lpr.c:271 src/9lpr.c:284
#, c-format
msgid ""
"The printer '%s' is not recognized.\n"
@@ -41,7 +41,7 @@ msgid ""
"used\n"
msgstr ""
-#: src/9lpr.c:266
+#: src/9lpr.c:294
#, c-format
msgid ""
"The printer '%s' cannot be used for printing.\n"
@@ -49,7 +49,7 @@ msgid ""
"the print."
msgstr ""
-#: src/9lpr.c:275
+#: src/9lpr.c:302
#, c-format
msgid ""
"The printer '%s' cannot be used for printing.\n"
@@ -60,14 +60,14 @@ msgid ""
"<i>%s</i>"
msgstr ""
-#: src/9lpr.c:287
+#: src/9lpr.c:315
#, c-format
msgid ""
"Printer error\n"
"The PPD \"%s\" is an invalid PPD or it can't be loaded."
msgstr ""
-#: src/9lpr.c:309 src/9lpr.c:318
+#: src/9lpr.c:337 src/9lpr.c:346
msgid ""
"Printing error\n"
"An unknown error occured while printing."
@@ -273,7 +273,7 @@ msgid "Realign heads"
msgid "Realign heads"
msgstr ""
-#: src/gui.c:156 src/gui.c:165 src/gui.c:899
+#: src/gui.c:156 src/gui.c:165 src/gui.c:892
msgid "Ink Levels"
msgstr ""
@@ -285,61 +285,61 @@ msgid "Not implemented"
msgid "Not implemented"
msgstr ""
-#: src/gui.c:454
+#: src/gui.c:447
msgid "This printer was not found for this printer."
msgstr ""
+#: src/gui.c:453
+msgid "No PPD was found for this printer."
+msgstr ""
+
#: src/gui.c:460
-msgid "No PPD was found for this printer."
-msgstr ""
-
-#: src/gui.c:467
msgid "The PPD is invalid."
msgstr ""
-#: src/gui.c:572
+#: src/gui.c:565
msgid "Select your printer:"
msgstr ""
-#: src/gui.c:605
+#: src/gui.c:598
msgid "Printers"
msgstr ""
-#: src/gui.c:621
+#: src/gui.c:614
msgid "Paper Settings"
msgstr ""
-#: src/gui.c:677
+#: src/gui.c:670
msgid "Options"
msgstr ""
-#: src/gui.c:713
+#: src/gui.c:706
msgid "Maintenance"
msgstr ""
-#: src/gui.c:860
+#: src/gui.c:853
msgid "Advanced Options"
msgstr ""
-#: src/gui.c:976
+#: src/gui.c:969
msgid "_Cancel"
msgstr ""
-#: src/gui.c:982
+#: src/gui.c:975
msgid "_Print"
msgstr ""
-#: src/gui.c:1073
+#: src/gui.c:1053
msgid "No printers detected."
msgstr ""
-#: src/ppd.c:313
+#: src/ppd.c:315
msgid ""
"Invalid syntax in PPD file.\n"
"A keyword must begin with a '*'."
msgstr ""
-#: src/ppd.c:472
+#: src/ppd.c:474
#, c-format
msgid ""
"Invalid PPD file.\n"
--- a/src/9lpr.c Mon Jun 02 16:52:11 2008 +0200
+++ b/src/9lpr.c Tue Jun 03 19:45:58 2008 +0200
@@ -33,6 +33,7 @@
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
+#include <locale.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
@@ -128,12 +129,10 @@ int main(int argc, char **argv)
if (strcmp(argv[0], "9lpr-gui") == 0)
opt_gui = 1;
-#if ENABLE_NLS
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
bind_textdomain_codeset(PACKAGE, "UTF-8");
textdomain(PACKAGE);
-#endif
#ifdef HAVE_GETOPT_LONG
while ((opt = getopt_long(argc, argv, short_options, long_options, &option_index)) != EOF)
--- a/src/foomatic-rip.c Mon Jun 02 16:52:11 2008 +0200
+++ b/src/foomatic-rip.c Tue Jun 03 19:45:58 2008 +0200
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <locale.h>
#include "ppd.h"
@@ -39,7 +40,6 @@ static const char *cups_filters_path = "
static const char *cups_filters_path = "/usr/lib/cups/filter";
static const char *ghostscript_for_cups = "gs -dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH -dNOMEDIAATTRS -sDEVICE=cups -sOutputFile=-%W -";
-static int opt_ps_accounting = 1;
static int opt_debug;
static int opt_print_version;
static int opt_verbose;
@@ -53,7 +53,7 @@ static char *job_title;
static char *job_title;
static char *job_user;
static int copies;
-static char *job_options;
+static GList *job_options;
static char *cups_filter_command;
@@ -61,7 +61,7 @@ static char *cups_filter_command;
-static int parse_options(int *argc, char ***argv);
+static int common_parse_options(int *argc, char ***argv);
static char *string_remove_shell_escapes(char *string);
static char *string_replace_markers(const char *string,
const char *cups_options_string,
@@ -72,6 +72,7 @@ static int cups_setup_with_ppd(struct p
static int cups_setup_with_ppd(struct ppd_t *ppd);
static char *cups_get_filter_from_mime_type(const char *mime_type, const char *program);
static char *cups_get_filter_command(struct ppd_t *ppd);
+static int send_job_to_ghostscript(const char *input_document, char **gs_argv);
void die(const char *fmt, ...);
void error(const char *fmt, ... );
@@ -109,104 +110,6 @@ void error(const char *fmt, ... ) GCC_AT
-#if 0
-static char postscript_accounting_prolog[] = "[{"
-"%% Code for writing CUPS accounting tags on standard error"
-""
-"/cupsPSLevel2 % Determine whether we can do PostScript level 2 or newer"
-" systemdict/languagelevel 2 copy"
-" known{get exec}{pop pop 1}ifelse 2 ge"
-"def"
-""
-"cupsPSLevel2"
-"{ % in case of level 2 or higher"
-" currentglobal true setglobal % define a dictioary foomaticDict"
-" globaldict begin % in global VM and establish a"
-" /foomaticDict % pages count key there"
-" <<"
-" /PhysPages 0"
-" >>def"
-" end"
-" setglobal"
-"}if"
-""
-"/cupsGetNumCopies { % Read the number of Copies requested for the current"
-" % page"
-" cupsPSLevel2"
-" {"
-" % PS Level 2+: Get number of copies from Page Device dictionary"
-" currentpagedevice /NumCopies get"
-" }"
-" {"
-" % PS Level 1: Number of copies not in Page Device dictionary"
-" null"
-" }"
-" ifelse"
-" % Check whether the number is defined, if it is \"null\" use #copies "
-" % instead"
-" dup null eq {"
-" pop #copies"
-" }"
-" if"
-" % Check whether the number is defined now, if it is still \"null\" use 1"
-" % instead"
-" dup null eq {"
-" pop 1"
-" } if"
-"} bind def"
-""
-"/cupsWrite { % write a string onto standard error"
-" (%stderr) (w) file"
-" exch writestring"
-"} bind def"
-""
-"/cupsFlush % flush standard error to make it sort of unbuffered"
-"{"
-" (%stderr)(w)file flushfile"
-"}bind def"
-""
-"cupsPSLevel2"
-"{ % In language level 2, we try to do something reasonable"
-" <<"
-" /EndPage"
-" [ % start the array that becomes the procedure"
-" currentpagedevice/EndPage 2 copy known"
-" {get} % get the existing EndPage procedure"
-" {pop pop {exch pop 2 ne}bind}ifelse % there is none, define the default"
-" /exec load % make sure it will be executed, whatever it is"
-" /dup load % duplicate the result value"
-" { % true: a sheet gets printed, do accounting"
-" currentglobal true setglobal % switch to global VM ..."
-" foomaticDict begin % ... and access our special dictionary"
-" PhysPages 1 add % count the sheets printed (including this one)"
-" dup /PhysPages exch def % and save the value"
-" end % leave our dict"
-" exch setglobal % return to previous VM"
-" (PAGE: )cupsWrite % assemble and print the accounting string ..."
-" 16 string cvs cupsWrite % ... the sheet count ..."
-" ( )cupsWrite % ... a space ..."
-" cupsGetNumCopies % ... the number of copies ..."
-" 16 string cvs cupsWrite % ..."
-" (\\n)cupsWrite % ... a newline"
-" cupsFlush"
-" }/if load"
-" % false: current page gets discarded; do nothing "
-" ]cvx bind % make the array executable and apply bind"
-" >>setpagedevice"
-"}"
-"{"
-" % In language level 1, we do no accounting currently, as there is no global VM"
-" % the contents of which are undesturbed by save and restore. "
-" % If we may be sure that showpage never gets called inside a page related save / restore pair"
-" % we might implement an hack with showpage similar to the one above."
-"}ifelse"
-""
-"} stopped cleartomark"
-"";
-#endif
-
-
-
@@ -217,13 +120,15 @@ main(int argc, char **argv)
main(int argc, char **argv)
{
struct ppd_t *ppd = NULL;
+ int gs_argc;
+ char **gs_argv;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
bind_textdomain_codeset(PACKAGE, "UTF-8");
textdomain(PACKAGE);
- parse_options(&argc, &argv);
+ common_parse_options(&argc, &argv);
if (opt_spooler != SPOOLER_CUPS)
{
@@ -231,19 +136,29 @@ main(int argc, char **argv)
exit(1);
}
- cups_setup_font_path_for_ghostscript();
cups_get_parameters(argc, argv);
ppd = load_and_parse_ppd(opt_ppdfile);
if (ppd == NULL)
die("PPD %s can't be parse\n", opt_ppdfile);
+ ppd_set_default_options(ppd);
+ ppd_set_options(ppd, job_options);
+
if (opt_debug)
- ppd_print_options(ppd);
+ {
+ ppd_print_options(ppd);
+ }
cups_setup_with_ppd(ppd);
+ ppd_build_gs_cmd_line(ppd, &gs_argc, &gs_argv);
+
+ cups_setup_font_path_for_ghostscript();
+
trace("printer command line = %s\n", cups_filter_command);
+
+ send_job_to_ghostscript(job_filename, gs_argv);
return 0;
@@ -269,7 +184,7 @@ static GOptionEntry entries[] =
* run the filter.
*/
static int
-parse_options(int *argc, char ***argv)
+common_parse_options(int *argc, char ***argv)
{
const char *env_PPD;
GError *gerror = NULL;
@@ -342,10 +257,14 @@ cups_setup_font_path_for_ghostscript(voi
const char *env_cups_fontpath, *env_gs_lib, *env_cups_datadir;
char *new_env = NULL;
+
/* set font path for ghostscript */
env_cups_fontpath = getenv("CUPS_FONTPATH");
env_cups_datadir = getenv("CUPS_DATADIR");
env_gs_lib = getenv("GS_LIB");
+ if (env_gs_lib == NULL)
+ env_gs_lib = "/usr/share/fonts/type1/gsfonts/";
+
if (env_cups_fontpath)
{
if (env_gs_lib)
@@ -369,10 +288,63 @@ cups_setup_font_path_for_ghostscript(voi
}
}
+
+/*
+ * Split a string into token like this:
+ *
+ * "PrintoutMode=Normal PageSize=A4 Quality=300GrayscaleK number-up=1 job-uuid=urn:c7ca740b-d33d-4cf5-a1fb-714b4c878726"
+ *
+ * PrintoutMode: Normal
+ * PageSize: A4
+ * Quality: 300GrayscaleK
+ * number-up: 1
+ * job-uuid: urn:c7ca740b-d33d-4cf5-a1fb-714b4c878726
+ *
+ */
+static GList *
+cups_split_options_parameters(const char *options)
+{
+ char **options_splitted, **key_value;
+ unsigned int i;
+ GList *list = NULL;
+
+ if (options == NULL)
+ return NULL;
+
+ if (strlen(options) == 0)
+ return NULL;
+
+ trace("options: %s\n", options);
+
+ options_splitted = g_strsplit(options, " ", -1);
+ for (i=0; options_splitted[i]; i++)
+ {
+ struct ppd_option *option = g_new0(struct ppd_option, 1);
+
+ if (strchr(options_splitted[i], '='))
+ {
+ key_value = g_strsplit(options_splitted[i], "=", 2);
+ option->name = key_value[0];
+ option->value = key_value[1];
+ g_free(key_value);
+ }
+ else
+ {
+ option->name = key_value[0];
+ option->value = g_strdup("");
+ }
+
+ list = g_list_prepend(list, option);
+ }
+
+ g_strfreev(options_splitted);
+
+ return list;
+}
+
static void
cups_get_parameters(int argc, char **argv)
{
-
if (argc < 6 || argc > 7)
{
error("Usage: %s job-id user title copies options [file]\n", PACKAGE_NAME);
@@ -383,7 +355,7 @@ cups_get_parameters(int argc, char **arg
job_user = string_remove_shell_escapes(g_strdup(argv[2]));
job_title = string_remove_shell_escapes(g_strdup(argv[3]));
copies = g_ascii_strtoll(argv[4], NULL, 10);
- job_options = g_strdup(argv[5]);
+ job_options = cups_split_options_parameters(argv[5]);
if (argc == 7)
{
@@ -398,28 +370,26 @@ cups_get_parameters(int argc, char **arg
job_filename = NULL;
- trace("job_options = %s\n", job_options);
-
-
- /* TODO: Try to get the printer spooler, from the ppdfile, because cups name it
- * with the same name */
+ if (1)
+ {
+ GList *list = job_options;
+ trace("job_options:\n");
+ while (list)
+ {
+ struct ppd_option *option = list->data;
+ trace(" %s=%s\n", option->name, option->value);
+
+ list = list->next;
+ }
+ }
}
static int
cups_setup_with_ppd(struct ppd_t *ppd)
{
- const char *foomatic_no_page_accounting;
char *cups_option_string;
char *cups_filter_command_template;
-
- /* Disable accounting ? */
- foomatic_no_page_accounting = ppd_get_option_value_by_keyword_name(ppd, "FoomaticNoPageAccounting");
- if (foomatic_no_page_accounting)
- {
- if (strcmp(foomatic_no_page_accounting, "True") == 0)
- opt_ps_accounting = 0;
- }
/* Get the filter command line to use */
cups_filter_command_template = cups_get_filter_command(ppd);
@@ -503,12 +473,131 @@ cups_get_filter_from_mime_type(const cha
else
{
error("Unsupported cups mime-type filter (%s)\n", mime_type);
- filter_command = "cat %%A %%B %%C %%D %%E %%F %%G %%H %%I %%J %%K %%L %%M %%Z";
+ filter_command = g_strdup_printf("cat %%A %%B %%C %%D %%E %%F %%G %%H %%I %%J %%K %%L %%M %%Z");
}
return filter_command;
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**
+ * Print the filename input_document, and output the result to filedescriptor
+ * output_printer_fd
+ */
+static int
+send_job_to_ghostscript(const char *input_document, char **gs_argv)
+{
+ GError *gerror;
+ gboolean status;
+ char *gs_stdout;
+ char *gs_stderr;
+ int gs_exit_status;
+
+#if 0
+ /* If the filename is not defined, then read the stdin */
+ if (input_document == NULL)
+ input_fd = STDIN_FILENO;
+ else
+ {
+ input_fd = open(input_document, O_RDONLY);
+ if (input_fd < 0)
+ {
+ error("Can't open file %s\n", input_document);
+ return -1;
+ }
+ }
+#endif
+
+ if (0)
+ {
+ unsigned int i;
+ trace("argv:\n");
+ for (i=0; gs_argv[i]; i++)
+ {
+ if (strcmp(gs_argv[i], "-dQUIET") == 0)
+ gs_argv[i] = g_strdup("-dSAFER");
+ else if (strcmp(gs_argv[i], "-q") == 0)
+ gs_argv[i] = g_strdup("-dSAFER");
+ }
+ }
+
+ if (opt_verbose)
+ {
+ unsigned int i;
+ trace("argv:\n");
+ for (i=0; gs_argv[i]; i++)
+ {
+ trace(" %s\n", gs_argv[i]);
+ }
+ }
+
+
+ status = g_spawn_sync(NULL, /* working_directory */
+ gs_argv, /* argv */
+ NULL, /* envp */
+ G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN, /* flags */
+ NULL, /* child_setup */
+ NULL, /* user_data */
+ &gs_stdout, /* standard_output */
+ &gs_stderr, /* standard_error */
+ &gs_exit_status, /* exit_status */
+ &gerror);
+
+ if (status == FALSE)
+ {
+ trace("g_spawn_sync failed: %s\n", gerror->message);
+ trace("standard_output:\n%s\n", gs_stdout);
+ trace("standard_error:\n%s\n", gs_stderr);
+ g_error_free(gerror);
+ g_free(gs_stdout);
+ g_free(gs_stderr);
+ return -1;
+ }
+
+ trace("exit_status = %d\n", gs_exit_status);
+
+ /* Job terminated */
+ trace("standard_output:\n%s\n", gs_stdout);
+ trace("gs_stderr:\n%s\n", gs_stderr);
+
+ g_free(gs_stdout);
+ g_free(gs_stderr);
+
+ return 0;
+}
--- a/src/ppd.c Mon Jun 02 16:52:11 2008 +0200
+++ b/src/ppd.c Tue Jun 03 19:45:58 2008 +0200
@@ -36,6 +36,7 @@
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
+#include <locale.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
@@ -1485,6 +1486,7 @@ ppd_build_gs_cmd_line(struct ppd_t *ppd,
/* strip out all of the %n's from the command line prototype */
foomatic_cmd_line = ppd_cleanup_string(new_cmdline, 1);
+ trace("foomatic_cmd_line=\"%s\"\n", foomatic_cmd_line);
g_shell_parse_argv(foomatic_cmd_line, argc_output, argv_output, &gerror);
if (gerror)