1 /* Copyright (C) 1995, 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: gdevos2p.c,v 1.9 2004/09/27 21:14:00 ghostgum Exp $ */
18 /*
19 * OS/2 printer device
20 *
21 * By Russell Lang, derived from mswinpr2 device by Russell Lang and
22 * L. Peter Deutsch, Aladdin Enterprises.
23 *
24 * Bug fixed by Pierre Arnaud 2000-03-20 (os2prn_set_bpp did not set anti_alias)
25 */
26
27 /* This device works when GS is a DLL loaded by a PM program */
28 /* It does not work when GS is a text mode EXE */
29
30 /* This driver uses the printer default size and resolution and
31 * ignores page size and resolution set using -gWIDTHxHEIGHT and
32 * -rXxY. You must still set the correct PageSize to get the
33 * correct clipping path. If you don't specify a value for
34 * -dBitsPerPixel, the depth will be obtained from the printer
35 * device context.
36 */
37
38 #define INCL_DOS
39 #define INCL_DOSERRORS
40 #define INCL_DEV
41 #define INCL_GPIBITMAPS
42 #define INCL_SPL
43 #define INCL_SPLDOSPRINT
44 #define INCL_SPLERRORS
45
46 #include <os2.h>
47
48 #include "gdevprn.h"
49 #include "gdevpccm.h"
50 #include "gp.h"
51 #include "gscdefs.h" /* for gs_product */
52
53 extern HWND hwndtext; /* in gp_os2.h */
54
55 typedef struct tagOS2QL {
56 PRQINFO3 *prq; /* queue list */
57 ULONG len; /* bytes in queue list (for gs_free) */
58 int defqueue; /* default queue */
59 int nqueues; /* number of queues */
60 } OS2QL;
61
62 #ifndef NERR_BufTooSmall
63 #define NERR_BufTooSmall 2123 /* For SplEnumQueue */
64 #endif
65
66 /* Make sure we cast to the correct structure type. */
67 typedef struct gx_device_os2prn_s gx_device_os2prn;
68
69 #undef opdev
70 #define opdev ((gx_device_os2prn *)dev)
71
72 /* Device procedures */
73
74 /* See gxdevice.h for the definitions of the procedures. */
75 private dev_proc_open_device(os2prn_open);
76 private dev_proc_close_device(os2prn_close);
77 private dev_proc_print_page(os2prn_print_page);
78 private dev_proc_map_rgb_color(os2prn_map_rgb_color);
79 private dev_proc_map_color_rgb(os2prn_map_color_rgb);
80 private dev_proc_put_params(os2prn_put_params);
81 private dev_proc_get_params(os2prn_get_params);
82
83 private void os2prn_set_bpp(gx_device * dev, int depth);
84 private int os2prn_get_queue_list(gs_memory_t *mem, OS2QL * ql);
85 private void os2prn_free_queue_list(gs_memory_t *mem, OS2QL * ql);
86 int os2prn_get_printer(OS2QL * ql);
87
88 private gx_device_procs os2prn_procs =
89 prn_color_params_procs(os2prn_open, gdev_prn_output_page, os2prn_close,
90 os2prn_map_rgb_color, os2prn_map_color_rgb,
91 os2prn_get_params, os2prn_put_params);
92
93
94 /* The device descriptor */
95 struct gx_device_os2prn_s {
96 gx_device_common;
97 gx_prn_device_common;
98 HAB hab;
99 HDC hdc;
100 HPS hps;
101 char queue_name[256]; /* OS/2 printer queue name */
102 int newframe; /* false before first page */
103 OS2QL ql;
104 int clipbox[4]; /* llx, lly, urx, ury in pixels */
105 HDC hdcMem;
106 HPS hpsMem;
107 };
108
109 gx_device_os2prn far_data gs_os2prn_device =
110 {
111 prn_device_std_body(gx_device_os2prn, os2prn_procs, "os2prn",
112 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 72, 72,
113 0, 0, 0, 0,
114 0, os2prn_print_page), /* depth = 0 */
115 0, /* hab */
116 0, /* hdc */
117 0, /* hps */
118 "" /* queue_name */
119 };
120
121 /* Open the os2prn driver */
122 private int
os2prn_open(gx_device * dev)123 os2prn_open(gx_device * dev)
124 {
125 int code;
126 PTIB pptib;
127 PPIB pppib;
128 DEVOPENSTRUC dop;
129 ULONG cbBuf;
130 ULONG cbNeeded;
131 APIRET rc;
132 PBYTE pbuf;
133 char *p;
134 SIZEL sizlPage;
135 LONG caps[2];
136 HCINFO hcinfo;
137 LONG nforms;
138 float m[4];
139 int depth;
140 FILE *pfile;
141 int i;
142 char *prefix = "\\\\spool\\"; /* 8 characters long */
143
144 PRQINFO3 *pprq;
145 gx_device_os2prn *oprn;
146
147 oprn = opdev;
148
149 if (DosGetInfoBlocks(&pptib, &pppib)) {
150 errprintf("\nos2prn_open: Couldn't get pid\n");
151 return gs_error_limitcheck;
152 }
153 if (pppib->pib_ultype != 3) {
154 /* if caller is not PM app */
155 errprintf("os2prn device can only be used from a PM application\n");
156 return gs_error_limitcheck;
157 }
158 opdev->hab = WinQueryAnchorBlock(hwndtext);
159 opdev->newframe = 0;
160
161 if (os2prn_get_queue_list(dev->memory, &opdev->ql))
162 return gs_error_limitcheck;
163
164 if (opdev->queue_name[0] == '\0') {
165 /* obtain printer name from filename */
166 p = opdev->fname;
167 for (i = 0; i < 8; i++) {
168 if (prefix[i] == '\\') {
169 if ((*p != '\\') && (*p != '/'))
170 break;
171 } else if (tolower(*p) != prefix[i])
172 break;
173 p++;
174 }
175 if (i == 8 && (strlen(p) != 0))
176 strcpy(opdev->queue_name, p);
177 }
178 pprq = NULL;
179 if (opdev->queue_name[0] != '\0') {
180 for (i = 0; i < opdev->ql.nqueues; i++) {
181 if (strcmp(opdev->ql.prq[i].pszName, opdev->queue_name) == 0) {
182 pprq = &(opdev->ql.prq[i]);
183 break;
184 }
185 }
186 } else {
187 /* use default queue */
188 pprq = &(opdev->ql.prq[opdev->ql.defqueue]);
189 }
190 if (pprq == (PRQINFO3 *) NULL) {
191 errprintf("Invalid os2prn queue name -sOS2QUEUE=\042%s\042\n", opdev->queue_name);
192 errprintf("Valid device names are:\n");
193 for (i = 0; i < opdev->ql.nqueues; i++) {
194 errprintf(" -sOS2QUEUE=\042%s\042\n", opdev->ql.prq[i].pszName);
195 }
196 return gs_error_rangecheck;
197 }
198 /* open printer device */
199 memset(&dop, 0, sizeof(dop));
200 dop.pszLogAddress = pprq->pszName; /* queue name */
201 p = strchr(pprq->pszDriverName, '.');
202 if (p != (char *)NULL)
203 *p = '\0';
204 dop.pszDriverName = pprq->pszDriverName;
205 dop.pszDataType = "PM_Q_STD";
206 dop.pdriv = pprq->pDriverData;
207 opdev->hdc = DevOpenDC(opdev->hab, OD_QUEUED, "*", 9L, (PDEVOPENDATA) & dop, (HDC) NULL);
208 if (opdev->hdc == DEV_ERROR) {
209 ERRORID eid = WinGetLastError(opdev->hab);
210
211 errprintf("DevOpenDC for printer error 0x%x\n", eid);
212 return gs_error_limitcheck;
213 }
214 os2prn_free_queue_list(dev->memory, &opdev->ql);
215
216 /* find out resolution of printer */
217 /* this is returned in pixels/metre */
218 DevQueryCaps(opdev->hdc, CAPS_HORIZONTAL_RESOLUTION, 2, caps);
219 dev->x_pixels_per_inch = (int)(caps[0] * 0.0254 + 0.5);
220 dev->y_pixels_per_inch = (int)(caps[1] * 0.0254 + 0.5);
221
222 /* find out page size and margins */
223 /* these are returned in millimetres */
224 nforms = DevQueryHardcopyCaps(opdev->hdc, 0, 0, &hcinfo);
225 for (i = 0; i < nforms; i++) {
226 DevQueryHardcopyCaps(opdev->hdc, i, 1, &hcinfo);
227 if (hcinfo.flAttributes & HCAPS_CURRENT)
228 break; /* this is the default page size */
229 }
230 /* GS size is in pixels */
231 dev->width = hcinfo.cx * caps[0] / 1000;
232 dev->height = hcinfo.cy * caps[1] / 1000;
233 /* GS margins are in inches */
234 m[0] /*left */ = hcinfo.xLeftClip / 25.4;
235 m[1] /*bottom */ = hcinfo.yBottomClip / 25.4;
236 m[2] /*right */ = (hcinfo.cx - hcinfo.xRightClip) / 25.4;
237 m[3] /*top */ = (hcinfo.cy - hcinfo.yTopClip) / 25.4;
238 gx_device_set_margins(dev, m, true);
239 /* set bounding box in pixels for later drawing */
240 opdev->clipbox[0] = (int)(hcinfo.xLeftClip / 25.4 * dev->x_pixels_per_inch + 1); /* round inwards */
241 opdev->clipbox[1] = (int)(hcinfo.yBottomClip / 25.4 * dev->y_pixels_per_inch + 1);
242 opdev->clipbox[2] = (int)(hcinfo.xRightClip / 25.4 * dev->x_pixels_per_inch);
243 opdev->clipbox[3] = (int)(hcinfo.yTopClip / 25.4 * dev->y_pixels_per_inch);
244
245 /* get presentation space */
246 sizlPage.cx = dev->width;
247 sizlPage.cy = dev->height;
248 opdev->hps = GpiCreatePS(opdev->hab, opdev->hdc, &sizlPage,
249 PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
250
251 depth = dev->color_info.depth;
252 if (depth == 0) {
253 /* Set parameters that were unknown before opening device */
254 /* Find out if the device supports color */
255 /* We recognize 1 bit monochrome and 24 bit color devices */
256 DevQueryCaps(opdev->hdc, CAPS_COLOR_PLANES, 2, caps);
257 /* caps[0] is #color planes, caps[1] is #bits per plane */
258 depth = caps[0] * caps[1];
259 if (depth > 1)
260 depth = 24;
261 }
262 os2prn_set_bpp(dev, depth);
263
264 /* create a memory DC compatible with printer */
265 opdev->hdcMem = DevOpenDC(opdev->hab, OD_MEMORY, "*", 0L, NULL, opdev->hdc);
266 if (opdev->hdcMem == DEV_ERROR) {
267 ERRORID eid = WinGetLastError(opdev->hab);
268
269 errprintf("DevOpenDC for memory error 0x%x\n", eid);
270 return gs_error_limitcheck;
271 }
272 sizlPage.cx = dev->width;
273 sizlPage.cy = dev->height;
274 opdev->hpsMem = GpiCreatePS(opdev->hab, opdev->hdcMem, &sizlPage,
275 PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
276 if (opdev->hpsMem == GPI_ERROR) {
277 ERRORID eid = WinGetLastError(opdev->hab);
278
279 errprintf("GpiCreatePS for memory error 0x%x\n", eid);
280 return gs_error_limitcheck;
281 }
282 if (DevEscape(opdev->hdc, DEVESC_STARTDOC, (LONG) strlen(gs_product),
283 (char *)gs_product, NULL, NULL) == DEVESC_ERROR) {
284 ERRORID eid = WinGetLastError(opdev->hab);
285
286 errprintf("DEVESC_STARTDOC error 0x%x\n", eid);
287 return gs_error_limitcheck;
288 }
289 /* gdev_prn_open opens a temporary file which we don't want */
290 /* so we specify the name now so we can delete it later */
291 pfile = gp_open_scratch_file(gp_scratch_file_name_prefix,
292 opdev->fname, "wb");
293 fclose(pfile);
294 code = gdev_prn_open(dev);
295
296 return code;
297 }
298
299 /* Close the os2prn driver */
300 private int
os2prn_close(gx_device * dev)301 os2prn_close(gx_device * dev)
302 {
303 int code;
304 LONG lOut;
305 USHORT usJobID;
306
307 /* tell printer that all is finished */
308 DevEscape(opdev->hdc, DEVESC_ENDDOC, 0L, NULL, &lOut, (PBYTE) & usJobID);
309 /* Free resources */
310 GpiAssociate(opdev->hps, (HDC) NULL);
311 GpiDestroyPS(opdev->hps);
312 DevCloseDC(opdev->hdc);
313
314 if (opdev->hpsMem != GPI_ERROR)
315 GpiDestroyPS(opdev->hpsMem);
316 if (opdev->hdcMem != DEV_ERROR)
317 DevCloseDC(opdev->hdcMem);
318
319 code = gdev_prn_close(dev);
320 /* delete unwanted temporary file */
321 unlink(opdev->fname);
322 return code;
323 }
324
325 /* Get os2pm parameters */
326 int
os2prn_get_params(gx_device * dev,gs_param_list * plist)327 os2prn_get_params(gx_device * dev, gs_param_list * plist)
328 {
329 int code = gdev_prn_get_params(dev, plist);
330 gs_param_string qs;
331
332 qs.data = opdev->queue_name, qs.size = strlen(qs.data),
333 qs.persistent = false;
334 code < 0 ||
335 (code = param_write_string(plist, "OS2QUEUE", &qs)) < 0;
336 return code;
337 }
338
339
340
341 /* We implement this ourselves so that we can change BitsPerPixel */
342 /* before the device is opened */
343 int
os2prn_put_params(gx_device * dev,gs_param_list * plist)344 os2prn_put_params(gx_device * dev, gs_param_list * plist)
345 {
346 int ecode = 0, code;
347 int old_bpp = dev->color_info.depth;
348 int bpp = old_bpp;
349 gs_param_string qs;
350
351 /* Handle extra parameters */
352 switch (code = param_read_string(plist, "OS2QUEUE", &qs)) {
353 case 0:
354 if (qs.size == strlen(opdev->queue_name) &&
355 !memcmp(opdev->queue_name, qs.data, qs.size)
356 ) {
357 qs.data = 0;
358 break;
359 }
360 if (dev->is_open)
361 ecode = gs_error_rangecheck;
362 else if (qs.size >= sizeof(opdev->queue_name))
363 ecode = gs_error_limitcheck;
364 else
365 break;
366 goto qe;
367 default:
368 ecode = code;
369 qe:param_signal_error(plist, "OS2QUEUE", ecode);
370 case 1:
371 qs.data = 0;
372 break;
373 }
374
375 switch (code = param_read_int(plist, "BitsPerPixel", &bpp)) {
376 case 0:
377 if (dev->is_open)
378 ecode = gs_error_rangecheck;
379 else { /* change dev->color_info is valid before device is opened */
380 os2prn_set_bpp(dev, bpp);
381 break;
382 }
383 goto bppe;
384 default:
385 ecode = code;
386 bppe:param_signal_error(plist, "BitsPerPixel", ecode);
387 case 1:
388 break;
389 }
390
391 if (ecode >= 0)
392 ecode = gdev_prn_put_params(dev, plist);
393
394 if ((ecode >= 0) && (qs.data != 0)) {
395 memcpy(opdev->queue_name, qs.data, qs.size);
396 opdev->queue_name[qs.size] = 0;
397 }
398 return ecode;
399 }
400
401
402
403 /* ------ Internal routines ------ */
404
405 #undef opdev
406 #define opdev ((gx_device_os2prn *)pdev)
407
408 /************************************************/
409
410
411 /* ------ Private definitions ------ */
412
413
414 /* new os2prn_print_page routine */
415
416 /* Write BMP header to memory, then send bitmap to printer */
417 /* one scan line at a time */
418 private int
os2prn_print_page(gx_device_printer * pdev,FILE * file)419 os2prn_print_page(gx_device_printer * pdev, FILE * file)
420 {
421 int raster = gdev_prn_raster(pdev);
422
423 /* BMP scan lines are padded to 32 bits. */
424 ulong bmp_raster = (raster + 3) & (~3);
425 ulong bmp_raster_multi;
426 int height = pdev->height;
427 int depth = pdev->color_info.depth;
428 byte *row;
429 int y;
430 int code = 0; /* return code */
431 POINTL apts[4];
432 APIRET rc;
433 POINTL aptsb[4];
434 HBITMAP hbmp, hbmr;
435 int i, lines;
436 int ystart, yend;
437 int yslice;
438
439 struct bmi_s {
440 BITMAPINFOHEADER2 h;
441 RGB2 pal[256];
442 } bmi;
443
444 yslice = 65535 / bmp_raster;
445 bmp_raster_multi = bmp_raster * yslice;
446 row = (byte *) gs_malloc(pdev->memory, bmp_raster_multi, 1, "bmp file buffer");
447 if (row == 0) /* can't allocate row buffer */
448 return_error(gs_error_VMerror);
449
450 if (opdev->newframe)
451 DevEscape(opdev->hdc, DEVESC_NEWFRAME, 0L, NULL, NULL, NULL);
452 opdev->newframe = 1;
453
454 /* Write the info header. */
455
456 memset(&bmi.h, 0, sizeof(bmi.h));
457 bmi.h.cbFix = sizeof(bmi.h);
458 bmi.h.cx = pdev->width; /* opdev->mdev.width; */
459 /* bmi.h.cy = height; */
460 bmi.h.cy = yslice; /* size for memory PS */
461 bmi.h.cPlanes = 1;
462 bmi.h.cBitCount = pdev->color_info.depth;
463
464 /* Write the palette. */
465
466 if (depth <= 8) {
467 int i;
468 gx_color_value rgb[3];
469 PRGB2 pq;
470
471 bmi.h.cclrUsed = 1 << depth;
472 bmi.h.cclrImportant = 1 << depth;
473 for (i = 0; i != 1 << depth; i++) {
474 (*dev_proc(pdev, map_color_rgb)) ((gx_device *) pdev,
475 (gx_color_index) i, rgb);
476 pq = &bmi.pal[i];
477 pq->bRed = gx_color_value_to_byte(rgb[0]);
478 pq->bGreen = gx_color_value_to_byte(rgb[1]);
479 pq->bBlue = gx_color_value_to_byte(rgb[2]);
480 pq->fcOptions = 0;
481 }
482 } else {
483 bmi.h.cclrUsed = 0;
484 bmi.h.cclrImportant = 0;
485 }
486
487 /* for GpiDrawBits */
488 /* target is inclusive */
489 apts[0].x = 0;
490 apts[0].y = 0; /* filled in later */
491 apts[1].x = pdev->width - 1;
492 apts[1].y = 0; /* filled in later */
493 /* source is not inclusive of top & right borders */
494 apts[2].x = 0;
495 apts[2].y = 0;
496 apts[3].x = pdev->width;
497 apts[3].y = 0; /* filled in later */
498
499 /* for GpiBitBlt */
500 /* target is not inclusive */
501 aptsb[0].x = opdev->clipbox[0];
502 aptsb[0].y = 0; /* filled in later */
503 aptsb[1].x = opdev->clipbox[2];
504 aptsb[1].y = 0; /* filled in later */
505 /* source is not inclusive */
506 aptsb[2].x = opdev->clipbox[0];
507 aptsb[2].y = 0;
508 aptsb[3].x = opdev->clipbox[2];
509 aptsb[3].y = 0; /* filled in later */
510
511 /* write the bits */
512 ystart = opdev->clipbox[3];
513 yend = opdev->clipbox[1];
514 y = ystart;
515 while (y > yend) {
516 /* create a bitmap for the memory DC */
517 hbmp = GpiCreateBitmap(opdev->hpsMem, &bmi.h, 0L, NULL, NULL);
518 if (hbmp == GPI_ERROR)
519 goto bmp_done;
520 hbmr = GpiSetBitmap(opdev->hpsMem, hbmp);
521
522 /* copy slice to memory bitmap */
523 if (y > yend + yslice)
524 lines = yslice;
525 else
526 lines = y - yend;
527 y -= lines;
528 for (i = lines - 1; i >= 0; i--)
529 gdev_prn_copy_scan_lines(pdev, ystart - 1 - (y + i), row + (bmp_raster * i), raster);
530 apts[0].y = 0; /* target */
531 apts[1].y = lines;
532 apts[3].y = lines - 1; /* source */
533 /* copy DIB bitmap to memory bitmap */
534 rc = GpiDrawBits(opdev->hpsMem, row, (BITMAPINFO2 *) & bmi, 4, apts,
535 (depth != 1) ? ROP_SRCCOPY : ROP_NOTSRCCOPY, 0);
536
537 /* copy slice to printer */
538 aptsb[0].y = y;
539 aptsb[1].y = y + lines;
540 aptsb[3].y = lines;
541 rc = GpiBitBlt(opdev->hps, opdev->hpsMem, 4, aptsb, ROP_SRCCOPY, BBO_IGNORE);
542
543 /* delete bitmap */
544 if (hbmr != HBM_ERROR)
545 GpiSetBitmap(opdev->hpsMem, (ULONG) 0);
546 hbmr = HBM_ERROR;
547 if (hbmp != GPI_ERROR)
548 GpiDeleteBitmap(hbmp);
549 hbmp = GPI_ERROR;
550 }
551
552 bmp_done:
553 if (row)
554 gs_free(pdev->memory, (char *)row, bmp_raster_multi, 1, "bmp file buffer");
555
556 return code;
557 }
558
559 /* combined color mappers */
560
561 /* 24-bit color mappers (taken from gdevmem2.c). */
562 /* Note that OS/2 expects RGB values in the order B,G,R. */
563
564 /* Encode a r-g-b color to a color index. */
565 private gx_color_index
os2prn_map_rgb_color(gx_device * dev,const gx_color_value cv[])566 os2prn_map_rgb_color(gx_device * dev, const gx_color_value cv[])
567 {
568 gx_color_value r = cv[0];
569 gx_color_value g = cv[1];
570 gx_color_value b = cv[2];
571 return gx_color_value_to_byte(r) +
572 ((uint) gx_color_value_to_byte(g) << 8) +
573 ((ulong) gx_color_value_to_byte(b) << 16);
574 }
575
576 /* Decode a color index to a r-g-b color. */
577 private int
os2prn_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])578 os2prn_map_color_rgb(gx_device * dev, gx_color_index color,
579 gx_color_value prgb[3])
580 {
581 prgb[2] = gx_color_value_from_byte(color >> 16);
582 prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
583 prgb[0] = gx_color_value_from_byte(color & 0xff);
584 return 0;
585 }
586
587 void
os2prn_set_bpp(gx_device * dev,int depth)588 os2prn_set_bpp(gx_device * dev, int depth)
589 {
590 gx_device_color_info dci = dev->color_info;
591 static const gx_device_color_info os2prn_dci_rgb = dci_std_color(24);
592 static const gx_device_color_info os2prn_dci_mono = dci_black_and_white;
593 if (depth == 24) {
594 dci = os2prn_dci_rgb;
595 dev->procs.get_color_mapping_procs = gx_default_DevRGB_get_color_mapping_procs;
596 dev->procs.get_color_comp_index = gx_default_DevRGB_get_color_comp_index;
597 dev->procs.map_rgb_color = dev->procs.encode_color =
598 os2prn_map_rgb_color;
599 dev->procs.map_color_rgb = dev->procs.decode_color =
600 os2prn_map_color_rgb;
601 } else { /* default is black and white */
602 dci = os2prn_dci_mono;
603 dev->procs.get_color_mapping_procs = gx_default_DevGray_get_color_mapping_procs;
604 dev->procs.get_color_comp_index = gx_default_DevGray_get_color_comp_index;
605 dev->procs.map_rgb_color = dev->procs.encode_color =
606 gx_default_b_w_map_rgb_color;
607 dev->procs.map_color_rgb = dev->procs.decode_color =
608 gx_default_b_w_map_color_rgb;
609 }
610 /* restore old anti_alias info */
611 dci.anti_alias = dev->color_info.anti_alias;
612 dev->color_info = dci;
613 /* Set the mask bits, etc. even though we are setting linear: unknown */
614 set_linear_color_bits_mask_shift(dev);
615 }
616
617 /* Get list of queues from SplEnumQueue */
618 /* returns 0 if OK, non-zero for error */
619 private int
os2prn_get_queue_list(gs_memory_t * mem,OS2QL * ql)620 os2prn_get_queue_list(gs_memory_t *mem, OS2QL * ql)
621 {
622 SPLERR splerr;
623 USHORT jobCount;
624 ULONG cbBuf;
625 ULONG cTotal;
626 ULONG cReturned;
627 ULONG cbNeeded;
628 ULONG ulLevel;
629 ULONG i;
630 PSZ pszComputerName;
631 PBYTE pBuf;
632 PPRQINFO3 prq;
633
634 ulLevel = 3L;
635 pszComputerName = (PSZ) NULL;
636 splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, 0L, /* cbBuf */
637 &cReturned, &cTotal,
638 &cbNeeded, NULL);
639 if (splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall) {
640 pBuf = gs_malloc(mem, cbNeeded, 1, "OS/2 printer device info buffer");
641 ql->prq = (PRQINFO3 *) pBuf;
642 if (ql->prq != (PRQINFO3 *) NULL) {
643 ql->len = cbNeeded;
644 cbBuf = cbNeeded;
645 splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, cbBuf,
646 &cReturned, &cTotal,
647 &cbNeeded, NULL);
648 if (splerr == NO_ERROR) {
649 /* Set pointer to point to the beginning of the buffer. */
650 prq = (PPRQINFO3) pBuf;
651 /* cReturned has the count of the number of PRQINFO3 structures. */
652 ql->nqueues = cReturned;
653 ql->defqueue = 0;
654 for (i = 0; i < cReturned; i++) {
655 if (prq->fsType & PRQ3_TYPE_APPDEFAULT)
656 ql->defqueue = i;
657 prq++;
658 } /*endfor cReturned */
659 }
660 }
661 } else {
662 /* If we are here we had a bad error code. Print it and some other info. */
663 eprintf4("SplEnumQueue Error=%ld, Total=%ld, Returned=%ld, Needed=%ld\n",
664 splerr, cTotal, cReturned, cbNeeded);
665 }
666 if (splerr)
667 return splerr;
668 return 0;
669 }
670
671
672 private void
os2prn_free_queue_list(gs_memory_t * mem,OS2QL * ql)673 os2prn_free_queue_list(gs_memory_t *mem, OS2QL * ql)
674 {
675 gs_free(mem, (char *)ql->prq, ql->len, 1, "os2prn queue list");
676 ql->prq = NULL;
677 ql->len = 0;
678 ql->defqueue = 0;
679 ql->nqueues = 0;
680 }
681