Hace tiempo que no escribo por aquí. Estoy liado creando un programa para mi empresa (en gambas naturalmente) y además he tenido líos con mi socio hasta que le he comprado su parte y ya soy dueño de mi negocio en su totalidad. Resultado mucho trabajo y nada de pasta hasta que me recupere.
Aprovecho un problema que tengo para saludaros a todos después de este tiempo.
Hace más de un año desarrollé un driver y un filter para una impresora de etiquetas Toshiba TEC B-SV4 con el objeto de utilizarla en mi trabajo con un programa de gestión que estoy desarrollando. Los productos que fabrico los etiqueto con esta impresora.
Si alguien conoce algún foro especializado en CUPS o con alguna sección que lo incluya también puede se una ayuda. Yo los estoy buscando y no he encontrado ninguno de momento.
El driver y su filtro funcionan bien en mi antigua instalación de Debian con los siguientes paquetes instalados
Citar:
Sin embargo en una instalación nueva con los siguientes paquetes no funciona:
Citar:
Ambas instalaciones son Whezzy y el driver lo desarrollé yo mismo. La antigua tiene los paquetes cups no actualizados 1.5.3-2.14 y la nueva los paquetes 1.5.3-5.
¿Alguien sabe si ha cambiado algo que impida funcionar el filtro? ¿Lo he instalado en una máquina amd64 con la misma configuración y da el mismo error?
Me da error cuando intenta utilizar el filtro rastertotec cuyo código escribo a continuación. Este código funciona perfectamente en la instalación previa, cosa que he podido comprobar porque está en otro disco duro viejo que aún mantego.
// Filter code to translate raster format to TCL2 Lite.
// Suitable for Toshiba TEC label printers
//
// Written by Sebastián González López using rastertolabel.c as a guide
//
/* orders to compile and leave the resuls in place
gcc -lm -o rastertotec `cups-config --cflags` rastertotec.c `cups-config --image --libs`
cp ./rastertotec /usr/lib/cups/filter/rastertotec
*/
/* Contents:
*
* Setup() - Prepare the printer for printing.
* StartPage() - Start a page of graphics.
* EndPage() - Finish a page of graphics.
* CancelJob() - Cancel the current job...
* OutputLine() - Output a line of graphics.
* main() - Main entry and processing of driver.
*/
/*
* Include necessary headers...
*/
#include <cups/cups.h>
#include <cups/string.h>
#include <cups/i18n.h>
#include <cups/raster.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <cups/ppd.h>
/*
*This driver filter support TEC B-SV4 printer
*/
#define TEC_TCL2 0x30 /* Toshiba TEC TCL2 Lite based printers*/
/*
* Globals...
*/
unsigned char *Buffer; /* Output buffer */
int ModelNumber, /* cupsModelNumber attribute */
Page, /* Current page */
Canceled; /* Non-zero if job is canceled */
/*
* Prototypes...
*/
void StartPage(ppd_file_t *ppd, cups_page_header2_t *header);
void EndPage(ppd_file_t *ppd, cups_page_header2_t *header);
void CancelJob(int sig);
void OutputLine(ppd_file_t *ppd, cups_page_header2_t *header, int y);
/*
* 'StartPage()' - Start a page of graphics.
*/
void
StartPage(ppd_file_t *ppd, /* I - PPD file */
cups_page_header2_t *header) /* I - Page header */
{
ppd_choice_t *choice; /* Marked choice */
float pitch; //Pitch length of the label or tag
int labelSep; //distance between two labels in mm
/*
* Show page device dictionary...
*/
fprintf(stderr, "DEBUG: StartPage...\n");
fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
header->HWResolution[1]);
fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
header->Margins[1]);
fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
header->PageSize[1]);
fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount);
fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed);
fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep);
if(Page==1) //Setting label size and feed fine adjust before de first page
{
//Getting distance between labels (LabelSaparation + Page height in 0,1mm units
if((choice = ppdFindMarkedChoice(ppd, "LabelSeparation")) != NULL)labelSep=atoi(choice->choice);
else labelSep=4;
pitch=(float)header->PageSize[1]/72.0*254.0+(float)(labelSep)*10;
printf("{D%04d,%04d,%04d|}",(int)pitch,
(int)(header->cupsWidth/0.78), (int)(header->cupsHeight/0.78));
//ajuste de posición -4 mm
printf("{AX;-040,+000,+00|}");
}
//Clearing the printers buffer
printf("{C|}");
/* Start raster image - missing graphic data that will be sent by lines*/
printf("{SG;0000,0000,%04d,%04d,5,",header->cupsWidth,header->cupsHeight);
/* Graphic data will be written by the OutputLine function
and the end of the graphic command will come with EndPage function*/
/*
* Allocate memory for a line of graphics...
*/
Buffer = malloc(header->cupsBytesPerLine);
}
/****************************************************************
* 'EndPage()' - Finish a page of graphics.
********************************************************************/
void
EndPage(ppd_file_t *ppd, /* I - PPD file */
cups_page_header2_t *header) /* I - Page header */
{
ppd_choice_t *choice; /* Marked choice */
// option values
int CutInterval=0;
int SensorType=2;
char PrintMode='C';
int PrintSpeed=5;
int Transfer=2;
//end graphic command
printf("|}");
//Getting options
if((choice = ppdFindMarkedChoice(ppd, "CutInterval"))!=NULL)
CutInterval=atoi(choice->choice);
if((choice = ppdFindMarkedChoice(ppd, "TypeOfSensor"))!=NULL)
{
if(!strcmp(choice->choice,"Continuous")) SensorType=0;
else if(!strcmp(choice->choice,"ReflectiveSensor")) SensorType=1;
else if(!strcmp(choice->choice,"TransmisiveSensor")) SensorType=2;
}
if((choice = ppdFindMarkedChoice(ppd, "PrintMode"))!=NULL)
{
if(!strcmp(choice->choice,"BatchMode")) PrintMode='C';
else if(!strcmp(choice->choice,"StripMode")) PrintMode='D';
}
if((choice = ppdFindMarkedChoice(ppd, "PrintRate"))!=NULL)
PrintSpeed=atoi(choice->choice);
if((choice = ppdFindMarkedChoice(ppd, "MediaType"))!=NULL)
{
if(!strcmp(choice->choice,"Thermal")) Transfer=2;
else if(!strcmp(choice->choice,"Direct")) Transfer=0;
}
//print a barcode
printf("{XB00;0100,0600,5,3,07,0,0200,1=843510760725|}");
//print the label
printf("{XS;I,0001,%03d%d%c%d%d01|}",CutInterval,SensorType,PrintMode,PrintSpeed,Transfer);//putchar(0);
fflush(stdout);
/*
* Free memory...
*/
free(Buffer);
}
/********************************************************
* 'CancelJob()' - Cancel the current job...
**************************************************************/
void
CancelJob(int sig) /* I - Signal */
{
/*
* Tell the main loop to stop...
*/
(void)sig;
Canceled = 1;
}
/********************************************************************
* 'OutputLine()' - Output a line of graphics...
************************************************************/
void
OutputLine(ppd_file_t *ppd, /* I - PPD file */
cups_page_header2_t *header, /* I - Page header */
int y) /* I - Line number */
{
//sent a line to printer
fwrite(Buffer, header->cupsBytesPerLine, 1, stdout);
fflush(stdout);
}
/************************************************************************************************
* 'main()' - Main entry and processing of driver.
*********************************************************************************************** */
int /* O - Exit status */
main(int argc, /* I - Number of command-line arguments */
char *argv[]) /* I - Command-line arguments */
{
int fd; /* File descriptor */
cups_raster_t *ras; /* Raster stream for printing */
cups_page_header2_t header; /* Page header from file */
int y; /* Current line */
ppd_file_t *ppd; /* PPD file */
int num_options; /* Number of options */
cups_option_t *options; /* Options */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
* Make sure status messages are not buffered...
*/
setbuf(stderr, NULL);
/*
* Check command-line...
*/
if (argc < 6 || argc > 7)
{
/*
* We don't have the correct number of arguments; write an error message
* and return.
*/
_cupsLangPrintf(stderr,
_("Usage: %s job-id user title copies options [file]\n"),
"rastertotec");
return (1);
}
/*
* Open the page stream...
*/
if (argc == 7)
{
if ((fd = open(argv[6], O_RDONLY)) == -1)
{
_cupsLangPrintf(stderr, _("ERROR: Unable to open raster file - %s\n"),
strerror(errno));
sleep(1);
return (1);
}
}
else
fd = 0;
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
/*
* Register a signal handler to eject the current page if the
* job is cancelled.
*/
Canceled = 0;
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
sigset(SIGTERM, CancelJob);
#elif defined(HAVE_SIGACTION)
memset(&action, 0, sizeof(action));
sigemptyset(&action.sa_mask);
action.sa_handler = CancelJob;
sigaction(SIGTERM, &action, NULL);
#else
signal(SIGTERM, CancelJob);
#endif /* HAVE_SIGSET */
/*
* Open the PPD file and apply options...
*/
num_options = cupsParseOptions(argv[5], 0, &options);
if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL)
{
ppdMarkDefaults(ppd);
cupsMarkOptions(ppd, num_options, options);
}
/*
* Initialize the print device...
*/
//Setup(ppd); No setup required
/*
* Process pages as needed...
*/
Page = 0;
while (cupsRasterReadHeader2(ras, &header))
{
/*
* Write a status message with the page number and number of copies.
*/
if (Canceled)
break;
Page ++;
fprintf(stderr, "PAGE: %d 1\n", Page);
/*
* Start the page...
*/
StartPage(ppd, &header);
/*
* Loop for each line on the page...
*/
for (y = 0; y < header.cupsHeight && !Canceled; y ++)
{
/*
* Let the user know how far we have progressed...
*/
if (Canceled)
break;
if ((y & 15) == 0)
_cupsLangPrintf(stderr, _("INFO: Printing page %d, %d%% complete...\n"),
Page, 100 * y / header.cupsHeight);
/*
* Read a line of graphics...
*/
if (cupsRasterReadPixels(ras, Buffer, header.cupsBytesPerLine) < 1)
break;
/*
* Write it to the printer...
*/
OutputLine(ppd, &header, y);
}
/*
* Eject the page...
*/
EndPage(ppd, &header);
if (Canceled)
break;
}
/*
* Close the raster stream...
*/
cupsRasterClose(ras);
if (fd != 0)
close(fd);
/*
* Close the PPD file and free the options...
*/
ppdClose(ppd);
cupsFreeOptions(num_options, options);
/*
* If no pages were printed, send an error message...
*/
if (Page == 0)
{
_cupsLangPuts(stderr, _("ERROR: No pages found!\n"));
return (1);
}
else
{
_cupsLangPuts(stderr, _("INFO: Ready to print.\n"));
return (0);
}
return (Page == 0);
}
// Suitable for Toshiba TEC label printers
//
// Written by Sebastián González López using rastertolabel.c as a guide
//
/* orders to compile and leave the resuls in place
gcc -lm -o rastertotec `cups-config --cflags` rastertotec.c `cups-config --image --libs`
cp ./rastertotec /usr/lib/cups/filter/rastertotec
*/
/* Contents:
*
* Setup() - Prepare the printer for printing.
* StartPage() - Start a page of graphics.
* EndPage() - Finish a page of graphics.
* CancelJob() - Cancel the current job...
* OutputLine() - Output a line of graphics.
* main() - Main entry and processing of driver.
*/
/*
* Include necessary headers...
*/
#include <cups/cups.h>
#include <cups/string.h>
#include <cups/i18n.h>
#include <cups/raster.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <cups/ppd.h>
/*
*This driver filter support TEC B-SV4 printer
*/
#define TEC_TCL2 0x30 /* Toshiba TEC TCL2 Lite based printers*/
/*
* Globals...
*/
unsigned char *Buffer; /* Output buffer */
int ModelNumber, /* cupsModelNumber attribute */
Page, /* Current page */
Canceled; /* Non-zero if job is canceled */
/*
* Prototypes...
*/
void StartPage(ppd_file_t *ppd, cups_page_header2_t *header);
void EndPage(ppd_file_t *ppd, cups_page_header2_t *header);
void CancelJob(int sig);
void OutputLine(ppd_file_t *ppd, cups_page_header2_t *header, int y);
/*
* 'StartPage()' - Start a page of graphics.
*/
void
StartPage(ppd_file_t *ppd, /* I - PPD file */
cups_page_header2_t *header) /* I - Page header */
{
ppd_choice_t *choice; /* Marked choice */
float pitch; //Pitch length of the label or tag
int labelSep; //distance between two labels in mm
/*
* Show page device dictionary...
*/
fprintf(stderr, "DEBUG: StartPage...\n");
fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
header->HWResolution[1]);
fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
header->Margins[1]);
fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
header->PageSize[1]);
fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount);
fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed);
fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep);
if(Page==1) //Setting label size and feed fine adjust before de first page
{
//Getting distance between labels (LabelSaparation + Page height in 0,1mm units
if((choice = ppdFindMarkedChoice(ppd, "LabelSeparation")) != NULL)labelSep=atoi(choice->choice);
else labelSep=4;
pitch=(float)header->PageSize[1]/72.0*254.0+(float)(labelSep)*10;
printf("{D%04d,%04d,%04d|}",(int)pitch,
(int)(header->cupsWidth/0.78), (int)(header->cupsHeight/0.78));
//ajuste de posición -4 mm
printf("{AX;-040,+000,+00|}");
}
//Clearing the printers buffer
printf("{C|}");
/* Start raster image - missing graphic data that will be sent by lines*/
printf("{SG;0000,0000,%04d,%04d,5,",header->cupsWidth,header->cupsHeight);
/* Graphic data will be written by the OutputLine function
and the end of the graphic command will come with EndPage function*/
/*
* Allocate memory for a line of graphics...
*/
Buffer = malloc(header->cupsBytesPerLine);
}
/****************************************************************
* 'EndPage()' - Finish a page of graphics.
********************************************************************/
void
EndPage(ppd_file_t *ppd, /* I - PPD file */
cups_page_header2_t *header) /* I - Page header */
{
ppd_choice_t *choice; /* Marked choice */
// option values
int CutInterval=0;
int SensorType=2;
char PrintMode='C';
int PrintSpeed=5;
int Transfer=2;
//end graphic command
printf("|}");
//Getting options
if((choice = ppdFindMarkedChoice(ppd, "CutInterval"))!=NULL)
CutInterval=atoi(choice->choice);
if((choice = ppdFindMarkedChoice(ppd, "TypeOfSensor"))!=NULL)
{
if(!strcmp(choice->choice,"Continuous")) SensorType=0;
else if(!strcmp(choice->choice,"ReflectiveSensor")) SensorType=1;
else if(!strcmp(choice->choice,"TransmisiveSensor")) SensorType=2;
}
if((choice = ppdFindMarkedChoice(ppd, "PrintMode"))!=NULL)
{
if(!strcmp(choice->choice,"BatchMode")) PrintMode='C';
else if(!strcmp(choice->choice,"StripMode")) PrintMode='D';
}
if((choice = ppdFindMarkedChoice(ppd, "PrintRate"))!=NULL)
PrintSpeed=atoi(choice->choice);
if((choice = ppdFindMarkedChoice(ppd, "MediaType"))!=NULL)
{
if(!strcmp(choice->choice,"Thermal")) Transfer=2;
else if(!strcmp(choice->choice,"Direct")) Transfer=0;
}
//print a barcode
printf("{XB00;0100,0600,5,3,07,0,0200,1=843510760725|}");
//print the label
printf("{XS;I,0001,%03d%d%c%d%d01|}",CutInterval,SensorType,PrintMode,PrintSpeed,Transfer);//putchar(0);
fflush(stdout);
/*
* Free memory...
*/
free(Buffer);
}
/********************************************************
* 'CancelJob()' - Cancel the current job...
**************************************************************/
void
CancelJob(int sig) /* I - Signal */
{
/*
* Tell the main loop to stop...
*/
(void)sig;
Canceled = 1;
}
/********************************************************************
* 'OutputLine()' - Output a line of graphics...
************************************************************/
void
OutputLine(ppd_file_t *ppd, /* I - PPD file */
cups_page_header2_t *header, /* I - Page header */
int y) /* I - Line number */
{
//sent a line to printer
fwrite(Buffer, header->cupsBytesPerLine, 1, stdout);
fflush(stdout);
}
/************************************************************************************************
* 'main()' - Main entry and processing of driver.
*********************************************************************************************** */
int /* O - Exit status */
main(int argc, /* I - Number of command-line arguments */
char *argv[]) /* I - Command-line arguments */
{
int fd; /* File descriptor */
cups_raster_t *ras; /* Raster stream for printing */
cups_page_header2_t header; /* Page header from file */
int y; /* Current line */
ppd_file_t *ppd; /* PPD file */
int num_options; /* Number of options */
cups_option_t *options; /* Options */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
* Make sure status messages are not buffered...
*/
setbuf(stderr, NULL);
/*
* Check command-line...
*/
if (argc < 6 || argc > 7)
{
/*
* We don't have the correct number of arguments; write an error message
* and return.
*/
_cupsLangPrintf(stderr,
_("Usage: %s job-id user title copies options [file]\n"),
"rastertotec");
return (1);
}
/*
* Open the page stream...
*/
if (argc == 7)
{
if ((fd = open(argv[6], O_RDONLY)) == -1)
{
_cupsLangPrintf(stderr, _("ERROR: Unable to open raster file - %s\n"),
strerror(errno));
sleep(1);
return (1);
}
}
else
fd = 0;
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
/*
* Register a signal handler to eject the current page if the
* job is cancelled.
*/
Canceled = 0;
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
sigset(SIGTERM, CancelJob);
#elif defined(HAVE_SIGACTION)
memset(&action, 0, sizeof(action));
sigemptyset(&action.sa_mask);
action.sa_handler = CancelJob;
sigaction(SIGTERM, &action, NULL);
#else
signal(SIGTERM, CancelJob);
#endif /* HAVE_SIGSET */
/*
* Open the PPD file and apply options...
*/
num_options = cupsParseOptions(argv[5], 0, &options);
if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL)
{
ppdMarkDefaults(ppd);
cupsMarkOptions(ppd, num_options, options);
}
/*
* Initialize the print device...
*/
//Setup(ppd); No setup required
/*
* Process pages as needed...
*/
Page = 0;
while (cupsRasterReadHeader2(ras, &header))
{
/*
* Write a status message with the page number and number of copies.
*/
if (Canceled)
break;
Page ++;
fprintf(stderr, "PAGE: %d 1\n", Page);
/*
* Start the page...
*/
StartPage(ppd, &header);
/*
* Loop for each line on the page...
*/
for (y = 0; y < header.cupsHeight && !Canceled; y ++)
{
/*
* Let the user know how far we have progressed...
*/
if (Canceled)
break;
if ((y & 15) == 0)
_cupsLangPrintf(stderr, _("INFO: Printing page %d, %d%% complete...\n"),
Page, 100 * y / header.cupsHeight);
/*
* Read a line of graphics...
*/
if (cupsRasterReadPixels(ras, Buffer, header.cupsBytesPerLine) < 1)
break;
/*
* Write it to the printer...
*/
OutputLine(ppd, &header, y);
}
/*
* Eject the page...
*/
EndPage(ppd, &header);
if (Canceled)
break;
}
/*
* Close the raster stream...
*/
cupsRasterClose(ras);
if (fd != 0)
close(fd);
/*
* Close the PPD file and free the options...
*/
ppdClose(ppd);
cupsFreeOptions(num_options, options);
/*
* If no pages were printed, send an error message...
*/
if (Page == 0)
{
_cupsLangPuts(stderr, _("ERROR: No pages found!\n"));
return (1);
}
else
{
_cupsLangPuts(stderr, _("INFO: Ready to print.\n"));
return (0);
}
return (Page == 0);
}