Hello community, here is the log from the commit of package cups-filters for openSUSE:Factory checked in at 2019-04-21 08:59:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cups-filters (Old) and /work/SRC/openSUSE:Factory/.cups-filters.new.5536 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cups-filters" Sun Apr 21 08:59:40 2019 rev:41 rq:695170 version:1.22.5 Changes: -------- --- /work/SRC/openSUSE:Factory/cups-filters/cups-filters.changes 2019-02-28 21:23:55.541922623 +0100 +++ /work/SRC/openSUSE:Factory/.cups-filters.new.5536/cups-filters.changes 2019-04-21 08:59:42.626289582 +0200 @@ -1,0 +2,55 @@ +Mon Apr 8 10:16:15 CEST 2019 - [email protected] + +- Version upgrade to 1.22.5 + * foomatic-rip: Changed Ghostscript call to count pages in a + PDF file to use "runpdfbegin" and not the undocumented + Ghostscript internal "pdfdict", so that it works with + Ghostscript 9.27 and later (Debian bug #926576, + Arch Linux bug #62251, openSUSE boo#1131771, + [email protected] mailing list thread + https://lists.cups.org/pipermail/cups/2019-April/074563.html). +- Version upgrade to 1.22.4 + * cups-browsed: Fix broken trailing space removal on + "NickName" (Pull request #103). + * pdftops: Emit PostScript Level 2 instead of Level 3 for + Brother PostScript printers as at least some of them + report to support level 3 but ontly work with Level 2 + (Ubuntu bug #1306849, comment #42). + * bannertopdf: When multiplying the page for N-up or Duplex + printing one page too much was generated (Issue #102). +- Version upgrade to 1.22.3 + * libcupsfilters: Added error checks for processing GIF, to + avoid crashes or hangs on broken GIF files (Issues #81, #82, + Pull request #100). + * cups-browsed: Added hint to the man page and configuration + file that with "DebugLogging stderr" the logging output goes + to journal or syslog if cups-browsed is running as system + service (Issue #28). +- Version upgrade to 1.22.2 + * cups-browsed: Let distribution of jobs sent to queues with + "implicitclass" backend (usually clusters) be done by a + "job-state" CUPS notification and not by + "printer-state-changed" any more. The "job-state" + notification already contains the job ID. Before we had to + poll the job ID from CUPS via IPP which was sometimes + unreliable (Issue #97). + * imagetopdf, imagetoraster, pdftopdf, libcupsfilters: Added + new page scaling options: "fill" scales the input page + (typically a photo) so that the output page (typically with + different aspect ratio) gets completely filled, aloowing for + some content of the input page getting lost. "crop-to-fit" + allows for easy printing of documents on slightly different + output page sizes (A4 <-> Letter) maintaining the size and + centering and cropping into the destination page. Thanks to + Dheeraj Yadav (dhirajyadav135 at gmail dot com) for the + patch (Pull request #92). + * cups-browsed: Do not do IPP request for printer-is-shared + option for remote cups queues with CUPS 2.2.x and newer + (Pull request #91). + * cups-browsed: Fix crash bug when reading "Cluster" + directive from configuration file (Issue #94). + * driverless: Updated man page as now also Mopria and + Wi-Fi Direct printers are supported. Mentioned also + ippusbxd. + +------------------------------------------------------------------- @@ -94,2 +149,2 @@ - * pdftoraster, pdftoopvp, pdftoijs: Fix build with Poppler >= - 0.70 + * pdftoraster, pdftoopvp, pdftoijs: Fix build with + Poppler >= 0.70 Old: ---- cups-filters-1.22.1.tar.xz New: ---- cups-filters-1.22.5.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cups-filters.spec ++++++ --- /var/tmp/diff_new_pack.221DmT/_old 2019-04-21 08:59:44.186291435 +0200 +++ /var/tmp/diff_new_pack.221DmT/_new 2019-04-21 08:59:44.210291464 +0200 @@ -1,7 +1,7 @@ # # spec file for package cups-filters # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,14 +12,14 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# Please submit bugfixes or comments via http://bugs.opensuse.org/ # Summary: OpenPrinting CUPS filters, backends, and cups-browsed -# See also http://www.linuxfoundation.org/collaborate/workgroups/openprinting/pdf_as_standard_print_job_format License: GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-only AND MIT Group: Hardware/Printing +# See also http://www.linuxfoundation.org/collaborate/workgroups/openprinting/pdf_as_standard_print_job_format Url: http://www.linuxfoundation.org/collaborate/workgroups/openprinting/cups-filters # For a breakdown of the licensing, see COPYING file # GPLv2: filters: commandto*, imagetoraster, pdftops, rasterto*, @@ -37,7 +37,7 @@ # and also run: zypper vcmp 'next version' 'current version' # e.g. zypper vcmp '1.0.49' '1.0.49.20140326' -> 1.0.49 is older than 1.0.49.20140326 # and zypper vcmp '1.0.50' '1.0.49.20140326' -> 1.0.50 is newer than 1.0.49.20140326 -Version: 1.22.1 +Version: 1.22.5 Release: 0 Source0: http://www.openprinting.org/download/cups-filters/cups-filters-%{version}.tar.xz # Upstream fix for https://bugs.linuxfoundation.org/show_bug.cgi?id=1421 ++++++ cups-filters-1.22.1.tar.xz -> cups-filters-1.22.5.tar.xz ++++++ ++++ 2094 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/INSTALL new/cups-filters-1.22.5/INSTALL --- old/cups-filters-1.22.1/INSTALL 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/INSTALL 2019-04-07 17:00:58.000000000 +0200 @@ -1,4 +1,4 @@ -INSTALL - OpenPrinting CUPS Filters v1.22.1 - 2019-02-15 +INSTALL - OpenPrinting CUPS Filters v1.22.5 - 2019-04-07 -------------------------------------------------------- This file describes how to compile and install OpenPrinting CUPS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/NEWS new/cups-filters-1.22.5/NEWS --- old/cups-filters-1.22.1/NEWS 2019-02-15 19:51:23.000000000 +0100 +++ new/cups-filters-1.22.5/NEWS 2019-04-07 17:00:58.000000000 +0200 @@ -1,6 +1,63 @@ -NEWS - OpenPrinting CUPS Filters v1.22.1 - 2019-02-15 +NEWS - OpenPrinting CUPS Filters v1.22.5 - 2019-04-07 ----------------------------------------------------- +CHANGES IN V1.22.5 + + - foomatic-rip: Changed Ghostscript call to count pages in a + PDF file to use "runpdfbegin" and not the undocumented + Ghostscript internal "pdfdict", so that it works with + Ghostscript 9.27 and later (Debian bug #926576, Arch Linux + bug #62251). + +CHANGES IN V1.22.4 + + - cups-browsed: Fix broken trailing space removal on + "NickName" (Pull request #103). + - pdftops: Emit PostScript Level 2 instead of Level 3 for + Brother PostScript printers as at least some of them + report to support level 3 but ontly work with Level 2 + (Ubuntu bug #1306849, comment #42). + - bannertopdf: When multiplying the page for N-up or Duplex + printing one page too much was generated (Issue #102). + +CHANGES IN V1.22.3 + + - libcupsfilters: Added error checks for processing GIF, to + avoid crashes or hangs on broken GIF files (Issues #81, #82, + Pull request #100). + - cups-browsed: Added hint to the man page and configuration + file that with "DebugLogging stderr" the logging output goes + to journal or syslog if cups-browsed is running as system + service (Issue #28). + +CHANGES IN V1.22.2 + + - cups-browsed: Let distribution of jobs sent to queues with + "implicitclass" backend (usually clusters) be done by a + "job-state" CUPS notification and not by + "printer-state-changed" any more. The "job-state" + notification already contains the job ID. Before we had to + poll the job ID from CUPS via IPP which was sometimes + unreliable (Issue #97). + - imagetopdf, imagetoraster, pdftopdf, libcupsfilters: Added + new page scaling options: "fill" scales the input page + (typically a photo) so that the output page (typically with + different aspect ratio) gets completely filled, aloowing for + some content of the input page getting lost. "crop-to-fit" + allows for easy printing of documents on slightly different + output page sizes (A4 <-> Letter) maintaining the size and + centering and cropping into the destination page. Thanks to + Dheeraj Yadav (dhirajyadav135 at gmail dot com) for the + patch (Pull request #92). + - cups-browsed: Do not do IPP request for printer-is-shared + option for remote cups queues with CUPS 2.2.x and newer + (Pull request #91). + - cups-browsed: Fix crash bug when reading "Cluster" + directive from configuration file (Issue #94). + - driverless: Updated man page as now also Mopria and + Wi-Fi Direct printers are supported. Mentioned also + ippusbxd. + CHANGES IN V1.22.1 - braille: Use sort command with LC_ALL=C for reproducibility diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/README new/cups-filters-1.22.5/README --- old/cups-filters-1.22.1/README 2019-02-15 19:51:23.000000000 +0100 +++ new/cups-filters-1.22.5/README 2019-04-07 17:00:58.000000000 +0200 @@ -1,4 +1,4 @@ -README - OpenPrinting CUPS Filters v1.22.1 - 2019-02-15 +README - OpenPrinting CUPS Filters v1.22.5 - 2019-04-07 ------------------------------------------------------- Looking for compile instructions? Read the file "INSTALL.txt" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/configure.ac new/cups-filters-1.22.5/configure.ac --- old/cups-filters-1.22.1/configure.ac 2019-02-15 19:51:23.000000000 +0100 +++ new/cups-filters-1.22.5/configure.ac 2019-04-07 17:00:58.000000000 +0200 @@ -7,7 +7,7 @@ # ==================== m4_define([cups_filters_version_major],[1]) m4_define([cups_filters_version_minor],[22]) -m4_define([cups_filters_version_micro],[1]) +m4_define([cups_filters_version_micro],[5]) m4_define([cups_filters_version],[cups_filters_version_major.cups_filters_version_minor.cups_filters_version_micro]) # ============= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/cupsfilters/image-gif.c new/cups-filters-1.22.5/cupsfilters/image-gif.c --- old/cups-filters-1.22.1/cupsfilters/image-gif.c 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/cupsfilters/image-gif.c 2019-04-07 17:00:58.000000000 +0200 @@ -126,7 +126,13 @@ transparent = buf[3]; } - while (gif_get_block(fp, buf) != 0); + while (gif_get_block(fp, buf) != 0) + { + if(gif_eof) + { + return (-1); + } + } break; case ',' : /* cupsImage data */ @@ -487,8 +493,11 @@ temp += bpp; if (xpos == img->xsize) { - _cupsImagePutRow(img, 0, ypos, img->xsize, pixels); - + int res = _cupsImagePutRow(img, 0, ypos, img->xsize, pixels); + if(res) + { + return (-1); + } xpos = 0; temp = pixels; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/cupsfilters/image.c new/cups-filters-1.22.5/cupsfilters/image.c --- old/cups-filters-1.22.1/cupsfilters/image.c 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/cupsfilters/image.c 2019-04-07 17:00:58.000000000 +0200 @@ -39,7 +39,7 @@ * Local functions... */ -static void flush_tile(cups_image_t *img); +static int flush_tile(cups_image_t *img); static cups_ib_t *get_tile(cups_image_t *img, int x, int y); @@ -614,7 +614,7 @@ * 'flush_tile()' - Flush the least-recently-used tile in the cache. */ -static void +static int flush_tile(cups_image_t *img) /* I - Image */ { int bpp; /* Bytes per pixel */ @@ -622,12 +622,16 @@ bpp = cupsImageGetDepth(img); + if(img==NULL||img->first==NULL||img->first->tile==NULL) + { + return -1; + } tile = img->first->tile; if (!tile->dirty) { tile->ic = NULL; - return; + return 0; } if (img->cachefile < 0) @@ -637,7 +641,7 @@ { tile->ic = NULL; tile->dirty = 0; - return; + return 0; } DEBUG_printf(("Created swap file \"%s\"...\n", img->cachename)); @@ -649,7 +653,7 @@ { tile->ic = NULL; tile->dirty = 0; - return; + return 0; } } else @@ -658,7 +662,7 @@ { tile->ic = NULL; tile->dirty = 0; - return; + return 0; } } @@ -668,6 +672,7 @@ tile->ic = NULL; tile->dirty = 0; + return 0; } @@ -743,7 +748,11 @@ { DEBUG_printf(("Flushing old cache tile (%p)...\n", img->first)); - flush_tile(img); + int res = flush_tile(img); + if(res) + { + return NULL; + } ic = img->first; } @@ -807,3 +816,30 @@ return (ic->pixels + bpp * (y * CUPS_TILE_SIZE + x)); } +/* + * Crop a image. + * (posw,posh): Position of left corner + * (width,height): width and height of required image. + */ +cups_image_t* cupsImageCrop(cups_image_t* img,int posw,int posh,int width,int height) +{ + int image_width = cupsImageGetWidth(img); + cups_image_t* temp=calloc(sizeof(cups_image_t),1); + cups_ib_t *pixels=(cups_ib_t*)malloc(img->xsize*cupsImageGetDepth(img)); + temp->cachefile = -1; + temp->max_ics = CUPS_TILE_MINIMUM; + temp->colorspace=img->colorspace; + temp->xppi = img->xppi; + temp->yppi = img->yppi; + temp->num_ics = 0; + temp->first =temp->last = NULL; + temp->tiles = NULL; + temp->xsize = width; + temp->ysize = height; + for(int i=posh;i<min(cupsImageGetHeight(img),posh+height);i++){ + cupsImageGetRow(img,posw,i,min(width,image_width-posw),pixels); + _cupsImagePutRow(temp,0,i-posh,min(width,image_width-posw),pixels); + } + free(pixels); + return temp; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/cupsfilters/image.h new/cups-filters-1.22.5/cupsfilters/image.h --- old/cups-filters-1.22.1/cupsfilters/image.h 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/cupsfilters/image.h 2019-04-07 17:00:58.000000000 +0200 @@ -112,7 +112,8 @@ cups_ib_t *out, int count) _CUPS_API_1_2; extern void cupsImageWhiteToWhite(const cups_ib_t *in, cups_ib_t *out, int count) _CUPS_API_1_2; - +extern cups_image_t* cupsImageCrop(cups_image_t* img,int posw, + int posh,int width,int height); # ifdef __cplusplus } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/bannertopdf.c new/cups-filters-1.22.5/filter/bannertopdf.c --- old/cups-filters-1.22.1/filter/bannertopdf.c 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/bannertopdf.c 2019-04-07 17:00:58.000000000 +0200 @@ -511,7 +511,7 @@ copies *= 2; if (copies > 1) - pdf_duplicate_page(doc, 1, copies); + pdf_duplicate_page(doc, 1, copies - 1); pdf_write(doc, stdout); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/foomatic-rip/pdf.c new/cups-filters-1.22.5/filter/foomatic-rip/pdf.c --- old/cups-filters-1.22.1/filter/foomatic-rip/pdf.c 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/foomatic-rip/pdf.c 2019-04-07 17:00:58.000000000 +0200 @@ -47,9 +47,8 @@ size_t bytes; snprintf(gscommand, CMDLINE_MAX, "%s -dNODISPLAY -q -c " - "'/pdffile (%s) (r) file def pdfdict begin pdffile pdfopen begin " - "(PageCount: ) print pdfpagecount == flush currentdict pdfclose " - "end end quit'", + "'/pdffile (%s) (r) file runpdfbegin (PageCount: ) print " + "pdfpagecount = quit'", gspath, filename); FILE *pd = popen(gscommand, "r"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/imagetopdf.c new/cups-filters-1.22.5/filter/imagetopdf.c --- old/cups-filters-1.22.1/filter/imagetopdf.c 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/imagetopdf.c 2019-04-07 17:00:58.000000000 +0200 @@ -693,7 +693,8 @@ int deviceReverse = 0; ppd_attr_t *attr; int pl,pr; - + int fillprint = 0; /* print-scaling = fill */ + int cropfit = 0; /* -o crop-to-fit = true */ /* * Make sure status messages are not buffered... */ @@ -810,6 +811,29 @@ } } + /* + * print-scaling = fill functionality. + */ + if((val = cupsGetOption("print-scaling",num_options,options)) !=0) { + if(!strcasecmp(val,"fill")) { + fillprint = 1; + } + } + else if((val = cupsGetOption("fill",num_options,options))!=0) { + if(!strcasecmp(val,"true")||!strcasecmp(val,"yes")) + { + fillprint = 1; + } + } + /* + * crop-to-fit + */ + if((val = cupsGetOption("crop-to-fit",num_options,options))!= NULL){ + if(!strcasecmp(val,"true")||!strcasecmp(val,"yes")) + { + cropfit=1; + } + } if ((val = cupsGetOption("OutputOrder",num_options,options)) != 0) { if (!strcasecmp(val, "Reverse")) { @@ -973,6 +997,111 @@ colorspace = ColorDevice ? CUPS_IMAGE_RGB_CMYK : CUPS_IMAGE_WHITE; img = cupsImageOpen(filename, colorspace, CUPS_IMAGE_WHITE, sat, hue, NULL); + if(fillprint||cropfit) + { + float w = (float)cupsImageGetWidth(img); + float h = (float)cupsImageGetHeight(img); + float pw = PageRight-PageLeft; + float ph = PageTop-PageBottom; + int tempOrientation = Orientation; + char *val; + int flag = 3; + if((val = cupsGetOption("orientation-requested",num_options,options))!=NULL) + { + tempOrientation = atoi(val); + } + else if((val = cupsGetOption("landscape",num_options,options))!=NULL) + { + if(!strcasecmp(val,"true")||!strcasecmp(val,"yes")) + { + tempOrientation = 4; + } + } + if(tempOrientation>0) + { + if(tempOrientation==4||tempOrientation==5) + { + float temp = pw; + pw = ph; + ph = temp; + flag = 4; + } + } + if(tempOrientation==0) + { + int temp1 = pw, + temp2 = ph, + temp3 = pw, + temp4 = ph; + if(temp1>w) temp1 = w; + if(temp2>h) temp2 = h; + if(temp3>h) temp3 = h; + if(temp4>w) temp4 = w; + if(temp1*temp2<temp3*temp4) + { + int temp = pw; + pw = ph; + ph = temp; + flag = 4; + } + } + if(fillprint){ + float final_w,final_h; + if(w*ph/pw <=h){ + final_w =w; + final_h =w*ph/pw; + } + else{ + final_w = h*pw/ph; + final_h = h; + } + float posw=(w-final_w)/2,posh=(h-final_h)/2; + posw = (1+XPosition)*posw; + posh = (1-YPosition)*posh; + cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h); + cupsImageClose(img); + img = img2; + } + else { + float final_w=w,final_h=h; + if(final_w>pw) + { + final_w = pw; + } + if(final_h>ph) + { + final_h = ph; + } + if((fabs(final_w-w)>0.5*w)||(fabs(final_h-h)>0.5*h)) + { + fprintf(stderr,"[DEBUG]: Ignoring crop-to-fit option!\n"); + cropfit=0; + } + else{ + float posw=(w-final_w)/2,posh=(h-final_h)/2; + posw = (1+XPosition)*posw; + posh = (1-YPosition)*posh; + cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h); + cupsImageClose(img); + img = img2; + if(flag==4) + { + PageBottom+=(PageTop-PageBottom-final_w)/2; + PageTop = PageBottom+final_w; + PageLeft +=(PageRight-PageLeft-final_h)/2; + PageRight = PageLeft+final_h; + } + else{ + PageBottom+=(PageTop-PageBottom-final_h)/2; + PageTop = PageBottom+final_h; + PageLeft +=(PageRight-PageLeft-final_w)/2; + PageRight = PageLeft+final_w; + } + if(PageBottom<0) PageBottom = 0; + if(PageLeft<0) PageLeft = 0; + } + } + } #if defined(USE_CONVERT_CMD) && defined(CONVERT_CMD) if (img == NULL) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/imagetoraster.c new/cups-filters-1.22.5/filter/imagetoraster.c --- old/cups-filters-1.22.1/filter/imagetoraster.c 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/imagetoraster.c 2019-04-07 17:00:58.000000000 +0200 @@ -190,8 +190,8 @@ char filename[1024]; /* Name of file to print */ cm_calibration_t cm_calibrate; /* Are we color calibrating the device? */ int cm_disabled; /* Color management disabled? */ - - + int fillprint = 0; /* print-scaling = fill */ + int cropfit = 0; /* -o crop-to-fit */ /* * Make sure status messages are not buffered... */ @@ -240,7 +240,6 @@ perror("ERROR: Unable to create pipes for filters"); return (errno); } - if ((pid = fork()) == 0) { /* @@ -264,7 +263,6 @@ perror("ERROR: Unable to fork filter"); return (errno); } - /* * Update stdout so it points at the new pstoraster... */ @@ -392,6 +390,24 @@ else if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL) zoom = 0.0; + if((val = cupsGetOption("print-scaling",num_options,options)) !=0) { + if(!strcasecmp(val,"fill")) { + fillprint = 1; + } + } + else if((val = cupsGetOption("fill",num_options,options))!=0) { + if(!strcasecmp(val,"true")||!strcasecmp(val,"yes")) + { + fillprint = 1; + } + } + if((val = cupsGetOption("crop-to-fit",num_options,options))!= NULL){ + if(!strcasecmp(val,"true")||!strcasecmp(val,"yes")) + { + cropfit=1; + } + } + if ((val = cupsGetOption("ppi", num_options, options)) != NULL) { if (sscanf(val, "%dx%d", &xppi, &yppi) < 2) @@ -691,7 +707,109 @@ img = cupsImageOpen(filename, primary, secondary, sat, hue, NULL); else img = cupsImageOpen(filename, primary, secondary, sat, hue, lut); - + if(img!=NULL) + { + if(fillprint||cropfit) + { + float w = (float)cupsImageGetWidth(img); + float h = (float)cupsImageGetHeight(img); + float pw = PageRight-PageLeft; + float ph = PageTop-PageBottom; + char *val; + int tempOrientation = Orientation; + int flag =3; + if((val = cupsGetOption("orientation-requested",num_options,options))!=NULL) + { + tempOrientation = atoi(val); + } + else if((val = cupsGetOption("landscape",num_options,options))!=NULL) + { + if(!strcasecmp(val,"true")||!strcasecmp(val,"yes")) + { + tempOrientation = 4; + } + } + if(tempOrientation>0) + { + if(tempOrientation==4||tempOrientation==5) + { + float temp = pw; + pw = ph; + ph = temp; + flag = 4; + } + } + if(tempOrientation==0) + { + if(min(pw,w)*min(ph,h)<min(pw,h)*min(ph,w)) + { + int temp = pw; + pw = ph; + ph = temp; + flag = 4; + } + } + if(fillprint) + { + // Final width and height of cropped image. + float final_w,final_h; + if(w*ph/pw <=h){ + final_w =w; + final_h =w*ph/pw; + } + else{ + final_w = h*pw/ph; + final_h = h; + } + // posw and posh are position of the cropped image along width and height. + float posw=(w-final_w)/2,posh=(h-final_h)/2; + posw = (1+XPosition)*posw; + posh = (1-YPosition)*posh; + cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h); + cupsImageClose(img); + img = img2; + } + else { + float final_w=w,final_h=h; + if(w>pw) + { + final_w = pw; + } + if(h>ph) + { + final_h = ph; + } + if((fabs(final_w-w)>0.5*w)||(fabs(final_h-h)>0.5*h)) + { + fprintf(stderr,"[DEBUG]: Ignoring crop-to-fit option!\n"); + cropfit=0; + } + else{ + float posw=(w-final_w)/2,posh=(h-final_h)/2; + posw = (1+XPosition)*posw; + posh = (1-YPosition)*posh; + cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h); + cupsImageClose(img); + img = img2; + if(flag==4) + { + PageBottom+=(PageTop-PageBottom-final_w)/2; + PageTop = PageBottom+final_w; + PageLeft +=(PageRight-PageLeft-final_h)/2; + PageRight = PageLeft+final_h; + } + else{ + PageBottom+=(PageTop-PageBottom-final_h)/2; + PageTop = PageBottom+final_h; + PageLeft +=(PageRight-PageLeft-final_w)/2; + PageRight = PageLeft+final_w; + } + if(PageBottom<0) PageBottom = 0; + if(PageLeft<0) PageLeft = 0; + } + } + } + } if (argc == 6) unlink(filename); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/pdftopdf/pdftopdf.cc new/cups-filters-1.22.5/filter/pdftopdf/pdftopdf.cc --- old/cups-filters-1.22.1/filter/pdftopdf/pdftopdf.cc 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/pdftopdf/pdftopdf.cc 2019-04-07 17:00:58.000000000 +0200 @@ -326,6 +326,27 @@ // TODO? pstops checks =="true", pdftops !is_false ... pstops says: fitplot only for PS (i.e. not for PDF, cmp. cgpdftopdf) param.fitplot=(val)&&(!is_false(val)); + if((val=cupsGetOption("print-scaling",num_options,options))!=NULL) { + if(!strcasecmp(val,"fill")) { + param.fillprint=true; + } + } + else if((val = cupsGetOption("fill",num_options,options))!=0) { + if(!strcasecmp(val,"true")||!strcasecmp(val,"yes")) + { + param.fillprint = true; + } + } + /* + * crop-to-fit + */ + if((val = cupsGetOption("crop-to-fit",num_options,options))!= NULL){ + if(!strcasecmp(val,"true")||!strcasecmp(val,"yes")) + { + param.cropfit=1; + } + } + if (ppd && (ppd->landscape < 0)) { // direction the printer rotates landscape (90 or -90) param.normal_landscape=ROT_270; } else { @@ -348,6 +369,8 @@ static const Rotation ipp2rot[4]={ROT_0, ROT_90, ROT_270, ROT_180}; param.orientation=ipp2rot[ipprot-3]; } + } else { + param.noOrientation = true; } ppd_size_t *pagesize; @@ -1023,6 +1046,7 @@ param.nup.nupY=2; //param.nup.yalign=TOP; param.border=BorderType::NONE; + //param.fillprint = true; //param.mirror=true; //param.reverse=true; //param.numCopies=3; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/pdftopdf/pdftopdf_processor.cc new/cups-filters-1.22.5/filter/pdftopdf/pdftopdf_processor.cc --- old/cups-filters-1.22.1/filter/pdftopdf/pdftopdf_processor.cc 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/pdftopdf/pdftopdf_processor.cc 2019-04-07 17:00:58.000000000 +0200 @@ -175,6 +175,22 @@ } const int numPages=std::max(shuffle.size(),pages.size()); + if(param.fillprint||param.cropfit){ + fprintf(stderr,"[DEBUG]: Cropping input pdf and Enabling fitplot.\n"); + if(param.noOrientation&&pages.size()) + { + bool land = pages[0]->is_landscape(param.orientation); + if(land) + param.orientation = param.normal_landscape; + } + for(int i=0;i<(int)pages.size();i++) + { + std::shared_ptr<PDFTOPDF_PageHandle> page = pages[i]; + Rotation currRot = page->crop(param.page,param.orientation,param.xpos,param.ypos,!param.cropfit); + } + param.fitplot = 1; + } + std::shared_ptr<PDFTOPDF_PageHandle> curpage; int outputpage=0; int outputno=0; @@ -322,7 +338,20 @@ if (!param.fitplot) { curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale,&rect); } else { - curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale); + if(param.cropfit){ + double xpos2 = (param.page.right-param.page.left-(page->getRect().width))/2; + double ypos2 = (param.page.top-param.page.bottom-(page->getRect().height))/2; + if(param.orientation==ROT_270||param.orientation==ROT_90) + { + xpos2 = (param.page.right-param.page.left-(page->getRect().height))/2; + ypos2 = (param.page.top-param.page.bottom-(page->getRect().width))/2; + curpage->add_subpage(page,ypos2+param.page.bottom,xpos2+param.page.left,1); + }else{ + curpage->add_subpage(page,xpos2+param.page.left,ypos2+param.page.bottom,1); + } + } + else + curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale); } #ifdef DEBUG diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/pdftopdf/pdftopdf_processor.h new/cups-filters-1.22.5/filter/pdftopdf/pdftopdf_processor.h --- old/cups-filters-1.22.1/filter/pdftopdf/pdftopdf_processor.h 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/pdftopdf/pdftopdf_processor.h 2019-04-07 17:00:58.000000000 +0200 @@ -14,6 +14,9 @@ : jobId(0),numCopies(1), user(0),title(0), fitplot(false), + fillprint(false), //print-scaling = fill + cropfit(false), + noOrientation(false), orientation(ROT_0),normal_landscape(ROT_270), paper_is_landscape(false), duplex(false), @@ -38,7 +41,6 @@ deviceCollate(false),setDuplex(false), page_logging(-1) - { page.width=612.0; // letter page.height=792.0; @@ -55,6 +57,9 @@ int jobId, numCopies; const char *user, *title; // will stay around bool fitplot; + bool fillprint; //print-scaling = fill + bool cropfit; // -o crop-to-fit + bool noOrientation; PageRect page; Rotation orientation,normal_landscape; // normal_landscape (i.e. default direction) is e.g. needed for number-up=2 bool paper_is_landscape; @@ -107,6 +112,8 @@ // fscale: inverse_scale (from nup, fitplot) virtual void add_border_rect(const PageRect &rect,BorderType border,float fscale) =0; // TODO?! add standalone crop(...) method (not only for subpages) + virtual Rotation crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos,bool scale) =0; + virtual bool is_landscape(Rotation orientation) =0 ; virtual void add_subpage(const std::shared_ptr<PDFTOPDF_PageHandle> &sub,float xpos,float ypos,float scale,const PageRect *crop=NULL) =0; virtual void mirror() =0; virtual void rotate(Rotation rot) =0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/pdftopdf/qpdf_pdftopdf_processor.cc new/cups-filters-1.22.5/filter/pdftopdf/qpdf_pdftopdf_processor.cc --- old/cups-filters-1.22.1/filter/pdftopdf/qpdf_pdftopdf_processor.cc 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/pdftopdf/qpdf_pdftopdf_processor.cc 2019-04-07 17:00:58.000000000 +0200 @@ -171,6 +171,89 @@ #endif } // }}} +/* + * This crop function is written for print-scaling=fill option. + * Trim Box is used for trimming the page in required size. + * scale tells if we need to scale input file. + */ +Rotation QPDF_PDFTOPDF_PageHandle::crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos,bool scale) +{ + page.assertInitialized(); + if(orientation==ROT_0||orientation==ROT_180) + page.replaceOrRemoveKey("/Rotate",makeRotate(ROT_90)); + else + page.replaceOrRemoveKey("/Rotate",makeRotate(ROT_0)); + + PageRect currpage= getBoxAsRect(getTrimBox(page)); + double width = currpage.right-currpage.left; + double height = currpage.top-currpage.bottom; + double pageWidth = cropRect.right-cropRect.left; + double pageHeight = cropRect.top-cropRect.bottom; + double final_w,final_h; //Width and height of cropped image. + + Rotation pageRot = getRotate(page); + if(pageRot==ROT_0||pageRot==ROT_180) + { + std::swap(pageHeight,pageWidth); + } + if(scale) + { + if(width*pageHeight/pageWidth<=height) + { + final_w = width; + final_h = width*pageHeight/pageWidth; + } + else{ + final_w = height*pageWidth/pageHeight; + final_h = height; + } + } + else{ + final_w = std::min(width,pageWidth); + final_h = std::min(height,pageHeight); + } + fprintf(stderr,"After Cropping: %lf %lf %lf %lf\n",width,height,final_w,final_h); + double posw = (width-final_w)/2, + posh = (height-final_h)/2; + // posw, posh : Position along width and height respectively. + // Calculating required position. + if(xpos==Position::LEFT) + posw =0; + else if(xpos==Position::RIGHT) + posw*=2; + + if(ypos==Position::TOP) + posh*=2; + else if(ypos==Position::BOTTOM) + posh=0; + + // making PageRect for cropping. + currpage.left += posw; + currpage.bottom += posh; + currpage.top =currpage.bottom+final_h; + currpage.right=currpage.left+final_w; + //Cropping. + // TODO: Borders are covered by the image. buffer space? + page.replaceKey("/TrimBox",makeBox(currpage.left,currpage.bottom,currpage.right,currpage.top)); + page.replaceOrRemoveKey("/Rotate",makeRotate(ROT_0)); + return getRotate(page); +} + +bool QPDF_PDFTOPDF_PageHandle::is_landscape(Rotation orientation) +{ + page.assertInitialized(); + if(orientation==ROT_0||orientation==ROT_180) + page.replaceOrRemoveKey("/Rotate",makeRotate(ROT_90)); + else + page.replaceOrRemoveKey("/Rotate",makeRotate(ROT_0)); + + PageRect currpage= getBoxAsRect(getTrimBox(page)); + double width = currpage.right-currpage.left; + double height = currpage.top-currpage.bottom; + if(width>height) + return true; + return false; +} // TODO: better cropping // TODO: test/fix with qsub rotation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/pdftopdf/qpdf_pdftopdf_processor.h new/cups-filters-1.22.5/filter/pdftopdf/qpdf_pdftopdf_processor.h --- old/cups-filters-1.22.1/filter/pdftopdf/qpdf_pdftopdf_processor.h 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/pdftopdf/qpdf_pdftopdf_processor.h 2019-04-07 17:00:58.000000000 +0200 @@ -12,7 +12,8 @@ virtual void mirror(); virtual void rotate(Rotation rot); virtual void add_label(const PageRect &rect, const std::string label); - + virtual Rotation crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos,bool scale); + virtual bool is_landscape(Rotation orientation); void debug(const PageRect &rect,float xpos,float ypos); private: bool isExisting() const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/pdftops.c new/cups-filters-1.22.5/filter/pdftops.c --- old/cups-filters-1.22.1/filter/pdftops.c 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/pdftops.c 2019-04-07 17:00:58.000000000 +0200 @@ -683,9 +683,12 @@ { if (renderer == PDFTOPS) { - /* Do not emit PS Level 3 with Poppler on HP PostScript laser printers - as some do not like it. See https://bugs.launchpad.net/bugs/277404.*/ + /* Do not emit PS Level 3 with Poppler on Brother and HP PostScript + laser printers as some do not like it. + See https://bugs.launchpad.net/bugs/277404 and + https://bugs.launchpad.net/bugs/1306849 comment #42. */ if (!make_model[0] || + !strncasecmp(make_model, "Brother", 7) || ((!strncasecmp(make_model, "HP", 2) || !strncasecmp(make_model, "Hewlett-Packard", 15) || !strncasecmp(make_model, "Hewlett Packard", 15)) && @@ -695,7 +698,16 @@ pdf_argv[pdf_argc++] = (char *)"-level3"; } else if (renderer == GS) - pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3"; + { + /* Do not emit PS Level 3 with Ghostscript on Brother PostScript + laser printers as some do not like it. + See https://bugs.launchpad.net/bugs/1306849 comment #42. */ + if (!make_model[0] || + !strncasecmp(make_model, "Brother", 7)) + pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=2"; + else + pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3"; + } else /* PDFTOCAIRO || ACROREAD */ pdf_argv[pdf_argc++] = (char *)"-level3"; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/filter/urftopdf.cpp new/cups-filters-1.22.5/filter/urftopdf.cpp --- old/cups-filters-1.22.1/filter/urftopdf.cpp 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/filter/urftopdf.cpp 2019-04-07 17:00:58.000000000 +0200 @@ -12,8 +12,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * - * @brief Decode URF to a PDF file - * @file urf_decode.cpp + * @brief Decode URF to a PDF file + * @file urftopdf.cpp * @author Neil 'Superna' Armstrong <[email protected]> (C) 2010 * @author Tobias Hoffmann <[email protected]> (c) 2012 */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/m4/libtool.m4 new/cups-filters-1.22.5/m4/libtool.m4 --- old/cups-filters-1.22.1/m4/libtool.m4 2019-02-15 19:51:30.000000000 +0100 +++ new/cups-filters-1.22.5/m4/libtool.m4 2019-04-07 17:01:06.000000000 +0200 @@ -4063,7 +4063,8 @@ if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -4703,6 +4704,12 @@ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/utils/cups-browsed.c new/cups-filters-1.22.5/utils/cups-browsed.c --- old/cups-filters-1.22.1/utils/cups-browsed.c 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/utils/cups-browsed.c 2019-04-07 17:00:58.000000000 +0200 @@ -451,6 +451,19 @@ #endif /* + * Option 'printer-is-shared' cannot be set on remote CUPS + * queue and requests for setting it ends with error since + * 2.1.1. Define HAVE_CUPS_2_2 to do not send IPP request + * for setting 'printer-is-shared' option on remote CUPS queues + * for newer versions of CUPS. + */ +#if (CUPS_VERSION_MAJOR > 2) || (CUPS_VERSION_MINOR > 1) +#define HAVE_CUPS_2_2 1 +#else +#define HAVE_CUPS_2_2 0 +#endif + +/* * CUPS 1.6 makes various structures private and * introduces these ippGet and ippSet functions * for all of the fields in these structures. @@ -3106,39 +3119,7 @@ gboolean printer_is_accepting_jobs, gpointer user_data) { - int i; char *ptr, buf[2048]; - remote_printer_t *p, *q; - http_t *http = NULL; - ipp_t *request, *response; - ipp_attribute_t *attr; - const char *pname = NULL; - char *remote_cups_queue; - ipp_pstate_t pstate = IPP_PRINTER_IDLE; - int paccept = 0; - int num_jobs, min_jobs = 99999999; - cups_job_t *jobs = NULL; - const char *dest_host = NULL; - int dest_port = 0; - char dest_name[1024]; - int dest_index = 0; - int valid_dest_found = 0; - char uri[HTTP_MAX_URI]; - int job_id = 0; - int num_options; - cups_option_t *options; - static const char *pattrs[] = - { - "printer-name", - "printer-state", - "printer-is-accepting-jobs" - }; - static const char *jattrs[] = - { - "job-id", - "job-state" - }; - http_t *conn = NULL; debug_printf("on_printer_state_changed() in THREAD %ld\n", pthread_self()); @@ -3217,7 +3198,94 @@ strncpy(buf, text, ptr - text); buf[ptr - text] = '\0'; debug_printf("[CUPS Notification] %s not default printer any more.\n", buf); - } else if ((ptr = strstr(text, " state changed to processing")) != NULL) { + } +} + +static void +on_job_state (CupsNotifier *object, + const gchar *text, + const gchar *printer_uri, + const gchar *printer, + guint printer_state, + const gchar *printer_state_reasons, + gboolean printer_is_accepting_jobs, + guint job_id, + guint job_state, + const gchar *job_state_reasons, + const gchar *job_name, + guint job_impressions_completed, + gpointer user_data) +{ + int i; + char buf[2048]; + remote_printer_t *p, *q; + http_t *http = NULL; + ipp_t *request, *response; + ipp_attribute_t *attr; + const char *pname = NULL; + char *remote_cups_queue; + ipp_pstate_t pstate = IPP_PRINTER_IDLE; + int paccept = 0; + int num_jobs, min_jobs = 99999999; + cups_job_t *jobs = NULL; + const char *dest_host = NULL; + int dest_port = 0; + char dest_name[1024]; + int dest_index = 0; + int valid_dest_found = 0; + char uri[HTTP_MAX_URI]; + /*int job_id = 0;*/ + int num_options; + cups_option_t *options; + static const char *pattrs[] = + { + "printer-name", + "printer-state", + "printer-is-accepting-jobs" + }; + http_t *conn = NULL; + + debug_printf("on_job_state() in THREAD %ld\n", pthread_self()); + + debug_printf("[CUPS Notification] Job state changed on printer %s: %s\n", + printer, text); + debug_printf("[CUPS Notification] Printer state reasons: %s\n", + printer_state_reasons); + debug_printf("[CUPS Notification] Job ID: %d\n", + job_id); + debug_printf("[CUPS Notification] Job State: %s\n", + job_state_reasons); + debug_printf("[CUPS Notification] Job is processing: %s\n", + job_state == IPP_JOB_PROCESSING ? "Yes" : "No"); + + if (terminating) { + debug_printf("[CUPS Notification]: Ignoring because cups-browsed is terminating.\n"); + return; + } + + if (autoshutdown && autoshutdown_on == NO_JOBS) { + if (check_jobs() == 0) { + /* If auto shutdown is active for triggering on no jobs being left, we + schedule the shutdown in autoshutdown_timeout seconds */ + if (!autoshutdown_exec_id) { + debug_printf ("No jobs there any more on printers made available by us, shutting down in %d sec...\n", autoshutdown_timeout); + autoshutdown_exec_id = + g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute, + NULL); + } + } else { + /* If auto shutdown is active for triggering on no jobs being left, we + cancel a shutdown in autoshutdown_timeout seconds as there are jobs + again. */ + if (autoshutdown_exec_id) { + debug_printf ("New jobs there on the printers made available by us, killing auto shutdown timer.\n"); + g_source_remove(autoshutdown_exec_id); + autoshutdown_exec_id = 0; + } + } + } + + if (job_id != 0 && job_state == IPP_JOB_PROCESSING) { /* Printer started processing a job, check if it uses the implicitclass backend and if so, we select the remote queue to which to send the job in a way so that we get load balancing between all remote queues @@ -3406,46 +3474,13 @@ if (i == q->last_printer) break; } - /* Find the ID of the current job */ - request = ippNewRequest(IPP_GET_JOBS); - httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, - "localhost", ippPort(), "/printers/%s", printer); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, - "printer-uri", NULL, uri); - ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "requested-attributes", - sizeof(jattrs) / sizeof(jattrs[0]), NULL, jattrs); - job_id = 0; - if ((response = cupsDoRequest(conn, request, "/")) != NULL) { - /* Get the current active job on this queue... */ - ipp_jstate_t jobstate = IPP_JOB_PENDING; - for (attr = ippFirstAttribute(response); attr != NULL; - attr = ippNextAttribute(response)) { - if (!ippGetName(attr)) { - if (jobstate == IPP_JOB_PROCESSING) - break; - else - continue; - } - if (!strcmp(ippGetName(attr), "job-id") && - ippGetValueTag(attr) == IPP_TAG_INTEGER) - job_id = ippGetInteger(attr, 0); - else if (!strcmp(ippGetName(attr), "job-state") && - ippGetValueTag(attr) == IPP_TAG_ENUM) - jobstate = (ipp_jstate_t)ippGetInteger(attr, 0); - } - if (jobstate != IPP_JOB_PROCESSING) - job_id = 0; - ippDelete(response); - } - if (job_id == 0) - debug_printf("ERROR: could not determine ID of curremt job on %s\n", - printer); /* Write the selected destination host into an option of our implicit class queue (cups-browsed-dest-printer="<dest>") so that the implicitclass backend will pick it up */ request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", ippPort(), "/printers/%s", printer); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, @@ -5242,8 +5277,8 @@ memmove(ptr, prefix, strlen(prefix)); ptr = line + strlen(line) - 1; while(isspace(*ptr) && ptr > line) { - ptr --; *ptr = '\0'; + ptr --; } if (*ptr != '"') { if (ptr < line + sizeof(line) - 2) { @@ -5438,7 +5473,15 @@ } cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION); cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER); - ippDelete(cupsDoRequest(http, request, "/admin/")); + /* + * Do IPP request for printer-is-shared option only when we have + * network printer or if we have remote CUPS queue, do IPP request + * only if we have CUPS older than 2.2. + */ + if (p->netprinter != 0 || !HAVE_CUPS_2_2) + ippDelete(cupsDoRequest(http, request, "/admin/")); + else + ippDelete(request); cupsFreeOptions(num_options, options); if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) debug_printf("Unable to modify the printer-is-shared bit (%s)!\n", @@ -7777,7 +7820,7 @@ cups_file_t *fp; int i, linenum = 0; char line[HTTP_MAX_BUFFER]; - char *value = NULL, *ptr, *start = NULL; + char *value = NULL, *ptr, *ptr2, *start; const char *delim = " \t,"; int browse_allow_line_found = 0; int browse_deny_line_found = 0; @@ -8175,6 +8218,7 @@ AutoClustering = 0; } else if (!strcasecmp(line, "Cluster") && value) { ptr = value; + ptr2 = NULL; /* Skip white space */ while (*ptr && isspace(*ptr)) ptr ++; /* Premature line end */ @@ -8193,26 +8237,27 @@ if (strlen(start) <= 0) goto cluster_fail; /* Clean queue name */ - start = remove_bad_chars(start, 0); + ptr2 = remove_bad_chars(start, 0); /* Check whether we have already a cluster with this name */ for (cluster = cupsArrayFirst(clusters); cluster; cluster = cupsArrayNext(clusters)) - if (!strcasecmp(start, cluster->local_queue_name)) { + if (!strcasecmp(ptr2, cluster->local_queue_name)) { debug_printf("Duplicate cluster with queue name \"%s\".\n", - start); + ptr2); cluster = NULL; goto cluster_fail; } /* Create the new cluster definition */ cluster = calloc (1, sizeof (cluster_t)); if (!cluster) goto cluster_fail; - cluster->local_queue_name = start; + cluster->local_queue_name = ptr2; cluster->members = cupsArrayNew(NULL, NULL); + ptr2 = NULL; if (!*ptr) { /* Only local queue name given, so assume this name as the only member name (only remote queues with this name match) */ - cupsArrayAdd(cluster->members, remove_bad_chars(start, 2)); + cupsArrayAdd(cluster->members, remove_bad_chars(ptr2, 2)); } else { /* The rest of the line lists one or more member queue names */ while (*ptr) { @@ -8231,9 +8276,9 @@ } } cupsArrayAdd (clusters, cluster); - if (start != NULL) { - free(start); - start = NULL; + if (ptr2 != NULL) { + free(ptr2); + ptr2 = NULL; } continue; cluster_fail: @@ -8250,9 +8295,9 @@ free(cluster); cluster = NULL; } - if (start != NULL) { - free(start); - start = NULL; + if (ptr2 != NULL) { + free(ptr2); + ptr2 = NULL; } } else if (!strcasecmp(line, "LoadBalancing") && value) { if (!strncasecmp(value, "QueueOnClient", 13)) @@ -8885,6 +8930,8 @@ if (cups_notifier != NULL) { g_signal_connect (cups_notifier, "printer-state-changed", G_CALLBACK (on_printer_state_changed), NULL); + g_signal_connect (cups_notifier, "job-state", + G_CALLBACK (on_job_state), NULL); g_signal_connect (cups_notifier, "printer-deleted", G_CALLBACK (on_printer_deleted), NULL); g_signal_connect (cups_notifier, "printer-modified", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/utils/cups-browsed.conf.5 new/cups-filters-1.22.5/utils/cups-browsed.conf.5 --- old/cups-filters-1.22.1/utils/cups-browsed.conf.5 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/utils/cups-browsed.conf.5 2019-04-07 17:00:58.000000000 +0200 @@ -33,6 +33,11 @@ Into the file /var/log/cups/cups-browsed_log ("file"), to stderr ("stderr"), or not at all ("none"). .PP +Note that if cups-browsed is running as a system service (for example +via systemd) logging to stderr makes the log output going to the +journal or syslog. Only if you run cups-browsed from the command line +(for development or debugging) it will actually appear on stderr. +.PP .nf .fam C DebugLogging file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/utils/cups-browsed.conf.in new/cups-filters-1.22.5/utils/cups-browsed.conf.in --- old/cups-filters-1.22.1/utils/cups-browsed.conf.in 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/utils/cups-browsed.conf.in 2019-04-07 17:00:58.000000000 +0200 @@ -23,6 +23,12 @@ # /var/log/cups/cups-browsed_log ('file'), to stderr ('stderr'), or # not at all ('none')? +# Note that if cups-browsed is running as a system service (for +# example via systemd) logging to stderr makes the log output going to +# the journal or syslog. Only if you run cups-browsed from the command +# line (for development or debugging) it will actually appear on +# stderr. + # DebugLogging file # DebugLogging stderr # DebugLogging file stderr diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/cups-filters-1.22.1/utils/driverless.1 new/cups-filters-1.22.5/utils/driverless.1 --- old/cups-filters-1.22.1/utils/driverless.1 2019-02-15 19:51:24.000000000 +0100 +++ new/cups-filters-1.22.5/utils/driverless.1 2019-04-07 17:00:58.000000000 +0200 @@ -13,13 +13,14 @@ .fi .SH DESCRIPTION \fBdriverless\fP generates PPD files for printers which are designed -for driverless printing (currently IPP Everywhere and AirPrint -printers) by polling capability information from the printers via -IPP. it can be either called for listing suitable printers in the -network and for actually generating the PPD. It can also be called by -CUPS when CUPS is listing available PPDs/drivers or creating print -queues, making the setup of driverless printers with printer setup -tools transparently working. +for driverless IPP printing (currently IPP Everywhere, AirPrint, +Mopria, and Wi-Fi-Direct printers, network printers and also +IPP-over-USB printers with the help of ippusbxd(8)) by polling +capability information from the printers via IPP. it can be either +called for listing suitable printers in the network and for actually +generating the PPD. It can also be called by CUPS when CUPS is listing +available PPDs/drivers or creating print queues, making the setup of +driverless printers with printer setup tools transparently working. .P driverless is placed in /usr/lib/cups/driver/ for listing available driverless-capable printers and generating PPDs for them. It should @@ -58,12 +59,13 @@ .B \fIIPP printer URI\fB Generate the PPD file for the supplied \fIIPP printer URI\fP (suitable URIs are listed when calling driverless without options). -.TP -When called without options, the IPP printer URIs of all available IPP printers will be listed. +.P +When called without options, the IPP printer URIs of all available +driverless-capable IPP printers will be listed. .P .SH SEE ALSO -\fBcups-browsed\fP(8), \fBippfind\fP(1) +\fBcups-browsed\fP(8), \fBippfind\fP(1), \fBippusbxd\fP(8) .PP .SH AUTHOR The authors of \fBdriverless\fP are listed in /usr/share/doc/\fBcups-filters\fP/AUTHORS.
