diff -urN gutenprint-5.2.4/src/main/print-ps.c print/src/main/print-ps.c
--- gutenprint-5.2.4/src/main/print-ps.c	2008-08-18 03:01:16.000000000 +0100
+++ print/src/main/print-ps.c	2009-09-03 01:33:52.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- * "$Id: print-ps.c,v 1.101 2008/08/18 02:00:18 rlk Exp $"
+ * "$Id: print-ps.c,v 1.102 2009/09/03 00:33:52 rlk Exp $"
  *
  *   Print plug-in Adobe PostScript driver for the GIMP.
  *
@@ -771,6 +771,121 @@
 }
 
 /*
+ * 'ps_print_device_settings()' - output postscript code from PPD into the
+ * postscript stream.
+ */
+
+static void
+ps_print_device_settings(stp_vars_t *v)
+{
+  int i;
+  stp_parameter_list_t param_list = ps_list_parameters(v);
+  if (! param_list)
+    return;
+  stp_puts("%%BeginSetup\n", v);
+  for (i = 0; i < stp_parameter_list_count(param_list); i++)
+    {
+      const stp_parameter_t *param = stp_parameter_list_param(param_list, i);
+      stp_parameter_t desc;
+      stp_describe_parameter(v, param->name, &desc);
+      if (desc.is_active)
+	{
+	  switch (desc.p_type)
+	    {
+	    case STP_PARAMETER_TYPE_STRING_LIST:
+	    case STP_PARAMETER_TYPE_BOOLEAN:
+	      {
+		const char *val=NULL;
+		const char *defval=NULL;
+
+		/* If this is a bool parameter, set val to "True" or "False" - otherwise fetch from string parameter. */
+		if(desc.p_type==STP_PARAMETER_TYPE_BOOLEAN)
+		  {
+		    val=stp_get_boolean_parameter(v,desc.name) ? "True" : "False";
+		    defval=desc.deflt.boolean ? "True" : "False";
+		  }
+		else
+		  {
+		    val=stp_get_string_parameter(v,desc.name);
+		    defval=desc.deflt.str;
+		  }
+
+		/* We only include the option's code if it's set to a value other than the default. */
+		if(val && defval && (strcmp(val,defval)!=0))
+		  {
+		    if(m_ppd)
+		      {
+			/* If we have a PPD xml tree we hunt for the appropriate "option" and "choice"... */
+			stp_mxml_node_t *node=m_ppd;
+			node=stp_mxmlFindElement(node,node, "option", "name", desc.name, STP_MXML_DESCEND);
+			if(node)
+			  {
+			    node=stp_mxmlFindElement(node,node, "choice", "name", val, STP_MXML_DESCEND);
+			    if(node)
+			      {
+				if(node->child && node->child->value.opaque && (strlen(node->child->value.opaque)>1))
+				  {
+				    /* If we have opaque data for the child, we use %%BeginFeature and copy the code verbatim. */
+				    stp_puts("[{\n", v);
+				    stp_zprintf(v, "%%%%BeginFeature: *%s %s\n", desc.name, val);
+				    if(node->child->value.opaque)
+				      stp_puts(node->child->value.opaque,v);
+				    stp_puts("\n%%EndFeature\n", v);
+				    stp_puts("} stopped cleartomark\n", v);
+				  }
+				else
+				  {
+				    /* If we don't have code, we use %%IncludeFeature instead. */
+				    stp_puts("[{\n", v);
+				    stp_zprintf(v, "%%%%IncludeFeature: *%s %s\n", desc.name, val);
+				    if(node->child->value.opaque)
+				      stp_puts(node->child->value.opaque,v);
+				    stp_puts("} stopped cleartomark\n", v);
+				  }
+			      }
+			  }
+		      }
+		  }
+	      }
+	      break;
+	    case STP_PARAMETER_TYPE_INT:
+	      if(stp_get_int_parameter(v,desc.name)!=desc.deflt.integer)
+		{
+		  stp_puts("[{\n", v);
+		  stp_zprintf(v, "%%%%IncludeFeature: *%s %d\n", desc.name,
+			      stp_get_int_parameter(v, desc.name));
+		  stp_puts("} stopped cleartomark\n", v);
+		}
+	      break;
+	    case STP_PARAMETER_TYPE_DOUBLE:
+	      if(stp_get_float_parameter(v,desc.name)!=desc.deflt.dbl)
+		{
+		  stp_puts("[{\n", v);
+		  stp_zprintf(v, "%%%%IncludeFeature: *%s %f\n", desc.name,
+			      stp_get_float_parameter(v, desc.name));
+		  stp_puts("} stopped cleartomark\n", v);
+		}
+	      break;
+	    case STP_PARAMETER_TYPE_DIMENSION:
+	      if(stp_get_dimension_parameter(v,desc.name)!=desc.deflt.dimension)
+		{
+		  stp_puts("[{\n", v);
+		  stp_zprintf(v, "%%%%IncludeFeature: *%s %d\n", desc.name,
+			      stp_get_dimension_parameter(v, desc.name));
+		  stp_puts("} stopped cleartomark\n", v);
+		}
+	      break;
+	    default:
+	      break;
+	    }
+	}
+      stp_parameter_description_destroy(&desc);
+    }
+  stp_puts("%%EndSetup\n", v);
+  stp_parameter_list_destroy(param_list);
+}
+
+/*
  * 'ps_print()' - Print an image to a PostScript printer.
  */
 
@@ -867,10 +982,7 @@
   stp_puts("%%Orientation: Portrait\n", v);
   stp_puts("%%EndComments\n", v);
 
-#if 0
-  /* This is still not correct -- rlk 20070601 */
   ps_print_device_settings(v);
-#endif
 
  /*
   * Output the page...
diff -urN gutenprint-5.2.4/src/main/xmlppd.c print/src/main/xmlppd.c
--- gutenprint-5.2.4/src/main/xmlppd.c	2008-08-18 03:01:16.000000000 +0100
+++ print/src/main/xmlppd.c	2009-08-26 01:56:15.000000000 +0100
@@ -23,6 +23,8 @@
 
 #include <stdio.h>
 #include <gutenprint/mxml.h>
+#include <gutenprint/util.h>
+#include <gutenprint/string-list.h>
 #include <stdlib.h>
 #include "xmlppd.h"
 
@@ -213,6 +215,8 @@
   int		order_length;
   char		*order_list;
   int		in_comment;
+  stp_string_list_t *ialist = stp_string_list_create();
+  stp_string_list_t *pdlist = stp_string_list_create();
 
 
  /*
@@ -478,35 +482,51 @@
 	}
       else if (!option && !strcmp(buffer, "*ImageableArea"))
 	{
-	  stp_mxml_node_t *psize = stpi_xmlppd_find_page_size(ppd, keyword);
-	  if (psize)
-	    {
-	      const char *data[4];
-	      parse_values(data, 4, value);
-	      if (data[3])
-		{
-		  stp_mxmlElementSetAttr(psize, "left", data[0]);
-		  stp_mxmlElementSetAttr(psize, "bottom", data[1]);
-		  stp_mxmlElementSetAttr(psize, "right", data[2]);
-		  stp_mxmlElementSetAttr(psize, "top", data[3]);
-		}
-	    }
+	  stp_string_list_add_string(ialist, keyword, value);
 	}
       else if (!option && !strcmp(buffer, "*PaperDimension"))
 	{
-	  stp_mxml_node_t *psize = stpi_xmlppd_find_page_size(ppd, keyword);
-	  if (psize)
+	  stp_string_list_add_string(pdlist, keyword, value);
+	}
+    }
+  for (i = 0; i < stp_string_list_count(ialist); i++)
+    {
+      stp_param_string_t *pstr = stp_string_list_param(ialist, i);
+      stp_mxml_node_t *psize = stpi_xmlppd_find_page_size(ppd, pstr->name);
+      if (psize)
+	{
+	  const char *data[4];
+	  value = stp_strdup(pstr->text);
+	  parse_values(data, 4, value);
+	  if (data[3])
 	    {
-	      const char *data[2];
-	      parse_values(data, 2, value);
-	      if (data[1])
-		{
-		  stp_mxmlElementSetAttr(psize, "width", data[0]);
-		  stp_mxmlElementSetAttr(psize, "height", data[1]);
-		}
+	      stp_mxmlElementSetAttr(psize, "left", data[0]);
+	      stp_mxmlElementSetAttr(psize, "bottom", data[1]);
+	      stp_mxmlElementSetAttr(psize, "right", data[2]);
+	      stp_mxmlElementSetAttr(psize, "top", data[3]);
+	    }
+	  stp_free(value);
+	}
+    }
+  stp_string_list_destroy(ialist);
+  for (i = 0; i < stp_string_list_count(pdlist); i++)
+    {
+      stp_param_string_t *pstr = stp_string_list_param(pdlist, i);
+      stp_mxml_node_t *psize = stpi_xmlppd_find_page_size(ppd, pstr->name);
+      if (psize)
+	{
+	  const char *data[2];
+	  value = stp_strdup(pstr->text);
+	  parse_values(data, 2, value);
+	  if (data[1])
+	    {
+	      stp_mxmlElementSetAttr(psize, "width", data[0]);
+	      stp_mxmlElementSetAttr(psize, "height", data[1]);
 	    }
+	  stp_free(value);
 	}
     }
+  stp_string_list_destroy(pdlist);
   option_count = stpi_xmlppd_find_option_count(ppd);
   order_length = 1;		/* Terminating null */
   order_array = malloc(sizeof(order_t) * option_count);
