예제 #1
0
파일: lpoptions.c 프로젝트: ezeep/cups
static void
list_options(cups_dest_t *dest)		/* I - Destination to list */
{
  int		i;			/* Looping var */
  const char	*filename;		/* PPD filename */
  ppd_file_t	*ppd;			/* PPD data */
  ppd_group_t	*group;			/* Current group */


  if ((filename = cupsGetPPD(dest->name)) == NULL)
  {
    _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"),
		    dest->name, cupsLastErrorString());
    return;
  }

  if ((ppd = ppdOpenFile(filename)) == NULL)
  {
    unlink(filename);
    _cupsLangPrintf(stderr, _("lpoptions: Unable to open PPD file for %s."),
		    dest->name);
    return;
  }

  ppdMarkDefaults(ppd);
  cupsMarkOptions(ppd, dest->num_options, dest->options);

  for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
    list_group(ppd, group);

  ppdClose(ppd);
  unlink(filename);
}
예제 #2
0
static
void mark_ps_param_options(ppd_file_t *p_ppd, ParamList *p_param)
{
	int num = param_list_num(p_param);

	if( num > 0 )
	{
		cups_option_t *options
			= (cups_option_t*)malloc(num * sizeof(cups_option_t));
		if( options )
		{
			int i;
			for( i = 0 ; i < num ; i++ )
			{
				options[i].name = p_param->key;
				options[i].value = p_param->value;
				p_param = p_param->next;
			}
			for( i = num - 1 ; i >= 0 ; i-- )
			{
				cupsMarkOptions(p_ppd, 1, &options[i]);
			}

			free(options);
		}
	}
}
예제 #3
0
int GetPrinterSettings( cups_option_t *p_cups_opt, int num_opt, ParamList **p_list, int *listNum )
{
	char *p_ppd_name = getenv("PPD");
	ppd_file_t *p_ppd;
	ppd_choice_t *p_choice;
	int result = -1;
	PpdToOptKey *p_opt_key_table = alloc_opt_key_table(p_ppd_name);
	PpdToOptKey *p_table = p_opt_key_table;
	int numCnt = 0;
	char choice[BUF_SIZE];
	ParamList *local_p_list = NULL;
	static const char *libpath;

	if ( (p_cups_opt == NULL) || (listNum == NULL) ) goto onErr;
	*listNum = 0;
	

	DEBUG_PRINT2( "DEBUG:[rastertocanonij] PPD Path(%s)\n", p_ppd_name );
	if ( (p_ppd = ppdOpenFile( p_ppd_name )) == NULL ) goto onErr;

	ppdMarkDefaults(p_ppd);
	cupsMarkOptions(p_ppd, num_opt, p_cups_opt);

	/* add libpath */
	libpath = GetExecProgPath();
	if ( libpath != NULL ){
		param_list_add( &local_p_list, "--filterpath", libpath, strlen(libpath) + 1 );
	}

	while( p_table->ppd_key != NULL ){
		p_choice = ppdFindMarkedChoice( p_ppd, p_table->ppd_key );
		if ( p_choice ) {
			DEBUG_PRINT3( "DEBUG:[rastertocanonij] OPTION(%s) / VALUE(%s)\n", p_table->ppd_key, p_choice->choice );
		}
		else {
			DEBUG_PRINT2( "DEBUG:[rastertocanonij] OPTION(%s) / VALUE(novalue)\n", p_table->ppd_key );
		}

		if ( p_choice != NULL ){
			strcpy( choice, p_choice->choice );
			//to_lower_except_size_X(choice);
			param_list_add( &local_p_list, p_table->opt_key, choice, strlen(choice) + 1 );
			numCnt++;
		}
		p_table++;
	}

	*listNum = numCnt;
	*p_list = local_p_list;
	result = 0;
onErr:
	return result;
}
예제 #4
0
파일: lpoptions.c 프로젝트: zdohnal/cups
static void
list_options(cups_dest_t *dest)		/* I - Destination to list */
{
  http_t	*http;			/* Connection to destination */
  char		resource[1024];		/* Resource path */
  int		i;			/* Looping var */
  const char	*filename;		/* PPD filename */
  ppd_file_t	*ppd;			/* PPD data */
  ppd_group_t	*group;			/* Current group */


  if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, resource, sizeof(resource), NULL, NULL)) == NULL)
  {
    _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"),
		    dest->name, cupsLastErrorString());
    return;
  }

  if ((filename = cupsGetPPD2(http, dest->name)) == NULL)
  {
    httpClose(http);

    _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"),
		    dest->name, cupsLastErrorString());
    return;
  }

  httpClose(http);

  if ((ppd = ppdOpenFile(filename)) == NULL)
  {
    unlink(filename);
    _cupsLangPrintf(stderr, _("lpoptions: Unable to open PPD file for %s."),
		    dest->name);
    return;
  }

  ppdMarkDefaults(ppd);
  cupsMarkOptions(ppd, dest->num_options, dest->options);

  for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
    list_group(ppd, group);

  ppdClose(ppd);
  unlink(filename);
}
예제 #5
0
/*
 * Ouverture et fermeture du fichier PPD
 * Opening or closing PPD file
 */
bool PPDFile::open(const char *file, const char *version, const char *useropts)
{
    const char *fileVersion;
    cups_option_t *options;
    int nr;

    // Check if a PPD file was previously opened
    if (_ppd) {
        ERRORMSG(_("Internal warning: a PPD file was previously opened. Please "
            "close it before opening a new one."));
        close();
    }

    // Open the PPD file
    _ppd = ppdOpenFile(file);
    if (!_ppd) {
        ERRORMSG(_("Cannot open PPD file %s"), file);
        return false;
    }

    // Mark the default values and the user options
    ppdMarkDefaults(_ppd);
    nr = cupsParseOptions(useropts, 0, &options);
    cupsMarkOptions(_ppd, nr, options);
    cupsFreeOptions(nr, options);

    // Check if the PPD version is compatible with this filter
    fileVersion = get("FileVersion");
    if (!fileVersion) { 
        ERRORMSG(_("No FileVersion found in the PPD file: invalid "
            "PPD file"));
        ppdClose(_ppd);
        _ppd = NULL;
        return false;
    }
    if (strcmp(fileVersion, version)) {
        ERRORMSG(_("Invalid PPD file version: %s but the PPD file "
            "is designed for SpliX V. %s"), version, fileVersion);
        ppdClose(_ppd);
        _ppd = NULL;
        return false;
    }

    return true;
}
예제 #6
0
int initializeCupsOptions(job_data_t *job, ppd_file_t **ppd, const char *argv[]) {
  char ls[64];
  
  job->job_id = atoi(argv[1]);
  job->user = argv[2];
  job->title = argv[3];
  job->num_options = cupsParseOptions(argv[5], 0, &(job->options));
  
  if ((*ppd = ppdOpenFile(getenv("PPD"))) != NULL) {
    ppdMarkDefaults(*ppd);
    cupsMarkOptions(*ppd, job->num_options, job->options);
  } else {
    l10nGetString("Unable to open PPD file", ls, sizeof(ls));
    fprintf(stderr, "ERROR: %s: %s\n", ls, strerror(errno));
    return 1;
  }
  return 0;
}
예제 #7
0
static int				/* O - Number of errors */
do_ppd_tests(const char    *filename,	/* I - PPD file */
             int           num_options,	/* I - Number of options */
             cups_option_t *options)	/* I - Options */
{
  ppd_file_t		*ppd;		/* PPD file data */
  cups_page_header2_t	header;		/* Page header */


  printf("\"%s\": ", filename);
  fflush(stdout);

  if ((ppd = ppdOpenFile(filename)) == NULL)
  {
    ppd_status_t	status;		/* Status from PPD loader */
    int			line;		/* Line number containing error */


    status = ppdLastError(&line);

    puts("FAIL (bad PPD file)");
    printf("    %s on line %d\n", ppdErrorString(status), line);

    return (1);
  }

  ppdMarkDefaults(ppd);
  cupsMarkOptions(ppd, num_options, options);

  if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, NULL))
  {
    puts("FAIL (error from function)");
    puts(cupsRasterErrorString());

    return (1);
  }
  else
  {
    puts("PASS");

    return (0);
  }
}
예제 #8
0
dt_printer_info_t *dt_get_printer_info(const char *printer_name)
{
  cups_dest_t *dests;
  int num_dests = cupsGetDests(&dests);
  cups_dest_t *dest = cupsGetDest(printer_name, NULL, num_dests, dests);
  dt_printer_info_t *result = NULL;

  if (dest)
  {
    const char *PPDFile = cupsGetPPD (printer_name);
    result = (dt_printer_info_t *)malloc(sizeof(dt_printer_info_t));
    g_strlcpy(result->name, dest->name, MAX_NAME);
    ppd_file_t *ppd = ppdOpenFile(PPDFile);

    if (ppd)
    {
      ppdMarkDefaults(ppd);
      cupsMarkOptions(ppd, dest->num_options, dest->options);

      // hardware margins

      ppd_attr_t *attr = ppdFindAttr(ppd, "HWMargins", NULL);

      if (attr)
      {
        sscanf(attr->value, "%lf %lf %lf %lf",
               &result->hw_margin_left, &result->hw_margin_bottom,
               &result->hw_margin_right, &result->hw_margin_top);

        result->hw_margin_left   = dt_pdf_point_to_mm (result->hw_margin_left);
        result->hw_margin_bottom = dt_pdf_point_to_mm (result->hw_margin_bottom);
        result->hw_margin_right  = dt_pdf_point_to_mm (result->hw_margin_right);
        result->hw_margin_top    = dt_pdf_point_to_mm (result->hw_margin_top);
      }

      // default resolution

      attr = ppdFindAttr(ppd, "DefaultResolution", NULL);

      if (attr)
      {
        char *x = strstr(attr->value, "x");

        if (x)
          sscanf (x+1, "%ddpi", &result->resolution);
        else
          sscanf (attr->value, "%ddpi", &result->resolution);
      }
      else
        result->resolution = 300;

      while(result->resolution>360)
        result->resolution /= 2.0;

      ppdClose(ppd);
      unlink(PPDFile);
    }
  }

  cupsFreeDests(num_dests, dests);
  return result;
}
예제 #9
0
ppd_file_t *				/* O - PPD file */
SetCommonOptions(
    int           num_options,		/* I - Number of options */
    cups_option_t *options,		/* I - Options */
    int           change_size)		/* I - Change page size? */
{
  ppd_file_t	*ppd;			/* PPD file */
  ppd_size_t	*pagesize;		/* Current page size */
  const char	*val;			/* Option value */


#ifdef LC_TIME
  setlocale(LC_TIME, "");
#endif /* LC_TIME */

  ppd = ppdOpenFile(getenv("PPD"));

  ppdMarkDefaults(ppd);
  cupsMarkOptions(ppd, num_options, options);

  if ((pagesize = ppdPageSize(ppd, NULL)) != NULL)
  {
    PageWidth  = pagesize->width;
    PageLength = pagesize->length;
    PageTop    = pagesize->top;
    PageBottom = pagesize->bottom;
    PageLeft   = pagesize->left;
    PageRight  = pagesize->right;

    fprintf(stderr, "DEBUG: Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
            PageWidth, PageLength, PageLeft, PageBottom, PageRight, PageTop);
  }

  if (ppd != NULL)
  {
    ColorDevice   = ppd->color_device;
    LanguageLevel = ppd->language_level;
  }

  if ((val = cupsGetOption("landscape", num_options, options)) != NULL)
  {
    if (_cups_strcasecmp(val, "no") != 0 && _cups_strcasecmp(val, "off") != 0 &&
        _cups_strcasecmp(val, "false") != 0)
    {
      if (ppd && ppd->landscape > 0)
        Orientation = 1;
      else
        Orientation = 3;
    }
  }
  else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
  {
   /*
    * Map IPP orientation values to 0 to 3:
    *
    *   3 = 0 degrees   = 0
    *   4 = 90 degrees  = 1
    *   5 = -90 degrees = 3
    *   6 = 180 degrees = 2
    */

    Orientation = atoi(val) - 3;
    if (Orientation >= 2)
      Orientation ^= 1;
  }

  if ((val = cupsGetOption("page-left", num_options, options)) != NULL)
  {
    switch (Orientation & 3)
    {
      case 0 :
          PageLeft = (float)atof(val);
	  break;
      case 1 :
          PageBottom = (float)atof(val);
	  break;
      case 2 :
          PageRight = PageWidth - (float)atof(val);
	  break;
      case 3 :
          PageTop = PageLength - (float)atof(val);
	  break;
    }
  }

  if ((val = cupsGetOption("page-right", num_options, options)) != NULL)
  {
    switch (Orientation & 3)
    {
      case 0 :
          PageRight = PageWidth - (float)atof(val);
	  break;
      case 1 :
          PageTop = PageLength - (float)atof(val);
	  break;
      case 2 :
          PageLeft = (float)atof(val);
	  break;
      case 3 :
          PageBottom = (float)atof(val);
	  break;
    }
  }

  if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL)
  {
    switch (Orientation & 3)
    {
      case 0 :
          PageBottom = (float)atof(val);
	  break;
      case 1 :
          PageLeft = (float)atof(val);
	  break;
      case 2 :
          PageTop = PageLength - (float)atof(val);
	  break;
      case 3 :
          PageRight = PageWidth - (float)atof(val);
	  break;
    }
  }

  if ((val = cupsGetOption("page-top", num_options, options)) != NULL)
  {
    switch (Orientation & 3)
    {
      case 0 :
          PageTop = PageLength - (float)atof(val);
	  break;
      case 1 :
          PageRight = PageWidth - (float)atof(val);
	  break;
      case 2 :
          PageBottom = (float)atof(val);
	  break;
      case 3 :
          PageLeft = (float)atof(val);
	  break;
    }
  }

  if (change_size)
    UpdatePageVars();

  if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
      ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
      ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
      ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
      ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
      ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
      ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
      ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))
    Duplex = 1;

  return (ppd);
}
예제 #10
0
CupsOptions::CupsOptions(QWidget* parent, QString Geraet) : QDialog( parent )
{
	FlagsOpt.clear();
	setModal(true);
	setWindowTitle( tr( "Printer Options" ) );
	setWindowIcon(QIcon(loadIcon ( "AppIcon.png" )));
	prefs = PrefsManager::instance()->prefsFile->getContext("cups_options");
	setSizeGripEnabled(true);
	CupsOptionsLayout = new QVBoxLayout( this );
	CupsOptionsLayout->setSpacing( 5 );
	CupsOptionsLayout->setMargin( 10 );
	Table = new QTableWidget(0, 2, this);
	Table->setSortingEnabled(false);
	Table->setSelectionMode(QAbstractItemView::NoSelection);
	Table->verticalHeader()->hide();
	Table->setHorizontalHeaderItem(0, new QTableWidgetItem( tr("Option")));
	Table->setHorizontalHeaderItem(1, new QTableWidgetItem( tr("Value")));
	QHeaderView* headerH = Table->horizontalHeader();
	headerH->setStretchLastSection(true);
	headerH->setMovable(false);
	headerH->setClickable(false);
	headerH->setResizeMode(QHeaderView::Fixed);
	Table->setMinimumSize(300, 100);
#ifdef HAVE_CUPS
	int i;
	cups_dest_t *dests;
	cups_dest_t *dest;
	int num_dests;
	const char	*filename;	/* PPD filename */
	ppd_file_t	*ppd;				/* PPD data */
	ppd_group_t	*group;			/* Current group */
	num_dests = cupsGetDests(&dests);
	dest = cupsGetDest(Geraet.toLocal8Bit().constData(), NULL, num_dests, dests);
	if (!(dest == NULL || (filename = cupsGetPPD(dest->name)) == NULL || (ppd = ppdOpenFile(filename)) == NULL))
	{
		ppdMarkDefaults(ppd);
		cupsMarkOptions(ppd, dest->num_options, dest->options);
		QStringList opts;
		QString Marked = "";
		KeyToText.clear();
		KeyToDefault.clear();
		for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, ++group)
		{
			int ix;
			ppd_option_t	*option;	/* Current option */
			ppd_choice_t	*choice;	/* Current choice */
			for (ix = group->num_options, option = group->options; ix > 0; ix --, ++option)
			{
				int j;
				Marked = "";
				struct OpData Daten;
				opts.clear();
				for (j = option->num_choices, choice = option->choices;
						j > 0; j --, ++choice)
				{
					opts.append(QString(choice->choice));
					if (choice->marked)
						Marked = QString(choice->choice);
				}
				if (!Marked.isEmpty())
				{
					Table->setRowCount(Table->rowCount()+1);
					Table->setItem(Table->rowCount()-1, 0, new QTableWidgetItem(QString(option->text)));
					QComboBox *item = new QComboBox( this );
					item->setEditable(false);
					FlagsOpt.append(item);
					Daten.Cnum = static_cast<int>(FlagsOpt.count()-1);
					Daten.KeyW = QString(option->keyword);
					KeyToText[QString(option->text)] = Daten;
					item->addItems(opts);
					int lastSelected = prefs->getInt(QString(option->text), 0);
					if (lastSelected >= static_cast<int>(opts.count()))
						lastSelected = 0;
					item->setCurrentIndex(lastSelected);
					KeyToDefault[QString(option->text)] = Marked;
					Table->setCellWidget(Table->rowCount()-1, 1, item);
				}
			}
		}
		ppdClose(ppd);
		cupsFreeDests(num_dests, dests);
	}
	struct OpData Daten;

	Table->setRowCount(Table->rowCount()+1);
	Table->setItem(Table->rowCount()-1, 0, new QTableWidgetItem(QString( tr("Page Set"))));
	QComboBox *item4 = new QComboBox( this );
	item4->setEditable(false);
	FlagsOpt.append(item4);
	Daten.Cnum = static_cast<int>(FlagsOpt.count()-1);
	Daten.KeyW = "page-set";
	KeyToText["Page Set"] = Daten;
	item4->addItem( tr("All Pages"));
	item4->addItem( tr("Even Pages only"));
	item4->addItem( tr("Odd Pages only"));
	int lastSelected = prefs->getInt( tr("Page Set"), 0);
	if (lastSelected >= 3)
		lastSelected = 0;
	item4->setCurrentIndex(lastSelected);
	KeyToDefault["Page Set"] = tr("All Pages");
	Table->setCellWidget(Table->rowCount()-1, 1, item4);
	Table->setRowCount(Table->rowCount()+1);
	Table->setItem(Table->rowCount()-1, 0, new QTableWidgetItem(QString( tr("Mirror"))));
	QComboBox *item2 = new QComboBox( this );
	item2->setEditable(false);
	FlagsOpt.append(item2);
	Daten.Cnum = static_cast<int>(FlagsOpt.count()-1);
	Daten.KeyW = "mirror";
	KeyToText["Mirror"] = Daten;
	item2->addItem(CommonStrings::trNo);
	item2->addItem(CommonStrings::trYes);
	item2->setCurrentIndex(0);
	lastSelected = prefs->getInt( tr("Mirror"), 0);
	if (lastSelected >= 2)
		lastSelected = 0;
	item2->setCurrentIndex(lastSelected);
	KeyToDefault["Mirror"] = CommonStrings::trNo;
	Table->setCellWidget(Table->rowCount()-1, 1, item2);
	Table->setRowCount(Table->rowCount()+1);
	Table->setItem(Table->rowCount()-1, 0, new QTableWidgetItem(QString( tr("Orientation"))));
	QComboBox *item5 = new QComboBox( this );
	item5->setEditable(false);
	FlagsOpt.append(item5);
	Daten.Cnum = static_cast<int>(FlagsOpt.count()-1);
	Daten.KeyW = "orientation";
	KeyToText["Orientation"] = Daten;
	item5->addItem( tr("Portrait"));
	item5->addItem( tr("Landscape"));
	item5->setCurrentIndex(0);
	lastSelected = prefs->getInt( tr("Orientation"), 0);
	if (lastSelected >= 2)
		lastSelected = 0;
	item5->setCurrentIndex(lastSelected);
	KeyToDefault["Orientation"] = tr("Portrait");
	Table->setCellWidget(Table->rowCount()-1, 1, item5);
	Table->setRowCount(Table->rowCount()+1);
	Table->setItem(Table->rowCount()-1, 0, new QTableWidgetItem(QString( tr("N-Up Printing"))));
	QComboBox *item3 = new QComboBox( this );
	item3->setEditable(false);
	FlagsOpt.append(item3);
	Daten.Cnum = static_cast<int>(FlagsOpt.count()-1);
	Daten.KeyW = "number-up";
	KeyToText["N-Up Printing"] = Daten;
	item3->addItem("1 "+ tr("Page per Sheet"));
	item3->addItem("2 "+ tr("Pages per Sheet"));
	item3->addItem("4 "+ tr("Pages per Sheet"));
	item3->addItem("6 "+ tr("Pages per Sheet"));
	item3->addItem("9 "+ tr("Pages per Sheet"));
	item3->addItem("16 "+ tr("Pages per Sheet"));
	lastSelected = prefs->getInt( tr("N-Up Printing"), 0);
	if (lastSelected >= 6)
		lastSelected = 0;
	item3->setCurrentIndex(lastSelected);
	KeyToDefault["N-Up Printing"] = "1 "+ tr("Page per Sheet");
	Table->setCellWidget(Table->rowCount()-1, 1, item3);
#endif
	Table->resizeColumnsToContents();
	CupsOptionsLayout->addWidget( Table );

	Layout2 = new QHBoxLayout;
	Layout2->setSpacing( 5 );
	Layout2->setMargin( 0 );
	QSpacerItem* spacer = new QSpacerItem( 2, 2, QSizePolicy::Expanding, QSizePolicy::Minimum );
	Layout2->addItem( spacer );
	PushButton1 = new QPushButton( CommonStrings::tr_OK, this );
	PushButton1->setDefault( true );
	Layout2->addWidget( PushButton1 );
	PushButton2 = new QPushButton( CommonStrings::tr_Cancel, this );
	PushButton2->setDefault( false );
	PushButton1->setFocus();
	Layout2->addWidget( PushButton2 );
	CupsOptionsLayout->addLayout( Layout2 );
	setMinimumSize( sizeHint() );
	resize(minimumSizeHint().expandedTo(QSize(300, 100)));

//tooltips
	Table->setToolTip( "<qt>" + tr( "This panel displays various CUPS options when printing. The exact parameters available will depend on your printer driver. You can confirm CUPS support by selecting Help > About. Look for the listings: C-C-T These equate to C=CUPS C=littlecms T=TIFF support. Missing library support is indicated by a *" ) + "</qt>" );

    // signals and slots connections
	connect( PushButton2, SIGNAL( clicked() ), this, SLOT( reject() ) );
	connect( PushButton1, SIGNAL( clicked() ), this, SLOT( accept() ) );
}
예제 #11
0
파일: rastertolabel.c 프로젝트: aosm/cups
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 */
  unsigned		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.
    */

    _cupsLangPrintFilter(stderr, "ERROR",
                         _("%s job-id user title copies options [file]"),
			 "rastertolabel");
    return (1);
  }

 /*
  * Open the page stream...
  */

  if (argc == 7)
  {
    if ((fd = open(argv[6], O_RDONLY)) == -1)
    {
      _cupsLangPrintError("ERROR", _("Unable to open raster file"));
      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);

  ppd = ppdOpenFile(getenv("PPD"));
  if (!ppd)
  {
    ppd_status_t	status;		/* PPD error */
    int			linenum;	/* Line number */

    _cupsLangPrintFilter(stderr, "ERROR",
                         _("The PPD file could not be opened."));

    status = ppdLastError(&linenum);

    fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);

    return (1);
  }

  ppdMarkDefaults(ppd);
  cupsMarkOptions(ppd, num_options, options);

 /*
  * Initialize the print device...
  */

  Setup(ppd);

 /*
  * 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);
    _cupsLangPrintFilter(stderr, "INFO", _("Starting page %d."), 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)
      {
        _cupsLangPrintFilter(stderr, "INFO",
	                     _("Printing page %d, %u%% complete."),
			     Page, 100 * y / header.cupsHeight);
        fprintf(stderr, "ATTR: job-media-progress=%u\n",
		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...
    */

    _cupsLangPrintFilter(stderr, "INFO", _("Finished page %d."), 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)
  {
    _cupsLangPrintFilter(stderr, "ERROR", _("No pages were found."));
    return (1);
  }
  else
    return (0);
}
예제 #12
0
static
char* make_cmd_param(cups_option_t *p_cups_opt, int num_opt,
	ParamList *p_param, char *p_product, int len)
{
#ifdef DEBUG_PPD
	char *p_ppd_name = "debug.ppd";
#else
	char *p_ppd_name = getenv("PPD");
#endif
	ppd_file_t *p_ppd;
	char *cmd_buf = NULL;
	ppd_choice_t *p_choice;
	ppd_size_t *p_size;
	ppd_size_t *p_default_size;
	int reso;
	char gs_exec_buf[256];
	char gs_cmd_buf[1024];
	char *flt_cmd_buf = NULL;

//For InkJet
	long minw_mm, maxw_mm;
	long minl_mm, maxl_mm;
	PpdToOptKey *p_opt_key_table = alloc_opt_key_table(p_ppd_name);
	PpdToOptKey *p_table = p_opt_key_table;
	ParamList *p_list = NULL;

	if( (p_ppd = ppdOpenFile(p_ppd_name)) == NULL )
		return NULL;

	if( p_opt_key_table == NULL)
		return NULL;

	ppdMarkDefaults(p_ppd);

	// Obtain default page size setting.
	p_choice = ppdFindMarkedChoice(p_ppd, "PageSize");
	p_default_size = ppdPageSize(p_ppd, p_choice->choice);

	mark_ps_param_options(p_ppd, p_param);
	cupsMarkOptions(p_ppd, num_opt, p_cups_opt);

	// Obtain page size setting.
	p_choice = ppdFindMarkedChoice(p_ppd, "PageSize");
	p_size = ppdPageSize(p_ppd, p_choice->choice);

	if (!p_size || ((int)(p_size->width == 0)) || ((int)(p_size->length == 0))) {
	    p_size = p_default_size;
	}

	// Obtain resolution setting.
	p_choice = ppdFindMarkedChoice(p_ppd, "Resolution");
	reso = atoi(p_choice->choice);

	//Obtain product name.
	parse_product_name(p_ppd->product, p_product, len);

	get_min_max_width_length(p_opt_key_table, p_cups_opt, num_opt,
		&minw_mm, &maxw_mm, &minl_mm, &maxl_mm);

// gs command
	strncpy(gs_exec_buf, GS_PATH, 256);
	strncat(gs_exec_buf, "/", 1);
	strncat(gs_exec_buf, GS_BIN, strlen(GS_BIN));
	snprintf(gs_cmd_buf, 1023,
	"%s -r%d -g%dx%d -q -dNOPROMPT -dSAFER -sDEVICE=ppmraw -sOutputFile=- -| ",
			gs_exec_buf, reso, (int)(p_size->width * (float)reso / 72.0),
			(int)(p_size->length * (float)reso / 72.0));

// For InkJet bjfilter Command 
	while( p_table->ppd_key != NULL )
	{
		p_choice = ppdFindMarkedChoice(p_ppd, p_table->ppd_key);
		if( p_choice != NULL )
		{
			char choice[256];

			strncpy(choice, p_choice->choice, 256);

			if( !strcmp(p_table->ppd_key, "PageSize")
			 && !strcmp(choice, "Custom") )
			{
				char pw[256];
				char pl[256];
				long pw_mm, pl_mm;
				pw_mm = (long)((double)p_size->width * 2540.0 / 72.0);
				pl_mm = (long)((double)p_size->length * 2540.0 / 72.0);
				if( minw_mm != -1 && pw_mm < minw_mm )
					pw_mm = minw_mm;
				if( maxw_mm != -1 && pw_mm > maxw_mm )
					pw_mm = maxw_mm;
				if( minl_mm != -1 && pl_mm < minl_mm )
					pl_mm = minl_mm;
				if( maxl_mm != -1 && pl_mm > maxl_mm )
					pl_mm = maxw_mm;
				snprintf(pw, 255, "%ld", pw_mm);
				snprintf(pl, 255, "%ld", pl_mm);
				param_list_add(&p_list, p_table->opt_key, "user", 5);
				param_list_add(&p_list,
					"--paperwidth", pw, strlen(pw) + 1);
				param_list_add(&p_list,
					"--paperheight", pl, strlen(pl) + 1);
			}
			else
			{
				if( !strcmp(p_table->ppd_key, "PageSize")
				 && is_borderless(choice) )
				{
					param_list_add(&p_list, "--borderless", "", 1);
				}
				param_list_add(&p_list, p_table->opt_key,
					choice, strlen(choice) + 1);
			}
		}
		p_table++;
	}

	while( num_opt-- > 0 )
	{
		char *opt_key = ppd_to_opt_key(p_opt_key_table, p_cups_opt->name);
		if( opt_key != NULL )
		{
			char *value = p_cups_opt->value;
			param_list_add(&p_list, opt_key, value, strlen(value) + 1);
		}
		p_cups_opt++;
	}

	{
		char bbox_buf[256];
		float dd = 1.0 - 36.0 / (float)reso;
		int left   = (int)p_size->left;
		int top    = (int)(p_size->top + dd);
		int right  = left + (int)(p_size->right - p_size->left + dd);
		int bottom = top - (int)(p_size->top - p_size->bottom + dd);

		snprintf(bbox_buf, 255, "%-d,%-d,%-d,%-d", left, bottom, right, top);
		param_list_add(&p_list, "--bbox",
				bbox_buf, strlen(bbox_buf) + 1);
	}

	flt_cmd_buf = make_filter_param_line(p_product, reso, p_list);

	if( p_list != NULL ){
		param_list_free(p_list);
		free_opt_key_table(p_opt_key_table);
	}

	ppdClose(p_ppd);

	if( flt_cmd_buf )
	{
		int buf_len;			
		
		buf_len = strlen(gs_cmd_buf) + strlen(flt_cmd_buf) + 1;

		if( (cmd_buf = (char*)malloc(buf_len)) != NULL )
		{
			strcpy(cmd_buf, gs_cmd_buf);
			strcat(cmd_buf, flt_cmd_buf);
		}
		free(flt_cmd_buf);
fprintf(stderr, "pstocanonbj: %s\n", cmd_buf);
		return cmd_buf;
	}
	else
		return NULL;
}
예제 #13
0
static int				/* O - 0 on success, 1 on fail */
set_printer_options(
    http_t        *http,		/* I - Server connection */
    char          *printer,		/* I - Printer */
    int           num_options,		/* I - Number of options */
    cups_option_t *options,		/* I - Options */
    char          *file)		/* I - PPD file/interface script */
{
  ipp_t		*request;		/* IPP Request */
  const char	*ppdfile;		/* PPD filename */
  int		ppdchanged;		/* PPD changed? */
  ppd_file_t	*ppd;			/* PPD file */
  ppd_choice_t	*choice;		/* Marked choice */
  char		uri[HTTP_MAX_URI],	/* URI for printer/class */
		line[1024],		/* Line from PPD file */
		keyword[1024],		/* Keyword from Default line */
		*keyptr,		/* Pointer into keyword... */
		tempfile[1024];		/* Temporary filename */
  cups_file_t	*in,			/* PPD file */
		*out;			/* Temporary file */
  const char	*protocol,		/* Old protocol option */
		*customval,		/* Custom option value */
		*boolval;		/* Boolean value */
  int		wrote_ipp_supplies = 0,	/* Wrote cupsIPPSupplies keyword? */
		wrote_snmp_supplies = 0;/* Wrote cupsSNMPSupplies keyword? */


  DEBUG_printf(("set_printer_options(http=%p, printer=\"%s\", num_options=%d, "
                "options=%p, file=\"%s\")\n", http, printer, num_options,
		options, file));

 /*
  * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which
  * requires the following attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requesting-user-name
  *    other options
  */

  if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)
    request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
  else
    request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
               "printer-uri", NULL, uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
               "requesting-user-name", NULL, cupsUser());

 /*
  * Add the options...
  */

  cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);

  if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL)
  {
    if (!_cups_strcasecmp(protocol, "bcp"))
      ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
                   NULL, "bcp");
    else if (!_cups_strcasecmp(protocol, "tbcp"))
      ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
                   NULL, "tbcp");
  }

  if (file)
    ppdfile = file;
  else if (request->request.op.operation_id == CUPS_ADD_MODIFY_PRINTER)
    ppdfile = cupsGetPPD(printer);
  else
    ppdfile = NULL;

  if (ppdfile != NULL)
  {
   /*
    * Set default options in the PPD file...
    */

    ppd = ppdOpenFile(ppdfile);
    ppdMarkDefaults(ppd);
    cupsMarkOptions(ppd, num_options, options);

    if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
    {
      _cupsLangPrintError(NULL, _("lpadmin: Unable to create temporary file"));
      ippDelete(request);
      if (ppdfile != file)
        unlink(ppdfile);
      return (1);
    }

    if ((in = cupsFileOpen(ppdfile, "r")) == NULL)
    {
      _cupsLangPrintf(stderr,
                      _("lpadmin: Unable to open PPD file \"%s\" - %s"),
        	      ppdfile, strerror(errno));
      ippDelete(request);
      if (ppdfile != file)
	unlink(ppdfile);
      cupsFileClose(out);
      unlink(tempfile);
      return (1);
    }

    ppdchanged = 0;

    while (cupsFileGets(in, line, sizeof(line)))
    {
      if (!strncmp(line, "*cupsIPPSupplies:", 17) &&
	  (boolval = cupsGetOption("cupsIPPSupplies", num_options,
	                           options)) != NULL)
      {
        wrote_ipp_supplies = 1;
        cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
	               (!_cups_strcasecmp(boolval, "true") ||
		        !_cups_strcasecmp(boolval, "yes") ||
		        !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
      }
      else if (!strncmp(line, "*cupsSNMPSupplies:", 18) &&
	       (boolval = cupsGetOption("cupsSNMPSupplies", num_options,
	                                options)) != NULL)
      {
        wrote_snmp_supplies = 1;
        cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
	               (!_cups_strcasecmp(boolval, "true") ||
		        !_cups_strcasecmp(boolval, "yes") ||
		        !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
      }
      else if (strncmp(line, "*Default", 8))
        cupsFilePrintf(out, "%s\n", line);
      else
      {
       /*
        * Get default option name...
	*/

        strlcpy(keyword, line + 8, sizeof(keyword));

	for (keyptr = keyword; *keyptr; keyptr ++)
	  if (*keyptr == ':' || isspace(*keyptr & 255))
	    break;

        *keyptr++ = '\0';
        while (isspace(*keyptr & 255))
	  keyptr ++;

        if (!strcmp(keyword, "PageRegion") ||
	    !strcmp(keyword, "PageSize") ||
	    !strcmp(keyword, "PaperDimension") ||
	    !strcmp(keyword, "ImageableArea"))
	{
	  if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL)
	    choice = ppdFindMarkedChoice(ppd, "PageRegion");
        }
	else
	  choice = ppdFindMarkedChoice(ppd, keyword);

        if (choice && strcmp(choice->choice, keyptr))
	{
	  if (strcmp(choice->choice, "Custom"))
	  {
	    cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice);
	    ppdchanged = 1;
	  }
	  else if ((customval = cupsGetOption(keyword, num_options,
	                                      options)) != NULL)
	  {
	    cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval);
	    ppdchanged = 1;
	  }
	  else
	    cupsFilePrintf(out, "%s\n", line);
	}
	else
	  cupsFilePrintf(out, "%s\n", line);
      }
    }

    if (!wrote_ipp_supplies &&
	(boolval = cupsGetOption("cupsIPPSupplies", num_options,
				 options)) != NULL)
    {
      cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
		     (!_cups_strcasecmp(boolval, "true") ||
		      !_cups_strcasecmp(boolval, "yes") ||
		      !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
    }

    if (!wrote_snmp_supplies &&
        (boolval = cupsGetOption("cupsSNMPSupplies", num_options,
			         options)) != NULL)
    {
      cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
		     (!_cups_strcasecmp(boolval, "true") ||
		      !_cups_strcasecmp(boolval, "yes") ||
		      !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
    }

    cupsFileClose(in);
    cupsFileClose(out);
    ppdClose(ppd);

   /*
    * Do the request...
    */

    ippDelete(cupsDoFileRequest(http, request, "/admin/",
                                ppdchanged ? tempfile : file));

   /*
    * Clean up temp files... (TODO: catch signals in case we CTRL-C during
    * lpadmin)
    */

    if (ppdfile != file)
      unlink(ppdfile);
    unlink(tempfile);
  }
  else
  {
   /*
    * No PPD file - just set the options...
    */

    ippDelete(cupsDoRequest(http, request, "/admin/"));
  }

 /*
  * Check the response...
  */

  if (cupsLastError() > IPP_OK_CONFLICT)
  {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

    return (1);
  }
  else
    return (0);
}
예제 #14
0
파일: graceapp.c 프로젝트: mariusal/grace
int gapp_init_print(RunTime *rt)
{
#ifdef HAVE_CUPS
    int i;
    cups_dest_t *dests;
    
    rt->print_dest = 0;
    
    rt->num_print_dests = cupsGetDests(&dests);
    if (!rt->num_print_dests) {
        /* no CUPS printers defined or CUPS not running */
        rt->use_cups = FALSE;
    } else {
        rt->print_dests = xcalloc(rt->num_print_dests, sizeof(PrintDest));
        if (rt->print_dests == NULL) {
            return RETURN_FAILURE;
        }
    }
    
    for (i = 0; i < rt->num_print_dests; i++) {
        cups_dest_t *dest = &dests[i];
        PrintDest *pd = &rt->print_dests[i];

        char *printer;
        int           j;
        const char    *filename;        /* PPD filename */
        ppd_file_t    *ppd;             /* PPD data */
        ppd_group_t   *group;           /* Current group */
        
        printer = copy_string(NULL, dest->name);
        if (dest->instance) {
            printer = concat_strings(printer, "/");
            printer = concat_strings(printer, dest->instance);
        }
        
        pd->name    = copy_string(NULL, dest->name);
        pd->inst    = copy_string(NULL, dest->instance);
        pd->printer = printer;
        
        if (dest->is_default) {
            rt->print_dest = i;
        }
        
        if ((filename = cupsGetPPD(dest->name)) == NULL) {
            continue;
        }

        if ((ppd = ppdOpenFile(filename)) == NULL) {
            remove(filename);
            continue;
        }

        ppdMarkDefaults(ppd);
        cupsMarkOptions(ppd, dest->num_options, dest->options);

        for (j = 0, group = ppd->groups; j < ppd->num_groups; j++, group++) {
            parse_group(pd, group);
        }

        ppdClose(ppd);
        remove(filename);
    }
    cupsFreeDests(rt->num_print_dests, dests);
#else
    rt->print_dest = 0;
    rt->num_print_dests = 0;
#endif

    return RETURN_SUCCESS;
}
static void
populate_options_real (PpOptionsDialog *dialog)
{
  GtkTreeSelection *selection;
  GtkTreeModel     *model;
  GtkTreeView      *treeview;
  GtkTreeIter       iter;
  ppd_file_t       *ppd_file;
  GtkWidget        *notebook;
  GtkWidget        *grid;
  GtkWidget        *general_tab_grid = tab_grid_new ();
  GtkWidget        *page_setup_tab_grid = tab_grid_new ();
  GtkWidget        *installable_options_tab_grid = tab_grid_new ();
  GtkWidget        *job_tab_grid = tab_grid_new ();
  GtkWidget        *image_quality_tab_grid = tab_grid_new ();
  GtkWidget        *color_tab_grid = tab_grid_new ();
  GtkWidget        *finishing_tab_grid = tab_grid_new ();
  GtkWidget        *advanced_tab_grid = tab_grid_new ();
  GtkWidget        *widget;
  gint              i, j;

  widget = (GtkWidget*)
    gtk_builder_get_object (dialog->builder, "options-spinner");
  gtk_widget_hide (widget);
  gtk_spinner_stop (GTK_SPINNER (widget));

  widget = (GtkWidget*)
    gtk_builder_get_object (dialog->builder, "progress-label");
  gtk_widget_hide (widget);

  treeview = (GtkTreeView *)
    gtk_builder_get_object (dialog->builder, "options-categories-treeview");

  notebook = (GtkWidget *)
    gtk_builder_get_object (dialog->builder, "options-notebook");

  if (dialog->ipp_attributes)
    {
      /* Add number-up option to Page Setup tab */
      ipp_option_add (g_hash_table_lookup (dialog->ipp_attributes,
                                           "number-up-supported"),
                      g_hash_table_lookup (dialog->ipp_attributes,
                                           "number-up-default"),
                      "number-up",
                      /* Translators: This option sets number of pages printed on one sheet */
                      _("Pages per side"),
                      dialog->printer_name,
                      page_setup_tab_grid,
                      dialog->sensitive);

      /* Add sides option to Page Setup tab */
      ipp_option_add (g_hash_table_lookup (dialog->ipp_attributes,
                                           "sides-supported"),
                      g_hash_table_lookup (dialog->ipp_attributes,
                                           "sides-default"),
                      "sides",
                      /* Translators: This option sets whether to print on both sides of paper */
                      _("Two-sided"),
                      dialog->printer_name,
                      page_setup_tab_grid,
                      dialog->sensitive);

      /* Add orientation-requested option to Page Setup tab */
      ipp_option_add (g_hash_table_lookup (dialog->ipp_attributes,
                                           "orientation-requested-supported"),
                      g_hash_table_lookup (dialog->ipp_attributes,
                                           "orientation-requested-default"),
                      "orientation-requested",
                      /* Translators: This option sets orientation of print (portrait, landscape...) */
                      _("Orientation"),
                      dialog->printer_name,
                      page_setup_tab_grid,
                      dialog->sensitive);
    }

  if (dialog->destination && dialog->ppd_filename)
    {
      ppd_file = ppdOpenFile (dialog->ppd_filename);
      ppdLocalize (ppd_file);

      if (ppd_file)
        {
          ppdMarkDefaults (ppd_file);
          cupsMarkOptions (ppd_file,
                           dialog->destination->num_options,
                           dialog->destination->options);

          for (i = 0; i < ppd_file->num_groups; i++)
            {
              for (j = 0; j < ppd_file->groups[i].num_options; j++)
                {
                  grid = NULL;

                  if (STRING_IN_TABLE (ppd_file->groups[i].name,
                                       color_group_whitelist))
                    grid = color_tab_grid;
                  else if (STRING_IN_TABLE (ppd_file->groups[i].name,
                                            image_quality_group_whitelist))
                    grid = image_quality_tab_grid;
                  else if (STRING_IN_TABLE (ppd_file->groups[i].name,
                                            job_group_whitelist))
                    grid = job_tab_grid;
                  else if (STRING_IN_TABLE (ppd_file->groups[i].name,
                                            finishing_group_whitelist))
                    grid = finishing_tab_grid;
                  else if (STRING_IN_TABLE (ppd_file->groups[i].name,
                                            installable_options_group_whitelist))
                    grid = installable_options_tab_grid;
                  else if (STRING_IN_TABLE (ppd_file->groups[i].name,
                                            page_setup_group_whitelist))
                    grid = page_setup_tab_grid;

                  if (!STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
                                        ppd_option_blacklist))
                    {
                      if (!grid && STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
                                                    color_option_whitelist))
                        grid = color_tab_grid;
                      else if (!grid && STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
                                                         image_quality_option_whitelist))
                        grid = image_quality_tab_grid;
                      else if (!grid && STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
                                                         finishing_option_whitelist))
                        grid = finishing_tab_grid;
                      else if (!grid && STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
                                                         page_setup_option_whitelist))
                        grid = page_setup_tab_grid;

                      if (!grid)
                        grid = advanced_tab_grid;

                      ppd_option_add (ppd_file->groups[i].options[j],
                                      dialog->printer_name,
                                      grid,
                                      dialog->sensitive);
                    }
                }
            }

          ppdClose (ppd_file);
        }
    }

  dialog->ppd_filename_set = FALSE;
  if (dialog->ppd_filename)
    {
      g_unlink (dialog->ppd_filename);
      g_free (dialog->ppd_filename);
      dialog->ppd_filename = NULL;
    }

  dialog->destination_set = FALSE;
  if (dialog->destination)
    {
      cupsFreeDests (1, dialog->destination);
      dialog->destination = NULL;
    }

  dialog->ipp_attributes_set = FALSE;
  if (dialog->ipp_attributes)
    {
      g_hash_table_unref (dialog->ipp_attributes);
      dialog->ipp_attributes = NULL;
    }

  /* Translators: "General" tab contains general printer options */
  tab_add (C_("Printer Option Group", "General"), notebook, treeview, general_tab_grid);

  /* Translators: "Page Setup" tab contains settings related to pages (page size, paper source, etc.) */
  tab_add (C_("Printer Option Group", "Page Setup"), notebook, treeview, page_setup_tab_grid);

  /* Translators: "Installable Options" tab contains settings of presence of installed options (amount of RAM, duplex unit, etc.) */
  tab_add (C_("Printer Option Group", "Installable Options"), notebook, treeview, installable_options_tab_grid);

  /* Translators: "Job" tab contains settings for jobs */
  tab_add (C_("Printer Option Group", "Job"), notebook, treeview, job_tab_grid);

  /* Translators: "Image Quality" tab contains settings for quality of output print (e.g. resolution) */
  tab_add (C_("Printer Option Group", "Image Quality"), notebook, treeview, image_quality_tab_grid);

  /* Translators: "Color" tab contains color settings (e.g. color printing) */
  tab_add (C_("Printer Option Group", "Color"), notebook, treeview, color_tab_grid);

  /* Translators: "Finishing" tab contains finishing settings (e.g. booklet printing) */
  tab_add (C_("Printer Option Group", "Finishing"), notebook, treeview, finishing_tab_grid);

  /* Translators: "Advanced" tab contains all others settings */
  tab_add (C_("Printer Option Group", "Advanced"), notebook, treeview, advanced_tab_grid);

  gtk_widget_show_all (GTK_WIDGET (notebook));

  /* Select the first option group */
  if ((selection = gtk_tree_view_get_selection (treeview)) != NULL)
    {
      g_signal_connect (selection,
                        "changed",
                        G_CALLBACK (category_selection_changed_cb), dialog);

      if ((model = gtk_tree_view_get_model (treeview)) != NULL &&
          gtk_tree_model_get_iter_first (model, &iter))
        gtk_tree_selection_select_iter (selection, &iter);
    }

  dialog->populating_dialog = FALSE;
  if (dialog->response != GTK_RESPONSE_NONE)
    {
      dialog->user_callback (GTK_DIALOG (dialog->dialog), dialog->response, dialog->user_data);
    }
}
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int			fd;		/* Raster file */
  cups_raster_t		*inras,		/* Input raster stream */
			*outras;	/* Output raster stream */
  cups_page_header2_t	inheader,	/* Input raster page header */
			outheader;	/* Output raster page header */
  int			y;		/* Current line */
  unsigned char		*line;		/* Line buffer */
  int			page = 0,	/* Current page */
			page_width,	/* Actual page width */
			page_height,	/* Actual page height */
			page_top,	/* Top margin */
			page_bottom,	/* Bottom margin */
			page_left,	/* Left margin */
			linesize,	/* Bytes per line */
			lineoffset;	/* Offset into line */
  unsigned char		white;		/* White pixel */
  ppd_file_t		*ppd;		/* PPD file */
  ppd_attr_t		*back;		/* cupsBackSize attribute */
  _ppd_cache_t		*cache;		/* PPD cache */
  _pwg_size_t		*pwg_size;	/* PWG media size */
  _pwg_media_t		*pwg_media;	/* PWG media name */
  int	 		num_options;	/* Number of options */
  cups_option_t		*options = NULL;/* Options */
  const char		*val;		/* Option value */


  if (argc < 6 || argc > 7)
  {
    puts("Usage: rastertopwg job user title copies options [filename]");
    return (1);
  }
  else if (argc == 7)
  {
    if ((fd = open(argv[6], O_RDONLY)) < 0)
    {
      perror("ERROR: Unable to open print file");
      return (1);
    }
  }
  else
    fd = 0;

  inras  = cupsRasterOpen(fd, CUPS_RASTER_READ);
  outras = cupsRasterOpen(1, CUPS_RASTER_WRITE_PWG);

  ppd   = ppdOpenFile(getenv("PPD"));
  back  = ppdFindAttr(ppd, "cupsBackSide", NULL);

  num_options = cupsParseOptions(argv[5], 0, &options);

  ppdMarkDefaults(ppd);
  cupsMarkOptions(ppd, num_options, options);

  cache = ppd ? ppd->cache : NULL;

  while (cupsRasterReadHeader2(inras, &inheader))
  {
   /*
    * Compute the real raster size...
    */

    page ++;

    fprintf(stderr, "PAGE: %d %d\n", page, inheader.NumCopies);

    page_width  = (int)(inheader.cupsPageSize[0] * inheader.HWResolution[0] /
                        72.0);
    page_height = (int)(inheader.cupsPageSize[1] * inheader.HWResolution[1] /
                        72.0);
    page_left   = (int)(inheader.cupsImagingBBox[0] *
                        inheader.HWResolution[0] / 72.0);
    page_bottom = (int)(inheader.cupsImagingBBox[1] *
                        inheader.HWResolution[1] / 72.0);
    page_top    = page_height - page_bottom - inheader.cupsHeight;
    linesize    = (page_width * inheader.cupsBitsPerPixel + 7) / 8;
    lineoffset  = page_left * inheader.cupsBitsPerPixel / 8; /* Round down */

    switch (inheader.cupsColorSpace)
    {
      case CUPS_CSPACE_W :
      case CUPS_CSPACE_RGB :
      case CUPS_CSPACE_SW :
      case CUPS_CSPACE_SRGB :
      case CUPS_CSPACE_ADOBERGB :
          white = 255;
	  break;

      case CUPS_CSPACE_K :
      case CUPS_CSPACE_CMYK :
      case CUPS_CSPACE_DEVICE1 :
      case CUPS_CSPACE_DEVICE2 :
      case CUPS_CSPACE_DEVICE3 :
      case CUPS_CSPACE_DEVICE4 :
      case CUPS_CSPACE_DEVICE5 :
      case CUPS_CSPACE_DEVICE6 :
      case CUPS_CSPACE_DEVICE7 :
      case CUPS_CSPACE_DEVICE8 :
      case CUPS_CSPACE_DEVICE9 :
      case CUPS_CSPACE_DEVICEA :
      case CUPS_CSPACE_DEVICEB :
      case CUPS_CSPACE_DEVICEC :
      case CUPS_CSPACE_DEVICED :
      case CUPS_CSPACE_DEVICEE :
      case CUPS_CSPACE_DEVICEF :
          white = 0;
	  break;

      default :
	  _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
	  fprintf(stderr, "DEBUG: Unsupported cupsColorSpace %d on page %d.\n",
	          inheader.cupsColorSpace, page);
	  return (1);
    }

    if (inheader.cupsColorOrder != CUPS_ORDER_CHUNKED)
    {
      _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
      fprintf(stderr, "DEBUG: Unsupported cupsColorOrder %d on page %d.\n",
              inheader.cupsColorOrder, page);
      return (1);
    }

    if (inheader.cupsBitsPerPixel != 1 &&
        inheader.cupsBitsPerColor != 8 && inheader.cupsBitsPerColor != 16)
    {
      _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
      fprintf(stderr, "DEBUG: Unsupported cupsBitsPerColor %d on page %d.\n",
              inheader.cupsBitsPerColor, page);
      return (1);
    }

    memcpy(&outheader, &inheader, sizeof(outheader));
    outheader.cupsWidth        = page_width;
    outheader.cupsHeight       = page_height;
    outheader.cupsBytesPerLine = linesize;

    outheader.cupsInteger[14]  = 0;	/* VendorIdentifier */
    outheader.cupsInteger[15]  = 0;	/* VendorLength */

    if ((val = cupsGetOption("print-content-optimize", num_options,
                             options)) != NULL)
    {
      if (!strcmp(val, "automatic"))
        strlcpy(outheader.OutputType, "Automatic",
                sizeof(outheader.OutputType));
      else if (!strcmp(val, "graphics"))
        strlcpy(outheader.OutputType, "Graphics", sizeof(outheader.OutputType));
      else if (!strcmp(val, "photo"))
        strlcpy(outheader.OutputType, "Photo", sizeof(outheader.OutputType));
      else if (!strcmp(val, "text"))
        strlcpy(outheader.OutputType, "Text", sizeof(outheader.OutputType));
      else if (!strcmp(val, "text-and-graphics"))
        strlcpy(outheader.OutputType, "TextAndGraphics",
                sizeof(outheader.OutputType));
      else
      {
        fprintf(stderr, "DEBUG: Unsupported print-content-type \"%s\".\n", val);
        outheader.OutputType[0] = '\0';
      }
    }

    if ((val = cupsGetOption("print-quality", num_options, options)) != NULL)
    {
      int quality = atoi(val);		/* print-quality value */

      if (quality >= IPP_QUALITY_DRAFT && quality <= IPP_QUALITY_HIGH)
	outheader.cupsInteger[8] = quality;
      else
      {
	fprintf(stderr, "DEBUG: Unsupported print-quality %d.\n", quality);
	outheader.cupsInteger[8] = 0;
      }
    }

    if ((val = cupsGetOption("print-rendering-intent", num_options,
                             options)) != NULL)
    {
      if (!strcmp(val, "absolute"))
        strlcpy(outheader.cupsRenderingIntent, "Absolute",
                sizeof(outheader.cupsRenderingIntent));
      else if (!strcmp(val, "automatic"))
        strlcpy(outheader.cupsRenderingIntent, "Automatic",
                sizeof(outheader.cupsRenderingIntent));
      else if (!strcmp(val, "perceptual"))
        strlcpy(outheader.cupsRenderingIntent, "Perceptual",
                sizeof(outheader.cupsRenderingIntent));
      else if (!strcmp(val, "relative"))
        strlcpy(outheader.cupsRenderingIntent, "Relative",
                sizeof(outheader.cupsRenderingIntent));
      else if (!strcmp(val, "relative-bpc"))
        strlcpy(outheader.cupsRenderingIntent, "RelativeBpc",
                sizeof(outheader.cupsRenderingIntent));
      else if (!strcmp(val, "saturation"))
        strlcpy(outheader.cupsRenderingIntent, "Saturation",
                sizeof(outheader.cupsRenderingIntent));
      else
      {
        fprintf(stderr, "DEBUG: Unsupported print-rendering-intent \"%s\".\n",
                val);
        outheader.cupsRenderingIntent[0] = '\0';
      }
    }

    if (inheader.cupsPageSizeName[0] &&
        (pwg_size = _ppdCacheGetSize(cache, inheader.cupsPageSizeName)) != NULL)
    {
      strlcpy(outheader.cupsPageSizeName, pwg_size->map.pwg,
	      sizeof(outheader.cupsPageSizeName));
    }
    else
    {
      pwg_media = _pwgMediaForSize((int)(2540.0 * inheader.cupsPageSize[0] /
                                         72.0),
                                   (int)(2540.0 * inheader.cupsPageSize[1] /
                                         72.0));

      if (pwg_media)
        strlcpy(outheader.cupsPageSizeName, pwg_media->pwg,
                sizeof(outheader.cupsPageSizeName));
      else
      {
        fprintf(stderr, "DEBUG: Unsupported PageSize %.2fx%.2f.\n",
                inheader.cupsPageSize[0], inheader.cupsPageSize[1]);
        outheader.cupsPageSizeName[0] = '\0';
      }
    }

    if (inheader.Duplex && !(page & 1) &&
        back && _cups_strcasecmp(back->value, "Normal"))
    {
      if (_cups_strcasecmp(back->value, "Flipped"))
      {
        if (inheader.Tumble)
        {
	  outheader.cupsInteger[1] = -1;/* CrossFeedTransform */
	  outheader.cupsInteger[2] = 1;	/* FeedTransform */

	  outheader.cupsInteger[3] = page_width - page_left -
	                             inheader.cupsWidth;
					/* ImageBoxLeft */
	  outheader.cupsInteger[4] = page_top;
					/* ImageBoxTop */
	  outheader.cupsInteger[5] = page_width - page_left;
      					/* ImageBoxRight */
	  outheader.cupsInteger[6] = page_height - page_bottom;
      					/* ImageBoxBottom */
        }
        else
        {
	  outheader.cupsInteger[1] = 1;	/* CrossFeedTransform */
	  outheader.cupsInteger[2] = -1;/* FeedTransform */

	  outheader.cupsInteger[3] = page_left;
					/* ImageBoxLeft */
	  outheader.cupsInteger[4] = page_bottom;
					/* ImageBoxTop */
	  outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
      					/* ImageBoxRight */
	  outheader.cupsInteger[6] = page_height - page_top;
      					/* ImageBoxBottom */
        }
      }
      else if (_cups_strcasecmp(back->value, "ManualTumble"))
      {
        if (inheader.Tumble)
        {
	  outheader.cupsInteger[1] = -1;/* CrossFeedTransform */
	  outheader.cupsInteger[2] = -1;/* FeedTransform */

	  outheader.cupsInteger[3] = page_width - page_left -
	                             inheader.cupsWidth;
					/* ImageBoxLeft */
	  outheader.cupsInteger[4] = page_bottom;
					/* ImageBoxTop */
	  outheader.cupsInteger[5] = page_width - page_left;
      					/* ImageBoxRight */
	  outheader.cupsInteger[6] = page_height - page_top;
      					/* ImageBoxBottom */
        }
        else
        {
	  outheader.cupsInteger[1] = 1;	/* CrossFeedTransform */
	  outheader.cupsInteger[2] = 1;	/* FeedTransform */

	  outheader.cupsInteger[3] = page_left;
					/* ImageBoxLeft */
	  outheader.cupsInteger[4] = page_top;
					/* ImageBoxTop */
	  outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
      					/* ImageBoxRight */
	  outheader.cupsInteger[6] = page_height - page_bottom;
      					/* ImageBoxBottom */
        }
      }
      else if (_cups_strcasecmp(back->value, "Rotated"))
      {
        if (inheader.Tumble)
        {
	  outheader.cupsInteger[1] = -1;/* CrossFeedTransform */
	  outheader.cupsInteger[2] = -1;/* FeedTransform */

	  outheader.cupsInteger[3] = page_width - page_left -
	                             inheader.cupsWidth;
					/* ImageBoxLeft */
	  outheader.cupsInteger[4] = page_bottom;
					/* ImageBoxTop */
	  outheader.cupsInteger[5] = page_width - page_left;
      					/* ImageBoxRight */
	  outheader.cupsInteger[6] = page_height - page_top;
      					/* ImageBoxBottom */
        }
        else
        {
	  outheader.cupsInteger[1] = 1;	/* CrossFeedTransform */
	  outheader.cupsInteger[2] = 1;	/* FeedTransform */

	  outheader.cupsInteger[3] = page_left;
					/* ImageBoxLeft */
	  outheader.cupsInteger[4] = page_top;
					/* ImageBoxTop */
	  outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
      					/* ImageBoxRight */
	  outheader.cupsInteger[6] = page_height - page_bottom;
      					/* ImageBoxBottom */
        }
      }
      else
      {
       /*
        * Unsupported value...
        */

        fprintf(stderr, "DEBUG: Unsupported cupsBackSide \"%s\".\n", back->value);

	outheader.cupsInteger[1] = 1;	/* CrossFeedTransform */
	outheader.cupsInteger[2] = 1;	/* FeedTransform */

	outheader.cupsInteger[3] = page_left;
					/* ImageBoxLeft */
	outheader.cupsInteger[4] = page_top;
					/* ImageBoxTop */
	outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
      					/* ImageBoxRight */
	outheader.cupsInteger[6] = page_height - page_bottom;
      					/* ImageBoxBottom */
      }
    }
    else
    {
      outheader.cupsInteger[1] = 1;	/* CrossFeedTransform */
      outheader.cupsInteger[2] = 1;	/* FeedTransform */

      outheader.cupsInteger[3] = page_left;
					/* ImageBoxLeft */
      outheader.cupsInteger[4] = page_top;
					/* ImageBoxTop */
      outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
      					/* ImageBoxRight */
      outheader.cupsInteger[6] = page_height - page_bottom;
      					/* ImageBoxBottom */
    }

    if (!cupsRasterWriteHeader2(outras, &outheader))
    {
      _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
      fprintf(stderr, "DEBUG: Unable to write header for page %d.\n", page);
      return (1);
    }

   /*
    * Copy raster data...
    */

    line = malloc(linesize);

    memset(line, white, linesize);
    for (y = page_top; y > 0; y --)
      if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
      {
	_cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
	fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
	        page_top - y + 1, page);
	return (1);
      }

    for (y = inheader.cupsHeight; y > 0; y --)
    {
      cupsRasterReadPixels(inras, line + lineoffset, inheader.cupsBytesPerLine);
      if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
      {
	_cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
	fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
	        inheader.cupsHeight - y + page_top + 1, page);
	return (1);
      }
    }

    memset(line, white, linesize);
    for (y = page_bottom; y > 0; y --)
      if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
      {
	_cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
	fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
	        page_bottom - y + page_top + inheader.cupsHeight + 1, page);
	return (1);
      }

    free(line);
  }

  cupsRasterClose(inras);
  if (fd)
    close(fd);

  cupsRasterClose(outras);

  return (0);
}
예제 #17
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  ppd_file_t	*ppd;			/* PPD file loaded from disk */
  char		line[256],		/* Input buffer */
		*ptr,			/* Pointer into buffer */
		*optr,			/* Pointer to first option name */
		*cptr;			/* Pointer to first choice */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  char		*option,		/* Current option */
		*choice;		/* Current choice */


  if (argc != 2)
  {
    puts("Usage: testconflicts filename.ppd");
    return (1);
  }

  if ((ppd = ppdOpenFile(argv[1])) == NULL)
  {
    ppd_status_t	err;		/* Last error in file */
    int			linenum;	/* Line number in file */

    err = ppdLastError(&linenum);

    printf("Unable to open PPD file \"%s\": %s on line %d\n", argv[1],
           ppdErrorString(err), linenum);
    return (1);
  }

  ppdMarkDefaults(ppd);

  option = NULL;
  choice = NULL;

  for (;;)
  {
    num_options = 0;
    options     = NULL;

    if (!cupsResolveConflicts(ppd, option, choice, &num_options, &options))
      puts("Unable to resolve conflicts!");
    else if ((!option && num_options > 0) || (option && num_options > 1))
    {
      fputs("Resolved conflicts with the following options:\n   ", stdout);
      for (i = 0; i < num_options; i ++)
        if (!option || _cups_strcasecmp(option, options[i].name))
	  printf(" %s=%s", options[i].name, options[i].value);
      putchar('\n');

      cupsFreeOptions(num_options, options);
    }

    if (option)
    {
      free(option);
      option = NULL;
    }

    if (choice)
    {
      free(choice);
      choice = NULL;
    }

    printf("\nNew Option(s): ");
    fflush(stdout);
    if (!fgets(line, sizeof(line), stdin) || line[0] == '\n')
      break;

    for (ptr = line; isspace(*ptr & 255); ptr ++);
    for (optr = ptr; *ptr && *ptr != '='; ptr ++);
    if (!*ptr)
      break;
    for (*ptr++ = '\0', cptr = ptr; *ptr && !isspace(*ptr & 255); ptr ++);
    if (!*ptr)
      break;
    *ptr++ = '\0';

    option      = strdup(optr);
    choice      = strdup(cptr);
    num_options = cupsParseOptions(ptr, 0, &options);

    ppdMarkOption(ppd, option, choice);
    if (cupsMarkOptions(ppd, num_options, options))
      puts("Options Conflict!");
    cupsFreeOptions(num_options, options);
  }

  if (option)
    free(option);
  if (choice)
    free(choice);

  return (0);
}
예제 #18
0
void GetOptionStringFromCups (char *pPrinter, int fd)
{
    int            i, j;
    int            iJS;
    int            num_dests;
    cups_dest_t    *dests;
    cups_dest_t    *dest;
    char           *opt;
    char           *ppdFileName;
    ppd_file_t     *ppdFile;
    char           szJSOptionString[1024];

fprintf (stderr, "DEBUG: In GetOption.... printer = %s, fd = %d\n", pPrinter, fd);
    ppdFileName = (char *) cupsGetPPD (pPrinter);
    if (!ppdFileName)
    {
fprintf (stderr, "DEBUG: did not get ppdfilename\n");
        return;
    }
fprintf (stderr, "DEBUG: ppdFileName = %s\n", ppdFileName);
    ppdFile = ppdOpenFile (ppdFileName);
fprintf (stderr, "DEBUG: ppdFileName = %s\n", ppdFileName);
    if (ppdFile == NULL)
    {
fprintf (stderr, "DEBUG: unable to open ppdfile, %s\n", ppdFileName);
        return;
    }
    num_dests = cupsGetDests (&dests);
    if (num_dests == 0)
    {
fprintf (stderr, "DEBUG: num_dests is zero\n");
        ppdClose (ppdFile);
        return;
    }
    dest = cupsGetDest (pPrinter, NULL, num_dests, dests);
    if (dest == NULL)
    {
fprintf (stderr, "DEBUG: did not get dest for printer %s\n", pPrinter);
        ppdClose (ppdFile);
        return;
    }
    ppdMarkDefaults (ppdFile);
    cupsMarkOptions (ppdFile, dest->num_options, dest->options);
    iJS = sizeof (szJSStrings) / sizeof (szJSStrings[0]);
    if ((opt = (char *) cupsGetOption ("HOLD", dest->num_options, dest->options)) == NULL)
    {
fprintf (stderr, "DEBUG: did not see HOLD option\nOptions in the list are:\n");
for (i = 0; i < dest->num_options; i++)
{
    fprintf (stderr, "DEBUG: Option = %s : value = %s\n", dest->options[i].name, dest->options[i].value);
}

        ppdClose (ppdFile);
        return;
    }
    memset (szJSOptionString, 0, sizeof (szJSOptionString));
    j = sprintf (szJSOptionString, "HOLD=%s", opt);
    for (i = 0; i < iJS; i++)
    {
        if ((opt = (char *) cupsGetOption (szJSStrings[i], dest->num_options, dest->options)))
        {
fprintf (stderr, "DEBUG: cupsGetOption returned %s = %s\n", szJSStrings[i], opt);
            j += sprintf (szJSOptionString + j, " %s=%s", szJSStrings[i], opt);
        }
    }
    ppdClose (ppdFile);
    cupsFreeDests (num_dests, dests);
fprintf (stderr, "DEBUG: Calling SendJobHoldCommands with %s\n", szJSOptionString);
    SendJobHoldCommands (szJSOptionString, fd);
}
예제 #19
0
void dt_get_printer_info(const char *printer_name, dt_printer_info_t *pinfo)
{
  cups_dest_t *dests;
  int num_dests = cupsGetDests(&dests);
  cups_dest_t *dest = cupsGetDest(printer_name, NULL, num_dests, dests);

  if (dest)
  {
    const char *PPDFile = cupsGetPPD (printer_name);
    g_strlcpy(pinfo->name, dest->name, MAX_NAME);
    ppd_file_t *ppd = ppdOpenFile(PPDFile);

    if (ppd)
    {
      ppdMarkDefaults(ppd);
      cupsMarkOptions(ppd, dest->num_options, dest->options);

      // first check if this is turboprint drived printer, two solutions:
      // 1. ModelName constains TurboPrint
      // 2. zedoPrinterDriver exists
      ppd_attr_t *attr = ppdFindAttr(ppd, "ModelName", NULL);

      if (attr)
      {
        pinfo->is_turboprint = strstr(attr->value, "TurboPrint") != NULL;
      }

      // hardware margins

      attr = ppdFindAttr(ppd, "HWMargins", NULL);

      if (attr)
      {
        sscanf(attr->value, "%lf %lf %lf %lf",
               &pinfo->hw_margin_left, &pinfo->hw_margin_bottom,
               &pinfo->hw_margin_right, &pinfo->hw_margin_top);

        pinfo->hw_margin_left   = dt_pdf_point_to_mm (pinfo->hw_margin_left);
        pinfo->hw_margin_bottom = dt_pdf_point_to_mm (pinfo->hw_margin_bottom);
        pinfo->hw_margin_right  = dt_pdf_point_to_mm (pinfo->hw_margin_right);
        pinfo->hw_margin_top    = dt_pdf_point_to_mm (pinfo->hw_margin_top);
      }

      // default resolution

      attr = ppdFindAttr(ppd, "DefaultResolution", NULL);

      if (attr)
      {
        char *x = strstr(attr->value, "x");

        if (x)
          sscanf (x+1, "%ddpi", &pinfo->resolution);
        else
          sscanf (attr->value, "%ddpi", &pinfo->resolution);
      }
      else
        pinfo->resolution = 300;

      while(pinfo->resolution>360)
        pinfo->resolution /= 2.0;

      ppdClose(ppd);
      g_unlink(PPDFile);
    }
  }

  cupsFreeDests(num_dests, dests);
}
예제 #20
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  ppd_file_t	*ppd;			/* PPD file loaded from disk */
  int		status;			/* Status of tests (0 = success, 1 = fail) */
  int		conflicts;		/* Number of conflicts */
  char		*s;			/* String */
  char		buffer[8192];		/* String buffer */
  const char	*text,			/* Localized text */
		*val;			/* Option value */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  ppd_size_t	minsize,		/* Minimum size */
		maxsize,		/* Maximum size */
		*size;			/* Current size */
  ppd_attr_t	*attr;			/* Current attribute */
  _ppd_cache_t	*pc;			/* PPD cache */


  status = 0;

  if (argc == 1)
  {
   /*
    * Setup directories for locale stuff...
    */

    if (access("locale", 0))
    {
      mkdir("locale", 0777);
      mkdir("locale/fr", 0777);
      symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
      mkdir("locale/zh_TW", 0777);
      symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
    }

    putenv("LOCALEDIR=locale");
    putenv("SOFTWARE=CUPS");

   /*
    * Do tests with test.ppd...
    */

    fputs("ppdOpenFile(test.ppd): ", stdout);

    if ((ppd = _ppdOpenFile("test.ppd", _PPD_LOCALIZATION_ALL)) != NULL)
      puts("PASS");
    else
    {
      ppd_status_t	err;		/* Last error in file */
      int		line;		/* Line number in file */


      status ++;
      err = ppdLastError(&line);

      printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
    }

    fputs("ppdFindAttr(wildcard): ", stdout);
    if ((attr = ppdFindAttr(ppd, "cupsTest", NULL)) == NULL)
    {
      status ++;
      puts("FAIL (not found)");
    }
    else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
    {
      status ++;
      printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
    }
    else
      puts("PASS");

    fputs("ppdFindNextAttr(wildcard): ", stdout);
    if ((attr = ppdFindNextAttr(ppd, "cupsTest", NULL)) == NULL)
    {
      status ++;
      puts("FAIL (not found)");
    }
    else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Bar"))
    {
      status ++;
      printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
    }
    else
      puts("PASS");

    fputs("ppdFindAttr(Foo): ", stdout);
    if ((attr = ppdFindAttr(ppd, "cupsTest", "Foo")) == NULL)
    {
      status ++;
      puts("FAIL (not found)");
    }
    else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
    {
      status ++;
      printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
    }
    else
      puts("PASS");

    fputs("ppdFindNextAttr(Foo): ", stdout);
    if ((attr = ppdFindNextAttr(ppd, "cupsTest", "Foo")) != NULL)
    {
      status ++;
      printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
    }
    else
      puts("PASS");

    fputs("ppdMarkDefaults: ", stdout);
    ppdMarkDefaults(ppd);

    if ((conflicts = ppdConflicts(ppd)) == 0)
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d conflicts)\n", conflicts);
    }

    fputs("ppdEmitString (defaults): ", stdout);
    if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
	!strcmp(s, default_code))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
	     (int)strlen(default_code));

      if (s)
	puts(s);
    }

    if (s)
      free(s);

    fputs("ppdEmitString (custom size and string): ", stdout);
    ppdMarkOption(ppd, "PageSize", "Custom.400x500");
    ppdMarkOption(ppd, "StringOption", "{String1=\"value 1\" String2=value(2)}");

    if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
	!strcmp(s, custom_code))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
	     (int)strlen(custom_code));

      if (s)
	puts(s);
    }

    if (s)
      free(s);

   /*
    * Test constraints...
    */

    fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout);
    ppdMarkOption(ppd, "PageSize", "Letter");

    num_options = cupsGetConflicts(ppd, "InputSlot", "Envelope", &options);
    if (num_options != 2 ||
        (val = cupsGetOption("PageRegion", num_options, options)) == NULL ||
	_cups_strcasecmp(val, "Letter") ||
	(val = cupsGetOption("PageSize", num_options, options)) == NULL ||
	_cups_strcasecmp(val, "Letter"))
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
      puts("PASS");

    fputs("ppdConflicts(): ", stdout);
    ppdMarkOption(ppd, "InputSlot", "Envelope");

    if ((conflicts = ppdConflicts(ppd)) == 2)
      puts("PASS (2)");
    else
    {
      printf("FAIL (%d)\n", conflicts);
      status ++;
    }

    fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout);
    num_options = 0;
    options     = NULL;
    if (!cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options,
                             &options))
    {
      puts("FAIL (Unable to resolve)");
      status ++;
    }
    else if (num_options != 2 ||
             !cupsGetOption("PageSize", num_options, options))
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
      puts("PASS (Resolved by changing PageSize)");

    cupsFreeOptions(num_options, options);

    fputs("cupsResolveConflicts(No option/choice): ", stdout);
    num_options = 0;
    options     = NULL;
    if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
        num_options == 1 && !_cups_strcasecmp(options[0].name, "InputSlot") &&
	!_cups_strcasecmp(options[0].value, "Tray"))
      puts("PASS (Resolved by changing InputSlot)");
    else if (num_options > 0)
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
    {
      puts("FAIL (Unable to resolve)");
      status ++;
    }
    cupsFreeOptions(num_options, options);

    fputs("ppdInstallableConflict(): ", stdout);
    if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
        !ppdInstallableConflict(ppd, "Duplex", "None"))
      puts("PASS");
    else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
    {
      puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
      status ++;
    }
    else
    {
      puts("FAIL (Duplex=None conflicted)");
      status ++;
    }

   /*
    * ppdPageSizeLimits
    */

    fputs("ppdPageSizeLimits: ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 36 || minsize.length != 36 ||
          maxsize.width != 1080 || maxsize.length != 86400)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=36x36, max=1080x86400)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }

   /*
    * cupsMarkOptions with PWG and IPP size names.
    */

    fputs("cupsMarkOptions(media=iso-a4): ", stdout);
    num_options = cupsAddOption("media", "iso-a4", 0, &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "A4"))
    {
      printf("FAIL (%s)\n", size ? size->name : "unknown");
      status ++;
    }
    else
      puts("PASS");

    fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout);
    num_options = cupsAddOption("media", "na_letter_8.5x11in", 0, &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "Letter"))
    {
      printf("FAIL (%s)\n", size ? size->name : "unknown");
      status ++;
    }
    else
      puts("PASS");

    fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout);
    num_options = cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0,
                                &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "Letter.Fullbleed"))
    {
      printf("FAIL (%s)\n", size ? size->name : "unknown");
      status ++;
    }
    else
      puts("PASS");

    fputs("cupsMarkOptions(media=A4): ", stdout);
    num_options = cupsAddOption("media", "A4", 0, &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "A4"))
    {
      printf("FAIL (%s)\n", size ? size->name : "unknown");
      status ++;
    }
    else
      puts("PASS");

   /*
    * Custom sizes...
    */

    fputs("cupsMarkOptions(media=Custom.8x10in): ", stdout);
    num_options = cupsAddOption("media", "Custom.8x10in", 0, &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "Custom") ||
        size->width != 576 || size->length != 720)
    {
      printf("FAIL (%s - %gx%g)\n", size ? size->name : "unknown",
             size ? size->width : 0.0, size ? size->length : 0.0);
      status ++;
    }
    else
      puts("PASS");

   /*
    * Test localization...
    */

    fputs("ppdLocalizeIPPReason(text): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
        !strcmp(buffer, "Foo Reason"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer);
    }

    fputs("ppdLocalizeIPPReason(http): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) &&
        !strcmp(buffer, "http://foo/bar.html"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer);
    }

    fputs("ppdLocalizeIPPReason(help): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) &&
        !strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer);
    }

    fputs("ppdLocalizeIPPReason(file): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) &&
        !strcmp(buffer, "/help/foo/bar.html"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer);
    }

    putenv("LANG=fr");
    putenv("LC_ALL=fr");
    putenv("LC_CTYPE=fr");
    putenv("LC_MESSAGES=fr");

    fputs("ppdLocalizeIPPReason(fr text): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
        !strcmp(buffer, "La Long Foo Reason"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer);
    }

    putenv("LANG=zh_TW");
    putenv("LC_ALL=zh_TW");
    putenv("LC_CTYPE=zh_TW");
    putenv("LC_MESSAGES=zh_TW");

    fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
        !strcmp(buffer, "Number 1 Foo Reason"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
    }

   /*
    * cupsMarkerName localization...
    */

    putenv("LANG=en");
    putenv("LC_ALL=en");
    putenv("LC_CTYPE=en");
    putenv("LC_MESSAGES=en");

    fputs("ppdLocalizeMarkerName(bogus): ", stdout);

    if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
    {
      status ++;
      printf("FAIL (\"%s\" instead of NULL)\n", text);
    }
    else
      puts("PASS");

    fputs("ppdLocalizeMarkerName(cyan): ", stdout);

    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
        !strcmp(text, "Cyan Toner"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
             text ? text : "(null)");
    }

    putenv("LANG=fr");
    putenv("LC_ALL=fr");
    putenv("LC_CTYPE=fr");
    putenv("LC_MESSAGES=fr");

    fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
        !strcmp(text, "La Toner Cyan"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
             text ? text : "(null)");
    }

    putenv("LANG=zh_TW");
    putenv("LC_ALL=zh_TW");
    putenv("LC_CTYPE=zh_TW");
    putenv("LC_MESSAGES=zh_TW");

    fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
        !strcmp(text, "Number 1 Cyan Toner"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
             text ? text : "(null)");
    }

    ppdClose(ppd);

   /*
    * Test new constraints...
    */

    fputs("ppdOpenFile(test2.ppd): ", stdout);

    if ((ppd = ppdOpenFile("test2.ppd")) != NULL)
      puts("PASS");
    else
    {
      ppd_status_t	err;		/* Last error in file */
      int		line;		/* Line number in file */


      status ++;
      err = ppdLastError(&line);

      printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
    }

    fputs("ppdMarkDefaults: ", stdout);
    ppdMarkDefaults(ppd);

    if ((conflicts = ppdConflicts(ppd)) == 0)
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d conflicts)\n", conflicts);
    }

    fputs("ppdEmitString (defaults): ", stdout);
    if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
	!strcmp(s, default2_code))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
	     (int)strlen(default2_code));

      if (s)
	puts(s);
    }

    if (s)
      free(s);

    fputs("ppdConflicts(): ", stdout);
    ppdMarkOption(ppd, "PageSize", "Env10");
    ppdMarkOption(ppd, "InputSlot", "Envelope");
    ppdMarkOption(ppd, "Quality", "Photo");

    if ((conflicts = ppdConflicts(ppd)) == 1)
      puts("PASS (1)");
    else
    {
      printf("FAIL (%d)\n", conflicts);
      status ++;
    }

    fputs("cupsResolveConflicts(Quality=Photo): ", stdout);
    num_options = 0;
    options     = NULL;
    if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options,
                             &options))
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
      puts("PASS (Unable to resolve)");
    cupsFreeOptions(num_options, options);

    fputs("cupsResolveConflicts(No option/choice): ", stdout);
    num_options = 0;
    options     = NULL;
    if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
        num_options == 1 && !_cups_strcasecmp(options->name, "Quality") &&
	!_cups_strcasecmp(options->value, "Normal"))
      puts("PASS");
    else if (num_options > 0)
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
    {
      puts("FAIL (Unable to resolve!)");
      status ++;
    }
    cupsFreeOptions(num_options, options);

    fputs("cupsResolveConflicts(loop test): ", stdout);
    ppdMarkOption(ppd, "PageSize", "A4");
    ppdMarkOption(ppd, "InputSlot", "Tray");
    ppdMarkOption(ppd, "Quality", "Photo");
    num_options = 0;
    options     = NULL;
    if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options))
      puts("PASS");
    else if (num_options > 0)
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
    }
    else
      puts("FAIL (No conflicts!)");

    fputs("ppdInstallableConflict(): ", stdout);
    if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
        !ppdInstallableConflict(ppd, "Duplex", "None"))
      puts("PASS");
    else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
    {
      puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
      status ++;
    }
    else
    {
      puts("FAIL (Duplex=None conflicted)");
      status ++;
    }

   /*
    * ppdPageSizeLimits
    */

    ppdMarkDefaults(ppd);

    fputs("ppdPageSizeLimits(default): ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 36 || minsize.length != 36 ||
          maxsize.width != 1080 || maxsize.length != 86400)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=36x36, max=1080x86400)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }

    ppdMarkOption(ppd, "InputSlot", "Manual");

    fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 100 || minsize.length != 100 ||
          maxsize.width != 1000 || maxsize.length != 1000)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=100x100, max=1000x1000)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }

    ppdMarkOption(ppd, "Quality", "Photo");

    fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 200 || minsize.length != 200 ||
          maxsize.width != 1000 || maxsize.length != 1000)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=200x200, max=1000x1000)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }

    ppdMarkOption(ppd, "InputSlot", "Tray");

    fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 300 || minsize.length != 300 ||
          maxsize.width != 1080 || maxsize.length != 86400)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=300x300, max=1080x86400)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }
  }
  else
  {
    const char	*filename;		/* PPD filename */
    struct stat	fileinfo;		/* File information */


    if (!strncmp(argv[1], "-d", 2))
    {
      const char *printer;		/* Printer name */

      if (argv[1][2])
	printer = argv[1] + 2;
      else if (argv[2])
	printer = argv[2];
      else
      {
        puts("Usage: ./testppd -d printer");
	return (1);
      }

      filename = cupsGetPPD(printer);

      if (!filename)
      {
        printf("%s: %s\n", printer, cupsLastErrorString());
        return (1);
      }
    }
    else
      filename = argv[1];

    if (lstat(filename, &fileinfo))
    {
      printf("%s: %s\n", filename, strerror(errno));
      return (1);
    }

    if (S_ISLNK(fileinfo.st_mode))
    {
      char	realfile[1024];		/* Real file path */
      ssize_t	realsize;		/* Size of real file path */


      if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0)
        strlcpy(realfile, "Unknown", sizeof(realfile));
      else
        realfile[realsize] = '\0';

      if (stat(realfile, &fileinfo))
	printf("%s: symlink to \"%s\", %s\n", filename, realfile,
	       strerror(errno));
      else
	printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile,
	       (long)fileinfo.st_size);
    }
    else
      printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size);

    if ((ppd = ppdOpenFile(filename)) == NULL)
    {
      ppd_status_t	err;		/* Last error in file */
      int		line;		/* Line number in file */


      status ++;
      err = ppdLastError(&line);

      printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line);
    }
    else
    {
      int		j, k;		/* Looping vars */
      ppd_group_t	*group;		/* Option group */
      ppd_option_t	*option;	/* Option */
      ppd_coption_t	*coption;	/* Custom option */
      ppd_cparam_t	*cparam;	/* Custom parameter */
      ppd_const_t	*c;		/* UIConstraints */
      char		lang[255],	/* LANG environment variable */
			lc_all[255],	/* LC_ALL environment variable */
			lc_ctype[255],	/* LC_CTYPE environment variable */
			lc_messages[255];/* LC_MESSAGES environment variable */


      if (argc > 2)
      {
        snprintf(lang, sizeof(lang), "LANG=%s", argv[2]);
	putenv(lang);
        snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]);
	putenv(lc_all);
        snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]);
	putenv(lc_ctype);
        snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]);
	putenv(lc_messages);
      }

      ppdLocalize(ppd);
      ppdMarkDefaults(ppd);

      if (argc > 3)
      {
        text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer));
	printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3],
	       text ? text : "(null)");
	return (text == NULL);
      }

      for (i = ppd->num_groups, group = ppd->groups;
	   i > 0;
	   i --, group ++)
      {
	printf("%s (%s):\n", group->name, group->text);

	for (j = group->num_options, option = group->options;
	     j > 0;
	     j --, option ++)
	{
	  printf("    %s (%s):\n", option->keyword, option->text);

	  for (k = 0; k < option->num_choices; k ++)
	    printf("        - %s%s (%s)\n",
	           option->choices[k].marked ? "*" : "",
		   option->choices[k].choice, option->choices[k].text);

          if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL)
	  {
	    for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
	         cparam;
		 cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
            {
	      switch (cparam->type)
	      {
	        case PPD_CUSTOM_CURVE :
		    printf("              %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_curve,
			   cparam->maximum.custom_curve);
		    break;

	        case PPD_CUSTOM_INT :
		    printf("              %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_int,
			   cparam->maximum.custom_int);
		    break;

	        case PPD_CUSTOM_INVCURVE :
		    printf("              %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_invcurve,
			   cparam->maximum.custom_invcurve);
		    break;

	        case PPD_CUSTOM_PASSCODE :
		    printf("              %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_passcode,
			   cparam->maximum.custom_passcode);
		    break;

	        case PPD_CUSTOM_PASSWORD :
		    printf("              %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_password,
			   cparam->maximum.custom_password);
		    break;

	        case PPD_CUSTOM_POINTS :
		    printf("              %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_points,
			   cparam->maximum.custom_points);
		    break;

	        case PPD_CUSTOM_REAL :
		    printf("              %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_real,
			   cparam->maximum.custom_real);
		    break;

	        case PPD_CUSTOM_STRING :
		    printf("              %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_string,
			   cparam->maximum.custom_string);
		    break;
	      }
	    }
	  }
	}
      }

      puts("\nSizes:");
      for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
        printf("    %s = %gx%g, [%g %g %g %g]\n", size->name, size->width,
	       size->length, size->left, size->bottom, size->right, size->top);

      puts("\nConstraints:");

      for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
        printf("    *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1,
	       c->option2, c->choice2);
      if (ppd->num_consts == 0)
        puts("    NO CONSTRAINTS");

      puts("\nFilters:");

      for (i = 0; i < ppd->num_filters; i ++)
        printf("    %s\n", ppd->filters[i]);

      if (ppd->num_filters == 0)
        puts("    NO FILTERS");

      puts("\nAttributes:");

      for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs);
           attr;
	   attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs))
        printf("    *%s %s/%s: \"%s\"\n", attr->name, attr->spec,
	       attr->text, attr->value ? attr->value : "");

      puts("\nPPD Cache:");
      if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
        printf("    Unable to create: %s\n", cupsLastErrorString());
      else
      {
        _ppdCacheWriteFile(pc, "t.cache", NULL);
        puts("    Wrote t.cache.");
      }
    }

    if (!strncmp(argv[1], "-d", 2))
      unlink(filename);
  }

#ifdef __APPLE__
  if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
  {
    char	command[1024];		/* malloc_history command */

    snprintf(command, sizeof(command), "malloc_history %d -all_by_size",
	     getpid());
    fflush(stdout);
    system(command);
  }
#endif /* __APPLE__ */

  ppdClose(ppd);

  return (status);
}