示例#1
0
/*
 * Returns list of page sizes and imageable area.
 */
JNIEXPORT jfloatArray JNICALL
Java_sun_print_CUPSPrinter_getPageSizes(JNIEnv *env,
                                         jobject printObj,
                                         jstring printer)
{
    ppd_file_t *ppd;
    ppd_option_t *option;
    ppd_choice_t *choice;
    ppd_size_t *size;

    const char *name = (*env)->GetStringUTFChars(env, printer, NULL);
    const char *filename;
    int i;
    jobjectArray sizeArray = NULL;
    jfloat *dims;

    // NOTE: cupsGetPPD returns a pointer to a filename of a temporary file.
    // unlink() must be called to remove the file after using it.
    filename = cupsGetPPD(name);
    (*env)->ReleaseStringUTFChars(env, printer, name);
    if (filename == NULL) {
        return NULL;
    }
    if ((ppd = ppdOpenFile(filename)) == NULL) {
        unlink(filename);
        DPRINTF("unable to open PPD  %s\n", filename)
        return NULL;
    }
示例#2
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);
}
示例#3
0
bool CupsAddSmb::doExport()
{
	m_status = false;
	m_state = None;

	if (!TQFile::exists(m_datadir+"/drivers/ADOBEPS5.DLL") ||
	    !TQFile::exists(m_datadir+"/drivers/ADOBEPS4.DRV"))
	{
		showError(
			i18n("Some driver files are missing. You can get them on "
			     "<a href=\"http://www.adobe.com\">Adobe</a> web site. "
			     "See <a href=\"man:/cupsaddsmb\">cupsaddsmb</a> manual "
				 "page for more details (you need <a href=\"http://www.cups.org\">CUPS</a> "
				 "version 1.1.11 or higher)."));
		return false;
	}

	m_bar->setTotalSteps(18);
	m_bar->setProgress(0);
	//m_text->setText(i18n("<p>Preparing to upload driver to host <b>%1</b>").arg(m_servered->text()));
	m_textinfo->setText(i18n("Preparing to upload driver to host %1").arg(m_servered->text()));
	m_cancel->setEnabled(false);
	m_logined->setEnabled( false );
	m_servered->setEnabled( false );
	m_passwded->setEnabled( false );
	m_doit->setText(i18n("&Abort"));

	const char	*ppdfile;

	if ((ppdfile = cupsGetPPD(m_dest.local8Bit())) == NULL)
	{
		showError(i18n("The driver for printer <b>%1</b> could not be found.").arg(m_dest));
		return false;
	}

	m_actions.clear();
	m_actions << "mkdir" << "W32X86";
	m_actions << "put" << ppdfile << "W32X86/"+m_dest+".PPD";
	m_actions << "put" << m_datadir+"/drivers/ADOBEPS5.DLL" << "W32X86/ADOBEPS5.DLL";
	m_actions << "put" << m_datadir+"/drivers/ADOBEPSU.DLL" << "W32X86/ADOBEPSU.DLL";
	m_actions << "put" << m_datadir+"/drivers/ADOBEPSU.HLP" << "W32X86/ADOBEPSU.HLP";
	m_actions << "mkdir" << "WIN40";
	m_actions << "put" << ppdfile << "WIN40/"+m_dest+".PPD";
	m_actions << "put" << m_datadir+"/drivers/ADFONTS.MFM" << "WIN40/ADFONTS.MFM";
	m_actions << "put" << m_datadir+"/drivers/ADOBEPS4.DRV" << "WIN40/ADOBEPS4.DRV";
	m_actions << "put" << m_datadir+"/drivers/ADOBEPS4.HLP" << "WIN40/ADOBEPS4.HLP";
	m_actions << "put" << m_datadir+"/drivers/DEFPRTR2.PPD" << "WIN40/DEFPRTR2.PPD";
	m_actions << "put" << m_datadir+"/drivers/ICONLIB.DLL" << "WIN40/ICONLIB.DLL";
	m_actions << "put" << m_datadir+"/drivers/PSMON.DLL" << "WIN40/PSMON.DLL";
	m_actions << "quit";

	m_proc.clearArguments();
	m_proc << "smbclient" << TQString::fromLatin1("//")+m_servered->text()+"/print$";
	return startProcess();
}
示例#4
0
///////////////////////////////////////////////////////////////////////////////////////////
//
// CS     : PUBLIC gint getProductName(gchar *pDestName, gchar *pProductName)
// IN     : gchar *pDestName : Printer name.
// OUT    : gchar *pProductName : Product name. ( ModelName )
// RETURN : ID_ERR_NO_ERROR : No error.
//          ID_ERR_UNKNOWN_PRINTER : Getting product name failed.
//
PUBLIC gint getProductName(gchar *pDestName, gchar *pProductName)
{
/*** Parameters start ***/
	const gchar	*pPPDName = NULL;					// Pointer to PPD file name.
	ppd_file_t	*pPPD;								// Pointer to PPD file.
	gint		retVal = ID_ERR_UNKNOWN_PRINTER;	// Return value.
/*** Parameters start ***/

	// Get PPD file name.
	pPPDName = cupsGetPPD(pDestName);
	if (pPPDName != NULL) {
		if ((pPPD = ppdOpenFile(pPPDName)) != NULL) {
			if (strcmp(pPPD->manufacturer, STR_MANUFACTURER_NAME) == 0) {
				strncpy(pProductName, pPPD->modelname, strlen(pPPD->modelname));	// use modelname from 22th Jan.'03
				retVal = ID_ERR_NO_ERROR;
			}
			ppdClose(pPPD);
		}
		unlink(pPPDName);	// Tora 020418: You should remove the copy of the PPD file.
	}

	return(retVal);
}// End getProductName
示例#5
0
GList *dt_get_media_type(const dt_printer_info_t *printer)
{
  const char *printer_name = printer->name;
  GList *result = NULL;

  // check now PPD media type

  const char *PPDFile = cupsGetPPD(printer_name);
  ppd_file_t *ppd = ppdOpenFile(PPDFile);

  if (ppd)
  {
      ppd_option_t *opt = ppdFindOption(ppd, "MediaType");

      if (opt)
      {
        ppd_choice_t *choice = opt->choices;

        for (int k=0; k<opt->num_choices; k++)
        {
          dt_medium_info_t *media = (dt_medium_info_t*)malloc(sizeof(dt_medium_info_t));
          g_strlcpy(media->name, choice->choice, MAX_NAME);
          g_strlcpy(media->common_name, choice->text, MAX_NAME);
          result = g_list_append (result, media);

          dt_print(DT_DEBUG_PRINT, "[print] new media %2d (%s) (%s)\n", k, media->name, media->common_name);
          choice++;
        }
      }
  }

  ppdClose(ppd);
  g_unlink(PPDFile);

  return result;
}
示例#6
0
int CreatePPDOptions(cngplpData *data)
{
#ifndef _OPAL
	char *pWorkPPD = (char *)cupsGetPPD(data->curr_printer);
	if(pWorkPPD) {
		data->ppdfile = strdup(pWorkPPD);
		if (!data->ppdfile) {
			unlink(pWorkPPD);
			return -1;
		}
	}
#else
	data->ppdfile = strdup(data->curr_printer);
	if(data->ppdfile == NULL)
		return -1;
#endif

	memset(data->ppd_opt, 0, sizeof(PPDOptions));

	data->ppd_opt->startnum_value = 1;
	data->ppd_opt->dpicon_pictid = -1;
	data->ppd_opt->enable_finishflag = -1;
	data->ppd_opt->enable_inputflag = -1;
	data->ppd_opt->enable_qualitytype = -1;
	data->ppd_opt->offset_num = 1;
	data->ppd_opt->tab_shift = 12.7;
	data->ppd_opt->ins_tab_shift = 12.7;
	data->ppd_opt->adjust_trim_num = 0.0;
	data->ppd_opt->adjust_frtrim_num = 0.0;
	data->ppd_opt->adjust_tbtrim_num = 0.0;
	data->ppd_opt->pb_fin_fore_trim_num = 0.0;
	data->ppd_opt->pb_fin_topbtm_trim_num = 0.0;
	data->ppd_opt->stack_copies_num = 1;
	data->ppd_opt->saddle_press_adjust = 0;

	data->ppd_opt->items_list = (UIItemsList *)malloc(sizeof(UIItemsList));
	if(data->ppd_opt->items_list == NULL)
		return -1;

	memset(data->ppd_opt->items_list, 0, sizeof(UIItemsList));

	if((ParsePPD(data->ppd_opt, data->ppdfile)) < 0){
		return -1;
	}
	char *max_val = GetUIValue(data, kPPD_Items_CNUITrimValMax);
	char *min_val = GetUIValue(data, kPPD_Items_CNUITrimValMin);
	char *def_val = GetUIValue(data, kPPD_Items_CNUIAdjustTrimNumDefault);
	if(def_val == NULL || max_val == NULL || min_val == NULL){
		if(max_val != NULL)
			UpdateUIValue(data, kPPD_Items_CNUITrimValMax, "10.2");
		else
			AddUIValueList(data->ppd_opt, kPPD_Items_CNUITrimValMax, "10.2", 0);
		if(min_val != NULL)
			UpdateUIValue(data, kPPD_Items_CNUITrimValMin, "2.0");
		else
			AddUIValueList(data->ppd_opt, kPPD_Items_CNUITrimValMin, "2.0", 0);
		data->ppd_opt->adjust_trim_num = 2.0;
		data->ppd_opt->adjust_frtrim_num = 2.0;
}
	char *ptbValMax = GetUIValue(data,kPPD_Items_CNUITopBottomTrimValMax);
	char *ptbValMin = GetUIValue(data,kPPD_Items_CNUITopBottomTrimValMin);
	char *ptbValDef = GetUIValue(data,kPPD_Items_CNUIAdjustTopBottomTrimNumDefault);
	if(ptbValDef == NULL || ptbValMax ==NULL || ptbValMin ==NULL){
		if(ptbValMax != NULL)
			UpdateUIValue(data,kPPD_Items_CNUITopBottomTrimValMax,"15.0");
		else
			AddUIValueList(data->ppd_opt,kPPD_Items_CNUITopBottomTrimValMax,"15.0",0);
		if(ptbValMin != NULL)
			UpdateUIValue(data,kPPD_Items_CNUITopBottomTrimValMin,"2.0");
		else
			AddUIValueList(data->ppd_opt,kPPD_Items_CNUITopBottomTrimValMin,"2.0",0);
		data->ppd_opt->adjust_tbtrim_num = 2.0;
	}

	if(data->ppdfile)
		InitUIDisable(data);

	if(data->ppdfile)
		SetDefaultOptIfAllOptConflict(data);

	return 0;
}
示例#7
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;
}
示例#8
0
bool PrinterUtil::getPrinterMarginValues(const QString& printerName, const QString& pageSize, double& ptsTopMargin, double& ptsBottomMargin, double& ptsLeftMargin, double& ptsRightMargin)
{
	bool retVal=false;
#if defined(HAVE_CUPS)
	const char *filename; // tmp PPD filename
	filename=cupsGetPPD(printerName.toLocal8Bit().constData());
	if (filename!=NULL)
	{
		ppd_file_t *ppd; // PPD data
		ppd = ppdOpenFile(filename);
		if (ppd!=NULL)
		{
			ppd_size_t *size; // page size data, null if printer doesnt support selected size
			size = ppdPageSize(ppd, pageSize.toLocal8Bit().constData());
			if (size!=NULL)
			{
				//Store in pts for returning via getNewPrinterMargins in pts
				retVal=true;
				ptsTopMargin=size->length-size->top;
				ptsBottomMargin=size->bottom;
				ptsLeftMargin=size->left;
				ptsRightMargin=size->width-size->right;
			}
			ppdClose(ppd);
		}
	}
#elif defined(_WIN32)
	DWORD nPaper;
	DWORD nPaperNames;
	typedef WCHAR wchar64[64];
	nPaper = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERS, NULL, NULL );
	nPaperNames = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERNAMES, NULL, NULL );
	if ( (nPaper > 0) && (nPaperNames > 0) && (nPaper == nPaperNames) )
	{
		int paperIndex = -1;
		DWORD   *papers = new DWORD[nPaper];
		wchar64 *paperNames = new wchar64[nPaperNames];
		DWORD s1 = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERS, (LPWSTR) papers, NULL );
		DWORD s2 = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERNAMES, (LPWSTR) paperNames, NULL );
		for ( uint i = 0; i < nPaperNames; i++ )
		{
			if ( pageSize == QString::fromUtf16((const ushort*) paperNames[i]) )
			{
				paperIndex = i;
				break;
			}
		}
		if ( paperIndex >= 0 )
		{
			Qt::HANDLE handle = NULL;
			if( OpenPrinterW( (LPWSTR) printerName.utf16(), &handle, NULL ) )
			{
				// Retrieve DEVMODE structure for selected device
				uint size = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), NULL, NULL, 0);
				QByteArray devModeW(size, 0);
				DEVMODEW* devMode = (DEVMODEW*) devModeW.data();
				DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), devMode, NULL, DM_OUT_BUFFER);
				ClosePrinter( handle );
				// Set paper size
				devMode->dmPaperSize = papers[paperIndex];
				// Create device context
				HDC printerDC = CreateDCW( NULL, (LPWSTR) printerName.utf16(), NULL, devMode );
				if( printerDC )
				{
					retVal = true;
					int logPixelsX = GetDeviceCaps( printerDC, LOGPIXELSX );
					int logPixelsY = GetDeviceCaps( printerDC, LOGPIXELSY );
					int physicalOffsetX = GetDeviceCaps( printerDC, PHYSICALOFFSETX );
					int physicalOffsetY = GetDeviceCaps( printerDC, PHYSICALOFFSETY );
					ptsLeftMargin = ptsRightMargin = ( physicalOffsetX / (double) logPixelsX * 72 );
					ptsTopMargin = ptsBottomMargin = ( physicalOffsetY / (double) logPixelsY * 72 );
					DeleteDC(printerDC);
				}
			}
		}
		delete[] papers;
		delete[] paperNames;
	}
#endif
	return retVal;
}
示例#9
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() ) );
}
示例#10
0
int				/* O - Exit status */
main(int  argc,			/* I - Number of command-line arguments */
     char *argv[])		/* I - Command-line arguments */
{
  int		i, j, k, m;	/* Looping vars */
  const char	*filename;	/* File to load */
  FILE          *ppdfile;

  // Temporary file name (for reading from stdin)
  char          tmpfile[19] = "/tmp/lphelp.XXXXXX";
  const int     blocksize = 1024;
  char          buffer[blocksize];
  int           bytesread;

  // variables for parsing PPD file for usual options (boolean, enumerated)
  ppd_file_t	*ppd;		/* PPD file record */
  ppd_size_t	*size;		/* Size record */
  ppd_group_t	*group;		/* UI group */
  ppd_option_t	*option;	/* Standard UI option */
  ppd_choice_t	*choice;	/* Standard UI option choice */
  static char	*uis[] = { "BOOLEAN", "PICKONE", "PICKMANY" };
  static char	*sections[] = { "ANY", "DOCUMENT", "EXIT",
                                "JCL", "PAGE", "PROLOG" };

  // variables for parsing CUPS-O-MATIC info for numerical options (float, int)
  char line[1024], /* buffer for reading PPD file line by
                      line to search numerical options */
       item[1024], /* item to be defined (left of "=>") */
       value[1024], /* value for item (right of "=>") */
       argname[1024], /* name of the current argument */
       comment[1024]; /* human-readable argument name */
  const char *line_contents; /* contents of line */
  const char *scan; /* pointer scanning the line */
  char *writepointer;
  double min, max, defvalue; /* Range of numerical 
                                CUPS-O-MATIC option */
  int opttype; /* 0 = other, 1 = int, 2 = float */
  int openbrackets; /* How many curled brackets are open? */
  int inquotes; /* are we in quotes now? */
  int inargspart; /* are we in the arguments part now? */
       
 /*
  * Display PPD files for each file listed on the command-line...
  */

  if (argc == 1) {
    fputs("Usage: lphelp <filename1>.ppd [<filename2>.ppd ...]\n       lphelp <printername1> [<printername2> ...]\n       lphelp -\n", stderr);
      return (1);
  }

  for (i = 1; i < argc; i ++) {
    if ((strstr(argv[i], ".ppd")) || (strstr(argv[i], "-")))
      filename = argv[i];
    else
      filename = cupsGetPPD(argv[i]);
    if (strcmp(filename,"-") == 0) {
      if ((ppdfile = fdopen(mkstemp(tmpfile), "w")) == NULL) {
	fprintf(stderr, "Unable to generate temporary file!\n");
      }
      while ((bytesread = fread(buffer, 1, blocksize, stdin)) > 0) {
	fwrite(buffer, 1, bytesread, ppdfile);
      }
      fclose(ppdfile);
      filename = tmpfile;
    }
    if ((ppd = ppdOpenFile(filename)) == NULL) {
      fprintf(stderr, "Unable to open \'%s\' as a PPD file!\n", filename);
      continue;
    }

    printf("==============================================================================\n\n");
    printf("%s\n\n", ppd->modelname);
    printf("==============================================================================\n\n");
    printf("   %s printer\n\n", ppd->color_device ? "Colour" : "Black & white");
    printf("   Printer-specific options\n");
    printf("   ------------------------\n\n");
    printf("   Besides the options described in the CUPS software users manual\n"); 
    printf("   (http://localhost:631/sum.html) you can use also the following options\n");
    printf("   when you print on this printer with the \"lp\" or \"lpr\" command (a choice\n");
    printf("   with the \"default\" mark represents the behaviour of the printer when the\n");
    printf("   appropriate option is not given on the command line):\n\n");

    for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) {
      for (k = 0, option = group->options; k < group->num_options;
           k ++, option ++) {
        if (strcmp(option->keyword, "PageRegion") != 0) {
          if ((strcmp(uis[option->ui],"BOOLEAN") == 0) || 
              (strcmp(uis[option->ui],"PICKONE") == 0)) {  
	    printf("   %s:  -o %s=<choice>\n\n",
	           option->text, option->keyword);
            printf("      <choice> can be one of the following:\n\n");
          } else {
	    printf("   %s:  -o %s=<choice1>,<choice2>,...\n\n",
	           option->text, option->keyword);
            printf("      <choice1>, <choice2>, and so on can be out of the following:\n\n");
          }
          if (strcmp(option->keyword, "PageSize") == 0) {
            for (m = option->num_choices, choice = option->choices;
	         m > 0;
	         m --, choice ++) {
	      size = ppdPageSize(ppd, choice->choice);

	      if (size == NULL)
	        printf("      %s  (%s, size unknown", choice->choice, choice->text);
              else
	        printf("      %s  (%s, size: %.2fx%.2fin", choice->choice,
	               choice->text, size->width / 72.0, size->length / 72.0);
              if (strcmp(option->defchoice, choice->choice) == 0)
	        puts(", default)");
	      else
	        puts(")");
            }
	  } else {
	    for (m = option->num_choices, choice = option->choices;
	         m > 0;
	         m --, choice ++) {
	      printf("      %s  (%s", choice->choice, choice->text);
              if (strcmp(option->defchoice, choice->choice) == 0)
	        puts(", default)");
	      else
	        puts(")");
	    }
          }
          printf("\n");
        }
      }
    }
    ppdClose(ppd);

    // Search for numerical options of CUPS-O-MATIC
    if ((ppdfile = fopen(filename,"r")) == NULL) {
      fprintf(stderr, "Unable to open \'%s\' as a PPD file!\n", filename);
      continue;
    }
    // Reset all variables
    opttype = 0;
    min = 0.0; max = 0.0; defvalue = 0.0;
    openbrackets = 0;
    inquotes = 0;
    writepointer = item;
    inargspart = 0;
    // Read the PPD file again, line by line.
    while (fgets(line,sizeof(line),ppdfile)) {
      // evaluate only lines with CUPS-O-MATIC info
      if (line_contents = strstr(line,"*% COMDATA #")) {
        line_contents += 12; // Go to the text after 
	                     // "*% COMDATA #"
        for (scan = line_contents; 
             (*scan != '\n') && (*scan != '\0');
	     scan ++) {
          switch(*scan) {
	    case '[': // open square bracket
	    case '{': // open curled bracket
              if (!inquotes) {
                openbrackets ++;
                // we are on the left hand side now
                *writepointer = '\0';
                writepointer = item;
                // in which type of block are we now?
                if ((openbrackets == 2) && 
                    (strncasecmp(item,"args",4) == 0)) {
                  // we are entering the arguments section now
                  inargspart = 1;
		}
                if ((openbrackets == 3) && 
                    (inargspart == 1)) {
                  // new argument, get its name
                  strcpy(argname,item);
		}
                // item already evaluated now
                item[0] = '\0';
              } else {*writepointer = *scan; writepointer ++;}
              break;
	    case ',': // end of logical line
	    case ']': // close square bracket
	    case '}': // close curled bracket
              if (!inquotes) {
                // right hand side completed, go to left hand side
                *writepointer = '\0';
                writepointer = item;
                // evaluate logical line
                if (item[0]) {
                  // Machine-readable argument name
                  if ((openbrackets == 3) &&
                      (inargspart == 1) &&
                      (strcasecmp(item,"name") == 0)) {
                    strcpy(argname,value);
		  }
                  // Human-readable argument name
                  if ((openbrackets == 3) &&
                      (inargspart == 1) &&
                      (strcasecmp(item,"comment") == 0)) {
                    strcpy(comment,value);
		  }
                  // argument type
                  if ((openbrackets == 3) &&
                      (inargspart == 1) &&
                      (strcasecmp(item,"type") == 0)) {
                    if (strcasecmp(value,"int") == 0) opttype = 1;
                    if (strcasecmp(value,"float") == 0) opttype = 2;
		  }
                  // minimum value
                  if ((openbrackets == 3) &&
                      (inargspart == 1) &&
                      (strcasecmp(item,"min") == 0)) {
                    min = atof(value);
		  }
                  // maximum value
                  if ((openbrackets == 3) &&
                      (inargspart == 1) &&
                      (strcasecmp(item,"max") == 0)) {
                    max = atof(value);
		  }
                  // default value
                  if ((openbrackets == 3) &&
                      (inargspart == 1) &&
                      (strcasecmp(item,"default") == 0)) {
                    defvalue = atof(value);
		  }
                  // item already evaluated now
                  item[0] = '\0';
                }
                // close bracket
                if ((*scan == '}') || (*scan == ']')) {
                  // which block did we complete now?
                  if ((openbrackets == 2) && 
                      (inargspart == 1)) {
                    // We are leaving the arguments part now
                    inargspart = 0;
                  }
                  if ((openbrackets == 3) && 
                      (inargspart == 1)) {
                    // The current option is completely parsed
                    // Is the option a valid numerical option?
                    if ((opttype > 0) &&
                        (min != max) &&
                        (argname[0])) {
                      // Correct the default value, if necessary
                      if (min < max) {
                        if (defvalue < min) defvalue = min;
                        if (defvalue > max) defvalue = max;
		      } else {
                        if (defvalue < max) defvalue = max;
                        if (defvalue > min) defvalue = min;
                      }
                      // Show the found argument
	              printf("   %s:  -o %s=<value>\n\n",
	                comment, argname);
                      if (opttype == 1) {
                        printf(
                          "      <value> must be an integer number in the range %d..%d\n",
                          (int)(min),(int)(max));
                        printf(
			  "      The default value is %d\n\n",
                          (int)(defvalue));
		      } else {
                        printf(
                          "      <value> must be a decimal number in the range %.2f..%.2f\n",
                          min,max);
                        printf(
			  "      The default value is %.2f\n\n",
                          defvalue);
                      }
                    }
                    // reset the values
                    argname[0] = '\0';
                    opttype = 0;
                    min = 0.0; max = 0.0; defvalue = 0.0;
                  }
                  openbrackets --;
                }
              } else {*writepointer = *scan; writepointer ++;}
              break;
	    case '\'': // quote
              if (!inquotes) { // open quote pair
                inquotes = 1;
	      } else { // close quote pair
                inquotes = 0;
              }
              break;
	    case '=': // "=>"
              if ((!inquotes) && (*(scan + 1) == '>')) {
                scan ++;
                // left hand side completed, go to right hand side
                *writepointer = '\0';
                writepointer = value;
              } else {*writepointer = *scan; writepointer ++;}
              break;
	    case ' ':  // white space
	    case '\t':
              if (!inquotes) {
                // ignore white space outside quotes
              } else {*writepointer = *scan; writepointer ++;}
              break;
	    default:
              // write all other characters
              *writepointer = *scan; writepointer ++;
              break;
          } 
        }
        inquotes = 0; // quote pairs cannot enclose more
	              // than one line
      }
    }
    fclose(ppdfile);
    printf("\n\n\n");
  }

  if (!(strstr(tmpfile, "XXXXXX"))) {
    unlink(tmpfile);
  }

  return (0);
}
示例#11
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);
}
示例#12
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;
}
示例#13
0
/*
 * Returns list of media: pages + trays
 */
JNIEXPORT jobjectArray JNICALL
Java_sun_print_CUPSPrinter_getMedia(JNIEnv *env,
                                         jobject printObj,
                                         jstring printer)
{
    ppd_file_t *ppd;
    ppd_option_t *optionTray, *optionPage;
    ppd_choice_t *choice;
    const char *name;
    const char *filename;
    int i, nTrays=0, nPages=0, nTotal=0;
    jstring utf_str;
    jclass cls;
    jobjectArray nameArray = NULL;

    name = (*env)->GetStringUTFChars(env, printer, NULL);
    if (name == NULL) {
        return NULL;
    }

    // NOTE: cupsGetPPD returns a pointer to a filename of a temporary file.
    // unlink() must be caled to remove the file when finished using it.
    filename = cupsGetPPD(name);
    (*env)->ReleaseStringUTFChars(env, printer, name);

    cls = (*env)->FindClass(env, "java/lang/String");

    if (filename == NULL) {
        return NULL;
    }

    if ((ppd = ppdOpenFile(filename)) == NULL) {
        unlink(filename);
        DPRINTF("CUPSfuncs::unable to open PPD  %s\n", filename);
        return NULL;
    }

    optionPage = ppdFindOption(ppd, "PageSize");
    if (optionPage != NULL) {
        nPages = optionPage->num_choices;
    }

    optionTray = ppdFindOption(ppd, "InputSlot");
    if (optionTray != NULL) {
        nTrays = optionTray->num_choices;
    }

    if ((nTotal = (nPages+nTrays) *2) > 0) {
        nameArray = (*env)->NewObjectArray(env, nTotal, cls, NULL);
        if (nameArray == NULL) {
            unlink(filename);
            ppdClose(ppd);
            DPRINTF("CUPSfuncs::bad alloc new array\n", "")
            JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
            return NULL;
        }

        for (i = 0; optionPage!=NULL && i<nPages; i++) {
            choice = (optionPage->choices)+i;
            utf_str = JNU_NewStringPlatform(env, choice->text);
            if (utf_str == NULL) {
                unlink(filename);
                ppdClose(ppd);
                DPRINTF("CUPSfuncs::bad alloc new string ->text\n", "")
                JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
                return NULL;
            }
            (*env)->SetObjectArrayElement(env, nameArray, i*2, utf_str);
            (*env)->DeleteLocalRef(env, utf_str);
            utf_str = JNU_NewStringPlatform(env, choice->choice);
            if (utf_str == NULL) {
                unlink(filename);
                ppdClose(ppd);
                DPRINTF("CUPSfuncs::bad alloc new string ->choice\n", "")
                JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
                return NULL;
            }
            (*env)->SetObjectArrayElement(env, nameArray, i*2+1, utf_str);
            (*env)->DeleteLocalRef(env, utf_str);
        }

        for (i = 0; optionTray!=NULL && i<nTrays; i++) {
            choice = (optionTray->choices)+i;
            utf_str = JNU_NewStringPlatform(env, choice->text);
            if (utf_str == NULL) {
                unlink(filename);
                ppdClose(ppd);
                DPRINTF("CUPSfuncs::bad alloc new string text\n", "")
                JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
                return NULL;
            }
            (*env)->SetObjectArrayElement(env, nameArray,
                                          (nPages+i)*2, utf_str);
            (*env)->DeleteLocalRef(env, utf_str);
            utf_str = JNU_NewStringPlatform(env, choice->choice);
            if (utf_str == NULL) {
                unlink(filename);
                ppdClose(ppd);
                DPRINTF("CUPSfuncs::bad alloc new string choice\n", "")
                JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
                return NULL;
            }
            (*env)->SetObjectArrayElement(env, nameArray,
                                          (nPages+i)*2+1, utf_str);
            (*env)->DeleteLocalRef(env, utf_str);
        }
    }
    ppdClose(ppd);
    unlink(filename);
    return nameArray;
}
示例#14
0
static PrinterInfo* GetPrinterInfo(const char* printer_name)
{
	FILE *fp = NULL;
	char buff[MAXWORDSIZE], *ptr = NULL, *tmp = NULL;
	char* lib_name = NULL, *lib_version = NULL;
	int lib_len = 0;
	gboolean find_lang = FALSE;
	const char* ppd_file = NULL;
	int printer_type = PRINTER_TYPE_OTHER;

	ppd_file = cupsGetPPD(printer_name);
	if(NULL == ppd_file){
		return NULL;
	}
	fp = fopen(ppd_file, "r");
	if(NULL == fp){
		return NULL;
	}else{
		while((fgets(buff, MAXWORDSIZE, fp)) != NULL){
			ptr = FillUp(buff);
			tmp = ChkMainKey(ptr, PRINT_LANG, strlen(PRINT_LANG));
			if(tmp != NULL){
				if(strstr(tmp, "LIPS4") != NULL){
					printer_type = PRINTER_TYPE_LIPS;
				}else if(strstr(tmp, "PS3") != NULL){
					printer_type = PRINTER_TYPE_PS;
				}else if(strstr(tmp, "UFR2") != NULL){
					printer_type = PRINTER_TYPE_UFR2;
				}else if(strstr(tmp, "CAPT") != NULL){
					printer_type = PRINTER_TYPE_CAPT;
				}
				find_lang = TRUE;
			}else{
				tmp = ChkMainKey(ptr, PRINT_LIB_NAME, strlen(PRINT_LIB_NAME));
				if(tmp != NULL){
					SetLibInfo(tmp, &lib_name);
				}else{
					tmp = ChkMainKey(ptr, PRINT_LIB_NAME_VER, strlen(PRINT_LIB_NAME_VER));
					if(tmp != NULL){
						SetLibInfo(tmp, &lib_version);
					}
				}
			}
			if((TRUE == find_lang) && (lib_name != NULL) && (lib_version != NULL)){
				break;
			}
		}
	}
	fclose(fp);
	unlink(ppd_file);
	if(NULL == lib_name || NULL == lib_version){
		if(lib_name != NULL){
			free(lib_name);
			lib_name = NULL;
		}
		if(lib_version != NULL){
			free(lib_version);
			lib_version = NULL;
		}
		return NULL;
	}
	PrinterInfo* info = (PrinterInfo*)malloc(sizeof(PrinterInfo));
	if(NULL == info){
		if(lib_name != NULL){
			free(lib_name);
			lib_name = NULL;
		}
		if(lib_version != NULL){
			free(lib_version);
			lib_version = NULL;
		}
		return NULL;
	}
	memset(info, 0, sizeof(PrinterInfo));
	info->name = strdup(printer_name);
	lib_len = strlen(LIB_PREFIX)+ strlen(lib_name) + strlen(LIB_SUFFIX) + strlen(SEPERATOR) + strlen(lib_version) + 1;
	info->lib = (char*)malloc(lib_len);
	memset(info->lib, 0, lib_len);
	strcat(info->lib, LIB_PREFIX);
	strcat(info->lib, lib_name);
	strcat(info->lib, LIB_SUFFIX);
	strcat(info->lib, SEPERATOR);
	strcat(info->lib, lib_version);
	free(lib_version);
	free(lib_name);
	info->type = printer_type;
	return info;
}
示例#15
0
文件: testcups.c 项目: jelmer/cups
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		status = 0,		/* Exit status */
		i,			/* Looping var */
		num_dests;		/* Number of destinations */
  cups_dest_t	*dests,			/* Destinations */
		*dest,			/* Current destination */
		*named_dest;		/* Current named destination */
  const char	*ppdfile;		/* PPD file */
  ppd_file_t	*ppd;			/* PPD file data */
  int		num_jobs;		/* Number of jobs for queue */
  cups_job_t	*jobs;			/* Jobs for queue */


  if (argc > 1)
  {
    if (!strcmp(argv[1], "enum"))
    {
      cups_ptype_t	mask = CUPS_PRINTER_LOCAL,
					/* Printer type mask */
			type = CUPS_PRINTER_LOCAL;
					/* Printer type */
      int		msec = 0;	/* Timeout in milliseconds */


      for (i = 2; i < argc; i ++)
        if (isdigit(argv[i][0] & 255) || argv[i][0] == '.')
          msec = (int)(atof(argv[i]) * 1000);
        else if (!_cups_strcasecmp(argv[i], "bw"))
        {
          mask |= CUPS_PRINTER_BW;
          type |= CUPS_PRINTER_BW;
        }
        else if (!_cups_strcasecmp(argv[i], "color"))
        {
          mask |= CUPS_PRINTER_COLOR;
          type |= CUPS_PRINTER_COLOR;
        }
        else if (!_cups_strcasecmp(argv[i], "mono"))
        {
          mask |= CUPS_PRINTER_COLOR;
        }
        else if (!_cups_strcasecmp(argv[i], "duplex"))
        {
          mask |= CUPS_PRINTER_DUPLEX;
          type |= CUPS_PRINTER_DUPLEX;
        }
        else if (!_cups_strcasecmp(argv[i], "simplex"))
        {
          mask |= CUPS_PRINTER_DUPLEX;
        }
        else if (!_cups_strcasecmp(argv[i], "staple"))
        {
          mask |= CUPS_PRINTER_STAPLE;
          type |= CUPS_PRINTER_STAPLE;
        }
        else if (!_cups_strcasecmp(argv[i], "copies"))
        {
          mask |= CUPS_PRINTER_COPIES;
          type |= CUPS_PRINTER_COPIES;
        }
        else if (!_cups_strcasecmp(argv[i], "collate"))
        {
          mask |= CUPS_PRINTER_COLLATE;
          type |= CUPS_PRINTER_COLLATE;
        }
        else if (!_cups_strcasecmp(argv[i], "punch"))
        {
          mask |= CUPS_PRINTER_PUNCH;
          type |= CUPS_PRINTER_PUNCH;
        }
        else if (!_cups_strcasecmp(argv[i], "cover"))
        {
          mask |= CUPS_PRINTER_COVER;
          type |= CUPS_PRINTER_COVER;
        }
        else if (!_cups_strcasecmp(argv[i], "bind"))
        {
          mask |= CUPS_PRINTER_BIND;
          type |= CUPS_PRINTER_BIND;
        }
        else if (!_cups_strcasecmp(argv[i], "sort"))
        {
          mask |= CUPS_PRINTER_SORT;
          type |= CUPS_PRINTER_SORT;
        }
        else if (!_cups_strcasecmp(argv[i], "mfp"))
        {
          mask |= CUPS_PRINTER_MFP;
          type |= CUPS_PRINTER_MFP;
        }
        else if (!_cups_strcasecmp(argv[i], "printer"))
        {
          mask |= CUPS_PRINTER_MFP;
        }
        else if (!_cups_strcasecmp(argv[i], "large"))
        {
          mask |= CUPS_PRINTER_LARGE;
          type |= CUPS_PRINTER_LARGE;
        }
        else if (!_cups_strcasecmp(argv[i], "medium"))
        {
          mask |= CUPS_PRINTER_MEDIUM;
          type |= CUPS_PRINTER_MEDIUM;
        }
        else if (!_cups_strcasecmp(argv[i], "small"))
        {
          mask |= CUPS_PRINTER_SMALL;
          type |= CUPS_PRINTER_SMALL;
        }
        else
          fprintf(stderr, "Unknown argument \"%s\" ignored...\n", argv[i]);

      cupsEnumDests(CUPS_DEST_FLAGS_NONE, msec, NULL, type, mask, enum_cb, NULL);
    }
    else if (!strcmp(argv[1], "password"))
    {
      const char *pass = cupsGetPassword("Password:"******"Password entered: %s\n", pass);
      else
	puts("No password entered.");
    }
    else if (!strcmp(argv[1], "ppd") && argc == 3)
    {
     /*
      * ./testcups ppd printer
      */

      http_status_t	http_status;	/* Status */
      char		buffer[1024];	/* PPD filename */
      time_t		modtime = 0;	/* Last modified */

      if ((http_status = cupsGetPPD3(CUPS_HTTP_DEFAULT, argv[2], &modtime,
                                     buffer, sizeof(buffer))) != HTTP_STATUS_OK)
        printf("Unable to get PPD: %d (%s)\n", (int)http_status,
               cupsLastErrorString());
      else
        puts(buffer);
    }
    else if (!strcmp(argv[1], "print") && argc == 5)
    {
     /*
      * ./testcups print printer file interval
      */

      int		interval,	/* Interval between writes */
			job_id;		/* Job ID */
      cups_file_t	*fp;		/* Print file */
      char		buffer[16384];	/* Read/write buffer */
      ssize_t		bytes;		/* Bytes read/written */

      if ((fp = cupsFileOpen(argv[3], "r")) == NULL)
      {
	printf("Unable to open \"%s\": %s\n", argv[2], strerror(errno));
	return (1);
      }

      if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, argv[2], "testcups", 0,
				  NULL)) <= 0)
      {
	printf("Unable to create print job on %s: %s\n", argv[1],
	       cupsLastErrorString());
	return (1);
      }

      interval = atoi(argv[4]);

      if (cupsStartDocument(CUPS_HTTP_DEFAULT, argv[1], job_id, argv[2],
			    CUPS_FORMAT_AUTO, 1) != HTTP_STATUS_CONTINUE)
      {
	puts("Unable to start document!");
	return (1);
      }

      while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
      {
	printf("Writing %d bytes...\n", (int)bytes);

	if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer,
				 bytes) != HTTP_STATUS_CONTINUE)
	{
	  puts("Unable to write bytes!");
	  return (1);
	}

        if (interval > 0)
	  sleep(interval);
      }

      cupsFileClose(fp);

      if (cupsFinishDocument(CUPS_HTTP_DEFAULT,
                             argv[1]) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
      {
	puts("Unable to finish document!");
	return (1);
      }
    }
    else
    {
      puts("Usage:");
      puts("");
      puts("Run basic unit tests:");
      puts("");
      puts("    ./testcups");
      puts("");
      puts("Enumerate printers (for N seconds, -1 for indefinitely):");
      puts("");
      puts("    ./testcups enum [seconds]");
      puts("");
      puts("Ask for a password:"******"");
      puts("    ./testcups password");
      puts("");
      puts("Get the PPD file:");
      puts("");
      puts("    ./testcups ppd printer");
      puts("");
      puts("Print a file (interval controls delay between buffers in seconds):");
      puts("");
      puts("    ./testcups print printer file interval");
      return (1);
    }

    return (0);
  }

 /*
  * cupsGetDests()
  */

  fputs("cupsGetDests: ", stdout);
  fflush(stdout);

  num_dests = cupsGetDests(&dests);

  if (num_dests == 0)
  {
    puts("FAIL");
    return (1);
  }
  else
  {
    printf("PASS (%d dests)\n", num_dests);

    for (i = num_dests, dest = dests; i > 0; i --, dest ++)
    {
      printf("    %s", dest->name);

      if (dest->instance)
        printf("    /%s", dest->instance);

      if (dest->is_default)
        puts(" ***DEFAULT***");
      else
        putchar('\n');
    }
  }

 /*
  * cupsGetDest(NULL)
  */

  fputs("cupsGetDest(NULL): ", stdout);
  fflush(stdout);

  if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
  {
    for (i = num_dests, dest = dests; i > 0; i --, dest ++)
      if (dest->is_default)
        break;

    if (i)
    {
      status = 1;
      puts("FAIL");
    }
    else
      puts("PASS (no default)");

    dest = NULL;
  }
  else
    printf("PASS (%s)\n", dest->name);

 /*
  * cupsGetNamedDest(NULL, NULL, NULL)
  */

  fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout);
  fflush(stdout);

  if ((named_dest = cupsGetNamedDest(NULL, NULL, NULL)) == NULL ||
      !dests_equal(dest, named_dest))
  {
    if (!dest)
      puts("PASS (no default)");
    else if (named_dest)
    {
      puts("FAIL (different values)");
      show_diffs(dest, named_dest);
      status = 1;
    }
    else
    {
      puts("FAIL (no default)");
      status = 1;
    }
  }
  else
    printf("PASS (%s)\n", named_dest->name);

  if (named_dest)
    cupsFreeDests(1, named_dest);

 /*
  * cupsGetDest(printer)
  */

  printf("cupsGetDest(\"%s\"): ", dests[num_dests / 2].name);
  fflush(stdout);

  if ((dest = cupsGetDest(dests[num_dests / 2].name, NULL, num_dests,
                          dests)) == NULL)
  {
    puts("FAIL");
    return (1);
  }
  else
    puts("PASS");

 /*
  * cupsGetNamedDest(NULL, printer, instance)
  */

  printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest->name,
         dest->instance ? dest->instance : "(null)");
  fflush(stdout);

  if ((named_dest = cupsGetNamedDest(NULL, dest->name,
                                     dest->instance)) == NULL ||
      !dests_equal(dest, named_dest))
  {
    if (named_dest)
    {
      puts("FAIL (different values)");
      show_diffs(dest, named_dest);
    }
    else
      puts("FAIL (no destination)");


    status = 1;
  }
  else
    puts("PASS");

  if (named_dest)
    cupsFreeDests(1, named_dest);

 /*
  * cupsPrintFile()
  */

  fputs("cupsPrintFile: ", stdout);
  fflush(stdout);

  if (cupsPrintFile(dest->name, "../data/testprint", "Test Page",
                    dest->num_options, dest->options) <= 0)
  {
    printf("FAIL (%s)\n", cupsLastErrorString());
    return (1);
  }
  else
    puts("PASS");

 /*
  * cupsGetPPD(printer)
  */

  fputs("cupsGetPPD(): ", stdout);
  fflush(stdout);

  if ((ppdfile = cupsGetPPD(dest->name)) == NULL)
  {
    puts("FAIL");
  }
  else
  {
    puts("PASS");

   /*
    * ppdOpenFile()
    */

    fputs("ppdOpenFile(): ", stdout);
    fflush(stdout);

    if ((ppd = ppdOpenFile(ppdfile)) == NULL)
    {
      puts("FAIL");
      return (1);
    }
    else
      puts("PASS");

    ppdClose(ppd);
    unlink(ppdfile);
  }

 /*
  * cupsGetJobs()
  */

  fputs("cupsGetJobs: ", stdout);
  fflush(stdout);

  num_jobs = cupsGetJobs(&jobs, NULL, 0, -1);

  if (num_jobs == 0)
  {
    puts("FAIL");
    return (1);
  }
  else
    puts("PASS");

  cupsFreeJobs(num_jobs, jobs);
  cupsFreeDests(num_dests, dests);

  return (status);
}
示例#16
0
GList *dt_get_papers(const dt_printer_info_t *printer)
{
  const char *printer_name = printer->name;
  GList *result = NULL;

#if ((CUPS_VERSION_MAJOR == 1) && (CUPS_VERSION_MINOR >= 7)) || CUPS_VERSION_MAJOR > 1
#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
  if (cupsConnectDest != NULL && cupsCopyDestInfo != NULL && cupsGetDestMediaCount != NULL &&
      cupsGetDestMediaByIndex != NULL && cupsFreeDestInfo != NULL)
#endif
  {
    cups_dest_t *dests;
    int num_dests = cupsGetDests(&dests);
    cups_dest_t *dest = cupsGetDest(printer_name, NULL, num_dests, dests);

    int cancel = 0; // important

    char resource[1024];

    if (dest)
    {
      http_t *hcon = cupsConnectDest(dest, 0, 2000, &cancel, resource, sizeof(resource), NULL, (void *)NULL);

      if (hcon)
      {
        cups_size_t size;
        cups_dinfo_t *info = cupsCopyDestInfo (hcon, dest);
        const int count = cupsGetDestMediaCount(hcon, dest, info, CUPS_MEDIA_FLAGS_DEFAULT);
        for (int k=0; k<count; k++)
        {
          if (cupsGetDestMediaByIndex(hcon, dest, info, k, CUPS_MEDIA_FLAGS_DEFAULT, &size))
          {
            if (size.width!=0 && size.length!=0 && !paper_exists(result, size.media))
            {
              pwg_media_t *med = pwgMediaForPWG (size.media);
              char common_name[MAX_NAME] = { 0 };

              if (med->ppd)
                g_strlcpy(common_name, med->ppd, sizeof(common_name));
              else
                g_strlcpy(common_name, size.media, sizeof(common_name));

              dt_paper_info_t *paper = (dt_paper_info_t*)malloc(sizeof(dt_paper_info_t));
              g_strlcpy(paper->name, size.media, sizeof(paper->name));
              g_strlcpy(paper->common_name, common_name, sizeof(paper->common_name));
              paper->width = (double)size.width / 100.0;
              paper->height = (double)size.length / 100.0;
              result = g_list_append (result, paper);

              dt_print(DT_DEBUG_PRINT,
                       "[print] new media paper %4d %6.2f x %6.2f (%s) (%s)\n",
                       k, paper->width, paper->height, paper->name, paper->common_name);
            }
          }
        }

        cupsFreeDestInfo(info);
        httpClose(hcon);
      }
      else
        dt_print(DT_DEBUG_PRINT, "[print] cannot connect to printer %s (cancel=%d)\n", printer_name, cancel);
    }

    cupsFreeDests(num_dests, dests);
  }
#endif

  // check now PPD page sizes

  const char *PPDFile = cupsGetPPD(printer_name);
  ppd_file_t *ppd = ppdOpenFile(PPDFile);

  if (ppd)
  {
    ppd_size_t *size = ppd->sizes;

    for (int k=0; k<ppd->num_sizes; k++)
    {
      if (size->width!=0 && size->length!=0 && !paper_exists(result, size->name))
      {
        dt_paper_info_t *paper = (dt_paper_info_t*)malloc(sizeof(dt_paper_info_t));
        g_strlcpy(paper->name, size->name, MAX_NAME);
        g_strlcpy(paper->common_name, size->name, MAX_NAME);
        paper->width = (double)dt_pdf_point_to_mm(size->width);
        paper->height = (double)dt_pdf_point_to_mm(size->length);
        result = g_list_append (result, paper);

        dt_print(DT_DEBUG_PRINT,
                 "[print] new ppd paper %4d %6.2f x %6.2f (%s) (%s)\n",
                 k, paper->width, paper->height, paper->name, paper->common_name);
      }
      size++;
    }

    ppdClose(ppd);
    g_unlink(PPDFile);
  }

  result = g_list_sort_with_data (result, (GCompareDataFunc)sort_papers, NULL);
  return result;
}
示例#17
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);
}
示例#18
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);
}
示例#19
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);
}