]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/emit.c
2 * "$Id: emit.c,v 1.25 2002/01/02 17:58:38 mike Exp $"
4 * PPD code emission routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2002 by Easy Software Products, all rights reserved.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * PostScript is a trademark of Adobe Systems, Inc.
28 * ppdCollect() - Collect all marked options that reside in the specified
29 * ppdEmit() - Emit code for marked options to a file.
30 * ppdEmitFd() - Emit code for marked options to a file.
31 * ppdEmitJCL() - Emit code for JCL options to a file.
32 * ppd_sort() - Sort options by ordering numbers...
36 * Include necessary headers...
43 #if defined(WIN32) || defined(__EMX__)
47 #endif /* WIN32 || __EMX__ */
54 static int ppd_sort(ppd_choice_t
**c1
, ppd_choice_t
**c2
);
58 * 'ppdCollect()' - Collect all marked options that reside in the specified
62 int /* O - Number of options marked */
63 ppdCollect(ppd_file_t
*ppd
, /* I - PPD file data */
64 ppd_section_t section
, /* I - Section to collect */
65 ppd_choice_t
***choices
) /* O - Pointers to choices */
67 int i
, j
, k
, m
; /* Looping vars */
68 ppd_group_t
*g
, /* Current group */
69 *sg
; /* Current sub-group */
70 ppd_option_t
*o
; /* Current option */
71 ppd_choice_t
*c
; /* Current choice */
72 int count
; /* Number of choices collected */
73 ppd_choice_t
**collect
; /* Collected choices */
80 * Allocate memory for up to 1000 selected choices...
84 collect
= calloc(sizeof(ppd_choice_t
*), 1000);
87 * Loop through all options and add choices as needed...
90 for (i
= ppd
->num_groups
, g
= ppd
->groups
; i
> 0; i
--, g
++)
92 for (j
= g
->num_options
, o
= g
->options
; j
> 0; j
--, o
++)
93 if (o
->section
== section
)
94 for (k
= o
->num_choices
, c
= o
->choices
; k
> 0; k
--, c
++)
95 if (c
->marked
&& count
< 1000)
101 for (j
= g
->num_subgroups
, sg
= g
->subgroups
; j
> 0; j
--, sg
++)
102 for (k
= sg
->num_options
, o
= sg
->options
; k
> 0; k
--, o
++)
103 if (o
->section
== section
)
104 for (m
= o
->num_choices
, c
= o
->choices
; m
> 0; m
--, c
++)
105 if (c
->marked
&& count
< 1000)
113 * If we have more than 1 marked choice, sort them...
117 qsort(collect
, count
, sizeof(ppd_choice_t
*),
118 (int (*)(const void *, const void *))ppd_sort
);
121 * Return the array and number of choices; if 0, free the array since
140 * 'ppdEmit()' - Emit code for marked options to a file.
143 int /* O - 0 on success, -1 on failure */
144 ppdEmit(ppd_file_t
*ppd
, /* I - PPD file record */
145 FILE *fp
, /* I - File to write to */
146 ppd_section_t section
) /* I - Section to write */
148 int i
, /* Looping var */
149 count
; /* Number of choices */
150 ppd_choice_t
**choices
; /* Choices */
151 ppd_size_t
*size
; /* Custom page size */
154 if ((count
= ppdCollect(ppd
, section
, &choices
)) == 0)
157 for (i
= 0; i
< count
; i
++)
158 if (section
!= PPD_ORDER_EXIT
&& section
!= PPD_ORDER_JCL
)
161 * Send wrapper commands to prevent printer errors for unsupported
165 if (fputs("[{\n", fp
) < 0)
172 * Send DSC comments with option...
175 if (fprintf(fp
, "%%%%BeginFeature: %s %s\n",
176 ((ppd_option_t
*)choices
[i
]->option
)->keyword
,
177 choices
[i
]->choice
) < 0)
183 if (strcasecmp(((ppd_option_t
*)choices
[i
]->option
)->keyword
, "PageSize") == 0 &&
184 strcasecmp(choices
[i
]->choice
, "Custom") == 0)
187 * Variable size; write out standard size options (this should
188 * eventually be changed to use the parameter positions defined
189 * in the PPD file...)
192 size
= ppdPageSize(ppd
, "Custom");
193 fprintf(fp
, "%.0f %.0f 0 0 0\n", size
->width
, size
->length
);
195 if (choices
[i
]->code
== NULL
)
198 * This can happen with certain buggy PPD files that don't include
199 * a CustomPageSize command sequence... We just use a generic
200 * Level 2 command sequence...
203 fputs("pop pop pop\n", fp
);
204 fputs("<</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\n", fp
);
208 if (choices
[i
]->code
!= NULL
&& choices
[i
]->code
[0] != '\0')
210 if (fputs(choices
[i
]->code
, fp
) < 0)
216 if (choices
[i
]->code
[strlen(choices
[i
]->code
) - 1] != '\n')
220 if (fputs("%%EndFeature\n", fp
) < 0)
226 if (fputs("} stopped cleartomark\n", fp
) < 0)
232 else if (fputs(choices
[i
]->code
, fp
) < 0)
244 * 'ppdEmitFd()' - Emit code for marked options to a file.
247 int /* O - 0 on success, -1 on failure */
248 ppdEmitFd(ppd_file_t
*ppd
, /* I - PPD file record */
249 int fd
, /* I - File to write to */
250 ppd_section_t section
) /* I - Section to write */
252 int i
, /* Looping var */
253 count
; /* Number of choices */
254 ppd_choice_t
**choices
; /* Choices */
255 char buf
[1024]; /* Output buffer for feature */
258 if ((count
= ppdCollect(ppd
, section
, &choices
)) == 0)
261 for (i
= 0; i
< count
; i
++)
262 if (section
!= PPD_ORDER_EXIT
&& section
!= PPD_ORDER_JCL
)
265 * Send wrapper commands to prevent printer errors for unsupported
269 if (write(fd
, "[{\n", 3) < 1)
276 * Send DSC comments with option...
279 snprintf(buf
, sizeof(buf
), "%%%%BeginFeature: %s %s\n",
280 ((ppd_option_t
*)choices
[i
]->option
)->keyword
,
283 if (write(fd
, buf
, strlen(buf
)) < 1)
289 if (write(fd
, choices
[i
]->code
, strlen(choices
[i
]->code
)) < 1)
295 if (write(fd
, "%%EndFeature\n", 13) < 1)
301 if (write(fd
, "} stopped cleartomark\n", 22) < 1)
307 else if (write(fd
, choices
[i
]->code
, strlen(choices
[i
]->code
)) < 1)
319 * 'ppdEmitJCL()' - Emit code for JCL options to a file.
322 int /* O - 0 on success, -1 on failure */
323 ppdEmitJCL(ppd_file_t
*ppd
, /* I - PPD file record */
324 FILE *fp
, /* I - File to write to */
325 int job_id
, /* I - Job ID */
326 const char *user
, /* I - Username */
327 const char *title
) /* I - Title */
329 const char *ptr
; /* Pointer into JCL string */
333 * Range check the input...
336 if (ppd
== NULL
|| ppd
->jcl_begin
== NULL
|| ppd
->jcl_ps
== NULL
)
340 * See if the printer supports HP PJL...
343 if (strncmp(ppd
->jcl_begin
, "\033%-12345X@", 10) == 0)
346 * This printer uses HP PJL commands for output; filter the output
347 * so that we only have a single "@PJL JOB" command in the header...
350 fputs("\033%-12345X", fp
);
351 for (ptr
= ppd
->jcl_begin
+ 9; *ptr
;)
352 if (strncmp(ptr
, "@PJL JOB", 8) == 0)
355 * Skip job command...
383 * Eliminate any path info from the job title...
386 if ((ptr
= strrchr(title
, '/')) != NULL
)
390 * Send PJL JOB command before we enter PostScript mode...
393 fprintf(fp
, "@PJL JOB NAME = \"%s\" DISPLAY = \"%d %s %s\"\n", title
,
394 job_id
, user
, title
);
397 fputs(ppd
->jcl_begin
, stdout
);
399 ppdEmit(ppd
, stdout
, PPD_ORDER_JCL
);
400 fputs(ppd
->jcl_ps
, stdout
);
407 * 'ppd_sort()' - Sort options by ordering numbers...
410 static int /* O - -1 if c1 < c2, 0 if equal, 1 otherwise */
411 ppd_sort(ppd_choice_t
**c1
, /* I - First choice */
412 ppd_choice_t
**c2
) /* I - Second choice */
414 if (((ppd_option_t
*)(*c1
)->option
)->order
< ((ppd_option_t
*)(*c2
)->option
)->order
)
416 else if (((ppd_option_t
*)(*c1
)->option
)->order
> ((ppd_option_t
*)(*c2
)->option
)->order
)
424 * End of "$Id: emit.c,v 1.25 2002/01/02 17:58:38 mike Exp $".