]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Move test client program to filter directory, finish initial implementation.
authorMichael Sweet <michael.r.sweet@gmail.com>
Tue, 29 Aug 2017 21:27:49 +0000 (17:27 -0400)
committerMichael Sweet <michael.r.sweet@gmail.com>
Tue, 29 Aug 2017 21:27:49 +0000 (17:27 -0400)
cups/Makefile
filter/Makefile
filter/testclient.c [moved from cups/testclient.c with 60% similarity]

index 6a07ba5f78a1f53218e72a1463cc490742cb9844..9a220c85114033c729cf54d568b404370afd343a 100644 (file)
@@ -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)
 #
index fc53f85c6c1517918f2bb024af3958a5639ce06c..02aab14d825759b77c1ae0e6491698303ef19159 100644 (file)
@@ -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
 #
similarity index 60%
rename from cups/testclient.c
rename to filter/testclient.c
index c936d264593cd4d9a7d1bd58411f25cb3ec5a03d..d6ad4249ca17990652aaf045dccd0e01f4b29aa0 100644 (file)
  * Include necessary headers...
  */
 
-#include "cups.h"
-#include "raster.h"
-#include "thread-private.h"
+#include <stdio.h>
 #include <stdlib.h>
+#include <cups/cups.h>
+#include <cups/raster.h>
+#include <cups/string-private.h>
+#include <cups/thread-private.h>
 
 
 /*
@@ -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 ++)