Beispiel #1
0
static void
raw_parameters(const stp_vars_t *v, const char *name,
	       stp_parameter_t *description)
{
  int		i;
  description->p_type = STP_PARAMETER_TYPE_INVALID;
  if (name == NULL)
    return;

  description->deflt.str = NULL;
  for (i = 0; i < the_parameter_count; i++)
    if (strcmp(name, the_parameters[i].name) == 0)
      {
	stp_fill_parameter_settings(description, &(the_parameters[i]));
	break;
      }
  if (strcmp(name, "InkType") == 0)
    {
      description->bounds.str = stp_string_list_create();
      for (i = 0; i < ink_count; i++)
	stp_string_list_add_string(description->bounds.str,
				  inks[i].name, inks[i].name);
      description->deflt.str =
	stp_string_list_param(description->bounds.str, 0)->name;
    }
  else if (strcmp(name, "PrintingMode") == 0)
    {
      description->bounds.str = stp_string_list_create();
      stp_string_list_add_string
	(description->bounds.str, "Color", _("Color"));
      stp_string_list_add_string
	(description->bounds.str, "BW", _("Black and White"));
      description->deflt.str =
	stp_string_list_param(description->bounds.str, 0)->name;
    }
  else if (strcmp(name, "PageSize") == 0)
    {
      int papersizes = stp_known_papersizes();
      description->bounds.str = stp_string_list_create();
      for (i = 0; i < papersizes; i++)
	{
	  const stp_papersize_t *pt = stp_get_papersize_by_index(i);
	  stp_string_list_add_string(description->bounds.str,
				     pt->name, gettext(pt->text));
	}
      description->deflt.str =
	stp_string_list_param(description->bounds.str, 0)->name;
    }
  else
    description->is_active = 0;
}
Beispiel #2
0
stp_string_list_t *
stp_string_list_create_from_params(const stp_param_string_t *list,
				   size_t count)
{
  size_t i = 0;
  stp_string_list_t *retval = stp_string_list_create();
  for (i = 0; i < count; i++)
    stp_string_list_add_string(retval, list[i].name, list[i].text);
  return retval;
}
int
main(int argc, char **argv)
{
  int i, j, k;
  int first_arg = 1;
  stp_string_list_t *printer_list = NULL;
  stp_parameter_level_t max_level = STP_PARAMETER_LEVEL_ADVANCED4;
  if (argc > 1 && !strcmp(argv[1], "-s"))
    {
      max_level = STP_PARAMETER_LEVEL_BASIC;
      first_arg++;
    }

  stp_init();
  
  if (argc > first_arg)
    {
      printer_list = stp_string_list_create();
      for (i = 1; i < argc; i++)
	stp_string_list_add_string(printer_list, argv[i], argv[i]);
    }
  for (i = 0; i < stp_printer_model_count(); i++)
    {
      stp_parameter_list_t params;
      int nparams;
      stp_parameter_t desc;
      const stp_printer_t *printer = stp_get_printer_by_index(i);
      const char *driver = stp_printer_get_driver(printer);
      const char *family = stp_printer_get_family(printer);
      stp_vars_t *pv = stp_vars_create_copy(stp_printer_get_defaults(printer));
      int tcount = 0;
      size_t count;
      int printer_is_color = 0;
      if (strcmp(family, "ps") == 0 || strcmp(family, "raw") == 0)
	continue;
      if (printer_list && !stp_string_list_is_present(printer_list, driver))
	continue;

      /* Set Job Mode to "Job" as this enables the Duplex option */
      stp_set_string_parameter(pv, "JobMode", "Job");

      stp_describe_parameter(pv, "PrintingMode", &desc);
      if (stp_string_list_is_present(desc.bounds.str, "Color"))
	printer_is_color = 1;
      stp_parameter_description_destroy(&desc);
      if (printer_is_color)
	stp_set_string_parameter(pv, "PrintingMode", "Color");
      else
	stp_set_string_parameter(pv, "PrintingMode", "BW");
      stp_set_string_parameter(pv, "ChannelBitDepth", "8");

      printf("# Printer model %s, long name `%s'\n", driver,
	     stp_printer_get_long_name(printer));

      printf("$families{'%s'} = '%s';\n", driver, family);
      printf("$models{'%s'} = '%d';\n", driver, stp_get_model_id(pv));

      params = stp_get_parameter_list(pv);
      nparams = stp_parameter_list_count(params);

      for (k = 0; k < nparams; k++)
	{
	  const stp_parameter_t *p = stp_parameter_list_param(params, k);
	  if (p->read_only ||
	      (p->p_level > max_level && strcmp(p->name, "Resolution") != 0) ||
	      (p->p_class != STP_PARAMETER_CLASS_OUTPUT &&
	       p->p_class != STP_PARAMETER_CLASS_CORE &&
	       p->p_class != STP_PARAMETER_CLASS_FEATURE))
	    continue;
	  count = 0;
	  stp_describe_parameter(pv, p->name, &desc);
	  if (desc.is_active)
	    {
	      printf("$longnames{'%s'}{'%s'} = '%s';\n",
		     driver, desc.name, desc.text);
	      printf("$param_classes{'%s'}{'%s'} = %d;\n",
		     driver, desc.name, desc.p_class);
	      printf("$param_types{'%s'}{'%s'} = %d;\n",
		     driver, desc.name, desc.p_type);
	      printf("$param_levels{'%s'}{'%s'} = %d;\n",
		     driver, desc.name, desc.p_level);
	      if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST)
		{
		  count = stp_string_list_count(desc.bounds.str);
		  if (count > 0)
		    {
		      if (desc.is_mandatory)
			{
			  printf("$defaults{'%s'}{'%s'} = '%s';\n",
				 driver, desc.name, desc.deflt.str);
			}
		      else
			{
			  printf("$defaults{'%s'}{'%s'} = '%s';\n",
				 driver, desc.name, "None");
			  printf("$stpdata{'%s'}{'%s'}{'%s'} = '%s';\n",
				 driver, desc.name, "None", "None");
			}
		      for (j = 0; j < count; j++)
			{
			  const stp_param_string_t *param =
			    stp_string_list_param(desc.bounds.str, j);
			  printf("$stpdata{'%s'}{'%s'}{'%s'} = '%s';\n",
				 driver, desc.name, param->name, param->text);
			  if (strcmp(desc.name, "Resolution") == 0)
			    {
			      int x, y;
			      stp_set_string_parameter(pv, "Resolution",
						       param->name);
			      stp_describe_resolution(pv, &x, &y);
			      if (x > 0 && y > 0)
				{
				  printf("$stpdata{'%s'}{'%s'}{'%s'} = '%d';\n",
					 driver, "x_resolution", param->name, x);
				  printf("$stpdata{'%s'}{'%s'}{'%s'} = '%d';\n",
					 driver, "y_resolution", param->name, y);
				}
			    }
			}
		    }
		}
	      else if (desc.p_type == STP_PARAMETER_TYPE_BOOLEAN)
		{
		  if (desc.is_mandatory)
		    {
		      printf("$defaults{'%s'}{'%s'} = '%d';\n",
			     driver, desc.name, desc.deflt.boolean);
		    }
		  else
		    {
		      printf("$defaults{'%s'}{'%s'} = '%s';\n",
			     driver, desc.name, "None");
		      printf("$stpdata{'%s'}{'%s'}{'%s'} = '%s';\n",
			     driver, desc.name, "None", "None");
		    }
		    
		  printf("$stpdata{'%s'}{'%s'}{'False'} = 'False';\n",
			 driver, desc.name);
		  printf("$stpdata{'%s'}{'%s'}{'True'} = 'True';\n",
			 driver, desc.name);
		}
	      else if (desc.p_type == STP_PARAMETER_TYPE_DOUBLE)
		{
		  if (desc.bounds.dbl.lower <= desc.deflt.dbl &&
		      desc.bounds.dbl.upper >= desc.deflt.dbl)
		    {
		      printf("$stp_float_values{'%s'}{'MINVAL'}{'%s'} = %.3f;\n",
			     driver, desc.name, desc.bounds.dbl.lower);
		      printf("$stp_float_values{'%s'}{'MAXVAL'}{'%s'} = %.3f;\n",
			     driver, desc.name, desc.bounds.dbl.upper);
		      printf("$stp_float_values{'%s'}{'DEFVAL'}{'%s'} = %.3f;\n",
			     driver, desc.name, desc.deflt.dbl);
		      /* printf("$stp_float_values{'%s'}{'LONG_NAME'}{'%s'} = '%s';\n",
			 driver, desc.name, gettext(desc.text)); */
		      printf("$stp_float_values{'%s'}{'CATEGORY'}{'%s'} = '%s';\n",
			     driver, desc.name, gettext(desc.category));
		      printf("$stp_float_values{'%s'}{'HELP'}{'%s'} = q(%s);\n",
			     driver, desc.name, (desc.help ? gettext(desc.help) : "''"));
		      printf("$stp_float_values{'%s'}{'MANDATORY'}{'%s'} = q(%d);\n",
			     driver, desc.name, desc.is_mandatory);
		    }
		}
	      else if (desc.p_type == STP_PARAMETER_TYPE_INT)
		{
		  if (desc.bounds.integer.lower <= desc.deflt.integer &&
		      desc.bounds.integer.upper >= desc.deflt.integer)
		    {
		      printf("$stp_int_values{'%s'}{'MINVAL'}{'%s'} = %d;\n",
			     driver, desc.name, desc.bounds.integer.lower);
		      printf("$stp_int_values{'%s'}{'MAXVAL'}{'%s'} = %d;\n",
			     driver, desc.name, desc.bounds.integer.upper);
		      printf("$stp_int_values{'%s'}{'DEFVAL'}{'%s'} = %d;\n",
			     driver, desc.name, desc.deflt.integer);
		      /* printf("$stp_int_values{'%s'}{'LONG_NAME'}{'%s'} = '%s';\n",
			 driver, desc.name, gettext(desc.text)); */
		      printf("$stp_int_values{'%s'}{'CATEGORY'}{'%s'} = '%s';\n",
			     driver, desc.name, gettext(desc.category));
		      printf("$stp_int_values{'%s'}{'HELP'}{'%s'} = q(%s);\n",
			     driver, desc.name, (desc.help ? gettext(desc.help) : "''"));
		      printf("$stp_int_values{'%s'}{'MANDATORY'}{'%s'} = q(%d);\n",
			     driver, desc.name, desc.is_mandatory);
		    }
		}
	      else if (desc.p_type == STP_PARAMETER_TYPE_DIMENSION)
		{
		  if (desc.bounds.dimension.lower <= desc.deflt.dimension &&
		      desc.bounds.dimension.upper >= desc.deflt.dimension)
		    {
		      printf("$stp_dimension_values{'%s'}{'MINVAL'}{'%s'} = %d;\n",
			     driver, desc.name, desc.bounds.dimension.lower);
		      printf("$stp_dimension_values{'%s'}{'MAXVAL'}{'%s'} = %d;\n",
			     driver, desc.name, desc.bounds.dimension.upper);
		      printf("$stp_dimension_values{'%s'}{'DEFVAL'}{'%s'} = %d;\n",
			     driver, desc.name, desc.deflt.dimension);
		      /* printf("$stp_dimension_values{'%s'}{'LONG_NAME'}{'%s'} = '%s';\n",
			 driver, desc.name, gettext(desc.text)); */
		      printf("$stp_dimension_values{'%s'}{'CATEGORY'}{'%s'} = '%s';\n",
			     driver, desc.name, gettext(desc.category));
		      printf("$stp_dimension_values{'%s'}{'HELP'}{'%s'} = q(%s);\n",
			     driver, desc.name, (desc.help ? gettext(desc.help) : "''"));
		      printf("$stp_dimension_values{'%s'}{'MANDATORY'}{'%s'} = q(%d);\n",
			     driver, desc.name, desc.is_mandatory);
		    }
		}
	      tcount += count;
	    }
	  stp_parameter_description_destroy(&desc);
	}
      stp_parameter_list_destroy(params);
      if (tcount > 0)
	{
	  if (printer_is_color)
	    {
	      printf("$defaults{'%s'}{'%s'} = '%s';\n",
		     driver, "Color", "Color");
	      printf("$stpdata{'%s'}{'%s'}{'%s'} = '%s';\n",
		     driver, "Color", "Color", "Color");
	      printf("$stpdata{'%s'}{'%s'}{'%s'} = '%s';\n",
		     driver, "Color", "RawCMYK", "Raw CMYK");
	    }
	  else
	    printf("$defaults{'%s'}{'%s'} = '%s';\n",
		   driver, "Color", "Grayscale");
	  printf("$stpdata{'%s'}{'%s'}{'%s'} = '%s';\n",
		 driver, "Color", "Grayscale", "Gray Scale");
	  printf("$stpdata{'%s'}{'%s'}{'%s'} = '%s';\n",
		 driver, "Color", "BlackAndWhite", "Black and White");
	}
      stp_vars_destroy(pv);
    }
  return 0;
}
static void
load_model_from_file(const stp_vars_t *v, stp_mxml_node_t *xmod, int model)
{
  stp_mxml_node_t *tmp = xmod->child;
  stpi_escp2_printer_t *p = stp_escp2_get_printer(v);
  int found_black_head_config = 0;
  int found_fast_head_config = 0;
  p->max_black_resolution = -1;
  p->cd_x_offset = -1;
  p->cd_y_offset = -1;
  p->duplex_left_margin = SHRT_MIN;
  p->duplex_right_margin = SHRT_MIN;
  p->duplex_top_margin = SHRT_MIN;
  p->duplex_bottom_margin = SHRT_MIN;
  while (tmp)
    {
      if (tmp->type == STP_MXML_ELEMENT)
	{
	  const char *name = tmp->value.element.name;
	  const char *target = stp_mxmlElementGetAttr(tmp, "src");
	  if (target)
	    {
	      if (!strcmp(name, "media"))
		stp_escp2_load_media(v, target);
	      else if (!strcmp(name, "inputSlots"))
		stp_escp2_load_input_slots(v, target);
	      else if (!strcmp(name, "mediaSizes"))
		stp_escp2_load_media_sizes(v, target);
	      else if (!strcmp(name, "printerWeaves"))
		stp_escp2_load_printer_weaves(v, target);
	      else if (!strcmp(name, "qualityPresets"))
		stp_escp2_load_quality_presets(v, target);
	      else if (!strcmp(name, "resolutions"))
		stp_escp2_load_resolutions(v, target);
	      else if (!strcmp(name, "inkGroup"))
		stp_escp2_load_inkgroup(v, target);
	    }
	  else if (tmp->child && tmp->child->type == STP_MXML_TEXT)
	    {
	      stp_mxml_node_t *child = tmp->child;
	      const char *val = child->value.text.string;
	      if (!strcmp(name, "verticalBorderlessSequence"))
		{
		  STPI_ASSERT(!p->vertical_borderless_sequence, NULL);
		  p->vertical_borderless_sequence = stp_xmlstrtoraw(val);
		}
	      else if (!strcmp(name, "preinitSequence"))
		{
		  STPI_ASSERT(!p->preinit_sequence, NULL);
		  p->preinit_sequence = stp_xmlstrtoraw(val);
		}
	      else if (!strcmp(name, "preinitRemoteSequence"))
		{
		  STPI_ASSERT(!p->preinit_remote_sequence, NULL);
		  p->preinit_remote_sequence = stp_xmlstrtoraw(val);
		}
	      else if (!strcmp(name, "postinitRemoteSequence"))
		{
		  STPI_ASSERT(!p->postinit_remote_sequence, NULL);
		  p->postinit_remote_sequence = stp_xmlstrtoraw(val);
		}
	      else if (!strcmp(name, "commandSet"))
		{
		  if (!strcmp(val, "1998"))
		    p->flags |= MODEL_COMMAND_1998;
		  else if (!strcmp(val, "1999"))
		    p->flags |= MODEL_COMMAND_1999;
		  else if (!strcmp(val, "2000"))
		    p->flags |= MODEL_COMMAND_2000;
		  else if (!strcmp(val, "Pro"))
		    p->flags |= MODEL_COMMAND_PRO;
		}
	      else if (!strcmp(name, "borderless"))
		{
		  if (!strcmp(val, "No"))
		    p->flags |= MODEL_ZEROMARGIN_NO;
		  else if (!strcmp(val, "Yes"))
		    p->flags |= MODEL_ZEROMARGIN_YES;
		  else if (!strcmp(val, "Full"))
		    p->flags |= MODEL_ZEROMARGIN_FULL;
		  else if (!strcmp(val, "VerticalRestricted"))
		    p->flags |= MODEL_ZEROMARGIN_RESTR;
		  else if (!strcmp(val, "HorizontalOnly"))
		    p->flags |= MODEL_ZEROMARGIN_H_ONLY;
		}
	      else if (!strcmp(name, "preferredEnvelopeOrientation") &&
		       !strcmp(val, "Landscape"))
		p->flags |= MODEL_ENVELOPE_LANDSCAPE_YES;
	      else if (!strcmp(name, "headConfiguration"))
		{
		  const char *htype = stp_mxmlElementGetAttr(tmp, "type");
		  unsigned long data[4] = { 0, 0, 0, 0 };
		  while (child)
		    {
		      if (child->type == STP_MXML_ELEMENT && child->child &&
			  child->child->type == STP_MXML_TEXT)
			{
			  const char *cname = child->value.element.name;
			  const char *cval = child->child->value.text.string;
			  if (!strcmp(cname, "Nozzles"))
			    data[0] = stp_xmlstrtoul(cval);
			  else if (!strcmp(cname, "MinNozzles"))
			    data[1] = stp_xmlstrtoul(cval);
			  else if (!strcmp(cname, "FirstNozzle"))
			    data[2] = stp_xmlstrtoul(cval);
			  else if (!strcmp(cname, "NozzleSeparation"))
			    data[3] = stp_xmlstrtoul(cval);
			}
		      child = child->next;
		    }		      
		  if (!strcmp(htype, "default"))
		    {
		      p->nozzles = data[0];
		      p->min_nozzles = data[1];
		      p->nozzle_start = data[2];
		      p->nozzle_separation = data[3];
		      if (!found_black_head_config)
			{
			  p->black_nozzles = data[0];
			  p->min_black_nozzles = data[1];
			  p->black_nozzle_start = data[2];
			  p->black_nozzle_separation = data[3];
			}
		      if (!found_fast_head_config)
			{
			  p->fast_nozzles = data[0];
			  p->min_fast_nozzles = data[1];
			  p->fast_nozzle_start = data[2];
			  p->fast_nozzle_separation = data[3];
			}
		    }
		  else if (!strcmp(htype, "black"))
		    {
		      p->black_nozzles = data[0];
		      p->min_black_nozzles = data[1];
		      p->black_nozzle_start = data[2];
		      p->black_nozzle_separation = data[3];
		      found_black_head_config = 1;
		    }
		  else if (!strcmp(htype, "fast"))
		    {
		      p->fast_nozzles = data[0];
		      p->min_fast_nozzles = data[1];
		      p->fast_nozzle_start = data[2];
		      p->fast_nozzle_separation = data[3];
		      found_fast_head_config = 1;
		    }
		}
	      else if (!strcmp(name, "margins"))
		{
		  const char *itype = stp_mxmlElementGetAttr(tmp, "interleave");
		  const char *mtype = stp_mxmlElementGetAttr(tmp, "media");
		  const char *dtype = stp_mxmlElementGetAttr(tmp, "duplex");
		  unsigned long data[4];
		  int i = 0;
		  while (child && i < 4)
		    {
		      if (child->type == STP_MXML_TEXT)
			data[i++] = stp_xmlstrtoul(child->value.text.string);
		      child = child->next;
		    }		      
		  if (dtype && !strcmp(dtype, "duplex"))
		    {
		      p->duplex_left_margin = data[0];
		      p->duplex_right_margin = data[1];
		      p->duplex_top_margin = data[2];
		      p->duplex_bottom_margin = data[3];
		    }
		  else if (itype && !strcmp(itype, "soft") &&
			   mtype && !strcmp(mtype, "sheet"))
		    {
		      p->left_margin = data[0];
		      p->right_margin = data[1];
		      p->top_margin = data[2];
		      p->bottom_margin = data[3];
		    }
		  else if (itype && !strcmp(itype, "printer") &&
			   mtype && !strcmp(mtype, "sheet"))
		    {
		      p->m_left_margin = data[0];
		      p->m_right_margin = data[1];
		      p->m_top_margin = data[2];
		      p->m_bottom_margin = data[3];
		    }
		  else if (itype && !strcmp(itype, "soft") &&
			   mtype && !strcmp(mtype, "roll"))
		    {
		      p->roll_left_margin = data[0];
		      p->roll_right_margin = data[1];
		      p->roll_top_margin = data[2];
		      p->roll_bottom_margin = data[3];
		    }
		  else if (itype && !strcmp(itype, "printer") &&
			   mtype && !strcmp(mtype, "roll"))
		    {
		      p->m_roll_left_margin = data[0];
		      p->m_roll_right_margin = data[1];
		      p->m_roll_top_margin = data[2];
		      p->m_roll_bottom_margin = data[3];
		    }
		}
	      else if (!strcmp(name, "physicalChannels"))
		p->physical_channels = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "baseSeparation"))
		p->base_separation = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "resolutionScale"))
		p->resolution_scale = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "maxBlackResolution"))
		p->max_black_resolution = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "minimumResolution"))
		{
		  p->min_hres = stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->min_vres = stp_xmlstrtoul(child->value.text.string);
		}
	      else if (!strcmp(name, "maximumResolution"))
		{
		  p->max_hres = stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->max_vres = stp_xmlstrtoul(child->value.text.string);
		}
	      else if (!strcmp(name, "extraVerticalFeed"))
		p->extra_feed = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "separationRows"))
		p->separation_rows = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "pseudoSeparationRows"))
		p->pseudo_separation_rows = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "zeroMarginOffset"))
		p->zero_margin_offset = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "microLeftMargin"))
		p->micro_left_margin = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "initialVerticalOffset"))
		p->initial_vertical_offset = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "blackInitialVerticalOffset"))
		p->black_initial_vertical_offset = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "extra720DPISeparation"))
		p->extra_720dpi_separation = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "minHorizontalAlignment"))
		p->min_horizontal_position_alignment = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "baseHorizontalAlignment"))
		p->base_horizontal_position_alignment = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "bidirectionalAutoUpperLimit"))
		p->bidirectional_upper_limit = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "minimumMediaSize"))
		{
		  p->min_paper_width = stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->min_paper_height = stp_xmlstrtoul(child->value.text.string);
		}
	      else if (!strcmp(name, "maximumMediaSize"))
		{
		  p->max_paper_width = stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->max_paper_height = stp_xmlstrtoul(child->value.text.string);
		}
	      else if (!strcmp(name, "maximumImageableArea"))
		{
		  p->max_imageable_width = stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->max_imageable_height = stp_xmlstrtoul(child->value.text.string);
		}
	      else if (!strcmp(name, "CDOffset"))
		{
		  p->cd_x_offset = stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->cd_y_offset = stp_xmlstrtoul(child->value.text.string);
		}
	      else if (!strcmp(name, "CDMediaSize"))
		{
		  p->cd_page_width = stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->cd_page_height = stp_xmlstrtoul(child->value.text.string);
		}
	      else if (!strcmp(name, "extraBottom"))
		p->paper_extra_bottom = stp_xmlstrtoul(val);
	      else if (!strcmp(name, "AlignmentChoices"))
		{
		  p->alignment_passes =
		    stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->alignment_choices =
		    stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->alternate_alignment_passes =
		    stp_xmlstrtoul(child->value.text.string);
		  child = child->next;
		  p->alternate_alignment_choices =
		    stp_xmlstrtoul(child->value.text.string);
		}
	      else if (!strcmp(name, "ChannelNames"))
		{
		  p->channel_names = stp_string_list_create();
		  while (child)
		    {
		      if (child->type == STP_MXML_ELEMENT &&
			  !strcmp(child->value.element.name, "ChannelName"))
			{
			  const char *cname = stp_mxmlElementGetAttr(child, "name");
			  stp_string_list_add_string(p->channel_names, cname, cname);
			}
		      child = child->next;
		    }
		}
	      else if (!strcmp(name, "resolutions"))
		stp_escp2_load_resolutions_from_xml(v, tmp);
	    }
	  else
	    {
	      if (!strcmp(name, "supportsVariableDropsizes"))
		p->flags |= MODEL_VARIABLE_YES;
	      else if (!strcmp(name, "hasFastGraymode"))
		p->flags |= MODEL_GRAYMODE_YES;
	      else if (!strcmp(name, "hasFast360DPI"))
		p->flags |= MODEL_FAST_360_YES;
	      else if (!strcmp(name, "sendZeroAdvance"))
		p->flags |= MODEL_SEND_ZERO_ADVANCE_YES;
	      else if (!strcmp(name, "supportsInkChange"))
		p->flags |= MODEL_SUPPORTS_INK_CHANGE_YES;
	      else if (!strcmp(name, "supportsD4Mode"))
		p->flags |= MODEL_PACKET_MODE_YES;
	      else if (!strcmp(name, "hasInterchangeableInkCartridges"))
		p->flags |= MODEL_INTERCHANGEABLE_INK_YES;
	      else if (!strcmp(name, "resolutions"))
		stp_escp2_load_resolutions_from_xml(v, tmp);
	    }
	}
      tmp = tmp->next;
    }
}