xref: /plan9/sys/src/cmd/gs/src/gdevdjet.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1989, 2000 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15  */
16 
17 /* $Id: gdevdjet.c,v 1.13 2005/04/07 09:12:15 igor Exp $ */
18 /* HP LaserJet/DeskJet driver for Ghostscript */
19 #include "gdevprn.h"
20 #include "gdevdljm.h"
21 
22 /*
23  * Thanks for various improvements to:
24  *      Jim Mayer (mayer@wrc.xerox.com)
25  *      Jan-Mark Wams (jms@cs.vu.nl)
26  *      Frans van Hoesel (hoesel@chem.rug.nl)
27  *      George Cameron (g.cameron@biomed.abdn.ac.uk)
28  *      Nick Duffek (nsd@bbc.com)
29  * Thanks for the FS-600 driver to:
30  *	Peter Schildmann (peter.schildmann@etechnik.uni-rostock.de)
31  * Thanks for the LJIIID duplex capability to:
32  *      PDP (Philip) Brown (phil@3soft-uk.com)
33  * Thanks for the OCE 9050 driver to:
34  *      William Bader (wbader@EECS.Lehigh.Edu)
35  * Thanks for the LJ4D duplex capability to:
36  *	Les Johnson <les@infolabs.com>
37  */
38 
39 /*
40  * You may select a default resolution of 75, 100, 150, 300, or
41  * (LJ4 only) 600 DPI in the makefile, or an actual resolution
42  * on the gs command line.
43  *
44  * If the preprocessor symbol A4 is defined, the default paper size is
45  * the European A4 size; otherwise it is the U.S. letter size (8.5"x11").
46  *
47  * To determine the proper "margin" settings for your printer, see the
48  * file align.ps.
49  */
50 
51 /* Define the default, maximum resolutions. */
52 #ifdef X_DPI
53 #  define X_DPI2 X_DPI
54 #else
55 #  define X_DPI 300
56 #  define X_DPI2 600
57 #endif
58 #ifdef Y_DPI
59 #  define Y_DPI2 Y_DPI
60 #else
61 #  define Y_DPI 300
62 #  define Y_DPI2 600
63 #endif
64 
65 /*
66  * For all DeskJet Printers:
67  *
68  *  Maximum printing width               = 2400 dots = 8"
69  *  Maximum recommended printing height  = 3100 dots = 10 1/3"
70  *
71  * All Deskjets have 1/2" unprintable bottom margin.
72  * The recommendation comes from the HP Software Developer's Guide for
73  * the DeskJet 500, DeskJet PLUS, and DeskJet printers, version C.01.00
74  * of 12/1/90.
75  *
76  * Note that the margins defined just below here apply only to the DeskJet;
77  * the paper size, width and height apply to the LaserJet as well.
78  */
79 
80 /* Margins are left, bottom, right, top. */
81 /* from Frans van Hoesel hoesel@rugr86.rug.nl. */
82 /* A4 has a left margin of 1/8 inch and at a printing width of
83  * 8 inch this give a right margin of 0.143. The 0.09 top margin is
84  * not the actual margin - which is 0.07 - but compensates for the
85  * inexact paperlength which is set to 117 10ths.
86  * Somebody should check for letter sized paper. I left it at 0.07".
87  */
88 #define DESKJET_MARGINS_LETTER  (float)0.2, (float)0.45, (float)0.3, (float)0.05
89 #define DESKJET_MARGINS_A4	(float)0.125, (float)0.5, (float)0.143, (float)0.09
90 /* Similar margins for the LaserJet. */
91 /* These are defined in the PCL 5 Technical Reference Manual. */
92 /* Note that for PCL 5 printers, we get the printer to translate the */
93 /* coordinate system: the margins only define the unprintable area. */
94 #define LASERJET_MARGINS_A4	(float)0.167, (float)0.167, (float)0.167, (float)0.167
95 #define LASERJET_MARGINS_LETTER	(float)0.167, (float)0.167, (float)0.167, (float)0.167
96 
97 /* See gdevdljm.h for the definitions of the PCL_ features. */
98 
99 /* The device descriptors */
100 private dev_proc_open_device(hpjet_open);
101 private dev_proc_close_device(hpjet_close);
102 private dev_proc_print_page_copies(djet_print_page_copies);
103 private dev_proc_print_page_copies(djet500_print_page_copies);
104 private dev_proc_print_page_copies(fs600_print_page_copies);
105 private dev_proc_print_page_copies(ljet_print_page_copies);
106 private dev_proc_print_page_copies(ljetplus_print_page_copies);
107 private dev_proc_print_page_copies(ljet2p_print_page_copies);
108 private dev_proc_print_page_copies(ljet3_print_page_copies);
109 private dev_proc_print_page_copies(ljet3d_print_page_copies);
110 private dev_proc_print_page_copies(ljet4_print_page_copies);
111 private dev_proc_print_page_copies(ljet4d_print_page_copies);
112 private dev_proc_print_page_copies(lp2563_print_page_copies);
113 private dev_proc_print_page_copies(oce9050_print_page_copies);
114 private dev_proc_get_params(hpjet_get_params);
115 private dev_proc_put_params(hpjet_put_params);
116 
117 private const gx_device_procs prn_hp_procs =
118 prn_params_procs(hpjet_open, gdev_prn_output_page, hpjet_close,
119 		 hpjet_get_params, hpjet_put_params);
120 
121 typedef struct gx_device_hpjet_s gx_device_hpjet;
122 
123 struct gx_device_hpjet_s {
124     gx_device_common;
125     gx_prn_device_common;
126     int MediaPosition;
127     bool MediaPosition_set;
128     bool ManualFeed;
129     bool ManualFeed_set;
130 };
131 
132 #define HPJET_DEVICE(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page_copies)\
133   { prn_device_std_margins_body_copies(gx_device_hpjet, procs, dname, \
134         w10, h10, xdpi, ydpi, lm, tm, lm, bm, rm, tm, color_bits, \
135         print_page_copies), \
136     0, false, false, false }
137 
138 const gx_device_hpjet gs_deskjet_device =
139 HPJET_DEVICE(prn_hp_procs, "deskjet",
140 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
141 	     X_DPI, Y_DPI,
142 	     0, 0, 0, 0,		/* margins filled in by hpjet_open */
143 	     1, djet_print_page_copies);
144 
145 const gx_device_hpjet gs_djet500_device =
146 HPJET_DEVICE(prn_hp_procs, "djet500",
147 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
148 	     X_DPI, Y_DPI,
149 	     0, 0, 0, 0,		/* margins filled in by hpjet_open */
150 	     1, djet500_print_page_copies);
151 
152 const gx_device_hpjet gs_fs600_device =
153 HPJET_DEVICE(prn_hp_procs, "fs600",
154 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
155 	     X_DPI2, Y_DPI2,
156 	     0.23, 0.0, 0.23, 0.04,      /* margins */
157 	     1, fs600_print_page_copies);
158 
159 const gx_device_hpjet gs_laserjet_device =
160 HPJET_DEVICE(prn_hp_procs, "laserjet",
161 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
162 	     X_DPI, Y_DPI,
163 	     0.05, 0.25, 0.55, 0.25,	/* margins */
164 	     1, ljet_print_page_copies);
165 
166 const gx_device_hpjet gs_ljetplus_device =
167 HPJET_DEVICE(prn_hp_procs, "ljetplus",
168 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
169 	     X_DPI, Y_DPI,
170 	     0.05, 0.25, 0.55, 0.25,	/* margins */
171 	     1, ljetplus_print_page_copies);
172 
173 const gx_device_hpjet gs_ljet2p_device =
174 HPJET_DEVICE(prn_hp_procs, "ljet2p",
175 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
176 	     X_DPI, Y_DPI,
177 	     0.20, 0.25, 0.25, 0.25,	/* margins */
178 	     1, ljet2p_print_page_copies);
179 
180 const gx_device_hpjet gs_ljet3_device =
181 HPJET_DEVICE(prn_hp_procs, "ljet3",
182 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
183 	     X_DPI, Y_DPI,
184 	     0.20, 0.25, 0.25, 0.25,	/* margins */
185 	     1, ljet3_print_page_copies);
186 
187 const gx_device_hpjet gs_ljet3d_device =
188 HPJET_DEVICE(prn_hp_procs, "ljet3d",
189 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
190 	     X_DPI, Y_DPI,
191 	     0.20, 0.25, 0.25, 0.25,	/* margins */
192 	     1, ljet3d_print_page_copies);
193 
194 const gx_device_hpjet gs_ljet4_device =
195 HPJET_DEVICE(prn_hp_procs, "ljet4",
196 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
197 	     X_DPI2, Y_DPI2,
198 	     0, 0, 0, 0,		/* margins */
199 	     1, ljet4_print_page_copies);
200 
201 const gx_device_hpjet gs_ljet4d_device =
202 HPJET_DEVICE(prn_hp_procs, "ljet4d",
203 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
204 	     X_DPI2, Y_DPI2,
205 	     0, 0, 0, 0,		/* margins */
206 	     1, ljet4d_print_page_copies);
207 
208 const gx_device_hpjet gs_lp2563_device =
209 HPJET_DEVICE(prn_hp_procs, "lp2563",
210 	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
211 	     X_DPI, Y_DPI,
212 	     0, 0, 0, 0,		/* margins */
213 	     1, lp2563_print_page_copies);
214 
215 const gx_device_hpjet gs_oce9050_device =
216 HPJET_DEVICE(prn_hp_procs, "oce9050",
217 	     24 * 10, 24 * 10,	/* 24 inch roll (can print 32" also) */
218 	     400, 400,		/* 400 dpi */
219 	     0, 0, 0, 0,		/* margins */
220 	     1, oce9050_print_page_copies);
221 
222 /* Open the printer, adjusting the margins if necessary. */
223 private int
hpjet_open(gx_device * pdev)224 hpjet_open(gx_device * pdev)
225 {				/* Change the margins if necessary. */
226     gx_device_printer *const ppdev = (gx_device_printer *)pdev;
227     const float *m = 0;
228     bool move_origin = true;
229 
230     if (ppdev->printer_procs.print_page_copies == djet_print_page_copies ||
231 	ppdev->printer_procs.print_page_copies == djet500_print_page_copies
232 	) {
233 	static const float m_a4[4] =
234 	{DESKJET_MARGINS_A4};
235 	static const float m_letter[4] =
236 	{DESKJET_MARGINS_LETTER};
237 
238 	m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? m_a4 :
239 	     m_letter);
240     } else if (ppdev->printer_procs.print_page_copies == oce9050_print_page_copies ||
241 	       ppdev->printer_procs.print_page_copies == lp2563_print_page_copies
242 	);
243     else {			/* LaserJet */
244 	static const float m_a4[4] =
245 	{LASERJET_MARGINS_A4};
246 	static const float m_letter[4] =
247 	{LASERJET_MARGINS_LETTER};
248 
249 	m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? m_a4 :
250 	     m_letter);
251 	move_origin = false;
252     }
253     if (m != 0)
254 	gx_device_set_margins(pdev, m, move_origin);
255     /* If this is a LJIIID, enable Duplex. */
256     if (ppdev->printer_procs.print_page_copies == ljet3d_print_page_copies)
257 	ppdev->Duplex = true, ppdev->Duplex_set = 0;
258     if (ppdev->printer_procs.print_page_copies == ljet4d_print_page_copies)
259 	ppdev->Duplex = true, ppdev->Duplex_set = 0;
260     return gdev_prn_open(pdev);
261 }
262 
263 /* hpjet_close is only here to eject odd numbered pages in duplex mode, */
264 /* and to reset the printer so the ink cartridge doesn't clog up. */
265 private int
hpjet_close(gx_device * pdev)266 hpjet_close(gx_device * pdev)
267 {
268     gx_device_printer *const ppdev = (gx_device_printer *)pdev;
269     int code = gdev_prn_open_printer(pdev, 1);
270 
271     if (code < 0)
272 	return code;
273     if (ppdev->PageCount > 0) {
274 	if (ppdev->Duplex_set >= 0 && ppdev->Duplex)
275 	    fputs("\033&l0H", ppdev->file);
276 
277 	fputs("\033E", ppdev->file);
278     }
279 
280     return gdev_prn_close(pdev);
281 }
282 
283 /* ------ Internal routines ------ */
284 
285 /* Make an init string that contains paper tray selection. The resulting
286    init string is stored in buf, so make sure that buf is at least 5
287    bytes larger than str. */
288 private void
hpjet_make_init(gx_device_printer * pdev,char * buf,const char * str)289 hpjet_make_init(gx_device_printer *pdev, char *buf, const char *str)
290 {
291     gx_device_hpjet *dev = (gx_device_hpjet *)pdev;
292     int paper_source = -1;
293     int paper_source_tab[] = { 5, 1 };
294 
295     if (dev->ManualFeed_set && dev->ManualFeed) paper_source = 2;
296     else if (dev->MediaPosition_set && dev->MediaPosition >= 0 &&
297 	     dev->MediaPosition < countof(paper_source_tab))
298 	paper_source = paper_source_tab[dev->MediaPosition];
299     if (paper_source >= 0)
300 	sprintf(buf, "%s\033&l%dH", str, paper_source);
301     else
302 	sprintf(buf, "%s", str);
303 }
304 
305 /* The DeskJet can compress (mode 2) */
306 private int
djet_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)307 djet_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
308 		       int num_copies)
309 {
310     char init[80];
311 
312     hpjet_make_init(pdev, init, "\033&k1W\033*b2M");
313     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
314 					300, PCL_DJ_FEATURES, init);
315 }
316 /* The DeskJet500 can compress (modes 2&3) */
317 private int
djet500_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)318 djet500_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
319 			  int num_copies)
320 {
321     char init[80];
322 
323     hpjet_make_init(pdev, init, "\033&k1W");
324     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
325 					300, PCL_DJ500_FEATURES, init);
326 }
327 /* The Kyocera FS-600 laser printer (and perhaps other printers */
328 /* which use the PeerlessPrint5 firmware) doesn't handle        */
329 /* ESC&l#u and ESC&l#Z correctly.                               */
330 private int
fs600_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)331 fs600_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
332 			int num_copies)
333 {
334     int dots_per_inch = (int)pdev->y_pixels_per_inch;
335     char base_init[60];
336     char init[80];
337 
338     sprintf(base_init, "\033*r0F\033&u%dD", dots_per_inch);
339     hpjet_make_init(pdev, init, base_init);
340     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
341 					dots_per_inch, PCL_FS600_FEATURES,
342 					init);
343 }
344 /* The LaserJet series II can't compress */
345 private int
ljet_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)346 ljet_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
347 		       int num_copies)
348 {
349     char init[80];
350 
351     hpjet_make_init(pdev, init, "\033*b0M");
352     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
353 					300, PCL_LJ_FEATURES, init);
354 }
355 /* The LaserJet Plus can't compress */
356 private int
ljetplus_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)357 ljetplus_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
358 			   int num_copies)
359 {
360     char init[80];
361 
362     hpjet_make_init(pdev, init, "\033*b0M");
363     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
364 					300, PCL_LJplus_FEATURES, init);
365 }
366 /* LaserJet series IIp & IId compress (mode 2) */
367 /* but don't support *p+ or *b vertical spacing. */
368 private int
ljet2p_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)369 ljet2p_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
370 			 int num_copies)
371 {
372     char init[80];
373 
374     hpjet_make_init(pdev, init, "\033*r0F\033*b2M");
375     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
376 					300, PCL_LJ2p_FEATURES, init);
377 }
378 /* All LaserJet series IIIs (III,IIId,IIIp,IIIsi) compress (modes 2&3) */
379 /* They also need their coordinate system translated slightly. */
380 private int
ljet3_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)381 ljet3_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
382 			int num_copies)
383 {
384     char init[80];
385 
386     hpjet_make_init(pdev, init, "\033&l-180u36Z\033*r0F");
387     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
388 					300, PCL_LJ3_FEATURES, init);
389 }
390 /* LaserJet IIId is same as LaserJet III, except for duplex */
391 private int
ljet3d_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)392 ljet3d_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
393 			 int num_copies)
394 {
395     char init[80];
396 
397     hpjet_make_init(pdev, init, "\033&l-180u36Z\033*r0F");
398     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
399 					300, PCL_LJ3D_FEATURES, init);
400 }
401 /* LaserJet 4 series compresses, and it needs a special sequence to */
402 /* allow it to specify coordinates at 600 dpi. */
403 /* It too needs its coordinate system translated slightly. */
404 private int
ljet4_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)405 ljet4_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
406 			int num_copies)
407 {
408     int dots_per_inch = (int)pdev->y_pixels_per_inch;
409     char base_init[60];
410     char init[80];
411 
412     sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
413     hpjet_make_init(pdev, init, base_init);
414     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
415 					dots_per_inch, PCL_LJ4_FEATURES,
416 					init);
417 }
418 private int
ljet4d_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)419 ljet4d_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
420 			 int num_copies)
421 {
422     int dots_per_inch = (int)pdev->y_pixels_per_inch;
423     char base_init[60];
424     char init[80];
425 
426     sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
427     hpjet_make_init(pdev, init, base_init);
428     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
429 					dots_per_inch, PCL_LJ4D_FEATURES,
430 					init);
431 }
432 /* The 2563B line printer can't compress */
433 /* and doesn't support *p+ or *b vertical spacing. */
434 private int
lp2563_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)435 lp2563_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
436 			 int num_copies)
437 {
438     char init[80];
439 
440     hpjet_make_init(pdev, init, "\033*b0M");
441     return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
442 					300, PCL_LP2563B_FEATURES, init);
443 }
444 /* The Oce line printer has TIFF compression */
445 /* and doesn't support *p+ or *b vertical spacing. */
446 private int
oce9050_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)447 oce9050_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
448 			  int num_copies)
449 {
450     int code;
451     char init[80];
452 
453     /* Switch to HP_RTL. */
454     fputs("\033%1B", prn_stream);	/* Enter HPGL/2 mode */
455     fputs("BP", prn_stream);	/* Begin Plot */
456     fputs("IN;", prn_stream);	/* Initialize (start plot) */
457     fputs("\033%1A", prn_stream);	/* Enter PCL mode */
458 
459     hpjet_make_init(pdev, init, "\033*b0M");
460 
461     code = dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
462 					400, PCL_OCE9050_FEATURES, init);
463 
464     /* Return to HPGL/2 mode. */
465     fputs("\033%1B", prn_stream);	/* Enter HPGL/2 mode */
466     if (code == 0) {
467 	fputs("PU", prn_stream);	/* Pen Up */
468 	fputs("SP0", prn_stream);	/* Pen Select */
469 	fputs("PG;", prn_stream);	/* Advance Full Page */
470 	fputs("\033E", prn_stream);	/* Reset */
471     }
472     return code;
473 }
474 
475 private int
hpjet_get_params(gx_device * pdev,gs_param_list * plist)476 hpjet_get_params(gx_device *pdev, gs_param_list *plist)
477 {
478     gx_device_hpjet *dev = (gx_device_hpjet *)pdev;
479     int code = gdev_prn_get_params(pdev, plist);
480 
481     if (code >= 0)
482 	code = param_write_bool(plist, "ManualFeed", &dev->ManualFeed);
483     return code;
484 }
485 
486 private int
hpjet_put_params(gx_device * pdev,gs_param_list * plist)487 hpjet_put_params(gx_device *pdev, gs_param_list *plist)
488 {
489     gx_device_hpjet *dev = (gx_device_hpjet *)pdev;
490     int code;
491     bool ManualFeed;
492     bool ManualFeed_set = false;
493     int MediaPosition;
494     bool MediaPosition_set = false;
495 
496     code = param_read_bool(plist, "ManualFeed", &ManualFeed);
497     if (code == 0) ManualFeed_set = true;
498     if (code >= 0) {
499 	code = param_read_int(plist, "%MediaSource", &MediaPosition);
500 	if (code == 0) MediaPosition_set = true;
501 	else if (code < 0) {
502 	    if (param_read_null(plist, "%MediaSource") == 0) {
503 		code = 0;
504 	    }
505 	}
506     }
507 
508     if (code >= 0)
509 	code = gdev_prn_put_params(pdev, plist);
510 
511     if (code >= 0) {
512 	if (ManualFeed_set) {
513 	    dev->ManualFeed = ManualFeed;
514 	    dev->ManualFeed_set = true;
515 	}
516 	if (MediaPosition_set) {
517 	    dev->MediaPosition = MediaPosition;
518 	    dev->MediaPosition_set = true;
519 	}
520     }
521 
522     return code;
523 }
524