From 4b16c717e5fe978a544bab5ce69bfd8edad31819 Mon Sep 17 00:00:00 2001 From: Michael Sweet Date: Tue, 29 Aug 2017 17:27:49 -0400 Subject: [PATCH] Move test client program to filter directory, finish initial implementation. --- cups/Makefile | 10 - filter/Makefile | 14 +- {cups => filter}/testclient.c | 334 ++++++++++++++++++++++++++++++++-- 3 files changed, 333 insertions(+), 25 deletions(-) rename {cups => filter}/testclient.c (60%) diff --git a/cups/Makefile b/cups/Makefile index 6a07ba5f7..9a220c851 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -411,16 +411,6 @@ testcache: testcache.o $(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) -# -# testclient (dependency on static CUPS library is intentional) -# - -testclient: testclient.o $(LIBCUPSSTATIC) - echo Linking $@... - $(LD_CC) $(LDFLAGS) -o $@ testclient.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) - - # # testconflicts (dependency on static CUPS library is intentional) # diff --git a/filter/Makefile b/filter/Makefile index fc53f85c6..02aab14d8 100644 --- a/filter/Makefile +++ b/filter/Makefile @@ -29,6 +29,7 @@ LIBTARGETS = \ libcupsimage.a UNITTARGETS = \ rasterbench \ + testclient \ testraster TARGETS = \ $(LIBTARGETS) \ @@ -38,7 +39,7 @@ IMAGEOBJS = error.o interpret.o raster.o OBJS = $(IMAGEOBJS) \ commandtops.o gziptoany.o common.o pstops.o \ rasterbench.o rastertoepson.o rastertohp.o rastertolabel.o \ - rastertopwg.o testraster.o + rastertopwg.o testclient.o testraster.o # @@ -340,6 +341,17 @@ rastertopwg-static: rastertopwg.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a $(SSLLIBS) $(DNSSDLIBS) $(LIBGSSAPI) +# +# testclient (dependency on static libraries is intentional) +# + +testclient: testclient.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a + echo Linking $@... + $(LD_CC) $(LDFLAGS) -o $@ testclient.o \ + libcupsimage.a ../cups/$(LIBCUPSSTATIC) \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + # # testraster # diff --git a/cups/testclient.c b/filter/testclient.c similarity index 60% rename from cups/testclient.c rename to filter/testclient.c index c936d2645..d6ad4249c 100644 --- a/cups/testclient.c +++ b/filter/testclient.c @@ -16,10 +16,12 @@ * Include necessary headers... */ -#include "cups.h" -#include "raster.h" -#include "thread-private.h" +#include #include +#include +#include +#include +#include /* @@ -155,7 +157,7 @@ main(int argc, /* I - Number of command-line arguments */ * Connect to the printer... */ - if (httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), username, sizeof(username), hostname, sizeof(hostname), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) { printf("Bad printer URI '%s'.\n", uri); return (1); @@ -265,7 +267,7 @@ main(int argc, /* I - Number of command-line arguments */ else opt = printfile; - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_name, "job-name", NULL, opt); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, opt); response = cupsDoRequest(http, request, resource); @@ -291,11 +293,12 @@ main(int argc, /* I - Number of command-line arguments */ ippDelete(response); - request = ippNewRequest(IPP_OP_CREATE_JOB); + request = ippNewRequest(IPP_OP_SEND_DOCUMENT); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", monitor.job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, printformat); + ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); response = cupsDoFileRequest(http, request, resource, printfile); @@ -336,6 +339,311 @@ make_raster_file(ipp_t *response, /* I - Printer attributes */ size_t tempsize, /* I - Size of temp file buffer */ const char **format) /* O - Print format */ { + int i, /* Looping var */ + count; /* Number of values */ + ipp_attribute_t *attr; /* Printer attribute */ + const char *type = NULL; /* Raster type (colorspace + bits) */ + pwg_media_t *media = NULL; /* Media size */ + int xdpi = 0, /* Horizontal resolution */ + ydpi = 0; /* Vertical resolution */ + int fd; /* Temporary file */ + cups_mode_t mode; /* Raster mode */ + cups_raster_t *ras; /* Raster stream */ + cups_page_header2_t header; /* Page header */ + unsigned char *line, /* Line of raster data */ + *lineptr; /* Pointer into line */ + unsigned y, /* Current position on page */ + xcount, ycount, /* Current count for X and Y */ + xrep, yrep, /* Repeat count for X and Y */ + xoff, yoff, /* Offsets for X and Y */ + yend; /* End Y value */ + int temprow, /* Row in template */ + tempcolor; /* Template color */ + const char *template; /* Pointer into template */ + const unsigned char *color; /* Current color */ + static const unsigned char colors[][3] = + { /* Colors for test */ + { 191, 191, 191 }, + { 127, 127, 127 }, + { 63, 63, 63 }, + { 0, 0, 0 }, + { 255, 0, 0 }, + { 255, 127, 0 }, + { 255, 255, 0 }, + { 127, 255, 0 }, + { 0, 255, 0 }, + { 0, 255, 127 }, + { 0, 255, 255 }, + { 0, 127, 255 }, + { 0, 0, 255 }, + { 127, 0, 255 }, + { 255, 0, 255 } + }; + static const char * const templates[] = + { /* Raster template */ + " CCC U U PPPP SSS TTTTT EEEEE SSS TTTTT 000 1 222 333 4 55555 66 77777 888 999 ", + "C C U U P P S S T E S S T 0 0 11 2 2 3 3 4 4 5 6 7 8 8 9 9 ", + "C U U P P S T E S T 0 0 1 2 3 4 4 5 6 7 8 8 9 9 ", + "C U U PPPP SSS ----- T EEEE SSS T 0 0 0 1 22 333 44444 555 6666 7 888 9999 ", + "C U U P S T E S T 0 0 1 2 3 4 5 6 6 7 8 8 9 ", + "C C U U P S S T E S S T 0 0 1 2 3 3 4 5 5 6 6 7 8 8 9 ", + " CCC UUU P SSS T EEEEE SSS T 000 111 22222 333 4 555 666 7 888 99 ", + " " + }; + + + /* + * Figure out the output format... + */ + + if ((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) == NULL) + { + puts("No supported document formats, aborting."); + return (NULL); + } + + if (ippContainsString(attr, "image/urf")) + { + /* + * Apple Raster format... + */ + + *format = "image/urf"; + mode = CUPS_RASTER_WRITE_APPLE; + } + else if (ippContainsString(attr, "image/pwg-raster")) + { + /* + * PWG Raster format... + */ + + *format = "image/pwg-raster"; + mode = CUPS_RASTER_WRITE_PWG; + } + else + { + /* + * No supported raster format... + */ + + puts("Printer does not support Apple or PWG raster files, aborting."); + return (NULL); + } + + /* + * Figure out the the media, resolution, and color mode... + */ + + if ((attr = ippFindAttribute(response, "media-default", IPP_TAG_KEYWORD)) != NULL) + { + /* + * Use default media... + */ + + media = pwgMediaForPWG(ippGetString(attr, 0, NULL)); + } + else if ((attr = ippFindAttribute(response, "media-ready", IPP_TAG_KEYWORD)) != NULL) + { + /* + * Use ready media... + */ + + if (ippContainsString(attr, "na_letter_8.5x11in")) + media = pwgMediaForPWG("na_letter_8.5x11in"); + else if (ippContainsString(attr, "iso_a4_210x297mm")) + media = pwgMediaForPWG("iso_a4_210x297mm"); + else + media = pwgMediaForPWG(ippGetString(attr, 0, NULL)); + } + else + { + puts("No default or ready media reported by printer, aborting."); + return (NULL); + } + + if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) + { + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + const char *val = ippGetString(attr, i, NULL); + + if (val[0] == 'R') + xdpi = ydpi = atoi(val + 1); + else if (!strcmp(val, "W8") && !type) + type = "sgray_8"; + else if (!strcmp(val, "SRGB24")) + type = "srgb_8"; + } + } + else if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) + { + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + int tempxdpi, tempydpi; + ipp_res_t tempunits; + + tempxdpi = ippGetResolution(attr, 0, &tempydpi, &tempunits); + + if (i == 0 || tempxdpi < xdpi || tempydpi < ydpi) + { + xdpi = tempxdpi; + ydpi = tempydpi; + } + } + + if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) != NULL) + { + if (ippContainsString(attr, "srgb_8")) + type = "srgb_8"; + else if (ippContainsString(attr, "sgray_8")) + type = "sgray_8"; + } + } + + if (xdpi < 72 || ydpi < 72) + { + puts("No supported raster resolutions, aborting."); + return (NULL); + } + + if (!type) + { + puts("No supported color spaces or bit depths, aborting."); + return (NULL); + } + + /* + * Make the raster context and details... + */ + + if (!cupsRasterInitPWGHeader(&header, media, type, xdpi, ydpi, "one-sided", NULL)) + { + printf("Unable to initialize raster context: %s\n", cupsRasterErrorString()); + return (NULL); + } + + header.cupsInteger[CUPS_RASTER_PWG_TotalPageCount] = 1; + + if (header.cupsWidth > (4 * header.HWResolution[0])) + { + xoff = header.HWResolution[0] / 2; + yoff = header.HWResolution[1] / 2; + } + else + { + xoff = 0; + yoff = 0; + } + + xrep = (header.cupsWidth - 2 * xoff) / 140; + yrep = xrep * header.HWResolution[1] / header.HWResolution[0]; + yend = header.cupsHeight - yoff; + + /* + * Prepare the raster file... + */ + + if ((line = malloc(header.cupsBytesPerLine)) == NULL) + { + printf("Unable to allocate %u bytes for raster output: %s\n", header.cupsBytesPerLine, strerror(errno)); + return (NULL); + } + + if ((fd = cupsTempFd(tempname, (int)tempsize)) < 0) + { + printf("Unable to create temporary print file: %s\n", strerror(errno)); + return (NULL); + } + + if ((ras = cupsRasterOpen(fd, mode)) == NULL) + { + printf("Unable to open raster stream: %s\n", cupsRasterErrorString()); + close(fd); + return (NULL); + } + + /* + * Write a single page consisting of the template dots repeated over the page. + */ + + cupsRasterWriteHeader2(ras, &header); + + memset(line, 0xff, header.cupsBytesPerLine); + + for (y = 0; y < yoff; y ++) + cupsRasterWritePixels(ras, line, header.cupsBytesPerLine); + + for (temprow = 0, tempcolor = 0; y < yend; y ++) + { + template = templates[temprow]; + color = colors[tempcolor]; + + temprow ++; + if (temprow >= (int)(sizeof(templates) / sizeof(templates[0]))) + { + temprow = 0; + tempcolor ++; + if (tempcolor >= (int)(sizeof(colors) / sizeof(colors[0]))) + tempcolor = 0; + } + + memset(line, 0xff, header.cupsBytesPerLine); + + if (header.cupsColorSpace == CUPS_CSPACE_SW) + { + /* + * Do grayscale output... + */ + + for (lineptr = line + xoff; *template; template ++) + { + if (*template != ' ') + { + for (xcount = xrep; xcount > 0; xcount --) + *lineptr++ = *color; + } + else + { + lineptr += xrep; + } + } + } + else + { + /* + * Do color output... + */ + + for (lineptr = line + 3 * xoff; *template; template ++) + { + if (*template != ' ') + { + for (xcount = xrep; xcount > 0; xcount --, lineptr += 3) + memcpy(lineptr, color, 3); + } + else + { + lineptr += 3 * xrep; + } + } + } + + for (ycount = yrep; ycount > 0 && y < yend; ycount --, y ++) + cupsRasterWritePixels(ras, line, header.cupsBytesPerLine); + } + + memset(line, 0xff, header.cupsBytesPerLine); + + for (y = 0; y < header.cupsHeight; y ++) + cupsRasterWritePixels(ras, line, header.cupsBytesPerLine); + + cupsRasterClose(ras); + + close(fd); + + printf("PRINT FILE: %s\n", tempname); + + return (tempname); } @@ -354,7 +662,6 @@ monitor_printer( ipp_pstate_t printer_state; /* Printer state */ char printer_state_reasons[1024]; /* Printer state reasons */ - int job_id; /* Job ID */ ipp_jstate_t job_state; /* Job state */ char job_state_reasons[1024];/* Printer state reasons */ static const char * const jattrs[] = /* Job attributes we want */ @@ -373,9 +680,7 @@ monitor_printer( * Open a connection to the printer... */ - http = httpConnect2(monitor->hostname, monitor->port, NULL, AF_UNSPEC, - monitor->encryption, 1, 0, NULL); - httpSetTimeout(http, 30.0, timeout_cb, NULL); + http = httpConnect2(monitor->hostname, monitor->port, NULL, AF_UNSPEC, monitor->encryption, 1, 0, NULL); /* * Loop until the job is canceled, aborted, or completed. @@ -394,7 +699,7 @@ monitor_printer( */ if (httpGetFd(http) < 0) - httpReconnect(http); + httpReconnect2(http, 30000, NULL); if (httpGetFd(http) >= 0) { @@ -457,7 +762,7 @@ monitor_printer( } } - if (monitor.job_state < IPP_JSTATE_CANCELED) + if (monitor->job_state < IPP_JSTATE_CANCELED) { /* * Sleep for 5 seconds... @@ -487,7 +792,7 @@ show_capabilities(ipp_t *response) /* I - Printer attributes */ int i; /* Looping var */ ipp_attribute_t *attr; /* Attribute */ char buffer[1024]; /* Attribute value buffer */ - static const char * const * pattrs[] =/* Attributes we want to show */ + static const char * const pattrs[] = /* Attributes we want to show */ { "copies-default", "copies-supported", @@ -508,7 +813,8 @@ show_capabilities(ipp_t *response) /* I - Printer attributes */ "pwg-raster-document-resolution-supported", "pwg-raster-document-type-supported", "urf-supported" - } + }; + puts("CAPABILITIES:"); for (i = 0; i < (int)(sizeof(pattrs) / sizeof(pattrs[0])); i ++) -- 2.39.5