1*3ff48bf5SDavid du Colombier /* Copyright (C) 1995, 2000 Aladdin Enterprises. All rights reserved. 27dd7cddfSDavid du Colombier 3*3ff48bf5SDavid du Colombier This file is part of AFPL Ghostscript. 47dd7cddfSDavid du Colombier 5*3ff48bf5SDavid du Colombier AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or 6*3ff48bf5SDavid du Colombier distributor accepts any responsibility for the consequences of using it, or 7*3ff48bf5SDavid du Colombier for whether it serves any particular purpose or works at all, unless he or 8*3ff48bf5SDavid du Colombier she says so in writing. Refer to the Aladdin Free Public License (the 9*3ff48bf5SDavid du Colombier "License") for full details. 107dd7cddfSDavid du Colombier 11*3ff48bf5SDavid du Colombier Every copy of AFPL Ghostscript must include a copy of the License, normally 12*3ff48bf5SDavid du Colombier in a plain ASCII text file named PUBLIC. The License grants you the right 13*3ff48bf5SDavid du Colombier to copy, modify and redistribute AFPL Ghostscript, but only under certain 14*3ff48bf5SDavid du Colombier conditions described in the License. Among other things, the License 15*3ff48bf5SDavid du Colombier requires that the copyright notice and this notice be preserved on all 16*3ff48bf5SDavid du Colombier copies. 177dd7cddfSDavid du Colombier */ 187dd7cddfSDavid du Colombier 19*3ff48bf5SDavid du Colombier /*$Id: gdevos2p.c,v 1.4 2001/03/13 06:51:39 ghostgum Exp $ */ 207dd7cddfSDavid du Colombier /* 217dd7cddfSDavid du Colombier * OS/2 printer device 227dd7cddfSDavid du Colombier * 237dd7cddfSDavid du Colombier * By Russell Lang, derived from mswinpr2 device by Russell Lang and 247dd7cddfSDavid du Colombier * L. Peter Deutsch, Aladdin Enterprises. 25*3ff48bf5SDavid du Colombier * 26*3ff48bf5SDavid du Colombier * Bug fixed by Pierre Arnaud 2000-03-20 (os2prn_set_bpp did not set anti_alias) 277dd7cddfSDavid du Colombier */ 287dd7cddfSDavid du Colombier 297dd7cddfSDavid du Colombier /* This device works when GS is a DLL loaded by a PM program */ 307dd7cddfSDavid du Colombier /* It does not work when GS is a text mode EXE */ 317dd7cddfSDavid du Colombier 327dd7cddfSDavid du Colombier /* This driver uses the printer default size and resolution and 337dd7cddfSDavid du Colombier * ignores page size and resolution set using -gWIDTHxHEIGHT and 347dd7cddfSDavid du Colombier * -rXxY. You must still set the correct PageSize to get the 357dd7cddfSDavid du Colombier * correct clipping path. If you don't specify a value for 367dd7cddfSDavid du Colombier * -dBitsPerPixel, the depth will be obtained from the printer 377dd7cddfSDavid du Colombier * device context. 387dd7cddfSDavid du Colombier */ 397dd7cddfSDavid du Colombier 407dd7cddfSDavid du Colombier #define INCL_DOS 417dd7cddfSDavid du Colombier #define INCL_DOSERRORS 427dd7cddfSDavid du Colombier #define INCL_DEV 437dd7cddfSDavid du Colombier #define INCL_GPIBITMAPS 447dd7cddfSDavid du Colombier #define INCL_SPL 457dd7cddfSDavid du Colombier #define INCL_SPLDOSPRINT 467dd7cddfSDavid du Colombier #define INCL_SPLERRORS 477dd7cddfSDavid du Colombier 487dd7cddfSDavid du Colombier #include <os2.h> 497dd7cddfSDavid du Colombier 507dd7cddfSDavid du Colombier #include "gdevprn.h" 517dd7cddfSDavid du Colombier #include "gdevpccm.h" 527dd7cddfSDavid du Colombier #include "gp.h" 537dd7cddfSDavid du Colombier #include "gscdefs.h" /* for gs_product */ 547dd7cddfSDavid du Colombier 557dd7cddfSDavid du Colombier extern HWND hwndtext; /* in gp_os2.h */ 567dd7cddfSDavid du Colombier 577dd7cddfSDavid du Colombier typedef struct tagOS2QL { 587dd7cddfSDavid du Colombier PRQINFO3 *prq; /* queue list */ 597dd7cddfSDavid du Colombier ULONG len; /* bytes in queue list (for gs_free) */ 607dd7cddfSDavid du Colombier int defqueue; /* default queue */ 617dd7cddfSDavid du Colombier int nqueues; /* number of queues */ 627dd7cddfSDavid du Colombier } OS2QL; 637dd7cddfSDavid du Colombier 647dd7cddfSDavid du Colombier #ifndef NERR_BufTooSmall 657dd7cddfSDavid du Colombier #define NERR_BufTooSmall 2123 /* For SplEnumQueue */ 667dd7cddfSDavid du Colombier #endif 677dd7cddfSDavid du Colombier 687dd7cddfSDavid du Colombier /* Make sure we cast to the correct structure type. */ 697dd7cddfSDavid du Colombier typedef struct gx_device_os2prn_s gx_device_os2prn; 707dd7cddfSDavid du Colombier 717dd7cddfSDavid du Colombier #undef opdev 727dd7cddfSDavid du Colombier #define opdev ((gx_device_os2prn *)dev) 737dd7cddfSDavid du Colombier 747dd7cddfSDavid du Colombier /* Device procedures */ 757dd7cddfSDavid du Colombier 767dd7cddfSDavid du Colombier /* See gxdevice.h for the definitions of the procedures. */ 777dd7cddfSDavid du Colombier private dev_proc_open_device(os2prn_open); 787dd7cddfSDavid du Colombier private dev_proc_close_device(os2prn_close); 797dd7cddfSDavid du Colombier private dev_proc_print_page(os2prn_print_page); 807dd7cddfSDavid du Colombier private dev_proc_map_rgb_color(os2prn_map_rgb_color); 817dd7cddfSDavid du Colombier private dev_proc_map_color_rgb(os2prn_map_color_rgb); 827dd7cddfSDavid du Colombier private dev_proc_put_params(os2prn_put_params); 837dd7cddfSDavid du Colombier private dev_proc_get_params(os2prn_get_params); 847dd7cddfSDavid du Colombier 857dd7cddfSDavid du Colombier private void os2prn_set_bpp(gx_device * dev, int depth); 867dd7cddfSDavid du Colombier private int os2prn_get_queue_list(OS2QL * ql); 877dd7cddfSDavid du Colombier private void os2prn_free_queue_list(OS2QL * ql); 887dd7cddfSDavid du Colombier int os2prn_get_printer(OS2QL * ql); 897dd7cddfSDavid du Colombier 907dd7cddfSDavid du Colombier private gx_device_procs os2prn_procs = 917dd7cddfSDavid du Colombier prn_color_params_procs(os2prn_open, gdev_prn_output_page, os2prn_close, 927dd7cddfSDavid du Colombier os2prn_map_rgb_color, os2prn_map_color_rgb, 937dd7cddfSDavid du Colombier os2prn_get_params, os2prn_put_params); 947dd7cddfSDavid du Colombier 957dd7cddfSDavid du Colombier 967dd7cddfSDavid du Colombier /* The device descriptor */ 977dd7cddfSDavid du Colombier struct gx_device_os2prn_s { 987dd7cddfSDavid du Colombier gx_device_common; 997dd7cddfSDavid du Colombier gx_prn_device_common; 1007dd7cddfSDavid du Colombier HAB hab; 1017dd7cddfSDavid du Colombier HDC hdc; 1027dd7cddfSDavid du Colombier HPS hps; 1037dd7cddfSDavid du Colombier char queue_name[256]; /* OS/2 printer queue name */ 1047dd7cddfSDavid du Colombier int newframe; /* false before first page */ 1057dd7cddfSDavid du Colombier OS2QL ql; 1067dd7cddfSDavid du Colombier int clipbox[4]; /* llx, lly, urx, ury in pixels */ 1077dd7cddfSDavid du Colombier HDC hdcMem; 1087dd7cddfSDavid du Colombier HPS hpsMem; 1097dd7cddfSDavid du Colombier }; 1107dd7cddfSDavid du Colombier 1117dd7cddfSDavid du Colombier gx_device_os2prn far_data gs_os2prn_device = 1127dd7cddfSDavid du Colombier { 1137dd7cddfSDavid du Colombier prn_device_std_body(gx_device_os2prn, os2prn_procs, "os2prn", 1147dd7cddfSDavid du Colombier DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 72, 72, 1157dd7cddfSDavid du Colombier 0, 0, 0, 0, 1167dd7cddfSDavid du Colombier 0, os2prn_print_page), /* depth = 0 */ 1177dd7cddfSDavid du Colombier 0, /* hab */ 1187dd7cddfSDavid du Colombier 0, /* hdc */ 1197dd7cddfSDavid du Colombier 0, /* hps */ 1207dd7cddfSDavid du Colombier "" /* queue_name */ 1217dd7cddfSDavid du Colombier }; 1227dd7cddfSDavid du Colombier 1237dd7cddfSDavid du Colombier /* Open the os2prn driver */ 1247dd7cddfSDavid du Colombier private int 1257dd7cddfSDavid du Colombier os2prn_open(gx_device * dev) 1267dd7cddfSDavid du Colombier { 1277dd7cddfSDavid du Colombier int code; 1287dd7cddfSDavid du Colombier PTIB pptib; 1297dd7cddfSDavid du Colombier PPIB pppib; 1307dd7cddfSDavid du Colombier DEVOPENSTRUC dop; 1317dd7cddfSDavid du Colombier ULONG cbBuf; 1327dd7cddfSDavid du Colombier ULONG cbNeeded; 1337dd7cddfSDavid du Colombier APIRET rc; 1347dd7cddfSDavid du Colombier PBYTE pbuf; 1357dd7cddfSDavid du Colombier char *p; 1367dd7cddfSDavid du Colombier SIZEL sizlPage; 1377dd7cddfSDavid du Colombier LONG caps[2]; 1387dd7cddfSDavid du Colombier HCINFO hcinfo; 1397dd7cddfSDavid du Colombier LONG nforms; 1407dd7cddfSDavid du Colombier float m[4]; 1417dd7cddfSDavid du Colombier int depth; 1427dd7cddfSDavid du Colombier FILE *pfile; 1437dd7cddfSDavid du Colombier int i; 1447dd7cddfSDavid du Colombier char *prefix = "\\\\spool\\"; /* 8 characters long */ 1457dd7cddfSDavid du Colombier 1467dd7cddfSDavid du Colombier PRQINFO3 *pprq; 1477dd7cddfSDavid du Colombier gx_device_os2prn *oprn; 1487dd7cddfSDavid du Colombier 1497dd7cddfSDavid du Colombier oprn = opdev; 1507dd7cddfSDavid du Colombier 1517dd7cddfSDavid du Colombier if (DosGetInfoBlocks(&pptib, &pppib)) { 152*3ff48bf5SDavid du Colombier errprintf("\nos2prn_open: Couldn't get pid\n"); 1537dd7cddfSDavid du Colombier return gs_error_limitcheck; 1547dd7cddfSDavid du Colombier } 1557dd7cddfSDavid du Colombier if (pppib->pib_ultype != 3) { 1567dd7cddfSDavid du Colombier /* if caller is not PM app */ 157*3ff48bf5SDavid du Colombier errprintf("os2prn device can only be used from a PM application\n"); 1587dd7cddfSDavid du Colombier return gs_error_limitcheck; 1597dd7cddfSDavid du Colombier } 1607dd7cddfSDavid du Colombier opdev->hab = WinQueryAnchorBlock(hwndtext); 1617dd7cddfSDavid du Colombier opdev->newframe = 0; 1627dd7cddfSDavid du Colombier 1637dd7cddfSDavid du Colombier if (os2prn_get_queue_list(&opdev->ql)) 1647dd7cddfSDavid du Colombier return gs_error_limitcheck; 1657dd7cddfSDavid du Colombier 1667dd7cddfSDavid du Colombier if (opdev->queue_name[0] == '\0') { 1677dd7cddfSDavid du Colombier /* obtain printer name from filename */ 1687dd7cddfSDavid du Colombier p = opdev->fname; 1697dd7cddfSDavid du Colombier for (i = 0; i < 8; i++) { 1707dd7cddfSDavid du Colombier if (prefix[i] == '\\') { 1717dd7cddfSDavid du Colombier if ((*p != '\\') && (*p != '/')) 1727dd7cddfSDavid du Colombier break; 1737dd7cddfSDavid du Colombier } else if (tolower(*p) != prefix[i]) 1747dd7cddfSDavid du Colombier break; 1757dd7cddfSDavid du Colombier p++; 1767dd7cddfSDavid du Colombier } 1777dd7cddfSDavid du Colombier if (i == 8 && (strlen(p) != 0)) 1787dd7cddfSDavid du Colombier strcpy(opdev->queue_name, p); 1797dd7cddfSDavid du Colombier } 1807dd7cddfSDavid du Colombier pprq = NULL; 1817dd7cddfSDavid du Colombier if (opdev->queue_name[0] != '\0') { 1827dd7cddfSDavid du Colombier for (i = 0; i < opdev->ql.nqueues; i++) { 1837dd7cddfSDavid du Colombier if (strcmp(opdev->ql.prq[i].pszName, opdev->queue_name) == 0) { 1847dd7cddfSDavid du Colombier pprq = &(opdev->ql.prq[i]); 1857dd7cddfSDavid du Colombier break; 1867dd7cddfSDavid du Colombier } 1877dd7cddfSDavid du Colombier } 1887dd7cddfSDavid du Colombier } else { 1897dd7cddfSDavid du Colombier /* use default queue */ 1907dd7cddfSDavid du Colombier pprq = &(opdev->ql.prq[opdev->ql.defqueue]); 1917dd7cddfSDavid du Colombier } 1927dd7cddfSDavid du Colombier if (pprq == (PRQINFO3 *) NULL) { 193*3ff48bf5SDavid du Colombier errprintf("Invalid os2prn queue name -sOS2QUEUE=\042%s\042\n", opdev->queue_name); 194*3ff48bf5SDavid du Colombier errprintf("Valid device names are:\n"); 1957dd7cddfSDavid du Colombier for (i = 0; i < opdev->ql.nqueues; i++) { 196*3ff48bf5SDavid du Colombier errprintf(" -sOS2QUEUE=\042%s\042\n", opdev->ql.prq[i].pszName); 1977dd7cddfSDavid du Colombier } 1987dd7cddfSDavid du Colombier return gs_error_rangecheck; 1997dd7cddfSDavid du Colombier } 2007dd7cddfSDavid du Colombier /* open printer device */ 2017dd7cddfSDavid du Colombier memset(&dop, 0, sizeof(dop)); 2027dd7cddfSDavid du Colombier dop.pszLogAddress = pprq->pszName; /* queue name */ 2037dd7cddfSDavid du Colombier p = strchr(pprq->pszDriverName, '.'); 2047dd7cddfSDavid du Colombier if (p != (char *)NULL) 2057dd7cddfSDavid du Colombier *p = '\0'; 2067dd7cddfSDavid du Colombier dop.pszDriverName = pprq->pszDriverName; 2077dd7cddfSDavid du Colombier dop.pszDataType = "PM_Q_STD"; 2087dd7cddfSDavid du Colombier dop.pdriv = pprq->pDriverData; 2097dd7cddfSDavid du Colombier opdev->hdc = DevOpenDC(opdev->hab, OD_QUEUED, "*", 9L, (PDEVOPENDATA) & dop, (HDC) NULL); 2107dd7cddfSDavid du Colombier if (opdev->hdc == DEV_ERROR) { 2117dd7cddfSDavid du Colombier ERRORID eid = WinGetLastError(opdev->hab); 2127dd7cddfSDavid du Colombier 213*3ff48bf5SDavid du Colombier errprintf("DevOpenDC for printer error 0x%x\n", eid); 2147dd7cddfSDavid du Colombier return gs_error_limitcheck; 2157dd7cddfSDavid du Colombier } 2167dd7cddfSDavid du Colombier os2prn_free_queue_list(&opdev->ql); 2177dd7cddfSDavid du Colombier 2187dd7cddfSDavid du Colombier /* find out resolution of printer */ 2197dd7cddfSDavid du Colombier /* this is returned in pixels/metre */ 2207dd7cddfSDavid du Colombier DevQueryCaps(opdev->hdc, CAPS_HORIZONTAL_RESOLUTION, 2, caps); 2217dd7cddfSDavid du Colombier dev->x_pixels_per_inch = (int)(caps[0] * 0.0254 + 0.5); 2227dd7cddfSDavid du Colombier dev->y_pixels_per_inch = (int)(caps[1] * 0.0254 + 0.5); 2237dd7cddfSDavid du Colombier 2247dd7cddfSDavid du Colombier /* find out page size and margins */ 2257dd7cddfSDavid du Colombier /* these are returned in millimetres */ 2267dd7cddfSDavid du Colombier nforms = DevQueryHardcopyCaps(opdev->hdc, 0, 0, &hcinfo); 2277dd7cddfSDavid du Colombier for (i = 0; i < nforms; i++) { 2287dd7cddfSDavid du Colombier DevQueryHardcopyCaps(opdev->hdc, i, 1, &hcinfo); 2297dd7cddfSDavid du Colombier if (hcinfo.flAttributes & HCAPS_CURRENT) 2307dd7cddfSDavid du Colombier break; /* this is the default page size */ 2317dd7cddfSDavid du Colombier } 2327dd7cddfSDavid du Colombier /* GS size is in pixels */ 2337dd7cddfSDavid du Colombier dev->width = hcinfo.cx * caps[0] / 1000; 2347dd7cddfSDavid du Colombier dev->height = hcinfo.cy * caps[1] / 1000; 2357dd7cddfSDavid du Colombier /* GS margins are in inches */ 2367dd7cddfSDavid du Colombier m[0] /*left */ = hcinfo.xLeftClip / 25.4; 2377dd7cddfSDavid du Colombier m[1] /*bottom */ = hcinfo.yBottomClip / 25.4; 2387dd7cddfSDavid du Colombier m[2] /*right */ = (hcinfo.cx - hcinfo.xRightClip) / 25.4; 2397dd7cddfSDavid du Colombier m[3] /*top */ = (hcinfo.cy - hcinfo.yTopClip) / 25.4; 2407dd7cddfSDavid du Colombier gx_device_set_margins(dev, m, true); 2417dd7cddfSDavid du Colombier /* set bounding box in pixels for later drawing */ 2427dd7cddfSDavid du Colombier opdev->clipbox[0] = (int)(hcinfo.xLeftClip / 25.4 * dev->x_pixels_per_inch + 1); /* round inwards */ 2437dd7cddfSDavid du Colombier opdev->clipbox[1] = (int)(hcinfo.yBottomClip / 25.4 * dev->y_pixels_per_inch + 1); 2447dd7cddfSDavid du Colombier opdev->clipbox[2] = (int)(hcinfo.xRightClip / 25.4 * dev->x_pixels_per_inch); 2457dd7cddfSDavid du Colombier opdev->clipbox[3] = (int)(hcinfo.yTopClip / 25.4 * dev->y_pixels_per_inch); 2467dd7cddfSDavid du Colombier 2477dd7cddfSDavid du Colombier /* get presentation space */ 2487dd7cddfSDavid du Colombier sizlPage.cx = dev->width; 2497dd7cddfSDavid du Colombier sizlPage.cy = dev->height; 2507dd7cddfSDavid du Colombier opdev->hps = GpiCreatePS(opdev->hab, opdev->hdc, &sizlPage, 2517dd7cddfSDavid du Colombier PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC); 2527dd7cddfSDavid du Colombier 2537dd7cddfSDavid du Colombier depth = dev->color_info.depth; 2547dd7cddfSDavid du Colombier if (depth == 0) { 2557dd7cddfSDavid du Colombier /* Set parameters that were unknown before opening device */ 2567dd7cddfSDavid du Colombier /* Find out if the device supports color */ 2577dd7cddfSDavid du Colombier /* We recognize 1, 3, 8 and 24 bit color devices */ 2587dd7cddfSDavid du Colombier DevQueryCaps(opdev->hdc, CAPS_COLOR_PLANES, 2, caps); 2597dd7cddfSDavid du Colombier /* caps[0] is #color planes, caps[1] is #bits per plane */ 2607dd7cddfSDavid du Colombier depth = caps[0] * caps[1]; 2617dd7cddfSDavid du Colombier } 2627dd7cddfSDavid du Colombier os2prn_set_bpp(dev, depth); 2637dd7cddfSDavid du Colombier 2647dd7cddfSDavid du Colombier /* create a memory DC compatible with printer */ 2657dd7cddfSDavid du Colombier opdev->hdcMem = DevOpenDC(opdev->hab, OD_MEMORY, "*", 0L, NULL, opdev->hdc); 2667dd7cddfSDavid du Colombier if (opdev->hdcMem == DEV_ERROR) { 2677dd7cddfSDavid du Colombier ERRORID eid = WinGetLastError(opdev->hab); 2687dd7cddfSDavid du Colombier 269*3ff48bf5SDavid du Colombier errprintf("DevOpenDC for memory error 0x%x\n", eid); 2707dd7cddfSDavid du Colombier return gs_error_limitcheck; 2717dd7cddfSDavid du Colombier } 2727dd7cddfSDavid du Colombier sizlPage.cx = dev->width; 2737dd7cddfSDavid du Colombier sizlPage.cy = dev->height; 2747dd7cddfSDavid du Colombier opdev->hpsMem = GpiCreatePS(opdev->hab, opdev->hdcMem, &sizlPage, 2757dd7cddfSDavid du Colombier PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC); 2767dd7cddfSDavid du Colombier if (opdev->hpsMem == GPI_ERROR) { 2777dd7cddfSDavid du Colombier ERRORID eid = WinGetLastError(opdev->hab); 2787dd7cddfSDavid du Colombier 279*3ff48bf5SDavid du Colombier errprintf("GpiCreatePS for memory error 0x%x\n", eid); 2807dd7cddfSDavid du Colombier return gs_error_limitcheck; 2817dd7cddfSDavid du Colombier } 2827dd7cddfSDavid du Colombier if (DevEscape(opdev->hdc, DEVESC_STARTDOC, (LONG) strlen(gs_product), 2837dd7cddfSDavid du Colombier (char *)gs_product, NULL, NULL) == DEVESC_ERROR) { 2847dd7cddfSDavid du Colombier ERRORID eid = WinGetLastError(opdev->hab); 2857dd7cddfSDavid du Colombier 286*3ff48bf5SDavid du Colombier errprintf("DEVESC_STARTDOC error 0x%x\n", eid); 2877dd7cddfSDavid du Colombier return gs_error_limitcheck; 2887dd7cddfSDavid du Colombier } 2897dd7cddfSDavid du Colombier /* gdev_prn_open opens a temporary file which we don't want */ 2907dd7cddfSDavid du Colombier /* so we specify the name now so we can delete it later */ 2917dd7cddfSDavid du Colombier pfile = gp_open_scratch_file(gp_scratch_file_name_prefix, 2927dd7cddfSDavid du Colombier opdev->fname, "wb"); 2937dd7cddfSDavid du Colombier fclose(pfile); 2947dd7cddfSDavid du Colombier code = gdev_prn_open(dev); 2957dd7cddfSDavid du Colombier 2967dd7cddfSDavid du Colombier return code; 2977dd7cddfSDavid du Colombier } 2987dd7cddfSDavid du Colombier 2997dd7cddfSDavid du Colombier /* Close the os2prn driver */ 3007dd7cddfSDavid du Colombier private int 3017dd7cddfSDavid du Colombier os2prn_close(gx_device * dev) 3027dd7cddfSDavid du Colombier { 3037dd7cddfSDavid du Colombier int code; 3047dd7cddfSDavid du Colombier LONG lOut; 3057dd7cddfSDavid du Colombier USHORT usJobID; 3067dd7cddfSDavid du Colombier 3077dd7cddfSDavid du Colombier /* tell printer that all is finished */ 3087dd7cddfSDavid du Colombier DevEscape(opdev->hdc, DEVESC_ENDDOC, 0L, NULL, &lOut, (PBYTE) & usJobID); 3097dd7cddfSDavid du Colombier /* Free resources */ 3107dd7cddfSDavid du Colombier GpiAssociate(opdev->hps, (HDC) NULL); 3117dd7cddfSDavid du Colombier GpiDestroyPS(opdev->hps); 3127dd7cddfSDavid du Colombier DevCloseDC(opdev->hdc); 3137dd7cddfSDavid du Colombier 3147dd7cddfSDavid du Colombier if (opdev->hpsMem != GPI_ERROR) 3157dd7cddfSDavid du Colombier GpiDestroyPS(opdev->hpsMem); 3167dd7cddfSDavid du Colombier if (opdev->hdcMem != DEV_ERROR) 3177dd7cddfSDavid du Colombier DevCloseDC(opdev->hdcMem); 3187dd7cddfSDavid du Colombier 3197dd7cddfSDavid du Colombier code = gdev_prn_close(dev); 3207dd7cddfSDavid du Colombier /* delete unwanted temporary file */ 3217dd7cddfSDavid du Colombier unlink(opdev->fname); 3227dd7cddfSDavid du Colombier return code; 3237dd7cddfSDavid du Colombier } 3247dd7cddfSDavid du Colombier 3257dd7cddfSDavid du Colombier /* Get os2pm parameters */ 3267dd7cddfSDavid du Colombier int 3277dd7cddfSDavid du Colombier os2prn_get_params(gx_device * dev, gs_param_list * plist) 3287dd7cddfSDavid du Colombier { 3297dd7cddfSDavid du Colombier int code = gdev_prn_get_params(dev, plist); 3307dd7cddfSDavid du Colombier gs_param_string qs; 3317dd7cddfSDavid du Colombier 3327dd7cddfSDavid du Colombier qs.data = opdev->queue_name, qs.size = strlen(qs.data), 3337dd7cddfSDavid du Colombier qs.persistent = false; 3347dd7cddfSDavid du Colombier code < 0 || 3357dd7cddfSDavid du Colombier (code = param_write_string(plist, "OS2QUEUE", &qs)) < 0; 3367dd7cddfSDavid du Colombier return code; 3377dd7cddfSDavid du Colombier } 3387dd7cddfSDavid du Colombier 3397dd7cddfSDavid du Colombier 3407dd7cddfSDavid du Colombier 3417dd7cddfSDavid du Colombier /* We implement this ourselves so that we can change BitsPerPixel */ 3427dd7cddfSDavid du Colombier /* before the device is opened */ 3437dd7cddfSDavid du Colombier int 3447dd7cddfSDavid du Colombier os2prn_put_params(gx_device * dev, gs_param_list * plist) 3457dd7cddfSDavid du Colombier { 3467dd7cddfSDavid du Colombier int ecode = 0, code; 3477dd7cddfSDavid du Colombier int old_bpp = dev->color_info.depth; 3487dd7cddfSDavid du Colombier int bpp = old_bpp; 3497dd7cddfSDavid du Colombier gs_param_string qs; 3507dd7cddfSDavid du Colombier 3517dd7cddfSDavid du Colombier /* Handle extra parameters */ 3527dd7cddfSDavid du Colombier switch (code = param_read_string(plist, "OS2QUEUE", &qs)) { 3537dd7cddfSDavid du Colombier case 0: 3547dd7cddfSDavid du Colombier if (qs.size == strlen(opdev->queue_name) && 3557dd7cddfSDavid du Colombier !memcmp(opdev->queue_name, qs.data, qs.size) 3567dd7cddfSDavid du Colombier ) { 3577dd7cddfSDavid du Colombier qs.data = 0; 3587dd7cddfSDavid du Colombier break; 3597dd7cddfSDavid du Colombier } 3607dd7cddfSDavid du Colombier if (dev->is_open) 3617dd7cddfSDavid du Colombier ecode = gs_error_rangecheck; 3627dd7cddfSDavid du Colombier else if (qs.size >= sizeof(opdev->queue_name)) 3637dd7cddfSDavid du Colombier ecode = gs_error_limitcheck; 3647dd7cddfSDavid du Colombier else 3657dd7cddfSDavid du Colombier break; 3667dd7cddfSDavid du Colombier goto qe; 3677dd7cddfSDavid du Colombier default: 3687dd7cddfSDavid du Colombier ecode = code; 3697dd7cddfSDavid du Colombier qe:param_signal_error(plist, "OS2QUEUE", ecode); 3707dd7cddfSDavid du Colombier case 1: 3717dd7cddfSDavid du Colombier qs.data = 0; 3727dd7cddfSDavid du Colombier break; 3737dd7cddfSDavid du Colombier } 3747dd7cddfSDavid du Colombier 3757dd7cddfSDavid du Colombier switch (code = param_read_int(plist, "BitsPerPixel", &bpp)) { 3767dd7cddfSDavid du Colombier case 0: 3777dd7cddfSDavid du Colombier if (dev->is_open) 3787dd7cddfSDavid du Colombier ecode = gs_error_rangecheck; 3797dd7cddfSDavid du Colombier else { /* change dev->color_info is valid before device is opened */ 3807dd7cddfSDavid du Colombier os2prn_set_bpp(dev, bpp); 3817dd7cddfSDavid du Colombier break; 3827dd7cddfSDavid du Colombier } 3837dd7cddfSDavid du Colombier goto bppe; 3847dd7cddfSDavid du Colombier default: 3857dd7cddfSDavid du Colombier ecode = code; 3867dd7cddfSDavid du Colombier bppe:param_signal_error(plist, "BitsPerPixel", ecode); 3877dd7cddfSDavid du Colombier case 1: 3887dd7cddfSDavid du Colombier break; 3897dd7cddfSDavid du Colombier } 3907dd7cddfSDavid du Colombier 3917dd7cddfSDavid du Colombier if (ecode >= 0) 3927dd7cddfSDavid du Colombier ecode = gdev_prn_put_params(dev, plist); 3937dd7cddfSDavid du Colombier 3947dd7cddfSDavid du Colombier if ((ecode >= 0) && (qs.data != 0)) { 3957dd7cddfSDavid du Colombier memcpy(opdev->queue_name, qs.data, qs.size); 3967dd7cddfSDavid du Colombier opdev->queue_name[qs.size] = 0; 3977dd7cddfSDavid du Colombier } 3987dd7cddfSDavid du Colombier return ecode; 3997dd7cddfSDavid du Colombier } 4007dd7cddfSDavid du Colombier 4017dd7cddfSDavid du Colombier 4027dd7cddfSDavid du Colombier 4037dd7cddfSDavid du Colombier /* ------ Internal routines ------ */ 4047dd7cddfSDavid du Colombier 4057dd7cddfSDavid du Colombier #undef opdev 4067dd7cddfSDavid du Colombier #define opdev ((gx_device_os2prn *)pdev) 4077dd7cddfSDavid du Colombier 4087dd7cddfSDavid du Colombier /************************************************/ 4097dd7cddfSDavid du Colombier 4107dd7cddfSDavid du Colombier 4117dd7cddfSDavid du Colombier /* ------ Private definitions ------ */ 4127dd7cddfSDavid du Colombier 4137dd7cddfSDavid du Colombier 4147dd7cddfSDavid du Colombier /* new os2prn_print_page routine */ 4157dd7cddfSDavid du Colombier 4167dd7cddfSDavid du Colombier /* Write BMP header to memory, then send bitmap to printer */ 4177dd7cddfSDavid du Colombier /* one scan line at a time */ 4187dd7cddfSDavid du Colombier private int 4197dd7cddfSDavid du Colombier os2prn_print_page(gx_device_printer * pdev, FILE * file) 4207dd7cddfSDavid du Colombier { 4217dd7cddfSDavid du Colombier int raster = gdev_prn_raster(pdev); 4227dd7cddfSDavid du Colombier 4237dd7cddfSDavid du Colombier /* BMP scan lines are padded to 32 bits. */ 4247dd7cddfSDavid du Colombier ulong bmp_raster = (raster + 3) & (~3); 4257dd7cddfSDavid du Colombier ulong bmp_raster_multi; 4267dd7cddfSDavid du Colombier int height = pdev->height; 4277dd7cddfSDavid du Colombier int depth = pdev->color_info.depth; 4287dd7cddfSDavid du Colombier byte *row; 4297dd7cddfSDavid du Colombier int y; 4307dd7cddfSDavid du Colombier int code = 0; /* return code */ 4317dd7cddfSDavid du Colombier POINTL apts[4]; 4327dd7cddfSDavid du Colombier APIRET rc; 4337dd7cddfSDavid du Colombier POINTL aptsb[4]; 4347dd7cddfSDavid du Colombier HBITMAP hbmp, hbmr; 4357dd7cddfSDavid du Colombier int i, lines; 4367dd7cddfSDavid du Colombier int ystart, yend; 4377dd7cddfSDavid du Colombier int yslice; 4387dd7cddfSDavid du Colombier 4397dd7cddfSDavid du Colombier struct bmi_s { 4407dd7cddfSDavid du Colombier BITMAPINFOHEADER2 h; 4417dd7cddfSDavid du Colombier RGB2 pal[256]; 4427dd7cddfSDavid du Colombier } bmi; 4437dd7cddfSDavid du Colombier 4447dd7cddfSDavid du Colombier yslice = 65535 / bmp_raster; 4457dd7cddfSDavid du Colombier bmp_raster_multi = bmp_raster * yslice; 4467dd7cddfSDavid du Colombier row = (byte *) gs_malloc(bmp_raster_multi, 1, "bmp file buffer"); 4477dd7cddfSDavid du Colombier if (row == 0) /* can't allocate row buffer */ 4487dd7cddfSDavid du Colombier return_error(gs_error_VMerror); 4497dd7cddfSDavid du Colombier 4507dd7cddfSDavid du Colombier if (opdev->newframe) 4517dd7cddfSDavid du Colombier DevEscape(opdev->hdc, DEVESC_NEWFRAME, 0L, NULL, NULL, NULL); 4527dd7cddfSDavid du Colombier opdev->newframe = 1; 4537dd7cddfSDavid du Colombier 4547dd7cddfSDavid du Colombier /* Write the info header. */ 4557dd7cddfSDavid du Colombier 4567dd7cddfSDavid du Colombier memset(&bmi.h, 0, sizeof(bmi.h)); 4577dd7cddfSDavid du Colombier bmi.h.cbFix = sizeof(bmi.h); 4587dd7cddfSDavid du Colombier bmi.h.cx = pdev->width; /* opdev->mdev.width; */ 4597dd7cddfSDavid du Colombier /* bmi.h.cy = height; */ 4607dd7cddfSDavid du Colombier bmi.h.cy = yslice; /* size for memory PS */ 4617dd7cddfSDavid du Colombier bmi.h.cPlanes = 1; 4627dd7cddfSDavid du Colombier bmi.h.cBitCount = pdev->color_info.depth; 4637dd7cddfSDavid du Colombier 4647dd7cddfSDavid du Colombier /* Write the palette. */ 4657dd7cddfSDavid du Colombier 4667dd7cddfSDavid du Colombier if (depth <= 8) { 4677dd7cddfSDavid du Colombier int i; 4687dd7cddfSDavid du Colombier gx_color_value rgb[3]; 4697dd7cddfSDavid du Colombier PRGB2 pq; 4707dd7cddfSDavid du Colombier 4717dd7cddfSDavid du Colombier bmi.h.cclrUsed = 1 << depth; 4727dd7cddfSDavid du Colombier bmi.h.cclrImportant = 1 << depth; 4737dd7cddfSDavid du Colombier for (i = 0; i != 1 << depth; i++) { 4747dd7cddfSDavid du Colombier (*dev_proc(pdev, map_color_rgb)) ((gx_device *) pdev, 4757dd7cddfSDavid du Colombier (gx_color_index) i, rgb); 4767dd7cddfSDavid du Colombier pq = &bmi.pal[i]; 4777dd7cddfSDavid du Colombier pq->bRed = gx_color_value_to_byte(rgb[0]); 4787dd7cddfSDavid du Colombier pq->bGreen = gx_color_value_to_byte(rgb[1]); 4797dd7cddfSDavid du Colombier pq->bBlue = gx_color_value_to_byte(rgb[2]); 4807dd7cddfSDavid du Colombier pq->fcOptions = 0; 4817dd7cddfSDavid du Colombier } 4827dd7cddfSDavid du Colombier } else { 4837dd7cddfSDavid du Colombier bmi.h.cclrUsed = 0; 4847dd7cddfSDavid du Colombier bmi.h.cclrImportant = 0; 4857dd7cddfSDavid du Colombier } 4867dd7cddfSDavid du Colombier 4877dd7cddfSDavid du Colombier /* for GpiDrawBits */ 4887dd7cddfSDavid du Colombier /* target is inclusive */ 4897dd7cddfSDavid du Colombier apts[0].x = 0; 4907dd7cddfSDavid du Colombier apts[0].y = 0; /* filled in later */ 4917dd7cddfSDavid du Colombier apts[1].x = pdev->width - 1; 4927dd7cddfSDavid du Colombier apts[1].y = 0; /* filled in later */ 4937dd7cddfSDavid du Colombier /* source is not inclusive of top & right borders */ 4947dd7cddfSDavid du Colombier apts[2].x = 0; 4957dd7cddfSDavid du Colombier apts[2].y = 0; 4967dd7cddfSDavid du Colombier apts[3].x = pdev->width; 4977dd7cddfSDavid du Colombier apts[3].y = 0; /* filled in later */ 4987dd7cddfSDavid du Colombier 4997dd7cddfSDavid du Colombier /* for GpiBitBlt */ 5007dd7cddfSDavid du Colombier /* target is not inclusive */ 5017dd7cddfSDavid du Colombier aptsb[0].x = opdev->clipbox[0]; 5027dd7cddfSDavid du Colombier aptsb[0].y = 0; /* filled in later */ 5037dd7cddfSDavid du Colombier aptsb[1].x = opdev->clipbox[2]; 5047dd7cddfSDavid du Colombier aptsb[1].y = 0; /* filled in later */ 5057dd7cddfSDavid du Colombier /* source is not inclusive */ 5067dd7cddfSDavid du Colombier aptsb[2].x = opdev->clipbox[0]; 5077dd7cddfSDavid du Colombier aptsb[2].y = 0; 5087dd7cddfSDavid du Colombier aptsb[3].x = opdev->clipbox[2]; 5097dd7cddfSDavid du Colombier aptsb[3].y = 0; /* filled in later */ 5107dd7cddfSDavid du Colombier 5117dd7cddfSDavid du Colombier /* write the bits */ 5127dd7cddfSDavid du Colombier ystart = opdev->clipbox[3]; 5137dd7cddfSDavid du Colombier yend = opdev->clipbox[1]; 5147dd7cddfSDavid du Colombier y = ystart; 5157dd7cddfSDavid du Colombier while (y > yend) { 5167dd7cddfSDavid du Colombier /* create a bitmap for the memory DC */ 5177dd7cddfSDavid du Colombier hbmp = GpiCreateBitmap(opdev->hpsMem, &bmi.h, 0L, NULL, NULL); 5187dd7cddfSDavid du Colombier if (hbmp == GPI_ERROR) 5197dd7cddfSDavid du Colombier goto bmp_done; 5207dd7cddfSDavid du Colombier hbmr = GpiSetBitmap(opdev->hpsMem, hbmp); 5217dd7cddfSDavid du Colombier 5227dd7cddfSDavid du Colombier /* copy slice to memory bitmap */ 5237dd7cddfSDavid du Colombier if (y > yend + yslice) 5247dd7cddfSDavid du Colombier lines = yslice; 5257dd7cddfSDavid du Colombier else 5267dd7cddfSDavid du Colombier lines = y - yend; 5277dd7cddfSDavid du Colombier y -= lines; 5287dd7cddfSDavid du Colombier for (i = lines - 1; i >= 0; i--) 5297dd7cddfSDavid du Colombier gdev_prn_copy_scan_lines(pdev, ystart - 1 - (y + i), row + (bmp_raster * i), raster); 5307dd7cddfSDavid du Colombier apts[0].y = 0; /* target */ 5317dd7cddfSDavid du Colombier apts[1].y = lines; 5327dd7cddfSDavid du Colombier apts[3].y = lines - 1; /* source */ 5337dd7cddfSDavid du Colombier /* copy DIB bitmap to memory bitmap */ 5347dd7cddfSDavid du Colombier rc = GpiDrawBits(opdev->hpsMem, row, (BITMAPINFO2 *) & bmi, 4, apts, 5357dd7cddfSDavid du Colombier (depth != 1) ? ROP_SRCCOPY : ROP_NOTSRCCOPY, 0); 5367dd7cddfSDavid du Colombier 5377dd7cddfSDavid du Colombier /* copy slice to printer */ 5387dd7cddfSDavid du Colombier aptsb[0].y = y; 5397dd7cddfSDavid du Colombier aptsb[1].y = y + lines; 5407dd7cddfSDavid du Colombier aptsb[3].y = lines; 5417dd7cddfSDavid du Colombier rc = GpiBitBlt(opdev->hps, opdev->hpsMem, 4, aptsb, ROP_SRCCOPY, BBO_IGNORE); 5427dd7cddfSDavid du Colombier 5437dd7cddfSDavid du Colombier /* delete bitmap */ 5447dd7cddfSDavid du Colombier if (hbmr != HBM_ERROR) 5457dd7cddfSDavid du Colombier GpiSetBitmap(opdev->hpsMem, (ULONG) 0); 5467dd7cddfSDavid du Colombier hbmr = HBM_ERROR; 5477dd7cddfSDavid du Colombier if (hbmp != GPI_ERROR) 5487dd7cddfSDavid du Colombier GpiDeleteBitmap(hbmp); 5497dd7cddfSDavid du Colombier hbmp = GPI_ERROR; 5507dd7cddfSDavid du Colombier } 5517dd7cddfSDavid du Colombier 5527dd7cddfSDavid du Colombier bmp_done: 5537dd7cddfSDavid du Colombier if (row) 5547dd7cddfSDavid du Colombier gs_free((char *)row, bmp_raster_multi, 1, "bmp file buffer"); 5557dd7cddfSDavid du Colombier 5567dd7cddfSDavid du Colombier return code; 5577dd7cddfSDavid du Colombier } 5587dd7cddfSDavid du Colombier 5597dd7cddfSDavid du Colombier /* combined color mappers */ 5607dd7cddfSDavid du Colombier 5617dd7cddfSDavid du Colombier /* 24-bit color mappers (taken from gdevmem2.c). */ 5627dd7cddfSDavid du Colombier /* Note that OS/2 expects RGB values in the order B,G,R. */ 5637dd7cddfSDavid du Colombier 5647dd7cddfSDavid du Colombier /* Map a r-g-b color to a color index. */ 5657dd7cddfSDavid du Colombier private gx_color_index 5667dd7cddfSDavid du Colombier os2prn_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g, 5677dd7cddfSDavid du Colombier gx_color_value b) 5687dd7cddfSDavid du Colombier { 5697dd7cddfSDavid du Colombier switch (dev->color_info.depth) { 5707dd7cddfSDavid du Colombier case 1: 5717dd7cddfSDavid du Colombier return gdev_prn_map_rgb_color(dev, r, g, b); 5727dd7cddfSDavid du Colombier case 4: 5737dd7cddfSDavid du Colombier /* use only 8 colors */ 5747dd7cddfSDavid du Colombier return (r > (gx_max_color_value / 2 + 1) ? 4 : 0) + 5757dd7cddfSDavid du Colombier (g > (gx_max_color_value / 2 + 1) ? 2 : 0) + 5767dd7cddfSDavid du Colombier (b > (gx_max_color_value / 2 + 1) ? 1 : 0); 5777dd7cddfSDavid du Colombier case 8: 5787dd7cddfSDavid du Colombier return pc_8bit_map_rgb_color(dev, r, g, b); 5797dd7cddfSDavid du Colombier case 24: 5807dd7cddfSDavid du Colombier return gx_color_value_to_byte(r) + 5817dd7cddfSDavid du Colombier ((uint) gx_color_value_to_byte(g) << 8) + 5827dd7cddfSDavid du Colombier ((ulong) gx_color_value_to_byte(b) << 16); 5837dd7cddfSDavid du Colombier } 5847dd7cddfSDavid du Colombier return 0; /* error */ 5857dd7cddfSDavid du Colombier } 5867dd7cddfSDavid du Colombier 5877dd7cddfSDavid du Colombier /* Map a color index to a r-g-b color. */ 5887dd7cddfSDavid du Colombier private int 5897dd7cddfSDavid du Colombier os2prn_map_color_rgb(gx_device * dev, gx_color_index color, 5907dd7cddfSDavid du Colombier gx_color_value prgb[3]) 5917dd7cddfSDavid du Colombier { 5927dd7cddfSDavid du Colombier switch (dev->color_info.depth) { 5937dd7cddfSDavid du Colombier case 1: 5947dd7cddfSDavid du Colombier gdev_prn_map_color_rgb(dev, color, prgb); 5957dd7cddfSDavid du Colombier break; 5967dd7cddfSDavid du Colombier case 4: 5977dd7cddfSDavid du Colombier /* use only 8 colors */ 5987dd7cddfSDavid du Colombier prgb[0] = (color & 4) ? gx_max_color_value : 0; 5997dd7cddfSDavid du Colombier prgb[1] = (color & 2) ? gx_max_color_value : 0; 6007dd7cddfSDavid du Colombier prgb[2] = (color & 1) ? gx_max_color_value : 0; 6017dd7cddfSDavid du Colombier break; 6027dd7cddfSDavid du Colombier case 8: 6037dd7cddfSDavid du Colombier pc_8bit_map_color_rgb(dev, color, prgb); 6047dd7cddfSDavid du Colombier break; 6057dd7cddfSDavid du Colombier case 24: 6067dd7cddfSDavid du Colombier prgb[2] = gx_color_value_from_byte(color >> 16); 6077dd7cddfSDavid du Colombier prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff); 6087dd7cddfSDavid du Colombier prgb[0] = gx_color_value_from_byte(color & 0xff); 6097dd7cddfSDavid du Colombier break; 6107dd7cddfSDavid du Colombier } 6117dd7cddfSDavid du Colombier return 0; 6127dd7cddfSDavid du Colombier } 6137dd7cddfSDavid du Colombier 6147dd7cddfSDavid du Colombier void 6157dd7cddfSDavid du Colombier os2prn_set_bpp(gx_device * dev, int depth) 6167dd7cddfSDavid du Colombier { 6177dd7cddfSDavid du Colombier if (depth > 8) { 6187dd7cddfSDavid du Colombier static const gx_device_color_info os2prn_24color = dci_std_color(24); 6197dd7cddfSDavid du Colombier 6207dd7cddfSDavid du Colombier dev->color_info = os2prn_24color; 6217dd7cddfSDavid du Colombier } else if (depth >= 8) { 6227dd7cddfSDavid du Colombier /* 8-bit (SuperVGA-style) color. */ 6237dd7cddfSDavid du Colombier /* (Uses a fixed palette of 3,3,2 bits.) */ 6247dd7cddfSDavid du Colombier static const gx_device_color_info os2prn_8color = dci_pc_8bit; 6257dd7cddfSDavid du Colombier 6267dd7cddfSDavid du Colombier dev->color_info = os2prn_8color; 6277dd7cddfSDavid du Colombier } else if (depth >= 3) { 6287dd7cddfSDavid du Colombier /* 3 plane printer */ 6297dd7cddfSDavid du Colombier /* suitable for impact dot matrix CMYK printers */ 6307dd7cddfSDavid du Colombier /* create 4-bit bitmap, but only use 8 colors */ 631*3ff48bf5SDavid du Colombier static const gx_device_color_info os2prn_4color = dci_values(3, 4, 1, 1, 2, 2); 6327dd7cddfSDavid du Colombier 6337dd7cddfSDavid du Colombier dev->color_info = os2prn_4color; 6347dd7cddfSDavid du Colombier } else { /* default is black_and_white */ 6357dd7cddfSDavid du Colombier static const gx_device_color_info os2prn_1color = dci_std_color(1); 6367dd7cddfSDavid du Colombier 6377dd7cddfSDavid du Colombier dev->color_info = os2prn_1color; 6387dd7cddfSDavid du Colombier } 6397dd7cddfSDavid du Colombier } 6407dd7cddfSDavid du Colombier 6417dd7cddfSDavid du Colombier /* Get list of queues from SplEnumQueue */ 6427dd7cddfSDavid du Colombier /* returns 0 if OK, non-zero for error */ 6437dd7cddfSDavid du Colombier private int 6447dd7cddfSDavid du Colombier os2prn_get_queue_list(OS2QL * ql) 6457dd7cddfSDavid du Colombier { 6467dd7cddfSDavid du Colombier SPLERR splerr; 6477dd7cddfSDavid du Colombier USHORT jobCount; 6487dd7cddfSDavid du Colombier ULONG cbBuf; 6497dd7cddfSDavid du Colombier ULONG cTotal; 6507dd7cddfSDavid du Colombier ULONG cReturned; 6517dd7cddfSDavid du Colombier ULONG cbNeeded; 6527dd7cddfSDavid du Colombier ULONG ulLevel; 6537dd7cddfSDavid du Colombier ULONG i; 6547dd7cddfSDavid du Colombier PSZ pszComputerName; 6557dd7cddfSDavid du Colombier PBYTE pBuf; 6567dd7cddfSDavid du Colombier PPRQINFO3 prq; 6577dd7cddfSDavid du Colombier 6587dd7cddfSDavid du Colombier ulLevel = 3L; 6597dd7cddfSDavid du Colombier pszComputerName = (PSZ) NULL; 6607dd7cddfSDavid du Colombier splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, 0L, /* cbBuf */ 6617dd7cddfSDavid du Colombier &cReturned, &cTotal, 6627dd7cddfSDavid du Colombier &cbNeeded, NULL); 6637dd7cddfSDavid du Colombier if (splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall) { 6647dd7cddfSDavid du Colombier pBuf = gs_malloc(cbNeeded, 1, "OS/2 printer device info buffer"); 6657dd7cddfSDavid du Colombier ql->prq = (PRQINFO3 *) pBuf; 6667dd7cddfSDavid du Colombier if (ql->prq != (PRQINFO3 *) NULL) { 6677dd7cddfSDavid du Colombier ql->len = cbNeeded; 6687dd7cddfSDavid du Colombier cbBuf = cbNeeded; 6697dd7cddfSDavid du Colombier splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, cbBuf, 6707dd7cddfSDavid du Colombier &cReturned, &cTotal, 6717dd7cddfSDavid du Colombier &cbNeeded, NULL); 6727dd7cddfSDavid du Colombier if (splerr == NO_ERROR) { 6737dd7cddfSDavid du Colombier /* Set pointer to point to the beginning of the buffer. */ 6747dd7cddfSDavid du Colombier prq = (PPRQINFO3) pBuf; 6757dd7cddfSDavid du Colombier /* cReturned has the count of the number of PRQINFO3 structures. */ 6767dd7cddfSDavid du Colombier ql->nqueues = cReturned; 6777dd7cddfSDavid du Colombier ql->defqueue = 0; 6787dd7cddfSDavid du Colombier for (i = 0; i < cReturned; i++) { 6797dd7cddfSDavid du Colombier if (prq->fsType & PRQ3_TYPE_APPDEFAULT) 6807dd7cddfSDavid du Colombier ql->defqueue = i; 6817dd7cddfSDavid du Colombier prq++; 6827dd7cddfSDavid du Colombier } /*endfor cReturned */ 6837dd7cddfSDavid du Colombier } 6847dd7cddfSDavid du Colombier } 6857dd7cddfSDavid du Colombier } else { 6867dd7cddfSDavid du Colombier /* If we are here we had a bad error code. Print it and some other info. */ 687*3ff48bf5SDavid du Colombier eprintf4("SplEnumQueue Error=%ld, Total=%ld, Returned=%ld, Needed=%ld\n", 6887dd7cddfSDavid du Colombier splerr, cTotal, cReturned, cbNeeded); 6897dd7cddfSDavid du Colombier } 6907dd7cddfSDavid du Colombier if (splerr) 6917dd7cddfSDavid du Colombier return splerr; 6927dd7cddfSDavid du Colombier return 0; 6937dd7cddfSDavid du Colombier } 6947dd7cddfSDavid du Colombier 6957dd7cddfSDavid du Colombier 6967dd7cddfSDavid du Colombier private void 6977dd7cddfSDavid du Colombier os2prn_free_queue_list(OS2QL * ql) 6987dd7cddfSDavid du Colombier { 6997dd7cddfSDavid du Colombier gs_free((char *)ql->prq, ql->len, 1, "os2prn queue list"); 7007dd7cddfSDavid du Colombier ql->prq = NULL; 7017dd7cddfSDavid du Colombier ql->len = 0; 7027dd7cddfSDavid du Colombier ql->defqueue = 0; 7037dd7cddfSDavid du Colombier ql->nqueues = 0; 7047dd7cddfSDavid du Colombier } 705