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