BOOL PrnQueryHardcopyCaps(HDC hdc, PHCINFO pHCInfo) { if (!hdc || !pHCInfo) return FALSE; // query how many forms are available long lAvail = DevQueryHardcopyCaps(hdc, 0, 0, 0); PHCINFO pBuffer = (PHCINFO)malloc(lAvail * sizeof(HCINFO)); DevQueryHardcopyCaps(hdc, 0, lAvail, pBuffer); BOOL rc = FALSE; for (long i = 0; i < lAvail; i++) { if (pBuffer[i].flAttributes & HCAPS_CURRENT) { memcpy(pHCInfo, &pBuffer[i], sizeof(HCINFO)); rc = TRUE; break; } } free( pBuffer); return rc; }
/* Open the os2prn driver */ static int os2prn_open(gx_device * dev) { int code; PTIB pptib; PPIB pppib; DEVOPENSTRUC dop; ULONG cbBuf; ULONG cbNeeded; APIRET rc; PBYTE pbuf; char *p; SIZEL sizlPage; LONG caps[2]; HCINFO hcinfo; LONG nforms; float m[4]; int depth; FILE *pfile; int i; char *prefix = "\\\\spool\\"; /* 8 characters long */ PRQINFO3 *pprq; gx_device_os2prn *oprn; oprn = opdev; if (DosGetInfoBlocks(&pptib, &pppib)) { errprintf("\nos2prn_open: Couldn't get pid\n"); return gs_error_limitcheck; } if (pppib->pib_ultype != 3) { /* if caller is not PM app */ errprintf("os2prn device can only be used from a PM application\n"); return gs_error_limitcheck; } opdev->hab = WinQueryAnchorBlock(hwndtext); opdev->newframe = 0; if (os2prn_get_queue_list(dev->memory, &opdev->ql)) return gs_error_limitcheck; if (opdev->queue_name[0] == '\0') { /* obtain printer name from filename */ p = opdev->fname; for (i = 0; i < 8; i++) { if (prefix[i] == '\\') { if ((*p != '\\') && (*p != '/')) break; } else if (tolower(*p) != prefix[i]) break; p++; } if (i == 8 && (strlen(p) != 0)) strcpy(opdev->queue_name, p); } pprq = NULL; if (opdev->queue_name[0] != '\0') { for (i = 0; i < opdev->ql.nqueues; i++) { if (strcmp(opdev->ql.prq[i].pszName, opdev->queue_name) == 0) { pprq = &(opdev->ql.prq[i]); break; } } } else { /* use default queue */ pprq = &(opdev->ql.prq[opdev->ql.defqueue]); } if (pprq == (PRQINFO3 *) NULL) { errprintf("Invalid os2prn queue name -sOS2QUEUE=\042%s\042\n", opdev->queue_name); errprintf("Valid device names are:\n"); for (i = 0; i < opdev->ql.nqueues; i++) { errprintf(" -sOS2QUEUE=\042%s\042\n", opdev->ql.prq[i].pszName); } return gs_error_rangecheck; } /* open printer device */ memset(&dop, 0, sizeof(dop)); dop.pszLogAddress = pprq->pszName; /* queue name */ p = strchr(pprq->pszDriverName, '.'); if (p != (char *)NULL) *p = '\0'; dop.pszDriverName = pprq->pszDriverName; dop.pszDataType = "PM_Q_STD"; dop.pdriv = pprq->pDriverData; opdev->hdc = DevOpenDC(opdev->hab, OD_QUEUED, "*", 9L, (PDEVOPENDATA) & dop, (HDC) NULL); if (opdev->hdc == DEV_ERROR) { ERRORID eid = WinGetLastError(opdev->hab); errprintf("DevOpenDC for printer error 0x%x\n", eid); return gs_error_limitcheck; } os2prn_free_queue_list(dev->memory, &opdev->ql); /* find out resolution of printer */ /* this is returned in pixels/metre */ DevQueryCaps(opdev->hdc, CAPS_HORIZONTAL_RESOLUTION, 2, caps); dev->x_pixels_per_inch = (int)(caps[0] * 0.0254 + 0.5); dev->y_pixels_per_inch = (int)(caps[1] * 0.0254 + 0.5); /* find out page size and margins */ /* these are returned in millimetres */ nforms = DevQueryHardcopyCaps(opdev->hdc, 0, 0, &hcinfo); for (i = 0; i < nforms; i++) { DevQueryHardcopyCaps(opdev->hdc, i, 1, &hcinfo); if (hcinfo.flAttributes & HCAPS_CURRENT) break; /* this is the default page size */ } /* GS size is in pixels */ dev->width = hcinfo.cx * caps[0] / 1000; dev->height = hcinfo.cy * caps[1] / 1000; /* GS margins are in inches */ m[0] /*left */ = hcinfo.xLeftClip / 25.4; m[1] /*bottom */ = hcinfo.yBottomClip / 25.4; m[2] /*right */ = (hcinfo.cx - hcinfo.xRightClip) / 25.4; m[3] /*top */ = (hcinfo.cy - hcinfo.yTopClip) / 25.4; gx_device_set_margins(dev, m, true); /* set bounding box in pixels for later drawing */ opdev->clipbox[0] = (int)(hcinfo.xLeftClip / 25.4 * dev->x_pixels_per_inch + 1); /* round inwards */ opdev->clipbox[1] = (int)(hcinfo.yBottomClip / 25.4 * dev->y_pixels_per_inch + 1); opdev->clipbox[2] = (int)(hcinfo.xRightClip / 25.4 * dev->x_pixels_per_inch); opdev->clipbox[3] = (int)(hcinfo.yTopClip / 25.4 * dev->y_pixels_per_inch); /* get presentation space */ sizlPage.cx = dev->width; sizlPage.cy = dev->height; opdev->hps = GpiCreatePS(opdev->hab, opdev->hdc, &sizlPage, PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC); depth = dev->color_info.depth; if (depth == 0) { /* Set parameters that were unknown before opening device */ /* Find out if the device supports color */ /* We recognize 1 bit monochrome and 24 bit color devices */ DevQueryCaps(opdev->hdc, CAPS_COLOR_PLANES, 2, caps); /* caps[0] is #color planes, caps[1] is #bits per plane */ depth = caps[0] * caps[1]; if (depth > 1) depth = 24; } os2prn_set_bpp(dev, depth); /* create a memory DC compatible with printer */ opdev->hdcMem = DevOpenDC(opdev->hab, OD_MEMORY, "*", 0L, NULL, opdev->hdc); if (opdev->hdcMem == DEV_ERROR) { ERRORID eid = WinGetLastError(opdev->hab); errprintf("DevOpenDC for memory error 0x%x\n", eid); return gs_error_limitcheck; } sizlPage.cx = dev->width; sizlPage.cy = dev->height; opdev->hpsMem = GpiCreatePS(opdev->hab, opdev->hdcMem, &sizlPage, PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC); if (opdev->hpsMem == GPI_ERROR) { ERRORID eid = WinGetLastError(opdev->hab); errprintf("GpiCreatePS for memory error 0x%x\n", eid); return gs_error_limitcheck; } if (DevEscape(opdev->hdc, DEVESC_STARTDOC, (LONG) strlen(gs_product), (char *)gs_product, NULL, NULL) == DEVESC_ERROR) { ERRORID eid = WinGetLastError(opdev->hab); errprintf("DEVESC_STARTDOC error 0x%x\n", eid); return gs_error_limitcheck; } /* gdev_prn_open opens a temporary file which we don't want */ /* so we specify the name now so we can delete it later */ pfile = gp_open_scratch_file(gp_scratch_file_name_prefix, opdev->fname, "wb"); fclose(pfile); code = gdev_prn_open(dev); return code; }